dirsql 0.4.22 → 0.4.24

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.
package/dist/core.d.ts CHANGED
@@ -12,6 +12,5 @@ export interface NativeDirSQLConstructor {
12
12
  }
13
13
  export interface CoreModule {
14
14
  DirSQL: NativeDirSQLConstructor;
15
- parseTableName(ddl: string): string | null;
16
15
  }
17
16
  export declare function getCore(): CoreModule;
package/dist/index.d.ts CHANGED
@@ -1,5 +1,4 @@
1
1
  export { DirSQL } from "./dirsql.js";
2
2
  export type { DirSQLOptions, ExtensionSpec, RowEvent, ScanFailure, } from "./dirsql.js";
3
- export { parseTableName } from "./parse-table-name.js";
4
3
  export { Table } from "./table.js";
5
4
  export type { TableDef } from "./table.js";
package/dist/index.js CHANGED
@@ -1,4 +1,3 @@
1
1
  // dirsql TypeScript SDK — public API barrel.
2
2
  export { DirSQL } from "./dirsql.js";
3
- export { parseTableName } from "./parse-table-name.js";
4
3
  export { Table } from "./table.js";
package/dist/table.d.ts CHANGED
@@ -1,5 +1,10 @@
1
1
  /** Definition of a SQL-indexed table backed by files on disk. */
