@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,1125 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Cloudflare Workers export target
|
|
3
|
+
*
|
|
4
|
+
* Generates Cloudflare Workers with Wrangler configuration.
|
|
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 Cloudflare Workers - Basic version
|
|
11
|
+
*/
|
|
12
|
+
const CLOUDFLARE_HANDLER_TEMPLATE = `{{GENERATED_HEADER}}
|
|
13
|
+
{{WORKFLOW_IMPORT}}
|
|
14
|
+
|
|
15
|
+
interface Env {
|
|
16
|
+
// Add your bindings here (D1, KV, R2, etc.)
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
export default {
|
|
20
|
+
async fetch(request: Request, env: Env): Promise<Response> {
|
|
21
|
+
// Only allow POST requests
|
|
22
|
+
if (request.method !== 'POST') {
|
|
23
|
+
return new Response(JSON.stringify({
|
|
24
|
+
success: false,
|
|
25
|
+
error: { code: 'METHOD_NOT_ALLOWED', message: 'Only POST requests are allowed' },
|
|
26
|
+
}), {
|
|
27
|
+
status: 405,
|
|
28
|
+
headers: { 'Content-Type': 'application/json' },
|
|
29
|
+
});
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
const requestId = request.headers.get('cf-ray') || crypto.randomUUID();
|
|
33
|
+
|
|
34
|
+
try {
|
|
35
|
+
const body = await request.json() as Record<string, unknown>;
|
|
36
|
+
const startTime = performance.now();
|
|
37
|
+
|
|
38
|
+
const result = await {{FUNCTION_NAME}}(true, body);
|
|
39
|
+
|
|
40
|
+
return new Response(JSON.stringify({
|
|
41
|
+
success: true,
|
|
42
|
+
result,
|
|
43
|
+
executionTime: Math.round(performance.now() - startTime),
|
|
44
|
+
requestId,
|
|
45
|
+
}), {
|
|
46
|
+
status: 200,
|
|
47
|
+
headers: {
|
|
48
|
+
'Content-Type': 'application/json',
|
|
49
|
+
'X-Request-Id': requestId,
|
|
50
|
+
'X-Execution-Time': \`\${Math.round(performance.now() - startTime)}ms\`,
|
|
51
|
+
},
|
|
52
|
+
});
|
|
53
|
+
} catch (error) {
|
|
54
|
+
return new Response(JSON.stringify({
|
|
55
|
+
success: false,
|
|
56
|
+
error: {
|
|
57
|
+
code: 'EXECUTION_ERROR',
|
|
58
|
+
message: error instanceof Error ? error.message : String(error),
|
|
59
|
+
},
|
|
60
|
+
requestId,
|
|
61
|
+
}), {
|
|
62
|
+
status: 500,
|
|
63
|
+
headers: {
|
|
64
|
+
'Content-Type': 'application/json',
|
|
65
|
+
'X-Request-Id': requestId,
|
|
66
|
+
},
|
|
67
|
+
});
|
|
68
|
+
}
|
|
69
|
+
},
|
|
70
|
+
} satisfies ExportedHandler<Env>;
|
|
71
|
+
`;
|
|
72
|
+
/**
|
|
73
|
+
* Handler template for Cloudflare Workers with API documentation
|
|
74
|
+
*/
|
|
75
|
+
const CLOUDFLARE_HANDLER_WITH_DOCS_TEMPLATE = `{{GENERATED_HEADER}}
|
|
76
|
+
{{WORKFLOW_IMPORT}}
|
|
77
|
+
import { openApiSpec } from './openapi.js';
|
|
78
|
+
|
|
79
|
+
interface Env {
|
|
80
|
+
// Add your bindings here (D1, KV, R2, etc.)
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
const SWAGGER_UI_HTML = \`<!DOCTYPE html>
|
|
84
|
+
<html lang="en">
|
|
85
|
+
<head>
|
|
86
|
+
<meta charset="UTF-8">
|
|
87
|
+
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
88
|
+
<title>{{WORKFLOW_NAME}} API Documentation</title>
|
|
89
|
+
<link rel="stylesheet" href="https://unpkg.com/swagger-ui-dist@5/swagger-ui.css">
|
|
90
|
+
</head>
|
|
91
|
+
<body>
|
|
92
|
+
<div id="swagger-ui"></div>
|
|
93
|
+
<script src="https://unpkg.com/swagger-ui-dist@5/swagger-ui-bundle.js"></script>
|
|
94
|
+
<script>
|
|
95
|
+
SwaggerUIBundle({
|
|
96
|
+
url: '/openapi.json',
|
|
97
|
+
dom_id: '#swagger-ui',
|
|
98
|
+
presets: [SwaggerUIBundle.presets.apis, SwaggerUIBundle.SwaggerUIStandalonePreset],
|
|
99
|
+
layout: 'BaseLayout'
|
|
100
|
+
});
|
|
101
|
+
</script>
|
|
102
|
+
</body>
|
|
103
|
+
</html>\`;
|
|
104
|
+
|
|
105
|
+
export default {
|
|
106
|
+
async fetch(request: Request, env: Env): Promise<Response> {
|
|
107
|
+
const url = new URL(request.url);
|
|
108
|
+
const path = url.pathname;
|
|
109
|
+
const method = request.method;
|
|
110
|
+
|
|
111
|
+
// Serve OpenAPI spec
|
|
112
|
+
if (path === '/openapi.json' && method === 'GET') {
|
|
113
|
+
return new Response(JSON.stringify(openApiSpec), {
|
|
114
|
+
status: 200,
|
|
115
|
+
headers: { 'Content-Type': 'application/json' },
|
|
116
|
+
});
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
// Serve Swagger UI
|
|
120
|
+
if (path === '/docs' && method === 'GET') {
|
|
121
|
+
return new Response(SWAGGER_UI_HTML, {
|
|
122
|
+
status: 200,
|
|
123
|
+
headers: { 'Content-Type': 'text/html' },
|
|
124
|
+
});
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
// Only allow POST requests for workflow execution
|
|
128
|
+
if (method !== 'POST') {
|
|
129
|
+
return new Response(JSON.stringify({
|
|
130
|
+
success: false,
|
|
131
|
+
error: { code: 'METHOD_NOT_ALLOWED', message: 'Only POST requests are allowed for workflow execution' },
|
|
132
|
+
}), {
|
|
133
|
+
status: 405,
|
|
134
|
+
headers: { 'Content-Type': 'application/json' },
|
|
135
|
+
});
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
const requestId = request.headers.get('cf-ray') || crypto.randomUUID();
|
|
139
|
+
|
|
140
|
+
try {
|
|
141
|
+
const body = await request.json() as Record<string, unknown>;
|
|
142
|
+
const startTime = performance.now();
|
|
143
|
+
|
|
144
|
+
const result = await {{FUNCTION_NAME}}(true, body);
|
|
145
|
+
|
|
146
|
+
return new Response(JSON.stringify({
|
|
147
|
+
success: true,
|
|
148
|
+
result,
|
|
149
|
+
executionTime: Math.round(performance.now() - startTime),
|
|
150
|
+
requestId,
|
|
151
|
+
}), {
|
|
152
|
+
status: 200,
|
|
153
|
+
headers: {
|
|
154
|
+
'Content-Type': 'application/json',
|
|
155
|
+
'X-Request-Id': requestId,
|
|
156
|
+
'X-Execution-Time': \`\${Math.round(performance.now() - startTime)}ms\`,
|
|
157
|
+
},
|
|
158
|
+
});
|
|
159
|
+
} catch (error) {
|
|
160
|
+
return new Response(JSON.stringify({
|
|
161
|
+
success: false,
|
|
162
|
+
error: {
|
|
163
|
+
code: 'EXECUTION_ERROR',
|
|
164
|
+
message: error instanceof Error ? error.message : String(error),
|
|
165
|
+
},
|
|
166
|
+
requestId,
|
|
167
|
+
}), {
|
|
168
|
+
status: 500,
|
|
169
|
+
headers: {
|
|
170
|
+
'Content-Type': 'application/json',
|
|
171
|
+
'X-Request-Id': requestId,
|
|
172
|
+
},
|
|
173
|
+
});
|
|
174
|
+
}
|
|
175
|
+
},
|
|
176
|
+
} satisfies ExportedHandler<Env>;
|
|
177
|
+
`;
|
|
178
|
+
/**
|
|
179
|
+
* OpenAPI spec file template
|
|
180
|
+
*/
|
|
181
|
+
const OPENAPI_SPEC_TEMPLATE = `// Generated OpenAPI specification
|
|
182
|
+
export const openApiSpec = {{OPENAPI_SPEC}};
|
|
183
|
+
`;
|
|
184
|
+
/**
|
|
185
|
+
* Wrangler configuration template
|
|
186
|
+
*/
|
|
187
|
+
const WRANGLER_TEMPLATE = `name = "{{WORKFLOW_NAME}}"
|
|
188
|
+
main = "dist/index.js"
|
|
189
|
+
compatibility_date = "2024-01-01"
|
|
190
|
+
|
|
191
|
+
[build]
|
|
192
|
+
command = "npm run build"
|
|
193
|
+
`;
|
|
194
|
+
/**
|
|
195
|
+
* Node type handler template for Cloudflare Workers
|
|
196
|
+
*/
|
|
197
|
+
const CLOUDFLARE_NODE_TYPE_HANDLER_TEMPLATE = `{{GENERATED_HEADER}}
|
|
198
|
+
{{NODE_TYPE_IMPORTS}}
|
|
199
|
+
import { openApiSpec } from './openapi.js';
|
|
200
|
+
|
|
201
|
+
interface Env {
|
|
202
|
+
// Add your bindings here (D1, KV, R2, etc.)
|
|
203
|
+
}
|
|
204
|
+
|
|
205
|
+
// Handler type for node type functions
|
|
206
|
+
type NodeTypeHandler = (execute: boolean, params: Record<string, unknown>) => unknown;
|
|
207
|
+
|
|
208
|
+
// Node type router
|
|
209
|
+
const nodeTypes: Record<string, NodeTypeHandler> = {
|
|
210
|
+
{{NODE_TYPE_ENTRIES}}
|
|
211
|
+
};
|
|
212
|
+
|
|
213
|
+
const SWAGGER_UI_HTML = \`<!DOCTYPE html>
|
|
214
|
+
<html lang="en">
|
|
215
|
+
<head>
|
|
216
|
+
<meta charset="UTF-8">
|
|
217
|
+
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
218
|
+
<title>{{SERVICE_NAME}} API Documentation</title>
|
|
219
|
+
<link rel="stylesheet" href="https://unpkg.com/swagger-ui-dist@5/swagger-ui.css">
|
|
220
|
+
</head>
|
|
221
|
+
<body>
|
|
222
|
+
<div id="swagger-ui"></div>
|
|
223
|
+
<script src="https://unpkg.com/swagger-ui-dist@5/swagger-ui-bundle.js"></script>
|
|
224
|
+
<script>
|
|
225
|
+
SwaggerUIBundle({
|
|
226
|
+
url: '/api/openapi.json',
|
|
227
|
+
dom_id: '#swagger-ui',
|
|
228
|
+
presets: [SwaggerUIBundle.presets.apis, SwaggerUIBundle.SwaggerUIStandalonePreset],
|
|
229
|
+
layout: 'BaseLayout'
|
|
230
|
+
});
|
|
231
|
+
</script>
|
|
232
|
+
</body>
|
|
233
|
+
</html>\`;
|
|
234
|
+
|
|
235
|
+
export default {
|
|
236
|
+
async fetch(request: Request, env: Env): Promise<Response> {
|
|
237
|
+
const url = new URL(request.url);
|
|
238
|
+
const path = url.pathname;
|
|
239
|
+
const method = request.method;
|
|
240
|
+
|
|
241
|
+
// Serve OpenAPI spec
|
|
242
|
+
if (path === '/api/openapi.json' && method === 'GET') {
|
|
243
|
+
return new Response(JSON.stringify(openApiSpec), {
|
|
244
|
+
status: 200,
|
|
245
|
+
headers: { 'Content-Type': 'application/json' },
|
|
246
|
+
});
|
|
247
|
+
}
|
|
248
|
+
|
|
249
|
+
// Serve Swagger UI
|
|
250
|
+
if (path === '/api/docs' && method === 'GET') {
|
|
251
|
+
return new Response(SWAGGER_UI_HTML, {
|
|
252
|
+
status: 200,
|
|
253
|
+
headers: { 'Content-Type': 'text/html' },
|
|
254
|
+
});
|
|
255
|
+
}
|
|
256
|
+
|
|
257
|
+
// Route to node type
|
|
258
|
+
const nodeTypeMatch = path.match(/^\\/api\\/([^\\/]+)$/);
|
|
259
|
+
if (!nodeTypeMatch) {
|
|
260
|
+
return new Response(JSON.stringify({ error: 'Not found' }), {
|
|
261
|
+
status: 404,
|
|
262
|
+
headers: { 'Content-Type': 'application/json' },
|
|
263
|
+
});
|
|
264
|
+
}
|
|
265
|
+
|
|
266
|
+
const nodeTypeName = nodeTypeMatch[1];
|
|
267
|
+
const nodeType = nodeTypes[nodeTypeName];
|
|
268
|
+
|
|
269
|
+
if (!nodeType) {
|
|
270
|
+
return new Response(JSON.stringify({
|
|
271
|
+
error: \`Node type '\${nodeTypeName}' not found\`,
|
|
272
|
+
availableNodeTypes: Object.keys(nodeTypes),
|
|
273
|
+
}), {
|
|
274
|
+
status: 404,
|
|
275
|
+
headers: { 'Content-Type': 'application/json' },
|
|
276
|
+
});
|
|
277
|
+
}
|
|
278
|
+
|
|
279
|
+
// Only POST for node type execution
|
|
280
|
+
if (method !== 'POST') {
|
|
281
|
+
return new Response(JSON.stringify({
|
|
282
|
+
success: false,
|
|
283
|
+
error: { code: 'METHOD_NOT_ALLOWED', message: 'Only POST requests are allowed for node type execution' },
|
|
284
|
+
}), {
|
|
285
|
+
status: 405,
|
|
286
|
+
headers: { 'Content-Type': 'application/json' },
|
|
287
|
+
});
|
|
288
|
+
}
|
|
289
|
+
|
|
290
|
+
const requestId = request.headers.get('cf-ray') || crypto.randomUUID();
|
|
291
|
+
|
|
292
|
+
try {
|
|
293
|
+
const body = await request.json() as Record<string, unknown>;
|
|
294
|
+
const startTime = performance.now();
|
|
295
|
+
|
|
296
|
+
const result = await nodeType(true, body);
|
|
297
|
+
|
|
298
|
+
return new Response(JSON.stringify({
|
|
299
|
+
success: true,
|
|
300
|
+
result,
|
|
301
|
+
executionTime: Math.round(performance.now() - startTime),
|
|
302
|
+
requestId,
|
|
303
|
+
}), {
|
|
304
|
+
status: 200,
|
|
305
|
+
headers: {
|
|
306
|
+
'Content-Type': 'application/json',
|
|
307
|
+
'X-Request-Id': requestId,
|
|
308
|
+
'X-Execution-Time': \`\${Math.round(performance.now() - startTime)}ms\`,
|
|
309
|
+
},
|
|
310
|
+
});
|
|
311
|
+
} catch (error) {
|
|
312
|
+
return new Response(JSON.stringify({
|
|
313
|
+
success: false,
|
|
314
|
+
error: {
|
|
315
|
+
code: 'EXECUTION_ERROR',
|
|
316
|
+
message: error instanceof Error ? error.message : String(error),
|
|
317
|
+
},
|
|
318
|
+
requestId,
|
|
319
|
+
}), {
|
|
320
|
+
status: 500,
|
|
321
|
+
headers: {
|
|
322
|
+
'Content-Type': 'application/json',
|
|
323
|
+
'X-Request-Id': requestId,
|
|
324
|
+
},
|
|
325
|
+
});
|
|
326
|
+
}
|
|
327
|
+
},
|
|
328
|
+
} satisfies ExportedHandler<Env>;
|
|
329
|
+
`;
|
|
330
|
+
/**
|
|
331
|
+
* Multi-workflow handler template for Cloudflare Workers
|
|
332
|
+
*/
|
|
333
|
+
const CLOUDFLARE_MULTI_HANDLER_TEMPLATE = `{{GENERATED_HEADER}}
|
|
334
|
+
{{WORKFLOW_IMPORTS}}
|
|
335
|
+
import { functionRegistry } from './runtime/function-registry.js';
|
|
336
|
+
import './runtime/builtin-functions.js';
|
|
337
|
+
import { openApiSpec } from './openapi.js';
|
|
338
|
+
|
|
339
|
+
interface Env {
|
|
340
|
+
// Add your bindings here (D1, KV, R2, etc.)
|
|
341
|
+
}
|
|
342
|
+
|
|
343
|
+
// Handler type for workflow functions
|
|
344
|
+
type WorkflowHandler = (execute: boolean, params: Record<string, unknown>) => unknown;
|
|
345
|
+
|
|
346
|
+
// Workflow router
|
|
347
|
+
const workflows: Record<string, WorkflowHandler> = {
|
|
348
|
+
{{WORKFLOW_ENTRIES}}
|
|
349
|
+
};
|
|
350
|
+
|
|
351
|
+
const SWAGGER_UI_HTML = \`<!DOCTYPE html>
|
|
352
|
+
<html lang="en">
|
|
353
|
+
<head>
|
|
354
|
+
<meta charset="UTF-8">
|
|
355
|
+
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
356
|
+
<title>{{SERVICE_NAME}} API Documentation</title>
|
|
357
|
+
<link rel="stylesheet" href="https://unpkg.com/swagger-ui-dist@5/swagger-ui.css">
|
|
358
|
+
</head>
|
|
359
|
+
<body>
|
|
360
|
+
<div id="swagger-ui"></div>
|
|
361
|
+
<script src="https://unpkg.com/swagger-ui-dist@5/swagger-ui-bundle.js"></script>
|
|
362
|
+
<script>
|
|
363
|
+
SwaggerUIBundle({
|
|
364
|
+
url: '/api/openapi.json',
|
|
365
|
+
dom_id: '#swagger-ui',
|
|
366
|
+
presets: [SwaggerUIBundle.presets.apis, SwaggerUIBundle.SwaggerUIStandalonePreset],
|
|
367
|
+
layout: 'BaseLayout'
|
|
368
|
+
});
|
|
369
|
+
</script>
|
|
370
|
+
</body>
|
|
371
|
+
</html>\`;
|
|
372
|
+
|
|
373
|
+
export default {
|
|
374
|
+
async fetch(request: Request, env: Env): Promise<Response> {
|
|
375
|
+
const url = new URL(request.url);
|
|
376
|
+
const path = url.pathname;
|
|
377
|
+
const method = request.method;
|
|
378
|
+
|
|
379
|
+
// Serve OpenAPI spec
|
|
380
|
+
if (path === '/api/openapi.json' && method === 'GET') {
|
|
381
|
+
return new Response(JSON.stringify(openApiSpec), {
|
|
382
|
+
status: 200,
|
|
383
|
+
headers: { 'Content-Type': 'application/json' },
|
|
384
|
+
});
|
|
385
|
+
}
|
|
386
|
+
|
|
387
|
+
// Serve Swagger UI
|
|
388
|
+
if (path === '/api/docs' && method === 'GET') {
|
|
389
|
+
return new Response(SWAGGER_UI_HTML, {
|
|
390
|
+
status: 200,
|
|
391
|
+
headers: { 'Content-Type': 'text/html' },
|
|
392
|
+
});
|
|
393
|
+
}
|
|
394
|
+
|
|
395
|
+
// List available functions
|
|
396
|
+
if (path === '/api/functions' && method === 'GET') {
|
|
397
|
+
const category = url.searchParams.get('category');
|
|
398
|
+
const functions = functionRegistry.list(category as any);
|
|
399
|
+
return new Response(JSON.stringify(functions), {
|
|
400
|
+
status: 200,
|
|
401
|
+
headers: { 'Content-Type': 'application/json' },
|
|
402
|
+
});
|
|
403
|
+
}
|
|
404
|
+
|
|
405
|
+
// Route to workflow
|
|
406
|
+
const workflowMatch = path.match(/^\\/api\\/([^\\/]+)$/);
|
|
407
|
+
if (!workflowMatch) {
|
|
408
|
+
return new Response(JSON.stringify({ error: 'Not found' }), {
|
|
409
|
+
status: 404,
|
|
410
|
+
headers: { 'Content-Type': 'application/json' },
|
|
411
|
+
});
|
|
412
|
+
}
|
|
413
|
+
|
|
414
|
+
const workflowName = workflowMatch[1];
|
|
415
|
+
const workflow = workflows[workflowName];
|
|
416
|
+
|
|
417
|
+
if (!workflow) {
|
|
418
|
+
return new Response(JSON.stringify({
|
|
419
|
+
error: \`Workflow '\${workflowName}' not found\`,
|
|
420
|
+
availableWorkflows: Object.keys(workflows),
|
|
421
|
+
}), {
|
|
422
|
+
status: 404,
|
|
423
|
+
headers: { 'Content-Type': 'application/json' },
|
|
424
|
+
});
|
|
425
|
+
}
|
|
426
|
+
|
|
427
|
+
// Only POST for workflow execution
|
|
428
|
+
if (method !== 'POST') {
|
|
429
|
+
return new Response(JSON.stringify({
|
|
430
|
+
success: false,
|
|
431
|
+
error: { code: 'METHOD_NOT_ALLOWED', message: 'Only POST requests are allowed for workflow execution' },
|
|
432
|
+
}), {
|
|
433
|
+
status: 405,
|
|
434
|
+
headers: { 'Content-Type': 'application/json' },
|
|
435
|
+
});
|
|
436
|
+
}
|
|
437
|
+
|
|
438
|
+
const requestId = request.headers.get('cf-ray') || crypto.randomUUID();
|
|
439
|
+
|
|
440
|
+
try {
|
|
441
|
+
const body = await request.json() as Record<string, unknown>;
|
|
442
|
+
const startTime = performance.now();
|
|
443
|
+
|
|
444
|
+
const result = await workflow(true, body);
|
|
445
|
+
|
|
446
|
+
return new Response(JSON.stringify({
|
|
447
|
+
success: true,
|
|
448
|
+
result,
|
|
449
|
+
executionTime: Math.round(performance.now() - startTime),
|
|
450
|
+
requestId,
|
|
451
|
+
}), {
|
|
452
|
+
status: 200,
|
|
453
|
+
headers: {
|
|
454
|
+
'Content-Type': 'application/json',
|
|
455
|
+
'X-Request-Id': requestId,
|
|
456
|
+
'X-Execution-Time': \`\${Math.round(performance.now() - startTime)}ms\`,
|
|
457
|
+
},
|
|
458
|
+
});
|
|
459
|
+
} catch (error) {
|
|
460
|
+
return new Response(JSON.stringify({
|
|
461
|
+
success: false,
|
|
462
|
+
error: {
|
|
463
|
+
code: 'EXECUTION_ERROR',
|
|
464
|
+
message: error instanceof Error ? error.message : String(error),
|
|
465
|
+
},
|
|
466
|
+
requestId,
|
|
467
|
+
}), {
|
|
468
|
+
status: 500,
|
|
469
|
+
headers: {
|
|
470
|
+
'Content-Type': 'application/json',
|
|
471
|
+
'X-Request-Id': requestId,
|
|
472
|
+
},
|
|
473
|
+
});
|
|
474
|
+
}
|
|
475
|
+
},
|
|
476
|
+
} satisfies ExportedHandler<Env>;
|
|
477
|
+
`;
|
|
478
|
+
/**
|
|
479
|
+
* Bundle handler template for Cloudflare Workers - unified workflows and node types
|
|
480
|
+
*/
|
|
481
|
+
const CLOUDFLARE_BUNDLE_HANDLER_TEMPLATE = `{{GENERATED_HEADER}}
|
|
482
|
+
{{WORKFLOW_IMPORTS}}
|
|
483
|
+
{{NODE_TYPE_IMPORTS}}
|
|
484
|
+
import { functionRegistry } from './runtime/function-registry.js';
|
|
485
|
+
import './runtime/builtin-functions.js';
|
|
486
|
+
import { openApiSpec } from './openapi.js';
|
|
487
|
+
|
|
488
|
+
interface Env {
|
|
489
|
+
// Add your bindings here (D1, KV, R2, etc.)
|
|
490
|
+
}
|
|
491
|
+
|
|
492
|
+
// Handler type for workflow/nodeType functions
|
|
493
|
+
type FunctionHandler = (execute: boolean, params: Record<string, unknown>) => unknown;
|
|
494
|
+
|
|
495
|
+
// Exposed workflows (have HTTP endpoints)
|
|
496
|
+
const exposedWorkflows: Record<string, FunctionHandler> = {
|
|
497
|
+
{{EXPOSED_WORKFLOW_ENTRIES}}
|
|
498
|
+
};
|
|
499
|
+
|
|
500
|
+
// Exposed node types (have HTTP endpoints)
|
|
501
|
+
const exposedNodeTypes: Record<string, FunctionHandler> = {
|
|
502
|
+
{{EXPOSED_NODE_TYPE_ENTRIES}}
|
|
503
|
+
};
|
|
504
|
+
|
|
505
|
+
const SWAGGER_UI_HTML = \`<!DOCTYPE html>
|
|
506
|
+
<html lang="en">
|
|
507
|
+
<head>
|
|
508
|
+
<meta charset="UTF-8">
|
|
509
|
+
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
510
|
+
<title>{{SERVICE_NAME}} API Documentation</title>
|
|
511
|
+
<link rel="stylesheet" href="https://unpkg.com/swagger-ui-dist@5/swagger-ui.css">
|
|
512
|
+
</head>
|
|
513
|
+
<body>
|
|
514
|
+
<div id="swagger-ui"></div>
|
|
515
|
+
<script src="https://unpkg.com/swagger-ui-dist@5/swagger-ui-bundle.js"></script>
|
|
516
|
+
<script>
|
|
517
|
+
SwaggerUIBundle({
|
|
518
|
+
url: '/api/openapi.json',
|
|
519
|
+
dom_id: '#swagger-ui',
|
|
520
|
+
presets: [SwaggerUIBundle.presets.apis, SwaggerUIBundle.SwaggerUIStandalonePreset],
|
|
521
|
+
layout: 'BaseLayout'
|
|
522
|
+
});
|
|
523
|
+
</script>
|
|
524
|
+
</body>
|
|
525
|
+
</html>\`;
|
|
526
|
+
|
|
527
|
+
export default {
|
|
528
|
+
async fetch(request: Request, env: Env): Promise<Response> {
|
|
529
|
+
const url = new URL(request.url);
|
|
530
|
+
const path = url.pathname;
|
|
531
|
+
const method = request.method;
|
|
532
|
+
|
|
533
|
+
// Serve OpenAPI spec
|
|
534
|
+
if (path === '/api/openapi.json' && method === 'GET') {
|
|
535
|
+
return new Response(JSON.stringify(openApiSpec), {
|
|
536
|
+
status: 200,
|
|
537
|
+
headers: { 'Content-Type': 'application/json' },
|
|
538
|
+
});
|
|
539
|
+
}
|
|
540
|
+
|
|
541
|
+
// Serve Swagger UI
|
|
542
|
+
if (path === '/api/docs' && method === 'GET') {
|
|
543
|
+
return new Response(SWAGGER_UI_HTML, {
|
|
544
|
+
status: 200,
|
|
545
|
+
headers: { 'Content-Type': 'text/html' },
|
|
546
|
+
});
|
|
547
|
+
}
|
|
548
|
+
|
|
549
|
+
// List available functions
|
|
550
|
+
if (path === '/api/functions' && method === 'GET') {
|
|
551
|
+
const category = url.searchParams.get('category');
|
|
552
|
+
const functions = functionRegistry.list(category as any);
|
|
553
|
+
return new Response(JSON.stringify(functions), {
|
|
554
|
+
status: 200,
|
|
555
|
+
headers: { 'Content-Type': 'application/json' },
|
|
556
|
+
});
|
|
557
|
+
}
|
|
558
|
+
|
|
559
|
+
// Route to workflow: /api/workflows/{name}
|
|
560
|
+
const workflowMatch = path.match(/^\\/api\\/workflows\\/([^\\/]+)$/);
|
|
561
|
+
if (workflowMatch) {
|
|
562
|
+
const workflowName = workflowMatch[1];
|
|
563
|
+
const workflow = exposedWorkflows[workflowName];
|
|
564
|
+
|
|
565
|
+
if (!workflow) {
|
|
566
|
+
return new Response(JSON.stringify({
|
|
567
|
+
error: \`Workflow '\${workflowName}' not found\`,
|
|
568
|
+
availableWorkflows: Object.keys(exposedWorkflows),
|
|
569
|
+
}), {
|
|
570
|
+
status: 404,
|
|
571
|
+
headers: { 'Content-Type': 'application/json' },
|
|
572
|
+
});
|
|
573
|
+
}
|
|
574
|
+
|
|
575
|
+
if (method !== 'POST') {
|
|
576
|
+
return new Response(JSON.stringify({
|
|
577
|
+
success: false,
|
|
578
|
+
error: { code: 'METHOD_NOT_ALLOWED', message: 'Only POST requests are allowed for workflow execution' },
|
|
579
|
+
}), {
|
|
580
|
+
status: 405,
|
|
581
|
+
headers: { 'Content-Type': 'application/json' },
|
|
582
|
+
});
|
|
583
|
+
}
|
|
584
|
+
|
|
585
|
+
const requestId = request.headers.get('cf-ray') || crypto.randomUUID();
|
|
586
|
+
|
|
587
|
+
try {
|
|
588
|
+
const body = await request.json() as Record<string, unknown>;
|
|
589
|
+
const startTime = performance.now();
|
|
590
|
+
|
|
591
|
+
const result = await workflow(true, body);
|
|
592
|
+
|
|
593
|
+
return new Response(JSON.stringify({
|
|
594
|
+
success: true,
|
|
595
|
+
result,
|
|
596
|
+
executionTime: Math.round(performance.now() - startTime),
|
|
597
|
+
requestId,
|
|
598
|
+
}), {
|
|
599
|
+
status: 200,
|
|
600
|
+
headers: {
|
|
601
|
+
'Content-Type': 'application/json',
|
|
602
|
+
'X-Request-Id': requestId,
|
|
603
|
+
'X-Execution-Time': \`\${Math.round(performance.now() - startTime)}ms\`,
|
|
604
|
+
},
|
|
605
|
+
});
|
|
606
|
+
} catch (error) {
|
|
607
|
+
return new Response(JSON.stringify({
|
|
608
|
+
success: false,
|
|
609
|
+
error: { code: 'EXECUTION_ERROR', message: error instanceof Error ? error.message : String(error) },
|
|
610
|
+
requestId,
|
|
611
|
+
}), {
|
|
612
|
+
status: 500,
|
|
613
|
+
headers: { 'Content-Type': 'application/json', 'X-Request-Id': requestId },
|
|
614
|
+
});
|
|
615
|
+
}
|
|
616
|
+
}
|
|
617
|
+
|
|
618
|
+
// Route to node type: /api/nodes/{name}
|
|
619
|
+
const nodeTypeMatch = path.match(/^\\/api\\/nodes\\/([^\\/]+)$/);
|
|
620
|
+
if (nodeTypeMatch) {
|
|
621
|
+
const nodeTypeName = nodeTypeMatch[1];
|
|
622
|
+
const nodeType = exposedNodeTypes[nodeTypeName];
|
|
623
|
+
|
|
624
|
+
if (!nodeType) {
|
|
625
|
+
return new Response(JSON.stringify({
|
|
626
|
+
error: \`Node type '\${nodeTypeName}' not found\`,
|
|
627
|
+
availableNodeTypes: Object.keys(exposedNodeTypes),
|
|
628
|
+
}), {
|
|
629
|
+
status: 404,
|
|
630
|
+
headers: { 'Content-Type': 'application/json' },
|
|
631
|
+
});
|
|
632
|
+
}
|
|
633
|
+
|
|
634
|
+
if (method !== 'POST') {
|
|
635
|
+
return new Response(JSON.stringify({
|
|
636
|
+
success: false,
|
|
637
|
+
error: { code: 'METHOD_NOT_ALLOWED', message: 'Only POST requests are allowed for node type execution' },
|
|
638
|
+
}), {
|
|
639
|
+
status: 405,
|
|
640
|
+
headers: { 'Content-Type': 'application/json' },
|
|
641
|
+
});
|
|
642
|
+
}
|
|
643
|
+
|
|
644
|
+
const requestId = request.headers.get('cf-ray') || crypto.randomUUID();
|
|
645
|
+
|
|
646
|
+
try {
|
|
647
|
+
const body = await request.json() as Record<string, unknown>;
|
|
648
|
+
const startTime = performance.now();
|
|
649
|
+
|
|
650
|
+
const result = await nodeType(true, body);
|
|
651
|
+
|
|
652
|
+
return new Response(JSON.stringify({
|
|
653
|
+
success: true,
|
|
654
|
+
result,
|
|
655
|
+
executionTime: Math.round(performance.now() - startTime),
|
|
656
|
+
requestId,
|
|
657
|
+
}), {
|
|
658
|
+
status: 200,
|
|
659
|
+
headers: {
|
|
660
|
+
'Content-Type': 'application/json',
|
|
661
|
+
'X-Request-Id': requestId,
|
|
662
|
+
'X-Execution-Time': \`\${Math.round(performance.now() - startTime)}ms\`,
|
|
663
|
+
},
|
|
664
|
+
});
|
|
665
|
+
} catch (error) {
|
|
666
|
+
return new Response(JSON.stringify({
|
|
667
|
+
success: false,
|
|
668
|
+
error: { code: 'EXECUTION_ERROR', message: error instanceof Error ? error.message : String(error) },
|
|
669
|
+
requestId,
|
|
670
|
+
}), {
|
|
671
|
+
status: 500,
|
|
672
|
+
headers: { 'Content-Type': 'application/json', 'X-Request-Id': requestId },
|
|
673
|
+
});
|
|
674
|
+
}
|
|
675
|
+
}
|
|
676
|
+
|
|
677
|
+
return new Response(JSON.stringify({ error: 'Not found' }), {
|
|
678
|
+
status: 404,
|
|
679
|
+
headers: { 'Content-Type': 'application/json' },
|
|
680
|
+
});
|
|
681
|
+
},
|
|
682
|
+
} satisfies ExportedHandler<Env>;
|
|
683
|
+
`;
|
|
684
|
+
/**
|
|
685
|
+
* Cloudflare Workers export target
|
|
686
|
+
*/
|
|
687
|
+
export class CloudflareTarget extends BaseExportTarget {
|
|
688
|
+
name = 'cloudflare';
|
|
689
|
+
description = 'Cloudflare Workers';
|
|
690
|
+
async generate(options) {
|
|
691
|
+
const files = [];
|
|
692
|
+
const includeDocs = options.includeDocs ?? false;
|
|
693
|
+
// Select appropriate handler template
|
|
694
|
+
const handlerTemplate = includeDocs
|
|
695
|
+
? CLOUDFLARE_HANDLER_WITH_DOCS_TEMPLATE
|
|
696
|
+
: CLOUDFLARE_HANDLER_TEMPLATE;
|
|
697
|
+
// Generate handler
|
|
698
|
+
const handlerContent = handlerTemplate
|
|
699
|
+
.replace('{{GENERATED_HEADER}}', getGeneratedBranding().header('export --target cloudflare'))
|
|
700
|
+
.replace('{{WORKFLOW_IMPORT}}', `import { ${options.workflowName} } from './workflow.js';`)
|
|
701
|
+
.replace(/\{\{FUNCTION_NAME\}\}/g, options.workflowName)
|
|
702
|
+
.replace(/\{\{WORKFLOW_NAME\}\}/g, options.displayName);
|
|
703
|
+
files.push(this.createFile(options.outputDir, 'index.ts', handlerContent, 'handler'));
|
|
704
|
+
// Generate OpenAPI spec file if docs are enabled
|
|
705
|
+
if (includeDocs) {
|
|
706
|
+
const openApiSpec = this.generateOpenAPISpec(options);
|
|
707
|
+
const openApiContent = OPENAPI_SPEC_TEMPLATE.replace('{{OPENAPI_SPEC}}', JSON.stringify(openApiSpec, null, 2));
|
|
708
|
+
files.push(this.createFile(options.outputDir, 'openapi.ts', openApiContent, 'config'));
|
|
709
|
+
}
|
|
710
|
+
// Generate wrangler.toml
|
|
711
|
+
const wranglerContent = WRANGLER_TEMPLATE.replace(/\{\{WORKFLOW_NAME\}\}/g, options.displayName);
|
|
712
|
+
files.push(this.createFile(options.outputDir, 'wrangler.toml', wranglerContent, 'config'));
|
|
713
|
+
// Generate package.json
|
|
714
|
+
const packageJson = this.generatePackageJson({
|
|
715
|
+
name: options.displayName,
|
|
716
|
+
description: options.description,
|
|
717
|
+
main: 'dist/index.js',
|
|
718
|
+
scripts: {
|
|
719
|
+
build: 'tsc',
|
|
720
|
+
dev: 'wrangler dev',
|
|
721
|
+
deploy: 'wrangler deploy',
|
|
722
|
+
},
|
|
723
|
+
devDependencies: {
|
|
724
|
+
'@cloudflare/workers-types': '^4.0.0',
|
|
725
|
+
wrangler: '^3.0.0',
|
|
726
|
+
},
|
|
727
|
+
});
|
|
728
|
+
files.push(this.createFile(options.outputDir, 'package.json', packageJson, 'package'));
|
|
729
|
+
// Generate tsconfig.json
|
|
730
|
+
const tsConfig = this.generateTsConfig({
|
|
731
|
+
outDir: './dist',
|
|
732
|
+
module: 'ESNext',
|
|
733
|
+
moduleResolution: 'Bundler',
|
|
734
|
+
types: ['@cloudflare/workers-types'],
|
|
735
|
+
});
|
|
736
|
+
files.push(this.createFile(options.outputDir, 'tsconfig.json', tsConfig, 'config'));
|
|
737
|
+
// Generate README from deploy instructions
|
|
738
|
+
const artifacts = { files, target: this.name, workflowName: options.displayName, entryPoint: 'index.ts' };
|
|
739
|
+
const instructions = this.getDeployInstructions(artifacts);
|
|
740
|
+
const readme = this.generateReadme(instructions, options.displayName, 'Cloudflare Workers');
|
|
741
|
+
files.push(this.createFile(options.outputDir, 'README.md', readme, 'other'));
|
|
742
|
+
return artifacts;
|
|
743
|
+
}
|
|
744
|
+
/**
|
|
745
|
+
* Generate OpenAPI specification for the workflow
|
|
746
|
+
*/
|
|
747
|
+
generateOpenAPISpec(options) {
|
|
748
|
+
return {
|
|
749
|
+
openapi: '3.0.3',
|
|
750
|
+
info: {
|
|
751
|
+
title: `${options.displayName} API`,
|
|
752
|
+
version: '1.0.0',
|
|
753
|
+
description: options.description || `API for the ${options.displayName} workflow`,
|
|
754
|
+
},
|
|
755
|
+
servers: [{ url: '/', description: 'Cloudflare Worker' }],
|
|
756
|
+
paths: {
|
|
757
|
+
'/': {
|
|
758
|
+
post: {
|
|
759
|
+
operationId: `execute_${options.workflowName}`,
|
|
760
|
+
summary: `Execute ${options.displayName} workflow`,
|
|
761
|
+
description: options.description || `Execute the ${options.displayName} workflow`,
|
|
762
|
+
tags: ['workflows'],
|
|
763
|
+
requestBody: {
|
|
764
|
+
description: 'Workflow input parameters',
|
|
765
|
+
required: true,
|
|
766
|
+
content: {
|
|
767
|
+
'application/json': {
|
|
768
|
+
schema: { type: 'object' },
|
|
769
|
+
},
|
|
770
|
+
},
|
|
771
|
+
},
|
|
772
|
+
responses: {
|
|
773
|
+
'200': {
|
|
774
|
+
description: 'Successful workflow execution',
|
|
775
|
+
content: {
|
|
776
|
+
'application/json': {
|
|
777
|
+
schema: {
|
|
778
|
+
type: 'object',
|
|
779
|
+
properties: {
|
|
780
|
+
success: { type: 'boolean' },
|
|
781
|
+
result: { type: 'object' },
|
|
782
|
+
executionTime: { type: 'number' },
|
|
783
|
+
requestId: { type: 'string' },
|
|
784
|
+
},
|
|
785
|
+
},
|
|
786
|
+
},
|
|
787
|
+
},
|
|
788
|
+
},
|
|
789
|
+
'500': {
|
|
790
|
+
description: 'Execution error',
|
|
791
|
+
content: {
|
|
792
|
+
'application/json': {
|
|
793
|
+
schema: {
|
|
794
|
+
type: 'object',
|
|
795
|
+
properties: {
|
|
796
|
+
success: { type: 'boolean' },
|
|
797
|
+
error: { type: 'object' },
|
|
798
|
+
requestId: { type: 'string' },
|
|
799
|
+
},
|
|
800
|
+
},
|
|
801
|
+
},
|
|
802
|
+
},
|
|
803
|
+
},
|
|
804
|
+
},
|
|
805
|
+
},
|
|
806
|
+
},
|
|
807
|
+
'/docs': {
|
|
808
|
+
get: {
|
|
809
|
+
operationId: 'get_docs',
|
|
810
|
+
summary: 'API Documentation',
|
|
811
|
+
description: 'Swagger UI documentation',
|
|
812
|
+
tags: ['documentation'],
|
|
813
|
+
responses: {
|
|
814
|
+
'200': {
|
|
815
|
+
description: 'Swagger UI HTML page',
|
|
816
|
+
content: {
|
|
817
|
+
'text/html': {},
|
|
818
|
+
},
|
|
819
|
+
},
|
|
820
|
+
},
|
|
821
|
+
},
|
|
822
|
+
},
|
|
823
|
+
'/openapi.json': {
|
|
824
|
+
get: {
|
|
825
|
+
operationId: 'get_openapi',
|
|
826
|
+
summary: 'OpenAPI Specification',
|
|
827
|
+
description: 'OpenAPI 3.0 specification in JSON format',
|
|
828
|
+
tags: ['documentation'],
|
|
829
|
+
responses: {
|
|
830
|
+
'200': {
|
|
831
|
+
description: 'OpenAPI specification',
|
|
832
|
+
content: {
|
|
833
|
+
'application/json': {},
|
|
834
|
+
},
|
|
835
|
+
},
|
|
836
|
+
},
|
|
837
|
+
},
|
|
838
|
+
},
|
|
839
|
+
},
|
|
840
|
+
tags: [
|
|
841
|
+
{ name: 'workflows', description: 'Workflow execution endpoints' },
|
|
842
|
+
{ name: 'documentation', description: 'API documentation endpoints' },
|
|
843
|
+
],
|
|
844
|
+
};
|
|
845
|
+
}
|
|
846
|
+
async generateMultiWorkflow(workflows, options) {
|
|
847
|
+
const files = [];
|
|
848
|
+
const serviceName = options.displayName || 'multi-workflow-service';
|
|
849
|
+
// Generate workflow imports and entries
|
|
850
|
+
const workflowImports = workflows
|
|
851
|
+
.map((w) => `import { ${w.functionName} } from './workflows/${w.name}.js';`)
|
|
852
|
+
.join('\n');
|
|
853
|
+
const workflowEntries = workflows.map((w) => ` '${w.name}': ${w.functionName},`).join('\n');
|
|
854
|
+
// Generate multi-workflow handler
|
|
855
|
+
const handlerContent = CLOUDFLARE_MULTI_HANDLER_TEMPLATE
|
|
856
|
+
.replace('{{GENERATED_HEADER}}', getGeneratedBranding().header('export --target cloudflare --multi'))
|
|
857
|
+
.replace('{{WORKFLOW_IMPORTS}}', workflowImports)
|
|
858
|
+
.replace('{{WORKFLOW_ENTRIES}}', workflowEntries)
|
|
859
|
+
.replace(/\{\{SERVICE_NAME\}\}/g, serviceName);
|
|
860
|
+
files.push(this.createFile(options.outputDir, 'index.ts', handlerContent, 'handler'));
|
|
861
|
+
// Generate consolidated OpenAPI spec
|
|
862
|
+
const openApiSpec = this.generateConsolidatedOpenAPI(workflows, {
|
|
863
|
+
title: `${serviceName} API`,
|
|
864
|
+
version: '1.0.0',
|
|
865
|
+
});
|
|
866
|
+
const openApiContent = `// Generated OpenAPI specification
|
|
867
|
+
export const openApiSpec = ${JSON.stringify(openApiSpec, null, 2)};
|
|
868
|
+
`;
|
|
869
|
+
files.push(this.createFile(options.outputDir, 'openapi.ts', openApiContent, 'config'));
|
|
870
|
+
// Generate wrangler.toml
|
|
871
|
+
const wranglerContent = WRANGLER_TEMPLATE.replace(/\{\{WORKFLOW_NAME\}\}/g, serviceName);
|
|
872
|
+
files.push(this.createFile(options.outputDir, 'wrangler.toml', wranglerContent, 'config'));
|
|
873
|
+
// Generate package.json
|
|
874
|
+
const packageJson = this.generatePackageJson({
|
|
875
|
+
name: serviceName,
|
|
876
|
+
description: `Multi-workflow service with ${workflows.length} workflows`,
|
|
877
|
+
main: 'dist/index.js',
|
|
878
|
+
scripts: {
|
|
879
|
+
build: 'tsc',
|
|
880
|
+
dev: 'wrangler dev',
|
|
881
|
+
deploy: 'wrangler deploy',
|
|
882
|
+
},
|
|
883
|
+
devDependencies: {
|
|
884
|
+
'@cloudflare/workers-types': '^4.0.0',
|
|
885
|
+
wrangler: '^3.0.0',
|
|
886
|
+
},
|
|
887
|
+
});
|
|
888
|
+
files.push(this.createFile(options.outputDir, 'package.json', packageJson, 'package'));
|
|
889
|
+
// Generate tsconfig.json
|
|
890
|
+
const tsConfig = this.generateTsConfig({
|
|
891
|
+
outDir: './dist',
|
|
892
|
+
module: 'ESNext',
|
|
893
|
+
moduleResolution: 'Bundler',
|
|
894
|
+
types: ['@cloudflare/workers-types'],
|
|
895
|
+
});
|
|
896
|
+
files.push(this.createFile(options.outputDir, 'tsconfig.json', tsConfig, 'config'));
|
|
897
|
+
// Generate workflow content files
|
|
898
|
+
files.push(...this.generateWorkflowContentFiles(workflows, options.outputDir));
|
|
899
|
+
return {
|
|
900
|
+
files,
|
|
901
|
+
target: this.name,
|
|
902
|
+
workflowName: serviceName,
|
|
903
|
+
workflowNames: workflows.map((w) => w.name),
|
|
904
|
+
entryPoint: 'index.ts',
|
|
905
|
+
openApiSpec,
|
|
906
|
+
};
|
|
907
|
+
}
|
|
908
|
+
async generateNodeTypeService(nodeTypes, options) {
|
|
909
|
+
const files = [];
|
|
910
|
+
const serviceName = options.serviceName || 'node-type-service';
|
|
911
|
+
// Generate node type imports and entries
|
|
912
|
+
// Use lowercase functionName for import paths to match the generated file names
|
|
913
|
+
const nodeTypeImports = nodeTypes
|
|
914
|
+
.map((nt) => `import { ${nt.functionName} } from './node-types/${nt.functionName.toLowerCase()}.js';`)
|
|
915
|
+
.join('\n');
|
|
916
|
+
const nodeTypeEntries = nodeTypes.map((nt) => ` '${nt.name}': ${nt.functionName},`).join('\n');
|
|
917
|
+
// Generate node type handler
|
|
918
|
+
const handlerContent = CLOUDFLARE_NODE_TYPE_HANDLER_TEMPLATE
|
|
919
|
+
.replace('{{GENERATED_HEADER}}', getGeneratedBranding().header('export --target cloudflare --node-types'))
|
|
920
|
+
.replace('{{NODE_TYPE_IMPORTS}}', nodeTypeImports)
|
|
921
|
+
.replace('{{NODE_TYPE_ENTRIES}}', nodeTypeEntries)
|
|
922
|
+
.replace(/\{\{SERVICE_NAME\}\}/g, serviceName);
|
|
923
|
+
files.push(this.createFile(options.outputDir, 'index.ts', handlerContent, 'handler'));
|
|
924
|
+
// Generate OpenAPI spec
|
|
925
|
+
const openApiSpec = this.generateNodeTypeOpenAPI(nodeTypes, {
|
|
926
|
+
title: `${serviceName} API`,
|
|
927
|
+
version: '1.0.0',
|
|
928
|
+
});
|
|
929
|
+
const openApiContent = `// Generated OpenAPI specification
|
|
930
|
+
export const openApiSpec = ${JSON.stringify(openApiSpec, null, 2)};
|
|
931
|
+
`;
|
|
932
|
+
files.push(this.createFile(options.outputDir, 'openapi.ts', openApiContent, 'config'));
|
|
933
|
+
// Generate wrangler.toml
|
|
934
|
+
const wranglerContent = WRANGLER_TEMPLATE.replace(/\{\{WORKFLOW_NAME\}\}/g, serviceName);
|
|
935
|
+
files.push(this.createFile(options.outputDir, 'wrangler.toml', wranglerContent, 'config'));
|
|
936
|
+
// Generate package.json
|
|
937
|
+
const packageJson = this.generatePackageJson({
|
|
938
|
+
name: serviceName,
|
|
939
|
+
description: `Node type service with ${nodeTypes.length} endpoints`,
|
|
940
|
+
main: 'dist/index.js',
|
|
941
|
+
scripts: {
|
|
942
|
+
build: 'tsc',
|
|
943
|
+
dev: 'wrangler dev',
|
|
944
|
+
deploy: 'wrangler deploy',
|
|
945
|
+
},
|
|
946
|
+
devDependencies: {
|
|
947
|
+
'@cloudflare/workers-types': '^4.0.0',
|
|
948
|
+
wrangler: '^3.0.0',
|
|
949
|
+
},
|
|
950
|
+
});
|
|
951
|
+
files.push(this.createFile(options.outputDir, 'package.json', packageJson, 'package'));
|
|
952
|
+
// Generate tsconfig.json
|
|
953
|
+
const tsConfig = this.generateTsConfig({
|
|
954
|
+
outDir: './dist',
|
|
955
|
+
module: 'ESNext',
|
|
956
|
+
moduleResolution: 'Bundler',
|
|
957
|
+
types: ['@cloudflare/workers-types'],
|
|
958
|
+
});
|
|
959
|
+
files.push(this.createFile(options.outputDir, 'tsconfig.json', tsConfig, 'config'));
|
|
960
|
+
// Generate node-type content files
|
|
961
|
+
files.push(...this.generateNodeTypeContentFiles(nodeTypes, options.outputDir));
|
|
962
|
+
return {
|
|
963
|
+
files,
|
|
964
|
+
target: this.name,
|
|
965
|
+
workflowName: serviceName,
|
|
966
|
+
nodeTypeNames: nodeTypes.map((nt) => nt.name),
|
|
967
|
+
entryPoint: 'index.ts',
|
|
968
|
+
openApiSpec,
|
|
969
|
+
};
|
|
970
|
+
}
|
|
971
|
+
async generateBundle(workflows, nodeTypes, options) {
|
|
972
|
+
const files = [];
|
|
973
|
+
const serviceName = options.displayName || 'bundle-service';
|
|
974
|
+
// Separate exposed and bundled-only items
|
|
975
|
+
const exposedWorkflows = workflows.filter((w) => w.expose);
|
|
976
|
+
const exposedNodeTypes = nodeTypes.filter((nt) => nt.expose);
|
|
977
|
+
// Filter to only include items that have generated code
|
|
978
|
+
// Also skip npm imports (names containing '/') as they should be installed via package.json
|
|
979
|
+
const workflowsWithCode = workflows.filter((w) => w.code);
|
|
980
|
+
const nodeTypesWithCode = nodeTypes.filter((nt) => nt.code && !nt.name.includes('/'));
|
|
981
|
+
// Detect name collisions between workflows and nodeTypes
|
|
982
|
+
const workflowNames = new Set(workflowsWithCode.map((w) => w.functionName));
|
|
983
|
+
const nodeTypeAliases = new Map();
|
|
984
|
+
for (const nt of nodeTypesWithCode) {
|
|
985
|
+
if (workflowNames.has(nt.functionName)) {
|
|
986
|
+
// Use alias for colliding nodeType names
|
|
987
|
+
nodeTypeAliases.set(nt.functionName, `${nt.functionName}_nodeType`);
|
|
988
|
+
}
|
|
989
|
+
}
|
|
990
|
+
// Generate all workflow imports (both exposed and bundled-only) - only for those with code
|
|
991
|
+
const workflowImports = workflowsWithCode.length > 0
|
|
992
|
+
? workflowsWithCode
|
|
993
|
+
.map((w) => `import { ${w.functionName} } from './workflows/${w.name}.js';`)
|
|
994
|
+
.join('\n')
|
|
995
|
+
: '// No workflows';
|
|
996
|
+
// Generate all node type imports (both exposed and bundled-only) with aliases for collisions - only for those with code
|
|
997
|
+
// Use lowercase functionName for import paths to match the generated file names
|
|
998
|
+
const nodeTypeImports = nodeTypesWithCode.length > 0
|
|
999
|
+
? nodeTypesWithCode
|
|
1000
|
+
.map((nt) => {
|
|
1001
|
+
const alias = nodeTypeAliases.get(nt.functionName);
|
|
1002
|
+
const lowerFunctionName = nt.functionName.toLowerCase();
|
|
1003
|
+
if (alias) {
|
|
1004
|
+
return `import { ${nt.functionName} as ${alias} } from './node-types/${lowerFunctionName}.js';`;
|
|
1005
|
+
}
|
|
1006
|
+
return `import { ${nt.functionName} } from './node-types/${lowerFunctionName}.js';`;
|
|
1007
|
+
})
|
|
1008
|
+
.join('\n')
|
|
1009
|
+
: '// No node types';
|
|
1010
|
+
// Generate entries only for exposed items
|
|
1011
|
+
// Filter exposed items to only include those with code
|
|
1012
|
+
const exposedWorkflowsWithCode = exposedWorkflows.filter((w) => w.code);
|
|
1013
|
+
const exposedNodeTypesWithCode = exposedNodeTypes.filter((nt) => nt.code);
|
|
1014
|
+
const exposedWorkflowEntries = exposedWorkflowsWithCode.length > 0
|
|
1015
|
+
? exposedWorkflowsWithCode.map((w) => ` '${w.name}': ${w.functionName},`).join('\n')
|
|
1016
|
+
: ' // No exposed workflows';
|
|
1017
|
+
const exposedNodeTypeEntries = exposedNodeTypesWithCode.length > 0
|
|
1018
|
+
? exposedNodeTypesWithCode
|
|
1019
|
+
.map((nt) => {
|
|
1020
|
+
const alias = nodeTypeAliases.get(nt.functionName);
|
|
1021
|
+
return ` '${nt.name}': ${alias || nt.functionName},`;
|
|
1022
|
+
})
|
|
1023
|
+
.join('\n')
|
|
1024
|
+
: ' // No exposed node types';
|
|
1025
|
+
// Generate bundle handler
|
|
1026
|
+
const handlerContent = CLOUDFLARE_BUNDLE_HANDLER_TEMPLATE
|
|
1027
|
+
.replace('{{GENERATED_HEADER}}', getGeneratedBranding().header('export --target cloudflare --bundle'))
|
|
1028
|
+
.replace('{{WORKFLOW_IMPORTS}}', workflowImports)
|
|
1029
|
+
.replace('{{NODE_TYPE_IMPORTS}}', nodeTypeImports)
|
|
1030
|
+
.replace('{{EXPOSED_WORKFLOW_ENTRIES}}', exposedWorkflowEntries)
|
|
1031
|
+
.replace('{{EXPOSED_NODE_TYPE_ENTRIES}}', exposedNodeTypeEntries)
|
|
1032
|
+
.replace(/\{\{SERVICE_NAME\}\}/g, serviceName);
|
|
1033
|
+
files.push(this.createFile(options.outputDir, 'index.ts', handlerContent, 'handler'));
|
|
1034
|
+
// Generate OpenAPI spec for exposed items only
|
|
1035
|
+
const openApiSpec = this.generateBundleOpenAPI(workflows, nodeTypes, {
|
|
1036
|
+
title: `${serviceName} API`,
|
|
1037
|
+
version: '1.0.0',
|
|
1038
|
+
});
|
|
1039
|
+
const openApiContent = `// Generated OpenAPI specification
|
|
1040
|
+
export const openApiSpec = ${JSON.stringify(openApiSpec, null, 2)};
|
|
1041
|
+
`;
|
|
1042
|
+
files.push(this.createFile(options.outputDir, 'openapi.ts', openApiContent, 'config'));
|
|
1043
|
+
// Generate wrangler.toml
|
|
1044
|
+
const wranglerContent = WRANGLER_TEMPLATE.replace(/\{\{WORKFLOW_NAME\}\}/g, serviceName);
|
|
1045
|
+
files.push(this.createFile(options.outputDir, 'wrangler.toml', wranglerContent, 'config'));
|
|
1046
|
+
// Generate package.json
|
|
1047
|
+
const packageJson = this.generatePackageJson({
|
|
1048
|
+
name: serviceName,
|
|
1049
|
+
description: `Bundle service with ${workflows.length} workflows and ${nodeTypes.length} node types`,
|
|
1050
|
+
main: 'dist/index.js',
|
|
1051
|
+
scripts: {
|
|
1052
|
+
build: 'tsc',
|
|
1053
|
+
dev: 'wrangler dev',
|
|
1054
|
+
deploy: 'wrangler deploy',
|
|
1055
|
+
},
|
|
1056
|
+
devDependencies: {
|
|
1057
|
+
'@cloudflare/workers-types': '^4.0.0',
|
|
1058
|
+
wrangler: '^3.0.0',
|
|
1059
|
+
},
|
|
1060
|
+
});
|
|
1061
|
+
files.push(this.createFile(options.outputDir, 'package.json', packageJson, 'package'));
|
|
1062
|
+
// Generate tsconfig.json
|
|
1063
|
+
const tsConfig = this.generateTsConfig({
|
|
1064
|
+
outDir: './dist',
|
|
1065
|
+
module: 'ESNext',
|
|
1066
|
+
moduleResolution: 'Bundler',
|
|
1067
|
+
types: ['@cloudflare/workers-types'],
|
|
1068
|
+
});
|
|
1069
|
+
files.push(this.createFile(options.outputDir, 'tsconfig.json', tsConfig, 'config'));
|
|
1070
|
+
// Generate shared runtime types module (workflows import from this)
|
|
1071
|
+
const isProduction = options.production ?? true;
|
|
1072
|
+
const runtimeTypesContent = generateStandaloneRuntimeModule(isProduction, 'esm');
|
|
1073
|
+
files.push(this.createFile(options.outputDir, 'runtime/types.ts', runtimeTypesContent, 'other'));
|
|
1074
|
+
// Generate real runtime files (function registry, builtin functions, parameter resolver)
|
|
1075
|
+
files.push(...this.generateRuntimeFiles(options.outputDir, workflows, nodeTypes));
|
|
1076
|
+
// Generate workflow and node-type content files
|
|
1077
|
+
files.push(...this.generateBundleContentFiles(workflows, nodeTypes, options.outputDir));
|
|
1078
|
+
return {
|
|
1079
|
+
files,
|
|
1080
|
+
target: this.name,
|
|
1081
|
+
workflowName: serviceName,
|
|
1082
|
+
workflowNames: workflows.map((w) => w.name),
|
|
1083
|
+
nodeTypeNames: nodeTypes.map((nt) => nt.name),
|
|
1084
|
+
entryPoint: 'index.ts',
|
|
1085
|
+
openApiSpec,
|
|
1086
|
+
};
|
|
1087
|
+
}
|
|
1088
|
+
getDeployInstructions(artifacts) {
|
|
1089
|
+
const outputDir = artifacts.files[0]?.absolutePath
|
|
1090
|
+
? artifacts.files[0].absolutePath.replace(/\/[^/]+$/, '')
|
|
1091
|
+
: '.';
|
|
1092
|
+
const hasDocs = artifacts.files.some((f) => f.relativePath === 'openapi.ts');
|
|
1093
|
+
const steps = [`cd ${outputDir}`, 'npm install', 'npm run deploy'];
|
|
1094
|
+
if (hasDocs) {
|
|
1095
|
+
steps.push('Visit /docs for API documentation');
|
|
1096
|
+
}
|
|
1097
|
+
return {
|
|
1098
|
+
title: 'Deploy to Cloudflare Workers',
|
|
1099
|
+
prerequisites: [
|
|
1100
|
+
'Wrangler CLI installed (npm install -g wrangler)',
|
|
1101
|
+
'Cloudflare account',
|
|
1102
|
+
'First run: wrangler login',
|
|
1103
|
+
],
|
|
1104
|
+
steps,
|
|
1105
|
+
localTestSteps: [
|
|
1106
|
+
`cd ${outputDir}`,
|
|
1107
|
+
'npm install',
|
|
1108
|
+
'npm run dev',
|
|
1109
|
+
'# Worker will be available at http://localhost:8787',
|
|
1110
|
+
'# Test with: curl -X POST http://localhost:8787 -H "Content-Type: application/json" -d \'{"key": "value"}\'',
|
|
1111
|
+
],
|
|
1112
|
+
links: [
|
|
1113
|
+
{
|
|
1114
|
+
label: 'Cloudflare Workers Documentation',
|
|
1115
|
+
url: 'https://developers.cloudflare.com/workers/',
|
|
1116
|
+
},
|
|
1117
|
+
{
|
|
1118
|
+
label: 'Wrangler CLI',
|
|
1119
|
+
url: 'https://developers.cloudflare.com/workers/wrangler/',
|
|
1120
|
+
},
|
|
1121
|
+
],
|
|
1122
|
+
};
|
|
1123
|
+
}
|
|
1124
|
+
}
|
|
1125
|
+
//# sourceMappingURL=cloudflare.js.map
|