@zenstackhq/server 3.0.0-beta.19 → 3.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/dist/api.cjs +76 -70
- package/dist/api.cjs.map +1 -1
- package/dist/api.d.cts +2 -2
- package/dist/api.d.ts +2 -2
- package/dist/api.js +78 -72
- package/dist/api.js.map +1 -1
- package/package.json +7 -7
package/dist/api.cjs
CHANGED
|
@@ -42,6 +42,7 @@ var import_orm = require("@zenstackhq/orm");
|
|
|
42
42
|
var import_decimal2 = require("decimal.js");
|
|
43
43
|
var import_superjson2 = __toESM(require("superjson"), 1);
|
|
44
44
|
var import_ts_japi = __toESM(require("ts-japi"), 1);
|
|
45
|
+
var import_ts_pattern2 = require("ts-pattern");
|
|
45
46
|
var import_url_pattern = __toESM(require("url-pattern"), 1);
|
|
46
47
|
var import_zod = __toESM(require("zod"), 1);
|
|
47
48
|
|
|
@@ -327,17 +328,17 @@ var RestApiHandler = class {
|
|
|
327
328
|
if (!pattern) {
|
|
328
329
|
throw new InvalidValueError(`Unknown route type: ${routeType}`);
|
|
329
330
|
}
|
|
330
|
-
const
|
|
331
|
-
if (!
|
|
331
|
+
const match4 = pattern.match(path);
|
|
332
|
+
if (!match4) {
|
|
332
333
|
return;
|
|
333
334
|
}
|
|
334
|
-
if (
|
|
335
|
-
throw new InvalidValueError(`use the mapped model name: ${this.modelNameMapping[
|
|
335
|
+
if (match4.type in this.modelNameMapping) {
|
|
336
|
+
throw new InvalidValueError(`use the mapped model name: ${this.modelNameMapping[match4.type]} and not ${match4.type}`);
|
|
336
337
|
}
|
|
337
|
-
if (
|
|
338
|
-
|
|
338
|
+
if (match4.type in this.reverseModelNameMapping) {
|
|
339
|
+
match4.type = this.reverseModelNameMapping[match4.type];
|
|
339
340
|
}
|
|
340
|
-
return
|
|
341
|
+
return match4;
|
|
341
342
|
}
|
|
342
343
|
async handleRequest({ client, method, path, query, requestBody }) {
|
|
343
344
|
method = method.toUpperCase();
|
|
@@ -347,21 +348,21 @@ var RestApiHandler = class {
|
|
|
347
348
|
try {
|
|
348
349
|
switch (method) {
|
|
349
350
|
case "GET": {
|
|
350
|
-
let
|
|
351
|
-
if (
|
|
352
|
-
return await this.processSingleRead(client,
|
|
351
|
+
let match4 = this.matchUrlPattern(path, "single");
|
|
352
|
+
if (match4) {
|
|
353
|
+
return await this.processSingleRead(client, match4.type, match4.id, query);
|
|
353
354
|
}
|
|
354
|
-
|
|
355
|
-
if (
|
|
356
|
-
return await this.processFetchRelated(client,
|
|
355
|
+
match4 = this.matchUrlPattern(path, "fetchRelationship");
|
|
356
|
+
if (match4) {
|
|
357
|
+
return await this.processFetchRelated(client, match4.type, match4.id, match4.relationship, query);
|
|
357
358
|
}
|
|
358
|
-
|
|
359
|
-
if (
|
|
360
|
-
return await this.processReadRelationship(client,
|
|
359
|
+
match4 = this.matchUrlPattern(path, "relationship");
|
|
360
|
+
if (match4) {
|
|
361
|
+
return await this.processReadRelationship(client, match4.type, match4.id, match4.relationship, query);
|
|
361
362
|
}
|
|
362
|
-
|
|
363
|
-
if (
|
|
364
|
-
return await this.processCollectionRead(client,
|
|
363
|
+
match4 = this.matchUrlPattern(path, "collection");
|
|
364
|
+
if (match4) {
|
|
365
|
+
return await this.processCollectionRead(client, match4.type, query);
|
|
365
366
|
}
|
|
366
367
|
return this.makeError("invalidPath");
|
|
367
368
|
}
|
|
@@ -369,19 +370,19 @@ var RestApiHandler = class {
|
|
|
369
370
|
if (!requestBody) {
|
|
370
371
|
return this.makeError("invalidPayload");
|
|
371
372
|
}
|
|
372
|
-
let
|
|
373
|
-
if (
|
|
373
|
+
let match4 = this.matchUrlPattern(path, "collection");
|
|
374
|
+
if (match4) {
|
|
374
375
|
const body = requestBody;
|
|
375
376
|
const upsertMeta = this.upsertMetaSchema.safeParse(body);
|
|
376
377
|
if (upsertMeta.success) {
|
|
377
|
-
return await this.processUpsert(client,
|
|
378
|
+
return await this.processUpsert(client, match4.type, query, requestBody);
|
|
378
379
|
} else {
|
|
379
|
-
return await this.processCreate(client,
|
|
380
|
+
return await this.processCreate(client, match4.type, query, requestBody);
|
|
380
381
|
}
|
|
381
382
|
}
|
|
382
|
-
|
|
383
|
-
if (
|
|
384
|
-
return await this.processRelationshipCRUD(client, "create",
|
|
383
|
+
match4 = this.matchUrlPattern(path, "relationship");
|
|
384
|
+
if (match4) {
|
|
385
|
+
return await this.processRelationshipCRUD(client, "create", match4.type, match4.id, match4.relationship, query, requestBody);
|
|
385
386
|
}
|
|
386
387
|
return this.makeError("invalidPath");
|
|
387
388
|
}
|
|
@@ -391,24 +392,24 @@ var RestApiHandler = class {
|
|
|
391
392
|
if (!requestBody) {
|
|
392
393
|
return this.makeError("invalidPayload");
|
|
393
394
|
}
|
|
394
|
-
let
|
|
395
|
-
if (
|
|
396
|
-
return await this.processUpdate(client,
|
|
395
|
+
let match4 = this.matchUrlPattern(path, "single");
|
|
396
|
+
if (match4) {
|
|
397
|
+
return await this.processUpdate(client, match4.type, match4.id, query, requestBody);
|
|
397
398
|
}
|
|
398
|
-
|
|
399
|
-
if (
|
|
400
|
-
return await this.processRelationshipCRUD(client, "update",
|
|
399
|
+
match4 = this.matchUrlPattern(path, "relationship");
|
|
400
|
+
if (match4) {
|
|
401
|
+
return await this.processRelationshipCRUD(client, "update", match4.type, match4.id, match4.relationship, query, requestBody);
|
|
401
402
|
}
|
|
402
403
|
return this.makeError("invalidPath");
|
|
403
404
|
}
|
|
404
405
|
case "DELETE": {
|
|
405
|
-
let
|
|
406
|
-
if (
|
|
407
|
-
return await this.processDelete(client,
|
|
406
|
+
let match4 = this.matchUrlPattern(path, "single");
|
|
407
|
+
if (match4) {
|
|
408
|
+
return await this.processDelete(client, match4.type, match4.id);
|
|
408
409
|
}
|
|
409
|
-
|
|
410
|
-
if (
|
|
411
|
-
return await this.processRelationshipCRUD(client, "delete",
|
|
410
|
+
match4 = this.matchUrlPattern(path, "relationship");
|
|
411
|
+
if (match4) {
|
|
412
|
+
return await this.processRelationshipCRUD(client, "delete", match4.type, match4.id, match4.relationship, query, requestBody);
|
|
412
413
|
}
|
|
413
414
|
return this.makeError("invalidPath");
|
|
414
415
|
}
|
|
@@ -418,8 +419,8 @@ var RestApiHandler = class {
|
|
|
418
419
|
} catch (err) {
|
|
419
420
|
if (err instanceof InvalidValueError) {
|
|
420
421
|
return this.makeError("invalidValue", err.message);
|
|
421
|
-
} else if (err instanceof import_orm.
|
|
422
|
-
return this.
|
|
422
|
+
} else if (err instanceof import_orm.ORMError) {
|
|
423
|
+
return this.handleORMError(err);
|
|
423
424
|
} else {
|
|
424
425
|
return this.handleGenericError(err);
|
|
425
426
|
}
|
|
@@ -1445,11 +1446,11 @@ ${err.stack}` : "Unknown error");
|
|
|
1445
1446
|
if (!value) {
|
|
1446
1447
|
continue;
|
|
1447
1448
|
}
|
|
1448
|
-
const
|
|
1449
|
-
if (!
|
|
1449
|
+
const match4 = key.match(this.filterParamPattern);
|
|
1450
|
+
if (!match4 || !match4.groups || !match4.groups["match"]) {
|
|
1450
1451
|
continue;
|
|
1451
1452
|
}
|
|
1452
|
-
const filterKeys =
|
|
1453
|
+
const filterKeys = match4.groups["match"].replaceAll(/[[\]]/g, " ").split(" ").filter((i) => i);
|
|
1453
1454
|
if (!filterKeys.length) {
|
|
1454
1455
|
continue;
|
|
1455
1456
|
}
|
|
@@ -1772,20 +1773,24 @@ ${err.stack}` : "Unknown error");
|
|
|
1772
1773
|
};
|
|
1773
1774
|
}
|
|
1774
1775
|
}
|
|
1775
|
-
|
|
1776
|
-
|
|
1777
|
-
return this.makeError("validationError", err.message, 422
|
|
1778
|
-
}
|
|
1779
|
-
return this.makeError("forbidden", err.message, 403,
|
|
1780
|
-
|
|
1781
|
-
|
|
1782
|
-
}
|
|
1783
|
-
return this.makeError("
|
|
1784
|
-
}
|
|
1776
|
+
handleORMError(err) {
|
|
1777
|
+
return (0, import_ts_pattern2.match)(err.reason).with(import_orm.ORMErrorReason.INVALID_INPUT, () => {
|
|
1778
|
+
return this.makeError("validationError", err.message, 422);
|
|
1779
|
+
}).with(import_orm.ORMErrorReason.REJECTED_BY_POLICY, () => {
|
|
1780
|
+
return this.makeError("forbidden", err.message, 403, {
|
|
1781
|
+
reason: err.rejectedByPolicyReason
|
|
1782
|
+
});
|
|
1783
|
+
}).with(import_orm.ORMErrorReason.NOT_FOUND, () => {
|
|
1784
|
+
return this.makeError("notFound", err.message, 404);
|
|
1785
|
+
}).with(import_orm.ORMErrorReason.DB_QUERY_ERROR, () => {
|
|
1786
|
+
return this.makeError("queryError", err.message, 400, {
|
|
1787
|
+
dbErrorCode: err.dbErrorCode
|
|
1788
|
+
});
|
|
1789
|
+
}).otherwise(() => {
|
|
1785
1790
|
return this.makeError("unknownError", err.message);
|
|
1786
|
-
}
|
|
1791
|
+
});
|
|
1787
1792
|
}
|
|
1788
|
-
makeError(code, detail, status,
|
|
1793
|
+
makeError(code, detail, status, otherFields = {}) {
|
|
1789
1794
|
status = status ?? this.errors[code]?.status ?? 500;
|
|
1790
1795
|
const error = {
|
|
1791
1796
|
status,
|
|
@@ -1795,9 +1800,7 @@ ${err.stack}` : "Unknown error");
|
|
|
1795
1800
|
if (detail) {
|
|
1796
1801
|
error.detail = detail;
|
|
1797
1802
|
}
|
|
1798
|
-
|
|
1799
|
-
error.reason = reason;
|
|
1800
|
-
}
|
|
1803
|
+
Object.assign(error, otherFields);
|
|
1801
1804
|
return {
|
|
1802
1805
|
status,
|
|
1803
1806
|
body: {
|
|
@@ -1819,6 +1822,7 @@ ${err.stack}` : "Unknown error");
|
|
|
1819
1822
|
var import_common_helpers2 = require("@zenstackhq/common-helpers");
|
|
1820
1823
|
var import_orm2 = require("@zenstackhq/orm");
|
|
1821
1824
|
var import_superjson3 = __toESM(require("superjson"), 1);
|
|
1825
|
+
var import_ts_pattern3 = require("ts-pattern");
|
|
1822
1826
|
registerCustomSerializers();
|
|
1823
1827
|
var RPCApiHandler = class {
|
|
1824
1828
|
static {
|
|
@@ -1931,8 +1935,8 @@ var RPCApiHandler = class {
|
|
|
1931
1935
|
return response;
|
|
1932
1936
|
} catch (err) {
|
|
1933
1937
|
log(this.options.log, "error", `error occurred when handling "${model}.${op}" request`, err);
|
|
1934
|
-
if (err instanceof import_orm2.
|
|
1935
|
-
return this.
|
|
1938
|
+
if (err instanceof import_orm2.ORMError) {
|
|
1939
|
+
return this.makeORMErrorResponse(err);
|
|
1936
1940
|
} else {
|
|
1937
1941
|
return this.makeGenericErrorResponse(err);
|
|
1938
1942
|
}
|
|
@@ -1965,27 +1969,29 @@ var RPCApiHandler = class {
|
|
|
1965
1969
|
log(this.options.log, "debug", () => `sending error response: ${(0, import_common_helpers2.safeJSONStringify)(resp)}${err instanceof Error ? "\n" + err.stack : ""}`);
|
|
1966
1970
|
return resp;
|
|
1967
1971
|
}
|
|
1968
|
-
|
|
1972
|
+
makeORMErrorResponse(err) {
|
|
1969
1973
|
let status = 400;
|
|
1970
1974
|
const error = {
|
|
1971
|
-
message: err.message
|
|
1975
|
+
message: err.message,
|
|
1976
|
+
reason: err.reason
|
|
1972
1977
|
};
|
|
1973
|
-
|
|
1974
|
-
error.cause = err.cause.message;
|
|
1975
|
-
}
|
|
1976
|
-
if (err instanceof import_orm2.NotFoundError) {
|
|
1978
|
+
(0, import_ts_pattern3.match)(err.reason).with(import_orm2.ORMErrorReason.NOT_FOUND, () => {
|
|
1977
1979
|
status = 404;
|
|
1978
1980
|
error.model = err.model;
|
|
1979
|
-
}
|
|
1981
|
+
}).with(import_orm2.ORMErrorReason.INVALID_INPUT, () => {
|
|
1980
1982
|
status = 422;
|
|
1981
1983
|
error.rejectedByValidation = true;
|
|
1982
1984
|
error.model = err.model;
|
|
1983
|
-
}
|
|
1985
|
+
}).with(import_orm2.ORMErrorReason.REJECTED_BY_POLICY, () => {
|
|
1984
1986
|
status = 403;
|
|
1985
1987
|
error.rejectedByPolicy = true;
|
|
1986
|
-
error.rejectReason = err.
|
|
1988
|
+
error.rejectReason = err.rejectedByPolicyReason;
|
|
1987
1989
|
error.model = err.model;
|
|
1988
|
-
}
|
|
1990
|
+
}).with(import_orm2.ORMErrorReason.DB_QUERY_ERROR, () => {
|
|
1991
|
+
status = 400;
|
|
1992
|
+
error.dbErrorCode = err.dbErrorCode;
|
|
1993
|
+
}).otherwise(() => {
|
|
1994
|
+
});
|
|
1989
1995
|
const resp = {
|
|
1990
1996
|
status,
|
|
1991
1997
|
body: {
|