@walkeros/cli 1.0.1 → 1.0.2-next-1769158278557

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.
package/CHANGELOG.md CHANGED
@@ -1,5 +1,98 @@
1
1
  # @walkeros/cli
2
2
 
3
+ ## 1.0.2-next-1769158278557
4
+
5
+ ### Patch Changes
6
+
7
+ - 2709933: Add `$code:` prefix support for inline JavaScript in flow.json
8
+
9
+ Values prefixed with `$code:` are output as raw JavaScript instead of quoted
10
+ strings in the bundled output. This enables features like `fn:` callbacks and
11
+ `condition:` predicates directly in JSON configuration files.
12
+
13
+ Example:
14
+
15
+ ```json
16
+ { "fn": "$code:(value) => value.toUpperCase()" }
17
+ ```
18
+
19
+ Outputs:
20
+
21
+ ```javascript
22
+ {
23
+ fn: (value) => value.toUpperCase();
24
+ }
25
+ ```
26
+
27
+ - 04469bb: Auto-detect default export for sources and destinations
28
+
29
+ Sources and destinations now automatically use their package's default export,
30
+ eliminating the need to specify `imports` for the main function.
31
+
32
+ Before (verbose):
33
+
34
+ ```json
35
+ "@walkeros/web-source-browser": { "imports": ["sourceBrowser"] }
36
+ ```
37
+
38
+ After (simpler):
39
+
40
+ ```json
41
+ "@walkeros/web-source-browser": {}
42
+ ```
43
+
44
+ The `imports` field is now only needed for utility functions. Explicit `code`
45
+ still works for packages without default exports.
46
+
47
+ - 544a79e: Implicit collector: auto-add @walkeros/collector when
48
+ sources/destinations exist
49
+
50
+ The CLI now automatically adds `@walkeros/collector` and imports `startFlow`
51
+ when your flow has sources or destinations. No need to declare the collector
52
+ package.
53
+
54
+ Before (verbose):
55
+
56
+ ```json
57
+ "packages": {
58
+ "@walkeros/collector": { "imports": ["startFlow"] },
59
+ "@walkeros/web-source-browser": {},
60
+ "@walkeros/destination-demo": {}
61
+ }
62
+ ```
63
+
64
+ After (simpler):
65
+
66
+ ```json
67
+ "packages": {
68
+ "@walkeros/web-source-browser": {},
69
+ "@walkeros/destination-demo": {}
70
+ }
71
+ ```
72
+
73
+ You only need to specify `@walkeros/collector` when you want to pin a specific
74
+ version or use a local path for development.
75
+
76
+ - 4da2ef3: Fix CLI commands hanging after completion
77
+
78
+ Commands (`bundle`, `simulate`, `push`) would hang indefinitely after
79
+ completing successfully due to open handles keeping the Node.js event loop
80
+ alive.
81
+
82
+ Root cause: esbuild worker threads and pacote HTTP keep-alive connections were
83
+ not being cleaned up.
84
+
85
+ Fixes:
86
+ - Add `esbuild.stop()` after builds to terminate worker threads
87
+ - Add explicit `process.exit(0)` on successful completion for all CLI commands
88
+
89
+ - 2f82a2e: Fix simulate command JSON output to use consistent `result` property
90
+ instead of `elbResult`
91
+ - Updated dependencies [b65b773]
92
+ - Updated dependencies [20eca6e]
93
+ - @walkeros/core@1.0.1-next-1769158278557
94
+ - @walkeros/server-core@1.0.1-next-1769158278557
95
+
3
96
  ## 1.0.1
4
97
 
5
98
  ### Patch Changes
@@ -4,8 +4,8 @@
4
4
  "variables": {
5
5
  "currency": "EUR",
6
6
  "flowVersion": "1.0.0",
7
- "ga4MeasurementId": "${GA4_MEASUREMENT_ID:G-DEMO123456}",
8
- "apiUrl": "${API_URL:http://localhost:8080/collect}"
7
+ "ga4MeasurementId": "$env.GA4_MEASUREMENT_ID:G-DEMO123456",
8
+ "apiUrl": "$env.API_URL:http://localhost:8080/collect"
9
9
  },
