unconventional 1.12.0 → 1.13.0
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/core/abstractbase.middleware.d.ts +21 -0
- package/dist/core/abstractbase.middleware.js +58 -0
- package/dist/core/index.d.ts +1 -0
- package/dist/core/index.js +1 -0
- package/dist/utils/middleware.utils.d.ts +5 -0
- package/dist/utils/middleware.utils.js +9 -1
- package/dist/utils/server.utils.d.ts +6 -1
- package/package.json +1 -1
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { BaseModel } from "./base.model";
|
|
2
|
+
/** A predicate that matches a model to a given condition */
|
|
3
|
+
export type ModelPredicate = (model: typeof BaseModel) => boolean;
|
|
4
|
+
/** Middleware base class with methods that can find the ancestors of a model */
|
|
5
|
+
export declare class AbstractBaseMiddleware<M extends typeof BaseModel> {
|
|
6
|
+
protected model: M;
|
|
7
|
+
constructor(model: M);
|
|
8
|
+
/**
|
|
9
|
+
* Finds an ancestor that matches the predicate
|
|
10
|
+
* @param id - The ID of the model to find the ancestor for
|
|
11
|
+
* @param predicate - The predicate to match the ancestor
|
|
12
|
+
* @returns The ancestor that matches the predicate or null if no ancestor is found
|
|
13
|
+
*/
|
|
14
|
+
findAncestor(id: string | number, predicate: ModelPredicate): Promise<any | null>;
|
|
15
|
+
/**
|
|
16
|
+
* Builds the relation path to reach an ancestor that matches the predicate
|
|
17
|
+
* @param predicate - The predicate to match the ancestor
|
|
18
|
+
* @returns The relation path (e.g. ['comments', 'post', 'user']) to the ancestor or null if no ancestor is found
|
|
19
|
+
*/
|
|
20
|
+
protected buildAncestralPath(predicate: ModelPredicate): string[] | null;
|
|
21
|
+
}
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.AbstractBaseMiddleware = void 0;
|
|
4
|
+
const types_1 = require("../types");
|
|
5
|
+
const utils_1 = require("../utils");
|
|
6
|
+
/** Middleware base class with methods that can find the ancestors of a model */
|
|
7
|
+
class AbstractBaseMiddleware {
|
|
8
|
+
model;
|
|
9
|
+
constructor(model) {
|
|
10
|
+
this.model = model;
|
|
11
|
+
}
|
|
12
|
+
/**
|
|
13
|
+
* Finds an ancestor that matches the predicate
|
|
14
|
+
* @param id - The ID of the model to find the ancestor for
|
|
15
|
+
* @param predicate - The predicate to match the ancestor
|
|
16
|
+
* @returns The ancestor that matches the predicate or null if no ancestor is found
|
|
17
|
+
*/
|
|
18
|
+
async findAncestor(id, predicate) {
|
|
19
|
+
const expansion = this.buildAncestralPath(predicate);
|
|
20
|
+
if (!expansion)
|
|
21
|
+
return null;
|
|
22
|
+
const result = await this.model.findById(id, {
|
|
23
|
+
expand: (0, utils_1.buildExpansionString)(expansion)
|
|
24
|
+
});
|
|
25
|
+
if (!result)
|
|
26
|
+
return null;
|
|
27
|
+
// Navigate through the expanded chain to get the owner
|
|
28
|
+
return expansion.reduce((obj, key) => obj?.[key], result);
|
|
29
|
+
}
|
|
30
|
+
/**
|
|
31
|
+
* Builds the relation path to reach an ancestor that matches the predicate
|
|
32
|
+
* @param predicate - The predicate to match the ancestor
|
|
33
|
+
* @returns The relation path (e.g. ['comments', 'post', 'user']) to the ancestor or null if no ancestor is found
|
|
34
|
+
*/
|
|
35
|
+
buildAncestralPath(predicate) {
|
|
36
|
+
let currentModel = this.model;
|
|
37
|
+
const path = [];
|
|
38
|
+
const visited = new Set();
|
|
39
|
+
while (!visited.has(currentModel)) {
|
|
40
|
+
// Found model that matches predicate
|
|
41
|
+
if (predicate(currentModel)) {
|
|
42
|
+
return path;
|
|
43
|
+
}
|
|
44
|
+
visited.add(currentModel);
|
|
45
|
+
// Find first BelongsTo relation
|
|
46
|
+
const belongsToRelation = Object.entries(currentModel.schema.props)
|
|
47
|
+
.find(([_, prop]) => prop.relation?.type === types_1.RelationType.BelongsTo);
|
|
48
|
+
if (!belongsToRelation)
|
|
49
|
+
return null;
|
|
50
|
+
const [relationKey, prop] = belongsToRelation;
|
|
51
|
+
const parentModel = (0, utils_1.getRelationModel)(prop.relation.model);
|
|
52
|
+
path.push(relationKey);
|
|
53
|
+
currentModel = parentModel;
|
|
54
|
+
}
|
|
55
|
+
return null; // Circular reference found or no matching owner
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
exports.AbstractBaseMiddleware = AbstractBaseMiddleware;
|
package/dist/core/index.d.ts
CHANGED
package/dist/core/index.js
CHANGED
|
@@ -15,6 +15,7 @@ var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
|
15
15
|
};
|
|
16
16
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
17
17
|
__exportStar(require("./abstractbase.controller"), exports);
|
|
18
|
+
__exportStar(require("./abstractbase.middleware"), exports);
|
|
18
19
|
__exportStar(require("./api-error"), exports);
|
|
19
20
|
__exportStar(require("./base.cache"), exports);
|
|
20
21
|
__exportStar(require("./base.model"), exports);
|
|
@@ -5,3 +5,8 @@ import { BaseHandler, Env } from "../types/api.types";
|
|
|
5
5
|
* the logical OR of their results.
|
|
6
6
|
*/
|
|
7
7
|
export declare function Or<E extends Env = Env, P extends string = any, I extends Input = Input, T extends BaseHandler<E, P, I> | MiddlewareHandler<E, P, I> = MiddlewareHandler<E, P, I>>(...methods: Array<T>): MiddlewareHandler<E, P, I>;
|
|
8
|
+
/**
|
|
9
|
+
* Converts an array of relation paths into a nested expansion string
|
|
10
|
+
* @example buildExpansionString(['comments', 'post', 'user']) => 'comments[post[user]]'
|
|
11
|
+
*/
|
|
12
|
+
export declare function buildExpansionString(path: string[]): string;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.Or = void 0;
|
|
3
|
+
exports.buildExpansionString = exports.Or = void 0;
|
|
4
4
|
/**
|
|
5
5
|
* Combines any number of RequestHandlers into one function that performs
|
|
6
6
|
* the logical OR of their results.
|
|
@@ -16,3 +16,11 @@ function Or(...methods) {
|
|
|
16
16
|
};
|
|
17
17
|
}
|
|
18
18
|
exports.Or = Or;
|
|
19
|
+
/**
|
|
20
|
+
* Converts an array of relation paths into a nested expansion string
|
|
21
|
+
* @example buildExpansionString(['comments', 'post', 'user']) => 'comments[post[user]]'
|
|
22
|
+
*/
|
|
23
|
+
function buildExpansionString(path) {
|
|
24
|
+
return path.reduceRight((acc, curr) => acc ? `${curr}[${acc}]` : curr, '');
|
|
25
|
+
}
|
|
26
|
+
exports.buildExpansionString = buildExpansionString;
|
|
@@ -1,7 +1,12 @@
|
|
|
1
|
+
/// <reference types="@cloudflare/workers-types" />
|
|
1
2
|
import { DBFactory } from "../types";
|
|
3
|
+
import { Context } from "hono";
|
|
4
|
+
import { HTTPResponseError } from "hono/types";
|
|
2
5
|
/** Default CORS middleware permitting all origins and methods */
|
|
3
6
|
export declare const defaultCors: import("hono").MiddlewareHandler;
|
|
4
7
|
/** Binds the database proxy to the BaseModel */
|
|
5
8
|
export declare const bindDatabase: (getDB: DBFactory) => (ctx: any, next: any) => Promise<void>;
|
|
6
9
|
/** Catches and formats errors in a standard way */
|
|
7
|
-
export declare const defaultErrorHandler: (err:
|
|
10
|
+
export declare const defaultErrorHandler: (err: Error | HTTPResponseError, ctx: Context) => Response & import("hono").TypedResponse<{
|
|
11
|
+
error: string;
|
|
12
|
+
}, import("hono/utils/http-status").StatusCode, "json">;
|