@walkeros/cli 4.3.0-next-1784120651691 → 4.3.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.
package/CHANGELOG.md CHANGED
@@ -1,6 +1,6 @@
1
1
  # @walkeros/cli
2
2
 
3
- ## 4.3.0-next-1784120651691
3
+ ## 4.3.0
4
4
 
5
5
  ### Minor Changes
6
6
 
@@ -62,11 +62,11 @@
62
62
  - Updated dependencies [f8408fd]
63
63
  - Updated dependencies [907eed0]
64
64
  - Updated dependencies [9506e3e]
65
- - @walkeros/collector@4.3.0-next-1784120651691
66
- - @walkeros/core@4.3.0-next-1784120651691
67
- - @walkeros/server-core@4.3.0-next-1784120651691
68
- - @walkeros/server-destination-api@4.3.0-next-1784120651691
69
- - @walkeros/transformer-validate@4.3.0-next-1784120651691
65
+ - @walkeros/collector@4.3.0
66
+ - @walkeros/core@4.3.0
67
+ - @walkeros/server-core@4.3.0
68
+ - @walkeros/server-destination-api@4.3.0
69
+ - @walkeros/transformer-validate@4.3.0
70
70
 
71
71
  ## 4.2.1
72
72
 
package/dist/cli.js CHANGED
@@ -6652,7 +6652,7 @@ async function Be2(e4, t4, n5, o4, r6, s4, a4) {
6652
6652
  }
6653
6653
  p3 && p3.length > 0 && (i5 = await er(p3, (t5) => Te(t5, e4), i5, e4));
6654
6654
  const y3 = await Xe(Fe, (t5) => (e4.logger.scope(`transformer:${s5.type || "unknown"}`).error("Push failed", { error: t5 }), false))(e4, s5, o5, i5, r6, c2);
