@fuzdev/fuz_util 0.49.1 → 0.49.2

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.
@@ -123,6 +123,10 @@ export declare const generate_import_lines: (imports: Map<string, PreprocessImpo
123
123
  * `skip` set are excluded from traversal — used to skip `ImportDeclaration`
124
124
  * nodes so the import's own specifier identifier doesn't false-positive.
125
125
  *
126
+ * Skips `Identifier` nodes in non-reference positions defined by
127
+ * `NON_REFERENCE_FIELDS` — for example, `obj.Mdz` (non-computed member property),
128
+ * `{ Mdz: value }` (non-computed object key), and statement labels.
129
+ *
126
130
  * Safe for Svelte template ASTs: `Component.name` is a plain string property
127
131
  * (not an `Identifier` node), so `<Mdz>` tags do not produce false matches.
128
132
  *
@@ -1 +1 @@
1
- {"version":3,"file":"svelte_preprocess_helpers.d.ts","sourceRoot":"../src/lib/","sources":["../src/lib/svelte_preprocess_helpers.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAEH,OAAO,KAAK,EAAC,UAAU,EAAE,iBAAiB,EAAE,sBAAsB,EAAE,eAAe,EAAC,MAAM,QAAQ,CAAC;AACnG,OAAO,KAAK,EAAC,GAAG,EAAC,MAAM,iBAAiB,CAAC;AAEzC,qDAAqD;AACrD,MAAM,WAAW,oBAAoB;IACpC,sCAAsC;IACtC,IAAI,EAAE,MAAM,CAAC;IACb,iDAAiD;IACjD,IAAI,EAAE,SAAS,GAAG,OAAO,CAAC;CAC1B;AAED,qDAAqD;AACrD,MAAM,WAAW,uBAAuB;IACvC,gEAAgE;IAChE,WAAW,EAAE,iBAAiB,CAAC;IAC/B,mDAAmD;IACnD,SAAS,EAAE,eAAe,GAAG,sBAAsB,CAAC;CACpD;AAED;;;;;;;;;GASG;AACH,eAAO,MAAM,cAAc,GAAI,MAAM,GAAG,CAAC,SAAS,EAAE,MAAM,MAAM,KAAG,GAAG,CAAC,SAAS,GAAG,SAOlF,CAAC;AAEF;;;;;;;;;;;GAWG;AACH,eAAO,MAAM,oBAAoB,GAChC,MAAM,UAAU,EAChB,WAAW,WAAW,CAAC,MAAM,EAAE,MAAM,CAAC,KACpC,MAAM,GAAG,IA+BX,CAAC;AAEF;;;;;;;;;;;;;;GAcG;AACH,eAAO,MAAM,qBAAqB,GACjC,OAAO,GAAG,CAAC,SAAS,CAAC,OAAO,CAAC,EAC7B,WAAW,WAAW,CAAC,MAAM,EAAE,MAAM,CAAC,KACpC,MAAM,GAAG,IAkBX,CAAC;AAEF;;;;;;;;;;;;;GAaG;AACH,eAAO,MAAM,qBAAqB,GAAI,KAAK,GAAG,CAAC,IAAI,KAAG,GAAG,CAAC,MAAM,EAAE,MAAM,CAiBvE,CAAC;AAEF;;;;;;;;;;GAUG;AACH,eAAO,MAAM,uBAAuB,GACnC,KAAK,GAAG,CAAC,IAAI,EACb,mBAAmB,KAAK,CAAC,MAAM,CAAC,KAC9B,GAAG,CAAC,MAAM,EAAE,uBAAuB,CAcrC,CAAC;AAEF;;;;;;;;GAQG;AACH,eAAO,MAAM,2BAA2B,GAAI,QAAQ,GAAG,CAAC,MAAM,KAAG,MAYhE,CAAC;AAEF;;;;;;;;;GASG;AACH,eAAO,MAAM,qBAAqB,GACjC,SAAS,GAAG,CAAC,MAAM,EAAE,oBAAoB,CAAC,EAC1C,SAAQ,MAAa,KACnB,MAyBF,CAAC;AAEF;;;;;;;;;;;;;;;GAeG;AACH,eAAO,MAAM,sBAAsB,GAClC,MAAM,OAAO,EACb,MAAM,MAAM,EACZ,OAAO,GAAG,CAAC,OAAO,CAAC,KACjB,OAYF,CAAC;AAEF;;;;;;;;;;;;;;;GAeG;AACH,eAAO,MAAM,kBAAkB,GAAI,MAAM,MAAM,KAAG,MAc/C,CAAC"}
1
+ {"version":3,"file":"svelte_preprocess_helpers.d.ts","sourceRoot":"../src/lib/","sources":["../src/lib/svelte_preprocess_helpers.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAEH,OAAO,KAAK,EAAC,UAAU,EAAE,iBAAiB,EAAE,sBAAsB,EAAE,eAAe,EAAC,MAAM,QAAQ,CAAC;AACnG,OAAO,KAAK,EAAC,GAAG,EAAC,MAAM,iBAAiB,CAAC;AAEzC,qDAAqD;AACrD,MAAM,WAAW,oBAAoB;IACpC,sCAAsC;IACtC,IAAI,EAAE,MAAM,CAAC;IACb,iDAAiD;IACjD,IAAI,EAAE,SAAS,GAAG,OAAO,CAAC;CAC1B;AAED,qDAAqD;AACrD,MAAM,WAAW,uBAAuB;IACvC,gEAAgE;IAChE,WAAW,EAAE,iBAAiB,CAAC;IAC/B,mDAAmD;IACnD,SAAS,EAAE,eAAe,GAAG,sBAAsB,CAAC;CACpD;AAED;;;;;;;;;GASG;AACH,eAAO,MAAM,cAAc,GAAI,MAAM,GAAG,CAAC,SAAS,EAAE,MAAM,MAAM,KAAG,GAAG,CAAC,SAAS,GAAG,SAOlF,CAAC;AAEF;;;;;;;;;;;GAWG;AACH,eAAO,MAAM,oBAAoB,GAChC,MAAM,UAAU,EAChB,WAAW,WAAW,CAAC,MAAM,EAAE,MAAM,CAAC,KACpC,MAAM,GAAG,IA+BX,CAAC;AAEF;;;;;;;;;;;;;;GAcG;AACH,eAAO,MAAM,qBAAqB,GACjC,OAAO,GAAG,CAAC,SAAS,CAAC,OAAO,CAAC,EAC7B,WAAW,WAAW,CAAC,MAAM,EAAE,MAAM,CAAC,KACpC,MAAM,GAAG,IAkBX,CAAC;AAOF;;;;;;;;;;;;;GAaG;AACH,eAAO,MAAM,qBAAqB,GAAI,KAAK,GAAG,CAAC,IAAI,KAAG,GAAG,CAAC,MAAM,EAAE,MAAM,CAiBvE,CAAC;AAEF;;;;;;;;;;GAUG;AACH,eAAO,MAAM,uBAAuB,GACnC,KAAK,GAAG,CAAC,IAAI,EACb,mBAAmB,KAAK,CAAC,MAAM,CAAC,KAC9B,GAAG,CAAC,MAAM,EAAE,uBAAuB,CAcrC,CAAC;AAEF;;;;;;;;GAQG;AACH,eAAO,MAAM,2BAA2B,GAAI,QAAQ,GAAG,CAAC,MAAM,KAAG,MAYhE,CAAC;AAEF;;;;;;;;;GASG;AACH,eAAO,MAAM,qBAAqB,GACjC,SAAS,GAAG,CAAC,MAAM,EAAE,oBAAoB,CAAC,EAC1C,SAAQ,MAAa,KACnB,MAyBF,CAAC;AA0BF;;;;;;;;;;;;;;;;;;;GAmBG;AACH,eAAO,MAAM,sBAAsB,GAClC,MAAM,OAAO,EACb,MAAM,MAAM,EACZ,OAAO,GAAG,CAAC,OAAO,CAAC,KACjB,OAgBF,CAAC;AAEF;;;;;;;;;;;;;;;GAeG;AACH,eAAO,MAAM,kBAAkB,GAAI,MAAM,MAAM,KAAG,MAc/C,CAAC"}
@@ -112,6 +112,10 @@ export const extract_static_string = (value, bindings) => {
112
112
  return null;
113
113
  return evaluate_static_expr(expr, bindings);
114
114
  };
115
+ // TODO cross-import tracing: resolve `import {x} from './constants.js'` by reading
116
+ // and parsing the imported module, extracting `export const` values. Would need path
117
+ // resolution ($lib, tsconfig paths), a Program-node variant of this function, and
118
+ // cache invalidation when the imported file changes. Start with relative .ts/.js only.
115
119
  /**
116
120
  * Builds a map of statically resolvable `const` bindings from a Svelte AST.
117
121
  *
@@ -235,6 +239,26 @@ export const generate_import_lines = (imports, indent = '\t') => {
235
239
  }
236
240
  return lines.join('\n');
237
241
  };
242
+ /**
243
+ * ESTree node fields that contain `Identifier` nodes which are NOT binding references.
244
+ *
245
+ * Keyed by node type. Each entry lists fields to skip during identifier search,
246
+ * optionally conditioned on the node's `computed` property being falsy.
247
+ *
248
+ * Examples of non-reference positions:
249
+ * - `obj.Mdz` — `MemberExpression.property` when `computed: false`
250
+ * - `{ Mdz: value }` — `Property.key` when `computed: false`
251
+ * - `label: for(...)` — `LabeledStatement.label`
252
+ */
253
+ const NON_REFERENCE_FIELDS = new Map([
254
+ ['MemberExpression', [{ field: 'property', when_not_computed: true }]],
255
+ ['Property', [{ field: 'key', when_not_computed: true }]],
256
+ ['PropertyDefinition', [{ field: 'key', when_not_computed: true }]],
257
+ ['MethodDefinition', [{ field: 'key', when_not_computed: true }]],
258
+ ['LabeledStatement', [{ field: 'label' }]],
259
+ ['BreakStatement', [{ field: 'label' }]],
260
+ ['ContinueStatement', [{ field: 'label' }]],
261
+ ]);
238
262
  /**
239
263
  * Checks if an identifier with the given name appears anywhere in an AST subtree.
240
264
  *
@@ -243,6 +267,10 @@ export const generate_import_lines = (imports, indent = '\t') => {
243
267
  * `skip` set are excluded from traversal — used to skip `ImportDeclaration`
244
268
  * nodes so the import's own specifier identifier doesn't false-positive.
245
269
  *
270
+ * Skips `Identifier` nodes in non-reference positions defined by
271
+ * `NON_REFERENCE_FIELDS` — for example, `obj.Mdz` (non-computed member property),
272
+ * `{ Mdz: value }` (non-computed object key), and statement labels.
273
+ *
246
274
  * Safe for Svelte template ASTs: `Component.name` is a plain string property
247
275
  * (not an `Identifier` node), so `<Mdz>` tags do not produce false matches.
248
276
  *
@@ -262,7 +290,11 @@ export const has_identifier_in_tree = (node, name, skip) => {
262
290
  const record = node;
263
291
  if (record.type === 'Identifier' && record.name === name)
264
292
  return true;
293
+ const rules = NON_REFERENCE_FIELDS.get(record.type);
265
294
  for (const key of Object.keys(record)) {
295
+ if (rules?.some((r) => r.field === key && (!r.when_not_computed || !record.computed))) {
296
+ continue;
297
+ }
266
298
  if (has_identifier_in_tree(record[key], name, skip))
267
299
  return true;
268
300
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@fuzdev/fuz_util",
3
- "version": "0.49.1",
3
+ "version": "0.49.2",
4
4
  "description": "utility belt for JS",
5
5
  "glyph": "🦕",
6
6
  "logo": "logo.svg",
@@ -136,6 +136,11 @@ export const extract_static_string = (
136
136
  return evaluate_static_expr(expr, bindings);
137
137
  };
138
138
 
139
+ // TODO cross-import tracing: resolve `import {x} from './constants.js'` by reading
140
+ // and parsing the imported module, extracting `export const` values. Would need path
141
+ // resolution ($lib, tsconfig paths), a Program-node variant of this function, and
142
+ // cache invalidation when the imported file changes. Start with relative .ts/.js only.
143
+
139
144
  /**
140
145
  * Builds a map of statically resolvable `const` bindings from a Svelte AST.
141
146
  *
@@ -262,6 +267,30 @@ export const generate_import_lines = (
262
267
  return lines.join('\n');
263
268
  };
264
269
 
270
+ /**
271
+ * ESTree node fields that contain `Identifier` nodes which are NOT binding references.
272
+ *
273
+ * Keyed by node type. Each entry lists fields to skip during identifier search,
274
+ * optionally conditioned on the node's `computed` property being falsy.
275
+ *
276
+ * Examples of non-reference positions:
277
+ * - `obj.Mdz` — `MemberExpression.property` when `computed: false`
278
+ * - `{ Mdz: value }` — `Property.key` when `computed: false`
279
+ * - `label: for(...)` — `LabeledStatement.label`
280
+ */
281
+ const NON_REFERENCE_FIELDS: Map<
282
+ string,
283
+ Array<{field: string; when_not_computed?: boolean}>
284
+ > = new Map([
285
+ ['MemberExpression', [{field: 'property', when_not_computed: true}]],
286
+ ['Property', [{field: 'key', when_not_computed: true}]],
287
+ ['PropertyDefinition', [{field: 'key', when_not_computed: true}]],
288
+ ['MethodDefinition', [{field: 'key', when_not_computed: true}]],
289
+ ['LabeledStatement', [{field: 'label'}]],
290
+ ['BreakStatement', [{field: 'label'}]],
291
+ ['ContinueStatement', [{field: 'label'}]],
292
+ ]);
293
+
265
294
  /**
266
295
  * Checks if an identifier with the given name appears anywhere in an AST subtree.
267
296
  *
@@ -270,6 +299,10 @@ export const generate_import_lines = (
270
299
  * `skip` set are excluded from traversal — used to skip `ImportDeclaration`
271
300
  * nodes so the import's own specifier identifier doesn't false-positive.
272
301
  *
302
+ * Skips `Identifier` nodes in non-reference positions defined by
303
+ * `NON_REFERENCE_FIELDS` — for example, `obj.Mdz` (non-computed member property),
304
+ * `{ Mdz: value }` (non-computed object key), and statement labels.
305
+ *
273
306
  * Safe for Svelte template ASTs: `Component.name` is a plain string property
274
307
  * (not an `Identifier` node), so `<Mdz>` tags do not produce false matches.
275
308
  *
@@ -290,7 +323,11 @@ export const has_identifier_in_tree = (
290
323
  }
291
324
  const record = node as Record<string, unknown>;
292
325
  if (record.type === 'Identifier' && record.name === name) return true;
326
+ const rules = NON_REFERENCE_FIELDS.get(record.type as string);
293
327
  for (const key of Object.keys(record)) {
328
+ if (rules?.some((r) => r.field === key && (!r.when_not_computed || !record.computed))) {
329
+ continue;
330
+ }
294
331
  if (has_identifier_in_tree(record[key], name, skip)) return true;
295
332
  }
296
333
  return false;