@rpcbase/db 0.35.0 → 0.36.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 (48) hide show
  1. package/README.md +10 -15
  2. package/dist/acl/index.js +11 -0
  3. package/dist/can-urGFf45M.js +131 -0
  4. package/dist/extendMongooseSchema.d.ts +6 -0
  5. package/dist/extendMongooseSchema.d.ts.map +1 -0
  6. package/dist/index.browser.d.ts +2 -0
  7. package/dist/index.browser.d.ts.map +1 -0
  8. package/dist/index.browser.js +22 -0
  9. package/dist/index.d.ts +5 -3
  10. package/dist/index.d.ts.map +1 -1
  11. package/dist/index.js +309 -1137
  12. package/dist/models/{Tenant.d.ts → RBTenant.d.ts} +1 -1
  13. package/dist/models/RBTenant.d.ts.map +1 -0
  14. package/dist/models/{User.d.ts → RBUser.d.ts} +1 -1
  15. package/dist/models/RBUser.d.ts.map +1 -0
  16. package/dist/models/index.d.ts +2 -2
  17. package/dist/models/index.d.ts.map +1 -1
  18. package/dist/mongoose/index.d.ts +4 -0
  19. package/dist/mongoose/index.d.ts.map +1 -0
  20. package/dist/zod/extension.d.ts +17 -0
  21. package/dist/zod/extension.d.ts.map +1 -0
  22. package/dist/zod/index.d.ts +3 -0
  23. package/dist/zod/index.d.ts.map +1 -0
  24. package/package.json +5 -4
  25. package/dist/acl.d.ts +0 -2
  26. package/dist/acl.d.ts.map +0 -1
  27. package/dist/models/Tenant.d.ts.map +0 -1
  28. package/dist/models/User.d.ts.map +0 -1
  29. package/dist/schema/assertions/assertions.d.ts +0 -20
  30. package/dist/schema/assertions/assertions.d.ts.map +0 -1
  31. package/dist/schema/assertions/constructor.d.ts +0 -10
  32. package/dist/schema/assertions/constructor.d.ts.map +0 -1
  33. package/dist/schema/assertions/custom.d.ts +0 -6
  34. package/dist/schema/assertions/custom.d.ts.map +0 -1
  35. package/dist/schema/assertions/instanceOf.d.ts +0 -10
  36. package/dist/schema/assertions/instanceOf.d.ts.map +0 -1
  37. package/dist/schema/assertions/staticNames.d.ts +0 -10
  38. package/dist/schema/assertions/staticNames.d.ts.map +0 -1
  39. package/dist/schema/assertions/types.d.ts +0 -17
  40. package/dist/schema/assertions/types.d.ts.map +0 -1
  41. package/dist/schema/extension.d.ts +0 -78
  42. package/dist/schema/extension.d.ts.map +0 -1
  43. package/dist/schema/index.d.ts +0 -73
  44. package/dist/schema/index.d.ts.map +0 -1
  45. package/dist/schema/mongoose.types.d.ts +0 -93
  46. package/dist/schema/mongoose.types.d.ts.map +0 -1
  47. package/dist/setupFile.d.ts +0 -2
  48. package/dist/setupFile.d.ts.map +0 -1
package/dist/index.js CHANGED
@@ -1,11 +1,14 @@
1
- import mongoose, { Schema, isValidObjectId, Types, SchemaTypes } from "mongoose";
2
- import { z, ZodMap, ZodRecord, ZodAny, ZodUnion, ZodNullable, ZodOptional, ZodDefault, ZodDate, ZodEnum, ZodBoolean, ZodArray, ZodObject, ZodNumber, ZodString } from "zod";
3
- export * from "zod";
1
+ import { a as registerPoliciesFromModules } from "./can-urGFf45M.js";
2
+ import { b, d, f, e, g, c, r } from "./can-urGFf45M.js";
3
+ import mongoose, { Schema as Schema$1, Types } from "mongoose";
4
+ import { default as default2 } from "mongoose";
5
+ import { z } from "zod";
4
6
  import { z as z2 } from "zod";
7
+ import { timingSafeEqual, createHmac } from "node:crypto";
8
+ import "./index.browser.js";
5
9
  import assert from "assert";
6
10
  import { accessibleBy, accessibleRecordsPlugin } from "@casl/mongoose";
