@archie/devtools 0.0.10 → 0.0.11

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/dist/index.mjs CHANGED
@@ -1,21 +1,503 @@
1
+ import "./chunk-QZ7TP4HQ.mjs";
2
+
3
+ // src/client/dnd/virtual/dndScopeVirtualModule.ts
4
+ var INTERNAL_DND_SCOPE_IMPORT_SOURCE = "virtual:archie-devtools/dnd-scope";
5
+ var RESOLVED_DND_SCOPE_MODULE_ID = `\0${INTERNAL_DND_SCOPE_IMPORT_SOURCE}`;
6
+ function getDndScopeVirtualModuleSource() {
7
+ return `
8
+ import React from 'react';
9
+
10
+ export function DndScope({ id, tag = 'div', tagProps = {}, items = [], direction }) {
11
+ void direction;
12
+ const children = Array.isArray(items)
13
+ ? items.map((item) => React.createElement(React.Fragment, { key: item.id }, item.node))
14
+ : [];
15
+
16
+ return React.createElement(
17
+ tag,
18
+ { ...(tagProps || {}), 'data-dnd-scope': id },
19
+ ...children,
20
+ );
21
+ }
22
+ `;
23
+ }
24
+
25
+ // src/client/dnd/babel-plugin-dnd-auto.ts
26
+ var SCOPE_LOCAL = "__DndScope";
27
+ function babelPluginDndAuto({ types: t }, opts = {}) {
28
+ const {
29
+ fileMatch,
30
+ fileExclude = /node_modules/,
31
+ minComponents = 2,
32
+ importSource = INTERNAL_DND_SCOPE_IMPORT_SOURCE
33
+ } = opts;
34
+ function getJSXTagName(el) {
35
+ const { name } = el;
36
+ if (t.isJSXIdentifier(name)) return name.name;
37
+ if (t.isJSXMemberExpression(name)) {
38
+ const obj = t.isJSXIdentifier(name.object) ? name.object.name : "";
39
+ return `${obj}.${name.property.name}`;
40
+ }
41
+ return "";
42
+ }
43
+ function isHTMLTag(name) {
44
+ return name.length > 0 && name[0] === name[0].toLowerCase();
45
+ }
46
+ function isPascalTag(name) {
47
+ return name.length > 0 && name[0] !== name[0].toLowerCase();
48
+ }
49
+ function attrsToObject(attrs) {
50
+ const props = [];
51
+ for (const attr of attrs) {
52
+ if (!t.isJSXAttribute(attr)) continue;
53
+ const keyName = t.isJSXIdentifier(attr.name) ? attr.name.name : attr.name.name.name;
54
+ let value;
55
+ if (attr.value === null || attr.value === void 0) {
56
+ value = t.booleanLiteral(true);
57
+ } else if (t.isStringLiteral(attr.value)) {
58
+ value = attr.value;
59
+ } else if (t.isJSXExpressionContainer(attr.value)) {
60
+ const expr = attr.value.expression;
61
+ value = t.isJSXEmptyExpression(expr) ? t.booleanLiteral(true) : expr;
62
+ } else {
63
+ continue;
64
+ }
65
+ props.push(t.objectProperty(t.identifier(keyName), value));
66
+ }
67
+ return t.objectExpression(props);
68
+ }
69
+ function buildItemObject(itemId, type, draggable, node) {
70
+ return t.objectExpression([
71
+ t.objectProperty(t.identifier("id"), t.stringLiteral(itemId)),
72
+ t.objectProperty(t.identifier("type"), t.stringLiteral(type)),
73
+ t.objectProperty(t.identifier("label"), t.stringLiteral(type)),
74
+ // `node` is a JSX element — valid inside a JS object literal
75
+ t.objectProperty(t.identifier("node"), node),
76
+ t.objectProperty(t.identifier("draggable"), t.booleanLiteral(draggable))
77
+ ]);
78
+ }
79
+ function maybeTransformRoot(jsxEl, componentName, scopeCounter) {
80
+ const { openingElement, children } = jsxEl;
81
+ const tagName = getJSXTagName(openingElement);
82
+ if (!isHTMLTag(tagName)) return null;
83
+ const elementChildren = children.filter(
84
+ (c) => t.isJSXElement(c)
85
+ );
86
+ const pascalCount = elementChildren.filter(
87
+ (c) => isPascalTag(getJSXTagName(c.openingElement))
88
+ ).length;
89
+ if (pascalCount < minComponents) return null;
90
+ scopeCounter.n += 1;
91
+ const scopeId = `${componentName}_s${scopeCounter.n}`;
92
+ const itemObjects = [];
93
+ elementChildren.forEach((child, idx) => {
94
+ const childTag = getJSXTagName(child.openingElement);
95
+ const draggable = isPascalTag(childTag);
96
+ const type = draggable ? childTag : `__html_${idx}`;
97
+ const itemId = `${scopeId}_${childTag}_${idx}`;
98
+ itemObjects.push(buildItemObject(itemId, type, draggable, child));
99
+ });
100
+ const jsxAttrs = openingElement.attributes.filter(
101
+ (a) => t.isJSXAttribute(a)
102
+ );
103
+ const tagPropsObj = attrsToObject(jsxAttrs);
104
+ const dndScopeEl = t.jsxElement(
105
+ t.jsxOpeningElement(
106
+ t.jsxIdentifier(SCOPE_LOCAL),
107
+ [
108
+ t.jsxAttribute(t.jsxIdentifier("id"), t.stringLiteral(scopeId)),
109
+ t.jsxAttribute(t.jsxIdentifier("tag"), t.stringLiteral(tagName)),
110
+ t.jsxAttribute(
111
+ t.jsxIdentifier("tagProps"),
112
+ t.jsxExpressionContainer(tagPropsObj)
113
+ ),
114
+ t.jsxAttribute(
115
+ t.jsxIdentifier("items"),
116
+ t.jsxExpressionContainer(t.arrayExpression(itemObjects))
117
+ )
118
+ ],
119
+ true
120
+ // self-closing
121
+ ),
122
+ null,
123
+ // no closing element (self-closing)
124
+ [],
125
+ true
126
+ );
127
+ return dndScopeEl;
128
+ }
129
+ return {
130
+ name: "babel-plugin-dnd-auto",
131
+ visitor: {
132
+ ExportDefaultDeclaration(path, state) {
133
+ const filename = state.filename ?? "";
134
+ if (fileExclude.test(filename)) return;
135
+ if (fileMatch && !fileMatch.test(filename)) return;
136
+ const { declaration } = path.node;
137
+ if (!t.isFunctionDeclaration(declaration)) return;
138
+ const componentName = declaration.id?.name ?? "Component";
139
+ const scopeCounter = { n: 0 };
140
+ let didTransform = false;
141
+ path.traverse({
142
+ ReturnStatement(retPath) {
143
+ const fnParent = retPath.getFunctionParent();
144
+ if (fnParent?.node !== declaration) return;
145
+ const arg = retPath.node.argument;
146
+ if (!arg || !t.isJSXElement(arg)) return;
147
+ const transformed = maybeTransformRoot(arg, componentName, scopeCounter);
148
+ if (transformed) {
149
+ retPath.node.argument = transformed;
150
+ didTransform = true;
151
+ }
152
+ }
153
+ });
154
+ if (didTransform && !state._dndInjected) {
155
+ state._dndInjected = true;
156
+ state.file.path.unshiftContainer(
157
+ "body",
158
+ t.importDeclaration(
159
+ [t.importSpecifier(t.identifier(SCOPE_LOCAL), t.identifier("DndScope"))],
160
+ t.stringLiteral(importSource)
161
+ )
162
+ );
163
+ }
164
+ }
165
+ }
166
+ };
167
+ }
168
+
169
+ // src/babel-plugin-editor-meta.ts
170
+ import * as nodePath from "path";
171
+ function isPackageImport(src) {
172
+ if (src.startsWith(".") || src.startsWith("/")) return false;
173
+ if (src.startsWith("@")) {
174
+ const slashIdx = src.indexOf("/");
175
+ if (slashIdx === 1) return false;
176
+ if (slashIdx > 1) return true;
177
+ return true;
178
+ }
179
+ if (src.startsWith("~/") || src.startsWith("#/")) return false;
180
+ return true;
181
+ }
182
+ function babelPluginEditorMeta({ types: t }, opts = {}) {
183
+ const {
184
+ fileExclude = /node_modules/,
185
+ instrumentImported = true,
186
+ includeHostSourceRef = false
187
+ } = opts;
188
+ function getJSXTagName(el) {
189
+ const { name } = el;
190
+ if (t.isJSXIdentifier(name)) return name.name;
191
+ if (t.isJSXMemberExpression(name)) {
192
+ const parts = [];
193
+ let current = name;
194
+ while (t.isJSXMemberExpression(current)) {
195
+ parts.unshift(current.property.name);
196
+ current = current.object;
197
+ }
198
+ if (t.isJSXIdentifier(current)) parts.unshift(current.name);
199
+ return parts.join(".");
200
+ }
201
+ return "";
202
+ }
203
+ function computeNodeId(file, line, col, componentName) {
204
+ return `${file}:${line}:${col}:${componentName}`;
205
+ }
206
+ function isMovable(path) {
207
+ const elPath = path.parentPath;
208
+ if (!elPath) return false;
209
+ const parentEl = elPath.parentPath;
210
+ if (!parentEl || !parentEl.isJSXElement()) return false;
211
+ const siblings = parentEl.node.children.filter(
212
+ (c) => t.isJSXElement(c)
213
+ );
214
+ return siblings.length >= 2;
215
+ }
216
+ function getParentNodeId(path, file) {
217
+ const elPath = path.parentPath;
218
+ if (!elPath) return null;
219
+ let ancestor = elPath.parentPath;
220
+ while (ancestor) {
221
+ if (ancestor.isJSXElement()) {
222
+ const opening = ancestor.node.openingElement;
223
+ const loc = opening.loc?.start;
224
+ if (loc) {
225
+ const tag = getJSXTagName(opening);
226
+ return computeNodeId(file, loc.line, loc.column, tag);
227
+ }
228
+ return null;
229
+ }
230
+ ancestor = ancestor.parentPath;
231
+ }
232
+ return null;
233
+ }
234
+ function extractStaticProps(attrs) {
235
+ const props = [];
236
+ let hasAny = false;
237
+ for (const attr of attrs) {
238
+ if (t.isJSXSpreadAttribute(attr)) continue;
239
+ if (!t.isJSXAttribute(attr)) continue;
240
+ const keyName = t.isJSXIdentifier(attr.name) ? attr.name.name : attr.name.name.name;
241
+ if (keyName === "__editorMeta") continue;
242
+ let value;
243
+ if (attr.value === null || attr.value === void 0) {
244
+ value = t.booleanLiteral(true);
245
+ } else if (t.isStringLiteral(attr.value)) {
246
+ value = attr.value;
247
+ } else if (t.isJSXExpressionContainer(attr.value)) {
248
+ const expr = attr.value.expression;
249
+ if (t.isNumericLiteral(expr)) {
250
+ value = expr;
251
+ } else if (t.isBooleanLiteral(expr)) {
252
+ value = expr;
253
+ } else if (t.isNullLiteral(expr)) {
254
+ value = expr;
255
+ } else if (t.isStringLiteral(expr)) {
256
+ value = expr;
257
+ } else {
258
+ value = t.stringLiteral("__dynamic__");
259
+ }
260
+ } else {
261
+ continue;
262
+ }
263
+ props.push(t.objectProperty(t.stringLiteral(keyName), value));
264
+ hasAny = true;
265
+ }
266
+ return hasAny ? t.objectExpression(props) : null;
267
+ }
268
+ function isMetaStripSpreadExpression(arg) {
269
+ if (!t.isCallExpression(arg)) return false;
270
+ if (!t.isArrowFunctionExpression(arg.callee)) return false;
271
+ const [firstParam] = arg.callee.params;
272
+ if (!firstParam || !t.isObjectPattern(firstParam)) return false;
273
+ return firstParam.properties.some((prop) => {
274
+ if (!t.isObjectProperty(prop)) return false;
275
+ if (!t.isIdentifier(prop.key)) return false;
276
+ return prop.key.name === "__editorMeta";
277
+ });
278
+ }
279
+ function hasTruthyAsChildProp(attrs) {
280
+ for (const attr of attrs) {
281
+ if (!t.isJSXAttribute(attr) || !t.isJSXIdentifier(attr.name, { name: "asChild" })) {
282
+ continue;
283
+ }
284
+ if (attr.value == null) return true;
285
+ if (t.isJSXExpressionContainer(attr.value)) {
286
+ const expr = attr.value.expression;
287
+ if (t.isBooleanLiteral(expr)) return expr.value;
288
+ }
289
+ if (t.isStringLiteral(attr.value)) return attr.value.value !== "false";
290
+ return true;
291
+ }
292
+ return false;
293
+ }
294
+ function sanitizeSpreadAttributes(attrs) {
295
+ for (const attr of attrs) {
296
+ if (!t.isJSXSpreadAttribute(attr)) continue;
297
+ if (isMetaStripSpreadExpression(attr.argument)) continue;
298
+ const origArg = attr.argument;
299
+ attr.argument = t.callExpression(
300
+ t.arrowFunctionExpression(
301
+ [
302
+ t.objectPattern([
303
+ t.objectProperty(
304
+ t.identifier("__editorMeta"),
305
+ t.identifier("_$em"),
306
+ false,
307
+ false
308
+ ),
309
+ t.restElement(t.identifier("_$r"))
310
+ ])
311
+ ],
312
+ t.identifier("_$r")
313
+ ),
314
+ [t.objectExpression([t.spreadElement(origArg)])]
315
+ );
316
+ }
317
+ }
318
+ return {
319
+ name: "babel-plugin-editor-meta",
320
+ visitor: {
321
+ CallExpression(path, state) {
322
+ const filename = state.filename ?? "";
323
+ if (fileExclude.test(filename)) return;
324
+ const callee = path.node.callee;
325
+ let isCreateElement = false;
326
+ let isCloneElement = false;
327
+ if (t.isIdentifier(callee, { name: "createElement" })) {
328
+ isCreateElement = true;
329
+ } else if (t.isMemberExpression(callee) && t.isIdentifier(callee.property, { name: "createElement" })) {
330
+ isCreateElement = true;
331
+ } else if (t.isIdentifier(callee, { name: "cloneElement" })) {
332
+ isCloneElement = true;
333
+ } else if (t.isMemberExpression(callee) && t.isIdentifier(callee.property, { name: "cloneElement" })) {
334
+ isCloneElement = true;
335
+ }
336
+ if (!isCreateElement && !isCloneElement) return;
337
+ const args = path.node.arguments;
338
+ if (args.length < 2) return;
339
+ if (isCreateElement && !t.isStringLiteral(args[0])) return;
340
+ const propsArg = args[1];
341
+ if (!propsArg || t.isNullLiteral(propsArg)) return;
342
+ if (!t.isExpression(propsArg)) return;
343
+ if (isMetaStripSpreadExpression(propsArg)) return;
344
+ args[1] = t.callExpression(
345
+ t.arrowFunctionExpression(
346
+ [
347
+ t.objectPattern([
348
+ t.objectProperty(
349
+ t.identifier("__editorMeta"),
350
+ t.identifier("_$em"),
351
+ false,
352
+ false
353
+ ),
354
+ t.restElement(t.identifier("_$r"))
355
+ ])
356
+ ],
357
+ t.identifier("_$r")
358
+ ),
359
+ [t.objectExpression([t.spreadElement(propsArg)])]
360
+ );
361
+ },
362
+ JSXOpeningElement(path, state) {
363
+ const filename = state.filename ?? "";
364
+ if (fileExclude.test(filename)) return;
365
+ const existing = path.node.attributes.find(
366
+ (a) => t.isJSXAttribute(a) && t.isJSXIdentifier(a.name, { name: "__editorMeta" })
367
+ );
368
+ if (existing) return;
369
+ const loc = path.node.loc?.start;
370
+ if (!loc) return;
371
+ const root = state.file.opts.root ?? "";
372
+ const file = root ? nodePath.relative(root, filename) : filename;
373
+ const line = loc.line;
374
+ const col = loc.column;
375
+ const componentName = getJSXTagName(path.node);
376
+ if (!componentName) return;
377
+ const isHostElement = componentName[0] === componentName[0].toLowerCase();
378
+ sanitizeSpreadAttributes(path.node.attributes);
379
+ if (hasTruthyAsChildProp(path.node.attributes)) {
380
+ return;
381
+ }
382
+ let rootName = null;
383
+ if (t.isJSXIdentifier(path.node.name)) {
384
+ rootName = path.node.name.name;
385
+ } else if (t.isJSXMemberExpression(path.node.name)) {
386
+ let cur = path.node.name;
387
+ while (t.isJSXMemberExpression(cur)) cur = cur.object;
388
+ if (t.isJSXIdentifier(cur)) rootName = cur.name;
389
+ }
390
+ if (rootName) {
391
+ const binding = path.scope.getBinding(rootName);
392
+ if (binding) {
393
+ const bp = binding.path;
394
+ if (bp.isImportSpecifier() || bp.isImportDefaultSpecifier() || bp.isImportNamespaceSpecifier()) {
395
+ if (!instrumentImported) return;
396
+ const decl = bp.parentPath;
397
+ if (decl?.isImportDeclaration()) {
398
+ const src = decl.node.source.value;
399
+ if (isPackageImport(src)) return;
400
+ }
401
+ }
402
+ const programScope = path.scope.getProgramParent();
403
+ if (binding.scope !== programScope) return;
404
+ }
405
+ }
406
+ const nodeId = computeNodeId(file, line, col, componentName);
407
+ const movable = isMovable(path);
408
+ const parentNodeId = getParentNodeId(path, file);
409
+ const staticPropsObj = extractStaticProps(path.node.attributes);
410
+ const metaObj = t.objectExpression([
411
+ t.objectProperty(t.identifier("nodeId"), t.stringLiteral(nodeId)),
412
+ t.objectProperty(t.identifier("file"), t.stringLiteral(file)),
413
+ t.objectProperty(t.identifier("line"), t.numericLiteral(line)),
414
+ t.objectProperty(t.identifier("col"), t.numericLiteral(col)),
415
+ t.objectProperty(t.identifier("componentName"), t.stringLiteral(componentName)),
416
+ t.objectProperty(
417
+ t.identifier("staticProps"),
418
+ staticPropsObj ?? t.nullLiteral()
419
+ ),
420
+ t.objectProperty(t.identifier("movable"), t.booleanLiteral(movable)),
421
+ t.objectProperty(
422
+ t.identifier("parentNodeId"),
423
+ parentNodeId ? t.stringLiteral(parentNodeId) : t.nullLiteral()
424
+ )
425
+ ]);
426
+ if (isHostElement && includeHostSourceRef) {
427
+ path.node.attributes.push(
428
+ t.jsxAttribute(
429
+ t.jsxIdentifier("data-archie-source-ref"),
430
+ t.stringLiteral(`${file}::${line}::${col}`)
431
+ )
432
+ );
433
+ }
434
+ path.node.attributes.push(
435
+ t.jsxAttribute(
436
+ t.jsxIdentifier("__editorMeta"),
437
+ t.jsxExpressionContainer(metaObj)
438
+ )
439
+ );
440
+ }
441
+ }
442
+ };
443
+ }
444
+
1
445
  // src/index.ts
