@this-npm-test-org/sql-driver-sdk 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
File without changes
@@ -0,0 +1,69 @@
1
+ /**
2
+ * @license
3
+ * Copyright 2026 Amodal Labs, Inc.
4
+ * SPDX-License-Identifier: MIT
5
+ */
6
+ import type { DriverDescriptor as TypesDriverDescriptor, DriverRegistry as DriverRegistryShape, RuntimeLogger as Logger, SqlDriver } from '@amodalai/types';
7
+ /**
8
+ * `amodalDriver` block as it appears in a package's `package.json`.
9
+ * The discovery scanner validates that all required fields are
10
+ * present and well-typed before producing a descriptor.
11
+ */
12
+ export interface DriverDescriptor {
13
+ /** npm package name (`@amodalai/postgres-driver`). */
14
+ packageName: string;
15
+ /** Dialect names this driver claims to handle. The runtime checks
16
+ `connection.dialect` against this list at load. */
17
+ dialects: string[];
18
+ /** Connection protocol — always `'sql'` for now, but reserved so
19
+ future protocols can reuse this discovery surface. */
20
+ protocol: 'sql';
21
+ /** Absolute path to the package directory inside node_modules. */
22
+ packageDir: string;
23
+ /** Absolute path to the JS entry the runtime dynamic-imports. */
24
+ moduleEntry: string;
25
+ /** Named export inside `moduleEntry` that returns a `SqlDriver`. */
26
+ exportName: string;
27
+ /** Range of `@amodalai/sql-driver-sdk` versions the driver was
28
+ built against. The runtime checks compatibility before invoking
29
+ the factory. */
30
+ sdkVersion: string;
31
+ }
32
+ export interface DiscoverDriversOptions {
33
+ /** Absolute path to the agent repo root (the directory containing
34
+ `node_modules`). */
35
+ repoPath: string;
36
+ /** Candidate package names to inspect. Sourced from the agent's
37
+ `packages` array in `amodal.json`. Packages without an
38
+ `amodalDriver` block are silently skipped. */
39
+ candidatePackages: string[];
40
+ logger: Logger;
41
+ }
42
+ /**
43
+ * Scan candidate packages for `amodalDriver` blocks and return
44
+ * descriptors. Packages missing the block are skipped silently;
45
+ * packages whose block is malformed throw `SqlRegistryError`.
46
+ */
47
+ export declare function discoverDrivers(opts: DiscoverDriversOptions): DriverDescriptor[];
48
+ /**
49
+ * Registry of discovered SQL drivers. Built once per agent-bundle load
50
+ * and queried per connection at runtime. Implements the
51
+ * `DriverRegistry` shape from `@amodalai/types` so it can be attached
52
+ * to `AgentBundle.sqlDrivers` and consumed across packages without
53
+ * importing concrete classes.
54
+ */
55
+ export declare class DriverRegistry implements DriverRegistryShape {
56
+ private readonly byName;
57
+ private readonly logger;
58
+ constructor(descriptors: DriverDescriptor[], logger: Logger);
59
+ list(): TypesDriverDescriptor[];
60
+ has(packageName: string): boolean;
61
+ get(packageName: string): DriverDescriptor | undefined;
62
+ /**
63
+ * Dynamic-import the descriptor's module, call the named factory,
64
+ * and return the resulting `SqlDriver`. Each call produces a fresh
65
+ * instance — drivers are not cached at the registry layer; the
66
+ * caller (typically the repo loader) owns lifecycle.
67
+ */
68
+ loadDriver(packageName: string): Promise<SqlDriver>;
69
+ }
@@ -0,0 +1,192 @@
1
+ /**
2
+ * @license
3
+ * Copyright 2026 Amodal Labs, Inc.
4
+ * SPDX-License-Identifier: MIT
5
+ */
6
+ /**
7
+ * Discovery and loading of SQL drivers published as npm packages.
8
+ *
9
+ * A driver opts in by declaring an `amodalDriver` block in its
10
+ * `package.json`. The runtime scans installed packages for these
11
+ * blocks at agent-bundle load and builds a `DriverRegistry`. At
12
+ * connection load, the registry dynamic-imports the named module and
13
+ * calls the declared zero-arg factory export, which returns a fresh
14
+ * `SqlDriver` instance. The runtime then calls `driver.init(config,
15
+ * parsers)` to wire it up — capabilities come back from the handshake,
16
+ * not from the descriptor.
17
+ */
18
+ import { existsSync, readFileSync } from 'node:fs';
19
+ import path from 'node:path';
20
+ import { pathToFileURL } from 'node:url';
21
+ import { SqlRegistryError } from './errors.js';
22
+ /**
23
+ * Scan candidate packages for `amodalDriver` blocks and return
24
+ * descriptors. Packages missing the block are skipped silently;
25
+ * packages whose block is malformed throw `SqlRegistryError`.
26
+ */
27
+ export function discoverDrivers(opts) {
28
+ const descriptors = [];
29
+ for (const packageName of opts.candidatePackages) {
30
+ const descriptor = readDriverDescriptor(packageName, opts.repoPath);
31
+ if (descriptor) {
32
+ descriptors.push(descriptor);
33
+ opts.logger.info('sql_driver_discovered', {
34
+ package: descriptor.packageName,
35
+ dialects: descriptor.dialects,
36
+ sdk_version: descriptor.sdkVersion,
37
+ });
38
+ }
39
+ }
40
+ return descriptors;
41
+ }
42
+ function readDriverDescriptor(packageName, repoPath) {
43
+ const packageDir = path.join(repoPath, 'node_modules', ...packageName.split('/'));
44
+ const pkgJsonPath = path.join(packageDir, 'package.json');
45
+ if (!existsSync(pkgJsonPath)) {
46
+ return undefined;
47
+ }
48
+ const pkgJson = parsePackageJson(pkgJsonPath, packageName);
49
+ const block = pkgJson['amodalDriver'];
50
+ if (block === undefined) {
51
+ return undefined;
52
+ }
53
+ return validateDriverDescriptor(block, packageName, packageDir);
54
+ }
55
+ function validateDriverDescriptor(block, packageName, packageDir) {
56
+ if (typeof block !== 'object' || block === null || Array.isArray(block)) {
57
+ throw new SqlRegistryError('INVALID_DESCRIPTOR', `Package "${packageName}" has an amodalDriver field that is not an object`, { kind: 'driver', packageName });
58
+ }
59
+ // eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion -- narrowed by the typeof/null/array guards above.
60
+ const raw = block;
61
+ const protocol = raw['protocol'];
62
+ if (protocol !== 'sql') {
63
+ throw new SqlRegistryError('INVALID_DESCRIPTOR', `Package "${packageName}" amodalDriver.protocol must be "sql"`, { kind: 'driver', packageName, context: { protocol } });
64
+ }
65
+ const dialects = raw['dialects'];
66
+ if (!Array.isArray(dialects) ||
67
+ dialects.length === 0 ||
68
+ !dialects.every((d) => typeof d === 'string')) {
69
+ throw new SqlRegistryError('INVALID_DESCRIPTOR', `Package "${packageName}" amodalDriver.dialects must be a non-empty string array`, { kind: 'driver', packageName });
70
+ }
71
+ const moduleRel = raw['module'];
72
+ if (typeof moduleRel !== 'string' || moduleRel.length === 0) {
73
+ throw new SqlRegistryError('INVALID_DESCRIPTOR', `Package "${packageName}" amodalDriver.module must be a relative path string`, { kind: 'driver', packageName });
74
+ }
75
+ const moduleEntry = path.resolve(packageDir, moduleRel);
76
+ if (!moduleEntry.startsWith(path.resolve(packageDir))) {
77
+ throw new SqlRegistryError('INVALID_DESCRIPTOR', `Package "${packageName}" amodalDriver.module escapes the package directory`, { kind: 'driver', packageName, context: { moduleRel } });
78
+ }
79
+ const exportName = raw['exportName'];
80
+ if (typeof exportName !== 'string' || exportName.length === 0) {
81
+ throw new SqlRegistryError('INVALID_DESCRIPTOR', `Package "${packageName}" amodalDriver.exportName must be a non-empty string`, { kind: 'driver', packageName });
82
+ }
83
+ const sdkVersion = raw['sdkVersion'];
84
+ if (typeof sdkVersion !== 'string' || sdkVersion.length === 0) {
85
+ throw new SqlRegistryError('INVALID_DESCRIPTOR', `Package "${packageName}" amodalDriver.sdkVersion must be a semver range string`, { kind: 'driver', packageName });
86
+ }
87
+ return {
88
+ packageName,
89
+ dialects,
90
+ protocol,
91
+ packageDir,
92
+ moduleEntry,
93
+ exportName,
94
+ sdkVersion,
95
+ };
96
+ }
97
+ function parsePackageJson(pkgJsonPath, packageName) {
98
+ const raw = readFileSync(pkgJsonPath, 'utf-8');
99
+ let parsed;
100
+ try {
101
+ parsed = JSON.parse(raw);
102
+ }
103
+ catch (cause) {
104
+ throw new SqlRegistryError('INVALID_DESCRIPTOR', `Package "${packageName}" has unparseable package.json`, { kind: 'driver', packageName, cause });
105
+ }
106
+ if (typeof parsed !== 'object' || parsed === null || Array.isArray(parsed)) {
107
+ throw new SqlRegistryError('INVALID_DESCRIPTOR', `Package "${packageName}" package.json is not an object`, { kind: 'driver', packageName });
108
+ }
109
+ // eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion -- narrowed by the typeof/null/array guards above.
110
+ return parsed;
111
+ }
112
+ /**
113
+ * Registry of discovered SQL drivers. Built once per agent-bundle load
114
+ * and queried per connection at runtime. Implements the
115
+ * `DriverRegistry` shape from `@amodalai/types` so it can be attached
116
+ * to `AgentBundle.sqlDrivers` and consumed across packages without
117
+ * importing concrete classes.
118
+ */
119
+ export class DriverRegistry {
120
+ byName;
121
+ logger;
122
+ constructor(descriptors, logger) {
123
+ this.byName = new Map(descriptors.map((d) => [d.packageName, d]));
124
+ this.logger = logger;
125
+ }
126
+ list() {
127
+ return Array.from(this.byName.values()).map((d) => ({
128
+ name: d.packageName,
129
+ dialects: d.dialects,
130
+ sdkVersion: d.sdkVersion,
131
+ }));
132
+ }
133
+ has(packageName) {
134
+ return this.byName.has(packageName);
135
+ }
136
+ get(packageName) {
137
+ return this.byName.get(packageName);
138
+ }
139
+ /**
140
+ * Dynamic-import the descriptor's module, call the named factory,
141
+ * and return the resulting `SqlDriver`. Each call produces a fresh
142
+ * instance — drivers are not cached at the registry layer; the
143
+ * caller (typically the repo loader) owns lifecycle.
144
+ */
145
+ async loadDriver(packageName) {
146
+ const descriptor = this.byName.get(packageName);
147
+ if (!descriptor) {
148
+ throw new SqlRegistryError('PACKAGE_NOT_FOUND', `Driver "${packageName}" was referenced but not discovered. Add it to the agent's packages list and run npm install.`, { kind: 'driver', packageName });
149
+ }
150
+ const moduleUrl = pathToFileURL(descriptor.moduleEntry).href;
151
+ let mod;
152
+ try {
153
+ // eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion -- dynamic import yields unknown module shape; narrowed below.
154
+ mod = (await import(moduleUrl));
155
+ }
156
+ catch (cause) {
157
+ throw new SqlRegistryError('FACTORY_FAILED', `Failed to import driver "${packageName}" from ${descriptor.moduleEntry}`, { kind: 'driver', packageName, cause });
158
+ }
159
+ const factory = mod[descriptor.exportName];
160
+ if (typeof factory !== 'function') {
161
+ throw new SqlRegistryError('FACTORY_MISSING', `Driver "${packageName}" does not export "${descriptor.exportName}" as a function`, { kind: 'driver', packageName, context: { exportName: descriptor.exportName } });
162
+ }
163
+ let instance;
164
+ try {
165
+ instance = factory();
166
+ }
167
+ catch (cause) {
168
+ throw new SqlRegistryError('FACTORY_FAILED', `Driver "${packageName}" factory "${descriptor.exportName}" threw`, { kind: 'driver', packageName, cause });
169
+ }
170
+ if (!isSqlDriver(instance)) {
171
+ throw new SqlRegistryError('INVALID_INSTANCE', `Driver "${packageName}" factory returned a value that is not a SqlDriver`, { kind: 'driver', packageName });
172
+ }
173
+ this.logger.info('sql_driver_loaded', {
174
+ package: packageName,
175
+ dialects: descriptor.dialects,
176
+ });
177
+ return instance;
178
+ }
179
+ }
180
+ function isSqlDriver(value) {
181
+ if (typeof value !== 'object' || value === null)
182
+ return false;
183
+ // eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion -- narrowed by the typeof/null guards above.
184
+ const obj = value;
185
+ return (typeof obj['init'] === 'function' &&
186
+ typeof obj['introspectSchema'] === 'function' &&
187
+ typeof obj['parse'] === 'function' &&
188
+ typeof obj['execute'] === 'function' &&
189
+ typeof obj['beginTransaction'] === 'function' &&
190
+ typeof obj['shutdown'] === 'function');
191
+ }
192
+ //# sourceMappingURL=driver-registry.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"driver-registry.js","sourceRoot":"","sources":["../../src/driver-registry.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,44 @@
1
+ /**
2
+ * @license
3
+ * Copyright 2026 Amodal Labs, Inc.
4
+ * SPDX-License-Identifier: MIT
5
+ */
6
+ /**
7
+ * Failures during SQL driver / parser discovery and loading.
8
+ *
9
+ * Discovery scans `node_modules` for `amodalDriver` / `amodalParser`
10
+ * blocks. Loading dynamic-imports the named module, calls the factory,
11
+ * and validates the returned instance against the SqlDriver / Parser
12
+ * shape.
13
+ */
14
+ export type SqlRegistryErrorCode =
15
+ /** Package referenced in connection config wasn't found in node_modules. */
16
+ 'PACKAGE_NOT_FOUND'
17
+ /** package.json has an `amodalDriver` / `amodalParser` block, but it's
18
+ missing required fields or has invalid values. */
19
+ | 'INVALID_DESCRIPTOR'
20
+ /** Dynamic import succeeded but the named factory export isn't a function. */
21
+ | 'FACTORY_MISSING'
22
+ /** Calling the factory threw. */
23
+ | 'FACTORY_FAILED'
24
+ /** Factory returned a value that doesn't satisfy the SqlDriver / Parser shape. */
25
+ | 'INVALID_INSTANCE'
26
+ /** Driver's SDK version doesn't satisfy the runtime's compatibility range. */
27
+ | 'SDK_VERSION_MISMATCH';
28
+ /**
29
+ * Errors thrown by `DriverRegistry` and `ParserRegistry` operations.
30
+ * The `kind` field discriminates which registry surfaced the failure
31
+ * for log/SIEM filtering — both use the same code set.
32
+ */
33
+ export declare class SqlRegistryError extends Error {
34
+ readonly code: SqlRegistryErrorCode;
35
+ readonly kind: 'driver' | 'parser';
36
+ readonly packageName: string;
37
+ readonly context: Record<string, unknown>;
38
+ constructor(code: SqlRegistryErrorCode, message: string, options: {
39
+ kind: 'driver' | 'parser';
40
+ packageName: string;
41
+ context?: Record<string, unknown>;
42
+ cause?: unknown;
43
+ });
44
+ }
@@ -0,0 +1,25 @@
1
+ /**
2
+ * @license
3
+ * Copyright 2026 Amodal Labs, Inc.
4
+ * SPDX-License-Identifier: MIT
5
+ */
6
+ /**
7
+ * Errors thrown by `DriverRegistry` and `ParserRegistry` operations.
8
+ * The `kind` field discriminates which registry surfaced the failure
9
+ * for log/SIEM filtering — both use the same code set.
10
+ */
11
+ export class SqlRegistryError extends Error {
12
+ code;
13
+ kind;
14
+ packageName;
15
+ context;
16
+ constructor(code, message, options) {
17
+ super(message, { cause: options.cause });
18
+ this.name = 'SqlRegistryError';
19
+ this.code = code;
20
+ this.kind = options.kind;
21
+ this.packageName = options.packageName;
22
+ this.context = options.context ?? {};
23
+ }
24
+ }
25
+ //# sourceMappingURL=errors.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"errors.js","sourceRoot":"","sources":["../../src/errors.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAyBH;;;;GAIG;AACH,MAAM,OAAO,gBAAiB,SAAQ,KAAK;IAChC,IAAI,CAAuB;IAC3B,IAAI,CAAsB;IAC1B,WAAW,CAAS;IACpB,OAAO,CAA0B;IAE1C,YACE,IAA0B,EAC1B,OAAe,EACf,OAKC;QAED,KAAK,CAAC,OAAO,EAAE,EAAC,KAAK,EAAE,OAAO,CAAC,KAAK,EAAC,CAAC,CAAC;QACvC,IAAI,CAAC,IAAI,GAAG,kBAAkB,CAAC;QAC/B,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC;QACjB,IAAI,CAAC,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC;QACzB,IAAI,CAAC,WAAW,GAAG,OAAO,CAAC,WAAW,CAAC;QACvC,IAAI,CAAC,OAAO,GAAG,OAAO,CAAC,OAAO,IAAI,EAAE,CAAC;IACvC,CAAC;CACF"}
@@ -0,0 +1,75 @@
1
+ /**
2
+ * @license
3
+ * Copyright 2026 Amodal Labs, Inc.
4
+ * SPDX-License-Identifier: MIT
5
+ */
6
+ /**
7
+ * Authoring surface for SQL drivers and parsers. Driver / parser
8
+ * packages depend on this SDK rather than directly on `@amodalai/types`
9
+ * so the runtime can evolve the type-level contracts on a slower
10
+ * cadence than the runtime internals. Conformance + version-
11
+ * compatibility checks live here too.
12
+ *
13
+ * The runtime cares about three things from a driver / parser package:
14
+ *
15
+ * 1. The `amodalDriver` / `amodalParser` block in `package.json`,
16
+ * pointing at this SDK's `sdkVersion` so the runtime can refuse
17
+ * to load packages built against an incompatible major.
18
+ * 2. The named factory export — a zero-arg function returning a
19
+ * `SqlDriver` or `Parser`. `defineDriver` / `defineParser` here
20
+ * are identity wrappers; their job is purely compile-time type
21
+ * inference today, but they're the natural hook for SDK-version
22
+ * checks or telemetry tomorrow.
23
+ * 3. The shape of the returned object. The runtime validates with
24
+ * structural type guards (see `core/sql/driver-registry.ts`); the
25
+ * types here are the compile-time contract.
26
+ */
27
+ export type { SqlDriver, DriverCapabilities, TransactionHandle, TransactionOptions, Parser, SessionContext, ParamValue, ResultSet, ResultField, SchemaInfo, SchemaInfoTable, SchemaInfoColumn, SqlConnectionConfig, DbConnectionSettings, McpDriverSettings, PoolSettings, ScopingPolicy, QueryConstraints, AuditPolicy, SchemaDriftPolicy, DriftAction, SchemaJson, TableSchema, TableScoping, ColumnPolicy, WriteThresholdRule, LoadedSqlConnection, ParsedStatement, StatementKind, StatementIntent, SelectStatement, InsertStatement, InsertValues, UpdateStatement, DeleteStatement, MergeStatement, MergeAction, SelectItem, TableRef, Assignment, OrderItem, LimitClause, CommonTableExpr, SetOperation, Expression, ColumnRef, ResolvedColumnRef, ParameterRef, LiteralExpr, FunctionCall, BinaryExpr, UnaryExpr, CaseExpr, CastExpr, SubqueryExpr, StarExpr, Predicate, ComparisonPredicate, InPredicate, BetweenPredicate, IsNullPredicate, AndPredicate, OrPredicate, NotPredicate, ExistsPredicate, FunctionPredicate, } from '@amodalai/types';
28
+ import type { Parser, SqlDriver } from '@amodalai/types';
29
+ /**
30
+ * The SDK version this package was built against. Drivers should
31
+ * reference this when declaring `amodalDriver.sdkVersion` in their
32
+ * `package.json` so the runtime's compatibility check is anchored to
33
+ * the actual published contract, not a hand-typed string.
34
+ *
35
+ * Bumped on every major SDK contract change.
36
+ */
37
+ export declare const SDK_VERSION: "1";
38
+ /**
39
+ * Identity helper. Wraps a `SqlDriver` so authors get full inference
40
+ * without explicit type annotations, and so future SDK versions can
41
+ * add behavior (capability claim validation, telemetry hooks) without
42
+ * a breaking signature change.
43
+ *
44
+ * ```ts
45
+ * import {defineDriver} from '@amodalai/sql-driver-sdk';
46
+ *
47
+ * export const createDriver = () => defineDriver({
48
+ * init: async (config, parsers) => { ... },
49
+ * parse: (sql) => { ... },
50
+ * // ...
51
+ * });
52
+ * ```
53
+ */
54
+ export declare function defineDriver<T extends SqlDriver>(driver: T): T;
55
+ /**
56
+ * Identity helper for parsers. Same intent as `defineDriver`.
57
+ *
58
+ * ```ts
59
+ * import {defineParser} from '@amodalai/sql-driver-sdk';
60
+ *
61
+ * export const createParser = () => defineParser({
62
+ * parse: (sql) => { ... },
63
+ * dialects: ['postgres'],
64
+ * });
65
+ * ```
66
+ */
67
+ export declare function defineParser<T extends Parser>(parser: T): T;
68
+ export { SqlRegistryError } from './errors.js';
69
+ export type { SqlRegistryErrorCode } from './errors.js';
70
+ export { DriverRegistry, discoverDrivers, } from './driver-registry.js';
71
+ export type { DriverDescriptor, DiscoverDriversOptions, } from './driver-registry.js';
72
+ export { ParserRegistry, discoverParsers, } from './parser-registry.js';
73
+ export type { ParserDescriptor, DiscoverParsersOptions, } from './parser-registry.js';
74
+ export { SqlConnectionConfigSchema, SchemaJsonSchema, } from './sql-connection-schemas.js';
75
+ export { parseSqlConnectionConfig, parseSchemaJson, } from './sql-connection-parsers.js';
@@ -0,0 +1,69 @@
1
+ /**
2
+ * @license
3
+ * Copyright 2026 Amodal Labs, Inc.
4
+ * SPDX-License-Identifier: MIT
5
+ */
6
+ // ---------------------------------------------------------------------------
7
+ // Authoring helpers
8
+ // ---------------------------------------------------------------------------
9
+ /**
10
+ * The SDK version this package was built against. Drivers should
11
+ * reference this when declaring `amodalDriver.sdkVersion` in their
12
+ * `package.json` so the runtime's compatibility check is anchored to
13
+ * the actual published contract, not a hand-typed string.
14
+ *
15
+ * Bumped on every major SDK contract change.
16
+ */
17
+ export const SDK_VERSION = '1';
18
+ /**
19
+ * Identity helper. Wraps a `SqlDriver` so authors get full inference
20
+ * without explicit type annotations, and so future SDK versions can
21
+ * add behavior (capability claim validation, telemetry hooks) without
22
+ * a breaking signature change.
23
+ *
24
+ * ```ts
25
+ * import {defineDriver} from '@amodalai/sql-driver-sdk';
26
+ *
27
+ * export const createDriver = () => defineDriver({
28
+ * init: async (config, parsers) => { ... },
29
+ * parse: (sql) => { ... },
30
+ * // ...
31
+ * });
32
+ * ```
33
+ */
34
+ export function defineDriver(driver) {
35
+ return driver;
36
+ }
37
+ /**
38
+ * Identity helper for parsers. Same intent as `defineDriver`.
39
+ *
40
+ * ```ts
41
+ * import {defineParser} from '@amodalai/sql-driver-sdk';
42
+ *
43
+ * export const createParser = () => defineParser({
44
+ * parse: (sql) => { ... },
45
+ * dialects: ['postgres'],
46
+ * });
47
+ * ```
48
+ */
49
+ export function defineParser(parser) {
50
+ return parser;
51
+ }
52
+ // ---------------------------------------------------------------------------
53
+ // Discovery + validation — host helpers used by the agent-bundle loader.
54
+ //
55
+ // These live in the SDK rather than `@amodalai/core` so that core never has
56
+ // to know SQL exists: the bundle loader imports `discoverDrivers` /
57
+ // `discoverParsers` / `parseSqlConnectionConfig` / `parseSchemaJson` from
58
+ // here and stays protocol-agnostic.
59
+ // ---------------------------------------------------------------------------
60
+ export { SqlRegistryError } from './errors.js';
61
+ // Concrete classes exposed as `DriverRegistry` / `ParserRegistry`. They
62
+ // implement the interfaces of the same name in `@amodalai/types`, so
63
+ // consumers can use the class type as the interface type wherever the
64
+ // interface was previously imported.
65
+ export { DriverRegistry, discoverDrivers, } from './driver-registry.js';
66
+ export { ParserRegistry, discoverParsers, } from './parser-registry.js';
67
+ export { SqlConnectionConfigSchema, SchemaJsonSchema, } from './sql-connection-schemas.js';
68
+ export { parseSqlConnectionConfig, parseSchemaJson, } from './sql-connection-parsers.js';
69
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AA+GH,8EAA8E;AAC9E,oBAAoB;AACpB,8EAA8E;AAE9E;;;;;;;GAOG;AACH,MAAM,CAAC,MAAM,WAAW,GAAG,GAAY,CAAC;AAExC;;;;;;;;;;;;;;;GAeG;AACH,MAAM,UAAU,YAAY,CAAsB,MAAS;IACzD,OAAO,MAAM,CAAC;AAChB,CAAC;AAED;;;;;;;;;;;GAWG;AACH,MAAM,UAAU,YAAY,CAAmB,MAAS;IACtD,OAAO,MAAM,CAAC;AAChB,CAAC;AAED,8EAA8E;AAC9E,yEAAyE;AACzE,EAAE;AACF,4EAA4E;AAC5E,oEAAoE;AACpE,0EAA0E;AAC1E,oCAAoC;AACpC,8EAA8E;AAE9E,OAAO,EAAC,gBAAgB,EAAC,MAAM,aAAa,CAAC;AAG7C,wEAAwE;AACxE,qEAAqE;AACrE,sEAAsE;AACtE,qCAAqC;AACrC,OAAO,EACL,cAAc,EACd,eAAe,GAChB,MAAM,sBAAsB,CAAC;AAM9B,OAAO,EACL,cAAc,EACd,eAAe,GAChB,MAAM,sBAAsB,CAAC;AAM9B,OAAO,EACL,yBAAyB,EACzB,gBAAgB,GACjB,MAAM,6BAA6B,CAAC;AAErC,OAAO,EACL,wBAAwB,EACxB,eAAe,GAChB,MAAM,6BAA6B,CAAC"}
@@ -0,0 +1,62 @@
1
+ /**
2
+ * @license
3
+ * Copyright 2026 Amodal Labs, Inc.
4
+ * SPDX-License-Identifier: MIT
5
+ */
6
+ import type { Parser, ParserDescriptor as TypesParserDescriptor, ParserRegistry as ParserRegistryShape, RuntimeLogger as Logger } from '@amodalai/types';
7
+ /**
8
+ * `amodalParser` block as it appears in a package's `package.json`,
9
+ * normalized into a descriptor by discovery.
10
+ */
11
+ export interface ParserDescriptor {
12
+ /** npm package name (`@amodalai/postgres-parser`). */
13
+ packageName: string;
14
+ /** Dialects this parser claims to accept. */
15
+ dialects: string[];
16
+ /** Absolute path to the package directory. */
17
+ packageDir: string;
18
+ /** Absolute path to the JS entry the runtime dynamic-imports. */
19
+ moduleEntry: string;
20
+ /** Named export inside `moduleEntry` that returns a `Parser`. */
21
+ exportName: string;
22
+ /** Range of `@amodalai/sql-driver-sdk` versions the parser was
23
+ built against (parsers ship from the same SDK as drivers). */
24
+ sdkVersion: string;
25
+ }
26
+ export interface DiscoverParsersOptions {
27
+ repoPath: string;
28
+ candidatePackages: string[];
29
+ logger: Logger;
30
+ }
31
+ /**
32
+ * Scan candidate packages for `amodalParser` blocks. Packages missing
33
+ * the block are skipped silently; malformed blocks throw
34
+ * `SqlRegistryError`.
35
+ */
36
+ export declare function discoverParsers(opts: DiscoverParsersOptions): ParserDescriptor[];
37
+ /**
38
+ * Implementation of the `ParserRegistry` shape from `@amodalai/types`,
39
+ * which is what `SqlDriver.init(config, parsers)` receives. Parsers
40
+ * are cached after first load — they're stateless and safely shared
41
+ * across drivers.
42
+ */
43
+ export declare class ParserRegistry implements ParserRegistryShape {
44
+ private readonly byName;
45
+ private readonly cache;
46
+ private readonly logger;
47
+ constructor(descriptors: ParserDescriptor[], logger: Logger);
48
+ list(): TypesParserDescriptor[];
49
+ has(packageName: string): boolean;
50
+ /**
51
+ * Synchronous interface required by `SqlDriver.init()` — drivers
52
+ * resolve parsers during the load handshake and shouldn't have to
53
+ * await. Parser instances must be preloaded via `prepare()` first.
54
+ */
55
+ getParser(packageName: string): Parser;
56
+ /**
57
+ * Preload a parser. Called by the repo loader for each parser name
58
+ * referenced by an SQL connection, before any `driver.init()` runs.
59
+ * Idempotent — calling twice returns the cached instance.
60
+ */
61
+ prepare(packageName: string): Promise<Parser>;
62
+ }