@appsemble/node-utils 0.20.45 → 0.21.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 (104) hide show
  1. package/README.md +3 -3
  2. package/app.d.ts +17 -0
  3. package/app.js +49 -0
  4. package/csv.d.ts +2 -0
  5. package/csv.js +55 -0
  6. package/fs.d.ts +3 -3
  7. package/fs.js +1 -1
  8. package/fs.test.js +5 -5
  9. package/getAppsembleMessages.d.ts +9 -0
  10. package/getAppsembleMessages.js +32 -0
  11. package/handleError.test.js +4 -4
  12. package/icon.d.ts +44 -0
  13. package/icon.js +69 -0
  14. package/index.d.ts +22 -1
  15. package/index.js +22 -1
  16. package/interceptors.test.js +5 -6
  17. package/jsonschema.d.ts +2 -0
  18. package/jsonschema.js +7 -0
  19. package/koa.d.ts +6 -0
  20. package/koa.js +27 -0
  21. package/logger.js +1 -1
  22. package/mergeMessages.d.ts +9 -0
  23. package/mergeMessages.js +17 -0
  24. package/middleware/boom.d.ts +7 -0
  25. package/middleware/boom.js +32 -0
  26. package/middleware/boom.test.js +58 -0
  27. package/middleware/conditional.d.ts +2 -0
  28. package/middleware/conditional.js +9 -0
  29. package/middleware/frontend.d.ts +3 -0
  30. package/middleware/frontend.js +40 -0
  31. package/{loggerMiddleware.js → middleware/loggerMiddleware.js} +1 -1
  32. package/{loggerMiddleware.test.js → middleware/loggerMiddleware.test.js} +14 -15
  33. package/odata.d.ts +18 -0
  34. package/odata.js +45 -0
  35. package/organizationBlocklist.d.ts +4 -0
  36. package/organizationBlocklist.js +5 -0
  37. package/package.json +45 -5
  38. package/parsers.d.ts +3 -0
  39. package/parsers.js +18 -0
  40. package/readAsset.d.ts +13 -0
  41. package/readAsset.js +6 -0
  42. package/readFileOrString.d.ts +1 -1
  43. package/render.d.ts +21 -0
  44. package/render.js +46 -0
  45. package/resource.d.ts +43 -0
  46. package/resource.js +172 -0
  47. package/scim.d.ts +26 -0
  48. package/scim.js +32 -0
  49. package/server/controllers/action.d.ts +7 -0
  50. package/server/controllers/action.js +129 -0
  51. package/server/controllers/appMembers.d.ts +3 -0
  52. package/server/controllers/appMembers.js +19 -0
  53. package/server/controllers/appMessages.d.ts +3 -0
  54. package/server/controllers/appMessages.js +75 -0
  55. package/server/controllers/assets.d.ts +5 -0
  56. package/server/controllers/assets.js +74 -0
  57. package/server/controllers/index.d.ts +7 -0
  58. package/server/controllers/index.js +8 -0
  59. package/server/controllers/oauth2Provider.d.ts +3 -0
  60. package/server/controllers/oauth2Provider.js +7 -0
  61. package/server/controllers/resources.d.ts +8 -0
  62. package/server/controllers/resources.js +273 -0
  63. package/server/controllers/resources.test.d.ts +1 -0
  64. package/server/controllers/resources.test.js +552 -0
  65. package/server/controllers/teams.d.ts +3 -0
  66. package/server/controllers/teams.js +12 -0
  67. package/server/routes/appRouter/blockAssetHandler.d.ts +3 -0
  68. package/server/routes/appRouter/blockAssetHandler.js +13 -0
  69. package/server/routes/appRouter/blockCssHandler.d.ts +3 -0
  70. package/server/routes/appRouter/blockCssHandler.js +15 -0
  71. package/server/routes/appRouter/bulmaHandler.d.ts +3 -0
  72. package/server/routes/appRouter/bulmaHandler.js +118 -0
  73. package/server/routes/appRouter/cssHandler.d.ts +3 -0
  74. package/server/routes/appRouter/cssHandler.js +12 -0
  75. package/server/routes/appRouter/iconHandler.d.ts +3 -0
  76. package/server/routes/appRouter/iconHandler.js +23 -0
  77. package/server/routes/appRouter/index.d.ts +3 -0
  78. package/server/routes/appRouter/index.js +85 -0
  79. package/server/routes/appRouter/indexHandler.d.ts +5 -0
  80. package/server/routes/appRouter/indexHandler.js +69 -0
  81. package/server/routes/appRouter/manifestHandler.d.ts +3 -0
  82. package/server/routes/appRouter/manifestHandler.js +47 -0
  83. package/server/routes/appRouter/robotsHandler.d.ts +2 -0
  84. package/server/routes/appRouter/robotsHandler.js +6 -0
  85. package/server/routes/appRouter/screenshotHandler.d.ts +3 -0
  86. package/server/routes/appRouter/screenshotHandler.js +19 -0
  87. package/server/routes/appRouter/serviceWorkerHandler.d.ts +3 -0
  88. package/server/routes/appRouter/serviceWorkerHandler.js +18 -0
  89. package/server/routes/appRouter/staticHandler.d.ts +2 -0
  90. package/server/routes/appRouter/staticHandler.js +9 -0
  91. package/server/types.d.ts +356 -0
  92. package/server/types.js +2 -0
  93. package/testFixtures.d.ts +3 -3
  94. package/testFixtures.js +1 -1
  95. package/tinyRouter.d.ts +16 -0
  96. package/tinyRouter.js +34 -0
  97. package/tinyRouter.test.d.ts +1 -0
  98. package/tinyRouter.test.js +85 -0
  99. package/vitest.config.d.ts +2 -0
  100. package/vitest.setup.d.ts +1 -0
  101. package/{jest.setup.js → vitest.setup.js} +1 -1
  102. /package/{jest.setup.d.ts → middleware/boom.test.d.ts} +0 -0
  103. /package/{loggerMiddleware.d.ts → middleware/loggerMiddleware.d.ts} +0 -0
  104. /package/{loggerMiddleware.test.d.ts → middleware/loggerMiddleware.test.d.ts} +0 -0
