@web-ts-toolkit/access-router 0.47.0 → 0.48.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/index.mjs CHANGED
@@ -137,6 +137,12 @@ function genPagination({
137
137
  }
138
138
  return { skip: _skip, limit: _limit };
139
139
  }
140
+ function parseSelectParam(select) {
141
+ if (select === void 0) return void 0;
142
+ const values = Array.isArray(select) ? select : [select];
143
+ const fields = values.flatMap((value) => String(value).split(/[\s,]+/)).filter(Boolean);
144
+ return fields.length > 0 ? fields : void 0;
145
+ }
140
146
  function normalizeSelect(select) {
141
147
  if (Array.isArray(select)) return flattenDeep(select.map(normalizeSelect));
142
148
  if (isPlainObject(select)) {
@@ -178,6 +184,15 @@ function getDocPermissions(modelName, doc) {
178
184
  const permissions = getDocValue(doc, docPermissionField, {});
179
185
  return isPlainObject2(permissions) ? permissions : {};
180
186
  }
187
+ function stripUnexposedDocPermissions(modelName, doc) {
188
+ const exposed = getModelOption(modelName, "exposedDocPermissionKeys");
189
+ if (exposed === void 0) return;
190
+ const docPermissionField = getModelOption(modelName, "documentPermissionField");
191
+ const current = getDocValue(doc, docPermissionField, void 0);
192
+ if (!isPlainObject2(current)) return;
193
+ const keep = /* @__PURE__ */ new Set(["_view", "_edit", ...exposed]);
194
+ setDocValue(doc, docPermissionField, Object.fromEntries(Object.entries(current).filter(([key]) => keep.has(key))));
195
+ }
181
196
  function toObject(doc) {
182
197
  return isDocument(doc) ? doc.toObject() : doc;
183
198
  }
@@ -1166,11 +1181,11 @@ var classifyPermissionSchema = (permissionSchema, modelPermissionPrefix) => {
1166
1181
  }
1167
1182
  if (isBoolean(value)) {
1168
1183
  globalPermissionKeys[accessKey].push(schemaKey);
1169
- return;
1184
+ continue;
1170
1185
  }
1171
1186
  if (hasModelPermission(value, modelPermissionPrefix)) {
1172
1187
  modelPermissionKeys[accessKey].push(schemaKey);
1173
- return;
1188
+ continue;
1174
1189
  }
1175
1190
  globalPermissionKeys[accessKey].push(schemaKey);
1176
1191
  }
@@ -2432,7 +2447,8 @@ var Base = class {
2432
2447
  ...options,
2433
2448
  access: "read",
2434
2449
  lean: true,
2435
- includePermissions: false
2450
+ includePermissions: false,
2451
+ includeFieldPermissions: false
2436
2452
  };
2437
2453
  const result = await svc.findOne(filter2, this.sanitizeIncludeArgs(args), trustedOptions);
2438
2454
  if (result.success) {
@@ -2460,6 +2476,7 @@ var Base = class {
2460
2476
  ...options,
2461
2477
  lean: true,
2462
2478
  includePermissions: false,
2479
+ includeFieldPermissions: false,
2463
2480
  includeCount: false
2464
2481
  };
2465
2482
  const trustedResult = await svc.find(filter2, trustedArgs, trustedOptions);
@@ -2590,7 +2607,7 @@ var Base = class {
2590
2607
  include: nestedInclude,
2591
2608
  overrides: { filter: authorized }
2592
2609
  },
2593
- { access: "read", lean: true, includePermissions: false }
2610
+ { access: "read", lean: true, includePermissions: false, includeFieldPermissions: false }
2594
2611
  );
2595
2612
  } catch (error2) {
2596
2613
  const clientResult = this.getClientRequestErrorResult(error2);
@@ -2668,7 +2685,7 @@ var Base = class {
2668
2685
  include: nestedInclude,
2669
2686
  overrides: { filter: authorized }
2670
2687
  },
2671
- { access: "read", lean: true, includePermissions: false }
2688
+ { access: "read", lean: true, includePermissions: false, includeFieldPermissions: false }
2672
2689
  );
2673
2690
  } catch (error2) {
2674
2691
  const clientResult = this.getClientRequestErrorResult(error2);
@@ -2753,7 +2770,7 @@ var Base = class {
2753
2770
  include: nestedInclude,
2754
2771
  overrides: { filter: authorized }
2755
2772
  },
2756
- { includeCount: false, lean: true, includePermissions: false }
2773
+ { includeCount: false, lean: true, includePermissions: false, includeFieldPermissions: false }
2757
2774
  );
