@deneb-ui/cli 2.0.30 → 2.0.31

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 (2) hide show
  1. package/package.json +2 -2
  2. package/src/arc/ast.cjs +18 -10
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@deneb-ui/cli",
3
- "version": "2.0.30",
3
+ "version": "2.0.31",
4
4
  "description": "Official DENEB CLI — scaffold, convert, validate, and package Fivora-ready storefront templates.",
5
5
  "bin": {
6
6
  "deneb": "bin/index.js",
@@ -49,7 +49,7 @@
49
49
  "license": "MIT",
50
50
  "dependencies": {
51
51
  "@babel/parser": "^7.28.0",
52
- "@deneb-ui/core": "^2.0.30",
52
+ "@deneb-ui/core": "^2.0.31",
53
53
  "adm-zip": "^0.6.0",
54
54
  "recast": "^0.23.11"
55
55
  },
package/src/arc/ast.cjs CHANGED
@@ -267,22 +267,30 @@ function hasDirective(ast, value) {
267
267
  function ensureImport(ast, source, names) {
268
268
  const program = ast.program || ast;
269
269
  const body = program.body || [];
270
+
271
+ // Deduplicate against any import in the entire module so we never import the same identifier twice
272
+ const alreadyImported = new Set();
273
+ for (const node of body) {
274
+ if (node.type === 'ImportDeclaration' && Array.isArray(node.specifiers)) {
275
+ for (const spec of node.specifiers) {
276
+ const local = spec.local?.name || spec.imported?.name;
277
+ if (local) alreadyImported.add(local);
278
+ }
279
+ }
280
+ }
281
+
282
+ const namesToImport = names.filter((name) => !alreadyImported.has(name));
283
+ if (namesToImport.length === 0) return;
284
+
270
285
  const existing = body.find((node) => node.type === 'ImportDeclaration' && node.source && node.source.value === source);
271
286
  if (existing) {
272
- const already = new Set(
273
- (existing.specifiers || [])
274
- .filter((s) => s.type === 'ImportSpecifier')
275
- .map((s) => s.imported?.name || s.local?.name)
276
- );
277
- for (const name of names) {
278
- if (!already.has(name)) {
279
- existing.specifiers.push(b.importSpecifier(b.identifier(name), b.identifier(name)));
280
- }
287
+ for (const name of namesToImport) {
288
+ existing.specifiers.push(b.importSpecifier(b.identifier(name), b.identifier(name)));
281
289
  }
282
290
  return;
283
291
  }
284
292
 
285
- const specifiers = names.map((name) => b.importSpecifier(b.identifier(name), b.identifier(name)));
293
+ const specifiers = namesToImport.map((name) => b.importSpecifier(b.identifier(name), b.identifier(name)));
286
294
  const decl = b.importDeclaration(specifiers, b.stringLiteral(source));
287
295
  let insertAt = 0;
288
296
  if (body[0] && body[0].type === 'ExpressionStatement') insertAt = 1;