@openapi-flow/core 0.1.0 → 0.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.
Files changed (239) hide show
  1. package/README.md +27 -5
  2. package/THIRD_PARTY_NOTICES.md +1 -1
  3. package/dist/arguments/list-api-request-media-types.d.ts +2 -0
  4. package/dist/arguments/list-api-request-media-types.js +8 -0
  5. package/dist/arguments/request-contract.d.ts +4 -0
  6. package/dist/arguments/request-contract.js +38 -0
  7. package/dist/arguments/request-media-type-priority.d.ts +2 -0
  8. package/dist/arguments/request-media-type-priority.js +8 -0
  9. package/dist/arguments/select-default-api-request-media-type.d.ts +3 -0
  10. package/dist/arguments/select-default-api-request-media-type.js +17 -0
  11. package/dist/arguments/validate-api-arguments.d.ts +2 -0
  12. package/dist/arguments/validate-api-arguments.js +140 -0
  13. package/dist/bindings/combine-binding-schemas.d.ts +4 -0
  14. package/dist/bindings/combine-binding-schemas.js +17 -0
  15. package/dist/bindings/create-native-array-item-schema.d.ts +4 -0
  16. package/dist/bindings/create-native-array-item-schema.js +16 -0
  17. package/dist/bindings/json-pointer.d.ts +3 -0
  18. package/dist/bindings/json-pointer.js +24 -0
  19. package/dist/bindings/materialize-api-arguments.d.ts +4 -0
  20. package/dist/bindings/materialize-api-arguments.js +54 -0
  21. package/dist/bindings/native-binding-schema.d.ts +3 -0
  22. package/dist/bindings/native-binding-schema.js +6 -0
  23. package/dist/bindings/project-array-item-schema.d.ts +5 -0
  24. package/dist/bindings/project-array-item-schema.js +67 -0
  25. package/dist/bindings/request-binding-schema.d.ts +2 -0
  26. package/dist/bindings/request-binding-schema.js +23 -0
  27. package/dist/bindings/request-container-kind.d.ts +3 -0
  28. package/dist/bindings/request-container-kind.js +17 -0
  29. package/dist/bindings/resources/clone-schema-resource.d.ts +3 -0
  30. package/dist/bindings/resources/clone-schema-resource.js +38 -0
  31. package/dist/bindings/resources/create-schema-resource-context.d.ts +4 -0
  32. package/dist/bindings/resources/create-schema-resource-context.js +130 -0
  33. package/dist/bindings/response-binding-schema.d.ts +3 -0
  34. package/dist/bindings/response-binding-schema.js +21 -0
  35. package/dist/bindings/schema-allows-container.d.ts +3 -0
  36. package/dist/bindings/schema-allows-container.js +20 -0
  37. package/dist/bindings/schema-at-pointer.d.ts +4 -0
  38. package/dist/bindings/schema-at-pointer.js +89 -0
  39. package/dist/bindings/validate-api-binding-assignments.d.ts +2 -0
  40. package/dist/bindings/validate-api-binding-assignments.js +81 -0
  41. package/dist/bindings/validate-api-binding-gaps.d.ts +2 -0
  42. package/dist/bindings/validate-api-binding-gaps.js +10 -0
  43. package/dist/bindings/validate-api-binding-plan.d.ts +3 -0
  44. package/dist/bindings/validate-api-binding-plan.js +11 -0
  45. package/dist/bindings/validate-native-output-contracts.d.ts +3 -0
  46. package/dist/bindings/validate-native-output-contracts.js +16 -0
  47. package/dist/internal-api.d.ts +30 -0
  48. package/dist/internal-api.js +25 -0
  49. package/dist/openapi/catalog/create-api-catalog.d.ts +2 -0
  50. package/dist/openapi/catalog/create-api-catalog.js +34 -0
  51. package/dist/openapi/catalog/list-api-operations.d.ts +2 -0
  52. package/dist/openapi/catalog/list-api-operations.js +3 -0
  53. package/dist/openapi/common/check-oas-value.d.ts +3 -0
  54. package/dist/openapi/common/check-oas-value.js +6 -0
  55. package/dist/openapi/common/check-schema-value.d.ts +2 -0
  56. package/dist/openapi/common/check-schema-value.js +12 -0
  57. package/dist/openapi/common/create-oas-value-validator.d.ts +3 -0
  58. package/dist/openapi/common/create-oas-value-validator.js +39 -0
  59. package/dist/openapi/common/normalize-oas-value-schema.d.ts +4 -0
  60. package/dist/openapi/common/normalize-oas-value-schema.js +50 -0
  61. package/dist/openapi/common/operation-metadata.d.ts +2 -0
  62. package/dist/openapi/common/operation-metadata.js +25 -0
  63. package/dist/openapi/common/operation-reference.d.ts +3 -0
  64. package/dist/openapi/{operation-reference.js → common/operation-reference.js} +1 -4
  65. package/dist/openapi/common/parse-spec-utils.d.ts +3 -0
  66. package/dist/openapi/common/parse-spec-utils.js +12 -0
  67. package/dist/openapi/common/resolve-openapi-security.d.ts +3 -0
  68. package/dist/openapi/common/resolve-openapi-security.js +28 -0
  69. package/dist/openapi/common/unsupported-operation-error.d.ts +4 -0
  70. package/dist/openapi/common/unsupported-operation-error.js +8 -0
  71. package/dist/openapi/common/validate-spec.d.ts +3 -0
  72. package/dist/openapi/{validate-spec.js → common/validate-spec.js} +2 -1
  73. package/dist/openapi/inbound/callback/parse-callback-operations.d.ts +3 -0
  74. package/dist/openapi/inbound/callback/parse-callback-operations.js +31 -0
  75. package/dist/openapi/inbound/inbound-path-item-operations.d.ts +4 -0
  76. package/dist/openapi/inbound/inbound-path-item-operations.js +31 -0
  77. package/dist/openapi/inbound/list-inbound-operations.d.ts +4 -0
  78. package/dist/openapi/inbound/list-inbound-operations.js +13 -0
  79. package/dist/openapi/inbound/webhook/parse-webhook-operations.d.ts +3 -0
  80. package/dist/openapi/inbound/webhook/parse-webhook-operations.js +13 -0
  81. package/dist/openapi/request/create-operation-catalog.d.ts +2 -0
  82. package/dist/openapi/request/create-operation-catalog.js +24 -0
  83. package/dist/openapi/request/encode-form-field.d.ts +2 -0
  84. package/dist/openapi/request/encode-form-field.js +6 -0
  85. package/dist/openapi/request/map-http-operation-contract.d.ts +4 -0
  86. package/dist/openapi/request/map-http-operation-contract.js +21 -0
  87. package/dist/openapi/request/operation-mapping.d.ts +3 -0
  88. package/dist/openapi/request/operation-mapping.js +10 -0
  89. package/dist/openapi/request/parse-operation-responses.d.ts +3 -0
  90. package/dist/openapi/request/parse-operation-responses.js +30 -0
  91. package/dist/openapi/request/parse-request-body.d.ts +3 -0
  92. package/dist/openapi/request/parse-request-body.js +29 -0
  93. package/dist/openapi/request/parse-request-operations.d.ts +7 -0
  94. package/dist/openapi/request/parse-request-operations.js +50 -0
  95. package/dist/openapi/request/parse-request-parameters.d.ts +3 -0
  96. package/dist/openapi/request/parse-request-parameters.js +93 -0
  97. package/dist/openapi/request/parse-security.d.ts +3 -0
  98. package/dist/openapi/request/parse-security.js +31 -0
  99. package/dist/openapi/request/request-operation-reference.d.ts +1 -0
  100. package/dist/openapi/request/request-operation-reference.js +4 -0
  101. package/dist/openapi/request/response-contract.d.ts +6 -0
  102. package/dist/openapi/request/response-contract.js +32 -0
  103. package/dist/openapi/request/scalar-response-schema.d.ts +2 -0
  104. package/dist/openapi/request/scalar-response-schema.js +20 -0
  105. package/dist/openapi/request/serialize-form-body.d.ts +3 -0
  106. package/dist/openapi/request/serialize-form-body.js +89 -0
  107. package/dist/openapi/request/serialize-parameter.d.ts +5 -0
  108. package/dist/openapi/request/serialize-parameter.js +145 -0
  109. package/dist/openapi/resolve-api-operations.d.ts +3 -0
  110. package/dist/openapi/resolve-api-operations.js +84 -0
  111. package/dist/openapi/response/api-response-validation-value.d.ts +3 -0
  112. package/dist/openapi/response/api-response-validation-value.js +21 -0
  113. package/dist/openapi/response/create-api-response-schema.d.ts +4 -0
  114. package/dist/openapi/response/create-api-response-schema.js +114 -0
  115. package/dist/openapi/response/create-response-array-item-schema.d.ts +4 -0
  116. package/dist/openapi/response/create-response-array-item-schema.js +12 -0
  117. package/dist/openapi/response/create-response-value-schema.d.ts +4 -0
  118. package/dist/openapi/response/create-response-value-schema.js +8 -0
  119. package/dist/openapi/response/list-api-response-pointers.d.ts +4 -0
  120. package/dist/openapi/response/list-api-response-pointers.js +30 -0
  121. package/dist/openapi/response/list-declared-schema-pointers.d.ts +4 -0
  122. package/dist/openapi/response/list-declared-schema-pointers.js +91 -0
  123. package/dist/public-api.d.ts +49 -7
  124. package/dist/public-api.js +35 -5
  125. package/dist/runtime-api.d.ts +6 -0
  126. package/dist/runtime-api.js +7 -0
  127. package/dist/schemas/create-api-argument-generation-contract.d.ts +4 -0
  128. package/dist/schemas/create-api-argument-generation-contract.js +72 -0
  129. package/dist/schemas/create-api-arguments-schema.d.ts +3 -0
  130. package/dist/schemas/create-api-arguments-schema.js +4 -0
  131. package/dist/schemas/create-api-request-schema.d.ts +4 -0
  132. package/dist/schemas/create-api-request-schema.js +50 -0
  133. package/dist/schemas/create-oas-value-schema.d.ts +6 -0
  134. package/dist/schemas/create-oas-value-schema.js +25 -0
  135. package/dist/schemas/operation-plan-schema.d.ts +8 -0
  136. package/dist/schemas/operation-plan-schema.js +99 -0
  137. package/dist/schemas/project-literal-array-schema.d.ts +4 -0
  138. package/dist/schemas/project-literal-array-schema.js +55 -0
  139. package/dist/schemas/project-literal-input-schema.d.ts +3 -0
  140. package/dist/schemas/project-literal-input-schema.js +129 -0
  141. package/dist/types/api-argument-generation.d.ts +13 -0
  142. package/dist/types/api-arguments.d.ts +42 -0
  143. package/dist/types/api-arguments.js +1 -0
  144. package/dist/types/api-bindings.d.ts +34 -0
  145. package/dist/types/api-bindings.js +1 -0
  146. package/dist/types/api-catalog.d.ts +34 -0
  147. package/dist/types/api-catalog.js +1 -0
  148. package/dist/types/api-operation.d.ts +26 -0
  149. package/dist/types/api-operation.js +1 -0
  150. package/dist/types/api-response-pointers.d.ts +20 -0
  151. package/dist/types/api-response-pointers.js +1 -0
  152. package/dist/types/api-response.d.ts +14 -0
  153. package/dist/types/api-response.js +1 -0
  154. package/dist/types/array-projection.d.ts +5 -0
  155. package/dist/types/array-projection.js +1 -0
  156. package/dist/types/catalog.d.ts +17 -0
  157. package/dist/types/catalog.js +1 -0
  158. package/dist/types/inbound.d.ts +18 -0
  159. package/dist/types/inbound.js +1 -0
  160. package/dist/types/legacy-plan.d.ts +47 -0
  161. package/dist/types/legacy-plan.js +1 -0
  162. package/dist/types/node-output.d.ts +11 -0
  163. package/dist/types/node-output.js +1 -0
  164. package/dist/types/oas-value-validation.d.ts +8 -0
  165. package/dist/types/oas-value-validation.js +1 -0
  166. package/dist/types/openapi.d.ts +7 -23
  167. package/dist/types/request.d.ts +41 -0
  168. package/dist/types/request.js +1 -0
  169. package/dist/types/reviewable-workflow.d.ts +53 -0
  170. package/dist/types/reviewable-workflow.js +1 -0
  171. package/dist/types/schema-dialect.d.ts +1 -0
  172. package/dist/types/schema-dialect.js +1 -0
  173. package/dist/types/schema-json.d.ts +4 -0
  174. package/dist/types/schema-json.js +1 -0
  175. package/dist/types/schema-resource.d.ts +12 -0
  176. package/dist/types/schema-resource.js +1 -0
  177. package/dist/types/security.d.ts +17 -0
  178. package/dist/types/security.js +1 -0
  179. package/dist/types/workflow-capability-planning.d.ts +10 -0
  180. package/dist/types/workflow-capability-planning.js +1 -0
  181. package/dist/types/workflow-plan.d.ts +104 -0
  182. package/dist/types/workflow-plan.js +1 -0
  183. package/dist/utils/is-object.d.ts +2 -0
  184. package/dist/utils/is-object.js +3 -0
  185. package/dist/utils/json-values-equal.d.ts +2 -0
  186. package/dist/utils/json-values-equal.js +16 -0
  187. package/dist/workflow/assert-api-call-identities.d.ts +1 -0
  188. package/dist/workflow/assert-api-call-identities.js +6 -0
  189. package/dist/workflow/create-native-output-contracts.d.ts +3 -0
  190. package/dist/workflow/create-native-output-contracts.js +23 -0
  191. package/dist/workflow/create-reviewable-node-contracts.d.ts +3 -0
  192. package/dist/workflow/create-reviewable-node-contracts.js +36 -0
  193. package/dist/workflow/create-reviewable-workflow-graph-plan.d.ts +2 -0
  194. package/dist/workflow/create-reviewable-workflow-graph-plan.js +29 -0
  195. package/dist/workflow/create-workflow-graph-plan.d.ts +2 -0
  196. package/dist/workflow/create-workflow-graph-plan.js +17 -0
  197. package/dist/workflow/create-workflow-node-contracts.d.ts +2 -0
  198. package/dist/workflow/create-workflow-node-contracts.js +50 -0
  199. package/dist/workflow/create-workflow-planning-capabilities.d.ts +3 -0
  200. package/dist/workflow/create-workflow-planning-capabilities.js +20 -0
  201. package/dist/workflow/parse-native-node-parameters.d.ts +3 -0
  202. package/dist/workflow/parse-native-node-parameters.js +7 -0
  203. package/dist/workflow/validate-exclusive-output-rejoin.d.ts +3 -0
  204. package/dist/workflow/validate-exclusive-output-rejoin.js +26 -0
  205. package/dist/workflow/validate-native-api-response-references.d.ts +2 -0
  206. package/dist/workflow/validate-native-api-response-references.js +26 -0
  207. package/dist/workflow/validate-reviewable-workflow-graph-plan.d.ts +2 -0
  208. package/dist/workflow/validate-reviewable-workflow-graph-plan.js +98 -0
  209. package/dist/workflow/validate-workflow-edges.d.ts +2 -0
  210. package/dist/workflow/validate-workflow-edges.js +19 -0
  211. package/dist/workflow/validate-workflow-graph-plan.d.ts +3 -0
  212. package/dist/workflow/validate-workflow-graph-plan.js +41 -0
  213. package/dist/workflow/validate-workflow-topology.d.ts +2 -0
  214. package/dist/workflow/validate-workflow-topology.js +105 -0
  215. package/package.json +19 -25
  216. package/dist/openapi/operation-reference.d.ts +0 -3
  217. package/dist/openapi/parse-spec-utils.d.ts +0 -5
  218. package/dist/openapi/parse-spec-utils.js +0 -52
  219. package/dist/openapi/parse-spec.d.ts +0 -5
  220. package/dist/openapi/parse-spec.js +0 -182
  221. package/dist/openapi/validate-spec.d.ts +0 -3
  222. package/dist/planning/generate-workflow.d.ts +0 -2
  223. package/dist/planning/generate-workflow.js +0 -126
  224. package/dist/schemas/planning-schemas.d.ts +0 -62
  225. package/dist/schemas/planning-schemas.js +0 -48
  226. package/dist/types/workflow.d.ts +0 -75
  227. package/dist/utils/validation.d.ts +0 -7
  228. package/dist/utils/validation.js +0 -44
  229. package/dist/utils/workflow-id.d.ts +0 -1
  230. package/dist/utils/workflow-id.js +0 -8
  231. package/dist/workflow/compile-sequence.d.ts +0 -2
  232. package/dist/workflow/compile-sequence.js +0 -167
  233. package/dist/workflow/compile-workflow.d.ts +0 -4
  234. package/dist/workflow/compile-workflow.js +0 -128
  235. package/dist/workflow/sequence-url.d.ts +0 -3
  236. package/dist/workflow/sequence-url.js +0 -81
  237. package/dist/workflow/workflow-helpers.d.ts +0 -6
  238. package/dist/workflow/workflow-helpers.js +0 -81
  239. /package/dist/types/{workflow.js → api-argument-generation.js} +0 -0
