@appsemble/node-utils 0.29.11 → 0.30.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 (100) hide show
  1. package/AppMemberPropertiesError.d.ts +3 -0
  2. package/AppMemberPropertiesError.js +8 -0
  3. package/README.md +3 -3
  4. package/app.d.ts +2 -3
  5. package/app.js +6 -7
  6. package/authentication.js +1 -1
  7. package/index.d.ts +1 -1
  8. package/index.js +1 -1
  9. package/package.json +3 -3
  10. package/resource.d.ts +5 -5
  11. package/resource.js +6 -6
  12. package/server/controllers/apps/actions/createProxyDeleteController.d.ts +3 -0
  13. package/server/controllers/apps/actions/createProxyDeleteController.js +5 -0
  14. package/server/controllers/apps/actions/createProxyGetController.d.ts +3 -0
  15. package/server/controllers/apps/actions/createProxyGetController.js +5 -0
  16. package/server/controllers/apps/actions/createProxyPatchController.d.ts +3 -0
  17. package/server/controllers/apps/actions/createProxyPatchController.js +5 -0
  18. package/server/controllers/apps/actions/createProxyPostController.d.ts +3 -0
  19. package/server/controllers/apps/actions/createProxyPostController.js +5 -0
  20. package/server/controllers/apps/actions/createProxyPutController.d.ts +3 -0
  21. package/server/controllers/apps/actions/createProxyPutController.js +5 -0
  22. package/server/controllers/apps/actions/index.d.ts +5 -0
  23. package/server/controllers/apps/actions/index.js +6 -0
  24. package/server/controllers/apps/index.d.ts +2 -0
  25. package/server/controllers/apps/index.js +3 -0
  26. package/server/controllers/apps/members/current/createGetCurrentAppMemberController.d.ts +3 -0
  27. package/server/controllers/apps/members/current/createGetCurrentAppMemberController.js +6 -0
  28. package/server/controllers/apps/members/current/index.d.ts +1 -0
  29. package/server/controllers/apps/members/current/index.js +2 -0
  30. package/server/controllers/apps/members/index.d.ts +1 -0
  31. package/server/controllers/apps/members/index.js +2 -0
  32. package/server/controllers/common/apps/assets/createGetAppAssetByIdController.d.ts +3 -0
  33. package/server/controllers/common/apps/assets/createGetAppAssetByIdController.js +37 -0
  34. package/server/controllers/common/apps/assets/index.d.ts +1 -0
  35. package/server/controllers/common/apps/assets/index.js +2 -0
  36. package/server/controllers/common/apps/groups/createGetAppGroupsController.d.ts +3 -0
  37. package/server/controllers/common/apps/groups/createGetAppGroupsController.js +16 -0
  38. package/server/controllers/common/apps/groups/index.d.ts +1 -0
  39. package/server/controllers/common/apps/groups/index.js +2 -0
  40. package/server/controllers/common/apps/index.d.ts +5 -0
  41. package/server/controllers/common/apps/index.js +6 -0
  42. package/server/controllers/common/apps/messages/createGetAppMessagesController.d.ts +3 -0
  43. package/server/controllers/{appMessages.js → common/apps/messages/createGetAppMessagesController.js} +3 -3
  44. package/server/controllers/common/apps/messages/index.d.ts +1 -0
  45. package/server/controllers/common/apps/messages/index.js +2 -0
  46. package/server/controllers/{appMessages.d.ts → common/apps/resources/createCountAppResourcesController.d.ts} +1 -1
  47. package/server/controllers/common/apps/resources/createCountAppResourcesController.js +40 -0
  48. package/server/controllers/common/apps/resources/createCreateAppResourceController.d.ts +15 -0
  49. package/server/controllers/common/apps/resources/createCreateAppResourceController.js +94 -0
  50. package/server/controllers/common/apps/resources/createDeleteAppResourceController.d.ts +3 -0
  51. package/server/controllers/common/apps/resources/createDeleteAppResourceController.js +46 -0
  52. package/server/controllers/common/apps/resources/createGetAppResourceByIdController.d.ts +3 -0
  53. package/server/controllers/common/apps/resources/createGetAppResourceByIdController.js +48 -0
  54. package/server/controllers/common/apps/resources/createQueryAppResourcesController.d.ts +3 -0
  55. package/server/controllers/common/apps/resources/createQueryAppResourcesController.js +58 -0
  56. package/server/controllers/common/apps/resources/createUpdateAppResourceController.d.ts +3 -0
  57. package/server/controllers/common/apps/resources/createUpdateAppResourceController.js +53 -0
  58. package/server/controllers/common/apps/resources/index.d.ts +6 -0
  59. package/server/controllers/common/apps/resources/index.js +7 -0
  60. package/server/controllers/{resources.test.js → common/apps/resources/resources.test.js} +44 -32
  61. package/server/controllers/common/apps/variables/createGetAppVariablesController.d.ts +3 -0
  62. package/server/controllers/{appVariables.js → common/apps/variables/createGetAppVariablesController.js} +4 -5
  63. package/server/controllers/common/apps/variables/index.d.ts +1 -0
  64. package/server/controllers/common/apps/variables/index.js +2 -0
  65. package/server/controllers/common/index.d.ts +1 -0
  66. package/server/controllers/common/index.js +2 -0
  67. package/server/controllers/index.d.ts +3 -8
  68. package/server/controllers/index.js +3 -8
  69. package/server/controllers/main/apps/assets/createCreateAppAssetController.d.ts +3 -0
  70. package/server/controllers/main/apps/assets/createCreateAppAssetController.js +16 -0
  71. package/server/controllers/main/apps/assets/index.d.ts +1 -0
  72. package/server/controllers/main/apps/assets/index.js +2 -0
  73. package/server/controllers/main/apps/index.d.ts +2 -0
  74. package/server/controllers/main/apps/index.js +3 -0
  75. package/server/controllers/main/apps/resources/createDeleteAppSeedResourcesController.d.ts +3 -0
  76. package/server/controllers/main/apps/resources/createDeleteAppSeedResourcesController.js +15 -0
  77. package/server/controllers/main/apps/resources/index.d.ts +1 -0
  78. package/server/controllers/main/apps/resources/index.js +2 -0
  79. package/server/controllers/main/index.d.ts +1 -0
  80. package/server/controllers/main/index.js +2 -0
  81. package/server/types.d.ts +51 -61
  82. package/server/utils/actions.d.ts +6 -0
  83. package/server/{controllers/action.js → utils/actions.js} +19 -50
  84. package/server/utils/resources.d.ts +8 -0
  85. package/server/utils/resources.js +51 -0
  86. package/UserPropertiesError.d.ts +0 -3
  87. package/UserPropertiesError.js +0 -8
  88. package/server/controllers/action.d.ts +0 -7
  89. package/server/controllers/appMembers.d.ts +0 -3
  90. package/server/controllers/appMembers.js +0 -13
  91. package/server/controllers/appVariables.d.ts +0 -3
  92. package/server/controllers/assets.d.ts +0 -5
  93. package/server/controllers/assets.js +0 -66
  94. package/server/controllers/oauth2Provider.d.ts +0 -3
  95. package/server/controllers/oauth2Provider.js +0 -7
  96. package/server/controllers/resources.d.ts +0 -10
  97. package/server/controllers/resources.js +0 -402
  98. package/server/controllers/teams.d.ts +0 -3
  99. package/server/controllers/teams.js +0 -10
  100. /package/server/controllers/{resources.test.d.ts → common/apps/resources/resources.test.d.ts} +0 -0
