@walkeros/server-destination-sqlite 4.0.0 → 4.1.0-next-1778155282668

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/README.md CHANGED
@@ -4,7 +4,7 @@ Server-side SQLite destination for
4
4
  [walkerOS](https://github.com/elbwalker/walkerOS). Writes events to a local
5
5
  SQLite file (via `better-sqlite3`) or a remote Turso / libSQL / sqld database
6
6
  (via `@libsql/client`). Driver is auto-selected from the connection URL. Both
7
- SDKs are optional peer dependencies -- install only what you need.
7
+ SDKs are optional peer dependencies, install only what you need.
8
8
 
9
9
  ## Installation
10
10
 
@@ -28,7 +28,8 @@ Local file:
28
28
  "sqlite": {
29
29
  "url": "./events.db"
30
30
  }
31
- }
31
+ },
32
+ "setup": true
32
33
  }
33
34
  }
34
35
  }
@@ -48,7 +49,8 @@ Remote Turso:
48
49
  "url": "libsql://my-db.turso.io",
49
50
  "authToken": "$env.TURSO_TOKEN"
50
51
  }
51
- }
52
+ },
53
+ "setup": true
52
54
  }
53
55
  }
54
56
  }
@@ -57,12 +59,12 @@ Remote Turso:
57
59
 
58
60
  ## Settings
59
61
 
60
- | Setting | Type | Required | Default | Description |
61
- | ------------------ | -------------------- | -------- | -------- | ---------------------------------------------------------------------------------------------------------------------------------------------- |
62
- | `sqlite.url` | `string` | Yes | -- | Connection URL. `libsql://`, `http(s)://`, `ws(s)://` route to libSQL. Anything else is treated as a local file. Use `:memory:` for in-memory. |
63
- | `sqlite.authToken` | `string` | No | -- | libSQL / Turso auth token. Ignored for local. |
64
- | `sqlite.table` | `string` | No | `events` | Target table name. |
65
- | `sqlite.schema` | `'auto' \| 'manual'` | No | `'auto'` | `auto` runs `CREATE TABLE IF NOT EXISTS` on init. `manual` skips creation (bring your own schema + mapping). |
62
+ | Setting | Type | Required | Default | Description |
63
+ | ------------------ | -------------------- | -------------- | -------- | ---------------------------------------------------------------------------------------------------------------------------------------------- |
64
+ | `sqlite.url` | `string` | Yes | `--` | Connection URL. `libsql://`, `http(s)://`, `ws(s)://` route to libSQL. Anything else is treated as a local file. Use `:memory:` for in-memory. |
65
+ | `sqlite.authToken` | `string` | No | `--` | libSQL / Turso auth token. Ignored for local. |
66
+ | `sqlite.table` | `string` | No | `events` | Target table name. |
67
+ | `sqlite.schema` | `'auto' \| 'manual'` | **DEPRECATED** | `--` | Use `config.setup` instead. `auto` maps to `setup: true`, `manual` maps to `setup: false`. Removed in next major. |
66
68
 
67
69
  ## Per-rule mapping overrides
68
70
 
@@ -70,40 +72,97 @@ Remote Turso:
70
72
  | ------------------------ | -------- | ------------------------------------ |
71
73
  | `mapping.settings.table` | `string` | Override target table for this rule. |
72
74
 
73
- ## Auto Schema
75
+ ## Setup
76
+
77
+ Create the events table and apply pragmas with one command:
78
+
79
+ ```bash
80
+ walkeros setup destination.sqlite
81
+ ```
82
+
83
+ This runs `CREATE TABLE IF NOT EXISTS` with the canonical 15-column walkerOS
84
+ Event v4 schema and applies four pragmas:
74
85
 
75
- With `schema: 'auto'` (the default), the first `init()` runs:
86
+ - `journal_mode = WAL` (better concurrent reads)
87
+ - `synchronous = NORMAL` (good durability vs. perf balance)
88
+ - `foreign_keys = ON`
89
+ - `temp_store = MEMORY`
90
+
91
+ Setup is idempotent. Re-running against a populated database is a safe no-op.
92
+ Drift between the declared schema and the actual table is logged as
93
+ `WARN setup.drift {field, declared, actual}`. Setup never auto-mutates an
94
+ existing table, no `ALTER TABLE`, no destructive recreates.
95
+
96
+ The default 15-column schema mirrors the canonical walkerOS Event v4 layout.
97
+ Only `name` is `NOT NULL`, every other column is nullable so partial events do
98
+ not block ingestion:
76
99
 
77
100
  ```sql
78
101
  CREATE TABLE IF NOT EXISTS events (
79
- id INTEGER PRIMARY KEY AUTOINCREMENT,
80
- created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
81
- timestamp INTEGER,
82
- event_id TEXT,
83
- name TEXT,
84
- entity TEXT,
85
- action TEXT,
86
- session_id TEXT,
87
- user_id TEXT,
88
- page_url TEXT,
89
- page_title TEXT,
90
- referrer_url TEXT,
91
- data TEXT,
92
- globals TEXT,
93
- consent TEXT
102
+ name TEXT NOT NULL,
103
+ data TEXT,
104
+ context TEXT,
105
+ globals TEXT,
106
+ custom TEXT,
107
+ user TEXT,
108
+ nested TEXT,
109
+ consent TEXT,
110
+ id TEXT,
111
+ trigger TEXT,
112
+ entity TEXT,
113
+ action TEXT,
114
+ timestamp TEXT,
115
+ timing INTEGER,
116
+ source TEXT
94
117
  )
95
118
  ```
96
119
 
97
- Nested JSON fields (`data`, `globals`, `consent`) are stored as JSON strings.
98
- `page_url` comes from `source.url`; `page_title` from `data.title`;
99
- `referrer_url` from `source.referrer`.
120
+ Override defaults in `config.setup`:
121
+
122
+ ```json
123
+ {
124
+ "destinations": {
125
+ "sqlite": {
126
+ "package": "@walkeros/server-destination-sqlite",
127
+ "config": {
128
+ "settings": { "sqlite": { "url": "./events.db" } },
129
+ "setup": {
130
+ "pragmas": { "journal_mode": "DELETE" },
131
+ "indexes": [{ "name": "idx_events_name", "columns": ["name"] }]
132
+ }
133
+ }
134
+ }
135
+ }
136
+ }
137
+ ```
138
+
139
+ `setup: true` accepts all defaults. `setup: false` (or omitted) means
140
+ `walkeros setup destination.sqlite` is a no-op for this destination.
141
+
142
+ ### Migration from `schema`
143
+
144
+ The package-local `settings.sqlite.schema` setting is deprecated. The framework
145
+ now owns the setup lifecycle through `config.setup`. The deprecated form still
146
+ works and emits a one-time WARN through the destination logger.
147
+
148
+ | Old (`settings.sqlite.schema`) | New (`config.setup`) | Effect |
149
+ | ------------------------------ | -------------------- | -------------------------------------------------- |
150
+ | `'auto'` | `true` | `walkeros setup destination.sqlite` creates table. |
151
+ | `'manual'` | `false` | Setup is a no-op. Bring your own schema + mapping. |
152
+ | omitted | omitted | No-op until `setup` is set explicitly. |
153
+
154
+ Remove the `schema` field from `settings.sqlite` and add `setup: true` (or
155
+ `false`) at the `config` level.
100
156
 
101
157
  ## Drivers
102
158
 
103
159
  - **Local** (`better-sqlite3`): sync native driver, ideal for single-host
104
- deployments. URL is treated as a filesystem path. `:memory:` works too.
160
+ deployments. URL is treated as a filesystem path. `:memory:` works too. All
161
+ four default pragmas are honored.
105
162
  - **Remote** (`@libsql/client`): async HTTP/WSS driver for Turso, sqld, or
106
- self-hosted libSQL. Auth via `authToken`.
163
+ self-hosted libSQL. Auth via `authToken`. The remote server controls
164
+ journaling, so client-side `journal_mode` is silently ignored. The other
165
+ pragmas (`synchronous`, `foreign_keys`, `temp_store`) still apply.
107
166
 
108
167
  Both are peer dependencies. The destination picks the driver at `init()` time
109
168
  based on the URL prefix.
@@ -119,9 +178,6 @@ are not closed.
119
178
  - v1 issues one `INSERT` per event. A `pushBatch` path is planned for v2.
120
179
  - Connection death is not auto-retried. A fatal driver error logs and drops
121
180
  events until the flow restarts.
122
- - `schema: 'manual'` skips `CREATE TABLE` but still uses the canonical column
123
- layout for the prepared INSERT. If your custom table has a different shape,
124
- also provide a mapping that produces matching args.
125
181
 
126
182
  ## Type Definitions
127
183
 
package/dist/dev.d.mts CHANGED
@@ -43,6 +43,11 @@ declare namespace index$1 {
43
43
  export { type index$1_Mapping as Mapping, index$1_MappingSchema as MappingSchema, type Settings$1 as Settings, index$1_SettingsSchema as SettingsSchema, index$1_SqliteSettingsSchema as SqliteSettingsSchema, index$1_mapping as mapping, index$1_settings as settings };
44
44
  }
45
45
 
46
+ /**
47
+ * @deprecated Use `config.setup` instead. Kept for one minor cycle.
48
+ * `'auto'` maps to `setup: true`, `'manual'` maps to `setup: false`.
49
+ * Removed in the next major.
50
+ */
46
51
  type SchemaMode = 'auto' | 'manual';