@@ -0,0 +1,273 @@
1
+ import { getRemapperContext, getResourceDefinition, logger, processResourceBody, } from '@appsemble/node-utils';
2
+ import { defaultLocale, remap } from '@appsemble/utils';
3
+ import { badRequest, internal, notFound } from '@hapi/boom';
4
+ function generateQuery(ctx, { parseQuery }) {
5
+ try {
6
+ return parseQuery({ $filter: ctx.queryParams.$filter, $orderby: ctx.queryParams.$orderby });
7
+ }
8
+ catch (error) {
9
+ if (error instanceof Error) {
10
+ throw badRequest('Unable to process this query', { syntaxError: error.message });
11
+ }
12
+ logger.error(error);
13
+ throw internal('Unable to process this query');
14
+ }
15
+ }
16
+ export function createQueryResources(options) {
17
+ return async (ctx) => {
18
+ var _a, _b, _c;
19
+ const { pathParams: { appId, resourceType }, queryParams: { $select, $skip, $top }, user, } = ctx;
20
+ const { getApp, getAppResources, verifyResourceActionPermission } = options;
21
+ const app = await getApp({ context: ctx, query: { where: { id: appId } } });
22
+ const { order, where } = generateQuery(ctx, options);
23
+ const userQuery = await verifyResourceActionPermission({
24
+ context: ctx,
25
+ app,
26
+ resourceType,
27
+ action: 'query',
28
+ options,
29
+ });
30
+ const findOptions = {
31
+ limit: $top,
32
+ offset: $skip,
33
+ attributes: $select === null || $select === void 0 ? void 0 : $select.split(',').map((s) => s.trim()),
34
+ where: {
35
+ and: [
36
+ where,
37
+ {
38
+ ...userQuery,
39
+ type: resourceType,
40
+ AppId: appId,
41
+ expires: { or: [{ gt: new Date() }, null] },
42
+ },
43
+ ],
44
+ },
45
+ order,
46
+ };
47
+ const resources = await getAppResources({
48
+ app,
49
+ findOptions,
50
+ type: resourceType,
51
+ context: ctx,
52
+ });
53
+ const view = (_a = ctx.queryParams) === null || _a === void 0 ? void 0 : _a.view;
54
+ const resourceDefinition = getResourceDefinition(app, resourceType, view);
55
+ if (view) {
56
+ const context = await getRemapperContext(app, app.definition.defaultLanguage || defaultLocale, user && {
57
+ sub: user.id,
58
+ name: user.name,
59
+ email: user.primaryEmail,
60
+ email_verified: Boolean((_c = (_b = user.EmailAuthorizations) === null || _b === void 0 ? void 0 : _b[0]) === null || _c === void 0 ? void 0 : _c.verified),
61
+ zoneinfo: user.timezone,
62
+ }, options, ctx);
63
+ ctx.body = resources.map((resource) => remap(resourceDefinition.views[view].remap, resource, context));
64
+ return;
65
+ }
66
+ ctx.body = resources;
67
+ };
68
+ }
69
+ export function createCountResources(options) {
70
+ return async (ctx) => {
71
+ const { pathParams: { appId, resourceType }, } = ctx;
72
+ const action = 'count';
73
+ const { getApp, getAppResources, verifyResourceActionPermission } = options;
74
+ const app = await getApp({ context: ctx, query: { where: { id: appId } } });
75
+ const userQuery = await verifyResourceActionPermission({
76
+ app,
77
+ context: ctx,
78
+ action,
79
+ resourceType,
80
+ options,
81
+ });
82
+ const { where } = generateQuery(ctx, options);
83
+ const findOptions = {
84
+ where: {
85
+ and: [
86
+ where || {},
87
+ {
88
+ ...userQuery,
89
+ type: resourceType,
90
+ AppId: appId,
91
+ expires: { or: [{ gt: new Date() }, null] },
92
+ },
93
+ ],
94
+ },
95
+ };
96
+ const resources = await getAppResources({
97
+ app,
98
+ findOptions,
99
+ type: resourceType,
100
+ context: ctx,
101
+ });
102
+ ctx.body = resources.length;
103
+ };
104
+ }
105
+ export function createGetResourceById(options) {
106
+ return async (ctx) => {
107
+ var _a, _b, _c;
108
+ const { pathParams: { appId, resourceId, resourceType }, user, } = ctx;
109
+ const action = 'get';
110
+ const { getApp, getAppResource, verifyResourceActionPermission } = options;
111
+ const app = await getApp({ context: ctx, query: { where: { id: appId } } });
112
+ const view = (_a = ctx.queryParams) === null || _a === void 0 ? void 0 : _a.view;
113
+ const resourceDefinition = getResourceDefinition(app, resourceType, view);
114
+ const userQuery = await verifyResourceActionPermission({
115
+ app,
116
+ context: ctx,
117
+ action,
118
+ resourceType,
119
+ options,
120
+ });
121
+ const findOptions = {
122
+ where: {
123
+ ...userQuery,
124
+ id: resourceId,
125
+ type: resourceType,
126
+ AppId: appId,
127
+ expires: { or: [{ gt: new Date() }, null] },
128
+ },
129
+ };
130
+ const resource = await getAppResource({
131
+ app,
132
+ id: resourceId,
133
+ type: resourceType,
134
+ context: ctx,
135
+ findOptions,
136
+ });
137
+ if (!resource) {
138
+ throw notFound('Resource not found');
139
+ }
140
+ if (view) {
141
+ const context = await getRemapperContext(app, app.definition.defaultLanguage || defaultLocale, user && {
142
+ sub: user.id,
143
+ name: user.name,
144
+ email: user.primaryEmail,
145
+ email_verified: Boolean((_c = (_b = user.EmailAuthorizations) === null || _b === void 0 ? void 0 : _b[0]) === null || _c === void 0 ? void 0 : _c.verified),
146
+ zoneinfo: user.timezone,
147
+ }, options, ctx);
148
+ ctx.body = remap(resourceDefinition.views[view].remap, resource, context);
149
+ return;
150
+ }
151
+ ctx.body = resource;
152
+ };
153
+ }
154
+ export function createCreateResource(options) {
155
+ return async (ctx) => {
156
+ const { pathParams: { appId, resourceType }, } = ctx;
157
+ const { createAppResourcesWithAssets, getApp, verifyResourceActionPermission } = options;
158
+ const action = 'create';
159
+ const app = await getApp({ context: ctx, query: { where: { id: appId } } });
160
+ const resourceDefinition = getResourceDefinition(app, resourceType);
161
+ await verifyResourceActionPermission({ app, context: ctx, action, resourceType, options });
162
+ const [processedBody, preparedAssets] = processResourceBody(ctx, resourceDefinition);
163
+ if (Array.isArray(processedBody) && !processedBody.length) {
164
+ ctx.body = [];
165
+ return;
166
+ }
167
+ const resources = Array.isArray(processedBody) ? processedBody : [processedBody];
168
+ const createdResources = await createAppResourcesWithAssets({
169
+ app,
170
+ context: ctx,
171
+ resources,
172
+ preparedAssets,
173
+ resourceType,
174
+ action,
175
+ options,
176
+ });
177
+ ctx.body = Array.isArray(processedBody) ? createdResources : createdResources[0];
178
+ };
179
+ }
180
+ export function createUpdateResource(options) {
181
+ return async (ctx) => {
182
+ const { pathParams: { appId, resourceId, resourceType }, } = ctx;
183
+ const { getApp, getAppAssets, getAppResource, updateAppResource, verifyResourceActionPermission, } = options;
184
+ const action = 'update';
185
+ const app = await getApp({ context: ctx, query: { where: { id: appId } } });
186
+ const resourceDefinition = getResourceDefinition(app, resourceType);
187
+ const userQuery = await verifyResourceActionPermission({
188
+ app,
189
+ context: ctx,
190
+ action,
191
+ resourceType,
192
+ options,
193
+ });
194
+ const findOptions = {
195
+ where: {
196
+ ...userQuery,
197
+ id: resourceId,
198
+ type: resourceType,
199
+ AppId: appId,
200
+ expires: { or: [{ gt: new Date() }, null] },
201
+ },
202
+ };
203
+ const oldResource = await getAppResource({
204
+ app,
205
+ id: resourceId,
206
+ type: resourceType,
207
+ context: ctx,
208
+ findOptions,
209
+ });
210
+ if (!oldResource) {
211
+ throw notFound('Resource not found');
212
+ }
213
+ const appAssets = await getAppAssets({ context: ctx, app });
214
+ const [processedBody, preparedAssets, deletedAssetIds] = processResourceBody(ctx, resourceDefinition, appAssets.filter((asset) => asset.resourceId === resourceId).map((asset) => asset.id), oldResource.expires);
215
+ const resources = Array.isArray(processedBody) ? processedBody : [processedBody];
216
+ ctx.body = await updateAppResource({
217
+ app,
218
+ context: ctx,
219
+ id: resourceId,
220
+ type: resourceType,
221
+ resource: resources[0],
222
+ preparedAssets,
223
+ deletedAssetIds,
224
+ resourceDefinition,
225
+ action,
226
+ options,
227
+ });
228
+ };
229
+ }
230
+ export function createDeleteResource(options) {
231
+ return async (ctx) => {
232
+ const { pathParams: { appId, resourceId, resourceType }, } = ctx;
233
+ const { deleteAppResource, getApp, getAppResource, verifyResourceActionPermission } = options;
234
+ const action = 'delete';
235
+ const app = await getApp({ context: ctx, query: { where: { id: appId } } });
236
+ const userQuery = await verifyResourceActionPermission({
237
+ app,
238
+ context: ctx,
239
+ action,
240
+ resourceType,
241
+ options,
242
+ });
243
+ const findOptions = {
244
+ where: {
245
+ ...userQuery,
246
+ id: resourceId,
247
+ type: resourceType,
248
+ AppId: appId,
249
+ expires: { or: [{ gt: new Date() }, null] },
250
+ },
251
+ };
252
+ const resource = await getAppResource({
253
+ app,
254
+ id: resourceId,
255
+ type: resourceType,
256
+ context: ctx,
257
+ findOptions,
258
+ });
259
+ if (!resource) {
260
+ throw notFound('Resource not found');
261
+ }
262
+ await deleteAppResource({
263
+ app,
264
+ context: ctx,
265
+ id: resourceId,
266
+ type: resourceType,
267
+ action,
268
+ options,
269
+ });
270
+ ctx.status = 204;
271
+ };
272
+ }
273
+ //# sourceMappingURL=resources.js.map
@@ -0,0 +1 @@
1
+ export {};