@walkeros/cli 4.6.0 → 4.7.0-next-1790187973605
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 +57 -0
- package/dist/cli.js +2665 -2127
- package/dist/examples/README.md +1 -0
- package/dist/examples/flow-complete.json +2 -4
- package/dist/examples/index.js +2 -4
- package/dist/examples/index.js.map +1 -1
- package/dist/index.d.ts +13 -43
- package/dist/index.js +190 -407
- package/dist/index.js.map +1 -1
- package/examples/README.md +1 -0
- package/examples/flow-complete.json +2 -4
- package/package.json +8 -8
package/dist/index.js
CHANGED
|
@@ -2689,6 +2689,7 @@ import path12 from "path";
|
|
|
2689
2689
|
import fs11 from "fs-extra";
|
|
2690
2690
|
import {
|
|
2691
2691
|
packageNameToVariable as packageNameToVariable2,
|
|
2692
|
+
getStepRuntimeProps,
|
|
2692
2693
|
ENV_MARKER_PREFIX,
|
|
2693
2694
|
SECRET_MARKER_PREFIX as SECRET_MARKER_PREFIX2,
|
|
2694
2695
|
isPathStepEntry,
|
|
@@ -2701,29 +2702,25 @@ function isInlineCode2(code) {
|
|
|
2701
2702
|
function hasCodeReference2(code) {
|
|
2702
2703
|
return isInlineCode2(code) || typeof code === "string";
|
|
2703
2704
|
}
|
|
2704
|
-
function generateInlineCode(inline,
|
|
2705
|
+
function generateInlineCode(inline, runtimeProps, isDestination) {
|
|
2705
2706
|
const pushFn = inline.push.replace("$code:", "");
|
|
2706
2707
|
const initFn = inline.init ? inline.init.replace("$code:", "") : void 0;
|
|
2707
2708
|
const typeLine = inline.type ? `type: '${inline.type}',` : "";
|
|
2708
|
-
const
|
|
2709
|
-
|
|
2710
|
-
|
|
2711
|
-
|
|
2712
|
-
|
|
2713
|
-
|
|
2714
|
-
}
|
|
2715
|
-
const chainBlock = chainLines.length ? `,
|
|
2716
|
-
${chainLines.join(",\n ")}` : "";
|
|
2709
|
+
const props = {
|
|
2710
|
+
config: {},
|
|
2711
|
+
env: {},
|
|
2712
|
+
...runtimeProps
|
|
2713
|
+
};
|
|
2714
|
+
const propLines = Object.entries(props).map(([key, value]) => `${key}: ${processConfigValue(value)}`).join(",\n ");
|
|
2717
2715
|
if (isDestination) {
|
|
2718
2716
|
return `{
|
|
2719
2717
|
code: {
|
|
2720
2718
|
${typeLine}
|
|
2721
|
-
config: ${processConfigValue(config
|
|
2719
|
+
config: ${processConfigValue(props.config)},
|
|
2722
2720
|
${initFn ? `init: ${initFn},` : ""}
|
|
2723
2721
|
push: ${pushFn}
|
|
2724
2722
|
},
|
|
2725
|
-
|
|
2726
|
-
env: ${processConfigValue(env || {})}${chainBlock}
|
|
2723
|
+
${propLines}
|
|
2727
2724
|
}`;
|
|
2728
2725
|
}
|
|
2729
2726
|
return `{
|
|
@@ -2733,8 +2730,7 @@ function generateInlineCode(inline, config, env, chains, isDestination) {
|
|
|
2733
2730
|
${initFn ? `init: ${initFn},` : ""}
|
|
2734
2731
|
push: ${pushFn}
|
|
2735
2732
|
}),
|
|
2736
|
-
|
|
2737
|
-
env: ${processConfigValue(env || {})}${chainBlock}
|
|
2733
|
+
${propLines}
|
|
2738
2734
|
}`;
|
|
2739
2735
|
}
|
|
2740
2736
|
async function copyIncludes(includes, sourceDir, outputDir, logger) {
|
|
@@ -3461,24 +3457,11 @@ function buildSplitConfigObject(flowSettings, namedImports) {
|
|
|
3461
3457
|
}
|
|
3462
3458
|
return packageNameToVariable2(step.package);
|
|
3463
3459
|
}
|
|
3464
|
-
function
|
|
3465
|
-
const
|
|
3466
|
-
for (const [key, value] of Object.entries(step)) {
|
|
3467
|
-
if (key === "code" || key === "package" || key === "import") continue;
|
|
3468
|
-
if (value !== void 0 && value !== null) {
|
|
3469
|
-
props[key] = value;
|
|
3470
|
-
}
|
|
3471
|
-
}
|
|
3472
|
-
return props;
|
|
3473
|
-
}
|
|
3474
|
-
function buildSplitStepEntry(section, stepId3, step) {
|
|
3475
|
-
const codeVar = resolveCodeVar(step);
|
|
3476
|
-
const stepProps = getStepProps(step);
|
|
3477
|
-
const { codeProps, dataProps } = classifyStepProperties(stepProps);
|
|
3460
|
+
function buildSplitStepEntry(section, stepId3, codeVar, runtimeProps) {
|
|
3461
|
+
const { codeProps, dataProps } = classifyStepProperties(runtimeProps);
|
|
3478
3462
|
const codeEntries = [];
|
|
3479
|
-
codeEntries.push(`code: ${codeVar}`);
|
|
3463
|
+
if (codeVar !== void 0) codeEntries.push(`code: ${codeVar}`);
|
|
3480
3464
|
for (const [key, value] of Object.entries(codeProps)) {
|
|
3481
|
-
if (key === "code") continue;
|
|
3482
3465
|
codeEntries.push(`${key}: ${processConfigValue(value)}`);
|
|
3483
3466
|
}
|
|
3484
3467
|
for (const key of Object.keys(dataProps)) {
|
|
@@ -3492,6 +3475,14 @@ function buildSplitConfigObject(flowSettings, namedImports) {
|
|
|
3492
3475
|
${codeEntries.join(",\n ")}
|
|
3493
3476
|
}`;
|
|
3494
3477
|
}
|
|
3478
|
+
function buildStepEntry(kind, section, stepId3, step) {
|
|
3479
|
+
const runtimeProps = getStepRuntimeProps(step, kind);
|
|
3480
|
+
if (isInlineCode2(step.code)) {
|
|
3481
|
+
return ` ${stepId3}: ${generateInlineCode(step.code, runtimeProps, kind === "Destination")}`;
|
|
3482
|
+
}
|
|
3483
|
+
const codeVar = isPathStepEntry({ ...step }, kind) ? void 0 : resolveCodeVar(step);
|
|
3484
|
+
return buildSplitStepEntry(section, stepId3, codeVar, runtimeProps);
|
|
3485
|
+
}
|
|
3495
3486
|
Object.entries(sources).forEach(([name, source]) => {
|
|
3496
3487
|
validateReference("Source", name, source);
|
|
3497
3488
|
});
|
|
@@ -3501,75 +3492,21 @@ function buildSplitConfigObject(flowSettings, namedImports) {
|
|
|
3501
3492
|
Object.entries(transformers).forEach(([name, transformer]) => {
|
|
3502
3493
|
validateReference("Transformer", name, transformer);
|
|
3503
3494
|
});
|
|
3504
|
-
const sourcesEntries = Object.entries(sources).filter(([, source]) => source.package || hasCodeReference2(source.code)).map(([key, source]) =>
|
|
3505
|
-
|
|
3506
|
-
|
|
3507
|
-
|
|
3508
|
-
return buildSplitStepEntry("sources", key, source);
|
|
3509
|
-
});
|
|
3510
|
-
const destinationsEntries = Object.entries(destinations).filter(([, dest]) => dest.package || hasCodeReference2(dest.code)).map(([key, dest]) => {
|
|
3511
|
-
if (isInlineCode2(dest.code)) {
|
|
3512
|
-
return ` ${key}: ${generateInlineCode(dest.code, dest.config || {}, dest.env, { before: dest.before, next: dest.next }, true)}`;
|
|
3513
|
-
}
|
|
3514
|
-
return buildSplitStepEntry("destinations", key, dest);
|
|
3515
|
-
});
|
|
3495
|
+
const sourcesEntries = Object.entries(sources).filter(([, source]) => source.package || hasCodeReference2(source.code)).map(([key, source]) => buildStepEntry("Source", "sources", key, source));
|
|
3496
|
+
const destinationsEntries = Object.entries(destinations).filter(([, dest]) => dest.package || hasCodeReference2(dest.code)).map(
|
|
3497
|
+
([key, dest]) => buildStepEntry("Destination", "destinations", key, dest)
|
|
3498
|
+
);
|
|
3516
3499
|
const transformersEntries = Object.entries(transformers).filter(
|
|
3517
3500
|
([, transformer]) => transformer.package || hasCodeReference2(transformer.code) || isPathStepEntry({ ...transformer }, "Transformer")
|
|
3518
|
-
).map(
|
|
3519
|
-
|
|
3520
|
-
|
|
3521
|
-
}
|
|
3522
|
-
if (isPathStepEntry({ ...transformer }, "Transformer")) {
|
|
3523
|
-
const chainLines = [];
|
|
3524
|
-
if (transformer.before !== void 0) {
|
|
3525
|
-
chainLines.push(`before: ${JSON.stringify(transformer.before)}`);
|
|
3526
|
-
}
|
|
3527
|
-
if (transformer.next !== void 0) {
|
|
3528
|
-
chainLines.push(`next: ${JSON.stringify(transformer.next)}`);
|
|
3529
|
-
}
|
|
3530
|
-
if (transformer.cache !== void 0) {
|
|
3531
|
-
chainLines.push(`cache: ${JSON.stringify(transformer.cache)}`);
|
|
3532
|
-
}
|
|
3533
|
-
if (transformer.config !== void 0) {
|
|
3534
|
-
chainLines.push(
|
|
3535
|
-
`config: ${processConfigValue(transformer.config)}`
|
|
3536
|
-
);
|
|
3537
|
-
}
|
|
3538
|
-
return ` ${key}: {
|
|
3539
|
-
${chainLines.join(",\n ")}
|
|
3540
|
-
}`;
|
|
3541
|
-
}
|
|
3542
|
-
return buildSplitStepEntry("transformers", key, transformer);
|
|
3543
|
-
});
|
|
3501
|
+
).map(
|
|
3502
|
+
([key, transformer]) => buildStepEntry("Transformer", "transformers", key, transformer)
|
|
3503
|
+
);
|
|
3544
3504
|
Object.entries(stores).forEach(([name, store]) => {
|
|
3545
3505
|
if (store.package || hasCodeReference2(store.code)) {
|
|
3546
3506
|
validateReference("Store", name, store);
|
|
3547
3507
|
}
|
|
3548
3508
|
});
|
|
3549
|
-
const storesEntries = Object.entries(stores).filter(([, store]) => store.package || hasCodeReference2(store.code)).map(([key, store]) =>
|
|
3550
|
-
if (isInlineCode2(store.code)) {
|
|
3551
|
-
return ` ${key}: ${generateInlineCode(store.code, store.config || {}, store.env)}`;
|
|
3552
|
-
}
|
|
3553
|
-
const codeVar = resolveCodeVar(store);
|
|
3554
|
-
const storeProps = getStepProps(store);
|
|
3555
|
-
const { codeProps, dataProps } = classifyStepProperties(storeProps);
|
|
3556
|
-
const codeEntries = [];
|
|
3557
|
-
codeEntries.push(`code: ${codeVar}`);
|
|
3558
|
-
for (const [propKey, value] of Object.entries(codeProps)) {
|
|
3559
|
-
if (propKey === "code") continue;
|
|
3560
|
-
codeEntries.push(`${propKey}: ${processConfigValue(value)}`);
|
|
3561
|
-
}
|
|
3562
|
-
for (const propKey of Object.keys(dataProps)) {
|
|
3563
|
-
codeEntries.push(`${propKey}: __data.stores.${key}.${propKey}`);
|
|
3564
|
-
}
|
|
3565
|
-
if (Object.keys(dataProps).length > 0) {
|
|
3566
|
-
if (!dataPayloadObj["stores"]) dataPayloadObj["stores"] = {};
|
|
3567
|
-
dataPayloadObj["stores"][key] = dataProps;
|
|
3568
|
-
}
|
|
3569
|
-
return ` ${key}: {
|
|
3570
|
-
${codeEntries.join(",\n ")}
|
|
3571
|
-
}`;
|
|
3572
|
-
});
|
|
3509
|
+
const storesEntries = Object.entries(stores).filter(([, store]) => store.package || hasCodeReference2(store.code)).map(([key, store]) => buildStepEntry("Store", "stores", key, store));
|
|
3573
3510
|
const storesDeclaration = storesEntries.length > 0 ? `const stores = {
|
|
3574
3511
|
${storesEntries.join(",\n")}
|
|
3575
3512
|
};` : "const stores = {};";
|
|
@@ -4486,17 +4423,11 @@ init_utils();
|
|
|
4486
4423
|
init_bundler();
|
|
4487
4424
|
import path16 from "path";
|
|
4488
4425
|
import fs15 from "fs-extra";
|
|
4489
|
-
import {
|
|
4490
|
-
createIngest,
|
|
4491
|
-
getPlatform as getPlatform3,
|
|
4492
|
-
getNextSteps,
|
|
4493
|
-
buildCacheContext,
|
|
4494
|
-
stepId
|
|
4495
|
-
} from "@walkeros/core";
|
|
4426
|
+
import { createIngest, getPlatform as getPlatform3, stepId } from "@walkeros/core";
|
|
4496
4427
|
import {
|
|
4497
4428
|
enrichEvent,
|
|
4498
4429
|
transformerInit,
|
|
4499
|
-
|
|
4430
|
+
runCollectorNext,
|
|
4500
4431
|
runTransformerChain,
|
|
4501
4432
|
wrapEnv
|
|
4502
4433
|
} from "@walkeros/collector";
|
|
@@ -4564,6 +4495,11 @@ function buildOverrides(flags, flowConfig) {
|
|
|
4564
4495
|
`--mock is not supported for sources. Use --simulate source.${parsed.name}`
|
|
4565
4496
|
);
|
|
4566
4497
|
}
|
|
4498
|
+
if (parsed.type === "collector" && !parsed.chainType) {
|
|
4499
|
+
throw new Error(
|
|
4500
|
+
`Use --mock collector.next.TRANSFORMER=VALUE to mock a step of the collector's chain`
|
|
4501
|
+
);
|
|
4502
|
+
}
|
|
4567
4503
|
if (parsed.type === "transformer" && !parsed.chainType) {
|
|
4568
4504
|
throw new Error(
|
|
4569
4505
|
`Use --mock destination.NAME.before.${parsed.name}=VALUE for path-specific transformer mocks`
|
|
@@ -4576,7 +4512,7 @@ function buildOverrides(flags, flowConfig) {
|
|
|
4576
4512
|
parsedValue = valuePart;
|
|
4577
4513
|
}
|
|
4578
4514
|
if (parsed.chainType && parsed.transformerId) {
|
|
4579
|
-
const chainPath = `destination.${parsed.name}.${parsed.chainType}`;
|
|
4515
|
+
const chainPath = parsed.type === "collector" ? `collector.${parsed.chainType}` : `destination.${parsed.name}.${parsed.chainType}`;
|
|
4580
4516
|
if (!overrides.transformerMocks) overrides.transformerMocks = {};
|
|
4581
4517
|
if (!overrides.transformerMocks[chainPath])
|
|
4582
4518
|
overrides.transformerMocks[chainPath] = {};
|
|
@@ -4613,6 +4549,19 @@ function parseStep(step) {
|
|
|
4613
4549
|
missingName: (input, p) => `Invalid step format: "${input}". Missing name after "${p}."`
|
|
4614
4550
|
}
|
|
4615
4551
|
});
|
|
4552
|
+
if (prefix === "collector" && rest.length > 0) {
|
|
4553
|
+
if (name !== "next" || rest.length !== 1 || !rest[0]) {
|
|
4554
|
+
throw new Error(
|
|
4555
|
+
`Invalid step format: "${step}". Expected "collector.next.TRANSFORMER"`
|
|
4556
|
+
);
|
|
4557
|
+
}
|
|
4558
|
+
return {
|
|
4559
|
+
type: prefix,
|
|
4560
|
+
name,
|
|
4561
|
+
chainType: "next",
|
|
4562
|
+
transformerId: rest[0]
|
|
4563
|
+
};
|
|
4564
|
+
}
|
|
4616
4565
|
if (rest.length >= 2) {
|
|
4617
4566
|
const chainType = rest[0];
|
|
4618
4567
|
if (chainType !== "before" && chainType !== "next") {
|
|
@@ -5186,6 +5135,7 @@ async function runPushCommand(options) {
|
|
|
5186
5135
|
{
|
|
5187
5136
|
collectorName: plan.ids[0],
|
|
5188
5137
|
flow: options.flow,
|
|
5138
|
+
mock: options.mock,
|
|
5189
5139
|
silent: options.silent,
|
|
5190
5140
|
verbose: options.verbose,
|
|
5191
5141
|
snapshot: options.snapshot
|
|
@@ -5268,37 +5218,6 @@ function getDevEnv(devModule) {
|
|
|
5268
5218
|
function isStringArray(value) {
|
|
5269
5219
|
return Array.isArray(value) && value.every(isString);
|
|
5270
5220
|
}
|
|
5271
|
-
function walkStaticChain(startId, transformers) {
|
|
5272
|
-
const chain = [];
|
|
5273
|
-
const visited = /* @__PURE__ */ new Set();
|
|
5274
|
-
let current = startId;
|
|
5275
|
-
while (current && transformers[current]) {
|
|
5276
|
-
if (visited.has(current)) break;
|
|
5277
|
-
visited.add(current);
|
|
5278
|
-
chain.push(current);
|
|
5279
|
-
const next = transformers[current].config?.next;
|
|
5280
|
-
if (typeof next === "string") {
|
|
5281
|
-
current = next;
|
|
5282
|
-
continue;
|
|
5283
|
-
}
|
|
5284
|
-
if (Array.isArray(next) && next.every(isString)) {
|
|
5285
|
-
chain.push(...next);
|
|
5286
|
-
break;
|
|
5287
|
-
}
|
|
5288
|
-
break;
|
|
5289
|
-
}
|
|
5290
|
-
return chain;
|
|
5291
|
-
}
|
|
5292
|
-
function resolveBeforeChain(before, transformers, ingest, event) {
|
|
5293
|
-
if (!before) return [];
|
|
5294
|
-
if (Array.isArray(before) && before.every(isString)) {
|
|
5295
|
-
return before;
|
|
5296
|
-
}
|
|
5297
|
-
const ids = getNextSteps(before, buildCacheContext(ingest, event));
|
|
5298
|
-
if (ids.length === 0) return [];
|
|
5299
|
-
if (ids.length === 1) return walkStaticChain(ids[0], transformers);
|
|
5300
|
-
return ids;
|
|
5301
|
-
}
|
|
5302
5221
|
async function pushCore(inputPath, event, options = {}) {
|
|
5303
5222
|
const logger = createCLILogger({
|
|
5304
5223
|
silent: options.silent,
|
|
@@ -5649,6 +5568,18 @@ async function simulateSource(configOrPath, input, options) {
|
|
|
5649
5568
|
await prepared.cleanup();
|
|
5650
5569
|
}
|
|
5651
5570
|
}
|
|
5571
|
+
async function runTransformerSimulation(collector, transformerId, event, ingest) {
|
|
5572
|
+
const result = await runTransformerChain(
|
|
5573
|
+
collector,
|
|
5574
|
+
collector.transformers,
|
|
5575
|
+
transformerId,
|
|
5576
|
+
event,
|
|
5577
|
+
ingest,
|
|
5578
|
+
void 0,
|
|
5579
|
+
`transformer.${transformerId}`
|
|
5580
|
+
);
|
|
5581
|
+
return result.copies.map((copy) => copy.event);
|
|
5582
|
+
}
|
|
5652
5583
|
async function simulateTransformer(configOrPath, event, options) {
|
|
5653
5584
|
const startTime = Date.now();
|
|
5654
5585
|
const parsed = schemas3.PartialEventSchema.safeParse(event);
|
|
@@ -5740,58 +5671,17 @@ async function simulateTransformer(configOrPath, event, options) {
|
|
|
5740
5671
|
};
|
|
5741
5672
|
const captured = [];
|
|
5742
5673
|
logger.info(`Simulating transformer: ${options.transformerId}`);
|
|
5743
|
-
|
|
5744
|
-
const before = transformer.config.before;
|
|
5745
|
-
if (before && collector.transformers) {
|
|
5746
|
-
const beforeChainIds = resolveBeforeChain(
|
|
5747
|
-
before,
|
|
5748
|
-
collector.transformers,
|
|
5749
|
-
ingest,
|
|
5750
|
-
processedEvent
|
|
5751
|
-
);
|
|
5752
|
-
if (beforeChainIds.length > 0) {
|
|
5753
|
-
const beforeResult = await runTransformerChain(
|
|
5754
|
-
collector,
|
|
5755
|
-
collector.transformers,
|
|
5756
|
-
beforeChainIds,
|
|
5757
|
-
processedEvent,
|
|
5758
|
-
ingest,
|
|
5759
|
-
void 0,
|
|
5760
|
-
`transformer.${options.transformerId}.before`
|
|
5761
|
-
);
|
|
5762
|
-
if (beforeResult === null) {
|
|
5763
|
-
captured.push({ event: null, timestamp: Date.now() });
|
|
5764
|
-
await collector.command("shutdown");
|
|
5765
|
-
return buildSimulationResult({
|
|
5766
|
-
step: "transformer",
|
|
5767
|
-
name: options.transformerId,
|
|
5768
|
-
startTime,
|
|
5769
|
-
captured
|
|
5770
|
-
});
|
|
5771
|
-
}
|
|
5772
|
-
processedEvent = Array.isArray(beforeResult) ? beforeResult[0] : beforeResult;
|
|
5773
|
-
}
|
|
5774
|
-
}
|
|
5775
|
-
const pushResult = await transformerPush(
|
|
5674
|
+
const outputs = await runTransformerSimulation(
|
|
5776
5675
|
collector,
|
|
5777
|
-
transformer,
|
|
5778
5676
|
options.transformerId,
|
|
5779
|
-
|
|
5677
|
+
inputEvent,
|
|
5780
5678
|
ingest
|
|
5781
5679
|
);
|
|
5782
|
-
if (
|
|
5680
|
+
if (outputs.length === 0) {
|
|
5783
5681
|
captured.push({ event: null, timestamp: Date.now() });
|
|
5784
|
-
}
|
|
5785
|
-
|
|
5786
|
-
|
|
5787
|
-
event: r.event || processedEvent,
|
|
5788
|
-
timestamp: Date.now()
|
|
5789
|
-
});
|
|
5790
|
-
}
|
|
5791
|
-
} else if (pushResult && typeof pushResult === "object" && pushResult.event) {
|
|
5792
|
-
captured.push({ event: pushResult.event, timestamp: Date.now() });
|
|
5793
|
-
} else {
|
|
5794
|
-
captured.push({ event: processedEvent, timestamp: Date.now() });
|
|
5682
|
+
}
|
|
5683
|
+
for (const output of outputs) {
|
|
5684
|
+
captured.push({ event: output, timestamp: Date.now() });
|
|
5795
5685
|
}
|
|
5796
5686
|
await collector.command("shutdown");
|
|
5797
5687
|
return buildSimulationResult({
|
|
@@ -5819,6 +5709,13 @@ async function simulateTransformer(configOrPath, event, options) {
|
|
|
5819
5709
|
await prepared.cleanup();
|
|
5820
5710
|
}
|
|
5821
5711
|
}
|
|
5712
|
+
async function runCollectorSimulation(collector, event) {
|
|
5713
|
+
const enriched = enrichEvent(collector, event);
|
|
5714
|
+
const result = await runCollectorNext(collector, enriched, {
|
|
5715
|
+
ingest: createIngest("collector")
|
|
5716
|
+
});
|
|
5717
|
+
return result.copies.map((copy) => copy.event);
|
|
5718
|
+
}
|
|
5822
5719
|
async function simulateCollector(configOrPath, event, options) {
|
|
5823
5720
|
const startTime = Date.now();
|
|
5824
5721
|
const parsed = schemas3.PartialEventSchema.safeParse(event);
|
|
@@ -5842,6 +5739,7 @@ async function simulateCollector(configOrPath, event, options) {
|
|
|
5842
5739
|
config,
|
|
5843
5740
|
flow: options.flow,
|
|
5844
5741
|
simulate: ["collector." + options.collectorName],
|
|
5742
|
+
mock: options.mock,
|
|
5845
5743
|
silent: options.silent,
|
|
5846
5744
|
verbose: options.verbose
|
|
5847
5745
|
} : {
|
|
@@ -5849,6 +5747,7 @@ async function simulateCollector(configOrPath, event, options) {
|
|
|
5849
5747
|
config,
|
|
5850
5748
|
flow: options.flow,
|
|
5851
5749
|
simulate: ["collector." + options.collectorName],
|
|
5750
|
+
mock: options.mock,
|
|
5852
5751
|
silent: options.silent,
|
|
5853
5752
|
verbose: options.verbose
|
|
5854
5753
|
};
|
|
@@ -5895,8 +5794,11 @@ async function simulateCollector(configOrPath, event, options) {
|
|
|
5895
5794
|
if (options.state.timing !== void 0)
|
|
5896
5795
|
collector.timing = options.state.timing;
|
|
5897
5796
|
}
|
|
5898
|
-
const
|
|
5899
|
-
const captured =
|
|
5797
|
+
const outputs = await runCollectorSimulation(collector, event);
|
|
5798
|
+
const captured = outputs.length > 0 ? outputs.map((output) => ({
|
|
5799
|
+
event: output,
|
|
5800
|
+
timestamp: Date.now()
|
|
5801
|
+
})) : [{ event: null, timestamp: Date.now() }];
|
|
5900
5802
|
await collector.command("shutdown");
|
|
5901
5803
|
return buildSimulationResult({
|
|
5902
5804
|
step: "collector",
|
|
@@ -8120,6 +8022,7 @@ function validateEvent2(input) {
|
|
|
8120
8022
|
// src/commands/validate/validators/flow.ts
|
|
8121
8023
|
import {
|
|
8122
8024
|
getFlowSettings as getFlowSettings2,
|
|
8025
|
+
getRouteGraph,
|
|
8123
8026
|
isObject as isObject5,
|
|
8124
8027
|
resolveContracts,
|
|
8125
8028
|
validateStepEntry as validateStepEntry2
|
|
@@ -8236,6 +8139,15 @@ function validateFlow(input, options = {}) {
|
|
|
8236
8139
|
if (coreResult.context) {
|
|
8237
8140
|
details.context = coreResult.context;
|
|
8238
8141
|
}
|
|
8142
|
+
if (errors.length === 0 && isFlowJson(input)) {
|
|
8143
|
+
const typedFlows = input.flows;
|
|
8144
|
+
const flowsToLint = options.flow ? options.flow in typedFlows ? [options.flow] : [] : Object.keys(typedFlows);
|
|
8145
|
+
for (const name of flowsToLint) {
|
|
8146
|
+
const flowSettings = typedFlows[name];
|
|
8147
|
+
if (!flowSettings) continue;
|
|
8148
|
+
lintFlowRoutes(name, flowSettings, errors, warnings);
|
|
8149
|
+
}
|
|
8150
|
+
}
|
|
8239
8151
|
if (errors.length === 0 && isFlowJson(input)) {
|
|
8240
8152
|
const typedFlows = input.flows;
|
|
8241
8153
|
const flowNames = Object.keys(typedFlows);
|
|
@@ -8283,15 +8195,6 @@ function validateFlow(input, options = {}) {
|
|
|
8283
8195
|
}
|
|
8284
8196
|
}
|
|
8285
8197
|
}
|
|
8286
|
-
if (errors.length === 0 && isFlowJson(input)) {
|
|
8287
|
-
const typedFlows = input.flows;
|
|
8288
|
-
const flowsToLint = options.flow ? options.flow in typedFlows ? [options.flow] : [] : Object.keys(typedFlows);
|
|
8289
|
-
for (const name of flowsToLint) {
|
|
8290
|
-
const flowSettings = typedFlows[name];
|
|
8291
|
-
if (!flowSettings) continue;
|
|
8292
|
-
lintFlowRoutes(name, flowSettings, warnings);
|
|
8293
|
-
}
|
|
8294
|
-
}
|
|
8295
8198
|
if (errors.length === 0 && isFlowJson(input)) {
|
|
8296
8199
|
const flowsMap = input.flows;
|
|
8297
8200
|
const flowsToResolve = options.flow ? options.flow in flowsMap ? [options.flow] : [] : Object.keys(flowsMap);
|
|
@@ -8325,48 +8228,19 @@ function validateFlow(input, options = {}) {
|
|
|
8325
8228
|
details
|
|
8326
8229
|
};
|
|
8327
8230
|
}
|
|
8328
|
-
function
|
|
8329
|
-
|
|
8330
|
-
|
|
8331
|
-
|
|
8332
|
-
|
|
8333
|
-
const value = spec.next;
|
|
8334
|
-
return value !== void 0;
|
|
8335
|
-
}
|
|
8336
|
-
function isRouteOne(spec) {
|
|
8337
|
-
if (!("one" in spec)) return false;
|
|
8338
|
-
const value = spec.one;
|
|
8339
|
-
return Array.isArray(value);
|
|
8340
|
-
}
|
|
8341
|
-
function isRouteMany(spec) {
|
|
8342
|
-
if (!("many" in spec)) return false;
|
|
8343
|
-
const value = spec.many;
|
|
8344
|
-
return Array.isArray(value);
|
|
8345
|
-
}
|
|
8346
|
-
function flattenRouteTargets(spec) {
|
|
8347
|
-
if (!spec) return [];
|
|
8348
|
-
if (typeof spec === "string") return [spec];
|
|
8349
|
-
if (isRouteConfig(spec)) {
|
|
8350
|
-
if (isRouteNext(spec)) return flattenRouteTargets(spec.next);
|
|
8351
|
-
if (isRouteOne(spec)) {
|
|
8352
|
-
return Array.from(new Set(spec.one.flatMap(flattenRouteTargets)));
|
|
8353
|
-
}
|
|
8354
|
-
if (isRouteMany(spec)) {
|
|
8355
|
-
return Array.from(new Set(spec.many.flatMap(flattenRouteTargets)));
|
|
8356
|
-
}
|
|
8357
|
-
return [];
|
|
8358
|
-
}
|
|
8359
|
-
if (spec.length === 0) return [];
|
|
8360
|
-
if (typeof spec[0] === "string") {
|
|
8361
|
-
return spec.filter((s) => typeof s === "string");
|
|
8231
|
+
function routeTargets(spec) {
|
|
8232
|
+
if (spec === void 0) return [];
|
|
8233
|
+
const targets = /* @__PURE__ */ new Set();
|
|
8234
|
+
for (const node of getRouteGraph(spec)) {
|
|
8235
|
+
for (const target of node.targets) targets.add(target);
|
|
8362
8236
|
}
|
|
8363
|
-
return
|
|
8237
|
+
return [...targets];
|
|
8364
8238
|
}
|
|
8365
8239
|
function buildConnectionGraph(config) {
|
|
8366
8240
|
const connections = [];
|
|
8367
8241
|
for (const [name, source] of Object.entries(config.sources || {})) {
|
|
8368
8242
|
if (!source.next || !source.examples) continue;
|
|
8369
|
-
const nextNames =
|
|
8243
|
+
const nextNames = routeTargets(source.next);
|
|
8370
8244
|
for (const nextName of nextNames) {
|
|
8371
8245
|
const transformer = config.transformers?.[nextName];
|
|
8372
8246
|
if (transformer?.examples) {
|
|
@@ -8383,7 +8257,7 @@ function buildConnectionGraph(config) {
|
|
|
8383
8257
|
}
|
|
8384
8258
|
for (const [name, transformer] of Object.entries(config.transformers || {})) {
|
|
8385
8259
|
if (!transformer.next || !transformer.examples) continue;
|
|
8386
|
-
const nextNames =
|
|
8260
|
+
const nextNames = routeTargets(transformer.next);
|
|
8387
8261
|
for (const nextName of nextNames) {
|
|
8388
8262
|
const nextTransformer = config.transformers?.[nextName];
|
|
8389
8263
|
if (nextTransformer?.examples) {
|
|
@@ -8404,7 +8278,7 @@ function buildConnectionGraph(config) {
|
|
|
8404
8278
|
}
|
|
8405
8279
|
for (const [name, dest] of Object.entries(config.destinations || {})) {
|
|
8406
8280
|
if (!dest.before || !dest.examples) continue;
|
|
8407
|
-
const beforeNames =
|
|
8281
|
+
const beforeNames = routeTargets(dest.before);
|
|
8408
8282
|
for (const beforeName of beforeNames) {
|
|
8409
8283
|
const transformer = config.transformers?.[beforeName];
|
|
8410
8284
|
if (transformer?.examples) {
|
|
@@ -8422,8 +8296,8 @@ function buildConnectionGraph(config) {
|
|
|
8422
8296
|
return connections;
|
|
8423
8297
|
}
|
|
8424
8298
|
function checkCompatibility(conn, errors, warnings) {
|
|
8425
|
-
const fromOuts = Object.entries(conn.from.examples).filter(([, ex]) => ex.out
|
|
8426
|
-
const toIns = Object.entries(conn.to.examples).filter(([, ex]) => ex.in !== void 0).map(([name, ex]) => ({ name, value: ex.in }));
|
|
8299
|
+
const fromOuts = Object.entries(conn.from.examples).filter(([, ex]) => hasComparableOut(ex.out)).map(([name, ex]) => ({ name, value: ex.out }));
|
|
8300
|
+
const toIns = Object.entries(conn.to.examples).filter(([, ex]) => ex.in !== void 0 && !ex.command).map(([name, ex]) => ({ name, value: ex.in }));
|
|
8427
8301
|
const path20 = `${conn.from.type}.${conn.from.name} \u2192 ${conn.to.type}.${conn.to.name}`;
|
|
8428
8302
|
if (fromOuts.length === 0 || toIns.length === 0) {
|
|
8429
8303
|
warnings.push({
|
|
@@ -8451,6 +8325,10 @@ function checkCompatibility(conn, errors, warnings) {
|
|
|
8451
8325
|
});
|
|
8452
8326
|
}
|
|
8453
8327
|
}
|
|
8328
|
+
function hasComparableOut(out) {
|
|
8329
|
+
if (Array.isArray(out) || typeof out === "string") return out.length > 0;
|
|
8330
|
+
return isObject5(out) && Object.keys(out).length > 0;
|
|
8331
|
+
}
|
|
8454
8332
|
function isStructurallyCompatible(a, b) {
|
|
8455
8333
|
if (typeof a !== typeof b) return false;
|
|
8456
8334
|
if (a === null || b === null) return a === b;
|
|
@@ -8463,87 +8341,98 @@ function isStructurallyCompatible(a, b) {
|
|
|
8463
8341
|
}
|
|
8464
8342
|
return true;
|
|
8465
8343
|
}
|
|
8466
|
-
function lintFlowRoutes(flowName, flow, warnings) {
|
|
8344
|
+
function lintFlowRoutes(flowName, flow, errors, warnings) {
|
|
8345
|
+
const known = new Set(Object.keys(flow.transformers || {}));
|
|
8346
|
+
const check = (spec, position) => {
|
|
8347
|
+
if (spec !== void 0) lintRoute(spec, position, known, errors, warnings);
|
|
8348
|
+
};
|
|
8349
|
+
const at = `flows.${flowName}`;
|
|
8467
8350
|
for (const [name, source] of Object.entries(flow.sources || {})) {
|
|
8468
|
-
|
|
8469
|
-
|
|
8470
|
-
source.before,
|
|
8471
|
-
`flows.${flowName}.sources.${name}.before`,
|
|
8472
|
-
warnings
|
|
8473
|
-
);
|
|
8351
|
+
check(source.before, `${at}.sources.${name}.before`);
|
|
8352
|
+
check(source.next, `${at}.sources.${name}.next`);
|
|
8474
8353
|
}
|
|
8475
8354
|
for (const [name, transformer] of Object.entries(flow.transformers || {})) {
|
|
8476
|
-
|
|
8477
|
-
|
|
8478
|
-
`flows.${flowName}.transformers.${name}.next`,
|
|
8479
|
-
warnings
|
|
8480
|
-
);
|
|
8481
|
-
lintRoute(
|
|
8482
|
-
transformer.before,
|
|
8483
|
-
`flows.${flowName}.transformers.${name}.before`,
|
|
8484
|
-
warnings
|
|
8485
|
-
);
|
|
8355
|
+
check(transformer.before, `${at}.transformers.${name}.before`);
|
|
8356
|
+
check(transformer.next, `${at}.transformers.${name}.next`);
|
|
8486
8357
|
}
|
|
8358
|
+
check(flow.collector?.next, `${at}.collector.next`);
|
|
8487
8359
|
for (const [name, dest] of Object.entries(flow.destinations || {})) {
|
|
8488
|
-
|
|
8489
|
-
|
|
8490
|
-
`flows.${flowName}.destinations.${name}.before`,
|
|
8491
|
-
warnings
|
|
8492
|
-
);
|
|
8493
|
-
lintRoute(
|
|
8494
|
-
dest.next,
|
|
8495
|
-
`flows.${flowName}.destinations.${name}.next`,
|
|
8496
|
-
warnings
|
|
8497
|
-
);
|
|
8360
|
+
check(dest.before, `${at}.destinations.${name}.before`);
|
|
8361
|
+
check(dest.next, `${at}.destinations.${name}.next`);
|
|
8498
8362
|
}
|
|
8499
8363
|
}
|
|
8500
|
-
function
|
|
8501
|
-
|
|
8502
|
-
|
|
8503
|
-
|
|
8504
|
-
|
|
8505
|
-
|
|
8506
|
-
|
|
8364
|
+
function routeAt(spec, path20) {
|
|
8365
|
+
let current = spec;
|
|
8366
|
+
for (const key of path20) {
|
|
8367
|
+
if (typeof key === "number")
|
|
8368
|
+
current = Array.isArray(current) ? current[key] : void 0;
|
|
8369
|
+
else current = isObject5(current) ? current[key] : void 0;
|
|
8370
|
+
}
|
|
8371
|
+
return current;
|
|
8372
|
+
}
|
|
8373
|
+
function lintRoute(spec, position, known, errors, warnings) {
|
|
8374
|
+
const where = (path20) => path20.length > 0 ? `${position}.${path20.join(".")}` : position;
|
|
8375
|
+
const reported = /* @__PURE__ */ new Set();
|
|
8376
|
+
const once = (key) => {
|
|
8377
|
+
if (reported.has(key)) return false;
|
|
8378
|
+
reported.add(key);
|
|
8379
|
+
return true;
|
|
8380
|
+
};
|
|
8381
|
+
for (const node of getRouteGraph(spec)) {
|
|
8382
|
+
for (const target of node.targets) {
|
|
8383
|
+
if (known.has(target) || !once(`unknown:${target}`)) continue;
|
|
8384
|
+
errors.push({
|
|
8385
|
+
path: position,
|
|
8386
|
+
message: `Unknown transformer "${target}" in route at ${position}`,
|
|
8387
|
+
code: "UNKNOWN_ROUTE_TARGET"
|
|
8388
|
+
});
|
|
8389
|
+
}
|
|
8390
|
+
const last = node.path[node.path.length - 1];
|
|
8391
|
+
if (node.stop && !node.match && node.kind !== "many") {
|
|
8392
|
+
const self = routeAt(spec, node.path);
|
|
8393
|
+
const list = routeAt(spec, node.path.slice(0, -1));
|
|
8394
|
+
if (isObject5(self) && self.stop === true && typeof last === "number" && Array.isArray(list) && last < list.length - 1 && once(`stop:${where(node.path)}`)) {
|
|
8395
|
+
const at = where(node.path);
|
|
8507
8396
|
warnings.push({
|
|
8508
|
-
path:
|
|
8509
|
-
message: `dead code after
|
|
8510
|
-
suggestion: "Remove entries after the
|
|
8397
|
+
path: at,
|
|
8398
|
+
message: `dead code after stop at ${at}: entries after an unconditional stop never run`,
|
|
8399
|
+
suggestion: "Remove the entries after the stop, or give the stop a match."
|
|
8511
8400
|
});
|
|
8512
8401
|
}
|
|
8513
|
-
lintRoute(entry, `${position}[${i}]`, warnings);
|
|
8514
|
-
}
|
|
8515
|
-
return;
|
|
8516
|
-
}
|
|
8517
|
-
if (isRouteNext(spec)) {
|
|
8518
|
-
lintRoute(spec.next, `${position}.next`, warnings);
|
|
8519
|
-
return;
|
|
8520
|
-
}
|
|
8521
|
-
if (isRouteOne(spec)) {
|
|
8522
|
-
for (let i = 0; i < spec.one.length; i++) {
|
|
8523
|
-
lintRoute(spec.one[i], `${position}.one[${i}]`, warnings);
|
|
8524
8402
|
}
|
|
8525
|
-
|
|
8526
|
-
|
|
8527
|
-
if (isRouteMany(spec)) {
|
|
8528
|
-
if (spec.many.length === 0) {
|
|
8529
|
-
warnings.push({
|
|
8530
|
-
path: position,
|
|
8531
|
-
message: `empty many at ${position}: main chain terminates with no branches; use next or remove`,
|
|
8532
|
-
suggestion: "Add one or more branch targets to many, or replace many with next if no fan-out is needed."
|
|
8533
|
-
});
|
|
8534
|
-
} else if (spec.many.length === 1) {
|
|
8535
|
-
const only = spec.many[0];
|
|
8536
|
-
const hint = typeof only === "string" ? `use 'next: "${only}"' for clarity` : `use 'next' for clarity`;
|
|
8403
|
+
if (node.kind === "many" && last === "many" && node.targets.length === 0 && once(`empty:${where(node.path)}`)) {
|
|
8404
|
+
const at = where(node.path.slice(0, -1));
|
|
8537
8405
|
warnings.push({
|
|
8538
|
-
path:
|
|
8539
|
-
message: `
|
|
8540
|
-
suggestion: "
|
|
8406
|
+
path: at,
|
|
8407
|
+
message: `empty many at ${at}: selects no branch, so it has no effect`,
|
|
8408
|
+
suggestion: "Add two or more branch targets to many, or remove it."
|
|
8541
8409
|
});
|
|
8542
8410
|
}
|
|
8543
|
-
for (
|
|
8544
|
-
|
|
8411
|
+
for (const decision of [...node.via ?? [], node]) {
|
|
8412
|
+
const index = decision.path[decision.path.length - 1];
|
|
8413
|
+
if (typeof index !== "number") continue;
|
|
8414
|
+
const listPath = decision.path.slice(0, -1);
|
|
8415
|
+
const list = routeAt(spec, listPath);
|
|
8416
|
+
if (!Array.isArray(list)) continue;
|
|
8417
|
+
const at = where(listPath);
|
|
8418
|
+
if (decision.kind === "many" && list.length === 1 && once(`single:${at}`)) {
|
|
8419
|
+
const only = list[0];
|
|
8420
|
+
const hint = typeof only === "string" ? `use 'next: "${only}"' for clarity` : `use 'next' for clarity`;
|
|
8421
|
+
warnings.push({
|
|
8422
|
+
path: at,
|
|
8423
|
+
message: `single-entry many at ${at}: ${hint}`,
|
|
8424
|
+
suggestion: "Replace many with next when only one branch exists."
|
|
8425
|
+
});
|
|
8426
|
+
}
|
|
8427
|
+
const explicitOne = listPath[listPath.length - 1] === "one";
|
|
8428
|
+
if (decision.kind === "one" && !explicitOne && list.length > 1 && once(`first-match:${at}`)) {
|
|
8429
|
+
warnings.push({
|
|
8430
|
+
path: at,
|
|
8431
|
+
message: `first-match array at ${at}: an array made only of route configs is an implicit one, the first matching entry wins`,
|
|
8432
|
+
suggestion: 'Write { "one": [...] } explicitly, or add the step ids as a sequence to run every entry in order.'
|
|
8433
|
+
});
|
|
8434
|
+
}
|
|
8545
8435
|
}
|
|
8546
|
-
return;
|
|
8547
8436
|
}
|
|
8548
8437
|
}
|
|
8549
8438
|
function checkContractCompliance(config, contract, errors, warnings, strict) {
|
|
@@ -8641,7 +8530,7 @@ function validateMapping(input) {
|
|
|
8641
8530
|
// src/commands/validate/validators/entry.ts
|
|
8642
8531
|
import Ajv from "ajv";
|
|
8643
8532
|
import { fetchPackageSchema } from "@walkeros/core";
|
|
8644
|
-
var CLIENT_HEADER = "walkeros-cli/4.
|
|
8533
|
+
var CLIENT_HEADER = "walkeros-cli/4.7.0-next-1790187973605";
|
|
8645
8534
|
var SECTIONS = ["destinations", "sources", "transformers"];
|
|
8646
8535
|
function resolveEntry(path20, flowConfig) {
|
|
8647
8536
|
const flows = flowConfig.flows;
|
|
@@ -8748,7 +8637,7 @@ async function validateEntry(path20, flowConfig) {
|
|
|
8748
8637
|
}
|
|
8749
8638
|
const config = entry.config;
|
|
8750
8639
|
const settings = config?.settings;
|
|
8751
|
-
const ajv = new Ajv({ allErrors: true });
|
|
8640
|
+
const ajv = new Ajv({ allErrors: true, validateFormats: false });
|
|
8752
8641
|
const validate2 = ajv.compile(settingsSchema);
|
|
8753
8642
|
const isValid = validate2(settings || {});
|
|
8754
8643
|
if (!isValid) {
|
|
@@ -8778,10 +8667,8 @@ async function validateEntry(path20, flowConfig) {
|
|
|
8778
8667
|
async function validate(type, input, options = {}) {
|
|
8779
8668
|
let resolved = input;
|
|
8780
8669
|
if (typeof input === "string") {
|
|
8781
|
-
|
|
8782
|
-
|
|
8783
|
-
required: true
|
|
8784
|
-
});
|
|
8670
|
+
if (input.trim() === "") throw new Error(`${type} is required`);
|
|
8671
|
+
resolved = await loadJsonConfig(input);
|
|
8785
8672
|
}
|
|
8786
8673
|
if (options.path) {
|
|
8787
8674
|
return validateEntry(options.path, resolved);
|
|
@@ -10897,108 +10784,6 @@ init_config_file();
|
|
|
10897
10784
|
init_sse();
|
|
10898
10785
|
init_utils();
|
|
10899
10786
|
|
|
10900
|
-
// src/commands/simulate/example-loader.ts
|
|
10901
|
-
function findExample(config, exampleName, stepTarget) {
|
|
10902
|
-
if (stepTarget) {
|
|
10903
|
-
return findExampleInStep(config, exampleName, stepTarget);
|
|
10904
|
-
}
|
|
10905
|
-
return findExampleAcrossSteps(config, exampleName);
|
|
10906
|
-
}
|
|
10907
|
-
function findExampleInStep(config, exampleName, stepTarget) {
|
|
10908
|
-
const dotIndex = stepTarget.indexOf(".");
|
|
10909
|
-
if (dotIndex === -1) {
|
|
10910
|
-
throw new Error(
|
|
10911
|
-
`Invalid --step format: "${stepTarget}". Expected "type.name" (e.g. "destination.gtag")`
|
|
10912
|
-
);
|
|
10913
|
-
}
|
|
10914
|
-
const type = stepTarget.substring(0, dotIndex);
|
|
10915
|
-
const name = stepTarget.substring(dotIndex + 1);
|
|
10916
|
-
const stepMap = getStepMap(config, type);
|
|
10917
|
-
if (!stepMap) {
|
|
10918
|
-
throw new Error(`No ${type}s found in flow config`);
|
|
10919
|
-
}
|
|
10920
|
-
const step = stepMap[name];
|
|
10921
|
-
if (!step) {
|
|
10922
|
-
const available = Object.keys(stepMap).join(", ");
|
|
10923
|
-
throw new Error(`${type} "${name}" not found. Available: ${available}`);
|
|
10924
|
-
}
|
|
10925
|
-
const examples = step.examples;
|
|
10926
|
-
if (!examples || !examples[exampleName]) {
|
|
10927
|
-
const available = examples ? Object.keys(examples).join(", ") : "none";
|
|
10928
|
-
throw new Error(
|
|
10929
|
-
`Example "${exampleName}" not found in ${type} "${name}". Available: ${available}`
|
|
10930
|
-
);
|
|
10931
|
-
}
|
|
10932
|
-
return {
|
|
10933
|
-
stepType: type,
|
|
10934
|
-
stepName: name,
|
|
10935
|
-
exampleName,
|
|
10936
|
-
example: examples[exampleName]
|
|
10937
|
-
};
|
|
10938
|
-
}
|
|
10939
|
-
function findExampleAcrossSteps(config, exampleName) {
|
|
10940
|
-
const matches = [];
|
|
10941
|
-
const stepTypes = ["source", "transformer", "destination"];
|
|
10942
|
-
for (const type of stepTypes) {
|
|
10943
|
-
const stepMap = getStepMap(config, type);
|
|
10944
|
-
if (!stepMap) continue;
|
|
10945
|
-
for (const [name, step] of Object.entries(stepMap)) {
|
|
10946
|
-
const examples = step.examples;
|
|
10947
|
-
if (examples && examples[exampleName]) {
|
|
10948
|
-
matches.push({
|
|
10949
|
-
stepType: type,
|
|
10950
|
-
stepName: name,
|
|
10951
|
-
exampleName,
|
|
10952
|
-
example: examples[exampleName]
|
|
10953
|
-
});
|
|
10954
|
-
}
|
|
10955
|
-
}
|
|
10956
|
-
}
|
|
10957
|
-
if (matches.length === 0) {
|
|
10958
|
-
throw new Error(`Example "${exampleName}" not found in any step`);
|
|
10959
|
-
}
|
|
10960
|
-
if (matches.length > 1) {
|
|
10961
|
-
const locations = matches.map((m) => `${m.stepType}.${m.stepName}`).join(", ");
|
|
10962
|
-
throw new Error(
|
|
10963
|
-
`Example "${exampleName}" found in multiple steps: ${locations}. Use --step to disambiguate.`
|
|
10964
|
-
);
|
|
10965
|
-
}
|
|
10966
|
-
return matches[0];
|
|
10967
|
-
}
|
|
10968
|
-
function getStepMap(config, type) {
|
|
10969
|
-
switch (type) {
|
|
10970
|
-
case "source":
|
|
10971
|
-
return config.sources;
|
|
10972
|
-
case "transformer":
|
|
10973
|
-
return config.transformers;
|
|
10974
|
-
case "destination":
|
|
10975
|
-
return config.destinations;
|
|
10976
|
-
default:
|
|
10977
|
-
throw new Error(
|
|
10978
|
-
`Invalid step type: "${type}". Must be "source", "transformer", or "destination"`
|
|
10979
|
-
);
|
|
10980
|
-
}
|
|
10981
|
-
}
|
|
10982
|
-
|
|
10983
|
-
// src/commands/simulate/compare.ts
|
|
10984
|
-
function compareOutput(expected, actual) {
|
|
10985
|
-
const expectedStr = JSON.stringify(expected, null, 2);
|
|
10986
|
-
const actualStr = JSON.stringify(actual, null, 2);
|
|
10987
|
-
if (expectedStr === actualStr) {
|
|
10988
|
-
return { expected, actual, match: true };
|
|
10989
|
-
}
|
|
10990
|
-
return {
|
|
10991
|
-
expected,
|
|
10992
|
-
actual,
|
|
10993
|
-
match: false,
|
|
10994
|
-
diff: `Expected:
|
|
10995
|
-
${expectedStr}
|
|
10996
|
-
|
|
10997
|
-
Actual:
|
|
10998
|
-
${actualStr}`
|
|
10999
|
-
};
|
|
11000
|
-
}
|
|
11001
|
-
|
|
11002
10787
|
// src/telemetry/index.ts
|
|
11003
10788
|
var telemetry_exports = {};
|
|
11004
10789
|
__export(telemetry_exports, {
|
|
@@ -11217,7 +11002,6 @@ export {
|
|
|
11217
11002
|
clearAuthFields,
|
|
11218
11003
|
clientContextHeaders,
|
|
11219
11004
|
compareContract,
|
|
11220
|
-
compareOutput,
|
|
11221
11005
|
completeDeviceLogin,
|
|
11222
11006
|
containsCodeMarkers,
|
|
11223
11007
|
createApiClient,
|
|
@@ -11251,7 +11035,6 @@ export {
|
|
|
11251
11035
|
feedback,
|
|
11252
11036
|
feedbackCommand,
|
|
11253
11037
|
fetchHealth,
|
|
11254
|
-
findExample,
|
|
11255
11038
|
getAuthHeaders,
|
|
11256
11039
|
getClientContext,
|
|
11257
11040
|
getDefaultProject,
|