47
52
  /**
48
53
  * Thin cross-driver connection interface. Both drivers are adapted to this shape.
@@ -56,6 +61,8 @@ interface SqliteClient {
56
61
  * Prepare a statement for repeated execution. Returned function binds args and runs.
57
62
  */
58
63
  prepare: (sql: string) => (args: ReadonlyArray<unknown>) => Promise<void>;
64
+ /** Run a query that returns rows. Used by setup() for sqlite_master and PRAGMA table_info. */
65
+ query: (sql: string, args?: ReadonlyArray<unknown>) => Promise<ReadonlyArray<Record<string, unknown>>>;
59
66
  /** Close the connection. */
60
67
  close: () => Promise<void>;
61
68
  }
@@ -76,20 +83,32 @@ interface SqliteSettings {
76
83
  /** Target table name. Defaults to `events`. */
77
84
  table?: string;
78
85
  /**
79
- * `auto` runs `CREATE TABLE IF NOT EXISTS` with the canonical schema on init.
80
- * `manual` skips CREATE TABLE. The user brings their own schema and mapping.
81
- * Defaults to `auto`.
86
+ * @deprecated Use `config.setup` instead. Kept for one minor cycle.
87
+ * `'auto'` maps to `setup: true` (init runs CREATE TABLE for the legacy schema).
88
+ * `'manual'` maps to `setup: false`. Removed in the next major.
82
89
  */
83
90
  schema?: SchemaMode;
84
91
  _client?: SqliteClient;
85
92
  _runInsert?: (args: ReadonlyArray<unknown>) => Promise<void>;
86
93
  _ownedClient?: boolean;
94
+ /**
95
+ * Internal flag set by the migration shim. When true, init() runs the legacy
96
+ * 13-column CREATE TABLE path for backward compatibility. Otherwise init()
97
+ * assumes the table already exists (created via `walkeros setup destination.<id>`).
98
+ */
99
+ _legacyAutoCreate?: boolean;
100
+ /**
101
+ * Internal flag set by the migration shim. When true (legacy `schema: 'manual'`),
102
+ * init() skips the modern table-existence probe so the user can bring their own
103
+ * table and column shape without hitting the new "table not found" hard-fail.
104
+ */
105
+ _legacySkipProbe?: boolean;
87
106
  }
88
107
  interface Settings {
89
108
  sqlite: SqliteSettings;
90
109
  }
91
110
  /**
92
- * Env -- optional driver override. Production leaves this undefined and the
111
+ * Env, optional driver override. Production leaves this undefined and the
93
112
  * destination loads better-sqlite3 or @libsql/client dynamically. Tests
94
113
  * provide a factory via `SqliteDriver` or a pre-built client via `client`.
95
114
  */
package/dist/dev.d.ts CHANGED
@@ -43,6 +43,11 @@ declare namespace index$1 {
43
43
  export { type index$1_Mapping as Mapping, index$1_MappingSchema as MappingSchema, type Settings$1 as Settings, index$1_SettingsSchema as SettingsSchema, index$1_SqliteSettingsSchema as SqliteSettingsSchema, index$1_mapping as mapping, index$1_settings as settings };
44
44
  }
45
45
 
46
+ /**
47
+ * @deprecated Use `config.setup` instead. Kept for one minor cycle.
48
+ * `'auto'` maps to `setup: true`, `'manual'` maps to `setup: false`.
49
+ * Removed in the next major.
50
+ */
46
51
  type SchemaMode = 'auto' | 'manual';
47
52
  /**
48
53
  * Thin cross-driver connection interface. Both drivers are adapted to this shape.
@@ -56,6 +61,8 @@ interface SqliteClient {
56
61
  * Prepare a statement for repeated execution. Returned function binds args and runs.
57
62
  */
58
63
  prepare: (sql: string) => (args: ReadonlyArray<unknown>) => Promise<void>;
64
+ /** Run a query that returns rows. Used by setup() for sqlite_master and PRAGMA table_info. */
65
+ query: (sql: string, args?: ReadonlyArray<unknown>) => Promise<ReadonlyArray<Record<string, unknown>>>;
59
66
  /** Close the connection. */
60
67
  close: () => Promise<void>;
61
68
  }
@@ -76,20 +83,32 @@ interface SqliteSettings {
76
83
  /** Target table name. Defaults to `events`. */
77
84
  table?: string;
78
85
  /**
79
- * `auto` runs `CREATE TABLE IF NOT EXISTS` with the canonical schema on init.
80
- * `manual` skips CREATE TABLE. The user brings their own schema and mapping.
81
- * Defaults to `auto`.
86
+ * @deprecated Use `config.setup` instead. Kept for one minor cycle.
87
+ * `'auto'` maps to `setup: true` (init runs CREATE TABLE for the legacy schema).
88
+ * `'manual'` maps to `setup: false`. Removed in the next major.
82
89
  */
83
90
  schema?: SchemaMode;
84
91
  _client?: SqliteClient;
85
92
  _runInsert?: (args: ReadonlyArray<unknown>) => Promise<void>;
86
93
  _ownedClient?: boolean;
94
+ /**
95
+ * Internal flag set by the migration shim. When true, init() runs the legacy
96
+ * 13-column CREATE TABLE path for backward compatibility. Otherwise init()
97
+ * assumes the table already exists (created via `walkeros setup destination.<id>`).
98
+ */
99
+ _legacyAutoCreate?: boolean;
100
+ /**
101
+ * Internal flag set by the migration shim. When true (legacy `schema: 'manual'`),
102
+ * init() skips the modern table-existence probe so the user can bring their own
103
+ * table and column shape without hitting the new "table not found" hard-fail.
104
+ */
105
+ _legacySkipProbe?: boolean;
87
106
  }
88
107
  interface Settings {
89
108
  sqlite: SqliteSettings;
90
109
  }
91
110
  /**
92
- * Env -- optional driver override. Production leaves this undefined and the
111
+ * Env, optional driver override. Production leaves this undefined and the
93
112
  * destination loads better-sqlite3 or @libsql/client dynamically. Tests
94
113
  * provide a factory via `SqliteDriver` or a pre-built client via `client`.
95
114
  */
