@mybuildex/pkg 0.2.1 → 0.3.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.
@@ -2,6 +2,15 @@ export interface FirebaseAdminOptions {
2
2
  /** Caminho do arquivo de service account para dev local (fallback:
3
3
  * env FIREBASE_CREDENTIALS_FILE). Ignorado quando ADC está disponível. */
4
4
  credentialsFile?: string;
5
+ /** Bucket default do admin.storage() (ex: magazines usa para upload de
6
+ * páginas). Fallback: env STORAGEBUCKET quando getBucket() é usado. */
7
+ storageBucket?: string;
5
8
  }
6
9
  export declare function initFirebaseAdmin(options?: FirebaseAdminOptions): any;
10
+ /** Auth default (sem tenant) — para APIs single-tenant como o core:
11
+ * createAuthMiddleware({tenantAware: false, getTenantAuth: () => getDefaultAuth()}) */
12
+ export declare function getDefaultAuth(): any;
13
+ /** Bucket default do admin.storage() (requer storageBucket na init ou env
14
+ * STORAGEBUCKET) — magazines usa para upload de páginas de revista. */
15
+ export declare function getBucket(): any;
7
16
  export declare function getTenantAuth(tenantId: string | undefined): any;
@@ -5,6 +5,8 @@
5
5
  // NUNCA embute credencial. `firebase-admin` é peer dep.
6
6
  Object.defineProperty(exports, "__esModule", { value: true });
7
7
  exports.initFirebaseAdmin = initFirebaseAdmin;
8
+ exports.getDefaultAuth = getDefaultAuth;
9
+ exports.getBucket = getBucket;
8
10
  exports.getTenantAuth = getTenantAuth;
9
11
  let adminInstance = null;
