@lovrozagar/oat 0.1.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 (145) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +401 -0
  3. package/bin/oat.js +2 -0
  4. package/dist/cli.js +386 -0
  5. package/dist/config/define-config.d.ts +165 -0
  6. package/dist/config/define-config.d.ts.map +1 -0
  7. package/dist/config/define-config.js +24 -0
  8. package/dist/config/define-config.js.map +1 -0
  9. package/dist/config/load.d.ts +10 -0
  10. package/dist/config/load.d.ts.map +1 -0
  11. package/dist/config/load.js +61 -0
  12. package/dist/config/load.js.map +1 -0
  13. package/dist/index.d.ts +17 -0
  14. package/dist/index.js +9 -0
  15. package/dist/reference/defects.d.ts +254 -0
  16. package/dist/reference/defects.d.ts.map +1 -0
  17. package/dist/reference/defects.js +265 -0
  18. package/dist/reference/defects.js.map +1 -0
  19. package/dist/reference/dialect.d.ts +104 -0
  20. package/dist/reference/dialect.d.ts.map +1 -0
  21. package/dist/reference/dialect.js +174 -0
  22. package/dist/reference/dialect.js.map +1 -0
  23. package/dist/reference/http.d.ts +79 -0
  24. package/dist/reference/http.d.ts.map +1 -0
  25. package/dist/reference/http.js +889 -0
  26. package/dist/reference/http.js.map +1 -0
  27. package/dist/reference/model.d.ts +56 -0
  28. package/dist/reference/model.d.ts.map +1 -0
  29. package/dist/reference/model.js +156 -0
  30. package/dist/reference/model.js.map +1 -0
  31. package/dist/reference/query.d.ts +45 -0
  32. package/dist/reference/query.d.ts.map +1 -0
  33. package/dist/reference/query.js +353 -0
  34. package/dist/reference/query.js.map +1 -0
  35. package/dist/reference/spec.d.ts +13 -0
  36. package/dist/reference/spec.d.ts.map +1 -0
  37. package/dist/reference/spec.js +547 -0
  38. package/dist/reference/spec.js.map +1 -0
  39. package/dist/reference/store-api.d.ts +59 -0
  40. package/dist/reference/store-api.d.ts.map +1 -0
  41. package/dist/reference/store-api.js +76 -0
  42. package/dist/reference/store-api.js.map +1 -0
  43. package/dist/reference/stores/memory.d.ts +27 -0
  44. package/dist/reference/stores/memory.d.ts.map +1 -0
  45. package/dist/reference/stores/memory.js +97 -0
  46. package/dist/reference/stores/memory.js.map +1 -0
  47. package/dist/reference/stores/postgres.d.ts +61 -0
  48. package/dist/reference/stores/postgres.d.ts.map +1 -0
  49. package/dist/reference/stores/postgres.js +406 -0
  50. package/dist/reference/stores/postgres.js.map +1 -0
  51. package/dist/reference/stores/sqlite-driver.d.ts +54 -0
  52. package/dist/reference/stores/sqlite-driver.d.ts.map +1 -0
  53. package/dist/reference/stores/sqlite-driver.js +99 -0
  54. package/dist/reference/stores/sqlite-driver.js.map +1 -0
  55. package/dist/reference/stores/sqlite.d.ts +68 -0
  56. package/dist/reference/stores/sqlite.d.ts.map +1 -0
  57. package/dist/reference/stores/sqlite.js +464 -0
  58. package/dist/reference/stores/sqlite.js.map +1 -0
  59. package/dist/report/console.d.ts +33 -0
  60. package/dist/report/console.d.ts.map +1 -0
  61. package/dist/report/console.js +237 -0
  62. package/dist/report/console.js.map +1 -0
  63. package/dist/report/matrix.d.ts +131 -0
  64. package/dist/report/matrix.d.ts.map +1 -0
  65. package/dist/report/matrix.js +865 -0
  66. package/dist/report/matrix.js.map +1 -0
  67. package/dist/report/render.d.ts +66 -0
  68. package/dist/report/render.d.ts.map +1 -0
  69. package/dist/report/render.js +423 -0
  70. package/dist/report/render.js.map +1 -0
  71. package/dist/runtime/async.d.ts +34 -0
  72. package/dist/runtime/async.d.ts.map +1 -0
  73. package/dist/runtime/async.js +130 -0
  74. package/dist/runtime/async.js.map +1 -0
  75. package/dist/runtime/auth.d.ts +46 -0
  76. package/dist/runtime/auth.d.ts.map +1 -0
  77. package/dist/runtime/auth.js +236 -0
  78. package/dist/runtime/auth.js.map +1 -0
  79. package/dist/runtime/checks.d.ts +89 -0
  80. package/dist/runtime/checks.d.ts.map +1 -0
  81. package/dist/runtime/checks.js +3400 -0
  82. package/dist/runtime/checks.js.map +1 -0
  83. package/dist/runtime/client.d.ts +65 -0
  84. package/dist/runtime/client.d.ts.map +1 -0
  85. package/dist/runtime/client.js +122 -0
  86. package/dist/runtime/client.js.map +1 -0
  87. package/dist/runtime/finding.d.ts +50 -0
  88. package/dist/runtime/finding.d.ts.map +1 -0
  89. package/dist/runtime/finding.js +50 -0
  90. package/dist/runtime/finding.js.map +1 -0
  91. package/dist/runtime/fixture.d.ts +20 -0
  92. package/dist/runtime/fixture.d.ts.map +1 -0
  93. package/dist/runtime/fixture.js +175 -0
  94. package/dist/runtime/fixture.js.map +1 -0
  95. package/dist/runtime/progress.d.ts +41 -0
  96. package/dist/runtime/progress.d.ts.map +1 -0
  97. package/dist/runtime/progress.js +186 -0
  98. package/dist/runtime/progress.js.map +1 -0
  99. package/dist/runtime/run.d.ts +69 -0
  100. package/dist/runtime/run.d.ts.map +1 -0
  101. package/dist/runtime/run.js +575 -0
  102. package/dist/runtime/run.js.map +1 -0
  103. package/dist/runtime/teardown.d.ts +38 -0
  104. package/dist/runtime/teardown.d.ts.map +1 -0
  105. package/dist/runtime/teardown.js +129 -0
  106. package/dist/runtime/teardown.js.map +1 -0
  107. package/dist/runtime/validate.d.ts +31 -0
  108. package/dist/runtime/validate.d.ts.map +1 -0
  109. package/dist/runtime/validate.js +111 -0
  110. package/dist/runtime/validate.js.map +1 -0
  111. package/dist/runtime/world.d.ts +49 -0
  112. package/dist/runtime/world.d.ts.map +1 -0
  113. package/dist/runtime/world.js +119 -0
  114. package/dist/runtime/world.js.map +1 -0
  115. package/dist/spec/collection.d.ts +31 -0
  116. package/dist/spec/collection.d.ts.map +1 -0
  117. package/dist/spec/collection.js +121 -0
  118. package/dist/spec/collection.js.map +1 -0
  119. package/dist/spec/conventions.d.ts +103 -0
  120. package/dist/spec/conventions.d.ts.map +1 -0
  121. package/dist/spec/conventions.js +275 -0
  122. package/dist/spec/conventions.js.map +1 -0
  123. package/dist/spec/extensions.d.ts +74 -0
  124. package/dist/spec/extensions.d.ts.map +1 -0
  125. package/dist/spec/extensions.js +335 -0
  126. package/dist/spec/extensions.js.map +1 -0
  127. package/dist/spec/graph.d.ts +89 -0
  128. package/dist/spec/graph.d.ts.map +1 -0
  129. package/dist/spec/graph.js +318 -0
  130. package/dist/spec/graph.js.map +1 -0
  131. package/dist/spec/load.d.ts +36 -0
  132. package/dist/spec/load.d.ts.map +1 -0
  133. package/dist/spec/load.js +166 -0
  134. package/dist/spec/load.js.map +1 -0
  135. package/dist/spec/types.d.ts +57 -0
  136. package/dist/spec/types.d.ts.map +1 -0
  137. package/dist/spec/types.js +24 -0
  138. package/dist/spec/types.js.map +1 -0
  139. package/labs/README.md +130 -0
  140. package/labs/annotated-openapi.yaml +311 -0
  141. package/labs/anyrow.config.ts +107 -0
  142. package/labs/demo.mjs +124 -0
  143. package/labs/local.config.ts +41 -0
  144. package/labs/minimal.config.ts +32 -0
  145. package/package.json +80 -0
