@synergenius/flow-weaver 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.
- package/LICENSE +122 -0
- package/README.md +315 -0
- package/dist/annotation-generator.d.ts +45 -0
- package/dist/annotation-generator.js +557 -0
- package/dist/api/builder.d.ts +223 -0
- package/dist/api/builder.js +345 -0
- package/dist/api/compile.d.ts +92 -0
- package/dist/api/compile.js +149 -0
- package/dist/api/extract-types.d.ts +29 -0
- package/dist/api/extract-types.js +57 -0
- package/dist/api/generate-in-place.d.ts +73 -0
- package/dist/api/generate-in-place.js +1353 -0
- package/dist/api/generate.d.ts +83 -0
- package/dist/api/generate.js +510 -0
- package/dist/api/helpers.d.ts +248 -0
- package/dist/api/helpers.js +285 -0
- package/dist/api/index.d.ts +46 -0
- package/dist/api/index.js +45 -0
- package/dist/api/inline-runtime.d.ts +27 -0
- package/dist/api/inline-runtime.js +551 -0
- package/dist/api/manipulation/connections.d.ts +79 -0
- package/dist/api/manipulation/connections.js +151 -0
- package/dist/api/manipulation/index.d.ts +34 -0
- package/dist/api/manipulation/index.js +41 -0
- package/dist/api/manipulation/node-types.d.ts +123 -0
- package/dist/api/manipulation/node-types.js +200 -0
- package/dist/api/manipulation/nodes.d.ts +144 -0
- package/dist/api/manipulation/nodes.js +333 -0
- package/dist/api/manipulation/ports.d.ts +59 -0
- package/dist/api/manipulation/ports.js +228 -0
- package/dist/api/manipulation/scopes.d.ts +52 -0
- package/dist/api/manipulation/scopes.js +156 -0
- package/dist/api/manipulation/validation.d.ts +6 -0
- package/dist/api/manipulation/validation.js +6 -0
- package/dist/api/manipulation/workflow.d.ts +81 -0
- package/dist/api/manipulation/workflow.js +116 -0
- package/dist/api/manipulation.d.ts +8 -0
- package/dist/api/manipulation.js +8 -0
- package/dist/api/parse.d.ts +48 -0
- package/dist/api/parse.js +110 -0
- package/dist/api/patterns.d.ts +112 -0
- package/dist/api/patterns.js +306 -0
- package/dist/api/query.d.ts +429 -0
- package/dist/api/query.js +816 -0
- package/dist/api/templates.d.ts +98 -0
- package/dist/api/templates.js +117 -0
- package/dist/api/transform.d.ts +31 -0
- package/dist/api/transform.js +40 -0
- package/dist/api/validate.d.ts +25 -0
- package/dist/api/validate.js +39 -0
- package/dist/api/workflow-file-operations.d.ts +29 -0
- package/dist/api/workflow-file-operations.js +180 -0
- package/dist/ast/builder.d.ts +210 -0
- package/dist/ast/builder.js +395 -0
- package/dist/ast/index.d.ts +5 -0
- package/dist/ast/index.js +5 -0
- package/dist/ast/serialization-node.d.ts +6 -0
- package/dist/ast/serialization-node.js +30 -0
- package/dist/ast/serialization.d.ts +43 -0
- package/dist/ast/serialization.js +134 -0
- package/dist/ast/types.d.ts +852 -0
- package/dist/ast/types.js +2 -0
- package/dist/ast/workflow-utils.d.ts +54 -0
- package/dist/ast/workflow-utils.js +114 -0
- package/dist/body-generator.d.ts +31 -0
- package/dist/body-generator.js +35 -0
- package/dist/built-in-nodes/delay.d.ts +11 -0
- package/dist/built-in-nodes/delay.js +29 -0
- package/dist/built-in-nodes/index.d.ts +5 -0
- package/dist/built-in-nodes/index.js +4 -0
- package/dist/built-in-nodes/invoke-workflow.d.ts +13 -0
- package/dist/built-in-nodes/invoke-workflow.js +25 -0
- package/dist/built-in-nodes/mock-types.d.ts +18 -0
- package/dist/built-in-nodes/mock-types.js +12 -0
- package/dist/built-in-nodes/wait-for-event.d.ts +13 -0
- package/dist/built-in-nodes/wait-for-event.js +25 -0
- package/dist/chevrotain-parser/connect-parser.d.ts +24 -0
- package/dist/chevrotain-parser/connect-parser.js +98 -0
- package/dist/chevrotain-parser/grammar-diagrams.d.ts +29 -0
- package/dist/chevrotain-parser/grammar-diagrams.js +264 -0
- package/dist/chevrotain-parser/index.d.ts +25 -0
- package/dist/chevrotain-parser/index.js +27 -0
- package/dist/chevrotain-parser/map-parser.d.ts +33 -0
- package/dist/chevrotain-parser/map-parser.js +130 -0
- package/dist/chevrotain-parser/node-parser.d.ts +36 -0
- package/dist/chevrotain-parser/node-parser.js +466 -0
- package/dist/chevrotain-parser/path-parser.d.ts +28 -0
- package/dist/chevrotain-parser/path-parser.js +118 -0
- package/dist/chevrotain-parser/port-parser.d.ts +36 -0
- package/dist/chevrotain-parser/port-parser.js +442 -0
- package/dist/chevrotain-parser/position-parser.d.ts +20 -0
- package/dist/chevrotain-parser/position-parser.js +83 -0
- package/dist/chevrotain-parser/scope-parser.d.ts +19 -0
- package/dist/chevrotain-parser/scope-parser.js +104 -0
- package/dist/chevrotain-parser/tokens.d.ts +78 -0
- package/dist/chevrotain-parser/tokens.js +384 -0
- package/dist/chevrotain-parser/trigger-cancel-parser.d.ts +50 -0
- package/dist/chevrotain-parser/trigger-cancel-parser.js +282 -0
- package/dist/cli/commands/changelog.d.ts +13 -0
- package/dist/cli/commands/changelog.js +135 -0
- package/dist/cli/commands/compile.d.ts +64 -0
- package/dist/cli/commands/compile.js +278 -0
- package/dist/cli/commands/create.d.ts +33 -0
- package/dist/cli/commands/create.js +147 -0
- package/dist/cli/commands/describe.d.ts +68 -0
- package/dist/cli/commands/describe.js +377 -0
- package/dist/cli/commands/dev.d.ts +32 -0
- package/dist/cli/commands/dev.js +384 -0
- package/dist/cli/commands/diagram.d.ts +13 -0
- package/dist/cli/commands/diagram.js +33 -0
- package/dist/cli/commands/diff.d.ts +11 -0
- package/dist/cli/commands/diff.js +59 -0
- package/dist/cli/commands/doctor.d.ts +57 -0
- package/dist/cli/commands/doctor.js +719 -0
- package/dist/cli/commands/export.d.ts +57 -0
- package/dist/cli/commands/export.js +163 -0
- package/dist/cli/commands/grammar.d.ts +9 -0
- package/dist/cli/commands/grammar.js +39 -0
- package/dist/cli/commands/init.d.ts +59 -0
- package/dist/cli/commands/init.js +435 -0
- package/dist/cli/commands/listen.d.ts +16 -0
- package/dist/cli/commands/listen.js +39 -0
- package/dist/cli/commands/market.d.ts +52 -0
- package/dist/cli/commands/market.js +436 -0
- package/dist/cli/commands/migrate.d.ts +13 -0
- package/dist/cli/commands/migrate.js +89 -0
- package/dist/cli/commands/openapi.d.ts +37 -0
- package/dist/cli/commands/openapi.js +67 -0
- package/dist/cli/commands/pattern.d.ts +34 -0
- package/dist/cli/commands/pattern.js +185 -0
- package/dist/cli/commands/plugin.d.ts +16 -0
- package/dist/cli/commands/plugin.js +176 -0
- package/dist/cli/commands/run.d.ts +49 -0
- package/dist/cli/commands/run.js +191 -0
- package/dist/cli/commands/serve.d.ts +45 -0
- package/dist/cli/commands/serve.js +81 -0
- package/dist/cli/commands/templates.d.ts +8 -0
- package/dist/cli/commands/templates.js +54 -0
- package/dist/cli/commands/ui.d.ts +16 -0
- package/dist/cli/commands/ui.js +130 -0
- package/dist/cli/commands/validate.d.ts +12 -0
- package/dist/cli/commands/validate.js +247 -0
- package/dist/cli/commands/watch.d.ts +9 -0
- package/dist/cli/commands/watch.js +70 -0
- package/dist/cli/flow-weaver.mjs +92924 -0
- package/dist/cli/index.d.ts +9 -0
- package/dist/cli/index.js +742 -0
- package/dist/cli/templates/ai/mock-provider.d.ts +7 -0
- package/dist/cli/templates/ai/mock-provider.js +64 -0
- package/dist/cli/templates/ai/types.d.ts +47 -0
- package/dist/cli/templates/ai/types.js +5 -0
- package/dist/cli/templates/approvals/index.d.ts +15 -0
- package/dist/cli/templates/approvals/index.js +241 -0
- package/dist/cli/templates/index.d.ts +102 -0
- package/dist/cli/templates/index.js +101 -0
- package/dist/cli/templates/nodes/agent-router.d.ts +3 -0
- package/dist/cli/templates/nodes/agent-router.js +114 -0
- package/dist/cli/templates/nodes/aggregator.d.ts +7 -0
- package/dist/cli/templates/nodes/aggregator.js +63 -0
- package/dist/cli/templates/nodes/conversation-memory.d.ts +3 -0
- package/dist/cli/templates/nodes/conversation-memory.js +85 -0
- package/dist/cli/templates/nodes/http.d.ts +7 -0
- package/dist/cli/templates/nodes/http.js +80 -0
- package/dist/cli/templates/nodes/human-approval.d.ts +3 -0
- package/dist/cli/templates/nodes/human-approval.js +110 -0
- package/dist/cli/templates/nodes/json-extractor.d.ts +3 -0
- package/dist/cli/templates/nodes/json-extractor.js +119 -0
- package/dist/cli/templates/nodes/llm-call.d.ts +3 -0
- package/dist/cli/templates/nodes/llm-call.js +106 -0
- package/dist/cli/templates/nodes/prompt-template.d.ts +3 -0
- package/dist/cli/templates/nodes/prompt-template.js +52 -0
- package/dist/cli/templates/nodes/rag-retriever.d.ts +3 -0
- package/dist/cli/templates/nodes/rag-retriever.js +128 -0
- package/dist/cli/templates/nodes/tool-executor.d.ts +3 -0
- package/dist/cli/templates/nodes/tool-executor.js +108 -0
- package/dist/cli/templates/nodes/transformer.d.ts +7 -0
- package/dist/cli/templates/nodes/transformer.js +68 -0
- package/dist/cli/templates/nodes/validator.d.ts +7 -0
- package/dist/cli/templates/nodes/validator.js +62 -0
- package/dist/cli/templates/providers/index.d.ts +14 -0
- package/dist/cli/templates/providers/index.js +239 -0
- package/dist/cli/templates/shared/approval-types.d.ts +9 -0
- package/dist/cli/templates/shared/approval-types.js +31 -0
- package/dist/cli/templates/shared/llm-types.d.ts +15 -0
- package/dist/cli/templates/shared/llm-types.js +104 -0
- package/dist/cli/templates/workflows/aggregator.d.ts +7 -0
- package/dist/cli/templates/workflows/aggregator.js +104 -0
- package/dist/cli/templates/workflows/ai-agent-durable.d.ts +8 -0
- package/dist/cli/templates/workflows/ai-agent-durable.js +338 -0
- package/dist/cli/templates/workflows/ai-agent.d.ts +31 -0
- package/dist/cli/templates/workflows/ai-agent.js +326 -0
- package/dist/cli/templates/workflows/ai-chat.d.ts +7 -0
- package/dist/cli/templates/workflows/ai-chat.js +169 -0
- package/dist/cli/templates/workflows/ai-pipeline-durable.d.ts +8 -0
- package/dist/cli/templates/workflows/ai-pipeline-durable.js +330 -0
- package/dist/cli/templates/workflows/ai-rag.d.ts +7 -0
- package/dist/cli/templates/workflows/ai-rag.js +186 -0
- package/dist/cli/templates/workflows/ai-react.d.ts +7 -0
- package/dist/cli/templates/workflows/ai-react.js +294 -0
- package/dist/cli/templates/workflows/conditional.d.ts +12 -0
- package/dist/cli/templates/workflows/conditional.js +142 -0
- package/dist/cli/templates/workflows/error-handler.d.ts +7 -0
- package/dist/cli/templates/workflows/error-handler.js +147 -0
- package/dist/cli/templates/workflows/foreach.d.ts +7 -0
- package/dist/cli/templates/workflows/foreach.js +143 -0
- package/dist/cli/templates/workflows/sequential.d.ts +7 -0
- package/dist/cli/templates/workflows/sequential.js +198 -0
- package/dist/cli/templates/workflows/webhook.d.ts +7 -0
- package/dist/cli/templates/workflows/webhook.js +161 -0
- package/dist/cli/utils/logger.d.ts +15 -0
- package/dist/cli/utils/logger.js +46 -0
- package/dist/constants.d.ts +100 -0
- package/dist/constants.js +125 -0
- package/dist/defaults.d.ts +3 -0
- package/dist/defaults.js +3 -0
- package/dist/deployment/config/defaults.d.ts +29 -0
- package/dist/deployment/config/defaults.js +98 -0
- package/dist/deployment/config/loader.d.ts +24 -0
- package/dist/deployment/config/loader.js +236 -0
- package/dist/deployment/config/types.d.ts +117 -0
- package/dist/deployment/config/types.js +5 -0
- package/dist/deployment/core/adapters.d.ts +90 -0
- package/dist/deployment/core/adapters.js +251 -0
- package/dist/deployment/core/executor.d.ts +62 -0
- package/dist/deployment/core/executor.js +197 -0
- package/dist/deployment/core/formatters.d.ts +57 -0
- package/dist/deployment/core/formatters.js +170 -0
- package/dist/deployment/index.d.ts +31 -0
- package/dist/deployment/index.js +48 -0
- package/dist/deployment/openapi/generator.d.ts +146 -0
- package/dist/deployment/openapi/generator.js +347 -0
- package/dist/deployment/openapi/schema-converter.d.ts +49 -0
- package/dist/deployment/openapi/schema-converter.js +192 -0
- package/dist/deployment/targets/base.d.ts +316 -0
- package/dist/deployment/targets/base.js +823 -0
- package/dist/deployment/targets/cloudflare.d.ts +23 -0
- package/dist/deployment/targets/cloudflare.js +1125 -0
- package/dist/deployment/targets/inngest.d.ts +38 -0
- package/dist/deployment/targets/inngest.js +926 -0
- package/dist/deployment/targets/lambda.d.ts +23 -0
- package/dist/deployment/targets/lambda.js +1289 -0
- package/dist/deployment/targets/vercel.d.ts +23 -0
- package/dist/deployment/targets/vercel.js +886 -0
- package/dist/deployment/types.d.ts +183 -0
- package/dist/deployment/types.js +8 -0
- package/dist/diagram/geometry.d.ts +26 -0
- package/dist/diagram/geometry.js +850 -0
- package/dist/diagram/index.d.ts +16 -0
- package/dist/diagram/index.js +42 -0
- package/dist/diagram/layout.d.ts +11 -0
- package/dist/diagram/layout.js +143 -0
- package/dist/diagram/orthogonal-router.d.ts +79 -0
- package/dist/diagram/orthogonal-router.js +568 -0
- package/dist/diagram/renderer.d.ts +3 -0
- package/dist/diagram/renderer.js +207 -0
- package/dist/diagram/theme.d.ts +20 -0
- package/dist/diagram/theme.js +189 -0
- package/dist/diagram/types.d.ts +70 -0
- package/dist/diagram/types.js +2 -0
- package/dist/diff/WorkflowDiffer.d.ts +13 -0
- package/dist/diff/WorkflowDiffer.js +429 -0
- package/dist/diff/formatDiff.d.ts +10 -0
- package/dist/diff/formatDiff.js +220 -0
- package/dist/diff/impact.d.ts +29 -0
- package/dist/diff/impact.js +119 -0
- package/dist/diff/index.d.ts +10 -0
- package/dist/diff/index.js +9 -0
- package/dist/diff/types.d.ts +138 -0
- package/dist/diff/types.js +35 -0
- package/dist/doc-metadata/extractors/annotations.d.ts +56 -0
- package/dist/doc-metadata/extractors/annotations.js +337 -0
- package/dist/doc-metadata/extractors/cli-commands.d.ts +17 -0
- package/dist/doc-metadata/extractors/cli-commands.js +355 -0
- package/dist/doc-metadata/extractors/mcp-tools.d.ts +16 -0
- package/dist/doc-metadata/extractors/mcp-tools.js +689 -0
- package/dist/doc-metadata/extractors/plugin-api.d.ts +19 -0
- package/dist/doc-metadata/extractors/plugin-api.js +279 -0
- package/dist/doc-metadata/index.d.ts +5 -0
- package/dist/doc-metadata/index.js +4 -0
- package/dist/doc-metadata/types.d.ts +120 -0
- package/dist/doc-metadata/types.js +5 -0
- package/dist/editor-completions/annotationValues.d.ts +12 -0
- package/dist/editor-completions/annotationValues.js +138 -0
- package/dist/editor-completions/contextParser.d.ts +40 -0
- package/dist/editor-completions/contextParser.js +410 -0
- package/dist/editor-completions/dataTypes.d.ts +16 -0
- package/dist/editor-completions/dataTypes.js +95 -0
- package/dist/editor-completions/goToDefinition.d.ts +27 -0
- package/dist/editor-completions/goToDefinition.js +112 -0
- package/dist/editor-completions/index.d.ts +39 -0
- package/dist/editor-completions/index.js +181 -0
- package/dist/editor-completions/jsDocAnnotations.d.ts +29 -0
- package/dist/editor-completions/jsDocAnnotations.js +357 -0
- package/dist/editor-completions/modifierCompletions.d.ts +17 -0
- package/dist/editor-completions/modifierCompletions.js +197 -0
- package/dist/editor-completions/types.d.ts +119 -0
- package/dist/editor-completions/types.js +8 -0
- package/dist/export/index.d.ts +68 -0
- package/dist/export/index.js +1074 -0
- package/dist/export/templates.d.ts +24 -0
- package/dist/export/templates.js +186 -0
- package/dist/friendly-errors.d.ts +35 -0
- package/dist/friendly-errors.js +375 -0
- package/dist/function-like.d.ts +38 -0
- package/dist/function-like.js +83 -0
- package/dist/generated-branding.d.ts +16 -0
- package/dist/generated-branding.js +22 -0
- package/dist/generator/async-detection.d.ts +27 -0
- package/dist/generator/async-detection.js +56 -0
- package/dist/generator/code-utils.d.ts +76 -0
- package/dist/generator/code-utils.js +410 -0
- package/dist/generator/control-flow.d.ts +54 -0
- package/dist/generator/control-flow.js +284 -0
- package/dist/generator/inngest.d.ts +53 -0
- package/dist/generator/inngest.js +1126 -0
- package/dist/generator/scope-function-generator.d.ts +78 -0
- package/dist/generator/scope-function-generator.js +360 -0
- package/dist/generator/unified.d.ts +42 -0
- package/dist/generator/unified.js +1504 -0
- package/dist/generator.d.ts +54 -0
- package/dist/generator.js +100 -0
- package/dist/index.d.ts +85 -0
- package/dist/index.js +89 -0
- package/dist/jsdoc-parser.d.ts +308 -0
- package/dist/jsdoc-parser.js +923 -0
- package/dist/jsdoc-port-sync/constants.d.ts +41 -0
- package/dist/jsdoc-port-sync/constants.js +103 -0
- package/dist/jsdoc-port-sync/diff.d.ts +76 -0
- package/dist/jsdoc-port-sync/diff.js +319 -0
- package/dist/jsdoc-port-sync/index.d.ts +42 -0
- package/dist/jsdoc-port-sync/index.js +45 -0
- package/dist/jsdoc-port-sync/port-parser.d.ts +68 -0
- package/dist/jsdoc-port-sync/port-parser.js +579 -0
- package/dist/jsdoc-port-sync/rename.d.ts +21 -0
- package/dist/jsdoc-port-sync/rename.js +256 -0
- package/dist/jsdoc-port-sync/signature-parser.d.ts +104 -0
- package/dist/jsdoc-port-sync/signature-parser.js +559 -0
- package/dist/jsdoc-port-sync/sync.d.ts +36 -0
- package/dist/jsdoc-port-sync/sync.js +644 -0
- package/dist/jsdoc-port-sync.d.ts +10 -0
- package/dist/jsdoc-port-sync.js +10 -0
- package/dist/marketplace/index.d.ts +11 -0
- package/dist/marketplace/index.js +10 -0
- package/dist/marketplace/manifest.d.ts +32 -0
- package/dist/marketplace/manifest.js +176 -0
- package/dist/marketplace/registry.d.ts +30 -0
- package/dist/marketplace/registry.js +100 -0
- package/dist/marketplace/types.d.ts +154 -0
- package/dist/marketplace/types.js +9 -0
- package/dist/marketplace/validator.d.ts +13 -0
- package/dist/marketplace/validator.js +131 -0
- package/dist/mcp/auto-registration.d.ts +3 -0
- package/dist/mcp/auto-registration.js +62 -0
- package/dist/mcp/editor-connection.d.ts +50 -0
- package/dist/mcp/editor-connection.js +125 -0
- package/dist/mcp/event-buffer.d.ts +62 -0
- package/dist/mcp/event-buffer.js +150 -0
- package/dist/mcp/index.d.ts +12 -0
- package/dist/mcp/index.js +11 -0
- package/dist/mcp/resources.d.ts +14 -0
- package/dist/mcp/resources.js +55 -0
- package/dist/mcp/response-utils.d.ts +63 -0
- package/dist/mcp/response-utils.js +89 -0
- package/dist/mcp/server.d.ts +4 -0
- package/dist/mcp/server.js +99 -0
- package/dist/mcp/tools-diagram.d.ts +8 -0
- package/dist/mcp/tools-diagram.js +53 -0
- package/dist/mcp/tools-editor.d.ts +5 -0
- package/dist/mcp/tools-editor.js +190 -0
- package/dist/mcp/tools-export.d.ts +9 -0
- package/dist/mcp/tools-export.js +180 -0
- package/dist/mcp/tools-marketplace.d.ts +9 -0
- package/dist/mcp/tools-marketplace.js +132 -0
- package/dist/mcp/tools-pattern.d.ts +3 -0
- package/dist/mcp/tools-pattern.js +783 -0
- package/dist/mcp/tools-query.d.ts +3 -0
- package/dist/mcp/tools-query.js +364 -0
- package/dist/mcp/tools-template.d.ts +10 -0
- package/dist/mcp/tools-template.js +119 -0
- package/dist/mcp/types.d.ts +70 -0
- package/dist/mcp/types.js +8 -0
- package/dist/mcp/workflow-executor.d.ts +47 -0
- package/dist/mcp/workflow-executor.js +133 -0
- package/dist/migration/registry.d.ts +30 -0
- package/dist/migration/registry.js +29 -0
- package/dist/node-types-generator.d.ts +49 -0
- package/dist/node-types-generator.js +139 -0
- package/dist/npm-packages.d.ts +56 -0
- package/dist/npm-packages.js +255 -0
- package/dist/parser.d.ts +204 -0
- package/dist/parser.js +2100 -0
- package/dist/plugin/PluginPanel.d.ts +12 -0
- package/dist/plugin/PluginPanel.js +5 -0
- package/dist/plugin/index.d.ts +13 -0
- package/dist/plugin/index.js +14 -0
- package/dist/plugin/types.d.ts +75 -0
- package/dist/plugin/types.js +8 -0
- package/dist/resolve-package-types.d.ts +17 -0
- package/dist/resolve-package-types.js +123 -0
- package/dist/runtime/CancellationError.d.ts +11 -0
- package/dist/runtime/CancellationError.js +20 -0
- package/dist/runtime/ExecutionContext.d.ts +146 -0
- package/dist/runtime/ExecutionContext.js +235 -0
- package/dist/runtime/builtin-functions.d.ts +8 -0
- package/dist/runtime/builtin-functions.js +549 -0
- package/dist/runtime/events.d.ts +50 -0
- package/dist/runtime/events.js +2 -0
- package/dist/runtime/function-registry.d.ts +59 -0
- package/dist/runtime/function-registry.js +66 -0
- package/dist/runtime/index.d.ts +7 -0
- package/dist/runtime/index.js +7 -0
- package/dist/runtime/parameter-resolver.d.ts +62 -0
- package/dist/runtime/parameter-resolver.js +113 -0
- package/dist/server/index.d.ts +7 -0
- package/dist/server/index.js +6 -0
- package/dist/server/types.d.ts +93 -0
- package/dist/server/types.js +5 -0
- package/dist/server/webhook-server.d.ts +50 -0
- package/dist/server/webhook-server.js +269 -0
- package/dist/server/workflow-registry.d.ts +61 -0
- package/dist/server/workflow-registry.js +202 -0
- package/dist/shared-project.d.ts +9 -0
- package/dist/shared-project.js +28 -0
- package/dist/sugar-optimizer.d.ts +40 -0
- package/dist/sugar-optimizer.js +387 -0
- package/dist/testing/assertions.d.ts +51 -0
- package/dist/testing/assertions.js +127 -0
- package/dist/testing/index.d.ts +30 -0
- package/dist/testing/index.js +24 -0
- package/dist/testing/mock-approval.d.ts +81 -0
- package/dist/testing/mock-approval.js +98 -0
- package/dist/testing/mock-llm.d.ts +124 -0
- package/dist/testing/mock-llm.js +119 -0
- package/dist/testing/recorder.d.ts +72 -0
- package/dist/testing/recorder.js +70 -0
- package/dist/testing/replayer.d.ts +56 -0
- package/dist/testing/replayer.js +143 -0
- package/dist/testing/token-tracker.d.ts +71 -0
- package/dist/testing/token-tracker.js +94 -0
- package/dist/type-checker.d.ts +42 -0
- package/dist/type-checker.js +190 -0
- package/dist/type-mappings.d.ts +29 -0
- package/dist/type-mappings.js +125 -0
- package/dist/types/branded-ports.d.ts +151 -0
- package/dist/types/branded-ports.js +121 -0
- package/dist/types/index.d.ts +5 -0
- package/dist/types/index.js +5 -0
- package/dist/types.d.ts +139 -0
- package/dist/types.js +15 -0
- package/dist/utils/error-utils.d.ts +15 -0
- package/dist/utils/error-utils.js +27 -0
- package/dist/utils/lru-cache.d.ts +15 -0
- package/dist/utils/lru-cache.js +40 -0
- package/dist/utils/port-ordering.d.ts +26 -0
- package/dist/utils/port-ordering.js +88 -0
- package/dist/utils/port-tag-utils.d.ts +23 -0
- package/dist/utils/port-tag-utils.js +41 -0
- package/dist/utils/string-distance.d.ts +14 -0
- package/dist/utils/string-distance.js +56 -0
- package/dist/validation/agent-detection.d.ts +33 -0
- package/dist/validation/agent-detection.js +115 -0
- package/dist/validation/agent-rules.d.ts +48 -0
- package/dist/validation/agent-rules.js +262 -0
- package/dist/validator.d.ts +92 -0
- package/dist/validator.js +970 -0
- package/package.json +109 -0
|
@@ -0,0 +1,1289 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* AWS Lambda export target
|
|
3
|
+
*
|
|
4
|
+
* Generates deployment-ready AWS Lambda functions with SAM templates.
|
|
5
|
+
*/
|
|
6
|
+
import { BaseExportTarget, } from './base.js';
|
|
7
|
+
import { getGeneratedBranding } from '../../generated-branding.js';
|
|
8
|
+
import { generateStandaloneRuntimeModule } from '../../api/inline-runtime.js';
|
|
9
|
+
/**
|
|
10
|
+
* Handler template for AWS Lambda (API Gateway v2) - Basic version without docs
|
|
11
|
+
*/
|
|
12
|
+
const LAMBDA_HANDLER_TEMPLATE = `{{GENERATED_HEADER}}
|
|
13
|
+
import type { APIGatewayProxyEventV2, APIGatewayProxyResultV2, Context } from 'aws-lambda';
|
|
14
|
+
{{WORKFLOW_IMPORT}}
|
|
15
|
+
|
|
16
|
+
export const handler = async (
|
|
17
|
+
event: APIGatewayProxyEventV2,
|
|
18
|
+
context: Context
|
|
19
|
+
): Promise<APIGatewayProxyResultV2> => {
|
|
20
|
+
context.callbackWaitsForEmptyEventLoop = false;
|
|
21
|
+
|
|
22
|
+
try {
|
|
23
|
+
const body = typeof event.body === 'string'
|
|
24
|
+
? JSON.parse(event.body || '{}')
|
|
25
|
+
: event.body || {};
|
|
26
|
+
|
|
27
|
+
const startTime = Date.now();
|
|
28
|
+
const result = await {{FUNCTION_NAME}}(true, body);
|
|
29
|
+
|
|
30
|
+
return {
|
|
31
|
+
statusCode: 200,
|
|
32
|
+
headers: {
|
|
33
|
+
'Content-Type': 'application/json',
|
|
34
|
+
'X-Execution-Time': \`\${Date.now() - startTime}ms\`,
|
|
35
|
+
'X-Request-Id': context.awsRequestId,
|
|
36
|
+
},
|
|
37
|
+
body: JSON.stringify({
|
|
38
|
+
success: true,
|
|
39
|
+
result,
|
|
40
|
+
executionTime: Date.now() - startTime,
|
|
41
|
+
requestId: context.awsRequestId,
|
|
42
|
+
}),
|
|
43
|
+
};
|
|
44
|
+
} catch (error) {
|
|
45
|
+
return {
|
|
46
|
+
statusCode: 500,
|
|
47
|
+
headers: { 'Content-Type': 'application/json' },
|
|
48
|
+
body: JSON.stringify({
|
|
49
|
+
success: false,
|
|
50
|
+
error: error instanceof Error ? error.message : String(error),
|
|
51
|
+
requestId: context.awsRequestId,
|
|
52
|
+
}),
|
|
53
|
+
};
|
|
54
|
+
}
|
|
55
|
+
};
|
|
56
|
+
`;
|
|
57
|
+
/**
|
|
58
|
+
* Handler template for AWS Lambda with API documentation routes
|
|
59
|
+
*/
|
|
60
|
+
const LAMBDA_HANDLER_WITH_DOCS_TEMPLATE = `{{GENERATED_HEADER}}
|
|
61
|
+
import type { APIGatewayProxyEventV2, APIGatewayProxyResultV2, Context } from 'aws-lambda';
|
|
62
|
+
{{WORKFLOW_IMPORT}}
|
|
63
|
+
import { openApiSpec } from './openapi.js';
|
|
64
|
+
|
|
65
|
+
const SWAGGER_UI_HTML = \`<!DOCTYPE html>
|
|
66
|
+
<html lang="en">
|
|
67
|
+
<head>
|
|
68
|
+
<meta charset="UTF-8">
|
|
69
|
+
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
70
|
+
<title>{{WORKFLOW_NAME}} API Documentation</title>
|
|
71
|
+
<link rel="stylesheet" href="https://unpkg.com/swagger-ui-dist@5/swagger-ui.css">
|
|
72
|
+
</head>
|
|
73
|
+
<body>
|
|
74
|
+
<div id="swagger-ui"></div>
|
|
75
|
+
<script src="https://unpkg.com/swagger-ui-dist@5/swagger-ui-bundle.js"></script>
|
|
76
|
+
<script>
|
|
77
|
+
SwaggerUIBundle({
|
|
78
|
+
url: './openapi.json',
|
|
79
|
+
dom_id: '#swagger-ui',
|
|
80
|
+
presets: [SwaggerUIBundle.presets.apis, SwaggerUIBundle.SwaggerUIStandalonePreset],
|
|
81
|
+
layout: 'BaseLayout'
|
|
82
|
+
});
|
|
83
|
+
</script>
|
|
84
|
+
</body>
|
|
85
|
+
</html>\`;
|
|
86
|
+
|
|
87
|
+
export const handler = async (
|
|
88
|
+
event: APIGatewayProxyEventV2,
|
|
89
|
+
context: Context
|
|
90
|
+
): Promise<APIGatewayProxyResultV2> => {
|
|
91
|
+
context.callbackWaitsForEmptyEventLoop = false;
|
|
92
|
+
const path = event.rawPath || event.requestContext?.http?.path || '/';
|
|
93
|
+
const method = event.requestContext?.http?.method || 'GET';
|
|
94
|
+
|
|
95
|
+
// Serve OpenAPI spec
|
|
96
|
+
if (path === '/openapi.json' && method === 'GET') {
|
|
97
|
+
return {
|
|
98
|
+
statusCode: 200,
|
|
99
|
+
headers: { 'Content-Type': 'application/json' },
|
|
100
|
+
body: JSON.stringify(openApiSpec),
|
|
101
|
+
};
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
// Serve Swagger UI
|
|
105
|
+
if (path === '/docs' && method === 'GET') {
|
|
106
|
+
return {
|
|
107
|
+
statusCode: 200,
|
|
108
|
+
headers: { 'Content-Type': 'text/html' },
|
|
109
|
+
body: SWAGGER_UI_HTML,
|
|
110
|
+
};
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
// Execute workflow
|
|
114
|
+
if (method !== 'POST') {
|
|
115
|
+
return {
|
|
116
|
+
statusCode: 405,
|
|
117
|
+
headers: { 'Content-Type': 'application/json' },
|
|
118
|
+
body: JSON.stringify({ error: 'Method not allowed' }),
|
|
119
|
+
};
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
try {
|
|
123
|
+
const body = typeof event.body === 'string'
|
|
124
|
+
? JSON.parse(event.body || '{}')
|
|
125
|
+
: event.body || {};
|
|
126
|
+
|
|
127
|
+
const startTime = Date.now();
|
|
128
|
+
const result = await {{FUNCTION_NAME}}(true, body);
|
|
129
|
+
|
|
130
|
+
return {
|
|
131
|
+
statusCode: 200,
|
|
132
|
+
headers: {
|
|
133
|
+
'Content-Type': 'application/json',
|
|
134
|
+
'X-Execution-Time': \`\${Date.now() - startTime}ms\`,
|
|
135
|
+
'X-Request-Id': context.awsRequestId,
|
|
136
|
+
},
|
|
137
|
+
body: JSON.stringify({
|
|
138
|
+
success: true,
|
|
139
|
+
result,
|
|
140
|
+
executionTime: Date.now() - startTime,
|
|
141
|
+
requestId: context.awsRequestId,
|
|
142
|
+
}),
|
|
143
|
+
};
|
|
144
|
+
} catch (error) {
|
|
145
|
+
return {
|
|
146
|
+
statusCode: 500,
|
|
147
|
+
headers: { 'Content-Type': 'application/json' },
|
|
148
|
+
body: JSON.stringify({
|
|
149
|
+
success: false,
|
|
150
|
+
error: error instanceof Error ? error.message : String(error),
|
|
151
|
+
requestId: context.awsRequestId,
|
|
152
|
+
}),
|
|
153
|
+
};
|
|
154
|
+
}
|
|
155
|
+
};
|
|
156
|
+
`;
|
|
157
|
+
/**
|
|
158
|
+
* OpenAPI spec file template
|
|
159
|
+
*/
|
|
160
|
+
const OPENAPI_SPEC_TEMPLATE = `// Generated OpenAPI specification
|
|
161
|
+
export const openApiSpec = {{OPENAPI_SPEC}};
|
|
162
|
+
`;
|
|
163
|
+
/**
|
|
164
|
+
* SAM template - Basic version
|
|
165
|
+
*/
|
|
166
|
+
const SAM_TEMPLATE = `AWSTemplateFormatVersion: '2010-09-09'
|
|
167
|
+
Transform: AWS::Serverless-2016-10-31
|
|
168
|
+
Description: Flow Weaver workflow - {{WORKFLOW_NAME}}
|
|
169
|
+
|
|
170
|
+
Globals:
|
|
171
|
+
Function:
|
|
172
|
+
Timeout: 30
|
|
173
|
+
Runtime: nodejs20.x
|
|
174
|
+
MemorySize: 256
|
|
175
|
+
|
|
176
|
+
Resources:
|
|
177
|
+
WorkflowFunction:
|
|
178
|
+
Type: AWS::Serverless::Function
|
|
179
|
+
Properties:
|
|
180
|
+
Handler: handler.handler
|
|
181
|
+
CodeUri: .
|
|
182
|
+
Description: {{WORKFLOW_DESCRIPTION}}
|
|
183
|
+
Events:
|
|
184
|
+
ApiEvent:
|
|
185
|
+
Type: HttpApi
|
|
186
|
+
Properties:
|
|
187
|
+
Path: /{{WORKFLOW_PATH}}
|
|
188
|
+
Method: POST
|
|
189
|
+
|
|
190
|
+
Outputs:
|
|
191
|
+
ApiEndpoint:
|
|
192
|
+
Description: API endpoint URL
|
|
193
|
+
Value: !Sub "https://\${ServerlessHttpApi}.execute-api.\${AWS::Region}.amazonaws.com/{{WORKFLOW_PATH}}"
|
|
194
|
+
`;
|
|
195
|
+
/**
|
|
196
|
+
* SAM template with docs routes
|
|
197
|
+
*/
|
|
198
|
+
const SAM_TEMPLATE_WITH_DOCS = `AWSTemplateFormatVersion: '2010-09-09'
|
|
199
|
+
Transform: AWS::Serverless-2016-10-31
|
|
200
|
+
Description: Flow Weaver workflow - {{WORKFLOW_NAME}}
|
|
201
|
+
|
|
202
|
+
Globals:
|
|
203
|
+
Function:
|
|
204
|
+
Timeout: 30
|
|
205
|
+
Runtime: nodejs20.x
|
|
206
|
+
MemorySize: 256
|
|
207
|
+
|
|
208
|
+
Resources:
|
|
209
|
+
WorkflowFunction:
|
|
210
|
+
Type: AWS::Serverless::Function
|
|
211
|
+
Properties:
|
|
212
|
+
Handler: handler.handler
|
|
213
|
+
CodeUri: .
|
|
214
|
+
Description: {{WORKFLOW_DESCRIPTION}}
|
|
215
|
+
Events:
|
|
216
|
+
ApiEvent:
|
|
217
|
+
Type: HttpApi
|
|
218
|
+
Properties:
|
|
219
|
+
Path: /{{WORKFLOW_PATH}}
|
|
220
|
+
Method: POST
|
|
221
|
+
DocsEvent:
|
|
222
|
+
Type: HttpApi
|
|
223
|
+
Properties:
|
|
224
|
+
Path: /docs
|
|
225
|
+
Method: GET
|
|
226
|
+
OpenApiEvent:
|
|
227
|
+
Type: HttpApi
|
|
228
|
+
Properties:
|
|
229
|
+
Path: /openapi.json
|
|
230
|
+
Method: GET
|
|
231
|
+
|
|
232
|
+
Outputs:
|
|
233
|
+
ApiEndpoint:
|
|
234
|
+
Description: API endpoint URL
|
|
235
|
+
Value: !Sub "https://\${ServerlessHttpApi}.execute-api.\${AWS::Region}.amazonaws.com/{{WORKFLOW_PATH}}"
|
|
236
|
+
DocsEndpoint:
|
|
237
|
+
Description: API documentation URL
|
|
238
|
+
Value: !Sub "https://\${ServerlessHttpApi}.execute-api.\${AWS::Region}.amazonaws.com/docs"
|
|
239
|
+
`;
|
|
240
|
+
/**
|
|
241
|
+
* Multi-workflow handler template for AWS Lambda
|
|
242
|
+
*/
|
|
243
|
+
const LAMBDA_MULTI_HANDLER_TEMPLATE = `{{GENERATED_HEADER}}
|
|
244
|
+
import type { APIGatewayProxyEventV2, APIGatewayProxyResultV2, Context } from 'aws-lambda';
|
|
245
|
+
{{WORKFLOW_IMPORTS}}
|
|
246
|
+
import { functionRegistry } from './runtime/function-registry.js';
|
|
247
|
+
import './runtime/builtin-functions.js';
|
|
248
|
+
import { openApiSpec } from './openapi.js';
|
|
249
|
+
|
|
250
|
+
// Handler type for workflow functions
|
|
251
|
+
type WorkflowHandler = (execute: boolean, params: Record<string, unknown>) => unknown;
|
|
252
|
+
|
|
253
|
+
// Workflow router
|
|
254
|
+
const workflows: Record<string, WorkflowHandler> = {
|
|
255
|
+
{{WORKFLOW_ENTRIES}}
|
|
256
|
+
};
|
|
257
|
+
|
|
258
|
+
const SWAGGER_UI_HTML = \`<!DOCTYPE html>
|
|
259
|
+
<html lang="en">
|
|
260
|
+
<head>
|
|
261
|
+
<meta charset="UTF-8">
|
|
262
|
+
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
263
|
+
<title>{{SERVICE_NAME}} API Documentation</title>
|
|
264
|
+
<link rel="stylesheet" href="https://unpkg.com/swagger-ui-dist@5/swagger-ui.css">
|
|
265
|
+
</head>
|
|
266
|
+
<body>
|
|
267
|
+
<div id="swagger-ui"></div>
|
|
268
|
+
<script src="https://unpkg.com/swagger-ui-dist@5/swagger-ui-bundle.js"></script>
|
|
269
|
+
<script>
|
|
270
|
+
SwaggerUIBundle({
|
|
271
|
+
url: './openapi.json',
|
|
272
|
+
dom_id: '#swagger-ui',
|
|
273
|
+
presets: [SwaggerUIBundle.presets.apis, SwaggerUIBundle.SwaggerUIStandalonePreset],
|
|
274
|
+
layout: 'BaseLayout'
|
|
275
|
+
});
|
|
276
|
+
</script>
|
|
277
|
+
</body>
|
|
278
|
+
</html>\`;
|
|
279
|
+
|
|
280
|
+
export const handler = async (
|
|
281
|
+
event: APIGatewayProxyEventV2,
|
|
282
|
+
context: Context
|
|
283
|
+
): Promise<APIGatewayProxyResultV2> => {
|
|
284
|
+
context.callbackWaitsForEmptyEventLoop = false;
|
|
285
|
+
const path = event.rawPath || event.requestContext?.http?.path || '/';
|
|
286
|
+
const method = event.requestContext?.http?.method || 'GET';
|
|
287
|
+
|
|
288
|
+
// Serve OpenAPI spec
|
|
289
|
+
if (path === '/api/openapi.json' && method === 'GET') {
|
|
290
|
+
return {
|
|
291
|
+
statusCode: 200,
|
|
292
|
+
headers: { 'Content-Type': 'application/json' },
|
|
293
|
+
body: JSON.stringify(openApiSpec),
|
|
294
|
+
};
|
|
295
|
+
}
|
|
296
|
+
|
|
297
|
+
// Serve Swagger UI
|
|
298
|
+
if (path === '/api/docs' && method === 'GET') {
|
|
299
|
+
return {
|
|
300
|
+
statusCode: 200,
|
|
301
|
+
headers: { 'Content-Type': 'text/html' },
|
|
302
|
+
body: SWAGGER_UI_HTML,
|
|
303
|
+
};
|
|
304
|
+
}
|
|
305
|
+
|
|
306
|
+
// List available functions
|
|
307
|
+
if (path === '/api/functions' && method === 'GET') {
|
|
308
|
+
const category = event.queryStringParameters?.category;
|
|
309
|
+
const functions = functionRegistry.list(category as any);
|
|
310
|
+
return {
|
|
311
|
+
statusCode: 200,
|
|
312
|
+
headers: { 'Content-Type': 'application/json' },
|
|
313
|
+
body: JSON.stringify(functions),
|
|
314
|
+
};
|
|
315
|
+
}
|
|
316
|
+
|
|
317
|
+
// Route to workflow
|
|
318
|
+
const workflowMatch = path.match(/^\\/api\\/([^\\/]+)$/);
|
|
319
|
+
if (!workflowMatch) {
|
|
320
|
+
return {
|
|
321
|
+
statusCode: 404,
|
|
322
|
+
headers: { 'Content-Type': 'application/json' },
|
|
323
|
+
body: JSON.stringify({ error: 'Not found' }),
|
|
324
|
+
};
|
|
325
|
+
}
|
|
326
|
+
|
|
327
|
+
const workflowName = workflowMatch[1];
|
|
328
|
+
const workflow = workflows[workflowName];
|
|
329
|
+
|
|
330
|
+
if (!workflow) {
|
|
331
|
+
return {
|
|
332
|
+
statusCode: 404,
|
|
333
|
+
headers: { 'Content-Type': 'application/json' },
|
|
334
|
+
body: JSON.stringify({
|
|
335
|
+
error: \`Workflow '\${workflowName}' not found\`,
|
|
336
|
+
availableWorkflows: Object.keys(workflows),
|
|
337
|
+
}),
|
|
338
|
+
};
|
|
339
|
+
}
|
|
340
|
+
|
|
341
|
+
if (method !== 'POST') {
|
|
342
|
+
return {
|
|
343
|
+
statusCode: 405,
|
|
344
|
+
headers: { 'Content-Type': 'application/json' },
|
|
345
|
+
body: JSON.stringify({ error: 'Method not allowed. Use POST to execute workflows.' }),
|
|
346
|
+
};
|
|
347
|
+
}
|
|
348
|
+
|
|
349
|
+
try {
|
|
350
|
+
const body = typeof event.body === 'string'
|
|
351
|
+
? JSON.parse(event.body || '{}')
|
|
352
|
+
: event.body || {};
|
|
353
|
+
|
|
354
|
+
const startTime = Date.now();
|
|
355
|
+
const result = await workflow(true, body);
|
|
356
|
+
|
|
357
|
+
return {
|
|
358
|
+
statusCode: 200,
|
|
359
|
+
headers: {
|
|
360
|
+
'Content-Type': 'application/json',
|
|
361
|
+
'X-Execution-Time': \`\${Date.now() - startTime}ms\`,
|
|
362
|
+
'X-Request-Id': context.awsRequestId,
|
|
363
|
+
},
|
|
364
|
+
body: JSON.stringify({
|
|
365
|
+
success: true,
|
|
366
|
+
result,
|
|
367
|
+
executionTime: Date.now() - startTime,
|
|
368
|
+
requestId: context.awsRequestId,
|
|
369
|
+
}),
|
|
370
|
+
};
|
|
371
|
+
} catch (error) {
|
|
372
|
+
return {
|
|
373
|
+
statusCode: 500,
|
|
374
|
+
headers: { 'Content-Type': 'application/json' },
|
|
375
|
+
body: JSON.stringify({
|
|
376
|
+
success: false,
|
|
377
|
+
error: error instanceof Error ? error.message : String(error),
|
|
378
|
+
requestId: context.awsRequestId,
|
|
379
|
+
}),
|
|
380
|
+
};
|
|
381
|
+
}
|
|
382
|
+
};
|
|
383
|
+
`;
|
|
384
|
+
/**
|
|
385
|
+
* Node type handler template for AWS Lambda
|
|
386
|
+
*/
|
|
387
|
+
const LAMBDA_NODE_TYPE_HANDLER_TEMPLATE = `{{GENERATED_HEADER}}
|
|
388
|
+
import type { APIGatewayProxyEventV2, APIGatewayProxyResultV2, Context } from 'aws-lambda';
|
|
389
|
+
{{NODE_TYPE_IMPORTS}}
|
|
390
|
+
import { openApiSpec } from './openapi.js';
|
|
391
|
+
|
|
392
|
+
// Handler type for node type functions
|
|
393
|
+
type NodeTypeHandler = (execute: boolean, params: Record<string, unknown>) => unknown;
|
|
394
|
+
|
|
395
|
+
// Node type router
|
|
396
|
+
const nodeTypes: Record<string, NodeTypeHandler> = {
|
|
397
|
+
{{NODE_TYPE_ENTRIES}}
|
|
398
|
+
};
|
|
399
|
+
|
|
400
|
+
const SWAGGER_UI_HTML = \`<!DOCTYPE html>
|
|
401
|
+
<html lang="en">
|
|
402
|
+
<head>
|
|
403
|
+
<meta charset="UTF-8">
|
|
404
|
+
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
405
|
+
<title>{{SERVICE_NAME}} API Documentation</title>
|
|
406
|
+
<link rel="stylesheet" href="https://unpkg.com/swagger-ui-dist@5/swagger-ui.css">
|
|
407
|
+
</head>
|
|
408
|
+
<body>
|
|
409
|
+
<div id="swagger-ui"></div>
|
|
410
|
+
<script src="https://unpkg.com/swagger-ui-dist@5/swagger-ui-bundle.js"></script>
|
|
411
|
+
<script>
|
|
412
|
+
SwaggerUIBundle({
|
|
413
|
+
url: './openapi.json',
|
|
414
|
+
dom_id: '#swagger-ui',
|
|
415
|
+
presets: [SwaggerUIBundle.presets.apis, SwaggerUIBundle.SwaggerUIStandalonePreset],
|
|
416
|
+
layout: 'BaseLayout'
|
|
417
|
+
});
|
|
418
|
+
</script>
|
|
419
|
+
</body>
|
|
420
|
+
</html>\`;
|
|
421
|
+
|
|
422
|
+
export const handler = async (
|
|
423
|
+
event: APIGatewayProxyEventV2,
|
|
424
|
+
context: Context
|
|
425
|
+
): Promise<APIGatewayProxyResultV2> => {
|
|
426
|
+
context.callbackWaitsForEmptyEventLoop = false;
|
|
427
|
+
const path = event.rawPath || event.requestContext?.http?.path || '/';
|
|
428
|
+
const method = event.requestContext?.http?.method || 'GET';
|
|
429
|
+
|
|
430
|
+
// Serve OpenAPI spec
|
|
431
|
+
if (path === '/api/openapi.json' && method === 'GET') {
|
|
432
|
+
return {
|
|
433
|
+
statusCode: 200,
|
|
434
|
+
headers: { 'Content-Type': 'application/json' },
|
|
435
|
+
body: JSON.stringify(openApiSpec),
|
|
436
|
+
};
|
|
437
|
+
}
|
|
438
|
+
|
|
439
|
+
// Serve Swagger UI
|
|
440
|
+
if (path === '/api/docs' && method === 'GET') {
|
|
441
|
+
return {
|
|
442
|
+
statusCode: 200,
|
|
443
|
+
headers: { 'Content-Type': 'text/html' },
|
|
444
|
+
body: SWAGGER_UI_HTML,
|
|
445
|
+
};
|
|
446
|
+
}
|
|
447
|
+
|
|
448
|
+
// Route to node type
|
|
449
|
+
const nodeTypeMatch = path.match(/^\\/api\\/([^\\/]+)$/);
|
|
450
|
+
if (!nodeTypeMatch) {
|
|
451
|
+
return {
|
|
452
|
+
statusCode: 404,
|
|
453
|
+
headers: { 'Content-Type': 'application/json' },
|
|
454
|
+
body: JSON.stringify({ error: 'Not found' }),
|
|
455
|
+
};
|
|
456
|
+
}
|
|
457
|
+
|
|
458
|
+
const nodeTypeName = nodeTypeMatch[1];
|
|
459
|
+
const nodeType = nodeTypes[nodeTypeName];
|
|
460
|
+
|
|
461
|
+
if (!nodeType) {
|
|
462
|
+
return {
|
|
463
|
+
statusCode: 404,
|
|
464
|
+
headers: { 'Content-Type': 'application/json' },
|
|
465
|
+
body: JSON.stringify({
|
|
466
|
+
error: \`Node type '\${nodeTypeName}' not found\`,
|
|
467
|
+
availableNodeTypes: Object.keys(nodeTypes),
|
|
468
|
+
}),
|
|
469
|
+
};
|
|
470
|
+
}
|
|
471
|
+
|
|
472
|
+
if (method !== 'POST') {
|
|
473
|
+
return {
|
|
474
|
+
statusCode: 405,
|
|
475
|
+
headers: { 'Content-Type': 'application/json' },
|
|
476
|
+
body: JSON.stringify({ error: 'Method not allowed. Use POST to execute node types.' }),
|
|
477
|
+
};
|
|
478
|
+
}
|
|
479
|
+
|
|
480
|
+
try {
|
|
481
|
+
const body = typeof event.body === 'string'
|
|
482
|
+
? JSON.parse(event.body || '{}')
|
|
483
|
+
: event.body || {};
|
|
484
|
+
|
|
485
|
+
const startTime = Date.now();
|
|
486
|
+
const result = await nodeType(true, body);
|
|
487
|
+
|
|
488
|
+
return {
|
|
489
|
+
statusCode: 200,
|
|
490
|
+
headers: {
|
|
491
|
+
'Content-Type': 'application/json',
|
|
492
|
+
'X-Execution-Time': \`\${Date.now() - startTime}ms\`,
|
|
493
|
+
'X-Request-Id': context.awsRequestId,
|
|
494
|
+
},
|
|
495
|
+
body: JSON.stringify({
|
|
496
|
+
success: true,
|
|
497
|
+
result,
|
|
498
|
+
executionTime: Date.now() - startTime,
|
|
499
|
+
requestId: context.awsRequestId,
|
|
500
|
+
}),
|
|
501
|
+
};
|
|
502
|
+
} catch (error) {
|
|
503
|
+
return {
|
|
504
|
+
statusCode: 500,
|
|
505
|
+
headers: { 'Content-Type': 'application/json' },
|
|
506
|
+
body: JSON.stringify({
|
|
507
|
+
success: false,
|
|
508
|
+
error: error instanceof Error ? error.message : String(error),
|
|
509
|
+
requestId: context.awsRequestId,
|
|
510
|
+
}),
|
|
511
|
+
};
|
|
512
|
+
}
|
|
513
|
+
};
|
|
514
|
+
`;
|
|
515
|
+
/**
|
|
516
|
+
* SAM template for node type deployment
|
|
517
|
+
*/
|
|
518
|
+
const SAM_NODE_TYPE_TEMPLATE = `AWSTemplateFormatVersion: '2010-09-09'
|
|
519
|
+
Transform: AWS::Serverless-2016-10-31
|
|
520
|
+
Description: Flow Weaver node type service - {{SERVICE_NAME}}
|
|
521
|
+
|
|
522
|
+
Globals:
|
|
523
|
+
Function:
|
|
524
|
+
Timeout: 30
|
|
525
|
+
Runtime: nodejs20.x
|
|
526
|
+
MemorySize: 256
|
|
527
|
+
|
|
528
|
+
Resources:
|
|
529
|
+
NodeTypeFunction:
|
|
530
|
+
Type: AWS::Serverless::Function
|
|
531
|
+
Properties:
|
|
532
|
+
Handler: handler.handler
|
|
533
|
+
CodeUri: .
|
|
534
|
+
Description: Node type service with {{NODE_TYPE_COUNT}} endpoints
|
|
535
|
+
Events:
|
|
536
|
+
ApiProxy:
|
|
537
|
+
Type: HttpApi
|
|
538
|
+
Properties:
|
|
539
|
+
Path: /api/{proxy+}
|
|
540
|
+
Method: ANY
|
|
541
|
+
ApiDocs:
|
|
542
|
+
Type: HttpApi
|
|
543
|
+
Properties:
|
|
544
|
+
Path: /api/docs
|
|
545
|
+
Method: GET
|
|
546
|
+
ApiOpenapi:
|
|
547
|
+
Type: HttpApi
|
|
548
|
+
Properties:
|
|
549
|
+
Path: /api/openapi.json
|
|
550
|
+
Method: GET
|
|
551
|
+
|
|
552
|
+
Outputs:
|
|
553
|
+
ApiEndpoint:
|
|
554
|
+
Description: API base URL
|
|
555
|
+
Value: !Sub "https://\${ServerlessHttpApi}.execute-api.\${AWS::Region}.amazonaws.com/api"
|
|
556
|
+
DocsEndpoint:
|
|
557
|
+
Description: API documentation URL
|
|
558
|
+
Value: !Sub "https://\${ServerlessHttpApi}.execute-api.\${AWS::Region}.amazonaws.com/api/docs"
|
|
559
|
+
`;
|
|
560
|
+
/**
|
|
561
|
+
* SAM template for multi-workflow deployment
|
|
562
|
+
*/
|
|
563
|
+
const SAM_MULTI_TEMPLATE = `AWSTemplateFormatVersion: '2010-09-09'
|
|
564
|
+
Transform: AWS::Serverless-2016-10-31
|
|
565
|
+
Description: Flow Weaver multi-workflow service - {{SERVICE_NAME}}
|
|
566
|
+
|
|
567
|
+
Globals:
|
|
568
|
+
Function:
|
|
569
|
+
Timeout: 30
|
|
570
|
+
Runtime: nodejs20.x
|
|
571
|
+
MemorySize: 256
|
|
572
|
+
|
|
573
|
+
Resources:
|
|
574
|
+
WorkflowFunction:
|
|
575
|
+
Type: AWS::Serverless::Function
|
|
576
|
+
Properties:
|
|
577
|
+
Handler: handler.handler
|
|
578
|
+
CodeUri: .
|
|
579
|
+
Description: Multi-workflow service with {{WORKFLOW_COUNT}} workflows
|
|
580
|
+
Events:
|
|
581
|
+
ApiProxy:
|
|
582
|
+
Type: HttpApi
|
|
583
|
+
Properties:
|
|
584
|
+
Path: /api/{proxy+}
|
|
585
|
+
Method: ANY
|
|
586
|
+
ApiFunctions:
|
|
587
|
+
Type: HttpApi
|
|
588
|
+
Properties:
|
|
589
|
+
Path: /api/functions
|
|
590
|
+
Method: GET
|
|
591
|
+
ApiDocs:
|
|
592
|
+
Type: HttpApi
|
|
593
|
+
Properties:
|
|
594
|
+
Path: /api/docs
|
|
595
|
+
Method: GET
|
|
596
|
+
ApiOpenapi:
|
|
597
|
+
Type: HttpApi
|
|
598
|
+
Properties:
|
|
599
|
+
Path: /api/openapi.json
|
|
600
|
+
Method: GET
|
|
601
|
+
|
|
602
|
+
Outputs:
|
|
603
|
+
ApiEndpoint:
|
|
604
|
+
Description: API base URL
|
|
605
|
+
Value: !Sub "https://\${ServerlessHttpApi}.execute-api.\${AWS::Region}.amazonaws.com/api"
|
|
606
|
+
DocsEndpoint:
|
|
607
|
+
Description: API documentation URL
|
|
608
|
+
Value: !Sub "https://\${ServerlessHttpApi}.execute-api.\${AWS::Region}.amazonaws.com/api/docs"
|
|
609
|
+
`;
|
|
610
|
+
/**
|
|
611
|
+
* Bundle handler template for AWS Lambda - unified workflows and node types
|
|
612
|
+
*/
|
|
613
|
+
const LAMBDA_BUNDLE_HANDLER_TEMPLATE = `{{GENERATED_HEADER}}
|
|
614
|
+
import type { APIGatewayProxyEventV2, APIGatewayProxyResultV2, Context } from 'aws-lambda';
|
|
615
|
+
{{WORKFLOW_IMPORTS}}
|
|
616
|
+
{{NODE_TYPE_IMPORTS}}
|
|
617
|
+
import { functionRegistry } from './runtime/function-registry.js';
|
|
618
|
+
import './runtime/builtin-functions.js';
|
|
619
|
+
import { openApiSpec } from './openapi.js';
|
|
620
|
+
|
|
621
|
+
// Handler type for workflow/nodeType functions
|
|
622
|
+
type FunctionHandler = (execute: boolean, params: Record<string, unknown>) => unknown;
|
|
623
|
+
|
|
624
|
+
// Exposed workflows (have HTTP endpoints)
|
|
625
|
+
const exposedWorkflows: Record<string, FunctionHandler> = {
|
|
626
|
+
{{EXPOSED_WORKFLOW_ENTRIES}}
|
|
627
|
+
};
|
|
628
|
+
|
|
629
|
+
// Exposed node types (have HTTP endpoints)
|
|
630
|
+
const exposedNodeTypes: Record<string, FunctionHandler> = {
|
|
631
|
+
{{EXPOSED_NODE_TYPE_ENTRIES}}
|
|
632
|
+
};
|
|
633
|
+
|
|
634
|
+
const SWAGGER_UI_HTML = \`<!DOCTYPE html>
|
|
635
|
+
<html lang="en">
|
|
636
|
+
<head>
|
|
637
|
+
<meta charset="UTF-8">
|
|
638
|
+
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
639
|
+
<title>{{SERVICE_NAME}} API Documentation</title>
|
|
640
|
+
<link rel="stylesheet" href="https://unpkg.com/swagger-ui-dist@5/swagger-ui.css">
|
|
641
|
+
</head>
|
|
642
|
+
<body>
|
|
643
|
+
<div id="swagger-ui"></div>
|
|
644
|
+
<script src="https://unpkg.com/swagger-ui-dist@5/swagger-ui-bundle.js"></script>
|
|
645
|
+
<script>
|
|
646
|
+
SwaggerUIBundle({
|
|
647
|
+
url: './openapi.json',
|
|
648
|
+
dom_id: '#swagger-ui',
|
|
649
|
+
presets: [SwaggerUIBundle.presets.apis, SwaggerUIBundle.SwaggerUIStandalonePreset],
|
|
650
|
+
layout: 'BaseLayout'
|
|
651
|
+
});
|
|
652
|
+
</script>
|
|
653
|
+
</body>
|
|
654
|
+
</html>\`;
|
|
655
|
+
|
|
656
|
+
export const handler = async (
|
|
657
|
+
event: APIGatewayProxyEventV2,
|
|
658
|
+
context: Context
|
|
659
|
+
): Promise<APIGatewayProxyResultV2> => {
|
|
660
|
+
context.callbackWaitsForEmptyEventLoop = false;
|
|
661
|
+
const path = event.rawPath || event.requestContext?.http?.path || '/';
|
|
662
|
+
const method = event.requestContext?.http?.method || 'GET';
|
|
663
|
+
|
|
664
|
+
// Serve OpenAPI spec
|
|
665
|
+
if (path === '/api/openapi.json' && method === 'GET') {
|
|
666
|
+
return {
|
|
667
|
+
statusCode: 200,
|
|
668
|
+
headers: { 'Content-Type': 'application/json' },
|
|
669
|
+
body: JSON.stringify(openApiSpec),
|
|
670
|
+
};
|
|
671
|
+
}
|
|
672
|
+
|
|
673
|
+
// Serve Swagger UI
|
|
674
|
+
if (path === '/api/docs' && method === 'GET') {
|
|
675
|
+
return {
|
|
676
|
+
statusCode: 200,
|
|
677
|
+
headers: { 'Content-Type': 'text/html' },
|
|
678
|
+
body: SWAGGER_UI_HTML,
|
|
679
|
+
};
|
|
680
|
+
}
|
|
681
|
+
|
|
682
|
+
// List available functions
|
|
683
|
+
if (path === '/api/functions' && method === 'GET') {
|
|
684
|
+
const category = event.queryStringParameters?.category;
|
|
685
|
+
const functions = functionRegistry.list(category as any);
|
|
686
|
+
return {
|
|
687
|
+
statusCode: 200,
|
|
688
|
+
headers: { 'Content-Type': 'application/json' },
|
|
689
|
+
body: JSON.stringify(functions),
|
|
690
|
+
};
|
|
691
|
+
}
|
|
692
|
+
|
|
693
|
+
// Route to workflow
|
|
694
|
+
const workflowMatch = path.match(/^\\/api\\/workflows\\/([^\\/]+)$/);
|
|
695
|
+
if (workflowMatch) {
|
|
696
|
+
const workflowName = workflowMatch[1];
|
|
697
|
+
const workflow = exposedWorkflows[workflowName];
|
|
698
|
+
|
|
699
|
+
if (!workflow) {
|
|
700
|
+
return {
|
|
701
|
+
statusCode: 404,
|
|
702
|
+
headers: { 'Content-Type': 'application/json' },
|
|
703
|
+
body: JSON.stringify({
|
|
704
|
+
error: \`Workflow '\${workflowName}' not found\`,
|
|
705
|
+
availableWorkflows: Object.keys(exposedWorkflows),
|
|
706
|
+
}),
|
|
707
|
+
};
|
|
708
|
+
}
|
|
709
|
+
|
|
710
|
+
if (method !== 'POST') {
|
|
711
|
+
return {
|
|
712
|
+
statusCode: 405,
|
|
713
|
+
headers: { 'Content-Type': 'application/json' },
|
|
714
|
+
body: JSON.stringify({ error: 'Method not allowed. Use POST to execute workflows.' }),
|
|
715
|
+
};
|
|
716
|
+
}
|
|
717
|
+
|
|
718
|
+
try {
|
|
719
|
+
const body = typeof event.body === 'string'
|
|
720
|
+
? JSON.parse(event.body || '{}')
|
|
721
|
+
: event.body || {};
|
|
722
|
+
|
|
723
|
+
const startTime = Date.now();
|
|
724
|
+
const result = await workflow(true, body);
|
|
725
|
+
|
|
726
|
+
return {
|
|
727
|
+
statusCode: 200,
|
|
728
|
+
headers: {
|
|
729
|
+
'Content-Type': 'application/json',
|
|
730
|
+
'X-Execution-Time': \`\${Date.now() - startTime}ms\`,
|
|
731
|
+
'X-Request-Id': context.awsRequestId,
|
|
732
|
+
},
|
|
733
|
+
body: JSON.stringify({
|
|
734
|
+
success: true,
|
|
735
|
+
result,
|
|
736
|
+
executionTime: Date.now() - startTime,
|
|
737
|
+
requestId: context.awsRequestId,
|
|
738
|
+
}),
|
|
739
|
+
};
|
|
740
|
+
} catch (error) {
|
|
741
|
+
return {
|
|
742
|
+
statusCode: 500,
|
|
743
|
+
headers: { 'Content-Type': 'application/json' },
|
|
744
|
+
body: JSON.stringify({
|
|
745
|
+
success: false,
|
|
746
|
+
error: error instanceof Error ? error.message : String(error),
|
|
747
|
+
requestId: context.awsRequestId,
|
|
748
|
+
}),
|
|
749
|
+
};
|
|
750
|
+
}
|
|
751
|
+
}
|
|
752
|
+
|
|
753
|
+
// Route to node type
|
|
754
|
+
const nodeTypeMatch = path.match(/^\\/api\\/nodes\\/([^\\/]+)$/);
|
|
755
|
+
if (nodeTypeMatch) {
|
|
756
|
+
const nodeTypeName = nodeTypeMatch[1];
|
|
757
|
+
const nodeType = exposedNodeTypes[nodeTypeName];
|
|
758
|
+
|
|
759
|
+
if (!nodeType) {
|
|
760
|
+
return {
|
|
761
|
+
statusCode: 404,
|
|
762
|
+
headers: { 'Content-Type': 'application/json' },
|
|
763
|
+
body: JSON.stringify({
|
|
764
|
+
error: \`Node type '\${nodeTypeName}' not found\`,
|
|
765
|
+
availableNodeTypes: Object.keys(exposedNodeTypes),
|
|
766
|
+
}),
|
|
767
|
+
};
|
|
768
|
+
}
|
|
769
|
+
|
|
770
|
+
if (method !== 'POST') {
|
|
771
|
+
return {
|
|
772
|
+
statusCode: 405,
|
|
773
|
+
headers: { 'Content-Type': 'application/json' },
|
|
774
|
+
body: JSON.stringify({ error: 'Method not allowed. Use POST to execute node types.' }),
|
|
775
|
+
};
|
|
776
|
+
}
|
|
777
|
+
|
|
778
|
+
try {
|
|
779
|
+
const body = typeof event.body === 'string'
|
|
780
|
+
? JSON.parse(event.body || '{}')
|
|
781
|
+
: event.body || {};
|
|
782
|
+
|
|
783
|
+
const startTime = Date.now();
|
|
784
|
+
const result = await nodeType(true, body);
|
|
785
|
+
|
|
786
|
+
return {
|
|
787
|
+
statusCode: 200,
|
|
788
|
+
headers: {
|
|
789
|
+
'Content-Type': 'application/json',
|
|
790
|
+
'X-Execution-Time': \`\${Date.now() - startTime}ms\`,
|
|
791
|
+
'X-Request-Id': context.awsRequestId,
|
|
792
|
+
},
|
|
793
|
+
body: JSON.stringify({
|
|
794
|
+
success: true,
|
|
795
|
+
result,
|
|
796
|
+
executionTime: Date.now() - startTime,
|
|
797
|
+
requestId: context.awsRequestId,
|
|
798
|
+
}),
|
|
799
|
+
};
|
|
800
|
+
} catch (error) {
|
|
801
|
+
return {
|
|
802
|
+
statusCode: 500,
|
|
803
|
+
headers: { 'Content-Type': 'application/json' },
|
|
804
|
+
body: JSON.stringify({
|
|
805
|
+
success: false,
|
|
806
|
+
error: error instanceof Error ? error.message : String(error),
|
|
807
|
+
requestId: context.awsRequestId,
|
|
808
|
+
}),
|
|
809
|
+
};
|
|
810
|
+
}
|
|
811
|
+
}
|
|
812
|
+
|
|
813
|
+
return {
|
|
814
|
+
statusCode: 404,
|
|
815
|
+
headers: { 'Content-Type': 'application/json' },
|
|
816
|
+
body: JSON.stringify({ error: 'Not found' }),
|
|
817
|
+
};
|
|
818
|
+
};
|
|
819
|
+
`;
|
|
820
|
+
/**
|
|
821
|
+
* SAM template for bundle deployment
|
|
822
|
+
*/
|
|
823
|
+
const SAM_BUNDLE_TEMPLATE = `AWSTemplateFormatVersion: '2010-09-09'
|
|
824
|
+
Transform: AWS::Serverless-2016-10-31
|
|
825
|
+
Description: Flow Weaver bundle service - {{SERVICE_NAME}}
|
|
826
|
+
|
|
827
|
+
Globals:
|
|
828
|
+
Function:
|
|
829
|
+
Timeout: 30
|
|
830
|
+
Runtime: nodejs20.x
|
|
831
|
+
MemorySize: 256
|
|
832
|
+
|
|
833
|
+
Resources:
|
|
834
|
+
BundleFunction:
|
|
835
|
+
Type: AWS::Serverless::Function
|
|
836
|
+
Properties:
|
|
837
|
+
Handler: handler.handler
|
|
838
|
+
CodeUri: .
|
|
839
|
+
Description: Bundle service with {{WORKFLOW_COUNT}} workflows and {{NODE_TYPE_COUNT}} node types
|
|
840
|
+
Events:
|
|
841
|
+
ApiProxy:
|
|
842
|
+
Type: HttpApi
|
|
843
|
+
Properties:
|
|
844
|
+
Path: /api/{proxy+}
|
|
845
|
+
Method: ANY
|
|
846
|
+
ApiFunctions:
|
|
847
|
+
Type: HttpApi
|
|
848
|
+
Properties:
|
|
849
|
+
Path: /api/functions
|
|
850
|
+
Method: GET
|
|
851
|
+
ApiDocs:
|
|
852
|
+
Type: HttpApi
|
|
853
|
+
Properties:
|
|
854
|
+
Path: /api/docs
|
|
855
|
+
Method: GET
|
|
856
|
+
ApiOpenapi:
|
|
857
|
+
Type: HttpApi
|
|
858
|
+
Properties:
|
|
859
|
+
Path: /api/openapi.json
|
|
860
|
+
Method: GET
|
|
861
|
+
|
|
862
|
+
Outputs:
|
|
863
|
+
ApiEndpoint:
|
|
864
|
+
Description: API base URL
|
|
865
|
+
Value: !Sub "https://\${ServerlessHttpApi}.execute-api.\${AWS::Region}.amazonaws.com/api"
|
|
866
|
+
DocsEndpoint:
|
|
867
|
+
Description: API documentation URL
|
|
868
|
+
Value: !Sub "https://\${ServerlessHttpApi}.execute-api.\${AWS::Region}.amazonaws.com/api/docs"
|
|
869
|
+
`;
|
|
870
|
+
/**
|
|
871
|
+
* AWS Lambda export target
|
|
872
|
+
*/
|
|
873
|
+
export class LambdaTarget extends BaseExportTarget {
|
|
874
|
+
name = 'lambda';
|
|
875
|
+
description = 'AWS Lambda with SAM (Serverless Application Model)';
|
|
876
|
+
async generate(options) {
|
|
877
|
+
const files = [];
|
|
878
|
+
const includeDocs = options.includeDocs ?? false;
|
|
879
|
+
// Select appropriate handler template
|
|
880
|
+
const handlerTemplate = includeDocs
|
|
881
|
+
? LAMBDA_HANDLER_WITH_DOCS_TEMPLATE
|
|
882
|
+
: LAMBDA_HANDLER_TEMPLATE;
|
|
883
|
+
// Generate handler
|
|
884
|
+
const handlerContent = handlerTemplate
|
|
885
|
+
.replace('{{GENERATED_HEADER}}', getGeneratedBranding().header('export --target lambda'))
|
|
886
|
+
.replace('{{WORKFLOW_IMPORT}}', `import { ${options.workflowName} } from './workflow.js';`)
|
|
887
|
+
.replace(/\{\{FUNCTION_NAME\}\}/g, options.workflowName)
|
|
888
|
+
.replace(/\{\{WORKFLOW_NAME\}\}/g, options.displayName);
|
|
889
|
+
files.push(this.createFile(options.outputDir, 'handler.ts', handlerContent, 'handler'));
|
|
890
|
+
// Generate OpenAPI spec file if docs are enabled
|
|
891
|
+
if (includeDocs) {
|
|
892
|
+
const openApiSpec = this.generateOpenAPISpec(options);
|
|
893
|
+
const openApiContent = OPENAPI_SPEC_TEMPLATE.replace('{{OPENAPI_SPEC}}', JSON.stringify(openApiSpec, null, 2));
|
|
894
|
+
files.push(this.createFile(options.outputDir, 'openapi.ts', openApiContent, 'config'));
|
|
895
|
+
}
|
|
896
|
+
// Select appropriate SAM template
|
|
897
|
+
const samTemplate = includeDocs ? SAM_TEMPLATE_WITH_DOCS : SAM_TEMPLATE;
|
|
898
|
+
// Generate SAM template
|
|
899
|
+
const samContent = samTemplate
|
|
900
|
+
.replace(/\{\{WORKFLOW_NAME\}\}/g, options.displayName)
|
|
901
|
+
.replace('{{WORKFLOW_DESCRIPTION}}', options.description || `Flow Weaver workflow: ${options.displayName}`)
|
|
902
|
+
.replace(/\{\{WORKFLOW_PATH\}\}/g, options.displayName);
|
|
903
|
+
files.push(this.createFile(options.outputDir, 'template.yaml', samContent, 'config'));
|
|
904
|
+
// Generate package.json
|
|
905
|
+
const packageJson = this.generatePackageJson({
|
|
906
|
+
name: options.displayName,
|
|
907
|
+
description: options.description,
|
|
908
|
+
main: 'handler.js',
|
|
909
|
+
scripts: {
|
|
910
|
+
build: 'tsc',
|
|
911
|
+
dev: 'sam build && sam local start-api',
|
|
912
|
+
deploy: 'sam build && sam deploy --guided',
|
|
913
|
+
},
|
|
914
|
+
devDependencies: {
|
|
915
|
+
'@types/aws-lambda': '^8.10.0',
|
|
916
|
+
},
|
|
917
|
+
});
|
|
918
|
+
files.push(this.createFile(options.outputDir, 'package.json', packageJson, 'package'));
|
|
919
|
+
// Generate tsconfig.json
|
|
920
|
+
const tsConfig = this.generateTsConfig({
|
|
921
|
+
outDir: './dist',
|
|
922
|
+
module: 'NodeNext',
|
|
923
|
+
moduleResolution: 'NodeNext',
|
|
924
|
+
});
|
|
925
|
+
files.push(this.createFile(options.outputDir, 'tsconfig.json', tsConfig, 'config'));
|
|
926
|
+
// Generate README from deploy instructions
|
|
927
|
+
const artifacts = { files, target: this.name, workflowName: options.displayName, entryPoint: 'handler.ts' };
|
|
928
|
+
const instructions = this.getDeployInstructions(artifacts);
|
|
929
|
+
const readme = this.generateReadme(instructions, options.displayName, 'AWS Lambda');
|
|
930
|
+
files.push(this.createFile(options.outputDir, 'README.md', readme, 'other'));
|
|
931
|
+
return artifacts;
|
|
932
|
+
}
|
|
933
|
+
/**
|
|
934
|
+
* Generate OpenAPI specification for the workflow
|
|
935
|
+
*/
|
|
936
|
+
generateOpenAPISpec(options) {
|
|
937
|
+
return {
|
|
938
|
+
openapi: '3.0.3',
|
|
939
|
+
info: {
|
|
940
|
+
title: `${options.displayName} API`,
|
|
941
|
+
version: '1.0.0',
|
|
942
|
+
description: options.description || `API for the ${options.displayName} workflow`,
|
|
943
|
+
},
|
|
944
|
+
servers: [{ url: '/', description: 'Current deployment' }],
|
|
945
|
+
paths: {
|
|
946
|
+
[`/${options.displayName}`]: {
|
|
947
|
+
post: {
|
|
948
|
+
operationId: `execute_${options.workflowName}`,
|
|
949
|
+
summary: `Execute ${options.displayName} workflow`,
|
|
950
|
+
description: options.description || `Execute the ${options.displayName} workflow`,
|
|
951
|
+
tags: ['workflows'],
|
|
952
|
+
requestBody: {
|
|
953
|
+
description: 'Workflow input parameters',
|
|
954
|
+
required: true,
|
|
955
|
+
content: {
|
|
956
|
+
'application/json': {
|
|
957
|
+
schema: { type: 'object' },
|
|
958
|
+
},
|
|
959
|
+
},
|
|
960
|
+
},
|
|
961
|
+
responses: {
|
|
962
|
+
'200': {
|
|
963
|
+
description: 'Successful workflow execution',
|
|
964
|
+
content: {
|
|
965
|
+
'application/json': {
|
|
966
|
+
schema: {
|
|
967
|
+
type: 'object',
|
|
968
|
+
properties: {
|
|
969
|
+
success: { type: 'boolean' },
|
|
970
|
+
result: { type: 'object' },
|
|
971
|
+
executionTime: { type: 'number' },
|
|
972
|
+
requestId: { type: 'string' },
|
|
973
|
+
},
|
|
974
|
+
},
|
|
975
|
+
},
|
|
976
|
+
},
|
|
977
|
+
},
|
|
978
|
+
'500': {
|
|
979
|
+
description: 'Execution error',
|
|
980
|
+
content: {
|
|
981
|
+
'application/json': {
|
|
982
|
+
schema: {
|
|
983
|
+
type: 'object',
|
|
984
|
+
properties: {
|
|
985
|
+
success: { type: 'boolean' },
|
|
986
|
+
error: { type: 'string' },
|
|
987
|
+
requestId: { type: 'string' },
|
|
988
|
+
},
|
|
989
|
+
},
|
|
990
|
+
},
|
|
991
|
+
},
|
|
992
|
+
},
|
|
993
|
+
},
|
|
994
|
+
},
|
|
995
|
+
},
|
|
996
|
+
},
|
|
997
|
+
tags: [{ name: 'workflows', description: 'Workflow execution endpoints' }],
|
|
998
|
+
};
|
|
999
|
+
}
|
|
1000
|
+
async generateMultiWorkflow(workflows, options) {
|
|
1001
|
+
const files = [];
|
|
1002
|
+
const serviceName = options.displayName || 'multi-workflow-service';
|
|
1003
|
+
// Generate workflow imports and entries
|
|
1004
|
+
const workflowImports = workflows
|
|
1005
|
+
.map((w) => `import { ${w.functionName} } from './workflows/${w.name}.js';`)
|
|
1006
|
+
.join('\n');
|
|
1007
|
+
const workflowEntries = workflows.map((w) => ` '${w.name}': ${w.functionName},`).join('\n');
|
|
1008
|
+
// Generate multi-workflow handler
|
|
1009
|
+
const handlerContent = LAMBDA_MULTI_HANDLER_TEMPLATE
|
|
1010
|
+
.replace('{{GENERATED_HEADER}}', getGeneratedBranding().header('export --target lambda --multi'))
|
|
1011
|
+
.replace('{{WORKFLOW_IMPORTS}}', workflowImports)
|
|
1012
|
+
.replace('{{WORKFLOW_ENTRIES}}', workflowEntries)
|
|
1013
|
+
.replace(/\{\{SERVICE_NAME\}\}/g, serviceName);
|
|
1014
|
+
files.push(this.createFile(options.outputDir, 'handler.ts', handlerContent, 'handler'));
|
|
1015
|
+
// Generate consolidated OpenAPI spec
|
|
1016
|
+
const openApiSpec = this.generateConsolidatedOpenAPI(workflows, {
|
|
1017
|
+
title: `${serviceName} API`,
|
|
1018
|
+
version: '1.0.0',
|
|
1019
|
+
});
|
|
1020
|
+
const openApiContent = `// Generated OpenAPI specification
|
|
1021
|
+
export const openApiSpec = ${JSON.stringify(openApiSpec, null, 2)};
|
|
1022
|
+
`;
|
|
1023
|
+
files.push(this.createFile(options.outputDir, 'openapi.ts', openApiContent, 'config'));
|
|
1024
|
+
// Generate SAM template
|
|
1025
|
+
const samContent = SAM_MULTI_TEMPLATE.replace(/\{\{SERVICE_NAME\}\}/g, serviceName).replace('{{WORKFLOW_COUNT}}', String(workflows.length));
|
|
1026
|
+
files.push(this.createFile(options.outputDir, 'template.yaml', samContent, 'config'));
|
|
1027
|
+
// Generate package.json
|
|
1028
|
+
const packageJson = this.generatePackageJson({
|
|
1029
|
+
name: serviceName,
|
|
1030
|
+
description: `Multi-workflow service with ${workflows.length} workflows`,
|
|
1031
|
+
main: 'handler.js',
|
|
1032
|
+
scripts: {
|
|
1033
|
+
build: 'tsc',
|
|
1034
|
+
deploy: 'sam build && sam deploy --guided',
|
|
1035
|
+
},
|
|
1036
|
+
devDependencies: {
|
|
1037
|
+
'@types/aws-lambda': '^8.10.0',
|
|
1038
|
+
},
|
|
1039
|
+
});
|
|
1040
|
+
files.push(this.createFile(options.outputDir, 'package.json', packageJson, 'package'));
|
|
1041
|
+
// Generate tsconfig.json
|
|
1042
|
+
const tsConfig = this.generateTsConfig({
|
|
1043
|
+
outDir: './dist',
|
|
1044
|
+
module: 'NodeNext',
|
|
1045
|
+
moduleResolution: 'NodeNext',
|
|
1046
|
+
});
|
|
1047
|
+
files.push(this.createFile(options.outputDir, 'tsconfig.json', tsConfig, 'config'));
|
|
1048
|
+
// Generate workflow content files
|
|
1049
|
+
files.push(...this.generateWorkflowContentFiles(workflows, options.outputDir));
|
|
1050
|
+
return {
|
|
1051
|
+
files,
|
|
1052
|
+
target: this.name,
|
|
1053
|
+
workflowName: serviceName,
|
|
1054
|
+
workflowNames: workflows.map((w) => w.name),
|
|
1055
|
+
entryPoint: 'handler.ts',
|
|
1056
|
+
openApiSpec,
|
|
1057
|
+
};
|
|
1058
|
+
}
|
|
1059
|
+
async generateNodeTypeService(nodeTypes, options) {
|
|
1060
|
+
const files = [];
|
|
1061
|
+
const serviceName = options.serviceName || 'node-type-service';
|
|
1062
|
+
// Generate node type imports and entries
|
|
1063
|
+
// Use lowercase functionName for import paths to match the generated file names
|
|
1064
|
+
const nodeTypeImports = nodeTypes
|
|
1065
|
+
.map((nt) => `import { ${nt.functionName} } from './node-types/${nt.functionName.toLowerCase()}.js';`)
|
|
1066
|
+
.join('\n');
|
|
1067
|
+
const nodeTypeEntries = nodeTypes.map((nt) => ` '${nt.name}': ${nt.functionName},`).join('\n');
|
|
1068
|
+
// Generate node type handler
|
|
1069
|
+
const handlerContent = LAMBDA_NODE_TYPE_HANDLER_TEMPLATE
|
|
1070
|
+
.replace('{{GENERATED_HEADER}}', getGeneratedBranding().header('export --target lambda --node-types'))
|
|
1071
|
+
.replace('{{NODE_TYPE_IMPORTS}}', nodeTypeImports)
|
|
1072
|
+
.replace('{{NODE_TYPE_ENTRIES}}', nodeTypeEntries)
|
|
1073
|
+
.replace(/\{\{SERVICE_NAME\}\}/g, serviceName);
|
|
1074
|
+
files.push(this.createFile(options.outputDir, 'handler.ts', handlerContent, 'handler'));
|
|
1075
|
+
// Generate OpenAPI spec
|
|
1076
|
+
const openApiSpec = this.generateNodeTypeOpenAPI(nodeTypes, {
|
|
1077
|
+
title: `${serviceName} API`,
|
|
1078
|
+
version: '1.0.0',
|
|
1079
|
+
});
|
|
1080
|
+
const openApiContent = `// Generated OpenAPI specification
|
|
1081
|
+
export const openApiSpec = ${JSON.stringify(openApiSpec, null, 2)};
|
|
1082
|
+
`;
|
|
1083
|
+
files.push(this.createFile(options.outputDir, 'openapi.ts', openApiContent, 'config'));
|
|
1084
|
+
// Generate SAM template
|
|
1085
|
+
const samContent = SAM_NODE_TYPE_TEMPLATE.replace(/\{\{SERVICE_NAME\}\}/g, serviceName).replace('{{NODE_TYPE_COUNT}}', String(nodeTypes.length));
|
|
1086
|
+
files.push(this.createFile(options.outputDir, 'template.yaml', samContent, 'config'));
|
|
1087
|
+
// Generate package.json
|
|
1088
|
+
const packageJson = this.generatePackageJson({
|
|
1089
|
+
name: serviceName,
|
|
1090
|
+
description: `Node type service with ${nodeTypes.length} endpoints`,
|
|
1091
|
+
main: 'handler.js',
|
|
1092
|
+
scripts: {
|
|
1093
|
+
build: 'tsc',
|
|
1094
|
+
deploy: 'sam build && sam deploy --guided',
|
|
1095
|
+
},
|
|
1096
|
+
devDependencies: {
|
|
1097
|
+
'@types/aws-lambda': '^8.10.0',
|
|
1098
|
+
},
|
|
1099
|
+
});
|
|
1100
|
+
files.push(this.createFile(options.outputDir, 'package.json', packageJson, 'package'));
|
|
1101
|
+
// Generate tsconfig.json
|
|
1102
|
+
const tsConfig = this.generateTsConfig({
|
|
1103
|
+
outDir: './dist',
|
|
1104
|
+
module: 'NodeNext',
|
|
1105
|
+
moduleResolution: 'NodeNext',
|
|
1106
|
+
});
|
|
1107
|
+
files.push(this.createFile(options.outputDir, 'tsconfig.json', tsConfig, 'config'));
|
|
1108
|
+
// Generate node-type content files
|
|
1109
|
+
files.push(...this.generateNodeTypeContentFiles(nodeTypes, options.outputDir));
|
|
1110
|
+
return {
|
|
1111
|
+
files,
|
|
1112
|
+
target: this.name,
|
|
1113
|
+
workflowName: serviceName,
|
|
1114
|
+
nodeTypeNames: nodeTypes.map((nt) => nt.name),
|
|
1115
|
+
entryPoint: 'handler.ts',
|
|
1116
|
+
openApiSpec,
|
|
1117
|
+
};
|
|
1118
|
+
}
|
|
1119
|
+
async generateBundle(workflows, nodeTypes, options) {
|
|
1120
|
+
const files = [];
|
|
1121
|
+
const serviceName = options.displayName || 'bundle-service';
|
|
1122
|
+
// Filter to only include items that have generated code
|
|
1123
|
+
// Filter to only include items that have generated code
|
|
1124
|
+
// Also skip npm imports (names containing '/') as they should be installed via package.json
|
|
1125
|
+
const workflowsWithCode = workflows.filter((w) => w.code);
|
|
1126
|
+
const nodeTypesWithCode = nodeTypes.filter((nt) => nt.code && !nt.name.includes('/'));
|
|
1127
|
+
// Separate exposed and bundled-only items
|
|
1128
|
+
const exposedWorkflows = workflows.filter((w) => w.expose);
|
|
1129
|
+
const exposedNodeTypes = nodeTypes.filter((nt) => nt.expose);
|
|
1130
|
+
// Detect name collisions between workflows and nodeTypes
|
|
1131
|
+
const workflowNames = new Set(workflowsWithCode.map((w) => w.functionName));
|
|
1132
|
+
const nodeTypeAliases = new Map();
|
|
1133
|
+
for (const nt of nodeTypesWithCode) {
|
|
1134
|
+
if (workflowNames.has(nt.functionName)) {
|
|
1135
|
+
nodeTypeAliases.set(nt.functionName, `${nt.functionName}_nodeType`);
|
|
1136
|
+
}
|
|
1137
|
+
}
|
|
1138
|
+
// Generate all workflow imports (both exposed and bundled-only) - only for those with code
|
|
1139
|
+
const workflowImports = workflowsWithCode.length > 0
|
|
1140
|
+
? workflowsWithCode
|
|
1141
|
+
.map((w) => `import { ${w.functionName} } from './workflows/${w.name}.js';`)
|
|
1142
|
+
.join('\n')
|
|
1143
|
+
: '// No workflows';
|
|
1144
|
+
// Generate all node type imports (both exposed and bundled-only) with aliases for collisions - only for those with code
|
|
1145
|
+
// Use lowercase functionName for import paths to match the generated file names
|
|
1146
|
+
const nodeTypeImports = nodeTypesWithCode.length > 0
|
|
1147
|
+
? nodeTypesWithCode
|
|
1148
|
+
.map((nt) => {
|
|
1149
|
+
const alias = nodeTypeAliases.get(nt.functionName);
|
|
1150
|
+
const lowerFunctionName = nt.functionName.toLowerCase();
|
|
1151
|
+
if (alias) {
|
|
1152
|
+
return `import { ${nt.functionName} as ${alias} } from './node-types/${lowerFunctionName}.js';`;
|
|
1153
|
+
}
|
|
1154
|
+
return `import { ${nt.functionName} } from './node-types/${lowerFunctionName}.js';`;
|
|
1155
|
+
})
|
|
1156
|
+
.join('\n')
|
|
1157
|
+
: '// No node types';
|
|
1158
|
+
// Filter exposed items to only include those with code
|
|
1159
|
+
const exposedWorkflowsWithCode = exposedWorkflows.filter((w) => w.code);
|
|
1160
|
+
const exposedNodeTypesWithCode = exposedNodeTypes.filter((nt) => nt.code);
|
|
1161
|
+
// Generate entries only for exposed items with code
|
|
1162
|
+
const exposedWorkflowEntries = exposedWorkflowsWithCode.length > 0
|
|
1163
|
+
? exposedWorkflowsWithCode.map((w) => ` '${w.name}': ${w.functionName},`).join('\n')
|
|
1164
|
+
: ' // No exposed workflows';
|
|
1165
|
+
const exposedNodeTypeEntries = exposedNodeTypesWithCode.length > 0
|
|
1166
|
+
? exposedNodeTypesWithCode
|
|
1167
|
+
.map((nt) => {
|
|
1168
|
+
const alias = nodeTypeAliases.get(nt.functionName);
|
|
1169
|
+
return ` '${nt.name}': ${alias || nt.functionName},`;
|
|
1170
|
+
})
|
|
1171
|
+
.join('\n')
|
|
1172
|
+
: ' // No exposed node types';
|
|
1173
|
+
// Generate bundle handler
|
|
1174
|
+
const handlerContent = LAMBDA_BUNDLE_HANDLER_TEMPLATE
|
|
1175
|
+
.replace('{{GENERATED_HEADER}}', getGeneratedBranding().header('export --target lambda --bundle'))
|
|
1176
|
+
.replace('{{WORKFLOW_IMPORTS}}', workflowImports)
|
|
1177
|
+
.replace('{{NODE_TYPE_IMPORTS}}', nodeTypeImports)
|
|
1178
|
+
.replace('{{EXPOSED_WORKFLOW_ENTRIES}}', exposedWorkflowEntries)
|
|
1179
|
+
.replace('{{EXPOSED_NODE_TYPE_ENTRIES}}', exposedNodeTypeEntries)
|
|
1180
|
+
.replace(/\{\{SERVICE_NAME\}\}/g, serviceName);
|
|
1181
|
+
files.push(this.createFile(options.outputDir, 'handler.ts', handlerContent, 'handler'));
|
|
1182
|
+
// Generate OpenAPI spec for exposed items only
|
|
1183
|
+
const openApiSpec = this.generateBundleOpenAPI(workflows, nodeTypes, {
|
|
1184
|
+
title: `${serviceName} API`,
|
|
1185
|
+
version: '1.0.0',
|
|
1186
|
+
});
|
|
1187
|
+
const openApiContent = `// Generated OpenAPI specification
|
|
1188
|
+
export const openApiSpec = ${JSON.stringify(openApiSpec, null, 2)};
|
|
1189
|
+
`;
|
|
1190
|
+
files.push(this.createFile(options.outputDir, 'openapi.ts', openApiContent, 'config'));
|
|
1191
|
+
// Generate SAM template
|
|
1192
|
+
const samContent = SAM_BUNDLE_TEMPLATE.replace(/\{\{SERVICE_NAME\}\}/g, serviceName)
|
|
1193
|
+
.replace('{{WORKFLOW_COUNT}}', String(workflows.length))
|
|
1194
|
+
.replace('{{NODE_TYPE_COUNT}}', String(nodeTypes.length));
|
|
1195
|
+
files.push(this.createFile(options.outputDir, 'template.yaml', samContent, 'config'));
|
|
1196
|
+
// Collect npm package dependencies from node types (pattern: npm/<package>/<export>)
|
|
1197
|
+
const npmDependencies = {};
|
|
1198
|
+
for (const nt of nodeTypes) {
|
|
1199
|
+
if (nt.name.startsWith('npm/')) {
|
|
1200
|
+
const rest = nt.name.slice(4);
|
|
1201
|
+
let packageName;
|
|
1202
|
+
if (rest.startsWith('@')) {
|
|
1203
|
+
// Scoped package: @scope/package/export
|
|
1204
|
+
const segments = rest.split('/');
|
|
1205
|
+
packageName = `${segments[0]}/${segments[1]}`;
|
|
1206
|
+
}
|
|
1207
|
+
else {
|
|
1208
|
+
packageName = rest.split('/')[0];
|
|
1209
|
+
}
|
|
1210
|
+
npmDependencies[packageName] = '*';
|
|
1211
|
+
}
|
|
1212
|
+
}
|
|
1213
|
+
// Generate package.json
|
|
1214
|
+
const packageJson = this.generatePackageJson({
|
|
1215
|
+
name: serviceName,
|
|
1216
|
+
description: `Bundle service with ${workflows.length} workflows and ${nodeTypes.length} node types`,
|
|
1217
|
+
main: 'handler.js',
|
|
1218
|
+
scripts: {
|
|
1219
|
+
build: 'tsc',
|
|
1220
|
+
deploy: 'sam build && sam deploy --guided',
|
|
1221
|
+
},
|
|
1222
|
+
dependencies: Object.keys(npmDependencies).length > 0 ? npmDependencies : undefined,
|
|
1223
|
+
devDependencies: {
|
|
1224
|
+
'@types/aws-lambda': '^8.10.0',
|
|
1225
|
+
},
|
|
1226
|
+
});
|
|
1227
|
+
files.push(this.createFile(options.outputDir, 'package.json', packageJson, 'package'));
|
|
1228
|
+
// Generate tsconfig.json
|
|
1229
|
+
const tsConfig = this.generateTsConfig({
|
|
1230
|
+
outDir: './dist',
|
|
1231
|
+
module: 'NodeNext',
|
|
1232
|
+
moduleResolution: 'NodeNext',
|
|
1233
|
+
});
|
|
1234
|
+
files.push(this.createFile(options.outputDir, 'tsconfig.json', tsConfig, 'config'));
|
|
1235
|
+
// Generate shared runtime types module (workflows import from this)
|
|
1236
|
+
const isProduction = options.production ?? true;
|
|
1237
|
+
const runtimeTypesContent = generateStandaloneRuntimeModule(isProduction, 'esm');
|
|
1238
|
+
files.push(this.createFile(options.outputDir, 'runtime/types.ts', runtimeTypesContent, 'other'));
|
|
1239
|
+
// Generate real runtime files (function registry, builtin functions, parameter resolver)
|
|
1240
|
+
files.push(...this.generateRuntimeFiles(options.outputDir, workflows, nodeTypes));
|
|
1241
|
+
// Generate workflow and node-type content files
|
|
1242
|
+
files.push(...this.generateBundleContentFiles(workflows, nodeTypes, options.outputDir));
|
|
1243
|
+
return {
|
|
1244
|
+
files,
|
|
1245
|
+
target: this.name,
|
|
1246
|
+
workflowName: serviceName,
|
|
1247
|
+
workflowNames: workflows.map((w) => w.name),
|
|
1248
|
+
nodeTypeNames: nodeTypes.map((nt) => nt.name),
|
|
1249
|
+
entryPoint: 'handler.ts',
|
|
1250
|
+
openApiSpec,
|
|
1251
|
+
};
|
|
1252
|
+
}
|
|
1253
|
+
getDeployInstructions(artifacts) {
|
|
1254
|
+
const outputDir = artifacts.files[0]?.absolutePath
|
|
1255
|
+
? artifacts.files[0].absolutePath.replace(/\/[^/]+$/, '')
|
|
1256
|
+
: '.';
|
|
1257
|
+
return {
|
|
1258
|
+
title: 'Deploy to AWS Lambda',
|
|
1259
|
+
prerequisites: [
|
|
1260
|
+
'AWS CLI configured with credentials',
|
|
1261
|
+
'AWS SAM CLI installed (https://aws.amazon.com/serverless/sam/)',
|
|
1262
|
+
],
|
|
1263
|
+
steps: [
|
|
1264
|
+
`cd ${outputDir}`,
|
|
1265
|
+
'npm install',
|
|
1266
|
+
'npm run build',
|
|
1267
|
+
'sam build && sam deploy --guided',
|
|
1268
|
+
],
|
|
1269
|
+
localTestSteps: [
|
|
1270
|
+
`cd ${outputDir}`,
|
|
1271
|
+
'npm install',
|
|
1272
|
+
'npm run dev',
|
|
1273
|
+
'# API will be available at http://127.0.0.1:3000',
|
|
1274
|
+
'# Test with: curl -X POST http://127.0.0.1:3000/{endpoint} -H "Content-Type: application/json" -d \'{"key": "value"}\'',
|
|
1275
|
+
],
|
|
1276
|
+
links: [
|
|
1277
|
+
{
|
|
1278
|
+
label: 'AWS SAM Documentation',
|
|
1279
|
+
url: 'https://docs.aws.amazon.com/serverless-application-model/',
|
|
1280
|
+
},
|
|
1281
|
+
{
|
|
1282
|
+
label: 'AWS Lambda Pricing',
|
|
1283
|
+
url: 'https://aws.amazon.com/lambda/pricing/',
|
|
1284
|
+
},
|
|
1285
|
+
],
|
|
1286
|
+
};
|
|
1287
|
+
}
|
|
1288
|
+
}
|
|
1289
|
+
//# sourceMappingURL=lambda.js.map
|