@pie-element/cli 0.1.1 → 0.1.2-next.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 (281) hide show
  1. package/README.md +48 -10
  2. package/dist/commands/dev/demo/index.d.ts +1 -1
  3. package/dist/commands/dev/demo/index.js +21 -0
  4. package/dist/commands/dev/demo/index.js.map +1 -1
  5. package/dist/commands/dev/test-bundler.d.ts +0 -1
  6. package/dist/commands/dev/test-bundler.js +2 -10
  7. package/dist/commands/dev/test-bundler.js.map +1 -1
  8. package/dist/commands/docs/generate.d.ts +16 -0
  9. package/dist/commands/docs/generate.js +150 -0
  10. package/dist/commands/docs/generate.js.map +1 -0
  11. package/dist/commands/docs/verify.d.ts +12 -0
  12. package/dist/commands/docs/verify.js +40 -0
  13. package/dist/commands/docs/verify.js.map +1 -0
  14. package/dist/commands/packages/create-controllers.d.ts +0 -1
  15. package/dist/commands/packages/create-controllers.js.map +1 -1
  16. package/dist/commands/packages/create-lib-react.d.ts +0 -1
  17. package/dist/commands/packages/create-lib-react.js +1 -3
  18. package/dist/commands/packages/create-lib-react.js.map +1 -1
  19. package/dist/commands/packages/create-react-elements.d.ts +0 -1
  20. package/dist/commands/packages/create-react-elements.js +2 -3
  21. package/dist/commands/packages/create-react-elements.js.map +1 -1
  22. package/dist/commands/packages/enable-publishing.d.ts +0 -1
  23. package/dist/commands/packages/enable-publishing.js +26 -23
  24. package/dist/commands/packages/enable-publishing.js.map +1 -1
  25. package/dist/commands/packages/init-synced-elements.d.ts +0 -1
  26. package/dist/commands/packages/init-synced-elements.js +1 -1
  27. package/dist/commands/packages/init-synced-elements.js.map +1 -1
  28. package/dist/commands/upstream/analyze-esm.d.ts +0 -1
  29. package/dist/commands/upstream/analyze-esm.js +5 -1
  30. package/dist/commands/upstream/analyze-esm.js.map +1 -1
  31. package/dist/commands/upstream/check.d.ts +0 -1
  32. package/dist/commands/upstream/check.js.map +1 -1
  33. package/dist/commands/upstream/deps.d.ts +0 -1
  34. package/dist/commands/upstream/deps.js.map +1 -1
  35. package/dist/commands/upstream/sync.d.ts +11 -2
  36. package/dist/commands/upstream/sync.js +364 -25
  37. package/dist/commands/upstream/sync.js.map +1 -1
  38. package/dist/commands/upstream/track.d.ts +0 -1
  39. package/dist/commands/upstream/track.js.map +1 -1
  40. package/dist/commands/upstream/update.d.ts +0 -1
  41. package/dist/commands/upstream/update.js +37 -7
  42. package/dist/commands/upstream/update.js.map +1 -1
  43. package/dist/commands/verify/controllers.d.ts +0 -1
  44. package/dist/commands/verify/controllers.js +213 -59
  45. package/dist/commands/verify/controllers.js.map +1 -1
  46. package/dist/commands/verify/dependency-integrity.d.ts +18 -0
  47. package/dist/commands/verify/dependency-integrity.js +147 -0
  48. package/dist/commands/verify/dependency-integrity.js.map +1 -0
  49. package/dist/commands/verify/react-build.d.ts +0 -1
  50. package/dist/commands/verify/react-build.js.map +1 -1
  51. package/dist/index.d.ts +0 -1
  52. package/dist/index.js.map +1 -1
  53. package/dist/lib/docs/contract-validator.d.ts +12 -0
  54. package/dist/lib/docs/contract-validator.js +38 -0
  55. package/dist/lib/docs/contract-validator.js.map +1 -0
  56. package/dist/lib/docs/contracts.d.ts +11 -0
  57. package/dist/lib/docs/contracts.js +241 -0
  58. package/dist/lib/docs/contracts.js.map +1 -0
  59. package/dist/lib/docs/discovery.d.ts +10 -0
  60. package/dist/lib/docs/discovery.js +91 -0
  61. package/dist/lib/docs/discovery.js.map +1 -0
  62. package/dist/lib/docs/generator.d.ts +14 -0
  63. package/dist/lib/docs/generator.js +450 -0
  64. package/dist/lib/docs/generator.js.map +1 -0
  65. package/dist/lib/docs/source-extractor.d.ts +2 -0
  66. package/dist/lib/docs/source-extractor.js +209 -0
  67. package/dist/lib/docs/source-extractor.js.map +1 -0
  68. package/dist/lib/docs/types.d.ts +77 -0
  69. package/dist/lib/docs/types.js +2 -0
  70. package/dist/lib/docs/types.js.map +1 -0
  71. package/dist/lib/upstream/repo-utils.d.ts +0 -1
  72. package/dist/lib/upstream/repo-utils.js.map +1 -1
  73. package/dist/lib/upstream/sync-compatibility.d.ts +0 -1
  74. package/dist/lib/upstream/sync-compatibility.js.map +1 -1
  75. package/dist/lib/upstream/sync-constants.d.ts +35 -7
  76. package/dist/lib/upstream/sync-constants.js +40 -11
  77. package/dist/lib/upstream/sync-constants.js.map +1 -1
  78. package/dist/lib/upstream/sync-controllers-strategy.d.ts +0 -1
  79. package/dist/lib/upstream/sync-controllers-strategy.js +14 -4
  80. package/dist/lib/upstream/sync-controllers-strategy.js.map +1 -1
  81. package/dist/lib/upstream/sync-demo-metadata.d.ts +0 -1
  82. package/dist/lib/upstream/sync-demo-metadata.js +1 -1
  83. package/dist/lib/upstream/sync-demo-metadata.js.map +1 -1
  84. package/dist/lib/upstream/sync-entry-discovery.d.ts +3 -0
  85. package/dist/lib/upstream/sync-entry-discovery.js +23 -0
  86. package/dist/lib/upstream/sync-entry-discovery.js.map +1 -0
  87. package/dist/lib/upstream/sync-externals.d.ts +7 -7
  88. package/dist/lib/upstream/sync-externals.js +51 -35
  89. package/dist/lib/upstream/sync-externals.js.map +1 -1
  90. package/dist/lib/upstream/sync-filesystem.d.ts +0 -1
  91. package/dist/lib/upstream/sync-filesystem.js.map +1 -1
  92. package/dist/lib/upstream/sync-imports.d.ts +82 -62
  93. package/dist/lib/upstream/sync-imports.js +658 -185
  94. package/dist/lib/upstream/sync-imports.js.map +1 -1
  95. package/dist/lib/upstream/sync-package-json.d.ts +0 -1
  96. package/dist/lib/upstream/sync-package-json.js +7 -0
  97. package/dist/lib/upstream/sync-package-json.js.map +1 -1
  98. package/dist/lib/upstream/sync-package-manager.d.ts +14 -4
  99. package/dist/lib/upstream/sync-package-manager.js +408 -72
  100. package/dist/lib/upstream/sync-package-manager.js.map +1 -1
  101. package/dist/lib/upstream/sync-pielib-strategy.d.ts +2 -1
  102. package/dist/lib/upstream/sync-pielib-strategy.js +228 -110
  103. package/dist/lib/upstream/sync-pielib-strategy.js.map +1 -1
  104. package/dist/lib/upstream/sync-presets.d.ts +53 -0
  105. package/dist/lib/upstream/sync-presets.js +203 -0
  106. package/dist/lib/upstream/sync-presets.js.map +1 -0
  107. package/dist/lib/upstream/sync-react-strategy.d.ts +6 -1
  108. package/dist/lib/upstream/sync-react-strategy.js +342 -134
  109. package/dist/lib/upstream/sync-react-strategy.js.map +1 -1
  110. package/dist/lib/upstream/sync-source-edit.d.ts +14 -0
  111. package/dist/lib/upstream/sync-source-edit.js +89 -0
  112. package/dist/lib/upstream/sync-source-edit.js.map +1 -0
  113. package/dist/lib/upstream/sync-source-tree.d.ts +22 -0
  114. package/dist/lib/upstream/sync-source-tree.js +99 -0
  115. package/dist/lib/upstream/sync-source-tree.js.map +1 -0
  116. package/dist/lib/upstream/sync-strategy.d.ts +1 -1
  117. package/dist/lib/upstream/sync-strategy.js.map +1 -1
  118. package/dist/lib/upstream/sync-summary.d.ts +0 -1
  119. package/dist/lib/upstream/sync-summary.js.map +1 -1
  120. package/dist/lib/upstream/sync-transforms.d.ts +13 -11
  121. package/dist/lib/upstream/sync-transforms.js +23 -17
  122. package/dist/lib/upstream/sync-transforms.js.map +1 -1
  123. package/dist/lib/upstream/sync-vite-config.d.ts +13 -1
  124. package/dist/lib/upstream/sync-vite-config.js +65 -46
  125. package/dist/lib/upstream/sync-vite-config.js.map +1 -1
  126. package/dist/utils/compatibility.d.ts +13 -1
  127. package/dist/utils/compatibility.js +143 -2
  128. package/dist/utils/compatibility.js.map +1 -1
  129. package/dist/utils/conversion.d.ts +0 -1
  130. package/dist/utils/conversion.js.map +1 -1
  131. package/dist/utils/dependency-integrity.d.ts +37 -0
  132. package/dist/utils/dependency-integrity.js +557 -0
  133. package/dist/utils/dependency-integrity.js.map +1 -0
  134. package/dist/utils/git.d.ts +0 -1
  135. package/dist/utils/git.js.map +1 -1
  136. package/dist/utils/logger.d.ts +0 -1
  137. package/dist/utils/logger.js.map +1 -1
  138. package/dist/utils/package-json.d.ts +0 -1
  139. package/dist/utils/package-json.js.map +1 -1
  140. package/package.json +24 -12
  141. package/.compatibility/report.json +0 -2491
  142. package/.turbo/turbo-build.log +0 -1
  143. package/CHANGELOG.md +0 -8
  144. package/REFACTORING.md +0 -131
  145. package/bin/dev.js +0 -5
  146. package/dist/commands/dev/demo/index.d.ts.map +0 -1
  147. package/dist/commands/dev/test-bundler.d.ts.map +0 -1
  148. package/dist/commands/mathquill/migrate.d.ts +0 -20
  149. package/dist/commands/mathquill/migrate.d.ts.map +0 -1
  150. package/dist/commands/mathquill/migrate.js +0 -240
  151. package/dist/commands/mathquill/migrate.js.map +0 -1
  152. package/dist/commands/mathquill/status.d.ts +0 -20
  153. package/dist/commands/mathquill/status.d.ts.map +0 -1
  154. package/dist/commands/mathquill/status.js +0 -231
  155. package/dist/commands/mathquill/status.js.map +0 -1
  156. package/dist/commands/packages/create-controllers.d.ts.map +0 -1
  157. package/dist/commands/packages/create-lib-react.d.ts.map +0 -1
  158. package/dist/commands/packages/create-react-elements.d.ts.map +0 -1
  159. package/dist/commands/packages/enable-publishing.d.ts.map +0 -1
  160. package/dist/commands/packages/init-synced-elements.d.ts.map +0 -1
  161. package/dist/commands/upstream/analyze-esm.d.ts.map +0 -1
  162. package/dist/commands/upstream/check.d.ts.map +0 -1
  163. package/dist/commands/upstream/deps.d.ts.map +0 -1
  164. package/dist/commands/upstream/sync-mathquill.d.ts +0 -12
  165. package/dist/commands/upstream/sync-mathquill.d.ts.map +0 -1
  166. package/dist/commands/upstream/sync-mathquill.js +0 -97
  167. package/dist/commands/upstream/sync-mathquill.js.map +0 -1
  168. package/dist/commands/upstream/sync.d.ts.map +0 -1
  169. package/dist/commands/upstream/track.d.ts.map +0 -1
  170. package/dist/commands/upstream/update.d.ts.map +0 -1
  171. package/dist/commands/verify/controllers.d.ts.map +0 -1
  172. package/dist/commands/verify/react-build.d.ts.map +0 -1
  173. package/dist/index.d.ts.map +0 -1
  174. package/dist/lib/mathquill/extension-generator.d.ts +0 -9
  175. package/dist/lib/mathquill/extension-generator.d.ts.map +0 -1
  176. package/dist/lib/mathquill/extension-generator.js +0 -107
  177. package/dist/lib/mathquill/extension-generator.js.map +0 -1
  178. package/dist/lib/mathquill/khan-extractor.d.ts +0 -16
  179. package/dist/lib/mathquill/khan-extractor.d.ts.map +0 -1
  180. package/dist/lib/mathquill/khan-extractor.js +0 -148
  181. package/dist/lib/mathquill/khan-extractor.js.map +0 -1
  182. package/dist/lib/mathquill/learnosity-extractor.d.ts +0 -15
  183. package/dist/lib/mathquill/learnosity-extractor.d.ts.map +0 -1
  184. package/dist/lib/mathquill/learnosity-extractor.js +0 -170
  185. package/dist/lib/mathquill/learnosity-extractor.js.map +0 -1
  186. package/dist/lib/mathquill/migration-orchestrator.d.ts +0 -77
  187. package/dist/lib/mathquill/migration-orchestrator.d.ts.map +0 -1
  188. package/dist/lib/mathquill/migration-orchestrator.js +0 -391
  189. package/dist/lib/mathquill/migration-orchestrator.js.map +0 -1
  190. package/dist/lib/mathquill/package-updater.d.ts +0 -9
  191. package/dist/lib/mathquill/package-updater.d.ts.map +0 -1
  192. package/dist/lib/mathquill/package-updater.js +0 -103
  193. package/dist/lib/mathquill/package-updater.js.map +0 -1
  194. package/dist/lib/mathquill/pie-extractor.d.ts +0 -14
  195. package/dist/lib/mathquill/pie-extractor.d.ts.map +0 -1
  196. package/dist/lib/mathquill/pie-extractor.js +0 -167
  197. package/dist/lib/mathquill/pie-extractor.js.map +0 -1
  198. package/dist/lib/upstream/repo-utils.d.ts.map +0 -1
  199. package/dist/lib/upstream/sync-compatibility.d.ts.map +0 -1
  200. package/dist/lib/upstream/sync-constants.d.ts.map +0 -1
  201. package/dist/lib/upstream/sync-controllers-strategy.d.ts.map +0 -1
  202. package/dist/lib/upstream/sync-demo-metadata.d.ts.map +0 -1
  203. package/dist/lib/upstream/sync-dev-exports.d.ts +0 -13
  204. package/dist/lib/upstream/sync-dev-exports.d.ts.map +0 -1
  205. package/dist/lib/upstream/sync-dev-exports.js +0 -115
  206. package/dist/lib/upstream/sync-dev-exports.js.map +0 -1
  207. package/dist/lib/upstream/sync-externals.d.ts.map +0 -1
  208. package/dist/lib/upstream/sync-filesystem.d.ts.map +0 -1
  209. package/dist/lib/upstream/sync-imports.d.ts.map +0 -1
  210. package/dist/lib/upstream/sync-mathquill.d.ts +0 -19
  211. package/dist/lib/upstream/sync-mathquill.d.ts.map +0 -1
  212. package/dist/lib/upstream/sync-mathquill.js +0 -160
  213. package/dist/lib/upstream/sync-mathquill.js.map +0 -1
  214. package/dist/lib/upstream/sync-package-json.d.ts.map +0 -1
  215. package/dist/lib/upstream/sync-package-manager.d.ts.map +0 -1
  216. package/dist/lib/upstream/sync-pielib-strategy.d.ts.map +0 -1
  217. package/dist/lib/upstream/sync-react-strategy.d.ts.map +0 -1
  218. package/dist/lib/upstream/sync-strategy.d.ts.map +0 -1
  219. package/dist/lib/upstream/sync-summary.d.ts.map +0 -1
  220. package/dist/lib/upstream/sync-transforms.d.ts.map +0 -1
  221. package/dist/lib/upstream/sync-vite-config.d.ts.map +0 -1
  222. package/dist/utils/compatibility.d.ts.map +0 -1
  223. package/dist/utils/conversion.d.ts.map +0 -1
  224. package/dist/utils/git.d.ts.map +0 -1
  225. package/dist/utils/logger.d.ts.map +0 -1
  226. package/dist/utils/package-json.d.ts.map +0 -1
  227. package/packages/cli/bin/dev.js +0 -5
  228. package/packages/cli/bin/run.js +0 -5
  229. package/src/commands/dev/demo/index.ts +0 -313
  230. package/src/commands/dev/test-bundler.ts +0 -345
  231. package/src/commands/mathquill/migrate.ts +0 -269
  232. package/src/commands/mathquill/status.ts +0 -267
  233. package/src/commands/packages/create-controllers.ts +0 -127
  234. package/src/commands/packages/create-lib-react.ts +0 -279
  235. package/src/commands/packages/create-react-elements.ts +0 -306
  236. package/src/commands/packages/enable-publishing.ts +0 -161
  237. package/src/commands/packages/init-synced-elements.ts +0 -259
  238. package/src/commands/upstream/README.md +0 -444
  239. package/src/commands/upstream/analyze-esm.ts +0 -1973
  240. package/src/commands/upstream/check.ts +0 -228
  241. package/src/commands/upstream/deps.ts +0 -222
  242. package/src/commands/upstream/sync-mathquill.ts +0 -108
  243. package/src/commands/upstream/sync.ts +0 -687
  244. package/src/commands/upstream/track.ts +0 -145
  245. package/src/commands/upstream/update.ts +0 -110
  246. package/src/commands/verify/controllers.ts +0 -166
  247. package/src/commands/verify/react-build.ts +0 -171
  248. package/src/index.ts +0 -1
  249. package/src/lib/mathquill/extension-generator.ts +0 -111
  250. package/src/lib/mathquill/khan-extractor.ts +0 -175
  251. package/src/lib/mathquill/learnosity-extractor.ts +0 -198
  252. package/src/lib/mathquill/migration-orchestrator.ts +0 -513
  253. package/src/lib/mathquill/package-updater.ts +0 -120
  254. package/src/lib/mathquill/pie-extractor.ts +0 -194
  255. package/src/lib/upstream/repo-utils.ts +0 -18
  256. package/src/lib/upstream/sync-compatibility.ts +0 -89
  257. package/src/lib/upstream/sync-constants.ts +0 -77
  258. package/src/lib/upstream/sync-controllers-strategy.ts +0 -291
  259. package/src/lib/upstream/sync-demo-metadata.ts +0 -199
  260. package/src/lib/upstream/sync-dev-exports.ts +0 -151
  261. package/src/lib/upstream/sync-externals.ts +0 -159
  262. package/src/lib/upstream/sync-filesystem.ts +0 -87
  263. package/src/lib/upstream/sync-imports.ts +0 -992
  264. package/src/lib/upstream/sync-mathquill.ts +0 -194
  265. package/src/lib/upstream/sync-package-json.ts +0 -86
  266. package/src/lib/upstream/sync-package-manager.ts +0 -694
  267. package/src/lib/upstream/sync-pielib-strategy.ts +0 -441
  268. package/src/lib/upstream/sync-react-strategy.ts +0 -945
  269. package/src/lib/upstream/sync-strategy.ts +0 -61
  270. package/src/lib/upstream/sync-summary.ts +0 -194
  271. package/src/lib/upstream/sync-transforms.ts +0 -154
  272. package/src/lib/upstream/sync-vite-config.ts +0 -243
  273. package/src/types/es-module-lexer.d.ts +0 -4
  274. package/src/utils/compatibility.ts +0 -182
  275. package/src/utils/conversion.ts +0 -153
  276. package/src/utils/git.ts +0 -63
  277. package/src/utils/logger.ts +0 -69
  278. package/src/utils/package-json.ts +0 -43
  279. package/tests/sync-package-manager.test.ts +0 -112
  280. package/tests/transform-assign-props.test.ts +0 -101
  281. package/tsconfig.json +0 -15
