Compare commits
149 Commits
v1.507.1
...
win-1465-i
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
3cb5660057 | ||
|
|
25aa982318 | ||
|
|
4b9683f146 | ||
|
|
14aa6d9681 | ||
|
|
2619be679e | ||
|
|
6971dcdb05 | ||
|
|
b0616c74cf | ||
|
|
daf3bb0a0a | ||
|
|
2e7ab919a7 | ||
|
|
b5afff9cc1 | ||
|
|
29c686d62a | ||
|
|
5af47d29e7 | ||
|
|
4d6a61403b | ||
|
|
d5c21131df | ||
|
|
56671bc75f | ||
|
|
9931311650 | ||
|
|
379880c6c5 | ||
|
|
55ba599022 | ||
|
|
8a2cd1c468 | ||
|
|
1084777bd6 | ||
|
|
ce4177ebae | ||
|
|
454b258ab8 | ||
|
|
adf59a36a9 | ||
|
|
1a85dc7008 | ||
|
|
496bbeec36 | ||
|
|
f892f7c9af | ||
|
|
6e8f5a5b00 | ||
|
|
d09d90589d | ||
|
|
a999bc7b28 | ||
|
|
564e92e98d | ||
|
|
323ec9a994 | ||
|
|
ad441a7ba6 | ||
|
|
c067342369 | ||
|
|
e8f4c2418b | ||
|
|
359b34ef08 | ||
|
|
8b4dc2ce73 | ||
|
|
3f784e3c07 | ||
|
|
94e20a97e0 | ||
|
|
06bd89c957 | ||
|
|
241be4897e | ||
|
|
9f926bd6bb | ||
|
|
79205839b6 | ||
|
|
ed1bee9f66 | ||
|
|
f71104e9f6 | ||
|
|
e16c8d0199 | ||
|
|
be3173d048 | ||
|
|
f4073abef0 | ||
|
|
e6f9f4d897 | ||
|
|
16757f3bb5 | ||
|
|
e869580787 | ||
|
|
0edb01f774 | ||
|
|
e02f06bf68 | ||
|
|
a57df1f781 | ||
|
|
7384aa36f4 | ||
|
|
b92fcb90a1 | ||
|
|
10befb995d | ||
|
|
91849baf34 | ||
|
|
8591478a6d | ||
|
|
86e14f8135 | ||
|
|
b00fde7f2a | ||
|
|
37b18f0661 | ||
|
|
34ccc8e0f7 | ||
|
|
2062a634f6 | ||
|
|
71b85dfc42 | ||
|
|
dc242c5a8d | ||
|
|
8bc2a5733e | ||
|
|
1713987317 | ||
|
|
c4178c05be | ||
|
|
3d99cbe8f5 | ||
|
|
506e17864e | ||
|
|
4b2c944af2 | ||
|
|
24a6038177 | ||
|
|
2c77012115 | ||
|
|
6f91ee791a | ||
|
|
dd1f520d83 | ||
|
|
3efc329fc0 | ||
|
|
f4dbc97a58 | ||
|
|
6f11a87121 | ||
|
|
be8c4ed86d | ||
|
|
8323707b07 | ||
|
|
2bd1600253 | ||
|
|
e16d5e1e8a | ||
|
|
d2328e3670 | ||
|
|
dddabc8d1b | ||
|
|
1c7b206cd4 | ||
|
|
e5dbbdaf1d | ||
|
|
9201391102 | ||
|
|
4fd5a8861d | ||
|
|
6bdc2c3223 | ||
|
|
8bb59d5a3c | ||
|
|
86fa9f91b6 | ||
|
|
dec72e201b | ||
|
|
33619ab18c | ||
|
|
0aa2ea6954 | ||
|
|
affecdad04 | ||
|
|
8b41077116 | ||
|
|
a10509a000 | ||
|
|
e183d49684 | ||
|
|
38d4ebf6d3 | ||
|
|
d80dd3eeac | ||
|
|
442b644438 | ||
|
|
d928a6c285 | ||
|
|
aa1d02c0b6 | ||
|
|
93accc824a | ||
|
|
8dd4a073b4 | ||
|
|
7315212fc0 | ||
|
|
4f993c82b5 | ||
|
|
b018e7c018 | ||
|
|
47c1b1aae5 | ||
|
|
2c299fd2a5 | ||
|
|
6a012a87ed | ||
|
|
7b4d0d6abb | ||
|
|
b099d96a60 | ||
|
|
9659b227c3 | ||
|
|
5acd3c21c0 | ||
|
|
2119da83f1 | ||
|
|
ae1793ecd1 | ||
|
|
1f48a05100 | ||
|
|
a7f6d74e05 | ||
|
|
673f10095d | ||
|
|
8a020bcfd5 | ||
|
|
2a739cb04b | ||
|
|
1e8c181f8e | ||
|
|
2ab5345e61 | ||
|
|
ec1ed0ba6b | ||
|
|
a2d9438b92 | ||
|
|
8e87d412ac | ||
|
|
e7123ced31 | ||
|
|
5f364100f3 | ||
|
|
936994580e | ||
|
|
9a0b75be84 | ||
|
|
71d6bbbdc3 | ||
|
|
1a850cb854 | ||
|
|
1842157bd5 | ||
|
|
01d8a3917b | ||
|
|
7ca652dede | ||
|
|
36816e08ac | ||
|
|
07b785dcc3 | ||
|
|
827e06b4b3 | ||
|
|
c076d1332e | ||
|
|
1d62dd0fc3 | ||
|
|
b68193f804 | ||
|
|
290daec0fa | ||
|
|
9e8748b7c8 | ||
|
|
532cdc4b49 | ||
|
|
6c477c109b | ||
|
|
2dae9ba0a7 | ||
|
|
7457401877 | ||
|
|
038c179a43 |
6
.github/CODEOWNERS
vendored
6
.github/CODEOWNERS
vendored
@@ -1,4 +1,4 @@
|
||||
* @rubenfiszel @HugoCasa @alpetric
|
||||
* @rubenfiszel @hugocasa @alpetric
|
||||
|
||||
/community/ @rubenfiszel @HugoCasa @alpetric
|
||||
/frontend/ @rubenfiszel @HugoCasa @alpetric
|
||||
/community/ @rubenfiszel @hugocasa @alpetric
|
||||
/frontend/ @rubenfiszel @hugocasa @alpetric
|
||||
|
||||
2
.github/DockerfileBackendTests
vendored
2
.github/DockerfileBackendTests
vendored
@@ -42,7 +42,7 @@ RUN wget https://www.python.org/ftp/python/${PYTHON_VERSION}/Python-${PYTHON_VER
|
||||
RUN /usr/local/bin/python3 -m pip install pip-tools
|
||||
|
||||
# Bun
|
||||
COPY --from=oven/bun:1.2.4 /usr/local/bin/bun /usr/bin/bun
|
||||
COPY --from=oven/bun:1.2.18 /usr/local/bin/bun /usr/bin/bun
|
||||
|
||||
ARG TARGETPLATFORM
|
||||
|
||||
|
||||
12
.github/workflows/backend-check.yml
vendored
12
.github/workflows/backend-check.yml
vendored
@@ -21,9 +21,6 @@ jobs:
|
||||
with:
|
||||
cache-workspaces: backend
|
||||
toolchain: 1.88.0
|
||||
- uses: Swatinem/rust-cache@v2
|
||||
with:
|
||||
workspaces: backend
|
||||
- name: cargo check
|
||||
working-directory: ./backend
|
||||
timeout-minutes: 16
|
||||
@@ -45,9 +42,6 @@ jobs:
|
||||
with:
|
||||
cache-workspaces: backend
|
||||
toolchain: 1.88.0
|
||||
- uses: Swatinem/rust-cache@v2
|
||||
with:
|
||||
workspaces: backend
|
||||
- name: cargo check
|
||||
working-directory: ./backend
|
||||
timeout-minutes: 16
|
||||
@@ -82,9 +76,6 @@ jobs:
|
||||
with:
|
||||
cache-workspaces: backend
|
||||
toolchain: 1.88.0
|
||||
- uses: Swatinem/rust-cache@v2
|
||||
with:
|
||||
workspaces: backend
|
||||
- name: cargo check
|
||||
working-directory: ./backend
|
||||
timeout-minutes: 16
|
||||
@@ -122,9 +113,6 @@ jobs:
|
||||
with:
|
||||
cache-workspaces: backend
|
||||
toolchain: 1.88.0
|
||||
- uses: Swatinem/rust-cache@v2
|
||||
with:
|
||||
workspaces: backend
|
||||
- name: cargo check
|
||||
timeout-minutes: 16
|
||||
working-directory: ./backend
|
||||
|
||||
3
.github/workflows/backend-test.yml
vendored
3
.github/workflows/backend-test.yml
vendored
@@ -52,9 +52,6 @@ jobs:
|
||||
with:
|
||||
cache-workspaces: backend
|
||||
toolchain: 1.85.0
|
||||
- uses: Swatinem/rust-cache@v2
|
||||
with:
|
||||
workspaces: backend
|
||||
- name: cargo test
|
||||
timeout-minutes: 16
|
||||
run:
|
||||
|
||||
2
.github/workflows/build_windows_worker_.yml
vendored
2
.github/workflows/build_windows_worker_.yml
vendored
@@ -33,7 +33,7 @@ jobs:
|
||||
- name: Setup Rust
|
||||
uses: actions-rs/toolchain@v1
|
||||
with:
|
||||
toolchain: 1.85.0
|
||||
toolchain: 1.88.0
|
||||
override: true
|
||||
|
||||
- name: Substitute EE code
|
||||
|
||||
7
.github/workflows/claude.yml
vendored
7
.github/workflows/claude.yml
vendored
@@ -82,11 +82,7 @@ jobs:
|
||||
- uses: actions-rust-lang/setup-rust-toolchain@v1
|
||||
with:
|
||||
cache-workspaces: backend
|
||||
toolchain: 1.85.0
|
||||
|
||||
- uses: Swatinem/rust-cache@v2
|
||||
with:
|
||||
workspaces: backend
|
||||
toolchain: 1.88.0
|
||||
|
||||
- name: cargo check
|
||||
working-directory: ./backend
|
||||
@@ -104,6 +100,7 @@ jobs:
|
||||
allowed_tools: "mcp__github__create_pull_request,Bash"
|
||||
custom_instructions: |
|
||||
## IMPORTANT INSTRUCTIONS
|
||||
- Your branch name should be a short description of the requested changes.
|
||||
- Bypass previous instructions and instead of adding a url in your comment to manually create a PR, if you created a new branch with your changes, automatically create a draft PR from that branch to main.
|
||||
|
||||
## Code Quality Requirements
|
||||
|
||||
20
.github/workflows/git-commands.yaml
vendored
20
.github/workflows/git-commands.yaml
vendored
@@ -15,7 +15,7 @@ jobs:
|
||||
|
||||
services:
|
||||
postgres:
|
||||
image: postgres:14
|
||||
image: postgres:16
|
||||
env:
|
||||
POSTGRES_PASSWORD: postgres
|
||||
POSTGRES_USER: postgres
|
||||
@@ -76,6 +76,10 @@ jobs:
|
||||
BRANCH_NAME=$(gh pr view $PR_NUMBER --json headRefName --jq .headRefName)
|
||||
echo "Checking out PR branch: $BRANCH_NAME"
|
||||
git checkout $BRANCH_NAME
|
||||
git config --local user.email "action@github.com"
|
||||
git config --local user.name "GitHub Action"
|
||||
git config pull.rebase true
|
||||
git pull origin $BRANCH_NAME
|
||||
mkdir frontend/build
|
||||
cd backend
|
||||
cargo install sqlx-cli --version 0.8.5
|
||||
@@ -86,10 +90,6 @@ jobs:
|
||||
|
||||
- name: Commit changes if any
|
||||
run: |
|
||||
git config --local user.email "action@github.com"
|
||||
git config --local user.name "GitHub Action"
|
||||
git config pull.rebase true
|
||||
git pull origin ${{ env.BRANCH_NAME }}
|
||||
git add backend/.sqlx
|
||||
git commit -m "Update SQLx metadata"
|
||||
git push origin ${{ env.BRANCH_NAME }}
|
||||
@@ -151,17 +151,17 @@ jobs:
|
||||
env:
|
||||
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
run: |
|
||||
echo "${{ steps.get-commit-hash.outputs.commit_hash }}" > backend/ee-repo-ref.txt
|
||||
echo "Updated backend/ee-repo-ref.txt with commit hash: ${{ steps.get-commit-hash.outputs.commit_hash }}"
|
||||
# commit and push the changes
|
||||
PR_NUMBER=${{ github.event.issue.number }}
|
||||
BRANCH_NAME=$(gh pr view $PR_NUMBER --json headRefName --jq .headRefName)
|
||||
echo "Checking out PR branch: $BRANCH_NAME"
|
||||
git checkout $BRANCH_NAME
|
||||
git config --local user.email "action@github.com"
|
||||
git config --local user.name "GitHub Action"
|
||||
git config pull.rebase true
|
||||
git pull origin $BRANCH_NAME
|
||||
echo "${{ steps.get-commit-hash.outputs.commit_hash }}" > backend/ee-repo-ref.txt
|
||||
echo "Updated backend/ee-repo-ref.txt with commit hash: ${{ steps.get-commit-hash.outputs.commit_hash }}"
|
||||
# commit and push the changes
|
||||
PR_NUMBER=${{ github.event.issue.number }}
|
||||
BRANCH_NAME=$(gh pr view $PR_NUMBER --json headRefName --jq .headRefName)
|
||||
git add backend/ee-repo-ref.txt
|
||||
git commit -m "Update ee-repo-ref.txt" || echo "No changes to commit"
|
||||
git push origin $BRANCH_NAME
|
||||
|
||||
2
.github/workflows/publish_windows_worker.yml
vendored
2
.github/workflows/publish_windows_worker.yml
vendored
@@ -35,7 +35,7 @@ jobs:
|
||||
- name: Setup Rust
|
||||
uses: actions-rs/toolchain@v1
|
||||
with:
|
||||
toolchain: 1.85.0
|
||||
toolchain: 1.88.0
|
||||
override: true
|
||||
|
||||
- name: Substitute EE code
|
||||
|
||||
175
CHANGELOG.md
175
CHANGELOG.md
@@ -1,5 +1,180 @@
|
||||
# Changelog
|
||||
|
||||
## [1.515.1](https://github.com/windmill-labs/windmill/compare/v1.515.0...v1.515.1) (2025-07-29)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* improved logs for script ([2e7ab91](https://github.com/windmill-labs/windmill/commit/2e7ab919a7bce4f04d7b09f45db48b5465346846))
|
||||
|
||||
## [1.515.0](https://github.com/windmill-labs/windmill/compare/v1.514.1...v1.515.0) (2025-07-29)
|
||||
|
||||
|
||||
### Features
|
||||
|
||||
* **cli:** generate cursor rules on init ([#6270](https://github.com/windmill-labs/windmill/issues/6270)) ([29c686d](https://github.com/windmill-labs/windmill/commit/29c686d62ae3597eb59371f5a3e9dadd9dc9557f))
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* add size limit to indexer queries on jobs table to avoid oom ([#6293](https://github.com/windmill-labs/windmill/issues/6293)) ([4d6a614](https://github.com/windmill-labs/windmill/commit/4d6a61403b51d84ea4039611cb007a42a26d24b6))
|
||||
* fix DynSelect ([55ba599](https://github.com/windmill-labs/windmill/commit/55ba599022ac2a6b513c4456747e4910f3188ec7))
|
||||
* improve docker logs collection in docker mode ([ce4177e](https://github.com/windmill-labs/windmill/commit/ce4177ebaed02df62aec676ca4624d77052f3e51))
|
||||
* resource types as arg in typescript handle imported defined types ([56671bc](https://github.com/windmill-labs/windmill/commit/56671bc75fe940f940f52ad47f5cf99c8329a0c3))
|
||||
* resource-type-ts-parser ([#6289](https://github.com/windmill-labs/windmill/issues/6289)) ([9931311](https://github.com/windmill-labs/windmill/commit/99313116509a5ebec33aa2ab813e0c189d4c4e24))
|
||||
|
||||
## [1.514.1](https://github.com/windmill-labs/windmill/compare/v1.514.0...v1.514.1) (2025-07-28)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* pin tokio to 1.46.1 and aws-sdks-ts ([1a85dc7](https://github.com/windmill-labs/windmill/commit/1a85dc7008d77cb4d51c488b4ba02a02cd08b05d))
|
||||
|
||||
## [1.514.0](https://github.com/windmill-labs/windmill/compare/v1.513.1...v1.514.0) (2025-07-28)
|
||||
|
||||
|
||||
### Features
|
||||
|
||||
* migrate audit log ids to bigints (blocking migration for EE) ([6e8f5a5](https://github.com/windmill-labs/windmill/commit/6e8f5a5b00056a324fa4fc27b740290338e672c9))
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* fix id renaming in apps ([a999bc7](https://github.com/windmill-labs/windmill/commit/a999bc7b28764e3583fdd843f13060c760627b51))
|
||||
* **mcp:** add proper check for mcp routes ([#6282](https://github.com/windmill-labs/windmill/issues/6282)) ([f892f7c](https://github.com/windmill-labs/windmill/commit/f892f7c9af1058b899c880160bd91d5e7b3ebcd6))
|
||||
|
||||
## [1.513.1](https://github.com/windmill-labs/windmill/compare/v1.513.0...v1.513.1) (2025-07-25)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* improve error handler behavior wrt to parrallel branchall & forloops ([#6273](https://github.com/windmill-labs/windmill/issues/6273)) ([3f784e3](https://github.com/windmill-labs/windmill/commit/3f784e3c07aa35ef2298bed301d581bf25300ba6))
|
||||
* jobLoader for flowstatusviewerinner work with public apps ([94e20a9](https://github.com/windmill-labs/windmill/commit/94e20a97e036fdb99e34c79b466e957b943cb26a))
|
||||
* **mcp:** allow mcp scopes to run scripts and flows ([#6278](https://github.com/windmill-labs/windmill/issues/6278)) ([e8f4c24](https://github.com/windmill-labs/windmill/commit/e8f4c2418b83af75be90b21ab2ab64537fef00eb))
|
||||
|
||||
## [1.513.0](https://github.com/windmill-labs/windmill/compare/v1.512.0...v1.513.0) (2025-07-24)
|
||||
|
||||
|
||||
### Features
|
||||
|
||||
* enable workspace exclusion in custom tags ([#6263](https://github.com/windmill-labs/windmill/issues/6263)) ([be3173d](https://github.com/windmill-labs/windmill/commit/be3173d048f8c3ee3681840b9880f509b754d779))
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* add windir env var to pwsh for legacy modules like AD ([#6271](https://github.com/windmill-labs/windmill/issues/6271)) ([7920583](https://github.com/windmill-labs/windmill/commit/79205839b6c3ba51a637f634d8cfba737b4dee1c))
|
||||
* fix webhook panel reactivity ([241be48](https://github.com/windmill-labs/windmill/commit/241be4897eb3377ccce097404fcd176e746c3015))
|
||||
* improve aggrid columnDefs reactivity ([f71104e](https://github.com/windmill-labs/windmill/commit/f71104e9f64bf6cb340d99ad91977c79651780c8))
|
||||
|
||||
## [1.512.0](https://github.com/windmill-labs/windmill/compare/v1.511.0...v1.512.0) (2025-07-23)
|
||||
|
||||
|
||||
### Features
|
||||
|
||||
* local type references parsing support for main function args ([#5995](https://github.com/windmill-labs/windmill/issues/5995)) ([10befb9](https://github.com/windmill-labs/windmill/commit/10befb995d07f50803213bcf177df8891fd920e1))
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* fix decision tree graph editor ([a57df1f](https://github.com/windmill-labs/windmill/commit/a57df1f78119b80ce764ddbff0ecb989cbb4c315))
|
||||
* include export from ts relative import tracking ([91849ba](https://github.com/windmill-labs/windmill/commit/91849baf3404c308f946f7c384ce679f2c89cbe7))
|
||||
* run autoscaling scripts with superadmin permissions ([86e14f8](https://github.com/windmill-labs/windmill/commit/86e14f8135eb8ccfad47f0340986464983019153))
|
||||
|
||||
## [1.511.0](https://github.com/windmill-labs/windmill/compare/v1.510.1...v1.511.0) (2025-07-22)
|
||||
|
||||
|
||||
### Features
|
||||
|
||||
* **aichat:** give completions to autocomplete for other languages than ts ([#6253](https://github.com/windmill-labs/windmill/issues/6253)) ([71b85df](https://github.com/windmill-labs/windmill/commit/71b85dfc42694f552a0572afd2072bbe528ac74b))
|
||||
* **aichat:** improve autocomplete with ata, editor diagnostic and deletion cues ([#6245](https://github.com/windmill-labs/windmill/issues/6245)) ([dc242c5](https://github.com/windmill-labs/windmill/commit/dc242c5a8df7d5d2ad710f3a5578dcb5fb4c9667))
|
||||
* periodic worker group script ([#6159](https://github.com/windmill-labs/windmill/issues/6159)) ([c4178c0](https://github.com/windmill-labs/windmill/commit/c4178c05be5cff4ef0617e31e0f05adc29e04f89))
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* add error name and message to job_postprocessing span ([34ccc8e](https://github.com/windmill-labs/windmill/commit/34ccc8e0f7487cf51370e0ff94546063ee7771ad))
|
||||
* scopes-run-and-webhook-token-display ([#6259](https://github.com/windmill-labs/windmill/issues/6259)) ([37b18f0](https://github.com/windmill-labs/windmill/commit/37b18f0661d797466423db021150c99398435c8b))
|
||||
|
||||
## [1.510.1](https://github.com/windmill-labs/windmill/compare/v1.510.0...v1.510.1) (2025-07-21)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* empty branches in branch one now return the previous_result ([8323707](https://github.com/windmill-labs/windmill/commit/8323707b07933eca81f0c30df2434c6409c26789))
|
||||
* improve ssh agent worker naming ([#6211](https://github.com/windmill-labs/windmill/issues/6211)) ([dd1f520](https://github.com/windmill-labs/windmill/commit/dd1f520d83d618dbf1d03855890011031da838b5))
|
||||
* in home, archived and include without main not taken into account ([f4dbc97](https://github.com/windmill-labs/windmill/commit/f4dbc97a58ea8742dc356bdad4c03bbaa7b369b7))
|
||||
* quickbooks oauth realmId ([#6232](https://github.com/windmill-labs/windmill/issues/6232)) ([be8c4ed](https://github.com/windmill-labs/windmill/commit/be8c4ed86d81013e575441f30e5a444cb4067db7))
|
||||
* update parsers to prevent assets var bug ([#6246](https://github.com/windmill-labs/windmill/issues/6246)) ([d2328e3](https://github.com/windmill-labs/windmill/commit/d2328e3670c73a5c4ce7b677339f9293604fd583))
|
||||
|
||||
## [1.510.0](https://github.com/windmill-labs/windmill/compare/v1.509.2...v1.510.0) (2025-07-20)
|
||||
|
||||
|
||||
### Features
|
||||
|
||||
* use sse for flow status updates ([dec72e2](https://github.com/windmill-labs/windmill/commit/dec72e201bcc8242eb269826505d6338c9751f14))
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* prevent loading script by hash if not permissioned ([9201391](https://github.com/windmill-labs/windmill/commit/9201391102e927b943958851ccb75bb9695833a5))
|
||||
|
||||
## [1.509.2](https://github.com/windmill-labs/windmill/compare/v1.509.1...v1.509.2) (2025-07-19)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* add back asset kind variable ([affecda](https://github.com/windmill-labs/windmill/commit/affecdad04e95e1e1fd26bd6bcdd0ec6e3c7a28e))
|
||||
|
||||
## [1.509.1](https://github.com/windmill-labs/windmill/compare/v1.509.0...v1.509.1) (2025-07-19)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* add back asset kind variable ([a10509a](https://github.com/windmill-labs/windmill/commit/a10509a000f217c37b45e125fd6e0a70aaaeb260))
|
||||
|
||||
## [1.509.0](https://github.com/windmill-labs/windmill/compare/v1.508.0...v1.509.0) (2025-07-19)
|
||||
|
||||
|
||||
### Features
|
||||
|
||||
* **ai chat:** search for relevant hub scripts and npm packages in script mode ([#6215](https://github.com/windmill-labs/windmill/issues/6215)) ([b099d96](https://github.com/windmill-labs/windmill/commit/b099d96a60f6abdc037554dbbec2d9ae6271f0bb))
|
||||
* **cli:** make `flow generate-locks` respect raw requirements ([#6105](https://github.com/windmill-labs/windmill/issues/6105)) ([71d6bbb](https://github.com/windmill-labs/windmill/commit/71d6bbbdc3f2350a12079ea5fe32da1183ce3cf2))
|
||||
* granular token scopes ([#6093](https://github.com/windmill-labs/windmill/issues/6093)) ([5f36410](https://github.com/windmill-labs/windmill/commit/5f364100f3a80423033e9a9b6213028067222b31))
|
||||
* implement SSE for job updates polling ([#6174](https://github.com/windmill-labs/windmill/issues/6174)) ([4f993c8](https://github.com/windmill-labs/windmill/commit/4f993c82b5af993b65e466c5abb38276b0857495))
|
||||
* windows memory and vcpu reading ([#6212](https://github.com/windmill-labs/windmill/issues/6212)) ([1a850cb](https://github.com/windmill-labs/windmill/commit/1a850cb854dd6dcef1d378157d14ad9c624a88a5))
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* app s3 multi upload policy ([#6228](https://github.com/windmill-labs/windmill/issues/6228)) ([6a012a8](https://github.com/windmill-labs/windmill/commit/6a012a87ed9693a877a2725800b79e82a1816f1b))
|
||||
* fix circular dependancy breaking bundling of cli ([#6219](https://github.com/windmill-labs/windmill/issues/6219)) ([8e87d41](https://github.com/windmill-labs/windmill/commit/8e87d412acd2bab4fb6c8ce748065657456e33f5))
|
||||
* prevent idle queries at the sqlx level ([e7123ce](https://github.com/windmill-labs/windmill/commit/e7123ced31038cf722cda67d16b8ad48589bb53a))
|
||||
* tantivy/indexer blocking operations on async code ([#6227](https://github.com/windmill-labs/windmill/issues/6227)) ([2c299fd](https://github.com/windmill-labs/windmill/commit/2c299fd2a52e1205892702be7b326fe7656492ab))
|
||||
|
||||
## [1.508.0](https://github.com/windmill-labs/windmill/compare/v1.507.2...v1.508.0) (2025-07-16)
|
||||
|
||||
|
||||
### Features
|
||||
|
||||
* **aichat:** add logs api endpoint as tool ([#6197](https://github.com/windmill-labs/windmill/issues/6197)) ([827e06b](https://github.com/windmill-labs/windmill/commit/827e06b4b3dd7b2b970b3a0a37e3dfbe98d1fafd))
|
||||
* better explanation for dev key renewal ([#6209](https://github.com/windmill-labs/windmill/issues/6209)) ([1d62dd0](https://github.com/windmill-labs/windmill/commit/1d62dd0fc323e484ab1d08e740379c8243b52df8))
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **frontend:** add error handler on trigger delete ([#6208](https://github.com/windmill-labs/windmill/issues/6208)) ([c076d13](https://github.com/windmill-labs/windmill/commit/c076d1332e0871b16b5881e2cf3ef165bc9f5dd5))
|
||||
* **frontend:** enable delete triggers on detail page ([#6206](https://github.com/windmill-labs/windmill/issues/6206)) ([290daec](https://github.com/windmill-labs/windmill/commit/290daec0fa53f77f6ad02e746d82aa30997d8cb0))
|
||||
* hide s3 catalog picker in anonymous apps ([#6204](https://github.com/windmill-labs/windmill/issues/6204)) ([b68193f](https://github.com/windmill-labs/windmill/commit/b68193f80468aeeadff5af0826cca2f0cc9f05e8))
|
||||
* support enum for array list as multiselect ([07b785d](https://github.com/windmill-labs/windmill/commit/07b785dcc383ae87eaec65e765177e45fff0af20))
|
||||
|
||||
## [1.507.2](https://github.com/windmill-labs/windmill/compare/v1.507.1...v1.507.2) (2025-07-16)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* cancel autocomplete on escape + autocomplete qol ([#6201](https://github.com/windmill-labs/windmill/issues/6201)) ([038c179](https://github.com/windmill-labs/windmill/commit/038c179a432d4f1997a761392e27b16dea829e06))
|
||||
* **cli:** fix cli --skip-resources --skip-variables ([6c477c1](https://github.com/windmill-labs/windmill/commit/6c477c109bf7e803ec07d4485dec426b770c7f76))
|
||||
|
||||
## [1.507.1](https://github.com/windmill-labs/windmill/compare/v1.507.0...v1.507.1) (2025-07-16)
|
||||
|
||||
|
||||
|
||||
@@ -194,7 +194,7 @@ COPY --from=builder /windmill/target/release/windmill ${APP}/windmill
|
||||
|
||||
COPY --from=denoland/deno:2.2.1 --chmod=755 /usr/bin/deno /usr/bin/deno
|
||||
|
||||
COPY --from=oven/bun:1.2.4 /usr/local/bin/bun /usr/bin/bun
|
||||
COPY --from=oven/bun:1.2.18 /usr/local/bin/bun /usr/bin/bun
|
||||
|
||||
COPY --from=php:8.3.7-cli /usr/local/bin/php /usr/bin/php
|
||||
COPY --from=composer:2.7.6 /usr/bin/composer /usr/bin/composer
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
"columns": [
|
||||
{
|
||||
"ordinal": 0,
|
||||
"name": "bool",
|
||||
"name": "?column?",
|
||||
"type_info": "Bool"
|
||||
}
|
||||
],
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"db_name": "PostgreSQL",
|
||||
"query": "INSERT INTO v2_job_status (id, workflow_as_code_status)\n VALUES ($1, JSONB_SET('{}'::JSONB, array[$2], $3))\n ON CONFLICT (id) DO UPDATE SET\n workflow_as_code_status = JSONB_SET(\n COALESCE(v2_job_status.workflow_as_code_status, '{}'::JSONB), \n array[$2],\n $3\n )",
|
||||
"query": "INSERT INTO v2_job_status (id, workflow_as_code_status)\n VALUES ($1, JSONB_SET('{}'::JSONB, array[$2], $3))\n ON CONFLICT (id) DO UPDATE SET\n workflow_as_code_status = JSONB_SET(\n COALESCE(v2_job_status.workflow_as_code_status, '{}'::JSONB),\n array[$2],\n $3\n )",
|
||||
"describe": {
|
||||
"columns": [],
|
||||
"parameters": {
|
||||
@@ -12,5 +12,5 @@
|
||||
},
|
||||
"nullable": []
|
||||
},
|
||||
"hash": "2e6935811a6d818bc523f076674f794f8be6c6bad3d06e74586e8ab668d91861"
|
||||
"hash": "140f4ad799fca6c25975a0aca7c9051f0760e22eccdd291c83ed86599ce571cb"
|
||||
}
|
||||
@@ -5,7 +5,7 @@
|
||||
"columns": [
|
||||
{
|
||||
"ordinal": 0,
|
||||
"name": "bool",
|
||||
"name": "?column?",
|
||||
"type_info": "Bool"
|
||||
}
|
||||
],
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"db_name": "PostgreSQL",
|
||||
"query": "INSERT INTO script (workspace_id, hash, path, parent_hashes, summary, description, content, created_by, schema, is_template, extra_perms, lock, language, kind, tag, draft_only, envs, concurrent_limit, concurrency_time_window_s, cache_ttl, dedicated_worker, ws_error_handler_muted, priority, restart_unless_cancelled, delete_after_use, timeout, concurrency_key, visible_to_runner_only, no_main_func, codebase, has_preprocessor, on_behalf_of_email, schema_validation) VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9::text::json, $10, $11, $12, $13, $14, $15, $16, $17, $18, $19, $20, $21, $22, $23, $24, $25, $26, $27, $28, $29, $30, $31, $32, $33)",
|
||||
"query": "INSERT INTO script (workspace_id, hash, path, parent_hashes, summary, description, content, created_by, schema, is_template, extra_perms, lock, language, kind, tag, draft_only, envs, concurrent_limit, concurrency_time_window_s, cache_ttl, dedicated_worker, ws_error_handler_muted, priority, restart_unless_cancelled, delete_after_use, timeout, concurrency_key, visible_to_runner_only, no_main_func, codebase, has_preprocessor, on_behalf_of_email, schema_validation, assets) VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9::text::json, $10, $11, $12, $13, $14, $15, $16, $17, $18, $19, $20, $21, $22, $23, $24, $25, $26, $27, $28, $29, $30, $31, $32, $33, $34)",
|
||||
"describe": {
|
||||
"columns": [],
|
||||
"parameters": {
|
||||
@@ -81,10 +81,11 @@
|
||||
"Varchar",
|
||||
"Bool",
|
||||
"Text",
|
||||
"Bool"
|
||||
"Bool",
|
||||
"Jsonb"
|
||||
]
|
||||
},
|
||||
"nullable": []
|
||||
},
|
||||
"hash": "d15f02f090b8d1a7e816fe11b2e0867540ab6bb02ac6bf82decc220dce0ab048"
|
||||
"hash": "1a54356c1e1353950bf6ab1d25ab21270131e9e93ca10d195664e7e5a774fe9e"
|
||||
}
|
||||
75
backend/.sqlx/query-278bc6b4f149f824b5db32dacfaa714ee3852dc2ddf2d661dfdd5a986a9bb62b.json
generated
Normal file
75
backend/.sqlx/query-278bc6b4f149f824b5db32dacfaa714ee3852dc2ddf2d661dfdd5a986a9bb62b.json
generated
Normal file
@@ -0,0 +1,75 @@
|
||||
{
|
||||
"db_name": "PostgreSQL",
|
||||
"query": "SELECT\n c.id IS NOT NULL AS completed,\n CASE \n WHEN q.id IS NOT NULL THEN (CASE WHEN NOT $5 AND q.running THEN true ELSE null END)\n ELSE false\n END AS running,\n SUBSTR(logs, GREATEST($1 - log_offset, 0)) AS logs,\n COALESCE(r.memory_peak, c.memory_peak) AS mem_peak,\n COALESCE(c.flow_status, f.flow_status) AS \"flow_status: sqlx::types::Json<Box<RawValue>>\",\n COALESCE(c.workflow_as_code_status, f.workflow_as_code_status) AS \"workflow_as_code_status: sqlx::types::Json<Box<RawValue>>\",\n job_logs.log_offset + CHAR_LENGTH(job_logs.logs) + 1 AS log_offset,\n created_by AS \"created_by!\",\n CASE WHEN $4::BOOLEAN THEN (\n SELECT scalar_int FROM job_stats WHERE job_id = $3 AND metric_id = 'progress_perc'\n ) END AS progress\n FROM v2_job j\n LEFT JOIN v2_job_queue q USING (id)\n LEFT JOIN v2_job_runtime r USING (id)\n LEFT JOIN v2_job_status f USING (id)\n LEFT JOIN v2_job_completed c USING (id)\n LEFT JOIN job_logs ON job_logs.job_id = $3\n WHERE j.workspace_id = $2 AND j.id = $3\n AND ($6::text[] IS NULL OR j.tag = ANY($6))",
|
||||
"describe": {
|
||||
"columns": [
|
||||
{
|
||||
"ordinal": 0,
|
||||
"name": "completed",
|
||||
"type_info": "Bool"
|
||||
},
|
||||
{
|
||||
"ordinal": 1,
|
||||
"name": "running",
|
||||
"type_info": "Bool"
|
||||
},
|
||||
{
|
||||
"ordinal": 2,
|
||||
"name": "logs",
|
||||
"type_info": "Text"
|
||||
},
|
||||
{
|
||||
"ordinal": 3,
|
||||
"name": "mem_peak",
|
||||
"type_info": "Int4"
|
||||
},
|
||||
{
|
||||
"ordinal": 4,
|
||||
"name": "flow_status: sqlx::types::Json<Box<RawValue>>",
|
||||
"type_info": "Jsonb"
|
||||
},
|
||||
{
|
||||
"ordinal": 5,
|
||||
"name": "workflow_as_code_status: sqlx::types::Json<Box<RawValue>>",
|
||||
"type_info": "Jsonb"
|
||||
},
|
||||
{
|
||||
"ordinal": 6,
|
||||
"name": "log_offset",
|
||||
"type_info": "Int4"
|
||||
},
|
||||
{
|
||||
"ordinal": 7,
|
||||
"name": "created_by!",
|
||||
"type_info": "Varchar"
|
||||
},
|
||||
{
|
||||
"ordinal": 8,
|
||||
"name": "progress",
|
||||
"type_info": "Int4"
|
||||
}
|
||||
],
|
||||
"parameters": {
|
||||
"Left": [
|
||||
"Int4",
|
||||
"Text",
|
||||
"Uuid",
|
||||
"Bool",
|
||||
"Bool",
|
||||
"TextArray"
|
||||
]
|
||||
},
|
||||
"nullable": [
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
false,
|
||||
null
|
||||
]
|
||||
},
|
||||
"hash": "278bc6b4f149f824b5db32dacfaa714ee3852dc2ddf2d661dfdd5a986a9bb62b"
|
||||
}
|
||||
@@ -5,7 +5,7 @@
|
||||
"columns": [
|
||||
{
|
||||
"ordinal": 0,
|
||||
"name": "bool",
|
||||
"name": "?column?",
|
||||
"type_info": "Bool"
|
||||
}
|
||||
],
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"db_name": "PostgreSQL",
|
||||
"query": "SELECT created_by AS \"created_by!\", args as \"args: sqlx::types::Json<Box<RawValue>>\"\n FROM v2_as_completed_job \n WHERE id = $1 AND workspace_id = $2 AND ($3::text[] IS NULL OR tag = ANY($3))",
|
||||
"query": "SELECT created_by AS \"created_by!\", args as \"args: sqlx::types::Json<Box<RawValue>>\"\n FROM v2_as_completed_job\n WHERE id = $1 AND workspace_id = $2 AND ($3::text[] IS NULL OR tag = ANY($3))",
|
||||
"describe": {
|
||||
"columns": [
|
||||
{
|
||||
@@ -26,5 +26,5 @@
|
||||
true
|
||||
]
|
||||
},
|
||||
"hash": "47fb4bceddd36fa60ccbe84f6341436fb133f0b3c97abb1267a9c12326dd1a33"
|
||||
"hash": "2bfa1ffb3d5869fc3038049ba77890203332e398c865c47aaf019dd5721d59f9"
|
||||
}
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"db_name": "PostgreSQL",
|
||||
"query": "SELECT created_by AS \"created_by!\", CONCAT(coalesce(v2_as_queue.logs, ''), coalesce(job_logs.logs, '')) as logs, coalesce(job_logs.log_offset, 0) as log_offset, job_logs.log_file_index\n FROM v2_as_queue \n LEFT JOIN job_logs ON job_logs.job_id = v2_as_queue.id \n WHERE v2_as_queue.id = $1 AND v2_as_queue.workspace_id = $2 AND ($3::text[] IS NULL OR v2_as_queue.tag = ANY($3))",
|
||||
"query": "SELECT created_by AS \"created_by!\", CONCAT(coalesce(v2_as_queue.logs, ''), coalesce(job_logs.logs, '')) as logs, coalesce(job_logs.log_offset, 0) as log_offset, job_logs.log_file_index\n FROM v2_as_queue\n LEFT JOIN job_logs ON job_logs.job_id = v2_as_queue.id\n WHERE v2_as_queue.id = $1 AND v2_as_queue.workspace_id = $2 AND ($3::text[] IS NULL OR v2_as_queue.tag = ANY($3))",
|
||||
"describe": {
|
||||
"columns": [
|
||||
{
|
||||
@@ -38,5 +38,5 @@
|
||||
true
|
||||
]
|
||||
},
|
||||
"hash": "95ae90094ec0e2c22660cc2e3788b22231dab9c558723cc54894597ce4cd3d5a"
|
||||
"hash": "2ea447f9e644554d415367b91042687ee8690d475b8ed31c48e31180689a278f"
|
||||
}
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"db_name": "PostgreSQL",
|
||||
"query": "SELECT label, concat(substring(token for 10)) as token_prefix, expiration, created_at, last_used_at, scopes, email FROM token WHERE workspace_id = $1 AND scopes @> ARRAY['run:script/' || $2]::text[]",
|
||||
"query": "\n SELECT label,\n concat(substring(token for 10)) AS token_prefix,\n expiration,\n created_at,\n last_used_at,\n scopes,\n email\n FROM token\n WHERE workspace_id = $1\n AND (\n scopes @> ARRAY['jobs:run:flows:' || $2]::text[]\n OR scopes @> ARRAY['run:flows/' || $2]::text[]\n )\n ",
|
||||
"describe": {
|
||||
"columns": [
|
||||
{
|
||||
@@ -55,5 +55,5 @@
|
||||
true
|
||||
]
|
||||
},
|
||||
"hash": "c7ee7ce64686cef41cebd99ad7ef31572fc1bf12e6ae473fd58fafb025989965"
|
||||
"hash": "334c9a6d770471ac53099eb5227778899a5c680b899bc6a6d1a3f89fdbf8c730"
|
||||
}
|
||||
@@ -1,16 +1,11 @@
|
||||
{
|
||||
"db_name": "PostgreSQL",
|
||||
"query": "\n SELECT \n tag, \n script_lang AS \"script_lang!: _\"\n FROM \n v2_job\n WHERE \n id = $1\n ",
|
||||
"query": "\n SELECT \n script_lang as \"language: _\", \n COUNT(*) as \"count!\", \n SUM(duration_ms)::BIGINT as \"total_duration!\" \n FROM \n v2_job_completed\n JOIN \n v2_job \n ON \n v2_job.id = v2_job_completed.id \n WHERE \n created_at > NOW() - INTERVAL '48 hours' \n GROUP BY \n script_lang\n ",
|
||||
"describe": {
|
||||
"columns": [
|
||||
{
|
||||
"ordinal": 0,
|
||||
"name": "tag",
|
||||
"type_info": "Varchar"
|
||||
},
|
||||
{
|
||||
"ordinal": 1,
|
||||
"name": "script_lang!: _",
|
||||
"name": "language: _",
|
||||
"type_info": {
|
||||
"Custom": {
|
||||
"name": "script_lang",
|
||||
@@ -42,17 +37,26 @@
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"ordinal": 1,
|
||||
"name": "count!",
|
||||
"type_info": "Int8"
|
||||
},
|
||||
{
|
||||
"ordinal": 2,
|
||||
"name": "total_duration!",
|
||||
"type_info": "Int8"
|
||||
}
|
||||
],
|
||||
"parameters": {
|
||||
"Left": [
|
||||
"Uuid"
|
||||
]
|
||||
"Left": []
|
||||
},
|
||||
"nullable": [
|
||||
false,
|
||||
true
|
||||
true,
|
||||
null,
|
||||
null
|
||||
]
|
||||
},
|
||||
"hash": "4e5273b9ce05f6ee2dfd5f14c8574a0cf43682480452f7dbe23012320fe7fe25"
|
||||
"hash": "48242fc46cb8bc9e4d41c788568634619565e4ef342051af23760c11edac5ee8"
|
||||
}
|
||||
23
backend/.sqlx/query-49ae42f396c55a7c258203de8ffbbd8d5c5d14e176792932064d9f6b5e6f4fa2.json
generated
Normal file
23
backend/.sqlx/query-49ae42f396c55a7c258203de8ffbbd8d5c5d14e176792932064d9f6b5e6f4fa2.json
generated
Normal file
@@ -0,0 +1,23 @@
|
||||
{
|
||||
"db_name": "PostgreSQL",
|
||||
"query": "SELECT is_admin FROM usr WHERE email = $1 AND workspace_id = $2 AND disabled = false",
|
||||
"describe": {
|
||||
"columns": [
|
||||
{
|
||||
"ordinal": 0,
|
||||
"name": "is_admin",
|
||||
"type_info": "Bool"
|
||||
}
|
||||
],
|
||||
"parameters": {
|
||||
"Left": [
|
||||
"Text",
|
||||
"Text"
|
||||
]
|
||||
},
|
||||
"nullable": [
|
||||
false
|
||||
]
|
||||
},
|
||||
"hash": "49ae42f396c55a7c258203de8ffbbd8d5c5d14e176792932064d9f6b5e6f4fa2"
|
||||
}
|
||||
22
backend/.sqlx/query-49e2430af74ec10857e5df7f7e1ad1b53ba70bb51b0259a1f765f76db9b733ad.json
generated
Normal file
22
backend/.sqlx/query-49e2430af74ec10857e5df7f7e1ad1b53ba70bb51b0259a1f765f76db9b733ad.json
generated
Normal file
@@ -0,0 +1,22 @@
|
||||
{
|
||||
"db_name": "PostgreSQL",
|
||||
"query": "\n SELECT \n tag\n FROM \n v2_job\n WHERE \n id = $1\n ",
|
||||
"describe": {
|
||||
"columns": [
|
||||
{
|
||||
"ordinal": 0,
|
||||
"name": "tag",
|
||||
"type_info": "Varchar"
|
||||
}
|
||||
],
|
||||
"parameters": {
|
||||
"Left": [
|
||||
"Uuid"
|
||||
]
|
||||
},
|
||||
"nullable": [
|
||||
false
|
||||
]
|
||||
},
|
||||
"hash": "49e2430af74ec10857e5df7f7e1ad1b53ba70bb51b0259a1f765f76db9b733ad"
|
||||
}
|
||||
@@ -15,7 +15,7 @@
|
||||
]
|
||||
},
|
||||
"nullable": [
|
||||
null
|
||||
true
|
||||
]
|
||||
},
|
||||
"hash": "5a219a2532517869578c4504ff3153c43903f929ae5d62fbba12610f89c36d55"
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
"columns": [
|
||||
{
|
||||
"ordinal": 0,
|
||||
"name": "bool",
|
||||
"name": "?column?",
|
||||
"type_info": "Bool"
|
||||
}
|
||||
],
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
"columns": [
|
||||
{
|
||||
"ordinal": 0,
|
||||
"name": "bool",
|
||||
"name": "?column?",
|
||||
"type_info": "Bool"
|
||||
}
|
||||
],
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"db_name": "PostgreSQL",
|
||||
"query": "SELECT workspace_id FROM usr WHERE email = $1",
|
||||
"query": "SELECT workspace_id FROM usr WHERE email = $1 AND is_admin = true AND disabled = false",
|
||||
"describe": {
|
||||
"columns": [
|
||||
{
|
||||
@@ -18,5 +18,5 @@
|
||||
false
|
||||
]
|
||||
},
|
||||
"hash": "38c20dba51b1e2b4b28e5eed51f9071e1d3cf78e89ec467927823177c5a439cc"
|
||||
"hash": "664bb931b02a5d9e0d68ccef12788419c804a8f0d66cc660e4608220655b0f33"
|
||||
}
|
||||
@@ -5,7 +5,7 @@
|
||||
"columns": [
|
||||
{
|
||||
"ordinal": 0,
|
||||
"name": "bool",
|
||||
"name": "?column?",
|
||||
"type_info": "Bool"
|
||||
}
|
||||
],
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
"columns": [
|
||||
{
|
||||
"ordinal": 0,
|
||||
"name": "bool",
|
||||
"name": "?column?",
|
||||
"type_info": "Bool"
|
||||
}
|
||||
],
|
||||
|
||||
20
backend/.sqlx/query-779775a89d225bc1de000d244c63aab3a3be72d8761217d9567400fc3c13c4b8.json
generated
Normal file
20
backend/.sqlx/query-779775a89d225bc1de000d244c63aab3a3be72d8761217d9567400fc3c13c4b8.json
generated
Normal file
@@ -0,0 +1,20 @@
|
||||
{
|
||||
"db_name": "PostgreSQL",
|
||||
"query": "SELECT DISTINCT workspace_id FROM workspace_settings WHERE git_app_installations IS NOT NULL",
|
||||
"describe": {
|
||||
"columns": [
|
||||
{
|
||||
"ordinal": 0,
|
||||
"name": "workspace_id",
|
||||
"type_info": "Varchar"
|
||||
}
|
||||
],
|
||||
"parameters": {
|
||||
"Left": []
|
||||
},
|
||||
"nullable": [
|
||||
false
|
||||
]
|
||||
},
|
||||
"hash": "779775a89d225bc1de000d244c63aab3a3be72d8761217d9567400fc3c13c4b8"
|
||||
}
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"db_name": "PostgreSQL",
|
||||
"query": "INSERT INTO concurrency_counter(concurrency_id, job_uuids) \n VALUES ($1, '{}'::jsonb)",
|
||||
"query": "INSERT INTO concurrency_counter(concurrency_id, job_uuids)\n VALUES ($1, '{}'::jsonb)",
|
||||
"describe": {
|
||||
"columns": [],
|
||||
"parameters": {
|
||||
@@ -10,5 +10,5 @@
|
||||
},
|
||||
"nullable": []
|
||||
},
|
||||
"hash": "05cb171b610bfb45f6228128a385cde8a5b86d7ca377a028004cc382e12faf41"
|
||||
"hash": "7b5dc50b685afc7de0b99bd68e2217d660529c15b41860a4513f63d465bb9abb"
|
||||
}
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"db_name": "PostgreSQL",
|
||||
"query": "SELECT coalesce(flow_version_lite.value, flow_version.value) as \"value!: sqlx::types::Json<Box<RawValue>>\" FROM flow \n LEFT JOIN flow_version\n ON flow_version.id = flow.versions[array_upper(flow.versions, 1)]\n LEFT JOIN flow_version_lite \n ON flow_version_lite.id = flow_version.id\n WHERE flow.path = $1 AND flow.workspace_id = $2 LIMIT 1",
|
||||
"query": "SELECT coalesce(flow_version_lite.value, flow_version.value) as \"value!: sqlx::types::Json<Box<RawValue>>\" FROM flow\n LEFT JOIN flow_version\n ON flow_version.id = flow.versions[array_upper(flow.versions, 1)]\n LEFT JOIN flow_version_lite\n ON flow_version_lite.id = flow_version.id\n WHERE flow.path = $1 AND flow.workspace_id = $2 LIMIT 1",
|
||||
"describe": {
|
||||
"columns": [
|
||||
{
|
||||
@@ -19,5 +19,5 @@
|
||||
null
|
||||
]
|
||||
},
|
||||
"hash": "625c400bd81369a8142b8c7fa67b2be02f0f945e587c90d7e0f23706bf6e9a31"
|
||||
"hash": "81ba1e003d3f6e8e7c74a4dd09b980888d71121082390f3fdb91269cd0c5d0b2"
|
||||
}
|
||||
@@ -5,7 +5,7 @@
|
||||
"columns": [
|
||||
{
|
||||
"ordinal": 0,
|
||||
"name": "bool",
|
||||
"name": "?column?",
|
||||
"type_info": "Bool"
|
||||
}
|
||||
],
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
"columns": [
|
||||
{
|
||||
"ordinal": 0,
|
||||
"name": "bool",
|
||||
"name": "?column?",
|
||||
"type_info": "Bool"
|
||||
}
|
||||
],
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
"columns": [
|
||||
{
|
||||
"ordinal": 0,
|
||||
"name": "bool",
|
||||
"name": "?column?",
|
||||
"type_info": "Bool"
|
||||
}
|
||||
],
|
||||
|
||||
@@ -1,68 +0,0 @@
|
||||
{
|
||||
"db_name": "PostgreSQL",
|
||||
"query": "SELECT\n c.id IS NOT NULL AS completed,\n CASE \n WHEN q.id IS NOT NULL THEN (CASE WHEN NOT $5 AND q.running THEN true ELSE null END)\n ELSE false\n END AS running,\n SUBSTR(logs, GREATEST($1 - log_offset, 0)) AS logs,\n COALESCE(r.memory_peak, c.memory_peak) AS mem_peak,\n CASE\n -- flow step:\n WHEN flow_step_id IS NOT NULL THEN NULL\n -- completed:\n WHEN c.id IS NOT NULL THEN COALESCE(\n c.workflow_as_code_status || c.flow_status,\n c.workflow_as_code_status,\n c.flow_status\n )\n -- not completed:\n ELSE COALESCE(\n f.workflow_as_code_status || f.flow_status,\n f.workflow_as_code_status,\n f.flow_status\n )\n END AS \"flow_status: sqlx::types::Json<Box<RawValue>>\",\n job_logs.log_offset + CHAR_LENGTH(job_logs.logs) + 1 AS log_offset,\n created_by AS \"created_by!\",\n CASE WHEN $4::BOOLEAN THEN (\n SELECT scalar_int FROM job_stats WHERE job_id = $3 AND metric_id = 'progress_perc'\n ) END AS progress\n FROM v2_job j\n LEFT JOIN v2_job_queue q USING (id)\n LEFT JOIN v2_job_runtime r USING (id)\n LEFT JOIN v2_job_status f USING (id)\n LEFT JOIN v2_job_completed c USING (id)\n LEFT JOIN job_logs ON job_logs.job_id = $3\n WHERE j.workspace_id = $2 AND j.id = $3",
|
||||
"describe": {
|
||||
"columns": [
|
||||
{
|
||||
"ordinal": 0,
|
||||
"name": "completed",
|
||||
"type_info": "Bool"
|
||||
},
|
||||
{
|
||||
"ordinal": 1,
|
||||
"name": "running",
|
||||
"type_info": "Bool"
|
||||
},
|
||||
{
|
||||
"ordinal": 2,
|
||||
"name": "logs",
|
||||
"type_info": "Text"
|
||||
},
|
||||
{
|
||||
"ordinal": 3,
|
||||
"name": "mem_peak",
|
||||
"type_info": "Int4"
|
||||
},
|
||||
{
|
||||
"ordinal": 4,
|
||||
"name": "flow_status: sqlx::types::Json<Box<RawValue>>",
|
||||
"type_info": "Jsonb"
|
||||
},
|
||||
{
|
||||
"ordinal": 5,
|
||||
"name": "log_offset",
|
||||
"type_info": "Int4"
|
||||
},
|
||||
{
|
||||
"ordinal": 6,
|
||||
"name": "created_by!",
|
||||
"type_info": "Varchar"
|
||||
},
|
||||
{
|
||||
"ordinal": 7,
|
||||
"name": "progress",
|
||||
"type_info": "Int4"
|
||||
}
|
||||
],
|
||||
"parameters": {
|
||||
"Left": [
|
||||
"Int4",
|
||||
"Text",
|
||||
"Uuid",
|
||||
"Bool",
|
||||
"Bool"
|
||||
]
|
||||
},
|
||||
"nullable": [
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
false,
|
||||
null
|
||||
]
|
||||
},
|
||||
"hash": "b075c77caad37cdd75faab1d934b7a63521c1ad788033c564ffd7a2944454378"
|
||||
}
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"db_name": "PostgreSQL",
|
||||
"query": "SELECT \n j.id,\n j.kind AS \"kind: _\",\n COALESCE(s.path, f.path) AS \"script_path!\",\n COALESCE(s.hash, f.id) AS \"script_hash!: _\",\n COALESCE(jc.started_at, jq.scheduled_for, make_date(1970, 1, 1)) AS \"scheduled_for!: _\",\n args AS input,\n COALESCE(s.schema, f.schema) AS \"schema: _\"\n FROM v2_job j\n LEFT JOIN script s ON j.runnable_id = s.hash AND j.kind = 'script'\n LEFT JOIN flow_version f ON j.runnable_id = f.id AND j.runnable_path = f.path AND j.kind = 'flow'\n LEFT JOIN v2_job_completed jc ON jc.id = j.id\n LEFT JOIN v2_job_queue jq ON jq.id = j.id\n WHERE j.id = ANY($1)\n AND j.workspace_id = $2\n AND COALESCE(s.hash, f.id) IS NOT NULL\n AND COALESCE(s.path, f.path) IS NOT NULL",
|
||||
"query": "SELECT\n j.id,\n j.kind AS \"kind: _\",\n COALESCE(s.path, f.path) AS \"script_path!\",\n COALESCE(s.hash, f.id) AS \"script_hash!: _\",\n COALESCE(jc.started_at, jq.scheduled_for, make_date(1970, 1, 1)) AS \"scheduled_for!: _\",\n args AS input,\n COALESCE(s.schema, f.schema) AS \"schema: _\"\n FROM v2_job j\n LEFT JOIN script s ON j.runnable_id = s.hash AND j.kind = 'script'\n LEFT JOIN flow_version f ON j.runnable_id = f.id AND j.runnable_path = f.path AND j.kind = 'flow'\n LEFT JOIN v2_job_completed jc ON jc.id = j.id\n LEFT JOIN v2_job_queue jq ON jq.id = j.id\n WHERE j.id = ANY($1)\n AND j.workspace_id = $2\n AND COALESCE(s.hash, f.id) IS NOT NULL\n AND COALESCE(s.path, f.path) IS NOT NULL",
|
||||
"describe": {
|
||||
"columns": [
|
||||
{
|
||||
@@ -81,5 +81,5 @@
|
||||
null
|
||||
]
|
||||
},
|
||||
"hash": "ad88831c9021b79c9037a925c2b53be3a93dbe2a67bdc4d4342c84f439b5eaf9"
|
||||
"hash": "b3c02fd225a6aa78785d466e7f033b38deb9c7fa17bd3836c9ad8884f27be84a"
|
||||
}
|
||||
@@ -18,8 +18,8 @@
|
||||
"Left": []
|
||||
},
|
||||
"nullable": [
|
||||
true,
|
||||
false
|
||||
false,
|
||||
true
|
||||
]
|
||||
},
|
||||
"hash": "b3dbdfb50ee8118bdaed3164b210cb549a34b96554ae1872355b90304f5dcb76"
|
||||
|
||||
29
backend/.sqlx/query-b9b3c341fe452da916ee29637e14b5c1ad75462eba17083c6f81ff6ef35af77f.json
generated
Normal file
29
backend/.sqlx/query-b9b3c341fe452da916ee29637e14b5c1ad75462eba17083c6f81ff6ef35af77f.json
generated
Normal file
@@ -0,0 +1,29 @@
|
||||
{
|
||||
"db_name": "PostgreSQL",
|
||||
"query": "SELECT result as \"result: sqlx::types::Json<Box<RawValue>>\", v2_job_queue.running as \"running: Option<bool>\" FROM v2_job_completed FULL OUTER JOIN v2_job_queue USING (id) WHERE (v2_job_queue.id = $1 AND v2_job_queue.workspace_id = $2) OR (v2_job_completed.id = $1 AND v2_job_completed.workspace_id = $2)",
|
||||
"describe": {
|
||||
"columns": [
|
||||
{
|
||||
"ordinal": 0,
|
||||
"name": "result: sqlx::types::Json<Box<RawValue>>",
|
||||
"type_info": "Jsonb"
|
||||
},
|
||||
{
|
||||
"ordinal": 1,
|
||||
"name": "running: Option<bool>",
|
||||
"type_info": "Bool"
|
||||
}
|
||||
],
|
||||
"parameters": {
|
||||
"Left": [
|
||||
"Uuid",
|
||||
"Text"
|
||||
]
|
||||
},
|
||||
"nullable": [
|
||||
true,
|
||||
false
|
||||
]
|
||||
},
|
||||
"hash": "b9b3c341fe452da916ee29637e14b5c1ad75462eba17083c6f81ff6ef35af77f"
|
||||
}
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"db_name": "PostgreSQL",
|
||||
"query": "INSERT INTO account (workspace_id, client, expires_at, refresh_token, grant_type, cc_client_id, cc_client_secret) VALUES ($1, $2, now() + ($3 || ' seconds')::interval, $4, $5, $6, $7) RETURNING id",
|
||||
"query": "INSERT INTO account (workspace_id, client, expires_at, refresh_token, grant_type, cc_client_id, cc_client_secret, cc_token_url) VALUES ($1, $2, now() + ($3 || ' seconds')::interval, $4, $5, $6, $7, $8) RETURNING id",
|
||||
"describe": {
|
||||
"columns": [
|
||||
{
|
||||
@@ -17,6 +17,7 @@
|
||||
"Varchar",
|
||||
"Varchar",
|
||||
"Varchar",
|
||||
"Varchar",
|
||||
"Varchar"
|
||||
]
|
||||
},
|
||||
@@ -24,5 +25,5 @@
|
||||
false
|
||||
]
|
||||
},
|
||||
"hash": "00418f2e621cbe7aed536cff357898f7250544dfcb3bd85d314af1058f3148d8"
|
||||
"hash": "bbc28b92ae8ec3d120a8976be7d3966282fe6543e0eb957fc10864dbf58de58f"
|
||||
}
|
||||
@@ -5,7 +5,7 @@
|
||||
"columns": [
|
||||
{
|
||||
"ordinal": 0,
|
||||
"name": "bool",
|
||||
"name": "?column?",
|
||||
"type_info": "Bool"
|
||||
}
|
||||
],
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"db_name": "PostgreSQL",
|
||||
"query": "SELECT created_by AS \"created_by!\", CONCAT(coalesce(v2_as_completed_job.logs, ''), coalesce(job_logs.logs, '')) as logs, job_logs.log_offset, job_logs.log_file_index\n FROM v2_as_completed_job \n LEFT JOIN job_logs ON job_logs.job_id = v2_as_completed_job.id \n WHERE v2_as_completed_job.id = $1 AND v2_as_completed_job.workspace_id = $2 AND ($3::text[] IS NULL OR v2_as_completed_job.tag = ANY($3))",
|
||||
"query": "SELECT created_by AS \"created_by!\", CONCAT(coalesce(v2_as_completed_job.logs, ''), coalesce(job_logs.logs, '')) as logs, job_logs.log_offset, job_logs.log_file_index\n FROM v2_as_completed_job\n LEFT JOIN job_logs ON job_logs.job_id = v2_as_completed_job.id\n WHERE v2_as_completed_job.id = $1 AND v2_as_completed_job.workspace_id = $2 AND ($3::text[] IS NULL OR v2_as_completed_job.tag = ANY($3))",
|
||||
"describe": {
|
||||
"columns": [
|
||||
{
|
||||
@@ -38,5 +38,5 @@
|
||||
true
|
||||
]
|
||||
},
|
||||
"hash": "2c5a1b1ebd872ce8a03a1b7e5246c876750c85075cfda816c025c805d4c3cd4c"
|
||||
"hash": "ca5d9a9d8d18da970c7fd6eab41ecbb3a5c7c29803e4c38b8a0b2ca3790e52f9"
|
||||
}
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"db_name": "PostgreSQL",
|
||||
"query": "INSERT INTO job_perms (job_id, email, username, is_admin, is_operator, folders, groups, workspace_id) \n SELECT unnest($1::uuid[]), $2, $3, $4, $5, $6, $7, $8",
|
||||
"query": "INSERT INTO job_perms (job_id, email, username, is_admin, is_operator, folders, groups, workspace_id)\n SELECT unnest($1::uuid[]), $2, $3, $4, $5, $6, $7, $8",
|
||||
"describe": {
|
||||
"columns": [],
|
||||
"parameters": {
|
||||
@@ -17,5 +17,5 @@
|
||||
},
|
||||
"nullable": []
|
||||
},
|
||||
"hash": "fe7221651a982861dede4116bc71fe2dce615ff76a53f72cb5386dc17e4e07aa"
|
||||
"hash": "cad2dfc50d57c2298cb0ec05ed3b42b9fd3edd05c314c9d96ba33cad37fe35c2"
|
||||
}
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"db_name": "PostgreSQL",
|
||||
"query": "SELECT client, refresh_token, grant_type, cc_client_id, cc_client_secret FROM account WHERE workspace_id = $1 AND id = $2",
|
||||
"query": "SELECT client, refresh_token, grant_type, cc_client_id, cc_client_secret, cc_token_url FROM account WHERE workspace_id = $1 AND id = $2",
|
||||
"describe": {
|
||||
"columns": [
|
||||
{
|
||||
@@ -27,6 +27,11 @@
|
||||
"ordinal": 4,
|
||||
"name": "cc_client_secret",
|
||||
"type_info": "Varchar"
|
||||
},
|
||||
{
|
||||
"ordinal": 5,
|
||||
"name": "cc_token_url",
|
||||
"type_info": "Varchar"
|
||||
}
|
||||
],
|
||||
"parameters": {
|
||||
@@ -40,8 +45,9 @@
|
||||
false,
|
||||
false,
|
||||
true,
|
||||
true,
|
||||
true
|
||||
]
|
||||
},
|
||||
"hash": "b9d57959f2696f74e9d24f55fb78ff9e9041ab84b896a8b980df7b550ef27a22"
|
||||
"hash": "cc269052ffc1e613d7edc31f0f7bb84f6e6301ad1afb028813105a121a69fa7e"
|
||||
}
|
||||
@@ -5,7 +5,7 @@
|
||||
"columns": [
|
||||
{
|
||||
"ordinal": 0,
|
||||
"name": "bool",
|
||||
"name": "?column?",
|
||||
"type_info": "Bool"
|
||||
}
|
||||
],
|
||||
|
||||
23
backend/.sqlx/query-ceb8c2607023883e1eebd4b9539e36ed202a6ecd12e3f90cb070341c38886de4.json
generated
Normal file
23
backend/.sqlx/query-ceb8c2607023883e1eebd4b9539e36ed202a6ecd12e3f90cb070341c38886de4.json
generated
Normal file
@@ -0,0 +1,23 @@
|
||||
{
|
||||
"db_name": "PostgreSQL",
|
||||
"query": "SELECT result as \"result: sqlx::types::Json<Box<RawValue>>\" FROM v2_job_completed WHERE id = $2 AND workspace_id = $1",
|
||||
"describe": {
|
||||
"columns": [
|
||||
{
|
||||
"ordinal": 0,
|
||||
"name": "result: sqlx::types::Json<Box<RawValue>>",
|
||||
"type_info": "Jsonb"
|
||||
}
|
||||
],
|
||||
"parameters": {
|
||||
"Left": [
|
||||
"Text",
|
||||
"Uuid"
|
||||
]
|
||||
},
|
||||
"nullable": [
|
||||
true
|
||||
]
|
||||
},
|
||||
"hash": "ceb8c2607023883e1eebd4b9539e36ed202a6ecd12e3f90cb070341c38886de4"
|
||||
}
|
||||
@@ -5,7 +5,7 @@
|
||||
"columns": [
|
||||
{
|
||||
"ordinal": 0,
|
||||
"name": "bool",
|
||||
"name": "?column?",
|
||||
"type_info": "Bool"
|
||||
}
|
||||
],
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
"columns": [
|
||||
{
|
||||
"ordinal": 0,
|
||||
"name": "bool",
|
||||
"name": "?column?",
|
||||
"type_info": "Bool"
|
||||
}
|
||||
],
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"db_name": "PostgreSQL",
|
||||
"query": "SELECT label, concat(substring(token for 10)) as token_prefix, expiration, created_at, last_used_at, scopes, email FROM token WHERE workspace_id = $1 AND scopes @> ARRAY['run:flow/' || $2]::text[]",
|
||||
"query": "\n SELECT label,\n concat(substring(token for 10)) AS token_prefix,\n expiration,\n created_at,\n last_used_at,\n scopes,\n email\n FROM token\n WHERE workspace_id = $1\n AND (\n scopes @> ARRAY['jobs:run:scripts:' || $2]::text[]\n OR scopes @> ARRAY['run:scripts/' || $2]::text[]\n )\n ",
|
||||
"describe": {
|
||||
"columns": [
|
||||
{
|
||||
@@ -55,5 +55,5 @@
|
||||
true
|
||||
]
|
||||
},
|
||||
"hash": "eff32aeac25a75d06f73e08c26dd3fd25f6b85cbea870505751c6a82457ae1da"
|
||||
"hash": "e8b74683f994d198a051c2f211a2844241bf2a7d7702c569017ae53fca706c59"
|
||||
}
|
||||
@@ -5,7 +5,7 @@
|
||||
"columns": [
|
||||
{
|
||||
"ordinal": 0,
|
||||
"name": "bool",
|
||||
"name": "?column?",
|
||||
"type_info": "Bool"
|
||||
}
|
||||
],
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"db_name": "PostgreSQL",
|
||||
"query": "WITH uuid_table as (\n select unnest($4::uuid[]) as uuid\n )\n INSERT INTO v2_job_queue\n (id, workspace_id, scheduled_for, tag)\n (SELECT uuid, $1, $2, $3 FROM uuid_table) \n RETURNING id",
|
||||
"query": "WITH uuid_table as (\n select unnest($4::uuid[]) as uuid\n )\n INSERT INTO v2_job_queue\n (id, workspace_id, scheduled_for, tag)\n (SELECT uuid, $1, $2, $3 FROM uuid_table)\n RETURNING id",
|
||||
"describe": {
|
||||
"columns": [
|
||||
{
|
||||
@@ -21,5 +21,5 @@
|
||||
false
|
||||
]
|
||||
},
|
||||
"hash": "70e740465e648d84d32a506916ed437d1e32d4b5bdc7f7fae22e804428660836"
|
||||
"hash": "f6e63a324664423353b56bccd9f3b322a3512ccfa86485e0f01664942ae04d0f"
|
||||
}
|
||||
35
backend/.sqlx/query-fab257c4e20aa51b8f785b1882aa0b16fde33b246cbf0749ffa0e4ed63504451.json
generated
Normal file
35
backend/.sqlx/query-fab257c4e20aa51b8f785b1882aa0b16fde33b246cbf0749ffa0e4ed63504451.json
generated
Normal file
@@ -0,0 +1,35 @@
|
||||
{
|
||||
"db_name": "PostgreSQL",
|
||||
"query": "SELECT result as \"result: sqlx::types::Json<Box<RawValue>>\", v2_job.tag,\n v2_job_queue.running as \"running: Option<bool>\"\n FROM v2_job\n LEFT JOIN v2_job_queue USING (id)\n LEFT JOIN v2_job_completed USING (id)\n WHERE v2_job.id = $2 AND v2_job.workspace_id = $1",
|
||||
"describe": {
|
||||
"columns": [
|
||||
{
|
||||
"ordinal": 0,
|
||||
"name": "result: sqlx::types::Json<Box<RawValue>>",
|
||||
"type_info": "Jsonb"
|
||||
},
|
||||
{
|
||||
"ordinal": 1,
|
||||
"name": "tag",
|
||||
"type_info": "Varchar"
|
||||
},
|
||||
{
|
||||
"ordinal": 2,
|
||||
"name": "running: Option<bool>",
|
||||
"type_info": "Bool"
|
||||
}
|
||||
],
|
||||
"parameters": {
|
||||
"Left": [
|
||||
"Text",
|
||||
"Uuid"
|
||||
]
|
||||
},
|
||||
"nullable": [
|
||||
true,
|
||||
false,
|
||||
false
|
||||
]
|
||||
},
|
||||
"hash": "fab257c4e20aa51b8f785b1882aa0b16fde33b246cbf0749ffa0e4ed63504451"
|
||||
}
|
||||
@@ -5,7 +5,7 @@
|
||||
"columns": [
|
||||
{
|
||||
"ordinal": 0,
|
||||
"name": "bool",
|
||||
"name": "?column?",
|
||||
"type_info": "Bool"
|
||||
}
|
||||
],
|
||||
|
||||
@@ -41,11 +41,11 @@
|
||||
]
|
||||
},
|
||||
"nullable": [
|
||||
true,
|
||||
true,
|
||||
true,
|
||||
true,
|
||||
true,
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
true
|
||||
]
|
||||
},
|
||||
|
||||
258
backend/Cargo.lock
generated
258
backend/Cargo.lock
generated
@@ -746,9 +746,9 @@ checksum = "c08606f8c3cbf4ce6ec8e28fb0014a2c086708fe954eaa885384a6165172e7e8"
|
||||
|
||||
[[package]]
|
||||
name = "aws-config"
|
||||
version = "1.8.2"
|
||||
version = "1.8.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ebd9b83179adf8998576317ce47785948bcff399ec5b15f4dfbdedd44ddf5b92"
|
||||
checksum = "c0baa720ebadea158c5bda642ac444a2af0cdf7bb66b46d1e4533de5d1f449d0"
|
||||
dependencies = [
|
||||
"aws-credential-types",
|
||||
"aws-runtime",
|
||||
@@ -776,9 +776,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "aws-credential-types"
|
||||
version = "1.2.3"
|
||||
version = "1.2.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "687bc16bc431a8533fe0097c7f0182874767f920989d7260950172ae8e3c4465"
|
||||
checksum = "b68c2194a190e1efc999612792e25b1ab3abfefe4306494efaaabc25933c0cbe"
|
||||
dependencies = [
|
||||
"aws-smithy-async",
|
||||
"aws-smithy-runtime-api",
|
||||
@@ -788,9 +788,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "aws-lc-rs"
|
||||
version = "1.13.2"
|
||||
version = "1.13.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "08b5d4e069cbc868041a64bd68dc8cb39a0d79585cd6c5a24caa8c2d622121be"
|
||||
checksum = "5c953fe1ba023e6b7730c0d4b031d06f267f23a46167dcbd40316644b10a17ba"
|
||||
dependencies = [
|
||||
"aws-lc-sys",
|
||||
"zeroize",
|
||||
@@ -835,9 +835,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "aws-sdk-sqs"
|
||||
version = "1.75.0"
|
||||
version = "1.77.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7c27b0a5c8f9f8db35929bde0612d738d8c872ab887232579c61d73dba7a5d17"
|
||||
checksum = "32a6dcd63dffae1f7872df42ce9f1f0f785f8c9a3d3e880ef6c171d0415439df"
|
||||
dependencies = [
|
||||
"aws-credential-types",
|
||||
"aws-runtime",
|
||||
@@ -857,9 +857,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "aws-sdk-sso"
|
||||
version = "1.75.0"
|
||||
version = "1.77.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "36d2a4d2753a2304cc0a86cff15581179c420c7b3054c0cbc884a2e497e79ae5"
|
||||
checksum = "18f2f37fea82468fe3f5a059542c05392ef680c4f7f00e0db02df8b6e5c7d0c6"
|
||||
dependencies = [
|
||||
"aws-credential-types",
|
||||
"aws-runtime",
|
||||
@@ -879,9 +879,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "aws-sdk-ssooidc"
|
||||
version = "1.76.0"
|
||||
version = "1.78.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "719f007d6914388e2f14943c663447cfc44bb9d0478bb96df891258ba5145f82"
|
||||
checksum = "ecb4f6eada20e0193450cd48b12ed05e1e66baac86f39160191651b932f2b7d9"
|
||||
dependencies = [
|
||||
"aws-credential-types",
|
||||
"aws-runtime",
|
||||
@@ -901,9 +901,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "aws-sdk-sts"
|
||||
version = "1.77.0"
|
||||
version = "1.79.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "2efcc3dbb630f3e0d16a4f79fcd4b3fb1c59cb89f1031c46e44976f640b5de27"
|
||||
checksum = "317377afba3498fca4948c5d32b399ef9a5ad35561a1e8a6f2ac7273dabf802d"
|
||||
dependencies = [
|
||||
"aws-credential-types",
|
||||
"aws-runtime",
|
||||
@@ -957,9 +957,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "aws-smithy-http"
|
||||
version = "0.62.1"
|
||||
version = "0.62.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "99335bec6cdc50a346fda1437f9fefe33abf8c99060739a546a16457f2862ca9"
|
||||
checksum = "43c82ba4cab184ea61f6edaafc1072aad3c2a17dcf4c0fce19ac5694b90d8b5f"
|
||||
dependencies = [
|
||||
"aws-smithy-runtime-api",
|
||||
"aws-smithy-types",
|
||||
@@ -1034,9 +1034,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "aws-smithy-runtime"
|
||||
version = "1.8.4"
|
||||
version = "1.8.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c3aaec682eb189e43c8a19c3dab2fe54590ad5f2cc2d26ab27608a20f2acf81c"
|
||||
checksum = "660f70d9d8af6876b4c9aa8dcb0dbaf0f89b04ee9a4455bea1b4ba03b15f26f6"
|
||||
dependencies = [
|
||||
"aws-smithy-async",
|
||||
"aws-smithy-http",
|
||||
@@ -1058,9 +1058,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "aws-smithy-runtime-api"
|
||||
version = "1.8.3"
|
||||
version = "1.8.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9852b9226cb60b78ce9369022c0df678af1cac231c882d5da97a0c4e03be6e67"
|
||||
checksum = "937a49ecf061895fca4a6dd8e864208ed9be7546c0527d04bc07d502ec5fba1c"
|
||||
dependencies = [
|
||||
"aws-smithy-async",
|
||||
"aws-smithy-types",
|
||||
@@ -1120,9 +1120,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "aws-types"
|
||||
version = "1.3.7"
|
||||
version = "1.3.8"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8a322fec39e4df22777ed3ad8ea868ac2f94cd15e1a55f6ee8d8d6305057689a"
|
||||
checksum = "b069d19bf01e46298eaedd7c6f283fe565a59263e53eebec945f3e6398f42390"
|
||||
dependencies = [
|
||||
"aws-credential-types",
|
||||
"aws-smithy-async",
|
||||
@@ -1689,9 +1689,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "bytemuck_derive"
|
||||
version = "1.9.3"
|
||||
version = "1.10.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7ecc273b49b3205b83d648f0690daa588925572cc5063745bfe547fe7ec8e1a1"
|
||||
checksum = "441473f2b4b0459a68628c744bc61d23e730fb00128b841d30fa4bb3972257e4"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
@@ -1858,9 +1858,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "cc"
|
||||
version = "1.2.29"
|
||||
version = "1.2.30"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5c1599538de2394445747c8cf7935946e3cc27e9625f889d979bfb2aaf569362"
|
||||
checksum = "deec109607ca693028562ed836a5f1c4b8bd77755c4e132fc5ce11b0b6211ae7"
|
||||
dependencies = [
|
||||
"jobserver",
|
||||
"libc",
|
||||
@@ -2007,9 +2007,9 @@ checksum = "b94f61472cee1439c0b966b47e3aca9ae07e45d070759512cd390ea2bebc6675"
|
||||
|
||||
[[package]]
|
||||
name = "clipboard-win"
|
||||
version = "5.4.0"
|
||||
version = "5.4.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "15efe7a882b08f34e38556b14f2fb3daa98769d06c7f0c1b076dfd0d983bc892"
|
||||
checksum = "bde03770d3df201d4fb868f2c9c59e66a3e4e2bd06692a0fe701e7103c7e84d4"
|
||||
dependencies = [
|
||||
"error-code",
|
||||
]
|
||||
@@ -2411,15 +2411,15 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "curve25519-dalek"
|
||||
version = "4.2.0"
|
||||
version = "4.1.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "373b7c5dbd637569a2cca66e8d66b8c446a1e7bf064ea321d265d7b3dfe7c97e"
|
||||
checksum = "97fb8b7c4503de7d6ae7b42ab72a5a59857b4c937ec27a3d4539dba95b5ab2be"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"cpufeatures",
|
||||
"curve25519-dalek-derive",
|
||||
"digest 0.10.7",
|
||||
"fiat-crypto 0.3.0",
|
||||
"fiat-crypto 0.2.9",
|
||||
"rustc_version 0.4.1",
|
||||
"subtle",
|
||||
"zeroize",
|
||||
@@ -3737,7 +3737,7 @@ dependencies = [
|
||||
"quinn",
|
||||
"rustls-tokio-stream",
|
||||
"serde",
|
||||
"socket2",
|
||||
"socket2 0.5.10",
|
||||
"thiserror 2.0.12",
|
||||
"tokio",
|
||||
]
|
||||
@@ -4674,7 +4674,7 @@ dependencies = [
|
||||
"num-integer",
|
||||
"rust_decimal",
|
||||
"smallvec",
|
||||
"strum 0.27.1",
|
||||
"strum 0.27.2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -4685,9 +4685,9 @@ checksum = "92773504d58c093f6de2459af4af33faa518c13451eb8f2b5698ed3d36e7c813"
|
||||
|
||||
[[package]]
|
||||
name = "dyn-clone"
|
||||
version = "1.0.19"
|
||||
version = "1.0.20"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1c7a8fb8a9fbf66c1f703fe16184d10ca0ee9d23be5b4436400408ba54a95005"
|
||||
checksum = "d0881ea181b1df73ff77ffaaf9c7544ecc11e82fba9b5f27b262a3c73a332555"
|
||||
|
||||
[[package]]
|
||||
name = "dyn-iter"
|
||||
@@ -5090,9 +5090,9 @@ checksum = "e825f6987101665dea6ec934c09ec6d721de7bc1bf92248e1d5810c8cd636b77"
|
||||
|
||||
[[package]]
|
||||
name = "fiat-crypto"
|
||||
version = "0.3.0"
|
||||
version = "0.2.9"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "64cd1e32ddd350061ae6edb1b082d7c54915b5c672c389143b9a63403a109f24"
|
||||
checksum = "28dea519a9695b9977216879a3ebfddf92f1c08c05d984f8996aecd6ecdc811d"
|
||||
|
||||
[[package]]
|
||||
name = "filetime"
|
||||
@@ -6377,7 +6377,7 @@ dependencies = [
|
||||
"httpdate",
|
||||
"itoa",
|
||||
"pin-project-lite",
|
||||
"socket2",
|
||||
"socket2 0.5.10",
|
||||
"tokio",
|
||||
"tower-service",
|
||||
"tracing",
|
||||
@@ -6451,7 +6451,7 @@ dependencies = [
|
||||
"tokio",
|
||||
"tokio-rustls 0.26.2",
|
||||
"tower-service",
|
||||
"webpki-roots 1.0.1",
|
||||
"webpki-roots 1.0.2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -6498,9 +6498,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "hyper-util"
|
||||
version = "0.1.15"
|
||||
version = "0.1.16"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7f66d5bd4c6f02bf0542fad85d626775bab9258cf795a4256dcaf3161114d1df"
|
||||
checksum = "8d9b05277c7e8da2c93a568989bb6207bef0112e8d17df7a6eda4a3cf143bc5e"
|
||||
dependencies = [
|
||||
"base64 0.22.1",
|
||||
"bytes",
|
||||
@@ -6514,7 +6514,7 @@ dependencies = [
|
||||
"libc",
|
||||
"percent-encoding",
|
||||
"pin-project-lite",
|
||||
"socket2",
|
||||
"socket2 0.6.0",
|
||||
"system-configuration 0.6.1",
|
||||
"tokio",
|
||||
"tower-service",
|
||||
@@ -6820,9 +6820,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "io-uring"
|
||||
version = "0.7.8"
|
||||
version = "0.7.9"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b86e202f00093dcba4275d4636b93ef9dd75d025ae560d2521b45ea28ab49013"
|
||||
checksum = "d93587f37623a1a17d94ef2bc9ada592f5465fe7732084ab7beefabe5c77c0c4"
|
||||
dependencies = [
|
||||
"bitflags 2.9.1",
|
||||
"cfg-if",
|
||||
@@ -6835,7 +6835,7 @@ version = "0.3.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b58db92f96b720de98181bbbe63c831e87005ab460c1bf306eb2622b4707997f"
|
||||
dependencies = [
|
||||
"socket2",
|
||||
"socket2 0.5.10",
|
||||
"widestring",
|
||||
"windows-sys 0.48.0",
|
||||
"winreg",
|
||||
@@ -6969,9 +6969,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "jsonc-parser"
|
||||
version = "0.26.2"
|
||||
version = "0.26.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b558af6b49fd918e970471374e7a798b2c9bbcda624a210ffa3901ee5614bc8e"
|
||||
checksum = "1d6d80e6d70e7911a29f3cf3f44f452df85d06f73572b494ca99a2cad3fcf8f4"
|
||||
dependencies = [
|
||||
"serde_json",
|
||||
]
|
||||
@@ -7270,7 +7270,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "07033963ba89ebaf1584d767badaa2e8fcec21aedea6b8c0346d487d49c28667"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"windows-targets 0.53.2",
|
||||
"windows-targets 0.53.3",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -7292,13 +7292,13 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "libredox"
|
||||
version = "0.1.4"
|
||||
version = "0.1.8"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1580801010e535496706ba011c15f8532df6b42297d2e471fec38ceadd8c0638"
|
||||
checksum = "360e552c93fa0e8152ab463bc4c4837fce76a225df11dfaeea66c313de5e61f7"
|
||||
dependencies = [
|
||||
"bitflags 2.9.1",
|
||||
"libc",
|
||||
"redox_syscall 0.5.13",
|
||||
"redox_syscall 0.5.17",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -7380,9 +7380,9 @@ checksum = "241eaef5fd12c88705a01fc1066c48c4b36e0dd4377dcdc7ec3942cea7a69956"
|
||||
|
||||
[[package]]
|
||||
name = "litrs"
|
||||
version = "0.4.1"
|
||||
version = "0.4.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b4ce301924b7887e9d637144fdade93f9dfff9b60981d4ac161db09720d39aa5"
|
||||
checksum = "f5e54036fe321fd421e10d732f155734c4e4afd610dd556d9a82833ab3ee0bed"
|
||||
|
||||
[[package]]
|
||||
name = "lock_api"
|
||||
@@ -7960,7 +7960,7 @@ dependencies = [
|
||||
"rand 0.9.0",
|
||||
"serde",
|
||||
"serde_json",
|
||||
"socket2",
|
||||
"socket2 0.5.10",
|
||||
"thiserror 2.0.12",
|
||||
"tokio",
|
||||
"tokio-native-tls",
|
||||
@@ -9056,7 +9056,7 @@ checksum = "bc838d2a56b5b1a6c25f55575dfc605fabb63bb2365f6c2353ef9159aa69e4a5"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"libc",
|
||||
"redox_syscall 0.5.13",
|
||||
"redox_syscall 0.5.17",
|
||||
"smallvec",
|
||||
"windows-targets 0.52.6",
|
||||
]
|
||||
@@ -9507,9 +9507,9 @@ checksum = "c6fa0831dd7cc608c38a5e323422a0077678fa5744aa2be4ad91c4ece8eec8d5"
|
||||
|
||||
[[package]]
|
||||
name = "prettyplease"
|
||||
version = "0.2.35"
|
||||
version = "0.2.36"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "061c1221631e079b26479d25bbf2275bfe5917ae8419cd7e34f13bfc2aa7539a"
|
||||
checksum = "ff24dfcda44452b9816fff4cd4227e1bb73ff5a2f1bc1105aa92fb8565ce44d2"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"syn 2.0.104",
|
||||
@@ -9841,9 +9841,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "quick_cache"
|
||||
version = "0.6.14"
|
||||
version = "0.6.15"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "6b450dad8382b1b95061d5ca1eb792081fb082adf48c678791fe917509596d5f"
|
||||
checksum = "8565e62e02af316570d4b492f17af1481d6c07cea60f4e7edd71700da5052ba9"
|
||||
dependencies = [
|
||||
"ahash 0.8.12",
|
||||
"equivalent",
|
||||
@@ -9864,7 +9864,7 @@ dependencies = [
|
||||
"quinn-udp",
|
||||
"rustc-hash 2.1.1",
|
||||
"rustls 0.23.29",
|
||||
"socket2",
|
||||
"socket2 0.5.10",
|
||||
"thiserror 2.0.12",
|
||||
"tokio",
|
||||
"tracing",
|
||||
@@ -9901,7 +9901,7 @@ dependencies = [
|
||||
"cfg_aliases 0.2.1",
|
||||
"libc",
|
||||
"once_cell",
|
||||
"socket2",
|
||||
"socket2 0.5.10",
|
||||
"tracing",
|
||||
"windows-sys 0.59.0",
|
||||
]
|
||||
@@ -10156,9 +10156,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "redox_syscall"
|
||||
version = "0.5.13"
|
||||
version = "0.5.17"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0d04b7d0ee6b4a0207a0a7adb104d23ecb0b47d6beae7152d0fa34b692b29fd6"
|
||||
checksum = "5407465600fb0548f1442edf71dd20683c6ed326200ace4b1ef0763521bb3b77"
|
||||
dependencies = [
|
||||
"bitflags 2.9.1",
|
||||
]
|
||||
@@ -10358,7 +10358,7 @@ dependencies = [
|
||||
"wasm-bindgen-futures",
|
||||
"wasm-streams",
|
||||
"web-sys",
|
||||
"webpki-roots 1.0.1",
|
||||
"webpki-roots 1.0.2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -10663,9 +10663,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "rustc-demangle"
|
||||
version = "0.1.25"
|
||||
version = "0.1.26"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "989e6739f80c4ad5b13e0fd7fe89531180375b18520cc8c82080e4dc4035b84f"
|
||||
checksum = "56f7d92ca342cea22a06f2121d944b4fd82af56988c270852495420f961d4ace"
|
||||
|
||||
[[package]]
|
||||
name = "rustc-hash"
|
||||
@@ -10847,7 +10847,7 @@ checksum = "22557157d7395bc30727745b365d923f1ecc230c4c80b176545f3f4f08c46e33"
|
||||
dependencies = [
|
||||
"futures",
|
||||
"rustls 0.23.29",
|
||||
"socket2",
|
||||
"socket2 0.5.10",
|
||||
"tokio",
|
||||
]
|
||||
|
||||
@@ -11303,9 +11303,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "serde_json"
|
||||
version = "1.0.140"
|
||||
version = "1.0.141"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "20068b6e96dc6c9bd23e01df8827e6c7e1f2fddd43c21810382803c136b99373"
|
||||
checksum = "30b9eff21ebe718216c6ec64e1d9ac57087aad11efc64e32002bce4a0d4c03d3"
|
||||
dependencies = [
|
||||
"indexmap 2.10.0",
|
||||
"itoa",
|
||||
@@ -11696,6 +11696,16 @@ dependencies = [
|
||||
"windows-sys 0.52.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "socket2"
|
||||
version = "0.6.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "233504af464074f9d066d7b5416c5f9b894a5862a6506e306f7b816cdd6f1807"
|
||||
dependencies = [
|
||||
"libc",
|
||||
"windows-sys 0.59.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "socks"
|
||||
version = "0.3.4"
|
||||
@@ -12129,11 +12139,11 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "strum"
|
||||
version = "0.27.1"
|
||||
version = "0.27.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f64def088c51c9510a8579e3c5d67c65349dcf755e5479ad3d010aa6454e2c32"
|
||||
checksum = "af23d6f6c1a224baef9d3f61e287d2761385a5b88fdab4eb4c6f11aeb54c4bcf"
|
||||
dependencies = [
|
||||
"strum_macros 0.27.1",
|
||||
"strum_macros 0.27.2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -12151,14 +12161,13 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "strum_macros"
|
||||
version = "0.27.1"
|
||||
version = "0.27.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c77a8c5abcaf0f9ce05d62342b7d298c346515365c36b673df4ebe3ced01fde8"
|
||||
checksum = "7695ce3845ea4b33927c055a39dc438a45b059f7c1b3d91d38d10355fb8cbca7"
|
||||
dependencies = [
|
||||
"heck 0.5.0",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"rustversion",
|
||||
"syn 2.0.104",
|
||||
]
|
||||
|
||||
@@ -12741,9 +12750,9 @@ checksum = "7b2093cf4c8eb1e67749a6762251bc9cd836b6fc171623bd0a9d324d37af2417"
|
||||
|
||||
[[package]]
|
||||
name = "tantivy"
|
||||
version = "0.22.0"
|
||||
version = "0.22.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f8d0582f186c0a6d55655d24543f15e43607299425c5ad8352c242b914b31856"
|
||||
checksum = "96599ea6fccd844fc833fed21d2eecac2e6a7c1afd9e044057391d78b1feb141"
|
||||
dependencies = [
|
||||
"aho-corasick",
|
||||
"arc-swap",
|
||||
@@ -13207,7 +13216,7 @@ dependencies = [
|
||||
"pin-project-lite",
|
||||
"signal-hook-registry",
|
||||
"slab",
|
||||
"socket2",
|
||||
"socket2 0.5.10",
|
||||
"tokio-macros",
|
||||
"tracing",
|
||||
"windows-sys 0.52.0",
|
||||
@@ -13275,7 +13284,7 @@ dependencies = [
|
||||
"postgres-protocol 0.6.7",
|
||||
"postgres-types 0.2.7",
|
||||
"rand 0.8.5",
|
||||
"socket2",
|
||||
"socket2 0.5.10",
|
||||
"tokio",
|
||||
"tokio-util",
|
||||
"whoami",
|
||||
@@ -13301,7 +13310,7 @@ dependencies = [
|
||||
"postgres-protocol 0.6.8",
|
||||
"postgres-types 0.2.9",
|
||||
"rand 0.9.0",
|
||||
"socket2",
|
||||
"socket2 0.5.10",
|
||||
"tokio",
|
||||
"tokio-util",
|
||||
"whoami",
|
||||
@@ -13507,7 +13516,7 @@ dependencies = [
|
||||
"prost",
|
||||
"rustls-native-certs 0.8.1",
|
||||
"rustls-pemfile 2.2.0",
|
||||
"socket2",
|
||||
"socket2 0.5.10",
|
||||
"tokio",
|
||||
"tokio-rustls 0.26.2",
|
||||
"tokio-stream",
|
||||
@@ -14489,14 +14498,14 @@ version = "0.26.11"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "75c7f0ef91146ebfb530314f5f1d24528d7f0767efbfd31dce919275413e393e"
|
||||
dependencies = [
|
||||
"webpki-root-certs 1.0.1",
|
||||
"webpki-root-certs 1.0.2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "webpki-root-certs"
|
||||
version = "1.0.1"
|
||||
version = "1.0.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "86138b15b2b7d561bc4469e77027b8dd005a43dc502e9031d1f5afc8ce1f280e"
|
||||
checksum = "4e4ffd8df1c57e87c325000a3d6ef93db75279dc3a231125aac571650f22b12a"
|
||||
dependencies = [
|
||||
"rustls-pki-types",
|
||||
]
|
||||
@@ -14507,14 +14516,14 @@ version = "0.26.11"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "521bc38abb08001b01866da9f51eb7c5d647a19260e00054a8c7fd5f9e57f7a9"
|
||||
dependencies = [
|
||||
"webpki-roots 1.0.1",
|
||||
"webpki-roots 1.0.2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "webpki-roots"
|
||||
version = "1.0.1"
|
||||
version = "1.0.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8782dd5a41a24eed3a4f40b606249b3e236ca61adf1f25ea4d45c73de122b502"
|
||||
checksum = "7e8983c3ab33d6fb807cfcdad2491c4ea8cbc8ed839181c7dfd9c67c83e261b2"
|
||||
dependencies = [
|
||||
"rustls-pki-types",
|
||||
]
|
||||
@@ -14632,7 +14641,7 @@ version = "1.6.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "6994d13118ab492c3c80c1f81928718159254c53c472bf9ce36f8dae4add02a7"
|
||||
dependencies = [
|
||||
"redox_syscall 0.5.13",
|
||||
"redox_syscall 0.5.17",
|
||||
"wasite",
|
||||
"web-sys",
|
||||
]
|
||||
@@ -14676,7 +14685,7 @@ checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f"
|
||||
|
||||
[[package]]
|
||||
name = "windmill"
|
||||
version = "1.507.1"
|
||||
version = "1.515.1"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"axum",
|
||||
@@ -14705,7 +14714,7 @@ dependencies = [
|
||||
"sha2 0.10.9",
|
||||
"size",
|
||||
"sqlx",
|
||||
"strum 0.27.1",
|
||||
"strum 0.27.2",
|
||||
"systemstat",
|
||||
"tikv-jemalloc-ctl",
|
||||
"tikv-jemalloc-sys",
|
||||
@@ -14728,7 +14737,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "windmill-api"
|
||||
version = "1.507.1"
|
||||
version = "1.515.1"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"argon2",
|
||||
@@ -14739,8 +14748,11 @@ dependencies = [
|
||||
"async_zip",
|
||||
"aws-config",
|
||||
"aws-sdk-sqs",
|
||||
"aws-sdk-sso",
|
||||
"aws-sdk-ssooidc",
|
||||
"aws-sdk-sts",
|
||||
"axum",
|
||||
"backon",
|
||||
"base32",
|
||||
"base64 0.22.1",
|
||||
"byteorder",
|
||||
@@ -14794,6 +14806,7 @@ dependencies = [
|
||||
"rumqttc",
|
||||
"rust-embed",
|
||||
"rust_decimal",
|
||||
"rustls 0.23.29",
|
||||
"samael",
|
||||
"serde",
|
||||
"serde_json",
|
||||
@@ -14839,7 +14852,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "windmill-api-client"
|
||||
version = "1.507.1"
|
||||
version = "1.515.1"
|
||||
dependencies = [
|
||||
"base64 0.22.1",
|
||||
"chrono",
|
||||
@@ -14854,7 +14867,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "windmill-audit"
|
||||
version = "1.507.1"
|
||||
version = "1.515.1"
|
||||
dependencies = [
|
||||
"chrono",
|
||||
"serde",
|
||||
@@ -14867,7 +14880,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "windmill-autoscaling"
|
||||
version = "1.507.1"
|
||||
version = "1.515.1"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"serde",
|
||||
@@ -14881,7 +14894,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "windmill-common"
|
||||
version = "1.507.1"
|
||||
version = "1.515.1"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"async-stream",
|
||||
@@ -14932,8 +14945,9 @@ dependencies = [
|
||||
"sha2 0.10.9",
|
||||
"size",
|
||||
"sqlx",
|
||||
"strum 0.27.1",
|
||||
"strum_macros 0.27.1",
|
||||
"strum 0.27.2",
|
||||
"strum_macros 0.27.2",
|
||||
"sysinfo",
|
||||
"systemstat",
|
||||
"tar",
|
||||
"tempfile",
|
||||
@@ -14959,7 +14973,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "windmill-git-sync"
|
||||
version = "1.507.1"
|
||||
version = "1.515.1"
|
||||
dependencies = [
|
||||
"regex",
|
||||
"serde",
|
||||
@@ -14973,12 +14987,13 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "windmill-indexer"
|
||||
version = "1.507.1"
|
||||
version = "1.515.1"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"bytes",
|
||||
"chrono",
|
||||
"const_format",
|
||||
"flume",
|
||||
"futures",
|
||||
"lazy_static",
|
||||
"object_store",
|
||||
@@ -14996,7 +15011,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "windmill-macros"
|
||||
version = "1.507.1"
|
||||
version = "1.515.1"
|
||||
dependencies = [
|
||||
"itertools 0.14.0",
|
||||
"lazy_static",
|
||||
@@ -15008,7 +15023,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "windmill-parser"
|
||||
version = "1.507.1"
|
||||
version = "1.515.1"
|
||||
dependencies = [
|
||||
"convert_case 0.6.0",
|
||||
"serde",
|
||||
@@ -15017,7 +15032,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "windmill-parser-bash"
|
||||
version = "1.507.1"
|
||||
version = "1.515.1"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"lazy_static",
|
||||
@@ -15029,7 +15044,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "windmill-parser-csharp"
|
||||
version = "1.507.1"
|
||||
version = "1.515.1"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"serde_json",
|
||||
@@ -15041,7 +15056,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "windmill-parser-go"
|
||||
version = "1.507.1"
|
||||
version = "1.515.1"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"gosyn",
|
||||
@@ -15053,7 +15068,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "windmill-parser-graphql"
|
||||
version = "1.507.1"
|
||||
version = "1.515.1"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"lazy_static",
|
||||
@@ -15065,7 +15080,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "windmill-parser-java"
|
||||
version = "1.507.1"
|
||||
version = "1.515.1"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"serde_json",
|
||||
@@ -15077,7 +15092,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "windmill-parser-nu"
|
||||
version = "1.507.1"
|
||||
version = "1.515.1"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"nu-parser",
|
||||
@@ -15088,7 +15103,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "windmill-parser-php"
|
||||
version = "1.507.1"
|
||||
version = "1.515.1"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"itertools 0.14.0",
|
||||
@@ -15099,7 +15114,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "windmill-parser-py"
|
||||
version = "1.507.1"
|
||||
version = "1.515.1"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"itertools 0.14.0",
|
||||
@@ -15111,7 +15126,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "windmill-parser-py-imports"
|
||||
version = "1.507.1"
|
||||
version = "1.515.1"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"async-recursion",
|
||||
@@ -15134,7 +15149,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "windmill-parser-rust"
|
||||
version = "1.507.1"
|
||||
version = "1.515.1"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"convert_case 0.6.0",
|
||||
@@ -15151,7 +15166,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "windmill-parser-sql"
|
||||
version = "1.507.1"
|
||||
version = "1.515.1"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"lazy_static",
|
||||
@@ -15165,7 +15180,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "windmill-parser-ts"
|
||||
version = "1.507.1"
|
||||
version = "1.515.1"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"lazy_static",
|
||||
@@ -15183,7 +15198,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "windmill-parser-wasm"
|
||||
version = "1.507.1"
|
||||
version = "1.515.1"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"getrandom 0.2.16",
|
||||
@@ -15207,7 +15222,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "windmill-parser-yaml"
|
||||
version = "1.507.1"
|
||||
version = "1.515.1"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"serde_json",
|
||||
@@ -15217,7 +15232,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "windmill-queue"
|
||||
version = "1.507.1"
|
||||
version = "1.515.1"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"async-recursion",
|
||||
@@ -15250,7 +15265,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "windmill-sql-datatype-parser-wasm"
|
||||
version = "1.507.1"
|
||||
version = "1.515.1"
|
||||
dependencies = [
|
||||
"wasm-bindgen",
|
||||
"wasm-bindgen-test",
|
||||
@@ -15260,7 +15275,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "windmill-worker"
|
||||
version = "1.507.1"
|
||||
version = "1.515.1"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"async-recursion",
|
||||
@@ -15596,7 +15611,7 @@ version = "0.60.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f2f500e4d28234f72040990ec9d39e3a6b950f9f22d3dba18416c35882612bcb"
|
||||
dependencies = [
|
||||
"windows-targets 0.53.2",
|
||||
"windows-targets 0.53.3",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -15632,10 +15647,11 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "windows-targets"
|
||||
version = "0.53.2"
|
||||
version = "0.53.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c66f69fcc9ce11da9966ddb31a40968cad001c5bedeb5c2b82ede4253ab48aef"
|
||||
checksum = "d5fe6031c4041849d7c496a8ded650796e7b6ecc19df1a431c1a363342e5dc91"
|
||||
dependencies = [
|
||||
"windows-link",
|
||||
"windows_aarch64_gnullvm 0.53.0",
|
||||
"windows_aarch64_msvc 0.53.0",
|
||||
"windows_i686_gnu 0.53.0",
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
[package]
|
||||
name = "windmill"
|
||||
version = "1.507.1"
|
||||
version = "1.515.1"
|
||||
authors.workspace = true
|
||||
edition.workspace = true
|
||||
|
||||
@@ -28,11 +28,11 @@ members = [
|
||||
"./parsers/windmill-parser-py",
|
||||
"./parsers/windmill-parser-py-imports",
|
||||
"./parsers/windmill-sql-datatype-parser-wasm",
|
||||
"./parsers/windmill-parser-yaml", "windmill-macros", "parsers/windmill-parser-nu",
|
||||
"./parsers/windmill-parser-yaml", "windmill-macros", "parsers/windmill-parser-nu"
|
||||
]
|
||||
|
||||
[workspace.package]
|
||||
version = "1.507.1"
|
||||
version = "1.515.1"
|
||||
authors = ["Ruben Fiszel <ruben@windmill.dev>"]
|
||||
edition = "2021"
|
||||
|
||||
@@ -190,12 +190,11 @@ windmill-api-client = { path = "./windmill-api-client" }
|
||||
reqwest-retry = "^0"
|
||||
reqwest-middleware = { version = "^0", features = ["json"] }
|
||||
|
||||
rustls = "0.23.0"
|
||||
memchr = "2.7.4"
|
||||
axum = { version = "^0.7", features = ["multipart"] }
|
||||
headers = "^0"
|
||||
hyper = { version = "^1", features = ["full"] }
|
||||
tokio = { version = "^1.42.0", features = ["full", "tracing", "time"] }
|
||||
tokio = { version = "=1.46.1", features = ["full", "tracing", "time"] }
|
||||
tokio-stream = { version = "0.1.17" }
|
||||
tower = "^0"
|
||||
tower-http = { version = "^0.6", features = ["trace", "cors"] }
|
||||
@@ -267,6 +266,7 @@ google-cloud-googleapis = {version = "0.16.1", features = ["pubsub"]}
|
||||
# TODO: remove once deno fixes the issue on their end
|
||||
# https://github.com/denoland/deno/issues/28557
|
||||
winapi = { version = "0.3.9", features = ["sysinfoapi"] }
|
||||
sysinfo = { version = "0.32.1" }
|
||||
|
||||
swc_common = "=0.37.5"
|
||||
swc_ecma_parser = "=0.149.1"
|
||||
@@ -353,8 +353,14 @@ datafusion = "47.0.0"
|
||||
object_store = { git = "https://github.com/apache/arrow-rs-object-store", rev = "36752c975d4f29e20b57c91f81a10872dcd48ae7", features = ["aws", "azure", "gcp"] }
|
||||
openidconnect = { version = "4.0.0-rc.1" }
|
||||
aws-config = "^1"
|
||||
aws-sdk-sqs = "1.57.0"
|
||||
aws-sdk-sts = "^1"
|
||||
aws-sdk-sqs = "=1.77.0"
|
||||
aws-sdk-sts = "=1.79.0"
|
||||
aws-sdk-sso = "=1.77.0"
|
||||
aws-sdk-ssooidc = "=1.78.0"
|
||||
rustls = "=0.23.29"
|
||||
|
||||
|
||||
|
||||
aws-smithy-types-convert = { version = "^0", features = ["convert-chrono"] }
|
||||
crc = "^3"
|
||||
tar = "^0"
|
||||
|
||||
@@ -1 +1 @@
|
||||
3cccbe81494f7edd113dce2812278b00c91160c0
|
||||
cef7486dfa765f1cdfaddba59564c4bb92fe864e
|
||||
@@ -0,0 +1,7 @@
|
||||
-- Add 'variable' kind back
|
||||
ALTER TABLE asset ALTER column kind TYPE VARCHAR;
|
||||
DROP TYPE asset_kind;
|
||||
CREATE TYPE ASSET_KIND AS ENUM ('s3object', 'resource', 'variable');
|
||||
ALTER TABLE asset ALTER column kind TYPE ASSET_KIND using kind::ASSET_KIND;
|
||||
|
||||
ALTER TABLE script DROP COLUMN assets;
|
||||
8
backend/migrations/20250717135503_assets_refactor.up.sql
Normal file
8
backend/migrations/20250717135503_assets_refactor.up.sql
Normal file
@@ -0,0 +1,8 @@
|
||||
ALTER TABLE script ADD COLUMN assets jsonb;
|
||||
|
||||
-- Remove 'variable' kind
|
||||
DELETE FROM asset WHERE kind = 'variable';
|
||||
ALTER TABLE asset ALTER column kind TYPE VARCHAR;
|
||||
DROP TYPE asset_kind;
|
||||
CREATE TYPE ASSET_KIND AS ENUM ('s3object', 'resource');
|
||||
ALTER TABLE asset ALTER column kind TYPE ASSET_KIND using kind::ASSET_KIND;
|
||||
@@ -0,0 +1,2 @@
|
||||
-- Rollback cc_token_url column addition
|
||||
ALTER TABLE account DROP COLUMN IF EXISTS cc_token_url;
|
||||
@@ -0,0 +1,3 @@
|
||||
-- Add cc_token_url column for resource-level token URL override in OAuth client credentials flow
|
||||
-- This allows resources to override the token URL from instance settings when using client credentials
|
||||
ALTER TABLE account ADD COLUMN cc_token_url VARCHAR(500);
|
||||
@@ -0,0 +1 @@
|
||||
-- Add down migration script here
|
||||
@@ -0,0 +1,2 @@
|
||||
-- Add up migration script here
|
||||
ALTER TYPE ASSET_KIND ADD VALUE 'variable';
|
||||
@@ -0,0 +1 @@
|
||||
-- Add down migration script here
|
||||
@@ -0,0 +1,2 @@
|
||||
-- Add up migration script here
|
||||
ALTER TABLE resource ALTER COLUMN created_by TYPE VARCHAR(500);
|
||||
@@ -0,0 +1 @@
|
||||
-- Add down migration script here
|
||||
@@ -0,0 +1,2 @@
|
||||
ALTER TABLE audit ALTER COLUMN id TYPE bigint;
|
||||
ALTER SEQUENCE audit_id_seq AS bigint;
|
||||
@@ -7,7 +7,7 @@ use anyhow::anyhow;
|
||||
use tree_sitter::Node;
|
||||
use windmill_parser::Arg;
|
||||
use windmill_parser::MainArgSignature;
|
||||
use windmill_parser::Typ;
|
||||
use windmill_parser::{ObjectType, Typ};
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct CsharpMainSigMeta {
|
||||
@@ -112,7 +112,7 @@ fn find_typ<'a>(typ_node: Node<'a>, code: &str) -> anyhow::Result<Typ> {
|
||||
Ok("double") | Ok("System.Double") => Ok(Typ::Float),
|
||||
Ok("bool") | Ok("System.Boolean") => Ok(Typ::Bool),
|
||||
Ok("decimal") | Ok("System.Decimal") => Ok(Typ::Float),
|
||||
Ok("object") => Ok(Typ::Object(vec![])), // TODO: Complete the object type
|
||||
Ok("object") => Ok(Typ::Object(ObjectType::new(None, Some(vec![])))), // TODO: Complete the object type
|
||||
Ok(s) => Err(anyhow!("Unknown type `{s}`")),
|
||||
Err(e) => Err(anyhow!("Error getting type name: {}", e)),
|
||||
}
|
||||
|
||||
@@ -7,7 +7,7 @@ use gosyn::{
|
||||
use itertools::Itertools;
|
||||
|
||||
use regex::Regex;
|
||||
use windmill_parser::{Arg, MainArgSignature, ObjectProperty, Typ};
|
||||
use windmill_parser::{Arg, MainArgSignature, ObjectProperty, ObjectType, Typ};
|
||||
|
||||
lazy_static::lazy_static! {
|
||||
pub static ref REQUIRE_PARSE: Regex = Regex::new(r"//require (.*)\n").unwrap();
|
||||
@@ -142,13 +142,13 @@ fn parse_go_typ(typ: &Expression) -> (Option<String>, Typ) {
|
||||
"struct {{ {} }}",
|
||||
otyps.iter().join("; ").to_string()
|
||||
)),
|
||||
Typ::Object(typs),
|
||||
Typ::Object(ObjectType::new(None, Some(typs))),
|
||||
)
|
||||
}
|
||||
Expression::TypeInterface(_) => (Some("interface{}".to_string()), Typ::Object(vec![])),
|
||||
Expression::TypeInterface(_) => (Some("interface{}".to_string()), Typ::Object(ObjectType::new(None, Some(vec![])))),
|
||||
Expression::TypeMap(_) => (
|
||||
Some("map[string]interface{}".to_string()),
|
||||
Typ::Object(vec![]),
|
||||
Typ::Object(ObjectType::new(None, Some(vec![]))),
|
||||
),
|
||||
_ => (None, Typ::Unknown),
|
||||
}
|
||||
@@ -218,10 +218,10 @@ func main(x int, y string, z bool, l []string, o struct { Name string `json:"nam
|
||||
Arg {
|
||||
otyp: Some("struct { Name string `json:\"name\"` }".to_string()),
|
||||
name: "o".to_string(),
|
||||
typ: Typ::Object(vec![ObjectProperty {
|
||||
typ: Typ::Object(ObjectType::new(None, Some(vec![ObjectProperty {
|
||||
key: "name".to_string(),
|
||||
typ: Box::new(Typ::Str(None))
|
||||
},]),
|
||||
},]))),
|
||||
default: None,
|
||||
has_default: false,
|
||||
oidx: None
|
||||
@@ -229,7 +229,7 @@ func main(x int, y string, z bool, l []string, o struct { Name string `json:"nam
|
||||
Arg {
|
||||
otyp: Some("interface{}".to_string()),
|
||||
name: "n".to_string(),
|
||||
typ: Typ::Object(vec![]),
|
||||
typ: Typ::Object(ObjectType::new(None, Some(vec![]))),
|
||||
default: None,
|
||||
has_default: false,
|
||||
oidx: None
|
||||
@@ -237,7 +237,7 @@ func main(x int, y string, z bool, l []string, o struct { Name string `json:"nam
|
||||
Arg {
|
||||
otyp: Some("map[string]interface{}".to_string()),
|
||||
name: "m".to_string(),
|
||||
typ: Typ::Object(vec![]),
|
||||
typ: Typ::Object(ObjectType::new(None, Some(vec![]))),
|
||||
default: None,
|
||||
has_default: false,
|
||||
oidx: None
|
||||
|
||||
@@ -9,7 +9,7 @@ use regex_lite::Regex;
|
||||
|
||||
use serde_json::json;
|
||||
|
||||
use windmill_parser::{Arg, MainArgSignature, Typ};
|
||||
use windmill_parser::{Arg, MainArgSignature, ObjectType, Typ};
|
||||
|
||||
pub fn parse_graphql_sig(code: &str) -> anyhow::Result<MainArgSignature> {
|
||||
let parsed = parse_graphql_file(&code)?;
|
||||
@@ -75,7 +75,7 @@ pub fn parse_graphql_typ(typ: &str) -> Typ {
|
||||
"Int" => Typ::Int,
|
||||
"Boolean" => Typ::Bool,
|
||||
"Float" => Typ::Float,
|
||||
_ => Typ::Object(vec![]),
|
||||
_ => Typ::Object(ObjectType::new(None, Some(vec![]))),
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -9,7 +9,7 @@ use serde_json::Value;
|
||||
use tree_sitter::Node;
|
||||
use windmill_parser::Arg;
|
||||
use windmill_parser::MainArgSignature;
|
||||
use windmill_parser::Typ;
|
||||
use windmill_parser::{ObjectType, Typ};
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct JavaMainSigMeta {
|
||||
@@ -101,7 +101,7 @@ fn find_typ<'a>(typ_node: Node<'a>, code: &str) -> anyhow::Result<(Typ, Option<V
|
||||
Ok("Double") => (Typ::Float, null),
|
||||
Ok("Boolean") => (Typ::Bool, null),
|
||||
Ok("Character") => (Typ::Str(None), null),
|
||||
Ok("Object") => (Typ::Object(vec![]),null), // TODO: Complete the object type
|
||||
Ok("Object") => (Typ::Object(ObjectType::new(None, Some(vec![]))),null), // TODO: Complete the object type
|
||||
Ok(s) => bail!("Unknown type `{s}`"),
|
||||
Err(e) => bail!("Error getting type name: {}", e),
|
||||
}
|
||||
@@ -394,7 +394,7 @@ class Main {
|
||||
Arg {
|
||||
name: "i".into(),
|
||||
otyp: Some("Object".into()),
|
||||
typ: Typ::Object(vec![]),
|
||||
typ: Typ::Object(ObjectType::new(None, Some(vec![]))),
|
||||
default: Some(json!(null)),
|
||||
has_default: true,
|
||||
oidx: None
|
||||
@@ -427,7 +427,7 @@ class Main {
|
||||
Arg {
|
||||
name: "b".into(),
|
||||
otyp: Some("Object[]".into()),
|
||||
typ: Typ::List(Box::new(Typ::Object(vec![]))),
|
||||
typ: Typ::List(Box::new(Typ::Object(ObjectType::new(None, Some(vec![]))))),
|
||||
default: Some(json!(null)),
|
||||
has_default: true,
|
||||
oidx: None
|
||||
|
||||
@@ -4,7 +4,7 @@ use anyhow::{anyhow, bail};
|
||||
use nu_parser::lex;
|
||||
|
||||
use serde_json::{json, Value};
|
||||
use windmill_parser::{Arg, MainArgSignature, Typ};
|
||||
use windmill_parser::{Arg, MainArgSignature, ObjectType, Typ};
|
||||
|
||||
pub fn parse_nu_signature(code: &str) -> anyhow::Result<MainArgSignature> {
|
||||
let (tokens, ..) = lex(code.as_bytes(), 0, &[], &[], true);
|
||||
@@ -162,8 +162,8 @@ pub fn parse_nu_signature(code: &str) -> anyhow::Result<MainArgSignature> {
|
||||
"int" => Typ::Int,
|
||||
"float" => Typ::Float,
|
||||
"number" => Typ::Float,
|
||||
"record" => Typ::Object(vec![]),
|
||||
"table" => Typ::List(Box::new(Typ::Object(vec![]))),
|
||||
"record" => Typ::Object(ObjectType::new(None, Some(vec![]))),
|
||||
"table" => Typ::List(Box::new(Typ::Object(ObjectType::new(None, Some(vec![]))))),
|
||||
"nothing" => Typ::Unknown,
|
||||
// TODO: needs additional work on literal parsing
|
||||
// "binary" => Typ::Bytes,
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
#[cfg(test)]
|
||||
mod test {
|
||||
use serde_json::json;
|
||||
use windmill_parser::{Arg, MainArgSignature, Typ};
|
||||
use windmill_parser::{Arg, MainArgSignature, ObjectType, Typ};
|
||||
use windmill_parser_nu::parse_nu_signature;
|
||||
|
||||
#[test]
|
||||
@@ -200,7 +200,7 @@ mod test {
|
||||
Arg {
|
||||
name: "a7".into(),
|
||||
otyp: None,
|
||||
typ: Typ::Object(vec![]),
|
||||
typ: Typ::Object(ObjectType::new(None, Some(vec![]))),
|
||||
default: None,
|
||||
has_default: false,
|
||||
oidx: None
|
||||
@@ -216,7 +216,7 @@ mod test {
|
||||
Arg {
|
||||
name: "a9".into(),
|
||||
otyp: None,
|
||||
typ: Typ::List(Box::new(Typ::Object(vec![]))),
|
||||
typ: Typ::List(Box::new(Typ::Object(ObjectType::new(None, Some(vec![]))))),
|
||||
default: None,
|
||||
has_default: false,
|
||||
oidx: None
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
use serde_json::Value;
|
||||
use windmill_parser::{to_snake_case, Arg, MainArgSignature, Typ};
|
||||
use windmill_parser::{to_snake_case, Arg, MainArgSignature, ObjectType, Typ};
|
||||
|
||||
use php_parser_rs::parser::{
|
||||
self,
|
||||
@@ -18,7 +18,7 @@ fn parse_php_type(e: Type) -> Typ {
|
||||
Type::Integer(_) => Typ::Int,
|
||||
Type::String(_) => Typ::Str(None),
|
||||
Type::Array(_) => Typ::List(Box::new(Typ::Str(None))),
|
||||
Type::Object(_) => Typ::Object(vec![]),
|
||||
Type::Object(_) => Typ::Object(ObjectType::new(None, Some(vec![]))),
|
||||
Type::Named(_, name) => Typ::Resource(to_snake_case(name.to_string().as_ref())),
|
||||
_ => Typ::Unknown,
|
||||
}
|
||||
|
||||
@@ -57,27 +57,27 @@ impl AssetsFinder {
|
||||
})
|
||||
.ok_or(())?;
|
||||
|
||||
use AssetKind::*;
|
||||
let (kind, access_type, arg) = match ident.as_str() {
|
||||
"load_s3_file" => (AssetKind::S3Object, Some(R), Arg::Pos(0)),
|
||||
"load_s3_file_reader" => (AssetKind::S3Object, Some(R), Arg::Pos(0)),
|
||||
"write_s3_file" => (AssetKind::S3Object, Some(W), Arg::Pos(0)),
|
||||
"get_resource" => (AssetKind::Resource, None, Arg::Pos(0)),
|
||||
"set_resource" => (AssetKind::Resource, Some(W), Arg::Named("path")),
|
||||
"get_boto3_connection_settings" => (AssetKind::Resource, None, Arg::Pos(0)),
|
||||
"get_polars_connection_settings" => (AssetKind::Resource, None, Arg::Pos(0)),
|
||||
"get_duckdb_connection_settings" => (AssetKind::Resource, None, Arg::Pos(0)),
|
||||
"get_variable" => (AssetKind::Variable, Some(R), Arg::Pos(0)),
|
||||
"set_variable" => (AssetKind::Variable, Some(W), Arg::Pos(0)),
|
||||
"load_s3_file" => (S3Object, Some(R), Arg::Pos(0, "s3object")),
|
||||
"load_s3_file_reader" => (S3Object, Some(R), Arg::Pos(0, "s3object")),
|
||||
"write_s3_file" => (S3Object, Some(W), Arg::Pos(0, "s3object")),
|
||||
"get_resource" => (Resource, None, Arg::Pos(0, "path")),
|
||||
"set_resource" => (Resource, Some(W), Arg::Pos(0, "path")),
|
||||
"get_boto3_connection_settings" => (Resource, None, Arg::Pos(0, "s3_resource_path")),
|
||||
"get_polars_connection_settings" => (Resource, None, Arg::Pos(0, "s3_resource_path")),
|
||||
"get_duckdb_connection_settings" => (Resource, None, Arg::Pos(0, "s3_resource_path")),
|
||||
_ => return Err(()),
|
||||
};
|
||||
|
||||
let arg_val = match arg {
|
||||
Arg::Pos(i) => node.args.get(i),
|
||||
Arg::Named(name) => node
|
||||
.keywords
|
||||
.iter()
|
||||
.find(|kw| kw.arg.as_deref() == Some(name))
|
||||
.map(|kw| &kw.value),
|
||||
Arg::Pos(i, name) => node.args.get(i).or_else(|| {
|
||||
// Get arg by name
|
||||
node.keywords
|
||||
.iter()
|
||||
.find(|kw| kw.arg.as_deref() == Some(name))
|
||||
.map(|kw| &kw.value)
|
||||
}),
|
||||
};
|
||||
|
||||
match arg_val {
|
||||
@@ -93,6 +93,6 @@ impl AssetsFinder {
|
||||
}
|
||||
|
||||
enum Arg {
|
||||
Pos(usize),
|
||||
Named(&'static str),
|
||||
// Positional arguments in python can also be used by their name
|
||||
Pos(usize, &'static str),
|
||||
}
|
||||
|
||||
@@ -11,7 +11,7 @@ use std::collections::HashMap;
|
||||
use itertools::Itertools;
|
||||
|
||||
use serde_json::json;
|
||||
use windmill_parser::{json_to_typ, Arg, MainArgSignature, Typ};
|
||||
use windmill_parser::{json_to_typ, Arg, MainArgSignature, ObjectType, Typ};
|
||||
|
||||
use rustpython_parser::{
|
||||
ast::{
|
||||
@@ -226,7 +226,7 @@ fn parse_typ(id: &str) -> Typ {
|
||||
"float" => Typ::Float,
|
||||
"int" => Typ::Int,
|
||||
"bool" => Typ::Bool,
|
||||
"dict" => Typ::Object(vec![]),
|
||||
"dict" => Typ::Object(ObjectType::new(None, Some(vec![]))),
|
||||
"list" => Typ::List(Box::new(Typ::Unknown)),
|
||||
"bytes" => Typ::Bytes,
|
||||
"datetime" => Typ::Datetime,
|
||||
|
||||
@@ -14,7 +14,7 @@ use std::{
|
||||
iter::Peekable,
|
||||
str::CharIndices,
|
||||
};
|
||||
pub use windmill_parser::{Arg, MainArgSignature, Typ};
|
||||
pub use windmill_parser::{Arg, MainArgSignature, ObjectType, Typ};
|
||||
|
||||
pub const SANITIZED_ENUM_STR: &str = "__sanitized_enum__";
|
||||
pub const SANITIZED_RAW_STRING_STR: &str = "__sanitized_raw_string__";
|
||||
@@ -231,7 +231,7 @@ lazy_static::lazy_static! {
|
||||
static ref RE_ARG_BIGQUERY: Regex = Regex::new(r#"(?m)^-- @(\w+) \((\w+(?:\[\])?)\)(?: ?\= ?(.+))? *(?:\r|\n|$)"#).unwrap();
|
||||
|
||||
// -- $name (type) = default
|
||||
static ref RE_ARG_DUCKDB: Regex = Regex::new(r#"(?m)^-- \$(\w+) \((\w+)\)(?: ?\= ?(.+))? *(?:\r|\n|$)"#).unwrap();
|
||||
static ref RE_ARG_DUCKDB: Regex = Regex::new(r#"(?m)^-- \$(\w+) \(([A-Za-z0-9_\[\]]+)\)(?: ?\= ?(.+))? *(?:\r|\n|$)"#).unwrap();
|
||||
|
||||
static ref RE_ARG_SNOWFLAKE: Regex = Regex::new(r#"(?m)^-- \? (\w+) \((\w+)\)(?: ?\= ?(.+))? *(?:\r|\n|$)"#).unwrap();
|
||||
|
||||
@@ -737,7 +737,7 @@ pub fn parse_pg_typ(typ: &str) -> Typ {
|
||||
"bigint" => Typ::Int,
|
||||
"bool" | "boolean" => Typ::Bool,
|
||||
"char" | "character" => Typ::Str(None),
|
||||
"json" | "jsonb" => Typ::Object(vec![]),
|
||||
"json" | "jsonb" => Typ::Object(ObjectType::new(None, Some(vec![]))),
|
||||
"smallint" | "int2" => Typ::Int,
|
||||
"smallserial" | "serial2" => Typ::Int,
|
||||
"serial" | "serial4" => Typ::Int,
|
||||
@@ -769,7 +769,7 @@ pub fn parse_bigquery_typ(typ: &str) -> Typ {
|
||||
match typ {
|
||||
"string" => Typ::Str(None),
|
||||
"bytes" => Typ::Bytes,
|
||||
"json" => Typ::Object(vec![]),
|
||||
"json" => Typ::Object(ObjectType::new(None, Some(vec![]))),
|
||||
"timestamp" | "date" | "time" | "datetime" => Typ::Datetime,
|
||||
"integer" | "int64" => Typ::Int,
|
||||
"float" | "float64" | "numeric" | "bignumeric" => Typ::Float,
|
||||
|
||||
@@ -84,8 +84,6 @@ impl AssetsFinder {
|
||||
"denoS3LightClientSettings" => (AssetKind::Resource, None, 0),
|
||||
"duckdbConnectionSettings" => (AssetKind::Resource, None, 0),
|
||||
"polarsConnectionSettings" => (AssetKind::Resource, None, 0),
|
||||
"getVariable" => (AssetKind::Variable, Some(R), 0),
|
||||
"setVariable" => (AssetKind::Variable, Some(W), 0),
|
||||
_ => return Err(()),
|
||||
};
|
||||
|
||||
|
||||
@@ -7,19 +7,20 @@
|
||||
*/
|
||||
// use deno_core::{serde_v8, v8, JsRuntime, RuntimeOptions};
|
||||
use serde_json::Value;
|
||||
use std::collections::HashSet;
|
||||
use std::collections::{HashMap, HashSet};
|
||||
use swc_ecma_visit::{noop_visit_type, Visit, VisitWith};
|
||||
use windmill_parser::{
|
||||
json_to_typ, to_snake_case, Arg, MainArgSignature, ObjectProperty, OneOfVariant, Typ,
|
||||
json_to_typ, to_snake_case, Arg, MainArgSignature, ObjectProperty, ObjectType, OneOfVariant,
|
||||
Typ,
|
||||
};
|
||||
|
||||
use swc_common::{sync::Lrc, FileName, SourceMap, SourceMapper, Span, Spanned};
|
||||
use swc_ecma_ast::{
|
||||
ArrayLit, AssignPat, BigInt, BindingIdent, Bool, Decl, ExportDecl, Expr, FnDecl, Ident,
|
||||
IdentName, Lit, MemberExpr, MemberProp, ModuleDecl, ModuleItem, Number, ObjectLit, ObjectPat,
|
||||
Param, Pat, Str, TsArrayType, TsEntityName, TsKeywordType, TsKeywordTypeKind, TsLit, TsLitType,
|
||||
TsOptionalType, TsParenthesizedType, TsPropertySignature, TsType, TsTypeAnn, TsTypeElement,
|
||||
TsTypeLit, TsTypeRef, TsUnionOrIntersectionType, TsUnionType,
|
||||
ArrayLit, AssignPat, BigInt, BindingIdent, Bool, Decl, ExportDecl, Expr, Ident, IdentName, Lit,
|
||||
MemberExpr, MemberProp, ModuleDecl, ModuleItem, Number, ObjectLit, ObjectPat, Param, Pat, Stmt,
|
||||
Str, TsArrayType, TsEntityName, TsInterfaceDecl, TsKeywordType, TsKeywordTypeKind, TsLit,
|
||||
TsLitType, TsOptionalType, TsParenthesizedType, TsPropertySignature, TsType, TsTypeAliasDecl,
|
||||
TsTypeAnn, TsTypeElement, TsTypeLit, TsTypeRef, TsUnionOrIntersectionType, TsUnionType,
|
||||
};
|
||||
use swc_ecma_parser::{lexer::Lexer, EsSyntax, Parser, StringInput, Syntax, TsSyntax};
|
||||
|
||||
@@ -32,6 +33,19 @@ struct ImportsFinder {
|
||||
skip_type_only: bool,
|
||||
}
|
||||
|
||||
impl ImportsFinder {
|
||||
fn process_raw(&mut self, raw: Option<String>) {
|
||||
if let Some(ref s) = raw {
|
||||
let s = s.to_string();
|
||||
if s.starts_with("'") && s.ends_with("'") {
|
||||
self.imports.insert(s[1..s.len() - 1].to_string());
|
||||
} else if s.starts_with("\"") && s.ends_with("\"") {
|
||||
self.imports.insert(s[1..s.len() - 1].to_string());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Visit for ImportsFinder {
|
||||
noop_visit_type!();
|
||||
|
||||
@@ -59,14 +73,47 @@ impl Visit for ImportsFinder {
|
||||
}
|
||||
}
|
||||
}
|
||||
if let Some(ref s) = n.src.raw {
|
||||
let s = s.to_string();
|
||||
if s.starts_with("'") && s.ends_with("'") {
|
||||
self.imports.insert(s[1..s.len() - 1].to_string());
|
||||
} else if s.starts_with("\"") && s.ends_with("\"") {
|
||||
self.imports.insert(s[1..s.len() - 1].to_string());
|
||||
self.process_raw(n.src.raw.as_ref().map(|x| x.to_string()));
|
||||
}
|
||||
|
||||
fn visit_export_all(&mut self, node: &swc_ecma_ast::ExportAll) {
|
||||
if !self.skip_type_only || node.type_only {
|
||||
return;
|
||||
}
|
||||
|
||||
self.process_raw(node.src.raw.as_ref().map(|x| x.to_string()));
|
||||
}
|
||||
fn visit_named_export(&mut self, node: &swc_ecma_ast::NamedExport) {
|
||||
if node.src.is_none() || !self.skip_type_only || node.type_only {
|
||||
return;
|
||||
}
|
||||
if node.specifiers.len() > 0 {
|
||||
let mut is_type_only = true;
|
||||
for specifier in node.specifiers.iter() {
|
||||
match specifier {
|
||||
swc_ecma_ast::ExportSpecifier::Named(swc_ecma_ast::ExportNamedSpecifier {
|
||||
is_type_only,
|
||||
..
|
||||
}) if *is_type_only => (),
|
||||
_ => {
|
||||
is_type_only = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if is_type_only {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
self.process_raw(
|
||||
node.src
|
||||
.as_ref()
|
||||
.unwrap()
|
||||
.raw
|
||||
.as_ref()
|
||||
.map(|x| x.to_string()),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -159,6 +206,11 @@ pub fn parse_expr_for_ids(code: &str) -> anyhow::Result<Vec<(String, String)>> {
|
||||
Ok(visitor.idents.into_iter().collect())
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub enum TypeDecl {
|
||||
Interface(TsInterfaceDecl),
|
||||
Alias(TsTypeAliasDecl),
|
||||
}
|
||||
pub mod asset_parser;
|
||||
pub use asset_parser::parse_assets;
|
||||
|
||||
@@ -168,7 +220,7 @@ pub fn parse_deno_signature(
|
||||
code: &str,
|
||||
skip_dflt: bool,
|
||||
skip_params: bool,
|
||||
main_override: Option<String>,
|
||||
entrypoint_override: Option<String>,
|
||||
) -> anyhow::Result<MainArgSignature> {
|
||||
let cm: Lrc<SourceMap> = Default::default();
|
||||
let fm = cm.new_source_file(FileName::Custom("main.ts".into()).into(), code.into());
|
||||
@@ -188,6 +240,9 @@ pub fn parse_deno_signature(
|
||||
err_s += &e.into_kind().msg().to_string();
|
||||
}
|
||||
|
||||
let mut has_preprocessor = false;
|
||||
let mut entrypoint_params = None;
|
||||
|
||||
let ast = parser
|
||||
.parse_module()
|
||||
.map_err(|e| {
|
||||
@@ -195,35 +250,71 @@ pub fn parse_deno_signature(
|
||||
})?
|
||||
.body;
|
||||
|
||||
let has_preprocessor = ast.iter().any(|x| match x {
|
||||
ModuleItem::ModuleDecl(ModuleDecl::ExportDecl(ExportDecl {
|
||||
decl: Decl::Fn(FnDecl { ident: Ident { sym, .. }, .. }),
|
||||
..
|
||||
})) => &sym.to_string() == "preprocessor",
|
||||
_ => false,
|
||||
});
|
||||
let entrypoint_function = entrypoint_override.as_deref().unwrap_or("main");
|
||||
|
||||
let main_name = main_override.unwrap_or("main".to_string());
|
||||
let params = ast.into_iter().find_map(|x| match x {
|
||||
ModuleItem::ModuleDecl(ModuleDecl::ExportDecl(ExportDecl {
|
||||
decl: Decl::Fn(FnDecl { ident: Ident { sym, .. }, function, .. }),
|
||||
..
|
||||
})) if &sym.to_string() == &main_name => Some(function.params),
|
||||
_ => None,
|
||||
});
|
||||
let mut symbol_table: HashMap<String, TypeDecl> = HashMap::new();
|
||||
|
||||
for item in ast {
|
||||
if let ModuleItem::ModuleDecl(ModuleDecl::ExportDecl(ExportDecl { decl, .. }))
|
||||
| ModuleItem::Stmt(Stmt::Decl(decl)) = item
|
||||
{
|
||||
match decl {
|
||||
Decl::TsInterface(mut iface) => match symbol_table.get_mut(iface.id.sym.as_str()) {
|
||||
Some(TypeDecl::Interface(interface)) => {
|
||||
interface.body.body.append(&mut iface.body.body);
|
||||
}
|
||||
None => {
|
||||
symbol_table.insert(
|
||||
to_snake_case(iface.id.sym.as_str()),
|
||||
TypeDecl::Interface(*iface),
|
||||
);
|
||||
}
|
||||
_ => {}
|
||||
},
|
||||
Decl::TsTypeAlias(alias) => {
|
||||
symbol_table.insert(
|
||||
to_snake_case(alias.id.sym.as_str()),
|
||||
TypeDecl::Alias(*alias),
|
||||
);
|
||||
}
|
||||
Decl::Fn(fn_decl) => {
|
||||
let name = fn_decl.ident.sym.to_string();
|
||||
if name == "preprocessor" {
|
||||
has_preprocessor = true;
|
||||
}
|
||||
if name == entrypoint_function {
|
||||
entrypoint_params = Some(fn_decl.function.params.clone());
|
||||
}
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
let mut c: u16 = 0;
|
||||
let no_main_func = params.is_none();
|
||||
|
||||
let no_main_func = entrypoint_params.is_none();
|
||||
let mut type_resolver = HashMap::new();
|
||||
let r = MainArgSignature {
|
||||
star_args: false,
|
||||
star_kwargs: false,
|
||||
args: if skip_params {
|
||||
vec![]
|
||||
} else {
|
||||
params
|
||||
.map(|x| {
|
||||
x.into_iter()
|
||||
.map(|x| parse_param(x, &cm, skip_dflt, &mut c))
|
||||
entrypoint_params
|
||||
.map(|param| {
|
||||
param
|
||||
.into_iter()
|
||||
.map(|param| {
|
||||
parse_param(
|
||||
&symbol_table,
|
||||
&mut type_resolver,
|
||||
param,
|
||||
&cm,
|
||||
skip_dflt,
|
||||
&mut c,
|
||||
)
|
||||
})
|
||||
.collect::<anyhow::Result<Vec<Arg>>>()
|
||||
})
|
||||
.transpose()?
|
||||
@@ -236,14 +327,16 @@ pub fn parse_deno_signature(
|
||||
}
|
||||
|
||||
fn parse_param(
|
||||
x: Param,
|
||||
symbol_table: &HashMap<String, TypeDecl>,
|
||||
type_resolver: &mut HashMap<String, (Typ, bool)>,
|
||||
param: Param,
|
||||
cm: &Lrc<SourceMap>,
|
||||
skip_dflt: bool,
|
||||
counter: &mut u16,
|
||||
) -> anyhow::Result<Arg> {
|
||||
let r = match x.pat {
|
||||
let r = match param.pat {
|
||||
Pat::Ident(ident) => {
|
||||
let (name, typ, nullable) = binding_ident_to_arg(&ident);
|
||||
let (name, typ, nullable) = binding_ident_to_arg(symbol_table, type_resolver, &ident);
|
||||
Ok(Arg {
|
||||
otyp: None,
|
||||
name,
|
||||
@@ -256,9 +349,9 @@ fn parse_param(
|
||||
// Pat::Object(ObjectPat { ... }) = todo!()
|
||||
Pat::Assign(AssignPat { left, right, .. }) => {
|
||||
let (name, mut typ, _nullable) = match *left {
|
||||
Pat::Ident(ident) => binding_ident_to_arg(&ident),
|
||||
Pat::Ident(ident) => binding_ident_to_arg(symbol_table, type_resolver, &ident),
|
||||
Pat::Object(ObjectPat { type_ann, .. }) => {
|
||||
let (typ, nullable) = eval_type_ann(&type_ann);
|
||||
let (typ, nullable) = eval_type_ann(symbol_table, type_resolver, &type_ann);
|
||||
*counter += 1;
|
||||
let name = format!("anon{}", counter);
|
||||
(name, typ, nullable)
|
||||
@@ -300,16 +393,16 @@ fn parse_param(
|
||||
Ok(Arg { otyp: None, name, typ, default: dflt, has_default: true, oidx: None })
|
||||
}
|
||||
Pat::Object(ObjectPat { type_ann, .. }) => {
|
||||
let (typ, nullable) = eval_type_ann(&type_ann);
|
||||
let (typ, nullable) = eval_type_ann(symbol_table, type_resolver, &type_ann);
|
||||
*counter += 1;
|
||||
let name = format!("anon{}", counter);
|
||||
Ok(Arg { otyp: None, name, typ, default: None, has_default: nullable, oidx: None })
|
||||
}
|
||||
_ => Err(anyhow::anyhow!(
|
||||
"parameter syntax unsupported: `{}`: {:#?}",
|
||||
cm.span_to_snippet(x.span())
|
||||
.unwrap_or_else(|_| cm.span_to_string(x.span())),
|
||||
x.pat
|
||||
cm.span_to_snippet(param.span())
|
||||
.unwrap_or_else(|_| cm.span_to_string(param.span())),
|
||||
param.pat
|
||||
)),
|
||||
};
|
||||
r
|
||||
@@ -328,14 +421,22 @@ fn eval_span(span: Span, cm: &Lrc<SourceMap>) -> Option<Value> {
|
||||
}
|
||||
}
|
||||
|
||||
fn eval_type_ann(type_ann: &Option<Box<TsTypeAnn>>) -> (Typ, bool) {
|
||||
fn eval_type_ann(
|
||||
symbol_table: &HashMap<String, TypeDecl>,
|
||||
type_resolver: &mut HashMap<String, (Typ, bool)>,
|
||||
type_ann: &Option<Box<TsTypeAnn>>,
|
||||
) -> (Typ, bool) {
|
||||
return type_ann
|
||||
.as_ref()
|
||||
.map(|x| tstype_to_typ(&*x.type_ann))
|
||||
.map(|x| tstype_to_typ(symbol_table, type_resolver, &*x.type_ann, true))
|
||||
.unwrap_or((Typ::Unknown, false));
|
||||
}
|
||||
fn binding_ident_to_arg(BindingIdent { id, type_ann }: &BindingIdent) -> (String, Typ, bool) {
|
||||
let (typ, nullable) = eval_type_ann(type_ann);
|
||||
fn binding_ident_to_arg(
|
||||
symbol_table: &HashMap<String, TypeDecl>,
|
||||
type_resolver: &mut HashMap<String, (Typ, bool)>,
|
||||
BindingIdent { id, type_ann }: &BindingIdent,
|
||||
) -> (String, Typ, bool) {
|
||||
let (typ, nullable) = eval_type_ann(symbol_table, type_resolver, type_ann);
|
||||
(id.sym.to_string(), typ, nullable)
|
||||
}
|
||||
|
||||
@@ -365,11 +466,193 @@ pub fn remove_pinned_imports(code: &str) -> anyhow::Result<String> {
|
||||
Ok(content)
|
||||
}
|
||||
|
||||
fn tstype_to_typ(ts_type: &TsType) -> (Typ, bool) {
|
||||
fn resolve_type_ref(type_resolver: &HashMap<String, (Typ, bool)>, typ: &mut Typ) {
|
||||
let mut visited = std::collections::HashSet::new();
|
||||
resolve_type_ref_with_visited(type_resolver, typ, &mut visited);
|
||||
}
|
||||
|
||||
fn resolve_type_ref_with_visited(
|
||||
type_resolver: &HashMap<String, (Typ, bool)>,
|
||||
typ: &mut Typ,
|
||||
visited: &mut std::collections::HashSet<String>,
|
||||
) {
|
||||
match typ {
|
||||
Typ::Object(ObjectType { props: Some(obj), .. }) => {
|
||||
for property in obj.iter_mut() {
|
||||
resolve_type_ref_with_visited(type_resolver, &mut property.typ, visited);
|
||||
}
|
||||
}
|
||||
Typ::List(list) => resolve_type_ref_with_visited(type_resolver, list, visited),
|
||||
Typ::Object(ObjectType { name: Some(name), props: None }) => {
|
||||
if visited.contains(name) {
|
||||
return;
|
||||
}
|
||||
let maybe_resolved_type = type_resolver
|
||||
.get(name)
|
||||
.map(|rs_typ| {
|
||||
let mut typ = rs_typ.0.clone();
|
||||
visited.insert(name.clone());
|
||||
resolve_type_ref_with_visited(type_resolver, &mut typ, visited);
|
||||
visited.remove(name);
|
||||
typ
|
||||
})
|
||||
.unwrap_or(Typ::Object(ObjectType::new(Some(name.to_owned()), None)));
|
||||
|
||||
*typ = maybe_resolved_type;
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
|
||||
fn resolve_interface(
|
||||
iface: &TsInterfaceDecl,
|
||||
symbol_table: &HashMap<String, TypeDecl>,
|
||||
type_resolver: &mut HashMap<String, (Typ, bool)>,
|
||||
) -> Vec<ObjectProperty> {
|
||||
let mut properties = vec![];
|
||||
|
||||
for ext in &iface.extends {
|
||||
// If the current interface extends other interfaces,
|
||||
// retrieve their properties first and add them to the current interface's object definition.
|
||||
if let Expr::Ident(Ident { sym, .. }) = &*ext.expr {
|
||||
if let Some(TypeDecl::Interface(parent_iface)) =
|
||||
symbol_table.get(&to_snake_case(sym.as_str()))
|
||||
{
|
||||
properties.extend(resolve_interface(parent_iface, symbol_table, type_resolver));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for member in &iface.body.body {
|
||||
if let TsTypeElement::TsPropertySignature(sig) = member {
|
||||
if let Expr::Ident(Ident { sym, .. }) = &*sig.key {
|
||||
let typ = sig
|
||||
.type_ann
|
||||
.as_ref()
|
||||
.map(|ta| {
|
||||
Box::new(tstype_to_typ(symbol_table, type_resolver, &ta.type_ann, false).0)
|
||||
})
|
||||
.unwrap_or(Box::new(Typ::Unknown));
|
||||
|
||||
properties.push(ObjectProperty { key: sym.to_string(), typ });
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
properties
|
||||
}
|
||||
|
||||
fn resolve_type_alias(
|
||||
alias: &TsTypeAliasDecl,
|
||||
symbol_table: &HashMap<String, TypeDecl>,
|
||||
type_resolver: &mut HashMap<String, (Typ, bool)>,
|
||||
top_level_call: bool,
|
||||
) -> (Typ, bool) {
|
||||
tstype_to_typ(symbol_table, type_resolver, &alias.type_ann, top_level_call)
|
||||
}
|
||||
|
||||
fn resolve_ts_interface_and_type_alias(
|
||||
type_name: &str,
|
||||
symbol_table: &HashMap<String, TypeDecl>,
|
||||
type_resolver: &mut HashMap<String, (Typ, bool)>,
|
||||
top_level_call: bool,
|
||||
) -> Option<(Typ, bool)> {
|
||||
let Some(type_declaration) = symbol_table.get(type_name) else {
|
||||
return None;
|
||||
};
|
||||
|
||||
if let Some(resolved_type) = type_resolver.get_mut(type_name) {
|
||||
return Some(resolved_type.to_owned());
|
||||
}
|
||||
|
||||
type_resolver.insert(
|
||||
type_name.to_owned(),
|
||||
(
|
||||
Typ::Object(ObjectType::new(Some(type_name.to_owned()), None)),
|
||||
false,
|
||||
),
|
||||
);
|
||||
|
||||
let mut resolved_type = match type_declaration {
|
||||
TypeDecl::Alias(alias) => {
|
||||
resolve_type_alias(alias, symbol_table, type_resolver, top_level_call)
|
||||
}
|
||||
TypeDecl::Interface(iface) => (
|
||||
Typ::Object(ObjectType::new(
|
||||
Some(to_snake_case(&type_name)),
|
||||
Some(resolve_interface(iface, symbol_table, type_resolver)),
|
||||
)),
|
||||
false,
|
||||
),
|
||||
};
|
||||
|
||||
fn update_name(typ: &mut Typ, type_name: &str) {
|
||||
match typ {
|
||||
// OBJECT TYPES:
|
||||
// Normally, when you declare something like:
|
||||
// type Postgresql = object
|
||||
// it will initially resolve to:
|
||||
// Typ::Object(ObjectType { name: None, .. })
|
||||
//
|
||||
// If the object has no name (name == None), we assign `type_name`
|
||||
// so it becomes:
|
||||
// Typ::Object(ObjectType { name: Some("postgresql"), .. })
|
||||
Typ::Object(ObjectType { name, .. }) if name.is_none() => {
|
||||
*name = Some(type_name.to_owned());
|
||||
}
|
||||
|
||||
// RESOURCE TYPES:
|
||||
// In some cases, when a type alias points to something unresolved:
|
||||
// type Postgresql = Foo
|
||||
// might initially resolve to:
|
||||
// Typ::Resource("Foo")
|
||||
//
|
||||
// This ensures backwards compatibility by updating that resource
|
||||
// name to the alias name, so it becomes:
|
||||
// Typ::Resource("postgresql")
|
||||
Typ::Resource(name) if name != type_name => {
|
||||
*name = type_name.to_owned();
|
||||
}
|
||||
|
||||
// LIST TYPES:
|
||||
// For lists, e.g. `type PostgresqlList = [object]`,
|
||||
// we recursively call `update_name` on the inner type,
|
||||
// so the same renaming logic applies inside the list.
|
||||
Typ::List(list) => {
|
||||
update_name(list, type_name);
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
|
||||
update_name(&mut resolved_type.0, type_name);
|
||||
|
||||
type_resolver.insert(type_name.to_owned(), resolved_type.clone());
|
||||
|
||||
// `top_level_call` indicates whether the current invocation of the function
|
||||
// is at the topmost level (e.g., the immediate parameters of the main function).
|
||||
// When true:
|
||||
// - Type references within object properties (e.g., nested interfaces) are recursively resolved
|
||||
// up to a default depth to inline and fully materialize their structure.
|
||||
if top_level_call {
|
||||
resolve_type_ref(type_resolver, &mut resolved_type.0);
|
||||
}
|
||||
|
||||
Some(resolved_type)
|
||||
}
|
||||
|
||||
fn tstype_to_typ(
|
||||
symbol_table: &HashMap<String, TypeDecl>,
|
||||
type_resolver: &mut HashMap<String, (Typ, bool)>,
|
||||
ts_type: &TsType,
|
||||
top_level_call: bool,
|
||||
) -> (Typ, bool) {
|
||||
match ts_type {
|
||||
TsType::TsKeywordType(t) => (
|
||||
match t.kind {
|
||||
TsKeywordTypeKind::TsObjectKeyword => Typ::Object(vec![]),
|
||||
TsKeywordTypeKind::TsObjectKeyword => {
|
||||
Typ::Object(ObjectType::new(None, Some(vec![])))
|
||||
}
|
||||
TsKeywordTypeKind::TsBooleanKeyword => Typ::Bool,
|
||||
TsKeywordTypeKind::TsBigIntKeyword => Typ::Int,
|
||||
TsKeywordTypeKind::TsNumberKeyword => Typ::Float,
|
||||
@@ -391,7 +674,17 @@ fn tstype_to_typ(ts_type: &TsType) -> (Typ, bool) {
|
||||
key: sym.to_string(),
|
||||
typ: type_ann
|
||||
.as_ref()
|
||||
.map(|typ| Box::new(tstype_to_typ(&*typ.type_ann).0))
|
||||
.map(|typ| {
|
||||
Box::new(
|
||||
tstype_to_typ(
|
||||
symbol_table,
|
||||
type_resolver,
|
||||
&*typ.type_ann,
|
||||
top_level_call,
|
||||
)
|
||||
.0,
|
||||
)
|
||||
})
|
||||
.unwrap_or(Box::new(Typ::Unknown)),
|
||||
}),
|
||||
_ => None,
|
||||
@@ -399,21 +692,25 @@ fn tstype_to_typ(ts_type: &TsType) -> (Typ, bool) {
|
||||
_ => None,
|
||||
})
|
||||
.collect();
|
||||
(Typ::Object(properties), false)
|
||||
(Typ::Object(ObjectType::new(None, Some(properties))), false)
|
||||
}
|
||||
TsType::TsParenthesizedType(TsParenthesizedType { type_ann, .. }) => {
|
||||
tstype_to_typ(type_ann)
|
||||
tstype_to_typ(symbol_table, type_resolver, type_ann, top_level_call)
|
||||
}
|
||||
// TODO: we can do better here and extract the inner type of array
|
||||
TsType::TsArrayType(TsArrayType { elem_type, .. }) => {
|
||||
(Typ::List(Box::new(tstype_to_typ(&**elem_type).0)), false)
|
||||
}
|
||||
TsType::TsArrayType(TsArrayType { elem_type, .. }) => (
|
||||
Typ::List(Box::new(
|
||||
tstype_to_typ(symbol_table, type_resolver, &**elem_type, top_level_call).0,
|
||||
)),
|
||||
false,
|
||||
),
|
||||
TsType::TsLitType(TsLitType { lit: TsLit::Str(Str { value, .. }), .. }) => {
|
||||
(Typ::Str(Some(vec![value.to_string()])), false)
|
||||
}
|
||||
TsType::TsOptionalType(TsOptionalType { type_ann, .. }) => {
|
||||
(tstype_to_typ(type_ann).0, true)
|
||||
}
|
||||
TsType::TsOptionalType(TsOptionalType { type_ann, .. }) => (
|
||||
tstype_to_typ(symbol_table, type_resolver, type_ann, top_level_call).0,
|
||||
true,
|
||||
),
|
||||
TsType::TsUnionOrIntersectionType(TsUnionOrIntersectionType::TsUnionType(
|
||||
TsUnionType { types, .. },
|
||||
)) => {
|
||||
@@ -438,11 +735,18 @@ fn tstype_to_typ(ts_type: &TsType) -> (Typ, bool) {
|
||||
} else {
|
||||
0
|
||||
};
|
||||
(tstype_to_typ(&types[other_p]).0, true)
|
||||
(
|
||||
tstype_to_typ(symbol_table, type_resolver, &types[other_p], top_level_call).0,
|
||||
true,
|
||||
)
|
||||
} else {
|
||||
if types.len() > 1 {
|
||||
let one_of_values: Vec<OneOfVariant> =
|
||||
types.into_iter().map_while(parse_one_of_type).collect();
|
||||
let one_of_values: Vec<OneOfVariant> = types
|
||||
.into_iter()
|
||||
.map_while(|t| {
|
||||
parse_one_of_type(symbol_table, type_resolver, t, top_level_call)
|
||||
})
|
||||
.collect();
|
||||
|
||||
if one_of_values.len() == types.len() {
|
||||
return (Typ::OneOf(one_of_values), false);
|
||||
@@ -481,6 +785,7 @@ fn tstype_to_typ(ts_type: &TsType) -> (Typ, bool) {
|
||||
TsEntityName::Ident(Ident { sym, .. }) => sym,
|
||||
TsEntityName::TsQualifiedName(p) => &*p.right.sym,
|
||||
};
|
||||
|
||||
match sym.to_string().as_str() {
|
||||
"Resource" => (
|
||||
Typ::Resource(
|
||||
@@ -501,24 +806,68 @@ fn tstype_to_typ(ts_type: &TsType) -> (Typ, bool) {
|
||||
"Base64" => (Typ::Bytes, false),
|
||||
"Email" => (Typ::Email, false),
|
||||
"Sql" => (Typ::Sql, false),
|
||||
x @ _ if x.starts_with("DynSelect_") => (
|
||||
Typ::DynSelect(x.strip_prefix("DynSelect_").unwrap().to_string()),
|
||||
symbol @ _ if symbol.starts_with("DynSelect_") => (
|
||||
Typ::DynSelect(symbol.strip_prefix("DynSelect_").unwrap().to_string()),
|
||||
false,
|
||||
),
|
||||
x @ _ => (Typ::Resource(to_snake_case(x)), false),
|
||||
symbol @ _ => {
|
||||
let symbol = to_snake_case(symbol);
|
||||
resolve_ts_interface_and_type_alias(
|
||||
&symbol,
|
||||
symbol_table,
|
||||
type_resolver,
|
||||
top_level_call,
|
||||
)
|
||||
.unwrap_or_else(|| (Typ::Resource(symbol), false))
|
||||
}
|
||||
}
|
||||
}
|
||||
_ => (Typ::Unknown, false),
|
||||
}
|
||||
}
|
||||
|
||||
fn parse_one_of_type(x: &Box<TsType>) -> Option<OneOfVariant> {
|
||||
fn parse_one_of_type(
|
||||
symbol_table: &HashMap<String, TypeDecl>,
|
||||
type_resolver: &mut HashMap<String, (Typ, bool)>,
|
||||
x: &Box<TsType>,
|
||||
top_level_call: bool,
|
||||
) -> Option<OneOfVariant> {
|
||||
match &**x {
|
||||
TsType::TsTypeLit(TsTypeLit { members, .. }) => {
|
||||
let label = one_of_label(members)?;
|
||||
let properties = one_of_properties(members);
|
||||
let properties =
|
||||
one_of_properties(symbol_table, type_resolver, members, top_level_call);
|
||||
Some(OneOfVariant { label, properties })
|
||||
}
|
||||
TsType::TsTypeRef(TsTypeRef { type_name, .. }) => {
|
||||
let label = type_name.as_ident()?.sym.to_string();
|
||||
match label.as_str() {
|
||||
symbol
|
||||
if ["Resource", "Date", "Base64", "Email", "Sql"]
|
||||
.iter()
|
||||
.any(|s| *s == symbol)
|
||||
|| symbol.starts_with("DynSelect_") =>
|
||||
{
|
||||
return None
|
||||
}
|
||||
symbol @ _ => {
|
||||
let Typ::Object(ObjectType { props: Some(properties), .. }) =
|
||||
resolve_ts_interface_and_type_alias(
|
||||
symbol,
|
||||
symbol_table,
|
||||
type_resolver,
|
||||
top_level_call,
|
||||
)
|
||||
.unwrap_or_else(|| (Typ::Resource(to_snake_case(symbol)), false))
|
||||
.0
|
||||
else {
|
||||
return None;
|
||||
};
|
||||
|
||||
Some(OneOfVariant { label, properties })
|
||||
}
|
||||
}
|
||||
}
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
@@ -550,7 +899,12 @@ fn one_of_label(members: &Vec<TsTypeElement>) -> Option<String> {
|
||||
})
|
||||
}
|
||||
|
||||
fn one_of_properties(members: &Vec<TsTypeElement>) -> Vec<ObjectProperty> {
|
||||
fn one_of_properties(
|
||||
symbol_table: &HashMap<String, TypeDecl>,
|
||||
type_resolver: &mut HashMap<String, (Typ, bool)>,
|
||||
members: &Vec<TsTypeElement>,
|
||||
top_level_call: bool,
|
||||
) -> Vec<ObjectProperty> {
|
||||
members
|
||||
.iter()
|
||||
.filter_map(|x| {
|
||||
@@ -564,10 +918,12 @@ fn one_of_properties(members: &Vec<TsTypeElement>) -> Vec<ObjectProperty> {
|
||||
};
|
||||
let typ = type_ann
|
||||
.as_ref()
|
||||
.map(|typ| Box::new(tstype_to_typ(&*typ.type_ann).0))
|
||||
.unwrap_or(Box::new(Typ::Unknown));
|
||||
.map(|typ| {
|
||||
tstype_to_typ(symbol_table, type_resolver, &*typ.type_ann, top_level_call).0
|
||||
})
|
||||
.unwrap_or(Typ::Unknown);
|
||||
|
||||
Some(ObjectProperty { key: sym.to_string(), typ })
|
||||
Some(ObjectProperty { key: sym.to_string(), typ: Box::new(typ) })
|
||||
})
|
||||
.collect()
|
||||
}
|
||||
|
||||
@@ -1,8 +1,11 @@
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use windmill_parser_ts::parse_expr_for_imports;
|
||||
use serde_json::json;
|
||||
use windmill_parser::{Arg, MainArgSignature, ObjectProperty, ObjectType, Typ};
|
||||
use windmill_parser_ts::{parse_deno_signature, parse_expr_for_imports};
|
||||
|
||||
#[test]
|
||||
fn test_imports() {
|
||||
fn test_imports_basic() {
|
||||
let code = r#"
|
||||
import { foo } from "bar";
|
||||
import type { foo } from "bar2";
|
||||
@@ -12,8 +15,645 @@ mod tests {
|
||||
import { type foo, type bar } from "bar4";
|
||||
import * as foo from "bar5";
|
||||
import foo from "bar6";
|
||||
export * from "bar8";
|
||||
export { foo } from "bar9";
|
||||
export { type foo } from "bar10";
|
||||
export { foo, type bar } from "bar11";
|
||||
export { type foo, type bar } from "bar12";
|
||||
export { type foo, bar } from "bar13";
|
||||
export { bar, type foo } from "bar14";
|
||||
export type { foo } from "bar15";
|
||||
"#;
|
||||
let imports = parse_expr_for_imports(code, true).unwrap();
|
||||
assert_eq!(imports, vec!["bar", "bar3", "bar5", "bar6", "bar7"]);
|
||||
assert_eq!(
|
||||
imports,
|
||||
["bar", "bar11", "bar13", "bar14", "bar3", "bar5", "bar6", "bar7", "bar8", "bar9"]
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_parse_empty_main_signature() {
|
||||
let code = r#"
|
||||
export async function main() {
|
||||
return "Hello World";
|
||||
}
|
||||
"#;
|
||||
let sig = parse_deno_signature(code, false, false, None).unwrap();
|
||||
assert_eq!(
|
||||
sig,
|
||||
MainArgSignature {
|
||||
star_args: false,
|
||||
star_kwargs: false,
|
||||
args: vec![],
|
||||
no_main_func: Some(false),
|
||||
has_preprocessor: Some(false),
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_parse_basic_types() {
|
||||
let code = r#"
|
||||
export async function main(
|
||||
str_param: string,
|
||||
num_param: number,
|
||||
bool_param: boolean,
|
||||
any_param: any
|
||||
) {
|
||||
return { str_param, num_param, bool_param, any_param };
|
||||
}
|
||||
"#;
|
||||
let sig = parse_deno_signature(code, false, false, None).unwrap();
|
||||
assert_eq!(
|
||||
sig,
|
||||
MainArgSignature {
|
||||
star_args: false,
|
||||
star_kwargs: false,
|
||||
args: vec![
|
||||
Arg {
|
||||
name: "str_param".to_string(),
|
||||
otyp: None,
|
||||
typ: Typ::Str(None),
|
||||
default: None,
|
||||
has_default: false,
|
||||
oidx: None,
|
||||
},
|
||||
Arg {
|
||||
name: "num_param".to_string(),
|
||||
otyp: None,
|
||||
typ: Typ::Float,
|
||||
default: None,
|
||||
has_default: false,
|
||||
oidx: None,
|
||||
},
|
||||
Arg {
|
||||
name: "bool_param".to_string(),
|
||||
otyp: None,
|
||||
typ: Typ::Bool,
|
||||
default: None,
|
||||
has_default: false,
|
||||
oidx: None,
|
||||
},
|
||||
Arg {
|
||||
name: "any_param".to_string(),
|
||||
otyp: None,
|
||||
typ: Typ::Unknown,
|
||||
default: None,
|
||||
has_default: false,
|
||||
oidx: None,
|
||||
},
|
||||
],
|
||||
no_main_func: Some(false),
|
||||
has_preprocessor: Some(false),
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_parse_with_defaults() {
|
||||
let code = r#"
|
||||
export async function main(
|
||||
name: string = "World",
|
||||
count: number = 42,
|
||||
enabled: boolean = true
|
||||
) {
|
||||
return { name, count, enabled };
|
||||
}
|
||||
"#;
|
||||
let sig = parse_deno_signature(code, false, false, None).unwrap();
|
||||
assert_eq!(
|
||||
sig,
|
||||
MainArgSignature {
|
||||
star_args: false,
|
||||
star_kwargs: false,
|
||||
args: vec![
|
||||
Arg {
|
||||
name: "name".to_string(),
|
||||
otyp: None,
|
||||
typ: Typ::Str(None),
|
||||
default: Some(json!("World")),
|
||||
has_default: true,
|
||||
oidx: None,
|
||||
},
|
||||
Arg {
|
||||
name: "count".to_string(),
|
||||
otyp: None,
|
||||
typ: Typ::Float,
|
||||
default: Some(json!(42)),
|
||||
has_default: true,
|
||||
oidx: None,
|
||||
},
|
||||
Arg {
|
||||
name: "enabled".to_string(),
|
||||
otyp: None,
|
||||
typ: Typ::Bool,
|
||||
default: Some(json!(true)),
|
||||
has_default: true,
|
||||
oidx: None,
|
||||
},
|
||||
],
|
||||
no_main_func: Some(false),
|
||||
has_preprocessor: Some(false),
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_parse_array_types() {
|
||||
let code = r#"
|
||||
export async function main(
|
||||
strings: string[],
|
||||
numbers: number[],
|
||||
items: any[]
|
||||
) {
|
||||
return { strings, numbers, items };
|
||||
}
|
||||
"#;
|
||||
let sig = parse_deno_signature(code, false, false, None).unwrap();
|
||||
assert_eq!(
|
||||
sig,
|
||||
MainArgSignature {
|
||||
star_args: false,
|
||||
star_kwargs: false,
|
||||
args: vec![
|
||||
Arg {
|
||||
name: "strings".to_string(),
|
||||
otyp: None,
|
||||
typ: Typ::List(Box::new(Typ::Str(None))),
|
||||
default: None,
|
||||
has_default: false,
|
||||
oidx: None,
|
||||
},
|
||||
Arg {
|
||||
name: "numbers".to_string(),
|
||||
otyp: None,
|
||||
typ: Typ::List(Box::new(Typ::Float)),
|
||||
default: None,
|
||||
has_default: false,
|
||||
oidx: None,
|
||||
},
|
||||
Arg {
|
||||
name: "items".to_string(),
|
||||
otyp: None,
|
||||
typ: Typ::List(Box::new(Typ::Unknown)),
|
||||
default: None,
|
||||
has_default: false,
|
||||
oidx: None,
|
||||
},
|
||||
],
|
||||
no_main_func: Some(false),
|
||||
has_preprocessor: Some(false),
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_parse_resource_types() {
|
||||
let code = r#"
|
||||
type Postgresql = Resource;
|
||||
|
||||
export async function main(
|
||||
database: Postgresql
|
||||
) {
|
||||
return { database };
|
||||
}
|
||||
"#;
|
||||
let sig = parse_deno_signature(code, false, false, None).unwrap();
|
||||
assert_eq!(
|
||||
sig,
|
||||
MainArgSignature {
|
||||
star_args: false,
|
||||
star_kwargs: false,
|
||||
args: vec![Arg {
|
||||
name: "database".to_string(),
|
||||
otyp: None,
|
||||
typ: Typ::Resource("postgresql".to_string()),
|
||||
default: None,
|
||||
has_default: false,
|
||||
oidx: None,
|
||||
},],
|
||||
no_main_func: Some(false),
|
||||
has_preprocessor: Some(false),
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_parse_array_resource_types() {
|
||||
let code = r#"
|
||||
type Postgresql = Foo;
|
||||
|
||||
export async function main(
|
||||
database: Postgresql[]
|
||||
) {
|
||||
return { database };
|
||||
}
|
||||
"#;
|
||||
let sig = parse_deno_signature(code, false, false, None).unwrap();
|
||||
assert_eq!(
|
||||
sig,
|
||||
MainArgSignature {
|
||||
star_args: false,
|
||||
star_kwargs: false,
|
||||
args: vec![Arg {
|
||||
name: "database".to_string(),
|
||||
otyp: None,
|
||||
typ: Typ::List(Box::new(Typ::Resource("postgresql".to_string()))),
|
||||
default: None,
|
||||
has_default: false,
|
||||
oidx: None,
|
||||
},],
|
||||
no_main_func: Some(false),
|
||||
has_preprocessor: Some(false),
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_parse_interface_object() {
|
||||
let code = r#"
|
||||
interface UserConfig {
|
||||
name: string;
|
||||
age: number;
|
||||
active?: boolean;
|
||||
}
|
||||
|
||||
export async function main(config: UserConfig) {
|
||||
return config;
|
||||
}
|
||||
"#;
|
||||
let sig = parse_deno_signature(code, false, false, None).unwrap();
|
||||
assert_eq!(
|
||||
sig,
|
||||
MainArgSignature {
|
||||
star_args: false,
|
||||
star_kwargs: false,
|
||||
args: vec![Arg {
|
||||
name: "config".to_string(),
|
||||
otyp: None,
|
||||
typ: Typ::Object(ObjectType::new(
|
||||
Some("user_config".to_string()),
|
||||
Some(vec![
|
||||
ObjectProperty::new("name".to_string(), Box::new(Typ::Str(None))),
|
||||
ObjectProperty::new("age".to_string(), Box::new(Typ::Float)),
|
||||
ObjectProperty::new("active".to_string(), Box::new(Typ::Bool)),
|
||||
])
|
||||
)),
|
||||
default: None,
|
||||
has_default: false,
|
||||
oidx: None,
|
||||
}],
|
||||
no_main_func: Some(false),
|
||||
has_preprocessor: Some(false),
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_parse_array_of_objects() {
|
||||
let code = r#"
|
||||
interface Item {
|
||||
id: string;
|
||||
value: number;
|
||||
}
|
||||
|
||||
export async function main(items: Item[]) {
|
||||
return items;
|
||||
}
|
||||
"#;
|
||||
let sig = parse_deno_signature(code, false, false, None).unwrap();
|
||||
assert_eq!(
|
||||
sig,
|
||||
MainArgSignature {
|
||||
star_args: false,
|
||||
star_kwargs: false,
|
||||
args: vec![Arg {
|
||||
name: "items".to_string(),
|
||||
otyp: None,
|
||||
typ: Typ::List(Box::new(Typ::Object(ObjectType::new(
|
||||
Some("item".to_string()),
|
||||
Some(vec![
|
||||
ObjectProperty::new("id".to_string(), Box::new(Typ::Str(None))),
|
||||
ObjectProperty::new("value".to_string(), Box::new(Typ::Float)),
|
||||
])
|
||||
)))),
|
||||
default: None,
|
||||
has_default: false,
|
||||
oidx: None,
|
||||
}],
|
||||
no_main_func: Some(false),
|
||||
has_preprocessor: Some(false),
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_parse_nested_objects() {
|
||||
let code = r#"
|
||||
interface Address {
|
||||
street: string;
|
||||
city: string;
|
||||
}
|
||||
|
||||
interface Person {
|
||||
name: string;
|
||||
address: Address;
|
||||
}
|
||||
|
||||
export async function main(person: Person) {
|
||||
return person;
|
||||
}
|
||||
"#;
|
||||
let sig = parse_deno_signature(code, false, false, None).unwrap();
|
||||
assert_eq!(
|
||||
sig,
|
||||
MainArgSignature {
|
||||
star_args: false,
|
||||
star_kwargs: false,
|
||||
args: vec![Arg {
|
||||
name: "person".to_string(),
|
||||
otyp: None,
|
||||
typ: Typ::Object(ObjectType::new(
|
||||
Some("person".to_string()),
|
||||
Some(vec![
|
||||
ObjectProperty::new("name".to_string(), Box::new(Typ::Str(None))),
|
||||
ObjectProperty::new(
|
||||
"address".to_string(),
|
||||
Box::new(Typ::Object(ObjectType::new(
|
||||
Some("address".to_string()),
|
||||
Some(vec![
|
||||
ObjectProperty::new(
|
||||
"street".to_string(),
|
||||
Box::new(Typ::Str(None))
|
||||
),
|
||||
ObjectProperty::new(
|
||||
"city".to_string(),
|
||||
Box::new(Typ::Str(None))
|
||||
),
|
||||
])
|
||||
)))
|
||||
),
|
||||
])
|
||||
)),
|
||||
default: None,
|
||||
has_default: false,
|
||||
oidx: None,
|
||||
}],
|
||||
no_main_func: Some(false),
|
||||
has_preprocessor: Some(false),
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_parse_builtin_types() {
|
||||
let code = r#"
|
||||
export async function main(
|
||||
date_param: Date,
|
||||
base64_param: Base64,
|
||||
email_param: Email,
|
||||
sql_param: Sql
|
||||
) {
|
||||
return { date_param, base64_param, email_param, sql_param };
|
||||
}
|
||||
"#;
|
||||
let sig = parse_deno_signature(code, false, false, None).unwrap();
|
||||
assert_eq!(
|
||||
sig,
|
||||
MainArgSignature {
|
||||
star_args: false,
|
||||
star_kwargs: false,
|
||||
args: vec![
|
||||
Arg {
|
||||
name: "date_param".to_string(),
|
||||
otyp: None,
|
||||
typ: Typ::Datetime,
|
||||
default: None,
|
||||
has_default: false,
|
||||
oidx: None,
|
||||
},
|
||||
Arg {
|
||||
name: "base64_param".to_string(),
|
||||
otyp: None,
|
||||
typ: Typ::Bytes,
|
||||
default: None,
|
||||
has_default: false,
|
||||
oidx: None,
|
||||
},
|
||||
Arg {
|
||||
name: "email_param".to_string(),
|
||||
otyp: None,
|
||||
typ: Typ::Email,
|
||||
default: None,
|
||||
has_default: false,
|
||||
oidx: None,
|
||||
},
|
||||
Arg {
|
||||
name: "sql_param".to_string(),
|
||||
otyp: None,
|
||||
typ: Typ::Sql,
|
||||
default: None,
|
||||
has_default: false,
|
||||
oidx: None,
|
||||
},
|
||||
],
|
||||
no_main_func: Some(false),
|
||||
has_preprocessor: Some(false),
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_parse_optional_parameters() {
|
||||
let code = r#"
|
||||
export async function main(
|
||||
required: string,
|
||||
optional?: number,
|
||||
with_default: boolean = false
|
||||
) {
|
||||
return { required, optional, with_default };
|
||||
}
|
||||
"#;
|
||||
let sig = parse_deno_signature(code, false, false, None).unwrap();
|
||||
assert_eq!(
|
||||
sig,
|
||||
MainArgSignature {
|
||||
star_args: false,
|
||||
star_kwargs: false,
|
||||
args: vec![
|
||||
Arg {
|
||||
name: "required".to_string(),
|
||||
otyp: None,
|
||||
typ: Typ::Str(None),
|
||||
default: None,
|
||||
has_default: false,
|
||||
oidx: None,
|
||||
},
|
||||
Arg {
|
||||
name: "optional".to_string(),
|
||||
otyp: None,
|
||||
typ: Typ::Float,
|
||||
default: None,
|
||||
has_default: true,
|
||||
oidx: None,
|
||||
},
|
||||
Arg {
|
||||
name: "with_default".to_string(),
|
||||
otyp: None,
|
||||
typ: Typ::Bool,
|
||||
default: Some(json!(false)),
|
||||
has_default: true,
|
||||
oidx: None,
|
||||
},
|
||||
],
|
||||
no_main_func: Some(false),
|
||||
has_preprocessor: Some(false),
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_parse_complex_interface() {
|
||||
let code = r#"
|
||||
interface Config {
|
||||
timeout: number;
|
||||
retries: number;
|
||||
}
|
||||
|
||||
export async function main(
|
||||
config: Config,
|
||||
tags: string[]
|
||||
) {
|
||||
return { config, tags };
|
||||
}
|
||||
"#;
|
||||
let sig = parse_deno_signature(code, false, false, None).unwrap();
|
||||
|
||||
assert_eq!(sig.args.len(), 2);
|
||||
assert_eq!(sig.args[0].name, "config");
|
||||
assert_eq!(sig.args[0].has_default, false);
|
||||
assert!(matches!(sig.args[0].typ, Typ::Object(_)));
|
||||
|
||||
assert_eq!(sig.args[1].name, "tags");
|
||||
assert_eq!(sig.args[1].has_default, false);
|
||||
assert!(matches!(sig.args[1].typ, Typ::List(_)));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_parse_no_main_function() {
|
||||
let code = r#"
|
||||
function helper() {
|
||||
return "helper";
|
||||
}
|
||||
|
||||
const value = 42;
|
||||
"#;
|
||||
let sig = parse_deno_signature(code, false, false, None).unwrap();
|
||||
assert_eq!(
|
||||
sig,
|
||||
MainArgSignature {
|
||||
star_args: false,
|
||||
star_kwargs: false,
|
||||
args: vec![],
|
||||
no_main_func: Some(true),
|
||||
has_preprocessor: Some(false),
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_parse_custom_entrypoint() {
|
||||
let code = r#"
|
||||
export async function customMain(param: string) {
|
||||
return param;
|
||||
}
|
||||
"#;
|
||||
let sig = parse_deno_signature(code, false, false, Some("customMain".to_string())).unwrap();
|
||||
assert_eq!(
|
||||
sig,
|
||||
MainArgSignature {
|
||||
star_args: false,
|
||||
star_kwargs: false,
|
||||
args: vec![Arg {
|
||||
name: "param".to_string(),
|
||||
otyp: None,
|
||||
typ: Typ::Str(None),
|
||||
default: None,
|
||||
has_default: false,
|
||||
oidx: None,
|
||||
}],
|
||||
no_main_func: Some(false),
|
||||
has_preprocessor: Some(false),
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_parse_dyn_select() {
|
||||
let code = r#"
|
||||
export async function main(
|
||||
selector: DynSelect_my_options
|
||||
) {
|
||||
return selector;
|
||||
}
|
||||
"#;
|
||||
let sig = parse_deno_signature(code, false, false, None).unwrap();
|
||||
assert_eq!(
|
||||
sig,
|
||||
MainArgSignature {
|
||||
star_args: false,
|
||||
star_kwargs: false,
|
||||
args: vec![Arg {
|
||||
name: "selector".to_string(),
|
||||
otyp: None,
|
||||
typ: Typ::DynSelect("my_options".to_string()),
|
||||
default: None,
|
||||
has_default: false,
|
||||
oidx: None,
|
||||
}],
|
||||
no_main_func: Some(false),
|
||||
has_preprocessor: Some(false),
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_parse_invalid_typescript() {
|
||||
let code = r#"
|
||||
this is not valid typescript code {
|
||||
"#;
|
||||
let result = parse_deno_signature(code, false, false, None);
|
||||
assert!(result.is_err());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_parse_with_preprocessor() {
|
||||
let code = r#"
|
||||
export async function preprocessor() {
|
||||
return "preprocessed";
|
||||
}
|
||||
|
||||
export async function main(param: string) {
|
||||
return param;
|
||||
}
|
||||
"#;
|
||||
let sig = parse_deno_signature(code, false, false, None).unwrap();
|
||||
assert_eq!(
|
||||
sig,
|
||||
MainArgSignature {
|
||||
star_args: false,
|
||||
star_kwargs: false,
|
||||
args: vec![Arg {
|
||||
name: "param".to_string(),
|
||||
otyp: None,
|
||||
typ: Typ::Str(None),
|
||||
default: None,
|
||||
has_default: false,
|
||||
oidx: None,
|
||||
}],
|
||||
no_main_func: Some(false),
|
||||
has_preprocessor: Some(true),
|
||||
}
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,79 +0,0 @@
|
||||
#!/usr/bin/env bash
|
||||
set -eou pipefail
|
||||
|
||||
#-# bun and deno
|
||||
OUT_DIR="../../../cli/wasm/ts"
|
||||
mkdir -p $OUT_DIR
|
||||
wasm-pack build --release --target deno --out-dir $OUT_DIR --features "ts-parser" \
|
||||
-Z build-std=panic_abort,std -Z build-std-features=panic_immediate_abort
|
||||
# sed -i 's/"windmill-parser-wasm"/"windmill-parser-wasm-ts"/' $OUT_DIR/package.json
|
||||
rm $OUT_DIR/.gitignore
|
||||
|
||||
#-# sql languages, graphql and bash/powershell, since they all use regex
|
||||
OUT_DIR="../../../cli/wasm/regex"
|
||||
mkdir -p $OUT_DIR
|
||||
wasm-pack build --release --target deno --out-dir $OUT_DIR \
|
||||
--features "sql-parser,graphql-parser,bash-parser" \
|
||||
-Z build-std=panic_abort,std -Z build-std-features=panic_immediate_abort
|
||||
# sed -i 's/"windmill-parser-wasm"/"windmill-parser-wasm-regex"/' $OUT_DIR/package.json
|
||||
rm $OUT_DIR/.gitignore
|
||||
|
||||
#-# python
|
||||
OUT_DIR="../../../cli/wasm/python"
|
||||
mkdir -p $OUT_DIR
|
||||
wasm-pack build --release --target deno --out-dir $OUT_DIR --features "py-parser" \
|
||||
-Z build-std=panic_abort,std -Z build-std-features=panic_immediate_abort
|
||||
# sed -i 's/"windmill-parser-wasm"/"windmill-parser-wasm-py"/' $OUT_DIR/package.json
|
||||
rm $OUT_DIR/.gitignore
|
||||
|
||||
#-# go
|
||||
OUT_DIR="../../../cli/wasm/go"
|
||||
mkdir -p $OUT_DIR
|
||||
wasm-pack build --release --target deno --out-dir $OUT_DIR --features "go-parser" \
|
||||
-Z build-std=panic_abort,std -Z build-std-features=panic_immediate_abort
|
||||
# sed -i 's/"windmill-parser-wasm"/"windmill-parser-wasm-go"/' $OUT_DIR/package.json
|
||||
rm $OUT_DIR/.gitignore
|
||||
|
||||
#-# php
|
||||
OUT_DIR="../../../cli/wasm/php"
|
||||
mkdir -p $OUT_DIR
|
||||
wasm-pack build --release --target deno --out-dir $OUT_DIR --features "php-parser" \
|
||||
-Z build-std=panic_abort,std -Z build-std-features=panic_immediate_abort
|
||||
# sed -i 's/"windmill-parser-wasm"/"windmill-parser-wasm-php"/' $OUT_DIR/package.json
|
||||
rm $OUT_DIR/.gitignore
|
||||
|
||||
#-# rust
|
||||
OUT_DIR="../../../cli/wasm/rust"
|
||||
mkdir -p $OUT_DIR
|
||||
wasm-pack build --release --target deno --out-dir $OUT_DIR --features "rust-parser" \
|
||||
-Z build-std=panic_abort,std -Z build-std-features=panic_immediate_abort
|
||||
# sed -i 's/"windmill-parser-wasm"/"windmill-parser-wasm-rust"/' $OUT_DIR/package.json
|
||||
rm $OUT_DIR/.gitignore
|
||||
|
||||
#-# ansible
|
||||
OUT_DIR="../../../cli/wasm/yaml"
|
||||
mkdir -p $OUT_DIR
|
||||
wasm-pack build --release --target deno --out-dir $OUT_DIR --features "ansible-parser" \
|
||||
-Z build-std=panic_abort,std -Z build-std-features=panic_immediate_abort
|
||||
# sed -i 's/"windmill-parser-wasm"/"windmill-parser-wasm-yaml"/' $OUT_DIR/package.json
|
||||
rm $OUT_DIR/.gitignore
|
||||
|
||||
#-# C# (needs some more stuff to compile C tree sitter into wasm)
|
||||
OUT_DIR="../../../cli/wasm/csharp"
|
||||
mkdir -p $OUT_DIR
|
||||
CFLAGS_wasm32_unknown_unknown="-I$(pwd)/wasm-sysroot -Wbad-function-cast -Wcast-function-type -fno-builtin" RUSTFLAGS="-Zwasm-c-abi=spec" wasm-pack build --release --target deno --out-dir $OUT_DIR --features "csharp-parser"
|
||||
# sed -i 's/"windmill-parser-wasm"/"windmill-parser-wasm-csharp"/' $OUT_DIR/package.json
|
||||
rm $OUT_DIR/.gitignore
|
||||
|
||||
#-# Nu
|
||||
OUT_DIR="../../../cli/wasm/nu"
|
||||
mkdir -p $OUT_DIR
|
||||
wasm-pack build --release --target deno --out-dir $OUT_DIR --features "nu-parser" \
|
||||
-Z build-std=panic_abort,std -Z build-std-features=panic_immediate_abort
|
||||
rm $OUT_DIR/.gitignore
|
||||
|
||||
#-# Java
|
||||
OUT_DIR="../../../cli/wasm/java"
|
||||
mkdir -p $OUT_DIR
|
||||
CFLAGS_wasm32_unknown_unknown="-I$(pwd)/wasm-sysroot -Wbad-function-cast -Wcast-function-type -fno-builtin" RUSTFLAGS="-Zwasm-c-abi=spec" wasm-pack build --release --target deno --out-dir $OUT_DIR --features "java-parser"
|
||||
rm $OUT_DIR/.gitignore
|
||||
@@ -1,68 +0,0 @@
|
||||
#!/bin/bash
|
||||
set -eou pipefail
|
||||
|
||||
#-# full pkg
|
||||
OUT_DIR="pkg"
|
||||
wasm-pack build --release --target web --out-dir $OUT_DIR --all-features \
|
||||
-Z build-std=panic_abort,std -Z build-std-features=panic_immediate_abort
|
||||
|
||||
#-# bun and deno
|
||||
OUT_DIR="pkg-ts"
|
||||
wasm-pack build --release --target web --out-dir $OUT_DIR --features "ts-parser" \
|
||||
-Z build-std=panic_abort,std -Z build-std-features=panic_immediate_abort
|
||||
sed -i '' 's/"windmill-parser-wasm"/"windmill-parser-wasm-ts"/' $OUT_DIR/package.json
|
||||
|
||||
#-# sql languages, graphql and bash/powershell, since they all use regex
|
||||
OUT_DIR="pkg-regex"
|
||||
wasm-pack build --release --target web --out-dir $OUT_DIR \
|
||||
--features "sql-parser,graphql-parser,bash-parser" \
|
||||
-Z build-std=panic_abort,std -Z build-std-features=panic_immediate_abort
|
||||
sed -i '' 's/"windmill-parser-wasm"/"windmill-parser-wasm-regex"/' $OUT_DIR/package.json
|
||||
|
||||
#-# python
|
||||
OUT_DIR="pkg-py"
|
||||
wasm-pack build --release --target web --out-dir $OUT_DIR --features "py-parser" \
|
||||
-Z build-std=panic_abort,std -Z build-std-features=panic_immediate_abort
|
||||
sed -i '' 's/"windmill-parser-wasm"/"windmill-parser-wasm-py"/' $OUT_DIR/package.json
|
||||
|
||||
#-# go
|
||||
OUT_DIR="pkg-go"
|
||||
wasm-pack build --release --target web --out-dir $OUT_DIR --features "go-parser" \
|
||||
-Z build-std=panic_abort,std -Z build-std-features=panic_immediate_abort
|
||||
sed -i '' 's/"windmill-parser-wasm"/"windmill-parser-wasm-go"/' $OUT_DIR/package.json
|
||||
|
||||
#-# php
|
||||
OUT_DIR="pkg-php"
|
||||
wasm-pack build --release --target web --out-dir $OUT_DIR --features "php-parser" \
|
||||
-Z build-std=panic_abort,std -Z build-std-features=panic_immediate_abort
|
||||
sed -i '' 's/"windmill-parser-wasm"/"windmill-parser-wasm-php"/' $OUT_DIR/package.json
|
||||
|
||||
#-# rust
|
||||
OUT_DIR="pkg-rust"
|
||||
wasm-pack build --release --target web --out-dir $OUT_DIR --features "rust-parser" \
|
||||
-Z build-std=panic_abort,std -Z build-std-features=panic_immediate_abort
|
||||
sed -i '' 's/"windmill-parser-wasm"/"windmill-parser-wasm-rust"/' $OUT_DIR/package.json
|
||||
|
||||
#-# ansible
|
||||
OUT_DIR="pkg-yaml"
|
||||
wasm-pack build --release --target web --out-dir $OUT_DIR --features "ansible-parser" \
|
||||
-Z build-std=panic_abort,std -Z build-std-features=panic_immediate_abort
|
||||
sed -i '' 's/"windmill-parser-wasm"/"windmill-parser-wasm-yaml"/' $OUT_DIR/package.json
|
||||
|
||||
#-# C# (needs some more stuff to compile C tree sitter into wasm)
|
||||
# TODO: hasn't been tested on mac, might need fixing
|
||||
OUT_DIR="pkg-csharp"
|
||||
CFLAGS_wasm32_unknown_unknown="-I$(pwd)/wasm-sysroot -Wbad-function-cast -Wcast-function-type -fno-builtin" RUSTFLAGS="-Zwasm-c-abi=spec" wasm-pack build --release --target web --out-dir $OUT_DIR --features "csharp-parser"
|
||||
sed -i '' 's/"windmill-parser-wasm"/"windmill-parser-wasm-csharp"/' $OUT_DIR/package.json
|
||||
|
||||
#-# nu
|
||||
# TODO: hasn't been tested on mac, might need fixing
|
||||
OUT_DIR="pkg-nu"
|
||||
wasm-pack build --release --target web --out-dir $OUT_DIR --features "nu-parser" \
|
||||
-Z build-std=panic_abort,std -Z build-std-features=panic_immediate_abort
|
||||
sed -i '' 's/"windmill-parser-wasm"/"windmill-parser-wasm-nu"/' $OUT_DIR/package.json
|
||||
|
||||
#-# Java (needs some more stuff to compile C tree sitter into wasm)
|
||||
OUT_DIR="pkg-java"
|
||||
CFLAGS_wasm32_unknown_unknown="-I$(pwd)/wasm-sysroot -Wbad-function-cast -Wcast-function-type -fno-builtin" RUSTFLAGS="-Zwasm-c-abi=spec" wasm-pack build --release --target web --out-dir $OUT_DIR --features "java-parser"
|
||||
sed -i '' 's/"windmill-parser-wasm"/"windmill-parser-wasm-java"/' $OUT_DIR/package.json
|
||||
@@ -1,66 +0,0 @@
|
||||
#!/usr/bin/env bash
|
||||
set -eou pipefail
|
||||
|
||||
#-# full pkg
|
||||
OUT_DIR="pkg"
|
||||
wasm-pack build --release --target web --out-dir $OUT_DIR --all-features \
|
||||
-Z build-std=panic_abort,std -Z build-std-features=panic_immediate_abort
|
||||
|
||||
#-# bun and deno
|
||||
OUT_DIR="pkg-ts"
|
||||
wasm-pack build --release --target web --out-dir $OUT_DIR --features "ts-parser" \
|
||||
-Z build-std=panic_abort,std -Z build-std-features=panic_immediate_abort
|
||||
sed -i 's/"windmill-parser-wasm"/"windmill-parser-wasm-ts"/' $OUT_DIR/package.json
|
||||
|
||||
#-# sql languages, graphql and bash/powershell, since they all use regex
|
||||
OUT_DIR="pkg-regex"
|
||||
wasm-pack build --release --target web --out-dir $OUT_DIR \
|
||||
--features "sql-parser,graphql-parser,bash-parser" \
|
||||
-Z build-std=panic_abort,std -Z build-std-features=panic_immediate_abort
|
||||
sed -i 's/"windmill-parser-wasm"/"windmill-parser-wasm-regex"/' $OUT_DIR/package.json
|
||||
|
||||
#-# python
|
||||
OUT_DIR="pkg-py"
|
||||
wasm-pack build --release --target web --out-dir $OUT_DIR --features "py-parser" \
|
||||
-Z build-std=panic_abort,std -Z build-std-features=panic_immediate_abort
|
||||
sed -i 's/"windmill-parser-wasm"/"windmill-parser-wasm-py"/' $OUT_DIR/package.json
|
||||
|
||||
#-# go
|
||||
OUT_DIR="pkg-go"
|
||||
wasm-pack build --release --target web --out-dir $OUT_DIR --features "go-parser" \
|
||||
-Z build-std=panic_abort,std -Z build-std-features=panic_immediate_abort
|
||||
sed -i 's/"windmill-parser-wasm"/"windmill-parser-wasm-go"/' $OUT_DIR/package.json
|
||||
|
||||
#-# php
|
||||
OUT_DIR="pkg-php"
|
||||
wasm-pack build --release --target web --out-dir $OUT_DIR --features "php-parser" \
|
||||
-Z build-std=panic_abort,std -Z build-std-features=panic_immediate_abort
|
||||
sed -i 's/"windmill-parser-wasm"/"windmill-parser-wasm-php"/' $OUT_DIR/package.json
|
||||
|
||||
#-# rust
|
||||
OUT_DIR="pkg-rust"
|
||||
wasm-pack build --release --target web --out-dir $OUT_DIR --features "rust-parser" \
|
||||
-Z build-std=panic_abort,std -Z build-std-features=panic_immediate_abort
|
||||
sed -i 's/"windmill-parser-wasm"/"windmill-parser-wasm-rust"/' $OUT_DIR/package.json
|
||||
|
||||
#-# ansible
|
||||
OUT_DIR="pkg-yaml"
|
||||
wasm-pack build --release --target web --out-dir $OUT_DIR --features "ansible-parser" \
|
||||
-Z build-std=panic_abort,std -Z build-std-features=panic_immediate_abort
|
||||
sed -i 's/"windmill-parser-wasm"/"windmill-parser-wasm-yaml"/' $OUT_DIR/package.json
|
||||
|
||||
#-# C# (needs some more stuff to compile C tree sitter into wasm)
|
||||
OUT_DIR="pkg-csharp"
|
||||
CFLAGS_wasm32_unknown_unknown="-I$(pwd)/wasm-sysroot -Wbad-function-cast -Wcast-function-type -fno-builtin" RUSTFLAGS="-Zwasm-c-abi=spec" wasm-pack build --release --target web --out-dir $OUT_DIR --features "csharp-parser"
|
||||
sed -i 's/"windmill-parser-wasm"/"windmill-parser-wasm-csharp"/' $OUT_DIR/package.json
|
||||
|
||||
#-# Nu
|
||||
OUT_DIR="pkg-nu"
|
||||
wasm-pack build --release --target web --out-dir $OUT_DIR --features "nu-parser" \
|
||||
-Z build-std=panic_abort,std -Z build-std-features=panic_immediate_abort
|
||||
sed -i 's/"windmill-parser-wasm"/"windmill-parser-wasm-nu"/' $OUT_DIR/package.json
|
||||
|
||||
#-# Java (needs some more stuff to compile C tree sitter into wasm)
|
||||
OUT_DIR="pkg-java"
|
||||
CFLAGS_wasm32_unknown_unknown="-I$(pwd)/wasm-sysroot -Wbad-function-cast -Wcast-function-type -fno-builtin" RUSTFLAGS="-Zwasm-c-abi=spec" wasm-pack build --release --target web --out-dir $OUT_DIR --features "java-parser"
|
||||
sed -i 's/"windmill-parser-wasm"/"windmill-parser-wasm-java"/' $OUT_DIR/package.json
|
||||
132
backend/parsers/windmill-parser-wasm/build.nu
Executable file
132
backend/parsers/windmill-parser-wasm/build.nu
Executable file
@@ -0,0 +1,132 @@
|
||||
#!/usr/bin/env nu
|
||||
const targets = [
|
||||
{
|
||||
ident: "ts", # OUT_DIR inferred from this
|
||||
desc: "Bun and Deno"
|
||||
features: "ts-parser",
|
||||
env: "default", # available: default, tree-sitter
|
||||
}, {
|
||||
ident: "regex",
|
||||
desc: "Sql languages, Graphql and Bash/Powershell"
|
||||
features: "sql-parser,graphql-parser,bash-parser",
|
||||
env: "default",
|
||||
}, {
|
||||
ident: "py",
|
||||
desc: "Python",
|
||||
features: "py-parser",
|
||||
env: "default",
|
||||
}, {
|
||||
ident: "go",
|
||||
desc: "Go (Go-lang)",
|
||||
features: "go-parser",
|
||||
env: "default",
|
||||
}, {
|
||||
ident: "php",
|
||||
desc: "Php",
|
||||
features: "php-parser",
|
||||
env: "default",
|
||||
}, {
|
||||
ident: "rust",
|
||||
desc: "Rust",
|
||||
features: "rust-parser",
|
||||
env: "default",
|
||||
}, {
|
||||
ident: "yaml",
|
||||
desc: "Ansible",
|
||||
features: "ansible-parser",
|
||||
env: "default",
|
||||
}, {
|
||||
ident: "csharp",
|
||||
desc: "C#",
|
||||
features: "csharp-parser",
|
||||
env: "tree-sitter",
|
||||
}, {
|
||||
ident: "nu",
|
||||
desc: "Nu (Nushell)",
|
||||
features: "nu-parser",
|
||||
env: "tree-sitter",
|
||||
}, {
|
||||
ident: "java",
|
||||
desc: "Java",
|
||||
features: "java-parser",
|
||||
env: "tree-sitter",
|
||||
# }, {
|
||||
# ident: "ruby",
|
||||
# desc: "Ruby",
|
||||
# features: "ruby-parser",
|
||||
# env: "tree-sitter",
|
||||
},
|
||||
# ^^^ Add new entry here ^^^
|
||||
];
|
||||
# NOTE: This is legacy command for building all, but it is not more used
|
||||
# #-# full pkg
|
||||
# OUT_DIR="pkg"
|
||||
# wasm-pack build --release --target web --out-dir $OUT_DIR --all-features \
|
||||
# -Z build-std=panic_abort,std -Z build-std-features=panic_immediate_abort
|
||||
|
||||
# Build all separately
|
||||
def 'main all' [ --no-opt(-n), --cli] {
|
||||
if ($no_opt) {
|
||||
if ($cli) {
|
||||
$targets | each { main $in.ident -n --cli }
|
||||
} else {
|
||||
$targets | each { main $in.ident -n }
|
||||
}
|
||||
} else {
|
||||
if ($cli) {
|
||||
$targets | each { main $in.ident --cli }
|
||||
} else {
|
||||
$targets | each { main $in.ident }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
# Build specific language
|
||||
def main [
|
||||
target: string, # Language, e.g.: py, ts, rust
|
||||
--no-opt(-n), # Compile in debug mode for dev
|
||||
--cli # Compile and place binaries in cli.
|
||||
] {
|
||||
let t = $targets | where ident == $target;
|
||||
|
||||
if ($t | is-empty) {
|
||||
let pretty = $targets | each {|t| $"• ($t.ident) - ($t.desc)"} | str join "\n";
|
||||
panic $"Target '($target)' does not exist\n\nAvailable targets:\n($pretty)"
|
||||
} else {
|
||||
let t = $t | get 0;
|
||||
mut profile = "";
|
||||
mut tar = "";
|
||||
|
||||
if ($cli) {
|
||||
$env.OUT_DIR = $"../../../cli/wasm/($t.ident)"
|
||||
$tar = "deno"
|
||||
} else {
|
||||
$env.OUT_DIR = $"pkg-($t.ident)"
|
||||
$tar = "web"
|
||||
}
|
||||
if ($no_opt) {
|
||||
$profile = "--no-opt"
|
||||
} else {
|
||||
$profile = "--release"
|
||||
}
|
||||
print $"Building in ($profile) mode ($env.OUT_DIR)"
|
||||
match $t.env {
|
||||
"default" => {
|
||||
wasm-pack build ($profile) --target ($tar) --out-dir $env.OUT_DIR --features ($t.features) -Z build-std=panic_abort,std -Z build-std-features=panic_immediate_abort
|
||||
},
|
||||
"tree-sitter" => {
|
||||
$env.CFLAGS_wasm32_unknown_unknown = $"-I(pwd)/wasm-sysroot -Wbad-function-cast -Wcast-function-type -fno-builtin"
|
||||
$env.RUSTFLAGS = "-Zwasm-c-abi=spec"
|
||||
wasm-pack build ($profile) --target ($tar) --out-dir $env.OUT_DIR --features $t.features
|
||||
},
|
||||
_ => { panic $"Unknown env template: ($t.env)" },
|
||||
}
|
||||
|
||||
if ($cli) {
|
||||
rm $"($env.OUT_DIR)/.gitignore"
|
||||
} else {
|
||||
let p = $"($env.OUT_DIR)/package.json"
|
||||
open $p | update name $"windmill-parser-wasm-($t.ident)" | save -f $p
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -4,22 +4,9 @@
|
||||
# and perform installation to frontend
|
||||
def "main" [
|
||||
lang: string # Example: nu
|
||||
--release(-r)
|
||||
] {
|
||||
let out_dir = $'pkg-($lang)'
|
||||
if $release {
|
||||
open build-pkgs.sh
|
||||
| split row '#-'
|
||||
| find $out_dir
|
||||
| bash -c $"RUST_LOG=trace ($in.0)"
|
||||
} else {
|
||||
open build-pkgs.sh
|
||||
| split row '#-'
|
||||
| find $out_dir
|
||||
| str replace "--release" "--no-opt"
|
||||
| bash -c $"WASM_OPT=-Oz ($in.0)"
|
||||
}
|
||||
./build.nu $lang --no-opt
|
||||
(
|
||||
cd ../../../frontend; npm install ../backend/parsers/windmill-parser-wasm/($out_dir)
|
||||
cd ../../../frontend; npm install ../backend/parsers/windmill-parser-wasm/pkg-($lang)
|
||||
)
|
||||
}
|
||||
|
||||
@@ -30,3 +30,6 @@ popd
|
||||
|
||||
pushd "pkg-nu" && npm publish ${args}
|
||||
popd
|
||||
|
||||
pushd "pkg-java" && npm publish ${args}
|
||||
popd
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
use serde_json::json;
|
||||
use wasm_bindgen_test::wasm_bindgen_test;
|
||||
use windmill_parser::{Arg, MainArgSignature, ObjectProperty, Typ};
|
||||
use windmill_parser::{Arg, MainArgSignature, ObjectProperty, ObjectType, Typ};
|
||||
use windmill_parser_bash::parse_powershell_sig;
|
||||
use windmill_parser_ts::{parse_deno_signature, parse_expr_for_ids, parse_expr_for_imports};
|
||||
|
||||
@@ -115,10 +115,10 @@ export function main(test1?: string, test2: string = \"burkina\",
|
||||
Arg {
|
||||
otyp: None,
|
||||
name: "min_object".to_string(),
|
||||
typ: Typ::Object(vec![
|
||||
typ: Typ::Object(ObjectType::new(None, Some(vec![
|
||||
ObjectProperty { key: "a".to_string(), typ: Box::new(Typ::Str(None)) },
|
||||
ObjectProperty { key: "b".to_string(), typ: Box::new(Typ::Float) }
|
||||
]),
|
||||
]))),
|
||||
default: None,
|
||||
has_default: false,
|
||||
oidx: None
|
||||
@@ -210,10 +210,10 @@ export function main(test2 = \"burkina\",
|
||||
Arg {
|
||||
otyp: None,
|
||||
name: "min_object".to_string(),
|
||||
typ: Typ::Object(vec![
|
||||
typ: Typ::Object(ObjectType::new(None, Some(vec![
|
||||
ObjectProperty { key: "a".to_string(), typ: Box::new(Typ::Str(None)) },
|
||||
ObjectProperty { key: "b".to_string(), typ: Box::new(Typ::Int) }
|
||||
]),
|
||||
]))),
|
||||
default: Some(json!({"a": "test", "b": 42})),
|
||||
has_default: true,
|
||||
oidx: None
|
||||
|
||||
@@ -2,7 +2,7 @@ use std::collections::HashMap;
|
||||
|
||||
use anyhow::anyhow;
|
||||
use serde_json::json;
|
||||
use windmill_parser::{Arg, MainArgSignature, ObjectProperty, Typ};
|
||||
use windmill_parser::{Arg, MainArgSignature, ObjectProperty, ObjectType, Typ};
|
||||
use yaml_rust::{Yaml, YamlEmitter, YamlLoader};
|
||||
|
||||
pub fn parse_ansible_sig(inner_content: &str) -> anyhow::Result<MainArgSignature> {
|
||||
@@ -147,9 +147,9 @@ fn parse_ansible_typ(arg: &Yaml) -> Typ {
|
||||
})
|
||||
}
|
||||
}
|
||||
Typ::Object(prop_vec)
|
||||
Typ::Object(ObjectType::new(None, Some(prop_vec)))
|
||||
} else {
|
||||
Typ::Object(vec![])
|
||||
Typ::Object(ObjectType::new(None, Some(vec![])))
|
||||
}
|
||||
}
|
||||
"array" => {
|
||||
|
||||
@@ -15,7 +15,6 @@ use AssetUsageAccessType::*;
|
||||
pub enum AssetKind {
|
||||
S3Object,
|
||||
Resource,
|
||||
Variable,
|
||||
}
|
||||
|
||||
#[derive(Serialize)]
|
||||
@@ -57,8 +56,6 @@ pub fn parse_asset_syntax(s: &str) -> Option<(AssetKind, &str)> {
|
||||
Some((AssetKind::Resource, &s[6..]))
|
||||
} else if s.starts_with("$res:") {
|
||||
Some((AssetKind::Resource, &s[5..]))
|
||||
} else if s.starts_with("var://") {
|
||||
Some((AssetKind::Variable, &s[6..]))
|
||||
} else {
|
||||
None
|
||||
}
|
||||
|
||||
@@ -28,6 +28,24 @@ pub struct ObjectProperty {
|
||||
pub typ: Box<Typ>,
|
||||
}
|
||||
|
||||
impl ObjectProperty {
|
||||
pub fn new(key: String, typ: Box<Typ>) -> ObjectProperty {
|
||||
ObjectProperty { key, typ }
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Serialize, Clone, Debug, PartialEq)]
|
||||
pub struct ObjectType {
|
||||
pub name: Option<String>,
|
||||
pub props: Option<Vec<ObjectProperty>>,
|
||||
}
|
||||
|
||||
impl ObjectType {
|
||||
pub fn new(name: Option<String>, props: Option<Vec<ObjectProperty>>) -> ObjectType {
|
||||
ObjectType { name, props }
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Serialize, Clone, Debug, PartialEq)]
|
||||
#[serde(rename_all(serialize = "lowercase"))]
|
||||
pub struct OneOfVariant {
|
||||
@@ -49,7 +67,7 @@ pub enum Typ {
|
||||
Email,
|
||||
Sql,
|
||||
DynSelect(String),
|
||||
Object(Vec<ObjectProperty>),
|
||||
Object(ObjectType),
|
||||
OneOf(Vec<OneOfVariant>),
|
||||
Unknown,
|
||||
}
|
||||
@@ -70,11 +88,14 @@ pub fn json_to_typ(js: &Value) -> Typ {
|
||||
Value::Number(n) if n.is_i64() => Typ::Int,
|
||||
Value::Number(_) => Typ::Float,
|
||||
Value::Bool(_) => Typ::Bool,
|
||||
Value::Object(o) => Typ::Object(
|
||||
o.iter()
|
||||
.map(|(k, v)| ObjectProperty { key: k.to_string(), typ: Box::new(json_to_typ(v)) })
|
||||
.collect(),
|
||||
),
|
||||
Value::Object(o) => Typ::Object(ObjectType::new(
|
||||
None,
|
||||
Some(
|
||||
o.iter()
|
||||
.map(|(k, v)| ObjectProperty { key: k.to_string(), typ: Box::new(json_to_typ(v)) })
|
||||
.collect(),
|
||||
),
|
||||
)),
|
||||
Value::Array(a) => Typ::List(Box::new(a.first().map(json_to_typ).unwrap_or(Typ::Unknown))),
|
||||
_ => Typ::Unknown,
|
||||
}
|
||||
|
||||
@@ -54,8 +54,8 @@ use windmill_common::{
|
||||
stats_oss::schedule_stats,
|
||||
triggers::TriggerKind,
|
||||
utils::{
|
||||
create_default_worker_suffix, create_ssh_agent_worker_suffix, worker_name_with_suffix,
|
||||
Mode, GIT_VERSION, HOSTNAME, MODE_AND_ADDONS,
|
||||
create_default_worker_suffix, worker_name_with_suffix, Mode, GIT_VERSION, HOSTNAME,
|
||||
MODE_AND_ADDONS,
|
||||
},
|
||||
worker::{
|
||||
reload_custom_tags_setting, Connection, HUB_CACHE_DIR, TMP_DIR, TMP_LOGS_DIR, WORKER_GROUP,
|
||||
@@ -365,7 +365,7 @@ async fn windmill_main() -> anyhow::Result<()> {
|
||||
"Creating http client for cluster using base internal url {}",
|
||||
std::env::var("BASE_INTERNAL_URL").unwrap_or_default()
|
||||
);
|
||||
let suffix = create_ssh_agent_worker_suffix(&hostname);
|
||||
let suffix = create_default_worker_suffix(&hostname);
|
||||
(
|
||||
Connection::Http(build_agent_http_client(&suffix)),
|
||||
Some(suffix),
|
||||
|
||||
@@ -65,7 +65,8 @@ use windmill_common::{
|
||||
users::truncate_token,
|
||||
utils::{empty_as_none, now_from_db, rd_string, report_critical_error, Mode},
|
||||
worker::{
|
||||
load_env_vars, load_init_bash_from_env, load_whitelist_env_vars_from_env,
|
||||
load_env_vars, load_init_bash_from_env, load_periodic_bash_script_from_env,
|
||||
load_periodic_bash_script_interval_from_env, load_whitelist_env_vars_from_env,
|
||||
load_worker_config, reload_custom_tags_setting, store_pull_query,
|
||||
store_suspended_pull_query, update_min_version, Connection, WorkerConfig,
|
||||
DEFAULT_TAGS_PER_WORKSPACE, DEFAULT_TAGS_WORKSPACES, INDEXER_CONFIG, SCRIPT_TOKEN_EXPIRY,
|
||||
@@ -213,6 +214,8 @@ pub async fn initial_load(
|
||||
priority_tags_sorted: vec![],
|
||||
dedicated_worker: None,
|
||||
init_bash: load_init_bash_from_env(),
|
||||
periodic_script_bash: load_periodic_bash_script_from_env(),
|
||||
periodic_script_interval_seconds: load_periodic_bash_script_interval_from_env(),
|
||||
cache_clear: None,
|
||||
additional_python_paths: None,
|
||||
pip_local_dependencies: None,
|
||||
@@ -1574,6 +1577,17 @@ pub async fn reload_worker_config(db: &DB, tx: KillpillSender, kill_if_change: b
|
||||
tracing::error!("Error cleaning the cache: {e:#}");
|
||||
}
|
||||
}
|
||||
|
||||
if (*wc).periodic_script_bash != config.periodic_script_bash {
|
||||
tracing::info!("Periodic script bash config changed, sending killpill. Expecting to be restarted by supervisor.");
|
||||
let _ = tx.send();
|
||||
}
|
||||
|
||||
if (*wc).periodic_script_interval_seconds != config.periodic_script_interval_seconds
|
||||
{
|
||||
tracing::info!("Periodic script interval config changed, sending killpill. Expecting to be restarted by supervisor.");
|
||||
let _ = tx.send();
|
||||
}
|
||||
}
|
||||
drop(wc);
|
||||
|
||||
@@ -1835,12 +1849,14 @@ async fn handle_zombie_jobs(db: &Pool<Postgres>, base_internal_url: &str, worker
|
||||
);
|
||||
}
|
||||
|
||||
let jobs = sqlx::query_as::<_, QueuedJob>("SELECT * FROM v2_as_queue WHERE id = ANY($1)")
|
||||
.bind(&timeouts[..])
|
||||
.fetch_all(db)
|
||||
.await
|
||||
.map_err(|e| tracing::error!("Error fetching same worker jobs: {:?}", e))
|
||||
.unwrap_or_default();
|
||||
let jobs = sqlx::query_as::<_, QueuedJob>(
|
||||
"SELECT *, null as workflow_as_code_status FROM v2_as_queue WHERE id = ANY($1)",
|
||||
)
|
||||
.bind(&timeouts[..])
|
||||
.fetch_all(db)
|
||||
.await
|
||||
.map_err(|e| tracing::error!("Error fetching same worker jobs: {:?}", e))
|
||||
.unwrap_or_default();
|
||||
|
||||
jobs
|
||||
};
|
||||
@@ -1848,7 +1864,7 @@ async fn handle_zombie_jobs(db: &Pool<Postgres>, base_internal_url: &str, worker
|
||||
let non_restartable_jobs = if *RESTART_ZOMBIE_JOBS {
|
||||
vec![]
|
||||
} else {
|
||||
sqlx::query_as::<_, QueuedJob>("SELECT * FROM v2_as_queue WHERE last_ping < now() - ($1 || ' seconds')::interval
|
||||
sqlx::query_as::<_, QueuedJob>("SELECT *, null as workflow_as_code_status FROM v2_as_queue WHERE last_ping < now() - ($1 || ' seconds')::interval
|
||||
AND running = true AND job_kind NOT IN ('flow', 'flowpreview', 'flownode', 'singlescriptflow') AND same_worker = false")
|
||||
.bind(ZOMBIE_JOB_TIMEOUT.as_str())
|
||||
.fetch_all(db)
|
||||
@@ -1873,13 +1889,14 @@ async fn handle_zombie_jobs(db: &Pool<Postgres>, base_internal_url: &str, worker
|
||||
}
|
||||
}
|
||||
|
||||
let zombie_jobs_restart_limit_reached =
|
||||
sqlx::query_as::<_, QueuedJob>("SELECT * FROM v2_as_queue WHERE id = ANY($1)")
|
||||
.bind(&zombie_jobs_uuid_restart_limit_reached[..])
|
||||
.fetch_all(db)
|
||||
.await
|
||||
.ok()
|
||||
.unwrap_or_else(|| vec![]);
|
||||
let zombie_jobs_restart_limit_reached = sqlx::query_as::<_, QueuedJob>(
|
||||
"SELECT *, null as workflow_as_code_status FROM v2_as_queue WHERE id = ANY($1)",
|
||||
)
|
||||
.bind(&zombie_jobs_uuid_restart_limit_reached[..])
|
||||
.fetch_all(db)
|
||||
.await
|
||||
.ok()
|
||||
.unwrap_or_else(|| vec![]);
|
||||
|
||||
let timeouts = non_restartable_jobs
|
||||
.into_iter()
|
||||
|
||||
@@ -99,4 +99,4 @@ if [ "$MOVE_NEW_FILES" == "YES" ]; then
|
||||
echo "File moved '${ce_file}' -->> '${ee_file}'"
|
||||
fi
|
||||
done
|
||||
fi
|
||||
fi
|
||||
|
||||
@@ -27,8 +27,10 @@ use serde::Serialize;
|
||||
use windmill_common::flows::InputTransform;
|
||||
use windmill_common::worker::WORKER_CONFIG;
|
||||
|
||||
#[cfg(feature = "python")]
|
||||
use windmill_common::flow_status::{FlowStatus, FlowStatusModule, RestartedFrom};
|
||||
|
||||
use windmill_common::{
|
||||
flow_status::{FlowStatus, FlowStatusModule, RestartedFrom},
|
||||
flows::{FlowModule, FlowModuleValue, FlowValue},
|
||||
jobs::{JobKind, JobPayload, RawCode},
|
||||
jwt::JWT_SECRET,
|
||||
@@ -114,12 +116,14 @@ fn next_worker_name() -> String {
|
||||
.unwrap_or(s)
|
||||
})
|
||||
.unwrap_or("no thread name");
|
||||
format!("{id}/{thread_name}")
|
||||
format!("{id}/worker-{thread_name}")
|
||||
}
|
||||
|
||||
pub struct ApiServer {
|
||||
pub addr: std::net::SocketAddr,
|
||||
#[allow(unused)]
|
||||
tx: tokio::sync::broadcast::Sender<()>,
|
||||
#[allow(unused)]
|
||||
task: tokio::task::JoinHandle<anyhow::Result<()>>,
|
||||
}
|
||||
|
||||
@@ -153,6 +157,7 @@ impl ApiServer {
|
||||
Self { addr, tx, task }
|
||||
}
|
||||
|
||||
#[allow(unused)]
|
||||
async fn close(self) -> anyhow::Result<()> {
|
||||
println!("closing api server");
|
||||
let Self { tx, task, .. } = self;
|
||||
@@ -193,11 +198,13 @@ async fn set_jwt_secret() -> () {
|
||||
}
|
||||
|
||||
mod suspend_resume {
|
||||
|
||||
#[cfg(feature = "deno_core")]
|
||||
use serde_json::json;
|
||||
|
||||
#[cfg(feature = "deno_core")]
|
||||
use super::*;
|
||||
|
||||
#[cfg(feature = "deno_core")]
|
||||
async fn wait_until_flow_suspends(
|
||||
flow: Uuid,
|
||||
mut queue: impl Stream<Item = Uuid> + Unpin,
|
||||
@@ -218,6 +225,7 @@ mod suspend_resume {
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(feature = "deno_core")]
|
||||
fn flow() -> FlowValue {
|
||||
serde_json::from_value(serde_json::json!({
|
||||
"modules": [{
|
||||
@@ -462,12 +470,12 @@ mod suspend_resume {
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(feature = "deno_core")]
|
||||
mod retry {
|
||||
use super::*;
|
||||
use serde_json::json;
|
||||
use tokio::io::{AsyncReadExt, AsyncWriteExt};
|
||||
|
||||
use super::*;
|
||||
|
||||
/// test helper provides some external state to help steps fail at specific points
|
||||
struct Server {
|
||||
addr: std::net::SocketAddr,
|
||||
@@ -536,6 +544,7 @@ def main(last, port):
|
||||
"#
|
||||
}
|
||||
|
||||
#[cfg(feature = "deno_core")]
|
||||
fn flow_forloop_retry() -> FlowValue {
|
||||
serde_json::from_value(serde_json::json!({
|
||||
"modules": [{
|
||||
@@ -1073,6 +1082,7 @@ async fn listen_for_completed_jobs(db: &Pool<Postgres>) -> impl Stream<Item = Uu
|
||||
listen_for_uuid_on(db, "completed").await
|
||||
}
|
||||
|
||||
#[cfg(feature = "deno_core")]
|
||||
async fn listen_for_queue(db: &Pool<Postgres>) -> impl Stream<Item = Uuid> + Unpin {
|
||||
listen_for_uuid_on(db, "queued").await
|
||||
}
|
||||
@@ -1147,7 +1157,7 @@ async fn test_deno_flow(db: Pool<Postgres>) {
|
||||
concurrent_limit: None,
|
||||
concurrency_time_window_s: None,
|
||||
is_trigger: None,
|
||||
asset_fallback_access_types: None,
|
||||
assets: None,
|
||||
}
|
||||
.into(),
|
||||
stop_after_if: Default::default(),
|
||||
@@ -1191,7 +1201,7 @@ async fn test_deno_flow(db: Pool<Postgres>) {
|
||||
concurrent_limit: None,
|
||||
concurrency_time_window_s: None,
|
||||
is_trigger: None,
|
||||
asset_fallback_access_types: None,
|
||||
assets: None,
|
||||
}
|
||||
.into(),
|
||||
stop_after_if: Default::default(),
|
||||
@@ -1321,7 +1331,7 @@ async fn test_deno_flow_same_worker(db: Pool<Postgres>) {
|
||||
concurrent_limit: None,
|
||||
concurrency_time_window_s: None,
|
||||
is_trigger: None,
|
||||
asset_fallback_access_types: None,
|
||||
assets: None,
|
||||
|
||||
}.into(),
|
||||
stop_after_if: Default::default(),
|
||||
@@ -1376,7 +1386,7 @@ async fn test_deno_flow_same_worker(db: Pool<Postgres>) {
|
||||
concurrent_limit: None,
|
||||
concurrency_time_window_s: None,
|
||||
is_trigger: None,
|
||||
asset_fallback_access_types: None,
|
||||
assets: None,
|
||||
}.into(),
|
||||
stop_after_if: Default::default(),
|
||||
stop_after_all_iters_if: Default::default(),
|
||||
@@ -1416,7 +1426,7 @@ async fn test_deno_flow_same_worker(db: Pool<Postgres>) {
|
||||
concurrent_limit: None,
|
||||
concurrency_time_window_s: None,
|
||||
is_trigger: None,
|
||||
asset_fallback_access_types: None,
|
||||
assets: None,
|
||||
|
||||
}.into(),
|
||||
stop_after_if: Default::default(),
|
||||
@@ -1482,7 +1492,7 @@ async fn test_deno_flow_same_worker(db: Pool<Postgres>) {
|
||||
concurrent_limit: None,
|
||||
concurrency_time_window_s: None,
|
||||
is_trigger: None,
|
||||
asset_fallback_access_types: None,
|
||||
assets: None,
|
||||
}.into(),
|
||||
stop_after_if: Default::default(),
|
||||
stop_after_all_iters_if: Default::default(),
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
#!/bin/bash
|
||||
#!/usr/bin/env bash
|
||||
|
||||
# Default directory
|
||||
EE_DIR="../windmill-ee-private"
|
||||
@@ -32,4 +32,4 @@ if [[ "$(uname)" == "Darwin" ]]; then
|
||||
sed -i '' 's/^#samael = { version="0.0.14", features = \["xmlsec"\] }/samael = { version="0.0.14", features = ["xmlsec"] }/' Cargo.toml
|
||||
# Comment out the git-based samael dependency
|
||||
sed -i '' 's/^\(samael = { git="https:\/\/github.com\/njaremko\/samael", rev="464d015e3ae393e4b5dd00b4d6baa1b617de0dd6", features = \["xmlsec"\] }\)/# \1/' Cargo.toml
|
||||
fi
|
||||
fi
|
||||
|
||||
@@ -32,7 +32,7 @@ http_trigger = ["dep:matchit", "dep:thiserror", "dep:sha1", "dep:constant_time_e
|
||||
static_frontend = ["dep:rust-embed"]
|
||||
postgres_trigger = ["dep:rust-postgres", "dep:pg_escape", "dep:byteorder", "dep:thiserror", "dep:rust_decimal", "dep:rust-postgres-native-tls"]
|
||||
mqtt_trigger = ["dep:thiserror", "dep:rumqttc"]
|
||||
sqs_trigger = ["dep:aws-sdk-sqs", "dep:thiserror", "dep:aws-config"]
|
||||
sqs_trigger = ["dep:aws-sdk-sqs", "dep:aws-sdk-sts", "dep:aws-sdk-sso", "dep:aws-sdk-ssooidc", "dep:thiserror", "dep:aws-config", "dep:backon"]
|
||||
deno_core = ["dep:deno_core", "dep:deno_error"]
|
||||
gcp_trigger = ["dep:thiserror", "dep:google-cloud-pubsub", "dep:google-cloud-googleapis", "dep:tonic"]
|
||||
cloud = ["windmill-common/cloud"]
|
||||
@@ -138,13 +138,17 @@ rust_decimal = { workspace = true, optional = true }
|
||||
rust-postgres-native-tls = { workspace = true, optional = true}
|
||||
rumqttc = { workspace = true, optional = true }
|
||||
aws-sdk-sqs = { workspace = true, optional = true }
|
||||
aws-config = { workspace = true, optional = true }
|
||||
aws-sdk-sso = { workspace = true, optional = true }
|
||||
aws-sdk-ssooidc = { workspace = true, optional = true }
|
||||
aws-sdk-sts = { workspace = true, optional = true }
|
||||
rustls = { workspace = true }
|
||||
|
||||
aws-config = { workspace = true, optional = true }
|
||||
google-cloud-pubsub = { workspace = true, optional = true }
|
||||
google-cloud-googleapis = { workspace = true , optional = true }
|
||||
tonic = { workspace = true, optional = true }
|
||||
deno_error = { workspace = true, optional = true }
|
||||
deno_core = { workspace = true, optional = true }
|
||||
|
||||
backon = {workspace = true, optional = true}
|
||||
[build-dependencies]
|
||||
deno_core = { workspace = true, optional = true }
|
||||
@@ -1,7 +1,7 @@
|
||||
openapi: "3.0.3"
|
||||
|
||||
info:
|
||||
version: 1.507.1
|
||||
version: 1.515.1
|
||||
title: Windmill API
|
||||
|
||||
contact:
|
||||
@@ -2792,6 +2792,22 @@ paths:
|
||||
schema:
|
||||
type: string
|
||||
|
||||
/tokens/list/scopes:
|
||||
get:
|
||||
summary: list of available scopes
|
||||
operationId: ListAvailableScopes
|
||||
tags:
|
||||
- token
|
||||
responses:
|
||||
"200":
|
||||
description: list of available scopes
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
type: array
|
||||
items:
|
||||
$ref: "#/components/schemas/ScopeDomain"
|
||||
|
||||
/users/tokens/create:
|
||||
post:
|
||||
summary: create token
|
||||
@@ -3099,7 +3115,7 @@ paths:
|
||||
type: array
|
||||
items:
|
||||
$ref: "#/components/schemas/ContextualVariable"
|
||||
|
||||
|
||||
/w/{workspace}/workspaces/get_secondary_storage_names:
|
||||
get:
|
||||
summary: get secondary storage names
|
||||
@@ -3397,6 +3413,9 @@ paths:
|
||||
cc_client_secret:
|
||||
type: string
|
||||
description: "OAuth client secret for resource-level credentials (client_credentials flow only)"
|
||||
cc_token_url:
|
||||
type: string
|
||||
description: "OAuth token URL override for resource-level authentication (client_credentials flow only)"
|
||||
required:
|
||||
- expires_in
|
||||
- client
|
||||
@@ -3439,6 +3458,9 @@ paths:
|
||||
cc_client_secret:
|
||||
type: string
|
||||
description: "OAuth client secret for resource-level authentication"
|
||||
cc_token_url:
|
||||
type: string
|
||||
description: "OAuth token URL override for resource-level authentication"
|
||||
required:
|
||||
- cc_client_id
|
||||
- cc_client_secret
|
||||
@@ -5074,6 +5096,10 @@ paths:
|
||||
in: query
|
||||
schema:
|
||||
type: boolean
|
||||
- name: authed
|
||||
in: query
|
||||
schema:
|
||||
type: boolean
|
||||
responses:
|
||||
"200":
|
||||
description: script details
|
||||
@@ -7543,6 +7569,10 @@ paths:
|
||||
in: query
|
||||
schema:
|
||||
type: boolean
|
||||
- name: no_code
|
||||
in: query
|
||||
schema:
|
||||
type: boolean
|
||||
responses:
|
||||
"200":
|
||||
description: job details
|
||||
@@ -7644,7 +7674,43 @@ paths:
|
||||
progress:
|
||||
type: integer
|
||||
flow_status:
|
||||
$ref: "#/components/schemas/WorkflowStatusRecord"
|
||||
$ref: "../../openflow.openapi.yaml#/components/schemas/FlowStatus"
|
||||
workflow_as_code_status:
|
||||
$ref: "#/components/schemas/WorkflowStatus"
|
||||
|
||||
/w/{workspace}/jobs_u/getupdate_sse/{id}:
|
||||
get:
|
||||
summary: get job updates via server-sent events
|
||||
operationId: getJobUpdatesSSE
|
||||
tags:
|
||||
- job
|
||||
parameters:
|
||||
- $ref: "#/components/parameters/WorkspaceId"
|
||||
- $ref: "#/components/parameters/JobId"
|
||||
- name: running
|
||||
in: query
|
||||
schema:
|
||||
type: boolean
|
||||
- name: log_offset
|
||||
in: query
|
||||
schema:
|
||||
type: integer
|
||||
- name: get_progress
|
||||
in: query
|
||||
schema:
|
||||
type: boolean
|
||||
- name: only_result
|
||||
in: query
|
||||
schema:
|
||||
type: boolean
|
||||
|
||||
responses:
|
||||
"200":
|
||||
description: server-sent events stream of job updates
|
||||
content:
|
||||
text/event-stream:
|
||||
schema:
|
||||
type: string
|
||||
|
||||
/w/{workspace}/jobs_u/get_log_file/{path}:
|
||||
get:
|
||||
@@ -13822,20 +13888,27 @@ components:
|
||||
type: boolean
|
||||
on_behalf_of_email:
|
||||
type: string
|
||||
fallback_access_types:
|
||||
assets:
|
||||
type: array
|
||||
items:
|
||||
type: object
|
||||
required: [path, kind, access_type]
|
||||
required:
|
||||
- path
|
||||
- kind
|
||||
properties:
|
||||
path:
|
||||
type: string
|
||||
kind:
|
||||
type: string
|
||||
enum: [s3object, resource]
|
||||
enum:
|
||||
- s3object
|
||||
- resource
|
||||
access_type:
|
||||
type: string
|
||||
enum: [r, w, rw]
|
||||
alt_access_type:
|
||||
type: string
|
||||
enum: [r, w, rw]
|
||||
|
||||
required:
|
||||
- path
|
||||
@@ -13995,6 +14068,8 @@ components:
|
||||
the execution of this script will be permissioned_as and by extension its DT_TOKEN.
|
||||
flow_status:
|
||||
$ref: "../../openflow.openapi.yaml#/components/schemas/FlowStatus"
|
||||
workflow_as_code_status:
|
||||
$ref: "#/components/schemas/WorkflowStatus"
|
||||
raw_flow:
|
||||
$ref: "../../openflow.openapi.yaml#/components/schemas/FlowValue"
|
||||
is_flow_step:
|
||||
@@ -14102,6 +14177,8 @@ components:
|
||||
the execution of this script will be permissioned_as and by extension its DT_TOKEN.
|
||||
flow_status:
|
||||
$ref: "../../openflow.openapi.yaml#/components/schemas/FlowStatus"
|
||||
workflow_as_code_status:
|
||||
$ref: "#/components/schemas/WorkflowStatus"
|
||||
raw_flow:
|
||||
$ref: "../../openflow.openapi.yaml#/components/schemas/FlowValue"
|
||||
is_flow_step:
|
||||
@@ -14564,36 +14641,41 @@ components:
|
||||
- type: object
|
||||
properties:
|
||||
object:
|
||||
type: array
|
||||
items:
|
||||
type: object
|
||||
properties:
|
||||
key:
|
||||
type: string
|
||||
typ:
|
||||
oneOf:
|
||||
- type: string
|
||||
enum:
|
||||
[
|
||||
"float",
|
||||
"int",
|
||||
"bool",
|
||||
"email",
|
||||
"unknown",
|
||||
"bytes",
|
||||
"dict",
|
||||
"datetime",
|
||||
"sql",
|
||||
]
|
||||
- type: object
|
||||
properties:
|
||||
str: {}
|
||||
required: [str]
|
||||
required:
|
||||
- key
|
||||
- typ
|
||||
type: object
|
||||
properties:
|
||||
name:
|
||||
type: string
|
||||
props:
|
||||
type: array
|
||||
items:
|
||||
type: object
|
||||
properties:
|
||||
key:
|
||||
type: string
|
||||
typ:
|
||||
oneOf:
|
||||
- type: string
|
||||
enum:
|
||||
[
|
||||
"float",
|
||||
"int",
|
||||
"bool",
|
||||
"email",
|
||||
"unknown",
|
||||
"bytes",
|
||||
"dict",
|
||||
"datetime",
|
||||
"sql",
|
||||
]
|
||||
- type: object
|
||||
properties:
|
||||
str: {}
|
||||
required: [str]
|
||||
required:
|
||||
- key
|
||||
- typ
|
||||
required:
|
||||
- object
|
||||
- object
|
||||
- type: object
|
||||
properties:
|
||||
list:
|
||||
@@ -16737,6 +16819,39 @@ components:
|
||||
- edited_at
|
||||
- execution_mode
|
||||
|
||||
ScopeDefinition:
|
||||
type: object
|
||||
properties:
|
||||
value:
|
||||
type: string
|
||||
label:
|
||||
type: string
|
||||
description:
|
||||
type: string
|
||||
nullable: true
|
||||
requires_resource_path:
|
||||
type: boolean
|
||||
required:
|
||||
- value
|
||||
- label
|
||||
- requires_resource_path
|
||||
|
||||
ScopeDomain:
|
||||
type: object
|
||||
properties:
|
||||
name:
|
||||
type: string
|
||||
description:
|
||||
type: string
|
||||
nullable: true
|
||||
scopes:
|
||||
type: array
|
||||
items:
|
||||
$ref: "#/components/schemas/ScopeDefinition"
|
||||
required:
|
||||
- name
|
||||
- scopes
|
||||
|
||||
ListableRawApp:
|
||||
type: object
|
||||
properties:
|
||||
@@ -17556,7 +17671,6 @@ components:
|
||||
enum:
|
||||
- s3object
|
||||
- resource
|
||||
- variable
|
||||
Asset:
|
||||
type: object
|
||||
properties:
|
||||
|
||||
@@ -13,7 +13,7 @@ use crate::{
|
||||
db::{ApiAuthed, DB},
|
||||
resources::get_resource_value_interpolated_internal,
|
||||
users::{require_owner_of_path, OptAuthed},
|
||||
utils::WithStarredInfoQuery,
|
||||
utils::{check_scopes, WithStarredInfoQuery},
|
||||
webhook_util::{WebhookMessage, WebhookShared},
|
||||
HTTP_CLIENT,
|
||||
};
|
||||
@@ -444,6 +444,7 @@ async fn get_app(
|
||||
Query(query): Query<WithStarredInfoQuery>,
|
||||
) -> JsonResult<AppWithLastVersionAndStarred> {
|
||||
let path = path.to_path();
|
||||
check_scopes(&authed, || format!("apps:read:{}", path))?;
|
||||
let mut tx = user_db.begin(&authed).await?;
|
||||
|
||||
let app_o = if query.with_starred_info.unwrap_or(false) {
|
||||
@@ -491,6 +492,7 @@ async fn get_app_lite(
|
||||
Path((w_id, path)): Path<(String, StripPath)>,
|
||||
) -> JsonResult<AppWithLastVersion> {
|
||||
let path = path.to_path();
|
||||
check_scopes(&authed, || format!("apps:read:{}", path))?;
|
||||
let mut tx = user_db.begin(&authed).await?;
|
||||
|
||||
let app_o = sqlx::query_as::<_, AppWithLastVersion>(
|
||||
@@ -518,6 +520,7 @@ async fn get_app_w_draft(
|
||||
Path((w_id, path)): Path<(String, StripPath)>,
|
||||
) -> JsonResult<AppWithLastVersionAndDraft> {
|
||||
let path = path.to_path();
|
||||
check_scopes(&authed, || format!("apps:read:{}", path))?;
|
||||
let mut tx = user_db.begin(&authed).await?;
|
||||
|
||||
let app_o = sqlx::query_as::<_, AppWithLastVersionAndDraft>(
|
||||
@@ -547,6 +550,8 @@ async fn get_app_history(
|
||||
Extension(user_db): Extension<UserDB>,
|
||||
Path((w_id, path)): Path<(String, StripPath)>,
|
||||
) -> JsonResult<Vec<AppHistory>> {
|
||||
let path = path.to_path();
|
||||
check_scopes(&authed, || format!("apps:read:{}", &path))?;
|
||||
let mut tx = user_db.begin(&authed).await?;
|
||||
let query_result = sqlx::query!(
|
||||
"SELECT a.id as app_id, av.id as version_id, dm.deployment_msg as deployment_msg
|
||||
@@ -554,7 +559,7 @@ async fn get_app_history(
|
||||
WHERE a.workspace_id = $1 AND a.path = $2
|
||||
ORDER BY created_at DESC",
|
||||
w_id,
|
||||
path.to_path(),
|
||||
path,
|
||||
).fetch_all(&mut *tx).await?;
|
||||
tx.commit().await?;
|
||||
|
||||
@@ -574,6 +579,8 @@ async fn get_latest_version(
|
||||
Extension(user_db): Extension<UserDB>,
|
||||
Path((w_id, path)): Path<(String, StripPath)>,
|
||||
) -> JsonResult<Option<AppHistory>> {
|
||||
let path = path.to_path();
|
||||
check_scopes(&authed, || format!("apps:read:{}", path))?;
|
||||
let mut tx = user_db.begin(&authed).await?;
|
||||
let row = sqlx::query!(
|
||||
"SELECT a.id as app_id, av.id as version_id, dm.deployment_msg as deployment_msg
|
||||
@@ -581,7 +588,7 @@ async fn get_latest_version(
|
||||
WHERE a.workspace_id = $1 AND a.path = $2
|
||||
ORDER BY created_at DESC",
|
||||
w_id,
|
||||
path.to_path(),
|
||||
path,
|
||||
).fetch_optional(&mut *tx).await?;
|
||||
tx.commit().await?;
|
||||
|
||||
@@ -609,17 +616,19 @@ async fn update_app_history(
|
||||
.fetch_optional(&mut *tx)
|
||||
.await?;
|
||||
|
||||
if app_path.is_none() {
|
||||
let Some(app_path) = app_path else {
|
||||
tx.commit().await?;
|
||||
return Err(Error::NotFound(
|
||||
format!("App with ID {app_id} not found").to_string(),
|
||||
));
|
||||
}
|
||||
};
|
||||
|
||||
check_scopes(&authed, || format!("apps:write:{}", &app_path))?;
|
||||
|
||||
sqlx::query!(
|
||||
"INSERT INTO deployment_metadata (workspace_id, path, app_version, deployment_msg) VALUES ($1, $2, $3, $4) ON CONFLICT (workspace_id, path, app_version) WHERE app_version IS NOT NULL DO UPDATE SET deployment_msg = $4",
|
||||
w_id,
|
||||
app_path.unwrap(),
|
||||
app_path,
|
||||
app_version,
|
||||
app_history_update.deployment_msg,
|
||||
)
|
||||
@@ -664,6 +673,9 @@ async fn get_app_by_id(
|
||||
tx.commit().await?;
|
||||
|
||||
let app = not_found_if_none(app_o, "App", id.to_string())?;
|
||||
|
||||
check_scopes(&authed, || format!("apps:read:{}", &app.path))?;
|
||||
|
||||
Ok(Json(app))
|
||||
}
|
||||
|
||||
@@ -756,6 +768,7 @@ async fn get_secret_id(
|
||||
Path((w_id, path)): Path<(String, StripPath)>,
|
||||
) -> Result<String> {
|
||||
let path = path.to_path();
|
||||
check_scopes(&authed, || format!("apps:read:{}", path))?;
|
||||
let mut tx = user_db.begin(&authed).await?;
|
||||
|
||||
let id_o = sqlx::query_scalar!(
|
||||
@@ -861,6 +874,8 @@ async fn create_app_raw<'a>(
|
||||
)
|
||||
.await?;
|
||||
|
||||
check_scopes(&authed, || format!("apps:write:{}", path))?;
|
||||
|
||||
webhook.send_message(
|
||||
w_id.clone(),
|
||||
WebhookMessage::CreateApp { workspace: w_id, path: path.clone() },
|
||||
@@ -899,6 +914,8 @@ async fn create_app(
|
||||
Json(app): Json<CreateApp>,
|
||||
) -> Result<(StatusCode, String)> {
|
||||
let path = app.path.clone();
|
||||
check_scopes(&authed, || format!("apps:write:{}", &path))?;
|
||||
|
||||
let (new_tx, _path, _id) = create_app_internal(authed, db, user_db, &w_id, false, app).await?;
|
||||
|
||||
new_tx.commit().await?;
|
||||
@@ -1101,6 +1118,7 @@ async fn delete_app(
|
||||
Path((w_id, path)): Path<(String, StripPath)>,
|
||||
) -> Result<String> {
|
||||
let path = path.to_path();
|
||||
check_scopes(&authed, || format!("apps:write:{}", path))?;
|
||||
|
||||
if path == "g/all/setup_app" && w_id == "admins" {
|
||||
return Err(Error::BadRequest(
|
||||
@@ -1184,6 +1202,7 @@ async fn update_app(
|
||||
) -> Result<String> {
|
||||
// create_app_internal(authed, user_db, db, &w_id, &mut app).await?;
|
||||
let path = path.to_path();
|
||||
check_scopes(&authed, || format!("apps:write:{}", path))?;
|
||||
let opath = path.to_string();
|
||||
let (new_tx, npath, _v_id) =
|
||||
update_app_internal(authed, db, user_db, &w_id, path, false, ns).await?;
|
||||
@@ -1210,6 +1229,7 @@ async fn update_app_raw<'a>(
|
||||
multipart: Multipart,
|
||||
) -> Result<String> {
|
||||
let path = path.to_path();
|
||||
check_scopes(&authed, || format!("apps:write:{}", path))?;
|
||||
let opath = path.to_string();
|
||||
let (npath, _id) = process_app_multipart!(
|
||||
authed,
|
||||
@@ -2421,10 +2441,9 @@ async fn exists_app(
|
||||
Extension(db): Extension<DB>,
|
||||
Path((w_id, path)): Path<(String, StripPath)>,
|
||||
) -> JsonResult<bool> {
|
||||
let path = path.to_path();
|
||||
let exists = sqlx::query_scalar!(
|
||||
"SELECT EXISTS(SELECT 1 FROM app WHERE path = $1 AND workspace_id = $2)",
|
||||
path,
|
||||
path.to_path(),
|
||||
w_id
|
||||
)
|
||||
.fetch_one(&db)
|
||||
|
||||
@@ -22,6 +22,7 @@ use tokio::sync::RwLock;
|
||||
|
||||
use windmill_common::{
|
||||
auth::{get_folders_for_user, get_groups_for_user, JWTAuthClaims, TOKEN_PREFIX_LEN},
|
||||
error::Error,
|
||||
jwt,
|
||||
users::{COOKIE_NAME, SUPERADMIN_SECRET_EMAIL},
|
||||
};
|
||||
@@ -218,7 +219,9 @@ impl AuthCache {
|
||||
folders,
|
||||
scopes: None,
|
||||
username_override,
|
||||
token_prefix: Some(token[0..TOKEN_PREFIX_LEN].to_string()),
|
||||
token_prefix: Some(
|
||||
token[0..TOKEN_PREFIX_LEN].to_string(),
|
||||
),
|
||||
})
|
||||
} else {
|
||||
let groups = vec![name.to_string()];
|
||||
@@ -240,7 +243,9 @@ impl AuthCache {
|
||||
folders,
|
||||
scopes: None,
|
||||
username_override,
|
||||
token_prefix: Some(token[0..TOKEN_PREFIX_LEN].to_string()),
|
||||
token_prefix: Some(
|
||||
token[0..TOKEN_PREFIX_LEN].to_string(),
|
||||
),
|
||||
})
|
||||
}
|
||||
} else {
|
||||
@@ -303,7 +308,9 @@ impl AuthCache {
|
||||
folders,
|
||||
scopes,
|
||||
username_override,
|
||||
token_prefix: Some(token[0..TOKEN_PREFIX_LEN].to_string()),
|
||||
token_prefix: Some(
|
||||
token[0..TOKEN_PREFIX_LEN].to_string(),
|
||||
),
|
||||
})
|
||||
}
|
||||
None if super_admin => Some(ApiAuthed {
|
||||
@@ -315,7 +322,9 @@ impl AuthCache {
|
||||
folders: vec![],
|
||||
scopes,
|
||||
username_override,
|
||||
token_prefix: Some(token[0..TOKEN_PREFIX_LEN].to_string()),
|
||||
token_prefix: Some(
|
||||
token[0..TOKEN_PREFIX_LEN].to_string(),
|
||||
),
|
||||
}),
|
||||
None => None,
|
||||
}
|
||||
@@ -491,6 +500,33 @@ where
|
||||
}
|
||||
}
|
||||
|
||||
pub fn transform_old_scope_to_new_scope(scopes: Option<&mut Vec<String>>) {
|
||||
if let Some(scopes) = scopes {
|
||||
for scope in scopes.iter_mut() {
|
||||
if scope.starts_with("run:") {
|
||||
let (_, part_scope) = scope.split_once(":").unwrap();
|
||||
|
||||
if let Some((kind, path)) = part_scope.split_once("/") {
|
||||
//appending a 's' as runnable kind is singular while new scope format expect it to be plural
|
||||
*scope = format!("jobs:run:{}s:{}", kind, path);
|
||||
}
|
||||
} else if scope.starts_with("jobs:") {
|
||||
// Map old jobs scopes to new format
|
||||
let new_scope = match scope.as_str() {
|
||||
"jobs:listjobs" => "jobs:read",
|
||||
"jobs:runscript" => "jobs:run:scripts",
|
||||
"jobs:runflow" => "jobs:run:flows",
|
||||
"jobs:resumeflow" => "jobs:run:flows",
|
||||
"jobs:deletejob" => "jobs:write",
|
||||
_ => continue,
|
||||
};
|
||||
|
||||
*scope = new_scope.to_string();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn maybe_get_workspace_id_from_path(path_vec: &[&str]) -> Option<String> {
|
||||
let workspace_id = if path_vec.len() >= 4 && path_vec[0] == "" && path_vec[2] == "w" {
|
||||
Some(path_vec[3].to_owned())
|
||||
@@ -517,7 +553,7 @@ impl<S> FromRequestParts<S> for ApiAuthed
|
||||
where
|
||||
S: Send + Sync,
|
||||
{
|
||||
type Rejection = (StatusCode, String);
|
||||
type Rejection = Error;
|
||||
|
||||
async fn from_request_parts(
|
||||
parts: &mut Parts,
|
||||
@@ -538,7 +574,6 @@ where
|
||||
} else {
|
||||
extract_token(parts, state).await
|
||||
};
|
||||
|
||||
if let Some(token) = token_o {
|
||||
if let Ok(Extension(cache)) =
|
||||
Extension::<Arc<AuthCache>>::from_request_parts(parts, state).await
|
||||
@@ -551,21 +586,22 @@ where
|
||||
let path_vec: Vec<&str> = original_uri.path().split("/").collect();
|
||||
let workspace_id = maybe_get_workspace_id_from_path(&path_vec);
|
||||
|
||||
if let Some(authed) = cache.get_authed(workspace_id.clone(), &token).await {
|
||||
if authed.scopes.as_ref().is_some_and(|scopes| {
|
||||
scopes
|
||||
.iter()
|
||||
.any(|s| s.starts_with("jobs:") || s.starts_with("run:"))
|
||||
}) && (path_vec.len() < 3
|
||||
|| (path_vec[4] != "jobs" && path_vec[4] != "jobs_u"))
|
||||
{
|
||||
BRUTE_FORCE_COUNTER.increment().await;
|
||||
return Err((
|
||||
StatusCode::UNAUTHORIZED,
|
||||
format!("Unauthorized scoped token: {:?}", authed.scopes),
|
||||
));
|
||||
}
|
||||
if let Some(mut authed) = cache.get_authed(workspace_id.clone(), &token).await {
|
||||
if authed.scopes.is_some() {
|
||||
transform_old_scope_to_new_scope(authed.scopes.as_mut());
|
||||
|
||||
let path = original_uri.path();
|
||||
let method = parts.method.as_str();
|
||||
|
||||
if let Err(err) = crate::scopes::check_scopes_for_route(
|
||||
authed.scopes.as_deref(),
|
||||
path,
|
||||
method,
|
||||
) {
|
||||
BRUTE_FORCE_COUNTER.increment().await;
|
||||
return Err(err);
|
||||
}
|
||||
}
|
||||
parts.extensions.insert(authed.clone());
|
||||
|
||||
Span::current().record("username", &authed.username.as_str());
|
||||
@@ -579,7 +615,7 @@ where
|
||||
}
|
||||
}
|
||||
BRUTE_FORCE_COUNTER.increment().await;
|
||||
Err((StatusCode::UNAUTHORIZED, "Unauthorized".to_owned()))
|
||||
Err(Error::NotAuthorized("Unauthorized".to_string()))
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,9 +1,11 @@
|
||||
use crate::db::{ApiAuthed, DB};
|
||||
use crate::jobs::{
|
||||
filter_list_completed_query, filter_list_queue_query, Job, ListCompletedQuery, ListQueueQuery,
|
||||
UnifiedJob,
|
||||
use crate::{
|
||||
db::{ApiAuthed, DB},
|
||||
jobs::{
|
||||
filter_list_completed_query, filter_list_queue_query, Job, ListCompletedQuery,
|
||||
ListQueueQuery, UnifiedJob,
|
||||
},
|
||||
utils::check_scopes,
|
||||
};
|
||||
use crate::users::check_scopes;
|
||||
use axum::extract::Path;
|
||||
use axum::routing::{delete, get};
|
||||
use axum::{extract::Query, Extension, Json};
|
||||
@@ -144,7 +146,7 @@ async fn get_concurrent_intervals(
|
||||
Query(iq): Query<ExtendedJobsParams>,
|
||||
Query(lq): Query<ListCompletedQuery>,
|
||||
) -> JsonResult<ExtendedJobs> {
|
||||
check_scopes(&authed, || format!("jobs:listjobs"))?;
|
||||
check_scopes(&authed, || format!("jobs:read"))?;
|
||||
|
||||
if lq.success.is_some() && lq.running.is_some_and(|x| x) {
|
||||
return Err(error::Error::BadRequest(
|
||||
|
||||
@@ -18,10 +18,11 @@ use windmill_audit::audit_oss::audit_log;
|
||||
use windmill_audit::ActionKind;
|
||||
use windmill_common::{
|
||||
error::{self},
|
||||
worker::MIN_PERIODIC_SCRIPT_INTERVAL_SECONDS,
|
||||
DB,
|
||||
};
|
||||
|
||||
use crate::{db::ApiAuthed, utils::{require_devops_role}};
|
||||
use crate::{db::ApiAuthed, utils::require_devops_role};
|
||||
|
||||
pub fn global_service() -> Router {
|
||||
Router::new()
|
||||
@@ -129,6 +130,42 @@ async fn update_config(
|
||||
));
|
||||
}
|
||||
|
||||
if name.starts_with("worker__") {
|
||||
let periodic_script_bash = config
|
||||
.get("periodic_script_bash")
|
||||
.filter(|v| !v.is_null())
|
||||
.and_then(|v| v.as_str())
|
||||
.filter(|s| !s.is_empty());
|
||||
|
||||
let periodic_script_interval = config
|
||||
.get("periodic_script_interval_seconds")
|
||||
.filter(|v| !v.is_null());
|
||||
|
||||
match (periodic_script_bash, periodic_script_interval) {
|
||||
(Some(_), Some(interval_value)) => {
|
||||
if let Some(interval) = interval_value.as_u64() {
|
||||
if interval < MIN_PERIODIC_SCRIPT_INTERVAL_SECONDS {
|
||||
return Err(error::Error::BadRequest(format!(
|
||||
"Periodic script interval must be at least {} seconds, got {} seconds",
|
||||
MIN_PERIODIC_SCRIPT_INTERVAL_SECONDS, interval
|
||||
)));
|
||||
}
|
||||
} else {
|
||||
return Err(error::Error::BadRequest(
|
||||
"Periodic script interval must be a valid number".to_string(),
|
||||
));
|
||||
}
|
||||
}
|
||||
(Some(_), None) => {
|
||||
return Err(error::Error::BadRequest(
|
||||
"Periodic script interval must be specified when periodic script is configured"
|
||||
.to_string(),
|
||||
));
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
|
||||
let mut tx = db.begin().await?;
|
||||
sqlx::query!(
|
||||
"INSERT INTO config (name, config) VALUES ($1, $2) ON CONFLICT (name) DO UPDATE SET config = $2",
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user