@xanots/sdk 0.0.1 → 0.0.3-beta.0

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 (59) hide show
  1. package/README.md +10 -1
  2. package/dist/.build-fingerprint +1 -0
  3. package/dist/{agent-file-refresh-7XCACU34.js → agent-file-refresh-J3KY54E5.js} +3 -2
  4. package/dist/bin.js +8 -8
  5. package/dist/chunk-4HKZH6YK.js +307 -0
  6. package/dist/{chunk-3DUAGYGP.js → chunk-55VHDNW5.js} +2 -2
  7. package/dist/{chunk-EMCAWMHC.js → chunk-5L4X5LS6.js} +16 -2
  8. package/dist/{chunk-LH6Z6KFV.js → chunk-5XZ744TS.js} +1 -1
  9. package/dist/chunk-6DHJVLYP.js +2044 -0
  10. package/dist/{chunk-TRU5OHQ5.js → chunk-CBL57QBQ.js} +53 -31
  11. package/dist/{chunk-5YTBTF25.js → chunk-EWFHDJY5.js} +2 -2
  12. package/dist/{chunk-MZUI3JNX.js → chunk-F6JCFRKO.js} +2 -2
  13. package/dist/{chunk-IZW6MK3U.js → chunk-FY6LXRR6.js} +2 -2
  14. package/dist/{chunk-NOO35BQ2.js → chunk-HKAX756N.js} +3 -3
  15. package/dist/{chunk-RVB7ITKN.js → chunk-LU7TRWMC.js} +2 -2
  16. package/dist/{chunk-33ND6LKO.js → chunk-MWLNBSTY.js} +2 -2
  17. package/dist/{chunk-26CNBZE2.js → chunk-P3TTMWUP.js} +13 -4
  18. package/dist/{chunk-YYRDLFSJ.js → chunk-QO4I5OYF.js} +40 -2
  19. package/dist/{chunk-YDZYMZBE.js → chunk-TQUO2OXY.js} +4 -4
  20. package/dist/{chunk-FJ6ZS5KB.js → chunk-U3G2UW65.js} +177 -60
  21. package/dist/{chunk-YGPIY3WT.js → chunk-VVXPK6SE.js} +64 -22
  22. package/dist/{chunk-VKFQJEMW.js → chunk-WRYT2PAX.js} +14 -371
  23. package/dist/{chunk-WKP4D5MO.js → chunk-YZ4GU6F5.js} +283 -252
  24. package/dist/cli.d.ts +22 -0
  25. package/dist/cli.js +8 -8
  26. package/dist/{codegen-command-OOKK6AZK.js → codegen-command-EXLKZ2ZI.js} +19 -17
  27. package/dist/codegen.js +2 -2
  28. package/dist/{completion-TIPPZN7H.js → completion-2PVZK6YX.js} +2 -2
  29. package/dist/{deploy-command-4EQ7XX5G.js → deploy-command-SXX6RJWM.js} +16 -16
  30. package/dist/{env-target-IFJ5QDHC.js → env-target-3EGIPR4D.js} +2 -2
  31. package/dist/{ephemeral-command-3X3I4ULC.js → ephemeral-command-OGOYP7D6.js} +15 -15
  32. package/dist/index.d.ts +106 -84
  33. package/dist/index.js +6 -6
  34. package/dist/{init-command-R6H7ZXW5.js → init-command-6DGXEVZD.js} +13 -11
  35. package/dist/internal.d.ts +2 -2
  36. package/dist/internal.js +29 -11
  37. package/dist/{live-diff-Y3AKETHE.js → live-diff-RXSJCVJ7.js} +2 -2
  38. package/dist/{lock-commands-XTR2YKLY.js → lock-commands-R22J54XV.js} +11 -11
  39. package/dist/{loop-OM3P2Z6O.js → loop-SAWAOUFO.js} +2 -2
  40. package/dist/{marketplace-command-RATXTKXN.js → marketplace-command-XJIWL4YP.js} +6 -6
  41. package/dist/meta-client-OW5WKWW7.js +1 -1
  42. package/dist/node.d.ts +2 -2
  43. package/dist/node.js +14 -14
  44. package/dist/{release-command-VV5UVZKL.js → release-command-6PLMLGDK.js} +20 -20
  45. package/dist/sandbox-export-command-QCJY4GMV.js +1 -1
  46. package/dist/scaffold.d.ts +1896 -0
  47. package/dist/scaffold.js +101 -0
  48. package/dist/{store-BQ97nKIF.d.ts → store-g45zwB33.d.ts} +91 -75
  49. package/dist/{test-command-TSPBQHBM.js → test-command-LLPXKT35.js} +4 -4
  50. package/dist/{validate-command-4ERHJSCO.js → validate-command-WAT3ZJT3.js} +11 -11
  51. package/dist/{workspace-command-OF23DPNI.js → workspace-command-JKMI7RZ4.js} +20 -18
  52. package/dist/workspace-export-AJMGN3CQ.js +1 -1
  53. package/llms/statements-calls.md +4 -4
  54. package/llms/statements-catalog.md +20 -20
  55. package/llms/statements-data.md +1 -1
  56. package/llms-full.txt +26 -26
  57. package/llms.txt +1 -1
  58. package/manifest.json +197 -84
  59. package/package.json +10 -1