@@ -1,402 +0,0 @@
1
- import { randomUUID } from 'node:crypto';
2
- import { isDeepStrictEqual } from 'node:util';
3
- import { assertKoaError, getRemapperContext, getResourceDefinition, logger, processResourceBody, throwKoaError, } from '@appsemble/node-utils';
4
- import { defaultLocale, remap } from '@appsemble/utils';
5
- function generateQuery(ctx, { parseQuery }, resourceDefinition) {
6
- try {
7
- return parseQuery({
8
- $filter: ctx.queryParams.$filter,
9
- $orderby: ctx.queryParams.$orderby,
10
- resourceDefinition,
11
- });
12
- }
13
- catch (error) {
14
- if (error instanceof Error) {
15
- throwKoaError(ctx, 400, 'Unable to process this query', { syntaxError: error.message });
16
- }
17
- logger.error(error);
18
- throwKoaError(ctx, 400, 'Unable to process this query');
19
- }
20
- }
21
- export function createQueryResources(options) {
22
- return async (ctx) => {
23
- var _a, _b, _c, _d, _e;
24
- const { pathParams: { appId, resourceType }, queryParams: { $select, $skip, $top }, user, } = ctx;
25
- const { getApp, getAppResources, verifyResourceActionPermission } = options;
26
- const app = await getApp({ context: ctx, query: { where: { id: appId } } });
27
- const view = (_a = ctx.queryParams) === null || _a === void 0 ? void 0 : _a.view;
28
- const resourceDefinition = getResourceDefinition(app, resourceType, ctx, view);
29
- const { order, where } = generateQuery(ctx, options, resourceDefinition);
30
- const memberQuery = await verifyResourceActionPermission({
31
- context: ctx,
32
- app,
33
- resourceType,
34
- action: 'query',
35
- options,
36
- ctx,
37
- });
38
- const isSameOrigin = ((_b = ctx === null || ctx === void 0 ? void 0 : ctx.headers) === null || _b === void 0 ? void 0 : _b.origin) === ((_c = ctx === null || ctx === void 0 ? void 0 : ctx.headers) === null || _c === void 0 ? void 0 : _c.host);
39
- const findOptions = {
40
- limit: $top,
41
- offset: $skip,
42
- attributes: $select === null || $select === void 0 ? void 0 : $select.split(',').map((s) => s.trim()),
43
- where: {
44
- and: [
45
- where,
46
- {
47
- ...memberQuery,
48
- type: resourceType,
49
- AppId: appId,
50
- expires: { or: [{ gt: new Date() }, null] },
51
- ...(app.demoMode && !isSameOrigin ? { seed: false, ephemeral: true } : {}),
52
- },
53
- ],
54
- },
55
- order,
56
- };
57
- const resources = await getAppResources({
58
- app,
59
- findOptions,
60
- type: resourceType,
61
- context: ctx,
62
- });
63
- if (view) {
64
- const context = await getRemapperContext(app, app.definition.defaultLanguage || defaultLocale, user && {
65
- sub: user.id,
66
- name: user.name,
67
- email: user.primaryEmail,
68
- email_verified: Boolean((_e = (_d = user.EmailAuthorizations) === null || _d === void 0 ? void 0 : _d[0]) === null || _e === void 0 ? void 0 : _e.verified),
69
- zoneinfo: user.timezone,
70
- }, options, ctx);
71
- ctx.body = resources.map((resource) => remap(resourceDefinition.views[view].remap, resource, context));
72
- return;
73
- }
74
- ctx.body = resources;
75
- };
76
- }
77
- export function createCountResources(options) {
78
- return async (ctx) => {
79
- const { pathParams: { appId, resourceType }, } = ctx;
80
- const action = 'count';
81
- const { getApp, getAppResources, verifyResourceActionPermission } = options;
82
- const app = await getApp({ context: ctx, query: { where: { id: appId } } });
83
- const memberQuery = await verifyResourceActionPermission({
84
- app,
85
- context: ctx,
86
- action,
87
- resourceType,
88
- options,
89
- ctx,
90
- });
91
- const { where } = generateQuery(ctx, options);
92
- const findOptions = {
93
- where: {
94
- and: [
95
- where || {},
96
- {
97
- ...memberQuery,
98
- type: resourceType,
99
- AppId: appId,
100
- expires: { or: [{ gt: new Date() }, null] },
101
- ...(app.demoMode ? { seed: false, ephemeral: true } : {}),
102
- },
103
- ],
104
- },
105
- };
106
- const resources = await getAppResources({
107
- app,
108
- findOptions,
109
- type: resourceType,
110
- context: ctx,
111
- });
112
- ctx.body = resources.length;
113
- };
114
- }
115
- export function createGetResourceById(options) {
116
- return async (ctx) => {
117
- var _a, _b, _c;
118
- const { pathParams: { appId, resourceId, resourceType }, user, } = ctx;
119
- const action = 'get';
120
- const { getApp, getAppResource, verifyResourceActionPermission } = options;
121
- const app = await getApp({ context: ctx, query: { where: { id: appId } } });
122
- const view = (_a = ctx.queryParams) === null || _a === void 0 ? void 0 : _a.view;
123
- const resourceDefinition = getResourceDefinition(app, resourceType, ctx, view);
124
- const memberQuery = await verifyResourceActionPermission({
125
- app,
126
- context: ctx,
127
- action,
128
- resourceType,
129
- options,
130
- ctx,
131
- });
132
- const findOptions = {
133
- where: {
134
- ...memberQuery,
135
- id: resourceId,
136
- type: resourceType,
137
- AppId: appId,
138
- expires: { or: [{ gt: new Date() }, null] },
139
- ...(app.demoMode ? { seed: false, ephemeral: true } : {}),
140
- },
141
- };
142
- const resource = await getAppResource({
143
- app,
144
- id: resourceId,
145
- type: resourceType,
146
- context: ctx,
147
- findOptions,
148
- });
149
- assertKoaError(!resource, ctx, 404, 'Resource not found');
150
- if (view) {
151
- const context = await getRemapperContext(app, app.definition.defaultLanguage || defaultLocale, user && {
152
- sub: user.id,
153
- name: user.name,
154
- email: user.primaryEmail,
155
- email_verified: Boolean((_c = (_b = user.EmailAuthorizations) === null || _b === void 0 ? void 0 : _b[0]) === null || _c === void 0 ? void 0 : _c.verified),
156
- zoneinfo: user.timezone,
157
- }, options, ctx);
158
- ctx.body = remap(resourceDefinition.views[view].remap, resource, context);
159
- return;
160
- }
161
- ctx.body = resource;
162
- };
163
- }
164
- export function createCreateResource(options) {
165
- return async (ctx) => {
166
- const { pathParams: { appId, resourceType }, } = ctx;
167
- const { createAppResourcesWithAssets, getApp, getAppAssets, verifyResourceActionPermission } = options;
168
- const action = 'create';
169
- const app = await getApp({ context: ctx, query: { where: { id: appId } } });
170
- const resourceDefinition = getResourceDefinition(app, resourceType, ctx);
171
- await verifyResourceActionPermission({ app, context: ctx, action, resourceType, options, ctx });
172
- const appAssets = await getAppAssets({ app, context: ctx });
173
- const [processedBody, preparedAssets] = processResourceBody(ctx, resourceDefinition, undefined, undefined, appAssets.map((appAsset) => ({ id: appAsset.id, name: appAsset.name })));
174
- if (Array.isArray(processedBody) && !processedBody.length) {
175
- ctx.body = [];
176
- return;
177
- }
178
- const resources = Array.isArray(processedBody) ? processedBody : [processedBody];
179
- const createdResources = await createAppResourcesWithAssets({
180
- app,
181
- context: ctx,
182
- resources: resources.map((resource) => ({
183
- ...resource,
184
- $seed: false,
185
- $ephemeral: app.demoMode,
186
- })),
187
- preparedAssets,
188
- resourceType,
189
- action,
190
- options,
191
- });
192
- ctx.body = Array.isArray(processedBody) ? createdResources : createdResources[0];
193
- };
194
- }
195
- export function createUpdateResource(options) {
196
- return async (ctx) => {
197
- const { pathParams: { appId, resourceId, resourceType }, } = ctx;
198
- const { getApp, getAppAssets, getAppResource, updateAppResource, verifyResourceActionPermission, } = options;
199
- const action = 'update';
200
- const app = await getApp({ context: ctx, query: { where: { id: appId } } });
201
- const resourceDefinition = getResourceDefinition(app, resourceType, ctx);
202
- const memberQuery = await verifyResourceActionPermission({
203
- app,
204
- context: ctx,
205
- action,
206
- resourceType,
207
- options,
208
- ctx,
209
- });
210
- const findOptions = {
211
- where: {
212
- ...memberQuery,
213
- id: resourceId,
214
- type: resourceType,
215
- AppId: appId,
216
- expires: { or: [{ gt: new Date() }, null] },
217
- ...(app.demoMode ? { seed: false, ephemeral: true } : {}),
218
- },
219
- };
220
- const oldResource = await getAppResource({
221
- app,
222
- id: resourceId,
223
- type: resourceType,
224
- context: ctx,
225
- findOptions,
226
- });
227
- assertKoaError(!oldResource, ctx, 404, 'Resource not found');
228
- const appAssets = await getAppAssets({ context: ctx, app });
229
- const [processedBody, preparedAssets, deletedAssetIds] = processResourceBody(ctx, resourceDefinition, appAssets.filter((asset) => asset.resourceId === resourceId).map((asset) => asset.id), oldResource.expires, appAssets.map((asset) => ({ id: asset.id, name: asset.name })));
230
- const resources = Array.isArray(processedBody) ? processedBody : [processedBody];
231
- ctx.body = await updateAppResource({
232
- app,
233
- context: ctx,
234
- id: resourceId,
235
- type: resourceType,
236
- resource: resources[0],
237
- preparedAssets,
238
- deletedAssetIds,
239
- resourceDefinition,
240
- action,
241
- options,
242
- });
243
- };
244
- }
245
- export function createDeleteResource(options) {
246
- return async (ctx) => {
247
- const { pathParams: { appId, resourceId, resourceType }, } = ctx;
248
- const { deleteAppResource, getApp, getAppResource, verifyResourceActionPermission } = options;
249
- const action = 'delete';
250
- const app = await getApp({ context: ctx, query: { where: { id: appId } } });
251
- const memberQuery = await verifyResourceActionPermission({
252
- app,
253
- context: ctx,
254
- action,
255
- resourceType,
256
- options,
257
- ctx,
258
- });
259
- const findOptions = {
260
- where: {
261
- ...memberQuery,
262
- id: resourceId,
263
- type: resourceType,
264
- AppId: appId,
265
- expires: { or: [{ gt: new Date() }, { eq: null }] },
266
- ...(app.demoMode ? { seed: false, ephemeral: true } : {}),
267
- },
268
- };
269
- const resource = await getAppResource({
270
- app,
271
- id: resourceId,
272
- type: resourceType,
273
- context: ctx,
274
- findOptions,
275
- });
276
- assertKoaError(!resource, ctx, 404, 'Resource not found');
277
- await deleteAppResource({
278
- app,
279
- context: ctx,
280
- id: resourceId,
281
- type: resourceType,
282
- options,
283
- });
284
- ctx.status = 204;
285
- };
286
- }
287
- export function createSeedResource(options) {
288
- return async (ctx) => {
289
- const { pathParams: { appId, resourceType }, } = ctx;
290
- const { createAppResourcesWithAssets, getApp, getAppAssets, verifyResourceActionPermission } = options;
291
- const action = 'create';
292
- const app = await getApp({ context: ctx, query: { where: { id: appId } } });
293
- const resourceDefinition = getResourceDefinition(app, resourceType, ctx);
294
- await verifyResourceActionPermission({ app, context: ctx, action, resourceType, options, ctx });
295
- const appAssets = await getAppAssets({ app, context: ctx });
296
- const [processedBody, preparedAssets] = processResourceBody(ctx, resourceDefinition, undefined, undefined, appAssets.map((appAsset) => ({ id: appAsset.id, name: appAsset.name })));
297
- if (Array.isArray(processedBody) && !processedBody.length) {
298
- ctx.body = [];
299
- return;
300
- }
301
- const resources = Array.isArray(processedBody) ? processedBody : [processedBody];
302
- let createdResources;
303
- const preparedSeedAssets = structuredClone(preparedAssets);
304
- const preparedSeedResources = resources.map((resource) => {
305
- var _a;
306
- const cleanResource = { ...resource };
307
- if (app.demoMode) {
308
- for (const referencedProperty of Object.keys((_a = resourceDefinition.references) !== null && _a !== void 0 ? _a : {})) {
309
- delete cleanResource[referencedProperty];
310
- }
311
- }
312
- return {
313
- ...cleanResource,
314
- $seed: true,
315
- $ephemeral: false,
316
- };
317
- });
318
- for (const preparedSeedAsset of preparedSeedAssets) {
319
- const index = resources.findIndex(({ $clonable: clonable, $ephemeral: ephemeral, $seed: seed, ...cleanResource }) => {
320
- const { $clonable, $ephemeral, $seed, ...cleanAssetResource } = preparedSeedAsset.resource;
321
- return isDeepStrictEqual(cleanResource, cleanAssetResource);
322
- });
323
- const previousAssetId = preparedSeedAsset.id;
324
- const newAssetId = randomUUID();
325
- const updatedResource = JSON.parse(JSON.stringify(preparedSeedResources[index]).replace(previousAssetId, newAssetId));
326
- preparedSeedAsset.id = newAssetId;
327
- preparedSeedAsset.resource = updatedResource;
328
- preparedSeedResources[index] = updatedResource;
329
- }
330
- createdResources = await createAppResourcesWithAssets({
331
- app,
332
- context: ctx,
333
- resources: preparedSeedResources,
334
- preparedAssets: preparedSeedAssets,
335
- resourceType,
336
- action,
337
- options,
338
- });
339
- if (app.demoMode) {
340
- createdResources = await createAppResourcesWithAssets({
341
- app,
342
- context: ctx,
343
- resources: resources.map((resource) => ({
344
- ...resource,
345
- $seed: false,
346
- $ephemeral: true,
347
- $clonable: false,
348
- })),
349
- preparedAssets,
350
- resourceType,
351
- action,
352
- options,
353
- });
354
- }
355
- ctx.body = Array.isArray(processedBody) ? createdResources : createdResources[0];
356
- };
357
- }
358
- async function deleteResourcesRecursively(type, app, options, context) {
359
- const { deleteAppResource, getAppResources } = options;
360
- const referencingResources = Object.entries(app.definition.resources).filter(([, resourceDefinition]) => {
361
- var _a;
362
- return Object.values((_a = resourceDefinition.references) !== null && _a !== void 0 ? _a : {}).find((resourceReference) => resourceReference.resource === type);
363
- });
364
- for (const [referencingResourceType] of referencingResources) {
365
- await deleteResourcesRecursively(referencingResourceType, app, options, context);
366
- }
367
- const resourcesToDeleteFindOptions = {
368
- where: {
369
- type,
370
- AppId: app.id,
371
- or: [{ seed: true }, { ephemeral: true }],
372
- },
373
- };
374
- const resourcesToDelete = await getAppResources({
375
- app,
376
- findOptions: resourcesToDeleteFindOptions,
377
- type,
378
- context,
379
- });
380
- for (const resourceToDelete of resourcesToDelete) {
381
- await deleteAppResource({
382
- app,
383
- context,
384
- options,
385
- id: resourceToDelete.id,
386
- type,
387
- });
388
- }
389
- }
390
- export function createDeleteSeedResources(options) {
391
- return async (ctx) => {
392
- var _a;
393
- const { pathParams: { appId }, } = ctx;
394
- const { getApp } = options;
395
- const app = await getApp({ context: ctx, query: { where: { id: appId } } });
396
- assertKoaError(!app, ctx, 404, 'App not found');
397
- for (const resourceType of Object.keys((_a = app.definition.resources) !== null && _a !== void 0 ? _a : {})) {
398
- await deleteResourcesRecursively(resourceType, app, options, ctx);
399
- }
400
- };
401
- }
402
- //# sourceMappingURL=resources.js.map
@@ -1,3 +0,0 @@
1
- import { type Middleware } from 'koa';
2
- import { type Options } from '../types.js';
3
- export declare function createGetTeams({ getApp, getAppTeams }: Options): Middleware;
@@ -1,10 +0,0 @@
1
- import { assertKoaError } from '../../koa.js';
2
- export function createGetTeams({ getApp, getAppTeams }) {
3
- return async (ctx) => {
4
- const { pathParams: { appId }, user, } = ctx;
5
- const app = await getApp({ context: ctx, query: { where: { id: appId } } });
6
- assertKoaError(!app, ctx, 404, 'App not found');
7
- ctx.body = await getAppTeams({ context: ctx, app, user });
8
- };
9
- }
10
- //# sourceMappingURL=teams.js.map