unconventional 0.0.3 → 0.0.4
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.controller.d.ts +34 -0
- package/dist/core/abstractbase.controller.js +101 -10
- package/dist/core/api-error.js +5 -1
- package/dist/core/base.cache.d.ts +6 -0
- package/dist/core/base.cache.js +31 -14
- package/dist/core/base.model.js +51 -46
- package/dist/core/base.options.d.ts +12 -0
- package/dist/core/base.options.js +2 -1
- package/dist/core/base.service.d.ts +46 -0
- package/dist/core/base.service.js +82 -30
- package/dist/core/index.js +22 -6
- package/dist/core/pg.driver.d.ts +1 -0
- package/dist/core/pg.driver.js +6 -1
- package/dist/decorators/index.decorator.d.ts +10 -0
- package/dist/decorators/index.decorator.js +16 -2
- package/dist/decorators/index.js +20 -4
- package/dist/decorators/prop.decorator.d.ts +14 -0
- package/dist/decorators/prop.decorator.js +19 -1
- package/dist/decorators/timestamp.decorator.d.ts +8 -0
- package/dist/decorators/timestamp.decorator.js +14 -2
- package/dist/decorators/utils.d.ts +5 -0
- package/dist/decorators/utils.js +10 -1
- package/dist/index.js +21 -5
- package/dist/server.d.ts +11 -0
- package/dist/server.js +30 -10
- package/dist/types/api.types.js +11 -8
- package/dist/types/db.types.js +10 -7
- package/dist/types/decorator.types.d.ts +31 -0
- package/dist/types/decorator.types.js +9 -2
- package/dist/types/index.js +20 -4
- package/dist/types/server.types.js +2 -1
- package/dist/utils/api.utils.d.ts +15 -0
- package/dist/utils/api.utils.js +34 -8
- package/dist/utils/array.utils.d.ts +2 -0
- package/dist/utils/array.utils.js +9 -2
- package/dist/utils/cache.utils.js +9 -2
- package/dist/utils/crypto.utils.d.ts +1 -0
- package/dist/utils/crypto.utils.js +7 -1
- package/dist/utils/db.utils.d.ts +5 -0
- package/dist/utils/db.utils.js +55 -36
- package/dist/utils/function.utils.d.ts +1 -0
- package/dist/utils/function.utils.js +6 -3
- package/dist/utils/index.js +24 -8
- package/dist/utils/middleware.utils.d.ts +4 -0
- package/dist/utils/middleware.utils.js +9 -1
- package/dist/utils/server.utils.d.ts +3 -0
- package/dist/utils/server.utils.js +20 -9
- package/package.json +1 -1
|
@@ -1,4 +1,18 @@
|
|
|
1
1
|
import BaseModel from '../core/base.model';
|
|
2
2
|
import type { PropOptions } from '../types/decorator.types';
|
|
3
|
+
/**
|
|
4
|
+
* Set Property Options for the property below
|
|
5
|
+
* @param options The Mongo options to Set
|
|
6
|
+
* @example
|
|
7
|
+
* ```ts
|
|
8
|
+
* class ClassName {
|
|
9
|
+
* @prop()
|
|
10
|
+
* public someProp?: string;
|
|
11
|
+
*
|
|
12
|
+
* @prop({ type: String[] })
|
|
13
|
+
* public someArrayProp?: string[];
|
|
14
|
+
* }
|
|
15
|
+
* ```
|
|
16
|
+
*/
|
|
3
17
|
declare function prop<Target = any, Source extends typeof BaseModel = any, Pivot extends typeof BaseModel = any>(options?: PropOptions<Target, Source, Pivot>): PropertyDecorator;
|
|
4
18
|
export { prop as Prop, prop };
|
|
@@ -1,3 +1,20 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.prop = exports.Prop = void 0;
|
|
4
|
+
/**
|
|
5
|
+
* Set Property Options for the property below
|
|
6
|
+
* @param options The Mongo options to Set
|
|
7
|
+
* @example
|
|
8
|
+
* ```ts
|
|
9
|
+
* class ClassName {
|
|
10
|
+
* @prop()
|
|
11
|
+
* public someProp?: string;
|
|
12
|
+
*
|
|
13
|
+
* @prop({ type: String[] })
|
|
14
|
+
* public someArrayProp?: string[];
|
|
15
|
+
* }
|
|
16
|
+
* ```
|
|
17
|
+
*/
|
|
1
18
|
function prop(options) {
|
|
2
19
|
return (target, key) => {
|
|
3
20
|
const parent = Object.getPrototypeOf(target.constructor);
|
|
@@ -10,4 +27,5 @@ function prop(options) {
|
|
|
10
27
|
child.schema.props[key] = options || {};
|
|
11
28
|
};
|
|
12
29
|
}
|
|
13
|
-
|
|
30
|
+
exports.Prop = prop;
|
|
31
|
+
exports.prop = prop;
|
|
@@ -1,4 +1,12 @@
|
|
|
1
1
|
import { TimeStamped } from '../core/base.model';
|
|
2
2
|
import { TypedClassDecorator } from '../types/decorator.types';
|
|
3
|
+
/**
|
|
4
|
+
* Adds createdAt and updatedAt fields to the class and updates them on create/update calls.
|
|
5
|
+
* @example Example:
|
|
6
|
+
* ```ts
|
|
7
|
+
* @timestamp()
|
|
8
|
+
* class ClassName {}
|
|
9
|
+
* ```
|
|
10
|
+
*/
|
|
3
11
|
export declare function timestamp<T extends typeof TimeStamped>(): TypedClassDecorator<T>;
|
|
4
12
|
export { timestamp as Timestamp };
|
|
@@ -1,6 +1,18 @@
|
|
|
1
|
-
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.Timestamp = exports.timestamp = void 0;
|
|
4
|
+
/**
|
|
5
|
+
* Adds createdAt and updatedAt fields to the class and updates them on create/update calls.
|
|
6
|
+
* @example Example:
|
|
7
|
+
* ```ts
|
|
8
|
+
* @timestamp()
|
|
9
|
+
* class ClassName {}
|
|
10
|
+
* ```
|
|
11
|
+
*/
|
|
12
|
+
function timestamp() {
|
|
2
13
|
return (target) => {
|
|
3
14
|
target.schema.timestamped = true;
|
|
4
15
|
};
|
|
5
16
|
}
|
|
6
|
-
|
|
17
|
+
exports.timestamp = timestamp;
|
|
18
|
+
exports.Timestamp = timestamp;
|
package/dist/decorators/utils.js
CHANGED
|
@@ -1,3 +1,12 @@
|
|
|
1
|
-
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.getName = void 0;
|
|
4
|
+
/**
|
|
5
|
+
* Returns the target name
|
|
6
|
+
* if target.constructor.name is "Function", return "target.name", otherwise "target.constructor.name"
|
|
7
|
+
* @param target The target to determine
|
|
8
|
+
*/
|
|
9
|
+
function getName(target) {
|
|
2
10
|
return target.constructor?.name === 'Function' ? target.name : target.constructor.name;
|
|
3
11
|
}
|
|
12
|
+
exports.getName = getName;
|
package/dist/index.js
CHANGED
|
@@ -1,5 +1,21 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
1
|
+
"use strict";
|
|
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);
|
|
15
|
+
};
|
|
16
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
17
|
+
__exportStar(require("./core"), exports);
|
|
18
|
+
__exportStar(require("./decorators"), exports);
|
|
19
|
+
__exportStar(require("./types"), exports);
|
|
20
|
+
__exportStar(require("./utils"), exports);
|
|
21
|
+
__exportStar(require("./server"), exports);
|
package/dist/server.d.ts
CHANGED
|
@@ -2,6 +2,17 @@
|
|
|
2
2
|
import { Hono } from "hono";
|
|
3
3
|
import type { Env } from "./types/api.types";
|
|
4
4
|
import type { ServerConfig } from "./types/server.types";
|
|
5
|
+
/**
|
|
6
|
+
* A wrapper around Hono that provides some default configuration
|
|
7
|
+
* and a simple interface for starting the server.
|
|
8
|
+
*
|
|
9
|
+
* @example
|
|
10
|
+
* const server = new BackendServer({
|
|
11
|
+
* name: "My Server",
|
|
12
|
+
* basePath: "/api",
|
|
13
|
+
* getDB: ctx => new DBProxy(ctx)
|
|
14
|
+
* });
|
|
15
|
+
*/
|
|
5
16
|
export declare class BackendServer {
|
|
6
17
|
private _app;
|
|
7
18
|
configured: boolean;
|
package/dist/server.js
CHANGED
|
@@ -1,12 +1,26 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.BackendServer = void 0;
|
|
4
|
+
const hono_1 = require("hono");
|
|
5
|
+
const cloudflare_pages_1 = require("hono/cloudflare-pages");
|
|
6
|
+
const utils_1 = require("./utils");
|
|
7
|
+
const cors_1 = require("hono/cors");
|
|
8
|
+
/**
|
|
9
|
+
* A wrapper around Hono that provides some default configuration
|
|
10
|
+
* and a simple interface for starting the server.
|
|
11
|
+
*
|
|
12
|
+
* @example
|
|
13
|
+
* const server = new BackendServer({
|
|
14
|
+
* name: "My Server",
|
|
15
|
+
* basePath: "/api",
|
|
16
|
+
* getDB: ctx => new DBProxy(ctx)
|
|
17
|
+
* });
|
|
18
|
+
*/
|
|
19
|
+
class BackendServer {
|
|
6
20
|
_app;
|
|
7
21
|
configured = false;
|
|
8
22
|
constructor(config) {
|
|
9
|
-
this._app = new Hono();
|
|
23
|
+
this._app = new hono_1.Hono();
|
|
10
24
|
if (config)
|
|
11
25
|
this.configure(config);
|
|
12
26
|
}
|
|
@@ -16,17 +30,23 @@ export class BackendServer {
|
|
|
16
30
|
configure(config) {
|
|
17
31
|
if (this.configured)
|
|
18
32
|
throw new Error("Cannot reconfigure server");
|
|
33
|
+
// Base path
|
|
19
34
|
if (config.basePath)
|
|
20
35
|
this._app = this._app.basePath(config.basePath);
|
|
21
|
-
|
|
22
|
-
this._app.use(
|
|
23
|
-
|
|
36
|
+
// Database binding
|
|
37
|
+
this._app.use((0, utils_1.bindDatabase)(config.getDB));
|
|
38
|
+
// CORS
|
|
39
|
+
this._app.use(config.cors ? (0, cors_1.cors)(config.cors) : utils_1.defaultCors);
|
|
40
|
+
// Error handling
|
|
41
|
+
this._app.onError(utils_1.defaultErrorHandler);
|
|
42
|
+
// Standard middleware
|
|
24
43
|
if (config.middleware)
|
|
25
44
|
this._app.use(...config.middleware);
|
|
26
45
|
this.configured = true;
|
|
27
46
|
return this;
|
|
28
47
|
}
|
|
29
48
|
start() {
|
|
30
|
-
return handle(this._app);
|
|
49
|
+
return (0, cloudflare_pages_1.handle)(this._app);
|
|
31
50
|
}
|
|
32
51
|
}
|
|
52
|
+
exports.BackendServer = BackendServer;
|
package/dist/types/api.types.js
CHANGED
|
@@ -1,17 +1,20 @@
|
|
|
1
|
-
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.BaseEnvKey = exports.MaxCacheTTL = exports.DefaultCacheTTL = exports.CachePrefix = exports.Query = void 0;
|
|
4
|
+
var Query;
|
|
2
5
|
(function (Query) {
|
|
3
6
|
Query["Expand"] = "expand";
|
|
4
|
-
})(Query || (Query = {}));
|
|
5
|
-
|
|
7
|
+
})(Query || (exports.Query = Query = {}));
|
|
8
|
+
var CachePrefix;
|
|
6
9
|
(function (CachePrefix) {
|
|
7
10
|
CachePrefix["Record"] = "rec_";
|
|
8
11
|
CachePrefix["Page"] = "page_";
|
|
9
|
-
})(CachePrefix || (CachePrefix = {}));
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
12
|
+
})(CachePrefix || (exports.CachePrefix = CachePrefix = {}));
|
|
13
|
+
exports.DefaultCacheTTL = 900; // 15 minutes
|
|
14
|
+
exports.MaxCacheTTL = 2147483647; // 68 years
|
|
15
|
+
var BaseEnvKey;
|
|
13
16
|
(function (BaseEnvKey) {
|
|
14
17
|
BaseEnvKey["ownerId"] = "ownerId";
|
|
15
18
|
BaseEnvKey["isPrivileged"] = "isPrivileged";
|
|
16
|
-
})(BaseEnvKey || (BaseEnvKey = {}));
|
|
19
|
+
})(BaseEnvKey || (exports.BaseEnvKey = BaseEnvKey = {}));
|
|
17
20
|
;
|
package/dist/types/db.types.js
CHANGED
|
@@ -1,12 +1,15 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.SqlAction = exports.andOrPattern = exports.ValidSortDirections = exports.NullSqlOperators = exports.ValidSqlOperators = void 0;
|
|
4
|
+
const unconventional_pg_queries_1 = require("unconventional-pg-queries");
|
|
5
|
+
exports.ValidSqlOperators = Object.values(unconventional_pg_queries_1.SqlWhereOperator);
|
|
6
|
+
exports.NullSqlOperators = [unconventional_pg_queries_1.SqlWhereOperator.IsNull, unconventional_pg_queries_1.SqlWhereOperator.IsNotNull];
|
|
7
|
+
exports.ValidSortDirections = Object.values(unconventional_pg_queries_1.SqlDirection);
|
|
8
|
+
exports.andOrPattern = /\s(?=AND|OR)/;
|
|
9
|
+
var SqlAction;
|
|
7
10
|
(function (SqlAction) {
|
|
8
11
|
SqlAction["Select"] = "SELECT";
|
|
9
12
|
SqlAction["Insert"] = "INSERT";
|
|
10
13
|
SqlAction["Update"] = "UPDATE";
|
|
11
14
|
SqlAction["Delete"] = "DELETE";
|
|
12
|
-
})(SqlAction || (SqlAction = {}));
|
|
15
|
+
})(SqlAction || (exports.SqlAction = SqlAction = {}));
|
|
@@ -1,38 +1,69 @@
|
|
|
1
1
|
import BaseModel from "../core/base.model";
|
|
2
2
|
export declare type TypedClassDecorator<T> = (target: T) => T | void;
|
|
3
|
+
/** Definition of a sortable index. 1=ascending, -1=descending */
|
|
3
4
|
export type IndexDefinition<T> = {
|
|
4
5
|
[P in keyof T]?: 1 | -1;
|
|
5
6
|
};
|
|
7
|
+
/** Options to pass to MongoDB when creating an Index */
|
|
6
8
|
export interface IndexOptions {
|
|
7
9
|
unique?: boolean;
|
|
8
10
|
}
|
|
11
|
+
/**
|
|
12
|
+
* Type for the Values stored in the Reflection for Indexes
|
|
13
|
+
* @example
|
|
14
|
+
* ```ts
|
|
15
|
+
* const indices: IIndexArray[] = Reflect.getMetadata(DecoratorKeys.Index, target) || []);
|
|
16
|
+
* ```
|
|
17
|
+
*/
|
|
9
18
|
export interface IndexSummary<T = any> {
|
|
10
19
|
definition: IndexDefinition<T>;
|
|
11
20
|
options?: IndexOptions;
|
|
12
21
|
}
|
|
22
|
+
/** Type of relational field between two models */
|
|
13
23
|
export declare enum RelationType {
|
|
14
24
|
HasOne = 0,
|
|
15
25
|
HasMany = 1,
|
|
16
26
|
ManyToMany = 2,
|
|
17
27
|
BelongsTo = 3
|
|
18
28
|
}
|
|
29
|
+
/** Details of the pivot table connecting two models */
|
|
19
30
|
export interface RelationPivot<T extends typeof BaseModel = any> {
|
|
31
|
+
/** The model to use for the pivot table */
|
|
20
32
|
model: T;
|
|
33
|
+
/** The field on this model related to the source */
|
|
21
34
|
from: keyof InstanceType<T>;
|
|
35
|
+
/** The field on this model related to the target */
|
|
22
36
|
to: keyof InstanceType<T>;
|
|
23
37
|
}
|
|
24
38
|
export interface Relation<Target extends typeof BaseModel = any, Source extends typeof BaseModel = any, Pivot extends typeof BaseModel = any> {
|
|
39
|
+
/** The type of relation */
|
|
25
40
|
type: RelationType;
|
|
41
|
+
/** The model to relate to */
|
|
26
42
|
model: Target;
|
|
43
|
+
/** The field on this model to use for the relation */
|
|
27
44
|
from: keyof InstanceType<Source>;
|
|
45
|
+
/** The field on the related model to use for the relation */
|
|
28
46
|
to: keyof InstanceType<Target>;
|
|
47
|
+
/** Details of the pivot table connecting this model to the related model */
|
|
29
48
|
through?: RelationPivot<Pivot>;
|
|
30
49
|
}
|
|
50
|
+
/** Options to pass to MongoDB when creating or validating a property */
|
|
31
51
|
export interface PropOptions<T = any, S extends typeof BaseModel = any, P extends typeof BaseModel = any> {
|
|
52
|
+
/**
|
|
53
|
+
* Is this value required?
|
|
54
|
+
* @default false
|
|
55
|
+
*/
|
|
32
56
|
required?: boolean;
|
|
57
|
+
/** Is this Property unique?
|
|
58
|
+
* @default false
|
|
59
|
+
*/
|
|
33
60
|
unique?: boolean;
|
|
61
|
+
/** Only accept Values from the Enum(|Array) */
|
|
34
62
|
enum?: any;
|
|
63
|
+
/** Give the Property a default Value */
|
|
35
64
|
default?: T | (() => T);
|
|
65
|
+
/** Relational field data */
|
|
36
66
|
relation?: T extends typeof BaseModel ? Relation<T, S, P> : never;
|
|
37
67
|
}
|
|
68
|
+
/** Type for the Values stored in the Reflection for Properties */
|
|
38
69
|
export type PropSummary<Target = any, Source extends typeof BaseModel = any> = Record<keyof Source, PropOptions<Target, Source>>;
|
|
@@ -1,7 +1,14 @@
|
|
|
1
|
-
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.RelationType = void 0;
|
|
4
|
+
//#endregion
|
|
5
|
+
//#region Relation
|
|
6
|
+
/** Type of relational field between two models */
|
|
7
|
+
var RelationType;
|
|
2
8
|
(function (RelationType) {
|
|
3
9
|
RelationType[RelationType["HasOne"] = 0] = "HasOne";
|
|
4
10
|
RelationType[RelationType["HasMany"] = 1] = "HasMany";
|
|
5
11
|
RelationType[RelationType["ManyToMany"] = 2] = "ManyToMany";
|
|
6
12
|
RelationType[RelationType["BelongsTo"] = 3] = "BelongsTo";
|
|
7
|
-
})(RelationType || (RelationType = {}));
|
|
13
|
+
})(RelationType || (exports.RelationType = RelationType = {}));
|
|
14
|
+
//#endregion
|
package/dist/types/index.js
CHANGED
|
@@ -1,4 +1,20 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
1
|
+
"use strict";
|
|
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);
|
|
15
|
+
};
|
|
16
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
17
|
+
__exportStar(require("./api.types"), exports);
|
|
18
|
+
__exportStar(require("./db.types"), exports);
|
|
19
|
+
__exportStar(require("./decorator.types"), exports);
|
|
20
|
+
__exportStar(require("./server.types"), exports);
|
|
@@ -1 +1,2 @@
|
|
|
1
|
-
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
@@ -1,8 +1,23 @@
|
|
|
1
1
|
import { AndOr } from "unconventional-pg-queries";
|
|
2
|
+
/**
|
|
3
|
+
* Decompose an expand-formatted string into an array of its parts.
|
|
4
|
+
* @example
|
|
5
|
+
* parseExpandString('a,b,c') // ['a', 'b', 'c']
|
|
6
|
+
* parseExpandString('a[b,c],d[e,f],g') // ['a[b,c]', 'd[e,f]', 'g']
|
|
7
|
+
*/
|
|
2
8
|
export declare function parseExpandString(expand: string): string[];
|
|
9
|
+
/**
|
|
10
|
+
* Split an expand-formatted into its parent and child parts.
|
|
11
|
+
* @example
|
|
12
|
+
* splitExpandUnit('a') // { parent: 'a', children: '' }
|
|
13
|
+
* splitExpandUnit('a[b,c]') // { parent: 'a', children: 'b,c' }
|
|
14
|
+
* splitExpandUnit('a[b,c[d,e]]') // { parent: 'a', children: 'b,c[d,e]' }
|
|
15
|
+
*/
|
|
3
16
|
export declare function splitExpandUnit(input: string): {
|
|
4
17
|
parent: string;
|
|
5
18
|
children: string;
|
|
6
19
|
};
|
|
20
|
+
/** Parse a filter string and replace clauses that reference the target field with the provided replacement. */
|
|
7
21
|
export declare function replaceFilter(filter: string | string[] | undefined, target: string, replacement: string, andOr?: AndOr): string;
|
|
22
|
+
/** Check if the filter has the specified target field. */
|
|
8
23
|
export declare function hasFilter(filter: string | string[] | undefined, target: string): boolean;
|
package/dist/utils/api.utils.js
CHANGED
|
@@ -1,9 +1,18 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.hasFilter = exports.replaceFilter = exports.splitExpandUnit = exports.parseExpandString = void 0;
|
|
4
|
+
const unconventional_pg_queries_1 = require("unconventional-pg-queries");
|
|
5
|
+
const db_types_1 = require("../types/db.types");
|
|
3
6
|
const defaultTarget = ',';
|
|
4
7
|
const openBracket = '[';
|
|
5
8
|
const closeBracket = ']';
|
|
6
|
-
|
|
9
|
+
/**
|
|
10
|
+
* Decompose an expand-formatted string into an array of its parts.
|
|
11
|
+
* @example
|
|
12
|
+
* parseExpandString('a,b,c') // ['a', 'b', 'c']
|
|
13
|
+
* parseExpandString('a[b,c],d[e,f],g') // ['a[b,c]', 'd[e,f]', 'g']
|
|
14
|
+
*/
|
|
15
|
+
function parseExpandString(expand) {
|
|
7
16
|
const text = expand.trim();
|
|
8
17
|
if (!text)
|
|
9
18
|
return [];
|
|
@@ -11,36 +20,53 @@ export function parseExpandString(expand) {
|
|
|
11
20
|
let word = '';
|
|
12
21
|
let bracketCount = 0;
|
|
13
22
|
for (const char of text) {
|
|
23
|
+
// If we encounter a comma and we're not inside brackets, push the word
|
|
14
24
|
if (bracketCount === 0 && char === defaultTarget) {
|
|
15
25
|
result.push(`${word}`);
|
|
16
26
|
word = '';
|
|
27
|
+
// Otherwise, add the character to the word
|
|
17
28
|
}
|
|
18
29
|
else {
|
|
19
30
|
word += char;
|
|
31
|
+
// If we encounter a bracket, increment or decrement the bracket count
|
|
20
32
|
if (char === openBracket)
|
|
21
33
|
bracketCount++;
|
|
22
34
|
else if (char === closeBracket)
|
|
23
35
|
bracketCount--;
|
|
24
36
|
}
|
|
25
37
|
}
|
|
38
|
+
// Push the last word
|
|
26
39
|
result.push(`${word}`);
|
|
27
40
|
return result;
|
|
28
41
|
}
|
|
29
|
-
|
|
42
|
+
exports.parseExpandString = parseExpandString;
|
|
43
|
+
/**
|
|
44
|
+
* Split an expand-formatted into its parent and child parts.
|
|
45
|
+
* @example
|
|
46
|
+
* splitExpandUnit('a') // { parent: 'a', children: '' }
|
|
47
|
+
* splitExpandUnit('a[b,c]') // { parent: 'a', children: 'b,c' }
|
|
48
|
+
* splitExpandUnit('a[b,c[d,e]]') // { parent: 'a', children: 'b,c[d,e]' }
|
|
49
|
+
*/
|
|
50
|
+
function splitExpandUnit(input) {
|
|
30
51
|
const index = input.indexOf(openBracket);
|
|
31
52
|
if (index === -1)
|
|
32
53
|
return { parent: input, children: '' };
|
|
33
54
|
return { parent: input.slice(0, index), children: input.slice(index + 1, -1) };
|
|
34
55
|
}
|
|
35
|
-
|
|
56
|
+
exports.splitExpandUnit = splitExpandUnit;
|
|
57
|
+
/** Parse a filter string and replace clauses that reference the target field with the provided replacement. */
|
|
58
|
+
function replaceFilter(filter, target, replacement, andOr = unconventional_pg_queries_1.AndOr.And) {
|
|
36
59
|
if (!filter)
|
|
37
60
|
return replacement;
|
|
38
|
-
const otherFilters = filter.split(andOrPattern).flatMap(x => x.includes(target) ? [] : x);
|
|
61
|
+
const otherFilters = filter.split(db_types_1.andOrPattern).flatMap(x => x.includes(target) ? [] : x);
|
|
39
62
|
otherFilters.push(`${otherFilters.length ? `${andOr} ` : ''}${replacement}`);
|
|
40
63
|
return otherFilters.join(' ');
|
|
41
64
|
}
|
|
42
|
-
|
|
65
|
+
exports.replaceFilter = replaceFilter;
|
|
66
|
+
/** Check if the filter has the specified target field. */
|
|
67
|
+
function hasFilter(filter, target) {
|
|
43
68
|
if (!filter)
|
|
44
69
|
return false;
|
|
45
|
-
return filter.split(andOrPattern).some(x => x.startsWith(target));
|
|
70
|
+
return filter.split(db_types_1.andOrPattern).some(x => x.startsWith(target));
|
|
46
71
|
}
|
|
72
|
+
exports.hasFilter = hasFilter;
|
|
@@ -1,2 +1,4 @@
|
|
|
1
|
+
/** Compares two arrays and returns true if they contain the same elements, regardless of order */
|
|
1
2
|
export declare const equalArrays: <T>(a: T[], b: T[]) => boolean;
|
|
3
|
+
/** Checks whether an object has no keys and/or the value for every key is undefined */
|
|
2
4
|
export declare function isEmpty(obj: any): boolean;
|
|
@@ -1,4 +1,8 @@
|
|
|
1
|
-
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.isEmpty = exports.equalArrays = void 0;
|
|
4
|
+
/** Compares two arrays and returns true if they contain the same elements, regardless of order */
|
|
5
|
+
const equalArrays = (a, b) => {
|
|
2
6
|
if (a.length !== b.length)
|
|
3
7
|
return false;
|
|
4
8
|
const clone = [...b];
|
|
@@ -12,9 +16,12 @@ export const equalArrays = (a, b) => {
|
|
|
12
16
|
}
|
|
13
17
|
return clone.length === 0;
|
|
14
18
|
};
|
|
15
|
-
|
|
19
|
+
exports.equalArrays = equalArrays;
|
|
20
|
+
/** Checks whether an object has no keys and/or the value for every key is undefined */
|
|
21
|
+
function isEmpty(obj) {
|
|
16
22
|
for (const key in obj)
|
|
17
23
|
if (obj[key] !== undefined)
|
|
18
24
|
return false;
|
|
19
25
|
return true;
|
|
20
26
|
}
|
|
27
|
+
exports.isEmpty = isEmpty;
|
|
@@ -1,14 +1,21 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.getCachedOrFetch = void 0;
|
|
4
|
+
const api_types_1 = require("../types/api.types");
|
|
5
|
+
async function getCachedOrFetch(cache, key, fetchFn, ttl = api_types_1.DefaultCacheTTL) {
|
|
6
|
+
// Check cache first
|
|
3
7
|
if (cache) {
|
|
4
8
|
const cachedResponse = await cache.get(key);
|
|
5
9
|
if (cachedResponse) {
|
|
6
10
|
return JSON.parse(cachedResponse);
|
|
7
11
|
}
|
|
8
12
|
}
|
|
13
|
+
// If not cached, fetch
|
|
9
14
|
const response = await fetchFn();
|
|
15
|
+
// Cache if successful
|
|
10
16
|
if (response && cache) {
|
|
11
17
|
await cache.put(key, JSON.stringify(response), { expirationTtl: ttl });
|
|
12
18
|
}
|
|
13
19
|
return response;
|
|
14
20
|
}
|
|
21
|
+
exports.getCachedOrFetch = getCachedOrFetch;
|
|
@@ -1,7 +1,13 @@
|
|
|
1
|
-
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.sha256 = void 0;
|
|
4
|
+
/** Hashes the given value using SHA-256 */
|
|
5
|
+
function sha256(value) {
|
|
2
6
|
var buffer = new TextEncoder().encode(value);
|
|
3
7
|
return crypto.subtle.digest("SHA-256", buffer).then(hex);
|
|
4
8
|
}
|
|
9
|
+
exports.sha256 = sha256;
|
|
10
|
+
/** Encodes a buffer in hex notation */
|
|
5
11
|
function hex(buffer) {
|
|
6
12
|
return [...new Uint8Array(buffer)]
|
|
7
13
|
.map(b => b.toString(16).padStart(2, '0'))
|
package/dist/utils/db.utils.d.ts
CHANGED
|
@@ -1,9 +1,14 @@
|
|
|
1
1
|
import { ConflictResolution, Expansion, SqlConflict, SqlOrder, SqlPaginate, SqlWhere, SqlWhereOperator } from "unconventional-pg-queries";
|
|
2
2
|
import BaseModel from "../core/base.model";
|
|
3
|
+
/** Converts a stringified list of relational fields to an array of data needed to expand those fields in a SQL environment */
|
|
3
4
|
export declare function getExpand<T extends typeof BaseModel>(model: T, expand?: string): Record<string, Expansion>;
|
|
5
|
+
/** Converts a string of filters to an array of 'where' clause outlines for a SQL environment */
|
|
4
6
|
export declare function getWhere<T extends typeof BaseModel>(model: T, filterString?: string): SqlWhere[];
|
|
7
|
+
/** Converts a stringified list of fields to order ascending or descending to an array of order data for a SQL environment */
|
|
5
8
|
export declare function getOrder<T extends typeof BaseModel>(model: T, sort?: string): SqlOrder[];
|
|
6
9
|
export declare function getPage<T extends typeof BaseModel>(model: T, cursor?: string | number): SqlPaginate | undefined;
|
|
10
|
+
/** Retrieves all non-relational fields from a model for the 'returning' clause of a SQL call */
|
|
7
11
|
export declare function getReturn<T extends typeof BaseModel>(model: T): string[];
|
|
8
12
|
export declare function getConflict<T extends typeof BaseModel>(model: T, action: ConflictResolution, constraint?: Array<keyof InstanceType<T>>): SqlConflict | undefined;
|
|
13
|
+
/** A type-safe way to build filter strings */
|
|
9
14
|
export declare function buildFilter<T>(field: keyof T, operator: SqlWhereOperator, value?: any): string;
|