DEV: Add experimental json_scheme site setting type (#12226)

This commit is contained in:
Penar Musaraj 2021-03-01 09:15:17 -05:00 committed by GitHub
parent bfa3e24e48
commit 6809cccd88
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
18 changed files with 411 additions and 3 deletions

View File

@ -0,0 +1,20 @@
import { action } from "@ember/object";
import Component from "@ember/component";
import showModal from "discourse/lib/show-modal";
export default Component.extend({
@action
launchJsonEditorModal() {
const schemaModal = showModal("json-schema-editor", {
model: {
value: this.value,
settingName: this.setting.setting,
jsonSchema: this.setting.json_schema,
},
});
schemaModal.set("onClose", () => {
this.set("value", schemaModal.model.value);
});
},
});

View File

@ -1,5 +1,11 @@
{{#if setting.textarea}}
{{textarea value=value classNames="input-setting-textarea"}}
{{else if setting.json_schema}}
{{d-button
action=(action "launchJsonEditorModal")
icon="pencil-alt"
label="admin.site_settings.json_schema.edit"
}}
{{else if isSecret}}
{{input type="password" value=value classNames="input-setting-string"}}
{{else}}

View File

@ -0,0 +1,63 @@
import { action } from "@ember/object";
import Component from "@ember/component";
import { create } from "virtual-dom";
import { iconNode } from "discourse-common/lib/icon-library";
import loadScript from "discourse/lib/load-script";
import { schedule } from "@ember/runloop";
export default Component.extend({
className: "json-editor-holder",
editor: null,
didReceiveAttrs() {
this._super(...arguments);
loadScript("/javascripts/jsoneditor.js").then(() => {
schedule("afterRender", () => {
let { JSONEditor } = window;
JSONEditor.defaults.options.theme = "bootstrap4";
JSONEditor.defaults.iconlibs = {
discourseIcons: DiscourseJsonSchemaEditorIconlib,
};
JSONEditor.defaults.options.iconlib = "discourseIcons";
const el = document.querySelector("#json-editor-holder");
this.editor = new JSONEditor(el, {
schema: this.model.jsonSchema,
disable_array_delete_all_rows: true,
disable_array_delete_last_row: true,
disable_array_reorder: true,
disable_array_copy: true,
disable_edit_json: true,
disable_properties: true,
disable_collapse: true,
startval: this.model.value ? JSON.parse(this.model.value) : null,
});
});
});
},
@action
saveChanges() {
const fieldValue = JSON.stringify(this.editor.getValue());
this.saveChangesCallback(fieldValue);
this.editor.destroy();
},
});
class DiscourseJsonSchemaEditorIconlib {
constructor() {
this.mapping = {
delete: "times",
add: "plus",
};
}
getIcon(key) {
if (!this.mapping[key]) {
return;
}
return create(iconNode(this.mapping[key]));
}
}

View File

@ -0,0 +1,13 @@
import { action } from "@ember/object";
import Controller from "@ember/controller";
import ModalFunctionality from "discourse/mixins/modal-functionality";
export default Controller.extend(ModalFunctionality, {
editor: null,
@action
saveChanges(value) {
this.set("model.value", value);
this.send("closeModal");
},
});

View File

@ -3,6 +3,7 @@
export const PUBLIC_JS_VERSIONS = {
"ace/ace.js": "ace.js/1.4.12/ace.js",
"jsoneditor.js": "@json-editor/json-editor/2.5.2/jsoneditor.js",
"Chart.min.js": "chart.js/2.9.3/Chart.min.js",
"chartjs-plugin-datalabels.min.js":
"chartjs-plugin-datalabels/0.7.0/chartjs-plugin-datalabels.min.js",

View File

@ -0,0 +1,11 @@
{{#d-modal-body rawTitle=(i18n "admin.site_settings.json_schema.modal_title" name=model.settingName)}}
<div id="json-editor-holder"></div>
{{/d-modal-body}}
<div class="modal-footer">
{{d-button
class="btn-primary"
action=(action "saveChanges")
label="save"
}}
</div>

View File

@ -0,0 +1 @@
{{json-editor model=this.model saveChangesCallback=(action "saveChanges") tagName=""}}

View File

@ -709,3 +709,60 @@
width: 10%;
}
}
.json-schema-editor-modal {
h3.card-title {
margin-top: 0;
label {
display: none;
}
}
.card .je-object__container {
border-bottom: 1px dashed var(--primary-low);
padding-bottom: 1em;
margin-bottom: 1em;
position: relative;
.card-title label {
display: inline-block;
font-size: $font-down-1;
color: var(--primary-medium);
}
.form-group {
label {
display: inline-block;
width: 33%;
}
.form-control {
width: 66%;
}
}
.btn-group:last-child {
position: absolute;
right: 0px;
top: 0px;
.btn {
font-size: $font-down-2;
}
}
}
.btn-group {
margin-top: 0;
}
.json-editor-btn-delete {
@extend .btn-danger !optional;
@extend .no-text !optional;
.d-icon + span {
display: none;
}
}
.card-body > .btn-group {
// !important needed to override inline style :-(
display: block !important;
text-align: right;
}
}

View File

@ -101,3 +101,9 @@
min-width: 450px;
}
}
.json-schema-editor-modal {
#json-editor-holder {
min-width: 500px;
}
}

View File

@ -5009,6 +5009,9 @@ en:
modal_no: "No, only apply change going forward"
simple_list:
add_item: "Add item..."
json_schema:
edit: Launch JSON Editor
modal_title: "Edit %{name}"
badges:
title: Badges

View File

@ -2303,6 +2303,7 @@ en:
invalid_string_min_max: "Must be between %{min} and %{max} characters."
invalid_string_min: "Must be at least %{min} characters."
invalid_string_max: "Must be no more than %{max} characters."
invalid_json: "Invalid JSON."
invalid_reply_by_email_address: "Value must contain '%{reply_key}' and be different from the notification email."
invalid_alternative_reply_by_email_addresses: "All values must contain '%{reply_key}' and be different from the notification email."
pop3_polling_host_is_empty: "You must set a 'pop3 polling host' before enabling POP3 polling."

View File

@ -5,8 +5,8 @@ module SiteSettings; end
class SiteSettings::TypeSupervisor
include SiteSettings::Validations
CONSUMED_OPTS = %i[enum choices type validator min max regex hidden regex_error allow_any list_type textarea].freeze
VALIDATOR_OPTS = %i[min max regex hidden regex_error].freeze
CONSUMED_OPTS = %i[enum choices type validator min max regex hidden regex_error allow_any list_type textarea json_schema].freeze
VALIDATOR_OPTS = %i[min max regex hidden regex_error json_schema].freeze
# For plugins, so they can tell if a feature is supported
SUPPORTED_TYPES = %i[email username list enum].freeze
@ -70,6 +70,7 @@ class SiteSettings::TypeSupervisor
@allow_any = {}
@list_type = {}
@textareas = {}
@json_schemas = {}
end
def load_setting(name_arg, opts = {})
@ -79,6 +80,10 @@ class SiteSettings::TypeSupervisor
@textareas[name] = opts[:textarea]
end
if opts[:json_schema]
@json_schemas[name] = opts[:json_schema].constantize
end
if (enum = opts[:enum])
@enums[name] = enum.is_a?(String) ? enum.constantize : enum
opts[:type] ||= :enum
@ -160,6 +165,9 @@ class SiteSettings::TypeSupervisor
result[:choices] = @choices[name] if @choices.has_key? name
result[:list_type] = @list_type[name] if @list_type.has_key? name
result[:textarea] = @textareas[name] if @textareas.has_key? name
if @json_schemas.has_key?(name) && json_klass = json_schema_class(name)
result[:json_schema] = json_klass.schema
end
result
end
@ -241,6 +249,10 @@ class SiteSettings::TypeSupervisor
@enums[name]
end
def json_schema_class(name)
@json_schemas[name]
end
def validator_for(type_name)
case type_name
when self.class.types[:email]

View File

@ -70,6 +70,10 @@ def dependencies
source: 'ace-builds/src-min-noconflict/ace.js',
destination: 'ace.js',
public: true
}, {
source: '@json-editor/json-editor/dist/jsoneditor.js',
package_name: '@json-editor/json-editor',
public: true
}, {
source: 'chart.js/dist/Chart.min.js',
public: true
@ -167,6 +171,7 @@ def dependencies
}, {
source: 'workbox-cacheable-response/build/.',
destination: 'workbox',
skip_versioning: true,
public: true
}, {
source: '@popperjs/core/dist/umd/popper.js'
@ -185,7 +190,7 @@ def dependencies
end
def node_package_name(f)
f[:source].split('/').first
f[:package_name] || f[:source].split('/').first
end
def public_path_name(f)

View File

@ -17,9 +17,23 @@ class StringSettingValidator
return false
end
return valid_json?(val) if (@opts[:json_schema])
regex_match?(val)
end
def valid_json?(json)
# TODO: right now this is only ensuring JSON is valid
# but ideally we should validate against the schema
begin
JSON.parse(json)
rescue JSON::ParserError => e
@json_fail = true
return false
end
true
end
def error_message
if @regex_fail
I18n.t(@regex_error)
@ -31,6 +45,8 @@ class StringSettingValidator
else
I18n.t('site_settings.errors.invalid_string_max', max: @opts[:max])
end
elsif @json_fail
I18n.t('site_settings.errors.invalid_json')
else
I18n.t('site_settings.errors.invalid_string')
end

View File

@ -7,6 +7,7 @@
"license": "GPL-2.0-only",
"dependencies": {
"@fortawesome/fontawesome-free": "5.11.2",
"@json-editor/json-editor": "^2.5.2",
"@popperjs/core": "v2.0.6",
"ace-builds": "1.4.12",
"blueimp-file-upload": "10.13.0",

File diff suppressed because one or more lines are too long

View File

@ -151,6 +151,22 @@ describe SiteSettings::TypeSupervisor do
end
end
class TestJsonSchemaClass
def self.schema
{
type: "array",
items: {
type: "object",
properties: {
name: {
type: "string",
},
},
},
}
end
end
before do
settings.setting(:type_null, nil)
settings.setting(:type_int, 1)
@ -164,6 +180,7 @@ describe SiteSettings::TypeSupervisor do
settings.setting(:type_mock_validate_method, 'no_value')
settings.setting(:type_custom, 'custom', type: 'list')
settings.setting(:type_upload, '', type: 'upload')
settings.setting(:type_json_schema, "[{\"name\":\"Brett\"}]", json_schema: 'TestJsonSchemaClass')
settings.refresh!
end
@ -245,6 +262,16 @@ describe SiteSettings::TypeSupervisor do
settings.type_supervisor.expects(:validate_type_mock_validate_method).with('no')
settings.type_supervisor.to_db_value(:type_mock_validate_method, 'no')
end
it 'raises when there is invalid json in a string with json schema' do
expect {
settings.type_supervisor.to_db_value(:type_json_schema, 'not-json')
}.to raise_error Discourse::InvalidParameters
end
it 'returns value for the given json schema string setting' do
expect(settings.type_supervisor.to_db_value(:type_json_schema, '{}')).to eq ['{}', SiteSetting.types[:string]]
end
end
describe '#to_rb_value' do

151
yarn.lock
View File

@ -14,6 +14,13 @@
dependencies:
"@babel/highlight" "^7.10.4"
"@babel/code-frame@^7.12.13":
version "7.12.13"
resolved "https://registry.yarnpkg.com/@babel/code-frame/-/code-frame-7.12.13.tgz#dcfc826beef65e75c50e21d3837d7d95798dd658"
integrity sha512-HV1Cm0Q3ZrpCR93tkWOYiuYIgLxZXZFVG2VgK+MBWjUqZTundupbfx2aXarXuw5Ko5aMcjtJgbSs4vUGBS5v6g==
dependencies:
"@babel/highlight" "^7.12.13"
"@babel/generator@^7.11.5":
version "7.11.6"
resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.11.6.tgz#b868900f81b163b4d464ea24545c61cbac4dc620"
@ -23,6 +30,26 @@
jsesc "^2.5.1"
source-map "^0.5.0"
"@babel/generator@^7.13.0":
version "7.13.0"
resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.13.0.tgz#bd00d4394ca22f220390c56a0b5b85568ec1ec0c"
integrity sha512-zBZfgvBB/ywjx0Rgc2+BwoH/3H+lDtlgD4hBOpEv5LxRnYsm/753iRuLepqnYlynpjC3AdQxtxsoeHJoEEwOAw==
dependencies:
"@babel/types" "^7.13.0"
jsesc "^2.5.1"
source-map "^0.5.0"
"@babel/helper-create-class-features-plugin@^7.13.0":
version "7.13.0"
resolved "https://registry.yarnpkg.com/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.13.0.tgz#28d04ad9cfbd1ed1d8b988c9ea7b945263365846"
integrity sha512-twwzhthM4/+6o9766AW2ZBHpIHPSGrPGk1+WfHiu13u/lBnggXGNYCpeAyVfNwGDKfkhEDp+WOD/xafoJ2iLjA==
dependencies:
"@babel/helper-function-name" "^7.12.13"
"@babel/helper-member-expression-to-functions" "^7.13.0"
"@babel/helper-optimise-call-expression" "^7.12.13"
"@babel/helper-replace-supers" "^7.13.0"
"@babel/helper-split-export-declaration" "^7.12.13"
"@babel/helper-function-name@^7.10.4":
version "7.10.4"
resolved "https://registry.yarnpkg.com/@babel/helper-function-name/-/helper-function-name-7.10.4.tgz#d2d3b20c59ad8c47112fa7d2a94bc09d5ef82f1a"
@ -32,6 +59,15 @@
"@babel/template" "^7.10.4"
"@babel/types" "^7.10.4"
"@babel/helper-function-name@^7.12.13":
version "7.12.13"
resolved "https://registry.yarnpkg.com/@babel/helper-function-name/-/helper-function-name-7.12.13.tgz#93ad656db3c3c2232559fd7b2c3dbdcbe0eb377a"
integrity sha512-TZvmPn0UOqmvi5G4vvw0qZTpVptGkB1GL61R6lKvrSdIxGm5Pky7Q3fpKiIkQCAtRCBUwB0PaThlx9vebCDSwA==
dependencies:
"@babel/helper-get-function-arity" "^7.12.13"
"@babel/template" "^7.12.13"
"@babel/types" "^7.12.13"
"@babel/helper-get-function-arity@^7.10.4":
version "7.10.4"
resolved "https://registry.yarnpkg.com/@babel/helper-get-function-arity/-/helper-get-function-arity-7.10.4.tgz#98c1cbea0e2332f33f9a4661b8ce1505b2c19ba2"
@ -39,6 +75,42 @@
dependencies:
"@babel/types" "^7.10.4"
"@babel/helper-get-function-arity@^7.12.13":
version "7.12.13"
resolved "https://registry.yarnpkg.com/@babel/helper-get-function-arity/-/helper-get-function-arity-7.12.13.tgz#bc63451d403a3b3082b97e1d8b3fe5bd4091e583"
integrity sha512-DjEVzQNz5LICkzN0REdpD5prGoidvbdYk1BVgRUOINaWJP2t6avB27X1guXK1kXNrX0WMfsrm1A/ZBthYuIMQg==
dependencies:
"@babel/types" "^7.12.13"
"@babel/helper-member-expression-to-functions@^7.13.0":
version "7.13.0"
resolved "https://registry.yarnpkg.com/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.13.0.tgz#6aa4bb678e0f8c22f58cdb79451d30494461b091"
integrity sha512-yvRf8Ivk62JwisqV1rFRMxiSMDGnN6KH1/mDMmIrij4jztpQNRoHqqMG3U6apYbGRPJpgPalhva9Yd06HlUxJQ==
dependencies:
"@babel/types" "^7.13.0"
"@babel/helper-optimise-call-expression@^7.12.13":
version "7.12.13"
resolved "https://registry.yarnpkg.com/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.12.13.tgz#5c02d171b4c8615b1e7163f888c1c81c30a2aaea"
integrity sha512-BdWQhoVJkp6nVjB7nkFWcn43dkprYauqtk++Py2eaf/GRDFm5BxRqEIZCiHlZUGAVmtwKcsVL1dC68WmzeFmiA==
dependencies:
"@babel/types" "^7.12.13"
"@babel/helper-plugin-utils@^7.13.0":
version "7.13.0"
resolved "https://registry.yarnpkg.com/@babel/helper-plugin-utils/-/helper-plugin-utils-7.13.0.tgz#806526ce125aed03373bc416a828321e3a6a33af"
integrity sha512-ZPafIPSwzUlAoWT8DKs1W2VyF2gOWthGd5NGFMsBcMMol+ZhK+EQY/e6V96poa6PA/Bh+C9plWN0hXO1uB8AfQ==
"@babel/helper-replace-supers@^7.13.0":
version "7.13.0"
resolved "https://registry.yarnpkg.com/@babel/helper-replace-supers/-/helper-replace-supers-7.13.0.tgz#6034b7b51943094cb41627848cb219cb02be1d24"
integrity sha512-Segd5me1+Pz+rmN/NFBOplMbZG3SqRJOBlY+mA0SxAv6rjj7zJqr1AVr3SfzUVTLCv7ZLU5FycOM/SBGuLPbZw==
dependencies:
"@babel/helper-member-expression-to-functions" "^7.13.0"
"@babel/helper-optimise-call-expression" "^7.12.13"
"@babel/traverse" "^7.13.0"
"@babel/types" "^7.13.0"
"@babel/helper-split-export-declaration@^7.11.0":
version "7.11.0"
resolved "https://registry.yarnpkg.com/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.11.0.tgz#f8a491244acf6a676158ac42072911ba83ad099f"
@ -46,11 +118,23 @@
dependencies:
"@babel/types" "^7.11.0"
"@babel/helper-split-export-declaration@^7.12.13":
version "7.12.13"
resolved "https://registry.yarnpkg.com/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.12.13.tgz#e9430be00baf3e88b0e13e6f9d4eaf2136372b05"
integrity sha512-tCJDltF83htUtXx5NLcaDqRmknv652ZWCHyoTETf1CXYJdPC7nohZohjUgieXhv0hTJdRf2FjDueFehdNucpzg==
dependencies:
"@babel/types" "^7.12.13"
"@babel/helper-validator-identifier@^7.10.4":
version "7.10.4"
resolved "https://registry.yarnpkg.com/@babel/helper-validator-identifier/-/helper-validator-identifier-7.10.4.tgz#a78c7a7251e01f616512d31b10adcf52ada5e0d2"
integrity sha512-3U9y+43hz7ZM+rzG24Qe2mufW5KhvFg/NhnNph+i9mgCtdTCtMJuI1TMkrIUiK7Ix4PYlRF9I5dhqaLYA/ADXw==
"@babel/helper-validator-identifier@^7.12.11":
version "7.12.11"
resolved "https://registry.yarnpkg.com/@babel/helper-validator-identifier/-/helper-validator-identifier-7.12.11.tgz#c9a1f021917dcb5ccf0d4e453e399022981fc9ed"
integrity sha512-np/lG3uARFybkoHokJUmf1QfEvRVCPbmQeUQpKow5cQ3xWrV9i3rUHodKDJPQfTVX61qKi+UdYk8kik84n7XOw==
"@babel/highlight@^7.10.4":
version "7.10.4"
resolved "https://registry.yarnpkg.com/@babel/highlight/-/highlight-7.10.4.tgz#7d1bdfd65753538fabe6c38596cdb76d9ac60143"
@ -60,11 +144,33 @@
chalk "^2.0.0"
js-tokens "^4.0.0"
"@babel/highlight@^7.12.13":
version "7.12.13"
resolved "https://registry.yarnpkg.com/@babel/highlight/-/highlight-7.12.13.tgz#8ab538393e00370b26271b01fa08f7f27f2e795c"
integrity sha512-kocDQvIbgMKlWxXe9fof3TQ+gkIPOUSEYhJjqUjvKMez3krV7vbzYCDq39Oj11UAVK7JqPVGQPlgE85dPNlQww==
dependencies:
"@babel/helper-validator-identifier" "^7.12.11"
chalk "^2.0.0"
js-tokens "^4.0.0"
"@babel/parser@^7.10.4", "@babel/parser@^7.11.5", "@babel/parser@^7.7.0":
version "7.11.5"
resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.11.5.tgz#c7ff6303df71080ec7a4f5b8c003c58f1cf51037"
integrity sha512-X9rD8qqm695vgmeaQ4fvz/o3+Wk4ZzQvSHkDBgpYKxpD4qTAUm88ZKtHkVqIOsYFFbIQ6wQYhC6q7pjqVK0E0Q==
"@babel/parser@^7.12.13", "@babel/parser@^7.13.0":
version "7.13.4"
resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.13.4.tgz#340211b0da94a351a6f10e63671fa727333d13ab"
integrity sha512-uvoOulWHhI+0+1f9L4BoozY7U5cIkZ9PgJqvb041d6vypgUmtVPG4vmGm4pSggjl8BELzvHyUeJSUyEMY6b+qA==
"@babel/plugin-proposal-class-properties@^7.10.4":
version "7.13.0"
resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-class-properties/-/plugin-proposal-class-properties-7.13.0.tgz#146376000b94efd001e57a40a88a525afaab9f37"
integrity sha512-KnTDjFNC1g+45ka0myZNvSBFLhNCLN+GeGYLDEA8Oq7MZ6yMgfLoIRh86GRT0FjtJhZw8JyUskP9uvj5pHM9Zg==
dependencies:
"@babel/helper-create-class-features-plugin" "^7.13.0"
"@babel/helper-plugin-utils" "^7.13.0"
"@babel/template@^7.10.4":
version "7.10.4"
resolved "https://registry.yarnpkg.com/@babel/template/-/template-7.10.4.tgz#3251996c4200ebc71d1a8fc405fba940f36ba278"
@ -74,6 +180,30 @@
"@babel/parser" "^7.10.4"
"@babel/types" "^7.10.4"
"@babel/template@^7.12.13":
version "7.12.13"
resolved "https://registry.yarnpkg.com/@babel/template/-/template-7.12.13.tgz#530265be8a2589dbb37523844c5bcb55947fb327"
integrity sha512-/7xxiGA57xMo/P2GVvdEumr8ONhFOhfgq2ihK3h1e6THqzTAkHbkXgB0xI9yeTfIUoH3+oAeHhqm/I43OTbbjA==
dependencies:
"@babel/code-frame" "^7.12.13"
"@babel/parser" "^7.12.13"
"@babel/types" "^7.12.13"
"@babel/traverse@^7.13.0":
version "7.13.0"
resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.13.0.tgz#6d95752475f86ee7ded06536de309a65fc8966cc"
integrity sha512-xys5xi5JEhzC3RzEmSGrs/b3pJW/o87SypZ+G/PhaE7uqVQNv/jlmVIBXuoh5atqQ434LfXV+sf23Oxj0bchJQ==
dependencies:
"@babel/code-frame" "^7.12.13"
"@babel/generator" "^7.13.0"
"@babel/helper-function-name" "^7.12.13"
"@babel/helper-split-export-declaration" "^7.12.13"
"@babel/parser" "^7.13.0"
"@babel/types" "^7.13.0"
debug "^4.1.0"
globals "^11.1.0"
lodash "^4.17.19"
"@babel/traverse@^7.7.0":
version "7.11.5"
resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.11.5.tgz#be777b93b518eb6d76ee2e1ea1d143daa11e61c3"
@ -98,6 +228,15 @@
lodash "^4.17.19"
to-fast-properties "^2.0.0"
"@babel/types@^7.12.13", "@babel/types@^7.13.0":
version "7.13.0"
resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.13.0.tgz#74424d2816f0171b4100f0ab34e9a374efdf7f80"
integrity sha512-hE+HE8rnG1Z6Wzo+MhaKE5lM5eMx71T4EHJgku2E3xIfaULhDcxiiRxUYgwX8qwP1BBSlag+TdGOt6JAidIZTA==
dependencies:
"@babel/helper-validator-identifier" "^7.12.11"
lodash "^4.17.19"
to-fast-properties "^2.0.0"
"@cnakazawa/watch@^1.0.3":
version "1.0.4"
resolved "https://registry.yarnpkg.com/@cnakazawa/watch/-/watch-1.0.4.tgz#f864ae85004d0fcab6f50be9141c4da368d1656a"
@ -147,6 +286,13 @@
"@glimmer/interfaces" "^0.54.2"
"@simple-dom/interface" "^1.4.0"
"@json-editor/json-editor@^2.5.2":
version "2.5.2"
resolved "https://registry.yarnpkg.com/@json-editor/json-editor/-/json-editor-2.5.2.tgz#d6f348d7e2f5bf9ccf2e3b34f637143674265e7f"
integrity sha512-OqrPtRw8FM2mSZbAFFvvxW6j8JvXCoQbhMgSiryhmcoByh3tQk+PuhK+2+bk9K/zn9PAt9KQsAiSc9sv6WIr/A==
dependencies:
core-js "^3.6.5"
"@mixer/parallel-prettier@^2.0.1":
version "2.0.1"
resolved "https://registry.yarnpkg.com/@mixer/parallel-prettier/-/parallel-prettier-2.0.1.tgz#fd69bb55e38b3c1dbb2f1a534ea1a0cd3fe34946"
@ -790,6 +936,11 @@ copy-descriptor@^0.1.0:
resolved "https://registry.yarnpkg.com/copy-descriptor/-/copy-descriptor-0.1.1.tgz#676f6eb3c39997c2ee1ac3a924fd6124748f578d"
integrity sha1-Z29us8OZl8LuGsOpJP1hJHSPV40=
core-js@^3.6.5:
version "3.9.0"
resolved "https://registry.yarnpkg.com/core-js/-/core-js-3.9.0.tgz#790b1bb11553a2272b36e2625c7179db345492f8"
integrity sha512-PyFBJaLq93FlyYdsndE5VaueA9K5cNB7CGzeCj191YYLhkQM0gdZR2SKihM70oF0wdqKSKClv/tEBOpoRmdOVQ==
core-util-is@~1.0.0:
version "1.0.2"
resolved "https://registry.yarnpkg.com/core-util-is/-/core-util-is-1.0.2.tgz#b5fd54220aa2bc5ab57aab7140c940754503c1a7"