10
12
  function initFirebaseAdmin(options = {}) {
@@ -15,8 +17,10 @@ function initFirebaseAdmin(options = {}) {
15
17
  if (!admin.apps.length) {
16
18
  const useADC = process.env.USE_ADC === "true" ||
17
19
  !!process.env.GOOGLE_APPLICATION_CREDENTIALS;
20
+ const storageBucket = options.storageBucket || process.env.STORAGEBUCKET;
21
+ const base = storageBucket ? { storageBucket } : {};
18
22
  if (useADC) {
19
- admin.initializeApp(); // ADC: credencial do ambiente
23
+ admin.initializeApp(base); // ADC: credencial do ambiente
20
24
  }
21
25
  else {
22
26
  const file = options.credentialsFile || process.env.FIREBASE_CREDENTIALS_FILE;
@@ -24,17 +28,27 @@ function initFirebaseAdmin(options = {}) {
24
28
  // Sem ADC e sem arquivo: inicializa via ADC mesmo assim — em
25
29
  // ambientes GCP funciona; fora, falha alto na primeira chamada
26
30
  // (melhor que embutir credencial).
27
- admin.initializeApp();
31
+ admin.initializeApp(base);
28
32
  }
29
33
  else {
30
34
  const serviceAccount = require(file);
31
- admin.initializeApp({ credential: admin.credential.cert(serviceAccount) });
35
+ admin.initializeApp({ ...base, credential: admin.credential.cert(serviceAccount) });
32
36
  }
33
37
  }
34
38
  }
35
39
  adminInstance = admin;
36
40
  return admin;
37
41
  }
42
+ /** Auth default (sem tenant) — para APIs single-tenant como o core:
43
+ * createAuthMiddleware({tenantAware: false, getTenantAuth: () => getDefaultAuth()}) */
44
+ function getDefaultAuth() {
45
+ return initFirebaseAdmin().auth();
46
+ }
47
+ /** Bucket default do admin.storage() (requer storageBucket na init ou env
48
+ * STORAGEBUCKET) — magazines usa para upload de páginas de revista. */
49
+ function getBucket() {
50
+ return initFirebaseAdmin().storage().bucket();
51
+ }
38
52
  // --- helper multi-tenant cacheado (Firebase Auth: 1 tenant por escola) ---
39
53
  const tenantAuthCache = new Map();
40
54
  function getTenantAuth(tenantId) {
@@ -1 +1 @@
1
- {"version":3,"file":"admin.js","sourceRoot":"","sources":["../../src/firebase/admin.ts"],"names":[],"mappings":";AAAA,4EAA4E;AAC5E,4EAA4E;AAC5E,6EAA6E;AAC7E,wDAAwD;;AAUxD,8CA2BC;AAKD,sCAQC;AAhDD,IAAI,aAAa,GAAQ,IAAI,CAAC;AAQ9B,SAAgB,iBAAiB,CAAC,UAAgC,EAAE;IAChE,IAAI,aAAa;QAAE,OAAO,aAAa,CAAC;IACxC,uDAAuD;IACvD,MAAM,KAAK,GAAG,OAAO,CAAC,gBAAgB,CAAC,CAAC;IAExC,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,MAAM,EAAE,CAAC;QACrB,MAAM,MAAM,GACR,OAAO,CAAC,GAAG,CAAC,OAAO,KAAK,MAAM;YAC9B,CAAC,CAAC,OAAO,CAAC,GAAG,CAAC,8BAA8B,CAAC;QAEjD,IAAI,MAAM,EAAE,CAAC;YACT,KAAK,CAAC,aAAa,EAAE,CAAC,CAAC,8BAA8B;QACzD,CAAC;aAAM,CAAC;YACJ,MAAM,IAAI,GAAG,OAAO,CAAC,eAAe,IAAI,OAAO,CAAC,GAAG,CAAC,yBAAyB,CAAC;YAC9E,IAAI,CAAC,IAAI,EAAE,CAAC;gBACR,6DAA6D;gBAC7D,+DAA+D;gBAC/D,mCAAmC;gBACnC,KAAK,CAAC,aAAa,EAAE,CAAC;YAC1B,CAAC;iBAAM,CAAC;gBACJ,MAAM,cAAc,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;gBACrC,KAAK,CAAC,aAAa,CAAC,EAAC,UAAU,EAAE,KAAK,CAAC,UAAU,CAAC,IAAI,CAAC,cAAc,CAAC,EAAC,CAAC,CAAC;YAC7E,CAAC;QACL,CAAC;IACL,CAAC;IACD,aAAa,GAAG,KAAK,CAAC;IACtB,OAAO,KAAK,CAAC;AACjB,CAAC;AAED,4EAA4E;AAC5E,MAAM,eAAe,GAAG,IAAI,GAAG,EAAe,CAAC;AAE/C,SAAgB,aAAa,CAAC,QAA4B;IACtD,IAAI,CAAC,QAAQ;QAAE,MAAM,IAAI,KAAK,CAAC,oCAAoC,CAAC,CAAC;IACrE,IAAI,CAAC,GAAG,eAAe,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC;IACtC,IAAI,CAAC,CAAC,EAAE,CAAC;QACL,CAAC,GAAG,iBAAiB,EAAE,CAAC,IAAI,EAAE,CAAC,aAAa,EAAE,CAAC,aAAa,CAAC,QAAQ,CAAC,CAAC;QACvE,eAAe,CAAC,GAAG,CAAC,QAAQ,EAAE,CAAC,CAAC,CAAC;IACrC,CAAC;IACD,OAAO,CAAC,CAAC;AACb,CAAC"}
1
+ {"version":3,"file":"admin.js","sourceRoot":"","sources":["../../src/firebase/admin.ts"],"names":[],"mappings":";AAAA,4EAA4E;AAC5E,4EAA4E;AAC5E,6EAA6E;AAC7E,wDAAwD;;AAaxD,8CA8BC;AAID,wCAEC;AAID,8BAEC;AAKD,sCAQC;AAlED,IAAI,aAAa,GAAQ,IAAI,CAAC;AAW9B,SAAgB,iBAAiB,CAAC,UAAgC,EAAE;IAChE,IAAI,aAAa;QAAE,OAAO,aAAa,CAAC;IACxC,uDAAuD;IACvD,MAAM,KAAK,GAAG,OAAO,CAAC,gBAAgB,CAAC,CAAC;IAExC,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,MAAM,EAAE,CAAC;QACrB,MAAM,MAAM,GACR,OAAO,CAAC,GAAG,CAAC,OAAO,KAAK,MAAM;YAC9B,CAAC,CAAC,OAAO,CAAC,GAAG,CAAC,8BAA8B,CAAC;QAEjD,MAAM,aAAa,GAAG,OAAO,CAAC,aAAa,IAAI,OAAO,CAAC,GAAG,CAAC,aAAa,CAAC;QACzE,MAAM,IAAI,GAAG,aAAa,CAAC,CAAC,CAAC,EAAC,aAAa,EAAC,CAAC,CAAC,CAAC,EAAE,CAAC;QAElD,IAAI,MAAM,EAAE,CAAC;YACT,KAAK,CAAC,aAAa,CAAC,IAAI,CAAC,CAAC,CAAC,8BAA8B;QAC7D,CAAC;aAAM,CAAC;YACJ,MAAM,IAAI,GAAG,OAAO,CAAC,eAAe,IAAI,OAAO,CAAC,GAAG,CAAC,yBAAyB,CAAC;YAC9E,IAAI,CAAC,IAAI,EAAE,CAAC;gBACR,6DAA6D;gBAC7D,+DAA+D;gBAC/D,mCAAmC;gBACnC,KAAK,CAAC,aAAa,CAAC,IAAI,CAAC,CAAC;YAC9B,CAAC;iBAAM,CAAC;gBACJ,MAAM,cAAc,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;gBACrC,KAAK,CAAC,aAAa,CAAC,EAAC,GAAG,IAAI,EAAE,UAAU,EAAE,KAAK,CAAC,UAAU,CAAC,IAAI,CAAC,cAAc,CAAC,EAAC,CAAC,CAAC;YACtF,CAAC;QACL,CAAC;IACL,CAAC;IACD,aAAa,GAAG,KAAK,CAAC;IACtB,OAAO,KAAK,CAAC;AACjB,CAAC;AAED;wFACwF;AACxF,SAAgB,cAAc;IAC1B,OAAO,iBAAiB,EAAE,CAAC,IAAI,EAAE,CAAC;AACtC,CAAC;AAED;wEACwE;AACxE,SAAgB,SAAS;IACrB,OAAO,iBAAiB,EAAE,CAAC,OAAO,EAAE,CAAC,MAAM,EAAE,CAAC;AAClD,CAAC;AAED,4EAA4E;AAC5E,MAAM,eAAe,GAAG,IAAI,GAAG,EAAe,CAAC;AAE/C,SAAgB,aAAa,CAAC,QAA4B;IACtD,IAAI,CAAC,QAAQ;QAAE,MAAM,IAAI,KAAK,CAAC,oCAAoC,CAAC,CAAC;IACrE,IAAI,CAAC,GAAG,eAAe,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC;IACtC,IAAI,CAAC,CAAC,EAAE,CAAC;QACL,CAAC,GAAG,iBAAiB,EAAE,CAAC,IAAI,EAAE,CAAC,aAAa,EAAE,CAAC,aAAa,CAAC,QAAQ,CAAC,CAAC;QACvE,eAAe,CAAC,GAAG,CAAC,QAAQ,EAAE,CAAC,CAAC,CAAC;IACrC,CAAC;IACD,OAAO,CAAC,CAAC;AACb,CAAC"}
@@ -1,5 +1,13 @@
1
1
  export interface FirebaseClientPluginOptions {
2
2
  initializeApp?: (config: any) => any;
3
3
  getStorage?: (app: any) => any;
4
+ /** Decorators extras além de firebase/storage (ex: acls/payments decoram
5
+ * authfirebase, firebasep, services próprios). */
6
+ decorate?: (fastify: any, ctx: {
7
+ app: any;
8
+ storage: any;
9
+ }) => void | Promise<void>;
4
10
  }
11
+ export declare function getFirebaseClientApp(): any;
12
+ export declare function getFirebaseStorage(): any;
5
13
  export declare function createFirebaseClientPlugin(options?: FirebaseClientPluginOptions): (fastify: any) => Promise<void>;
@@ -2,14 +2,22 @@
2
2
  // Firebase CLIENT SDK (storage) das APIs. Config 100% via env — as chaves de
3
3
  // client do Firebase (apiKey etc.) não são segredo, mas nada fica hardcoded.
4
4
  // `firebase` é peer dep; injeção opcional dos módulos para teste.
5
+ //
6
+ // getFirebaseStorage()/getFirebaseClientApp(): uso STANDALONE (fora do
7
+ // Fastify) — ex: worker Pub/Sub do templates. Singleton compartilhado com o
8
+ // plugin (uma instância só por processo).
5
9
  Object.defineProperty(exports, "__esModule", { value: true });
10
+ exports.getFirebaseClientApp = getFirebaseClientApp;
11
+ exports.getFirebaseStorage = getFirebaseStorage;
6
12
  exports.createFirebaseClientPlugin = createFirebaseClientPlugin;
7
- function createFirebaseClientPlugin(options = {}) {
8
- return async function pluginFirebase(fastify) {
9
- /* eslint-disable @typescript-eslint/no-var-requires */
10
- const initializeApp = options.initializeApp ?? require("firebase/app").initializeApp;
11
- const getStorage = options.getStorage ?? require("firebase/storage").getStorage;
12
- const firebaseConfig = {
13
+ let clientApp = null;
14
+ let clientStorage = null;
15
+ /* eslint-disable @typescript-eslint/no-var-requires */
16
+ function initClient(inject = {}) {
17
+ if (!clientApp) {
18
+ const initializeApp = inject.initializeApp ?? require("firebase/app").initializeApp;
19
+ const getStorage = inject.getStorage ?? require("firebase/storage").getStorage;
20
+ clientApp = initializeApp({
13
21
  apiKey: process.env.APIKEY,
14
22
  authDomain: process.env.AUTHDOMAIN,
15
23
  projectId: process.env.PROJECTID,
@@ -17,11 +25,24 @@ function createFirebaseClientPlugin(options = {}) {
17
25
  messagingSenderId: process.env.MESSAGINGSENDERID,
18
26
  appId: process.env.APPID,
19
27
  measurementId: process.env.MEASUREMENTID,
20
- };
21
- const appFirebase = initializeApp(firebaseConfig);
22
- const storageFirebase = getStorage(appFirebase);
23
- fastify.decorate("firebase", appFirebase);
24
- fastify.decorate("storage", storageFirebase);
28
+ });
29
+ clientStorage = getStorage(clientApp);
30
+ }
31
+ return { app: clientApp, storage: clientStorage };
32
+ }
33
+ function getFirebaseClientApp() {
34
+ return initClient().app;
35
+ }
36
+ function getFirebaseStorage() {
37
+ return initClient().storage;
38
+ }
39
+ function createFirebaseClientPlugin(options = {}) {
40
+ return async function pluginFirebase(fastify) {
41
+ const { app, storage } = initClient(options);
42
+ fastify.decorate("firebase", app);
43
+ fastify.decorate("storage", storage);
44
+ if (options.decorate)
45
+ await options.decorate(fastify, { app, storage });
25
46
  };
26
47
  }
27
48
  //# sourceMappingURL=client-plugin.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"client-plugin.js","sourceRoot":"","sources":["../../src/firebase/client-plugin.ts"],"names":[],"mappings":";AAAA,6EAA6E;AAC7E,6EAA6E;AAC7E,kEAAkE;;AAOlE,gEAoBC;AApBD,SAAgB,0BAA0B,CAAC,UAAuC,EAAE;IAChF,OAAO,KAAK,UAAU,cAAc,CAAC,OAAY;QAC7C,uDAAuD;QACvD,MAAM,aAAa,GAAG,OAAO,CAAC,aAAa,IAAI,OAAO,CAAC,cAAc,CAAC,CAAC,aAAa,CAAC;QACrF,MAAM,UAAU,GAAG,OAAO,CAAC,UAAU,IAAI,OAAO,CAAC,kBAAkB,CAAC,CAAC,UAAU,CAAC;QAEhF,MAAM,cAAc,GAAG;YACnB,MAAM,EAAE,OAAO,CAAC,GAAG,CAAC,MAAM;YAC1B,UAAU,EAAE,OAAO,CAAC,GAAG,CAAC,UAAU;YAClC,SAAS,EAAE,OAAO,CAAC,GAAG,CAAC,SAAS;YAChC,aAAa,EAAE,OAAO,CAAC,GAAG,CAAC,aAAa;YACxC,iBAAiB,EAAE,OAAO,CAAC,GAAG,CAAC,iBAAiB;YAChD,KAAK,EAAE,OAAO,CAAC,GAAG,CAAC,KAAK;YACxB,aAAa,EAAE,OAAO,CAAC,GAAG,CAAC,aAAa;SAC3C,CAAC;QACF,MAAM,WAAW,GAAG,aAAa,CAAC,cAAc,CAAC,CAAC;QAClD,MAAM,eAAe,GAAG,UAAU,CAAC,WAAW,CAAC,CAAC;QAChD,OAAO,CAAC,QAAQ,CAAC,UAAU,EAAE,WAAW,CAAC,CAAC;QAC1C,OAAO,CAAC,QAAQ,CAAC,SAAS,EAAE,eAAe,CAAC,CAAC;IACjD,CAAC,CAAC;AACN,CAAC"}
1
+ {"version":3,"file":"client-plugin.js","sourceRoot":"","sources":["../../src/firebase/client-plugin.ts"],"names":[],"mappings":";AAAA,6EAA6E;AAC7E,6EAA6E;AAC7E,kEAAkE;AAClE,EAAE;AACF,uEAAuE;AACvE,4EAA4E;AAC5E,0CAA0C;;AAgC1C,oDAEC;AAED,gDAEC;AAED,gEAOC;AArCD,IAAI,SAAS,GAAQ,IAAI,CAAC;AAC1B,IAAI,aAAa,GAAQ,IAAI,CAAC;AAE9B,uDAAuD;AACvD,SAAS,UAAU,CAAC,SAAsC,EAAE;IACxD,IAAI,CAAC,SAAS,EAAE,CAAC;QACb,MAAM,aAAa,GAAG,MAAM,CAAC,aAAa,IAAI,OAAO,CAAC,cAAc,CAAC,CAAC,aAAa,CAAC;QACpF,MAAM,UAAU,GAAG,MAAM,CAAC,UAAU,IAAI,OAAO,CAAC,kBAAkB,CAAC,CAAC,UAAU,CAAC;QAC/E,SAAS,GAAG,aAAa,CAAC;YACtB,MAAM,EAAE,OAAO,CAAC,GAAG,CAAC,MAAM;YAC1B,UAAU,EAAE,OAAO,CAAC,GAAG,CAAC,UAAU;YAClC,SAAS,EAAE,OAAO,CAAC,GAAG,CAAC,SAAS;YAChC,aAAa,EAAE,OAAO,CAAC,GAAG,CAAC,aAAa;YACxC,iBAAiB,EAAE,OAAO,CAAC,GAAG,CAAC,iBAAiB;YAChD,KAAK,EAAE,OAAO,CAAC,GAAG,CAAC,KAAK;YACxB,aAAa,EAAE,OAAO,CAAC,GAAG,CAAC,aAAa;SAC3C,CAAC,CAAC;QACH,aAAa,GAAG,UAAU,CAAC,SAAS,CAAC,CAAC;IAC1C,CAAC;IACD,OAAO,EAAC,GAAG,EAAE,SAAS,EAAE,OAAO,EAAE,aAAa,EAAC,CAAC;AACpD,CAAC;AAED,SAAgB,oBAAoB;IAChC,OAAO,UAAU,EAAE,CAAC,GAAG,CAAC;AAC5B,CAAC;AAED,SAAgB,kBAAkB;IAC9B,OAAO,UAAU,EAAE,CAAC,OAAO,CAAC;AAChC,CAAC;AAED,SAAgB,0BAA0B,CAAC,UAAuC,EAAE;IAChF,OAAO,KAAK,UAAU,cAAc,CAAC,OAAY;QAC7C,MAAM,EAAC,GAAG,EAAE,OAAO,EAAC,GAAG,UAAU,CAAC,OAAO,CAAC,CAAC;QAC3C,OAAO,CAAC,QAAQ,CAAC,UAAU,EAAE,GAAG,CAAC,CAAC;QAClC,OAAO,CAAC,QAAQ,CAAC,SAAS,EAAE,OAAO,CAAC,CAAC;QACrC,IAAI,OAAO,CAAC,QAAQ;YAAE,MAAM,OAAO,CAAC,QAAQ,CAAC,OAAO,EAAE,EAAC,GAAG,EAAE,OAAO,EAAC,CAAC,CAAC;IAC1E,CAAC,CAAC;AACN,CAAC"}
@@ -3,6 +3,8 @@ export interface ErrorHandlerOptions {
3
3
  genericMessage?: string;
4
4
  /** Força expor mensagens cruas (ex: dev local). Default: false */
5
5
  exposeInternal?: boolean;
6
+ /** Mensagens por código Prisma (P2002 etc). String fixa ou função(error). */
7
+ prismaMessages?: Record<string, string | ((error: any) => string)>;
6
8
  }
7
9
  export declare function isInternalError(error: any): boolean;
8
10
  export declare function createErrorHandler(options?: ErrorHandlerOptions): (fastify: any) => Promise<void>;
@@ -3,6 +3,11 @@
3
3
  // infra (Prisma/banco/rede) NUNCA chegam ao cliente com a mensagem crua —
4
4
  // "Can't reach database server at /cloudsql/..." no browser do aluno é
5
5
  // exposição de infraestrutura. Log completo sempre; resposta sanitizada.
6
+ //
7
+ // - Preserva error.statusCode quando presente (ex: GuardError 403 do post);
8
+ // sem statusCode, mantém o 400 histórico das APIs.
9
+ // - prismaMessages: mapa código Prisma -> mensagem amigável (ex: P2002 ->
10
+ // "Registro duplicado") — a mensagem mapeada é exposta mesmo sendo Prisma.
6
11
  Object.defineProperty(exports, "__esModule", { value: true });
7
12
  exports.isInternalError = isInternalError;
8
13
  exports.createErrorHandler = createErrorHandler;
@@ -22,11 +27,20 @@ function createErrorHandler(options = {}) {
22
27
  return async function onErrorMiddleware(fastify) {
23
28
  fastify.setErrorHandler(async (error, request, reply) => {
24
29
  console.error(error);
25
- const expose = options.exposeInternal || !isInternalError(error);
26
- reply.code(400).send({
27
- statusCode: 400,
28
- message: expose ? error.message : generic,
29
- });
30
+ const status = Number(error?.statusCode) || 400;
31
+ const code = typeof error?.code === "string" ? error.code : "";
32
+ const mapped = code ? options.prismaMessages?.[code] : undefined;
33
+ let message;
34
+ if (mapped !== undefined) {
35
+ message = typeof mapped === "function" ? mapped(error) : mapped;
36
+ }
37
+ else if (options.exposeInternal || !isInternalError(error)) {
38
+ message = error.message;
39
+ }
40
+ else {
41
+ message = generic;
42
+ }
43
+ reply.code(status).send({ statusCode: status, message });
30
44
  });
31
45
  };
32
46
  }
@@ -1 +1 @@
1
- {"version":3,"file":"error-handler.js","sourceRoot":"","sources":["../../src/http/error-handler.ts"],"names":[],"mappings":";AAAA,4EAA4E;AAC5E,0EAA0E;AAC1E,uEAAuE;AACvE,yEAAyE;;AAYzE,0CAKC;AAED,gDAYC;AAtBD,yEAAyE;AACzE,MAAM,iBAAiB,GAAG,mHAAmH,CAAC;AAE9I,SAAgB,eAAe,CAAC,KAAU;IACtC,IAAI,KAAK,EAAE,IAAI,EAAE,UAAU,EAAE,CAAC,cAAc,CAAC;QAAE,OAAO,IAAI,CAAC;IAC3D,IAAI,OAAO,KAAK,EAAE,IAAI,KAAK,QAAQ,IAAI,UAAU,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC;QAAE,OAAO,IAAI,CAAC;IAChF,IAAI,CAAC,KAAK,EAAE,UAAU,IAAI,CAAC,CAAC,IAAI,GAAG;QAAE,OAAO,IAAI,CAAC;IACjD,OAAO,iBAAiB,CAAC,IAAI,CAAC,MAAM,CAAC,KAAK,EAAE,OAAO,IAAI,EAAE,CAAC,CAAC,CAAC;AAChE,CAAC;AAED,SAAgB,kBAAkB,CAAC,UAA+B,EAAE;IAChE,MAAM,OAAO,GAAG,OAAO,CAAC,cAAc,IAAI,+BAA+B,CAAC;IAC1E,OAAO,KAAK,UAAU,iBAAiB,CAAC,OAAY;QAChD,OAAO,CAAC,eAAe,CAAC,KAAK,EAAE,KAAU,EAAE,OAAY,EAAE,KAAU,EAAE,EAAE;YACnE,OAAO,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;YACrB,MAAM,MAAM,GAAG,OAAO,CAAC,cAAc,IAAI,CAAC,eAAe,CAAC,KAAK,CAAC,CAAC;YACjE,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC;gBACjB,UAAU,EAAE,GAAG;gBACf,OAAO,EAAE,MAAM,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,OAAO;aAC5C,CAAC,CAAC;QACP,CAAC,CAAC,CAAC;IACP,CAAC,CAAC;AACN,CAAC"}
1
+ {"version":3,"file":"error-handler.js","sourceRoot":"","sources":["../../src/http/error-handler.ts"],"names":[],"mappings":";AAAA,4EAA4E;AAC5E,0EAA0E;AAC1E,uEAAuE;AACvE,yEAAyE;AACzE,EAAE;AACF,4EAA4E;AAC5E,qDAAqD;AACrD,0EAA0E;AAC1E,6EAA6E;;AAc7E,0CAKC;AAED,gDAsBC;AAhCD,yEAAyE;AACzE,MAAM,iBAAiB,GAAG,mHAAmH,CAAC;AAE9I,SAAgB,eAAe,CAAC,KAAU;IACtC,IAAI,KAAK,EAAE,IAAI,EAAE,UAAU,EAAE,CAAC,cAAc,CAAC;QAAE,OAAO,IAAI,CAAC;IAC3D,IAAI,OAAO,KAAK,EAAE,IAAI,KAAK,QAAQ,IAAI,UAAU,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC;QAAE,OAAO,IAAI,CAAC;IAChF,IAAI,CAAC,KAAK,EAAE,UAAU,IAAI,CAAC,CAAC,IAAI,GAAG;QAAE,OAAO,IAAI,CAAC;IACjD,OAAO,iBAAiB,CAAC,IAAI,CAAC,MAAM,CAAC,KAAK,EAAE,OAAO,IAAI,EAAE,CAAC,CAAC,CAAC;AAChE,CAAC;AAED,SAAgB,kBAAkB,CAAC,UAA+B,EAAE;IAChE,MAAM,OAAO,GAAG,OAAO,CAAC,cAAc,IAAI,+BAA+B,CAAC;IAC1E,OAAO,KAAK,UAAU,iBAAiB,CAAC,OAAY;QAChD,OAAO,CAAC,eAAe,CAAC,KAAK,EAAE,KAAU,EAAE,OAAY,EAAE,KAAU,EAAE,EAAE;YACnE,OAAO,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;YAErB,MAAM,MAAM,GAAG,MAAM,CAAC,KAAK,EAAE,UAAU,CAAC,IAAI,GAAG,CAAC;YAEhD,MAAM,IAAI,GAAG,OAAO,KAAK,EAAE,IAAI,KAAK,QAAQ,CAAC,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC;YAC/D,MAAM,MAAM,GAAG,IAAI,CAAC,CAAC,CAAC,OAAO,CAAC,cAAc,EAAE,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC;YACjE,IAAI,OAAe,CAAC;YACpB,IAAI,MAAM,KAAK,SAAS,EAAE,CAAC;gBACvB,OAAO,GAAG,OAAO,MAAM,KAAK,UAAU,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC;YACpE,CAAC;iBAAM,IAAI,OAAO,CAAC,cAAc,IAAI,CAAC,eAAe,CAAC,KAAK,CAAC,EAAE,CAAC;gBAC3D,OAAO,GAAG,KAAK,CAAC,OAAO,CAAC;YAC5B,CAAC;iBAAM,CAAC;gBACJ,OAAO,GAAG,OAAO,CAAC;YACtB,CAAC;YAED,KAAK,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,EAAC,UAAU,EAAE,MAAM,EAAE,OAAO,EAAC,CAAC,CAAC;QAC3D,CAAC,CAAC,CAAC;IACP,CAAC,CAAC;AACN,CAAC"}
package/dist/index.d.ts CHANGED
@@ -12,9 +12,9 @@ export { createCorsPlugin, DEFAULT_CORS } from "./cors/plugin";
12
12
  export type { CorsOptions } from "./cors/plugin";
13
13
  export { createSwaggerPlugin } from "./swagger/plugin";
14
14
  export type { SwaggerPluginOptions } from "./swagger/plugin";
15
- export { createFirebaseClientPlugin } from "./firebase/client-plugin";
15
+ export { createFirebaseClientPlugin, getFirebaseClientApp, getFirebaseStorage } from "./firebase/client-plugin";
16
16
  export type { FirebaseClientPluginOptions } from "./firebase/client-plugin";
17
- export { initFirebaseAdmin, getTenantAuth } from "./firebase/admin";
17
+ export { initFirebaseAdmin, getTenantAuth, getDefaultAuth, getBucket } from "./firebase/admin";
18
18
  export type { FirebaseAdminOptions } from "./firebase/admin";
19
19
  export { createErrorHandler, isInternalError } from "./http/error-handler";
20
20
  export type { ErrorHandlerOptions } from "./http/error-handler";
package/dist/index.js CHANGED
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.EMBED_MODEL = exports.GEMINI_MODEL = exports.EMBED_DIM = exports.GeminiHelp = exports.isInternalError = exports.createErrorHandler = exports.getTenantAuth = exports.initFirebaseAdmin = exports.createFirebaseClientPlugin = exports.createSwaggerPlugin = exports.DEFAULT_CORS = exports.createCorsPlugin = exports.createMultitenantPrismaMariaDb = exports.createMultitenantPrisma = exports.createAuthMiddleware = exports.createTenantMiddleware = exports.resolveTenantId = void 0;
3
+ exports.EMBED_MODEL = exports.GEMINI_MODEL = exports.EMBED_DIM = exports.GeminiHelp = exports.isInternalError = exports.createErrorHandler = exports.getBucket = exports.getDefaultAuth = exports.getTenantAuth = exports.initFirebaseAdmin = exports.getFirebaseStorage = exports.getFirebaseClientApp = exports.createFirebaseClientPlugin = exports.createSwaggerPlugin = exports.DEFAULT_CORS = exports.createCorsPlugin = exports.createMultitenantPrismaMariaDb = exports.createMultitenantPrisma = exports.createAuthMiddleware = exports.createTenantMiddleware = exports.resolveTenantId = void 0;
4
4
  var resolve_1 = require("./tenant/resolve");
5
5
  Object.defineProperty(exports, "resolveTenantId", { enumerable: true, get: function () { return resolve_1.resolveTenantId; } });
6
6
  var middleware_1 = require("./tenant/middleware");
@@ -18,9 +18,13 @@ var plugin_2 = require("./swagger/plugin");
18
18
  Object.defineProperty(exports, "createSwaggerPlugin", { enumerable: true, get: function () { return plugin_2.createSwaggerPlugin; } });
19
19
  var client_plugin_1 = require("./firebase/client-plugin");
20
20
  Object.defineProperty(exports, "createFirebaseClientPlugin", { enumerable: true, get: function () { return client_plugin_1.createFirebaseClientPlugin; } });
21
+ Object.defineProperty(exports, "getFirebaseClientApp", { enumerable: true, get: function () { return client_plugin_1.getFirebaseClientApp; } });
22
+ Object.defineProperty(exports, "getFirebaseStorage", { enumerable: true, get: function () { return client_plugin_1.getFirebaseStorage; } });
21
23
  var admin_1 = require("./firebase/admin");
22
24
  Object.defineProperty(exports, "initFirebaseAdmin", { enumerable: true, get: function () { return admin_1.initFirebaseAdmin; } });
23
25
  Object.defineProperty(exports, "getTenantAuth", { enumerable: true, get: function () { return admin_1.getTenantAuth; } });
26
+ Object.defineProperty(exports, "getDefaultAuth", { enumerable: true, get: function () { return admin_1.getDefaultAuth; } });
27
+ Object.defineProperty(exports, "getBucket", { enumerable: true, get: function () { return admin_1.getBucket; } });
24
28
  var error_handler_1 = require("./http/error-handler");
25
29
  Object.defineProperty(exports, "createErrorHandler", { enumerable: true, get: function () { return error_handler_1.createErrorHandler; } });
26
30
  Object.defineProperty(exports, "isInternalError", { enumerable: true, get: function () { return error_handler_1.isInternalError; } });
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";;;AAAA,4CAAiD;AAAzC,0GAAA,eAAe,OAAA;AAGvB,kDAA2D;AAAnD,oHAAA,sBAAsB,OAAA;AAG9B,sCAAmD;AAA3C,4GAAA,oBAAoB,OAAA;AAG5B,oDAA6D;AAArD,sHAAA,uBAAuB,OAAA;AAC/B,4DAAwE;AAAhE,iIAAA,8BAA8B,OAAA;AAUtC,wCAA6D;AAArD,0GAAA,gBAAgB,OAAA;AAAE,sGAAA,YAAY,OAAA;AAGtC,2CAAqD;AAA7C,6GAAA,mBAAmB,OAAA;AAG3B,0DAAoE;AAA5D,2HAAA,0BAA0B,OAAA;AAGlC,0CAAkE;AAA1D,0GAAA,iBAAiB,OAAA;AAAE,sGAAA,aAAa,OAAA;AAGxC,sDAAyE;AAAjE,mHAAA,kBAAkB,OAAA;AAAE,gHAAA,eAAe,OAAA;AAG3C,sCAA6E;AAArE,oGAAA,UAAU,OAAA;AAAE,mGAAA,SAAS,OAAA;AAAE,sGAAA,YAAY,OAAA;AAAE,qGAAA,WAAW,OAAA"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";;;AAAA,4CAAiD;AAAzC,0GAAA,eAAe,OAAA;AAGvB,kDAA2D;AAAnD,oHAAA,sBAAsB,OAAA;AAG9B,sCAAmD;AAA3C,4GAAA,oBAAoB,OAAA;AAG5B,oDAA6D;AAArD,sHAAA,uBAAuB,OAAA;AAC/B,4DAAwE;AAAhE,iIAAA,8BAA8B,OAAA;AAUtC,wCAA6D;AAArD,0GAAA,gBAAgB,OAAA;AAAE,sGAAA,YAAY,OAAA;AAGtC,2CAAqD;AAA7C,6GAAA,mBAAmB,OAAA;AAG3B,0DAA8G;AAAtG,2HAAA,0BAA0B,OAAA;AAAE,qHAAA,oBAAoB,OAAA;AAAE,mHAAA,kBAAkB,OAAA;AAG5E,0CAA6F;AAArF,0GAAA,iBAAiB,OAAA;AAAE,sGAAA,aAAa,OAAA;AAAE,uGAAA,cAAc,OAAA;AAAE,kGAAA,SAAS,OAAA;AAGnE,sDAAyE;AAAjE,mHAAA,kBAAkB,OAAA;AAAE,gHAAA,eAAe,OAAA;AAG3C,sCAA6E;AAArE,oGAAA,UAAU,OAAA;AAAE,mGAAA,SAAS,OAAA;AAAE,sGAAA,YAAY,OAAA;AAAE,qGAAA,WAAW,OAAA"}
@@ -3,5 +3,7 @@ export interface SwaggerPluginOptions {
3
3
  description: string;
4
4
  version?: string;
5
5
  routePrefix?: string;
6
+ /** CSP estático do Swagger UI (magazines usa false). Default: true */
7
+ staticCSP?: boolean;
6
8
  }
7
9
  export declare function createSwaggerPlugin(options: SwaggerPluginOptions): (fastify: any) => Promise<void>;
@@ -47,7 +47,7 @@ function createSwaggerPlugin(options) {
47
47
  docExpansion: "none",
48
48
  deepLinking: false,
49
49
  },
50
- staticCSP: true,
50
+ staticCSP: options.staticCSP ?? true,
51
51
  exposeRoute: true,
52
52
  transformStaticCSP: (header) => header,
53
53
  });
@@ -1 +1 @@
1
- {"version":3,"file":"plugin.js","sourceRoot":"","sources":["../../src/swagger/plugin.ts"],"names":[],"mappings":";AAAA,wEAAwE;AACxE,0EAA0E;AAC1E,yEAAyE;;AAoBzE,kDAwCC;AAnDD,yEAAyE;AACzE,qEAAqE;AACrE,aAAa;AACb,IAAI,CAAE,MAAM,CAAC,SAAiB,CAAC,MAAM,EAAE,CAAC;IACpC,aAAa;IACb,MAAM,CAAC,SAAS,CAAC,MAAM,GAAG;QACtB,MAAM,GAAG,GAAG,MAAM,CAAC,QAAQ,CAAC,IAAI,CAAC,QAAQ,EAAE,CAAC,CAAC;QAC7C,OAAO,GAAG,IAAI,IAAI,CAAC,QAAQ,EAAE,CAAC;IAClC,CAAC,CAAC;AACN,CAAC;AAED,SAAgB,mBAAmB,CAAC,OAA6B;IAC7D,OAAO,KAAK,UAAU,aAAa,CAAC,OAAY;QAC5C,uDAAuD;QACvD,MAAM,OAAO,GAAG,OAAO,CAAC,kBAAkB,CAAC,CAAC;QAC5C,MAAM,SAAS,GAAG,OAAO,CAAC,qBAAqB,CAAC,CAAC;QAEjD,MAAM,OAAO,CAAC,QAAQ,CAAC,OAAO,EAAE;YAC5B,SAAS,EAAE,IAAI;YACf,WAAW,EAAE,IAAI;YACjB,OAAO,EAAE;gBACL,IAAI,EAAE;oBACF,KAAK,EAAE,OAAO,CAAC,KAAK;oBACpB,WAAW,EAAE,OAAO,CAAC,WAAW;oBAChC,OAAO,EAAE,OAAO,CAAC,OAAO,IAAI,OAAO;iBACtC;gBACD,IAAI,EAAE,OAAO,CAAC,GAAG,CAAC,MAAM;gBACxB,OAAO,EAAE,CAAC,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC;gBAC3B,mBAAmB,EAAE;oBACjB,UAAU,EAAE;wBACR,IAAI,EAAE,QAAQ;wBACd,IAAI,EAAE,eAAe;wBACrB,EAAE,EAAE,QAAQ;wBACZ,WAAW,EAAE,wDAAwD;qBACxE;iBACJ;gBACD,QAAQ,EAAE,CAAC,EAAC,UAAU,EAAE,EAAE,EAAC,CAAC;aAC/B;SACJ,CAAC,CAAC;QAEH,MAAM,OAAO,CAAC,QAAQ,CAAC,SAAS,EAAE;YAC9B,WAAW,EAAE,OAAO,CAAC,WAAW,IAAI,gBAAgB;YACpD,QAAQ,EAAE;gBACN,YAAY,EAAE,MAAM;gBACpB,WAAW,EAAE,KAAK;aACrB;YACD,SAAS,EAAE,IAAI;YACf,WAAW,EAAE,IAAI;YACjB,kBAAkB,EAAE,CAAC,MAAW,EAAE,EAAE,CAAC,MAAM;SAC9C,CAAC,CAAC;IACP,CAAC,CAAC;AACN,CAAC"}
1
+ {"version":3,"file":"plugin.js","sourceRoot":"","sources":["../../src/swagger/plugin.ts"],"names":[],"mappings":";AAAA,wEAAwE;AACxE,0EAA0E;AAC1E,yEAAyE;;AAsBzE,kDAwCC;AAnDD,yEAAyE;AACzE,qEAAqE;AACrE,aAAa;AACb,IAAI,CAAE,MAAM,CAAC,SAAiB,CAAC,MAAM,EAAE,CAAC;IACpC,aAAa;IACb,MAAM,CAAC,SAAS,CAAC,MAAM,GAAG;QACtB,MAAM,GAAG,GAAG,MAAM,CAAC,QAAQ,CAAC,IAAI,CAAC,QAAQ,EAAE,CAAC,CAAC;QAC7C,OAAO,GAAG,IAAI,IAAI,CAAC,QAAQ,EAAE,CAAC;IAClC,CAAC,CAAC;AACN,CAAC;AAED,SAAgB,mBAAmB,CAAC,OAA6B;IAC7D,OAAO,KAAK,UAAU,aAAa,CAAC,OAAY;QAC5C,uDAAuD;QACvD,MAAM,OAAO,GAAG,OAAO,CAAC,kBAAkB,CAAC,CAAC;QAC5C,MAAM,SAAS,GAAG,OAAO,CAAC,qBAAqB,CAAC,CAAC;QAEjD,MAAM,OAAO,CAAC,QAAQ,CAAC,OAAO,EAAE;YAC5B,SAAS,EAAE,IAAI;YACf,WAAW,EAAE,IAAI;YACjB,OAAO,EAAE;gBACL,IAAI,EAAE;oBACF,KAAK,EAAE,OAAO,CAAC,KAAK;oBACpB,WAAW,EAAE,OAAO,CAAC,WAAW;oBAChC,OAAO,EAAE,OAAO,CAAC,OAAO,IAAI,OAAO;iBACtC;gBACD,IAAI,EAAE,OAAO,CAAC,GAAG,CAAC,MAAM;gBACxB,OAAO,EAAE,CAAC,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC;gBAC3B,mBAAmB,EAAE;oBACjB,UAAU,EAAE;wBACR,IAAI,EAAE,QAAQ;wBACd,IAAI,EAAE,eAAe;wBACrB,EAAE,EAAE,QAAQ;wBACZ,WAAW,EAAE,wDAAwD;qBACxE;iBACJ;gBACD,QAAQ,EAAE,CAAC,EAAC,UAAU,EAAE,EAAE,EAAC,CAAC;aAC/B;SACJ,CAAC,CAAC;QAEH,MAAM,OAAO,CAAC,QAAQ,CAAC,SAAS,EAAE;YAC9B,WAAW,EAAE,OAAO,CAAC,WAAW,IAAI,gBAAgB;YACpD,QAAQ,EAAE;gBACN,YAAY,EAAE,MAAM;gBACpB,WAAW,EAAE,KAAK;aACrB;YACD,SAAS,EAAE,OAAO,CAAC,SAAS,IAAI,IAAI;YACpC,WAAW,EAAE,IAAI;YACjB,kBAAkB,EAAE,CAAC,MAAW,EAAE,EAAE,CAAC,MAAM;SAC9C,CAAC,CAAC;IACP,CAAC,CAAC;AACN,CAAC"}
@@ -6,6 +6,9 @@ export interface AuthMiddlewareOptions {
6
6
  publicRoutes: RegExp[];
7
7
  /** Resolve o Auth do tenant Firebase (ex: getTenantAuth do pkg) */
8
8
  getTenantAuth: (tenantId: string | undefined) => TenantAuthLike;
9
+ /** false = API single-tenant (ex: core): não lê o claim firebase.tenant e
10
+ * chama getTenantAuth(undefined) — passe () => getDefaultAuth(). Default: true */
11
+ tenantAware?: boolean;
9
12
  /** Aceitar token via ?token= (default: false — vaza em logs) */
10
13
  allowQueryToken?: boolean;
11
14
  /** Bypass SEM token (dev local). NUNCA ligar em produção. Default: false */
@@ -76,12 +76,16 @@ function createAuthMiddleware(options) {
76
76
  }
77
77
  }
78
78
  request.user = cached;
79
+ request.user_id = cached.uid;
79
80
  request.authToken = authHeader;
80
81
  return;
81
82
  }
82
83
  // o claim de tenant orienta QUAL Auth valida; a prova é criptográfica
83
- const payload = JSON.parse(Buffer.from(parts[1], "base64").toString("utf-8"));
84
- const tenantId = payload?.firebase?.tenant;
84
+ let tenantId;
85
+ if (options.tenantAware !== false) {
86
+ const payload = JSON.parse(Buffer.from(parts[1], "base64").toString("utf-8"));
87
+ tenantId = payload?.firebase?.tenant;
88
+ }
85
89
  const auth = options.getTenantAuth(tenantId);
86
90
  const decodedToken = await auth.verifyIdToken(authHeader, true);
87
91
  setCached(authHeader, decodedToken, decodedToken.exp);
@@ -94,6 +98,7 @@ function createAuthMiddleware(options) {
94
98
  }
95
99
  }
