@walkeros/cli 4.8.1 → 4.8.3-next-1793115089237

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 (51) hide show
  1. package/CHANGELOG.md +115 -3
  2. package/README.md +2 -2
  3. package/dist/cli.js +4149 -4149
  4. package/dist/dev.d.ts +51 -3
  5. package/dist/dev.js +186 -0
  6. package/dist/dev.js.map +1 -1
  7. package/dist/examples/README.md +12 -1
  8. package/dist/examples/contracts/app.json +261 -0
  9. package/dist/examples/contracts/base.json +708 -0
  10. package/dist/examples/contracts/ecommerce.json +963 -0
  11. package/dist/examples/contracts/leadgen.json +240 -0
  12. package/dist/examples/contracts/publisher.json +372 -0
  13. package/dist/examples/contracts/saas.json +229 -0
  14. package/dist/examples/contracts/travel.json +234 -0
  15. package/dist/examples/customers/README.md +4 -1
  16. package/dist/examples/event.json +1 -1
  17. package/dist/examples/flow-complete.json +107 -130
  18. package/dist/examples/flow-complete.md +12 -10
  19. package/dist/examples/flow-order-complete.json +1 -1
  20. package/dist/examples/flow.json +1 -1
  21. package/dist/examples/index.d.ts +34 -4
  22. package/dist/examples/index.js +128 -139
  23. package/dist/examples/index.js.map +1 -1
  24. package/dist/examples/shared/README.md +4 -0
  25. package/dist/index.d.ts +63 -223
  26. package/dist/index.js +572 -992
  27. package/dist/index.js.map +1 -1
  28. package/dist/validate.d.ts +1 -1
  29. package/dist/validate.js +337 -204
  30. package/dist/validate.js.map +1 -1
  31. package/examples/README.md +12 -1
  32. package/examples/contracts/app.json +261 -0
  33. package/examples/contracts/base.json +708 -0
  34. package/examples/contracts/ecommerce.json +963 -0
  35. package/examples/contracts/leadgen.json +240 -0
  36. package/examples/contracts/publisher.json +372 -0
  37. package/examples/contracts/saas.json +229 -0
  38. package/examples/contracts/travel.json +234 -0
  39. package/examples/customers/README.md +4 -1
  40. package/examples/event.json +1 -1
  41. package/examples/flow-complete.json +107 -130
  42. package/examples/flow-complete.md +12 -10
  43. package/examples/flow-order-complete.json +1 -1
  44. package/examples/flow.json +1 -1
  45. package/examples/shared/README.md +4 -0
  46. package/package.json +30 -30
  47. package/src/telemetry/flow.json +42 -34
  48. package/dist/examples/test.html +0 -43
  49. package/dist/examples/web-serve.js +0 -25503
  50. package/examples/test.html +0 -43
  51. package/examples/web-serve.js +0 -25503
package/dist/validate.js CHANGED
@@ -2,7 +2,7 @@
2
2
  import * as fs9 from "fs";
3
3
  import * as path3 from "path";
4
4
  import chalk2 from "chalk";
5
- import { isObject as isObject7 } from "@walkeros/core";
5
+ import { isObject as isObject8 } from "@walkeros/core";
6
6
 
7
7
  // src/core/cli-logger.ts
8
8
  import chalk from "chalk";
@@ -133,34 +133,6 @@ import fs4 from "fs-extra";
133
133
  // src/core/stdin.ts
134
134
  import fs5 from "fs-extra";
135
135
 
136
- // src/core/oauth-client.ts
137
- import { z as z2 } from "zod";
138
-
139
- // src/core/app-fetch.ts
140
- import { z } from "zod";
141
- var AppErrorSchema = z.object({
142
- error: z.object({ message: z.string().min(1) })
143
- });
144
-
145
- // src/core/oauth-client.ts
146
- var DeviceAuthorizationSchema = z2.object({
147
- device_code: z2.string().min(1),
148
- user_code: z2.string().min(1),
149
- verification_uri: z2.string().min(1),
150
- verification_uri_complete: z2.string().min(1).optional(),
151
- expires_in: z2.number().int().nonnegative(),
152
- interval: z2.number().int().nonnegative()
153
- });
154
- var TokenSchema = z2.object({
155
- access_token: z2.string().min(1),
156
- expires_in: z2.number().int().nonnegative(),
157
- refresh_token: z2.string().min(1).optional()
158
- });
159
- var ErrorSchema = z2.object({
160
- error: z2.string().min(1),
161
- error_description: z2.string().optional()
162
- });
163
-
164
136
  // src/core/event-validation.ts
165
137
  import { schemas } from "@walkeros/core/dev";
166
138
  var { PartialEventSchema } = schemas;
@@ -256,6 +228,7 @@ var { safeParseConfig } = schemas2;
256
228
  // src/config/loader.ts
257
229
  import fs7 from "fs-extra";
258
230
  import { getFlowSettings, getPlatform } from "@walkeros/core";
231
+ import { validateFlowStructure } from "@walkeros/core/dev";
259
232
 
260
233
  // src/core/content-digest.ts
261
234
  import { createHash } from "crypto";
@@ -265,16 +238,9 @@ import fs6 from "fs-extra";
265
238
  import { checkWindowCollector } from "@walkeros/core";
266
239
 
267
240
  // src/commands/validate/validators/contract.ts
268
- import { isObject as isObject2 } from "@walkeros/core";
241
+ import { CONTRACT_RULE_KEYS, isObject as isObject2 } from "@walkeros/core";
242
+ var KNOWN_KEYS = new Set(CONTRACT_RULE_KEYS);
269
243
  var SECTION_KEYS = ["globals", "context", "custom", "user", "consent"];
