@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,945 +0,0 @@
1
- /**
2
- * React components sync strategy - syncs React components from upstream pie-elements
3
- *
4
- * Synced from: pie-elements/packages/{element}/src/
5
- * Target: packages/elements-react/{element}/src/
6
- */
7
-
8
- import { existsSync } from 'node:fs';
9
- import { mkdir, readFile, stat as fsStat, writeFile, rm as fsRm } 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, existsAny, readdir } from './sync-filesystem.js';
15
- import { createExternalFunction, createKonvaExternalFunction } from './sync-externals.js';
16
- import { fixImportsInFile, containsJsx } from './sync-imports.js';
17
- import { createReactComponentTransformPipeline } from './sync-transforms.js';
18
- import { ensureElementPackageJson } from './sync-package-manager.js';
19
- import { isSubdirectoryCompatible } from './sync-compatibility.js';
20
- import { EXCLUDED_UPSTREAM_ELEMENTS } from './sync-constants.js';
21
-
22
- interface InternalSyncResult {
23
- filesChecked: number;
24
- filesCopied: number;
25
- filesSkipped: number;
26
- filesUpdated: number;
27
- }
28
-
29
- export class ReactComponentsStrategy implements SyncStrategy {
30
- private touchedElementPackages = new Set<string>();
31
- private result: InternalSyncResult = {
32
- filesChecked: 0,
33
- filesCopied: 0,
34
- filesSkipped: 0,
35
- filesUpdated: 0,
36
- };
37
-
38
- getName(): string {
39
- return 'react-components';
40
- }
41
-
42
- getDescription(): string {
43
- return 'React components';
44
- }
45
-
46
- shouldRun(config: SyncConfig): boolean {
47
- return config.syncReactComponents;
48
- }
49
-
50
- async execute(context: SyncContext): Promise<SyncResult> {
51
- const { config, logger } = context;
52
- this.touchedElementPackages.clear();
53
- this.result = {
54
- filesChecked: 0,
55
- filesCopied: 0,
56
- filesSkipped: 0,
57
- filesUpdated: 0,
58
- };
59
-
60
- if (!logger.isVerbose()) {
61
- logger.progressStart('Syncing React components...');
62
- } else {
63
- logger.section('⚛️ Syncing React components');
64
- }
65
-
66
- const upstreamElementsDir = join(config.pieElements, 'packages');
67
- const targetBaseDir = join(config.pieElementsNg, 'packages/elements-react');
68
-
69
- const upstreamCommit = getCurrentCommit(config.pieElements);
70
-
71
- const packages = await readdir(upstreamElementsDir);
72
-
73
- for (const pkg of packages) {
74
- if (EXCLUDED_UPSTREAM_ELEMENTS.includes(pkg as (typeof EXCLUDED_UPSTREAM_ELEMENTS)[number])) {
75
- continue;
76
- }
77
-
78
- if (context.packageFilter && pkg !== context.packageFilter) {
79
- continue;
80
- }
81
-
82
- // Check if element is in compatibility report (ESM-compatible)
83
- if (context.compatibilityReport) {
84
- if (!context.compatibilityReport.elements.includes(pkg)) {
85
- continue; // Skip non-compatible elements
86
- }
87
-
88
- // Check if student UI (src/) is ESM-compatible
89
- if (!isSubdirectoryCompatible(pkg, 'src', context)) {
90
- if (logger.isVerbose()) {
91
- logger.info(` ⏭️ ${pkg}: skipping src/ (not ESM-compatible)`);
92
- }
93
- continue;
94
- }
95
- }
96
-
97
- // Check if React component exists upstream (src/ directory)
98
- const componentSrcDir = join(upstreamElementsDir, pkg, 'src');
99
- if (!existsSync(componentSrcDir)) {
100
- continue;
101
- }
102
-
103
- // Target: packages/elements-react/{element}/src/
104
- const targetDir = join(targetBaseDir, pkg);
105
- const targetSrcDir = join(targetDir, 'src');
106
-
107
- // Clean target src subtree first so removed upstream files don't linger
108
- // BUT: preserve controller/ subdirectory if it exists (synced separately)
109
- await this.cleanTargetDirExcept(
110
- targetSrcDir,
111
- ['controller'],
112
- `elements-react/${pkg}/src`,
113
- logger
114
- );
115
-
116
- // Recursively sync all files from src/ directory to delivery/ subdirectory
117
- const beforeChanges = this.result.filesCopied + this.result.filesUpdated;
118
- const targetDeliveryDir = join(targetDir, 'src/delivery');
119
- let elementFilesProcessed = await this.syncDirectory(
120
- componentSrcDir,
121
- targetDeliveryDir,
122
- 'src',
123
- pkg,
124
- upstreamCommit
125
- );
126
-
127
- // Also sync configure/ if it exists and is ESM-compatible
128
- // Note: Renamed to author/ in the target directory
129
- const configureDir = join(upstreamElementsDir, pkg, 'configure');
130
- if (existsSync(configureDir)) {
131
- // Check if configure subdirectory is ESM-compatible
132
- const configureCompatible = isSubdirectoryCompatible(pkg, 'configure', context);
133
- if (configureCompatible) {
134
- // First, sync configure/src/ -> src/author/
135
- const configureSrcDir = join(configureDir, 'src');
136
- if (existsSync(configureSrcDir)) {
137
- const targetAuthorDir = join(targetDir, 'src/author');
138
- const configureFilesProcessed = await this.syncDirectory(
139
- configureSrcDir,
140
- targetAuthorDir,
141
- 'configure/src',
142
- pkg,
143
- upstreamCommit
144
- );
145
- elementFilesProcessed += configureFilesProcessed;
146
- }
147
-
148
- // Then, sync configure/*.js files (not in subdirectories) -> src/author/
149
- // These are utility files that live directly in configure/ like utils.js
150
- const targetAuthorDir = join(targetDir, 'src/author');
151
- const configureRootFilesProcessed = await this.syncConfigureRootFiles(
152
- configureDir,
153
- targetAuthorDir,
154
- pkg,
155
- upstreamCommit
156
- );
157
- elementFilesProcessed += configureRootFilesProcessed;
158
- } else if (logger.isVerbose()) {
159
- logger.info(` ⏭️ ${pkg}: skipping configure/ (not ESM-compatible)`);
160
- }
161
- }
162
-
163
- // Sync print file if it exists (src/print.js -> src/print/index.ts)
164
- const upstreamPrintFile = join(componentSrcDir, 'print.js');
165
- if (existsSync(upstreamPrintFile)) {
166
- const targetPrintDir = join(targetDir, 'src/print');
167
- const printFilesProcessed = await this.syncPrintFile(
168
- upstreamPrintFile,
169
- targetPrintDir,
170
- pkg,
171
- upstreamCommit
172
- );
173
- elementFilesProcessed += printFilesProcessed;
174
- }
175
-
176
- // Generate src/index.ts that re-exports from delivery/
177
- const mainIndexPath = join(targetDir, 'src/index.ts');
178
- const mainIndexContent = `export { default } from './delivery/index.js';\n`;
179
- await writeFile(mainIndexPath, mainIndexContent, 'utf-8');
180
-
181
- const afterChanges = this.result.filesCopied + this.result.filesUpdated;
182
- const elementChanged = afterChanges > beforeChanges;
183
-
184
- if (elementFilesProcessed > 0 && logger.isVerbose()) {
185
- logger.success(` ✨ ${pkg}: ${elementFilesProcessed} file(s) synced`);
186
- }
187
-
188
- const elementDir = join(targetBaseDir, pkg);
189
-
190
- // Ensure IIFE files exist before generating package.json scripts.
191
- // package.json generation derives the build script from presence of iife files.
192
- await this.ensureIifeEntryPoint(pkg, elementDir, config, logger);
193
- await this.ensureIifeViteConfig(pkg, elementDir, config, logger);
194
-
195
- // Ensure package.json has ESM module support and expected exports.
196
- let wrotePkgJson = false;
197
- wrotePkgJson = await ensureElementPackageJson(pkg, elementDir, config);
198
- await this.ensureElementViteConfig(pkg, elementDir, logger);
199
- const wroteTsConfig = await this.ensureTsConfig(pkg, elementDir, logger);
200
-
201
- // Ensure demo structure
202
- await this.ensureElementDemoStructure(pkg, elementDir, config, logger);
203
- // Demo configs are maintained locally - we do NOT apply overrides from upstream
204
-
205
- if (elementChanged || wrotePkgJson || wroteTsConfig) {
206
- this.touchedElementPackages.add(pkg);
207
- }
208
- }
209
-
210
- // Demo configs are maintained locally - we do NOT apply overrides to existing elements
211
-
212
- if (!logger.isVerbose()) {
213
- logger.progressCompleteWithCount(this.touchedElementPackages.size, 'packages');
214
- } else {
215
- logger.info(`\nSynced ${this.touchedElementPackages.size} React component package(s)`);
216
- }
217
- return {
218
- count: this.touchedElementPackages.size,
219
- packageNames: Array.from(this.touchedElementPackages).sort(),
220
- };
221
- }
222
-
223
- private async cleanTargetDirExcept(
224
- targetDir: string,
225
- preserveDirs: string[],
226
- label: string,
227
- logger: any
228
- ): Promise<void> {
229
- await cleanDirectory(
230
- targetDir,
231
- label,
232
- { dryRun: false, verbose: false, preserve: preserveDirs },
233
- logger
234
- );
235
- }
236
-
237
- private async syncDirectory(
238
- sourceDir: string,
239
- targetDir: string,
240
- relativePath: string,
241
- pkg: string,
242
- upstreamCommit: string
243
- ): Promise<number> {
244
- let filesProcessed = 0;
245
- const defaultExportFiles = new Set<string>(); // Track files with default exports
246
-
247
- const items = await readdir(sourceDir);
248
-
249
- for (const item of items) {
250
- const srcPath = join(sourceDir, item);
251
- const stat = await fsStat(srcPath);
252
-
253
- if (stat.isDirectory()) {
254
- // Skip __tests__, __mocks__, etc.
255
- if (item.startsWith('__')) {
256
- continue;
257
- }
258
- // Recursively sync subdirectories
259
- const subFilesProcessed = await this.syncDirectory(
260
- srcPath,
261
- join(targetDir, item),
262
- join(relativePath, item),
263
- pkg,
264
- upstreamCommit
265
- );
266
- filesProcessed += subFilesProcessed;
267
- continue;
268
- }
269
-
270
- // Only process .js and .jsx files
271
- if (!item.endsWith('.js') && !item.endsWith('.jsx')) {
272
- continue;
273
- }
274
-
275
- // Skip print.js/print.jsx files - they're synced to src/print/ separately
276
- if (item === 'print.js' || item === 'print.jsx') {
277
- continue;
278
- }
279
-
280
- this.result.filesChecked++;
281
- filesProcessed++;
282
-
283
- // Read source
284
- let sourceContent = await readFile(srcPath, 'utf-8');
285
-
286
- // Apply all standard transformations
287
- const packageName = `@pie-element/${pkg}`;
288
- const transformPipeline = createReactComponentTransformPipeline(packageName);
289
- sourceContent = transformPipeline(sourceContent, join(relativePath, item));
290
-
291
- const hasJsx = item.endsWith('.jsx') || (item.endsWith('.js') && containsJsx(sourceContent));
292
-
293
- // Convert .js → .ts/.tsx and .jsx → .tsx
294
- const targetFile = item.replace(/\.jsx?$/, hasJsx ? '.tsx' : '.ts');
295
- const targetPath = join(targetDir, targetFile);
296
-
297
- // Convert based on file extension
298
- const conversionResult = hasJsx
299
- ? convertJsxToTsx(sourceContent, {
300
- sourcePath: `pie-elements/packages/${pkg}/${relativePath}/${item}`,
301
- commit: upstreamCommit,
302
- })
303
- : convertJsToTs(sourceContent, {
304
- sourcePath: `pie-elements/packages/${pkg}/${relativePath}/${item}`,
305
- commit: upstreamCommit,
306
- });
307
-
308
- const converted = conversionResult.code;
309
-
310
- // Track files that export default objects (for import fixing later)
311
- if (conversionResult.hasDefaultObjectExport) {
312
- // Store the file name without extension for import matching
313
- const fileNameWithoutExt = targetFile.replace(/\.(ts|tsx)$/, '');
314
- defaultExportFiles.add(fileNameWithoutExt);
315
- }
316
-
317
- // Check if different
318
- // NOTE: This comparison is exact (===) to ensure any changes in:
319
- // - Upstream source code
320
- // - Transformation logic (lodash-es, event packages, etc.)
321
- // - Sync version (tracked in @sync-version header)
322
- // will trigger a file update. This prioritizes correctness over speed.
323
- const isNew = !existsSync(targetPath);
324
- if (!isNew) {
325
- const currentContent = await readFile(targetPath, 'utf-8');
326
- if (currentContent === converted) {
327
- this.result.filesSkipped++;
328
- continue;
329
- }
330
- this.result.filesUpdated++;
331
- } else {
332
- this.result.filesCopied++;
333
- }
334
-
335
- // Write
336
- await mkdir(dirname(targetPath), { recursive: true });
337
- await writeFile(targetPath, converted, 'utf-8');
338
- }
339
-
340
- // After all files are synced, fix import statements in consuming files
341
- if (defaultExportFiles.size > 0) {
342
- const targetDirItems = await readdir(targetDir);
343
- for (const item of targetDirItems) {
344
- const itemPath = join(targetDir, item);
345
- const stat = await fsStat(itemPath);
346
- if (stat.isFile() && (item.endsWith('.tsx') || item.endsWith('.ts'))) {
347
- await fixImportsInFile(itemPath, defaultExportFiles);
348
- }
349
- }
350
- }
351
-
352
- return filesProcessed;
353
- }
354
-
355
- /**
356
- * Sync root-level .js files from configure/ directory (not including subdirectories)
357
- * These are typically utility files like utils.js that are imported by files in configure/src/
358
- */
359
- private async syncConfigureRootFiles(
360
- sourceDir: string,
361
- targetDir: string,
362
- pkg: string,
363
- upstreamCommit: string
364
- ): Promise<number> {
365
- let filesProcessed = 0;
366
-
367
- const items = await readdir(sourceDir);
368
-
369
- for (const item of items) {
370
- const srcPath = join(sourceDir, item);
371
- const stat = await fsStat(srcPath);
372
-
373
- // Skip directories - we only want root-level files
374
- if (stat.isDirectory()) {
375
- continue;
376
- }
377
-
378
- // Only process .js and .jsx files
379
- if (!item.endsWith('.js') && !item.endsWith('.jsx')) {
380
- continue;
381
- }
382
-
383
- this.result.filesChecked++;
384
- filesProcessed++;
385
-
386
- // Read source
387
- let sourceContent = await readFile(srcPath, 'utf-8');
388
-
389
- // Apply all standard transformations
390
- const packageName = `@pie-element/${pkg}`;
391
- const transformPipeline = createReactComponentTransformPipeline(packageName);
392
- sourceContent = transformPipeline(sourceContent);
393
-
394
- const hasJsx = item.endsWith('.jsx') || (item.endsWith('.js') && containsJsx(sourceContent));
395
-
396
- // Convert .js → .ts/.tsx and .jsx → .tsx
397
- const targetFile = item.replace(/\.jsx?$/, hasJsx ? '.tsx' : '.ts');
398
- const targetPath = join(targetDir, targetFile);
399
-
400
- // Convert based on file extension
401
- const conversionResult = hasJsx
402
- ? convertJsxToTsx(sourceContent, {
403
- sourcePath: `pie-elements/packages/${pkg}/configure/${item}`,
404
- commit: upstreamCommit,
405
- })
406
- : convertJsToTs(sourceContent, {
407
- sourcePath: `pie-elements/packages/${pkg}/configure/${item}`,
408
- commit: upstreamCommit,
409
- });
410
-
411
- const converted = conversionResult.code;
412
-
413
- // Check if file already exists (synced from configure/src/)
414
- const isNew = !existsSync(targetPath);
415
- if (!isNew) {
416
- // File exists - this means configure/src/utils.js was already synced
417
- // We need to merge the exports instead of overwriting
418
- const existingContent = await readFile(targetPath, 'utf-8');
419
-
420
- // Extract exports from both files and merge them
421
- const mergedContent = this.mergeUtilsFiles(existingContent, converted);
422
-
423
- if (existingContent === mergedContent) {
424
- this.result.filesSkipped++;
425
- continue;
426
- }
427
-
428
- await writeFile(targetPath, mergedContent, 'utf-8');
429
- this.result.filesUpdated++;
430
- } else {
431
- // New file - just write it
432
- await mkdir(dirname(targetPath), { recursive: true });
433
- await writeFile(targetPath, converted, 'utf-8');
434
- this.result.filesCopied++;
435
- }
436
- }
437
-
438
- return filesProcessed;
439
- }
440
-
441
- /**
442
- * Sync a single print file (src/print.js -> src/print/index.ts)
443
- */
444
- private async syncPrintFile(
445
- sourceFile: string,
446
- targetDir: string,
447
- pkg: string,
448
- upstreamCommit: string
449
- ): Promise<number> {
450
- this.result.filesChecked++;
451
-
452
- // Read source
453
- let sourceContent = await readFile(sourceFile, 'utf-8');
454
-
455
- // Apply all standard transformations
456
- const packageName = `@pie-element/${pkg}`;
457
- const transformPipeline = createReactComponentTransformPipeline(packageName);
458
- sourceContent = transformPipeline(sourceContent);
459
-
460
- // Transform imports from './' to '../delivery/' since print is now in print/
461
- // This handles './main', './stimulus-tabs', './choice', etc.
462
- sourceContent = sourceContent.replace(/from\s+['"]\.\/([^'"]+)['"]/g, "from '../delivery/$1'");
463
- sourceContent = sourceContent.replace(
464
- /import\s*\(\s*['"]\.\/([^'"]+)['"]\s*\)/g,
465
- "import('../delivery/$1')"
466
- );
467
-
468
- const hasJsx = sourceContent.includes('React.createElement') || containsJsx(sourceContent);
469
-
470
- // Convert to TypeScript
471
- const conversionResult = hasJsx
472
- ? convertJsxToTsx(sourceContent, {
473
- sourcePath: `pie-elements/packages/${pkg}/src/print.js`,
474
- commit: upstreamCommit,
475
- })
476
- : convertJsToTs(sourceContent, {
477
- sourcePath: `pie-elements/packages/${pkg}/src/print.js`,
478
- commit: upstreamCommit,
479
- });
480
-
481
- const converted = conversionResult.code;
482
- const targetFile = hasJsx ? 'index.tsx' : 'index.ts';
483
- const targetPath = join(targetDir, targetFile);
484
-
485
- // Check if needs update
486
- const isNew = !existsSync(targetPath);
487
- if (!isNew) {
488
- const existingContent = await readFile(targetPath, 'utf-8');
489
- if (existingContent === converted) {
490
- this.result.filesSkipped++;
491
- return 1;
492
- }
493
- await writeFile(targetPath, converted, 'utf-8');
494
- this.result.filesUpdated++;
495
- } else {
496
- await mkdir(targetDir, { recursive: true });
497
- await writeFile(targetPath, converted, 'utf-8');
498
- this.result.filesCopied++;
499
- }
500
-
501
- return 1;
502
- }
503
-
504
- /**
505
- * Merge two utils files by combining their exports
506
- *
507
- * When syncing configure/ files, we may have:
508
- * - configure/src/utils.js (already synced to src/configure/utils.ts)
509
- * - configure/utils.js (being synced now to src/configure/utils.ts)
510
- *
511
- * Both files export different functions, so we need to merge them.
512
- */
513
- private mergeUtilsFiles(existingContent: string, newContent: string): string {
514
- // Extract the header comment from existing file (has sync metadata)
515
- const headerMatch = existingContent.match(/^\/\/ @ts-nocheck\n\/\*\*[\s\S]*?\*\/\n\n/);
516
- const existingHeader = headerMatch ? headerMatch[0] : '';
517
-
518
- // Extract exports from existing file (remove header and blank lines)
519
- const existingExports = existingContent
520
- .replace(/^\/\/ @ts-nocheck\n\/\*\*[\s\S]*?\*\/\n\n/, '')
521
- .trim();
522
-
523
- // Extract exports from new file (remove header and blank lines)
524
- const newExports = newContent.replace(/^\/\/ @ts-nocheck\n\/\*\*[\s\S]*?\*\/\n\n/, '').trim();
525
-
526
- // Combine: use existing header + both sets of exports
527
- return `${existingHeader}${existingExports}\n\n${newExports}\n`;
528
- }
529
-
530
- private async ensureElementViteConfig(
531
- _elementName: string,
532
- elementDir: string,
533
- _logger: any
534
- ): Promise<void> {
535
- if (!existsSync(elementDir)) {
536
- return;
537
- }
538
-
539
- const viteConfigPath = join(elementDir, 'vite.config.ts');
540
-
541
- // Always regenerate to reflect current directory structure
542
- // (e.g., if configure/ was skipped due to ESM incompatibility)
543
-
544
- // Detect entry points
545
- const entryPoints: Record<string, string> = {};
546
-
547
- // Helper to find which file extension exists (.ts or .tsx)
548
- const findEntry = (basePath: string): string | null => {
549
- if (existsSync(join(elementDir, `${basePath}.tsx`))) return `${basePath}.tsx`;
550
- if (existsSync(join(elementDir, `${basePath}.ts`))) return `${basePath}.ts`;
551
- return null;
552
- };
553
-
554
- const indexEntry = findEntry('src/index');
555
- if (indexEntry) {
556
- entryPoints.index = indexEntry;
557
- }
558
-
559
- const controllerEntry = findEntry('src/controller/index');
560
- if (controllerEntry) {
561
- entryPoints['controller/index'] = controllerEntry;
562
- }
563
-
564
- const configureEntry = findEntry('src/configure/index');
565
- if (configureEntry) {
566
- entryPoints['configure/index'] = configureEntry;
567
- }
568
-
569
- const deliveryEntry = findEntry('src/delivery/index');
570
- if (deliveryEntry) {
571
- entryPoints['delivery/index'] = deliveryEntry;
572
- }
573
-
574
- const authorEntry = findEntry('src/author/index');
575
- if (authorEntry) {
576
- entryPoints['author/index'] = authorEntry;
577
- }
578
-
579
- const printEntry = findEntry('src/print/index');
580
- if (printEntry) {
581
- entryPoints['print/index'] = printEntry;
582
- }
583
-
584
- const typesEntry = findEntry('src/types/index');
585
- if (typesEntry) {
586
- entryPoints['types/index'] = typesEntry;
587
- }
588
-
589
- if (Object.keys(entryPoints).length === 0) {
590
- return; // No entry points, skip vite config
591
- }
592
-
593
- // Format entry points for vite config
594
- const entryLines = Object.entries(entryPoints)
595
- .map(([key, value]) => ` '${key}': resolve(__dirname, '${value}'),`)
596
- .join('\n');
597
-
598
- // Konva is now external like other dependencies - no special bundling needed
599
- // This avoids workspace dependency resolution issues
600
- const shouldBundleKonva = false;
601
-
602
- // Check if demo directory exists
603
- const hasDemoDir = existsSync(join(elementDir, 'docs/demo'));
604
-
605
- // Generate appropriate config based on element characteristics
606
- const viteConfig = shouldBundleKonva
607
- ? this.generateViteConfigWithBundledKonva(entryLines, hasDemoDir)
608
- : this.generateStandardViteConfig(entryLines, hasDemoDir);
609
-
610
- await writeFile(viteConfigPath, viteConfig, 'utf-8');
611
- }
612
-
613
- private generateStandardViteConfig(entryLines: string, hasDemoDir: boolean): string {
614
- const demoModeConfig = hasDemoDir
615
- ? `({ mode, command }) => {
616
- // Demo mode: serve the docs/demo directory
617
- if (mode === 'demo' && command === 'serve') {
618
- return {
619
- plugins: [react()],
620
- root: resolve(__dirname, 'docs/demo'),
621
- };
622
- }
623
-
624
- // Build mode: build the library
625
- return {`
626
- : `{`;
627
-
628
- return `import { resolve } from 'node:path';
629
- import react from '@vitejs/plugin-react';
630
- import { defineConfig } from 'vite';
631
-
632
- export default defineConfig(${demoModeConfig}
633
- plugins: [react()],
634
- build: {
635
- lib: {
636
- entry: {
637
- ${entryLines}
638
- },
639
- formats: ['es'],
640
- },
641
- rollupOptions: {
642
- external: ${createExternalFunction('element')},
643
- output: {
644
- preserveModules: true,
645
- preserveModulesRoot: 'src',
646
- },
647
- },
648
- },${hasDemoDir ? '\n };' : ''}
649
- });
650
- `;
651
- }
652
-
653
- private generateViteConfigWithBundledKonva(entryLines: string, hasDemoDir: boolean): string {
654
- const demoModeConfig = hasDemoDir
655
- ? `({ mode, command }) => ({
656
- plugins: [react()],
657
- // Only change root for demo mode when serving (not building)
658
- root: mode === 'demo' && command === 'serve' ? resolve(__dirname, 'docs/demo') : __dirname,`
659
- : `{
660
- plugins: [react()],`;
661
-
662
- return `import { resolve } from 'node:path';
663
- import react from '@vitejs/plugin-react';
664
- import { defineConfig } from 'vite';
665
-
666
- export default defineConfig(${demoModeConfig}
667
- build: {
668
- lib: {
669
- entry: {
670
- ${entryLines}
671
- },
672
- formats: ['es'],
673
- },
674
- rollupOptions: {
675
- external: ${createKonvaExternalFunction()},
676
- output: {
677
- preserveModules: false,
678
- // Paths helps resolve external lodash imports correctly in the bundled output
679
- paths: (id) => {
680
- if (id.startsWith('lodash/')) {
681
- // Keep lodash subpath imports as-is so they resolve via import map
682
- return id;
683
- }
684
- return id;
685
- },
686
- },
687
- },
688
- },
689
- }${hasDemoDir ? '))' : ')'};
690
- `;
691
- }
692
-
693
- /**
694
- * Ensure IIFE entry point exists for element
695
- */
696
- private async ensureIifeEntryPoint(
697
- elementName: string,
698
- elementDir: string,
699
- _config: SyncConfig,
700
- _logger: any
701
- ): Promise<void> {
702
- const iifeEntryPath = join(elementDir, 'src/index.iife.ts');
703
-
704
- // Check if main entry point exists
705
- const mainEntryExists = existsAny([
706
- join(elementDir, 'src/index.ts'),
707
- join(elementDir, 'src/index.tsx'),
708
- ]);
709
-
710
- if (!mainEntryExists) {
711
- return; // No main entry, skip IIFE
712
- }
713
-
714
- const iifeContent = `/**
715
- * IIFE entry point for ${elementName} element
716
- * This file is only used for IIFE builds and includes auto-registration
717
- *
718
- * @sync-generated - Auto-generated during sync from pie-elements
719
- */
720
-
721
- import Element from './index';
722
-
723
- // Auto-register the custom element for IIFE mode
724
- if (typeof window !== 'undefined' && !customElements.get('${elementName}-element')) {
725
- customElements.define('${elementName}-element', Element);
726
- }
727
-
728
- // Export for IIFE global
729
- export default Element;
730
- `;
731
-
732
- await writeFile(iifeEntryPath, iifeContent, 'utf-8');
733
- }
734
-
735
- /**
736
- * Ensure IIFE Vite config exists for element
737
- */
738
- private async ensureIifeViteConfig(
739
- elementName: string,
740
- elementDir: string,
741
- _config: SyncConfig,
742
- _logger: any
743
- ): Promise<void> {
744
- const iifeViteConfigPath = join(elementDir, 'vite.config.iife.ts');
745
-
746
- // Check if IIFE entry exists
747
- if (!existsSync(join(elementDir, 'src/index.iife.ts'))) {
748
- return;
749
- }
750
-
751
- // Compute global name (e.g., "hotspot" → "HotspotElement")
752
- const globalName =
753
- elementName
754
- .split('-')
755
- .map((part) => part.charAt(0).toUpperCase() + part.slice(1))
756
- .join('') + 'Element';
757
-
758
- const config = `import { existsSync } from 'node:fs';
759
- import { resolve } from 'node:path';
760
- import react from '@vitejs/plugin-react';
761
- import { defineConfig } from 'vite';
762
-
763
- const resolveWorkspaceEntry = (baseDir: string): string | null => {
764
- const candidates = ['index.ts', 'index.tsx', 'index.js', 'index.jsx'];
765
- for (const candidate of candidates) {
766
- const fullPath = resolve(baseDir, candidate);
767
- if (existsSync(fullPath)) {
768
- return fullPath;
769
- }
770
- }
771
- return null;
772
- };
773
-
774
- export default defineConfig({
775
- plugins: [
776
- {
777
- name: 'iife-workspace-and-shim-resolver',
778
- enforce: 'pre',
779
- resolveId(id) {
780
- const sharedMatch = id.match(/^@pie-element\\/shared-(.+)$/);
781
- if (sharedMatch) {
782
- const entry = resolveWorkspaceEntry(resolve(__dirname, '../../shared', sharedMatch[1], 'src'));
783
- if (entry) {
784
- return entry;
785
- }
786
- }
787
-
788
- const pieLibMatch = id.match(/^@pie-lib\\/([^/]+)$/);
789
- if (pieLibMatch) {
790
- const entry = resolveWorkspaceEntry(resolve(__dirname, '../../lib-react', pieLibMatch[1], 'src'));
791
- if (entry) {
792
- return entry;
793
- }
794
- }
795
-
796
- if (id === 'debug') {
797
- return '\\0iife-debug-shim';
798
- }
799
- if (id === 'prop-types') {
800
- return '\\0iife-prop-types-shim';
801
- }
802
- },
803
- load(id) {
804
- if (id === '\\0iife-debug-shim') {
805
- return 'export default function debug() { return () => {}; }';
806
- }
807
- if (id === '\\0iife-prop-types-shim') {
808
- return "const fn = () => null; const types = new Proxy(fn, { get: () => fn }); export default types;";
809
- }
810
- },
811
- },
812
- react(),
813
- ],
814
- define: {
815
- 'process.env.NODE_ENV': JSON.stringify('production'),
816
- },
817
- build: {
818
- emptyOutDir: false, // Don't wipe existing ESM builds
819
- lib: {
820
- entry: resolve(__dirname, 'src/index.iife.ts'),
821
- name: '${globalName}',
822
- fileName: () => 'index.iife.js',
823
- formats: ['iife'] as const,
824
- },
825
- rollupOptions: {
826
- external: (id: string) => {
827
- // Bundle everything including React and math-rendering
828
- // This creates a fully self-contained IIFE bundle
829
- return false;
830
- },
831
- output: {
832
- // IIFE global name
833
- name: '${globalName}',
834
- extend: true,
835
- },
836
- },
837
- },
838
- });
839
- `;
840
-
841
- await writeFile(iifeViteConfigPath, config, 'utf-8');
842
- }
843
-
844
- /**
845
- * Ensure element demo structure exists with new dev/production split
846
- */
847
- private async ensureElementDemoStructure(
848
- elementName: string,
849
- elementDir: string,
850
- config: SyncConfig,
851
- _logger: any
852
- ): Promise<void> {
853
- const upstreamDemoDir = join(config.pieElements, 'packages', elementName, 'docs/demo');
854
-
855
- // Only generate if upstream has demo files
856
- if (!existsSync(upstreamDemoDir)) {
857
- return;
858
- }
859
-
860
- const targetDemoDir = join(elementDir, 'docs/demo');
861
- await mkdir(targetDemoDir, { recursive: true });
862
-
863
- // Demo configs are maintained locally for the unified demo app (apps/element-demo).
864
- // We do NOT sync demo configs from upstream - each element should have its own
865
- // locally-maintained multi-demo config.mjs in docs/demo/.
866
- //
867
- // If a new element is synced and doesn't have a local demo config yet,
868
- // it should be created manually with multiple demo scenarios.
869
- //
870
- // The unified demo app showcases all elements with rich demo configurations,
871
- // so we maintain these locally rather than using upstream's single-demo configs.
872
-
873
- // Convert session.js (CommonJS) to session.mjs (ESM) if it exists upstream
874
- const sessionJs = join(upstreamDemoDir, 'session.js');
875
- const sessionMjs = join(upstreamDemoDir, 'session.mjs');
876
-
877
- let sessionContent: string | null = null;
878
-
879
- if (existsSync(sessionMjs)) {
880
- // If session.mjs exists, just copy it
881
- sessionContent = await readFile(sessionMjs, 'utf-8');
882
- } else if (existsSync(sessionJs)) {
883
- // Convert CommonJS session.js to ESM session.mjs
884
- const content = await readFile(sessionJs, 'utf-8');
885
- // Simple conversion: replace module.exports with export default
886
- sessionContent = content
887
- .replace(/module\.exports\s*=/, 'export default')
888
- .replace(/exports\.\w+\s*=/g, 'export const');
889
- }
890
-
891
- if (sessionContent) {
892
- await writeFile(join(targetDemoDir, 'session.mjs'), sessionContent, 'utf-8');
893
- }
894
-
895
- // Demo configs are maintained locally - we do NOT apply overrides from upstream
896
-
897
- // Remove unused generate.js if config.mjs exists (from demo dir only)
898
- const configPath = join(targetDemoDir, 'config.mjs');
899
- const generatePath = join(targetDemoDir, 'generate.js');
900
- if (existsSync(configPath) && existsSync(generatePath)) {
901
- await fsRm(generatePath, { force: true });
902
- }
903
- }
904
-
905
- private async ensureTsConfig(
906
- elementName: string,
907
- elementDir: string,
908
- logger: any
909
- ): Promise<boolean> {
910
- if (!existsSync(elementDir)) {
911
- return false;
912
- }
913
-
914
- const tsConfigPath = join(elementDir, 'tsconfig.json');
915
- const tsConfig = this.generateTsConfig();
916
-
917
- // Check if tsconfig needs to be written
918
- const currentContent = existsSync(tsConfigPath)
919
- ? await readFile(tsConfigPath, 'utf-8').catch(() => null)
920
- : null;
921
-
922
- if (currentContent === tsConfig) {
923
- return false;
924
- }
925
-
926
- await writeFile(tsConfigPath, tsConfig, 'utf-8');
927
- if (logger.isVerbose()) {
928
- logger.success(` 📝 ${elementName}: generated tsconfig.json`);
929
- }
930
- return true;
931
- }
932
-
933
- private generateTsConfig(): string {
934
- return `{
935
- "extends": "../../../tsconfig.base.json",
936
- "compilerOptions": {
937
- "outDir": "dist",
938
- "declarationDir": "dist",
939
- "rootDir": "src"
940
- },
941
- "include": ["src/**/*"]
942
- }
943
- `;
944
- }
945
- }