package/dist/dev.js CHANGED
@@ -1 +1 @@
1
- "use strict";var e,t=Object.defineProperty,r=Object.getOwnPropertyDescriptor,i=Object.getOwnPropertyNames,s=Object.prototype.hasOwnProperty,o=(e,r)=>{for(var i in r)t(e,i,{get:r[i],enumerable:!0})},n={};o(n,{examples:()=>v,schemas:()=>a}),module.exports=(e=n,((e,o,n,a)=>{if(o&&"object"==typeof o||"function"==typeof o)for(let l of i(o))s.call(e,l)||l===n||t(e,l,{get:()=>o[l],enumerable:!(a=r(o,l))||a.enumerable});return e})(t({},"__esModule",{value:!0}),e));var a={};o(a,{MappingSchema:()=>d,SettingsSchema:()=>p,SqliteSettingsSchema:()=>m,mapping:()=>g,settings:()=>b});var l=require("@walkeros/core/dev"),c=require("@walkeros/core/dev"),m=c.z.object({url:c.z.string().min(1).describe("SQLite connection URL. libsql://, http(s)://, ws(s):// route to libSQL/Turso. Anything else is treated as a local file path via better-sqlite3. Use ':memory:' for an ephemeral in-memory database."),authToken:c.z.string().describe("libSQL / Turso auth token. Ignored for better-sqlite3 (local) connections.").optional(),table:c.z.string().describe('Target table name. Defaults to "events".').optional(),schema:c.z.enum(["auto","manual"]).describe('"auto" creates the canonical events table with CREATE TABLE IF NOT EXISTS on init. "manual" skips table creation. The user brings their own schema and mapping.').optional()}),p=c.z.object({sqlite:m.describe("SQLite / libSQL configuration (like { url: './events.db' } or { url: 'libsql://my-db.turso.io', authToken: '...' })")}),u=require("@walkeros/core/dev"),d=u.z.object({table:u.z.string().describe("Override target table name for this rule. Takes precedence over settings.sqlite.table.").optional()}),b=(0,l.zodToSchema)(p),g=(0,l.zodToSchema)(d),v={};o(v,{env:()=>h,step:()=>O});var h={};o(h,{push:()=>y,simulation:()=>S});var f={execute:()=>Promise.resolve(),prepare:()=>()=>Promise.resolve(),close:()=>Promise.resolve()},y={SqliteDriver:()=>Promise.resolve(f)},S=["call:client.prepare","call:client.execute"],O={};o(O,{customTable:()=>T,defaultInsert:()=>N,ignoredEvent:()=>k,orderComplete:()=>J,tableOverride:()=>q});var w=require("@walkeros/core"),N={title:"Default insert",description:"A walker event is inserted into the default events table with canonical columns and JSON-encoded sections.",in:(0,w.getEvent)("page view",{timestamp:1700000100,id:"evt-1",user:{session:"sess-1",id:"user-42"},data:{title:"Home"},source:{type:"browser",platform:"web",url:"https://example.com/",referrer:"https://example.com/prev"},globals:{env:"prod"},consent:{analytics:!0}}),out:[["client.runInsert",[1700000100,"evt-1","page view","page","view","sess-1","user-42","https://example.com/","Home","https://example.com/prev",JSON.stringify({title:"Home"}),JSON.stringify({env:"prod"}),JSON.stringify({analytics:!0})]]]},T={title:"Custom table",description:"A destination-level table setting inserts events into a custom SQLite table with the same column layout.",in:(0,w.getEvent)("form submit",{timestamp:1700000101,id:"evt-2",user:{session:"sess-99",id:""},data:{type:"contact"},source:{type:"browser",platform:"web",url:"https://example.com/contact"},globals:{},consent:{}}),settings:{sqlite:{url:":memory:",table:"siteEvents"}},out:[["client.runInsert",[1700000101,"evt-2","form submit","form","submit","sess-99","","https://example.com/contact","","",JSON.stringify({type:"contact"}),JSON.stringify({}),JSON.stringify({})]]]},J={title:"Order insert",description:"An order complete is inserted with numeric data serialized as JSON in the data column.",in:(0,w.getEvent)("order complete",{timestamp:1700000102,id:"evt-3",user:{session:"",id:""},data:{id:"ORD-1",total:99},source:{type:"collector",schema:"4"},globals:{},consent:{}}),out:[["client.runInsert",[1700000102,"evt-3","order complete","order","complete","","","","","",JSON.stringify({id:"ORD-1",total:99}),JSON.stringify({}),JSON.stringify({})]]]},q={title:"Table override",description:"A mapping rule overrides the target table so specific events are inserted into a dedicated SQLite table.",in:(0,w.getEvent)("order complete",{timestamp:1700000103,id:"evt-4",user:{session:"",id:""},data:{id:"ORD-2",total:42},source:{type:"collector",schema:"4"},globals:{},consent:{}}),mapping:{settings:{table:"orders"}},out:[["client.runInsert",[1700000103,"evt-4","order complete","order","complete","","","","","",JSON.stringify({id:"ORD-2",total:42}),JSON.stringify({}),JSON.stringify({})]]]},k={public:!1,in:(0,w.getEvent)("debug noise",{timestamp:1700000104,id:"evt-5",source:{type:"collector",schema:"4"}}),mapping:{ignore:!0},out:[]};//# sourceMappingURL=dev.js.map
1
+ "use strict";var e,t=Object.defineProperty,r=Object.getOwnPropertyDescriptor,s=Object.getOwnPropertyNames,i=Object.prototype.hasOwnProperty,o=(e,r)=>{for(var s in r)t(e,s,{get:r[s],enumerable:!0})},n={};o(n,{examples:()=>g,schemas:()=>a}),module.exports=(e=n,((e,o,n,a)=>{if(o&&"object"==typeof o||"function"==typeof o)for(let l of s(o))i.call(e,l)||l===n||t(e,l,{get:()=>o[l],enumerable:!(a=r(o,l))||a.enumerable});return e})(t({},"__esModule",{value:!0}),e));var a={};o(a,{MappingSchema:()=>d,SettingsSchema:()=>p,SqliteSettingsSchema:()=>m,mapping:()=>v,settings:()=>b});var l=require("@walkeros/core/dev"),c=require("@walkeros/core/dev"),m=c.z.object({url:c.z.string().min(1).describe("SQLite connection URL. libsql://, http(s)://, ws(s):// route to libSQL/Turso. Anything else is treated as a local file path via better-sqlite3. Use ':memory:' for an ephemeral in-memory database."),authToken:c.z.string().describe("libSQL / Turso auth token. Ignored for better-sqlite3 (local) connections.").optional(),table:c.z.string().describe('Target table name. Defaults to "events".').optional(),schema:c.z.enum(["auto","manual"]).describe('[DEPRECATED] Use config.setup instead. "auto" maps to "setup: true" (run `walkeros setup destination.<id>`); "manual" maps to "setup: false". Removed in the next major.').optional()}),p=c.z.object({sqlite:m.describe("SQLite / libSQL configuration (like { url: './events.db' } or { url: 'libsql://my-db.turso.io', authToken: '...' })")}),u=require("@walkeros/core/dev"),d=u.z.object({table:u.z.string().describe("Override target table name for this rule. Takes precedence over settings.sqlite.table.").optional()}),b=(0,l.zodToSchema)(p),v=(0,l.zodToSchema)(d),g={};o(g,{env:()=>f,step:()=>O});var f={};o(f,{push:()=>h,simulation:()=>S});var y={execute:()=>Promise.resolve(),prepare:()=>()=>Promise.resolve(),query:()=>Promise.resolve([]),close:()=>Promise.resolve()},h={SqliteDriver:()=>Promise.resolve(y)},S=["call:client.prepare","call:client.execute"],O={};o(O,{customTable:()=>q,defaultInsert:()=>N,ignoredEvent:()=>x,orderComplete:()=>J,tableOverride:()=>k});var w=require("@walkeros/core"),N={title:"Default insert",description:"A walker event is inserted into the default events table with canonical columns and JSON-encoded sections.",in:(0,w.getEvent)("page view",{timestamp:1700000100,id:"evt-1",user:{session:"sess-1",id:"user-42"},data:{title:"Home"},source:{type:"browser",platform:"web",url:"https://example.com/",referrer:"https://example.com/prev"},globals:{env:"prod"},consent:{analytics:!0}}),out:[["client.runInsert",[1700000100,"evt-1","page view","page","view","sess-1","user-42","https://example.com/","Home","https://example.com/prev",JSON.stringify({title:"Home"}),JSON.stringify({env:"prod"}),JSON.stringify({analytics:!0})]]]},q={title:"Custom table",description:"A destination-level table setting inserts events into a custom SQLite table with the same column layout.",in:(0,w.getEvent)("form submit",{timestamp:1700000101,id:"evt-2",user:{session:"sess-99",id:""},data:{type:"contact"},source:{type:"browser",platform:"web",url:"https://example.com/contact"},globals:{},consent:{}}),settings:{sqlite:{url:":memory:",table:"siteEvents"}},out:[["client.runInsert",[1700000101,"evt-2","form submit","form","submit","sess-99","","https://example.com/contact","","",JSON.stringify({type:"contact"}),JSON.stringify({}),JSON.stringify({})]]]},J={title:"Order insert",description:"An order complete is inserted with numeric data serialized as JSON in the data column.",in:(0,w.getEvent)("order complete",{timestamp:1700000102,id:"evt-3",user:{session:"",id:""},data:{id:"ORD-1",total:99},source:{type:"collector",schema:"4"},globals:{},consent:{}}),out:[["client.runInsert",[1700000102,"evt-3","order complete","order","complete","","","","","",JSON.stringify({id:"ORD-1",total:99}),JSON.stringify({}),JSON.stringify({})]]]},k={title:"Table override",description:"A mapping rule overrides the target table so specific events are inserted into a dedicated SQLite table.",in:(0,w.getEvent)("order complete",{timestamp:1700000103,id:"evt-4",user:{session:"",id:""},data:{id:"ORD-2",total:42},source:{type:"collector",schema:"4"},globals:{},consent:{}}),mapping:{settings:{table:"orders"}},out:[["client.runInsert",[1700000103,"evt-4","order complete","order","complete","","","","","",JSON.stringify({id:"ORD-2",total:42}),JSON.stringify({}),JSON.stringify({})]]]},x={public:!1,in:(0,w.getEvent)("debug noise",{timestamp:1700000104,id:"evt-5",source:{type:"collector",schema:"4"}}),mapping:{ignore:!0},out:[]};//# sourceMappingURL=dev.js.map
package/dist/dev.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/dev.ts","../src/schemas/index.ts","../src/schemas/settings.ts","../src/schemas/mapping.ts","../src/examples/index.ts","../src/examples/env.ts","../src/examples/step.ts"],"sourcesContent":["export * as schemas from './schemas';\nexport * as examples from './examples';\n","import { zodToSchema } from '@walkeros/core/dev';\nimport { SettingsSchema } from './settings';\nimport { MappingSchema } from './mapping';\n\nexport {\n SettingsSchema,\n SqliteSettingsSchema,\n type Settings,\n} from './settings';\nexport { MappingSchema, type Mapping } from './mapping';\n\n// JSON Schema\nexport const settings = zodToSchema(SettingsSchema);\nexport const mapping = zodToSchema(MappingSchema);\n","import { z } from '@walkeros/core/dev';\n\nexport const SqliteSettingsSchema = z.object({\n url: z\n .string()\n .min(1)\n .describe(\n \"SQLite connection URL. libsql://, http(s)://, ws(s):// route to libSQL/Turso. Anything else is treated as a local file path via better-sqlite3. Use ':memory:' for an ephemeral in-memory database.\",\n ),\n authToken: z\n .string()\n .describe(\n 'libSQL / Turso auth token. Ignored for better-sqlite3 (local) connections.',\n )\n .optional(),\n table: z\n .string()\n .describe('Target table name. Defaults to \"events\".')\n .optional(),\n schema: z\n .enum(['auto', 'manual'])\n .describe(\n '\"auto\" creates the canonical events table with CREATE TABLE IF NOT EXISTS on init. \"manual\" skips table creation. The user brings their own schema and mapping.',\n )\n .optional(),\n});\n\nexport const SettingsSchema = z.object({\n sqlite: SqliteSettingsSchema.describe(\n \"SQLite / libSQL configuration (like { url: './events.db' } or { url: 'libsql://my-db.turso.io', authToken: '...' })\",\n ),\n});\n\nexport type Settings = z.infer<typeof SettingsSchema>;\n","import { z } from '@walkeros/core/dev';\n\nexport const MappingSchema = z.object({\n table: z\n .string()\n .describe(\n 'Override target table name for this rule. Takes precedence over settings.sqlite.table.',\n )\n .optional(),\n});\n\nexport type Mapping = z.infer<typeof MappingSchema>;\n","export * as env from './env';\nexport * as step from './step';\n","import type { Env, SqliteClient, SqliteClientFactory } from '../types';\n\n// Narrow helper type aliases so mock functions are typed without `any`.\ntype ExecuteFn = (sql: string, args?: ReadonlyArray<unknown>) => Promise<void>;\ntype PrepareFn = (\n sql: string,\n) => (args: ReadonlyArray<unknown>) => Promise<void>;\ntype CloseFn = () => Promise<void>;\n\nconst asyncExecute: ExecuteFn = () => Promise.resolve();\nconst asyncClose: CloseFn = () => Promise.resolve();\nconst asyncPrepare: PrepareFn = () => () => Promise.resolve();\n\nconst mockClient: SqliteClient = {\n execute: asyncExecute,\n prepare: asyncPrepare,\n close: asyncClose,\n};\n\nconst mockFactory: SqliteClientFactory = () => Promise.resolve(mockClient);\n\nexport const push: Env = {\n SqliteDriver: mockFactory,\n};\n\n/**\n * Simulation tracking paths. Specifies which function calls to record when\n * running step examples through the collector.\n */\nexport const simulation = ['call:client.prepare', 'call:client.execute'];\n","import type { Flow } from '@walkeros/core';\nimport { getEvent } from '@walkeros/core';\nimport type { Settings } from '../types';\n\n/**\n * Extended step example that may carry destination-level settings overrides.\n */\nexport type SqliteStepExample = Flow.StepExample & {\n settings?: Partial<Settings>;\n};\n\n/**\n * Canonical insert into the default `events` table. `out` records the\n * column args the prepared INSERT is bound with.\n */\nexport const defaultInsert: SqliteStepExample = {\n title: 'Default insert',\n description:\n 'A walker event is inserted into the default events table with canonical columns and JSON-encoded sections.',\n in: getEvent('page view', {\n timestamp: 1700000100,\n id: 'evt-1',\n user: { session: 'sess-1', id: 'user-42' },\n data: { title: 'Home' },\n source: {\n type: 'browser',\n platform: 'web',\n url: 'https://example.com/',\n referrer: 'https://example.com/prev',\n },\n globals: { env: 'prod' },\n consent: { analytics: true },\n }),\n out: [\n [\n 'client.runInsert',\n [\n 1700000100,\n 'evt-1',\n 'page view',\n 'page',\n 'view',\n 'sess-1',\n 'user-42',\n 'https://example.com/',\n 'Home',\n 'https://example.com/prev',\n JSON.stringify({ title: 'Home' }),\n JSON.stringify({ env: 'prod' }),\n JSON.stringify({ analytics: true }),\n ],\n ],\n ],\n};\n\n/**\n * Custom table name. Verifies table overrides while using the canonical column set.\n */\nexport const customTable: SqliteStepExample = {\n title: 'Custom table',\n description:\n 'A destination-level table setting inserts events into a custom SQLite table with the same column layout.',\n in: getEvent('form submit', {\n timestamp: 1700000101,\n id: 'evt-2',\n user: { session: 'sess-99', id: '' },\n data: { type: 'contact' },\n source: {\n type: 'browser',\n platform: 'web',\n url: 'https://example.com/contact',\n },\n globals: {},\n consent: {},\n }),\n settings: {\n sqlite: {\n url: ':memory:',\n table: 'siteEvents',\n },\n },\n out: [\n [\n 'client.runInsert',\n [\n 1700000101,\n 'evt-2',\n 'form submit',\n 'form',\n 'submit',\n 'sess-99',\n '',\n 'https://example.com/contact',\n '',\n '',\n JSON.stringify({ type: 'contact' }),\n JSON.stringify({}),\n JSON.stringify({}),\n ],\n ],\n ],\n};\n\n/**\n * Order event with numeric data. Confirms JSON serialization of nested values.\n */\nexport const orderComplete: SqliteStepExample = {\n title: 'Order insert',\n description:\n 'An order complete is inserted with numeric data serialized as JSON in the data column.',\n in: getEvent('order complete', {\n timestamp: 1700000102,\n id: 'evt-3',\n user: { session: '', id: '' },\n data: { id: 'ORD-1', total: 99 },\n source: { type: 'collector', schema: '4' },\n globals: {},\n consent: {},\n }),\n out: [\n [\n 'client.runInsert',\n [\n 1700000102,\n 'evt-3',\n 'order complete',\n 'order',\n 'complete',\n '',\n '',\n '',\n '',\n '',\n JSON.stringify({ id: 'ORD-1', total: 99 }),\n JSON.stringify({}),\n JSON.stringify({}),\n ],\n ],\n ],\n};\n\n/**\n * Table override per rule -- routes this event to a dedicated table.\n */\nexport const tableOverride: SqliteStepExample = {\n title: 'Table override',\n description:\n 'A mapping rule overrides the target table so specific events are inserted into a dedicated SQLite table.',\n in: getEvent('order complete', {\n timestamp: 1700000103,\n id: 'evt-4',\n user: { session: '', id: '' },\n data: { id: 'ORD-2', total: 42 },\n source: { type: 'collector', schema: '4' },\n globals: {},\n consent: {},\n }),\n mapping: {\n settings: {\n table: 'orders',\n },\n },\n out: [\n [\n 'client.runInsert',\n [\n 1700000103,\n 'evt-4',\n 'order complete',\n 'order',\n 'complete',\n '',\n '',\n '',\n '',\n '',\n JSON.stringify({ id: 'ORD-2', total: 42 }),\n JSON.stringify({}),\n JSON.stringify({}),\n ],\n ],\n ],\n};\n\n/**\n * Ignored event -- mapping.ignore: true produces no insert call.\n */\nexport const ignoredEvent: SqliteStepExample = {\n public: false,\n in: getEvent('debug noise', {\n timestamp: 1700000104,\n id: 'evt-5',\n source: { type: 'collector', schema: '4' },\n }),\n mapping: { ignore: true },\n out: [],\n};\n"],"mappings":"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","names":["import_dev","import_dev"]}
1
+ {"version":3,"sources":["../src/dev.ts","../src/schemas/index.ts","../src/schemas/settings.ts","../src/schemas/mapping.ts","../src/examples/index.ts","../src/examples/env.ts","../src/examples/step.ts"],"sourcesContent":["export * as schemas from './schemas';\nexport * as examples from './examples';\n","import { zodToSchema } from '@walkeros/core/dev';\nimport { SettingsSchema } from './settings';\nimport { MappingSchema } from './mapping';\n\nexport {\n SettingsSchema,\n SqliteSettingsSchema,\n type Settings,\n} from './settings';\nexport { MappingSchema, type Mapping } from './mapping';\n\n// JSON Schema\nexport const settings = zodToSchema(SettingsSchema);\nexport const mapping = zodToSchema(MappingSchema);\n","import { z } from '@walkeros/core/dev';\n\nexport const SqliteSettingsSchema = z.object({\n url: z\n .string()\n .min(1)\n .describe(\n \"SQLite connection URL. libsql://, http(s)://, ws(s):// route to libSQL/Turso. Anything else is treated as a local file path via better-sqlite3. Use ':memory:' for an ephemeral in-memory database.\",\n ),\n authToken: z\n .string()\n .describe(\n 'libSQL / Turso auth token. Ignored for better-sqlite3 (local) connections.',\n )\n .optional(),\n table: z\n .string()\n .describe('Target table name. Defaults to \"events\".')\n .optional(),\n schema: z\n .enum(['auto', 'manual'])\n .describe(\n '[DEPRECATED] Use config.setup instead. \"auto\" maps to \"setup: true\" (run `walkeros setup destination.<id>`); \"manual\" maps to \"setup: false\". Removed in the next major.',\n )\n .optional(),\n});\n\nexport const SettingsSchema = z.object({\n sqlite: SqliteSettingsSchema.describe(\n \"SQLite / libSQL configuration (like { url: './events.db' } or { url: 'libsql://my-db.turso.io', authToken: '...' })\",\n ),\n});\n\nexport type Settings = z.infer<typeof SettingsSchema>;\n","import { z } from '@walkeros/core/dev';\n\nexport const MappingSchema = z.object({\n table: z\n .string()\n .describe(\n 'Override target table name for this rule. Takes precedence over settings.sqlite.table.',\n )\n .optional(),\n});\n\nexport type Mapping = z.infer<typeof MappingSchema>;\n","export * as env from './env';\nexport * as step from './step';\n","import type { Env, SqliteClient, SqliteClientFactory } from '../types';\n\n// Narrow helper type aliases so mock functions are typed without `any`.\ntype ExecuteFn = (sql: string, args?: ReadonlyArray<unknown>) => Promise<void>;\ntype PrepareFn = (\n sql: string,\n) => (args: ReadonlyArray<unknown>) => Promise<void>;\ntype QueryFn = (\n sql: string,\n args?: ReadonlyArray<unknown>,\n) => Promise<ReadonlyArray<Record<string, unknown>>>;\ntype CloseFn = () => Promise<void>;\n\nconst asyncExecute: ExecuteFn = () => Promise.resolve();\nconst asyncClose: CloseFn = () => Promise.resolve();\nconst asyncPrepare: PrepareFn = () => () => Promise.resolve();\nconst asyncQuery: QueryFn = () => Promise.resolve([]);\n\nconst mockClient: SqliteClient = {\n execute: asyncExecute,\n prepare: asyncPrepare,\n query: asyncQuery,\n close: asyncClose,\n};\n\nconst mockFactory: SqliteClientFactory = () => Promise.resolve(mockClient);\n\nexport const push: Env = {\n SqliteDriver: mockFactory,\n};\n\n/**\n * Simulation tracking paths. Specifies which function calls to record when\n * running step examples through the collector.\n */\nexport const simulation = ['call:client.prepare', 'call:client.execute'];\n","import type { Flow } from '@walkeros/core';\nimport { getEvent } from '@walkeros/core';\nimport type { Settings } from '../types';\n\n/**\n * Extended step example that may carry destination-level settings overrides.\n */\nexport type SqliteStepExample = Flow.StepExample & {\n settings?: Partial<Settings>;\n};\n\n/**\n * Canonical insert into the default `events` table. `out` records the\n * column args the prepared INSERT is bound with.\n */\nexport const defaultInsert: SqliteStepExample = {\n title: 'Default insert',\n description:\n 'A walker event is inserted into the default events table with canonical columns and JSON-encoded sections.',\n in: getEvent('page view', {\n timestamp: 1700000100,\n id: 'evt-1',\n user: { session: 'sess-1', id: 'user-42' },\n data: { title: 'Home' },\n source: {\n type: 'browser',\n platform: 'web',\n url: 'https://example.com/',\n referrer: 'https://example.com/prev',\n },\n globals: { env: 'prod' },\n consent: { analytics: true },\n }),\n out: [\n [\n 'client.runInsert',\n [\n 1700000100,\n 'evt-1',\n 'page view',\n 'page',\n 'view',\n 'sess-1',\n 'user-42',\n 'https://example.com/',\n 'Home',\n 'https://example.com/prev',\n JSON.stringify({ title: 'Home' }),\n JSON.stringify({ env: 'prod' }),\n JSON.stringify({ analytics: true }),\n ],\n ],\n ],\n};\n\n/**\n * Custom table name. Verifies table overrides while using the canonical column set.\n */\nexport const customTable: SqliteStepExample = {\n title: 'Custom table',\n description:\n 'A destination-level table setting inserts events into a custom SQLite table with the same column layout.',\n in: getEvent('form submit', {\n timestamp: 1700000101,\n id: 'evt-2',\n user: { session: 'sess-99', id: '' },\n data: { type: 'contact' },\n source: {\n type: 'browser',\n platform: 'web',\n url: 'https://example.com/contact',\n },\n globals: {},\n consent: {},\n }),\n settings: {\n sqlite: {\n url: ':memory:',\n table: 'siteEvents',\n },\n },\n out: [\n [\n 'client.runInsert',\n [\n 1700000101,\n 'evt-2',\n 'form submit',\n 'form',\n 'submit',\n 'sess-99',\n '',\n 'https://example.com/contact',\n '',\n '',\n JSON.stringify({ type: 'contact' }),\n JSON.stringify({}),\n JSON.stringify({}),\n ],\n ],\n ],\n};\n\n/**\n * Order event with numeric data. Confirms JSON serialization of nested values.\n */\nexport const orderComplete: SqliteStepExample = {\n title: 'Order insert',\n description:\n 'An order complete is inserted with numeric data serialized as JSON in the data column.',\n in: getEvent('order complete', {\n timestamp: 1700000102,\n id: 'evt-3',\n user: { session: '', id: '' },\n data: { id: 'ORD-1', total: 99 },\n source: { type: 'collector', schema: '4' },\n globals: {},\n consent: {},\n }),\n out: [\n [\n 'client.runInsert',\n [\n 1700000102,\n 'evt-3',\n 'order complete',\n 'order',\n 'complete',\n '',\n '',\n '',\n '',\n '',\n JSON.stringify({ id: 'ORD-1', total: 99 }),\n JSON.stringify({}),\n JSON.stringify({}),\n ],\n ],\n ],\n};\n\n/**\n * Table override per rule -- routes this event to a dedicated table.\n */\nexport const tableOverride: SqliteStepExample = {\n title: 'Table override',\n description:\n 'A mapping rule overrides the target table so specific events are inserted into a dedicated SQLite table.',\n in: getEvent('order complete', {\n timestamp: 1700000103,\n id: 'evt-4',\n user: { session: '', id: '' },\n data: { id: 'ORD-2', total: 42 },\n source: { type: 'collector', schema: '4' },\n globals: {},\n consent: {},\n }),\n mapping: {\n settings: {\n table: 'orders',\n },\n },\n out: [\n [\n 'client.runInsert',\n [\n 1700000103,\n 'evt-4',\n 'order complete',\n 'order',\n 'complete',\n '',\n '',\n '',\n '',\n '',\n JSON.stringify({ id: 'ORD-2', total: 42 }),\n JSON.stringify({}),\n JSON.stringify({}),\n ],\n ],\n ],\n};\n\n/**\n * Ignored event -- mapping.ignore: true produces no insert call.\n */\nexport const ignoredEvent: SqliteStepExample = {\n public: false,\n in: getEvent('debug noise', {\n timestamp: 1700000104,\n id: 'evt-5',\n source: { type: 'collector', schema: '4' },\n }),\n mapping: { ignore: true },\n out: [],\n};\n"],"mappings":"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","names":["import_dev","import_dev"]}
package/dist/dev.mjs CHANGED
@@ -1 +1 @@
1
- var e=Object.defineProperty,t=(t,i)=>{for(var s in i)e(t,s,{get:i[s],enumerable:!0})},i={};t(i,{MappingSchema:()=>l,SettingsSchema:()=>a,SqliteSettingsSchema:()=>o,mapping:()=>m,settings:()=>c});import{zodToSchema as s}from"@walkeros/core/dev";import{z as r}from"@walkeros/core/dev";var o=r.object({url:r.string().min(1).describe("SQLite connection URL. libsql://, http(s)://, ws(s):// route to libSQL/Turso. Anything else is treated as a local file path via better-sqlite3. Use ':memory:' for an ephemeral in-memory database."),authToken:r.string().describe("libSQL / Turso auth token. Ignored for better-sqlite3 (local) connections.").optional(),table:r.string().describe('Target table name. Defaults to "events".').optional(),schema:r.enum(["auto","manual"]).describe('"auto" creates the canonical events table with CREATE TABLE IF NOT EXISTS on init. "manual" skips table creation. The user brings their own schema and mapping.').optional()}),a=r.object({sqlite:o.describe("SQLite / libSQL configuration (like { url: './events.db' } or { url: 'libsql://my-db.turso.io', authToken: '...' })")});import{z as n}from"@walkeros/core/dev";var l=n.object({table:n.string().describe("Override target table name for this rule. Takes precedence over settings.sqlite.table.").optional()}),c=s(a),m=s(l),p={};t(p,{env:()=>d,step:()=>g});var d={};t(d,{push:()=>b,simulation:()=>v});var u={execute:()=>Promise.resolve(),prepare:()=>()=>Promise.resolve(),close:()=>Promise.resolve()},b={SqliteDriver:()=>Promise.resolve(u)},v=["call:client.prepare","call:client.execute"],g={};t(g,{customTable:()=>S,defaultInsert:()=>f,ignoredEvent:()=>w,orderComplete:()=>y,tableOverride:()=>O});import{getEvent as h}from"@walkeros/core";var f={title:"Default insert",description:"A walker event is inserted into the default events table with canonical columns and JSON-encoded sections.",in:h("page view",{timestamp:1700000100,id:"evt-1",user:{session:"sess-1",id:"user-42"},data:{title:"Home"},source:{type:"browser",platform:"web",url:"https://example.com/",referrer:"https://example.com/prev"},globals:{env:"prod"},consent:{analytics:!0}}),out:[["client.runInsert",[1700000100,"evt-1","page view","page","view","sess-1","user-42","https://example.com/","Home","https://example.com/prev",JSON.stringify({title:"Home"}),JSON.stringify({env:"prod"}),JSON.stringify({analytics:!0})]]]},S={title:"Custom table",description:"A destination-level table setting inserts events into a custom SQLite table with the same column layout.",in:h("form submit",{timestamp:1700000101,id:"evt-2",user:{session:"sess-99",id:""},data:{type:"contact"},source:{type:"browser",platform:"web",url:"https://example.com/contact"},globals:{},consent:{}}),settings:{sqlite:{url:":memory:",table:"siteEvents"}},out:[["client.runInsert",[1700000101,"evt-2","form submit","form","submit","sess-99","","https://example.com/contact","","",JSON.stringify({type:"contact"}),JSON.stringify({}),JSON.stringify({})]]]},y={title:"Order insert",description:"An order complete is inserted with numeric data serialized as JSON in the data column.",in:h("order complete",{timestamp:1700000102,id:"evt-3",user:{session:"",id:""},data:{id:"ORD-1",total:99},source:{type:"collector",schema:"4"},globals:{},consent:{}}),out:[["client.runInsert",[1700000102,"evt-3","order complete","order","complete","","","","","",JSON.stringify({id:"ORD-1",total:99}),JSON.stringify({}),JSON.stringify({})]]]},O={title:"Table override",description:"A mapping rule overrides the target table so specific events are inserted into a dedicated SQLite table.",in:h("order complete",{timestamp:1700000103,id:"evt-4",user:{session:"",id:""},data:{id:"ORD-2",total:42},source:{type:"collector",schema:"4"},globals:{},consent:{}}),mapping:{settings:{table:"orders"}},out:[["client.runInsert",[1700000103,"evt-4","order complete","order","complete","","","","","",JSON.stringify({id:"ORD-2",total:42}),JSON.stringify({}),JSON.stringify({})]]]},w={public:!1,in:h("debug noise",{timestamp:1700000104,id:"evt-5",source:{type:"collector",schema:"4"}}),mapping:{ignore:!0},out:[]};export{p as examples,i as schemas};//# sourceMappingURL=dev.mjs.map
1
+ var e=Object.defineProperty,t=(t,s)=>{for(var i in s)e(t,i,{get:s[i],enumerable:!0})},s={};t(s,{MappingSchema:()=>l,SettingsSchema:()=>a,SqliteSettingsSchema:()=>o,mapping:()=>m,settings:()=>c});import{zodToSchema as i}from"@walkeros/core/dev";import{z as r}from"@walkeros/core/dev";var o=r.object({url:r.string().min(1).describe("SQLite connection URL. libsql://, http(s)://, ws(s):// route to libSQL/Turso. Anything else is treated as a local file path via better-sqlite3. Use ':memory:' for an ephemeral in-memory database."),authToken:r.string().describe("libSQL / Turso auth token. Ignored for better-sqlite3 (local) connections.").optional(),table:r.string().describe('Target table name. Defaults to "events".').optional(),schema:r.enum(["auto","manual"]).describe('[DEPRECATED] Use config.setup instead. "auto" maps to "setup: true" (run `walkeros setup destination.<id>`); "manual" maps to "setup: false". Removed in the next major.').optional()}),a=r.object({sqlite:o.describe("SQLite / libSQL configuration (like { url: './events.db' } or { url: 'libsql://my-db.turso.io', authToken: '...' })")});import{z as n}from"@walkeros/core/dev";var l=n.object({table:n.string().describe("Override target table name for this rule. Takes precedence over settings.sqlite.table.").optional()}),c=i(a),m=i(l),p={};t(p,{env:()=>d,step:()=>g});var d={};t(d,{push:()=>b,simulation:()=>v});var u={execute:()=>Promise.resolve(),prepare:()=>()=>Promise.resolve(),query:()=>Promise.resolve([]),close:()=>Promise.resolve()},b={SqliteDriver:()=>Promise.resolve(u)},v=["call:client.prepare","call:client.execute"],g={};t(g,{customTable:()=>y,defaultInsert:()=>h,ignoredEvent:()=>w,orderComplete:()=>S,tableOverride:()=>O});import{getEvent as f}from"@walkeros/core";var h={title:"Default insert",description:"A walker event is inserted into the default events table with canonical columns and JSON-encoded sections.",in:f("page view",{timestamp:1700000100,id:"evt-1",user:{session:"sess-1",id:"user-42"},data:{title:"Home"},source:{type:"browser",platform:"web",url:"https://example.com/",referrer:"https://example.com/prev"},globals:{env:"prod"},consent:{analytics:!0}}),out:[["client.runInsert",[1700000100,"evt-1","page view","page","view","sess-1","user-42","https://example.com/","Home","https://example.com/prev",JSON.stringify({title:"Home"}),JSON.stringify({env:"prod"}),JSON.stringify({analytics:!0})]]]},y={title:"Custom table",description:"A destination-level table setting inserts events into a custom SQLite table with the same column layout.",in:f("form submit",{timestamp:1700000101,id:"evt-2",user:{session:"sess-99",id:""},data:{type:"contact"},source:{type:"browser",platform:"web",url:"https://example.com/contact"},globals:{},consent:{}}),settings:{sqlite:{url:":memory:",table:"siteEvents"}},out:[["client.runInsert",[1700000101,"evt-2","form submit","form","submit","sess-99","","https://example.com/contact","","",JSON.stringify({type:"contact"}),JSON.stringify({}),JSON.stringify({})]]]},S={title:"Order insert",description:"An order complete is inserted with numeric data serialized as JSON in the data column.",in:f("order complete",{timestamp:1700000102,id:"evt-3",user:{session:"",id:""},data:{id:"ORD-1",total:99},source:{type:"collector",schema:"4"},globals:{},consent:{}}),out:[["client.runInsert",[1700000102,"evt-3","order complete","order","complete","","","","","",JSON.stringify({id:"ORD-1",total:99}),JSON.stringify({}),JSON.stringify({})]]]},O={title:"Table override",description:"A mapping rule overrides the target table so specific events are inserted into a dedicated SQLite table.",in:f("order complete",{timestamp:1700000103,id:"evt-4",user:{session:"",id:""},data:{id:"ORD-2",total:42},source:{type:"collector",schema:"4"},globals:{},consent:{}}),mapping:{settings:{table:"orders"}},out:[["client.runInsert",[1700000103,"evt-4","order complete","order","complete","","","","","",JSON.stringify({id:"ORD-2",total:42}),JSON.stringify({}),JSON.stringify({})]]]},w={public:!1,in:f("debug noise",{timestamp:1700000104,id:"evt-5",source:{type:"collector",schema:"4"}}),mapping:{ignore:!0},out:[]};export{p as examples,s as schemas};//# sourceMappingURL=dev.mjs.map
package/dist/dev.mjs.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/schemas/index.ts","../src/schemas/settings.ts","../src/schemas/mapping.ts","../src/examples/index.ts","../src/examples/env.ts","../src/examples/step.ts"],"sourcesContent":["import { zodToSchema } from '@walkeros/core/dev';\nimport { SettingsSchema } from './settings';\nimport { MappingSchema } from './mapping';\n\nexport {\n SettingsSchema,\n SqliteSettingsSchema,\n type Settings,\n} from './settings';\nexport { MappingSchema, type Mapping } from './mapping';\n\n// JSON Schema\nexport const settings = zodToSchema(SettingsSchema);\nexport const mapping = zodToSchema(MappingSchema);\n","import { z } from '@walkeros/core/dev';\n\nexport const SqliteSettingsSchema = z.object({\n url: z\n .string()\n .min(1)\n .describe(\n \"SQLite connection URL. libsql://, http(s)://, ws(s):// route to libSQL/Turso. Anything else is treated as a local file path via better-sqlite3. Use ':memory:' for an ephemeral in-memory database.\",\n ),\n authToken: z\n .string()\n .describe(\n 'libSQL / Turso auth token. Ignored for better-sqlite3 (local) connections.',\n )\n .optional(),\n table: z\n .string()\n .describe('Target table name. Defaults to \"events\".')\n .optional(),\n schema: z\n .enum(['auto', 'manual'])\n .describe(\n '\"auto\" creates the canonical events table with CREATE TABLE IF NOT EXISTS on init. \"manual\" skips table creation. The user brings their own schema and mapping.',\n )\n .optional(),\n});\n\nexport const SettingsSchema = z.object({\n sqlite: SqliteSettingsSchema.describe(\n \"SQLite / libSQL configuration (like { url: './events.db' } or { url: 'libsql://my-db.turso.io', authToken: '...' })\",\n ),\n});\n\nexport type Settings = z.infer<typeof SettingsSchema>;\n","import { z } from '@walkeros/core/dev';\n\nexport const MappingSchema = z.object({\n table: z\n .string()\n .describe(\n 'Override target table name for this rule. Takes precedence over settings.sqlite.table.',\n )\n .optional(),\n});\n\nexport type Mapping = z.infer<typeof MappingSchema>;\n","export * as env from './env';\nexport * as step from './step';\n","import type { Env, SqliteClient, SqliteClientFactory } from '../types';\n\n// Narrow helper type aliases so mock functions are typed without `any`.\ntype ExecuteFn = (sql: string, args?: ReadonlyArray<unknown>) => Promise<void>;\ntype PrepareFn = (\n sql: string,\n) => (args: ReadonlyArray<unknown>) => Promise<void>;\ntype CloseFn = () => Promise<void>;\n\nconst asyncExecute: ExecuteFn = () => Promise.resolve();\nconst asyncClose: CloseFn = () => Promise.resolve();\nconst asyncPrepare: PrepareFn = () => () => Promise.resolve();\n\nconst mockClient: SqliteClient = {\n execute: asyncExecute,\n prepare: asyncPrepare,\n close: asyncClose,\n};\n\nconst mockFactory: SqliteClientFactory = () => Promise.resolve(mockClient);\n\nexport const push: Env = {\n SqliteDriver: mockFactory,\n};\n\n/**\n * Simulation tracking paths. Specifies which function calls to record when\n * running step examples through the collector.\n */\nexport const simulation = ['call:client.prepare', 'call:client.execute'];\n","import type { Flow } from '@walkeros/core';\nimport { getEvent } from '@walkeros/core';\nimport type { Settings } from '../types';\n\n/**\n * Extended step example that may carry destination-level settings overrides.\n */\nexport type SqliteStepExample = Flow.StepExample & {\n settings?: Partial<Settings>;\n};\n\n/**\n * Canonical insert into the default `events` table. `out` records the\n * column args the prepared INSERT is bound with.\n */\nexport const defaultInsert: SqliteStepExample = {\n title: 'Default insert',\n description:\n 'A walker event is inserted into the default events table with canonical columns and JSON-encoded sections.',\n in: getEvent('page view', {\n timestamp: 1700000100,\n id: 'evt-1',\n user: { session: 'sess-1', id: 'user-42' },\n data: { title: 'Home' },\n source: {\n type: 'browser',\n platform: 'web',\n url: 'https://example.com/',\n referrer: 'https://example.com/prev',\n },\n globals: { env: 'prod' },\n consent: { analytics: true },\n }),\n out: [\n [\n 'client.runInsert',\n [\n 1700000100,\n 'evt-1',\n 'page view',\n 'page',\n 'view',\n 'sess-1',\n 'user-42',\n 'https://example.com/',\n 'Home',\n 'https://example.com/prev',\n JSON.stringify({ title: 'Home' }),\n JSON.stringify({ env: 'prod' }),\n JSON.stringify({ analytics: true }),\n ],\n ],\n ],\n};\n\n/**\n * Custom table name. Verifies table overrides while using the canonical column set.\n */\nexport const customTable: SqliteStepExample = {\n title: 'Custom table',\n description:\n 'A destination-level table setting inserts events into a custom SQLite table with the same column layout.',\n in: getEvent('form submit', {\n timestamp: 1700000101,\n id: 'evt-2',\n user: { session: 'sess-99', id: '' },\n data: { type: 'contact' },\n source: {\n type: 'browser',\n platform: 'web',\n url: 'https://example.com/contact',\n },\n globals: {},\n consent: {},\n }),\n settings: {\n sqlite: {\n url: ':memory:',\n table: 'siteEvents',\n },\n },\n out: [\n [\n 'client.runInsert',\n [\n 1700000101,\n 'evt-2',\n 'form submit',\n 'form',\n 'submit',\n 'sess-99',\n '',\n 'https://example.com/contact',\n '',\n '',\n JSON.stringify({ type: 'contact' }),\n JSON.stringify({}),\n JSON.stringify({}),\n ],\n ],\n ],\n};\n\n/**\n * Order event with numeric data. Confirms JSON serialization of nested values.\n */\nexport const orderComplete: SqliteStepExample = {\n title: 'Order insert',\n description:\n 'An order complete is inserted with numeric data serialized as JSON in the data column.',\n in: getEvent('order complete', {\n timestamp: 1700000102,\n id: 'evt-3',\n user: { session: '', id: '' },\n data: { id: 'ORD-1', total: 99 },\n source: { type: 'collector', schema: '4' },\n globals: {},\n consent: {},\n }),\n out: [\n [\n 'client.runInsert',\n [\n 1700000102,\n 'evt-3',\n 'order complete',\n 'order',\n 'complete',\n '',\n '',\n '',\n '',\n '',\n JSON.stringify({ id: 'ORD-1', total: 99 }),\n JSON.stringify({}),\n JSON.stringify({}),\n ],\n ],\n ],\n};\n\n/**\n * Table override per rule -- routes this event to a dedicated table.\n */\nexport const tableOverride: SqliteStepExample = {\n title: 'Table override',\n description:\n 'A mapping rule overrides the target table so specific events are inserted into a dedicated SQLite table.',\n in: getEvent('order complete', {\n timestamp: 1700000103,\n id: 'evt-4',\n user: { session: '', id: '' },\n data: { id: 'ORD-2', total: 42 },\n source: { type: 'collector', schema: '4' },\n globals: {},\n consent: {},\n }),\n mapping: {\n settings: {\n table: 'orders',\n },\n },\n out: [\n [\n 'client.runInsert',\n [\n 1700000103,\n 'evt-4',\n 'order complete',\n 'order',\n 'complete',\n '',\n '',\n '',\n '',\n '',\n JSON.stringify({ id: 'ORD-2', total: 42 }),\n JSON.stringify({}),\n JSON.stringify({}),\n ],\n ],\n ],\n};\n\n/**\n * Ignored event -- mapping.ignore: true produces no insert call.\n */\nexport const ignoredEvent: SqliteStepExample = {\n public: false,\n in: getEvent('debug noise', {\n timestamp: 1700000104,\n id: 'evt-5',\n source: { type: 'collector', schema: '4' },\n }),\n mapping: { ignore: true },\n out: [],\n};\n"],"mappings":"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","names":["z"]}
1
+ {"version":3,"sources":["../src/schemas/index.ts","../src/schemas/settings.ts","../src/schemas/mapping.ts","../src/examples/index.ts","../src/examples/env.ts","../src/examples/step.ts"],"sourcesContent":["import { zodToSchema } from '@walkeros/core/dev';\nimport { SettingsSchema } from './settings';\nimport { MappingSchema } from './mapping';\n\nexport {\n SettingsSchema,\n SqliteSettingsSchema,\n type Settings,\n} from './settings';\nexport { MappingSchema, type Mapping } from './mapping';\n\n// JSON Schema\nexport const settings = zodToSchema(SettingsSchema);\nexport const mapping = zodToSchema(MappingSchema);\n","import { z } from '@walkeros/core/dev';\n\nexport const SqliteSettingsSchema = z.object({\n url: z\n .string()\n .min(1)\n .describe(\n \"SQLite connection URL. libsql://, http(s)://, ws(s):// route to libSQL/Turso. Anything else is treated as a local file path via better-sqlite3. Use ':memory:' for an ephemeral in-memory database.\",\n ),\n authToken: z\n .string()\n .describe(\n 'libSQL / Turso auth token. Ignored for better-sqlite3 (local) connections.',\n )\n .optional(),\n table: z\n .string()\n .describe('Target table name. Defaults to \"events\".')\n .optional(),\n schema: z\n .enum(['auto', 'manual'])\n .describe(\n '[DEPRECATED] Use config.setup instead. \"auto\" maps to \"setup: true\" (run `walkeros setup destination.<id>`); \"manual\" maps to \"setup: false\". Removed in the next major.',\n )\n .optional(),\n});\n\nexport const SettingsSchema = z.object({\n sqlite: SqliteSettingsSchema.describe(\n \"SQLite / libSQL configuration (like { url: './events.db' } or { url: 'libsql://my-db.turso.io', authToken: '...' })\",\n ),\n});\n\nexport type Settings = z.infer<typeof SettingsSchema>;\n","import { z } from '@walkeros/core/dev';\n\nexport const MappingSchema = z.object({\n table: z\n .string()\n .describe(\n 'Override target table name for this rule. Takes precedence over settings.sqlite.table.',\n )\n .optional(),\n});\n\nexport type Mapping = z.infer<typeof MappingSchema>;\n","export * as env from './env';\nexport * as step from './step';\n","import type { Env, SqliteClient, SqliteClientFactory } from '../types';\n\n// Narrow helper type aliases so mock functions are typed without `any`.\ntype ExecuteFn = (sql: string, args?: ReadonlyArray<unknown>) => Promise<void>;\ntype PrepareFn = (\n sql: string,\n) => (args: ReadonlyArray<unknown>) => Promise<void>;\ntype QueryFn = (\n sql: string,\n args?: ReadonlyArray<unknown>,\n) => Promise<ReadonlyArray<Record<string, unknown>>>;\ntype CloseFn = () => Promise<void>;\n\nconst asyncExecute: ExecuteFn = () => Promise.resolve();\nconst asyncClose: CloseFn = () => Promise.resolve();\nconst asyncPrepare: PrepareFn = () => () => Promise.resolve();\nconst asyncQuery: QueryFn = () => Promise.resolve([]);\n\nconst mockClient: SqliteClient = {\n execute: asyncExecute,\n prepare: asyncPrepare,\n query: asyncQuery,\n close: asyncClose,\n};\n\nconst mockFactory: SqliteClientFactory = () => Promise.resolve(mockClient);\n\nexport const push: Env = {\n SqliteDriver: mockFactory,\n};\n\n/**\n * Simulation tracking paths. Specifies which function calls to record when\n * running step examples through the collector.\n */\nexport const simulation = ['call:client.prepare', 'call:client.execute'];\n","import type { Flow } from '@walkeros/core';\nimport { getEvent } from '@walkeros/core';\nimport type { Settings } from '../types';\n\n/**\n * Extended step example that may carry destination-level settings overrides.\n */\nexport type SqliteStepExample = Flow.StepExample & {\n settings?: Partial<Settings>;\n};\n\n/**\n * Canonical insert into the default `events` table. `out` records the\n * column args the prepared INSERT is bound with.\n */\nexport const defaultInsert: SqliteStepExample = {\n title: 'Default insert',\n description:\n 'A walker event is inserted into the default events table with canonical columns and JSON-encoded sections.',\n in: getEvent('page view', {\n timestamp: 1700000100,\n id: 'evt-1',\n user: { session: 'sess-1', id: 'user-42' },\n data: { title: 'Home' },\n source: {\n type: 'browser',\n platform: 'web',\n url: 'https://example.com/',\n referrer: 'https://example.com/prev',\n },\n globals: { env: 'prod' },\n consent: { analytics: true },\n }),\n out: [\n [\n 'client.runInsert',\n [\n 1700000100,\n 'evt-1',\n 'page view',\n 'page',\n 'view',\n 'sess-1',\n 'user-42',\n 'https://example.com/',\n 'Home',\n 'https://example.com/prev',\n JSON.stringify({ title: 'Home' }),\n JSON.stringify({ env: 'prod' }),\n JSON.stringify({ analytics: true }),\n ],\n ],\n ],\n};\n\n/**\n * Custom table name. Verifies table overrides while using the canonical column set.\n */\nexport const customTable: SqliteStepExample = {\n title: 'Custom table',\n description:\n 'A destination-level table setting inserts events into a custom SQLite table with the same column layout.',\n in: getEvent('form submit', {\n timestamp: 1700000101,\n id: 'evt-2',\n user: { session: 'sess-99', id: '' },\n data: { type: 'contact' },\n source: {\n type: 'browser',\n platform: 'web',\n url: 'https://example.com/contact',\n },\n globals: {},\n consent: {},\n }),\n settings: {\n sqlite: {\n url: ':memory:',\n table: 'siteEvents',\n },\n },\n out: [\n [\n 'client.runInsert',\n [\n 1700000101,\n 'evt-2',\n 'form submit',\n 'form',\n 'submit',\n 'sess-99',\n '',\n 'https://example.com/contact',\n '',\n '',\n JSON.stringify({ type: 'contact' }),\n JSON.stringify({}),\n JSON.stringify({}),\n ],\n ],\n ],\n};\n\n/**\n * Order event with numeric data. Confirms JSON serialization of nested values.\n */\nexport const orderComplete: SqliteStepExample = {\n title: 'Order insert',\n description:\n 'An order complete is inserted with numeric data serialized as JSON in the data column.',\n in: getEvent('order complete', {\n timestamp: 1700000102,\n id: 'evt-3',\n user: { session: '', id: '' },\n data: { id: 'ORD-1', total: 99 },\n source: { type: 'collector', schema: '4' },\n globals: {},\n consent: {},\n }),\n out: [\n [\n 'client.runInsert',\n [\n 1700000102,\n 'evt-3',\n 'order complete',\n 'order',\n 'complete',\n '',\n '',\n '',\n '',\n '',\n JSON.stringify({ id: 'ORD-1', total: 99 }),\n JSON.stringify({}),\n JSON.stringify({}),\n ],\n ],\n ],\n};\n\n/**\n * Table override per rule -- routes this event to a dedicated table.\n */\nexport const tableOverride: SqliteStepExample = {\n title: 'Table override',\n description:\n 'A mapping rule overrides the target table so specific events are inserted into a dedicated SQLite table.',\n in: getEvent('order complete', {\n timestamp: 1700000103,\n id: 'evt-4',\n user: { session: '', id: '' },\n data: { id: 'ORD-2', total: 42 },\n source: { type: 'collector', schema: '4' },\n globals: {},\n consent: {},\n }),\n mapping: {\n settings: {\n table: 'orders',\n },\n },\n out: [\n [\n 'client.runInsert',\n [\n 1700000103,\n 'evt-4',\n 'order complete',\n 'order',\n 'complete',\n '',\n '',\n '',\n '',\n '',\n JSON.stringify({ id: 'ORD-2', total: 42 }),\n JSON.stringify({}),\n JSON.stringify({}),\n ],\n ],\n ],\n};\n\n/**\n * Ignored event -- mapping.ignore: true produces no insert call.\n */\nexport const ignoredEvent: SqliteStepExample = {\n public: false,\n in: getEvent('debug noise', {\n timestamp: 1700000104,\n id: 'evt-5',\n source: { type: 'collector', schema: '4' },\n }),\n mapping: { ignore: true },\n out: [],\n};\n"],"mappings":"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","names":["z"]}
@@ -1,6 +1,11 @@
1
1
  import { DestinationServer } from '@walkeros/server-core';
