@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,219 @@
1
+ #!/usr/bin/env node
2
+ /**
3
+ * Probe runner — entry point for the online-store inspection framework.
4
+ *
5
+ * Invocation:
6
+ * node --import tsx \
7
+ * node_modules/@essential-apps/shopify-test-runner/src/probes/runProbe.ts \
8
+ * <probe-name> [--key=value …]
9
+ *
10
+ * What it does:
11
+ * 1. Loads the consuming app's `.env.test` so probes can read
12
+ * env (e.g. STOREFRONT_PASSWORD).
13
+ * 2. Picks an installed store from `tests/test-online/.stores.json`.
14
+ * 3. Launches Playwright chromium via patchright with the
15
+ * saved Partner storage state — same recipe online tests use.
16
+ * 4. Hands control to the probe.
17
+ *
18
+ * Adding a probe: drop a file in `packages/runner/src/probes/<name>.ts`
19
+ * default-exporting a {@link Probe}, and add a row to `PROBES` below.
20
+ */
21
+ import { existsSync, mkdirSync, readFileSync } from 'node:fs';
22
+ import { resolve, dirname } from 'node:path';
23
+ import { fileURLToPath } from 'node:url';
24
+ import { readRegistry, storageStatePath, } from '@essential-apps/shopify-test-core';
25
+ import fontsProbe from './fonts.js';
26
+ import mirrorProbe from './mirror.js';
27
+ import { launchStealthBrowser } from '../lib/stealthLaunch.js';
28
+ // ── Registry of available probes ──────────────────────────────
29
+ // Order matters only for `--help` listing.
30
+ const PROBES = {
31
+ [fontsProbe.name]: fontsProbe,
32
+ [mirrorProbe.name]: mirrorProbe,
33
+ };
34
+ function parseArgs(argv) {
35
+ const [name, ...rest] = argv;
36
+ const args = {};
37
+ let help = false;
38
+ for (const a of rest) {
39
+ if (a === '--help' || a === '-h') {
40
+ help = true;
41
+ continue;
42
+ }
43
+ const m = a.match(/^--([^=]+)=(.*)$/);
44
+ if (m) {
45
+ args[m[1]] = m[2];
46
+ continue;
47
+ }
48
+ // Bare flag: --foo (no value) → true
49
+ const bare = a.match(/^--(.+)$/);
50
+ if (bare) {
51
+ args[bare[1]] = '';
52
+ }
53
+ }
54
+ return { name: name ?? '', args, help };
55
+ }
56
+ function printUsage() {
57
+ console.error('Usage: runProbe <name> [--key=value …]');
58
+ console.error('');
59
+ console.error('Available probes:');
60
+ for (const p of Object.values(PROBES)) {
61
+ console.error(` ${p.name.padEnd(14)} ${p.description}`);
62
+ }
63
+ console.error('');
64
+ console.error('Global flags:');
65
+ console.error(' --help Show this help');
66
+ console.error(' --store=<slug> Use a specific store from the pool (default: any available)');
67
+ console.error('');
68
+ }
69
+ // ── Workspace path discovery ──────────────────────────────────
70
+ /**
71
+ * Locate the workspace root. When this script runs from a packed
72
+ * tarball inside a consumer's node_modules, the workspace is the
73
+ * shopify-test repo's root — the package nearest us with
74
+ * `name === "@essential-apps/shopify-test"`. When running from the
75
+ * repo itself, that's the repo root.
76
+ *
77
+ * We walk up from this file looking for a `package.json` whose
78
+ * `name` matches, falling back to the nearest directory containing
79
+ * a `packages/` folder (matches the monorepo layout).
80
+ */
81
+ function findWorkspaceRoot() {
82
+ // When invoked from a consumer, the runner's source lives under
83
+ // `node_modules/@essential-apps/shopify-test-runner/src/`. That
84
+ // path doesn't help us reach the workspace's themes/, etc.
85
+ // Look upward from this file for the workspace root marker.
86
+ let dir = dirname(fileURLToPath(import.meta.url));
87
+ for (let i = 0; i < 10; i++) {
88
+ const pj = resolve(dir, 'package.json');
89
+ if (existsSync(pj)) {
90
+ try {
91
+ const pkg = JSON.parse(readFileSync(pj, 'utf8'));
92
+ if (pkg.name === '@essential-apps/shopify-test')
93
+ return dir;
94
+ }
95
+ catch {
96
+ /* fall through */
97
+ }
98
+ }
99
+ const parent = resolve(dir, '..');
100
+ if (parent === dir)
101
+ break;
102
+ dir = parent;
103
+ }
104
+ // Fallback: assume cwd is the consumer app — outputs go to its
105
+ // tests/test-online/probe-output/ if we can't find a workspace.
106
+ return process.cwd();
107
+ }
108
+ // ── Store selection ───────────────────────────────────────────
109
+ function pickStore(slug) {
110
+ const { stores } = readRegistry();
111
+ if (slug) {
112
+ const s = stores.find((x) => x.slug === slug);
113
+ if (!s) {
114
+ throw new Error(`Store with slug "${slug}" not found in registry. ` +
115
+ `Available: ${stores.map((x) => x.slug).join(', ')}`);
116
+ }
117
+ return s;
118
+ }
119
+ const candidate = stores.find((s) => s.appInstalled && s.status === 'available') ??
120
+ stores.find((s) => s.appInstalled) ??
121
+ stores[0];
122
+ if (!candidate) {
123
+ throw new Error('No stores in registry. Run `npm run test:online:add` + `npm run test:online:install` first.');
124
+ }
125
+ return candidate;
126
+ }
127
+ /**
128
+ * Synthesize a Store record from a bare URL. Used by `--url=<full>`
129
+ * mode so probes can run against arbitrary public Shopify storefronts
130
+ * (e.g. `theme-dawn-demo.myshopify.com` for canonical Dawn font
131
+ * mirroring) without needing a Partner-auth registry entry.
132
+ */
133
+ function storeFromUrl(rawUrl) {
134
+ const u = new URL(rawUrl);
135
+ const shop = u.hostname;
136
+ const slug = shop.replace(/\.myshopify\.com$/, '');
137
+ return {
138
+ shop,
139
+ slug,
140
+ plan: 'PUBLIC',
141
+ appInstalled: false,
142
+ status: 'available',
143
+ };
144
+ }
145
+ // ── Browser bootstrap ─────────────────────────────────────────
146
+ async function launchBrowser(opts) {
147
+ // Reuse the same chrome+patchright recipe as the online-test store
148
+ // pool: real Google Chrome via patchright. For probes against
149
+ // Partner-owned stores we layer in the saved Partner storage
150
+ // state so password gates / admin redirects work; for public
151
+ // storefronts (--url mode) we skip that — no auth needed.
152
+ const browser = await launchStealthBrowser({ headless: true });
153
+ const storageState = opts.needAuth && existsSync(storageStatePath)
154
+ ? JSON.parse(readFileSync(storageStatePath, 'utf8'))
155
+ : undefined;
156
+ if (opts.needAuth && !storageState) {
157
+ throw new Error(`Storage state not found at ${storageStatePath}. ` +
158
+ `Run online tests at least once to capture Partner auth cookies, ` +
159
+ `or pass --url=<public-store-url> to skip auth.`);
160
+ }
161
+ const context = await browser.newContext({
162
+ viewport: { width: 1400, height: 900 },
163
+ ignoreHTTPSErrors: true,
164
+ ...(storageState ? { storageState } : {}),
165
+ });
166
+ return context;
167
+ }
168
+ // ── Main ──────────────────────────────────────────────────────
169
+ async function main() {
170
+ const parsed = parseArgs(process.argv.slice(2));
171
+ if (parsed.help || !parsed.name) {
172
+ printUsage();
173
+ process.exit(parsed.name ? 0 : 1);
174
+ }
175
+ const probe = PROBES[parsed.name];
176
+ if (!probe) {
177
+ console.error(`Unknown probe: "${parsed.name}"\n`);
178
+ printUsage();
179
+ process.exit(1);
180
+ }
181
+ const workspaceRoot = findWorkspaceRoot();
182
+ // --url=<full> mode: synthesize a Store record from the URL and
183
+ // skip auth. For probing arbitrary public storefronts (e.g.
184
+ // theme-dawn-demo.myshopify.com for canonical Dawn font mirroring).
185
+ const urlMode = parsed.args['url'];
186
+ const store = urlMode ? storeFromUrl(urlMode) : pickStore(parsed.args['store']);
187
+ const outputDir = resolve(workspaceRoot, probe.outputDir.replace(/\$\{name\}/g, probe.name));
188
+ mkdirSync(outputDir, { recursive: true });
189
+ console.log(`[runProbe] probe: ${probe.name}`);
190
+ console.log(`[runProbe] store: ${store.shop} (${store.slug})${urlMode ? ' [public --url mode]' : ''}`);
191
+ console.log(`[runProbe] output: ${outputDir}`);
192
+ const browserContext = await launchBrowser({ needAuth: !urlMode });
193
+ const page = await browserContext.newPage();
194
+ const ctx = {
195
+ store,
196
+ browserContext,
197
+ page,
198
+ outputDir,
199
+ args: parsed.args,
200
+ workspaceRoot,
201
+ };
202
+ try {
203
+ await probe.run(ctx);
204
+ console.log(`[runProbe] ✓ ${probe.name} complete`);
205
+ }
206
+ catch (err) {
207
+ console.error(`[runProbe] ✗ ${probe.name} failed:`, err);
208
+ process.exitCode = 1;
209
+ }
210
+ finally {
211
+ await browserContext.close().catch(() => { });
212
+ await browserContext.browser()?.close().catch(() => { });
213
+ }
214
+ }
215
+ main().catch((err) => {
216
+ console.error(err);
217
+ process.exit(1);
218
+ });
219
+ //# sourceMappingURL=runProbe.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"runProbe.js","sourceRoot":"","sources":["../../src/probes/runProbe.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,72 @@
1
+ /**
2
+ * Probe framework — a reusable harness for asking real Shopify
3
+ * "what does this actually look like?" against the online test store
4
+ * pool.
5
+ *
6
+ * Why this exists: every offline mock has a long tail of "is our
7
+ * shape right?" questions. Examples we've already hit:
8
+ * - what URLs does Shopify's `font_face` Liquid filter emit?
9
+ * - what does the real `themes/{id}/assets.json` response look like?
10
+ * - what HTTP headers does fonts.shopifycdn.com set on a .woff2?
11
+ * - what's the exact `settings_data.json` shape when an app embed
12
+ * is activated?
13
+ *
14
+ * Each probe is a small Node script that drives a Playwright browser
15
+ * against a real online store (picked from `tests/test-online/.stores.json`),
16
+ * captures structured fixture data, and writes it somewhere the
17
+ * mocks can read at runtime.
18
+ *
19
+ * Adding a probe: create `packages/runner/src/probes/<name>.ts`,
20
+ * default-export an object conforming to {@link Probe}, and add a
21
+ * row to the registry in `runProbe.ts`.
22
+ *
23
+ * Invoke from the consuming app's repo:
24
+ * node --import tsx \
25
+ * node_modules/@essential-apps/shopify-test-runner/src/probes/runProbe.ts \
26
+ * <probe-name> [--key=value …]
27
+ */
28
+ import type { BrowserContext, Page } from '@playwright/test';
29
+ import type { Store } from '@essential-apps/shopify-test-core';
30
+ /**
31
+ * Per-probe execution context. The runner sets up the browser +
32
+ * store before invoking the probe; the probe focuses on what it
33
+ * captures, not how to get a browser.
34
+ */
35
+ export interface ProbeContext {
36
+ /** The online store this probe runs against. */
37
+ store: Store;
38
+ /** Logged-in Playwright BrowserContext (storage state pre-loaded). */
39
+ browserContext: BrowserContext;
40
+ /** Convenience: a fresh page in the context. Probes can open more. */
41
+ page: Page;
42
+ /**
43
+ * Absolute path where probe artifacts go. Probes write fixture
44
+ * files (JSON, binary, etc.) under here so the mock packages
45
+ * can read them later. Conventionally the workspace path
46
+ * `packages/<owner-package>/fixtures/<probe-name>/`.
47
+ */
48
+ outputDir: string;
49
+ /** Parsed --key=value CLI args. */
50
+ args: Record<string, string>;
51
+ /** Workspace root absolute path (the shopify-test repo). */
52
+ workspaceRoot: string;
53
+ }
54
+ export interface Probe {
55
+ /** Probe name — what you type after `runProbe`. */
56
+ name: string;
57
+ /** One-line description shown in `runProbe --help`. */
58
+ description: string;
59
+ /**
60
+ * Where outputs should go, relative to workspaceRoot. The harness
61
+ * creates this dir and passes its absolute path as
62
+ * `ctx.outputDir`. Use `${name}` etc. — substituted at runtime.
63
+ */
64
+ outputDir: string;
65
+ /**
66
+ * Main entry point. Throws on failure; logs progress to stdout.
67
+ * Should be idempotent — re-running a probe should refresh
68
+ * outputs cleanly.
69
+ */
70
+ run(ctx: ProbeContext): Promise<void>;
71
+ }
72
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/probes/types.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AACH,OAAO,KAAK,EAAE,cAAc,EAAE,IAAI,EAAE,MAAM,kBAAkB,CAAC;AAC7D,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,mCAAmC,CAAC;AAE/D;;;;GAIG;AACH,MAAM,WAAW,YAAY;IAC3B,gDAAgD;IAChD,KAAK,EAAE,KAAK,CAAC;IACb,sEAAsE;IACtE,cAAc,EAAE,cAAc,CAAC;IAC/B,sEAAsE;IACtE,IAAI,EAAE,IAAI,CAAC;IACX;;;;;OAKG;IACH,SAAS,EAAE,MAAM,CAAC;IAClB,mCAAmC;IACnC,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC7B,4DAA4D;IAC5D,aAAa,EAAE,MAAM,CAAC;CACvB;AAED,MAAM,WAAW,KAAK;IACpB,mDAAmD;IACnD,IAAI,EAAE,MAAM,CAAC;IACb,uDAAuD;IACvD,WAAW,EAAE,MAAM,CAAC;IACpB;;;;OAIG;IACH,SAAS,EAAE,MAAM,CAAC;IAClB;;;;OAIG;IACH,GAAG,CAAC,GAAG,EAAE,YAAY,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;CACvC"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/probes/types.ts"],"names":[],"mappings":""}
@@ -0,0 +1,3 @@
1
+ #!/usr/bin/env node
2
+ export {};
3
+ //# sourceMappingURL=_probeSourceUrl.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"_probeSourceUrl.d.ts","sourceRoot":"","sources":["../../src/scripts/_probeSourceUrl.ts"],"names":[],"mappings":""}
@@ -0,0 +1,119 @@
1
+ #!/usr/bin/env node
2
+ /** Test the CLI's actual format: tar + brotli, sourceExtension: BR. */
3
+ import { createReadStream, readFileSync, statSync, writeFileSync } from 'node:fs';
4
+ import { Readable } from 'node:stream';
5
+ import { randomUUID } from 'node:crypto';
6
+ import { brotliCompressSync, constants as zlibConst } from 'node:zlib';
7
+ import { pack as tarPack } from 'tar-stream';
8
+ const TOKEN = process.env.SHOPIFY_APP_AUTOMATION_TOKEN;
9
+ const ORG = 'gid://shopify/Organization/217838969';
10
+ const APP = 'gid://shopify/App/366427176961';
11
+ const WS = '/Users/domas/Developer/supercorp/essential-upsell';
12
+ async function getAt() {
13
+ const body = new URLSearchParams({
14
+ grant_type: 'urn:ietf:params:oauth:grant-type:token-exchange',
15
+ requested_token_type: 'urn:ietf:params:oauth:token-type:access_token',
16
+ subject_token_type: 'urn:ietf:params:oauth:token-type:access_token',
17
+ client_id: 'fbdb2649-e327-4907-8f67-908d24cfd7e3',
18
+ audience: '7ee65a63608843c577db8b23c4d7316ea0a01bd2f7594f8a9c06ea668c1b775c',
19
+ scope: 'https://api.shopify.com/auth/organization.apps.manage',
20
+ subject_token: TOKEN,
21
+ }).toString();
22
+ const r = await fetch('https://accounts.shopify.com/oauth/token', { method: 'POST', headers: { 'Content-Type': 'application/x-www-form-urlencoded' }, body });
23
+ return JSON.parse(await r.text()).access_token;
24
+ }
25
+ async function gql(at, body) {
26
+ const r = await fetch('https://app.shopify.com/app_management/unstable/graphql.json', { method: 'POST', headers: { 'Content-Type': 'application/json', Authorization: `Bearer ${at}`, 'X-Shopify-Access-Token': `Bearer ${at}` }, body: JSON.stringify(body) });
27
+ return { status: r.status, body: await r.text() };
28
+ }
29
+ async function mintBr(at) {
30
+ const r = await gql(at, { query: `mutation Q($o:ID!){appRequestSourceUploadUrl(sourceExtension:BR,organizationId:$o){sourceUploadUrl userErrors{field message}}}`, variables: { o: ORG } });
31
+ return JSON.parse(r.body).data.appRequestSourceUploadUrl.sourceUploadUrl;
32
+ }
33
+ async function upload(url, path) {
34
+ const size = statSync(path).size;
35
+ const body = Readable.toWeb(createReadStream(path));
36
+ const r = await fetch(url, {
37
+ method: 'PUT', body,
38
+ // Match CLI: no content-encoding header, raw bytes
39
+ headers: { 'Content-Length': String(size) },
40
+ // @ts-expect-error
41
+ duplex: 'half',
42
+ });
43
+ if (!r.ok)
44
+ throw new Error(`upload: ${r.status} ${await r.text()}`);
45
+ }
46
+ /** Build a tar archive in memory from { path: bytes } map. */
47
+ async function buildTarBr(files) {
48
+ return new Promise((resolve, reject) => {
49
+ const pack = tarPack();
50
+ const chunks = [];
51
+ pack.on('data', (c) => chunks.push(c));
52
+ pack.on('end', () => {
53
+ const tarBuf = Buffer.concat(chunks);
54
+ const brBuf = brotliCompressSync(tarBuf, {
55
+ params: { [zlibConst.BROTLI_PARAM_QUALITY]: 7 },
56
+ });
57
+ resolve(brBuf);
58
+ });
59
+ pack.on('error', reject);
60
+ (async () => {
61
+ for (const [name, content] of Object.entries(files)) {
62
+ const buf = Buffer.isBuffer(content) ? content : Buffer.from(content, 'utf8');
63
+ await new Promise((res, rej) => {
64
+ pack.entry({ name }, buf, (err) => (err ? rej(err) : res()));
65
+ });
66
+ }
67
+ pack.finalize();
68
+ })().catch(reject);
69
+ });
70
+ }
71
+ async function tryIt(at, label, manifest, files) {
72
+ const tarBr = await buildTarBr({ 'manifest.json': JSON.stringify(manifest, null, 2), ...files });
73
+ const p = `/tmp/probe-${Date.now()}.tar.br`;
74
+ writeFileSync(p, tarBr);
75
+ console.log(`\n--- ${label} (tar.br: ${tarBr.length} bytes) ---`);
76
+ const url = await mintBr(at);
77
+ await upload(url, p);
78
+ const r = await gql(at, {
79
+ query: `mutation Q($a:ID!,$v:AppVersionInput!,$m:VersionMetadataInput){appVersionCreate(appId:$a,version:$v,metadata:$m){version{id metadata{versionTag} appModules{uuid handle specification{identifier}}} userErrors{field message category code}}}`,
80
+ variables: { a: APP, v: { sourceUrl: url }, m: { versionTag: `probe-${Date.now()}`, message: label } },
81
+ });
82
+ console.log(`status ${r.status}: ${r.body.slice(0, 1500)}`);
83
+ }
84
+ async function main() {
85
+ const at = await getAt();
86
+ const fnWasm = readFileSync(`${WS}/app_extensions/discounts/dist/function.wasm`);
87
+ const fnWasmB64 = fnWasm.toString('base64');
88
+ const iq1 = readFileSync(`${WS}/app_extensions/discounts/src/cart_lines_discounts_generate_run.graphql`, 'utf8');
89
+ const iq2 = readFileSync(`${WS}/app_extensions/discounts/src/cart_delivery_options_discounts_generate_run.graphql`, 'utf8');
90
+ const targets = [
91
+ { handle: 'cart.lines.discounts.generate.run', export: 'cart-lines-discounts-generate-run', input_query: iq1 },
92
+ { handle: 'cart.delivery-options.discounts.generate.run', export: 'cart-delivery-options-discounts-generate-run', input_query: iq2 },
93
+ ];
94
+ const uid = randomUUID();
95
+ await tryIt(at, 'V53: tar.br with <uid>/dist/index.wasm (base64 text), full CLI shape', {
96
+ name: 'Essential Upsell Test Online',
97
+ handle: '',
98
+ modules: [{
99
+ type: 'function',
100
+ handle: 'discounts',
101
+ uid,
102
+ assets: uid,
103
+ target: '',
104
+ config: {
105
+ title: 'Discounts',
106
+ module_id: randomUUID(),
107
+ description: 'Discount function',
108
+ app_key: '3384e849dbc1e2588cb63240b79907d3',
109
+ api_version: '2026-04',
110
+ enable_creation_ui: true,
111
+ targets,
112
+ },
113
+ }],
114
+ }, {
115
+ [`${uid}/dist/index.wasm`]: fnWasmB64,
116
+ });
117
+ }
118
+ main().catch((e) => { console.error(e); process.exit(1); });
119
+ //# sourceMappingURL=_probeSourceUrl.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"_probeSourceUrl.js","sourceRoot":"","sources":["../../src/scripts/_probeSourceUrl.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,3 @@
1
+ #!/usr/bin/env node
2
+ export {};
3
+ //# sourceMappingURL=addStore.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"addStore.d.ts","sourceRoot":"","sources":["../../src/scripts/addStore.ts"],"names":[],"mappings":""}
@@ -0,0 +1,46 @@
1
+ #!/usr/bin/env node
2
+ import { parseArgs } from 'node:util';
3
+ import { loadEnv, printEnvSummary, appendStore, readRegistry, } from '@essential-apps/shopify-test-core';
4
+ async function main() {
5
+ const { values } = parseArgs({
6
+ options: {
7
+ shop: { type: 'string' },
8
+ plan: { type: 'string' },
9
+ },
10
+ });
11
+ const shop = values.shop?.trim();
12
+ if (!shop) {
13
+ console.error('Usage: npm run test:online:add -- --shop online-1.myshopify.com [--plan UNLIMITED_APP_DEVELOPMENT]');
14
+ process.exit(1);
15
+ }
16
+ if (!/^[a-z0-9-]+\.myshopify\.com$/.test(shop)) {
17
+ console.error(`Invalid shop format. Expected "<slug>.myshopify.com", got "${shop}".`);
18
+ process.exit(1);
19
+ }
20
+ const env = loadEnv();
21
+ printEnvSummary(env);
22
+ const reg = readRegistry();
23
+ if (reg.stores.some((s) => s.shop === shop)) {
24
+ console.error(`Already in registry: ${shop}`);
25
+ process.exit(1);
26
+ }
27
+ const slug = shop.replace('.myshopify.com', '');
28
+ appendStore({
29
+ shop,
30
+ slug,
31
+ plan: values.plan ?? env.plan,
32
+ createdAt: new Date().toISOString(),
33
+ appInstalled: false,
34
+ status: 'available',
35
+ });
36
+ console.log(`✓ Added ${shop} to pool.`);
37
+ console.log('');
38
+ console.log('Next: install the dev app on this store.');
39
+ console.log(` Make sure your dev server is running, then:`);
40
+ console.log(` npm run test:online:install -- --shop ${shop}`);
41
+ }
42
+ main().catch((err) => {
43
+ console.error(err);
44
+ process.exit(1);
45
+ });
46
+ //# sourceMappingURL=addStore.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"addStore.js","sourceRoot":"","sources":["../../src/scripts/addStore.ts"],"names":[],"mappings":";AACA,OAAO,EAAE,SAAS,EAAE,MAAM,WAAW,CAAC;AACtC,OAAO,EACL,OAAO,EACP,eAAe,EACf,WAAW,EACX,YAAY,GACb,MAAM,mCAAmC,CAAC;AAE3C,KAAK,UAAU,IAAI;IACjB,MAAM,EAAE,MAAM,EAAE,GAAG,SAAS,CAAC;QAC3B,OAAO,EAAE;YACP,IAAI,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE;YACxB,IAAI,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE;SACzB;KACF,CAAC,CAAC;IAEH,MAAM,IAAI,GAAG,MAAM,CAAC,IAAI,EAAE,IAAI,EAAE,CAAC;IACjC,IAAI,CAAC,IAAI,EAAE,CAAC;QACV,OAAO,CAAC,KAAK,CACX,oGAAoG,CACrG,CAAC;QACF,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;IACD,IAAI,CAAC,8BAA8B,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC;QAC/C,OAAO,CAAC,KAAK,CAAC,8DAA8D,IAAI,IAAI,CAAC,CAAC;QACtF,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;IAED,MAAM,GAAG,GAAG,OAAO,EAAE,CAAC;IACtB,eAAe,CAAC,GAAG,CAAC,CAAC;IAErB,MAAM,GAAG,GAAG,YAAY,EAAE,CAAC;IAC3B,IAAI,GAAG,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,IAAI,CAAC,EAAE,CAAC;QAC5C,OAAO,CAAC,KAAK,CAAC,wBAAwB,IAAI,EAAE,CAAC,CAAC;QAC9C,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;IAED,MAAM,IAAI,GAAG,IAAI,CAAC,OAAO,CAAC,gBAAgB,EAAE,EAAE,CAAC,CAAC;IAChD,WAAW,CAAC;QACV,IAAI;QACJ,IAAI;QACJ,IAAI,EAAE,MAAM,CAAC,IAAI,IAAI,GAAG,CAAC,IAAI;QAC7B,SAAS,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;QACnC,YAAY,EAAE,KAAK;QACnB,MAAM,EAAE,WAAW;KACpB,CAAC,CAAC;IAEH,OAAO,CAAC,GAAG,CAAC,WAAW,IAAI,WAAW,CAAC,CAAC;IACxC,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;IAChB,OAAO,CAAC,GAAG,CAAC,0CAA0C,CAAC,CAAC;IACxD,OAAO,CAAC,GAAG,CAAC,+CAA+C,CAAC,CAAC;IAC7D,OAAO,CAAC,GAAG,CAAC,6CAA6C,IAAI,EAAE,CAAC,CAAC;AACnE,CAAC;AAED,IAAI,EAAE,CAAC,KAAK,CAAC,CAAC,GAAG,EAAE,EAAE;IACnB,OAAO,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;IACnB,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AAClB,CAAC,CAAC,CAAC"}
@@ -0,0 +1,3 @@
1
+ #!/usr/bin/env node
2
+ export {};
3
+ //# sourceMappingURL=buildDockerImage.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"buildDockerImage.d.ts","sourceRoot":"","sources":["../../src/scripts/buildDockerImage.ts"],"names":[],"mappings":""}
@@ -0,0 +1,60 @@
1
+ #!/usr/bin/env node
2
+ /**
3
+ * Build the canonical `shopify-test` image from the Dockerfile
4
+ * bundled in this package. Run from the shopify-test workspace
5
+ * root:
6
+ *
7
+ * npm run docker:build
8
+ *
9
+ * Or directly:
10
+ *
11
+ * node --import tsx packages/runner/src/scripts/buildDockerImage.ts
12
+ *
13
+ * The image is amd64-only (Rosetta on Apple Silicon) — see
14
+ * docker/README.md for why.
15
+ */
16
+ import { spawn } from 'node:child_process';
17
+ import { existsSync } from 'node:fs';
18
+ import { dirname, resolve } from 'node:path';
19
+ import { fileURLToPath } from 'node:url';
20
+ // Mirrors the npm scope (`@essential-apps/shopify-test`) so anyone
21
+ // inspecting `container images` sees the same name they `npm install`.
22
+ const DEFAULT_TAG = 'essential-apps/shopify-test:latest';
23
+ function dockerContextDir() {
24
+ // This file lives at packages/runner/src/scripts/ (or dist/scripts/
25
+ // after build). Walk up + sideways to docker/.
26
+ const here = dirname(fileURLToPath(import.meta.url));
27
+ // here = .../packages/runner/{src,dist}/scripts
28
+ const candidates = [
29
+ resolve(here, '../../docker'),
30
+ resolve(here, '../docker'),
31
+ ];
32
+ for (const c of candidates) {
33
+ if (existsSync(resolve(c, 'Dockerfile')))
34
+ return c;
35
+ }
36
+ throw new Error(`Could not locate the Dockerfile under packages/runner/docker/. ` +
37
+ `Tried: ${candidates.join(', ')}`);
38
+ }
39
+ async function main() {
40
+ const tag = process.env['SHOPIFY_TEST_IMAGE_TAG'] ?? DEFAULT_TAG;
41
+ const context = dockerContextDir();
42
+ console.log('────────────────────────────────────────────────────────────');
43
+ console.log(' shopify-test docker image build');
44
+ console.log('────────────────────────────────────────────────────────────');
45
+ console.log(` Tag : ${tag}`);
46
+ console.log(` Context : ${context}`);
47
+ console.log(` Arch : amd64`);
48
+ console.log('────────────────────────────────────────────────────────────');
49
+ console.log('');
50
+ const args = ['build', '--arch', 'amd64', '--tag', tag, context];
51
+ const p = spawn('container', args, { stdio: 'inherit' });
52
+ p.on('exit', (code) => process.exit(code ?? 0));
53
+ process.on('SIGINT', () => p.kill('SIGINT'));
54
+ process.on('SIGTERM', () => p.kill('SIGTERM'));
55
+ }
56
+ main().catch((err) => {
57
+ console.error(err);
58
+ process.exit(1);
59
+ });
60
+ //# sourceMappingURL=buildDockerImage.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"buildDockerImage.js","sourceRoot":"","sources":["../../src/scripts/buildDockerImage.ts"],"names":[],"mappings":";AACA;;;;;;;;;;;;;GAaG;AACH,OAAO,EAAE,KAAK,EAAE,MAAM,oBAAoB,CAAC;AAC3C,OAAO,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;AACrC,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAC7C,OAAO,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AAEzC,mEAAmE;AACnE,uEAAuE;AACvE,MAAM,WAAW,GAAG,oCAAoC,CAAC;AAEzD,SAAS,gBAAgB;IACvB,oEAAoE;IACpE,+CAA+C;IAC/C,MAAM,IAAI,GAAG,OAAO,CAAC,aAAa,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC;IACrD,gDAAgD;IAChD,MAAM,UAAU,GAAG;QACjB,OAAO,CAAC,IAAI,EAAE,cAAc,CAAC;QAC7B,OAAO,CAAC,IAAI,EAAE,WAAW,CAAC;KAC3B,CAAC;IACF,KAAK,MAAM,CAAC,IAAI,UAAU,EAAE,CAAC;QAC3B,IAAI,UAAU,CAAC,OAAO,CAAC,CAAC,EAAE,YAAY,CAAC,CAAC;YAAE,OAAO,CAAC,CAAC;IACrD,CAAC;IACD,MAAM,IAAI,KAAK,CACb,iEAAiE;QAC/D,UAAU,UAAU,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CACpC,CAAC;AACJ,CAAC;AAED,KAAK,UAAU,IAAI;IACjB,MAAM,GAAG,GAAG,OAAO,CAAC,GAAG,CAAC,wBAAwB,CAAC,IAAI,WAAW,CAAC;IACjE,MAAM,OAAO,GAAG,gBAAgB,EAAE,CAAC;IAEnC,OAAO,CAAC,GAAG,CAAC,8DAA8D,CAAC,CAAC;IAC5E,OAAO,CAAC,GAAG,CAAC,kCAAkC,CAAC,CAAC;IAChD,OAAO,CAAC,GAAG,CAAC,8DAA8D,CAAC,CAAC;IAC5E,OAAO,CAAC,GAAG,CAAC,gBAAgB,GAAG,EAAE,CAAC,CAAC;IACnC,OAAO,CAAC,GAAG,CAAC,gBAAgB,OAAO,EAAE,CAAC,CAAC;IACvC,OAAO,CAAC,GAAG,CAAC,oBAAoB,CAAC,CAAC;IAClC,OAAO,CAAC,GAAG,CAAC,8DAA8D,CAAC,CAAC;IAC5E,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;IAEhB,MAAM,IAAI,GAAG,CAAC,OAAO,EAAE,QAAQ,EAAE,OAAO,EAAE,OAAO,EAAE,GAAG,EAAE,OAAO,CAAC,CAAC;IACjE,MAAM,CAAC,GAAG,KAAK,CAAC,WAAW,EAAE,IAAI,EAAE,EAAE,KAAK,EAAE,SAAS,EAAE,CAAC,CAAC;IACzD,CAAC,CAAC,EAAE,CAAC,MAAM,EAAE,CAAC,IAAI,EAAE,EAAE,CAAC,OAAO,CAAC,IAAI,CAAC,IAAI,IAAI,CAAC,CAAC,CAAC,CAAC;IAChD,OAAO,CAAC,EAAE,CAAC,QAAQ,EAAE,GAAG,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAC;IAC7C,OAAO,CAAC,EAAE,CAAC,SAAS,EAAE,GAAG,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC;AACjD,CAAC;AAED,IAAI,EAAE,CAAC,KAAK,CAAC,CAAC,GAAG,EAAE,EAAE;IACnB,OAAO,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;IACnB,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AAClB,CAAC,CAAC,CAAC"}
@@ -0,0 +1,3 @@
1
+ #!/usr/bin/env node
2
+ export {};
3
+ //# sourceMappingURL=captureAuth.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"captureAuth.d.ts","sourceRoot":"","sources":["../../src/scripts/captureAuth.ts"],"names":[],"mappings":""}