@node-tenant/tenant-express 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.
package/README.md ADDED
@@ -0,0 +1,136 @@
1
+ # @node-tenant/tenant-express
2
+
3
+ > **Express.js middleware** for the `@node-tenant` ecosystem — effortlessly resolves tenant context from HTTP requests.
4
+
5
+ [![npm version](https://img.shields.io/npm/v/@node-tenant/tenant-express)](https://www.npmjs.com/package/@node-tenant/tenant-express)
6
+ [![license](https://img.shields.io/npm/l/@node-tenant/tenant-express)](./LICENSE)
7
+
8
+ ---
9
+
10
+ ## Overview
11
+
12
+ `@node-tenant/tenant-express` provides middleware and resolvers to automatically identify which tenant is making an HTTP request in your Express application. It integrates perfectly with `@node-tenant/tenant-core` to establish the tenant context using Node.js `AsyncLocalStorage`.
13
+
14
+ ---
15
+
16
+ ## Table of Contents
17
+
18
+ - [Installation](#installation)
19
+ - [Quick Start](#quick-start)
20
+ - [Resolvers](#resolvers)
21
+ - [Header Resolver](#header-resolver)
22
+ - [Subdomain Resolver](#subdomain-resolver)
23
+ - [Custom Resolver](#custom-resolver)
24
+ - [API Reference](#api-reference)
25
+ - [License](#license)
26
+
27
+ ---
28
+
29
+ ## Installation
30
+
31
+ ```bash
32
+ npm install @node-tenant/tenant-core @node-tenant/tenant-express
33
+ ```
34
+
35
+ > **Peer dependency**: `express >= 4.0.0` must be installed in your project.
36
+
37
+ ---
38
+
39
+ ## Quick Start
40
+
41
+ ```ts
42
+ import express from 'express';
43
+ import { TenantManager, TenantContextManager } from '@node-tenant/tenant-core';
44
+ import { tenantMiddleware, headerResolver } from '@node-tenant/tenant-express';
45
+
46
+ const manager = new TenantManager({ /* storage, etc */ });
47
+ const app = express();
48
+
49
+ // Use the middleware globally (or on specific routes)
50
+ // This will look for a tenant slug in the 'x-tenant-id' header
51
+ app.use(tenantMiddleware({
52
+ manager,
53
+ resolver: headerResolver('x-tenant-id')
54
+ }));
55
+
56
+ app.get('/api/me', (req, res) => {
57
+ // Access the resolved tenant context safely!
58
+ const tenant = TenantContextManager.currentOrThrow();
59
+
60
+ res.json({
61
+ message: `Hello from tenant: ${tenant.name}`,
62
+ tenantId: tenant.id
63
+ });
64
+ });
65
+
66
+ app.listen(3000);
67
+ ```
68
+
69
+ ---
70
+
71
+ ## Resolvers
72
+
73
+ Resolvers are strategies for extracting the tenant identifier (slug or ID) from an incoming Express request.
74
+
75
+ ### Header Resolver
76
+
77
+ Extracts the tenant identifier from an HTTP header. Common in API-first applications.
78
+
79
+ ```ts
80
+ import { headerResolver } from '@node-tenant/tenant-express';
81
+
82
+ // Looks for 'x-tenant-id' in headers
83
+ const resolver = headerResolver('x-tenant-id');
84
+ ```
85
+
86
+ ### Subdomain Resolver
87
+
88
+ Extracts the tenant identifier from the subdomain (e.g., `acme` in `acme.myapp.com`). You **must** provide the `storage` adapter so the resolver can lookup the tenant by its slug.
89
+
90
+ ```ts
91
+ import { subdomainResolver } from '@node-tenant/tenant-express';
92
+
93
+ // Extracts subdomain and looks up tenant via storage.getTenantBySlug(subdomain)
94
+ const resolver = subdomainResolver(manager.storage);
95
+ ```
96
+
97
+ ### Custom Resolver
98
+
99
+ You can easily write your own resolver by implementing the `TenantResolver` signature: `(req: Request) => Promise<string | undefined>`
100
+
101
+ ```ts
102
+ const jwtResolver = async (req) => {
103
+ // Extract tenant ID from a decoded JWT token
104
+ return req.user?.tenantId;
105
+ };
106
+
107
+ app.use(tenantMiddleware({ manager, resolver: jwtResolver }));
108
+ ```
109
+
110
+ ---
111
+
112
+ ## API Reference
113
+
114
+ ### `tenantMiddleware(options)`
115
+
116
+ Creates the Express middleware.
117
+
118
+ ```ts
119
+ const middleware = tenantMiddleware({
120
+ manager: managerInstance,
121
+ resolver: myResolver,
122
+ requireTenant: true // default: false
123
+ });
124
+ ```
125
+
126
+ | Option | Type | Required | Description |
127
+ |---|---|---|---|
128
+ | `manager` | `TenantManager` | ✅ | Instance of `TenantManager` |
129
+ | `resolver` | `TenantResolver` | ✅ | Function to extract tenant ID/slug from request |
130
+ | `requireTenant` | `boolean` | ❌ | If true, returns 401 if no tenant is found. Default: `false`. |
131
+
132
+ ---
133
+
134
+ ## License
135
+
136
+ MIT © AdPulseFlow
package/dist/index.cjs ADDED
@@ -0,0 +1,91 @@
1
+ "use strict";
2
+ var __defProp = Object.defineProperty;
3
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
+ var __getOwnPropNames = Object.getOwnPropertyNames;
5
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
6
+ var __export = (target, all) => {
7
+ for (var name in all)
8
+ __defProp(target, name, { get: all[name], enumerable: true });
9
+ };
10
+ var __copyProps = (to, from, except, desc) => {
11
+ if (from && typeof from === "object" || typeof from === "function") {
12
+ for (let key of __getOwnPropNames(from))
13
+ if (!__hasOwnProp.call(to, key) && key !== except)
14
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
15
+ }
16
+ return to;
17
+ };
18
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
+
20
+ // src/index.ts
21
+ var index_exports = {};
22
+ __export(index_exports, {
23
+ chainResolvers: () => import_tenant_core2.chainResolvers,
24
+ domainResolver: () => import_tenant_core2.domainResolver,
25
+ getCurrentTenant: () => getCurrentTenant,
26
+ headerResolver: () => import_tenant_core2.headerResolver,
27
+ pathResolver: () => import_tenant_core2.pathResolver,
28
+ subdomainResolver: () => import_tenant_core2.subdomainResolver,
29
+ tenantMiddleware: () => tenantMiddleware
30
+ });
31
+ module.exports = __toCommonJS(index_exports);
32
+ var import_tenant_core = require("@node-tenant/tenant-core");
33
+ var import_tenant_core2 = require("@node-tenant/tenant-core");
34
+ function tenantMiddleware(options) {
35
+ const { manager, resolver, required = true } = options;
36
+ return async (req, res, next) => {
37
+ try {
38
+ const result = await resolver(req);
39
+ if (!result) {
40
+ if (required) {
41
+ if (options.onNotFound) {
42
+ return options.onNotFound(req, res, next);
43
+ }
44
+ res.status(401).json({ error: "Tenant not found" });
45
+ return;
46
+ }
47
+ return next();
48
+ }
49
+ const tenant = await manager.getTenant(result.tenantId);
50
+ if (!tenant) {
51
+ if (required) {
52
+ res.status(401).json({ error: "Tenant not found" });
53
+ return;
54
+ }
55
+ return next();
56
+ }
57
+ if (tenant.status !== "active") {
58
+ res.status(403).json({ error: `Tenant is ${tenant.status}` });
59
+ return;
60
+ }
61
+ const ctx = {
62
+ id: tenant.id,
63
+ slug: tenant.slug,
64
+ strategy: tenant.strategy,
65
+ organizationId: tenant.organizationId,
66
+ config: tenant.config
67
+ };
68
+ for (const plugin of manager.plugins) {
69
+ await plugin.onTenantResolved?.(ctx);
70
+ }
71
+ manager.emit("tenant.resolved", ctx);
72
+ import_tenant_core.TenantContextManager.run(ctx, () => next());
73
+ } catch (err) {
74
+ next(err);
75
+ }
76
+ };
77
+ }
78
+ function getCurrentTenant() {
79
+ return import_tenant_core.TenantContextManager.currentOrThrow();
80
+ }
81
+ // Annotate the CommonJS export names for ESM import in node:
82
+ 0 && (module.exports = {
83
+ chainResolvers,
84
+ domainResolver,
85
+ getCurrentTenant,
86
+ headerResolver,
87
+ pathResolver,
88
+ subdomainResolver,
89
+ tenantMiddleware
90
+ });
91
+ //# sourceMappingURL=index.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/index.ts"],"sourcesContent":["import type { Request, Response, NextFunction, RequestHandler } from 'express';\nimport {\n TenantContextManager,\n TenantManager,\n type TenantResolverFn,\n type TenantPlugin,\n} from '@node-tenant/tenant-core';\n\nexport interface TenantMiddlewareOptions {\n manager: TenantManager;\n resolver: TenantResolverFn<Request>;\n /** If true, 401 is returned when tenant cannot be resolved. Default: true */\n required?: boolean;\n /** Called when tenant resolution fails */\n onNotFound?: (req: Request, res: Response, next: NextFunction) => void;\n}\n\n/**\n * Express middleware that resolves the tenant for each request and\n * runs the rest of the middleware chain inside that tenant's context.\n *\n * Usage:\n * app.use(tenantMiddleware({ manager, resolver: subdomainResolver(manager.storage) }))\n */\nexport function tenantMiddleware(options: TenantMiddlewareOptions): RequestHandler {\n const { manager, resolver, required = true } = options;\n\n return async (req, res, next) => {\n try {\n const result = await resolver(req);\n\n if (!result) {\n if (required) {\n if (options.onNotFound) {\n return options.onNotFound(req, res, next);\n }\n res.status(401).json({ error: 'Tenant not found' });\n return;\n }\n return next();\n }\n\n const tenant = await manager.getTenant(result.tenantId);\n if (!tenant) {\n if (required) {\n res.status(401).json({ error: 'Tenant not found' });\n return;\n }\n return next();\n }\n\n if (tenant.status !== 'active') {\n res.status(403).json({ error: `Tenant is ${tenant.status}` });\n return;\n }\n\n const ctx = {\n id: tenant.id,\n slug: tenant.slug,\n strategy: tenant.strategy,\n organizationId: tenant.organizationId,\n config: tenant.config,\n };\n\n for (const plugin of (manager as any).plugins as TenantPlugin[]) {\n await plugin.onTenantResolved?.(ctx);\n }\n\n manager.emit('tenant.resolved', ctx);\n\n TenantContextManager.run(ctx, () => next());\n } catch (err) {\n next(err);\n }\n };\n}\n\n/**\n * Get the current tenant context inside an Express handler.\n * Must be used after tenantMiddleware().\n */\nexport function getCurrentTenant() {\n return TenantContextManager.currentOrThrow();\n}\n\nexport { subdomainResolver, domainResolver, pathResolver, headerResolver, chainResolvers } from '@node-tenant/tenant-core';\n"],"mappings":";;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA,yBAKO;AA+EP,IAAAA,sBAAgG;AA7DzF,SAAS,iBAAiB,SAAkD;AACjF,QAAM,EAAE,SAAS,UAAU,WAAW,KAAK,IAAI;AAE/C,SAAO,OAAO,KAAK,KAAK,SAAS;AAC/B,QAAI;AACF,YAAM,SAAS,MAAM,SAAS,GAAG;AAEjC,UAAI,CAAC,QAAQ;AACX,YAAI,UAAU;AACZ,cAAI,QAAQ,YAAY;AACtB,mBAAO,QAAQ,WAAW,KAAK,KAAK,IAAI;AAAA,UAC1C;AACA,cAAI,OAAO,GAAG,EAAE,KAAK,EAAE,OAAO,mBAAmB,CAAC;AAClD;AAAA,QACF;AACA,eAAO,KAAK;AAAA,MACd;AAEA,YAAM,SAAS,MAAM,QAAQ,UAAU,OAAO,QAAQ;AACtD,UAAI,CAAC,QAAQ;AACX,YAAI,UAAU;AACZ,cAAI,OAAO,GAAG,EAAE,KAAK,EAAE,OAAO,mBAAmB,CAAC;AAClD;AAAA,QACF;AACA,eAAO,KAAK;AAAA,MACd;AAEA,UAAI,OAAO,WAAW,UAAU;AAC9B,YAAI,OAAO,GAAG,EAAE,KAAK,EAAE,OAAO,aAAa,OAAO,MAAM,GAAG,CAAC;AAC5D;AAAA,MACF;AAEA,YAAM,MAAM;AAAA,QACV,IAAI,OAAO;AAAA,QACX,MAAM,OAAO;AAAA,QACb,UAAU,OAAO;AAAA,QACjB,gBAAgB,OAAO;AAAA,QACvB,QAAQ,OAAO;AAAA,MACjB;AAEA,iBAAW,UAAW,QAAgB,SAA2B;AAC/D,cAAM,OAAO,mBAAmB,GAAG;AAAA,MACrC;AAEA,cAAQ,KAAK,mBAAmB,GAAG;AAEnC,8CAAqB,IAAI,KAAK,MAAM,KAAK,CAAC;AAAA,IAC5C,SAAS,KAAK;AACZ,WAAK,GAAG;AAAA,IACV;AAAA,EACF;AACF;AAMO,SAAS,mBAAmB;AACjC,SAAO,wCAAqB,eAAe;AAC7C;","names":["import_tenant_core"]}
@@ -0,0 +1,28 @@
1
+ import * as _node_tenant_tenant_core from '@node-tenant/tenant-core';
2
+ import { TenantManager, TenantResolverFn } from '@node-tenant/tenant-core';
3
+ export { chainResolvers, domainResolver, headerResolver, pathResolver, subdomainResolver } from '@node-tenant/tenant-core';
4
+ import { Request, Response, NextFunction, RequestHandler } from 'express';
5
+
6
+ interface TenantMiddlewareOptions {
7
+ manager: TenantManager;
8
+ resolver: TenantResolverFn<Request>;
9
+ /** If true, 401 is returned when tenant cannot be resolved. Default: true */
10
+ required?: boolean;
11
+ /** Called when tenant resolution fails */
12
+ onNotFound?: (req: Request, res: Response, next: NextFunction) => void;
13
+ }
14
+ /**
15
+ * Express middleware that resolves the tenant for each request and
16
+ * runs the rest of the middleware chain inside that tenant's context.
17
+ *
18
+ * Usage:
19
+ * app.use(tenantMiddleware({ manager, resolver: subdomainResolver(manager.storage) }))
20
+ */
21
+ declare function tenantMiddleware(options: TenantMiddlewareOptions): RequestHandler;
22
+ /**
23
+ * Get the current tenant context inside an Express handler.
24
+ * Must be used after tenantMiddleware().
25
+ */
26
+ declare function getCurrentTenant(): _node_tenant_tenant_core.TenantContext;
27
+
28
+ export { type TenantMiddlewareOptions, getCurrentTenant, tenantMiddleware };
@@ -0,0 +1,28 @@
1
+ import * as _node_tenant_tenant_core from '@node-tenant/tenant-core';
2
+ import { TenantManager, TenantResolverFn } from '@node-tenant/tenant-core';
3
+ export { chainResolvers, domainResolver, headerResolver, pathResolver, subdomainResolver } from '@node-tenant/tenant-core';
4
+ import { Request, Response, NextFunction, RequestHandler } from 'express';
5
+
6
+ interface TenantMiddlewareOptions {
7
+ manager: TenantManager;
8
+ resolver: TenantResolverFn<Request>;
9
+ /** If true, 401 is returned when tenant cannot be resolved. Default: true */
10
+ required?: boolean;
11
+ /** Called when tenant resolution fails */
12
+ onNotFound?: (req: Request, res: Response, next: NextFunction) => void;
13
+ }
14
+ /**
15
+ * Express middleware that resolves the tenant for each request and
16
+ * runs the rest of the middleware chain inside that tenant's context.
17
+ *
18
+ * Usage:
19
+ * app.use(tenantMiddleware({ manager, resolver: subdomainResolver(manager.storage) }))
20
+ */
21
+ declare function tenantMiddleware(options: TenantMiddlewareOptions): RequestHandler;
22
+ /**
23
+ * Get the current tenant context inside an Express handler.
24
+ * Must be used after tenantMiddleware().
25
+ */
26
+ declare function getCurrentTenant(): _node_tenant_tenant_core.TenantContext;
27
+
28
+ export { type TenantMiddlewareOptions, getCurrentTenant, tenantMiddleware };
package/dist/index.js ADDED
@@ -0,0 +1,62 @@
1
+ // src/index.ts
2
+ import {
3
+ TenantContextManager
4
+ } from "@node-tenant/tenant-core";
5
+ import { subdomainResolver, domainResolver, pathResolver, headerResolver, chainResolvers } from "@node-tenant/tenant-core";
6
+ function tenantMiddleware(options) {
7
+ const { manager, resolver, required = true } = options;
8
+ return async (req, res, next) => {
9
+ try {
10
+ const result = await resolver(req);
11
+ if (!result) {
12
+ if (required) {
13
+ if (options.onNotFound) {
14
+ return options.onNotFound(req, res, next);
15
+ }
16
+ res.status(401).json({ error: "Tenant not found" });
17
+ return;
18
+ }
19
+ return next();
20
+ }
21
+ const tenant = await manager.getTenant(result.tenantId);
22
+ if (!tenant) {
23
+ if (required) {
24
+ res.status(401).json({ error: "Tenant not found" });
25
+ return;
26
+ }
27
+ return next();
28
+ }
29
+ if (tenant.status !== "active") {
30
+ res.status(403).json({ error: `Tenant is ${tenant.status}` });
31
+ return;
32
+ }
33
+ const ctx = {
34
+ id: tenant.id,
35
+ slug: tenant.slug,
36
+ strategy: tenant.strategy,
37
+ organizationId: tenant.organizationId,
38
+ config: tenant.config
39
+ };
40
+ for (const plugin of manager.plugins) {
41
+ await plugin.onTenantResolved?.(ctx);
42
+ }
43
+ manager.emit("tenant.resolved", ctx);
44
+ TenantContextManager.run(ctx, () => next());
45
+ } catch (err) {
46
+ next(err);
47
+ }
48
+ };
49
+ }
50
+ function getCurrentTenant() {
51
+ return TenantContextManager.currentOrThrow();
52
+ }
53
+ export {
54
+ chainResolvers,
55
+ domainResolver,
56
+ getCurrentTenant,
57
+ headerResolver,
58
+ pathResolver,
59
+ subdomainResolver,
60
+ tenantMiddleware
61
+ };
62
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/index.ts"],"sourcesContent":["import type { Request, Response, NextFunction, RequestHandler } from 'express';\nimport {\n TenantContextManager,\n TenantManager,\n type TenantResolverFn,\n type TenantPlugin,\n} from '@node-tenant/tenant-core';\n\nexport interface TenantMiddlewareOptions {\n manager: TenantManager;\n resolver: TenantResolverFn<Request>;\n /** If true, 401 is returned when tenant cannot be resolved. Default: true */\n required?: boolean;\n /** Called when tenant resolution fails */\n onNotFound?: (req: Request, res: Response, next: NextFunction) => void;\n}\n\n/**\n * Express middleware that resolves the tenant for each request and\n * runs the rest of the middleware chain inside that tenant's context.\n *\n * Usage:\n * app.use(tenantMiddleware({ manager, resolver: subdomainResolver(manager.storage) }))\n */\nexport function tenantMiddleware(options: TenantMiddlewareOptions): RequestHandler {\n const { manager, resolver, required = true } = options;\n\n return async (req, res, next) => {\n try {\n const result = await resolver(req);\n\n if (!result) {\n if (required) {\n if (options.onNotFound) {\n return options.onNotFound(req, res, next);\n }\n res.status(401).json({ error: 'Tenant not found' });\n return;\n }\n return next();\n }\n\n const tenant = await manager.getTenant(result.tenantId);\n if (!tenant) {\n if (required) {\n res.status(401).json({ error: 'Tenant not found' });\n return;\n }\n return next();\n }\n\n if (tenant.status !== 'active') {\n res.status(403).json({ error: `Tenant is ${tenant.status}` });\n return;\n }\n\n const ctx = {\n id: tenant.id,\n slug: tenant.slug,\n strategy: tenant.strategy,\n organizationId: tenant.organizationId,\n config: tenant.config,\n };\n\n for (const plugin of (manager as any).plugins as TenantPlugin[]) {\n await plugin.onTenantResolved?.(ctx);\n }\n\n manager.emit('tenant.resolved', ctx);\n\n TenantContextManager.run(ctx, () => next());\n } catch (err) {\n next(err);\n }\n };\n}\n\n/**\n * Get the current tenant context inside an Express handler.\n * Must be used after tenantMiddleware().\n */\nexport function getCurrentTenant() {\n return TenantContextManager.currentOrThrow();\n}\n\nexport { subdomainResolver, domainResolver, pathResolver, headerResolver, chainResolvers } from '@node-tenant/tenant-core';\n"],"mappings":";AACA;AAAA,EACE;AAAA,OAIK;AA+EP,SAAS,mBAAmB,gBAAgB,cAAc,gBAAgB,sBAAsB;AA7DzF,SAAS,iBAAiB,SAAkD;AACjF,QAAM,EAAE,SAAS,UAAU,WAAW,KAAK,IAAI;AAE/C,SAAO,OAAO,KAAK,KAAK,SAAS;AAC/B,QAAI;AACF,YAAM,SAAS,MAAM,SAAS,GAAG;AAEjC,UAAI,CAAC,QAAQ;AACX,YAAI,UAAU;AACZ,cAAI,QAAQ,YAAY;AACtB,mBAAO,QAAQ,WAAW,KAAK,KAAK,IAAI;AAAA,UAC1C;AACA,cAAI,OAAO,GAAG,EAAE,KAAK,EAAE,OAAO,mBAAmB,CAAC;AAClD;AAAA,QACF;AACA,eAAO,KAAK;AAAA,MACd;AAEA,YAAM,SAAS,MAAM,QAAQ,UAAU,OAAO,QAAQ;AACtD,UAAI,CAAC,QAAQ;AACX,YAAI,UAAU;AACZ,cAAI,OAAO,GAAG,EAAE,KAAK,EAAE,OAAO,mBAAmB,CAAC;AAClD;AAAA,QACF;AACA,eAAO,KAAK;AAAA,MACd;AAEA,UAAI,OAAO,WAAW,UAAU;AAC9B,YAAI,OAAO,GAAG,EAAE,KAAK,EAAE,OAAO,aAAa,OAAO,MAAM,GAAG,CAAC;AAC5D;AAAA,MACF;AAEA,YAAM,MAAM;AAAA,QACV,IAAI,OAAO;AAAA,QACX,MAAM,OAAO;AAAA,QACb,UAAU,OAAO;AAAA,QACjB,gBAAgB,OAAO;AAAA,QACvB,QAAQ,OAAO;AAAA,MACjB;AAEA,iBAAW,UAAW,QAAgB,SAA2B;AAC/D,cAAM,OAAO,mBAAmB,GAAG;AAAA,MACrC;AAEA,cAAQ,KAAK,mBAAmB,GAAG;AAEnC,2BAAqB,IAAI,KAAK,MAAM,KAAK,CAAC;AAAA,IAC5C,SAAS,KAAK;AACZ,WAAK,GAAG;AAAA,IACV;AAAA,EACF;AACF;AAMO,SAAS,mBAAmB;AACjC,SAAO,qBAAqB,eAAe;AAC7C;","names":[]}
package/package.json ADDED
@@ -0,0 +1,41 @@
1
+ {
2
+ "name": "@node-tenant/tenant-express",
3
+ "version": "0.1.0",
4
+ "description": "Express.js middleware for @node-tenant/tenant",
5
+ "license": "MIT",
6
+ "type": "module",
7
+ "main": "./dist/index.cjs",
8
+ "module": "./dist/index.js",
9
+ "types": "./dist/index.d.ts",
10
+ "exports": {
11
+ ".":{
12
+ "types": "./dist/index.d.ts",
13
+ "import": "./dist/index.js",
14
+ "require": "./dist/index.cjs"
15
+ }
16
+ },
17
+ "files": ["dist"],
18
+ "scripts": {
19
+ "build": "tsup",
20
+ "dev": "tsup --watch",
21
+ "test": "vitest run",
22
+ "lint": "eslint src --ext .ts",
23
+ "typecheck": "tsc --noEmit",
24
+ "clean": "rimraf dist"
25
+ },
26
+ "dependencies": {
27
+ "@node-tenant/tenant-core": "^0.1.0"
28
+ },
29
+ "peerDependencies": {
30
+ "express": ">=4.0.0"
31
+ },
32
+ "devDependencies": {
33
+ "@types/express": "^4.17.21",
34
+ "express": "^4.18.3",
35
+ "rimraf": "^5.0.5",
36
+ "tsup": "^8.0.0",
37
+ "typescript": "^5.4.0",
38
+ "vitest": "^1.4.0"
39
+ }
40
+ }
41
+