@walkeros/cli 0.4.1 → 0.4.2

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 (194) hide show
  1. package/CHANGELOG.md +13 -0
  2. package/README.md +112 -42
  3. package/dist/__tests__/bundle/bundler.test.js +174 -164
  4. package/dist/__tests__/bundle/bundler.test.js.map +1 -1
  5. package/dist/__tests__/bundle/programmatic.test.js +76 -53
  6. package/dist/__tests__/bundle/programmatic.test.js.map +1 -1
  7. package/dist/__tests__/cli.test.js +58 -46
  8. package/dist/__tests__/cli.test.js.map +1 -1
  9. package/dist/__tests__/config-loader.test.d.ts +1 -1
  10. package/dist/__tests__/config-loader.test.js +231 -212
  11. package/dist/__tests__/config-loader.test.js.map +1 -1
  12. package/dist/__tests__/core/build-cache.test.d.ts +2 -0
  13. package/dist/__tests__/core/build-cache.test.d.ts.map +1 -0
  14. package/dist/__tests__/core/build-cache.test.js +55 -0
  15. package/dist/__tests__/core/build-cache.test.js.map +1 -0
  16. package/dist/__tests__/core/cache-utils.test.d.ts +2 -0
  17. package/dist/__tests__/core/cache-utils.test.d.ts.map +1 -0
  18. package/dist/__tests__/core/cache-utils.test.js +70 -0
  19. package/dist/__tests__/core/cache-utils.test.js.map +1 -0
  20. package/dist/__tests__/integration/bundle-run.integration.test.js +8 -4
  21. package/dist/__tests__/integration/bundle-run.integration.test.js.map +1 -1
  22. package/dist/__tests__/simulate/node-executor.test.d.ts +5 -0
  23. package/dist/__tests__/simulate/node-executor.test.d.ts.map +1 -0
  24. package/dist/__tests__/simulate/node-executor.test.js +25 -0
  25. package/dist/__tests__/simulate/node-executor.test.js.map +1 -0
  26. package/dist/__tests__/simulate/server-simulate.integration.test.d.ts +5 -0
  27. package/dist/__tests__/simulate/server-simulate.integration.test.d.ts.map +1 -0
  28. package/dist/__tests__/simulate/server-simulate.integration.test.js +59 -0
  29. package/dist/__tests__/simulate/server-simulate.integration.test.js.map +1 -0
  30. package/dist/__tests__/smoke/production.smoke.test.js +9 -2
  31. package/dist/__tests__/smoke/production.smoke.test.js.map +1 -1
  32. package/dist/commands/bundle/bundler.d.ts.map +1 -1
  33. package/dist/commands/bundle/bundler.js +93 -3
  34. package/dist/commands/bundle/bundler.js.map +1 -1
  35. package/dist/commands/bundle/index.d.ts +16 -10
  36. package/dist/commands/bundle/index.d.ts.map +1 -1
  37. package/dist/commands/bundle/index.js +44 -32
  38. package/dist/commands/bundle/index.js.map +1 -1
  39. package/dist/commands/bundle/package-manager.d.ts +2 -1
  40. package/dist/commands/bundle/package-manager.d.ts.map +1 -1
  41. package/dist/commands/bundle/package-manager.js +34 -7
  42. package/dist/commands/bundle/package-manager.js.map +1 -1
  43. package/dist/commands/cache.d.ts +3 -0
  44. package/dist/commands/cache.d.ts.map +1 -0
  45. package/dist/commands/cache.js +44 -0
  46. package/dist/commands/cache.js.map +1 -0
  47. package/dist/commands/push/index.d.ts.map +1 -1
  48. package/dist/commands/push/index.js +49 -44
  49. package/dist/commands/push/index.js.map +1 -1
  50. package/dist/commands/push/types.d.ts +1 -1
  51. package/dist/commands/push/types.d.ts.map +1 -1
  52. package/dist/commands/run/__tests__/run.integration.test.js +14 -15
  53. package/dist/commands/run/__tests__/run.integration.test.js.map +1 -1
  54. package/dist/commands/run/utils.d.ts +4 -1
  55. package/dist/commands/run/utils.d.ts.map +1 -1
  56. package/dist/commands/run/utils.js +18 -24
  57. package/dist/commands/run/utils.js.map +1 -1
  58. package/dist/commands/run/validators.d.ts +9 -5
  59. package/dist/commands/run/validators.d.ts.map +1 -1
  60. package/dist/commands/run/validators.js +14 -11
  61. package/dist/commands/run/validators.js.map +1 -1
  62. package/dist/commands/simulate/index.d.ts +1 -0
  63. package/dist/commands/simulate/index.d.ts.map +1 -1
  64. package/dist/commands/simulate/index.js +1 -0
  65. package/dist/commands/simulate/index.js.map +1 -1
  66. package/dist/commands/simulate/node-executor.d.ts +28 -0
  67. package/dist/commands/simulate/node-executor.d.ts.map +1 -0
  68. package/dist/commands/simulate/node-executor.js +94 -0
  69. package/dist/commands/simulate/node-executor.js.map +1 -0
  70. package/dist/commands/simulate/simulator.d.ts.map +1 -1
  71. package/dist/commands/simulate/simulator.js +36 -32
  72. package/dist/commands/simulate/simulator.js.map +1 -1
  73. package/dist/config/build-defaults.d.ts +49 -0
  74. package/dist/config/build-defaults.d.ts.map +1 -0
  75. package/dist/config/build-defaults.js +72 -0
  76. package/dist/config/build-defaults.js.map +1 -0
  77. package/dist/config/index.d.ts +6 -7
  78. package/dist/config/index.d.ts.map +1 -1
  79. package/dist/config/index.js +6 -7
  80. package/dist/config/index.js.map +1 -1
  81. package/dist/config/loader.d.ts +34 -27
  82. package/dist/config/loader.d.ts.map +1 -1
  83. package/dist/config/loader.js +107 -92
  84. package/dist/config/loader.js.map +1 -1
  85. package/dist/config/validators.d.ts +34 -8
  86. package/dist/config/validators.d.ts.map +1 -1
  87. package/dist/config/validators.js +59 -21
  88. package/dist/config/validators.js.map +1 -1
  89. package/dist/core/asset-resolver.d.ts +8 -15
  90. package/dist/core/asset-resolver.d.ts.map +1 -1
  91. package/dist/core/asset-resolver.js +30 -37
  92. package/dist/core/asset-resolver.js.map +1 -1
  93. package/dist/core/build-cache.d.ts +23 -0
  94. package/dist/core/build-cache.d.ts.map +1 -0
  95. package/dist/core/build-cache.js +43 -0
  96. package/dist/core/build-cache.js.map +1 -0
  97. package/dist/core/cache-utils.d.ts +27 -0
  98. package/dist/core/cache-utils.d.ts.map +1 -0
  99. package/dist/core/cache-utils.js +60 -0
  100. package/dist/core/cache-utils.js.map +1 -0
  101. package/dist/core/docker.d.ts.map +1 -1
  102. package/dist/core/docker.js +8 -25
  103. package/dist/core/docker.js.map +1 -1
  104. package/dist/core/index.d.ts +1 -0
  105. package/dist/core/index.d.ts.map +1 -1
  106. package/dist/core/index.js +1 -0
  107. package/dist/core/index.js.map +1 -1
  108. package/dist/core/local-packages.d.ts +19 -0
  109. package/dist/core/local-packages.d.ts.map +1 -0
  110. package/dist/core/local-packages.js +60 -0
  111. package/dist/core/local-packages.js.map +1 -0
  112. package/dist/examples/.npm-cache/content-v2/sha512/0d/2d/7581c288670eaf8538ddd9df145b78756ce3be0791c6e0b9cd33429b3bae894525b9bda287a3cedffbcdd2c7b3107bafc03f2b0367eea489eee1cc042abb +1 -0
  113. package/dist/examples/.npm-cache/content-v2/sha512/12/20/bc4f5acca143809f7e07da1fdafb38137d93243de4d5b403e6e10b92d0d3a6e51eab24fe9dbc9d3ed1cd72e8f7a406085e99c422bb2c7d1166cf9f1f564e +0 -0
  114. package/dist/examples/.npm-cache/content-v2/sha512/22/ee/fb2695b01871c1d36946bdcfb49f1b520a57200d0a0b221b1e7d5f047ab38a8b2ab0e5f0e25a00acde1f3f2f9d24430a18f1092d438bc1a9e9891cc45f75 +0 -0
  115. package/dist/examples/.npm-cache/content-v2/sha512/24/89/da1ce6a61bca6de7e132f241a675c01c83738bf6b78af25b5cce01d3030361332b3fe938571e2b721f1555da9ddf930fdcf8c02f0471556071590e68cc09 +0 -0
  116. package/dist/examples/.npm-cache/content-v2/sha512/47/fd/c6be997da99228c3e279b95d4a46d6913947078a178f54ac71795a159f3513b1483232f4c2d0a1f403178bf9f96bb19615de32a9e2133e949880c6bc15e2 +0 -0
  117. package/dist/examples/.npm-cache/content-v2/sha512/4b/1c/c1cb7f8b32102071a89fef97158daa32080ebaedfbbd596880d2213d84e305abc76d2a95a412ded55c1c3d487adcb1ceff87fc2c85d7e2856ebd9d3f16f3 +0 -0
  118. package/dist/examples/.npm-cache/content-v2/sha512/6e/53/ff864769671f44f39d8a3bf904cd646535b745cc4824a8bb3189193b474678049f43b5178ba15cad7f0289046105e70f1565afc84e907120b35a466690fd +1 -0
  119. package/dist/examples/.npm-cache/content-v2/sha512/70/4c/4c8837d446965c5551b4ea527e95fa011744fb727581d82cf35bb5599ea0b57d18baa490f7af93ef9a16e8e45e5c0802737da20575f4056a4a5c9a3cd288 +0 -0
  120. package/dist/examples/.npm-cache/content-v2/sha512/96/ad/05de3bbb12d7de8ea353f962bdaea7d2eb44f707f2973462a6635daf537c67b46cca7764fed7d464fe62152c3f783a07aba1ceb35e09ad446bff05a4b466 +1 -0
  121. package/dist/examples/.npm-cache/content-v2/sha512/b5/20/52dde94e6cef7170f6089c64a4843e57be18be450d956f4e455905aed047ae6a368451c93035e6ac3ee59576b600f03f815afba0836b3a16e10a9aaca4ba +1 -0
  122. package/dist/examples/.npm-cache/content-v2/sha512/c7/a9/d166a1c39f97df312c59261319ba1cf9aac178bda0a0cb697d5ddd78bd8dd38ef1bf40017bcc8633c2049896c2d70696d9bff9280851f270792ff38bb3a0 +1 -0
  123. package/dist/examples/.npm-cache/content-v2/sha512/e0/d0/8c14083b633e6adbd3c6a93da5fc0f6bbd456c5512ef276920bedd8d85d551052adff992de977aff326616a211aaa2d6ddcc801149e9b7f914f566359b6a +1 -0
  124. package/dist/examples/.npm-cache/content-v2/sha512/e7/c5/06ad3fd79ac4f1031fe0b16ea5e54e232ca397bbcd7592c679021cbfb027276099f8c848f3f7a7691f0102ad53aa64f9141e61d729b037a678bd60440d17 +1 -0
  125. package/dist/examples/.npm-cache/content-v2/sha512/f3/28/d5d32329604ed7d471a4949105daa2cc98858cf24f45b0b97c41d0eb0d5a9fe7bf1f69c792161cc6693e4fc1b52e886ac41875ebfb8fe47fafe417ca3e6e +0 -0
  126. package/dist/examples/.npm-cache/index-v5/04/5a/2b5d7a7c407d85d746baa0f5c9388a333e35a717a8a0a81943daa6cb1364 +3 -0
  127. package/dist/examples/.npm-cache/index-v5/12/9a/eba560cbace295d8ee04cf283015377bd77b379e70968fb6bc407c7fc410 +15 -0
  128. package/dist/examples/.npm-cache/index-v5/2f/a2/7b047564b0ee21ac835ec609e89153dd6549be554d098584d5bfd19fe043 +15 -0
  129. package/dist/examples/.npm-cache/index-v5/32/8e/322d58dd8d1e000be248ada51385bf96288e56039de9feec1a4c6a467653 +3 -0
  130. package/dist/examples/.npm-cache/index-v5/57/93/d1d7cd1402e3e26468db03f2870822bb2c9018a506cdfb3b405f38cd3e1c +3 -0
  131. package/dist/examples/.npm-cache/index-v5/5d/f8/0a1f4fa7149e4ff33e09eb6aea41ac8d1730c868a5d3ace91f762698acff +3 -0
  132. package/dist/examples/.npm-cache/index-v5/69/a4/a92c72d838259b051cdf8e0acfb2bc680b6d4cfc642314a7836c3f7b2c50 +15 -0
  133. package/dist/examples/.npm-cache/index-v5/71/31/6da3423bb203f3de5eb16c942431073f89be2cfcb40058ec91dcb5ce0abc +15 -0
  134. package/dist/examples/.npm-cache/index-v5/7b/94/72b6bffa050d9ef52a558dd220663695bc606f756be0dfa196ef4f3913ba +3 -0
  135. package/dist/examples/.npm-cache/index-v5/85/9e/99e97fdd562517e56285337db91d1a8f2f416b8d631cf4d7d754fa671299 +15 -0
  136. package/dist/examples/.npm-cache/index-v5/92/4c/9416ada81a9b3c679539fd1ab53f8de3d41ff268f35eba7a194389a85b06 +3 -0
  137. package/dist/examples/.npm-cache/index-v5/c1/5a/13df76b218deed8a6ef12961116af5183db98c53fad1b922fd9edc075247 +3 -0
  138. package/dist/examples/.npm-cache/index-v5/cb/11/253c55410a8ab7c4a9ea9d6e1bf8ef1450a581da64c478074dfd82c8bff6 +3 -0
  139. package/dist/examples/.npm-cache/index-v5/d5/ae/b57fad3a62b5ba2dbdf24b042a9e7b70820f3db00e5a630f02e1fea020dc +3 -0
  140. package/dist/examples/.npm-cache/index-v5/d6/32/2f620f83c7d14451de98de8298c2408e05a16cc0829bd16c891ac19d7a67 +3 -0
  141. package/dist/examples/.npm-cache/index-v5/dd/b5/01dc7a3cd8b6a03a69aee9af500d51ae19cb0aa12631a4aafd152148b8e5 +15 -0
  142. package/dist/examples/.npm-cache/index-v5/e0/cf/6b862c15d74630d3871cd813d305210ab741311deb10baf8813014e0bc30 +3 -0
  143. package/dist/examples/.npm-cache/index-v5/e2/be/e880ccd35950a814d3c1dded34d3938ac61b15a195321dc51357f801aad4 +15 -0
  144. package/dist/examples/.npm-cache/index-v5/e5/1f/f4affe0b392cd03288f23cc03abcb274ff11a2c8f8965299de681914abb2 +3 -0
  145. package/dist/examples/.npm-cache/index-v5/f3/5b/9ebe450958ff0d7cc44ab0a00080cb8a3ff1389744b5eab5f97b68a6a6af +3 -0
  146. package/dist/examples/.npm-cache/index-v5/fb/c1/0de405e902866d53e7c30cf36a97dc2578838622b261816f44dc377c9a80 +3 -0
  147. package/dist/examples/README.md +343 -0
  148. package/dist/examples/event.json +53 -0
  149. package/dist/examples/flow-order-complete.json +68 -0
  150. package/dist/examples/flow-simple.json +32 -0
  151. package/dist/examples/flow.json +82 -0
  152. package/dist/examples/server-collect.json +60 -0
  153. package/dist/examples/server-collect.mjs +13540 -0
  154. package/dist/examples/test.html +43 -0
  155. package/dist/examples/web-serve.js +25503 -0
  156. package/dist/examples/web-serve.json +74 -0
  157. package/dist/index.d.ts +84 -201
  158. package/dist/index.d.ts.map +1 -1
  159. package/dist/index.js +675 -422
  160. package/dist/index.js.map +1 -1
  161. package/dist/schemas/index.d.ts +9 -0
  162. package/dist/schemas/index.d.ts.map +1 -0
  163. package/dist/schemas/index.js +9 -0
  164. package/dist/schemas/index.js.map +1 -0
  165. package/dist/schemas/primitives.d.ts +37 -0
  166. package/dist/schemas/primitives.d.ts.map +1 -0
  167. package/dist/schemas/primitives.js +43 -0
  168. package/dist/schemas/primitives.js.map +1 -0
  169. package/dist/schemas/run.d.ts +23 -0
  170. package/dist/schemas/run.d.ts.map +1 -0
  171. package/dist/schemas/run.js +20 -0
  172. package/dist/schemas/run.js.map +1 -0
  173. package/dist/templates/server.hbs +29 -0
  174. package/dist/templates/web.hbs +45 -0
  175. package/dist/types/bundle.d.ts +68 -190
  176. package/dist/types/bundle.d.ts.map +1 -1
  177. package/dist/types/bundle.js +2 -2
  178. package/dist/walker.js +1 -0
  179. package/examples/README.md +42 -29
  180. package/examples/flow-order-complete.json +57 -57
  181. package/examples/flow-simple.json +25 -25
  182. package/examples/flow.json +69 -69
  183. package/examples/server-collect.json +51 -44
  184. package/examples/server-collect.mjs +1 -1
  185. package/examples/web-serve.json +62 -63
  186. package/package.json +2 -2
  187. package/dist/config/defaults.d.ts +0 -33
  188. package/dist/config/defaults.d.ts.map +0 -1
  189. package/dist/config/defaults.js +0 -69
  190. package/dist/config/defaults.js.map +0 -1
  191. package/dist/config/parser.d.ts +0 -128
  192. package/dist/config/parser.d.ts.map +0 -1
  193. package/dist/config/parser.js +0 -256
  194. package/dist/config/parser.js.map +0 -1