2
2
  export interface TableDef {
3
+ /**
4
+ * The table's SQL name, declared rather than derived from `ddl`. The `ddl`
5
+ * must create a table by this name; a mismatch is a load-time error.
6
+ */
7
+ name: string;
3
8
  /** SQL DDL statement, e.g. `CREATE TABLE users (name TEXT, age INTEGER)`. */
4
9
  ddl: string;
5
10
  /** Glob pattern (relative to the DirSQL root) for files backing this table. */
@@ -16,7 +21,7 @@ export interface TableDef {
16
21
  }
17
22
  /**
18
23
  * Thin class wrapper around {@link TableDef} for parity with the Python
19
- * `Table(ddl=..., glob=..., on_file=...)` and Rust `Table::new(...)`
24
+ * `Table(name=..., ddl=..., glob=..., on_file=...)` and Rust `Table::new(...)`
20
25
  * constructors. `new Table({...})` is structurally identical to a plain
21
26
  * object literal satisfying `TableDef` — anything accepting `TableDef[]`
22
27
  * (e.g. {@link DirSQL}'s `tables` option) takes either form.
@@ -27,6 +32,7 @@ export interface TableDef {
27
32
  * `strict` to `undefined` under `useDefineForClassFields`.
28
33
  */
29
34
  export declare class Table implements TableDef {
35
+ readonly name: string;
30
36
  readonly ddl: string;
31
37
  readonly glob: string;
32
38
  readonly onFile: (filePath: string) => Record<string, unknown>[];
package/dist/table.js CHANGED
@@ -4,7 +4,7 @@
4
4
  // unit test instead of an exemption (#239).
5
5
  /**
6
6
  * Thin class wrapper around {@link TableDef} for parity with the Python
7
- * `Table(ddl=..., glob=..., on_file=...)` and Rust `Table::new(...)`
7
+ * `Table(name=..., ddl=..., glob=..., on_file=...)` and Rust `Table::new(...)`
8
8
  * constructors. `new Table({...})` is structurally identical to a plain
9
9
  * object literal satisfying `TableDef` — anything accepting `TableDef[]`
10
10
  * (e.g. {@link DirSQL}'s `tables` option) takes either form.
@@ -16,6 +16,7 @@
16
16
  */
17
17
  export class Table {
18
18
  constructor(def) {
19
+ this.name = def.name;
19
20
  this.ddl = def.ddl;
20
21
  this.glob = def.glob;
21
22
  this.onFile = def.onFile;
@@ -164,6 +164,7 @@ Now create a `.dirsql.toml` that points a table at it:
164
164
  ```bash
165
165
  cat > .dirsql.toml <<'EOF'
166
166
  [[table]]
167
+ name = "notes"
167
168
  ddl = "CREATE TABLE notes (title TEXT, author TEXT)"
168
169
  glob = "notes/**/*.md"
169
170
  on-file = "sh note.sh {path}"
@@ -33,6 +33,7 @@ Point a table at it in `.dirsql.toml`:
33
33
 
34
34
  ```toml
35
35
  [[table]]
36
+ name = "photos"
36
37
  ddl = "CREATE TABLE photos (year TEXT, month TEXT, basename TEXT)"
37
38
  glob = "photos/*/*/*.jpg"
38
39
  on-file = "python3 pathcols.py {path}"
@@ -26,6 +26,7 @@ Then declare the table in `.dirsql.toml`:
26
26
 
27
27
  ```toml
28
28
  [[table]]
29
+ name = "posts"
29
30
  ddl = "CREATE TABLE posts (title TEXT, slug TEXT)"
30
31
  glob = "posts/**/*.md"
31
32
  on-file = "python3 extract.py {path}"
@@ -60,6 +60,7 @@ async def main() -> None:
60
60
  "./comments-root",
61
61
  tables=[
62
62
  Table(
63
+ name="comments",
63
64
  ddl="CREATE TABLE comments (thread TEXT, author TEXT, body TEXT)",
64
65
  glob="comments/*/*.json",
65
66
  on_file=on_file,
@@ -83,6 +84,7 @@ const db = new DirSQL({
83
84
  root: "./comments-root",
84
85
  tables: [
85
86
  {
87
+ name: "comments",
86
88
  ddl: "CREATE TABLE comments (thread TEXT, author TEXT, body TEXT)",
87
89
  glob: "comments/*/*.json",
88
90
  onFile: (path) => [
@@ -129,6 +131,7 @@ fn main() -> Result<(), Box<dyn std::error::Error>> {
129
131
  let db = DirSQL::builder()
130
132
  .root("./comments-root")
131
133
  .table(Table::new(
134
+ "comments",
132
135
  "CREATE TABLE comments (thread TEXT, author TEXT, body TEXT)",
133
136
  "comments/*/*.json",
134
137
  on_file,
@@ -18,6 +18,7 @@ stdout works. With [`jq`](https://jqlang.org/):
18
18
 
19
19
  ```toml
20
20
  [[table]]
21
+ name = "books"
21
22
  ddl = "CREATE TABLE books (title TEXT, author TEXT, year INTEGER)"
22
23
  glob = "books/*.json"
23
24
  on-file = "jq -c '[{title, author, year}]' {path}"
@@ -53,6 +54,7 @@ row per line, slurp it:
53
54
 
54
55
  ```toml
55
56
  [[table]]
57
+ name = "events"
56
58
  ddl = "CREATE TABLE events (event TEXT, user TEXT)"
57
59
  glob = "logs/*.jsonl"
58
60
  on-file = "jq -c -s '.' {path}"
@@ -84,6 +84,7 @@ command in verbatim:
84
84
 
85
85
  ```toml
86
86
  [[table]]
87
+ name = "posts"
87
88
  ddl = "CREATE TABLE posts (title TEXT, author TEXT)"
88
89
  glob = "posts/*.md"
89
90
  on-file = "python3 extract.py {path}"
@@ -14,6 +14,7 @@ prints each file's basename:
14
14
  ```toml
15
15
  # .dirsql.toml
16
16
  [[table]]
17
+ name = "files"
17
18
  ddl = "CREATE TABLE files (basename TEXT)"
18
19
  glob = "**/*"
19
20
  on-file = '''sh -c 'printf "[{\"basename\":\"%s\"}]" "${1##*/}"' sh {path}'''
@@ -22,6 +22,7 @@ Exclude the noise in `.dirsql.toml`:
22
22
  ignore = ["notes/drafts/**", "**/*.tmp"]
23
23
 
24
24
  [[table]]
25
+ name = "notes"
25
26
  ddl = "CREATE TABLE notes (basename TEXT)"
26
27
  glob = "notes/**/*"
27
28
  on-file = '''sh -c 'printf "[{\"basename\":\"%s\"}]" "${1##*/}"' sh {path}'''
@@ -108,6 +108,7 @@ path = "sqlite_vec"
108
108
  entrypoint = "sqlite3_vec_init"
109
109
 
110
110
  [[table]]
111
+ name = "notes"
111
112
  ddl = "CREATE TABLE notes (path TEXT, text TEXT, embedding TEXT)"
112
113
  glob = "notes/*.md"
113
114
  on-file = "uv run --with model2vec python embed.py {path} {root}"
package/docs/index.md CHANGED
@@ -34,6 +34,7 @@ db = DirSQL(
34
34
  "./my-project",
35
35
  tables=[
36
36
  Table(
37
+ name="records",
37
38
  ddl="CREATE TABLE records (name TEXT, size INTEGER, type TEXT)",
38
39
  glob="data/*.json",
39
40
  on_file=lambda path: [json.loads(open(path, encoding="utf-8").read())],
@@ -52,6 +53,7 @@ let db = DirSQL::new(
52
53
  "./my-project",
53
54
  vec![
54
55
  Table::new(
56
+ "records",
55
57
  "CREATE TABLE records (name TEXT, size INTEGER, type TEXT)",
56
58
  "data/*.json",
57
59
  |path| vec![serde_json::from_str(&std::fs::read_to_string(path).unwrap()).unwrap()],
@@ -70,6 +72,7 @@ const db = new DirSQL({
70
72
  root: './my-project',
71
73
  tables: [
72
74
  new Table({
75
+ name: 'records',
73
76
  ddl: 'CREATE TABLE records (name TEXT, size INTEGER, type TEXT)',
74
77
  glob: 'data/*.json',
75
78
  onFile: (path) => [JSON.parse(readFileSync(path, 'utf8'))],
@@ -166,7 +166,8 @@ what its required `on-file` command emits — dirsql injects nothing (see
166
166
 
167
167
  | Key | Required | Description |
168
168
  |---|---|---|
169
- | `ddl` | yes | A SQLite `CREATE TABLE` statement. The table name is parsed from it. Only the columns declared here are kept; keys the `on-file` command emits that are not declared are dropped. |
169
+ | `name` | yes | The table's SQL name — the name you query it by. Declared, never derived from `ddl`: dirsql does not read the DDL text. The `ddl` must create a table by this name; if it doesn't, loading fails. |
170
+ | `ddl` | yes | A SQLite `CREATE TABLE` statement, run verbatim. Only the columns declared here are kept; keys the `on-file` command emits that are not declared are dropped. |
170
171
  | `glob` | yes | Glob pattern matched against root-relative paths. Every table whose glob matches a file receives that file's rows — a file can populate multiple tables. A `{name}` segment is rewritten to `*` (it matches one path segment but captures nothing). |
171
172
  | `on-file` | **yes** | A command run once per matched file; its stdout (a JSON array of row objects) becomes the file's rows. Must be non-empty. A `[[table]]` with no `on-file` is a load error (see [parse errors](#parse-errors)). See [Command hooks](./hooks.md#on-file). |
172
173
  | `strict` | no (default `false`) | When `true`, rows whose keys do not exactly match the declared columns are rejected with an error: extra keys error, and every declared column must be supplied by the `on-file` output. When `false`, extra keys are dropped and missing columns become `NULL`. |
@@ -180,11 +181,13 @@ instead of declaring a table.
180
181
 
181
182
  ```toml
182
183
  [[table]]
184
+ name = "comments"
183
185
  ddl = "CREATE TABLE comments (path TEXT, author TEXT, body TEXT)"
184
186
  glob = "_comments/*/*.jsonl"
185
187
  on-file = "jq -c -s '.' {path}"
186
188
 
187
189
  [[table]]
190
+ name = "papers"
188
191
  ddl = "CREATE TABLE papers (paper_id TEXT, title TEXT)"
189
192
  glob = "**/meta.json"
190
193
  on-file = "uv run python extract_papers.py {path}"
@@ -241,7 +244,16 @@ SDKs raise/reject) when:
241
244
  - The TOML is malformed.
242
245
  - Any table contains an unknown key (top level, `[dirsql]`, `[[table]]`, or
243
246
  `[[dirsql.extension]]`). The error names the offending key.
244
- - A `[[table]]` entry omits `ddl` or `glob`.
247
+ - A `[[table]]` entry omits `name`, `ddl`, or `glob` (or `name` is
248
+ empty/whitespace).
249
+ - A `[[table]]` entry's `ddl` runs but creates no table by its `name`. The
250
+ error carries the entry's name and points at the fix:
251
+
252
+ > `table 'messages': its `ddl` ran but created no table called 'messages'. Set `name` to the table the `ddl` creates.`
253
+
254
+ dirsql asks SQLite's catalog rather than interpreting the DDL, so quoted
255
+ (`CREATE TABLE "messages"`), schema-qualified (`main.messages`) and
256
+ `IF NOT EXISTS` forms all match a plain `name = "messages"`.
245
257
  - A `[[table]]` entry omits `on-file` (or it is empty/whitespace). The error
246
258
  names the offending glob and points at the fix:
247
259
 
@@ -275,11 +287,13 @@ deterministic = true
275
287
  timeout = "600s"
276
288
 
277
289
  [[table]]
290
+ name = "comments"
278
291
  ddl = "CREATE TABLE comments (author TEXT, body TEXT)"
279
292
  glob = "_comments/*/*.jsonl"
280
293
  on-file = "jq -c -s '.' {path}"
281
294
 
282
295
  [[table]]
296
+ name = "documents"
283
297
  ddl = "CREATE TABLE documents (title TEXT, summary TEXT)"
284
298
  glob = "**/index.md"
285
299
  on-file = "uv run python extract_doc.py {path}"
@@ -317,27 +317,30 @@ rather than waiting — an intentional, language-idiomatic difference.
317
317
  ::: code-group
318
318
 
319
319
  ```python [Python]
320
- Table(*, ddl: str, glob: str, on_file: Callable[[str], list[dict]], strict: bool = False)
320
+ Table(*, name: str, ddl: str, glob: str, on_file: Callable[[str], list[dict]], strict: bool = False)
321
321
  ```
322
322
 
323
323
  ```typescript [TypeScript]
324
- new Table({ ddl, glob, onFile, strict? })
324
+ new Table({ name, ddl, glob, onFile, strict? })
325
325
  // or a plain object — TableDef and Table are interchangeable:
326
- { ddl: string, glob: string, onFile: (path: string) => Record<string, unknown>[], strict?: boolean }
326
+ { name: string, ddl: string, glob: string, onFile: (path: string) => Record<string, unknown>[], strict?: boolean }
327
327
  ```
328
328
 
329
329
  ```rust [Rust]
330
- Table::new(ddl, glob, on_file) // on_file: Fn(&str) -> Vec<Row>, infallible
331
- Table::try_new(ddl, glob, on_file) // on_file: Fn(&str) -> Result<Vec<Row>, _>
332
- Table::strict(ddl, glob, on_file) // Table::new with strict = true
330
+ Table::new(name, ddl, glob, on_file) // on_file: Fn(&str) -> Vec<Row>, infallible
331
+ Table::try_new(name, ddl, glob, on_file) // on_file: Fn(&str) -> Result<Vec<Row>, _>
332
+ Table::strict(name, ddl, glob, on_file) // Table::new with strict = true
333
333
  ```
334
334
 
335
335
  :::
336
336
 
337
337
  Maps files to table rows.
338
338
 
339
- - `ddl` — A SQLite `CREATE TABLE` statement; the table name is parsed from
340
- it. Table names must be unique across all tables.
339
+ - `name` — The table's SQL name, declared rather than derived from `ddl`.
340
+ Must be unique across all tables. Building fails if the `ddl` creates no
341
+ table by this name (checked against SQLite's catalog, before any file is
342
+ indexed).
343
+ - `ddl` — A SQLite `CREATE TABLE` statement, run verbatim.
341
344
  - `glob` — Glob pattern matched against root-relative paths. Every table whose
342
345
  glob matches a file receives that file's rows — a file can populate multiple
343
346
  tables. A `{name}` segment is rewritten to `*` (it matches one path segment
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "dirsql",
3
- "version": "0.4.22",
3
+ "version": "0.4.24",
4
4
  "description": "Ephemeral SQL index over a local directory",
5
5
  "license": "MIT",
6
6
  "repository": "https://github.com/thekevinscott/dirsql",
@@ -213,10 +213,10 @@
213
213
  ]
214
214
  },
215
215
  "optionalDependencies": {
216
- "@dirsql/lib-linux-x64-gnu": "0.4.22",
217
- "@dirsql/lib-linux-arm64-gnu": "0.4.22",
218
- "@dirsql/lib-darwin-x64": "0.4.22",
219
- "@dirsql/lib-darwin-arm64": "0.4.22",
220
- "@dirsql/lib-win32-x64-msvc": "0.4.22"
216
+ "@dirsql/lib-linux-x64-gnu": "0.4.24",
217
+ "@dirsql/lib-linux-arm64-gnu": "0.4.24",
218
+ "@dirsql/lib-darwin-x64": "0.4.24",
219
+ "@dirsql/lib-darwin-arm64": "0.4.24",
220
+ "@dirsql/lib-win32-x64-msvc": "0.4.24"
221
221
  }
222
222
  }
@@ -1,8 +0,0 @@
1
- /**
2
- * Parse the table name out of a `CREATE TABLE <name> (...)` DDL.
3
- *
4
- * Returns `null` for a DDL the parser doesn't recognize. Backed by the
5
- * core Rust implementation (`dirsql::db::parse_table_name`) so the JS
6
- * SDK and the orchestrator agree on table-name resolution.
7
- */
8
- export declare function parseTableName(ddl: string): string | null;
@@ -1,15 +0,0 @@
1
- // `parseTableName` — table-name resolution delegated to the Rust core.
2
- //
3
- // Split out of the public barrel (`index.ts`) so it carries a colocated
4
- // unit test instead of an exemption (#239).
5
- import { getCore } from "./core.js";
6
- /**
7
- * Parse the table name out of a `CREATE TABLE <name> (...)` DDL.
8
- *
9
- * Returns `null` for a DDL the parser doesn't recognize. Backed by the
10
- * core Rust implementation (`dirsql::db::parse_table_name`) so the JS
11
- * SDK and the orchestrator agree on table-name resolution.
12
- */
13
- export function parseTableName(ddl) {
14
- return getCore().parseTableName(ddl);
15
- }