@telorun/sql 0.7.0 → 0.7.2

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
@@ -55,11 +55,11 @@ metadata:
55
55
  A complete feedback collection REST API — no code, pure YAML.
56
56
  Persists entries to SQLite and serves them over HTTP.
57
57
  imports:
58
- Http: std/http-server@0.8.0
59
- Sql: std/sql@0.5.1
58
+ Http: std/http-server@0.11.0
59
+ Sql: std/sql@0.9.0
60
60
  targets:
61
- - Migrations
62
- - Server
61
+ - !ref Migrations
62
+ - !ref Server
63
63
  ---
64
64
  # SQLite database — swap driver/host/database for PostgreSQL with zero YAML changes
65
65
  kind: Sql.Connection
@@ -72,9 +72,7 @@ file: ./tmp/feedback.db
72
72
  kind: Sql.Migrations
73
73
  metadata:
74
74
  name: Migrations
75
- connection:
76
- kind: Sql.Connection
77
- name: Db
75
+ connection: !ref Db
78
76
  ---
79
77
  kind: Sql.Migration
80
78
  metadata:
@@ -101,7 +99,7 @@ openapi:
101
99
  version: 1.0.0
102
100
  mounts:
103
101
  - path: /v1
104
- type: Http.Api.FeedbackRoutes
102
+ mount: !ref FeedbackRoutes
105
103
  ---
106
104
  kind: Http.Api
107
105
  metadata:
@@ -123,9 +121,7 @@ routes:
123
121
  required: [ text ]
124
122
  handler:
125
123
  kind: Sql.Exec
126
- connection:
127
- kind: Sql.Connection
128
- name: Db
124
+ connection: !ref Db
129
125
  inputs:
130
126
  sql: "INSERT INTO feedback (text, source, score) VALUES (?, ?, ?)"
131
127
  bindings:
@@ -146,9 +142,7 @@ routes:
146
142
  method: GET
147
143
  handler:
148
144
  kind: Sql.Select
149
- connection:
150
- kind: Sql.Connection
151
- name: Db
145
+ connection: !ref Db
152
146
  from: feedback
153
147
  columns: [ id, text, source, score, created_at ]
154
148
  orderBy:
@@ -172,9 +166,7 @@ routes:
172
166
  required: [ id ]
173
167
  handler:
174
168
  kind: Sql.Select
175
- connection:
176
- kind: Sql.Connection
177
- name: Db
169
+ connection: !ref Db
178
170
  from: feedback
179
171
  columns: [ id, text, source, score, created_at ]
180
172
  where:
@@ -158,10 +158,12 @@ export async function openSqliteDatabase(file = ":memory:") {
158
158
  await mkdir(dir, { recursive: true });
159
159
  }
160
160
  }
161
- if (typeof Bun !== "undefined") {
162
- const { openDatabase } = await import("./sqlite-driver-bun.js");
163
- return openDatabase(file);
164
- }
165
- const { openDatabase } = await import("./sqlite-driver-node.js");
161
+ // Route through the package's own `./sqlite-driver` subpath export so the
162
+ // resolver selects the driver per runtime (Bun → bun:sqlite, Node →
163
+ // better-sqlite3). A manual `typeof Bun` check with relative imports gets
164
+ // flattened by the controller bundler into an unconditional top-level
165
+ // `import "bun:sqlite"`, which Node's ESM loader rejects before the guard
166
+ // runs; an external `@telorun/*` specifier stays a deferred dynamic import.
167
+ const { openDatabase } = await import("@telorun/sql/sqlite-driver");
166
168
  return openDatabase(file);
167
169
  }
@@ -2,6 +2,7 @@ import type { ResourceContext } from "@telorun/sdk";
2
2
  import type { SqlConnectionResource } from "./sql-connection-controller.js";
3
3
  interface ConnectionRef {
4
4
  name: string;
5
+ alias?: string;
5
6
  }
6
7
  export declare function resolveSqlConnection(value: SqlConnectionResource | ConnectionRef | undefined, ctx: ResourceContext): SqlConnectionResource | undefined;
7
8
  export {};
