@zenstackhq/runtime 0.1.0 → 0.1.2
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/lib/handler/data/handler.d.ts +16 -0
- package/lib/handler/data/handler.js +207 -0
- package/lib/handler/data/handler.js.map +1 -0
- package/lib/handler/data/query-processor.d.ts +7 -0
- package/lib/handler/data/query-processor.js +59 -0
- package/lib/handler/data/query-processor.js.map +1 -0
- package/lib/handler/index.d.ts +1 -0
- package/lib/handler/index.js +2 -0
- package/lib/handler/index.js.map +1 -0
- package/lib/handler/types.d.ts +10 -0
- package/lib/handler/types.js +10 -0
- package/lib/handler/types.js.map +1 -0
- package/lib/index.d.ts +2 -1
- package/lib/index.js +2 -1
- package/lib/index.js.map +1 -1
- package/lib/request/index.d.ts +6 -0
- package/lib/request/index.js +69 -0
- package/lib/request/index.js.map +1 -0
- package/lib/request-handler.d.ts +6 -0
- package/lib/request-handler.js +23 -0
- package/lib/request-handler.js.map +1 -0
- package/lib/request.d.ts +1 -1
- package/lib/request.js +3 -3
- package/lib/request.js.map +1 -1
- package/lib/types.d.ts +32 -0
- package/lib/types.js +10 -0
- package/lib/types.js.map +1 -0
- package/package.json +14 -2
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { NextApiRequest, NextApiResponse } from 'next';
|
|
2
|
+
import { RequestHandlerOptions } from '../../request-handler';
|
|
3
|
+
import { Service } from '../../types';
|
|
4
|
+
import { RequestHandler } from '../types';
|
|
5
|
+
export default class DataHandler<DbClient> implements RequestHandler {
|
|
6
|
+
private readonly service;
|
|
7
|
+
private readonly options;
|
|
8
|
+
private readonly queryProcessor;
|
|
9
|
+
constructor(service: Service<DbClient>, options: RequestHandlerOptions);
|
|
10
|
+
handle(req: NextApiRequest, res: NextApiResponse, path: string[]): Promise<void>;
|
|
11
|
+
private get;
|
|
12
|
+
private post;
|
|
13
|
+
private put;
|
|
14
|
+
private del;
|
|
15
|
+
private ensureEntityPolicy;
|
|
16
|
+
}
|
|
@@ -0,0 +1,207 @@
|
|
|
1
|
+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
2
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
3
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
4
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
5
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
6
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
7
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
8
|
+
});
|
|
9
|
+
};
|
|
10
|
+
import { ServerErrorCode, } from '../../types';
|
|
11
|
+
import { RequestHandlerError } from '../types';
|
|
12
|
+
import { QueryProcessor } from './query-processor';
|
|
13
|
+
const PRISMA_ERROR_MAPPING = {
|
|
14
|
+
P2002: ServerErrorCode.UNIQUE_CONSTRAINT_VIOLATION,
|
|
15
|
+
P2003: ServerErrorCode.REFERENCE_CONSTRAINT_VIOLATION,
|
|
16
|
+
};
|
|
17
|
+
export default class DataHandler {
|
|
18
|
+
constructor(service, options) {
|
|
19
|
+
this.service = service;
|
|
20
|
+
this.options = options;
|
|
21
|
+
this.queryProcessor = new QueryProcessor(service);
|
|
22
|
+
}
|
|
23
|
+
handle(req, res, path) {
|
|
24
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
25
|
+
const [model, id] = path;
|
|
26
|
+
const method = req.method;
|
|
27
|
+
const context = { user: yield this.options.getServerUser(req, res) };
|
|
28
|
+
try {
|
|
29
|
+
switch (method) {
|
|
30
|
+
case 'GET':
|
|
31
|
+
yield this.get(req, res, model, id, context);
|
|
32
|
+
break;
|
|
33
|
+
case 'POST':
|
|
34
|
+
yield this.post(req, res, model, context);
|
|
35
|
+
break;
|
|
36
|
+
case 'PUT':
|
|
37
|
+
yield this.put(req, res, model, id, context);
|
|
38
|
+
break;
|
|
39
|
+
case 'DELETE':
|
|
40
|
+
yield this.del(req, res, model, id, context);
|
|
41
|
+
break;
|
|
42
|
+
default:
|
|
43
|
+
console.warn(`Unhandled method: ${method}`);
|
|
44
|
+
res.status(200).send({});
|
|
45
|
+
break;
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
catch (err) {
|
|
49
|
+
console.error(`Error handling ${method} ${model}: ${err}`);
|
|
50
|
+
if (err instanceof RequestHandlerError) {
|
|
51
|
+
switch (err.code) {
|
|
52
|
+
case ServerErrorCode.DENIED_BY_POLICY:
|
|
53
|
+
res.status(403).send({
|
|
54
|
+
code: err.code,
|
|
55
|
+
message: err.message,
|
|
56
|
+
});
|
|
57
|
+
break;
|
|
58
|
+
case ServerErrorCode.ENTITY_NOT_FOUND:
|
|
59
|
+
res.status(404).send({
|
|
60
|
+
code: err.code,
|
|
61
|
+
message: err.message,
|
|
62
|
+
});
|
|
63
|
+
break;
|
|
64
|
+
default:
|
|
65
|
+
res.status(400).send({
|
|
66
|
+
code: err.code,
|
|
67
|
+
message: err.message,
|
|
68
|
+
});
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
else if (err.code && PRISMA_ERROR_MAPPING[err.code]) {
|
|
72
|
+
res.status(400).send({
|
|
73
|
+
code: PRISMA_ERROR_MAPPING[err.code],
|
|
74
|
+
message: 'database access error',
|
|
75
|
+
});
|
|
76
|
+
}
|
|
77
|
+
else {
|
|
78
|
+
console.error(`An unknown error occurred: ${JSON.stringify(err)}`);
|
|
79
|
+
res.status(500).send({ error: ServerErrorCode.UNKNOWN });
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
});
|
|
83
|
+
}
|
|
84
|
+
get(req, res, model, id, context) {
|
|
85
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
86
|
+
const db = this.service.db[model];
|
|
87
|
+
const args = req.query.q ? JSON.parse(req.query.q) : {};
|
|
88
|
+
const processedArgs = yield this.queryProcessor.processQueryArgs(model, args, 'read', context);
|
|
89
|
+
let r;
|
|
90
|
+
if (id) {
|
|
91
|
+
if (processedArgs.where) {
|
|
92
|
+
processedArgs.where = {
|
|
93
|
+
AND: [args.where, { id }],
|
|
94
|
+
};
|
|
95
|
+
}
|
|
96
|
+
else {
|
|
97
|
+
processedArgs.where = { id };
|
|
98
|
+
}
|
|
99
|
+
r = yield db.findFirst(processedArgs);
|
|
100
|
+
if (!r) {
|
|
101
|
+
throw new RequestHandlerError(ServerErrorCode.ENTITY_NOT_FOUND, 'not found');
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
else {
|
|
105
|
+
r = yield db.findMany(processedArgs);
|
|
106
|
+
}
|
|
107
|
+
console.log(`Finding ${model}:\n${JSON.stringify(processedArgs, undefined, 2)}`);
|
|
108
|
+
yield this.queryProcessor.postProcess(model, processedArgs, r, 'read', context);
|
|
109
|
+
res.status(200).send(r);
|
|
110
|
+
});
|
|
111
|
+
}
|
|
112
|
+
post(req, res, model, context) {
|
|
113
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
114
|
+
const args = req.body;
|
|
115
|
+
if (!args) {
|
|
116
|
+
throw new RequestHandlerError(ServerErrorCode.INVALID_REQUEST_PARAMS, 'body is required');
|
|
117
|
+
}
|
|
118
|
+
const db = this.service.db;
|
|
119
|
+
const processedArgs = yield this.queryProcessor.processQueryArgs(model, args, 'create', context, false);
|
|
120
|
+
const r = yield db.$transaction((tx) => __awaiter(this, void 0, void 0, function* () {
|
|
121
|
+
console.log(`Create ${model}:\n${JSON.stringify(processedArgs, undefined, 2)}`);
|
|
122
|
+
const created = yield tx[model].create(processedArgs);
|
|
123
|
+
let queryArgs = {
|
|
124
|
+
where: { id: created.id },
|
|
125
|
+
include: args.include,
|
|
126
|
+
select: args.select,
|
|
127
|
+
};
|
|
128
|
+
queryArgs = yield this.queryProcessor.processQueryArgs(model, queryArgs, 'create', context);
|
|
129
|
+
console.log(`Finding created ${model}:\n${JSON.stringify(queryArgs, undefined, 2)}`);
|
|
130
|
+
const found = yield tx[model].findFirst(queryArgs);
|
|
131
|
+
if (!found) {
|
|
132
|
+
throw new RequestHandlerError(ServerErrorCode.DENIED_BY_POLICY, 'denied by policy');
|
|
133
|
+
}
|
|
134
|
+
return created;
|
|
135
|
+
}));
|
|
136
|
+
yield this.queryProcessor.postProcess(model, processedArgs, r, 'create', context);
|
|
137
|
+
res.status(201).send(r);
|
|
138
|
+
});
|
|
139
|
+
}
|
|
140
|
+
put(req, res, model, id, context) {
|
|
141
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
142
|
+
if (!id) {
|
|
143
|
+
throw new RequestHandlerError(ServerErrorCode.INVALID_REQUEST_PARAMS, 'missing "id" parameter');
|
|
144
|
+
}
|
|
145
|
+
// ensure entity passes policy check
|
|
146
|
+
yield this.ensureEntityPolicy(id, model, 'update', context);
|
|
147
|
+
const args = req.body;
|
|
148
|
+
if (!args) {
|
|
149
|
+
throw new RequestHandlerError(ServerErrorCode.INVALID_REQUEST_PARAMS, 'body is required');
|
|
150
|
+
}
|
|
151
|
+
const db = this.service.db;
|
|
152
|
+
const updateArgs = yield this.queryProcessor.processQueryArgs(model, args, 'update', context, false);
|
|
153
|
+
updateArgs.where = Object.assign(Object.assign({}, updateArgs.where), { id });
|
|
154
|
+
const r = yield db.$transaction((tx) => __awaiter(this, void 0, void 0, function* () {
|
|
155
|
+
console.log(`Update ${model}:\n${JSON.stringify(updateArgs, undefined, 2)}`);
|
|
156
|
+
const updated = yield tx[model].update(updateArgs);
|
|
157
|
+
// make sure after update, the entity passes policy check
|
|
158
|
+
let queryArgs = {
|
|
159
|
+
where: updateArgs.where,
|
|
160
|
+
include: args.include,
|
|
161
|
+
select: args.select,
|
|
162
|
+
};
|
|
163
|
+
queryArgs = yield this.queryProcessor.processQueryArgs(model, queryArgs, 'update', context);
|
|
164
|
+
console.log(`Finding post-updated ${model}:\n${JSON.stringify(queryArgs, undefined, 2)}`);
|
|
165
|
+
const found = yield tx[model].findFirst(queryArgs);
|
|
166
|
+
if (!found) {
|
|
167
|
+
throw new RequestHandlerError(ServerErrorCode.DENIED_BY_POLICY, 'post-update denied by policy');
|
|
168
|
+
}
|
|
169
|
+
return updated;
|
|
170
|
+
}));
|
|
171
|
+
yield this.queryProcessor.postProcess(model, updateArgs, r, 'update', context);
|
|
172
|
+
res.status(200).send(r);
|
|
173
|
+
});
|
|
174
|
+
}
|
|
175
|
+
del(req, res, model, id, context) {
|
|
176
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
177
|
+
if (!id) {
|
|
178
|
+
throw new RequestHandlerError(ServerErrorCode.INVALID_REQUEST_PARAMS, 'missing "id" parameter');
|
|
179
|
+
}
|
|
180
|
+
// ensure entity passes policy check
|
|
181
|
+
yield this.ensureEntityPolicy(id, model, 'delete', context);
|
|
182
|
+
const args = req.query.q ? JSON.parse(req.query.q) : {};
|
|
183
|
+
// proceed with deleting
|
|
184
|
+
const delArgs = yield this.queryProcessor.processQueryArgs(model, args, 'delete', context, false);
|
|
185
|
+
delArgs.where = Object.assign(Object.assign({}, delArgs.where), { id });
|
|
186
|
+
console.log(`Deleting ${model}:\n${JSON.stringify(delArgs, undefined, 2)}`);
|
|
187
|
+
const db = this.service.db[model];
|
|
188
|
+
const r = yield db.delete(delArgs);
|
|
189
|
+
yield this.queryProcessor.postProcess(model, delArgs, r, 'delete', context);
|
|
190
|
+
res.status(200).send(r);
|
|
191
|
+
});
|
|
192
|
+
}
|
|
193
|
+
ensureEntityPolicy(id, model, operation, context) {
|
|
194
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
195
|
+
const db = this.service.db[model];
|
|
196
|
+
// check if the record is readable concerning "delete" policy
|
|
197
|
+
const readArgs = yield this.queryProcessor.processQueryArgs(model, { where: { id } }, operation, context);
|
|
198
|
+
console.log(`Finding to-be-deleted ${model}:\n${JSON.stringify(readArgs, undefined, 2)}`);
|
|
199
|
+
const read = yield db.findFirst(readArgs);
|
|
200
|
+
if (!read) {
|
|
201
|
+
throw new RequestHandlerError(ServerErrorCode.DENIED_BY_POLICY, 'denied by policy');
|
|
202
|
+
}
|
|
203
|
+
return read;
|
|
204
|
+
});
|
|
205
|
+
}
|
|
206
|
+
}
|
|
207
|
+
//# sourceMappingURL=handler.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"handler.js","sourceRoot":"","sources":["../../../src/handler/data/handler.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import { PolicyOperationKind, QueryContext, Service } from '../../types';
|
|
2
|
+
export declare class QueryProcessor {
|
|
3
|
+
private readonly service;
|
|
4
|
+
constructor(service: Service);
|
|
5
|
+
processQueryArgs(model: string, args: any, operation: PolicyOperationKind, context: QueryContext, injectWhere?: boolean): Promise<any>;
|
|
6
|
+
postProcess(model: string, queryArgs: any, data: any, operation: PolicyOperationKind, context: QueryContext): Promise<void>;
|
|
7
|
+
}
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
2
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
3
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
4
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
5
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
6
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
7
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
8
|
+
});
|
|
9
|
+
};
|
|
10
|
+
import deepcopy from 'deepcopy';
|
|
11
|
+
export class QueryProcessor {
|
|
12
|
+
constructor(service) {
|
|
13
|
+
this.service = service;
|
|
14
|
+
}
|
|
15
|
+
processQueryArgs(model, args, operation, context, injectWhere = true) {
|
|
16
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
17
|
+
const r = args ? deepcopy(args) : {};
|
|
18
|
+
if (injectWhere) {
|
|
19
|
+
const guard = yield this.service.buildQueryGuard(model, operation, context);
|
|
20
|
+
if (guard) {
|
|
21
|
+
if (!r.where) {
|
|
22
|
+
r.where = guard;
|
|
23
|
+
}
|
|
24
|
+
else {
|
|
25
|
+
r.where = {
|
|
26
|
+
AND: [guard, r.where],
|
|
27
|
+
};
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
if (r.include || r.select) {
|
|
32
|
+
// "include" and "select" are mutually exclusive
|
|
33
|
+
const selector = r.include ? 'include' : 'select';
|
|
34
|
+
for (const [field, value] of Object.entries(r[selector])) {
|
|
35
|
+
const fieldInfo = yield this.service.resolveField(model, field);
|
|
36
|
+
if (fieldInfo) {
|
|
37
|
+
if (fieldInfo.isArray) {
|
|
38
|
+
// note that Prisma only allows to attach filter for "to-many" relation
|
|
39
|
+
// query, so we need to handle "to-one" filter separately in post-processing
|
|
40
|
+
const fieldGuard = yield this.processQueryArgs(fieldInfo.type, value === true ? {} : value, operation, context);
|
|
41
|
+
r[selector][field] = fieldGuard;
|
|
42
|
+
}
|
|
43
|
+
else {
|
|
44
|
+
// make sure "id" field is included so that we can do post-process filtering
|
|
45
|
+
if (selector === 'select') {
|
|
46
|
+
r[selector].id = true;
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
return r;
|
|
53
|
+
});
|
|
54
|
+
}
|
|
55
|
+
postProcess(model, queryArgs, data, operation, context) {
|
|
56
|
+
return __awaiter(this, void 0, void 0, function* () { });
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
//# sourceMappingURL=query-processor.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"query-processor.js","sourceRoot":"","sources":["../../../src/handler/data/query-processor.ts"],"names":[],"mappings":";;;;;;;;;AAAA,OAAO,QAAQ,MAAM,UAAU,CAAC;AAGhC,MAAM,OAAO,cAAc;IACvB,YAA6B,OAAgB;QAAhB,YAAO,GAAP,OAAO,CAAS;IAAG,CAAC;IAE3C,gBAAgB,CAClB,KAAa,EACb,IAAS,EACT,SAA8B,EAC9B,OAAqB,EACrB,cAAuB,IAAI;;YAE3B,MAAM,CAAC,GAAG,IAAI,CAAC,CAAC,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;YAErC,IAAI,WAAW,EAAE;gBACb,MAAM,KAAK,GAAG,MAAM,IAAI,CAAC,OAAO,CAAC,eAAe,CAC5C,KAAK,EACL,SAAS,EACT,OAAO,CACV,CAAC;gBACF,IAAI,KAAK,EAAE;oBACP,IAAI,CAAC,CAAC,CAAC,KAAK,EAAE;wBACV,CAAC,CAAC,KAAK,GAAG,KAAK,CAAC;qBACnB;yBAAM;wBACH,CAAC,CAAC,KAAK,GAAG;4BACN,GAAG,EAAE,CAAC,KAAK,EAAE,CAAC,CAAC,KAAK,CAAC;yBACxB,CAAC;qBACL;iBACJ;aACJ;YAED,IAAI,CAAC,CAAC,OAAO,IAAI,CAAC,CAAC,MAAM,EAAE;gBACvB,gDAAgD;gBAChD,MAAM,QAAQ,GAAG,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,QAAQ,CAAC;gBAClD,KAAK,MAAM,CAAC,KAAK,EAAE,KAAK,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,EAAE;oBACtD,MAAM,SAAS,GAAG,MAAM,IAAI,CAAC,OAAO,CAAC,YAAY,CAAC,KAAK,EAAE,KAAK,CAAC,CAAC;oBAChE,IAAI,SAAS,EAAE;wBACX,IAAI,SAAS,CAAC,OAAO,EAAE;4BACnB,uEAAuE;4BACvE,4EAA4E;4BAC5E,MAAM,UAAU,GAAG,MAAM,IAAI,CAAC,gBAAgB,CAC1C,SAAS,CAAC,IAAI,EACd,KAAK,KAAK,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,KAAK,EAC3B,SAAS,EACT,OAAO,CACV,CAAC;4BACF,CAAC,CAAC,QAAQ,CAAC,CAAC,KAAK,CAAC,GAAG,UAAU,CAAC;yBACnC;6BAAM;4BACH,4EAA4E;4BAC5E,IAAI,QAAQ,KAAK,QAAQ,EAAE;gCACvB,CAAC,CAAC,QAAQ,CAAC,CAAC,EAAE,GAAG,IAAI,CAAC;6BACzB;yBACJ;qBACJ;iBACJ;aACJ;YAED,OAAO,CAAC,CAAC;QACb,CAAC;KAAA;IAEK,WAAW,CACb,KAAa,EACb,SAAc,EACd,IAAS,EACT,SAA8B,EAC9B,OAAqB;8DACtB,CAAC;KAAA;CACP"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { default as DataHandler } from './data/handler';
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/handler/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,IAAI,WAAW,EAAE,MAAM,gBAAgB,CAAC"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { NextApiRequest, NextApiResponse } from 'next';
|
|
2
|
+
import { ServerErrorCode } from '../types';
|
|
3
|
+
export interface RequestHandler {
|
|
4
|
+
handle(req: NextApiRequest, res: NextApiResponse, path: string[]): Promise<void>;
|
|
5
|
+
}
|
|
6
|
+
export declare class RequestHandlerError extends Error {
|
|
7
|
+
readonly code: ServerErrorCode;
|
|
8
|
+
constructor(code: ServerErrorCode, message: string);
|
|
9
|
+
toString(): string;
|
|
10
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/handler/types.ts"],"names":[],"mappings":"AAWA,MAAM,OAAO,mBAAoB,SAAQ,KAAK;IAC1C,YAA4B,IAAqB,EAAE,OAAe;QAC9D,KAAK,CAAC,OAAO,CAAC,CAAC;QADS,SAAI,GAAJ,IAAI,CAAiB;IAEjD,CAAC;IAED,QAAQ;QACJ,OAAO,0BAA0B,IAAI,CAAC,IAAI,KAAK,IAAI,CAAC,OAAO,EAAE,CAAC;IAClE,CAAC;CACJ"}
|
package/lib/index.d.ts
CHANGED
|
@@ -1 +1,2 @@
|
|
|
1
|
-
export * from './
|
|
1
|
+
export * from './types';
|
|
2
|
+
export * from './request-handler';
|
package/lib/index.js
CHANGED
package/lib/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,SAAS,CAAC;AACxB,cAAc,mBAAmB,CAAC"}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import type { ScopedMutator } from 'swr/dist/types';
|
|
2
|
+
export declare function get<Data, Error = any>(url: string, args?: unknown): import("swr").SWRResponse<Data, Error>;
|
|
3
|
+
export declare function post<Data, Result>(url: string, data: Data, mutate: ScopedMutator<any>): Promise<Result>;
|
|
4
|
+
export declare function put<Data, Result>(url: string, data: Data, mutate: ScopedMutator<any>): Promise<Result>;
|
|
5
|
+
export declare function del<Result>(url: string, args: unknown, mutate: ScopedMutator<any>): Promise<Result>;
|
|
6
|
+
export declare function getMutate(): ScopedMutator<any>;
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
2
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
3
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
4
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
5
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
6
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
7
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
8
|
+
});
|
|
9
|
+
};
|
|
10
|
+
import useSWR, { useSWRConfig } from 'swr';
|
|
11
|
+
const fetcher = (url, options) => __awaiter(void 0, void 0, void 0, function* () {
|
|
12
|
+
const res = yield fetch(url, options);
|
|
13
|
+
if (!res.ok) {
|
|
14
|
+
const error = new Error('An error occurred while fetching the data.');
|
|
15
|
+
error.info = yield res.json();
|
|
16
|
+
error.status = res.status;
|
|
17
|
+
throw error;
|
|
18
|
+
}
|
|
19
|
+
return res.json();
|
|
20
|
+
});
|
|
21
|
+
function makeUrl(url, args) {
|
|
22
|
+
return args ? url + `q=${encodeURIComponent(JSON.stringify(args))}` : url;
|
|
23
|
+
}
|
|
24
|
+
export function get(url, args) {
|
|
25
|
+
return useSWR(makeUrl(url, args), fetcher);
|
|
26
|
+
}
|
|
27
|
+
export function post(url, data, mutate) {
|
|
28
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
29
|
+
const r = yield fetcher(url, {
|
|
30
|
+
method: 'POST',
|
|
31
|
+
headers: {
|
|
32
|
+
'content-type': 'application/json',
|
|
33
|
+
},
|
|
34
|
+
body: JSON.stringify(data),
|
|
35
|
+
});
|
|
36
|
+
mutate(url);
|
|
37
|
+
return r;
|
|
38
|
+
});
|
|
39
|
+
}
|
|
40
|
+
export function put(url, data, mutate) {
|
|
41
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
42
|
+
const r = yield fetcher(url, {
|
|
43
|
+
method: 'PUT',
|
|
44
|
+
headers: {
|
|
45
|
+
'content-type': 'application/json',
|
|
46
|
+
},
|
|
47
|
+
body: JSON.stringify(data),
|
|
48
|
+
});
|
|
49
|
+
mutate(url, r);
|
|
50
|
+
return r;
|
|
51
|
+
});
|
|
52
|
+
}
|
|
53
|
+
export function del(url, args, mutate) {
|
|
54
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
55
|
+
const reqUrl = makeUrl(url, args);
|
|
56
|
+
const r = yield fetcher(reqUrl, {
|
|
57
|
+
method: 'DELETE',
|
|
58
|
+
});
|
|
59
|
+
const path = url.split('/');
|
|
60
|
+
path.pop();
|
|
61
|
+
mutate(path.join('/'));
|
|
62
|
+
return r;
|
|
63
|
+
});
|
|
64
|
+
}
|
|
65
|
+
export function getMutate() {
|
|
66
|
+
const { mutate } = useSWRConfig();
|
|
67
|
+
return mutate;
|
|
68
|
+
}
|
|
69
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/request/index.ts"],"names":[],"mappings":";;;;;;;;;AAAA,OAAO,MAAM,EAAE,EAAE,YAAY,EAAE,MAAM,KAAK,CAAC;AAG3C,MAAM,OAAO,GAAG,CAAO,GAAW,EAAE,OAAqB,EAAE,EAAE;IACzD,MAAM,GAAG,GAAG,MAAM,KAAK,CAAC,GAAG,EAAE,OAAO,CAAC,CAAC;IACtC,IAAI,CAAC,GAAG,CAAC,EAAE,EAAE;QACT,MAAM,KAAK,GAA4C,IAAI,KAAK,CAC5D,4CAA4C,CAC/C,CAAC;QACF,KAAK,CAAC,IAAI,GAAG,MAAM,GAAG,CAAC,IAAI,EAAE,CAAC;QAC9B,KAAK,CAAC,MAAM,GAAG,GAAG,CAAC,MAAM,CAAC;QAC1B,MAAM,KAAK,CAAC;KACf;IACD,OAAO,GAAG,CAAC,IAAI,EAAE,CAAC;AACtB,CAAC,CAAA,CAAC;AAEF,SAAS,OAAO,CAAC,GAAW,EAAE,IAAa;IACvC,OAAO,IAAI,CAAC,CAAC,CAAC,GAAG,GAAG,KAAK,kBAAkB,CAAC,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC;AAC9E,CAAC;AAED,MAAM,UAAU,GAAG,CAAoB,GAAW,EAAE,IAAc;IAC9D,OAAO,MAAM,CAAc,OAAO,CAAC,GAAG,EAAE,IAAI,CAAC,EAAE,OAAO,CAAC,CAAC;AAC5D,CAAC;AAED,MAAM,UAAgB,IAAI,CACtB,GAAW,EACX,IAAU,EACV,MAA0B;;QAE1B,MAAM,CAAC,GAAW,MAAM,OAAO,CAAC,GAAG,EAAE;YACjC,MAAM,EAAE,MAAM;YACd,OAAO,EAAE;gBACL,cAAc,EAAE,kBAAkB;aACrC;YACD,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC;SAC7B,CAAC,CAAC;QACH,MAAM,CAAC,GAAG,CAAC,CAAC;QACZ,OAAO,CAAC,CAAC;IACb,CAAC;CAAA;AAED,MAAM,UAAgB,GAAG,CACrB,GAAW,EACX,IAAU,EACV,MAA0B;;QAE1B,MAAM,CAAC,GAAW,MAAM,OAAO,CAAC,GAAG,EAAE;YACjC,MAAM,EAAE,KAAK;YACb,OAAO,EAAE;gBACL,cAAc,EAAE,kBAAkB;aACrC;YACD,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC;SAC7B,CAAC,CAAC;QACH,MAAM,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC;QACf,OAAO,CAAC,CAAC;IACb,CAAC;CAAA;AAED,MAAM,UAAgB,GAAG,CACrB,GAAW,EACX,IAAa,EACb,MAA0B;;QAE1B,MAAM,MAAM,GAAG,OAAO,CAAC,GAAG,EAAE,IAAI,CAAC,CAAC;QAClC,MAAM,CAAC,GAAW,MAAM,OAAO,CAAC,MAAM,EAAE;YACpC,MAAM,EAAE,QAAQ;SACnB,CAAC,CAAC;QACH,MAAM,IAAI,GAAG,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;QAC5B,IAAI,CAAC,GAAG,EAAE,CAAC;QACX,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC;QACvB,OAAO,CAAC,CAAC;IACb,CAAC;CAAA;AAED,MAAM,UAAU,SAAS;IACrB,MAAM,EAAE,MAAM,EAAE,GAAG,YAAY,EAAE,CAAC;IAClC,OAAO,MAAM,CAAC;AAClB,CAAC"}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import { NextApiRequest, NextApiResponse } from 'next';
|
|
2
|
+
import { AuthUser, Service } from './types';
|
|
3
|
+
export declare type RequestHandlerOptions = {
|
|
4
|
+
getServerUser: (req: NextApiRequest, res: NextApiResponse) => Promise<AuthUser | undefined>;
|
|
5
|
+
};
|
|
6
|
+
export declare function RequestHandler<DbClient>(service: Service<DbClient>, options: RequestHandlerOptions): (req: NextApiRequest, res: NextApiResponse) => Promise<void>;
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
2
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
3
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
4
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
5
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
6
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
7
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
8
|
+
});
|
|
9
|
+
};
|
|
10
|
+
import { DataHandler } from './handler';
|
|
11
|
+
export function RequestHandler(service, options) {
|
|
12
|
+
const dataHandler = new DataHandler(service, options);
|
|
13
|
+
return (req, res) => __awaiter(this, void 0, void 0, function* () {
|
|
14
|
+
const [route, ...rest] = req.query.path;
|
|
15
|
+
switch (route) {
|
|
16
|
+
case 'data':
|
|
17
|
+
return dataHandler.handle(req, res, rest);
|
|
18
|
+
default:
|
|
19
|
+
res.status(404).json({ error: 'Unknown route: ' + route });
|
|
20
|
+
}
|
|
21
|
+
});
|
|
22
|
+
}
|
|
23
|
+
//# sourceMappingURL=request-handler.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"request-handler.js","sourceRoot":"","sources":["../src/request-handler.ts"],"names":[],"mappings":";;;;;;;;;AACA,OAAO,EAAE,WAAW,EAAE,MAAM,WAAW,CAAC;AAUxC,MAAM,UAAU,cAAc,CAC1B,OAA0B,EAC1B,OAA8B;IAE9B,MAAM,WAAW,GAAG,IAAI,WAAW,CAAW,OAAO,EAAE,OAAO,CAAC,CAAC;IAChE,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,KAAK,MAAM;gBACP,OAAO,WAAW,CAAC,MAAM,CAAC,GAAG,EAAE,GAAG,EAAE,IAAI,CAAC,CAAC;YAE9C;gBACI,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,iBAAiB,GAAG,KAAK,EAAE,CAAC,CAAC;SAClE;IACL,CAAC,CAAA,CAAC;AACN,CAAC"}
|
package/lib/request.d.ts
CHANGED
|
@@ -2,5 +2,5 @@ import type { ScopedMutator } from 'swr/dist/types';
|
|
|
2
2
|
export declare function get<Data, Error = any>(url: string, args?: unknown): import("swr").SWRResponse<Data, Error>;
|
|
3
3
|
export declare function post<Data, Result>(url: string, data: Data, mutate: ScopedMutator<any>): Promise<Result>;
|
|
4
4
|
export declare function put<Data, Result>(url: string, data: Data, mutate: ScopedMutator<any>): Promise<Result>;
|
|
5
|
-
export declare function del<Result>(url: string, mutate: ScopedMutator<any>): Promise<Result>;
|
|
5
|
+
export declare function del<Result>(url: string, args: unknown, mutate: ScopedMutator<any>): Promise<Result>;
|
|
6
6
|
export declare function getMutate(): ScopedMutator<any>;
|
package/lib/request.js
CHANGED
|
@@ -12,7 +12,6 @@ const fetcher = (url, options) => __awaiter(void 0, void 0, void 0, function* ()
|
|
|
12
12
|
const res = yield fetch(url, options);
|
|
13
13
|
if (!res.ok) {
|
|
14
14
|
const error = new Error('An error occurred while fetching the data.');
|
|
15
|
-
// Attach extra info to the error object.
|
|
16
15
|
error.info = yield res.json();
|
|
17
16
|
error.status = res.status;
|
|
18
17
|
throw error;
|
|
@@ -51,9 +50,10 @@ export function put(url, data, mutate) {
|
|
|
51
50
|
return r;
|
|
52
51
|
});
|
|
53
52
|
}
|
|
54
|
-
export function del(url, mutate) {
|
|
53
|
+
export function del(url, args, mutate) {
|
|
55
54
|
return __awaiter(this, void 0, void 0, function* () {
|
|
56
|
-
const
|
|
55
|
+
const reqUrl = makeUrl(url, args);
|
|
56
|
+
const r = yield fetcher(reqUrl, {
|
|
57
57
|
method: 'DELETE',
|
|
58
58
|
});
|
|
59
59
|
const path = url.split('/');
|
package/lib/request.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"request.js","sourceRoot":"","sources":["../src/request.ts"],"names":[],"mappings":";;;;;;;;;AAAA,OAAO,MAAM,EAAE,EAAE,YAAY,EAAE,MAAM,KAAK,CAAC;AAG3C,MAAM,OAAO,GAAG,CAAO,GAAW,EAAE,OAAqB,EAAE,EAAE;IACzD,MAAM,GAAG,GAAG,MAAM,KAAK,CAAC,GAAG,EAAE,OAAO,CAAC,CAAC;IACtC,IAAI,CAAC,GAAG,CAAC,EAAE,EAAE;QACT,MAAM,KAAK,GAA4C,IAAI,KAAK,CAC5D,4CAA4C,CAC/C,CAAC;QACF,
|
|
1
|
+
{"version":3,"file":"request.js","sourceRoot":"","sources":["../src/request.ts"],"names":[],"mappings":";;;;;;;;;AAAA,OAAO,MAAM,EAAE,EAAE,YAAY,EAAE,MAAM,KAAK,CAAC;AAG3C,MAAM,OAAO,GAAG,CAAO,GAAW,EAAE,OAAqB,EAAE,EAAE;IACzD,MAAM,GAAG,GAAG,MAAM,KAAK,CAAC,GAAG,EAAE,OAAO,CAAC,CAAC;IACtC,IAAI,CAAC,GAAG,CAAC,EAAE,EAAE;QACT,MAAM,KAAK,GAA4C,IAAI,KAAK,CAC5D,4CAA4C,CAC/C,CAAC;QACF,KAAK,CAAC,IAAI,GAAG,MAAM,GAAG,CAAC,IAAI,EAAE,CAAC;QAC9B,KAAK,CAAC,MAAM,GAAG,GAAG,CAAC,MAAM,CAAC;QAC1B,MAAM,KAAK,CAAC;KACf;IACD,OAAO,GAAG,CAAC,IAAI,EAAE,CAAC;AACtB,CAAC,CAAA,CAAC;AAEF,SAAS,OAAO,CAAC,GAAW,EAAE,IAAa;IACvC,OAAO,IAAI,CAAC,CAAC,CAAC,GAAG,GAAG,KAAK,kBAAkB,CAAC,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC;AAC9E,CAAC;AAED,MAAM,UAAU,GAAG,CAAoB,GAAW,EAAE,IAAc;IAC9D,OAAO,MAAM,CAAc,OAAO,CAAC,GAAG,EAAE,IAAI,CAAC,EAAE,OAAO,CAAC,CAAC;AAC5D,CAAC;AAED,MAAM,UAAgB,IAAI,CACtB,GAAW,EACX,IAAU,EACV,MAA0B;;QAE1B,MAAM,CAAC,GAAW,MAAM,OAAO,CAAC,GAAG,EAAE;YACjC,MAAM,EAAE,MAAM;YACd,OAAO,EAAE;gBACL,cAAc,EAAE,kBAAkB;aACrC;YACD,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC;SAC7B,CAAC,CAAC;QACH,MAAM,CAAC,GAAG,CAAC,CAAC;QACZ,OAAO,CAAC,CAAC;IACb,CAAC;CAAA;AAED,MAAM,UAAgB,GAAG,CACrB,GAAW,EACX,IAAU,EACV,MAA0B;;QAE1B,MAAM,CAAC,GAAW,MAAM,OAAO,CAAC,GAAG,EAAE;YACjC,MAAM,EAAE,KAAK;YACb,OAAO,EAAE;gBACL,cAAc,EAAE,kBAAkB;aACrC;YACD,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC;SAC7B,CAAC,CAAC;QACH,MAAM,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC;QACf,OAAO,CAAC,CAAC;IACb,CAAC;CAAA;AAED,MAAM,UAAgB,GAAG,CACrB,GAAW,EACX,IAAa,EACb,MAA0B;;QAE1B,MAAM,MAAM,GAAG,OAAO,CAAC,GAAG,EAAE,IAAI,CAAC,CAAC;QAClC,MAAM,CAAC,GAAW,MAAM,OAAO,CAAC,MAAM,EAAE;YACpC,MAAM,EAAE,QAAQ;SACnB,CAAC,CAAC;QACH,MAAM,IAAI,GAAG,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;QAC5B,IAAI,CAAC,GAAG,EAAE,CAAC;QACX,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC;QACvB,OAAO,CAAC,CAAC;IACb,CAAC;CAAA;AAED,MAAM,UAAU,SAAS;IACrB,MAAM,EAAE,MAAM,EAAE,GAAG,YAAY,EAAE,CAAC;IAClC,OAAO,MAAM,CAAC;AAClB,CAAC"}
|
package/lib/types.d.ts
ADDED
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
export interface DbOperations {
|
|
2
|
+
findMany(args: any): Promise<any[]>;
|
|
3
|
+
findFirst(args: any): Promise<any>;
|
|
4
|
+
create(args: any): Promise<any>;
|
|
5
|
+
update(args: any): Promise<any>;
|
|
6
|
+
delete(args: any): Promise<any>;
|
|
7
|
+
}
|
|
8
|
+
export declare type PolicyKind = 'allow' | 'deny';
|
|
9
|
+
export declare type PolicyOperationKind = 'create' | 'update' | 'read' | 'delete';
|
|
10
|
+
export declare type AuthUser = {
|
|
11
|
+
id: string;
|
|
12
|
+
} & Record<string, any>;
|
|
13
|
+
export declare type QueryContext = {
|
|
14
|
+
user?: AuthUser;
|
|
15
|
+
};
|
|
16
|
+
export declare type FieldInfo = {
|
|
17
|
+
type: string;
|
|
18
|
+
isArray: boolean;
|
|
19
|
+
};
|
|
20
|
+
export interface Service<DbClient = any> {
|
|
21
|
+
get db(): DbClient;
|
|
22
|
+
resolveField(model: string, field: string): Promise<FieldInfo | undefined>;
|
|
23
|
+
buildQueryGuard(model: string, operation: PolicyOperationKind, context: QueryContext): any;
|
|
24
|
+
}
|
|
25
|
+
export declare enum ServerErrorCode {
|
|
26
|
+
ENTITY_NOT_FOUND = "ENTITY_NOT_FOUND",
|
|
27
|
+
INVALID_REQUEST_PARAMS = "INVALID_REQUEST_PARAMS",
|
|
28
|
+
DENIED_BY_POLICY = "DENIED_BY_POLICY",
|
|
29
|
+
UNIQUE_CONSTRAINT_VIOLATION = "UNIQUE_CONSTRAINT_VIOLATION",
|
|
30
|
+
REFERENCE_CONSTRAINT_VIOLATION = "REFERENCE_CONSTRAINT_VIOLATION",
|
|
31
|
+
UNKNOWN = "UNKNOWN"
|
|
32
|
+
}
|
package/lib/types.js
ADDED
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
export var ServerErrorCode;
|
|
2
|
+
(function (ServerErrorCode) {
|
|
3
|
+
ServerErrorCode["ENTITY_NOT_FOUND"] = "ENTITY_NOT_FOUND";
|
|
4
|
+
ServerErrorCode["INVALID_REQUEST_PARAMS"] = "INVALID_REQUEST_PARAMS";
|
|
5
|
+
ServerErrorCode["DENIED_BY_POLICY"] = "DENIED_BY_POLICY";
|
|
6
|
+
ServerErrorCode["UNIQUE_CONSTRAINT_VIOLATION"] = "UNIQUE_CONSTRAINT_VIOLATION";
|
|
7
|
+
ServerErrorCode["REFERENCE_CONSTRAINT_VIOLATION"] = "REFERENCE_CONSTRAINT_VIOLATION";
|
|
8
|
+
ServerErrorCode["UNKNOWN"] = "UNKNOWN";
|
|
9
|
+
})(ServerErrorCode || (ServerErrorCode = {}));
|
|
10
|
+
//# sourceMappingURL=types.js.map
|
package/lib/types.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAgCA,MAAM,CAAN,IAAY,eAOX;AAPD,WAAY,eAAe;IACvB,wDAAqC,CAAA;IACrC,oEAAiD,CAAA;IACjD,wDAAqC,CAAA;IACrC,8EAA2D,CAAA;IAC3D,oFAAiE,CAAA;IACjE,sCAAmB,CAAA;AACvB,CAAC,EAPW,eAAe,KAAf,eAAe,QAO1B"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@zenstackhq/runtime",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.2",
|
|
4
4
|
"description": "ZenStack runtime library",
|
|
5
5
|
"main": "lib/index.js",
|
|
6
6
|
"types": "lib/index.d.ts",
|
|
@@ -11,16 +11,28 @@
|
|
|
11
11
|
"lib/**/*"
|
|
12
12
|
],
|
|
13
13
|
"dependencies": {
|
|
14
|
+
"deepcopy": "^2.1.0",
|
|
14
15
|
"swr": "^1.3.0"
|
|
15
16
|
},
|
|
16
17
|
"peerDependencies": {
|
|
18
|
+
"next": "12.3.1",
|
|
17
19
|
"react": "^17.0.2 || ^18",
|
|
18
20
|
"react-dom": "^17.0.2 || ^18"
|
|
19
21
|
},
|
|
20
22
|
"devDependencies": {
|
|
23
|
+
"@types/jest": "^29.0.3",
|
|
24
|
+
"@types/node": "^14.18.29",
|
|
25
|
+
"jest": "^29.0.3",
|
|
26
|
+
"ts-jest": "^29.0.1",
|
|
27
|
+
"ts-node": "^10.9.1",
|
|
28
|
+
"tsc-alias": "^1.7.0",
|
|
29
|
+
"tsconfig-paths-jest": "^0.0.1",
|
|
21
30
|
"typescript": "^4.6.2"
|
|
22
31
|
},
|
|
23
32
|
"scripts": {
|
|
24
|
-
"build": "tsc"
|
|
33
|
+
"build": "tsc",
|
|
34
|
+
"watch": "tsc --watch",
|
|
35
|
+
"test": "jest",
|
|
36
|
+
"npm-publish": "pnpm build && pnpm publish --no-git-checks --access public"
|
|
25
37
|
}
|
|
26
38
|
}
|