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

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 (34) hide show
  1. package/dist/commands/packages/create-react-elements.js +12 -31
  2. package/dist/commands/packages/create-react-elements.js.map +1 -1
  3. package/dist/commands/packages/init-synced-elements.js +3 -5
  4. package/dist/commands/packages/init-synced-elements.js.map +1 -1
  5. package/dist/lib/upstream/sync-compatibility.d.ts +0 -8
  6. package/dist/lib/upstream/sync-compatibility.js +0 -31
  7. package/dist/lib/upstream/sync-compatibility.js.map +1 -1
  8. package/dist/lib/upstream/sync-constants.d.ts +1 -11
  9. package/dist/lib/upstream/sync-constants.js +26 -15
  10. package/dist/lib/upstream/sync-constants.js.map +1 -1
  11. package/dist/lib/upstream/sync-imports.d.ts +0 -21
  12. package/dist/lib/upstream/sync-imports.js +0 -77
  13. package/dist/lib/upstream/sync-imports.js.map +1 -1
  14. package/dist/lib/upstream/sync-package-json.d.ts +0 -19
  15. package/dist/lib/upstream/sync-package-json.js +0 -58
  16. package/dist/lib/upstream/sync-package-json.js.map +1 -1
  17. package/dist/lib/upstream/sync-package-manager.d.ts +6 -0
  18. package/dist/lib/upstream/sync-package-manager.js +47 -24
  19. package/dist/lib/upstream/sync-package-manager.js.map +1 -1
  20. package/dist/lib/upstream/sync-source-tree.js +3 -1
  21. package/dist/lib/upstream/sync-source-tree.js.map +1 -1
  22. package/dist/lib/upstream/sync-vite-config.d.ts +0 -4
  23. package/dist/lib/upstream/sync-vite-config.js +1 -12
  24. package/dist/lib/upstream/sync-vite-config.js.map +1 -1
  25. package/dist/utils/compatibility.d.ts +0 -15
  26. package/dist/utils/compatibility.js +0 -34
  27. package/dist/utils/compatibility.js.map +1 -1
  28. package/dist/utils/conversion.d.ts +0 -5
  29. package/dist/utils/conversion.js +0 -21
  30. package/dist/utils/conversion.js.map +1 -1
  31. package/dist/utils/git.d.ts +0 -1
  32. package/dist/utils/git.js +0 -8
  33. package/dist/utils/git.js.map +1 -1
  34. package/package.json +2 -2
@@ -1 +1 @@
1
- {"version":3,"file":"sync-source-tree.js","sourceRoot":"","sources":["../../../src/lib/upstream/sync-source-tree.ts"],"names":[],"mappings":"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","sourcesContent":["import { existsSync } from 'node:fs';\nimport { mkdir, readFile, stat as fsStat, writeFile } from 'node:fs/promises';\nimport { dirname, join } from 'node:path';\nimport { convertJsToTs, convertJsxToTsx } from '../../utils/conversion.js';\nimport { containsJsx, fixImportsInFile } from './sync-imports.js';\nimport { readdir } from './sync-filesystem.js';\n\nexport interface SyncSourceTreeStats {\n filesChecked: number;\n filesCopied: number;\n filesProcessed: number;\n filesSkipped: number;\n filesUpdated: number;\n}\n\nexport interface SyncSourceTransformContext {\n absoluteSourcePath: string;\n relativeFilePath: string;\n upstreamSourcePath: string;\n}\n\nexport interface SyncSourceTreeOptions {\n sourceDir: string;\n targetDir: string;\n relativePath: string;\n sourcePathPrefix: string;\n upstreamCommit: string;\n transform: (content: string, context: SyncSourceTransformContext) => string;\n skipFile?: (fileName: string, context: SyncSourceTransformContext) => boolean;\n}\n\nexport async function syncSourceTree(options: SyncSourceTreeOptions): Promise<SyncSourceTreeStats> {\n const stats: SyncSourceTreeStats = {\n filesChecked: 0,\n filesCopied: 0,\n filesProcessed: 0,\n filesSkipped: 0,\n filesUpdated: 0,\n };\n const defaultExportFiles = new Set<string>();\n const items = await readdir(options.sourceDir);\n\n for (const item of items) {\n const srcPath = join(options.sourceDir, item);\n const stat = await fsStat(srcPath);\n\n if (stat.isDirectory()) {\n if (item.startsWith('__')) {\n continue;\n }\n\n const subStats = await syncSourceTree({\n ...options,\n sourceDir: srcPath,\n targetDir: join(options.targetDir, item),\n relativePath: join(options.relativePath, item),\n });\n addStats(stats, subStats);\n continue;\n }\n\n if (!item.endsWith('.js') && !item.endsWith('.jsx')) {\n continue;\n }\n\n const relativeFilePath = join(options.relativePath, item);\n const context: SyncSourceTransformContext = {\n absoluteSourcePath: srcPath,\n relativeFilePath,\n upstreamSourcePath: `${options.sourcePathPrefix}/${relativeFilePath}`,\n };\n\n if (options.skipFile?.(item, context)) {\n continue;\n }\n\n stats.filesChecked++;\n stats.filesProcessed++;\n\n let sourceContent = await readFile(srcPath, 'utf-8');\n sourceContent = options.transform(sourceContent, context);\n\n const hasJsx = item.endsWith('.jsx') || (item.endsWith('.js') && containsJsx(sourceContent));\n const targetFile = item.replace(/\\.jsx?$/, hasJsx ? '.tsx' : '.ts');\n const targetPath = join(options.targetDir, targetFile);\n const conversionResult = hasJsx\n ? convertJsxToTsx(sourceContent, {\n sourcePath: context.upstreamSourcePath,\n commit: options.upstreamCommit,\n })\n : convertJsToTs(sourceContent, {\n sourcePath: context.upstreamSourcePath,\n commit: options.upstreamCommit,\n });\n const converted = conversionResult.code;\n\n if (conversionResult.hasDefaultObjectExport) {\n defaultExportFiles.add(targetFile.replace(/\\.(ts|tsx)$/, ''));\n }\n\n const isNew = !existsSync(targetPath);\n if (!isNew) {\n const currentContent = await readFile(targetPath, 'utf-8');\n if (currentContent === converted) {\n stats.filesSkipped++;\n continue;\n }\n stats.filesUpdated++;\n } else {\n stats.filesCopied++;\n }\n\n await mkdir(dirname(targetPath), { recursive: true });\n await writeFile(targetPath, converted, 'utf-8');\n }\n\n if (defaultExportFiles.size > 0) {\n const targetDirItems = await readdir(options.targetDir);\n for (const item of targetDirItems) {\n const itemPath = join(options.targetDir, item);\n const stat = await fsStat(itemPath);\n if (stat.isFile() && (item.endsWith('.tsx') || item.endsWith('.ts'))) {\n await fixImportsInFile(itemPath, defaultExportFiles);\n }\n }\n }\n\n return stats;\n}\n\nfunction addStats(target: SyncSourceTreeStats, source: SyncSourceTreeStats): void {\n target.filesChecked += source.filesChecked;\n target.filesCopied += source.filesCopied;\n target.filesProcessed += source.filesProcessed;\n target.filesSkipped += source.filesSkipped;\n target.filesUpdated += source.filesUpdated;\n}\n"]}
1
+ {"version":3,"file":"sync-source-tree.js","sourceRoot":"","sources":["../../../src/lib/upstream/sync-source-tree.ts"],"names":[],"mappings":"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","sourcesContent":["import { existsSync } from 'node:fs';\nimport { mkdir, readFile, stat as fsStat, writeFile } from 'node:fs/promises';\nimport { dirname, join } from 'node:path';\nimport { convertJsToTs, convertJsxToTsx } from '../../utils/conversion.js';\nimport { RETIRED_UPSTREAM_SOURCE_FILES } from './sync-constants.js';\nimport { containsJsx, fixImportsInFile } from './sync-imports.js';\nimport { readdir } from './sync-filesystem.js';\n\nexport interface SyncSourceTreeStats {\n filesChecked: number;\n filesCopied: number;\n filesProcessed: number;\n filesSkipped: number;\n filesUpdated: number;\n}\n\nexport interface SyncSourceTransformContext {\n absoluteSourcePath: string;\n relativeFilePath: string;\n upstreamSourcePath: string;\n}\n\nexport interface SyncSourceTreeOptions {\n sourceDir: string;\n targetDir: string;\n relativePath: string;\n sourcePathPrefix: string;\n upstreamCommit: string;\n transform: (content: string, context: SyncSourceTransformContext) => string;\n skipFile?: (fileName: string, context: SyncSourceTransformContext) => boolean;\n}\n\nexport async function syncSourceTree(options: SyncSourceTreeOptions): Promise<SyncSourceTreeStats> {\n const stats: SyncSourceTreeStats = {\n filesChecked: 0,\n filesCopied: 0,\n filesProcessed: 0,\n filesSkipped: 0,\n filesUpdated: 0,\n };\n const defaultExportFiles = new Set<string>();\n const items = await readdir(options.sourceDir);\n\n for (const item of items) {\n const srcPath = join(options.sourceDir, item);\n const stat = await fsStat(srcPath);\n\n if (stat.isDirectory()) {\n if (item.startsWith('__')) {\n continue;\n }\n\n const subStats = await syncSourceTree({\n ...options,\n sourceDir: srcPath,\n targetDir: join(options.targetDir, item),\n relativePath: join(options.relativePath, item),\n });\n addStats(stats, subStats);\n continue;\n }\n\n if (!item.endsWith('.js') && !item.endsWith('.jsx')) {\n continue;\n }\n\n const relativeFilePath = join(options.relativePath, item);\n const context: SyncSourceTransformContext = {\n absoluteSourcePath: srcPath,\n relativeFilePath,\n upstreamSourcePath: `${options.sourcePathPrefix}/${relativeFilePath}`,\n };\n\n if (\n RETIRED_UPSTREAM_SOURCE_FILES.has(context.upstreamSourcePath) ||\n options.skipFile?.(item, context)\n ) {\n continue;\n }\n\n stats.filesChecked++;\n stats.filesProcessed++;\n\n let sourceContent = await readFile(srcPath, 'utf-8');\n sourceContent = options.transform(sourceContent, context);\n\n const hasJsx = item.endsWith('.jsx') || (item.endsWith('.js') && containsJsx(sourceContent));\n const targetFile = item.replace(/\\.jsx?$/, hasJsx ? '.tsx' : '.ts');\n const targetPath = join(options.targetDir, targetFile);\n const conversionResult = hasJsx\n ? convertJsxToTsx(sourceContent, {\n sourcePath: context.upstreamSourcePath,\n commit: options.upstreamCommit,\n })\n : convertJsToTs(sourceContent, {\n sourcePath: context.upstreamSourcePath,\n commit: options.upstreamCommit,\n });\n const converted = conversionResult.code;\n\n if (conversionResult.hasDefaultObjectExport) {\n defaultExportFiles.add(targetFile.replace(/\\.(ts|tsx)$/, ''));\n }\n\n const isNew = !existsSync(targetPath);\n if (!isNew) {\n const currentContent = await readFile(targetPath, 'utf-8');\n if (currentContent === converted) {\n stats.filesSkipped++;\n continue;\n }\n stats.filesUpdated++;\n } else {\n stats.filesCopied++;\n }\n\n await mkdir(dirname(targetPath), { recursive: true });\n await writeFile(targetPath, converted, 'utf-8');\n }\n\n if (defaultExportFiles.size > 0) {\n const targetDirItems = await readdir(options.targetDir);\n for (const item of targetDirItems) {\n const itemPath = join(options.targetDir, item);\n const stat = await fsStat(itemPath);\n if (stat.isFile() && (item.endsWith('.tsx') || item.endsWith('.ts'))) {\n await fixImportsInFile(itemPath, defaultExportFiles);\n }\n }\n }\n\n return stats;\n}\n\nfunction addStats(target: SyncSourceTreeStats, source: SyncSourceTreeStats): void {\n target.filesChecked += source.filesChecked;\n target.filesCopied += source.filesCopied;\n target.filesProcessed += source.filesProcessed;\n target.filesSkipped += source.filesSkipped;\n target.filesUpdated += source.filesUpdated;\n}\n"]}
@@ -1,7 +1,3 @@
1
- /**
2
- * Detect entry points for an element package
3
- */
4
- export declare function detectElementEntryPoints(elementDir: string): Record<string, string>;
5
1
  /**
6
2
  * Generate Vite config content for an element package
7
3
  *
@@ -1,20 +1,9 @@
1
1
  /**
2
2
  * Vite configuration generation for sync operations
3
3
  */