2
2
  import { Flow } from '@walkeros/core';
3
3
 
4
+ /**
5
+ * @deprecated Use `config.setup` instead. Kept for one minor cycle.
6
+ * `'auto'` maps to `setup: true`, `'manual'` maps to `setup: false`.
7
+ * Removed in the next major.
8
+ */
4
9
  type SchemaMode = 'auto' | 'manual';
5
10
  /**
6
11
  * Thin cross-driver connection interface. Both drivers are adapted to this shape.
@@ -14,6 +19,8 @@ interface SqliteClient {
14
19
  * Prepare a statement for repeated execution. Returned function binds args and runs.
15
20
  */
16
21
  prepare: (sql: string) => (args: ReadonlyArray<unknown>) => Promise<void>;
22
+ /** Run a query that returns rows. Used by setup() for sqlite_master and PRAGMA table_info. */
23
+ query: (sql: string, args?: ReadonlyArray<unknown>) => Promise<ReadonlyArray<Record<string, unknown>>>;
17
24
  /** Close the connection. */
18
25
  close: () => Promise<void>;
19
26
  }
@@ -34,20 +41,32 @@ interface SqliteSettings {
34
41
  /** Target table name. Defaults to `events`. */
35
42
  table?: string;
36
43
  /**
37
- * `auto` runs `CREATE TABLE IF NOT EXISTS` with the canonical schema on init.
38
- * `manual` skips CREATE TABLE. The user brings their own schema and mapping.
39
- * Defaults to `auto`.
44
+ * @deprecated Use `config.setup` instead. Kept for one minor cycle.
45
+ * `'auto'` maps to `setup: true` (init runs CREATE TABLE for the legacy schema).
46
+ * `'manual'` maps to `setup: false`. Removed in the next major.
40
47
  */
41
48
  schema?: SchemaMode;
42
49
  _client?: SqliteClient;
43
50
  _runInsert?: (args: ReadonlyArray<unknown>) => Promise<void>;
44
51
  _ownedClient?: boolean;
52
+ /**
53
+ * Internal flag set by the migration shim. When true, init() runs the legacy
54
+ * 13-column CREATE TABLE path for backward compatibility. Otherwise init()
55
+ * assumes the table already exists (created via `walkeros setup destination.<id>`).
56
+ */
57
+ _legacyAutoCreate?: boolean;
58
+ /**
59
+ * Internal flag set by the migration shim. When true (legacy `schema: 'manual'`),
60
+ * init() skips the modern table-existence probe so the user can bring their own
61
+ * table and column shape without hitting the new "table not found" hard-fail.
62
+ */
63
+ _legacySkipProbe?: boolean;
45
64
  }