10
10
  "definitions": {
11
11
  "ga4ItemsLoop": {
@@ -212,7 +212,7 @@
212
212
  "config": {
213
213
  "consent": { "marketing": true },
214
214
  "settings": {
215
- "ga4": { "measurementId": "$variables.ga4MeasurementId" }
215
+ "ga4": { "measurementId": "$var.ga4MeasurementId" }
216
216
  },
217
217
  "mapping": {
218
218
  "page": {
@@ -233,7 +233,7 @@
233
233
  "map": {
234
234
  "currency": {
235
235
  "key": "data.currency",
236
- "value": "$variables.currency"
236
+ "value": "$var.currency"
237
237
  },
238
238
  "value": "data.price",
239
239
  "items": {
@@ -258,7 +258,7 @@
258
258
  "map": {
259
259
  "currency": {
260
260
  "key": "data.currency",
261
- "value": "$variables.currency"
261
+ "value": "$var.currency"
262
262
  },
263
263
  "value": "data.price",
264
264
  "items": {
@@ -286,11 +286,11 @@
286
286
  "value": "data.total",
287
287
  "currency": {
288
288
  "key": "data.currency",
289
- "value": "$variables.currency"
289
+ "value": "$var.currency"
290
290
  },
291
291
  "tax": "data.tax",
292
292
  "shipping": "data.shipping",
293
- "items": { "$ref": "#/definitions/ga4ItemsLoop" }
293
+ "items": "$def.ga4ItemsLoop"
294
294
  }
295
295
  }
296
296
  }
@@ -307,7 +307,7 @@
307
307
  "package": "@walkeros/web-destination-api",
308
308
  "config": {
309
309
  "settings": {
310
- "url": "$variables.apiUrl",
310
+ "url": "$var.apiUrl",
311
311
  "batch": 5
312
312
  },
313
313
  "mapping": {
@@ -322,7 +322,7 @@
322
322
  "key": "user.email",
323
323
  "consent": { "marketing": true }
324
324
  },
325
- "items": { "$ref": "#/definitions/ga4ItemsLoop" }
325
+ "items": "$def.ga4ItemsLoop"
326
326
  }
327
327
  }
328
328
  }
@@ -347,7 +347,7 @@
347
347
  },
348
348
  "globals": {
349
349
  "environment": "demo",
350
- "version": "$variables.flowVersion"
350
+ "version": "$var.flowVersion"
351
351
  },
352
352
  "custom": {
353
353
  "campaign": "flow-demo"
@@ -357,8 +357,8 @@
357
357
  "server": {
358
358
  "server": {},
359
359
  "variables": {
360
- "metaPixelId": "${META_PIXEL_ID:123456789012345}",
361
- "metaAccessToken": "${META_ACCESS_TOKEN:demo_token}"
360
+ "metaPixelId": "$env.META_PIXEL_ID:123456789012345",
361
+ "metaAccessToken": "$env.META_ACCESS_TOKEN:demo_token"
362
362
  },
363
363
  "packages": {
364
364
  "@walkeros/collector": {},
@@ -444,8 +444,8 @@
444
444
  "before": "fingerprint",
445
445
  "config": {
446
446
  "settings": {
447
- "pixelId": "$variables.metaPixelId",
448
- "accessToken": "$variables.metaAccessToken",
447
+ "pixelId": "$var.metaPixelId",
448
+ "accessToken": "$var.metaAccessToken",
449
449
  "user_data": {
450
450
  "external_id": {
451
451
  "set": ["user.device", "user.session"]
@@ -481,7 +481,7 @@
481
481
  "value": "data.price",
482
482
  "currency": {
483
483
  "key": "data.currency",
484
- "value": "$variables.currency"
484
+ "value": "$var.currency"
485
485
  },
486
486
  "content_type": { "value": "product" },
487
487
  "content_ids": {
@@ -497,7 +497,7 @@
497
497
  "value": "data.price",
498
498
  "currency": {
499
499
  "key": "data.currency",
500
- "value": "$variables.currency"
500
+ "value": "$var.currency"
501
501
  },
502
502
  "content_type": { "value": "product" },
503
503
  "contents": {
@@ -523,10 +523,10 @@
523
523
  "value": "data.total",
524
524
  "currency": {
525
525
  "key": "data.currency",
526
- "value": "$variables.currency"
526
+ "value": "$var.currency"
527
527
  },
528
528
  "order_id": "data.id",
529
- "contents": { "$ref": "#/definitions/metaContentsLoop" }
529
+ "contents": "$def.metaContentsLoop"
530
530
  }
531
531
  }
532
532
  }
@@ -562,7 +562,7 @@
562
562
  },
563
563
  "globals": {
564
564
  "environment": "demo",
565
- "version": "$variables.flowVersion",
565
+ "version": "$var.flowVersion",
566
566
  "platform": "server"
567
567
  }
568
568
  }
package/dist/index.js CHANGED
@@ -870,6 +870,14 @@ async function bundleCore(flowConfig, buildOptions, logger2, showStats = false)
870
870
  }
871
871
  try {
872
872
  await fs7.ensureDir(TEMP_DIR);
873
+ const hasSourcesOrDests = Object.keys(
874
+ flowConfig.sources || {}
875
+ ).length > 0 || Object.keys(
876
+ flowConfig.destinations || {}
877
+ ).length > 0;
878
+ if (hasSourcesOrDests && !buildOptions.packages["@walkeros/collector"]) {
879
+ buildOptions.packages["@walkeros/collector"] = {};
880
+ }
873
881
  logger2.debug("Downloading packages");
874
882
  const packagesArray = Object.entries(buildOptions.packages).map(
875
883
  ([name, packageConfig]) => ({
@@ -935,6 +943,8 @@ async function bundleCore(flowConfig, buildOptions, logger2, showStats = false)
935
943
  buildError,
936
944
  buildOptions.code || ""
937
945
  );
946
+ } finally {
947
+ await esbuild.stop();
938
948
  }
939
949
  const outputStats = await fs7.stat(outputPath);
940
950
  const sizeKB = (outputStats.size / 1024).toFixed(1);
@@ -1127,30 +1137,31 @@ function generateImportStatements(packages, destinationPackages, sourcePackages,
1127
1137
  for (const [packageName, packageConfig] of Object.entries(packages)) {
1128
1138
  const isUsedByDestOrSource = usedPackages.has(packageName);
1129
1139
  const hasExplicitCode = explicitCodeImports.has(packageName);
1140
+ const namedImportsToGenerate = [];
1141
+ if (isUsedByDestOrSource && !hasExplicitCode) {
1142
+ const varName = packageNameToVariable(packageName);
1143
+ importStatements.push(`import ${varName} from '${packageName}';`);
1144
+ }
1145
+ if (hasExplicitCode) {
1146
+ const codes = Array.from(explicitCodeImports.get(packageName));
1147
+ namedImportsToGenerate.push(...codes);
1148
+ }
1130
1149
  if (packageConfig.imports && packageConfig.imports.length > 0) {
1131
1150
  const uniqueImports = [...new Set(packageConfig.imports)];
1132
- const defaultImports = [];
1133
- const namedImports = [];
1134
1151
  for (const imp of uniqueImports) {
1135
1152
  if (imp.startsWith("default as ")) {
1136
- defaultImports.push(imp.replace("default as ", ""));
1153
+ if (!isUsedByDestOrSource || hasExplicitCode) {
1154
+ const defaultImportName = imp.replace("default as ", "");
1155
+ importStatements.push(
1156
+ `import ${defaultImportName} from '${packageName}';`
1157
+ );
1158
+ }
1137
1159
  } else {
1138
- namedImports.push(imp);
1139
- }
1140
- }
1141
- if (defaultImports.length > 0) {
1142
- for (const defaultImport of defaultImports) {
1143
- importStatements.push(
1144
- `import ${defaultImport} from '${packageName}';`
1145
- );
1160
+ if (!namedImportsToGenerate.includes(imp)) {
1161
+ namedImportsToGenerate.push(imp);
1162
+ }
1146
1163
  }
1147
1164
  }
1148
- if (namedImports.length > 0) {
1149
- const importList = namedImports.join(", ");
1150
- importStatements.push(
1151
- `import { ${importList} } from '${packageName}';`
1152
- );
1153
- }
1154
1165
  const examplesImport = uniqueImports.find(
1155
1166
  (imp) => imp.includes("examples as ")
1156
1167
  );
@@ -1166,14 +1177,13 @@ function generateImportStatements(packages, destinationPackages, sourcePackages,
1166
1177
  );
1167
1178
  }
1168
1179
  }
1169
- } else if (hasExplicitCode) {
1170
- const codes = Array.from(explicitCodeImports.get(packageName));
1171
- importStatements.push(
1172
- `import { ${codes.join(", ")} } from '${packageName}';`
1173
- );
1174
- } else if (isUsedByDestOrSource) {
1175
- const varName = packageNameToVariable(packageName);
1176
- importStatements.push(`import ${varName} from '${packageName}';`);
1180
+ }
1181
+ if (packageName === "@walkeros/collector" && !namedImportsToGenerate.includes("startFlow")) {
1182
+ namedImportsToGenerate.push("startFlow");
1183
+ }
1184
+ if (namedImportsToGenerate.length > 0) {
1185
+ const importList = namedImportsToGenerate.join(", ");
1186
+ importStatements.push(`import { ${importList} } from '${packageName}';`);
1177
1187
  }
1178
1188
  }
1179
1189
  return { importStatements, examplesMappings };
@@ -1269,7 +1279,37 @@ ${destinationsEntries.join(",\n")}
1269
1279
  }`;
1270
1280
  }
1271
1281
  function processConfigValue(value) {
1272
- return JSON.stringify(value, null, 2);
1282
+ return serializeWithCode(value, 0);
1283
+ }
1284
+ function serializeWithCode(value, indent) {
1285
+ const spaces = " ".repeat(indent);
1286
+ const nextSpaces = " ".repeat(indent + 1);
1287
+ if (typeof value === "string") {
1288
+ if (value.startsWith("$code:")) {
1289
+ return value.slice(6);
1290
+ }
1291
+ return JSON.stringify(value);
1292
+ }
1293
+ if (Array.isArray(value)) {
1294
+ if (value.length === 0) return "[]";
1295
+ const items = value.map(
1296
+ (v) => nextSpaces + serializeWithCode(v, indent + 1)
1297
+ );
1298
+ return `[
1299
+ ${items.join(",\n")}
1300
+ ${spaces}]`;
1301
+ }
1302
+ if (value !== null && typeof value === "object") {
1303
+ const entries = Object.entries(value);
1304
+ if (entries.length === 0) return "{}";
1305
+ const props = entries.map(
1306
+ ([k, v]) => `${nextSpaces}${JSON.stringify(k)}: ${serializeWithCode(v, indent + 1)}`
1307
+ );
1308
+ return `{
1309
+ ${props.join(",\n")}
1310
+ ${spaces}}`;
1311
+ }
1312
+ return JSON.stringify(value);
1273
1313
  }
1274
1314
  function generatePlatformWrapper(configObject, userCode, buildOptions) {
1275
1315
  if (buildOptions.platform === "browser") {
@@ -1434,6 +1474,7 @@ Build Summary: ${successCount}/${results.length} succeeded`
1434
1474
  throw new Error(`${failureCount} flow(s) failed to build`);
1435
1475
  }
1436
1476
  }
1477
+ process.exit(0);
1437
1478
  } catch (error) {
1438
1479
  const duration = timer.getElapsed() / 1e3;
1439
1480
  const errorMessage = getErrorMessage(error);
@@ -2004,17 +2045,15 @@ async function simulateCommand(options) {
2004
2045
  ...result,
2005
2046
  duration: (Date.now() - startTime) / 1e3
2006
2047
  };
2048
+ const output = formatSimulationResult(resultWithDuration, {
2049
+ json: options.json
2050
+ });
2007
2051
  if (options.json) {
2008
- logger2.json(resultWithDuration);
2052
+ console.log(output);
2009
2053
  } else {
2010
- const output = formatSimulationResult(resultWithDuration, {
2011
- json: false
2012
- });
2013
2054
  logger2.log(output);
2014
2055
  }
2015
- if (!result.success) {
2016
- process.exit(1);
2017
- }
2056
+ process.exit(result.success ? 0 : 1);
2018
2057
  } catch (error) {
2019
2058
  const errorMessage = getErrorMessage(error);
2020
2059
  if (options.json) {
@@ -2132,6 +2171,7 @@ async function pushCommand(options) {
2132
2171
  process.exit(1);
2133
2172
  }
2134
2173
  }
2174
+ process.exit(0);
2135
2175
  } catch (error) {
2136
2176
  const duration = Date.now() - startTime;
2137
2177
  const errorMessage = getErrorMessage(error);