@pie-element/cli 0.1.1

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 (255) hide show
  1. package/.compatibility/report.json +2491 -0
  2. package/.turbo/turbo-build.log +1 -0
  3. package/CHANGELOG.md +8 -0
  4. package/README.md +240 -0
  5. package/REFACTORING.md +131 -0
  6. package/bin/dev.js +5 -0
  7. package/bin/run.js +5 -0
  8. package/dist/commands/dev/demo/index.d.ts +33 -0
  9. package/dist/commands/dev/demo/index.d.ts.map +1 -0
  10. package/dist/commands/dev/demo/index.js +274 -0
  11. package/dist/commands/dev/demo/index.js.map +1 -0
  12. package/dist/commands/dev/test-bundler.d.ts +18 -0
  13. package/dist/commands/dev/test-bundler.d.ts.map +1 -0
  14. package/dist/commands/dev/test-bundler.js +284 -0
  15. package/dist/commands/dev/test-bundler.js.map +1 -0
  16. package/dist/commands/mathquill/migrate.d.ts +20 -0
  17. package/dist/commands/mathquill/migrate.d.ts.map +1 -0
  18. package/dist/commands/mathquill/migrate.js +240 -0
  19. package/dist/commands/mathquill/migrate.js.map +1 -0
  20. package/dist/commands/mathquill/status.d.ts +20 -0
  21. package/dist/commands/mathquill/status.d.ts.map +1 -0
  22. package/dist/commands/mathquill/status.js +231 -0
  23. package/dist/commands/mathquill/status.js.map +1 -0
  24. package/dist/commands/packages/create-controllers.d.ts +13 -0
  25. package/dist/commands/packages/create-controllers.d.ts.map +1 -0
  26. package/dist/commands/packages/create-controllers.js +103 -0
  27. package/dist/commands/packages/create-controllers.js.map +1 -0
  28. package/dist/commands/packages/create-lib-react.d.ts +17 -0
  29. package/dist/commands/packages/create-lib-react.d.ts.map +1 -0
  30. package/dist/commands/packages/create-lib-react.js +228 -0
  31. package/dist/commands/packages/create-lib-react.js.map +1 -0
  32. package/dist/commands/packages/create-react-elements.d.ts +16 -0
  33. package/dist/commands/packages/create-react-elements.d.ts.map +1 -0
  34. package/dist/commands/packages/create-react-elements.js +259 -0
  35. package/dist/commands/packages/create-react-elements.js.map +1 -0
  36. package/dist/commands/packages/enable-publishing.d.ts +11 -0
  37. package/dist/commands/packages/enable-publishing.d.ts.map +1 -0
  38. package/dist/commands/packages/enable-publishing.js +117 -0
  39. package/dist/commands/packages/enable-publishing.js.map +1 -0
  40. package/dist/commands/packages/init-synced-elements.d.ts +16 -0
  41. package/dist/commands/packages/init-synced-elements.d.ts.map +1 -0
  42. package/dist/commands/packages/init-synced-elements.js +204 -0
  43. package/dist/commands/packages/init-synced-elements.js.map +1 -0
  44. package/dist/commands/upstream/analyze-esm.d.ts +59 -0
  45. package/dist/commands/upstream/analyze-esm.d.ts.map +1 -0
  46. package/dist/commands/upstream/analyze-esm.js +1481 -0
  47. package/dist/commands/upstream/analyze-esm.js.map +1 -0
  48. package/dist/commands/upstream/check.d.ts +15 -0
  49. package/dist/commands/upstream/check.d.ts.map +1 -0
  50. package/dist/commands/upstream/check.js +165 -0
  51. package/dist/commands/upstream/check.js.map +1 -0
  52. package/dist/commands/upstream/deps.d.ts +15 -0
  53. package/dist/commands/upstream/deps.d.ts.map +1 -0
  54. package/dist/commands/upstream/deps.js +174 -0
  55. package/dist/commands/upstream/deps.js.map +1 -0
  56. package/dist/commands/upstream/sync-mathquill.d.ts +12 -0
  57. package/dist/commands/upstream/sync-mathquill.d.ts.map +1 -0
  58. package/dist/commands/upstream/sync-mathquill.js +97 -0
  59. package/dist/commands/upstream/sync-mathquill.js.map +1 -0
  60. package/dist/commands/upstream/sync.d.ts +25 -0
  61. package/dist/commands/upstream/sync.d.ts.map +1 -0
  62. package/dist/commands/upstream/sync.js +552 -0
  63. package/dist/commands/upstream/sync.js.map +1 -0
  64. package/dist/commands/upstream/track.d.ts +15 -0
  65. package/dist/commands/upstream/track.d.ts.map +1 -0
  66. package/dist/commands/upstream/track.js +115 -0
  67. package/dist/commands/upstream/track.js.map +1 -0
  68. package/dist/commands/upstream/update.d.ts +15 -0
  69. package/dist/commands/upstream/update.d.ts.map +1 -0
  70. package/dist/commands/upstream/update.js +98 -0
  71. package/dist/commands/upstream/update.js.map +1 -0
  72. package/dist/commands/verify/controllers.d.ts +12 -0
  73. package/dist/commands/verify/controllers.d.ts.map +1 -0
  74. package/dist/commands/verify/controllers.js +138 -0
  75. package/dist/commands/verify/controllers.js.map +1 -0
  76. package/dist/commands/verify/react-build.d.ts +13 -0
  77. package/dist/commands/verify/react-build.d.ts.map +1 -0
  78. package/dist/commands/verify/react-build.js +135 -0
  79. package/dist/commands/verify/react-build.js.map +1 -0
  80. package/dist/index.d.ts +2 -0
  81. package/dist/index.d.ts.map +1 -0
  82. package/dist/index.js +2 -0
  83. package/dist/index.js.map +1 -0
  84. package/dist/lib/mathquill/extension-generator.d.ts +9 -0
  85. package/dist/lib/mathquill/extension-generator.d.ts.map +1 -0
  86. package/dist/lib/mathquill/extension-generator.js +107 -0
  87. package/dist/lib/mathquill/extension-generator.js.map +1 -0
  88. package/dist/lib/mathquill/khan-extractor.d.ts +16 -0
  89. package/dist/lib/mathquill/khan-extractor.d.ts.map +1 -0
  90. package/dist/lib/mathquill/khan-extractor.js +148 -0
  91. package/dist/lib/mathquill/khan-extractor.js.map +1 -0
  92. package/dist/lib/mathquill/learnosity-extractor.d.ts +15 -0
  93. package/dist/lib/mathquill/learnosity-extractor.d.ts.map +1 -0
  94. package/dist/lib/mathquill/learnosity-extractor.js +170 -0
  95. package/dist/lib/mathquill/learnosity-extractor.js.map +1 -0
  96. package/dist/lib/mathquill/migration-orchestrator.d.ts +77 -0
  97. package/dist/lib/mathquill/migration-orchestrator.d.ts.map +1 -0
  98. package/dist/lib/mathquill/migration-orchestrator.js +391 -0
  99. package/dist/lib/mathquill/migration-orchestrator.js.map +1 -0
  100. package/dist/lib/mathquill/package-updater.d.ts +9 -0
  101. package/dist/lib/mathquill/package-updater.d.ts.map +1 -0
  102. package/dist/lib/mathquill/package-updater.js +103 -0
  103. package/dist/lib/mathquill/package-updater.js.map +1 -0
  104. package/dist/lib/mathquill/pie-extractor.d.ts +14 -0
  105. package/dist/lib/mathquill/pie-extractor.d.ts.map +1 -0
  106. package/dist/lib/mathquill/pie-extractor.js +167 -0
  107. package/dist/lib/mathquill/pie-extractor.js.map +1 -0
  108. package/dist/lib/upstream/repo-utils.d.ts +9 -0
  109. package/dist/lib/upstream/repo-utils.d.ts.map +1 -0
  110. package/dist/lib/upstream/repo-utils.js +10 -0
  111. package/dist/lib/upstream/repo-utils.js.map +1 -0
  112. package/dist/lib/upstream/sync-compatibility.d.ts +29 -0
  113. package/dist/lib/upstream/sync-compatibility.d.ts.map +1 -0
  114. package/dist/lib/upstream/sync-compatibility.js +70 -0
  115. package/dist/lib/upstream/sync-compatibility.js.map +1 -0
  116. package/dist/lib/upstream/sync-constants.d.ts +50 -0
  117. package/dist/lib/upstream/sync-constants.d.ts.map +1 -0
  118. package/dist/lib/upstream/sync-constants.js +66 -0
  119. package/dist/lib/upstream/sync-constants.js.map +1 -0
  120. package/dist/lib/upstream/sync-controllers-strategy.d.ts +18 -0
  121. package/dist/lib/upstream/sync-controllers-strategy.d.ts.map +1 -0
  122. package/dist/lib/upstream/sync-controllers-strategy.js +243 -0
  123. package/dist/lib/upstream/sync-controllers-strategy.js.map +1 -0
  124. package/dist/lib/upstream/sync-demo-metadata.d.ts +15 -0
  125. package/dist/lib/upstream/sync-demo-metadata.d.ts.map +1 -0
  126. package/dist/lib/upstream/sync-demo-metadata.js +165 -0
  127. package/dist/lib/upstream/sync-demo-metadata.js.map +1 -0
  128. package/dist/lib/upstream/sync-dev-exports.d.ts +13 -0
  129. package/dist/lib/upstream/sync-dev-exports.d.ts.map +1 -0
  130. package/dist/lib/upstream/sync-dev-exports.js +115 -0
  131. package/dist/lib/upstream/sync-dev-exports.js.map +1 -0
  132. package/dist/lib/upstream/sync-externals.d.ts +29 -0
  133. package/dist/lib/upstream/sync-externals.d.ts.map +1 -0
  134. package/dist/lib/upstream/sync-externals.js +164 -0
  135. package/dist/lib/upstream/sync-externals.js.map +1 -0
  136. package/dist/lib/upstream/sync-filesystem.d.ts +21 -0
  137. package/dist/lib/upstream/sync-filesystem.d.ts.map +1 -0
  138. package/dist/lib/upstream/sync-filesystem.js +64 -0
  139. package/dist/lib/upstream/sync-filesystem.js.map +1 -0
  140. package/dist/lib/upstream/sync-imports.d.ts +284 -0
  141. package/dist/lib/upstream/sync-imports.d.ts.map +1 -0
  142. package/dist/lib/upstream/sync-imports.js +816 -0
  143. package/dist/lib/upstream/sync-imports.js.map +1 -0
  144. package/dist/lib/upstream/sync-mathquill.d.ts +19 -0
  145. package/dist/lib/upstream/sync-mathquill.d.ts.map +1 -0
  146. package/dist/lib/upstream/sync-mathquill.js +160 -0
  147. package/dist/lib/upstream/sync-mathquill.js.map +1 -0
  148. package/dist/lib/upstream/sync-package-json.d.ts +28 -0
  149. package/dist/lib/upstream/sync-package-json.d.ts.map +1 -0
  150. package/dist/lib/upstream/sync-package-json.js +66 -0
  151. package/dist/lib/upstream/sync-package-json.js.map +1 -0
  152. package/dist/lib/upstream/sync-package-manager.d.ts +50 -0
  153. package/dist/lib/upstream/sync-package-manager.d.ts.map +1 -0
  154. package/dist/lib/upstream/sync-package-manager.js +570 -0
  155. package/dist/lib/upstream/sync-package-manager.js.map +1 -0
  156. package/dist/lib/upstream/sync-pielib-strategy.d.ts +26 -0
  157. package/dist/lib/upstream/sync-pielib-strategy.d.ts.map +1 -0
  158. package/dist/lib/upstream/sync-pielib-strategy.js +345 -0
  159. package/dist/lib/upstream/sync-pielib-strategy.js.map +1 -0
  160. package/dist/lib/upstream/sync-react-strategy.d.ts +54 -0
  161. package/dist/lib/upstream/sync-react-strategy.d.ts.map +1 -0
  162. package/dist/lib/upstream/sync-react-strategy.js +733 -0
  163. package/dist/lib/upstream/sync-react-strategy.js.map +1 -0
  164. package/dist/lib/upstream/sync-strategy.d.ts +49 -0
  165. package/dist/lib/upstream/sync-strategy.d.ts.map +1 -0
  166. package/dist/lib/upstream/sync-strategy.js +2 -0
  167. package/dist/lib/upstream/sync-strategy.js.map +1 -0
  168. package/dist/lib/upstream/sync-summary.d.ts +20 -0
  169. package/dist/lib/upstream/sync-summary.d.ts.map +1 -0
  170. package/dist/lib/upstream/sync-summary.js +157 -0
  171. package/dist/lib/upstream/sync-summary.js.map +1 -0
  172. package/dist/lib/upstream/sync-transforms.d.ts +60 -0
  173. package/dist/lib/upstream/sync-transforms.d.ts.map +1 -0
  174. package/dist/lib/upstream/sync-transforms.js +97 -0
  175. package/dist/lib/upstream/sync-transforms.js.map +1 -0
  176. package/dist/lib/upstream/sync-vite-config.d.ts +13 -0
  177. package/dist/lib/upstream/sync-vite-config.d.ts.map +1 -0
  178. package/dist/lib/upstream/sync-vite-config.js +231 -0
  179. package/dist/lib/upstream/sync-vite-config.js.map +1 -0
  180. package/dist/utils/compatibility.d.ts +129 -0
  181. package/dist/utils/compatibility.d.ts.map +1 -0
  182. package/dist/utils/compatibility.js +44 -0
  183. package/dist/utils/compatibility.js.map +1 -0
  184. package/dist/utils/conversion.d.ts +25 -0
  185. package/dist/utils/conversion.d.ts.map +1 -0
  186. package/dist/utils/conversion.js +123 -0
  187. package/dist/utils/conversion.js.map +1 -0
  188. package/dist/utils/git.d.ts +7 -0
  189. package/dist/utils/git.d.ts.map +1 -0
  190. package/dist/utils/git.js +63 -0
  191. package/dist/utils/git.js.map +1 -0
  192. package/dist/utils/logger.d.ts +29 -0
  193. package/dist/utils/logger.d.ts.map +1 -0
  194. package/dist/utils/logger.js +63 -0
  195. package/dist/utils/logger.js.map +1 -0
  196. package/dist/utils/package-json.d.ts +12 -0
  197. package/dist/utils/package-json.d.ts.map +1 -0
  198. package/dist/utils/package-json.js +29 -0
  199. package/dist/utils/package-json.js.map +1 -0
  200. package/package.json +59 -0
  201. package/packages/cli/bin/dev.js +5 -0
  202. package/packages/cli/bin/run.js +5 -0
  203. package/src/commands/dev/demo/index.ts +313 -0
  204. package/src/commands/dev/test-bundler.ts +345 -0
  205. package/src/commands/mathquill/migrate.ts +269 -0
  206. package/src/commands/mathquill/status.ts +267 -0
  207. package/src/commands/packages/create-controllers.ts +127 -0
  208. package/src/commands/packages/create-lib-react.ts +279 -0
  209. package/src/commands/packages/create-react-elements.ts +306 -0
  210. package/src/commands/packages/enable-publishing.ts +161 -0
  211. package/src/commands/packages/init-synced-elements.ts +259 -0
  212. package/src/commands/upstream/README.md +444 -0
  213. package/src/commands/upstream/analyze-esm.ts +1973 -0
  214. package/src/commands/upstream/check.ts +228 -0
  215. package/src/commands/upstream/deps.ts +222 -0
  216. package/src/commands/upstream/sync-mathquill.ts +108 -0
  217. package/src/commands/upstream/sync.ts +687 -0
  218. package/src/commands/upstream/track.ts +145 -0
  219. package/src/commands/upstream/update.ts +110 -0
  220. package/src/commands/verify/controllers.ts +166 -0
  221. package/src/commands/verify/react-build.ts +171 -0
  222. package/src/index.ts +1 -0
  223. package/src/lib/mathquill/extension-generator.ts +111 -0
  224. package/src/lib/mathquill/khan-extractor.ts +175 -0
  225. package/src/lib/mathquill/learnosity-extractor.ts +198 -0
  226. package/src/lib/mathquill/migration-orchestrator.ts +513 -0
  227. package/src/lib/mathquill/package-updater.ts +120 -0
  228. package/src/lib/mathquill/pie-extractor.ts +194 -0
  229. package/src/lib/upstream/repo-utils.ts +18 -0
  230. package/src/lib/upstream/sync-compatibility.ts +89 -0
  231. package/src/lib/upstream/sync-constants.ts +77 -0
  232. package/src/lib/upstream/sync-controllers-strategy.ts +291 -0
  233. package/src/lib/upstream/sync-demo-metadata.ts +199 -0
  234. package/src/lib/upstream/sync-dev-exports.ts +151 -0
  235. package/src/lib/upstream/sync-externals.ts +159 -0
  236. package/src/lib/upstream/sync-filesystem.ts +87 -0
  237. package/src/lib/upstream/sync-imports.ts +992 -0
  238. package/src/lib/upstream/sync-mathquill.ts +194 -0
  239. package/src/lib/upstream/sync-package-json.ts +86 -0
  240. package/src/lib/upstream/sync-package-manager.ts +694 -0
  241. package/src/lib/upstream/sync-pielib-strategy.ts +441 -0
  242. package/src/lib/upstream/sync-react-strategy.ts +945 -0
  243. package/src/lib/upstream/sync-strategy.ts +61 -0
  244. package/src/lib/upstream/sync-summary.ts +194 -0
  245. package/src/lib/upstream/sync-transforms.ts +154 -0
  246. package/src/lib/upstream/sync-vite-config.ts +243 -0
  247. package/src/types/es-module-lexer.d.ts +4 -0
  248. package/src/utils/compatibility.ts +182 -0
  249. package/src/utils/conversion.ts +153 -0
  250. package/src/utils/git.ts +63 -0
  251. package/src/utils/logger.ts +69 -0
  252. package/src/utils/package-json.ts +43 -0
  253. package/tests/sync-package-manager.test.ts +112 -0
  254. package/tests/transform-assign-props.test.ts +101 -0
  255. package/tsconfig.json +15 -0