@@ -0,0 +1,68 @@
1
+ /**
2
+ * SQLite-backed storage for the reference backend.
3
+ *
4
+ * The in-memory store executes the query grammar in JavaScript, which quietly sidesteps the
5
+ * behaviours that break real APIs: NULL ordering, collation, LIKE escaping, type affinity, and
6
+ * result order when a sort has no total order. Those are exactly the semantics oat's checks
7
+ * reason about, so a reference backend that never touches SQL can only prove so much.
8
+ *
9
+ * The engine is supplied as a driver, so the same SQL runs in-process via `node:sqlite` and
10
+ * remotely against Cloudflare D1. That second target is not redundancy: D1 is a different build
11
+ * with different compile flags, reached over the network, backed by a database that persists
12
+ * between runs — three properties an in-process store cannot exhibit.
13
+ */
14
+ import type { DefectSet } from "../defects.ts";
15
+ import type { EntityDef } from "../model.ts";
16
+ import { type QueryOptions, type QueryParams, type QueryResult, type Row, SqlError, type Store } from "../store-api.ts";
17
+ import type { SqliteDriver } from "./sqlite-driver.ts";
18
+ export { SqlError };
19
+ export type { QueryParams, QueryResult, Row };
20
+ export declare class SqlStore implements Store {
21
+ private readonly defects;
22
+ private readonly db;
23
+ private readonly prefix;
24
+ private sequence;
25
+ private constructor();
26
+ /**
27
+ * Schema creation is a set of round trips on a networked engine, so it cannot live in a
28
+ * constructor. `prefix` isolates one run's tables from another's on a shared database.
29
+ */
30
+ static create(defects: DefectSet, driver: SqliteDriver, prefix?: string): Promise<SqlStore>;
31
+ close(): Promise<void>;
32
+ private ddl;
33
+ nextId(prefix: string): string;
34
+ now(): number;
35
+ /** The stored column for a field — diverges from the declared name only under the defect. */
36
+ private physical;
37
+ insert(entity: EntityDef, record: Row): Promise<Row>;
38
+ /**
39
+ * Explicit column list, as production code writes it.
40
+ *
41
+ * `SELECT *` would paper over a DDL/read naming mismatch; naming columns is what lets
42
+ * SQLite's double-quoted-string fallback surface — an unresolvable "name" silently becomes
43
+ * the literal 'name' rather than an error. See COLUMN_NAME_MISMATCH.
44
+ */
45
+ private selectList;
46
+ byId(entity: EntityDef, id: string): Promise<Row | null>;
47
+ update(entity: EntityDef, id: string, patch: Row): Promise<Row | null>;
48
+ /**
49
+ * Reads the row, yields, then writes every column back — the `save(entity)` pattern.
50
+ *
51
+ * A synchronous driver does not prevent this: the lost update comes from the *handler*
52
+ * holding state across an await, not from engine-level locking, so it reproduces here
53
+ * exactly as it does on a networked database.
54
+ */
55
+ private readModifyWrite;
56
+ remove(entity: EntityDef, id: string): Promise<void>;
57
+ /**
58
+ * Converts stored values back to their declared shape. SQLite has no boolean type, so a
59
+ * field declared boolean comes back as 0/1 and would fail its own response schema.
60
+ */
61
+ private decode;
62
+ query(entity: EntityDef, scope: Record<string, string>, params: QueryParams, options: QueryOptions): Promise<QueryResult>;
63
+ private compileFilter;
64
+ /** Set by compileOrder when the descending-drops-nulls defect applies to this query. */
65
+ private dropNullsFor;
66
+ private compileOrder;
67
+ }
68
+ //# sourceMappingURL=sqlite.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sqlite.d.ts","sourceRoot":"","sources":["../../../src/reference/stores/sqlite.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAEH,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,eAAe,CAAA;AAC9C,OAAO,KAAK,EAAE,SAAS,EAAY,MAAM,aAAa,CAAA;AAEtD,OAAO,EAIN,KAAK,YAAY,EACjB,KAAK,WAAW,EAChB,KAAK,WAAW,EAChB,KAAK,GAAG,EACR,QAAQ,EAGR,KAAK,KAAK,EACV,MAAM,iBAAiB,CAAA;AACxB,OAAO,KAAK,EAAE,YAAY,EAAY,MAAM,oBAAoB,CAAA;AAEhE,OAAO,EAAE,QAAQ,EAAE,CAAA;AACnB,YAAY,EAAE,WAAW,EAAE,WAAW,EAAE,GAAG,EAAE,CAAA;AAiC7C,qBAAa,QAAS,YAAW,KAAK;IAIpC,OAAO,CAAC,QAAQ,CAAC,OAAO;IACxB,OAAO,CAAC,QAAQ,CAAC,EAAE;IACnB,OAAO,CAAC,QAAQ,CAAC,MAAM;IALxB,OAAO,CAAC,QAAQ,CAAI;IAEpB,OAAO;IAMP;;;OAGG;WACU,MAAM,CAClB,OAAO,EAAE,SAAS,EAClB,MAAM,EAAE,YAAY,EACpB,MAAM,SAAK,GACT,OAAO,CAAC,QAAQ,CAAC;IAQd,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;IAe5B,OAAO,CAAC,GAAG;IAaX,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM;IAK9B,GAAG,IAAI,MAAM;IAMb,6FAA6F;IAC7F,OAAO,CAAC,QAAQ;IAMV,MAAM,CAAC,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,GAAG,GAAG,OAAO,CAAC,GAAG,CAAC;IAgB1D;;;;;;OAMG;IACH,OAAO,CAAC,UAAU;IAqBZ,IAAI,CAAC,MAAM,EAAE,SAAS,EAAE,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,GAAG,GAAG,IAAI,CAAC;IASxD,MAAM,CAAC,MAAM,EAAE,SAAS,EAAE,EAAE,EAAE,MAAM,EAAE,KAAK,EAAE,GAAG,GAAG,OAAO,CAAC,GAAG,GAAG,IAAI,CAAC;IAc5E;;;;;;OAMG;YACW,eAAe;IAcvB,MAAM,CAAC,MAAM,EAAE,SAAS,EAAE,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAO1D;;;OAGG;IACH,OAAO,CAAC,MAAM;IAeR,KAAK,CACV,MAAM,EAAE,SAAS,EACjB,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,EAC7B,MAAM,EAAE,WAAW,EACnB,OAAO,EAAE,YAAY,GACnB,OAAO,CAAC,WAAW,CAAC;IA6HvB,OAAO,CAAC,aAAa;IA4FrB,wFAAwF;IACxF,OAAO,CAAC,YAAY,CAAsB;IAE1C,OAAO,CAAC,YAAY;CAkDpB"}
@@ -0,0 +1,464 @@
1
+ /**
2
+ * SQLite-backed storage for the reference backend.
3
+ *
4
+ * The in-memory store executes the query grammar in JavaScript, which quietly sidesteps the
5
+ * behaviours that break real APIs: NULL ordering, collation, LIKE escaping, type affinity, and
6
+ * result order when a sort has no total order. Those are exactly the semantics oat's checks
7
+ * reason about, so a reference backend that never touches SQL can only prove so much.
8
+ *
9
+ * The engine is supplied as a driver, so the same SQL runs in-process via `node:sqlite` and
10
+ * remotely against Cloudflare D1. That second target is not redundancy: D1 is a different build
11
+ * with different compile flags, reached over the network, backed by a database that persists
12
+ * between runs — three properties an in-process store cannot exhibit.
13
+ */
14
+ import { ENTITIES, OVERCLAIMED_FIELD, fieldsWhere } from "../model.js";
15
+ import { decodeCursor, encodeCursor, project, SqlError, splitTopLevel, stripParens, } from "../store-api.js";
16
+ export { SqlError };
17
+ /** SQLite storage class per declared field type. */
18
+ const AFFINITY = {
19
+ boolean: "INTEGER",
20
+ integer: "INTEGER",
21
+ number: "REAL",
22
+ string: "TEXT",
23
+ };
24
+ /**
25
+ * Physical column name.
26
+ *
27
+ * Deliberately the declared field name, quoted. A production API this was modelled on named
28
+ * columns one way in DDL and another way in every read, and SQLite's double-quoted-string
29
+ * fallback turned the mismatch into wrong data instead of an error — see the
30
+ * COLUMN_NAME_MISMATCH defect, which reproduces it.
31
+ */
32
+ function col(name) {
33
+ return `"${name.replace(/"/g, '""')}"`;
34
+ }
35
+ /**
36
+ * Physical table name.
37
+ *
38
+ * Prefixed per store instance because a remote database outlives the process that created it:
39
+ * two runs sharing one D1 would otherwise collide on both schema and data, and the resulting
40
+ * cross-talk would surface as findings that describe the harness rather than the backend.
41
+ */
42
+ function tableName(entity, prefix) {
43
+ return `"${prefix}${entity.plural}"`;
44
+ }
45
+ export class SqlStore {
46
+ defects;
47
+ db;
48
+ prefix;
49
+ sequence = 0;
50
+ constructor(defects, db, prefix) {
51
+ this.defects = defects;
52
+ this.db = db;
53
+ this.prefix = prefix;
54
+ }
55
+ /**
56
+ * Schema creation is a set of round trips on a networked engine, so it cannot live in a
57
+ * constructor. `prefix` isolates one run's tables from another's on a shared database.
58
+ */
59
+ static async create(defects, driver, prefix = "") {
60
+ const store = new SqlStore(defects, driver, prefix);
61
+ /* One statement per table would be one network round trip per table. Both drivers accept
62
+ * a multi-statement script, so the whole schema costs a single trip. */
63
+ await driver.exec(ENTITIES.map((entity) => store.ddl(entity)).join(";\n"));
64
+ return store;
65
+ }
66
+ async close() {
67
+ /* Persistent engines keep whatever this run created unless it is dropped. Failures here
68
+ * are swallowed: teardown must not mask the result the run was there to produce. */
69
+ if (this.prefix !== "") {
70
+ for (const entity of ENTITIES) {
71
+ try {
72
+ await this.db.exec(`DROP TABLE IF EXISTS ${tableName(entity, this.prefix)}`);
73
+ }
74
+ catch {
75
+ /* ignore */
76
+ }
77
+ }
78
+ }
79
+ await this.db.close();
80
+ }
81
+ ddl(entity) {
82
+ const columns = entity.fields.map((field) => {
83
+ const physical = this.physical(field.name);
84
+ const notNull = field.required === true ? " NOT NULL" : "";
85
+ return ` ${physical} ${AFFINITY[field.type]}${notNull}`;
86
+ });
87
+ const table = tableName(entity, this.prefix);
88
+ return (`CREATE TABLE ${table} (\n${columns.join(",\n")}\n);\n`
89
+ + `CREATE INDEX "${this.prefix}idx_${entity.plural}_id" ON ${table} (${col(entity.identity)})`);
90
+ }
91
+ nextId(prefix) {
92
+ this.sequence += 1;
93
+ return `${prefix}_${String(this.sequence).padStart(6, "0")}`;
94
+ }
95
+ now() {
96
+ /* Monotonic and derived from the sequence: wall-clock timestamps make ordering
97
+ * assertions flaky for reasons that have nothing to do with the backend. */
98
+ return 1_700_000_000_000 + this.sequence * 1000;
99
+ }
100
+ /** The stored column for a field — diverges from the declared name only under the defect. */
101
+ physical(name) {
102
+ return this.defects.has("COLUMN_NAME_MISMATCH") && name === "name"
103
+ ? col("mislabelled_name")
104
+ : col(name);
105
+ }
106
+ async insert(entity, record) {
107
+ const names = entity.fields.map((f) => f.name).filter((n) => record[n] !== undefined);
108
+ const placeholders = names.map(() => "?").join(", ");
109
+ const columns = names.map((n) => this.physical(n)).join(", ");
110
+ const values = names.map((n) => toSql(record[n]));
111
+ /* RETURNING reads the stored row back in the same statement. On a networked engine the
112
+ * separate SELECT this replaces doubled the cost of every write. */
113
+ const written = await this.db.all(`INSERT INTO ${tableName(entity, this.prefix)} (${columns}) VALUES (${placeholders}) `
114
+ + `RETURNING ${this.selectList(entity)}`, values);
115
+ const row = written[0];
116
+ return row === undefined ? record : this.decode(entity, row);
117
+ }
118
+ /**
119
+ * Explicit column list, as production code writes it.
120
+ *
121
+ * `SELECT *` would paper over a DDL/read naming mismatch; naming columns is what lets
122
+ * SQLite's double-quoted-string fallback surface — an unresolvable "name" silently becomes
123
+ * the literal 'name' rather than an error. See COLUMN_NAME_MISMATCH.
124
+ */
125
+ selectList(entity) {
126
+ return entity.fields
127
+ .map((f) => {
128
+ if (!this.defects.has("COLUMN_NAME_MISMATCH") || f.name !== "name")
129
+ return col(f.name);
130
+ /*
131
+ * The bug is that DDL wrote `mislabelled_name` while reads ask for `name`.
132
+ *
133
+ * On an engine with double-quoted-string fallback ON, that is expressible in its
134
+ * natural form — `"name"` resolves to no column, so SQLite hands back the literal
135
+ * 'name' and the API serves the column's own name as every row's value. Writing
136
+ * it that way means the *engine* produces the damage, which is a materially
137
+ * stronger test than asserting oat catches a hand-written imitation.
138
+ *
139
+ * Where the fallback is compiled off the same SQL is an error, not a silent wrong
140
+ * answer, so the damaging outcome is emitted directly instead.
141
+ */
142
+ return this.db.dqs ? col(f.name) : `'${f.name}' AS ${col(f.name)}`;
143
+ })
144
+ .join(", ");
145
+ }
146
+ async byId(entity, id) {
147
+ const rows = await this.db.all(`SELECT ${this.selectList(entity)} FROM ${tableName(entity, this.prefix)} WHERE ${col(entity.identity)} = ?`, [id]);
148
+ const row = rows[0];
149
+ return row === undefined ? null : this.decode(entity, row);
150
+ }
151
+ async update(entity, id, patch) {
152
+ if (this.defects.has("CONCURRENT_WRITE_LOST"))
153
+ return this.readModifyWrite(entity, id, patch);
154
+ const names = Object.keys(patch).filter((n) => entity.fields.some((f) => f.name === n));
155
+ if (names.length === 0)
156
+ return this.byId(entity, id);
157
+ const assignments = names.map((n) => `${this.physical(n)} = ?`).join(", ");
158
+ const written = await this.db.all(`UPDATE ${tableName(entity, this.prefix)} SET ${assignments} `
159
+ + `WHERE ${col(entity.identity)} = ? RETURNING ${this.selectList(entity)}`, [...names.map((n) => toSql(patch[n])), id]);
160
+ const row = written[0];
161
+ return row === undefined ? null : this.decode(entity, row);
162
+ }
163
+ /**
164
+ * Reads the row, yields, then writes every column back — the `save(entity)` pattern.
165
+ *
166
+ * A synchronous driver does not prevent this: the lost update comes from the *handler*
167
+ * holding state across an await, not from engine-level locking, so it reproduces here
168
+ * exactly as it does on a networked database.
169
+ */
170
+ async readModifyWrite(entity, id, patch) {
171
+ const current = await this.byId(entity, id);
172
+ if (current === null)
173
+ return null;
174
+ await new Promise((resolve) => setTimeout(resolve, 15));
175
+ const merged = { ...current, ...patch };
176
+ const names = entity.fields.map((f) => f.name);
177
+ const assignments = names.map((n) => `${this.physical(n)} = ?`).join(", ");
178
+ await this.db.run(`UPDATE ${tableName(entity, this.prefix)} SET ${assignments} WHERE ${col(entity.identity)} = ?`, [...names.map((n) => toSql(merged[n])), id]);
179
+ return this.byId(entity, id);
180
+ }
181
+ async remove(entity, id) {
182
+ await this.db.run(`DELETE FROM ${tableName(entity, this.prefix)} WHERE ${col(entity.identity)} = ?`, [id]);
183
+ }
184
+ /**
185
+ * Converts stored values back to their declared shape. SQLite has no boolean type, so a
186
+ * field declared boolean comes back as 0/1 and would fail its own response schema.
187
+ */
188
+ decode(entity, row) {
189
+ const out = {};
190
+ for (const field of entity.fields) {
191
+ const raw = row[field.name];
192
+ if (raw === undefined || raw === null) {
193
+ out[field.name] = null;
194
+ continue;
195
+ }
196
+ out[field.name] = field.type === "boolean" ? raw === 1 : raw;
197
+ }
198
+ return out;
199
+ }
200
+ /* ------------------------------------------------------------------ querying */
201
+ async query(entity, scope, params, options) {
202
+ const where = [];
203
+ const args = [];
204
+ /* Ancestor scoping — `.../tables/{table_id}/rows` lists that table only. The defect
205
+ * applies scoping to the plain listing but drops it once a filter is present, which is
206
+ * how a filter turns into an authorization bypass. */
207
+ const scoped = !(this.defects.has("TENANT_LEAK_VIA_FILTER") && params.filter !== undefined);
208
+ for (const parent of scoped ? entity.parents : []) {
209
+ const value = scope[parent];
210
+ if (value === undefined)
211
+ continue;
212
+ if (!entity.fields.some((f) => f.name === parent))
213
+ continue;
214
+ where.push(`${col(parent)} = ?`);
215
+ args.push(value);
216
+ }
217
+ const soft = options.softDeleteField;
218
+ if (soft !== undefined && !this.defects.has("SOFT_DELETE_LEAK")) {
219
+ const mentioned = params.filter?.includes(soft) === true;
220
+ if (!mentioned)
221
+ where.push(`${col(soft)} IS NULL`);
222
+ }
223
+ if (params.filter !== undefined && params.filter !== "") {
224
+ const compiled = this.compileFilter(params.filter, entity);
225
+ where.push(compiled.sql);
226
+ args.push(...compiled.args);
227
+ }
228
+ if (params.q !== undefined && params.q !== "" && !this.defects.has("SEARCH_IGNORED")) {
229
+ const searchable = fieldsWhere(entity, "searchable");
230
+ if (searchable.length > 0) {
231
+ const clauses = searchable.map((f) => `${col(f)} LIKE ? ESCAPE '\\'`);
232
+ where.push(`(${clauses.join(" OR ")})`);
233
+ for (const _ of searchable)
234
+ args.push(`%${escapeLike(params.q)}%`);
235
+ }
236
+ }
237
+ const orderSql = this.compileOrder(params.order, entity);
238
+ if (this.dropNullsFor !== null)
239
+ where.push(`${col(this.dropNullsFor)} IS NOT NULL`);
240
+ const whereSql = where.length > 0 ? ` WHERE ${where.join(" AND ")}` : "";
241
+ const countWhere = this.defects.has("COUNT_IGNORES_FILTER") ? "" : whereSql;
242
+ const countArgs = this.defects.has("COUNT_IGNORES_FILTER") ? [] : args;
243
+ const counted = await this.db.all(`SELECT COUNT(*) AS n FROM ${tableName(entity, this.prefix)}${countWhere}`, countArgs);
244
+ const total = { n: Number(counted[0]?.n ?? 0) };
245
+ const requested = params.limit ?? entity.defaultLimit;
246
+ const limit = this.defects.has("LIMIT_EXCEEDS_MAX")
247
+ ? requested
248
+ : Math.min(requested, entity.maxLimit);
249
+ let offset;
250
+ let page;
251
+ if (params.cursor !== undefined && params.cursor !== "") {
252
+ const afterId = decodeCursor(params.cursor);
253
+ /* The cursor boundary must be resolved under exactly the listing's ordering. Under the
254
+ * defect it uses NOCASE while the listing uses BINARY, so the index found here is not
255
+ * the index the listing would have produced and the page boundary lands elsewhere. */
256
+ /* NOCASE against the listing's BINARY: with mixed-case data the two disagree, because
257
+ * BINARY sorts every uppercase letter before every lowercase one. */
258
+ const cursorOrderSql = this.defects.has("COLLATION_INCONSISTENT")
259
+ ? orderSql.replace(/(".*?")( (?:ASC|DESC))/g, "$1 COLLATE NOCASE$2")
260
+ : orderSql;
261
+ const ordered = (await this.db.all(`SELECT ${col(entity.identity)} AS id FROM ${tableName(entity, this.prefix)}${whereSql}${cursorOrderSql}`, args));
262
+ const index = ordered.findIndex((r) => String(r.id) === afterId);
263
+ offset = index === -1 ? 0 : index + (this.defects.has("CURSOR_DRIFT") ? 0 : 1);
264
+ page = null;
265
+ }
266
+ else {
267
+ const requestedPage = Math.max(params.page ?? 1, 1);
268
+ offset =
269
+ (requestedPage - 1) * limit +
270
+ (this.defects.has("OFF_BY_ONE_PAGE") && requestedPage > 1 ? 1 : 0);
271
+ page = requestedPage;
272
+ }
273
+ const window = this.defects.has("LIMIT_IGNORED") ? -1 : limit;
274
+ const rows = await this.db.all(`SELECT ${this.selectList(entity)} FROM ${tableName(entity, this.prefix)}${whereSql}${orderSql} LIMIT ? OFFSET ?`, [...args, window, offset]);
275
+ /* The "no results must mean a bad query" guard — falls back to the unfiltered set and
276
+ * makes an empty result impossible to express. */
277
+ const effective = this.defects.has("EMPTY_RESULT_RETURNS_ALL") && rows.length === 0 && where.length > 0
278
+ ? await this.db.all(`SELECT ${this.selectList(entity)} FROM ${tableName(entity, this.prefix)}${orderSql} LIMIT ? OFFSET ?`, [window, offset])
279
+ : rows;
280
+ const decoded = effective.map((row) => this.decode(entity, row));
281
+ const last = decoded.at(-1);
282
+ const hasMore = this.defects.has("HASMORE_ALWAYS_FALSE")
283
+ ? false
284
+ : offset + decoded.length < total.n;
285
+ return {
286
+ count: this.defects.has("COUNT_ALWAYS_ZERO") ? 0 : total.n,
287
+ hasMore,
288
+ items: decoded
289
+ .map((row) => (options.transform === undefined ? row : options.transform(row)))
290
+ .map((row) => project(row, params.select, this.defects.has("SELECT_IGNORED"), this.defects.has("SPEC_OVERCLAIMS_SELECTABLE") ? [OVERCLAIMED_FIELD] : [])),
291
+ limit,
292
+ nextCursor: hasMore && last !== undefined ? encodeCursor(String(last[entity.identity])) : null,
293
+ page,
294
+ };
295
+ }
296
+ /* ------------------------------------------------------------- filter → SQL */
297
+ compileFilter(expression, entity) {
298
+ const trimmed = expression.trim();
299
+ const group = /^(and|or)\((.*)\)$/s.exec(trimmed);
300
+ if (group?.[1] && group[2] !== undefined) {
301
+ const parts = splitTopLevel(group[2]).map((part) => this.compileFilter(part, entity));
302
+ if (parts.length === 0)
303
+ throw new SqlError("invalid_filter", "empty filter group");
304
+ const effective = this.defects.has("FILTER_GROUP_COMBINATOR_SWAPPED")
305
+ ? (group[1] === "and" ? "or" : "and")
306
+ : group[1];
307
+ return {
308
+ args: parts.flatMap((p) => p.args),
309
+ sql: `(${parts.map((p) => p.sql).join(effective === "and" ? " AND " : " OR ")})`,
310
+ };
311
+ }
312
+ const segments = trimmed.split(".");
313
+ if (segments.length < 3) {
314
+ throw new SqlError("invalid_filter", `malformed filter term "${trimmed}"`);
315
+ }
316
+ const [field, op] = segments;
317
+ const raw = segments.slice(2).join(".");
318
+ /* Under the overclaim defect the backend refuses a field the document still declares
319
+ * filterable — the backend is not wrong to refuse, the document is wrong to promise. */
320
+ const filterable = this.defects.has("SPEC_OVERCLAIMS_FILTERABLE")
321
+ ? fieldsWhere(entity, "filterable").filter((f) => f !== OVERCLAIMED_FIELD)
322
+ : fieldsWhere(entity, "filterable");
323
+ if (!filterable.includes(field)) {
324
+ if (this.defects.has("FILTER_IGNORED"))
325
+ return { args: [], sql: "1 = 1" };
326
+ throw new SqlError("invalid_filter", `field "${field}" is not filterable`);
327
+ }
328
+ const declared = entity.fields.find((f) => f.name === field);
329
+ const numeric = declared?.type === "integer" || declared?.type === "number";
330
+ /* SQLite compares by storage class, so a numeric column normally orders numerically.
331
+ * Casting to TEXT is what reproduces `amount > 9` missing 10. */
332
+ const ref = numeric && this.defects.has("NUMERIC_COMPARED_AS_TEXT")
333
+ ? `CAST(${col(field)} AS TEXT)`
334
+ : col(field);
335
+ const asText = !numeric || this.defects.has("NUMERIC_COMPARED_AS_TEXT");
336
+ switch (op) {
337
+ case "eq":
338
+ if (this.defects.has("FILTER_EQ_NOT_APPLIED"))
339
+ return { args: [], sql: "1 = 1" };
340
+ return { args: [coerce(raw, asText)], sql: `${ref} = ?` };
341
+ case "neq":
342
+ /* Correct negation must re-admit NULLs: in SQL `col <> x` is NULL — not true — for
343
+ * NULL rows, so they silently vanish without the explicit IS NULL branch. The
344
+ * defect drops that branch, which is the real-world bug this models. */
345
+ return this.defects.has("NEQ_DROPS_NULLS")
346
+ ? { args: [coerce(raw)], sql: `${ref} <> ?` }
347
+ : { args: [coerce(raw)], sql: `(${ref} <> ? OR ${ref} IS NULL)` };
348
+ case "gt":
349
+ return { args: [coerce(raw, asText)], sql: `${ref} > ?` };
350
+ case "gte":
351
+ return { args: [coerce(raw, asText)], sql: `${ref} >= ?` };
352
+ case "lt":
353
+ return { args: [coerce(raw, asText)], sql: `${ref} < ?` };
354
+ case "lte":
355
+ return { args: [coerce(raw, asText)], sql: `${ref} <= ?` };
356
+ case "in":
357
+ case "nin": {
358
+ const members = stripParens(raw).split(",").map((s) => coerce(s.trim()));
359
+ const holes = members.map(() => "?").join(", ");
360
+ return {
361
+ args: members,
362
+ sql: op === "in" ? `${ref} IN (${holes})` : `${ref} NOT IN (${holes})`,
363
+ };
364
+ }
365
+ case "is":
366
+ if (raw === "null")
367
+ return { args: [], sql: `${ref} IS NULL` };
368
+ if (raw === "true")
369
+ return { args: [1], sql: `${ref} = ?` };
370
+ if (raw === "false")
371
+ return { args: [0], sql: `${ref} = ?` };
372
+ throw new SqlError("invalid_filter", `is.${raw} is not a recognised predicate`);
373
+ case "like":
374
+ case "ilike": {
375
+ /* `*` is the grammar's wildcard; % and _ are literals and must be escaped, or a
376
+ * value containing them matches far more than the caller asked for. */
377
+ const pattern = this.defects.has("LIKE_UNESCAPED")
378
+ ? raw.replace(/\*/g, "%")
379
+ : escapeLike(raw).replace(/\*/g, "%");
380
+ return { args: [pattern], sql: `${ref} LIKE ? ESCAPE '\\'` };
381
+ }
382
+ default:
383
+ throw new SqlError("invalid_filter", `unknown operator "${op}"`);
384
+ }
385
+ }
386
+ /** Set by compileOrder when the descending-drops-nulls defect applies to this query. */
387
+ dropNullsFor = null;
388
+ compileOrder(expression, entity) {
389
+ this.dropNullsFor = null;
390
+ if (this.defects.has("ORDER_IGNORED"))
391
+ return "";
392
+ const terms = [];
393
+ if (expression !== undefined && expression !== "") {
394
+ for (const raw of splitTopLevel(expression)) {
395
+ const [field, ...modifiers] = raw.split(".");
396
+ /* Under the overclaim defect the backend refuses a field the document still declares
397
+ * sortable — the backend is not wrong to refuse, the document is wrong to promise. */
398
+ const sortable = this.defects.has("SPEC_OVERCLAIMS_SORTABLE")
399
+ ? fieldsWhere(entity, "sortable").filter((f) => f !== OVERCLAIMED_FIELD)
400
+ : fieldsWhere(entity, "sortable");
401
+ if (field === undefined || !sortable.includes(field)) {
402
+ throw new SqlError("invalid_order", `field "${field ?? ""}" is not sortable`);
403
+ }
404
+ const descending = modifiers.includes("desc");
405
+ const nullsFirst = modifiers.includes("nullsfirst")
406
+ ? true
407
+ : modifiers.includes("nullslast")
408
+ ? false
409
+ : descending;
410
+ const declared = entity.fields.find((f) => f.name === field);
411
+ const numeric = declared?.type === "integer" || declared?.type === "number";
412
+ const ref = numeric && this.defects.has("NUMERIC_COMPARED_AS_TEXT")
413
+ ? `CAST(${col(field)} AS TEXT)`
414
+ : col(field);
415
+ terms.push(`${col(field)} IS NULL ${nullsFirst ? "DESC" : "ASC"}`);
416
+ terms.push(`${ref} ${descending ? "DESC" : "ASC"}`);
417
+ if (descending && this.defects.has("SORT_DESC_DROPS_NULLS")) {
418
+ this.dropNullsFor = field;
419
+ }
420
+ }
421
+ }
422
+ /* The tiebreak is what makes pagination sound: without a total order, equal keys may come
423
+ * back in any order and a page boundary moves between requests. */
424
+ if (this.defects.has("UNSTABLE_SORT")) {
425
+ /* Without a tiebreak, rows with equal keys come back in whatever order the plan
426
+ * produced — arbitrary, and different between two identical queries. SQLite would
427
+ * otherwise fall back to rowid and look stable by accident, so ties are randomised
428
+ * to model the real behaviour rather than a friendlier version of it. */
429
+ terms.push("random()");
430
+ }
431
+ else {
432
+ terms.push(`${col(entity.identity)} ASC`);
433
+ }
434
+ return terms.length > 0 ? ` ORDER BY ${terms.join(", ")}` : "";
435
+ }
436
+ }
437
+ /* ---------------------------------------------------------------------- helpers */
438
+ function toSql(value) {
439
+ if (value === null || value === undefined)
440
+ return null;
441
+ if (typeof value === "boolean")
442
+ return value ? 1 : 0;
443
+ if (typeof value === "object")
444
+ return JSON.stringify(value);
445
+ return value;
446
+ }
447
+ function coerce(raw, asText = false) {
448
+ if (raw === "null")
449
+ return null;
450
+ if (raw === "true")
451
+ return 1;
452
+ if (raw === "false")
453
+ return 0;
454
+ /* A numeric column compared as text needs a text bind too, or SQLite would compare a TEXT
455
+ * expression against an INTEGER and match nothing at all — a different bug than the one
456
+ * being modelled. */
457
+ if (!asText && raw !== "" && !Number.isNaN(Number(raw)))
458
+ return Number(raw);
459
+ return raw;
460
+ }
461
+ function escapeLike(value) {
462
+ return value.replace(/[\\%_]/g, (ch) => `\\${ch}`);
463
+ }
464
+ //# sourceMappingURL=sqlite.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sqlite.js","sourceRoot":"","sources":["../../../src/reference/stores/sqlite.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,33 @@
1
+ /**
2
+ * Console renderers for the offline commands.
3
+ *
4
+ * `doctor` is the adoption surface: it reports what oat cannot test against this spec and names
5
+ * the meta tag that would close each gap. A backend team's path to full coverage is to run it
6
+ * and work the list down.
7
+ */
8
+ import type { SpecModel } from "../spec/graph.ts";
9
+ /**
10
+ * Which checks each tag makes possible, measured rather than estimated.
11
+ *
12
+ * `oat conformance` runs the reference backend twice — once with its tags, once with them
13
+ * stripped — and asserts this map matches the difference, so it cannot drift into marketing.
14
+ *
15
+ * The distinction below is the honest part. Some tags *unlock* checks that are otherwise
16
+ * impossible: nothing in a document reveals that a 202 is a receipt, or that a column is a
17
+ * tombstone. Others do not change how much runs at all — they change whether what runs is
18
+ * trustworthy. Without `x-query`, oat assumes every scalar property is filterable and probes
19
+ * fields the backend may never have indexed; without `x-tenant`, a cross-tenant read is reported
20
+ * as an ambiguity because oat only inferred the boundary it thinks was crossed.
21
+ */
22
+ export declare const TAG_UNLOCKS: Record<string, readonly string[]>;
23
+ declare function plan(model: SpecModel, asJson: boolean): string;
24
+ declare function doctor(model: SpecModel, externalRefs: string[], asJson: boolean): {
25
+ text: string;
26
+ blocking: number;
27
+ };
28
+ export declare const report: {
29
+ doctor: typeof doctor;
30
+ plan: typeof plan;
31
+ };
32
+ export {};
33
+ //# sourceMappingURL=console.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"console.d.ts","sourceRoot":"","sources":["../../src/report/console.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,KAAK,EAAe,SAAS,EAAE,MAAM,kBAAkB,CAAA;AAE9D;;;;;;;;;;;;GAYG;AACH,eAAO,MAAM,WAAW,EAAE,MAAM,CAAC,MAAM,EAAE,SAAS,MAAM,EAAE,CAczD,CAAA;AAqCD,iBAAS,IAAI,CAAC,KAAK,EAAE,SAAS,EAAE,MAAM,EAAE,OAAO,GAAG,MAAM,CAwCvD;AAED,iBAAS,MAAM,CACd,KAAK,EAAE,SAAS,EAChB,YAAY,EAAE,MAAM,EAAE,EACtB,MAAM,EAAE,OAAO,GACb;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,QAAQ,EAAE,MAAM,CAAA;CAAE,CAuJpC;AAED,eAAO,MAAM,MAAM;;;CAAmB,CAAA"}