@essential-apps/shopify-test-runner 1.0.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 (265) hide show
  1. package/dist/contracts/normalize.d.ts +61 -0
  2. package/dist/contracts/normalize.d.ts.map +1 -0
  3. package/dist/contracts/normalize.js +99 -0
  4. package/dist/contracts/normalize.js.map +1 -0
  5. package/dist/contracts/normalizeHtml.d.ts +37 -0
  6. package/dist/contracts/normalizeHtml.d.ts.map +1 -0
  7. package/dist/contracts/normalizeHtml.js +89 -0
  8. package/dist/contracts/normalizeHtml.js.map +1 -0
  9. package/dist/edge/cert.d.ts +44 -0
  10. package/dist/edge/cert.d.ts.map +1 -0
  11. package/dist/edge/cert.js +117 -0
  12. package/dist/edge/cert.js.map +1 -0
  13. package/dist/edge/edgeProxy.d.ts +43 -0
  14. package/dist/edge/edgeProxy.d.ts.map +1 -0
  15. package/dist/edge/edgeProxy.js +297 -0
  16. package/dist/edge/edgeProxy.js.map +1 -0
  17. package/dist/edge/nodeShim.d.ts +2 -0
  18. package/dist/edge/nodeShim.d.ts.map +1 -0
  19. package/dist/edge/nodeShim.js +217 -0
  20. package/dist/edge/nodeShim.js.map +1 -0
  21. package/dist/index.d.ts +39 -0
  22. package/dist/index.d.ts.map +1 -0
  23. package/dist/index.js +36 -0
  24. package/dist/index.js.map +1 -0
  25. package/dist/lib/buildSourceBundle.d.ts +56 -0
  26. package/dist/lib/buildSourceBundle.d.ts.map +1 -0
  27. package/dist/lib/buildSourceBundle.js +153 -0
  28. package/dist/lib/buildSourceBundle.js.map +1 -0
  29. package/dist/lib/freePort.d.ts +5 -0
  30. package/dist/lib/freePort.d.ts.map +1 -0
  31. package/dist/lib/freePort.js +33 -0
  32. package/dist/lib/freePort.js.map +1 -0
  33. package/dist/lib/functionBuild.d.ts +99 -0
  34. package/dist/lib/functionBuild.d.ts.map +1 -0
  35. package/dist/lib/functionBuild.js +413 -0
  36. package/dist/lib/functionBuild.js.map +1 -0
  37. package/dist/lib/neonWsProxy.d.ts +41 -0
  38. package/dist/lib/neonWsProxy.d.ts.map +1 -0
  39. package/dist/lib/neonWsProxy.js +101 -0
  40. package/dist/lib/neonWsProxy.js.map +1 -0
  41. package/dist/lib/sourceZipUpload.d.ts +45 -0
  42. package/dist/lib/sourceZipUpload.d.ts.map +1 -0
  43. package/dist/lib/sourceZipUpload.js +129 -0
  44. package/dist/lib/sourceZipUpload.js.map +1 -0
  45. package/dist/lib/stealthLaunch.d.ts +35 -0
  46. package/dist/lib/stealthLaunch.d.ts.map +1 -0
  47. package/dist/lib/stealthLaunch.js +46 -0
  48. package/dist/lib/stealthLaunch.js.map +1 -0
  49. package/dist/lib/storeAutomation.d.ts +22 -0
  50. package/dist/lib/storeAutomation.d.ts.map +1 -0
  51. package/dist/lib/storeAutomation.js +85 -0
  52. package/dist/lib/storeAutomation.js.map +1 -0
  53. package/dist/playwright/baseConfig.d.ts +62 -0
  54. package/dist/playwright/baseConfig.d.ts.map +1 -0
  55. package/dist/playwright/baseConfig.js +68 -0
  56. package/dist/playwright/baseConfig.js.map +1 -0
  57. package/dist/playwright/globalSetup.d.ts +2 -0
  58. package/dist/playwright/globalSetup.d.ts.map +1 -0
  59. package/dist/playwright/globalSetup.js +139 -0
  60. package/dist/playwright/globalSetup.js.map +1 -0
  61. package/dist/playwright/index.d.ts +9 -0
  62. package/dist/playwright/index.d.ts.map +1 -0
  63. package/dist/playwright/index.js +9 -0
  64. package/dist/playwright/index.js.map +1 -0
  65. package/dist/probes/fonts.d.ts +4 -0
  66. package/dist/probes/fonts.d.ts.map +1 -0
  67. package/dist/probes/fonts.js +255 -0
  68. package/dist/probes/fonts.js.map +1 -0
  69. package/dist/probes/mirror.d.ts +4 -0
  70. package/dist/probes/mirror.d.ts.map +1 -0
  71. package/dist/probes/mirror.js +260 -0
  72. package/dist/probes/mirror.js.map +1 -0
  73. package/dist/probes/runProbe.d.ts +3 -0
  74. package/dist/probes/runProbe.d.ts.map +1 -0
  75. package/dist/probes/runProbe.js +219 -0
  76. package/dist/probes/runProbe.js.map +1 -0
  77. package/dist/probes/types.d.ts +72 -0
  78. package/dist/probes/types.d.ts.map +1 -0
  79. package/dist/probes/types.js +2 -0
  80. package/dist/probes/types.js.map +1 -0
  81. package/dist/scripts/_probeSourceUrl.d.ts +3 -0
  82. package/dist/scripts/_probeSourceUrl.d.ts.map +1 -0
  83. package/dist/scripts/_probeSourceUrl.js +119 -0
  84. package/dist/scripts/_probeSourceUrl.js.map +1 -0
  85. package/dist/scripts/addStore.d.ts +3 -0
  86. package/dist/scripts/addStore.d.ts.map +1 -0
  87. package/dist/scripts/addStore.js +46 -0
  88. package/dist/scripts/addStore.js.map +1 -0
  89. package/dist/scripts/buildDockerImage.d.ts +3 -0
  90. package/dist/scripts/buildDockerImage.d.ts.map +1 -0
  91. package/dist/scripts/buildDockerImage.js +60 -0
  92. package/dist/scripts/buildDockerImage.js.map +1 -0
  93. package/dist/scripts/captureAuth.d.ts +3 -0
  94. package/dist/scripts/captureAuth.d.ts.map +1 -0
  95. package/dist/scripts/captureAuth.js +124 -0
  96. package/dist/scripts/captureAuth.js.map +1 -0
  97. package/dist/scripts/captureContracts.d.ts +3 -0
  98. package/dist/scripts/captureContracts.d.ts.map +1 -0
  99. package/dist/scripts/captureContracts.js +517 -0
  100. package/dist/scripts/captureContracts.js.map +1 -0
  101. package/dist/scripts/captureRestContracts.d.ts +3 -0
  102. package/dist/scripts/captureRestContracts.d.ts.map +1 -0
  103. package/dist/scripts/captureRestContracts.js +245 -0
  104. package/dist/scripts/captureRestContracts.js.map +1 -0
  105. package/dist/scripts/checkOperationCoverage.d.ts +3 -0
  106. package/dist/scripts/checkOperationCoverage.d.ts.map +1 -0
  107. package/dist/scripts/checkOperationCoverage.js +302 -0
  108. package/dist/scripts/checkOperationCoverage.js.map +1 -0
  109. package/dist/scripts/cleanupStores.d.ts +3 -0
  110. package/dist/scripts/cleanupStores.d.ts.map +1 -0
  111. package/dist/scripts/cleanupStores.js +77 -0
  112. package/dist/scripts/cleanupStores.js.map +1 -0
  113. package/dist/scripts/createStores.d.ts +3 -0
  114. package/dist/scripts/createStores.d.ts.map +1 -0
  115. package/dist/scripts/createStores.js +66 -0
  116. package/dist/scripts/createStores.js.map +1 -0
  117. package/dist/scripts/deployAppVersion.d.ts +3 -0
  118. package/dist/scripts/deployAppVersion.d.ts.map +1 -0
  119. package/dist/scripts/deployAppVersion.js +591 -0
  120. package/dist/scripts/deployAppVersion.js.map +1 -0
  121. package/dist/scripts/devE2eBackend.d.ts +3 -0
  122. package/dist/scripts/devE2eBackend.d.ts.map +1 -0
  123. package/dist/scripts/devE2eBackend.js +117 -0
  124. package/dist/scripts/devE2eBackend.js.map +1 -0
  125. package/dist/scripts/devOnlineBackend.d.ts +3 -0
  126. package/dist/scripts/devOnlineBackend.d.ts.map +1 -0
  127. package/dist/scripts/devOnlineBackend.js +117 -0
  128. package/dist/scripts/devOnlineBackend.js.map +1 -0
  129. package/dist/scripts/installApp.d.ts +3 -0
  130. package/dist/scripts/installApp.d.ts.map +1 -0
  131. package/dist/scripts/installApp.js +163 -0
  132. package/dist/scripts/installApp.js.map +1 -0
  133. package/dist/scripts/listStores.d.ts +3 -0
  134. package/dist/scripts/listStores.d.ts.map +1 -0
  135. package/dist/scripts/listStores.js +18 -0
  136. package/dist/scripts/listStores.js.map +1 -0
  137. package/dist/scripts/runDocker.d.ts +3 -0
  138. package/dist/scripts/runDocker.d.ts.map +1 -0
  139. package/dist/scripts/runDocker.js +88 -0
  140. package/dist/scripts/runDocker.js.map +1 -0
  141. package/dist/scripts/runDockerAuth.d.ts +3 -0
  142. package/dist/scripts/runDockerAuth.d.ts.map +1 -0
  143. package/dist/scripts/runDockerAuth.js +108 -0
  144. package/dist/scripts/runDockerAuth.js.map +1 -0
  145. package/dist/scripts/runDockerOffline.d.ts +3 -0
  146. package/dist/scripts/runDockerOffline.d.ts.map +1 -0
  147. package/dist/scripts/runDockerOffline.js +129 -0
  148. package/dist/scripts/runDockerOffline.js.map +1 -0
  149. package/dist/scripts/runDockerOfflineExplore.d.ts +3 -0
  150. package/dist/scripts/runDockerOfflineExplore.d.ts.map +1 -0
  151. package/dist/scripts/runDockerOfflineExplore.js +116 -0
  152. package/dist/scripts/runDockerOfflineExplore.js.map +1 -0
  153. package/dist/scripts/runIsolatedDockerOffline.d.ts +3 -0
  154. package/dist/scripts/runIsolatedDockerOffline.d.ts.map +1 -0
  155. package/dist/scripts/runIsolatedDockerOffline.js +351 -0
  156. package/dist/scripts/runIsolatedDockerOffline.js.map +1 -0
  157. package/dist/scripts/runOffline.d.ts +3 -0
  158. package/dist/scripts/runOffline.d.ts.map +1 -0
  159. package/dist/scripts/runOffline.js +521 -0
  160. package/dist/scripts/runOffline.js.map +1 -0
  161. package/dist/scripts/runOfflineE2e.d.ts +3 -0
  162. package/dist/scripts/runOfflineE2e.d.ts.map +1 -0
  163. package/dist/scripts/runOfflineE2e.js +408 -0
  164. package/dist/scripts/runOfflineE2e.js.map +1 -0
  165. package/dist/scripts/runOfflineFullTests.d.ts +3 -0
  166. package/dist/scripts/runOfflineFullTests.d.ts.map +1 -0
  167. package/dist/scripts/runOfflineFullTests.js +1456 -0
  168. package/dist/scripts/runOfflineFullTests.js.map +1 -0
  169. package/dist/scripts/runSupermachine.d.ts +3 -0
  170. package/dist/scripts/runSupermachine.d.ts.map +1 -0
  171. package/dist/scripts/runSupermachine.js +474 -0
  172. package/dist/scripts/runSupermachine.js.map +1 -0
  173. package/dist/scripts/runSupermachineAuth.d.ts +3 -0
  174. package/dist/scripts/runSupermachineAuth.d.ts.map +1 -0
  175. package/dist/scripts/runSupermachineAuth.js +454 -0
  176. package/dist/scripts/runSupermachineAuth.js.map +1 -0
  177. package/dist/scripts/runTests.d.ts +3 -0
  178. package/dist/scripts/runTests.d.ts.map +1 -0
  179. package/dist/scripts/runTests.js +278 -0
  180. package/dist/scripts/runTests.js.map +1 -0
  181. package/dist/scripts/runVm.d.ts +3 -0
  182. package/dist/scripts/runVm.d.ts.map +1 -0
  183. package/dist/scripts/runVm.js +524 -0
  184. package/dist/scripts/runVm.js.map +1 -0
  185. package/dist/scripts/runVmAuth.d.ts +3 -0
  186. package/dist/scripts/runVmAuth.d.ts.map +1 -0
  187. package/dist/scripts/runVmAuth.js +475 -0
  188. package/dist/scripts/runVmAuth.js.map +1 -0
  189. package/dist/scripts/runVmScript.d.ts +3 -0
  190. package/dist/scripts/runVmScript.d.ts.map +1 -0
  191. package/dist/scripts/runVmScript.js +242 -0
  192. package/dist/scripts/runVmScript.js.map +1 -0
  193. package/dist/scripts/setupTestDb.d.ts +3 -0
  194. package/dist/scripts/setupTestDb.d.ts.map +1 -0
  195. package/dist/scripts/setupTestDb.js +61 -0
  196. package/dist/scripts/setupTestDb.js.map +1 -0
  197. package/dist/scripts/verifyContracts.d.ts +3 -0
  198. package/dist/scripts/verifyContracts.d.ts.map +1 -0
  199. package/dist/scripts/verifyContracts.js +258 -0
  200. package/dist/scripts/verifyContracts.js.map +1 -0
  201. package/dist/scripts/verifyRestContracts.d.ts +3 -0
  202. package/dist/scripts/verifyRestContracts.d.ts.map +1 -0
  203. package/dist/scripts/verifyRestContracts.js +237 -0
  204. package/dist/scripts/verifyRestContracts.js.map +1 -0
  205. package/dist/vite/offlineConfig.d.ts +34 -0
  206. package/dist/vite/offlineConfig.d.ts.map +1 -0
  207. package/dist/vite/offlineConfig.js +61 -0
  208. package/dist/vite/offlineConfig.js.map +1 -0
  209. package/dist/vite/onlineConfig.d.ts +42 -0
  210. package/dist/vite/onlineConfig.d.ts.map +1 -0
  211. package/dist/vite/onlineConfig.js +56 -0
  212. package/dist/vite/onlineConfig.js.map +1 -0
  213. package/docker/Dockerfile +67 -0
  214. package/docker/Dockerfile.vm +137 -0
  215. package/docker/README.md +50 -0
  216. package/docker/entrypoint.sh +198 -0
  217. package/package.json +85 -0
  218. package/src/contracts/normalize.ts +96 -0
  219. package/src/contracts/normalizeHtml.ts +98 -0
  220. package/src/edge/ca.cnf +14 -0
  221. package/src/edge/ca.crt +22 -0
  222. package/src/edge/ca.key +28 -0
  223. package/src/edge/cert.ts +117 -0
  224. package/src/edge/edgeProxy.ts +390 -0
  225. package/src/edge/server.cnf +28 -0
  226. package/src/edge/server.crt +26 -0
  227. package/src/edge/server.key +28 -0
  228. package/src/index.ts +67 -0
  229. package/src/lib/buildSourceBundle.ts +197 -0
  230. package/src/lib/freePort.ts +33 -0
  231. package/src/lib/functionBuild.ts +490 -0
  232. package/src/lib/neonWsProxy.ts +124 -0
  233. package/src/lib/sourceZipUpload.ts +168 -0
  234. package/src/lib/stealthLaunch.ts +57 -0
  235. package/src/lib/storeAutomation.ts +110 -0
  236. package/src/playwright/baseConfig.ts +120 -0
  237. package/src/playwright/globalSetup.ts +179 -0
  238. package/src/playwright/index.ts +11 -0
  239. package/src/probes/fonts.ts +279 -0
  240. package/src/probes/mirror.ts +283 -0
  241. package/src/probes/runProbe.ts +257 -0
  242. package/src/probes/types.ts +73 -0
  243. package/src/scripts/addStore.ts +59 -0
  244. package/src/scripts/buildDockerImage.ts +66 -0
  245. package/src/scripts/captureAuth.ts +145 -0
  246. package/src/scripts/captureContracts.ts +675 -0
  247. package/src/scripts/captureRestContracts.ts +319 -0
  248. package/src/scripts/checkOperationCoverage.ts +365 -0
  249. package/src/scripts/cleanupStores.ts +91 -0
  250. package/src/scripts/createStores.ts +77 -0
  251. package/src/scripts/deployAppVersion.ts +692 -0
  252. package/src/scripts/devOnlineBackend.ts +141 -0
  253. package/src/scripts/installApp.ts +188 -0
  254. package/src/scripts/listStores.ts +19 -0
  255. package/src/scripts/runDockerAuth.ts +120 -0
  256. package/src/scripts/runOffline.ts +577 -0
  257. package/src/scripts/runOfflineFullTests.ts +1634 -0
  258. package/src/scripts/runTests.ts +306 -0
  259. package/src/scripts/runVm.ts +562 -0
  260. package/src/scripts/runVmAuth.ts +541 -0
  261. package/src/scripts/runVmScript.ts +282 -0
  262. package/src/scripts/setupTestDb.ts +71 -0
  263. package/src/scripts/verifyContracts.ts +310 -0
  264. package/src/scripts/verifyRestContracts.ts +275 -0
  265. package/src/vite/onlineConfig.ts +60 -0
