@rpcbase/db 0.25.0 → 0.27.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.
@@ -0,0 +1,3 @@
1
+ import { AclAction, AclSubjectType, AppAbility } from './types';
2
+ export declare const getAccessibleByQuery: (ability: AppAbility, action: AclAction, subject: Exclude<AclSubjectType, "all">) => Record<string, unknown>;
3
+ //# sourceMappingURL=accessible.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"accessible.d.ts","sourceRoot":"","sources":["../../src/acl/accessible.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,SAAS,EAAE,cAAc,EAAE,UAAU,EAAE,MAAM,SAAS,CAAA;AAGpE,eAAO,MAAM,oBAAoB,GAC/B,SAAS,UAAU,EACnB,QAAQ,SAAS,EACjB,SAAS,OAAO,CAAC,cAAc,EAAE,KAAK,CAAC,KACtC,MAAM,CAAC,MAAM,EAAE,OAAO,CAExB,CAAA"}
@@ -0,0 +1,3 @@
1
+ import { AclContext, AppAbility } from './types';
2
+ export declare const buildAbility: (ctx: AclContext) => AppAbility;
3
+ //# sourceMappingURL=buildAbility.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"buildAbility.d.ts","sourceRoot":"","sources":["../../src/acl/buildAbility.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,UAAU,EAAE,UAAU,EAAE,MAAM,SAAS,CAAA;AAGrD,eAAO,MAAM,YAAY,GAAI,KAAK,UAAU,KAAG,UAc9C,CAAA"}
@@ -0,0 +1,3 @@
1
+ import { AclAction, AclSubjectMap, AclSubjectType, AppAbility } from './types';
2
+ export declare const can: <TSubject extends Exclude<AclSubjectType, "all">>(ability: AppAbility, action: AclAction, subjectType: TSubject, object?: Partial<AclSubjectMap[TSubject]> | null) => boolean;
3
+ //# sourceMappingURL=can.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"can.d.ts","sourceRoot":"","sources":["../../src/acl/can.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,SAAS,EAAc,aAAa,EAAE,cAAc,EAAE,UAAU,EAAE,MAAM,SAAS,CAAA;AAG/F,eAAO,MAAM,GAAG,GAAI,QAAQ,SAAS,OAAO,CAAC,cAAc,EAAE,KAAK,CAAC,EACjE,SAAS,UAAU,EACnB,QAAQ,SAAS,EACjB,aAAa,QAAQ,EACrB,SAAS,OAAO,CAAC,aAAa,CAAC,QAAQ,CAAC,CAAC,GAAG,IAAI,KAC/C,OAKF,CAAA"}
@@ -0,0 +1,7 @@
1
+ export * from './types';
2
+ export * from './registry';
3
+ export * from './buildAbility';
4
+ export * from './session';
5
+ export * from './accessible';
6
+ export * from './can';
7
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/acl/index.ts"],"names":[],"mappings":"AAAA,cAAc,SAAS,CAAA;AACvB,cAAc,YAAY,CAAA;AAC1B,cAAc,gBAAgB,CAAA;AAC9B,cAAc,WAAW,CAAA;AACzB,cAAc,cAAc,CAAA;AAC5B,cAAc,OAAO,CAAA"}
@@ -0,0 +1,10 @@
1
+ import { AbilityBuilder } from '@casl/ability';
2
+ import { AclContext, AclSubjectType, AppAbility } from './types';
3
+ export type AclPolicy = {
4
+ subject: Exclude<AclSubjectType, "all">;
5
+ define: (builder: AbilityBuilder<AppAbility>, ctx: AclContext) => void;
6
+ };
7
+ export declare const registerPolicy: (policy: AclPolicy) => void;
8
+ export declare const registerPoliciesFromModules: (modules: Record<string, unknown>) => void;
9
+ export declare const getRegisteredPolicies: () => Array<AclPolicy["define"]>;
10
+ //# sourceMappingURL=registry.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"registry.d.ts","sourceRoot":"","sources":["../../src/acl/registry.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,eAAe,CAAA;AAEnD,OAAO,KAAK,EAAE,UAAU,EAAE,cAAc,EAAE,UAAU,EAAE,MAAM,SAAS,CAAA;AAGrE,MAAM,MAAM,SAAS,GAAG;IACtB,OAAO,EAAE,OAAO,CAAC,cAAc,EAAE,KAAK,CAAC,CAAA;IACvC,MAAM,EAAE,CAAC,OAAO,EAAE,cAAc,CAAC,UAAU,CAAC,EAAE,GAAG,EAAE,UAAU,KAAK,IAAI,CAAA;CACvE,CAAA;AAuBD,eAAO,MAAM,cAAc,GAAI,QAAQ,SAAS,KAAG,IAIlD,CAAA;AAED,eAAO,MAAM,2BAA2B,GAAI,SAAS,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,KAAG,IAmB9E,CAAA;AAED,eAAO,MAAM,qBAAqB,QAAO,KAAK,CAAC,SAAS,CAAC,QAAQ,CAAC,CAMjE,CAAA"}
@@ -0,0 +1,17 @@
1
+ import { AppAbility } from './types';
2
+ type SessionUserLike = {
3
+ id?: unknown;
4
+ signedInTenants?: unknown;
5
+ tenantRoles?: unknown;
6
+ };
7
+ type SessionLike = {
8
+ user?: SessionUserLike;
9
+ };
10
+ export declare const getTenantRolesFromSessionUser: (user: unknown, tenantId: string) => string[];
11
+ export declare const buildAbilityFromSession: ({ tenantId, session, claims, }: {
12
+ tenantId: string;
13
+ session: SessionLike | null | undefined;
14
+ claims?: Record<string, unknown>;
15
+ }) => AppAbility;
16
+ export {};
17
+ //# sourceMappingURL=session.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"session.d.ts","sourceRoot":"","sources":["../../src/acl/session.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,UAAU,EAAyB,MAAM,SAAS,CAAA;AAGhE,KAAK,eAAe,GAAG;IACrB,EAAE,CAAC,EAAE,OAAO,CAAA;IACZ,eAAe,CAAC,EAAE,OAAO,CAAA;IACzB,WAAW,CAAC,EAAE,OAAO,CAAA;CACtB,CAAA;AAED,KAAK,WAAW,GAAG;IACjB,IAAI,CAAC,EAAE,eAAe,CAAA;CACvB,CAAA;AA+BD,eAAO,MAAM,6BAA6B,GAAI,MAAM,OAAO,EAAE,UAAU,MAAM,KAAG,MAAM,EAKrF,CAAA;AAED,eAAO,MAAM,uBAAuB,GAAI,gCAIrC;IACD,QAAQ,EAAE,MAAM,CAAA;IAChB,OAAO,EAAE,WAAW,GAAG,IAAI,GAAG,SAAS,CAAA;IACvC,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;CACjC,KAAG,UAuBH,CAAA"}
@@ -0,0 +1,22 @@
1
+ import { ForcedSubject, MongoAbility } from '@casl/ability';
2
+ export type AclAction = "manage" | "create" | "read" | "update" | "delete";
3
+ export interface AclSubjectMap {
4
+ RBUploadSession: Record<string, unknown>;
5
+ RBNotification: Record<string, unknown>;
6
+ RBNotificationSettings: Record<string, unknown>;
7
+ }
8
+ export type AclSubjectType = keyof AclSubjectMap | "all";
9
+ type AclSubjectObject = {
10
+ [K in keyof AclSubjectMap]: ForcedSubject<K> & Partial<AclSubjectMap[K]>;
11
+ }[keyof AclSubjectMap];
12
+ export type AclSubject = AclSubjectType | AclSubjectObject;
13
+ export type AppAbility = MongoAbility<[AclAction, AclSubject]>;
14
+ export type TenantRolesByTenantId = Record<string, string[]>;
15
+ export type AclContext = {
16
+ tenantId: string;
17
+ userId: string | null;
18
+ roles: string[];
19
+ claims?: Record<string, unknown>;
20
+ };
21
+ export {};
22
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/acl/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,YAAY,EAAE,MAAM,eAAe,CAAA;AAGhE,MAAM,MAAM,SAAS,GACjB,QAAQ,GACR,QAAQ,GACR,MAAM,GACN,QAAQ,GACR,QAAQ,CAAA;AAEZ,MAAM,WAAW,aAAa;IAC5B,eAAe,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;IACxC,cAAc,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;IACvC,sBAAsB,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;CAChD;AAED,MAAM,MAAM,cAAc,GAAG,MAAM,aAAa,GAAG,KAAK,CAAA;AAExD,KAAK,gBAAgB,GAAG;KACrB,CAAC,IAAI,MAAM,aAAa,GAAG,aAAa,CAAC,CAAC,CAAC,GAAG,OAAO,CAAC,aAAa,CAAC,CAAC,CAAC,CAAC;CACzE,CAAC,MAAM,aAAa,CAAC,CAAA;AAEtB,MAAM,MAAM,UAAU,GAAG,cAAc,GAAG,gBAAgB,CAAA;AAE1D,MAAM,MAAM,UAAU,GAAG,YAAY,CAAC,CAAC,SAAS,EAAE,UAAU,CAAC,CAAC,CAAA;AAE9D,MAAM,MAAM,qBAAqB,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,EAAE,CAAC,CAAA;AAE5D,MAAM,MAAM,UAAU,GAAG;IACvB,QAAQ,EAAE,MAAM,CAAA;IAChB,MAAM,EAAE,MAAM,GAAG,IAAI,CAAA;IACrB,KAAK,EAAE,MAAM,EAAE,CAAA;IACf,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;CACjC,CAAA"}
package/dist/acl.d.ts ADDED
@@ -0,0 +1,2 @@
1
+ export * from './acl/index';
2
+ //# sourceMappingURL=acl.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"acl.d.ts","sourceRoot":"","sources":["../src/acl.ts"],"names":[],"mappings":"AAAA,cAAc,aAAa,CAAA"}
@@ -6,8 +6,9 @@ type ExtractModelNamesFromSchemas<TModules> = {
6
6
  }[keyof TModules] & string;
