@openapi-flow/n8n 0.2.0 → 0.3.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (141) hide show
  1. package/README.md +29 -1
  2. package/dist/nodes/inputs/compile-template-input-validators.d.ts +3 -0
  3. package/dist/nodes/inputs/compile-template-input-validators.js +26 -0
  4. package/dist/nodes/inputs/create-template-input-nodes.d.ts +4 -0
  5. package/dist/nodes/inputs/create-template-input-nodes.js +61 -0
  6. package/dist/nodes/native/arrays/create-bound-native-array-capability.d.ts +4 -0
  7. package/dist/nodes/native/arrays/create-bound-native-array-capability.js +81 -0
  8. package/dist/nodes/native/arrays/create-native-array-capability.d.ts +1 -0
  9. package/dist/nodes/native/arrays/create-native-array-capability.js +7 -59
  10. package/dist/nodes/native/arrays/native-array-definition.d.ts +2 -0
  11. package/dist/nodes/native/arrays/native-array-definition.js +27 -0
  12. package/dist/nodes/native/common/create-material-planning-capability.d.ts +4 -0
  13. package/dist/nodes/native/common/create-material-planning-capability.js +14 -0
  14. package/dist/nodes/native/common/define-material-bound-capability.d.ts +4 -0
  15. package/dist/nodes/native/common/define-material-bound-capability.js +33 -0
  16. package/dist/nodes/native/common/resolve-native-runtime-source.d.ts +3 -0
  17. package/dist/nodes/native/common/resolve-native-runtime-source.js +15 -0
  18. package/dist/nodes/native/common/response-reference-bindings.d.ts +4 -0
  19. package/dist/nodes/native/common/response-reference-bindings.js +15 -0
  20. package/dist/nodes/native/create-exclusive-branch-merge-capability.js +10 -0
  21. package/dist/nodes/native/create-json-output-capability.js +14 -4
  22. package/dist/nodes/native/create-native-capabilities.js +13 -12
  23. package/dist/nodes/native/create-pass-through-capability.js +2 -0
  24. package/dist/nodes/native/create-response-array-capability.js +13 -8
  25. package/dist/nodes/native/create-response-collection-capability.js +10 -8
  26. package/dist/nodes/native/if-capability.js +6 -2
  27. package/dist/nodes/native/inputs/native-input-runtime.bundle.js +24 -0
  28. package/dist/nodes/native/inputs/prepend-native-parameter-guard.d.ts +4 -0
  29. package/dist/nodes/native/inputs/prepend-native-parameter-guard.js +52 -0
  30. package/dist/nodes/native/item-join/create-bound-item-join-capability.d.ts +3 -0
  31. package/dist/nodes/native/item-join/create-bound-item-join-capability.js +169 -0
  32. package/dist/nodes/native/item-join/create-item-join-capability.d.ts +2 -1
  33. package/dist/nodes/native/item-join/create-item-join-capability.js +8 -151
  34. package/dist/nodes/native/item-join/item-join-definition.d.ts +2 -0
  35. package/dist/nodes/native/item-join/item-join-definition.js +33 -0
  36. package/dist/nodes/native/merge-append-capability.js +2 -0
  37. package/dist/nodes/native/registry/native-feature-definitions.d.ts +4 -0
  38. package/dist/nodes/native/registry/native-feature-definitions.js +93 -0
  39. package/dist/nodes/native/registry/native-feature-material-requirements.d.ts +3 -0
  40. package/dist/nodes/native/registry/native-feature-material-requirements.js +10 -0
  41. package/dist/nodes/native/registry/resolve-n8n-native-features.d.ts +3 -0
  42. package/dist/nodes/native/registry/resolve-n8n-native-features.js +6 -0
  43. package/dist/nodes/native/registry/resolve-n8n-native-planning-features.d.ts +3 -0
  44. package/dist/nodes/native/registry/resolve-n8n-native-planning-features.js +5 -0
  45. package/dist/nodes/native/registry/resolve-native-feature-registry.d.ts +3 -0
  46. package/dist/nodes/native/registry/resolve-native-feature-registry.js +99 -0
  47. package/dist/nodes/native/registry/validate-native-feature-context.d.ts +2 -0
  48. package/dist/nodes/native/registry/validate-native-feature-context.js +46 -0
  49. package/dist/nodes/native/response-array-definition.d.ts +2 -0
  50. package/dist/nodes/native/response-array-definition.js +27 -0
  51. package/dist/nodes/native/response-assertion-capability.js +5 -1
  52. package/dist/nodes/native/response-check-code.d.ts +1 -1
  53. package/dist/nodes/native/response-check-code.js +13 -7
  54. package/dist/nodes/native/response-checks/create-response-check-reader.d.ts +1 -1
  55. package/dist/nodes/native/response-checks/create-response-check-reader.js +2 -2
  56. package/dist/nodes/native/response-collection-definition.d.ts +2 -0
  57. package/dist/nodes/native/response-collection-definition.js +27 -0
  58. package/dist/nodes/native/stop-and-error-capability.js +28 -14
  59. package/dist/nodes/request/bindings/compile-request-validator.d.ts +1 -1
  60. package/dist/nodes/request/bindings/compile-request-validator.js +2 -2
  61. package/dist/nodes/request/bindings/create-bound-request-fragment.js +8 -3
  62. package/dist/nodes/request/bindings/create-output-item-reader-code.d.ts +2 -0
  63. package/dist/nodes/request/bindings/create-output-item-reader-code.js +7 -0
  64. package/dist/nodes/request/bindings/create-output-reader-code.d.ts +1 -1
  65. package/dist/nodes/request/bindings/create-output-reader-code.js +4 -4
  66. package/dist/nodes/request/create-http-request-node.js +23 -44
  67. package/dist/nodes/request/finalize-http-request-fragment.d.ts +3 -0
  68. package/dist/nodes/request/finalize-http-request-fragment.js +22 -0
  69. package/dist/nodes/request/resolve-http-request-node-configuration.d.ts +4 -0
  70. package/dist/nodes/request/resolve-http-request-node-configuration.js +41 -0
  71. package/dist/nodes/request/response/create-http-response-decoder.js +2 -1
  72. package/dist/nodes/request/response/http-response-node-name.d.ts +2 -0
  73. package/dist/nodes/request/response/http-response-node-name.js +4 -0
  74. package/dist/nodes/request/response/response-runtime.bundle.js +1 -1
  75. package/dist/nodes/request/runtime/materialize-http-request.d.ts +2 -1
  76. package/dist/nodes/request/runtime/materialize-http-request.js +21 -3
  77. package/dist/nodes/request/runtime/request-runtime.bundle.js +1 -1
  78. package/dist/public-api.d.ts +13 -0
  79. package/dist/public-api.js +9 -0
  80. package/dist/schemas/native-feature-registry-schema.d.ts +17 -0
  81. package/dist/schemas/native-feature-registry-schema.js +8 -0
  82. package/dist/schemas/native-runtime-input-schema.d.ts +5 -0
  83. package/dist/schemas/native-runtime-input-schema.js +5 -0
  84. package/dist/schemas/template-deployment-selection-schema.d.ts +3 -0
  85. package/dist/schemas/template-deployment-selection-schema.js +10 -0
  86. package/dist/schemas/workflow-input-value-map-schema.d.ts +5 -0
  87. package/dist/schemas/workflow-input-value-map-schema.js +5 -0
  88. package/dist/schemas/workflow-template-schema.d.ts +11 -0
  89. package/dist/schemas/workflow-template-schema.js +10 -0
  90. package/dist/types/native-capability.d.ts +10 -1
  91. package/dist/types/native-feature-registry.d.ts +70 -0
  92. package/dist/types/native-feature-registry.js +14 -0
  93. package/dist/types/native-material-binding.d.ts +56 -0
  94. package/dist/types/native-material-binding.js +1 -0
  95. package/dist/types/native-runtime-parameters.d.ts +55 -0
  96. package/dist/types/native-runtime-parameters.js +1 -0
  97. package/dist/types/output-binding-source.d.ts +5 -0
  98. package/dist/types/request-materialization.d.ts +9 -1
  99. package/dist/types/request-node-configuration.d.ts +13 -0
  100. package/dist/types/request-node-configuration.js +1 -0
  101. package/dist/types/response-check-compilation.d.ts +1 -1
  102. package/dist/types/reviewable-workflow.d.ts +2 -0
  103. package/dist/types/workflow-compilation.d.ts +3 -0
  104. package/dist/types/workflow-template.d.ts +121 -0
  105. package/dist/types/workflow-template.js +1 -0
  106. package/dist/workflow/batch/compile-batched-n8n-workflow.js +22 -4
  107. package/dist/workflow/build-n8n-workflow.js +3 -6
  108. package/dist/workflow/compile-native-material-fragments.d.ts +3 -0
  109. package/dist/workflow/compile-native-material-fragments.js +76 -0
  110. package/dist/workflow/compile-native-workflow-nodes.js +22 -23
  111. package/dist/workflow/compile-planned-n8n-workflow.js +28 -3
  112. package/dist/workflow/compile-reviewable-n8n-workflow.js +31 -3
  113. package/dist/workflow/compile-validated-workflow-fragments.js +14 -14
  114. package/dist/workflow/compile-workflow-material-fragments.d.ts +4 -0
  115. package/dist/workflow/compile-workflow-material-fragments.js +18 -0
  116. package/dist/workflow/create-n8n-native-output-sources.js +53 -12
  117. package/dist/workflow/entrypoint/manual-trigger.d.ts +4 -0
  118. package/dist/workflow/entrypoint/manual-trigger.js +16 -0
  119. package/dist/workflow/find-singleton-api-responses.d.ts +3 -0
  120. package/dist/workflow/find-singleton-api-responses.js +22 -0
  121. package/dist/workflow/inputs/compile-native-runtime-inputs.d.ts +5 -0
  122. package/dist/workflow/inputs/compile-native-runtime-inputs.js +129 -0
  123. package/dist/workflow/inputs/create-runtime-input-native-capabilities.d.ts +4 -0
  124. package/dist/workflow/inputs/create-runtime-input-native-capabilities.js +36 -0
  125. package/dist/workflow/resolve-n8n-native-materials.d.ts +2 -0
  126. package/dist/workflow/resolve-n8n-native-materials.js +16 -0
  127. package/dist/workflow/templates/compile-n8n-workflow-template.d.ts +3 -0
  128. package/dist/workflow/templates/compile-n8n-workflow-template.js +211 -0
  129. package/dist/workflow/templates/create-template-artifact-mapping.d.ts +2 -0
  130. package/dist/workflow/templates/create-template-artifact-mapping.js +58 -0
  131. package/dist/workflow/templates/create-template-gap-regions.d.ts +5 -0
  132. package/dist/workflow/templates/create-template-gap-regions.js +22 -0
  133. package/dist/workflow/templates/create-workflow-template-guide.d.ts +3 -0
  134. package/dist/workflow/templates/create-workflow-template-guide.js +44 -0
  135. package/dist/workflow/templates/prepare-template-api-fragments.d.ts +3 -0
  136. package/dist/workflow/templates/prepare-template-api-fragments.js +74 -0
  137. package/dist/workflow/templates/select-n8n-template-deployments.d.ts +3 -0
  138. package/dist/workflow/templates/select-n8n-template-deployments.js +12 -0
  139. package/dist/workflow/templates/workflow-template-identities.d.ts +5 -0
  140. package/dist/workflow/templates/workflow-template-identities.js +5 -0
  141. package/package.json +9 -4