@@ -5,8 +5,20 @@ export function resolveSqlConnection(value, ctx) {
5
5
  if (typeof value.execute === "function") {
6
6
  return value;
7
7
  }
8
- if (typeof value.name !== "string") {
8
+ const ref = value;
9
+ if (typeof ref.name !== "string") {
9
10
  throw new Error("Sql: invalid connection reference");
10
11
  }
11
- return ctx.moduleContext.getInstance(value.name);
12
+ // Cross-module reference (`!ref Alias.Connection`): a connection resolved
13
+ // inside a nested library is not Phase-5-injected, so the controller receives
14
+ // the raw `{name, alias}` ref and must route through the import's exported
15
+ // scope rather than a bare local lookup.
16
+ if (ref.alias && ref.alias !== "Self") {
17
+ const instance = ctx.moduleContext.resolveImportedInstance(ref.alias, ref.name);
18
+ if (typeof instance?.execute !== "function") {
19
+ throw new Error(`Sql: connection reference '${ref.alias}.${ref.name}' did not resolve to an exported connection instance.`);
20
+ }
21
+ return instance;
22
+ }
23
+ return ctx.moduleContext.getInstance(ref.name);
12
24
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@telorun/sql",
3
- "version": "0.7.0",
3
+ "version": "0.7.2",
4
4
  "description": "Telo SQL module - SQL database resource kinds for Telo manifests.",
5
5
  "keywords": [
6
6
  "telo",
@@ -74,7 +74,7 @@
74
74
  "@types/node": "^20.0.0",
75
75
  "@types/pg": "^8.0.0",
76
76
  "typescript": "^5.0.0",
77
- "@telorun/sdk": "0.21.0"
77
+ "@telorun/sdk": "0.26.0"
78
78
  },
79
79
  "peerDependencies": {
80
80
  "@telorun/sdk": "*"
@@ -226,11 +226,12 @@ export async function openSqliteDatabase(file = ":memory:"): Promise<SqliteDb> {
226
226
  }
227
227
  }
228
228
 
229
- if (typeof Bun !== "undefined") {
230
- const { openDatabase } = await import("./sqlite-driver-bun.js");
231
- return openDatabase(file);
232
- }
233
-
234
- const { openDatabase } = await import("./sqlite-driver-node.js");
229
+ // Route through the package's own `./sqlite-driver` subpath export so the
230
+ // resolver selects the driver per runtime (Bun → bun:sqlite, Node →
231
+ // better-sqlite3). A manual `typeof Bun` check with relative imports gets
232
+ // flattened by the controller bundler into an unconditional top-level
233
+ // `import "bun:sqlite"`, which Node's ESM loader rejects before the guard
234
+ // runs; an external `@telorun/*` specifier stays a deferred dynamic import.
235
+ const { openDatabase } = await import("@telorun/sql/sqlite-driver");
235
236
  return openDatabase(file);
236
237
  }
@@ -3,6 +3,7 @@ import type { SqlConnectionResource } from "./sql-connection-controller.js";
3
3
 
4
4
  interface ConnectionRef {
5
5
  name: string;
6
+ alias?: string;
6
7
  }
7
8
 
8
9
  export function resolveSqlConnection(
@@ -17,9 +18,24 @@ export function resolveSqlConnection(
17
18
  return value as SqlConnectionResource;
18
19
  }
19
20
 
20
- if (typeof (value as ConnectionRef).name !== "string") {
21
+ const ref = value as ConnectionRef;
22
+ if (typeof ref.name !== "string") {
21
23
  throw new Error("Sql: invalid connection reference");
22
24
  }
23
25
 
24
- return ctx.moduleContext.getInstance((value as ConnectionRef).name) as SqlConnectionResource;
26
+ // Cross-module reference (`!ref Alias.Connection`): a connection resolved
27
+ // inside a nested library is not Phase-5-injected, so the controller receives
28
+ // the raw `{name, alias}` ref and must route through the import's exported
29
+ // scope rather than a bare local lookup.
30
+ if (ref.alias && ref.alias !== "Self") {
31
+ const instance = ctx.moduleContext.resolveImportedInstance(ref.alias, ref.name);
32
+ if (typeof (instance as SqlConnectionResource | undefined)?.execute !== "function") {
33
+ throw new Error(
34
+ `Sql: connection reference '${ref.alias}.${ref.name}' did not resolve to an exported connection instance.`,
35
+ );
36
+ }
37
+ return instance as unknown as SqlConnectionResource;
38
+ }
39
+
40
+ return ctx.moduleContext.getInstance(ref.name) as SqlConnectionResource;
25
41
  }