2
446
  function archieDevTools(options = {}) {
3
- const { debug = false } = options;
447
+ const {
448
+ debug = false,
449
+ dndPages = /src\/pages\//
450
+ } = options;
4
451
  const log = (...args) => {
5
- if (debug) {
6
- console.log("[Archie DevTools]", ...args);
7
- }
452
+ if (debug) console.log("[Archie DevTools]", ...args);
8
453
  };
9
- return {
454
+ let includeHostSourceRef = false;
455
+ const plugin = {
10
456
  name: "vite-plugin-archie-devtools",
11
457
  enforce: "pre",
458
+ config() {
459
+ return {
460
+ resolve: {
461
+ dedupe: ["react", "react-dom"]
462
+ }
463
+ };
464
+ },
12
465
  configResolved(config) {
13
- log("Plugin initialized for project:", config.root);
466
+ includeHostSourceRef = !config.isProduction;
467
+ },
468
+ resolveId(id) {
469
+ if (id === INTERNAL_DND_SCOPE_IMPORT_SOURCE) {
470
+ return RESOLVED_DND_SCOPE_MODULE_ID;
471
+ }
472
+ return null;
473
+ },
474
+ load(id) {
475
+ if (id === RESOLVED_DND_SCOPE_MODULE_ID) {
476
+ return getDndScopeVirtualModuleSource();
477
+ }
478
+ return null;
14
479
  },
15
- configureServer() {
16
- log("Dev server configured");
480
+ api: {
481
+ reactBabel(babelOptions, context) {
482
+ if (!/node_modules/.test(context.id)) {
483
+ babelOptions.plugins.push(
484
+ (babel) => babelPluginEditorMeta(babel, {
485
+ includeHostSourceRef
486
+ })
487
+ );
488
+ }
489
+ if (dndPages.test(context.id)) {
490
+ log("Applying DnD transform to:", context.id);
491
+ babelOptions.plugins.push(
492
+ (babel) => babelPluginDndAuto(babel, {
493
+ importSource: INTERNAL_DND_SCOPE_IMPORT_SOURCE
494
+ })
495
+ );
496
+ }
497
+ }
17
498
  }
18
499
  };
500
+ return plugin;
19
501
  }
20
502
  export {
21
503
  archieDevTools
package/package.json CHANGED
@@ -1,7 +1,15 @@
1
1
  {
2
2
  "name": "@archie/devtools",
3
- "version": "0.0.10",
3
+ "version": "0.0.11",
4
4
  "description": "DevTools for Archie generated applications - Route synchronization and editor communication",
5
+ "repository": {
6
+ "type": "git",
7
+ "url": "git+https://github.com/8base-archie/archie-devtools.git"
8
+ },
9
+ "publishConfig": {
10
+ "access": "restricted",
11
+ "provenance": false
12
+ },
5
13
  "main": "dist/index.js",
6
14
  "module": "dist/index.mjs",
7
15
  "types": "dist/index.d.ts",
@@ -15,24 +23,14 @@
15
23
  "types": "./dist/client/client.d.ts",
16
24
  "import": "./dist/client/client.mjs",
17
25
  "require": "./dist/client/client.js"
18
- },
19
- "./client/inject-inspector/auto": {
20
- "types": "./dist/client/inject-inspector/auto.d.ts",
21
- "import": "./dist/client/inject-inspector/auto.mjs",
22
- "require": "./dist/client/inject-inspector/auto.js"
23
- },
24
- "./constants": {
25
- "types": "./dist/constants/archieOrigins.d.ts",
26
- "import": "./dist/constants/archieOrigins.mjs",
27
- "require": "./dist/constants/archieOrigins.js"
28
26
  }
29
27
  },
30
28
  "scripts": {
31
29
  "test": "vitest run",
32
30
  "test:watch": "vitest",
33
31
  "inspector:local": "node scripts/generate-inspector-local.js",
34
- "build": "tsup src/index.ts src/client/client.ts src/client/inject-inspector/injectInspector.ts src/client/inject-inspector/auto.ts src/client/route-listener/routeListener.ts src/constants/archieOrigins.ts --format cjs,esm --dts",
35
- "dev": "tsup src/index.ts src/client/client.ts src/client/inject-inspector/injectInspector.ts src/client/inject-inspector/auto.ts src/client/route-listener/routeListener.ts src/constants/archieOrigins.ts --format cjs,esm --dts --watch",
32
+ "build": "tsup",
33
+ "dev": "tsup --watch",
36
34
  "typecheck": "tsc --noEmit",
37
35
  "release": "node publish.js"
38
36
  },
@@ -47,28 +45,31 @@
47
45
  "react-router"
48
46
  ],
49
47
  "author": "8base",
50
- "license": "MIT",
48
+ "license": "UNLICENSED",
51
49
  "devDependencies": {
50
+ "@babel/core": "^7.29.0",
51
+ "@babel/types": "^7.29.0",
52
+ "@dnd-kit/core": "^6.3.1",
53
+ "@dnd-kit/sortable": "^10.0.0",
54
+ "@dnd-kit/utilities": "^3.2.2",
52
55
  "@remix-run/router": "^1.0.0",
56
+ "@types/babel__core": "^7.20.5",
53
57
  "@types/react": "^19.0.0",
54
58
  "@types/react-dom": "^19.0.0",
55
59
  "happy-dom": "^20.5.0",
60
+ "lucide-react": "^0.577.0",
56
61
  "react": "^19.0.0",
57
62
  "react-dom": "^19.0.0",
58
63
  "react-router-dom": "^7.0.0",
59
64
  "tsup": "^8.0.0",
60
65
  "typescript": "^5.0.0",
61
66
  "vite": "^5.0.0 || ^6.0.0 || ^7.0.0",
62
- "vitest": "^2.1.9"
67
+ "vitest": "^2.1.9",
68
+ "zustand": "^5.0.11"
63
69
  },
64
70
  "peerDependencies": {
65
71
  "react": ">=18.0.0",
66
72
  "react-dom": ">=18.0.0",
67
73
  "react-router-dom": ">=6.4.0"
68
- },
69
- "peerDependenciesMeta": {
70
- "vite": {
71
- "optional": true
72
- }
73
74
  }
74
75
  }