@@ -1,313 +0,0 @@
1
- import { Command, Flags } from '@oclif/core';
2
- import { spawn, type ChildProcess } from 'node:child_process';
3
- import path from 'node:path';
4
- import { existsSync, readFileSync, rmSync, unlinkSync, writeFileSync } from 'node:fs';
5
- import { tmpdir } from 'node:os';
6
-
7
- /**
8
- * Start unified demo application for all PIE elements.
9
- *
10
- * This command starts the apps/element-demo SvelteKit application which provides
11
- * a unified demo experience for all 27 PIE elements with multiple demo configurations.
12
- */
13
- export default class DevDemo extends Command {
14
- static override description = 'Start unified demo app for all PIE elements (apps/element-demo)';
15
-
16
- static override examples = [
17
- '<%= config.bin %> <%= command.id %>',
18
- '<%= config.bin %> <%= command.id %> --port 5180',
19
- '<%= config.bin %> <%= command.id %> --open',
20
- '<%= config.bin %> <%= command.id %> --build',
21
- ];
22
-
23
- static override flags = {
24
- port: Flags.integer({
25
- char: 'p',
26
- description: 'Vite dev server port',
27
- default: 5222,
28
- }),
29
- build: Flags.boolean({
30
- char: 'b',
31
- description: 'Build all elements before starting',
32
- default: false,
33
- }),
34
- open: Flags.boolean({
35
- char: 'o',
36
- description: 'Open browser automatically',
37
- default: false,
38
- allowNo: true,
39
- }),
40
- };
41
-
42
- static override args = {};
43
-
44
- private viteProcess: ChildProcess | null = null;
45
- private lockFilePath = '';
46
- private bundlerInstanceDir = '';
47
-
48
- public async run(): Promise<void> {
49
- const { flags } = await this.parse(DevDemo);
50
-
51
- // Find monorepo root - check if we're already at root or need to traverse up
52
- let monorepoRoot = process.cwd();
53
- const rootPackageJson = path.join(monorepoRoot, 'package.json');
54
-
55
- // If package.json doesn't exist at current level, we're in a subdirectory (like tools/cli)
56
- // Traverse up to find the root
57
- if (!existsSync(rootPackageJson) || !existsSync(path.join(monorepoRoot, 'apps'))) {
58
- monorepoRoot = path.resolve(monorepoRoot, '../..');
59
- }
60
-
61
- const demoAppPath = path.join(monorepoRoot, 'apps', 'element-demo');
62
-
63
- this.lockFilePath = this.getLockFilePath(flags.port);
64
- this.acquireLock(flags.port);
65
- this.bundlerInstanceDir = this.createBundlerInstanceDir(flags.port);
66
-
67
- this.log('Starting unified demo app for all PIE elements...');
68
- this.log('');
69
- this.log('Bundler mode: local (default)');
70
- this.log(`Bundler workspace: ${this.bundlerInstanceDir}`);
71
- this.log('');
72
-
73
- try {
74
- // 1. Build all elements if requested
75
- if (flags.build) {
76
- this.log('Building all React elements...');
77
- await this.buildAllElements(monorepoRoot);
78
- }
79
-
80
- // 2. Install workspace dependencies (only if building)
81
- if (flags.build) {
82
- this.log('Installing workspace dependencies...');
83
- await this.installDependencies(monorepoRoot);
84
- this.log('✓ Dependencies installed\n');
85
- }
86
-
87
- // 3. Start Vite dev server
88
- this.log(`Starting Vite dev server on port ${flags.port}...`);
89
- if (!existsSync(demoAppPath)) {
90
- this.error(`Demo app not found at ${demoAppPath}`);
91
- }
92
- this.viteProcess = await this.startVite(demoAppPath, flags.port, {
93
- DEMO_BUNDLER_INSTANCE_DIR: this.bundlerInstanceDir,
94
- });
95
-
96
- // 4. Open browser
97
- if (flags.open) {
98
- await this.sleep(3000); // Wait for Vite to start
99
- const url = `http://localhost:${flags.port}`;
100
- this.log(`Opening ${url}...`);
101
- await this.openBrowser(url);
102
- }
103
-
104
- this.log('');
105
- this.log('✓ Demo app running');
106
- this.log(` URL: http://localhost:${flags.port}`);
107
- this.log('');
108
- if (!flags.build) {
109
- this.log('ℹ️ Running without rebuild. Use --build to rebuild all elements first.');
110
- this.log('');
111
- }
112
- this.log('📖 The demo app showcases all 27 PIE elements with multiple demos');
113
- this.log(' Navigate to any element to see available demo configurations');
114
- this.log('');
115
- this.log('Press Ctrl+C to stop');
116
-
117
- // 7. Handle graceful shutdown
118
- process.on('SIGINT', () => {
119
- this.log('\nShutting down...');
120
- this.cleanup();
121
- process.exit(0);
122
- });
123
-
124
- process.on('SIGTERM', () => {
125
- this.cleanup();
126
- process.exit(0);
127
- });
128
-
129
- // Keep process alive
130
- await new Promise(() => {});
131
- } catch (error) {
132
- this.cleanup();
133
- throw error;
134
- }
135
- }
136
-
137
- private async buildAllElements(cwd: string): Promise<void> {
138
- return new Promise((resolve, reject) => {
139
- const build = spawn(
140
- 'bun',
141
- [
142
- 'run',
143
- 'turbo',
144
- 'build',
145
- '--force',
146
- '--filter',
147
- './packages/elements-react/*',
148
- '--filter',
149
- './packages/elements-svelte/*',
150
- ],
151
- {
152
- stdio: 'inherit',
153
- cwd,
154
- }
155
- );
156
-
157
- build.on('close', (code) => {
158
- if (code === 0) {
159
- this.log('✓ All elements built\n');
160
- resolve();
161
- } else {
162
- reject(new Error(`Build failed with code ${code}`));
163
- }
164
- });
165
-
166
- build.on('error', reject);
167
- });
168
- }
169
-
170
- private async startVite(
171
- demoPath: string,
172
- port: number,
173
- env: Record<string, string>
174
- ): Promise<ChildProcess> {
175
- const proc = spawn('bunx', ['vite', '--port', port.toString(), '--host'], {
176
- cwd: demoPath,
177
- stdio: 'inherit',
178
- env: {
179
- ...process.env,
180
- PORT: port.toString(),
181
- ...env,
182
- },
183
- });
184
-
185
- proc.on('error', (error) => {
186
- this.error(`Failed to start Vite: ${error.message}`);
187
- });
188
-
189
- return proc;
190
- }
191
-
192
- private async openBrowser(url: string): Promise<void> {
193
- try {
194
- const open = await import('open');
195
- await open.default(url);
196
- } catch (error) {
197
- this.warn(`Could not open browser: ${error}`);
198
- this.log(`Please open ${url} manually`);
199
- }
200
- }
201
-
202
- private async installDependencies(cwd: string): Promise<void> {
203
- return new Promise((resolve, reject) => {
204
- const install = spawn('bun', ['install'], {
205
- cwd, // Run from monorepo root to resolve all workspaces
206
- stdio: 'inherit',
207
- });
208
-
209
- install.on('close', (code) => {
210
- if (code === 0) {
211
- resolve();
212
- } else {
213
- reject(new Error(`Dependency installation failed with code ${code}`));
214
- }
215
- });
216
-
217
- install.on('error', reject);
218
- });
219
- }
220
-
221
- private cleanup(): void {
222
- if (this.viteProcess) {
223
- try {
224
- this.viteProcess.kill('SIGTERM');
225
- } catch (error) {
226
- // Ignore errors during cleanup
227
- }
228
- this.viteProcess = null;
229
- }
230
-
231
- if (this.bundlerInstanceDir) {
232
- try {
233
- rmSync(this.bundlerInstanceDir, { recursive: true, force: true });
234
- } catch {
235
- // Ignore cleanup errors.
236
- }
237
- this.bundlerInstanceDir = '';
238
- }
239
-
240
- this.releaseLock();
241
- }
242
-
243
- private sleep(ms: number): Promise<void> {
244
- return new Promise((resolve) => setTimeout(resolve, ms));
245
- }
246
-
247
- private acquireLock(port: number): void {
248
- if (existsSync(this.lockFilePath)) {
249
- try {
250
- const raw = readFileSync(this.lockFilePath, 'utf-8');
251
- const lock = JSON.parse(raw);
252
- if (lock?.pid && this.isProcessRunning(lock.pid)) {
253
- this.error(
254
- `A demo server is already running (port: ${lock.port ?? 'unknown'}, pid: ${
255
- lock.pid
256
- }). Stop it or use --port to run on a different port.`
257
- );
258
- }
259
- } catch (error) {
260
- // If the lock is unreadable, remove it and continue.
261
- }
262
-
263
- try {
264
- unlinkSync(this.lockFilePath);
265
- } catch {
266
- // Ignore cleanup errors.
267
- }
268
- }
269
-
270
- const lockInfo = {
271
- pid: process.pid,
272
- port,
273
- startedAt: new Date().toISOString(),
274
- };
275
- writeFileSync(this.lockFilePath, `${JSON.stringify(lockInfo, null, 2)}\n`);
276
- }
277
-
278
- private getLockFilePath(port: number): string {
279
- return path.join(process.cwd(), `.demo-server.${port}.lock`);
280
- }
281
-
282
- private createBundlerInstanceDir(port: number): string {
283
- // New run => new temp dir, so local cache is fresh after every restart.
284
- const instanceId = `demo-${port}-${process.pid}-${Date.now()}`;
285
- return path.join(tmpdir(), 'pie-element-demo-bundler', instanceId);
286
- }
287
-
288
- private releaseLock(): void {
289
- if (!existsSync(this.lockFilePath)) return;
290
- try {
291
- const raw = readFileSync(this.lockFilePath, 'utf-8');
292
- const lock = JSON.parse(raw);
293
- if (lock?.pid !== process.pid) return;
294
- } catch {
295
- // If parsing fails, still attempt to remove stale lock.
296
- }
297
-
298
- try {
299
- unlinkSync(this.lockFilePath);
300
- } catch {
301
- // Ignore cleanup errors.
302
- }
303
- }
304
-
305
- private isProcessRunning(pid: number): boolean {
306
- try {
307
- process.kill(pid, 0);
308
- return true;
309
- } catch {
310
- return false;
311
- }
312
- }
313
- }
@@ -1,345 +0,0 @@
1
- import { Command, Flags } from '@oclif/core';
2
- import { Logger } from '../../utils/logger.js';
3
- import {
4
- mkDependencyHash,
5
- generateEntries,
6
- createWebpackConfig,
7
- type BuildDependency,
8
- } from '@pie-element/bundler-shared';
9
- import webpack from 'webpack';
10
- import { execSync } from 'node:child_process';
11
- import { existsSync, readFileSync, rmSync, symlinkSync, mkdirSync, writeFileSync } from 'node:fs';
12
- import { tmpdir } from 'node:os';
13
- import { join } from 'node:path';
14
-
15
- export default class TestBundler extends Command {
16
- static override description = 'Test the PIE bundler service with local workspace packages';
17
-
18
- static override examples = [
19
- 'bun run cli <%= command.id %>',
20
- 'bun cli <%= command.id %>',
21
- '<%= config.bin %> <%= command.id %>',
22
- 'bun cli <%= command.id %> --element multiple-choice',
23
- 'bun cli <%= command.id %> --clean',
24
- ];
25
-
26
- static override flags = {
27
- element: Flags.string({
28
- char: 'e',
29
- description: 'Test with specific element (default: multiple-choice)',
30
- default: 'multiple-choice',
31
- }),
32
- clean: Flags.boolean({
33
- description: 'Clean test workspace before running',
34
- default: false,
35
- }),
36
- verbose: Flags.boolean({
37
- char: 'v',
38
- description: 'Show detailed output including webpack logs',
39
- default: false,
40
- }),
41
- 'keep-workspace': Flags.boolean({
42
- description: 'Keep workspace directory after test (for debugging)',
43
- default: false,
44
- }),
45
- };
46
-
47
- private logger!: Logger;
48
-
49
- public async run(): Promise<void> {
50
- const { flags } = await this.parse(TestBundler);
51
- this.logger = new Logger(flags.verbose);
52
-
53
- this.logger.section('🚀 Testing PIE Bundler with Workspace Packages');
54
-
55
- // Setup paths
56
- const workspaceRoot = join(tmpdir(), 'pie-bundler-workspace-test');
57
- const cacheDir = join(workspaceRoot, 'cache');
58
- const outputDir = join(workspaceRoot, 'output');
59
-
60
- if (flags.clean && existsSync(workspaceRoot)) {
61
- this.logger.info('Cleaning old workspace...');
62
- rmSync(workspaceRoot, { recursive: true, force: true });
63
- }
64
-
65
- mkdirSync(outputDir, { recursive: true });
66
- mkdirSync(cacheDir, { recursive: true });
67
-
68
- // Build local packages first
69
- this.log('\n📦 Building local packages');
70
- await this.buildLocalPackages(flags.element);
71
-
72
- // Create workspace with local packages
73
- this.log('\n🔗 Setting up test workspace');
74
- const workspaceDir = await this.setupWorkspace(workspaceRoot, flags.element);
75
-
76
- // Test the bundler - use workspaceDir instead of installing from NPM
77
- this.log('\n⚙️ Running bundler test');
78
-
79
- try {
80
- this.logger.info(`Building bundle for @pie-element/${flags.element}...`);
81
-
82
- // Call bundler directly without download step - workspace already has packages
83
- const result = await this.buildFromWorkspace(workspaceDir, outputDir, flags.element);
84
-
85
- if (flags.verbose) {
86
- this.log('\nBuild Result:');
87
- this.log(JSON.stringify(result, null, 2));
88
- }
89
-
90
- if (!result.success) {
91
- this.logger.error('Build failed');
92
- if (result.errors) {
93
- this.log('\nErrors:');
94
- for (const err of result.errors) {
95
- this.log(` - ${err}`);
96
- }
97
- }
98
- this.error('Bundler test failed', { exit: 1 });
99
- }
100
-
101
- // Verify results
102
- this.log('\n✓ Verifying bundles');
103
- await this.verifyBundles(outputDir, result.hash);
104
-
105
- // Summary
106
- this.log(`\n${'='.repeat(60)}`);
107
- this.log('✅ BUNDLER TEST PASSED');
108
- this.log('='.repeat(60));
109
- this.log(`Element: @pie-element/${flags.element}`);
110
- this.log(`Hash: ${result.hash}`);
111
- this.log(`Duration: ${result.duration}ms`);
112
- this.log(`Cached: ${result.cached ? 'Yes' : 'No'}`);
113
- this.log(`Bundle dir: ${join(outputDir, result.hash)}`);
114
-
115
- if (!flags['keep-workspace']) {
116
- this.logger.info('\nCleaning up workspace...');
117
- rmSync(workspaceRoot, { recursive: true, force: true });
118
- } else {
119
- this.log(`Workspace: ${workspaceRoot}`);
120
- }
121
-
122
- this.log('='.repeat(60));
123
- this.log('');
124
- } catch (error: any) {
125
- this.logger.error(`Test failed: ${error.message}`);
126
- if (flags.verbose) {
127
- this.log(error.stack);
128
- }
129
- this.error('Bundler test failed', { exit: 1 });
130
- }
131
- }
132
-
133
- private async buildLocalPackages(element: string): Promise<void> {
134
- const packages = ['packages/shared/mathquill', `packages/elements-react/${element}`];
135
-
136
- for (const pkg of packages) {
137
- if (!existsSync(pkg)) {
138
- this.logger.warn(`Package not found: ${pkg}`);
139
- continue;
140
- }
141
-
142
- this.logger.info(`Building ${pkg}...`);
143
- try {
144
- execSync('bun run build', {
145
- cwd: pkg,
146
- stdio: this.logger.isVerbose() ? 'inherit' : 'pipe',
147
- });
148
- } catch (error: any) {
149
- this.logger.warn(`Build failed for ${pkg}: ${error.message}`);
150
- }
151
- }
152
- }
153
-
154
- private async setupWorkspace(workspaceRoot: string, element: string): Promise<string> {
155
- const workspaceDir = join(workspaceRoot, 'workspace');
156
- const packagesDir = join(workspaceDir, 'packages');
157
-
158
- mkdirSync(packagesDir, { recursive: true });
159
-
160
- // Create workspace package.json with bundler dependencies
161
- writeFileSync(
162
- join(workspaceDir, 'package.json'),
163
- JSON.stringify(
164
- {
165
- name: 'pie-bundler-test-workspace',
166
- private: true,
167
- workspaces: [
168
- 'packages/*',
169
- 'packages/*/controller',
170
- 'packages/*/configure',
171
- 'packages/*/author',
172
- ],
173
- dependencies: {
174
- 'esbuild-loader': '^4.4.2',
175
- 'css-loader': '^7.1.2',
176
- 'style-loader': '^4.0.0',
177
- 'url-loader': '^4.1.1',
178
- },
179
- },
180
- null,
181
- 2
182
- )
183
- );
184
-
185
- // Symlink local packages
186
- const localPackages = {
187
- 'shared-mathquill': 'packages/shared/mathquill',
188
- [element]: `packages/elements-react/${element}`,
189
- };
190
-
191
- for (const [name, path] of Object.entries(localPackages)) {
192
- if (!existsSync(path)) {
193
- this.logger.warn(`Package not found: ${path}`);
194
- continue;
195
- }
196
-
197
- const linkPath = join(packagesDir, name);
198
- if (existsSync(linkPath)) {
199
- rmSync(linkPath, { recursive: true, force: true });
200
- }
201
-
202
- this.logger.info(`Linking ${name} → ${path}`);
203
- symlinkSync(join(process.cwd(), path), linkPath, 'dir');
204
- }
205
-
206
- // Install dependencies
207
- this.logger.info('Installing workspace dependencies...');
208
- try {
209
- execSync('bun install', {
210
- cwd: workspaceDir,
211
- stdio: this.logger.isVerbose() ? 'inherit' : 'pipe',
212
- });
213
- } catch (error: any) {
214
- this.logger.warn(`Workspace install had issues: ${error.message}`);
215
- }
216
-
217
- // Create symlinks in node_modules for @pie-element packages
218
- const nodeModulesDir = join(workspaceDir, 'node_modules');
219
- const pieElementDir = join(nodeModulesDir, '@pie-element');
220
- mkdirSync(pieElementDir, { recursive: true });
221
-
222
- // Link shared-mathquill
223
- const mathquillLink = join(pieElementDir, 'shared-mathquill');
224
- if (existsSync(mathquillLink)) {
225
- rmSync(mathquillLink, { recursive: true, force: true });
226
- }
227
- symlinkSync(join(packagesDir, 'shared-mathquill'), mathquillLink, 'dir');
228
- this.logger.info('Linked @pie-element/shared-mathquill in node_modules');
229
-
230
- // Link element package
231
- const elementLink = join(pieElementDir, element);
232
- if (existsSync(elementLink)) {
233
- rmSync(elementLink, { recursive: true, force: true });
234
- }
235
- symlinkSync(join(packagesDir, element), elementLink, 'dir');
236
- this.logger.info(`Linked @pie-element/${element} in node_modules`);
237
-
238
- return workspaceDir;
239
- }
240
-
241
- private async buildFromWorkspace(
242
- workspaceDir: string,
243
- outputDir: string,
244
- element: string
245
- ): Promise<any> {
246
- const dependencies: BuildDependency[] = [{ name: `@pie-element/${element}`, version: '0.1.0' }];
247
- const hash = mkDependencyHash(dependencies);
248
- const startTime = Date.now();
249
-
250
- this.logger.info(`Bundle hash: ${hash}`);
251
-
252
- // Generate entry files
253
- const entryDir = join(workspaceDir, 'entries');
254
- mkdirSync(entryDir, { recursive: true });
255
-
256
- const requestedBundles: Array<'player' | 'client-player' | 'editor'> = [
257
- 'player',
258
- 'client-player',
259
- 'editor',
260
- ];
261
- const entries = generateEntries(dependencies, workspaceDir, requestedBundles);
262
-
263
- writeFileSync(join(entryDir, 'player.js'), entries.player || '');
264
- writeFileSync(join(entryDir, 'client-player.js'), entries['client-player'] || '');
265
- writeFileSync(join(entryDir, 'editor.js'), entries.editor || '');
266
-
267
- // Create webpack config
268
- const bundleOutputPath = join(outputDir, hash);
269
- mkdirSync(bundleOutputPath, { recursive: true });
270
-
271
- const webpackConfig = createWebpackConfig({
272
- context: entryDir,
273
- entry: {
274
- player: join(entryDir, 'player.js'),
275
- 'client-player': join(entryDir, 'client-player.js'),
276
- editor: join(entryDir, 'editor.js'),
277
- },
278
- outputPath: bundleOutputPath,
279
- workspaceDir,
280
- elements: dependencies.map((d) => d.name.split('/')[1]),
281
- });
282
-
283
- // Add repo's node_modules to webpack resolve paths for workspace testing
284
- if (!webpackConfig.resolve) webpackConfig.resolve = {};
285
- if (!webpackConfig.resolve.modules) webpackConfig.resolve.modules = [];
286
- webpackConfig.resolve.modules.push(join(process.cwd(), 'node_modules'));
287
-
288
- // Run webpack
289
- return new Promise((resolve, reject) => {
290
- webpack(webpackConfig, (err: any, stats: any) => {
291
- if (err) {
292
- reject(err);
293
- return;
294
- }
295
-
296
- if (stats?.hasErrors()) {
297
- const errors = stats.toString({ colors: false, errorDetails: true });
298
- reject(new Error(errors));
299
- return;
300
- }
301
-
302
- resolve({
303
- success: true,
304
- hash,
305
- bundles: {
306
- player: `/bundles/${hash}/player.js`,
307
- clientPlayer: `/bundles/${hash}/client-player.js`,
308
- editor: `/bundles/${hash}/editor.js`,
309
- },
310
- duration: Date.now() - startTime,
311
- cached: false,
312
- });
313
- });
314
- });
315
- }
316
-
317
- private async verifyBundles(outputDir: string, hash: string): Promise<void> {
318
- const bundleDir = join(outputDir, hash);
319
- const files = ['player.js', 'client-player.js', 'editor.js'];
320
-
321
- let allOk = true;
322
-
323
- for (const file of files) {
324
- const filePath = join(bundleDir, file);
325
- if (!existsSync(filePath)) {
326
- this.logger.error(`❌ ${file} not found`);
327
- allOk = false;
328
- continue;
329
- }
330
-
331
- const content = readFileSync(filePath, 'utf-8');
332
- const size = (content.length / 1024).toFixed(1);
333
- this.logger.success(`✅ ${file} (${size} KB)`);
334
-
335
- // Verify IIFE format for player bundle
336
- if (file === 'player.js' && !content.includes('window.pie')) {
337
- this.logger.warn(`⚠️ ${file} doesn't contain window.pie`);
338
- }
339
- }
340
-
341
- if (!allOk) {
342
- this.error('Bundle verification failed', { exit: 1 });
343
- }
344
- }
345
- }