@@ -0,0 +1,56 @@
1
+ /** A single entry in the manifest.json's `modules` array. Matches
2
+ * the CLI's `ManifestModule` interface from app.ts. */
3
+ export interface ManifestModule {
4
+ type: string;
5
+ handle: string;
6
+ uid: string;
7
+ /** Folder name inside the archive that holds this module's
8
+ * artifacts. Conventionally equal to `uid`. */
9
+ assets?: string;
10
+ /** Single-target handle (e.g. "cart.lines.discounts.generate.run").
11
+ * Empty string for multi-target functions, omitted for non-targeted
12
+ * modules like app_home / branding / app_access. */
13
+ target?: string;
14
+ config: Record<string, unknown>;
15
+ }
16
+ export interface BuildSourceBundleOptions {
17
+ /** The app's top-level display name. Goes into `manifest.name`. */
18
+ name: string;
19
+ /** All modules for this deploy. */
20
+ modules: ManifestModule[];
21
+ /**
22
+ * Files to embed in the archive, keyed by their path-inside-the-
23
+ * archive. Function .wasm files MUST be base64-encoded as text by
24
+ * the caller (we'd do it here, but the caller already has the
25
+ * raw wasm and may or may not have other text/binary content —
26
+ * doing it here would obscure the contract).
27
+ */
28
+ files: Record<string, Buffer | string>;
29
+ /** Output path. Caller owns the path — typically /tmp/<…>.tar.br. */
30
+ outPath: string;
31
+ /**
32
+ * Brotli quality (0-11). Default 7 matches the CLI's choice. Higher
33
+ * = smaller + slower. Functions + theme bundles fit comfortably in
34
+ * a few hundred KB at quality 7.
35
+ */
36
+ brotliQuality?: number;
37
+ }
38
+ /**
39
+ * Build a tar+brotli source bundle and write it to `outPath`. Returns
40
+ * the path written.
41
+ *
42
+ * Implementation note: we tar in-memory (chunked into Node Buffers)
43
+ * then brotli-compress in one shot. Suitable for the < 10MB bundles
44
+ * we deal with; switch to streaming if that changes.
45
+ */
46
+ export declare function buildSourceBundle(opts: BuildSourceBundleOptions): Promise<string>;
47
+ /**
48
+ * Walk an extension directory and return its file contents keyed by
49
+ * the path-inside-the-archive-folder (i.e. NOT prefixed with the
50
+ * uid; the caller prepends that). Returns raw Buffers.
51
+ *
52
+ * Skips dirs/files that aren't shipped (same list as the inline
53
+ * theme bundler in deployAppVersion.ts).
54
+ */
55
+ export declare function readExtensionFilesAsBuffers(extensionDir: string): Record<string, Buffer>;
56
+ //# sourceMappingURL=buildSourceBundle.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"buildSourceBundle.d.ts","sourceRoot":"","sources":["../../src/lib/buildSourceBundle.ts"],"names":[],"mappings":"AAyDA;wDACwD;AACxD,MAAM,WAAW,cAAc;IAC7B,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,MAAM,CAAC;IACf,GAAG,EAAE,MAAM,CAAC;IACZ;oDACgD;IAChD,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB;;yDAEqD;IACrD,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CACjC;AAED,MAAM,WAAW,wBAAwB;IACvC,mEAAmE;IACnE,IAAI,EAAE,MAAM,CAAC;IACb,mCAAmC;IACnC,OAAO,EAAE,cAAc,EAAE,CAAC;IAC1B;;;;;;OAMG;IACH,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAAC,CAAC;IACvC,qEAAqE;IACrE,OAAO,EAAE,MAAM,CAAC;IAChB;;;;OAIG;IACH,aAAa,CAAC,EAAE,MAAM,CAAC;CACxB;AAED;;;;;;;GAOG;AACH,wBAAsB,iBAAiB,CACrC,IAAI,EAAE,wBAAwB,GAC7B,OAAO,CAAC,MAAM,CAAC,CAwCjB;AAED;;;;;;;GAOG;AACH,wBAAgB,2BAA2B,CACzC,YAAY,EAAE,MAAM,GACnB,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAsCxB"}
@@ -0,0 +1,153 @@
1
+ /**
2
+ * Assemble the source archive uploaded for `appVersionCreate` via
3
+ * the `sourceUrl` path.
4
+ *
5
+ * What format does Shopify actually accept?
6
+ * -----------------------------------------
7
+ * Empirically (May 2026, App Management /unstable/ endpoint): the
8
+ * server accepts **tar + brotli** (`.tar.br`), AND requires
9
+ * `sourceExtension: BR` when minting the signed-upload URL via
10
+ * `appRequestSourceUploadUrl`. The legacy `sourceExtension: ZIP`
11
+ * branch exists in the schema and returns a working signed URL, but
12
+ * something downstream chokes on zips that contain a per-extension
13
+ * folder layout — the server 500s on any zip whose top level has a
14
+ * `<uid>/...` directory entry. Tar+brotli works.
15
+ *
16
+ * This was reverse-engineered from `Shopify/cli`'s bundle pipeline:
17
+ * packages/app/src/cli/services/bundle.ts
18
+ * packages/cli-kit/src/public/node/archiver.ts
19
+ * The CLI ALWAYS uses tar+brotli; the ZIP code path appears to be
20
+ * unused / vestigial.
21
+ *
22
+ * Layout inside the archive
23
+ * -------------------------
24
+ * manifest.json ← top-level module list
25
+ * <module_uid>/dist/index.wasm ← function WASM, BASE64-
26
+ * ENCODED AS TEXT (not raw
27
+ * binary — see below)
28
+ * <theme_uid>/assets/<file> ← theme files, raw bytes
29
+ * <theme_uid>/blocks/<file>
30
+ * <theme_uid>/locales/<file>
31
+ * <theme_uid>/snippets/<file>
32
+ *
33
+ * The base64-encoding-of-wasm is THE critical detail that gets you
34
+ * past `"Wasm file is not present"`. The Shopify CLI does this in
35
+ * `bundleFunctionExtension(wasmPath, bundlePath)` which calls
36
+ * `readFile(path, {encoding: 'base64'})` and `writeFile(bundlePath, b64)`.
37
+ * The server reads the file at `<uid>/dist/index.wasm` and expects
38
+ * base64 text content, decoding it back to WASM bytes on its side.
39
+ *
40
+ * Manifest format
41
+ * ---------------
42
+ * Mirrors the CLI's `app.manifest()` builder
43
+ * (`packages/app/src/cli/models/app/app.ts`). Each module entry has:
44
+ * {
45
+ * type: <externalIdentifier — e.g. 'function' for plain function>,
46
+ * handle: <toml handle>,
47
+ * uid: <stable uuid>,
48
+ * assets: <uid>, ← same string as uid; folder name in archive
49
+ * target: <contextValue>, ← single-target handle, or '' for multi
50
+ * config: { … per-spec deployConfig output … },
51
+ * }
52
+ */
53
+ import { readFileSync, readdirSync, statSync, writeFileSync } from 'node:fs';
54
+ import { resolve } from 'node:path';
55
+ import { brotliCompressSync, constants as zlibConst } from 'node:zlib';
56
+ import { pack as tarPack } from 'tar-stream';
57
+ /**
58
+ * Build a tar+brotli source bundle and write it to `outPath`. Returns
59
+ * the path written.
60
+ *
61
+ * Implementation note: we tar in-memory (chunked into Node Buffers)
62
+ * then brotli-compress in one shot. Suitable for the < 10MB bundles
63
+ * we deal with; switch to streaming if that changes.
64
+ */
65
+ export async function buildSourceBundle(opts) {
66
+ const manifestJson = JSON.stringify({ name: opts.name, handle: '', modules: opts.modules }, null, 2);
67
+ const entries = [
68
+ { name: 'manifest.json', content: Buffer.from(manifestJson, 'utf8') },
69
+ ];
70
+ for (const [name, content] of Object.entries(opts.files)) {
71
+ entries.push({
72
+ name,
73
+ content: Buffer.isBuffer(content) ? content : Buffer.from(content, 'utf8'),
74
+ });
75
+ }
76
+ // tar-stream pack: collect chunks, finalize, then brotli-compress.
77
+ const tarBuf = await new Promise((resolve_, reject) => {
78
+ const pack = tarPack();
79
+ const chunks = [];
80
+ pack.on('data', (c) => chunks.push(c));
81
+ pack.on('end', () => resolve_(Buffer.concat(chunks)));
82
+ pack.on('error', reject);
83
+ (async () => {
84
+ for (const e of entries) {
85
+ await new Promise((res, rej) => {
86
+ pack.entry({ name: e.name }, e.content, (err) => (err ? rej(err) : res()));
87
+ });
88
+ }
89
+ pack.finalize();
90
+ })().catch(reject);
91
+ });
92
+ const brBuf = brotliCompressSync(tarBuf, {
93
+ params: {
94
+ [zlibConst.BROTLI_PARAM_QUALITY]: opts.brotliQuality ?? 7,
95
+ },
96
+ });
97
+ writeFileSync(opts.outPath, brBuf);
98
+ return opts.outPath;
99
+ }
100
+ /**
101
+ * Walk an extension directory and return its file contents keyed by
102
+ * the path-inside-the-archive-folder (i.e. NOT prefixed with the
103
+ * uid; the caller prepends that). Returns raw Buffers.
104
+ *
105
+ * Skips dirs/files that aren't shipped (same list as the inline
106
+ * theme bundler in deployAppVersion.ts).
107
+ */
108
+ export function readExtensionFilesAsBuffers(extensionDir) {
109
+ const SKIP_DIRS = new Set([
110
+ 'node_modules',
111
+ '.git',
112
+ 'src',
113
+ 'frontend',
114
+ 'generated',
115
+ ]);
116
+ const SKIP_FILES = new Set([
117
+ 'shopify.extension.toml',
118
+ 'package.json',
119
+ 'package-lock.json',
120
+ 'tsconfig.json',
121
+ '.shopifyignore',
122
+ '.gitignore',
123
+ 'README.md',
124
+ ]);
125
+ const out = {};
126
+ function walk(dir, rel) {
127
+ for (const name of readdirSync(dir)) {
128
+ const full = resolve(dir, name);
129
+ const relPath = rel ? `${rel}/${name}` : name;
130
+ const st = statSync(full);
131
+ if (st.isDirectory()) {
132
+ if (SKIP_DIRS.has(name) || name.startsWith('.'))
133
+ continue;
134
+ walk(full, relPath);
135
+ continue;
136
+ }
137
+ if (SKIP_FILES.has(name))
138
+ continue;
139
+ if (name.endsWith('.config.ts') || name.endsWith('.config.mts'))
140
+ continue;
141
+ if (name.endsWith('.config.js') || name.endsWith('.config.cjs'))
142
+ continue;
143
+ if (name.endsWith('.js.map'))
144
+ continue; // CLI excludes these
145
+ if (name.endsWith('.metafile.json'))
146
+ continue; // CLI excludes these
147
+ out[relPath] = readFileSync(full);
148
+ }
149
+ }
150
+ walk(extensionDir, '');
151
+ return out;
152
+ }
153
+ //# sourceMappingURL=buildSourceBundle.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"buildSourceBundle.js","sourceRoot":"","sources":["../../src/lib/buildSourceBundle.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,5 @@
1
+ /** Asks the OS for a random free TCP port. */
2
+ export declare function findFreePort(): Promise<number>;
3
+ /** Returns true if the given port is free to bind. */
4
+ export declare function isPortFree(port: number): Promise<boolean>;
5
+ //# sourceMappingURL=freePort.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"freePort.d.ts","sourceRoot":"","sources":["../../src/lib/freePort.ts"],"names":[],"mappings":"AAEA,8CAA8C;AAC9C,wBAAgB,YAAY,IAAI,OAAO,CAAC,MAAM,CAAC,CAgB9C;AAED,sDAAsD;AACtD,wBAAgB,UAAU,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAUzD"}
@@ -0,0 +1,33 @@
1
+ import { createServer } from 'node:net';
2
+ /** Asks the OS for a random free TCP port. */
3
+ export function findFreePort() {
4
+ return new Promise((resolve, reject) => {
5
+ const srv = createServer();
6
+ srv.unref();
7
+ srv.on('error', reject);
8
+ srv.listen(0, '127.0.0.1', () => {
9
+ const addr = srv.address();
10
+ if (addr && typeof addr === 'object') {
11
+ const port = addr.port;
12
+ srv.close(() => resolve(port));
13
+ }
14
+ else {
15
+ srv.close();
16
+ reject(new Error('Could not determine free port'));
17
+ }
18
+ });
19
+ });
20
+ }
21
+ /** Returns true if the given port is free to bind. */
22
+ export function isPortFree(port) {
23
+ return new Promise((resolve) => {
24
+ const srv = createServer();
25
+ srv.unref();
26
+ srv.once('error', () => resolve(false));
27
+ srv.once('listening', () => {
28
+ srv.close(() => resolve(true));
29
+ });
30
+ srv.listen(port, '127.0.0.1');
31
+ });
32
+ }
33
+ //# sourceMappingURL=freePort.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"freePort.js","sourceRoot":"","sources":["../../src/lib/freePort.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,UAAU,CAAC;AAExC,8CAA8C;AAC9C,MAAM,UAAU,YAAY;IAC1B,OAAO,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE;QACrC,MAAM,GAAG,GAAG,YAAY,EAAE,CAAC;QAC3B,GAAG,CAAC,KAAK,EAAE,CAAC;QACZ,GAAG,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,CAAC,CAAC;QACxB,GAAG,CAAC,MAAM,CAAC,CAAC,EAAE,WAAW,EAAE,GAAG,EAAE;YAC9B,MAAM,IAAI,GAAG,GAAG,CAAC,OAAO,EAAE,CAAC;YAC3B,IAAI,IAAI,IAAI,OAAO,IAAI,KAAK,QAAQ,EAAE,CAAC;gBACrC,MAAM,IAAI,GAAG,IAAI,CAAC,IAAI,CAAC;gBACvB,GAAG,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC;YACjC,CAAC;iBAAM,CAAC;gBACN,GAAG,CAAC,KAAK,EAAE,CAAC;gBACZ,MAAM,CAAC,IAAI,KAAK,CAAC,+BAA+B,CAAC,CAAC,CAAC;YACrD,CAAC;QACH,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;AACL,CAAC;AAED,sDAAsD;AACtD,MAAM,UAAU,UAAU,CAAC,IAAY;IACrC,OAAO,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,EAAE;QAC7B,MAAM,GAAG,GAAG,YAAY,EAAE,CAAC;QAC3B,GAAG,CAAC,KAAK,EAAE,CAAC;QACZ,GAAG,CAAC,IAAI,CAAC,OAAO,EAAE,GAAG,EAAE,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC;QACxC,GAAG,CAAC,IAAI,CAAC,WAAW,EAAE,GAAG,EAAE;YACzB,GAAG,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC;QACjC,CAAC,CAAC,CAAC;QACH,GAAG,CAAC,MAAM,CAAC,IAAI,EAAE,WAAW,CAAC,CAAC;IAChC,CAAC,CAAC,CAAC;AACL,CAAC"}
@@ -0,0 +1,99 @@
1
+ /**
2
+ * Pinned Javy version. Bumping = updating the URL pattern in
3
+ * `binaryUrlForJavy` AND verifying the `-C` flag interface hasn't
4
+ * changed across the bump (Javy did break flags between v0.x and v3+).
5
+ */
6
+ export declare const JAVY_VERSION = "v7.0.1";
7
+ /**
8
+ * Pinned Shopify Functions Javy plugin wasm. The URL contains the
9
+ * major version (`_v3`) — if Shopify publishes a `_v4`, we explicitly
10
+ * decide whether to upgrade (the plugin's host ABI is what user JS
11
+ * sees via `@shopify/shopify_function`).
12
+ */
13
+ export declare const PLUGIN_URL = "https://cdn.shopify.com/shopifycloud/shopify-functions-javy-plugin/shopify_functions_javy_v3.wasm";
14
+ /**
15
+ * Return a path to the Javy binary, downloading it on first use.
16
+ * Idempotent — second call hits the on-disk cache. `JAVY_BIN`
17
+ * environment variable bypasses the download and points at a local
18
+ * build (useful when tracking Javy main).
19
+ */
20
+ export declare function ensureJavy(): Promise<string>;
21
+ /**
22
+ * Return a path to the Shopify Functions Javy plugin wasm,
23
+ * downloading it on first use. `JAVY_PLUGIN_WASM` env overrides for
24
+ * local plugin development.
25
+ */
26
+ export declare function ensureJavyPlugin(): Promise<string>;
27
+ /**
28
+ * One `[[extensions.targeting]]` block in a function's
29
+ * `shopify.extension.toml`. Maps to one exported function in the
30
+ * compiled wasm.
31
+ *
32
+ * target e.g. "cart.lines.discounts.generate.run" (Shopify-defined)
33
+ * export e.g. "cart-lines-discounts-generate-run" (what we name
34
+ * the wasm export — Shopify's docs use kebab-case here)
35
+ * input_query path (relative to the function dir) of the GraphQL
36
+ * query that produces the function's input — embedded
37
+ * into the deploy manifest, NOT compiled into the wasm.
38
+ */
39
+ export interface FunctionTarget {
40
+ target: string;
41
+ export: string;
42
+ inputQueryPath: string;
43
+ }
44
+ /**
45
+ * Subset of `shopify.extension.toml` that we care about for the build.
46
+ * We don't validate fields we don't use (e.g. `name`/`description`
47
+ * which come from locales) so this shape may grow as we touch more
48
+ * function deploys.
49
+ */
50
+ export interface ParsedFunctionToml {
51
+ handle: string;
52
+ /** Stable per-extension UUID baked into the toml. Shopify uses it
53
+ * to correlate the manifest entry with the right folder inside the
54
+ * source zip (the zip layout is `<uid>/dist/function.wasm`). */
55
+ uid: string;
56
+ type: 'function';
57
+ apiVersion: string;
58
+ /** Each target becomes one exported function in the compiled wasm. */
59
+ targets: FunctionTarget[];
60
+ /** `[extensions.build].path` — defaults to `dist/function.wasm`. */
61
+ outputRelativePath: string;
62
+ }
63
+ /**
64
+ * Bespoke parser for the function's `shopify.extension.toml`. The
65
+ * minimal-toml reader in `deployAppVersion.ts` doesn't grok arrays of
66
+ * inline tables (`[[extensions.targeting]]`), so we do a tiny ad-hoc
67
+ * parse here. It's intentionally narrow — only handles the shape
68
+ * `shopify app function init` produces (essentially: a single
69
+ * `[[extensions]]` table containing N `[[extensions.targeting]]`
70
+ * sub-tables and one `[extensions.build]` sub-table).
71
+ *
72
+ * If/when we deploy a function with multiple top-level `[[extensions]]`
73
+ * entries (rare — usually one file per extension dir), this needs
74
+ * generalizing.
75
+ */
76
+ export declare function parseFunctionToml(path: string): ParsedFunctionToml;
77
+ export interface BuildFunctionWasmOptions {
78
+ /** Directory containing `shopify.extension.toml` + `src/index.{ts,js}`. */
79
+ functionDir: string;
80
+ /**
81
+ * Optional override for the input source file. Defaults to
82
+ * src/index.ts / src/index.js. Useful for tests.
83
+ */
84
+ entrySource?: string;
85
+ }
86
+ export interface BuildFunctionWasmResult {
87
+ wasmPath: string;
88
+ parsedToml: ParsedFunctionToml;
89
+ }
90
+ /**
91
+ * Build a deployable `.wasm` for a JS Shopify Function.
92
+ *
93
+ * Idempotent: rebuilds on every call (we don't try to be clever about
94
+ * stale-cache detection — esbuild + javy together are ~hundreds of
95
+ * milliseconds, fast enough that incremental caching is unnecessary
96
+ * for our use case).
97
+ */
98
+ export declare function buildFunctionWasm(opts: BuildFunctionWasmOptions): Promise<BuildFunctionWasmResult>;
99
+ //# sourceMappingURL=functionBuild.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"functionBuild.d.ts","sourceRoot":"","sources":["../../src/lib/functionBuild.ts"],"names":[],"mappings":"AAyDA;;;;GAIG;AACH,eAAO,MAAM,YAAY,WAAW,CAAC;AAErC;;;;;GAKG;AACH,eAAO,MAAM,UAAU,sGAC8E,CAAC;AAoFtG;;;;;GAKG;AACH,wBAAsB,UAAU,IAAI,OAAO,CAAC,MAAM,CAAC,CAclD;AAED;;;;GAIG;AACH,wBAAsB,gBAAgB,IAAI,OAAO,CAAC,MAAM,CAAC,CAaxD;AAED;;;;;;;;;;;GAWG;AACH,MAAM,WAAW,cAAc;IAC7B,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;IACf,cAAc,EAAE,MAAM,CAAC;CACxB;AAED;;;;;GAKG;AACH,MAAM,WAAW,kBAAkB;IACjC,MAAM,EAAE,MAAM,CAAC;IACf;;oEAEgE;IAChE,GAAG,EAAE,MAAM,CAAC;IACZ,IAAI,EAAE,UAAU,CAAC;IACjB,UAAU,EAAE,MAAM,CAAC;IACnB,sEAAsE;IACtE,OAAO,EAAE,cAAc,EAAE,CAAC;IAC1B,oEAAoE;IACpE,kBAAkB,EAAE,MAAM,CAAC;CAC5B;AAED;;;;;;;;;;;;GAYG;AACH,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,MAAM,GAAG,kBAAkB,CA6ElE;AA0ED,MAAM,WAAW,wBAAwB;IACvC,2EAA2E;IAC3E,WAAW,EAAE,MAAM,CAAC;IACpB;;;OAGG;IACH,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB;AAED,MAAM,WAAW,uBAAuB;IACtC,QAAQ,EAAE,MAAM,CAAC;IACjB,UAAU,EAAE,kBAAkB,CAAC;CAChC;AAED;;;;;;;GAOG;AACH,wBAAsB,iBAAiB,CACrC,IAAI,EAAE,wBAAwB,GAC7B,OAAO,CAAC,uBAAuB,CAAC,CAiElC"}