@pie-element/cli 0.1.2-next.10 → 0.1.2-next.14

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 (41) hide show
  1. package/README.md +5 -5
  2. package/dist/commands/packages/create-react-elements.js +12 -31
  3. package/dist/commands/packages/create-react-elements.js.map +1 -1
  4. package/dist/commands/packages/init-synced-elements.js +3 -5
  5. package/dist/commands/packages/init-synced-elements.js.map +1 -1
  6. package/dist/commands/upstream/analyze-esm.js +1 -34
  7. package/dist/commands/upstream/analyze-esm.js.map +1 -1
  8. package/dist/commands/upstream/sync.js +0 -1
  9. package/dist/commands/upstream/sync.js.map +1 -1
  10. package/dist/lib/upstream/sync-compatibility.d.ts +0 -8
  11. package/dist/lib/upstream/sync-compatibility.js +0 -31
  12. package/dist/lib/upstream/sync-compatibility.js.map +1 -1
  13. package/dist/lib/upstream/sync-constants.d.ts +2 -12
  14. package/dist/lib/upstream/sync-constants.js +33 -16
  15. package/dist/lib/upstream/sync-constants.js.map +1 -1
  16. package/dist/lib/upstream/sync-demo-metadata.js +117 -109
  17. package/dist/lib/upstream/sync-demo-metadata.js.map +1 -1
  18. package/dist/lib/upstream/sync-imports.d.ts +0 -21
  19. package/dist/lib/upstream/sync-imports.js +0 -77
  20. package/dist/lib/upstream/sync-imports.js.map +1 -1
  21. package/dist/lib/upstream/sync-package-json.d.ts +0 -19
  22. package/dist/lib/upstream/sync-package-json.js +0 -58
  23. package/dist/lib/upstream/sync-package-json.js.map +1 -1
  24. package/dist/lib/upstream/sync-package-manager.d.ts +6 -0
  25. package/dist/lib/upstream/sync-package-manager.js +47 -24
  26. package/dist/lib/upstream/sync-package-manager.js.map +1 -1
  27. package/dist/lib/upstream/sync-source-tree.js +3 -1
  28. package/dist/lib/upstream/sync-source-tree.js.map +1 -1
  29. package/dist/lib/upstream/sync-vite-config.d.ts +0 -4
  30. package/dist/lib/upstream/sync-vite-config.js +1 -12
  31. package/dist/lib/upstream/sync-vite-config.js.map +1 -1
  32. package/dist/utils/compatibility.d.ts +0 -15
  33. package/dist/utils/compatibility.js +0 -34
  34. package/dist/utils/compatibility.js.map +1 -1
  35. package/dist/utils/conversion.d.ts +0 -5
  36. package/dist/utils/conversion.js +0 -21
  37. package/dist/utils/conversion.js.map +1 -1
  38. package/dist/utils/git.d.ts +0 -1
  39. package/dist/utils/git.js +0 -8
  40. package/dist/utils/git.js.map +1 -1
  41. package/package.json +2 -2
@@ -1,76 +1,133 @@
1
1
  /**
2
2
  * Generate demo metadata for SvelteKit demo app
3
3
  *
4
- * This module generates:
5
- * 1. Element registry (lib/elements/registry.ts)
6
- * 2. Sample configs converted to JSON from each element
7
- * 3. Sample sessions converted to JSON from each element
4
+ * Scans packages/elements-react and packages/elements-svelte and rewrites the element registry
5
+ * (lib/elements/registry.ts). Each element's demos live in lib/samples/<element>.json, which the
6
+ * demo app reads; an element's docs/demo/config.mjs seeds that file only when it does not exist.
8
7
  */
8
+ import { existsSync, readdirSync, readFileSync } from 'node:fs';
9
9
  import { mkdir, writeFile } from 'node:fs/promises';
10
10
  import { join, dirname } from 'node:path';
11
11
  import { fileURLToPath } from 'node:url';
12
12
  const __dirname = dirname(fileURLToPath(import.meta.url));
13
13
  const REPO_ROOT = join(__dirname, '../../../../..');
14
14
  const DEMO_APP_PATH = join(REPO_ROOT, 'apps/element-demo');
15
- const ELEMENTS_REACT_PATH = join(REPO_ROOT, 'packages/elements-react');
15
+ const REGISTRY_PATH = join(DEMO_APP_PATH, 'src/lib/elements/registry.ts');
16
+ const SAMPLES_PATH = join(DEMO_APP_PATH, 'src/lib/samples');
17
+ const ELEMENT_ROOTS = ['packages/elements-react', 'packages/elements-svelte'];
16
18
  /**
17
- * Scan elements-react directory for all elements
19
+ * Read the current registry entries, whose hand-set title and hasSession survive regeneration
18
20
  */
