@xanots/sdk 0.0.11 → 0.0.13

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 (100) hide show
  1. package/CHANGELOG.md +37 -0
  2. package/README.md +16 -9
  3. package/dist/.build-fingerprint +1 -1
  4. package/dist/{agent-file-refresh-QNKN5RYD.js → agent-file-refresh-GQWAAOBV.js} +4 -4
  5. package/dist/bin.js +11 -11
  6. package/dist/{branch-commands-2BLOC2GR.js → branch-commands-5KMPAAZV.js} +7 -7
  7. package/dist/bundle.d.ts +2 -2
  8. package/dist/bundle.js +2 -2
  9. package/dist/{capture-4WVJY4DQ.js → capture-YLUVAITI.js} +2 -2
  10. package/dist/{chunk-22TKBSDV.js → chunk-2AY3PKF4.js} +2 -2
  11. package/dist/chunk-2VTJSI6X.js +192 -0
  12. package/dist/{chunk-5XZ744TS.js → chunk-2ZCUO2UG.js} +1 -1
  13. package/dist/{chunk-XEOX6AM7.js → chunk-3LQGF2WS.js} +2 -2
  14. package/dist/{chunk-WP4OZZV4.js → chunk-3VFCKHOB.js} +2 -2
  15. package/dist/{chunk-XHEXOES3.js → chunk-5YDINUAP.js} +1 -1
  16. package/dist/{chunk-LU7TRWMC.js → chunk-6VNRMKFJ.js} +2 -2
  17. package/dist/{chunk-CTD5ZCV6.js → chunk-7WRJPKGK.js} +2 -2
  18. package/dist/{chunk-3INK4Y4E.js → chunk-AE3PDSDS.js} +1 -1
  19. package/dist/{chunk-DBFU47BJ.js → chunk-AOFFKSJC.js} +2 -2
  20. package/dist/{chunk-TCFIPDB3.js → chunk-AVGDL6RB.js} +1 -1
  21. package/dist/{chunk-UOZMSF4C.js → chunk-BYQHCCYU.js} +5 -5
  22. package/dist/{chunk-BC2C5GVI.js → chunk-DCMANKMX.js} +1 -1
  23. package/dist/{chunk-WHOJWOSV.js → chunk-EETVJZAZ.js} +1 -1
  24. package/dist/{chunk-VNQM3V2C.js → chunk-EXENFOWE.js} +2 -2
  25. package/dist/{chunk-AIZKXUNP.js → chunk-IMLYGQK6.js} +2 -2
  26. package/dist/{chunk-OWGCOGKK.js → chunk-MEFMTICH.js} +83 -8
  27. package/dist/{chunk-QK7ZQJLP.js → chunk-N74KDCBD.js} +39 -25
  28. package/dist/{chunk-3IGNIP6R.js → chunk-NDP7OUPS.js} +1 -1
  29. package/dist/{chunk-4Q7ZOHH7.js → chunk-OONT4ZL4.js} +3 -3
  30. package/dist/{chunk-EQW3YT5U.js → chunk-P6PVBQL6.js} +2 -2
  31. package/dist/{chunk-QYMAZRAU.js → chunk-PJNWOZMT.js} +5 -5
  32. package/dist/{chunk-BSK7ELHU.js → chunk-PR7OXHGZ.js} +1 -1
  33. package/dist/{chunk-RCT7UX7B.js → chunk-RLI6XD4O.js} +32 -27
  34. package/dist/{chunk-ZQ2PKR6R.js → chunk-RQ3FXV4K.js} +2 -2
  35. package/dist/{chunk-Q77KNEUL.js → chunk-RQNMTDXD.js} +1703 -2
  36. package/dist/{chunk-4IF54NU5.js → chunk-S3DOJOW4.js} +41 -21
  37. package/dist/{chunk-HYBN4H3F.js → chunk-SS2V2QOG.js} +27 -20
  38. package/dist/{chunk-QKM4U5UK.js → chunk-TJS2AF5Y.js} +2 -2
  39. package/dist/{chunk-DIA7CT7J.js → chunk-V5Y7D4LH.js} +11 -2
  40. package/dist/{chunk-KA6G2L7U.js → chunk-VK26K7AY.js} +3 -3
  41. package/dist/{chunk-VAF6A3YD.js → chunk-XWFRNJMQ.js} +1 -1
  42. package/dist/{chunk-7ZYW652H.js → chunk-YHS6VVLJ.js} +2 -2
  43. package/dist/{chunk-G4EJMQLD.js → chunk-YX22LKQE.js} +2 -2
  44. package/dist/{chunk-F6CYJ7TN.js → chunk-Z2ZIE5CO.js} +2 -2
  45. package/dist/cli.d.ts +13 -6
  46. package/dist/cli.js +10 -10
  47. package/dist/codegen-command-ZDHMGFWZ.js +47 -0
  48. package/dist/codegen.d.ts +5 -5
  49. package/dist/codegen.js +2 -2
  50. package/dist/{completion-WF46272M.js → completion-HJU5QEFB.js} +2 -2
  51. package/dist/{deploy-command-IP7V7GT4.js → deploy-command-CGVKRWUE.js} +19 -19
  52. package/dist/{ephemeral-command-U4AQ3TXX.js → ephemeral-command-2NKPEXUU.js} +8 -8
  53. package/dist/index.d.ts +88 -104
  54. package/dist/index.js +9 -9
  55. package/dist/init-command-DNDONP3O.js +32 -0
  56. package/dist/internal.d.ts +10 -16
  57. package/dist/internal.js +34 -34
  58. package/dist/{io-P2H75UV2.js → io-UBDMMDH6.js} +3 -3
  59. package/dist/{live-diff-IXKBVG4K.js → live-diff-HCOTN5WC.js} +3 -3
  60. package/dist/{lock-46FWYE4D.js → lock-HQ4KARU2.js} +2 -2
  61. package/dist/{lock-commands-ZZKZ4LZJ.js → lock-commands-6U7UIJGR.js} +11 -11
  62. package/dist/{login-command-Z6CHTA57.js → login-command-P7LXD5TE.js} +6 -6
  63. package/dist/{loop-D5NPL4VH.js → loop-IC5ISSYB.js} +3 -3
  64. package/dist/{marketplace-command-P4IPLJ6J.js → marketplace-command-T6JCHW7J.js} +4 -4
  65. package/dist/{meta-client-K2J4XH64.js → meta-client-LKRKR3L2.js} +4 -4
  66. package/dist/node.d.ts +6 -6
  67. package/dist/node.js +14 -14
  68. package/dist/{preflight-command-K346GPTY.js → preflight-command-UYE7SUQV.js} +16 -16
  69. package/dist/{profile-command-LJSBDV2L.js → profile-command-WBNSMQSI.js} +3 -3
  70. package/dist/{release-command-IMNTIVWK.js → release-command-CMMYT6XK.js} +26 -26
  71. package/dist/{response-BQVQ24l1.d.ts → response-D6xGLEIn.d.ts} +18 -23
  72. package/dist/{routes-manifest-PWZHDOI5.js → routes-manifest-MN6XBYRE.js} +25 -14
  73. package/dist/{runtime-V4C3AC3A.js → runtime-LSLIDALK.js} +1 -1
  74. package/dist/scaffold.d.ts +16 -8
  75. package/dist/scaffold.js +7 -11
  76. package/dist/{static-host-3WMV7IZO.js → static-host-4JDQCHUW.js} +1 -1
  77. package/dist/{status-command-AL47VG7H.js → status-command-VARULAR5.js} +4 -4
  78. package/dist/{store-BLyNeQ8S.d.ts → store-9Psd0jiF.d.ts} +115 -102
  79. package/dist/{test-command-YAZLKLGQ.js → test-command-YCAR4O35.js} +7 -7
  80. package/dist/{upgrade-command-BN3EHAOI.js → upgrade-command-A75DOIUH.js} +15 -16
  81. package/dist/{workspace-2COHDBM3.js → workspace-33KHFLX3.js} +2 -2
  82. package/dist/{workspace-command-MNK7Y7MQ.js → workspace-command-YELP47SJ.js} +26 -28
  83. package/dist/{workspace-export-DURY5WYL.js → workspace-export-MLYTYZS5.js} +3 -3
  84. package/dist/{xdo-BjJj5W_E.d.ts → xdo-ODuJklk6.d.ts} +27 -23
  85. package/guides/authoring.md +11 -2
  86. package/guides/typed-frontend.md +23 -6
  87. package/llms/kinds-realtime.md +2 -2
  88. package/llms/statements-data.md +3 -2
  89. package/llms/tests.md +1 -1
  90. package/llms/triggers.md +2 -2
  91. package/llms/values.md +1 -1
  92. package/llms-full.txt +26 -26
  93. package/llms.txt +17 -18
  94. package/manifest.json +6 -2
  95. package/package.json +1 -1
  96. package/dist/chunk-ANUDXFEX.js +0 -881
  97. package/dist/chunk-JGCWTCA7.js +0 -95
  98. package/dist/chunk-YBC3IKMF.js +0 -845
  99. package/dist/codegen-command-FUT2KJB6.js +0 -49
  100. package/dist/init-command-NPVL32L6.js +0 -34
