@_linked/cli 1.46.2 → 1.47.0

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 (167) hide show
  1. package/CHANGELOG.md +107 -0
  2. package/README.md +48 -36
  3. package/hooks/drift.cjs +169 -0
  4. package/hooks/git-hook.cjs +170 -0
  5. package/hooks/hook-shim.cjs +63 -0
  6. package/hooks/lock-at-rest.cjs +268 -0
  7. package/hooks/manifests.cjs +216 -0
  8. package/hooks/platform.cjs +25 -0
  9. package/lib/esm/app-release/build-backend.d.ts.map +1 -1
  10. package/lib/esm/app-release/build-backend.js +2 -1
  11. package/lib/esm/app-release/build-backend.js.map +1 -1
  12. package/lib/esm/cli-methods.d.ts.map +1 -1
  13. package/lib/esm/cli-methods.js +166 -150
  14. package/lib/esm/cli-methods.js.map +1 -1
  15. package/lib/esm/cli.js +20 -22
  16. package/lib/esm/cli.js.map +1 -1
  17. package/lib/esm/commands/build-app.d.ts.map +1 -1
  18. package/lib/esm/commands/build-app.js +2 -1
  19. package/lib/esm/commands/build-app.js.map +1 -1
  20. package/lib/esm/commands/build-package.d.ts.map +1 -1
  21. package/lib/esm/commands/build-package.js +6 -2
  22. package/lib/esm/commands/build-package.js.map +1 -1
  23. package/lib/esm/commands/localize.d.ts +9 -15
  24. package/lib/esm/commands/localize.d.ts.map +1 -1
  25. package/lib/esm/commands/localize.js +43 -74
  26. package/lib/esm/commands/localize.js.map +1 -1
  27. package/lib/esm/commands/setup-publish.d.ts.map +1 -1
  28. package/lib/esm/commands/setup-publish.js +22 -15
  29. package/lib/esm/commands/setup-publish.js.map +1 -1
  30. package/lib/esm/commands/start.d.ts +8 -0
  31. package/lib/esm/commands/start.d.ts.map +1 -1
  32. package/lib/esm/commands/start.js +20 -8
  33. package/lib/esm/commands/start.js.map +1 -1
  34. package/lib/esm/installed-packages.d.ts +5 -13
  35. package/lib/esm/installed-packages.d.ts.map +1 -1
  36. package/lib/esm/installed-packages.js +5 -38
  37. package/lib/esm/installed-packages.js.map +1 -1
  38. package/lib/esm/lifecycle.d.ts +35 -22
  39. package/lib/esm/lifecycle.d.ts.map +1 -1
  40. package/lib/esm/lifecycle.js +62 -36
  41. package/lib/esm/lifecycle.js.map +1 -1
  42. package/lib/esm/localize/adopt.d.ts +5 -5
  43. package/lib/esm/localize/adopt.d.ts.map +1 -1
  44. package/lib/esm/localize/adopt.js +46 -55
  45. package/lib/esm/localize/adopt.js.map +1 -1
  46. package/lib/esm/localize/app-root.d.ts +16 -0
  47. package/lib/esm/localize/app-root.d.ts.map +1 -0
  48. package/lib/esm/localize/app-root.js +94 -0
  49. package/lib/esm/localize/app-root.js.map +1 -0
  50. package/lib/esm/localize/app-setup.d.ts +21 -0
  51. package/lib/esm/localize/app-setup.d.ts.map +1 -0
  52. package/lib/esm/localize/app-setup.js +178 -0
  53. package/lib/esm/localize/app-setup.js.map +1 -0
  54. package/lib/esm/localize/delocalize.d.ts.map +1 -1
  55. package/lib/esm/localize/delocalize.js +169 -104
  56. package/lib/esm/localize/delocalize.js.map +1 -1
  57. package/lib/esm/localize/drift-hook.d.ts +18 -0
  58. package/lib/esm/localize/drift-hook.d.ts.map +1 -0
  59. package/lib/esm/localize/drift-hook.js +37 -0
  60. package/lib/esm/localize/drift-hook.js.map +1 -0
  61. package/lib/esm/localize/drift.d.ts +36 -0
  62. package/lib/esm/localize/drift.d.ts.map +1 -0
  63. package/lib/esm/localize/drift.js +34 -0
  64. package/lib/esm/localize/drift.js.map +1 -0
  65. package/lib/esm/localize/errors.d.ts +14 -8
  66. package/lib/esm/localize/errors.d.ts.map +1 -1
  67. package/lib/esm/localize/errors.js +14 -8
  68. package/lib/esm/localize/errors.js.map +1 -1
  69. package/lib/esm/localize/fsops.d.ts +11 -27
  70. package/lib/esm/localize/fsops.d.ts.map +1 -1
  71. package/lib/esm/localize/fsops.js +40 -115
  72. package/lib/esm/localize/fsops.js.map +1 -1
  73. package/lib/esm/localize/git-hooks.d.ts +33 -0
  74. package/lib/esm/localize/git-hooks.d.ts.map +1 -0
  75. package/lib/esm/localize/git-hooks.js +146 -0
  76. package/lib/esm/localize/git-hooks.js.map +1 -0
  77. package/lib/esm/localize/hook-module.d.ts +6 -0
  78. package/lib/esm/localize/hook-module.d.ts.map +1 -0
  79. package/lib/esm/localize/hook-module.js +37 -0
  80. package/lib/esm/localize/hook-module.js.map +1 -0
  81. package/lib/esm/localize/index.d.ts +14 -15
  82. package/lib/esm/localize/index.d.ts.map +1 -1
  83. package/lib/esm/localize/index.js +8 -9
  84. package/lib/esm/localize/index.js.map +1 -1
  85. package/lib/esm/localize/list.d.ts +6 -10
  86. package/lib/esm/localize/list.d.ts.map +1 -1
  87. package/lib/esm/localize/list.js +49 -189
  88. package/lib/esm/localize/list.js.map +1 -1
  89. package/lib/esm/localize/localize.d.ts +46 -62
  90. package/lib/esm/localize/localize.d.ts.map +1 -1
  91. package/lib/esm/localize/localize.js +411 -285
  92. package/lib/esm/localize/localize.js.map +1 -1
  93. package/lib/esm/localize/members.d.ts +13 -0
  94. package/lib/esm/localize/members.d.ts.map +1 -0
  95. package/lib/esm/localize/members.js +46 -0
  96. package/lib/esm/localize/members.js.map +1 -0
  97. package/lib/esm/localize/resolve.d.ts +1 -2
  98. package/lib/esm/localize/resolve.d.ts.map +1 -1
  99. package/lib/esm/localize/resolve.js +3 -5
  100. package/lib/esm/localize/resolve.js.map +1 -1
  101. package/lib/esm/localize/run.d.ts +1 -0
  102. package/lib/esm/localize/run.d.ts.map +1 -1
  103. package/lib/esm/localize/run.js +11 -6
  104. package/lib/esm/localize/run.js.map +1 -1
  105. package/lib/esm/localize/setup-lockfile.d.ts +13 -0
  106. package/lib/esm/localize/setup-lockfile.d.ts.map +1 -0
  107. package/lib/esm/localize/setup-lockfile.js +80 -0
  108. package/lib/esm/localize/setup-lockfile.js.map +1 -0
  109. package/lib/esm/utils/createPackageLocation.d.ts +4 -13
  110. package/lib/esm/utils/createPackageLocation.d.ts.map +1 -1
  111. package/lib/esm/utils/createPackageLocation.js +12 -21
  112. package/lib/esm/utils/createPackageLocation.js.map +1 -1
  113. package/lib/esm/utils/packageSetup.d.ts +5 -2
  114. package/lib/esm/utils/packageSetup.d.ts.map +1 -1
  115. package/lib/esm/utils/packageSetup.js +9 -3
  116. package/lib/esm/utils/packageSetup.js.map +1 -1
  117. package/lib/esm/utils/platform.d.ts +24 -0
  118. package/lib/esm/utils/platform.d.ts.map +1 -0
  119. package/lib/esm/utils/platform.js +62 -0
  120. package/lib/esm/utils/platform.js.map +1 -0
  121. package/lib/esm/utils/shapeReferences.d.ts.map +1 -1
  122. package/lib/esm/utils/shapeReferences.js +3 -2
  123. package/lib/esm/utils/shapeReferences.js.map +1 -1
  124. package/lib/esm/utils/spawn.d.ts +65 -0
  125. package/lib/esm/utils/spawn.d.ts.map +1 -0
  126. package/lib/esm/utils/spawn.js +181 -0
  127. package/lib/esm/utils/spawn.js.map +1 -0
  128. package/lib/esm/utils.d.ts.map +1 -1
  129. package/lib/esm/utils.js +19 -5
  130. package/lib/esm/utils.js.map +1 -1
  131. package/lib/esm/vite-config.d.ts +5 -12
  132. package/lib/esm/vite-config.d.ts.map +1 -1
  133. package/lib/esm/vite-config.js +41 -33
  134. package/lib/esm/vite-config.js.map +1 -1
  135. package/package.json +4 -3
  136. package/lib/esm/localize/ensure.d.ts +0 -44
  137. package/lib/esm/localize/ensure.d.ts.map +0 -1
  138. package/lib/esm/localize/ensure.js +0 -151
  139. package/lib/esm/localize/ensure.js.map +0 -1
  140. package/lib/esm/localize/manifest.d.ts +0 -63
  141. package/lib/esm/localize/manifest.d.ts.map +0 -1
  142. package/lib/esm/localize/manifest.js +0 -133
  143. package/lib/esm/localize/manifest.js.map +0 -1
  144. package/lib/esm/localize/one-copy-hook.d.ts +0 -16
  145. package/lib/esm/localize/one-copy-hook.d.ts.map +0 -1
  146. package/lib/esm/localize/one-copy-hook.js +0 -20
  147. package/lib/esm/localize/one-copy-hook.js.map +0 -1
  148. package/lib/esm/localize/provided.d.ts +0 -28
  149. package/lib/esm/localize/provided.d.ts.map +0 -1
  150. package/lib/esm/localize/provided.js +0 -89
  151. package/lib/esm/localize/provided.js.map +0 -1
  152. package/lib/esm/localize/prune.d.ts +0 -182
  153. package/lib/esm/localize/prune.d.ts.map +0 -1
  154. package/lib/esm/localize/prune.js +0 -703
  155. package/lib/esm/localize/prune.js.map +0 -1
  156. package/lib/esm/localize/relink.d.ts +0 -13
  157. package/lib/esm/localize/relink.d.ts.map +0 -1
  158. package/lib/esm/localize/relink.js +0 -181
  159. package/lib/esm/localize/relink.js.map +0 -1
  160. package/lib/esm/localized-dedupe.d.ts +0 -26
  161. package/lib/esm/localized-dedupe.d.ts.map +0 -1
  162. package/lib/esm/localized-dedupe.js +0 -139
  163. package/lib/esm/localized-dedupe.js.map +0 -1
  164. package/lib/esm/utils/relinkHooks.d.ts +0 -19
  165. package/lib/esm/utils/relinkHooks.d.ts.map +0 -1
  166. package/lib/esm/utils/relinkHooks.js +0 -74
  167. package/lib/esm/utils/relinkHooks.js.map +0 -1
@@ -9,11 +9,12 @@
9
9
  * - `packages-local/` — the package has a repository of its own. It goes where
10
10
  * `linked localize` keeps checkouts, under the same name localize would give
11
11
  * it (`@_linked/foo` → `packages-local/_linked-foo`), and is handed to
12
- * localize's `adopt`, so the two can never disagree about it.
12
+ * localize's `adopt`, so the two can never disagree about it. Like every
13
+ * checkout it is a workspace member through the app's `packages-local/*`
14
+ * glob.
13
15
  */
14
16
  import fs from 'fs';
15
17
  import path from 'path';
16
- import { ensureRelinkHooks } from './relinkHooks.js';
17
18
  export const PACKAGE_LOCATIONS = ['packages', 'packages-local'];
18
19
  /** A refusal of create-package's own, as opposed to a crash. */
