assign-gingerly 0.0.81 → 0.0.83
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/DX/emojis.js +2 -1
- package/DX/emojis.ts +2 -1
- package/DX/paths.js +14 -14
- package/DX/paths.ts +155 -156
- package/README.md +2 -1
- package/assignFrom.js +6 -3
- package/assignFrom.ts +6 -3
- package/assignFromAsync.js +4 -3
- package/assignFromAsync.ts +4 -3
- package/inferencer/types/NewCustomElement.md +8 -5
- package/inferencer/types/NewHTMLFirstCustomElement.md +75 -14
- package/inferencer/types/assign-gingerly/types.d.ts +21 -0
- package/inferencer/types/el-maker/types.d.ts +2 -0
- package/inferencer/types/roundabout/types.d.ts +9 -1
- package/inferencer/types/swipe-dismiss/types.d.ts +43 -0
- package/package.json +1 -1
- package/processHandlerCommands.js +2 -0
- package/processHandlerCommands.ts +2 -0
- package/resolve/getValues.js +55 -9
- package/resolve/getValues.ts +70 -9
- package/types/assign-gingerly/types.d.ts +21 -0
package/resolve/getValues.ts
CHANGED
|
@@ -85,6 +85,58 @@ function applyAliases(path: string, aliasMap: Map<string, string>): string {
|
|
|
85
85
|
return substituted.join('?.');
|
|
86
86
|
}
|
|
87
87
|
|
|
88
|
+
/**
|
|
89
|
+
* Apply value substitutions to a path string.
|
|
90
|
+
* Replaces complete tokens between `?.` delimiters with their resolved values.
|
|
91
|
+
* Substitutions are applied before aliases.
|
|
92
|
+
*/
|
|
93
|
+
function applySubstitutions(path: string, substitutionMap?: Map<string, string>): string {
|
|
94
|
+
if (!substitutionMap || substitutionMap.size === 0) return path;
|
|
95
|
+
const parts = path.split('?.');
|
|
96
|
+
const substituted = parts.map(part => substitutionMap.get(part) ?? part);
|
|
97
|
+
return substituted.join('?.');
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
/**
|
|
101
|
+
* Resolve substitution values declared in options.substitutions.
|
|
102
|
+
* Each substitution path is resolved against the source object without
|
|
103
|
+
* applying substitutions itself, to avoid infinite recursion.
|
|
104
|
+
* Resolved values must be strings and must not contain `?.`.
|
|
105
|
+
*/
|
|
106
|
+
function resolveSubstitutions(
|
|
107
|
+
substitutions: Record<string, string> | undefined,
|
|
108
|
+
source: any,
|
|
109
|
+
options: GetValuesOptions | undefined
|
|
110
|
+
): Map<string, string> {
|
|
111
|
+
const map = new Map<string, string>();
|
|
112
|
+
if (!substitutions) return map;
|
|
113
|
+
|
|
114
|
+
for (const [name, path] of Object.entries(substitutions)) {
|
|
115
|
+
// Resolve the substitution path against the source, but do not apply
|
|
116
|
+
// substitutions to that path. Root references ($0) are also disabled
|
|
117
|
+
// for substitution paths so values are sourced from `from` only.
|
|
118
|
+
const resolved = getValue(
|
|
119
|
+
path,
|
|
120
|
+
source,
|
|
121
|
+
options
|
|
122
|
+
? { ...options, substitutions: undefined, root: undefined }
|
|
123
|
+
: undefined
|
|
124
|
+
);
|
|
125
|
+
if (typeof resolved !== 'string') {
|
|
126
|
+
throw new Error(
|
|
127
|
+
`Substitution '${name}' must resolve to a string, got ${typeof resolved}`
|
|
128
|
+
);
|
|
129
|
+
}
|
|
130
|
+
if (resolved.includes('?.')) {
|
|
131
|
+
throw new Error(
|
|
132
|
+
`Substitution '${name}' resolved to a string containing '?.', which would alter the path structure: '${resolved}'`
|
|
133
|
+
);
|
|
134
|
+
}
|
|
135
|
+
map.set(name, resolved);
|
|
136
|
+
}
|
|
137
|
+
return map;
|
|
138
|
+
}
|
|
139
|
+
|
|
88
140
|
/**
|
|
89
141
|
* Resolve a special root-reference token at the start of a string.
|
|
90
142
|
* '$0' refers to the first argument passed to assignFrom / resolveValues.
|
|
@@ -200,13 +252,15 @@ function getArray(
|
|
|
200
252
|
aliasMap: Map<string, string>,
|
|
201
253
|
withMethods: Set<string> | undefined,
|
|
202
254
|
protocols: Record<string, (key: string) => any> | undefined,
|
|
203
|
-
options?: GetValuesOptions
|
|
255
|
+
options?: GetValuesOptions,
|
|
256
|
+
substitutionMap?: Map<string, string>
|
|
204
257
|
): any[] {
|
|
205
258
|
const permissionProcessor = options?.permissionProcessor;
|
|
206
259
|
const result: any[] = [];
|
|
207
260
|
for (const item of arr) {
|
|
208
261
|
if (typeof item === 'string' && item.startsWith('?.')) {
|
|
209
|
-
const
|
|
262
|
+
const substituted = applySubstitutions(item, substitutionMap);
|
|
263
|
+
const aliased = applyAliases(substituted, aliasMap);
|
|
210
264
|
const parts = parseCachedPath(aliased);
|
|
211
265
|
result.push(parts.length === 0 ? source : navigatePath(source, parts, withMethods, permissionProcessor));
|
|
212
266
|
} else if (typeof item === 'string' && item.startsWith('$0')) {
|
|
@@ -214,7 +268,8 @@ function getArray(
|
|
|
214
268
|
if (rootRef === null) {
|
|
215
269
|
result.push(source);
|
|
216
270
|
} else {
|
|
217
|
-
const
|
|
271
|
+
const substitutedPath = applySubstitutions(rootRef.path, substitutionMap);
|
|
272
|
+
const aliased = applyAliases(substitutedPath, aliasMap);
|
|
218
273
|
const normalizedPath = aliased.startsWith('?.') ? aliased : (aliased ? `?.${aliased}` : '?.');
|
|
219
274
|
const parts = parseCachedPath(normalizedPath);
|
|
220
275
|
result.push(parts.length === 0 ? rootRef.source : navigatePath(rootRef.source, parts, withMethods, permissionProcessor));
|
|
@@ -222,7 +277,7 @@ function getArray(
|
|
|
222
277
|
} else if (typeof item === 'string' && protocols && hasProtocol(item)) {
|
|
223
278
|
result.push(getProtocolValue(item, protocols, options));
|
|
224
279
|
} else if (Array.isArray(item)) {
|
|
225
|
-
result.push(getArray(item, source, aliasMap, withMethods, protocols, options));
|
|
280
|
+
result.push(getArray(item, source, aliasMap, withMethods, protocols, options, substitutionMap));
|
|
226
281
|
} else if (item && typeof item === 'object') {
|
|
227
282
|
const proto = Object.getPrototypeOf(item);
|
|
228
283
|
if (proto === Object.prototype || proto === null) {
|
|
@@ -255,6 +310,7 @@ export function getValues(
|
|
|
255
310
|
options?: GetValuesOptions
|
|
256
311
|
): Record<string, any> {
|
|
257
312
|
const { aliasMap, withMethods } = normalizeAliasOptions(options);
|
|
313
|
+
const substitutionMap = resolveSubstitutions(options?.substitutions, source, options);
|
|
258
314
|
|
|
259
315
|
const protocols = options?.protocols;
|
|
260
316
|
const permissionProcessor = options?.permissionProcessor;
|
|
@@ -262,7 +318,8 @@ export function getValues(
|
|
|
262
318
|
const result: Record<string, any> = {};
|
|
263
319
|
for (const [key, value] of Object.entries(pattern)) {
|
|
264
320
|
if (typeof value === 'string' && value.startsWith('?.')) {
|
|
265
|
-
const
|
|
321
|
+
const substituted = applySubstitutions(value, substitutionMap);
|
|
322
|
+
const aliased = applyAliases(substituted, aliasMap);
|
|
266
323
|
const parts = parseCachedPath(aliased);
|
|
267
324
|
result[key] = parts.length === 0 ? source : navigatePath(source, parts, withMethods, permissionProcessor);
|
|
268
325
|
} else if (typeof value === 'string' && value.startsWith('$0')) {
|
|
@@ -270,7 +327,8 @@ export function getValues(
|
|
|
270
327
|
if (rootRef === null) {
|
|
271
328
|
result[key] = source;
|
|
272
329
|
} else {
|
|
273
|
-
const
|
|
330
|
+
const substitutedPath = applySubstitutions(rootRef.path, substitutionMap);
|
|
331
|
+
const aliased = applyAliases(substitutedPath, aliasMap);
|
|
274
332
|
const normalizedPath = aliased.startsWith('?.') ? aliased : (aliased ? `?.${aliased}` : '?.');
|
|
275
333
|
const parts = parseCachedPath(normalizedPath);
|
|
276
334
|
result[key] = parts.length === 0 ? rootRef.source : navigatePath(rootRef.source, parts, withMethods, permissionProcessor);
|
|
@@ -278,7 +336,7 @@ export function getValues(
|
|
|
278
336
|
} else if (typeof value === 'string' && protocols && hasProtocol(value)) {
|
|
279
337
|
result[key] = getProtocolValue(value, protocols, options);
|
|
280
338
|
} else if (Array.isArray(value)) {
|
|
281
|
-
result[key] = getArray(value, source, aliasMap, withMethods, protocols, options);
|
|
339
|
+
result[key] = getArray(value, source, aliasMap, withMethods, protocols, options, substitutionMap);
|
|
282
340
|
} else if (typeof value === 'object' && value !== null) {
|
|
283
341
|
const proto = Object.getPrototypeOf(value);
|
|
284
342
|
if (proto === Object.prototype || proto === null) {
|
|
@@ -314,10 +372,13 @@ export function getValue(
|
|
|
314
372
|
return path;
|
|
315
373
|
}
|
|
316
374
|
|
|
317
|
-
|
|
375
|
+
const substitutionMap = resolveSubstitutions(options?.substitutions, source, options);
|
|
376
|
+
|
|
377
|
+
const substituted = applySubstitutions(path, substitutionMap);
|
|
378
|
+
let aliased = substituted;
|
|
318
379
|
const { aliasMap } = normalizeAliasOptions(options);
|
|
319
380
|
if (aliasMap.size > 0) {
|
|
320
|
-
aliased = applyAliases(
|
|
381
|
+
aliased = applyAliases(substituted, aliasMap);
|
|
321
382
|
}
|
|
322
383
|
|
|
323
384
|
const normalizedPath = aliased.startsWith('?.') ? aliased : (aliased ? `?.${aliased}` : '?.');
|
|
@@ -267,6 +267,17 @@ export interface IAssignGingerlyOptions {
|
|
|
267
267
|
*/
|
|
268
268
|
aka?: Record<string, string>;
|
|
269
269
|
|
|
270
|
+
/**
|
|
271
|
+
* Value substitutions for path segments.
|
|
272
|
+
* Each key names a placeholder; the value is a `?.`-delimited path resolved
|
|
273
|
+
* against the source (`from`) object. The resolved string value replaces any
|
|
274
|
+
* matching whole path segment in RHS path strings before path evaluation.
|
|
275
|
+
*
|
|
276
|
+
* Substitution values must be strings and must not contain the `?.` sequence,
|
|
277
|
+
* otherwise an error is thrown.
|
|
278
|
+
*/
|
|
279
|
+
substitutions?: Record<string, string>;
|
|
280
|
+
|
|
270
281
|
/**
|
|
271
282
|
* Shorthand for binding method aliases from the source object.
|
|
272
283
|
* Each entry maps an alias to a method name and is normalized into
|
|
@@ -357,6 +368,16 @@ export interface AssignFromOptions {
|
|
|
357
368
|
/** Alias mappings for path segments */
|
|
358
369
|
aka?: Record<string, string>;
|
|
359
370
|
|
|
371
|
+
/**
|
|
372
|
+
* Value substitutions for path segments.
|
|
373
|
+
* Each key names a placeholder; the value is a `?.`-delimited path resolved
|
|
374
|
+
* against `from`. The resolved string value replaces any matching whole path
|
|
375
|
+
* segment in RHS path strings before path evaluation.
|
|
376
|
+
*
|
|
377
|
+
* Substitution values must be strings and must not contain `?.`.
|
|
378
|
+
*/
|
|
379
|
+
substitutions?: Record<string, string>;
|
|
380
|
+
|
|
360
381
|
/** AbortSignal for cleanup */
|
|
361
382
|
signal?: AbortSignal;
|
|
362
383
|
|