@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,259 @@
1
+ import { Command, Flags } from '@oclif/core';
2
+ import { Logger } from '../../utils/logger.js';
3
+ import { existsSync } from 'node:fs';
4
+ import { readdir, readFile, writeFile, stat as fsStat } from 'node:fs/promises';
5
+ import { join } from 'node:path';
6
+
7
+ const ELEMENTS_REACT_DIR = 'packages/elements-react';
8
+ const PIE_ELEMENTS_DIR = '../pie-elements/packages';
9
+
10
+ interface PackageTemplate {
11
+ name: string;
12
+ private: boolean;
13
+ version: string;
14
+ description: string;
15
+ type: string;
16
+ main: string;
17
+ types: string;
18
+ exports: Record<string, unknown>;
19
+ files: string[];
20
+ scripts: Record<string, string>;
21
+ dependencies: Record<string, string>;
22
+ peerDependencies: Record<string, string>;
23
+ devDependencies: Record<string, string>;
24
+ keywords: string[];
25
+ license: string;
26
+ repository: {
27
+ type: string;
28
+ url: string;
29
+ directory: string;
30
+ };
31
+ }
32
+
33
+ export default class InitSyncedElements extends Command {
34
+ static override description =
35
+ 'Initialize package.json and vite.config.ts files for synced React elements';
36
+
37
+ static override examples = [
38
+ '<%= config.bin %> <%= command.id %>',
39
+ '<%= config.bin %> <%= command.id %> --element=categorize',
40
+ '<%= config.bin %> <%= command.id %> --dry-run',
41
+ ];
42
+
43
+ static override flags = {
44
+ element: Flags.string({
45
+ description: 'Initialize only specified element',
46
+ }),
47
+ 'dry-run': Flags.boolean({
48
+ description: 'Show what would be created without making changes',
49
+ default: false,
50
+ }),
51
+ verbose: Flags.boolean({
52
+ char: 'v',
53
+ description: 'Show detailed output',
54
+ default: false,
55
+ }),
56
+ };
57
+
58
+ private logger = new Logger();
59
+
60
+ public async run(): Promise<void> {
61
+ const { flags } = await this.parse(InitSyncedElements);
62
+
63
+ this.logger = new Logger(flags.verbose);
64
+
65
+ this.logger.section('🔧 Initializing synced React elements');
66
+
67
+ if (flags['dry-run']) {
68
+ this.logger.info(' Mode: DRY RUN\n');
69
+ }
70
+
71
+ const elements = await readdir(ELEMENTS_REACT_DIR);
72
+ let created = 0;
73
+ let skipped = 0;
74
+
75
+ for (const element of elements) {
76
+ // Skip if filtering by element and this isn't it
77
+ if (flags.element && element !== flags.element) {
78
+ continue;
79
+ }
80
+
81
+ const elementDir = join(ELEMENTS_REACT_DIR, element);
82
+
83
+ // Skip if not a directory
84
+ const statResult = await fsStat(elementDir).catch(() => null);
85
+ if (!statResult?.isDirectory()) {
86
+ continue;
87
+ }
88
+
89
+ // Skip if src directory doesn't exist
90
+ if (!existsSync(join(elementDir, 'src'))) {
91
+ continue;
92
+ }
93
+
94
+ const packageJsonPath = join(elementDir, 'package.json');
95
+
96
+ // Skip if package.json already exists
97
+ if (existsSync(packageJsonPath)) {
98
+ if (flags.verbose) {
99
+ this.logger.info(` ⏭️ ${element}: package.json already exists`);
100
+ }
101
+ skipped++;
102
+ continue;
103
+ }
104
+
105
+ // Read upstream package.json
106
+ const upstreamPkg = await this.readUpstreamPackageJson(element);
107
+ if (!upstreamPkg) {
108
+ this.logger.warn(` ⚠️ ${element}: Could not read upstream package.json`);
109
+ continue;
110
+ }
111
+
112
+ // Generate package.json
113
+ const pkg = this.generatePackageJson(element, upstreamPkg);
114
+
115
+ if (!flags['dry-run']) {
116
+ await writeFile(packageJsonPath, `${JSON.stringify(pkg, null, 2)}\n`, 'utf-8');
117
+ this.logger.success(` ✨ ${element}: Created package.json`);
118
+ } else {
119
+ this.logger.info(` 🔍 ${element}: Would create package.json`);
120
+ }
121
+
122
+ // Generate vite.config.ts
123
+ const viteConfigPath = join(elementDir, 'vite.config.ts');
124
+ if (!existsSync(viteConfigPath)) {
125
+ if (!flags['dry-run']) {
126
+ await writeFile(viteConfigPath, this.generateViteConfig(), 'utf-8');
127
+ this.logger.success(` ✨ ${element}: Created vite.config.ts`);
128
+ } else {
129
+ this.logger.info(` 🔍 ${element}: Would create vite.config.ts`);
130
+ }
131
+ }
132
+
133
+ created++;
134
+ }
135
+
136
+ this.logger.section(
137
+ `\n📊 Summary: ${created} ${flags['dry-run'] ? 'would be created' : 'created'}, ${skipped} skipped`
138
+ );
139
+ }
140
+
141
+ private async readUpstreamPackageJson(
142
+ elementName: string
143
+ ): Promise<Record<string, unknown> | null> {
144
+ const upstreamPath = join(PIE_ELEMENTS_DIR, elementName, 'package.json');
145
+
146
+ if (!existsSync(upstreamPath)) {
147
+ return null;
148
+ }
149
+
150
+ try {
151
+ const content = await readFile(upstreamPath, 'utf-8');
152
+ return JSON.parse(content);
153
+ } catch {
154
+ return null;
155
+ }
156
+ }
157
+
158
+ private generatePackageJson(
159
+ elementName: string,
160
+ upstreamPkg: Record<string, unknown>
161
+ ): PackageTemplate {
162
+ const deps: Record<string, string> = {};
163
+
164
+ // Map upstream dependencies to workspace:* for @pie-lib packages
165
+ const upstreamDeps = upstreamPkg.dependencies as Record<string, string> | undefined;
166
+ if (upstreamDeps) {
167
+ for (const [name] of Object.entries(upstreamDeps)) {
168
+ if (name.startsWith('@pie-lib/')) {
169
+ deps[name] = 'workspace:*';
170
+ } else if (!name.startsWith('react') && name !== 'react-dom') {
171
+ deps[name] = '*';
172
+ }
173
+ }
174
+ }
175
+
176
+ return {
177
+ name: `@pie-element/${elementName}`,
178
+ private: true,
179
+ version: '0.1.0',
180
+ description: `React implementation of ${elementName} element synced from pie-elements`,
181
+ type: 'module',
182
+ main: './dist/index.js',
183
+ types: './dist/index.d.ts',
184
+ exports: {
185
+ '.': {
186
+ types: './dist/index.d.ts',
187
+ default: './dist/index.js',
188
+ },
189
+ },
190
+ files: ['dist', 'src'],
191
+ scripts: {
192
+ dev: 'vite',
193
+ build: 'vite build && tsc --emitDeclarationOnly',
194
+ test: 'vitest run',
195
+ lint: 'biome check .',
196
+ 'lint:fix': 'biome check --write .',
197
+ },
198
+ dependencies: deps,
199
+ peerDependencies: {
200
+ react: '^18.0.0',
201
+ 'react-dom': '^18.0.0',
202
+ },
203
+ devDependencies: {
204
+ '@types/react': '^18.2.0',
205
+ '@types/react-dom': '^18.2.0',
206
+ '@vitejs/plugin-react': '^4.2.0',
207
+ typescript: '^5.9.3',
208
+ vite: '^6.0.0',
209
+ vitest: '^2.1.0',
210
+ },
211
+ keywords: ['pie', 'pie-element', 'react', 'assessment', elementName],
212
+ license: 'ISC',
213
+ repository: {
214
+ type: 'git',
215
+ url: 'https://github.com/pie-framework/pie-elements-ng.git',
216
+ directory: `packages/elements-react/${elementName}`,
217
+ },
218
+ };
219
+ }
220
+
221
+ private generateViteConfig(): string {
222
+ return `import { resolve } from 'node:path';
223
+ import react from '@vitejs/plugin-react';
224
+ import { defineConfig } from 'vite';
225
+
226
+ export default defineConfig({
227
+ plugins: [react()],
228
+ build: {
229
+ lib: {
230
+ entry: {
231
+ index: resolve(__dirname, 'src/index.ts'),
232
+ },
233
+ formats: ['es'],
234
+ },
235
+ rollupOptions: {
236
+ external: (id) => {
237
+ return (
238
+ /^react($|\\/)/.test(id) ||
239
+ /^react-dom($|\\/)/.test(id) ||
240
+ /^@pie-lib\\//.test(id) ||
241
+ /^@pie-element\\//.test(id) ||
242
+ /^@pie-framework\\//.test(id) ||
243
+ /^@mui\\//.test(id) ||
244
+ /^d3-/.test(id) ||
245
+ id === 'lodash' ||
246
+ /^lodash\\//.test(id) ||
247
+ ['prop-types', 'classnames', 'debug'].includes(id)
248
+ );
249
+ },
250
+ output: {
251
+ preserveModules: true,
252
+ preserveModulesRoot: 'src',
253
+ },
254
+ },
255
+ },
256
+ });
257
+ `;
258
+ }
259
+ }
@@ -0,0 +1,444 @@
1
+ # Upstream Commands
2
+
3
+ This directory contains commands for managing the synchronization between the upstream PIE repositories and this project.
4
+
5
+ **Audience:** These commands are for maintainers who sync from upstream. Regular developers don't need these commands - synced packages are already committed to git, so just `git pull` to get updates.
6
+
7
+ ## Overview
8
+
9
+ The PIE Elements NG project syncs code from two upstream repositories:
10
+
11
+ - **pie-elements** - Contains element controllers and React components
12
+ - **pie-lib** - Contains shared library packages
13
+
14
+ These commands help manage that synchronization process, analyze ESM compatibility, and track what's been synced.
15
+
16
+ Synced packages (`packages/elements-react/*` and `packages/lib-react/*`) are committed to git, so regular developers can work without checking out the upstream repositories.
17
+
18
+ At a high level, the update workflow does more than copy files. It:
19
+
20
+ - Filters upstream packages via ESM compatibility analysis
21
+ - Syncs controllers, React UI, and pie-lib sources into local packages
22
+ - Converts source files to TypeScript (`.js`→`.ts`, `.jsx`→`.tsx`)
23
+ - Rewrites package metadata (exports, entrypoints, sideEffects)
24
+ - Generates element-specific Vite config and demo metadata
25
+ - Cleans workspace deps and installs updated dependencies
26
+
27
+ ## Commands
28
+
29
+ ### `update` (Recommended)
30
+
31
+ **The main command you should use!** Combines ESM analysis and syncing in one step.
32
+
33
+ **Usage:**
34
+
35
+ ```bash
36
+ # Update everything (analyze + sync)
37
+ bun cli upstream:update
38
+
39
+ # Dry run to see what would change
40
+ bun cli upstream:update --dry-run
41
+
42
+ # Update specific element
43
+ bun cli upstream:update --element=multiple-choice
44
+
45
+ # Verbose output
46
+ bun cli upstream:update --verbose
47
+ ```
48
+
49
+ **What it does:**
50
+
51
+ 1. **Analyzes** ESM compatibility of all upstream packages
52
+ 2. **Syncs** all compatible packages automatically
53
+ 3. **Builds** touched packages (unless --skip-build)
54
+
55
+ This is the recommended workflow as it ensures the analysis is always fresh before syncing.
56
+
57
+ ---
58
+
59
+ ### `analyze-esm`
60
+
61
+ Analyzes ESM compatibility of upstream packages to determine what can be safely synced.
62
+
63
+ **When to use:** When you only want to check compatibility without syncing, or for debugging.
64
+
65
+ **Usage:**
66
+
67
+ ```bash
68
+ # Analyze all packages
69
+ bun cli upstream:analyze-esm
70
+
71
+ # Verbose output with dependency details
72
+ bun cli upstream:analyze-esm --verbose
73
+
74
+ # Include dev dependencies in analysis
75
+ bun cli upstream:analyze-esm --include-dev-deps
76
+
77
+ # Validate with runtime checks
78
+ bun cli upstream:analyze-esm --validate
79
+ ```
80
+
81
+ **What it does:**
82
+
83
+ 1. Scans all upstream packages for ESM blockers (CommonJS-only dependencies)
84
+ 2. Checks element-to-element dependencies for transitive compatibility
85
+ 3. Tracks @pie-lib dependencies used by elements
86
+ 4. Generates compatibility report at `.compatibility/report.json`
87
+ 5. Optional: Runtime validation by actually loading packages
88
+
89
+ **Output:**
90
+
91
+ - Lists ESM-compatible elements
92
+ - Lists blocked elements with reasons
93
+ - Shows @pie-lib package compatibility
94
+ - Provides recommendations for fixing issues
95
+
96
+ **Why run this first?**
97
+ The sync command uses this report to automatically filter out incompatible packages, ensuring you only sync elements that will work as ESM modules.
98
+
99
+ ### `sync`
100
+
101
+ Synchronizes ESM-compatible code from upstream repositories to this project.
102
+
103
+ **When to use:** When you've already run `analyze-esm` and want to sync without re-analyzing, or for advanced workflows.
104
+
105
+ **Usage:**
106
+
107
+ ```bash
108
+ # Sync everything (automatically filters to ESM-compatible packages)
109
+ bun cli upstream:sync
110
+
111
+ # Dry run to see what would change
112
+ bun cli upstream:sync --dry-run
113
+
114
+ # Sync specific element
115
+ bun cli upstream:sync --element=multiple-choice
116
+
117
+ # Verbose output
118
+ bun cli upstream:sync --verbose
119
+ ```
120
+
121
+ **What it does:**
122
+
123
+ 1. **Reads compatibility report** from `analyze-esm` to filter packages
124
+ 2. **Controllers**: Syncs from `pie-elements/packages/{element}/controller/src/` to `packages/elements-react/{element}/src/controller/`
125
+ 3. **React Components**: Syncs from `pie-elements/packages/{element}/src/` to `packages/elements-react/{element}/src/`
126
+ 4. **Pie-Lib**: Syncs from `pie-lib/packages/{package}/src/` to `packages/lib-react/{package}/src/`
127
+ 5. **Conversions**: Automatically converts `.js` → `.ts` and `.jsx` → `.tsx`
128
+ 6. **Package.json**: Generates ESM-compatible package.json with proper exports
129
+ 7. **Build**: Automatically builds touched packages after sync
130
+
131
+ **Strategy Pattern:**
132
+ The sync command uses the strategy pattern for clean separation:
133
+
134
+ - `ControllersStrategy` - Handles controller syncing
135
+ - `ReactComponentsStrategy` - Handles React component syncing
136
+ - `PieLibStrategy` - Handles pie-lib package syncing
137
+
138
+ Each strategy is self-contained and independently testable.
139
+
140
+ ### `track`
141
+
142
+ Tracks synced packages and their upstream status.
143
+
144
+ **Usage:**
145
+
146
+ ```bash
147
+ # Show sync status for all packages
148
+ bun cli upstream:track
149
+
150
+ # Check specific element
151
+ bun cli upstream:track --element=multiple-choice
152
+ ```
153
+
154
+ **What it does:**
155
+
156
+ 1. Shows which packages have been synced
157
+ 2. Displays upstream commit hash for each package
158
+ 3. Identifies packages that may need updates
159
+
160
+ ## Workflow
161
+
162
+ ### Initial Setup (Maintainers Only)
163
+
164
+ **Note:** Only needed if you're a maintainer syncing from upstream. Regular developers can skip this.
165
+
166
+ 1. Clone the upstream repositories as siblings to this repo:
167
+
168
+ ```bash
169
+ cd /path/to/projects
170
+ git clone https://github.com/PieLabs/pie-elements.git
171
+ git clone https://github.com/PieLabs/pie-lib.git
172
+ git clone https://github.com/pie-framework/pie-elements-ng.git
173
+ cd pie-elements-ng
174
+ ```
175
+
176
+ 2. Run initial analysis to see what's available:
177
+
178
+ ```bash
179
+ bun cli upstream:analyze-esm --verbose
180
+ ```
181
+
182
+ ### Regular Update Workflow (Simple)
183
+
184
+ The simplest workflow using the combined `update` command:
185
+
186
+ 1. **Pull upstream changes:**
187
+
188
+ ```bash
189
+ cd ../pie-elements && git pull
190
+ cd ../pie-lib && git pull
191
+ cd ../pie-element
192
+ ```
193
+
194
+ 2. **Check what would change** (dry run):
195
+
196
+ ```bash
197
+ bun cli upstream:update --dry-run --verbose
198
+ ```
199
+
200
+ 3. **Update everything:**
201
+
202
+ ```bash
203
+ bun cli upstream:update
204
+ ```
205
+
206
+ 4. **Review, test, and commit:**
207
+
208
+ ```bash
209
+ git diff
210
+ bun test
211
+ git add .
212
+ git commit -m "sync: update from upstream"
213
+ git push
214
+ ```
215
+
216
+ ### Incremental Update Workflow (Safer)
217
+
218
+ For testing changes to individual elements first:
219
+
220
+ 1. **Pull upstream changes:**
221
+
222
+ ```bash
223
+ cd ../pie-elements && git pull
224
+ cd ../pie-lib && git pull
225
+ cd ../pie-element
226
+ ```
227
+
228
+ 2. **Update specific element** (with dry run first):
229
+
230
+ ```bash
231
+ bun cli upstream:update --element=multiple-choice --dry-run
232
+ bun cli upstream:update --element=multiple-choice
233
+ ```
234
+
235
+ 3. **Test the element:**
236
+
237
+ ```bash
238
+ bun test packages/elements-react/multiple-choice
239
+ ```
240
+
241
+ 4. **If good, update all:**
242
+
243
+ ```bash
244
+ bun cli upstream:update
245
+ ```
246
+
247
+ 5. **Commit and push:**
248
+
249
+ ```bash
250
+ git add .
251
+ git commit -m "sync: update from upstream"
252
+ git push
253
+ ```
254
+
255
+ ### Working with Blocked Elements
256
+
257
+ If an element is blocked from ESM compatibility:
258
+
259
+ 1. **Check why it's blocked:**
260
+
261
+ ```bash
262
+ bun cli upstream:analyze-esm --verbose | grep element-name
263
+ ```
264
+
265
+ 2. **Common blockers:**
266
+ - `lodash` → Replace with native JS or `lodash-es`
267
+ - `react-dnd` → Upgrade to v16+ (ESM compatible)
268
+ - Sibling dependencies → Fix the dependency first
269
+
270
+ 3. **Fix in upstream** (preferred):
271
+ - Create PR in pie-elements to fix the blocker
272
+ - Wait for merge
273
+ - Re-analyze and sync
274
+
275
+ 4. **Fix locally** (if urgent):
276
+ - Sync the element
277
+ - Manually fix the blocker in the local copy
278
+ - Document the change
279
+ - Create upstream PR later
280
+
281
+ ## Advanced Features
282
+
283
+ ### Always-Include Pie-Lib Packages
284
+
285
+ Some @pie-lib packages (like `controller-utils`) are imported directly in controller code but not declared in element package.json files. To ensure these are always synced, they're defined in the `ALWAYS_INCLUDE_PIE_LIB` constant in [analyze-esm.ts](./analyze-esm.ts):
286
+
287
+ ```typescript
288
+ // PIE lib packages that should always be included if compatible
289
+ // These are packages that may be imported directly in code (e.g., controllers)
290
+ // but not declared in package.json dependencies
291
+ const ALWAYS_INCLUDE_PIE_LIB = [
292
+ "controller-utils", // Used in controller code via direct imports
293
+ ];
294
+ ```
295
+
296
+ **When to add a package here:**
297
+
298
+ - Package is imported in controller/component code
299
+ - Package is NOT in element package.json dependencies
300
+ - Package should be available for all elements that need it
301
+
302
+ ### Element-Specific Build Configuration
303
+
304
+ Some elements require special vite configuration (e.g., bundling specific dependencies instead of externalizing them). This is handled automatically by [sync-react-strategy.ts](./sync-react-strategy.ts).
305
+
306
+ #### Konva Bundling Example
307
+
308
+ Elements using konva/react-konva (like hotspot, drawing-response) bundle these libraries instead of externalizing them to avoid runtime resolution issues with transitive dependencies:
309
+
310
+ ```typescript
311
+ // In sync-react-strategy.ts
312
+ const konvaElements = ["hotspot", "drawing-response"];
313
+ const shouldBundleKonva = konvaElements.includes(elementName);
314
+ ```
315
+
316
+ This generates a special vite.config.ts that:
317
+
318
+ - Bundles konva, react-konva, scheduler, and react-reconciler (not externalized)
319
+ - Uses `preserveModules: true` to maintain proper import statements for other externals
320
+ - Avoids CDN import map issues with complex dependency chains while preserving lodash imports
321
+
322
+ **When to add an element to konvaElements:**
323
+
324
+ - Element imports konva or react-konva
325
+ - Seeing "schedulerExports is not defined" or similar runtime errors
326
+ - Dependencies have complex transitive chains not suitable for CDN loading
327
+
328
+ **Why bundle instead of externalize?**
329
+
330
+ - Element-specific libraries (only 2-3 elements use konva)
331
+ - Complex transitive dependencies (scheduler, react-reconciler)
332
+ - CDN (esm.sh) import paths don't match local import maps
333
+ - Better reliability and performance for specialized packages
334
+
335
+ ### Demo Mode Configuration
336
+
337
+ Elements with a `docs/demo` directory automatically get demo mode support in their vite.config.ts:
338
+
339
+ ```typescript
340
+ export default defineConfig(({ mode, command }) => ({
341
+ plugins: [react()],
342
+ // Only change root for demo mode when serving (not building)
343
+ root:
344
+ mode === "demo" && command === "serve"
345
+ ? resolve(__dirname, "docs/demo")
346
+ : __dirname,
347
+ // ... rest of config
348
+ }));
349
+ ```
350
+
351
+ This allows running `bun run demo` in the element package to serve the demo application.
352
+
353
+ ## File Organization
354
+
355
+ ```
356
+ tools/cli/src/commands/upstream/
357
+ ├── README.md # This file
358
+ ├── update.ts # Combined update command (recommended)
359
+ ├── analyze-esm.ts # ESM compatibility analyzer
360
+ ├── sync.ts # Sync command (orchestration)
361
+ ├── track.ts # Package tracking command
362
+ ├── sync-strategy.ts # Strategy interface
363
+ ├── sync-controllers-strategy.ts # Controller sync strategy
364
+ ├── sync-react-strategy.ts # React component sync strategy
365
+ ├── sync-pielib-strategy.ts # Pie-lib sync strategy
366
+ ├── sync-filesystem.ts # File system utilities
367
+ ├── sync-package-json.ts # Package.json utilities
368
+ ├── sync-vite-config.ts # Vite config generation
369
+ ├── sync-demo.ts # Demo generation utilities
370
+ └── sync-imports.ts # Import fixing utilities
371
+ ```
372
+
373
+ ## Best Practices
374
+
375
+ ### Do's ✅
376
+
377
+ - **Always dry-run first** to see what will change
378
+ - **Sync one element at a time** when testing
379
+ - **Review diffs carefully** before committing
380
+ - **Test after syncing** to ensure functionality
381
+ - **Keep upstream siblings up to date** (git pull regularly)
382
+ - **Use ESM-compatible dependencies** to unblock packages
383
+ - **Document breaking changes** in commit messages
384
+
385
+ ### Don'ts ❌
386
+
387
+ - **Don't modify synced files directly** - changes will be overwritten on next sync
388
+ - **Don't skip the build** - it catches issues early
389
+ - **Don't force-sync incompatible elements** - they won't work as ESM
390
+ - **Don't commit without testing** - broken elements affect everyone
391
+ - **Don't sync without upstream being clean** - use stable commits
392
+
393
+ ## Troubleshooting
394
+
395
+ ### Sync fails with "file not found"
396
+
397
+ Check that upstream repositories are at the expected locations:
398
+
399
+ ```bash
400
+ ls -la ../pie-elements ../pie-lib
401
+ ```
402
+
403
+ ### Build fails after sync
404
+
405
+ 1. Check if dependencies changed in upstream package.json
406
+ 2. Run `bun install` to update dependencies
407
+ 3. Check for TypeScript errors in synced files
408
+
409
+ ### Element marked as incompatible
410
+
411
+ Run detailed analysis:
412
+
413
+ ```bash
414
+ bun cli upstream:analyze-esm --verbose --element=element-name
415
+ ```
416
+
417
+ Fix the blockers (see "Working with Blocked Elements" above).
418
+
419
+ ### Import errors after sync
420
+
421
+ The sync automatically fixes default exports, but some edge cases may require manual fixes:
422
+
423
+ ```typescript
424
+ // If you see errors like "X is not exported from Y"
425
+ // Check if the import needs to be a named import
426
+ import { something } from "./file"; // Instead of default import
427
+ ```
428
+
429
+ ## Contributing
430
+
431
+ When adding new functionality to the sync process:
432
+
433
+ 1. **Utilities** → Add to appropriate utility file (sync-\*.ts)
434
+ 2. **New sync type** → Create a new strategy file
435
+ 3. **Strategy changes** → Modify the specific strategy file
436
+ 4. **Orchestration** → Update sync.ts (main command)
437
+
438
+ Keep the strategy pattern clean - each strategy should be self-contained.
439
+
440
+ ## Related Documentation
441
+
442
+ - [REFACTORING.md](../../REFACTORING.md) - Details on the refactoring work
443
+ - [Main CLI README](../../../README.md) - General CLI usage
444
+ - [UPSTREAM_SYNC_GUIDE.md](../../../../../docs/migration/UPSTREAM_SYNC_GUIDE.md) - Detailed sync guide