@fgv/ts-json 5.0.0-2 → 5.0.0-21

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.
Files changed (94) hide show
  1. package/.vscode/launch.json +16 -0
  2. package/.vscode/settings.json +32 -0
  3. package/config/api-extractor.json +343 -0
  4. package/config/rig.json +16 -0
  5. package/dist/ts-json.d.ts +719 -28
  6. package/dist/tsdoc-metadata.json +1 -1
  7. package/lib/index.d.ts +2 -0
  8. package/lib/index.js +25 -0
  9. package/lib/packlets/diff/detailedDiff.d.ts +375 -0
  10. package/lib/packlets/diff/detailedDiff.js +342 -0
  11. package/lib/packlets/diff/index.d.ts +3 -0
  12. package/lib/packlets/diff/index.js +40 -0
  13. package/lib/packlets/diff/threeWayDiff.d.ts +263 -0
  14. package/lib/packlets/diff/threeWayDiff.js +261 -0
  15. package/lib/packlets/diff/utils.d.ts +6 -0
  16. package/lib/packlets/diff/utils.js +62 -0
  17. package/lib/packlets/editor/common.d.ts +6 -0
  18. package/lib/packlets/editor/jsonEditor.d.ts +57 -28
  19. package/lib/packlets/editor/jsonEditor.js +101 -32
  20. package/lib/test/legacy/jsonConverter.conditional.test.d.ts +2 -0
  21. package/lib/test/legacy/jsonEditor/rules/conditional.test.d.ts +2 -0
  22. package/lib/test/legacy/jsonEditor/rules/multivalue.test.d.ts +2 -0
  23. package/lib/test/legacy/jsonEditor/rules/references.test.d.ts +2 -0
  24. package/lib/test/legacy/jsonEditor/rules/templates.test.d.ts +2 -0
  25. package/lib/test/unit/contextHelpers.test.d.ts +2 -0
  26. package/lib/test/unit/converters.test.d.ts +2 -0
  27. package/lib/test/unit/diff/jsonDiff.test.d.ts +2 -0
  28. package/lib/test/unit/jsonConverter.test.d.ts +2 -0
  29. package/lib/test/unit/jsonEditor/jsonEditor.test.d.ts +2 -0
  30. package/lib/test/unit/jsonEditor/templateContext.test.d.ts +2 -0
  31. package/lib/test/unit/jsonReferenceMap.test.d.ts +2 -0
  32. package/package.json +11 -11
  33. package/src/index.ts +29 -0
  34. package/src/packlets/context/compositeJsonMap.ts +120 -0
  35. package/src/packlets/context/contextHelpers.ts +221 -0
  36. package/src/packlets/context/index.ts +33 -0
  37. package/src/packlets/context/jsonContext.ts +133 -0
  38. package/src/packlets/converters/converters.ts +117 -0
  39. package/src/packlets/converters/index.ts +26 -0
  40. package/src/packlets/converters/jsonConverter.ts +476 -0
  41. package/src/packlets/diff/detailedDiff.ts +585 -0
  42. package/src/packlets/diff/index.ts +24 -0
  43. package/src/packlets/diff/threeWayDiff.ts +420 -0
  44. package/src/packlets/diff/utils.ts +66 -0
  45. package/src/packlets/editor/common.ts +125 -0
  46. package/src/packlets/editor/index.ts +36 -0
  47. package/src/packlets/editor/jsonEditor.ts +523 -0
  48. package/src/packlets/editor/jsonEditorRule.ts +117 -0
  49. package/src/packlets/editor/jsonEditorState.ts +225 -0
  50. package/src/packlets/editor/jsonReferenceMap.ts +516 -0
  51. package/src/packlets/editor/rules/conditional.ts +222 -0
  52. package/src/packlets/editor/rules/index.ts +25 -0
  53. package/src/packlets/editor/rules/multivalue.ts +206 -0
  54. package/src/packlets/editor/rules/references.ts +177 -0
  55. package/src/packlets/editor/rules/templates.ts +159 -0
  56. package/CHANGELOG.md +0 -115
  57. package/lib/index.d.ts.map +0 -1
  58. package/lib/index.js.map +0 -1
  59. package/lib/packlets/context/compositeJsonMap.d.ts.map +0 -1
  60. package/lib/packlets/context/compositeJsonMap.js.map +0 -1
  61. package/lib/packlets/context/contextHelpers.d.ts.map +0 -1
  62. package/lib/packlets/context/contextHelpers.js.map +0 -1
  63. package/lib/packlets/context/index.d.ts.map +0 -1
  64. package/lib/packlets/context/index.js.map +0 -1
  65. package/lib/packlets/context/jsonContext.d.ts.map +0 -1
  66. package/lib/packlets/context/jsonContext.js.map +0 -1
  67. package/lib/packlets/converters/converters.d.ts.map +0 -1
  68. package/lib/packlets/converters/converters.js.map +0 -1
  69. package/lib/packlets/converters/index.d.ts.map +0 -1
  70. package/lib/packlets/converters/index.js.map +0 -1
  71. package/lib/packlets/converters/jsonConverter.d.ts.map +0 -1
  72. package/lib/packlets/converters/jsonConverter.js.map +0 -1
  73. package/lib/packlets/editor/common.d.ts.map +0 -1
  74. package/lib/packlets/editor/common.js.map +0 -1
  75. package/lib/packlets/editor/index.d.ts.map +0 -1
  76. package/lib/packlets/editor/index.js.map +0 -1
  77. package/lib/packlets/editor/jsonEditor.d.ts.map +0 -1
  78. package/lib/packlets/editor/jsonEditor.js.map +0 -1
  79. package/lib/packlets/editor/jsonEditorRule.d.ts.map +0 -1
  80. package/lib/packlets/editor/jsonEditorRule.js.map +0 -1
  81. package/lib/packlets/editor/jsonEditorState.d.ts.map +0 -1
  82. package/lib/packlets/editor/jsonEditorState.js.map +0 -1
  83. package/lib/packlets/editor/jsonReferenceMap.d.ts.map +0 -1
  84. package/lib/packlets/editor/jsonReferenceMap.js.map +0 -1
  85. package/lib/packlets/editor/rules/conditional.d.ts.map +0 -1
  86. package/lib/packlets/editor/rules/conditional.js.map +0 -1
  87. package/lib/packlets/editor/rules/index.d.ts.map +0 -1
  88. package/lib/packlets/editor/rules/index.js.map +0 -1
  89. package/lib/packlets/editor/rules/multivalue.d.ts.map +0 -1
  90. package/lib/packlets/editor/rules/multivalue.js.map +0 -1
  91. package/lib/packlets/editor/rules/references.d.ts.map +0 -1
  92. package/lib/packlets/editor/rules/references.js.map +0 -1
  93. package/lib/packlets/editor/rules/templates.d.ts.map +0 -1
  94. package/lib/packlets/editor/rules/templates.js.map +0 -1