@@ -1,47 +0,0 @@
1
- // src/constants/archieOrigins.ts
2
- var ARCHIE_HOST_ORIGINS = [
3
- "https://app.dev.archie-platform.com",
4
- "https://app.staging.archie-platform.com",
5
- "https://app.archie.com"
6
- ];
7
- var ARCHIE_PREVIEW_ORIGIN_SUFFIXES = [
8
- ".staging.archie-platform.com",
9
- ".archie-platform.com",
10
- ".archie.com"
11
- ];
12
- var PREVIEW_DEPLOY_HOST_SUFFIXES = [
13
- ".previews.staging.archie-platform.com",
14
- ".previews.archie-platform.com",
15
- ".previews.archie.com"
16
- ];
17
- var LOCAL_DEV_ORIGINS = [
18
- "http://localhost:3000",
19
- "http://localhost:3001"
20
- ];
21
- function getAllowedOrigins(includeLocal = false) {
22
- const list = [...ARCHIE_HOST_ORIGINS];
23
- if (includeLocal) list.push(...LOCAL_DEV_ORIGINS);
24
- return list;
25
- }
26
- function getAllowedOriginPatterns() {
27
- return [...ARCHIE_PREVIEW_ORIGIN_SUFFIXES];
28
- }
29
- function isPreviewOrigin(origin) {
30
- if (!origin || typeof origin !== "string") return false;
31
- try {
32
- const host = new URL(origin).host;
33
- return PREVIEW_DEPLOY_HOST_SUFFIXES.some((suffix) => host.endsWith(suffix));
34
- } catch {
35
- return false;
36
- }
37
- }
38
-
39
- export {
40
- ARCHIE_HOST_ORIGINS,
41
- ARCHIE_PREVIEW_ORIGIN_SUFFIXES,
42
- PREVIEW_DEPLOY_HOST_SUFFIXES,
43
- LOCAL_DEV_ORIGINS,
44
- getAllowedOrigins,
45
- getAllowedOriginPatterns,
46
- isPreviewOrigin
47
- };