@@ -1,55 +1,55 @@
1
1
  /**
2
2
  * Config Loader Tests
3
3
  *
4
- * Tests for multi-environment configuration loading.
4
+ * Tests for Flow.Setup configuration loading with the new format.
5
5
  */
6
- import { loadBundleConfig, loadAllEnvironments, getAvailableEnvironments, } from '../config/index.js';
6
+ import { loadBundleConfig, loadAllFlows, getAvailableFlows, } from '../config/index.js';
7
7
  describe('Config Loader', () => {
8
8
  // ========================================
9
- // Single Environment Tests
9
+ // Single Flow (Flow.Setup with one flow)
10
10
  // ========================================
11
- describe('Single Environment Config', () => {
12
- test('loads single-environment config successfully', () => {
11
+ describe('Single Flow (Flow.Setup)', () => {
12
+ test('loads Flow.Setup with single flow automatically', () => {
13
13
  const config = {
14
- flow: {
15
- platform: 'web',
16
- sources: {
17
- browser: {
18
- package: '@walkeros/web-source-browser',
14
+ version: 1,
15
+ flows: {
16
+ default: {
17
+ web: {},
18
+ packages: {
19
+ '@walkeros/core': { imports: ['getId'] },
19
20
  },
20
- },
21
- destinations: {
22
- gtag: {
23
- package: '@walkeros/web-destination-gtag',
24
- config: {
25
- settings: { ga4: { measurementId: 'G-123' } },
21
+ sources: {
22
+ browser: {
23
+ package: '@walkeros/web-source-browser',
24
+ },
25
+ },
26
+ destinations: {
27
+ gtag: {
28
+ package: '@walkeros/web-destination-gtag',
29
+ config: {
30
+ settings: { ga4: { measurementId: 'G-123' } },
31
+ },
26
32
  },
27
33
  },
28
34
  },
29
35
  },
30
- build: {
31
- packages: {},
32
- code: 'export {};',
33
- output: './dist/test.js',
34
- },
35
36
  };
36
37
  const result = loadBundleConfig(config, {
37
38
  configPath: '/test/config.json',
38
39
  });
39
- expect(result.environment).toBe('default');
40
- expect(result.isMultiEnvironment).toBe(false);
41
- expect(result.flowConfig.platform).toBe('web');
40
+ expect(result.flowName).toBe('default');
41
+ expect(result.isMultiFlow).toBe(false);
42
+ expect(result.flowConfig.web).toBeDefined();
42
43
  expect(result.flowConfig.sources).toBeDefined();
43
44
  });
44
45
  test('applies platform-specific defaults for web', () => {
45
46
  const config = {
46
- flow: {
47
- platform: 'web',
48
- },
49
- build: {
50
- packages: {},
51
- code: 'export {};',
52
- output: '',
47
+ version: 1,
48
+ flows: {
49
+ default: {
50
+ web: {},
51
+ packages: {},
52
+ },
53
53
  },
54
54
  };
55
55
  const result = loadBundleConfig(config, {
@@ -58,18 +58,19 @@ describe('Config Loader', () => {
58
58
  expect(result.buildOptions.platform).toBe('browser');
59
59
  expect(result.buildOptions.format).toBe('iife');
60
60
  expect(result.buildOptions.target).toBe('es2020');
61
+ expect(result.buildOptions.minify).toBe(true);
62
+ expect(result.buildOptions.template).toBe('web.hbs');
61
63
  // Output path is resolved relative to config file directory
62
64
  expect(result.buildOptions.output).toBe('/test/dist/walker.js');
63
65
  });
64
66
  test('applies platform-specific defaults for server', () => {
65
67
  const config = {
66
- flow: {
67
- platform: 'server',
68
- },
69
- build: {
70
- packages: {},
71
- code: 'export {};',
72
- output: '',
68
+ version: 1,
69
+ flows: {
70
+ default: {
71
+ server: {},
72
+ packages: {},
73
+ },
73
74
  },
74
75
  };
75
76
  const result = loadBundleConfig(config, {
@@ -78,266 +79,266 @@ describe('Config Loader', () => {
78
79
  expect(result.buildOptions.platform).toBe('node');
79
80
  expect(result.buildOptions.format).toBe('esm');
80
81
  expect(result.buildOptions.target).toBe('node20');
82
+ expect(result.buildOptions.minify).toBe(true);
83
+ expect(result.buildOptions.template).toBe('server.hbs');
81
84
  // Output path is resolved relative to config file directory
82
- expect(result.buildOptions.output).toBe('/test/dist/bundle.js');
85
+ expect(result.buildOptions.output).toBe('/test/dist/bundle.mjs');
83
86
  });
84
- test('merges custom build options with defaults', () => {
87
+ test('extracts packages from flowConfig', () => {
85
88
  const config = {
86
- flow: {
87
- platform: 'web',
88
- },
89
- build: {
90
- packages: {},
91
- code: 'export {};',
92
- output: '',
93
- minify: true,
94
- format: 'esm',
89
+ version: 1,
90
+ flows: {
91
+ default: {
92
+ web: {},
93
+ packages: {
94
+ '@walkeros/core': { imports: ['getId', 'clone'] },
95
+ '@walkeros/destination-demo': { imports: ['destinationDemo'] },
96
+ },
97
+ },
95
98
  },
96
99
  };
97
100
  const result = loadBundleConfig(config, {
98
101
  configPath: '/test/config.json',
99
102
  });
100
- expect(result.buildOptions.minify).toBe(true);
101
- expect(result.buildOptions.format).toBe('esm'); // Custom overrides default
102
- expect(result.buildOptions.target).toBe('es2020'); // Default preserved
103
+ expect(result.buildOptions.packages).toEqual({
104
+ '@walkeros/core': { imports: ['getId', 'clone'] },
105
+ '@walkeros/destination-demo': { imports: ['destinationDemo'] },
106
+ });
103
107
  });
104
- test('auto-selects templates based on platform', () => {
108
+ test('respects build overrides from CLI', () => {
105
109
  const config = {
106
- flow: {
107
- platform: 'web',
108
- },
109
- build: {
110
- packages: {},
111
- code: 'export {};',
112
- output: '',
110
+ version: 1,
111
+ flows: {
112
+ default: {
113
+ web: {},
114
+ packages: {},
115
+ },
113
116
  },
114
117
  };
115
118
  const result = loadBundleConfig(config, {
116
119
  configPath: '/test/config.json',
120
+ buildOverrides: {
121
+ minify: false,
122
+ output: '/custom/output.js',
123
+ },
117
124
  });
118
- // Should auto-select web.hbs for web platform
119
- expect(result.buildOptions.template).toBe('web.hbs');
125
+ expect(result.buildOptions.minify).toBe(false);
126
+ expect(result.buildOptions.output).toBe('/custom/output.js');
120
127
  });
121
128
  });
122
129
  // ========================================
123
- // Multi-Environment Tests
130
+ // Multi-Flow Tests
124
131
  // ========================================
125
- describe('Multi-Environment Config', () => {
126
- const multiEnvConfig = {
132
+ describe('Multi-Flow Config', () => {
133
+ const multiFlowConfig = {
127
134
  version: 1,
128
- environments: {
135
+ flows: {
129
136
  web_prod: {
130
- flow: {
131
- platform: 'web',
132
- sources: {
133
- browser: {
134
- package: '@walkeros/web-source-browser',
135
- },
136
- },
137
- destinations: {
138
- gtag: {
139
- package: '@walkeros/web-destination-gtag',
140
- config: { settings: { ga4: { measurementId: 'G-PROD' } } },
141
- },
137
+ web: {},
138
+ packages: {},
139
+ sources: {
140
+ browser: {
141
+ package: '@walkeros/web-source-browser',
142
142
  },
143
143
  },
144
- build: {
145
- packages: {},
146
- code: 'export {};',
147
- output: './dist/prod.js',
144
+ destinations: {
145
+ gtag: {
146
+ package: '@walkeros/web-destination-gtag',
147
+ config: { settings: { ga4: { measurementId: 'G-PROD' } } },
148
+ },
148
149
  },
149
150
  },
150
151
  web_stage: {
151
- flow: {
152
- platform: 'web',
153
- sources: {
154
- browser: {
155
- package: '@walkeros/web-source-browser',
156
- },
157
- },
158
- destinations: {
159
- gtag: {
160
- package: '@walkeros/web-destination-gtag',
161
- config: { settings: { ga4: { measurementId: 'G-STAGE' } } },
162
- },
152
+ web: {},
153
+ packages: {},
154
+ sources: {
155
+ browser: {
156
+ package: '@walkeros/web-source-browser',
163
157
  },
164
158
  },
165
- build: {
166
- packages: {},
167
- code: 'export {};',
168
- output: './dist/stage.js',
159
+ destinations: {
160
+ gtag: {
161
+ package: '@walkeros/web-destination-gtag',
162
+ config: { settings: { ga4: { measurementId: 'G-STAGE' } } },
163
+ },
169
164
  },
170
165
  },
171
166
  server_prod: {
172
- flow: {
173
- platform: 'server',
174
- destinations: {
175
- api: {
176
- package: '@walkeros/server-destination-api',
177
- },
167
+ server: {},
168
+ packages: {},
169
+ destinations: {
170
+ api: {
171
+ package: '@walkeros/server-destination-api',
178
172
  },
179
173
  },
180
- build: {
181
- packages: {},
182
- code: 'export {};',
183
- output: './dist/server.js',
184
- },
185
174
  },
186
175
  },
187
176
  };
188
- test('loads specific environment from multi-environment config', () => {
189
- const result = loadBundleConfig(multiEnvConfig, {
177
+ test('loads specific flow from multi-flow config', () => {
178
+ const result = loadBundleConfig(multiFlowConfig, {
190
179
  configPath: '/test/config.json',
191
- environment: 'web_prod',
180
+ flowName: 'web_prod',
192
181
  });
193
- expect(result.environment).toBe('web_prod');
194
- expect(result.isMultiEnvironment).toBe(true);
195
- expect(result.availableEnvironments).toEqual([
182
+ expect(result.flowName).toBe('web_prod');
183
+ expect(result.isMultiFlow).toBe(true);
184
+ expect(result.availableFlows).toEqual([
196
185
  'web_prod',
197
186
  'web_stage',
198
187
  'server_prod',
199
188
  ]);
200
- expect(result.flowConfig.platform).toBe('web');
189
+ expect(result.flowConfig.web).toBeDefined();
201
190
  });
202
- test('throws error if environment not specified for multi-env config', () => {
203
- expect(() => loadBundleConfig(multiEnvConfig, {
191
+ test('throws error if flow not specified for multi-flow config', () => {
192
+ expect(() => loadBundleConfig(multiFlowConfig, {
204
193
  configPath: '/test/config.json',
205
- })).toThrow('Please specify an environment using --env flag');
194
+ })).toThrow('Please specify a flow using --flow flag');
206
195
  });
207
- test('throws error if specified environment not found', () => {
208
- expect(() => loadBundleConfig(multiEnvConfig, {
196
+ test('throws error if specified flow not found', () => {
197
+ expect(() => loadBundleConfig(multiFlowConfig, {
209
198
  configPath: '/test/config.json',
210
- environment: 'nonexistent',
211
- })).toThrow('Environment "nonexistent" not found');
199
+ flowName: 'nonexistent',
200
+ })).toThrow('Flow "nonexistent" not found');
212
201
  });
213
- test('loads all environments', () => {
214
- const results = loadAllEnvironments(multiEnvConfig, {
202
+ test('loads all flows', () => {
203
+ const results = loadAllFlows(multiFlowConfig, {
215
204
  configPath: '/test/config.json',
216
205
  });
217
206
  expect(results).toHaveLength(3);
218
- expect(results.map((r) => r.environment)).toEqual([
207
+ expect(results.map((r) => r.flowName)).toEqual([
219
208
  'web_prod',
220
209
  'web_stage',
221
210
  'server_prod',
222
211
  ]);
223
- expect(results[0].flowConfig.platform).toBe('web');
224
- expect(results[2].flowConfig.platform).toBe('server');
212
+ expect(results[0].flowConfig.web).toBeDefined();
213
+ expect(results[2].flowConfig.server).toBeDefined();
225
214
  });
226
- test('throws error if --all used with single-environment config', () => {
227
- const singleConfig = {
228
- flow: { platform: 'web' },
229
- build: { packages: {}, code: 'export {};', output: '' },
230
- };
231
- expect(() => loadAllEnvironments(singleConfig, {
232
- configPath: '/test/config.json',
233
- })).toThrow('--all flag requires a multi-environment configuration');
234
- });
235
- test('gets available environments from multi-env config', () => {
236
- const environments = getAvailableEnvironments(multiEnvConfig);
237
- expect(environments).toEqual(['web_prod', 'web_stage', 'server_prod']);
238
- });
239
- test('returns empty array for single-env config', () => {
240
- const singleConfig = {
241
- flow: { platform: 'web' },
242
- build: { packages: {}, code: 'export {};', output: '' },
243
- };
244
- const environments = getAvailableEnvironments(singleConfig);
245
- expect(environments).toEqual([]);
215
+ test('gets available flows from multi-flow config', () => {
216
+ const flows = getAvailableFlows(multiFlowConfig);
217
+ expect(flows).toEqual(['web_prod', 'web_stage', 'server_prod']);
246
218
  });
247
219
  });
248
220
  // ========================================
249
221
  // Error Handling Tests
250
222
  // ========================================
251
223
  describe('Error Handling', () => {
252
- test('throws detailed error for invalid config format', () => {
224
+ test('throws error for invalid config format (missing version)', () => {
253
225
  const invalidConfig = {
254
- flow: {
255
- platform: 'invalid',
226
+ flows: {
227
+ default: { web: {} },
256
228
  },
257
- build: { packages: {}, code: 'export {};', output: '' },
258
229
  };
259
230
  expect(() => loadBundleConfig(invalidConfig, {
260
231
  configPath: '/test/config.json',
261
- })).toThrow('Invalid platform "invalid". Must be "web" or "server".');
232
+ })).toThrow(/Invalid configuration[\s\S]*version/);
262
233
  });
263
- test('throws error for missing required fields', () => {
264
- const invalidConfig = {};
234
+ test('throws error for invalid config format (wrong version)', () => {
235
+ const invalidConfig = {
236
+ version: 2,
237
+ flows: {
238
+ default: { web: {} },
239
+ },
240
+ };
265
241
  expect(() => loadBundleConfig(invalidConfig, {
266
242
  configPath: '/test/config.json',
267
- })).toThrow();
243
+ })).toThrow(/Invalid configuration[\s\S]*version/);
268
244
  });
269
- test('throws error for invalid version in multi-env config', () => {
245
+ test('throws error for invalid config format (missing flows)', () => {
270
246
  const invalidConfig = {
271
- version: 2,
272
- environments: {
273
- prod: {
274
- flow: { platform: 'web' },
275
- build: { packages: {}, code: 'export {};', output: '' },
247
+ version: 1,
248
+ };
249
+ expect(() => loadBundleConfig(invalidConfig, {
250
+ configPath: '/test/config.json',
251
+ })).toThrow(/Invalid configuration[\s\S]*flows/);
252
+ });
253
+ test('throws error for empty flows', () => {
254
+ const invalidConfig = {
255
+ version: 1,
256
+ flows: {},
257
+ };
258
+ expect(() => loadBundleConfig(invalidConfig, {
259
+ configPath: '/test/config.json',
260
+ })).toThrow(/at least one flow/i);
261
+ });
262
+ test('throws error for flow without web/server key', () => {
263
+ const invalidConfig = {
264
+ version: 1,
265
+ flows: {
266
+ default: {
267
+ packages: {},
276
268
  },
277
269
  },
278
270
  };
279
271
  expect(() => loadBundleConfig(invalidConfig, {
280
272
  configPath: '/test/config.json',
281
- environment: 'prod',
282
- })).toThrow();
273
+ })).toThrow(/web.*or.*server|Exactly one of/i);
274
+ });
275
+ test('returns empty array for non-Flow.Setup config', () => {
276
+ const oldFormatConfig = {
277
+ flow: { platform: 'web' },
278
+ build: { packages: {} },
279
+ };
280
+ const flows = getAvailableFlows(oldFormatConfig);
281
+ expect(flows).toEqual([]);
283
282
  });
284
283
  });
285
284
  // ========================================
286
285
  // Logger Integration Tests
287
286
  // ========================================
288
287
  describe('Logger Integration', () => {
289
- test('logs info message for multi-environment config', () => {
288
+ test('logs info message for multi-flow config', () => {
290
289
  const logger = {
291
290
  info: jest.fn(),
292
291
  warn: jest.fn(),
293
292
  };
294
293
  const config = {
295
294
  version: 1,
296
- environments: {
295
+ flows: {
297
296
  prod: {
298
- flow: { platform: 'web' },
299
- build: { packages: {}, code: 'export {};', output: '' },
297
+ web: {},
298
+ packages: {},
299
+ },
300
+ stage: {
301
+ web: {},
302
+ packages: {},
300
303
  },
301
304
  },
302
305
  };
303
306
  loadBundleConfig(config, {
304
307
  configPath: '/test/config.json',
305
- environment: 'prod',
308
+ flowName: 'prod',
306
309
  logger,
307
310
  });
308
- expect(logger.info).toHaveBeenCalledWith(expect.stringContaining('Using environment: prod'));
311
+ expect(logger.info).toHaveBeenCalledWith(expect.stringContaining('Using flow: prod'));
309
312
  });
310
- test('logs warning for ignored --env flag on single-env config', () => {
313
+ test('does not log for single-flow config', () => {
311
314
  const logger = {
312
315
  info: jest.fn(),
313
316
  warn: jest.fn(),
314
317
  };
315
318
  const config = {
316
- flow: {
317
- platform: 'web',
318
- },
319
- build: {
320
- packages: {},
321
- code: 'export {};',
322
- output: '',
319
+ version: 1,
320
+ flows: {
321
+ default: {
322
+ web: {},
323
+ packages: {},
324
+ },
323
325
  },
324
326
  };
325
327
  loadBundleConfig(config, {
326
328
  configPath: '/test/config.json',
327
- environment: 'ignored',
328
329
  logger,
329
330
  });
330
- expect(logger.warn).toHaveBeenCalledWith(expect.stringContaining('configuration is single-environment'));
331
+ // Should not log flow selection for single-flow
332
+ expect(logger.info).not.toHaveBeenCalled();
331
333
  });
332
334
  });
333
335
  // ========================================
334
336
  // Real-World Scenario Tests
335
337
  // ========================================
336
338
  describe('Real-World Scenarios', () => {
337
- test('loads complex multi-environment setup', () => {
339
+ test('loads complex multi-flow setup', () => {
338
340
  const complexConfig = {
339
341
  version: 1,
340
- $schema: 'https://walkeros.io/schema/flow/v1.json',
341
342
  variables: {
342
343
  CURRENCY: 'USD',
343
344
  },
@@ -346,51 +347,69 @@ describe('Config Loader', () => {
346
347
  page: { view: { name: 'page_view' } },
347
348
  },
348
349
  },
349
- environments: {
350
+ flows: {
350
351
  web_production: {
351
- flow: {
352
- platform: 'web',
353
- sources: {
354
- browser: {
355
- package: '@walkeros/web-source-browser@2.0.0',
356
- config: {
357
- settings: { pageview: true },
358
- },
359
- primary: true,
360
- },
352
+ web: {},
353
+ packages: {
354
+ '@walkeros/collector': { imports: ['startFlow'] },
355
+ '@walkeros/web-source-browser': { imports: ['sourceBrowser'] },
356
+ '@walkeros/web-destination-gtag': {
357
+ imports: ['destinationGtag'],
361
358
  },
362
- destinations: {
363
- gtag: {
364
- package: '@walkeros/web-destination-gtag@2.0.0',
365
- config: {
366
- settings: { ga4: { measurementId: 'G-PROD' } },
367
- },
359
+ },
360
+ sources: {
361
+ browser: {
362
+ package: '@walkeros/web-source-browser@2.0.0',
363
+ config: {
364
+ settings: { pageview: true },
368
365
  },
366
+ primary: true,
369
367
  },
370
- collector: {
371
- run: true,
372
- tagging: 1,
368
+ },
369
+ destinations: {
370
+ gtag: {
371
+ package: '@walkeros/web-destination-gtag@2.0.0',
372
+ config: {
373
+ settings: { ga4: { measurementId: 'G-PROD' } },
374
+ },
373
375
  },
374
376
  },
375
- build: {
376
- packages: {},
377
- code: 'export {};',
378
- minify: true,
379
- sourcemap: false,
380
- output: './dist/walker.min.js',
377
+ collector: {
378
+ run: true,
379
+ tagging: 1,
381
380
  },
382
381
  },
383
382
  },
384
383
  };
385
384
  const result = loadBundleConfig(complexConfig, {
386
385
  configPath: '/test/config.json',
387
- environment: 'web_production',
386
+ flowName: 'web_production',
388
387
  });
389
- expect(result.flowConfig.platform).toBe('web');
388
+ expect(result.flowConfig.web).toBeDefined();
390
389
  expect(result.flowConfig.sources?.browser?.package).toBe('@walkeros/web-source-browser@2.0.0');
391
390
  expect(result.buildOptions.minify).toBe(true);
392
- // Output path is resolved relative to config file directory
393
- expect(result.buildOptions.output).toBe('/test/dist/walker.min.js');
391
+ // Output uses convention default
392
+ expect(result.buildOptions.output).toBe('/test/dist/walker.js');
393
+ });
394
+ test('extracts windowCollector and windowElb from web config', () => {
395
+ const config = {
396
+ version: 1,
397
+ flows: {
398
+ default: {
399
+ web: {
400
+ windowCollector: 'myCollector',
401
+ windowElb: 'myElb',
402
+ },
403
+ packages: {},
404
+ },
405
+ },
406
+ };
407
+ const result = loadBundleConfig(config, {
408
+ configPath: '/test/config.json',
409
+ });
410
+ // Web config values should be in flowConfig
411
+ expect(result.flowConfig.web.windowCollector).toBe('myCollector');
412
+ expect(result.flowConfig.web.windowElb).toBe('myElb');
394
413
  });
395
414
  });
396
415
  });