270
- var KNOWN_KEYS = /* @__PURE__ */ new Set([
271
- "extend",
272
- "tagging",
273
- "description",
274
- "events",
275
- "schema",
276
- ...SECTION_KEYS
277
- ]);
278
244
  function validateContract(input) {
279
245
  const errors = [];
280
246
  const warnings = [];
@@ -315,7 +281,9 @@ function validateContract(input) {
315
281
  const keys = Object.keys(obj);
316
282
  const unknownKeys = keys.filter((k) => !KNOWN_KEYS.has(k));
317
283
  const hasKnownKey = keys.some((k) => KNOWN_KEYS.has(k));
318
- const objectValuedUnknown = unknownKeys.filter((k) => isObject2(obj[k]));
284
+ const objectValuedUnknown = unknownKeys.filter(
285
+ (k) => isObject2(obj[k]) && !SECTION_KEYS.includes(k)
286
+ );
319
287
  if (!hasKnownKey && objectValuedUnknown.length > 0) {
320
288
  errors.push({
321
289
  path: name,
@@ -325,9 +293,9 @@ function validateContract(input) {
325
293
  continue;
326
294
  }
327
295
  for (const key of unknownKeys) {
328
- warnings.push({
296
+ errors.push({
329
297
  path: `${name}.${key}`,
330
- message: `Unknown contract key "${key}" is ignored`,
298
+ message: SECTION_KEYS.includes(key) ? `Contract section "${key}" is not enforced: the validate transformer reads only "events" and "schema". Put the rule into "schema" (a JSON Schema for the whole event), for example "schema": { "properties": { "${key}": { ... } } }.` : `Unknown contract key "${key}" is not supported. Known keys: ${[...KNOWN_KEYS].join(", ")}.`,
331
299
  code: "UNKNOWN_CONTRACT_KEY"
332
300
  });
333
301
  }
@@ -361,18 +329,6 @@ function validateContract(input) {
361
329
  });
362
330
  }
363
331
  }
364
- for (const key of SECTION_KEYS) {
365
- if (key in obj) {
366
- if (typeof obj[key] !== "object" || obj[key] === null) {
367
- errors.push({
368
- path: `${name}.${key}`,
369
- message: `Section "${key}" must be a JSON Schema object`,
370
- value: obj[key],
371
- code: "INVALID_SECTION"
372
- });
373
- }
374
- }
375
- }
376
332
  if (obj.events !== void 0) {
377
333
  if (typeof obj.events !== "object" || obj.events === null) {
378
334
  errors.push({
@@ -481,12 +437,17 @@ import {
481
437
  ENV_MARKER_PREFIX as ENV_MARKER_PREFIX2,
482
438
  getByPath,
483
439
  getRouteGraph,
484
- isObject as isObject5,
440
+ isObject as isObject6,
485
441
  REF_CONTRACT,
486
442
  resolveContracts,
443
+ SECRET_MARKER_PREFIX as SECRET_MARKER_PREFIX2,
487
444
  validateStepEntry
488
445
  } from "@walkeros/core";
489
- import { schemas as schemas3, validateFlowStructure } from "@walkeros/core/dev";
446
+ import {
447
+ checkStepKeys,
448
+ schemas as schemas3,
449
+ validateFlowStructure as validateFlowStructure2
450
+ } from "@walkeros/core/dev";
490
451
  import {
491
452
  validateEventAgainstContract
492
453
  } from "@walkeros/transformer-validate";
@@ -675,14 +636,12 @@ function resolutionCode(error) {
675
636
  }
676
637
 
677
638
  // src/commands/validate/validators/settings.ts
678
- import * as fs8 from "fs";
679
- import * as path2 from "path";
680
639
  import Ajv from "ajv";
681
640
  import {
641
+ createLogger,
682
642
  ENV_MARKER_PREFIX,
683
- fetchPackage,
684
643
  getErrorMessage as getErrorMessage3,
685
- isObject as isObject4,
644
+ isObject as isObject5,
686
645
  REF_CODE_PREFIX,
687
646
  REF_STORE,
688
647
  SECRET_MARKER_PREFIX
@@ -728,15 +687,191 @@ function resolveExportName(flow, kind, id) {
728
687
 
729
688
  // src/core/step-packages.ts
730
689
  import { packageNameToVariable } from "@walkeros/core";
690
+ function getFlowSection(flow, section) {
691
+ switch (section) {
692
+ case "sources":
693
+ return flow.sources;
694
+ case "destinations":
695
+ return flow.destinations;
696
+ case "transformers":
697
+ return flow.transformers;
698
+ case "stores":
699
+ return flow.stores;
700
+ }
701
+ }
702
+ function isLocalPath(spec) {
703
+ return spec.startsWith(".") || spec.startsWith("/");
704
+ }
731
705
  function parsePackageSpec(spec) {
732
706
  const at = spec.lastIndexOf("@");
733
707
  if (at <= 0) return { name: spec };
734
708
  const version = spec.slice(at + 1);
735
709
  return version ? { name: spec.slice(0, at), version } : { name: spec.slice(0, at) };
736
710
  }
711
+ function detectStepPackages(flowSettings, section) {
712
+ const packages = /* @__PURE__ */ new Set();
713
+ const steps = getFlowSection(flowSettings, section);
714
+ if (steps) {
715
+ for (const [, stepConfig] of Object.entries(steps)) {
716
+ if (typeof stepConfig !== "object" || stepConfig === null) continue;
717
+ if (typeof stepConfig.package === "string") {
718
+ packages.add(stepConfig.package);
719
+ }
720
+ }
721
+ }
722
+ return packages;
723
+ }
724
+ function collectAllStepPackages(flowSettings) {
725
+ const allPackages = /* @__PURE__ */ new Set();
726
+ const sections = [
727
+ "sources",
728
+ "destinations",
729
+ "transformers",
730
+ "stores"
731
+ ];
732
+ for (const section of sections) {
733
+ for (const pkg of detectStepPackages(flowSettings, section)) {
734
+ allPackages.add(pkg);
735
+ }
736
+ }
737
+ return allPackages;
738
+ }
739
+ function applyStepPackages(flowSettings, packages, logger) {
740
+ const stepPackages = collectAllStepPackages(flowSettings);
741
+ const originalPins = /* @__PURE__ */ new Map();
742
+ const inlineSeen = /* @__PURE__ */ new Map();
743
+ const rewriteSteps = (from, to) => {
744
+ for (const section of [
745
+ "sources",
746
+ "destinations",
747
+ "transformers",
748
+ "stores"
749
+ ]) {
750
+ const steps = getFlowSection(flowSettings, section);
751
+ if (!steps) continue;
752
+ for (const step of Object.values(steps)) {
753
+ if (step.package === from) {
754
+ step.package = to;
755
+ }
756
+ }
757
+ }
758
+ };
759
+ for (const pkg of stepPackages) {
760
+ if (isLocalPath(pkg)) {
761
+ const varName = packageNameToVariable(pkg);
762
+ if (!packages[varName]) {
763
+ packages[varName] = {
764
+ path: pkg
765
+ };
766
+ }
767
+ rewriteSteps(pkg, varName);
768
+ continue;
769
+ }
770
+ const { name, version } = parsePackageSpec(pkg);
771
+ if (!originalPins.has(name)) {
772
+ const entry = packages[name];
773
+ originalPins.set(
774
+ name,
775
+ entry?.version !== void 0 || entry?.path !== void 0
776
+ );
777
+ }
778
+ const hasBundlePin = originalPins.get(name) === true;
779
+ if (name !== pkg) {
780
+ rewriteSteps(pkg, name);
781
+ }
782
+ if (version && !hasBundlePin) {
783
+ const seen = inlineSeen.get(name);
784
+ if (seen !== void 0 && seen !== version) {
785
+ throw new Error(
786
+ `Conflicting inline versions for ${name}: "${seen}" and "${version}" are declared by different steps. Pin one version in config.bundle.packages.`
787
+ );
788
+ }
789
+ inlineSeen.set(name, version);
790
+ }
791
+ const existing = packages[name];
792
+ if (!existing) {
793
+ packages[name] = version ? { version } : {};
794
+ } else if (version && !existing.path) {
795
+ if (!existing.version) {
796
+ existing.version = version;
797
+ } else if (existing.version !== version) {
798
+ logger.warn(
799
+ `Package ${name}: config.bundle.packages pins ${existing.version}; a step declares ${version} inline. Using the bundle pin.`
800
+ );
801
+ }
802
+ }
803
+ }
804
+ }
805
+ var KIND_TO_SECTION = {
806
+ source: "sources",
807
+ transformer: "transformers",
808
+ destination: "destinations",
809
+ store: "stores"
810
+ };
811
+ function resolveStepPackage(flow, kind, id, logger) {
812
+ const normalizedFlow = structuredClone(flow);
813
+ const packages = structuredClone(
814
+ normalizedFlow.config?.bundle?.packages ?? {}
815
+ );
816
+ applyStepPackages(normalizedFlow, packages, logger);
817
+ const bucket = getFlowSection(normalizedFlow, KIND_TO_SECTION[kind]);
818
+ const step = bucket?.[id];
819
+ if (!step) {
820
+ const available = Object.keys(bucket ?? {}).join(", ") || "(none)";
821
+ throw new Error(
822
+ `${kind} "${id}" not found in flow. Available: ${available}`
823
+ );
824
+ }
825
+ if (typeof step.package !== "string") {
826
+ throw new Error(
827
+ `${kind}.${id} has no "package" (inline code cannot be set up).`
828
+ );
829
+ }
830
+ const declared = getFlowSection(flow, KIND_TO_SECTION[kind])?.[id]?.package;
831
+ return {
832
+ packageName: step.package,
833
+ label: declared !== void 0 && isLocalPath(declared) ? declared : step.package,
834
+ spec: packages[step.package] ?? {},
835
+ overrides: normalizedFlow.config?.bundle?.overrides ?? {},
836
+ normalizedFlow
837
+ };
838
+ }
839
+
840
+ // src/core/package-info.ts
841
+ import * as fs8 from "fs";
842
+ import * as path2 from "path";
843
+ import { fetchPackage, isObject as isObject4, parseWalkerOSJson } from "@walkeros/core";
844
+ function readJson(file) {
845
+ return JSON.parse(fs8.readFileSync(file, "utf-8"));
846
+ }
847
+ async function readStepPackageInfo(resolved, options) {
848
+ const { packageName, spec } = resolved;
849
+ if (spec.path === void 0)
850
+ return fetchPackage(packageName, {
851
+ ...spec.version ? { version: spec.version } : {},
852
+ client: options.client
853
+ });
854
+ if (options.configDir === void 0)
855
+ throw new Error(
856
+ "it is a local path package and the input is not a file, so there is no directory to read it from"
857
+ );
858
+ const root = path2.isAbsolute(spec.path) ? spec.path : path2.resolve(options.configDir, spec.path);
859
+ const file = [
860
+ path2.join(root, "dist", "walkerOS.json"),
861
+ path2.join(root, "walkerOS.json")
862
+ ].find((candidate) => fs8.existsSync(candidate));
863
+ if (!file) throw new Error(`no walkerOS.json under ${root}`);
864
+ const meta = readJson(file);
865
+ if (!isObject4(meta)) throw new Error(`${file} is not a JSON object`);
866
+ const pkgFile = path2.join(root, "package.json");
867
+ const pkg = fs8.existsSync(pkgFile) ? readJson(pkgFile) : void 0;
868
+ const version = isObject4(pkg) && typeof pkg.version === "string" ? pkg.version : void 0;
869
+ return { ...parseWalkerOSJson(meta), ...version ? { version } : {} };
870
+ }
737
871
 
738
872
  // src/commands/validate/validators/settings.ts
739
- var CLIENT_HEADER = "walkeros-cli/4.8.1";
873
+ var CLIENT_HEADER = "walkeros-cli/4.8.3-next-1793115089237";
874
+ var LOGGER = createLogger();
740
875
  function createSettingsContext(configDir) {
741
876
  return { configDir, cache: /* @__PURE__ */ new Map(), compiled: /* @__PURE__ */ new Map() };
742
877
  }
@@ -747,7 +882,7 @@ function selectSettingsSchema(pkg, packageLabel, exportName) {
747
882
  pkg.exportSchemas,
748
883
  exportName
749
884
  ) ? pkg.exportSchemas[exportName] : void 0;
750
- if (!isObject4(entry))
885
+ if (!isObject5(entry))
751
886
  return {
752
887
  ok: false,
753
888
  reason: `${packageLabel} has no export "${exportName}"`
@@ -775,7 +910,7 @@ function valueAt(root, segments) {
775
910
  let current = root;
776
911
  for (const segment of segments) {
777
912
  if (Array.isArray(current)) current = current[Number(segment)];
778
- else if (isObject4(current)) current = current[segment];
913
+ else if (isObject5(current)) current = current[segment];
779
914
  else return void 0;
780
915
  }
781
916
  return current;
@@ -790,7 +925,7 @@ function prepareSettings(settings) {
790
925
  const walk = (value, segments) => {
791
926
  if (Array.isArray(value))
792
927
  return value.map((item, index) => walk(item, [...segments, `${index}`]));
793
- if (isObject4(value))
928
+ if (isObject5(value))
794
929
  return Object.fromEntries(
795
930
  Object.entries(value).map(([key, item]) => [
796
931
  key,
@@ -834,62 +969,9 @@ function prepareSettings(settings) {
834
969
  function isUnder(segments, prefix) {
835
970
  return prefix.every((segment, index) => segments[index] === segment);
836
971
  }
837
- function bundlePin(rawFlow, name) {
838
- const config = isObject4(rawFlow) ? rawFlow.config : void 0;
839
- const bundle = isObject4(config) ? config.bundle : void 0;
840
- const packages = isObject4(bundle) ? bundle.packages : void 0;
841
- const pin = isObject4(packages) ? packages[name] : void 0;
842
- if (!isObject4(pin)) return {};
843
- return {
844
- ...typeof pin.version === "string" ? { version: pin.version } : {},
845
- ...typeof pin.path === "string" ? { path: pin.path } : {}
846
- };
847
- }
848
- function packageSource(spec, rawFlow) {
849
- if (spec.startsWith(".") || spec.startsWith("/"))
850
- return { name: spec, localPath: spec };
851
- const { name, version } = parsePackageSpec(spec);
852
- const pin = bundlePin(rawFlow, name);
853
- if (pin.path) return { name, localPath: pin.path };
854
- const pinned = pin.version ?? version;
855
- return pinned ? { name, version: pinned } : { name };
856
- }
857
- function readJson(file) {
858
- return JSON.parse(fs8.readFileSync(file, "utf-8"));
859
- }
860
- function readLocalSchema(source, configDir) {
861
- const localPath = source.localPath ?? "";
862
- const root = path2.isAbsolute(localPath) ? localPath : path2.resolve(configDir, localPath);
863
- const file = [
864
- path2.join(root, "dist", "walkerOS.json"),
865
- path2.join(root, "walkerOS.json")
866
- ].find((candidate) => fs8.existsSync(candidate));
867
- if (!file) throw new Error(`no walkerOS.json under ${root}`);
868
- const meta = readJson(file);
869
- const pkgFile = path2.join(root, "package.json");
870
- const pkg = fs8.existsSync(pkgFile) ? readJson(pkgFile) : void 0;
871
- const schemas5 = isObject4(meta) ? meta.schemas : void 0;
872
- const exportSchemas = isObject4(meta) ? meta.exportSchemas : void 0;
873
- const declared = isObject4(meta) && isObject4(meta.$meta) ? meta.$meta.exports : void 0;
874
- const version = isObject4(pkg) && typeof pkg.version === "string" ? pkg.version : void 0;
875
- return {
876
- ...version ? { version } : {},
877
- settings: isObject4(schemas5) ? schemas5.settings : void 0,
878
- ...isObject4(exportSchemas) ? { exportSchemas } : {},
879
- ...isObject4(declared) ? { exports: Object.keys(declared) } : {}
880
- };
881
- }
882
- async function loadSchema(source, context) {
883
- if (source.localPath !== void 0) {
884
- const configDir = context.configDir;
885
- if (configDir === void 0)
886
- throw new Error(
887
- "it is a local path package and the input is not a file, so there is no directory to read it from"
888
- );
889
- return readLocalSchema(source, configDir);
890
- }
891
- const info = await fetchPackage(source.name, {
892
- ...source.version ? { version: source.version } : {},
972
+ async function loadSchema(resolved, context) {
973
+ const info = await readStepPackageInfo(resolved, {
974
+ configDir: context.configDir,
893
975
  client: CLIENT_HEADER
894
976
  });
895
977
  return {
@@ -900,7 +982,7 @@ async function loadSchema(source, context) {
900
982
  };
901
983
  }
902
984
  function compileSettings(settings) {
903
- if (!isObject4(settings)) return void 0;
985
+ if (!isObject5(settings)) return void 0;
904
986
  const ajv = new Ajv({ allErrors: true, validateFormats: false });
905
987
  try {
906
988
  return { ok: true, validate: ajv.compile(settings) };
@@ -908,26 +990,26 @@ function compileSettings(settings) {
908
990
  return { ok: false, message: getErrorMessage3(error) };
909
991
  }
910
992
  }
911
- function sourceKey(source) {
912
- return source.localPath ? `path:${source.localPath}` : `${source.name}@${source.version ?? "latest"}`;
993
+ function sourceKey({ packageName, spec }) {
994
+ return spec.path !== void 0 ? `path:${spec.path}` : `${packageName}@${spec.version ?? "latest"}`;
913
995
  }
914
- function cachedSchema(source, context) {
915
- const key = sourceKey(source);
996
+ function cachedSchema(resolved, context) {
997
+ const key = sourceKey(resolved);
916
998
  let pending = context.cache.get(key);
917
999
  if (!pending) {
918
- pending = loadSchema(source, context);
1000
+ pending = loadSchema(resolved, context);
919
1001
  context.cache.set(key, pending);
920
1002
  }
921
1003
  return pending;
922
1004
  }
923
- function cachedCompile(source, exportName, settings, context) {
924
- const key = `${sourceKey(source)}#${exportName ?? ""}`;
1005
+ function cachedCompile(resolved, exportName, settings, context) {
1006
+ const key = `${sourceKey(resolved)}#${exportName ?? ""}`;
925
1007
  if (context.compiled.has(key)) return context.compiled.get(key);
926
1008
  const compiled = compileSettings(settings);
927
1009
  context.compiled.set(key, compiled);
928
1010
  return compiled;
929
1011
  }
930
- async function checkStepSettings(target, resolvedFlow, rawFlow, check, context) {
1012
+ async function checkStepSettings(target, resolvedFlow, check, context) {
931
1013
  const at = `flows.${target.flow}.${target.section}.${target.key}`;
932
1014
  const outcome = { findings: [], skipped: [], deferred: [] };
933
1015
  const spec = typeof target.entry.package === "string" ? target.entry.package : "";
@@ -940,33 +1022,51 @@ async function checkStepSettings(target, resolvedFlow, rawFlow, check, context)
940
1022
  });
941
1023
  return outcome;
942
1024
  }
943
- const source = packageSource(spec, rawFlow);
1025
+ let resolved;
1026
+ try {
1027
+ resolved = resolveStepPackage(
1028
+ resolvedFlow,
1029
+ SECTION_KIND[target.section],
1030
+ target.key,
1031
+ LOGGER
1032
+ );
1033
+ } catch (error) {
1034
+ outcome.skipped.push({
1035
+ path: at,
1036
+ check,
1037
+ reason: `Schema for ${spec} could not be loaded: ${getErrorMessage3(error)}`,
1038
+ code: "SCHEMA_UNAVAILABLE"
1039
+ });
1040
+ return outcome;
1041
+ }
1042
+ const { label } = resolved;
1043
+ const pinned = resolved.spec.path === void 0 ? resolved.spec.version : void 0;
944
1044
  let schema;
945
1045
  try {
946
- schema = await cachedSchema(source, context);
1046
+ schema = await cachedSchema(resolved, context);
947
1047
  } catch (error) {
948
1048
  outcome.skipped.push({
949
1049
  path: at,
950
1050
  check,
951
- reason: `Schema for ${source.name}${source.version ? `@${source.version}` : ""} could not be loaded: ${getErrorMessage3(error)}`,
1051
+ reason: `Schema for ${label}${pinned ? `@${pinned}` : ""} could not be loaded: ${getErrorMessage3(error)}`,
952
1052
  code: "SCHEMA_UNAVAILABLE"
953
1053
  });
954
1054
  return outcome;
955
1055
  }
956
1056
  outcome.checked = {
957
1057
  path: at,
958
- package: source.name,
1058
+ package: label,
959
1059
  ...schema.version ? { version: schema.version } : {}
960
1060
  };
961
1061
  const { exportName } = resolveExportName(
962
- resolvedFlow,
1062
+ resolved.normalizedFlow,
963
1063
  SECTION_KIND[target.section],
964
1064
  target.key
965
1065
  );
966
- const version = schema.version ?? source.version;
1066
+ const version = schema.version ?? pinned;
967
1067
  const selection = selectSettingsSchema(
968
1068
  schema,
969
- version ? `${source.name}@${version}` : source.name,
1069
+ version ? `${label}@${version}` : label,
970
1070
  exportName
971
1071
  );
972
1072
  if (!selection.ok) {
@@ -979,7 +1079,7 @@ async function checkStepSettings(target, resolvedFlow, rawFlow, check, context)
979
1079
  return outcome;
980
1080
  }
981
1081
  const compiled = cachedCompile(
982
- source,
1082
+ resolved,
983
1083
  exportName,
984
1084
  selection.settings,
985
1085
  context
@@ -988,7 +1088,7 @@ async function checkStepSettings(target, resolvedFlow, rawFlow, check, context)
988
1088
  outcome.skipped.push({
989
1089
  path: at,
990
1090
  check,
991
- reason: `Package ${source.name} has no settings schema`,
1091
+ reason: `Package ${label} has no settings schema`,
992
1092
  code: "NO_SETTINGS_SCHEMA"
993
1093
  });
994
1094
  return outcome;
@@ -997,14 +1097,14 @@ async function checkStepSettings(target, resolvedFlow, rawFlow, check, context)
997
1097
  outcome.skipped.push({
998
1098
  path: at,
999
1099
  check,
1000
- reason: `The settings schema of ${source.name} cannot be compiled: ${compiled.message}`,
1100
+ reason: `The settings schema of ${label} cannot be compiled: ${compiled.message}`,
1001
1101
  code: "SCHEMA_UNAVAILABLE"
1002
1102
  });
1003
1103
  return outcome;
1004
1104
  }
1005
1105
  const validate2 = compiled.validate;
1006
1106
  const step = stepOf(resolvedFlow, target.section, target.key);
1007
- const config = isObject4(step?.config) ? step.config : {};
1107
+ const config = isObject5(step?.config) ? step.config : {};
1008
1108
  const prepared = prepareSettings(config.settings ?? {});
1009
1109
  const base = `${at}.config.settings`;
1010
1110
  for (const { segments, reference } of prepared.deferred) {
@@ -1051,7 +1151,9 @@ var { validateFlowConfig: validateFlowConfig2 } = schemas3;
1051
1151
  var DEPRECATED_PACKAGES = {
1052
1152
  "@walkeros/store-memory": "has been removed. Use the built-in cache by omitting cache.store, or remove the store declaration if it was only used as a cache target."
1053
1153
  };
1054
- var OPEN_STEP_KINDS = [
1154
+ var STEP_KINDS = [
1155
+ ["sources", "Source"],
1156
+ ["transformers", "Transformer"],
1055
1157
  ["destinations", "Destination"],
1056
1158
  ["stores", "Store"]
1057
1159
  ];
@@ -1083,24 +1185,22 @@ async function validateFlowWithPackages(input, options = {}) {
1083
1185
  continue;
1084
1186
  }
1085
1187
  for (const section of ENTRY_SECTIONS) {
1086
- const steps = isObject5(rawFlow[section]) ? rawFlow[section] : {};
1188
+ const steps = isObject6(rawFlow[section]) ? rawFlow[section] : {};
1087
1189
  for (const [key, entry] of Object.entries(steps)) {
1088
- if (!isObject5(entry) || entry.package === void 0) continue;
1190
+ if (!isObject6(entry) || entry.package === void 0) continue;
1089
1191
  const target = { flow: name, section, key, entry };
1090
1192
  pending.push(
1091
- checkStepSettings(
1092
- target,
1093
- flow,
1094
- rawFlow,
1095
- "flow:package-settings",
1096
- context
1097
- )
1193
+ checkStepSettings(target, flow, "flow:package-settings", context)
1098
1194
  );
1099
1195
  }
1100
1196
  }
1101
1197
  }
1102
1198
  for (const outcome of await Promise.all(pending)) {
1103
- result.warnings.push(...outcome.findings);
1199
+ for (const finding of outcome.findings) {
1200
+ if (finding.keyword === "additionalProperties")
1201
+ result.errors.push(finding);
1202
+ else result.warnings.push(finding);
1203
+ }
1104
1204
  run.skipped.push(...outcome.skipped);
1105
1205
  deferred.push(...outcome.deferred);
1106
1206
  if (outcome.checked) packages.push(outcome.checked);
@@ -1108,6 +1208,7 @@ async function validateFlowWithPackages(input, options = {}) {
1108
1208
  result.details.scope = describeScope(scope, run.checks);
1109
1209
  result.details.deferred = [...result.details.deferred ?? [], ...deferred];
1110
1210
  if (packages.length > 0) result.details.packages = packages;
1211
+ result.valid = result.errors.length === 0;
1111
1212
  return result;
1112
1213
  }
1113
1214
  function runFlowChecks(input, options) {
@@ -1144,9 +1245,9 @@ function runFlowChecks(input, options) {
1144
1245
  };
1145
1246
  }
1146
1247
  errors.push(...scope.errors);
1147
- const config = isObject5(input) ? input : {};
1248
+ const config = isObject6(input) ? input : {};
1148
1249
  const flowsValue = config.flows;
1149
- const flows = isObject5(flowsValue) ? flowsValue : void 0;
1250
+ const flows = isObject6(flowsValue) ? flowsValue : void 0;
1150
1251
  const allFlows = scope.allFlows;
1151
1252
  const inScope = (path4) => {
1152
1253
  const flow = flowOfPath(path4, allFlows);
@@ -1166,8 +1267,13 @@ function runFlowChecks(input, options) {
1166
1267
  for (const issue of coreResult.errors) {
1167
1268
  const path4 = issue.path || "root";
1168
1269
  if (!inScope(path4)) continue;
1169
- if (path4 === "contract" && contractErrors > 0) continue;
1170
- errors.push({ path: path4, message: issue.message, code: "SCHEMA_VALIDATION" });
1270
+ if ((path4 === "contract" || path4.startsWith("contract.")) && contractErrors > 0)
1271
+ continue;
1272
+ errors.push({
1273
+ path: path4,
1274
+ message: issue.message,
1275
+ code: issue.code ?? "SCHEMA_VALIDATION"
1276
+ });
1171
1277
  }
1172
1278
  for (const issue of coreResult.warnings) {
1173
1279
  const path4 = issue.path || "root";
@@ -1184,13 +1290,13 @@ function runFlowChecks(input, options) {
1184
1290
  checks.push("flow:steps");
1185
1291
  for (const flowName of scope.flows) {
1186
1292
  const flowValue = flows?.[flowName];
1187
- if (!isObject5(flowValue)) continue;
1293
+ if (!isObject6(flowValue)) continue;
1188
1294
  const transformersValue = flowValue.transformers;
1189
- if (isObject5(transformersValue)) {
1295
+ if (isObject6(transformersValue)) {
1190
1296
  for (const [name, transformerValue] of Object.entries(
1191
1297
  transformersValue
1192
1298
  )) {
1193
- if (!isObject5(transformerValue)) continue;
1299
+ if (!isObject6(transformerValue)) continue;
1194
1300
  const result2 = validateStepEntry(transformerValue, "Transformer");
1195
1301
  if (!result2.ok) {
1196
1302
  errors.push({
@@ -1201,20 +1307,13 @@ function runFlowChecks(input, options) {
1201
1307
  }
1202
1308
  }
1203
1309
  }
1204
- for (const [section, kind] of OPEN_STEP_KINDS) {
1310
+ for (const [section, kind] of STEP_KINDS) {
1205
1311
  const steps = flowValue[section];
1206
- if (!isObject5(steps)) continue;
1312
+ if (!isObject6(steps)) continue;
1207
1313
  for (const [name, step] of Object.entries(steps)) {
1208
- if (!isObject5(step)) continue;
1314
+ if (!isObject6(step)) continue;
1209
1315
  const at = `flows.${flowName}.${section}.${name}`;
1210
- for (const key of unknownStepKeys(step, kind)) {
1211
- warnings.push({
1212
- path: `${at}.${key}`,
1213
- message: `Unknown key "${key}" on ${kind} is ignored by the runtime`,
1214
- suggestion: "Remove the key, or move it to where it belongs.",
1215
- code: "UNKNOWN_KEY"
1216
- });
1217
- }
1316
+ errors.push(...checkStepKeys(step, kind, at));
1218
1317
  const pkg = step.package;
1219
1318
  if (typeof pkg === "string" && pkg in DEPRECATED_PACKAGES) {
1220
1319
  warnings.push({
@@ -1225,6 +1324,7 @@ function runFlowChecks(input, options) {
1225
1324
  }
1226
1325
  }
1227
1326
  }
1327
+ checkWebLoggerFormat(flowName, flowValue, errors);
1228
1328
  }
1229
1329
  if (flows) {
1230
1330
  details.flowNames = allFlows;
@@ -1234,15 +1334,15 @@ function runFlowChecks(input, options) {
1234
1334
  let totalPackageCount = 0;
1235
1335
  for (const flowName of scope.flows) {
1236
1336
  const flowValue = flows?.[flowName];
1237
- if (!isObject5(flowValue)) continue;
1337
+ if (!isObject6(flowValue)) continue;
1238
1338
  const flowConfig = flowValue.config;
1239
- if (!isObject5(flowConfig)) continue;
1339
+ if (!isObject6(flowConfig)) continue;
1240
1340
  const bundle = flowConfig.bundle;
1241
- if (!isObject5(bundle)) continue;
1341
+ if (!isObject6(bundle)) continue;
1242
1342
  const packages = bundle.packages;
1243
- if (!isObject5(packages)) continue;
1343
+ if (!isObject6(packages)) continue;
1244
1344
  for (const [pkgName, pkgConfigValue] of Object.entries(packages)) {
1245
- if (!isObject5(pkgConfigValue)) continue;
1345
+ if (!isObject6(pkgConfigValue)) continue;
1246
1346
  if (!pkgConfigValue.version && !pkgConfigValue.path) {
1247
1347
  warnings.push({
1248
1348
  path: `flows.${flowName}.config.bundle.packages.${pkgName}`,
@@ -1288,7 +1388,7 @@ function runFlowChecks(input, options) {
1288
1388
  }
1289
1389
  };
1290
1390
  perFlow(["flow:structure"], (name, flow, file) => {
1291
- const structure = validateFlowStructure({
1391
+ const structure = validateFlowStructure2({
1292
1392
  ...file,
1293
1393
  flows: { [name]: flow }
1294
1394
  });
@@ -1330,13 +1430,13 @@ function runFlowChecks(input, options) {
1330
1430
  warnings,
1331
1431
  options.strict === true,
1332
1432
  skipped,
1333
- isObject5(resolvedConfig) && isObject5(resolvedConfig.settings) ? resolvedConfig.settings : void 0
1433
+ isObject6(resolvedConfig) && isObject6(resolvedConfig.settings) ? resolvedConfig.settings : void 0
1334
1434
  );
1335
1435
  }
1336
1436
  for (const [destName, dest] of Object.entries(flow.destinations || {})) {
1337
- if (!isObject5(dest.config)) continue;
1437
+ if (!isObject6(dest.config)) continue;
1338
1438
  const mapping = dest.config.mapping;
1339
- if (!isObject5(mapping)) continue;
1439
+ if (!isObject6(mapping)) continue;
1340
1440
  for (const key of Object.keys(mapping)) {
1341
1441
  if (key.includes(".") && !key.includes(" ")) {
1342
1442
  const parts = key.split(".");
@@ -1396,16 +1496,31 @@ function checkResolvedWindowCollector(name, raw, flow, errors, deferred) {
1396
1496
  code: "SCHEMA_VALIDATION"
1397
1497
  });
1398
1498
  }
1399
- function unknownStepKeys(step, kind) {
1400
- const unknown = [];
1401
- const rest = { ...step };
1402
- for (; ; ) {
1403
- const verdict = validateStepEntry(rest, kind);
1404
- if (verdict.code !== "UNKNOWN_KEY" || verdict.key === void 0) break;
1405
- unknown.push(verdict.key);
1406
- Reflect.deleteProperty(rest, verdict.key);
1499
+ function checkWebLoggerFormat(flowName, flow, errors) {
1500
+ if (!isObject6(flow.config) || flow.config.platform !== "web") return;
1501
+ const at = `flows.${flowName}`;
1502
+ const loggers = [];
1503
+ if (isObject6(flow.collector))
1504
+ loggers.push([`${at}.collector.logger`, flow.collector.logger]);
1505
+ for (const [section] of STEP_KINDS) {
1506
+ const steps = flow[section];
1507
+ if (!isObject6(steps)) continue;
1508
+ for (const [name, step] of Object.entries(steps)) {
1509
+ if (isObject6(step) && isObject6(step.config))
1510
+ loggers.push([
1511
+ `${at}.${section}.${name}.config.logger`,
1512
+ step.config.logger
1513
+ ]);
1514
+ }
1515
+ }
1516
+ for (const [path4, logger] of loggers) {
1517
+ if (!isObject6(logger) || logger.format === void 0) continue;
1518
+ errors.push({
1519
+ path: `${path4}.format`,
1520
+ message: "logger.format applies to server flows only: a web flow logs to the browser console, which has no output format. Remove it.",
1521
+ code: "WEB_LOGGER_FORMAT"
1522
+ });
1407
1523
  }
1408
- return unknown;
1409
1524
  }
1410
1525
  function routeTargets(spec) {
1411
1526
  if (spec === void 0) return [];
@@ -1504,21 +1619,21 @@ function isStepOut(value) {
1504
1619
  return Array.isArray(value) && value.every((entry) => Array.isArray(entry) && typeof entry[0] === "string");
1505
1620
  }
1506
1621
  function returnedEvents(value) {
1507
- if (isObject5(value)) return [isObject5(value.event) ? value.event : value];
1622
+ if (isObject6(value)) return [isObject6(value.event) ? value.event : value];
1508
1623
  if (Array.isArray(value)) return value.flatMap(returnedEvents);
1509
1624
  return [];
1510
1625
  }
1511
1626
  function outEvents(out) {
1512
1627
  if (isStepOut(out)) {
1513
1628
  return out.flatMap(([head, first]) => {
1514
- if (head === "elb") return isObject5(first) ? [first] : [];
1629
+ if (head === "elb") return isObject6(first) ? [first] : [];
1515
1630
  if (head === "return") return returnedEvents(first);
1516
1631
  return [];
1517
1632
  });
1518
1633
  }
1519
1634
  if (Array.isArray(out) || typeof out === "string")
1520
1635
  return out.length > 0 ? [out] : [];
1521
- return isObject5(out) && Object.keys(out).length > 0 ? [out] : [];
1636
+ return isObject6(out) && Object.keys(out).length > 0 ? [out] : [];
1522
1637
  }
1523
1638
  function hasComparableOut(out) {
1524
1639
  return outEvents(out).length > 0;
@@ -1560,7 +1675,7 @@ function routeAt(spec, path4) {
1560
1675
  for (const key of path4) {
1561
1676
  if (typeof key === "number")
1562
1677
  current = Array.isArray(current) ? current[key] : void 0;
1563
- else current = isObject5(current) ? current[key] : void 0;
1678
+ else current = isObject6(current) ? current[key] : void 0;
1564
1679
  }
1565
1680
  return current;
1566
1681
  }
@@ -1585,7 +1700,7 @@ function lintRoute(spec, position, known, errors, warnings) {
1585
1700
  if (node.stop && !node.match && node.kind !== "many") {
1586
1701
  const self = routeAt(spec, node.path);
1587
1702
  const list = routeAt(spec, node.path.slice(0, -1));
1588
- if (isObject5(self) && self.stop === true && typeof last === "number" && Array.isArray(list) && last < list.length - 1 && once(`stop:${where(node.path)}`)) {
1703
+ if (isObject6(self) && self.stop === true && typeof last === "number" && Array.isArray(list) && last < list.length - 1 && once(`stop:${where(node.path)}`)) {
1589
1704
  const at = where(node.path);
1590
1705
  warnings.push({
1591
1706
  path: at,
@@ -1633,6 +1748,12 @@ function lintRoute(spec, position, known, errors, warnings) {
1633
1748
  }
1634
1749
  }
1635
1750
  }
1751
+ function hasRuntimeValue(value) {
1752
+ if (typeof value === "string")
1753
+ return value.includes(ENV_MARKER_PREFIX2) || value.startsWith(SECRET_MARKER_PREFIX2) || /\$(?:env|secret)\./.test(value);
1754
+ if (Array.isArray(value)) return value.some(hasRuntimeValue);
1755
+ return isObject6(value) && Object.values(value).some(hasRuntimeValue);
1756
+ }
1636
1757
  var VALIDATE_PACKAGE = "@walkeros/transformer-validate";
1637
1758
  function isValidateStep(step) {
1638
1759
  return step.package === VALIDATE_PACKAGE;
@@ -1651,7 +1772,7 @@ function resolveStepContracts(entries, contract) {
1651
1772
  }
1652
1773
  const sources = [];
1653
1774
  for (const [index, entry] of entries.entries()) {
1654
- if (isObject5(entry)) {
1775
+ if (isObject6(entry)) {
1655
1776
  sources.push(entry);
1656
1777
  continue;
1657
1778
  }
@@ -1669,7 +1790,7 @@ function resolveStepContracts(entries, contract) {
1669
1790
  message: `contract "${match[1]}" is not defined in the root contract (defined: ${Object.keys(resolved).join(", ") || "none"})`
1670
1791
  };
1671
1792
  const rule = match[2] ? getByPath(resolved[match[1]], match[2]) : resolved[match[1]];
1672
- if (!isObject5(rule))
1793
+ if (!isObject6(rule))
1673
1794
  return {
1674
1795
  ok: false,
1675
1796
  index,
@@ -1680,7 +1801,7 @@ function resolveStepContracts(entries, contract) {
1680
1801
  return { ok: true, sources };
1681
1802
  }
1682
1803
  function checkValidateStepExamples(stepPath, step, contract, errors, warnings, strict, skipped, resolvedSettings) {
1683
- const settings = resolvedSettings ?? (isObject5(step.config) && isObject5(step.config.settings) ? step.config.settings : {});
1804
+ const settings = resolvedSettings ?? (isObject6(step.config) && isObject6(step.config.settings) ? step.config.settings : {});
1684
1805
  const contractPath = `${stepPath}.config.settings.contract`;
1685
1806
  if (settings.contract !== void 0 && !Array.isArray(settings.contract)) {
1686
1807
  if (step.examples)
@@ -1703,12 +1824,21 @@ function checkValidateStepExamples(stepPath, step, contract, errors, warnings, s
1703
1824
  }
1704
1825
  if (!step.examples) return;
1705
1826
  const contracts = resolution.sources;
1827
+ if (contracts.some(hasRuntimeValue)) {
1828
+ skipped?.push({
1829
+ path: stepPath,
1830
+ check: "flow:contract-examples",
1831
+ reason: "the contract uses a $env or $secret value, known only when the bundle builds or runs, so the examples cannot be judged statically",
1832
+ code: "CONTRACT_NOT_STATIC"
1833
+ });
1834
+ return;
1835
+ }
1706
1836
  const mode = settings.mode === "strict" ? "strict" : "pass";
1707
1837
  const format = settings.format === true;
1708
- const output = isObject5(settings.output) ? settings.output : {};
1838
+ const output = isObject6(settings.output) ? settings.output : {};
1709
1839
  const isValidPath = typeof output.isValid === "string" ? output.isValid : "source.valid";
1710
1840
  for (const [exName, example] of Object.entries(step.examples)) {
1711
- if (example.command || !isObject5(example.in)) continue;
1841
+ if (example.command || !isObject6(example.in)) continue;
1712
1842
  if (example.out === void 0) continue;
1713
1843
  const event = example.in;
1714
1844
  const verdict = validateEventAgainstContract(event, void 0, {
@@ -1746,14 +1876,14 @@ function checkValidateStepExamples(stepPath, step, contract, errors, warnings, s
1746
1876
  }
1747
1877
 
1748
1878
  // src/commands/validate/validators/mapping.ts
1749
- import { isObject as isObject6 } from "@walkeros/core";
1879
+ import { isObject as isObject7 } from "@walkeros/core";
1750
1880
  import { schemas as schemas4 } from "@walkeros/core/dev";
1751
1881
  var { RuleSchema } = schemas4.MappingSchemas;
1752
1882
  function isRule(value) {
1753
- return isObject6(value) && RuleSchema.safeParse(value).success;
1883
+ return isObject7(value) && RuleSchema.safeParse(value).success;
1754
1884
  }
1755
1885
  function isNestedActions(key, value) {
1756
- if (key.includes(" ") || !isObject6(value)) return false;
1886
+ if (key.includes(" ") || !isObject7(value)) return false;
1757
1887
  const rules = Object.values(value);
1758
1888
  return rules.length > 0 && rules.every(
1759
1889
  (rule) => Array.isArray(rule) ? rule.length > 0 && rule.every(isRule) : isRule(rule)
@@ -1763,7 +1893,7 @@ function validateMapping(input) {
1763
1893
  const errors = [];
1764
1894
  const warnings = [];
1765
1895
  const details = {};
1766
- if (!isObject6(input)) {
1896
+ if (!isObject7(input)) {
1767
1897
  errors.push({
1768
1898
  path: "root",
1769
1899
  message: "Mapping must be an object with event patterns as keys",
@@ -1852,7 +1982,6 @@ async function validateEntry(path4, flowConfig, options = {}) {
1852
1982
  const outcome = await checkStepSettings(
1853
1983
  target,
1854
1984
  resolution.flow,
1855
- file?.flows[target.flow],
1856
1985
  "entry:settings",
1857
1986
  context
1858
1987
  );
@@ -1909,6 +2038,7 @@ var VALIDATE_CODES = [
1909
2038
  "CONTRACT_VIOLATION",
1910
2039
  "MAPPING_DOT_KEY",
1911
2040
  "FLOW_REF_WARNING",
2041
+ "WEB_LOGGER_FORMAT",
1912
2042
  "FLOW_CYCLE",
1913
2043
  "VAR_CYCLE",
1914
2044
  // Structure (the bundler's own preflight, validateFlowStructure)
@@ -1917,7 +2047,11 @@ var VALIDATE_CODES = [
1917
2047
  "STORE_REFERENCE_NOT_FOUND",
1918
2048
  "STATE_STORE_UNKNOWN",
1919
2049
  "STATE_STORE_FILE",
1920
- "TRANSFORMER_MAPPING_NO_OP",
2050
+ "MAPPING_NO_OP",
2051
+ "MAPPING_VALUE_NO_OPERATOR",
2052
+ "MAPPING_VALUE_PRODUCERS",
2053
+ "BATCH_WITHOUT_PUSH_BATCH",
2054
+ "MALFORMED_REFERENCE",
1921
2055
  // Resolution (getFlowSettings, as the bundler resolves the flow)
1922
2056
  "UNRESOLVED_REFERENCE",
1923
2057
  "MISSING_ENV",
@@ -1934,7 +2068,6 @@ var VALIDATE_CODES = [
1934
2068
  "INVALID_TAGGING",
1935
2069
  "INVALID_SCHEMA",
1936
2070
  "INVALID_EXTENDS",
1937
- "INVALID_SECTION",
1938
2071
  "INVALID_EVENTS",
1939
2072
  "CIRCULAR_EXTENDS",
1940
2073
  "INVALID_ENTITY_KEY",
@@ -1988,7 +2121,7 @@ function inapplicableOptions(type, options) {
1988
2121
  }
1989
2122
  function validateContractInput(input) {
1990
2123
  if (!isFlowJson(input)) return validateContract(input);
1991
- const contract = isObject7(input) ? input.contract : void 0;
2124
+ const contract = isObject8(input) ? input.contract : void 0;
1992
2125
  if (contract === void 0) {
1993
2126
  return {
1994
2127
  valid: false,