@aeriajs/core 0.0.87 → 0.0.89
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/assets.d.ts +3 -3
- package/dist/assets.js +4 -11
- package/dist/assets.mjs +6 -13
- package/dist/collection/define.d.ts +2 -3
- package/dist/collection/fill.d.ts +2 -0
- package/dist/collection/fill.js +14 -0
- package/dist/collection/fill.mjs +11 -0
- package/dist/collection/index.d.ts +3 -1
- package/dist/collection/index.js +3 -1
- package/dist/collection/index.mjs +3 -1
- package/dist/collection/normalizeProjection.d.ts +2 -0
- package/dist/collection/normalizeProjection.js +22 -0
- package/dist/collection/normalizeProjection.mjs +17 -0
- package/dist/collection/pagination.js +1 -1
- package/dist/collection/pagination.mjs +1 -1
- package/dist/collection/prepareInsert.d.ts +2 -0
- package/dist/collection/prepareInsert.js +46 -0
- package/dist/collection/prepareInsert.mjs +41 -0
- package/dist/collection/traverseDocument.d.ts +4 -3
- package/dist/collection/traverseDocument.js +15 -14
- package/dist/collection/traverseDocument.mjs +13 -12
- package/dist/context.d.ts +1 -1
- package/dist/context.js +1 -1
- package/dist/context.mjs +1 -1
- package/dist/functions/builtin/get.d.ts +2 -2
- package/dist/functions/builtin/get.js +4 -1
- package/dist/functions/builtin/get.mjs +4 -1
- package/dist/functions/builtin/insert.d.ts +27 -2
- package/dist/functions/builtin/insert.js +51 -18
- package/dist/functions/builtin/insert.mjs +50 -18
- package/dist/functions/builtin/remove.js +5 -4
- package/dist/functions/builtin/remove.mjs +6 -5
- package/dist/use.d.ts +1 -1
- package/package.json +8 -8
- package/dist/collection/utils.d.ts +0 -4
- package/dist/collection/utils.js +0 -89
- package/dist/collection/utils.mjs +0 -76
package/dist/assets.d.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import type { Context, Collection, Token } from '@aeriajs/types';
|
|
2
2
|
import { ACError } from '@aeriajs/types';
|
|
3
|
-
export declare const internalGetCollectionAsset: <TCollectionName extends string, TAssetName extends "item" | "description" | "security" | "functions" | "contracts" | "exposedFunctions">(collectionName: TCollectionName, assetName: TAssetName) => Promise<import("@aeriajs/types").Left<ACError.ResourceNotFound> | import("@aeriajs/types").
|
|
4
|
-
export declare const getCollectionAsset: <TCollectionName extends string, TAssetName extends "item" | "description" | "security" | "functions" | "contracts" | "exposedFunctions">(collectionName: TCollectionName, assetName: TAssetName) => Promise<import("@aeriajs/types").Left<ACError.ResourceNotFound> | import("@aeriajs/types").
|
|
3
|
+
export declare const internalGetCollectionAsset: <TCollectionName extends string, TAssetName extends "item" | "description" | "security" | "functions" | "contracts" | "exposedFunctions">(collectionName: TCollectionName, assetName: TAssetName) => Promise<import("@aeriajs/types").Left<ACError.ResourceNotFound> | import("@aeriajs/types").Right<any>>;
|
|
4
|
+
export declare const getCollectionAsset: <TCollectionName extends string, TAssetName extends "item" | "description" | "security" | "functions" | "contracts" | "exposedFunctions">(collectionName: TCollectionName, assetName: TAssetName) => Promise<import("@aeriajs/types").Left<ACError.ResourceNotFound> | import("@aeriajs/types").Right<NonNullable<Collection[TAssetName]>>>;
|
|
5
5
|
export declare const getFunction: <TCollectionName extends string, TFunctionName extends string>(collectionName: TCollectionName, functionName: TFunctionName, token?: Token, options?: {
|
|
6
6
|
exposedOnly: boolean;
|
|
7
|
-
}) => Promise<import("@aeriajs/types").Left<ACError.ResourceNotFound> | import("@aeriajs/types").Left<ACError.
|
|
7
|
+
}) => Promise<import("@aeriajs/types").Left<ACError.ResourceNotFound> | import("@aeriajs/types").Left<ACError.FunctionNotFound> | import("@aeriajs/types").Left<ACError.FunctionNotExposed> | import("@aeriajs/types").Left<ACError.AuthorizationError> | import("@aeriajs/types").Right<(payload: unknown, context: Context) => Promise<any>>>;
|
package/dist/assets.js
CHANGED
|
@@ -13,10 +13,7 @@ const internalGetCollectionAsset = async (collectionName, assetName) => {
|
|
|
13
13
|
const collection = await (0, entrypoint_1.getCollection)(collectionName);
|
|
14
14
|
const asset = collection?.[assetName];
|
|
15
15
|
if (!asset) {
|
|
16
|
-
|
|
17
|
-
return (0, common_1.left)(types_1.ACError.ResourceNotFound);
|
|
18
|
-
}
|
|
19
|
-
return (0, common_1.left)(types_1.ACError.AssetNotFound);
|
|
16
|
+
return (0, common_1.left)(types_1.ACError.ResourceNotFound);
|
|
20
17
|
}
|
|
21
18
|
return (0, common_1.right)(asset);
|
|
22
19
|
};
|
|
@@ -63,13 +60,9 @@ const getFunction = async (collectionName, functionName, token, options = {
|
|
|
63
60
|
const securityPolicy = collection.security?.functions?.[functionName];
|
|
64
61
|
if (securityPolicy) {
|
|
65
62
|
if (securityPolicy.rateLimiting) {
|
|
66
|
-
const
|
|
67
|
-
if ((0, common_1.
|
|
68
|
-
|
|
69
|
-
return context.error(types_1.HTTPStatus.TooManyRequests, {
|
|
70
|
-
code: error,
|
|
71
|
-
message: 'rate limit was achieved for this resource',
|
|
72
|
-
});
|
|
63
|
+
const rate = await (0, security_1.limitRate)(securityPolicy.rateLimiting, context);
|
|
64
|
+
if ((0, common_1.isError)(rate)) {
|
|
65
|
+
return rate;
|
|
73
66
|
}
|
|
74
67
|
}
|
|
75
68
|
}
|
package/dist/assets.mjs
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
-
import { ACError
|
|
3
|
-
import { left, right, isLeft, unwrapEither } from "@aeriajs/common";
|
|
2
|
+
import { ACError } from "@aeriajs/types";
|
|
3
|
+
import { isError, left, right, isLeft, unwrapEither } from "@aeriajs/common";
|
|
4
4
|
import { limitRate } from "@aeriajs/security";
|
|
5
5
|
import { getCollection } from "@aeriajs/entrypoint";
|
|
6
6
|
import { isFunctionExposed, FunctionExposedStatus } from "./accessControl.mjs";
|
|
@@ -11,10 +11,7 @@ export const internalGetCollectionAsset = async (collectionName, assetName) => {
|
|
|
11
11
|
const collection = await getCollection(collectionName);
|
|
12
12
|
const asset = collection?.[assetName];
|
|
13
13
|
if (!asset) {
|
|
14
|
-
|
|
15
|
-
return left(ACError.ResourceNotFound);
|
|
16
|
-
}
|
|
17
|
-
return left(ACError.AssetNotFound);
|
|
14
|
+
return left(ACError.ResourceNotFound);
|
|
18
15
|
}
|
|
19
16
|
return right(asset);
|
|
20
17
|
};
|
|
@@ -61,13 +58,9 @@ export const getFunction = async (collectionName, functionName, token, options =
|
|
|
61
58
|
const securityPolicy = collection.security?.functions?.[functionName];
|
|
62
59
|
if (securityPolicy) {
|
|
63
60
|
if (securityPolicy.rateLimiting) {
|
|
64
|
-
const
|
|
65
|
-
if (
|
|
66
|
-
|
|
67
|
-
return context.error(HTTPStatus.TooManyRequests, {
|
|
68
|
-
code: error,
|
|
69
|
-
message: "rate limit was achieved for this resource"
|
|
70
|
-
});
|
|
61
|
+
const rate = await limitRate(securityPolicy.rateLimiting, context);
|
|
62
|
+
if (isError(rate)) {
|
|
63
|
+
return rate;
|
|
71
64
|
}
|
|
72
65
|
}
|
|
73
66
|
}
|
|
@@ -8,8 +8,7 @@ export declare const defineCollection: <TCollection extends Omit<Collection<TCol
|
|
|
8
8
|
contracts?: TContracts;
|
|
9
9
|
exposedFunctions?: TExposedFunctions;
|
|
10
10
|
security?: CollectionSecurityPolicy<{
|
|
11
|
-
|
|
12
|
-
functions: NoInfer<TFunctions>;
|
|
11
|
+
functions: TFunctions;
|
|
13
12
|
}>;
|
|
14
13
|
}) => TCollection & {
|
|
15
14
|
item: SchemaWithId<TDescription>;
|
|
@@ -21,7 +20,7 @@ export declare const extendCollection: <const TLeftCollection extends Collection
|
|
|
21
20
|
description?: Partial<Description> | undefined;
|
|
22
21
|
item?: Partial<any> | undefined;
|
|
23
22
|
security?: Partial<CollectionSecurityPolicy<any> | undefined>;
|
|
24
|
-
functions?: Partial<Record<string, (payload: any, context: import("@aeriajs/types").Context
|
|
23
|
+
functions?: Partial<Record<string, (payload: any, context: import("@aeriajs/types").Context<any>, ...args: any[]) => any> | undefined>;
|
|
25
24
|
contracts?: Partial<Record<string, Contract> | undefined>;
|
|
26
25
|
exposedFunctions?: Partial<Record<string, AccessCondition> | undefined>;
|
|
27
26
|
}>(left: TLeftCollection, right: TRightCollection) => ExtendCollection<TLeftCollection, TRightCollection>;
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.fill = void 0;
|
|
4
|
+
const common_1 = require("@aeriajs/common");
|
|
5
|
+
const fill = (doc, description) => {
|
|
6
|
+
const docCopy = Object.assign({}, doc);
|
|
7
|
+
for (const key in docCopy) {
|
|
8
|
+
if (docCopy[key] === null) {
|
|
9
|
+
delete docCopy[key];
|
|
10
|
+
}
|
|
11
|
+
}
|
|
12
|
+
return Object.assign((0, common_1.freshItem)(description), docCopy);
|
|
13
|
+
};
|
|
14
|
+
exports.fill = fill;
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
import { freshItem } from "@aeriajs/common";
|
|
3
|
+
export const fill = (doc, description) => {
|
|
4
|
+
const docCopy = Object.assign({}, doc);
|
|
5
|
+
for (const key in docCopy) {
|
|
6
|
+
if (docCopy[key] === null) {
|
|
7
|
+
delete docCopy[key];
|
|
8
|
+
}
|
|
9
|
+
}
|
|
10
|
+
return Object.assign(freshItem(description), docCopy);
|
|
11
|
+
};
|
|
@@ -1,8 +1,10 @@
|
|
|
1
1
|
export * from './cascadingRemove.js';
|
|
2
2
|
export * from './define.js';
|
|
3
3
|
export * from './description.js';
|
|
4
|
+
export * from './fill.js';
|
|
5
|
+
export * from './normalizeProjection.js';
|
|
4
6
|
export * from './pagination.js';
|
|
5
7
|
export * from './preload.js';
|
|
8
|
+
export * from './prepareInsert.js';
|
|
6
9
|
export * from './reference.js';
|
|
7
10
|
export * from './traverseDocument.js';
|
|
8
|
-
export * from './utils.js';
|
package/dist/collection/index.js
CHANGED
|
@@ -17,8 +17,10 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
17
17
|
__exportStar(require("./cascadingRemove.js"), exports);
|
|
18
18
|
__exportStar(require("./define.js"), exports);
|
|
19
19
|
__exportStar(require("./description.js"), exports);
|
|
20
|
+
__exportStar(require("./fill.js"), exports);
|
|
21
|
+
__exportStar(require("./normalizeProjection.js"), exports);
|
|
20
22
|
__exportStar(require("./pagination.js"), exports);
|
|
21
23
|
__exportStar(require("./preload.js"), exports);
|
|
24
|
+
__exportStar(require("./prepareInsert.js"), exports);
|
|
22
25
|
__exportStar(require("./reference.js"), exports);
|
|
23
26
|
__exportStar(require("./traverseDocument.js"), exports);
|
|
24
|
-
__exportStar(require("./utils.js"), exports);
|
|
@@ -2,8 +2,10 @@
|
|
|
2
2
|
export * from "./cascadingRemove.mjs";
|
|
3
3
|
export * from "./define.mjs";
|
|
4
4
|
export * from "./description.mjs";
|
|
5
|
+
export * from "./fill.mjs";
|
|
6
|
+
export * from "./normalizeProjection.mjs";
|
|
5
7
|
export * from "./pagination.mjs";
|
|
6
8
|
export * from "./preload.mjs";
|
|
9
|
+
export * from "./prepareInsert.mjs";
|
|
7
10
|
export * from "./reference.mjs";
|
|
8
11
|
export * from "./traverseDocument.mjs";
|
|
9
|
-
export * from "./utils.mjs";
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
import type { Description } from '@aeriajs/types';
|
|
2
|
+
export declare const normalizeProjection: <TDescription extends Pick<Description, "properties">, TProjectedProperties extends (keyof TDescription["properties"])[]>(properties: TProjectedProperties, description: TDescription) => {} | null;
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.normalizeProjection = void 0;
|
|
4
|
+
const normalizeProjection = (properties, description) => {
|
|
5
|
+
const target = Array.from(properties);
|
|
6
|
+
if (target.length === 0) {
|
|
7
|
+
target.push(...Object.keys(description.properties));
|
|
8
|
+
}
|
|
9
|
+
const projection = target.reduce((a, key) => {
|
|
10
|
+
if (key !== '_id' && description.properties[key].hidden) {
|
|
11
|
+
return a;
|
|
12
|
+
}
|
|
13
|
+
return {
|
|
14
|
+
...a,
|
|
15
|
+
[key]: 1,
|
|
16
|
+
};
|
|
17
|
+
}, {});
|
|
18
|
+
return Object.keys(projection).length === 0
|
|
19
|
+
? null
|
|
20
|
+
: projection;
|
|
21
|
+
};
|
|
22
|
+
exports.normalizeProjection = normalizeProjection;
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
export const normalizeProjection = (properties, description) => {
|
|
3
|
+
const target = Array.from(properties);
|
|
4
|
+
if (target.length === 0) {
|
|
5
|
+
target.push(...Object.keys(description.properties));
|
|
6
|
+
}
|
|
7
|
+
const projection = target.reduce((a, key) => {
|
|
8
|
+
if (key !== "_id" && description.properties[key].hidden) {
|
|
9
|
+
return a;
|
|
10
|
+
}
|
|
11
|
+
return {
|
|
12
|
+
...a,
|
|
13
|
+
[key]: 1
|
|
14
|
+
};
|
|
15
|
+
}, {});
|
|
16
|
+
return Object.keys(projection).length === 0 ? null : projection;
|
|
17
|
+
};
|
|
@@ -6,7 +6,7 @@ const makePagination = async (payload, documents, context) => {
|
|
|
6
6
|
? payload.limit
|
|
7
7
|
: context.config.paginationLimit;
|
|
8
8
|
const offset = payload.offset || 0;
|
|
9
|
-
const recordsTotal = context.collection.
|
|
9
|
+
const recordsTotal = context.collection.originalFunctions.count
|
|
10
10
|
? await context.collection.functions.count({
|
|
11
11
|
filters: payload.filters,
|
|
12
12
|
})
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
export const makePagination = async (payload, documents, context) => {
|
|
3
3
|
const limit = payload.limit ? payload.limit : context.config.paginationLimit;
|
|
4
4
|
const offset = payload.offset || 0;
|
|
5
|
-
const recordsTotal = context.collection.
|
|
5
|
+
const recordsTotal = context.collection.originalFunctions.count ? await context.collection.functions.count({
|
|
6
6
|
filters: payload.filters
|
|
7
7
|
}) : await context.collection.model.countDocuments(payload.filters);
|
|
8
8
|
return {
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.prepareInsert = void 0;
|
|
4
|
+
const prepareCreate = (doc, description) => {
|
|
5
|
+
const result = Object.assign({}, description.defaults || {});
|
|
6
|
+
for (const propName in doc) {
|
|
7
|
+
const value = doc[propName];
|
|
8
|
+
if (value === null || value === undefined) {
|
|
9
|
+
continue;
|
|
10
|
+
}
|
|
11
|
+
result[propName] = value;
|
|
12
|
+
}
|
|
13
|
+
return result;
|
|
14
|
+
};
|
|
15
|
+
const prepareUpdate = (doc) => {
|
|
16
|
+
const result = {
|
|
17
|
+
$set: {},
|
|
18
|
+
$unset: {},
|
|
19
|
+
};
|
|
20
|
+
for (const propName in doc) {
|
|
21
|
+
const value = doc[propName];
|
|
22
|
+
if (value === null || value === undefined) {
|
|
23
|
+
result.$unset[propName] = value;
|
|
24
|
+
continue;
|
|
25
|
+
}
|
|
26
|
+
result.$set[propName] = value;
|
|
27
|
+
}
|
|
28
|
+
return result;
|
|
29
|
+
};
|
|
30
|
+
const prepareInsert = (payload, description) => {
|
|
31
|
+
const doc = Object.assign({}, payload);
|
|
32
|
+
const docId = payload._id;
|
|
33
|
+
delete doc._id;
|
|
34
|
+
delete doc.created_at;
|
|
35
|
+
delete doc.updated_at;
|
|
36
|
+
const what = docId
|
|
37
|
+
? prepareUpdate(doc)
|
|
38
|
+
: prepareCreate(doc, description);
|
|
39
|
+
Object.keys(what).forEach((k) => {
|
|
40
|
+
if (typeof what[k] === 'object' && Object.keys(what[k]).length === 0) {
|
|
41
|
+
delete what[k];
|
|
42
|
+
}
|
|
43
|
+
});
|
|
44
|
+
return what;
|
|
45
|
+
};
|
|
46
|
+
exports.prepareInsert = prepareInsert;
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
const prepareCreate = (doc, description) => {
|
|
3
|
+
const result = Object.assign({}, description.defaults || {});
|
|
4
|
+
for (const propName in doc) {
|
|
5
|
+
const value = doc[propName];
|
|
6
|
+
if (value === null || value === void 0) {
|
|
7
|
+
continue;
|
|
8
|
+
}
|
|
9
|
+
result[propName] = value;
|
|
10
|
+
}
|
|
11
|
+
return result;
|
|
12
|
+
};
|
|
13
|
+
const prepareUpdate = (doc) => {
|
|
14
|
+
const result = {
|
|
15
|
+
$set: {},
|
|
16
|
+
$unset: {}
|
|
17
|
+
};
|
|
18
|
+
for (const propName in doc) {
|
|
19
|
+
const value = doc[propName];
|
|
20
|
+
if (value === null || value === void 0) {
|
|
21
|
+
result.$unset[propName] = value;
|
|
22
|
+
continue;
|
|
23
|
+
}
|
|
24
|
+
result.$set[propName] = value;
|
|
25
|
+
}
|
|
26
|
+
return result;
|
|
27
|
+
};
|
|
28
|
+
export const prepareInsert = (payload, description) => {
|
|
29
|
+
const doc = Object.assign({}, payload);
|
|
30
|
+
const docId = payload._id;
|
|
31
|
+
delete doc._id;
|
|
32
|
+
delete doc.created_at;
|
|
33
|
+
delete doc.updated_at;
|
|
34
|
+
const what = docId ? prepareUpdate(doc) : prepareCreate(doc, description);
|
|
35
|
+
Object.keys(what).forEach((k) => {
|
|
36
|
+
if (typeof what[k] === "object" && Object.keys(what[k]).length === 0) {
|
|
37
|
+
delete what[k];
|
|
38
|
+
}
|
|
39
|
+
});
|
|
40
|
+
return what;
|
|
41
|
+
};
|
|
@@ -1,10 +1,11 @@
|
|
|
1
|
-
import type { Description, Property,
|
|
1
|
+
import type { Description, Property, ValidationError, Context } from '@aeriajs/types';
|
|
2
|
+
import { ACError } from '@aeriajs/types';
|
|
2
3
|
import { ObjectId } from 'mongodb';
|
|
3
4
|
export type TraverseOptions = {
|
|
4
5
|
autoCast?: boolean;
|
|
5
6
|
getters?: boolean;
|
|
6
7
|
validate?: boolean;
|
|
7
|
-
validateRequired?:
|
|
8
|
+
validateRequired?: Description['required'];
|
|
8
9
|
moveFiles?: boolean;
|
|
9
10
|
fromProperties?: boolean;
|
|
10
11
|
allowOperators?: boolean;
|
|
@@ -16,7 +17,7 @@ export type TraverseNormalized = {
|
|
|
16
17
|
description: Description;
|
|
17
18
|
pipe: <T = unknown>(value: unknown, phaseContext: PhaseContext) => T | Promise<T>;
|
|
18
19
|
};
|
|
19
|
-
export declare enum
|
|
20
|
+
export declare enum TraverseError {
|
|
20
21
|
InvalidDocumentId = "INVALID_DOCUMENT_ID",
|
|
21
22
|
InvalidTempfile = "INVALID_TEMPFILE"
|
|
22
23
|
}
|
|
@@ -23,7 +23,7 @@ var __importStar = (this && this.__importStar) || function (mod) {
|
|
|
23
23
|
return result;
|
|
24
24
|
};
|
|
25
25
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
26
|
-
exports.traverseDocument = exports.
|
|
26
|
+
exports.traverseDocument = exports.TraverseError = void 0;
|
|
27
27
|
const types_1 = require("@aeriajs/types");
|
|
28
28
|
const common_1 = require("@aeriajs/common");
|
|
29
29
|
const validation_1 = require("@aeriajs/validation");
|
|
@@ -31,11 +31,11 @@ const mongodb_1 = require("mongodb");
|
|
|
31
31
|
const assets_js_1 = require("../assets.js");
|
|
32
32
|
const preload_js_1 = require("./preload.js");
|
|
33
33
|
const fs = __importStar(require("fs/promises"));
|
|
34
|
-
var
|
|
35
|
-
(function (
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
})(
|
|
34
|
+
var TraverseError;
|
|
35
|
+
(function (TraverseError) {
|
|
36
|
+
TraverseError["InvalidDocumentId"] = "INVALID_DOCUMENT_ID";
|
|
37
|
+
TraverseError["InvalidTempfile"] = "INVALID_TEMPFILE";
|
|
38
|
+
})(TraverseError || (exports.TraverseError = TraverseError = {}));
|
|
39
39
|
const getProperty = (propertyName, parentProperty) => {
|
|
40
40
|
if (propertyName === '_id') {
|
|
41
41
|
return {
|
|
@@ -65,7 +65,7 @@ const disposeOldFiles = async (ctx, options = {}) => {
|
|
|
65
65
|
},
|
|
66
66
|
});
|
|
67
67
|
if (!doc) {
|
|
68
|
-
return (0, common_1.left)(
|
|
68
|
+
return (0, common_1.left)(TraverseError.InvalidDocumentId);
|
|
69
69
|
}
|
|
70
70
|
let fileIds = (0, common_1.getValueFromPath)(doc, ctx.propPath);
|
|
71
71
|
if (options.fromIds) {
|
|
@@ -196,7 +196,7 @@ const moveFiles = async (value, ctx) => {
|
|
|
196
196
|
_id: new mongodb_1.ObjectId(value.tempId),
|
|
197
197
|
});
|
|
198
198
|
if (!tempFile) {
|
|
199
|
-
return (0, common_1.left)(
|
|
199
|
+
return (0, common_1.left)(TraverseError.InvalidTempfile);
|
|
200
200
|
}
|
|
201
201
|
if (ctx.root._id) {
|
|
202
202
|
await disposeOldFiles(ctx);
|
|
@@ -268,12 +268,13 @@ const recurse = async (target, ctx) => {
|
|
|
268
268
|
// if first propName is preceded by '$' we assume
|
|
269
269
|
// it contains MongoDB query operators
|
|
270
270
|
if (Object.keys(value)[0]?.startsWith('$')) {
|
|
271
|
-
if (ctx.options.allowOperators) {
|
|
272
|
-
|
|
273
|
-
propName,
|
|
274
|
-
value,
|
|
275
|
-
]);
|
|
271
|
+
if (!ctx.options.allowOperators) {
|
|
272
|
+
return (0, common_1.left)(types_1.ACError.InsecureOperator);
|
|
276
273
|
}
|
|
274
|
+
entries.push([
|
|
275
|
+
propName,
|
|
276
|
+
value,
|
|
277
|
+
]);
|
|
277
278
|
continue;
|
|
278
279
|
}
|
|
279
280
|
if (Array.isArray(value)) {
|
|
@@ -412,7 +413,7 @@ const traverseDocument = async (what, description, _options) => {
|
|
|
412
413
|
}
|
|
413
414
|
if (validationError) {
|
|
414
415
|
return (0, common_1.left)((0, validation_1.makeValidationError)({
|
|
415
|
-
code: types_1.
|
|
416
|
+
code: types_1.ValidationErrorCode.InvalidProperties,
|
|
416
417
|
errors: validationError,
|
|
417
418
|
}));
|
|
418
419
|
}
|
|
@@ -1,16 +1,16 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
-
import {
|
|
2
|
+
import { ACError, ValidationErrorCode } from "@aeriajs/types";
|
|
3
3
|
import { left, right, isLeft, unwrapEither, unsafe, pipe, isReference, getValueFromPath, isObjectId } from "@aeriajs/common";
|
|
4
4
|
import { makeValidationError, validateProperty, validateWholeness } from "@aeriajs/validation";
|
|
5
5
|
import { ObjectId } from "mongodb";
|
|
6
6
|
import { getCollectionAsset } from "../assets.mjs";
|
|
7
7
|
import { preloadDescription } from "./preload.mjs";
|
|
8
8
|
import * as fs from "fs/promises";
|
|
9
|
-
export var
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
return
|
|
13
|
-
})(
|
|
9
|
+
export var TraverseError = /* @__PURE__ */ ((TraverseError2) => {
|
|
10
|
+
TraverseError2["InvalidDocumentId"] = "INVALID_DOCUMENT_ID";
|
|
11
|
+
TraverseError2["InvalidTempfile"] = "INVALID_TEMPFILE";
|
|
12
|
+
return TraverseError2;
|
|
13
|
+
})(TraverseError || {});
|
|
14
14
|
const getProperty = (propertyName, parentProperty) => {
|
|
15
15
|
if (propertyName === "_id") {
|
|
16
16
|
return {
|
|
@@ -230,12 +230,13 @@ const recurse = async (target, ctx) => {
|
|
|
230
230
|
}
|
|
231
231
|
if (!property && value && (value.constructor === Object || value.constructor === Array)) {
|
|
232
232
|
if (Object.keys(value)[0]?.startsWith("$")) {
|
|
233
|
-
if (ctx.options.allowOperators) {
|
|
234
|
-
|
|
235
|
-
propName,
|
|
236
|
-
value
|
|
237
|
-
]);
|
|
233
|
+
if (!ctx.options.allowOperators) {
|
|
234
|
+
return left(ACError.InsecureOperator);
|
|
238
235
|
}
|
|
236
|
+
entries.push([
|
|
237
|
+
propName,
|
|
238
|
+
value
|
|
239
|
+
]);
|
|
239
240
|
continue;
|
|
240
241
|
}
|
|
241
242
|
if (Array.isArray(value)) {
|
|
@@ -370,7 +371,7 @@ export const traverseDocument = async (what, description, _options) => {
|
|
|
370
371
|
}
|
|
371
372
|
if (validationError) {
|
|
372
373
|
return left(makeValidationError({
|
|
373
|
-
code:
|
|
374
|
+
code: ValidationErrorCode.InvalidProperties,
|
|
374
375
|
errors: validationError
|
|
375
376
|
}));
|
|
376
377
|
}
|
package/dist/context.d.ts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
import type { ContextOptions } from '@aeriajs/types';
|
|
2
|
-
export declare const createContext: (options?: ContextOptions) => Promise<import("@aeriajs/types").RouteContext<null> & import("@aeriajs/types").CollectionContext<
|
|
2
|
+
export declare const createContext: (options?: ContextOptions) => Promise<import("@aeriajs/types").RouteContext<null> & import("@aeriajs/types").CollectionContext<import("@aeriajs/types").Description, any>>;
|
package/dist/context.js
CHANGED
|
@@ -79,7 +79,7 @@ const createContext = async (options = {}) => {
|
|
|
79
79
|
context.error = (httpStatus, endpointError) => {
|
|
80
80
|
return (0, common_1.error)(Object.assign({
|
|
81
81
|
httpStatus,
|
|
82
|
-
}, endpointError)
|
|
82
|
+
}, endpointError));
|
|
83
83
|
};
|
|
84
84
|
context.limitRate = (params) => {
|
|
85
85
|
return (0, security_1.limitRate)(params, context);
|
package/dist/context.mjs
CHANGED
|
@@ -54,7 +54,7 @@ export const createContext = async (options = {}) => {
|
|
|
54
54
|
context.error = (httpStatus, endpointError) => {
|
|
55
55
|
return error(Object.assign({
|
|
56
56
|
httpStatus
|
|
57
|
-
}, endpointError)
|
|
57
|
+
}, endpointError));
|
|
58
58
|
};
|
|
59
59
|
context.limitRate = (params) => {
|
|
60
60
|
return limitRate(params, context);
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import type { Context, SchemaWithId, GetPayload } from '@aeriajs/types';
|
|
1
|
+
import type { Context, SchemaWithId, GetPayload, GetReturnType } from '@aeriajs/types';
|
|
2
2
|
export type GetOptions = {
|
|
3
3
|
bypassSecurity?: boolean;
|
|
4
4
|
};
|
|
5
|
-
export declare const get: <TContext extends Context>(payload: GetPayload<SchemaWithId<TContext['description']>>, context: TContext extends Context<any> ? TContext : never, options?: GetOptions) => Promise<
|
|
5
|
+
export declare const get: <TContext extends Context>(payload: GetPayload<SchemaWithId<TContext['description']>>, context: TContext extends Context<any> ? TContext : never, options?: GetOptions) => Promise<GetReturnType<TContext['description']>>;
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.get = void 0;
|
|
4
|
+
const types_1 = require("@aeriajs/types");
|
|
4
5
|
const security_1 = require("@aeriajs/security");
|
|
5
6
|
const common_1 = require("@aeriajs/common");
|
|
6
7
|
const index_js_1 = require("../../collection/index.js");
|
|
@@ -35,7 +36,9 @@ const get = async (payload, context, options) => {
|
|
|
35
36
|
}));
|
|
36
37
|
const result = await context.collection.model.aggregate(pipeline).next();
|
|
37
38
|
if (!result) {
|
|
38
|
-
return
|
|
39
|
+
return context.error(types_1.HTTPStatus.NotFound, {
|
|
40
|
+
code: types_1.ACError.ResourceNotFound,
|
|
41
|
+
});
|
|
39
42
|
}
|
|
40
43
|
return (0, index_js_1.fill)((0, common_1.unsafe)(await (0, index_js_1.traverseDocument)(result, context.description, {
|
|
41
44
|
getters: true,
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
+
import { HTTPStatus, ACError } from "@aeriajs/types";
|
|
2
3
|
import { useSecurity } from "@aeriajs/security";
|
|
3
4
|
import { unsafe } from "@aeriajs/common";
|
|
4
5
|
import {
|
|
@@ -40,7 +41,9 @@ export const get = async (payload, context, options) => {
|
|
|
40
41
|
}));
|
|
41
42
|
const result = await context.collection.model.aggregate(pipeline).next();
|
|
42
43
|
if (!result) {
|
|
43
|
-
return
|
|
44
|
+
return context.error(HTTPStatus.NotFound, {
|
|
45
|
+
code: ACError.ResourceNotFound
|
|
46
|
+
});
|
|
44
47
|
}
|
|
45
48
|
return fill(unsafe(await traverseDocument(result, context.description, {
|
|
46
49
|
getters: true,
|
|
@@ -1,5 +1,30 @@
|
|
|
1
|
-
import type { Context, SchemaWithId, InsertPayload } from '@aeriajs/types';
|
|
1
|
+
import type { Context, SchemaWithId, InsertPayload, InsertReturnType } from '@aeriajs/types';
|
|
2
|
+
import { HTTPStatus, ACError, ValidationErrorCode } from '@aeriajs/types';
|
|
2
3
|
export type InsertOptions = {
|
|
3
4
|
bypassSecurity?: boolean;
|
|
4
5
|
};
|
|
5
|
-
export declare const
|
|
6
|
+
export declare const insertErrorSchema: {
|
|
7
|
+
readonly type: "object";
|
|
8
|
+
readonly properties: {
|
|
9
|
+
readonly value: {
|
|
10
|
+
readonly type: "object";
|
|
11
|
+
readonly required: readonly ["httpStatus", "code"];
|
|
12
|
+
readonly properties: {
|
|
13
|
+
readonly httpStatus: {
|
|
14
|
+
readonly enum: (HTTPStatus.NotFound | HTTPStatus.UnprocessableContent)[];
|
|
15
|
+
};
|
|
16
|
+
readonly code: {
|
|
17
|
+
readonly enum: (ACError | ValidationErrorCode)[];
|
|
18
|
+
};
|
|
19
|
+
readonly message: {
|
|
20
|
+
readonly type: "string";
|
|
21
|
+
};
|
|
22
|
+
readonly details: {
|
|
23
|
+
readonly type: "object";
|
|
24
|
+
readonly variable: true;
|
|
25
|
+
};
|
|
26
|
+
};
|
|
27
|
+
};
|
|
28
|
+
};
|
|
29
|
+
};
|
|
30
|
+
export declare const insert: <TContext extends Context>(payload: InsertPayload<SchemaWithId<TContext['description']>>, context: TContext, options?: InsertOptions) => Promise<InsertReturnType<SchemaWithId<TContext['description']>>>;
|
|
@@ -1,9 +1,25 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.insert = void 0;
|
|
3
|
+
exports.insert = exports.insertErrorSchema = void 0;
|
|
4
|
+
const types_1 = require("@aeriajs/types");
|
|
4
5
|
const security_1 = require("@aeriajs/security");
|
|
5
6
|
const common_1 = require("@aeriajs/common");
|
|
6
7
|
const index_js_1 = require("../../collection/index.js");
|
|
8
|
+
exports.insertErrorSchema = (0, common_1.endpointErrorSchema)({
|
|
9
|
+
httpStatus: [
|
|
10
|
+
types_1.HTTPStatus.UnprocessableContent,
|
|
11
|
+
types_1.HTTPStatus.NotFound,
|
|
12
|
+
],
|
|
13
|
+
code: [
|
|
14
|
+
types_1.ACError.InsecureOperator,
|
|
15
|
+
types_1.ACError.OwnershipError,
|
|
16
|
+
types_1.ACError.ResourceNotFound,
|
|
17
|
+
types_1.ACError.TargetImmutable,
|
|
18
|
+
types_1.ValidationErrorCode.EmptyTarget,
|
|
19
|
+
types_1.ValidationErrorCode.InvalidProperties,
|
|
20
|
+
types_1.ValidationErrorCode.MissingProperties,
|
|
21
|
+
],
|
|
22
|
+
});
|
|
7
23
|
const insert = async (payload, context, options) => {
|
|
8
24
|
const security = (0, security_1.useSecurity)(context);
|
|
9
25
|
const query = !options?.bypassSecurity
|
|
@@ -21,52 +37,69 @@ const insert = async (payload, context, options) => {
|
|
|
21
37
|
});
|
|
22
38
|
if ((0, common_1.isLeft)(whatEither)) {
|
|
23
39
|
const error = (0, common_1.unwrapEither)(whatEither);
|
|
24
|
-
|
|
40
|
+
if (typeof error === 'string') {
|
|
41
|
+
return context.error(types_1.HTTPStatus.UnprocessableContent, {
|
|
42
|
+
code: error,
|
|
43
|
+
});
|
|
44
|
+
}
|
|
45
|
+
return context.error(types_1.HTTPStatus.UnprocessableContent, {
|
|
46
|
+
code: error.code,
|
|
47
|
+
details: error.errors,
|
|
48
|
+
});
|
|
25
49
|
}
|
|
26
50
|
const what = (0, common_1.unwrapEither)(whatEither);
|
|
27
51
|
const docId = '_id' in what
|
|
28
52
|
? what._id
|
|
29
53
|
: null;
|
|
30
|
-
const
|
|
54
|
+
const content = (0, index_js_1.prepareInsert)(what, context.description);
|
|
31
55
|
const projection = payload.project
|
|
32
56
|
? (0, index_js_1.normalizeProjection)(payload.project, context.description)
|
|
33
57
|
: {};
|
|
34
58
|
let newId = docId;
|
|
35
59
|
if (!newId) {
|
|
36
60
|
const now = new Date();
|
|
37
|
-
Object.assign(
|
|
61
|
+
Object.assign(content, {
|
|
38
62
|
created_at: now,
|
|
39
63
|
updated_at: now,
|
|
40
64
|
});
|
|
41
|
-
newId = (await context.collection.model.insertOne(
|
|
65
|
+
newId = (await context.collection.model.insertOne(content)).insertedId;
|
|
42
66
|
}
|
|
43
67
|
else {
|
|
44
|
-
|
|
45
|
-
|
|
68
|
+
content.$set ??= {};
|
|
69
|
+
content.$set.updated_at = new Date();
|
|
46
70
|
await context.collection.model.updateOne({
|
|
47
71
|
_id: docId,
|
|
48
|
-
},
|
|
72
|
+
}, content);
|
|
49
73
|
}
|
|
74
|
+
let doc;
|
|
50
75
|
if (context.collection.originalFunctions.get) {
|
|
51
|
-
|
|
76
|
+
doc = await context.collection.originalFunctions.get({
|
|
52
77
|
filters: {
|
|
53
78
|
_id: newId,
|
|
54
79
|
},
|
|
55
|
-
},
|
|
80
|
+
}, Object.assign({
|
|
81
|
+
inherited: true,
|
|
82
|
+
}, context), {
|
|
56
83
|
bypassSecurity: true,
|
|
57
84
|
});
|
|
58
|
-
return (0, common_1.right)(document);
|
|
59
85
|
}
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
86
|
+
else {
|
|
87
|
+
doc = await context.collection.model.findOne({
|
|
88
|
+
_id: newId,
|
|
89
|
+
}, {
|
|
90
|
+
projection,
|
|
91
|
+
});
|
|
92
|
+
}
|
|
93
|
+
if (!doc) {
|
|
94
|
+
return context.error(types_1.HTTPStatus.NotFound, {
|
|
95
|
+
code: types_1.ACError.ResourceNotFound,
|
|
96
|
+
});
|
|
97
|
+
}
|
|
98
|
+
const result = (0, common_1.unsafe)(await (0, index_js_1.traverseDocument)(doc, context.description, {
|
|
66
99
|
getters: true,
|
|
67
100
|
fromProperties: true,
|
|
68
101
|
recurseReferences: true,
|
|
69
102
|
}));
|
|
70
|
-
return
|
|
103
|
+
return result;
|
|
71
104
|
};
|
|
72
105
|
exports.insert = insert;
|
|
@@ -1,7 +1,23 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
+
import { HTTPStatus, ACError, ValidationErrorCode } from "@aeriajs/types";
|
|
2
3
|
import { useSecurity } from "@aeriajs/security";
|
|
3
|
-
import {
|
|
4
|
+
import { isLeft, unwrapEither, unsafe, endpointErrorSchema } from "@aeriajs/common";
|
|
4
5
|
import { traverseDocument, normalizeProjection, prepareInsert } from "../../collection/index.mjs";
|
|
6
|
+
export const insertErrorSchema = endpointErrorSchema({
|
|
7
|
+
httpStatus: [
|
|
8
|
+
HTTPStatus.UnprocessableContent,
|
|
9
|
+
HTTPStatus.NotFound
|
|
10
|
+
],
|
|
11
|
+
code: [
|
|
12
|
+
ACError.InsecureOperator,
|
|
13
|
+
ACError.OwnershipError,
|
|
14
|
+
ACError.ResourceNotFound,
|
|
15
|
+
ACError.TargetImmutable,
|
|
16
|
+
ValidationErrorCode.EmptyTarget,
|
|
17
|
+
ValidationErrorCode.InvalidProperties,
|
|
18
|
+
ValidationErrorCode.MissingProperties
|
|
19
|
+
]
|
|
20
|
+
});
|
|
5
21
|
export const insert = async (payload, context, options) => {
|
|
6
22
|
const security = useSecurity(context);
|
|
7
23
|
const query = !options?.bypassSecurity ? unsafe(await security.beforeWrite(payload)) : payload;
|
|
@@ -15,46 +31,62 @@ export const insert = async (payload, context, options) => {
|
|
|
15
31
|
});
|
|
16
32
|
if (isLeft(whatEither)) {
|
|
17
33
|
const error = unwrapEither(whatEither);
|
|
18
|
-
|
|
34
|
+
if (typeof error === "string") {
|
|
35
|
+
return context.error(HTTPStatus.UnprocessableContent, {
|
|
36
|
+
code: error
|
|
37
|
+
});
|
|
38
|
+
}
|
|
39
|
+
return context.error(HTTPStatus.UnprocessableContent, {
|
|
40
|
+
code: error.code,
|
|
41
|
+
details: error.errors
|
|
42
|
+
});
|
|
19
43
|
}
|
|
20
44
|
const what = unwrapEither(whatEither);
|
|
21
45
|
const docId = "_id" in what ? what._id : null;
|
|
22
|
-
const
|
|
46
|
+
const content = prepareInsert(what, context.description);
|
|
23
47
|
const projection = payload.project ? normalizeProjection(payload.project, context.description) : {};
|
|
24
48
|
let newId = docId;
|
|
25
49
|
if (!newId) {
|
|
26
50
|
const now = /* @__PURE__ */ new Date();
|
|
27
|
-
Object.assign(
|
|
51
|
+
Object.assign(content, {
|
|
28
52
|
created_at: now,
|
|
29
53
|
updated_at: now
|
|
30
54
|
});
|
|
31
|
-
newId = (await context.collection.model.insertOne(
|
|
55
|
+
newId = (await context.collection.model.insertOne(content)).insertedId;
|
|
32
56
|
} else {
|
|
33
|
-
|
|
34
|
-
|
|
57
|
+
content.$set ??= {};
|
|
58
|
+
content.$set.updated_at = /* @__PURE__ */ new Date();
|
|
35
59
|
await context.collection.model.updateOne({
|
|
36
60
|
_id: docId
|
|
37
|
-
},
|
|
61
|
+
}, content);
|
|
38
62
|
}
|
|
63
|
+
let doc;
|
|
39
64
|
if (context.collection.originalFunctions.get) {
|
|
40
|
-
|
|
65
|
+
doc = await context.collection.originalFunctions.get({
|
|
41
66
|
filters: {
|
|
42
67
|
_id: newId
|
|
43
68
|
}
|
|
44
|
-
},
|
|
69
|
+
}, Object.assign({
|
|
70
|
+
inherited: true
|
|
71
|
+
}, context), {
|
|
45
72
|
bypassSecurity: true
|
|
46
73
|
});
|
|
47
|
-
|
|
74
|
+
} else {
|
|
75
|
+
doc = await context.collection.model.findOne({
|
|
76
|
+
_id: newId
|
|
77
|
+
}, {
|
|
78
|
+
projection
|
|
79
|
+
});
|
|
48
80
|
}
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
}
|
|
54
|
-
const result = unsafe(await traverseDocument(
|
|
81
|
+
if (!doc) {
|
|
82
|
+
return context.error(HTTPStatus.NotFound, {
|
|
83
|
+
code: ACError.ResourceNotFound
|
|
84
|
+
});
|
|
85
|
+
}
|
|
86
|
+
const result = unsafe(await traverseDocument(doc, context.description, {
|
|
55
87
|
getters: true,
|
|
56
88
|
fromProperties: true,
|
|
57
89
|
recurseReferences: true
|
|
58
90
|
}));
|
|
59
|
-
return
|
|
91
|
+
return result;
|
|
60
92
|
};
|
|
@@ -1,12 +1,13 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.remove = void 0;
|
|
4
|
+
const types_1 = require("@aeriajs/types");
|
|
4
5
|
const common_1 = require("@aeriajs/common");
|
|
5
6
|
const index_js_1 = require("../../collection/index.js");
|
|
6
7
|
const remove = async (payload, context) => {
|
|
7
8
|
if (!payload.filters._id) {
|
|
8
|
-
return (
|
|
9
|
-
|
|
9
|
+
return context.error(types_1.HTTPStatus.NotFound, {
|
|
10
|
+
code: types_1.ACError.ResourceNotFound,
|
|
10
11
|
});
|
|
11
12
|
}
|
|
12
13
|
const filters = (0, common_1.unsafe)(await (0, index_js_1.traverseDocument)(payload.filters, context.description, {
|
|
@@ -14,8 +15,8 @@ const remove = async (payload, context) => {
|
|
|
14
15
|
}));
|
|
15
16
|
const target = await context.collection.model.findOne(filters);
|
|
16
17
|
if (!target) {
|
|
17
|
-
return (
|
|
18
|
-
|
|
18
|
+
return context.error(types_1.HTTPStatus.NotFound, {
|
|
19
|
+
code: types_1.ACError.ResourceNotFound,
|
|
19
20
|
});
|
|
20
21
|
}
|
|
21
22
|
await (0, index_js_1.cascadingRemove)(target, context);
|
|
@@ -1,10 +1,11 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
-
import {
|
|
2
|
+
import { HTTPStatus, ACError } from "@aeriajs/types";
|
|
3
|
+
import { unsafe } from "@aeriajs/common";
|
|
3
4
|
import { traverseDocument, cascadingRemove } from "../../collection/index.mjs";
|
|
4
5
|
export const remove = async (payload, context) => {
|
|
5
6
|
if (!payload.filters._id) {
|
|
6
|
-
return
|
|
7
|
-
|
|
7
|
+
return context.error(HTTPStatus.NotFound, {
|
|
8
|
+
code: ACError.ResourceNotFound
|
|
8
9
|
});
|
|
9
10
|
}
|
|
10
11
|
const filters = unsafe(await traverseDocument(payload.filters, context.description, {
|
|
@@ -12,8 +13,8 @@ export const remove = async (payload, context) => {
|
|
|
12
13
|
}));
|
|
13
14
|
const target = await context.collection.model.findOne(filters);
|
|
14
15
|
if (!target) {
|
|
15
|
-
return
|
|
16
|
-
|
|
16
|
+
return context.error(HTTPStatus.NotFound, {
|
|
17
|
+
code: ACError.ResourceNotFound
|
|
17
18
|
});
|
|
18
19
|
}
|
|
19
20
|
await cascadingRemove(target, context);
|
package/dist/use.d.ts
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
export declare const createAeria: () => Promise<import("@aeriajs/types").RouteContext<null> & import("@aeriajs/types").CollectionContext<
|
|
1
|
+
export declare const createAeria: () => Promise<import("@aeriajs/types").RouteContext<null> & import("@aeriajs/types").CollectionContext<import("@aeriajs/types").Description, any>>;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@aeriajs/core",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.89",
|
|
4
4
|
"description": "",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"module": "dist/index.mjs",
|
|
@@ -41,13 +41,13 @@
|
|
|
41
41
|
"mongodb-memory-server": "^9.2.0"
|
|
42
42
|
},
|
|
43
43
|
"peerDependencies": {
|
|
44
|
-
"@aeriajs/builtins": "^0.0.
|
|
45
|
-
"@aeriajs/common": "^0.0.
|
|
46
|
-
"@aeriajs/entrypoint": "^0.0.
|
|
47
|
-
"@aeriajs/http": "^0.0.
|
|
48
|
-
"@aeriajs/security": "^0.0.
|
|
49
|
-
"@aeriajs/types": "^0.0.
|
|
50
|
-
"@aeriajs/validation": "^0.0.
|
|
44
|
+
"@aeriajs/builtins": "^0.0.89",
|
|
45
|
+
"@aeriajs/common": "^0.0.55",
|
|
46
|
+
"@aeriajs/entrypoint": "^0.0.55",
|
|
47
|
+
"@aeriajs/http": "^0.0.63",
|
|
48
|
+
"@aeriajs/security": "^0.0.89",
|
|
49
|
+
"@aeriajs/types": "^0.0.52",
|
|
50
|
+
"@aeriajs/validation": "^0.0.58"
|
|
51
51
|
},
|
|
52
52
|
"dependencies": {
|
|
53
53
|
"mongodb": "^6.5.0",
|
|
@@ -1,4 +0,0 @@
|
|
|
1
|
-
import type { Description } from '@aeriajs/types';
|
|
2
|
-
export declare const normalizeProjection: <TDescription extends Pick<Description, "properties">, TProjectedProperties extends (keyof TDescription["properties"])[]>(properties: TProjectedProperties, description: TDescription) => {} | null;
|
|
3
|
-
export declare const fill: <TDocument extends OptionalId<any>>(item: TDocument & Record<string, any>, description: Pick<Description, 'properties' | 'freshItem'>) => Record<string, any> & TDocument;
|
|
4
|
-
export declare const prepareInsert: (payload: any, description: Pick<Description, 'properties' | 'form' | 'writable' | 'owned' | 'defaults'>) => Record<string, any>;
|
package/dist/collection/utils.js
DELETED
|
@@ -1,89 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.prepareInsert = exports.fill = exports.normalizeProjection = void 0;
|
|
4
|
-
const common_1 = require("@aeriajs/common");
|
|
5
|
-
const normalizeProjection = (properties, description) => {
|
|
6
|
-
const target = Array.from(properties);
|
|
7
|
-
if (target.length === 0) {
|
|
8
|
-
target.push(...Object.keys(description.properties));
|
|
9
|
-
}
|
|
10
|
-
const projection = target.reduce((a, key) => {
|
|
11
|
-
if (key !== '_id' && description.properties[key].hidden) {
|
|
12
|
-
return a;
|
|
13
|
-
}
|
|
14
|
-
return {
|
|
15
|
-
...a,
|
|
16
|
-
[key]: 1,
|
|
17
|
-
};
|
|
18
|
-
}, {});
|
|
19
|
-
return Object.keys(projection).length === 0
|
|
20
|
-
? null
|
|
21
|
-
: projection;
|
|
22
|
-
};
|
|
23
|
-
exports.normalizeProjection = normalizeProjection;
|
|
24
|
-
const fill = (item, description) => {
|
|
25
|
-
const itemCopy = Object.assign({}, item);
|
|
26
|
-
for (const key in itemCopy) {
|
|
27
|
-
if (itemCopy[key] === null) {
|
|
28
|
-
delete itemCopy[key];
|
|
29
|
-
}
|
|
30
|
-
}
|
|
31
|
-
return Object.assign((0, common_1.freshItem)(description), itemCopy);
|
|
32
|
-
};
|
|
33
|
-
exports.fill = fill;
|
|
34
|
-
const prepareInsert = (payload, description) => {
|
|
35
|
-
const rest = Object.assign({}, payload);
|
|
36
|
-
const docId = payload._id;
|
|
37
|
-
delete rest._id;
|
|
38
|
-
delete rest.created_at;
|
|
39
|
-
delete rest.updated_at;
|
|
40
|
-
const forbidden = (key) => {
|
|
41
|
-
return description.properties[key].readOnly
|
|
42
|
-
|| (description.writable && !description.writable.includes(key));
|
|
43
|
-
};
|
|
44
|
-
const prepareUpdate = () => Object.entries(rest).reduce((a, [key, value]) => {
|
|
45
|
-
// it's a mongodb operator
|
|
46
|
-
if (key[0] === '$') {
|
|
47
|
-
// it's not possible to use mongodb operators when user specifies
|
|
48
|
-
// writable properties nor when it is a creation operation
|
|
49
|
-
if (!description.writable && docId) {
|
|
50
|
-
a[key] = value;
|
|
51
|
-
}
|
|
52
|
-
return a;
|
|
53
|
-
}
|
|
54
|
-
if (forbidden(key)) {
|
|
55
|
-
return a;
|
|
56
|
-
}
|
|
57
|
-
if (value === null || value === undefined) {
|
|
58
|
-
a.$unset[key] = 1;
|
|
59
|
-
return a;
|
|
60
|
-
}
|
|
61
|
-
a.$set[key] = value;
|
|
62
|
-
return a;
|
|
63
|
-
}, {
|
|
64
|
-
$set: description.defaults || {},
|
|
65
|
-
$unset: {},
|
|
66
|
-
});
|
|
67
|
-
const prepareCreate = () => Object.entries(rest).reduce((a, [key, value]) => {
|
|
68
|
-
if (forbidden(key) || [
|
|
69
|
-
undefined,
|
|
70
|
-
null,
|
|
71
|
-
].includes(value)) {
|
|
72
|
-
return a;
|
|
73
|
-
}
|
|
74
|
-
return {
|
|
75
|
-
...a,
|
|
76
|
-
[key]: value,
|
|
77
|
-
};
|
|
78
|
-
}, description.defaults || {});
|
|
79
|
-
const what = docId
|
|
80
|
-
? prepareUpdate()
|
|
81
|
-
: prepareCreate();
|
|
82
|
-
Object.keys(what).forEach((k) => {
|
|
83
|
-
if (typeof what[k] === 'object' && JSON.stringify(what) === '{}') {
|
|
84
|
-
delete what[k];
|
|
85
|
-
}
|
|
86
|
-
});
|
|
87
|
-
return what;
|
|
88
|
-
};
|
|
89
|
-
exports.prepareInsert = prepareInsert;
|
|
@@ -1,76 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
import { freshItem } from "@aeriajs/common";
|
|
3
|
-
export const normalizeProjection = (properties, description) => {
|
|
4
|
-
const target = Array.from(properties);
|
|
5
|
-
if (target.length === 0) {
|
|
6
|
-
target.push(...Object.keys(description.properties));
|
|
7
|
-
}
|
|
8
|
-
const projection = target.reduce((a, key) => {
|
|
9
|
-
if (key !== "_id" && description.properties[key].hidden) {
|
|
10
|
-
return a;
|
|
11
|
-
}
|
|
12
|
-
return {
|
|
13
|
-
...a,
|
|
14
|
-
[key]: 1
|
|
15
|
-
};
|
|
16
|
-
}, {});
|
|
17
|
-
return Object.keys(projection).length === 0 ? null : projection;
|
|
18
|
-
};
|
|
19
|
-
export const fill = (item, description) => {
|
|
20
|
-
const itemCopy = Object.assign({}, item);
|
|
21
|
-
for (const key in itemCopy) {
|
|
22
|
-
if (itemCopy[key] === null) {
|
|
23
|
-
delete itemCopy[key];
|
|
24
|
-
}
|
|
25
|
-
}
|
|
26
|
-
return Object.assign(freshItem(description), itemCopy);
|
|
27
|
-
};
|
|
28
|
-
export const prepareInsert = (payload, description) => {
|
|
29
|
-
const rest = Object.assign({}, payload);
|
|
30
|
-
const docId = payload._id;
|
|
31
|
-
delete rest._id;
|
|
32
|
-
delete rest.created_at;
|
|
33
|
-
delete rest.updated_at;
|
|
34
|
-
const forbidden = (key) => {
|
|
35
|
-
return description.properties[key].readOnly || description.writable && !description.writable.includes(key);
|
|
36
|
-
};
|
|
37
|
-
const prepareUpdate = () => Object.entries(rest).reduce((a, [key, value]) => {
|
|
38
|
-
if (key[0] === "$") {
|
|
39
|
-
if (!description.writable && docId) {
|
|
40
|
-
a[key] = value;
|
|
41
|
-
}
|
|
42
|
-
return a;
|
|
43
|
-
}
|
|
44
|
-
if (forbidden(key)) {
|
|
45
|
-
return a;
|
|
46
|
-
}
|
|
47
|
-
if (value === null || value === void 0) {
|
|
48
|
-
a.$unset[key] = 1;
|
|
49
|
-
return a;
|
|
50
|
-
}
|
|
51
|
-
a.$set[key] = value;
|
|
52
|
-
return a;
|
|
53
|
-
}, {
|
|
54
|
-
$set: description.defaults || {},
|
|
55
|
-
$unset: {}
|
|
56
|
-
});
|
|
57
|
-
const prepareCreate = () => Object.entries(rest).reduce((a, [key, value]) => {
|
|
58
|
-
if (forbidden(key) || [
|
|
59
|
-
void 0,
|
|
60
|
-
null
|
|
61
|
-
].includes(value)) {
|
|
62
|
-
return a;
|
|
63
|
-
}
|
|
64
|
-
return {
|
|
65
|
-
...a,
|
|
66
|
-
[key]: value
|
|
67
|
-
};
|
|
68
|
-
}, description.defaults || {});
|
|
69
|
-
const what = docId ? prepareUpdate() : prepareCreate();
|
|
70
|
-
Object.keys(what).forEach((k) => {
|
|
71
|
-
if (typeof what[k] === "object" && JSON.stringify(what) === "{}") {
|
|
72
|
-
delete what[k];
|
|
73
|
-
}
|
|
74
|
-
});
|
|
75
|
-
return what;
|
|
76
|
-
};
|