assign-gingerly 0.0.74 → 0.0.76

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 (62) hide show
  1. package/DX/installForwarding.js +1 -1
  2. package/DX/installForwarding.ts +1 -1
  3. package/README.md +2 -0
  4. package/assignFrom.js +18 -17
  5. package/assignFrom.ts +23 -23
  6. package/assignFromAsync.js +14 -13
  7. package/assignFromAsync.ts +15 -15
  8. package/assignGingerly.js +46 -42
  9. package/assignGingerly.ts +131 -124
  10. package/assignPermissions/PermissionProcessor.js +166 -0
  11. package/assignPermissions/PermissionProcessor.ts +210 -0
  12. package/assignPermissions/isAllowedImportPath.js +2 -6
  13. package/assignPermissions/isAllowedImportPath.ts +3 -5
  14. package/assignPermissions/isAllowedUrl.js +18 -0
  15. package/assignPermissions/isAllowedUrl.ts +15 -0
  16. package/assignTentatively.js +9 -11
  17. package/assignTentatively.ts +11 -13
  18. package/beVigilant.js +1 -1
  19. package/beVigilant.ts +1 -1
  20. package/buildCSSQuery.js +1 -1
  21. package/buildCSSQuery.ts +1 -1
  22. package/eachTime.js +5 -6
  23. package/eachTime.ts +12 -15
  24. package/enhanceAll.js +3 -3
  25. package/enhanceAll.ts +4 -4
  26. package/evaluatePathWithAsyncMethods.js +12 -8
  27. package/evaluatePathWithAsyncMethods.ts +129 -117
  28. package/handlers/addEventListener.js +11 -11
  29. package/handlers/addEventListener.ts +12 -13
  30. package/handlers/lazyLoad.ts +7 -7
  31. package/handlers/lazyLoadSwitch.ts +3 -3
  32. package/handlers/manageTemplateList.js +10 -10
  33. package/handlers/manageTemplateList.ts +12 -12
  34. package/handlers/rangeSelector.ts +3 -3
  35. package/index.js +2 -3
  36. package/index.ts +2 -3
  37. package/inferencer/types/assign-gingerly/types.d.ts +37 -23
  38. package/inferencer/types/el-maker/types.d.ts +33 -0
  39. package/inferencer/types/scratch-box/types.d.ts +3 -0
  40. package/inferencer/types/truth-sourcer/types.d.ts +4 -0
  41. package/package.json +25 -23
  42. package/parseWithAttrs.js +1 -1
  43. package/parseWithAttrs.ts +1 -1
  44. package/processHandlerCommands.js +5 -7
  45. package/processHandlerCommands.ts +12 -15
  46. package/{getValues.js → resolve/getValues.js} +19 -8
  47. package/{getValues.ts → resolve/getValues.ts} +331 -314
  48. package/{resolveIdRef.js → resolve/resolveIdRef.js} +1 -1
  49. package/{resolveIdRef.ts → resolve/resolveIdRef.ts} +1 -1
  50. package/{resolveValues.ts → resolve/resolveValues.ts} +1 -1
  51. package/types/assign-gingerly/types.d.ts +37 -8
  52. package/utils/findClassPrototypeInPath.js +57 -0
  53. package/utils/findClassPrototypeInPath.ts +62 -0
  54. package/utils/isAsyncSpawn.js +20 -0
  55. package/utils/isAsyncSpawn.ts +17 -0
  56. package/assignPermissions/restrictedProps.js +0 -43
  57. package/assignPermissions/restrictedProps.ts +0 -53
  58. package/resolveAndAssignFeatures.js +0 -36
  59. package/resolveAndAssignFeatures.ts +0 -43
  60. /package/{resolveTemplate.js → resolve/resolveTemplate.js} +0 -0
  61. /package/{resolveTemplate.ts → resolve/resolveTemplate.ts} +0 -0
  62. /package/{resolveValues.js → resolve/resolveValues.js} +0 -0
package/enhanceAll.ts CHANGED
@@ -18,7 +18,7 @@
18
18
 
19
19
  import { isAllowedImportPath } from './assignPermissions/isAllowedImportPath.js';
20
20
  import { findClassPrototypeInPath } from './utils/findClassPrototypeInPath.js';
21
- import type { AssignPermissions } from './types/assign-gingerly/types.js';
21
+ import type { PermissionProcessor } from './types/assign-gingerly/types.js';
22
22
 