4
- import { collectEntryPoints, detectEntryFile } from './sync-entry-discovery.js';
4
+ import { detectEntryFile } from './sync-entry-discovery.js';
5
5
  import { createExternalFunction } from './sync-externals.js';
6
6
  import { getPieLibVitePreset } from './sync-presets.js';
7
- /**
8
- * Detect entry points for an element package
9
- */
10
- export function detectElementEntryPoints(elementDir) {
11
- return collectEntryPoints(elementDir, [
12
- ['index', 'src/index'],
13
- ['controller/index', 'src/controller/index'],
14
- ['configure/index', 'src/configure/index'],
15
- ['delivery/index', 'src/delivery/index'],
16
- ]);
17
- }
18
7
  /**
19
8
  * Generate Vite config content for an element package
20
9
  *
@@ -1 +1 @@
1
- {"version":3,"file":"sync-vite-config.js","sourceRoot":"","sources":["../../../src/lib/upstream/sync-vite-config.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,OAAO,EAAE,kBAAkB,EAAE,eAAe,EAAE,MAAM,2BAA2B,CAAC;AAChF,OAAO,EAAE,sBAAsB,EAAE,MAAM,qBAAqB,CAAC;AAC7D,OAAO,EAAE,mBAAmB,EAAE,MAAM,mBAAmB,CAAC;AAExD;;GAEG;AACH,MAAM,UAAU,wBAAwB,CAAC,UAAkB;IACzD,OAAO,kBAAkB,CAAC,UAAU,EAAE;QACpC,CAAC,OAAO,EAAE,WAAW,CAAC;QACtB,CAAC,kBAAkB,EAAE,sBAAsB,CAAC;QAC5C,CAAC,iBAAiB,EAAE,qBAAqB,CAAC;QAC1C,CAAC,gBAAgB,EAAE,oBAAoB,CAAC;KACzC,CAAC,CAAC;AACL,CAAC;AAED;;;;;;;;;;;;;;;GAeG;AACH,MAAM,UAAU,yBAAyB,CAAC,WAAmC;IAC3E,IAAI,MAAM,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QAC1C,MAAM,IAAI,KAAK,CAAC,mCAAmC,CAAC,CAAC;IACvD,CAAC;IAED,MAAM,SAAS,GAAG,IAAI,CAAC,SAAS,CAAC,WAAW,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,OAAO,CAAC,KAAK,EAAE,QAAQ,CAAC,CAAC;IAEhF,OAAO;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;iBA+BQ,SAAS,CAAC,SAAS,EAAE;;;;oBAIlB,sBAAsB,CAAC,SAAS,CAAC;;;;;;;;;CASpD,CAAC;AACF,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,wBAAwB,CAAC,WAAoB,EAAE,UAAmB;IAChF,6DAA6D;IAC7D,IAAI,UAAU,GAAG,cAAc,CAAC;IAChC,IAAI,UAAU,EAAE,CAAC;QACf,UAAU,GAAG,eAAe,CAAC,UAAU,EAAE,WAAW,CAAC,IAAI,UAAU,CAAC;IACtE,CAAC;IAED,MAAM,MAAM,GAAG,mBAAmB,CAAC,WAAW,CAAC,CAAC;IAEhD,2EAA2E;IAC3E,IAAI,MAAM,KAAK,wBAAwB,EAAE,CAAC;QACxC,OAAO;;;;;;;;;;;;;qCAa0B,UAAU;;;;;;;;;;;;;;;;;;;;CAoB9C,CAAC;IACA,CAAC;IAED,qEAAqE;IACrE,IAAI,MAAM,KAAK,YAAY,EAAE,CAAC;QAC5B,OAAO;;;;;;;;;;;;;;;qCAe0B,UAAU;;;;;kBAK7B,sBAAsB,CAAC,QAAQ,CAAC;;;;;;;;CAQjD,CAAC;IACA,CAAC;IAED,iFAAiF;IACjF,IAAI,MAAM,KAAK,uBAAuB,EAAE,CAAC;QACvC,OAAO;;;;;;;;;;;;;;;qCAe0B,UAAU;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAkC9C,CAAC;IACA,CAAC;IAED,yBAAyB;IACzB,OAAO;;;;;;;;;;;;;;;qCAe4B,UAAU;;;;;kBAK7B,sBAAsB,CAAC,QAAQ,EAAE;QAC3C,iBAAiB,EAAE,WAAW,KAAK,WAAW;KAC/C,CAAC;;;;;;;;CAQP,CAAC;AACF,CAAC","sourcesContent":["/**\n * Vite configuration generation for sync operations\n */\nimport { collectEntryPoints, detectEntryFile } from './sync-entry-discovery.js';\nimport { createExternalFunction } from './sync-externals.js';\nimport { getPieLibVitePreset } from './sync-presets.js';\n\n/**\n * Detect entry points for an element package\n */\nexport function detectElementEntryPoints(elementDir: string): Record<string, string> {\n return collectEntryPoints(elementDir, [\n ['index', 'src/index'],\n ['controller/index', 'src/controller/index'],\n ['configure/index', 'src/configure/index'],\n ['delivery/index', 'src/delivery/index'],\n ]);\n}\n\n/**\n * Generate Vite config content for an element package\n *\n * @tech-debt The __PIE_PACKAGE_VERSION__ injection was added in commit 8a579dfe\n * \"fix: support private child elements in browser esm\" to enable version-scoped\n * custom element registration (e.g., 'ebsr-multiple-choice--version-8-1-1').\n *\n * This prevents name collisions when multiple versions of elements coexist in\n * browser ESM bundles. However, it adds boilerplate to all 51+ element configs,\n * even though only ~2 elements (EBSR, complex-rubric) actually need it.\n *\n * Consider refactoring:\n * - Move to shared @pie-element/vite-plugin-version\n * - Only inject for elements with private children\n * - Use runtime version detection instead of compile-time injection\n */\nexport function generateElementViteConfig(entryPoints: Record<string, string>): string {\n if (Object.keys(entryPoints).length === 0) {\n throw new Error('No entry points found for element');\n }\n\n const entryJson = JSON.stringify(entryPoints, null, 8).replace(/^/gm, ' ');\n\n return `import { readFileSync } from 'node:fs';\nimport { resolve } from 'node:path';\nimport react from '@vitejs/plugin-react';\nimport { defineConfig } from 'vite';\n\nconst packageJson = JSON.parse(readFileSync(resolve(__dirname, 'package.json'), 'utf-8')) as {\n name?: string;\n version?: string;\n};\n\nexport default defineConfig(({ mode }) => {\n // Demo mode: serve the docs/demo directory\n if (mode === 'demo') {\n return {\n plugins: [react()],\n root: 'docs/demo',\n server: {\n port: 5174,\n },\n };\n }\n\n // Build mode: build the library\n return {\n plugins: [react()],\n define: {\n __PIE_PACKAGE_NAME__: JSON.stringify(packageJson.name ?? ''),\n __PIE_PACKAGE_VERSION__: JSON.stringify(packageJson.version ?? 'local'),\n },\n build: {\n lib: {\n entry: ${entryJson.trimStart()},\n formats: ['es'],\n },\n rollupOptions: {\n external: ${createExternalFunction('element')},\n output: {\n preserveModules: true,\n preserveModulesRoot: 'src',\n },\n },\n },\n };\n});\n`;\n}\n\n/**\n * Generate Vite config content for a pie-lib package\n */\nexport function generatePieLibViteConfig(packageName?: string, packageDir?: string): string {\n // Detect entry point extension if package directory provided\n let entryPoint = 'src/index.ts';\n if (packageDir) {\n entryPoint = detectEntryFile(packageDir, 'src/index') ?? entryPoint;\n }\n\n const preset = getPieLibVitePreset(packageName);\n\n // Special config for math-rendering wrapper (externalizes adapter package)\n if (preset === 'math-rendering-wrapper') {\n return `import { resolve } from 'node:path';\nimport { defineConfig } from 'vite';\n\nexport default defineConfig({\n // ESM-first resolution. A dependency with no exports map (@visx/* v3,\n // @hello-pangea/dnd) otherwise falls back to its CommonJS main entry, and\n // bundling CommonJS while React is external makes rolldown emit a\n // require(\"react\") shim that throws in the browser. Preferring the module\n // field resolves those dependencies to their ESM build instead.\n resolve: { mainFields: ['module', 'browser', 'main'] },\n build: {\n lib: {\n entry: {\n index: resolve(__dirname, '${entryPoint}'),\n },\n formats: ['es'],\n },\n rollupOptions: {\n external: (id) => {\n return (\n /^@pie-element\\\\/shared-/.test(id) ||\n id === '@pie-element/shared-math-rendering-mathjax' ||\n /^@pie-lib\\\\//.test(id) ||\n ['debug'].includes(id)\n );\n },\n output: {\n preserveModules: true,\n preserveModulesRoot: 'src',\n },\n },\n },\n});\n`;\n }\n\n // Special config for test-utils (includes testing library externals)\n if (preset === 'test-utils') {\n return `import { resolve } from 'node:path';\nimport react from '@vitejs/plugin-react';\nimport { defineConfig } from 'vite';\n\nexport default defineConfig({\n // ESM-first resolution. A dependency with no exports map (@visx/* v3,\n // @hello-pangea/dnd) otherwise falls back to its CommonJS main entry, and\n // bundling CommonJS while React is external makes rolldown emit a\n // require(\"react\") shim that throws in the browser. Preferring the module\n // field resolves those dependencies to their ESM build instead.\n resolve: { mainFields: ['module', 'browser', 'main'] },\n plugins: [react()],\n build: {\n lib: {\n entry: {\n index: resolve(__dirname, '${entryPoint}'),\n },\n formats: ['es'],\n },\n rollupOptions: {\n external: ${createExternalFunction('pielib')},\n output: {\n preserveModules: true,\n preserveModulesRoot: 'src',\n },\n },\n },\n});\n`;\n }\n\n // Special config for editable-html-tip-tap (externalizes prosemirror and tiptap)\n if (preset === 'editable-html-tip-tap') {\n return `import { resolve } from 'node:path';\nimport react from '@vitejs/plugin-react';\nimport { defineConfig } from 'vite';\n\nexport default defineConfig({\n // ESM-first resolution. A dependency with no exports map (@visx/* v3,\n // @hello-pangea/dnd) otherwise falls back to its CommonJS main entry, and\n // bundling CommonJS while React is external makes rolldown emit a\n // require(\"react\") shim that throws in the browser. Preferring the module\n // field resolves those dependencies to their ESM build instead.\n resolve: { mainFields: ['module', 'browser', 'main'] },\n plugins: [react()],\n build: {\n lib: {\n entry: {\n index: resolve(__dirname, '${entryPoint}'),\n },\n formats: ['es'],\n },\n rollupOptions: {\n external: (id) => {\n return (\n /^react($|\\\\/)/.test(id) ||\n /^react-dom($|\\\\/)/.test(id) ||\n /^@pie-lib\\\\//.test(id) ||\n /^@pie-element\\\\//.test(id) ||\n /^@pie-element\\\\//.test(id) ||\n /^@pie-framework\\\\//.test(id) ||\n /^@mui\\\\//.test(id) ||\n /^@emotion\\\\//.test(id) ||\n /^d3-/.test(id) ||\n /^@testing-library\\\\//.test(id) ||\n /^styled-components/.test(id) ||\n id === 'konva' || /^konva\\\\//.test(id) ||\n id === 'react-konva' || /^react-konva\\\\//.test(id) ||\n id === '@mdi/react' || /^@mdi\\\\/react\\\\//.test(id) ||\n id === '@mdi/js' || /^@mdi\\\\/js\\\\//.test(id) ||\n /^prosemirror-/.test(id) ||\n /^@tiptap\\\\//.test(id) ||\n ['prop-types', 'debug', 'i18next', 'humps', 'mathjs', 'react-jss', 'js-combinatorics', '@dnd-kit/core', 'react-transition-group'].includes(id)\n );\n },\n output: {\n preserveModules: true,\n preserveModulesRoot: 'src',\n },\n },\n },\n});\n`;\n }\n\n // Default pie-lib config\n return `import { resolve } from 'node:path';\nimport react from '@vitejs/plugin-react';\nimport { defineConfig } from 'vite';\n\nexport default defineConfig({\n // ESM-first resolution. A dependency with no exports map (@visx/* v3,\n // @hello-pangea/dnd) otherwise falls back to its CommonJS main entry, and\n // bundling CommonJS while React is external makes rolldown emit a\n // require(\"react\") shim that throws in the browser. Preferring the module\n // field resolves those dependencies to their ESM build instead.\n resolve: { mainFields: ['module', 'browser', 'main'] },\n plugins: [react()],\n build: {\n lib: {\n entry: {\n index: resolve(__dirname, '${entryPoint}'),\n },\n formats: ['es'],\n },\n rollupOptions: {\n external: ${createExternalFunction('pielib', {\n externalizeMathjs: packageName !== 'config-ui',\n })},\n output: {\n preserveModules: true,\n preserveModulesRoot: 'src',\n },\n },\n },\n});\n`;\n}\n"]}
1
+ {"version":3,"file":"sync-vite-config.js","sourceRoot":"","sources":["../../../src/lib/upstream/sync-vite-config.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,OAAO,EAAE,eAAe,EAAE,MAAM,2BAA2B,CAAC;AAC5D,OAAO,EAAE,sBAAsB,EAAE,MAAM,qBAAqB,CAAC;AAC7D,OAAO,EAAE,mBAAmB,EAAE,MAAM,mBAAmB,CAAC;AAExD;;;;;;;;;;;;;;;GAeG;AACH,MAAM,UAAU,yBAAyB,CAAC,WAAmC;IAC3E,IAAI,MAAM,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QAC1C,MAAM,IAAI,KAAK,CAAC,mCAAmC,CAAC,CAAC;IACvD,CAAC;IAED,MAAM,SAAS,GAAG,IAAI,CAAC,SAAS,CAAC,WAAW,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,OAAO,CAAC,KAAK,EAAE,QAAQ,CAAC,CAAC;IAEhF,OAAO;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;iBA+BQ,SAAS,CAAC,SAAS,EAAE;;;;oBAIlB,sBAAsB,CAAC,SAAS,CAAC;;;;;;;;;CASpD,CAAC;AACF,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,wBAAwB,CAAC,WAAoB,EAAE,UAAmB;IAChF,6DAA6D;IAC7D,IAAI,UAAU,GAAG,cAAc,CAAC;IAChC,IAAI,UAAU,EAAE,CAAC;QACf,UAAU,GAAG,eAAe,CAAC,UAAU,EAAE,WAAW,CAAC,IAAI,UAAU,CAAC;IACtE,CAAC;IAED,MAAM,MAAM,GAAG,mBAAmB,CAAC,WAAW,CAAC,CAAC;IAEhD,2EAA2E;IAC3E,IAAI,MAAM,KAAK,wBAAwB,EAAE,CAAC;QACxC,OAAO;;;;;;;;;;;;;qCAa0B,UAAU;;;;;;;;;;;;;;;;;;;;CAoB9C,CAAC;IACA,CAAC;IAED,qEAAqE;IACrE,IAAI,MAAM,KAAK,YAAY,EAAE,CAAC;QAC5B,OAAO;;;;;;;;;;;;;;;qCAe0B,UAAU;;;;;kBAK7B,sBAAsB,CAAC,QAAQ,CAAC;;;;;;;;CAQjD,CAAC;IACA,CAAC;IAED,iFAAiF;IACjF,IAAI,MAAM,KAAK,uBAAuB,EAAE,CAAC;QACvC,OAAO;;;;;;;;;;;;;;;qCAe0B,UAAU;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAkC9C,CAAC;IACA,CAAC;IAED,yBAAyB;IACzB,OAAO;;;;;;;;;;;;;;;qCAe4B,UAAU;;;;;kBAK7B,sBAAsB,CAAC,QAAQ,EAAE;QAC3C,iBAAiB,EAAE,WAAW,KAAK,WAAW;KAC/C,CAAC;;;;;;;;CAQP,CAAC;AACF,CAAC","sourcesContent":["/**\n * Vite configuration generation for sync operations\n */\nimport { detectEntryFile } from './sync-entry-discovery.js';\nimport { createExternalFunction } from './sync-externals.js';\nimport { getPieLibVitePreset } from './sync-presets.js';\n\n/**\n * Generate Vite config content for an element package\n *\n * @tech-debt The __PIE_PACKAGE_VERSION__ injection was added in commit 8a579dfe\n * \"fix: support private child elements in browser esm\" to enable version-scoped\n * custom element registration (e.g., 'ebsr-multiple-choice--version-8-1-1').\n *\n * This prevents name collisions when multiple versions of elements coexist in\n * browser ESM bundles. However, it adds boilerplate to all 51+ element configs,\n * even though only ~2 elements (EBSR, complex-rubric) actually need it.\n *\n * Consider refactoring:\n * - Move to shared @pie-element/vite-plugin-version\n * - Only inject for elements with private children\n * - Use runtime version detection instead of compile-time injection\n */\nexport function generateElementViteConfig(entryPoints: Record<string, string>): string {\n if (Object.keys(entryPoints).length === 0) {\n throw new Error('No entry points found for element');\n }\n\n const entryJson = JSON.stringify(entryPoints, null, 8).replace(/^/gm, ' ');\n\n return `import { readFileSync } from 'node:fs';\nimport { resolve } from 'node:path';\nimport react from '@vitejs/plugin-react';\nimport { defineConfig } from 'vite';\n\nconst packageJson = JSON.parse(readFileSync(resolve(__dirname, 'package.json'), 'utf-8')) as {\n name?: string;\n version?: string;\n};\n\nexport default defineConfig(({ mode }) => {\n // Demo mode: serve the docs/demo directory\n if (mode === 'demo') {\n return {\n plugins: [react()],\n root: 'docs/demo',\n server: {\n port: 5174,\n },\n };\n }\n\n // Build mode: build the library\n return {\n plugins: [react()],\n define: {\n __PIE_PACKAGE_NAME__: JSON.stringify(packageJson.name ?? ''),\n __PIE_PACKAGE_VERSION__: JSON.stringify(packageJson.version ?? 'local'),\n },\n build: {\n lib: {\n entry: ${entryJson.trimStart()},\n formats: ['es'],\n },\n rollupOptions: {\n external: ${createExternalFunction('element')},\n output: {\n preserveModules: true,\n preserveModulesRoot: 'src',\n },\n },\n },\n };\n});\n`;\n}\n\n/**\n * Generate Vite config content for a pie-lib package\n */\nexport function generatePieLibViteConfig(packageName?: string, packageDir?: string): string {\n // Detect entry point extension if package directory provided\n let entryPoint = 'src/index.ts';\n if (packageDir) {\n entryPoint = detectEntryFile(packageDir, 'src/index') ?? entryPoint;\n }\n\n const preset = getPieLibVitePreset(packageName);\n\n // Special config for math-rendering wrapper (externalizes adapter package)\n if (preset === 'math-rendering-wrapper') {\n return `import { resolve } from 'node:path';\nimport { defineConfig } from 'vite';\n\nexport default defineConfig({\n // ESM-first resolution. A dependency with no exports map (@visx/* v3,\n // @hello-pangea/dnd) otherwise falls back to its CommonJS main entry, and\n // bundling CommonJS while React is external makes rolldown emit a\n // require(\"react\") shim that throws in the browser. Preferring the module\n // field resolves those dependencies to their ESM build instead.\n resolve: { mainFields: ['module', 'browser', 'main'] },\n build: {\n lib: {\n entry: {\n index: resolve(__dirname, '${entryPoint}'),\n },\n formats: ['es'],\n },\n rollupOptions: {\n external: (id) => {\n return (\n /^@pie-element\\\\/shared-/.test(id) ||\n id === '@pie-element/shared-math-rendering-mathjax' ||\n /^@pie-lib\\\\//.test(id) ||\n ['debug'].includes(id)\n );\n },\n output: {\n preserveModules: true,\n preserveModulesRoot: 'src',\n },\n },\n },\n});\n`;\n }\n\n // Special config for test-utils (includes testing library externals)\n if (preset === 'test-utils') {\n return `import { resolve } from 'node:path';\nimport react from '@vitejs/plugin-react';\nimport { defineConfig } from 'vite';\n\nexport default defineConfig({\n // ESM-first resolution. A dependency with no exports map (@visx/* v3,\n // @hello-pangea/dnd) otherwise falls back to its CommonJS main entry, and\n // bundling CommonJS while React is external makes rolldown emit a\n // require(\"react\") shim that throws in the browser. Preferring the module\n // field resolves those dependencies to their ESM build instead.\n resolve: { mainFields: ['module', 'browser', 'main'] },\n plugins: [react()],\n build: {\n lib: {\n entry: {\n index: resolve(__dirname, '${entryPoint}'),\n },\n formats: ['es'],\n },\n rollupOptions: {\n external: ${createExternalFunction('pielib')},\n output: {\n preserveModules: true,\n preserveModulesRoot: 'src',\n },\n },\n },\n});\n`;\n }\n\n // Special config for editable-html-tip-tap (externalizes prosemirror and tiptap)\n if (preset === 'editable-html-tip-tap') {\n return `import { resolve } from 'node:path';\nimport react from '@vitejs/plugin-react';\nimport { defineConfig } from 'vite';\n\nexport default defineConfig({\n // ESM-first resolution. A dependency with no exports map (@visx/* v3,\n // @hello-pangea/dnd) otherwise falls back to its CommonJS main entry, and\n // bundling CommonJS while React is external makes rolldown emit a\n // require(\"react\") shim that throws in the browser. Preferring the module\n // field resolves those dependencies to their ESM build instead.\n resolve: { mainFields: ['module', 'browser', 'main'] },\n plugins: [react()],\n build: {\n lib: {\n entry: {\n index: resolve(__dirname, '${entryPoint}'),\n },\n formats: ['es'],\n },\n rollupOptions: {\n external: (id) => {\n return (\n /^react($|\\\\/)/.test(id) ||\n /^react-dom($|\\\\/)/.test(id) ||\n /^@pie-lib\\\\//.test(id) ||\n /^@pie-element\\\\//.test(id) ||\n /^@pie-element\\\\//.test(id) ||\n /^@pie-framework\\\\//.test(id) ||\n /^@mui\\\\//.test(id) ||\n /^@emotion\\\\//.test(id) ||\n /^d3-/.test(id) ||\n /^@testing-library\\\\//.test(id) ||\n /^styled-components/.test(id) ||\n id === 'konva' || /^konva\\\\//.test(id) ||\n id === 'react-konva' || /^react-konva\\\\//.test(id) ||\n id === '@mdi/react' || /^@mdi\\\\/react\\\\//.test(id) ||\n id === '@mdi/js' || /^@mdi\\\\/js\\\\//.test(id) ||\n /^prosemirror-/.test(id) ||\n /^@tiptap\\\\//.test(id) ||\n ['prop-types', 'debug', 'i18next', 'humps', 'mathjs', 'react-jss', 'js-combinatorics', '@dnd-kit/core', 'react-transition-group'].includes(id)\n );\n },\n output: {\n preserveModules: true,\n preserveModulesRoot: 'src',\n },\n },\n },\n});\n`;\n }\n\n // Default pie-lib config\n return `import { resolve } from 'node:path';\nimport react from '@vitejs/plugin-react';\nimport { defineConfig } from 'vite';\n\nexport default defineConfig({\n // ESM-first resolution. A dependency with no exports map (@visx/* v3,\n // @hello-pangea/dnd) otherwise falls back to its CommonJS main entry, and\n // bundling CommonJS while React is external makes rolldown emit a\n // require(\"react\") shim that throws in the browser. Preferring the module\n // field resolves those dependencies to their ESM build instead.\n resolve: { mainFields: ['module', 'browser', 'main'] },\n plugins: [react()],\n build: {\n lib: {\n entry: {\n index: resolve(__dirname, '${entryPoint}'),\n },\n formats: ['es'],\n },\n rollupOptions: {\n external: ${createExternalFunction('pielib', {\n externalizeMathjs: packageName !== 'config-ui',\n })},\n output: {\n preserveModules: true,\n preserveModulesRoot: 'src',\n },\n },\n },\n});\n`;\n}\n"]}
@@ -124,18 +124,3 @@ export declare function deriveStaticBrowserEsmReport(repoRoot: string): Promise<
124
124
  export declare function formatCompatibilityReportLastAnalyzed(report: CompatibilityReport): string;
125
125
  export declare function createTrackedCompatibilityReport(report: CompatibilityReport): CompatibilityReport;
126
126
  export declare function loadCompatibilityReport(path: string): Promise<CompatibilityReport>;
127
- export declare function isElementCompatible(element: string, report: CompatibilityReport): boolean;
128
- export declare function isPieLibPackageCompatible(pkg: string, report: CompatibilityReport): boolean;
129
- export declare function getElementBlockers(element: string, report: CompatibilityReport): string[];
130
- /**
131
- * Check if an element is ESM player ready (no CommonJS deps + proper ESM package structure)
132
- */
133
- export declare function isElementEsmPlayerReady(element: string, report: CompatibilityReport): boolean;
134
- /**
135
- * Check if an element has student UI ready (even if configure/controller aren't)
136
- */
137
- export declare function isElementStudentUIReady(element: string, report: CompatibilityReport): boolean;
138
- /**
139
- * Get ESM validation details for an element
140
- */
141
- export declare function getEsmValidation(element: string, report: CompatibilityReport): EsmValidationResult | null;
@@ -148,38 +148,4 @@ export async function loadCompatibilityReport(path) {
148
148
  const content = await readFile(path, 'utf-8');
149
149
  return normalizeCompatibilityReport(JSON.parse(content));
150
150
  }
151
- export function isElementCompatible(element, report) {
152
- return report.elements.includes(element);
153
- }
154
- export function isPieLibPackageCompatible(pkg, report) {
155
- return report.pieLibPackages.includes(pkg);
156
- }
157
- export function getElementBlockers(element, report) {
158
- return report.blockedElements[element] || [];
159
- }
160
- /**
161
- * Check if an element is ESM player ready (no CommonJS deps + proper ESM package structure)
162
- */
163
- export function isElementEsmPlayerReady(element, report) {
164
- return report.esmPlayerReady.includes(element);
165
- }
166
- /**
167
- * Check if an element has student UI ready (even if configure/controller aren't)
168
- */
169
- export function isElementStudentUIReady(element, report) {
170
- const detail = report.elementDetails[element];
171
- if (!detail)
172
- return false;
173
- // If fully compatible, student UI is ready
174
- if (detail.compatible)
175
- return true;
176
- // Check if student UI is explicitly marked as compatible
177
- return detail.studentUI?.compatible === true;
178
- }
179
- /**
180
- * Get ESM validation details for an element
181
- */
182
- export function getEsmValidation(element, report) {
183
- return report.esmValidation[element] || null;
184
- }
185
151
  //# sourceMappingURL=compatibility.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"compatibility.js","sourceRoot":"","sources":["../../src/utils/compatibility.ts"],"names":[],"mappings":"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","sourcesContent":["import { readFile, readdir } from 'node:fs/promises';\nimport { existsSync } from 'node:fs';\nimport { join } from 'node:path';\n\n/**\n * ESM package.json validation result\n */\nexport interface EsmPackageValidation {\n hasTypeModule: boolean;\n hasExportsField: boolean;\n hasMainExport: boolean;\n hasControllerExport: boolean;\n sideEffectsFree: boolean;\n mainExportIsEsm: boolean;\n controllerExportIsEsm: boolean;\n}\n\n/**\n * ESM player validation result for an element\n */\nexport interface EsmValidationResult {\n compatible: boolean;\n packageJson: EsmPackageValidation;\n blockers: string[];\n warnings: string[];\n}\n\n/**\n * Runtime-ish validation for ESM player readiness (CDN resolution / module parse).\n * Note: this is NOT a full browser execution test, but it provides production-like signal\n * by verifying CDN URLs resolve and the returned JS parses as an ES module.\n */\nexport interface EsmRuntimeValidationResult {\n /**\n * Whether this element passed the runtime-ish probe.\n * When false, see `errors` for details.\n */\n compatible: boolean;\n /** The CDN base URL used for probing (e.g. https://esm.sh). */\n cdnBaseUrl: string;\n /** Version that was probed (usually the upstream package.json version). */\n version: string;\n /** Whether the package entrypoint URL resolved (HTTP 200). */\n entryOk: boolean;\n /** Whether the controller URL resolved (HTTP 200). */\n controllerOk: boolean;\n /** Whether the returned JS for the entry parsed as an ES module. */\n entryParseOk: boolean;\n /** Whether the returned JS for the controller parsed as an ES module. */\n controllerParseOk: boolean;\n /** Any errors/warnings collected during probe. */\n errors: string[];\n\n /**\n * Probe details (for deep/transitive validation)\n */\n probeMode?: 'shallow' | 'deep';\n maxDepth?: number;\n maxModules?: number;\n fetchedModules?: number;\n fetchedOk?: number;\n firstFailingUrl?: string;\n}\n\n/**\n * Compatibility report structure\n */\nexport interface CompatibilityReport {\n browserEsmReady?: string[];\n browserEsmUnsupported?: Record<string, { reason: string }>;\n\n elements: string[];\n pieLibPackages: string[];\n blockedElements: Record<string, string[]>;\n elementDetails: Record<string, ElementDetail>;\n pieLibDetails: Record<string, PieLibDetail>;\n\n // ESM player validation\n esmPlayerReady: string[];\n esmValidation: Record<string, EsmValidationResult>;\n /**\n * Whether ESM player validation (package.json structure / exports) was run as part of analysis.\n * Optional for backwards compatibility with older reports.\n */\n esmPlayerValidationEnabled?: boolean;\n\n // Runtime-ish validation (CDN probes)\n esmRuntimeValidationEnabled?: boolean;\n esmRuntimeCdnBaseUrl?: string;\n esmRuntimeValidation?: Record<string, EsmRuntimeValidationResult>;\n\n // Student UI only (elements where student UI is ESM-ready but authoring isn't)\n studentUIOnly?: string[];\n\n lastAnalyzed: string;\n summary: {\n totalElements: number;\n compatibleElements: number;\n blockedElements: number;\n studentUIOnlyElements?: number;\n esmPlayerReady: number;\n esmRuntimeReady?: number;\n totalPieLibPackages: number;\n compatiblePieLibPackages: number;\n };\n}\n\nexport interface StaticBrowserEsmReport {\n browserEsmReady: string[];\n browserEsmUnsupported: Record<string, { reason: string }>;\n}\n\nexport interface ElementDetail {\n compatible: boolean;\n directDeps: string[];\n pieLibDeps: string[];\n pieElementDeps: string[];\n blockers: string[];\n\n // Separate analysis for student UI vs authoring\n studentUI?: {\n compatible: boolean;\n blockers: string[];\n };\n configure?: {\n compatible: boolean;\n blockers: string[];\n };\n controller?: {\n compatible: boolean;\n blockers: string[];\n };\n}\n\nexport interface PieLibDetail {\n compatible: boolean;\n usedBy: string[];\n blockers: string[];\n}\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return typeof value === 'object' && value !== null && !Array.isArray(value);\n}\n\nfunction stringArray(value: unknown): string[] {\n return Array.isArray(value)\n ? value.filter((item): item is string => typeof item === 'string')\n : [];\n}\n\nfunction hasBrowserExport(exportsMap: unknown, key: string): boolean {\n if (!isRecord(exportsMap)) return false;\n const value = exportsMap[key];\n if (typeof value === 'string') return value.length > 0;\n return isRecord(value) && typeof value.default === 'string' && value.default.length > 0;\n}\n\nexport async function deriveStaticBrowserEsmReport(\n repoRoot: string\n): Promise<StaticBrowserEsmReport> {\n const ready: string[] = [];\n const unsupported: Record<string, { reason: string }> = {};\n const packageRoots = [\n join(repoRoot, 'packages', 'elements-react'),\n join(repoRoot, 'packages', 'elements-svelte'),\n ];\n\n for (const packageRoot of packageRoots) {\n const entries = await readdir(packageRoot, { withFileTypes: true }).catch(() => []);\n for (const entry of entries) {\n if (!entry.isDirectory()) continue;\n const packageJsonPath = join(packageRoot, entry.name, 'package.json');\n if (!existsSync(packageJsonPath)) continue;\n\n const pkg = JSON.parse(await readFile(packageJsonPath, 'utf-8')) as Record<string, unknown>;\n if (\n pkg.private === true ||\n typeof pkg.name !== 'string' ||\n !pkg.name.startsWith('@pie-element/')\n ) {\n continue;\n }\n\n const missing = ['./browser/delivery', './browser/controller'].filter(\n (key) => !hasBrowserExport(pkg.exports, key)\n );\n if (missing.length === 0) {\n ready.push(entry.name);\n } else {\n unsupported[entry.name] = {\n reason: `Missing browser ESM exports: ${missing.join(', ')}`,\n };\n }\n }\n }\n\n return {\n browserEsmReady: ready.sort(),\n browserEsmUnsupported: Object.fromEntries(Object.entries(unsupported).sort()),\n };\n}\n\nfunction blockedReason(value: unknown): string[] {\n if (typeof value === 'string') {\n return [value];\n }\n if (Array.isArray(value)) {\n const reasons = stringArray(value);\n return reasons.length > 0 ? reasons : ['Unsupported by static browser ESM report'];\n }\n if (isRecord(value) && typeof value.reason === 'string') {\n return [value.reason];\n }\n return ['Unsupported by static browser ESM report'];\n}\n\nfunction normalizeStaticBrowserEsmReport(report: Record<string, unknown>): CompatibilityReport {\n const elements = stringArray(report.browserEsmReady);\n const unsupported = isRecord(report.browserEsmUnsupported) ? report.browserEsmUnsupported : {};\n const blockedElements = Object.fromEntries(\n Object.entries(unsupported).map(([element, details]) => [element, blockedReason(details)])\n );\n const elementDetails: Record<string, ElementDetail> = {};\n\n for (const element of elements) {\n elementDetails[element] = {\n compatible: true,\n directDeps: [],\n pieLibDeps: [],\n pieElementDeps: [],\n blockers: [],\n studentUI: { compatible: true, blockers: [] },\n configure: { compatible: true, blockers: [] },\n controller: { compatible: true, blockers: [] },\n };\n }\n\n for (const [element, blockers] of Object.entries(blockedElements)) {\n elementDetails[element] = {\n compatible: false,\n directDeps: [],\n pieLibDeps: [],\n pieElementDeps: [],\n blockers,\n studentUI: { compatible: false, blockers },\n configure: { compatible: false, blockers },\n controller: { compatible: false, blockers },\n };\n }\n\n return {\n ...report,\n elements,\n pieLibPackages: [],\n blockedElements,\n elementDetails,\n pieLibDetails: {},\n esmPlayerReady: elements,\n esmValidation: {},\n lastAnalyzed: typeof report.lastAnalyzed === 'string' ? report.lastAnalyzed : 'unknown',\n summary: {\n totalElements: elements.length + Object.keys(blockedElements).length,\n compatibleElements: elements.length,\n blockedElements: Object.keys(blockedElements).length,\n esmPlayerReady: elements.length,\n totalPieLibPackages: 0,\n compatiblePieLibPackages: 0,\n },\n };\n}\n\nfunction normalizeCompatibilityReport(report: unknown): CompatibilityReport {\n if (\n isRecord(report) &&\n Array.isArray(report.browserEsmReady) &&\n !Array.isArray(report.elements)\n ) {\n return normalizeStaticBrowserEsmReport(report);\n }\n\n return report as CompatibilityReport;\n}\n\nexport function formatCompatibilityReportLastAnalyzed(report: CompatibilityReport): string {\n const timestamp = report.lastAnalyzed;\n if (!timestamp || timestamp === 'unknown') {\n return 'unknown';\n }\n\n const analyzedAt = new Date(timestamp);\n return Number.isNaN(analyzedAt.getTime()) ? 'unknown' : analyzedAt.toLocaleString();\n}\n\nexport function createTrackedCompatibilityReport(report: CompatibilityReport): CompatibilityReport {\n const { esmRuntimeValidation, esmRuntimeValidationEnabled, esmRuntimeCdnBaseUrl, ...tracked } =\n report;\n const { esmRuntimeReady, ...summary } = report.summary;\n\n return {\n ...tracked,\n lastAnalyzed: 'unknown',\n summary,\n };\n}\n\nexport async function loadCompatibilityReport(path: string): Promise<CompatibilityReport> {\n if (!existsSync(path)) {\n throw new Error(`Compatibility report not found at: ${path}`);\n }\n\n const content = await readFile(path, 'utf-8');\n return normalizeCompatibilityReport(JSON.parse(content) as unknown);\n}\n\nexport function isElementCompatible(element: string, report: CompatibilityReport): boolean {\n return report.elements.includes(element);\n}\n\nexport function isPieLibPackageCompatible(pkg: string, report: CompatibilityReport): boolean {\n return report.pieLibPackages.includes(pkg);\n}\n\nexport function getElementBlockers(element: string, report: CompatibilityReport): string[] {\n return report.blockedElements[element] || [];\n}\n\n/**\n * Check if an element is ESM player ready (no CommonJS deps + proper ESM package structure)\n */\nexport function isElementEsmPlayerReady(element: string, report: CompatibilityReport): boolean {\n return report.esmPlayerReady.includes(element);\n}\n\n/**\n * Check if an element has student UI ready (even if configure/controller aren't)\n */\nexport function isElementStudentUIReady(element: string, report: CompatibilityReport): boolean {\n const detail = report.elementDetails[element];\n if (!detail) return false;\n\n // If fully compatible, student UI is ready\n if (detail.compatible) return true;\n\n // Check if student UI is explicitly marked as compatible\n return detail.studentUI?.compatible === true;\n}\n\n/**\n * Get ESM validation details for an element\n */\nexport function getEsmValidation(\n element: string,\n report: CompatibilityReport\n): EsmValidationResult | null {\n return report.esmValidation[element] || null;\n}\n"]}
1
+ {"version":3,"file":"compatibility.js","sourceRoot":"","sources":["../../src/utils/compatibility.ts"],"names":[],"mappings":"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","sourcesContent":["import { readFile, readdir } from 'node:fs/promises';\nimport { existsSync } from 'node:fs';\nimport { join } from 'node:path';\n\n/**\n * ESM package.json validation result\n */\nexport interface EsmPackageValidation {\n hasTypeModule: boolean;\n hasExportsField: boolean;\n hasMainExport: boolean;\n hasControllerExport: boolean;\n sideEffectsFree: boolean;\n mainExportIsEsm: boolean;\n controllerExportIsEsm: boolean;\n}\n\n/**\n * ESM player validation result for an element\n */\nexport interface EsmValidationResult {\n compatible: boolean;\n packageJson: EsmPackageValidation;\n blockers: string[];\n warnings: string[];\n}\n\n/**\n * Runtime-ish validation for ESM player readiness (CDN resolution / module parse).\n * Note: this is NOT a full browser execution test, but it provides production-like signal\n * by verifying CDN URLs resolve and the returned JS parses as an ES module.\n */\nexport interface EsmRuntimeValidationResult {\n /**\n * Whether this element passed the runtime-ish probe.\n * When false, see `errors` for details.\n */\n compatible: boolean;\n /** The CDN base URL used for probing (e.g. https://esm.sh). */\n cdnBaseUrl: string;\n /** Version that was probed (usually the upstream package.json version). */\n version: string;\n /** Whether the package entrypoint URL resolved (HTTP 200). */\n entryOk: boolean;\n /** Whether the controller URL resolved (HTTP 200). */\n controllerOk: boolean;\n /** Whether the returned JS for the entry parsed as an ES module. */\n entryParseOk: boolean;\n /** Whether the returned JS for the controller parsed as an ES module. */\n controllerParseOk: boolean;\n /** Any errors/warnings collected during probe. */\n errors: string[];\n\n /**\n * Probe details (for deep/transitive validation)\n */\n probeMode?: 'shallow' | 'deep';\n maxDepth?: number;\n maxModules?: number;\n fetchedModules?: number;\n fetchedOk?: number;\n firstFailingUrl?: string;\n}\n\n/**\n * Compatibility report structure\n */\nexport interface CompatibilityReport {\n browserEsmReady?: string[];\n browserEsmUnsupported?: Record<string, { reason: string }>;\n\n elements: string[];\n pieLibPackages: string[];\n blockedElements: Record<string, string[]>;\n elementDetails: Record<string, ElementDetail>;\n pieLibDetails: Record<string, PieLibDetail>;\n\n // ESM player validation\n esmPlayerReady: string[];\n esmValidation: Record<string, EsmValidationResult>;\n /**\n * Whether ESM player validation (package.json structure / exports) was run as part of analysis.\n * Optional for backwards compatibility with older reports.\n */\n esmPlayerValidationEnabled?: boolean;\n\n // Runtime-ish validation (CDN probes)\n esmRuntimeValidationEnabled?: boolean;\n esmRuntimeCdnBaseUrl?: string;\n esmRuntimeValidation?: Record<string, EsmRuntimeValidationResult>;\n\n // Student UI only (elements where student UI is ESM-ready but authoring isn't)\n studentUIOnly?: string[];\n\n lastAnalyzed: string;\n summary: {\n totalElements: number;\n compatibleElements: number;\n blockedElements: number;\n studentUIOnlyElements?: number;\n esmPlayerReady: number;\n esmRuntimeReady?: number;\n totalPieLibPackages: number;\n compatiblePieLibPackages: number;\n };\n}\n\nexport interface StaticBrowserEsmReport {\n browserEsmReady: string[];\n browserEsmUnsupported: Record<string, { reason: string }>;\n}\n\nexport interface ElementDetail {\n compatible: boolean;\n directDeps: string[];\n pieLibDeps: string[];\n pieElementDeps: string[];\n blockers: string[];\n\n // Separate analysis for student UI vs authoring\n studentUI?: {\n compatible: boolean;\n blockers: string[];\n };\n configure?: {\n compatible: boolean;\n blockers: string[];\n };\n controller?: {\n compatible: boolean;\n blockers: string[];\n };\n}\n\nexport interface PieLibDetail {\n compatible: boolean;\n usedBy: string[];\n blockers: string[];\n}\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return typeof value === 'object' && value !== null && !Array.isArray(value);\n}\n\nfunction stringArray(value: unknown): string[] {\n return Array.isArray(value)\n ? value.filter((item): item is string => typeof item === 'string')\n : [];\n}\n\nfunction hasBrowserExport(exportsMap: unknown, key: string): boolean {\n if (!isRecord(exportsMap)) return false;\n const value = exportsMap[key];\n if (typeof value === 'string') return value.length > 0;\n return isRecord(value) && typeof value.default === 'string' && value.default.length > 0;\n}\n\nexport async function deriveStaticBrowserEsmReport(\n repoRoot: string\n): Promise<StaticBrowserEsmReport> {\n const ready: string[] = [];\n const unsupported: Record<string, { reason: string }> = {};\n const packageRoots = [\n join(repoRoot, 'packages', 'elements-react'),\n join(repoRoot, 'packages', 'elements-svelte'),\n ];\n\n for (const packageRoot of packageRoots) {\n const entries = await readdir(packageRoot, { withFileTypes: true }).catch(() => []);\n for (const entry of entries) {\n if (!entry.isDirectory()) continue;\n const packageJsonPath = join(packageRoot, entry.name, 'package.json');\n if (!existsSync(packageJsonPath)) continue;\n\n const pkg = JSON.parse(await readFile(packageJsonPath, 'utf-8')) as Record<string, unknown>;\n if (\n pkg.private === true ||\n typeof pkg.name !== 'string' ||\n !pkg.name.startsWith('@pie-element/')\n ) {\n continue;\n }\n\n const missing = ['./browser/delivery', './browser/controller'].filter(\n (key) => !hasBrowserExport(pkg.exports, key)\n );\n if (missing.length === 0) {\n ready.push(entry.name);\n } else {\n unsupported[entry.name] = {\n reason: `Missing browser ESM exports: ${missing.join(', ')}`,\n };\n }\n }\n }\n\n return {\n browserEsmReady: ready.sort(),\n browserEsmUnsupported: Object.fromEntries(Object.entries(unsupported).sort()),\n };\n}\n\nfunction blockedReason(value: unknown): string[] {\n if (typeof value === 'string') {\n return [value];\n }\n if (Array.isArray(value)) {\n const reasons = stringArray(value);\n return reasons.length > 0 ? reasons : ['Unsupported by static browser ESM report'];\n }\n if (isRecord(value) && typeof value.reason === 'string') {\n return [value.reason];\n }\n return ['Unsupported by static browser ESM report'];\n}\n\nfunction normalizeStaticBrowserEsmReport(report: Record<string, unknown>): CompatibilityReport {\n const elements = stringArray(report.browserEsmReady);\n const unsupported = isRecord(report.browserEsmUnsupported) ? report.browserEsmUnsupported : {};\n const blockedElements = Object.fromEntries(\n Object.entries(unsupported).map(([element, details]) => [element, blockedReason(details)])\n );\n const elementDetails: Record<string, ElementDetail> = {};\n\n for (const element of elements) {\n elementDetails[element] = {\n compatible: true,\n directDeps: [],\n pieLibDeps: [],\n pieElementDeps: [],\n blockers: [],\n studentUI: { compatible: true, blockers: [] },\n configure: { compatible: true, blockers: [] },\n controller: { compatible: true, blockers: [] },\n };\n }\n\n for (const [element, blockers] of Object.entries(blockedElements)) {\n elementDetails[element] = {\n compatible: false,\n directDeps: [],\n pieLibDeps: [],\n pieElementDeps: [],\n blockers,\n studentUI: { compatible: false, blockers },\n configure: { compatible: false, blockers },\n controller: { compatible: false, blockers },\n };\n }\n\n return {\n ...report,\n elements,\n pieLibPackages: [],\n blockedElements,\n elementDetails,\n pieLibDetails: {},\n esmPlayerReady: elements,\n esmValidation: {},\n lastAnalyzed: typeof report.lastAnalyzed === 'string' ? report.lastAnalyzed : 'unknown',\n summary: {\n totalElements: elements.length + Object.keys(blockedElements).length,\n compatibleElements: elements.length,\n blockedElements: Object.keys(blockedElements).length,\n esmPlayerReady: elements.length,\n totalPieLibPackages: 0,\n compatiblePieLibPackages: 0,\n },\n };\n}\n\nfunction normalizeCompatibilityReport(report: unknown): CompatibilityReport {\n if (\n isRecord(report) &&\n Array.isArray(report.browserEsmReady) &&\n !Array.isArray(report.elements)\n ) {\n return normalizeStaticBrowserEsmReport(report);\n }\n\n return report as CompatibilityReport;\n}\n\nexport function formatCompatibilityReportLastAnalyzed(report: CompatibilityReport): string {\n const timestamp = report.lastAnalyzed;\n if (!timestamp || timestamp === 'unknown') {\n return 'unknown';\n }\n\n const analyzedAt = new Date(timestamp);\n return Number.isNaN(analyzedAt.getTime()) ? 'unknown' : analyzedAt.toLocaleString();\n}\n\nexport function createTrackedCompatibilityReport(report: CompatibilityReport): CompatibilityReport {\n const { esmRuntimeValidation, esmRuntimeValidationEnabled, esmRuntimeCdnBaseUrl, ...tracked } =\n report;\n const { esmRuntimeReady, ...summary } = report.summary;\n\n return {\n ...tracked,\n lastAnalyzed: 'unknown',\n summary,\n };\n}\n\nexport async function loadCompatibilityReport(path: string): Promise<CompatibilityReport> {\n if (!existsSync(path)) {\n throw new Error(`Compatibility report not found at: ${path}`);\n }\n\n const content = await readFile(path, 'utf-8');\n return normalizeCompatibilityReport(JSON.parse(content) as unknown);\n}\n"]}
@@ -17,8 +17,3 @@ export declare function convertJsToTs(jsCode: string, metadata: ConversionMetada
17
17
  * Convert JSX to TSX
18
18
  */
19
19
  export declare function convertJsxToTsx(jsxCode: string, metadata: ConversionMetadata): ConversionResult;
20
- /**
21
- * Fix imports from default export files
22
- * Some files export default objects but are imported with named imports
23
- */
24
- export declare function fixImports(content: string, hasDefaultObjectExport: boolean): string;
@@ -99,25 +99,4 @@ export function convertJsxToTsx(jsxCode, metadata) {
99
99
  `;
100
100
  return { code: tsNoCheck + header + tsxCode, hasDefaultObjectExport };
101
101
  }
102
- /**
103
- * Fix imports from default export files
104
- * Some files export default objects but are imported with named imports
105
- */
106
- export function fixImports(content, hasDefaultObjectExport) {
107
- if (!hasDefaultObjectExport) {
108
- return content;
109
- }
110
- // Convert: import { something } from './file'
111
- // To: import * as file from './file'
112
- // This is needed when the imported file has export default {}
113
- return content.replace(/import\s+{\s*([^}]+)\s*}\s+from\s+(['"]\.\/[^'"]+['"])/g, (_match, _imports, path) => {
114
- // Extract filename from path
115
- const filename = path
116
- .replace(/['"]/g, '')
117
- .split('/')
118
- .pop()
119
- ?.replace(/\.\w+$/, '') || 'module';
120
- return `import * as ${filename} from ${path}`;
121
- });
122
- }
123
102
  //# sourceMappingURL=conversion.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"conversion.js","sourceRoot":"","sources":["../../src/utils/conversion.ts"],"names":[],"mappings":"AAAA;;GAEG;AAYH;;GAEG;AACH,MAAM,UAAU,aAAa,CAAC,MAAc,EAAE,QAA4B;IACxE,2DAA2D;IAC3D,4FAA4F;IAC5F,0DAA0D;IAC1D,IAAI,MAAM,GAAG,MAAM,CAAC;IACpB,MAAM,sBAAsB,GAAG,KAAK,CAAC;IAErC,gDAAgD;IAChD,MAAM,GAAG,yBAAyB,CAAC,MAAM,CAAC,CAAC;IAE3C,mFAAmF;IACnF,wEAAwE;IACxE,MAAM,SAAS,GAAG,kBAAkB,CAAC;IAErC,2BAA2B;IAC3B,MAAM,MAAM,GAAG;kBACC,QAAQ,CAAC,UAAU;;;;;;;;CAQpC,CAAC;IACA,OAAO,EAAE,IAAI,EAAE,SAAS,GAAG,MAAM,GAAG,MAAM,EAAE,sBAAsB,EAAE,CAAC;AACvE,CAAC;AAED;;GAEG;AACH,SAAS,yBAAyB,CAAC,OAAe;IAChD,6DAA6D;IAC7D,MAAM,oBAAoB,GAAG,wCAAwC,CAAC;IACtE,MAAM,KAAK,GAAG,OAAO,CAAC,KAAK,CAAC,oBAAoB,CAAC,CAAC;IAElD,IAAI,CAAC,KAAK,EAAE,CAAC;QACX,OAAO,OAAO,CAAC;IACjB,CAAC;IAED,MAAM,CAAC,SAAS,EAAE,aAAa,CAAC,GAAG,KAAK,CAAC;IAEzC,gDAAgD;IAChD,MAAM,OAAO,GAAa,EAAE,CAAC;IAC7B,MAAM,KAAK,GAAG,aAAa,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;IAExC,IAAI,UAAU,GAAkB,IAAI,CAAC;IACrC,IAAI,YAAY,GAAa,EAAE,CAAC;IAEhC,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;QACzB,MAAM,OAAO,GAAG,IAAI,CAAC,IAAI,EAAE,CAAC;QAC5B,IAAI,CAAC,OAAO,IAAI,OAAO,KAAK,GAAG,IAAI,OAAO,KAAK,GAAG;YAAE,SAAS;QAE7D,sCAAsC;QACtC,MAAM,QAAQ,GAAG,OAAO,CAAC,KAAK,CAAC,gBAAgB,CAAC,CAAC;QACjD,IAAI,QAAQ,EAAE,CAAC;YACb,8BAA8B;YAC9B,IAAI,UAAU,EAAE,CAAC;gBACf,MAAM,KAAK,GAAG,YAAY,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,OAAO,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC,CAAC,wBAAwB;gBACpF,OAAO,CAAC,IAAI,CAAC,gBAAgB,UAAU,OAAO,KAAK,GAAG,CAAC,CAAC;YAC1D,CAAC;YAED,mBAAmB;YACnB,UAAU,GAAG,QAAQ,CAAC,CAAC,CAAC,CAAC;YACzB,YAAY,GAAG,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC;QAC/B,CAAC;aAAM,CAAC;YACN,gCAAgC;YAChC,YAAY,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QAC1B,CAAC;IACH,CAAC;IAED,mBAAmB;IACnB,IAAI,UAAU,EAAE,CAAC;QACf,MAAM,KAAK,GAAG,YAAY,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,OAAO,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC;QAC3D,OAAO,CAAC,IAAI,CAAC,gBAAgB,UAAU,OAAO,KAAK,GAAG,CAAC,CAAC;IAC1D,CAAC;IAED,0DAA0D;IAC1D,MAAM,UAAU,GAAG,OAAO,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;IACxC,OAAO,OAAO,CAAC,OAAO,CAAC,SAAS,EAAE,UAAU,CAAC,CAAC;AAChD,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,eAAe,CAAC,OAAe,EAAE,QAA4B;IAC3E,+DAA+D;IAC/D,4FAA4F;IAC5F,0DAA0D;IAC1D,MAAM,OAAO,GAAG,OAAO,CAAC;IACxB,MAAM,sBAAsB,GAAG,KAAK,CAAC;IAErC,mFAAmF;IACnF,yEAAyE;IACzE,MAAM,SAAS,GAAG,kBAAkB,CAAC;IAErC,2BAA2B;IAC3B,MAAM,MAAM,GAAG;kBACC,QAAQ,CAAC,UAAU;;;;;;;;CAQpC,CAAC;IACA,OAAO,EAAE,IAAI,EAAE,SAAS,GAAG,MAAM,GAAG,OAAO,EAAE,sBAAsB,EAAE,CAAC;AACxE,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,UAAU,CAAC,OAAe,EAAE,sBAA+B;IACzE,IAAI,CAAC,sBAAsB,EAAE,CAAC;QAC5B,OAAO,OAAO,CAAC;IACjB,CAAC;IAED,8CAA8C;IAC9C,qCAAqC;IACrC,8DAA8D;IAC9D,OAAO,OAAO,CAAC,OAAO,CACpB,yDAAyD,EACzD,CAAC,MAAM,EAAE,QAAQ,EAAE,IAAI,EAAE,EAAE;QACzB,6BAA6B;QAC7B,MAAM,QAAQ,GACZ,IAAI;aACD,OAAO,CAAC,OAAO,EAAE,EAAE,CAAC;aACpB,KAAK,CAAC,GAAG,CAAC;aACV,GAAG,EAAE;YACN,EAAE,OAAO,CAAC,QAAQ,EAAE,EAAE,CAAC,IAAI,QAAQ,CAAC;QACxC,OAAO,eAAe,QAAQ,SAAS,IAAI,EAAE,CAAC;IAChD,CAAC,CACF,CAAC;AACJ,CAAC","sourcesContent":["/**\n * JavaScript to TypeScript conversion utilities\n */\n\nexport interface ConversionMetadata {\n sourcePath: string;\n commit: string;\n}\n\nexport interface ConversionResult {\n code: string;\n hasDefaultObjectExport: boolean;\n}\n\n/**\n * Convert JavaScript to TypeScript\n */\nexport function convertJsToTs(jsCode: string, metadata: ConversionMetadata): ConversionResult {\n // We intentionally do NOT transform the JavaScript syntax.\n // Goal: keep upstream source as-is, while letting the monorepo's TS/Vite pipeline build it.\n // TypeScript diagnostics are suppressed for synced files.\n let tsCode = jsCode;\n const hasDefaultObjectExport = false;\n\n // Convert CommonJS module.exports to ES modules\n tsCode = convertModuleExportsToEsm(tsCode);\n\n // Must be at the very top of the file to reliably suppress TypeScript diagnostics.\n // We keep synced files buildable even when upstream JS has type issues.\n const tsNoCheck = `// @ts-nocheck\\n`;\n\n // Add sync metadata header\n const header = `/**\n * @synced-from ${metadata.sourcePath}\n * @auto-generated\n *\n * This file is automatically synced from pie-elements and converted to TypeScript.\n * Manual edits will be overwritten on next sync.\n * To make changes, edit the upstream JavaScript file and run sync again.\n */\n\n`;\n return { code: tsNoCheck + header + tsCode, hasDefaultObjectExport };\n}\n\n/**\n * Convert CommonJS module.exports to ES module exports\n */\nfunction convertModuleExportsToEsm(content: string): string {\n // Match: module.exports = { key: value, key2: value2, ... };\n const moduleExportsPattern = /module\\.exports\\s*=\\s*\\{([\\s\\S]*?)\\};?/;\n const match = content.match(moduleExportsPattern);\n\n if (!match) {\n return content;\n }\n\n const [fullMatch, objectContent] = match;\n\n // Parse the object content into key-value pairs\n const exports: string[] = [];\n const lines = objectContent.split('\\n');\n\n let currentKey: string | null = null;\n let currentValue: string[] = [];\n\n for (const line of lines) {\n const trimmed = line.trim();\n if (!trimmed || trimmed === '{' || trimmed === '}') continue;\n\n // Check if this line starts a new key\n const keyMatch = trimmed.match(/^(\\w+):\\s*(.*)/);\n if (keyMatch) {\n // Save previous export if any\n if (currentKey) {\n const value = currentValue.join('\\n').replace(/,\\s*$/, ''); // Remove trailing comma\n exports.push(`export const ${currentKey} =\\n${value};`);\n }\n\n // Start new export\n currentKey = keyMatch[1];\n currentValue = [keyMatch[2]];\n } else {\n // Continuation of current value\n currentValue.push(line);\n }\n }\n\n // Save last export\n if (currentKey) {\n const value = currentValue.join('\\n').replace(/,\\s*$/, '');\n exports.push(`export const ${currentKey} =\\n${value};`);\n }\n\n // Replace the module.exports block with ES module exports\n const esmExports = exports.join('\\n\\n');\n return content.replace(fullMatch, esmExports);\n}\n\n/**\n * Convert JSX to TSX\n */\nexport function convertJsxToTsx(jsxCode: string, metadata: ConversionMetadata): ConversionResult {\n // We intentionally do NOT transform the JavaScript/JSX syntax.\n // Goal: keep upstream source as-is, while letting the monorepo's TS/Vite pipeline build it.\n // TypeScript diagnostics are suppressed for synced files.\n const tsxCode = jsxCode;\n const hasDefaultObjectExport = false;\n\n // Must be at the very top of the file to reliably suppress TypeScript diagnostics.\n // We keep synced files buildable even when upstream JSX has type issues.\n const tsNoCheck = `// @ts-nocheck\\n`;\n\n // Add sync metadata header\n const header = `/**\n * @synced-from ${metadata.sourcePath}\n * @auto-generated\n *\n * This file is automatically synced from pie-elements and converted to TypeScript.\n * Manual edits will be overwritten on next sync.\n * To make changes, edit the upstream JavaScript file and run sync again.\n */\n\n`;\n return { code: tsNoCheck + header + tsxCode, hasDefaultObjectExport };\n}\n\n/**\n * Fix imports from default export files\n * Some files export default objects but are imported with named imports\n */\nexport function fixImports(content: string, hasDefaultObjectExport: boolean): string {\n if (!hasDefaultObjectExport) {\n return content;\n }\n\n // Convert: import { something } from './file'\n // To: import * as file from './file'\n // This is needed when the imported file has export default {}\n return content.replace(\n /import\\s+{\\s*([^}]+)\\s*}\\s+from\\s+(['\"]\\.\\/[^'\"]+['\"])/g,\n (_match, _imports, path) => {\n // Extract filename from path\n const filename =\n path\n .replace(/['\"]/g, '')\n .split('/')\n .pop()\n ?.replace(/\\.\\w+$/, '') || 'module';\n return `import * as ${filename} from ${path}`;\n }\n );\n}\n"]}
1
+ {"version":3,"file":"conversion.js","sourceRoot":"","sources":["../../src/utils/conversion.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * JavaScript to TypeScript conversion utilities\n */\n\nexport interface ConversionMetadata {\n sourcePath: string;\n commit: string;\n}\n\nexport interface ConversionResult {\n code: string;\n hasDefaultObjectExport: boolean;\n}\n\n/**\n * Convert JavaScript to TypeScript\n */\nexport function convertJsToTs(jsCode: string, metadata: ConversionMetadata): ConversionResult {\n // We intentionally do NOT transform the JavaScript syntax.\n // Goal: keep upstream source as-is, while letting the monorepo's TS/Vite pipeline build it.\n // TypeScript diagnostics are suppressed for synced files.\n let tsCode = jsCode;\n const hasDefaultObjectExport = false;\n\n // Convert CommonJS module.exports to ES modules\n tsCode = convertModuleExportsToEsm(tsCode);\n\n // Must be at the very top of the file to reliably suppress TypeScript diagnostics.\n // We keep synced files buildable even when upstream JS has type issues.\n const tsNoCheck = `// @ts-nocheck\\n`;\n\n // Add sync metadata header\n const header = `/**\n * @synced-from ${metadata.sourcePath}\n * @auto-generated\n *\n * This file is automatically synced from pie-elements and converted to TypeScript.\n * Manual edits will be overwritten on next sync.\n * To make changes, edit the upstream JavaScript file and run sync again.\n */\n\n`;\n return { code: tsNoCheck + header + tsCode, hasDefaultObjectExport };\n}\n\n/**\n * Convert CommonJS module.exports to ES module exports\n */\nfunction convertModuleExportsToEsm(content: string): string {\n // Match: module.exports = { key: value, key2: value2, ... };\n const moduleExportsPattern = /module\\.exports\\s*=\\s*\\{([\\s\\S]*?)\\};?/;\n const match = content.match(moduleExportsPattern);\n\n if (!match) {\n return content;\n }\n\n const [fullMatch, objectContent] = match;\n\n // Parse the object content into key-value pairs\n const exports: string[] = [];\n const lines = objectContent.split('\\n');\n\n let currentKey: string | null = null;\n let currentValue: string[] = [];\n\n for (const line of lines) {\n const trimmed = line.trim();\n if (!trimmed || trimmed === '{' || trimmed === '}') continue;\n\n // Check if this line starts a new key\n const keyMatch = trimmed.match(/^(\\w+):\\s*(.*)/);\n if (keyMatch) {\n // Save previous export if any\n if (currentKey) {\n const value = currentValue.join('\\n').replace(/,\\s*$/, ''); // Remove trailing comma\n exports.push(`export const ${currentKey} =\\n${value};`);\n }\n\n // Start new export\n currentKey = keyMatch[1];\n currentValue = [keyMatch[2]];\n } else {\n // Continuation of current value\n currentValue.push(line);\n }\n }\n\n // Save last export\n if (currentKey) {\n const value = currentValue.join('\\n').replace(/,\\s*$/, '');\n exports.push(`export const ${currentKey} =\\n${value};`);\n }\n\n // Replace the module.exports block with ES module exports\n const esmExports = exports.join('\\n\\n');\n return content.replace(fullMatch, esmExports);\n}\n\n/**\n * Convert JSX to TSX\n */\nexport function convertJsxToTsx(jsxCode: string, metadata: ConversionMetadata): ConversionResult {\n // We intentionally do NOT transform the JavaScript/JSX syntax.\n // Goal: keep upstream source as-is, while letting the monorepo's TS/Vite pipeline build it.\n // TypeScript diagnostics are suppressed for synced files.\n const tsxCode = jsxCode;\n const hasDefaultObjectExport = false;\n\n // Must be at the very top of the file to reliably suppress TypeScript diagnostics.\n // We keep synced files buildable even when upstream JSX has type issues.\n const tsNoCheck = `// @ts-nocheck\\n`;\n\n // Add sync metadata header\n const header = `/**\n * @synced-from ${metadata.sourcePath}\n * @auto-generated\n *\n * This file is automatically synced from pie-elements and converted to TypeScript.\n * Manual edits will be overwritten on next sync.\n * To make changes, edit the upstream JavaScript file and run sync again.\n */\n\n`;\n return { code: tsNoCheck + header + tsxCode, hasDefaultObjectExport };\n}\n"]}
@@ -6,7 +6,6 @@
6
6
  */
7
7
  export declare function isolatedGitEnv(env?: NodeJS.ProcessEnv): NodeJS.ProcessEnv;
8
8
  export declare function getCurrentCommit(cwd: string): string;
9
- export declare function getCurrentCommitShort(cwd: string): string;
10
9
  export declare function getCommitsSince(since: string, cwd: string): string[];
11
10
  export declare function getFileModifiedDate(filePath: string, cwd: string): Date;
12
11
  export declare function getCommitDetails(commit: string, cwd: string): string;
package/dist/utils/git.js CHANGED
@@ -19,14 +19,6 @@ export function getCurrentCommit(cwd) {
19
19
  throw new Error(`Failed to get current commit: ${error}`);
20
20
  }
21
21
  }
22
- export function getCurrentCommitShort(cwd) {
23
- try {
24
- return git('rev-parse --short HEAD', cwd).trim();
25
- }
26
- catch (error) {
27
- throw new Error(`Failed to get short commit: ${error}`);
28
- }
29
- }
30
22
  export function getCommitsSince(since, cwd) {
31
23
  try {
32
24
  const output = git(`log ${since}..HEAD --oneline`, cwd).trim();
@@ -1 +1 @@
1
- {"version":3,"file":"git.js","sourceRoot":"","sources":["../../src/utils/git.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,oBAAoB,CAAC;AAE9C;;;;;GAKG;AACH,MAAM,UAAU,cAAc,CAAC,MAAyB,OAAO,CAAC,GAAG;IACjE,OAAO,MAAM,CAAC,WAAW,CAAC,MAAM,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,EAAE,CAAC,CAAC,GAAG,CAAC,UAAU,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC;AAC5F,CAAC;AAED,SAAS,GAAG,CAAC,OAAe,EAAE,GAAW;IACvC,OAAO,QAAQ,CAAC,OAAO,OAAO,EAAE,EAAE,EAAE,GAAG,EAAE,QAAQ,EAAE,MAAM,EAAE,GAAG,EAAE,cAAc,EAAE,EAAE,CAAC,CAAC;AACtF,CAAC;AAED,MAAM,UAAU,gBAAgB,CAAC,GAAW;IAC1C,IAAI,CAAC;QACH,OAAO,GAAG,CAAC,gBAAgB,EAAE,GAAG,CAAC,CAAC,IAAI,EAAE,CAAC;IAC3C,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,MAAM,IAAI,KAAK,CAAC,iCAAiC,KAAK,EAAE,CAAC,CAAC;IAC5D,CAAC;AACH,CAAC;AAED,MAAM,UAAU,qBAAqB,CAAC,GAAW;IAC/C,IAAI,CAAC;QACH,OAAO,GAAG,CAAC,wBAAwB,EAAE,GAAG,CAAC,CAAC,IAAI,EAAE,CAAC;IACnD,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,MAAM,IAAI,KAAK,CAAC,+BAA+B,KAAK,EAAE,CAAC,CAAC;IAC1D,CAAC;AACH,CAAC;AAED,MAAM,UAAU,eAAe,CAAC,KAAa,EAAE,GAAW;IACxD,IAAI,CAAC;QACH,MAAM,MAAM,GAAG,GAAG,CAAC,OAAO,KAAK,kBAAkB,EAAE,GAAG,CAAC,CAAC,IAAI,EAAE,CAAC;QAE/D,IAAI,CAAC,MAAM;YAAE,OAAO,EAAE,CAAC;QACvB,OAAO,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;IAC5B,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,MAAM,IAAI,KAAK,CAAC,+BAA+B,KAAK,KAAK,KAAK,EAAE,CAAC,CAAC;IACpE,CAAC;AACH,CAAC;AAED,MAAM,UAAU,mBAAmB,CAAC,QAAgB,EAAE,GAAW;IAC/D,IAAI,CAAC;QACH,MAAM,SAAS,GAAG,GAAG,CAAC,2BAA2B,QAAQ,GAAG,EAAE,GAAG,CAAC,CAAC,IAAI,EAAE,CAAC;QAE1E,OAAO,IAAI,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,SAAS,EAAE,EAAE,CAAC,GAAG,IAAI,CAAC,CAAC;IACzD,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,MAAM,IAAI,KAAK,CAAC,yCAAyC,KAAK,EAAE,CAAC,CAAC;IACpE,CAAC;AACH,CAAC;AAED,MAAM,UAAU,gBAAgB,CAAC,MAAc,EAAE,GAAW;IAC1D,IAAI,CAAC;QACH,OAAO,GAAG,CAAC,eAAe,MAAM,EAAE,EAAE,GAAG,CAAC,CAAC;IAC3C,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,MAAM,IAAI,KAAK,CAAC,iCAAiC,KAAK,EAAE,CAAC,CAAC;IAC5D,CAAC;AACH,CAAC;AAED,MAAM,UAAU,aAAa,CAAC,GAAW;IACvC,IAAI,CAAC;QACH,OAAO,GAAG,CAAC,kBAAkB,EAAE,GAAG,CAAC,CAAC,IAAI,EAAE,CAAC;IAC7C,CAAC;IAAC,OAAO,MAAM,EAAE,CAAC;QAChB,OAAO,SAAS,CAAC;IACnB,CAAC;AACH,CAAC","sourcesContent":["import { execSync } from 'node:child_process';\n\n/**\n * The environment for a git subprocess aimed at a repository through `cwd`.\n * A git hook exports `GIT_DIR`, which overrides `cwd`: from a worktree it is an\n * absolute path, so `git init` in a temp dir re-initialises the hooked\n * repository as bare and `rev-parse` reads the hooked repository's HEAD.\n */\nexport function isolatedGitEnv(env: NodeJS.ProcessEnv = process.env): NodeJS.ProcessEnv {\n return Object.fromEntries(Object.entries(env).filter(([key]) => !key.startsWith('GIT_')));\n}\n\nfunction git(command: string, cwd: string): string {\n return execSync(`git ${command}`, { cwd, encoding: 'utf8', env: isolatedGitEnv() });\n}\n\nexport function getCurrentCommit(cwd: string): string {\n try {\n return git('rev-parse HEAD', cwd).trim();\n } catch (error) {\n throw new Error(`Failed to get current commit: ${error}`);\n }\n}\n\nexport function getCurrentCommitShort(cwd: string): string {\n try {\n return git('rev-parse --short HEAD', cwd).trim();\n } catch (error) {\n throw new Error(`Failed to get short commit: ${error}`);\n }\n}\n\nexport function getCommitsSince(since: string, cwd: string): string[] {\n try {\n const output = git(`log ${since}..HEAD --oneline`, cwd).trim();\n\n if (!output) return [];\n return output.split('\\n');\n } catch (error) {\n throw new Error(`Failed to get commits since ${since}: ${error}`);\n }\n}\n\nexport function getFileModifiedDate(filePath: string, cwd: string): Date {\n try {\n const timestamp = git(`log -1 --format=%ct -- \"${filePath}\"`, cwd).trim();\n\n return new Date(Number.parseInt(timestamp, 10) * 1000);\n } catch (error) {\n throw new Error(`Failed to get file modification date: ${error}`);\n }\n}\n\nexport function getCommitDetails(commit: string, cwd: string): string {\n try {\n return git(`show --stat ${commit}`, cwd);\n } catch (error) {\n throw new Error(`Failed to get commit details: ${error}`);\n }\n}\n\nexport function getAuthorName(cwd: string): string {\n try {\n return git('config user.name', cwd).trim();\n } catch (_error) {\n return 'Unknown';\n }\n}\n"]}
1
+ {"version":3,"file":"git.js","sourceRoot":"","sources":["../../src/utils/git.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,oBAAoB,CAAC;AAE9C;;;;;GAKG;AACH,MAAM,UAAU,cAAc,CAAC,MAAyB,OAAO,CAAC,GAAG;IACjE,OAAO,MAAM,CAAC,WAAW,CAAC,MAAM,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,EAAE,CAAC,CAAC,GAAG,CAAC,UAAU,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC;AAC5F,CAAC;AAED,SAAS,GAAG,CAAC,OAAe,EAAE,GAAW;IACvC,OAAO,QAAQ,CAAC,OAAO,OAAO,EAAE,EAAE,EAAE,GAAG,EAAE,QAAQ,EAAE,MAAM,EAAE,GAAG,EAAE,cAAc,EAAE,EAAE,CAAC,CAAC;AACtF,CAAC;AAED,MAAM,UAAU,gBAAgB,CAAC,GAAW;IAC1C,IAAI,CAAC;QACH,OAAO,GAAG,CAAC,gBAAgB,EAAE,GAAG,CAAC,CAAC,IAAI,EAAE,CAAC;IAC3C,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,MAAM,IAAI,KAAK,CAAC,iCAAiC,KAAK,EAAE,CAAC,CAAC;IAC5D,CAAC;AACH,CAAC;AAED,MAAM,UAAU,eAAe,CAAC,KAAa,EAAE,GAAW;IACxD,IAAI,CAAC;QACH,MAAM,MAAM,GAAG,GAAG,CAAC,OAAO,KAAK,kBAAkB,EAAE,GAAG,CAAC,CAAC,IAAI,EAAE,CAAC;QAE/D,IAAI,CAAC,MAAM;YAAE,OAAO,EAAE,CAAC;QACvB,OAAO,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;IAC5B,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,MAAM,IAAI,KAAK,CAAC,+BAA+B,KAAK,KAAK,KAAK,EAAE,CAAC,CAAC;IACpE,CAAC;AACH,CAAC;AAED,MAAM,UAAU,mBAAmB,CAAC,QAAgB,EAAE,GAAW;IAC/D,IAAI,CAAC;QACH,MAAM,SAAS,GAAG,GAAG,CAAC,2BAA2B,QAAQ,GAAG,EAAE,GAAG,CAAC,CAAC,IAAI,EAAE,CAAC;QAE1E,OAAO,IAAI,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,SAAS,EAAE,EAAE,CAAC,GAAG,IAAI,CAAC,CAAC;IACzD,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,MAAM,IAAI,KAAK,CAAC,yCAAyC,KAAK,EAAE,CAAC,CAAC;IACpE,CAAC;AACH,CAAC;AAED,MAAM,UAAU,gBAAgB,CAAC,MAAc,EAAE,GAAW;IAC1D,IAAI,CAAC;QACH,OAAO,GAAG,CAAC,eAAe,MAAM,EAAE,EAAE,GAAG,CAAC,CAAC;IAC3C,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,MAAM,IAAI,KAAK,CAAC,iCAAiC,KAAK,EAAE,CAAC,CAAC;IAC5D,CAAC;AACH,CAAC;AAED,MAAM,UAAU,aAAa,CAAC,GAAW;IACvC,IAAI,CAAC;QACH,OAAO,GAAG,CAAC,kBAAkB,EAAE,GAAG,CAAC,CAAC,IAAI,EAAE,CAAC;IAC7C,CAAC;IAAC,OAAO,MAAM,EAAE,CAAC;QAChB,OAAO,SAAS,CAAC;IACnB,CAAC;AACH,CAAC","sourcesContent":["import { execSync } from 'node:child_process';\n\n/**\n * The environment for a git subprocess aimed at a repository through `cwd`.\n * A git hook exports `GIT_DIR`, which overrides `cwd`: from a worktree it is an\n * absolute path, so `git init` in a temp dir re-initialises the hooked\n * repository as bare and `rev-parse` reads the hooked repository's HEAD.\n */\nexport function isolatedGitEnv(env: NodeJS.ProcessEnv = process.env): NodeJS.ProcessEnv {\n return Object.fromEntries(Object.entries(env).filter(([key]) => !key.startsWith('GIT_')));\n}\n\nfunction git(command: string, cwd: string): string {\n return execSync(`git ${command}`, { cwd, encoding: 'utf8', env: isolatedGitEnv() });\n}\n\nexport function getCurrentCommit(cwd: string): string {\n try {\n return git('rev-parse HEAD', cwd).trim();\n } catch (error) {\n throw new Error(`Failed to get current commit: ${error}`);\n }\n}\n\nexport function getCommitsSince(since: string, cwd: string): string[] {\n try {\n const output = git(`log ${since}..HEAD --oneline`, cwd).trim();\n\n if (!output) return [];\n return output.split('\\n');\n } catch (error) {\n throw new Error(`Failed to get commits since ${since}: ${error}`);\n }\n}\n\nexport function getFileModifiedDate(filePath: string, cwd: string): Date {\n try {\n const timestamp = git(`log -1 --format=%ct -- \"${filePath}\"`, cwd).trim();\n\n return new Date(Number.parseInt(timestamp, 10) * 1000);\n } catch (error) {\n throw new Error(`Failed to get file modification date: ${error}`);\n }\n}\n\nexport function getCommitDetails(commit: string, cwd: string): string {\n try {\n return git(`show --stat ${commit}`, cwd);\n } catch (error) {\n throw new Error(`Failed to get commit details: ${error}`);\n }\n}\n\nexport function getAuthorName(cwd: string): string {\n try {\n return git('config user.name', cwd).trim();\n } catch (_error) {\n return 'Unknown';\n }\n}\n"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pie-element/cli",
3
- "version": "0.1.2-next.10",
3
+ "version": "0.1.2-next.13",
4
4
  "description": "CLI tools for managing PIE Elements NG",
5
5
  "type": "module",
6
6
  "bin": {
@@ -23,7 +23,7 @@
23
23
  "dependencies": {
24
24
  "@oclif/core": "^4.0.0",
25
25
  "@oclif/plugin-help": "^6.2.0",
26
- "@pie-element/element-bundler": "0.1.2-next.4",
26
+ "@pie-element/element-bundler": "0.1.2-next.5",
27
27
  "es-module-lexer": "^1.7.0",
28
28
  "glob": "^13.0.0",
29
29
  "open": "^10.0.3",