diff --git a/backend/parsers/windmill-parser-sql/src/lib.rs b/backend/parsers/windmill-parser-sql/src/lib.rs index 0fe72f0296..9cdab08f36 100644 --- a/backend/parsers/windmill-parser-sql/src/lib.rs +++ b/backend/parsers/windmill-parser-sql/src/lib.rs @@ -19,6 +19,25 @@ pub use windmill_parser::{Arg, MainArgSignature, Typ}; pub const SANITIZED_ENUM_STR: &str = "__sanitized_enum__"; pub const SANITIZED_RAW_STRING_STR: &str = "__sanitized_raw_string__"; +pub fn parse_assets(code: &str) -> anyhow::Result> { + let mut assets = vec![]; + + lazy_static::lazy_static! { + static ref RE_S3_PATH: Regex = Regex::new(r#"['"]s3://([^\s'"]+)['"]"#).unwrap(); + static ref RE_RESOURCE_PATH: Regex = Regex::new(r#"ATTACH +['"]\$res:([^\s'"]+)['"]"#).unwrap(); + } + + for cap in RE_S3_PATH.captures_iter(code) { + assets.push(format!("s3://{}", cap.get(1).unwrap().as_str())); + } + + for cap in RE_RESOURCE_PATH.captures_iter(code) { + assets.push(format!("$res:{}", cap.get(1).unwrap().as_str())); + } + + Ok(assets) +} + pub fn parse_mysql_sig(code: &str) -> anyhow::Result { let parsed = parse_mysql_file(&code)?; if let Some(x) = parsed { diff --git a/backend/parsers/windmill-parser-wasm/src/lib.rs b/backend/parsers/windmill-parser-wasm/src/lib.rs index 4270c28c60..891a7bd3f1 100644 --- a/backend/parsers/windmill-parser-wasm/src/lib.rs +++ b/backend/parsers/windmill-parser-wasm/src/lib.rs @@ -168,4 +168,14 @@ pub fn parse_java(code: &str) -> String { wrap_sig(windmill_parser_java::parse_java_signature(code)) } +#[cfg(feature = "sql-parser")] +#[wasm_bindgen] +pub fn parse_assets_sql(code: &str) -> String { + if let Ok(r) = windmill_parser_sql::parse_assets(code) { + return serde_json::to_string(&r).unwrap(); + } else { + return "Invalid".to_string(); + } +} + // for related places search: ADD_NEW_LANG diff --git a/frontend/src/lib/infer.ts b/frontend/src/lib/infer.ts index 6582930715..1ce86af373 100644 --- a/frontend/src/lib/infer.ts +++ b/frontend/src/lib/infer.ts @@ -16,7 +16,8 @@ import initRegexParsers, { parse_mssql, parse_db_resource, parse_bash, - parse_powershell + parse_powershell, + parse_assets_sql } from 'windmill-parser-wasm-regex' import initPythonParser, { parse_python } from 'windmill-parser-wasm-py' import initGoParser, { parse_go } from 'windmill-parser-wasm-go' @@ -78,6 +79,32 @@ async function initWasmJava() { await initJavaParser(wasmUrlJava) } +export async function inferAssets( + language: SupportedLanguage | undefined, + code: string +): Promise { + async function parseAssets(): Promise { + if (language === 'duckdb') { + await initWasmRegex() + return JSON.parse(parse_assets_sql(code)) + } + return [] + } + const assets = new Array(...new Set(await parseAssets())) + assets.sort() + return assets +} + +const SQL_LANGUAGES = [ + 'postgresql', + 'mysql', + 'bigquery', + 'snowflake', + 'mssql', + 'oracledb', + 'duckdb' +] + export async function inferArgs( language: SupportedLanguage | 'bunnative' | undefined, code: string, @@ -97,12 +124,17 @@ export async function inferArgs( } let inlineDBResource: string | undefined = undefined + + if (language && SQL_LANGUAGES.includes(language)) { + await initWasmRegex() + } + if ( ['postgresql', 'mysql', 'bigquery', 'snowflake', 'mssql', 'oracledb'].includes(language ?? '') ) { - await initWasmRegex() inlineDBResource = parse_db_resource(code) } + if (language == 'python3') { await initWasmPython() inferedSchema = JSON.parse(parse_python(code, mainOverride)) @@ -151,7 +183,6 @@ export async function inferArgs( ] } } else if (language == 'duckdb') { - await initWasmRegex() inferedSchema = JSON.parse(parse_duckdb(code)) } else if (language == 'snowflake') { inferedSchema = JSON.parse(parse_snowflake(code))