@zerotal/tenancy 1.6.3 → 1.7.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.
Files changed (2) hide show
  1. package/api-surface.md +305 -0
  2. package/package.json +4 -3
package/api-surface.md ADDED
@@ -0,0 +1,305 @@
1
+ # @zerotal/tenancy — public API surface
2
+
3
+ <!-- AUTO-GENERATED by scripts/api-surface.ts. Do not edit by hand.
4
+ Run `bun run api:surface` to regenerate after an intentional API change. -->
5
+
6
+ ## . `(./src/index.ts)`
7
+
8
+ class AuthResolver = {
9
+ new (opts?: AuthResolverOptions): AuthResolver
10
+ readonly trusted: true
11
+ resolve: (http: HttpContext) => TenantResolverResult | null
12
+ }
13
+
14
+ class EnsureTenancyMiddleware = {
15
+ new (): EnsureTenancyMiddleware
16
+ static with: <T extends new (...args: any[]) => BaseMiddleware<any>, Opts = T extends new (...args: any[]) => BaseMiddleware<infer U> ? U : object>(this: T, options: DeepPartial<NoInfer<Opts>>) => new () => InstanceType<T>
17
+ afterResponse?: (ctx: HttpContext) => Promise<void>
18
+ handle: (_http: HttpContext, next: NextFn) => Promise<Response | void>
19
+ onError?: (ctx: HttpContext, error: Error) => Promise<void>
20
+ }
21
+
22
+ class HeaderResolver = {
23
+ new (header: string): HeaderResolver
24
+ resolve: (http: HttpContext) => TenantResolverResult | null
25
+ }
26
+
27
+ class NoActiveTenantError = {
28
+ new (message?: string): NoActiveTenantError
29
+ readonly code: string
30
+ readonly context?: Record<string, unknown> | undefined
31
+ readonly status: number
32
+ }
33
+
34
+ class PathResolver = {
35
+ new (opts?: PathResolverOptions): PathResolver
36
+ resolve: (http: HttpContext) => TenantResolverResult | null
37
+ }
38
+
39
+ class RouteParamResolver = {
40
+ new (opts?: RouteParamResolverOptions): RouteParamResolver
41
+ resolve: (http: HttpContext) => TenantResolverResult | null
42
+ }
43
+
44
+ class SubdomainResolver = {
45
+ new (domain: string): SubdomainResolver
46
+ resolve: (http: HttpContext) => TenantResolverResult | null
47
+ }
48
+
49
+ class Tenancy = {
50
+ new (): Tenancy
51
+ addMember: (userId: number, opts?: { admin?: boolean;}) => Promise<void>
52
+ all: () => Promise<TenantModel[]>
53
+ check: () => boolean
54
+ create: (data: Partial<Tenant> & { slug: string; name: string;}) => Promise<TenantModel>
55
+ current: () => Tenant | null
56
+ delete: () => Promise<void>
57
+ demote: (userId: number) => Promise<void>
58
+ exists: (slug: string) => Promise<boolean>
59
+ find: (slug: string) => Promise<TenantModel | null>
60
+ findById: (id: number) => Promise<TenantModel | null>
61
+ forId: <T>(id: number, cb: () => T | Promise<T>) => Promise<T>
62
+ forceDelete: () => Promise<void>
63
+ forceUpdate: (data: Partial<Tenant>) => Promise<TenantModel>
64
+ id: () => number | null
65
+ isMember: (userId?: number | null) => Promise<boolean>
66
+ isMemberAdmin: (userId?: number | null) => Promise<boolean>
67
+ member: <T = BaseModel>() => Promise<T | null>
68
+ memberCount: () => Promise<number>
69
+ members: <T = BaseModel>() => Promise<T[]>
70
+ onTenantDeleted: (hook: TenantDeletedHook) => void
71
+ promote: (userId: number) => Promise<void>
72
+ removeMember: (userId: number) => Promise<void>
73
+ run: <T>(tenant: Tenant, cb: () => T) => T
74
+ slug: () => string | null
75
+ update: (data: Partial<Tenant>) => Promise<TenantModel>
76
+ }
77
+
78
+ class TenancyConfigError = {
79
+ new (message: string): TenancyConfigError
80
+ readonly code: string
81
+ readonly context?: Record<string, unknown> | undefined
82
+ readonly status: number
83
+ }
84
+
85
+ class TenancyNotConfiguredError = {
86
+ new (message?: string): TenancyNotConfiguredError
87
+ headers?: Record<string, string>
88
+ readonly code: string
89
+ readonly context?: Record<string, unknown> | undefined
90
+ readonly status: number
91
+ }
92
+
93
+ class TenancyProvider = {
94
+ new (app: Application): TenancyProvider
95
+ static dependsOn?: (new (app: Application) => ServiceProvider)[]
96
+ static environments: AppEnvironment[]
97
+ static priority?: number
98
+ static provides: readonly ['tenancy']
99
+ static withConfig: (config: TenancyConfigShape) => typeof TenancyProvider
100
+ devProcesses: () => DevProcessDefinition[]
101
+ doctorChecks: () => DoctorCheck[]
102
+ onBooted: () => Promise<void>
103
+ onBooting: () => Promise<void>
104
+ onRegister: () => void
105
+ onRequestProcessed: (_ctx: HttpContext) => Promise<void>
106
+ onRequestReceived: (_ctx: HttpContext) => Promise<void>
107
+ onResponseSent: (_ctx: HttpContext) => Promise<void>
108
+ onStarted: () => Promise<void>
109
+ onStarting: () => Promise<void>
110
+ onStopped: () => Promise<void>
111
+ onStopping: () => Promise<void>
112
+ replContext: () => Record<string, unknown>
113
+ }
114
+
115
+ class TenantContext = {
116
+ new (): TenantContext
117
+ static get: () => Tenant
118
+ static id: () => number | null
119
+ static run: <T>(tenant: Tenant, callback: () => T) => T
120
+ static slug: () => string | null
121
+ static tryGet: () => Tenant | undefined
122
+ }
123
+
124
+ class TenantForbiddenError = {
125
+ new (message?: string): TenantForbiddenError
126
+ headers?: Record<string, string>
127
+ readonly code: string
128
+ readonly context?: Record<string, unknown> | undefined
129
+ readonly status: number
130
+ }
131
+
132
+ class TenantInactiveError = {
133
+ new (message?: string): TenantInactiveError
134
+ headers?: Record<string, string>
135
+ readonly code: string
136
+ readonly context?: Record<string, unknown> | undefined
137
+ readonly status: number
138
+ }
139
+
140
+ class TenantManager = {
141
+ new (opts: TenantManagerOptions): TenantManager
142
+ closeAll: () => void
143
+ connection: () => SQLInstance
144
+ connectionFor: (tenant: MultiDbTenant) => SQLInstance
145
+ evict: (tenant: Tenant) => void
146
+ warmUp: (tenant: MultiDbTenant) => void
147
+ }
148
+
149
+ class TenantModel = {
150
+ new (): TenantModel
151
+ static _isFillable: (key: string) => boolean
152
+ static _unscopedQuery: <T extends BaseModel>(this: typeof BaseModel & (new () => T)) => ModelQueryBuilder<T>
153
+ static addGlobalScope: <T extends BaseModel>(this: typeof BaseModel & (new () => T), name: string, callback: GlobalScopeCallback) => void
154
+ static all: <T extends BaseModel>(this: typeof BaseModel & (new () => T)) => Promise<T[]>
155
+ static appends: string[]
156
+ static bulkInsert: <T extends BaseModel>(this: typeof BaseModel & (new () => T), records: InsertPayload<T>[]) => Promise<number>
157
+ static casts?: Record<string, 'boolean' | 'date' | 'datetime' | 'array' | 'integer' | 'json' | 'float' | 'enum' | 'immutable_datetime' | 'encrypted' | 'encrypted:json' | `decimal:${number}` | { get?: (dbValue: unknown) => unknown; set?: (jsValue: unknown) => unknown;} | CastContract<unknown> | undefined>
158
+ static connection?: string
159
+ static count: <T extends BaseModel>(this: typeof BaseModel & (new () => T)) => Promise<number>
160
+ static create: <T extends BaseModel, F extends string = string>(this: (typeof BaseModel & (new () => T)) & { fillable?: readonly F[] | undefined;}, data: FillablePayload<T, F>) => Promise<T>
161
+ static createMany: <T extends BaseModel>(this: typeof BaseModel & (new () => T), records: InsertPayload<T>[]) => Promise<T[]>
162
+ static dispatchesEvents?: Record<string, new (model: unknown) => object>
163
+ static encryptable?: string[]
164
+ static fillable?: readonly string[]
165
+ static find: <T extends BaseModel>(this: typeof BaseModel & (new () => T), id: number | string) => Promise<T | null>
166
+ static findBy: <T extends BaseModel>(this: typeof BaseModel & (new () => T), column: string, value: unknown) => Promise<T | null>
167
+ static findMany: <T extends BaseModel>(this: typeof BaseModel & (new () => T), ids: (number | string)[]) => Promise<T[]>
168
+ static findOrFail: <T extends BaseModel>(this: typeof BaseModel & (new () => T), id: number | string) => Promise<T>
169
+ static findOrNew: <T extends BaseModel>(this: typeof BaseModel & (new () => T), id: number | string) => Promise<T>
170
+ static first: <T extends BaseModel>(this: typeof BaseModel & (new () => T)) => Promise<T | null>
171
+ static firstOrCreate: <T extends BaseModel>(this: typeof BaseModel & (new () => T), search: UpdatePayload<T>, create?: UpdatePayload<T>) => Promise<T>
172
+ static firstOrFail: <T extends BaseModel>(this: typeof BaseModel & (new () => T)) => Promise<T>
173
+ static firstOrNew: <T extends BaseModel>(this: typeof BaseModel & (new () => T), search: UpdatePayload<T>, values?: UpdatePayload<T>) => Promise<T>
174
+ static forceCreate: <T extends BaseModel>(this: typeof BaseModel & (new () => T), data: Record<string, unknown>) => Promise<T>
175
+ static fromRow: (row: Record<string, unknown>) => BaseModel
176
+ static guarded?: readonly string[]
177
+ static hashable?: string[]
178
+ static hidden: string[]
179
+ static implicitBinding?: boolean
180
+ static implicitBindingKey?: string
181
+ static latest: <T extends BaseModel>(this: typeof BaseModel & (new () => T), column?: string) => ModelQueryBuilder<T>
182
+ static loadCount: <T extends BaseModel>(this: typeof BaseModel, models: T[], relations: string | string[]) => Promise<T[]>
183
+ static massPrune: boolean
184
+ static observe: <T extends BaseModel>(this: typeof BaseModel & (new () => T), ObserverClass: new () => ModelObserver<T>) => void
185
+ static oldest: <T extends BaseModel>(this: typeof BaseModel & (new () => T), column?: string) => ModelQueryBuilder<T>
186
+ static orderBy: <T extends BaseModel>(this: typeof BaseModel & (new () => T), column: string, direction?: OrderDirection) => ModelQueryBuilder<T>
187
+ static paginate: <T extends BaseModel>(this: typeof BaseModel & (new () => T), perPage?: number, page?: number, pageName?: string) => Promise<PaginateResult<T>>
188
+ static primaryKey: string
189
+ static prunable?: <T extends BaseModel>(this: typeof BaseModel & (new () => T)) => ModelQueryBuilder<T>
190
+ static prune: <T extends BaseModel>(this: typeof BaseModel & (new () => T), chunkSize?: number) => Promise<number>
191
+ static query: <T extends BaseModel>(this: typeof BaseModel & (new () => T)) => ModelQueryBuilder<T>
192
+ static reactiveCasts: boolean
193
+ static registerConnection: (name: string, conn: SQLInstance, dialect?: Dialect) => void
194
+ static reguard: () => void
195
+ static removeGlobalScope: <T extends BaseModel>(this: typeof BaseModel & (new () => T), name: string) => void
196
+ static saveMany: <T extends BaseModel>(this: typeof BaseModel & (new () => T), models: T[]) => Promise<T[]>
197
+ static scope: <Args extends unknown[]>(fn: (query: QueryBuilder, ...args: Args) => void) => (...args: Args) => ScopeApplicator
198
+ static softDeletes: boolean
199
+ static table: string
200
+ static timestamps: boolean
201
+ static unguard: () => void
202
+ static unguarded: boolean
203
+ static updateOrCreate: <T extends BaseModel>(this: typeof BaseModel & (new () => T), search: UpdatePayload<T>, values?: UpdatePayload<T>) => Promise<T>
204
+ static upsert: <T extends BaseModel>(this: typeof BaseModel & (new () => T), data: InsertPayload<T>, conflictKeys: (keyof T & string)[], updateCols?: (keyof T & string)[]) => Promise<void>
205
+ static using: Compose
206
+ static visible: string[]
207
+ static where: { <T extends BaseModel>(this: typeof BaseModel & (new () => T), column: string, value: unknown): ModelQueryBuilder<T>; <T extends BaseModel>(this: typeof BaseModel & (new () => T), column: string, operator: WhereOperator, value: unknown): ModelQueryBuilder<T>;}
208
+ static whereIn: <T extends BaseModel>(this: typeof BaseModel & (new () => T), column: string, values: unknown[]) => ModelQueryBuilder<T>
209
+ static withoutGuard: <T>(callback: () => T | Promise<T>) => Promise<T>
210
+ static withoutTimestamps: <R>(callback: () => Promise<R> | R) => Promise<R>
211
+ $dirty: () => Record<string, unknown>
212
+ append: (...keys: string[]) => TenantModel
213
+ associate: (relation: string, model: BaseModel) => TenantModel
214
+ createdAt?: Date
215
+ database?: string | null
216
+ decrement: (column: 'id' | 'name' | 'createdAt' | 'updatedAt' | '__isZerotalModel' | 'fill' | 'forceFill' | 'save' | 'delete' | 'load' | 'loadMissing' | 'fresh' | 'refresh' | 'replicate' | 'touch' | 'is' | 'isNot' | 'increment' | 'decrement' | 'loadCount' | 'loadSum' | 'loadAvg' | 'loadMin' | 'loadMax' | 'makeHidden' | 'makeVisible' | 'append' | 'associate' | 'dissociate' | 'isDirty' | '$dirty' | 'markDirty' | 'toJSON' | 'database' | 'slug' | 'isActive', amount?: number) => Promise<TenantModel>
217
+ delete: () => Promise<void>
218
+ dissociate: (relation: string) => TenantModel
219
+ fill: (data: Partial<InsertPayload<TenantModel>>) => TenantModel
220
+ forceFill: (data: Record<string, unknown>) => TenantModel
221
+ fresh: () => Promise<TenantModel>
222
+ id: number
223
+ increment: (column: 'id' | 'name' | 'createdAt' | 'updatedAt' | '__isZerotalModel' | 'fill' | 'forceFill' | 'save' | 'delete' | 'load' | 'loadMissing' | 'fresh' | 'refresh' | 'replicate' | 'touch' | 'is' | 'isNot' | 'increment' | 'decrement' | 'loadCount' | 'loadSum' | 'loadAvg' | 'loadMin' | 'loadMax' | 'makeHidden' | 'makeVisible' | 'append' | 'associate' | 'dissociate' | 'isDirty' | '$dirty' | 'markDirty' | 'toJSON' | 'database' | 'slug' | 'isActive', amount?: number) => Promise<TenantModel>
224
+ is: (other: BaseModel | null | undefined) => boolean
225
+ isActive: boolean
226
+ isDirty: (column?: string) => boolean
227
+ isNot: (other: BaseModel | null | undefined) => boolean
228
+ load: (relations: string[]) => Promise<TenantModel>
229
+ loadAvg: (relation: string, column: string) => Promise<TenantModel>
230
+ loadCount: (relations: string | string[]) => Promise<TenantModel>
231
+ loadMax: (relation: string, column: string) => Promise<TenantModel>
232
+ loadMin: (relation: string, column: string) => Promise<TenantModel>
233
+ loadMissing: (relations: string[]) => Promise<TenantModel>
234
+ loadSum: (relation: string, column: string) => Promise<TenantModel>
235
+ makeHidden: (...keys: string[]) => TenantModel
236
+ makeVisible: (...keys: string[]) => TenantModel
237
+ markDirty: (property: keyof TenantModel) => TenantModel
238
+ name: string
239
+ readonly __isZerotalModel: true
240
+ refresh: () => Promise<TenantModel>
241
+ replicate: (except?: string[]) => TenantModel
242
+ save: () => Promise<TenantModel>
243
+ slug: string
244
+ toJSON: () => Record<string, unknown>
245
+ touch: () => Promise<TenantModel>
246
+ updatedAt?: Date
247
+ }
248
+
249
+ class TenantNotFoundError = {
250
+ new (message?: string): TenantNotFoundError
251
+ headers?: Record<string, string>
252
+ readonly code: string
253
+ readonly context?: Record<string, unknown> | undefined
254
+ readonly status: number
255
+ }
256
+
257
+ class TenantStoragePathError = {
258
+ new (path: string, slug: string): TenantStoragePathError
259
+ readonly code: string
260
+ readonly context?: Record<string, unknown> | undefined
261
+ readonly status: number
262
+ }
263
+
264
+ function TenancyConfig = (config: Partial<TenancyConfigShape> & Pick<TenancyConfigShape, 'resolvers'>) => TenancyConfigShape
265
+
266
+ function Tenantable = <TBase extends Constructor>(Base: TBase) => { new (...args: any[]): cls; prototype: Tenantable<any>.cls; tenantColumn: string;} & TBase
267
+
268
+ function tenantCache = (store?: string, cacheResolver?: CacheResolverLike) => CacheManagerLike
269
+
270
+ function tenantDisk = (disk?: string, storageManager?: StorageManagerLike) => StorageDriver
271
+
272
+ interface MultiDbTenant = {
273
+ database: string
274
+ id: number
275
+ isActive: boolean
276
+ name: string
277
+ slug: string
278
+ }
279
+
280
+ interface TenancyConfigShape = {
281
+ connect?: (tenant: MultiDbTenant) => SQLInstance
282
+ resolvers: TenantResolver[]
283
+ strategy: TenancyStrategy
284
+ tenantColumn?: string
285
+ }
286
+
287
+ interface TenantManagerOptions = {
288
+ connect: (tenant: MultiDbTenant) => SQLInstance
289
+ }
290
+
291
+ interface TenantResolver = {
292
+ readonly trusted?: boolean
293
+ resolve: (http: HttpContext) => TenantResolverResult | null
294
+ }
295
+
296
+ interface TenantResolverResult = {
297
+ by?: 'id' | 'slug'
298
+ identifier: string | number
299
+ }
300
+
301
+ type TenancyStrategy = 'single-database' | 'multi-database'
302
+
303
+ type Tenant = TenantRecord
304
+
305
+ type TenantDeletedHook = (tenant: Tenant) => void | Promise<void>
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@zerotal/tenancy",
3
- "version": "1.6.3",
3
+ "version": "1.7.0",
4
4
  "license": "MIT",
5
5
  "maturity": "stable",
6
6
  "private": false,
@@ -12,6 +12,7 @@
12
12
  },
13
13
  "files": [
14
14
  "CHANGELOG.md",
15
+ "api-surface.md",
15
16
  "src",
16
17
  "!src/**/*.test.ts",
17
18
  "!src/**/*.test.tsx",
@@ -29,8 +30,8 @@
29
30
  "typecheck": "tsc --noEmit"
30
31
  },
31
32
  "dependencies": {
32
- "@zerotal/core": "1.6.3",
33
- "@zerotal/orm": "1.6.3"
33
+ "@zerotal/core": "1.7.0",
34
+ "@zerotal/orm": "1.7.0"
34
35
  },
35
36
  "devDependencies": {
36
37
  "typescript": "^5.8.0"