7
7
  type FrameworkModelName = ExtractModelNamesFromSchemas<typeof frameworkSchemas>;
8
8
  type WithoutRbPrefix<TName extends string> = TName extends `RB${string}` ? never : TName;
9
- export type TenantModelName<TModules extends ModelModules> = WithoutRbPrefix<ExtractModelNamesFromSchemas<TModules>> | WithoutRbPrefix<FrameworkModelName>;
10
- export type RbModelName = ExtractModelNamesFromSchemas<typeof frameworkSchemas> extends infer Name ? Name extends string ? Name extends `RB${string}` ? Name extends "RBRtsChange" | "RBRtsCounter" | "RBUploadSession" | "RBUploadChunk" ? never : Name : never : never : never;
9
+ type TenantInternalRbModelName = "RBUploadSession" | "RBUploadChunk" | "RBNotification" | "RBNotificationSettings";
10
+ export type TenantModelName<TModules extends ModelModules> = WithoutRbPrefix<ExtractModelNamesFromSchemas<TModules>> | WithoutRbPrefix<FrameworkModelName> | TenantInternalRbModelName;
11
+ export type RbModelName = ExtractModelNamesFromSchemas<typeof frameworkSchemas> extends infer Name ? Name extends string ? Name extends `RB${string}` ? Name extends "RBRtsChange" | "RBRtsCounter" | "RBUploadSession" | "RBUploadChunk" | "RBNotification" | "RBNotificationSettings" ? never : Name : never : never : never;
11
12
  export type ModelsClient<TModules extends ModelModules> = {
12
13
  register: (modules: TModules) => void;
13
14
  get: (modelName: TenantModelName<TModules>, ctx: LoadModelCtx) => ReturnType<typeof loadModel>;
@@ -1 +1 @@
1
- {"version":3,"file":"createModels.d.ts","sourceRoot":"","sources":["../src/createModels.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,aAAa,CAAA;AAC/C,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,kBAAkB,CAAA;AACpD,OAAO,KAAK,KAAK,gBAAgB,MAAM,UAAU,CAAA;AACjD,OAAO,EAAE,SAAS,EAAE,WAAW,EAAE,MAAM,aAAa,CAAA;AAIpD,KAAK,4BAA4B,CAAC,QAAQ,IAAI;KAC3C,CAAC,IAAI,MAAM,QAAQ,CAAC,CAAC,GAAG,CAAC,SAAS,GAAG,MAAM,IAAI,QAAQ,GAAG,IAAI,GAAG,KAAK;CACxE,CAAC,MAAM,QAAQ,CAAC,GAAG,MAAM,CAAA;AAE1B,KAAK,kBAAkB,GAAG,4BAA4B,CAAC,OAAO,gBAAgB,CAAC,CAAA;AAE/E,KAAK,eAAe,CAAC,KAAK,SAAS,MAAM,IAAI,KAAK,SAAS,KAAK,MAAM,EAAE,GAAG,KAAK,GAAG,KAAK,CAAA;AAExF,MAAM,MAAM,eAAe,CAAC,QAAQ,SAAS,YAAY,IACrD,eAAe,CAAC,4BAA4B,CAAC,QAAQ,CAAC,CAAC,GACvD,eAAe,CAAC,kBAAkB,CAAC,CAAA;AAEvC,MAAM,MAAM,WAAW,GAAG,4BAA4B,CAAC,OAAO,gBAAgB,CAAC,SAAS,MAAM,IAAI,GAC9F,IAAI,SAAS,MAAM,GACjB,IAAI,SAAS,KAAK,MAAM,EAAE,GACxB,IAAI,SAAS,aAAa,GAAG,cAAc,GAAG,iBAAiB,GAAG,eAAe,GAC/E,KAAK,GACL,IAAI,GACN,KAAK,GACP,KAAK,GACP,KAAK,CAAA;AAET,MAAM,MAAM,YAAY,CAAC,QAAQ,SAAS,YAAY,IAAI;IACxD,QAAQ,EAAE,CAAC,OAAO,EAAE,QAAQ,KAAK,IAAI,CAAA;IACrC,GAAG,EAAE,CAAC,SAAS,EAAE,eAAe,CAAC,QAAQ,CAAC,EAAE,GAAG,EAAE,YAAY,KAAK,UAAU,CAAC,OAAO,SAAS,CAAC,CAAA;IAC9F,KAAK,EAAE,CAAC,SAAS,EAAE,WAAW,EAAE,GAAG,EAAE,YAAY,KAAK,UAAU,CAAC,OAAO,WAAW,CAAC,CAAA;CACrF,CAAA;AAED,eAAO,MAAM,YAAY,GAAI,QAAQ,SAAS,YAAY,EAAE,SAAS,QAAQ,KAAG,YAAY,CAAC,QAAQ,CAQpG,CAAA"}
1
+ {"version":3,"file":"createModels.d.ts","sourceRoot":"","sources":["../src/createModels.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,aAAa,CAAA;AAC/C,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,kBAAkB,CAAA;AACpD,OAAO,KAAK,KAAK,gBAAgB,MAAM,UAAU,CAAA;AACjD,OAAO,EAAE,SAAS,EAAE,WAAW,EAAE,MAAM,aAAa,CAAA;AAIpD,KAAK,4BAA4B,CAAC,QAAQ,IAAI;KAC3C,CAAC,IAAI,MAAM,QAAQ,CAAC,CAAC,GAAG,CAAC,SAAS,GAAG,MAAM,IAAI,QAAQ,GAAG,IAAI,GAAG,KAAK;CACxE,CAAC,MAAM,QAAQ,CAAC,GAAG,MAAM,CAAA;AAE1B,KAAK,kBAAkB,GAAG,4BAA4B,CAAC,OAAO,gBAAgB,CAAC,CAAA;AAE/E,KAAK,eAAe,CAAC,KAAK,SAAS,MAAM,IAAI,KAAK,SAAS,KAAK,MAAM,EAAE,GAAG,KAAK,GAAG,KAAK,CAAA;AAExF,KAAK,yBAAyB,GAC1B,iBAAiB,GACjB,eAAe,GACf,gBAAgB,GAChB,wBAAwB,CAAA;AAE5B,MAAM,MAAM,eAAe,CAAC,QAAQ,SAAS,YAAY,IACrD,eAAe,CAAC,4BAA4B,CAAC,QAAQ,CAAC,CAAC,GACvD,eAAe,CAAC,kBAAkB,CAAC,GACnC,yBAAyB,CAAA;AAE7B,MAAM,MAAM,WAAW,GAAG,4BAA4B,CAAC,OAAO,gBAAgB,CAAC,SAAS,MAAM,IAAI,GAC9F,IAAI,SAAS,MAAM,GACjB,IAAI,SAAS,KAAK,MAAM,EAAE,GACxB,IAAI,SACF,aAAa,GACb,cAAc,GACd,iBAAiB,GACjB,eAAe,GACf,gBAAgB,GAChB,wBAAwB,GACxB,KAAK,GACL,IAAI,GACN,KAAK,GACP,KAAK,GACP,KAAK,CAAA;AAET,MAAM,MAAM,YAAY,CAAC,QAAQ,SAAS,YAAY,IAAI;IACxD,QAAQ,EAAE,CAAC,OAAO,EAAE,QAAQ,KAAK,IAAI,CAAA;IACrC,GAAG,EAAE,CAAC,SAAS,EAAE,eAAe,CAAC,QAAQ,CAAC,EAAE,GAAG,EAAE,YAAY,KAAK,UAAU,CAAC,OAAO,SAAS,CAAC,CAAA;IAC9F,KAAK,EAAE,CAAC,SAAS,EAAE,WAAW,EAAE,GAAG,EAAE,YAAY,KAAK,UAAU,CAAC,OAAO,WAAW,CAAC,CAAA;CACrF,CAAA;AAED,eAAO,MAAM,YAAY,GAAI,QAAQ,SAAS,YAAY,EAAE,SAAS,QAAQ,KAAG,YAAY,CAAC,QAAQ,CAQpG,CAAA"}
package/dist/index.d.ts CHANGED
@@ -3,4 +3,5 @@ export * from './schema';
3
3
  export * from './createModels';
4
4
  export * from './loadModel';
5
5
  export * from './tenantFilesystemDb';
6
+ export * from './acl';
6
7
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,UAAU,CAAA;AACxB,cAAc,UAAU,CAAA;AACxB,cAAc,gBAAgB,CAAA;AAC9B,cAAc,aAAa,CAAA;AAC3B,cAAc,sBAAsB,CAAA"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,UAAU,CAAA;AACxB,cAAc,UAAU,CAAA;AACxB,cAAc,gBAAgB,CAAA;AAC9B,cAAc,aAAa,CAAA;AAC3B,cAAc,sBAAsB,CAAA;AACpC,cAAc,OAAO,CAAA"}
package/dist/index.js CHANGED
@@ -3,12 +3,15 @@ import { z, ZodMap, ZodRecord, ZodAny, ZodUnion, ZodNullable, ZodOptional, ZodDe
3
3
  export * from "zod";
4
4
  import { z as z2 } from "zod";
5
5
  import assert from "assert";
6
+ import { accessibleBy, accessibleRecordsPlugin } from "@casl/mongoose";
7
+ import { AbilityBuilder, createMongoAbility, subject } from "@casl/ability";
6
8
  const ZRBUser = z.object({
7
9
  email: z.string().email().optional(),
8
10
  password: z.string(),
9
11
  name: z.string().optional(),
10
12
  phone: z.string().optional(),
11
13
  tenants: z.array(z.string()),
14
+ tenantRoles: z.record(z.string(), z.array(z.string())).optional(),
12
15
  emailVerificationCode: z.string().length(6).optional(),
13
16
  emailVerificationExpiresAt: z.date().optional()
14
17
  });
@@ -18,6 +21,7 @@ const RBUserSchema = new Schema({
18
21
  password: { type: String, required: true },
19
22
  name: String,
20
23
  tenants: { type: [String], index: true, required: true },
24
+ tenantRoles: { type: Map, of: [String], required: false, default: {} },
21
25
  emailVerificationCode: { type: String, required: false },
22
26
  emailVerificationExpiresAt: { type: Date, required: false }
23
27
  }, { collection: "users" });
@@ -244,6 +248,23 @@ const RBUploadSessionSchema = new Schema(
244
248
  }
245
249
  );
246
250
  RBUploadSessionSchema.index({ expiresAt: 1 }, { expireAfterSeconds: 0 });
251
+ const RBUploadSessionPolicy = {
252
+ subject: "RBUploadSession",
253
+ define: (builder, ctx) => {
254
+ builder.can("create", "RBUploadSession");
255
+ if (ctx.userId) {
256
+ builder.can("read", "RBUploadSession", { userId: ctx.userId });
257
+ builder.can("update", "RBUploadSession", { userId: ctx.userId });
258
+ builder.can("delete", "RBUploadSession", { userId: ctx.userId });
259
+ }
260
+ const uploadKeyHash = typeof ctx.claims?.uploadKeyHash === "string" ? ctx.claims.uploadKeyHash.trim() : "";
261
+ if (uploadKeyHash) {
262
+ builder.can("read", "RBUploadSession", { ownerKeyHash: uploadKeyHash });
263
+ builder.can("update", "RBUploadSession", { ownerKeyHash: uploadKeyHash });
264
+ builder.can("delete", "RBUploadSession", { ownerKeyHash: uploadKeyHash });
265
+ }
266
+ }
267
+ };
247
268
  const ZRBUploadChunk = z.object({
248
269
  uploadId: z.string(),
249
270
  index: z.number().int().min(0),
@@ -270,16 +291,124 @@ const RBUploadChunkSchema = new Schema(
270
291
  );
271
292
  RBUploadChunkSchema.index({ uploadId: 1, index: 1 }, { unique: true });
272
293
  RBUploadChunkSchema.index({ expiresAt: 1 }, { expireAfterSeconds: 0 });
294
+ const ZRBNotification = z.object({
295
+ userId: z.string(),
296
+ topic: z.string().optional(),
297
+ title: z.string(),
298
+ body: z.string().optional(),
299
+ url: z.string().optional(),
300
+ createdAt: z.date(),
301
+ seenAt: z.date().optional(),
302
+ readAt: z.date().optional(),
303
+ archivedAt: z.date().optional(),
304
+ metadata: z.record(z.string(), z.unknown()).optional()
305
+ });
306
+ const TTL_90_DAYS_S = 60 * 60 * 24 * 90;
307
+ const RBNotificationSchema = new Schema(
308
+ {
309
+ userId: { type: String, required: true, index: true },
310
+ topic: { type: String, required: false, index: true },
311
+ title: { type: String, required: true },
312
+ body: { type: String, required: false },
313
+ url: { type: String, required: false },
314
+ createdAt: { type: Date, required: true, default: Date.now, index: true },
315
+ seenAt: { type: Date, required: false, index: true },
316
+ readAt: { type: Date, required: false, index: true },
317
+ archivedAt: { type: Date, required: false },
318
+ metadata: { type: Schema.Types.Mixed, required: false }
319
+ },
320
+ {
321
+ versionKey: false,
322
+ collection: "notifications"
323
+ }
324
+ );
325
+ RBNotificationSchema.index({ userId: 1, archivedAt: 1, createdAt: -1 });
326
+ RBNotificationSchema.index({ userId: 1, seenAt: 1, archivedAt: 1, createdAt: -1 });
327
+ RBNotificationSchema.index({ userId: 1, readAt: 1, archivedAt: 1, createdAt: -1 });
328
+ RBNotificationSchema.index({ archivedAt: 1 }, { expireAfterSeconds: TTL_90_DAYS_S });
329
+ const RBNotificationPolicy = {
330
+ subject: "RBNotification",
331
+ define: (builder, ctx) => {
332
+ if (!ctx.userId) return;
333
+ builder.can("create", "RBNotification");
334
+ builder.can("read", "RBNotification", { userId: ctx.userId });
335
+ builder.can("update", "RBNotification", { userId: ctx.userId });
336
+ builder.can("delete", "RBNotification", { userId: ctx.userId });
337
+ }
338
+ };
339
+ const ZRBNotificationDigestFrequency = z.enum(["off", "daily", "weekly"]);
340
+ const ZRBNotificationTopicPreference = z.object({
341
+ topic: z.string(),
342
+ inApp: z.boolean(),
343
+ emailDigest: z.boolean(),
344
+ push: z.boolean()
345
+ });
346
+ const ZRBNotificationSettings = z.object({
347
+ userId: z.string(),
348
+ digestFrequency: ZRBNotificationDigestFrequency,
349
+ topicPreferences: z.array(ZRBNotificationTopicPreference).optional(),
350
+ lastDigestSentAt: z.date().optional()
351
+ });
352
+ const TopicPreferenceSchema = new Schema(
353
+ {
354
+ topic: { type: String, required: true },
355
+ inApp: { type: Boolean, required: true, default: true },
356
+ emailDigest: { type: Boolean, required: true, default: true },
357
+ push: { type: Boolean, required: true, default: false }
358
+ },
359
+ { _id: false }
360
+ );
361
+ const RBNotificationSettingsSchema = new Schema(
362
+ {
363
+ userId: { type: String, required: true },
364
+ digestFrequency: {
365
+ type: String,
366
+ required: true,
367
+ enum: ZRBNotificationDigestFrequency.options,
368
+ default: "weekly"
369
+ },
370
+ topicPreferences: {
371
+ type: [TopicPreferenceSchema],
372
+ default: []
373
+ },
374
+ lastDigestSentAt: { type: Date, required: false }
375
+ },
376
+ {
377
+ versionKey: false,
378
+ collection: "notificationSettings",
379
+ timestamps: true
380
+ }
381
+ );
382
+ RBNotificationSettingsSchema.index({ userId: 1 }, { unique: true });
383
+ RBNotificationSettingsSchema.index({ userId: 1, "topicPreferences.topic": 1 });
384
+ const RBNotificationSettingsPolicy = {
385
+ subject: "RBNotificationSettings",
386
+ define: (builder, ctx) => {
387
+ if (!ctx.userId) return;
388
+ builder.can("create", "RBNotificationSettings");
389
+ builder.can("read", "RBNotificationSettings", { userId: ctx.userId });
390
+ builder.can("update", "RBNotificationSettings", { userId: ctx.userId });
391
+ }
392
+ };
273
393
  const frameworkSchemas = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
274
394
  __proto__: null,
395
+ RBNotificationPolicy,
396
+ RBNotificationSchema,
397
+ RBNotificationSettingsPolicy,
398
+ RBNotificationSettingsSchema,
275
399
  RBRtsChangeSchema,
276
400
  RBRtsCounterSchema,
277
401
  RBTenantSchema,
278
402
  RBTenantSubscriptionEventSchema,
279
403
  RBTenantSubscriptionSchema,
280
404
  RBUploadChunkSchema,
405
+ RBUploadSessionPolicy,
281
406
  RBUploadSessionSchema,
282
407
  RBUserSchema,
408
+ ZRBNotification,
409
+ ZRBNotificationDigestFrequency,
410
+ ZRBNotificationSettings,
411
+ ZRBNotificationTopicPreference,
283
412
  ZRBRtsChange,
284
413
  ZRBRtsChangeOp,
285
414
  ZRBRtsCounter,
@@ -1176,8 +1305,128 @@ const rtsChangeLogPlugin = (schema) => {
1176
1305
  }
1177
1306
  });
1178
1307
  };
1308
+ const POLICIES_GLOBAL_KEY = /* @__PURE__ */ Symbol.for("@rpcbase/db/acl/policiesBySubject");
1309
+ const getGlobalPoliciesMap = () => {
1310
+ const store = globalThis;
1311
+ const existing = store[POLICIES_GLOBAL_KEY];
1312
+ if (existing instanceof Map) {
1313
+ return existing;
1314
+ }
1315
+ const created = /* @__PURE__ */ new Map();
1316
+ store[POLICIES_GLOBAL_KEY] = created;
1317
+ return created;
1318
+ };
1319
+ const policiesBySubject = getGlobalPoliciesMap();
1320
+ const isPolicy = (value) => {
1321
+ if (!value || typeof value !== "object") return false;
1322
+ const maybe = value;
1323
+ return typeof maybe.subject === "string" && typeof maybe.define === "function";
1324
+ };
1325
+ const registerPolicy = (policy) => {
1326
+ const set = policiesBySubject.get(policy.subject) ?? /* @__PURE__ */ new Set();
1327
+ set.add(policy.define);
1328
+ policiesBySubject.set(policy.subject, set);
1329
+ };
1330
+ const registerPoliciesFromModules = (modules) => {
1331
+ for (const [exportName, value] of Object.entries(modules)) {
1332
+ if (!isPolicy(value)) continue;
1333
+ if (!exportName.endsWith("Policy")) {
1334
+ throw new Error(
1335
+ `Invalid policy export name "${exportName}". Policies must be exported as "<ModelName>Policy".`
1336
+ );
1337
+ }
1338
+ const expectedSubject = exportName.slice(0, -"Policy".length);
1339
+ if (value.subject !== expectedSubject) {
1340
+ throw new Error(
1341
+ `Invalid policy "${exportName}": expected subject "${expectedSubject}", got "${value.subject}".`
1342
+ );
1343
+ }
1344
+ registerPolicy(value);
1345
+ }
1346
+ };
1347
+ const getRegisteredPolicies = () => {
1348
+ const out = [];
1349
+ for (const set of policiesBySubject.values()) {
1350
+ for (const fn of set) out.push(fn);
1351
+ }
1352
+ return out;
1353
+ };
1354
+ const buildAbility = (ctx) => {
1355
+ const builder = new AbilityBuilder(createMongoAbility);
1356
+ const { can: can2 } = builder;
1357
+ if (ctx.roles.includes("owner") || ctx.roles.includes("admin")) {
1358
+ can2("manage", "all");
1359
+ }
1360
+ for (const define of getRegisteredPolicies()) {
1361
+ define(builder, ctx);
1362
+ }
1363
+ return builder.build();
1364
+ };
1365
+ const normalizeRole = (raw) => {
1366
+ if (typeof raw !== "string") return null;
1367
+ const normalized = raw.trim();
1368
+ return normalized ? normalized : null;
1369
+ };
1370
+ const normalizeRoles = (raw) => {
1371
+ if (Array.isArray(raw)) {
1372
+ return raw.map(normalizeRole).filter((r) => Boolean(r));
1373
+ }
1374
+ const role = normalizeRole(raw);
1375
+ return role ? [role] : [];
1376
+ };
1377
+ const normalizeRolesByTenantId = (raw) => {
1378
+ if (!raw || typeof raw !== "object") return null;
1379
+ if (raw instanceof Map) {
1380
+ return Object.fromEntries(Array.from(raw.entries()).map(([key, value]) => [String(key), normalizeRoles(value)]));
1381
+ }
1382
+ const obj = raw;
1383
+ const out = {};
1384
+ for (const [key, value] of Object.entries(obj)) {
1385
+ const tenantId = String(key).trim();
1386
+ if (!tenantId) continue;
1387
+ out[tenantId] = normalizeRoles(value);
1388
+ }
1389
+ return out;
1390
+ };
1391
+ const getTenantRolesFromSessionUser = (user, tenantId) => {
1392
+ if (!user || typeof user !== "object") return [];
1393
+ const rolesByTenantId = normalizeRolesByTenantId(user.tenantRoles);
1394
+ if (!rolesByTenantId) return [];
1395
+ return rolesByTenantId[tenantId]?.filter(Boolean) ?? [];
1396
+ };
1397
+ const buildAbilityFromSession = ({
1398
+ tenantId,
1399
+ session,
1400
+ claims
1401
+ }) => {
1402
+ const user = session?.user;
1403
+ const userId = typeof user?.id === "string" ? user.id.trim() : "";
1404
+ const rolesByTenantId = normalizeRolesByTenantId(user?.tenantRoles);
1405
+ const hasExplicitTenantEntry = Boolean(
1406
+ rolesByTenantId && Object.prototype.hasOwnProperty.call(rolesByTenantId, tenantId)
1407
+ );
1408
+ const signedInTenantsRaw = user?.signedInTenants;
1409
+ const signedInTenants = Array.isArray(signedInTenantsRaw) ? signedInTenantsRaw.map(String) : [];
1410
+ const roles = hasExplicitTenantEntry ? rolesByTenantId[tenantId] ?? [] : userId && signedInTenants.includes(tenantId) ? ["owner"] : getTenantRolesFromSessionUser(user, tenantId);
1411
+ return buildAbility({
1412
+ tenantId,
1413
+ userId: userId || null,
1414
+ roles,
1415
+ claims
1416
+ });
1417
+ };
1418
+ const getAccessibleByQuery = (ability, action, subject2) => {
1419
+ return accessibleBy(ability, action).ofType(subject2);
1420
+ };
1421
+ const can = (ability, action, subjectType, object) => {
1422
+ if (object && typeof object === "object") {
1423
+ return ability.can(action, subject(subjectType, object));
1424
+ }
1425
+ return ability.can(action, subjectType);
1426
+ };
1179
1427
  const RTS_CHANGELOG_EXCLUDED_MODELS = /* @__PURE__ */ new Set(["RBRtsChange", "RBRtsCounter"]);
1180
1428
  const rtsChangeLogApplied = /* @__PURE__ */ new WeakSet();
1429
+ const accessibleRecordsApplied = /* @__PURE__ */ new WeakSet();
1181
1430
  let cachedModels = null;
1182
1431
  const isRtsChangelogExcludedModelName = (name) => name.startsWith("RB") || RTS_CHANGELOG_EXCLUDED_MODELS.has(name);
1183
1432
  const assertSchema = (exportName, value) => {
@@ -1193,6 +1442,10 @@ const assertSchema = (exportName, value) => {
1193
1442
  const buildAppModels = (modules) => Object.entries(modules).filter(([key]) => key.endsWith("Schema")).map(([key, schemaValue]) => {
1194
1443
  const schema = assertSchema(key, schemaValue);
1195
1444
  const name = key.replace(/Schema$/, "");
1445
+ if (!accessibleRecordsApplied.has(schema)) {
1446
+ schema.plugin(accessibleRecordsPlugin);
1447
+ accessibleRecordsApplied.add(schema);
1448
+ }
1196
1449
  if (!isRtsChangelogExcludedModelName(name)) {
1197
1450
  if (!rtsChangeLogApplied.has(schema)) {
1198
1451
  schema.plugin(rtsChangeLogPlugin);
@@ -1207,6 +1460,10 @@ const buildAppModels = (modules) => Object.entries(modules).filter(([key]) => ke
1207
1460
  const buildFrameworkModels = () => Object.entries(frameworkSchemas).filter(([key]) => key.endsWith("Schema")).map(([key, schemaValue]) => {
1208
1461
  const schema = assertSchema(key, schemaValue);
1209
1462
  const name = key.replace(/Schema$/, "");
1463
+ if (!accessibleRecordsApplied.has(schema)) {
1464
+ schema.plugin(accessibleRecordsPlugin);
1465
+ accessibleRecordsApplied.add(schema);
1466
+ }
1210
1467
  if (!isRtsChangelogExcludedModelName(name)) {
1211
1468
  if (!rtsChangeLogApplied.has(schema)) {
1212
1469
  schema.plugin(rtsChangeLogPlugin);
@@ -1227,6 +1484,8 @@ const buildModels = (modules) => {
1227
1484
  }, {});
1228
1485
  };
1229
1486
  const registerModels = (modules) => {
1487
+ registerPoliciesFromModules(frameworkSchemas);
1488
+ registerPoliciesFromModules(modules);
1230
1489
  cachedModels = buildModels(modules);
1231
1490
  };
1232
1491
  const getRegisteredModels = () => {
@@ -1240,7 +1499,9 @@ const TENANT_INTERNAL_MODEL_NAMES = /* @__PURE__ */ new Set([
1240
1499
  "RBRtsChange",
1241
1500
  "RBRtsCounter",
1242
1501
  "RBUploadSession",
1243
- "RBUploadChunk"
1502
+ "RBUploadChunk",
1503
+ "RBNotification",
1504
+ "RBNotificationSettings"
1244
1505
  ]);
1245
1506
  const assertTenantModelName = (modelName) => {
1246
1507
  if (TENANT_INTERNAL_MODEL_NAMES.has(modelName)) return;
@@ -1302,14 +1563,23 @@ const getTenantFilesystemDbFromCtx = async (ctx) => {
1302
1563
  };
1303
1564
  export {
1304
1565
  LANGUAGE_CODE_REGEX,
1566
+ RBNotificationPolicy,
1567
+ RBNotificationSchema,
1568
+ RBNotificationSettingsPolicy,
1569
+ RBNotificationSettingsSchema,
1305
1570
  RBRtsChangeSchema,
1306
1571
  RBRtsCounterSchema,
1307
1572
  RBTenantSchema,
1308
1573
  RBTenantSubscriptionEventSchema,
1309
1574
  RBTenantSubscriptionSchema,
1310
1575
  RBUploadChunkSchema,
1576
+ RBUploadSessionPolicy,
1311
1577
  RBUploadSessionSchema,
1312
1578
  RBUserSchema,
1579
+ ZRBNotification,
1580
+ ZRBNotificationDigestFrequency,
1581
+ ZRBNotificationSettings,
1582
+ ZRBNotificationTopicPreference,
1313
1583
  ZRBRtsChange,
1314
1584
  ZRBRtsChangeOp,
1315
1585
  ZRBRtsCounter,
@@ -1326,14 +1596,22 @@ export {
1326
1596
  ZRBUploadSession,
1327
1597
  ZRBUploadSessionStatus,
1328
1598
  ZRBUser,
1599
+ buildAbility,
1600
+ buildAbilityFromSession,
1329
1601
  buildLocaleFallbackChain,
1602
+ can,
1330
1603
  createModels,
1331
1604
  extendZod,
1605
+ getAccessibleByQuery,
1606
+ getRegisteredPolicies,
1332
1607
  getTenantFilesystemDb,
1333
1608
  getTenantFilesystemDbFromCtx,
1334
1609
  getTenantFilesystemDbName,
1610
+ getTenantRolesFromSessionUser,
1335
1611
  loadModel,
1336
1612
  loadRbModel,
1613
+ registerPoliciesFromModules,
1614
+ registerPolicy,
1337
1615
  resolveLocalizedString,
1338
1616
  withLocalizedStringFallback,
1339
1617
  z2 as z,
@@ -1 +1 @@
1
- {"version":3,"file":"loadModel.d.ts","sourceRoot":"","sources":["../src/loadModel.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,QAAQ,MAAM,UAAU,CAAA;AAMpC,KAAK,YAAY,GAAG;IAClB,GAAG,EAAE;QACH,OAAO,CAAC,EAAE;YACR,IAAI,CAAC,EAAE;gBACL,eAAe,CAAC,EAAE,MAAM,CAAC;aAC1B,CAAA;SACF,GAAG,IAAI,CAAC;KACV,CAAC;CACH,CAAC;AAuCF,eAAO,MAAM,SAAS,GAAU,WAAW,MAAM,EAAE,KAAK,YAAY,4DAOnE,CAAA;AAED,eAAO,MAAM,WAAW,GAAU,WAAW,MAAM,EAAE,MAAM,YAAY,4DAItE,CAAA;AAED,YAAY,EAAE,YAAY,EAAE,CAAA"}
1
+ {"version":3,"file":"loadModel.d.ts","sourceRoot":"","sources":["../src/loadModel.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,QAAQ,MAAM,UAAU,CAAA;AAMpC,KAAK,YAAY,GAAG;IAClB,GAAG,EAAE;QACH,OAAO,CAAC,EAAE;YACR,IAAI,CAAC,EAAE;gBACL,eAAe,CAAC,EAAE,MAAM,CAAC;aAC1B,CAAA;SACF,GAAG,IAAI,CAAC;KACV,CAAC;CACH,CAAC;AAyCF,eAAO,MAAM,SAAS,GAAU,WAAW,MAAM,EAAE,KAAK,YAAY,4DAOnE,CAAA;AAED,eAAO,MAAM,WAAW,GAAU,WAAW,MAAM,EAAE,MAAM,YAAY,4DAItE,CAAA;AAED,YAAY,EAAE,YAAY,EAAE,CAAA"}
@@ -0,0 +1,19 @@
1
+ import { Schema } from '../../../vite/node_modules/mongoose';
2
+ import { z } from '../../../vite/node_modules/zod';
3
+ import { AclPolicy } from '../acl';
4
+ export declare const ZRBNotification: z.ZodObject<{
5
+ userId: z.ZodString;
6
+ topic: z.ZodOptional<z.ZodString>;
7
+ title: z.ZodString;
8
+ body: z.ZodOptional<z.ZodString>;
9
+ url: z.ZodOptional<z.ZodString>;
10
+ createdAt: z.ZodDate;
11
+ seenAt: z.ZodOptional<z.ZodDate>;
12
+ readAt: z.ZodOptional<z.ZodDate>;
13
+ archivedAt: z.ZodOptional<z.ZodDate>;
14
+ metadata: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
15
+ }, z.core.$strip>;
16
+ export type IRBNotification = z.infer<typeof ZRBNotification>;
17
+ export declare const RBNotificationSchema: Schema;
18
+ export declare const RBNotificationPolicy: AclPolicy;
19
+ //# sourceMappingURL=RBNotification.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"RBNotification.d.ts","sourceRoot":"","sources":["../../src/models/RBNotification.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,UAAU,CAAA;AACjC,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAA;AAEvB,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,QAAQ,CAAA;AAGvC,eAAO,MAAM,eAAe;;;;;;;;;;;iBAW1B,CAAA;AAEF,MAAM,MAAM,eAAe,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,eAAe,CAAC,CAAA;AAI7D,eAAO,MAAM,oBAAoB,EAAE,MAiBlC,CAAA;AAOD,eAAO,MAAM,oBAAoB,EAAE,SASlC,CAAA"}
@@ -0,0 +1,33 @@
1
+ import { Schema } from '../../../vite/node_modules/mongoose';
2
+ import { z } from '../../../vite/node_modules/zod';
3
+ import { AclPolicy } from '../acl';
4
+ export declare const ZRBNotificationDigestFrequency: z.ZodEnum<{
5
+ off: "off";
6
+ daily: "daily";
7
+ weekly: "weekly";
8
+ }>;
9
+ export declare const ZRBNotificationTopicPreference: z.ZodObject<{
10
+ topic: z.ZodString;
11
+ inApp: z.ZodBoolean;
12
+ emailDigest: z.ZodBoolean;
13
+ push: z.ZodBoolean;
14
+ }, z.core.$strip>;
15
+ export declare const ZRBNotificationSettings: z.ZodObject<{
16
+ userId: z.ZodString;
17
+ digestFrequency: z.ZodEnum<{
18
+ off: "off";
19
+ daily: "daily";
20
+ weekly: "weekly";
21
+ }>;
22
+ topicPreferences: z.ZodOptional<z.ZodArray<z.ZodObject<{
23
+ topic: z.ZodString;
24
+ inApp: z.ZodBoolean;
25
+ emailDigest: z.ZodBoolean;
26
+ push: z.ZodBoolean;
27
+ }, z.core.$strip>>>;
28
+ lastDigestSentAt: z.ZodOptional<z.ZodDate>;
29
+ }, z.core.$strip>;
30
+ export type IRBNotificationSettings = z.infer<typeof ZRBNotificationSettings>;
31
+ export declare const RBNotificationSettingsSchema: Schema;
32
+ export declare const RBNotificationSettingsPolicy: AclPolicy;
33
+ //# sourceMappingURL=RBNotificationSettings.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"RBNotificationSettings.d.ts","sourceRoot":"","sources":["../../src/models/RBNotificationSettings.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,UAAU,CAAA;AACjC,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAA;AAEvB,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,QAAQ,CAAA;AAGvC,eAAO,MAAM,8BAA8B;;;;EAAqC,CAAA;AAEhF,eAAO,MAAM,8BAA8B;;;;;iBAKzC,CAAA;AAEF,eAAO,MAAM,uBAAuB;;;;;;;;;;;;;;iBAKlC,CAAA;AAEF,MAAM,MAAM,uBAAuB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,uBAAuB,CAAC,CAAA;AAY7E,eAAO,MAAM,4BAA4B,EAAE,MAoB1C,CAAA;AAKD,eAAO,MAAM,4BAA4B,EAAE,SAQ1C,CAAA"}
@@ -1,5 +1,6 @@
1
1
  import { Schema } from '../../../vite/node_modules/mongoose';
2
2
  import { z } from '../../../vite/node_modules/zod';
3
+ import { AclPolicy } from '../acl';
3
4
  export declare const ZRBUploadSessionStatus: z.ZodEnum<{
4
5
  error: "error";
5
6
  done: "done";
@@ -28,4 +29,5 @@ export declare const ZRBUploadSession: z.ZodObject<{
28
29
  }, z.core.$strip>;
29
30
  export type IRBUploadSession = z.infer<typeof ZRBUploadSession>;
30
31
  export declare const RBUploadSessionSchema: Schema;
32
+ export declare const RBUploadSessionPolicy: AclPolicy;
31
33
  //# sourceMappingURL=RBUploadSession.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"RBUploadSession.d.ts","sourceRoot":"","sources":["../../src/models/RBUploadSession.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,UAAU,CAAA;AACjC,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAA;AAGvB,eAAO,MAAM,sBAAsB;;;;;EAAuD,CAAA;AAE1F,eAAO,MAAM,gBAAgB;;;;;;;;;;;;;;;;;;;iBAc3B,CAAA;AAEF,MAAM,MAAM,gBAAgB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,gBAAgB,CAAC,CAAA;AAE/D,eAAO,MAAM,qBAAqB,EAAE,MAoBnC,CAAA"}
1
+ {"version":3,"file":"RBUploadSession.d.ts","sourceRoot":"","sources":["../../src/models/RBUploadSession.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,UAAU,CAAA;AACjC,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAA;AAEvB,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,QAAQ,CAAA;AAGvC,eAAO,MAAM,sBAAsB;;;;;EAAuD,CAAA;AAE1F,eAAO,MAAM,gBAAgB;;;;;;;;;;;;;;;;;;;iBAc3B,CAAA;AAEF,MAAM,MAAM,gBAAgB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,gBAAgB,CAAC,CAAA;AAE/D,eAAO,MAAM,qBAAqB,EAAE,MAoBnC,CAAA;AAID,eAAO,MAAM,qBAAqB,EAAE,SAkBnC,CAAA"}
@@ -6,6 +6,7 @@ export declare const ZRBUser: z.ZodObject<{
6
6
  name: z.ZodOptional<z.ZodString>;
7
7
  phone: z.ZodOptional<z.ZodString>;
8
8
  tenants: z.ZodArray<z.ZodString>;
9
+ tenantRoles: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodArray<z.ZodString>>>;
9
10
  emailVerificationCode: z.ZodOptional<z.ZodString>;
10
11
  emailVerificationExpiresAt: z.ZodOptional<z.ZodDate>;
11
12
  }, z.core.$strip>;
@@ -1 +1 @@
1
- {"version":3,"file":"User.d.ts","sourceRoot":"","sources":["../../src/models/User.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,UAAU,CAAA;AACjC,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAA;AAGvB,eAAO,MAAM,OAAO;;;;;;;;iBAQlB,CAAA;AAEF,MAAM,MAAM,OAAO,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,OAAO,CAAC,CAAC;AAE9C,eAAO,MAAM,YAAY,EAAE,MAQA,CAAA"}
1
+ {"version":3,"file":"User.d.ts","sourceRoot":"","sources":["../../src/models/User.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,UAAU,CAAA;AACjC,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAA;AAGvB,eAAO,MAAM,OAAO;;;;;;;;;iBASlB,CAAA;AAEF,MAAM,MAAM,OAAO,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,OAAO,CAAC,CAAC;AAE9C,eAAO,MAAM,YAAY,EAAE,MASA,CAAA"}
@@ -6,4 +6,6 @@ export * from './RBRtsCounter';
6
6
  export * from './RBRtsChange';
7
7
  export * from './RBUploadSession';
8
8
  export * from './RBUploadChunk';
9
+ export * from './RBNotification';
10
+ export * from './RBNotificationSettings';
9
11
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/models/index.ts"],"names":[],"mappings":"AAAA,cAAc,QAAQ,CAAA;AACtB,cAAc,UAAU,CAAA;AACxB,cAAc,wBAAwB,CAAA;AACtC,cAAc,6BAA6B,CAAA;AAC3C,cAAc,gBAAgB,CAAA;AAC9B,cAAc,eAAe,CAAA;AAC7B,cAAc,mBAAmB,CAAA;AACjC,cAAc,iBAAiB,CAAA"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/models/index.ts"],"names":[],"mappings":"AAAA,cAAc,QAAQ,CAAA;AACtB,cAAc,UAAU,CAAA;AACxB,cAAc,wBAAwB,CAAA;AACtC,cAAc,6BAA6B,CAAA;AAC3C,cAAc,gBAAgB,CAAA;AAC9B,cAAc,eAAe,CAAA;AAC7B,cAAc,mBAAmB,CAAA;AACjC,cAAc,iBAAiB,CAAA;AAC/B,cAAc,kBAAkB,CAAA;AAChC,cAAc,0BAA0B,CAAA"}
@@ -1 +1 @@
1
- {"version":3,"file":"registerModels.d.ts","sourceRoot":"","sources":["../src/registerModels.ts"],"names":[],"mappings":"AAAA,OAAO,QAAQ,MAAM,UAAU,CAAA;AAU/B,KAAK,YAAY,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;AAiE3C,eAAO,MAAM,cAAc,GAAI,SAAS,YAAY,SAEnD,CAAA;AAED,eAAO,MAAM,mBAAmB,sEAK/B,CAAA;AAED,YAAY,EAAE,YAAY,EAAE,CAAA"}
1
+ {"version":3,"file":"registerModels.d.ts","sourceRoot":"","sources":["../src/registerModels.ts"],"names":[],"mappings":"AAAA,OAAO,QAAQ,MAAM,UAAU,CAAA;AAa/B,KAAK,YAAY,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;AAyE3C,eAAO,MAAM,cAAc,GAAI,SAAS,YAAY,SAInD,CAAA;AAED,eAAO,MAAM,mBAAmB,sEAK/B,CAAA;AAED,YAAY,EAAE,YAAY,EAAE,CAAA"}
package/package.json CHANGED
@@ -1,12 +1,24 @@
1
1
  {
2
2
  "name": "@rpcbase/db",
3
- "version": "0.25.0",
3
+ "version": "0.27.0",
4
4
  "type": "module",
5
5
  "files": [
6
6
  "dist"
7
7
  ],
8
8
  "main": "./dist/index.js",
9
9
  "types": "./dist/index.d.ts",
10
+ "exports": {
11
+ ".": {
12
+ "types": "./dist/index.d.ts",
13
+ "import": "./dist/index.js",
14
+ "default": "./dist/index.js"
15
+ },
16
+ "./acl": {
17
+ "types": "./dist/index.d.ts",
18
+ "import": "./dist/index.js",
19
+ "default": "./dist/index.js"
20
+ }
21
+ },
10
22
  "scripts": {
11
23
  "build": "wireit",
12
24
  "test": "vitest run --coverage",
@@ -55,9 +67,13 @@
55
67
  "mongoose": "^9",
56
68
  "zod": "^4"
57
69
  },
70
+ "dependencies": {
71
+ "@casl/ability": "6.7.5",
72
+ "@casl/mongoose": "8.0.3"
73
+ },
58
74
  "devDependencies": {
59
- "@types/node": "24.10.1",
60
- "@vitest/coverage-v8": "4.0.9",
61
- "vitest": "4.0.9"
75
+ "@types/node": "25.0.3",
76
+ "@vitest/coverage-v8": "4.0.16",
77
+ "vitest": "4.0.16"
62
78
  }
63
79
  }