assign-gingerly 0.0.71 → 0.0.72

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/eachTime.ts CHANGED
@@ -4,7 +4,9 @@
4
4
  * Provides event-driven iteration over elements as they mount
5
5
  */
6
6
 
7
- import type { IAssignGingerlyOptions } from './types/assign-gingerly/types.js';
7
+ import type { IAssignGingerlyOptions } from './types/assign-gingerly/types.js';
8
+ import type { AssignPermissions, RestrictedPropSettingsMap } from './isAllowedImportPath.js';
9
+ import { redirectRestrictedProp } from './isAllowedImportPath.js';
8
10
 
9
11
  /**
10
12
  * Check if a value is an EventTarget
@@ -29,9 +31,11 @@ export async function handleEachTime(
29
31
  pathParts: string[],
30
32
  forEachIndex: number,
31
33
  value: any,
32
- withMethods: Set<string> | undefined,
33
- aliasMap: Map<string, string>,
34
- options?: IAssignGingerlyOptions
34
+ withMethods: Set<string> | undefined,
35
+ aliasMap: Map<string, string>,
36
+ options?: IAssignGingerlyOptions,
37
+ permissions?: AssignPermissions,
38
+ restrictedPropSet?: RestrictedPropSettingsMap
35
39
  ): Promise<void> {
36
40
  // Validate signal - required for cleanup
37
41
  if (!options?.signal) {
@@ -92,7 +96,10 @@ export async function handleEachTime(
92
96
  // Last segment is a method - call it
93
97
  const method = result.target[result.lastKey];
94
98
  if (typeof method === 'function') {
95
- if (Array.isArray(value)) {
99
+ if (result.isZeroArg) {
100
+ // Trailing | marker - call with no arguments, ignoring the value
101
+ method.call(result.target);
102
+ } else if (Array.isArray(value)) {
96
103
  method.apply(result.target, value);
97
104
  } else {
98
105
  method.call(result.target, value);
@@ -103,7 +110,9 @@ export async function handleEachTime(
103
110
  const lastKey = result.lastKey;
104
111
  const parent = result.target;
105
112
 
106
- if (typeof value === 'object' && value !== null && !Array.isArray(value)) {
113
+ if (redirectRestrictedProp(restrictedPropSet, parent, lastKey, value)) {
114
+ // skip
115
+ } else if (typeof value === 'object' && value !== null && !Array.isArray(value)) {
107
116
  // Check if property exists and is readonly
108
117
  if (lastKey in parent && isReadonlyProperty(parent, lastKey)) {
109
118
  const currentValue = parent[lastKey];
@@ -113,7 +122,7 @@ export async function handleEachTime(
113
122
  );
114
123
  }
115
124
  // Recursively apply assignGingerly
116
- assignGingerly(currentValue, value, options);
125
+ assignGingerly(currentValue, value, options, permissions);
117
126
  } else {
118
127
  // Property is writable - replace it
119
128
  parent[lastKey] = value;
@@ -28,12 +28,19 @@ export async function evaluatePathWithAsyncMethods(target, pathParts, value, wit
28
28
  while (i < pathParts.length - 1) {
29
29
  const part = pathParts[i];
30
30
  const nextPart = pathParts[i + 1];
31
- if (withAsyncMethods.has(part)) {
31
+ // A trailing | marks a zero-argument method call: 'deref|' calls deref()
32
+ // 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));
35
+ const baseName = (isZeroArgSync || isZeroArgAsync) ? part.slice(0, -1) : part;
36
+ const nextIsMethod = withAsyncMethods.has(nextPart) || withMethods.has(nextPart)
37
+ || (nextPart.endsWith('|') && (withAsyncMethods.has(nextPart.slice(0, -1)) || withMethods.has(nextPart.slice(0, -1))));
38
+ if (withAsyncMethods.has(part) || isZeroArgAsync) {
32
39
  // Async method — call and await
33
- const method = current[part];
40
+ const method = current[baseName];
34
41
  if (typeof method === 'function') {
35
- if (withAsyncMethods.has(nextPart) || withMethods.has(nextPart)) {
36
- // Next is also a method call current with no args
42
+ if (isZeroArgAsync || nextIsMethod) {
43
+ // Zero-arg call — next is either a method or explicitly not an argument
37
44
  current = await method.call(current);
38
45
  }
39
46
  else {
@@ -44,18 +51,18 @@ export async function evaluatePathWithAsyncMethods(target, pathParts, value, wit
44
51
  }
45
52
  else {
46
53
  // Not a function — just access property
47
- if (current[part] === undefined || current[part] === null) {
48
- current[part] = {};
54
+ if (current[baseName] === undefined || current[baseName] === null) {
55
+ current[baseName] = {};
49
56
  }
50
- current = current[part];
57
+ current = current[baseName];
51
58
  }
52
59
  }
53
- else if (withMethods.has(part)) {
60
+ else if (withMethods.has(part) || isZeroArgSync) {
54
61
  // Sync method — same logic as evaluatePathWithMethods
55
- const method = current[part];
62
+ const method = current[baseName];
56
63
  if (typeof method === 'function') {
57
- if (withMethods.has(nextPart) || withAsyncMethods.has(nextPart)) {
58
- // Next is also a method call current with no args
64
+ if (isZeroArgSync || nextIsMethod) {
65
+ // Zero-arg call — next is either a method or explicitly not an argument
59
66
  current = method.call(current);
60
67
  }
61
68
  else {
@@ -65,10 +72,10 @@ export async function evaluatePathWithAsyncMethods(target, pathParts, value, wit
65
72
  }
66
73
  }
67
74
  else {
68
- if (!(part in current) || typeof current[part] !== 'object' || current[part] === null) {
69
- current[part] = {};
75
+ if (!(baseName in current) || typeof current[baseName] !== 'object' || current[baseName] === null) {
76
+ current[baseName] = {};
70
77
  }
71
- current = current[part];
78
+ current = current[baseName];
72
79
  }
73
80
  }
74
81
  else {
@@ -80,11 +87,17 @@ export async function evaluatePathWithAsyncMethods(target, pathParts, value, wit
80
87
  }
81
88
  i++;
82
89
  }
83
- const lastKey = pathParts[pathParts.length - 1];
90
+ // Strip a trailing | from the last segment only when it names a listed method;
91
+ // otherwise it is a literal property name (e.g. an exotic key ending in |).
92
+ const rawLastKey = pathParts[pathParts.length - 1];
93
+ const isZeroArg = rawLastKey.endsWith('|')
94
+ && (withMethods.has(rawLastKey.slice(0, -1)) || withAsyncMethods.has(rawLastKey.slice(0, -1)));
95
+ const lastKey = isZeroArg ? rawLastKey.slice(0, -1) : rawLastKey;
84
96
  return {
85
97
  target: current,
86
98
  lastKey,
87
99
  isMethod: withMethods.has(lastKey),
88
- isAsyncMethod: withAsyncMethods.has(lastKey)
100
+ isAsyncMethod: withAsyncMethods.has(lastKey),
101
+ isZeroArg
89
102
  };
90
103
  }
@@ -16,6 +16,7 @@ export interface AsyncPathResult {
16
16
  lastKey: string;
17
17
  isMethod: boolean;
18
18
  isAsyncMethod: boolean;
19
+ isZeroArg: boolean;
19
20
  }
20
21
 
21
22
  /**
@@ -44,12 +45,20 @@ export async function evaluatePathWithAsyncMethods(
44
45
  const part = pathParts[i];
45
46
  const nextPart = pathParts[i + 1];
46
47
 
47
- if (withAsyncMethods.has(part)) {
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) {
48
57
  // Async method — call and await
49
- const method = current[part];
58
+ const method = current[baseName];
50
59
  if (typeof method === 'function') {
51
- if (withAsyncMethods.has(nextPart) || withMethods.has(nextPart)) {
52
- // Next is also a method call current with no args
60
+ if (isZeroArgAsync || nextIsMethod) {
61
+ // Zero-arg call — next is either a method or explicitly not an argument
53
62
  current = await method.call(current);
54
63
  } else {
55
64
  // Call with next part as string arg, then await
@@ -58,17 +67,17 @@ export async function evaluatePathWithAsyncMethods(
58
67
  }
59
68
  } else {
60
69
  // Not a function — just access property
61
- if (current[part] === undefined || current[part] === null) {
62
- current[part] = {};
70
+ if (current[baseName] === undefined || current[baseName] === null) {
71
+ current[baseName] = {};
63
72
  }
64
- current = current[part];
73
+ current = current[baseName];
65
74
  }
66
- } else if (withMethods.has(part)) {
75
+ } else if (withMethods.has(part) || isZeroArgSync) {
67
76
  // Sync method — same logic as evaluatePathWithMethods
68
- const method = current[part];
77
+ const method = current[baseName];
69
78
  if (typeof method === 'function') {
70
- if (withMethods.has(nextPart) || withAsyncMethods.has(nextPart)) {
71
- // Next is also a method call current with no args
79
+ if (isZeroArgSync || nextIsMethod) {
80
+ // Zero-arg call — next is either a method or explicitly not an argument
72
81
  current = method.call(current);
73
82
  } else {
74
83
  // Call with next part as string arg
@@ -76,10 +85,10 @@ export async function evaluatePathWithAsyncMethods(
76
85
  i++; // Skip next part since we consumed it as argument
77
86
  }
78
87
  } else {
79
- if (!(part in current) || typeof current[part] !== 'object' || current[part] === null) {
80
- current[part] = {};
88
+ if (!(baseName in current) || typeof current[baseName] !== 'object' || current[baseName] === null) {
89
+ current[baseName] = {};
81
90
  }
82
- current = current[part];
91
+ current = current[baseName];
83
92
  }
84
93
  } else {
85
94
  // Not a method — normal property access
@@ -92,11 +101,17 @@ export async function evaluatePathWithAsyncMethods(
92
101
  i++;
93
102
  }
94
103
 
95
- const lastKey = pathParts[pathParts.length - 1];
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;
96
110
  return {
97
111
  target: current,
98
112
  lastKey,
99
113
  isMethod: withMethods.has(lastKey),
100
- isAsyncMethod: withAsyncMethods.has(lastKey)
114
+ isAsyncMethod: withAsyncMethods.has(lastKey),
115
+ isZeroArg
101
116
  };
102
117
  }
@@ -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) {
40
+ function processVector(vector, source, target, host, lhs, inheritedOptions, useAssignFrom, permissions) {
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 });
53
+ assignFrom(dest, pattern, { from: source, ...inheritedOptions, ...vector.withOptions }, permissions);
54
54
  });
55
55
  }
56
56
  else {
57
- assignGingerly(dest, pattern, inheritedOptions);
57
+ assignGingerly(dest, pattern, inheritedOptions, permissions);
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 });
65
+ assignFrom(host, shorthand, { from: source, ...inheritedOptions, ...vector.withOptions }, permissions);
66
66
  });
67
67
  }
68
68
  else {
69
- assignGingerly(host, shorthand, inheritedOptions);
69
+ assignGingerly(host, shorthand, inheritedOptions, permissions);
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) {
82
+ export function attachEventListener(lhs, config, target, host, inheritedOptions, permissions) {
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);
115
+ processVector(config, null, target, host, lhs, inheritedOptions, false, permissions);
116
116
  // fromLHS assignments
117
117
  if (fromLHS) {
118
- processVector(fromLHS, lhs, target, host, lhs, inheritedOptions, true);
118
+ processVector(fromLHS, lhs, target, host, lhs, inheritedOptions, true, permissions);
119
119
  }
120
120
  // fromHost assignments
121
121
  if (fromHost) {
122
- processVector(fromHost, host, target, host, lhs, inheritedOptions, true);
122
+ processVector(fromHost, host, target, host, lhs, inheritedOptions, true, permissions);
123
123
  }
124
124
  // fromTarget assignments
125
125
  if (fromTarget) {
126
- processVector(fromTarget, target, target, host, lhs, inheritedOptions, true);
126
+ processVector(fromTarget, target, target, host, lhs, inheritedOptions, true, permissions);
127
127
  }
128
128
  // fromEvent assignments
129
129
  if (fromEvent) {
130
- processVector(fromEvent, event, target, host, lhs, inheritedOptions, true);
130
+ processVector(fromEvent, event, target, host, lhs, inheritedOptions, true, permissions);
131
131
  }
132
132
  // Dispatch custom event if configured
133
133
  const dispatchConfig = dispatch || getDispatch;
@@ -7,8 +7,9 @@
7
7
  * Attaches an event listener that executes assign vectors on event fire.
8
8
  */
