windmill-cli 1.700.1 → 1.700.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (2) hide show
  1. package/esm/main.js +157 -105
  2. package/package.json +1 -1
package/esm/main.js CHANGED
@@ -16752,7 +16752,7 @@ var init_OpenAPI = __esm(() => {
16752
16752
  PASSWORD: undefined,
16753
16753
  TOKEN: getEnv3("WM_TOKEN"),
16754
16754
  USERNAME: undefined,
16755
- VERSION: "1.700.1",
16755
+ VERSION: "1.700.2",
16756
16756
  WITH_CREDENTIALS: true,
16757
16757
  interceptors: {
16758
16758
  request: new Interceptors,
@@ -84945,9 +84945,9 @@ name: raw-app
84945
84945
  description: MUST use when creating raw apps.
84946
84946
  ---
84947
84947
 
84948
- # Windmill Raw Apps
84948
+ # Windmill Raw Apps — CLI workflow
84949
84949
 
84950
- Raw apps let you build custom frontends with React, Svelte, or Vue that connect to Windmill backend runnables and datatables.
84950
+ This guide covers raw apps from the terminal: scaffolding via \`wmill app new\`, the on-disk layout, and the file-based conventions the CLI uses to represent backend runnables and data table configuration. The platform shape (how a raw app behaves at runtime — frontend bundling, runnable types, datatable SDK calls) is covered in the companion authoring guide.
84951
84951
 
84952
84952
  ## Creating a Raw App
84953
84953
 
@@ -85016,7 +85016,7 @@ wmill app new
85016
85016
 
85017
85017
  This is the wizard. It only works when run by a human in a real terminal. Don't call it this way from an agent.
85018
85018
 
85019
- ## App Structure
85019
+ ## On-disk app layout
85020
85020
 
85021
85021
  \`\`\`
85022
85022
  my_app{{RAW_APP_SUFFIX}}/
@@ -85036,11 +85036,7 @@ my_app{{RAW_APP_SUFFIX}}/
85036
85036
  └── *.sql # SQL files to apply via dev server
85037
85037
  \`\`\`
85038
85038
 
85039
- ## Backend Runnables
85040
-
85041
- Backend runnables are server-side scripts that your frontend can call. They live in the \`backend/\` folder.
85042
-
85043
- ### Creating a Backend Runnable
85039
+ ## Backend runnables on disk
85044
85040
 
85045
85041
  Add a code file to the \`backend/\` folder:
85046
85042
 
@@ -85050,7 +85046,7 @@ backend/<id>.<ext>
85050
85046
 
85051
85047
  The runnable ID is the filename without extension. For example, \`get_user.ts\` creates a runnable with ID \`get_user\`.
85052
85048
 
85053
- ### Supported Languages
85049
+ ### Supported languages (extension-driven)
85054
85050
 
85055
85051
  | Language | Extension | Example |
85056
85052
  |------------------|--------------|------------------|
@@ -85072,27 +85068,14 @@ The runnable ID is the filename without extension. For example, \`get_user.ts\`
85072
85068
  | C# | \`.cs\` | \`myFunc.cs\` |
85073
85069
  | Java | \`.java\` | \`myFunc.java\` |
85074
85070
 
85075
- ### Example Backend Runnable
85076
-
85077
- **backend/get_user.ts:**
85078
- \`\`\`typescript
85079
- import * as wmill from 'windmill-client';
85080
-
85081
- export async function main(user_id: string) {
85082
- const sql = wmill.datatable();
85083
- const user = await sql\`SELECT * FROM users WHERE id = \${user_id}\`.fetchOne();
85084
- return user;
85085
- }
85086
- \`\`\`
85087
-
85088
- After creating, tell the user they can generate lock files by running:
85071
+ After creating a runnable, tell the user they can generate lock files by running:
85089
85072
  \`\`\`bash
85090
85073
  wmill generate-metadata
85091
85074
  \`\`\`
85092
85075
 
85093
- ### Optional YAML Configuration
85076
+ ### Optional YAML configuration
85094
85077
 
85095
- Add a \`<id>.yaml\` file to configure fields or static values:
85078
+ Add a \`<id>.yaml\` file alongside the code to configure fields or static values:
85096
85079
 
85097
85080
  **backend/get_user.yaml:**
85098
85081
  \`\`\`yaml
@@ -85103,7 +85086,7 @@ fields:
85103
85086
  value: "default_user"
85104
85087
  \`\`\`
85105
85088
 
85106
- ### Referencing Existing Scripts
85089
+ ### Referencing existing scripts
85107
85090
 
85108
85091
  To use an existing Windmill script instead of inline code:
85109
85092
 
@@ -85119,32 +85102,9 @@ type: flow
85119
85102
  path: f/my_folder/my_flow
85120
85103
  \`\`\`
85121
85104
 
85122
- ### Calling Backend from Frontend
85123
-
85124
- Import from the auto-generated \`wmill.ts\`:
85105
+ ## Data tables \`raw_app.yaml\` config
85125
85106
 
85126
- \`\`\`typescript
85127
- import { backend } from './wmill';
85128
-
85129
- // Call a backend runnable
85130
- const user = await backend.get_user({ user_id: '123' });
85131
- \`\`\`
85132
-
85133
- The \`wmill.ts\` file provides type-safe access to all backend runnables.
85134
-
85135
- ## Data Tables
85136
-
85137
- Raw apps can query Windmill datatables (PostgreSQL databases managed by Windmill).
85138
-
85139
- ### Critical Rules
85140
-
85141
- 1. **ONLY USE WHITELISTED TABLES**: You can ONLY query tables listed in \`raw_app.yaml\` → \`data.tables\`. Tables not in this list are NOT accessible.
85142
-
85143
- 2. **ADD TABLES BEFORE USING**: To use a new table, first add it to \`data.tables\` in \`raw_app.yaml\`.
85144
-
85145
- 3. **USE CONFIGURED DATATABLE/SCHEMA**: Check the app's \`raw_app.yaml\` for the default datatable and schema.
85146
-
85147
- ### Configuration in raw_app.yaml
85107
+ The \`data\` block in \`raw_app.yaml\` controls which tables the app can query.
85148
85108
 
85149
85109
  \`\`\`yaml
85150
85110
  data:
@@ -85156,48 +85116,9 @@ data:
85156
85116
  \`\`\`
85157
85117
 
85158
85118
  **Table reference formats:**
85159
- - \`<datatable>\` - All tables in the datatable
85160
- - \`<datatable>/<table>\` - Specific table in public schema
85161
- - \`<datatable>/<schema>:<table>\` - Table in specific schema
85162
-
85163
- ### Querying in TypeScript (Bun/Deno)
85164
-
85165
- \`\`\`typescript
85166
- import * as wmill from 'windmill-client';
85167
-
85168
- export async function main(user_id: string) {
85169
- const sql = wmill.datatable(); // Or: wmill.datatable('other_datatable')
85170
-
85171
- // Parameterized queries (safe from SQL injection)
85172
- const user = await sql\`SELECT * FROM users WHERE id = \${user_id}\`.fetchOne();
85173
- const users = await sql\`SELECT * FROM users WHERE active = \${true}\`.fetch();
85174
-
85175
- // Insert/Update
85176
- await sql\`INSERT INTO users (name, email) VALUES (\${name}, \${email})\`;
85177
- await sql\`UPDATE users SET name = \${newName} WHERE id = \${user_id}\`;
85178
-
85179
- return user;
85180
- }
85181
- \`\`\`
85182
-
85183
- ### Querying in Python
85184
-
85185
- \`\`\`python
85186
- import wmill
85187
-
85188
- def main(user_id: str):
85189
- db = wmill.datatable() # Or: wmill.datatable('other_datatable')
85190
-
85191
- # Use $1, $2, etc. for parameters
85192
- user = db.query('SELECT * FROM users WHERE id = $1', user_id).fetch_one()
85193
- users = db.query('SELECT * FROM users WHERE active = $1', True).fetch()
85194
-
85195
- # Insert/Update
85196
- db.query('INSERT INTO users (name, email) VALUES ($1, $2)', name, email)
85197
- db.query('UPDATE users SET name = $1 WHERE id = $2', new_name, user_id)
85198
-
85199
- return user
85200
- \`\`\`
85119
+ - \`<datatable>\` All tables in the datatable
85120
+ - \`<datatable>/<table>\` Specific table in public schema
85121
+ - \`<datatable>/<schema>:<table>\` Table in specific schema
85201
85122
 
85202
85123
  ## SQL Migrations (sql_to_apply/)
85203
85124
 
@@ -85206,11 +85127,11 @@ The \`sql_to_apply/\` folder is for creating/modifying database tables during de
85206
85127
  ### Workflow
85207
85128
 
85208
85129
  1. Create \`.sql\` files in \`sql_to_apply/\`
85209
- 2. Run \`wmill app dev\` - the dev server watches this folder
85130
+ 2. Run \`wmill app dev\` the dev server watches this folder
85210
85131
  3. When SQL files change, a modal appears in the browser to confirm execution
85211
85132
  4. After creating tables, **add them to \`data.tables\`** in \`raw_app.yaml\`
85212
85133
 
85213
- ### Example Migration
85134
+ ### Example migration
85214
85135
 
85215
85136
  **sql_to_apply/001_create_users.sql:**
85216
85137
  \`\`\`sql
@@ -85229,12 +85150,12 @@ data:
85229
85150
  - main/users
85230
85151
  \`\`\`
85231
85152
 
85232
- ### Migration Best Practices
85153
+ ### Migration best practices
85233
85154
 
85234
85155
  - **Use idempotent SQL**: \`CREATE TABLE IF NOT EXISTS\`, etc.
85235
85156
  - **Number files**: \`001_\`, \`002_\` for ordering
85236
85157
  - **Always whitelist tables** after creation
85237
- - This folder is NOT synced - it's for local development only
85158
+ - This folder is NOT synced it's for local development only
85238
85159
 
85239
85160
  ## CLI Commands
85240
85161
 
@@ -85250,14 +85171,145 @@ For everything else, tell the user which command fits their intent and let them
85250
85171
  | \`wmill sync push\` | Deploy app to Windmill |
85251
85172
  | \`wmill sync pull\` | Pull latest from Windmill |
85252
85173
 
85174
+
85175
+
85176
+ # Windmill Raw Apps
85177
+
85178
+ Raw apps let you build custom frontends with React, Svelte, or Vue that connect to Windmill backend runnables and datatables.
85179
+
85180
+ ## App shape
85181
+
85182
+ A raw app has three logical parts:
85183
+
85184
+ - **Frontend** — bundled with esbuild from \`index.tsx\` as the entrypoint. Files include the entrypoint, components (\`App.tsx\`), styles, etc.
85185
+ - **Backend runnables** — server-side scripts the frontend calls, each addressed by a unique key.
85186
+ - **Data** — optional whitelisted datatables (managed PostgreSQL) that the backend runnables can query. The frontend never queries the database directly; backend runnables are the only bridge.
85187
+
85188
+ ## Frontend
85189
+
85190
+ ### Entrypoint
85191
+
85192
+ \`index.tsx\` is the bundling entrypoint. It typically renders a top-level \`App\` component. The bundler is esbuild.
85193
+
85194
+ ### Generated bindings (\`wmill.d.ts\` / \`wmill.ts\`)
85195
+
85196
+ The frontend imports a generated module that mirrors the backend runnables. **Never write to it directly** — it gets regenerated whenever backend runnables change. Modifying it by hand will be overwritten.
85197
+
85198
+ ### Calling backend runnables
85199
+
85200
+ Import the generated bindings and call the runnable like a function:
85201
+
85202
+ \`\`\`typescript
85203
+ import { backend } from './wmill';
85204
+
85205
+ // Call a backend runnable
85206
+ const user = await backend.get_user({ user_id: '123' });
85207
+ \`\`\`
85208
+
85209
+ The frontend cannot reach datatables, workspace items, or external services on its own — it goes through \`backend.<key>(args)\` for everything server-side.
85210
+
85211
+ ## Backend runnables
85212
+
85213
+ Each runnable has a unique key (used to call it from the frontend) and one of four types:
85214
+
85215
+ | Type | What it is |
85216
+ |---|---|
85217
+ | \`inline\` | Custom code stored on the app itself. Most common for app-specific logic. |
85218
+ | \`script\` | Reference to an existing workspace script by path. |
85219
+ | \`flow\` | Reference to an existing workspace flow by path. |
85220
+ | \`hubscript\` | Reference to a hub script by path. |
85221
+
85222
+ ### Inline runnables
85223
+
85224
+ Inline runnables carry their own source code. For file-based raw apps, the runnable language is determined by the backend file extension. The script must expose a \`main\` function as its entrypoint.
85225
+
85226
+ **TypeScript example** (\`backend/get_user.ts\`):
85227
+
85228
+ \`\`\`typescript
85229
+ import * as wmill from 'windmill-client';
85230
+
85231
+ export async function main(user_id: string) {
85232
+ const sql = wmill.datatable();
85233
+ const user = await sql\`SELECT * FROM users WHERE id = \${user_id}\`.fetchOne();
85234
+ return user;
85235
+ }
85236
+ \`\`\`
85237
+
85238
+ **Python example** (\`backend/get_user.py\`):
85239
+
85240
+ \`\`\`python
85241
+ import wmill
85242
+
85243
+ def main(user_id: str):
85244
+ db = wmill.datatable()
85245
+ user = db.query('SELECT * FROM users WHERE id = $1', user_id).fetch_one()
85246
+ return user
85247
+ \`\`\`
85248
+
85249
+ ### Path runnables (script / flow / hubscript)
85250
+
85251
+ When \`type\` is \`script\`, \`flow\`, or \`hubscript\`, the runnable just stores a \`path\` to an existing workspace or hub item — no inline code. The referenced item's input/output schema becomes the runnable's surface.
85252
+
85253
+ ### Static inputs
85254
+
85255
+ \`staticInputs\` is an optional \`Record<string, any>\` for arguments not overridable from the frontend. Useful with path runnables to pre-fill some args while leaving the rest to the frontend caller.
85256
+
85257
+ ## Data Tables
85258
+
85259
+ Data tables are PostgreSQL databases managed by Windmill. Backend runnables query them via the \`wmill\` client; the frontend never queries them directly.
85260
+
85261
+ ### Critical rules
85262
+
85263
+ 1. **Whitelisted tables only**: a runnable can only query tables listed in the app's \`data.tables\` config. Tables not in this list are not accessible.
85264
+ 2. **Add tables before using**: queries against unlisted tables fail at runtime. When you introduce a new table, register it in \`data.tables\` first.
85265
+ 3. **Use the configured datatable/schema**: the app's \`data\` config sets the default datatable and schema; reference them consistently across runnables.
85266
+
85267
+ ### Querying in TypeScript (Bun/Deno)
85268
+
85269
+ \`\`\`typescript
85270
+ import * as wmill from 'windmill-client';
85271
+
85272
+ export async function main(user_id: string) {
85273
+ const sql = wmill.datatable(); // Or: wmill.datatable('other_datatable')
85274
+
85275
+ // Parameterized queries (safe from SQL injection)
85276
+ const user = await sql\`SELECT * FROM users WHERE id = \${user_id}\`.fetchOne();
85277
+ const users = await sql\`SELECT * FROM users WHERE active = \${true}\`.fetch();
85278
+
85279
+ // Insert/Update
85280
+ await sql\`INSERT INTO users (name, email) VALUES (\${name}, \${email})\`;
85281
+ await sql\`UPDATE users SET name = \${newName} WHERE id = \${user_id}\`;
85282
+
85283
+ return user;
85284
+ }
85285
+ \`\`\`
85286
+
85287
+ ### Querying in Python
85288
+
85289
+ \`\`\`python
85290
+ import wmill
85291
+
85292
+ def main(user_id: str):
85293
+ db = wmill.datatable() # Or: wmill.datatable('other_datatable')
85294
+
85295
+ # Use $1, $2, etc. for parameters
85296
+ user = db.query('SELECT * FROM users WHERE id = $1', user_id).fetch_one()
85297
+ users = db.query('SELECT * FROM users WHERE active = $1', True).fetch()
85298
+
85299
+ # Insert/Update
85300
+ db.query('INSERT INTO users (name, email) VALUES ($1, $2)', name, email)
85301
+ db.query('UPDATE users SET name = $1 WHERE id = $2', new_name, user_id)
85302
+
85303
+ return user
85304
+ \`\`\`
85305
+
85253
85306
  ## Best Practices
85254
85307
 
85255
- 1. **Check DATATABLES.md** for existing tables before creating new ones
85256
- 2. **Use parameterized queries** - never concatenate user input into SQL
85257
- 3. **Keep runnables focused** - one function per file
85258
- 4. **Use descriptive IDs** - \`get_user.ts\` not \`a.ts\`
85259
- 5. **Always whitelist tables** - add to \`data.tables\` before querying
85260
- 6. **Generate locks** - tell the user to run \`wmill generate-metadata\` after adding/modifying backend runnables
85308
+ 1. **Check existing tables** before creating new ones — reuse beats schema growth.
85309
+ 2. **Use parameterized queries** never concatenate user input into SQL.
85310
+ 3. **Keep runnables focused** one function per runnable; small surface area.
85311
+ 4. **Use descriptive keys** \`get_user\`, not \`a\`.
85312
+ 5. **Always whitelist tables** adding a runnable that queries a new table requires the table to be in \`data.tables\` first.
85261
85313
  `,
85262
85314
  triggers: `---
85263
85315
  name: triggers
@@ -89624,7 +89676,7 @@ var config_default = command35;
89624
89676
 
89625
89677
  // src/main.ts
89626
89678
  await init_context();
89627
- var VERSION = "1.700.1";
89679
+ var VERSION = "1.700.2";
89628
89680
  async function checkVersionSafe(cmd) {
89629
89681
  const mainCommand = cmd.getMainCommand();
89630
89682
  const upgradeCommand = mainCommand.getCommand("upgrade");
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "windmill-cli",
3
- "version": "1.700.1",
3
+ "version": "1.700.2",
4
4
  "description": "CLI for Windmill",
5
5
  "license": "Apache 2.0",
6
6
  "type": "module",