@noormdev/sdk 1.0.0-alpha.18 → 1.0.0-alpha.19

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,4 +1,40 @@
1
- import { Kysely, MssqlDialect, sql } from 'kysely';
1
+ import { Kysely, MssqlDialect, sql, OperationNodeTransformer } from 'kysely';
2
+
3
+ // src/core/connection/dialects/mssql.ts
4
+ var LimitToTopTransformer = class extends OperationNodeTransformer {
5
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
6
+ transformSelectQuery(node) {
7
+ const transformed = super.transformSelectQuery(node);
8
+ if (!transformed.limit || transformed.top) {
9
+ return transformed;
10
+ }
11
+ const limitOp = transformed.limit.limit;
12
+ let value;
13
+ if (limitOp?.kind === "ValueNode" && (typeof limitOp.value === "number" || typeof limitOp.value === "bigint")) {
14
+ value = limitOp.value;
15
+ }
16
+ if (value === void 0) {
17
+ return transformed;
18
+ }
19
+ return {
20
+ ...transformed,
21
+ limit: void 0,
22
+ top: {
23
+ kind: "TopNode",
24
+ expression: value
25
+ }
26
+ };
27
+ }
28
+ };
29
+ var MssqlLimitPlugin = class {
30
+ #transformer = new LimitToTopTransformer();
31
+ transformQuery(args) {
32
+ return this.#transformer.transformNode(args.node);
33
+ }
34
+ async transformResult(args) {
35
+ return args.result;
36
+ }
37
+ };
2
38
 
3
39
  // src/core/connection/dialects/mssql.ts
4
40
  function buildTediousConfig(Tedious, config, database) {
@@ -34,7 +70,8 @@ async function verifyDatabaseExists(Tedious, Tarn, config) {
34
70
  ...Tedious,
35
71
  connectionFactory: () => buildTediousConfig(Tedious, config, "master")
36
72
  }
37
- })
73
+ }),
74
+ plugins: [new MssqlLimitPlugin()]
38
75
  });