19
20
  export class CreatePackageError extends Error {
@@ -94,16 +95,18 @@ export function bareName(name) {
94
95
  return match[2];
95
96
  }
96
97
  /**
97
- * Make sure the app's `workspaces` covers `packages/*`, so a package created
98
- * there is a workspace member. Mutates `pkg`.
98
+ * Make sure the app's `workspaces` covers `<location>/*` (default
99
+ * `packages/*`), so a package created there is a workspace member. Mutates
100
+ * `pkg`.
99
101
  *
100
102
  * @returns whether it changed, and a warning when it cannot tell.
101
103
  */
102
- export function ensureWorkspaceGlob(pkg) {
104
+ export function ensureWorkspaceGlob(pkg, location = 'packages') {
103
105
  var _a;
104
- const covers = (globs) => globs.some((g) => g === 'packages/*' || g === 'packages/**');
106
+ const glob = `${location}/*`;
107
+ const covers = (globs) => globs.some((g) => g === glob || g === `${location}/**`);
105
108
  if (pkg.workspaces === undefined) {
106
- pkg.workspaces = ['packages/*'];
109
+ pkg.workspaces = [glob];
107
110
  return { changed: true };
108
111
  }
109
112
  const globs = Array.isArray(pkg.workspaces)
@@ -114,26 +117,14 @@ export function ensureWorkspaceGlob(pkg) {
114
117
  if (!globs) {
115
118
  return {
116
119
  changed: false,
117
- warning: `the app's "workspaces" field has a shape this command does not edit; make sure it covers packages/*.`,
120
+ warning: `the app's "workspaces" field has a shape this command does not edit; make sure it covers ${glob}.`,
118
121
  };
119
122
  }
120
123
  if (covers(globs))
121
124
  return { changed: false };
122
- globs.push('packages/*');
125
+ globs.push(glob);
123
126
  return { changed: true };
124
127
  }
125
- export { RELINK_COMMAND, ensureRelinkHooks } from './relinkHooks.js';
126
- /**
127
- * Make sure the app's `postinstall` AND `dependencies` scripts recreate
128
- * localize's links -- see `./relinkHooks.js` for why npm needs both. Kept
129
- * under its old name for existing callers; prefer `ensureRelinkHooks`.
130
- * Mutates `pkg`.
131
- *
132
- * @returns true when it changed `pkg`.
133
- */
134
- export function ensureRelinkPostinstall(pkg) {
135
- return ensureRelinkHooks(pkg).length > 0;
136
- }
137
128
  /**
138
129
  * A git remote as npm wants it in `repository.url`: `git+https://…`, or
139
130
  * `git+ssh://git@host/path` for the scp-like `git@host:path` form.
@@ -1 +1 @@
1
- {"version":3,"file":"createPackageLocation.js","sourceRoot":"","sources":["../../../src/utils/createPackageLocation.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AACH,OAAO,EAAE,MAAM,IAAI,CAAC;AACpB,OAAO,IAAI,MAAM,MAAM,CAAC;AAExB,OAAO,EAAC,iBAAiB,EAAC,MAAM,kBAAkB,CAAC;AAEnD,MAAM,CAAC,MAAM,iBAAiB,GAAG,CAAC,UAAU,EAAE,gBAAgB,CAAU,CAAC;AAoCzE,gEAAgE;AAChE,MAAM,OAAO,kBAAmB,SAAQ,KAAK;IAC3C,YAAY,OAAe;QACzB,KAAK,CAAC,OAAO,CAAC,CAAC;QACf,IAAI,CAAC,IAAI,GAAG,oBAAoB,CAAC;IACnC,CAAC;CACF;AAED;;;;GAIG;AACH,MAAM,UAAU,iBAAiB,CAAC,KAAa;IAC7C,IAAI,GAAG,GAAG,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC;IAC9B,iDAAiD;IACjD,OAAO,IAAI,EAAE,CAAC;QACZ,IAAI,CAAC;YACH,MAAM,GAAG,GAAG,IAAI,CAAC,KAAK,CACpB,EAAE,CAAC,YAAY,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,cAAc,CAAC,EAAE,MAAM,CAAC,CACxD,CAAC;YACF,IAAI,CAAA,GAAG,aAAH,GAAG,uBAAH,GAAG,CAAE,SAAS,MAAK,IAAI;gBAAE,OAAO,GAAG,CAAC;QAC1C,CAAC;QAAC,WAAM,CAAC;YACP,6DAA6D;QAC/D,CAAC;QACD,MAAM,MAAM,GAAG,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC;QACjC,IAAI,MAAM,KAAK,GAAG;YAAE,OAAO,IAAI,CAAC;QAChC,GAAG,GAAG,MAAM,CAAC;IACf,CAAC;AACH,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,yBAAyB,CAAC,EACxC,OAAO,EACP,OAAO,EACP,KAAK,GAKN;;IACC,MAAM,EAAC,MAAM,EAAE,IAAI,GAAG,KAAK,EAAC,GAAG,OAAO,CAAC;IACvC,MAAM,QAAQ,GAAuB,OAAO,CAAC,QAAQ,CAAC;IACtD,MAAM,KAAK,GAAG,QAAQ,KAAK,SAAS,IAAI,MAAM,KAAK,SAAS,IAAI,IAAI,CAAC;IAErE,IAAI,QAAQ,KAAK,SAAS,IAAI,CAAC,iBAAiB,CAAC,QAAQ,CAAC,EAAE,CAAC;QAC3D,OAAO,MAAM,CACX,6BAA6B,iBAAiB,CAAC,IAAI,CAAC,IAAI,CAAC,UAAU,QAAQ,IAAI,CAChF,CAAC;IACJ,CAAC;IACD,IAAI,CAAC,OAAO,EAAE,CAAC;QACb,OAAO,KAAK;YACV,CAAC,CAAC,MAAM,CACJ,sFAAsF;gBACpF,wDAAwD,CAC3D;YACH,CAAC,CAAC,EAAC,IAAI,EAAE,SAAS,EAAC,CAAC;IACxB,CAAC;IACD,IAAI,IAAI,IAAI,CAAC,MAAM,EAAE,CAAC;QACpB,OAAO,MAAM,CAAC,qDAAqD,CAAC,CAAC;IACvE,CAAC;IACD,IAAI,MAAM,IAAI,QAAQ,KAAK,UAAU,EAAE,CAAC;QACtC,OAAO,MAAM,CACX,yFAAyF;YACvF,gFAAgF,CACnF,CAAC;IACJ,CAAC;IACD,IAAI,KAAK,EAAE,CAAC;QACV,qCACE,IAAI,EAAE,UAAU,EAChB,QAAQ,EAAE,MAAC,QAA4B,mCAAI,gBAAgB,IACxD,CAAC,MAAM,CAAC,CAAC,CAAC,EAAC,MAAM,EAAC,CAAC,CAAC,CAAC,EAAE,CAAC,KAC3B,IAAI,IACJ;IACJ,CAAC;IACD,IAAI,KAAK;QAAE,OAAO,EAAC,IAAI,EAAE,KAAK,EAAC,CAAC;IAChC,OAAO,MAAM,CACX,2FAA2F;QACzF,qFAAqF,CACxF,CAAC;AACJ,CAAC;AAED,MAAM,UAAU,iBAAiB,CAAC,KAAa;IAC7C,OAAQ,iBAAuC,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC;AAClE,CAAC;AAED,SAAS,MAAM,CAAC,OAAe;IAC7B,OAAO,EAAC,IAAI,EAAE,QAAQ,EAAE,OAAO,EAAC,CAAC;AACnC,CAAC;AAED,uEAAuE;AACvE,MAAM,UAAU,QAAQ,CAAC,IAAY;IACnC,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,wBAAwB,CAAC,CAAC;IACnD,IAAI,CAAC,KAAK,EAAE,CAAC;QACX,MAAM,IAAI,kBAAkB,CAAC,IAAI,IAAI,iCAAiC,CAAC,CAAC;IAC1E,CAAC;IACD,OAAO,KAAK,CAAC,CAAC,CAAC,CAAC;AAClB,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,mBAAmB,CAAC,GAAwB;;IAI1D,MAAM,MAAM,GAAG,CAAC,KAAgB,EAAE,EAAE,CAClC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,KAAK,YAAY,IAAI,CAAC,KAAK,aAAa,CAAC,CAAC;IAE/D,IAAI,GAAG,CAAC,UAAU,KAAK,SAAS,EAAE,CAAC;QACjC,GAAG,CAAC,UAAU,GAAG,CAAC,YAAY,CAAC,CAAC;QAChC,OAAO,EAAC,OAAO,EAAE,IAAI,EAAC,CAAC;IACzB,CAAC;IACD,MAAM,KAAK,GAAG,KAAK,CAAC,OAAO,CAAC,GAAG,CAAC,UAAU,CAAC;QACzC,CAAC,CAAC,GAAG,CAAC,UAAU;QAChB,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,MAAA,GAAG,CAAC,UAAU,0CAAE,QAAQ,CAAC;YACvC,CAAC,CAAC,GAAG,CAAC,UAAU,CAAC,QAAQ;YACzB,CAAC,CAAC,IAAI,CAAC;IACX,IAAI,CAAC,KAAK,EAAE,CAAC;QACX,OAAO;YACL,OAAO,EAAE,KAAK;YACd,OAAO,EAAE,sGAAsG;SAChH,CAAC;IACJ,CAAC;IACD,IAAI,MAAM,CAAC,KAAK,CAAC;QAAE,OAAO,EAAC,OAAO,EAAE,KAAK,EAAC,CAAC;IAC3C,KAAK,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC;IACzB,OAAO,EAAC,OAAO,EAAE,IAAI,EAAC,CAAC;AACzB,CAAC;AAED,OAAO,EAAC,cAAc,EAAE,iBAAiB,EAAC,MAAM,kBAAkB,CAAC;AAEnE;;;;;;;GAOG;AACH,MAAM,UAAU,uBAAuB,CAAC,GAAwB;IAC9D,OAAO,iBAAiB,CAAC,GAAG,CAAC,CAAC,MAAM,GAAG,CAAC,CAAC;AAC3C,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,gBAAgB,CAAC,MAAc;IAC7C,MAAM,GAAG,GAAG,MAAM,CAAC,IAAI,EAAE,CAAC;IAC1B,IAAI,GAAG,CAAC,UAAU,CAAC,MAAM,CAAC;QAAE,OAAO,GAAG,CAAC;IACvC,MAAM,GAAG,GAAG,gCAAgC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;IACvD,IAAI,GAAG;QAAE,OAAO,aAAa,GAAG,CAAC,CAAC,CAAC,IAAI,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC;IAChD,IAAI,oBAAoB,CAAC,IAAI,CAAC,GAAG,CAAC;QAAE,OAAO,OAAO,GAAG,EAAE,CAAC;IACxD,OAAO,GAAG,CAAC;AACb,CAAC","sourcesContent":["/**\n * Where `linked create-package` puts a new package, decided without touching\n * anything — the IO lives in `createPackage`.\n *\n * Inside an app there are two homes, and they mean different things:\n *\n * - `packages/` — the package is part of the app's own repository: a tracked\n * npm workspace member, declared as a dependency like any other.\n * - `packages-local/` — the package has a repository of its own. It goes where\n * `linked localize` keeps checkouts, under the same name localize would give\n * it (`@_linked/foo` → `packages-local/_linked-foo`), and is handed to\n * localize's `adopt`, so the two can never disagree about it.\n */\nimport fs from 'fs';\nimport path from 'path';\nimport type {PackageKind} from './packageKind.js';\nimport {ensureRelinkHooks} from './relinkHooks.js';\n\nexport const PACKAGE_LOCATIONS = ['packages', 'packages-local'] as const;\nexport type PackageLocation = (typeof PACKAGE_LOCATIONS)[number];\n\nexport interface CreatePackageOptions {\n /** Validated at runtime too, since the command line passes any string. */\n location?: PackageLocation;\n /** A git URL. Implies `packages-local`. */\n remote?: string;\n /** Push the initial commit. Needs `remote`. */\n push?: boolean;\n /**\n * What to scaffold: an ontology package, an asset package or both. See\n * `./packageKind.js`. Validated at runtime too.\n */\n kind?: PackageKind;\n /** Write the files only: no install, no build, no git. */\n skipInstall?: boolean;\n /**\n * The root the package's IRIs are minted under. Inside an app it defaults to the\n * app's `LINKED_BASE_URI`; see `./packageBaseUri.js`.\n */\n baseUri?: string;\n}\n\n/**\n * - `outside`: no app above us — the old behaviour, unchanged.\n * - `resolved`: the flags (or the prompt's answers) settle it.\n * - `ask`: inside an app, no flags, on a terminal.\n * - `refuse`: a contradiction, or no answer and no terminal to ask.\n */\nexport type TargetDecision =\n | {kind: 'outside'}\n | {kind: 'resolved'; location: PackageLocation; remote?: string; push: boolean}\n | {kind: 'ask'}\n | {kind: 'refuse'; message: string};\n\n/** A refusal of create-package's own, as opposed to a crash. */\nexport class CreatePackageError extends Error {\n constructor(message: string) {\n super(message);\n this.name = 'CreatePackageError';\n }\n}\n\n/**\n * The nearest directory, from `start` upwards, whose package.json says\n * `linkedApp: true`. That is the app — whether or not it has `workspaces`,\n * which the app template does not.\n */\nexport function findLinkedAppRoot(start: string): string | null {\n let dir = path.resolve(start);\n // eslint-disable-next-line no-constant-condition\n while (true) {\n try {\n const pkg = JSON.parse(\n fs.readFileSync(path.join(dir, 'package.json'), 'utf8'),\n );\n if (pkg?.linkedApp === true) return dir;\n } catch {\n // no package.json here, or not one we can read: keep walking\n }\n const parent = path.dirname(dir);\n if (parent === dir) return null;\n dir = parent;\n }\n}\n\n/**\n * Flags decide everything they can. Any of `--location`, `--remote` or\n * `--push` is taken as the complete answer, so a scripted call never meets a\n * prompt; with none of them, a terminal is asked and anything else is refused.\n */\nexport function decideCreatePackageTarget({\n appRoot,\n options,\n isTTY,\n}: {\n appRoot: string | null;\n options: CreatePackageOptions;\n isTTY: boolean;\n}): TargetDecision {\n const {remote, push = false} = options;\n const location: string | undefined = options.location;\n const given = location !== undefined || remote !== undefined || push;\n\n if (location !== undefined && !isPackageLocation(location)) {\n return refuse(\n `--location must be one of ${PACKAGE_LOCATIONS.join(', ')}, not \"${location}\".`,\n );\n }\n if (!appRoot) {\n return given\n ? refuse(\n `--location, --remote and --push only apply inside a linked app, and no package.json ` +\n `with \"linkedApp\": true was found above this directory.`,\n )\n : {kind: 'outside'};\n }\n if (push && !remote) {\n return refuse('--push needs --remote: there is nowhere to push to.');\n }\n if (remote && location === 'packages') {\n return refuse(\n `--remote gives the package a repository of its own, but packages/ is for packages that ` +\n `live in the app's repository. Use --location packages-local, or drop --remote.`,\n );\n }\n if (given) {\n return {\n kind: 'resolved',\n location: (location as PackageLocation) ?? 'packages-local',\n ...(remote ? {remote} : {}),\n push,\n };\n }\n if (isTTY) return {kind: 'ask'};\n return refuse(\n `Where should the package go? Pass --location packages (part of this app's repository) or ` +\n `--location packages-local (its own repository, optionally with --remote <git-url>).`,\n );\n}\n\nexport function isPackageLocation(value: string): value is PackageLocation {\n return (PACKAGE_LOCATIONS as readonly string[]).includes(value);\n}\n\nfunction refuse(message: string): TargetDecision {\n return {kind: 'refuse', message};\n}\n\n/** `@scope/foo-bar` → `foo-bar`: the folder name under `packages/`. */\nexport function bareName(name: string): string {\n const match = name.match(/(@[\\w\\-]+\\/)?([\\w\\-]+)/);\n if (!match) {\n throw new CreatePackageError(`\"${name}\" is not a usable package name.`);\n }\n return match[2];\n}\n\n/**\n * Make sure the app's `workspaces` covers `packages/*`, so a package created\n * there is a workspace member. Mutates `pkg`.\n *\n * @returns whether it changed, and a warning when it cannot tell.\n */\nexport function ensureWorkspaceGlob(pkg: Record<string, any>): {\n changed: boolean;\n warning?: string;\n} {\n const covers = (globs: unknown[]) =>\n globs.some((g) => g === 'packages/*' || g === 'packages/**');\n\n if (pkg.workspaces === undefined) {\n pkg.workspaces = ['packages/*'];\n return {changed: true};\n }\n const globs = Array.isArray(pkg.workspaces)\n ? pkg.workspaces\n : Array.isArray(pkg.workspaces?.packages)\n ? pkg.workspaces.packages\n : null;\n if (!globs) {\n return {\n changed: false,\n warning: `the app's \"workspaces\" field has a shape this command does not edit; make sure it covers packages/*.`,\n };\n }\n if (covers(globs)) return {changed: false};\n globs.push('packages/*');\n return {changed: true};\n}\n\nexport {RELINK_COMMAND, ensureRelinkHooks} from './relinkHooks.js';\n\n/**\n * Make sure the app's `postinstall` AND `dependencies` scripts recreate\n * localize's links -- see `./relinkHooks.js` for why npm needs both. Kept\n * under its old name for existing callers; prefer `ensureRelinkHooks`.\n * Mutates `pkg`.\n *\n * @returns true when it changed `pkg`.\n */\nexport function ensureRelinkPostinstall(pkg: Record<string, any>): boolean {\n return ensureRelinkHooks(pkg).length > 0;\n}\n\n/**\n * A git remote as npm wants it in `repository.url`: `git+https://…`, or\n * `git+ssh://git@host/path` for the scp-like `git@host:path` form.\n */\nexport function repositoryUrlFor(remote: string): string {\n const url = remote.trim();\n if (url.startsWith('git+')) return url;\n const scp = /^([\\w.-]+@[\\w.-]+):(?!\\/)(.+)$/.exec(url);\n if (scp) return `git+ssh://${scp[1]}/${scp[2]}`;\n if (/^(https?|ssh):\\/\\//.test(url)) return `git+${url}`;\n return url;\n}\n"]}
1
+ {"version":3,"file":"createPackageLocation.js","sourceRoot":"","sources":["../../../src/utils/createPackageLocation.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Where `linked create-package` puts a new package, decided without touching\n * anything — the IO lives in `createPackage`.\n *\n * Inside an app there are two homes, and they mean different things:\n *\n * - `packages/` — the package is part of the app's own repository: a tracked\n * npm workspace member, declared as a dependency like any other.\n * - `packages-local/` — the package has a repository of its own. It goes where\n * `linked localize` keeps checkouts, under the same name localize would give\n * it (`@_linked/foo` → `packages-local/_linked-foo`), and is handed to\n * localize's `adopt`, so the two can never disagree about it. Like every\n * checkout it is a workspace member through the app's `packages-local/*`\n * glob.\n */\nimport fs from 'fs';\nimport path from 'path';\nimport type {PackageKind} from './packageKind.js';\n\nexport const PACKAGE_LOCATIONS = ['packages', 'packages-local'] as const;\nexport type PackageLocation = (typeof PACKAGE_LOCATIONS)[number];\n\nexport interface CreatePackageOptions {\n /** Validated at runtime too, since the command line passes any string. */\n location?: PackageLocation;\n /** A git URL. Implies `packages-local`. */\n remote?: string;\n /** Push the initial commit. Needs `remote`. */\n push?: boolean;\n /**\n * What to scaffold: an ontology package, an asset package or both. See\n * `./packageKind.js`. Validated at runtime too.\n */\n kind?: PackageKind;\n /** Write the files only: no install, no build, no git. */\n skipInstall?: boolean;\n /**\n * The root the package's IRIs are minted under. Inside an app it defaults to the\n * app's `LINKED_BASE_URI`; see `./packageBaseUri.js`.\n */\n baseUri?: string;\n}\n\n/**\n * - `outside`: no app above us — the old behaviour, unchanged.\n * - `resolved`: the flags (or the prompt's answers) settle it.\n * - `ask`: inside an app, no flags, on a terminal.\n * - `refuse`: a contradiction, or no answer and no terminal to ask.\n */\nexport type TargetDecision =\n | {kind: 'outside'}\n | {kind: 'resolved'; location: PackageLocation; remote?: string; push: boolean}\n | {kind: 'ask'}\n | {kind: 'refuse'; message: string};\n\n/** A refusal of create-package's own, as opposed to a crash. */\nexport class CreatePackageError extends Error {\n constructor(message: string) {\n super(message);\n this.name = 'CreatePackageError';\n }\n}\n\n/**\n * The nearest directory, from `start` upwards, whose package.json says\n * `linkedApp: true`. That is the app — whether or not it has `workspaces`,\n * which the app template does not.\n */\nexport function findLinkedAppRoot(start: string): string | null {\n let dir = path.resolve(start);\n // eslint-disable-next-line no-constant-condition\n while (true) {\n try {\n const pkg = JSON.parse(\n fs.readFileSync(path.join(dir, 'package.json'), 'utf8'),\n );\n if (pkg?.linkedApp === true) return dir;\n } catch {\n // no package.json here, or not one we can read: keep walking\n }\n const parent = path.dirname(dir);\n if (parent === dir) return null;\n dir = parent;\n }\n}\n\n/**\n * Flags decide everything they can. Any of `--location`, `--remote` or\n * `--push` is taken as the complete answer, so a scripted call never meets a\n * prompt; with none of them, a terminal is asked and anything else is refused.\n */\nexport function decideCreatePackageTarget({\n appRoot,\n options,\n isTTY,\n}: {\n appRoot: string | null;\n options: CreatePackageOptions;\n isTTY: boolean;\n}): TargetDecision {\n const {remote, push = false} = options;\n const location: string | undefined = options.location;\n const given = location !== undefined || remote !== undefined || push;\n\n if (location !== undefined && !isPackageLocation(location)) {\n return refuse(\n `--location must be one of ${PACKAGE_LOCATIONS.join(', ')}, not \"${location}\".`,\n );\n }\n if (!appRoot) {\n return given\n ? refuse(\n `--location, --remote and --push only apply inside a linked app, and no package.json ` +\n `with \"linkedApp\": true was found above this directory.`,\n )\n : {kind: 'outside'};\n }\n if (push && !remote) {\n return refuse('--push needs --remote: there is nowhere to push to.');\n }\n if (remote && location === 'packages') {\n return refuse(\n `--remote gives the package a repository of its own, but packages/ is for packages that ` +\n `live in the app's repository. Use --location packages-local, or drop --remote.`,\n );\n }\n if (given) {\n return {\n kind: 'resolved',\n location: (location as PackageLocation) ?? 'packages-local',\n ...(remote ? {remote} : {}),\n push,\n };\n }\n if (isTTY) return {kind: 'ask'};\n return refuse(\n `Where should the package go? Pass --location packages (part of this app's repository) or ` +\n `--location packages-local (its own repository, optionally with --remote <git-url>).`,\n );\n}\n\nexport function isPackageLocation(value: string): value is PackageLocation {\n return (PACKAGE_LOCATIONS as readonly string[]).includes(value);\n}\n\nfunction refuse(message: string): TargetDecision {\n return {kind: 'refuse', message};\n}\n\n/** `@scope/foo-bar` → `foo-bar`: the folder name under `packages/`. */\nexport function bareName(name: string): string {\n const match = name.match(/(@[\\w\\-]+\\/)?([\\w\\-]+)/);\n if (!match) {\n throw new CreatePackageError(`\"${name}\" is not a usable package name.`);\n }\n return match[2];\n}\n\n/**\n * Make sure the app's `workspaces` covers `<location>/*` (default\n * `packages/*`), so a package created there is a workspace member. Mutates\n * `pkg`.\n *\n * @returns whether it changed, and a warning when it cannot tell.\n */\nexport function ensureWorkspaceGlob(\n pkg: Record<string, any>,\n location: PackageLocation = 'packages',\n): {\n changed: boolean;\n warning?: string;\n} {\n const glob = `${location}/*`;\n const covers = (globs: unknown[]) =>\n globs.some((g) => g === glob || g === `${location}/**`);\n\n if (pkg.workspaces === undefined) {\n pkg.workspaces = [glob];\n return {changed: true};\n }\n const globs = Array.isArray(pkg.workspaces)\n ? pkg.workspaces\n : Array.isArray(pkg.workspaces?.packages)\n ? pkg.workspaces.packages\n : null;\n if (!globs) {\n return {\n changed: false,\n warning: `the app's \"workspaces\" field has a shape this command does not edit; make sure it covers ${glob}.`,\n };\n }\n if (covers(globs)) return {changed: false};\n globs.push(glob);\n return {changed: true};\n}\n\n/**\n * A git remote as npm wants it in `repository.url`: `git+https://…`, or\n * `git+ssh://git@host/path` for the scp-like `git@host:path` form.\n */\nexport function repositoryUrlFor(remote: string): string {\n const url = remote.trim();\n if (url.startsWith('git+')) return url;\n const scp = /^([\\w.-]+@[\\w.-]+):(?!\\/)(.+)$/.exec(url);\n if (scp) return `git+ssh://${scp[1]}/${scp[2]}`;\n if (/^(https?|ssh):\\/\\//.test(url)) return `git+${url}`;\n return url;\n}\n"]}
@@ -18,7 +18,10 @@ export type PackageSetupPlan = {
18
18
  * package is pinned to the node-modules linker. Yarn 1 ignores .yarnrc.yml.
19
19
  * - The build runs through the CLI that is currently executing (node + its own
20
20
  * launch script) instead of `npm exec linked`, which cannot resolve a bin
21
- * that a different package manager installed.
21
+ * that a different package manager installed. Both paths are quoted for the
22
+ * shell that runs the command: `cmd.exe` on Windows, where a path cannot
23
+ * hold a `"` and a JSON string's doubled backslashes would be taken as
24
+ * they are.
22
25
  */
23
- export declare function planPackageSetup(yarnVersionOutput: string, launchScript: string, nodeBinary?: string, insideYarnProject?: boolean): PackageSetupPlan;
26
+ export declare function planPackageSetup(yarnVersionOutput: string, launchScript: string, nodeBinary?: string, insideYarnProject?: boolean, platform?: NodeJS.Platform): PackageSetupPlan;
24
27
  //# sourceMappingURL=packageSetup.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"packageSetup.d.ts","sourceRoot":"","sources":["../../../src/utils/packageSetup.ts"],"names":[],"mappings":"AAEA,MAAM,MAAM,gBAAgB,GAAG;IAC7B,cAAc,EAAE,MAAM,GAAG,KAAK,CAAC;IAC/B,gFAAgF;IAChF,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;IACtB,cAAc,EAAE,MAAM,CAAC;IACvB,YAAY,EAAE,MAAM,CAAC;CACtB,CAAC;AAEF;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,gBAAgB,CAC9B,iBAAiB,EAAE,MAAM,EACzB,YAAY,EAAE,MAAM,EACpB,UAAU,GAAE,MAAyB,EACrC,iBAAiB,GAAE,OAAe,GACjC,gBAAgB,CAiBlB"}
1
+ {"version":3,"file":"packageSetup.d.ts","sourceRoot":"","sources":["../../../src/utils/packageSetup.ts"],"names":[],"mappings":"AAEA,MAAM,MAAM,gBAAgB,GAAG;IAC7B,cAAc,EAAE,MAAM,GAAG,KAAK,CAAC;IAC/B,gFAAgF;IAChF,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;IACtB,cAAc,EAAE,MAAM,CAAC;IACvB,YAAY,EAAE,MAAM,CAAC;CACtB,CAAC;AAEF;;;;;;;;;;;;;;;;;GAiBG;AACH,wBAAgB,gBAAgB,CAC9B,iBAAiB,EAAE,MAAM,EACzB,YAAY,EAAE,MAAM,EACpB,UAAU,GAAE,MAAyB,EACrC,iBAAiB,GAAE,OAAe,EAClC,QAAQ,GAAE,MAAM,CAAC,QAA2B,GAC3C,gBAAgB,CAoBlB"}
@@ -12,9 +12,12 @@ import path from 'path';
12
12
  * package is pinned to the node-modules linker. Yarn 1 ignores .yarnrc.yml.
13
13
  * - The build runs through the CLI that is currently executing (node + its own
14
14
  * launch script) instead of `npm exec linked`, which cannot resolve a bin
15
- * that a different package manager installed.
15
+ * that a different package manager installed. Both paths are quoted for the
16
+ * shell that runs the command: `cmd.exe` on Windows, where a path cannot
17
+ * hold a `"` and a JSON string's doubled backslashes would be taken as
18
+ * they are.
16
19
  */
17
- export function planPackageSetup(yarnVersionOutput, launchScript, nodeBinary = process.execPath, insideYarnProject = false) {
20
+ export function planPackageSetup(yarnVersionOutput, launchScript, nodeBinary = process.execPath, insideYarnProject = false, platform = process.platform) {
18
21
  const match = (yarnVersionOutput || '').trim().match(/^(\d+)\./);
19
22
  const yarnMajor = !insideYarnProject
20
23
  ? null
@@ -28,7 +31,10 @@ export function planPackageSetup(yarnVersionOutput, launchScript, nodeBinary = p
28
31
  ? 'nodeLinker: node-modules\n'
29
32
  : null,
30
33
  installCommand: packageManager === 'yarn' ? 'yarn install' : 'npm install',
31
- buildCommand: `${JSON.stringify(nodeBinary)} ${JSON.stringify(path.resolve(launchScript))} build`,
34
+ buildCommand: `${quotePath(nodeBinary, platform)} ${quotePath((platform === 'win32' ? path.win32 : path).resolve(launchScript), platform)} build`,
32
35
  };
33
36
  }
37
+ function quotePath(p, platform) {
38
+ return platform === 'win32' ? `"${p}"` : JSON.stringify(p);
39
+ }
34
40
  //# sourceMappingURL=packageSetup.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"packageSetup.js","sourceRoot":"","sources":["../../../src/utils/packageSetup.ts"],"names":[],"mappings":"AAAA,OAAO,IAAI,MAAM,MAAM,CAAC;AAUxB;;;;;;;;;;;;;;GAcG;AACH,MAAM,UAAU,gBAAgB,CAC9B,iBAAyB,EACzB,YAAoB,EACpB,aAAqB,OAAO,CAAC,QAAQ,EACrC,oBAA6B,KAAK;IAElC,MAAM,KAAK,GAAG,CAAC,iBAAiB,IAAI,EAAE,CAAC,CAAC,IAAI,EAAE,CAAC,KAAK,CAAC,UAAU,CAAC,CAAC;IACjE,MAAM,SAAS,GAAG,CAAC,iBAAiB;QAClC,CAAC,CAAC,IAAI;QACN,CAAC,CAAC,KAAK;YACL,CAAC,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC;YACxB,CAAC,CAAC,IAAI,CAAC;IACX,MAAM,cAAc,GAAG,SAAS,KAAK,IAAI,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,CAAC;IAC3D,OAAO;QACL,cAAc;QACd,MAAM,EACJ,SAAS,KAAK,IAAI,IAAI,SAAS,IAAI,CAAC;YAClC,CAAC,CAAC,4BAA4B;YAC9B,CAAC,CAAC,IAAI;QACV,cAAc,EAAE,cAAc,KAAK,MAAM,CAAC,CAAC,CAAC,cAAc,CAAC,CAAC,CAAC,aAAa;QAC1E,YAAY,EAAE,GAAG,IAAI,CAAC,SAAS,CAAC,UAAU,CAAC,IAAI,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,OAAO,CAAC,YAAY,CAAC,CAAC,QAAQ;KAClG,CAAC;AACJ,CAAC","sourcesContent":["import path from 'path';\n\nexport type PackageSetupPlan = {\n packageManager: 'yarn' | 'npm';\n /** Contents for a `.yarnrc.yml` in the new package, or null when not needed. */\n yarnrc: string | null;\n installCommand: string;\n buildCommand: string;\n};\n\n/**\n * Plans the install + first build of a freshly scaffolded linked package.\n *\n * - npm is the default. yarn is only used when the new package lands inside an\n * existing yarn project (`insideYarnProject`) — e.g. a package added to a\n * yarn-3 monorepo — because mixing npm into such a workspace produces a\n * second lockfile and an unresolvable bin. Merely having yarn on PATH is no\n * longer enough to pick it.\n * - Yarn 2+ defaults to Plug'n'Play, which leaves no node_modules. The build\n * step shells out to `npx tsc` / `npx tsconfig-to-dual-package`, so the\n * package is pinned to the node-modules linker. Yarn 1 ignores .yarnrc.yml.\n * - The build runs through the CLI that is currently executing (node + its own\n * launch script) instead of `npm exec linked`, which cannot resolve a bin\n * that a different package manager installed.\n */\nexport function planPackageSetup(\n yarnVersionOutput: string,\n launchScript: string,\n nodeBinary: string = process.execPath,\n insideYarnProject: boolean = false,\n): PackageSetupPlan {\n const match = (yarnVersionOutput || '').trim().match(/^(\\d+)\\./);\n const yarnMajor = !insideYarnProject\n ? null\n : match\n ? parseInt(match[1], 10)\n : null;\n const packageManager = yarnMajor === null ? 'npm' : 'yarn';\n return {\n packageManager,\n yarnrc:\n yarnMajor !== null && yarnMajor >= 2\n ? 'nodeLinker: node-modules\\n'\n : null,\n installCommand: packageManager === 'yarn' ? 'yarn install' : 'npm install',\n buildCommand: `${JSON.stringify(nodeBinary)} ${JSON.stringify(path.resolve(launchScript))} build`,\n };\n}\n"]}
1
+ {"version":3,"file":"packageSetup.js","sourceRoot":"","sources":["../../../src/utils/packageSetup.ts"],"names":[],"mappings":"AAAA,OAAO,IAAI,MAAM,MAAM,CAAC;AAUxB;;;;;;;;;;;;;;;;;GAiBG;AACH,MAAM,UAAU,gBAAgB,CAC9B,iBAAyB,EACzB,YAAoB,EACpB,aAAqB,OAAO,CAAC,QAAQ,EACrC,oBAA6B,KAAK,EAClC,WAA4B,OAAO,CAAC,QAAQ;IAE5C,MAAM,KAAK,GAAG,CAAC,iBAAiB,IAAI,EAAE,CAAC,CAAC,IAAI,EAAE,CAAC,KAAK,CAAC,UAAU,CAAC,CAAC;IACjE,MAAM,SAAS,GAAG,CAAC,iBAAiB;QAClC,CAAC,CAAC,IAAI;QACN,CAAC,CAAC,KAAK;YACL,CAAC,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC;YACxB,CAAC,CAAC,IAAI,CAAC;IACX,MAAM,cAAc,GAAG,SAAS,KAAK,IAAI,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,CAAC;IAC3D,OAAO;QACL,cAAc;QACd,MAAM,EACJ,SAAS,KAAK,IAAI,IAAI,SAAS,IAAI,CAAC;YAClC,CAAC,CAAC,4BAA4B;YAC9B,CAAC,CAAC,IAAI;QACV,cAAc,EAAE,cAAc,KAAK,MAAM,CAAC,CAAC,CAAC,cAAc,CAAC,CAAC,CAAC,aAAa;QAC1E,YAAY,EAAE,GAAG,SAAS,CAAC,UAAU,EAAE,QAAQ,CAAC,IAAI,SAAS,CAC3D,CAAC,QAAQ,KAAK,OAAO,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,OAAO,CAAC,YAAY,CAAC,EAChE,QAAQ,CACT,QAAQ;KACV,CAAC;AACJ,CAAC;AAED,SAAS,SAAS,CAAC,CAAS,EAAE,QAAyB;IACrD,OAAO,QAAQ,KAAK,OAAO,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC;AAC7D,CAAC","sourcesContent":["import path from 'path';\n\nexport type PackageSetupPlan = {\n packageManager: 'yarn' | 'npm';\n /** Contents for a `.yarnrc.yml` in the new package, or null when not needed. */\n yarnrc: string | null;\n installCommand: string;\n buildCommand: string;\n};\n\n/**\n * Plans the install + first build of a freshly scaffolded linked package.\n *\n * - npm is the default. yarn is only used when the new package lands inside an\n * existing yarn project (`insideYarnProject`) — e.g. a package added to a\n * yarn-3 monorepo — because mixing npm into such a workspace produces a\n * second lockfile and an unresolvable bin. Merely having yarn on PATH is no\n * longer enough to pick it.\n * - Yarn 2+ defaults to Plug'n'Play, which leaves no node_modules. The build\n * step shells out to `npx tsc` / `npx tsconfig-to-dual-package`, so the\n * package is pinned to the node-modules linker. Yarn 1 ignores .yarnrc.yml.\n * - The build runs through the CLI that is currently executing (node + its own\n * launch script) instead of `npm exec linked`, which cannot resolve a bin\n * that a different package manager installed. Both paths are quoted for the\n * shell that runs the command: `cmd.exe` on Windows, where a path cannot\n * hold a `\"` and a JSON string's doubled backslashes would be taken as\n * they are.\n */\nexport function planPackageSetup(\n yarnVersionOutput: string,\n launchScript: string,\n nodeBinary: string = process.execPath,\n insideYarnProject: boolean = false,\n platform: NodeJS.Platform = process.platform,\n): PackageSetupPlan {\n const match = (yarnVersionOutput || '').trim().match(/^(\\d+)\\./);\n const yarnMajor = !insideYarnProject\n ? null\n : match\n ? parseInt(match[1], 10)\n : null;\n const packageManager = yarnMajor === null ? 'npm' : 'yarn';\n return {\n packageManager,\n yarnrc:\n yarnMajor !== null && yarnMajor >= 2\n ? 'nodeLinker: node-modules\\n'\n : null,\n installCommand: packageManager === 'yarn' ? 'yarn install' : 'npm install',\n buildCommand: `${quotePath(nodeBinary, platform)} ${quotePath(\n (platform === 'win32' ? path.win32 : path).resolve(launchScript),\n platform,\n )} build`,\n };\n}\n\nfunction quotePath(p: string, platform: NodeJS.Platform): string {\n return platform === 'win32' ? `\"${p}\"` : JSON.stringify(p);\n}\n"]}
@@ -0,0 +1,24 @@
1
+ /** Do `a` and `b` name the same path on `platform`? No filesystem access. */
2
+ export declare function samePath(a: string, b: string, platform?: NodeJS.Platform): boolean;
3
+ /** Is `child` at or below `parent` on `platform`? No filesystem access. */
4
+ export declare function isPathInside(child: string, parent: string, platform?: NodeJS.Platform): boolean;
5
+ /**
6
+ * Link `linkPath` to the directory `target`. On Windows a junction, with an
7
+ * absolute target (a junction cannot be relative); elsewhere a relative
8
+ * symlink, so moving the app keeps it working.
9
+ */
10
+ export declare function linkDirectory(target: string, linkPath: string, platform?: NodeJS.Platform, symlink?: (target: string, linkPath: string, type: 'dir' | 'junction') => void): void;
11
+ /**
12
+ * What to pass to `import()` for the absolute path `file`: on Windows its
13
+ * `file:` URL (`import('C:\\x.js')` fails: `c:` reads as a URL scheme);
14
+ * elsewhere the path itself, which Node takes as it is.
15
+ */
16
+ export declare function importSpecifier(file: string, platform?: NodeJS.Platform): string;
17
+ /** `import()` of a file by its absolute path. */
18
+ export declare function importFile<T = any>(file: string): Promise<T>;
19
+ /**
20
+ * `text` with the line endings of `original`: CRLF throughout when `original`
21
+ * uses CRLF (a checkout with `core.autocrlf`), else `text` unchanged.
22
+ */
23
+ export declare function withEolOf(text: string, original: string): string;
24
+ //# sourceMappingURL=platform.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"platform.d.ts","sourceRoot":"","sources":["../../../src/utils/platform.ts"],"names":[],"mappings":"AAoBA,6EAA6E;AAC7E,wBAAgB,QAAQ,CACtB,CAAC,EAAE,MAAM,EACT,CAAC,EAAE,MAAM,EACT,QAAQ,GAAE,MAAM,CAAC,QAA2B,GAC3C,OAAO,CAET;AAED,2EAA2E;AAC3E,wBAAgB,YAAY,CAC1B,KAAK,EAAE,MAAM,EACb,MAAM,EAAE,MAAM,EACd,QAAQ,GAAE,MAAM,CAAC,QAA2B,GAC3C,OAAO,CAWT;AAED;;;;GAIG;AACH,wBAAgB,aAAa,CAC3B,MAAM,EAAE,MAAM,EACd,QAAQ,EAAE,MAAM,EAChB,QAAQ,GAAE,MAAM,CAAC,QAA2B,EAC5C,OAAO,GAAE,CACP,MAAM,EAAE,MAAM,EACd,QAAQ,EAAE,MAAM,EAChB,IAAI,EAAE,KAAK,GAAG,UAAU,KACrB,IAAqB,GACzB,IAAI,CAMN;AAED;;;;GAIG;AACH,wBAAgB,eAAe,CAC7B,IAAI,EAAE,MAAM,EACZ,QAAQ,GAAE,MAAM,CAAC,QAA2B,GAC3C,MAAM,CAGR;AAED,iDAAiD;AACjD,wBAAgB,UAAU,CAAC,CAAC,GAAG,GAAG,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,CAAC,CAAC,CAE5D;AAED;;;GAGG;AACH,wBAAgB,SAAS,CAAC,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,MAAM,CAEhE"}
@@ -0,0 +1,62 @@
1
+ /**
2
+ * Filesystem rules that differ on Windows, in one place: path identity
3
+ * (case-insensitive, either separator), directory links (junctions, which
4
+ * need no administrator rights or Developer Mode), `import()` of a path (a
5
+ * `file:` URL, since `C:\…` reads as a URL scheme) and line endings kept when
6
+ * a file is rewritten. Each takes the platform so tests can ask for the other.
7
+ */
8
+ import fs from 'node:fs';
9
+ import path from 'node:path';
10
+ import { pathToFileURL } from 'node:url';
11
+ const pathFor = (platform) => platform === 'win32' ? path.win32 : path.posix;
12
+ /** Paths as compared on `platform`: resolved, and lower-cased where the filesystem ignores case. */
13
+ function comparable(p, platform) {
14
+ const resolved = pathFor(platform).resolve(p);
15
+ return platform === 'win32' ? resolved.toLowerCase() : resolved;
16
+ }
17
+ /** Do `a` and `b` name the same path on `platform`? No filesystem access. */
18
+ export function samePath(a, b, platform = process.platform) {
19
+ return comparable(a, platform) === comparable(b, platform);
20
+ }
21
+ /** Is `child` at or below `parent` on `platform`? No filesystem access. */
22
+ export function isPathInside(child, parent, platform = process.platform) {
23
+ const p = pathFor(platform);
24
+ const rel = p.relative(comparable(parent, platform), comparable(child, platform));
25
+ // `..foo` is a child named `..foo`; only `..` itself or a `../` prefix leaves `parent`.
26
+ return (rel === '' ||
27
+ (rel !== '..' && !rel.startsWith('..' + p.sep) && !p.isAbsolute(rel)));
28
+ }
29
+ /**
30
+ * Link `linkPath` to the directory `target`. On Windows a junction, with an
31
+ * absolute target (a junction cannot be relative); elsewhere a relative
32
+ * symlink, so moving the app keeps it working.
33
+ */
34
+ export function linkDirectory(target, linkPath, platform = process.platform, symlink = fs.symlinkSync) {
35
+ if (platform === 'win32') {
36
+ symlink(path.win32.resolve(target), linkPath, 'junction');
37
+ return;
38
+ }
39
+ symlink(path.relative(path.dirname(linkPath), target), linkPath, 'dir');
40
+ }
41
+ /**
42
+ * What to pass to `import()` for the absolute path `file`: on Windows its
43
+ * `file:` URL (`import('C:\\x.js')` fails: `c:` reads as a URL scheme);
44
+ * elsewhere the path itself, which Node takes as it is.
45
+ */
46
+ export function importSpecifier(file, platform = process.platform) {
47
+ if (platform !== 'win32')
48
+ return file;
49
+ return pathToFileURL(path.win32.resolve(file), { windows: true }).href;
50
+ }
51
+ /** `import()` of a file by its absolute path. */
52
+ export function importFile(file) {
53
+ return import(/* @vite-ignore */ importSpecifier(file));
54
+ }
55
+ /**
56
+ * `text` with the line endings of `original`: CRLF throughout when `original`
57
+ * uses CRLF (a checkout with `core.autocrlf`), else `text` unchanged.
58
+ */
59
+ export function withEolOf(text, original) {
60
+ return original.includes('\r\n') ? text.replace(/\r?\n/g, '\r\n') : text;
61
+ }
62
+ //# sourceMappingURL=platform.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"platform.js","sourceRoot":"","sources":["../../../src/utils/platform.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AACH,OAAO,EAAE,MAAM,SAAS,CAAC;AACzB,OAAO,IAAI,MAAM,WAAW,CAAC;AAC7B,OAAO,EAAC,aAAa,EAAC,MAAM,UAAU,CAAC;AAEvC,MAAM,OAAO,GAAG,CAAC,QAAyB,EAAE,EAAE,CAC5C,QAAQ,KAAK,OAAO,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC;AAEjD,oGAAoG;AACpG,SAAS,UAAU,CAAC,CAAS,EAAE,QAAyB;IACtD,MAAM,QAAQ,GAAG,OAAO,CAAC,QAAQ,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC;IAC9C,OAAO,QAAQ,KAAK,OAAO,CAAC,CAAC,CAAC,QAAQ,CAAC,WAAW,EAAE,CAAC,CAAC,CAAC,QAAQ,CAAC;AAClE,CAAC;AAED,6EAA6E;AAC7E,MAAM,UAAU,QAAQ,CACtB,CAAS,EACT,CAAS,EACT,WAA4B,OAAO,CAAC,QAAQ;IAE5C,OAAO,UAAU,CAAC,CAAC,EAAE,QAAQ,CAAC,KAAK,UAAU,CAAC,CAAC,EAAE,QAAQ,CAAC,CAAC;AAC7D,CAAC;AAED,2EAA2E;AAC3E,MAAM,UAAU,YAAY,CAC1B,KAAa,EACb,MAAc,EACd,WAA4B,OAAO,CAAC,QAAQ;IAE5C,MAAM,CAAC,GAAG,OAAO,CAAC,QAAQ,CAAC,CAAC;IAC5B,MAAM,GAAG,GAAG,CAAC,CAAC,QAAQ,CACpB,UAAU,CAAC,MAAM,EAAE,QAAQ,CAAC,EAC5B,UAAU,CAAC,KAAK,EAAE,QAAQ,CAAC,CAC5B,CAAC;IACF,wFAAwF;IACxF,OAAO,CACL,GAAG,KAAK,EAAE;QACV,CAAC,GAAG,KAAK,IAAI,IAAI,CAAC,GAAG,CAAC,UAAU,CAAC,IAAI,GAAG,CAAC,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC,CACtE,CAAC;AACJ,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,aAAa,CAC3B,MAAc,EACd,QAAgB,EAChB,WAA4B,OAAO,CAAC,QAAQ,EAC5C,UAIY,EAAE,CAAC,WAAW;IAE1B,IAAI,QAAQ,KAAK,OAAO,EAAE,CAAC;QACzB,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC,EAAE,QAAQ,EAAE,UAAU,CAAC,CAAC;QAC1D,OAAO;IACT,CAAC;IACD,OAAO,CAAC,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,EAAE,MAAM,CAAC,EAAE,QAAQ,EAAE,KAAK,CAAC,CAAC;AAC1E,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,eAAe,CAC7B,IAAY,EACZ,WAA4B,OAAO,CAAC,QAAQ;IAE5C,IAAI,QAAQ,KAAK,OAAO;QAAE,OAAO,IAAI,CAAC;IACtC,OAAO,aAAa,CAAC,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE,EAAC,OAAO,EAAE,IAAI,EAAC,CAAC,CAAC,IAAI,CAAC;AACvE,CAAC;AAED,iDAAiD;AACjD,MAAM,UAAU,UAAU,CAAU,IAAY;IAC9C,OAAO,MAAM,CAAC,kBAAkB,CAAC,eAAe,CAAC,IAAI,CAAC,CAAC,CAAC;AAC1D,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,SAAS,CAAC,IAAY,EAAE,QAAgB;IACtD,OAAO,QAAQ,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,QAAQ,EAAE,MAAM,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;AAC3E,CAAC","sourcesContent":["/**\n * Filesystem rules that differ on Windows, in one place: path identity\n * (case-insensitive, either separator), directory links (junctions, which\n * need no administrator rights or Developer Mode), `import()` of a path (a\n * `file:` URL, since `C:\\…` reads as a URL scheme) and line endings kept when\n * a file is rewritten. Each takes the platform so tests can ask for the other.\n */\nimport fs from 'node:fs';\nimport path from 'node:path';\nimport {pathToFileURL} from 'node:url';\n\nconst pathFor = (platform: NodeJS.Platform) =>\n platform === 'win32' ? path.win32 : path.posix;\n\n/** Paths as compared on `platform`: resolved, and lower-cased where the filesystem ignores case. */\nfunction comparable(p: string, platform: NodeJS.Platform): string {\n const resolved = pathFor(platform).resolve(p);\n return platform === 'win32' ? resolved.toLowerCase() : resolved;\n}\n\n/** Do `a` and `b` name the same path on `platform`? No filesystem access. */\nexport function samePath(\n a: string,\n b: string,\n platform: NodeJS.Platform = process.platform,\n): boolean {\n return comparable(a, platform) === comparable(b, platform);\n}\n\n/** Is `child` at or below `parent` on `platform`? No filesystem access. */\nexport function isPathInside(\n child: string,\n parent: string,\n platform: NodeJS.Platform = process.platform,\n): boolean {\n const p = pathFor(platform);\n const rel = p.relative(\n comparable(parent, platform),\n comparable(child, platform),\n );\n // `..foo` is a child named `..foo`; only `..` itself or a `../` prefix leaves `parent`.\n return (\n rel === '' ||\n (rel !== '..' && !rel.startsWith('..' + p.sep) && !p.isAbsolute(rel))\n );\n}\n\n/**\n * Link `linkPath` to the directory `target`. On Windows a junction, with an\n * absolute target (a junction cannot be relative); elsewhere a relative\n * symlink, so moving the app keeps it working.\n */\nexport function linkDirectory(\n target: string,\n linkPath: string,\n platform: NodeJS.Platform = process.platform,\n symlink: (\n target: string,\n linkPath: string,\n type: 'dir' | 'junction',\n ) => void = fs.symlinkSync,\n): void {\n if (platform === 'win32') {\n symlink(path.win32.resolve(target), linkPath, 'junction');\n return;\n }\n symlink(path.relative(path.dirname(linkPath), target), linkPath, 'dir');\n}\n\n/**\n * What to pass to `import()` for the absolute path `file`: on Windows its\n * `file:` URL (`import('C:\\\\x.js')` fails: `c:` reads as a URL scheme);\n * elsewhere the path itself, which Node takes as it is.\n */\nexport function importSpecifier(\n file: string,\n platform: NodeJS.Platform = process.platform,\n): string {\n if (platform !== 'win32') return file;\n return pathToFileURL(path.win32.resolve(file), {windows: true}).href;\n}\n\n/** `import()` of a file by its absolute path. */\nexport function importFile<T = any>(file: string): Promise<T> {\n return import(/* @vite-ignore */ importSpecifier(file));\n}\n\n/**\n * `text` with the line endings of `original`: CRLF throughout when `original`\n * uses CRLF (a checkout with `core.autocrlf`), else `text` unchanged.\n */\nexport function withEolOf(text: string, original: string): string {\n return original.includes('\\r\\n') ? text.replace(/\\r?\\n/g, '\\r\\n') : text;\n}\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"shapeReferences.d.ts","sourceRoot":"","sources":["../../../src/utils/shapeReferences.ts"],"names":[],"mappings":"AAMA;;;;;;;;;;;;;;;;;;;GAmBG;AAEH,8CAA8C;AAC9C,MAAM,WAAW,oBAAoB;IACnC,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,EAAE,MAAM,CAAC;CACf;AAED;;;;GAIG;AACH,MAAM,WAAW,wBAAwB;IACvC,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,MAAM,CAAC;IACjB,UAAU,EAAE,MAAM,CAAC;IACnB,OAAO,EAAE,MAAM,EAAE,CAAC;IAClB;;;;;;OAMG;IACH,MAAM,EAAE,YAAY,GAAG,SAAS,GAAG,kBAAkB,GAAG,SAAS,CAAC;IAClE,yDAAyD;IACzD,aAAa,CAAC,EAAE,MAAM,CAAC;CACxB;AAED,MAAM,WAAW,oBAAoB;IACnC,OAAO,EAAE,MAAM,EAAE,CAAC;IAClB,UAAU,EAAE,oBAAoB,EAAE,CAAC;IACnC,UAAU,EAAE,wBAAwB,EAAE,CAAC;IACvC,iEAAiE;IACjE,KAAK,EAAE,wBAAwB,EAAE,CAAC;IAClC;;;;;OAKG;IACH,UAAU,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,EAAE,CAAC,CAAC;IACrC,4EAA4E;IAC5E,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED;;;;;;;;;;GAUG;AACH,eAAO,MAAM,gBAAgB,EAAE;IAC7B,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,MAAM,CAAC;IACjB,UAAU,EAAE,MAAM,CAAC;CACpB,EAAO,CAAC;AAET,mGAAmG;AACnG,eAAO,MAAM,iBAAiB,GAAI,aAAa,MAAM,KAAG,MAKtC,CAAC;AA0InB,uGAAuG;AACvG,eAAO,MAAM,gBAAgB,GAAI,QAAQ,MAAM,KAAG,MAAM,EAuBvD,CAAC;AAoBF;;;GAGG;AACH,eAAO,MAAM,sBAAsB,GACjC,aAAa,MAAM,EACnB;;;CAGM,KACL,OAAO,CAAC,oBAAoB,CA6F9B,CAAC;AAsBF;;;;GAIG;AACH,eAAO,MAAM,oBAAoB,GAC/B,aAAa,MAAM,EACnB,UAAU,UAAU,CAAC,OAAO,sBAAsB,CAAC,CAAC,CAAC,CAAC,EACtD,aAAa,OAAO,CAAC,oBAAoB,CAAC,KACzC,OAAO,CAAC,IAAI,GAAG,MAAM,GAAG;IAAC,KAAK,EAAE,MAAM,CAAA;CAAC,CA4BzC,CAAC"}
1
+ {"version":3,"file":"shapeReferences.d.ts","sourceRoot":"","sources":["../../../src/utils/shapeReferences.ts"],"names":[],"mappings":"AAOA;;;;;;;;;;;;;;;;;;;GAmBG;AAEH,8CAA8C;AAC9C,MAAM,WAAW,oBAAoB;IACnC,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,EAAE,MAAM,CAAC;CACf;AAED;;;;GAIG;AACH,MAAM,WAAW,wBAAwB;IACvC,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,MAAM,CAAC;IACjB,UAAU,EAAE,MAAM,CAAC;IACnB,OAAO,EAAE,MAAM,EAAE,CAAC;IAClB;;;;;;OAMG;IACH,MAAM,EAAE,YAAY,GAAG,SAAS,GAAG,kBAAkB,GAAG,SAAS,CAAC;IAClE,yDAAyD;IACzD,aAAa,CAAC,EAAE,MAAM,CAAC;CACxB;AAED,MAAM,WAAW,oBAAoB;IACnC,OAAO,EAAE,MAAM,EAAE,CAAC;IAClB,UAAU,EAAE,oBAAoB,EAAE,CAAC;IACnC,UAAU,EAAE,wBAAwB,EAAE,CAAC;IACvC,iEAAiE;IACjE,KAAK,EAAE,wBAAwB,EAAE,CAAC;IAClC;;;;;OAKG;IACH,UAAU,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,EAAE,CAAC,CAAC;IACrC,4EAA4E;IAC5E,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED;;;;;;;;;;GAUG;AACH,eAAO,MAAM,gBAAgB,EAAE;IAC7B,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,MAAM,CAAC;IACjB,UAAU,EAAE,MAAM,CAAC;CACpB,EAAO,CAAC;AAET,mGAAmG;AACnG,eAAO,MAAM,iBAAiB,GAAI,aAAa,MAAM,KAAG,MAKtC,CAAC;AA0InB,uGAAuG;AACvG,eAAO,MAAM,gBAAgB,GAAI,QAAQ,MAAM,KAAG,MAAM,EAuBvD,CAAC;AAoBF;;;GAGG;AACH,eAAO,MAAM,sBAAsB,GACjC,aAAa,MAAM,EACnB;;;CAGM,KACL,OAAO,CAAC,oBAAoB,CA6F9B,CAAC;AAsBF;;;;GAIG;AACH,eAAO,MAAM,oBAAoB,GAC/B,aAAa,MAAM,EACnB,UAAU,UAAU,CAAC,OAAO,sBAAsB,CAAC,CAAC,CAAC,CAAC,EACtD,aAAa,OAAO,CAAC,oBAAoB,CAAC,KACzC,OAAO,CAAC,IAAI,GAAG,MAAM,GAAG;IAAC,KAAK,EAAE,MAAM,CAAA;CAAC,CA4BzC,CAAC"}
@@ -11,6 +11,7 @@ import { execFile } from 'child_process';
11
11
  import fs from 'fs';
12
12
  import os from 'os';
13
13
  import path from 'path';
14
+ import { pathToFileURL } from 'url';
14
15
  import { declaresShape } from './shapeNames.js';
15
16
  /**
16
17
  * References known to be unresolved, reported as warnings rather than failures.
@@ -112,7 +113,7 @@ const MARK = '__LINKED_SHAPE_REFERENCES__';
112
113
  const runProbe = (modulePath, packagePath, env, timeoutMs) => new Promise((resolve) => {
113
114
  execFile(process.execPath, ['--input-type=module', '-e', PROBE], {
114
115
  cwd: packagePath,
115
- env: Object.assign(Object.assign(Object.assign({}, process.env), env), { LINKED_PROBE_MODULE: 'file://' + modulePath }),
116
+ env: Object.assign(Object.assign(Object.assign({}, process.env), env), { LINKED_PROBE_MODULE: pathToFileURL(modulePath).href }),
116
117
  timeout: timeoutMs,
117
118
  maxBuffer: 64 * 1024 * 1024,
118
119
  }, (err, stdout, stderr) => {
@@ -202,7 +203,7 @@ export const inspectShapeReferences = (packagePath_1, ...args_1) => __awaiter(vo
202
203
  for (const name of new Set([ownName, pkgJson.name])) {
203
204
  entries[packageNameToSlug(name)] = {
204
205
  name,
205
- specifier: fs.existsSync(ownEntry) ? 'file://' + ownEntry : name,
206
+ specifier: fs.existsSync(ownEntry) ? pathToFileURL(ownEntry).href : name,
206
207
  };
207
208
  }
208
209
  const env = {
@@ -1 +1 @@
1
- {"version":3,"file":"shapeReferences.js","sourceRoot":"","sources":["../../../src/utils/shapeReferences.ts"],"names":[],"mappings":"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","sourcesContent":["import {execFile} from 'child_process';\nimport fs from 'fs';\nimport os from 'os';\nimport path from 'path';\nimport {declaresShape} from './shapeNames.js';\n\n/**\n * Checking shape references: does loading a compiled shape module, on its own,\n * register every shape its properties point at?\n *\n * A property can name its value shape by `[package, name]` instead of by class\n * (`shape: ['@_linked/schema', 'ImageObject']`), usually because importing the\n * class would close an import cycle. That names the shape without loading it.\n * A shape registers only when its module is evaluated, and consumers deep-import\n * single shape modules (`@_linked/schema/shapes/Thing`), so nothing guarantees\n * the named shape is registered when a query traverses the property. The query\n * then throws `Shape class not found for …/ImageObject` — in a production bundle,\n * far from the cause. A reference to a package under an old name\n * (`['lincd-sioc', …]`) can never resolve at all.\n *\n * So each module is loaded the way a consumer's fresh process would load it: in\n * a child `node` of its own, with nothing else imported first. Separate processes\n * rather than one process re-importing: ESM has no module-cache eviction, and the\n * shape registry lives on `globalThis`, so a second module in the same process\n * would see every shape the first one registered.\n */\n\n/** One module that could not be evaluated. */\nexport interface ShapeModuleLoadError {\n module: string;\n error: string;\n}\n\n/**\n * A property whose value shape was not registered after loading `modules`\n * (each on its own). One entry per distinct reference, however many modules\n * showed it.\n */\nexport interface UnresolvedShapeReference {\n shape: string;\n property: string;\n valueShape: string;\n modules: string[];\n /**\n * What the target package's entry does for it: `registered` — loading the\n * entry registers it, so the referencing module just does not import it;\n * `missing` — not even the entry registers it, so the name or package is\n * wrong; `not-a-dependency` — the IRI's package is neither this package nor\n * one of its dependencies; `unknown` — the entry could not be loaded.\n */\n target: 'registered' | 'missing' | 'not-a-dependency' | 'unknown';\n /** The package the IRI's slug maps to, when one does. */\n targetPackage?: string;\n}\n\nexport interface ShapeReferenceReport {\n modules: string[];\n loadErrors: ShapeModuleLoadError[];\n unresolved: UnresolvedShapeReference[];\n /** Unresolved references that match {@link KNOWN_UNRESOLVED}. */\n known: UnresolvedShapeReference[];\n /**\n * The package's own shapes (by IRI) registered after loading each module on\n * its own, keyed like {@link modules}. Read before the probe loads any entry\n * for its second look, so it is exactly what that one module registers.\n * Modules that threw are absent.\n */\n registered: Record<string, string[]>;\n /** Set when the registry could not be inspected, so nothing was checked. */\n skipped?: string;\n}\n\n/**\n * References known to be unresolved, reported as warnings rather than failures.\n *\n * This is deliberately a list in the CLI rather than an opt-out a package can\n * write for itself: every entry is a shipped bug with a tracked fix, not an\n * accepted design. No package was found with a legitimate reason to leave a\n * reference unresolved; add an opt-out mechanism when one turns up.\n *\n * Empty: `@_linked/core`'s `PropertyShape.in -> List`, the one entry this held,\n * is fixed in core (List is registered wherever PropertyShape is).\n */\nexport const KNOWN_UNRESOLVED: {\n package: string;\n shape: string;\n property: string;\n valueShape: string;\n}[] = [];\n\n/** arch-02: the `{slug}` in `{baseUri}shape/{slug}/{Name}`. Mirrors core's `packageNameToSlug`. */\nexport const packageNameToSlug = (packageName: string): string =>\n packageName\n .replace(/^@[^/]+\\//, '')\n .replace(/[^a-zA-Z0-9]+/g, '-')\n .replace(/^-+|-+$/g, '')\n .toLowerCase();\n\n/** The slug in a node-shape IRI, or undefined when it is not shaped like one. */\nconst slugOf = (iri: string): string | undefined =>\n iri.match(/\\/shape\\/([^/]+)\\/[^/]+$/)?.[1];\n\n/**\n * A loader hook for the child: asset imports (`import styles from\n * './X.module.css'`) evaluate to a stub. Node cannot load them and a consumer's\n * bundler always can, so without this a shape module whose file also holds a\n * component would look broken when it is not. A CSS-module stub maps every\n * class name to itself.\n */\nconst ASSET_HOOK = `\nconst ASSET = /\\\\.(css|scss|sass|less|styl|svg|png|jpe?g|gif|webp|avif|ico|woff2?|ttf|otf|eot)$/i;\nexport async function load(url, context, next) {\n if (url.startsWith('file:') && ASSET.test(new URL(url).pathname)) {\n return {format: 'module', shortCircuit: true,\n source: 'export default new Proxy({}, {get: (_, k) => typeof k === \"string\" ? k : undefined});'};\n }\n return next(url, context);\n}\n`;\n\n/**\n * The script each child runs. Plain JS, passed with `-e`, so it runs the same\n * from `src` under a test runner as from the published `lib`.\n *\n * It reads the registry from `globalThis.__linkedShapeRegistry` rather than\n * importing `@_linked/core`: the module under test decides which copy of core\n * it loads, and the registry is shared by every copy.\n */\nconst PROBE = `\nimport {register} from 'node:module';\nregister('data:text/javascript,' + encodeURIComponent(${JSON.stringify(ASSET_HOOK)}));\nconst MARK = '__LINKED_SHAPE_REFERENCES__';\nconst out = {error: null, unresolved: [], registry: true, registered: []};\nconst reg = () => globalThis.__linkedShapeRegistry;\nconst ownSlug = process.env.LINKED_PROBE_SLUG;\nconst report = () => {\n process.stdout.write('\\\\n' + MARK + JSON.stringify(out) + '\\\\n', () => process.exit(0));\n};\ntry {\n await import(process.env.LINKED_PROBE_MODULE);\n const r = reg();\n if (!r || !r.nodeShapeRegistry) {\n out.registry = false;\n } else {\n // Before the second look below: that loads whole entries and would add theirs.\n for (const id of r.nodeShapeRegistry.keys()) {\n if (id.includes('/shape/' + ownSlug + '/')) out.registered.push(id);\n }\n for (const [id, ns] of r.nodeShapeRegistry) {\n if (!id.includes('/shape/' + ownSlug + '/')) continue;\n for (const ps of ns.propertyShapes || []) {\n const v = ps.valueShape && ps.valueShape.id;\n if (v && !r.nodeShapeRegistry.has(v)) {\n out.unresolved.push({shape: id, property: ps.label, valueShape: v});\n }\n }\n }\n // For each unresolved target, load its package's entry and look again: that\n // tells a missing import apart from a name that can never resolve.\n const entries = JSON.parse(process.env.LINKED_PROBE_ENTRIES || '{}');\n const tried = {};\n for (const u of out.unresolved) {\n const slug = (u.valueShape.match(/\\\\/shape\\\\/([^/]+)\\\\/[^/]+$/) || [])[1];\n const entry = entries[slug];\n if (!entry) { u.target = 'not-a-dependency'; continue; }\n u.targetPackage = entry.name;\n if (!(slug in tried)) {\n try { await import(entry.specifier); tried[slug] = true; }\n catch (e) { tried[slug] = false; }\n }\n u.target = !tried[slug] ? 'unknown'\n : reg().nodeShapeRegistry.has(u.valueShape) ? 'registered' : 'missing';\n }\n }\n} catch (e) {\n out.error = e && e.stack ? e.stack.split('\\\\n').slice(0, 4).join('\\\\n') : String(e);\n}\nreport();\n`;\n\ninterface ProbeResult {\n error: string | null;\n registry: boolean;\n registered: string[];\n unresolved: {\n shape: string;\n property: string;\n valueShape: string;\n target: UnresolvedShapeReference['target'];\n targetPackage?: string;\n }[];\n}\n\nconst MARK = '__LINKED_SHAPE_REFERENCES__';\n\nconst runProbe = (\n modulePath: string,\n packagePath: string,\n env: Record<string, string>,\n timeoutMs: number,\n): Promise<ProbeResult> =>\n new Promise((resolve) => {\n execFile(\n process.execPath,\n ['--input-type=module', '-e', PROBE],\n {\n cwd: packagePath,\n env: {\n ...process.env,\n ...env,\n LINKED_PROBE_MODULE: 'file://' + modulePath,\n },\n timeout: timeoutMs,\n maxBuffer: 64 * 1024 * 1024,\n },\n (err, stdout, stderr) => {\n const line = String(stdout)\n .split('\\n')\n .reverse()\n .find((l) => l.startsWith(MARK));\n if (line) {\n resolve(JSON.parse(line.slice(MARK.length)));\n return;\n }\n const why =\n err && (err as any).killed\n ? `did not finish loading within ${timeoutMs}ms`\n : String(stderr).trim().split('\\n').slice(-4).join('\\n') ||\n String(err || 'exited without reporting');\n resolve({error: why, registry: true, registered: [], unresolved: []});\n },\n );\n });\n\n/** Every compiled module that declares a shape: all of `shapes/`, plus decorated classes elsewhere. */\nexport const findShapeModules = (libEsm: string): string[] => {\n const found: string[] = [];\n const walk = (dir: string) => {\n for (const entry of fs.readdirSync(dir, {withFileTypes: true})) {\n const full = path.join(dir, entry.name);\n if (entry.isDirectory()) {\n walk(full);\n } else if (\n entry.name.endsWith('.js') &&\n !/\\.(test|spec|class)\\.js$/.test(entry.name)\n ) {\n const rel = path.relative(libEsm, full);\n if (\n rel.split(path.sep)[0] === 'shapes' ||\n declaresShape(fs.readFileSync(full, 'utf8'))\n ) {\n found.push(full);\n }\n }\n }\n };\n if (fs.existsSync(libEsm)) walk(libEsm);\n return found.sort();\n};\n\n/** The name the package registers its shapes under: `linkedPackage('<name>')` in `package.js`. */\nconst runtimePackageName = (libEsm: string, pkgJson: any): string => {\n const pkgModule = path.join(libEsm, 'package.js');\n if (fs.existsSync(pkgModule)) {\n const m = fs\n .readFileSync(pkgModule, 'utf8')\n .match(/linkedPackage\\(\\s*['\"]([^'\"]+)['\"]/);\n if (m) return m[1];\n }\n return pkgJson.name;\n};\n\nconst DEPENDENCY_FIELDS = [\n 'dependencies',\n 'peerDependencies',\n 'optionalDependencies',\n];\n\n/**\n * Load each shape module of the package at `packagePath` in isolation and\n * collect load errors and unresolved property value shapes.\n */\nexport const inspectShapeReferences = async (\n packagePath: string,\n {\n concurrency = Math.min(8, Math.max(1, os.cpus().length - 1)),\n timeoutMs = 60000,\n } = {},\n): Promise<ShapeReferenceReport> => {\n const libEsm = path.join(packagePath, 'lib', 'esm');\n const pkgJson = JSON.parse(\n fs.readFileSync(path.join(packagePath, 'package.json'), 'utf8'),\n );\n const modules = findShapeModules(libEsm);\n const report: ShapeReferenceReport = {\n modules: modules.map((m) => path.relative(libEsm, m)),\n loadErrors: [],\n unresolved: [],\n known: [],\n registered: {},\n };\n if (modules.length === 0) return report;\n\n const ownName = runtimePackageName(libEsm, pkgJson);\n // The entry each slug's package is loaded through for the second look. This\n // package's own entry is loaded by path: a package cannot always import\n // itself by name.\n const entries: Record<string, {name: string; specifier: string}> = {};\n for (const field of DEPENDENCY_FIELDS) {\n for (const dep of Object.keys(pkgJson[field] || {})) {\n entries[packageNameToSlug(dep)] = {name: dep, specifier: dep};\n }\n }\n const ownEntry = path.join(\n packagePath,\n pkgJson.module || pkgJson.main || 'lib/esm/index.js',\n );\n for (const name of new Set([ownName, pkgJson.name])) {\n entries[packageNameToSlug(name)] = {\n name,\n specifier: fs.existsSync(ownEntry) ? 'file://' + ownEntry : name,\n };\n }\n const env = {\n LINKED_PROBE_SLUG: packageNameToSlug(ownName),\n LINKED_PROBE_ENTRIES: JSON.stringify(entries),\n };\n\n const results: ProbeResult[] = new Array(modules.length);\n let next = 0;\n await Promise.all(\n Array.from({length: Math.min(concurrency, modules.length)}, async () => {\n while (next < modules.length) {\n const i = next++;\n results[i] = await runProbe(modules[i], packagePath, env, timeoutMs);\n }\n }),\n );\n\n // No registry on `globalThis` after loading a module that declares a shape\n // means a core older than 2.22.3, whose registry is module-scoped. A module\n // under `shapes/` that declares none (a store, a helper) registers nothing.\n const stale = results.findIndex(\n (r, i) =>\n !r.error &&\n !r.registry &&\n declaresShape(fs.readFileSync(modules[i], 'utf8')),\n );\n if (stale !== -1) {\n report.skipped =\n `no shape registry on globalThis after loading ${report.modules[stale]}: the ` +\n '@_linked/core it loads is older than 2.22.3, whose registry cannot be inspected from outside';\n return report;\n }\n\n const byReference = new Map<string, UnresolvedShapeReference>();\n results.forEach((r, i) => {\n const module = report.modules[i];\n if (r.error) {\n report.loadErrors.push({module, error: r.error});\n return;\n }\n report.registered[module] = r.registered;\n for (const u of r.unresolved) {\n const key = `${u.shape}\\u0000${u.property}\\u0000${u.valueShape}`;\n const existing = byReference.get(key);\n if (existing) existing.modules.push(module);\n else byReference.set(key, {...u, modules: [module]});\n }\n });\n for (const ref of byReference.values()) {\n const isKnown = KNOWN_UNRESOLVED.some(\n (k) =>\n k.package === ownName &&\n ref.shape.endsWith(k.shape) &&\n ref.property === k.property &&\n ref.valueShape.endsWith(k.valueShape),\n );\n (isKnown ? report.known : report.unresolved).push(ref);\n }\n return report;\n};\n\nconst shortIri = (iri: string) => iri.replace(/^.*\\/shape\\//, '');\n\nconst modulesList = (modules: string[]) =>\n modules.length <= 3\n ? modules.join(', ')\n : `${modules.slice(0, 3).join(', ')} and ${modules.length - 3} more`;\n\nconst describeReference = (ref: UnresolvedShapeReference): string => {\n const label = `${shortIri(ref.shape)}.${ref.property} -> ${ref.valueShape}`;\n const fix =\n ref.target === 'registered'\n ? `${ref.targetPackage}'s entry registers it, so the module that declares the property must import the module that declares ${shortIri(ref.valueShape)}`\n : ref.target === 'missing'\n ? `not registered even by ${ref.targetPackage}'s entry: the shape name is wrong or ${ref.targetPackage} does not define it`\n : ref.target === 'not-a-dependency'\n ? `'${slugOf(ref.valueShape)}' is neither this package nor one of its dependencies (an old package name?)`\n : `${ref.targetPackage}'s entry could not be loaded to tell why`;\n return ` ${label}\\n unresolved after loading ${modulesList(ref.modules)}\\n ${fix}`;\n};\n\n/**\n * Build step. Load errors and unresolved references fail the build: each is a\n * bug the package would ship, and it only surfaces in a consumer's bundle. The\n * references in {@link KNOWN_UNRESOLVED} warn instead.\n */\nexport const checkShapeReferences = async (\n packagePath: string,\n options?: Parameters<typeof inspectShapeReferences>[1],\n inspection?: Promise<ShapeReferenceReport>,\n): Promise<true | string | {error: string}> => {\n const report = await (inspection ?? inspectShapeReferences(packagePath, options));\n if (report.skipped) return `skipped: ${report.skipped}`;\n const problems: string[] = [];\n if (report.loadErrors.length > 0) {\n problems.push(\n `${report.loadErrors.length} shape module(s) throw when loaded on their own:\\n` +\n report.loadErrors\n .map((e) => ` ${e.module}: ${e.error.split('\\n').join('\\n ')}`)\n .join('\\n'),\n );\n }\n if (report.unresolved.length > 0) {\n problems.push(\n `${report.unresolved.length} property value shape(s) are not registered when the module that ` +\n `declares the property is loaded on its own, so a query traversing them throws ` +\n `\"Shape class not found\":\\n` +\n report.unresolved.map(describeReference).join('\\n'),\n );\n }\n if (problems.length > 0) return {error: problems.join('\\n')};\n if (report.known.length > 0) {\n return (\n `${report.known.length} known unresolved reference(s), tracked for a fix:\\n` +\n report.known.map(describeReference).join('\\n')\n );\n }\n return true;\n};\n"]}
1
+ {"version":3,"file":"shapeReferences.js","sourceRoot":"","sources":["../../../src/utils/shapeReferences.ts"],"names":[],"mappings":"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","sourcesContent":["import {execFile} from 'child_process';\nimport fs from 'fs';\nimport os from 'os';\nimport path from 'path';\nimport {pathToFileURL} from 'url';\nimport {declaresShape} from './shapeNames.js';\n\n/**\n * Checking shape references: does loading a compiled shape module, on its own,\n * register every shape its properties point at?\n *\n * A property can name its value shape by `[package, name]` instead of by class\n * (`shape: ['@_linked/schema', 'ImageObject']`), usually because importing the\n * class would close an import cycle. That names the shape without loading it.\n * A shape registers only when its module is evaluated, and consumers deep-import\n * single shape modules (`@_linked/schema/shapes/Thing`), so nothing guarantees\n * the named shape is registered when a query traverses the property. The query\n * then throws `Shape class not found for …/ImageObject` — in a production bundle,\n * far from the cause. A reference to a package under an old name\n * (`['lincd-sioc', …]`) can never resolve at all.\n *\n * So each module is loaded the way a consumer's fresh process would load it: in\n * a child `node` of its own, with nothing else imported first. Separate processes\n * rather than one process re-importing: ESM has no module-cache eviction, and the\n * shape registry lives on `globalThis`, so a second module in the same process\n * would see every shape the first one registered.\n */\n\n/** One module that could not be evaluated. */\nexport interface ShapeModuleLoadError {\n module: string;\n error: string;\n}\n\n/**\n * A property whose value shape was not registered after loading `modules`\n * (each on its own). One entry per distinct reference, however many modules\n * showed it.\n */\nexport interface UnresolvedShapeReference {\n shape: string;\n property: string;\n valueShape: string;\n modules: string[];\n /**\n * What the target package's entry does for it: `registered` — loading the\n * entry registers it, so the referencing module just does not import it;\n * `missing` — not even the entry registers it, so the name or package is\n * wrong; `not-a-dependency` — the IRI's package is neither this package nor\n * one of its dependencies; `unknown` — the entry could not be loaded.\n */\n target: 'registered' | 'missing' | 'not-a-dependency' | 'unknown';\n /** The package the IRI's slug maps to, when one does. */\n targetPackage?: string;\n}\n\nexport interface ShapeReferenceReport {\n modules: string[];\n loadErrors: ShapeModuleLoadError[];\n unresolved: UnresolvedShapeReference[];\n /** Unresolved references that match {@link KNOWN_UNRESOLVED}. */\n known: UnresolvedShapeReference[];\n /**\n * The package's own shapes (by IRI) registered after loading each module on\n * its own, keyed like {@link modules}. Read before the probe loads any entry\n * for its second look, so it is exactly what that one module registers.\n * Modules that threw are absent.\n */\n registered: Record<string, string[]>;\n /** Set when the registry could not be inspected, so nothing was checked. */\n skipped?: string;\n}\n\n/**\n * References known to be unresolved, reported as warnings rather than failures.\n *\n * This is deliberately a list in the CLI rather than an opt-out a package can\n * write for itself: every entry is a shipped bug with a tracked fix, not an\n * accepted design. No package was found with a legitimate reason to leave a\n * reference unresolved; add an opt-out mechanism when one turns up.\n *\n * Empty: `@_linked/core`'s `PropertyShape.in -> List`, the one entry this held,\n * is fixed in core (List is registered wherever PropertyShape is).\n */\nexport const KNOWN_UNRESOLVED: {\n package: string;\n shape: string;\n property: string;\n valueShape: string;\n}[] = [];\n\n/** arch-02: the `{slug}` in `{baseUri}shape/{slug}/{Name}`. Mirrors core's `packageNameToSlug`. */\nexport const packageNameToSlug = (packageName: string): string =>\n packageName\n .replace(/^@[^/]+\\//, '')\n .replace(/[^a-zA-Z0-9]+/g, '-')\n .replace(/^-+|-+$/g, '')\n .toLowerCase();\n\n/** The slug in a node-shape IRI, or undefined when it is not shaped like one. */\nconst slugOf = (iri: string): string | undefined =>\n iri.match(/\\/shape\\/([^/]+)\\/[^/]+$/)?.[1];\n\n/**\n * A loader hook for the child: asset imports (`import styles from\n * './X.module.css'`) evaluate to a stub. Node cannot load them and a consumer's\n * bundler always can, so without this a shape module whose file also holds a\n * component would look broken when it is not. A CSS-module stub maps every\n * class name to itself.\n */\nconst ASSET_HOOK = `\nconst ASSET = /\\\\.(css|scss|sass|less|styl|svg|png|jpe?g|gif|webp|avif|ico|woff2?|ttf|otf|eot)$/i;\nexport async function load(url, context, next) {\n if (url.startsWith('file:') && ASSET.test(new URL(url).pathname)) {\n return {format: 'module', shortCircuit: true,\n source: 'export default new Proxy({}, {get: (_, k) => typeof k === \"string\" ? k : undefined});'};\n }\n return next(url, context);\n}\n`;\n\n/**\n * The script each child runs. Plain JS, passed with `-e`, so it runs the same\n * from `src` under a test runner as from the published `lib`.\n *\n * It reads the registry from `globalThis.__linkedShapeRegistry` rather than\n * importing `@_linked/core`: the module under test decides which copy of core\n * it loads, and the registry is shared by every copy.\n */\nconst PROBE = `\nimport {register} from 'node:module';\nregister('data:text/javascript,' + encodeURIComponent(${JSON.stringify(ASSET_HOOK)}));\nconst MARK = '__LINKED_SHAPE_REFERENCES__';\nconst out = {error: null, unresolved: [], registry: true, registered: []};\nconst reg = () => globalThis.__linkedShapeRegistry;\nconst ownSlug = process.env.LINKED_PROBE_SLUG;\nconst report = () => {\n process.stdout.write('\\\\n' + MARK + JSON.stringify(out) + '\\\\n', () => process.exit(0));\n};\ntry {\n await import(process.env.LINKED_PROBE_MODULE);\n const r = reg();\n if (!r || !r.nodeShapeRegistry) {\n out.registry = false;\n } else {\n // Before the second look below: that loads whole entries and would add theirs.\n for (const id of r.nodeShapeRegistry.keys()) {\n if (id.includes('/shape/' + ownSlug + '/')) out.registered.push(id);\n }\n for (const [id, ns] of r.nodeShapeRegistry) {\n if (!id.includes('/shape/' + ownSlug + '/')) continue;\n for (const ps of ns.propertyShapes || []) {\n const v = ps.valueShape && ps.valueShape.id;\n if (v && !r.nodeShapeRegistry.has(v)) {\n out.unresolved.push({shape: id, property: ps.label, valueShape: v});\n }\n }\n }\n // For each unresolved target, load its package's entry and look again: that\n // tells a missing import apart from a name that can never resolve.\n const entries = JSON.parse(process.env.LINKED_PROBE_ENTRIES || '{}');\n const tried = {};\n for (const u of out.unresolved) {\n const slug = (u.valueShape.match(/\\\\/shape\\\\/([^/]+)\\\\/[^/]+$/) || [])[1];\n const entry = entries[slug];\n if (!entry) { u.target = 'not-a-dependency'; continue; }\n u.targetPackage = entry.name;\n if (!(slug in tried)) {\n try { await import(entry.specifier); tried[slug] = true; }\n catch (e) { tried[slug] = false; }\n }\n u.target = !tried[slug] ? 'unknown'\n : reg().nodeShapeRegistry.has(u.valueShape) ? 'registered' : 'missing';\n }\n }\n} catch (e) {\n out.error = e && e.stack ? e.stack.split('\\\\n').slice(0, 4).join('\\\\n') : String(e);\n}\nreport();\n`;\n\ninterface ProbeResult {\n error: string | null;\n registry: boolean;\n registered: string[];\n unresolved: {\n shape: string;\n property: string;\n valueShape: string;\n target: UnresolvedShapeReference['target'];\n targetPackage?: string;\n }[];\n}\n\nconst MARK = '__LINKED_SHAPE_REFERENCES__';\n\nconst runProbe = (\n modulePath: string,\n packagePath: string,\n env: Record<string, string>,\n timeoutMs: number,\n): Promise<ProbeResult> =>\n new Promise((resolve) => {\n execFile(\n process.execPath,\n ['--input-type=module', '-e', PROBE],\n {\n cwd: packagePath,\n env: {\n ...process.env,\n ...env,\n LINKED_PROBE_MODULE: pathToFileURL(modulePath).href,\n },\n timeout: timeoutMs,\n maxBuffer: 64 * 1024 * 1024,\n },\n (err, stdout, stderr) => {\n const line = String(stdout)\n .split('\\n')\n .reverse()\n .find((l) => l.startsWith(MARK));\n if (line) {\n resolve(JSON.parse(line.slice(MARK.length)));\n return;\n }\n const why =\n err && (err as any).killed\n ? `did not finish loading within ${timeoutMs}ms`\n : String(stderr).trim().split('\\n').slice(-4).join('\\n') ||\n String(err || 'exited without reporting');\n resolve({error: why, registry: true, registered: [], unresolved: []});\n },\n );\n });\n\n/** Every compiled module that declares a shape: all of `shapes/`, plus decorated classes elsewhere. */\nexport const findShapeModules = (libEsm: string): string[] => {\n const found: string[] = [];\n const walk = (dir: string) => {\n for (const entry of fs.readdirSync(dir, {withFileTypes: true})) {\n const full = path.join(dir, entry.name);\n if (entry.isDirectory()) {\n walk(full);\n } else if (\n entry.name.endsWith('.js') &&\n !/\\.(test|spec|class)\\.js$/.test(entry.name)\n ) {\n const rel = path.relative(libEsm, full);\n if (\n rel.split(path.sep)[0] === 'shapes' ||\n declaresShape(fs.readFileSync(full, 'utf8'))\n ) {\n found.push(full);\n }\n }\n }\n };\n if (fs.existsSync(libEsm)) walk(libEsm);\n return found.sort();\n};\n\n/** The name the package registers its shapes under: `linkedPackage('<name>')` in `package.js`. */\nconst runtimePackageName = (libEsm: string, pkgJson: any): string => {\n const pkgModule = path.join(libEsm, 'package.js');\n if (fs.existsSync(pkgModule)) {\n const m = fs\n .readFileSync(pkgModule, 'utf8')\n .match(/linkedPackage\\(\\s*['\"]([^'\"]+)['\"]/);\n if (m) return m[1];\n }\n return pkgJson.name;\n};\n\nconst DEPENDENCY_FIELDS = [\n 'dependencies',\n 'peerDependencies',\n 'optionalDependencies',\n];\n\n/**\n * Load each shape module of the package at `packagePath` in isolation and\n * collect load errors and unresolved property value shapes.\n */\nexport const inspectShapeReferences = async (\n packagePath: string,\n {\n concurrency = Math.min(8, Math.max(1, os.cpus().length - 1)),\n timeoutMs = 60000,\n } = {},\n): Promise<ShapeReferenceReport> => {\n const libEsm = path.join(packagePath, 'lib', 'esm');\n const pkgJson = JSON.parse(\n fs.readFileSync(path.join(packagePath, 'package.json'), 'utf8'),\n );\n const modules = findShapeModules(libEsm);\n const report: ShapeReferenceReport = {\n modules: modules.map((m) => path.relative(libEsm, m)),\n loadErrors: [],\n unresolved: [],\n known: [],\n registered: {},\n };\n if (modules.length === 0) return report;\n\n const ownName = runtimePackageName(libEsm, pkgJson);\n // The entry each slug's package is loaded through for the second look. This\n // package's own entry is loaded by path: a package cannot always import\n // itself by name.\n const entries: Record<string, {name: string; specifier: string}> = {};\n for (const field of DEPENDENCY_FIELDS) {\n for (const dep of Object.keys(pkgJson[field] || {})) {\n entries[packageNameToSlug(dep)] = {name: dep, specifier: dep};\n }\n }\n const ownEntry = path.join(\n packagePath,\n pkgJson.module || pkgJson.main || 'lib/esm/index.js',\n );\n for (const name of new Set([ownName, pkgJson.name])) {\n entries[packageNameToSlug(name)] = {\n name,\n specifier: fs.existsSync(ownEntry) ? pathToFileURL(ownEntry).href : name,\n };\n }\n const env = {\n LINKED_PROBE_SLUG: packageNameToSlug(ownName),\n LINKED_PROBE_ENTRIES: JSON.stringify(entries),\n };\n\n const results: ProbeResult[] = new Array(modules.length);\n let next = 0;\n await Promise.all(\n Array.from({length: Math.min(concurrency, modules.length)}, async () => {\n while (next < modules.length) {\n const i = next++;\n results[i] = await runProbe(modules[i], packagePath, env, timeoutMs);\n }\n }),\n );\n\n // No registry on `globalThis` after loading a module that declares a shape\n // means a core older than 2.22.3, whose registry is module-scoped. A module\n // under `shapes/` that declares none (a store, a helper) registers nothing.\n const stale = results.findIndex(\n (r, i) =>\n !r.error &&\n !r.registry &&\n declaresShape(fs.readFileSync(modules[i], 'utf8')),\n );\n if (stale !== -1) {\n report.skipped =\n `no shape registry on globalThis after loading ${report.modules[stale]}: the ` +\n '@_linked/core it loads is older than 2.22.3, whose registry cannot be inspected from outside';\n return report;\n }\n\n const byReference = new Map<string, UnresolvedShapeReference>();\n results.forEach((r, i) => {\n const module = report.modules[i];\n if (r.error) {\n report.loadErrors.push({module, error: r.error});\n return;\n }\n report.registered[module] = r.registered;\n for (const u of r.unresolved) {\n const key = `${u.shape}\\u0000${u.property}\\u0000${u.valueShape}`;\n const existing = byReference.get(key);\n if (existing) existing.modules.push(module);\n else byReference.set(key, {...u, modules: [module]});\n }\n });\n for (const ref of byReference.values()) {\n const isKnown = KNOWN_UNRESOLVED.some(\n (k) =>\n k.package === ownName &&\n ref.shape.endsWith(k.shape) &&\n ref.property === k.property &&\n ref.valueShape.endsWith(k.valueShape),\n );\n (isKnown ? report.known : report.unresolved).push(ref);\n }\n return report;\n};\n\nconst shortIri = (iri: string) => iri.replace(/^.*\\/shape\\//, '');\n\nconst modulesList = (modules: string[]) =>\n modules.length <= 3\n ? modules.join(', ')\n : `${modules.slice(0, 3).join(', ')} and ${modules.length - 3} more`;\n\nconst describeReference = (ref: UnresolvedShapeReference): string => {\n const label = `${shortIri(ref.shape)}.${ref.property} -> ${ref.valueShape}`;\n const fix =\n ref.target === 'registered'\n ? `${ref.targetPackage}'s entry registers it, so the module that declares the property must import the module that declares ${shortIri(ref.valueShape)}`\n : ref.target === 'missing'\n ? `not registered even by ${ref.targetPackage}'s entry: the shape name is wrong or ${ref.targetPackage} does not define it`\n : ref.target === 'not-a-dependency'\n ? `'${slugOf(ref.valueShape)}' is neither this package nor one of its dependencies (an old package name?)`\n : `${ref.targetPackage}'s entry could not be loaded to tell why`;\n return ` ${label}\\n unresolved after loading ${modulesList(ref.modules)}\\n ${fix}`;\n};\n\n/**\n * Build step. Load errors and unresolved references fail the build: each is a\n * bug the package would ship, and it only surfaces in a consumer's bundle. The\n * references in {@link KNOWN_UNRESOLVED} warn instead.\n */\nexport const checkShapeReferences = async (\n packagePath: string,\n options?: Parameters<typeof inspectShapeReferences>[1],\n inspection?: Promise<ShapeReferenceReport>,\n): Promise<true | string | {error: string}> => {\n const report = await (inspection ?? inspectShapeReferences(packagePath, options));\n if (report.skipped) return `skipped: ${report.skipped}`;\n const problems: string[] = [];\n if (report.loadErrors.length > 0) {\n problems.push(\n `${report.loadErrors.length} shape module(s) throw when loaded on their own:\\n` +\n report.loadErrors\n .map((e) => ` ${e.module}: ${e.error.split('\\n').join('\\n ')}`)\n .join('\\n'),\n );\n }\n if (report.unresolved.length > 0) {\n problems.push(\n `${report.unresolved.length} property value shape(s) are not registered when the module that ` +\n `declares the property is loaded on its own, so a query traversing them throws ` +\n `\"Shape class not found\":\\n` +\n report.unresolved.map(describeReference).join('\\n'),\n );\n }\n if (problems.length > 0) return {error: problems.join('\\n')};\n if (report.known.length > 0) {\n return (\n `${report.known.length} known unresolved reference(s), tracked for a fix:\\n` +\n report.known.map(describeReference).join('\\n')\n );\n }\n return true;\n};\n"]}
@@ -0,0 +1,65 @@
1
+ /**
2
+ * The one way the cli starts `npm`, `npx` and other command shims with an
3
+ * argument list.
4
+ *
5
+ * On macOS and Linux a command runs as it is named, without a shell. On
6
+ * Windows `npm`, `npx`, `yarn` and every `node_modules/.bin` entry are `.cmd`
7
+ * batch files, which Node refuses to spawn without a shell (EINVAL since
8
+ * Node 18.20.2 / 20.12.2, CVE-2024-27980). There:
9
+ *
10
+ * - `npm` and `npx` run as `node <npm-cli.js|npx-cli.js>` when the npm that
11
+ * started this process says where it lives (`npm_execpath`): no shell, no
12
+ * quoting;
13
+ * - any other shim runs through `cmd.exe` as one command line, each argument
14
+ * quoted for it;
15
+ * - everything else (`git`, `gh`, `node`) is an `.exe` and runs as it is.
16
+ *
17
+ * Commands given as one shell string (`exec`, a configured build command) go
18
+ * to the platform's shell as they are; they must not use POSIX-only syntax.
19
+ */
20
+ import { type ChildProcess, type SpawnOptions, type SpawnSyncOptions, type SpawnSyncReturns } from 'node:child_process';
21
+ export interface CommandPlan {
22
+ command: string;
23
+ args: string[];
24
+ shell: boolean;
25
+ }
26
+ export interface PlanOptions {
27
+ platform?: NodeJS.Platform;
28
+ env?: NodeJS.ProcessEnv;
29
+ /** The node binary that runs npm's own scripts; `process.execPath` by default. */
30
+ execPath?: string;
31
+ /** Injectable for tests; `fs.existsSync` by default. */
32
+ exists?: (p: string) => boolean;
33
+ }
34
+ /**
35
+ * `arg` as one argument on a `cmd.exe` command line: quoted the way the C
36
+ * runtime splits arguments, then every `cmd.exe` metacharacter escaped with
37
+ * `^` -- twice for a `.cmd` shim whose `%*` is parsed again (`reparsesArgs`).
38
+ * The same scheme as cross-spawn.
39
+ */
40
+ export declare function quoteCmdArg(arg: string, doubleEscape?: boolean): string;
41
+ /** How to start `cmd` with `args` on `platform`; see the module comment. */
42
+ export declare function planCommand(cmd: string, args: readonly string[], opts?: PlanOptions): CommandPlan;
43
+ /**
44
+ * `spawnSync` for an argument list, planned by `planCommand`. A `shell` in
45
+ * `options` is ignored: whether a shell is needed is the plan's call.
46
+ */
47
+ export declare function spawnCommandSync(cmd: string, args: readonly string[], options: SpawnSyncOptions & {
48
+ encoding: BufferEncoding;
49
+ }): SpawnSyncReturns<string>;
50
+ /** `spawn` for an argument list, planned by `planCommand`. */
51
+ export declare function spawnCommand(cmd: string, args: readonly string[], options?: SpawnOptions): ChildProcess;
52
+ export interface CommandOutput {
53
+ status: number;
54
+ stdout: string;
55
+ stderr: string;
56
+ }
57
+ /**
58
+ * Run `cmd` with `args` and collect its output; resolves (never rejects) with
59
+ * the exit status, 1 when it could not start. `echo` also streams the output.
60
+ */
61
+ export declare function runCommand(cmd: string, args: readonly string[], options?: SpawnOptions & {
62
+ echo?: boolean;
63
+ input?: string;
64
+ }): Promise<CommandOutput>;
65
+ //# sourceMappingURL=spawn.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"spawn.d.ts","sourceRoot":"","sources":["../../../src/utils/spawn.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;GAkBG;AACH,OAAO,EAGL,KAAK,YAAY,EACjB,KAAK,YAAY,EACjB,KAAK,gBAAgB,EACrB,KAAK,gBAAgB,EACtB,MAAM,oBAAoB,CAAC;AAI5B,MAAM,WAAW,WAAW;IAC1B,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,EAAE,MAAM,EAAE,CAAC;IACf,KAAK,EAAE,OAAO,CAAC;CAChB;AAED,MAAM,WAAW,WAAW;IAC1B,QAAQ,CAAC,EAAE,MAAM,CAAC,QAAQ,CAAC;IAC3B,GAAG,CAAC,EAAE,MAAM,CAAC,UAAU,CAAC;IACxB,kFAAkF;IAClF,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,wDAAwD;IACxD,MAAM,CAAC,EAAE,CAAC,CAAC,EAAE,MAAM,KAAK,OAAO,CAAC;CACjC;AAiBD;;;;;GAKG;AACH,wBAAgB,WAAW,CAAC,GAAG,EAAE,MAAM,EAAE,YAAY,UAAQ,GAAG,MAAM,CAQrE;AAgDD,4EAA4E;AAC5E,wBAAgB,WAAW,CACzB,GAAG,EAAE,MAAM,EACX,IAAI,EAAE,SAAS,MAAM,EAAE,EACvB,IAAI,GAAE,WAAgB,GACrB,WAAW,CA+Bb;AAED;;;GAGG;AACH,wBAAgB,gBAAgB,CAC9B,GAAG,EAAE,MAAM,EACX,IAAI,EAAE,SAAS,MAAM,EAAE,EACvB,OAAO,EAAE,gBAAgB,GAAG;IAAC,QAAQ,EAAE,cAAc,CAAA;CAAC,GACrD,gBAAgB,CAAC,MAAM,CAAC,CAG1B;AAED,8DAA8D;AAC9D,wBAAgB,YAAY,CAC1B,GAAG,EAAE,MAAM,EACX,IAAI,EAAE,SAAS,MAAM,EAAE,EACvB,OAAO,GAAE,YAAiB,GACzB,YAAY,CAGd;AAED,MAAM,WAAW,aAAa;IAC5B,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;CAChB;AAED;;;GAGG;AACH,wBAAgB,UAAU,CACxB,GAAG,EAAE,MAAM,EACX,IAAI,EAAE,SAAS,MAAM,EAAE,EACvB,OAAO,GAAE,YAAY,GAAG;IAAC,IAAI,CAAC,EAAE,OAAO,CAAC;IAAC,KAAK,CAAC,EAAE,MAAM,CAAA;CAAM,GAC5D,OAAO,CAAC,aAAa,CAAC,CA2BxB"}