@qelos/plugin-play 3.2.9 → 3.3.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/crud.d.ts +2 -0
- package/dist/crud.js +198 -0
- package/dist/crud.js.map +1 -0
- package/dist/crud.types.d.ts +42 -0
- package/dist/crud.types.js +2 -0
- package/dist/crud.types.js.map +1 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.js +1 -0
- package/dist/index.js.map +1 -1
- package/dist/manifest.d.ts +3 -0
- package/dist/manifest.js +1 -0
- package/dist/manifest.js.map +1 -1
- package/dist/micro-frontends.d.ts +3 -7
- package/dist/micro-frontends.js +1 -27
- package/dist/micro-frontends.js.map +1 -1
- package/dist/request.types.d.ts +8 -6
- package/package.json +1 -1
- package/src/crud.ts +229 -0
- package/src/crud.types.ts +45 -0
- package/src/index.ts +1 -0
- package/src/manifest.ts +4 -1
- package/src/micro-frontends.ts +4 -36
- package/src/request.types.ts +9 -1
package/dist/crud.d.ts
ADDED
package/dist/crud.js
ADDED
|
@@ -0,0 +1,198 @@
|
|
|
1
|
+
import { addProxyEndpoint } from './endpoints';
|
|
2
|
+
import { ResponseError } from './response-error';
|
|
3
|
+
import logger from './logger';
|
|
4
|
+
import manifest from './manifest';
|
|
5
|
+
import { addGroupedMicroFrontends } from './micro-frontends';
|
|
6
|
+
function getDisplayNames(name) {
|
|
7
|
+
const plural = name.toLowerCase() + (name.endsWith('e') ? 's' : 'es');
|
|
8
|
+
const capitalized = name.split(' ').map(word => word[0].toUpperCase() + word.slice(1).toLowerCase()).join(' ');
|
|
9
|
+
const capitalizedPlural = capitalized + (capitalized.endsWith('e') ? 's' : 'es');
|
|
10
|
+
return {
|
|
11
|
+
name,
|
|
12
|
+
plural,
|
|
13
|
+
capitalized,
|
|
14
|
+
capitalizedPlural
|
|
15
|
+
};
|
|
16
|
+
}
|
|
17
|
+
export function createCrud(options) {
|
|
18
|
+
const display = getDisplayNames(options.display.name);
|
|
19
|
+
const screens = {
|
|
20
|
+
list: {},
|
|
21
|
+
create: {},
|
|
22
|
+
edit: {},
|
|
23
|
+
...options.screens,
|
|
24
|
+
};
|
|
25
|
+
const crudOptions = {
|
|
26
|
+
name: display.plural.replaceAll(' ', '-'),
|
|
27
|
+
identifierKey: '_id',
|
|
28
|
+
verify: async () => null,
|
|
29
|
+
...options,
|
|
30
|
+
display: {
|
|
31
|
+
...display,
|
|
32
|
+
...options.display
|
|
33
|
+
},
|
|
34
|
+
screens: {
|
|
35
|
+
list: {
|
|
36
|
+
use: screens.list.use || 'rows-list',
|
|
37
|
+
structure: screens.list.structure,
|
|
38
|
+
},
|
|
39
|
+
create: {
|
|
40
|
+
use: screens.create.use || 'basic-form',
|
|
41
|
+
structure: screens.create.structure
|
|
42
|
+
},
|
|
43
|
+
edit: {
|
|
44
|
+
use: screens.edit.use || 'basic-form',
|
|
45
|
+
structure: screens.edit.structure,
|
|
46
|
+
},
|
|
47
|
+
},
|
|
48
|
+
nav: options.nav || {}
|
|
49
|
+
};
|
|
50
|
+
function getPublicData(item) {
|
|
51
|
+
const exposed = { [crudOptions.identifierKey]: item[crudOptions.identifierKey] };
|
|
52
|
+
crudOptions.publicKeys.forEach(key => exposed[key] = item[key]);
|
|
53
|
+
return exposed;
|
|
54
|
+
}
|
|
55
|
+
function handleError(err, reply) {
|
|
56
|
+
if (err instanceof ResponseError) {
|
|
57
|
+
logger.error(err);
|
|
58
|
+
reply.statusCode = err.status;
|
|
59
|
+
return err.responseMessage;
|
|
60
|
+
}
|
|
61
|
+
throw err;
|
|
62
|
+
}
|
|
63
|
+
const itemPath = crudOptions.name + '/:id';
|
|
64
|
+
// get one
|
|
65
|
+
addProxyEndpoint(itemPath, {
|
|
66
|
+
verifyToken: true,
|
|
67
|
+
method: 'GET',
|
|
68
|
+
handler: async (req, reply) => {
|
|
69
|
+
try {
|
|
70
|
+
await crudOptions.verify(req, reply);
|
|
71
|
+
const id = req.params.id || '';
|
|
72
|
+
const item = await crudOptions.readOne(id, req, reply);
|
|
73
|
+
if (!crudOptions.publicKeys) {
|
|
74
|
+
return item;
|
|
75
|
+
}
|
|
76
|
+
return getPublicData(item);
|
|
77
|
+
}
|
|
78
|
+
catch (err) {
|
|
79
|
+
return handleError(err, reply);
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
});
|
|
83
|
+
// update one
|
|
84
|
+
addProxyEndpoint(itemPath, {
|
|
85
|
+
verifyToken: true,
|
|
86
|
+
method: 'PUT',
|
|
87
|
+
handler: async (req, reply) => {
|
|
88
|
+
try {
|
|
89
|
+
await crudOptions.verify(req, reply);
|
|
90
|
+
const id = req.params.id || '';
|
|
91
|
+
const item = await crudOptions.updateOne(id, req.body, req, reply);
|
|
92
|
+
if (!crudOptions.publicKeys) {
|
|
93
|
+
return item;
|
|
94
|
+
}
|
|
95
|
+
return getPublicData(item);
|
|
96
|
+
}
|
|
97
|
+
catch (err) {
|
|
98
|
+
return handleError(err, reply);
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
});
|
|
102
|
+
// delete one
|
|
103
|
+
addProxyEndpoint(itemPath, {
|
|
104
|
+
verifyToken: true,
|
|
105
|
+
method: 'DELETE',
|
|
106
|
+
handler: async (req, reply) => {
|
|
107
|
+
try {
|
|
108
|
+
await crudOptions.verify(req, reply);
|
|
109
|
+
const id = req.params.id || '';
|
|
110
|
+
const item = await crudOptions.deleteOne(id, req, reply);
|
|
111
|
+
if (!crudOptions.publicKeys) {
|
|
112
|
+
return item;
|
|
113
|
+
}
|
|
114
|
+
return getPublicData(item);
|
|
115
|
+
}
|
|
116
|
+
catch (err) {
|
|
117
|
+
return handleError(err, reply);
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
});
|
|
121
|
+
// create one
|
|
122
|
+
addProxyEndpoint(crudOptions.name, {
|
|
123
|
+
verifyToken: true,
|
|
124
|
+
method: 'POST',
|
|
125
|
+
handler: async (req, reply) => {
|
|
126
|
+
try {
|
|
127
|
+
await crudOptions.verify(req, reply);
|
|
128
|
+
const item = await crudOptions.createOne(req.body, req, reply);
|
|
129
|
+
if (!crudOptions.publicKeys) {
|
|
130
|
+
return item;
|
|
131
|
+
}
|
|
132
|
+
return getPublicData(item);
|
|
133
|
+
}
|
|
134
|
+
catch (err) {
|
|
135
|
+
return handleError(err, reply);
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
});
|
|
139
|
+
// get many
|
|
140
|
+
addProxyEndpoint(crudOptions.name, {
|
|
141
|
+
verifyToken: true,
|
|
142
|
+
method: 'GET',
|
|
143
|
+
handler: async (req, reply) => {
|
|
144
|
+
try {
|
|
145
|
+
await crudOptions.verify(req, reply);
|
|
146
|
+
const list = await crudOptions.readMany((req.query || {}), req, reply);
|
|
147
|
+
if (!crudOptions.publicKeys) {
|
|
148
|
+
return list;
|
|
149
|
+
}
|
|
150
|
+
return list.map(getPublicData);
|
|
151
|
+
}
|
|
152
|
+
catch (err) {
|
|
153
|
+
return handleError(err, reply);
|
|
154
|
+
}
|
|
155
|
+
}
|
|
156
|
+
});
|
|
157
|
+
manifest.cruds.push({
|
|
158
|
+
name: crudOptions.name,
|
|
159
|
+
display: crudOptions.display
|
|
160
|
+
});
|
|
161
|
+
const singlePath = crudOptions.display.name.toLowerCase().replaceAll(' ', '-');
|
|
162
|
+
addGroupedMicroFrontends({ name: crudOptions.display.capitalizedPlural, key: crudOptions.name, ...crudOptions.nav }, [
|
|
163
|
+
{
|
|
164
|
+
name: 'List',
|
|
165
|
+
crud: crudOptions.name,
|
|
166
|
+
description: 'List of ' + crudOptions.display.capitalizedPlural,
|
|
167
|
+
use: crudOptions.screens.list.use,
|
|
168
|
+
route: {
|
|
169
|
+
name: 'List',
|
|
170
|
+
path: crudOptions.name,
|
|
171
|
+
navBarPosition: 'top'
|
|
172
|
+
}
|
|
173
|
+
},
|
|
174
|
+
{
|
|
175
|
+
name: 'Create',
|
|
176
|
+
crud: crudOptions.name,
|
|
177
|
+
description: 'Create a new ' + crudOptions.display.capitalized,
|
|
178
|
+
use: crudOptions.screens.create.use,
|
|
179
|
+
route: {
|
|
180
|
+
name: 'Create',
|
|
181
|
+
path: 'add-' + singlePath,
|
|
182
|
+
navBarPosition: 'top'
|
|
183
|
+
}
|
|
184
|
+
},
|
|
185
|
+
{
|
|
186
|
+
name: 'Edit',
|
|
187
|
+
crud: crudOptions.name,
|
|
188
|
+
description: 'Edit existing ' + crudOptions.display.capitalized,
|
|
189
|
+
use: crudOptions.screens.edit.use,
|
|
190
|
+
route: {
|
|
191
|
+
name: 'Edit',
|
|
192
|
+
path: `edit-${singlePath}/:id`,
|
|
193
|
+
navBarPosition: false
|
|
194
|
+
}
|
|
195
|
+
}
|
|
196
|
+
]);
|
|
197
|
+
}
|
|
198
|
+
//# sourceMappingURL=crud.js.map
|
package/dist/crud.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"crud.js","sourceRoot":"","sources":["../src/crud.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import { FastifyRequest } from 'fastify/types/request';
|
|
2
|
+
import { FastifyReply } from 'fastify/types/reply';
|
|
3
|
+
export type Crud = {
|
|
4
|
+
name: string;
|
|
5
|
+
display: {
|
|
6
|
+
name: string;
|
|
7
|
+
plural: string;
|
|
8
|
+
capitalized: string;
|
|
9
|
+
capitalizedPlural: string;
|
|
10
|
+
};
|
|
11
|
+
};
|
|
12
|
+
export interface Screen {
|
|
13
|
+
use?: string;
|
|
14
|
+
structure?: string;
|
|
15
|
+
}
|
|
16
|
+
export interface ICrudOptions<ResourcePublicData, ResourceInsertData> {
|
|
17
|
+
name?: string;
|
|
18
|
+
identifierKey?: string;
|
|
19
|
+
display: {
|
|
20
|
+
name: string;
|
|
21
|
+
plural?: string;
|
|
22
|
+
capitalized?: string;
|
|
23
|
+
capitalizedPlural?: string;
|
|
24
|
+
};
|
|
25
|
+
nav?: {
|
|
26
|
+
iconName?: string;
|
|
27
|
+
iconSvg?: string;
|
|
28
|
+
priority?: number;
|
|
29
|
+
};
|
|
30
|
+
screens?: {
|
|
31
|
+
list: Screen;
|
|
32
|
+
create: Screen;
|
|
33
|
+
edit: Screen;
|
|
34
|
+
};
|
|
35
|
+
publicKeys?: string[];
|
|
36
|
+
verify?: (request: FastifyRequest, reply: FastifyReply) => Promise<any>;
|
|
37
|
+
createOne: (body: Partial<ResourceInsertData>, request: FastifyRequest, reply: FastifyReply) => (any | Promise<ResourcePublicData>);
|
|
38
|
+
readOne: (id: string, request: FastifyRequest, reply: FastifyReply) => (Promise<ResourcePublicData>);
|
|
39
|
+
readMany: (query: Record<string, string | string[]>, request: FastifyRequest, reply: FastifyReply) => (Promise<ResourcePublicData[]>);
|
|
40
|
+
updateOne: (id: string, body: Partial<ResourceInsertData>, request: FastifyRequest, reply: FastifyReply) => (Promise<ResourcePublicData>);
|
|
41
|
+
deleteOne: (id: string, request: FastifyRequest, reply: FastifyReply) => (Promise<ResourcePublicData>);
|
|
42
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"crud.types.js","sourceRoot":"","sources":["../src/crud.types.ts"],"names":[],"mappings":""}
|
package/dist/index.d.ts
CHANGED
|
@@ -9,4 +9,5 @@ export { addEndpoint, addProxyEndpoint, addInternalEndpoint } from './endpoints'
|
|
|
9
9
|
export { getSdkForTenant, getSdk, getSdkForUrl } from './sdk';
|
|
10
10
|
export { addGroupedMicroFrontends, addMicroFrontend, MicroFrontend } from './micro-frontends';
|
|
11
11
|
export { addInjectable, Injectable } from './injectables';
|
|
12
|
+
export { createCrud } from './crud';
|
|
12
13
|
export { logger };
|
package/dist/index.js
CHANGED
|
@@ -9,5 +9,6 @@ export { addEndpoint, addProxyEndpoint, addInternalEndpoint } from './endpoints'
|
|
|
9
9
|
export { getSdkForTenant, getSdk, getSdkForUrl } from './sdk';
|
|
10
10
|
export { addGroupedMicroFrontends, addMicroFrontend } from './micro-frontends';
|
|
11
11
|
export { addInjectable } from './injectables';
|
|
12
|
+
export { createCrud } from './crud';
|
|
12
13
|
export { logger };
|
|
13
14
|
//# sourceMappingURL=index.js.map
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,iBAAiB,CAAC;AAEzB,OAAO,MAAM,MAAM,UAAU,CAAC;AAE9B,OAAO,EAAC,aAAa,EAAC,MAAM,kBAAkB,CAAC;AAE/C,OAAO,EAAC,KAAK,EAAE,SAAS,EAAE,cAAc,EAAC,MAAM,OAAO,CAAC;AACvD,OAAO,EACL,EAAE,EAAE,cAAc,EAEnB,MAAM,aAAa,CAAC;AACrB,OAAO,EAAC,YAAY,EAAC,MAAM,iBAAiB,CAAC;AAC7C,OAAO,EAAC,cAAc,EAAE,UAAU,EAAE,WAAW,EAAE,WAAW,EAAE,UAAU,EAAC,MAAM,YAAY,CAAC;AAC5F,OAAO,EAAC,WAAW,EAAE,gBAAgB,EAAE,mBAAmB,EAAC,MAAM,aAAa,CAAA;AAC9E,OAAO,EAAC,eAAe,EAAE,MAAM,EAAE,YAAY,EAAC,MAAM,OAAO,CAAC;AAC5D,OAAO,EAAC,wBAAwB,EAAE,gBAAgB,EAAgB,MAAM,mBAAmB,CAAC;AAC5F,OAAO,EAAC,aAAa,EAAa,MAAM,eAAe,CAAC;AACxD,OAAO,EACL,MAAM,EACP,CAAA"}
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,iBAAiB,CAAC;AAEzB,OAAO,MAAM,MAAM,UAAU,CAAC;AAE9B,OAAO,EAAC,aAAa,EAAC,MAAM,kBAAkB,CAAC;AAE/C,OAAO,EAAC,KAAK,EAAE,SAAS,EAAE,cAAc,EAAC,MAAM,OAAO,CAAC;AACvD,OAAO,EACL,EAAE,EAAE,cAAc,EAEnB,MAAM,aAAa,CAAC;AACrB,OAAO,EAAC,YAAY,EAAC,MAAM,iBAAiB,CAAC;AAC7C,OAAO,EAAC,cAAc,EAAE,UAAU,EAAE,WAAW,EAAE,WAAW,EAAE,UAAU,EAAC,MAAM,YAAY,CAAC;AAC5F,OAAO,EAAC,WAAW,EAAE,gBAAgB,EAAE,mBAAmB,EAAC,MAAM,aAAa,CAAA;AAC9E,OAAO,EAAC,eAAe,EAAE,MAAM,EAAE,YAAY,EAAC,MAAM,OAAO,CAAC;AAC5D,OAAO,EAAC,wBAAwB,EAAE,gBAAgB,EAAgB,MAAM,mBAAmB,CAAC;AAC5F,OAAO,EAAC,aAAa,EAAa,MAAM,eAAe,CAAC;AACxD,OAAO,EAAC,UAAU,EAAC,MAAM,QAAQ,CAAC;AAClC,OAAO,EACL,MAAM,EACP,CAAA"}
|
package/dist/manifest.d.ts
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { Crud } from './crud.types';
|
|
1
2
|
export declare const manifest: {
|
|
2
3
|
name: any;
|
|
3
4
|
description: any;
|
|
@@ -14,6 +15,7 @@ export declare const manifest: {
|
|
|
14
15
|
navBarGroups: any[];
|
|
15
16
|
microFrontends: any[];
|
|
16
17
|
injectables: any[];
|
|
18
|
+
cruds: Crud[];
|
|
17
19
|
authAcquire: {
|
|
18
20
|
refreshTokenUrl: string;
|
|
19
21
|
refreshTokenKey: string;
|
|
@@ -30,5 +32,6 @@ export type NavBarGroup = {
|
|
|
30
32
|
export type ManifestOptions = Partial<typeof manifest> & {
|
|
31
33
|
appUrl?: string;
|
|
32
34
|
navBarGroups?: NavBarGroup[];
|
|
35
|
+
cruds?: Crud[];
|
|
33
36
|
};
|
|
34
37
|
export default manifest;
|
package/dist/manifest.js
CHANGED
package/dist/manifest.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"manifest.js","sourceRoot":"","sources":["../src/manifest.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"manifest.js","sourceRoot":"","sources":["../src/manifest.ts"],"names":[],"mappings":"AAEA,MAAM,GAAG,GAAG,OAAO,CAAC,OAAO,CAAC,GAAG,EAAE,GAAG,eAAe,CAAC,CAAC;AAErD,MAAM,CAAC,MAAM,QAAQ,GAAG;IACtB,IAAI,EAAE,GAAG,CAAC,IAAI;IACd,WAAW,EAAE,GAAG,CAAC,WAAW;IAC5B,MAAM,EAAE,OAAO,CAAC,GAAG,CAAC,OAAO,IAAI,EAAE;IACjC,OAAO,EAAE,GAAG,CAAC,IAAI;IACjB,WAAW,EAAE,oBAAoB;IACjC,WAAW,EAAE,eAAe;IAC5B,WAAW,EAAE,eAAe;IAC5B,YAAY,EAAE,gBAAgB;IAC9B,cAAc,EAAE,mBAAmB;IACnC,SAAS,EAAE,WAAW;IACtB,QAAQ,EAAE,EAAE;IACZ,gBAAgB,EAAE,EAAE;IACpB,YAAY,EAAE,EAAE;IAChB,cAAc,EAAE,EAAE;IAClB,WAAW,EAAE,EAAE;IACf,KAAK,EAAE,EAAY;IACnB,WAAW,EAAE;QACX,eAAe,EAAE,oBAAoB;QACrC,eAAe,EAAE,eAAe;QAChC,cAAc,EAAE,cAAc;KAC/B;CACF,CAAC;AAQF,eAAe,QAAQ,CAAC"}
|
|
@@ -1,14 +1,10 @@
|
|
|
1
1
|
import { NavBarGroup } from './manifest';
|
|
2
|
-
import { QelosRouteParams } from './endpoints';
|
|
3
2
|
export interface IframeMicroFrontend extends GlobalMicroFrontend {
|
|
4
3
|
url: string;
|
|
5
4
|
}
|
|
6
|
-
|
|
5
|
+
interface PreDesignedMicroFrontend extends GlobalMicroFrontend {
|
|
7
6
|
use: string;
|
|
8
|
-
|
|
9
|
-
}
|
|
10
|
-
interface PreDesignedMicroFrontend extends Omit<PreDesignedMicroFrontendOptions, 'handler' | 'verifyToken'> {
|
|
11
|
-
fetchUrl: string;
|
|
7
|
+
crud: string;
|
|
12
8
|
}
|
|
13
9
|
export interface GlobalMicroFrontend {
|
|
14
10
|
name: string;
|
|
@@ -32,7 +28,7 @@ export interface GlobalMicroFrontend {
|
|
|
32
28
|
size: 'sm' | 'md' | 'lg' | 'full';
|
|
33
29
|
};
|
|
34
30
|
}
|
|
35
|
-
export type MicroFrontendOptions = IframeMicroFrontend |
|
|
31
|
+
export type MicroFrontendOptions = IframeMicroFrontend | PreDesignedMicroFrontend;
|
|
36
32
|
export type MicroFrontend = IframeMicroFrontend | PreDesignedMicroFrontend;
|
|
37
33
|
export declare function addMicroFrontend(mfe: MicroFrontendOptions): void;
|
|
38
34
|
export declare function addGroupedMicroFrontends(group: NavBarGroup, mfeArray: MicroFrontendOptions[]): void;
|
package/dist/micro-frontends.js
CHANGED
|
@@ -1,32 +1,6 @@
|
|
|
1
1
|
import manifest from './manifest';
|
|
2
|
-
import { addProxyEndpoint } from './endpoints';
|
|
3
2
|
export function addMicroFrontend(mfe) {
|
|
4
|
-
|
|
5
|
-
let manifestMfe;
|
|
6
|
-
if ('use' in mfe) {
|
|
7
|
-
const verifyToken = mfe.verifyToken || true;
|
|
8
|
-
delete mfe.verifyToken;
|
|
9
|
-
if ('handler' in mfe) {
|
|
10
|
-
const fetchUrl = mfe.fetchUrl || btoa(mfe.name);
|
|
11
|
-
const handler = mfe.handler;
|
|
12
|
-
delete mfe.handler;
|
|
13
|
-
addProxyEndpoint(fetchUrl, {
|
|
14
|
-
handler,
|
|
15
|
-
verifyToken,
|
|
16
|
-
});
|
|
17
|
-
manifestMfe = {
|
|
18
|
-
...mfe,
|
|
19
|
-
fetchUrl
|
|
20
|
-
};
|
|
21
|
-
}
|
|
22
|
-
else if ('fetchUrl' in mfe) {
|
|
23
|
-
manifestMfe = mfe;
|
|
24
|
-
}
|
|
25
|
-
}
|
|
26
|
-
else {
|
|
27
|
-
manifestMfe = mfe;
|
|
28
|
-
}
|
|
29
|
-
manifest.microFrontends.push(manifestMfe);
|
|
3
|
+
manifest.microFrontends.push({ ...mfe });
|
|
30
4
|
}
|
|
31
5
|
export function addGroupedMicroFrontends(group, mfeArray) {
|
|
32
6
|
manifest.navBarGroups.push(group);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"micro-frontends.js","sourceRoot":"","sources":["../src/micro-frontends.ts"],"names":[],"mappings":"AAAA,OAAO,QAAuB,MAAM,YAAY,CAAC;
|
|
1
|
+
{"version":3,"file":"micro-frontends.js","sourceRoot":"","sources":["../src/micro-frontends.ts"],"names":[],"mappings":"AAAA,OAAO,QAAuB,MAAM,YAAY,CAAC;AAqCjD,MAAM,UAAU,gBAAgB,CAAC,GAAyB;IACxD,QAAQ,CAAC,cAAc,CAAC,IAAI,CAAC,EAAC,GAAG,GAAG,EAAC,CAAC,CAAC;AACzC,CAAC;AAED,MAAM,UAAU,wBAAwB,CAAC,KAAkB,EAAE,QAAgC;IAC3F,QAAQ,CAAC,YAAY,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;IAClC,QAAQ,CAAC,OAAO,CAAC,GAAG,CAAC,EAAE;QACrB,gBAAgB,CAAC,EAAC,GAAG,GAAG,EAAE,KAAK,EAAE,EAAC,GAAG,GAAG,CAAC,KAAK,EAAE,KAAK,EAAE,KAAK,CAAC,GAAG,EAAC,EAAC,CAAC,CAAA;IACrE,CAAC,CAAC,CAAA;AACJ,CAAC"}
|
package/dist/request.types.d.ts
CHANGED
|
@@ -1,12 +1,14 @@
|
|
|
1
1
|
import { StandardPayload } from './handlers';
|
|
2
|
+
export type RequestUser = {
|
|
3
|
+
_id: string;
|
|
4
|
+
email: string;
|
|
5
|
+
firstName: string;
|
|
6
|
+
lastName: string;
|
|
7
|
+
roles: string[];
|
|
8
|
+
};
|
|
2
9
|
declare module 'fastify' {
|
|
3
10
|
interface FastifyRequest {
|
|
4
11
|
tenantPayload: StandardPayload & any;
|
|
5
|
-
user?:
|
|
6
|
-
_id: any;
|
|
7
|
-
email: any;
|
|
8
|
-
firstName: any;
|
|
9
|
-
lastName: any;
|
|
10
|
-
};
|
|
12
|
+
user?: RequestUser;
|
|
11
13
|
}
|
|
12
14
|
}
|
package/package.json
CHANGED
package/src/crud.ts
ADDED
|
@@ -0,0 +1,229 @@
|
|
|
1
|
+
import {FastifyReply} from 'fastify/types/reply';
|
|
2
|
+
import {addProxyEndpoint} from './endpoints';
|
|
3
|
+
import {ResponseError} from './response-error';
|
|
4
|
+
import logger from './logger';
|
|
5
|
+
import manifest from './manifest';
|
|
6
|
+
import {Crud, ICrudOptions} from './crud.types';
|
|
7
|
+
import {addGroupedMicroFrontends} from './micro-frontends';
|
|
8
|
+
|
|
9
|
+
function getDisplayNames(name: string) {
|
|
10
|
+
const plural = name.toLowerCase() + (name.endsWith('e') ? 's' : 'es');
|
|
11
|
+
const capitalized = name.split(' ').map(word => word[0].toUpperCase() + word.slice(1).toLowerCase()).join(' ');
|
|
12
|
+
const capitalizedPlural = capitalized + (capitalized.endsWith('e') ? 's' : 'es');
|
|
13
|
+
|
|
14
|
+
return {
|
|
15
|
+
name,
|
|
16
|
+
plural,
|
|
17
|
+
capitalized,
|
|
18
|
+
capitalizedPlural
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
export function createCrud<ResourcePublicData = any, ResourceInsertData = any>(
|
|
23
|
+
options: ICrudOptions<ResourcePublicData, ResourceInsertData>) {
|
|
24
|
+
|
|
25
|
+
const display = getDisplayNames(options.display.name);
|
|
26
|
+
|
|
27
|
+
const screens = {
|
|
28
|
+
list: {},
|
|
29
|
+
create: {},
|
|
30
|
+
edit: {},
|
|
31
|
+
...options.screens,
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
const crudOptions: ICrudOptions<ResourcePublicData, ResourceInsertData> & Crud = {
|
|
35
|
+
name: display.plural.replaceAll(' ', '-'),
|
|
36
|
+
identifierKey: '_id',
|
|
37
|
+
verify: async () => null,
|
|
38
|
+
...options,
|
|
39
|
+
display: {
|
|
40
|
+
...display,
|
|
41
|
+
...options.display
|
|
42
|
+
},
|
|
43
|
+
screens: {
|
|
44
|
+
list: {
|
|
45
|
+
use: screens.list.use || 'rows-list',
|
|
46
|
+
structure: screens.list.structure,
|
|
47
|
+
},
|
|
48
|
+
create: {
|
|
49
|
+
use: screens.create.use || 'basic-form',
|
|
50
|
+
structure: screens.create.structure
|
|
51
|
+
},
|
|
52
|
+
edit: {
|
|
53
|
+
use: screens.edit.use || 'basic-form',
|
|
54
|
+
structure: screens.edit.structure,
|
|
55
|
+
},
|
|
56
|
+
},
|
|
57
|
+
nav: options.nav || {}
|
|
58
|
+
};
|
|
59
|
+
|
|
60
|
+
function getPublicData(item) {
|
|
61
|
+
const exposed = {[crudOptions.identifierKey]: item[crudOptions.identifierKey]}
|
|
62
|
+
crudOptions.publicKeys.forEach(key => exposed[key] = item[key]);
|
|
63
|
+
return exposed;
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
function handleError(err: Error, reply: FastifyReply) {
|
|
67
|
+
if (err instanceof ResponseError) {
|
|
68
|
+
logger.error(err);
|
|
69
|
+
reply.statusCode = err.status;
|
|
70
|
+
return err.responseMessage;
|
|
71
|
+
}
|
|
72
|
+
throw err;
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
const itemPath = crudOptions.name + '/:id';
|
|
76
|
+
|
|
77
|
+
// get one
|
|
78
|
+
addProxyEndpoint(itemPath, {
|
|
79
|
+
verifyToken: true,
|
|
80
|
+
method: 'GET',
|
|
81
|
+
handler: async (req, reply) => {
|
|
82
|
+
try {
|
|
83
|
+
await crudOptions.verify(req, reply);
|
|
84
|
+
const id: string = (req.params as any).id || '';
|
|
85
|
+
const item = await crudOptions.readOne(id, req, reply);
|
|
86
|
+
|
|
87
|
+
if (!crudOptions.publicKeys) {
|
|
88
|
+
return item;
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
return getPublicData(item);
|
|
92
|
+
|
|
93
|
+
} catch (err) {
|
|
94
|
+
return handleError(err, reply);
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
})
|
|
98
|
+
|
|
99
|
+
// update one
|
|
100
|
+
addProxyEndpoint(itemPath, {
|
|
101
|
+
verifyToken: true,
|
|
102
|
+
method: 'PUT',
|
|
103
|
+
handler: async (req, reply) => {
|
|
104
|
+
try {
|
|
105
|
+
await crudOptions.verify(req, reply);
|
|
106
|
+
const id: string = (req.params as any).id || '';
|
|
107
|
+
const item = await crudOptions.updateOne(id, req.body as ResourceInsertData, req, reply);
|
|
108
|
+
|
|
109
|
+
if (!crudOptions.publicKeys) {
|
|
110
|
+
return item;
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
return getPublicData(item);
|
|
114
|
+
|
|
115
|
+
} catch (err) {
|
|
116
|
+
return handleError(err, reply);
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
})
|
|
120
|
+
|
|
121
|
+
// delete one
|
|
122
|
+
addProxyEndpoint(itemPath, {
|
|
123
|
+
verifyToken: true,
|
|
124
|
+
method: 'DELETE',
|
|
125
|
+
handler: async (req, reply) => {
|
|
126
|
+
try {
|
|
127
|
+
await crudOptions.verify(req, reply);
|
|
128
|
+
const id: string = (req.params as any).id || '';
|
|
129
|
+
const item = await crudOptions.deleteOne(id, req, reply);
|
|
130
|
+
|
|
131
|
+
if (!crudOptions.publicKeys) {
|
|
132
|
+
return item;
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
return getPublicData(item);
|
|
136
|
+
|
|
137
|
+
} catch (err) {
|
|
138
|
+
return handleError(err, reply);
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
})
|
|
142
|
+
|
|
143
|
+
// create one
|
|
144
|
+
addProxyEndpoint(crudOptions.name, {
|
|
145
|
+
verifyToken: true,
|
|
146
|
+
method: 'POST',
|
|
147
|
+
handler: async (req, reply) => {
|
|
148
|
+
try {
|
|
149
|
+
await crudOptions.verify(req, reply);
|
|
150
|
+
const item = await crudOptions.createOne(req.body as ResourceInsertData, req, reply);
|
|
151
|
+
|
|
152
|
+
if (!crudOptions.publicKeys) {
|
|
153
|
+
return item;
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
return getPublicData(item);
|
|
157
|
+
|
|
158
|
+
} catch (err) {
|
|
159
|
+
return handleError(err, reply);
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
})
|
|
163
|
+
|
|
164
|
+
// get many
|
|
165
|
+
addProxyEndpoint(crudOptions.name, {
|
|
166
|
+
verifyToken: true,
|
|
167
|
+
method: 'GET',
|
|
168
|
+
handler: async (req, reply) => {
|
|
169
|
+
try {
|
|
170
|
+
await crudOptions.verify(req, reply);
|
|
171
|
+
const list = await crudOptions.readMany((req.query || {}) as Record<string, string | string[]>, req, reply);
|
|
172
|
+
|
|
173
|
+
if (!crudOptions.publicKeys) {
|
|
174
|
+
return list;
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
return list.map(getPublicData);
|
|
178
|
+
} catch (err) {
|
|
179
|
+
return handleError(err, reply);
|
|
180
|
+
}
|
|
181
|
+
}
|
|
182
|
+
})
|
|
183
|
+
|
|
184
|
+
manifest.cruds.push({
|
|
185
|
+
name: crudOptions.name,
|
|
186
|
+
display: crudOptions.display
|
|
187
|
+
});
|
|
188
|
+
|
|
189
|
+
const singlePath = crudOptions.display.name.toLowerCase().replaceAll(' ', '-');
|
|
190
|
+
|
|
191
|
+
addGroupedMicroFrontends(
|
|
192
|
+
{name: crudOptions.display.capitalizedPlural, key: crudOptions.name, ...crudOptions.nav},
|
|
193
|
+
[
|
|
194
|
+
{
|
|
195
|
+
name: 'List',
|
|
196
|
+
crud: crudOptions.name,
|
|
197
|
+
description: 'List of ' + crudOptions.display.capitalizedPlural,
|
|
198
|
+
use: crudOptions.screens.list.use,
|
|
199
|
+
route: {
|
|
200
|
+
name: 'List',
|
|
201
|
+
path: crudOptions.name,
|
|
202
|
+
navBarPosition: 'top'
|
|
203
|
+
}
|
|
204
|
+
},
|
|
205
|
+
{
|
|
206
|
+
name: 'Create',
|
|
207
|
+
crud: crudOptions.name,
|
|
208
|
+
description: 'Create a new ' + crudOptions.display.capitalized,
|
|
209
|
+
use: crudOptions.screens.create.use,
|
|
210
|
+
route: {
|
|
211
|
+
name: 'Create',
|
|
212
|
+
path: 'add-' + singlePath,
|
|
213
|
+
navBarPosition: 'top'
|
|
214
|
+
}
|
|
215
|
+
},
|
|
216
|
+
{
|
|
217
|
+
name: 'Edit',
|
|
218
|
+
crud: crudOptions.name,
|
|
219
|
+
description: 'Edit existing ' + crudOptions.display.capitalized,
|
|
220
|
+
use: crudOptions.screens.edit.use,
|
|
221
|
+
route: {
|
|
222
|
+
name: 'Edit',
|
|
223
|
+
path: `edit-${singlePath}/:id`,
|
|
224
|
+
navBarPosition: false
|
|
225
|
+
}
|
|
226
|
+
}
|
|
227
|
+
]
|
|
228
|
+
)
|
|
229
|
+
}
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import {FastifyRequest} from 'fastify/types/request';
|
|
2
|
+
import {FastifyReply} from 'fastify/types/reply';
|
|
3
|
+
|
|
4
|
+
export type Crud = {
|
|
5
|
+
name: string,
|
|
6
|
+
display: {
|
|
7
|
+
name: string;
|
|
8
|
+
plural: string;
|
|
9
|
+
capitalized: string;
|
|
10
|
+
capitalizedPlural: string;
|
|
11
|
+
}
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
export interface Screen {
|
|
15
|
+
use?: string;
|
|
16
|
+
structure?: string;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
export interface ICrudOptions<ResourcePublicData, ResourceInsertData> {
|
|
20
|
+
name?: string;
|
|
21
|
+
identifierKey?: string;
|
|
22
|
+
display: {
|
|
23
|
+
name: string;
|
|
24
|
+
plural?: string;
|
|
25
|
+
capitalized?: string;
|
|
26
|
+
capitalizedPlural?: string;
|
|
27
|
+
},
|
|
28
|
+
nav?: {
|
|
29
|
+
iconName?: string;
|
|
30
|
+
iconSvg?: string;
|
|
31
|
+
priority?: number;
|
|
32
|
+
},
|
|
33
|
+
screens?: {
|
|
34
|
+
list: Screen;
|
|
35
|
+
create: Screen;
|
|
36
|
+
edit: Screen;
|
|
37
|
+
},
|
|
38
|
+
publicKeys?: string[];
|
|
39
|
+
verify?: (request: FastifyRequest, reply: FastifyReply) => Promise<any>;
|
|
40
|
+
createOne: (body: Partial<ResourceInsertData>, request: FastifyRequest, reply: FastifyReply) => (any | Promise<ResourcePublicData>),
|
|
41
|
+
readOne: (id: string, request: FastifyRequest, reply: FastifyReply) => (Promise<ResourcePublicData>);
|
|
42
|
+
readMany: (query: Record<string, string | string[]>, request: FastifyRequest, reply: FastifyReply) => (Promise<ResourcePublicData[]>);
|
|
43
|
+
updateOne: (id: string, body: Partial<ResourceInsertData>, request: FastifyRequest, reply: FastifyReply) => (Promise<ResourcePublicData>);
|
|
44
|
+
deleteOne: (id: string, request: FastifyRequest, reply: FastifyReply) => (Promise<ResourcePublicData>);
|
|
45
|
+
}
|
package/src/index.ts
CHANGED
|
@@ -15,6 +15,7 @@ export {addEndpoint, addProxyEndpoint, addInternalEndpoint} from './endpoints'
|
|
|
15
15
|
export {getSdkForTenant, getSdk, getSdkForUrl} from './sdk';
|
|
16
16
|
export {addGroupedMicroFrontends, addMicroFrontend, MicroFrontend} from './micro-frontends';
|
|
17
17
|
export {addInjectable, Injectable} from './injectables';
|
|
18
|
+
export {createCrud} from './crud';
|
|
18
19
|
export {
|
|
19
20
|
logger
|
|
20
21
|
}
|
package/src/manifest.ts
CHANGED
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
import {Crud} from './crud.types';
|
|
2
|
+
|
|
1
3
|
const pkg = require(process.cwd() + '/package.json');
|
|
2
4
|
|
|
3
5
|
export const manifest = {
|
|
@@ -16,6 +18,7 @@ export const manifest = {
|
|
|
16
18
|
navBarGroups: [],
|
|
17
19
|
microFrontends: [],
|
|
18
20
|
injectables: [],
|
|
21
|
+
cruds: [] as Crud[],
|
|
19
22
|
authAcquire: {
|
|
20
23
|
refreshTokenUrl: '/api/token/refresh',
|
|
21
24
|
refreshTokenKey: 'refresh_token',
|
|
@@ -27,6 +30,6 @@ export type NavBarGroup = { key: string, name: string, iconName?: string, iconSv
|
|
|
27
30
|
|
|
28
31
|
export type ManifestOptions =
|
|
29
32
|
Partial<typeof manifest>
|
|
30
|
-
& { appUrl?: string, navBarGroups?: NavBarGroup[] };
|
|
33
|
+
& { appUrl?: string, navBarGroups?: NavBarGroup[], cruds?: Crud[] };
|
|
31
34
|
|
|
32
35
|
export default manifest;
|
package/src/micro-frontends.ts
CHANGED
|
@@ -1,20 +1,12 @@
|
|
|
1
1
|
import manifest, {NavBarGroup} from './manifest';
|
|
2
|
-
import {addProxyEndpoint, QelosRouteParams} from './endpoints';
|
|
3
2
|
|
|
4
3
|
export interface IframeMicroFrontend extends GlobalMicroFrontend {
|
|
5
4
|
url: string;
|
|
6
5
|
}
|
|
7
6
|
|
|
8
|
-
|
|
9
|
-
extends Pick<QelosRouteParams, 'verifyToken'>,
|
|
10
|
-
Partial<Pick<QelosRouteParams, 'handler'>>,
|
|
11
|
-
GlobalMicroFrontend {
|
|
7
|
+
interface PreDesignedMicroFrontend extends GlobalMicroFrontend {
|
|
12
8
|
use: string;
|
|
13
|
-
|
|
14
|
-
}
|
|
15
|
-
|
|
16
|
-
interface PreDesignedMicroFrontend extends Omit<PreDesignedMicroFrontendOptions, 'handler' | 'verifyToken'> {
|
|
17
|
-
fetchUrl: string;
|
|
9
|
+
crud: string;
|
|
18
10
|
}
|
|
19
11
|
|
|
20
12
|
export interface GlobalMicroFrontend {
|
|
@@ -40,35 +32,11 @@ export interface GlobalMicroFrontend {
|
|
|
40
32
|
}
|
|
41
33
|
}
|
|
42
34
|
|
|
43
|
-
export type MicroFrontendOptions = IframeMicroFrontend |
|
|
35
|
+
export type MicroFrontendOptions = IframeMicroFrontend | PreDesignedMicroFrontend
|
|
44
36
|
export type MicroFrontend = IframeMicroFrontend | PreDesignedMicroFrontend
|
|
45
37
|
|
|
46
38
|
export function addMicroFrontend(mfe: MicroFrontendOptions) {
|
|
47
|
-
|
|
48
|
-
let manifestMfe: MicroFrontend;
|
|
49
|
-
if ('use' in mfe) {
|
|
50
|
-
const verifyToken = mfe.verifyToken || true;
|
|
51
|
-
delete mfe.verifyToken;
|
|
52
|
-
|
|
53
|
-
if ('handler' in mfe) {
|
|
54
|
-
const fetchUrl = mfe.fetchUrl || btoa(mfe.name);
|
|
55
|
-
const handler = mfe.handler;
|
|
56
|
-
delete mfe.handler;
|
|
57
|
-
addProxyEndpoint(fetchUrl, {
|
|
58
|
-
handler,
|
|
59
|
-
verifyToken,
|
|
60
|
-
});
|
|
61
|
-
manifestMfe = {
|
|
62
|
-
...mfe as PreDesignedMicroFrontend,
|
|
63
|
-
fetchUrl
|
|
64
|
-
}
|
|
65
|
-
} else if ('fetchUrl' in mfe) {
|
|
66
|
-
manifestMfe = mfe as PreDesignedMicroFrontend;
|
|
67
|
-
}
|
|
68
|
-
} else {
|
|
69
|
-
manifestMfe = mfe;
|
|
70
|
-
}
|
|
71
|
-
manifest.microFrontends.push(manifestMfe);
|
|
39
|
+
manifest.microFrontends.push({...mfe});
|
|
72
40
|
}
|
|
73
41
|
|
|
74
42
|
export function addGroupedMicroFrontends(group: NavBarGroup, mfeArray: MicroFrontendOptions[]) {
|
package/src/request.types.ts
CHANGED
|
@@ -1,8 +1,16 @@
|
|
|
1
1
|
import {StandardPayload} from './handlers';
|
|
2
2
|
|
|
3
|
+
export type RequestUser = {
|
|
4
|
+
_id: string,
|
|
5
|
+
email: string,
|
|
6
|
+
firstName: string,
|
|
7
|
+
lastName: string,
|
|
8
|
+
roles: string[]
|
|
9
|
+
};
|
|
10
|
+
|
|
3
11
|
declare module 'fastify' {
|
|
4
12
|
interface FastifyRequest {
|
|
5
13
|
tenantPayload: StandardPayload & any;
|
|
6
|
-
user?:
|
|
14
|
+
user?: RequestUser
|
|
7
15
|
}
|
|
8
16
|
}
|