9
9
 
10
- import assignGingerly from '../assignGingerly.js';
11
- import type { AddEventListenerConfig, AssignDispatchVector } from '../types/assign-gingerly/types.js';
10
+ import assignGingerly from '../assignGingerly.js';
11
+ import type { AddEventListenerConfig, AssignDispatchVector } from '../types/assign-gingerly/types.js';
12
+ import type { AssignPermissions } from '../isAllowedImportPath.js';
12
13
 
13
14
  /**
14
15
  * WeakMap for dedup: Element → Map<key, AbortController>
@@ -48,9 +49,10 @@ function processVector(
48
49
  source: any,
49
50
  target: any,
50
51
  host: any,
51
- lhs: Element,
52
- inheritedOptions: any,
53
- useAssignFrom: boolean
52
+ lhs: Element,
53
+ inheritedOptions: any,
54
+ useAssignFrom: boolean,
55
+ permissions?: AssignPermissions
54
56
  ): void {
55
57
  const destinations = [
56
58
  { key: 'toTarget' as const, dest: target },
@@ -64,10 +66,10 @@ function processVector(
64
66
  if (useAssignFrom && source != null) {
65
67
  // Dynamic import assignFrom on demand (fire-and-forget context, already async)
66
68
  import('../assignFrom.js').then(({ assignFrom }) => {
67
- assignFrom(dest, pattern, { from: source, ...inheritedOptions, ...vector.withOptions });
69
+ assignFrom(dest, pattern, { from: source, ...inheritedOptions, ...vector.withOptions }, permissions);
68
70
  });
69
71
  } else {
70
- assignGingerly(dest, pattern, inheritedOptions);
72
+ assignGingerly(dest, pattern, inheritedOptions, permissions);
71
73
  }
72
74
  }
73
75
 
@@ -76,10 +78,10 @@ function processVector(
76
78
  if (shorthand) {
77
79
  if (useAssignFrom && source != null) {
78
80
  import('../assignFrom.js').then(({ assignFrom }) => {
79
- assignFrom(host, shorthand, { from: source, ...inheritedOptions, ...vector.withOptions });
81
+ assignFrom(host, shorthand, { from: source, ...inheritedOptions, ...vector.withOptions }, permissions);
80
82
  });
81
83
  } else {
82
- assignGingerly(host, shorthand, inheritedOptions);
84
+ assignGingerly(host, shorthand, inheritedOptions, permissions);
83
85
  }
84
86
  }
85
87
  }
@@ -98,7 +100,8 @@ export function attachEventListener(
98
100
  config: AddEventListenerConfig,
99
101
  target: any,
100
102
  host: any,
101
- inheritedOptions: any
103
+ inheritedOptions: any,
104
+ permissions?: AssignPermissions
102
105
  ): void {
103
106
  const { on: eventName, get: getConfig, fromLHS, fromHost, fromTarget, fromEvent, dispatch } = config;
104
107
 
@@ -131,26 +134,26 @@ export function attachEventListener(
131
134
  if (preventDefault) event.preventDefault();
132
135
 
133
136
  // Static assignments (no from) — top-level toTarget/toHost/toLHS + shorthand
134
- processVector(config, null, target, host, lhs, inheritedOptions, false);
137
+ processVector(config, null, target, host, lhs, inheritedOptions, false, permissions);
135
138
 
136
139
  // fromLHS assignments
137
140
  if (fromLHS) {
138
- processVector(fromLHS, lhs, target, host, lhs, inheritedOptions, true);
141
+ processVector(fromLHS, lhs, target, host, lhs, inheritedOptions, true, permissions);
139
142
  }
140
143
 
141
144
  // fromHost assignments
142
145
  if (fromHost) {
143
- processVector(fromHost, host, target, host, lhs, inheritedOptions, true);
146
+ processVector(fromHost, host, target, host, lhs, inheritedOptions, true, permissions);
144
147
  }
145
148
 
146
149
  // fromTarget assignments
147
150
  if (fromTarget) {
148
- processVector(fromTarget, target, target, host, lhs, inheritedOptions, true);
151
+ processVector(fromTarget, target, target, host, lhs, inheritedOptions, true, permissions);
149
152
  }
150
153
 
151
154
  // fromEvent assignments
152
155
  if (fromEvent) {
153
- processVector(fromEvent, event, target, host, lhs, inheritedOptions, true);
156
+ processVector(fromEvent, event, target, host, lhs, inheritedOptions, true, permissions);
154
157
  }
155
158
 
156
159
  // Dispatch custom event if configured
@@ -23,7 +23,8 @@ import type { AssignFromHandler } from '../assignFromAsync.js';
23
23
  import type { LazyLoadResolvedParams, LazyLoadInstantiatedContext } 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
- import { assignFrom } from '../assignFrom.js';
26
+ import { assignFrom } from '../assignFrom.js';
27
+ import type { AssignPermissions } from '../isAllowedImportPath.js';
27
28
 
28
29
  export type { LazyLoadResolvedParams, LazyLoadInstantiatedContext };
29
30
 
@@ -46,16 +47,18 @@ function getMarkerName(templateEl: any): string {
46
47
  * Exported so it can be subclassed for custom behavior.
47
48
  */