@@ -13,7 +13,7 @@ import {
13
13
  reversedRegexOperands,
14
14
  stackReferencesAuth,
15
15
  tableColumns
16
- } from "./chunk-QK7ZQJLP.js";
16
+ } from "./chunk-N74KDCBD.js";
17
17
  import {
18
18
  CANONICAL_PAYLOAD_KEYS,
19
19
  REFERENCEABLE_KINDS,
@@ -26,7 +26,7 @@ import {
26
26
  mintCanonical,
27
27
  recordObserved,
28
28
  resolveRef
29
- } from "./chunk-VAF6A3YD.js";
29
+ } from "./chunk-XWFRNJMQ.js";
30
30
 
31
31
  // src/workspace/seed-coerce.ts
32
32
  function coerceScalarValue(label, column, type, value, values) {
@@ -777,6 +777,79 @@ function checkUnboundVarRefs(sections, bag) {
777
777
  }
778
778
  }
779
779
  }
780
+ function checkPasswordInputHashing(sections, bag) {
781
+ for (const [payloadKey, arr] of Object.entries(sections)) {
782
+ for (const obj of arr ?? []) {
783
+ if (!obj || typeof obj !== "object") continue;
784
+ const record = obj;
785
+ if (!Array.isArray(record.input)) continue;
786
+ const passwordInputs = /* @__PURE__ */ new Set();
787
+ for (const entry of record.input) {
788
+ const declared = entry;
789
+ if (typeof declared?.name === "string" && declared.type === "password") {
790
+ passwordInputs.add(declared.name);
791
+ }
792
+ }
793
+ if (passwordInputs.size === 0) continue;
794
+ const name = record.name;
795
+ const owner = `${payloadKey} "${typeof name === "string" ? name : "?"}"`;
796
+ const statements = [];
797
+ collectStatements(obj, statements);
798
+ const reported = /* @__PURE__ */ new Set();
799
+ for (const statement of statements) {
800
+ if (statement.name !== "mvp:check_pass") continue;
801
+ const cell = statementInput(statement, "text_password");
802
+ if (cell?.tag !== "input" || typeof cell.value !== "string") continue;
803
+ const declaredName = inputBase(cell.value);
804
+ if (!passwordInputs.has(declaredName)) continue;
805
+ if (reported.has(declaredName)) continue;
806
+ reported.add(declaredName);
807
+ bag.warn(
808
+ "stack.password-input-double-hash",
809
+ `${owner}: \`s.security.check_password\` reads \`inp("${cell.value}")\`, and the input \`${declaredName}\` is declared \`input.password()\`. That hashes the submission on bind, and the stored \`f.password()\` column hashed on write, so \`check_password\` compares two DIFFERENT hashes and a correct password always fails \u2014 the endpoint answers false on a row it found, which reads as a wrong credential. Declare it \`input.text()\` and pass the plaintext: \`check_password\` does the comparison hash itself.`
810
+ );
811
+ }
812
+ }
813
+ }
814
+ }
815
+ function checkToThrowScope(sections, bag) {
816
+ for (const [payloadKey, arr] of Object.entries(sections)) {
817
+ for (const obj of arr ?? []) {
818
+ if (!obj || typeof obj !== "object") continue;
819
+ const name = obj.name;
820
+ const owner = `${payloadKey} "${typeof name === "string" ? name : "?"}"`;
821
+ const all = [];
822
+ collectStatements(obj, all);
823
+ const toThrows = all.filter((st) => st.name === "mvp:test_expect_to_throw");
824
+ if (toThrows.length === 0) continue;
825
+ const boundAnywhere = collectBindings(all);
826
+ for (const toThrow of toThrows) {
827
+ const body = toThrow.context?.run;
828
+ if (!Array.isArray(body) || body.length === 0) continue;
829
+ const inside = [];
830
+ collectStatements(body, inside);
831
+ const boundInside = collectBindings(inside);
832
+ const refs = [];
833
+ collectVarRefs(body, refs);
834
+ const reported = /* @__PURE__ */ new Set();
835
+ for (const path of refs) {
836
+ const dot = path.indexOf(".");
837
+ const base = dot === -1 ? path : path.slice(0, dot);
838
+ if (base === "" || base.startsWith("$")) continue;
839
+ if (RESERVED_VAR_NAMESPACES[base]) continue;
840
+ if (boundInside.has(base)) continue;
841
+ if (!boundAnywhere.has(base)) continue;
842
+ if (reported.has(base)) continue;
843
+ reported.add(base);
844
+ bag.warn(
845
+ "stack.to-throw-isolated-var",
846
+ `${owner}: \`ref("${path}")\` inside an \`s.expect.to_throw\` body names \`${base}\`, which is bound OUTSIDE the body. \`to_throw\` runs its \`body\` in an ISOLATED var stack, so \`${base}\` is not visible in there: the body raises \`Missing var entry: ${base}\` before reaching the statement under test, and the test reports \`to_throw failed - expected "\u2026" not found in error "Missing var entry: ${base}"\` \u2014 which reads as the guard not firing. Bind what the body needs INSIDE the body, or pass the value as a literal.`
847
+ );
848
+ }
849
+ }
850
+ }
851
+ }
852
+ }
780
853
  var DB_MATCH_ARG = {
781
854
  "mvp:dbo_getby": "field_value",
782
855
  "mvp:dbo_delby": "field_value",
@@ -1411,7 +1484,7 @@ var Xano = class {
1411
1484
  }
1412
1485
  /**
1413
1486
  * Every def object handed to {@link register}, by identity, so the SAME one
1414
- * registered twice is caught at the call that did it (issue #54).
1487
+ * registered twice is caught at the call that did it.
1415
1488
  *
1416
1489
  * Identity, not structure. Two separately constructed defs sharing a name are
1417
1490
  * a genuine collision, and the guid check at export already diagnoses that
@@ -1448,7 +1521,7 @@ var Xano = class {
1448
1521
  * what `workspace("my-app")` set — so the natural chain
1449
1522
  * `workspace("my-app").registerWorkspace(workspaceConfig({ history }))` no
1450
1523
  * longer makes an author restate a name this registry has held since its
1451
- * first call (#228). An explicit `name` still wins, and a rename this way is
1524
+ * first call. An explicit `name` still wins, and a rename this way is
1452
1525
  * a rename of the workspace.
1453
1526
  */
1454
1527
  registerWorkspace(def) {
@@ -1576,7 +1649,7 @@ var Xano = class {
1576
1649
  * With `options.strict`, every build WARNING fails the export instead of
1577
1650
  * printing — the shapes that deploy clean and then lose data or return the
1578
1651
  * wrong rows. Nothing about the emitted bundle changes; it either exports or
1579
- * it does not (issue #15).
1652
+ * it does not.
1580
1653
  */
1581
1654
  export(options = {}) {
1582
1655
  const lockCtx = options.lock;
@@ -1617,6 +1690,8 @@ var Xano = class {
1617
1690
  checkRealtimeDeliver(this.bundleType, sections, bag);
1618
1691
  checkTriggerBindings(sections, bag);
1619
1692
  checkUnboundVarRefs(sections, bag);
1693
+ checkToThrowScope(sections, bag);
1694
+ checkPasswordInputHashing(sections, bag);
1620
1695
  checkSafeRefMatchArgs(sections, bag);
1621
1696
  checkNullMatchArgs(sections, bag);
1622
1697
  checkPathSegmentCandidates(sections, bag);
@@ -1686,7 +1761,7 @@ var Xano = class {
1686
1761
  }
1687
1762
  /**
1688
1763
  * Warn about an `auth()`-keyed middleware **directly attached** to a host where
1689
- * `auth()` may resolve to `null` (issue #81).
1764
+ * `auth()` may resolve to `null`.
1690
1765
  *
1691
1766
  * The footgun: a rate limiter keyed by `auth("id")` is the canonical middleware,
1692
1767
  * but attach it to a host with no authenticated caller and `auth()` silently
@@ -1701,7 +1776,7 @@ var Xano = class {
1701
1776
  * false positives on legitimate use. The warning names the host and reason so
1702
1777
  * the author can confirm intent, vary the key, or move to an authenticated host.
1703
1778
  *
1704
- * Scope: the host's EFFECTIVE chain, across all three tiers (issue #43). The
1779
+ * Scope: the host's EFFECTIVE chain, across all three tiers. The
1705
1780
  * guard used to see only a host's own `middleware.pre`/`post`, so an author who
1706
1781
  * DRY'd a per-user limiter up to `apiGroup({ middleware })` or to the workspace
1707
1782
  * tier silently reintroduced the shared bucket — the same collapse, attached
@@ -1858,4 +1933,4 @@ export {
1858
1933
  Xano,
1859
1934
  workspace
1860
1935
  };
1861
- //# sourceMappingURL=chunk-OWGCOGKK.js.map
1936
+ //# sourceMappingURL=chunk-MEFMTICH.js.map
@@ -2,7 +2,7 @@ import {
2
2
  assertPathParamInputs,
3
3
  fillPathParams,
4
4
  parsePathParams
5
- } from "./chunk-WHOJWOSV.js";
5
+ } from "./chunk-EETVJZAZ.js";
6
6
  import {
7
7
  appNamesByGuid,
8
8
  deriveGuid,
@@ -12,7 +12,7 @@ import {
12
12
  lockNameForObject,
13
13
  queryGroupComponent,
14
14
  resolveRef
15
- } from "./chunk-VAF6A3YD.js";
15
+ } from "./chunk-XWFRNJMQ.js";
16
16
  import {
17
17
  COLUMN_CONTEXT,
18
18
  INPUT_CONTEXT,
@@ -22,7 +22,7 @@ import {
22
22
  encodeStatement,
23
23
  rawResponseItems,
24
24
  registerStatement
25
- } from "./chunk-5XZ744TS.js";
25
+ } from "./chunk-2ZCUO2UG.js";
26
26
  import {
27
27
  sha1Bytes
28
28
  } from "./chunk-OHX6MIUZ.js";
@@ -139,7 +139,7 @@ var DiagnosticBag = class {
139
139
  * a guard. But the audience for this SDK is largely an agent that never reads
140
140
  * stderr, and CI has no way to notice a message nobody fails on. `strict`
141
141
  * gives a pipeline one switch that turns "printed something" into "did not
142
- * ship" (issue #15).
142
+ * ship".
143
143
  *
144
144
  * Scope: the diagnostics an EXPORT collects. A guard that runs while a
145
145
  * statement is being built ({@link emitDiagnostic}) has already had its say by
@@ -374,7 +374,7 @@ var c = {
374
374
  * A `number` that is not an integer, or is past `Number.MAX_SAFE_INTEGER`,
375
375
  * **throws**: by the time such a literal reaches here its precision is already
376
376
  * gone, so encoding it would write a value the caller did not type. The throw
377
- * names the string form. (issue #153)
377
+ * names the string form.
378
378
  */
379
379
  int(n) {
380
380
  return val(intLiteral(n), "const:int");
@@ -422,7 +422,7 @@ var c = {
422
422
  * null** the engine writes into a `db.*` statement's `@meta` slot —
423
423
  * `c.null("const:obj")` → `{tag:"const:obj", value:"null"}`, 16 of them across
424
424
  * eight ordinary queries in the survey corpus, which had no spelling and came
425
- * back as `rawValue` (issue #151).
425
+ * back as `rawValue`.
426
426
  *
427
427
  * ⚠ Not the same bytes as `c.obj(null)`, which is the BLANK object
428
428
  * (`value: ""`). Both evaluate to null — the engine JSON-decodes the stored
@@ -438,7 +438,7 @@ var c = {
438
438
  * (`fl.regex_test`/`regex_match`/`regex_replace`/…). Xano runs PHP `preg_*`, so
439
439
  * the pattern MUST be delimiter-wrapped — a bare `c.text("^…$")` is an invalid
440
440
  * PCRE and the filter then matches *nothing* for every input, so a precondition
441
- * built on it silently rejects all values (issue #128). This wraps the raw
441
+ * built on it silently rejects all values. This wraps the raw
442
442
  * pattern in `/…/`, escapes any interior `/`, and appends `flags`, so the result
443
443
  * is always valid; `withFilters` rejects a bare `c.text` pattern and points here.
444
444
  *
@@ -466,8 +466,13 @@ var c = {
466
466
  * `text("now") |to_epoch_ms` chain; both evaluate to the same epoch-ms number
467
467
  * on a live engine, and both persist verbatim, but the native tag is what the
468
468
  * editor writes and needs no filter to get there. Chain math onto it as usual:
469
- * `withFilters(c.now(), fl.epochms_add_ms(c.int(-maxAgeMs)))`. (issues #120,
470
- * #145)
469
+ * `withFilters(c.now(), fl.epochms_add_ms(c.int(-maxAgeMs)))`.
470
+ *
471
+ * Inside an `obj()` the tag is flattened into an expression string, where the
472
+ * identifier `now` alone is the STRING "now" — so `obj()` writes the
473
+ * `now|to_epochms` coercion that restores this tag's meaning. A `c.now()` used
474
+ * as a FILTER ARGUMENT there is refused: the coercion cannot be written in
475
+ * that position. Hoist it with `s.set_var` and `ref()` it.
471
476
  */
472
477
  now() {
473
478
  return val("now", "const:epochms");
@@ -478,7 +483,6 @@ var c = {
478
483
  * compile error and throws at runtime — it would serialize as internal
479
484
  * representation the engine can't decode. For a computed/multi-key object
480
485
  * response use a record of values (`response: { key: value }`), not `c.obj`.
481
- * See issue #42.
482
486
  *
483
487
  * Called with no argument it is the **empty object**, `{}` — the same default
484
488
  * the editor gives a new object variable, and the only empty form current
@@ -495,7 +499,7 @@ var c = {
495
499
  * same bytes instead of being quietly re-pointed at `{}`.
496
500
  *
497
501
  * A **populated** object is stored the way the editor stores one: an empty
498
- * `{}` base carrying one `set` filter per key (issue #248). It is NOT a
502
+ * `{}` base carrying one `set` filter per key. It is NOT a
499
503
  * populated JSON string — that form fails the request at runtime, see
500
504
  * {@link objSetFilters}.
501
505
  *
@@ -516,7 +520,7 @@ var c = {
516
520
  /**
517
521
  * Array constant → JSON-string value with `tag:"const:array"`. Takes **plain
518
522
  * JSON literals only** — like {@link obj}, a nested tagged value is a compile
519
- * error and throws at runtime. See issue #42.
523
+ * error and throws at runtime.
520
524
  */
521
525
  array(a) {
522
526
  assertPlainJson(a);
@@ -1350,7 +1354,7 @@ var f = {
1350
1354
  * bytes, and a map does not preserve it.
1351
1355
  *
1352
1356
  * Without this there is no way to author a structured JSON column at all
1353
- * (issue #135).
1357
+ *.
1354
1358
  */
1355
1359
  json(options = {}) {
1356
1360
  return descriptor("json", { ...options });
@@ -1420,9 +1424,8 @@ var f = {
1420
1424
  * instead: `f.tableRef("tweets", { type: "int" })`. Identity guids derive
1421
1425
  * from `(type, name)`, so the name form resolves to the same guid.
1422
1426
  *
1423
- * Byte-verified whole-object against a persisted table readback
1424
- * (`test/fixtures/tables/ex_field_table_ref.json`, asserted in
1425
- * `test/conformance/kinds-corpus.test.ts`): the `@` method carries
1427
+ * Byte-verified whole-object against a persisted table readback: the `@`
1428
+ * method carries
1426
1429
  * `disabled:false`, sits last in `methods`, and its `dbo=` arg is the target
1427
1430
  * table's payload guid.
1428
1431
  *
@@ -1469,7 +1472,7 @@ var input = {
1469
1472
  * password on **both** signup and login, let the `f.password` *column* hash on write,
1470
1473
  * and pass the plaintext straight to `check_password`. See the auth recipe in the
1471
1474
  * README. Reach for `input.password` only when you specifically want bind-time hashing
1472
- * and are not also comparing it with `check_password` (issue #109).
1475
+ * and are not also comparing it with `check_password`.
1473
1476
  */
1474
1477
  password: makeInput("password"),
1475
1478
  /**
@@ -1599,8 +1602,15 @@ var IDENT = /^[A-Za-z_$][A-Za-z0-9_$]*$/;
1599
1602
  function serializeValue(v2, path) {
1600
1603
  const record = objSetRecord(v2, path);
1601
1604
  if (record) return record;
1605
+ const nowExpr = serializeEpochMs(v2);
1606
+ if (nowExpr !== null) return nowExpr + serializeFilters(v2, path);
1602
1607
  return serializeAtom(v2, path) + serializeFilters(v2, path);
1603
1608
  }
1609
+ function serializeEpochMs(v2) {
1610
+ if (v2.tag !== "const:epochms") return null;
1611
+ if (v2.value !== "now") return null;
1612
+ return "now|to_epochms";
1613
+ }
1604
1614
  function objSetRecord(v2, path) {
1605
1615
  if (v2.tag !== "const:obj") return null;
1606
1616
  if (v2.value === "") {
@@ -1717,12 +1727,16 @@ function serializeAtom(v2, path) {
1717
1727
  // renders `$env.STRIPE_KEY`.
1718
1728
  case "setting":
1719
1729
  return `$env.${v2.value}`;
1720
- // The engine's native current-time constant. Only ever holds `"now"` the
1721
- // same narrowing the decoder makes so anything else falls through to the
1722
- // rejection rather than being rendered as a `now` it is not.
1730
+ // The engine's native current-time constant reaches this function ONLY as a
1731
+ // filter argumenta member position is answered by `serializeEpochMs`
1732
+ // above. There it is unwritable: the value needs a leading `|to_epochms` to
1733
+ // evaluate as a time at all (see `serializeEpochMs`), and inside an argument
1734
+ // a trailing `|` binds to the whole value rather than to the argument, which
1735
+ // is the same wall a pre-filtered argument hits.
1723
1736
  case "const:epochms":
1724
- if (v2.value === "now") return "now";
1725
- break;
1737
+ throw new Error(
1738
+ `obj(): \`${path}\` is \`c.now()\` used as a FILTER ARGUMENT. In an expression the current-time constant has to carry a \`|to_epochms\` coercion, and a \`|\` inside an argument binds to the whole value instead \u2014 so this cannot be written without changing what it means. Compute it in a prior step (\`s.set_var("now", c.now())\`) and reference it with \`ref("now")\`.`
1739
+ );
1726
1740
  // `c.array([…])` stores plain JSON, and the literal grammar spells the same
1727
1741
  // list — so it renders to the identical bytes a bare `[…]` member does. The
1728
1742
  // bare form always worked and this one used to throw, which made the empty
@@ -1801,7 +1815,7 @@ var slotted = (name, argNames, required, capped = true) => (...args) => {
1801
1815
  const hole = argNames.slice(0, last).findIndex((n) => named[n] === void 0);
1802
1816
  if (hole !== -1) {
1803
1817
  throw new Error(
1804
- `fl.${name}: \`${argNames[hole]}\` is omitted but \`${argNames[last]}\` is supplied. Filter arguments are positional even in this form \u2014 the engine reads them by slot, so one in the middle cannot be skipped. Supply \`${argNames[hole]}\` too. (issue #221)`
1818
+ `fl.${name}: \`${argNames[hole]}\` is omitted but \`${argNames[last]}\` is supplied. Filter arguments are positional even in this form \u2014 the engine reads them by slot, so one in the middle cannot be skipped. Supply \`${argNames[hole]}\` too.`
1805
1819
  );
1806
1820
  }
1807
1821
  assertArity(name, argNames, required, last + 1);
@@ -1810,7 +1824,7 @@ var slotted = (name, argNames, required, capped = true) => (...args) => {
1810
1824
  var assertArity = (name, argNames, required, got) => {
1811
1825
  if (got >= required) return;
1812
1826
  throw new Error(
1813
- `fl.${name} needs ${required} argument(s) \u2014 ${argNames.slice(0, required).join(", ")} \u2014 but got ${got}. Filter arguments are positional and the engine refuses a short call, so a missing one cannot be inferred \u2014 not even where the filter's own documentation calls it optional. Some filters accept omission from the END and some require every argument regardless; which is which is probed, not declared. (issues #221, #246)`
1827
+ `fl.${name} needs ${required} argument(s) \u2014 ${argNames.slice(0, required).join(", ")} \u2014 but got ${got}. Filter arguments are positional and the engine refuses a short call, so a missing one cannot be inferred \u2014 not even where the filter's own documentation calls it optional. Some filters accept omission from the END and some require every argument regardless; which is which is probed, not declared.`
1814
1828
  );
1815
1829
  };
1816
1830
  var assertMaxArity = (name, argNames, got) => {
@@ -4237,4 +4251,4 @@ export {
4237
4251
  serializeBundle,
4238
4252
  emitBundle
4239
4253
  };
4240
- //# sourceMappingURL=chunk-QK7ZQJLP.js.map
4254
+ //# sourceMappingURL=chunk-N74KDCBD.js.map
@@ -86,4 +86,4 @@ export {
86
86
  fetchReadOrExplain,
87
87
  retryingFetch
88
88
  };
89
- //# sourceMappingURL=chunk-3IGNIP6R.js.map
89
+ //# sourceMappingURL=chunk-NDP7OUPS.js.map
@@ -1,9 +1,9 @@
1
1
  import {
2
2
  compileBundle
3
- } from "./chunk-RCT7UX7B.js";
3
+ } from "./chunk-RLI6XD4O.js";
4
4
  import {
5
5
  missingArgument
6
- } from "./chunk-F6CYJ7TN.js";
6
+ } from "./chunk-Z2ZIE5CO.js";
7
7
 
8
8
  // src/emit/bundle-input.ts
9
9
  import { existsSync, readFileSync } from "fs";
@@ -34,4 +34,4 @@ export {
34
34
  assertBundleInput,
35
35
  loadBundleText
36
36
  };
37
- //# sourceMappingURL=chunk-4Q7ZOHH7.js.map
37
+ //# sourceMappingURL=chunk-OONT4ZL4.js.map
@@ -1,7 +1,7 @@
1
1
  import {
2
2
  describeTransportFailure,
3
3
  httpFailure
4
- } from "./chunk-3IGNIP6R.js";
4
+ } from "./chunk-NDP7OUPS.js";
5
5
 
6
6
  // src/deploy/branch.ts
7
7
  var BRANCH_TIMEOUT_MS = 3e4;
@@ -156,4 +156,4 @@ export {
156
156
  assertBranchAbsent,
157
157
  requireBranch
158
158
  };
159
- //# sourceMappingURL=chunk-EQW3YT5U.js.map
159
+ //# sourceMappingURL=chunk-P6PVBQL6.js.map
@@ -6,7 +6,7 @@ import {
6
6
  realtimeChannelGuid,
7
7
  realtimeServerRefName,
8
8
  resolveRealtimeServerRef
9
- } from "./chunk-UOZMSF4C.js";
9
+ } from "./chunk-BYQHCCYU.js";
10
10
  import {
11
11
  assertCanonical,
12
12
  assertOneOf,
@@ -25,17 +25,17 @@ import {
25
25
  resolveAuthRef,
26
26
  resolveMockKeys,
27
27
  warnLiveDatasource
28
- } from "./chunk-QK7ZQJLP.js";
28
+ } from "./chunk-N74KDCBD.js";
29
29
  import {
30
30
  deriveGuid,
31
31
  getLockedCanonical,
32
32
  lockKey,
33
33
  realtimeMessageSeedName,
34
34
  resolveRef
35
- } from "./chunk-VAF6A3YD.js";
35
+ } from "./chunk-XWFRNJMQ.js";
36
36
  import {
37
37
  encodeStatement
38
- } from "./chunk-5XZ744TS.js";
38
+ } from "./chunk-2ZCUO2UG.js";
39
39
 
40
40
  // src/kinds/canonical.ts
41
41
  function resolveCanonicalToken(label, payloadKey, accessor, def, override) {
@@ -667,4 +667,4 @@ export {
667
667
  addonKind,
668
668
  addon
669
669
  };
670
- //# sourceMappingURL=chunk-QYMAZRAU.js.map
670
+ //# sourceMappingURL=chunk-PJNWOZMT.js.map
@@ -67,4 +67,4 @@ export {
67
67
  SUPERSEDED_STATEMENTS,
68
68
  supersededBy
69
69
  };
70
- //# sourceMappingURL=chunk-BSK7ELHU.js.map
70
+ //# sourceMappingURL=chunk-PR7OXHGZ.js.map
@@ -1,10 +1,10 @@
1
1
  import {
2
2
  ENV_SPELLINGS
3
- } from "./chunk-CTD5ZCV6.js";
3
+ } from "./chunk-7WRJPKGK.js";
4
4
  import {
5
5
  readLockFile,
6
6
  writeLockFile
7
- } from "./chunk-XEOX6AM7.js";
7
+ } from "./chunk-3LQGF2WS.js";
8
8
  import {
9
9
  UsageError,
10
10
  extraArguments,
@@ -15,7 +15,7 @@ import {
15
15
  unknownFlag,
16
16
  unknownHelpTopic,
17
17
  unknownSubcommand
18
- } from "./chunk-F6CYJ7TN.js";
18
+ } from "./chunk-Z2ZIE5CO.js";
19
19
  import {
20
20
  detail,
21
21
  info,
@@ -26,13 +26,13 @@ import {
26
26
  Xano,
27
27
  assertSeedIds,
28
28
  coerceSeedRowValues
29
- } from "./chunk-OWGCOGKK.js";
29
+ } from "./chunk-MEFMTICH.js";
30
30
  import {
31
31
  getCommand,
32
32
  getSubcommand,
33
33
  isCommand,
34
34
  suggest
35
- } from "./chunk-DIA7CT7J.js";
35
+ } from "./chunk-V5Y7D4LH.js";
36
36
  import {
37
37
  FILTER_NAMES,
38
38
  KNOWLEDGE_DIR,
@@ -46,7 +46,7 @@ import {
46
46
  pathSegment,
47
47
  serializeBundle,
48
48
  tableColumns
49
- } from "./chunk-QK7ZQJLP.js";
49
+ } from "./chunk-N74KDCBD.js";
50
50
  import {
51
51
  WORKSPACE_KEY,
52
52
  createLockContext,
@@ -58,7 +58,7 @@ import {
58
58
  seedLockOverrides,
59
59
  serializeLock,
60
60
  validateLockModel
61
- } from "./chunk-VAF6A3YD.js";
61
+ } from "./chunk-XWFRNJMQ.js";
62
62
 
63
63
  // src/emit/cli.ts
64
64
  import { pathToFileURL as pathToFileURL3, fileURLToPath as fileURLToPath3 } from "url";
@@ -441,6 +441,7 @@ function parseArgs(argv) {
441
441
  let backupBranch;
442
442
  let emit2;
443
443
  let json = false;
444
+ let noRefresh = false;
444
445
  let open = false;
445
446
  const positionals = [];
446
447
  const positionalAt = [];
@@ -670,6 +671,8 @@ function parseArgs(argv) {
670
671
  } else if (arg.startsWith("--backup-branch=")) {
671
672
  const value = arg.slice("--backup-branch=".length);
672
673
  backupBranch = value === "" ? true : value;
674
+ } else if (arg === "--no-refresh") {
675
+ noRefresh = true;
673
676
  } else if (arg === "--json") {
674
677
  json = true;
675
678
  } else if (arg === "--open") {
@@ -785,6 +788,7 @@ function parseArgs(argv) {
785
788
  backupBranch,
786
789
  emit: emit2,
787
790
  json,
791
+ noRefresh,
788
792
  open,
789
793
  unknownFlags
790
794
  };
@@ -1004,11 +1008,11 @@ async function run(argv) {
1004
1008
  return;
1005
1009
  }
1006
1010
  if (command === "init") {
1007
- const { runInitCommand } = await import("./init-command-NPVL32L6.js");
1011
+ const { runInitCommand } = await import("./init-command-DNDONP3O.js");
1008
1012
  return runInitCommand(args);
1009
1013
  }
1010
1014
  if (command === "completion") {
1011
- const { isCompletionShell, runCompletionCommand, COMPLETION_SHELLS } = await import("./completion-WF46272M.js");
1015
+ const { isCompletionShell, runCompletionCommand, COMPLETION_SHELLS } = await import("./completion-HJU5QEFB.js");
1012
1016
  const shell = args.positionals[0];
1013
1017
  if (shell === void 0 || !isCompletionShell(shell)) {
1014
1018
  throw new UsageError(
@@ -1019,15 +1023,15 @@ async function run(argv) {
1019
1023
  return runCompletionCommand(shell);
1020
1024
  }
1021
1025
  if (command === "upgrade") {
1022
- const { runUpgradeCommand } = await import("./upgrade-command-BN3EHAOI.js");
1026
+ const { runUpgradeCommand } = await import("./upgrade-command-A75DOIUH.js");
1023
1027
  return runUpgradeCommand(args);
1024
1028
  }
1025
1029
  if (command === "lock") {
1026
- const { runLockCommand } = await import("./lock-commands-ZZKZ4LZJ.js");
1030
+ const { runLockCommand } = await import("./lock-commands-6U7UIJGR.js");
1027
1031
  return runLockCommand(args);
1028
1032
  }
1029
1033
  if (command === "login") {
1030
- const { runLoginCommand } = await import("./login-command-Z6CHTA57.js");
1034
+ const { runLoginCommand } = await import("./login-command-P7LXD5TE.js");
1031
1035
  return runLoginCommand(args);
1032
1036
  }
1033
1037
  if (command === "logout") {
@@ -1035,45 +1039,45 @@ async function run(argv) {
1035
1039
  return runLogoutCommand(args);
1036
1040
  }
1037
1041
  if (command === "deploy") {
1038
- const { runDeployCommand } = await import("./deploy-command-IP7V7GT4.js");
1042
+ const { runDeployCommand } = await import("./deploy-command-CGVKRWUE.js");
1039
1043
  return runDeployCommand(args);
1040
1044
  }
1041
1045
  if (command === "ephemeral") {
1042
- const { runEphemeralCommand } = await import("./ephemeral-command-U4AQ3TXX.js");
1046
+ const { runEphemeralCommand } = await import("./ephemeral-command-2NKPEXUU.js");
1043
1047
  return runEphemeralCommand(args);
1044
1048
  }
1045
1049
  if (command === "release") {
1046
- const { runReleaseCommand } = await import("./release-command-IMNTIVWK.js");
1050
+ const { runReleaseCommand } = await import("./release-command-CMMYT6XK.js");
1047
1051
  return runReleaseCommand(args);
1048
1052
  }
1049
1053
  if (command === "test") {
1050
- const { runTestCommand } = await import("./test-command-YAZLKLGQ.js");
1054
+ const { runTestCommand } = await import("./test-command-YCAR4O35.js");
1051
1055
  return runTestCommand(args);
1052
1056
  }
1053
1057
  if (command === "workspace") {
1054
- const { runWorkspaceCommand } = await import("./workspace-command-MNK7Y7MQ.js");
1058
+ const { runWorkspaceCommand } = await import("./workspace-command-YELP47SJ.js");
1055
1059
  return runWorkspaceCommand(args);
1056
1060
  }
1057
1061
  if (command === "status") {
1058
- const { runStatusCommand } = await import("./status-command-AL47VG7H.js");
1062
+ const { runStatusCommand } = await import("./status-command-VARULAR5.js");
1059
1063
  return runStatusCommand(args);
1060
1064
  }
1061
1065
  if (command === "whoami") {
1062
- const { runProfileCommand } = await import("./profile-command-LJSBDV2L.js");
1066
+ const { runProfileCommand } = await import("./profile-command-WBNSMQSI.js");
1063
1067
  return runProfileCommand(args);
1064
1068
  }
1065
1069
  if (command === "profile") {
1066
1070
  if (args.subcommand !== "me") {
1067
1071
  throw unknownSubcommand("profile", args.subcommand);
1068
1072
  }
1069
- const { runProfileCommand } = await import("./profile-command-LJSBDV2L.js");
1073
+ const { runProfileCommand } = await import("./profile-command-WBNSMQSI.js");
1070
1074
  return runProfileCommand(args);
1071
1075
  }
1072
1076
  if (command === "marketplace") {
1073
1077
  if (!["list", "search", "details", "install"].includes(args.subcommand ?? "")) {
1074
1078
  throw unknownSubcommand("marketplace", args.subcommand);
1075
1079
  }
1076
- const marketplace = await import("./marketplace-command-P4IPLJ6J.js");
1080
+ const marketplace = await import("./marketplace-command-T6JCHW7J.js");
1077
1081
  if (args.subcommand === "list") return marketplace.runMarketplaceListCommand(args);
1078
1082
  if (args.subcommand === "search") return marketplace.runMarketplaceSearchCommand(args);
1079
1083
  if (args.subcommand === "details") return marketplace.runMarketplaceDetailsCommand(args);
@@ -1083,7 +1087,7 @@ async function run(argv) {
1083
1087
  throw unknownCommand("push");
1084
1088
  }
1085
1089
  if (command === "preflight") {
1086
- const { runPreflightCommand } = await import("./preflight-command-K346GPTY.js");
1090
+ const { runPreflightCommand } = await import("./preflight-command-UYE7SUQV.js");
1087
1091
  return runPreflightCommand(args);
1088
1092
  }
1089
1093
  if (command !== "compile" && command !== "export" && command !== "paths" && command !== "routes") {
@@ -1113,9 +1117,10 @@ async function run(argv) {
1113
1117
  process.stdout.write(json + "\n");
1114
1118
  }
1115
1119
  }
1116
- async function refreshAgentGuidance() {
1120
+ async function refreshAgentGuidance(args) {
1121
+ if (args.noRefresh) return;
1117
1122
  try {
1118
- const { refreshAgentFiles } = await import("./agent-file-refresh-QNKN5RYD.js");
1123
+ const { refreshAgentFiles } = await import("./agent-file-refresh-GQWAAOBV.js");
1119
1124
  const refreshed = refreshAgentFiles({
1120
1125
  projectDir: process.cwd(),
1121
1126
  sdkVersion: readVersion()
@@ -1231,7 +1236,7 @@ async function runPaths(args) {
1231
1236
  return;
1232
1237
  }
1233
1238
  if (unresolved.length === 0) {
1234
- const { renderRouteManifest } = await import("./routes-manifest-PWZHDOI5.js");
1239
+ const { renderRouteManifest } = await import("./routes-manifest-MN6XBYRE.js");
1235
1240
  const source = renderRouteManifest(
1236
1241
  resolved.map((r) => ({ name: r.name, verb: r.verb, canonical: r.canonical })),
1237
1242
  describableServers.length > 0 ? { servers: describableServers, channels: channelRows } : void 0
@@ -1287,7 +1292,7 @@ async function compileBundle(args, opts = {}) {
1287
1292
  `--frozen-lock: no xano.lock found at ${lockPath}. Create one with \`xanots export ${file} --lock\` and commit it.`
1288
1293
  );
1289
1294
  }
1290
- await refreshAgentGuidance();
1295
+ await refreshAgentGuidance(args);
1291
1296
  const def = await loadDefault(file);
1292
1297
  if (!Xano.isXano(def)) {
1293
1298
  throw new Error(`Module "${file}" must default-export a Xano registry for \`export\`.`);
@@ -1348,4 +1353,4 @@ export {
1348
1353
  exportBundleJson,
1349
1354
  compileBundle
1350
1355
  };
1351
- //# sourceMappingURL=chunk-RCT7UX7B.js.map
1356
+ //# sourceMappingURL=chunk-RLI6XD4O.js.map
@@ -27,7 +27,7 @@ async function resolveMetaTarget(auth, selector, deps = {}) {
27
27
  case "workspace":
28
28
  return { base: auth.instance, workspaceId: auth.workspaceId, label: `workspace ${auth.workspaceId}` };
29
29
  case "ephemeral": {
30
- const resolveLive = deps.resolveLive ?? (await import("./ephemeral-command-U4AQ3TXX.js")).resolveLive;
30
+ const resolveLive = deps.resolveLive ?? (await import("./ephemeral-command-2NKPEXUU.js")).resolveLive;
31
31
  return resolveEphemeral(auth, selector.name, { ...deps, resolveLive });
32
32
  }
33
33
  }
@@ -37,4 +37,4 @@ export {
37
37
  resolveEphemeralName,
38
38
  resolveMetaTarget
39
39
  };
40
- //# sourceMappingURL=chunk-ZQ2PKR6R.js.map
40
+ //# sourceMappingURL=chunk-RQ3FXV4K.js.map