arkgate 2.10.0 → 2.11.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 +43 -0
- package/README.md +6 -2
- package/SECURITY.md +3 -4
- package/bin/ark-check.mjs +41 -16
- package/bin/ark-mcp.mjs +54 -10
- package/bin/ark.mjs +35 -5
- package/bin/lib/agent-gates.mjs +9 -5
- package/bin/lib/architecture-scan.mjs +4 -1
- package/bin/lib/baseline-key.mjs +17 -0
- package/bin/lib/config-warnings.mjs +22 -0
- package/bin/lib/core-layers.mjs +7 -0
- package/bin/lib/core-ratchet.mjs +3 -7
- package/bin/lib/doctor-plan.mjs +29 -5
- package/bin/lib/safety-diagnostics.mjs +263 -0
- package/bin/lib/scan-files.mjs +51 -6
- package/bin/lib/violations.mjs +3 -3
- package/dist/index.cjs +103 -8
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +5 -3
- package/dist/index.d.ts +5 -3
- package/dist/index.js +103 -8
- package/dist/index.js.map +1 -1
- package/dist/nestjs/index.cjs +18 -5
- package/dist/nestjs/index.cjs.map +1 -1
- package/dist/nestjs/index.d.cts +1 -1
- package/dist/nestjs/index.d.ts +1 -1
- package/dist/nestjs/index.js +18 -5
- package/dist/nestjs/index.js.map +1 -1
- package/dist/runtime/index.cjs +103 -8
- package/dist/runtime/index.cjs.map +1 -1
- package/dist/runtime/index.d.cts +1 -1
- package/dist/runtime/index.d.ts +1 -1
- package/dist/runtime/index.js +103 -8
- package/dist/runtime/index.js.map +1 -1
- package/dist/{types-D6Q8WHes.d.cts → types-BZ17b9i5.d.cts} +5 -1
- package/dist/{types-D6Q8WHes.d.ts → types-BZ17b9i5.d.ts} +5 -1
- package/docs/agent-guide.md +1 -1
- package/docs/ai-gates.md +20 -2
- package/docs/package-surface.md +2 -2
- package/docs/production-hardening.md +5 -0
- package/package.json +5 -2
- package/server.json +2 -2
package/dist/index.d.cts
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
import { I as IntentRegistry, a as IntentName, D as DefineIntentOptions, b as IntentCreator, P as PolicyViolation, c as PolicySeverity, d as PolicyEnforcementMode, e as Policy, f as CreateArchitectureProfileOptions, g as ArchitectureProfile, h as ArkCheckConfig, i as CreateArchitectureProfileFromArkConfigOptions, j as CreateElevenLayerArkConfigOptions, k as DependencyGraph, G as GraphEdge, l as IntentRelationship, m as AuditStore, n as AuditRecord, o as AuditQuery, p as CreateAuditTrailOptions, q as AuditTrail, E as EventContractRegistry, r as EventContract, s as DomainEvent, t as EventContractValidationResult, O as OutboxStore, u as OutboxRecord, v as OutboxStatus, w as EventBusOptions, x as EventBus, y as CreateObservabilityReporterOptions, z as ObservabilityReporter, M as MetadataRegistry, R as ReadModelStore, B as CreateProjectionRegistryOptions, F as ProjectionRegistry, H as PolicyEngine, J as ArkManifest, W as WorkflowStore, S as SagaContext, K as WorkflowSnapshot, L as SagaDefinition, N as CreateWorkflowEngineOptions, Q as SagaInstance, T as WorkflowEngine, C as CreateArkKernelOptions, A as ArkKernel, U as ArkKernelConfig, V as CreateArkKernelFromConfigOptions, X as TraceRecordType, Y as TraceRecord, Z as ObservabilityDriftReport } from './types-
|
|
2
|
-
export { _ as ArchitectureLayer, $ as ArchitectureLayerConfig, a0 as ArchitectureRule, a1 as ArkManifestArchitecture, a2 as ArkManifestData, a3 as ArkManifestEntityLink, a4 as ArkManifestGraph, a5 as ArkManifestIntent, a6 as ArkManifestPolicy, a7 as ArkManifestProjection, a8 as AuditRecordInput, a9 as AuditRecordType, aa as CorrelationId, ab as EntityMeta, ac as EventContractIssue, ad as EventHandler, ae as EventInterceptionInfo, af as EventInterceptor, ag as EventInterceptorContext, ah as EventMetadata, ai as EventPayloadPatch, aj as EventPayloadSchema, ak as EventPublisher, al as EventSchemaField, am as EventSchemaFieldType, an as FieldMeta, ao as GraphNode, ap as IntentRelationshipKind, aq as ObservabilityFlow, ar as ObservedLayerFlowMode, as as PolicyEvaluationResult, at as ProjectionCheckpoint, au as ProjectionDefinition, av as PublishedEventRecord, aw as RetryPolicy, ax as SagaStatus, ay as SagaStep, az as TraceSink, aA as Unsubscribe, aB as WorkflowDefinition, aC as WorkflowStatus, aD as WorkflowStep } from './types-
|
|
1
|
+
import { I as IntentRegistry, a as IntentName, D as DefineIntentOptions, b as IntentCreator, P as PolicyViolation, c as PolicySeverity, d as PolicyEnforcementMode, e as Policy, f as CreateArchitectureProfileOptions, g as ArchitectureProfile, h as ArkCheckConfig, i as CreateArchitectureProfileFromArkConfigOptions, j as CreateElevenLayerArkConfigOptions, k as DependencyGraph, G as GraphEdge, l as IntentRelationship, m as AuditStore, n as AuditRecord, o as AuditQuery, p as CreateAuditTrailOptions, q as AuditTrail, E as EventContractRegistry, r as EventContract, s as DomainEvent, t as EventContractValidationResult, O as OutboxStore, u as OutboxRecord, v as OutboxStatus, w as EventBusOptions, x as EventBus, y as CreateObservabilityReporterOptions, z as ObservabilityReporter, M as MetadataRegistry, R as ReadModelStore, B as CreateProjectionRegistryOptions, F as ProjectionRegistry, H as PolicyEngine, J as ArkManifest, W as WorkflowStore, S as SagaContext, K as WorkflowSnapshot, L as SagaDefinition, N as CreateWorkflowEngineOptions, Q as SagaInstance, T as WorkflowEngine, C as CreateArkKernelOptions, A as ArkKernel, U as ArkKernelConfig, V as CreateArkKernelFromConfigOptions, X as TraceRecordType, Y as TraceRecord, Z as ObservabilityDriftReport } from './types-BZ17b9i5.cjs';
|
|
2
|
+
export { _ as ArchitectureLayer, $ as ArchitectureLayerConfig, a0 as ArchitectureRule, a1 as ArkManifestArchitecture, a2 as ArkManifestData, a3 as ArkManifestEntityLink, a4 as ArkManifestGraph, a5 as ArkManifestIntent, a6 as ArkManifestPolicy, a7 as ArkManifestProjection, a8 as AuditRecordInput, a9 as AuditRecordType, aa as CorrelationId, ab as EntityMeta, ac as EventContractIssue, ad as EventHandler, ae as EventInterceptionInfo, af as EventInterceptor, ag as EventInterceptorContext, ah as EventMetadata, ai as EventPayloadPatch, aj as EventPayloadSchema, ak as EventPublisher, al as EventSchemaField, am as EventSchemaFieldType, an as FieldMeta, ao as GraphNode, ap as IntentRelationshipKind, aq as ObservabilityFlow, ar as ObservedLayerFlowMode, as as PolicyEvaluationResult, at as ProjectionCheckpoint, au as ProjectionDefinition, av as PublishedEventRecord, aw as RetryPolicy, ax as SagaStatus, ay as SagaStep, az as TraceSink, aA as Unsubscribe, aB as WorkflowDefinition, aC as WorkflowStatus, aD as WorkflowStep } from './types-BZ17b9i5.cjs';
|
|
3
3
|
|
|
4
4
|
/** ArkGate library version — single source of truth. */
|
|
5
|
-
declare const version = "2.
|
|
5
|
+
declare const version = "2.11.0";
|
|
6
6
|
|
|
7
7
|
/**
|
|
8
8
|
* defineIntent
|
|
@@ -603,6 +603,8 @@ interface AICodeGateOptions<Context = AICodeGateContext> {
|
|
|
603
603
|
name: string;
|
|
604
604
|
patterns?: string[];
|
|
605
605
|
}>;
|
|
606
|
+
/** Explicit file-level escape hatch for reviewed non-literal dynamic imports. */
|
|
607
|
+
allowNonLiteralDynamicImport?: (filePath?: string) => boolean;
|
|
606
608
|
}
|
|
607
609
|
declare function createAICodeGate<Context = AICodeGateContext>(options?: AICodeGateOptions<Context>): AICodeGate<Context>;
|
|
608
610
|
|
package/dist/index.d.ts
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
import { I as IntentRegistry, a as IntentName, D as DefineIntentOptions, b as IntentCreator, P as PolicyViolation, c as PolicySeverity, d as PolicyEnforcementMode, e as Policy, f as CreateArchitectureProfileOptions, g as ArchitectureProfile, h as ArkCheckConfig, i as CreateArchitectureProfileFromArkConfigOptions, j as CreateElevenLayerArkConfigOptions, k as DependencyGraph, G as GraphEdge, l as IntentRelationship, m as AuditStore, n as AuditRecord, o as AuditQuery, p as CreateAuditTrailOptions, q as AuditTrail, E as EventContractRegistry, r as EventContract, s as DomainEvent, t as EventContractValidationResult, O as OutboxStore, u as OutboxRecord, v as OutboxStatus, w as EventBusOptions, x as EventBus, y as CreateObservabilityReporterOptions, z as ObservabilityReporter, M as MetadataRegistry, R as ReadModelStore, B as CreateProjectionRegistryOptions, F as ProjectionRegistry, H as PolicyEngine, J as ArkManifest, W as WorkflowStore, S as SagaContext, K as WorkflowSnapshot, L as SagaDefinition, N as CreateWorkflowEngineOptions, Q as SagaInstance, T as WorkflowEngine, C as CreateArkKernelOptions, A as ArkKernel, U as ArkKernelConfig, V as CreateArkKernelFromConfigOptions, X as TraceRecordType, Y as TraceRecord, Z as ObservabilityDriftReport } from './types-
|
|
2
|
-
export { _ as ArchitectureLayer, $ as ArchitectureLayerConfig, a0 as ArchitectureRule, a1 as ArkManifestArchitecture, a2 as ArkManifestData, a3 as ArkManifestEntityLink, a4 as ArkManifestGraph, a5 as ArkManifestIntent, a6 as ArkManifestPolicy, a7 as ArkManifestProjection, a8 as AuditRecordInput, a9 as AuditRecordType, aa as CorrelationId, ab as EntityMeta, ac as EventContractIssue, ad as EventHandler, ae as EventInterceptionInfo, af as EventInterceptor, ag as EventInterceptorContext, ah as EventMetadata, ai as EventPayloadPatch, aj as EventPayloadSchema, ak as EventPublisher, al as EventSchemaField, am as EventSchemaFieldType, an as FieldMeta, ao as GraphNode, ap as IntentRelationshipKind, aq as ObservabilityFlow, ar as ObservedLayerFlowMode, as as PolicyEvaluationResult, at as ProjectionCheckpoint, au as ProjectionDefinition, av as PublishedEventRecord, aw as RetryPolicy, ax as SagaStatus, ay as SagaStep, az as TraceSink, aA as Unsubscribe, aB as WorkflowDefinition, aC as WorkflowStatus, aD as WorkflowStep } from './types-
|
|
1
|
+
import { I as IntentRegistry, a as IntentName, D as DefineIntentOptions, b as IntentCreator, P as PolicyViolation, c as PolicySeverity, d as PolicyEnforcementMode, e as Policy, f as CreateArchitectureProfileOptions, g as ArchitectureProfile, h as ArkCheckConfig, i as CreateArchitectureProfileFromArkConfigOptions, j as CreateElevenLayerArkConfigOptions, k as DependencyGraph, G as GraphEdge, l as IntentRelationship, m as AuditStore, n as AuditRecord, o as AuditQuery, p as CreateAuditTrailOptions, q as AuditTrail, E as EventContractRegistry, r as EventContract, s as DomainEvent, t as EventContractValidationResult, O as OutboxStore, u as OutboxRecord, v as OutboxStatus, w as EventBusOptions, x as EventBus, y as CreateObservabilityReporterOptions, z as ObservabilityReporter, M as MetadataRegistry, R as ReadModelStore, B as CreateProjectionRegistryOptions, F as ProjectionRegistry, H as PolicyEngine, J as ArkManifest, W as WorkflowStore, S as SagaContext, K as WorkflowSnapshot, L as SagaDefinition, N as CreateWorkflowEngineOptions, Q as SagaInstance, T as WorkflowEngine, C as CreateArkKernelOptions, A as ArkKernel, U as ArkKernelConfig, V as CreateArkKernelFromConfigOptions, X as TraceRecordType, Y as TraceRecord, Z as ObservabilityDriftReport } from './types-BZ17b9i5.js';
|
|
2
|
+
export { _ as ArchitectureLayer, $ as ArchitectureLayerConfig, a0 as ArchitectureRule, a1 as ArkManifestArchitecture, a2 as ArkManifestData, a3 as ArkManifestEntityLink, a4 as ArkManifestGraph, a5 as ArkManifestIntent, a6 as ArkManifestPolicy, a7 as ArkManifestProjection, a8 as AuditRecordInput, a9 as AuditRecordType, aa as CorrelationId, ab as EntityMeta, ac as EventContractIssue, ad as EventHandler, ae as EventInterceptionInfo, af as EventInterceptor, ag as EventInterceptorContext, ah as EventMetadata, ai as EventPayloadPatch, aj as EventPayloadSchema, ak as EventPublisher, al as EventSchemaField, am as EventSchemaFieldType, an as FieldMeta, ao as GraphNode, ap as IntentRelationshipKind, aq as ObservabilityFlow, ar as ObservedLayerFlowMode, as as PolicyEvaluationResult, at as ProjectionCheckpoint, au as ProjectionDefinition, av as PublishedEventRecord, aw as RetryPolicy, ax as SagaStatus, ay as SagaStep, az as TraceSink, aA as Unsubscribe, aB as WorkflowDefinition, aC as WorkflowStatus, aD as WorkflowStep } from './types-BZ17b9i5.js';
|
|
3
3
|
|
|
4
4
|
/** ArkGate library version — single source of truth. */
|
|
5
|
-
declare const version = "2.
|
|
5
|
+
declare const version = "2.11.0";
|
|
6
6
|
|
|
7
7
|
/**
|
|
8
8
|
* defineIntent
|
|
@@ -603,6 +603,8 @@ interface AICodeGateOptions<Context = AICodeGateContext> {
|
|
|
603
603
|
name: string;
|
|
604
604
|
patterns?: string[];
|
|
605
605
|
}>;
|
|
606
|
+
/** Explicit file-level escape hatch for reviewed non-literal dynamic imports. */
|
|
607
|
+
allowNonLiteralDynamicImport?: (filePath?: string) => boolean;
|
|
606
608
|
}
|
|
607
609
|
declare function createAICodeGate<Context = AICodeGateContext>(options?: AICodeGateOptions<Context>): AICodeGate<Context>;
|
|
608
610
|
|
package/dist/index.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
// src/version.ts
|
|
2
|
-
var version = "2.
|
|
2
|
+
var version = "2.11.0";
|
|
3
3
|
|
|
4
4
|
// src/kernel/intent/IntentRegistry.ts
|
|
5
5
|
var IntentRegistry = class {
|
|
@@ -2181,6 +2181,75 @@ function extractModuleSpecifiers(source) {
|
|
|
2181
2181
|
}
|
|
2182
2182
|
return matches.sort((a, b) => a.index - b.index);
|
|
2183
2183
|
}
|
|
2184
|
+
function extractModuleSpecifiersAst(ts, source) {
|
|
2185
|
+
const sourceFile = ts.createSourceFile("generated.ts", source, ts.ScriptTarget.Latest, true);
|
|
2186
|
+
const matches = [];
|
|
2187
|
+
const push = (node, value, kind, typeOnly = false) => {
|
|
2188
|
+
matches.push({
|
|
2189
|
+
value,
|
|
2190
|
+
index: node.getStart(sourceFile),
|
|
2191
|
+
kind,
|
|
2192
|
+
typeOnly
|
|
2193
|
+
});
|
|
2194
|
+
};
|
|
2195
|
+
const visit = (node) => {
|
|
2196
|
+
if (ts.isImportDeclaration(node) && ts.isStringLiteralLike(node.moduleSpecifier)) {
|
|
2197
|
+
const clause = node.importClause;
|
|
2198
|
+
const namedBindings = clause?.namedBindings;
|
|
2199
|
+
const specifiersOnly = clause && !clause.name && namedBindings && ts.isNamedImports(namedBindings) && namedBindings.elements.length > 0 && namedBindings.elements.every((element) => element.isTypeOnly === true);
|
|
2200
|
+
push(
|
|
2201
|
+
node.moduleSpecifier,
|
|
2202
|
+
node.moduleSpecifier.text,
|
|
2203
|
+
"import",
|
|
2204
|
+
Boolean(clause?.isTypeOnly || specifiersOnly)
|
|
2205
|
+
);
|
|
2206
|
+
} else if (ts.isExportDeclaration(node) && ts.isStringLiteralLike(node.moduleSpecifier)) {
|
|
2207
|
+
const clause = node.exportClause;
|
|
2208
|
+
const specifiersOnly = clause && ts.isNamedExports(clause) && clause.elements.length > 0 && clause.elements.every((element) => element.isTypeOnly === true);
|
|
2209
|
+
push(
|
|
2210
|
+
node.moduleSpecifier,
|
|
2211
|
+
node.moduleSpecifier.text,
|
|
2212
|
+
"export",
|
|
2213
|
+
Boolean(node.isTypeOnly || specifiersOnly)
|
|
2214
|
+
);
|
|
2215
|
+
} else if (ts.isCallExpression(node) && node.arguments.length === 1) {
|
|
2216
|
+
const argument = node.arguments[0];
|
|
2217
|
+
const value = tsStringLiteralText(ts, argument);
|
|
2218
|
+
if (value !== void 0 && node.expression.kind === ts.SyntaxKind.ImportKeyword) {
|
|
2219
|
+
push(argument, value, "dynamic-import");
|
|
2220
|
+
} else if (value !== void 0 && ts.isIdentifier(node.expression) && node.expression.text === "require") {
|
|
2221
|
+
push(argument, value, "require");
|
|
2222
|
+
}
|
|
2223
|
+
}
|
|
2224
|
+
ts.forEachChild(node, visit);
|
|
2225
|
+
};
|
|
2226
|
+
visit(sourceFile);
|
|
2227
|
+
return matches.sort((a, b) => a.index - b.index);
|
|
2228
|
+
}
|
|
2229
|
+
function nonLiteralDynamicImportLines(ts, source) {
|
|
2230
|
+
const sourceFile = ts.createSourceFile("generated.ts", source, ts.ScriptTarget.Latest, true);
|
|
2231
|
+
const lines = [];
|
|
2232
|
+
const visit = (node) => {
|
|
2233
|
+
if (ts.isCallExpression(node) && node.expression.kind === ts.SyntaxKind.ImportKeyword && (!node.arguments[0] || !ts.isStringLiteralLike(node.arguments[0]))) {
|
|
2234
|
+
lines.push(sourceFile.getLineAndCharacterOfPosition(node.getStart(sourceFile)).line + 1);
|
|
2235
|
+
}
|
|
2236
|
+
ts.forEachChild(node, visit);
|
|
2237
|
+
};
|
|
2238
|
+
visit(sourceFile);
|
|
2239
|
+
return lines;
|
|
2240
|
+
}
|
|
2241
|
+
function extractQuotedStringsAst(ts, source) {
|
|
2242
|
+
const sourceFile = ts.createSourceFile("generated.ts", source, ts.ScriptTarget.Latest, true);
|
|
2243
|
+
const matches = [];
|
|
2244
|
+
const visit = (node) => {
|
|
2245
|
+
if (ts.isStringLiteralLike(node)) {
|
|
2246
|
+
matches.push({ value: node.text, index: node.getStart(sourceFile) });
|
|
2247
|
+
}
|
|
2248
|
+
ts.forEachChild(node, visit);
|
|
2249
|
+
};
|
|
2250
|
+
visit(sourceFile);
|
|
2251
|
+
return matches;
|
|
2252
|
+
}
|
|
2184
2253
|
function looksLikeIntentName(s) {
|
|
2185
2254
|
return /^(Domain|Application|Adapter|Workflow|Job|Presentation|Reporting|Metadata|Security|Audit|Observability|Kernel)\.[A-Za-z0-9_.]+$/.test(s);
|
|
2186
2255
|
}
|
|
@@ -2375,6 +2444,19 @@ function createAICodeGate(options = {}) {
|
|
|
2375
2444
|
const gateContext = context;
|
|
2376
2445
|
const filePath = gateContext?.filePath;
|
|
2377
2446
|
const contextLayer = gateContext?.layer;
|
|
2447
|
+
const moduleSpecifiers = options.typescript ? extractModuleSpecifiersAst(options.typescript, source) : extractModuleSpecifiers(source);
|
|
2448
|
+
const quotedStrings = options.typescript ? extractQuotedStringsAst(options.typescript, source) : extractQuotedStrings(source);
|
|
2449
|
+
if (options.typescript && !options.allowNonLiteralDynamicImport?.(filePath)) {
|
|
2450
|
+
for (const line of nonLiteralDynamicImportLines(options.typescript, source)) {
|
|
2451
|
+
violations.push(
|
|
2452
|
+
violation(
|
|
2453
|
+
"DYNAMIC_IMPORT_NOT_ALLOWLISTED",
|
|
2454
|
+
"Non-literal dynamic import cannot be resolved statically; add the reviewed file to dynamicImportAllowlist.",
|
|
2455
|
+
{ line, filePath }
|
|
2456
|
+
)
|
|
2457
|
+
);
|
|
2458
|
+
}
|
|
2459
|
+
}
|
|
2378
2460
|
const exemptFromInfraHeuristics = contextLayer !== void 0 && (explicitInfraLayers.has(contextLayer) || layerHasInfrastructureRole(contextLayer));
|
|
2379
2461
|
const infraLayerEscapeHatch = contextLayer !== void 0 ? ` If "${contextLayer}" is an infrastructure layer, mark it in ark.config.json with "mayImportInfrastructure": true (or name it with an infra token like Adapters/Persistence/Repository).` : "";
|
|
2380
2462
|
for (const pat of userForbidden) {
|
|
@@ -2400,7 +2482,7 @@ function createAICodeGate(options = {}) {
|
|
|
2400
2482
|
);
|
|
2401
2483
|
}
|
|
2402
2484
|
}
|
|
2403
|
-
for (const specifier of
|
|
2485
|
+
for (const specifier of moduleSpecifiers) {
|
|
2404
2486
|
const targetHit = options.resolveImportTarget?.(specifier.value, filePath) ?? (options.resolveImportLayer ? { layer: options.resolveImportLayer(specifier.value, filePath) } : void 0);
|
|
2405
2487
|
const sourceHit = typeof filePath === "string" ? options.resolveImportTarget?.(filePath) ?? (options.resolveImportLayer ? { layer: contextLayer, relPath: void 0 } : void 0) : void 0;
|
|
2406
2488
|
const targetLayer = targetHit?.layer;
|
|
@@ -2491,7 +2573,7 @@ function createAICodeGate(options = {}) {
|
|
|
2491
2573
|
}
|
|
2492
2574
|
}
|
|
2493
2575
|
if (enforceAllowlist && intentNames.size > 0) {
|
|
2494
|
-
for (const literal of
|
|
2576
|
+
for (const literal of quotedStrings) {
|
|
2495
2577
|
if (looksLikeIntentName(literal.value) && !intentNames.has(literal.value)) {
|
|
2496
2578
|
violations.push(
|
|
2497
2579
|
violation(
|
|
@@ -2509,7 +2591,7 @@ function createAICodeGate(options = {}) {
|
|
|
2509
2591
|
}
|
|
2510
2592
|
}
|
|
2511
2593
|
if (options.architectureProfile && contextLayer) {
|
|
2512
|
-
for (const literal of
|
|
2594
|
+
for (const literal of quotedStrings) {
|
|
2513
2595
|
if (!looksLikeIntentName(literal.value)) continue;
|
|
2514
2596
|
const targetLayer = options.architectureProfile.resolveLayer(literal.value);
|
|
2515
2597
|
if (!targetLayer) continue;
|
|
@@ -2785,15 +2867,18 @@ function sleep(ms) {
|
|
|
2785
2867
|
});
|
|
2786
2868
|
}
|
|
2787
2869
|
async function withTimeout(operation, timeoutMs, stepName) {
|
|
2788
|
-
|
|
2870
|
+
const controller = new AbortController();
|
|
2871
|
+
if (timeoutMs === void 0) return operation(controller.signal);
|
|
2789
2872
|
let timeout;
|
|
2790
2873
|
const timeoutPromise = new Promise((_, reject) => {
|
|
2791
2874
|
timeout = setTimeout(() => {
|
|
2792
|
-
|
|
2875
|
+
const error = new Error(`Workflow step "${stepName}" timed out after ${timeoutMs}ms.`);
|
|
2876
|
+
controller.abort(error);
|
|
2877
|
+
reject(error);
|
|
2793
2878
|
}, timeoutMs);
|
|
2794
2879
|
});
|
|
2795
2880
|
try {
|
|
2796
|
-
return await Promise.race([operation, timeoutPromise]);
|
|
2881
|
+
return await Promise.race([operation(controller.signal), timeoutPromise]);
|
|
2797
2882
|
} finally {
|
|
2798
2883
|
if (timeout) clearTimeout(timeout);
|
|
2799
2884
|
}
|
|
@@ -2828,6 +2913,15 @@ var WorkflowEngineImpl = class {
|
|
|
2828
2913
|
if (this.definitions.has(definition.name)) {
|
|
2829
2914
|
throw new Error(`Workflow "${definition.name}" is already registered.`);
|
|
2830
2915
|
}
|
|
2916
|
+
const names = /* @__PURE__ */ new Set();
|
|
2917
|
+
for (const step of definition.steps) {
|
|
2918
|
+
if (names.has(step.name)) {
|
|
2919
|
+
throw new Error(
|
|
2920
|
+
`Workflow "${definition.name}" has duplicate step name "${step.name}".`
|
|
2921
|
+
);
|
|
2922
|
+
}
|
|
2923
|
+
names.add(step.name);
|
|
2924
|
+
}
|
|
2831
2925
|
this.definitions.set(definition.name, definition);
|
|
2832
2926
|
if (definition.startOn) {
|
|
2833
2927
|
const trigger = definition.startOn;
|
|
@@ -2868,6 +2962,7 @@ var WorkflowEngineImpl = class {
|
|
|
2868
2962
|
} catch (err) {
|
|
2869
2963
|
await this.compensate(snapshot, definition.steps, err);
|
|
2870
2964
|
snapshot.status = "failed";
|
|
2965
|
+
snapshot.currentStep = void 0;
|
|
2871
2966
|
snapshot.error = errorMessage(err);
|
|
2872
2967
|
snapshot.updatedAt = (/* @__PURE__ */ new Date()).toISOString();
|
|
2873
2968
|
await this.store.save(snapshot);
|
|
@@ -2896,7 +2991,7 @@ var WorkflowEngineImpl = class {
|
|
|
2896
2991
|
await this.store.save(snapshot);
|
|
2897
2992
|
try {
|
|
2898
2993
|
const result = await withTimeout(
|
|
2899
|
-
Promise.resolve(step.execute(snapshot.context, this.bus)),
|
|
2994
|
+
(signal) => Promise.resolve(step.execute(snapshot.context, this.bus, signal)),
|
|
2900
2995
|
step.timeoutMs,
|
|
2901
2996
|
step.name
|
|
2902
2997
|
);
|