2758
2775
  } catch (error2) {
2759
2776
  const clientResult = this.getClientRequestErrorResult(error2);
@@ -3345,6 +3362,16 @@ async function getParentDoc(service, id, sub, args, options) {
3345
3362
  }
3346
3363
 
3347
3364
  // src/services/model-service-defaults.ts
3365
+ function applyPermissionsPosture(service, resolved) {
3366
+ const posture = service.getPermissionsPosture();
3367
+ if (posture.stripPermissionsField) {
3368
+ resolved.includePermissions = false;
3369
+ resolved.includeFieldPermissions = false;
3370
+ } else if (posture.disableFieldPermissions) {
3371
+ resolved.includeFieldPermissions = false;
3372
+ }
3373
+ return resolved;
3374
+ }
3348
3375
  function resolveFindOneArgs(service, args = {}) {
3349
3376
  return {
3350
3377
  select: args.select ?? service.defaults.findOneArgs?.select,
@@ -3355,13 +3382,15 @@ function resolveFindOneArgs(service, args = {}) {
3355
3382
  };
3356
3383
  }
3357
3384
  function resolveFindOneOptions(service, options = {}) {
3358
- return {
3385
+ const includePermissions = options.includePermissions ?? service.defaults.findOneOptions?.includePermissions ?? true;
3386
+ return applyPermissionsPosture(service, {
3359
3387
  skim: options.skim ?? service.defaults.findOneOptions?.skim ?? false,
3360
- includePermissions: options.includePermissions ?? service.defaults.findOneOptions?.includePermissions ?? true,
3388
+ includePermissions,
3389
+ includeFieldPermissions: options.includeFieldPermissions ?? service.defaults.findOneOptions?.includeFieldPermissions ?? includePermissions,
3361
3390
  access: options.access ?? service.defaults.findOneOptions?.access ?? "read",
3362
3391
  populateAccess: options.populateAccess ?? service.defaults.findOneOptions?.populateAccess,
3363
3392
  lean: options.lean ?? service.defaults.findOneOptions?.lean ?? false
3364
- };
3393
+ });
3365
3394
  }
3366
3395
  function resolveFindByIdArgs(service, args = {}) {
3367
3396
  return {
@@ -3372,13 +3401,15 @@ function resolveFindByIdArgs(service, args = {}) {
3372
3401
  };
3373
3402
  }
3374
3403
  function resolveFindByIdOptions(service, options = {}) {
3375
- return {
3404
+ const includePermissions = options.includePermissions ?? service.defaults.findByIdOptions?.includePermissions ?? true;
3405
+ return applyPermissionsPosture(service, {
3376
3406
  skim: options.skim ?? service.defaults.findByIdOptions?.skim ?? false,
3377
- includePermissions: options.includePermissions ?? service.defaults.findByIdOptions?.includePermissions ?? true,
3407
+ includePermissions,
3408
+ includeFieldPermissions: options.includeFieldPermissions ?? service.defaults.findByIdOptions?.includeFieldPermissions ?? includePermissions,
3378
3409
  access: options.access ?? service.defaults.findByIdOptions?.access ?? "read",
3379
3410
  populateAccess: options.populateAccess ?? service.defaults.findByIdOptions?.populateAccess,
3380
3411
  lean: options.lean ?? service.defaults.findByIdOptions?.lean ?? false
3381
- };
3412
+ });
3382
3413
  }
3383
3414
  function resolveFindArgs(service, args = {}) {
3384
3415
  return {
@@ -3394,13 +3425,15 @@ function resolveFindArgs(service, args = {}) {
3394
3425
  };
3395
3426
  }
3396
3427
  function resolveFindOptions(service, options = {}) {
3397
- return {
3428
+ const includePermissions = options.includePermissions ?? service.defaults.findOptions?.includePermissions ?? true;
3429
+ return applyPermissionsPosture(service, {
3398
3430
  skim: options.skim ?? service.defaults.findOptions?.skim ?? false,
3399
- includePermissions: options.includePermissions ?? service.defaults.findOptions?.includePermissions ?? true,
3431
+ includePermissions,
3432
+ includeFieldPermissions: options.includeFieldPermissions ?? service.defaults.findOptions?.includeFieldPermissions ?? includePermissions,
3400
3433
  includeCount: options.includeCount ?? service.defaults.findOptions?.includeCount ?? false,
3401
3434
  populateAccess: options.populateAccess ?? service.defaults.findOptions?.populateAccess ?? "read",
3402
3435
  lean: options.lean ?? service.defaults.findOptions?.lean ?? false
3403
- };
3436
+ });
3404
3437
  }
3405
3438
  function resolveCreateArgs(service, args = {}) {
3406
3439
  return {
@@ -3408,11 +3441,13 @@ function resolveCreateArgs(service, args = {}) {
3408
3441
  };
3409
3442
  }
3410
3443
  function resolveCreateOptions(service, options = {}) {
3411
- return {
3444
+ const includePermissions = options.includePermissions ?? service.defaults.createOptions?.includePermissions ?? true;
3445
+ return applyPermissionsPosture(service, {
3412
3446
  skim: options.skim ?? service.defaults.createOptions?.skim ?? false,
3413
- includePermissions: options.includePermissions ?? service.defaults.createOptions?.includePermissions ?? true,
3447
+ includePermissions,
3448
+ includeFieldPermissions: options.includeFieldPermissions ?? service.defaults.createOptions?.includeFieldPermissions ?? includePermissions,
3414
3449
  populateAccess: options.populateAccess ?? service.defaults.createOptions?.populateAccess ?? "read"
3415
- };
3450
+ });
3416
3451
  }
3417
3452
  function resolveUpdateOneArgs(service, args = {}) {
3418
3453
  return {
@@ -3421,11 +3456,13 @@ function resolveUpdateOneArgs(service, args = {}) {
3421
3456
  };
3422
3457
  }
3423
3458
  function resolveUpdateOneOptions(service, options = {}) {
3424
- return {
3459
+ const includePermissions = options.includePermissions ?? service.defaults.updateOneOptions?.includePermissions ?? true;
3460
+ return applyPermissionsPosture(service, {
3425
3461
  skim: options.skim ?? service.defaults.updateOneOptions?.skim ?? false,
3426
- includePermissions: options.includePermissions ?? service.defaults.updateOneOptions?.includePermissions ?? true,
3462
+ includePermissions,
3463
+ includeFieldPermissions: options.includeFieldPermissions ?? service.defaults.updateOneOptions?.includeFieldPermissions ?? includePermissions,
3427
3464
  populateAccess: options.populateAccess ?? service.defaults.updateOneOptions?.populateAccess ?? "read"
3428
- };
3465
+ });
3429
3466
  }
3430
3467
  function resolveUpdateByIdArgs(service, args = {}) {
3431
3468
  return {
@@ -3434,11 +3471,13 @@ function resolveUpdateByIdArgs(service, args = {}) {
3434
3471
  };
3435
3472
  }
3436
3473
  function resolveUpdateByIdOptions(service, options = {}) {
3437
- return {
3474
+ const includePermissions = options.includePermissions ?? service.defaults.updateByIdOptions?.includePermissions ?? true;
3475
+ return applyPermissionsPosture(service, {
3438
3476
  skim: options.skim ?? service.defaults.updateByIdOptions?.skim ?? false,
3439
- includePermissions: options.includePermissions ?? service.defaults.updateByIdOptions?.includePermissions ?? true,
3477
+ includePermissions,
3478
+ includeFieldPermissions: options.includeFieldPermissions ?? service.defaults.updateByIdOptions?.includeFieldPermissions ?? includePermissions,
3440
3479
  populateAccess: options.populateAccess ?? service.defaults.updateByIdOptions?.populateAccess ?? "read"
3441
- };
3480
+ });
3442
3481
  }
3443
3482
  function resolveUpsertArgs(service, args = {}) {
3444
3483
  return {
@@ -3447,11 +3486,13 @@ function resolveUpsertArgs(service, args = {}) {
3447
3486
  };
3448
3487
  }
3449
3488
  function resolveUpsertOptions(service, options = {}) {
3450
- return {
3489
+ const includePermissions = options.includePermissions ?? service.defaults.upsertOptions?.includePermissions ?? true;
3490
+ return applyPermissionsPosture(service, {
3451
3491
  skim: options.skim ?? service.defaults.upsertOptions?.skim ?? false,
3452
- includePermissions: options.includePermissions ?? service.defaults.upsertOptions?.includePermissions ?? true,
3492
+ includePermissions,
3493
+ includeFieldPermissions: options.includeFieldPermissions ?? service.defaults.upsertOptions?.includeFieldPermissions ?? includePermissions,
3453
3494
  populateAccess: options.populateAccess ?? service.defaults.upsertOptions?.populateAccess ?? "read"
3454
- };
3495
+ });
3455
3496
  }
3456
3497
  function resolveExistsOptions(service, options = {}) {
3457
3498
  return {
@@ -3513,6 +3554,27 @@ var Service = class extends Base {
3513
3554
  getModelRouterOptions(modelName) {
3514
3555
  return getModelOptions(modelName);
3515
3556
  }
3557
+ /**
3558
+ * Router-level permission output postures (see `ModelRouterOptions`).
3559
+ * Absolute: they win over client input and per-operation `defaults`.
3560
+ */
3561
+ getPermissionsPosture() {
3562
+ return {
3563
+ stripPermissionsField: this.options.stripPermissionsField ?? false,
3564
+ disableFieldPermissions: this.options.disableFieldPermissions ?? false
3565
+ };
3566
+ }
3567
+ /**
3568
+ * Router posture `stripPermissionsField`: drop the whole document
3569
+ * permissions field (including the empty placeholder) from output instead
3570
+ * of emitting permission metadata. Returns true when applied.
3571
+ */
3572
+ stripPermissionsOutput(doc) {
3573
+ if (!this.options.stripPermissionsField) return false;
3574
+ const field = this.options.documentPermissionField;
3575
+ if (field) unsetDocPath(doc, field);
3576
+ return true;
3577
+ }
3516
3578
  asServiceHookContext(context) {
3517
3579
  return context;
3518
3580
  }
@@ -3520,6 +3582,14 @@ var Service = class extends Base {
3520
3582
  const extra = this.options?.sortableFields ?? [];
3521
3583
  return extra.length > 0 ? [...allowedSortFields, ...extra] : allowedSortFields;
3522
3584
  }
3585
+ /**
3586
+ * With `requireExplicitSelect`, an omitted client select behaves as an
3587
+ * `_id`-only projection, yielding field-less rows. Explicit selects pass
3588
+ * through untouched.
3589
+ */
3590
+ resolveEffectiveSelect(select) {
3591
+ return this.options?.requireExplicitSelect && select === void 0 ? ["_id"] : select;
3592
+ }
3523
3593
  beginOp(op, filter2, extra) {
3524
3594
  const startedAt = Date.now();
3525
3595
  debug({
@@ -3544,8 +3614,9 @@ var Service = class extends Base {
3544
3614
  async findOne(filter2, args, options) {
3545
3615
  const filterErrors = this.validateClientFilter(filter2);
3546
3616
  if (filterErrors.length > 0) return { success: false, kind: "error", code: "bad_request" /* BadRequest */, errors: filterErrors };
3547
- const { select, sort, populate, include, overrides } = this.resolveFindOneArgs(args);
3548
- const { skim, includePermissions, access, populateAccess, lean } = this.resolveFindOneOptions(options);
3617
+ const { select: requestedSelect, sort, populate, include, overrides } = this.resolveFindOneArgs(args);
3618
+ const select = this.resolveEffectiveSelect(requestedSelect);
3619
+ const { skim, includePermissions, includeFieldPermissions, access, populateAccess, lean } = this.resolveFindOneOptions(options);
3549
3620
  const { filter: overrideFilter, select: overrideSelect, populate: overridePopulate } = overrides ?? {};
3550
3621
  let parsedFilter;
3551
3622
  let processedInclude;
@@ -3626,11 +3697,11 @@ var Service = class extends Base {
3626
3697
  throw error2;
3627
3698
  }
3628
3699
  let includeDocPermissions = includePermissions;
3629
- if (!includeDocPermissions && !skim) {
3700
+ if (!includeDocPermissions && (!skim || includeFieldPermissions)) {
3630
3701
  includeDocPermissions = this.checkIfModelPermissionExists([access, "read", "update"]);
3631
3702
  }
3632
3703
  if (includeDocPermissions) doc = await this.addDocPermissions(doc, access, context);
3633
- if (includePermissions) doc = await this.addFieldPermissions(doc, access, context);
3704
+ if (includeFieldPermissions) doc = await this.addFieldPermissions(doc, access, context);
3634
3705
  doc = await this.trimOutputFields(
3635
3706
  doc,
3636
3707
  access,
@@ -3648,13 +3719,16 @@ var Service = class extends Base {
3648
3719
  if (!shouldKeepCorrelatedRef(ref, keep)) unsetDocPath(doc, ref);
3649
3720
  }
3650
3721
  }
3651
- if (!includePermissions) doc = this.addEmptyPermissions(doc);
3722
+ if (!this.stripPermissionsOutput(doc)) {
3723
+ if (!includePermissions && !includeFieldPermissions) doc = this.addEmptyPermissions(doc);
3724
+ stripUnexposedDocPermissions(this.modelName, doc);
3725
+ }
3652
3726
  this.completeOp("findOne", startedAt, "success" /* Success */, _filter);
3653
3727
  return { success: true, kind: "single", code: "success" /* Success */, data: doc, query, context };
3654
3728
  }
3655
3729
  async findById(id, args, options) {
3656
3730
  const { select, populate, include, overrides } = this.resolveFindByIdArgs(args);
3657
- const { skim, includePermissions, access, populateAccess, lean } = this.resolveFindByIdOptions(options);
3731
+ const { skim, includePermissions, includeFieldPermissions, access, populateAccess, lean } = this.resolveFindByIdOptions(options);
3658
3732
  const { select: overrideSelect, populate: overridePopulate, idFilter: overrideIdFilter } = overrides ?? {};
3659
3733
  const filter2 = overrideIdFilter ?? await this.genIDFilter(id);
3660
3734
  if (filter2 === false) return { success: false, kind: "error", code: "forbidden" /* Forbidden */, query: { filter: filter2 } };
@@ -3669,14 +3743,25 @@ var Service = class extends Base {
3669
3743
  populate: overridePopulate
3670
3744
  }
3671
3745
  },
3672
- { skim, includePermissions, access, populateAccess, lean }
3746
+ { skim, includePermissions, includeFieldPermissions, access, populateAccess, lean }
3673
3747
  );
3674
3748
  }
3675
3749
  async find(filter2, args, options, decorate) {
3676
3750
  const filterErrors = this.validateClientFilter(filter2);
3677
3751
  if (filterErrors.length > 0) return { success: false, kind: "error", code: "bad_request" /* BadRequest */, errors: filterErrors };
3678
- const { select, populate, include, sort, skip, limit, page, pageSize, overrides } = this.resolveFindArgs(args);
3679
- const { skim, includePermissions, includeCount, populateAccess, lean } = this.resolveFindOptions(options);
3752
+ const {
3753
+ select: requestedSelect,
3754
+ populate,
3755
+ include,
3756
+ sort,
3757
+ skip,
3758
+ limit,
3759
+ page,
3760
+ pageSize,
3761
+ overrides
3762
+ } = this.resolveFindArgs(args);
3763
+ const select = this.resolveEffectiveSelect(requestedSelect);
3764
+ const { skim, includePermissions, includeFieldPermissions, includeCount, populateAccess, lean } = this.resolveFindOptions(options);
3680
3765
  const { filter: overrideFilter, select: overrideSelect, populate: overridePopulate } = overrides ?? {};
3681
3766
  let parsedFilter;
3682
3767
  let processedInclude;
@@ -3760,16 +3845,16 @@ var Service = class extends Base {
3760
3845
  }
3761
3846
  throw error2;
3762
3847
  }
3763
- const fieldPermissionAccess = includePermissions ? await this.getFieldPermissionAccess(docs.map((doc) => doc._id)) : void 0;
3848
+ const fieldPermissionAccess = includeFieldPermissions ? await this.getFieldPermissionAccess(docs.map((doc) => doc._id)) : void 0;
3764
3849
  docs = await Promise.all(
3765
3850
  docs.map(async (doc, i) => {
3766
3851
  this.asServiceHookContext(contexts[i]).fieldPermissionAccess = fieldPermissionAccess;
3767
3852
  let includeDocPermissions = includePermissions;
3768
- if (!includeDocPermissions && !skim) {
3853
+ if (!includeDocPermissions && (!skim || includeFieldPermissions)) {
3769
3854
  includeDocPermissions = this.checkIfModelPermissionExists(["list", "read", "update"]);
3770
3855
  }
3771
3856
  if (includeDocPermissions) doc = await this.addDocPermissions(doc, "list", contexts[i]);
3772
- if (includePermissions) doc = await this.addFieldPermissions(doc, "list", contexts[i]);
3857
+ if (includeFieldPermissions) doc = await this.addFieldPermissions(doc, "list", contexts[i]);
3773
3858
  doc = await this.trimOutputFields(
3774
3859
  doc,
3775
3860
  "list",
@@ -3788,7 +3873,10 @@ var Service = class extends Base {
3788
3873
  }
3789
3874
  }
3790
3875
  doc = await _decorate(doc, contexts[i]);
3791
- if (!includePermissions) doc = this.addEmptyPermissions(doc);
3876
+ if (!this.stripPermissionsOutput(doc)) {
3877
+ if (!includePermissions && !includeFieldPermissions) doc = this.addEmptyPermissions(doc);
3878
+ stripUnexposedDocPermissions(this.modelName, doc);
3879
+ }
3792
3880
  return doc;
3793
3881
  })
3794
3882
  );
@@ -3806,7 +3894,7 @@ var Service = class extends Base {
3806
3894
  }
3807
3895
  async create(data, args, options, decorate) {
3808
3896
  const { populate } = this.resolveCreateArgs(args);
3809
- const { skim, includePermissions, populateAccess } = this.resolveCreateOptions(options);
3897
+ const { skim, includePermissions, includeFieldPermissions, populateAccess } = this.resolveCreateOptions(options);
3810
3898
  const isArr = Array.isArray(data);
3811
3899
  let dataArr = isArr ? data : [data];
3812
3900
  const { maxBulkItems, maxBulkConcurrency } = this.getRequestComplexity();
@@ -3913,15 +4001,18 @@ var Service = class extends Base {
3913
4001
  contexts[index].currentDocument = doc;
3914
4002
  contexts[index].finalDocumentSnapshot = doc.toObject({ virtuals: false });
3915
4003
  let includeDocPermissions = includePermissions;
3916
- if (!includeDocPermissions && !skim) {
4004
+ if (!includeDocPermissions && (!skim || includeFieldPermissions)) {
3917
4005
  includeDocPermissions = this.checkIfModelPermissionExists(["create", "read", "update"]);
3918
4006
  }
3919
4007
  if (includeDocPermissions) doc = await this.addDocPermissions(doc, "create", contexts[index]);
3920
- if (includePermissions) doc = await this.addFieldPermissions(doc, "read", contexts[index]);
4008
+ if (includeFieldPermissions) doc = await this.addFieldPermissions(doc, "read", contexts[index]);
3921
4009
  if (resolvedPopulate.length > 0) await this.persist(() => populateDoc(doc, resolvedPopulate));
3922
4010
  doc = await this.trimOutputFields(doc, "read", this.baseFieldsExt);
3923
4011
  let outputDoc = await _decorate(doc, contexts[index]);
3924
- if (!includePermissions) outputDoc = this.addEmptyPermissions(outputDoc);
4012
+ if (!this.stripPermissionsOutput(outputDoc)) {
4013
+ if (!includePermissions && !includeFieldPermissions) outputDoc = this.addEmptyPermissions(outputDoc);
4014
+ stripUnexposedDocPermissions(this.modelName, outputDoc);
4015
+ }
3925
4016
  return outputDoc;
3926
4017
  });
3927
4018
  return {
@@ -3957,7 +4048,8 @@ var Service = class extends Base {
3957
4048
  return { ...typedIssue, detail, pointer: `#/${index}` };
3958
4049
  }
3959
4050
  async new(args, options) {
3960
- const { skim, includePermissions } = options ?? {};
4051
+ const { skim, includePermissions: requestedPermissions } = options ?? {};
4052
+ const includePermissions = this.options.stripPermissionsField ? false : requestedPermissions;
3961
4053
  const data = await this.model.new();
3962
4054
  let doc = data;
3963
4055
  doc = await this.trimOutputFields(doc, "create", this.baseFieldsExt);
@@ -3966,7 +4058,10 @@ var Service = class extends Base {
3966
4058
  includeDocPermissions = this.checkIfModelPermissionExists(["create", "read", "update"]);
3967
4059
  }
3968
4060
  if (includeDocPermissions) doc = await this.addDocPermissions(doc, "create", {});
3969
- if (!includePermissions) doc = this.addEmptyPermissions(doc);
4061
+ if (!this.stripPermissionsOutput(doc)) {
4062
+ if (!includePermissions) doc = this.addEmptyPermissions(doc);
4063
+ stripUnexposedDocPermissions(this.modelName, doc);
4064
+ }
3970
4065
  return {
3971
4066
  success: true,
3972
4067
  kind: "single",
@@ -3985,7 +4080,7 @@ var Service = class extends Base {
3985
4080
  const filterErrors = this.validateClientFilter(filter2);
3986
4081
  if (filterErrors.length > 0) return { success: false, kind: "error", code: "bad_request" /* BadRequest */, errors: filterErrors };
3987
4082
  const { populate, overrides } = this.resolveUpdateOneArgs(args);
3988
- const { skim, includePermissions, populateAccess } = this.resolveUpdateOneOptions(options);
4083
+ const { skim, includePermissions, includeFieldPermissions, populateAccess } = this.resolveUpdateOneOptions(options);
3989
4084
  const { filter: overrideFilter, populate: overridePopulate } = overrides ?? {};
3990
4085
  const [_filter, _populate] = await Promise.all([
3991
4086
  overrideFilter ?? this.genFilter("update", filter2),
@@ -4062,22 +4157,25 @@ var Service = class extends Base {
4062
4157
  this.asServiceHookContext(context).diff(doc);
4063
4158
  await this.changes(doc.toObject({ virtuals: false }), context);
4064
4159
  let includeDocPermissions = includePermissions;
4065
- if (!includeDocPermissions && !skim) {
4160
+ if (!includeDocPermissions && (!skim || includeFieldPermissions)) {
4066
4161
  includeDocPermissions = this.checkIfModelPermissionExists(["read", "update"]);
4067
4162
  }
4068
4163
  if (includeDocPermissions) doc = await this.addDocPermissions(doc, "update", context);
4069
- if (includePermissions) doc = await this.addFieldPermissions(doc, "update", context);
4164
+ if (includeFieldPermissions) doc = await this.addFieldPermissions(doc, "update", context);
4070
4165
  if (_populate) await this.persist(() => populateDoc(doc, _populate));
4071
4166
  doc = await this.trimOutputFields(doc, "read", this.baseFieldsExt);
4072
4167
  let outputDoc = doc;
4073
4168
  if (isFunction3(decorate)) outputDoc = await decorate(outputDoc, context);
4074
- if (!includePermissions) outputDoc = this.addEmptyPermissions(outputDoc);
4169
+ if (!this.stripPermissionsOutput(outputDoc)) {
4170
+ if (!includePermissions && !includeFieldPermissions) outputDoc = this.addEmptyPermissions(outputDoc);
4171
+ stripUnexposedDocPermissions(this.modelName, outputDoc);
4172
+ }
4075
4173
  this.completeOp("updateOne", startedAt, "success" /* Success */, _filter);
4076
4174
  return { success: true, kind: "single", code: "success" /* Success */, data: outputDoc, input: prepared };
4077
4175
  }
4078
4176
  async updateById(id, data, args = {}, options = {}, decorate) {
4079
4177
  const { populate, overrides } = this.resolveUpdateByIdArgs(args);
4080
- const { skim, includePermissions, populateAccess } = this.resolveUpdateByIdOptions(options);
4178
+ const { skim, includePermissions, includeFieldPermissions, populateAccess } = this.resolveUpdateByIdOptions(options);
4081
4179
  const { populate: overridePopulate, idFilter: overrideIdFilter } = overrides;
4082
4180
  const filter2 = overrideIdFilter ?? await this.genIDFilter(id);
4083
4181
  if (filter2 === false) return { success: false, kind: "error", code: "forbidden" /* Forbidden */, query: { filter: filter2 } };
@@ -4090,7 +4188,7 @@ var Service = class extends Base {
4090
4188
  populate: overridePopulate
4091
4189
  }
4092
4190
  },
4093
- { skim, includePermissions, populateAccess },
4191
+ { skim, includePermissions, includeFieldPermissions, populateAccess },
4094
4192
  decorate
4095
4193
  );
4096
4194
  }
@@ -4098,7 +4196,7 @@ var Service = class extends Base {
4098
4196
  const filterErrors = this.validateClientFilter(filter2);
4099
4197
  if (filterErrors.length > 0) return { success: false, kind: "error", code: "bad_request" /* BadRequest */, errors: filterErrors };
4100
4198
  const { populate, overrides } = this.resolveUpsertArgs(args);
4101
- const { skim, includePermissions, populateAccess } = this.resolveUpsertOptions(options);
4199
+ const { skim, includePermissions, includeFieldPermissions, populateAccess } = this.resolveUpsertOptions(options);
4102
4200
  const { filter: overrideFilter, populate: overridePopulate } = overrides ?? {};
4103
4201
  const _filter = await (overrideFilter ?? this.genFilter("update", filter2));
4104
4202
  const query = { filter: _filter };
@@ -4120,7 +4218,7 @@ var Service = class extends Base {
4120
4218
  populate: overridePopulate
4121
4219
  }
4122
4220
  },
4123
- { skim, includePermissions, populateAccess },
4221
+ { skim, includePermissions, includeFieldPermissions, populateAccess },
4124
4222
  decorate
4125
4223
  );
4126
4224
  } else {
@@ -4130,6 +4228,7 @@ var Service = class extends Base {
4130
4228
  {
4131
4229
  skim,
4132
4230
  includePermissions,
4231
+ includeFieldPermissions,
4133
4232
  populateAccess
4134
4233
  },
4135
4234
  decorate
@@ -4454,11 +4553,11 @@ import { pick as pick4 } from "@web-ts-toolkit/utils";
4454
4553
  var PublicService = class extends Service {
4455
4554
  async _list(filter2, args, options) {
4456
4555
  const { select, populate, include, sort, skip, limit, page, pageSize, tasks } = this.resolvePublicListArgs(args);
4457
- const { skim, includePermissions, includeCount, populateAccess, lean } = this.resolvePublicListOptions(options);
4556
+ const { skim, includePermissions, includeFieldPermissions, includeCount, populateAccess, lean } = this.resolvePublicListOptions(options);
4458
4557
  const result = await this.find(
4459
4558
  filter2,
4460
4559
  { select, populate, include, sort, skip, limit, page, pageSize },
4461
- { skim, includePermissions, includeCount, populateAccess, lean },
4560
+ { skim, includePermissions, includeFieldPermissions, includeCount, populateAccess, lean },
4462
4561
  async (doc, context) => {
4463
4562
  doc = toObject(doc);
4464
4563
  return this.decorate(doc, "list", context);
@@ -4480,11 +4579,11 @@ var PublicService = class extends Service {
4480
4579
  }
4481
4580
  async _create(data, args, options) {
4482
4581
  const { select, populate, tasks } = this.resolvePublicCreateArgs(args);
4483
- const { skim, includePermissions, populateAccess } = this.resolvePublicCreateOptions(options);
4582
+ const { skim, includePermissions, includeFieldPermissions, populateAccess } = this.resolvePublicCreateOptions(options);
4484
4583
  const result = await this.create(
4485
4584
  data,
4486
4585
  { populate },
4487
- { skim, includePermissions, populateAccess },
4586
+ { skim, includePermissions, includeFieldPermissions, populateAccess },
4488
4587
  async (doc, context) => {
4489
4588
  let d = toObject(doc);
4490
4589
  d = await this.decorate(d, "create", context);
@@ -4503,7 +4602,7 @@ var PublicService = class extends Service {
4503
4602
  }
4504
4603
  async _read(id, args, options) {
4505
4604
  const { select, populate, include, tasks } = this.resolvePublicReadArgs(args);
4506
- const { skim, includePermissions, tryList, populateAccess, lean } = this.resolvePublicReadOptions(options);
4605
+ const { skim, includePermissions, includeFieldPermissions, tryList, populateAccess, lean } = this.resolvePublicReadOptions(options);
4507
4606
  let access = "read";
4508
4607
  const idFilter = await this.genIDFilter(id);
4509
4608
  let result = await this.findById(
@@ -4514,7 +4613,7 @@ var PublicService = class extends Service {
4514
4613
  include,
4515
4614
  overrides: { idFilter }
4516
4615
  },
4517
- { skim, includePermissions, access, populateAccess, lean }
4616
+ { skim, includePermissions, includeFieldPermissions, access, populateAccess, lean }
4518
4617
  );
4519
4618
  if (!result.success && (result.code === "bad_request" /* BadRequest */ || result.code === "forbidden" /* Forbidden */)) return result;
4520
4619
  if (tryList && (!result.success || !result.data)) {
@@ -4531,7 +4630,7 @@ var PublicService = class extends Service {
4531
4630
  include,
4532
4631
  overrides: { idFilter }
4533
4632
  },
4534
- { skim, includePermissions, access, populateAccess, lean }
4633
+ { skim, includePermissions, includeFieldPermissions, access, populateAccess, lean }
4535
4634
  );
4536
4635
  }
4537
4636
  if (!result.success) {
@@ -4544,7 +4643,7 @@ var PublicService = class extends Service {
4544
4643
  }
4545
4644
  async _readFilter(filter2, args, options) {
4546
4645
  const { select, sort, populate, include, tasks } = this.resolvePublicReadFilterArgs(args);
4547
- const { skim, includePermissions, tryList, populateAccess, lean } = this.resolvePublicReadOptions(options);
4646
+ const { skim, includePermissions, includeFieldPermissions, tryList, populateAccess, lean } = this.resolvePublicReadOptions(options);
4548
4647
  let access = "read";
4549
4648
  let result = await this.findOne(
4550
4649
  filter2,
@@ -4555,7 +4654,7 @@ var PublicService = class extends Service {
4555
4654
  include,
4556
4655
  overrides: {}
4557
4656
  },
4558
- { skim, includePermissions, access, populateAccess, lean }
4657
+ { skim, includePermissions, includeFieldPermissions, access, populateAccess, lean }
4559
4658
  );
4560
4659
  if (!result.success && (result.code === "bad_request" /* BadRequest */ || result.code === "forbidden" /* Forbidden */)) return result;
4561
4660
  if (tryList && (!result.success || !result.data)) {
@@ -4573,7 +4672,7 @@ var PublicService = class extends Service {
4573
4672
  include,
4574
4673
  overrides: {}
4575
4674
  },
4576
- { skim, includePermissions, access, populateAccess, lean }
4675
+ { skim, includePermissions, includeFieldPermissions, access, populateAccess, lean }
4577
4676
  );
4578
4677
  }
4579
4678
  if (!result.success) {
@@ -4585,13 +4684,14 @@ var PublicService = class extends Service {
4585
4684
  return { ...result, data: doc };
4586
4685
  }
4587
4686
  async _update(id, data, args, options) {
4588
- const { select, populate, tasks } = this.resolvePublicUpdateArgs(args);
4589
- const { skim, returningAll, includePermissions, populateAccess } = this.resolvePublicUpdateOptions(options);
4687
+ const { select: requestedSelect, populate, tasks } = this.resolvePublicUpdateArgs(args);
4688
+ const select = this.resolveEffectiveSelect(requestedSelect);
4689
+ const { skim, returningAll, includePermissions, includeFieldPermissions, populateAccess } = this.resolvePublicUpdateOptions(options);
4590
4690
  const result = await this.updateById(
4591
4691
  id,
4592
4692
  data,
4593
4693
  { populate },
4594
- { skim, includePermissions, populateAccess },
4694
+ { skim, includePermissions, includeFieldPermissions, populateAccess },
4595
4695
  async (doc, context) => {
4596
4696
  let d = toObject(doc);
4597
4697
  d = await this.decorate(d, "update", context);
@@ -4631,6 +4731,7 @@ var PublicService = class extends Service {
4631
4731
  return this._create(otherData, args, {
4632
4732
  skim: options?.skim,
4633
4733
  includePermissions: options?.includePermissions,
4734
+ includeFieldPermissions: options?.includeFieldPermissions,
4634
4735
  populateAccess: options?.populateAccess
4635
4736
  });
4636
4737
  }
@@ -4660,9 +4761,11 @@ var PublicService = class extends Service {
4660
4761
  };
4661
4762
  }
4662
4763
  resolvePublicListOptions(options = {}) {
4764
+ const includePermissions = options.includePermissions ?? this.defaults.publicListOptions?.includePermissions ?? false;
4663
4765
  return {
4664
4766
  skim: options.skim ?? this.defaults.publicListOptions?.skim ?? true,
4665
- includePermissions: options.includePermissions ?? this.defaults.publicListOptions?.includePermissions ?? false,
4767
+ includePermissions,
4768
+ includeFieldPermissions: options.includeFieldPermissions ?? this.defaults.publicListOptions?.includeFieldPermissions ?? includePermissions,
4666
4769
  includeCount: options.includeCount ?? this.defaults.publicListOptions?.includeCount ?? false,
4667
4770
  populateAccess: options.populateAccess ?? this.defaults.publicListOptions?.populateAccess ?? "read",
4668
4771
  lean: options.lean ?? this.defaults.publicListOptions?.lean ?? true
@@ -4676,9 +4779,11 @@ var PublicService = class extends Service {
4676
4779
  };
4677
4780
  }
4678
4781
  resolvePublicCreateOptions(options = {}) {
4782
+ const includePermissions = options.includePermissions ?? this.defaults.publicCreateOptions?.includePermissions ?? true;
4679
4783
  return {
4680
4784
  skim: options.skim ?? this.defaults.publicCreateOptions?.skim ?? false,
4681
- includePermissions: options.includePermissions ?? this.defaults.publicCreateOptions?.includePermissions ?? true,
4785
+ includePermissions,
4786
+ includeFieldPermissions: options.includeFieldPermissions ?? this.defaults.publicCreateOptions?.includeFieldPermissions ?? includePermissions,
4682
4787
  populateAccess: options.populateAccess ?? this.defaults.publicCreateOptions?.populateAccess ?? "read"
4683
4788
  };
4684
4789
  }
@@ -4698,9 +4803,11 @@ var PublicService = class extends Service {
4698
4803
  };
4699
4804
  }
4700
4805
  resolvePublicReadOptions(options = {}) {
4806
+ const includePermissions = options.includePermissions ?? this.defaults.publicReadOptions?.includePermissions ?? true;
4701
4807
  return {
4702
4808
  skim: options.skim ?? this.defaults.publicReadOptions?.skim ?? false,
4703
- includePermissions: options.includePermissions ?? this.defaults.publicReadOptions?.includePermissions ?? true,
4809
+ includePermissions,
4810
+ includeFieldPermissions: options.includeFieldPermissions ?? this.defaults.publicReadOptions?.includeFieldPermissions ?? includePermissions,
4704
4811
  tryList: options.tryList ?? this.defaults.publicReadOptions?.tryList ?? true,
4705
4812
  populateAccess: options.populateAccess ?? this.defaults.publicReadOptions?.populateAccess,
4706
4813
  lean: options.lean ?? this.defaults.publicReadOptions?.lean ?? false
@@ -4714,10 +4821,12 @@ var PublicService = class extends Service {
4714
4821
  };
4715
4822
  }
4716
4823
  resolvePublicUpdateOptions(options = {}) {
4824
+ const includePermissions = options.includePermissions ?? this.defaults.publicUpdateOptions?.includePermissions ?? true;
4717
4825
  return {
4718
4826
  skim: options.skim ?? this.defaults.publicUpdateOptions?.skim ?? false,
4719
4827
  returningAll: options.returningAll ?? this.defaults.publicUpdateOptions?.returningAll ?? true,
4720
- includePermissions: options.includePermissions ?? this.defaults.publicUpdateOptions?.includePermissions ?? true,
4828
+ includePermissions,
4829
+ includeFieldPermissions: options.includeFieldPermissions ?? this.defaults.publicUpdateOptions?.includeFieldPermissions ?? includePermissions,
4721
4830
  populateAccess: options.populateAccess ?? this.defaults.publicUpdateOptions?.populateAccess ?? "read"
4722
4831
  };
4723
4832
  }
@@ -6792,23 +6901,32 @@ var listQuerySchema = z3.object({
6792
6901
  page_size: positiveIntegerString.optional(),
6793
6902
  skim: queryBooleanString.optional(),
6794
6903
  include_permissions: queryBooleanString.optional(),
6904
+ include_field_permissions: queryBooleanString.optional(),
6795
6905
  include_count: queryBooleanString.optional(),
6796
- include_extra_headers: queryBooleanString.optional()
6906
+ include_extra_headers: queryBooleanString.optional(),
6907
+ select: stringOrStringArray.optional(),
6908
+ sort: z3.string().optional().describe("Space-separated sort fields; prefix a field with - for descending order.")
6797
6909
  }).passthrough();
6798
6910
  var createQuerySchema = z3.object({
6799
- include_permissions: queryBooleanString.optional()
6911
+ include_permissions: queryBooleanString.optional(),
6912
+ include_field_permissions: queryBooleanString.optional()
6800
6913
  }).passthrough();
6801
6914
  var readQuerySchema = z3.object({
6802
6915
  include_permissions: queryBooleanString.optional(),
6803
- try_list: queryBooleanString.optional()
6916
+ include_field_permissions: queryBooleanString.optional(),
6917
+ try_list: queryBooleanString.optional(),
6918
+ select: stringOrStringArray.optional()
6804
6919
  }).passthrough();
6805
6920
  var updateQuerySchema = z3.object({
6806
6921
  returning_all: queryBooleanString.optional(),
6807
- include_permissions: queryBooleanString.optional()
6922
+ include_permissions: queryBooleanString.optional(),
6923
+ include_field_permissions: queryBooleanString.optional(),
6924
+ select: stringOrStringArray.optional()
6808
6925
  }).passthrough();
6809
6926
  var upsertQuerySchema = z3.object({
6810
6927
  returning_all: queryBooleanString.optional(),
6811
- include_permissions: queryBooleanString.optional()
6928
+ include_permissions: queryBooleanString.optional(),
6929
+ include_field_permissions: queryBooleanString.optional()
6812
6930
  }).passthrough();
6813
6931
  var listBodySchema = z3.object({
6814
6932
  filter: objectOrArraySchema.optional(),
@@ -6824,6 +6942,7 @@ var listBodySchema = z3.object({
6824
6942
  options: z3.object({
6825
6943
  skim: z3.boolean().optional(),
6826
6944
  includePermissions: z3.boolean().optional(),
6945
+ includeFieldPermissions: z3.boolean().optional(),
6827
6946
  includeCount: z3.boolean().optional(),
6828
6947
  includeExtraHeaders: z3.boolean().optional(),
6829
6948
  populateAccess: z3.unknown().optional()
@@ -6842,6 +6961,7 @@ var readFilterBodySchema = z3.object({
6842
6961
  options: z3.object({
6843
6962
  skim: z3.boolean().optional(),
6844
6963
  includePermissions: z3.boolean().optional(),
6964
+ includeFieldPermissions: z3.boolean().optional(),
6845
6965
  tryList: z3.boolean().optional(),
6846
6966
  populateAccess: z3.unknown().optional()
6847
6967
  }).passthrough().optional()
@@ -6854,6 +6974,7 @@ var readByIdBodySchema = z3.object({
6854
6974
  options: z3.object({
6855
6975
  skim: z3.boolean().optional(),
6856
6976
  includePermissions: z3.boolean().optional(),
6977
+ includeFieldPermissions: z3.boolean().optional(),
6857
6978
  tryList: z3.boolean().optional(),
6858
6979
  populateAccess: z3.unknown().optional()
6859
6980
  }).passthrough().optional()
@@ -6865,6 +6986,7 @@ var advancedCreateBodySchema = z3.object({
6865
6986
  tasks: tasksSchema.optional(),
6866
6987
  options: z3.object({
6867
6988
  includePermissions: z3.boolean().optional(),
6989
+ includeFieldPermissions: z3.boolean().optional(),
6868
6990
  populateAccess: z3.unknown().optional()
6869
6991
  }).passthrough().optional()
6870
6992
  }).passthrough();
@@ -6881,6 +7003,7 @@ var advancedUpdateBodySchema = z3.object({
6881
7003
  options: z3.object({
6882
7004
  returningAll: z3.boolean().optional(),
6883
7005
  includePermissions: z3.boolean().optional(),
7006
+ includeFieldPermissions: z3.boolean().optional(),
6884
7007
  populateAccess: z3.unknown().optional()
6885
7008
  }).passthrough().optional()
6886
7009
  }).passthrough();
@@ -6893,6 +7016,7 @@ var advancedUpsertBodySchema = z3.object({
6893
7016
  options: z3.object({
6894
7017
  returningAll: z3.boolean().optional(),
6895
7018
  includePermissions: z3.boolean().optional(),
7019
+ includeFieldPermissions: z3.boolean().optional(),
6896
7020
  populateAccess: z3.unknown().optional()
6897
7021
  }).passthrough().optional()
6898
7022
  }).passthrough();
@@ -6963,6 +7087,7 @@ var rootModelListArgsSchema = z5.object({
6963
7087
  var rootModelListOptionsSchema = z5.object({
6964
7088
  skim: z5.boolean().optional(),
6965
7089
  includePermissions: z5.boolean().optional(),
7090
+ includeFieldPermissions: z5.boolean().optional(),
6966
7091
  includeCount: z5.boolean().optional(),
6967
7092
  populateAccess: z5.unknown().optional(),
6968
7093
  lean: z5.boolean().optional()
@@ -6979,6 +7104,7 @@ var rootModelReadFilterArgsSchema = rootModelReadArgsSchema.extend({
6979
7104
  var rootModelReadOptionsSchema = z5.object({
6980
7105
  skim: z5.boolean().optional(),
6981
7106
  includePermissions: z5.boolean().optional(),
7107
+ includeFieldPermissions: z5.boolean().optional(),
6982
7108
  tryList: z5.boolean().optional(),
6983
7109
  populateAccess: z5.unknown().optional(),
6984
7110
  lean: z5.boolean().optional()
@@ -6991,6 +7117,7 @@ var rootModelCreateArgsSchema = z5.object({
6991
7117
  var rootModelCreateOptionsSchema = z5.object({
6992
7118
  skim: z5.boolean().optional(),
6993
7119
  includePermissions: z5.boolean().optional(),
7120
+ includeFieldPermissions: z5.boolean().optional(),
6994
7121
  populateAccess: z5.unknown().optional()
6995
7122
  }).passthrough();
6996
7123
  var rootModelUpdateArgsSchema = z5.object({
@@ -7002,6 +7129,7 @@ var rootModelUpdateOptionsSchema = z5.object({
7002
7129
  skim: z5.boolean().optional(),
7003
7130
  returningAll: z5.boolean().optional(),
7004
7131
  includePermissions: z5.boolean().optional(),
7132
+ includeFieldPermissions: z5.boolean().optional(),
7005
7133
  populateAccess: z5.unknown().optional()
7006
7134
  }).passthrough();
7007
7135
  var rootModelUpsertArgsSchema = rootModelUpdateArgsSchema;
@@ -7033,7 +7161,8 @@ var rootModelNewArgsSchema = z5.object({
7033
7161
  }).passthrough();
7034
7162
  var rootModelNewOptionsSchema = z5.object({
7035
7163
  skim: z5.boolean().optional(),
7036
- includePermissions: z5.boolean().optional()
7164
+ includePermissions: z5.boolean().optional(),
7165
+ includeFieldPermissions: z5.boolean().optional()
7037
7166
  }).passthrough();
7038
7167
  var rootModelQueryEntrySchema = z5.union([
7039
7168
  z5.object({
@@ -7202,16 +7331,29 @@ function setModelCollectionRoutes(context) {
7202
7331
  };
7203
7332
  router.get("", async (req) => {
7204
7333
  await context.assertAllowed(req, "list");
7205
- const { skip, limit, page, page_size, skim, include_permissions, include_count, include_extra_headers } = parseQuery(requestSchemas.listQuery, req.query);
7334
+ const {
7335
+ skip,
7336
+ limit,
7337
+ page,
7338
+ page_size,
7339
+ skim,
7340
+ include_permissions,
7341
+ include_field_permissions,
7342
+ include_count,
7343
+ include_extra_headers,
7344
+ select,
7345
+ sort
7346
+ } = parseQuery(requestSchemas.listQuery, req.query);
7206
7347
  const svc = context.getPublicService(req);
7207
7348
  const includeCount = parseBooleanString(include_count);
7208
7349
  const includeExtraHeaders = parseBooleanString(include_extra_headers);
7209
7350
  const result = await svc._list(
7210
7351
  {},
7211
- { skip, limit, page, pageSize: page_size },
7352
+ { select: parseSelectParam(select), sort, skip, limit, page, pageSize: page_size },
7212
7353
  {
7213
7354
  skim: parseBooleanString(skim),
7214
7355
  includePermissions: parseBooleanString(include_permissions),
7356
+ includeFieldPermissions: parseBooleanString(include_field_permissions),
7215
7357
  includeCount
7216
7358
  }
7217
7359
  );
@@ -7234,7 +7376,7 @@ function setModelCollectionRoutes(context) {
7234
7376
  );
7235
7377
  const { filter: filter2, select, sort, populate, include, tasks, skip, limit, page, pageSize } = body;
7236
7378
  const advancedOptions = body.options ?? {};
7237
- const { skim, includePermissions, includeCount, includeExtraHeaders, populateAccess } = advancedOptions;
7379
+ const { skim, includePermissions, includeFieldPermissions, includeCount, includeExtraHeaders, populateAccess } = advancedOptions;
7238
7380
  const svc = context.getPublicService(req);
7239
7381
  const listFilter = filter2 ?? {};
7240
7382
  const result = await svc._list(
@@ -7243,6 +7385,7 @@ function setModelCollectionRoutes(context) {
7243
7385
  {
7244
7386
  skim,
7245
7387
  includePermissions,
7388
+ includeFieldPermissions,
7246
7389
  includeCount,
7247
7390
  populateAccess
7248
7391
  }
@@ -7259,14 +7402,21 @@ function setModelCollectionRoutes(context) {
7259
7402
  });
7260
7403
  router.post("", async (req) => {
7261
7404
  await context.assertAllowed(req, "create");
7262
- const { include_permissions } = parseQuery(requestSchemas.createQuery, req.query);
7405
+ const { include_permissions, include_field_permissions } = parseQuery(requestSchemas.createQuery, req.query);
7263
7406
  const data = await parseBodyWithSchema(
7264
7407
  createBodySchema,
7265
7408
  req.body,
7266
7409
  context.getRequestSchema("requestSchemas.create")
7267
7410
  );
7268
7411
  const svc = context.getPublicService(req);
7269
- const result = await svc._create(data, {}, { includePermissions: parseBooleanString(include_permissions) });
7412
+ const result = await svc._create(
7413
+ data,
7414
+ {},
7415
+ {
7416
+ includePermissions: parseBooleanString(include_permissions),
7417
+ includeFieldPermissions: parseBooleanString(include_field_permissions)
7418
+ }
7419
+ );
7270
7420
  handleResultError(result);
7271
7421
  return formatModelCreatedResponse(result);
7272
7422
  });
@@ -7280,7 +7430,7 @@ function setModelCollectionRoutes(context) {
7280
7430
  });
7281
7431
  router.post(`/${options.mutationRouteSegment}`, async (req) => {
7282
7432
  await context.assertAllowed(req, "create");
7283
- const { include_permissions } = parseQuery(requestSchemas.createQuery, req.query);
7433
+ const { include_permissions, include_field_permissions } = parseQuery(requestSchemas.createQuery, req.query);
7284
7434
  const intermediateBody = await parseNestedBodyWithSchema(
7285
7435
  advancedCreateBodySchema,
7286
7436
  req.body,
@@ -7296,13 +7446,14 @@ function setModelCollectionRoutes(context) {
7296
7446
  );
7297
7447
  const { data: finalData, select: finalSelect, populate: finalPopulate, tasks: finalTasks } = finalBody;
7298
7448
  const finalOptions = finalBody.options ?? {};
7299
- const { includePermissions, populateAccess } = finalOptions;
7449
+ const { includePermissions, includeFieldPermissions, populateAccess } = finalOptions;
7300
7450
  const svc = context.getPublicService(req);
7301
7451
  const result = await svc._create(
7302
7452
  finalData,
7303
7453
  { select: finalSelect, populate: finalPopulate, tasks: finalTasks },
7304
7454
  {
7305
7455
  includePermissions: includePermissions ?? parseBooleanString(include_permissions),
7456
+ includeFieldPermissions: includeFieldPermissions ?? parseBooleanString(include_field_permissions),
7306
7457
  populateAccess
7307
7458
  }
7308
7459
  );
@@ -7320,7 +7471,7 @@ function setModelCollectionRoutes(context) {
7320
7471
  router.get("/new", async (req) => {
7321
7472
  await context.assertAllowed(req, "new");
7322
7473
  const svc = context.getPublicService(req);
7323
- const result = await svc._new({}, { includePermissions: false });
7474
+ const result = await svc._new({}, { includePermissions: false, includeFieldPermissions: false });
7324
7475
  handleResultError(result);
7325
7476
  return unwrapServiceData(result);
7326
7477
  });
@@ -7388,13 +7539,17 @@ function setModelDocumentRoutes(context) {
7388
7539
  router.get(`/:${options.idParam}`, async (req) => {
7389
7540
  await context.assertAllowed(req, "read");
7390
7541
  const id = parsePathParam(req.params[options.idParam], options.idParam);
7391
- const { include_permissions, try_list } = parseQuery(requestSchemas.readQuery, req.query);
7542
+ const { include_permissions, include_field_permissions, try_list, select } = parseQuery(
7543
+ requestSchemas.readQuery,
7544
+ req.query
7545
+ );
7392
7546
  const svc = context.getPublicService(req);
7393
7547
  const result = await svc._read(
7394
7548
  id,
7395
- {},
7549
+ { select: parseSelectParam(select) },
7396
7550
  {
7397
7551
  includePermissions: parseBooleanString(include_permissions),
7552
+ includeFieldPermissions: parseBooleanString(include_field_permissions),
7398
7553
  tryList: parseBooleanString(try_list)
7399
7554
  }
7400
7555
  );
@@ -7417,12 +7572,18 @@ function setModelDocumentRoutes(context) {
7417
7572
  );
7418
7573
  const { filter: filter2, select, sort, populate, include, tasks } = body;
7419
7574
  const advancedOptions = body.options ?? {};
7420
- const { skim, includePermissions, tryList, populateAccess } = advancedOptions;
7575
+ const { skim, includePermissions, includeFieldPermissions, tryList, populateAccess } = advancedOptions;
7421
7576
  const svc = context.getPublicService(req);
7422
7577
  const result = await svc._readFilter(
7423
7578
  filter2 ?? {},
7424
7579
  { select, sort, populate, include, tasks },
7425
- { skim, includePermissions, tryList, populateAccess }
7580
+ {
7581
+ skim,
7582
+ includePermissions,
7583
+ includeFieldPermissions,
7584
+ tryList,
7585
+ populateAccess
7586
+ }
7426
7587
  );
7427
7588
  handleResultError(result);
7428
7589
  return unwrapServiceData(result);
@@ -7446,12 +7607,18 @@ function setModelDocumentRoutes(context) {
7446
7607
  );
7447
7608
  const { select, populate, include, tasks } = body;
7448
7609
  const advancedOptions = body.options ?? {};
7449
- const { skim, includePermissions, tryList, populateAccess } = advancedOptions;
7610
+ const { skim, includePermissions, includeFieldPermissions, tryList, populateAccess } = advancedOptions;
7450
7611
  const svc = context.getPublicService(req);
7451
7612
  const result = await svc._read(
7452
7613
  id,
7453
7614
  { select, populate, include, tasks },
7454
- { skim, includePermissions, tryList, populateAccess }
7615
+ {
7616
+ skim,
7617
+ includePermissions,
7618
+ includeFieldPermissions,
7619
+ tryList,
7620
+ populateAccess
7621
+ }
7455
7622
  );
7456
7623
  handleResultError(result);
7457
7624
  return unwrapServiceData(result);
@@ -7468,7 +7635,10 @@ function setModelDocumentRoutes(context) {
7468
7635
  router.patch(`/:${options.idParam}`, async (req) => {
7469
7636
  await context.assertAllowed(req, "update");
7470
7637
  const id = parsePathParam(req.params[options.idParam], options.idParam);
7471
- const { returning_all, include_permissions } = parseQuery(requestSchemas.updateQuery, req.query);
7638
+ const { returning_all, include_permissions, include_field_permissions, select } = parseQuery(
7639
+ requestSchemas.updateQuery,
7640
+ req.query
7641
+ );
7472
7642
  const data = await parseBodyWithSchema(
7473
7643
  updateBodySchema,
7474
7644
  req.body,
@@ -7478,10 +7648,11 @@ function setModelDocumentRoutes(context) {
7478
7648
  const result = await svc._update(
7479
7649
  id,
7480
7650
  data,
7481
- {},
7651
+ { select: parseSelectParam(select) },
7482
7652
  {
7483
7653
  returningAll: parseBooleanString(returning_all),
7484
- includePermissions: parseBooleanString(include_permissions)
7654
+ includePermissions: parseBooleanString(include_permissions),
7655
+ includeFieldPermissions: parseBooleanString(include_field_permissions)
7485
7656
  }
7486
7657
  );
7487
7658
  handleResultError(result);
@@ -7498,7 +7669,10 @@ function setModelDocumentRoutes(context) {
7498
7669
  router.patch(`/${options.mutationRouteSegment}/:${options.idParam}`, async (req) => {
7499
7670
  await context.assertAllowed(req, "update");
7500
7671
  const id = parsePathParam(req.params[options.idParam], options.idParam);
7501
- const { returning_all, include_permissions } = parseQuery(requestSchemas.updateQuery, req.query);
7672
+ const { returning_all, include_permissions, include_field_permissions } = parseQuery(
7673
+ requestSchemas.updateQuery,
7674
+ req.query
7675
+ );
7502
7676
  const intermediateBody = await parseNestedBodyWithSchema(
7503
7677
  advancedUpdateBodySchema,
7504
7678
  req.body,
@@ -7520,7 +7694,7 @@ function setModelDocumentRoutes(context) {
7520
7694
  );
7521
7695
  const { data: finalData, select: finalSelect, populate: finalPopulate, tasks: finalTasks } = finalBody;
7522
7696
  const finalOptions = finalBody.options ?? {};
7523
- const { returningAll, includePermissions, populateAccess } = finalOptions;
7697
+ const { returningAll, includePermissions, includeFieldPermissions, populateAccess } = finalOptions;
7524
7698
  const svc = context.getPublicService(req);
7525
7699
  const result = await svc._update(
7526
7700
  id,
@@ -7529,6 +7703,7 @@ function setModelDocumentRoutes(context) {
7529
7703
  {
7530
7704
  returningAll: returningAll ?? parseBooleanString(returning_all),
7531
7705
  includePermissions: includePermissions ?? parseBooleanString(include_permissions),
7706
+ includeFieldPermissions: includeFieldPermissions ?? parseBooleanString(include_field_permissions),
7532
7707
  populateAccess
7533
7708
  }
7534
7709
  );
@@ -7546,7 +7721,10 @@ function setModelDocumentRoutes(context) {
7546
7721
  router.put(`/`, async (req) => {
7547
7722
  await context.assertAllowed(req, "upsert");
7548
7723
  const svc = context.getPublicService(req);
7549
- const { returning_all, include_permissions } = parseQuery(requestSchemas.upsertQuery, req.query);
7724
+ const { returning_all, include_permissions, include_field_permissions } = parseQuery(
7725
+ requestSchemas.upsertQuery,
7726
+ req.query
7727
+ );
7550
7728
  const body = await parseBodyWithSchema(
7551
7729
  upsertBodySchema,
7552
7730
  req.body,
@@ -7557,7 +7735,8 @@ function setModelDocumentRoutes(context) {
7557
7735
  {},
7558
7736
  {
7559
7737
  returningAll: parseBooleanString(returning_all),
7560
- includePermissions: parseBooleanString(include_permissions)
7738
+ includePermissions: parseBooleanString(include_permissions),
7739
+ includeFieldPermissions: parseBooleanString(include_field_permissions)
7561
7740
  }
7562
7741
  );
7563
7742
  handleResultError(result);
@@ -7574,7 +7753,10 @@ function setModelDocumentRoutes(context) {
7574
7753
  router.put(`/${options.mutationRouteSegment}`, async (req) => {
7575
7754
  await context.assertAllowed(req, "upsert");
7576
7755
  const svc = context.getPublicService(req);
7577
- const { returning_all, include_permissions } = parseQuery(requestSchemas.upsertQuery, req.query);
7756
+ const { returning_all, include_permissions, include_field_permissions } = parseQuery(
7757
+ requestSchemas.upsertQuery,
7758
+ req.query
7759
+ );
7578
7760
  const intermediateBody = await parseNestedBodyWithSchema(
7579
7761
  advancedUpsertBodySchema,
7580
7762
  req.body,
@@ -7596,13 +7778,14 @@ function setModelDocumentRoutes(context) {
7596
7778
  );
7597
7779
  const { data: finalData, select: finalSelect, populate: finalPopulate, tasks: finalTasks } = finalBody;
7598
7780
  const finalOptions = finalBody.options ?? {};
7599
- const { returningAll, includePermissions, populateAccess } = finalOptions;
7781
+ const { returningAll, includePermissions, includeFieldPermissions, populateAccess } = finalOptions;
7600
7782
  const result = await svc._upsert(
7601
7783
  finalData,
7602
7784
  { select: finalSelect, populate: finalPopulate, tasks: finalTasks },
7603
7785
  {
7604
7786
  returningAll: returningAll ?? parseBooleanString(returning_all),
7605
7787
  includePermissions: includePermissions ?? parseBooleanString(include_permissions),
7788
+ includeFieldPermissions: includeFieldPermissions ?? parseBooleanString(include_field_permissions),
7606
7789
  populateAccess
7607
7790
  }
7608
7791
  );