46
65
  interface Settings {
47
66
  sqlite: SqliteSettings;
48
67
  }
49
68
  /**
50
- * Env -- optional driver override. Production leaves this undefined and the
69
+ * Env, optional driver override. Production leaves this undefined and the
51
70
  * destination loads better-sqlite3 or @libsql/client dynamically. Tests
52
71
  * provide a factory via `SqliteDriver` or a pre-built client via `client`.
53
72
  */
@@ -1,6 +1,11 @@
1
1
  import { DestinationServer } from '@walkeros/server-core';
2
2
  import { Flow } from '@walkeros/core';
3
3
 
4
+ /**
5
+ * @deprecated Use `config.setup` instead. Kept for one minor cycle.
6
+ * `'auto'` maps to `setup: true`, `'manual'` maps to `setup: false`.
7
+ * Removed in the next major.
8
+ */
4
9
  type SchemaMode = 'auto' | 'manual';
5
10
  /**
6
11
  * Thin cross-driver connection interface. Both drivers are adapted to this shape.
@@ -14,6 +19,8 @@ interface SqliteClient {
14
19
  * Prepare a statement for repeated execution. Returned function binds args and runs.
15
20
  */
16
21
  prepare: (sql: string) => (args: ReadonlyArray<unknown>) => Promise<void>;