@@ -0,0 +1,441 @@
1
+ /**
2
+ * Pie-lib sync strategy - syncs @pie-lib packages from upstream pie-lib
3
+ *
4
+ * Synced from: pie-lib/packages/{package}/src/
5
+ * Target: packages/lib-react/{package}/src/
6
+ */
7
+
8
+ import { existsSync } from 'node:fs';
9
+ import { mkdir, readFile, stat as fsStat, writeFile } from 'node:fs/promises';
10
+ import { dirname, join } from 'node:path';
11
+ import { convertJsToTs, convertJsxToTsx } from '../../utils/conversion.js';
12
+ import { getCurrentCommit } from '../../utils/git.js';
13
+ import type { SyncStrategy, SyncContext, SyncConfig, SyncResult } from './sync-strategy.js';
14
+ import { cleanDirectory, readdir } from './sync-filesystem.js';
15
+ import { fixImportsInFile, containsJsx } from './sync-imports.js';
16
+ import { generatePieLibViteConfig } from './sync-vite-config.js';
17
+ import { createPieLibTransformPipeline } from './sync-transforms.js';
18
+ import { ensurePieLibPackageJson } from './sync-package-manager.js';
19
+
20
+ interface InternalSyncResult {
21
+ filesChecked: number;
22
+ filesCopied: number;
23
+ filesSkipped: number;
24
+ filesUpdated: number;
25
+ }
26
+
27
+ export class PieLibStrategy implements SyncStrategy {
28
+ private touchedPieLibPackages = new Set<string>();
29
+ private result: InternalSyncResult = {
30
+ filesChecked: 0,
31
+ filesCopied: 0,
32
+ filesSkipped: 0,
33
+ filesUpdated: 0,
34
+ };
35
+
36
+ getName(): string {
37
+ return 'pie-lib';
38
+ }
39
+
40
+ getDescription(): string {
41
+ return '@pie-lib packages';
42
+ }
43
+
44
+ shouldRun(config: SyncConfig): boolean {
45
+ return config.syncPieLib;
46
+ }
47
+
48
+ async execute(context: SyncContext): Promise<SyncResult> {
49
+ const { config, logger } = context;
50
+ this.touchedPieLibPackages.clear();
51
+ this.result = {
52
+ filesChecked: 0,
53
+ filesCopied: 0,
54
+ filesSkipped: 0,
55
+ filesUpdated: 0,
56
+ };
57
+
58
+ if (!logger.isVerbose()) {
59
+ logger.progressStart('Syncing @pie-lib packages...');
60
+ } else {
61
+ logger.section('📚 Syncing @pie-lib packages');
62
+ }
63
+
64
+ const upstreamLibDir = join(config.pieLib, 'packages');
65
+ const targetBaseDir = join(config.pieElementsNg, 'packages/lib-react');
66
+
67
+ // Verify pie-lib exists
68
+ if (!existsSync(upstreamLibDir)) {
69
+ logger.error(`pie-lib packages not found at ${upstreamLibDir}`);
70
+ return { count: 0, packageNames: [] };
71
+ }
72
+
73
+ const upstreamCommit = getCurrentCommit(config.pieLib);
74
+
75
+ // Get list of packages to sync
76
+ const allPackages = await readdir(upstreamLibDir);
77
+ let packagesToSync: string[];
78
+
79
+ if (logger.isVerbose()) {
80
+ logger.info(` Compat report present: ${!!context.compatibilityReport}`);
81
+ logger.info(
82
+ ` Compat pieLibPackages: ${context.compatibilityReport?.pieLibPackages?.length || 0}`
83
+ );
84
+ }
85
+
86
+ // Use the filtered list from config if available (computed from element dependencies)
87
+ // This ensures we only sync the pie-lib packages actually needed by the elements being synced
88
+ if (config.pieLibPackages && config.pieLibPackages.length > 0) {
89
+ packagesToSync = config.pieLibPackages;
90
+ if (logger.isVerbose()) {
91
+ logger.info(` Using filtered pie-lib list: ${packagesToSync.length} packages`);
92
+ logger.info(` Packages: ${packagesToSync.join(', ')}`);
93
+ }
94
+ } else if (context.compatibilityReport?.pieLibPackages?.length) {
95
+ // Fallback to compatibility report list (used when no filtering is needed)
96
+ packagesToSync = context.compatibilityReport.pieLibPackages;
97
+ if (logger.isVerbose()) {
98
+ logger.info(` Using ESM compatibility report list: ${packagesToSync.length} packages`);
99
+ logger.info(` Packages: ${packagesToSync.join(', ')}`);
100
+ }
101
+ } else {
102
+ // Final fallback: sync all packages
103
+ packagesToSync = allPackages;
104
+ if (logger.isVerbose()) {
105
+ logger.info(` Using all packages fallback: ${allPackages.length} packages`);
106
+ }
107
+ }
108
+
109
+ for (const pkg of packagesToSync) {
110
+ // Skip if package doesn't exist
111
+ const pkgSrcDir = join(upstreamLibDir, pkg, 'src');
112
+ if (!existsSync(pkgSrcDir)) {
113
+ continue;
114
+ }
115
+
116
+ // Target: packages/lib-react/{package}/src/
117
+ const targetDir = join(targetBaseDir, pkg);
118
+ const targetSrcDir = join(targetDir, 'src');
119
+
120
+ // Clean target src subtree first so removed upstream files don't linger
121
+ await this.cleanTargetDir(targetSrcDir, `lib-react/${pkg}/src`, logger);
122
+
123
+ // Special handling for math-rendering - generate wrapper instead of full sync
124
+ let filesProcessed: number;
125
+ let libChanged: boolean;
126
+
127
+ if (pkg === 'math-rendering') {
128
+ filesProcessed = await this.generateMathRenderingWrapper(targetSrcDir, logger);
129
+ libChanged = filesProcessed > 0;
130
+ } else {
131
+ // Recursively sync all files from src/ directory
132
+ const beforeChanges = this.result.filesCopied + this.result.filesUpdated;
133
+ filesProcessed = await this.syncDirectory(
134
+ pkgSrcDir,
135
+ targetSrcDir,
136
+ 'src',
137
+ pkg,
138
+ upstreamCommit
139
+ );
140
+ const afterChanges = this.result.filesCopied + this.result.filesUpdated;
141
+ libChanged = afterChanges > beforeChanges;
142
+ }
143
+
144
+ if (filesProcessed > 0 && logger.isVerbose()) {
145
+ logger.success(` ✨ ${pkg}: ${filesProcessed} file(s) synced`);
146
+ }
147
+
148
+ // Keep local compatibility exports that upstream plot package currently misses.
149
+ const wroteCompatibilityPatch = await this.ensurePlotTypesCompatibilityPatch(
150
+ pkg,
151
+ targetSrcDir
152
+ );
153
+
154
+ // Ensure package.json has ESM module support and expected exports
155
+ let wrotePkgJson = false;
156
+ wrotePkgJson = await ensurePieLibPackageJson(pkg, targetDir, config);
157
+
158
+ // Ensure vite.config.ts exists
159
+ const wroteViteConfig = await this.ensureViteConfig(pkg, targetDir, logger);
160
+
161
+ // Ensure tsconfig.json exists
162
+ const wroteTsConfig = await this.ensureTsConfig(pkg, targetDir, logger);
163
+
164
+ if (
165
+ libChanged ||
166
+ wroteCompatibilityPatch ||
167
+ wrotePkgJson ||
168
+ wroteViteConfig ||
169
+ wroteTsConfig
170
+ ) {
171
+ this.touchedPieLibPackages.add(pkg);
172
+ }
173
+ }
174
+
175
+ if (!logger.isVerbose()) {
176
+ logger.progressCompleteWithCount(this.touchedPieLibPackages.size, 'packages');
177
+ } else {
178
+ logger.info(`\nSynced ${this.touchedPieLibPackages.size} @pie-lib package(s)`);
179
+ }
180
+ return {
181
+ count: this.touchedPieLibPackages.size,
182
+ packageNames: Array.from(this.touchedPieLibPackages)
183
+ .sort()
184
+ .map((pkg) => `@pie-lib/${pkg}`),
185
+ };
186
+ }
187
+
188
+ private async cleanTargetDir(targetDir: string, label: string, logger: any): Promise<void> {
189
+ // Preserve non-synced pie-elements-ng files
190
+ const preserve: string[] = [];
191
+
192
+ // Preserve inline-menu.tsx in render-ui (not from upstream)
193
+ if (label.includes('render-ui')) {
194
+ preserve.push('inline-menu.tsx');
195
+ }
196
+
197
+ await cleanDirectory(targetDir, label, { dryRun: false, verbose: false, preserve }, logger);
198
+ }
199
+
200
+ private async syncDirectory(
201
+ sourceDir: string,
202
+ targetDir: string,
203
+ relativePath: string,
204
+ pkg: string,
205
+ upstreamCommit: string
206
+ ): Promise<number> {
207
+ let filesProcessed = 0;
208
+ const defaultExportFiles = new Set<string>(); // Track files with default exports
209
+
210
+ const items = await readdir(sourceDir);
211
+
212
+ for (const item of items) {
213
+ const srcPath = join(sourceDir, item);
214
+ const stat = await fsStat(srcPath);
215
+
216
+ if (stat.isDirectory()) {
217
+ // Skip __tests__, __mocks__, etc.
218
+ if (item.startsWith('__')) {
219
+ continue;
220
+ }
221
+ // Recursively sync subdirectories
222
+ const subFilesProcessed = await this.syncDirectory(
223
+ srcPath,
224
+ join(targetDir, item),
225
+ join(relativePath, item),
226
+ pkg,
227
+ upstreamCommit
228
+ );
229
+ filesProcessed += subFilesProcessed;
230
+ continue;
231
+ }
232
+
233
+ // Only process .js and .jsx files
234
+ if (!item.endsWith('.js') && !item.endsWith('.jsx')) {
235
+ continue;
236
+ }
237
+
238
+ this.result.filesChecked++;
239
+ filesProcessed++;
240
+
241
+ // Read source
242
+ let sourceContent = await readFile(srcPath, 'utf-8');
243
+
244
+ // Apply all standard transformations
245
+ const transformPipeline = createPieLibTransformPipeline();
246
+ sourceContent = transformPipeline(sourceContent, srcPath);
247
+
248
+ const hasJsx = item.endsWith('.jsx') || (item.endsWith('.js') && containsJsx(sourceContent));
249
+
250
+ // Convert .js → .ts/.tsx and .jsx → .tsx
251
+ const targetFile = item.replace(/\.jsx?$/, hasJsx ? '.tsx' : '.ts');
252
+ const targetPath = join(targetDir, targetFile);
253
+
254
+ // Convert based on file extension
255
+ const conversionResult = hasJsx
256
+ ? convertJsxToTsx(sourceContent, {
257
+ sourcePath: `pie-lib/packages/${pkg}/${relativePath}/${item}`,
258
+ commit: upstreamCommit,
259
+ })
260
+ : convertJsToTs(sourceContent, {
261
+ sourcePath: `pie-lib/packages/${pkg}/${relativePath}/${item}`,
262
+ commit: upstreamCommit,
263
+ });
264
+
265
+ let converted = conversionResult.code;
266
+
267
+ // Track files that export default objects (for import fixing later)
268
+ if (conversionResult.hasDefaultObjectExport) {
269
+ // Store the file name without extension for import matching
270
+ const fileNameWithoutExt = targetFile.replace(/\.(ts|tsx)$/, '');
271
+ defaultExportFiles.add(fileNameWithoutExt);
272
+ }
273
+
274
+ // Check if different
275
+ // NOTE: This comparison is exact (===) to ensure any changes in:
276
+ // - Upstream source code
277
+ // - Transformation logic (lodash-es, event packages, etc.)
278
+ // - Sync version (tracked in @sync-version header)
279
+ // will trigger a file update. This prioritizes correctness over speed.
280
+ const isNew = !existsSync(targetPath);
281
+ if (!isNew) {
282
+ const currentContent = await readFile(targetPath, 'utf-8');
283
+ if (currentContent === converted) {
284
+ this.result.filesSkipped++;
285
+ continue;
286
+ }
287
+ this.result.filesUpdated++;
288
+ } else {
289
+ this.result.filesCopied++;
290
+ }
291
+
292
+ // Write
293
+ await mkdir(dirname(targetPath), { recursive: true });
294
+ await writeFile(targetPath, converted, 'utf-8');
295
+ }
296
+
297
+ // After all files are synced, fix import statements in consuming files
298
+ if (defaultExportFiles.size > 0) {
299
+ const targetDirItems = await readdir(targetDir);
300
+ for (const item of targetDirItems) {
301
+ const itemPath = join(targetDir, item);
302
+ const stat = await fsStat(itemPath);
303
+ if (stat.isFile() && (item.endsWith('.tsx') || item.endsWith('.ts'))) {
304
+ await fixImportsInFile(itemPath, defaultExportFiles);
305
+ }
306
+ }
307
+ }
308
+
309
+ return filesProcessed;
310
+ }
311
+
312
+ /**
313
+ * Generate a thin wrapper for math-rendering that re-exports from @pie-element/math-rendering
314
+ */
315
+ private async generateMathRenderingWrapper(targetSrcDir: string, logger: any): Promise<number> {
316
+ await mkdir(targetSrcDir, { recursive: true });
317
+
318
+ const wrapperContent = `// @ts-nocheck
319
+ /**
320
+ * @synced-from pie-lib/packages/math-rendering
321
+ * @auto-generated
322
+ *
323
+ * This is a thin wrapper that re-exports from @pie-element/shared-math-rendering-mathjax.
324
+ * The actual implementation is in packages/shared/math-rendering-mathjax.
325
+ */
326
+
327
+ export { renderMath, wrapMath, unWrapMath, mmlToLatex } from '@pie-element/shared-math-rendering-mathjax';
328
+ `;
329
+
330
+ const indexPath = join(targetSrcDir, 'index.ts');
331
+ const needsWrite =
332
+ !existsSync(indexPath) || (await readFile(indexPath, 'utf-8')) !== wrapperContent;
333
+
334
+ if (needsWrite) {
335
+ await writeFile(indexPath, wrapperContent, 'utf-8');
336
+ if (logger.isVerbose()) {
337
+ logger.success(` ✨ math-rendering: generated wrapper`);
338
+ }
339
+ return 1;
340
+ }
341
+
342
+ return 0;
343
+ }
344
+
345
+ private async ensureViteConfig(pkgName: string, pkgDir: string, logger: any): Promise<boolean> {
346
+ if (!existsSync(pkgDir)) {
347
+ return false;
348
+ }
349
+
350
+ const viteConfigPath = join(pkgDir, 'vite.config.ts');
351
+ const viteConfig = generatePieLibViteConfig(pkgName, pkgDir);
352
+
353
+ // Check if vite config needs to be written
354
+ const currentContent = existsSync(viteConfigPath)
355
+ ? await readFile(viteConfigPath, 'utf-8').catch(() => null)
356
+ : null;
357
+
358
+ if (currentContent === viteConfig) {
359
+ return false;
360
+ }
361
+
362
+ await writeFile(viteConfigPath, viteConfig, 'utf-8');
363
+ if (logger.isVerbose()) {
364
+ logger.success(` 📝 ${pkgName}: generated vite.config.ts`);
365
+ }
366
+ return true;
367
+ }
368
+
369
+ private async ensurePlotTypesCompatibilityPatch(
370
+ pkgName: string,
371
+ targetSrcDir: string
372
+ ): Promise<boolean> {
373
+ if (pkgName !== 'plot') {
374
+ return false;
375
+ }
376
+
377
+ const typesPath = join(targetSrcDir, 'types.ts');
378
+ if (!existsSync(typesPath)) {
379
+ return false;
380
+ }
381
+
382
+ const current = await readFile(typesPath, 'utf-8');
383
+ if (current.includes('ToolPropTypeFields')) {
384
+ return false;
385
+ }
386
+
387
+ const patch = `
388
+
389
+ // Local compatibility export used by graphing tool components.
390
+ export const ToolPropTypeFields = {
391
+ graphProps: GraphPropsType.isRequired,
392
+ mark: PropTypes.object,
393
+ onChange: PropTypes.func,
394
+ onDelete: PropTypes.func,
395
+ onClick: PropTypes.func,
396
+ };
397
+
398
+ export const ToolPropType = PropTypes.shape(ToolPropTypeFields);
399
+ `;
400
+
401
+ await writeFile(typesPath, `${current}${patch}`, 'utf-8');
402
+ return true;
403
+ }
404
+
405
+ private async ensureTsConfig(pkgName: string, pkgDir: string, logger: any): Promise<boolean> {
406
+ if (!existsSync(pkgDir)) {
407
+ return false;
408
+ }
409
+
410
+ const tsConfigPath = join(pkgDir, 'tsconfig.json');
411
+ const tsConfig = this.generateTsConfig();
412
+
413
+ // Check if tsconfig needs to be written
414
+ const currentContent = existsSync(tsConfigPath)
415
+ ? await readFile(tsConfigPath, 'utf-8').catch(() => null)
416
+ : null;
417
+
418
+ if (currentContent === tsConfig) {
419
+ return false;
420
+ }
421
+
422
+ await writeFile(tsConfigPath, tsConfig, 'utf-8');
423
+ if (logger.isVerbose()) {
424
+ logger.success(` 📝 ${pkgName}: generated tsconfig.json`);
425
+ }
426
+ return true;
427
+ }
428
+
429
+ private generateTsConfig(): string {
430
+ return `{
431
+ "extends": "../../../tsconfig.base.json",
432
+ "compilerOptions": {
433
+ "outDir": "dist",
434
+ "declarationDir": "dist",
435
+ "rootDir": "src"
436
+ },
437
+ "include": ["src/**/*"]
438
+ }
439
+ `;
440
+ }
441
+ }