48
49
  export class LazyLoadHandler implements AssignFromHandler {
49
- config: any;
50
- _options: any;
50
+ config: any;
51
+ _options: any;
52
+ _permissions?: AssignPermissions;
51
53
  static #markerCounter = 0;
52
54
 
53
55
  constructor(config: any) {
54
56
  this.config = config;
55
57
  }
56
58
 
57
- async assign(lhsTarget: any, resolvedParams: LazyLoadResolvedParams, options?: any): Promise<void> {
58
- this._options = options; // Store for applyAssign access
59
+ async assign(lhsTarget: any, resolvedParams: LazyLoadResolvedParams, options?: any, permissions?: AssignPermissions): Promise<void> {
60
+ this._options = options; // Store for applyAssign access
61
+ this._permissions = permissions;
59
62
  const {
60
63
  if: condition,
61
64
  instantiate,
@@ -317,10 +320,10 @@ export class LazyLoadHandler implements AssignFromHandler {
317
320
  const len = Math.min(elements.length, assign.configs.length);
318
321
  for (let j = 0; j < len; j++) {
319
322
  const cfg = assign.configs[j];
320
- assignFrom(elements[j], cfg.toClone ?? {}, { from, ...cfg.withOptions });
323
+ assignFrom(elements[j], cfg.toClone ?? {}, { from, ...cfg.withOptions }, this._permissions);
321
324
  }
322
325
  } else if (assign.toClone) {
323
- assignFrom(elements[0], assign.toClone, { from, ...assign.withOptions });
326
+ assignFrom(elements[0], assign.toClone, { from, ...assign.withOptions }, this._permissions);
324
327
  }
325
328
  }
326
329
 
@@ -20,7 +20,8 @@
20
20
  * }, { withMethods: ['querySelector'], from: vm, protocols: { globalThis: k => globalThis[k] } });
21
21
  */
22
22
 
23
- import { LazyLoadHandler } from './lazyLoad.js';
23
+ import { LazyLoadHandler } from './lazyLoad.js';
24
+ import type { AssignPermissions } from '../isAllowedImportPath.js';
24
25
  import type { AssignFromHandler } from '../assignFromAsync.js';
25
26
  import type { LazyLoadSwitchResolvedParams } from '../types/assign-gingerly/types.js';
26
27
 
@@ -55,10 +56,10 @@ function evaluateOp(lhs: any, op: string, rhs: any): boolean {
55
56
  */
56
57
  export class LazyLoadSwitchHandler extends LazyLoadHandler implements AssignFromHandler {
57
58
 
58
- async assign(lhsTarget: any, resolvedParams: LazyLoadSwitchResolvedParams): Promise<void> {
59
+ async assign(lhsTarget: any, resolvedParams: LazyLoadSwitchResolvedParams, options?: any, permissions?: AssignPermissions): Promise<void> {
59
60
  const { lhs, op = '===', rhs, ...rest } = resolvedParams;
60
61
  const condition = evaluateOp(lhs, op, rhs);
61
62
  // Delegate to parent with computed condition
62
- return super.assign(lhsTarget, { ...rest, if: condition });
63
+ return super.assign(lhsTarget, { ...rest, if: condition }, options, permissions);
63
64
  }
64
65
  }
@@ -55,7 +55,7 @@ export class ManageTemplateListHandler {
55
55
  constructor(config) {
56
56
  this.config = config;
57
57
  }
58
- async assign(lhsTarget, resolvedParams, options) {
58
+ async assign(lhsTarget, resolvedParams, options, permissions) {
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 });
146
+ assignFrom(elements[j], cfg.toClone ?? {}, { from: item, ...cfg.withOptions }, permissions);
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 });
156
+ assignFrom(rootEl, toClone, { from: item, ...withOptions }, permissions);
157
157
  }
158
158
  if (hostToClone && options?.from) {
159
- assignFrom(rootEl, hostToClone, { from: options.from, ...hostWithOptions });
159
+ assignFrom(rootEl, hostToClone, { from: options.from, ...hostWithOptions }, permissions);
160
160
  }
161
161
  if (targetToClone) {
162
- assignFrom(rootEl, targetToClone, { from: lhsTarget, ...targetWithOptions });
162
+ assignFrom(rootEl, targetToClone, { from: lhsTarget, ...targetWithOptions }, permissions);
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 });
195
+ assignFrom(elements[j], cfg.toClone ?? {}, { from: item, ...cfg.withOptions }, permissions);
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 });
207
+ assignFrom(rootEl, toClone, { from: item, ...withOptions }, permissions);
208
208
  }
