mirror of
https://github.com/windmill-labs/windmill.git
synced 2026-09-21 00:02:30 +00:00
feat: add script bootstrap and script generate-metadata CLI commands (#3007)
* feat: add script bootstrap and script generate-metadata CLI commands * Address PR comments on code
This commit is contained in:
Generated
+20
-20
@@ -3752,9 +3752,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "js-sys"
|
||||
version = "0.3.67"
|
||||
version = "0.3.66"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9a1d36f1235bc969acba30b7f5990b864423a6068a10f7c90ae8f0112e3a59d1"
|
||||
checksum = "cee9c64da59eae3b50095c18d3e74f8b73c0b86d2792824ff01bbce68ba229ca"
|
||||
dependencies = [
|
||||
"wasm-bindgen",
|
||||
]
|
||||
@@ -9044,9 +9044,9 @@ checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423"
|
||||
|
||||
[[package]]
|
||||
name = "wasm-bindgen"
|
||||
version = "0.2.90"
|
||||
version = "0.2.89"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b1223296a201415c7fad14792dbefaace9bd52b62d33453ade1c5b5f07555406"
|
||||
checksum = "0ed0d4f68a3015cc185aff4db9506a015f4b96f95303897bfa23f846db54064e"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"wasm-bindgen-macro",
|
||||
@@ -9054,9 +9054,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "wasm-bindgen-backend"
|
||||
version = "0.2.90"
|
||||
version = "0.2.89"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "fcdc935b63408d58a32f8cc9738a0bffd8f05cc7c002086c6ef20b7312ad9dcd"
|
||||
checksum = "1b56f625e64f3a1084ded111c4d5f477df9f8c92df113852fa5a374dbda78826"
|
||||
dependencies = [
|
||||
"bumpalo",
|
||||
"log",
|
||||
@@ -9069,9 +9069,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "wasm-bindgen-futures"
|
||||
version = "0.4.40"
|
||||
version = "0.4.39"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "bde2032aeb86bdfaecc8b261eef3cba735cc426c1f3a3416d1e0791be95fc461"
|
||||
checksum = "ac36a15a220124ac510204aec1c3e5db8a22ab06fd6706d881dc6149f8ed9a12"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"js-sys",
|
||||
@@ -9081,9 +9081,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "wasm-bindgen-macro"
|
||||
version = "0.2.90"
|
||||
version = "0.2.89"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3e4c238561b2d428924c49815533a8b9121c664599558a5d9ec51f8a1740a999"
|
||||
checksum = "0162dbf37223cd2afce98f3d0785506dcb8d266223983e4b5b525859e6e182b2"
|
||||
dependencies = [
|
||||
"quote",
|
||||
"wasm-bindgen-macro-support",
|
||||
@@ -9091,9 +9091,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "wasm-bindgen-macro-support"
|
||||
version = "0.2.90"
|
||||
version = "0.2.89"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "bae1abb6806dc1ad9e560ed242107c0f6c84335f1749dd4e8ddb012ebd5e25a7"
|
||||
checksum = "f0eb82fcb7930ae6219a7ecfd55b217f5f0893484b7a13022ebb2b2bf20b5283"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
@@ -9104,15 +9104,15 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "wasm-bindgen-shared"
|
||||
version = "0.2.90"
|
||||
version = "0.2.89"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4d91413b1c31d7539ba5ef2451af3f0b833a005eb27a631cec32bc0635a8602b"
|
||||
checksum = "7ab9b36309365056cd639da3134bf87fa8f3d86008abf99e612384a6eecd459f"
|
||||
|
||||
[[package]]
|
||||
name = "wasm-bindgen-test"
|
||||
version = "0.3.40"
|
||||
version = "0.3.39"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "139bd73305d50e1c1c4333210c0db43d989395b64a237bd35c10ef3832a7f70c"
|
||||
checksum = "2cf9242c0d27999b831eae4767b2a146feb0b27d332d553e605864acd2afd403"
|
||||
dependencies = [
|
||||
"console_error_panic_hook",
|
||||
"js-sys",
|
||||
@@ -9124,9 +9124,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "wasm-bindgen-test-macro"
|
||||
version = "0.3.40"
|
||||
version = "0.3.39"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "70072aebfe5da66d2716002c729a14e4aec4da0e23cc2ea66323dac541c93928"
|
||||
checksum = "794645f5408c9a039fd09f4d113cdfb2e7eba5ff1956b07bcf701cf4b394fe89"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
@@ -9157,9 +9157,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "web-sys"
|
||||
version = "0.3.67"
|
||||
version = "0.3.66"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "58cd2333b6e0be7a39605f0e255892fd7418a682d8da8fe042fe25128794d2ed"
|
||||
checksum = "50c24a44ec86bb68fbecd1b3efed7e85ea5621b39b35ef2766b66cd984f8010f"
|
||||
dependencies = [
|
||||
"js-sys",
|
||||
"wasm-bindgen",
|
||||
|
||||
+1
-1
@@ -189,7 +189,7 @@ rsmq_async = { version = "5.1.5" }
|
||||
gosyn = "0.2.6"
|
||||
bytes = "1.4.0"
|
||||
gethostname = "0.4.3"
|
||||
wasm-bindgen = "0.2"
|
||||
wasm-bindgen = "=0.2.89"
|
||||
serde-wasm-bindgen = "0.4"
|
||||
wasm-bindgen-test = "0.3.0"
|
||||
convert_case = "0.6.0"
|
||||
|
||||
@@ -0,0 +1,4 @@
|
||||
#!/bin/bash
|
||||
set -eou pipefail
|
||||
|
||||
deno task wasmbuild --out ../../../cli/wasm/
|
||||
@@ -0,0 +1,5 @@
|
||||
{
|
||||
"tasks": {
|
||||
"wasmbuild": "deno run -A https://deno.land/x/wasmbuild@0.15.4/main.ts"
|
||||
}
|
||||
}
|
||||
@@ -1,6 +1,6 @@
|
||||
openapi: 3.0.3
|
||||
info:
|
||||
version: 1.242.0
|
||||
version: 1.244.2
|
||||
title: Windmill API
|
||||
contact:
|
||||
name: Windmill Team
|
||||
@@ -2530,13 +2530,10 @@ paths:
|
||||
type: string
|
||||
expires_in:
|
||||
type: integer
|
||||
owner:
|
||||
type: string
|
||||
client:
|
||||
type: string
|
||||
required:
|
||||
- expires_in
|
||||
- owner
|
||||
- client
|
||||
responses:
|
||||
'200':
|
||||
@@ -3358,32 +3355,32 @@ paths:
|
||||
id:
|
||||
type: string
|
||||
value:
|
||||
oneOf: &ref_204
|
||||
oneOf: &ref_206
|
||||
- type: object
|
||||
properties: &ref_188
|
||||
properties: &ref_190
|
||||
input_transforms:
|
||||
type: object
|
||||
additionalProperties:
|
||||
oneOf: &ref_26
|
||||
- type: object
|
||||
properties: &ref_184
|
||||
properties: &ref_186
|
||||
value: {}
|
||||
type:
|
||||
type: string
|
||||
enum:
|
||||
- javascript
|
||||
required: &ref_185
|
||||
required: &ref_187
|
||||
- expr
|
||||
- type
|
||||
- type: object
|
||||
properties: &ref_186
|
||||
properties: &ref_188
|
||||
expr:
|
||||
type: string
|
||||
type:
|
||||
type: string
|
||||
enum:
|
||||
- javascript
|
||||
required: &ref_187
|
||||
required: &ref_189
|
||||
- expr
|
||||
- type
|
||||
discriminator: &ref_27
|
||||
@@ -3423,13 +3420,13 @@ paths:
|
||||
type: number
|
||||
concurrency_time_window_s:
|
||||
type: number
|
||||
required: &ref_189
|
||||
required: &ref_191
|
||||
- type
|
||||
- content
|
||||
- language
|
||||
- input_transforms
|
||||
- type: object
|
||||
properties: &ref_190
|
||||
properties: &ref_192
|
||||
input_transforms:
|
||||
type: object
|
||||
additionalProperties:
|
||||
@@ -3443,12 +3440,12 @@ paths:
|
||||
type: string
|
||||
enum:
|
||||
- script
|
||||
required: &ref_191
|
||||
required: &ref_193
|
||||
- type
|
||||
- path
|
||||
- input_transforms
|
||||
- type: object
|
||||
properties: &ref_192
|
||||
properties: &ref_194
|
||||
input_transforms:
|
||||
type: object
|
||||
additionalProperties:
|
||||
@@ -3460,12 +3457,12 @@ paths:
|
||||
type: string
|
||||
enum:
|
||||
- flow
|
||||
required: &ref_193
|
||||
required: &ref_195
|
||||
- type
|
||||
- path
|
||||
- input_transforms
|
||||
- type: object
|
||||
properties: &ref_194
|
||||
properties: &ref_196
|
||||
modules:
|
||||
type: array
|
||||
items:
|
||||
@@ -3487,13 +3484,13 @@ paths:
|
||||
type: boolean
|
||||
parallelism:
|
||||
type: integer
|
||||
required: &ref_195
|
||||
required: &ref_197
|
||||
- modules
|
||||
- iterator
|
||||
- skip_failures
|
||||
- type
|
||||
- type: object
|
||||
properties: &ref_196
|
||||
properties: &ref_198
|
||||
branches:
|
||||
type: array
|
||||
items:
|
||||
@@ -3524,12 +3521,12 @@ paths:
|
||||
type: string
|
||||
enum:
|
||||
- branchone
|
||||
required: &ref_197
|
||||
required: &ref_199
|
||||
- branches
|
||||
- default
|
||||
- type
|
||||
- type: object
|
||||
properties: &ref_198
|
||||
properties: &ref_200
|
||||
branches:
|
||||
type: array
|
||||
items:
|
||||
@@ -3554,28 +3551,28 @@ paths:
|
||||
- branchall
|
||||
parallel:
|
||||
type: boolean
|
||||
required: &ref_199
|
||||
- branches
|
||||
- type
|
||||
- type: object
|
||||
properties: &ref_200
|
||||
type:
|
||||
type: string
|
||||
enum:
|
||||
- identity
|
||||
flow:
|
||||
type: boolean
|
||||
required: &ref_201
|
||||
- branches
|
||||
- type
|
||||
- type: object
|
||||
properties: &ref_202
|
||||
type:
|
||||
type: string
|
||||
enum:
|
||||
- graphql
|
||||
- identity
|
||||
flow:
|
||||
type: boolean
|
||||
required: &ref_203
|
||||
- type
|
||||
discriminator: &ref_205
|
||||
- type: object
|
||||
properties: &ref_204
|
||||
type:
|
||||
type: string
|
||||
enum:
|
||||
- graphql
|
||||
required: &ref_205
|
||||
- type
|
||||
discriminator: &ref_207
|
||||
propertyName: type
|
||||
mapping:
|
||||
rawscript: '#/components/schemas/RawScript'
|
||||
@@ -6746,6 +6743,71 @@ paths:
|
||||
schema:
|
||||
type: string
|
||||
format: uuid
|
||||
/w/{workspace}/jobs/run/dependencies:
|
||||
post:
|
||||
summary: run a one-off dependencies job
|
||||
operationId: runRawScriptDependencies
|
||||
tags:
|
||||
- job
|
||||
parameters:
|
||||
- name: workspace
|
||||
in: path
|
||||
required: true
|
||||
schema: *ref_0
|
||||
requestBody:
|
||||
description: raw script content
|
||||
required: true
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
type: object
|
||||
properties:
|
||||
raw_scripts:
|
||||
type: array
|
||||
items:
|
||||
type: object
|
||||
properties: &ref_184
|
||||
content:
|
||||
type: string
|
||||
path:
|
||||
type: string
|
||||
language:
|
||||
type: string
|
||||
enum:
|
||||
- python3
|
||||
- deno
|
||||
- go
|
||||
- bash
|
||||
- powershell
|
||||
- postgresql
|
||||
- mysql
|
||||
- bigquery
|
||||
- snowflake
|
||||
- mssql
|
||||
- graphql
|
||||
- nativets
|
||||
- bun
|
||||
required: &ref_185
|
||||
- content
|
||||
- path
|
||||
- language
|
||||
entrypoint:
|
||||
type: string
|
||||
required:
|
||||
- entrypoint
|
||||
- raw_scripts
|
||||
responses:
|
||||
'201':
|
||||
description: dependency job result
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
type: object
|
||||
properties:
|
||||
lock:
|
||||
type: string
|
||||
required:
|
||||
- lock
|
||||
/w/{workspace}/jobs/run/preview_flow:
|
||||
post:
|
||||
summary: run flow preview
|
||||
@@ -11224,56 +11286,60 @@ components:
|
||||
type: object
|
||||
properties: *ref_182
|
||||
required: *ref_183
|
||||
StaticTransform:
|
||||
RawScriptForDependencies:
|
||||
type: object
|
||||
properties: *ref_184
|
||||
required: *ref_185
|
||||
JavascriptTransform:
|
||||
StaticTransform:
|
||||
type: object
|
||||
properties: *ref_186
|
||||
required: *ref_187
|
||||
JavascriptTransform:
|
||||
type: object
|
||||
properties: *ref_188
|
||||
required: *ref_189
|
||||
InputTransform:
|
||||
oneOf: *ref_26
|
||||
discriminator: *ref_27
|
||||
RawScript:
|
||||
type: object
|
||||
properties: *ref_188
|
||||
required: *ref_189
|
||||
PathScript:
|
||||
type: object
|
||||
properties: *ref_190
|
||||
required: *ref_191
|
||||
PathFlow:
|
||||
PathScript:
|
||||
type: object
|
||||
properties: *ref_192
|
||||
required: *ref_193
|
||||
PathFlow:
|
||||
type: object
|
||||
properties: *ref_194
|
||||
required: *ref_195
|
||||
FlowModule:
|
||||
type: object
|
||||
properties: *ref_28
|
||||
required: *ref_29
|
||||
ForloopFlow:
|
||||
type: object
|
||||
properties: *ref_194
|
||||
required: *ref_195
|
||||
BranchOne:
|
||||
type: object
|
||||
properties: *ref_196
|
||||
required: *ref_197
|
||||
BranchAll:
|
||||
BranchOne:
|
||||
type: object
|
||||
properties: *ref_198
|
||||
required: *ref_199
|
||||
Identity:
|
||||
BranchAll:
|
||||
type: object
|
||||
properties: *ref_200
|
||||
required: *ref_201
|
||||
Graphql:
|
||||
Identity:
|
||||
type: object
|
||||
properties: *ref_202
|
||||
required: *ref_203
|
||||
Graphql:
|
||||
type: object
|
||||
properties: *ref_204
|
||||
required: *ref_205
|
||||
FlowModuleValue:
|
||||
oneOf: *ref_204
|
||||
discriminator: *ref_205
|
||||
oneOf: *ref_206
|
||||
discriminator: *ref_207
|
||||
Retry:
|
||||
type: object
|
||||
properties: *ref_78
|
||||
|
||||
@@ -4617,6 +4617,45 @@ paths:
|
||||
type: string
|
||||
format: uuid
|
||||
|
||||
/w/{workspace}/jobs/run/dependencies:
|
||||
post:
|
||||
summary: run a one-off dependencies job
|
||||
operationId: runRawScriptDependencies
|
||||
tags:
|
||||
- job
|
||||
parameters:
|
||||
- $ref: "#/components/parameters/WorkspaceId"
|
||||
|
||||
requestBody:
|
||||
description: raw script content
|
||||
required: true
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
type: object
|
||||
properties:
|
||||
raw_scripts:
|
||||
type: array
|
||||
items:
|
||||
$ref: "#/components/schemas/RawScriptForDependencies"
|
||||
entrypoint:
|
||||
type: string
|
||||
required:
|
||||
- entrypoint
|
||||
- raw_scripts
|
||||
responses:
|
||||
"201":
|
||||
description: dependency job result
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
type: object
|
||||
properties:
|
||||
lock:
|
||||
type: string
|
||||
required:
|
||||
- lock
|
||||
|
||||
/w/{workspace}/jobs/run/preview_flow:
|
||||
post:
|
||||
summary: run flow preview
|
||||
@@ -9313,3 +9352,33 @@ components:
|
||||
required:
|
||||
- timestamp
|
||||
- value
|
||||
|
||||
RawScriptForDependencies:
|
||||
type: object
|
||||
properties:
|
||||
content:
|
||||
type: string
|
||||
path:
|
||||
type: string
|
||||
language:
|
||||
type: string
|
||||
enum:
|
||||
[
|
||||
python3,
|
||||
deno,
|
||||
go,
|
||||
bash,
|
||||
powershell,
|
||||
postgresql,
|
||||
mysql,
|
||||
bigquery,
|
||||
snowflake,
|
||||
mssql,
|
||||
graphql,
|
||||
nativets,
|
||||
bun,
|
||||
]
|
||||
required:
|
||||
- content
|
||||
- path
|
||||
- language
|
||||
|
||||
@@ -152,6 +152,7 @@ pub fn workspaced_service() -> Router {
|
||||
"/result_by_id/:job_id/:node_id",
|
||||
get(get_result_by_id).layer(cors.clone()),
|
||||
)
|
||||
.route("/run/dependencies", post(run_dependencies_job))
|
||||
}
|
||||
|
||||
pub fn global_service() -> Router {
|
||||
@@ -1945,10 +1946,10 @@ pub struct WindmillCompositeResult {
|
||||
windmill_content_type: Option<String>,
|
||||
result: Option<Box<RawValue>>,
|
||||
}
|
||||
async fn run_wait_result<T>(
|
||||
async fn run_wait_result(
|
||||
db: &DB,
|
||||
uuid: Uuid,
|
||||
Path((w_id, _)): Path<(String, T)>,
|
||||
w_id: String,
|
||||
node_id_for_empty_return: Option<String>,
|
||||
) -> error::Result<Response> {
|
||||
let mut result;
|
||||
@@ -2183,7 +2184,7 @@ pub async fn run_wait_result_job_by_path_get(
|
||||
.await?;
|
||||
tx.commit().await?;
|
||||
|
||||
let wait_result = run_wait_result(&db, uuid, Path((w_id, script_path)), None).await;
|
||||
let wait_result = run_wait_result(&db, uuid, w_id, None).await;
|
||||
if delete_after_use.unwrap_or(false) {
|
||||
delete_job_metadata_after_use(&db, uuid).await?;
|
||||
}
|
||||
@@ -2302,7 +2303,7 @@ async fn run_wait_result_script_by_path_internal(
|
||||
.await?;
|
||||
tx.commit().await?;
|
||||
|
||||
let wait_result = run_wait_result(&db, uuid, Path((w_id, script_path)), None).await;
|
||||
let wait_result = run_wait_result(&db, uuid, w_id, None).await;
|
||||
if delete_after_use.unwrap_or(false) {
|
||||
delete_job_metadata_after_use(&db, uuid).await?;
|
||||
}
|
||||
@@ -2377,7 +2378,7 @@ pub async fn run_wait_result_script_by_hash(
|
||||
.await?;
|
||||
tx.commit().await?;
|
||||
|
||||
let wait_result = run_wait_result(&db, uuid, Path((w_id, script_hash)), None).await;
|
||||
let wait_result = run_wait_result(&db, uuid, w_id, None).await;
|
||||
if delete_after_use.unwrap_or(false) {
|
||||
delete_job_metadata_after_use(&db, uuid).await?;
|
||||
}
|
||||
@@ -2459,7 +2460,7 @@ async fn run_wait_result_flow_by_path_internal(
|
||||
.await?;
|
||||
tx.commit().await?;
|
||||
|
||||
run_wait_result(&db, uuid, Path((w_id, flow_path)), early_return).await
|
||||
run_wait_result(&db, uuid, w_id, early_return).await
|
||||
}
|
||||
|
||||
async fn run_preview_job(
|
||||
@@ -2527,6 +2528,82 @@ async fn run_preview_job(
|
||||
Ok((StatusCode::CREATED, uuid.to_string()))
|
||||
}
|
||||
|
||||
#[derive(Deserialize)]
|
||||
pub struct RunDependenciesRequest {
|
||||
pub raw_scripts: Vec<RawScriptForDependencies>,
|
||||
pub entrypoint: String,
|
||||
}
|
||||
|
||||
#[derive(Deserialize, Clone)]
|
||||
pub struct RawScriptForDependencies {
|
||||
pub script_path: String,
|
||||
pub raw_code: String,
|
||||
pub language: ScriptLang,
|
||||
}
|
||||
|
||||
#[derive(Serialize)]
|
||||
pub struct RunDependenciesResponse {
|
||||
pub dependencies: String,
|
||||
}
|
||||
|
||||
pub async fn run_dependencies_job(
|
||||
authed: ApiAuthed,
|
||||
Extension(db): Extension<DB>,
|
||||
Extension(rsmq): Extension<Option<rsmq_async::MultiplexedRsmq>>,
|
||||
Path(w_id): Path<String>,
|
||||
Json(req): Json<RunDependenciesRequest>,
|
||||
) -> error::Result<Response> {
|
||||
check_scopes(&authed, || format!("runscript"))?;
|
||||
if authed.is_operator {
|
||||
return Err(error::Error::NotAuthorized(
|
||||
"Operators cannot run dependencies jobs for security reasons".to_string(),
|
||||
));
|
||||
}
|
||||
|
||||
if req.raw_scripts.len() != 1 || req.raw_scripts[0].script_path != req.entrypoint {
|
||||
return Err(error::Error::InternalErr(
|
||||
"For now only a single raw script can be passed to this endpoint, and the entrypoint should be set to the script path".to_string(),
|
||||
));
|
||||
}
|
||||
let raw_script = req.raw_scripts[0].clone();
|
||||
let script_path = raw_script.script_path;
|
||||
let raw_code = raw_script.raw_code;
|
||||
let language = raw_script.language;
|
||||
|
||||
let (uuid, tx) = push(
|
||||
&db,
|
||||
PushIsolationLevel::IsolatedRoot(db.clone(), rsmq),
|
||||
&w_id,
|
||||
JobPayload::RawScriptDependencies {
|
||||
script_path: script_path,
|
||||
content: raw_code,
|
||||
language: language,
|
||||
},
|
||||
PushArgs::empty(),
|
||||
&authed.username,
|
||||
&authed.email,
|
||||
username_to_permissioned_as(&authed.username),
|
||||
None,
|
||||
None,
|
||||
None,
|
||||
None,
|
||||
None,
|
||||
false,
|
||||
false,
|
||||
None,
|
||||
true,
|
||||
None,
|
||||
None,
|
||||
None,
|
||||
None,
|
||||
)
|
||||
.await?;
|
||||
tx.commit().await?;
|
||||
|
||||
let wait_result = run_wait_result(&db, uuid, w_id, None).await;
|
||||
wait_result
|
||||
}
|
||||
|
||||
#[derive(Deserialize)]
|
||||
struct BatchInfo {
|
||||
kind: String,
|
||||
|
||||
@@ -294,6 +294,11 @@ pub enum JobPayload {
|
||||
path: String,
|
||||
version: i64,
|
||||
},
|
||||
RawScriptDependencies {
|
||||
script_path: String,
|
||||
content: String,
|
||||
language: ScriptLang,
|
||||
},
|
||||
Flow {
|
||||
path: String,
|
||||
dedicated_worker: Option<bool>,
|
||||
|
||||
@@ -2516,6 +2516,20 @@ pub async fn push<'c, T: Serialize + Send + Sync, R: rsmq_async::RsmqConnection
|
||||
dedicated_worker,
|
||||
None,
|
||||
),
|
||||
JobPayload::RawScriptDependencies { script_path, content, language } => (
|
||||
None,
|
||||
Some(script_path),
|
||||
Some((content, None)),
|
||||
JobKind::Dependencies,
|
||||
None,
|
||||
None,
|
||||
Some(language),
|
||||
None,
|
||||
None,
|
||||
None,
|
||||
None,
|
||||
None,
|
||||
),
|
||||
JobPayload::FlowDependencies { path, dedicated_worker } => {
|
||||
let value_json = fetch_scalar_isolated!(
|
||||
sqlx::query_scalar!(
|
||||
|
||||
@@ -3173,14 +3173,18 @@ async fn handle_dependency_job<R: rsmq_async::RsmqConnection + Send + Sync + Clo
|
||||
token: &str,
|
||||
rsmq: Option<R>,
|
||||
) -> error::Result<Box<RawValue>> {
|
||||
let raw_code = sqlx::query_scalar!(
|
||||
"SELECT content FROM script WHERE hash = $1 AND workspace_id = $2",
|
||||
&job.script_hash.unwrap_or(ScriptHash(0)).0,
|
||||
&job.workspace_id
|
||||
)
|
||||
.fetch_optional(db)
|
||||
.await?
|
||||
.unwrap_or_else(|| "No script found at this hash".to_string());
|
||||
let raw_code = match job.raw_code {
|
||||
Some(ref code) => code.to_owned(),
|
||||
None => sqlx::query_scalar!(
|
||||
"SELECT content FROM script WHERE hash = $1 AND workspace_id = $2",
|
||||
&job.script_hash.unwrap_or(ScriptHash(0)).0,
|
||||
&job.workspace_id
|
||||
)
|
||||
.fetch_optional(db)
|
||||
.await?
|
||||
.unwrap_or_else(|| "No script found at this hash".to_string()),
|
||||
};
|
||||
|
||||
let script_path = job.script_path();
|
||||
let content = capture_dependency_job(
|
||||
&job.id,
|
||||
@@ -3205,6 +3209,13 @@ async fn handle_dependency_job<R: rsmq_async::RsmqConnection + Send + Sync + Clo
|
||||
.await;
|
||||
match content {
|
||||
Ok(content) => {
|
||||
if job.script_hash.is_none() {
|
||||
// it a one-off raw script dependency job, no need to update the db
|
||||
return Ok(to_raw_value_owned(
|
||||
json!({ "success": "Successful lock file generation", "lock": content }),
|
||||
));
|
||||
}
|
||||
|
||||
let hash = job.script_hash.unwrap_or(ScriptHash(0));
|
||||
let w_id = &job.workspace_id;
|
||||
sqlx::query!(
|
||||
|
||||
@@ -0,0 +1,24 @@
|
||||
|
||||
export interface SchemaProperty {
|
||||
type: string | undefined
|
||||
description?: string
|
||||
pattern?: string
|
||||
default?: any
|
||||
enum?: string[]
|
||||
contentEncoding?: 'base64' | 'binary'
|
||||
format?: string
|
||||
items?: {
|
||||
type?: 'string' | 'number' | 'bytes' | 'object'
|
||||
contentEncoding?: 'base64'
|
||||
enum?: string[]
|
||||
}
|
||||
min?: number
|
||||
max?: number
|
||||
currency?: string
|
||||
currencyLocale?: string
|
||||
multiselect?: boolean
|
||||
customErrorMessage?: string
|
||||
properties?: { [name: string]: SchemaProperty }
|
||||
required?: string[]
|
||||
showExpr?: string
|
||||
}
|
||||
@@ -0,0 +1,35 @@
|
||||
import { SchemaProperty } from "./common.ts";
|
||||
|
||||
export interface FlowDefinition {
|
||||
summary: string,
|
||||
description: string,
|
||||
value: {
|
||||
modules: any[]
|
||||
},
|
||||
schema: {
|
||||
$schema: string,
|
||||
type: string,
|
||||
order: string[],
|
||||
properties: { [name: string]: SchemaProperty},
|
||||
required: string[]
|
||||
}
|
||||
ws_error_handler_muted: false
|
||||
}
|
||||
|
||||
export function defaultFlowDefinition(): FlowDefinition {
|
||||
return {
|
||||
summary: '',
|
||||
description: '',
|
||||
value: {
|
||||
modules: []
|
||||
},
|
||||
schema: {
|
||||
$schema: 'https://json-schema.org/draft/2020-12/schema',
|
||||
type: 'object',
|
||||
order: [],
|
||||
properties: {},
|
||||
required: []
|
||||
},
|
||||
ws_error_handler_muted: false,
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,83 @@
|
||||
import { SchemaProperty } from "./common.ts";
|
||||
|
||||
export interface ScriptMetadata {
|
||||
summary: string,
|
||||
description: string,
|
||||
lock: string[],
|
||||
is_template: boolean,
|
||||
kind: string,
|
||||
schema: {
|
||||
$schema: string,
|
||||
type: string,
|
||||
properties: { [name: string]: SchemaProperty},
|
||||
required: string[]
|
||||
}
|
||||
}
|
||||
|
||||
export function defaultScriptMetadata(): ScriptMetadata {
|
||||
return {
|
||||
summary: '',
|
||||
description: '',
|
||||
lock: [],
|
||||
is_template: false,
|
||||
kind: 'script',
|
||||
schema: {
|
||||
$schema: 'https://json-schema.org/draft/2020-12/schema',
|
||||
type: 'object',
|
||||
properties: {},
|
||||
required: []
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export const scriptBootstrapCode = {
|
||||
python3: `def main():
|
||||
return "Hello world"
|
||||
`,
|
||||
|
||||
nativets: `export async function main() {
|
||||
return "Hello world";
|
||||
}
|
||||
`,
|
||||
|
||||
bun: `export async function main() {
|
||||
return "Hello world";
|
||||
}
|
||||
`,
|
||||
|
||||
deno: `export async function main() {
|
||||
return "Hello world";
|
||||
}
|
||||
`,
|
||||
|
||||
go: `package inner
|
||||
func main() (interface{}, error) {
|
||||
return "Hello world", nil
|
||||
}
|
||||
`,
|
||||
|
||||
mysql: `SELECT 'Hello world' AS message
|
||||
`,
|
||||
|
||||
bigquery: `SELECT 'Hello world' AS message
|
||||
`,
|
||||
|
||||
snowflake: `SELECT 'Hello world' AS message
|
||||
`,
|
||||
|
||||
mssql: `SELECT 'Hello world' AS message
|
||||
`,
|
||||
|
||||
graphql: `query() {
|
||||
demo() {}
|
||||
}`,
|
||||
|
||||
postgresql: `SELECT 'Hello world' AS message
|
||||
`,
|
||||
|
||||
bash: `echo "Hello world"
|
||||
`,
|
||||
|
||||
powershell: `Write-Output "Hello world"`,
|
||||
|
||||
}
|
||||
+33
-2
@@ -1,6 +1,6 @@
|
||||
// deno-lint-ignore-file no-explicit-any
|
||||
import { GlobalOptions, isSuperset } from "./types.ts";
|
||||
import { SEP, log } from "./deps.ts";
|
||||
import { SEP, log, yamlStringify } from "./deps.ts";
|
||||
import {
|
||||
colors,
|
||||
Command,
|
||||
@@ -13,6 +13,7 @@ import {
|
||||
} from "./deps.ts";
|
||||
import { requireLogin, resolveWorkspace, validatePath } from "./context.ts";
|
||||
import { resolve, track_job } from "./script.ts";
|
||||
import { defaultFlowDefinition } from "./bootstrap/flow_bootstrap.ts";
|
||||
|
||||
export interface FlowFile {
|
||||
summary: string;
|
||||
@@ -193,6 +194,31 @@ async function run(
|
||||
log.info(jobInfo.result ?? {});
|
||||
}
|
||||
|
||||
export function bootstrap(opts: GlobalOptions & {summary: string, description: string}, flowPath: string) {
|
||||
if (!validatePath(flowPath)) {
|
||||
return;
|
||||
}
|
||||
|
||||
const flowDirFullPath = `${flowPath}.flow`
|
||||
Deno.mkdirSync(flowDirFullPath, { recursive: false });
|
||||
|
||||
const newFlowDefinition = defaultFlowDefinition();
|
||||
if (opts.summary !== undefined) {
|
||||
newFlowDefinition.summary = opts.summary;
|
||||
}
|
||||
if (opts.description !== undefined) {
|
||||
newFlowDefinition.description = opts.description;
|
||||
}
|
||||
|
||||
const newFlowDefinitionYaml = yamlStringify(newFlowDefinition as Record<string, any>);
|
||||
|
||||
const flowYamlPath = `${flowDirFullPath}/flow.yaml`;
|
||||
Deno.writeTextFile(
|
||||
flowYamlPath,
|
||||
newFlowDefinitionYaml,
|
||||
{ createNew: true });
|
||||
}
|
||||
|
||||
const command = new Command()
|
||||
.description("flow related commands")
|
||||
.option("--show-archived", "Enable archived scripts in output")
|
||||
@@ -213,6 +239,11 @@ const command = new Command()
|
||||
"-s --silent",
|
||||
"Do not ouput anything other then the final output. Useful for scripting."
|
||||
)
|
||||
.action(run as any);
|
||||
.action(run as any)
|
||||
.command("bootstrap", "create a new empty flow")
|
||||
.arguments("<flow_path:string>")
|
||||
.option("--summary <summary:string>", "script summary")
|
||||
.option("--description <description:string>", "script description")
|
||||
.action(bootstrap as any);
|
||||
|
||||
export default command;
|
||||
|
||||
+384
-31
@@ -13,8 +13,13 @@ import {
|
||||
Table,
|
||||
writeAllSync,
|
||||
yamlParse,
|
||||
yamlStringify,
|
||||
} from "./deps.ts";
|
||||
import { deepEqual } from "./utils.ts";
|
||||
import { defaultScriptMetadata, scriptBootstrapCode } from "./bootstrap/script_bootstrap.ts";
|
||||
import { instantiate as instantiateWasm, parse_bash, parse_bigquery, parse_deno, parse_go, parse_graphql, parse_mssql, parse_mysql, parse_powershell, parse_python, parse_snowflake, parse_sql } from "./wasm/windmill_parser_wasm.generated.js"
|
||||
import { Workspace } from "./workspace.ts";
|
||||
import { SchemaProperty } from "./bootstrap/common.ts";
|
||||
|
||||
export interface ScriptFile {
|
||||
parent_hash?: string;
|
||||
@@ -63,6 +68,29 @@ export async function handleScriptMetadata(
|
||||
}
|
||||
}
|
||||
|
||||
async function parseMetadataFile(scriptPath: string): Promise<{isJson: boolean, payload: any} | undefined> {
|
||||
let metadataFilePath = scriptPath + ".script.json";
|
||||
try {
|
||||
await Deno.stat(metadataFilePath);
|
||||
return {
|
||||
payload: JSON.parse(await Deno.readTextFile(metadataFilePath)),
|
||||
isJson: true,
|
||||
}
|
||||
} catch {
|
||||
try {
|
||||
metadataFilePath = scriptPath + ".script.yaml";
|
||||
await Deno.stat(metadataFilePath);
|
||||
return {
|
||||
payload: yamlParse(await Deno.readTextFile(metadataFilePath)),
|
||||
isJson: false,
|
||||
}
|
||||
} catch {
|
||||
// no meta file
|
||||
}
|
||||
}
|
||||
return undefined;
|
||||
}
|
||||
|
||||
export async function handleFile(
|
||||
path: string,
|
||||
workspace: string,
|
||||
@@ -88,21 +116,7 @@ export async function handleFile(
|
||||
const remotePath = path
|
||||
.substring(0, path.indexOf("."))
|
||||
.replaceAll("\\", "/");
|
||||
const metaPath = remotePath + ".script.json";
|
||||
let typed = undefined;
|
||||
try {
|
||||
await Deno.stat(metaPath);
|
||||
typed = JSON.parse(await Deno.readTextFile(metaPath));
|
||||
} catch {
|
||||
const metaPath = remotePath + ".script.yaml";
|
||||
try {
|
||||
await Deno.stat(metaPath);
|
||||
typed = yamlParse(await Deno.readTextFile(metaPath));
|
||||
} catch {
|
||||
// no meta file
|
||||
}
|
||||
}
|
||||
|
||||
const typed = (await parseMetadataFile(path))?.payload;
|
||||
const language = inferContentTypeFromFilePath(path);
|
||||
|
||||
let remote = undefined;
|
||||
@@ -256,22 +270,45 @@ export async function findContentFile(filePath: string) {
|
||||
return validCandidates[0];
|
||||
}
|
||||
|
||||
type ScriptLanguage = "python3" | "deno" | "bun" | "nativets" | "go" | "bash" | "powershell" | "postgresql" | "mysql" | "bigquery" | "snowflake" | "mssql" | "graphql";
|
||||
|
||||
export function filePathExtensionFromContentType(language: ScriptLanguage): string {
|
||||
if (language === "python3") {
|
||||
return ".py";
|
||||
} else if (language === "nativets") {
|
||||
return ".fetch.ts";
|
||||
} else if (language === "bun") {
|
||||
return ".bun.ts";
|
||||
} else if (language === "deno") {
|
||||
return ".ts";
|
||||
} else if (language === "go") {
|
||||
return ".go";
|
||||
} else if (language === "mysql") {
|
||||
return ".my.sql";
|
||||
} else if (language === "bigquery") {
|
||||
return ".bq.sql";
|
||||
} else if (language === "snowflake") {
|
||||
return ".sf.sql";
|
||||
} else if (language === "mssql") {
|
||||
return ".ms.sql";
|
||||
} else if (language === "postgresql") {
|
||||
return ".pg.sql";
|
||||
} else if (language === "graphql") {
|
||||
return ".gql";
|
||||
} else if (language === "bash") {
|
||||
return ".sh";
|
||||
} else if (language === "powershell") {
|
||||
return ".ps1";
|
||||
} else {
|
||||
throw new Error(
|
||||
"Invalid language: " + language
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
export function inferContentTypeFromFilePath(
|
||||
contentPath: string
|
||||
):
|
||||
| "python3"
|
||||
| "deno"
|
||||
| "bun"
|
||||
| "nativets"
|
||||
| "go"
|
||||
| "bash"
|
||||
| "powershell"
|
||||
| "postgresql"
|
||||
| "mysql"
|
||||
| "bigquery"
|
||||
| "snowflake"
|
||||
| "mssql"
|
||||
| "graphql" {
|
||||
): ScriptLanguage {
|
||||
if (contentPath.endsWith(".py")) {
|
||||
return "python3";
|
||||
} else if (contentPath.endsWith("fetch.ts")) {
|
||||
@@ -305,6 +342,189 @@ export function inferContentTypeFromFilePath(
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// below functions copied from Windmill's FE inferArgs function. TODO: refactor //
|
||||
////////////////////////////////////////////////////////////////////////////////////////////
|
||||
export function inferSchema(language: ScriptLanguage, content: string, currentSchema: any) {
|
||||
let inferedSchema: any;
|
||||
if (language === "python3") {
|
||||
inferedSchema = JSON.parse(parse_python(content));
|
||||
} else if (language === "nativets") {
|
||||
inferedSchema = JSON.parse(parse_deno(content));
|
||||
} else if (language === "bun") {
|
||||
inferedSchema = JSON.parse(parse_deno(content));
|
||||
} else if (language === "deno") {
|
||||
inferedSchema = JSON.parse(parse_deno(content));
|
||||
} else if (language === "go") {
|
||||
inferedSchema = JSON.parse(parse_go(content));
|
||||
} else if (language === "mysql") {
|
||||
inferedSchema = JSON.parse(parse_mysql(content));
|
||||
inferedSchema.args = [
|
||||
{ name: 'database', typ: { resource: 'mysql' } },
|
||||
...inferedSchema.args
|
||||
]
|
||||
} else if (language === "bigquery") {
|
||||
inferedSchema = JSON.parse(parse_bigquery(content));
|
||||
inferedSchema.args = [
|
||||
{ name: 'database', typ: { resource: 'bigquery' } },
|
||||
...inferedSchema.args
|
||||
]
|
||||
} else if (language === "snowflake") {
|
||||
inferedSchema = JSON.parse(parse_snowflake(content));
|
||||
inferedSchema.args = [
|
||||
{ name: 'database', typ: { resource: 'snowflake' } },
|
||||
...inferedSchema.args
|
||||
]
|
||||
} else if (language === "mssql") {
|
||||
inferedSchema = JSON.parse(parse_mssql(content));
|
||||
inferedSchema.args = [
|
||||
{ name: 'database', typ: { resource: 'ms_sql_server' } },
|
||||
...inferedSchema.args
|
||||
]
|
||||
} else if (language === "postgresql") {
|
||||
inferedSchema = JSON.parse(parse_sql(content));
|
||||
inferedSchema.args = [
|
||||
{ name: 'database', typ: { resource: 'postgresql' } },
|
||||
...inferedSchema.args
|
||||
]
|
||||
} else if (language === "graphql") {
|
||||
inferedSchema = JSON.parse(parse_graphql(content));
|
||||
inferedSchema.args = [
|
||||
{ name: 'api', typ: { resource: 'graphql' } },
|
||||
...inferedSchema.args
|
||||
]
|
||||
} else if (language === "bash") {
|
||||
inferedSchema = JSON.parse(parse_bash(content));
|
||||
} else if (language === "powershell") {
|
||||
inferedSchema = JSON.parse(parse_powershell(content));
|
||||
} else {
|
||||
throw new Error(
|
||||
"Invalid language: " + language
|
||||
);
|
||||
}
|
||||
if (inferedSchema.type == 'Invalid') {
|
||||
throw new Error(`Script invalid, it cannot be parsed to infer schema. Error was: ${inferedSchema.error}`)
|
||||
}
|
||||
|
||||
currentSchema.required = []
|
||||
const oldProperties = JSON.parse(JSON.stringify(currentSchema.properties))
|
||||
currentSchema.properties = {}
|
||||
|
||||
for (const arg of inferedSchema.args) {
|
||||
if (!(arg.name in oldProperties)) {
|
||||
currentSchema.properties[arg.name] = { description: '', type: '' }
|
||||
} else {
|
||||
currentSchema.properties[arg.name] = oldProperties[arg.name]
|
||||
}
|
||||
currentSchema.properties[arg.name] = sortObject(currentSchema.properties[arg.name])
|
||||
|
||||
argSigToJsonSchemaType(arg.typ, currentSchema.properties[arg.name])
|
||||
|
||||
currentSchema.properties[arg.name].default = arg.default
|
||||
|
||||
if (!arg.has_default && !currentSchema.required.includes(arg.name)) {
|
||||
currentSchema.required.push(arg.name)
|
||||
}
|
||||
}
|
||||
|
||||
return currentSchema;
|
||||
}
|
||||
|
||||
function sortObject(obj: any): any {
|
||||
return Object.keys(obj)
|
||||
.sort()
|
||||
.reduce((acc, key) => ({
|
||||
...acc, [key]: obj[key]
|
||||
}), {})
|
||||
}
|
||||
|
||||
function argSigToJsonSchemaType(
|
||||
typ:
|
||||
| string
|
||||
| { resource: string | null }
|
||||
| { list: string | { str: any } | { object: { key: string; typ: any }[] } | null }
|
||||
| { str: string[] | null }
|
||||
| { object: { key: string; typ: any }[] },
|
||||
oldS: SchemaProperty
|
||||
): void {
|
||||
const newS: SchemaProperty = { type: '' }
|
||||
if (typ === 'int') {
|
||||
newS.type = 'integer'
|
||||
} else if (typ === 'float') {
|
||||
newS.type = 'number'
|
||||
} else if (typ === 'bool') {
|
||||
newS.type = 'boolean'
|
||||
} else if (typ === 'email') {
|
||||
newS.type = 'string'
|
||||
newS.format = 'email'
|
||||
} else if (typ === 'sql') {
|
||||
newS.type = 'string'
|
||||
newS.format = 'sql'
|
||||
} else if (typ === 'yaml') {
|
||||
newS.type = 'string'
|
||||
newS.format = 'yaml'
|
||||
} else if (typ === 'bytes') {
|
||||
newS.type = 'string'
|
||||
newS.contentEncoding = 'base64'
|
||||
} else if (typ === 'datetime') {
|
||||
newS.type = 'string'
|
||||
newS.format = 'date-time'
|
||||
} else if (typeof typ !== 'string' && `object` in typ) {
|
||||
newS.type = 'object'
|
||||
if (typ.object) {
|
||||
const properties: Record<string, SchemaProperty> = {};
|
||||
for (const prop of typ.object) {
|
||||
properties[prop.key] = {type: undefined}
|
||||
argSigToJsonSchemaType(prop.typ, properties[prop.key])
|
||||
}
|
||||
newS.properties = properties
|
||||
}
|
||||
} else if (typeof typ !== 'string' && `str` in typ) {
|
||||
newS.type = 'string'
|
||||
if (typ.str) {
|
||||
newS.enum = typ.str
|
||||
}
|
||||
} else if (typeof typ !== 'string' && `resource` in typ) {
|
||||
newS.type = 'object'
|
||||
newS.format = `resource-${typ.resource}`
|
||||
} else if (typeof typ !== 'string' && `list` in typ) {
|
||||
newS.type = 'array'
|
||||
if (typ.list === 'int' || typ.list === 'float') {
|
||||
newS.items = { type: 'number' }
|
||||
} else if (typ.list === 'bytes') {
|
||||
newS.items = { type: 'string', contentEncoding: 'base64' }
|
||||
} else if (typ.list == 'string') {
|
||||
newS.items = { type: 'string' }
|
||||
} else if (typ.list && typeof typ.list == 'object' && 'str' in typ.list) {
|
||||
newS.items = { type: 'string', enum: typ.list.str }
|
||||
} else {
|
||||
newS.items = { type: 'object' }
|
||||
}
|
||||
} else {
|
||||
newS.type = 'object'
|
||||
}
|
||||
|
||||
if (oldS.type != newS.type) {
|
||||
for (const prop of Object.getOwnPropertyNames(newS)) {
|
||||
if (prop != 'description') {
|
||||
delete oldS[prop]
|
||||
}
|
||||
}
|
||||
} else if (oldS.format == 'date-time' && newS.format != 'date-time') {
|
||||
delete oldS.format
|
||||
} else if (oldS.items?.type != newS.items?.type) {
|
||||
delete oldS.items
|
||||
}
|
||||
|
||||
Object.assign(oldS, newS)
|
||||
if (oldS.format?.startsWith('resource-') && newS.type != 'object') {
|
||||
oldS.format = undefined
|
||||
}
|
||||
}
|
||||
////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// end of refactoring TODO //
|
||||
////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
async function list(opts: GlobalOptions & { showArchived?: boolean }) {
|
||||
const workspace = await resolveWorkspace(opts);
|
||||
await requireLogin(opts);
|
||||
@@ -484,6 +704,129 @@ async function show(opts: GlobalOptions, path: string) {
|
||||
log.info(s.content);
|
||||
}
|
||||
|
||||
async function bootstrap(opts: GlobalOptions & {summary: string, description: string}, scriptPath: string, language: ScriptLanguage) {
|
||||
if (!validatePath(scriptPath)) {
|
||||
return;
|
||||
}
|
||||
|
||||
const scriptInitialCode = scriptBootstrapCode[language];
|
||||
if (scriptInitialCode === undefined) {
|
||||
throw new Error("Language unknown");
|
||||
}
|
||||
|
||||
const extension = filePathExtensionFromContentType(language);
|
||||
const scriptCodeFileFullPath = scriptPath + extension;
|
||||
const scriptMetadataFileFullPath = scriptPath + ".script.yaml";
|
||||
|
||||
try {
|
||||
await Deno.stat(scriptCodeFileFullPath);
|
||||
await Deno.stat(scriptMetadataFileFullPath);
|
||||
throw new Error("File already exists in repository");
|
||||
} catch {
|
||||
// file does not exist, we can continue
|
||||
}
|
||||
|
||||
const scriptMetadata = defaultScriptMetadata();
|
||||
if (opts.summary !== undefined) {
|
||||
scriptMetadata.summary = opts.summary;
|
||||
}
|
||||
if (opts.description !== undefined) {
|
||||
scriptMetadata.description = opts.description;
|
||||
}
|
||||
|
||||
const scriptInitialMetadataYaml = yamlStringify(scriptMetadata as Record<string, any>);
|
||||
|
||||
Deno.writeTextFile(
|
||||
scriptCodeFileFullPath,
|
||||
scriptInitialCode,
|
||||
{ createNew: true });
|
||||
Deno.writeTextFile(
|
||||
scriptMetadataFileFullPath,
|
||||
scriptInitialMetadataYaml,
|
||||
{ createNew: true });
|
||||
}
|
||||
|
||||
async function generateMetadata(opts: GlobalOptions & {lockOnly: boolean, schemaOnly: boolean}, scriptPath: string) {
|
||||
if (!validatePath(scriptPath)) {
|
||||
return;
|
||||
}
|
||||
|
||||
const workspace = await resolveWorkspace(opts);
|
||||
await requireLogin(opts);
|
||||
|
||||
const language = inferContentTypeFromFilePath(scriptPath);
|
||||
|
||||
// read script metadata file
|
||||
const remotePath = scriptPath
|
||||
.substring(0, scriptPath.indexOf("."))
|
||||
.replaceAll("\\", "/");
|
||||
const metadataWithType = await parseMetadataFile(remotePath);
|
||||
if (metadataWithType === undefined) {
|
||||
throw new Error("Script metadata file does not exist at this path");
|
||||
}
|
||||
|
||||
// read script content
|
||||
const scriptContent = await Deno.readTextFile(scriptPath);
|
||||
|
||||
const metadataParsedContent = metadataWithType?.payload as Record<string, any>;
|
||||
|
||||
if (!opts.lockOnly) {
|
||||
await updateScriptSchema(scriptContent, language, metadataParsedContent);
|
||||
}
|
||||
|
||||
if (!opts.schemaOnly) {
|
||||
await updateScriptLock(workspace, scriptContent, language, remotePath, metadataParsedContent);
|
||||
}
|
||||
|
||||
let metaPath = remotePath + ".script.yaml";
|
||||
let newMetadataContent = yamlStringify(metadataParsedContent);
|
||||
if (metadataWithType.isJson) {
|
||||
metaPath = remotePath + ".script.json"
|
||||
newMetadataContent = JSON.stringify(metadataParsedContent);
|
||||
}
|
||||
Deno.writeTextFile(
|
||||
metaPath,
|
||||
newMetadataContent);
|
||||
}
|
||||
|
||||
async function updateScriptSchema(scriptContent: string, language: ScriptLanguage, metadataContent: Record<string, any>): Promise<void> {
|
||||
// infer schema from script content and update it inplace
|
||||
await instantiateWasm();
|
||||
const newSchema = inferSchema(language, scriptContent, metadataContent.schema);
|
||||
metadataContent.schema = newSchema;
|
||||
}
|
||||
|
||||
async function updateScriptLock(workspace: Workspace, scriptContent: string, language: ScriptLanguage, remotePath: string, metadataContent: Record<string, any>): Promise<void> {
|
||||
// generate the script lock running a dependency job in Windmill and update it inplace
|
||||
// TODO: update this once the client is released
|
||||
const rawResponse = await fetch(`${workspace.remote}api/w/${workspace.workspaceId}/jobs/run/dependencies`, {
|
||||
method: "POST",
|
||||
headers: {
|
||||
"Cookie": `token=${workspace.token}`,
|
||||
"Content-Type": "application/json"
|
||||
},
|
||||
body: JSON.stringify({
|
||||
"raw_scripts": [{
|
||||
"raw_code": scriptContent,
|
||||
"language": language,
|
||||
"script_path": remotePath,
|
||||
}],
|
||||
"entrypoint": remotePath,
|
||||
})
|
||||
});
|
||||
|
||||
try {
|
||||
const response = await rawResponse.json();
|
||||
const lock = response.lock;
|
||||
if (lock === undefined) {
|
||||
throw new Error(`Failed to generate lockfile. Full response was: ${JSON.stringify(response)}`);
|
||||
}
|
||||
metadataContent.lock = lock.split("\n");
|
||||
} catch {
|
||||
throw new Error(`Failed to generate lockfile. Status was: ${rawResponse.statusText}`);
|
||||
}
|
||||
}
|
||||
|
||||
const command = new Command()
|
||||
.description("script related commands")
|
||||
.option("--show-archived", "Enable archived scripts in output")
|
||||
@@ -505,8 +848,18 @@ const command = new Command()
|
||||
)
|
||||
.option(
|
||||
"-s --silent",
|
||||
"Do not ouput anything other then the final output. Useful for scripting."
|
||||
"Do not output anything other then the final output. Useful for scripting."
|
||||
)
|
||||
.action(run as any);
|
||||
.action(run as any)
|
||||
.command("bootstrap", "create a new script")
|
||||
.arguments("<path:string> <language:string>")
|
||||
.option("--summary <summary:string>", "script summary")
|
||||
.option("--description <description:string>", "script description")
|
||||
.action(bootstrap as any)
|
||||
.command("generate-metadata", "re-generate the metadata file updating the lock and the script schema")
|
||||
.arguments("<path:string>")
|
||||
.option("--lock-only", "re-generate only the lock")
|
||||
.option("--schema-only", "re-generate only script schema")
|
||||
.action(generateMetadata as any);
|
||||
|
||||
export default command;
|
||||
|
||||
@@ -0,0 +1,832 @@
|
||||
// @generated file from wasmbuild -- do not edit
|
||||
// deno-lint-ignore-file
|
||||
// deno-fmt-ignore-file
|
||||
// source-hash: f38890e80d35ec2affe2a260e12308f96bcbf771
|
||||
let wasm;
|
||||
|
||||
const heap = new Array(128).fill(undefined);
|
||||
|
||||
heap.push(undefined, null, true, false);
|
||||
|
||||
function getObject(idx) {
|
||||
return heap[idx];
|
||||
}
|
||||
|
||||
let heap_next = heap.length;
|
||||
|
||||
function dropObject(idx) {
|
||||
if (idx < 132) return;
|
||||
heap[idx] = heap_next;
|
||||
heap_next = idx;
|
||||
}
|
||||
|
||||
function takeObject(idx) {
|
||||
const ret = getObject(idx);
|
||||
dropObject(idx);
|
||||
return ret;
|
||||
}
|
||||
|
||||
let WASM_VECTOR_LEN = 0;
|
||||
|
||||
let cachedUint8Memory0 = null;
|
||||
|
||||
function getUint8Memory0() {
|
||||
if (cachedUint8Memory0 === null || cachedUint8Memory0.byteLength === 0) {
|
||||
cachedUint8Memory0 = new Uint8Array(wasm.memory.buffer);
|
||||
}
|
||||
return cachedUint8Memory0;
|
||||
}
|
||||
|
||||
const cachedTextEncoder = typeof TextEncoder !== "undefined"
|
||||
? new TextEncoder("utf-8")
|
||||
: {
|
||||
encode: () => {
|
||||
throw Error("TextEncoder not available");
|
||||
},
|
||||
};
|
||||
|
||||
const encodeString = function (arg, view) {
|
||||
return cachedTextEncoder.encodeInto(arg, view);
|
||||
};
|
||||
|
||||
function passStringToWasm0(arg, malloc, realloc) {
|
||||
if (realloc === undefined) {
|
||||
const buf = cachedTextEncoder.encode(arg);
|
||||
const ptr = malloc(buf.length, 1) >>> 0;
|
||||
getUint8Memory0().subarray(ptr, ptr + buf.length).set(buf);
|
||||
WASM_VECTOR_LEN = buf.length;
|
||||
return ptr;
|
||||
}
|
||||
|
||||
let len = arg.length;
|
||||
let ptr = malloc(len, 1) >>> 0;
|
||||
|
||||
const mem = getUint8Memory0();
|
||||
|
||||
let offset = 0;
|
||||
|
||||
for (; offset < len; offset++) {
|
||||
const code = arg.charCodeAt(offset);
|
||||
if (code > 0x7F) break;
|
||||
mem[ptr + offset] = code;
|
||||
}
|
||||
|
||||
if (offset !== len) {
|
||||
if (offset !== 0) {
|
||||
arg = arg.slice(offset);
|
||||
}
|
||||
ptr = realloc(ptr, len, len = offset + arg.length * 3, 1) >>> 0;
|
||||
const view = getUint8Memory0().subarray(ptr + offset, ptr + len);
|
||||
const ret = encodeString(arg, view);
|
||||
|
||||
offset += ret.written;
|
||||
}
|
||||
|
||||
WASM_VECTOR_LEN = offset;
|
||||
return ptr;
|
||||
}
|
||||
|
||||
function isLikeNone(x) {
|
||||
return x === undefined || x === null;
|
||||
}
|
||||
|
||||
let cachedInt32Memory0 = null;
|
||||
|
||||
function getInt32Memory0() {
|
||||
if (cachedInt32Memory0 === null || cachedInt32Memory0.byteLength === 0) {
|
||||
cachedInt32Memory0 = new Int32Array(wasm.memory.buffer);
|
||||
}
|
||||
return cachedInt32Memory0;
|
||||
}
|
||||
|
||||
const 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 getStringFromWasm0(ptr, len) {
|
||||
ptr = ptr >>> 0;
|
||||
return cachedTextDecoder.decode(getUint8Memory0().subarray(ptr, ptr + len));
|
||||
}
|
||||
|
||||
function addHeapObject(obj) {
|
||||
if (heap_next === heap.length) heap.push(heap.length + 1);
|
||||
const idx = heap_next;
|
||||
heap_next = heap[idx];
|
||||
|
||||
heap[idx] = obj;
|
||||
return idx;
|
||||
}
|
||||
|
||||
let cachedFloat64Memory0 = null;
|
||||
|
||||
function getFloat64Memory0() {
|
||||
if (cachedFloat64Memory0 === null || cachedFloat64Memory0.byteLength === 0) {
|
||||
cachedFloat64Memory0 = new Float64Array(wasm.memory.buffer);
|
||||
}
|
||||
return cachedFloat64Memory0;
|
||||
}
|
||||
|
||||
let cachedBigInt64Memory0 = null;
|
||||
|
||||
function getBigInt64Memory0() {
|
||||
if (
|
||||
cachedBigInt64Memory0 === null || cachedBigInt64Memory0.byteLength === 0
|
||||
) {
|
||||
cachedBigInt64Memory0 = new BigInt64Array(wasm.memory.buffer);
|
||||
}
|
||||
return cachedBigInt64Memory0;
|
||||
}
|
||||
|
||||
function debugString(val) {
|
||||
// primitive types
|
||||
const type = typeof val;
|
||||
if (type == "number" || type == "boolean" || val == null) {
|
||||
return `${val}`;
|
||||
}
|
||||
if (type == "string") {
|
||||
return `"${val}"`;
|
||||
}
|
||||
if (type == "symbol") {
|
||||
const description = val.description;
|
||||
if (description == null) {
|
||||
return "Symbol";
|
||||
} else {
|
||||
return `Symbol(${description})`;
|
||||
}
|
||||
}
|
||||
if (type == "function") {
|
||||
const name = val.name;
|
||||
if (typeof name == "string" && name.length > 0) {
|
||||
return `Function(${name})`;
|
||||
} else {
|
||||
return "Function";
|
||||
}
|
||||
}
|
||||
// objects
|
||||
if (Array.isArray(val)) {
|
||||
const length = val.length;
|
||||
let debug = "[";
|
||||
if (length > 0) {
|
||||
debug += debugString(val[0]);
|
||||
}
|
||||
for (let i = 1; i < length; i++) {
|
||||
debug += ", " + debugString(val[i]);
|
||||
}
|
||||
debug += "]";
|
||||
return debug;
|
||||
}
|
||||
// Test for built-in
|
||||
const builtInMatches = /\[object ([^\]]+)\]/.exec(toString.call(val));
|
||||
let className;
|
||||
if (builtInMatches.length > 1) {
|
||||
className = builtInMatches[1];
|
||||
} else {
|
||||
// Failed to match the standard '[object ClassName]'
|
||||
return toString.call(val);
|
||||
}
|
||||
if (className == "Object") {
|
||||
// we're a user defined class or Object
|
||||
// JSON.stringify avoids problems with cycles, and is generally much
|
||||
// easier than looping through ownProperties of `val`.
|
||||
try {
|
||||
return "Object(" + JSON.stringify(val) + ")";
|
||||
} catch (_) {
|
||||
return "Object";
|
||||
}
|
||||
}
|
||||
// errors
|
||||
if (val instanceof Error) {
|
||||
return `${val.name}: ${val.message}\n${val.stack}`;
|
||||
}
|
||||
// TODO we could test for more things here, like `Set`s and `Map`s.
|
||||
return className;
|
||||
}
|
||||
/**
|
||||
* @param {string} code
|
||||
* @returns {string}
|
||||
*/
|
||||
export function parse_deno(code) {
|
||||
let deferred2_0;
|
||||
let deferred2_1;
|
||||
try {
|
||||
const retptr = wasm.__wbindgen_add_to_stack_pointer(-16);
|
||||
const ptr0 = passStringToWasm0(
|
||||
code,
|
||||
wasm.__wbindgen_malloc,
|
||||
wasm.__wbindgen_realloc,
|
||||
);
|
||||
const len0 = WASM_VECTOR_LEN;
|
||||
wasm.parse_deno(retptr, ptr0, len0);
|
||||
var r0 = getInt32Memory0()[retptr / 4 + 0];
|
||||
var r1 = getInt32Memory0()[retptr / 4 + 1];
|
||||
deferred2_0 = r0;
|
||||
deferred2_1 = r1;
|
||||
return getStringFromWasm0(r0, r1);
|
||||
} finally {
|
||||
wasm.__wbindgen_add_to_stack_pointer(16);
|
||||
wasm.__wbindgen_free(deferred2_0, deferred2_1, 1);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {string} code
|
||||
* @returns {string}
|
||||
*/
|
||||
export function parse_outputs(code) {
|
||||
let deferred2_0;
|
||||
let deferred2_1;
|
||||
try {
|
||||
const retptr = wasm.__wbindgen_add_to_stack_pointer(-16);
|
||||
const ptr0 = passStringToWasm0(
|
||||
code,
|
||||
wasm.__wbindgen_malloc,
|
||||
wasm.__wbindgen_realloc,
|
||||
);
|
||||
const len0 = WASM_VECTOR_LEN;
|
||||
wasm.parse_outputs(retptr, ptr0, len0);
|
||||
var r0 = getInt32Memory0()[retptr / 4 + 0];
|
||||
var r1 = getInt32Memory0()[retptr / 4 + 1];
|
||||
deferred2_0 = r0;
|
||||
deferred2_1 = r1;
|
||||
return getStringFromWasm0(r0, r1);
|
||||
} finally {
|
||||
wasm.__wbindgen_add_to_stack_pointer(16);
|
||||
wasm.__wbindgen_free(deferred2_0, deferred2_1, 1);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {string} code
|
||||
* @returns {string}
|
||||
*/
|
||||
export function parse_ts_imports(code) {
|
||||
let deferred2_0;
|
||||
let deferred2_1;
|
||||
try {
|
||||
const retptr = wasm.__wbindgen_add_to_stack_pointer(-16);
|
||||
const ptr0 = passStringToWasm0(
|
||||
code,
|
||||
wasm.__wbindgen_malloc,
|
||||
wasm.__wbindgen_realloc,
|
||||
);
|
||||
const len0 = WASM_VECTOR_LEN;
|
||||
wasm.parse_ts_imports(retptr, ptr0, len0);
|
||||
var r0 = getInt32Memory0()[retptr / 4 + 0];
|
||||
var r1 = getInt32Memory0()[retptr / 4 + 1];
|
||||
deferred2_0 = r0;
|
||||
deferred2_1 = r1;
|
||||
return getStringFromWasm0(r0, r1);
|
||||
} finally {
|
||||
wasm.__wbindgen_add_to_stack_pointer(16);
|
||||
wasm.__wbindgen_free(deferred2_0, deferred2_1, 1);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {string} code
|
||||
* @returns {string}
|
||||
*/
|
||||
export function parse_bash(code) {
|
||||
let deferred2_0;
|
||||
let deferred2_1;
|
||||
try {
|
||||
const retptr = wasm.__wbindgen_add_to_stack_pointer(-16);
|
||||
const ptr0 = passStringToWasm0(
|
||||
code,
|
||||
wasm.__wbindgen_malloc,
|
||||
wasm.__wbindgen_realloc,
|
||||
);
|
||||
const len0 = WASM_VECTOR_LEN;
|
||||
wasm.parse_bash(retptr, ptr0, len0);
|
||||
var r0 = getInt32Memory0()[retptr / 4 + 0];
|
||||
var r1 = getInt32Memory0()[retptr / 4 + 1];
|
||||
deferred2_0 = r0;
|
||||
deferred2_1 = r1;
|
||||
return getStringFromWasm0(r0, r1);
|
||||
} finally {
|
||||
wasm.__wbindgen_add_to_stack_pointer(16);
|
||||
wasm.__wbindgen_free(deferred2_0, deferred2_1, 1);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {string} code
|
||||
* @returns {string}
|
||||
*/
|
||||
export function parse_powershell(code) {
|
||||
let deferred2_0;
|
||||
let deferred2_1;
|
||||
try {
|
||||
const retptr = wasm.__wbindgen_add_to_stack_pointer(-16);
|
||||
const ptr0 = passStringToWasm0(
|
||||
code,
|
||||
wasm.__wbindgen_malloc,
|
||||
wasm.__wbindgen_realloc,
|
||||
);
|
||||
const len0 = WASM_VECTOR_LEN;
|
||||
wasm.parse_powershell(retptr, ptr0, len0);
|
||||
var r0 = getInt32Memory0()[retptr / 4 + 0];
|
||||
var r1 = getInt32Memory0()[retptr / 4 + 1];
|
||||
deferred2_0 = r0;
|
||||
deferred2_1 = r1;
|
||||
return getStringFromWasm0(r0, r1);
|
||||
} finally {
|
||||
wasm.__wbindgen_add_to_stack_pointer(16);
|
||||
wasm.__wbindgen_free(deferred2_0, deferred2_1, 1);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {string} code
|
||||
* @returns {string}
|
||||
*/
|
||||
export function parse_go(code) {
|
||||
let deferred2_0;
|
||||
let deferred2_1;
|
||||
try {
|
||||
const retptr = wasm.__wbindgen_add_to_stack_pointer(-16);
|
||||
const ptr0 = passStringToWasm0(
|
||||
code,
|
||||
wasm.__wbindgen_malloc,
|
||||
wasm.__wbindgen_realloc,
|
||||
);
|
||||
const len0 = WASM_VECTOR_LEN;
|
||||
wasm.parse_go(retptr, ptr0, len0);
|
||||
var r0 = getInt32Memory0()[retptr / 4 + 0];
|
||||
var r1 = getInt32Memory0()[retptr / 4 + 1];
|
||||
deferred2_0 = r0;
|
||||
deferred2_1 = r1;
|
||||
return getStringFromWasm0(r0, r1);
|
||||
} finally {
|
||||
wasm.__wbindgen_add_to_stack_pointer(16);
|
||||
wasm.__wbindgen_free(deferred2_0, deferred2_1, 1);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {string} code
|
||||
* @returns {string}
|
||||
*/
|
||||
export function parse_python(code) {
|
||||
let deferred2_0;
|
||||
let deferred2_1;
|
||||
try {
|
||||
const retptr = wasm.__wbindgen_add_to_stack_pointer(-16);
|
||||
const ptr0 = passStringToWasm0(
|
||||
code,
|
||||
wasm.__wbindgen_malloc,
|
||||
wasm.__wbindgen_realloc,
|
||||
);
|
||||
const len0 = WASM_VECTOR_LEN;
|
||||
wasm.parse_python(retptr, ptr0, len0);
|
||||
var r0 = getInt32Memory0()[retptr / 4 + 0];
|
||||
var r1 = getInt32Memory0()[retptr / 4 + 1];
|
||||
deferred2_0 = r0;
|
||||
deferred2_1 = r1;
|
||||
return getStringFromWasm0(r0, r1);
|
||||
} finally {
|
||||
wasm.__wbindgen_add_to_stack_pointer(16);
|
||||
wasm.__wbindgen_free(deferred2_0, deferred2_1, 1);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {string} code
|
||||
* @returns {string}
|
||||
*/
|
||||
export function parse_sql(code) {
|
||||
let deferred2_0;
|
||||
let deferred2_1;
|
||||
try {
|
||||
const retptr = wasm.__wbindgen_add_to_stack_pointer(-16);
|
||||
const ptr0 = passStringToWasm0(
|
||||
code,
|
||||
wasm.__wbindgen_malloc,
|
||||
wasm.__wbindgen_realloc,
|
||||
);
|
||||
const len0 = WASM_VECTOR_LEN;
|
||||
wasm.parse_sql(retptr, ptr0, len0);
|
||||
var r0 = getInt32Memory0()[retptr / 4 + 0];
|
||||
var r1 = getInt32Memory0()[retptr / 4 + 1];
|
||||
deferred2_0 = r0;
|
||||
deferred2_1 = r1;
|
||||
return getStringFromWasm0(r0, r1);
|
||||
} finally {
|
||||
wasm.__wbindgen_add_to_stack_pointer(16);
|
||||
wasm.__wbindgen_free(deferred2_0, deferred2_1, 1);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {string} code
|
||||
* @returns {string}
|
||||
*/
|
||||
export function parse_mysql(code) {
|
||||
let deferred2_0;
|
||||
let deferred2_1;
|
||||
try {
|
||||
const retptr = wasm.__wbindgen_add_to_stack_pointer(-16);
|
||||
const ptr0 = passStringToWasm0(
|
||||
code,
|
||||
wasm.__wbindgen_malloc,
|
||||
wasm.__wbindgen_realloc,
|
||||
);
|
||||
const len0 = WASM_VECTOR_LEN;
|
||||
wasm.parse_mysql(retptr, ptr0, len0);
|
||||
var r0 = getInt32Memory0()[retptr / 4 + 0];
|
||||
var r1 = getInt32Memory0()[retptr / 4 + 1];
|
||||
deferred2_0 = r0;
|
||||
deferred2_1 = r1;
|
||||
return getStringFromWasm0(r0, r1);
|
||||
} finally {
|
||||
wasm.__wbindgen_add_to_stack_pointer(16);
|
||||
wasm.__wbindgen_free(deferred2_0, deferred2_1, 1);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {string} code
|
||||
* @returns {string}
|
||||
*/
|
||||
export function parse_bigquery(code) {
|
||||
let deferred2_0;
|
||||
let deferred2_1;
|
||||
try {
|
||||
const retptr = wasm.__wbindgen_add_to_stack_pointer(-16);
|
||||
const ptr0 = passStringToWasm0(
|
||||
code,
|
||||
wasm.__wbindgen_malloc,
|
||||
wasm.__wbindgen_realloc,
|
||||
);
|
||||
const len0 = WASM_VECTOR_LEN;
|
||||
wasm.parse_bigquery(retptr, ptr0, len0);
|
||||
var r0 = getInt32Memory0()[retptr / 4 + 0];
|
||||
var r1 = getInt32Memory0()[retptr / 4 + 1];
|
||||
deferred2_0 = r0;
|
||||
deferred2_1 = r1;
|
||||
return getStringFromWasm0(r0, r1);
|
||||
} finally {
|
||||
wasm.__wbindgen_add_to_stack_pointer(16);
|
||||
wasm.__wbindgen_free(deferred2_0, deferred2_1, 1);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {string} code
|
||||
* @returns {string}
|
||||
*/
|
||||
export function parse_snowflake(code) {
|
||||
let deferred2_0;
|
||||
let deferred2_1;
|
||||
try {
|
||||
const retptr = wasm.__wbindgen_add_to_stack_pointer(-16);
|
||||
const ptr0 = passStringToWasm0(
|
||||
code,
|
||||
wasm.__wbindgen_malloc,
|
||||
wasm.__wbindgen_realloc,
|
||||
);
|
||||
const len0 = WASM_VECTOR_LEN;
|
||||
wasm.parse_snowflake(retptr, ptr0, len0);
|
||||
var r0 = getInt32Memory0()[retptr / 4 + 0];
|
||||
var r1 = getInt32Memory0()[retptr / 4 + 1];
|
||||
deferred2_0 = r0;
|
||||
deferred2_1 = r1;
|
||||
return getStringFromWasm0(r0, r1);
|
||||
} finally {
|
||||
wasm.__wbindgen_add_to_stack_pointer(16);
|
||||
wasm.__wbindgen_free(deferred2_0, deferred2_1, 1);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {string} code
|
||||
* @returns {string}
|
||||
*/
|
||||
export function parse_mssql(code) {
|
||||
let deferred2_0;
|
||||
let deferred2_1;
|
||||
try {
|
||||
const retptr = wasm.__wbindgen_add_to_stack_pointer(-16);
|
||||
const ptr0 = passStringToWasm0(
|
||||
code,
|
||||
wasm.__wbindgen_malloc,
|
||||
wasm.__wbindgen_realloc,
|
||||
);
|
||||
const len0 = WASM_VECTOR_LEN;
|
||||
wasm.parse_mssql(retptr, ptr0, len0);
|
||||
var r0 = getInt32Memory0()[retptr / 4 + 0];
|
||||
var r1 = getInt32Memory0()[retptr / 4 + 1];
|
||||
deferred2_0 = r0;
|
||||
deferred2_1 = r1;
|
||||
return getStringFromWasm0(r0, r1);
|
||||
} finally {
|
||||
wasm.__wbindgen_add_to_stack_pointer(16);
|
||||
wasm.__wbindgen_free(deferred2_0, deferred2_1, 1);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {string} code
|
||||
* @returns {string}
|
||||
*/
|
||||
export function parse_graphql(code) {
|
||||
let deferred2_0;
|
||||
let deferred2_1;
|
||||
try {
|
||||
const retptr = wasm.__wbindgen_add_to_stack_pointer(-16);
|
||||
const ptr0 = passStringToWasm0(
|
||||
code,
|
||||
wasm.__wbindgen_malloc,
|
||||
wasm.__wbindgen_realloc,
|
||||
);
|
||||
const len0 = WASM_VECTOR_LEN;
|
||||
wasm.parse_graphql(retptr, ptr0, len0);
|
||||
var r0 = getInt32Memory0()[retptr / 4 + 0];
|
||||
var r1 = getInt32Memory0()[retptr / 4 + 1];
|
||||
deferred2_0 = r0;
|
||||
deferred2_1 = r1;
|
||||
return getStringFromWasm0(r0, r1);
|
||||
} finally {
|
||||
wasm.__wbindgen_add_to_stack_pointer(16);
|
||||
wasm.__wbindgen_free(deferred2_0, deferred2_1, 1);
|
||||
}
|
||||
}
|
||||
|
||||
function handleError(f, args) {
|
||||
try {
|
||||
return f.apply(this, args);
|
||||
} catch (e) {
|
||||
wasm.__wbindgen_exn_store(addHeapObject(e));
|
||||
}
|
||||
}
|
||||
|
||||
const imports = {
|
||||
__wbindgen_placeholder__: {
|
||||
__wbindgen_object_drop_ref: function (arg0) {
|
||||
takeObject(arg0);
|
||||
},
|
||||
__wbindgen_string_get: function (arg0, arg1) {
|
||||
const obj = getObject(arg1);
|
||||
const ret = typeof obj === "string" ? obj : undefined;
|
||||
var ptr1 = isLikeNone(ret)
|
||||
? 0
|
||||
: passStringToWasm0(
|
||||
ret,
|
||||
wasm.__wbindgen_malloc,
|
||||
wasm.__wbindgen_realloc,
|
||||
);
|
||||
var len1 = WASM_VECTOR_LEN;
|
||||
getInt32Memory0()[arg0 / 4 + 1] = len1;
|
||||
getInt32Memory0()[arg0 / 4 + 0] = ptr1;
|
||||
},
|
||||
__wbindgen_error_new: function (arg0, arg1) {
|
||||
const ret = new Error(getStringFromWasm0(arg0, arg1));
|
||||
return addHeapObject(ret);
|
||||
},
|
||||
__wbindgen_boolean_get: function (arg0) {
|
||||
const v = getObject(arg0);
|
||||
const ret = typeof v === "boolean" ? (v ? 1 : 0) : 2;
|
||||
return ret;
|
||||
},
|
||||
__wbindgen_is_bigint: function (arg0) {
|
||||
const ret = typeof (getObject(arg0)) === "bigint";
|
||||
return ret;
|
||||
},
|
||||
__wbindgen_bigint_from_i64: function (arg0) {
|
||||
const ret = arg0;
|
||||
return addHeapObject(ret);
|
||||
},
|
||||
__wbindgen_jsval_eq: function (arg0, arg1) {
|
||||
const ret = getObject(arg0) === getObject(arg1);
|
||||
return ret;
|
||||
},
|
||||
__wbindgen_bigint_from_u64: function (arg0) {
|
||||
const ret = BigInt.asUintN(64, arg0);
|
||||
return addHeapObject(ret);
|
||||
},
|
||||
__wbindgen_number_get: function (arg0, arg1) {
|
||||
const obj = getObject(arg1);
|
||||
const ret = typeof obj === "number" ? obj : undefined;
|
||||
getFloat64Memory0()[arg0 / 8 + 1] = isLikeNone(ret) ? 0 : ret;
|
||||
getInt32Memory0()[arg0 / 4 + 0] = !isLikeNone(ret);
|
||||
},
|
||||
__wbindgen_is_object: function (arg0) {
|
||||
const val = getObject(arg0);
|
||||
const ret = typeof val === "object" && val !== null;
|
||||
return ret;
|
||||
},
|
||||
__wbindgen_in: function (arg0, arg1) {
|
||||
const ret = getObject(arg0) in getObject(arg1);
|
||||
return ret;
|
||||
},
|
||||
__wbg_eval_c330e1bec5b1705c: function (arg0, arg1) {
|
||||
const ret = eval(getStringFromWasm0(arg0, arg1));
|
||||
return addHeapObject(ret);
|
||||
},
|
||||
__wbindgen_jsval_loose_eq: function (arg0, arg1) {
|
||||
const ret = getObject(arg0) == getObject(arg1);
|
||||
return ret;
|
||||
},
|
||||
__wbg_get_f01601b5a68d10e3: function (arg0, arg1) {
|
||||
const ret = getObject(arg0)[arg1 >>> 0];
|
||||
return addHeapObject(ret);
|
||||
},
|
||||
__wbg_length_1009b1af0c481d7b: function (arg0) {
|
||||
const ret = getObject(arg0).length;
|
||||
return ret;
|
||||
},
|
||||
__wbindgen_is_function: function (arg0) {
|
||||
const ret = typeof (getObject(arg0)) === "function";
|
||||
return ret;
|
||||
},
|
||||
__wbg_next_9b877f231f476d01: function (arg0) {
|
||||
const ret = getObject(arg0).next;
|
||||
return addHeapObject(ret);
|
||||
},
|
||||
__wbg_next_6529ee0cca8d57ed: function () {
|
||||
return handleError(function (arg0) {
|
||||
const ret = getObject(arg0).next();
|
||||
return addHeapObject(ret);
|
||||
}, arguments);
|
||||
},
|
||||
__wbg_done_5fe336b092d60cf2: function (arg0) {
|
||||
const ret = getObject(arg0).done;
|
||||
return ret;
|
||||
},
|
||||
__wbg_value_0c248a78fdc8e19f: function (arg0) {
|
||||
const ret = getObject(arg0).value;
|
||||
return addHeapObject(ret);
|
||||
},
|
||||
__wbg_iterator_db7ca081358d4fb2: function () {
|
||||
const ret = Symbol.iterator;
|
||||
return addHeapObject(ret);
|
||||
},
|
||||
__wbg_get_7b48513de5dc5ea4: function () {
|
||||
return handleError(function (arg0, arg1) {
|
||||
const ret = Reflect.get(getObject(arg0), getObject(arg1));
|
||||
return addHeapObject(ret);
|
||||
}, arguments);
|
||||
},
|
||||
__wbg_call_90c26b09837aba1c: function () {
|
||||
return handleError(function (arg0, arg1) {
|
||||
const ret = getObject(arg0).call(getObject(arg1));
|
||||
return addHeapObject(ret);
|
||||
}, arguments);
|
||||
},
|
||||
__wbg_isArray_74fb723e24f76012: function (arg0) {
|
||||
const ret = Array.isArray(getObject(arg0));
|
||||
return ret;
|
||||
},
|
||||
__wbg_instanceof_ArrayBuffer_e7d53d51371448e2: function (arg0) {
|
||||
let result;
|
||||
try {
|
||||
result = getObject(arg0) instanceof ArrayBuffer;
|
||||
} catch (_) {
|
||||
result = false;
|
||||
}
|
||||
const ret = result;
|
||||
return ret;
|
||||
},
|
||||
__wbg_isSafeInteger_f93fde0dca9820f8: function (arg0) {
|
||||
const ret = Number.isSafeInteger(getObject(arg0));
|
||||
return ret;
|
||||
},
|
||||
__wbg_entries_9e2e2aa45aa5094a: function (arg0) {
|
||||
const ret = Object.entries(getObject(arg0));
|
||||
return addHeapObject(ret);
|
||||
},
|
||||
__wbg_buffer_a448f833075b71ba: function (arg0) {
|
||||
const ret = getObject(arg0).buffer;
|
||||
return addHeapObject(ret);
|
||||
},
|
||||
__wbg_new_8f67e318f15d7254: function (arg0) {
|
||||
const ret = new Uint8Array(getObject(arg0));
|
||||
return addHeapObject(ret);
|
||||
},
|
||||
__wbg_set_2357bf09366ee480: function (arg0, arg1, arg2) {
|
||||
getObject(arg0).set(getObject(arg1), arg2 >>> 0);
|
||||
},
|
||||
__wbg_length_1d25fa9e4ac21ce7: function (arg0) {
|
||||
const ret = getObject(arg0).length;
|
||||
return ret;
|
||||
},
|
||||
__wbg_instanceof_Uint8Array_bced6f43aed8c1aa: function (arg0) {
|
||||
let result;
|
||||
try {
|
||||
result = getObject(arg0) instanceof Uint8Array;
|
||||
} catch (_) {
|
||||
result = false;
|
||||
}
|
||||
const ret = result;
|
||||
return ret;
|
||||
},
|
||||
__wbindgen_bigint_get_as_i64: function (arg0, arg1) {
|
||||
const v = getObject(arg1);
|
||||
const ret = typeof v === "bigint" ? v : undefined;
|
||||
getBigInt64Memory0()[arg0 / 8 + 1] = isLikeNone(ret) ? BigInt(0) : ret;
|
||||
getInt32Memory0()[arg0 / 4 + 0] = !isLikeNone(ret);
|
||||
},
|
||||
__wbindgen_debug_string: function (arg0, arg1) {
|
||||
const ret = debugString(getObject(arg1));
|
||||
const ptr1 = passStringToWasm0(
|
||||
ret,
|
||||
wasm.__wbindgen_malloc,
|
||||
wasm.__wbindgen_realloc,
|
||||
);
|
||||
const len1 = WASM_VECTOR_LEN;
|
||||
getInt32Memory0()[arg0 / 4 + 1] = len1;
|
||||
getInt32Memory0()[arg0 / 4 + 0] = ptr1;
|
||||
},
|
||||
__wbindgen_throw: function (arg0, arg1) {
|
||||
throw new Error(getStringFromWasm0(arg0, arg1));
|
||||
},
|
||||
__wbindgen_memory: function () {
|
||||
const ret = wasm.memory;
|
||||
return addHeapObject(ret);
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
import { Loader } from "https://deno.land/x/wasmbuild@0.15.4/loader.ts";
|
||||
import { cacheToLocalDir } from "https://deno.land/x/wasmbuild@0.15.4/cache.ts";
|
||||
|
||||
const loader = new Loader({
|
||||
imports,
|
||||
cache: cacheToLocalDir,
|
||||
});
|
||||
/**
|
||||
* Decompression callback
|
||||
*
|
||||
* @callback DecompressCallback
|
||||
* @param {Uint8Array} compressed
|
||||
* @return {Uint8Array} decompressed
|
||||
*/
|
||||
|
||||
/**
|
||||
* Options for instantiating a Wasm instance.
|
||||
* @typedef {Object} InstantiateOptions
|
||||
* @property {URL=} url - Optional url to the Wasm file to instantiate.
|
||||
* @property {DecompressCallback=} decompress - Callback to decompress the
|
||||
* raw Wasm file bytes before instantiating.
|
||||
*/
|
||||
|
||||
/** Instantiates an instance of the Wasm module returning its functions.
|
||||
* @remarks It is safe to call this multiple times and once successfully
|
||||
* loaded it will always return a reference to the same object.
|
||||
* @param {InstantiateOptions=} opts
|
||||
*/
|
||||
export async function instantiate(opts) {
|
||||
return (await instantiateWithInstance(opts)).exports;
|
||||
}
|
||||
|
||||
/** Instantiates an instance of the Wasm module along with its exports.
|
||||
* @remarks It is safe to call this multiple times and once successfully
|
||||
* loaded it will always return a reference to the same object.
|
||||
* @param {InstantiateOptions=} opts
|
||||
* @returns {Promise<{
|
||||
* instance: WebAssembly.Instance;
|
||||
* exports: { parse_deno: typeof parse_deno; parse_outputs: typeof parse_outputs; parse_ts_imports: typeof parse_ts_imports; parse_bash: typeof parse_bash; parse_powershell: typeof parse_powershell; parse_go: typeof parse_go; parse_python: typeof parse_python; parse_sql: typeof parse_sql; parse_mysql: typeof parse_mysql; parse_bigquery: typeof parse_bigquery; parse_snowflake: typeof parse_snowflake; parse_mssql: typeof parse_mssql; parse_graphql: typeof parse_graphql }
|
||||
* }>}
|
||||
*/
|
||||
export async function instantiateWithInstance(opts) {
|
||||
const { instance } = await loader.load(
|
||||
opts?.url ?? new URL("windmill_parser_wasm_bg.wasm", import.meta.url),
|
||||
opts?.decompress,
|
||||
);
|
||||
wasm = wasm ?? instance.exports;
|
||||
cachedInt32Memory0 = cachedInt32Memory0 ?? new Int32Array(wasm.memory.buffer);
|
||||
cachedUint8Memory0 = cachedUint8Memory0 ?? new Uint8Array(wasm.memory.buffer);
|
||||
return {
|
||||
instance,
|
||||
exports: getWasmInstanceExports(),
|
||||
};
|
||||
}
|
||||
|
||||
function getWasmInstanceExports() {
|
||||
return {
|
||||
parse_deno,
|
||||
parse_outputs,
|
||||
parse_ts_imports,
|
||||
parse_bash,
|
||||
parse_powershell,
|
||||
parse_go,
|
||||
parse_python,
|
||||
parse_sql,
|
||||
parse_mysql,
|
||||
parse_bigquery,
|
||||
parse_snowflake,
|
||||
parse_mssql,
|
||||
parse_graphql,
|
||||
};
|
||||
}
|
||||
|
||||
/** Gets if the Wasm module has been instantiated. */
|
||||
export function isInstantiated() {
|
||||
return loader.instance != null;
|
||||
}
|
||||
Binary file not shown.
Reference in New Issue
Block a user