@ghentcdh/crouton-api 0.0.1-alpha.30 → 0.0.1-alpha.32

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/dist/index.cjs CHANGED
@@ -560,6 +560,7 @@ var JsonOperationsSchema = import_zod9.z.object({
560
560
  findOne: import_zod9.z.boolean().default(true),
561
561
  create: import_zod9.z.boolean().default(true),
562
562
  update: import_zod9.z.boolean().default(true),
563
+ patch: import_zod9.z.boolean().default(true),
563
564
  upsert: BoolOrUpsertSchema.default(false),
564
565
  delete: import_zod9.z.boolean().default(true)
565
566
  });
@@ -1666,9 +1667,10 @@ var ReadRepository = class {
1666
1667
  skip: params.offset ?? (params.page - 1) * params.pageSize,
1667
1668
  orderBy: this.safeSort(sanitizeValueLabelSort(params.sort, this.config.valueLabelColumns), params.sortDir)
1668
1669
  };
1669
- if (subResources.length) {
1670
+ const countableSubResources = subResources.filter((s) => s.relationType !== "manyToOne");
1671
+ if (countableSubResources.length) {
1670
1672
  const countClause = {
1671
- select: Object.fromEntries(subResources.map((s) => [
1673
+ select: Object.fromEntries(countableSubResources.map((s) => [
1672
1674
  s.relation,
1673
1675
  true
1674
1676
  ]))
@@ -1688,10 +1690,10 @@ var ReadRepository = class {
1688
1690
  Object.assign(query, projection);
1689
1691
  }
1690
1692
  const rows = await this.prismaModel.findMany(query);
1691
- const mapped = subResources.length ? rows.map((row) => {
1693
+ const mapped = countableSubResources.length ? rows.map((row) => {
1692
1694
  const { _count, ...rest } = row;
1693
1695
  if (!_count) return rest;
1694
- const counts = Object.fromEntries(subResources.map((s) => [
1696
+ const counts = Object.fromEntries(countableSubResources.map((s) => [
1695
1697
  s.column,
1696
1698
  _count[s.relation] ?? 0
1697
1699
  ]));
@@ -2017,6 +2019,21 @@ var WriteRepository = class {
2017
2019
  throw e;
2018
2020
  }
2019
2021
  }
2022
+ async patch(id, data) {
2023
+ const idField = this.config.idField ?? "id";
2024
+ try {
2025
+ const result = await this.prismaModel.update({
2026
+ where: {
2027
+ [idField]: this.toId(id)
2028
+ },
2029
+ data: await this.prepare(this.stripSubResourceKeys(data), "patch", this.toId(id))
2030
+ });
2031
+ return this.postWrite(result, "patch", this.toId(id));
2032
+ } catch (e) {
2033
+ if (e?.code === PRISMA_NOT_FOUND_CODE) throw this.notFound(id);
2034
+ throw e;
2035
+ }
2036
+ }
2020
2037
  async upsert(data) {
2021
2038
  const where = this.upsertWhere(data);
2022
2039
  const existing = await this.prismaModel.findFirst({
@@ -2166,6 +2183,7 @@ function createCrudRepository(prisma, config) {
2166
2183
  findOneChild: reader.findOneChild.bind(reader),
2167
2184
  create: writer.create.bind(writer),
2168
2185
  update: writer.update.bind(writer),
2186
+ patch: writer.patch.bind(writer),
2169
2187
  upsert: writer.upsert.bind(writer),
2170
2188
  upsertMany: writer.upsertMany.bind(writer),
2171
2189
  delete: writer.delete.bind(writer),
@@ -2464,6 +2482,9 @@ var create = /* @__PURE__ */ __name(async (repo, body) => {
2464
2482
  var update = /* @__PURE__ */ __name(async (repo, id, body) => {
2465
2483
  return repo.update(id, body);
2466
2484
  }, "update");
2485
+ var patch = /* @__PURE__ */ __name(async (repo, id, body) => {
2486
+ return repo.patch(id, body);
2487
+ }, "patch");
2467
2488
  var upsert = /* @__PURE__ */ __name(async (repo, body) => {
2468
2489
  return repo.upsert(body);
2469
2490
  }, "upsert");
@@ -2552,11 +2573,11 @@ var registerUpdate = /* @__PURE__ */ __name((ctx) => {
2552
2573
  return update(this.repo, id, body);
2553
2574
  });
2554
2575
  const d = desc(cls, "update");
2555
- (0, import_common8.Patch)(":id")(cls.prototype, "update", d);
2576
+ (0, import_common8.Put)(":id")(cls.prototype, "update", d);
2556
2577
  (0, import_common8.Param)("id")(cls.prototype, "update", 0);
2557
2578
  bodyDecorator(updateSchema)(cls.prototype, "update", 1);
2558
2579
  (0, import_swagger3.ApiOperation)({
2559
- summary: `Update a ${name}`
2580
+ summary: `Replace a ${name}`
2560
2581
  })(cls.prototype, "update", d);
2561
2582
  (0, import_swagger3.ApiParam)(idParamMeta)(cls.prototype, "update", d);
2562
2583
  if (updateSchema) (0, import_swagger3.ApiBody)({
@@ -2564,12 +2585,38 @@ var registerUpdate = /* @__PURE__ */ __name((ctx) => {
2564
2585
  })(cls.prototype, "update", d);
2565
2586
  (0, import_swagger3.ApiResponse)({
2566
2587
  status: 200,
2567
- description: `${name} updated`
2588
+ description: `${name} replaced`
2568
2589
  })(cls.prototype, "update", d);
2569
2590
  (0, import_swagger3.ApiNotFoundResponse)({
2570
2591
  description: "Not found"
2571
2592
  })(cls.prototype, "update", d);
2572
2593
  }, "registerUpdate");
2594
+ var registerPatch = /* @__PURE__ */ __name((ctx) => {
2595
+ if (!isOperationEnabled(ctx.definition, "patch")) return;
2596
+ const { cls, config, patchSchema, idParamMeta, bodyDecorator } = ctx;
2597
+ const { name } = config;
2598
+ def(cls, "patch", function(id, body) {
2599
+ return patch(this.repo, id, body);
2600
+ });
2601
+ const d = desc(cls, "patch");
2602
+ (0, import_common8.Patch)(":id")(cls.prototype, "patch", d);
2603
+ (0, import_common8.Param)("id")(cls.prototype, "patch", 0);
2604
+ bodyDecorator(patchSchema)(cls.prototype, "patch", 1);
2605
+ (0, import_swagger3.ApiOperation)({
2606
+ summary: `Update a ${name}`
2607
+ })(cls.prototype, "patch", d);
2608
+ (0, import_swagger3.ApiParam)(idParamMeta)(cls.prototype, "patch", d);
2609
+ if (patchSchema) (0, import_swagger3.ApiBody)({
2610
+ schema: toJsonSchema(patchSchema)
2611
+ })(cls.prototype, "patch", d);
2612
+ (0, import_swagger3.ApiResponse)({
2613
+ status: 200,
2614
+ description: `${name} updated`
2615
+ })(cls.prototype, "patch", d);
2616
+ (0, import_swagger3.ApiNotFoundResponse)({
2617
+ description: "Not found"
2618
+ })(cls.prototype, "patch", d);
2619
+ }, "registerPatch");
2573
2620
  var registerUpsert = /* @__PURE__ */ __name((ctx) => {
2574
2621
  if (!isOperationEnabled(ctx.definition, "upsert")) return;
2575
2622
  const { cls, config, upsertSchema, bodyDecorator } = ctx;
@@ -2646,6 +2693,12 @@ var buildSubResourceOperations = /* @__PURE__ */ __name((ops, baseUri, idField =
2646
2693
  },
2647
2694
  ...ops.update && {
2648
2695
  update: {
2696
+ uri: `${baseUri}/${idPlaceholder}`,
2697
+ method: "put"
2698
+ }
2699
+ },
2700
+ ...ops.patch && {
2701
+ patch: {
2649
2702
  uri: `${baseUri}/${idPlaceholder}`,
2650
2703
  method: "patch"
2651
2704
  }
@@ -2663,13 +2716,15 @@ var RESOURCE_OPS = [
2663
2716
  "findOne",
2664
2717
  "create",
2665
2718
  "update",
2719
+ "patch",
2666
2720
  "delete"
2667
2721
  ];
2668
2722
  var OP_METHOD = {
2669
2723
  findAll: "get",
2670
2724
  findOne: "get",
2671
2725
  create: "post",
2672
- update: "patch",
2726
+ update: "put",
2727
+ patch: "patch",
2673
2728
  delete: "delete"
2674
2729
  };
2675
2730
  var OP_SUFFIX = {
@@ -2677,6 +2732,7 @@ var OP_SUFFIX = {
2677
2732
  findOne: "/{id}",
2678
2733
  create: "",
2679
2734
  update: "/{id}",
2735
+ patch: "/{id}",
2680
2736
  delete: "/{id}"
2681
2737
  };
2682
2738
  var buildResourceOperations = /* @__PURE__ */ __name((definition, baseUri) => Object.fromEntries(RESOURCE_OPS.filter((op) => isOperationEnabled(definition, op)).map((op) => [
@@ -2693,12 +2749,14 @@ var buildDefinitionPayload = /* @__PURE__ */ __name((config) => {
2693
2749
  const oneSchema = schemaFor(definition, "findOne") ?? listSchema;
2694
2750
  const createSchema = schemaFor(definition, "create");
2695
2751
  const updateSchema = schemaFor(definition, "update");
2752
+ const patchSchema = schemaFor(definition, "patch");
2696
2753
  const upsertSchema = schemaFor(definition, "upsert") ?? createSchema;
2697
2754
  const operations = [
2698
2755
  "findAll",
2699
2756
  "findOne",
2700
2757
  "create",
2701
2758
  "update",
2759
+ "patch",
2702
2760
  "upsert",
2703
2761
  "delete"
2704
2762
  ].filter((op) => isOperationEnabled(definition, op));
@@ -2709,6 +2767,7 @@ var buildDefinitionPayload = /* @__PURE__ */ __name((config) => {
2709
2767
  tag,
2710
2768
  operations,
2711
2769
  upsertOn: upsertOnFor(definition),
2770
+ display: config.display,
2712
2771
  schemas: {
2713
2772
  ...listSchema && {
2714
2773
  findAll: toJsonSchema(listSchema)
@@ -2722,6 +2781,9 @@ var buildDefinitionPayload = /* @__PURE__ */ __name((config) => {
2722
2781
  ...updateSchema && {
2723
2782
  update: toJsonSchema(updateSchema)
2724
2783
  },
2784
+ ...patchSchema && {
2785
+ patch: toJsonSchema(patchSchema)
2786
+ },
2725
2787
  ...isOperationEnabled(definition, "upsert") && upsertSchema ? {
2726
2788
  upsert: toJsonSchema(upsertSchema)
2727
2789
  } : {}
@@ -3075,6 +3137,27 @@ var registerSubResourceUpdate = /* @__PURE__ */ __name((ctx, sub) => {
3075
3137
  return updateChild(this.repo, sub, childId, body);
3076
3138
  });
3077
3139
  const d = desc(cls, methodName);
3140
+ (0, import_common10.Put)(`:id/${sub.childRoute}/:childId`)(cls.prototype, methodName, d);
3141
+ (0, import_common10.Param)("id")(cls.prototype, methodName, 0);
3142
+ (0, import_common10.Param)("childId")(cls.prototype, methodName, 1);
3143
+ (0, import_common10.Body)()(cls.prototype, methodName, 2);
3144
+ (0, import_swagger5.ApiOperation)({
3145
+ summary: `Replace a ${sub.childRoute} record`
3146
+ })(cls.prototype, methodName, d);
3147
+ (0, import_swagger5.ApiParam)(ctx.idParamMeta)(cls.prototype, methodName, d);
3148
+ (0, import_swagger5.ApiResponse)({
3149
+ status: 200,
3150
+ description: `${sub.childRoute} replaced`
3151
+ })(cls.prototype, methodName, d);
3152
+ }, "registerSubResourceUpdate");
3153
+ var registerSubResourcePatch = /* @__PURE__ */ __name((ctx, sub) => {
3154
+ if (!sub.operations?.patch) return;
3155
+ const { cls } = ctx;
3156
+ const methodName = `patchChild_${sub.childRoute}`;
3157
+ def(cls, methodName, async function(_id, childId, body) {
3158
+ return updateChild(this.repo, sub, childId, body);
3159
+ });
3160
+ const d = desc(cls, methodName);
3078
3161
  (0, import_common10.Patch)(`:id/${sub.childRoute}/:childId`)(cls.prototype, methodName, d);
3079
3162
  (0, import_common10.Param)("id")(cls.prototype, methodName, 0);
3080
3163
  (0, import_common10.Param)("childId")(cls.prototype, methodName, 1);
@@ -3087,7 +3170,7 @@ var registerSubResourceUpdate = /* @__PURE__ */ __name((ctx, sub) => {
3087
3170
  status: 200,
3088
3171
  description: `${sub.childRoute} updated`
3089
3172
  })(cls.prototype, methodName, d);
3090
- }, "registerSubResourceUpdate");
3173
+ }, "registerSubResourcePatch");
3091
3174
  var registerSubResourceDelete = /* @__PURE__ */ __name((ctx, sub) => {
3092
3175
  if (!sub.operations?.delete) return;
3093
3176
  const { cls } = ctx;
@@ -3115,6 +3198,7 @@ var registerSubResourceRoutes = /* @__PURE__ */ __name((ctx) => {
3115
3198
  registerSubResourceCreate(ctx, sub);
3116
3199
  registerSubResourceFindOne(ctx, sub);
3117
3200
  registerSubResourceUpdate(ctx, sub);
3201
+ registerSubResourcePatch(ctx, sub);
3118
3202
  registerSubResourceDelete(ctx, sub);
3119
3203
  }
3120
3204
  }, "registerSubResourceRoutes");
@@ -3127,6 +3211,8 @@ function createCrudController(config, baseUrl) {
3127
3211
  const oneSchema = schemaFor(definition, "findOne") ?? listSchema;
3128
3212
  const createSchema = schemaFor(definition, "create");
3129
3213
  const updateSchema = schemaFor(definition, "update");
3214
+ const explicitPatchSchema = schemaFor(definition, "patch");
3215
+ const patchSchema = explicitPatchSchema ?? (updateSchema && isZodSchema(updateSchema) ? updateSchema.partial() : void 0) ?? updateSchema;
3130
3216
  const upsertSchema = schemaFor(definition, "upsert") ?? createSchema;
3131
3217
  if (isOperationEnabled(definition, "upsert") && !upsertOnFor(definition)) {
3132
3218
  throw new Error(`Resource "${name}" declares 'upsert' but no upsertOn`);
@@ -3156,6 +3242,7 @@ function createCrudController(config, baseUrl) {
3156
3242
  oneSchema,
3157
3243
  createSchema,
3158
3244
  updateSchema,
3245
+ patchSchema,
3159
3246
  upsertSchema,
3160
3247
  idParamMeta: {
3161
3248
  name: "id",
@@ -3174,6 +3261,7 @@ function createCrudController(config, baseUrl) {
3174
3261
  registerFindOne(ctx);
3175
3262
  registerCreate(ctx);
3176
3263
  registerUpdate(ctx);
3264
+ registerPatch(ctx);
3177
3265
  registerUpsert(ctx);
3178
3266
  registerDelete(ctx);
3179
3267
  (0, import_common11.Controller)(route)(CrudControllerBase);
@@ -4130,6 +4218,8 @@ var buildSubResources = /* @__PURE__ */ __name((columns, parentRoute, parentMode
4130
4218
  findOne: childOps.findOne !== false,
4131
4219
  create: childOps.create !== false,
4132
4220
  update: childOps.update !== false,
4221
+ patch: childOps.patch !== false,
4222
+ upsert: childOps.upsert ?? false,
4133
4223
  delete: childOps.delete !== false
4134
4224
  },
4135
4225
  ...childJson?.actions?.length && {
@@ -4149,7 +4239,8 @@ var buildSubResources = /* @__PURE__ */ __name((columns, parentRoute, parentMode
4149
4239
  },
4150
4240
  ...buildValueLabelColumns(childColumns).length && {
4151
4241
  valueLabelColumns: buildValueLabelColumns(childColumns)
4152
- }
4242
+ },
4243
+ relationType: c.fieldInput?.relationType ?? deriveRelationTypeFromColumns(c, columns)
4153
4244
  };
4154
4245
  });
4155
4246
  }, "buildSubResources");
@@ -4268,6 +4359,7 @@ var import_zod23 = require("zod");
4268
4359
  var WriteOpSchema = import_zod23.z.enum([
4269
4360
  "create",
4270
4361
  "update",
4362
+ "patch",
4271
4363
  "upsert",
4272
4364
  "delete"
4273
4365
  ]);