package/README.md CHANGED
@@ -102,8 +102,17 @@ npx @xanots/sdk init my-app && cd my-app
102
102
  npm run dev # the frontend runs immediately
103
103
  ```
104
104
 
105
+ In a terminal it asks three questions — framework, theme, AI instruction files — each with a
106
+ default. The theme is shadcn's own: a base color plus an optional accent, rendered into the
107
+ token stylesheet, with a complete dark palette either way.
108
+
109
+ ```bash
110
+ npx @xanots/sdk init my-app --theme zinc-blue --dark toggle
111
+ npx @xanots/sdk init my-app --theme https://ui.shadcn.com/r/themes/slate.json # or any registry theme
112
+ ```
113
+
105
114
  The starter backend is empty but already compiles and deploys — grow it from the walkthrough
106
- in `xano/EXAMPLE.md`. For the flags, the two presets, and add-ons, see
115
+ in `xano/EXAMPLE.md`. For the flags, the two presets, theming, and add-ons, see
107
116
  [The scaffolded project](https://github.com/xanots/sdk/blob/main/guides/scaffold.md).
108
117
 
109
118
  **3. Build the frontend.**
@@ -0,0 +1 @@
1
+ f76d4016cad82dc8dd5a4715fbed070d613d1f69be8bda57ea3ca194658c21dd
@@ -5,8 +5,9 @@ import {
5
5
  presetFilePath,
6
6
  renderPreset,
7
7
  upsertManagedBlock
8
- } from "./chunk-VKFQJEMW.js";
8
+ } from "./chunk-WRYT2PAX.js";
9
9
  import "./chunk-47WDWMBJ.js";
10
+ import "./chunk-6DHJVLYP.js";
10
11
  import {
11
12
  warn
12
13
  } from "./chunk-EZG76F7R.js";
@@ -92,4 +93,4 @@ export {
92
93
  isCI,
93
94
  refreshAgentFiles
94
95
  };
95
- //# sourceMappingURL=agent-file-refresh-7XCACU34.js.map
96
+ //# sourceMappingURL=agent-file-refresh-J3KY54E5.js.map
package/dist/bin.js CHANGED
@@ -2,11 +2,12 @@
2
2
  import {
3
3
  readVersion,
4
4
  run
5
- } from "./chunk-YGPIY3WT.js";
5
+ } from "./chunk-VVXPK6SE.js";
6
6
  import {
7
7
  exitCodeOf,
8
8
  reportFailure
9
- } from "./chunk-IZW6MK3U.js";
9
+ } from "./chunk-FY6LXRR6.js";
10
+ import "./chunk-HJPTWBLH.js";
10
11
  import {
11
12
  blank,
12
13
  clearProgress,
@@ -15,15 +16,14 @@ import {
15
16
  style,
16
17
  warn
17
18
  } from "./chunk-EZG76F7R.js";
18
- import "./chunk-3DUAGYGP.js";
19
- import "./chunk-YYRDLFSJ.js";
20
- import "./chunk-EMCAWMHC.js";
21
- import "./chunk-WHOJWOSV.js";
22
- import "./chunk-LH6Z6KFV.js";
23
- import "./chunk-HJPTWBLH.js";
24
19
  import {
25
20
  atomicWrite
26
21
  } from "./chunk-GNPVYOPB.js";
22
+ import "./chunk-55VHDNW5.js";
23
+ import "./chunk-QO4I5OYF.js";
24
+ import "./chunk-5L4X5LS6.js";
25
+ import "./chunk-WHOJWOSV.js";
26
+ import "./chunk-5XZ744TS.js";
27
27
  import "./chunk-4HT3BNZ7.js";
28
28
 
29
29
  // src/emit/update-check.ts
@@ -0,0 +1,307 @@
1
+ import {
2
+ presetFilePath,
3
+ resolveAiPresets,
4
+ scaffoldProject
5
+ } from "./chunk-WRYT2PAX.js";
6
+ import {
7
+ DEFAULT_FRAMEWORK,
8
+ allFrontendPresets,
9
+ findFrontendPreset,
10
+ initLanding,
11
+ renderApiTs,
12
+ renderCnUtil,
13
+ renderEnvExample,
14
+ renderGitignore,
15
+ renderIndexCss,
16
+ renderIndexHtml,
17
+ renderPackageJson,
18
+ renderReadme,
19
+ renderThemeModule,
20
+ renderTsconfig,
21
+ renderViteConfig,
22
+ renderXanoExampleMd,
23
+ renderXanoIndex,
24
+ resolveFrameworkFlag
25
+ } from "./chunk-YZ4GU6F5.js";
26
+ import {
27
+ DEFAULT_DARK_MODE,
28
+ curatedThemes,
29
+ defaultTheme,
30
+ defaultThemeChoice,
31
+ normalizeRadius,
32
+ resolveDarkModeFlag,
33
+ resolveFontFlag,
34
+ resolveIconsFlag,
35
+ resolveThemeFlag,
36
+ themeFromRegistryItem,
37
+ themeSwatch,
38
+ withRadius
39
+ } from "./chunk-6DHJVLYP.js";
40
+ import {
41
+ readVersion
42
+ } from "./chunk-VVXPK6SE.js";
43
+ import {
44
+ blank,
45
+ detail,
46
+ info,
47
+ step,
48
+ style,
49
+ success
50
+ } from "./chunk-EZG76F7R.js";
51
+
52
+ // src/emit/init-command.ts
53
+ import { basename, resolve } from "path";
54
+
55
+ // src/emit/frontend-resolve.ts
56
+ import { createInterface } from "readline/promises";
57
+ function defaultFrontendPreset() {
58
+ const preset = findFrontendPreset(DEFAULT_FRAMEWORK);
59
+ if (preset === void 0) {
60
+ throw new Error(`Default frontend preset "${DEFAULT_FRAMEWORK}" is missing from the table.`);
61
+ }
62
+ return preset;
63
+ }
64
+ async function promptFramework() {
65
+ const presets = allFrontendPresets();
66
+ const rl = createInterface({ input: process.stdin, output: process.stderr });
67
+ try {
68
+ process.stderr.write(
69
+ `
70
+ Which frontend framework?
71
+ ` + presets.map((p, i) => ` ${i + 1}) ${p.label}${p.id === DEFAULT_FRAMEWORK ? " (default)" : ""}`).join("\n") + `
72
+ `
73
+ );
74
+ const answer = await rl.question(`Enter a number or name, or leave blank for the default: `);
75
+ const token = answer.trim().toLowerCase();
76
+ if (token === "") return defaultFrontendPreset();
77
+ const byIndex = Number.parseInt(token, 10);
78
+ if (Number.isInteger(byIndex) && byIndex >= 1 && byIndex <= presets.length) {
79
+ return presets[byIndex - 1];
80
+ }
81
+ return findFrontendPreset(token) ?? defaultFrontendPreset();
82
+ } finally {
83
+ rl.close();
84
+ }
85
+ }
86
+ async function resolveFrontendPreset(flag) {
87
+ if (flag !== void 0 && flag !== "") return resolveFrameworkFlag(flag);
88
+ if (process.stdin.isTTY && process.stderr.isTTY) return promptFramework();
89
+ return defaultFrontendPreset();
90
+ }
91
+
92
+ // src/emit/theme-resolve.ts
93
+ import { createInterface as createInterface2 } from "readline/promises";
94
+ import { readFileSync } from "fs";
95
+ import { resolve as resolvePath } from "path";
96
+ function isRegistryRef(value) {
97
+ return /^https?:\/\//i.test(value) || value.toLowerCase().endsWith(".json");
98
+ }
99
+ async function loadRegistryTheme(ref) {
100
+ if (/^https?:\/\//i.test(ref)) {
101
+ let res;
102
+ try {
103
+ res = await fetch(ref, { headers: { accept: "application/json" } });
104
+ } catch (err) {
105
+ throw new Error(
106
+ `Could not fetch the theme at ${ref}: ${err instanceof Error ? err.message : String(err)}`
107
+ );
108
+ }
109
+ if (!res.ok) throw new Error(`Could not fetch the theme at ${ref}: ${res.status} ${res.statusText}`);
110
+ const text2 = await res.text();
111
+ return themeFromRegistryItem(parseJson(text2, ref), ref);
112
+ }
113
+ const path = resolvePath(ref);
114
+ let text;
115
+ try {
116
+ text = readFileSync(path, "utf8");
117
+ } catch (err) {
118
+ throw new Error(
119
+ `Could not read the theme file ${path}: ${err instanceof Error ? err.message : String(err)}`
120
+ );
121
+ }
122
+ return themeFromRegistryItem(parseJson(text, path), path);
123
+ }
124
+ function parseJson(text, source) {
125
+ try {
126
+ return JSON.parse(text);
127
+ } catch {
128
+ throw new Error(`${source} is not valid JSON \u2014 a registry theme is a JSON registry item.`);
129
+ }
130
+ }
131
+ async function themeFromFlag(raw) {
132
+ return isRegistryRef(raw.trim()) ? loadRegistryTheme(raw.trim()) : resolveThemeFlag(raw);
133
+ }
134
+ function swatch(theme, color) {
135
+ if (!color) return "";
136
+ const blocks = themeSwatch(theme).map(({ r, g, b }) => `\x1B[38;2;${r};${g};${b}m\u2588\x1B[0m`).join("");
137
+ return blocks === "" ? "" : `${blocks} `;
138
+ }
139
+ function colorEnabled() {
140
+ if (process.env.FORCE_COLOR) return process.env.FORCE_COLOR !== "0";
141
+ return !process.env.NO_COLOR && process.stderr.isTTY === true;
142
+ }
143
+ async function promptTheme() {
144
+ const themes = curatedThemes();
145
+ const color = colorEnabled();
146
+ const rl = createInterface2({ input: process.stdin, output: process.stderr });
147
+ try {
148
+ process.stderr.write(
149
+ `
150
+ Which theme? (shadcn/ui color tokens \u2014 everything else is identical)
151
+ ` + themes.map((t, i) => ` ${i + 1}) ${swatch(t, color)}${t.label}${i === 0 ? " (default)" : ""}`).join("\n") + `
152
+ ${style.dim(
153
+ ` \u2026or any <base>-<accent> pair, or a registry theme URL. See \`xanots init --help\`.`
154
+ )}
155
+ `
156
+ );
157
+ for (; ; ) {
158
+ const answer = (await rl.question(`Enter a number, a theme, or leave blank for the default: `)).trim();
159
+ if (answer === "") return defaultTheme();
160
+ const byIndex = Number.parseInt(answer, 10);
161
+ if (Number.isInteger(byIndex) && byIndex >= 1 && byIndex <= themes.length) {
162
+ return themes[byIndex - 1];
163
+ }
164
+ if (!isRegistryRef(answer)) {
165
+ try {
166
+ return resolveThemeFlag(answer);
167
+ } catch {
168
+ return defaultTheme();
169
+ }
170
+ }
171
+ try {
172
+ return await loadRegistryTheme(answer);
173
+ } catch (err) {
174
+ process.stderr.write(`${style.yellow("!")} ${err instanceof Error ? err.message : String(err)}
175
+ `);
176
+ }
177
+ }
178
+ } finally {
179
+ rl.close();
180
+ }
181
+ }
182
+ async function resolveThemeChoice(args) {
183
+ const dark = args.dark === void 0 || args.dark === "" ? DEFAULT_DARK_MODE : resolveDarkModeFlag(args.dark);
184
+ const fonts = {
185
+ ...args.font !== void 0 && args.font !== "" ? { sans: resolveFontFlag(args.font, "sans") } : {},
186
+ ...args.fontMono !== void 0 && args.fontMono !== "" ? { mono: resolveFontFlag(args.fontMono, "mono") } : {},
187
+ ...args.fontHeading !== void 0 && args.fontHeading !== "" ? { heading: resolveFontFlag(args.fontHeading, "heading") } : {}
188
+ };
189
+ const icons = args.icons === void 0 || args.icons === "" ? void 0 : resolveIconsFlag(args.icons).id;
190
+ let theme;
191
+ if (args.theme !== void 0 && args.theme !== "") {
192
+ theme = await themeFromFlag(args.theme);
193
+ } else if (process.stdin.isTTY && process.stderr.isTTY) {
194
+ theme = await promptTheme();
195
+ } else {
196
+ theme = defaultThemeChoice().theme;
197
+ }
198
+ if (args.radius !== void 0 && args.radius !== "") {
199
+ theme = withRadius(theme, normalizeRadius(args.radius));
200
+ }
201
+ return {
202
+ theme,
203
+ dark,
204
+ ...Object.keys(fonts).length === 0 ? {} : { fonts },
205
+ ...icons === void 0 ? {} : { icons }
206
+ };
207
+ }
208
+
209
+ // src/emit/init-command.ts
210
+ function sanitizeAppName(raw) {
211
+ const name = raw.toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/^-+|-+$/g, "");
212
+ return name === "" ? "app" : name;
213
+ }
214
+ function projectShellFiles(vars, preset, parts, choice = defaultThemeChoice()) {
215
+ return [
216
+ { path: "package.json", content: renderPackageJson(vars, preset, choice) },
217
+ { path: "tsconfig.json", content: renderTsconfig(preset) },
218
+ { path: "vite.config.ts", content: renderViteConfig(preset) },
219
+ { path: ".gitignore", content: renderGitignore(preset) },
220
+ { path: ".env.example", content: renderEnvExample() },
221
+ { path: "README.md", content: parts.readme },
222
+ // Skipped when the framework supplies its own entry document — see
223
+ // FrontendPreset.ownsHtmlEntry. A second index.html beside SvelteKit's
224
+ // app.html would never be served and would still read as the entry point.
225
+ ...preset.ownsHtmlEntry === true ? [] : [{ path: "frontend/index.html", content: renderIndexHtml(vars, preset, choice) }],
226
+ // Shared across every framework: both UI kits resolve against the same
227
+ // Tailwind v4 semantic tokens, back `cn()` with clsx + tailwind-merge, and
228
+ // look for library code at frontend/src/lib/. Only the alias NAME pointing
229
+ // at that directory differs, and the preset owns that.
230
+ { path: "frontend/src/index.css", content: renderIndexCss(choice) },
231
+ { path: "frontend/src/lib/api.ts", content: renderApiTs() },
232
+ { path: "frontend/src/lib/utils.ts", content: renderCnUtil(preset.libUtilsExtra) },
233
+ // The mode store behind `--dark toggle`, shared by both presets' toggles —
234
+ // it is plain DOM and localStorage, with nothing framework-shaped in it.
235
+ // `system` and `off` need no state, so nothing is written for them.
236
+ ...choice.dark === "toggle" ? [{ path: "frontend/src/lib/theme.ts", content: renderThemeModule() }] : [],
237
+ // The framework's own half: entry module, app component, vendored UI kit,
238
+ // and whatever tool config that kit's CLI reads.
239
+ ...preset.files(vars, parts.landing, choice)
240
+ ];
241
+ }
242
+ function buildFileSet(vars, preset, choice) {
243
+ return [
244
+ ...projectShellFiles(
245
+ vars,
246
+ preset,
247
+ { readme: renderReadme(vars, preset, choice), landing: initLanding(vars) },
248
+ choice
249
+ ),
250
+ { path: "xano/index.ts", content: renderXanoIndex(vars) },
251
+ { path: "xano/EXAMPLE.md", content: renderXanoExampleMd(vars) }
252
+ ];
253
+ }
254
+ async function runInitCommand(args) {
255
+ const targetArg = args.positionals[0] ?? ".";
256
+ const targetDir = resolve(targetArg);
257
+ const appName = sanitizeAppName(args.name ?? basename(targetDir));
258
+ const preset = await resolveFrontendPreset(args.framework);
259
+ const choice = await resolveThemeChoice(args);
260
+ const presets = await resolveAiPresets(args.ai);
261
+ const vars = { appName, sdkVersion: readVersion() };
262
+ step(
263
+ `Scaffolding ${style.bold(appName)} (${preset.label}, ${choice.theme.label}) in ${targetDir}`
264
+ );
265
+ const result = await scaffoldProject({
266
+ targetDir,
267
+ files: buildFileSet(vars, preset, choice),
268
+ presets,
269
+ appName,
270
+ force: args.force,
271
+ noInstall: args.noInstall,
272
+ // An `init` project's `xano/` is hand-authored, never machine-written: it is
273
+ // not refreshable, and `--force` must not clear it.
274
+ regenerable: false,
275
+ sdkVersion: readVersion(),
276
+ frontend: preset,
277
+ theme: choice
278
+ });
279
+ info(`Theme: ${choice.theme.label} \u2014 dark mode: ${choice.dark}`);
280
+ if (presets.length > 0) {
281
+ info(`AI instructions: ${presets.map(presetFilePath).join(", ")}`);
282
+ }
283
+ blank();
284
+ success("Project ready.");
285
+ const cdHint = targetDir === process.cwd() ? "" : ` cd ${targetArg}
286
+ `;
287
+ detail(
288
+ `Next steps:
289
+ ` + cdHint + (result.install === "installed" ? `` : ` npm install
290
+ `) + ` npm run dev # run the frontend
291
+ xanots login # authenticate with Xano
292
+ npm run xano:deploy # build the frontend, then deploy \u2192 live ephemeral URL
293
+
294
+ The first export or deploy writes xano/xano.lock \u2014 commit it. It pins each
295
+ object's identity, so renaming one later renames it instead of deleting and
296
+ recreating it. See "xano.lock \u2014 commit it" in the README.`
297
+ );
298
+ }
299
+
300
+ export {
301
+ resolveFrontendPreset,
302
+ resolveThemeChoice,
303
+ sanitizeAppName,
304
+ projectShellFiles,
305
+ runInitCommand
306
+ };
307
+ //# sourceMappingURL=chunk-4HKZH6YK.js.map
@@ -12,7 +12,7 @@ import {
12
12
  middlewareEntryGuid,
13
13
  stackReferencesAuth,
14
14
  tableColumns
15
- } from "./chunk-EMCAWMHC.js";
15
+ } from "./chunk-5L4X5LS6.js";
16
16
  import {
17
17
  CANONICAL_PAYLOAD_KEYS,
18
18
  REFERENCEABLE_KINDS,
@@ -1547,4 +1547,4 @@ export {
1547
1547
  Xano,
1548
1548
  workspace
1549
1549
  };
1550
- //# sourceMappingURL=chunk-3DUAGYGP.js.map
1550
+ //# sourceMappingURL=chunk-55VHDNW5.js.map
@@ -12,7 +12,7 @@ import {
12
12
  encodeStatement,
13
13
  rawResponseItems,
14
14
  registerStatement
15
- } from "./chunk-LH6Z6KFV.js";
15
+ } from "./chunk-5XZ744TS.js";
16
16
  import {
17
17
  deriveGuid,
18
18
  getLockedCanonical,
@@ -2777,6 +2777,15 @@ function encodeComparison(when) {
2777
2777
  return encodeExpression(when);
2778
2778
  }
2779
2779
 
2780
+ // src/statements/args.ts
2781
+ function argsOrEmpty(a) {
2782
+ return a ?? {};
2783
+ }
2784
+ function assertArg(statement, name, v2) {
2785
+ if (v2 === void 0)
2786
+ throw new Error(`Statement "${statement}": required argument "${name}" is missing.`);
2787
+ }
2788
+
2780
2789
  // src/statements/conditional.ts
2781
2790
  var CONDITIONAL = "mvp:conditional";
2782
2791
  var CONDITIONAL_ELIF = "mvp:conditional_elif";
@@ -2788,6 +2797,9 @@ function conditionalElif(args) {
2788
2797
  return annotate({ name: CONDITIONAL_ELIF, context, input: [] }, args);
2789
2798
  }
2790
2799
  function conditional(args) {
2800
+ args = argsOrEmpty(args);
2801
+ assertArg(CONDITIONAL, "when", args.when);
2802
+ assertArg(CONDITIONAL, "then", args.then);
2791
2803
  const context = {
2792
2804
  expr: encodeRuntimeCondition(args.when, "s.conditional `when`"),
2793
2805
  if: { run: args.then.map(encodeStatement) },
@@ -3903,6 +3915,8 @@ export {
3903
3915
  FILTER_SPECS,
3904
3916
  FILTER_REQUIRED_ARGS,
3905
3917
  fl,
3918
+ argsOrEmpty,
3919
+ assertArg,
3906
3920
  expr,
3907
3921
  isSearchOp,
3908
3922
  cmp,
@@ -3979,4 +3993,4 @@ export {
3979
3993
  serializeBundle,
3980
3994
  emitBundle
3981
3995
  };
3982
- //# sourceMappingURL=chunk-EMCAWMHC.js.map
3996
+ //# sourceMappingURL=chunk-5L4X5LS6.js.map
@@ -244,4 +244,4 @@ export {
244
244
  rawResponse,
245
245
  rawResponseItems
246
246
  };
247
- //# sourceMappingURL=chunk-LH6Z6KFV.js.map
247
+ //# sourceMappingURL=chunk-5XZ744TS.js.map