@spinajs/orm-api 2.0.180 → 2.0.182
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/cjs/PlainJsonCollectionTransformer.d.ts +8 -8
- package/lib/cjs/PlainJsonCollectionTransformer.js +29 -29
- package/lib/cjs/PlainJsonCollectionTransformer.js.map +1 -1
- package/lib/cjs/config/orm-api.d.ts +16 -16
- package/lib/cjs/config/orm-api.js +24 -24
- package/lib/cjs/controllers/JsonApi.js +244 -244
- package/lib/cjs/controllers/crud/Create.d.ts +15 -15
- package/lib/cjs/controllers/crud/Create.js +144 -144
- package/lib/cjs/controllers/crud/Create.js.map +1 -1
- package/lib/cjs/controllers/crud/Delete.d.ts +15 -15
- package/lib/cjs/controllers/crud/Delete.js +157 -157
- package/lib/cjs/controllers/crud/Delete.js.map +1 -1
- package/lib/cjs/controllers/crud/Read.d.ts +39 -39
- package/lib/cjs/controllers/crud/Read.js +226 -226
- package/lib/cjs/controllers/crud/Read.js.map +1 -1
- package/lib/cjs/controllers/crud/Update.d.ts +12 -12
- package/lib/cjs/controllers/crud/Update.js +98 -98
- package/lib/cjs/controllers/crud/Update.js.map +1 -1
- package/lib/cjs/dto/QueryArgs.d.ts +8 -8
- package/lib/cjs/dto/QueryArgs.js +27 -27
- package/lib/cjs/dto/QueryArgs.js.map +1 -1
- package/lib/cjs/dto/QueryFilter.d.ts +5 -5
- package/lib/cjs/dto/QueryFilter.js +30 -30
- package/lib/cjs/dto/QueryFilter.js.map +1 -1
- package/lib/cjs/dto/QueryIncludes.d.ts +4 -4
- package/lib/cjs/dto/QueryIncludes.js +30 -30
- package/lib/cjs/dto/QueryIncludes.js.map +1 -1
- package/lib/cjs/hydrators/QueryFilterHydrator.d.ts +4 -4
- package/lib/cjs/hydrators/QueryFilterHydrator.js +14 -14
- package/lib/cjs/hydrators/QueryIncludesHydrator.d.ts +4 -4
- package/lib/cjs/hydrators/QueryIncludesHydrator.js +20 -20
- package/lib/cjs/index.d.ts +28 -28
- package/lib/cjs/index.js +100 -100
- package/lib/cjs/index.js.map +1 -1
- package/lib/cjs/interfaces.d.ts +41 -41
- package/lib/cjs/interfaces.js +49 -49
- package/lib/cjs/interfaces.js.map +1 -1
- package/lib/cjs/middleware.d.ts +21 -21
- package/lib/cjs/middleware.js +30 -30
- package/lib/cjs/policies/FindModelType.d.ts +7 -7
- package/lib/cjs/policies/FindModelType.js +42 -42
- package/lib/cjs/policies/FindModelType.js.map +1 -1
- package/lib/cjs/route-args/ModelType.d.ts +12 -12
- package/lib/cjs/route-args/ModelType.js +38 -38
- package/lib/cjs/route-args/ModelType.js.map +1 -1
- package/lib/cjs/schemas/QueryArgs.schema.d.ts +19 -19
- package/lib/cjs/schemas/QueryArgs.schema.js +12 -12
- package/lib/cjs/schemas/QueryFilter.schema.d.ts +20 -20
- package/lib/cjs/schemas/QueryFilter.schema.js +15 -15
- package/lib/cjs/schemas/QueryIncludes.schema.d.ts +7 -7
- package/lib/cjs/schemas/QueryIncludes.schema.js +9 -9
- package/lib/mjs/PlainJsonCollectionTransformer.d.ts +8 -8
- package/lib/mjs/PlainJsonCollectionTransformer.js +26 -26
- package/lib/mjs/PlainJsonCollectionTransformer.js.map +1 -1
- package/lib/mjs/config/orm-api.d.ts +16 -16
- package/lib/mjs/config/orm-api.js +22 -22
- package/lib/mjs/controllers/JsonApi.d.ts +1 -1
- package/lib/mjs/controllers/JsonApi.js +245 -245
- package/lib/mjs/controllers/crud/Create.d.ts +15 -15
- package/lib/mjs/controllers/crud/Create.js +138 -138
- package/lib/mjs/controllers/crud/Create.js.map +1 -1
- package/lib/mjs/controllers/crud/Crud.d.ts +1 -1
- package/lib/mjs/controllers/crud/Crud.js +1 -1
- package/lib/mjs/controllers/crud/Delete.d.ts +15 -15
- package/lib/mjs/controllers/crud/Delete.js +154 -154
- package/lib/mjs/controllers/crud/Delete.js.map +1 -1
- package/lib/mjs/controllers/crud/Read.d.ts +39 -39
- package/lib/mjs/controllers/crud/Read.js +223 -223
- package/lib/mjs/controllers/crud/Read.js.map +1 -1
- package/lib/mjs/controllers/crud/Update.d.ts +12 -12
- package/lib/mjs/controllers/crud/Update.js +95 -95
- package/lib/mjs/controllers/crud/Update.js.map +1 -1
- package/lib/mjs/dto/QueryArgs.d.ts +8 -8
- package/lib/mjs/dto/QueryArgs.js +21 -21
- package/lib/mjs/dto/QueryArgs.js.map +1 -1
- package/lib/mjs/dto/QueryFilter.d.ts +5 -5
- package/lib/mjs/dto/QueryFilter.js +24 -24
- package/lib/mjs/dto/QueryFilter.js.map +1 -1
- package/lib/mjs/dto/QueryIncludes.d.ts +4 -4
- package/lib/mjs/dto/QueryIncludes.js +24 -24
- package/lib/mjs/dto/QueryIncludes.js.map +1 -1
- package/lib/mjs/hydrators/QueryFilterHydrator.d.ts +4 -4
- package/lib/mjs/hydrators/QueryFilterHydrator.js +10 -10
- package/lib/mjs/hydrators/QueryIncludesHydrator.d.ts +4 -4
- package/lib/mjs/hydrators/QueryIncludesHydrator.js +13 -13
- package/lib/mjs/index.d.ts +28 -28
- package/lib/mjs/index.js +94 -94
- package/lib/mjs/index.js.map +1 -1
- package/lib/mjs/interfaces.d.ts +41 -41
- package/lib/mjs/interfaces.js +44 -44
- package/lib/mjs/interfaces.js.map +1 -1
- package/lib/mjs/middleware.d.ts +21 -21
- package/lib/mjs/middleware.js +26 -26
- package/lib/mjs/policies/FindModelType.d.ts +7 -7
- package/lib/mjs/policies/FindModelType.js +39 -39
- package/lib/mjs/policies/FindModelType.js.map +1 -1
- package/lib/mjs/route-args/ModelType.d.ts +12 -12
- package/lib/mjs/route-args/ModelType.js +34 -34
- package/lib/mjs/route-args/ModelType.js.map +1 -1
- package/lib/mjs/schemas/QueryArgs.schema.d.ts +19 -19
- package/lib/mjs/schemas/QueryArgs.schema.js +10 -10
- package/lib/mjs/schemas/QueryFilter.schema.d.ts +20 -20
- package/lib/mjs/schemas/QueryFilter.schema.js +13 -13
- package/lib/mjs/schemas/QueryIncludes.schema.d.ts +7 -7
- package/lib/mjs/schemas/QueryIncludes.schema.js +7 -7
- package/lib/tsconfig.cjs.tsbuildinfo +1 -1
- package/lib/tsconfig.mjs.tsbuildinfo +1 -1
- package/package.json +12 -12
|
@@ -1,246 +1,246 @@
|
|
|
1
|
-
// import { Autoinject, Constructor, DI, Inject } from '@spinajs/di';
|
|
2
|
-
// import { BaseController, ArgHydrator, Hydrator, Ok, Del, Post, Query, Req } from '@spinajs/http';
|
|
3
|
-
// import { BasePath, Get, Param, Body, Patch } from '@spinajs/http';
|
|
4
|
-
// import { extractModelDescriptor, ModelBase, SelectQueryBuilder, Orm, DeleteQueryBuilder, createQuery, UpdateQueryBuilder, InsertQueryBuilder, IModelDescriptor, RelationType } from '@spinajs/orm';
|
|
5
|
-
// import _ from 'lodash';
|
|
6
|
-
// import * as express from 'express';
|
|
7
|
-
// import { RepositoryMiddleware } from '../middleware.js';
|
|
8
|
-
// import { JsonApiIncomingObject } from '../interfaces.js';
|
|
9
|
-
export {};
|
|
10
|
-
// class IncludesHydrator extends ArgHydrator {
|
|
11
|
-
// public async hydrate(input: any): Promise<any> {
|
|
12
|
-
// return new Includes(input ? input.split(',').map((x: string) => x.split('.')) : []);
|
|
13
|
-
// }
|
|
14
|
-
// }
|
|
15
|
-
// class FiltersHydrator extends ArgHydrator {
|
|
16
|
-
// public async hydrate(input: any): Promise<any> {
|
|
17
|
-
// return new Filters(input ? JSON.parse(input) : []);
|
|
18
|
-
// }
|
|
19
|
-
// }
|
|
20
|
-
// class ModelParamHydrator extends ArgHydrator {
|
|
21
|
-
// @Autoinject(Orm)
|
|
22
|
-
// protected Orm: Orm;
|
|
23
|
-
// public async hydrate(input: string): Promise<any> {
|
|
24
|
-
// const model = this.Orm.Models.find((x) => x.name.toLowerCase() === input.toLowerCase());
|
|
25
|
-
// if (!model) {
|
|
26
|
-
// return null;
|
|
27
|
-
// }
|
|
28
|
-
// const desc = extractModelDescriptor(model.type);
|
|
29
|
-
// const param = new Model();
|
|
30
|
-
// param.Descriptor = desc;
|
|
31
|
-
// param.Type = model.type;
|
|
32
|
-
// return param;
|
|
33
|
-
// }
|
|
34
|
-
// }
|
|
35
|
-
// function dehydrate(model: ModelBase, omit?: string[]) {
|
|
36
|
-
// const dObj = {
|
|
37
|
-
// type: model.constructor.name,
|
|
38
|
-
// id: model.PrimaryKeyValue,
|
|
39
|
-
// attributes: model.dehydrate(omit),
|
|
40
|
-
// relationships: _.mapValues(_.groupBy(model.getFlattenRelationModels(false), '__relationKey__'), (x) => {
|
|
41
|
-
// return x.map((xx) => {
|
|
42
|
-
// return {
|
|
43
|
-
// type: xx.constructor.name,
|
|
44
|
-
// id: xx.PrimaryKeyValue,
|
|
45
|
-
// };
|
|
46
|
-
// });
|
|
47
|
-
// }),
|
|
48
|
-
// };
|
|
49
|
-
// return dObj;
|
|
50
|
-
// }
|
|
51
|
-
// function modelToJsonApi(model: ModelBase | ModelBase[]) {
|
|
52
|
-
// return {
|
|
53
|
-
// data: Array.isArray(model) ? model.map((m) => dehydrate(m)) : dehydrate(model),
|
|
54
|
-
// included: Array.isArray(model) ? _.flatMap(model, extractIncluded) : extractIncluded(model),
|
|
55
|
-
// };
|
|
56
|
-
// }
|
|
57
|
-
// function extractIncluded(model: ModelBase) {
|
|
58
|
-
// return model.getFlattenRelationModels(true).map((m) => dehydrate(m));
|
|
59
|
-
// }
|
|
60
|
-
// function applyQueryIncludes(includes: Includes, query: SelectQueryBuilder<any>) {
|
|
61
|
-
// let currQuery: SelectQueryBuilder<any> = null;
|
|
62
|
-
// includes.Param.forEach((i) => {
|
|
63
|
-
// currQuery = query;
|
|
64
|
-
// i.forEach((ii: string) => {
|
|
65
|
-
// currQuery.populate(ii, function () {
|
|
66
|
-
// currQuery = this;
|
|
67
|
-
// });
|
|
68
|
-
// });
|
|
69
|
-
// });
|
|
70
|
-
// }
|
|
71
|
-
// @Hydrator(IncludesHydrator)
|
|
72
|
-
// class Includes {
|
|
73
|
-
// constructor(public Param: string[][]) {}
|
|
74
|
-
// }
|
|
75
|
-
// @Hydrator(FiltersHydrator)
|
|
76
|
-
// class Filters {
|
|
77
|
-
// constructor(public Param: any) {}
|
|
78
|
-
// }
|
|
79
|
-
// @Hydrator(ModelParamHydrator)
|
|
80
|
-
// class Model {
|
|
81
|
-
// public Type: Constructor<ModelBase>;
|
|
82
|
-
// public Descriptor: IModelDescriptor;
|
|
83
|
-
// public get SelectQuery() {
|
|
84
|
-
// return createQuery(this.Type, SelectQueryBuilder).query as SelectQueryBuilder<ModelBase>;
|
|
85
|
-
// }
|
|
86
|
-
// public get InserQuery() {
|
|
87
|
-
// return createQuery(this.Type, InsertQueryBuilder).query;
|
|
88
|
-
// }
|
|
89
|
-
// public get DeleteQuery() {
|
|
90
|
-
// return createQuery(this.Type, DeleteQueryBuilder).query;
|
|
91
|
-
// }
|
|
92
|
-
// public get UpdateQueryBuilder() {
|
|
93
|
-
// return createQuery(this.Type, UpdateQueryBuilder).query;
|
|
94
|
-
// }
|
|
95
|
-
// }
|
|
96
|
-
// const PrimaryKeySchema = {
|
|
97
|
-
// $id: 'JsonApiPrimaryKeySchema',
|
|
98
|
-
// title: 'Json api primary key schema for id parameter',
|
|
99
|
-
// anyOf: [
|
|
100
|
-
// { type: 'string', minLength: 0, maxLength: 16 },
|
|
101
|
-
// { type: 'number', minimum: 0 },
|
|
102
|
-
// { type: 'string', pattern: '^[0-9a-f]{8}-?[0-9a-f]{4}-?[0-9a-f]{4}-?[0-9a-f]{4}-?[0-9a-f]{12}$', minLength: 32, maxLength: 36 },
|
|
103
|
-
// ],
|
|
104
|
-
// };
|
|
105
|
-
// const modelSchema = {
|
|
106
|
-
// $id: 'JsonApiModelSchema',
|
|
107
|
-
// title: 'Json api modele/resource schema',
|
|
108
|
-
// type: 'string',
|
|
109
|
-
// minLength: 0,
|
|
110
|
-
// maxLength: 32,
|
|
111
|
-
// };
|
|
112
|
-
// const genericStringSchema = {
|
|
113
|
-
// $id: 'JsonApiIncludeSchema',
|
|
114
|
-
// title: 'Json api modele/resource schema',
|
|
115
|
-
// type: 'string',
|
|
116
|
-
// minLength: 0,
|
|
117
|
-
// maxLength: 256,
|
|
118
|
-
// };
|
|
119
|
-
// @BasePath('repository')
|
|
120
|
-
// @Inject(Orm)
|
|
121
|
-
// export class JsonApi extends BaseController {
|
|
122
|
-
// protected Middlewares: RepositoryMiddleware[];
|
|
123
|
-
// constructor(protected Orm: Orm) {
|
|
124
|
-
// super();
|
|
125
|
-
// }
|
|
126
|
-
// public async resolve(): Promise<void> {
|
|
127
|
-
// super.resolve();
|
|
128
|
-
// this.Middlewares = await DI.resolve(Array.ofType(RepositoryMiddleware));
|
|
129
|
-
// }
|
|
130
|
-
// @Get(':model/:id', {
|
|
131
|
-
// model: modelSchema,
|
|
132
|
-
// id: PrimaryKeySchema,
|
|
133
|
-
// include: genericStringSchema,
|
|
134
|
-
// _filters: genericStringSchema,
|
|
135
|
-
// })
|
|
136
|
-
// public async get(@Param() model: Model, @Param() id: string | number, @Query() include: Includes, @Query() _filters: Filters, @Req() req: express.Request) {
|
|
137
|
-
// await Promise.all(this.Middlewares.map((m) => m.onGetMiddlewareStart(id, req)));
|
|
138
|
-
// const query = model.SelectQuery.select('*').where(model.Descriptor.PrimaryKey, id);
|
|
139
|
-
// applyQueryIncludes(include, query);
|
|
140
|
-
// this.Middlewares.forEach((m) => m.onGetMiddlewareQuery(query, model.Type, req));
|
|
141
|
-
// const result = await query.firstOrFail();
|
|
142
|
-
// let jResult = modelToJsonApi(result);
|
|
143
|
-
// this.Middlewares.forEach((m) => {
|
|
144
|
-
// jResult = m.onGetMiddlewareResult(jResult, req);
|
|
145
|
-
// });
|
|
146
|
-
// return new Ok(jResult);
|
|
147
|
-
// }
|
|
148
|
-
// @Get(':model', {
|
|
149
|
-
// model: modelSchema,
|
|
150
|
-
// include: genericStringSchema,
|
|
151
|
-
// _filters: genericStringSchema,
|
|
152
|
-
// })
|
|
153
|
-
// public async getAll(@Param() model: Model, @Query() page: number, @Query() perPage: number, @Query() order: string, @Query() orderDirection: 'ASC' | 'DESC', @Query() include: Includes, @Query() _filters: Filters, @Req() req: express.Request) {
|
|
154
|
-
// await Promise.all(this.Middlewares.map((m) => m.onGetAllMiddlewareStart(req)));
|
|
155
|
-
// const query = model.SelectQuery.select('*')
|
|
156
|
-
// .take(perPage)
|
|
157
|
-
// .skip(page * perPage);
|
|
158
|
-
// if (order) {
|
|
159
|
-
// query.order(order, orderDirection ?? 'ASC');
|
|
160
|
-
// }
|
|
161
|
-
// applyQueryIncludes(include, query);
|
|
162
|
-
// this.Middlewares.forEach((m) => m.onGetAllMiddlewareQuery(query, model.Type, req));
|
|
163
|
-
// const result = await query;
|
|
164
|
-
// let jResult = modelToJsonApi(result);
|
|
165
|
-
// this.Middlewares.forEach((m) => {
|
|
166
|
-
// jResult = m.onGetAllMiddlewareResult(jResult, req);
|
|
167
|
-
// });
|
|
168
|
-
// return new Ok(jResult);
|
|
169
|
-
// }
|
|
170
|
-
// @Del(':model/:id', {
|
|
171
|
-
// model: modelSchema,
|
|
172
|
-
// id: PrimaryKeySchema,
|
|
173
|
-
// })
|
|
174
|
-
// public async del(@Param() model: Model, @Param() id: string | number, @Req() req: express.Request) {
|
|
175
|
-
// await Promise.all(this.Middlewares.map((m) => m.onDeleteMiddlewareStart(id, req)));
|
|
176
|
-
// const entity: ModelBase = await model.SelectQuery.where(model.Descriptor.PrimaryKey, id).firstOrFail();
|
|
177
|
-
// await entity.destroy();
|
|
178
|
-
// this.Middlewares.forEach((m) => m.onDeleteMiddlewareResult(req));
|
|
179
|
-
// return new Ok();
|
|
180
|
-
// }
|
|
181
|
-
// @Patch(':model/:id', {
|
|
182
|
-
// model: modelSchema,
|
|
183
|
-
// id: PrimaryKeySchema,
|
|
184
|
-
// })
|
|
185
|
-
// public async patch(@Param() model: Model, @Param() id: string | number, @Body() incoming: JsonApiIncomingObject, @Req() req: express.Request) {
|
|
186
|
-
// await Promise.all(this.Middlewares.map((m) => m.onUpdateMiddlewareStart(id, incoming, req)));
|
|
187
|
-
// const entity: ModelBase = await model.SelectQuery.where(model.Descriptor.PrimaryKey, id).firstOrFail();
|
|
188
|
-
// await this.updateOneToOneRelations(incoming, model, entity);
|
|
189
|
-
// if (incoming.data.attributes) {
|
|
190
|
-
// entity.hydrate(incoming.data.attributes);
|
|
191
|
-
// }
|
|
192
|
-
// await entity.update();
|
|
193
|
-
// await this.updateOneToMany(incoming, model, entity);
|
|
194
|
-
// let jResult = modelToJsonApi(entity);
|
|
195
|
-
// this.Middlewares.forEach((m) => {
|
|
196
|
-
// jResult = m.onUpdateMiddlewareResult(jResult, req);
|
|
197
|
-
// });
|
|
198
|
-
// return new Ok(jResult);
|
|
199
|
-
// }
|
|
200
|
-
// @Post(':model', {
|
|
201
|
-
// model: modelSchema,
|
|
202
|
-
// })
|
|
203
|
-
// public async insert(@Param() model: Model, @Body() incoming: JsonApiIncomingObject, @Req() req: express.Request) {
|
|
204
|
-
// await Promise.all(this.Middlewares.map((m) => m.onInsertMiddlewareStart(incoming, req)));
|
|
205
|
-
// const entity: ModelBase = new model.Type();
|
|
206
|
-
// entity.hydrate(incoming.data.attributes);
|
|
207
|
-
// await this.updateOneToOneRelations(incoming, model, entity);
|
|
208
|
-
// await entity.insert();
|
|
209
|
-
// await this.updateOneToMany(incoming, model, entity);
|
|
210
|
-
// let jResult = modelToJsonApi(entity);
|
|
211
|
-
// this.Middlewares.forEach((m) => {
|
|
212
|
-
// jResult = m.onInsertMiddlewareResult(jResult, req);
|
|
213
|
-
// });
|
|
214
|
-
// return new Ok(jResult);
|
|
215
|
-
// }
|
|
216
|
-
// protected async updateOneToOneRelations(incoming: JsonApiIncomingObject, model: Model, entity: ModelBase) {
|
|
217
|
-
// // fillout one to one relations if possible
|
|
218
|
-
// if (incoming.data.relationships) {
|
|
219
|
-
// for (const key in incoming.data.relationships) {
|
|
220
|
-
// const relation = model.Descriptor.Relations.get(key);
|
|
221
|
-
// if (relation.Type === RelationType.One) {
|
|
222
|
-
// (entity as any)[relation.ForeignKey] = incoming.data.relationships[key].data.id;
|
|
223
|
-
// }
|
|
224
|
-
// }
|
|
225
|
-
// }
|
|
226
|
-
// }
|
|
227
|
-
// protected async updateOneToMany(incoming: JsonApiIncomingObject, model: Model, entity: ModelBase) {
|
|
228
|
-
// if (incoming.data.relationships) {
|
|
229
|
-
// for (const key in incoming.data.relationships) {
|
|
230
|
-
// const relation = model.Descriptor.Relations.get(key);
|
|
231
|
-
// if (relation.Type === RelationType.Many) {
|
|
232
|
-
// const rQuery = createQuery(relation.TargetModel, UpdateQueryBuilder).query;
|
|
233
|
-
// await rQuery
|
|
234
|
-
// .update({
|
|
235
|
-
// [relation.ForeignKey]: entity.PrimaryKeyValue,
|
|
236
|
-
// })
|
|
237
|
-
// .whereIn(
|
|
238
|
-
// relation.PrimaryKey,
|
|
239
|
-
// incoming.data.relationships[key].data.map((x: any) => x.id),
|
|
240
|
-
// );
|
|
241
|
-
// }
|
|
242
|
-
// }
|
|
243
|
-
// }
|
|
244
|
-
// }
|
|
245
|
-
// }
|
|
1
|
+
// import { Autoinject, Constructor, DI, Inject } from '@spinajs/di';
|
|
2
|
+
// import { BaseController, ArgHydrator, Hydrator, Ok, Del, Post, Query, Req } from '@spinajs/http';
|
|
3
|
+
// import { BasePath, Get, Param, Body, Patch } from '@spinajs/http';
|
|
4
|
+
// import { extractModelDescriptor, ModelBase, SelectQueryBuilder, Orm, DeleteQueryBuilder, createQuery, UpdateQueryBuilder, InsertQueryBuilder, IModelDescriptor, RelationType } from '@spinajs/orm';
|
|
5
|
+
// import _ from 'lodash';
|
|
6
|
+
// import * as express from 'express';
|
|
7
|
+
// import { RepositoryMiddleware } from '../middleware.js';
|
|
8
|
+
// import { JsonApiIncomingObject } from '../interfaces.js';
|
|
9
|
+
export {};
|
|
10
|
+
// class IncludesHydrator extends ArgHydrator {
|
|
11
|
+
// public async hydrate(input: any): Promise<any> {
|
|
12
|
+
// return new Includes(input ? input.split(',').map((x: string) => x.split('.')) : []);
|
|
13
|
+
// }
|
|
14
|
+
// }
|
|
15
|
+
// class FiltersHydrator extends ArgHydrator {
|
|
16
|
+
// public async hydrate(input: any): Promise<any> {
|
|
17
|
+
// return new Filters(input ? JSON.parse(input) : []);
|
|
18
|
+
// }
|
|
19
|
+
// }
|
|
20
|
+
// class ModelParamHydrator extends ArgHydrator {
|
|
21
|
+
// @Autoinject(Orm)
|
|
22
|
+
// protected Orm: Orm;
|
|
23
|
+
// public async hydrate(input: string): Promise<any> {
|
|
24
|
+
// const model = this.Orm.Models.find((x) => x.name.toLowerCase() === input.toLowerCase());
|
|
25
|
+
// if (!model) {
|
|
26
|
+
// return null;
|
|
27
|
+
// }
|
|
28
|
+
// const desc = extractModelDescriptor(model.type);
|
|
29
|
+
// const param = new Model();
|
|
30
|
+
// param.Descriptor = desc;
|
|
31
|
+
// param.Type = model.type;
|
|
32
|
+
// return param;
|
|
33
|
+
// }
|
|
34
|
+
// }
|
|
35
|
+
// function dehydrate(model: ModelBase, omit?: string[]) {
|
|
36
|
+
// const dObj = {
|
|
37
|
+
// type: model.constructor.name,
|
|
38
|
+
// id: model.PrimaryKeyValue,
|
|
39
|
+
// attributes: model.dehydrate(omit),
|
|
40
|
+
// relationships: _.mapValues(_.groupBy(model.getFlattenRelationModels(false), '__relationKey__'), (x) => {
|
|
41
|
+
// return x.map((xx) => {
|
|
42
|
+
// return {
|
|
43
|
+
// type: xx.constructor.name,
|
|
44
|
+
// id: xx.PrimaryKeyValue,
|
|
45
|
+
// };
|
|
46
|
+
// });
|
|
47
|
+
// }),
|
|
48
|
+
// };
|
|
49
|
+
// return dObj;
|
|
50
|
+
// }
|
|
51
|
+
// function modelToJsonApi(model: ModelBase | ModelBase[]) {
|
|
52
|
+
// return {
|
|
53
|
+
// data: Array.isArray(model) ? model.map((m) => dehydrate(m)) : dehydrate(model),
|
|
54
|
+
// included: Array.isArray(model) ? _.flatMap(model, extractIncluded) : extractIncluded(model),
|
|
55
|
+
// };
|
|
56
|
+
// }
|
|
57
|
+
// function extractIncluded(model: ModelBase) {
|
|
58
|
+
// return model.getFlattenRelationModels(true).map((m) => dehydrate(m));
|
|
59
|
+
// }
|
|
60
|
+
// function applyQueryIncludes(includes: Includes, query: SelectQueryBuilder<any>) {
|
|
61
|
+
// let currQuery: SelectQueryBuilder<any> = null;
|
|
62
|
+
// includes.Param.forEach((i) => {
|
|
63
|
+
// currQuery = query;
|
|
64
|
+
// i.forEach((ii: string) => {
|
|
65
|
+
// currQuery.populate(ii, function () {
|
|
66
|
+
// currQuery = this;
|
|
67
|
+
// });
|
|
68
|
+
// });
|
|
69
|
+
// });
|
|
70
|
+
// }
|
|
71
|
+
// @Hydrator(IncludesHydrator)
|
|
72
|
+
// class Includes {
|
|
73
|
+
// constructor(public Param: string[][]) {}
|
|
74
|
+
// }
|
|
75
|
+
// @Hydrator(FiltersHydrator)
|
|
76
|
+
// class Filters {
|
|
77
|
+
// constructor(public Param: any) {}
|
|
78
|
+
// }
|
|
79
|
+
// @Hydrator(ModelParamHydrator)
|
|
80
|
+
// class Model {
|
|
81
|
+
// public Type: Constructor<ModelBase>;
|
|
82
|
+
// public Descriptor: IModelDescriptor;
|
|
83
|
+
// public get SelectQuery() {
|
|
84
|
+
// return createQuery(this.Type, SelectQueryBuilder).query as SelectQueryBuilder<ModelBase>;
|
|
85
|
+
// }
|
|
86
|
+
// public get InserQuery() {
|
|
87
|
+
// return createQuery(this.Type, InsertQueryBuilder).query;
|
|
88
|
+
// }
|
|
89
|
+
// public get DeleteQuery() {
|
|
90
|
+
// return createQuery(this.Type, DeleteQueryBuilder).query;
|
|
91
|
+
// }
|
|
92
|
+
// public get UpdateQueryBuilder() {
|
|
93
|
+
// return createQuery(this.Type, UpdateQueryBuilder).query;
|
|
94
|
+
// }
|
|
95
|
+
// }
|
|
96
|
+
// const PrimaryKeySchema = {
|
|
97
|
+
// $id: 'JsonApiPrimaryKeySchema',
|
|
98
|
+
// title: 'Json api primary key schema for id parameter',
|
|
99
|
+
// anyOf: [
|
|
100
|
+
// { type: 'string', minLength: 0, maxLength: 16 },
|
|
101
|
+
// { type: 'number', minimum: 0 },
|
|
102
|
+
// { type: 'string', pattern: '^[0-9a-f]{8}-?[0-9a-f]{4}-?[0-9a-f]{4}-?[0-9a-f]{4}-?[0-9a-f]{12}$', minLength: 32, maxLength: 36 },
|
|
103
|
+
// ],
|
|
104
|
+
// };
|
|
105
|
+
// const modelSchema = {
|
|
106
|
+
// $id: 'JsonApiModelSchema',
|
|
107
|
+
// title: 'Json api modele/resource schema',
|
|
108
|
+
// type: 'string',
|
|
109
|
+
// minLength: 0,
|
|
110
|
+
// maxLength: 32,
|
|
111
|
+
// };
|
|
112
|
+
// const genericStringSchema = {
|
|
113
|
+
// $id: 'JsonApiIncludeSchema',
|
|
114
|
+
// title: 'Json api modele/resource schema',
|
|
115
|
+
// type: 'string',
|
|
116
|
+
// minLength: 0,
|
|
117
|
+
// maxLength: 256,
|
|
118
|
+
// };
|
|
119
|
+
// @BasePath('repository')
|
|
120
|
+
// @Inject(Orm)
|
|
121
|
+
// export class JsonApi extends BaseController {
|
|
122
|
+
// protected Middlewares: RepositoryMiddleware[];
|
|
123
|
+
// constructor(protected Orm: Orm) {
|
|
124
|
+
// super();
|
|
125
|
+
// }
|
|
126
|
+
// public async resolve(): Promise<void> {
|
|
127
|
+
// super.resolve();
|
|
128
|
+
// this.Middlewares = await DI.resolve(Array.ofType(RepositoryMiddleware));
|
|
129
|
+
// }
|
|
130
|
+
// @Get(':model/:id', {
|
|
131
|
+
// model: modelSchema,
|
|
132
|
+
// id: PrimaryKeySchema,
|
|
133
|
+
// include: genericStringSchema,
|
|
134
|
+
// _filters: genericStringSchema,
|
|
135
|
+
// })
|
|
136
|
+
// public async get(@Param() model: Model, @Param() id: string | number, @Query() include: Includes, @Query() _filters: Filters, @Req() req: express.Request) {
|
|
137
|
+
// await Promise.all(this.Middlewares.map((m) => m.onGetMiddlewareStart(id, req)));
|
|
138
|
+
// const query = model.SelectQuery.select('*').where(model.Descriptor.PrimaryKey, id);
|
|
139
|
+
// applyQueryIncludes(include, query);
|
|
140
|
+
// this.Middlewares.forEach((m) => m.onGetMiddlewareQuery(query, model.Type, req));
|
|
141
|
+
// const result = await query.firstOrFail();
|
|
142
|
+
// let jResult = modelToJsonApi(result);
|
|
143
|
+
// this.Middlewares.forEach((m) => {
|
|
144
|
+
// jResult = m.onGetMiddlewareResult(jResult, req);
|
|
145
|
+
// });
|
|
146
|
+
// return new Ok(jResult);
|
|
147
|
+
// }
|
|
148
|
+
// @Get(':model', {
|
|
149
|
+
// model: modelSchema,
|
|
150
|
+
// include: genericStringSchema,
|
|
151
|
+
// _filters: genericStringSchema,
|
|
152
|
+
// })
|
|
153
|
+
// public async getAll(@Param() model: Model, @Query() page: number, @Query() perPage: number, @Query() order: string, @Query() orderDirection: 'ASC' | 'DESC', @Query() include: Includes, @Query() _filters: Filters, @Req() req: express.Request) {
|
|
154
|
+
// await Promise.all(this.Middlewares.map((m) => m.onGetAllMiddlewareStart(req)));
|
|
155
|
+
// const query = model.SelectQuery.select('*')
|
|
156
|
+
// .take(perPage)
|
|
157
|
+
// .skip(page * perPage);
|
|
158
|
+
// if (order) {
|
|
159
|
+
// query.order(order, orderDirection ?? 'ASC');
|
|
160
|
+
// }
|
|
161
|
+
// applyQueryIncludes(include, query);
|
|
162
|
+
// this.Middlewares.forEach((m) => m.onGetAllMiddlewareQuery(query, model.Type, req));
|
|
163
|
+
// const result = await query;
|
|
164
|
+
// let jResult = modelToJsonApi(result);
|
|
165
|
+
// this.Middlewares.forEach((m) => {
|
|
166
|
+
// jResult = m.onGetAllMiddlewareResult(jResult, req);
|
|
167
|
+
// });
|
|
168
|
+
// return new Ok(jResult);
|
|
169
|
+
// }
|
|
170
|
+
// @Del(':model/:id', {
|
|
171
|
+
// model: modelSchema,
|
|
172
|
+
// id: PrimaryKeySchema,
|
|
173
|
+
// })
|
|
174
|
+
// public async del(@Param() model: Model, @Param() id: string | number, @Req() req: express.Request) {
|
|
175
|
+
// await Promise.all(this.Middlewares.map((m) => m.onDeleteMiddlewareStart(id, req)));
|
|
176
|
+
// const entity: ModelBase = await model.SelectQuery.where(model.Descriptor.PrimaryKey, id).firstOrFail();
|
|
177
|
+
// await entity.destroy();
|
|
178
|
+
// this.Middlewares.forEach((m) => m.onDeleteMiddlewareResult(req));
|
|
179
|
+
// return new Ok();
|
|
180
|
+
// }
|
|
181
|
+
// @Patch(':model/:id', {
|
|
182
|
+
// model: modelSchema,
|
|
183
|
+
// id: PrimaryKeySchema,
|
|
184
|
+
// })
|
|
185
|
+
// public async patch(@Param() model: Model, @Param() id: string | number, @Body() incoming: JsonApiIncomingObject, @Req() req: express.Request) {
|
|
186
|
+
// await Promise.all(this.Middlewares.map((m) => m.onUpdateMiddlewareStart(id, incoming, req)));
|
|
187
|
+
// const entity: ModelBase = await model.SelectQuery.where(model.Descriptor.PrimaryKey, id).firstOrFail();
|
|
188
|
+
// await this.updateOneToOneRelations(incoming, model, entity);
|
|
189
|
+
// if (incoming.data.attributes) {
|
|
190
|
+
// entity.hydrate(incoming.data.attributes);
|
|
191
|
+
// }
|
|
192
|
+
// await entity.update();
|
|
193
|
+
// await this.updateOneToMany(incoming, model, entity);
|
|
194
|
+
// let jResult = modelToJsonApi(entity);
|
|
195
|
+
// this.Middlewares.forEach((m) => {
|
|
196
|
+
// jResult = m.onUpdateMiddlewareResult(jResult, req);
|
|
197
|
+
// });
|
|
198
|
+
// return new Ok(jResult);
|
|
199
|
+
// }
|
|
200
|
+
// @Post(':model', {
|
|
201
|
+
// model: modelSchema,
|
|
202
|
+
// })
|
|
203
|
+
// public async insert(@Param() model: Model, @Body() incoming: JsonApiIncomingObject, @Req() req: express.Request) {
|
|
204
|
+
// await Promise.all(this.Middlewares.map((m) => m.onInsertMiddlewareStart(incoming, req)));
|
|
205
|
+
// const entity: ModelBase = new model.Type();
|
|
206
|
+
// entity.hydrate(incoming.data.attributes);
|
|
207
|
+
// await this.updateOneToOneRelations(incoming, model, entity);
|
|
208
|
+
// await entity.insert();
|
|
209
|
+
// await this.updateOneToMany(incoming, model, entity);
|
|
210
|
+
// let jResult = modelToJsonApi(entity);
|
|
211
|
+
// this.Middlewares.forEach((m) => {
|
|
212
|
+
// jResult = m.onInsertMiddlewareResult(jResult, req);
|
|
213
|
+
// });
|
|
214
|
+
// return new Ok(jResult);
|
|
215
|
+
// }
|
|
216
|
+
// protected async updateOneToOneRelations(incoming: JsonApiIncomingObject, model: Model, entity: ModelBase) {
|
|
217
|
+
// // fillout one to one relations if possible
|
|
218
|
+
// if (incoming.data.relationships) {
|
|
219
|
+
// for (const key in incoming.data.relationships) {
|
|
220
|
+
// const relation = model.Descriptor.Relations.get(key);
|
|
221
|
+
// if (relation.Type === RelationType.One) {
|
|
222
|
+
// (entity as any)[relation.ForeignKey] = incoming.data.relationships[key].data.id;
|
|
223
|
+
// }
|
|
224
|
+
// }
|
|
225
|
+
// }
|
|
226
|
+
// }
|
|
227
|
+
// protected async updateOneToMany(incoming: JsonApiIncomingObject, model: Model, entity: ModelBase) {
|
|
228
|
+
// if (incoming.data.relationships) {
|
|
229
|
+
// for (const key in incoming.data.relationships) {
|
|
230
|
+
// const relation = model.Descriptor.Relations.get(key);
|
|
231
|
+
// if (relation.Type === RelationType.Many) {
|
|
232
|
+
// const rQuery = createQuery(relation.TargetModel, UpdateQueryBuilder).query;
|
|
233
|
+
// await rQuery
|
|
234
|
+
// .update({
|
|
235
|
+
// [relation.ForeignKey]: entity.PrimaryKeyValue,
|
|
236
|
+
// })
|
|
237
|
+
// .whereIn(
|
|
238
|
+
// relation.PrimaryKey,
|
|
239
|
+
// incoming.data.relationships[key].data.map((x: any) => x.id),
|
|
240
|
+
// );
|
|
241
|
+
// }
|
|
242
|
+
// }
|
|
243
|
+
// }
|
|
244
|
+
// }
|
|
245
|
+
// }
|
|
246
246
|
//# sourceMappingURL=JsonApi.js.map
|
|
@@ -1,16 +1,16 @@
|
|
|
1
|
-
import { IModelStatic, Orm } from '@spinajs/orm';
|
|
2
|
-
import { Ok } from '@spinajs/http';
|
|
3
|
-
import { Log } from '@spinajs/log';
|
|
4
|
-
import { AccessControl, User as UserModel } from '@spinajs/rbac';
|
|
5
|
-
import { Permission } from 'accesscontrol';
|
|
6
|
-
import { Crud } from './../../interfaces.js';
|
|
7
|
-
export declare class CrudCreate extends Crud {
|
|
8
|
-
protected Log: Log;
|
|
9
|
-
protected Orm: Orm;
|
|
10
|
-
protected Ac: AccessControl;
|
|
11
|
-
protected checkAny(resource: string, user?: UserModel): Permission;
|
|
12
|
-
protected checkOwn(resource: string, user?: UserModel): Permission;
|
|
13
|
-
save(model: IModelStatic, data: unknown, user?: UserModel): Promise<Ok>;
|
|
14
|
-
insertRelation(model: IModelStatic, id: any, relation: string, data: unknown, user?: UserModel): Promise<Ok>;
|
|
15
|
-
}
|
|
1
|
+
import { IModelStatic, Orm } from '@spinajs/orm';
|
|
2
|
+
import { Ok } from '@spinajs/http';
|
|
3
|
+
import { Log } from '@spinajs/log';
|
|
4
|
+
import { AccessControl, User as UserModel } from '@spinajs/rbac';
|
|
5
|
+
import { Permission } from 'accesscontrol';
|
|
6
|
+
import { Crud } from './../../interfaces.js';
|
|
7
|
+
export declare class CrudCreate extends Crud {
|
|
8
|
+
protected Log: Log;
|
|
9
|
+
protected Orm: Orm;
|
|
10
|
+
protected Ac: AccessControl;
|
|
11
|
+
protected checkAny(resource: string, user?: UserModel): Permission;
|
|
12
|
+
protected checkOwn(resource: string, user?: UserModel): Permission;
|
|
13
|
+
save(model: IModelStatic, data: unknown, user?: UserModel): Promise<Ok>;
|
|
14
|
+
insertRelation(model: IModelStatic, id: any, relation: string, data: unknown, user?: UserModel): Promise<Ok>;
|
|
15
|
+
}
|
|
16
16
|
//# sourceMappingURL=Create.d.ts.map
|