23
23
  /**
24
24
  * Configuration for a single enhancement to apply in bulk.
@@ -51,15 +51,15 @@ export interface EnhanceConfig {
51
51
  export async function enhanceAll(
52
52
  target: Element,
53
53
  configs: EnhanceConfig[],
54
- permissions?: AssignPermissions
54
+ permissionProcessor?: PermissionProcessor
55
55
  ): Promise<void> {
56
56
  for (const config of configs) {
57
57
  // Validate EMC path unless cross-domain imports are explicitly permitted
58
- if (!permissions?.crossDomainImports && !isAllowedImportPath(config.emc)) {
58
+ if (!permissionProcessor?.crossDomainImports && !isAllowedImportPath(config.emc)) {
59
59
  throw new Error(
60
60
  `enhanceAll: EMC path "${config.emc}" is a cross-domain URL. ` +
61
61
  `Only same-origin paths or import-map-covered specifiers are allowed by default. ` +
62
- `Pass { crossDomainImports: true } in permissions to override.`
62
+ `Pass { crossDomainImports: true } in permissionProcessor to override.`
63
63
  );
64
64
  }
65
65
 
@@ -10,6 +10,10 @@
10
10
  * NOTE: Interaction with @each and @eachTime is not yet implemented.
11
11
  * Deferred until a compelling use case presents itself.
12
12
  */
13
+ import { isAllowedMethod } from './assignGingerly.js';
14
+ function isAllowedAsyncMethod(methodName, withAsyncMethods, permissionProcessor) {
15
+ return withAsyncMethods.has(methodName) && !permissionProcessor?.checkRestrictedMethod(methodName);
16
+ }
13
17
  /**
14
18
  * Evaluates a path with support for both sync and async method calls.
15
19
  * Awaits the return value of any method in the withAsyncMethods set.
@@ -21,7 +25,7 @@
21
25
  * @param withAsyncMethods - Set of method names that are awaited
22
26
  * @returns Promise resolving to the evaluation result
23
27
  */