@@ -0,0 +1,225 @@
1
+ /*
2
+ * Copyright (c) 2020 Erik Fortune
3
+ *
4
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
5
+ * of this software and associated documentation files (the "Software"), to deal
6
+ * in the Software without restriction, including without limitation the rights
7
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8
+ * copies of the Software, and to permit persons to whom the Software is
9
+ * furnished to do so, subject to the following conditions:
10
+ *
11
+ * The above copyright notice and this permission notice shall be included in all
12
+ * copies or substantial portions of the Software.
13
+ *
14
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
20
+ * SOFTWARE.
21
+ */
22
+
23
+ import { JsonObject } from '@fgv/ts-json-base';
24
+ import { DetailedFailure, Result, failWithDetail, succeed } from '@fgv/ts-utils';
25
+ import { IJsonContext, IJsonReferenceMap, JsonContextHelper, TemplateVars, VariableValue } from '../context';
26
+ import {
27
+ IJsonCloneEditor,
28
+ IJsonEditorOptions,
29
+ IJsonEditorValidationOptions,
30
+ JsonEditFailureReason,
31
+ JsonEditorValidationRules,
32
+ JsonPropertyEditFailureReason
33
+ } from './common';
34
+
35
+ /**
36
+ * Represents the internal state of a {@link JsonEditor | JsonEditor}.
37
+ * @public
38
+ */
39
+ export class JsonEditorState {
40
+ /**
41
+ * Static global counter used to assign each {@link JsonEditorState | JsonEditorState}
42
+ * a unique identifier.
43
+ * @internal
44
+ */
45
+ protected static _nextId: number = 0;
46
+
47
+ /**
48
+ * The {@link IJsonCloneEditor | editor} for which this state applies.
49
+ */
50
+ public readonly editor: IJsonCloneEditor;
51
+
52
+ /**
53
+ * Fully resolved {@link IJsonEditorOptions | editor options} that apply
54
+ * to the operation for which this state applies.
55
+ */
56
+ public readonly options: IJsonEditorOptions;
57
+
58
+ /**
59
+ * Any deferred JSON objects to be merged during finalization.
60
+ * @internal
61
+ */
62
+ protected readonly _deferred: JsonObject[] = [];
63
+
64
+ /**
65
+ * Unique global identifier for this {@link JsonEditorState | state object}.
66
+ * @internal
67
+ */
68
+ protected readonly _id: number;
69
+
70
+ /**
71
+ * Constructs a new {@link JsonEditorState | JsonEditorState}.
72
+ * @param editor - The {@link IJsonCloneEditor | editor} to which this state
73
+ * applies.
74
+ * @param baseOptions - The {@link IJsonEditorOptions | editor options} that
75
+ * apply to this rule.
76
+ * @param runtimeContext - An optional {@link IJsonContext | JSON context} to be used
77
+ * for json value conversion.
78
+ */
79
+ public constructor(
80
+ editor: IJsonCloneEditor,
81
+ baseOptions: IJsonEditorOptions,
82
+ runtimeContext?: IJsonContext
83
+ ) {
84
+ this.editor = editor;
85
+ this.options = JsonEditorState._getEffectiveOptions(baseOptions, runtimeContext).orThrow();
86
+ this._id = JsonEditorState._nextId++;
87
+ }
88
+
89
+ /**
90
+ * The optional {@link IJsonContext | JSON context} for this state.
91
+ */
92
+ public get context(): IJsonContext | undefined {
93
+ return this.options.context;
94
+ }
95
+
96
+ /**
97
+ * An array of JSON objects that were deferred for merge during
98
+ * finalization.
99
+ */
100
+ public get deferred(): JsonObject[] {
101
+ return this._deferred;
102
+ }
103
+
104
+ /**
105
+ * Merges an optional {@link IJsonContext | JSON context} into a supplied set
106
+ * of {@link IJsonEditorOptions | JSON editor options}.
107
+ * @param options - The {@link IJsonEditorOptions | IJsonEditorOptions} into
108
+ * which the the new context is to be merged.
109
+ * @param context - The {@link IJsonContext | JSON context} to be merged into the
110
+ * editor options.
111
+ * @returns `Success` with the supplied {@link IJsonEditorOptions | options} if
112
+ * there was nothing to merge, or aa new {@link IJsonEditorOptions | IJsonEditorOptions}
113
+ * constructed from the base options merged with the supplied context. Returns `Failure`
114
+ * with more information if an error occurs.
115
+ * @internal
116
+ */
117
+ protected static _getEffectiveOptions(
118
+ options: IJsonEditorOptions,
119
+ context?: IJsonContext
120
+ ): Result<IJsonEditorOptions> {
121
+ if (!context) {
122
+ return succeed(options);
123
+ }
124
+ return JsonContextHelper.mergeContext(options.context, context).onSuccess((merged) => {
125
+ return succeed({ context: merged, validation: options.validation, merge: options.merge });
126
+ });
127
+ }
128
+
129
+ /**
130
+ * Adds a supplied `JsonObject` to the deferred list.
131
+ * @param obj - The `JsonObject` to be deferred.
132
+ */
133
+ public defer(obj: JsonObject): void {
134
+ this._deferred.push(obj);
135
+ }
136
+
137
+ /**
138
+ * Gets a {@link TemplateVars | TemplateVars} from the context of this {@link JsonEditorState | JsonEditorState},
139
+ * or from an optional supplied {@link IJsonContext | IJsonContext} if the current state has no default
140
+ * context.
141
+ * @param defaultContext - An optional default {@link IJsonContext | IJsonContext} to use as `TemplateVars`
142
+ * if the current state does not have context.
143
+ * @returns A {@link TemplateVars | TemplateVars} reflecting the appropriate {@link IJsonContext | JSON context}, or
144
+ * `undefined` if no vars are found.
145
+ */
146
+ public getVars(defaultContext?: IJsonContext): TemplateVars | undefined {
147
+ /* c8 ignore next */ // c8 seems to be struggling atm
148
+ return this.options.context?.vars ?? defaultContext?.vars;
149
+ }
150
+
151
+ /**
152
+ * Gets an {@link IJsonReferenceMap | reference map} containing any other values
153
+ * referenced during the operation.
154
+ * @param defaultContext - An optional default {@link IJsonContext | IJsonContext} to use as
155
+ * {@link TemplateVars | TemplateVars} if the current state does not have context.
156
+ * @returns An {@link IJsonReferenceMap | IJsonReferenceMap} containing any values referenced
157
+ * during this operation.
158
+ */
159
+ public getRefs(defaultContext?: IJsonContext): IJsonReferenceMap | undefined {
160
+ /* c8 ignore next */ // c8 seems to be struggling atm
161
+ return this.options.context?.refs ?? defaultContext?.refs;
162
+ }
163
+
164
+ /**
165
+ * Gets the context of this {@link JsonEditorState | JsonEditorState} or an optionally
166
+ * supplied default context if this state has no context.
167
+ * @param defaultContext - The default {@link IJsonContext | JSON context} to use as default
168
+ * if this state has no context.
169
+ * @returns The appropriate {@link IJsonContext | IJsonContext} or `undefined` if no context
170
+ * is available.
171
+ */
172
+ public getContext(defaultContext?: IJsonContext): IJsonContext | undefined {
173
+ return JsonContextHelper.mergeContext(defaultContext, this.options.context).orDefault();
174
+ }
175
+
176
+ /**
177
+ * Constructs a new {@link IJsonContext | IJsonContext} by merging supplied variables
178
+ * and references into a supplied existing context.
179
+ * @param baseContext - The {@link IJsonContext | IJsonContext} into which variables
180
+ * and references are to be merged, or `undefined` to start with a default empty context.
181
+ * @param add - The {@link VariableValue | variable values} and/or
182
+ * {@link IJsonReferenceMap | JSON entity references} to be merged into the base context.
183
+ * @returns A new {@link IJsonContext | IJsonContext} created by merging the supplied values.
184
+ */
185
+ public extendContext(
186
+ baseContext: IJsonContext | undefined,
187
+ add: { vars?: VariableValue[]; refs?: IJsonReferenceMap[] }
188
+ ): Result<IJsonContext | undefined> {
189
+ const context = this.getContext(baseContext);
190
+ return JsonContextHelper.extendContext(context, add);
191
+ }
192
+
193
+ /**
194
+ * Helper method to constructs `DetailedFailure` with appropriate details and messaging
195
+ * for various validation failures.
196
+ * @param rule - The {@link JsonEditorValidationRules | validation rule} that failed.
197
+ * @param message - A string message describing the failed validation.
198
+ * @param validation - The {@link IJsonEditorValidationOptions | validation options}
199
+ * in effect.
200
+ * @returns A `DetailedFailure` with appropriate detail and message.
201
+ */
202
+ public failValidation<T = JsonObject>(
203
+ rule: JsonEditorValidationRules,
204
+ message?: string,
205
+ validation?: IJsonEditorValidationOptions
206
+ ): DetailedFailure<T, JsonEditFailureReason> {
207
+ let detail: JsonPropertyEditFailureReason = 'error';
208
+ const effective = validation ?? this.options.validation;
209
+ switch (rule) {
210
+ case 'invalidPropertyName':
211
+ detail = effective.onInvalidPropertyName !== 'ignore' ? 'error' : 'inapplicable';
212
+ break;
213
+ case 'invalidPropertyValue':
214
+ detail = effective.onInvalidPropertyValue !== 'ignore' ? 'error' : 'ignore';
215
+ break;
216
+ case 'undefinedPropertyValue':
217
+ detail = effective.onUndefinedPropertyValue !== 'error' ? 'ignore' : 'error';
218
+ /* c8 ignore next */
219
+ message = message ?? 'Cannot convert undefined to JSON';
220
+ break;
221
+ }
222
+ /* c8 ignore next */
223
+ return failWithDetail(message ?? rule, detail);
224
+ }
225
+ }