22
+ /** Run a query that returns rows. Used by setup() for sqlite_master and PRAGMA table_info. */
23
+ query: (sql: string, args?: ReadonlyArray<unknown>) => Promise<ReadonlyArray<Record<string, unknown>>>;
17
24
  /** Close the connection. */
18
25
  close: () => Promise<void>;
19
26
  }
@@ -34,20 +41,32 @@ interface SqliteSettings {
34
41
  /** Target table name. Defaults to `events`. */
35
42
  table?: string;
36
43
  /**
37
- * `auto` runs `CREATE TABLE IF NOT EXISTS` with the canonical schema on init.
38
- * `manual` skips CREATE TABLE. The user brings their own schema and mapping.
39
- * Defaults to `auto`.
44
+ * @deprecated Use `config.setup` instead. Kept for one minor cycle.
45
+ * `'auto'` maps to `setup: true` (init runs CREATE TABLE for the legacy schema).
46
+ * `'manual'` maps to `setup: false`. Removed in the next major.
40
47
  */
41
48
  schema?: SchemaMode;
42
49
  _client?: SqliteClient;
43
50
  _runInsert?: (args: ReadonlyArray<unknown>) => Promise<void>;
44
51
  _ownedClient?: boolean;
52
+ /**
53
+ * Internal flag set by the migration shim. When true, init() runs the legacy
54
+ * 13-column CREATE TABLE path for backward compatibility. Otherwise init()
55
+ * assumes the table already exists (created via `walkeros setup destination.<id>`).
56
+ */
57
+ _legacyAutoCreate?: boolean;
58
+ /**
59
+ * Internal flag set by the migration shim. When true (legacy `schema: 'manual'`),
60
+ * init() skips the modern table-existence probe so the user can bring their own
61
+ * table and column shape without hitting the new "table not found" hard-fail.
62
+ */
63
+ _legacySkipProbe?: boolean;
45
64
  }
