export declare const WORKFLOW_SDK_PATTERNS = "\n```javascript\nimport { workflow, node, trigger, sticky, placeholder, newCredential, ifElse, switchCase, merge, splitInBatches, nextBatch, languageModel, memory, tool, outputParser, embedding, embeddings, vectorStore, retriever, documentLoader, textSplitter, fromAi, expr } from '@n8n/workflow-sdk';\n\n// 1. Define all nodes first\nconst startTrigger = trigger({\n type: 'n8n-nodes-base.manualTrigger',\n version: 1,\n config: { name: 'Start' }\n});\n\nconst fetchData = node({\n type: 'n8n-nodes-base.httpRequest',\n version: 4.3,\n config: { name: 'Fetch Data', parameters: { method: 'GET', url: '...' } }\n});\n\nconst processData = node({\n type: 'n8n-nodes-base.set',\n version: 3.4,\n config: {\n name: 'Process Data',\n parameters: {\n mode: 'manual',\n includeOtherFields: true,\n assignments: {\n assignments: [\n { id: 'processed-title', name: 'processedTitle', value: expr('{{ $json.title }}'), type: 'string' }\n ]\n }\n }\n }\n});\n\n// 2. Compose workflow\nexport default workflow('id', 'name')\n .add(startTrigger)\n .to(fetchData)\n .to(processData);\n```\n\n\n\n\nWhen nodes return more than 1 item, chaining causes item multiplication: if Source A returns N items, a chained Source B runs N times instead of once.\n\n**When to use `executeOnce: true`:**\n- A node fetches data independently but is chained after another data source (prevents N\u00D7M multiplication)\n- A node should summarize/aggregate all upstream items in a single call (e.g., AI summary, send one notification)\n- A node calls an API that doesn't vary per input item\n\nFix with `executeOnce: true` (simplest) or parallel branches + Merge (when combining results):\n\n```javascript\n// sourceA outputs 10 items. sourceB outputs 10 items.\n// WRONG - processResults runs 100 times\n// startTrigger.to(sourceA.to(sourceB.to(processResults)))\n\n// FIX 1 - executeOnce: sourceB runs once regardless of input items\nconst sourceB = node({ ..., config: { ..., executeOnce: true } });\nstartTrigger.to(sourceA.to(sourceB.to(processResults)));\n\n// FIX 2 - parallel branches + Merge (combine by position)\n// .input(n) is 0-based: .input(0) = first input, .input(1) = second input.\nconst combineResults = merge({\n version: 3.2,\n config: { name: 'Combine Results', parameters: { mode: 'combine', combineBy: 'combineByPosition' } }\n});\nexport default workflow('id', 'name')\n .add(startTrigger)\n .to(sourceA.to(combineResults.input(0))) // first input (index 0)\n .add(startTrigger)\n .to(sourceB.to(combineResults.input(1))) // second input (index 1)\n .add(combineResults)\n .to(processResults);\n\n// FIX 3 - parallel branches + Merge (append)\nconst allResults = merge({\n version: 3.2,\n config: { name: 'All Results', parameters: { mode: 'append' } }\n});\nexport default workflow('id', 'name')\n .add(startTrigger)\n .to(sourceA.to(allResults.input(0))) // first input (index 0)\n .add(startTrigger)\n .to(sourceB.to(allResults.input(1))) // second input (index 1)\n .add(allResults)\n .to(processResults);\n```\n\n\n\n\nWhen a node returns 0 items, downstream nodes are skipped for that execution. **This is usually the correct behavior** \u2014 the scheduler / trigger fires again later, and when there is data, the chain runs normally. Don't paper over an empty result with `alwaysOutputData: true` by default.\n\n**`alwaysOutputData: true` forces a synthetic `{json: {}}` item downstream.** This is a footgun: downstream nodes will try to read fields that don't exist, HTTP requests will hit `GET undefined`, and loops will run once on a fake item. Use it *only* when the empty case has its own dedicated branch that you want to execute.\n\n**Correct pattern \u2014 no `alwaysOutputData`:**\n```javascript\n// Scheduler that processes pending work\nworkflow('ingest', 'Ingest Worker')\n .add(scheduleTrigger) // fires every 5 min\n .to(getPending) // returns 0..N rows; no alwaysOutputData\n .to(splitInBatches({version: 3, config: {parameters: {batchSize: 1}}})\n .onEachBatch(fetchUrl.to(embed).to(saveChunk))\n );\n// On runs where getPending returns 0 items, the loop simply doesn't execute.\n// On runs where it returns rows, the loop iterates. No gate, no filter needed.\n```\n\n**Correct pattern \u2014 empty case needs its own branch:**\n```javascript\n// \"No matches found\" deserves a notification\nconst search = node({\n type: 'n8n-nodes-base.httpRequest',\n version: 4.4,\n config: {\n name: 'Search',\n alwaysOutputData: true, // empty-case branch below needs to execute\n parameters: { /* ... */ }\n }\n});\nconst hasResults = ifElse({\n version: 2.2,\n config: {\n name: 'Has Results?',\n parameters: {\n conditions: {\n options: { caseSensitive: true, typeValidation: 'loose' },\n conditions: [{ leftValue: expr('{{ $json.results }}'), operator: { type: 'array', operation: 'notEmpty' } }],\n combinator: 'and'\n }\n }\n }\n});\nworkflow('search', 'Search').add(trigger).to(search).to(\n hasResults.onTrue(processResults).onFalse(notifyNoMatches)\n);\n```\n\n**When to use `alwaysOutputData: true`:** only when you've paired it with an explicit empty-case branch, AND the downstream branch doesn't blindly read item fields.\n\n**When NOT to use it:**\n- Scheduled/polling triggers where the \"no work\" case should silently skip\n- Before a `splitInBatches` loop \u2014 loops already no-op on empty input\n- Before a `filter` \u2014 the filter already no-ops on empty input\n- When all you'd do on the empty case is \"nothing\"\n\n**Don't gate loops with an `IF`.** `ifElse.onTrue(splitInBatches)` to check \"are there items?\" is redundant \u2014 the loop already does the right thing with 0 items. Drop the IF.\n\n\n\n\n\n**CRITICAL:** Each branch defines a COMPLETE processing path. Chain multiple steps INSIDE the branch using .to().\n\nEvery IF/Filter `conditions` parameter MUST include `options`, `conditions`, and `combinator`:\n```javascript\nconst checkValid = ifElse({\n version: 2.2,\n config: {\n name: 'Check Valid',\n parameters: {\n conditions: {\n options: { caseSensitive: true, leftValue: '', typeValidation: 'strict' },\n conditions: [{ leftValue: expr('{{ $json.status }}'), operator: { type: 'string', operation: 'equals' }, rightValue: 'active' }],\n combinator: 'and'\n }\n }\n }\n});\n\nexport default workflow('id', 'name')\n .add(startTrigger)\n .to(checkValid\n .onTrue(formatData.to(enrichData.to(saveToDb))) // Chain 3 nodes on true branch\n .onFalse(logError));\n```\n\n\n\n\n\nSwitch rules use `rules.values` (NOT `rules.rules`). Each rule needs `outputKey` and a complete `conditions` object:\n```javascript\nconst routeByPriority = switchCase({\n version: 3.2,\n config: {\n name: 'Route by Priority',\n parameters: {\n rules: {\n values: [\n { outputKey: 'urgent', conditions: { options: { caseSensitive: true, leftValue: '', typeValidation: 'strict' }, conditions: [{ leftValue: expr('{{ $json.priority }}'), operator: { type: 'string', operation: 'equals' }, rightValue: 'urgent' }], combinator: 'and' } },\n { outputKey: 'normal', conditions: { options: { caseSensitive: true, leftValue: '', typeValidation: 'strict' }, conditions: [{ leftValue: expr('{{ $json.priority }}'), operator: { type: 'string', operation: 'equals' }, rightValue: 'normal' }], combinator: 'and' } },\n ]\n },\n options: { fallbackOutput: 'extra', renameFallbackOutput: 'Fallback' }\n }\n }\n});\n\nexport default workflow('id', 'name')\n .add(startTrigger)\n .to(routeByPriority\n .onCase(0, processUrgent.to(notifyTeam.to(escalate)))\n .onCase(1, processNormal)\n .onCase(2, archive));\n```\n\n\n\n\n```javascript\n// First declare the Merge node using merge()\nconst combineResults = merge({\n version: 3.2,\n config: { name: 'Combine Results', parameters: { mode: 'combine' } }\n});\n\n// Declare branch nodes\nconst branch1 = node({ type: 'n8n-nodes-base.httpRequest', ... });\nconst branch2 = node({ type: 'n8n-nodes-base.httpRequest', ... });\nconst processResults = node({ type: 'n8n-nodes-base.set', ... });\n\n// Connect branches to specific merge inputs using .input(n).\n// Indices are 0-based: .input(0) is the FIRST input, .input(1) is the SECOND.\nexport default workflow('id', 'name')\n .add(trigger({ ... }))\n .to(branch1.to(combineResults.input(0))) // first input (index 0)\n .add(trigger({ ... }))\n .to(branch2.to(combineResults.input(1))) // second input (index 1)\n .add(combineResults)\n .to(processResults); // Process merged results\n```\n\n\n\n\n```javascript\nconst startTrigger = trigger({\n type: 'n8n-nodes-base.manualTrigger',\n version: 1,\n config: { name: 'Start' }\n});\n\nconst fetchRecords = node({\n type: 'n8n-nodes-base.httpRequest',\n version: 4.3,\n config: { name: 'Fetch Records', parameters: { method: 'GET', url: '...' } }\n});\n\nconst finalizeResults = node({\n type: 'n8n-nodes-base.set',\n version: 3.4,\n config: {\n name: 'Finalize',\n parameters: {\n mode: 'manual',\n includeOtherFields: true,\n assignments: {\n assignments: [\n { id: 'processed-at', name: 'processedAt', value: expr('{{ $now.toISO() }}'), type: 'string' }\n ]\n }\n }\n }\n});\n\nconst processRecord = node({\n type: 'n8n-nodes-base.httpRequest',\n version: 4.3,\n config: { name: 'Process Record', parameters: { method: 'POST', url: '...' } }\n});\n\nconst sibNode = splitInBatches({ version: 3, config: { name: 'Batch Process', parameters: { batchSize: 10 } } });\n\nexport default workflow('id', 'name')\n .add(startTrigger)\n .to(fetchRecords)\n .to(sibNode\n .onDone(finalizeResults)\n .onEachBatch(processRecord.to(nextBatch(sibNode)))\n );\n```\n\n\n\n\n```javascript\nconst webhookTrigger = trigger({\n type: 'n8n-nodes-base.webhook',\n version: 2.1,\n config: { name: 'Webhook' }\n});\n\nconst processWebhook = node({\n type: 'n8n-nodes-base.set',\n version: 3.4,\n config: {\n name: 'Process Webhook',\n parameters: {\n mode: 'manual',\n includeOtherFields: true,\n assignments: {\n assignments: [\n { id: 'source', name: 'source', value: 'webhook', type: 'string' }\n ]\n }\n }\n }\n});\n\nconst scheduleTrigger = trigger({\n type: 'n8n-nodes-base.scheduleTrigger',\n version: 1.3,\n config: { name: 'Daily Schedule', parameters: {} }\n});\n\nconst processSchedule = node({\n type: 'n8n-nodes-base.set',\n version: 3.4,\n config: {\n name: 'Process Schedule',\n parameters: {\n mode: 'manual',\n includeOtherFields: true,\n assignments: {\n assignments: [\n { id: 'source', name: 'source', value: 'schedule', type: 'string' }\n ]\n }\n }\n }\n});\n\nexport default workflow('id', 'name')\n .add(webhookTrigger)\n .to(processWebhook)\n .add(scheduleTrigger)\n .to(processSchedule);\n```\n\n\n\n\n```javascript\n// Each trigger's execution runs in COMPLETE ISOLATION.\n// Different branches have no effect on each other.\n// Never duplicate chains for \"isolation\" - it's already guaranteed.\n\nconst webhookTrigger = trigger({\n type: 'n8n-nodes-base.webhook',\n version: 2.1,\n config: { name: 'Webhook Trigger' }\n});\n\nconst scheduleTrigger = trigger({\n type: 'n8n-nodes-base.scheduleTrigger',\n version: 1.3,\n config: { name: 'Daily Schedule' }\n});\n\nconst processData = node({\n type: 'n8n-nodes-base.set',\n version: 3.4,\n config: {\n name: 'Process Data',\n parameters: {\n mode: 'manual',\n includeOtherFields: true,\n assignments: {\n assignments: [\n { id: 'received-at', name: 'receivedAt', value: expr('{{ $now.toISO() }}'), type: 'string' }\n ]\n }\n }\n }\n});\n\nconst sendNotification = node({\n type: 'n8n-nodes-base.slack',\n version: 2.3,\n config: { name: 'Notify Slack', parameters: {} }\n});\n\nexport default workflow('id', 'name')\n .add(webhookTrigger)\n .to(processData)\n .to(sendNotification)\n .add(scheduleTrigger)\n .to(processData);\n```\n\n\n\n\n```javascript\nconst openAiModel = languageModel({\n type: '@n8n/n8n-nodes-langchain.lmChatOpenAi',\n version: 1.3,\n config: { name: 'OpenAI Model', parameters: {} }\n});\n\nconst startTrigger = trigger({\n type: 'n8n-nodes-base.manualTrigger',\n version: 1,\n config: { name: 'Start' }\n});\n\nconst aiAgent = node({\n type: '@n8n/n8n-nodes-langchain.agent',\n version: 3.1,\n config: {\n name: 'AI Assistant',\n parameters: { promptType: 'define', text: 'You are a helpful assistant' },\n subnodes: { model: openAiModel }\n }\n});\n\nexport default workflow('ai-assistant', 'AI Assistant')\n .add(startTrigger)\n .to(aiAgent);\n```\n\n\n\n\n```javascript\nconst openAiModel = languageModel({\n type: '@n8n/n8n-nodes-langchain.lmChatOpenAi',\n version: 1.3,\n config: {\n name: 'OpenAI Model',\n parameters: {},\n credentials: { openAiApi: newCredential('OpenAI') }\n }\n});\n\nconst calculatorTool = tool({\n type: '@n8n/n8n-nodes-langchain.toolCalculator',\n version: 1,\n config: { name: 'Calculator', parameters: {} }\n});\n\nconst startTrigger = trigger({\n type: 'n8n-nodes-base.manualTrigger',\n version: 1,\n config: { name: 'Start' }\n});\n\nconst aiAgent = node({\n type: '@n8n/n8n-nodes-langchain.agent',\n version: 3.1,\n config: {\n name: 'Math Agent',\n parameters: { promptType: 'define', text: 'You can use tools to help users' },\n subnodes: { model: openAiModel, tools: [calculatorTool] }\n }\n});\n\nexport default workflow('ai-calculator', 'AI Calculator')\n .add(startTrigger)\n .to(aiAgent);\n```\n\n\n\n\n```javascript\nconst openAiModel = languageModel({\n type: '@n8n/n8n-nodes-langchain.lmChatOpenAi',\n version: 1.3,\n config: {\n name: 'OpenAI Model',\n parameters: {},\n credentials: { openAiApi: newCredential('OpenAI') }\n }\n});\n\nconst gmailTool = tool({\n type: 'n8n-nodes-base.gmailTool',\n version: 1,\n config: {\n name: 'Gmail Tool',\n parameters: {\n sendTo: fromAi('recipient', 'Email address'),\n subject: fromAi('subject', 'Email subject'),\n message: fromAi('body', 'Email content')\n },\n credentials: { gmailOAuth2: newCredential('Gmail') }\n }\n});\n\nconst startTrigger = trigger({\n type: 'n8n-nodes-base.manualTrigger',\n version: 1,\n config: { name: 'Start' }\n});\n\nconst aiAgent = node({\n type: '@n8n/n8n-nodes-langchain.agent',\n version: 3.1,\n config: {\n name: 'Email Agent',\n parameters: { promptType: 'define', text: 'You can send emails' },\n subnodes: { model: openAiModel, tools: [gmailTool] }\n }\n});\n\nexport default workflow('ai-email', 'AI Email Sender')\n .add(startTrigger)\n .to(aiAgent);\n```\n\n\n\n```javascript\nconst structuredParser = outputParser({\n type: '@n8n/n8n-nodes-langchain.outputParserStructured',\n version: 1.3,\n config: {\n name: 'Structured Output Parser',\n parameters: {\n schemaType: 'fromJson',\n jsonSchemaExample: '{ \"sentiment\": \"positive\", \"confidence\": 0.95, \"summary\": \"brief summary\" }'\n }\n }\n});\n\nconst aiAgent = node({\n type: '@n8n/n8n-nodes-langchain.agent',\n version: 3.1,\n config: {\n name: 'Sentiment Analyzer',\n parameters: { promptType: 'define', text: 'Analyze the sentiment of the input text', hasOutputParser: true },\n subnodes: { model: openAiModel, outputParser: structuredParser }\n }\n});\n\nexport default workflow('ai-sentiment', 'AI Sentiment Analyzer')\n .add(startTrigger)\n .to(aiAgent);\n```\n"; export { WORKFLOW_SDK_PATTERNS as WORKFLOW_PATTERNS_CONCISE };