@rpcbase/db 0.35.0 → 0.37.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 (52) hide show
  1. package/README.md +30 -11
  2. package/dist/acl/index.js +11 -0
  3. package/dist/can-urGFf45M.js +131 -0
  4. package/dist/index.browser.d.ts +2 -0
  5. package/dist/index.browser.d.ts.map +1 -0
  6. package/dist/index.browser.js +114 -0
  7. package/dist/index.d.ts +4 -3
  8. package/dist/index.d.ts.map +1 -1
  9. package/dist/index.js +319 -1130
  10. package/dist/models/{Tenant.d.ts → RBTenant.d.ts} +1 -1
  11. package/dist/models/RBTenant.d.ts.map +1 -0
  12. package/dist/models/{User.d.ts → RBUser.d.ts} +1 -1
  13. package/dist/models/RBUser.d.ts.map +1 -0
  14. package/dist/models/index.d.ts +2 -2
  15. package/dist/models/index.d.ts.map +1 -1
  16. package/dist/mongoose/extendMongooseSchema.d.ts +6 -0
  17. package/dist/mongoose/extendMongooseSchema.d.ts.map +1 -0
  18. package/dist/mongoose/index.d.ts +6 -0
  19. package/dist/mongoose/index.d.ts.map +1 -0
  20. package/dist/mongoose/localizedStringField.d.ts +4 -0
  21. package/dist/mongoose/localizedStringField.d.ts.map +1 -0
  22. package/dist/zod/extension.d.ts +17 -0
  23. package/dist/zod/extension.d.ts.map +1 -0
  24. package/dist/zod/index.d.ts +5 -0
  25. package/dist/zod/index.d.ts.map +1 -0
  26. package/dist/zod/localizedString.d.ts +14 -0
  27. package/dist/zod/localizedString.d.ts.map +1 -0
  28. package/package.json +5 -4
  29. package/dist/acl.d.ts +0 -2
  30. package/dist/acl.d.ts.map +0 -1
  31. package/dist/models/Tenant.d.ts.map +0 -1
  32. package/dist/models/User.d.ts.map +0 -1
  33. package/dist/schema/assertions/assertions.d.ts +0 -20
  34. package/dist/schema/assertions/assertions.d.ts.map +0 -1
  35. package/dist/schema/assertions/constructor.d.ts +0 -10
  36. package/dist/schema/assertions/constructor.d.ts.map +0 -1
  37. package/dist/schema/assertions/custom.d.ts +0 -6
  38. package/dist/schema/assertions/custom.d.ts.map +0 -1
  39. package/dist/schema/assertions/instanceOf.d.ts +0 -10
  40. package/dist/schema/assertions/instanceOf.d.ts.map +0 -1
  41. package/dist/schema/assertions/staticNames.d.ts +0 -10
  42. package/dist/schema/assertions/staticNames.d.ts.map +0 -1
  43. package/dist/schema/assertions/types.d.ts +0 -17
  44. package/dist/schema/assertions/types.d.ts.map +0 -1
  45. package/dist/schema/extension.d.ts +0 -78
  46. package/dist/schema/extension.d.ts.map +0 -1
  47. package/dist/schema/index.d.ts +0 -73
  48. package/dist/schema/index.d.ts.map +0 -1
  49. package/dist/schema/mongoose.types.d.ts +0 -93
  50. package/dist/schema/mongoose.types.d.ts.map +0 -1
  51. package/dist/setupFile.d.ts +0 -2
  52. package/dist/setupFile.d.ts.map +0 -1
package/dist/index.js CHANGED
@@ -1,11 +1,15 @@
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 { withLocalizedStringFallback } from "./index.browser.js";
9
+ import { LANGUAGE_CODE_REGEX, buildLocaleFallbackChain, extendZod, resolveLocalizedString, zI18nString, zLocalizedString } from "./index.browser.js";
5
10
  import assert from "assert";
6
11
  import { accessibleBy, accessibleRecordsPlugin } from "@casl/mongoose";