@@ -0,0 +1,50 @@
1
+ import { isObject } from '../../utils/is-object.js';
2
+ /** Convert only OAS 3.0 assertion syntax, not formats, annotations or data. */
3
+ export function normalizeOasValueSchema(input, dialect) {
4
+ if (dialect === 'draft-2020-12' || typeof input === 'boolean')
5
+ return structuredClone(input);
6
+ const schema = structuredClone(input);
7
+ if (schema.nullable === true && typeof schema.type === 'string')
8
+ schema.type = [schema.type, 'null'];
9
+ delete schema.nullable;
10
+ for (const bound of ['Minimum', 'Maximum']) {
11
+ const exclusive = `exclusive${bound}`;
12
+ const inclusive = bound.toLowerCase();
13
+ if (typeof schema[exclusive] !== 'boolean')
14
+ continue;
15
+ if (schema[exclusive] === true && typeof schema[inclusive] === 'number') {
16
+ schema[exclusive] = schema[inclusive];
17
+ delete schema[inclusive];
18
+ }
19
+ else
20
+ delete schema[exclusive];
21
+ }
22
+ for (const key of [
23
+ 'properties',
24
+ 'patternProperties',
25
+ '$defs',
26
+ 'definitions',
27
+ ]) {
28
+ if (!isObject(schema[key]))
29
+ continue;
30
+ schema[key] = Object.fromEntries(Object.entries(schema[key]).map(([name, child]) => [
31
+ name,
32
+ isObject(child) || typeof child === 'boolean'
33
+ ? normalizeOasValueSchema(child, dialect)
34
+ : child,
35
+ ]));
36
+ }
37
+ for (const key of ['items', 'additionalProperties', 'not']) {
38
+ const child = schema[key];
39
+ if (isObject(child) || typeof child === 'boolean')
40
+ schema[key] = normalizeOasValueSchema(child, dialect);
41
+ }
42
+ for (const key of ['allOf', 'anyOf', 'oneOf', 'prefixItems']) {
43
+ if (!Array.isArray(schema[key]))
44
+ continue;
45
+ schema[key] = schema[key].map((child) => isObject(child) || typeof child === 'boolean'
46
+ ? normalizeOasValueSchema(child, dialect)
47
+ : child);
48
+ }
49
+ return schema;
50
+ }
@@ -0,0 +1,2 @@
1
+ import type { JsonObject, OperationMetadata } from '../../types/openapi.js';
2
+ export declare function operationMetadata(operation: JsonObject, source: string): OperationMetadata;
@@ -0,0 +1,25 @@
1
+ export function operationMetadata(operation, source) {
2
+ if (operation.operationId !== undefined &&
3
+ typeof operation.operationId !== 'string') {
4
+ throw new Error(`${source}.operationId must be a string`);
5
+ }
6
+ if (operation.tags !== undefined &&
7
+ (!Array.isArray(operation.tags) ||
8
+ !operation.tags.every((tag) => typeof tag === 'string'))) {
9
+ throw new Error(`${source}.tags must be an array of strings`);
10
+ }
11
+ if (operation.summary !== undefined &&
12
+ typeof operation.summary !== 'string') {
13
+ throw new Error(`${source}.summary must be a string`);
14
+ }
15
+ if (operation.description !== undefined &&
16
+ typeof operation.description !== 'string') {
17
+ throw new Error(`${source}.description must be a string`);
18
+ }
19
+ return {
20
+ operationId: operation.operationId,
21
+ summary: operation.summary === undefined ? '' : operation.summary,
22
+ description: operation.description === undefined ? '' : operation.description,
23
+ tags: operation.tags === undefined ? [] : operation.tags,
24
+ };
25
+ }
@@ -0,0 +1,3 @@
1
+ import type { OperationEntry } from '../../types/openapi.js';
2
+ export declare function pointerSegment(value: string): string;
3
+ export declare function operationEntries(pathItem: Record<string, unknown>): OperationEntry[];
@@ -9,7 +9,7 @@ const methods = [
9
9
  'trace',
10
10
  'query',
11
11
  ];