46
65
  interface Settings {
47
66
  sqlite: SqliteSettings;
48
67
  }
49
68
  /**
50
- * Env -- optional driver override. Production leaves this undefined and the
69
+ * Env, optional driver override. Production leaves this undefined and the
51
70
  * destination loads better-sqlite3 or @libsql/client dynamically. Tests
52
71
  * provide a factory via `SqliteDriver` or a pre-built client via `client`.
53
72
  */
@@ -34,9 +34,11 @@ __export(env_exports, {
34
34
  var asyncExecute = () => Promise.resolve();
35
35
  var asyncClose = () => Promise.resolve();
36
36
  var asyncPrepare = () => () => Promise.resolve();
37
+ var asyncQuery = () => Promise.resolve([]);
37
38
  var mockClient = {
38
39
  execute: asyncExecute,
39
40
  prepare: asyncPrepare,
41
+ query: asyncQuery,
40
42
  close: asyncClose
41
43
  };
42
44
  var mockFactory = () => Promise.resolve(mockClient);
@@ -13,9 +13,11 @@ __export(env_exports, {
13
13
  var asyncExecute = () => Promise.resolve();
14
14
  var asyncClose = () => Promise.resolve();
15
15
  var asyncPrepare = () => () => Promise.resolve();
16
+ var asyncQuery = () => Promise.resolve([]);
16
17
  var mockClient = {
17
18
  execute: asyncExecute,
18
19
  prepare: asyncPrepare,
20
+ query: asyncQuery,
19
21
  close: asyncClose
20
22
  };
21
23
  var mockFactory = () => Promise.resolve(mockClient);