39
76
  try {
40
77
  const { rows } = await sql`
@@ -67,7 +104,8 @@ async function createMssqlConnection(config) {
67
104
  ...Tedious,
68
105
  connectionFactory: () => buildTediousConfig(Tedious, config)
69
106
  }
70
- })
107
+ }),
108
+ plugins: [new MssqlLimitPlugin()]
71
109
  });
72
110
  return {
73
111
  db,
@@ -77,5 +115,5 @@ async function createMssqlConnection(config) {
77
115
  }
78
116
 
79
117
  export { createMssqlConnection };
80
- //# sourceMappingURL=mssql-7VB7EHRX.js.map
81
- //# sourceMappingURL=mssql-7VB7EHRX.js.map
118
+ //# sourceMappingURL=mssql-65M7MY4Q.js.map
119
+ //# sourceMappingURL=mssql-65M7MY4Q.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../src/core/connection/dialects/mssql-limit-plugin.ts","../../../src/core/connection/dialects/mssql.ts"],"names":[],"mappings":";;;AA4CA,IAAM,qBAAA,GAAN,cAAoC,wBAAA,CAAyB;AAAA;AAAA,EAGtC,qBAAqB,IAAA,EAAgB;AAGpD,IAAA,MAAM,WAAA,GAAc,KAAA,CAAM,oBAAA,CAAqB,IAAI,CAAA;AAGnD,IAAA,IAAI,CAAC,WAAA,CAAY,KAAA,IAAS,WAAA,CAAY,GAAA,EAAK;AAEvC,MAAA,OAAO,WAAA;AAAA,IAEX;AAIA,IAAA,MAAM,OAAA,GAAU,YAAY,KAAA,CAAM,KAAA;AAClC,IAAA,IAAI,KAAA;AAEJ,IAAA,IAAI,OAAA,EAAS,IAAA,KAAS,WAAA,KAAgB,OAAO,OAAA,CAAQ,UAAU,QAAA,IAAY,OAAO,OAAA,CAAQ,KAAA,KAAU,QAAA,CAAA,EAAW;AAE3G,MAAA,KAAA,GAAQ,OAAA,CAAQ,KAAA;AAAA,IAEpB;AAGA,IAAA,IAAI,UAAU,MAAA,EAAW;AAErB,MAAA,OAAO,WAAA;AAAA,IAEX;AAGA,IAAA,OAAO;AAAA,MACH,GAAG,WAAA;AAAA,MACH,KAAA,EAAO,MAAA;AAAA,MACP,GAAA,EAAK;AAAA,QACD,IAAA,EAAM,SAAA;AAAA,QACN,UAAA,EAAY;AAAA;AAChB,KACJ;AAAA,EAEJ;AAEJ,CAAA;AAYO,IAAM,mBAAN,MAA+C;AAAA,EAEzC,YAAA,GAAe,IAAI,qBAAA,EAAsB;AAAA,EAElD,eAAe,IAAA,EAAmD;AAE9D,IAAA,OAAO,IAAA,CAAK,YAAA,CAAa,aAAA,CAAc,IAAA,CAAK,IAAI,CAAA;AAAA,EAEpD;AAAA,EAEA,MAAM,gBAAgB,IAAA,EAAmE;AAErF,IAAA,OAAO,IAAA,CAAK,MAAA;AAAA,EAEhB;AAEJ,CAAA;;;ACjGA,SAAS,kBAAA,CACL,OAAA,EACA,MAAA,EACA,QAAA,EACF;AAEE,EAAA,OAAO,IAAI,QAAQ,UAAA,CAAW;AAAA,IAC1B,MAAA,EAAQ,OAAO,IAAA,IAAQ,WAAA;AAAA,IACvB,cAAA,EAAgB;AAAA,MACZ,IAAA,EAAM,SAAA;AAAA,MACN,OAAA,EAAS;AAAA,QACL,UAAU,MAAA,CAAO,IAAA;AAAA,QACjB,UAAU,MAAA,CAAO;AAAA;AACrB,KACJ;AAAA,IACA,OAAA,EAAS;AAAA,MACL,IAAA,EAAM,OAAO,IAAA,IAAQ,IAAA;AAAA,MACrB,QAAA,EAAU,YAAY,MAAA,CAAO,QAAA;AAAA,MAC7B,sBAAA,EAAwB,CAAC,MAAA,CAAO,GAAA;AAAA,MAChC,OAAA,EAAS;AAAA;AACb,GACH,CAAA;AAEL;AASA,eAAe,oBAAA,CACX,OAAA,EACA,IAAA,EACA,MAAA,EACa;AAEb,EAAA,MAAM,QAAA,GAAW,IAAI,MAAA,CAAgB;AAAA,IACjC,OAAA,EAAS,IAAI,YAAA,CAAa;AAAA,MACtB,IAAA,EAAM;AAAA,QACF,GAAG,IAAA;AAAA,QACH,OAAA,EAAS;AAAA,UACL,GAAA,EAAK,CAAA;AAAA,UACL,GAAA,EAAK,CAAA;AAAA,UACL,oBAAA,EAAsB;AAAA;AAC1B,OACJ;AAAA,MACA,OAAA,EAAS;AAAA,QACL,GAAG,OAAA;AAAA,QACH,iBAAA,EAAmB,MAAM,kBAAA,CAAmB,OAAA,EAAS,QAAQ,QAAQ;AAAA;AACzE,KACH,CAAA;AAAA,IACD,OAAA,EAAS,CAAC,IAAI,gBAAA,EAAkB;AAAA,GACnC,CAAA;AAED,EAAA,IAAI;AAEA,IAAA,MAAM,EAAE,IAAA,EAAK,GAAI,MAAM,GAAA;AAAA,wDAAA,EAC2B,OAAO,QAAQ;AAAA,QAAA,CAAA,CAC/D,QAAQ,QAAQ,CAAA;AAElB,IAAA,IAAI,IAAA,CAAK,WAAW,CAAA,EAAG;AAEnB,MAAA,MAAM,IAAI,KAAA;AAAA,QACN,CAAA,UAAA,EAAa,MAAA,CAAO,QAAQ,CAAA,oBAAA,EAAuB,MAAA,CAAO,QAAQ,WAAW,CAAA,CAAA,EAAI,MAAA,CAAO,IAAA,IAAQ,IAAI,CAAA;AAAA,OACxG;AAAA,IAEJ;AAAA,EAEJ,CAAA,SACA;AAEI,IAAA,MAAM,SAAS,OAAA,EAAQ;AAAA,EAE3B;AAEJ;AAqBA,eAAsB,sBAAsB,MAAA,EAAqD;AAG7F,EAAA,MAAM,OAAA,GAAU,MAAM,OAAO,SAAS,CAAA;AACtC,EAAA,MAAM,IAAA,GAAO,MAAM,OAAO,MAAM,CAAA;AAGhC,EAAA,MAAM,oBAAA,CAAqB,OAAA,EAAS,IAAA,EAAM,MAAM,CAAA;AAEhD,EAAA,MAAM,EAAA,GAAK,IAAI,MAAA,CAAgB;AAAA,IAC3B,OAAA,EAAS,IAAI,YAAA,CAAa;AAAA,MACtB,IAAA,EAAM;AAAA,QACF,GAAG,IAAA;AAAA,QACH,OAAA,EAAS;AAAA,UACL,GAAA,EAAK,MAAA,CAAO,IAAA,EAAM,GAAA,IAAO,CAAA;AAAA,UACzB,GAAA,EAAK,MAAA,CAAO,IAAA,EAAM,GAAA,IAAO,EAAA;AAAA,UACzB,oBAAA,EAAsB;AAAA;AAC1B,OACJ;AAAA,MACA,OAAA,EAAS;AAAA,QACL,GAAG,OAAA;AAAA,QACH,iBAAA,EAAmB,MAAM,kBAAA,CAAmB,OAAA,EAAS,MAAM;AAAA;AAC/D,KACH,CAAA;AAAA,IACD,OAAA,EAAS,CAAC,IAAI,gBAAA,EAAkB;AAAA,GACnC,CAAA;AAED,EAAA,OAAO;AAAA,IACH,EAAA;AAAA,IACA,OAAA,EAAS,OAAA;AAAA,IACT,OAAA,EAAS,MAAM,EAAA,CAAG,OAAA;AAAQ,GAC9B;AAEJ","file":"mssql-65M7MY4Q.js","sourcesContent":["/**\n * Kysely plugin that converts LIMIT to TOP for MSSQL.\n *\n * Kysely 0.28.x's MssqlQueryCompiler does not override visitLimit(),\n * so .limit(n) generates invalid `LIMIT n` SQL instead of `TOP(n)`.\n * This plugin transforms the query AST before compilation, converting\n * LimitNode to TopNode on SELECT queries.\n *\n * WHY: MSSQL does not support the LIMIT keyword. It uses TOP(n) for\n * simple row limiting and OFFSET...FETCH for pagination.\n *\n * @example\n * ```typescript\n * import { Kysely, MssqlDialect } from 'kysely'\n * import { MssqlLimitPlugin } from './mssql-limit-plugin'\n *\n * const db = new Kysely({\n * dialect: new MssqlDialect({...}),\n * plugins: [new MssqlLimitPlugin()],\n * })\n *\n * // .limit() now works correctly on MSSQL\n * await db.selectFrom('users').selectAll().limit(10).execute()\n * // SQL: SELECT TOP(10) * FROM \"users\"\n * ```\n */\nimport {\n OperationNodeTransformer,\n type KyselyPlugin,\n type PluginTransformQueryArgs,\n type PluginTransformResultArgs,\n type QueryResult,\n type UnknownRow,\n} from 'kysely';\n\nimport type { RootOperationNode } from 'kysely';\n\n/**\n * AST transformer that rewrites LimitNode → TopNode on SELECT queries.\n *\n * Only transforms when:\n * - The SELECT has a limit but no top already set\n * - The limit value is a ValueNode containing a number\n */\nclass LimitToTopTransformer extends OperationNodeTransformer {\n\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n protected override transformSelectQuery(node: any): any {\n\n // Let parent transform children first (handles subqueries)\n const transformed = super.transformSelectQuery(node);\n\n // Only convert if there's a limit and no top already\n if (!transformed.limit || transformed.top) {\n\n return transformed;\n\n }\n\n // Extract the numeric value from the LimitNode\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n const limitOp = transformed.limit.limit as any;\n let value: number | bigint | undefined;\n\n if (limitOp?.kind === 'ValueNode' && (typeof limitOp.value === 'number' || typeof limitOp.value === 'bigint')) {\n\n value = limitOp.value;\n\n }\n\n // Can't convert non-literal limits\n if (value === undefined) {\n\n return transformed;\n\n }\n\n // Replace limit with top\n return {\n ...transformed,\n limit: undefined,\n top: {\n kind: 'TopNode',\n expression: value,\n },\n };\n\n }\n\n}\n\n/**\n * Kysely plugin that patches .limit() for MSSQL compatibility.\n *\n * Add to the Kysely instance via the plugins option:\n *\n * @example\n * ```typescript\n * new Kysely({ dialect, plugins: [new MssqlLimitPlugin()] })\n * ```\n */\nexport class MssqlLimitPlugin implements KyselyPlugin {\n\n readonly #transformer = new LimitToTopTransformer();\n\n transformQuery(args: PluginTransformQueryArgs): RootOperationNode {\n\n return this.#transformer.transformNode(args.node) as RootOperationNode;\n\n }\n\n async transformResult(args: PluginTransformResultArgs): Promise<QueryResult<UnknownRow>> {\n\n return args.result;\n\n }\n\n}\n","/**\n * SQL Server (MSSQL) dialect adapter.\n *\n * Uses 'tedious' and 'tarn' packages for MSSQL connections.\n * Install with: npm install tedious tarn\n *\n * Verifies database existence via sys.databases before connecting\n * to the target database, avoiding cryptic ECONNRESET errors when\n * the database doesn't exist.\n */\nimport { Kysely, MssqlDialect, sql } from 'kysely';\nimport type { ConnectionConfig, ConnectionResult } from '../types.js';\nimport { MssqlLimitPlugin } from './mssql-limit-plugin.js';\n\n/**\n * Build tedious connection options from noorm config.\n *\n * Centralizes the tedious config so both the preflight check\n * and the real pool use the same settings.\n */\nfunction buildTediousConfig(\n Tedious: typeof import('tedious'),\n config: ConnectionConfig,\n database?: string,\n) {\n\n return new Tedious.Connection({\n server: config.host ?? 'localhost',\n authentication: {\n type: 'default',\n options: {\n userName: config.user,\n password: config.password,\n },\n },\n options: {\n port: config.port ?? 1433,\n database: database ?? config.database,\n trustServerCertificate: !config.ssl,\n encrypt: true,\n },\n });\n\n}\n\n/**\n * Verify the target database exists by querying sys.databases on master.\n *\n * Connects to 'master' first and checks sys.databases. Throws a clear\n * error if the database is missing, instead of letting tedious hang\n * with a cryptic ECONNRESET.\n */\nasync function verifyDatabaseExists(\n Tedious: typeof import('tedious'),\n Tarn: typeof import('tarn'),\n config: ConnectionConfig,\n): Promise<void> {\n\n const masterDb = new Kysely<unknown>({\n dialect: new MssqlDialect({\n tarn: {\n ...Tarn,\n options: {\n min: 0,\n max: 1,\n propagateCreateError: true,\n },\n },\n tedious: {\n ...Tedious,\n connectionFactory: () => buildTediousConfig(Tedious, config, 'master'),\n },\n }),\n plugins: [new MssqlLimitPlugin()],\n });\n\n try {\n\n const { rows } = await sql<{ name: string }>`\n SELECT name FROM sys.databases WHERE name = ${config.database}\n `.execute(masterDb);\n\n if (rows.length === 0) {\n\n throw new Error(\n `Database '${config.database}' does not exist on ${config.host ?? 'localhost'}:${config.port ?? 1433}`,\n );\n\n }\n\n }\n finally {\n\n await masterDb.destroy();\n\n }\n\n}\n\n/**\n * Create a SQL Server connection.\n *\n * Verifies the target database exists via master before opening\n * the connection pool. This avoids the tedious/tarn hang that\n * occurs when MSSQL rejects login for a non-existent database.\n *\n * @example\n * ```typescript\n * const conn = createMssqlConnection({\n * dialect: 'mssql',\n * host: 'localhost',\n * port: 1433,\n * database: 'myapp',\n * user: 'sa',\n * password: 'secret',\n * })\n * ```\n */\nexport async function createMssqlConnection(config: ConnectionConfig): Promise<ConnectionResult> {\n\n // Dynamic import to avoid compile-time dependency\n const Tedious = await import('tedious');\n const Tarn = await import('tarn');\n\n // Preflight: verify database exists via master\n await verifyDatabaseExists(Tedious, Tarn, config);\n\n const db = new Kysely<unknown>({\n dialect: new MssqlDialect({\n tarn: {\n ...Tarn,\n options: {\n min: config.pool?.min ?? 0,\n max: config.pool?.max ?? 10,\n propagateCreateError: true,\n },\n },\n tedious: {\n ...Tedious,\n connectionFactory: () => buildTediousConfig(Tedious, config),\n },\n }),\n plugins: [new MssqlLimitPlugin()],\n });\n\n return {\n db,\n dialect: 'mssql',\n destroy: () => db.destroy(),\n };\n\n}\n"]}
@@ -0,0 +1,4 @@
1
+ export { deleteVaultSecret, getAllVaultSecrets, getVaultKey, getVaultSecret, getVaultStatus, initializeVault, listVaultSecretKeys, setVaultSecret, vaultSecretExists } from './chunk-HB3JXUJV.js';
2
+ import './chunk-BP4PMFJF.js';
3
+ //# sourceMappingURL=storage-WTYJE355.js.map
4
+ //# sourceMappingURL=storage-WTYJE355.js.map
@@ -1 +1 @@
1
- {"version":3,"sources":[],"names":[],"mappings":"","file":"storage-NDKBEHIZ.js"}
1
+ {"version":3,"sources":[],"names":[],"mappings":"","file":"storage-WTYJE355.js"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@noormdev/sdk",
3
- "version": "1.0.0-alpha.18",
3
+ "version": "1.0.0-alpha.19",
4
4
  "description": "Database schema & changeset manager SDK",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../../../src/core/observer.ts"],"names":[],"mappings":";;;AAoMO,IAAM,QAAA,GAAW,IAAI,cAAA,CAA4B;AAAA,EACpD,IAAA,EAAM,OAAA;AAAA,EACN,KAAK,OAAA,CAAQ,GAAA,CAAI,aAAa,CAAA,GACxB,CAAC,WAAW,OAAA,CAAQ,KAAA,CAAM,CAAA,OAAA,EAAU,MAAA,CAAO,EAAE,CAAA,EAAA,EAAK,MAAA,CAAO,OAAO,KAAK,CAAC,EAAE,CAAA,GACxE;AACV,CAAC","file":"chunk-4HW4CS2C.js","sourcesContent":["/**\n * Central event system for noorm.\n *\n * Core modules emit events, CLI subscribes. This creates a clean separation\n * between business logic and UI concerns.\n *\n * @example\n * ```typescript\n * // In core module - emit events at key points\n * observer.emit('file:before', { filepath, checksum, configName })\n *\n * // In CLI - subscribe to events\n * const cleanup = observer.on('file:after', (data) => updateProgress(data))\n *\n * // Pattern matching for multiple events\n * observer.on(/^file:/, ({ event, data }) => logFileEvent(event, data))\n * ```\n */\nimport { ObserverEngine, type Events } from '@logosdx/observer';\n\nimport type { SettingsEvents } from './settings/index.js';\nimport type { AppMode, ShutdownReason, ShutdownPhase, PhaseStatus } from './lifecycle/types.js';\nimport type { UpdateEvents } from './update/types.js';\nimport type { VaultEvents } from './vault/events.js';\nimport type { TransferEvents } from './transfer/events.js';\nimport type { DtEvents } from './dt/events.js';\n\n/**\n * All events emitted by noorm core modules.\n *\n * Events are namespaced by module:\n * - `file:*` - Individual SQL file execution\n * - `build:*` - Schema build operations\n * - `run:*` - Ad-hoc file/dir execution\n * - `change:*` - Change execution\n * - `lock:*` - Lock acquisition/release\n * - `state:*` - State load/persist\n * - `config:*` - Config CRUD\n * - `secret:*` - Secret CRUD\n * - `db:*` - Database lifecycle\n * - `template:*` - Template rendering\n * - `identity:*` - Identity resolution\n * - `connection:*` - Database connections\n * - `settings:*` - Settings lifecycle and mutations\n * - `vault:*` - Vault operations\n * - `transfer:*` - Data transfer operations\n * - `dt:*` - .dt format export/import/stream operations\n * - `error` - Catch-all errors\n */\nexport interface NoormEvents extends SettingsEvents, UpdateEvents, VaultEvents, TransferEvents, DtEvents {\n // File execution\n 'file:before': { filepath: string; checksum: string; configName: string };\n 'file:after': {\n filepath: string;\n status: 'success' | 'failed';\n durationMs: number;\n error?: string;\n };\n 'file:skip': { filepath: string; reason: 'unchanged' | 'already-run' };\n 'file:dry-run': {\n filepath: string;\n status: 'success' | 'failed';\n outputPath?: string;\n error?: string;\n };\n\n // Change lifecycle\n 'change:created': { name: string; path: string };\n 'change:start': { name: string; direction: 'change' | 'revert'; files: string[] };\n 'change:file': { change: string; filepath: string; index: number; total: number };\n 'change:complete': {\n name: string;\n direction: 'change' | 'revert';\n status: 'success' | 'failed';\n durationMs: number;\n };\n 'change:skip': { name: string; reason: string };\n\n // Build/Run\n 'build:start': { sqlPath: string; fileCount: number };\n 'build:complete': {\n status: 'success' | 'failed' | 'partial';\n filesRun: number;\n filesSkipped: number;\n filesFailed: number;\n durationMs: number;\n };\n 'run:file': { filepath: string; configName: string };\n 'run:dir': { dirpath: string; fileCount: number; configName: string };\n\n // Lock\n 'lock:acquiring': { configName: string; identity: string };\n 'lock:acquired': { configName: string; identity: string; expiresAt: Date };\n 'lock:released': { configName: string; identity: string };\n 'lock:blocked': { configName: string; holder: string; heldSince: Date };\n 'lock:expired': { configName: string; previousHolder: string };\n\n // State\n 'state:loaded': { configCount: number; activeConfig: string | null; version: string };\n 'state:persisted': { configCount: number };\n 'state:migrated': { from: string; to: string };\n\n // Config\n 'config:created': { name: string };\n 'config:updated': { name: string; fields: string[] };\n 'config:deleted': { name: string };\n 'config:activated': { name: string; previous: string | null };\n\n // Secrets (config-scoped)\n 'secret:set': { configName: string; key: string };\n 'secret:deleted': { configName: string; key: string };\n\n // Global secrets (app-level)\n 'global-secret:set': { key: string };\n 'global-secret:deleted': { key: string };\n\n // Known users\n 'known-user:added': { email: string; source: string };\n\n // DB lifecycle\n 'db:creating': { configName: string; database: string };\n 'db:created': { configName: string; database: string; durationMs: number };\n 'db:destroying': { configName: string; database: string };\n 'db:destroyed': { configName: string; database: string };\n 'db:bootstrap': { configName: string; tables: string[] };\n\n // Template\n 'template:render': { filepath: string; durationMs: number };\n 'template:load': { filepath: string; format: string };\n 'template:helpers': { filepath: string; count: number };\n\n // Identity (audit)\n 'identity:resolved': {\n name: string;\n email?: string;\n source: 'state' | 'git' | 'system' | 'config' | 'env';\n };\n\n // Identity (cryptographic)\n 'identity:created': { identityHash: string; name: string; email: string; machine: string };\n 'identity:registered': { identityHash: string; name: string; email: string };\n 'identity:synced': { configName: string; registered: boolean; knownUsersCount: number };\n 'identity:not-found': void;\n\n // Connection\n 'connection:open': { configName: string; dialect: string };\n 'connection:close': { configName: string };\n 'connection:error': { configName: string; error: string };\n\n // App lifecycle\n 'app:starting': { mode: AppMode };\n 'app:ready': { mode: AppMode; startedAt: Date };\n 'app:shutdown': { reason: ShutdownReason; exitCode: number };\n 'app:shutdown:phase': {\n phase: ShutdownPhase;\n status: PhaseStatus;\n durationMs?: number;\n error?: Error;\n };\n 'app:exit': { code: number };\n 'app:fatal': { error: Error; type?: 'exception' | 'rejection' };\n\n // Router\n 'router:navigated': { from: string; to: string; params: Record<string, string | number | boolean | undefined> };\n 'router:popped': { popped: string; to: string };\n\n // Errors\n error: { source: string; error: Error; context?: Record<string, unknown> };\n}\n\nexport type NoormEventNames = Events<NoormEvents>;\nexport type NoormEventCallback<E extends NoormEventNames> = ObserverEngine.EventCallback<\n NoormEvents[E]\n>;\n\n/**\n * Global observer instance for noorm.\n *\n * Enable debug mode with `NOORM_DEBUG=1` to see all events as they occur.\n *\n * @example\n * ```typescript\n * import { observer } from './observer'\n *\n * // Emit an event\n * observer.emit('file:before', { filepath, checksum, configName })\n *\n * // Subscribe to an event\n * const cleanup = observer.on('file:after', (data) => {\n * console.log(`File ${data.filepath}: ${data.status}`)\n * })\n *\n * // Clean up when done\n * cleanup()\n * ```\n */\nexport const observer = new ObserverEngine<NoormEvents>({\n name: 'noorm',\n spy: process.env['NOORM_DEBUG']\n ? (action) => console.error(`[noorm:${action.fn}] ${String(action.event)}`)\n : undefined,\n});\n\n// ? Not against this, but why are we re-exporting? convenience\nexport type { ObserverEngine };\n\n"]}
@@ -1,4 +0,0 @@
1
- export { eta, isTemplate, processFile, processFiles, renderTemplate } from './chunk-KF7GE2VM.js';
2
- import './chunk-4HW4CS2C.js';
3
- //# sourceMappingURL=engine-IFYFFWFR.js.map
4
- //# sourceMappingURL=engine-IFYFFWFR.js.map
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../../../src/core/connection/dialects/mssql.ts"],"names":[],"mappings":";;;AAmBA,SAAS,kBAAA,CACL,OAAA,EACA,MAAA,EACA,QAAA,EACF;AAEE,EAAA,OAAO,IAAI,QAAQ,UAAA,CAAW;AAAA,IAC1B,MAAA,EAAQ,OAAO,IAAA,IAAQ,WAAA;AAAA,IACvB,cAAA,EAAgB;AAAA,MACZ,IAAA,EAAM,SAAA;AAAA,MACN,OAAA,EAAS;AAAA,QACL,UAAU,MAAA,CAAO,IAAA;AAAA,QACjB,UAAU,MAAA,CAAO;AAAA;AACrB,KACJ;AAAA,IACA,OAAA,EAAS;AAAA,MACL,IAAA,EAAM,OAAO,IAAA,IAAQ,IAAA;AAAA,MACrB,QAAA,EAAU,YAAY,MAAA,CAAO,QAAA;AAAA,MAC7B,sBAAA,EAAwB,CAAC,MAAA,CAAO,GAAA;AAAA,MAChC,OAAA,EAAS;AAAA;AACb,GACH,CAAA;AAEL;AASA,eAAe,oBAAA,CACX,OAAA,EACA,IAAA,EACA,MAAA,EACa;AAEb,EAAA,MAAM,QAAA,GAAW,IAAI,MAAA,CAAgB;AAAA,IACjC,OAAA,EAAS,IAAI,YAAA,CAAa;AAAA,MACtB,IAAA,EAAM;AAAA,QACF,GAAG,IAAA;AAAA,QACH,OAAA,EAAS;AAAA,UACL,GAAA,EAAK,CAAA;AAAA,UACL,GAAA,EAAK,CAAA;AAAA,UACL,oBAAA,EAAsB;AAAA;AAC1B,OACJ;AAAA,MACA,OAAA,EAAS;AAAA,QACL,GAAG,OAAA;AAAA,QACH,iBAAA,EAAmB,MAAM,kBAAA,CAAmB,OAAA,EAAS,QAAQ,QAAQ;AAAA;AACzE,KACH;AAAA,GACJ,CAAA;AAED,EAAA,IAAI;AAEA,IAAA,MAAM,EAAE,IAAA,EAAK,GAAI,MAAM,GAAA;AAAA,wDAAA,EAC2B,OAAO,QAAQ;AAAA,QAAA,CAAA,CAC/D,QAAQ,QAAQ,CAAA;AAElB,IAAA,IAAI,IAAA,CAAK,WAAW,CAAA,EAAG;AAEnB,MAAA,MAAM,IAAI,KAAA;AAAA,QACN,CAAA,UAAA,EAAa,MAAA,CAAO,QAAQ,CAAA,oBAAA,EAAuB,MAAA,CAAO,QAAQ,WAAW,CAAA,CAAA,EAAI,MAAA,CAAO,IAAA,IAAQ,IAAI,CAAA;AAAA,OACxG;AAAA,IAEJ;AAAA,EAEJ,CAAA,SACA;AAEI,IAAA,MAAM,SAAS,OAAA,EAAQ;AAAA,EAE3B;AAEJ;AAqBA,eAAsB,sBAAsB,MAAA,EAAqD;AAG7F,EAAA,MAAM,OAAA,GAAU,MAAM,OAAO,SAAS,CAAA;AACtC,EAAA,MAAM,IAAA,GAAO,MAAM,OAAO,MAAM,CAAA;AAGhC,EAAA,MAAM,oBAAA,CAAqB,OAAA,EAAS,IAAA,EAAM,MAAM,CAAA;AAEhD,EAAA,MAAM,EAAA,GAAK,IAAI,MAAA,CAAgB;AAAA,IAC3B,OAAA,EAAS,IAAI,YAAA,CAAa;AAAA,MACtB,IAAA,EAAM;AAAA,QACF,GAAG,IAAA;AAAA,QACH,OAAA,EAAS;AAAA,UACL,GAAA,EAAK,MAAA,CAAO,IAAA,EAAM,GAAA,IAAO,CAAA;AAAA,UACzB,GAAA,EAAK,MAAA,CAAO,IAAA,EAAM,GAAA,IAAO,EAAA;AAAA,UACzB,oBAAA,EAAsB;AAAA;AAC1B,OACJ;AAAA,MACA,OAAA,EAAS;AAAA,QACL,GAAG,OAAA;AAAA,QACH,iBAAA,EAAmB,MAAM,kBAAA,CAAmB,OAAA,EAAS,MAAM;AAAA;AAC/D,KACH;AAAA,GACJ,CAAA;AAED,EAAA,OAAO;AAAA,IACH,EAAA;AAAA,IACA,OAAA,EAAS,OAAA;AAAA,IACT,OAAA,EAAS,MAAM,EAAA,CAAG,OAAA;AAAQ,GAC9B;AAEJ","file":"mssql-7VB7EHRX.js","sourcesContent":["/**\n * SQL Server (MSSQL) dialect adapter.\n *\n * Uses 'tedious' and 'tarn' packages for MSSQL connections.\n * Install with: npm install tedious tarn\n *\n * Verifies database existence via sys.databases before connecting\n * to the target database, avoiding cryptic ECONNRESET errors when\n * the database doesn't exist.\n */\nimport { Kysely, MssqlDialect, sql } from 'kysely';\nimport type { ConnectionConfig, ConnectionResult } from '../types.js';\n\n/**\n * Build tedious connection options from noorm config.\n *\n * Centralizes the tedious config so both the preflight check\n * and the real pool use the same settings.\n */\nfunction buildTediousConfig(\n Tedious: typeof import('tedious'),\n config: ConnectionConfig,\n database?: string,\n) {\n\n return new Tedious.Connection({\n server: config.host ?? 'localhost',\n authentication: {\n type: 'default',\n options: {\n userName: config.user,\n password: config.password,\n },\n },\n options: {\n port: config.port ?? 1433,\n database: database ?? config.database,\n trustServerCertificate: !config.ssl,\n encrypt: true,\n },\n });\n\n}\n\n/**\n * Verify the target database exists by querying sys.databases on master.\n *\n * Connects to 'master' first and checks sys.databases. Throws a clear\n * error if the database is missing, instead of letting tedious hang\n * with a cryptic ECONNRESET.\n */\nasync function verifyDatabaseExists(\n Tedious: typeof import('tedious'),\n Tarn: typeof import('tarn'),\n config: ConnectionConfig,\n): Promise<void> {\n\n const masterDb = new Kysely<unknown>({\n dialect: new MssqlDialect({\n tarn: {\n ...Tarn,\n options: {\n min: 0,\n max: 1,\n propagateCreateError: true,\n },\n },\n tedious: {\n ...Tedious,\n connectionFactory: () => buildTediousConfig(Tedious, config, 'master'),\n },\n }),\n });\n\n try {\n\n const { rows } = await sql<{ name: string }>`\n SELECT name FROM sys.databases WHERE name = ${config.database}\n `.execute(masterDb);\n\n if (rows.length === 0) {\n\n throw new Error(\n `Database '${config.database}' does not exist on ${config.host ?? 'localhost'}:${config.port ?? 1433}`,\n );\n\n }\n\n }\n finally {\n\n await masterDb.destroy();\n\n }\n\n}\n\n/**\n * Create a SQL Server connection.\n *\n * Verifies the target database exists via master before opening\n * the connection pool. This avoids the tedious/tarn hang that\n * occurs when MSSQL rejects login for a non-existent database.\n *\n * @example\n * ```typescript\n * const conn = createMssqlConnection({\n * dialect: 'mssql',\n * host: 'localhost',\n * port: 1433,\n * database: 'myapp',\n * user: 'sa',\n * password: 'secret',\n * })\n * ```\n */\nexport async function createMssqlConnection(config: ConnectionConfig): Promise<ConnectionResult> {\n\n // Dynamic import to avoid compile-time dependency\n const Tedious = await import('tedious');\n const Tarn = await import('tarn');\n\n // Preflight: verify database exists via master\n await verifyDatabaseExists(Tedious, Tarn, config);\n\n const db = new Kysely<unknown>({\n dialect: new MssqlDialect({\n tarn: {\n ...Tarn,\n options: {\n min: config.pool?.min ?? 0,\n max: config.pool?.max ?? 10,\n propagateCreateError: true,\n },\n },\n tedious: {\n ...Tedious,\n connectionFactory: () => buildTediousConfig(Tedious, config),\n },\n }),\n });\n\n return {\n db,\n dialect: 'mssql',\n destroy: () => db.destroy(),\n };\n\n}\n"]}
@@ -1,4 +0,0 @@
1
- export { deleteVaultSecret, getAllVaultSecrets, getVaultKey, getVaultSecret, getVaultStatus, initializeVault, listVaultSecretKeys, setVaultSecret, vaultSecretExists } from './chunk-LJDHQEWW.js';
2
- import './chunk-4HW4CS2C.js';
3
- //# sourceMappingURL=storage-NDKBEHIZ.js.map
4
- //# sourceMappingURL=storage-NDKBEHIZ.js.map