@walkeros/cli 1.1.3 → 1.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +12 -0
- package/dist/examples/flow-complete.json +10 -1
- package/dist/examples/flow-complete.md +23 -24
- package/dist/index.d.ts +29 -1
- package/dist/index.js +297 -3
- package/dist/index.js.map +1 -1
- package/examples/flow-complete.json +10 -1
- package/examples/flow-complete.md +23 -24
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,17 @@
|
|
|
1
1
|
# @walkeros/cli
|
|
2
2
|
|
|
3
|
+
## 1.2.0
|
|
4
|
+
|
|
5
|
+
### Minor Changes
|
|
6
|
+
|
|
7
|
+
- cc68f50: Add validate command for events, flows, and mappings
|
|
8
|
+
- `walkeros validate event` - validates event structure using
|
|
9
|
+
PartialEventSchema
|
|
10
|
+
- `walkeros validate flow` - validates flow configurations using SetupSchema
|
|
11
|
+
- `walkeros validate mapping` - validates mapping event patterns
|
|
12
|
+
|
|
13
|
+
Includes programmatic API via `import { validate } from '@walkeros/cli'`
|
|
14
|
+
|
|
3
15
|
## 1.1.3
|
|
4
16
|
|
|
5
17
|
### Patch Changes
|
|
@@ -250,7 +250,10 @@
|
|
|
250
250
|
"this",
|
|
251
251
|
{
|
|
252
252
|
"map": {
|
|
253
|
-
"item_id":
|
|
253
|
+
"item_id": [
|
|
254
|
+
{ "key": "data.sku" },
|
|
255
|
+
{ "key": "data.id" }
|
|
256
|
+
],
|
|
254
257
|
"item_name": "data.name",
|
|
255
258
|
"item_category": "data.category",
|
|
256
259
|
"price": "data.price"
|
|
@@ -322,6 +325,12 @@
|
|
|
322
325
|
"url": "$var.apiUrl",
|
|
323
326
|
"batch": 5
|
|
324
327
|
},
|
|
328
|
+
"data": {
|
|
329
|
+
"map": {
|
|
330
|
+
"sent_at": { "fn": "$code:() => Date.now()" },
|
|
331
|
+
"flow_version": "$var.flowVersion"
|
|
332
|
+
}
|
|
333
|
+
},
|
|
325
334
|
"mapping": {
|
|
326
335
|
"order": {
|
|
327
336
|
"complete": {
|
|
@@ -71,7 +71,7 @@ npx walkeros serve packages/cli/examples/flow-complete.json --flow web
|
|
|
71
71
|
|
|
72
72
|
## Feature Inventory
|
|
73
73
|
|
|
74
|
-
### Features Used (
|
|
74
|
+
### Features Used (53)
|
|
75
75
|
|
|
76
76
|
#### Mapping - Value Extraction
|
|
77
77
|
|
|
@@ -81,6 +81,7 @@ npx walkeros serve packages/cli/examples/flow-complete.json --flow web
|
|
|
81
81
|
| Static value | Meta ViewContent | `"content_type": { "value": "product" }` |
|
|
82
82
|
| Key with fallback | GA4 add_to_cart | `{ "key": "data.currency", "value": "$variables.currency" }` |
|
|
83
83
|
| Nested key (deep) | dataLayer mapping | `"items.0.item_id"` |
|
|
84
|
+
| Fallback array | GA4 view_item | `[{ "key": "data.sku" }, { "key": "data.id" }]` |
|
|
84
85
|
|
|
85
86
|
#### Mapping - Structure
|
|
86
87
|
|
|
@@ -92,6 +93,7 @@ npx walkeros serve packages/cli/examples/flow-complete.json --flow web
|
|
|
92
93
|
| Set (single value) | Meta ViewContent | `"content_ids": { "set": ["data.id"] }` |
|
|
93
94
|
| Set (multiple values) | Meta settings | `"external_id": { "set": ["user.device", "user.session"] }` |
|
|
94
95
|
| Direct passthrough | Meta PageView | `"data": "data"` |
|
|
96
|
+
| Config-level data | API destination | `"data": { "map": { "sent_at": {...} } }` |
|
|
95
97
|
|
|
96
98
|
#### Mapping - Control
|
|
97
99
|
|
|
@@ -175,36 +177,33 @@ npx walkeros serve packages/cli/examples/flow-complete.json --flow web
|
|
|
175
177
|
|
|
176
178
|
---
|
|
177
179
|
|
|
178
|
-
### Features NOT Used (
|
|
180
|
+
### Features NOT Used (6)
|
|
179
181
|
|
|
180
|
-
####
|
|
182
|
+
#### Now Available via $code: Prefix ✅
|
|
181
183
|
|
|
182
|
-
These features
|
|
184
|
+
These features are now fully supported in JSON via `$code:` prefix (and ARE used
|
|
185
|
+
in this example):
|
|
183
186
|
|
|
184
|
-
| Feature |
|
|
185
|
-
| --------------------------- |
|
|
186
|
-
| `fn:` function |
|
|
187
|
-
| `condition:` |
|
|
188
|
-
| Conditional mapping (array) |
|
|
189
|
-
| Custom transformer code |
|
|
190
|
-
| Custom
|
|
191
|
-
| Custom destination code | Requires JavaScript |
|
|
192
|
-
| Event handler callbacks | Requires JavaScript |
|
|
187
|
+
| Feature | Status |
|
|
188
|
+
| --------------------------- | ----------------------------------- |
|
|
189
|
+
| `fn:` function | ✅ Used via `$code:` in GA4 value |
|
|
190
|
+
| `condition:` | ✅ Used via `$code:` in definitions |
|
|
191
|
+
| Conditional mapping (array) | ✅ Used in serverValidator |
|
|
192
|
+
| Custom transformer code | ✅ Used in enricher, filter |
|
|
193
|
+
| Custom destination code | ✅ Used in debug logger |
|
|
193
194
|
|
|
194
|
-
#### Omitted for Clarity (
|
|
195
|
+
#### Omitted for Clarity (6)
|
|
195
196
|
|
|
196
197
|
These features could be added but were omitted to keep the example focused:
|
|
197
198
|
|
|
198
|
-
| Feature | Why Omitted
|
|
199
|
-
| ------------------------- |
|
|
200
|
-
| Multiple named flows (3+) | Two flows sufficient for demo
|
|
201
|
-
| Queue config | Advanced batching scenario
|
|
202
|
-
| Retry config | Advanced error handling
|
|
203
|
-
| Custom fetch options | API destination advanced
|
|
204
|
-
|
|
|
205
|
-
|
|
|
206
|
-
| Custom headers in API | Would add complexity |
|
|
207
|
-
| Multiple validators | One per flow sufficient |
|
|
199
|
+
| Feature | Why Omitted |
|
|
200
|
+
| ------------------------- | ------------------------------ |
|
|
201
|
+
| Multiple named flows (3+) | Two flows sufficient for demo |
|
|
202
|
+
| Queue config | Advanced batching scenario |
|
|
203
|
+
| Retry config | Advanced error handling |
|
|
204
|
+
| Custom fetch options | API destination advanced |
|
|
205
|
+
| Custom headers in API | Would add complexity |
|
|
206
|
+
| `validate:` function | Could add via $code: if needed |
|
|
208
207
|
|
|
209
208
|
---
|
|
210
209
|
|
package/dist/index.d.ts
CHANGED
|
@@ -419,4 +419,32 @@ declare function runCommand(mode: string, options: RunCommandOptions): Promise<v
|
|
|
419
419
|
*/
|
|
420
420
|
declare function run(mode: RunMode, options: RunOptions): Promise<RunResult>;
|
|
421
421
|
|
|
422
|
-
|
|
422
|
+
type ValidationType = 'event' | 'flow' | 'mapping';
|
|
423
|
+
interface ValidationError {
|
|
424
|
+
path: string;
|
|
425
|
+
message: string;
|
|
426
|
+
value?: unknown;
|
|
427
|
+
code?: string;
|
|
428
|
+
}
|
|
429
|
+
interface ValidationWarning {
|
|
430
|
+
path: string;
|
|
431
|
+
message: string;
|
|
432
|
+
suggestion?: string;
|
|
433
|
+
}
|
|
434
|
+
interface ValidateResult {
|
|
435
|
+
valid: boolean;
|
|
436
|
+
type: ValidationType;
|
|
437
|
+
errors: ValidationError[];
|
|
438
|
+
warnings: ValidationWarning[];
|
|
439
|
+
details: Record<string, unknown>;
|
|
440
|
+
}
|
|
441
|
+
|
|
442
|
+
/**
|
|
443
|
+
* Programmatic API for validation.
|
|
444
|
+
* Can be called directly from code or MCP server.
|
|
445
|
+
*/
|
|
446
|
+
declare function validate(type: ValidationType, input: unknown, options?: {
|
|
447
|
+
flow?: string;
|
|
448
|
+
}): Promise<ValidateResult>;
|
|
449
|
+
|
|
450
|
+
export { type BuildOptions, type BundleStats, type CLIBuildOptions, type GlobalOptions, type MinifyOptions, type RunCommandOptions, type RunMode, type RunOptions, type RunResult, type SimulationResult, type ValidateResult, type ValidationError, type ValidationType, type ValidationWarning, bundle, bundleCommand, pushCommand, run, runCommand, simulate, simulateCommand, validate };
|
package/dist/index.js
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
// src/index.ts
|
|
4
4
|
import { Command } from "commander";
|
|
5
|
-
import
|
|
5
|
+
import chalk3 from "chalk";
|
|
6
6
|
|
|
7
7
|
// src/version.ts
|
|
8
8
|
import { readFileSync } from "fs";
|
|
@@ -2905,6 +2905,288 @@ async function run(mode, options) {
|
|
|
2905
2905
|
}
|
|
2906
2906
|
}
|
|
2907
2907
|
|
|
2908
|
+
// src/commands/validate/index.ts
|
|
2909
|
+
import chalk2 from "chalk";
|
|
2910
|
+
|
|
2911
|
+
// src/commands/validate/validators/event.ts
|
|
2912
|
+
import { schemas as schemas3 } from "@walkeros/core/dev";
|
|
2913
|
+
var { PartialEventSchema } = schemas3;
|
|
2914
|
+
function validateEvent(input) {
|
|
2915
|
+
const errors = [];
|
|
2916
|
+
const warnings = [];
|
|
2917
|
+
const details = {};
|
|
2918
|
+
const event = typeof input === "object" && input !== null ? input : {};
|
|
2919
|
+
if (!("name" in event) || event.name === void 0) {
|
|
2920
|
+
errors.push({
|
|
2921
|
+
path: "name",
|
|
2922
|
+
message: "Event must have a name field",
|
|
2923
|
+
code: "MISSING_EVENT_NAME"
|
|
2924
|
+
});
|
|
2925
|
+
} else if (typeof event.name !== "string" || event.name.trim() === "") {
|
|
2926
|
+
errors.push({
|
|
2927
|
+
path: "name",
|
|
2928
|
+
message: "Event name cannot be empty",
|
|
2929
|
+
value: event.name,
|
|
2930
|
+
code: "EMPTY_EVENT_NAME"
|
|
2931
|
+
});
|
|
2932
|
+
} else {
|
|
2933
|
+
const name = event.name;
|
|
2934
|
+
if (!name.includes(" ")) {
|
|
2935
|
+
errors.push({
|
|
2936
|
+
path: "name",
|
|
2937
|
+
message: 'Event name must be "entity action" format with space (e.g., "page view")',
|
|
2938
|
+
value: name,
|
|
2939
|
+
code: "INVALID_EVENT_NAME"
|
|
2940
|
+
});
|
|
2941
|
+
details.entity = null;
|
|
2942
|
+
details.action = null;
|
|
2943
|
+
} else {
|
|
2944
|
+
const parts = name.trim().split(/\s+/);
|
|
2945
|
+
const action = parts.pop();
|
|
2946
|
+
const entity = parts.join(" ");
|
|
2947
|
+
details.entity = entity;
|
|
2948
|
+
details.action = action;
|
|
2949
|
+
}
|
|
2950
|
+
}
|
|
2951
|
+
const zodResult = PartialEventSchema.safeParse(input);
|
|
2952
|
+
if (!zodResult.success) {
|
|
2953
|
+
for (const issue of zodResult.error.issues) {
|
|
2954
|
+
const path14 = issue.path.join(".");
|
|
2955
|
+
if (path14 === "name") continue;
|
|
2956
|
+
errors.push({
|
|
2957
|
+
path: path14 || "root",
|
|
2958
|
+
message: issue.message,
|
|
2959
|
+
code: "SCHEMA_VALIDATION"
|
|
2960
|
+
});
|
|
2961
|
+
}
|
|
2962
|
+
}
|
|
2963
|
+
if (!event.consent) {
|
|
2964
|
+
warnings.push({
|
|
2965
|
+
path: "consent",
|
|
2966
|
+
message: "No consent object provided",
|
|
2967
|
+
suggestion: "Consider adding a consent object for GDPR/privacy compliance"
|
|
2968
|
+
});
|
|
2969
|
+
}
|
|
2970
|
+
details.hasConsent = !!event.consent;
|
|
2971
|
+
details.hasData = !!event.data;
|
|
2972
|
+
details.hasContext = !!event.context;
|
|
2973
|
+
return {
|
|
2974
|
+
valid: errors.length === 0,
|
|
2975
|
+
type: "event",
|
|
2976
|
+
errors,
|
|
2977
|
+
warnings,
|
|
2978
|
+
details
|
|
2979
|
+
};
|
|
2980
|
+
}
|
|
2981
|
+
|
|
2982
|
+
// src/commands/validate/validators/flow.ts
|
|
2983
|
+
import { schemas as schemas4 } from "@walkeros/core/dev";
|
|
2984
|
+
var { SetupSchema } = schemas4;
|
|
2985
|
+
function validateFlow(input, options = {}) {
|
|
2986
|
+
const errors = [];
|
|
2987
|
+
const warnings = [];
|
|
2988
|
+
const details = {};
|
|
2989
|
+
const config = typeof input === "object" && input !== null ? input : {};
|
|
2990
|
+
const zodResult = SetupSchema.safeParse(input);
|
|
2991
|
+
if (!zodResult.success) {
|
|
2992
|
+
for (const issue of zodResult.error.issues) {
|
|
2993
|
+
const path14 = issue.path.join(".");
|
|
2994
|
+
errors.push({
|
|
2995
|
+
path: path14 || "root",
|
|
2996
|
+
message: issue.message,
|
|
2997
|
+
code: "SCHEMA_VALIDATION"
|
|
2998
|
+
});
|
|
2999
|
+
}
|
|
3000
|
+
}
|
|
3001
|
+
const flows = config.flows;
|
|
3002
|
+
if (flows && typeof flows === "object" && Object.keys(flows).length === 0) {
|
|
3003
|
+
errors.push({
|
|
3004
|
+
path: "flows",
|
|
3005
|
+
message: "At least one flow is required",
|
|
3006
|
+
code: "EMPTY_FLOWS"
|
|
3007
|
+
});
|
|
3008
|
+
}
|
|
3009
|
+
if (flows && typeof flows === "object") {
|
|
3010
|
+
const flowNames = Object.keys(flows);
|
|
3011
|
+
details.flowNames = flowNames;
|
|
3012
|
+
details.flowCount = flowNames.length;
|
|
3013
|
+
if (options.flow) {
|
|
3014
|
+
if (!flowNames.includes(options.flow)) {
|
|
3015
|
+
errors.push({
|
|
3016
|
+
path: "flows",
|
|
3017
|
+
message: `Flow "${options.flow}" not found. Available: ${flowNames.join(", ")}`,
|
|
3018
|
+
code: "FLOW_NOT_FOUND"
|
|
3019
|
+
});
|
|
3020
|
+
} else {
|
|
3021
|
+
details.validatedFlow = options.flow;
|
|
3022
|
+
}
|
|
3023
|
+
}
|
|
3024
|
+
}
|
|
3025
|
+
const packages = config.packages;
|
|
3026
|
+
if (packages && typeof packages === "object") {
|
|
3027
|
+
for (const [pkgName, pkgConfig] of Object.entries(packages)) {
|
|
3028
|
+
if (!pkgConfig.version && !pkgConfig.path) {
|
|
3029
|
+
warnings.push({
|
|
3030
|
+
path: `packages.${pkgName}`,
|
|
3031
|
+
message: `Package "${pkgName}" has no version specified`,
|
|
3032
|
+
suggestion: "Consider specifying a version for reproducible builds"
|
|
3033
|
+
});
|
|
3034
|
+
}
|
|
3035
|
+
}
|
|
3036
|
+
details.packageCount = Object.keys(packages).length;
|
|
3037
|
+
}
|
|
3038
|
+
return {
|
|
3039
|
+
valid: errors.length === 0,
|
|
3040
|
+
type: "flow",
|
|
3041
|
+
errors,
|
|
3042
|
+
warnings,
|
|
3043
|
+
details
|
|
3044
|
+
};
|
|
3045
|
+
}
|
|
3046
|
+
|
|
3047
|
+
// src/commands/validate/validators/mapping.ts
|
|
3048
|
+
function validateMapping(input) {
|
|
3049
|
+
const errors = [];
|
|
3050
|
+
const warnings = [];
|
|
3051
|
+
const details = {};
|
|
3052
|
+
if (typeof input !== "object" || input === null || Array.isArray(input)) {
|
|
3053
|
+
errors.push({
|
|
3054
|
+
path: "root",
|
|
3055
|
+
message: "Mapping must be an object with event patterns as keys",
|
|
3056
|
+
code: "INVALID_MAPPING_TYPE"
|
|
3057
|
+
});
|
|
3058
|
+
return { valid: false, type: "mapping", errors, warnings, details };
|
|
3059
|
+
}
|
|
3060
|
+
const mapping = input;
|
|
3061
|
+
const patterns = Object.keys(mapping);
|
|
3062
|
+
details.eventPatterns = patterns;
|
|
3063
|
+
details.patternCount = patterns.length;
|
|
3064
|
+
patterns.forEach((pattern, index) => {
|
|
3065
|
+
const isWildcard = pattern.includes("*");
|
|
3066
|
+
const hasSpace = pattern.includes(" ");
|
|
3067
|
+
if (!isWildcard && !hasSpace) {
|
|
3068
|
+
errors.push({
|
|
3069
|
+
path: pattern,
|
|
3070
|
+
message: `Invalid event pattern "${pattern}". Must be "entity action" format or contain wildcard (*)`,
|
|
3071
|
+
code: "INVALID_EVENT_PATTERN"
|
|
3072
|
+
});
|
|
3073
|
+
}
|
|
3074
|
+
if (pattern === "*" && index !== patterns.length - 1) {
|
|
3075
|
+
warnings.push({
|
|
3076
|
+
path: "*",
|
|
3077
|
+
message: "Catch-all pattern (*) should be last",
|
|
3078
|
+
suggestion: "Move the catch-all pattern (*) to last position for predictable matching"
|
|
3079
|
+
});
|
|
3080
|
+
}
|
|
3081
|
+
const rule = mapping[pattern];
|
|
3082
|
+
const isValidRule = Array.isArray(rule) ? rule.every((r) => typeof r === "object" && r !== null) : typeof rule === "object" && rule !== null;
|
|
3083
|
+
if (!isValidRule) {
|
|
3084
|
+
errors.push({
|
|
3085
|
+
path: pattern,
|
|
3086
|
+
message: "Mapping rule must be an object or array of objects",
|
|
3087
|
+
code: "INVALID_RULE_TYPE"
|
|
3088
|
+
});
|
|
3089
|
+
}
|
|
3090
|
+
});
|
|
3091
|
+
return {
|
|
3092
|
+
valid: errors.length === 0,
|
|
3093
|
+
type: "mapping",
|
|
3094
|
+
errors,
|
|
3095
|
+
warnings,
|
|
3096
|
+
details
|
|
3097
|
+
};
|
|
3098
|
+
}
|
|
3099
|
+
|
|
3100
|
+
// src/commands/validate/index.ts
|
|
3101
|
+
async function validate(type, input, options = {}) {
|
|
3102
|
+
switch (type) {
|
|
3103
|
+
case "event":
|
|
3104
|
+
return validateEvent(input);
|
|
3105
|
+
case "flow":
|
|
3106
|
+
return validateFlow(input, { flow: options.flow });
|
|
3107
|
+
case "mapping":
|
|
3108
|
+
return validateMapping(input);
|
|
3109
|
+
default:
|
|
3110
|
+
throw new Error(`Unknown validation type: ${type}`);
|
|
3111
|
+
}
|
|
3112
|
+
}
|
|
3113
|
+
function formatResult(result, options) {
|
|
3114
|
+
if (options.json) {
|
|
3115
|
+
return JSON.stringify(result, null, 2);
|
|
3116
|
+
}
|
|
3117
|
+
const lines = [];
|
|
3118
|
+
lines.push("");
|
|
3119
|
+
lines.push(`Validating ${result.type}...`);
|
|
3120
|
+
lines.push("");
|
|
3121
|
+
if (options.verbose && Object.keys(result.details).length > 0) {
|
|
3122
|
+
lines.push("Details:");
|
|
3123
|
+
for (const [key, value] of Object.entries(result.details)) {
|
|
3124
|
+
lines.push(` ${key}: ${JSON.stringify(value)}`);
|
|
3125
|
+
}
|
|
3126
|
+
lines.push("");
|
|
3127
|
+
}
|
|
3128
|
+
lines.push("Validation Results:");
|
|
3129
|
+
for (const error of result.errors) {
|
|
3130
|
+
lines.push(chalk2.red(` \u2717 ${error.path}: ${error.message}`));
|
|
3131
|
+
}
|
|
3132
|
+
for (const warning of result.warnings) {
|
|
3133
|
+
lines.push(chalk2.yellow(` \u26A0 ${warning.path}: ${warning.message}`));
|
|
3134
|
+
if (warning.suggestion) {
|
|
3135
|
+
lines.push(chalk2.gray(` \u2192 ${warning.suggestion}`));
|
|
3136
|
+
}
|
|
3137
|
+
}
|
|
3138
|
+
if (result.valid) {
|
|
3139
|
+
lines.push(chalk2.green(` \u2713 All checks passed`));
|
|
3140
|
+
}
|
|
3141
|
+
lines.push("");
|
|
3142
|
+
lines.push(
|
|
3143
|
+
`Summary: ${result.errors.length} error(s), ${result.warnings.length} warning(s)`
|
|
3144
|
+
);
|
|
3145
|
+
return lines.join("\n");
|
|
3146
|
+
}
|
|
3147
|
+
async function validateCommand(options) {
|
|
3148
|
+
const logger2 = createCommandLogger(options);
|
|
3149
|
+
try {
|
|
3150
|
+
const input = await loadJsonFromSource(options.input, {
|
|
3151
|
+
name: options.type,
|
|
3152
|
+
required: true
|
|
3153
|
+
});
|
|
3154
|
+
const result = await validate(options.type, input, {
|
|
3155
|
+
flow: options.flow
|
|
3156
|
+
});
|
|
3157
|
+
const output = formatResult(result, {
|
|
3158
|
+
json: options.json,
|
|
3159
|
+
verbose: options.verbose
|
|
3160
|
+
});
|
|
3161
|
+
if (options.json) {
|
|
3162
|
+
console.log(output);
|
|
3163
|
+
} else {
|
|
3164
|
+
logger2.log(output);
|
|
3165
|
+
}
|
|
3166
|
+
if (!result.valid) {
|
|
3167
|
+
process.exit(1);
|
|
3168
|
+
}
|
|
3169
|
+
if (options.strict && result.warnings.length > 0) {
|
|
3170
|
+
process.exit(2);
|
|
3171
|
+
}
|
|
3172
|
+
process.exit(0);
|
|
3173
|
+
} catch (error) {
|
|
3174
|
+
const errorMessage = getErrorMessage(error);
|
|
3175
|
+
if (options.json) {
|
|
3176
|
+
logger2.json({
|
|
3177
|
+
valid: false,
|
|
3178
|
+
type: options.type,
|
|
3179
|
+
errors: [{ path: "input", message: errorMessage, code: "INPUT_ERROR" }],
|
|
3180
|
+
warnings: [],
|
|
3181
|
+
details: {}
|
|
3182
|
+
});
|
|
3183
|
+
} else {
|
|
3184
|
+
logger2.error(`Error: ${errorMessage}`);
|
|
3185
|
+
}
|
|
3186
|
+
process.exit(3);
|
|
3187
|
+
}
|
|
3188
|
+
}
|
|
3189
|
+
|
|
2908
3190
|
// src/commands/cache.ts
|
|
2909
3191
|
import fs13 from "fs-extra";
|
|
2910
3192
|
function registerCacheCommand(program2) {
|
|
@@ -2955,7 +3237,7 @@ program.name("walkeros").description("walkerOS CLI - Bundle and deploy walkerOS
|
|
|
2955
3237
|
program.hook("preAction", (thisCommand, actionCommand) => {
|
|
2956
3238
|
const options = actionCommand.opts();
|
|
2957
3239
|
if (!options.silent && !options.json) {
|
|
2958
|
-
console.log(`${
|
|
3240
|
+
console.log(`${chalk3.hex("#01b5e2")("walkerOS")} v${VERSION}`);
|
|
2959
3241
|
}
|
|
2960
3242
|
});
|
|
2961
3243
|
program.command("bundle [file]").description("Bundle NPM packages with custom code").option("--flow <name>", "flow name for multi-flow configs").option("--all", "build all flows for multi-flow configs").option("--stats", "show bundle statistics").option("--json", "output as JSON (implies --stats)").option("--no-cache", "disable package caching").option("-v, --verbose", "verbose output").option("-s, --silent", "suppress output").option(
|
|
@@ -3002,6 +3284,17 @@ program.command("push [file]").description("Push an event through the flow with
|
|
|
3002
3284
|
silent: options.silent
|
|
3003
3285
|
});
|
|
3004
3286
|
});
|
|
3287
|
+
program.command("validate <type> [input]").description("Validate event, flow, or mapping configuration").option("--flow <name>", "flow name for multi-flow configs").option("--json", "output as JSON").option("-v, --verbose", "verbose output").option("-s, --silent", "suppress output").option("--strict", "fail on warnings").action(async (type, input, options) => {
|
|
3288
|
+
await validateCommand({
|
|
3289
|
+
type,
|
|
3290
|
+
input,
|
|
3291
|
+
flow: options.flow,
|
|
3292
|
+
json: options.json,
|
|
3293
|
+
verbose: options.verbose,
|
|
3294
|
+
silent: options.silent,
|
|
3295
|
+
strict: options.strict
|
|
3296
|
+
});
|
|
3297
|
+
});
|
|
3005
3298
|
var runCmd = program.command("run").description("Run walkerOS flows in collect or serve mode");
|
|
3006
3299
|
runCmd.command("collect [file]").description(
|
|
3007
3300
|
"Run collector mode (event collection endpoint). Defaults to server-collect.mjs if no file specified."
|
|
@@ -3039,6 +3332,7 @@ export {
|
|
|
3039
3332
|
run,
|
|
3040
3333
|
runCommand,
|
|
3041
3334
|
simulate,
|
|
3042
|
-
simulateCommand
|
|
3335
|
+
simulateCommand,
|
|
3336
|
+
validate
|
|
3043
3337
|
};
|
|
3044
3338
|
//# sourceMappingURL=index.js.map
|