@nymphjs/server 1.0.0-beta.2 → 1.0.0-beta.21
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/CHANGELOG.md +84 -0
- package/README.md +77 -5
- package/dist/HttpError.d.ts +5 -0
- package/dist/HttpError.js +13 -0
- package/dist/HttpError.js.map +1 -0
- package/dist/cache.test.js +5 -5
- package/dist/cache.test.js.map +1 -1
- package/dist/createServer.d.ts +5 -0
- package/dist/createServer.js +728 -0
- package/dist/createServer.js.map +1 -0
- package/dist/index.d.ts +5 -5
- package/dist/index.js +18 -712
- package/dist/index.js.map +1 -1
- package/dist/index.test.js +67 -39
- package/dist/index.test.js.map +1 -1
- package/dist/statusDescriptions.d.ts +3 -0
- package/dist/statusDescriptions.js +69 -0
- package/dist/statusDescriptions.js.map +1 -0
- package/dist/testArtifacts.d.ts +4 -0
- package/dist/testArtifacts.js +20 -5
- package/dist/testArtifacts.js.map +1 -1
- package/package.json +12 -12
- package/src/HttpError.ts +12 -0
- package/src/cache.test.ts +6 -3
- package/src/createServer.ts +807 -0
- package/src/index.test.ts +38 -5
- package/src/index.ts +5 -793
- package/src/statusDescriptions.ts +68 -0
- package/src/testArtifacts.ts +23 -3
package/dist/index.js
CHANGED
|
@@ -1,716 +1,22 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
-
var
|
|
3
|
-
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
14
|
+
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
|
4
15
|
};
|
|
5
16
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
-
const
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
function createServer(nymph, { jsonOptions = {} } = {}) {
|
|
12
|
-
const rest = (0, express_1.default)();
|
|
13
|
-
rest.use((0, cookie_parser_1.default)());
|
|
14
|
-
rest.use(express_1.default.json(jsonOptions || {}));
|
|
15
|
-
function instantiateNymph(_request, response, next) {
|
|
16
|
-
response.locals.nymph = nymph.clone();
|
|
17
|
-
next();
|
|
18
|
-
}
|
|
19
|
-
function authenticateTilmeld(request, response, next) {
|
|
20
|
-
if (response.locals.nymph.tilmeld) {
|
|
21
|
-
response.locals.nymph.tilmeld.request = request;
|
|
22
|
-
response.locals.nymph.tilmeld.response = response;
|
|
23
|
-
try {
|
|
24
|
-
response.locals.nymph.tilmeld.authenticate();
|
|
25
|
-
}
|
|
26
|
-
catch (e) {
|
|
27
|
-
httpError(response, 500, 'Internal Server Error', e);
|
|
28
|
-
return;
|
|
29
|
-
}
|
|
30
|
-
}
|
|
31
|
-
next();
|
|
32
|
-
}
|
|
33
|
-
function unauthenticateTilmeld(_request, response, next) {
|
|
34
|
-
if (response.locals.nymph.tilmeld) {
|
|
35
|
-
response.locals.nymph.tilmeld.request = null;
|
|
36
|
-
response.locals.nymph.tilmeld.response = null;
|
|
37
|
-
try {
|
|
38
|
-
response.locals.nymph.tilmeld.clearSession();
|
|
39
|
-
}
|
|
40
|
-
catch (e) {
|
|
41
|
-
httpError(response, 500, 'Internal Server Error', e);
|
|
42
|
-
return;
|
|
43
|
-
}
|
|
44
|
-
}
|
|
45
|
-
next();
|
|
46
|
-
}
|
|
47
|
-
function getActionData(request) {
|
|
48
|
-
if (request.method === 'GET') {
|
|
49
|
-
if (typeof request.query?.action !== 'string' ||
|
|
50
|
-
typeof request.query?.data !== 'string') {
|
|
51
|
-
return {
|
|
52
|
-
action: '',
|
|
53
|
-
data: {},
|
|
54
|
-
};
|
|
55
|
-
}
|
|
56
|
-
return {
|
|
57
|
-
action: JSON.parse(request.query.action) ?? '',
|
|
58
|
-
data: JSON.parse(request.query.data),
|
|
59
|
-
};
|
|
60
|
-
}
|
|
61
|
-
else {
|
|
62
|
-
return {
|
|
63
|
-
action: request.body.action ?? '',
|
|
64
|
-
data: request.body.data,
|
|
65
|
-
};
|
|
66
|
-
}
|
|
67
|
-
}
|
|
68
|
-
rest.use(instantiateNymph);
|
|
69
|
-
rest.use(authenticateTilmeld);
|
|
70
|
-
rest.get('/', async (request, response) => {
|
|
71
|
-
try {
|
|
72
|
-
const { action, data } = getActionData(request);
|
|
73
|
-
if (['entity', 'entities', 'uid'].indexOf(action) === -1) {
|
|
74
|
-
httpError(response, 400, 'Bad Request');
|
|
75
|
-
return;
|
|
76
|
-
}
|
|
77
|
-
if (['entity', 'entities'].indexOf(action) !== -1) {
|
|
78
|
-
if (!Array.isArray(data)) {
|
|
79
|
-
httpError(response, 400, 'Bad Request');
|
|
80
|
-
return;
|
|
81
|
-
}
|
|
82
|
-
const count = data.length;
|
|
83
|
-
if (count < 1 || typeof data[0] !== 'object') {
|
|
84
|
-
httpError(response, 400, 'Bad Request');
|
|
85
|
-
return;
|
|
86
|
-
}
|
|
87
|
-
if (!('class' in data[0])) {
|
|
88
|
-
httpError(response, 400, 'Bad Request');
|
|
89
|
-
return;
|
|
90
|
-
}
|
|
91
|
-
let [options, ...selectors] = data;
|
|
92
|
-
let EntityClass;
|
|
93
|
-
try {
|
|
94
|
-
EntityClass = response.locals.nymph.getEntityClass(data[0].class);
|
|
95
|
-
}
|
|
96
|
-
catch (e) {
|
|
97
|
-
httpError(response, 400, 'Bad Request', e);
|
|
98
|
-
return;
|
|
99
|
-
}
|
|
100
|
-
options.class = EntityClass;
|
|
101
|
-
options.source = 'client';
|
|
102
|
-
options.skipAc = false;
|
|
103
|
-
selectors = (0, nymph_1.classNamesToEntityConstructors)(response.locals.nymph, selectors);
|
|
104
|
-
let result;
|
|
105
|
-
try {
|
|
106
|
-
if (action === 'entity') {
|
|
107
|
-
result = await response.locals.nymph.getEntity(options, ...selectors);
|
|
108
|
-
}
|
|
109
|
-
else {
|
|
110
|
-
result = await response.locals.nymph.getEntities(options, ...selectors);
|
|
111
|
-
}
|
|
112
|
-
}
|
|
113
|
-
catch (e) {
|
|
114
|
-
httpError(response, 500, 'Internal Server Error', e);
|
|
115
|
-
return;
|
|
116
|
-
}
|
|
117
|
-
if (result == null || (Array.isArray(result) && result.length === 0)) {
|
|
118
|
-
if (action === 'entity' ||
|
|
119
|
-
response.locals.nymph.config.emptyListError) {
|
|
120
|
-
httpError(response, 404, 'Not Found');
|
|
121
|
-
return;
|
|
122
|
-
}
|
|
123
|
-
}
|
|
124
|
-
response.setHeader('Content-Type', 'application/json');
|
|
125
|
-
response.send(JSON.stringify(result));
|
|
126
|
-
}
|
|
127
|
-
else {
|
|
128
|
-
if (typeof data !== 'string') {
|
|
129
|
-
httpError(response, 400, 'Bad Request');
|
|
130
|
-
return;
|
|
131
|
-
}
|
|
132
|
-
if (response.locals.nymph.tilmeld) {
|
|
133
|
-
if (!response.locals.nymph.tilmeld.checkClientUIDPermissions(data, nymph_1.TilmeldAccessLevels.READ_ACCESS)) {
|
|
134
|
-
httpError(response, 403, 'Forbidden');
|
|
135
|
-
return;
|
|
136
|
-
}
|
|
137
|
-
}
|
|
138
|
-
let result;
|
|
139
|
-
try {
|
|
140
|
-
result = await response.locals.nymph.getUID(data);
|
|
141
|
-
}
|
|
142
|
-
catch (e) {
|
|
143
|
-
httpError(response, 500, 'Internal Server Error', e);
|
|
144
|
-
return;
|
|
145
|
-
}
|
|
146
|
-
if (result === null) {
|
|
147
|
-
httpError(response, 404, 'Not Found');
|
|
148
|
-
return;
|
|
149
|
-
}
|
|
150
|
-
else if (typeof result !== 'number') {
|
|
151
|
-
httpError(response, 500, 'Internal Server Error');
|
|
152
|
-
return;
|
|
153
|
-
}
|
|
154
|
-
response.setHeader('Content-Type', 'text/plain');
|
|
155
|
-
response.send(`${result}`);
|
|
156
|
-
}
|
|
157
|
-
}
|
|
158
|
-
catch (e) {
|
|
159
|
-
httpError(response, 500, 'Internal Server Error', e);
|
|
160
|
-
return;
|
|
161
|
-
}
|
|
162
|
-
});
|
|
163
|
-
rest.post('/', async (request, response) => {
|
|
164
|
-
try {
|
|
165
|
-
const { action, data: dataConst } = getActionData(request);
|
|
166
|
-
let data = dataConst;
|
|
167
|
-
if (['entity', 'entities', 'uid', 'method'].indexOf(action) === -1) {
|
|
168
|
-
httpError(response, 400, 'Bad Request');
|
|
169
|
-
return;
|
|
170
|
-
}
|
|
171
|
-
if (['entity', 'entities'].indexOf(action) !== -1) {
|
|
172
|
-
if (action === 'entity') {
|
|
173
|
-
data = [data];
|
|
174
|
-
}
|
|
175
|
-
const created = [];
|
|
176
|
-
let hadSuccess = false;
|
|
177
|
-
let invalidRequest = false;
|
|
178
|
-
let conflict = false;
|
|
179
|
-
let notfound = false;
|
|
180
|
-
let lastException = null;
|
|
181
|
-
for (let entData of data) {
|
|
182
|
-
if (entData.guid) {
|
|
183
|
-
invalidRequest = true;
|
|
184
|
-
created.push(null);
|
|
185
|
-
continue;
|
|
186
|
-
}
|
|
187
|
-
let entity;
|
|
188
|
-
try {
|
|
189
|
-
entity = await loadEntity(entData, response.locals.nymph);
|
|
190
|
-
}
|
|
191
|
-
catch (e) {
|
|
192
|
-
if (e instanceof nymph_1.EntityConflictError) {
|
|
193
|
-
conflict = true;
|
|
194
|
-
}
|
|
195
|
-
else if (e.message === NOT_FOUND_ERROR) {
|
|
196
|
-
notfound = true;
|
|
197
|
-
}
|
|
198
|
-
else if (e instanceof nymph_1.InvalidParametersError) {
|
|
199
|
-
invalidRequest = true;
|
|
200
|
-
lastException = e;
|
|
201
|
-
}
|
|
202
|
-
else {
|
|
203
|
-
lastException = e;
|
|
204
|
-
}
|
|
205
|
-
created.push(null);
|
|
206
|
-
continue;
|
|
207
|
-
}
|
|
208
|
-
if (!entity) {
|
|
209
|
-
invalidRequest = true;
|
|
210
|
-
created.push(null);
|
|
211
|
-
continue;
|
|
212
|
-
}
|
|
213
|
-
try {
|
|
214
|
-
if (await entity.$save()) {
|
|
215
|
-
created.push(entity);
|
|
216
|
-
hadSuccess = true;
|
|
217
|
-
}
|
|
218
|
-
else {
|
|
219
|
-
created.push(false);
|
|
220
|
-
}
|
|
221
|
-
}
|
|
222
|
-
catch (e) {
|
|
223
|
-
if (e instanceof nymph_2.EntityInvalidDataError) {
|
|
224
|
-
invalidRequest = true;
|
|
225
|
-
}
|
|
226
|
-
else {
|
|
227
|
-
lastException = e;
|
|
228
|
-
}
|
|
229
|
-
created.push(null);
|
|
230
|
-
}
|
|
231
|
-
}
|
|
232
|
-
if (!hadSuccess) {
|
|
233
|
-
if (invalidRequest) {
|
|
234
|
-
httpError(response, 400, 'Bad Request', lastException);
|
|
235
|
-
return;
|
|
236
|
-
}
|
|
237
|
-
else if (conflict) {
|
|
238
|
-
httpError(response, 409, 'Conflict');
|
|
239
|
-
return;
|
|
240
|
-
}
|
|
241
|
-
else if (notfound) {
|
|
242
|
-
httpError(response, 404, 'Not Found');
|
|
243
|
-
return;
|
|
244
|
-
}
|
|
245
|
-
else {
|
|
246
|
-
httpError(response, 500, 'Internal Server Error', lastException);
|
|
247
|
-
return;
|
|
248
|
-
}
|
|
249
|
-
}
|
|
250
|
-
response.status(201);
|
|
251
|
-
response.setHeader('Content-Type', 'application/json');
|
|
252
|
-
if (action === 'entity') {
|
|
253
|
-
response.send(JSON.stringify(created[0]));
|
|
254
|
-
}
|
|
255
|
-
else {
|
|
256
|
-
response.send(created);
|
|
257
|
-
}
|
|
258
|
-
}
|
|
259
|
-
else if (action === 'method') {
|
|
260
|
-
if (!Array.isArray(data.params)) {
|
|
261
|
-
httpError(response, 400, 'Bad Request');
|
|
262
|
-
return;
|
|
263
|
-
}
|
|
264
|
-
const params = referencesToEntities([...data.params], response.locals.nymph);
|
|
265
|
-
if (data.static) {
|
|
266
|
-
let EntityClass;
|
|
267
|
-
try {
|
|
268
|
-
EntityClass = response.locals.nymph.getEntityClass(data.class);
|
|
269
|
-
}
|
|
270
|
-
catch (e) {
|
|
271
|
-
httpError(response, 400, 'Bad Request');
|
|
272
|
-
return;
|
|
273
|
-
}
|
|
274
|
-
if (EntityClass.clientEnabledStaticMethods.indexOf(data.method) === -1) {
|
|
275
|
-
httpError(response, 403, 'Forbidden');
|
|
276
|
-
return;
|
|
277
|
-
}
|
|
278
|
-
if (!(data.method in EntityClass)) {
|
|
279
|
-
httpError(response, 400, 'Bad Request');
|
|
280
|
-
return;
|
|
281
|
-
}
|
|
282
|
-
const method = EntityClass[data.method];
|
|
283
|
-
if (typeof method !== 'function') {
|
|
284
|
-
httpError(response, 400, 'Bad Request');
|
|
285
|
-
return;
|
|
286
|
-
}
|
|
287
|
-
try {
|
|
288
|
-
const result = method.call(EntityClass, ...params);
|
|
289
|
-
let ret = result;
|
|
290
|
-
if (result instanceof Promise) {
|
|
291
|
-
ret = await result;
|
|
292
|
-
}
|
|
293
|
-
response.status(200);
|
|
294
|
-
response.setHeader('Content-Type', 'application/json');
|
|
295
|
-
response.send({ return: ret });
|
|
296
|
-
}
|
|
297
|
-
catch (e) {
|
|
298
|
-
httpError(response, 500, 'Internal Server Error', e);
|
|
299
|
-
return;
|
|
300
|
-
}
|
|
301
|
-
}
|
|
302
|
-
else {
|
|
303
|
-
let entity;
|
|
304
|
-
try {
|
|
305
|
-
entity = await loadEntity(data.entity, response.locals.nymph);
|
|
306
|
-
}
|
|
307
|
-
catch (e) {
|
|
308
|
-
if (e instanceof nymph_1.EntityConflictError) {
|
|
309
|
-
httpError(response, 409, 'Conflict');
|
|
310
|
-
}
|
|
311
|
-
else if (e.message === NOT_FOUND_ERROR) {
|
|
312
|
-
httpError(response, 404, 'Not Found', e);
|
|
313
|
-
}
|
|
314
|
-
else if (e instanceof nymph_1.InvalidParametersError) {
|
|
315
|
-
httpError(response, 400, 'Bad Request', e);
|
|
316
|
-
}
|
|
317
|
-
else {
|
|
318
|
-
httpError(response, 500, 'Internal Server Error', e);
|
|
319
|
-
}
|
|
320
|
-
return;
|
|
321
|
-
}
|
|
322
|
-
if (data.entity.guid && !entity.guid) {
|
|
323
|
-
httpError(response, 400, 'Bad Request');
|
|
324
|
-
return;
|
|
325
|
-
}
|
|
326
|
-
if (entity.$getClientEnabledMethods().indexOf(data.method) === -1) {
|
|
327
|
-
httpError(response, 403, 'Forbidden');
|
|
328
|
-
return;
|
|
329
|
-
}
|
|
330
|
-
if (!(data.method in entity) ||
|
|
331
|
-
typeof entity[data.method] !== 'function') {
|
|
332
|
-
httpError(response, 400, 'Bad Request');
|
|
333
|
-
return;
|
|
334
|
-
}
|
|
335
|
-
try {
|
|
336
|
-
const result = entity[data.method](...params);
|
|
337
|
-
let ret = result;
|
|
338
|
-
if (result instanceof Promise) {
|
|
339
|
-
ret = await result;
|
|
340
|
-
}
|
|
341
|
-
response.status(200);
|
|
342
|
-
response.setHeader('Content-Type', 'application/json');
|
|
343
|
-
if (data.stateless) {
|
|
344
|
-
response.send({ return: ret });
|
|
345
|
-
}
|
|
346
|
-
else {
|
|
347
|
-
response.send({ entity: entity, return: ret });
|
|
348
|
-
}
|
|
349
|
-
}
|
|
350
|
-
catch (e) {
|
|
351
|
-
httpError(response, 500, 'Internal Server Error', e);
|
|
352
|
-
return;
|
|
353
|
-
}
|
|
354
|
-
}
|
|
355
|
-
}
|
|
356
|
-
else {
|
|
357
|
-
if (typeof data !== 'string') {
|
|
358
|
-
httpError(response, 400, 'Bad Request');
|
|
359
|
-
return;
|
|
360
|
-
}
|
|
361
|
-
if (response.locals.nymph.tilmeld) {
|
|
362
|
-
if (!response.locals.nymph.tilmeld.checkClientUIDPermissions(data, nymph_1.TilmeldAccessLevels.WRITE_ACCESS)) {
|
|
363
|
-
httpError(response, 403, 'Forbidden');
|
|
364
|
-
return;
|
|
365
|
-
}
|
|
366
|
-
}
|
|
367
|
-
let result;
|
|
368
|
-
try {
|
|
369
|
-
result = await response.locals.nymph.newUID(data);
|
|
370
|
-
}
|
|
371
|
-
catch (e) {
|
|
372
|
-
httpError(response, 500, 'Internal Server Error', e);
|
|
373
|
-
return;
|
|
374
|
-
}
|
|
375
|
-
if (typeof result !== 'number') {
|
|
376
|
-
httpError(response, 500, 'Internal Server Error');
|
|
377
|
-
return;
|
|
378
|
-
}
|
|
379
|
-
response.status(201);
|
|
380
|
-
response.setHeader('Content-Type', 'text/plain');
|
|
381
|
-
response.send(`${result}`);
|
|
382
|
-
}
|
|
383
|
-
}
|
|
384
|
-
catch (e) {
|
|
385
|
-
httpError(response, 500, 'Internal Server Error', e);
|
|
386
|
-
return;
|
|
387
|
-
}
|
|
388
|
-
});
|
|
389
|
-
rest.put('/', async (request, response) => {
|
|
390
|
-
try {
|
|
391
|
-
const { action, data } = getActionData(request);
|
|
392
|
-
if (['entity', 'entities', 'uid'].indexOf(action) === -1) {
|
|
393
|
-
httpError(response, 400, 'Bad Request');
|
|
394
|
-
return;
|
|
395
|
-
}
|
|
396
|
-
await doPutOrPatch(response, action, data, false);
|
|
397
|
-
}
|
|
398
|
-
catch (e) {
|
|
399
|
-
httpError(response, 500, 'Internal Server Error', e);
|
|
400
|
-
return;
|
|
401
|
-
}
|
|
402
|
-
});
|
|
403
|
-
rest.patch('/', async (request, response) => {
|
|
404
|
-
try {
|
|
405
|
-
const { action, data } = getActionData(request);
|
|
406
|
-
if (['entity', 'entities'].indexOf(action) === -1) {
|
|
407
|
-
httpError(response, 400, 'Bad Request');
|
|
408
|
-
return;
|
|
409
|
-
}
|
|
410
|
-
await doPutOrPatch(response, action, data, true);
|
|
411
|
-
}
|
|
412
|
-
catch (e) {
|
|
413
|
-
httpError(response, 500, 'Internal Server Error', e);
|
|
414
|
-
return;
|
|
415
|
-
}
|
|
416
|
-
});
|
|
417
|
-
async function doPutOrPatch(response, action, data, patch) {
|
|
418
|
-
if (action === 'uid') {
|
|
419
|
-
if (typeof data.name !== 'string' || typeof data.value !== 'number') {
|
|
420
|
-
httpError(response, 400, 'Bad Request');
|
|
421
|
-
return;
|
|
422
|
-
}
|
|
423
|
-
if (response.locals.nymph.tilmeld) {
|
|
424
|
-
if (!response.locals.nymph.tilmeld.checkClientUIDPermissions(data.name, nymph_1.TilmeldAccessLevels.FULL_ACCESS)) {
|
|
425
|
-
httpError(response, 403, 'Forbidden');
|
|
426
|
-
return;
|
|
427
|
-
}
|
|
428
|
-
}
|
|
429
|
-
let result;
|
|
430
|
-
try {
|
|
431
|
-
result = await response.locals.nymph.setUID(data.name, data.value);
|
|
432
|
-
}
|
|
433
|
-
catch (e) {
|
|
434
|
-
httpError(response, 500, 'Internal Server Error', e);
|
|
435
|
-
return;
|
|
436
|
-
}
|
|
437
|
-
if (!result) {
|
|
438
|
-
httpError(response, 500, 'Internal Server Error');
|
|
439
|
-
return;
|
|
440
|
-
}
|
|
441
|
-
response.status(200);
|
|
442
|
-
response.setHeader('Content-Type', 'text/plain');
|
|
443
|
-
response.send(`${result}`);
|
|
444
|
-
}
|
|
445
|
-
else {
|
|
446
|
-
if (action === 'entity') {
|
|
447
|
-
data = [data];
|
|
448
|
-
}
|
|
449
|
-
const saved = [];
|
|
450
|
-
let hadSuccess = false;
|
|
451
|
-
let invalidRequest = false;
|
|
452
|
-
let conflict = false;
|
|
453
|
-
let notfound = false;
|
|
454
|
-
let lastException = null;
|
|
455
|
-
for (let entData of data) {
|
|
456
|
-
if (entData.guid && entData.guid.length != 24) {
|
|
457
|
-
invalidRequest = true;
|
|
458
|
-
saved.push(null);
|
|
459
|
-
continue;
|
|
460
|
-
}
|
|
461
|
-
let entity;
|
|
462
|
-
try {
|
|
463
|
-
entity = await loadEntity(entData, response.locals.nymph, patch);
|
|
464
|
-
}
|
|
465
|
-
catch (e) {
|
|
466
|
-
if (e instanceof nymph_1.EntityConflictError) {
|
|
467
|
-
conflict = true;
|
|
468
|
-
}
|
|
469
|
-
else if (e.message === NOT_FOUND_ERROR) {
|
|
470
|
-
notfound = true;
|
|
471
|
-
}
|
|
472
|
-
else if (e instanceof nymph_1.InvalidParametersError) {
|
|
473
|
-
invalidRequest = true;
|
|
474
|
-
lastException = e;
|
|
475
|
-
}
|
|
476
|
-
else {
|
|
477
|
-
lastException = e;
|
|
478
|
-
}
|
|
479
|
-
saved.push(null);
|
|
480
|
-
continue;
|
|
481
|
-
}
|
|
482
|
-
if (!entity) {
|
|
483
|
-
invalidRequest = true;
|
|
484
|
-
saved.push(null);
|
|
485
|
-
continue;
|
|
486
|
-
}
|
|
487
|
-
try {
|
|
488
|
-
if (await entity.$save()) {
|
|
489
|
-
saved.push(entity);
|
|
490
|
-
hadSuccess = true;
|
|
491
|
-
}
|
|
492
|
-
else {
|
|
493
|
-
saved.push(false);
|
|
494
|
-
}
|
|
495
|
-
}
|
|
496
|
-
catch (e) {
|
|
497
|
-
if (e instanceof nymph_2.EntityInvalidDataError) {
|
|
498
|
-
invalidRequest = true;
|
|
499
|
-
}
|
|
500
|
-
else {
|
|
501
|
-
lastException = e;
|
|
502
|
-
}
|
|
503
|
-
saved.push(null);
|
|
504
|
-
}
|
|
505
|
-
}
|
|
506
|
-
if (!hadSuccess) {
|
|
507
|
-
if (invalidRequest) {
|
|
508
|
-
httpError(response, 400, 'Bad Request', lastException);
|
|
509
|
-
}
|
|
510
|
-
else if (conflict) {
|
|
511
|
-
httpError(response, 409, 'Conflict');
|
|
512
|
-
}
|
|
513
|
-
else if (notfound) {
|
|
514
|
-
httpError(response, 404, 'Not Found');
|
|
515
|
-
}
|
|
516
|
-
else {
|
|
517
|
-
httpError(response, 500, 'Internal Server Error', lastException);
|
|
518
|
-
}
|
|
519
|
-
return;
|
|
520
|
-
}
|
|
521
|
-
response.status(200);
|
|
522
|
-
response.setHeader('Content-Type', 'application/json');
|
|
523
|
-
if (action === 'entity') {
|
|
524
|
-
response.send(JSON.stringify(saved[0]));
|
|
525
|
-
}
|
|
526
|
-
else {
|
|
527
|
-
response.send(saved);
|
|
528
|
-
}
|
|
529
|
-
}
|
|
530
|
-
}
|
|
531
|
-
rest.delete('/', async (request, response) => {
|
|
532
|
-
try {
|
|
533
|
-
const { action, data: dataConst } = getActionData(request);
|
|
534
|
-
let data = dataConst;
|
|
535
|
-
if (['entity', 'entities', 'uid'].indexOf(action) === -1) {
|
|
536
|
-
httpError(response, 400, 'Bad Request');
|
|
537
|
-
return;
|
|
538
|
-
}
|
|
539
|
-
if (['entity', 'entities'].indexOf(action) !== -1) {
|
|
540
|
-
if (action === 'entity') {
|
|
541
|
-
data = [data];
|
|
542
|
-
}
|
|
543
|
-
const deleted = [];
|
|
544
|
-
let failures = false;
|
|
545
|
-
let hadSuccess = false;
|
|
546
|
-
let invalidRequest = false;
|
|
547
|
-
let notfound = false;
|
|
548
|
-
let lastException = null;
|
|
549
|
-
for (let entData of data) {
|
|
550
|
-
if (entData.guid && entData.guid.length != 24) {
|
|
551
|
-
invalidRequest = true;
|
|
552
|
-
continue;
|
|
553
|
-
}
|
|
554
|
-
let EntityClass;
|
|
555
|
-
try {
|
|
556
|
-
EntityClass = response.locals.nymph.getEntityClass(entData.class);
|
|
557
|
-
}
|
|
558
|
-
catch (e) {
|
|
559
|
-
invalidRequest = true;
|
|
560
|
-
failures = true;
|
|
561
|
-
continue;
|
|
562
|
-
}
|
|
563
|
-
let entity;
|
|
564
|
-
try {
|
|
565
|
-
entity = await response.locals.nymph.getEntity({ class: EntityClass }, { type: '&', guid: entData.guid });
|
|
566
|
-
}
|
|
567
|
-
catch (e) {
|
|
568
|
-
lastException = e;
|
|
569
|
-
failures = true;
|
|
570
|
-
continue;
|
|
571
|
-
}
|
|
572
|
-
if (!entity) {
|
|
573
|
-
notfound = true;
|
|
574
|
-
failures = true;
|
|
575
|
-
continue;
|
|
576
|
-
}
|
|
577
|
-
try {
|
|
578
|
-
if (await entity.$delete()) {
|
|
579
|
-
deleted.push(entData.guid);
|
|
580
|
-
hadSuccess = true;
|
|
581
|
-
}
|
|
582
|
-
else {
|
|
583
|
-
failures = true;
|
|
584
|
-
}
|
|
585
|
-
}
|
|
586
|
-
catch (e) {
|
|
587
|
-
lastException = e;
|
|
588
|
-
failures = true;
|
|
589
|
-
}
|
|
590
|
-
}
|
|
591
|
-
if (deleted.length === 0) {
|
|
592
|
-
if (invalidRequest || !failures) {
|
|
593
|
-
httpError(response, 400, 'Bad Request', lastException);
|
|
594
|
-
}
|
|
595
|
-
else if (notfound) {
|
|
596
|
-
httpError(response, 404, 'Not Found');
|
|
597
|
-
}
|
|
598
|
-
else {
|
|
599
|
-
httpError(response, 500, 'Internal Server Error', lastException);
|
|
600
|
-
}
|
|
601
|
-
return;
|
|
602
|
-
}
|
|
603
|
-
response.status(200);
|
|
604
|
-
response.setHeader('Content-Type', 'application/json');
|
|
605
|
-
if (action === 'entity') {
|
|
606
|
-
response.send(JSON.stringify(deleted[0]));
|
|
607
|
-
}
|
|
608
|
-
else {
|
|
609
|
-
response.send(deleted);
|
|
610
|
-
}
|
|
611
|
-
}
|
|
612
|
-
else {
|
|
613
|
-
if (typeof data !== 'string') {
|
|
614
|
-
httpError(response, 400, 'Bad Request');
|
|
615
|
-
return;
|
|
616
|
-
}
|
|
617
|
-
if (response.locals.nymph.tilmeld) {
|
|
618
|
-
if (!response.locals.nymph.tilmeld.checkClientUIDPermissions(data, nymph_1.TilmeldAccessLevels.FULL_ACCESS)) {
|
|
619
|
-
httpError(response, 403, 'Forbidden');
|
|
620
|
-
return;
|
|
621
|
-
}
|
|
622
|
-
}
|
|
623
|
-
let result;
|
|
624
|
-
try {
|
|
625
|
-
result = await response.locals.nymph.deleteUID(data);
|
|
626
|
-
}
|
|
627
|
-
catch (e) {
|
|
628
|
-
httpError(response, 500, 'Internal Server Error', e);
|
|
629
|
-
return;
|
|
630
|
-
}
|
|
631
|
-
if (!result) {
|
|
632
|
-
httpError(response, 500, 'Internal Server Error');
|
|
633
|
-
return;
|
|
634
|
-
}
|
|
635
|
-
response.status(200);
|
|
636
|
-
response.setHeader('Content-Type', 'application/json');
|
|
637
|
-
response.send(JSON.stringify(result));
|
|
638
|
-
}
|
|
639
|
-
}
|
|
640
|
-
catch (e) {
|
|
641
|
-
httpError(response, 500, 'Internal Server Error', e);
|
|
642
|
-
return;
|
|
643
|
-
}
|
|
644
|
-
});
|
|
645
|
-
rest.use(unauthenticateTilmeld);
|
|
646
|
-
async function loadEntity(entityData, nymph, patch = false, allowConflict = false) {
|
|
647
|
-
if (entityData.class === 'Entity') {
|
|
648
|
-
throw new nymph_1.InvalidParametersError("Can't use Entity class directly from the front end.");
|
|
649
|
-
}
|
|
650
|
-
let EntityClass = nymph.getEntityClass(entityData.class);
|
|
651
|
-
let entity;
|
|
652
|
-
if (entityData.guid) {
|
|
653
|
-
entity = await nymph.getEntity({ class: EntityClass, source: 'client' }, {
|
|
654
|
-
type: '&',
|
|
655
|
-
guid: `${entityData['guid']}`,
|
|
656
|
-
});
|
|
657
|
-
if (entity === null) {
|
|
658
|
-
throw new Error(NOT_FOUND_ERROR);
|
|
659
|
-
}
|
|
660
|
-
}
|
|
661
|
-
else {
|
|
662
|
-
entity = await EntityClass.factory();
|
|
663
|
-
}
|
|
664
|
-
if (patch) {
|
|
665
|
-
entity.$jsonAcceptPatch(entityData, allowConflict);
|
|
666
|
-
}
|
|
667
|
-
else {
|
|
668
|
-
entity.$jsonAcceptData(entityData, allowConflict);
|
|
669
|
-
}
|
|
670
|
-
return entity;
|
|
671
|
-
}
|
|
672
|
-
function referencesToEntities(item, nymph) {
|
|
673
|
-
if (Array.isArray(item)) {
|
|
674
|
-
if (item.length === 3 && item[0] === 'nymph_entity_reference') {
|
|
675
|
-
try {
|
|
676
|
-
const EntityClass = nymph.getEntityClass(item[1]);
|
|
677
|
-
return EntityClass.factoryReference(item);
|
|
678
|
-
}
|
|
679
|
-
catch (e) {
|
|
680
|
-
return item;
|
|
681
|
-
}
|
|
682
|
-
}
|
|
683
|
-
return item.map((entry) => referencesToEntities(entry, nymph));
|
|
684
|
-
}
|
|
685
|
-
else if (typeof item === 'object' && !(item instanceof nymph_1.Entity)) {
|
|
686
|
-
const newItem = {};
|
|
687
|
-
for (let curProperty in item) {
|
|
688
|
-
newItem[curProperty] = referencesToEntities(item[curProperty], nymph);
|
|
689
|
-
}
|
|
690
|
-
return newItem;
|
|
691
|
-
}
|
|
692
|
-
return item;
|
|
693
|
-
}
|
|
694
|
-
function httpError(res, errorCode, message, error) {
|
|
695
|
-
if (!res.headersSent) {
|
|
696
|
-
res.status(errorCode);
|
|
697
|
-
res.setHeader('Content-Type', 'application/json');
|
|
698
|
-
}
|
|
699
|
-
if (error) {
|
|
700
|
-
res.send({
|
|
701
|
-
textStatus: `${errorCode} ${message}`,
|
|
702
|
-
message: error.message,
|
|
703
|
-
error,
|
|
704
|
-
...(process.env.NODE_ENV !== 'production'
|
|
705
|
-
? { stack: error.stack }
|
|
706
|
-
: {}),
|
|
707
|
-
});
|
|
708
|
-
}
|
|
709
|
-
else {
|
|
710
|
-
res.send({ textStatus: `${errorCode} ${message}` });
|
|
711
|
-
}
|
|
712
|
-
}
|
|
713
|
-
return rest;
|
|
714
|
-
}
|
|
715
|
-
exports.default = createServer;
|
|
17
|
+
const createServer_1 = require("./createServer");
|
|
18
|
+
__exportStar(require("./HttpError"), exports);
|
|
19
|
+
__exportStar(require("./statusDescriptions"), exports);
|
|
20
|
+
__exportStar(require("./createServer"), exports);
|
|
21
|
+
exports.default = createServer_1.createServer;
|
|
716
22
|
//# sourceMappingURL=index.js.map
|