@appweaver/data 0.0.0-stage → 2.0.1

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 (157) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +61 -2
  3. package/config.d.ts +6 -0
  4. package/config.js +22 -0
  5. package/database/create-client.d.ts +11 -0
  6. package/database/create-client.js +145 -0
  7. package/database/database-config.d.ts +14 -0
  8. package/database/database-config.js +40 -0
  9. package/database/database-error.d.ts +49 -0
  10. package/database/database-error.js +216 -0
  11. package/database/index.d.ts +3 -0
  12. package/database/index.js +19 -0
  13. package/database/prisma-database.d.ts +33 -0
  14. package/database/prisma-database.js +178 -0
  15. package/database/run-transaction.d.ts +21 -0
  16. package/database/run-transaction.js +15 -0
  17. package/export/export-config.d.ts +7 -0
  18. package/export/export-config.js +17 -0
  19. package/export/export-service.d.ts +22 -0
  20. package/export/export-service.js +188 -0
  21. package/export/index.d.ts +1 -0
  22. package/export/index.js +17 -0
  23. package/factory/create-model.d.ts +11 -0
  24. package/factory/create-model.js +479 -0
  25. package/factory/create-policy.d.ts +12 -0
  26. package/factory/create-policy.js +20 -0
  27. package/factory/create-service.d.ts +14 -0
  28. package/factory/create-service.js +116 -0
  29. package/index.d.ts +22 -0
  30. package/index.js +38 -0
  31. package/internal.d.ts +2 -0
  32. package/internal.js +6 -0
  33. package/module.d.ts +3 -0
  34. package/module.js +81 -0
  35. package/package.json +67 -3
  36. package/prisma/client/browser.d.ts +39 -0
  37. package/prisma/client/browser.js +56 -0
  38. package/prisma/client/client.d.ts +58 -0
  39. package/prisma/client/client.js +70 -0
  40. package/prisma/client/commonInputTypes.d.ts +345 -0
  41. package/prisma/client/commonInputTypes.js +11 -0
  42. package/prisma/client/enums.d.ts +1 -0
  43. package/prisma/client/enums.js +11 -0
  44. package/prisma/client/internal/class.d.ts +198 -0
  45. package/prisma/client/internal/class.js +85 -0
  46. package/prisma/client/internal/prismaNamespace.d.ts +1125 -0
  47. package/prisma/client/internal/prismaNamespace.js +204 -0
  48. package/prisma/client/internal/prismaNamespaceBrowser.d.ts +137 -0
  49. package/prisma/client/internal/prismaNamespaceBrowser.js +175 -0
  50. package/prisma/client/models/ApiKey.d.ts +1167 -0
  51. package/prisma/client/models/ApiKey.js +2 -0
  52. package/prisma/client/models/ConnectedAccount.d.ts +1094 -0
  53. package/prisma/client/models/ConnectedAccount.js +2 -0
  54. package/prisma/client/models/File.d.ts +1291 -0
  55. package/prisma/client/models/File.js +2 -0
  56. package/prisma/client/models/OneTimeToken.d.ts +1055 -0
  57. package/prisma/client/models/OneTimeToken.js +2 -0
  58. package/prisma/client/models/Permission.d.ts +1209 -0
  59. package/prisma/client/models/Permission.js +2 -0
  60. package/prisma/client/models/Role.d.ts +1209 -0
  61. package/prisma/client/models/Role.js +2 -0
  62. package/prisma/client/models/Seeder.d.ts +1023 -0
  63. package/prisma/client/models/Seeder.js +2 -0
  64. package/prisma/client/models.d.ts +8 -0
  65. package/prisma/client/models.js +2 -0
  66. package/resource/load-data-resources.d.ts +13 -0
  67. package/resource/load-data-resources.js +37 -0
  68. package/resource/model-schema.d.ts +34 -0
  69. package/resource/model-schema.js +54 -0
  70. package/resource/resource-config.d.ts +16 -0
  71. package/resource/resource-config.js +62 -0
  72. package/resource/resource-loader.d.ts +25 -0
  73. package/resource/resource-loader.js +138 -0
  74. package/resource/resource-service.d.ts +462 -0
  75. package/resource/resource-service.js +1042 -0
  76. package/resource/schemas/index.d.ts +3 -0
  77. package/resource/schemas/index.js +19 -0
  78. package/resource/schemas/resource-aggregate-schema.d.ts +53 -0
  79. package/resource/schemas/resource-aggregate-schema.js +130 -0
  80. package/resource/schemas/resource-filter-schema.d.ts +39 -0
  81. package/resource/schemas/resource-filter-schema.js +153 -0
  82. package/resource/schemas/resource-sort-schema.d.ts +38 -0
  83. package/resource/schemas/resource-sort-schema.js +113 -0
  84. package/resource/utils/aggregate-util.d.ts +113 -0
  85. package/resource/utils/aggregate-util.js +322 -0
  86. package/resource/utils/cursor-util.d.ts +60 -0
  87. package/resource/utils/cursor-util.js +116 -0
  88. package/resource/utils/date-util.d.ts +22 -0
  89. package/resource/utils/date-util.js +112 -0
  90. package/resource/utils/delete-util.d.ts +131 -0
  91. package/resource/utils/delete-util.js +385 -0
  92. package/resource/utils/filter-util.d.ts +24 -0
  93. package/resource/utils/filter-util.js +289 -0
  94. package/resource/utils/prune-util.d.ts +11 -0
  95. package/resource/utils/prune-util.js +56 -0
  96. package/resource/utils/relation-util.d.ts +75 -0
  97. package/resource/utils/relation-util.js +400 -0
  98. package/resource/utils/sort-util.d.ts +31 -0
  99. package/resource/utils/sort-util.js +235 -0
  100. package/resource/utils/text-search-util.d.ts +14 -0
  101. package/resource/utils/text-search-util.js +39 -0
  102. package/resources.d.ts +10 -0
  103. package/resources.js +26 -0
  104. package/security/auth-config.d.ts +23 -0
  105. package/security/auth-config.js +43 -0
  106. package/security/create-auth-resources.d.ts +28 -0
  107. package/security/create-auth-resources.js +163 -0
  108. package/security/helper.d.ts +109 -0
  109. package/security/helper.js +298 -0
  110. package/security/resources/api-key/model.d.ts +2 -0
  111. package/security/resources/api-key/model.js +67 -0
  112. package/security/resources/api-key/policy.d.ts +2 -0
  113. package/security/resources/api-key/policy.js +27 -0
  114. package/security/resources/api-key/service.d.ts +3 -0
  115. package/security/resources/api-key/service.js +34 -0
  116. package/security/resources/connected-account/model.d.ts +2 -0
  117. package/security/resources/connected-account/model.js +57 -0
  118. package/security/resources/connected-account/service.d.ts +2 -0
  119. package/security/resources/connected-account/service.js +7 -0
  120. package/security/resources/one-time-token/model.d.ts +2 -0
  121. package/security/resources/one-time-token/model.js +36 -0
  122. package/security/resources/permission/model.d.ts +2 -0
  123. package/security/resources/permission/model.js +16 -0
  124. package/security/resources/role/model.d.ts +2 -0
  125. package/security/resources/role/model.js +22 -0
  126. package/security/store/database-security-store.d.ts +5 -0
  127. package/security/store/database-security-store.js +54 -0
  128. package/seeder/create-seeder.d.ts +29 -0
  129. package/seeder/create-seeder.js +28 -0
  130. package/seeder/index.d.ts +2 -0
  131. package/seeder/index.js +18 -0
  132. package/seeder/resources/seeder/model.d.ts +2 -0
  133. package/seeder/resources/seeder/model.js +38 -0
  134. package/seeder/seeder.d.ts +29 -0
  135. package/seeder/seeder.js +197 -0
  136. package/storage/file-service.d.ts +133 -0
  137. package/storage/file-service.js +586 -0
  138. package/storage/image-config.d.ts +3 -0
  139. package/storage/image-config.js +11 -0
  140. package/storage/resources/file/model.d.ts +2 -0
  141. package/storage/resources/file/model.js +80 -0
  142. package/types/auth.d.ts +23 -0
  143. package/types/auth.js +2 -0
  144. package/types/generated.d.ts +366 -0
  145. package/types/generated.js +3 -0
  146. package/types/storage.d.ts +35 -0
  147. package/types/storage.js +2 -0
  148. package/utils/export-util.d.ts +8 -0
  149. package/utils/export-util.js +26 -0
  150. package/utils/file-util.d.ts +106 -0
  151. package/utils/file-util.js +254 -0
  152. package/utils/model-util.d.ts +36 -0
  153. package/utils/model-util.js +154 -0
  154. package/utils/policy-util.d.ts +18 -0
  155. package/utils/policy-util.js +28 -0
  156. package/utils/virtual-util.d.ts +11 -0
  157. package/utils/virtual-util.js +53 -0
