@oktis-works/database 0.1.8 → 0.1.9

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/dist/index.d.ts CHANGED
@@ -1,5 +1,6 @@
1
1
  export { createConnection, getConnection, closeConnection, healthCheck } from './connection.js';
2
2
  export { setTenantContext, clearTenantContext, getCurrentTenantId, enableRLS } from './rls/index.js';
3
3
  export { loadMigrationsFromDir, getAppliedMigrations, applyMigration, rollbackMigration, runMigrations, runPluginMigrations, rollbackPluginMigrations, type MigrationFile, } from './migrations/runner.js';
4
+ export { ensureCoreSchema, resolveTenantId } from './migrations/bootstrap.js';
4
5
  export { schema, getSchema } from './schema/index.js';
5
6
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,gBAAgB,EAAE,aAAa,EAAE,eAAe,EAAE,WAAW,EAAE,MAAM,iBAAiB,CAAC;AAChG,OAAO,EAAE,gBAAgB,EAAE,kBAAkB,EAAE,kBAAkB,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;AACrG,OAAO,EACL,qBAAqB,EACrB,oBAAoB,EACpB,cAAc,EACd,iBAAiB,EACjB,aAAa,EACb,mBAAmB,EACnB,wBAAwB,EACxB,KAAK,aAAa,GACnB,MAAM,wBAAwB,CAAC;AAChC,OAAO,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,mBAAmB,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,gBAAgB,EAAE,aAAa,EAAE,eAAe,EAAE,WAAW,EAAE,MAAM,iBAAiB,CAAC;AAChG,OAAO,EAAE,gBAAgB,EAAE,kBAAkB,EAAE,kBAAkB,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;AACrG,OAAO,EACL,qBAAqB,EACrB,oBAAoB,EACpB,cAAc,EACd,iBAAiB,EACjB,aAAa,EACb,mBAAmB,EACnB,wBAAwB,EACxB,KAAK,aAAa,GACnB,MAAM,wBAAwB,CAAC;AAChC,OAAO,EAAE,gBAAgB,EAAE,eAAe,EAAE,MAAM,2BAA2B,CAAC;AAC9E,OAAO,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,mBAAmB,CAAC"}
package/dist/index.js CHANGED
@@ -2,5 +2,6 @@
2
2
  export { createConnection, getConnection, closeConnection, healthCheck } from './connection.js';
3
3
  export { setTenantContext, clearTenantContext, getCurrentTenantId, enableRLS } from './rls/index.js';
4
4
  export { loadMigrationsFromDir, getAppliedMigrations, applyMigration, rollbackMigration, runMigrations, runPluginMigrations, rollbackPluginMigrations, } from './migrations/runner.js';
5
+ export { ensureCoreSchema, resolveTenantId } from './migrations/bootstrap.js';
5
6
  export { schema, getSchema } from './schema/index.js';