209
209
  if (hostToClone && options?.from) {
210
- assignFrom(rootEl, hostToClone, { from: options.from, ...hostWithOptions });
210
+ assignFrom(rootEl, hostToClone, { from: options.from, ...hostWithOptions }, permissions);
211
211
  }
212
212
  if (targetToClone) {
213
- assignFrom(rootEl, targetToClone, { from: lhsTarget, ...targetWithOptions });
213
+ assignFrom(rootEl, targetToClone, { from: lhsTarget, ...targetWithOptions }, permissions);
214
214
  }
215
215
  }
216
216
  }
@@ -30,7 +30,8 @@ import type { ManageTemplateListResolvedParams } from '../types/assign-gingerly/
30
30
  import { findMarkers, createMarkers, getNodesBetweenMarkers, MARKER_START_PREFIX, MARKER_END } from '../markerUtils.js';
31
31
  import { resolveValue } from '../resolveValues.js';
32
32
  import { assignFrom } from '../assignFrom.js';
33
- import { processInferredAssignments } from '../inferredAssignments.js';
33
+ import { processInferredAssignments } from '../inferredAssignments.js';
34
+ import type { AssignPermissions } from '../isAllowedImportPath.js';
34
35
 
35
36
  /**
36
37
  * Reserved keys in fromEachItem config — not treated as shorthand patterns.
@@ -74,7 +75,7 @@ export class ManageTemplateListHandler implements AssignFromHandler {
74
75
  this.config = config;
75
76
  }
76
77
 
77
- async assign(lhsTarget: any, resolvedParams: ManageTemplateListResolvedParams, options?: any): Promise<void> {
78
+ async assign(lhsTarget: any, resolvedParams: ManageTemplateListResolvedParams, options?: any, permissions?: AssignPermissions): Promise<void> {
78
79
  //return;
79
80
  const {
80
81
  forEach: items,
@@ -183,7 +184,7 @@ export class ManageTemplateListHandler implements AssignFromHandler {
183
184
  const len = Math.min(elements.length, configs.length);
184
185
  for (let j = 0; j < len; j++) {
185
186
  const cfg = configs[j];
186
- assignFrom(elements[j], cfg.toClone ?? {}, { from: item, ...cfg.withOptions });
187
+ assignFrom(elements[j], cfg.toClone ?? {}, { from: item, ...cfg.withOptions }, permissions);
187
188
  }
188
189
  } else {
189
190
  const rootEl = existingNodes.find(n => n instanceof Element) as Element | undefined;
@@ -191,13 +192,13 @@ export class ManageTemplateListHandler implements AssignFromHandler {
191
192
  if (processInferred) {
192
193
  processInferred(rootEl, item, inferredConfig === true ? { byItemprop: true } : inferredConfig);
193
194
  } else {
194
- assignFrom(rootEl, toClone, { from: item, ...withOptions });
195
+ assignFrom(rootEl, toClone, { from: item, ...withOptions }, permissions);
195
196
  }
196
197
  if (hostToClone && options?.from) {
197
- assignFrom(rootEl, hostToClone, { from: options.from, ...hostWithOptions });
198
+ assignFrom(rootEl, hostToClone, { from: options.from, ...hostWithOptions }, permissions);
198
199
  }
199
200
  if (targetToClone) {
200
- assignFrom(rootEl, targetToClone, { from: lhsTarget, ...targetWithOptions });
201
+ assignFrom(rootEl, targetToClone, { from: lhsTarget, ...targetWithOptions }, permissions);
201
202
  }
202
203
  }
203
204
  }
@@ -228,7 +229,7 @@ export class ManageTemplateListHandler implements AssignFromHandler {
228
229
  const len = Math.min(elements.length, configs.length);
229
230
  for (let j = 0; j < len; j++) {
230
231
  const cfg = configs[j];
231
- assignFrom(elements[j], cfg.toClone ?? {}, { from: item, ...cfg.withOptions });
232
+ assignFrom(elements[j], cfg.toClone ?? {}, { from: item, ...cfg.withOptions }, permissions);
232
233
  }
233
234
  } else {
234
235
  const rootEl = clonedNodes.find(n => n instanceof Element) as Element | undefined;
@@ -239,14 +240,14 @@ export class ManageTemplateListHandler implements AssignFromHandler {
239
240
  if (processInferred) {
240
241
  processInferred(rootEl, item, inferredConfig === true ? { byItemprop: true } : inferredConfig);
241
242
  } else {
242
- assignFrom(rootEl, toClone, { from: item, ...withOptions });
243
+ assignFrom(rootEl, toClone, { from: item, ...withOptions }, permissions);
243
244
  }
244
245
 
245
246
  if (hostToClone && options?.from) {
246
- assignFrom(rootEl, hostToClone, { from: options.from, ...hostWithOptions });
247
+ assignFrom(rootEl, hostToClone, { from: options.from, ...hostWithOptions }, permissions);
247
248
  }
248
249
  if (targetToClone) {
249
- assignFrom(rootEl, targetToClone, { from: lhsTarget, ...targetWithOptions });
250
+ assignFrom(rootEl, targetToClone, { from: lhsTarget, ...targetWithOptions }, permissions);
250
251
  }
251
252
  }
252
253
  }
@@ -22,7 +22,8 @@
22
22
  */