@@ -5,8 +5,15 @@ import { compilePlannedN8nWorkflow } from './compile-planned-n8n-workflow.js';
5
5
  import { compileNativeWorkflowNodes } from './compile-native-workflow-nodes.js';
6
6
  import { buildN8nWorkflow } from './build-n8n-workflow.js';
7
7
  import { validateCompiledBindingSources } from './validate-compiled-binding-sources.js';
8
+ import { prepareNativeRuntimeInputs, assembleNativeRuntimeInputs, } from './inputs/compile-native-runtime-inputs.js';
8
9
  export function compileReviewableN8nWorkflow(input) {
9
- validateReviewableWorkflowGraphPlan(input);
10
+ // This legacy executable-fragment path does not own deferred API input slots.
11
+ // Only the canonical template compiler may install their preflight/materialization nodes.
12
+ validateReviewableWorkflowGraphPlan({
13
+ materials: input.materials,
14
+ capabilities: input.capabilities,
15
+ plan: input.plan,
16
+ });
10
17
  const blocked = new Set(input.plan.blockedCalls.map((item) => item.callId));
11
18
  const ready = input.materials.filter((item) => item.status === 'ready' && !blocked.has(item.arguments.callId));
12
19
  const expected = ready.map((item) => item.arguments.callId).sort();
@@ -15,9 +22,23 @@ export function compileReviewableN8nWorkflow(input) {
15
22
  throw new Error('review apiNodes must exactly match unblocked ready calls');
16
23
  if (!input.plan.gaps.length)
17
24
  return compilePlannedN8nWorkflow({ ...input, materials: ready });
25
+ const nativeInputs = prepareNativeRuntimeInputs({
26
+ nativeInputs: input.nativeInputs,
27
+ nativeNodes: input.plan.nativeNodes,
28
+ capabilities: input.capabilities,
29
+ apiMaterials: ready.map((item) => ({
30
+ callId: item.arguments.callId,
31
+ operation: item.operation,
32
+ requestMediaType: item.arguments.requestMediaType,
33
+ })),
34
+ nativeOutputs: [],
35
+ });
18
36
  const nativeNodes = compileNativeWorkflowNodes({
19
37
  ...input,
20
38
  materials: ready,
39
+ capabilities: nativeInputs === undefined
40
+ ? input.capabilities
41
+ : nativeInputs.capabilities,
21
42
  });
22
43
  validateCompiledBindingSources(input.apiNodes, nativeNodes, createNativeOutputContracts({
23
44
  nativeNodes: input.plan.nativeNodes,
@@ -48,7 +69,7 @@ export function compileReviewableN8nWorkflow(input) {
48
69
  });
49
70
  }
50
71
  const regions = placeholders.map(createGapReviewRegion);
51
- const result = buildN8nWorkflow({
72
+ const graph = {
52
73
  id: input.id,
53
74
  name: input.name,
54
75
  nodes: [
@@ -60,11 +81,18 @@ export function compileReviewableN8nWorkflow(input) {
60
81
  starts: input.plan.starts,
61
82
  triggerConnections: 'detached',
62
83
  annotations: regions.map((region) => region.annotation),
63
- });
84
+ };
85
+ const compiled = nativeInputs === undefined
86
+ ? undefined
87
+ : assembleNativeRuntimeInputs({ ...graph, nativeInputs });
88
+ const result = compiled === undefined ? buildN8nWorkflow(graph) : compiled.workflow;
64
89
  result.settings = { ...result.settings, executionOrder: 'v1' };
65
90
  return {
66
91
  status: 'needs-review',
67
92
  workflow: result,
68
93
  diagnostics: input.plan.gaps,
94
+ ...(compiled === undefined
95
+ ? {}
96
+ : { nativeInputTemplate: compiled.nativeInputTemplate }),
69
97
  };
70
98
  }
@@ -1,20 +1,20 @@
1
- import { compileNativeWorkflowNodes } from './compile-native-workflow-nodes.js';
2
- import { validateWorkflowGraphPlan, createNativeOutputContracts, } from '@openapi-flow/core';
3
- import { validateCompiledBindingSources } from './validate-compiled-binding-sources.js';
1
+ import { validateWorkflowGraphPlan } from '@openapi-flow/core';
2
+ import { compileWorkflowMaterialFragments } from './compile-workflow-material-fragments.js';
3
+ import { resolveN8nNativeMaterials } from './resolve-n8n-native-materials.js';
4
4
  export function compileValidatedWorkflowFragments(input) {
5
5
  if (input.plan.gaps.length)
6
6
  throw new Error(`Workflow needs review: ${JSON.stringify(input.plan.gaps)}`);
7
- validateWorkflowGraphPlan(input);
8
- const expectedIds = input.materials
9
- .map((item) => item.arguments.callId)
10
- .sort();
11
- const actualIds = input.apiNodes.map((item) => item.nodeId).sort();
12
- if (JSON.stringify(expectedIds) !== JSON.stringify(actualIds))
13
- throw new Error('apiNodes must match material callIds exactly');
14
- const nativeNodes = compileNativeWorkflowNodes(input);
15
- validateCompiledBindingSources(input.apiNodes, nativeNodes, createNativeOutputContracts({
7
+ const materialSnapshot = resolveN8nNativeMaterials({
8
+ apiMaterials: input.materials.map((material) => ({
9
+ callId: material.arguments.callId,
10
+ operation: material.operation,
11
+ requestMediaType: material.arguments.requestMediaType,
12
+ })),
13
+ nativeOutputs: [],
16
14
  nativeNodes: input.plan.nativeNodes,
17
15
  capabilities: input.capabilities,
18
- }), input.materials);
19
- return [...input.apiNodes, ...nativeNodes];
16
+ });
17
+ const current = { ...input, capabilities: materialSnapshot.capabilities };
18
+ validateWorkflowGraphPlan(current);
19
+ return compileWorkflowMaterialFragments(current);
20
20
  }
@@ -0,0 +1,4 @@
1
+ import type { CompileNativeWorkflowNodesInput } from '../types/native-capability.js';
2
+ import type { N8nNodeFragment } from '../types/node-fragment.js';
3
+ /** Shared SDK material lowering. The owning strict/draft boundary validates the whole topology first. */
4
+ export declare function compileWorkflowMaterialFragments(input: CompileNativeWorkflowNodesInput): N8nNodeFragment[];
@@ -0,0 +1,18 @@
1
+ import { createNativeOutputContracts } from '@openapi-flow/core';
2
+ import { compileNativeWorkflowNodes } from './compile-native-workflow-nodes.js';
3
+ import { validateCompiledBindingSources } from './validate-compiled-binding-sources.js';
4
+ /** Shared SDK material lowering. The owning strict/draft boundary validates the whole topology first. */
5
+ export function compileWorkflowMaterialFragments(input) {
6
+ const expected = input.materials
7
+ .map((material) => material.arguments.callId)
8
+ .sort();
9
+ const actual = input.apiNodes.map((fragment) => fragment.nodeId).sort();
10
+ if (JSON.stringify(expected) !== JSON.stringify(actual))
11
+ throw new Error('apiNodes must match material callIds exactly');
12
+ const nativeNodes = compileNativeWorkflowNodes(input);
13
+ validateCompiledBindingSources(input.apiNodes, nativeNodes, createNativeOutputContracts({
14
+ nativeNodes: input.plan.nativeNodes,
15
+ capabilities: input.capabilities,
16
+ }), input.materials);
17
+ return [...input.apiNodes, ...nativeNodes];
18
+ }
@@ -1,17 +1,58 @@
1
- import { createNativeOutputContracts } from '@openapi-flow/core';
1
+ import { inspectNativeReferenceStructure, resolveNativeStructureParameters, } from '@openapi-flow/core';
2
+ import { resolveN8nNativeMaterials } from './resolve-n8n-native-materials.js';
3
+ import { compileNativeMaterialFragments } from './compile-native-material-fragments.js';
4
+ import { prepareNativeRuntimeInputs } from './inputs/compile-native-runtime-inputs.js';
2
5
  /** Resolve runtime names from the actual SDK producer, not an ID/name guess. */
3
6
  export function createN8nNativeOutputSources(input) {
4
- const outputs = createNativeOutputContracts(input);
5
- return outputs.map((output) => {
6
- const planned = input.nativeNodes.find((item) => item.id === output.nodeId);
7
- const capability = input.capabilities.find((item) => item.name === planned.capability);
8
- const fragment = capability.compile({
9
- planned,
10
- apiNodeNames: input.apiNodeNames,
11
- position: [600, 300],
7
+ const references = input.nativeNodes.flatMap((node) => {
8
+ const capability = input.capabilities.find((capability) => capability.name === node.capability);
9
+ if (!capability)
10
+ throw new Error('Missing native compiler ' + node.capability);
11
+ if (capability.referenceStructureSchema)
12
+ return inspectNativeReferenceStructure({ node, capability }).map((binding) => binding.reference);
13
+ const parameters = resolveNativeStructureParameters(node, capability);
14
+ return [
15
+ ...capability.responseReferences(parameters),
16
+ ...Object.values(capability.inputReferences
17
+ ? capability.inputReferences(parameters)
18
+ : {}).flat(),
19
+ ];
20
+ });
21
+ for (const reference of references)
22
+ if (reference.source === 'response' &&
23
+ (!input.apiResponseContracts ||
24
+ !Object.hasOwn(input.apiResponseContracts, reference.nodeId)))
25
+ throw new Error('createN8nNativeOutputSources.apiResponseContracts is missing ' +
26
+ reference.nodeId);
27
+ const apiMaterials = input.apiResponseContracts === undefined
28
+ ? []
29
+ : Object.entries(input.apiResponseContracts).map(([callId, operation]) => ({ callId, operation }));
30
+ const externalNativeOutputSources = input.externalNativeOutputSources === undefined
31
+ ? []
32
+ : input.externalNativeOutputSources;
33
+ const nativeInputs = input.nativeInputs === undefined
34
+ ? undefined
35
+ : prepareNativeRuntimeInputs({
36
+ nativeInputs: input.nativeInputs,
37
+ nativeNodes: input.nativeNodes,
38
+ capabilities: input.capabilities,
39
+ apiMaterials,
40
+ nativeOutputs: externalNativeOutputSources,
12
41
  });
13
- if (fragment.nodeId !== output.nodeId || !fragment.exit.name.trim())
14
- throw new Error(`native output ${output.nodeId} requires its compiled identity/name`);
15
- return { ...output, nodeName: fragment.exit.name };
42
+ const materials = resolveN8nNativeMaterials({
43
+ apiMaterials,
44
+ nativeOutputs: externalNativeOutputSources,
45
+ nativeNodes: input.nativeNodes,
46
+ capabilities: nativeInputs === undefined
47
+ ? input.capabilities
48
+ : nativeInputs.capabilities,
16
49
  });
50
+ return compileNativeMaterialFragments({
51
+ nativeNodes: input.nativeNodes,
52
+ materials,
53
+ apiMaterials,
54
+ apiNodeNames: input.apiNodeNames,
55
+ externalNativeOutputSources,
56
+ nodeIds: materials.outputs.map((output) => output.nodeId),
57
+ }).outputSources;
17
58
  }
@@ -0,0 +1,4 @@
1
+ import type { WorkflowEntryPointContract } from '@openapi-flow/core';
2
+ /** The same compiler-owned start is described to planning and built by the SDK. */
3
+ export declare function describeN8nManualTrigger(): WorkflowEntryPointContract;
4
+ export declare function createN8nManualTrigger(): import("@n8n/workflow-sdk").TriggerInstance<string, `${number}`, unknown>;
@@ -0,0 +1,16 @@
1
+ import { trigger } from '@n8n/workflow-sdk';
2
+ const nodeType = 'n8n-nodes-base.manualTrigger';
3
+ /** The same compiler-owned start is described to planning and built by the SDK. */
4
+ export function describeN8nManualTrigger() {
5
+ return {
6
+ kind: nodeType,
7
+ description: 'The n8n compiler supplies one Manual Trigger start. Users run the workflow manually; this entrypoint is not a selectable native capability and requires no extra planned trigger instance.',
8
+ };
9
+ }
10
+ export function createN8nManualTrigger() {
11
+ return trigger({
12
+ type: nodeType,
13
+ version: 1,
14
+ config: { id: 'openapi-flow-start', name: 'Start', position: [0, 0] },
15
+ });
16
+ }
@@ -0,0 +1,3 @@
1
+ import type { CompileNativeWorkflowNodesInput } from '../types/native-capability.js';
2
+ /** Prove at-most-one output from the single Manual Trigger item; unknown native streams are not singleton evidence. */
3
+ export declare function findSingletonApiResponses(input: CompileNativeWorkflowNodesInput): string[];
@@ -0,0 +1,22 @@
1
+ /** Prove at-most-one output from the single Manual Trigger item; unknown native streams are not singleton evidence. */
2
+ export function findSingletonApiResponses(input) {
3
+ const proven = new Set();
4
+ const pending = input.apiNodes.filter((fragment) => fragment.preservesInputItems === true);
5
+ let changed = true;
6
+ while (pending.length && changed) {
7
+ changed = false;
8
+ for (let index = 0; index < pending.length;) {
9
+ const node = pending[index];
10
+ const incoming = input.plan.edges.filter((edge) => edge.to === node.nodeId);
11
+ const isRoot = incoming.length === 0 && input.plan.starts.includes(node.nodeId);
12
+ if (isRoot || (incoming.length === 1 && proven.has(incoming[0].from))) {
13
+ proven.add(node.nodeId);
14
+ pending.splice(index, 1);
15
+ changed = true;
16
+ }
17
+ else
18
+ index++;
19
+ }
20
+ }
21
+ return [...proven];
22
+ }
@@ -0,0 +1,5 @@
1
+ import type { PrepareNativeRuntimeInputsInput, PreparedNativeRuntimeInputs, AssembleNativeRuntimeInputsInput, N8nNativeInputCompilationResult } from '../../types/native-runtime-parameters.js';
2
+ /** One explicit execution-input protocol, shared by strict and review compilation. */
3
+ export declare function prepareNativeRuntimeInputs(input: PrepareNativeRuntimeInputsInput): PreparedNativeRuntimeInputs | undefined;
4
+ /** Preserve every original DAG edge; only explicit system roots precede the graph. */
5
+ export declare function assembleNativeRuntimeInputs(input: AssembleNativeRuntimeInputsInput): N8nNativeInputCompilationResult;
@@ -0,0 +1,129 @@
1
+ import { sticky } from '@n8n/workflow-sdk';
2
+ import { inspectNativeRuntimeInputs, createNativeRuntimeParameterMaterializations, } from '@openapi-flow/core';
3
+ import { n8nNativeInputConfigurationSchema } from '../../schemas/native-runtime-input-schema.js';
4
+ import { resolveN8nNativeMaterials } from '../resolve-n8n-native-materials.js';
5
+ import { createRuntimeInputNativeCapabilities } from './create-runtime-input-native-capabilities.js';
6
+ import { createTemplateInputNodes } from '../../nodes/inputs/create-template-input-nodes.js';
7
+ import { buildN8nWorkflow } from '../build-n8n-workflow.js';
8
+ import { TEMPLATE_INPUT_ID, TEMPLATE_INPUT_NAME, TEMPLATE_PREFLIGHT_ID, TEMPLATE_PREFLIGHT_NAME, TEMPLATE_GUIDE_ID, } from '../templates/workflow-template-identities.js';
9
+ /** One explicit execution-input protocol, shared by strict and review compilation. */
10
+ export function prepareNativeRuntimeInputs(input) {
11
+ if (input.nativeInputs === undefined) {
12
+ if (input.nativeNodes.some((node) => node.runtimeParameters !== undefined))
13
+ throw new Error('nativeInputs.revision is required when the plan declares native runtime parameters');
14
+ return undefined;
15
+ }
16
+ const configuration = n8nNativeInputConfigurationSchema.parse(input.nativeInputs);
17
+ const snapshot = resolveN8nNativeMaterials({
18
+ apiMaterials: input.apiMaterials,
19
+ nativeOutputs: input.nativeOutputs,
20
+ nativeNodes: input.nativeNodes,
21
+ capabilities: input.capabilities,
22
+ });
23
+ const inputValues = configuration.inputValues === undefined ? {} : configuration.inputValues;
24
+ const inspection = inspectNativeRuntimeInputs({
25
+ nativeNodes: input.nativeNodes,
26
+ capabilities: snapshot.capabilities,
27
+ inputValues,
28
+ });
29
+ if (inspection.status === 'invalid-input')
30
+ throw new Error(`nativeInputs.inputValues: ${inspection.issues.map((issue) => issue.message).join('; ')}`);
31
+ if (!inspection.slots.length)
32
+ return undefined;
33
+ return {
34
+ revision: configuration.revision,
35
+ inputValues: structuredClone(inputValues),
36
+ inputsReady: inspection.status === 'ready',
37
+ slots: inspection.slots,
38
+ nativeParameters: createNativeRuntimeParameterMaterializations({
39
+ nativeNodes: input.nativeNodes,
40
+ capabilities: snapshot.capabilities,
41
+ }),
42
+ capabilities: createRuntimeInputNativeCapabilities({
43
+ capabilities: snapshot.capabilities,
44
+ slots: inspection.slots,
45
+ revision: configuration.revision,
46
+ inputNodeName: TEMPLATE_PREFLIGHT_NAME,
47
+ }),
48
+ };
49
+ }
50
+ /** Preserve every original DAG edge; only explicit system roots precede the graph. */
51
+ export function assembleNativeRuntimeInputs(input) {
52
+ const prepared = input.nativeInputs;
53
+ const inputSlots = prepared.slots.map((slot) => {
54
+ const fragment = input.nodes.find((node) => node.nodeId === slot.nodeId);
55
+ if (!fragment)
56
+ throw new Error(`Native input ${slot.id} has no compiled node ${slot.nodeId}`);
57
+ return {
58
+ ...slot,
59
+ editNodeId: TEMPLATE_INPUT_ID,
60
+ editNodeName: TEMPLATE_INPUT_NAME,
61
+ editParameter: 'jsCode',
62
+ materializerNodeName: fragment.entry.name,
63
+ };
64
+ });
65
+ const guide = [
66
+ '# Native 실행 입력 안내',
67
+ `입력 버전: ${prepared.revision}`,
68
+ '입력 설정 노드의 inputValues 객체에 아래 슬롯 ID와 실제 JSON 값을 넣으세요. 미입력 값에 임시 값을 넣지 마세요. 인증 비밀값은 n8n credential에 설정하세요.',
69
+ `입력 준비: ${prepared.inputsReady ? '완료' : '미입력 값 있음'}`,
70
+ ...(input.triggerConnections === 'detached'
71
+ ? [
72
+ '결손이 있어 Start 연결을 끊었습니다. 경고 영역을 해결한 뒤 연결을 검토하세요.',
73
+ ]
74
+ : []),
75
+ ...inputSlots.map((slot) => `\n## ${slot.nodeId}${slot.targetPointer}\n슬롯 ID: ${slot.id}\n입력 위치: ${slot.editNodeName}\n실행 직전 검사: ${slot.materializerNodeName}\n원래 형식:\n\`\`\`json\n${JSON.stringify(slot.schema, null, 2)}\n\`\`\``),
76
+ '입력 사전 검사는 모든 초기 native 값을 외부 호출 전에 확인합니다. 각 native 노드는 실행 직전에도 원래 전체 스키마와 버전을 검사합니다. 부분 실행이나 pinning은 검사를 우회할 수 있으므로 보안 경계로 사용하지 마세요.',
77
+ ].join('\n\n');
78
+ const system = createTemplateInputNodes({
79
+ revision: prepared.revision,
80
+ slots: prepared.slots,
81
+ inputValues: prepared.inputValues,
82
+ requests: [],
83
+ nativeParameters: prepared.nativeParameters,
84
+ });
85
+ const height = 160 +
86
+ guide
87
+ .split('\n')
88
+ .reduce((total, line) => total + Math.max(1, Math.ceil(line.length / 90)) * 24, 0);
89
+ const workflow = buildN8nWorkflow({
90
+ ...input,
91
+ nodes: [...system, ...input.nodes],
92
+ edges: [
93
+ {
94
+ from: TEMPLATE_INPUT_ID,
95
+ output: 'main',
96
+ to: TEMPLATE_PREFLIGHT_ID,
97
+ input: 'main',
98
+ },
99
+ ...input.starts.map((to) => ({
100
+ from: TEMPLATE_PREFLIGHT_ID,
101
+ output: 'main',
102
+ to,
103
+ input: 'main',
104
+ })),
105
+ ...input.edges,
106
+ ],
107
+ starts: [TEMPLATE_INPUT_ID],
108
+ annotations: [
109
+ ...input.annotations,
110
+ sticky(guide, [], {
111
+ id: TEMPLATE_GUIDE_ID,
112
+ name: 'Native 실행 입력 안내',
113
+ position: [0, -height - 100],
114
+ width: 1000,
115
+ height,
116
+ color: prepared.inputsReady ? 5 : 3,
117
+ }),
118
+ ],
119
+ });
120
+ return {
121
+ workflow,
122
+ nativeInputTemplate: {
123
+ revision: prepared.revision,
124
+ inputsReady: prepared.inputsReady,
125
+ inputSlots,
126
+ guide,
127
+ },
128
+ };
129
+ }
@@ -0,0 +1,4 @@
1
+ import type { CreateRuntimeInputNativeCapabilitiesInput } from '../../types/native-runtime-parameters.js';
2
+ import type { N8nNativeCapability } from '../../types/native-capability.js';
3
+ /** Runtime ownership remains explicit; the original schema and metadata are never replaced. */
4
+ export declare function createRuntimeInputNativeCapabilities(input: CreateRuntimeInputNativeCapabilitiesInput): N8nNativeCapability[];
@@ -0,0 +1,36 @@
1
+ import { createNativeRuntimeParameterMaterializations, captureNativePlanningCapability, } from '@openapi-flow/core';
2
+ /** Runtime ownership remains explicit; the original schema and metadata are never replaced. */
3
+ export function createRuntimeInputNativeCapabilities(input) {
4
+ function wrap(capability) {
5
+ if (capability.supportsRuntimeParameters !== true)
6
+ return capability;
7
+ const bind = capability.bindMaterialContracts;
8
+ return {
9
+ ...capability,
10
+ ...captureNativePlanningCapability(capability),
11
+ bindMaterialContracts: bind === undefined
12
+ ? undefined
13
+ : (sources) => wrap(bind.call(capability, sources)),
14
+ compile(source) {
15
+ if (source.planned.runtimeParameters === undefined)
16
+ return capability.compile(source);
17
+ const [materialization] = createNativeRuntimeParameterMaterializations({
18
+ nativeNodes: [source.planned],
19
+ capabilities: [capability],
20
+ });
21
+ if (!materialization ||
22
+ materialization.inputs.some((source) => !input.slots.some((slot) => slot.id === source.id)))
23
+ throw new Error(`node ${source.planned.id}: template has no declared native runtime input slot`);
24
+ return capability.compile({
25
+ ...source,
26
+ runtimeInput: {
27
+ materialization,
28
+ revision: input.revision,
29
+ inputNodeName: input.inputNodeName,
30
+ },
31
+ });
32
+ },
33
+ };
34
+ }
35
+ return input.capabilities.map(wrap);
36
+ }
@@ -0,0 +1,2 @@
1
+ import type { ResolveN8nNativeMaterialsInput, ResolvedN8nNativeMaterials } from '../types/native-material-binding.js';
2
+ export declare function resolveN8nNativeMaterials(input: ResolveN8nNativeMaterialsInput): ResolvedN8nNativeMaterials;
@@ -0,0 +1,16 @@
1
+ import { resolveNativeMaterialSnapshot, NativeMaterialResolutionError, } from '@openapi-flow/core';
2
+ export function resolveN8nNativeMaterials(input) {
3
+ const snapshot = resolveNativeMaterialSnapshot({
4
+ ...input,
5
+ deferredNodeIds: [],
6
+ });
7
+ if (snapshot.status !== 'ready')
8
+ throw new NativeMaterialResolutionError(snapshot.pending);
9
+ for (const capability of snapshot.capabilities)
10
+ if (!('compile' in capability) || typeof capability.compile !== 'function')
11
+ throw new Error(`Native material binding ${capability.name} did not retain its n8n compiler`);
12
+ return {
13
+ capabilities: snapshot.capabilities,
14
+ outputs: snapshot.outputs,
15
+ };
16
+ }
@@ -0,0 +1,3 @@
1
+ import type { CompileN8nWorkflowTemplateInput, N8nWorkflowTemplateResult } from '../../types/workflow-template.js';
2
+ /** An explicit template boundary, never a false fully-resolved strict request. */
3
+ export declare function compileN8nWorkflowTemplate(source: CompileN8nWorkflowTemplateInput): N8nWorkflowTemplateResult;