7
- import { AbilityBuilder, createMongoAbility, subject } from "@casl/ability";
8
- import { timingSafeEqual, createHmac } from "node:crypto";
12
+ import "@casl/ability";
9
13
  const ZRBUser = z.object({
10
14
  email: z.string().email().optional(),
11
15
  password: z.string(),
@@ -16,7 +20,7 @@ const ZRBUser = z.object({
16
20
  emailVerificationCode: z.string().length(6).optional(),
17
21
  emailVerificationExpiresAt: z.date().optional()
18
22
  });
19
- const RBUserSchema = new Schema({
23
+ const RBUserSchema = new Schema$1({
20
24
  email: { type: String, unique: true, sparse: true },
21
25
  phone: { type: String, unique: true, sparse: true },
22
26
  password: { type: String, required: true },
@@ -31,7 +35,7 @@ const ZRBTenant = z.object({
31
35
  parentTenantId: z.string().optional(),
32
36
  name: z.string().optional()
33
37
  });
34
- const RBTenantSchema = new Schema({
38
+ const RBTenantSchema = new Schema$1({
35
39
  tenantId: { type: String, required: true, unique: true, index: true },
36
40
  parentTenantId: { type: String },
37
41
  name: { type: String }
@@ -72,7 +76,7 @@ const ZRBTenantSubscription = z.object({
72
76
  latestEventAt: z.date().optional(),
73
77
  metadata: z.record(z.string(), z.unknown()).optional()
74
78
  });
75
- const RBTenantSubscriptionSchema = new Schema(
79
+ const RBTenantSubscriptionSchema = new Schema$1(
76
80
  {
77
81
  tenantId: { type: String, required: true, index: true },
78
82
  subscriptionId: { type: String, required: true },
@@ -96,7 +100,7 @@ const RBTenantSubscriptionSchema = new Schema(
96
100
  providerSubscriptionId: { type: String },
97
101
  latestEventId: { type: String },
98
102
  latestEventAt: { type: Date },
99
- metadata: { type: Schema.Types.Mixed }
103
+ metadata: { type: Schema$1.Types.Mixed }
100
104
  },
101
105
  {
102
106
  collection: "tenantSubscriptions"
@@ -140,7 +144,7 @@ const ZRBTenantSubscriptionEvent = z.object({
140
144
  providerPayload: z.unknown().optional(),
141
145
  metadata: z.record(z.string(), z.unknown()).optional()
142
146
  });
143
- const RBTenantSubscriptionEventSchema = new Schema(
147
+ const RBTenantSubscriptionEventSchema = new Schema$1(
144
148
  {
145
149
  tenantId: { type: String, required: true, index: true },
146
150
  subscriptionId: { type: String, required: true, index: true },
@@ -163,8 +167,8 @@ const RBTenantSubscriptionEventSchema = new Schema(
163
167
  reason: { type: String },
164
168
  provider: { type: String },
165
169
  providerEventId: { type: String },
166
- providerPayload: { type: Schema.Types.Mixed },
167
- metadata: { type: Schema.Types.Mixed }
170
+ providerPayload: { type: Schema$1.Types.Mixed },
171
+ metadata: { type: Schema$1.Types.Mixed }
168
172
  },
169
173
  {
170
174
  collection: "tenantSubscriptionEvents"
@@ -176,7 +180,7 @@ const ZRBRtsCounter = z.object({
176
180
  _id: z.string(),
177
181
  seq: z.number().int().min(0)
178
182
  });
179
- const RBRtsCounterSchema = new Schema(
183
+ const RBRtsCounterSchema = new Schema$1(
180
184
  {
181
185
  _id: { type: String, required: true },
182
186
  seq: { type: Number, required: true, default: 0 }
@@ -196,7 +200,7 @@ const ZRBRtsChange = z.object({
196
200
  docId: z.string().optional(),
197
201
  ts: z.date()
198
202
  });
199
- const RBRtsChangeSchema = new Schema(
203
+ const RBRtsChangeSchema = new Schema$1(
200
204
  {
201
205
  seq: { type: Number, required: true },
202
206
  modelName: { type: String, required: true, index: true },
@@ -228,7 +232,7 @@ const ZRBUploadSession = z.object({
228
232
  isPublic: z.boolean().optional(),
229
233
  error: z.string().optional()
230
234
  });
231
- const RBUploadSessionSchema = new Schema(
235
+ const RBUploadSessionSchema = new Schema$1(
232
236
  {
233
237
  _id: { type: String, required: true },
234
238
  userId: { type: String, required: false, index: true },
@@ -277,7 +281,7 @@ const ZRBUploadChunk = z.object({
277
281
  createdAt: z.date(),
278
282
  expiresAt: z.date()
279
283
  });
280
- const RBUploadChunkSchema = new Schema(
284
+ const RBUploadChunkSchema = new Schema$1(
281
285
  {
282
286
  uploadId: { type: String, required: true, index: true },
283
287
  index: { type: Number, required: true },
@@ -307,7 +311,7 @@ const ZRBNotification = z.object({
307
311
  metadata: z.record(z.string(), z.unknown()).optional()
308
312
  });
309
313
  const TTL_90_DAYS_S = 60 * 60 * 24 * 90;
310
- const RBNotificationSchema = new Schema(
314
+ const RBNotificationSchema = new Schema$1(
311
315
  {
312
316
  userId: { type: String, required: true, index: true },
313
317
  topic: { type: String, required: false, index: true },
@@ -318,7 +322,7 @@ const RBNotificationSchema = new Schema(
318
322
  seenAt: { type: Date, required: false, index: true },
319
323
  readAt: { type: Date, required: false, index: true },
320
324
  archivedAt: { type: Date, required: false },
321
- metadata: { type: Schema.Types.Mixed, required: false }
325
+ metadata: { type: Schema$1.Types.Mixed, required: false }
322
326
  },
323
327
  {
324
328
  versionKey: false,
@@ -352,7 +356,7 @@ const ZRBNotificationSettings = z.object({
352
356
  topicPreferences: z.array(ZRBNotificationTopicPreference).optional(),
353
357
  lastDigestSentAt: z.date().optional()
354
358
  });
355
- const TopicPreferenceSchema = new Schema(
359
+ const TopicPreferenceSchema = new Schema$1(
356
360
  {
357
361
  topic: { type: String, required: true },
358
362
  inApp: { type: Boolean, required: true, default: true },
@@ -361,7 +365,7 @@ const TopicPreferenceSchema = new Schema(
361
365
  },
362
366
  { _id: false }
363
367
  );
364
- const RBNotificationSettingsSchema = new Schema(
368
+ const RBNotificationSettingsSchema = new Schema$1(
365
369
  {
366
370
  userId: { type: String, required: true },
367
371
  digestFrequency: {
@@ -429,723 +433,309 @@ const frameworkSchemas = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.de
429
433
  ZRBUploadSessionStatus,
430
434
  ZRBUser
431
435
  }, 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";
436
+ function extendMongooseSchema(baseSchema, ...extensions) {
437
+ const schema = baseSchema.clone();
438
+ extensions.forEach((extension) => schema.add(extension));
439
+ return schema;
440
+ }
441
+ function omitMongooseSchemaPaths(schema, paths) {
442
+ const clone = schema.clone();
443
+ paths.forEach((path) => clone.remove(path));
444
+ return clone;
445
+ }
446
+ function localizedStringField(options) {
447
+ const userGet = options?.get;
448
+ return {
449
+ ...options,
450
+ type: Schema$1.Types.Mixed,
451
+ get: (value) => withLocalizedStringFallback(userGet ? userGet(value) : value)
452
+ };
453
+ }
454
+ const { Schema, model } = mongoose;
455
+ class PaginationValidationError extends Error {
456
+ code = "invalid_pagination";
457
+ statusCode = 400;
458
+ constructor(message, options) {
459
+ super(message, options);
460
+ this.name = "PaginationValidationError";
479
461
  }
462
+ }
463
+ const isPaginationValidationError = (error) => {
464
+ if (!error || typeof error !== "object") return false;
465
+ const anyError = error;
466
+ return anyError.name === "PaginationValidationError" && anyError.code === "invalid_pagination" && anyError.statusCode === 400;
480
467
  };
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;
468
+ const DISALLOWED_MONGO_FIELD_SEGMENTS = /* @__PURE__ */ new Set(["__proto__", "constructor", "prototype"]);
469
+ const PAGINATION_LIMIT_MAX = 128;
470
+ const normalizePaginationSpec = (spec) => {
471
+ if (!spec || typeof spec !== "object") throw new PaginationValidationError("Invalid PaginationSpec");
472
+ const limit = normalizeLimit(spec.limit);
473
+ const direction = spec.direction ?? "next";
474
+ if (direction !== "next" && direction !== "prev") throw new PaginationValidationError("Invalid pagination direction");
475
+ if (!Array.isArray(spec.sort) || spec.sort.length === 0) throw new PaginationValidationError("Invalid pagination sort");
476
+ const sort = spec.sort.map(({ field, order }) => ({
477
+ field: assertSafeMongoFieldPath(field),
478
+ order: normalizeOrder(order)
479
+ }));
480
+ const seenFields = /* @__PURE__ */ new Set();
481
+ for (const { field } of sort) {
482
+ if (seenFields.has(field)) throw new PaginationValidationError(`Duplicate pagination sort field: ${field}`);
483
+ seenFields.add(field);
520
484
  }
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");
485
+ const primaryOrder = sort[0]?.order;
486
+ if (!seenFields.has("_id")) {
487
+ sort.push({ field: "_id", order: primaryOrder });
561
488
  }
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));
489
+ return {
490
+ ...spec,
491
+ limit,
492
+ direction,
493
+ sort
567
494
  };
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
- }
495
+ };
496
+ const normalizeLimit = (limit) => {
497
+ if (typeof limit !== "number" || !Number.isFinite(limit) || !Number.isInteger(limit) || limit <= 0) {
498
+ throw new PaginationValidationError("Invalid pagination limit");
589
499
  }
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;
500
+ if (limit > PAGINATION_LIMIT_MAX) {
501
+ throw new PaginationValidationError("Invalid pagination limit");
600
502
  }
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
- };
503
+ return limit;
504
+ };
505
+ const normalizeOrder = (order) => {
506
+ if (order !== "asc" && order !== "desc") throw new PaginationValidationError("Invalid pagination order");
507
+ return order;
508
+ };
509
+ const assertSafeMongoFieldPath = (field) => {
510
+ if (typeof field !== "string" || field.length === 0) throw new PaginationValidationError("Invalid pagination sort field");
511
+ if (field.startsWith("$")) throw new PaginationValidationError("Invalid pagination sort field");
512
+ const parts = field.split(".");
513
+ for (const part of parts) {
514
+ if (part.length === 0) throw new PaginationValidationError("Invalid pagination sort field");
515
+ if (DISALLOWED_MONGO_FIELD_SEGMENTS.has(part)) throw new PaginationValidationError("Invalid pagination sort field");
516
+ if (!/^[a-zA-Z0-9_]+$/.test(part)) throw new PaginationValidationError("Invalid pagination sort field");
628
517
  }
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
- });
518
+ return field;
519
+ };
520
+ const encodePaginationCursor = (spec, node, options) => {
521
+ const normalized = normalizePaginationSpec(spec);
522
+ const values = /* @__PURE__ */ Object.create(null);
523
+ for (const { field } of normalized.sort) {
524
+ const value = readFieldValue(node, field);
525
+ if (typeof value === "undefined") {
526
+ throw new Error(`Pagination cursor encode failed (missing field: ${field})`);
653
527
  }
528
+ values[field] = encodeCursorValue(field, value);
654
529
  }
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;
530
+ const payload = { v: 1, values };
531
+ const payloadB64 = Buffer.from(JSON.stringify(payload), "utf8").toString("base64url");
532
+ const sigB64 = signCursorPayloadB64(payloadB64, options.signingSecret);
533
+ return `${payloadB64}.${sigB64}`;
534
+ };
535
+ const decodePaginationCursor = (spec, cursor, options) => {
536
+ const normalized = normalizePaginationSpec(spec);
537
+ const [payloadB64, sigB64, ...rest] = cursor.split(".");
538
+ if (rest.length > 0) throw new PaginationValidationError("Invalid pagination cursor format");
539
+ if (!sigB64) throw new PaginationValidationError("Invalid pagination cursor format");
540
+ verifyCursorSignature(payloadB64, sigB64, options.signingSecret);
541
+ const payloadRaw = Buffer.from(payloadB64, "base64url").toString("utf8");
542
+ let payloadUnknown;
755
543
  try {
756
- return getCanonicalLocales(trimmed)[0] ?? trimmed;
544
+ payloadUnknown = JSON.parse(payloadRaw);
757
545
  } catch {
758
- return trimmed;
546
+ throw new PaginationValidationError("Invalid pagination cursor payload");
759
547
  }
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();
548
+ if (!payloadUnknown || typeof payloadUnknown !== "object") throw new PaginationValidationError("Invalid pagination cursor payload");
549
+ const payload = payloadUnknown;
550
+ if (payload.v !== 1) throw new PaginationValidationError("Unsupported pagination cursor version");
551
+ if (!payload.values || typeof payload.values !== "object") throw new PaginationValidationError("Invalid pagination cursor payload");
552
+ const decoded = /* @__PURE__ */ Object.create(null);
553
+ for (const { field } of normalized.sort) {
554
+ if (!Object.prototype.hasOwnProperty.call(payload.values, field)) {
555
+ throw new PaginationValidationError(`Pagination cursor missing field: ${field}`);
779
556
  }
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];
557
+ const encodedValue = payload.values[field];
558
+ decoded[field] = decodeCursorValue(field, encodedValue);
794
559
  }
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;
560
+ return decoded;
832
561
  };
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
- );
562
+ const signCursorPayloadB64 = (payloadB64, secret) => {
563
+ return createHmac("sha256", secret).update(payloadB64, "utf8").digest("base64url");
564
+ };
565
+ const verifyCursorSignature = (payloadB64, sigB64, secret) => {
566
+ const expectedSigB64 = signCursorPayloadB64(payloadB64, secret);
567
+ const a = Buffer.from(sigB64, "utf8");
568
+ const b2 = Buffer.from(expectedSigB64, "utf8");
569
+ if (a.length !== b2.length || !timingSafeEqual(a, b2)) {
570
+ throw new PaginationValidationError("Invalid pagination cursor signature");
978
571
  }
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
- );
572
+ };
573
+ const encodeCursorValue = (field, value) => {
574
+ if (value === null) return null;
575
+ if (field === "_id") {
576
+ if (value instanceof Types.ObjectId) return { $oid: value.toHexString() };
577
+ throw new Error("Pagination cursor encode failed (_id must be an ObjectId)");
987
578
  }
988
- if (zmAssert$1.optional(field)) {
989
- return parseField(field._def.innerType, false, void 0, currentRefinement);
579
+ if (value instanceof Date) return { $date: value.toISOString() };
580
+ if (typeof value === "string" || typeof value === "number" || typeof value === "boolean") return value;
581
+ if (value instanceof Types.ObjectId) return { $oid: value.toHexString() };
582
+ throw new Error(`Unsupported pagination cursor value type for field: ${field}`);
583
+ };
584
+ const decodeCursorValue = (field, value) => {
585
+ if (value === null) return null;
586
+ if (typeof value === "string") {
587
+ if (field === "_id") throw new PaginationValidationError(`Invalid pagination cursor ObjectId for field: ${field}`);
588
+ return value;
990
589
  }
991
- if (zmAssert$1.nullable(field)) {
992
- return parseField(
993
- field._def.innerType,
994
- false,
995
- def || null,
996
- currentRefinement
997
- );
590
+ if (typeof value === "number" || typeof value === "boolean") return value;
591
+ if (!value || typeof value !== "object") throw new PaginationValidationError(`Invalid pagination cursor value for field: ${field}`);
592
+ if ("$date" in value) {
593
+ if (typeof value.$date !== "string") throw new PaginationValidationError(`Invalid pagination cursor date for field: ${field}`);
594
+ const d2 = new Date(value.$date);
595
+ if (Number.isNaN(d2.getTime())) throw new PaginationValidationError(`Invalid pagination cursor date for field: ${field}`);
596
+ return d2;
998
597
  }
999
- if (zmAssert$1.union(field)) {
1000
- return parseField(field._def.options[0], required, def, currentRefinement);
598
+ if ("$oid" in value) {
599
+ if (typeof value.$oid !== "string" || !Types.ObjectId.isValid(value.$oid)) {
600
+ throw new PaginationValidationError(`Invalid pagination cursor ObjectId for field: ${field}`);
601
+ }
602
+ return new Types.ObjectId(value.$oid);
1001
603
  }
1002
- if (zmAssert$1.any(field)) {
1003
- return parseMixed(required, def);
604
+ throw new PaginationValidationError(`Invalid pagination cursor value for field: ${field}`);
605
+ };
606
+ const readFieldValue = (node, field) => {
607
+ if (!node || typeof node !== "object") return void 0;
608
+ if ("get" in node && typeof node.get === "function") {
609
+ return node.get(field);
1004
610
  }
1005
- if (field.__rpcbase_localizedString) {
611
+ return field.split(".").reduce((acc, key) => {
612
+ if (!acc || typeof acc !== "object") return void 0;
613
+ return acc[key];
614
+ }, node);
615
+ };
616
+ const compileMongoPagination = (spec, options) => {
617
+ const normalized = normalizePaginationSpec(spec);
618
+ const mongoLimit = normalized.limit + 1;
619
+ const mongoSort = toMongoSort(normalized);
620
+ if (normalized.cursor == null) {
1006
621
  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)
622
+ spec: normalized,
623
+ mongoFilterDelta: {},
624
+ mongoSort,
625
+ mongoLimit
1025
626
  };
1026
627
  }
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
- );
628
+ if (typeof normalized.cursor !== "string" || normalized.cursor.length === 0) {
629
+ throw new PaginationValidationError("Invalid pagination cursor");
1038
630
  }
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) {
1068
- return {
1069
- type: String,
1070
- unique: false,
1071
- sparse: false,
1072
- default: def,
1073
- enum: values,
1074
- required
1075
- };
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");
631
+ const cursorValues = decodePaginationCursor(normalized, normalized.cursor, options.cursor);
632
+ const mongoFilterDelta = buildKeysetFilterDelta(normalized, cursorValues);
1109
633
  return {
1110
- type: [innerType],
1111
- default: def,
1112
- required
634
+ spec: normalized,
635
+ mongoFilterDelta,
636
+ mongoSort,
637
+ mongoLimit
1113
638
  };
1114
- }
1115
- function parseMap(required = true, valueType, def) {
1116
- if (!valueType) {
1117
- throw new Error("Unsupported map value type: undefined");
639
+ };
640
+ const toMongoSort = (spec) => {
641
+ const mongoSort = /* @__PURE__ */ Object.create(null);
642
+ for (const { field, order } of spec.sort) {
643
+ const forQueryOrder = spec.direction === "prev" ? invertOrder(order) : order;
644
+ mongoSort[field] = forQueryOrder === "asc" ? 1 : -1;
1118
645
  }
1119
- const pointer = parseField(valueType);
1120
- if (!pointer) {
1121
- const typeName = valueType?.constructor?.name ?? "unknown";
1122
- throw new Error(`Unsupported map value type (${typeName})`);
646
+ return mongoSort;
647
+ };
648
+ const buildKeysetFilterDelta = (spec, cursorValues) => {
649
+ const branches = [];
650
+ for (let i = 0; i < spec.sort.length; i++) {
651
+ const current = spec.sort[i];
652
+ if (!current) continue;
653
+ const and = [];
654
+ for (let j = 0; j < i; j++) {
655
+ const prev = spec.sort[j];
656
+ if (!prev) continue;
657
+ const eq = /* @__PURE__ */ Object.create(null);
658
+ eq[prev.field] = cursorValues[prev.field];
659
+ and.push(eq);
660
+ }
661
+ const op = getKeysetOp(current.order, spec.direction);
662
+ const cmpOp = /* @__PURE__ */ Object.create(null);
663
+ cmpOp[op] = cursorValues[current.field];
664
+ const cmp = /* @__PURE__ */ Object.create(null);
665
+ cmp[current.field] = cmpOp;
666
+ and.push(cmp);
667
+ branches.push(and.length === 1 ? and[0] : { $and: and });
1123
668
  }
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
669
+ return { $or: branches };
670
+ };
671
+ const getKeysetOp = (order, direction) => {
672
+ if (direction === "next") return order === "asc" ? "$gt" : "$lt";
673
+ return order === "asc" ? "$lt" : "$gt";
674
+ };
675
+ const invertOrder = (order) => {
676
+ return order === "asc" ? "desc" : "asc";
677
+ };
678
+ const materializeMongoPagination = (compiled, fetchedNodes, options) => {
679
+ const limit = compiled.spec.limit;
680
+ const hasMore = fetchedNodes.length > limit;
681
+ const trimmed = fetchedNodes.slice(0, limit);
682
+ const nodes = compiled.spec.direction === "prev" ? trimmed.reverse() : trimmed;
683
+ const hasPrevPage = compiled.spec.direction === "next" ? Boolean(compiled.spec.cursor) : hasMore;
684
+ const hasNextPage = compiled.spec.direction === "next" ? hasMore : Boolean(compiled.spec.cursor);
685
+ const pageInfo = {
686
+ hasNextPage,
687
+ hasPrevPage
1137
688
  };
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
689
+ if (nodes.length === 0) {
690
+ return { nodes, pageInfo };
691
+ }
692
+ if (hasPrevPage) {
693
+ pageInfo.prevCursor = encodePaginationCursor(compiled.spec, nodes[0], options.cursor);
694
+ }
695
+ if (hasNextPage) {
696
+ pageInfo.nextCursor = encodePaginationCursor(compiled.spec, nodes[nodes.length - 1], options.cursor);
697
+ }
698
+ return { nodes, pageInfo };
699
+ };
700
+ const MongoAdapter = {
701
+ applyPagination: (query, compiled) => {
702
+ query.where(compiled.mongoFilterDelta);
703
+ query.sort(compiled.mongoSort);
704
+ query.limit(compiled.mongoLimit);
705
+ return query;
706
+ }
707
+ };
708
+ const paginateMongoQuery = async (query, pagination, options) => {
709
+ const compiled = compileMongoPagination(pagination, { cursor: options.cursor });
710
+ MongoAdapter.applyPagination(query, compiled);
711
+ const fetchedNodes = await query.exec();
712
+ if (!Array.isArray(fetchedNodes)) {
713
+ throw new Error("paginateMongoQuery expects query.exec() to return an array");
714
+ }
715
+ return materializeMongoPagination(compiled, fetchedNodes, { cursor: options.cursor });
716
+ };
717
+ const getQueryOptions$1 = (query) => {
718
+ if (!query || typeof query !== "object") return void 0;
719
+ if (!("getOptions" in query) || typeof query.getOptions !== "function") return void 0;
720
+ return query.getOptions();
721
+ };
722
+ const getPaginationFromOptions = (query) => {
723
+ const options = getQueryOptions$1(query);
724
+ return options?.pagination;
725
+ };
726
+ const getCursorFromOptions = (query) => {
727
+ const options = getQueryOptions$1(query);
728
+ return options?.paginationCursor;
729
+ };
730
+ const mongoPaginationPlugin = (schema, pluginOptions) => {
731
+ schema.query.paginate = async function(pagination, options) {
732
+ const spec = pagination ?? getPaginationFromOptions(this);
733
+ if (!spec) throw new Error("Missing pagination spec");
734
+ const cursor = options?.cursor ?? getCursorFromOptions(this) ?? pluginOptions?.cursor;
735
+ if (!cursor?.signingSecret) throw new Error("Missing pagination cursor signingSecret");
736
+ return await paginateMongoQuery(this, spec, { cursor });
1147
737
  };
1148
- }
738
+ };
1149
739
  const getAppName$1 = (env = process.env) => {
1150
740
  const appName = env.APP_NAME?.trim();
1151
741
  if (!appName) {
@@ -1237,11 +827,11 @@ const insertChanges = async (db, changes) => {
1237
827
  if (!changes.length) return;
1238
828
  const { RtsChange } = getRtsModels(db);
1239
829
  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,
830
+ await RtsChange.insertMany(changes.map((c2) => ({
831
+ seq: c2.seq,
832
+ modelName: c2.modelName,
833
+ op: c2.op,
834
+ docId: c2.docId ?? void 0,
1245
835
  ts
1246
836
  })));
1247
837
  };
@@ -1272,7 +862,7 @@ const captureDeleteMeta = async (query, mode) => {
1272
862
  findQuery.limit(maxDeleteIds + 1);
1273
863
  }
1274
864
  const docs = await findQuery;
1275
- const ids = Array.isArray(docs) ? docs.map((d) => normalizeId(d?._id)).filter((id) => Boolean(id)) : [];
865
+ const ids = Array.isArray(docs) ? docs.map((d2) => normalizeId(d2?._id)).filter((id) => Boolean(id)) : [];
1276
866
  const reset = mode === "many" && ids.length > maxDeleteIds;
1277
867
  const trimmedIds = reset ? [] : ids;
1278
868
  const meta = {
@@ -1326,125 +916,6 @@ const rtsChangeLogPlugin = (schema) => {
1326
916
  }
1327
917
  });
1328
918
  };
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
919
  const isRecord = (value) => Boolean(value) && typeof value === "object" && !Array.isArray(value);
1449
920
  const mergeMongoQuery = (left, right) => {
1450
921
  const leftQuery = isRecord(left) ? left : {};
@@ -1452,13 +923,13 @@ const mergeMongoQuery = (left, right) => {
1452
923
  if (Object.keys(right).length === 0) return leftQuery;
1453
924
  return { $and: [leftQuery, right] };
1454
925
  };
1455
- const getQueryOptions$1 = (query) => {
926
+ const getQueryOptions = (query) => {
1456
927
  if (!query || typeof query !== "object") return void 0;
1457
928
  if (!("getOptions" in query) || typeof query.getOptions !== "function") return void 0;
1458
929
  return query.getOptions();
1459
930
  };
1460
931
  const getStoredAclFromQuery = (query) => {
1461
- const options = getQueryOptions$1(query);
932
+ const options = getQueryOptions(query);
1462
933
  const raw = options?.rbAcl;
1463
934
  if (!isRecord(raw)) return null;
1464
935
  if (!("ability" in raw)) return null;
@@ -1526,8 +997,8 @@ const patchAggregateAcl = () => {
1526
997
  return this;
1527
998
  };
1528
999
  };
1529
- const createModelAclProxy = (model, ability) => {
1530
- return new Proxy(model, {
1000
+ const createModelAclProxy = (model2, ability) => {
1001
+ return new Proxy(model2, {
1531
1002
  get(target, prop, receiver) {
1532
1003
  const value = Reflect.get(target, prop, receiver);
1533
1004
  if (typeof value !== "function") return value;
@@ -1590,290 +1061,6 @@ const mongooseAclPlugin = (schema) => {
1590
1061
  addQueryAclFilter(this, "update");
1591
1062
  });
1592
1063
  };
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
1064
  let cachedModels = null;
1878
1065
  const DEFAULT_GLOBAL_RB_MODEL_NAMES_SET = /* @__PURE__ */ new Set([
1879
1066
  "RBUser",
@@ -2043,6 +1230,7 @@ export {
2043
1230
  RBUploadSessionPolicy,
2044
1231
  RBUploadSessionSchema,
2045
1232
  RBUserSchema,
1233
+ Schema,
2046
1234
  ZRBNotification,
2047
1235
  ZRBNotificationDigestFrequency,
2048
1236
  ZRBNotificationSettings,
@@ -2063,30 +1251,31 @@ export {
2063
1251
  ZRBUploadSession,
2064
1252
  ZRBUploadSessionStatus,
2065
1253
  ZRBUser,
2066
- buildAbility,
2067
- buildAbilityFromSession,
1254
+ b as buildAbility,
1255
+ d as buildAbilityFromSession,
2068
1256
  buildLocaleFallbackChain,
2069
- can,
1257
+ f as can,
2070
1258
  createModels,
1259
+ extendMongooseSchema,
2071
1260
  extendZod,
2072
- getAccessibleByQuery,
2073
- getRegisteredPolicies,
1261
+ e as getAccessibleByQuery,
1262
+ g as getRegisteredPolicies,
2074
1263
  getTenantFilesystemDb,
2075
1264
  getTenantFilesystemDbFromCtx,
2076
1265
  getTenantFilesystemDbName,
2077
- getTenantRolesFromSessionUser,
1266
+ c as getTenantRolesFromSessionUser,
2078
1267
  isPaginationValidationError,
1268
+ localizedStringField,
1269
+ model,
2079
1270
  models,
2080
1271
  mongoPaginationPlugin,
1272
+ default2 as mongoose,
1273
+ omitMongooseSchemaPaths,
2081
1274
  registerPoliciesFromModules,
2082
- registerPolicy,
1275
+ r as registerPolicy,
2083
1276
  resolveLocalizedString,
2084
1277
  withLocalizedStringFallback,
2085
1278
  z2 as z,
2086
1279
  zI18nString,
2087
- zId,
2088
- zLocalizedString,
2089
- zUUID,
2090
- zodSchema,
2091
- zodSchemaRaw
1280
+ zLocalizedString
2092
1281
  };