19
- async function scanReactElements() {
20
- const { readdirSync, existsSync: fsExistsSync, statSync } = await import('node:fs');
21
- if (!fsExistsSync(ELEMENTS_REACT_PATH)) {
22
- console.log('[demo-metadata] elements-react directory not found, skipping');
23
- return [];
21
+ function readExistingRegistry() {
22
+ if (!existsSync(REGISTRY_PATH))
23
+ return new Map();
24
+ const content = readFileSync(REGISTRY_PATH, 'utf-8');
25
+ const match = content.match(/export const ELEMENT_REGISTRY[^=]*=\s*(\[[\s\S]*?\]);/);
26
+ if (!match)
27
+ throw new Error(`Could not find ELEMENT_REGISTRY in ${REGISTRY_PATH}`);
28
+ const entries = JSON.parse(match[1]);
29
+ return new Map(entries.map((entry) => [entry.name, entry]));
30
+ }
31
+ /**
32
+ * Convert old format (models array) to new format (demos array)
33
+ */
34
+ function toDemosFormat(configData) {
35
+ if (!configData?.models || configData?.demos)
36
+ return configData;
37
+ return {
38
+ demos: configData.models.map((model, index) => ({
39
+ id: index === 0 ? 'default' : `demo-${index + 1}`,
40
+ title: index === 0 ? 'Default Demo' : `Demo ${index + 1}`,
41
+ description: 'Default configuration',
42
+ tags: [],
43
+ model: model,
44
+ session: { value: [] },
45
+ })),
46
+ };
47
+ }
48
+ /**
49
+ * Load an element's samples JSON, seeding it from docs/demo/config.mjs when it does not exist
50
+ */
51
+ async function loadSamples(name, elementPath) {
52
+ const samplesPath = join(SAMPLES_PATH, `${name}.json`);
53
+ const configPath = join(elementPath, 'docs/demo/config.mjs');
54
+ const existing = existsSync(samplesPath)
55
+ ? JSON.parse(readFileSync(samplesPath, 'utf-8'))
56
+ : undefined;
57
+ if (!existsSync(configPath))
58
+ return existing;
59
+ let configData;
60
+ try {
61
+ configData = toDemosFormat((await import(`file://${configPath}`)).default);
62
+ }
63
+ catch (e) {
64
+ console.warn(`[demo-metadata] Failed to convert config for ${name}:`, e);
65
+ return existing;
24
66
  }
67
+ if (existing) {
68
+ if (JSON.stringify(configData) !== JSON.stringify(existing)) {
69
+ console.warn(`[demo-metadata] ${name}: docs/demo/config.mjs differs from samples/${name}.json; ` +
70
+ 'kept the samples file (delete it to regenerate from config.mjs)');
71
+ }
72
+ return existing;
73
+ }
74
+ await mkdir(SAMPLES_PATH, { recursive: true });
75
+ await writeFile(samplesPath, JSON.stringify(configData, null, 2) + '\n', 'utf-8');
76
+ console.log(`[demo-metadata] Seeded samples/${name}.json from docs/demo/config.mjs`);
77
+ return configData;
78
+ }
79
+ /**
80
+ * Scan the element package directories for all elements
81
+ */
82
+ async function scanElements(existing) {
25
83
  const elements = [];
26
- const dirs = readdirSync(ELEMENTS_REACT_PATH);
27
- for (const dir of dirs) {
28
- const elementPath = join(ELEMENTS_REACT_PATH, dir);
29
- const stat = statSync(elementPath);
30
- if (!stat.isDirectory())
31
- continue;
32
- // Check for required structure
33
- const srcPath = join(elementPath, 'src');
34
- const deliveryPath = join(srcPath, 'delivery');
35
- if (!fsExistsSync(deliveryPath))
84
+ for (const root of ELEMENT_ROOTS) {
85
+ const rootPath = join(REPO_ROOT, root);
86
+ if (!existsSync(rootPath))
36
87
  continue;
37
- // Check for author and print
38
- const hasAuthor = fsExistsSync(join(srcPath, 'author'));
39
- const hasPrint = fsExistsSync(join(srcPath, 'print'));
40
- // Check for demo files
41
- const docsPath = join(elementPath, 'docs/demo');
42
- const hasConfig = fsExistsSync(join(docsPath, 'config.mjs'));
43
- const hasSession = fsExistsSync(join(docsPath, 'session.mjs'));
44
- // Generate title from name (e.g., "multiple-choice" -> "Multiple Choice")
45
- const title = dir
46
- .split('-')
47
- .map((word) => word.charAt(0).toUpperCase() + word.slice(1))
48
- .join(' ');
49
- elements.push({
50
- name: dir,
51
- title,
52
- packageName: `@pie-element/${dir}`,
53
- hasAuthor,
54
- hasPrint,
55
- hasConfig,
56
- hasSession,
57
- demoCount: 0, // Will be updated in copySampleConfigs
58
- });
88
+ for (const dir of readdirSync(rootPath, { withFileTypes: true })) {
89
+ if (!dir.isDirectory())
90
+ continue;
91
+ // Check for required structure
92
+ const elementPath = join(rootPath, dir.name);
93
+ const srcPath = join(elementPath, 'src');
94
+ if (!existsSync(join(srcPath, 'delivery')))
95
+ continue;
96
+ const pkg = JSON.parse(readFileSync(join(elementPath, 'package.json'), 'utf-8'));
97
+ const samples = await loadSamples(dir.name, elementPath);
98
+ const previous = existing.get(dir.name);
99
+ if (!previous) {
100
+ console.log(`[demo-metadata] Added ${dir.name}; check its title and hasSession in registry.ts`);
101
+ }
102
+ elements.push({
103
+ name: dir.name,
104
+ // Generate title from name (e.g., "multiple-choice" -> "Multiple Choice")
105
+ title: previous?.title ??
106
+ dir.name
107
+ .split('-')
108
+ .map((word) => word.charAt(0).toUpperCase() + word.slice(1))
109
+ .join(' '),
110
+ packageName: pkg.name,
111
+ hasAuthor: existsSync(join(srcPath, 'author')),
112
+ hasPrint: existsSync(join(srcPath, 'print')),
113
+ hasConfig: samples !== undefined,
114
+ hasSession: previous?.hasSession ?? true,
115
+ demoCount: Array.isArray(samples?.demos) ? samples.demos.length : 0,
116
+ });
117
+ }
59
118
  }
60
- return elements;
119
+ return elements.sort((a, b) => a.name.localeCompare(b.name));
61
120
  }
62
121
  /**
63
122
  * Generate registry.ts file
64
123
  */
65
124
  async function generateRegistry(elements) {
66
- const registryPath = join(DEMO_APP_PATH, 'src/lib/elements/registry.ts');
67
125
  const content = `/**
68
126
  * Element Registry
69
127
  *
70
- * AUTO-GENERATED by upstream:sync command.
71
- * DO NOT EDIT MANUALLY - changes will be overwritten.
72
- *
73
- * Generated: ${new Date().toISOString()}
128
+ * Generated by \`bun tools/generate-demo-metadata.mjs\` from packages/elements-react and
129
+ * packages/elements-svelte. Edit \`title\` and \`hasSession\` here; regeneration keeps them and
130
+ * overwrites the other fields.
74
131
  */
75
132
 
76
133
  export interface ElementMetadata {
@@ -90,76 +147,27 @@ export function getElement(name: string): ElementMetadata | undefined {
90
147
  return ELEMENT_REGISTRY.find((el) => el.name === name);
91
148
  }
92
149
 
93
- export function getAllElements(): ElementMetadata[] {
150
+ export function getAllElements(): readonly ElementMetadata[] {
94
151
  return ELEMENT_REGISTRY;
95
152
  }
96
153
  `;
97
- await mkdir(dirname(registryPath), { recursive: true });
98
- await writeFile(registryPath, content, 'utf-8');
154
+ await mkdir(dirname(REGISTRY_PATH), { recursive: true });
155
+ await writeFile(REGISTRY_PATH, content, 'utf-8');
99
156
  console.log(`[demo-metadata] Generated registry with ${elements.length} elements`);
100
157
  }
101
- /**
102
- * Convert and copy sample configs for an element as JSON
103
- */
104
- async function copySampleConfigs(elements) {
105
- for (const element of elements) {
106
- const sourcePath = join(ELEMENTS_REACT_PATH, element.name, 'docs/demo');
107
- const targetDir = join(DEMO_APP_PATH, 'src/lib/samples');
108
- await mkdir(targetDir, { recursive: true });
109
- // Convert config.mjs to JSON
110
- if (element.hasConfig) {
111
- const sourceConfig = join(sourcePath, 'config.mjs');
112
- const targetConfig = join(targetDir, `${element.name}.json`);
113
- try {
114
- // Dynamic import the .mjs file
115
- const configModule = await import(`file://${sourceConfig}`);
116
- let configData = configModule.default;
117
- // Convert old format (models array) to new format (demos array)
118
- if (configData?.models && !configData?.demos) {
119
- console.log(`[demo-metadata] Converting ${element.name} from old format to new format`);
120
- configData = {
121
- demos: configData.models.map((model, index) => ({
122
- id: index === 0 ? 'default' : `demo-${index + 1}`,
123
- title: index === 0 ? 'Default Demo' : `Demo ${index + 1}`,
124
- description: 'Default configuration',
125
- tags: [],
126
- model: model,
127
- session: { value: [] },
128
- })),
129
- };
130
- }
131
- // Count demos (now all in 'demos' format)
132
- if (configData?.demos && Array.isArray(configData.demos)) {
133
- element.demoCount = configData.demos.length;
134
- }
135
- else {
136
- element.demoCount = 0;
137
- }
138
- // Write as JSON
139
- await writeFile(targetConfig, JSON.stringify(configData, null, 2) + '\n', 'utf-8');
140
- }
141
- catch (e) {
142
- console.warn(`[demo-metadata] Failed to convert config for ${element.name}:`, e);
143
- }
144
- }
145
- // Note: session.mjs files are no longer copied as separate files.
146
- // Sessions are now embedded within each demo object in the config.
147
- // Old format session files are automatically converted during config import above.
148
- }
149
- console.log(`[demo-metadata] Converted sample configs to JSON for ${elements.length} elements`);
150
- }
151
158
  /**
152
159
  * Main entry point
153
160
  */
154
161
  export async function generateDemoMetadata() {
155
162
  console.log('[demo-metadata] Scanning elements...');
156
- const reactElements = await scanReactElements();
157
- const allElements = [...reactElements].sort((a, b) => a.name.localeCompare(b.name));
158
- console.log(`[demo-metadata] Found ${reactElements.length} React elements`);
159
- // Copy sample configs first so demoCount gets populated
160
- await copySampleConfigs(allElements);
161
- // Then generate registry with updated demoCount values
162
- await generateRegistry(allElements);
163
+ const existing = readExistingRegistry();
164
+ const elements = await scanElements(existing);
165
+ for (const name of existing.keys()) {
166
+ if (!elements.some((element) => element.name === name)) {
167
+ console.log(`[demo-metadata] Removed ${name}; no element package found`);
168
+ }
169
+ }
170
+ await generateRegistry(elements);
163
171
  console.log('[demo-metadata] ✓ Demo metadata generation complete');
164
172
  }
165
173
  //# sourceMappingURL=sync-demo-metadata.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"sync-demo-metadata.js","sourceRoot":"","sources":["../../../src/lib/upstream/sync-demo-metadata.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Generate demo metadata for SvelteKit demo app\n *\n * This module generates:\n * 1. Element registry (lib/elements/registry.ts)\n * 2. Sample configs converted to JSON from each element\n * 3. Sample sessions converted to JSON from each element\n */\nimport { mkdir, writeFile } from 'node:fs/promises';\nimport { join, dirname } from 'node:path';\nimport { fileURLToPath } from 'node:url';\n\nconst __dirname = dirname(fileURLToPath(import.meta.url));\nconst REPO_ROOT = join(__dirname, '../../../../..');\nconst DEMO_APP_PATH = join(REPO_ROOT, 'apps/element-demo');\nconst ELEMENTS_REACT_PATH = join(REPO_ROOT, 'packages/elements-react');\n\nexport interface ElementMetadata {\n name: string;\n title: string;\n packageName: string;\n hasAuthor: boolean;\n hasPrint: boolean;\n hasConfig: boolean;\n hasSession: boolean;\n demoCount: number;\n}\n\n/**\n * Scan elements-react directory for all elements\n */\nasync function scanReactElements(): Promise<ElementMetadata[]> {\n const { readdirSync, existsSync: fsExistsSync, statSync } = await import('node:fs');\n\n if (!fsExistsSync(ELEMENTS_REACT_PATH)) {\n console.log('[demo-metadata] elements-react directory not found, skipping');\n return [];\n }\n\n const elements: ElementMetadata[] = [];\n const dirs = readdirSync(ELEMENTS_REACT_PATH);\n\n for (const dir of dirs) {\n const elementPath = join(ELEMENTS_REACT_PATH, dir);\n const stat = statSync(elementPath);\n\n if (!stat.isDirectory()) continue;\n\n // Check for required structure\n const srcPath = join(elementPath, 'src');\n const deliveryPath = join(srcPath, 'delivery');\n if (!fsExistsSync(deliveryPath)) continue;\n\n // Check for author and print\n const hasAuthor = fsExistsSync(join(srcPath, 'author'));\n const hasPrint = fsExistsSync(join(srcPath, 'print'));\n\n // Check for demo files\n const docsPath = join(elementPath, 'docs/demo');\n const hasConfig = fsExistsSync(join(docsPath, 'config.mjs'));\n const hasSession = fsExistsSync(join(docsPath, 'session.mjs'));\n\n // Generate title from name (e.g., \"multiple-choice\" -> \"Multiple Choice\")\n const title = dir\n .split('-')\n .map((word) => word.charAt(0).toUpperCase() + word.slice(1))\n .join(' ');\n\n elements.push({\n name: dir,\n title,\n packageName: `@pie-element/${dir}`,\n hasAuthor,\n hasPrint,\n hasConfig,\n hasSession,\n demoCount: 0, // Will be updated in copySampleConfigs\n });\n }\n\n return elements;\n}\n\n/**\n * Generate registry.ts file\n */\nasync function generateRegistry(elements: ElementMetadata[]): Promise<void> {\n const registryPath = join(DEMO_APP_PATH, 'src/lib/elements/registry.ts');\n\n const content = `/**\n * Element Registry\n *\n * AUTO-GENERATED by upstream:sync command.\n * DO NOT EDIT MANUALLY - changes will be overwritten.\n *\n * Generated: ${new Date().toISOString()}\n */\n\nexport interface ElementMetadata {\n name: string;\n title: string;\n packageName: string;\n hasAuthor: boolean;\n hasPrint: boolean;\n hasConfig: boolean;\n hasSession: boolean;\n demoCount: number;\n}\n\nexport const ELEMENT_REGISTRY: readonly ElementMetadata[] = ${JSON.stringify(elements, null, 2)};\n\nexport function getElement(name: string): ElementMetadata | undefined {\n return ELEMENT_REGISTRY.find((el) => el.name === name);\n}\n\nexport function getAllElements(): ElementMetadata[] {\n return ELEMENT_REGISTRY;\n}\n`;\n\n await mkdir(dirname(registryPath), { recursive: true });\n await writeFile(registryPath, content, 'utf-8');\n console.log(`[demo-metadata] Generated registry with ${elements.length} elements`);\n}\n\n/**\n * Convert and copy sample configs for an element as JSON\n */\nasync function copySampleConfigs(elements: ElementMetadata[]): Promise<void> {\n for (const element of elements) {\n const sourcePath = join(ELEMENTS_REACT_PATH, element.name, 'docs/demo');\n const targetDir = join(DEMO_APP_PATH, 'src/lib/samples');\n await mkdir(targetDir, { recursive: true });\n\n // Convert config.mjs to JSON\n if (element.hasConfig) {\n const sourceConfig = join(sourcePath, 'config.mjs');\n const targetConfig = join(targetDir, `${element.name}.json`);\n try {\n // Dynamic import the .mjs file\n const configModule = await import(`file://${sourceConfig}`);\n let configData = configModule.default;\n\n // Convert old format (models array) to new format (demos array)\n if (configData?.models && !configData?.demos) {\n console.log(`[demo-metadata] Converting ${element.name} from old format to new format`);\n configData = {\n demos: configData.models.map((model: any, index: number) => ({\n id: index === 0 ? 'default' : `demo-${index + 1}`,\n title: index === 0 ? 'Default Demo' : `Demo ${index + 1}`,\n description: 'Default configuration',\n tags: [],\n model: model,\n session: { value: [] },\n })),\n };\n }\n\n // Count demos (now all in 'demos' format)\n if (configData?.demos && Array.isArray(configData.demos)) {\n element.demoCount = configData.demos.length;\n } else {\n element.demoCount = 0;\n }\n\n // Write as JSON\n await writeFile(targetConfig, JSON.stringify(configData, null, 2) + '\\n', 'utf-8');\n } catch (e) {\n console.warn(`[demo-metadata] Failed to convert config for ${element.name}:`, e);\n }\n }\n\n // Note: session.mjs files are no longer copied as separate files.\n // Sessions are now embedded within each demo object in the config.\n // Old format session files are automatically converted during config import above.\n }\n\n console.log(`[demo-metadata] Converted sample configs to JSON for ${elements.length} elements`);\n}\n\n/**\n * Main entry point\n */\nexport async function generateDemoMetadata(): Promise<void> {\n console.log('[demo-metadata] Scanning elements...');\n\n const reactElements = await scanReactElements();\n const allElements = [...reactElements].sort((a, b) => a.name.localeCompare(b.name));\n\n console.log(`[demo-metadata] Found ${reactElements.length} React elements`);\n\n // Copy sample configs first so demoCount gets populated\n await copySampleConfigs(allElements);\n\n // Then generate registry with updated demoCount values\n await generateRegistry(allElements);\n\n console.log('[demo-metadata] ✓ Demo metadata generation complete');\n}\n"]}
1
+ {"version":3,"file":"sync-demo-metadata.js","sourceRoot":"","sources":["../../../src/lib/upstream/sync-demo-metadata.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Generate demo metadata for SvelteKit demo app\n *\n * Scans packages/elements-react and packages/elements-svelte and rewrites the element registry\n * (lib/elements/registry.ts). Each element's demos live in lib/samples/<element>.json, which the\n * demo app reads; an element's docs/demo/config.mjs seeds that file only when it does not exist.\n */\nimport { existsSync, readdirSync, readFileSync } from 'node:fs';\nimport { mkdir, writeFile } from 'node:fs/promises';\nimport { join, dirname } from 'node:path';\nimport { fileURLToPath } from 'node:url';\n\nconst __dirname = dirname(fileURLToPath(import.meta.url));\nconst REPO_ROOT = join(__dirname, '../../../../..');\nconst DEMO_APP_PATH = join(REPO_ROOT, 'apps/element-demo');\nconst REGISTRY_PATH = join(DEMO_APP_PATH, 'src/lib/elements/registry.ts');\nconst SAMPLES_PATH = join(DEMO_APP_PATH, 'src/lib/samples');\nconst ELEMENT_ROOTS = ['packages/elements-react', 'packages/elements-svelte'];\n\nexport interface ElementMetadata {\n name: string;\n title: string;\n packageName: string;\n hasAuthor: boolean;\n hasPrint: boolean;\n hasConfig: boolean;\n hasSession: boolean;\n demoCount: number;\n}\n\n/**\n * Read the current registry entries, whose hand-set title and hasSession survive regeneration\n */\nfunction readExistingRegistry(): Map<string, ElementMetadata> {\n if (!existsSync(REGISTRY_PATH)) return new Map();\n\n const content = readFileSync(REGISTRY_PATH, 'utf-8');\n const match = content.match(/export const ELEMENT_REGISTRY[^=]*=\\s*(\\[[\\s\\S]*?\\]);/);\n if (!match) throw new Error(`Could not find ELEMENT_REGISTRY in ${REGISTRY_PATH}`);\n\n const entries: ElementMetadata[] = JSON.parse(match[1]);\n return new Map(entries.map((entry) => [entry.name, entry]));\n}\n\n/**\n * Convert old format (models array) to new format (demos array)\n */\nfunction toDemosFormat(configData: any): any {\n if (!configData?.models || configData?.demos) return configData;\n\n return {\n demos: configData.models.map((model: any, index: number) => ({\n id: index === 0 ? 'default' : `demo-${index + 1}`,\n title: index === 0 ? 'Default Demo' : `Demo ${index + 1}`,\n description: 'Default configuration',\n tags: [],\n model: model,\n session: { value: [] },\n })),\n };\n}\n\n/**\n * Load an element's samples JSON, seeding it from docs/demo/config.mjs when it does not exist\n */\nasync function loadSamples(name: string, elementPath: string): Promise<any | undefined> {\n const samplesPath = join(SAMPLES_PATH, `${name}.json`);\n const configPath = join(elementPath, 'docs/demo/config.mjs');\n const existing = existsSync(samplesPath)\n ? JSON.parse(readFileSync(samplesPath, 'utf-8'))\n : undefined;\n\n if (!existsSync(configPath)) return existing;\n\n let configData: any;\n try {\n configData = toDemosFormat((await import(`file://${configPath}`)).default);\n } catch (e) {\n console.warn(`[demo-metadata] Failed to convert config for ${name}:`, e);\n return existing;\n }\n\n if (existing) {\n if (JSON.stringify(configData) !== JSON.stringify(existing)) {\n console.warn(\n `[demo-metadata] ${name}: docs/demo/config.mjs differs from samples/${name}.json; ` +\n 'kept the samples file (delete it to regenerate from config.mjs)'\n );\n }\n return existing;\n }\n\n await mkdir(SAMPLES_PATH, { recursive: true });\n await writeFile(samplesPath, JSON.stringify(configData, null, 2) + '\\n', 'utf-8');\n console.log(`[demo-metadata] Seeded samples/${name}.json from docs/demo/config.mjs`);\n return configData;\n}\n\n/**\n * Scan the element package directories for all elements\n */\nasync function scanElements(existing: Map<string, ElementMetadata>): Promise<ElementMetadata[]> {\n const elements: ElementMetadata[] = [];\n\n for (const root of ELEMENT_ROOTS) {\n const rootPath = join(REPO_ROOT, root);\n if (!existsSync(rootPath)) continue;\n\n for (const dir of readdirSync(rootPath, { withFileTypes: true })) {\n if (!dir.isDirectory()) continue;\n\n // Check for required structure\n const elementPath = join(rootPath, dir.name);\n const srcPath = join(elementPath, 'src');\n if (!existsSync(join(srcPath, 'delivery'))) continue;\n\n const pkg = JSON.parse(readFileSync(join(elementPath, 'package.json'), 'utf-8'));\n const samples = await loadSamples(dir.name, elementPath);\n const previous = existing.get(dir.name);\n\n if (!previous) {\n console.log(\n `[demo-metadata] Added ${dir.name}; check its title and hasSession in registry.ts`\n );\n }\n\n elements.push({\n name: dir.name,\n // Generate title from name (e.g., \"multiple-choice\" -> \"Multiple Choice\")\n title:\n previous?.title ??\n dir.name\n .split('-')\n .map((word) => word.charAt(0).toUpperCase() + word.slice(1))\n .join(' '),\n packageName: pkg.name,\n hasAuthor: existsSync(join(srcPath, 'author')),\n hasPrint: existsSync(join(srcPath, 'print')),\n hasConfig: samples !== undefined,\n hasSession: previous?.hasSession ?? true,\n demoCount: Array.isArray(samples?.demos) ? samples.demos.length : 0,\n });\n }\n }\n\n return elements.sort((a, b) => a.name.localeCompare(b.name));\n}\n\n/**\n * Generate registry.ts file\n */\nasync function generateRegistry(elements: ElementMetadata[]): Promise<void> {\n const content = `/**\n * Element Registry\n *\n * Generated by \\`bun tools/generate-demo-metadata.mjs\\` from packages/elements-react and\n * packages/elements-svelte. Edit \\`title\\` and \\`hasSession\\` here; regeneration keeps them and\n * overwrites the other fields.\n */\n\nexport interface ElementMetadata {\n name: string;\n title: string;\n packageName: string;\n hasAuthor: boolean;\n hasPrint: boolean;\n hasConfig: boolean;\n hasSession: boolean;\n demoCount: number;\n}\n\nexport const ELEMENT_REGISTRY: readonly ElementMetadata[] = ${JSON.stringify(elements, null, 2)};\n\nexport function getElement(name: string): ElementMetadata | undefined {\n return ELEMENT_REGISTRY.find((el) => el.name === name);\n}\n\nexport function getAllElements(): readonly ElementMetadata[] {\n return ELEMENT_REGISTRY;\n}\n`;\n\n await mkdir(dirname(REGISTRY_PATH), { recursive: true });\n await writeFile(REGISTRY_PATH, content, 'utf-8');\n console.log(`[demo-metadata] Generated registry with ${elements.length} elements`);\n}\n\n/**\n * Main entry point\n */\nexport async function generateDemoMetadata(): Promise<void> {\n console.log('[demo-metadata] Scanning elements...');\n\n const existing = readExistingRegistry();\n const elements = await scanElements(existing);\n\n for (const name of existing.keys()) {\n if (!elements.some((element) => element.name === name)) {\n console.log(`[demo-metadata] Removed ${name}; no element package found`);\n }\n }\n\n await generateRegistry(elements);\n\n console.log('[demo-metadata] ✓ Demo metadata generation complete');\n}\n"]}
@@ -35,21 +35,6 @@ export declare function reexportTokenTypes(code: string, filePath: string): stri
35
35
  * when configure directory is not synced (ESM-incompatible due to Slate v0.x)
36
36
  */
37
37
  export declare function inlineConfigureDefaults(code: string): string;
38
- /**
39
- * Determine if a file should have .tsx extension based on content
40
- */
41
- export declare function shouldUseTsxExtension(content: string, originalPath: string): boolean;
42
- /**
43
- * Convert CommonJS module.exports to ES module exports
44
- *
45
- * Handles patterns like:
46
- * module.exports = { foo: ..., bar: ... }
47
- *
48
- * Converts to:
49
- * export const foo = ...;
50
- * export const bar = ...;
51
- */
52
- export declare function convertModuleExportsToEsm(content: string): string;
53
38
  /**
54
39
  * Transform lodash and lodash-es imports to the vendored shared lodash package.
55
40
  *
@@ -58,7 +43,6 @@ export declare function convertModuleExportsToEsm(content: string): string;
58
43
  * resolution while keeping import shapes tree-shakeable.
59
44
  */
60
45
  export declare function transformLodashToVendoredLodash(content: string): string;
61
- export declare const transformLodashToLodashEs: typeof transformLodashToVendoredLodash;
62
46
  /**
63
47
  * Transform classnames imports to clsx.
64
48
  *
@@ -97,11 +81,6 @@ export declare function transformReactInputAutosizeToLocal(content: string, sour
97
81
  * parsing.
98
82
  */
99
83
  export declare function transformConfigUiMathjsToLocalFraction(content: string, sourcePath?: string): string;
100
- /**
101
- * Compatibility wrapper retained for older callers. Lodash imports now target
102
- * the vendored shared package rather than lodash-es deep modules.
103
- */
104
- export declare function transformLodashEsDeepImportsToFullySpecified(content: string): string;
105
84
  /**
106
85
  * Ensure known strict-ESM deep imports include explicit file extensions.
107
86
  *
@@ -208,75 +208,6 @@ const ${importName} = {
208
208
  };`;
209
209
  return code.replace(configureImportRegex, inlinedDefaults);
210
210
  }
211
- /**
212
- * Determine if a file should have .tsx extension based on content
213
- */
214
- export function shouldUseTsxExtension(content, originalPath) {
215
- // If original file was .jsx, use .tsx
216
- if (originalPath.endsWith('.jsx')) {
217
- return true;
218
- }
219
- // If content contains JSX, use .tsx
220
- if (containsJsx(content)) {
221
- return true;
222
- }
223
- // Otherwise use .ts
224
- return false;
225
- }
226
- /**
227
- * Convert CommonJS module.exports to ES module exports
228
- *
229
- * Handles patterns like:
230
- * module.exports = { foo: ..., bar: ... }
231
- *
232
- * Converts to:
233
- * export const foo = ...;
234
- * export const bar = ...;
235
- */
236
- export function convertModuleExportsToEsm(content) {
237
- // Match: module.exports = { key: value, key2: value2, ... };
238
- const moduleExportsPattern = /module\.exports\s*=\s*\{([\s\S]*?)\};?/;
239
- const match = content.match(moduleExportsPattern);
240
- if (!match) {
241
- return content;
242
- }
243
- const [fullMatch, objectContent] = match;
244
- // Parse the object content into key-value pairs
245
- // Match patterns like: key: value, (with value possibly spanning multiple lines)
246
- const exports = [];
247
- const lines = objectContent.split('\n');
248
- let currentKey = null;
249
- let currentValue = [];
250
- for (const line of lines) {
251
- const trimmed = line.trim();
252
- if (!trimmed || trimmed === '{' || trimmed === '}')
253
- continue;
254
- // Check if this line starts a new key
255
- const keyMatch = trimmed.match(/^(\w+):\s*(.*)/);
256
- if (keyMatch) {
257
- // Save previous export if any
258
- if (currentKey) {
259
- const value = currentValue.join('\n').replace(/,\s*$/, ''); // Remove trailing comma
260
- exports.push(`export const ${currentKey} =\n${value};`);
261
- }
262
- // Start new export
263
- currentKey = keyMatch[1];
264
- currentValue = [keyMatch[2]];
265
- }
266
- else {
267
- // Continuation of current value
268
- currentValue.push(line);
269
- }
270
- }
271
- // Save last export
272
- if (currentKey) {
273
- const value = currentValue.join('\n').replace(/,\s*$/, '');
274
- exports.push(`export const ${currentKey} =\n${value};`);
275
- }
276
- // Replace the module.exports block with ES module exports
277
- const esmExports = exports.join('\n\n');
278
- return content.replace(fullMatch, esmExports);
279
- }
280
211
  const VENDORED_LODASH_PACKAGE = '@pie-element/shared-lodash';
281
212
  function lodashMemberFromPath(path) {
282
213
  return path.replace(/\.js$/i, '').split('/').pop() ?? path;
@@ -412,7 +343,6 @@ function lodashExportSpecifierBinding(member, specifier) {
412
343
  function formatLodashBinding(imported, local) {
413
344
  return imported === local ? imported : `${imported} as ${local}`;
414
345
  }
415
- export const transformLodashToLodashEs = transformLodashToVendoredLodash;
416
346
  /**
417
347
  * Transform classnames imports to clsx.
418
348
  *
@@ -617,13 +547,6 @@ export function transformConfigUiMathjsToLocalFraction(content, sourcePath) {
617
547
  }
618
548
  return transformed;
619
549
  }
620
- /**
621
- * Compatibility wrapper retained for older callers. Lodash imports now target
622
- * the vendored shared package rather than lodash-es deep modules.
623
- */
624
- export function transformLodashEsDeepImportsToFullySpecified(content) {
625
- return transformLodashToVendoredLodash(content);
626
- }
627
550
  /**
628
551
  * Ensure known strict-ESM deep imports include explicit file extensions.
629
552
  *