@fgv/ts-json 5.0.0-7 → 5.0.0-9
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/ts-json.d.ts +63 -28
- package/lib/packlets/editor/common.d.ts +6 -0
- package/lib/packlets/editor/common.d.ts.map +1 -1
- package/lib/packlets/editor/common.js.map +1 -1
- package/lib/packlets/editor/jsonEditor.d.ts +57 -28
- package/lib/packlets/editor/jsonEditor.d.ts.map +1 -1
- package/lib/packlets/editor/jsonEditor.js +101 -32
- package/lib/packlets/editor/jsonEditor.js.map +1 -1
- package/package.json +6 -6
package/dist/ts-json.d.ts
CHANGED
|
@@ -638,6 +638,12 @@ export declare interface IJsonEditorMergeOptions {
|
|
|
638
638
|
* - `'replace'`: Existing array is completely replaced with the new array
|
|
639
639
|
*/
|
|
640
640
|
arrayMergeBehavior: ArrayMergeBehavior;
|
|
641
|
+
/**
|
|
642
|
+
* Controls whether null values should be treated as property deletion during merge operations.
|
|
643
|
+
* - `false` (default): Null values are merged normally, setting the property to null
|
|
644
|
+
* - `true`: Null values delete the property from the target object during merge
|
|
645
|
+
*/
|
|
646
|
+
nullAsDelete?: boolean;
|
|
641
647
|
}
|
|
642
648
|
|
|
643
649
|
/**
|
|
@@ -1280,6 +1286,11 @@ export declare class JsonEditor implements IJsonCloneEditor {
|
|
|
1280
1286
|
*/
|
|
1281
1287
|
static getDefaultRules(options?: IJsonEditorOptions): Result<IJsonEditorRule[]>;
|
|
1282
1288
|
/**
|
|
1289
|
+
* Creates a complete IJsonEditorOptions object from partial options, filling in
|
|
1290
|
+
* default values for any missing properties. This ensures all editor instances
|
|
1291
|
+
* have consistent, complete configuration including validation rules and merge behavior.
|
|
1292
|
+
* @param options - Optional partial editor options to merge with defaults
|
|
1293
|
+
* @returns Success with complete editor options, or Failure if validation fails
|
|
1283
1294
|
* @internal
|
|
1284
1295
|
*/
|
|
1285
1296
|
protected static _getDefaultOptions(options?: Partial<IJsonEditorOptions>): Result<IJsonEditorOptions>;
|
|
@@ -1322,54 +1333,78 @@ export declare class JsonEditor implements IJsonCloneEditor {
|
|
|
1322
1333
|
*/
|
|
1323
1334
|
clone(src: JsonValue, context?: IJsonContext): DetailedResult<JsonValue, JsonEditFailureReason>;
|
|
1324
1335
|
/**
|
|
1325
|
-
*
|
|
1326
|
-
*
|
|
1327
|
-
*
|
|
1328
|
-
* @param
|
|
1329
|
-
* @
|
|
1336
|
+
* Merges properties from a source object into a target object, applying editor rules and
|
|
1337
|
+
* null-as-delete logic. This is the core merge implementation that handles property-by-property
|
|
1338
|
+
* merging with rule processing and deferred property handling.
|
|
1339
|
+
* @param target - The target object to merge properties into
|
|
1340
|
+
* @param src - The source object containing properties to merge
|
|
1341
|
+
* @param state - The editor state containing options and context
|
|
1342
|
+
* @returns Success with the modified target object, or Failure with error details
|
|
1330
1343
|
* @internal
|
|
1331
1344
|
*/
|
|
1332
1345
|
protected _mergeObjectInPlace(target: JsonObject, src: JsonObject, state: JsonEditorState): Result<JsonObject>;
|
|
1333
1346
|
/**
|
|
1334
|
-
*
|
|
1335
|
-
*
|
|
1336
|
-
*
|
|
1337
|
-
* @
|
|
1347
|
+
* Creates a deep clone of a JSON array by recursively cloning each element.
|
|
1348
|
+
* Each array element is cloned using the main clone method, preserving the
|
|
1349
|
+
* editor's rules and validation settings.
|
|
1350
|
+
* @param src - The source JSON array to clone
|
|
1351
|
+
* @param context - Optional JSON context for cloning operations
|
|
1352
|
+
* @returns Success with the cloned array, or Failure with error details
|
|
1338
1353
|
* @internal
|
|
1339
1354
|
*/
|
|
1340
1355
|
protected _cloneArray(src: JsonArray, context?: IJsonContext): DetailedResult<JsonArray, JsonEditFailureReason>;
|
|
1341
1356
|
/**
|
|
1342
|
-
*
|
|
1343
|
-
*
|
|
1344
|
-
*
|
|
1345
|
-
*
|
|
1346
|
-
* @param
|
|
1347
|
-
* @
|
|
1357
|
+
* Merges a single cloned property value into a target object. This method handles
|
|
1358
|
+
* the core merge logic including null-as-delete behavior, array merging, and
|
|
1359
|
+
* recursive object merging. The null-as-delete check occurs before primitive
|
|
1360
|
+
* handling to ensure null values can signal property deletion.
|
|
1361
|
+
* @param target - The target object to merge the property into
|
|
1362
|
+
* @param key - The property key being merged
|
|
1363
|
+
* @param newValue - The cloned value to merge (from source object)
|
|
1364
|
+
* @param state - The editor state containing merge options and context
|
|
1365
|
+
* @returns Success with the merged value, or Failure with error details
|
|
1348
1366
|
* @internal
|
|
1349
1367
|
*/
|
|
1350
1368
|
protected _mergeClonedProperty(target: JsonObject, key: string, newValue: JsonValue, state: JsonEditorState): DetailedResult<JsonValue, JsonEditFailureReason>;
|
|
1351
1369
|
/**
|
|
1352
|
-
*
|
|
1353
|
-
*
|
|
1354
|
-
*
|
|
1355
|
-
* @param
|
|
1356
|
-
* @
|
|
1370
|
+
* Applies editor rules to a single property during merge operations. This method
|
|
1371
|
+
* iterates through all configured editor rules to process the property, handling
|
|
1372
|
+
* templates, conditionals, multi-value properties, and references.
|
|
1373
|
+
* @param key - The property key to edit
|
|
1374
|
+
* @param value - The property value to edit
|
|
1375
|
+
* @param state - The editor state containing rules and context
|
|
1376
|
+
* @returns Success with transformed property object, or Failure if rules cannot process
|
|
1357
1377
|
* @internal
|
|
1358
1378
|
*/
|
|
1359
1379
|
protected _editProperty(key: string, value: JsonValue, state: JsonEditorState): DetailedResult<JsonObject, JsonPropertyEditFailureReason>;
|
|
1360
1380
|
/**
|
|
1361
|
-
*
|
|
1362
|
-
*
|
|
1363
|
-
*
|
|
1364
|
-
* @
|
|
1381
|
+
* Applies editor rules to a single JSON value during clone operations. This method
|
|
1382
|
+
* iterates through all configured editor rules to process the value, handling
|
|
1383
|
+
* templates, conditionals, multi-value expressions, and references.
|
|
1384
|
+
* @param value - The JSON value to edit and transform
|
|
1385
|
+
* @param state - The editor state containing rules and context
|
|
1386
|
+
* @returns Success with transformed value, or Failure if rules cannot process
|
|
1365
1387
|
* @internal
|
|
1366
1388
|
*/
|
|
1367
1389
|
protected _editValue(value: JsonValue, state: JsonEditorState): DetailedResult<JsonValue, JsonEditFailureReason>;
|
|
1368
1390
|
/**
|
|
1369
|
-
*
|
|
1370
|
-
*
|
|
1371
|
-
* @param
|
|
1372
|
-
* @
|
|
1391
|
+
* Clone an object without applying null-as-delete behavior.
|
|
1392
|
+
* This preserves null values during cloning so they can be used for deletion signaling during merge.
|
|
1393
|
+
* @param target - The target object to clone into
|
|
1394
|
+
* @param src - The source object to clone
|
|
1395
|
+
* @param state - The editor state
|
|
1396
|
+
* @returns The cloned object
|
|
1397
|
+
* @internal
|
|
1398
|
+
*/
|
|
1399
|
+
protected _cloneObjectWithoutNullAsDelete(target: JsonObject, src: JsonObject, state: JsonEditorState): DetailedResult<JsonObject, JsonEditFailureReason>;
|
|
1400
|
+
/**
|
|
1401
|
+
* Finalizes the merge operation by processing any deferred properties and merging
|
|
1402
|
+
* them into the target object. Deferred properties are those that require special
|
|
1403
|
+
* processing after the initial merge phase, such as references that depend on
|
|
1404
|
+
* other properties being resolved first.
|
|
1405
|
+
* @param target - The target object that has been merged
|
|
1406
|
+
* @param state - The editor state containing deferred properties and rules
|
|
1407
|
+
* @returns Success with the finalized target object, or Failure with error details
|
|
1373
1408
|
* @internal
|
|
1374
1409
|
*/
|
|
1375
1410
|
protected _finalizeAndMerge(target: JsonObject, state: JsonEditorState): DetailedResult<JsonObject, JsonEditFailureReason>;
|
|
@@ -32,6 +32,12 @@ export interface IJsonEditorMergeOptions {
|
|
|
32
32
|
* - `'replace'`: Existing array is completely replaced with the new array
|
|
33
33
|
*/
|
|
34
34
|
arrayMergeBehavior: ArrayMergeBehavior;
|
|
35
|
+
/**
|
|
36
|
+
* Controls whether null values should be treated as property deletion during merge operations.
|
|
37
|
+
* - `false` (default): Null values are merged normally, setting the property to null
|
|
38
|
+
* - `true`: Null values delete the property from the target object during merge
|
|
39
|
+
*/
|
|
40
|
+
nullAsDelete?: boolean;
|
|
35
41
|
}
|
|
36
42
|
/**
|
|
37
43
|
* Validation options for a {@link JsonEditor | JsonEditor}.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"common.d.ts","sourceRoot":"","sources":["../../../src/packlets/editor/common.ts"],"names":[],"mappings":"AAqBA,OAAO,EAAE,SAAS,EAAE,MAAM,mBAAmB,CAAC;AAC9C,OAAO,EAAE,cAAc,EAAE,MAAM,eAAe,CAAC;AAC/C,OAAO,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAE1C;;;GAGG;AACH,MAAM,MAAM,qBAAqB,GAAG,QAAQ,GAAG,cAAc,GAAG,QAAQ,GAAG,OAAO,CAAC;AAEnF;;;GAGG;AACH,MAAM,MAAM,6BAA6B,GAAG,qBAAqB,GAAG,UAAU,CAAC;AAE/E;;;GAGG;AACH,MAAM,MAAM,yBAAyB,GACjC,qBAAqB,GACrB,sBAAsB,GACtB,wBAAwB,CAAC;AAE7B;;;GAGG;AACH,MAAM,MAAM,kBAAkB,GAAG,QAAQ,GAAG,SAAS,CAAC;AAEtD;;;GAGG;AACH,MAAM,WAAW,uBAAuB;IACtC;;;;OAIG;IACH,kBAAkB,EAAE,kBAAkB,CAAC;
|
|
1
|
+
{"version":3,"file":"common.d.ts","sourceRoot":"","sources":["../../../src/packlets/editor/common.ts"],"names":[],"mappings":"AAqBA,OAAO,EAAE,SAAS,EAAE,MAAM,mBAAmB,CAAC;AAC9C,OAAO,EAAE,cAAc,EAAE,MAAM,eAAe,CAAC;AAC/C,OAAO,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAE1C;;;GAGG;AACH,MAAM,MAAM,qBAAqB,GAAG,QAAQ,GAAG,cAAc,GAAG,QAAQ,GAAG,OAAO,CAAC;AAEnF;;;GAGG;AACH,MAAM,MAAM,6BAA6B,GAAG,qBAAqB,GAAG,UAAU,CAAC;AAE/E;;;GAGG;AACH,MAAM,MAAM,yBAAyB,GACjC,qBAAqB,GACrB,sBAAsB,GACtB,wBAAwB,CAAC;AAE7B;;;GAGG;AACH,MAAM,MAAM,kBAAkB,GAAG,QAAQ,GAAG,SAAS,CAAC;AAEtD;;;GAGG;AACH,MAAM,WAAW,uBAAuB;IACtC;;;;OAIG;IACH,kBAAkB,EAAE,kBAAkB,CAAC;IAEvC;;;;OAIG;IACH,YAAY,CAAC,EAAE,OAAO,CAAC;CACxB;AAED;;;GAGG;AACH,MAAM,WAAW,4BAA4B;IAC3C;;;;;OAKG;IACH,qBAAqB,EAAE,OAAO,GAAG,QAAQ,CAAC;IAE1C;;;;;OAKG;IACH,sBAAsB,EAAE,OAAO,GAAG,QAAQ,CAAC;IAE3C;;;;;OAKG;IACH,wBAAwB,EAAE,OAAO,GAAG,QAAQ,CAAC;CAC9C;AAED;;;GAGG;AACH,MAAM,WAAW,kBAAkB;IACjC,OAAO,CAAC,EAAE,YAAY,CAAC;IACvB,UAAU,EAAE,4BAA4B,CAAC;IACzC,KAAK,CAAC,EAAE,uBAAuB,CAAC;CACjC;AAED;;;GAGG;AACH,MAAM,WAAW,gBAAgB;IAC/B;;;;;OAKG;IACH,KAAK,CAAC,GAAG,EAAE,SAAS,EAAE,OAAO,CAAC,EAAE,YAAY,GAAG,cAAc,CAAC,SAAS,EAAE,qBAAqB,CAAC,CAAC;CACjG"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"common.js","sourceRoot":"","sources":["../../../src/packlets/editor/common.ts"],"names":[],"mappings":"","sourcesContent":["/*\n * Copyright (c) 2020 Erik Fortune\n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to deal\n * in the Software without restriction, including without limitation the rights\n * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n * copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in all\n * copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n * SOFTWARE.\n */\nimport { JsonValue } from '@fgv/ts-json-base';\nimport { DetailedResult } from '@fgv/ts-utils';\nimport { IJsonContext } from '../context';\n\n/**\n * Possible `DetailedResult` details for various editor operations.\n * @public\n */\nexport type JsonEditFailureReason = 'ignore' | 'inapplicable' | 'edited' | 'error';\n\n/**\n * Possible `DetailedResult` details for property edit operations.\n * @public\n */\nexport type JsonPropertyEditFailureReason = JsonEditFailureReason | 'deferred';\n\n/**\n * Possible validation rules for a {@link JsonEditor | JsonEditor}.\n * @public\n */\nexport type JsonEditorValidationRules =\n | 'invalidPropertyName'\n | 'invalidPropertyValue'\n | 'undefinedPropertyValue';\n\n/**\n * Array merge behavior options for a {@link JsonEditor | JsonEditor}.\n * @public\n */\nexport type ArrayMergeBehavior = 'append' | 'replace';\n\n/**\n * Merge options for a {@link JsonEditor | JsonEditor}.\n * @public\n */\nexport interface IJsonEditorMergeOptions {\n /**\n * Controls how arrays are merged when combining JSON values.\n * - `'append'` (default): Existing array elements are preserved and new elements are appended\n * - `'replace'`: Existing array is completely replaced with the new array\n */\n arrayMergeBehavior: ArrayMergeBehavior;\n}\n\n/**\n * Validation options for a {@link JsonEditor | JsonEditor}.\n * @public\n */\nexport interface IJsonEditorValidationOptions {\n /**\n * If `onInvalidPropertyName` is `'error'` (default) then any property name\n * that is invalid after template rendering causes an error and stops\n * conversion. If `onInvalidPropertyName` is `'ignore'`, then names which\n * are invalid after template rendering are passed through unchanged.\n */\n onInvalidPropertyName: 'error' | 'ignore';\n\n /**\n * If `onInvalidPropertyValue` is `'error'` (default) then any illegal\n * property value other than `undefined` causes an error and stops\n * conversion. If `onInvalidPropertyValue` is `'ignore'` then any\n * invalid property values are silently ignored.\n */\n onInvalidPropertyValue: 'error' | 'ignore';\n\n /**\n * If `onUndefinedPropertyValue` is `'error'`, then any property with\n * value `undefined` will cause an error and stop conversion. If\n * `onUndefinedPropertyValue` is `'ignore'` (default) then any\n * property with value `undefined` is silently ignored.\n */\n onUndefinedPropertyValue: 'error' | 'ignore';\n}\n\n/**\n * Initialization options for a {@link JsonEditor | JsonEditor}.\n * @public\n */\nexport interface IJsonEditorOptions {\n context?: IJsonContext;\n validation: IJsonEditorValidationOptions;\n merge?: IJsonEditorMergeOptions;\n}\n\n/**\n * A specialized JSON editor which does a deep clone of a supplied `JsonValue`.\n * @public\n */\nexport interface IJsonCloneEditor {\n /**\n * Returns a deep clone of a supplied `JsonValue`.\n * @param src - The `JsonValue` to be cloned.\n * @param context - An optional {@link IJsonContext | JSON context} used for clone\n * conversion operations.\n */\n clone(src: JsonValue, context?: IJsonContext): DetailedResult<JsonValue, JsonEditFailureReason>;\n}\n"]}
|
|
1
|
+
{"version":3,"file":"common.js","sourceRoot":"","sources":["../../../src/packlets/editor/common.ts"],"names":[],"mappings":"","sourcesContent":["/*\n * Copyright (c) 2020 Erik Fortune\n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to deal\n * in the Software without restriction, including without limitation the rights\n * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n * copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in all\n * copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n * SOFTWARE.\n */\nimport { JsonValue } from '@fgv/ts-json-base';\nimport { DetailedResult } from '@fgv/ts-utils';\nimport { IJsonContext } from '../context';\n\n/**\n * Possible `DetailedResult` details for various editor operations.\n * @public\n */\nexport type JsonEditFailureReason = 'ignore' | 'inapplicable' | 'edited' | 'error';\n\n/**\n * Possible `DetailedResult` details for property edit operations.\n * @public\n */\nexport type JsonPropertyEditFailureReason = JsonEditFailureReason | 'deferred';\n\n/**\n * Possible validation rules for a {@link JsonEditor | JsonEditor}.\n * @public\n */\nexport type JsonEditorValidationRules =\n | 'invalidPropertyName'\n | 'invalidPropertyValue'\n | 'undefinedPropertyValue';\n\n/**\n * Array merge behavior options for a {@link JsonEditor | JsonEditor}.\n * @public\n */\nexport type ArrayMergeBehavior = 'append' | 'replace';\n\n/**\n * Merge options for a {@link JsonEditor | JsonEditor}.\n * @public\n */\nexport interface IJsonEditorMergeOptions {\n /**\n * Controls how arrays are merged when combining JSON values.\n * - `'append'` (default): Existing array elements are preserved and new elements are appended\n * - `'replace'`: Existing array is completely replaced with the new array\n */\n arrayMergeBehavior: ArrayMergeBehavior;\n\n /**\n * Controls whether null values should be treated as property deletion during merge operations.\n * - `false` (default): Null values are merged normally, setting the property to null\n * - `true`: Null values delete the property from the target object during merge\n */\n nullAsDelete?: boolean;\n}\n\n/**\n * Validation options for a {@link JsonEditor | JsonEditor}.\n * @public\n */\nexport interface IJsonEditorValidationOptions {\n /**\n * If `onInvalidPropertyName` is `'error'` (default) then any property name\n * that is invalid after template rendering causes an error and stops\n * conversion. If `onInvalidPropertyName` is `'ignore'`, then names which\n * are invalid after template rendering are passed through unchanged.\n */\n onInvalidPropertyName: 'error' | 'ignore';\n\n /**\n * If `onInvalidPropertyValue` is `'error'` (default) then any illegal\n * property value other than `undefined` causes an error and stops\n * conversion. If `onInvalidPropertyValue` is `'ignore'` then any\n * invalid property values are silently ignored.\n */\n onInvalidPropertyValue: 'error' | 'ignore';\n\n /**\n * If `onUndefinedPropertyValue` is `'error'`, then any property with\n * value `undefined` will cause an error and stop conversion. If\n * `onUndefinedPropertyValue` is `'ignore'` (default) then any\n * property with value `undefined` is silently ignored.\n */\n onUndefinedPropertyValue: 'error' | 'ignore';\n}\n\n/**\n * Initialization options for a {@link JsonEditor | JsonEditor}.\n * @public\n */\nexport interface IJsonEditorOptions {\n context?: IJsonContext;\n validation: IJsonEditorValidationOptions;\n merge?: IJsonEditorMergeOptions;\n}\n\n/**\n * A specialized JSON editor which does a deep clone of a supplied `JsonValue`.\n * @public\n */\nexport interface IJsonCloneEditor {\n /**\n * Returns a deep clone of a supplied `JsonValue`.\n * @param src - The `JsonValue` to be cloned.\n * @param context - An optional {@link IJsonContext | JSON context} used for clone\n * conversion operations.\n */\n clone(src: JsonValue, context?: IJsonContext): DetailedResult<JsonValue, JsonEditFailureReason>;\n}\n"]}
|
|
@@ -58,6 +58,11 @@ export declare class JsonEditor implements IJsonCloneEditor {
|
|
|
58
58
|
*/
|
|
59
59
|
static getDefaultRules(options?: IJsonEditorOptions): Result<IJsonEditorRule[]>;
|
|
60
60
|
/**
|
|
61
|
+
* Creates a complete IJsonEditorOptions object from partial options, filling in
|
|
62
|
+
* default values for any missing properties. This ensures all editor instances
|
|
63
|
+
* have consistent, complete configuration including validation rules and merge behavior.
|
|
64
|
+
* @param options - Optional partial editor options to merge with defaults
|
|
65
|
+
* @returns Success with complete editor options, or Failure if validation fails
|
|
61
66
|
* @internal
|
|
62
67
|
*/
|
|
63
68
|
protected static _getDefaultOptions(options?: Partial<IJsonEditorOptions>): Result<IJsonEditorOptions>;
|
|
@@ -100,54 +105,78 @@ export declare class JsonEditor implements IJsonCloneEditor {
|
|
|
100
105
|
*/
|
|
101
106
|
clone(src: JsonValue, context?: IJsonContext): DetailedResult<JsonValue, JsonEditFailureReason>;
|
|
102
107
|
/**
|
|
103
|
-
*
|
|
104
|
-
*
|
|
105
|
-
*
|
|
106
|
-
* @param
|
|
107
|
-
* @
|
|
108
|
+
* Merges properties from a source object into a target object, applying editor rules and
|
|
109
|
+
* null-as-delete logic. This is the core merge implementation that handles property-by-property
|
|
110
|
+
* merging with rule processing and deferred property handling.
|
|
111
|
+
* @param target - The target object to merge properties into
|
|
112
|
+
* @param src - The source object containing properties to merge
|
|
113
|
+
* @param state - The editor state containing options and context
|
|
114
|
+
* @returns Success with the modified target object, or Failure with error details
|
|
108
115
|
* @internal
|
|
109
116
|
*/
|
|
110
117
|
protected _mergeObjectInPlace(target: JsonObject, src: JsonObject, state: JsonEditorState): Result<JsonObject>;
|
|
111
118
|
/**
|
|
112
|
-
*
|
|
113
|
-
*
|
|
114
|
-
*
|
|
115
|
-
* @
|
|
119
|
+
* Creates a deep clone of a JSON array by recursively cloning each element.
|
|
120
|
+
* Each array element is cloned using the main clone method, preserving the
|
|
121
|
+
* editor's rules and validation settings.
|
|
122
|
+
* @param src - The source JSON array to clone
|
|
123
|
+
* @param context - Optional JSON context for cloning operations
|
|
124
|
+
* @returns Success with the cloned array, or Failure with error details
|
|
116
125
|
* @internal
|
|
117
126
|
*/
|
|
118
127
|
protected _cloneArray(src: JsonArray, context?: IJsonContext): DetailedResult<JsonArray, JsonEditFailureReason>;
|
|
119
128
|
/**
|
|
120
|
-
*
|
|
121
|
-
*
|
|
122
|
-
*
|
|
123
|
-
*
|
|
124
|
-
* @param
|
|
125
|
-
* @
|
|
129
|
+
* Merges a single cloned property value into a target object. This method handles
|
|
130
|
+
* the core merge logic including null-as-delete behavior, array merging, and
|
|
131
|
+
* recursive object merging. The null-as-delete check occurs before primitive
|
|
132
|
+
* handling to ensure null values can signal property deletion.
|
|
133
|
+
* @param target - The target object to merge the property into
|
|
134
|
+
* @param key - The property key being merged
|
|
135
|
+
* @param newValue - The cloned value to merge (from source object)
|
|
136
|
+
* @param state - The editor state containing merge options and context
|
|
137
|
+
* @returns Success with the merged value, or Failure with error details
|
|
126
138
|
* @internal
|
|
127
139
|
*/
|
|
128
140
|
protected _mergeClonedProperty(target: JsonObject, key: string, newValue: JsonValue, state: JsonEditorState): DetailedResult<JsonValue, JsonEditFailureReason>;
|
|
129
141
|
/**
|
|
130
|
-
*
|
|
131
|
-
*
|
|
132
|
-
*
|
|
133
|
-
* @param
|
|
134
|
-
* @
|
|
142
|
+
* Applies editor rules to a single property during merge operations. This method
|
|
143
|
+
* iterates through all configured editor rules to process the property, handling
|
|
144
|
+
* templates, conditionals, multi-value properties, and references.
|
|
145
|
+
* @param key - The property key to edit
|
|
146
|
+
* @param value - The property value to edit
|
|
147
|
+
* @param state - The editor state containing rules and context
|
|
148
|
+
* @returns Success with transformed property object, or Failure if rules cannot process
|
|
135
149
|
* @internal
|
|
136
150
|
*/
|
|
137
151
|
protected _editProperty(key: string, value: JsonValue, state: JsonEditorState): DetailedResult<JsonObject, JsonPropertyEditFailureReason>;
|
|
138
152
|
/**
|
|
139
|
-
*
|
|
140
|
-
*
|
|
141
|
-
*
|
|
142
|
-
* @
|
|
153
|
+
* Applies editor rules to a single JSON value during clone operations. This method
|
|
154
|
+
* iterates through all configured editor rules to process the value, handling
|
|
155
|
+
* templates, conditionals, multi-value expressions, and references.
|
|
156
|
+
* @param value - The JSON value to edit and transform
|
|
157
|
+
* @param state - The editor state containing rules and context
|
|
158
|
+
* @returns Success with transformed value, or Failure if rules cannot process
|
|
143
159
|
* @internal
|
|
144
160
|
*/
|
|
145
161
|
protected _editValue(value: JsonValue, state: JsonEditorState): DetailedResult<JsonValue, JsonEditFailureReason>;
|
|
146
162
|
/**
|
|
147
|
-
*
|
|
148
|
-
*
|
|
149
|
-
* @param
|
|
150
|
-
* @
|
|
163
|
+
* Clone an object without applying null-as-delete behavior.
|
|
164
|
+
* This preserves null values during cloning so they can be used for deletion signaling during merge.
|
|
165
|
+
* @param target - The target object to clone into
|
|
166
|
+
* @param src - The source object to clone
|
|
167
|
+
* @param state - The editor state
|
|
168
|
+
* @returns The cloned object
|
|
169
|
+
* @internal
|
|
170
|
+
*/
|
|
171
|
+
protected _cloneObjectWithoutNullAsDelete(target: JsonObject, src: JsonObject, state: JsonEditorState): DetailedResult<JsonObject, JsonEditFailureReason>;
|
|
172
|
+
/**
|
|
173
|
+
* Finalizes the merge operation by processing any deferred properties and merging
|
|
174
|
+
* them into the target object. Deferred properties are those that require special
|
|
175
|
+
* processing after the initial merge phase, such as references that depend on
|
|
176
|
+
* other properties being resolved first.
|
|
177
|
+
* @param target - The target object that has been merged
|
|
178
|
+
* @param state - The editor state containing deferred properties and rules
|
|
179
|
+
* @returns Success with the finalized target object, or Failure with error details
|
|
151
180
|
* @internal
|
|
152
181
|
*/
|
|
153
182
|
protected _finalizeAndMerge(target: JsonObject, state: JsonEditorState): DetailedResult<JsonObject, JsonEditFailureReason>;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"jsonEditor.d.ts","sourceRoot":"","sources":["../../../src/packlets/editor/jsonEditor.ts"],"names":[],"mappings":"AAsBA,OAAO,EACL,cAAc,EACd,MAAM,EAQP,MAAM,eAAe,CAAC;AAQvB,OAAO,EACL,SAAS,EACT,UAAU,EACV,SAAS,EAIV,MAAM,mBAAmB,CAAC;AAC3B,OAAO,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAC1C,OAAO,EACL,gBAAgB,EAEhB,kBAAkB,EAElB,qBAAqB,EACrB,6BAA6B,EAC9B,MAAM,UAAU,CAAC;AAElB,OAAO,EAAE,eAAe,EAAE,MAAM,kBAAkB,CAAC;AACnD,OAAO,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAC;AAEpD;;;;;GAKG;AACH,qBAAa,UAAW,YAAW,gBAAgB;IACjD;;;OAGG;IACH,SAAS,CAAC,MAAM,CAAC,QAAQ,CAAC,EAAE,UAAU,CAAC;IAEvC;;OAEG;IACI,OAAO,EAAE,kBAAkB,CAAC;IAEnC;;;OAGG;IACH,SAAS,CAAC,MAAM,EAAE,eAAe,EAAE,CAAC;IAEpC;;;;;;;OAOG;IACH,SAAS,aAAa,OAAO,CAAC,EAAE,OAAO,CAAC,kBAAkB,CAAC,EAAE,KAAK,CAAC,EAAE,eAAe,EAAE;IAKtF;;;OAGG;IACH,WAAkB,OAAO,IAAI,UAAU,CAMtC;IAED;;;;;;OAMG;WACW,MAAM,CAAC,OAAO,CAAC,EAAE,OAAO,CAAC,kBAAkB,CAAC,EAAE,KAAK,CAAC,EAAE,eAAe,EAAE,GAAG,MAAM,CAAC,UAAU,CAAC;IAI1G;;;;;;;;OAQG;WACW,eAAe,CAAC,OAAO,CAAC,EAAE,kBAAkB,GAAG,MAAM,CAAC,eAAe,EAAE,CAAC;IAStF
|
|
1
|
+
{"version":3,"file":"jsonEditor.d.ts","sourceRoot":"","sources":["../../../src/packlets/editor/jsonEditor.ts"],"names":[],"mappings":"AAsBA,OAAO,EACL,cAAc,EACd,MAAM,EAQP,MAAM,eAAe,CAAC;AAQvB,OAAO,EACL,SAAS,EACT,UAAU,EACV,SAAS,EAIV,MAAM,mBAAmB,CAAC;AAC3B,OAAO,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAC1C,OAAO,EACL,gBAAgB,EAEhB,kBAAkB,EAElB,qBAAqB,EACrB,6BAA6B,EAC9B,MAAM,UAAU,CAAC;AAElB,OAAO,EAAE,eAAe,EAAE,MAAM,kBAAkB,CAAC;AACnD,OAAO,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAC;AAEpD;;;;;GAKG;AACH,qBAAa,UAAW,YAAW,gBAAgB;IACjD;;;OAGG;IACH,SAAS,CAAC,MAAM,CAAC,QAAQ,CAAC,EAAE,UAAU,CAAC;IAEvC;;OAEG;IACI,OAAO,EAAE,kBAAkB,CAAC;IAEnC;;;OAGG;IACH,SAAS,CAAC,MAAM,EAAE,eAAe,EAAE,CAAC;IAEpC;;;;;;;OAOG;IACH,SAAS,aAAa,OAAO,CAAC,EAAE,OAAO,CAAC,kBAAkB,CAAC,EAAE,KAAK,CAAC,EAAE,eAAe,EAAE;IAKtF;;;OAGG;IACH,WAAkB,OAAO,IAAI,UAAU,CAMtC;IAED;;;;;;OAMG;WACW,MAAM,CAAC,OAAO,CAAC,EAAE,OAAO,CAAC,kBAAkB,CAAC,EAAE,KAAK,CAAC,EAAE,eAAe,EAAE,GAAG,MAAM,CAAC,UAAU,CAAC;IAI1G;;;;;;;;OAQG;WACW,eAAe,CAAC,OAAO,CAAC,EAAE,kBAAkB,GAAG,MAAM,CAAC,eAAe,EAAE,CAAC;IAStF;;;;;;;OAOG;IACH,SAAS,CAAC,MAAM,CAAC,kBAAkB,CAAC,OAAO,CAAC,EAAE,OAAO,CAAC,kBAAkB,CAAC,GAAG,MAAM,CAAC,kBAAkB,CAAC;IAyBtG;;;;;;;;OAQG;IACI,kBAAkB,CACvB,MAAM,EAAE,UAAU,EAClB,GAAG,EAAE,UAAU,EACf,cAAc,CAAC,EAAE,YAAY,GAC5B,MAAM,CAAC,UAAU,CAAC;IAOrB;;;;;;;;OAQG;IACI,mBAAmB,CAAC,MAAM,EAAE,UAAU,EAAE,UAAU,EAAE,UAAU,EAAE,GAAG,MAAM,CAAC,UAAU,CAAC;IAI5F;;;;;;;;;OASG;IACI,8BAA8B,CACnC,OAAO,EAAE,YAAY,GAAG,SAAS,EACjC,IAAI,EAAE,UAAU,EAChB,UAAU,EAAE,UAAU,EAAE,GACvB,MAAM,CAAC,UAAU,CAAC;IAUrB;;;;;OAKG;IACI,KAAK,CAAC,GAAG,EAAE,SAAS,EAAE,OAAO,CAAC,EAAE,YAAY,GAAG,cAAc,CAAC,SAAS,EAAE,qBAAqB,CAAC;IA6BtG;;;;;;;;;OASG;IACH,SAAS,CAAC,mBAAmB,CAC3B,MAAM,EAAE,UAAU,EAClB,GAAG,EAAE,UAAU,EACf,KAAK,EAAE,eAAe,GACrB,MAAM,CAAC,UAAU,CAAC;IAmCrB;;;;;;;;OAQG;IACH,SAAS,CAAC,WAAW,CACnB,GAAG,EAAE,SAAS,EACd,OAAO,CAAC,EAAE,YAAY,GACrB,cAAc,CAAC,SAAS,EAAE,qBAAqB,CAAC;IAYnD;;;;;;;;;;;OAWG;IACH,SAAS,CAAC,oBAAoB,CAC5B,MAAM,EAAE,UAAU,EAClB,GAAG,EAAE,MAAM,EACX,QAAQ,EAAE,SAAS,EACnB,KAAK,EAAE,eAAe,GACrB,cAAc,CAAC,SAAS,EAAE,qBAAqB,CAAC;IAwDnD;;;;;;;;;OASG;IACH,SAAS,CAAC,aAAa,CACrB,GAAG,EAAE,MAAM,EACX,KAAK,EAAE,SAAS,EAChB,KAAK,EAAE,eAAe,GACrB,cAAc,CAAC,UAAU,EAAE,6BAA6B,CAAC;IAU5D;;;;;;;;OAQG;IACH,SAAS,CAAC,UAAU,CAClB,KAAK,EAAE,SAAS,EAChB,KAAK,EAAE,eAAe,GACrB,cAAc,CAAC,SAAS,EAAE,qBAAqB,CAAC;IAUnD;;;;;;;;OAQG;IACH,SAAS,CAAC,+BAA+B,CACvC,MAAM,EAAE,UAAU,EAClB,GAAG,EAAE,UAAU,EACf,KAAK,EAAE,eAAe,GACrB,cAAc,CAAC,UAAU,EAAE,qBAAqB,CAAC;IAoBpD;;;;;;;;;OASG;IACH,SAAS,CAAC,iBAAiB,CACzB,MAAM,EAAE,UAAU,EAClB,KAAK,EAAE,eAAe,GACrB,cAAc,CAAC,UAAU,EAAE,qBAAqB,CAAC;CAoBrD"}
|
|
@@ -84,9 +84,15 @@ class JsonEditor {
|
|
|
84
84
|
]);
|
|
85
85
|
}
|
|
86
86
|
/**
|
|
87
|
+
* Creates a complete IJsonEditorOptions object from partial options, filling in
|
|
88
|
+
* default values for any missing properties. This ensures all editor instances
|
|
89
|
+
* have consistent, complete configuration including validation rules and merge behavior.
|
|
90
|
+
* @param options - Optional partial editor options to merge with defaults
|
|
91
|
+
* @returns Success with complete editor options, or Failure if validation fails
|
|
87
92
|
* @internal
|
|
88
93
|
*/
|
|
89
94
|
static _getDefaultOptions(options) {
|
|
95
|
+
var _a;
|
|
90
96
|
const context = options === null || options === void 0 ? void 0 : options.context;
|
|
91
97
|
let validation = options === null || options === void 0 ? void 0 : options.validation;
|
|
92
98
|
if (validation === undefined) {
|
|
@@ -99,7 +105,14 @@ class JsonEditor {
|
|
|
99
105
|
let merge = options === null || options === void 0 ? void 0 : options.merge;
|
|
100
106
|
if (merge === undefined) {
|
|
101
107
|
merge = {
|
|
102
|
-
arrayMergeBehavior: 'append'
|
|
108
|
+
arrayMergeBehavior: 'append',
|
|
109
|
+
nullAsDelete: false
|
|
110
|
+
};
|
|
111
|
+
}
|
|
112
|
+
else {
|
|
113
|
+
merge = {
|
|
114
|
+
arrayMergeBehavior: merge.arrayMergeBehavior,
|
|
115
|
+
nullAsDelete: (_a = merge.nullAsDelete) !== null && _a !== void 0 ? _a : false
|
|
103
116
|
};
|
|
104
117
|
}
|
|
105
118
|
return (0, ts_utils_1.succeed)({ context, validation, merge });
|
|
@@ -171,7 +184,7 @@ class JsonEditor {
|
|
|
171
184
|
return (0, ts_utils_1.succeedWithDetail)(value, 'edited');
|
|
172
185
|
}
|
|
173
186
|
else if ((0, ts_json_base_1.isJsonObject)(value)) {
|
|
174
|
-
return this.
|
|
187
|
+
return this._cloneObjectWithoutNullAsDelete({}, value, state);
|
|
175
188
|
}
|
|
176
189
|
else if ((0, ts_json_base_1.isJsonArray)(value)) {
|
|
177
190
|
return this._cloneArray(value, state.context);
|
|
@@ -182,16 +195,22 @@ class JsonEditor {
|
|
|
182
195
|
return state.failValidation('invalidPropertyValue', `Cannot convert invalid JSON: "${JSON.stringify(value)}"`);
|
|
183
196
|
}
|
|
184
197
|
/**
|
|
185
|
-
*
|
|
186
|
-
*
|
|
187
|
-
*
|
|
188
|
-
* @param
|
|
189
|
-
* @
|
|
198
|
+
* Merges properties from a source object into a target object, applying editor rules and
|
|
199
|
+
* null-as-delete logic. This is the core merge implementation that handles property-by-property
|
|
200
|
+
* merging with rule processing and deferred property handling.
|
|
201
|
+
* @param target - The target object to merge properties into
|
|
202
|
+
* @param src - The source object containing properties to merge
|
|
203
|
+
* @param state - The editor state containing options and context
|
|
204
|
+
* @returns Success with the modified target object, or Failure with error details
|
|
190
205
|
* @internal
|
|
191
206
|
*/
|
|
192
207
|
_mergeObjectInPlace(target, src, state) {
|
|
193
208
|
for (const key in src) {
|
|
194
209
|
if (src.hasOwnProperty(key)) {
|
|
210
|
+
// Skip dangerous property names to prevent prototype pollution
|
|
211
|
+
if (key === '__proto__' || key === 'constructor' || key === 'prototype') {
|
|
212
|
+
continue;
|
|
213
|
+
}
|
|
195
214
|
const propResult = this._editProperty(key, src[key], state);
|
|
196
215
|
if (propResult.isSuccess()) {
|
|
197
216
|
if (propResult.detail === 'deferred') {
|
|
@@ -223,10 +242,12 @@ class JsonEditor {
|
|
|
223
242
|
return (0, ts_utils_1.succeed)(target);
|
|
224
243
|
}
|
|
225
244
|
/**
|
|
226
|
-
*
|
|
227
|
-
*
|
|
228
|
-
*
|
|
229
|
-
* @
|
|
245
|
+
* Creates a deep clone of a JSON array by recursively cloning each element.
|
|
246
|
+
* Each array element is cloned using the main clone method, preserving the
|
|
247
|
+
* editor's rules and validation settings.
|
|
248
|
+
* @param src - The source JSON array to clone
|
|
249
|
+
* @param context - Optional JSON context for cloning operations
|
|
250
|
+
* @returns Success with the cloned array, or Failure with error details
|
|
230
251
|
* @internal
|
|
231
252
|
*/
|
|
232
253
|
_cloneArray(src, context) {
|
|
@@ -240,17 +261,30 @@ class JsonEditor {
|
|
|
240
261
|
.withFailureDetail('error');
|
|
241
262
|
}
|
|
242
263
|
/**
|
|
243
|
-
*
|
|
244
|
-
*
|
|
245
|
-
*
|
|
246
|
-
*
|
|
247
|
-
* @param
|
|
248
|
-
* @
|
|
264
|
+
* Merges a single cloned property value into a target object. This method handles
|
|
265
|
+
* the core merge logic including null-as-delete behavior, array merging, and
|
|
266
|
+
* recursive object merging. The null-as-delete check occurs before primitive
|
|
267
|
+
* handling to ensure null values can signal property deletion.
|
|
268
|
+
* @param target - The target object to merge the property into
|
|
269
|
+
* @param key - The property key being merged
|
|
270
|
+
* @param newValue - The cloned value to merge (from source object)
|
|
271
|
+
* @param state - The editor state containing merge options and context
|
|
272
|
+
* @returns Success with the merged value, or Failure with error details
|
|
249
273
|
* @internal
|
|
250
274
|
*/
|
|
251
275
|
_mergeClonedProperty(target, key, newValue, state) {
|
|
252
|
-
var _a, _b;
|
|
276
|
+
var _a, _b, _c;
|
|
277
|
+
// Skip dangerous property names to prevent prototype pollution
|
|
278
|
+
if (key === '__proto__' || key === 'constructor' || key === 'prototype') {
|
|
279
|
+
return (0, ts_utils_1.succeedWithDetail)(newValue, 'edited');
|
|
280
|
+
}
|
|
253
281
|
const existing = target[key];
|
|
282
|
+
// Handle null-as-delete behavior before primitive check
|
|
283
|
+
/* c8 ignore next 1 - ? is defense in depth */
|
|
284
|
+
if (newValue === null && ((_a = state.options.merge) === null || _a === void 0 ? void 0 : _a.nullAsDelete) === true) {
|
|
285
|
+
delete target[key];
|
|
286
|
+
return (0, ts_utils_1.succeedWithDetail)(null, 'edited');
|
|
287
|
+
}
|
|
254
288
|
// merge is called right after clone so this should never happen
|
|
255
289
|
// since clone itself will have failed
|
|
256
290
|
if ((0, ts_json_base_1.isJsonPrimitive)(newValue)) {
|
|
@@ -268,7 +302,7 @@ class JsonEditor {
|
|
|
268
302
|
if ((0, ts_json_base_1.isJsonArray)(newValue)) {
|
|
269
303
|
if ((0, ts_json_base_1.isJsonArray)(existing)) {
|
|
270
304
|
/* c8 ignore next 1 - ?? is defense in depth */
|
|
271
|
-
const arrayMergeBehavior = (
|
|
305
|
+
const arrayMergeBehavior = (_c = (_b = state.options.merge) === null || _b === void 0 ? void 0 : _b.arrayMergeBehavior) !== null && _c !== void 0 ? _c : 'append';
|
|
272
306
|
switch (arrayMergeBehavior) {
|
|
273
307
|
case 'append':
|
|
274
308
|
target[key] = existing.concat(...newValue);
|
|
@@ -289,11 +323,13 @@ class JsonEditor {
|
|
|
289
323
|
return (0, ts_utils_1.failWithDetail)(`Invalid JSON: ${JSON.stringify(newValue)}`, 'error');
|
|
290
324
|
} /* c8 ignore stop */
|
|
291
325
|
/**
|
|
292
|
-
*
|
|
293
|
-
*
|
|
294
|
-
*
|
|
295
|
-
* @param
|
|
296
|
-
* @
|
|
326
|
+
* Applies editor rules to a single property during merge operations. This method
|
|
327
|
+
* iterates through all configured editor rules to process the property, handling
|
|
328
|
+
* templates, conditionals, multi-value properties, and references.
|
|
329
|
+
* @param key - The property key to edit
|
|
330
|
+
* @param value - The property value to edit
|
|
331
|
+
* @param state - The editor state containing rules and context
|
|
332
|
+
* @returns Success with transformed property object, or Failure if rules cannot process
|
|
297
333
|
* @internal
|
|
298
334
|
*/
|
|
299
335
|
_editProperty(key, value, state) {
|
|
@@ -306,10 +342,12 @@ class JsonEditor {
|
|
|
306
342
|
return (0, ts_utils_1.failWithDetail)('inapplicable', 'inapplicable');
|
|
307
343
|
}
|
|
308
344
|
/**
|
|
309
|
-
*
|
|
310
|
-
*
|
|
311
|
-
*
|
|
312
|
-
* @
|
|
345
|
+
* Applies editor rules to a single JSON value during clone operations. This method
|
|
346
|
+
* iterates through all configured editor rules to process the value, handling
|
|
347
|
+
* templates, conditionals, multi-value expressions, and references.
|
|
348
|
+
* @param value - The JSON value to edit and transform
|
|
349
|
+
* @param state - The editor state containing rules and context
|
|
350
|
+
* @returns Success with transformed value, or Failure if rules cannot process
|
|
313
351
|
* @internal
|
|
314
352
|
*/
|
|
315
353
|
_editValue(value, state) {
|
|
@@ -322,10 +360,41 @@ class JsonEditor {
|
|
|
322
360
|
return (0, ts_utils_1.failWithDetail)('inapplicable', 'inapplicable');
|
|
323
361
|
}
|
|
324
362
|
/**
|
|
325
|
-
*
|
|
326
|
-
*
|
|
327
|
-
* @param
|
|
328
|
-
* @
|
|
363
|
+
* Clone an object without applying null-as-delete behavior.
|
|
364
|
+
* This preserves null values during cloning so they can be used for deletion signaling during merge.
|
|
365
|
+
* @param target - The target object to clone into
|
|
366
|
+
* @param src - The source object to clone
|
|
367
|
+
* @param state - The editor state
|
|
368
|
+
* @returns The cloned object
|
|
369
|
+
* @internal
|
|
370
|
+
*/
|
|
371
|
+
_cloneObjectWithoutNullAsDelete(target, src, state) {
|
|
372
|
+
var _a, _b;
|
|
373
|
+
// Temporarily disable null-as-delete during cloning
|
|
374
|
+
const modifiedOptions = {
|
|
375
|
+
context: state.options.context,
|
|
376
|
+
validation: state.options.validation,
|
|
377
|
+
merge: {
|
|
378
|
+
/* c8 ignore next 1 - ? is defense in depth */
|
|
379
|
+
arrayMergeBehavior: (_b = (_a = state.options.merge) === null || _a === void 0 ? void 0 : _a.arrayMergeBehavior) !== null && _b !== void 0 ? _b : 'append',
|
|
380
|
+
nullAsDelete: false
|
|
381
|
+
}
|
|
382
|
+
};
|
|
383
|
+
const modifiedState = new jsonEditorState_1.JsonEditorState(state.editor, modifiedOptions, state.context);
|
|
384
|
+
return this._mergeObjectInPlace(target, src, modifiedState)
|
|
385
|
+
.onSuccess((merged) => {
|
|
386
|
+
return this._finalizeAndMerge(merged, modifiedState);
|
|
387
|
+
})
|
|
388
|
+
.withFailureDetail('error');
|
|
389
|
+
}
|
|
390
|
+
/**
|
|
391
|
+
* Finalizes the merge operation by processing any deferred properties and merging
|
|
392
|
+
* them into the target object. Deferred properties are those that require special
|
|
393
|
+
* processing after the initial merge phase, such as references that depend on
|
|
394
|
+
* other properties being resolved first.
|
|
395
|
+
* @param target - The target object that has been merged
|
|
396
|
+
* @param state - The editor state containing deferred properties and rules
|
|
397
|
+
* @returns Success with the finalized target object, or Failure with error details
|
|
329
398
|
* @internal
|
|
330
399
|
*/
|
|
331
400
|
_finalizeAndMerge(target, state) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"jsonEditor.js","sourceRoot":"","sources":["../../../src/packlets/editor/jsonEditor.ts"],"names":[],"mappings":";AAAA;;;;;;;;;;;;;;;;;;;;GAoBG;;;AAEH,4CAUuB;AACvB,mCAKiB;AAEjB,oDAO2B;AAY3B,uDAAoD;AAEpD;;;;;GAKG;AACH,MAAa,UAAU;IAkBrB;;;;;;;OAOG;IACH,YAAsB,OAAqC,EAAE,KAAyB;QACpF,IAAI,CAAC,OAAO,GAAG,UAAU,CAAC,kBAAkB,CAAC,OAAO,CAAC,CAAC,OAAO,EAAE,CAAC;QAChE,IAAI,CAAC,MAAM,GAAG,KAAK,IAAI,UAAU,CAAC,eAAe,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,OAAO,EAAE,CAAC;IAC5E,CAAC;IAED;;;OAGG;IACI,MAAM,KAAK,OAAO;QACvB,IAAI,CAAC,UAAU,CAAC,QAAQ,EAAE,CAAC;YACzB,MAAM,KAAK,GAAG,IAAI,CAAC,eAAe,EAAE,CAAC,SAAS,EAAE,CAAC;YACjD,UAAU,CAAC,QAAQ,GAAG,IAAI,UAAU,CAAC,SAAS,EAAE,KAAK,CAAC,CAAC;QACzD,CAAC;QACD,OAAO,UAAU,CAAC,QAAQ,CAAC;IAC7B,CAAC;IAED;;;;;;OAMG;IACI,MAAM,CAAC,MAAM,CAAC,OAAqC,EAAE,KAAyB;QACnF,OAAO,IAAA,wBAAa,EAAC,GAAG,EAAE,CAAC,IAAI,UAAU,CAAC,OAAO,EAAE,KAAK,CAAC,CAAC,CAAC;IAC7D,CAAC;IAED;;;;;;;;OAQG;IACI,MAAM,CAAC,eAAe,CAAC,OAA4B;QACxD,OAAO,IAAA,qBAAU,EAAkB;YACjC,+BAAuB,CAAC,MAAM,CAAC,OAAO,CAAC;YACvC,iCAAyB,CAAC,MAAM,CAAC,OAAO,CAAC;YACzC,gCAAwB,CAAC,MAAM,CAAC,OAAO,CAAC;YACxC,+BAAuB,CAAC,MAAM,CAAC,OAAO,CAAC;SACxC,CAAC,CAAC;IACL,CAAC;IAED;;OAEG;IACO,MAAM,CAAC,kBAAkB,CAAC,OAAqC;QACvE,MAAM,OAAO,GAA6B,OAAO,aAAP,OAAO,uBAAP,OAAO,CAAE,OAAO,CAAC;QAC3D,IAAI,UAAU,GAA6C,OAAO,aAAP,OAAO,uBAAP,OAAO,CAAE,UAAU,CAAC;QAC/E,IAAI,UAAU,KAAK,SAAS,EAAE,CAAC;YAC7B,UAAU,GAAG;gBACX,qBAAqB,EAAE,OAAO;gBAC9B,sBAAsB,EAAE,OAAO;gBAC/B,wBAAwB,EAAE,QAAQ;aACnC,CAAC;QACJ,CAAC;QACD,IAAI,KAAK,GAAwC,OAAO,aAAP,OAAO,uBAAP,OAAO,CAAE,KAAK,CAAC;QAChE,IAAI,KAAK,KAAK,SAAS,EAAE,CAAC;YACxB,KAAK,GAAG;gBACN,kBAAkB,EAAE,QAAQ;aAC7B,CAAC;QACJ,CAAC;QACD,OAAO,IAAA,kBAAO,EAAC,EAAE,OAAO,EAAE,UAAU,EAAE,KAAK,EAAE,CAAC,CAAC;IACjD,CAAC;IAED;;;;;;;;OAQG;IACI,kBAAkB,CACvB,MAAkB,EAClB,GAAe,EACf,cAA6B;QAE7B,MAAM,KAAK,GAAG,IAAI,iCAAe,CAAC,IAAI,EAAE,IAAI,CAAC,OAAO,EAAE,cAAc,CAAC,CAAC;QACtE,OAAO,IAAI,CAAC,mBAAmB,CAAC,MAAM,EAAE,GAAG,EAAE,KAAK,CAAC,CAAC,SAAS,CAAC,CAAC,MAAM,EAAE,EAAE;YACvE,OAAO,IAAI,CAAC,iBAAiB,CAAC,MAAM,EAAE,KAAK,CAAC,CAAC;QAC/C,CAAC,CAAC,CAAC;IACL,CAAC;IAED;;;;;;;;OAQG;IACI,mBAAmB,CAAC,MAAkB,EAAE,UAAwB;QACrE,OAAO,IAAI,CAAC,8BAA8B,CAAC,IAAI,CAAC,OAAO,CAAC,OAAO,EAAE,MAAM,EAAE,UAAU,CAAC,CAAC;IACvF,CAAC;IAED;;;;;;;;;OASG;IACI,8BAA8B,CACnC,OAAiC,EACjC,IAAgB,EAChB,UAAwB;QAExB,KAAK,MAAM,GAAG,IAAI,UAAU,EAAE,CAAC;YAC7B,MAAM,WAAW,GAAG,IAAI,CAAC,kBAAkB,CAAC,IAAI,EAAE,GAAG,EAAE,OAAO,CAAC,CAAC;YAChE,IAAI,WAAW,CAAC,SAAS,EAAE,EAAE,CAAC;gBAC5B,OAAO,WAAW,CAAC,iBAAiB,CAAC,OAAO,CAAC,CAAC;YAChD,CAAC;QACH,CAAC;QACD,OAAO,IAAA,4BAAiB,EAAC,IAAI,CAAC,CAAC;IACjC,CAAC;IAED;;;;;OAKG;IACI,KAAK,CAAC,GAAc,EAAE,OAAsB;QACjD,MAAM,KAAK,GAAG,IAAI,iCAAe,CAAC,IAAI,EAAE,IAAI,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC;QAC/D,IAAI,KAAK,GAAG,GAAG,CAAC;QAChB,IAAI,WAAW,GAAG,IAAI,CAAC,UAAU,CAAC,GAAG,EAAE,KAAK,CAAC,CAAC;QAE9C,OAAO,WAAW,CAAC,SAAS,EAAE,EAAE,CAAC;YAC/B,KAAK,GAAG,WAAW,CAAC,KAAK,CAAC;YAC1B,WAAW,GAAG,IAAI,CAAC,UAAU,CAAC,KAAK,EAAE,KAAK,CAAC,CAAC;QAC9C,CAAC;QAED,IAAI,WAAW,CAAC,MAAM,KAAK,OAAO,IAAI,WAAW,CAAC,MAAM,KAAK,QAAQ,EAAE,CAAC;YACtE,OAAO,WAAW,CAAC;QACrB,CAAC;QAED,IAAI,IAAA,8BAAe,EAAC,KAAK,CAAC,IAAI,KAAK,KAAK,IAAI,EAAE,CAAC;YAC7C,OAAO,IAAA,4BAAiB,EAAC,KAAK,EAAE,QAAQ,CAAC,CAAC;QAC5C,CAAC;aAAM,IAAI,IAAA,2BAAY,EAAC,KAAK,CAAC,EAAE,CAAC;YAC/B,OAAO,IAAI,CAAC,kBAAkB,CAAC,EAAE,EAAE,KAAK,EAAE,KAAK,CAAC,OAAO,CAAC,CAAC,iBAAiB,CAAC,OAAO,CAAC,CAAC;QACtF,CAAC;aAAM,IAAI,IAAA,0BAAW,EAAC,KAAK,CAAC,EAAE,CAAC;YAC9B,OAAO,IAAI,CAAC,WAAW,CAAC,KAAK,EAAE,KAAK,CAAC,OAAO,CAAC,CAAC;QAChD,CAAC;aAAM,IAAI,KAAK,KAAK,SAAS,EAAE,CAAC;YAC/B,OAAO,KAAK,CAAC,cAAc,CAAC,wBAAwB,CAAC,CAAC;QACxD,CAAC;QACD,OAAO,KAAK,CAAC,cAAc,CACzB,sBAAsB,EACtB,iCAAiC,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,GAAG,CAC1D,CAAC;IACJ,CAAC;IAED;;;;;;;OAOG;IACO,mBAAmB,CAC3B,MAAkB,EAClB,GAAe,EACf,KAAsB;QAEtB,KAAK,MAAM,GAAG,IAAI,GAAG,EAAE,CAAC;YACtB,IAAI,GAAG,CAAC,cAAc,CAAC,GAAG,CAAC,EAAE,CAAC;gBAC5B,MAAM,UAAU,GAAG,IAAI,CAAC,aAAa,CAAC,GAAG,EAAE,GAAG,CAAC,GAAG,CAAC,EAAE,KAAK,CAAC,CAAC;gBAC5D,IAAI,UAAU,CAAC,SAAS,EAAE,EAAE,CAAC;oBAC3B,IAAI,UAAU,CAAC,MAAM,KAAK,UAAU,EAAE,CAAC;wBACrC,KAAK,CAAC,KAAK,CAAC,UAAU,CAAC,KAAK,CAAC,CAAC;oBAChC,CAAC;yBAAM,CAAC;wBACN,MAAM,WAAW,GAAG,IAAI,CAAC,mBAAmB,CAAC,MAAM,EAAE,UAAU,CAAC,KAAK,EAAE,KAAK,CAAC,CAAC;wBAC9E,IAAI,WAAW,CAAC,SAAS,EAAE,EAAE,CAAC;4BAC5B,OAAO,WAAW,CAAC;wBACrB,CAAC;oBACH,CAAC;gBACH,CAAC;qBAAM,IAAI,UAAU,CAAC,MAAM,KAAK,cAAc,EAAE,CAAC;oBAChD,MAAM,WAAW,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,KAAK,CAAC,OAAO,CAAC,CAAC,SAAS,CAAC,CAAC,MAAM,EAAE,EAAE;wBAC3E,OAAO,IAAI,CAAC,oBAAoB,CAAC,MAAM,EAAE,GAAG,EAAE,MAAM,EAAE,KAAK,CAAC,CAAC;oBAC/D,CAAC,CAAC,CAAC;oBAEH,IAAI,WAAW,CAAC,SAAS,EAAE,IAAI,WAAW,CAAC,MAAM,KAAK,OAAO,EAAE,CAAC;wBAC9D,OAAO,IAAA,eAAI,EAAC,GAAG,GAAG,KAAK,WAAW,CAAC,OAAO,EAAE,CAAC,CAAC;oBAChD,CAAC;gBACH,CAAC;qBAAM,IAAI,UAAU,CAAC,MAAM,KAAK,QAAQ,EAAE,CAAC;oBAC1C,OAAO,IAAA,eAAI,EAAC,GAAG,GAAG,KAAK,UAAU,CAAC,OAAO,EAAE,CAAC,CAAC;gBAC/C,CAAC;YACH,CAAC;iBAAM,CAAC;gBACN,OAAO,IAAA,eAAI,EAAC,GAAG,GAAG,qCAAqC,CAAC,CAAC;YAC3D,CAAC;QACH,CAAC;QACD,OAAO,IAAA,kBAAO,EAAC,MAAM,CAAC,CAAC;IACzB,CAAC;IAED;;;;;;OAMG;IACO,WAAW,CACnB,GAAc,EACd,OAAsB;QAEtB,MAAM,OAAO,GAAG,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE;YAC5B,OAAO,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,OAAO,CAAC,CAAC;QAChC,CAAC,CAAC,CAAC;QAEH,OAAO,IAAA,6BAAkB,EAAmC,OAAO,EAAE,CAAC,QAAQ,CAAC,CAAC;aAC7E,SAAS,CAAC,CAAC,SAAS,EAAE,EAAE;YACvB,OAAO,IAAA,kBAAO,EAAC,SAAS,CAAC,CAAC;QAC5B,CAAC,CAAC;aACD,iBAAiB,CAAC,OAAO,CAAC,CAAC;IAChC,CAAC;IAED;;;;;;;;OAQG;IACO,oBAAoB,CAC5B,MAAkB,EAClB,GAAW,EACX,QAAmB,EACnB,KAAsB;;QAEtB,MAAM,QAAQ,GAAG,MAAM,CAAC,GAAG,CAAC,CAAC;QAE7B,gEAAgE;QAChE,sCAAsC;QAEtC,IAAI,IAAA,8BAAe,EAAC,QAAQ,CAAC,EAAE,CAAC;YAC9B,MAAM,CAAC,GAAG,CAAC,GAAG,QAAQ,CAAC;YACvB,OAAO,IAAA,4BAAiB,EAAC,QAAQ,EAAE,QAAQ,CAAC,CAAC;QAC/C,CAAC;QAED,IAAI,IAAA,2BAAY,EAAC,QAAQ,CAAC,EAAE,CAAC;YAC3B,IAAI,IAAA,2BAAY,EAAC,QAAQ,CAAC,EAAE,CAAC;gBAC3B,OAAO,IAAI,CAAC,kBAAkB,CAAC,QAAQ,EAAE,QAAQ,EAAE,KAAK,CAAC,OAAO,CAAC,CAAC,iBAAiB,CAAC,OAAO,CAAC,CAAC;YAC/F,CAAC;YACD,MAAM,CAAC,GAAG,CAAC,GAAG,QAAQ,CAAC;YACvB,OAAO,IAAA,4BAAiB,EAAC,QAAQ,EAAE,QAAQ,CAAC,CAAC;QAC/C,CAAC;QAED,oBAAoB;QACpB,IAAI,IAAA,0BAAW,EAAC,QAAQ,CAAC,EAAE,CAAC;YAC1B,IAAI,IAAA,0BAAW,EAAC,QAAQ,CAAC,EAAE,CAAC;gBAC1B,+CAA+C;gBAC/C,MAAM,kBAAkB,GAAG,MAAA,MAAA,KAAK,CAAC,OAAO,CAAC,KAAK,0CAAE,kBAAkB,mCAAI,QAAQ,CAAC;gBAC/E,QAAQ,kBAAkB,EAAE,CAAC;oBAC3B,KAAK,QAAQ;wBACX,MAAM,CAAC,GAAG,CAAC,GAAG,QAAQ,CAAC,MAAM,CAAC,GAAG,QAAQ,CAAC,CAAC;wBAC3C,MAAM;oBACR,KAAK,SAAS;wBACZ,MAAM,CAAC,GAAG,CAAC,GAAG,QAAQ,CAAC;wBACvB,MAAM;oBACR,sEAAsE;oBACtE;wBACE,OAAO,IAAA,yBAAc,EAAC,iCAAiC,kBAA4B,EAAE,EAAE,OAAO,CAAC,CAAC;gBACpG,CAAC;gBACD,OAAO,IAAA,4BAAiB,EAAC,MAAM,CAAC,GAAG,CAAC,EAAE,QAAQ,CAAC,CAAC;YAClD,CAAC;YACD,MAAM,CAAC,GAAG,CAAC,GAAG,QAAQ,CAAC;YACvB,OAAO,IAAA,4BAAiB,EAAC,QAAQ,EAAE,QAAQ,CAAC,CAAC;QAC/C,CAAC;QACD,qBAAqB;QACrB,OAAO,IAAA,yBAAc,EAAC,iBAAiB,IAAI,CAAC,SAAS,CAAC,QAAQ,CAAC,EAAE,EAAE,OAAO,CAAC,CAAC;IAC9E,CAAC,CAAC,oBAAoB;IAEtB;;;;;;;OAOG;IACO,aAAa,CACrB,GAAW,EACX,KAAgB,EAChB,KAAsB;QAEtB,KAAK,MAAM,IAAI,IAAI,IAAI,CAAC,MAAM,EAAE,CAAC;YAC/B,MAAM,UAAU,GAAG,IAAI,CAAC,YAAY,CAAC,GAAG,EAAE,KAAK,EAAE,KAAK,CAAC,CAAC;YACxD,IAAI,UAAU,CAAC,SAAS,EAAE,IAAI,UAAU,CAAC,MAAM,KAAK,cAAc,EAAE,CAAC;gBACnE,OAAO,UAAU,CAAC;YACpB,CAAC;QACH,CAAC;QACD,OAAO,IAAA,yBAAc,EAAC,cAAc,EAAE,cAAc,CAAC,CAAC;IACxD,CAAC;IAED;;;;;;OAMG;IACO,UAAU,CAClB,KAAgB,EAChB,KAAsB;QAEtB,KAAK,MAAM,IAAI,IAAI,IAAI,CAAC,MAAM,EAAE,CAAC;YAC/B,MAAM,UAAU,GAAG,IAAI,CAAC,SAAS,CAAC,KAAK,EAAE,KAAK,CAAC,CAAC;YAChD,IAAI,UAAU,CAAC,SAAS,EAAE,IAAI,UAAU,CAAC,MAAM,KAAK,cAAc,EAAE,CAAC;gBACnE,OAAO,UAAU,CAAC;YACpB,CAAC;QACH,CAAC;QACD,OAAO,IAAA,yBAAc,EAAC,cAAc,EAAE,cAAc,CAAC,CAAC;IACxD,CAAC;IAED;;;;;;OAMG;IACO,iBAAiB,CACzB,MAAkB,EAClB,KAAsB;QAEtB,MAAM,QAAQ,GAAG,KAAK,CAAC,QAAQ,CAAC;QAChC,IAAI,QAAQ,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YACxB,KAAK,MAAM,IAAI,IAAI,IAAI,CAAC,MAAM,EAAE,CAAC;gBAC/B,MAAM,UAAU,GAAG,IAAI,CAAC,kBAAkB,CAAC,QAAQ,EAAE,KAAK,CAAC,CAAC;gBAC5D,IAAI,UAAU,CAAC,SAAS,EAAE,EAAE,CAAC;oBAC3B,OAAO,IAAI,CAAC,8BAA8B,CACxC,KAAK,CAAC,OAAO,EACb,MAAM,EACN,UAAU,CAAC,KAAK,CACjB,CAAC,iBAAiB,CAAC,OAAO,CAAC,CAAC;gBAC/B,CAAC;qBAAM,IAAI,UAAU,CAAC,MAAM,KAAK,QAAQ,EAAE,CAAC;oBAC1C,IAAA,4BAAiB,EAAC,MAAM,EAAE,QAAQ,CAAC,CAAC;gBACtC,CAAC;qBAAM,IAAI,UAAU,CAAC,MAAM,KAAK,cAAc,EAAE,CAAC;oBAChD,OAAO,IAAA,yBAAc,EAAC,UAAU,CAAC,OAAO,EAAE,UAAU,CAAC,MAAM,CAAC,CAAC;gBAC/D,CAAC;YACH,CAAC;QACH,CAAC;QACD,OAAO,IAAA,4BAAiB,EAAC,MAAM,EAAE,QAAQ,CAAC,CAAC;IAC7C,CAAC;CACF;AA7XD,gCA6XC","sourcesContent":["/*\n * Copyright (c) 2020 Erik Fortune\n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to deal\n * in the Software without restriction, including without limitation the rights\n * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n * copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in all\n * copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n * SOFTWARE.\n */\n\nimport {\n DetailedResult,\n Result,\n captureResult,\n fail,\n failWithDetail,\n mapDetailedResults,\n mapResults,\n succeed,\n succeedWithDetail\n} from '@fgv/ts-utils';\nimport {\n ConditionalJsonEditorRule,\n MultiValueJsonEditorRule,\n ReferenceJsonEditorRule,\n TemplatedJsonEditorRule\n} from './rules';\n\nimport {\n JsonArray,\n JsonObject,\n JsonValue,\n isJsonArray,\n isJsonObject,\n isJsonPrimitive\n} from '@fgv/ts-json-base';\nimport { IJsonContext } from '../context';\nimport {\n IJsonCloneEditor,\n IJsonEditorMergeOptions,\n IJsonEditorOptions,\n IJsonEditorValidationOptions,\n JsonEditFailureReason,\n JsonPropertyEditFailureReason\n} from './common';\n\nimport { IJsonEditorRule } from './jsonEditorRule';\nimport { JsonEditorState } from './jsonEditorState';\n\n/**\n * A {@link JsonEditor | JsonEditor} can be used to edit JSON objects in place or to\n * clone any JSON value, applying a default context and optional set of editor rules that\n * were supplied at initialization.\n * @public\n */\nexport class JsonEditor implements IJsonCloneEditor {\n /**\n * Default singleton {@link JsonEditor | JsonEditor}.\n * @internal\n */\n protected static _default?: JsonEditor;\n\n /**\n * Full set of {@link IJsonEditorOptions | editor options} in effect for this editor.\n */\n public options: IJsonEditorOptions;\n\n /**\n * The set of {@link IJsonEditorRule | editor rules} applied by this editor.\n * @internal\n */\n protected _rules: IJsonEditorRule[];\n\n /**\n * Protected constructor for {@link JsonEditor | JsonEditor} and derived classes.\n * External consumers should instantiate via the {@link JsonEditor.create | create static method}.\n * @param options - Optional partial {@link IJsonEditorOptions | editor options} for the\n * constructed editor.\n * @param rules - Any {@link IJsonEditorRule | editor rules} to be applied by the editor.\n * @internal\n */\n protected constructor(options?: Partial<IJsonEditorOptions>, rules?: IJsonEditorRule[]) {\n this.options = JsonEditor._getDefaultOptions(options).orThrow();\n this._rules = rules || JsonEditor.getDefaultRules(this.options).orThrow();\n }\n\n /**\n * Default singleton {@link JsonEditor | JsonEditor} for simple use. Applies all rules\n * but with no default context.\n */\n public static get default(): JsonEditor {\n if (!JsonEditor._default) {\n const rules = this.getDefaultRules().orDefault();\n JsonEditor._default = new JsonEditor(undefined, rules);\n }\n return JsonEditor._default;\n }\n\n /**\n * Constructs a new {@link JsonEditor | JsonEditor}.\n * @param options - Optional partial {@link IJsonEditorOptions | editor options} for the\n * constructed editor.\n * @param rules - Optional set of {@link IJsonEditorRule | editor rules} to be applied by the editor.\n * @readonly A new {@link JsonEditor | JsonEditor}.\n */\n public static create(options?: Partial<IJsonEditorOptions>, rules?: IJsonEditorRule[]): Result<JsonEditor> {\n return captureResult(() => new JsonEditor(options, rules));\n }\n\n /**\n * Gets the default set of rules to be applied for a given set of options.\n * By default, all available rules (templates, conditionals, multi-value and references)\n * are applied.\n * @param options - Optional partial {@link IJsonEditorOptions | editor options} for\n * all rules.\n * @returns Default {@link IJsonEditorRule | editor rules} with any supplied options\n * applied.\n */\n public static getDefaultRules(options?: IJsonEditorOptions): Result<IJsonEditorRule[]> {\n return mapResults<IJsonEditorRule>([\n TemplatedJsonEditorRule.create(options),\n ConditionalJsonEditorRule.create(options),\n MultiValueJsonEditorRule.create(options),\n ReferenceJsonEditorRule.create(options)\n ]);\n }\n\n /**\n * @internal\n */\n protected static _getDefaultOptions(options?: Partial<IJsonEditorOptions>): Result<IJsonEditorOptions> {\n const context: IJsonContext | undefined = options?.context;\n let validation: IJsonEditorValidationOptions | undefined = options?.validation;\n if (validation === undefined) {\n validation = {\n onInvalidPropertyName: 'error',\n onInvalidPropertyValue: 'error',\n onUndefinedPropertyValue: 'ignore'\n };\n }\n let merge: IJsonEditorMergeOptions | undefined = options?.merge;\n if (merge === undefined) {\n merge = {\n arrayMergeBehavior: 'append'\n };\n }\n return succeed({ context, validation, merge });\n }\n\n /**\n * Merges a supplied source object into a supplied target, updating the target object.\n * @param target - The target `JsonObject` to be updated\n * @param src - The source `JsonObject` to be merged\n * @param runtimeContext - An optional {@link IJsonContext | IJsonContext} supplying variables\n * and references.\n * @returns `Success` with the original source `JsonObject` if merge was successful.\n * Returns `Failure` with details if an error occurs.\n */\n public mergeObjectInPlace(\n target: JsonObject,\n src: JsonObject,\n runtimeContext?: IJsonContext\n ): Result<JsonObject> {\n const state = new JsonEditorState(this, this.options, runtimeContext);\n return this._mergeObjectInPlace(target, src, state).onSuccess((merged) => {\n return this._finalizeAndMerge(merged, state);\n });\n }\n\n /**\n * Merges multiple supplied source objects into a supplied target, updating the target\n * object and using the default context supplied at creation time.\n * @param target - The target `JsonObject` to be updated\n * @param srcObjects - `JsonObject`s to be merged into the target object, in the order\n * supplied.\n * @returns `Success` with the original source `JsonObject` if merge was successful.\n * Returns `Failure` with details if an error occurs.\n */\n public mergeObjectsInPlace(target: JsonObject, srcObjects: JsonObject[]): Result<JsonObject> {\n return this.mergeObjectsInPlaceWithContext(this.options.context, target, srcObjects);\n }\n\n /**\n * Merges multiple supplied source objects into a supplied target, updating the target\n * object and using an optional {@link IJsonContext | context} supplied in the call.\n * @param context - An optional {@link IJsonContext | IJsonContext} supplying variables and\n * references.\n * @param base - The base `JsonObject` to be updated\n * @param srcObjects - Objects to be merged into the target object, in the order supplied.\n * @returns `Success` with the original source `JsonObject` if merge was successful.\n * Returns `Failure` with details if an error occurs.\n */\n public mergeObjectsInPlaceWithContext(\n context: IJsonContext | undefined,\n base: JsonObject,\n srcObjects: JsonObject[]\n ): Result<JsonObject> {\n for (const src of srcObjects) {\n const mergeResult = this.mergeObjectInPlace(base, src, context);\n if (mergeResult.isFailure()) {\n return mergeResult.withFailureDetail('error');\n }\n }\n return succeedWithDetail(base);\n }\n\n /**\n * Deep clones a supplied `JsonValue`, applying all editor rules and a default\n * or optionally supplied context\n * @param src - The `JsonValue` to be cloned.\n * @param context - An optional {@link IJsonContext | JSON context} supplying variables and references.\n */\n public clone(src: JsonValue, context?: IJsonContext): DetailedResult<JsonValue, JsonEditFailureReason> {\n const state = new JsonEditorState(this, this.options, context);\n let value = src;\n let valueResult = this._editValue(src, state);\n\n while (valueResult.isSuccess()) {\n value = valueResult.value;\n valueResult = this._editValue(value, state);\n }\n\n if (valueResult.detail === 'error' || valueResult.detail === 'ignore') {\n return valueResult;\n }\n\n if (isJsonPrimitive(value) || value === null) {\n return succeedWithDetail(value, 'edited');\n } else if (isJsonObject(value)) {\n return this.mergeObjectInPlace({}, value, state.context).withFailureDetail('error');\n } else if (isJsonArray(value)) {\n return this._cloneArray(value, state.context);\n } else if (value === undefined) {\n return state.failValidation('undefinedPropertyValue');\n }\n return state.failValidation(\n 'invalidPropertyValue',\n `Cannot convert invalid JSON: \"${JSON.stringify(value)}\"`\n );\n }\n\n /**\n *\n * @param target -\n * @param src -\n * @param state -\n * @returns\n * @internal\n */\n protected _mergeObjectInPlace(\n target: JsonObject,\n src: JsonObject,\n state: JsonEditorState\n ): Result<JsonObject> {\n for (const key in src) {\n if (src.hasOwnProperty(key)) {\n const propResult = this._editProperty(key, src[key], state);\n if (propResult.isSuccess()) {\n if (propResult.detail === 'deferred') {\n state.defer(propResult.value);\n } else {\n const mergeResult = this._mergeObjectInPlace(target, propResult.value, state);\n if (mergeResult.isFailure()) {\n return mergeResult;\n }\n }\n } else if (propResult.detail === 'inapplicable') {\n const valueResult = this.clone(src[key], state.context).onSuccess((cloned) => {\n return this._mergeClonedProperty(target, key, cloned, state);\n });\n\n if (valueResult.isFailure() && valueResult.detail === 'error') {\n return fail(`${key}: ${valueResult.message}`);\n }\n } else if (propResult.detail !== 'ignore') {\n return fail(`${key}: ${propResult.message}`);\n }\n } else {\n return fail(`${key}: Cannot merge inherited properties`);\n }\n }\n return succeed(target);\n }\n\n /**\n *\n * @param src -\n * @param context -\n * @returns\n * @internal\n */\n protected _cloneArray(\n src: JsonArray,\n context?: IJsonContext\n ): DetailedResult<JsonArray, JsonEditFailureReason> {\n const results = src.map((v) => {\n return this.clone(v, context);\n });\n\n return mapDetailedResults<JsonValue, JsonEditFailureReason>(results, ['ignore'])\n .onSuccess((converted) => {\n return succeed(converted);\n })\n .withFailureDetail('error');\n }\n\n /**\n *\n * @param target -\n * @param key -\n * @param newValue -\n * @param state -\n * @returns\n * @internal\n */\n protected _mergeClonedProperty(\n target: JsonObject,\n key: string,\n newValue: JsonValue,\n state: JsonEditorState\n ): DetailedResult<JsonValue, JsonEditFailureReason> {\n const existing = target[key];\n\n // merge is called right after clone so this should never happen\n // since clone itself will have failed\n\n if (isJsonPrimitive(newValue)) {\n target[key] = newValue;\n return succeedWithDetail(newValue, 'edited');\n }\n\n if (isJsonObject(newValue)) {\n if (isJsonObject(existing)) {\n return this.mergeObjectInPlace(existing, newValue, state.context).withFailureDetail('error');\n }\n target[key] = newValue;\n return succeedWithDetail(newValue, 'edited');\n }\n\n /* c8 ignore else */\n if (isJsonArray(newValue)) {\n if (isJsonArray(existing)) {\n /* c8 ignore next 1 - ?? is defense in depth */\n const arrayMergeBehavior = state.options.merge?.arrayMergeBehavior ?? 'append';\n switch (arrayMergeBehavior) {\n case 'append':\n target[key] = existing.concat(...newValue);\n break;\n case 'replace':\n target[key] = newValue;\n break;\n /* c8 ignore next 2 - exhaustive switch for ArrayMergeBehavior type */\n default:\n return failWithDetail(`Invalid array merge behavior: ${arrayMergeBehavior as string}`, 'error');\n }\n return succeedWithDetail(target[key], 'edited');\n }\n target[key] = newValue;\n return succeedWithDetail(newValue, 'edited');\n }\n /* c8 ignore start */\n return failWithDetail(`Invalid JSON: ${JSON.stringify(newValue)}`, 'error');\n } /* c8 ignore stop */\n\n /**\n *\n * @param key -\n * @param value -\n * @param state -\n * @returns\n * @internal\n */\n protected _editProperty(\n key: string,\n value: JsonValue,\n state: JsonEditorState\n ): DetailedResult<JsonObject, JsonPropertyEditFailureReason> {\n for (const rule of this._rules) {\n const ruleResult = rule.editProperty(key, value, state);\n if (ruleResult.isSuccess() || ruleResult.detail !== 'inapplicable') {\n return ruleResult;\n }\n }\n return failWithDetail('inapplicable', 'inapplicable');\n }\n\n /**\n *\n * @param value -\n * @param state -\n * @returns\n * @internal\n */\n protected _editValue(\n value: JsonValue,\n state: JsonEditorState\n ): DetailedResult<JsonValue, JsonEditFailureReason> {\n for (const rule of this._rules) {\n const ruleResult = rule.editValue(value, state);\n if (ruleResult.isSuccess() || ruleResult.detail !== 'inapplicable') {\n return ruleResult;\n }\n }\n return failWithDetail('inapplicable', 'inapplicable');\n }\n\n /**\n *\n * @param target -\n * @param state -\n * @returns\n * @internal\n */\n protected _finalizeAndMerge(\n target: JsonObject,\n state: JsonEditorState\n ): DetailedResult<JsonObject, JsonEditFailureReason> {\n const deferred = state.deferred;\n if (deferred.length > 0) {\n for (const rule of this._rules) {\n const ruleResult = rule.finalizeProperties(deferred, state);\n if (ruleResult.isSuccess()) {\n return this.mergeObjectsInPlaceWithContext(\n state.context,\n target,\n ruleResult.value\n ).withFailureDetail('error');\n } else if (ruleResult.detail === 'ignore') {\n succeedWithDetail(target, 'edited');\n } else if (ruleResult.detail !== 'inapplicable') {\n return failWithDetail(ruleResult.message, ruleResult.detail);\n }\n }\n }\n return succeedWithDetail(target, 'edited');\n }\n}\n"]}
|
|
1
|
+
{"version":3,"file":"jsonEditor.js","sourceRoot":"","sources":["../../../src/packlets/editor/jsonEditor.ts"],"names":[],"mappings":"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","sourcesContent":["/*\n * Copyright (c) 2020 Erik Fortune\n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to deal\n * in the Software without restriction, including without limitation the rights\n * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n * copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in all\n * copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n * SOFTWARE.\n */\n\nimport {\n DetailedResult,\n Result,\n captureResult,\n fail,\n failWithDetail,\n mapDetailedResults,\n mapResults,\n succeed,\n succeedWithDetail\n} from '@fgv/ts-utils';\nimport {\n ConditionalJsonEditorRule,\n MultiValueJsonEditorRule,\n ReferenceJsonEditorRule,\n TemplatedJsonEditorRule\n} from './rules';\n\nimport {\n JsonArray,\n JsonObject,\n JsonValue,\n isJsonArray,\n isJsonObject,\n isJsonPrimitive\n} from '@fgv/ts-json-base';\nimport { IJsonContext } from '../context';\nimport {\n IJsonCloneEditor,\n IJsonEditorMergeOptions,\n IJsonEditorOptions,\n IJsonEditorValidationOptions,\n JsonEditFailureReason,\n JsonPropertyEditFailureReason\n} from './common';\n\nimport { IJsonEditorRule } from './jsonEditorRule';\nimport { JsonEditorState } from './jsonEditorState';\n\n/**\n * A {@link JsonEditor | JsonEditor} can be used to edit JSON objects in place or to\n * clone any JSON value, applying a default context and optional set of editor rules that\n * were supplied at initialization.\n * @public\n */\nexport class JsonEditor implements IJsonCloneEditor {\n /**\n * Default singleton {@link JsonEditor | JsonEditor}.\n * @internal\n */\n protected static _default?: JsonEditor;\n\n /**\n * Full set of {@link IJsonEditorOptions | editor options} in effect for this editor.\n */\n public options: IJsonEditorOptions;\n\n /**\n * The set of {@link IJsonEditorRule | editor rules} applied by this editor.\n * @internal\n */\n protected _rules: IJsonEditorRule[];\n\n /**\n * Protected constructor for {@link JsonEditor | JsonEditor} and derived classes.\n * External consumers should instantiate via the {@link JsonEditor.create | create static method}.\n * @param options - Optional partial {@link IJsonEditorOptions | editor options} for the\n * constructed editor.\n * @param rules - Any {@link IJsonEditorRule | editor rules} to be applied by the editor.\n * @internal\n */\n protected constructor(options?: Partial<IJsonEditorOptions>, rules?: IJsonEditorRule[]) {\n this.options = JsonEditor._getDefaultOptions(options).orThrow();\n this._rules = rules || JsonEditor.getDefaultRules(this.options).orThrow();\n }\n\n /**\n * Default singleton {@link JsonEditor | JsonEditor} for simple use. Applies all rules\n * but with no default context.\n */\n public static get default(): JsonEditor {\n if (!JsonEditor._default) {\n const rules = this.getDefaultRules().orDefault();\n JsonEditor._default = new JsonEditor(undefined, rules);\n }\n return JsonEditor._default;\n }\n\n /**\n * Constructs a new {@link JsonEditor | JsonEditor}.\n * @param options - Optional partial {@link IJsonEditorOptions | editor options} for the\n * constructed editor.\n * @param rules - Optional set of {@link IJsonEditorRule | editor rules} to be applied by the editor.\n * @readonly A new {@link JsonEditor | JsonEditor}.\n */\n public static create(options?: Partial<IJsonEditorOptions>, rules?: IJsonEditorRule[]): Result<JsonEditor> {\n return captureResult(() => new JsonEditor(options, rules));\n }\n\n /**\n * Gets the default set of rules to be applied for a given set of options.\n * By default, all available rules (templates, conditionals, multi-value and references)\n * are applied.\n * @param options - Optional partial {@link IJsonEditorOptions | editor options} for\n * all rules.\n * @returns Default {@link IJsonEditorRule | editor rules} with any supplied options\n * applied.\n */\n public static getDefaultRules(options?: IJsonEditorOptions): Result<IJsonEditorRule[]> {\n return mapResults<IJsonEditorRule>([\n TemplatedJsonEditorRule.create(options),\n ConditionalJsonEditorRule.create(options),\n MultiValueJsonEditorRule.create(options),\n ReferenceJsonEditorRule.create(options)\n ]);\n }\n\n /**\n * Creates a complete IJsonEditorOptions object from partial options, filling in\n * default values for any missing properties. This ensures all editor instances\n * have consistent, complete configuration including validation rules and merge behavior.\n * @param options - Optional partial editor options to merge with defaults\n * @returns Success with complete editor options, or Failure if validation fails\n * @internal\n */\n protected static _getDefaultOptions(options?: Partial<IJsonEditorOptions>): Result<IJsonEditorOptions> {\n const context: IJsonContext | undefined = options?.context;\n let validation: IJsonEditorValidationOptions | undefined = options?.validation;\n if (validation === undefined) {\n validation = {\n onInvalidPropertyName: 'error',\n onInvalidPropertyValue: 'error',\n onUndefinedPropertyValue: 'ignore'\n };\n }\n let merge: IJsonEditorMergeOptions | undefined = options?.merge;\n if (merge === undefined) {\n merge = {\n arrayMergeBehavior: 'append',\n nullAsDelete: false\n };\n } else {\n merge = {\n arrayMergeBehavior: merge.arrayMergeBehavior,\n nullAsDelete: merge.nullAsDelete ?? false\n };\n }\n return succeed({ context, validation, merge });\n }\n\n /**\n * Merges a supplied source object into a supplied target, updating the target object.\n * @param target - The target `JsonObject` to be updated\n * @param src - The source `JsonObject` to be merged\n * @param runtimeContext - An optional {@link IJsonContext | IJsonContext} supplying variables\n * and references.\n * @returns `Success` with the original source `JsonObject` if merge was successful.\n * Returns `Failure` with details if an error occurs.\n */\n public mergeObjectInPlace(\n target: JsonObject,\n src: JsonObject,\n runtimeContext?: IJsonContext\n ): Result<JsonObject> {\n const state = new JsonEditorState(this, this.options, runtimeContext);\n return this._mergeObjectInPlace(target, src, state).onSuccess((merged) => {\n return this._finalizeAndMerge(merged, state);\n });\n }\n\n /**\n * Merges multiple supplied source objects into a supplied target, updating the target\n * object and using the default context supplied at creation time.\n * @param target - The target `JsonObject` to be updated\n * @param srcObjects - `JsonObject`s to be merged into the target object, in the order\n * supplied.\n * @returns `Success` with the original source `JsonObject` if merge was successful.\n * Returns `Failure` with details if an error occurs.\n */\n public mergeObjectsInPlace(target: JsonObject, srcObjects: JsonObject[]): Result<JsonObject> {\n return this.mergeObjectsInPlaceWithContext(this.options.context, target, srcObjects);\n }\n\n /**\n * Merges multiple supplied source objects into a supplied target, updating the target\n * object and using an optional {@link IJsonContext | context} supplied in the call.\n * @param context - An optional {@link IJsonContext | IJsonContext} supplying variables and\n * references.\n * @param base - The base `JsonObject` to be updated\n * @param srcObjects - Objects to be merged into the target object, in the order supplied.\n * @returns `Success` with the original source `JsonObject` if merge was successful.\n * Returns `Failure` with details if an error occurs.\n */\n public mergeObjectsInPlaceWithContext(\n context: IJsonContext | undefined,\n base: JsonObject,\n srcObjects: JsonObject[]\n ): Result<JsonObject> {\n for (const src of srcObjects) {\n const mergeResult = this.mergeObjectInPlace(base, src, context);\n if (mergeResult.isFailure()) {\n return mergeResult.withFailureDetail('error');\n }\n }\n return succeedWithDetail(base);\n }\n\n /**\n * Deep clones a supplied `JsonValue`, applying all editor rules and a default\n * or optionally supplied context\n * @param src - The `JsonValue` to be cloned.\n * @param context - An optional {@link IJsonContext | JSON context} supplying variables and references.\n */\n public clone(src: JsonValue, context?: IJsonContext): DetailedResult<JsonValue, JsonEditFailureReason> {\n const state = new JsonEditorState(this, this.options, context);\n let value = src;\n let valueResult = this._editValue(src, state);\n\n while (valueResult.isSuccess()) {\n value = valueResult.value;\n valueResult = this._editValue(value, state);\n }\n\n if (valueResult.detail === 'error' || valueResult.detail === 'ignore') {\n return valueResult;\n }\n\n if (isJsonPrimitive(value) || value === null) {\n return succeedWithDetail(value, 'edited');\n } else if (isJsonObject(value)) {\n return this._cloneObjectWithoutNullAsDelete({}, value, state);\n } else if (isJsonArray(value)) {\n return this._cloneArray(value, state.context);\n } else if (value === undefined) {\n return state.failValidation('undefinedPropertyValue');\n }\n return state.failValidation(\n 'invalidPropertyValue',\n `Cannot convert invalid JSON: \"${JSON.stringify(value)}\"`\n );\n }\n\n /**\n * Merges properties from a source object into a target object, applying editor rules and\n * null-as-delete logic. This is the core merge implementation that handles property-by-property\n * merging with rule processing and deferred property handling.\n * @param target - The target object to merge properties into\n * @param src - The source object containing properties to merge\n * @param state - The editor state containing options and context\n * @returns Success with the modified target object, or Failure with error details\n * @internal\n */\n protected _mergeObjectInPlace(\n target: JsonObject,\n src: JsonObject,\n state: JsonEditorState\n ): Result<JsonObject> {\n for (const key in src) {\n if (src.hasOwnProperty(key)) {\n // Skip dangerous property names to prevent prototype pollution\n if (key === '__proto__' || key === 'constructor' || key === 'prototype') {\n continue;\n }\n const propResult = this._editProperty(key, src[key], state);\n if (propResult.isSuccess()) {\n if (propResult.detail === 'deferred') {\n state.defer(propResult.value);\n } else {\n const mergeResult = this._mergeObjectInPlace(target, propResult.value, state);\n if (mergeResult.isFailure()) {\n return mergeResult;\n }\n }\n } else if (propResult.detail === 'inapplicable') {\n const valueResult = this.clone(src[key], state.context).onSuccess((cloned) => {\n return this._mergeClonedProperty(target, key, cloned, state);\n });\n\n if (valueResult.isFailure() && valueResult.detail === 'error') {\n return fail(`${key}: ${valueResult.message}`);\n }\n } else if (propResult.detail !== 'ignore') {\n return fail(`${key}: ${propResult.message}`);\n }\n } else {\n return fail(`${key}: Cannot merge inherited properties`);\n }\n }\n return succeed(target);\n }\n\n /**\n * Creates a deep clone of a JSON array by recursively cloning each element.\n * Each array element is cloned using the main clone method, preserving the\n * editor's rules and validation settings.\n * @param src - The source JSON array to clone\n * @param context - Optional JSON context for cloning operations\n * @returns Success with the cloned array, or Failure with error details\n * @internal\n */\n protected _cloneArray(\n src: JsonArray,\n context?: IJsonContext\n ): DetailedResult<JsonArray, JsonEditFailureReason> {\n const results = src.map((v) => {\n return this.clone(v, context);\n });\n\n return mapDetailedResults<JsonValue, JsonEditFailureReason>(results, ['ignore'])\n .onSuccess((converted) => {\n return succeed(converted);\n })\n .withFailureDetail('error');\n }\n\n /**\n * Merges a single cloned property value into a target object. This method handles\n * the core merge logic including null-as-delete behavior, array merging, and\n * recursive object merging. The null-as-delete check occurs before primitive\n * handling to ensure null values can signal property deletion.\n * @param target - The target object to merge the property into\n * @param key - The property key being merged\n * @param newValue - The cloned value to merge (from source object)\n * @param state - The editor state containing merge options and context\n * @returns Success with the merged value, or Failure with error details\n * @internal\n */\n protected _mergeClonedProperty(\n target: JsonObject,\n key: string,\n newValue: JsonValue,\n state: JsonEditorState\n ): DetailedResult<JsonValue, JsonEditFailureReason> {\n // Skip dangerous property names to prevent prototype pollution\n if (key === '__proto__' || key === 'constructor' || key === 'prototype') {\n return succeedWithDetail(newValue, 'edited');\n }\n\n const existing = target[key];\n\n // Handle null-as-delete behavior before primitive check\n /* c8 ignore next 1 - ? is defense in depth */\n if (newValue === null && state.options.merge?.nullAsDelete === true) {\n delete target[key];\n return succeedWithDetail(null, 'edited');\n }\n\n // merge is called right after clone so this should never happen\n // since clone itself will have failed\n\n if (isJsonPrimitive(newValue)) {\n target[key] = newValue;\n return succeedWithDetail(newValue, 'edited');\n }\n\n if (isJsonObject(newValue)) {\n if (isJsonObject(existing)) {\n return this.mergeObjectInPlace(existing, newValue, state.context).withFailureDetail('error');\n }\n target[key] = newValue;\n return succeedWithDetail(newValue, 'edited');\n }\n\n /* c8 ignore else */\n if (isJsonArray(newValue)) {\n if (isJsonArray(existing)) {\n /* c8 ignore next 1 - ?? is defense in depth */\n const arrayMergeBehavior = state.options.merge?.arrayMergeBehavior ?? 'append';\n switch (arrayMergeBehavior) {\n case 'append':\n target[key] = existing.concat(...newValue);\n break;\n case 'replace':\n target[key] = newValue;\n break;\n /* c8 ignore next 2 - exhaustive switch for ArrayMergeBehavior type */\n default:\n return failWithDetail(`Invalid array merge behavior: ${arrayMergeBehavior as string}`, 'error');\n }\n return succeedWithDetail(target[key], 'edited');\n }\n target[key] = newValue;\n return succeedWithDetail(newValue, 'edited');\n }\n /* c8 ignore start */\n return failWithDetail(`Invalid JSON: ${JSON.stringify(newValue)}`, 'error');\n } /* c8 ignore stop */\n\n /**\n * Applies editor rules to a single property during merge operations. This method\n * iterates through all configured editor rules to process the property, handling\n * templates, conditionals, multi-value properties, and references.\n * @param key - The property key to edit\n * @param value - The property value to edit\n * @param state - The editor state containing rules and context\n * @returns Success with transformed property object, or Failure if rules cannot process\n * @internal\n */\n protected _editProperty(\n key: string,\n value: JsonValue,\n state: JsonEditorState\n ): DetailedResult<JsonObject, JsonPropertyEditFailureReason> {\n for (const rule of this._rules) {\n const ruleResult = rule.editProperty(key, value, state);\n if (ruleResult.isSuccess() || ruleResult.detail !== 'inapplicable') {\n return ruleResult;\n }\n }\n return failWithDetail('inapplicable', 'inapplicable');\n }\n\n /**\n * Applies editor rules to a single JSON value during clone operations. This method\n * iterates through all configured editor rules to process the value, handling\n * templates, conditionals, multi-value expressions, and references.\n * @param value - The JSON value to edit and transform\n * @param state - The editor state containing rules and context\n * @returns Success with transformed value, or Failure if rules cannot process\n * @internal\n */\n protected _editValue(\n value: JsonValue,\n state: JsonEditorState\n ): DetailedResult<JsonValue, JsonEditFailureReason> {\n for (const rule of this._rules) {\n const ruleResult = rule.editValue(value, state);\n if (ruleResult.isSuccess() || ruleResult.detail !== 'inapplicable') {\n return ruleResult;\n }\n }\n return failWithDetail('inapplicable', 'inapplicable');\n }\n\n /**\n * Clone an object without applying null-as-delete behavior.\n * This preserves null values during cloning so they can be used for deletion signaling during merge.\n * @param target - The target object to clone into\n * @param src - The source object to clone\n * @param state - The editor state\n * @returns The cloned object\n * @internal\n */\n protected _cloneObjectWithoutNullAsDelete(\n target: JsonObject,\n src: JsonObject,\n state: JsonEditorState\n ): DetailedResult<JsonObject, JsonEditFailureReason> {\n // Temporarily disable null-as-delete during cloning\n const modifiedOptions: IJsonEditorOptions = {\n context: state.options.context,\n validation: state.options.validation,\n merge: {\n /* c8 ignore next 1 - ? is defense in depth */\n arrayMergeBehavior: state.options.merge?.arrayMergeBehavior ?? 'append',\n nullAsDelete: false\n }\n };\n const modifiedState = new JsonEditorState(state.editor, modifiedOptions, state.context);\n\n return this._mergeObjectInPlace(target, src, modifiedState)\n .onSuccess((merged) => {\n return this._finalizeAndMerge(merged, modifiedState);\n })\n .withFailureDetail('error');\n }\n\n /**\n * Finalizes the merge operation by processing any deferred properties and merging\n * them into the target object. Deferred properties are those that require special\n * processing after the initial merge phase, such as references that depend on\n * other properties being resolved first.\n * @param target - The target object that has been merged\n * @param state - The editor state containing deferred properties and rules\n * @returns Success with the finalized target object, or Failure with error details\n * @internal\n */\n protected _finalizeAndMerge(\n target: JsonObject,\n state: JsonEditorState\n ): DetailedResult<JsonObject, JsonEditFailureReason> {\n const deferred = state.deferred;\n if (deferred.length > 0) {\n for (const rule of this._rules) {\n const ruleResult = rule.finalizeProperties(deferred, state);\n if (ruleResult.isSuccess()) {\n return this.mergeObjectsInPlaceWithContext(\n state.context,\n target,\n ruleResult.value\n ).withFailureDetail('error');\n } else if (ruleResult.detail === 'ignore') {\n succeedWithDetail(target, 'edited');\n } else if (ruleResult.detail !== 'inapplicable') {\n return failWithDetail(ruleResult.message, ruleResult.detail);\n }\n }\n }\n return succeedWithDetail(target, 'edited');\n }\n}\n"]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@fgv/ts-json",
|
|
3
|
-
"version": "5.0.0-
|
|
3
|
+
"version": "5.0.0-9",
|
|
4
4
|
"description": "Typescript utilities for working with JSON",
|
|
5
5
|
"main": "lib/index.js",
|
|
6
6
|
"types": "dist/ts-json.d.ts",
|
|
@@ -40,14 +40,14 @@
|
|
|
40
40
|
"@microsoft/api-documenter": "^7.26.29",
|
|
41
41
|
"@rushstack/eslint-config": "~4.4.0",
|
|
42
42
|
"eslint-plugin-tsdoc": "~0.4.0",
|
|
43
|
-
"@fgv/ts-utils": "5.0.0-
|
|
44
|
-
"@fgv/ts-
|
|
45
|
-
"@fgv/ts-
|
|
43
|
+
"@fgv/ts-utils-jest": "5.0.0-9",
|
|
44
|
+
"@fgv/ts-json-base": "5.0.0-9",
|
|
45
|
+
"@fgv/ts-utils": "5.0.0-9"
|
|
46
46
|
},
|
|
47
47
|
"peerDependencies": {
|
|
48
48
|
"mustache": "^4.2.0",
|
|
49
|
-
"@fgv/ts-
|
|
50
|
-
"@fgv/ts-
|
|
49
|
+
"@fgv/ts-utils": "5.0.0-9",
|
|
50
|
+
"@fgv/ts-json-base": "5.0.0-9"
|
|
51
51
|
},
|
|
52
52
|
"scripts": {
|
|
53
53
|
"build": "heft build --clean",
|