96
100
  request.user = decodedToken;
101
+ request.user_id = decodedToken.uid;
97
102
  request.authToken = authHeader;
98
103
  }
99
104
  catch (err) {
@@ -1 +1 @@
1
- {"version":3,"file":"auth.js","sourceRoot":"","sources":["../../src/tenant/auth.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"auth.js","sourceRoot":"","sources":["../../src/tenant/auth.ts"],"names":[],"mappings":"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"}
@@ -1,5 +1,9 @@
1
1
  export interface TenantMiddlewareOptions<TClient> {
2
2
  getTenantClient: (idSchool: string) => TClient;
3
3
  defaultClient: TClient;
4
+ /** Chamado após resolver o tenant e setar req.prisma; idSchool = null
5
+ * quando o request caiu no default. Erros aqui NÃO derrubam o request
6
+ * (log + segue) — enriquecimento é best-effort. */
7
+ onTenantResolved?: (req: any, idSchool: string | null) => void | Promise<void>;
4
8
  }
5
9
  export declare function createTenantMiddleware<TClient>(options: TenantMiddlewareOptions<TClient>): (fastify: any) => Promise<void>;
@@ -4,6 +4,10 @@
4
4
  // para o client default quando não há id válido. É a ÚNICA porta de entrada
5
5
  // oficial do Prisma nos handlers — garante que o :id_school da URL decide o
6
6
  // schema, nunca o handler.
7
+ //
8
+ // Também seta req.id_school (número; undefined quando sem id válido) e
9
+ // oferece onTenantResolved para enriquecer o request (ex: carregar
10
+ // permissões do usuário) sem cada API duplicar lógica no middleware.
7
11
  Object.defineProperty(exports, "__esModule", { value: true });
8
12
  exports.createTenantMiddleware = createTenantMiddleware;
9
13
  const resolve_1 = require("./resolve");
@@ -11,9 +15,21 @@ function createTenantMiddleware(options) {
11
15
  return async function tenantMiddleware(fastify) {
12
16
  fastify.addHook("preValidation", async (req) => {
13
17
  const idSchool = (0, resolve_1.resolveTenantId)(req);
14
- req.prisma = idSchool
15
- ? options.getTenantClient(idSchool)
16
- : options.defaultClient;
18
+ if (idSchool) {
19
+ req.prisma = options.getTenantClient(idSchool);
20
+ req.id_school = Number(idSchool);
21
+ }
22
+ else {
23
+ req.prisma = options.defaultClient;
24
+ }
25
+ if (options.onTenantResolved) {
26
+ try {
27
+ await options.onTenantResolved(req, idSchool);
28
+ }
29
+ catch (e) {
30
+ console.error("onTenantResolved error:", e);
31
+ }
32
+ }
17
33
  });
18
34
  };
19
35
  }
@@ -1 +1 @@
1
- {"version":3,"file":"middleware.js","sourceRoot":"","sources":["../../src/tenant/middleware.ts"],"names":[],"mappings":";AAAA,4EAA4E;AAC5E,4EAA4E;AAC5E,4EAA4E;AAC5E,4EAA4E;AAC5E,2BAA2B;;AAS3B,wDASC;AAhBD,uCAA6D;AAO7D,SAAgB,sBAAsB,CAAU,OAAyC;IACrF,OAAO,KAAK,UAAU,gBAAgB,CAAC,OAAY;QAC/C,OAAO,CAAC,OAAO,CAAC,eAAe,EAAE,KAAK,EAAE,GAA6C,EAAE,EAAE;YACrF,MAAM,QAAQ,GAAG,IAAA,yBAAe,EAAC,GAAG,CAAC,CAAC;YACtC,GAAG,CAAC,MAAM,GAAG,QAAQ;gBACjB,CAAC,CAAC,OAAO,CAAC,eAAe,CAAC,QAAQ,CAAC;gBACnC,CAAC,CAAC,OAAO,CAAC,aAAa,CAAC;QAChC,CAAC,CAAC,CAAC;IACP,CAAC,CAAC;AACN,CAAC"}
1
+ {"version":3,"file":"middleware.js","sourceRoot":"","sources":["../../src/tenant/middleware.ts"],"names":[],"mappings":";AAAA,4EAA4E;AAC5E,4EAA4E;AAC5E,4EAA4E;AAC5E,4EAA4E;AAC5E,2BAA2B;AAC3B,EAAE;AACF,uEAAuE;AACvE,mEAAmE;AACnE,qEAAqE;;AAarE,wDAsBC;AAjCD,uCAA6D;AAW7D,SAAgB,sBAAsB,CAAU,OAAyC;IACrF,OAAO,KAAK,UAAU,gBAAgB,CAAC,OAAY;QAC/C,OAAO,CAAC,OAAO,CAAC,eAAe,EAAE,KAAK,EAAE,GAGvC,EAAE,EAAE;YACD,MAAM,QAAQ,GAAG,IAAA,yBAAe,EAAC,GAAG,CAAC,CAAC;YACtC,IAAI,QAAQ,EAAE,CAAC;gBACX,GAAG,CAAC,MAAM,GAAG,OAAO,CAAC,eAAe,CAAC,QAAQ,CAAC,CAAC;gBAC/C,GAAG,CAAC,SAAS,GAAG,MAAM,CAAC,QAAQ,CAAC,CAAC;YACrC,CAAC;iBAAM,CAAC;gBACJ,GAAG,CAAC,MAAM,GAAG,OAAO,CAAC,aAAa,CAAC;YACvC,CAAC;YACD,IAAI,OAAO,CAAC,gBAAgB,EAAE,CAAC;gBAC3B,IAAI,CAAC;oBACD,MAAM,OAAO,CAAC,gBAAgB,CAAC,GAAG,EAAE,QAAQ,CAAC,CAAC;gBAClD,CAAC;gBAAC,OAAO,CAAC,EAAE,CAAC;oBACT,OAAO,CAAC,KAAK,CAAC,yBAAyB,EAAE,CAAC,CAAC,CAAC;gBAChD,CAAC;YACL,CAAC;QACL,CAAC,CAAC,CAAC;IACP,CAAC,CAAC;AACN,CAAC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@mybuildex/pkg",
3
- "version": "0.2.1",
3
+ "version": "0.3.0",
4
4
  "description": "Infra comum das APIs MyBuilder: multitenancy Prisma (pool único), middleware de tenant e CORS",
5
5
  "license": "MIT",
6
6
  "repository": {