6655
- if (false === y3) return { event: null, respond: c2 };
6655
+ if (false === y3) return { event: null, respond: c2, droppedBy: o5 };
6656
6656
  if (Array.isArray(y3)) {
6657
6657
  const s6 = n5.slice(n5.indexOf(o5) + 1), u3 = await Promise.all(y3.map(async (n6) => {
6658
6658
  const o6 = await m3(n6.event || i5), u4 = Ue2(r6, "unknown");
@@ -7464,7 +7464,7 @@ function Gt(e4, t4, n5) {
7464
7464
  if (!o4 || !r6) throw new Error("Event name is invalid");
7465
7465
  const { timestamp: s4 = Date.now(), name: a4 = `${o4} ${r6}`, data: i5 = {}, context: c2 = {}, globals: u2 = e4.globals, custom: d2 = {}, user: l3 = e4.user, nested: f3 = [], consent: p3 = e4.consent, id: g3 = Ne(), trigger: m3 = "", entity: h2 = o4, action: v3 = r6, timing: y3 = 0, source: w3 = { type: "collector", schema: "4" } } = t4, b3 = w3.count ?? (e4.count += 1), k3 = w3.trace ?? n5?._meta.trace ?? e4.trace, I2 = { ...w3, count: b3 };
7466
7466
  void 0 !== k3 && (I2.trace = k3);
7467
- const C3 = e4.name ?? w3.platform ?? "default", E3 = e4.release ?? "4.3.0-next-1784120651691";
7467
+ const C3 = e4.name ?? w3.platform ?? "default", E3 = e4.release ?? "4.3.0";
7468
7468
  return I2.release = { ...w3.release, [C3]: E3 }, { name: a4, data: i5, context: c2, globals: u2, custom: d2, user: l3, nested: f3, consent: p3, id: g3, trigger: m3, entity: h2, action: v3, timestamp: s4, timing: y3, source: I2 };
7469
7469
  }
7470
7470
  function Wt(e4, t4, n5) {
@@ -7494,7 +7494,7 @@ function en2(e4, t4) {
7494
7494
  }
7495
7495
  if (u2?.length && e4.transformers && Object.keys(e4.transformers).length > 0) {
7496
7496
  const n7 = await Be2(e4, e4.transformers, u2, p3, m3, f3, s4 ? `source.${s4}.next` : void 0);
7497
- if (null === n7.event) return Ot2({ ok: true });
7497
+ if (null === n7.event) return e4.logger.debug("Event dropped by transformer chain" + (n7.droppedBy ? ` (${n7.droppedBy})` : "")), Ot2({ ok: true, dropped: true });
7498
7498
  if (n7.stopped) return n7.respond && (f3 = n7.respond), Ot2({ ok: true });
7499
7499
  if (n7.respond && (f3 = n7.respond), Array.isArray(n7.event)) {
7500
7500
  const o5 = await Promise.all(n7.event.map(async (n8) => {
@@ -10225,11 +10225,14 @@ function createPoller(config, logger) {
10225
10225
  init_dist();
10226
10226
  import http from "http";
10227
10227
  var PREVIEW_LOG = "[walkerOS:preview]";
10228
- function answerPreviewPreflight(res) {
10228
+ function answerPreviewPreflight(req, res) {
10229
+ const requested = req.headers["access-control-request-headers"];
10230
+ const requestedHeaders = Array.isArray(requested) ? requested.join(", ") : requested;
10229
10231
  res.writeHead(204, {
10230
10232
  "Access-Control-Allow-Origin": "*",
10231
10233
  "Access-Control-Allow-Methods": "GET, POST, OPTIONS",
10232
- "Access-Control-Allow-Headers": "Content-Type, X-Walkeros-Preview"
10234
+ "Access-Control-Allow-Headers": requestedHeaders || "Content-Type, X-Walkeros-Preview",
10235
+ Vary: "Access-Control-Request-Headers"
10233
10236
  });
10234
10237
  res.end();
10235
10238
  }
@@ -10319,7 +10322,7 @@ function createHealthServer(port, logger, previewGate) {
10319
10322
  };
10320
10323
  if (previewGate) {
10321
10324
  if (req.method === "OPTIONS") {
10322
- answerPreviewPreflight(res);
10325
+ answerPreviewPreflight(req, res);
10323
10326
  return;
10324
10327
  }
10325
10328
  guardPreviewIntake(req, res, previewGate, logger, delegate);
@@ -11618,11 +11621,14 @@ init_config();
11618
11621
  import chalk3 from "chalk";
11619
11622
 
11620
11623
  // src/commands/validate/validators/contract.ts
11624
+ init_dist();
11621
11625
  var SECTION_KEYS = ["globals", "context", "custom", "user", "consent"];
11622
11626
  var KNOWN_KEYS = /* @__PURE__ */ new Set([
11623
11627
  "extend",
11628
+ "tagging",
11624
11629
  "description",
11625
11630
  "events",
11631
+ "schema",
11626
11632
  ...SECTION_KEYS
11627
11633
  ]);
11628
11634
  function validateContract(input) {
@@ -11640,7 +11646,19 @@ function validateContract(input) {
11640
11646
  const contracts = input;
11641
11647
  const contractNames = Object.keys(contracts);
11642
11648
  details.contractCount = contractNames.length;
11649
+ for (const name of contractNames) {
11650
+ if (name.startsWith("$")) {
11651
+ errors.push({
11652
+ path: name,
11653
+ message: `"${name}" is not a named contract entry. This looks like the flat shape; use named ContractRule entries, lift $tagging to the rule field "tagging", and nest entity-action schemas under "events".`,
11654
+ code: "FLAT_CONTRACT_SHAPE"
11655
+ });
11656
+ }
11657
+ }
11643
11658
  for (const [name, entry] of Object.entries(contracts)) {
11659
+ if (name.startsWith("$")) {
11660
+ continue;
11661
+ }
11644
11662
  if (typeof entry !== "object" || entry === null) {
11645
11663
  errors.push({
11646
11664
  path: name,
@@ -11650,6 +11668,39 @@ function validateContract(input) {
11650
11668
  continue;
11651
11669
  }
11652
11670
  const obj = entry;
11671
+ const keys = Object.keys(obj);
11672
+ const unknownKeys = keys.filter((k3) => !KNOWN_KEYS.has(k3));
11673
+ const hasKnownKey = keys.some((k3) => KNOWN_KEYS.has(k3));
11674
+ const objectValuedUnknown = unknownKeys.filter((k3) => de(obj[k3]));
11675
+ if (!hasKnownKey && objectValuedUnknown.length > 0) {
11676
+ errors.push({
11677
+ path: name,
11678
+ message: `Contract "${name}" looks like a flat entity-action map. Nest entity-action schemas under an "events" key of a named ContractRule.`,
11679
+ code: "FLAT_CONTRACT_SHAPE"
11680
+ });
11681
+ continue;
11682
+ }
11683
+ for (const key of unknownKeys) {
11684
+ warnings.push({
11685
+ path: `${name}.${key}`,
11686
+ message: `Unknown contract key "${key}" is ignored`,
11687
+ code: "UNKNOWN_CONTRACT_KEY"
11688
+ });
11689
+ }
11690
+ if (obj.tagging !== void 0 && typeof obj.tagging !== "number") {
11691
+ errors.push({
11692
+ path: `${name}.tagging`,
11693
+ message: "tagging must be a number",
11694
+ code: "INVALID_TAGGING"
11695
+ });
11696
+ }
11697
+ if (obj.schema !== void 0 && !de(obj.schema)) {
11698
+ errors.push({
11699
+ path: `${name}.schema`,
11700
+ message: "schema must be a JSON Schema object",
11701
+ code: "INVALID_SCHEMA"
11702
+ });
11703
+ }
11653
11704
  if (obj.extend !== void 0) {
11654
11705
  if (typeof obj.extend !== "string") {
11655
11706
  errors.push({
@@ -13401,7 +13452,7 @@ function validateMapping(input) {
13401
13452
  // src/commands/validate/validators/entry.ts
13402
13453
  init_dist();
13403
13454
  import Ajv from "ajv";
13404
- var CLIENT_HEADER = "walkeros-cli/4.3.0-next-1784120651691";
13455
+ var CLIENT_HEADER = "walkeros-cli/4.3.0";
13405
13456
  var SECTIONS = ["destinations", "sources", "transformers"];
13406
13457
  function resolveEntry(path19, flowConfig) {
13407
13458
  const flows = flowConfig.flows;
package/dist/index.d.ts CHANGED
@@ -665,6 +665,7 @@ interface ValidationWarning {
665
665
  path: string;
666
666
  message: string;
667
667
  suggestion?: string;
668
+ code?: string;
668
669
  }
669
670
  interface ValidateResult {
670
671
  valid: boolean;
package/dist/index.js CHANGED
@@ -6409,11 +6409,14 @@ function createPoller(config, logger) {
6409
6409
  import http from "http";
6410
6410
  import { verifyActivation } from "@walkeros/core";
6411
6411
  var PREVIEW_LOG = "[walkerOS:preview]";
6412
- function answerPreviewPreflight(res) {
6412
+ function answerPreviewPreflight(req, res) {
6413
+ const requested = req.headers["access-control-request-headers"];
6414
+ const requestedHeaders = Array.isArray(requested) ? requested.join(", ") : requested;
6413
6415
  res.writeHead(204, {
6414
6416
  "Access-Control-Allow-Origin": "*",
6415
6417
  "Access-Control-Allow-Methods": "GET, POST, OPTIONS",
6416
- "Access-Control-Allow-Headers": "Content-Type, X-Walkeros-Preview"
6418
+ "Access-Control-Allow-Headers": requestedHeaders || "Content-Type, X-Walkeros-Preview",
6419
+ Vary: "Access-Control-Request-Headers"
6417
6420
  });
6418
6421
  res.end();
6419
6422
  }
@@ -6503,7 +6506,7 @@ function createHealthServer(port, logger, previewGate) {
6503
6506
  };
6504
6507
  if (previewGate) {
6505
6508
  if (req.method === "OPTIONS") {
6506
- answerPreviewPreflight(res);
6509
+ answerPreviewPreflight(req, res);
6507
6510
  return;
6508
6511
  }
6509
6512
  guardPreviewIntake(req, res, previewGate, logger, delegate);
@@ -7574,11 +7577,14 @@ init_config();
7574
7577
  import chalk2 from "chalk";
7575
7578
 
7576
7579
  // src/commands/validate/validators/contract.ts
7580
+ import { isObject as isObject4 } from "@walkeros/core";
7577
7581
  var SECTION_KEYS = ["globals", "context", "custom", "user", "consent"];
7578
7582
  var KNOWN_KEYS = /* @__PURE__ */ new Set([
7579
7583
  "extend",
7584
+ "tagging",
7580
7585
  "description",
7581
7586
  "events",
7587
+ "schema",
7582
7588
  ...SECTION_KEYS
7583
7589
  ]);
7584
7590
  function validateContract(input) {
@@ -7596,7 +7602,19 @@ function validateContract(input) {
7596
7602
  const contracts = input;
7597
7603
  const contractNames = Object.keys(contracts);
7598
7604
  details.contractCount = contractNames.length;
7605
+ for (const name of contractNames) {
7606
+ if (name.startsWith("$")) {
7607
+ errors.push({
7608
+ path: name,
7609
+ message: `"${name}" is not a named contract entry. This looks like the flat shape; use named ContractRule entries, lift $tagging to the rule field "tagging", and nest entity-action schemas under "events".`,
7610
+ code: "FLAT_CONTRACT_SHAPE"
7611
+ });
7612
+ }
7613
+ }
7599
7614
  for (const [name, entry] of Object.entries(contracts)) {
7615
+ if (name.startsWith("$")) {
7616
+ continue;
7617
+ }
7600
7618
  if (typeof entry !== "object" || entry === null) {
7601
7619
  errors.push({
7602
7620
  path: name,
@@ -7606,6 +7624,39 @@ function validateContract(input) {
7606
7624
  continue;
7607
7625
  }
7608
7626
  const obj = entry;
7627
+ const keys = Object.keys(obj);
7628
+ const unknownKeys = keys.filter((k) => !KNOWN_KEYS.has(k));
7629
+ const hasKnownKey = keys.some((k) => KNOWN_KEYS.has(k));
7630
+ const objectValuedUnknown = unknownKeys.filter((k) => isObject4(obj[k]));
7631
+ if (!hasKnownKey && objectValuedUnknown.length > 0) {
7632
+ errors.push({
7633
+ path: name,
7634
+ message: `Contract "${name}" looks like a flat entity-action map. Nest entity-action schemas under an "events" key of a named ContractRule.`,
7635
+ code: "FLAT_CONTRACT_SHAPE"
7636
+ });
7637
+ continue;
7638
+ }
7639
+ for (const key of unknownKeys) {
7640
+ warnings.push({
7641
+ path: `${name}.${key}`,
7642
+ message: `Unknown contract key "${key}" is ignored`,
7643
+ code: "UNKNOWN_CONTRACT_KEY"
7644
+ });
7645
+ }
7646
+ if (obj.tagging !== void 0 && typeof obj.tagging !== "number") {
7647
+ errors.push({
7648
+ path: `${name}.tagging`,
7649
+ message: "tagging must be a number",
7650
+ code: "INVALID_TAGGING"
7651
+ });
7652
+ }
7653
+ if (obj.schema !== void 0 && !isObject4(obj.schema)) {
7654
+ errors.push({
7655
+ path: `${name}.schema`,
7656
+ message: "schema must be a JSON Schema object",
7657
+ code: "INVALID_SCHEMA"
7658
+ });
7659
+ }
7609
7660
  if (obj.extend !== void 0) {
7610
7661
  if (typeof obj.extend !== "string") {
7611
7662
  errors.push({
@@ -7733,7 +7784,7 @@ function validateEvent2(input) {
7733
7784
  // src/commands/validate/validators/flow.ts
7734
7785
  import {
7735
7786
  getFlowSettings as getFlowSettings2,
7736
- isObject as isObject4,
7787
+ isObject as isObject5,
7737
7788
  resolveContracts,
7738
7789
  validateStepEntry as validateStepEntry2
7739
7790
  } from "@walkeros/core";
@@ -7741,9 +7792,9 @@ import { schemas as schemas4 } from "@walkeros/core/dev";
7741
7792
  import { validateEventAgainstContract } from "@walkeros/transformer-validate";
7742
7793
  var { validateFlowConfig: validateFlowConfig2 } = schemas4;
7743
7794
  function isFlowJson(value) {
7744
- if (!isObject4(value)) return false;
7795
+ if (!isObject5(value)) return false;
7745
7796
  if (!("version" in value) || !("flows" in value)) return false;
7746
- return isObject4(value.flows);
7797
+ return isObject5(value.flows);
7747
7798
  }
7748
7799
  function validateFlow(input, options = {}) {
7749
7800
  const errors = [];
@@ -7774,9 +7825,9 @@ function validateFlow(input, options = {}) {
7774
7825
  message: issue.message
7775
7826
  });
7776
7827
  }
7777
- const config = isObject4(input) ? input : {};
7828
+ const config = isObject5(input) ? input : {};
7778
7829
  const flowsValue = config.flows;
7779
- const flows = isObject4(flowsValue) ? flowsValue : void 0;
7830
+ const flows = isObject5(flowsValue) ? flowsValue : void 0;
7780
7831
  if (flows && Object.keys(flows).length === 0) {
7781
7832
  errors.push({
7782
7833
  path: "flows",
@@ -7786,13 +7837,13 @@ function validateFlow(input, options = {}) {
7786
7837
  }
7787
7838
  if (flows) {
7788
7839
  for (const [flowName, flowValue] of Object.entries(flows)) {
7789
- if (!isObject4(flowValue)) continue;
7840
+ if (!isObject5(flowValue)) continue;
7790
7841
  const transformersValue = flowValue.transformers;
7791
- if (!isObject4(transformersValue)) continue;
7842
+ if (!isObject5(transformersValue)) continue;
7792
7843
  for (const [name, transformerValue] of Object.entries(
7793
7844
  transformersValue
7794
7845
  )) {
7795
- if (!isObject4(transformerValue)) continue;
7846
+ if (!isObject5(transformerValue)) continue;
7796
7847
  const result = validateStepEntry2(transformerValue, "Transformer");
7797
7848
  if (!result.ok) {
7798
7849
  errors.push({
@@ -7823,15 +7874,15 @@ function validateFlow(input, options = {}) {
7823
7874
  let totalPackageCount = 0;
7824
7875
  if (flows) {
7825
7876
  for (const [flowName, flowValue] of Object.entries(flows)) {
7826
- if (!isObject4(flowValue)) continue;
7877
+ if (!isObject5(flowValue)) continue;
7827
7878
  const flowConfig = flowValue.config;
7828
- if (!isObject4(flowConfig)) continue;
7879
+ if (!isObject5(flowConfig)) continue;
7829
7880
  const bundle2 = flowConfig.bundle;
7830
- if (!isObject4(bundle2)) continue;
7881
+ if (!isObject5(bundle2)) continue;
7831
7882
  const packages = bundle2.packages;
7832
- if (!isObject4(packages)) continue;
7883
+ if (!isObject5(packages)) continue;
7833
7884
  for (const [pkgName, pkgConfigValue] of Object.entries(packages)) {
7834
- if (!isObject4(pkgConfigValue)) continue;
7885
+ if (!isObject5(pkgConfigValue)) continue;
7835
7886
  if (!pkgConfigValue.version && !pkgConfigValue.path) {
7836
7887
  warnings.push({
7837
7888
  path: `flows.${flowName}.config.bundle.packages.${pkgName}`,
@@ -7880,9 +7931,9 @@ function validateFlow(input, options = {}) {
7880
7931
  for (const [destName, dest] of Object.entries(
7881
7932
  flowSettings.destinations || {}
7882
7933
  )) {
7883
- if (!isObject4(dest.config)) continue;
7934
+ if (!isObject5(dest.config)) continue;
7884
7935
  const mapping = dest.config.mapping;
7885
- if (!isObject4(mapping)) continue;
7936
+ if (!isObject5(mapping)) continue;
7886
7937
  for (const key of Object.keys(mapping)) {
7887
7938
  if (key.includes(".") && !key.includes(" ")) {
7888
7939
  const parts = key.split(".");
@@ -8164,7 +8215,7 @@ function checkContractCompliance(config, contract, errors, warnings, strict) {
8164
8215
  const rules = Object.values(resolved);
8165
8216
  if (rules.length === 0) return;
8166
8217
  const checkExample = (path20, candidate) => {
8167
- if (!isObject4(candidate)) return;
8218
+ if (!isObject5(candidate)) return;
8168
8219
  const entity = typeof candidate.entity === "string" ? candidate.entity : void 0;
8169
8220
  const action = typeof candidate.action === "string" ? candidate.action : void 0;
8170
8221
  if (!entity || !action) return;
@@ -8254,7 +8305,7 @@ function validateMapping(input) {
8254
8305
  // src/commands/validate/validators/entry.ts
8255
8306
  import Ajv from "ajv";
8256
8307
  import { fetchPackageSchema } from "@walkeros/core";
8257
- var CLIENT_HEADER = "walkeros-cli/4.3.0-next-1784120651691";
8308
+ var CLIENT_HEADER = "walkeros-cli/4.3.0";
8258
8309
  var SECTIONS = ["destinations", "sources", "transformers"];
8259
8310
  function resolveEntry(path20, flowConfig) {
8260
8311
  const flows = flowConfig.flows;
@@ -9974,7 +10025,7 @@ init_config_classifier();
9974
10025
 
9975
10026
  // src/commands/bundle/validate-structure.ts
9976
10027
  init_structural_validators();
9977
- import { isObject as isObject5, validateStepEntry as validateStepEntry3 } from "@walkeros/core";
10028
+ import { isObject as isObject6, validateStepEntry as validateStepEntry3 } from "@walkeros/core";
9978
10029
  var STEP_SECTIONS = [
9979
10030
  "sources",
9980
10031
  "destinations",
@@ -10001,7 +10052,7 @@ function getSection(flow, section) {
10001
10052
  }
10002
10053
  function hasCodeReference3(code) {
10003
10054
  if (typeof code === "string") return true;
10004
- return isObject5(code) && "push" in code;
10055
+ return isObject6(code) && "push" in code;
10005
10056
  }
10006
10057
  function messageOf(error) {
10007
10058
  return error instanceof Error ? error.message : String(error);
@@ -10010,10 +10061,10 @@ function validateFlowStructure(flowConfig) {
10010
10061
  const errors = [];
10011
10062
  const details = {};
10012
10063
  const flows = flowConfig.flows;
10013
- const flowNames = isObject5(flows) ? Object.keys(flows) : [];
10064
+ const flowNames = isObject6(flows) ? Object.keys(flows) : [];
10014
10065
  details.flowNames = flowNames;
10015
10066
  details.flowCount = flowNames.length;
10016
- if (!isObject5(flows) || flowNames.length === 0) {
10067
+ if (!isObject6(flows) || flowNames.length === 0) {
10017
10068
  errors.push({
10018
10069
  path: "flows",
10019
10070
  message: "At least one flow is required",