@walkeros/cli 4.8.2 → 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.
- package/CHANGELOG.md +59 -3
- package/README.md +2 -2
- package/dist/cli.js +1320 -1318
- package/dist/dev.d.ts +51 -3
- package/dist/dev.js +186 -0
- package/dist/dev.js.map +1 -1
- package/dist/examples/README.md +12 -1
- package/dist/examples/contracts/app.json +261 -0
- package/dist/examples/contracts/base.json +708 -0
- package/dist/examples/contracts/ecommerce.json +963 -0
- package/dist/examples/contracts/leadgen.json +240 -0
- package/dist/examples/contracts/publisher.json +372 -0
- package/dist/examples/contracts/saas.json +229 -0
- package/dist/examples/contracts/travel.json +234 -0
- package/dist/examples/customers/README.md +4 -1
- package/dist/examples/flow-complete.json +40 -25
- package/dist/examples/flow-complete.md +5 -3
- package/dist/examples/index.js +42 -27
- package/dist/examples/index.js.map +1 -1
- package/dist/examples/shared/README.md +4 -0
- package/dist/index.d.ts +41 -41
- package/dist/index.js +161 -134
- package/dist/index.js.map +1 -1
- package/dist/validate.js +264 -132
- package/dist/validate.js.map +1 -1
- package/examples/README.md +12 -1
- package/examples/contracts/app.json +261 -0
- package/examples/contracts/base.json +708 -0
- package/examples/contracts/ecommerce.json +963 -0
- package/examples/contracts/leadgen.json +240 -0
- package/examples/contracts/publisher.json +372 -0
- package/examples/contracts/saas.json +229 -0
- package/examples/contracts/travel.json +234 -0
- package/examples/customers/README.md +4 -1
- package/examples/flow-complete.json +40 -25
- package/examples/flow-complete.md +5 -3
- package/examples/shared/README.md +4 -0
- package/package.json +30 -30
- package/dist/examples/test.html +0 -43
- package/dist/examples/web-serve.js +0 -25503
- package/examples/test.html +0 -43
- 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
|
|
5
|
+
import { isObject as isObject8 } from "@walkeros/core";
|
|
6
6
|
|
|
7
7
|
// src/core/cli-logger.ts
|
|
8
8
|
import chalk from "chalk";
|
|
@@ -437,7 +437,7 @@ import {
|
|
|
437
437
|
ENV_MARKER_PREFIX as ENV_MARKER_PREFIX2,
|
|
438
438
|
getByPath,
|
|
439
439
|
getRouteGraph,
|
|
440
|
-
isObject as
|
|
440
|
+
isObject as isObject6,
|
|
441
441
|
REF_CONTRACT,
|
|
442
442
|
resolveContracts,
|
|
443
443
|
SECRET_MARKER_PREFIX as SECRET_MARKER_PREFIX2,
|
|
@@ -636,14 +636,12 @@ function resolutionCode(error) {
|
|
|
636
636
|
}
|
|
637
637
|
|
|
638
638
|
// src/commands/validate/validators/settings.ts
|
|
639
|
-
import * as fs8 from "fs";
|
|
640
|
-
import * as path2 from "path";
|
|
641
639
|
import Ajv from "ajv";
|
|
642
640
|
import {
|
|
641
|
+
createLogger,
|
|
643
642
|
ENV_MARKER_PREFIX,
|
|
644
|
-
fetchPackage,
|
|
645
643
|
getErrorMessage as getErrorMessage3,
|
|
646
|
-
isObject as
|
|
644
|
+
isObject as isObject5,
|
|
647
645
|
REF_CODE_PREFIX,
|
|
648
646
|
REF_STORE,
|
|
649
647
|
SECRET_MARKER_PREFIX
|
|
@@ -689,15 +687,191 @@ function resolveExportName(flow, kind, id) {
|
|
|
689
687
|
|
|
690
688
|
// src/core/step-packages.ts
|
|
691
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
|
+
}
|
|
692
705
|
function parsePackageSpec(spec) {
|
|
693
706
|
const at = spec.lastIndexOf("@");
|
|
694
707
|
if (at <= 0) return { name: spec };
|
|
695
708
|
const version = spec.slice(at + 1);
|
|
696
709
|
return version ? { name: spec.slice(0, at), version } : { name: spec.slice(0, at) };
|
|
697
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
|
+
}
|
|
698
871
|
|
|
699
872
|
// src/commands/validate/validators/settings.ts
|
|
700
|
-
var CLIENT_HEADER = "walkeros-cli/4.8.
|
|
873
|
+
var CLIENT_HEADER = "walkeros-cli/4.8.3-next-1793115089237";
|
|
874
|
+
var LOGGER = createLogger();
|
|
701
875
|
function createSettingsContext(configDir) {
|
|
702
876
|
return { configDir, cache: /* @__PURE__ */ new Map(), compiled: /* @__PURE__ */ new Map() };
|
|
703
877
|
}
|
|
@@ -708,7 +882,7 @@ function selectSettingsSchema(pkg, packageLabel, exportName) {
|
|
|
708
882
|
pkg.exportSchemas,
|
|
709
883
|
exportName
|
|
710
884
|
) ? pkg.exportSchemas[exportName] : void 0;
|
|
711
|
-
if (!
|
|
885
|
+
if (!isObject5(entry))
|
|
712
886
|
return {
|
|
713
887
|
ok: false,
|
|
714
888
|
reason: `${packageLabel} has no export "${exportName}"`
|
|
@@ -736,7 +910,7 @@ function valueAt(root, segments) {
|
|
|
736
910
|
let current = root;
|
|
737
911
|
for (const segment of segments) {
|
|
738
912
|
if (Array.isArray(current)) current = current[Number(segment)];
|
|
739
|
-
else if (
|
|
913
|
+
else if (isObject5(current)) current = current[segment];
|
|
740
914
|
else return void 0;
|
|
741
915
|
}
|
|
742
916
|
return current;
|
|
@@ -751,7 +925,7 @@ function prepareSettings(settings) {
|
|
|
751
925
|
const walk = (value, segments) => {
|
|
752
926
|
if (Array.isArray(value))
|
|
753
927
|
return value.map((item, index) => walk(item, [...segments, `${index}`]));
|
|
754
|
-
if (
|
|
928
|
+
if (isObject5(value))
|
|
755
929
|
return Object.fromEntries(
|
|
756
930
|
Object.entries(value).map(([key, item]) => [
|
|
757
931
|
key,
|
|
@@ -795,62 +969,9 @@ function prepareSettings(settings) {
|
|
|
795
969
|
function isUnder(segments, prefix) {
|
|
796
970
|
return prefix.every((segment, index) => segments[index] === segment);
|
|
797
971
|
}
|
|
798
|
-
function
|
|
799
|
-
const
|
|
800
|
-
|
|
801
|
-
const packages = isObject4(bundle) ? bundle.packages : void 0;
|
|
802
|
-
const pin = isObject4(packages) ? packages[name] : void 0;
|
|
803
|
-
if (!isObject4(pin)) return {};
|
|
804
|
-
return {
|
|
805
|
-
...typeof pin.version === "string" ? { version: pin.version } : {},
|
|
806
|
-
...typeof pin.path === "string" ? { path: pin.path } : {}
|
|
807
|
-
};
|
|
808
|
-
}
|
|
809
|
-
function packageSource(spec, rawFlow) {
|
|
810
|
-
if (spec.startsWith(".") || spec.startsWith("/"))
|
|
811
|
-
return { name: spec, localPath: spec };
|
|
812
|
-
const { name, version } = parsePackageSpec(spec);
|
|
813
|
-
const pin = bundlePin(rawFlow, name);
|
|
814
|
-
if (pin.path) return { name, localPath: pin.path };
|
|
815
|
-
const pinned = pin.version ?? version;
|
|
816
|
-
return pinned ? { name, version: pinned } : { name };
|
|
817
|
-
}
|
|
818
|
-
function readJson(file) {
|
|
819
|
-
return JSON.parse(fs8.readFileSync(file, "utf-8"));
|
|
820
|
-
}
|
|
821
|
-
function readLocalSchema(source, configDir) {
|
|
822
|
-
const localPath = source.localPath ?? "";
|
|
823
|
-
const root = path2.isAbsolute(localPath) ? localPath : path2.resolve(configDir, localPath);
|
|
824
|
-
const file = [
|
|
825
|
-
path2.join(root, "dist", "walkerOS.json"),
|
|
826
|
-
path2.join(root, "walkerOS.json")
|
|
827
|
-
].find((candidate) => fs8.existsSync(candidate));
|
|
828
|
-
if (!file) throw new Error(`no walkerOS.json under ${root}`);
|
|
829
|
-
const meta = readJson(file);
|
|
830
|
-
const pkgFile = path2.join(root, "package.json");
|
|
831
|
-
const pkg = fs8.existsSync(pkgFile) ? readJson(pkgFile) : void 0;
|
|
832
|
-
const schemas5 = isObject4(meta) ? meta.schemas : void 0;
|
|
833
|
-
const exportSchemas = isObject4(meta) ? meta.exportSchemas : void 0;
|
|
834
|
-
const declared = isObject4(meta) && isObject4(meta.$meta) ? meta.$meta.exports : void 0;
|
|
835
|
-
const version = isObject4(pkg) && typeof pkg.version === "string" ? pkg.version : void 0;
|
|
836
|
-
return {
|
|
837
|
-
...version ? { version } : {},
|
|
838
|
-
settings: isObject4(schemas5) ? schemas5.settings : void 0,
|
|
839
|
-
...isObject4(exportSchemas) ? { exportSchemas } : {},
|
|
840
|
-
...isObject4(declared) ? { exports: Object.keys(declared) } : {}
|
|
841
|
-
};
|
|
842
|
-
}
|
|
843
|
-
async function loadSchema(source, context) {
|
|
844
|
-
if (source.localPath !== void 0) {
|
|
845
|
-
const configDir = context.configDir;
|
|
846
|
-
if (configDir === void 0)
|
|
847
|
-
throw new Error(
|
|
848
|
-
"it is a local path package and the input is not a file, so there is no directory to read it from"
|
|
849
|
-
);
|
|
850
|
-
return readLocalSchema(source, configDir);
|
|
851
|
-
}
|
|
852
|
-
const info = await fetchPackage(source.name, {
|
|
853
|
-
...source.version ? { version: source.version } : {},
|
|
972
|
+
async function loadSchema(resolved, context) {
|
|
973
|
+
const info = await readStepPackageInfo(resolved, {
|
|
974
|
+
configDir: context.configDir,
|
|
854
975
|
client: CLIENT_HEADER
|
|
855
976
|
});
|
|
856
977
|
return {
|
|
@@ -861,7 +982,7 @@ async function loadSchema(source, context) {
|
|
|
861
982
|
};
|
|
862
983
|
}
|
|
863
984
|
function compileSettings(settings) {
|
|
864
|
-
if (!
|
|
985
|
+
if (!isObject5(settings)) return void 0;
|
|
865
986
|
const ajv = new Ajv({ allErrors: true, validateFormats: false });
|
|
866
987
|
try {
|
|
867
988
|
return { ok: true, validate: ajv.compile(settings) };
|
|
@@ -869,26 +990,26 @@ function compileSettings(settings) {
|
|
|
869
990
|
return { ok: false, message: getErrorMessage3(error) };
|
|
870
991
|
}
|
|
871
992
|
}
|
|
872
|
-
function sourceKey(
|
|
873
|
-
return
|
|
993
|
+
function sourceKey({ packageName, spec }) {
|
|
994
|
+
return spec.path !== void 0 ? `path:${spec.path}` : `${packageName}@${spec.version ?? "latest"}`;
|
|
874
995
|
}
|
|
875
|
-
function cachedSchema(
|
|
876
|
-
const key = sourceKey(
|
|
996
|
+
function cachedSchema(resolved, context) {
|
|
997
|
+
const key = sourceKey(resolved);
|
|
877
998
|
let pending = context.cache.get(key);
|
|
878
999
|
if (!pending) {
|
|
879
|
-
pending = loadSchema(
|
|
1000
|
+
pending = loadSchema(resolved, context);
|
|
880
1001
|
context.cache.set(key, pending);
|
|
881
1002
|
}
|
|
882
1003
|
return pending;
|
|
883
1004
|
}
|
|
884
|
-
function cachedCompile(
|
|
885
|
-
const key = `${sourceKey(
|
|
1005
|
+
function cachedCompile(resolved, exportName, settings, context) {
|
|
1006
|
+
const key = `${sourceKey(resolved)}#${exportName ?? ""}`;
|
|
886
1007
|
if (context.compiled.has(key)) return context.compiled.get(key);
|
|
887
1008
|
const compiled = compileSettings(settings);
|
|
888
1009
|
context.compiled.set(key, compiled);
|
|
889
1010
|
return compiled;
|
|
890
1011
|
}
|
|
891
|
-
async function checkStepSettings(target, resolvedFlow,
|
|
1012
|
+
async function checkStepSettings(target, resolvedFlow, check, context) {
|
|
892
1013
|
const at = `flows.${target.flow}.${target.section}.${target.key}`;
|
|
893
1014
|
const outcome = { findings: [], skipped: [], deferred: [] };
|
|
894
1015
|
const spec = typeof target.entry.package === "string" ? target.entry.package : "";
|
|
@@ -901,33 +1022,51 @@ async function checkStepSettings(target, resolvedFlow, rawFlow, check, context)
|
|
|
901
1022
|
});
|
|
902
1023
|
return outcome;
|
|
903
1024
|
}
|
|
904
|
-
|
|
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;
|
|
905
1044
|
let schema;
|
|
906
1045
|
try {
|
|
907
|
-
schema = await cachedSchema(
|
|
1046
|
+
schema = await cachedSchema(resolved, context);
|
|
908
1047
|
} catch (error) {
|
|
909
1048
|
outcome.skipped.push({
|
|
910
1049
|
path: at,
|
|
911
1050
|
check,
|
|
912
|
-
reason: `Schema for ${
|
|
1051
|
+
reason: `Schema for ${label}${pinned ? `@${pinned}` : ""} could not be loaded: ${getErrorMessage3(error)}`,
|
|
913
1052
|
code: "SCHEMA_UNAVAILABLE"
|
|
914
1053
|
});
|
|
915
1054
|
return outcome;
|
|
916
1055
|
}
|
|
917
1056
|
outcome.checked = {
|
|
918
1057
|
path: at,
|
|
919
|
-
package:
|
|
1058
|
+
package: label,
|
|
920
1059
|
...schema.version ? { version: schema.version } : {}
|
|
921
1060
|
};
|
|
922
1061
|
const { exportName } = resolveExportName(
|
|
923
|
-
|
|
1062
|
+
resolved.normalizedFlow,
|
|
924
1063
|
SECTION_KIND[target.section],
|
|
925
1064
|
target.key
|
|
926
1065
|
);
|
|
927
|
-
const version = schema.version ??
|
|
1066
|
+
const version = schema.version ?? pinned;
|
|
928
1067
|
const selection = selectSettingsSchema(
|
|
929
1068
|
schema,
|
|
930
|
-
version ? `${
|
|
1069
|
+
version ? `${label}@${version}` : label,
|
|
931
1070
|
exportName
|
|
932
1071
|
);
|
|
933
1072
|
if (!selection.ok) {
|
|
@@ -940,7 +1079,7 @@ async function checkStepSettings(target, resolvedFlow, rawFlow, check, context)
|
|
|
940
1079
|
return outcome;
|
|
941
1080
|
}
|
|
942
1081
|
const compiled = cachedCompile(
|
|
943
|
-
|
|
1082
|
+
resolved,
|
|
944
1083
|
exportName,
|
|
945
1084
|
selection.settings,
|
|
946
1085
|
context
|
|
@@ -949,7 +1088,7 @@ async function checkStepSettings(target, resolvedFlow, rawFlow, check, context)
|
|
|
949
1088
|
outcome.skipped.push({
|
|
950
1089
|
path: at,
|
|
951
1090
|
check,
|
|
952
|
-
reason: `Package ${
|
|
1091
|
+
reason: `Package ${label} has no settings schema`,
|
|
953
1092
|
code: "NO_SETTINGS_SCHEMA"
|
|
954
1093
|
});
|
|
955
1094
|
return outcome;
|
|
@@ -958,14 +1097,14 @@ async function checkStepSettings(target, resolvedFlow, rawFlow, check, context)
|
|
|
958
1097
|
outcome.skipped.push({
|
|
959
1098
|
path: at,
|
|
960
1099
|
check,
|
|
961
|
-
reason: `The settings schema of ${
|
|
1100
|
+
reason: `The settings schema of ${label} cannot be compiled: ${compiled.message}`,
|
|
962
1101
|
code: "SCHEMA_UNAVAILABLE"
|
|
963
1102
|
});
|
|
964
1103
|
return outcome;
|
|
965
1104
|
}
|
|
966
1105
|
const validate2 = compiled.validate;
|
|
967
1106
|
const step = stepOf(resolvedFlow, target.section, target.key);
|
|
968
|
-
const config =
|
|
1107
|
+
const config = isObject5(step?.config) ? step.config : {};
|
|
969
1108
|
const prepared = prepareSettings(config.settings ?? {});
|
|
970
1109
|
const base = `${at}.config.settings`;
|
|
971
1110
|
for (const { segments, reference } of prepared.deferred) {
|
|
@@ -1046,18 +1185,12 @@ async function validateFlowWithPackages(input, options = {}) {
|
|
|
1046
1185
|
continue;
|
|
1047
1186
|
}
|
|
1048
1187
|
for (const section of ENTRY_SECTIONS) {
|
|
1049
|
-
const steps =
|
|
1188
|
+
const steps = isObject6(rawFlow[section]) ? rawFlow[section] : {};
|
|
1050
1189
|
for (const [key, entry] of Object.entries(steps)) {
|
|
1051
|
-
if (!
|
|
1190
|
+
if (!isObject6(entry) || entry.package === void 0) continue;
|
|
1052
1191
|
const target = { flow: name, section, key, entry };
|
|
1053
1192
|
pending.push(
|
|
1054
|
-
checkStepSettings(
|
|
1055
|
-
target,
|
|
1056
|
-
flow,
|
|
1057
|
-
rawFlow,
|
|
1058
|
-
"flow:package-settings",
|
|
1059
|
-
context
|
|
1060
|
-
)
|
|
1193
|
+
checkStepSettings(target, flow, "flow:package-settings", context)
|
|
1061
1194
|
);
|
|
1062
1195
|
}
|
|
1063
1196
|
}
|
|
@@ -1112,9 +1245,9 @@ function runFlowChecks(input, options) {
|
|
|
1112
1245
|
};
|
|
1113
1246
|
}
|
|
1114
1247
|
errors.push(...scope.errors);
|
|
1115
|
-
const config =
|
|
1248
|
+
const config = isObject6(input) ? input : {};
|
|
1116
1249
|
const flowsValue = config.flows;
|
|
1117
|
-
const flows =
|
|
1250
|
+
const flows = isObject6(flowsValue) ? flowsValue : void 0;
|
|
1118
1251
|
const allFlows = scope.allFlows;
|
|
1119
1252
|
const inScope = (path4) => {
|
|
1120
1253
|
const flow = flowOfPath(path4, allFlows);
|
|
@@ -1157,13 +1290,13 @@ function runFlowChecks(input, options) {
|
|
|
1157
1290
|
checks.push("flow:steps");
|
|
1158
1291
|
for (const flowName of scope.flows) {
|
|
1159
1292
|
const flowValue = flows?.[flowName];
|
|
1160
|
-
if (!
|
|
1293
|
+
if (!isObject6(flowValue)) continue;
|
|
1161
1294
|
const transformersValue = flowValue.transformers;
|
|
1162
|
-
if (
|
|
1295
|
+
if (isObject6(transformersValue)) {
|
|
1163
1296
|
for (const [name, transformerValue] of Object.entries(
|
|
1164
1297
|
transformersValue
|
|
1165
1298
|
)) {
|
|
1166
|
-
if (!
|
|
1299
|
+
if (!isObject6(transformerValue)) continue;
|
|
1167
1300
|
const result2 = validateStepEntry(transformerValue, "Transformer");
|
|
1168
1301
|
if (!result2.ok) {
|
|
1169
1302
|
errors.push({
|
|
@@ -1176,9 +1309,9 @@ function runFlowChecks(input, options) {
|
|
|
1176
1309
|
}
|
|
1177
1310
|
for (const [section, kind] of STEP_KINDS) {
|
|
1178
1311
|
const steps = flowValue[section];
|
|
1179
|
-
if (!
|
|
1312
|
+
if (!isObject6(steps)) continue;
|
|
1180
1313
|
for (const [name, step] of Object.entries(steps)) {
|
|
1181
|
-
if (!
|
|
1314
|
+
if (!isObject6(step)) continue;
|
|
1182
1315
|
const at = `flows.${flowName}.${section}.${name}`;
|
|
1183
1316
|
errors.push(...checkStepKeys(step, kind, at));
|
|
1184
1317
|
const pkg = step.package;
|
|
@@ -1201,15 +1334,15 @@ function runFlowChecks(input, options) {
|
|
|
1201
1334
|
let totalPackageCount = 0;
|
|
1202
1335
|
for (const flowName of scope.flows) {
|
|
1203
1336
|
const flowValue = flows?.[flowName];
|
|
1204
|
-
if (!
|
|
1337
|
+
if (!isObject6(flowValue)) continue;
|
|
1205
1338
|
const flowConfig = flowValue.config;
|
|
1206
|
-
if (!
|
|
1339
|
+
if (!isObject6(flowConfig)) continue;
|
|
1207
1340
|
const bundle = flowConfig.bundle;
|
|
1208
|
-
if (!
|
|
1341
|
+
if (!isObject6(bundle)) continue;
|
|
1209
1342
|
const packages = bundle.packages;
|
|
1210
|
-
if (!
|
|
1343
|
+
if (!isObject6(packages)) continue;
|
|
1211
1344
|
for (const [pkgName, pkgConfigValue] of Object.entries(packages)) {
|
|
1212
|
-
if (!
|
|
1345
|
+
if (!isObject6(pkgConfigValue)) continue;
|
|
1213
1346
|
if (!pkgConfigValue.version && !pkgConfigValue.path) {
|
|
1214
1347
|
warnings.push({
|
|
1215
1348
|
path: `flows.${flowName}.config.bundle.packages.${pkgName}`,
|
|
@@ -1297,13 +1430,13 @@ function runFlowChecks(input, options) {
|
|
|
1297
1430
|
warnings,
|
|
1298
1431
|
options.strict === true,
|
|
1299
1432
|
skipped,
|
|
1300
|
-
|
|
1433
|
+
isObject6(resolvedConfig) && isObject6(resolvedConfig.settings) ? resolvedConfig.settings : void 0
|
|
1301
1434
|
);
|
|
1302
1435
|
}
|
|
1303
1436
|
for (const [destName, dest] of Object.entries(flow.destinations || {})) {
|
|
1304
|
-
if (!
|
|
1437
|
+
if (!isObject6(dest.config)) continue;
|
|
1305
1438
|
const mapping = dest.config.mapping;
|
|
1306
|
-
if (!
|
|
1439
|
+
if (!isObject6(mapping)) continue;
|
|
1307
1440
|
for (const key of Object.keys(mapping)) {
|
|
1308
1441
|
if (key.includes(".") && !key.includes(" ")) {
|
|
1309
1442
|
const parts = key.split(".");
|
|
@@ -1364,16 +1497,16 @@ function checkResolvedWindowCollector(name, raw, flow, errors, deferred) {
|
|
|
1364
1497
|
});
|
|
1365
1498
|
}
|
|
1366
1499
|
function checkWebLoggerFormat(flowName, flow, errors) {
|
|
1367
|
-
if (!
|
|
1500
|
+
if (!isObject6(flow.config) || flow.config.platform !== "web") return;
|
|
1368
1501
|
const at = `flows.${flowName}`;
|
|
1369
1502
|
const loggers = [];
|
|
1370
|
-
if (
|
|
1503
|
+
if (isObject6(flow.collector))
|
|
1371
1504
|
loggers.push([`${at}.collector.logger`, flow.collector.logger]);
|
|
1372
1505
|
for (const [section] of STEP_KINDS) {
|
|
1373
1506
|
const steps = flow[section];
|
|
1374
|
-
if (!
|
|
1507
|
+
if (!isObject6(steps)) continue;
|
|
1375
1508
|
for (const [name, step] of Object.entries(steps)) {
|
|
1376
|
-
if (
|
|
1509
|
+
if (isObject6(step) && isObject6(step.config))
|
|
1377
1510
|
loggers.push([
|
|
1378
1511
|
`${at}.${section}.${name}.config.logger`,
|
|
1379
1512
|
step.config.logger
|
|
@@ -1381,7 +1514,7 @@ function checkWebLoggerFormat(flowName, flow, errors) {
|
|
|
1381
1514
|
}
|
|
1382
1515
|
}
|
|
1383
1516
|
for (const [path4, logger] of loggers) {
|
|
1384
|
-
if (!
|
|
1517
|
+
if (!isObject6(logger) || logger.format === void 0) continue;
|
|
1385
1518
|
errors.push({
|
|
1386
1519
|
path: `${path4}.format`,
|
|
1387
1520
|
message: "logger.format applies to server flows only: a web flow logs to the browser console, which has no output format. Remove it.",
|
|
@@ -1486,21 +1619,21 @@ function isStepOut(value) {
|
|
|
1486
1619
|
return Array.isArray(value) && value.every((entry) => Array.isArray(entry) && typeof entry[0] === "string");
|
|
1487
1620
|
}
|
|
1488
1621
|
function returnedEvents(value) {
|
|
1489
|
-
if (
|
|
1622
|
+
if (isObject6(value)) return [isObject6(value.event) ? value.event : value];
|
|
1490
1623
|
if (Array.isArray(value)) return value.flatMap(returnedEvents);
|
|
1491
1624
|
return [];
|
|
1492
1625
|
}
|
|
1493
1626
|
function outEvents(out) {
|
|
1494
1627
|
if (isStepOut(out)) {
|
|
1495
1628
|
return out.flatMap(([head, first]) => {
|
|
1496
|
-
if (head === "elb") return
|
|
1629
|
+
if (head === "elb") return isObject6(first) ? [first] : [];
|
|
1497
1630
|
if (head === "return") return returnedEvents(first);
|
|
1498
1631
|
return [];
|
|
1499
1632
|
});
|
|
1500
1633
|
}
|
|
1501
1634
|
if (Array.isArray(out) || typeof out === "string")
|
|
1502
1635
|
return out.length > 0 ? [out] : [];
|
|
1503
|
-
return
|
|
1636
|
+
return isObject6(out) && Object.keys(out).length > 0 ? [out] : [];
|
|
1504
1637
|
}
|
|
1505
1638
|
function hasComparableOut(out) {
|
|
1506
1639
|
return outEvents(out).length > 0;
|
|
@@ -1542,7 +1675,7 @@ function routeAt(spec, path4) {
|
|
|
1542
1675
|
for (const key of path4) {
|
|
1543
1676
|
if (typeof key === "number")
|
|
1544
1677
|
current = Array.isArray(current) ? current[key] : void 0;
|
|
1545
|
-
else current =
|
|
1678
|
+
else current = isObject6(current) ? current[key] : void 0;
|
|
1546
1679
|
}
|
|
1547
1680
|
return current;
|
|
1548
1681
|
}
|
|
@@ -1567,7 +1700,7 @@ function lintRoute(spec, position, known, errors, warnings) {
|
|
|
1567
1700
|
if (node.stop && !node.match && node.kind !== "many") {
|
|
1568
1701
|
const self = routeAt(spec, node.path);
|
|
1569
1702
|
const list = routeAt(spec, node.path.slice(0, -1));
|
|
1570
|
-
if (
|
|
1703
|
+
if (isObject6(self) && self.stop === true && typeof last === "number" && Array.isArray(list) && last < list.length - 1 && once(`stop:${where(node.path)}`)) {
|
|
1571
1704
|
const at = where(node.path);
|
|
1572
1705
|
warnings.push({
|
|
1573
1706
|
path: at,
|
|
@@ -1619,7 +1752,7 @@ function hasRuntimeValue(value) {
|
|
|
1619
1752
|
if (typeof value === "string")
|
|
1620
1753
|
return value.includes(ENV_MARKER_PREFIX2) || value.startsWith(SECRET_MARKER_PREFIX2) || /\$(?:env|secret)\./.test(value);
|
|
1621
1754
|
if (Array.isArray(value)) return value.some(hasRuntimeValue);
|
|
1622
|
-
return
|
|
1755
|
+
return isObject6(value) && Object.values(value).some(hasRuntimeValue);
|
|
1623
1756
|
}
|
|
1624
1757
|
var VALIDATE_PACKAGE = "@walkeros/transformer-validate";
|
|
1625
1758
|
function isValidateStep(step) {
|
|
@@ -1639,7 +1772,7 @@ function resolveStepContracts(entries, contract) {
|
|
|
1639
1772
|
}
|
|
1640
1773
|
const sources = [];
|
|
1641
1774
|
for (const [index, entry] of entries.entries()) {
|
|
1642
|
-
if (
|
|
1775
|
+
if (isObject6(entry)) {
|
|
1643
1776
|
sources.push(entry);
|
|
1644
1777
|
continue;
|
|
1645
1778
|
}
|
|
@@ -1657,7 +1790,7 @@ function resolveStepContracts(entries, contract) {
|
|
|
1657
1790
|
message: `contract "${match[1]}" is not defined in the root contract (defined: ${Object.keys(resolved).join(", ") || "none"})`
|
|
1658
1791
|
};
|
|
1659
1792
|
const rule = match[2] ? getByPath(resolved[match[1]], match[2]) : resolved[match[1]];
|
|
1660
|
-
if (!
|
|
1793
|
+
if (!isObject6(rule))
|
|
1661
1794
|
return {
|
|
1662
1795
|
ok: false,
|
|
1663
1796
|
index,
|
|
@@ -1668,7 +1801,7 @@ function resolveStepContracts(entries, contract) {
|
|
|
1668
1801
|
return { ok: true, sources };
|
|
1669
1802
|
}
|
|
1670
1803
|
function checkValidateStepExamples(stepPath, step, contract, errors, warnings, strict, skipped, resolvedSettings) {
|
|
1671
|
-
const settings = resolvedSettings ?? (
|
|
1804
|
+
const settings = resolvedSettings ?? (isObject6(step.config) && isObject6(step.config.settings) ? step.config.settings : {});
|
|
1672
1805
|
const contractPath = `${stepPath}.config.settings.contract`;
|
|
1673
1806
|
if (settings.contract !== void 0 && !Array.isArray(settings.contract)) {
|
|
1674
1807
|
if (step.examples)
|
|
@@ -1702,10 +1835,10 @@ function checkValidateStepExamples(stepPath, step, contract, errors, warnings, s
|
|
|
1702
1835
|
}
|
|
1703
1836
|
const mode = settings.mode === "strict" ? "strict" : "pass";
|
|
1704
1837
|
const format = settings.format === true;
|
|
1705
|
-
const output =
|
|
1838
|
+
const output = isObject6(settings.output) ? settings.output : {};
|
|
1706
1839
|
const isValidPath = typeof output.isValid === "string" ? output.isValid : "source.valid";
|
|
1707
1840
|
for (const [exName, example] of Object.entries(step.examples)) {
|
|
1708
|
-
if (example.command || !
|
|
1841
|
+
if (example.command || !isObject6(example.in)) continue;
|
|
1709
1842
|
if (example.out === void 0) continue;
|
|
1710
1843
|
const event = example.in;
|
|
1711
1844
|
const verdict = validateEventAgainstContract(event, void 0, {
|
|
@@ -1743,14 +1876,14 @@ function checkValidateStepExamples(stepPath, step, contract, errors, warnings, s
|
|
|
1743
1876
|
}
|
|
1744
1877
|
|
|
1745
1878
|
// src/commands/validate/validators/mapping.ts
|
|
1746
|
-
import { isObject as
|
|
1879
|
+
import { isObject as isObject7 } from "@walkeros/core";
|
|
1747
1880
|
import { schemas as schemas4 } from "@walkeros/core/dev";
|
|
1748
1881
|
var { RuleSchema } = schemas4.MappingSchemas;
|
|
1749
1882
|
function isRule(value) {
|
|
1750
|
-
return
|
|
1883
|
+
return isObject7(value) && RuleSchema.safeParse(value).success;
|
|
1751
1884
|
}
|
|
1752
1885
|
function isNestedActions(key, value) {
|
|
1753
|
-
if (key.includes(" ") || !
|
|
1886
|
+
if (key.includes(" ") || !isObject7(value)) return false;
|
|
1754
1887
|
const rules = Object.values(value);
|
|
1755
1888
|
return rules.length > 0 && rules.every(
|
|
1756
1889
|
(rule) => Array.isArray(rule) ? rule.length > 0 && rule.every(isRule) : isRule(rule)
|
|
@@ -1760,7 +1893,7 @@ function validateMapping(input) {
|
|
|
1760
1893
|
const errors = [];
|
|
1761
1894
|
const warnings = [];
|
|
1762
1895
|
const details = {};
|
|
1763
|
-
if (!
|
|
1896
|
+
if (!isObject7(input)) {
|
|
1764
1897
|
errors.push({
|
|
1765
1898
|
path: "root",
|
|
1766
1899
|
message: "Mapping must be an object with event patterns as keys",
|
|
@@ -1849,7 +1982,6 @@ async function validateEntry(path4, flowConfig, options = {}) {
|
|
|
1849
1982
|
const outcome = await checkStepSettings(
|
|
1850
1983
|
target,
|
|
1851
1984
|
resolution.flow,
|
|
1852
|
-
file?.flows[target.flow],
|
|
1853
1985
|
"entry:settings",
|
|
1854
1986
|
context
|
|
1855
1987
|
);
|
|
@@ -1989,7 +2121,7 @@ function inapplicableOptions(type, options) {
|
|
|
1989
2121
|
}
|
|
1990
2122
|
function validateContractInput(input) {
|
|
1991
2123
|
if (!isFlowJson(input)) return validateContract(input);
|
|
1992
|
-
const contract =
|
|
2124
|
+
const contract = isObject8(input) ? input.contract : void 0;
|
|
1993
2125
|
if (contract === void 0) {
|
|
1994
2126
|
return {
|
|
1995
2127
|
valid: false,
|