@zenstackhq/runtime 0.3.9 → 0.3.11
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/{LICENSE.md → LICENSE} +0 -0
- package/client/index.d.ts +4 -0
- package/client/index.js +7 -0
- package/lib/client.d.ts +3 -0
- package/lib/client.js +34 -0
- package/lib/client.js.map +1 -0
- package/lib/config.d.ts +14 -0
- package/lib/config.js +3 -0
- package/lib/config.js.map +1 -0
- package/lib/constants.d.ts +12 -0
- package/lib/constants.js +16 -0
- package/lib/constants.js.map +1 -0
- package/lib/handler/data/handler.d.ts +19 -0
- package/lib/handler/data/handler.js +306 -0
- package/lib/handler/data/handler.js.map +1 -0
- package/lib/handler/data/nested-write-vistor.d.ts +31 -0
- package/lib/handler/data/nested-write-vistor.js +67 -0
- package/lib/handler/data/nested-write-vistor.js.map +1 -0
- package/lib/handler/data/policy-utils.d.ts +73 -0
- package/lib/handler/data/policy-utils.js +477 -0
- package/lib/handler/data/policy-utils.js.map +1 -0
- package/lib/handler/index.d.ts +1 -0
- package/lib/handler/index.js +9 -0
- package/lib/handler/index.js.map +1 -0
- package/lib/handler/types.d.ts +28 -0
- package/lib/handler/types.js +36 -0
- package/lib/handler/types.js.map +1 -0
- package/lib/index.d.ts +5 -0
- package/lib/index.js +22 -0
- package/lib/index.js.map +1 -0
- package/lib/request-handler.d.ts +21 -0
- package/lib/request-handler.js +37 -0
- package/lib/request-handler.js.map +1 -0
- package/lib/request.d.ts +16 -0
- package/lib/request.js +171 -0
- package/lib/request.js.map +1 -0
- package/lib/service.d.ts +32 -0
- package/lib/service.js +185 -0
- package/lib/service.js.map +1 -0
- package/lib/types.d.ts +168 -0
- package/lib/types.js +59 -0
- package/lib/types.js.map +1 -0
- package/lib/validation.d.ts +12 -0
- package/lib/validation.js +26 -0
- package/lib/validation.js.map +1 -0
- package/package.json +32 -7
- package/{auth.d.ts → server/auth.d.ts} +0 -0
- package/{auth.js → server/auth.js} +0 -0
- package/server/index.d.ts +16 -0
- package/server/index.js +7 -0
- package/{types.d.ts → types/index.d.ts} +0 -0
- package/{types.js → types/index.js} +0 -0
- package/README.md +0 -5
- package/client.d.ts +0 -1
- package/client.js +0 -3
- package/hooks.d.ts +0 -10
- package/hooks.js +0 -3
- package/index.d.ts +0 -3
- package/index.js +0 -1
- package/server.d.ts +0 -1
- package/server.js +0 -3
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
3
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
4
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
5
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
6
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
7
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
8
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
9
|
+
});
|
|
10
|
+
};
|
|
11
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12
|
+
exports.requestHandler = void 0;
|
|
13
|
+
const handler_1 = require("./handler");
|
|
14
|
+
/**
|
|
15
|
+
* Creates a Next.js API endpoint request handler which encapsulates RESTful APIs generated by ZenStack.
|
|
16
|
+
* The created handler should be mounted at /api/zenstack endpoint.
|
|
17
|
+
*
|
|
18
|
+
* @param service ZenStack service which wraps a Prisma db client inside
|
|
19
|
+
* @param options Options for initialization
|
|
20
|
+
* @returns An API endpoint request handler
|
|
21
|
+
*/
|
|
22
|
+
function requestHandler(service, options) {
|
|
23
|
+
const dataHandler = new handler_1.DataHandler(service, options);
|
|
24
|
+
return (req, res) => __awaiter(this, void 0, void 0, function* () {
|
|
25
|
+
const [route, ...rest] = req.query.path;
|
|
26
|
+
switch (route) {
|
|
27
|
+
// "/data" route is for handling data-access requests
|
|
28
|
+
case 'data':
|
|
29
|
+
return dataHandler.handle(req, res, rest);
|
|
30
|
+
default:
|
|
31
|
+
service.warn(`Unknown route: ${route}`);
|
|
32
|
+
res.status(404).json({ error: `Unknown route: ${route}` });
|
|
33
|
+
}
|
|
34
|
+
});
|
|
35
|
+
}
|
|
36
|
+
exports.requestHandler = requestHandler;
|
|
37
|
+
//# sourceMappingURL=request-handler.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"request-handler.js","sourceRoot":"","sources":["../../src/request-handler.ts"],"names":[],"mappings":";;;;;;;;;;;;AACA,uCAAwC;AAiBxC;;;;;;;GAOG;AACH,SAAgB,cAAc,CAC1B,OAA0B,EAC1B,OAA8B;IAE9B,MAAM,WAAW,GAAG,IAAI,qBAAW,CAC/B,OAAoC,EACpC,OAAO,CACV,CAAC;IACF,OAAO,CAAO,GAAmB,EAAE,GAAoB,EAAE,EAAE;QACvD,MAAM,CAAC,KAAK,EAAE,GAAG,IAAI,CAAC,GAAG,GAAG,CAAC,KAAK,CAAC,IAAgB,CAAC;QACpD,QAAQ,KAAK,EAAE;YACX,qDAAqD;YACrD,KAAK,MAAM;gBACP,OAAO,WAAW,CAAC,MAAM,CAAC,GAAG,EAAE,GAAG,EAAE,IAAI,CAAC,CAAC;YAE9C;gBACI,OAAO,CAAC,IAAI,CAAC,kBAAkB,KAAK,EAAE,CAAC,CAAC;gBACxC,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,kBAAkB,KAAK,EAAE,EAAE,CAAC,CAAC;SAClE;IACL,CAAC,CAAA,CAAC;AACN,CAAC;AApBD,wCAoBC"}
|
package/lib/request.d.ts
ADDED
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import type { MutatorCallback, MutatorOptions, SWRResponse } from 'swr/dist/types';
|
|
2
|
+
import { RequestOptions } from './types';
|
|
3
|
+
/**
|
|
4
|
+
* Makes a GET request with SWR.
|
|
5
|
+
*
|
|
6
|
+
* @param url The request URL.
|
|
7
|
+
* @param args The request args object, which will be JSON-stringified and appended as "?q=" parameter
|
|
8
|
+
* @returns SWR response
|
|
9
|
+
*/
|
|
10
|
+
export declare function get<Data, Error = any>(url: string | null, args?: unknown, options?: RequestOptions): SWRResponse<Data, Error>;
|
|
11
|
+
export declare function post<Data, Result>(url: string, data: Data, mutate: Mutator): Promise<Result>;
|
|
12
|
+
export declare function put<Data, Result>(url: string, data: Data, mutate: Mutator): Promise<Result>;
|
|
13
|
+
export declare function del<Result>(url: string, args: unknown, mutate: Mutator): Promise<Result>;
|
|
14
|
+
type Mutator = (key: string, prefix: boolean, data?: unknown | Promise<unknown> | MutatorCallback, opts?: boolean | MutatorOptions) => Promise<unknown[]>;
|
|
15
|
+
export declare function getMutate(): Mutator;
|
|
16
|
+
export {};
|
package/lib/request.js
ADDED
|
@@ -0,0 +1,171 @@
|
|
|
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 __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || function (mod) {
|
|
19
|
+
if (mod && mod.__esModule) return mod;
|
|
20
|
+
var result = {};
|
|
21
|
+
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
|
|
22
|
+
__setModuleDefault(result, mod);
|
|
23
|
+
return result;
|
|
24
|
+
};
|
|
25
|
+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
26
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
27
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
28
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
29
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
30
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
31
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
32
|
+
});
|
|
33
|
+
};
|
|
34
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
35
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
36
|
+
};
|
|
37
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
38
|
+
exports.getMutate = exports.del = exports.put = exports.post = exports.get = void 0;
|
|
39
|
+
const decimal_js_1 = __importDefault(require("decimal.js"));
|
|
40
|
+
const swr_1 = __importStar(require("swr"));
|
|
41
|
+
function isBuffer(value) {
|
|
42
|
+
return (!!value &&
|
|
43
|
+
value.type === 'Buffer' &&
|
|
44
|
+
Array.isArray(value.data));
|
|
45
|
+
}
|
|
46
|
+
function isBigInt(value) {
|
|
47
|
+
return (!!value &&
|
|
48
|
+
value.type === 'BigInt' &&
|
|
49
|
+
typeof value.data === 'string');
|
|
50
|
+
}
|
|
51
|
+
function isDate(value) {
|
|
52
|
+
return (!!value &&
|
|
53
|
+
value.type === 'Date' &&
|
|
54
|
+
typeof value.data === 'string');
|
|
55
|
+
}
|
|
56
|
+
function isDecimal(value) {
|
|
57
|
+
return (!!value &&
|
|
58
|
+
value.type === 'Decimal' &&
|
|
59
|
+
typeof value.data === 'string');
|
|
60
|
+
}
|
|
61
|
+
const dataReviver = (key, value) => {
|
|
62
|
+
// Buffer
|
|
63
|
+
if (isBuffer(value)) {
|
|
64
|
+
return Buffer.from(value.data);
|
|
65
|
+
}
|
|
66
|
+
// BigInt
|
|
67
|
+
if (isBigInt(value)) {
|
|
68
|
+
return BigInt(value.data);
|
|
69
|
+
}
|
|
70
|
+
// Date
|
|
71
|
+
if (isDate(value)) {
|
|
72
|
+
return new Date(value.data);
|
|
73
|
+
}
|
|
74
|
+
// Decimal
|
|
75
|
+
if (isDecimal(value)) {
|
|
76
|
+
return new decimal_js_1.default(value.data);
|
|
77
|
+
}
|
|
78
|
+
return value;
|
|
79
|
+
};
|
|
80
|
+
const fetcher = (url, options) => __awaiter(void 0, void 0, void 0, function* () {
|
|
81
|
+
const res = yield fetch(url, options);
|
|
82
|
+
if (!res.ok) {
|
|
83
|
+
const error = new Error('An error occurred while fetching the data.');
|
|
84
|
+
error.info = yield res.json();
|
|
85
|
+
error.status = res.status;
|
|
86
|
+
throw error;
|
|
87
|
+
}
|
|
88
|
+
const textResult = yield res.text();
|
|
89
|
+
console.log;
|
|
90
|
+
try {
|
|
91
|
+
return JSON.parse(textResult, dataReviver);
|
|
92
|
+
}
|
|
93
|
+
catch (err) {
|
|
94
|
+
console.error(`Unable to deserialize data:`, textResult);
|
|
95
|
+
throw err;
|
|
96
|
+
}
|
|
97
|
+
});
|
|
98
|
+
function makeUrl(url, args) {
|
|
99
|
+
return args ? url + `?q=${encodeURIComponent(JSON.stringify(args))}` : url;
|
|
100
|
+
}
|
|
101
|
+
/**
|
|
102
|
+
* Makes a GET request with SWR.
|
|
103
|
+
*
|
|
104
|
+
* @param url The request URL.
|
|
105
|
+
* @param args The request args object, which will be JSON-stringified and appended as "?q=" parameter
|
|
106
|
+
* @returns SWR response
|
|
107
|
+
*/
|
|
108
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
109
|
+
function get(url, args, options) {
|
|
110
|
+
const reqUrl = (options === null || options === void 0 ? void 0 : options.disabled) ? null : url ? makeUrl(url, args) : null;
|
|
111
|
+
return (0, swr_1.default)(reqUrl, fetcher);
|
|
112
|
+
}
|
|
113
|
+
exports.get = get;
|
|
114
|
+
function post(url, data, mutate) {
|
|
115
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
116
|
+
const r = yield fetcher(url, {
|
|
117
|
+
method: 'POST',
|
|
118
|
+
headers: {
|
|
119
|
+
'content-type': 'application/json',
|
|
120
|
+
},
|
|
121
|
+
body: JSON.stringify(data),
|
|
122
|
+
});
|
|
123
|
+
mutate(url, true);
|
|
124
|
+
return r;
|
|
125
|
+
});
|
|
126
|
+
}
|
|
127
|
+
exports.post = post;
|
|
128
|
+
function put(url, data, mutate) {
|
|
129
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
130
|
+
const r = yield fetcher(url, {
|
|
131
|
+
method: 'PUT',
|
|
132
|
+
headers: {
|
|
133
|
+
'content-type': 'application/json',
|
|
134
|
+
},
|
|
135
|
+
body: JSON.stringify(data),
|
|
136
|
+
});
|
|
137
|
+
mutate(url, true);
|
|
138
|
+
return r;
|
|
139
|
+
});
|
|
140
|
+
}
|
|
141
|
+
exports.put = put;
|
|
142
|
+
function del(url, args, mutate) {
|
|
143
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
144
|
+
const reqUrl = makeUrl(url, args);
|
|
145
|
+
const r = yield fetcher(reqUrl, {
|
|
146
|
+
method: 'DELETE',
|
|
147
|
+
});
|
|
148
|
+
const path = url.split('/');
|
|
149
|
+
path.pop();
|
|
150
|
+
mutate(path.join('/'), true);
|
|
151
|
+
return r;
|
|
152
|
+
});
|
|
153
|
+
}
|
|
154
|
+
exports.del = del;
|
|
155
|
+
function getMutate() {
|
|
156
|
+
// https://swr.vercel.app/docs/advanced/cache#mutate-multiple-keys-from-regex
|
|
157
|
+
const { cache, mutate } = (0, swr_1.useSWRConfig)();
|
|
158
|
+
return (key, prefix, data, opts) => {
|
|
159
|
+
if (!prefix) {
|
|
160
|
+
return mutate(key, data, opts);
|
|
161
|
+
}
|
|
162
|
+
if (!(cache instanceof Map)) {
|
|
163
|
+
throw new Error('mutate requires the cache provider to be a Map instance');
|
|
164
|
+
}
|
|
165
|
+
const keys = Array.from(cache.keys()).filter((k) => typeof k === 'string' && k.startsWith(key));
|
|
166
|
+
const mutations = keys.map((key) => mutate(key, data, opts));
|
|
167
|
+
return Promise.all(mutations);
|
|
168
|
+
};
|
|
169
|
+
}
|
|
170
|
+
exports.getMutate = getMutate;
|
|
171
|
+
//# sourceMappingURL=request.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"request.js","sourceRoot":"","sources":["../../src/request.ts"],"names":[],"mappings":"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"}
|
package/lib/service.d.ts
ADDED
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
/// <reference types="node" />
|
|
2
|
+
import { EventEmitter } from 'stream';
|
|
3
|
+
import { ServiceConfig } from './config';
|
|
4
|
+
import { FieldInfo, LogEvent, LogLevel, PolicyOperationKind, QueryContext, Service } from './types';
|
|
5
|
+
export declare abstract class DefaultService<DbClient extends {
|
|
6
|
+
$on: (eventType: any, handler: (event: any) => void) => void;
|
|
7
|
+
}> implements Service<DbClient> {
|
|
8
|
+
protected config: ServiceConfig;
|
|
9
|
+
private prisma;
|
|
10
|
+
protected readonly logEmitter: EventEmitter;
|
|
11
|
+
private readonly logSettings;
|
|
12
|
+
private guardModule;
|
|
13
|
+
private fieldConstraintModule;
|
|
14
|
+
private readonly prismaLogLevels;
|
|
15
|
+
constructor();
|
|
16
|
+
private initialize;
|
|
17
|
+
$on(level: LogLevel, callback: (event: LogEvent) => void): void;
|
|
18
|
+
private handleLog;
|
|
19
|
+
private loadConfig;
|
|
20
|
+
get db(): DbClient;
|
|
21
|
+
resolveField(model: string, field: string): Promise<FieldInfo | undefined>;
|
|
22
|
+
buildQueryGuard(model: string, operation: PolicyOperationKind, context: QueryContext): Promise<unknown>;
|
|
23
|
+
validateModelPayload(model: string, mode: 'create' | 'update', payload: unknown): Promise<void>;
|
|
24
|
+
verbose(message: string): void;
|
|
25
|
+
info(message: string): void;
|
|
26
|
+
warn(message: string): void;
|
|
27
|
+
error(message: string): void;
|
|
28
|
+
reinitialize(): void;
|
|
29
|
+
protected abstract initializePrisma(): DbClient;
|
|
30
|
+
protected abstract loadGuardModule(): Promise<any>;
|
|
31
|
+
protected abstract loadFieldConstraintModule(): Promise<any>;
|
|
32
|
+
}
|
package/lib/service.js
ADDED
|
@@ -0,0 +1,185 @@
|
|
|
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 __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || function (mod) {
|
|
19
|
+
if (mod && mod.__esModule) return mod;
|
|
20
|
+
var result = {};
|
|
21
|
+
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
|
|
22
|
+
__setModuleDefault(result, mod);
|
|
23
|
+
return result;
|
|
24
|
+
};
|
|
25
|
+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
26
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
27
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
28
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
29
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
30
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
31
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
32
|
+
});
|
|
33
|
+
};
|
|
34
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
35
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
36
|
+
};
|
|
37
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
38
|
+
exports.DefaultService = void 0;
|
|
39
|
+
const colors_1 = __importDefault(require("colors"));
|
|
40
|
+
const fs = __importStar(require("fs"));
|
|
41
|
+
const stream_1 = require("stream");
|
|
42
|
+
const validation_1 = require("./validation");
|
|
43
|
+
class DefaultService {
|
|
44
|
+
constructor() {
|
|
45
|
+
this.logEmitter = new stream_1.EventEmitter();
|
|
46
|
+
this.logSettings = {
|
|
47
|
+
query: { stdout: false, emit: false },
|
|
48
|
+
verbose: { stdout: false, emit: false },
|
|
49
|
+
info: { stdout: true, emit: false },
|
|
50
|
+
warn: { stdout: true, emit: false },
|
|
51
|
+
error: { stdout: true, emit: false },
|
|
52
|
+
};
|
|
53
|
+
this.prismaLogLevels = [
|
|
54
|
+
'query',
|
|
55
|
+
'info',
|
|
56
|
+
'warn',
|
|
57
|
+
'error',
|
|
58
|
+
];
|
|
59
|
+
this.initialize();
|
|
60
|
+
}
|
|
61
|
+
initialize() {
|
|
62
|
+
this.config = this.loadConfig();
|
|
63
|
+
// initialize log sink mapping
|
|
64
|
+
if (this.config.log) {
|
|
65
|
+
// reset all levels
|
|
66
|
+
for (const key of Object.keys(this.logSettings)) {
|
|
67
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
68
|
+
this.logSettings[key] = { stdout: false, emit: false };
|
|
69
|
+
}
|
|
70
|
+
for (const entry of this.config.log) {
|
|
71
|
+
const level = typeof entry === 'string' ? entry : entry.level;
|
|
72
|
+
if (!Object.keys(this.logSettings).includes(level)) {
|
|
73
|
+
console.error(`Unknown log level "${level}"`);
|
|
74
|
+
continue;
|
|
75
|
+
}
|
|
76
|
+
if (typeof entry === 'string') {
|
|
77
|
+
this.logSettings[level].stdout = true;
|
|
78
|
+
}
|
|
79
|
+
else if (entry.emit === 'stdout') {
|
|
80
|
+
this.logSettings[level].stdout = true;
|
|
81
|
+
}
|
|
82
|
+
else {
|
|
83
|
+
this.logSettings[level].emit = true;
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
console.log('Initializing ZenStack service with config:', JSON.stringify(this.config));
|
|
88
|
+
this.prisma = this.initializePrisma();
|
|
89
|
+
for (const level of this.prismaLogLevels) {
|
|
90
|
+
if (this.logSettings[level].emit) {
|
|
91
|
+
this.verbose(`Hooking prisma log level ${level}`);
|
|
92
|
+
this.prisma.$on(level, (e) => {
|
|
93
|
+
this.logEmitter.emit(level, e);
|
|
94
|
+
});
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
$on(level, callback) {
|
|
99
|
+
this.logEmitter.on(level, callback);
|
|
100
|
+
}
|
|
101
|
+
handleLog(level, message) {
|
|
102
|
+
if (this.logSettings[level].stdout) {
|
|
103
|
+
switch (level) {
|
|
104
|
+
case 'verbose':
|
|
105
|
+
console.log(colors_1.default.blue(`zenstack:${level}`), message);
|
|
106
|
+
break;
|
|
107
|
+
case 'info':
|
|
108
|
+
console.log(colors_1.default.cyan(`zenstack:${level}`), message);
|
|
109
|
+
break;
|
|
110
|
+
case 'warn':
|
|
111
|
+
console.warn(colors_1.default.yellow(`zenstack:${level}`), message);
|
|
112
|
+
break;
|
|
113
|
+
case 'error':
|
|
114
|
+
console.error(colors_1.default.red(`zenstack:${level}`), message);
|
|
115
|
+
break;
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
if (this.logSettings[level].emit) {
|
|
119
|
+
this.logEmitter.emit(level, { timestamp: new Date(), message });
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
loadConfig() {
|
|
123
|
+
const configFile = './zenstack.config.json';
|
|
124
|
+
if (fs.existsSync(configFile)) {
|
|
125
|
+
try {
|
|
126
|
+
const config = JSON.parse(fs.readFileSync(configFile).toString('utf-8'));
|
|
127
|
+
return config;
|
|
128
|
+
}
|
|
129
|
+
catch (err) {
|
|
130
|
+
console.error('Failed to load zenstack.config.json', err);
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
return {};
|
|
134
|
+
}
|
|
135
|
+
get db() {
|
|
136
|
+
return this.prisma;
|
|
137
|
+
}
|
|
138
|
+
resolveField(model, field) {
|
|
139
|
+
var _a, _b;
|
|
140
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
141
|
+
if (!this.guardModule) {
|
|
142
|
+
this.guardModule = yield this.loadGuardModule();
|
|
143
|
+
}
|
|
144
|
+
return (_b = (_a = this.guardModule._fieldMapping) === null || _a === void 0 ? void 0 : _a[model]) === null || _b === void 0 ? void 0 : _b[field];
|
|
145
|
+
});
|
|
146
|
+
}
|
|
147
|
+
buildQueryGuard(model, operation, context) {
|
|
148
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
149
|
+
if (!this.guardModule) {
|
|
150
|
+
this.guardModule = yield this.loadGuardModule();
|
|
151
|
+
}
|
|
152
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
153
|
+
const provider = this.guardModule[model + '_' + operation];
|
|
154
|
+
return provider(context);
|
|
155
|
+
});
|
|
156
|
+
}
|
|
157
|
+
validateModelPayload(model, mode, payload) {
|
|
158
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
159
|
+
if (!this.fieldConstraintModule) {
|
|
160
|
+
this.fieldConstraintModule = yield this.loadFieldConstraintModule();
|
|
161
|
+
}
|
|
162
|
+
const validator = this.fieldConstraintModule[`${model}_${mode}_validator`];
|
|
163
|
+
if (validator) {
|
|
164
|
+
(0, validation_1.validate)(validator, payload);
|
|
165
|
+
}
|
|
166
|
+
});
|
|
167
|
+
}
|
|
168
|
+
verbose(message) {
|
|
169
|
+
this.handleLog('verbose', message);
|
|
170
|
+
}
|
|
171
|
+
info(message) {
|
|
172
|
+
this.handleLog('info', message);
|
|
173
|
+
}
|
|
174
|
+
warn(message) {
|
|
175
|
+
this.handleLog('warn', message);
|
|
176
|
+
}
|
|
177
|
+
error(message) {
|
|
178
|
+
this.handleLog('error', message);
|
|
179
|
+
}
|
|
180
|
+
reinitialize() {
|
|
181
|
+
this.initialize();
|
|
182
|
+
}
|
|
183
|
+
}
|
|
184
|
+
exports.DefaultService = DefaultService;
|
|
185
|
+
//# sourceMappingURL=service.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"service.js","sourceRoot":"","sources":["../../src/service.ts"],"names":[],"mappings":"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"}
|
package/lib/types.d.ts
ADDED
|
@@ -0,0 +1,168 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Weakly-typed database access methods
|
|
3
|
+
*/
|
|
4
|
+
export interface DbOperations {
|
|
5
|
+
findMany(args: unknown): Promise<unknown[]>;
|
|
6
|
+
findFirst(args: unknown): Promise<unknown>;
|
|
7
|
+
findUnique(args: unknown): Promise<unknown>;
|
|
8
|
+
create(args: unknown): Promise<unknown>;
|
|
9
|
+
update(args: unknown): Promise<unknown>;
|
|
10
|
+
delete(args: unknown): Promise<unknown>;
|
|
11
|
+
deleteMany(args: unknown): Promise<unknown>;
|
|
12
|
+
count(args: unknown): Promise<number>;
|
|
13
|
+
}
|
|
14
|
+
/**
|
|
15
|
+
* Kinds of access policy
|
|
16
|
+
*/
|
|
17
|
+
export type PolicyKind = 'allow' | 'deny';
|
|
18
|
+
/**
|
|
19
|
+
* Kinds of operations controlled by access policies
|
|
20
|
+
*/
|
|
21
|
+
export type PolicyOperationKind = 'create' | 'update' | 'read' | 'delete';
|
|
22
|
+
/**
|
|
23
|
+
* Current login user info
|
|
24
|
+
*
|
|
25
|
+
* @todo Support for non-string "id" field
|
|
26
|
+
*/
|
|
27
|
+
export type AuthUser = {
|
|
28
|
+
id: string;
|
|
29
|
+
} & Record<string, unknown>;
|
|
30
|
+
/**
|
|
31
|
+
* Context for database query
|
|
32
|
+
*/
|
|
33
|
+
export type QueryContext = {
|
|
34
|
+
/**
|
|
35
|
+
* Current login user (provided by @see RequestHandlerOptions)
|
|
36
|
+
*/
|
|
37
|
+
user?: AuthUser;
|
|
38
|
+
};
|
|
39
|
+
export type RuntimeAttribute = {
|
|
40
|
+
name: string;
|
|
41
|
+
args: Array<{
|
|
42
|
+
name?: string;
|
|
43
|
+
value: unknown;
|
|
44
|
+
}>;
|
|
45
|
+
};
|
|
46
|
+
/**
|
|
47
|
+
* Runtime information of a data model field
|
|
48
|
+
*/
|
|
49
|
+
export type FieldInfo = {
|
|
50
|
+
name: string;
|
|
51
|
+
type: string;
|
|
52
|
+
isDataModel: boolean;
|
|
53
|
+
isArray: boolean;
|
|
54
|
+
isOptional: boolean;
|
|
55
|
+
attributes: RuntimeAttribute[];
|
|
56
|
+
};
|
|
57
|
+
export type DbClientContract = Record<string, DbOperations> & {
|
|
58
|
+
$transaction: <T>(action: (tx: Record<string, DbOperations>) => Promise<T>) => Promise<T>;
|
|
59
|
+
};
|
|
60
|
+
/**
|
|
61
|
+
* Logging levels
|
|
62
|
+
*/
|
|
63
|
+
export type LogLevel = 'verbose' | 'info' | 'query' | 'warn' | 'error';
|
|
64
|
+
/**
|
|
65
|
+
* The main service of ZenStack. Implementation of this interface is automatically generated.
|
|
66
|
+
*/
|
|
67
|
+
export interface Service<DbClient = any> {
|
|
68
|
+
/**
|
|
69
|
+
* Returns the wrapped Prisma db client
|
|
70
|
+
*/
|
|
71
|
+
get db(): DbClient;
|
|
72
|
+
/**
|
|
73
|
+
* Resolves information of a data model field.
|
|
74
|
+
*
|
|
75
|
+
* @param model Model name
|
|
76
|
+
* @param field Field name
|
|
77
|
+
*/
|
|
78
|
+
resolveField(model: string, field: string): Promise<FieldInfo | undefined>;
|
|
79
|
+
/**
|
|
80
|
+
* Builds policy check guard object for an operation over a model, which will be injected to
|
|
81
|
+
* the query body sent to Prisma client.
|
|
82
|
+
*
|
|
83
|
+
* @param model Model name
|
|
84
|
+
* @param operation Operation kind
|
|
85
|
+
* @param context Query context
|
|
86
|
+
*/
|
|
87
|
+
buildQueryGuard(model: string, operation: PolicyOperationKind, context: QueryContext): Promise<unknown>;
|
|
88
|
+
validateModelPayload(model: string, mode: 'create' | 'update', payload: unknown): Promise<void>;
|
|
89
|
+
/**
|
|
90
|
+
* Generates a log message with verbose level.
|
|
91
|
+
*/
|
|
92
|
+
verbose(message: string): void;
|
|
93
|
+
/**
|
|
94
|
+
* Generates a log message with info level.
|
|
95
|
+
*/
|
|
96
|
+
info(message: string): void;
|
|
97
|
+
/**
|
|
98
|
+
* Generates a log message with warn level.
|
|
99
|
+
*/
|
|
100
|
+
warn(message: string): void;
|
|
101
|
+
/**
|
|
102
|
+
* Generates a log message with error level.
|
|
103
|
+
*/
|
|
104
|
+
error(message: string): void;
|
|
105
|
+
/**
|
|
106
|
+
* Registers a listener to log events.
|
|
107
|
+
*/
|
|
108
|
+
$on(level: LogLevel, callback: (event: LogEvent) => void): void;
|
|
109
|
+
}
|
|
110
|
+
/**
|
|
111
|
+
* Error codes for errors on server side
|
|
112
|
+
*/
|
|
113
|
+
export declare enum ServerErrorCode {
|
|
114
|
+
/**
|
|
115
|
+
* The specified entity cannot be found
|
|
116
|
+
*/
|
|
117
|
+
ENTITY_NOT_FOUND = "ENTITY_NOT_FOUND",
|
|
118
|
+
/**
|
|
119
|
+
* The request parameter is invalid, either containing invalid fields or missing required fields
|
|
120
|
+
*/
|
|
121
|
+
INVALID_REQUEST_PARAMS = "INVALID_REQUEST_PARAMS",
|
|
122
|
+
/**
|
|
123
|
+
* The request is rejected by policy checks
|
|
124
|
+
*/
|
|
125
|
+
DENIED_BY_POLICY = "DENIED_BY_POLICY",
|
|
126
|
+
/**
|
|
127
|
+
* Violation of database unique constraints
|
|
128
|
+
*/
|
|
129
|
+
UNIQUE_CONSTRAINT_VIOLATION = "UNIQUE_CONSTRAINT_VIOLATION",
|
|
130
|
+
/**
|
|
131
|
+
* Violation of database reference constraint (aka. foreign key constraints)
|
|
132
|
+
*/
|
|
133
|
+
REFERENCE_CONSTRAINT_VIOLATION = "REFERENCE_CONSTRAINT_VIOLATION",
|
|
134
|
+
/**
|
|
135
|
+
* A write operation succeeded but the result cannot be read back due to policy control
|
|
136
|
+
*/
|
|
137
|
+
READ_BACK_AFTER_WRITE_DENIED = "READ_BACK_AFTER_WRITE_DENIED",
|
|
138
|
+
/**
|
|
139
|
+
* Unknown error
|
|
140
|
+
*/
|
|
141
|
+
UNKNOWN = "UNKNOWN"
|
|
142
|
+
}
|
|
143
|
+
export declare function getServerErrorMessage(code: ServerErrorCode): string;
|
|
144
|
+
export type LogEventHandler = (LogEvent: any, handler: (event: LogEvent) => void) => void;
|
|
145
|
+
export type LogEvent = {
|
|
146
|
+
timestamp: Date;
|
|
147
|
+
query?: string;
|
|
148
|
+
params?: string;
|
|
149
|
+
duration?: number;
|
|
150
|
+
target?: string;
|
|
151
|
+
message?: string;
|
|
152
|
+
};
|
|
153
|
+
/**
|
|
154
|
+
* Client request options
|
|
155
|
+
*/
|
|
156
|
+
export type RequestOptions = {
|
|
157
|
+
disabled: boolean;
|
|
158
|
+
};
|
|
159
|
+
/**
|
|
160
|
+
* Hooks invocation error
|
|
161
|
+
*/
|
|
162
|
+
export type HooksError = {
|
|
163
|
+
status: number;
|
|
164
|
+
info: {
|
|
165
|
+
code: ServerErrorCode;
|
|
166
|
+
message: string;
|
|
167
|
+
};
|
|
168
|
+
};
|