fix: preproccessor ui and expanding preprocessor support (#6872)

* preproccessor php

* fix

* ok

* remove folder

* chore: publish parser

---------

Co-authored-by: HugoCasa <hugo@casademont.ch>
This commit is contained in:
dieriba
2025-11-10 12:22:31 +01:00
committed by GitHub
parent e047c3b2b1
commit fc5034e94d
16 changed files with 347 additions and 71 deletions
+31 -13
View File
@@ -44,23 +44,41 @@ fn parse_default_expr(e: Expression) -> Option<Value> {
pub fn parse_php_signature(
code: &str,
override_main: Option<String>,
override_entrypoint: Option<String>,
) -> anyhow::Result<MainArgSignature> {
let main_name = override_main.unwrap_or("main".to_string());
let entrypoint_fn_name = override_entrypoint.unwrap_or("main".to_string());
let ast = parser::parse(code)
.map_err(|e| anyhow::anyhow!("Error parsing code: {}", e.to_string()))?;
let params = ast.into_iter().find_map(|x| match x {
Statement::Function(FunctionStatement {
name,
parameters: FunctionParameterList { parameters, .. },
..
}) if name.to_string() == main_name => Some(parameters),
_ => None,
});
let mut entrypoint_params = None;
let mut has_preprocessor = None;
for node in ast.into_iter() {
match node {
Statement::Function(FunctionStatement {
name,
parameters: FunctionParameterList { parameters, .. },
..
}) => {
let fn_name = name.to_string();
if let Some(params) = params {
if has_preprocessor.is_none() && fn_name == "preprocessor" {
has_preprocessor = Some(true);
}
if entrypoint_params.is_none() && fn_name == entrypoint_fn_name {
entrypoint_params = Some(parameters);
}
if has_preprocessor.is_some() && entrypoint_params.is_some() {
break;
}
}
_ => {}
};
}
if let Some(params) = entrypoint_params {
let args = params
.into_iter()
.map(|x| {
@@ -82,7 +100,7 @@ pub fn parse_php_signature(
star_kwargs: false,
args,
no_main_func: Some(false),
has_preprocessor: None,
has_preprocessor,
})
} else {
Ok(MainArgSignature {
@@ -90,7 +108,7 @@ pub fn parse_php_signature(
star_kwargs: false,
args: vec![],
no_main_func: Some(true),
has_preprocessor: None,
has_preprocessor,
})
}
}
@@ -134,8 +134,11 @@ pub fn parse_graphql(code: &str) -> String {
#[cfg(feature = "php-parser")]
#[wasm_bindgen]
pub fn parse_php(code: &str) -> String {
wrap_sig(windmill_parser_php::parse_php_signature(code, None))
pub fn parse_php(code: &str, main_override: Option<String>) -> String {
wrap_sig(windmill_parser_php::parse_php_signature(
code,
main_override,
))
}
#[cfg(feature = "rust-parser")]
+3 -1
View File
@@ -2232,7 +2232,7 @@ async fn push_next_flow_job(
}
});
// if this is an empty module without preprocessor of if the module has already been completed, successfully, update the parent flow
// if this is an empty module without preprocessor or if the module has already been completed, successfully, update the parent flow
if (flow.modules.is_empty() && !step.is_preprocessor_step())
|| matches!(status_module, FlowStatusModule::Success { .. })
{
@@ -3717,11 +3717,13 @@ pub struct JobPayloadWithTag {
pub timeout: Option<i32>,
pub on_behalf_of: Option<OnBehalfOf>,
}
#[derive(Debug)]
enum ContinuePayload {
SingleJob(JobPayloadWithTag),
ParallelJobs(Vec<JobPayloadWithTag>),
}
#[derive(Debug)]
enum NextFlowTransform {
EmptyInnerFlows { branch_chosen: Option<BranchChosen> },
Continue(ContinuePayload, NextStatus),
+1 -1
View File
@@ -1,3 +1,3 @@
/* tslint:disable */
/* eslint-disable */
export function parse_php(code: string): string;
export function parse_php(code: string, main_override?: string | null): string;
+20 -9
View File
@@ -56,30 +56,41 @@ function passStringToWasm0(arg, malloc, realloc) {
return ptr;
}
const cachedTextDecoder = (typeof TextDecoder !== 'undefined' ? new TextDecoder('utf-8', { ignoreBOM: true, fatal: true }) : { decode: () => { throw Error('TextDecoder not available') } } );
function isLikeNone(x) {
return x === undefined || x === null;
}
let cachedTextDecoder = (typeof TextDecoder !== 'undefined' ? new TextDecoder('utf-8', { ignoreBOM: true, fatal: true }) : { decode: () => { throw Error('TextDecoder not available') } } );
if (typeof TextDecoder !== 'undefined') { cachedTextDecoder.decode(); };
function decodeText(ptr, len) {
return cachedTextDecoder.decode(getUint8ArrayMemory0().subarray(ptr, ptr + len));
}
function getStringFromWasm0(ptr, len) {
ptr = ptr >>> 0;
return cachedTextDecoder.decode(getUint8ArrayMemory0().subarray(ptr, ptr + len));
return decodeText(ptr, len);
}
/**
* @param {string} code
* @param {string | null} [main_override]
* @returns {string}
*/
export function parse_php(code) {
let deferred2_0;
let deferred2_1;
export function parse_php(code, main_override) {
let deferred3_0;
let deferred3_1;
try {
const ptr0 = passStringToWasm0(code, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
const len0 = WASM_VECTOR_LEN;
const ret = wasm.parse_php(ptr0, len0);
deferred2_0 = ret[0];
deferred2_1 = ret[1];
var ptr1 = isLikeNone(main_override) ? 0 : passStringToWasm0(main_override, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
var len1 = WASM_VECTOR_LEN;
const ret = wasm.parse_php(ptr0, len0, ptr1, len1);
deferred3_0 = ret[0];
deferred3_1 = ret[1];
return getStringFromWasm0(ret[0], ret[1]);
} finally {
wasm.__wbindgen_free(deferred2_0, deferred2_1, 1);
wasm.__wbindgen_free(deferred3_0, deferred3_1, 1);
}
}
Binary file not shown.
+1 -1
View File
@@ -1,7 +1,7 @@
/* tslint:disable */
/* eslint-disable */
export const memory: WebAssembly.Memory;
export const parse_php: (a: number, b: number) => [number, number];
export const parse_php: (a: number, b: number, c: number, d: number) => [number, number];
export const __wbindgen_export_0: WebAssembly.Table;
export const __wbindgen_malloc: (a: number, b: number) => number;
export const __wbindgen_realloc: (a: number, b: number, c: number, d: number) => number;
+4 -4
View File
@@ -77,7 +77,7 @@
"windmill-parser-wasm-go": "1.510.1",
"windmill-parser-wasm-java": "1.510.1",
"windmill-parser-wasm-nu": "1.510.1",
"windmill-parser-wasm-php": "1.510.1",
"windmill-parser-wasm-php": "1.574.1",
"windmill-parser-wasm-py": "1.538.0",
"windmill-parser-wasm-regex": "1.565.0",
"windmill-parser-wasm-ruby": "1.526.1",
@@ -13749,9 +13749,9 @@
"integrity": "sha512-AJLFiUy6af+LpUe7CddDo4+JOmw3c0K/1iOWh8NdTwXcLDj90lL6089mdsVo1apyloLgrTbcuFDzZMXVGBgtCg=="
},
"node_modules/windmill-parser-wasm-php": {
"version": "1.510.1",
"resolved": "https://registry.npmjs.org/windmill-parser-wasm-php/-/windmill-parser-wasm-php-1.510.1.tgz",
"integrity": "sha512-qM+yeaqPdMuAaPpqND31ZabpeHlPxxtmRWLs11cGHOCHU32FIaZ92/icNUoAxgBhdJjRhR4GXaeZG32nWit2cg=="
"version": "1.574.1",
"resolved": "https://registry.npmjs.org/windmill-parser-wasm-php/-/windmill-parser-wasm-php-1.574.1.tgz",
"integrity": "sha512-COyid6B1RYs+bpzUCInsA4HY/WZkpDLfkQ90+AqU/TVTpzYSbAC2JCbIwy0cRElBvlhI4bQ+9Wg6hSQKMpEkpA=="
},
"node_modules/windmill-parser-wasm-py": {
"version": "1.538.0",
+1 -1
View File
@@ -142,7 +142,7 @@
"windmill-parser-wasm-go": "1.510.1",
"windmill-parser-wasm-java": "1.510.1",
"windmill-parser-wasm-nu": "1.510.1",
"windmill-parser-wasm-php": "1.510.1",
"windmill-parser-wasm-php": "1.574.1",
"windmill-parser-wasm-py": "1.538.0",
"windmill-parser-wasm-regex": "1.565.0",
"windmill-parser-wasm-ruby": "1.526.1",
+12 -6
View File
@@ -92,7 +92,7 @@
import { aiChatManager } from './copilot/chat/AIChatManager.svelte'
import type { Selection } from 'monaco-editor'
import { getDbSchemas } from './apps/components/display/dbtable/utils'
import { PYTHON_PREPROCESSOR_MODULE_CODE, TS_PREPROCESSOR_MODULE_CODE } from '$lib/script_helpers'
import { canHavePreprocessor, getPreprocessorModuleCode } from '$lib/script_helpers'
import { setMonacoTypescriptOptions } from './monacoLanguagesOptions'
import { copilotInfo } from '$lib/aiStore'
// import EditorTheme from './EditorTheme.svelte'
@@ -620,12 +620,18 @@
}
let preprocessorCompletor: IDisposable | undefined = undefined
function addPreprocessorCompletions(lang: 'typescript' | 'python') {
function addPreprocessorCompletions(lang: string) {
if (preprocessorCompletor) {
preprocessorCompletor.dispose()
}
const preprocessorCode =
lang === 'typescript' ? TS_PREPROCESSOR_MODULE_CODE : PYTHON_PREPROCESSOR_MODULE_CODE
const windmillLang = lang === 'typescript' ? 'deno' : lang === 'python' ? 'python3' : lang
const preprocessorCode = getPreprocessorModuleCode(windmillLang as ScriptLang)
if (!preprocessorCode) {
return
}
preprocessorCompletor = languages.registerCompletionItemProvider(lang, {
provideCompletionItems: function (model, position) {
const word = model.getWordUntilPosition(position)
@@ -1653,8 +1659,8 @@
})
$effect(() => {
initialized && (lang === 'typescript' || lang === 'python') && enablePreprocessorSnippet
? untrack(() => addPreprocessorCompletions(lang as 'typescript' | 'python'))
initialized && canHavePreprocessor(lang) && enablePreprocessorSnippet
? untrack(() => addPreprocessorCompletions(lang))
: preprocessorCompletor?.dispose()
})
@@ -15,7 +15,12 @@
WorkerService
} from '$lib/gen'
import { inferArgs } from '$lib/infer'
import { initialCode } from '$lib/script_helpers'
import {
initialCode,
canHavePreprocessor,
getPreprocessorFullCode,
getMainFunctionPattern
} from '$lib/script_helpers'
import AIFormSettings from './copilot/AIFormSettings.svelte'
import {
defaultScripts,
@@ -80,12 +85,6 @@
import DeployOverrideConfirmationModal from '$lib/components/common/confirmationModal/DeployOverrideConfirmationModal.svelte'
import TriggersEditor from './triggers/TriggersEditor.svelte'
import type { ScheduleTrigger, TriggerContext } from './triggers'
import {
TS_PREPROCESSOR_MODULE_CODE,
TS_PREPROCESSOR_SCRIPT_INTRO,
PYTHON_PREPROCESSOR_MODULE_CODE,
PYTHON_PREPROCESSOR_SCRIPT_INTRO
} from '$lib/script_helpers'
import CaptureTable from './triggers/CaptureTable.svelte'
import type { SavedAndModifiedValue } from './common/confirmationModal/unsavedTypes'
import DeployButton from './DeployButton.svelte'
@@ -313,7 +312,7 @@
{
value: 'preprocessor',
title: 'Preprocessor',
desc: 'Transform incoming requests before they are passed to the flow.',
desc: 'Transform incoming requests before they are passed to the main entrypoint.',
documentationLink: 'https://www.windmill.dev/docs/core_concepts/preprocessors',
Icon: Shuffle
}
@@ -853,13 +852,10 @@
function addPreprocessor() {
const code = editor?.getCode()
if (code) {
const preprocessorCode =
script.language === 'python3'
? PYTHON_PREPROCESSOR_SCRIPT_INTRO + PYTHON_PREPROCESSOR_MODULE_CODE
: TS_PREPROCESSOR_SCRIPT_INTRO + TS_PREPROCESSOR_MODULE_CODE
const mainIndex = code.indexOf(
script.language === 'python3' ? 'def main' : 'export async function main'
)
const preprocessorCode = getPreprocessorFullCode(script.language, false)
const mainPattern = getMainFunctionPattern(script.language)
const mainIndex = code.indexOf(mainPattern)
if (mainIndex === -1) {
editor?.setCode(code + preprocessorCode)
} else {
@@ -1139,7 +1135,8 @@
btnClasses={isPicked ? '' : 'm-[1px]'}
on:click={() => onScriptLanguageTrigger(lang)}
disabled={lockedLanguage ||
(enterpriseLangs.includes(lang) && !$enterpriseLicense)}
(enterpriseLangs.includes(lang) && !$enterpriseLicense) ||
(script.kind == 'preprocessor' && !canHavePreprocessor(lang))}
startIcon={{
icon: LanguageIcon,
props: { lang }
@@ -1667,9 +1664,7 @@
newItem={initialPath == ''}
isFlow={false}
{hasPreprocessor}
canHavePreprocessor={script.language === 'bun' ||
script.language === 'deno' ||
script.language === 'python3'}
canHavePreprocessor={canHavePreprocessor(script.language)}
args={hasPreprocessor && selectedInputTab !== 'preprocessor' ? {} : args}
isDeployed={savedScript && !savedScript?.draft_only}
schema={script.schema}
@@ -48,6 +48,7 @@
import { aiChatManager, AIMode } from './copilot/chat/AIChatManager.svelte'
import { triggerableByAI } from '$lib/actions/triggerableByAI.svelte'
import AssetsDropdownButton from './assets/AssetsDropdownButton.svelte'
import { canHavePreprocessor } from '$lib/script_helpers'
import { assetEq, type AssetWithAltAccessType } from './assets/lib'
import { editor as meditor } from 'monaco-editor'
import type { ReviewChangesOpts } from './copilot/chat/monaco-adapter'
@@ -741,7 +742,7 @@
<CaptureTable
bind:this={captureTable}
{hasPreprocessor}
canHavePreprocessor={lang === 'bun' || lang === 'deno' || lang === 'python3'}
canHavePreprocessor={canHavePreprocessor(lang)}
isFlow={false}
path={stablePathForCaptures}
canEdit={true}
@@ -18,6 +18,7 @@
import type { SupportedLanguage } from '$lib/common'
import DefaultScripts from '$lib/components/DefaultScripts.svelte'
import type { FlowBuilderWhitelabelCustomUi } from '$lib/components/custom_ui'
import { canHavePreprocessor } from '$lib/script_helpers'
interface Props {
failureModule: boolean
@@ -57,18 +58,51 @@
)
function displayLang(lang: SupportedLanguage | 'docker', kind: string) {
if (lang == 'bun' || lang == 'python3' || lang == 'deno') {
if (preprocessorModule) {
return canHavePreprocessor(lang as SupportedLanguage)
}
if (failureModule || kind === 'trigger') {
if (
[
'postgresql',
'mysql',
'bigquery',
'snowflake',
'mssql',
'graphql',
'duckdb',
'oracledb'
].includes(lang)
) {
return false
}
return true
}
if (lang == 'go') {
return (kind == 'script' || kind == 'trigger' || failureModule) && !preprocessorModule
if (kind === 'script') {
return lang !== 'docker'
}
if (lang == 'bash' || lang == 'nativets') {
return kind == 'script' && !preprocessorModule
if (kind === 'approval') {
if (
[
'postgresql',
'mysql',
'bigquery',
'snowflake',
'mssql',
'graphql',
'duckdb',
'oracledb'
].includes(lang)
) {
return false
}
return true
}
return kind == 'script' && !failureModule && !preprocessorModule
return false
}
let customUi: undefined | FlowBuilderWhitelabelCustomUi = getContext('customUi')
@@ -30,6 +30,12 @@
import GenAiQuick from './GenAiQuick.svelte'
import FlowToplevelNode from '../pickers/FlowToplevelNode.svelte'
import { copilotInfo } from '$lib/aiStore'
import {
canHavePreprocessor,
canHaveTrigger,
canHaveApproval,
canHaveFailure
} from '$lib/script_helpers'
const dispatch = createEventDispatcher()
@@ -94,17 +100,17 @@
kind: 'script' | 'flow' | 'approval' | 'trigger' | 'preprocessor' | 'failure'
) {
if (kind == 'trigger') {
return ['python3', 'bun', 'deno', 'go'].includes(lang)
return canHaveTrigger(lang as SupportedLanguage)
} else if (kind == 'script') {
return true
} else if (kind == 'approval') {
return ['python3', 'bun', 'deno'].includes(lang)
return canHaveApproval(lang as SupportedLanguage)
} else if (kind == 'flow') {
return false
} else if (kind == 'preprocessor') {
return ['python3', 'bun', 'deno'].includes(lang)
return canHavePreprocessor(lang as SupportedLanguage)
} else if (kind == 'failure') {
return ['python3', 'bun', 'deno', 'go'].includes(lang)
return canHaveFailure(lang as SupportedLanguage)
}
}
+6 -2
View File
@@ -23,7 +23,11 @@ import initPythonParser, { parse_assets_py, parse_python } from 'windmill-parser
import initGoParser, { parse_go } from 'windmill-parser-wasm-go'
import initPhpParser, { parse_php } from 'windmill-parser-wasm-php'
import initRustParser, { parse_rust } from 'windmill-parser-wasm-rust'
import initYamlParser, { parse_assets_ansible, parse_ansible, parse_ansible_delegate } from 'windmill-parser-wasm-yaml'
import initYamlParser, {
parse_assets_ansible,
parse_ansible,
parse_ansible_delegate
} from 'windmill-parser-wasm-yaml'
import initCSharpParser, { parse_csharp } from 'windmill-parser-wasm-csharp'
import initNuParser, { parse_nu } from 'windmill-parser-wasm-nu'
import initJavaParser, { parse_java } from 'windmill-parser-wasm-java'
@@ -244,7 +248,7 @@ export async function inferArgs(
inferedSchema = JSON.parse(parse_powershell(code))
} else if (language == 'php') {
await initWasmPhp()
inferedSchema = JSON.parse(parse_php(code))
inferedSchema = JSON.parse(parse_php(code, mainOverride))
} else if (language == 'rust') {
await initWasmRust()
inferedSchema = JSON.parse(parse_rust(code))
+197 -1
View File
@@ -969,6 +969,86 @@ def preprocessor(event: Event):
}
`
export const PHP_PREPROCESSOR_SCRIPT_INTRO = `<?php
/**
* Trigger preprocessor
*
* This function runs BEFORE the main function.
*
* It processes raw trigger data from various sources (webhook, custom HTTP route, SQS, WebSocket, Kafka, NATS, MQTT, Postgres, or email)
* before passing it to \`main\`. This separates the trigger logic from the main logic and keeps the auto-generated runnable UI clean.
*
* The returned object defines the parameter values passed to \`main()\`.
* e.g., ['b' => 1, 'a' => 2] Calls \`main(2, 1)\`, assuming \`main\` is defined as \`main($a, $b)\`.
* Ensure that the parameter names in \`main\` match the keys in the returned array.
*
* Learn more: https://www.windmill.dev/docs/core_concepts/preprocessors
*/
`
export const PHP_PREPROCESSOR_FLOW_INTRO = `<?php
/**
* Trigger preprocessor
*
* It processes raw trigger data from various sources (webhook, custom HTTP route, SQS, WebSocket, Kafka, NATS, MQTT, Postgres, or email)
* before passing it to the flow. This separates the trigger logic from the flow logic and keeps the auto-generated UI clean.
*
* The returned object determines the parameter values passed to the flow.
* e.g., ['b' => 1, 'a' => 2] Calls the flow with \`a = 2\` and \`b = 1\`, assuming the flow has two inputs called \`a\` and \`b\`.
* Ensure that the input names of the flow match the keys in the returned array.
*
* Learn more: https://www.windmill.dev/docs/core_concepts/preprocessors
*/
`
export const PHP_PREPROCESSOR_MODULE_CODE = `function preprocessor(object $event) {
// $event can be one of the following types:
//
// Webhook event:
// ['kind' => 'webhook', 'body' => [...], 'raw_string' => '...', 'query' => [...], 'headers' => [...]]
//
// HTTP event:
// ['kind' => 'http', 'body' => [...], 'raw_string' => '...', 'route' => '...', 'path' => '...',
// 'method' => '...', 'params' => [...], 'query' => [...], 'headers' => [...]]
//
// Email event:
// ['kind' => 'email', 'parsed_email' => [...], 'raw_email' => '...', 'email_extra_args' => [...]]
//
// WebSocket event:
// ['kind' => 'websocket', 'msg' => '...', 'url' => '...']
//
// Kafka event:
// ['kind' => 'kafka', 'payload' => '...', 'brokers' => [...], 'topic' => '...', 'group_id' => '...']
//
// NATS event:
// ['kind' => 'nats', 'payload' => '...', 'servers' => [...], 'subject' => '...',
// 'headers' => [...], 'status' => 200, 'description' => '...', 'length' => 100]
//
// SQS event:
// ['kind' => 'sqs', 'msg' => '...', 'queue_url' => '...', 'message_id' => '...',
// 'receipt_handle' => '...', 'attributes' => [...], 'message_attributes' => [...]]
//
// MQTT event:
// ['kind' => 'mqtt', 'payload' => '...', 'topic' => '...', 'retain' => true, 'pkid' => 1,
// 'qos' => 1, 'v5' => [...]]
//
// GCP event:
// ['kind' => 'gcp', 'payload' => '...', 'message_id' => '...', 'subscription' => '...',
// 'ordering_key' => '...', 'attributes' => [...], 'delivery_type' => 'push',
// 'headers' => [...], 'publish_time' => '...', 'ack_id' => '...']
//
// Postgres event:
// ['kind' => 'postgres', 'transaction_type' => 'insert', 'schema_name' => '...',
// 'table_name' => '...', 'old_row' => [...], 'row' => [...]]
return [
// return the args to be passed to the runnable
];
}
`
const DOCKER_INIT_CODE = `# shellcheck shell=bash
# docker
# The annotation "docker" above is important, it tells windmill that after
@@ -1226,7 +1306,8 @@ export const INITIAL_CODE = {
script: ORACLEDB_INIT_CODE
},
php: {
script: PHP_INIT_CODE
script: PHP_INIT_CODE,
preprocessor: PHP_PREPROCESSOR_FLOW_INTRO + PHP_PREPROCESSOR_MODULE_CODE
},
rust: {
script: RUST_INIT_CODE
@@ -1349,6 +1430,9 @@ export function initialCode(
} else if (language == 'duckdb') {
return INITIAL_CODE.duckdb.script
} else if (language == 'php') {
if (kind == 'preprocessor') {
return INITIAL_CODE.php.preprocessor
}
return INITIAL_CODE.php.script
} else if (language == 'rust') {
return INITIAL_CODE.rust.script
@@ -1420,3 +1504,115 @@ export function getResetCode(
return initialCode(language, kind, subkind)
}
}
export const PREPROCESSOR_SUPPORTED_LANGUAGES = [
'typescript',
'python',
'python3',
'deno',
'bun',
'php'
] as const
export function canHavePreprocessor(language: string | undefined): boolean {
if (!language) {
return false
}
return PREPROCESSOR_SUPPORTED_LANGUAGES.includes(language as any)
}
export function canHaveTrigger(language: SupportedLanguage | undefined): boolean {
if (!language) {
return false
}
return ['python3', 'bun', 'deno', 'go'].includes(language)
}
export function canHaveApproval(language: SupportedLanguage | undefined): boolean {
if (!language) {
return false
}
return ['python3', 'bun', 'deno'].includes(language)
}
export function canHaveFailure(language: SupportedLanguage | undefined): boolean {
if (!language) {
return false
}
return ['python3', 'bun', 'deno', 'go'].includes(language)
}
export function getPreprocessorIntro(
language: SupportedLanguage | 'docker' | 'bunnative' | undefined,
isFlow: boolean = false
): string {
if (!language || !PREPROCESSOR_SUPPORTED_LANGUAGES.includes(language as any)) {
return ''
}
switch (language) {
case 'python3':
return isFlow ? PYTHON_PREPROCESSOR_FLOW_INTRO : PYTHON_PREPROCESSOR_SCRIPT_INTRO
case 'deno':
case 'bun':
return isFlow ? TS_PREPROCESSOR_FLOW_INTRO : TS_PREPROCESSOR_SCRIPT_INTRO
case 'php':
return isFlow ? PHP_PREPROCESSOR_FLOW_INTRO : PHP_PREPROCESSOR_SCRIPT_INTRO
default:
return ''
}
}
export function getPreprocessorModuleCode(
language: SupportedLanguage | 'docker' | 'bunnative' | undefined
): string {
if (!language || !PREPROCESSOR_SUPPORTED_LANGUAGES.includes(language as any)) {
return ''
}
switch (language) {
case 'python3':
return PYTHON_PREPROCESSOR_MODULE_CODE
case 'deno':
case 'bun':
return TS_PREPROCESSOR_MODULE_CODE
case 'php':
return PHP_PREPROCESSOR_MODULE_CODE
default:
return ''
}
}
export function getPreprocessorFullCode(
language: SupportedLanguage | 'docker' | 'bunnative' | undefined,
isFlow: boolean = false
): string {
const intro = getPreprocessorIntro(language, isFlow)
const moduleCode = getPreprocessorModuleCode(language)
return intro + moduleCode
}
export function getMainFunctionPattern(
language: SupportedLanguage | 'docker' | 'bunnative' | undefined
): string {
if (!language) {
return ''
}
switch (language) {
case 'python3':
return 'def main'
case 'deno':
case 'bun':
case 'nativets':
return 'export async function main'
case 'php':
return 'function main'
default:
return 'main'
}
}