dirsql 0.3.24 → 0.3.26

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.
@@ -1,23 +1,21 @@
1
- import { afterEach, beforeEach, describe, expect, it, vi } from "vitest";
2
- import { __setCoreForTesting, } from "../../index.js";
1
+ import { describe, expect, it, vi } from "vitest";
3
2
  import { buildTables } from "./buildTables.js";
3
+ // `buildTables`'s only collaborator is `parseTableName` from the core barrel.
4
+ // Mock it so the SUT picks up the fake directly -- no real core, no
5
+ // `__setCoreForTesting` seam.
6
+ // Anchor the double to the real barrel (so it can't drift), then override the
7
+ // only collaborator `buildTables` reaches for. The barrel's `parseTableName`
8
+ // lazy-loads the native core *when called*; the fake below is what runs, so
9
+ // the real native implementation is never invoked.
10
+ vi.mock("../../index.js", async () => ({
11
+ ...(await vi.importActual("../../index.js")),
12
+ parseTableName: vi.fn((ddl) => /CREATE\s+TABLE\s+(\w+)/i.exec(ddl)?.[1] ?? null),
13
+ }));
4
14
  const noopExtract = () => [];
5
15
  function fakeApp(tables) {
6
16
  return { _options: { tables } };
7
17
  }
8
18
  describe("buildTables", () => {
9
- beforeEach(() => {
10
- __setCoreForTesting({
11
- // biome-ignore lint/suspicious/noExplicitAny: minimal core stub
12
- DirSQL: {},
13
- parseTableName: vi
14
- .fn()
15
- .mockImplementation((ddl) => /CREATE\s+TABLE\s+(\w+)/i.exec(ddl)?.[1] ?? null),
16
- });
17
- });
18
- afterEach(() => {
19
- __setCoreForTesting(null);
20
- });
21
19
  it("returns an empty map when the app has no tables", () => {
22
20
  expect(buildTables(fakeApp([]))).toEqual(new Map());
23
21
  });
@@ -1 +1 @@
1
- {"version":3,"file":"buildTables.test.js","sourceRoot":"","sources":["../../../src/cli/interpret/buildTables.test.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"buildTables.test.js","sourceRoot":"","sources":["../../../src/cli/interpret/buildTables.test.ts"],"names":[],"mappings":"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"}
@@ -1,10 +1,23 @@
1
- import { Readable } from "node:stream";
2
1
  import { afterEach, beforeEach, describe, expect, it, vi, } from "vitest";
3
- import * as buildTablesMod from "./buildTables.js";
4
- import * as dispatchMod from "./dispatchExtract.js";
2
+ import { buildTables } from "./buildTables.js";
3
+ import { dispatchExtract } from "./dispatchExtract.js";
5
4
  import { interpret } from "./interpret.js";
6
- import * as loadAppMod from "./loadApp.js";
7
- import * as writeMod from "./writeMessage.js";
5
+ import { loadApp } from "./loadApp.js";
6
+ import { writeMessage } from "./writeMessage.js";
7
+ // Every collaborator is mocked so the test isolates `interpret`'s glue logic.
8
+ // `node:readline`'s `createInterface` is faked to return an async iterable of
9
+ // lines directly -- this stands in for the line-buffered read over stdin, so
10
+ // the test never needs a real `Readable` stream.
11
+ vi.mock("./buildTables.js");
12
+ vi.mock("./dispatchExtract.js");
13
+ vi.mock("./loadApp.js");
14
+ vi.mock("./writeMessage.js");
15
+ vi.mock("node:readline", async () => ({
16
+ ...(await vi.importActual("node:readline")),
17
+ createInterface: vi.fn(),
18
+ }));
19
+ // Imported after the mock so we get the mocked module.
20
+ const { createInterface } = await import("node:readline");
8
21
  function fakeApp(overrides = {}) {
9
22
  const app = {
10
23
  ready: Promise.resolve(),
@@ -14,8 +27,14 @@ function fakeApp(overrides = {}) {
14
27
  };
15
28
  return app;
16
29
  }
17
- function asLines(lines) {
18
- return Readable.from(lines.map((l) => `${l}\n`));
30
+ // Fake the readline interface as an async iterable yielding the given lines.
31
+ function stubLines(lines) {
32
+ vi.mocked(createInterface).mockReturnValue((async function* () {
33
+ for (const l of lines) {
34
+ yield l;
35
+ }
36
+ // biome-ignore lint/suspicious/noExplicitAny: minimal readline stub
37
+ })());
19
38
  }
20
39
  describe("interpret", () => {
21
40
  let stderrWrite;
@@ -23,12 +42,12 @@ describe("interpret", () => {
23
42
  stderrWrite = vi.fn();
24
43
  vi.stubGlobal("process", {
25
44
  ...process,
26
- stdin: asLines([]),
27
45
  stderr: { write: stderrWrite },
28
46
  });
29
- vi.spyOn(writeMod, "writeMessage").mockImplementation(() => { });
30
- vi.spyOn(buildTablesMod, "buildTables").mockReturnValue(new Map());
31
- vi.spyOn(dispatchMod, "dispatchExtract").mockResolvedValue({
47
+ stubLines([]);
48
+ vi.mocked(writeMessage).mockImplementation(() => { });
49
+ vi.mocked(buildTables).mockReturnValue(new Map());
50
+ vi.mocked(dispatchExtract).mockResolvedValue({
32
51
  type: "result",
33
52
  id: 1,
34
53
  ok: true,
@@ -45,12 +64,12 @@ describe("interpret", () => {
45
64
  expect(stderrWrite).toHaveBeenCalledExactlyOnceWith("dirsql interpret: expected one config path, got 0\n");
46
65
  });
47
66
  it("returns 1 and writes a dirsql-prefixed line when loadApp throws", async () => {
48
- vi.spyOn(loadAppMod, "loadApp").mockRejectedValue(new Error("no app"));
67
+ vi.mocked(loadApp).mockRejectedValue(new Error("no app"));
49
68
  expect(await interpret("bad.mjs")).toBe(1);
50
69
  expect(stderrWrite).toHaveBeenCalledExactlyOnceWith("dirsql interpret: no app\n");
51
70
  });
52
71
  it("coerces non-Error throws via String() in the stderr message", async () => {
53
- vi.spyOn(loadAppMod, "loadApp").mockRejectedValue("plain string");
72
+ vi.mocked(loadApp).mockRejectedValue("plain string");
54
73
  expect(await interpret("bad.mjs")).toBe(1);
55
74
  expect(stderrWrite).toHaveBeenCalledExactlyOnceWith("dirsql interpret: plain string\n");
56
75
  });
@@ -60,9 +79,9 @@ describe("interpret", () => {
60
79
  const app = fakeApp({
61
80
  toJSON: () => ({ root: "/here", tables: [], ignore: [], persist: false }),
62
81
  });
63
- vi.spyOn(loadAppMod, "loadApp").mockResolvedValue(app);
82
+ vi.mocked(loadApp).mockResolvedValue(app);
64
83
  await interpret("good.mjs");
65
- expect(writeMod.writeMessage).toHaveBeenCalledWith({
84
+ expect(writeMessage).toHaveBeenCalledWith({
66
85
  type: "config",
67
86
  state: { root: "/here", tables: [], ignore: [], persist: false },
68
87
  });
@@ -75,77 +94,57 @@ describe("interpret", () => {
75
94
  const app = fakeApp({
76
95
  ready: { catch: catchSpy },
77
96
  });
78
- vi.spyOn(loadAppMod, "loadApp").mockResolvedValue(app);
97
+ vi.mocked(loadApp).mockResolvedValue(app);
79
98
  await interpret("good.mjs");
80
99
  expect(catchSpy).toHaveBeenCalledOnce();
81
100
  });
82
101
  });
83
102
  describe("extract loop", () => {
84
103
  it("dispatches one extract request and writes the response", async () => {
85
- vi.spyOn(loadAppMod, "loadApp").mockResolvedValue(fakeApp());
104
+ vi.mocked(loadApp).mockResolvedValue(fakeApp());
86
105
  const req = { type: "extract", id: 1, table: "t", path: "/a" };
87
- vi.stubGlobal("process", {
88
- ...process,
89
- stdin: asLines([JSON.stringify(req)]),
90
- stderr: { write: stderrWrite },
91
- });
106
+ stubLines([JSON.stringify(req)]);
92
107
  const expected = {
93
108
  type: "result",
94
109
  id: 1,
95
110
  ok: true,
96
111
  rows: [{ row: "/a" }],
97
112
  };
98
- vi.mocked(dispatchMod.dispatchExtract).mockResolvedValue(expected);
113
+ vi.mocked(dispatchExtract).mockResolvedValue(expected);
99
114
  expect(await interpret("good.mjs")).toBe(0);
100
- expect(dispatchMod.dispatchExtract).toHaveBeenCalledWith(req, new Map());
115
+ expect(dispatchExtract).toHaveBeenCalledWith(req, new Map());
101
116
  // handshake first, then response
102
- expect(writeMod.writeMessage).toHaveBeenCalledTimes(2);
103
- expect(writeMod.writeMessage).toHaveBeenLastCalledWith(expected);
117
+ expect(writeMessage).toHaveBeenCalledTimes(2);
118
+ expect(writeMessage).toHaveBeenLastCalledWith(expected);
104
119
  });
105
120
  it("skips blank lines silently", async () => {
106
- vi.spyOn(loadAppMod, "loadApp").mockResolvedValue(fakeApp());
107
- vi.stubGlobal("process", {
108
- ...process,
109
- stdin: asLines(["", " "]),
110
- stderr: { write: stderrWrite },
111
- });
121
+ vi.mocked(loadApp).mockResolvedValue(fakeApp());
122
+ stubLines(["", " "]);
112
123
  expect(await interpret("good.mjs")).toBe(0);
113
- expect(dispatchMod.dispatchExtract).not.toHaveBeenCalled();
124
+ expect(dispatchExtract).not.toHaveBeenCalled();
114
125
  // handshake only
115
- expect(writeMod.writeMessage).toHaveBeenCalledOnce();
126
+ expect(writeMessage).toHaveBeenCalledOnce();
116
127
  });
117
128
  it("skips malformed JSON silently", async () => {
118
- vi.spyOn(loadAppMod, "loadApp").mockResolvedValue(fakeApp());
119
- vi.stubGlobal("process", {
120
- ...process,
121
- stdin: asLines(["not json", "{also bad"]),
122
- stderr: { write: stderrWrite },
123
- });
129
+ vi.mocked(loadApp).mockResolvedValue(fakeApp());
130
+ stubLines(["not json", "{also bad"]);
124
131
  expect(await interpret("good.mjs")).toBe(0);
125
- expect(dispatchMod.dispatchExtract).not.toHaveBeenCalled();
132
+ expect(dispatchExtract).not.toHaveBeenCalled();
126
133
  });
127
134
  it("skips non-extract messages silently", async () => {
128
- vi.spyOn(loadAppMod, "loadApp").mockResolvedValue(fakeApp());
129
- vi.stubGlobal("process", {
130
- ...process,
131
- stdin: asLines([JSON.stringify({ type: "ping" })]),
132
- stderr: { write: stderrWrite },
133
- });
135
+ vi.mocked(loadApp).mockResolvedValue(fakeApp());
136
+ stubLines([JSON.stringify({ type: "ping" })]);
134
137
  expect(await interpret("good.mjs")).toBe(0);
135
- expect(dispatchMod.dispatchExtract).not.toHaveBeenCalled();
138
+ expect(dispatchExtract).not.toHaveBeenCalled();
136
139
  });
137
140
  it("skips a null / non-object JSON payload silently", async () => {
138
- vi.spyOn(loadAppMod, "loadApp").mockResolvedValue(fakeApp());
139
- vi.stubGlobal("process", {
140
- ...process,
141
- stdin: asLines(["null", "42", "[]"]),
142
- stderr: { write: stderrWrite },
143
- });
141
+ vi.mocked(loadApp).mockResolvedValue(fakeApp());
142
+ stubLines(["null", "42", "[]"]);
144
143
  expect(await interpret("good.mjs")).toBe(0);
145
- expect(dispatchMod.dispatchExtract).not.toHaveBeenCalled();
144
+ expect(dispatchExtract).not.toHaveBeenCalled();
146
145
  });
147
146
  it("returns 0 when stdin closes", async () => {
148
- vi.spyOn(loadAppMod, "loadApp").mockResolvedValue(fakeApp());
147
+ vi.mocked(loadApp).mockResolvedValue(fakeApp());
149
148
  expect(await interpret("good.mjs")).toBe(0);
150
149
  });
151
150
  });
@@ -1 +1 @@
1
- {"version":3,"file":"interpret.test.js","sourceRoot":"","sources":["../../../src/cli/interpret/interpret.test.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"interpret.test.js","sourceRoot":"","sources":["../../../src/cli/interpret/interpret.test.ts"],"names":[],"mappings":"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"}
@@ -1,3 +1,5 @@
1
1
  import type { DirSQL } from "../../index.js";
2
- export declare function loadApp(configPath: string): Promise<DirSQL>;
2
+ export declare function loadApp(configPath: string, importer?: (url: string) => Promise<{
3
+ default?: unknown;
4
+ }>): Promise<DirSQL>;
3
5
  //# sourceMappingURL=loadApp.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"loadApp.d.ts","sourceRoot":"","sources":["../../../src/cli/interpret/loadApp.ts"],"names":[],"mappings":"AAWA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,gBAAgB,CAAC;AAE7C,wBAAsB,OAAO,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAQjE"}
1
+ {"version":3,"file":"loadApp.d.ts","sourceRoot":"","sources":["../../../src/cli/interpret/loadApp.ts"],"names":[],"mappings":"AAWA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,gBAAgB,CAAC;AAM7C,wBAAsB,OAAO,CAC3B,UAAU,EAAE,MAAM,EAClB,QAAQ,GAAE,CAAC,GAAG,EAAE,MAAM,KAAK,OAAO,CAAC;IAAE,OAAO,CAAC,EAAE,OAAO,CAAA;CAAE,CAC3C,GACZ,OAAO,CAAC,MAAM,CAAC,CAQjB"}
@@ -8,8 +8,12 @@
8
8
  // no `default` export. The launcher in `cli/main.ts` catches both as
9
9
  // startup failures.
10
10
  import { pathToFileURL } from "node:url";
11
- export async function loadApp(configPath) {
12
- const mod = await import(pathToFileURL(configPath).href);
11
+ // The dynamic `import()` is the effectful collaborator. It can't be
12
+ // `vi.mock()`-ed (the specifier is a computed file URL), so it's exposed as
13
+ // an injected `importer` callback. The default preserves production behavior
14
+ // exactly; tests pass a fake `importer` to isolate the unit.
15
+ export async function loadApp(configPath, importer = (url) => import(url)) {
16
+ const mod = await importer(pathToFileURL(configPath).href);
13
17
  if (!mod.default) {
14
18
  throw new Error(`${configPath}: module must default-export a DirSQL instance`);
15
19
  }
@@ -1 +1 @@
1
- {"version":3,"file":"loadApp.js","sourceRoot":"","sources":["../../../src/cli/interpret/loadApp.ts"],"names":[],"mappings":"AAAA,qEAAqE;AACrE,sEAAsE;AACtE,oEAAoE;AACpE,oEAAoE;AACpE,qBAAqB;AACrB,EAAE;AACF,qEAAqE;AACrE,qEAAqE;AACrE,oBAAoB;AAEpB,OAAO,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AAGzC,MAAM,CAAC,KAAK,UAAU,OAAO,CAAC,UAAkB;IAC9C,MAAM,GAAG,GAAG,MAAM,MAAM,CAAC,aAAa,CAAC,UAAU,CAAC,CAAC,IAAI,CAAC,CAAC;IACzD,IAAI,CAAC,GAAG,CAAC,OAAO,EAAE,CAAC;QACjB,MAAM,IAAI,KAAK,CACb,GAAG,UAAU,gDAAgD,CAC9D,CAAC;IACJ,CAAC;IACD,OAAO,GAAG,CAAC,OAAiB,CAAC;AAC/B,CAAC"}
1
+ {"version":3,"file":"loadApp.js","sourceRoot":"","sources":["../../../src/cli/interpret/loadApp.ts"],"names":[],"mappings":"AAAA,qEAAqE;AACrE,sEAAsE;AACtE,oEAAoE;AACpE,oEAAoE;AACpE,qBAAqB;AACrB,EAAE;AACF,qEAAqE;AACrE,qEAAqE;AACrE,oBAAoB;AAEpB,OAAO,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AAGzC,oEAAoE;AACpE,4EAA4E;AAC5E,6EAA6E;AAC7E,6DAA6D;AAC7D,MAAM,CAAC,KAAK,UAAU,OAAO,CAC3B,UAAkB,EAClB,WAA4D,CAAC,GAAG,EAAE,EAAE,CAClE,MAAM,CAAC,GAAG,CAAC;IAEb,MAAM,GAAG,GAAG,MAAM,QAAQ,CAAC,aAAa,CAAC,UAAU,CAAC,CAAC,IAAI,CAAC,CAAC;IAC3D,IAAI,CAAC,GAAG,CAAC,OAAO,EAAE,CAAC;QACjB,MAAM,IAAI,KAAK,CACb,GAAG,UAAU,gDAAgD,CAC9D,CAAC;IACJ,CAAC;IACD,OAAO,GAAG,CAAC,OAAiB,CAAC;AAC/B,CAAC"}
@@ -1,41 +1,33 @@
1
- import { mkdtempSync, rmSync, writeFileSync } from "node:fs";
2
- import { tmpdir } from "node:os";
3
- import { join } from "node:path";
4
- import { afterEach, beforeEach, describe, expect, it } from "vitest";
1
+ import { describe, expect, it, vi } from "vitest";
5
2
  import { loadApp } from "./loadApp.js";
6
3
  describe("loadApp", () => {
7
- let dir;
8
- beforeEach(() => {
9
- dir = mkdtempSync(join(tmpdir(), "dirsql-loadapp-"));
10
- });
11
- afterEach(() => {
12
- rmSync(dir, { recursive: true, force: true });
13
- });
14
- it("returns the default export of an .mjs config", async () => {
15
- const path = join(dir, "config.mjs");
16
- writeFileSync(path, "export default { sentinel: 'value' };\n");
17
- const app = (await loadApp(path));
4
+ it("returns the default export the importer yields", async () => {
5
+ const importer = vi
6
+ .fn()
7
+ .mockResolvedValue({ default: { sentinel: "value" } });
8
+ const app = (await loadApp("/cfg/config.mjs", importer));
18
9
  expect(app.sentinel).toBe("value");
19
- });
20
- it("returns the module.exports of a .cjs config", async () => {
21
- const path = join(dir, "config.cjs");
22
- writeFileSync(path, "module.exports = { sentinel: 'cjs' };\n");
23
- const app = (await loadApp(path));
24
- expect(app.sentinel).toBe("cjs");
10
+ // The importer receives the file:// URL form of the config path.
11
+ expect(importer).toHaveBeenCalledWith(expect.stringMatching(/^file:.*config\.mjs$/));
25
12
  });
26
13
  it("throws a path-aware error when the module has no default export", async () => {
27
- const path = join(dir, "no_default.mjs");
28
- writeFileSync(path, "export const x = 1;\n");
29
- await expect(loadApp(path)).rejects.toThrow(/must default-export a DirSQL instance/);
30
- await expect(loadApp(path)).rejects.toThrow(path);
14
+ const importer = vi.fn().mockResolvedValue({ x: 1 });
15
+ await expect(loadApp("/cfg/no_default.mjs", importer)).rejects.toThrow(/must default-export a DirSQL instance/);
16
+ await expect(loadApp("/cfg/no_default.mjs", importer)).rejects.toThrow("/cfg/no_default.mjs");
31
17
  });
32
18
  it("propagates errors thrown during module evaluation", async () => {
33
- const path = join(dir, "boom.mjs");
34
- writeFileSync(path, "throw new Error('synthetic boom');\n");
35
- await expect(loadApp(path)).rejects.toThrow(/synthetic boom/);
19
+ const importer = vi.fn().mockRejectedValue(new Error("synthetic boom"));
20
+ await expect(loadApp("/cfg/boom.mjs", importer)).rejects.toThrow(/synthetic boom/);
21
+ });
22
+ it("rejects when the importer rejects (missing file)", async () => {
23
+ const importer = vi.fn().mockRejectedValue(new Error("Cannot find module"));
24
+ await expect(loadApp("/cfg/nope.mjs", importer)).rejects.toThrow();
36
25
  });
37
- it("rejects when the file does not exist", async () => {
38
- await expect(loadApp(join(dir, "nope.mjs"))).rejects.toThrow();
26
+ it("defaults to the real dynamic import when no importer is injected", async () => {
27
+ // Exercises the default `importer` arg (a real `import()`). The path
28
+ // doesn't exist, so the underlying import rejects -- which is all we
29
+ // need to drive the default callback's single line.
30
+ await expect(loadApp("/no/such/dirsql.config.mjs")).rejects.toThrow();
39
31
  });
40
32
  });
41
33
  //# sourceMappingURL=loadApp.test.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"loadApp.test.js","sourceRoot":"","sources":["../../../src/cli/interpret/loadApp.test.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,EAAE,aAAa,EAAE,MAAM,SAAS,CAAC;AAC7D,OAAO,EAAE,MAAM,EAAE,MAAM,SAAS,CAAC;AACjC,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AACjC,OAAO,EAAE,SAAS,EAAE,UAAU,EAAE,QAAQ,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,QAAQ,CAAC;AACrE,OAAO,EAAE,OAAO,EAAE,MAAM,cAAc,CAAC;AAEvC,QAAQ,CAAC,SAAS,EAAE,GAAG,EAAE;IACvB,IAAI,GAAW,CAAC;IAEhB,UAAU,CAAC,GAAG,EAAE;QACd,GAAG,GAAG,WAAW,CAAC,IAAI,CAAC,MAAM,EAAE,EAAE,iBAAiB,CAAC,CAAC,CAAC;IACvD,CAAC,CAAC,CAAC;IAEH,SAAS,CAAC,GAAG,EAAE;QACb,MAAM,CAAC,GAAG,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC;IAChD,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,8CAA8C,EAAE,KAAK,IAAI,EAAE;QAC5D,MAAM,IAAI,GAAG,IAAI,CAAC,GAAG,EAAE,YAAY,CAAC,CAAC;QACrC,aAAa,CAAC,IAAI,EAAE,yCAAyC,CAAC,CAAC;QAC/D,MAAM,GAAG,GAAG,CAAC,MAAM,OAAO,CAAC,IAAI,CAAC,CAAoC,CAAC;QACrE,MAAM,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;IACrC,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,6CAA6C,EAAE,KAAK,IAAI,EAAE;QAC3D,MAAM,IAAI,GAAG,IAAI,CAAC,GAAG,EAAE,YAAY,CAAC,CAAC;QACrC,aAAa,CAAC,IAAI,EAAE,yCAAyC,CAAC,CAAC;QAC/D,MAAM,GAAG,GAAG,CAAC,MAAM,OAAO,CAAC,IAAI,CAAC,CAAoC,CAAC;QACrE,MAAM,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;IACnC,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,iEAAiE,EAAE,KAAK,IAAI,EAAE;QAC/E,MAAM,IAAI,GAAG,IAAI,CAAC,GAAG,EAAE,gBAAgB,CAAC,CAAC;QACzC,aAAa,CAAC,IAAI,EAAE,uBAAuB,CAAC,CAAC;QAC7C,MAAM,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,OAAO,CAAC,OAAO,CACzC,uCAAuC,CACxC,CAAC;QACF,MAAM,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,OAAO,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;IACpD,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,mDAAmD,EAAE,KAAK,IAAI,EAAE;QACjE,MAAM,IAAI,GAAG,IAAI,CAAC,GAAG,EAAE,UAAU,CAAC,CAAC;QACnC,aAAa,CAAC,IAAI,EAAE,sCAAsC,CAAC,CAAC;QAC5D,MAAM,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,OAAO,CAAC,OAAO,CAAC,gBAAgB,CAAC,CAAC;IAChE,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,sCAAsC,EAAE,KAAK,IAAI,EAAE;QACpD,MAAM,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC,GAAG,EAAE,UAAU,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,OAAO,EAAE,CAAC;IACjE,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC"}
1
+ {"version":3,"file":"loadApp.test.js","sourceRoot":"","sources":["../../../src/cli/interpret/loadApp.test.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,EAAE,EAAE,EAAE,EAAE,EAAE,MAAM,QAAQ,CAAC;AAClD,OAAO,EAAE,OAAO,EAAE,MAAM,cAAc,CAAC;AAEvC,QAAQ,CAAC,SAAS,EAAE,GAAG,EAAE;IACvB,EAAE,CAAC,gDAAgD,EAAE,KAAK,IAAI,EAAE;QAC9D,MAAM,QAAQ,GAAG,EAAE;aAChB,EAAE,EAAE;aACJ,iBAAiB,CAAC,EAAE,OAAO,EAAE,EAAE,QAAQ,EAAE,OAAO,EAAE,EAAE,CAAC,CAAC;QACzD,MAAM,GAAG,GAAG,CAAC,MAAM,OAAO,CAAC,iBAAiB,EAAE,QAAQ,CAAC,CAEtD,CAAC;QACF,MAAM,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;QACnC,iEAAiE;QACjE,MAAM,CAAC,QAAQ,CAAC,CAAC,oBAAoB,CACnC,MAAM,CAAC,cAAc,CAAC,sBAAsB,CAAC,CAC9C,CAAC;IACJ,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,iEAAiE,EAAE,KAAK,IAAI,EAAE;QAC/E,MAAM,QAAQ,GAAG,EAAE,CAAC,EAAE,EAAE,CAAC,iBAAiB,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC;QACrD,MAAM,MAAM,CAAC,OAAO,CAAC,qBAAqB,EAAE,QAAQ,CAAC,CAAC,CAAC,OAAO,CAAC,OAAO,CACpE,uCAAuC,CACxC,CAAC;QACF,MAAM,MAAM,CAAC,OAAO,CAAC,qBAAqB,EAAE,QAAQ,CAAC,CAAC,CAAC,OAAO,CAAC,OAAO,CACpE,qBAAqB,CACtB,CAAC;IACJ,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,mDAAmD,EAAE,KAAK,IAAI,EAAE;QACjE,MAAM,QAAQ,GAAG,EAAE,CAAC,EAAE,EAAE,CAAC,iBAAiB,CAAC,IAAI,KAAK,CAAC,gBAAgB,CAAC,CAAC,CAAC;QACxE,MAAM,MAAM,CAAC,OAAO,CAAC,eAAe,EAAE,QAAQ,CAAC,CAAC,CAAC,OAAO,CAAC,OAAO,CAC9D,gBAAgB,CACjB,CAAC;IACJ,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,kDAAkD,EAAE,KAAK,IAAI,EAAE;QAChE,MAAM,QAAQ,GAAG,EAAE,CAAC,EAAE,EAAE,CAAC,iBAAiB,CAAC,IAAI,KAAK,CAAC,oBAAoB,CAAC,CAAC,CAAC;QAC5E,MAAM,MAAM,CAAC,OAAO,CAAC,eAAe,EAAE,QAAQ,CAAC,CAAC,CAAC,OAAO,CAAC,OAAO,EAAE,CAAC;IACrE,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,kEAAkE,EAAE,KAAK,IAAI,EAAE;QAChF,qEAAqE;QACrE,qEAAqE;QACrE,oDAAoD;QACpD,MAAM,MAAM,CAAC,OAAO,CAAC,4BAA4B,CAAC,CAAC,CAAC,OAAO,CAAC,OAAO,EAAE,CAAC;IACxE,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC"}
@@ -1,22 +1,22 @@
1
1
  // Unit tests for `resolveConfig`.
2
- import { mkdtempSync, rmSync, writeFileSync } from "node:fs";
3
- import { tmpdir } from "node:os";
4
- import { isAbsolute, join } from "node:path";
5
- import { afterEach, beforeEach, describe, expect, it } from "vitest";
2
+ import { readFileSync } from "node:fs";
3
+ import { describe, expect, it, vi } from "vitest";
6
4
  import { resolveConfig } from "./resolveConfig.js";
5
+ // `resolveConfig`'s only effectful collaborator is `readFileSync`; `node:path`
6
+ // and `smol-toml` are pure. Mock fs so the test never touches a real file --
7
+ // each "with a config file" case stubs the TOML body it wants to parse.
8
+ vi.mock("node:fs", async () => ({
9
+ ...(await vi.importActual("node:fs")),
10
+ readFileSync: vi.fn(),
11
+ }));
7
12
  const noopExtract = () => [];
13
+ // Fixed posix config path. CI is linux, so `dirname(resolve(cfgPath))` is
14
+ // deterministically `/cfg` -- relative config paths resolve against it.
15
+ const cfgPath = "/cfg/.dirsql.toml";
16
+ const cfgDir = "/cfg";
8
17
  describe("resolveConfig", () => {
9
- let dir;
10
- let cfgPath;
11
- beforeEach(() => {
12
- dir = mkdtempSync(join(tmpdir(), "dirsql-resolveConfig-"));
13
- cfgPath = join(dir, ".dirsql.toml");
14
- });
15
- afterEach(() => {
16
- rmSync(dir, { recursive: true, force: true });
17
- });
18
18
  const writeCfg = (body) => {
19
- writeFileSync(cfgPath, body);
19
+ vi.mocked(readFileSync).mockReturnValue(body);
20
20
  };
21
21
  describe("without a config file", () => {
22
22
  it("forwards the root kwarg, defaults everything else", () => {
@@ -67,8 +67,7 @@ describe("resolveConfig", () => {
67
67
  it("resolves a relative [dirsql].root against the config file's parent", () => {
68
68
  writeCfg('[dirsql]\nroot = "data"\n');
69
69
  const out = resolveConfig({ config: cfgPath });
70
- expect(out.root).toBe(join(dir, "data"));
71
- expect(isAbsolute(out.root)).toBe(true);
70
+ expect(out.root).toBe("/cfg/data");
72
71
  });
73
72
  it("preserves an absolute [dirsql].root verbatim", () => {
74
73
  writeCfg('[dirsql]\nroot = "/other/abs/path"\n');
@@ -78,17 +77,17 @@ describe("resolveConfig", () => {
78
77
  it("defaults the root to the config file's parent when [dirsql].root is absent", () => {
79
78
  writeCfg('[dirsql]\nignore = ["x"]\n');
80
79
  const out = resolveConfig({ config: cfgPath });
81
- expect(out.root).toBe(dir);
80
+ expect(out.root).toBe(cfgDir);
82
81
  });
83
82
  it("defaults the root to the config file's parent when [dirsql] is absent entirely", () => {
84
83
  writeCfg('[[table]]\nddl = "CREATE TABLE t (x TEXT)"\nglob = "*.json"\n');
85
84
  const out = resolveConfig({ config: cfgPath });
86
- expect(out.root).toBe(dir);
85
+ expect(out.root).toBe(cfgDir);
87
86
  });
88
87
  it("handles a non-string [dirsql].root by falling back to the config dir", () => {
89
88
  writeCfg("[dirsql]\nroot = 42\n");
90
89
  const out = resolveConfig({ config: cfgPath });
91
- expect(out.root).toBe(dir);
90
+ expect(out.root).toBe(cfgDir);
92
91
  });
93
92
  it("reads [[table]] entries with strict defaulting to false", () => {
94
93
  writeCfg('[[table]]\nddl = "CREATE TABLE t (x TEXT)"\nglob = "*.json"\n');
@@ -134,7 +133,7 @@ describe("resolveConfig", () => {
134
133
  it("resolves a relative [dirsql].persist_path against the config dir", () => {
135
134
  writeCfg('[dirsql]\npersist = true\npersist_path = "cache/dirsql.db"\n');
136
135
  const out = resolveConfig({ config: cfgPath });
137
- expect(out.persistPath).toBe(join(dir, "cache/dirsql.db"));
136
+ expect(out.persistPath).toBe("/cfg/cache/dirsql.db");
138
137
  });
139
138
  it("preserves an absolute [dirsql].persist_path verbatim", () => {
140
139
  writeCfg('[dirsql]\npersist_path = "/var/cache/dirsql.db"\n');
@@ -1 +1 @@
1
- {"version":3,"file":"resolveConfig.test.js","sourceRoot":"","sources":["../src/resolveConfig.test.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"resolveConfig.test.js","sourceRoot":"","sources":["../src/resolveConfig.test.ts"],"names":[],"mappings":"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"}
package/docs/api/index.md CHANGED
@@ -188,11 +188,12 @@ import { Table } from 'dirsql';
188
188
  ::: code-group
189
189
 
190
190
  ```python [Python]
191
- Table(*, ddl: str, glob: str, extract: Callable[[str], list[dict]])
191
+ Table(*, ddl: str, glob: str, extract: Callable[[str], list[dict]], strict: bool = False)
192
192
  ```
193
193
 
194
194
  ```rust [Rust]
195
- Table::new(ddl: &str, glob: &str, extract: fn(&str) -> Vec<Value>)
195
+ // Row = HashMap<String, Value>
196
+ Table::new(ddl: &str, glob: &str, extract: fn(&str) -> Vec<HashMap<String, Value>>)
196
197
  ```
197
198
 
198
199
  ```typescript [TypeScript]
@@ -207,7 +208,8 @@ Defines a mapping from files to SQLite table rows.
207
208
 
208
209
  - `ddl` -- A `CREATE TABLE` statement. The table name is parsed from this DDL.
209
210
  - `glob` -- A glob pattern matched against file paths relative to the root directory.
210
- - `extract` -- A callable `(path) -> list[dict]`. Receives the absolute filesystem path of the matched file. `dirsql` does not read file contents; a callback that needs the file body reads `path` itself. Returns a list of dicts/maps mapping column names to values. Return an empty list to skip a file.
211
+ - `extract` -- A callable `(path) -> list[dict]`. Receives the path of the matched file -- relative to the scan root, or absolute when `root` is absolute. `dirsql` does not read file contents; a callback that needs the file body reads `path` itself. Returns a list of dicts/maps mapping column names to values. Return an empty list to skip a file.
212
+ - `strict` -- Optional (default `False`). Controls row/schema validation. In the default relaxed mode, extra row keys are dropped and missing columns become `NULL`. When `True`, every row key must be a valid column identifier and any extra or missing key raises an error. Surfaced in [serialization](#serialization) above as part of each table's `{ ddl, glob, strict }`.
211
213
 
212
214
  **Attributes:**
213
215
 
@@ -231,7 +233,7 @@ use dirsql::RowEvent;
231
233
  ```
232
234
 
233
235
  ```typescript [TypeScript]
234
- import { RowEvent } from 'dirsql';
236
+ import type { RowEvent } from 'dirsql';
235
237
  ```
236
238
 
237
239
  :::
@@ -171,7 +171,7 @@ const results = await db.query(`
171
171
 
172
172
  1. `dirsql` walks the directory tree
173
173
  2. Files matching each table's glob pattern are identified
174
- 3. The `extract` function receives each matched file's absolute path and returns rows
174
+ 3. The `extract` function receives each matched file's path (relative to the scan root, or absolute when `root` is absolute) and returns rows
175
175
  4. Rows are inserted into an in-memory SQLite database
176
176
  5. SQL queries run against that database
177
177
 
@@ -28,6 +28,7 @@ async def main():
28
28
  ),
29
29
  ],
30
30
  )
31
+ await db.ready()
31
32
 
32
33
  # Query (runs in a thread, does not block the event loop)
33
34
  results = await db.query("SELECT * FROM items WHERE value > 10")
@@ -37,7 +38,31 @@ asyncio.run(main())
37
38
  ```
38
39
 
39
40
  ```rust [Rust]
40
- use dirsql::{DirSQL, Table};
41
+ use dirsql::{DirSQL, Table, Value};
42
+ use std::collections::HashMap;
43
+
44
+ // See `row_from_json` in getting-started.md for a reusable helper that
45
+ // turns a JSON object into a dirsql row (dirsql::Value is not Deserialize,
46
+ // so a row can't be produced by serde_json::from_str directly).
47
+ fn row_from_json(raw: &str) -> HashMap<String, Value> {
48
+ let v: serde_json::Value = serde_json::from_str(raw).unwrap();
49
+ let serde_json::Value::Object(obj) = v else { return HashMap::new() };
50
+ obj.into_iter()
51
+ .map(|(k, val)| {
52
+ let v = match val {
53
+ serde_json::Value::String(s) => Value::Text(s),
54
+ serde_json::Value::Number(n) => n
55
+ .as_i64()
56
+ .map(Value::Integer)
57
+ .unwrap_or_else(|| Value::Real(n.as_f64().unwrap_or(0.0))),
58
+ serde_json::Value::Bool(b) => Value::Integer(b as i64),
59
+ serde_json::Value::Null => Value::Null,
60
+ other => Value::Text(other.to_string()),
61
+ };
62
+ (k, v)
63
+ })
64
+ .collect()
65
+ }
41
66
 
42
67
  #[tokio::main]
43
68
  async fn main() -> Result<(), Box<dyn std::error::Error>> {
@@ -47,7 +72,7 @@ async fn main() -> Result<(), Box<dyn std::error::Error>> {
47
72
  Table::new(
48
73
  "CREATE TABLE items (name TEXT, value INTEGER)",
49
74
  "data/*.json",
50
- |path| vec![serde_json::from_str(&std::fs::read_to_string(path).unwrap()).unwrap()],
75
+ |path| vec![row_from_json(&std::fs::read_to_string(path).unwrap())],
51
76
  ),
52
77
  ],
53
78
  )?;
@@ -83,7 +108,7 @@ console.log(results);
83
108
  ## Constructor
84
109
 
85
110
  ```python
86
- DirSQL(root=None, *, tables=None, ignore=None, config=None)
111
+ DirSQL(root=None, *, tables=None, ignore=None, config=None, persist=False, persist_path=None)
87
112
  ```
88
113
 
89
114
  The constructor immediately starts scanning in a background thread via `asyncio.ensure_future`. The constructor itself returns immediately without blocking.
@@ -132,15 +157,29 @@ async for event in db.watch():
132
157
  ```
133
158
 
134
159
  ```rust [Rust]
160
+ // `RowEvent` is an enum; match on the variant to destructure its fields.
161
+ // `StreamExt` (for `.next()`) comes from the `futures` crate, which is only a
162
+ // dirsql dependency under its `cli` feature -- add it to your own project:
163
+ //
164
+ // cargo add futures
165
+ use dirsql::RowEvent;
135
166
  use futures::StreamExt;
136
167
 
137
- let mut stream = db.watch();
168
+ let mut stream = db.watch()?; // watch() returns Result<WatchStream>
138
169
  while let Some(event) = stream.next().await {
139
- match event.action {
140
- Action::Insert => println!("New row in {}: {:?}", event.table, event.row),
141
- Action::Update => println!("Updated row in {}: {:?}", event.table, event.row),
142
- Action::Delete => println!("Deleted row from {}: {:?}", event.table, event.row),
143
- Action::Error => eprintln!("Error: {:?}", event.error),
170
+ match event {
171
+ RowEvent::Insert { table, row, file_path } => {
172
+ println!("New row in {table} ({file_path}): {row:?}")
173
+ }
174
+ RowEvent::Update { table, new_row, file_path, .. } => {
175
+ println!("Updated row in {table} ({file_path}): {new_row:?}")
176
+ }
177
+ RowEvent::Delete { table, row, file_path } => {
178
+ println!("Deleted row from {table} ({file_path}): {row:?}")
179
+ }
180
+ RowEvent::Error { file_path, error, .. } => {
181
+ eprintln!("Error on {file_path:?}: {error}")
182
+ }
144
183
  }
145
184
  }
146
185
  ```
@@ -188,16 +227,20 @@ async def main():
188
227
  ```
189
228
 
190
229
  ```rust [Rust]
191
- async fn watch_and_serve(db: &DirSQL) {
192
- let mut stream = db.watch();
230
+ // `.next()` needs `StreamExt` from the `futures` crate (`cargo add futures`).
231
+ use futures::StreamExt;
232
+
233
+ async fn watch_and_serve(db: &DirSQL) -> Result<(), Box<dyn std::error::Error>> {
234
+ let mut stream = db.watch()?; // watch() returns Result<WatchStream>
193
235
  while let Some(event) = stream.next().await {
194
236
  notify_clients(&event).await;
195
237
  }
238
+ Ok(())
196
239
  }
197
240
 
198
241
  #[tokio::main]
199
242
  async fn main() -> Result<(), Box<dyn std::error::Error>> {
200
- let db = DirSQL::new("./data", vec![...])?;
243
+ let db = DirSQL::new("./data", vec![/* tables */])?;
201
244
 
202
245
  tokio::join!(
203
246
  watch_and_serve(&db),
@@ -94,7 +94,7 @@ const tables: TableDef[] = [
94
94
  },
95
95
  ];
96
96
 
97
- const db = new DirSQL('./workspace', tables);
97
+ const db = new DirSQL({ root: './workspace', tables });
98
98
  ```
99
99
 
100
100
  :::
@@ -160,8 +160,9 @@ assert!(matches!(err, dirsql::DirSqlError::WriteForbidden));
160
160
  ```
161
161
 
162
162
  ```typescript [TypeScript]
163
- // Throws an Error whose message explains writes are not accepted.
164
- expect(() => db.query('DELETE FROM posts')).toThrow(/read-only/i);
163
+ // Rejects with an Error whose message explains writes are not accepted.
164
+ // `db.query` is async, so assert on the rejected promise.
165
+ await expect(db.query('DELETE FROM posts')).rejects.toThrow(/read-only/i);
165
166
  ```
166
167
 
167
168
  :::
@@ -91,7 +91,7 @@ Glob syntax follows standard Unix globbing rules. `**` matches any number of dir
91
91
 
92
92
  A callable `(path: str) -> list[dict]` that converts a file into rows.
93
93
 
94
- - `path` is the **absolute filesystem path** of the matched file
94
+ - `path` is the path of the matched file, **relative to the scan root** (or absolute when the `root` passed to `DirSQL` is absolute)
95
95
  - Return a list of dicts, where each dict maps column names to values
96
96
  - Return an empty list to skip a file
97
97
 
@@ -36,6 +36,10 @@ async for event in db.watch():
36
36
  ```
37
37
 
38
38
  ```rust [Rust]
39
+ // `StreamExt` (for `.next()`) comes from the `futures` crate. dirsql only
40
+ // depends on `futures` under its `cli` feature, so add it to your project:
41
+ //
42
+ // cargo add futures
39
43
  use dirsql::{DirSQL, RowEvent, Table, Value};
40
44
  use futures::StreamExt;
41
45
  use std::collections::HashMap;
@@ -84,8 +88,8 @@ while let Some(event) = stream.next().await {
84
88
  RowEvent::Delete { table, row, file_path } => {
85
89
  println!("delete on {table} ({file_path}): {row:?}")
86
90
  }
87
- RowEvent::Error { file_path, error } => {
88
- println!("error on {file_path:?}: {error}")
91
+ RowEvent::Error { table, file_path, error } => {
92
+ println!("error on {table:?} {file_path:?}: {error}")
89
93
  }
90
94
  }
91
95
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "dirsql",
3
- "version": "0.3.24",
3
+ "version": "0.3.26",
4
4
  "description": "Ephemeral SQL index over a local directory",
5
5
  "license": "MIT",
6
6
  "repository": "https://github.com/thekevinscott/dirsql",
@@ -195,15 +195,15 @@
195
195
  "smol-toml": "^1.6.1"
196
196
  },
197
197
  "optionalDependencies": {
198
- "@dirsql/lib-linux-x64-gnu": "0.3.24",
199
- "@dirsql/lib-linux-arm64-gnu": "0.3.24",
200
- "@dirsql/lib-darwin-x64": "0.3.24",
201
- "@dirsql/lib-darwin-arm64": "0.3.24",
202
- "@dirsql/lib-win32-x64-msvc": "0.3.24",
203
- "@dirsql/cli-linux-x64-gnu": "0.3.24",
204
- "@dirsql/cli-linux-arm64-gnu": "0.3.24",
205
- "@dirsql/cli-darwin-x64": "0.3.24",
206
- "@dirsql/cli-darwin-arm64": "0.3.24",
207
- "@dirsql/cli-win32-x64-msvc": "0.3.24"
198
+ "@dirsql/lib-linux-x64-gnu": "0.3.26",
199
+ "@dirsql/lib-linux-arm64-gnu": "0.3.26",
200
+ "@dirsql/lib-darwin-x64": "0.3.26",
201
+ "@dirsql/lib-darwin-arm64": "0.3.26",
202
+ "@dirsql/lib-win32-x64-msvc": "0.3.26",
203
+ "@dirsql/cli-linux-x64-gnu": "0.3.26",
204
+ "@dirsql/cli-linux-arm64-gnu": "0.3.26",
205
+ "@dirsql/cli-darwin-x64": "0.3.26",
206
+ "@dirsql/cli-darwin-arm64": "0.3.26",
207
+ "@dirsql/cli-win32-x64-msvc": "0.3.26"
208
208
  }
209
209
  }