24
- export async function evaluatePathWithAsyncMethods(target, pathParts, value, withMethods, withAsyncMethods) {
28
+ export async function evaluatePathWithAsyncMethods(target, pathParts, value, withMethods, withAsyncMethods, permissionProcessor) {
25
29
  let current = target;
26
30
  let i = 0;
27
31
  // Process all segments except the last one
@@ -30,12 +34,12 @@ export async function evaluatePathWithAsyncMethods(target, pathParts, value, wit
30
34
  const nextPart = pathParts[i + 1];
31
35
  // A trailing | marks a zero-argument method call: 'deref|' calls deref()
32
36
  // without consuming the next segment. Only applies to listed method names.
33
- const isZeroArgSync = part.endsWith('|') && withMethods.has(part.slice(0, -1));
34
- const isZeroArgAsync = part.endsWith('|') && withAsyncMethods.has(part.slice(0, -1));
37
+ const isZeroArgSync = part.endsWith('|') && isAllowedMethod(part.slice(0, -1), withMethods, permissionProcessor);
38
+ const isZeroArgAsync = part.endsWith('|') && isAllowedAsyncMethod(part.slice(0, -1), withAsyncMethods, permissionProcessor);
35
39
  const baseName = (isZeroArgSync || isZeroArgAsync) ? part.slice(0, -1) : part;
36
40
  const nextIsMethod = withAsyncMethods.has(nextPart) || withMethods.has(nextPart)
37
41
  || (nextPart.endsWith('|') && (withAsyncMethods.has(nextPart.slice(0, -1)) || withMethods.has(nextPart.slice(0, -1))));
38
- if (withAsyncMethods.has(part) || isZeroArgAsync) {
42
+ if (isAllowedAsyncMethod(part, withAsyncMethods, permissionProcessor) || isZeroArgAsync) {
39
43
  // Async method — call and await
40
44
  const method = current[baseName];
41
45
  if (typeof method === 'function') {
@@ -57,7 +61,7 @@ export async function evaluatePathWithAsyncMethods(target, pathParts, value, wit
57
61
  current = current[baseName];
58
62
  }
59
63
  }
60
- else if (withMethods.has(part) || isZeroArgSync) {
64
+ else if (isAllowedMethod(part, withMethods, permissionProcessor) || isZeroArgSync) {
61
65
  // Sync method — same logic as evaluatePathWithMethods
62
66
  const method = current[baseName];
63
67
  if (typeof method === 'function') {
@@ -91,13 +95,13 @@ export async function evaluatePathWithAsyncMethods(target, pathParts, value, wit
91
95
  // otherwise it is a literal property name (e.g. an exotic key ending in |).
92
96
  const rawLastKey = pathParts[pathParts.length - 1];
93
97
  const isZeroArg = rawLastKey.endsWith('|')
94
- && (withMethods.has(rawLastKey.slice(0, -1)) || withAsyncMethods.has(rawLastKey.slice(0, -1)));
98
+ && (isAllowedMethod(rawLastKey.slice(0, -1), withMethods, permissionProcessor) || isAllowedAsyncMethod(rawLastKey.slice(0, -1), withAsyncMethods, permissionProcessor));
95
99
  const lastKey = isZeroArg ? rawLastKey.slice(0, -1) : rawLastKey;
96
100
  return {
97
101
  target: current,
98
102
  lastKey,
99
- isMethod: withMethods.has(lastKey),
100
- isAsyncMethod: withAsyncMethods.has(lastKey),
103
+ isMethod: isAllowedMethod(lastKey, withMethods, permissionProcessor),
104
+ isAsyncMethod: isAllowedAsyncMethod(lastKey, withAsyncMethods, permissionProcessor),
101
105
  isZeroArg
102
106
  };
103
107
  }
@@ -1,117 +1,129 @@
1
- /**
2
- * evaluatePathWithAsyncMethods - Async variant of evaluatePathWithMethods.
3
- *
4
- * Walks a path of property accesses and method calls, awaiting any methods
5
- * that are in the withAsyncMethods set before continuing the chain.
6
- *
7
- * This module is loaded dynamically (only when withAsyncMethods is used)
8
- * to avoid adding async overhead to the synchronous path.
9
- *
10
- * NOTE: Interaction with @each and @eachTime is not yet implemented.
11
- * Deferred until a compelling use case presents itself.
12
- */
13
-
14
- export interface AsyncPathResult {
15
- target: any;
16
- lastKey: string;
17
- isMethod: boolean;
18
- isAsyncMethod: boolean;
19
- isZeroArg: boolean;
20
- }
21
-
22
- /**
23
- * Evaluates a path with support for both sync and async method calls.
24
- * Awaits the return value of any method in the withAsyncMethods set.
25
- *
26
- * @param target - The root object to start path evaluation from
27
- * @param pathParts - Array of path segments (split from '?.' notation)
28
- * @param value - The value to assign or pass as argument at the end
29
- * @param withMethods - Set of method names that are called synchronously
30
- * @param withAsyncMethods - Set of method names that are awaited
31
- * @returns Promise resolving to the evaluation result
32
- */
33
- export async function evaluatePathWithAsyncMethods(
34
- target: any,
35
- pathParts: string[],
36
- value: any,
37
- withMethods: Set<string>,
38
- withAsyncMethods: Set<string>
39
- ): Promise<AsyncPathResult> {
40
- let current = target;
41
- let i = 0;
42
-
43
- // Process all segments except the last one
44
- while (i < pathParts.length - 1) {
45
- const part = pathParts[i];
46
- const nextPart = pathParts[i + 1];
47
-
48
- // A trailing | marks a zero-argument method call: 'deref|' calls deref()
49
- // without consuming the next segment. Only applies to listed method names.
50
- const isZeroArgSync = part.endsWith('|') && withMethods.has(part.slice(0, -1));
51
- const isZeroArgAsync = part.endsWith('|') && withAsyncMethods.has(part.slice(0, -1));
52
- const baseName = (isZeroArgSync || isZeroArgAsync) ? part.slice(0, -1) : part;
53
- const nextIsMethod = withAsyncMethods.has(nextPart) || withMethods.has(nextPart)
54
- || (nextPart.endsWith('|') && (withAsyncMethods.has(nextPart.slice(0, -1)) || withMethods.has(nextPart.slice(0, -1))));
55
-
56
- if (withAsyncMethods.has(part) || isZeroArgAsync) {
57
- // Async method — call and await
58
- const method = current[baseName];
59
- if (typeof method === 'function') {
60
- if (isZeroArgAsync || nextIsMethod) {
61
- // Zero-arg call next is either a method or explicitly not an argument
62
- current = await method.call(current);
63
- } else {
64
- // Call with next part as string arg, then await
65
- current = await method.call(current, nextPart);
66
- i++; // Skip next part since we consumed it as argument
67
- }
68
- } else {
69
- // Not a function just access property
70
- if (current[baseName] === undefined || current[baseName] === null) {
71
- current[baseName] = {};
72
- }
73
- current = current[baseName];
74
- }
75
- } else if (withMethods.has(part) || isZeroArgSync) {
76
- // Sync method same logic as evaluatePathWithMethods
77
- const method = current[baseName];
78
- if (typeof method === 'function') {
79
- if (isZeroArgSync || nextIsMethod) {
80
- // Zero-arg call — next is either a method or explicitly not an argument
81
- current = method.call(current);
82
- } else {
83
- // Call with next part as string arg
84
- current = method.call(current, nextPart);
85
- i++; // Skip next part since we consumed it as argument
86
- }
87
- } else {
88
- if (!(baseName in current) || typeof current[baseName] !== 'object' || current[baseName] === null) {
89
- current[baseName] = {};
90
- }
91
- current = current[baseName];
92
- }
93
- } else {
94
- // Not a method — normal property access
95
- if (!(part in current) || typeof current[part] !== 'object' || current[part] === null) {
96
- current[part] = {};
97
- }
98
- current = current[part];
99
- }
100
-
101
- i++;
102
- }
103
-
104
- // Strip a trailing | from the last segment only when it names a listed method;
105
- // otherwise it is a literal property name (e.g. an exotic key ending in |).
106
- const rawLastKey = pathParts[pathParts.length - 1];
107
- const isZeroArg = rawLastKey.endsWith('|')
108
- && (withMethods.has(rawLastKey.slice(0, -1)) || withAsyncMethods.has(rawLastKey.slice(0, -1)));
109
- const lastKey = isZeroArg ? rawLastKey.slice(0, -1) : rawLastKey;
110
- return {
111
- target: current,
112
- lastKey,
113
- isMethod: withMethods.has(lastKey),
114
- isAsyncMethod: withAsyncMethods.has(lastKey),
115
- isZeroArg
116
- };
117
- }
1
+ /**
2
+ * evaluatePathWithAsyncMethods - Async variant of evaluatePathWithMethods.
3
+ *
4
+ * Walks a path of property accesses and method calls, awaiting any methods
5
+ * that are in the withAsyncMethods set before continuing the chain.
6
+ *
7
+ * This module is loaded dynamically (only when withAsyncMethods is used)
8
+ * to avoid adding async overhead to the synchronous path.
9
+ *
10
+ * NOTE: Interaction with @each and @eachTime is not yet implemented.
11
+ * Deferred until a compelling use case presents itself.
12
+ */
13
+
14
+ import type { PermissionProcessor } from './types/assign-gingerly/types.js';
15
+ import { isAllowedMethod } from './assignGingerly.js';
16
+
17
+ export interface AsyncPathResult {
18
+ target: any;
19
+ lastKey: string;
20
+ isMethod: boolean;
21
+ isAsyncMethod: boolean;
22
+ isZeroArg: boolean;
23
+ }
24
+
25
+ function isAllowedAsyncMethod(
26
+ methodName: string,
27
+ withAsyncMethods: Set<string>,
28
+ permissionProcessor?: PermissionProcessor
29
+ ): boolean {
30
+ return withAsyncMethods.has(methodName) && !permissionProcessor?.checkRestrictedMethod(methodName);
31
+ }
32
+
33
+ /**
34
+ * Evaluates a path with support for both sync and async method calls.
35
+ * Awaits the return value of any method in the withAsyncMethods set.
36
+ *
37
+ * @param target - The root object to start path evaluation from
38
+ * @param pathParts - Array of path segments (split from '?.' notation)
39
+ * @param value - The value to assign or pass as argument at the end
40
+ * @param withMethods - Set of method names that are called synchronously
41
+ * @param withAsyncMethods - Set of method names that are awaited
42
+ * @returns Promise resolving to the evaluation result
43
+ */
44
+ export async function evaluatePathWithAsyncMethods(
45
+ target: any,
46
+ pathParts: string[],
47
+ value: any,
48
+ withMethods: Set<string>,
49
+ withAsyncMethods: Set<string>,
50
+ permissionProcessor?: PermissionProcessor
51
+ ): Promise<AsyncPathResult> {
52
+ let current = target;
53
+ let i = 0;
54
+
55
+ // Process all segments except the last one
56
+ while (i < pathParts.length - 1) {
57
+ const part = pathParts[i];
58
+ const nextPart = pathParts[i + 1];
59
+
60
+ // A trailing | marks a zero-argument method call: 'deref|' calls deref()
61
+ // without consuming the next segment. Only applies to listed method names.
62
+ const isZeroArgSync = part.endsWith('|') && isAllowedMethod(part.slice(0, -1), withMethods, permissionProcessor);
63
+ const isZeroArgAsync = part.endsWith('|') && isAllowedAsyncMethod(part.slice(0, -1), withAsyncMethods, permissionProcessor);
64
+ const baseName = (isZeroArgSync || isZeroArgAsync) ? part.slice(0, -1) : part;
65
+ const nextIsMethod = withAsyncMethods.has(nextPart) || withMethods.has(nextPart)
66
+ || (nextPart.endsWith('|') && (withAsyncMethods.has(nextPart.slice(0, -1)) || withMethods.has(nextPart.slice(0, -1))));
67
+
68
+ if (isAllowedAsyncMethod(part, withAsyncMethods, permissionProcessor) || isZeroArgAsync) {
69
+ // Async methodcall and await
70
+ const method = current[baseName];
71
+ if (typeof method === 'function') {
72
+ if (isZeroArgAsync || nextIsMethod) {
73
+ // Zero-arg call — next is either a method or explicitly not an argument
74
+ current = await method.call(current);
75
+ } else {
76
+ // Call with next part as string arg, then await
77
+ current = await method.call(current, nextPart);
78
+ i++; // Skip next part since we consumed it as argument
79
+ }
80
+ } else {
81
+ // Not a function — just access property
82
+ if (current[baseName] === undefined || current[baseName] === null) {
83
+ current[baseName] = {};
84
+ }
85
+ current = current[baseName];
86
+ }
87
+ } else if (isAllowedMethod(part, withMethods, permissionProcessor) || isZeroArgSync) {
88
+ // Sync method same logic as evaluatePathWithMethods
89
+ const method = current[baseName];
90
+ if (typeof method === 'function') {
91
+ if (isZeroArgSync || nextIsMethod) {
92
+ // Zero-arg call — next is either a method or explicitly not an argument
93
+ current = method.call(current);
94
+ } else {
95
+ // Call with next part as string arg
96
+ current = method.call(current, nextPart);
97
+ i++; // Skip next part since we consumed it as argument
98
+ }
99
+ } else {
100
+ if (!(baseName in current) || typeof current[baseName] !== 'object' || current[baseName] === null) {
101
+ current[baseName] = {};
102
+ }
103
+ current = current[baseName];
104
+ }
105
+ } else {
106
+ // Not a method normal property access
107
+ if (!(part in current) || typeof current[part] !== 'object' || current[part] === null) {
108
+ current[part] = {};
109
+ }
110
+ current = current[part];
111
+ }
112
+
113
+ i++;
114
+ }
115
+
116
+ // Strip a trailing | from the last segment only when it names a listed method;
117
+ // otherwise it is a literal property name (e.g. an exotic key ending in |).
118
+ const rawLastKey = pathParts[pathParts.length - 1];
119
+ const isZeroArg = rawLastKey.endsWith('|')
120
+ && (isAllowedMethod(rawLastKey.slice(0, -1), withMethods, permissionProcessor) || isAllowedAsyncMethod(rawLastKey.slice(0, -1), withAsyncMethods, permissionProcessor));
121
+ const lastKey = isZeroArg ? rawLastKey.slice(0, -1) : rawLastKey;
122
+ return {
123
+ target: current,
124
+ lastKey,
125
+ isMethod: isAllowedMethod(lastKey, withMethods, permissionProcessor),
126
+ isAsyncMethod: isAllowedAsyncMethod(lastKey, withAsyncMethods, permissionProcessor),
127
+ isZeroArg
128
+ };
129
+ }
@@ -37,7 +37,7 @@ function extractShorthand(config) {
37
37
  /**
38
38
  * Process a single AssignDispatchVector — execute all toTarget/toHost/toLHS assignments.
39
39
  */
40
- function processVector(vector, source, target, host, lhs, inheritedOptions, useAssignFrom, permissions) {
40
+ function processVector(vector, source, target, host, lhs, inheritedOptions, useAssignFrom, permissionProcessor) {
41
41
  const destinations = [
42
42
  { key: 'toTarget', dest: target },
43
43
  { key: 'toHost', dest: host },
@@ -50,11 +50,11 @@ function processVector(vector, source, target, host, lhs, inheritedOptions, useA
50
50
  if (useAssignFrom && source != null) {
51
51
  // Dynamic import assignFrom on demand (fire-and-forget context, already async)
52
52
  import('../assignFrom.js').then(({ assignFrom }) => {
53
- assignFrom(dest, pattern, { from: source, ...inheritedOptions, ...vector.withOptions }, permissions);
53
+ assignFrom(dest, pattern, { from: source, ...inheritedOptions, ...vector.withOptions }, permissionProcessor);
54
54
  });
55
55
  }
56
56
  else {
57
- assignGingerly(dest, pattern, inheritedOptions, permissions);
57
+ assignGingerly(dest, pattern, inheritedOptions, permissionProcessor);
58
58
  }
59
59
  }
60
60
  // Handle shorthand (implicit toHost)
@@ -62,11 +62,11 @@ function processVector(vector, source, target, host, lhs, inheritedOptions, useA
62
62
  if (shorthand) {
63
63
  if (useAssignFrom && source != null) {
64
64
  import('../assignFrom.js').then(({ assignFrom }) => {
65
- assignFrom(host, shorthand, { from: source, ...inheritedOptions, ...vector.withOptions }, permissions);
65
+ assignFrom(host, shorthand, { from: source, ...inheritedOptions, ...vector.withOptions }, permissionProcessor);
66
66
  });
67
67
  }
68
68
  else {
69
- assignGingerly(host, shorthand, inheritedOptions, permissions);
69
+ assignGingerly(host, shorthand, inheritedOptions, permissionProcessor);
70
70
  }
71
71
  }
72
72
  }
@@ -79,7 +79,7 @@ function processVector(vector, source, target, host, lhs, inheritedOptions, useA
79
79
  * @param host - The options.from (source/view model)
80
80
  * @param inheritedOptions - Parent assignFrom options (withMethods, aka, etc.)
81
81
  */
82
- export function attachEventListener(lhs, config, target, host, inheritedOptions, permissions) {
82
+ export function attachEventListener(lhs, config, target, host, inheritedOptions, permissionProcessor) {
83
83
  const { on: eventName, get: getConfig, fromLHS, fromHost, fromTarget, fromEvent, dispatch } = config;
84
84
  // Resolve get config values
85
85
  const { abortController, key, nudge, options: listenerOptions, stopPropagation, preventDefault, dispatch: getDispatch } = getConfig ?? {};
@@ -112,22 +112,22 @@ export function attachEventListener(lhs, config, target, host, inheritedOptions,
112
112
  if (preventDefault)
113
113
  event.preventDefault();
114
114
  // Static assignments (no from) — top-level toTarget/toHost/toLHS + shorthand
115
- processVector(config, null, target, host, lhs, inheritedOptions, false, permissions);
115
+ processVector(config, null, target, host, lhs, inheritedOptions, false, permissionProcessor);
116
116
  // fromLHS assignments
117
117
  if (fromLHS) {
118
- processVector(fromLHS, lhs, target, host, lhs, inheritedOptions, true, permissions);
118
+ processVector(fromLHS, lhs, target, host, lhs, inheritedOptions, true, permissionProcessor);
119
119
  }
120
120
  // fromHost assignments
121
121
  if (fromHost) {
122
- processVector(fromHost, host, target, host, lhs, inheritedOptions, true, permissions);
122
+ processVector(fromHost, host, target, host, lhs, inheritedOptions, true, permissionProcessor);
123
123
  }
124
124
  // fromTarget assignments
125
125
  if (fromTarget) {
126
- processVector(fromTarget, target, target, host, lhs, inheritedOptions, true, permissions);
126
+ processVector(fromTarget, target, target, host, lhs, inheritedOptions, true, permissionProcessor);
127
127
  }
128
128
  // fromEvent assignments
129
129
  if (fromEvent) {
130
- processVector(fromEvent, event, target, host, lhs, inheritedOptions, true, permissions);
130
+ processVector(fromEvent, event, target, host, lhs, inheritedOptions, true, permissionProcessor);
131
131
  }
132
132
  // Dispatch custom event if configured
133
133
  const dispatchConfig = dispatch || getDispatch;
@@ -8,8 +8,7 @@
8
8
  */
9
9
 
10
10
  import assignGingerly from '../assignGingerly.js';
11
- import type { AddEventListenerConfig, AssignDispatchVector } from '../types/assign-gingerly/types.js';
12
- import type { AssignPermissions } from '../types/assign-gingerly/types.js';
11
+ import type { AddEventListenerConfig, AssignDispatchVector, PermissionProcessor } from '../types/assign-gingerly/types.js';
13
12
 
14
13
  /**
15
14
  * WeakMap for dedup: Element → Map<key, AbortController>
@@ -52,7 +51,7 @@ function processVector(
52
51
  lhs: Element,
53
52
  inheritedOptions: any,
54
53
  useAssignFrom: boolean,
55
- permissions?: AssignPermissions
54
+ permissionProcessor?: PermissionProcessor
56
55
  ): void {
57
56
  const destinations = [
58
57
  { key: 'toTarget' as const, dest: target },
@@ -66,10 +65,10 @@ function processVector(
66
65
  if (useAssignFrom && source != null) {
67
66
  // Dynamic import assignFrom on demand (fire-and-forget context, already async)
68
67
  import('../assignFrom.js').then(({ assignFrom }) => {
69
- assignFrom(dest, pattern, { from: source, ...inheritedOptions, ...vector.withOptions }, permissions);
68
+ assignFrom(dest, pattern, { from: source, ...inheritedOptions, ...vector.withOptions }, permissionProcessor);
70
69
  });
71
70
  } else {
72
- assignGingerly(dest, pattern, inheritedOptions, permissions);
71
+ assignGingerly(dest, pattern, inheritedOptions, permissionProcessor);
73
72
  }
74
73
  }
75
74
 
@@ -78,10 +77,10 @@ function processVector(
78
77
  if (shorthand) {
79
78
  if (useAssignFrom && source != null) {
80
79
  import('../assignFrom.js').then(({ assignFrom }) => {
81
- assignFrom(host, shorthand, { from: source, ...inheritedOptions, ...vector.withOptions }, permissions);
80
+ assignFrom(host, shorthand, { from: source, ...inheritedOptions, ...vector.withOptions }, permissionProcessor);
82
81
  });
83
82
  } else {
84
- assignGingerly(host, shorthand, inheritedOptions, permissions);
83
+ assignGingerly(host, shorthand, inheritedOptions, permissionProcessor);
85
84
  }
86
85
  }
87
86
  }
@@ -101,7 +100,7 @@ export function attachEventListener(
101
100
  target: any,
102
101
  host: any,
103
102
  inheritedOptions: any,
104
- permissions?: AssignPermissions
103
+ permissionProcessor?: PermissionProcessor
105
104
  ): void {
106
105
  const { on: eventName, get: getConfig, fromLHS, fromHost, fromTarget, fromEvent, dispatch } = config;
107
106
 
@@ -134,26 +133,26 @@ export function attachEventListener(
134
133
  if (preventDefault) event.preventDefault();
135
134
 
136
135
  // Static assignments (no from) — top-level toTarget/toHost/toLHS + shorthand
137
- processVector(config, null, target, host, lhs, inheritedOptions, false, permissions);
136
+ processVector(config, null, target, host, lhs, inheritedOptions, false, permissionProcessor);
138
137
 
139
138
  // fromLHS assignments
140
139
  if (fromLHS) {
141
- processVector(fromLHS, lhs, target, host, lhs, inheritedOptions, true, permissions);
140
+ processVector(fromLHS, lhs, target, host, lhs, inheritedOptions, true, permissionProcessor);
142
141
  }
143
142
 
144
143
  // fromHost assignments
145
144
  if (fromHost) {
146
- processVector(fromHost, host, target, host, lhs, inheritedOptions, true, permissions);
145
+ processVector(fromHost, host, target, host, lhs, inheritedOptions, true, permissionProcessor);
147
146
  }
148
147
 
149
148
  // fromTarget assignments
150
149
  if (fromTarget) {
151
- processVector(fromTarget, target, target, host, lhs, inheritedOptions, true, permissions);
150
+ processVector(fromTarget, target, target, host, lhs, inheritedOptions, true, permissionProcessor);
152
151
  }
153
152
 
154
153
  // fromEvent assignments
155
154
  if (fromEvent) {
156
- processVector(fromEvent, event, target, host, lhs, inheritedOptions, true, permissions);
155
+ processVector(fromEvent, event, target, host, lhs, inheritedOptions, true, permissionProcessor);
157
156
  }
158
157
 
159
158
  // Dispatch custom event if configured
@@ -20,11 +20,11 @@
20
20
  */
21
21
 
22
22
  import type { AssignFromHandler } from '../assignFromAsync.js';
23
- import type { LazyLoadResolvedParams, LazyLoadInstantiatedContext } from '../types/assign-gingerly/types.js';
23
+ import type { LazyLoadResolvedParams, LazyLoadInstantiatedContext, PermissionProcessor } from '../types/assign-gingerly/types.js';
24
24
  import { withTransition, ensureHideStyle, DEFAULT_HIDE_CLASS } from '../transitionHelper.js';
25
25
  import { findMarkers, createMarkers, getNodesBetweenMarkers, findMarkersSibling, createMarkersSibling, MARKER_START_PREFIX, MARKER_END } from '../markerUtils.js';
26
26
  import { assignFrom } from '../assignFrom.js';
27
- import type { AssignPermissions } from '../types/assign-gingerly/types.js';
27
+
28
28
 
29
29
  export type { LazyLoadResolvedParams, LazyLoadInstantiatedContext };
30
30
 
@@ -49,16 +49,16 @@ function getMarkerName(templateEl: any): string {
49
49
  export class LazyLoadHandler implements AssignFromHandler {
50
50
  config: any;
51
51
  _options: any;
52
- _permissions?: AssignPermissions;
52
+ _permissionProcessor?: PermissionProcessor;
53
53
  static #markerCounter = 0;
54
54
 
55
55
  constructor(config: any) {
56
56
  this.config = config;
57
57
  }
58
58
 
59
- async assign(lhsTarget: any, resolvedParams: LazyLoadResolvedParams, options?: any, permissions?: AssignPermissions): Promise<void> {
59
+ async assign(lhsTarget: any, resolvedParams: LazyLoadResolvedParams, options?: any, permissionProcessor?: PermissionProcessor): Promise<void> {
60
60
  this._options = options; // Store for applyAssign access
61
- this._permissions = permissions;
61
+ this._permissionProcessor = permissionProcessor;
62
62
  const {
63
63
  if: condition,
64
64
  instantiate,
@@ -320,10 +320,10 @@ export class LazyLoadHandler implements AssignFromHandler {
320
320
  const len = Math.min(elements.length, assign.configs.length);
321
321
  for (let j = 0; j < len; j++) {
322
322
  const cfg = assign.configs[j];
323
- assignFrom(elements[j], cfg.toClone ?? {}, { from, ...cfg.withOptions }, this._permissions);
323
+ assignFrom(elements[j], cfg.toClone ?? {}, { from, ...cfg.withOptions }, this._permissionProcessor);
324
324
  }
325
325
  } else if (assign.toClone) {
326
- assignFrom(elements[0], assign.toClone, { from, ...assign.withOptions }, this._permissions);
326
+ assignFrom(elements[0], assign.toClone, { from, ...assign.withOptions }, this._permissionProcessor);
327
327
  }
328
328
  }
329
329
 
@@ -21,7 +21,7 @@
21
21
  */
22
22
 
23
23
  import { LazyLoadHandler } from './lazyLoad.js';
24
- import type { AssignPermissions } from '../types/assign-gingerly/types.js';
24
+ import type { PermissionProcessor } from '../types/assign-gingerly/types.js';
25
25
  import type { AssignFromHandler } from '../assignFromAsync.js';
26
26
  import type { LazyLoadSwitchResolvedParams } from '../types/assign-gingerly/types.js';
27
27
 
@@ -56,10 +56,10 @@ function evaluateOp(lhs: any, op: string, rhs: any): boolean {
56
56
  */
57
57
  export class LazyLoadSwitchHandler extends LazyLoadHandler implements AssignFromHandler {
58
58
 
59
- async assign(lhsTarget: any, resolvedParams: LazyLoadSwitchResolvedParams, options?: any, permissions?: AssignPermissions): Promise<void> {
59
+ async assign(lhsTarget: any, resolvedParams: LazyLoadSwitchResolvedParams, options?: any, permissionProcessor?: PermissionProcessor): Promise<void> {
60
60
  const { lhs, op = '===', rhs, ...rest } = resolvedParams;
61
61
  const condition = evaluateOp(lhs, op, rhs);
62
62
  // Delegate to parent with computed condition
63
- return super.assign(lhsTarget, { ...rest, if: condition }, options, permissions);
63
+ return super.assign(lhsTarget, { ...rest, if: condition }, options, permissionProcessor);
64
64
  }
65
65
  }
@@ -25,7 +25,7 @@
25
25
  * }, { from: vm, withMethods: ['querySelector'], protocols: { globalThis: k => globalThis[k] } });
26
26
  */
27
27
  import { findMarkers, createMarkers } from '../markerUtils.js';
28
- import { resolveValue } from '../resolveValues.js';
28
+ import { resolveValue } from '../resolve/resolveValues.js';
29
29
  import { assignFrom } from '../assignFrom.js';
30
30
  import { processInferredAssignments } from '../inferredAssignments.js';
31
31
  /**
@@ -55,7 +55,7 @@ export class ManageTemplateListHandler {
55
55
  constructor(config) {
56
56
  this.config = config;
57
57
  }
58
- async assign(lhsTarget, resolvedParams, options, permissions) {
58
+ async assign(lhsTarget, resolvedParams, options, permissionProcessor) {
59
59
  //return;
60
60
  const { forEach: items, instantiate, method = 'appendChild', forget = false, markerName, yieldEvery, } = resolvedParams;
61
61
  if (!(lhsTarget instanceof Element)) {
@@ -143,7 +143,7 @@ export class ManageTemplateListHandler {
143
143
  const len = Math.min(elements.length, configs.length);
144
144
  for (let j = 0; j < len; j++) {
145
145
  const cfg = configs[j];
146
- assignFrom(elements[j], cfg.toClone ?? {}, { from: item, ...cfg.withOptions }, permissions);
146
+ assignFrom(elements[j], cfg.toClone ?? {}, { from: item, ...cfg.withOptions }, permissionProcessor);
147
147
  }
148
148
  }
149
149
  else {
@@ -153,13 +153,13 @@ export class ManageTemplateListHandler {
153
153
  processInferred(rootEl, item, inferredConfig === true ? { byItemprop: true } : inferredConfig);
154
154
  }
155
155
  else {
156
- assignFrom(rootEl, toClone, { from: item, ...withOptions }, permissions);
156
+ assignFrom(rootEl, toClone, { from: item, ...withOptions }, permissionProcessor);
157
157
  }
158
158
  if (hostToClone && options?.from) {
159
- assignFrom(rootEl, hostToClone, { from: options.from, ...hostWithOptions }, permissions);
159
+ assignFrom(rootEl, hostToClone, { from: options.from, ...hostWithOptions }, permissionProcessor);
160
160
  }
161
161
  if (targetToClone) {
162
- assignFrom(rootEl, targetToClone, { from: lhsTarget, ...targetWithOptions }, permissions);
162
+ assignFrom(rootEl, targetToClone, { from: lhsTarget, ...targetWithOptions }, permissionProcessor);
163
163
  }
164
164
  }
165
165
  }
@@ -192,7 +192,7 @@ export class ManageTemplateListHandler {
192
192
  const len = Math.min(elements.length, configs.length);
193
193
  for (let j = 0; j < len; j++) {
194
194
  const cfg = configs[j];
195
- assignFrom(elements[j], cfg.toClone ?? {}, { from: item, ...cfg.withOptions }, permissions);
195
+ assignFrom(elements[j], cfg.toClone ?? {}, { from: item, ...cfg.withOptions }, permissionProcessor);
196
196
  }
197
197
  }
198
198
  else {
@@ -204,13 +204,13 @@ export class ManageTemplateListHandler {
204
204
  processInferred(rootEl, item, inferredConfig === true ? { byItemprop: true } : inferredConfig);
205
205
  }
206
206
  else {
207
- assignFrom(rootEl, toClone, { from: item, ...withOptions }, permissions);
207
+ assignFrom(rootEl, toClone, { from: item, ...withOptions }, permissionProcessor);
208
208
  }
209
209
  if (hostToClone && options?.from) {
210
- assignFrom(rootEl, hostToClone, { from: options.from, ...hostWithOptions }, permissions);
210
+ assignFrom(rootEl, hostToClone, { from: options.from, ...hostWithOptions }, permissionProcessor);
211
211
  }
212
212
  if (targetToClone) {
213
- assignFrom(rootEl, targetToClone, { from: lhsTarget, ...targetWithOptions }, permissions);
213
+ assignFrom(rootEl, targetToClone, { from: lhsTarget, ...targetWithOptions }, permissionProcessor);
214
214
  }
215
215
  }
216
216
  }