23
23
 
24
24
  import type { AssignFromHandler } from '../assignFromAsync.js';
25
- import assignGingerly from '../assignGingerly.js';
25
+ import assignGingerly from '../assignGingerly.js';
26
+ import type { AssignPermissions } from '../isAllowedImportPath.js';
26
27
 
27
28
  /**
28
29
  * Operator keys recognized in case objects.
@@ -72,7 +73,7 @@ export class RangeSelectorHandler implements AssignFromHandler {
72
73
  this.config = config;
73
74
  }
74
75
 
75
- async assign(lhsTarget: any, resolvedParams: any): Promise<void> {
76
+ async assign(lhsTarget: any, resolvedParams: any, _options?: any, permissions?: AssignPermissions): Promise<void> {
76
77
  const { value, when } = resolvedParams;
77
78
 
78
79
  if (!Array.isArray(when)) return;
@@ -81,7 +82,7 @@ export class RangeSelectorHandler implements AssignFromHandler {
81
82
  for (const caseObj of when) {
82
83
  if (caseMatches(value, caseObj)) {
83
84
  if (caseObj.merge && typeof caseObj.merge === 'object') {
84
- assignGingerly(lhsTarget, caseObj.merge);
85
+ assignGingerly(lhsTarget, caseObj.merge, undefined, permissions);
85
86
  }
86
87
  return; // First match wins
87
88
  }