6
7
  //# sourceMappingURL=index.js.map
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,2CAA2C;AAE3C,OAAO,EAAE,gBAAgB,EAAE,aAAa,EAAE,eAAe,EAAE,WAAW,EAAE,MAAM,iBAAiB,CAAC;AAChG,OAAO,EAAE,gBAAgB,EAAE,kBAAkB,EAAE,kBAAkB,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;AACrG,OAAO,EACL,qBAAqB,EACrB,oBAAoB,EACpB,cAAc,EACd,iBAAiB,EACjB,aAAa,EACb,mBAAmB,EACnB,wBAAwB,GAEzB,MAAM,wBAAwB,CAAC;AAChC,OAAO,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,mBAAmB,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,2CAA2C;AAE3C,OAAO,EAAE,gBAAgB,EAAE,aAAa,EAAE,eAAe,EAAE,WAAW,EAAE,MAAM,iBAAiB,CAAC;AAChG,OAAO,EAAE,gBAAgB,EAAE,kBAAkB,EAAE,kBAAkB,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;AACrG,OAAO,EACL,qBAAqB,EACrB,oBAAoB,EACpB,cAAc,EACd,iBAAiB,EACjB,aAAa,EACb,mBAAmB,EACnB,wBAAwB,GAEzB,MAAM,wBAAwB,CAAC;AAChC,OAAO,EAAE,gBAAgB,EAAE,eAAe,EAAE,MAAM,2BAA2B,CAAC;AAC9E,OAAO,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,mBAAmB,CAAC"}
@@ -0,0 +1,14 @@
1
+ /**
2
+ * Aplica o schema core se o banco ainda não foi inicializado.
3
+ * Retorna `true` quando aplicou (banco fresco), `false` se já existia.
4
+ */
5
+ export declare function ensureCoreSchema(): Promise<boolean>;
6
+ /**
7
+ * Resolve o argumento `--tenant` para um UUID:
8
+ * - UUID válido → devolve direto;
9
+ * - slug existente em tenants.slug → devolve o id;
10
+ * - slug "default" inexistente → cria o tenant (bootstrap) e devolve o id;
11
+ * - qualquer outro slug inexistente → erro claro (não cria slug com typo).
12
+ */
13
+ export declare function resolveTenantId(input: string): Promise<string>;
14
+ //# sourceMappingURL=bootstrap.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"bootstrap.d.ts","sourceRoot":"","sources":["../../src/migrations/bootstrap.ts"],"names":[],"mappings":"AAkBA;;;GAGG;AACH,wBAAsB,gBAAgB,IAAI,OAAO,CAAC,OAAO,CAAC,CAkBzD;AAED;;;;;;GAMG;AACH,wBAAsB,eAAe,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAqCpE"}
@@ -0,0 +1,75 @@
1
+ // @oktis-works/database - Bootstrap de banco fresco
2
+ //
3
+ // Um banco novo não tem NADA: nem o schema core (a tabela `migrations` sequer
4
+ // existe — e tem FK para `tenants`), nem o tenant usado pelo CLI. Sem isto,
5
+ // `okcms db:migrate` morria com `relation "migrations" does not exist`.
6
+ //
7
+ // - ensureCoreSchema aplica o schema.sql UMA única vez. A detecção é via
8
+ // to_regclass (não via registro em migrations): o schema tem CREATE POLICY,
9
+ // que não é idempotente, então reexecutar daria erro — e na primeira
10
+ // execução a tabela de controle ainda nem existe para registrar algo.
11
+ // - resolveTenantId traduz o `--tenant` (default: "default") para o UUID real
12
+ // de tenants.slug, criando o tenant default na primeira vez (bootstrap).
13
+ import { getConnection } from '../connection.js';
14
+ import { getSchema } from '../schema/index.js';
15
+ const UUID_RE = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;
16
+ /**
17
+ * Aplica o schema core se o banco ainda não foi inicializado.
18
+ * Retorna `true` quando aplicou (banco fresco), `false` se já existia.
19
+ */
20
+ export async function ensureCoreSchema() {
21
+ const sql = getConnection();
22
+ const probe = await sql `
23
+ SELECT to_regclass('public.tenants')::text AS exists
24
+ `;
25
+ if (probe[0]?.exists) {
26
+ return false;
27
+ }
28
+ await sql.begin(async (tx) => {
29
+ // Só warnings/erros: o schema tem ALTER ... ADD COLUMN IF NOT EXISTS
30
+ // redundantes (a coluna já vem no CREATE TABLE) e o Postgres responde
31
+ // NOTICE 42701 "already exists, skipping" — ruído puro no output do init.
32
+ await tx `SET client_min_messages = warning`;
33
+ await tx.unsafe(getSchema());
34
+ });
35
+ return true;
36
+ }
37
+ /**
38
+ * Resolve o argumento `--tenant` para um UUID:
39
+ * - UUID válido → devolve direto;
40
+ * - slug existente em tenants.slug → devolve o id;
41
+ * - slug "default" inexistente → cria o tenant (bootstrap) e devolve o id;
42
+ * - qualquer outro slug inexistente → erro claro (não cria slug com typo).
43
+ */
44
+ export async function resolveTenantId(input) {
45
+ if (UUID_RE.test(input)) {
46
+ return input;
47
+ }
48
+ const sql = getConnection();
49
+ const found = await sql `
50
+ SELECT id FROM tenants WHERE slug = ${input} LIMIT 1
51
+ `;
52
+ if (found[0]) {
53
+ return found[0].id;
54
+ }
55
+ if (input !== 'default') {
56
+ throw new Error(`Tenant "${input}" não encontrado. Crie-o no admin ou passe um UUID com --tenant.`);
57
+ }
58
+ const created = await sql `
59
+ INSERT INTO tenants (name, slug) VALUES ('Default', 'default')
60
+ ON CONFLICT (slug) DO NOTHING
61
+ RETURNING id
62
+ `;
63
+ if (created[0]) {
64
+ return created[0].id;
65
+ }
66
+ // Corrida: outro processo criou o tenant entre o SELECT e o INSERT.
67
+ const again = await sql `
68
+ SELECT id FROM tenants WHERE slug = ${input} LIMIT 1
69
+ `;
70
+ if (again[0]) {
71
+ return again[0].id;
72
+ }
73
+ throw new Error('Falha ao criar o tenant default');
74
+ }
75
+ //# sourceMappingURL=bootstrap.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"bootstrap.js","sourceRoot":"","sources":["../../src/migrations/bootstrap.ts"],"names":[],"mappings":"AAAA,oDAAoD;AACpD,EAAE;AACF,8EAA8E;AAC9E,4EAA4E;AAC5E,wEAAwE;AACxE,EAAE;AACF,yEAAyE;AACzE,8EAA8E;AAC9E,uEAAuE;AACvE,wEAAwE;AACxE,8EAA8E;AAC9E,2EAA2E;AAE3E,OAAO,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAC;AACjD,OAAO,EAAE,SAAS,EAAE,MAAM,oBAAoB,CAAC;AAE/C,MAAM,OAAO,GAAG,iEAAiE,CAAC;AAElF;;;GAGG;AACH,MAAM,CAAC,KAAK,UAAU,gBAAgB;IACpC,MAAM,GAAG,GAAG,aAAa,EAAE,CAAC;IAE5B,MAAM,KAAK,GAAG,MAAM,GAAG,CAA6B;;GAEnD,CAAC;IACF,IAAI,KAAK,CAAC,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC;QACrB,OAAO,KAAK,CAAC;IACf,CAAC;IAED,MAAM,GAAG,CAAC,KAAK,CAAC,KAAK,EAAE,EAAE,EAAE,EAAE;QAC3B,qEAAqE;QACrE,sEAAsE;QACtE,0EAA0E;QAC1E,MAAM,EAAE,CAAA,mCAAmC,CAAC;QAC5C,MAAM,EAAE,CAAC,MAAM,CAAC,SAAS,EAAE,CAAC,CAAC;IAC/B,CAAC,CAAC,CAAC;IACH,OAAO,IAAI,CAAC;AACd,CAAC;AAED;;;;;;GAMG;AACH,MAAM,CAAC,KAAK,UAAU,eAAe,CAAC,KAAa;IACjD,IAAI,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC;QACxB,OAAO,KAAK,CAAC;IACf,CAAC;IAED,MAAM,GAAG,GAAG,aAAa,EAAE,CAAC;IAE5B,MAAM,KAAK,GAAG,MAAM,GAAG,CAAkB;0CACD,KAAK;GAC5C,CAAC;IACF,IAAI,KAAK,CAAC,CAAC,CAAC,EAAE,CAAC;QACb,OAAO,KAAK,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;IACrB,CAAC;IAED,IAAI,KAAK,KAAK,SAAS,EAAE,CAAC;QACxB,MAAM,IAAI,KAAK,CACb,WAAW,KAAK,kEAAkE,CACnF,CAAC;IACJ,CAAC;IAED,MAAM,OAAO,GAAG,MAAM,GAAG,CAAkB;;;;GAI1C,CAAC;IACF,IAAI,OAAO,CAAC,CAAC,CAAC,EAAE,CAAC;QACf,OAAO,OAAO,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;IACvB,CAAC;IAED,oEAAoE;IACpE,MAAM,KAAK,GAAG,MAAM,GAAG,CAAkB;0CACD,KAAK;GAC5C,CAAC;IACF,IAAI,KAAK,CAAC,CAAC,CAAC,EAAE,CAAC;QACb,OAAO,KAAK,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;IACrB,CAAC;IACD,MAAM,IAAI,KAAK,CAAC,iCAAiC,CAAC,CAAC;AACrD,CAAC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@oktis-works/database",
3
- "version": "0.1.8",
3
+ "version": "0.1.9",
4
4
  "private": false,
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
@@ -19,8 +19,8 @@
19
19
  "db:rollback": "node --loader ts-node/esm src/migrations/runner.ts rollback"
20
20
  },
21
21
  "dependencies": {
22
- "@oktis-works/types": "0.1.8",
23
- "@oktis-works/config": "0.1.8",
22
+ "@oktis-works/types": "0.1.9",
23
+ "@oktis-works/config": "0.1.9",
24
24
  "postgres": "3.4.0"
25
25
  },
26
26
  "devDependencies": {