12
- function pointerSegment(value) {
12
+ export function pointerSegment(value) {
13
13
  return value.replace(/~/g, '~0').replace(/\//g, '~1');
14
14
  }
15
15
  export function operationEntries(pathItem) {
@@ -36,6 +36,3 @@ export function operationEntries(pathItem) {
36
36
  }
37
37
  return entries;
38
38
  }
39
- export function operationReference(path, key) {
40
- return '#/paths/' + pointerSegment(path) + '/' + key;
41
- }
@@ -0,0 +1,3 @@
1
+ import type { JsonObject } from '../../types/openapi.js';
2
+ export declare function object(value: unknown, source: string): JsonObject;
3
+ export declare function dereferencedObject(value: unknown, source: string): JsonObject;
@@ -0,0 +1,12 @@
1
+ export function object(value, source) {
2
+ if (value === null || typeof value !== 'object' || Array.isArray(value)) {
3
+ throw new Error(`${source} must be an object`);
4
+ }
5
+ return value;
6
+ }
7
+ export function dereferencedObject(value, source) {
8
+ const item = object(value, source);
9
+ if (item.$ref !== undefined)
10
+ throw new Error(`${source} has an unresolved $ref`);
11
+ return item;
12
+ }
@@ -0,0 +1,3 @@
1
+ import type { ResolveOpenApiSecurityInput, ResolvedOpenApiSecurity } from '../../types/security.js';
2
+ /** Preserve OAS OR alternatives and AND schemes; adapters own credential mappings. */
3
+ export declare function resolveOpenApiSecurity(input: ResolveOpenApiSecurityInput): ResolvedOpenApiSecurity | undefined;
@@ -0,0 +1,28 @@
1
+ import { dereferencedObject, object } from './parse-spec-utils.js';
2
+ /** Preserve OAS OR alternatives and AND schemes; adapters own credential mappings. */
3
+ export function resolveOpenApiSecurity(input) {
4
+ const source = `${input.operationRef}.security`;
5
+ if (!Array.isArray(input.security))
6
+ throw new Error(`${source} must be an array`);
7
+ if (!input.security.length && input.requirementIndex === undefined)
8
+ return undefined;
9
+ if (input.security.length > 1 && input.requirementIndex === undefined)
10
+ throw new Error(`${source} has alternatives; securityRequirementIndex is required`);
11
+ const index = input.requirementIndex === undefined ? 0 : input.requirementIndex;
12
+ if (!Number.isInteger(index) || index < 0 || index >= input.security.length)
13
+ throw new Error(`${source} securityRequirementIndex ${index} is not declared`);
14
+ const requirement = object(input.security[index], `${source}[${index}]`);
15
+ return {
16
+ requirementIndex: index,
17
+ schemes: Object.entries(requirement).map(([name, scopes]) => {
18
+ if (!Array.isArray(scopes) ||
19
+ scopes.some((scope) => typeof scope !== 'string'))
20
+ throw new Error(`${source}[${index}].${name} scopes must be strings`);
21
+ return {
22
+ name,
23
+ scopes: [...scopes],
24
+ definition: dereferencedObject(input.securitySchemes[name], `${input.operationRef}.securitySchemes.${name}`),
25
+ };
26
+ }),
27
+ };
28
+ }
@@ -0,0 +1,4 @@
1
+ export declare class UnsupportedOperationError extends Error {
2
+ readonly operationRef: string;
3
+ constructor(operationRef: string, message: string);
4
+ }
@@ -0,0 +1,8 @@
1
+ export class UnsupportedOperationError extends Error {
2
+ operationRef;
3
+ constructor(operationRef, message) {
4
+ super(message);
5
+ this.name = 'UnsupportedOperationError';
6
+ this.operationRef = operationRef;
7
+ }
8
+ }
@@ -0,0 +1,3 @@
1
+ import type { OpenApiDocument, ParsedDocument } from '../../types/openapi.js';
2
+ export declare function validateOpenApi(input: unknown): OpenApiDocument;
3
+ export declare function validateAndResolveOpenApiDocument(input: OpenApiDocument): Promise<ParsedDocument>;
@@ -17,9 +17,10 @@ export function validateOpenApi(input) {
17
17
  throw new Error('spec OpenAPI validation failed: ' +
18
18
  result.errors.map((error) => error.message).join('; '));
19
19
  }
20
+ // The external validator proved the OpenAPI contract before narrowing.
20
21
  return spec;
21
22
  }
22
- export async function validatedDocument(input) {
23
+ export async function validateAndResolveOpenApiDocument(input) {
23
24
  const spec = validateOpenApi(input);
24
25
  const result = await resolveAndValidate(spec);
25
26
  if (!result.valid) {
@@ -0,0 +1,3 @@
1
+ import type { ParsedDocument } from '../../../types/openapi.js';
2
+ import type { CallbackOperationSource } from '../../../types/inbound.js';
3
+ export declare function callbackOperationsFromDocument(document: ParsedDocument): CallbackOperationSource[];
@@ -0,0 +1,31 @@
1
+ import { operationEntries, pointerSegment, } from '../../common/operation-reference.js';
2
+ import { dereferencedObject, object } from '../../common/parse-spec-utils.js';
3
+ import { inboundPathItemOperations } from '../inbound-path-item-operations.js';
4
+ export function callbackOperationsFromDocument(document) {
5
+ const candidates = [];
6
+ for (const [path, rawPathItem] of Object.entries(document.paths)) {
7
+ const pathItem = dereferencedObject(rawPathItem, `spec.paths[${path}]`);
8
+ for (const entry of operationEntries(pathItem)) {
9
+ const parentOperationRef = '#/paths/' + pointerSegment(path) + '/' + entry.key;
10
+ const operation = object(entry.value, `operationRef ${parentOperationRef}`);
11
+ if (operation.callbacks === undefined)
12
+ continue;
13
+ const callbacks = object(operation.callbacks, `operationRef ${parentOperationRef}.callbacks`);
14
+ for (const [name, rawCallback] of Object.entries(callbacks)) {
15
+ const callback = dereferencedObject(rawCallback, `operationRef ${parentOperationRef}.callbacks.${name}`);
16
+ for (const [expression, raw] of Object.entries(callback)) {
17
+ if (expression.startsWith('x-'))
18
+ continue;
19
+ const pointer = parentOperationRef +
20
+ '/callbacks/' +
21
+ pointerSegment(name) +
22
+ '/' +
23
+ pointerSegment(expression);
24
+ const callbackPathItem = dereferencedObject(raw, `operationRef ${pointer}`);
25
+ candidates.push(...inboundPathItemOperations(callbackPathItem, expression, pointer, 'callbacks', parentOperationRef));
26
+ }
27
+ }
28
+ }
29
+ }
30
+ return candidates;
31
+ }
@@ -0,0 +1,4 @@
1
+ import type { JsonObject } from '../../types/openapi.js';
2
+ import type { CallbackOperationSource, WebhookOperationSource } from '../../types/inbound.js';
3
+ export declare function inboundPathItemOperations(pathItem: JsonObject, path: string, pointer: string, source: 'webhooks'): WebhookOperationSource[];
4
+ export declare function inboundPathItemOperations(pathItem: JsonObject, path: string, pointer: string, source: 'callbacks', parentOperationRef: string): CallbackOperationSource[];
@@ -0,0 +1,31 @@
1
+ import { operationMetadata } from '../common/operation-metadata.js';
2
+ import { operationEntries } from '../common/operation-reference.js';
3
+ import { object } from '../common/parse-spec-utils.js';
4
+ function requiredCallbackParent(pointer, parentOperationRef) {
5
+ if (parentOperationRef === undefined)
6
+ throw new Error(`operationRef ${pointer} callback has no parent operation`);
7
+ return parentOperationRef;
8
+ }
9
+ export function inboundPathItemOperations(pathItem, path, pointer, source, parentOperationRef) {
10
+ return operationEntries(pathItem).map((entry) => {
11
+ const operationRef = pointer + '/' + entry.key;
12
+ const operation = object(entry.value, `operationRef ${operationRef}`);
13
+ const shared = {
14
+ operationRef,
15
+ ...operationMetadata(operation, `operationRef ${operationRef}`),
16
+ method: entry.method,
17
+ path,
18
+ };
19
+ const result = source === 'callbacks'
20
+ ? {
21
+ candidate: {
22
+ ...shared,
23
+ source,
24
+ parentOperationRef: requiredCallbackParent(pointer, parentOperationRef),
25
+ },
26
+ operation,
27
+ }
28
+ : { candidate: { ...shared, source }, operation };
29
+ return result;
30
+ });
31
+ }
@@ -0,0 +1,4 @@
1
+ import type { OpenApiDocument, ParsedDocument } from '../../types/openapi.js';
2
+ import type { InboundOperationCandidate, InboundOperationSource } from '../../types/inbound.js';
3
+ export declare function inboundOperationSourcesFromDocument(document: ParsedDocument): InboundOperationSource[];
4
+ export declare function inboundOperationsFromSpec(input: OpenApiDocument): Promise<InboundOperationCandidate[]>;
@@ -0,0 +1,13 @@
1
+ import { validateAndResolveOpenApiDocument } from '../common/validate-spec.js';
2
+ import { callbackOperationsFromDocument } from './callback/parse-callback-operations.js';
3
+ import { webhookOperationsFromDocument } from './webhook/parse-webhook-operations.js';
4
+ export function inboundOperationSourcesFromDocument(document) {
5
+ return [
6
+ ...webhookOperationsFromDocument(document),
7
+ ...callbackOperationsFromDocument(document),
8
+ ];
9
+ }
10
+ export async function inboundOperationsFromSpec(input) {
11
+ const document = await validateAndResolveOpenApiDocument(input);
12
+ return inboundOperationSourcesFromDocument(document).map((source) => source.candidate);
13
+ }
@@ -0,0 +1,3 @@
1
+ import type { ParsedDocument } from '../../../types/openapi.js';
2
+ import type { WebhookOperationSource } from '../../../types/inbound.js';
3
+ export declare function webhookOperationsFromDocument(document: ParsedDocument): WebhookOperationSource[];
@@ -0,0 +1,13 @@
1
+ import { pointerSegment } from '../../common/operation-reference.js';
2
+ import { dereferencedObject, object } from '../../common/parse-spec-utils.js';
3
+ import { inboundPathItemOperations } from '../inbound-path-item-operations.js';
4
+ export function webhookOperationsFromDocument(document) {
5
+ if (document.spec.webhooks === undefined)
6
+ return [];
7
+ const webhooks = object(document.spec.webhooks, 'spec.webhooks');
8
+ return Object.entries(webhooks).flatMap(([name, raw]) => {
9
+ const pointer = '#/webhooks/' + pointerSegment(name);
10
+ const pathItem = dereferencedObject(raw, `spec.webhooks[${name}]`);
11
+ return inboundPathItemOperations(pathItem, name, pointer, 'webhooks');
12
+ });
13
+ }
@@ -0,0 +1,2 @@
1
+ import type { CatalogSource, OperationCatalog } from '../../types/catalog.js';
2
+ export declare function createOperationCatalog(sources: CatalogSource[]): Promise<OperationCatalog>;
@@ -0,0 +1,24 @@
1
+ import { validateAndResolveOpenApiDocument } from '../common/validate-spec.js';
2
+ import { operationsFromDocument } from './parse-request-operations.js';
3
+ import { isObject } from '../../utils/is-object.js';
4
+ export async function createOperationCatalog(sources) {
5
+ if (!Array.isArray(sources) || sources.length === 0)
6
+ throw new Error('sources must be a non-empty array of OAS documents');
7
+ const catalog = { sources: new Map(), entries: [] };
8
+ for (const source of sources) {
9
+ if (!isObject(source) || typeof source.id !== 'string' || !source.id.trim())
10
+ throw new Error('sources[].id must be a non-empty string');
11
+ if (catalog.sources.has(source.id))
12
+ throw new Error(`sources has duplicate id ${source.id}`);
13
+ try {
14
+ const document = await validateAndResolveOpenApiDocument(source.spec);
15
+ const operations = operationsFromDocument(document);
16
+ catalog.sources.set(source.id, { ...source, document, operations });
17
+ catalog.entries.push(...operations.map((candidate) => ({ id: source.id, candidate })));
18
+ }
19
+ catch (error) {
20
+ throw new Error(`sources[${source.id}] is invalid`, { cause: error });
21
+ }
22
+ }
23
+ return catalog;
24
+ }
@@ -0,0 +1,2 @@
1
+ /** WHATWG form percent-encode set; works in restricted n8n Code VMs too. */
2
+ export declare function encodeFormField(value: string): string;
@@ -0,0 +1,6 @@
1
+ /** WHATWG form percent-encode set; works in restricted n8n Code VMs too. */
2
+ export function encodeFormField(value) {
3
+ return encodeURIComponent(value.toWellFormed())
4
+ .replace(/[!'()~]/g, (character) => '%' + character.charCodeAt(0).toString(16).toUpperCase())
5
+ .replaceAll('%20', '+');
6
+ }
@@ -0,0 +1,4 @@
1
+ import type { JsonObject, OperationMethod } from '../../types/openapi.js';
2
+ import type { Operation } from '../../types/request.js';
3
+ /** HTTP contracts only. Authentication is resolved separately by the engine adapter. */
4
+ export declare function mapHttpOperationContract(path: string, method: OperationMethod, operationRef: string, pathItem: JsonObject, raw: unknown): Operation;
@@ -0,0 +1,21 @@
1
+ import { operationMetadata } from '../common/operation-metadata.js';
2
+ import { object } from '../common/parse-spec-utils.js';
3
+ import { parseOperationResponses } from './parse-operation-responses.js';
4
+ import { parseRequestBody } from './parse-request-body.js';
5
+ import { parseRequestParameters } from './parse-request-parameters.js';
6
+ /** HTTP contracts only. Authentication is resolved separately by the engine adapter. */
7
+ export function mapHttpOperationContract(path, method, operationRef, pathItem, raw) {
8
+ const operation = object(raw, `spec.paths[${path}].${method.toLowerCase()}`);
9
+ if (!path.startsWith('/'))
10
+ throw new Error(`operationRef ${operationRef} path must start with /`);
11
+ return {
12
+ operationRef,
13
+ source: 'paths',
14
+ ...operationMetadata(operation, `operationRef ${operationRef}`),
15
+ method,
16
+ path,
17
+ parameters: parseRequestParameters(path, pathItem, operation, operationRef),
18
+ body: parseRequestBody(operation, operationRef),
19
+ responses: parseOperationResponses(operation, operationRef),
20
+ };
21
+ }
@@ -0,0 +1,3 @@
1
+ import type { JsonObject, OperationMethod } from '../../types/openapi.js';
2
+ import type { Operation } from '../../types/request.js';
3
+ export declare function mapOperationForWorkflow(spec: JsonObject, path: string, method: OperationMethod, operationRef: string, pathItem: JsonObject, raw: unknown): Operation;
@@ -0,0 +1,10 @@
1
+ import { object } from '../common/parse-spec-utils.js';
2
+ import { parseOperationSecurity } from './parse-security.js';
3
+ import { mapHttpOperationContract } from './map-http-operation-contract.js';
4
+ export function mapOperationForWorkflow(spec, path, method, operationRef, pathItem, raw) {
5
+ const operation = object(raw, `spec.paths[${path}].${method.toLowerCase()}`);
6
+ return {
7
+ ...mapHttpOperationContract(path, method, operationRef, pathItem, operation),
8
+ authentication: parseOperationSecurity(spec, operation, operationRef),
9
+ };
10
+ }
@@ -0,0 +1,3 @@
1
+ import type { JsonObject } from '../../types/openapi.js';
2
+ import type { OperationResponses } from '../../types/request.js';
3
+ export declare function parseOperationResponses(operation: JsonObject, operationRef: string): OperationResponses;
@@ -0,0 +1,30 @@
1
+ import { dereferencedObject, object } from '../common/parse-spec-utils.js';
2
+ export function parseOperationResponses(operation, operationRef) {
3
+ const responses = object(operation.responses, `operationRef ${operationRef}.responses`);
4
+ const parsedResponses = {};
5
+ for (const [responseCode, rawResponse] of Object.entries(responses)) {
6
+ const response = dereferencedObject(rawResponse, `operationRef ${operationRef}.responses.${responseCode}`);
7
+ const responseProperties = {};
8
+ if (response.content !== undefined) {
9
+ const content = object(response.content, `operationRef ${operationRef}.responses.${responseCode}.content`);
10
+ if (content['application/json'] !== undefined) {
11
+ const media = object(content['application/json'], `operationRef ${operationRef}.responses.${responseCode}.application/json`);
12
+ const responseSchema = media.schema === undefined || typeof media.schema === 'boolean'
13
+ ? undefined
14
+ : dereferencedObject(media.schema, `operationRef ${operationRef}.responses.${responseCode}.schema`);
15
+ if (responseSchema?.type === 'object' &&
16
+ responseSchema.properties !== undefined) {
17
+ const properties = object(responseSchema.properties, `operationRef ${operationRef}.responses.${responseCode}.schema.properties`);
18
+ for (const [name, property] of Object.entries(properties)) {
19
+ responseProperties[name] =
20
+ typeof property === 'boolean'
21
+ ? property
22
+ : dereferencedObject(property, `operationRef ${operationRef}.responses.${responseCode}.schema.properties.${name}`);
23
+ }
24
+ }
25
+ }
26
+ }
27
+ parsedResponses[responseCode] = responseProperties;
28
+ }
29
+ return parsedResponses;
30
+ }
@@ -0,0 +1,3 @@
1
+ import type { JsonObject } from '../../types/openapi.js';
2
+ import type { OperationBody } from '../../types/request.js';
3
+ export declare function parseRequestBody(operation: JsonObject, operationRef: string): OperationBody | undefined;
@@ -0,0 +1,29 @@
1
+ import { dereferencedObject, object } from '../common/parse-spec-utils.js';
2
+ export function parseRequestBody(operation, operationRef) {
3
+ if (operation.requestBody === undefined)
4
+ return undefined;
5
+ const requestBody = dereferencedObject(operation.requestBody, `operationRef ${operationRef}.requestBody`);
6
+ const content = object(requestBody.content, `operationRef ${operationRef}.requestBody.content`);
7
+ const mediaTypes = Object.create(null);
8
+ for (const [mediaType, value] of Object.entries(content)) {
9
+ const media = object(value, `operationRef ${operationRef}.requestBody.${mediaType}`);
10
+ const bodySchema = media.schema === undefined
11
+ ? undefined
12
+ : typeof media.schema === 'boolean'
13
+ ? media.schema
14
+ : dereferencedObject(media.schema, `operationRef ${operationRef}.requestBody.${mediaType}.schema`);
15
+ const properties = typeof bodySchema !== 'object' || bodySchema.properties === undefined
16
+ ? {}
17
+ : object(bodySchema.properties, `operationRef ${operationRef}.requestBody.${mediaType}.schema.properties`);
18
+ mediaTypes[mediaType] = {
19
+ schema: bodySchema,
20
+ properties,
21
+ ...(media.encoding === undefined
22
+ ? {}
23
+ : {
24
+ encoding: object(media.encoding, `operationRef ${operationRef}.requestBody.${mediaType}.encoding`),
25
+ }),
26
+ };
27
+ }
28
+ return { required: requestBody.required === true, mediaTypes };
29
+ }
@@ -0,0 +1,7 @@
1
+ import type { OpenApiDocument, OperationCandidate, ParsedDocument } from '../../types/openapi.js';
2
+ import type { Operation, OperationSource } from '../../types/request.js';
3
+ export declare function operationsFromDocument({ paths, }: ParsedDocument): OperationCandidate[];
4
+ export declare function operationsFromSpec(input: OpenApiDocument): Promise<OperationCandidate[]>;
5
+ export declare function operationFromSpec(input: OpenApiDocument, operationRef: string): Promise<Operation>;
6
+ export declare function selectedOperationSource(parsed: ParsedDocument, operationRef: string): OperationSource;
7
+ export declare function operationFromDocument(parsed: ParsedDocument, operationRef: string): Operation;
@@ -0,0 +1,50 @@
1
+ import { mapOperationForWorkflow } from './operation-mapping.js';
2
+ import { operationMetadata } from '../common/operation-metadata.js';
3
+ import { operationEntries } from '../common/operation-reference.js';
4
+ import { dereferencedObject, object } from '../common/parse-spec-utils.js';
5
+ import { validateAndResolveOpenApiDocument } from '../common/validate-spec.js';
6
+ import { requestOperationReference } from './request-operation-reference.js';
7
+ export function operationsFromDocument({ paths, }) {
8
+ const operations = [];
9
+ for (const [path, pathValue] of Object.entries(paths)) {
10
+ const pathItem = dereferencedObject(pathValue, `spec.paths[${path}]`);
11
+ for (const { method, key, value } of operationEntries(pathItem)) {
12
+ const operation = object(value, `spec.paths[${path}].${key}`);
13
+ operations.push({
14
+ operationRef: requestOperationReference(path, key),
15
+ source: 'paths',
16
+ ...operationMetadata(operation, `spec.paths[${path}].${key}`),
17
+ method,
18
+ path,
19
+ });
20
+ }
21
+ }
22
+ const ids = operations.flatMap(({ operationId }) => operationId === undefined ? [] : [operationId]);
23
+ if (new Set(ids).size !== ids.length)
24
+ throw new Error('spec.paths has duplicate operationId values');
25
+ return operations;
26
+ }
27
+ export async function operationsFromSpec(input) {
28
+ return operationsFromDocument(await validateAndResolveOpenApiDocument(input));
29
+ }
30
+ export async function operationFromSpec(input, operationRef) {
31
+ return operationFromDocument(await validateAndResolveOpenApiDocument(input), operationRef);
32
+ }
33
+ export function selectedOperationSource(parsed, operationRef) {
34
+ const candidates = operationsFromDocument(parsed);
35
+ const matches = candidates.filter((item) => item.operationRef === operationRef || item.operationId === operationRef);
36
+ if (matches.length > 1)
37
+ throw new Error('plan.operationRef identifies multiple operations: ' + operationRef);
38
+ const candidate = matches[0];
39
+ if (!candidate)
40
+ throw new Error('plan.operationRef is not in spec.paths: ' + operationRef);
41
+ const pathItem = dereferencedObject(parsed.paths[candidate.path], `spec.paths[${candidate.path}]`);
42
+ const operationEntry = operationEntries(pathItem).find(({ key }) => requestOperationReference(candidate.path, key) === candidate.operationRef);
43
+ if (!operationEntry)
44
+ throw new Error('spec.paths is missing operation: ' + candidate.operationRef);
45
+ return { candidate, pathItem, entry: operationEntry };
46
+ }
47
+ export function operationFromDocument(parsed, operationRef) {
48
+ const { candidate, pathItem, entry } = selectedOperationSource(parsed, operationRef);
49
+ return mapOperationForWorkflow(parsed.spec, candidate.path, candidate.method, candidate.operationRef, pathItem, entry.value);
50
+ }
@@ -0,0 +1,3 @@
1
+ import type { JsonObject } from '../../types/openapi.js';
2
+ import type { OperationParameter } from '../../types/request.js';
3
+ export declare function parseRequestParameters(path: string, pathItem: JsonObject, operation: JsonObject, operationRef: string): OperationParameter[];
@@ -0,0 +1,93 @@
1
+ import { dereferencedObject, object } from '../common/parse-spec-utils.js';
2
+ import { UnsupportedOperationError } from '../common/unsupported-operation-error.js';
3
+ function parseParameter(raw, operationRef, index) {
4
+ const parameter = dereferencedObject(raw, `operationRef ${operationRef} parameter ${index}`);
5
+ if (typeof parameter.name !== 'string' ||
6
+ !parameter.name ||
7
+ (parameter.in === 'path' && parameter.required !== true)) {
8
+ throw new Error(`operationRef ${operationRef} has an invalid parameter`);
9
+ }
10
+ if (!['path', 'query', 'header', 'cookie'].includes(String(parameter.in))) {
11
+ throw new UnsupportedOperationError(operationRef, `operationRef ${operationRef} has an unsupported parameter`);
12
+ }
13
+ if (parameter.in === 'header' &&
14
+ ['accept', 'content-type', 'authorization'].includes(parameter.name.toLowerCase())) {
15
+ return undefined;
16
+ }
17
+ let schema;
18
+ let contentMediaType;
19
+ if (parameter.content !== undefined) {
20
+ const content = object(parameter.content, `operationRef ${operationRef} parameter ${parameter.name}.content`);
21
+ const types = Object.keys(content);
22
+ if (types.length !== 1 || types[0] !== 'application/json')
23
+ throw new UnsupportedOperationError(operationRef, `operationRef ${operationRef} parameter ${parameter.name} content media type is not mapped`);
24
+ contentMediaType = types[0];
25
+ const media = dereferencedObject(content[contentMediaType], `operationRef ${operationRef} parameter ${parameter.name}.content.${contentMediaType}`);
26
+ schema =
27
+ media.schema === undefined
28
+ ? true
29
+ : typeof media.schema === 'boolean'
30
+ ? media.schema
31
+ : dereferencedObject(media.schema, `operationRef ${operationRef} parameter ${parameter.name}.content.${contentMediaType}.schema`);
32
+ }
33
+ else {
34
+ schema =
35
+ typeof parameter.schema === 'boolean'
36
+ ? parameter.schema
37
+ : dereferencedObject(parameter.schema, `operationRef ${operationRef} parameter ${parameter.name}.schema`);
38
+ }
39
+ const style = typeof parameter.style === 'string'
40
+ ? parameter.style
41
+ : parameter.in === 'path' || parameter.in === 'header'
42
+ ? 'simple'
43
+ : 'form';
44
+ const explode = typeof parameter.explode === 'boolean'
45
+ ? parameter.explode
46
+ : style === 'form' || style === 'cookie';
47
+ return {
48
+ name: parameter.name,
49
+ in: parameter.in,
50
+ required: parameter.required === true,
51
+ schema,
52
+ style,
53
+ explode,
54
+ allowReserved: parameter.allowReserved === true,
55
+ ...(contentMediaType === undefined ? {} : { contentMediaType }),
56
+ };
57
+ }
58
+ export function parseRequestParameters(path, pathItem, operation, operationRef) {
59
+ if ((pathItem.parameters !== undefined &&
60
+ !Array.isArray(pathItem.parameters)) ||
61
+ (operation.parameters !== undefined && !Array.isArray(operation.parameters))) {
62
+ throw new Error(`operationRef ${operationRef} parameters must be arrays`);
63
+ }
64
+ const pathParameters = Array.isArray(pathItem.parameters)
65
+ ? pathItem.parameters
66
+ : [];
67
+ const operationParameters = Array.isArray(operation.parameters)
68
+ ? operation.parameters
69
+ : [];
70
+ const parametersByName = new Map();
71
+ for (const rawParameters of [pathParameters, operationParameters]) {
72
+ const namesAtLevel = new Set();
73
+ for (const [index, rawParameter] of rawParameters.entries()) {
74
+ const parameter = parseParameter(rawParameter, operationRef, index);
75
+ if (parameter === undefined)
76
+ continue;
77
+ const name = `${parameter.in}.${parameter.name}`;
78
+ if (namesAtLevel.has(name))
79
+ throw new Error(`operationRef ${operationRef} has duplicate parameters`);
80
+ namesAtLevel.add(name);
81
+ parametersByName.set(name, parameter);
82
+ }
83
+ }
84
+ const parameters = [...parametersByName.values()];
85
+ for (const name of path
86
+ .match(/\{([^}]+)\}/g)
87
+ ?.map((token) => token.slice(1, -1)) ?? []) {
88
+ if (!parameters.some((parameter) => parameter.in === 'path' && parameter.name === name)) {
89
+ throw new Error(`operationRef ${operationRef} is missing path parameter ${name}`);
90
+ }
91
+ }
92
+ return parameters;
93
+ }
@@ -0,0 +1,3 @@
1
+ import type { JsonObject } from '../../types/openapi.js';
2
+ import type { OperationAuthentication } from '../../types/request.js';
3
+ export declare function parseOperationSecurity(spec: JsonObject, operation: JsonObject, operationRef: string): OperationAuthentication | undefined;