7
- import { AbilityBuilder, createMongoAbility, subject } from "@casl/ability";
8
- import { timingSafeEqual, createHmac } from "node:crypto";
11
+ import "@casl/ability";
9
12
  const ZRBUser = z.object({
10
13
  email: z.string().email().optional(),
11
14
  password: z.string(),
@@ -16,7 +19,7 @@ const ZRBUser = z.object({
16
19
  emailVerificationCode: z.string().length(6).optional(),
17
20
  emailVerificationExpiresAt: z.date().optional()
18
21
  });
19
- const RBUserSchema = new Schema({
22
+ const RBUserSchema = new Schema$1({
20
23
  email: { type: String, unique: true, sparse: true },
21
24
  phone: { type: String, unique: true, sparse: true },
22
25
  password: { type: String, required: true },
@@ -31,7 +34,7 @@ const ZRBTenant = z.object({
31
34
  parentTenantId: z.string().optional(),
32
35
  name: z.string().optional()
33
36
  });
34
- const RBTenantSchema = new Schema({
37
+ const RBTenantSchema = new Schema$1({
35
38
  tenantId: { type: String, required: true, unique: true, index: true },
36
39
  parentTenantId: { type: String },
37
40
  name: { type: String }
@@ -72,7 +75,7 @@ const ZRBTenantSubscription = z.object({
72
75
  latestEventAt: z.date().optional(),
73
76
  metadata: z.record(z.string(), z.unknown()).optional()
74
77
  });
75
- const RBTenantSubscriptionSchema = new Schema(
78
+ const RBTenantSubscriptionSchema = new Schema$1(
76
79
  {
77
80
  tenantId: { type: String, required: true, index: true },
78
81
  subscriptionId: { type: String, required: true },
@@ -96,7 +99,7 @@ const RBTenantSubscriptionSchema = new Schema(
96
99
  providerSubscriptionId: { type: String },
97
100
  latestEventId: { type: String },
98
101
  latestEventAt: { type: Date },
99
- metadata: { type: Schema.Types.Mixed }
102
+ metadata: { type: Schema$1.Types.Mixed }
100
103
  },
101
104
  {
102
105
  collection: "tenantSubscriptions"
@@ -140,7 +143,7 @@ const ZRBTenantSubscriptionEvent = z.object({
140
143
  providerPayload: z.unknown().optional(),
141
144
  metadata: z.record(z.string(), z.unknown()).optional()
142
145
  });
143
- const RBTenantSubscriptionEventSchema = new Schema(
146
+ const RBTenantSubscriptionEventSchema = new Schema$1(
144
147
  {
145
148
  tenantId: { type: String, required: true, index: true },
146
149
  subscriptionId: { type: String, required: true, index: true },
@@ -163,8 +166,8 @@ const RBTenantSubscriptionEventSchema = new Schema(
163
166
  reason: { type: String },
164
167
  provider: { type: String },
165
168
  providerEventId: { type: String },
166
- providerPayload: { type: Schema.Types.Mixed },
167
- metadata: { type: Schema.Types.Mixed }
169
+ providerPayload: { type: Schema$1.Types.Mixed },
170
+ metadata: { type: Schema$1.Types.Mixed }
168
171
  },
169
172
  {
170
173
  collection: "tenantSubscriptionEvents"
@@ -176,7 +179,7 @@ const ZRBRtsCounter = z.object({
176
179
  _id: z.string(),
177
180
  seq: z.number().int().min(0)
178
181
  });
179
- const RBRtsCounterSchema = new Schema(
182
+ const RBRtsCounterSchema = new Schema$1(
180
183
  {
181
184
  _id: { type: String, required: true },
182
185
  seq: { type: Number, required: true, default: 0 }
@@ -196,7 +199,7 @@ const ZRBRtsChange = z.object({
196
199
  docId: z.string().optional(),
197
200
  ts: z.date()
198
201
  });
199
- const RBRtsChangeSchema = new Schema(
202
+ const RBRtsChangeSchema = new Schema$1(
200
203
  {
201
204
  seq: { type: Number, required: true },
202
205
  modelName: { type: String, required: true, index: true },
@@ -228,7 +231,7 @@ const ZRBUploadSession = z.object({
228
231
  isPublic: z.boolean().optional(),
229
232
  error: z.string().optional()
230
233
  });
231
- const RBUploadSessionSchema = new Schema(
234
+ const RBUploadSessionSchema = new Schema$1(
232
235
  {
233
236
  _id: { type: String, required: true },
234
237
  userId: { type: String, required: false, index: true },
@@ -277,7 +280,7 @@ const ZRBUploadChunk = z.object({
277
280
  createdAt: z.date(),
278
281
  expiresAt: z.date()
279
282
  });
280
- const RBUploadChunkSchema = new Schema(
283
+ const RBUploadChunkSchema = new Schema$1(
281
284
  {
282
285
  uploadId: { type: String, required: true, index: true },
283
286
  index: { type: Number, required: true },
@@ -307,7 +310,7 @@ const ZRBNotification = z.object({
307
310
  metadata: z.record(z.string(), z.unknown()).optional()
308
311
  });
309
312
  const TTL_90_DAYS_S = 60 * 60 * 24 * 90;
310
- const RBNotificationSchema = new Schema(
313
+ const RBNotificationSchema = new Schema$1(
311
314
  {
312
315
  userId: { type: String, required: true, index: true },
313
316
  topic: { type: String, required: false, index: true },
@@ -318,7 +321,7 @@ const RBNotificationSchema = new Schema(
318
321
  seenAt: { type: Date, required: false, index: true },
319
322
  readAt: { type: Date, required: false, index: true },
320
323
  archivedAt: { type: Date, required: false },
321
- metadata: { type: Schema.Types.Mixed, required: false }
324
+ metadata: { type: Schema$1.Types.Mixed, required: false }
322
325
  },
323
326
  {
324
327
  versionKey: false,
@@ -352,7 +355,7 @@ const ZRBNotificationSettings = z.object({
352
355
  topicPreferences: z.array(ZRBNotificationTopicPreference).optional(),
353
356
  lastDigestSentAt: z.date().optional()
354
357
  });
355
- const TopicPreferenceSchema = new Schema(
358
+ const TopicPreferenceSchema = new Schema$1(
356
359
  {
357
360
  topic: { type: String, required: true },
358
361
  inApp: { type: Boolean, required: true, default: true },
@@ -361,7 +364,7 @@ const TopicPreferenceSchema = new Schema(
361
364
  },
362
365
  { _id: false }
363
366
  );
364
- const RBNotificationSettingsSchema = new Schema(
367
+ const RBNotificationSettingsSchema = new Schema$1(
365
368
  {
366
369
  userId: { type: String, required: true },
367
370
  digestFrequency: {
@@ -429,723 +432,291 @@ const frameworkSchemas = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.de
429
432
  ZRBUploadSessionStatus,
430
433
  ZRBUser
431
434
  }, Symbol.toStringTag, { value: "Module" }));
432
- const zmAssert$4 = {
433
- string(f) {
434
- return f.constructor.name === "ZodString";
435
- },
436
- number(f) {
437
- return f.constructor.name === "ZodNumber";
438
- },
439
- object(f) {
440
- return f.constructor.name === "ZodObject";
441
- },
442
- array(f) {
443
- return f.constructor.name === "ZodArray";
444
- },
445
- boolean(f) {
446
- return f.constructor.name === "ZodBoolean";
447
- },
448
- enumerable(f) {
449
- return f.constructor.name === "ZodEnum";
450
- },
451
- date(f) {
452
- return f.constructor.name === "ZodDate";
453
- },
454
- def(f) {
455
- return f.constructor.name === "ZodDefault";
456
- },
457
- optional(f) {
458
- return f.constructor.name === "ZodOptional";
459
- },
460
- nullable(f) {
461
- return f.constructor.name === "ZodNullable";
462
- },
463
- union(f) {
464
- return f.constructor.name === "ZodUnion";
465
- },
466
- any(f) {
467
- return f.constructor.name === "ZodAny";
468
- },
469
- mapOrRecord(f) {
470
- return f.constructor.name === "ZodMap" || f.constructor.name === "ZodRecord";
471
- }
472
- };
473
- const zmAssertIds = {
474
- objectId(f) {
475
- return "__zm_type" in f && f.__zm_type === "ObjectId";
476
- },
477
- uuid(f) {
478
- return "__zm_type" in f && f.__zm_type === "UUID";
435
+ const { Schema, model } = mongoose;
436
+ class PaginationValidationError extends Error {
437
+ code = "invalid_pagination";
438
+ statusCode = 400;
439
+ constructor(message, options) {
440
+ super(message, options);
441
+ this.name = "PaginationValidationError";
479
442
  }
443
+ }
444
+ const isPaginationValidationError = (error) => {
445
+ if (!error || typeof error !== "object") return false;
446
+ const anyError = error;
447
+ return anyError.name === "PaginationValidationError" && anyError.code === "invalid_pagination" && anyError.statusCode === 400;
480
448
  };
481
- const zmAssert$3 = {
482
- string(f) {
483
- return f instanceof ZodString;
484
- },
485
- number(f) {
486
- return f instanceof ZodNumber;
487
- },
488
- object(f) {
489
- return f instanceof ZodObject;
490
- },
491
- array(f) {
492
- return f instanceof ZodArray;
493
- },
494
- boolean(f) {
495
- return f instanceof ZodBoolean;
496
- },
497
- enumerable(f) {
498
- return f instanceof ZodEnum;
499
- },
500
- date(f) {
501
- return f instanceof ZodDate;
502
- },
503
- def(f) {
504
- return f instanceof ZodDefault;
505
- },
506
- optional(f) {
507
- return f instanceof ZodOptional;
508
- },
509
- nullable(f) {
510
- return f instanceof ZodNullable;
511
- },
512
- union(f) {
513
- return f instanceof ZodUnion;
514
- },
515
- any(f) {
516
- return f instanceof ZodAny;
517
- },
518
- mapOrRecord(f) {
519
- return f instanceof ZodMap || f instanceof ZodRecord;
449
+ const DISALLOWED_MONGO_FIELD_SEGMENTS = /* @__PURE__ */ new Set(["__proto__", "constructor", "prototype"]);
450
+ const PAGINATION_LIMIT_MAX = 128;
451
+ const normalizePaginationSpec = (spec) => {
452
+ if (!spec || typeof spec !== "object") throw new PaginationValidationError("Invalid PaginationSpec");
453
+ const limit = normalizeLimit(spec.limit);
454
+ const direction = spec.direction ?? "next";
455
+ if (direction !== "next" && direction !== "prev") throw new PaginationValidationError("Invalid pagination direction");
456
+ if (!Array.isArray(spec.sort) || spec.sort.length === 0) throw new PaginationValidationError("Invalid pagination sort");
457
+ const sort = spec.sort.map(({ field, order }) => ({
458
+ field: assertSafeMongoFieldPath(field),
459
+ order: normalizeOrder(order)
460
+ }));
461
+ const seenFields = /* @__PURE__ */ new Set();
462
+ for (const { field } of sort) {
463
+ if (seenFields.has(field)) throw new PaginationValidationError(`Duplicate pagination sort field: ${field}`);
464
+ seenFields.add(field);
520
465
  }
521
- };
522
- const zmAssert$2 = {
523
- string(f) {
524
- return "__zm_type" in f && f.__zm_type === "String";
525
- },
526
- number(f) {
527
- return "__zm_type" in f && f.__zm_type === "Number";
528
- },
529
- object(f) {
530
- return "__zm_type" in f && f.__zm_type === "Object";
531
- },
532
- array(f) {
533
- return "__zm_type" in f && f.__zm_type === "Array";
534
- },
535
- boolean(f) {
536
- return "__zm_type" in f && f.__zm_type === "Boolean";
537
- },
538
- enumerable(f) {
539
- return "__zm_type" in f && f.__zm_type === "Enum";
540
- },
541
- date(f) {
542
- return "__zm_type" in f && f.__zm_type === "Date";
543
- },
544
- def(f) {
545
- return "__zm_type" in f && f.__zm_type === "Default";
546
- },
547
- optional(f) {
548
- return "__zm_type" in f && f.__zm_type === "Optional";
549
- },
550
- nullable(f) {
551
- return "__zm_type" in f && f.__zm_type === "Nullable";
552
- },
553
- union(f) {
554
- return "__zm_type" in f && f.__zm_type === "Union";
555
- },
556
- any(f) {
557
- return "__zm_type" in f && f.__zm_type === "Any";
558
- },
559
- mapOrRecord(f) {
560
- return "__zm_type" in f && (f.__zm_type === "Map" || f.__zm_type === "Record");
466
+ const primaryOrder = sort[0]?.order;
467
+ if (!seenFields.has("_id")) {
468
+ sort.push({ field: "_id", order: primaryOrder });
561
469
  }
562
- };
563
- const assertions = [zmAssert$4, zmAssert$3, zmAssert$2];
564
- const zmAssert = Object.keys(zmAssert$4).map((key) => key).reduce((acc, key) => {
565
- acc[key] = (f) => {
566
- return assertions.some((assertion) => assertion[key](f));
470
+ return {
471
+ ...spec,
472
+ limit,
473
+ direction,
474
+ sort
567
475
  };
568
- return acc;
569
- }, {});
570
- const zmAssert$1 = {
571
- ...zmAssert,
572
- ...zmAssertIds
573
- };
574
- let zod_extended = false;
575
- const isSchemaCandidate = (value) => {
576
- return Boolean(value && typeof value === "object" && "_def" in value);
577
- };
578
- const resolveSchemaAndFlag = (self, args, defaultFlag = true) => {
579
- let schema = isSchemaCandidate(self) ? self : void 0;
580
- let flag;
581
- if (args.length > 0) {
582
- const [firstArg, secondArg] = args;
583
- if (typeof firstArg === "boolean") flag = firstArg;
584
- if (typeof secondArg === "boolean") flag = secondArg;
585
- if (!schema && isSchemaCandidate(firstArg)) {
586
- schema = firstArg;
587
- if (typeof secondArg === "boolean") flag = secondArg;
588
- }
476
+ };
477
+ const normalizeLimit = (limit) => {
478
+ if (typeof limit !== "number" || !Number.isFinite(limit) || !Number.isInteger(limit) || limit <= 0) {
479
+ throw new PaginationValidationError("Invalid pagination limit");
589
480
  }
590
- if (!schema) return { schema: void 0, flag: defaultFlag };
591
- if (typeof flag !== "boolean") flag = defaultFlag;
592
- return { schema, flag };
593
- };
594
- const resolveSchemaAndValue = (self, args) => {
595
- let schema = isSchemaCandidate(self) ? self : void 0;
596
- let value = args[0];
597
- if (!schema && isSchemaCandidate(value)) {
598
- schema = value;
599
- value = args.length > 1 ? args[1] : void 0;
481
+ if (limit > PAGINATION_LIMIT_MAX) {
482
+ throw new PaginationValidationError("Invalid pagination limit");
600
483
  }
601
- return { schema, value };
602
- };
603
- function extendZod(z_0) {
604
- if (zod_extended) return;
605
- zod_extended = true;
606
- const UNIQUE_SUPPORT_LIST = [z_0.ZodString, z_0.ZodNumber, z_0.ZodDate];
607
- for (const type of UNIQUE_SUPPORT_LIST) {
608
- const proto = type?.prototype;
609
- if (!proto) continue;
610
- proto.unique = function unique(...args) {
611
- const { schema, flag } = resolveSchemaAndFlag(this, args);
612
- if (!schema) return this;
613
- schema.__zm_unique = flag;
614
- if (schema._def && typeof schema._def === "object") {
615
- schema._def.__zm_unique = flag;
616
- }
617
- return schema;
618
- };
619
- proto.sparse = function sparse(...args) {
620
- const { schema, flag } = resolveSchemaAndFlag(this, args);
621
- if (!schema) return this;
622
- schema.__zm_sparse = flag;
623
- if (schema._def && typeof schema._def === "object") {
624
- schema._def.__zm_sparse = flag;
625
- }
626
- return schema;
627
- };
484
+ return limit;
485
+ };
486
+ const normalizeOrder = (order) => {
487
+ if (order !== "asc" && order !== "desc") throw new PaginationValidationError("Invalid pagination order");
488
+ return order;
489
+ };
490
+ const assertSafeMongoFieldPath = (field) => {
491
+ if (typeof field !== "string" || field.length === 0) throw new PaginationValidationError("Invalid pagination sort field");
492
+ if (field.startsWith("$")) throw new PaginationValidationError("Invalid pagination sort field");
493
+ const parts = field.split(".");
494
+ for (const part of parts) {
495
+ if (part.length === 0) throw new PaginationValidationError("Invalid pagination sort field");
496
+ if (DISALLOWED_MONGO_FIELD_SEGMENTS.has(part)) throw new PaginationValidationError("Invalid pagination sort field");
497
+ if (!/^[a-zA-Z0-9_]+$/.test(part)) throw new PaginationValidationError("Invalid pagination sort field");
628
498
  }
629
- const TypesMap = {
630
- String: z_0.ZodString,
631
- Number: z_0.ZodNumber,
632
- Object: z_0.ZodObject,
633
- Array: z_0.ZodArray,
634
- Boolean: z_0.ZodBoolean,
635
- Enum: z_0.ZodEnum,
636
- Date: z_0.ZodDate,
637
- Default: z_0.ZodDefault,
638
- Optional: z_0.ZodOptional,
639
- Nullable: z_0.ZodNullable,
640
- Union: z_0.ZodUnion,
641
- Any: z_0.ZodAny,
642
- Map: z_0.ZodMap,
643
- Record: z_0.ZodRecord,
644
- Pipe: z_0.ZodPipe
645
- };
646
- for (const [key, value] of Object.entries(TypesMap)) {
647
- if (value?.prototype) {
648
- Object.defineProperty(value.prototype, "__zm_type", {
649
- value: key,
650
- configurable: true,
651
- writable: true
652
- });
499
+ return field;
500
+ };
501
+ const encodePaginationCursor = (spec, node, options) => {
502
+ const normalized = normalizePaginationSpec(spec);
503
+ const values = /* @__PURE__ */ Object.create(null);
504
+ for (const { field } of normalized.sort) {
505
+ const value = readFieldValue(node, field);
506
+ if (typeof value === "undefined") {
507
+ throw new Error(`Pagination cursor encode failed (missing field: ${field})`);
653
508
  }
509
+ values[field] = encodeCursorValue(field, value);
654
510
  }
655
- }
656
- const createId = () => {
657
- return z.string().refine((v) => isValidObjectId(v), { error: "Invalid ObjectId" }).or(z.instanceof(Types.ObjectId));
658
- };
659
- const zId = (ref) => {
660
- const output = createId();
661
- const schema = output;
662
- schema.__zm_type = "ObjectId";
663
- schema.__zm_ref = ref;
664
- schema.ref = function ref2(...args) {
665
- const { schema: target, value } = resolveSchemaAndValue(this, args);
666
- if (!target || typeof value !== "string") return target ?? this;
667
- target.__zm_ref = value;
668
- if (target._def && typeof target._def === "object") {
669
- target._def.__zm_ref = value;
670
- }
671
- return target;
672
- };
673
- schema.refPath = function refPath(...args) {
674
- const { schema: target, value } = resolveSchemaAndValue(this, args);
675
- if (!target || typeof value !== "string") return target ?? this;
676
- target.__zm_refPath = value;
677
- if (target._def && typeof target._def === "object") {
678
- target._def.__zm_refPath = value;
679
- }
680
- return target;
681
- };
682
- schema.unique = function unique(...args) {
683
- const { schema: target, flag } = resolveSchemaAndFlag(this, args);
684
- if (!target) return this;
685
- target.__zm_unique = flag;
686
- if (target._def && typeof target._def === "object") {
687
- target._def.__zm_unique = flag;
688
- }
689
- return target;
690
- };
691
- schema.sparse = function sparse(...args) {
692
- const { schema: target, flag } = resolveSchemaAndFlag(this, args);
693
- if (!target) return this;
694
- target.__zm_sparse = flag;
695
- if (target._def && typeof target._def === "object") {
696
- target._def.__zm_sparse = flag;
697
- }
698
- return target;
699
- };
700
- return output;
701
- };
702
- const createUUID = () => {
703
- return z.uuid({ error: "Invalid UUID" }).or(z.instanceof(Types.UUID));
704
- };
705
- const zUUID = (ref) => {
706
- const output = createUUID();
707
- const schema = output;
708
- schema.__zm_type = "UUID";
709
- schema.__zm_ref = ref;
710
- schema.ref = function ref2(...args) {
711
- const { schema: target, value } = resolveSchemaAndValue(this, args);
712
- if (!target || typeof value !== "string") return target ?? this;
713
- target.__zm_ref = value;
714
- if (target._def && typeof target._def === "object") {
715
- target._def.__zm_ref = value;
716
- }
717
- return target;
718
- };
719
- schema.refPath = function refPath(...args) {
720
- const { schema: target, value } = resolveSchemaAndValue(this, args);
721
- if (!target || typeof value !== "string") return target ?? this;
722
- target.__zm_refPath = value;
723
- if (target._def && typeof target._def === "object") {
724
- target._def.__zm_refPath = value;
725
- }
726
- return target;
727
- };
728
- schema.unique = function unique(...args) {
729
- const { schema: target, flag } = resolveSchemaAndFlag(this, args);
730
- if (!target) return this;
731
- target.__zm_unique = flag;
732
- if (target._def && typeof target._def === "object") {
733
- target._def.__zm_unique = flag;
734
- }
735
- return target;
736
- };
737
- schema.sparse = function sparse(...args) {
738
- const { schema: target, flag } = resolveSchemaAndFlag(this, args);
739
- if (!target) return this;
740
- target.__zm_sparse = flag;
741
- if (target._def && typeof target._def === "object") {
742
- target._def.__zm_sparse = flag;
743
- }
744
- return target;
745
- };
746
- return output;
747
- };
748
- const LANGUAGE_CODE_REGEX = /^[a-z]{2,3}(?:-[A-Za-z0-9]{2,8})*$/;
749
- const LOCALIZED_STRING_PROXY_CACHE = /* @__PURE__ */ new WeakMap();
750
- function normalizeLocale(locale) {
751
- const trimmed = locale.trim();
752
- if (!trimmed) return "";
753
- const getCanonicalLocales = Intl?.getCanonicalLocales;
754
- if (typeof getCanonicalLocales !== "function") return trimmed;
511
+ const payload = { v: 1, values };
512
+ const payloadB64 = Buffer.from(JSON.stringify(payload), "utf8").toString("base64url");
513
+ const sigB64 = signCursorPayloadB64(payloadB64, options.signingSecret);
514
+ return `${payloadB64}.${sigB64}`;
515
+ };
516
+ const decodePaginationCursor = (spec, cursor, options) => {
517
+ const normalized = normalizePaginationSpec(spec);
518
+ const [payloadB64, sigB64, ...rest] = cursor.split(".");
519
+ if (rest.length > 0) throw new PaginationValidationError("Invalid pagination cursor format");
520
+ if (!sigB64) throw new PaginationValidationError("Invalid pagination cursor format");
521
+ verifyCursorSignature(payloadB64, sigB64, options.signingSecret);
522
+ const payloadRaw = Buffer.from(payloadB64, "base64url").toString("utf8");
523
+ let payloadUnknown;
755
524
  try {
756
- return getCanonicalLocales(trimmed)[0] ?? trimmed;
525
+ payloadUnknown = JSON.parse(payloadRaw);
757
526
  } catch {
758
- return trimmed;
527
+ throw new PaginationValidationError("Invalid pagination cursor payload");
759
528
  }
760
- }
761
- function buildLocaleFallbackChain(locale, fallbacks) {
762
- const base = locale.trim();
763
- const canonical = normalizeLocale(base);
764
- const extra = typeof fallbacks === "string" ? [fallbacks] : fallbacks ?? [];
765
- const output = [];
766
- const seen = /* @__PURE__ */ new Set();
767
- const push = (value) => {
768
- if (!value) return;
769
- if (seen.has(value)) return;
770
- seen.add(value);
771
- output.push(value);
772
- };
773
- const addChain = (value) => {
774
- if (!value) return;
775
- const parts = value.split("-").filter(Boolean);
776
- while (parts.length > 0) {
777
- push(parts.join("-"));
778
- parts.pop();
529
+ if (!payloadUnknown || typeof payloadUnknown !== "object") throw new PaginationValidationError("Invalid pagination cursor payload");
530
+ const payload = payloadUnknown;
531
+ if (payload.v !== 1) throw new PaginationValidationError("Unsupported pagination cursor version");
532
+ if (!payload.values || typeof payload.values !== "object") throw new PaginationValidationError("Invalid pagination cursor payload");
533
+ const decoded = /* @__PURE__ */ Object.create(null);
534
+ for (const { field } of normalized.sort) {
535
+ if (!Object.prototype.hasOwnProperty.call(payload.values, field)) {
536
+ throw new PaginationValidationError(`Pagination cursor missing field: ${field}`);
779
537
  }
780
- };
781
- addChain(base);
782
- addChain(canonical);
783
- for (const fallback of extra) addChain(normalizeLocale(fallback));
784
- return output;
785
- }
786
- function resolveLocalizedString(value, locale, options) {
787
- if (!value) return void 0;
788
- const chain = buildLocaleFallbackChain(locale, options?.fallbacks);
789
- if (chain.length === 0) return void 0;
790
- const record = value;
791
- for (const key of chain) {
792
- if (!Object.prototype.hasOwnProperty.call(record, key)) continue;
793
- return record[key];
538
+ const encodedValue = payload.values[field];
539
+ decoded[field] = decodeCursorValue(field, encodedValue);
794
540
  }
795
- return void 0;
796
- }
797
- function withLocalizedStringFallback(value) {
798
- if (!value || typeof value !== "object" || Array.isArray(value)) return value;
799
- if (value instanceof Map) return value;
800
- const cached = LOCALIZED_STRING_PROXY_CACHE.get(value);
801
- if (cached) return cached;
802
- const proxy = withFallbackRecord(value);
803
- LOCALIZED_STRING_PROXY_CACHE.set(value, proxy);
804
- return proxy;
805
- }
806
- function withFallbackRecord(record) {
807
- const getExact = (key) => record[key];
808
- const hasExact = (key) => Object.prototype.hasOwnProperty.call(record, key);
809
- return new Proxy(record, {
810
- get(target, prop) {
811
- if (prop === "getExact") return getExact;
812
- if (prop === "hasExact") return hasExact;
813
- if (prop === "get") return (key) => resolveLocalizedString(record, key);
814
- if (typeof prop === "string" && !(prop in target)) {
815
- return resolveLocalizedString(record, prop);
816
- }
817
- return target[prop];
818
- },
819
- set(target, prop, next) {
820
- target[prop] = next;
821
- return true;
822
- }
823
- });
824
- }
825
- const zLocalizedString = () => {
826
- const schema = z.record(
827
- z.string().regex(LANGUAGE_CODE_REGEX, { message: "Expected a language code (BCP 47, e.g. en or fr-FR)." }),
828
- z.string()
829
- );
830
- schema.__rpcbase_localizedString = true;
831
- return schema;
541
+ return decoded;
832
542
  };
833
- const zI18nString = zLocalizedString;
834
- function zodSchema(schema, options) {
835
- const definition = parseObject(schema);
836
- return new Schema(definition, options);
837
- }
838
- function zodSchemaRaw(schema) {
839
- return parseObject(schema);
840
- }
841
- function parseObject(obj) {
842
- const object = {};
843
- for (const [key, rawField] of Object.entries(obj.shape)) {
844
- const field = rawField;
845
- if (zmAssert$1.object(field)) {
846
- object[key] = parseObject(field);
847
- } else {
848
- const f = parseField(field);
849
- if (!f) throw new Error(`Unsupported field type: ${field.constructor}`);
850
- object[key] = f;
851
- }
852
- }
853
- return object;
854
- }
855
- function extractCustomValidation(field) {
856
- const checks = field._def?.checks;
857
- if (!Array.isArray(checks)) return void 0;
858
- for (const check of checks) {
859
- if (!check || typeof check !== "object") continue;
860
- if (check.__zm_validation) {
861
- return check.__zm_validation;
862
- }
863
- const def = check.def;
864
- if (!def || def.type !== "custom" || typeof def.fn !== "function") continue;
865
- const validator = (value) => {
866
- try {
867
- const result = def.fn(value, {
868
- ctx: {
869
- addIssue() {
870
- return void 0;
871
- }
872
- },
873
- input: value,
874
- parsedType: typeof value
875
- });
876
- return result !== false;
877
- } catch {
878
- return false;
879
- }
880
- };
881
- let message;
882
- if (typeof def.error === "function") {
883
- try {
884
- const computed = def.error({
885
- ctx: {
886
- addIssue() {
887
- return void 0;
888
- }
889
- },
890
- input: void 0,
891
- parsedType: "unknown"
892
- });
893
- if (typeof computed === "string") {
894
- message = computed;
895
- }
896
- } catch {
897
- }
898
- }
899
- const validation = {
900
- validator,
901
- message
902
- };
903
- check.__zm_validation = validation;
904
- return validation;
905
- }
906
- return void 0;
907
- }
908
- function parseField(field, required = true, def, refinement) {
909
- if (!field) return null;
910
- const customRefinement = extractCustomValidation(field);
911
- const directRefinement = field.__zm_validation ?? field._def?.__zm_validation ?? customRefinement;
912
- const currentRefinement = refinement ?? directRefinement;
913
- if (zmAssert$1.objectId(field)) {
914
- const ref = field.__zm_ref;
915
- const refPath = field.__zm_refPath;
916
- const unique = field.__zm_unique ?? (field._def?.__zm_unique ?? false);
917
- const sparse = field.__zm_sparse ?? (field._def?.__zm_sparse ?? false);
918
- return parseObjectId(required, ref, unique, refPath, sparse);
919
- }
920
- if (zmAssert$1.uuid(field)) {
921
- const ref = field.__zm_ref;
922
- const refPath = field.__zm_refPath;
923
- const unique = field.__zm_unique ?? (field._def?.__zm_unique ?? false);
924
- const sparse = field.__zm_sparse ?? (field._def?.__zm_sparse ?? false);
925
- return parseUUID(required, ref, unique, refPath, sparse);
926
- }
927
- if (zmAssert$1.object(field)) {
928
- return parseObject(field);
929
- }
930
- if (zmAssert$1.number(field)) {
931
- const isUnique = field.__zm_unique ?? field._def?.__zm_unique ?? false;
932
- const isSparse = field.__zm_sparse ?? field._def?.__zm_sparse ?? false;
933
- return parseNumber(
934
- field,
935
- required,
936
- def,
937
- isUnique,
938
- currentRefinement,
939
- isSparse
940
- );
941
- }
942
- if (zmAssert$1.string(field)) {
943
- const isUnique = field.__zm_unique ?? field._def?.__zm_unique ?? false;
944
- const isSparse = field.__zm_sparse ?? field._def?.__zm_sparse ?? false;
945
- return parseString(
946
- field,
947
- required,
948
- def,
949
- isUnique,
950
- currentRefinement,
951
- isSparse
952
- );
953
- }
954
- if (zmAssert$1.enumerable(field)) {
955
- const enumValues = Array.isArray(field.options) ? field.options : Object.values(field.enum ?? {});
956
- return parseEnum(enumValues, required, def);
957
- }
958
- if (zmAssert$1.boolean(field)) {
959
- return parseBoolean(required, def);
960
- }
961
- if (zmAssert$1.date(field)) {
962
- const isUnique = field.__zm_unique ?? field._def?.__zm_unique ?? false;
963
- const isSparse = field.__zm_sparse ?? field._def?.__zm_sparse ?? false;
964
- return parseDate(
965
- required,
966
- def,
967
- currentRefinement,
968
- isUnique,
969
- isSparse
970
- );
971
- }
972
- if (zmAssert$1.array(field)) {
973
- return parseArray(
974
- required,
975
- field.element,
976
- def
977
- );
543
+ const signCursorPayloadB64 = (payloadB64, secret) => {
544
+ return createHmac("sha256", secret).update(payloadB64, "utf8").digest("base64url");
545
+ };
546
+ const verifyCursorSignature = (payloadB64, sigB64, secret) => {
547
+ const expectedSigB64 = signCursorPayloadB64(payloadB64, secret);
548
+ const a = Buffer.from(sigB64, "utf8");
549
+ const b2 = Buffer.from(expectedSigB64, "utf8");
550
+ if (a.length !== b2.length || !timingSafeEqual(a, b2)) {
551
+ throw new PaginationValidationError("Invalid pagination cursor signature");
978
552
  }
979
- if (zmAssert$1.def(field)) {
980
- const defaultValue = typeof field._def.defaultValue === "function" ? field._def.defaultValue() : field._def.defaultValue;
981
- return parseField(
982
- field._def.innerType,
983
- required,
984
- defaultValue,
985
- currentRefinement
986
- );
553
+ };
554
+ const encodeCursorValue = (field, value) => {
555
+ if (value === null) return null;
556
+ if (field === "_id") {
557
+ if (value instanceof Types.ObjectId) return { $oid: value.toHexString() };
558
+ throw new Error("Pagination cursor encode failed (_id must be an ObjectId)");
987
559
  }
988
- if (zmAssert$1.optional(field)) {
989
- return parseField(field._def.innerType, false, void 0, currentRefinement);
560
+ if (value instanceof Date) return { $date: value.toISOString() };
561
+ if (typeof value === "string" || typeof value === "number" || typeof value === "boolean") return value;
562
+ if (value instanceof Types.ObjectId) return { $oid: value.toHexString() };
563
+ throw new Error(`Unsupported pagination cursor value type for field: ${field}`);
564
+ };
565
+ const decodeCursorValue = (field, value) => {
566
+ if (value === null) return null;
567
+ if (typeof value === "string") {
568
+ if (field === "_id") throw new PaginationValidationError(`Invalid pagination cursor ObjectId for field: ${field}`);
569
+ return value;
990
570
  }
991
- if (zmAssert$1.nullable(field)) {
992
- return parseField(
993
- field._def.innerType,
994
- false,
995
- def || null,
996
- currentRefinement
997
- );
571
+ if (typeof value === "number" || typeof value === "boolean") return value;
572
+ if (!value || typeof value !== "object") throw new PaginationValidationError(`Invalid pagination cursor value for field: ${field}`);
573
+ if ("$date" in value) {
574
+ if (typeof value.$date !== "string") throw new PaginationValidationError(`Invalid pagination cursor date for field: ${field}`);
575
+ const d2 = new Date(value.$date);
576
+ if (Number.isNaN(d2.getTime())) throw new PaginationValidationError(`Invalid pagination cursor date for field: ${field}`);
577
+ return d2;
998
578
  }
999
- if (zmAssert$1.union(field)) {
1000
- return parseField(field._def.options[0], required, def, currentRefinement);
579
+ if ("$oid" in value) {
580
+ if (typeof value.$oid !== "string" || !Types.ObjectId.isValid(value.$oid)) {
581
+ throw new PaginationValidationError(`Invalid pagination cursor ObjectId for field: ${field}`);
582
+ }
583
+ return new Types.ObjectId(value.$oid);
1001
584
  }
1002
- if (zmAssert$1.any(field)) {
1003
- return parseMixed(required, def);
585
+ throw new PaginationValidationError(`Invalid pagination cursor value for field: ${field}`);
586
+ };
587
+ const readFieldValue = (node, field) => {
588
+ if (!node || typeof node !== "object") return void 0;
589
+ if ("get" in node && typeof node.get === "function") {
590
+ return node.get(field);
1004
591
  }
1005
- if (field.__rpcbase_localizedString) {
592
+ return field.split(".").reduce((acc, key) => {
593
+ if (!acc || typeof acc !== "object") return void 0;
594
+ return acc[key];
595
+ }, node);
596
+ };
597
+ const compileMongoPagination = (spec, options) => {
598
+ const normalized = normalizePaginationSpec(spec);
599
+ const mongoLimit = normalized.limit + 1;
600
+ const mongoSort = toMongoSort(normalized);
601
+ if (normalized.cursor == null) {
1006
602
  return {
1007
- type: SchemaTypes.Mixed,
1008
- default: def,
1009
- required,
1010
- validate: {
1011
- validator: (value) => {
1012
- if (value == null) return true;
1013
- if (typeof value !== "object" || Array.isArray(value)) return false;
1014
- const proto = Object.getPrototypeOf(value);
1015
- if (proto !== Object.prototype && proto !== null) return false;
1016
- for (const [key, entry] of Object.entries(value)) {
1017
- if (!LANGUAGE_CODE_REGEX.test(key)) return false;
1018
- if (typeof entry !== "string") return false;
1019
- }
1020
- return true;
1021
- },
1022
- message: "Expected a localized string record."
1023
- },
1024
- get: (value) => value == null ? value : withLocalizedStringFallback(value)
603
+ spec: normalized,
604
+ mongoFilterDelta: {},
605
+ mongoSort,
606
+ mongoLimit
1025
607
  };
1026
608
  }
1027
- if (zmAssert$1.mapOrRecord(field)) {
1028
- const mapValueType = field.valueType ?? field.valueSchema;
1029
- const mapKeyType = field.keyType ?? field.keySchema;
1030
- if (!mapKeyType) {
1031
- throw new Error("Unsupported map key type: undefined");
1032
- }
1033
- return parseMap(
1034
- required,
1035
- mapValueType,
1036
- def
1037
- );
609
+ if (typeof normalized.cursor !== "string" || normalized.cursor.length === 0) {
610
+ throw new PaginationValidationError("Invalid pagination cursor");
1038
611
  }
1039
- return null;
1040
- }
1041
- function parseNumber(field, required = true, def, unique = false, validate, sparse = false) {
1042
- const output = {
1043
- type: Number,
1044
- default: def,
1045
- min: field.minValue ?? void 0,
1046
- max: field.maxValue ?? void 0,
1047
- required,
1048
- unique,
1049
- sparse
1050
- };
1051
- if (validate) output.validate = validate;
1052
- return output;
1053
- }
1054
- function parseString(field, required = true, def, unique = false, validate, sparse = false) {
1055
- const output = {
1056
- type: String,
1057
- default: def,
1058
- required,
1059
- minLength: field.minLength ?? void 0,
1060
- maxLength: field.maxLength ?? void 0,
1061
- unique,
1062
- sparse
1063
- };
1064
- if (validate) output.validate = validate;
1065
- return output;
1066
- }
1067
- function parseEnum(values, required = true, def) {
612
+ const cursorValues = decodePaginationCursor(normalized, normalized.cursor, options.cursor);
613
+ const mongoFilterDelta = buildKeysetFilterDelta(normalized, cursorValues);
1068
614
  return {
1069
- type: String,
1070
- unique: false,
1071
- sparse: false,
1072
- default: def,
1073
- enum: values,
1074
- required
615
+ spec: normalized,
616
+ mongoFilterDelta,
617
+ mongoSort,
618
+ mongoLimit
1075
619
  };
1076
- }
1077
- function parseBoolean(required = true, def) {
1078
- return {
1079
- type: Boolean,
1080
- default: def,
1081
- required
1082
- };
1083
- }
1084
- function parseDate(required = true, def, validate, unique = false, sparse = false) {
1085
- const output = {
1086
- type: Date,
1087
- default: def,
1088
- required,
1089
- unique,
1090
- sparse
1091
- };
1092
- if (validate) output.validate = validate;
1093
- return output;
1094
- }
1095
- function parseObjectId(required = true, ref, unique = false, refPath, sparse = false) {
1096
- const output = {
1097
- type: SchemaTypes.ObjectId,
1098
- required,
1099
- unique,
1100
- sparse
1101
- };
1102
- if (ref) output.ref = ref;
1103
- if (refPath) output.refPath = refPath;
1104
- return output;
1105
- }
1106
- function parseArray(required = true, element, def) {
1107
- const innerType = parseField(element);
1108
- if (!innerType) throw new Error("Unsupported array type");
1109
- return {
1110
- type: [innerType],
1111
- default: def,
1112
- required
1113
- };
1114
- }
1115
- function parseMap(required = true, valueType, def) {
1116
- if (!valueType) {
1117
- throw new Error("Unsupported map value type: undefined");
620
+ };
621
+ const toMongoSort = (spec) => {
622
+ const mongoSort = /* @__PURE__ */ Object.create(null);
623
+ for (const { field, order } of spec.sort) {
624
+ const forQueryOrder = spec.direction === "prev" ? invertOrder(order) : order;
625
+ mongoSort[field] = forQueryOrder === "asc" ? 1 : -1;
1118
626
  }
1119
- const pointer = parseField(valueType);
1120
- if (!pointer) {
1121
- const typeName = valueType?.constructor?.name ?? "unknown";
1122
- throw new Error(`Unsupported map value type (${typeName})`);
627
+ return mongoSort;
628
+ };
629
+ const buildKeysetFilterDelta = (spec, cursorValues) => {
630
+ const branches = [];
631
+ for (let i = 0; i < spec.sort.length; i++) {
632
+ const current = spec.sort[i];
633
+ if (!current) continue;
634
+ const and = [];
635
+ for (let j = 0; j < i; j++) {
636
+ const prev = spec.sort[j];
637
+ if (!prev) continue;
638
+ const eq = /* @__PURE__ */ Object.create(null);
639
+ eq[prev.field] = cursorValues[prev.field];
640
+ and.push(eq);
641
+ }
642
+ const op = getKeysetOp(current.order, spec.direction);
643
+ const cmpOp = /* @__PURE__ */ Object.create(null);
644
+ cmpOp[op] = cursorValues[current.field];
645
+ const cmp = /* @__PURE__ */ Object.create(null);
646
+ cmp[current.field] = cmpOp;
647
+ and.push(cmp);
648
+ branches.push(and.length === 1 ? and[0] : { $and: and });
1123
649
  }
1124
- return {
1125
- type: Map,
1126
- of: pointer,
1127
- default: def,
1128
- required
1129
- };
1130
- }
1131
- function parseUUID(required = true, ref, unique = false, refPath, sparse = false) {
1132
- const output = {
1133
- type: SchemaTypes.UUID,
1134
- required,
1135
- unique,
1136
- sparse
650
+ return { $or: branches };
651
+ };
652
+ const getKeysetOp = (order, direction) => {
653
+ if (direction === "next") return order === "asc" ? "$gt" : "$lt";
654
+ return order === "asc" ? "$lt" : "$gt";
655
+ };
656
+ const invertOrder = (order) => {
657
+ return order === "asc" ? "desc" : "asc";
658
+ };
659
+ const materializeMongoPagination = (compiled, fetchedNodes, options) => {
660
+ const limit = compiled.spec.limit;
661
+ const hasMore = fetchedNodes.length > limit;
662
+ const trimmed = fetchedNodes.slice(0, limit);
663
+ const nodes = compiled.spec.direction === "prev" ? trimmed.reverse() : trimmed;
664
+ const hasPrevPage = compiled.spec.direction === "next" ? Boolean(compiled.spec.cursor) : hasMore;
665
+ const hasNextPage = compiled.spec.direction === "next" ? hasMore : Boolean(compiled.spec.cursor);
666
+ const pageInfo = {
667
+ hasNextPage,
668
+ hasPrevPage
1137
669
  };
1138
- if (ref) output.ref = ref;
1139
- if (refPath) output.refPath = refPath;
1140
- return output;
1141
- }
1142
- function parseMixed(required = true, def) {
1143
- return {
1144
- type: SchemaTypes.Mixed,
1145
- default: def,
1146
- required
670
+ if (nodes.length === 0) {
671
+ return { nodes, pageInfo };
672
+ }
673
+ if (hasPrevPage) {
674
+ pageInfo.prevCursor = encodePaginationCursor(compiled.spec, nodes[0], options.cursor);
675
+ }
676
+ if (hasNextPage) {
677
+ pageInfo.nextCursor = encodePaginationCursor(compiled.spec, nodes[nodes.length - 1], options.cursor);
678
+ }
679
+ return { nodes, pageInfo };
680
+ };
681
+ const MongoAdapter = {
682
+ applyPagination: (query, compiled) => {
683
+ query.where(compiled.mongoFilterDelta);
684
+ query.sort(compiled.mongoSort);
685
+ query.limit(compiled.mongoLimit);
686
+ return query;
687
+ }
688
+ };
689
+ const paginateMongoQuery = async (query, pagination, options) => {
690
+ const compiled = compileMongoPagination(pagination, { cursor: options.cursor });
691
+ MongoAdapter.applyPagination(query, compiled);
692
+ const fetchedNodes = await query.exec();
693
+ if (!Array.isArray(fetchedNodes)) {
694
+ throw new Error("paginateMongoQuery expects query.exec() to return an array");
695
+ }
696
+ return materializeMongoPagination(compiled, fetchedNodes, { cursor: options.cursor });
697
+ };
698
+ const getQueryOptions$1 = (query) => {
699
+ if (!query || typeof query !== "object") return void 0;
700
+ if (!("getOptions" in query) || typeof query.getOptions !== "function") return void 0;
701
+ return query.getOptions();
702
+ };
703
+ const getPaginationFromOptions = (query) => {
704
+ const options = getQueryOptions$1(query);
705
+ return options?.pagination;
706
+ };
707
+ const getCursorFromOptions = (query) => {
708
+ const options = getQueryOptions$1(query);
709
+ return options?.paginationCursor;
710
+ };
711
+ const mongoPaginationPlugin = (schema, pluginOptions) => {
712
+ schema.query.paginate = async function(pagination, options) {
713
+ const spec = pagination ?? getPaginationFromOptions(this);
714
+ if (!spec) throw new Error("Missing pagination spec");
715
+ const cursor = options?.cursor ?? getCursorFromOptions(this) ?? pluginOptions?.cursor;
716
+ if (!cursor?.signingSecret) throw new Error("Missing pagination cursor signingSecret");
717
+ return await paginateMongoQuery(this, spec, { cursor });
1147
718
  };
1148
- }
719
+ };
1149
720
  const getAppName$1 = (env = process.env) => {
1150
721
  const appName = env.APP_NAME?.trim();
1151
722
  if (!appName) {
@@ -1237,11 +808,11 @@ const insertChanges = async (db, changes) => {
1237
808
  if (!changes.length) return;
1238
809
  const { RtsChange } = getRtsModels(db);
1239
810
  const ts = /* @__PURE__ */ new Date();
1240
- await RtsChange.insertMany(changes.map((c) => ({
1241
- seq: c.seq,
1242
- modelName: c.modelName,
1243
- op: c.op,
1244
- docId: c.docId ?? void 0,
811
+ await RtsChange.insertMany(changes.map((c2) => ({
812
+ seq: c2.seq,
813
+ modelName: c2.modelName,
814
+ op: c2.op,
815
+ docId: c2.docId ?? void 0,
1245
816
  ts
1246
817
  })));
1247
818
  };
@@ -1272,7 +843,7 @@ const captureDeleteMeta = async (query, mode) => {
1272
843
  findQuery.limit(maxDeleteIds + 1);
1273
844
  }
1274
845
  const docs = await findQuery;
1275
- const ids = Array.isArray(docs) ? docs.map((d) => normalizeId(d?._id)).filter((id) => Boolean(id)) : [];
846
+ const ids = Array.isArray(docs) ? docs.map((d2) => normalizeId(d2?._id)).filter((id) => Boolean(id)) : [];
1276
847
  const reset = mode === "many" && ids.length > maxDeleteIds;
1277
848
  const trimmedIds = reset ? [] : ids;
1278
849
  const meta = {
@@ -1326,125 +897,6 @@ const rtsChangeLogPlugin = (schema) => {
1326
897
  }
1327
898
  });
1328
899
  };
1329
- const POLICIES_GLOBAL_KEY = /* @__PURE__ */ Symbol.for("@rpcbase/db/acl/policiesBySubject");
1330
- const getGlobalPoliciesMap = () => {
1331
- const store = globalThis;
1332
- const existing = store[POLICIES_GLOBAL_KEY];
1333
- if (existing instanceof Map) {
1334
- return existing;
1335
- }
1336
- const created = /* @__PURE__ */ new Map();
1337
- store[POLICIES_GLOBAL_KEY] = created;
1338
- return created;
1339
- };
1340
- const policiesBySubject = getGlobalPoliciesMap();
1341
- const isPolicy = (value) => {
1342
- if (!value || typeof value !== "object") return false;
1343
- const maybe = value;
1344
- return typeof maybe.subject === "string" && typeof maybe.define === "function";
1345
- };
1346
- const registerPolicy = (policy) => {
1347
- const set = policiesBySubject.get(policy.subject) ?? /* @__PURE__ */ new Set();
1348
- set.add(policy.define);
1349
- policiesBySubject.set(policy.subject, set);
1350
- };
1351
- const registerPoliciesFromModules = (modules) => {
1352
- for (const [exportName, value] of Object.entries(modules)) {
1353
- if (!isPolicy(value)) continue;
1354
- if (!exportName.endsWith("Policy")) {
1355
- throw new Error(
1356
- `Invalid policy export name "${exportName}". Policies must be exported as "<ModelName>Policy".`
1357
- );
1358
- }
1359
- const expectedSubject = exportName.slice(0, -"Policy".length);
1360
- if (value.subject !== expectedSubject) {
1361
- throw new Error(
1362
- `Invalid policy "${exportName}": expected subject "${expectedSubject}", got "${value.subject}".`
1363
- );
1364
- }
1365
- registerPolicy(value);
1366
- }
1367
- };
1368
- const getRegisteredPolicies = () => {
1369
- const out = [];
1370
- for (const set of policiesBySubject.values()) {
1371
- for (const fn of set) out.push(fn);
1372
- }
1373
- return out;
1374
- };
1375
- const buildAbility = (ctx) => {
1376
- const builder = new AbilityBuilder(createMongoAbility);
1377
- const { can: can2 } = builder;
1378
- if (ctx.roles.includes("owner") || ctx.roles.includes("admin")) {
1379
- can2("manage", "all");
1380
- }
1381
- for (const define of getRegisteredPolicies()) {
1382
- define(builder, ctx);
1383
- }
1384
- return builder.build();
1385
- };
1386
- const normalizeRole = (raw) => {
1387
- if (typeof raw !== "string") return null;
1388
- const normalized = raw.trim();
1389
- return normalized ? normalized : null;
1390
- };
1391
- const normalizeRoles = (raw) => {
1392
- if (Array.isArray(raw)) {
1393
- return raw.map(normalizeRole).filter((r) => Boolean(r));
1394
- }
1395
- const role = normalizeRole(raw);
1396
- return role ? [role] : [];
1397
- };
1398
- const normalizeRolesByTenantId = (raw) => {
1399
- if (!raw || typeof raw !== "object") return null;
1400
- if (raw instanceof Map) {
1401
- return Object.fromEntries(Array.from(raw.entries()).map(([key, value]) => [String(key), normalizeRoles(value)]));
1402
- }
1403
- const obj = raw;
1404
- const out = {};
1405
- for (const [key, value] of Object.entries(obj)) {
1406
- const tenantId = String(key).trim();
1407
- if (!tenantId) continue;
1408
- out[tenantId] = normalizeRoles(value);
1409
- }
1410
- return out;
1411
- };
1412
- const getTenantRolesFromSessionUser = (user, tenantId) => {
1413
- if (!user || typeof user !== "object") return [];
1414
- const rolesByTenantId = normalizeRolesByTenantId(user.tenantRoles);
1415
- if (!rolesByTenantId) return [];
1416
- return rolesByTenantId[tenantId]?.filter(Boolean) ?? [];
1417
- };
1418
- const buildAbilityFromSession = ({
1419
- tenantId,
1420
- session,
1421
- claims
1422
- }) => {
1423
- const user = session?.user;
1424
- const userId = typeof user?.id === "string" ? user.id.trim() : "";
1425
- const rolesByTenantId = normalizeRolesByTenantId(user?.tenantRoles);
1426
- const hasExplicitTenantEntry = Boolean(
1427
- rolesByTenantId && Object.prototype.hasOwnProperty.call(rolesByTenantId, tenantId)
1428
- );
1429
- const signedInTenantsRaw = user?.signedInTenants;
1430
- const signedInTenants = Array.isArray(signedInTenantsRaw) ? signedInTenantsRaw.map(String) : [];
1431
- const roles = hasExplicitTenantEntry ? rolesByTenantId[tenantId] ?? [] : userId && signedInTenants.includes(tenantId) ? ["owner"] : getTenantRolesFromSessionUser(user, tenantId);
1432
- return buildAbility({
1433
- tenantId,
1434
- userId: userId || null,
1435
- roles,
1436
- claims
1437
- });
1438
- };
1439
- const getAccessibleByQuery = (ability, action, subject2) => {
1440
- return accessibleBy(ability, action).ofType(subject2);
1441
- };
1442
- const can = (ability, action, subjectType, object) => {
1443
- if (object && typeof object === "object") {
1444
- return ability.can(action, subject(subjectType, object));
1445
- }
1446
- return ability.can(action, subjectType);
1447
- };
1448
900
  const isRecord = (value) => Boolean(value) && typeof value === "object" && !Array.isArray(value);
1449
901
  const mergeMongoQuery = (left, right) => {
1450
902
  const leftQuery = isRecord(left) ? left : {};
@@ -1452,13 +904,13 @@ const mergeMongoQuery = (left, right) => {
1452
904
  if (Object.keys(right).length === 0) return leftQuery;
1453
905
  return { $and: [leftQuery, right] };
1454
906
  };
1455
- const getQueryOptions$1 = (query) => {
907
+ const getQueryOptions = (query) => {
1456
908
  if (!query || typeof query !== "object") return void 0;
1457
909
  if (!("getOptions" in query) || typeof query.getOptions !== "function") return void 0;
1458
910
  return query.getOptions();
1459
911
  };
1460
912
  const getStoredAclFromQuery = (query) => {
1461
- const options = getQueryOptions$1(query);
913
+ const options = getQueryOptions(query);
1462
914
  const raw = options?.rbAcl;
1463
915
  if (!isRecord(raw)) return null;
1464
916
  if (!("ability" in raw)) return null;
@@ -1526,8 +978,8 @@ const patchAggregateAcl = () => {
1526
978
  return this;
1527
979
  };
1528
980
  };
1529
- const createModelAclProxy = (model, ability) => {
1530
- return new Proxy(model, {
981
+ const createModelAclProxy = (model2, ability) => {
982
+ return new Proxy(model2, {
1531
983
  get(target, prop, receiver) {
1532
984
  const value = Reflect.get(target, prop, receiver);
1533
985
  if (typeof value !== "function") return value;
@@ -1590,290 +1042,6 @@ const mongooseAclPlugin = (schema) => {
1590
1042
  addQueryAclFilter(this, "update");
1591
1043
  });
1592
1044
  };
1593
- class PaginationValidationError extends Error {
1594
- code = "invalid_pagination";
1595
- statusCode = 400;
1596
- constructor(message, options) {
1597
- super(message, options);
1598
- this.name = "PaginationValidationError";
1599
- }
1600
- }
1601
- const isPaginationValidationError = (error) => {
1602
- if (!error || typeof error !== "object") return false;
1603
- const anyError = error;
1604
- return anyError.name === "PaginationValidationError" && anyError.code === "invalid_pagination" && anyError.statusCode === 400;
1605
- };
1606
- const DISALLOWED_MONGO_FIELD_SEGMENTS = /* @__PURE__ */ new Set(["__proto__", "constructor", "prototype"]);
1607
- const PAGINATION_LIMIT_MAX = 128;
1608
- const normalizePaginationSpec = (spec) => {
1609
- if (!spec || typeof spec !== "object") throw new PaginationValidationError("Invalid PaginationSpec");
1610
- const limit = normalizeLimit(spec.limit);
1611
- const direction = spec.direction ?? "next";
1612
- if (direction !== "next" && direction !== "prev") throw new PaginationValidationError("Invalid pagination direction");
1613
- if (!Array.isArray(spec.sort) || spec.sort.length === 0) throw new PaginationValidationError("Invalid pagination sort");
1614
- const sort = spec.sort.map(({ field, order }) => ({
1615
- field: assertSafeMongoFieldPath(field),
1616
- order: normalizeOrder(order)
1617
- }));
1618
- const seenFields = /* @__PURE__ */ new Set();
1619
- for (const { field } of sort) {
1620
- if (seenFields.has(field)) throw new PaginationValidationError(`Duplicate pagination sort field: ${field}`);
1621
- seenFields.add(field);
1622
- }
1623
- const primaryOrder = sort[0]?.order;
1624
- if (!seenFields.has("_id")) {
1625
- sort.push({ field: "_id", order: primaryOrder });
1626
- }
1627
- return {
1628
- ...spec,
1629
- limit,
1630
- direction,
1631
- sort
1632
- };
1633
- };
1634
- const normalizeLimit = (limit) => {
1635
- if (typeof limit !== "number" || !Number.isFinite(limit) || !Number.isInteger(limit) || limit <= 0) {
1636
- throw new PaginationValidationError("Invalid pagination limit");
1637
- }
1638
- if (limit > PAGINATION_LIMIT_MAX) {
1639
- throw new PaginationValidationError("Invalid pagination limit");
1640
- }
1641
- return limit;
1642
- };
1643
- const normalizeOrder = (order) => {
1644
- if (order !== "asc" && order !== "desc") throw new PaginationValidationError("Invalid pagination order");
1645
- return order;
1646
- };
1647
- const assertSafeMongoFieldPath = (field) => {
1648
- if (typeof field !== "string" || field.length === 0) throw new PaginationValidationError("Invalid pagination sort field");
1649
- if (field.startsWith("$")) throw new PaginationValidationError("Invalid pagination sort field");
1650
- const parts = field.split(".");
1651
- for (const part of parts) {
1652
- if (part.length === 0) throw new PaginationValidationError("Invalid pagination sort field");
1653
- if (DISALLOWED_MONGO_FIELD_SEGMENTS.has(part)) throw new PaginationValidationError("Invalid pagination sort field");
1654
- if (!/^[a-zA-Z0-9_]+$/.test(part)) throw new PaginationValidationError("Invalid pagination sort field");
1655
- }
1656
- return field;
1657
- };
1658
- const encodePaginationCursor = (spec, node, options) => {
1659
- const normalized = normalizePaginationSpec(spec);
1660
- const values = /* @__PURE__ */ Object.create(null);
1661
- for (const { field } of normalized.sort) {
1662
- const value = readFieldValue(node, field);
1663
- if (typeof value === "undefined") {
1664
- throw new Error(`Pagination cursor encode failed (missing field: ${field})`);
1665
- }
1666
- values[field] = encodeCursorValue(field, value);
1667
- }
1668
- const payload = { v: 1, values };
1669
- const payloadB64 = Buffer.from(JSON.stringify(payload), "utf8").toString("base64url");
1670
- const sigB64 = signCursorPayloadB64(payloadB64, options.signingSecret);
1671
- return `${payloadB64}.${sigB64}`;
1672
- };
1673
- const decodePaginationCursor = (spec, cursor, options) => {
1674
- const normalized = normalizePaginationSpec(spec);
1675
- const [payloadB64, sigB64, ...rest] = cursor.split(".");
1676
- if (rest.length > 0) throw new PaginationValidationError("Invalid pagination cursor format");
1677
- if (!sigB64) throw new PaginationValidationError("Invalid pagination cursor format");
1678
- verifyCursorSignature(payloadB64, sigB64, options.signingSecret);
1679
- const payloadRaw = Buffer.from(payloadB64, "base64url").toString("utf8");
1680
- let payloadUnknown;
1681
- try {
1682
- payloadUnknown = JSON.parse(payloadRaw);
1683
- } catch {
1684
- throw new PaginationValidationError("Invalid pagination cursor payload");
1685
- }
1686
- if (!payloadUnknown || typeof payloadUnknown !== "object") throw new PaginationValidationError("Invalid pagination cursor payload");
1687
- const payload = payloadUnknown;
1688
- if (payload.v !== 1) throw new PaginationValidationError("Unsupported pagination cursor version");
1689
- if (!payload.values || typeof payload.values !== "object") throw new PaginationValidationError("Invalid pagination cursor payload");
1690
- const decoded = /* @__PURE__ */ Object.create(null);
1691
- for (const { field } of normalized.sort) {
1692
- if (!Object.prototype.hasOwnProperty.call(payload.values, field)) {
1693
- throw new PaginationValidationError(`Pagination cursor missing field: ${field}`);
1694
- }
1695
- const encodedValue = payload.values[field];
1696
- decoded[field] = decodeCursorValue(field, encodedValue);
1697
- }
1698
- return decoded;
1699
- };
1700
- const signCursorPayloadB64 = (payloadB64, secret) => {
1701
- return createHmac("sha256", secret).update(payloadB64, "utf8").digest("base64url");
1702
- };
1703
- const verifyCursorSignature = (payloadB64, sigB64, secret) => {
1704
- const expectedSigB64 = signCursorPayloadB64(payloadB64, secret);
1705
- const a = Buffer.from(sigB64, "utf8");
1706
- const b = Buffer.from(expectedSigB64, "utf8");
1707
- if (a.length !== b.length || !timingSafeEqual(a, b)) {
1708
- throw new PaginationValidationError("Invalid pagination cursor signature");
1709
- }
1710
- };
1711
- const encodeCursorValue = (field, value) => {
1712
- if (value === null) return null;
1713
- if (field === "_id") {
1714
- if (value instanceof Types.ObjectId) return { $oid: value.toHexString() };
1715
- throw new Error("Pagination cursor encode failed (_id must be an ObjectId)");
1716
- }
1717
- if (value instanceof Date) return { $date: value.toISOString() };
1718
- if (typeof value === "string" || typeof value === "number" || typeof value === "boolean") return value;
1719
- if (value instanceof Types.ObjectId) return { $oid: value.toHexString() };
1720
- throw new Error(`Unsupported pagination cursor value type for field: ${field}`);
1721
- };
1722
- const decodeCursorValue = (field, value) => {
1723
- if (value === null) return null;
1724
- if (typeof value === "string") {
1725
- if (field === "_id") throw new PaginationValidationError(`Invalid pagination cursor ObjectId for field: ${field}`);
1726
- return value;
1727
- }
1728
- if (typeof value === "number" || typeof value === "boolean") return value;
1729
- if (!value || typeof value !== "object") throw new PaginationValidationError(`Invalid pagination cursor value for field: ${field}`);
1730
- if ("$date" in value) {
1731
- if (typeof value.$date !== "string") throw new PaginationValidationError(`Invalid pagination cursor date for field: ${field}`);
1732
- const d = new Date(value.$date);
1733
- if (Number.isNaN(d.getTime())) throw new PaginationValidationError(`Invalid pagination cursor date for field: ${field}`);
1734
- return d;
1735
- }
1736
- if ("$oid" in value) {
1737
- if (typeof value.$oid !== "string" || !Types.ObjectId.isValid(value.$oid)) {
1738
- throw new PaginationValidationError(`Invalid pagination cursor ObjectId for field: ${field}`);
1739
- }
1740
- return new Types.ObjectId(value.$oid);
1741
- }
1742
- throw new PaginationValidationError(`Invalid pagination cursor value for field: ${field}`);
1743
- };
1744
- const readFieldValue = (node, field) => {
1745
- if (!node || typeof node !== "object") return void 0;
1746
- if ("get" in node && typeof node.get === "function") {
1747
- return node.get(field);
1748
- }
1749
- return field.split(".").reduce((acc, key) => {
1750
- if (!acc || typeof acc !== "object") return void 0;
1751
- return acc[key];
1752
- }, node);
1753
- };
1754
- const compileMongoPagination = (spec, options) => {
1755
- const normalized = normalizePaginationSpec(spec);
1756
- const mongoLimit = normalized.limit + 1;
1757
- const mongoSort = toMongoSort(normalized);
1758
- if (normalized.cursor == null) {
1759
- return {
1760
- spec: normalized,
1761
- mongoFilterDelta: {},
1762
- mongoSort,
1763
- mongoLimit
1764
- };
1765
- }
1766
- if (typeof normalized.cursor !== "string" || normalized.cursor.length === 0) {
1767
- throw new PaginationValidationError("Invalid pagination cursor");
1768
- }
1769
- const cursorValues = decodePaginationCursor(normalized, normalized.cursor, options.cursor);
1770
- const mongoFilterDelta = buildKeysetFilterDelta(normalized, cursorValues);
1771
- return {
1772
- spec: normalized,
1773
- mongoFilterDelta,
1774
- mongoSort,
1775
- mongoLimit
1776
- };
1777
- };
1778
- const toMongoSort = (spec) => {
1779
- const mongoSort = /* @__PURE__ */ Object.create(null);
1780
- for (const { field, order } of spec.sort) {
1781
- const forQueryOrder = spec.direction === "prev" ? invertOrder(order) : order;
1782
- mongoSort[field] = forQueryOrder === "asc" ? 1 : -1;
1783
- }
1784
- return mongoSort;
1785
- };
1786
- const buildKeysetFilterDelta = (spec, cursorValues) => {
1787
- const branches = [];
1788
- for (let i = 0; i < spec.sort.length; i++) {
1789
- const current = spec.sort[i];
1790
- if (!current) continue;
1791
- const and = [];
1792
- for (let j = 0; j < i; j++) {
1793
- const prev = spec.sort[j];
1794
- if (!prev) continue;
1795
- const eq = /* @__PURE__ */ Object.create(null);
1796
- eq[prev.field] = cursorValues[prev.field];
1797
- and.push(eq);
1798
- }
1799
- const op = getKeysetOp(current.order, spec.direction);
1800
- const cmpOp = /* @__PURE__ */ Object.create(null);
1801
- cmpOp[op] = cursorValues[current.field];
1802
- const cmp = /* @__PURE__ */ Object.create(null);
1803
- cmp[current.field] = cmpOp;
1804
- and.push(cmp);
1805
- branches.push(and.length === 1 ? and[0] : { $and: and });
1806
- }
1807
- return { $or: branches };
1808
- };
1809
- const getKeysetOp = (order, direction) => {
1810
- if (direction === "next") return order === "asc" ? "$gt" : "$lt";
1811
- return order === "asc" ? "$lt" : "$gt";
1812
- };
1813
- const invertOrder = (order) => {
1814
- return order === "asc" ? "desc" : "asc";
1815
- };
1816
- const materializeMongoPagination = (compiled, fetchedNodes, options) => {
1817
- const limit = compiled.spec.limit;
1818
- const hasMore = fetchedNodes.length > limit;
1819
- const trimmed = fetchedNodes.slice(0, limit);
1820
- const nodes = compiled.spec.direction === "prev" ? trimmed.reverse() : trimmed;
1821
- const hasPrevPage = compiled.spec.direction === "next" ? Boolean(compiled.spec.cursor) : hasMore;
1822
- const hasNextPage = compiled.spec.direction === "next" ? hasMore : Boolean(compiled.spec.cursor);
1823
- const pageInfo = {
1824
- hasNextPage,
1825
- hasPrevPage
1826
- };
1827
- if (nodes.length === 0) {
1828
- return { nodes, pageInfo };
1829
- }
1830
- if (hasPrevPage) {
1831
- pageInfo.prevCursor = encodePaginationCursor(compiled.spec, nodes[0], options.cursor);
1832
- }
1833
- if (hasNextPage) {
1834
- pageInfo.nextCursor = encodePaginationCursor(compiled.spec, nodes[nodes.length - 1], options.cursor);
1835
- }
1836
- return { nodes, pageInfo };
1837
- };
1838
- const MongoAdapter = {
1839
- applyPagination: (query, compiled) => {
1840
- query.where(compiled.mongoFilterDelta);
1841
- query.sort(compiled.mongoSort);
1842
- query.limit(compiled.mongoLimit);
1843
- return query;
1844
- }
1845
- };
1846
- const paginateMongoQuery = async (query, pagination, options) => {
1847
- const compiled = compileMongoPagination(pagination, { cursor: options.cursor });
1848
- MongoAdapter.applyPagination(query, compiled);
1849
- const fetchedNodes = await query.exec();
1850
- if (!Array.isArray(fetchedNodes)) {
1851
- throw new Error("paginateMongoQuery expects query.exec() to return an array");
1852
- }
1853
- return materializeMongoPagination(compiled, fetchedNodes, { cursor: options.cursor });
1854
- };
1855
- const getQueryOptions = (query) => {
1856
- if (!query || typeof query !== "object") return void 0;
1857
- if (!("getOptions" in query) || typeof query.getOptions !== "function") return void 0;
1858
- return query.getOptions();
1859
- };
1860
- const getPaginationFromOptions = (query) => {
1861
- const options = getQueryOptions(query);
1862
- return options?.pagination;
1863
- };
1864
- const getCursorFromOptions = (query) => {
1865
- const options = getQueryOptions(query);
1866
- return options?.paginationCursor;
1867
- };
1868
- const mongoPaginationPlugin = (schema, pluginOptions) => {
1869
- schema.query.paginate = async function(pagination, options) {
1870
- const spec = pagination ?? getPaginationFromOptions(this);
1871
- if (!spec) throw new Error("Missing pagination spec");
1872
- const cursor = options?.cursor ?? getCursorFromOptions(this) ?? pluginOptions?.cursor;
1873
- if (!cursor?.signingSecret) throw new Error("Missing pagination cursor signingSecret");
1874
- return await paginateMongoQuery(this, spec, { cursor });
1875
- };
1876
- };
1877
1045
  let cachedModels = null;
1878
1046
  const DEFAULT_GLOBAL_RB_MODEL_NAMES_SET = /* @__PURE__ */ new Set([
1879
1047
  "RBUser",
@@ -2010,6 +1178,16 @@ const createModels = (modules) => {
2010
1178
  getGlobal
2011
1179
  };
2012
1180
  };
1181
+ function extendMongooseSchema(baseSchema, ...extensions) {
1182
+ const schema = baseSchema.clone();
1183
+ extensions.forEach((extension) => schema.add(extension));
1184
+ return schema;
1185
+ }
1186
+ function omitSchemaPaths(schema, paths) {
1187
+ const clone = schema.clone();
1188
+ paths.forEach((path) => clone.remove(path));
1189
+ return clone;
1190
+ }
2013
1191
  const getAppName = () => {
2014
1192
  const appName = process.env.APP_NAME?.trim();
2015
1193
  assert(appName, "Missing APP_NAME");
@@ -2028,7 +1206,6 @@ const getTenantFilesystemDbFromCtx = async (ctx) => {
2028
1206
  return getTenantFilesystemDb(tenantId);
2029
1207
  };
2030
1208
  export {
2031
- LANGUAGE_CODE_REGEX,
2032
1209
  PaginationValidationError,
2033
1210
  RBNotificationPolicy,
2034
1211
  RBNotificationSchema,
@@ -2043,6 +1220,7 @@ export {
2043
1220
  RBUploadSessionPolicy,
2044
1221
  RBUploadSessionSchema,
2045
1222
  RBUserSchema,
1223
+ Schema,
2046
1224
  ZRBNotification,
2047
1225
  ZRBNotificationDigestFrequency,
2048
1226
  ZRBNotificationSettings,
@@ -2063,30 +1241,24 @@ export {
2063
1241
  ZRBUploadSession,
2064
1242
  ZRBUploadSessionStatus,
2065
1243
  ZRBUser,
2066
- buildAbility,
2067
- buildAbilityFromSession,
2068
- buildLocaleFallbackChain,
2069
- can,
1244
+ b as buildAbility,
1245
+ d as buildAbilityFromSession,
1246
+ f as can,
2070
1247
  createModels,
2071
- extendZod,
2072
- getAccessibleByQuery,
2073
- getRegisteredPolicies,
1248
+ extendMongooseSchema,
1249
+ e as getAccessibleByQuery,
1250
+ g as getRegisteredPolicies,
2074
1251
  getTenantFilesystemDb,
2075
1252
  getTenantFilesystemDbFromCtx,
2076
1253
  getTenantFilesystemDbName,
2077
- getTenantRolesFromSessionUser,
1254
+ c as getTenantRolesFromSessionUser,
2078
1255
  isPaginationValidationError,
1256
+ model,
2079
1257
  models,
2080
1258
  mongoPaginationPlugin,
1259
+ default2 as mongoose,
1260
+ omitSchemaPaths,
2081
1261
  registerPoliciesFromModules,
2082
- registerPolicy,
2083
- resolveLocalizedString,
2084
- withLocalizedStringFallback,
2085
- z2 as z,
2086
- zI18nString,
2087
- zId,
2088
- zLocalizedString,
2089
- zUUID,
2090
- zodSchema,
2091
- zodSchemaRaw
1262
+ r as registerPolicy,
1263
+ z2 as z
2092
1264
  };