@@ -0,0 +1,462 @@
1
+ import { ActionType, AggregateOptions, AggregateResponse, AggregateSelect, AggregateSelected, BulkItem, IResourceService, QueryFilter, QueryOptions, QueryResponse, QuerySort, Resource, ResourceId, ResourceClient, ResourceData } from '@appweaver/common';
2
+ export declare abstract class ResourceService<ReadOne = Resource, ReadMany = Resource, Create = ResourceData<Resource>, Update = Partial<ResourceData<Resource>>, Query = QueryFilter<ReadOne>, Replace = Create> implements IResourceService<ReadOne, ReadMany, Create, Update, Query, Replace> {
3
+ readonly modelName: string;
4
+ /**
5
+ * Creates the service for the given resource model and resolves its database
6
+ * client from the Prisma client instance.
7
+ *
8
+ * @param {string} modelName The resource model name this service operates on,
9
+ * as defined by its model file (i.e. `User`, `Post`).
10
+ * @throws An error if no database client exists for the provided model name.
11
+ */
12
+ constructor(modelName: string);
13
+ /**
14
+ * The underlying Prisma model delegate for this resource, useful for
15
+ * executing custom database operations that the service methods do not cover.
16
+ *
17
+ * @return {ResourceClient} The resource client of the model this service was
18
+ * created for, bound to the current transaction (see `runTransaction`).
19
+ */
20
+ get client(): ResourceClient;
21
+ /**
22
+ * Finds a single resource by its id, applying the read restrictions and the
23
+ * access check of this service, and including all relation and file fields
24
+ * configured for output on the find action. A resource event is emitted after
25
+ * a successful lookup.
26
+ *
27
+ * @param {ResourceId} id The id of the resource to find.
28
+ * @return {Promise<Object>} The found resource with its virtual fields and
29
+ * relation counts projected.
30
+ * @throws {@link ResourceError} `RESOURCE_NOT_FOUND` if the resource does not
31
+ * exist or is filtered out by the read restrictions, `RESOURCE_FORBIDDEN` if
32
+ * the access check denies it, and a {@link DatabaseError} on a database error.
33
+ */
34
+ find(id: ResourceId): Promise<ReadOne>;
35
+ /**
36
+ * Queries a page of resources matching the provided filter. The filter is
37
+ * mapped to a database query, combined with the optional `searchText` full
38
+ * text search query and the read restrictions of this service, and executed
39
+ * together with the total count in a single transaction. A resource event is
40
+ * emitted after a successful query.
41
+ *
42
+ * @param {QueryOptions} [options] The query options:
43
+ * - `filter` The query filter object, supporting the logical (`_and`, `_or`,
44
+ * `_not`, `_nor`), comparison (`_eq`, `_ne`, `_gt`, `_gte`, `_lt`, `_lte`,
45
+ * `_in`, `_nin`, `_between`, `_like`, `_ilike`, `_starts`, `_ends`,
46
+ * `_contains`, `_exists`), list (`_has`, `_hasSome`, `_hasEvery`,
47
+ * `_isEmpty`), and relation (`_some`, `_every`, `_none`) operators, as well
48
+ * as plain field values. Its `searchText` property, if present, is passed to
49
+ * {@link ResourceService.textSearchQuery} instead of being matched as a
50
+ * field.
51
+ * - `page` The one-based page number of results to return, ignored when a
52
+ * cursor is given (default: `1`).
53
+ * - `size` The maximum number of results per page (default: `50`).
54
+ * - `sort` The fields to sort by, either as a comma-separated list where a
55
+ * field prefixed with `-` is sorted in descending order (i.e.
56
+ * `-createdAt,id`), or as an object of field directions (i.e.
57
+ * `{ createdAt: 'desc', id: 'asc' }`). Both forms support the fields of the
58
+ * included to-one relations, given with a dot notation (`author.createdAt`)
59
+ * or as a nested object (`{ author: { createdAt: 'desc' } }`) (default:
60
+ * `-createdAt`).
61
+ * - `cursor` The cursor of the page to return, as issued in the `nextCursor`
62
+ * or `prevCursor` of an earlier response, which also carries the direction
63
+ * the page runs in. Takes precedence over `page`.
64
+ * - `totalCount` Whether to count all matching resources, which costs a scan
65
+ * of every one of them (default: `true`).
66
+ * @return {Promise<QueryResponse<Object>>} The paged query response containing
67
+ * the returned resources, the count of the returned items, the cursors of the
68
+ * adjacent pages, and the total count unless it was opted out of.
69
+ * @throws {@link ResourceError} `RESOURCE_INVALID_SORT` if the sort input names
70
+ * a field that cannot be sorted by, `RESOURCE_INVALID_CURSOR` if the cursor
71
+ * was issued for another filter or sort order, and a {@link DatabaseError} on
72
+ * a database error.
73
+ */
74
+ query(options?: QueryOptions<ReadMany, Query>): Promise<QueryResponse<ReadMany>>;
75
+ /**
76
+ * Finds the first resource matching the provided filter, applying the read
77
+ * restrictions of the query action and the access check of the find action,
78
+ * and including the relation and file fields configured for output on the
79
+ * find action. A resource event of the find action is emitted when a resource
80
+ * matches.
81
+ *
82
+ * @param {Object} [filter] The query filter object, mapped the same way as in
83
+ * {@link ResourceService.query}.
84
+ * @param {QuerySort} [sort] The fields to sort the matching resources by, of
85
+ * which the first one is returned, in the same form as in
86
+ * {@link ResourceService.query} (default: `-createdAt`).
87
+ * @return {Promise<Object|null>} The first matching resource with its virtual
88
+ * fields and relation counts projected, or null when none matches.
89
+ * @throws {@link ResourceError} `RESOURCE_FORBIDDEN` if the access check denies
90
+ * the matching resource, `RESOURCE_INVALID_SORT` if the sort input names a
91
+ * field that cannot be sorted by, and a {@link DatabaseError} on a database
92
+ * error.
93
+ */
94
+ single(filter?: Query, sort?: QuerySort<ReadOne>): Promise<ReadOne | null>;
95
+ /**
96
+ * Counts the resources matching the provided filter, applying the read
97
+ * restrictions of the query action.
98
+ *
99
+ * @param {Object} [filter] The query filter object, mapped the same way as in
100
+ * {@link ResourceService.query}.
101
+ * @return {Promise<number>} The number of matching resources.
102
+ * @throws {@link DatabaseError} On a database error.
103
+ */
104
+ count(filter?: Query): Promise<number>;
105
+ /**
106
+ * Checks whether any resource matches the provided filter, applying the read
107
+ * restrictions of the query action.
108
+ *
109
+ * @param {Object} [filter] The query filter object, mapped the same way as in
110
+ * {@link ResourceService.query}.
111
+ * @return {Promise<boolean>} True if at least one resource matches, otherwise
112
+ * false.
113
+ * @throws {@link DatabaseError} On a database error.
114
+ */
115
+ exists(filter?: Query): Promise<boolean>;
116
+ /**
117
+ * Aggregates resources matching the provided filter over a date range, both
118
+ * as a single overall result and as a series of results for the equally sized
119
+ * periods the range is split into. All aggregations are executed in a single
120
+ * transaction.
121
+ *
122
+ * @param {AggregateOptions} options The aggregation options:
123
+ * - `select` The aggregation operations to perform per field (i.e.
124
+ * `{ views: { count: true, sum: true } }`). Only the numeric fields of the
125
+ * model accept every operator, while its date fields accept `count`, `min`,
126
+ * `max`, `first` and `last`. The `first` and `last` operators take the value
127
+ * the earliest and the latest record of a period holds, which costs one
128
+ * additional query per period and boundary, skipped for the periods holding
129
+ * no record.
130
+ * - `filter` The query filter object, mapped the same way as in
131
+ * {@link ResourceService.query}.
132
+ * - `dateField` The date field the range is applied on (default:
133
+ * `createdAt`).
134
+ * - `from` The ISO date string of the range start. Defaults to seven days
135
+ * before the range end.
136
+ * - `to` The ISO date string of the range end. Defaults to the current date
137
+ * and time.
138
+ * - `step` The size of a single period in units of the automatically selected
139
+ * time unit. If not provided, one unit is used and the unit is derived from
140
+ * the range length (seconds up to a minute, minutes up to an hour, hours up
141
+ * to a day, days up to a month, months up to a year, and years beyond that).
142
+ * - `safeIncrement` Whether the period increments use the derived time unit
143
+ * and stay consistent across daylight saving time changes. When false, the
144
+ * step is interpreted in seconds (default: `true`).
145
+ * @return {Promise<AggregateResponse<Object>>} The aggregation response with
146
+ * the overall total and one result per period, each labeled with the median
147
+ * date of its period. It is typed by the fields the selection named, not by
148
+ * the whole model, whenever the selection is passed as an object literal or
149
+ * annotated with `satisfies`.
150
+ * @throws {@link ResourceError} `RESOURCE_INVALID_AGGREGATE` if the selection
151
+ * is empty or names a field or operator that cannot be aggregated, and a
152
+ * {@link DatabaseError} on a database error.
153
+ */
154
+ aggregate<S extends AggregateSelect<ReadOne>>(options: AggregateOptions<ReadOne, S, Query>): Promise<AggregateResponse<AggregateSelected<ReadOne, S>>>;
155
+ /**
156
+ * Creates a new resource. The provided data is merged with the write
157
+ * restrictions, checked for access, sanitized against the model configuration
158
+ * and mapped to the relation write actions (connect, create, or
159
+ * connect-or-create) before the record is created. The `createdBy` audit
160
+ * relation is connected to the currently authenticated user when configured.
161
+ * The resource cache is invalidated and a resource event is emitted after a
162
+ * successful create.
163
+ *
164
+ * @param {Object} data The data of the resource to create, including any inline
165
+ * relation and file payloads.
166
+ * @return {Promise<Object>} The created resource with its virtual fields and
167
+ * relation counts projected.
168
+ * @throws {@link ResourceError} `RESOURCE_FORBIDDEN` if the access check denies
169
+ * the action, `RESOURCE_INVALID_RELATION` if an inline relation payload is
170
+ * missing required fields or the relation does not accept new records, and a
171
+ * {@link DatabaseError} on a database error, i.e. `DATABASE_UNIQUE_VIOLATION`.
172
+ */
173
+ create(data: Create): Promise<ReadOne>;
174
+ /**
175
+ * Updates an existing resource by its id. The current record is loaded with
176
+ * the read restrictions applied and checked for access, then updated with the
177
+ * data merged with the write restrictions inside a single transaction.
178
+ * Relations missing from the new value are disconnected, or deleted when
179
+ * `orphanRemoval` is configured for them, the same way a delete does. The resource cache is invalidated and a
180
+ * resource event carrying both the previous and the current state is emitted
181
+ * after a successful update.
182
+ *
183
+ * @param {ResourceId} id The id of the resource to update.
184
+ * @param {Object} data The partial data to update the resource with, including
185
+ * any inline relation and file payloads.
186
+ * @return {Promise<Object>} The updated resource with its virtual fields and
187
+ * relation counts projected.
188
+ * @throws {@link ResourceError} `RESOURCE_NOT_FOUND` if the resource does not
189
+ * exist or is filtered out by the read restrictions, `RESOURCE_FORBIDDEN` if
190
+ * the access check denies the action, `RESOURCE_INVALID_RELATION` if an
191
+ * inline relation payload is missing required fields or the relation does not
192
+ * accept new records, `RESOURCE_DELETE_RESTRICTED` if a live record
193
+ * references a soft deleted orphan through a restricting relation, and a
194
+ * {@link DatabaseError} on a database error, i.e. `DATABASE_UNIQUE_VIOLATION`.
195
+ */
196
+ update(id: ResourceId, data: Update): Promise<ReadOne>;
197
+ /**
198
+ * Replaces an existing resource by its id as a whole. The updatable scalar
199
+ * fields missing from the data are reset to their configured default value,
200
+ * or to null when they are optional (see
201
+ * {@link ResourceService.replacementData}), and the resource is then updated
202
+ * the same way as {@link ResourceService.update}, applying the same policies,
203
+ * invalidating the same cache, and emitting the same update event. The
204
+ * optional relations missing from the data are left untouched, and a null or
205
+ * an empty list clears them.
206
+ *
207
+ * @param {ResourceId} id The id of the resource to replace.
208
+ * @param {Object} data The new state of the resource, including any inline
209
+ * relation payloads.
210
+ * @return {Promise<Object>} The replaced resource with its virtual fields and
211
+ * relation counts projected.
212
+ * @throws The same errors as {@link ResourceService.update}.
213
+ */
214
+ replace(id: ResourceId, data: Replace): Promise<ReadOne>;
215
+ /**
216
+ * Deletes an existing resource by its id. The current record is loaded with
217
+ * the read restrictions applied and checked for access before it is deleted
218
+ * inside a single transaction.
219
+ *
220
+ * A model with `softDelete` enabled marks the record with the `deletedAt`
221
+ * and `deletedById` columns instead, soft deleting its cascade as well.
222
+ *
223
+ * The stored files of the deleted records follow the `onResourceDeleted`, or
224
+ * for soft deleted records the `onResourceSoftDeleted`, option of each file
225
+ * field: kept files are marked deleted in the transaction and no longer
226
+ * served, the others are removed once it commits. The cache of every affected
227
+ * model is invalidated and a resource event is emitted.
228
+ *
229
+ * @param {ResourceId} id The id of the resource to delete.
230
+ * @return {Promise<Object>} The deleted resource with its virtual fields and
231
+ * relation counts projected.
232
+ * @throws {@link ResourceError} `RESOURCE_NOT_FOUND` if the resource does not
233
+ * exist or is filtered out by the read restrictions, `RESOURCE_FORBIDDEN` if
234
+ * the access check denies it, `RESOURCE_DELETE_RESTRICTED` if a restricting
235
+ * relation still references a soft deleted resource, and a
236
+ * {@link DatabaseError} on a database error, i.e.
237
+ * `DATABASE_FOREIGN_KEY_VIOLATION` for a restricting relation of a removed
238
+ * resource.
239
+ */
240
+ delete(id: ResourceId): Promise<ReadOne>;
241
+ /**
242
+ * Creates many resources in a single transaction, one after another the same
243
+ * way as {@link ResourceService.create}, so every item runs through the same
244
+ * policies and hooks. Either every resource is created or, when any item
245
+ * fails, none: the error of the failed item is thrown and the transaction is
246
+ * rolled back. The cache invalidation and the create resource event of every
247
+ * item wait for the commit, and are dropped on a rollback.
248
+ *
249
+ * @param {Object[]} items The data of every resource to create.
250
+ * @return {Promise<Object[]>} The created resources, in the order of the
251
+ * items.
252
+ * @throws The error of the first item that failed, the same errors as
253
+ * {@link ResourceService.create}.
254
+ */
255
+ bulkCreate(items: Create[]): Promise<ReadOne[]>;
256
+ /**
257
+ * Updates the given fields of many resources in a single transaction, one
258
+ * after another the same way as {@link ResourceService.update}. Either every
259
+ * resource is updated or none, see {@link ResourceService.bulkCreate}.
260
+ *
261
+ * @param {BulkItem[]} items The id and the partial data of every resource.
262
+ * @return {Promise<Object[]>} The updated resources, in the order of the
263
+ * items.
264
+ * @throws The error of the first item that failed, the same errors as
265
+ * {@link ResourceService.update}.
266
+ */
267
+ bulkUpdate(items: BulkItem<Update>[]): Promise<ReadOne[]>;
268
+ /**
269
+ * Replaces many resources as a whole in a single transaction, one after
270
+ * another the same way as {@link ResourceService.replace}. Either every
271
+ * resource is replaced or none, see {@link ResourceService.bulkCreate}.
272
+ *
273
+ * @param {BulkItem[]} items The id and the new state of every resource.
274
+ * @return {Promise<Object[]>} The replaced resources, in the order of the
275
+ * items.
276
+ * @throws The error of the first item that failed, the same errors as
277
+ * {@link ResourceService.replace}.
278
+ */
279
+ bulkReplace(items: BulkItem<Replace>[]): Promise<ReadOne[]>;
280
+ /**
281
+ * Deletes many resources in a single transaction, one after another the same
282
+ * way as {@link ResourceService.delete}, cascades and stored files included.
283
+ * Either every resource is deleted or none, see
284
+ * {@link ResourceService.bulkCreate}. Every id must exist up front, while an
285
+ * id the cascade of an earlier one already removed is skipped.
286
+ *
287
+ * @param {ResourceId[]} ids The ids of the resources to delete.
288
+ * @return {Promise<Object[]>} The resources deleted by their own id, in the
289
+ * order of the ids.
290
+ * @throws {@link ResourceError} `RESOURCE_NOT_FOUND` if an id does not exist,
291
+ * and otherwise the error of the first resource that failed, the same errors
292
+ * as {@link ResourceService.delete}.
293
+ */
294
+ bulkDelete(ids: ResourceId[]): Promise<ReadOne[]>;
295
+ /**
296
+ * Updates an existing resource the same way as {@link ResourceService.update},
297
+ * returning the state the resource had before the update along with the
298
+ * updated one.
299
+ *
300
+ * @param {ResourceId} id The id of the resource to update.
301
+ * @param {Object} data The partial data to update the resource with.
302
+ * @return {Promise<{ previous: Object, current: Object }>} The resource before
303
+ * and after the update, both with their virtual fields and relation counts
304
+ * projected.
305
+ */
306
+ protected updateWithPrevious(id: ResourceId, data: Update): Promise<{
307
+ previous: ReadOne;
308
+ current: ReadOne;
309
+ }>;
310
+ /**
311
+ * Completes the data of a replacement with the updatable scalar fields it
312
+ * leaves out: each one is set to the `default` value of its configuration,
313
+ * or to null when it is optional. A required field without a default value,
314
+ * which the request validation of the PUT route never lets a request leave
315
+ * out, is left untouched, and so are the hidden fields, the fields the
316
+ * `update` option of the model excludes, the virtual fields, and the
317
+ * relations.
318
+ *
319
+ * @param {Object} data The data of the replacement.
320
+ * @return {Object} A shallow copy of the data, with the missing fields set.
321
+ */
322
+ protected replacementData(data: Replace): Update;
323
+ /**
324
+ * This method should be overridden with custom logic for restricting read
325
+ * operations on specific data for currently logged-in user and other
326
+ * authorization rules. The returned object will be applied as a filter on
327
+ * all actions (except create action) which will prevent unwanted data access
328
+ * and modifications. This method can also cancel the current action by
329
+ * throwing an error, i.e. a {@link ResourceError} with the
330
+ * `RESOURCE_FORBIDDEN` code or an `ApplicationError` with a code of the
331
+ * application.
332
+ *
333
+ * Not called for the calls run with internal access (see `withoutPolicies`).
334
+ *
335
+ * @param {ActionType} action The called action method on this service (find,
336
+ * query, aggregate, update, or delete)
337
+ * @param {Object|ResourceId} data The passed data to the called function can be
338
+ * number or object. If the data is a type of number, then it represents the
339
+ * resource id, otherwise it depends on the action and can be one of the
340
+ * following:
341
+ *
342
+ * - query and aggregate -> filter object
343
+ * - update -> combined id and the data object (i.e. { id, ...data })
344
+ *
345
+ * For other actions (find and delete) it represents the resource id.
346
+ * @return {Promise<Object>} The database-level `where` conditions containing
347
+ * additional query restrictions. The returned object is applied directly to
348
+ * the database query, so it uses the native Prisma filter syntax.
349
+ */
350
+ protected readRestrictions(action: Exclude<ActionType, 'create'>, data: any): Promise<any>;
351
+ /**
352
+ * This method should be overridden with custom logic for restricting write
353
+ * operations on specific data for currently logged-in users and other
354
+ * authorization rules. The returned object will be applied as a filter on
355
+ * all actions (create and update) to ensure that users can only modify
356
+ * data they are authorized to access. This method can also cancel the
357
+ * current action by throwing an error, i.e. a {@link ResourceError} with the
358
+ * `RESOURCE_FORBIDDEN` code or an `ApplicationError` with a code of the
359
+ * application.
360
+ *
361
+ * Not called for the calls run with internal access (see `withoutPolicies`).
362
+ *
363
+ * @param {'create'|'update'} action The called action method on this service
364
+ * (create or update)
365
+ * @param {Object} data The passed data to the called function, which should be
366
+ * an object representing the resource data to be created or updated. For
367
+ * update operations, this object will also include the resource ID.
368
+ *
369
+ * @return {Promise<Object>} A partial object containing additional data
370
+ * restrictions to be applied, or an empty object if no restrictions are
371
+ * necessary.
372
+ */
373
+ protected writeRestrictions(action: 'create' | 'update', data: any): Promise<Partial<Create & Update>>;
374
+ /**
375
+ * This method should provide logic for checking the access permissions for
376
+ * the provided resource object. If the resource should not be accessible by
377
+ * a currently authenticated user or other logic, this method should return
378
+ * false. Otherwise, it returns true and continues with the request execution.
379
+ *
380
+ * Not called for the calls run with internal access (see `withoutPolicies`).
381
+ *
382
+ * @param {ActionType} action The called action method on this service (find,
383
+ * query, aggregate, create, update, or delete)
384
+ * @param {Object} resource The resource object that is being checked for access.
385
+ * @return {Promise<boolean>} True if the access for resource is granted, false
386
+ * otherwise.
387
+ */
388
+ protected checkAccess(action: ActionType, resource: ReadOne): Promise<boolean>;
389
+ /**
390
+ * Constructs a query object for performing a text search on resources in the
391
+ * database based on the provided search text. This method will transform the
392
+ * search text into a format suitable for text search functionality, returning
393
+ * a query object that can be used to filter results.
394
+ *
395
+ * @param {string} searchText The text string used for searching resources.
396
+ * @return {Object} A query object that represents the conditions for the text
397
+ * search operation, using the native Prisma filter syntax. This will be used
398
+ * by the database query methods to retrieve matching resources.
399
+ */
400
+ protected textSearchQuery(searchText: string): any;
401
+ /**
402
+ * Removes the `searchText` property from the provided filter and converts it
403
+ * into a text search query using
404
+ * {@link ResourceService.textSearchQuery}. The filter object is mutated so the
405
+ * search text is not matched as a regular resource field.
406
+ *
407
+ * @param {Object} filter The request filter object, possibly containing a
408
+ * `searchText` property. The property is deleted from this object when present.
409
+ * @return {Object} The text search query for the extracted search text, or an
410
+ * empty object if the filter contains no search text.
411
+ */
412
+ private extractTextSearchQuery;
413
+ /**
414
+ * Prepares a resource for the response by resolving the virtual fields of its
415
+ * model and flattening the Prisma `_count` aggregation into the individual
416
+ * relation count fields (i.e. `_count.posts` becomes `postsCount`).
417
+ *
418
+ * @param {Object} resource The resource object as returned by the database
419
+ * client.
420
+ * @return {Object} The same resource with the virtual fields resolved and, if a
421
+ * `_count` selection was present, with a count property per counted relation
422
+ * and the `_count` property removed.
423
+ */
424
+ private projectResource;
425
+ /**
426
+ * Lists the conditions hiding the soft deleted resources from a query. It is
427
+ * empty for a model that deletes its records, so its query and the cursors
428
+ * bound to it stay the same.
429
+ *
430
+ * @return {Object[]} The `deletedAt: null` condition, or no condition.
431
+ */
432
+ private liveFilters;
433
+ /**
434
+ * Cleans up after records were deleted, once the deleting transaction
435
+ * commits: removes the stored files their fields do not keep, since the
436
+ * storage cannot take part in the transaction, and invalidates the cache of
437
+ * every model they belong to.
438
+ *
439
+ * @param {DeletedRecords} deleted The soft deleted and the removed records.
440
+ */
441
+ private cleanupDeletedRecords;
442
+ /**
443
+ * Prepares a write payload for the database by removing the virtual fields
444
+ * that have no column, filling in default values for the hidden required
445
+ * scalars of a create action, and recursively applying the same rules to the
446
+ * nested relation and file payloads. Unique key values, arrays of them and null
447
+ * values are left untouched, so the relation actions can still map them to the
448
+ * connect and disconnect operations.
449
+ *
450
+ * @param {'create'|'update'} action The write action the payload is sanitized
451
+ * for. Default values for the hidden required scalars are only applied on a
452
+ * create action.
453
+ * @param {Object} data The write payload to sanitize.
454
+ * @param {string} [resourceName] The name of the model the payload belongs to.
455
+ * Defaults to the model of this service and is set to the related model name
456
+ * when recursing into a nested relation or file payload.
457
+ * @return {Object} A shallow copy of the payload without the virtual fields,
458
+ * with the missing hidden required scalars defaulted, and with the nested
459
+ * payloads sanitized against their own models.
460
+ */
461
+ private sanitizeData;
462
+ }