@owlmeans/server-api 0.1.0

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.
Files changed (66) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +613 -0
  3. package/build/.gitkeep +0 -0
  4. package/build/consts.d.ts +5 -0
  5. package/build/consts.d.ts.map +1 -0
  6. package/build/consts.js +5 -0
  7. package/build/consts.js.map +1 -0
  8. package/build/errors.d.ts +14 -0
  9. package/build/errors.d.ts.map +1 -0
  10. package/build/errors.js +27 -0
  11. package/build/errors.js.map +1 -0
  12. package/build/helper.d.ts +13 -0
  13. package/build/helper.d.ts.map +1 -0
  14. package/build/helper.js +53 -0
  15. package/build/helper.js.map +1 -0
  16. package/build/index.d.ts +6 -0
  17. package/build/index.d.ts.map +1 -0
  18. package/build/index.js +5 -0
  19. package/build/index.js.map +1 -0
  20. package/build/server.d.ts +7 -0
  21. package/build/server.d.ts.map +1 -0
  22. package/build/server.js +146 -0
  23. package/build/server.js.map +1 -0
  24. package/build/types.d.ts +21 -0
  25. package/build/types.d.ts.map +1 -0
  26. package/build/types.js +2 -0
  27. package/build/types.js.map +1 -0
  28. package/build/utils/context.d.ts +4 -0
  29. package/build/utils/context.d.ts.map +1 -0
  30. package/build/utils/context.js +5 -0
  31. package/build/utils/context.js.map +1 -0
  32. package/build/utils/error.d.ts +3 -0
  33. package/build/utils/error.d.ts.map +1 -0
  34. package/build/utils/error.js +16 -0
  35. package/build/utils/error.js.map +1 -0
  36. package/build/utils/guards.d.ts +9 -0
  37. package/build/utils/guards.d.ts.map +1 -0
  38. package/build/utils/guards.js +57 -0
  39. package/build/utils/guards.js.map +1 -0
  40. package/build/utils/index.d.ts +7 -0
  41. package/build/utils/index.d.ts.map +1 -0
  42. package/build/utils/index.js +7 -0
  43. package/build/utils/index.js.map +1 -0
  44. package/build/utils/payload.d.ts +10 -0
  45. package/build/utils/payload.d.ts.map +1 -0
  46. package/build/utils/payload.js +55 -0
  47. package/build/utils/payload.js.map +1 -0
  48. package/build/utils/server.d.ts +10 -0
  49. package/build/utils/server.d.ts.map +1 -0
  50. package/build/utils/server.js +56 -0
  51. package/build/utils/server.js.map +1 -0
  52. package/package.json +62 -0
  53. package/src/consts.ts +7 -0
  54. package/src/errors.ts +35 -0
  55. package/src/helper.ts +89 -0
  56. package/src/index.ts +6 -0
  57. package/src/server.ts +183 -0
  58. package/src/types.ts +26 -0
  59. package/src/utils/context.ts +9 -0
  60. package/src/utils/error.ts +18 -0
  61. package/src/utils/guards.ts +75 -0
  62. package/src/utils/index.ts +7 -0
  63. package/src/utils/payload.ts +62 -0
  64. package/src/utils/server.ts +70 -0
  65. package/tsconfig.json +15 -0
  66. package/tsconfig.tsbuildinfo +1 -0
@@ -0,0 +1 @@
1
+ {"version":3,"file":"errors.js","sourceRoot":"","sources":["../src/errors.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAA;AACxC,OAAO,EAAE,cAAc,EAAE,MAAM,iBAAiB,CAAA;AAEhD,MAAM,OAAO,eAAgB,SAAQ,QAAQ;IACpC,MAAM,CAAU,QAAQ,GAAG,iBAAiB,CAAA;IAEnD,YAAY,UAAkB,OAAO;QACnC,KAAK,CAAC,QAAQ,OAAO,EAAE,CAAC,CAAA;QACxB,IAAI,CAAC,IAAI,GAAG,eAAe,CAAC,QAAQ,CAAA;IACtC,CAAC;;AAGH,MAAM,OAAO,WAAY,SAAQ,QAAQ;IAChC,MAAM,CAAU,QAAQ,GAAG,SAAS,eAAe,CAAC,QAAQ,EAAE,CAAA;IAErE,YAAY,UAAkB,OAAO;QACnC,KAAK,CAAC,UAAU,OAAO,EAAE,CAAC,CAAA;QAC1B,IAAI,CAAC,IAAI,GAAG,WAAW,CAAC,QAAQ,CAAA;IAClC,CAAC;;AAGH,MAAM,OAAO,WAAY,SAAQ,QAAQ;IAChC,MAAM,CAAU,QAAQ,GAAG,aAAa,CAAA;IAE/C;QACE,KAAK,CAAC,SAAS,CAAC,CAAA;QAChB,IAAI,CAAC,IAAI,GAAG,WAAW,CAAC,QAAQ,CAAA;IAClC,CAAC;;AAGH,cAAc,CAAC,kBAAkB,CAAC,eAAe,CAAC,CAAA;AAClD,cAAc,CAAC,kBAAkB,CAAC,WAAW,CAAC,CAAA;AAC9C,cAAc,CAAC,kBAAkB,CAAC,WAAW,CAAC,CAAA"}
@@ -0,0 +1,13 @@
1
+ import type { BasicConfig, BasicContext } from '@owlmeans/context';
2
+ import type { AbstractRequest, AbstractResponse } from '@owlmeans/module';
3
+ import type { RefedModuleHandler } from '@owlmeans/server-module';
4
+ import type { Context } from './types.js';
5
+ import type { MultipartFile } from '@fastify/multipart';
6
+ export declare const handleBody: <T>(handler: (payload: T, ctx: BasicContext<BasicConfig>, req: AbstractRequest) => Promise<any>) => RefedModuleHandler<AbstractResponse<any>>;
7
+ export declare const handleParams: <T>(handler: (payload: T, ctx: BasicContext<BasicConfig>, req: AbstractRequest) => Promise<any>) => RefedModuleHandler<AbstractResponse<any>>;
8
+ export declare const handleRequest: (handler: (payload: AbstractRequest, ctx: BasicContext<BasicConfig>, res?: AbstractResponse<any>) => Promise<any>) => RefedModuleHandler<AbstractResponse<any>>;
9
+ export declare const handleIntermediate: (handler: (payload: AbstractRequest, ctx: BasicContext<BasicConfig>) => Promise<BasicContext<BasicConfig> | null>) => RefedModuleHandler<AbstractResponse<Context | null>>;
10
+ export declare const extractUploadedFile: <T extends {} = {}>(req: AbstractRequest<T>) => Promise<UploadedFile | undefined>;
11
+ export interface UploadedFile extends MultipartFile {
12
+ }
13
+ //# sourceMappingURL=helper.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"helper.d.ts","sourceRoot":"","sources":["../src/helper.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,WAAW,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAA;AAGlE,OAAO,KAAK,EAAE,eAAe,EAAE,gBAAgB,EAAE,MAAM,kBAAkB,CAAA;AACzE,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,yBAAyB,CAAA;AACjE,OAAO,KAAK,EAAU,OAAO,EAAE,MAAM,YAAY,CAAA;AAEjD,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAA;AAMvD,eAAO,MAAM,UAAU,EAAE,CAAC,CAAC,EACzB,OAAO,EAAE,CAAC,OAAO,EAAE,CAAC,EAAE,GAAG,EAAE,YAAY,CAAC,WAAW,CAAC,EAAE,GAAG,EAAE,eAAe,KAAK,OAAO,CAAC,GAAG,CAAC,KACxF,kBAAkB,CAAC,gBAAgB,CAAC,GAAG,CAAC,CAa5C,CAAA;AAED,eAAO,MAAM,YAAY,EAAE,CAAC,CAAC,EAC3B,OAAO,EAAE,CAAC,OAAO,EAAE,CAAC,EAAE,GAAG,EAAE,YAAY,CAAC,WAAW,CAAC,EAAE,GAAG,EAAE,eAAe,KAAK,OAAO,CAAC,GAAG,CAAC,KAExF,kBAAkB,CAAC,gBAAgB,CAAC,GAAG,CAAC,CAa5C,CAAA;AAED,eAAO,MAAM,aAAa,EAAE,CAC1B,OAAO,EAAE,CAAC,OAAO,EAAE,eAAe,EAAE,GAAG,EAAE,YAAY,CAAC,WAAW,CAAC,EAAE,GAAG,CAAC,EAAE,gBAAgB,CAAC,GAAG,CAAC,KAAK,OAAO,CAAC,GAAG,CAAC,KAC7G,kBAAkB,CAAC,gBAAgB,CAAC,GAAG,CAAC,CAW5C,CAAA;AAED,eAAO,MAAM,kBAAkB,EAAE,CAC/B,OAAO,EAAE,CAAC,OAAO,EAAE,eAAe,EAAE,GAAG,EAAE,YAAY,CAAC,WAAW,CAAC,KAAK,OAAO,CAAC,YAAY,CAAC,WAAW,CAAC,GAAG,IAAI,CAAC,KAC7G,kBAAkB,CAAC,gBAAgB,CAAC,OAAO,GAAG,IAAI,CAAC,CAcvD,CAAA;AAED,eAAO,MAAM,mBAAmB,GAAU,CAAC,SAAS,EAAE,YAAY,eAAe,CAAC,CAAC,CAAC,KAAG,OAAO,CAAC,YAAY,GAAG,SAAS,CAItH,CAAA;AAED,MAAM,WAAW,YAAa,SAAQ,aAAa;CAAI"}
@@ -0,0 +1,53 @@
1
+ import { assertContext } from '@owlmeans/context';
2
+ import { ModuleOutcome } from '@owlmeans/module';
3
+ const _castContextFromOriginal = (req, def) => {
4
+ return req.original._ctx ?? def;
5
+ };
6
+ export const handleBody = handler => ref => async (req, res) => {
7
+ const ctx = assertContext(ref.ref?.ctx);
8
+ try {
9
+ res.resolve(await handler(req.body, _castContextFromOriginal(req, ctx), req), ModuleOutcome.Ok);
10
+ }
11
+ catch (e) {
12
+ res.reject(e);
13
+ }
14
+ return res.value;
15
+ };
16
+ export const handleParams = handler => ref => async (req, res) => {
17
+ const ctx = assertContext(ref.ref?.ctx);
18
+ try {
19
+ res.resolve(await handler(req.params, _castContextFromOriginal(req, ctx), req), ModuleOutcome.Ok);
20
+ }
21
+ catch (e) {
22
+ res.reject(e);
23
+ }
24
+ return res.value;
25
+ };
26
+ export const handleRequest = handler => ref => async (req, res) => {
27
+ const ctx = assertContext(ref.ref?.ctx);
28
+ try {
29
+ res.resolve(await handler(req, _castContextFromOriginal(req, ctx), res), ModuleOutcome.Ok);
30
+ }
31
+ catch (e) {
32
+ res.reject(e);
33
+ }
34
+ return res.value;
35
+ };
36
+ export const handleIntermediate = handler => ref => async (req, res) => {
37
+ const ctx = assertContext(ref.ref?.ctx);
38
+ try {
39
+ const result = await handler(req, _castContextFromOriginal(req, ctx));
40
+ if (result != null) {
41
+ res.resolve(result);
42
+ }
43
+ return res.value;
44
+ }
45
+ catch (e) {
46
+ res.reject(e);
47
+ }
48
+ };
49
+ export const extractUploadedFile = async (req) => {
50
+ const request = req.original;
51
+ return request.file();
52
+ };
53
+ //# sourceMappingURL=helper.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"helper.js","sourceRoot":"","sources":["../src/helper.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,6 @@
1
+ export type * from './types.js';
2
+ export * from './server.js';
3
+ export * from './consts.js';
4
+ export * from './errors.js';
5
+ export * from './helper.js';
6
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AACA,mBAAmB,YAAY,CAAA;AAC/B,cAAc,aAAa,CAAA;AAC3B,cAAc,aAAa,CAAA;AAC3B,cAAc,aAAa,CAAA;AAC3B,cAAc,aAAa,CAAA"}
package/build/index.js ADDED
@@ -0,0 +1,5 @@
1
+ export * from './server.js';
2
+ export * from './consts.js';
3
+ export * from './errors.js';
4
+ export * from './helper.js';
5
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAEA,cAAc,aAAa,CAAA;AAC3B,cAAc,aAAa,CAAA;AAC3B,cAAc,aAAa,CAAA;AAC3B,cAAc,aAAa,CAAA"}
@@ -0,0 +1,7 @@
1
+ import type { ServerConfig, ServerContext } from '@owlmeans/server-context';
2
+ import type { ApiServer, ApiServerAppend } from './types.js';
3
+ type Config = ServerConfig;
4
+ export declare const createApiServer: (alias: string) => ApiServer;
5
+ export declare const appendApiServer: <C extends Config, T extends ServerContext<C>>(ctx: T, alias?: string) => T & ApiServerAppend;
6
+ export {};
7
+ //# sourceMappingURL=server.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,aAAa,EAAE,MAAM,0BAA0B,CAAA;AAC3E,OAAO,KAAK,EAAE,SAAS,EAAE,eAAe,EAAE,MAAM,YAAY,CAAA;AAiC5D,KAAK,MAAM,GAAG,YAAY,CAAA;AAG1B,eAAO,MAAM,eAAe,UAAW,MAAM,KAAG,SAgI/C,CAAA;AAED,eAAO,MAAM,eAAe,GAAI,CAAC,SAAS,MAAM,EAAE,CAAC,SAAS,aAAa,CAAC,CAAC,CAAC,OACrE,CAAC,UAAS,MAAM,KACpB,CAAC,GAAG,eAWN,CAAA"}
@@ -0,0 +1,146 @@
1
+ import { Layer, assertContext, createService } from '@owlmeans/context';
2
+ import { canServeModule, executeResponse, provideRequest } from './utils/index.js';
3
+ import { DEFAULT_ALIAS, CLOSED_HOST, PORT, OPENED_HOST } from './consts.js';
4
+ import { RouteMethod } from '@owlmeans/route';
5
+ import { createServerHandler, fixFormatDates } from './utils/index.js';
6
+ import { provideResponse } from '@owlmeans/module';
7
+ import { TOKEN_UPDATE } from '@owlmeans/auth-common';
8
+ import Fastify from 'fastify';
9
+ import cors from '@fastify/cors';
10
+ import rawBody from 'fastify-raw-body';
11
+ import Middie from '@fastify/middie';
12
+ import Helmet from '@fastify/helmet';
13
+ import Multipart from '@fastify/multipart';
14
+ import formatsPlugin from 'ajv-formats';
15
+ import Ajv from 'ajv';
16
+ import ajvErrors from "ajv-errors";
17
+ const ajv = new Ajv({
18
+ removeAdditional: true,
19
+ useDefaults: true,
20
+ coerceTypes: true,
21
+ allErrors: true,
22
+ strict: false
23
+ });
24
+ formatsPlugin(ajv);
25
+ ajvErrors(ajv, { singleError: true });
26
+ export const createApiServer = (alias) => {
27
+ const location = `service:${alias}`;
28
+ const _assertContext = (context) => assertContext(context, location);
29
+ const service = createService(alias, {
30
+ server: Fastify({
31
+ logger: true,
32
+ /*{
33
+ transport: {
34
+ target: 'pino-pretty',
35
+ options: {
36
+ singleLine: true,
37
+ translateTime: 'HH:MM:ss Z',
38
+ ignore: 'pid,hostname',
39
+ },
40
+ },
41
+ }*/
42
+ }),
43
+ layers: [Layer.System],
44
+ listen: async () => {
45
+ const context = _assertContext(service.ctx);
46
+ const config = context.cfg.services[context.cfg.service];
47
+ const port = config?.internalPort ?? config?.port ?? PORT;
48
+ const host = config.opened === true ? OPENED_HOST : CLOSED_HOST;
49
+ await service.server.listen({ port, host });
50
+ console.info(`${location}: server listening on ${host}${port != null ? `:${port}` : ''}`);
51
+ process.on('SIGTERM', () => {
52
+ service.server.close().then(() => {
53
+ process.exit(0);
54
+ });
55
+ });
56
+ }
57
+ }, service => async () => {
58
+ if (service.server.server.listening) {
59
+ await service.server.close();
60
+ service.server = Fastify({ logger: true });
61
+ }
62
+ const context = _assertContext(service.ctx);
63
+ const server = service.server;
64
+ // @TODO We should ensure some way that Resilient Error is thrown and go to the flow
65
+ server.setValidatorCompiler(opts => ajv.compile(opts.schema));
66
+ // @TODO It's quite unsafe and should be properly configured
67
+ await server.register(cors, {
68
+ origin: '*',
69
+ exposedHeaders: [TOKEN_UPDATE]
70
+ });
71
+ await server.register(Multipart, {
72
+ throwFileSizeLimit: true,
73
+ // @TODO It shouldn't be this way, becaues the file is buffer this way
74
+ attachFieldsToBody: 'keyValues',
75
+ limits: {
76
+ fileSize: 5 * 1024 * 1024,
77
+ files: 5,
78
+ }
79
+ });
80
+ await server.register(Helmet);
81
+ await server.register(rawBody, { field: 'rawBody', global: true, runFirst: true });
82
+ await server.register(Middie);
83
+ server.addHook('preHandler', async (request, reply) => {
84
+ const context = _assertContext(service.ctx);
85
+ // We pass context further using fastify request object
86
+ request._ctx = await context.modules().filter(module => canServeModule(context, module) && module.route.isIntermediate()).reduce(async (promise, module) => {
87
+ let context = await promise;
88
+ if (reply.sent) {
89
+ return context;
90
+ }
91
+ // await module.route.resolve(context as any)
92
+ await module.resolve();
93
+ // Actually intermediate module can be created without handler by elevate function
94
+ if (module.route.match(request) && module.handle != null) {
95
+ const response = provideResponse(reply);
96
+ const currentRequest = provideRequest(module.alias, request, true);
97
+ currentRequest.original._ctx = context;
98
+ const result = await module.handle(currentRequest, response);
99
+ if (result != null) {
100
+ context = result;
101
+ }
102
+ executeResponse(response, reply, true);
103
+ }
104
+ return context;
105
+ }, Promise.resolve(context));
106
+ });
107
+ await Promise.all(context.modules()
108
+ .filter(module => canServeModule(context, module) && !module.route.isIntermediate())
109
+ .map(async (module) => {
110
+ // await module.route.resolve(context as any)
111
+ await module.resolve();
112
+ const method = module.route.route.method ?? RouteMethod.GET;
113
+ if (module.handle == null) {
114
+ return;
115
+ }
116
+ server.route({
117
+ url: module.getPath(), method,
118
+ schema: {
119
+ consumes: [
120
+ 'application/json',
121
+ 'application/x-www-form-urlencoded',
122
+ 'multipart/form-data',
123
+ ],
124
+ querystring: fixFormatDates(module.filter?.query ?? {}),
125
+ ...(method !== RouteMethod.GET ? { body: fixFormatDates(module.filter?.body ?? {}) } : {}),
126
+ params: fixFormatDates(module.filter?.params ?? {}),
127
+ response: module.filter?.response,
128
+ headers: fixFormatDates(module.filter?.headers ?? {})
129
+ },
130
+ handler: createServerHandler(module, location)
131
+ });
132
+ }));
133
+ service.initialized = true;
134
+ });
135
+ return service;
136
+ };
137
+ export const appendApiServer = (ctx, alias = DEFAULT_ALIAS) => {
138
+ const service = createApiServer(alias);
139
+ const context = ctx;
140
+ context.registerService(service);
141
+ if (context.getApiServer == null) {
142
+ context.getApiServer = () => ctx.service(service.alias);
143
+ }
144
+ return context;
145
+ };
146
+ //# sourceMappingURL=server.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"server.js","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,21 @@
1
+ import type { InitializedService, Layer } from '@owlmeans/context';
2
+ import type { ServerConfig, ServerContext } from '@owlmeans/server-context';
3
+ import type { FastifyInstance, FastifyReply, FastifyRequest } from 'fastify';
4
+ import '@fastify/middie/types/index.d.ts';
5
+ export interface ApiServer extends InitializedService {
6
+ server: FastifyInstance;
7
+ layers: [Layer.System];
8
+ listen: () => Promise<void>;
9
+ }
10
+ export interface Request extends FastifyRequest {
11
+ }
12
+ export interface Response extends FastifyReply {
13
+ }
14
+ export interface ApiServerAppend {
15
+ getApiServer: () => ApiServer;
16
+ }
17
+ export interface Config extends ServerConfig {
18
+ }
19
+ export interface Context<C extends Config = Config> extends ServerContext<C>, ApiServerAppend {
20
+ }
21
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,kBAAkB,EAAE,KAAK,EAAE,MAAM,mBAAmB,CAAA;AAClE,OAAO,KAAK,EAAE,YAAY,EAAE,aAAa,EAAE,MAAM,0BAA0B,CAAA;AAC3E,OAAO,KAAK,EAAE,eAAe,EAAE,YAAY,EAAE,cAAc,EAAE,MAAM,SAAS,CAAA;AAC5E,OAAO,kCAAkC,CAAA;AAEzC,MAAM,WAAW,SAAU,SAAQ,kBAAkB;IACnD,MAAM,EAAE,eAAe,CAAA;IAEvB,MAAM,EAAE,CAAC,KAAK,CAAC,MAAM,CAAC,CAAA;IAEtB,MAAM,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAA;CAC5B;AAED,MAAM,WAAW,OAAQ,SAAQ,cAAc;CAAI;AAEnD,MAAM,WAAW,QAAS,SAAQ,YAAY;CAAI;AAElD,MAAM,WAAW,eAAe;IAC9B,YAAY,EAAE,MAAM,SAAS,CAAA;CAC9B;AAED,MAAM,WAAW,MAAO,SAAQ,YAAY;CAAI;AAEhD,MAAM,WAAW,OAAO,CAAC,CAAC,SAAS,MAAM,GAAG,MAAM,CAAE,SAAQ,aAAa,CAAC,CAAC,CAAC,EAC1E,eAAe;CAAI"}
package/build/types.js ADDED
@@ -0,0 +1,2 @@
1
+ import '@fastify/middie/types/index.d.ts';
2
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAIA,OAAO,kCAAkC,CAAA"}
@@ -0,0 +1,4 @@
1
+ import type { Config, Context, Request } from '../types.js';
2
+ export declare const populateContext: <C extends Config, T extends Context<C>>(req: Request, context: T) => void;
3
+ export declare const extractContext: <C extends Config, T extends Context<C>>(req: Request, ctx?: T, location?: string) => T;
4
+ //# sourceMappingURL=context.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"context.d.ts","sourceRoot":"","sources":["../../src/utils/context.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO,EAAE,MAAM,aAAa,CAAA;AAG3D,eAAO,MAAM,eAAe,GAAI,CAAC,SAAS,MAAM,EAAE,CAAC,SAAS,OAAO,CAAC,CAAC,CAAC,OAAO,OAAO,WAAW,CAAC,KAAG,IAC/D,CAAA;AAEpC,eAAO,MAAM,cAAc,GAAI,CAAC,SAAS,MAAM,EAAE,CAAC,SAAS,OAAO,CAAC,CAAC,CAAC,OAAO,OAAO,QAAQ,CAAC,aAAa,MAAM,KAAG,CACxC,CAAA"}
@@ -0,0 +1,5 @@
1
+ import { assertContext } from '@owlmeans/context';
2
+ import { DEFAULT_ALIAS } from '../consts.js';
3
+ export const populateContext = (req, context) => void (req._ctx = context);
4
+ export const extractContext = (req, ctx, location) => assertContext(req._ctx ?? ctx, location ?? DEFAULT_ALIAS);
5
+ //# sourceMappingURL=context.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"context.js","sourceRoot":"","sources":["../../src/utils/context.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,mBAAmB,CAAA;AAEjD,OAAO,EAAE,aAAa,EAAE,MAAM,cAAc,CAAA;AAE5C,MAAM,CAAC,MAAM,eAAe,GAAG,CAAyC,GAAY,EAAE,OAAU,EAAQ,EAAE,CACxG,KAAK,CAAE,GAAW,CAAC,IAAI,GAAG,OAAO,CAAC,CAAA;AAEpC,MAAM,CAAC,MAAM,cAAc,GAAG,CAAyC,GAAY,EAAE,GAAO,EAAE,QAAiB,EAAK,EAAE,CACpH,aAAa,CAAQ,GAAW,CAAC,IAAI,IAAI,GAAG,EAAE,QAAQ,IAAI,aAAa,CAAC,CAAA"}
@@ -0,0 +1,3 @@
1
+ import type { FastifyReply } from 'fastify';
2
+ export declare const handleError: (error: Error, reply: FastifyReply) => void;
3
+ //# sourceMappingURL=error.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"error.d.ts","sourceRoot":"","sources":["../../src/utils/error.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,SAAS,CAAA;AAI3C,eAAO,MAAM,WAAW,UAAW,KAAK,SAAS,YAAY,SAY5D,CAAA"}
@@ -0,0 +1,16 @@
1
+ import { FORBIDDEN_ERROR, SERVER_ERROR, UNAUTHORIZED_ERROR } from '@owlmeans/api';
2
+ import { AccessError, AuthFailedError } from '../errors.js';
3
+ import { ResilientError } from '@owlmeans/error';
4
+ export const handleError = (error, reply) => {
5
+ let code = SERVER_ERROR;
6
+ if (error instanceof AuthFailedError) {
7
+ code = UNAUTHORIZED_ERROR;
8
+ }
9
+ else if (error instanceof AccessError) {
10
+ code = FORBIDDEN_ERROR;
11
+ }
12
+ if (!reply.sent) {
13
+ reply.code(code).send(ResilientError.marshal(ResilientError.ensure(error)).message);
14
+ }
15
+ };
16
+ //# sourceMappingURL=error.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"error.js","sourceRoot":"","sources":["../../src/utils/error.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,YAAY,EAAE,kBAAkB,EAAE,MAAM,eAAe,CAAA;AAEjF,OAAO,EAAE,WAAW,EAAE,eAAe,EAAE,MAAM,cAAc,CAAA;AAC3D,OAAO,EAAE,cAAc,EAAE,MAAM,iBAAiB,CAAA;AAEhD,MAAM,CAAC,MAAM,WAAW,GAAG,CAAC,KAAY,EAAE,KAAmB,EAAE,EAAE;IAC/D,IAAI,IAAI,GAAW,YAAY,CAAA;IAC/B,IAAI,KAAK,YAAY,eAAe,EAAE,CAAC;QACrC,IAAI,GAAG,kBAAkB,CAAA;IAC3B,CAAC;SAAM,IAAI,KAAK,YAAY,WAAW,EAAE,CAAC;QACxC,IAAI,GAAG,eAAe,CAAA;IACxB,CAAC;IACD,IAAI,CAAC,KAAK,CAAC,IAAI,EAAE,CAAC;QAChB,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,IAAI,CACnB,cAAc,CAAC,OAAO,CAAC,cAAc,CAAC,MAAM,CAAC,KAAc,CAAC,CAAC,CAAC,OAAO,CACtE,CAAA;IACH,CAAC;AACH,CAAC,CAAA"}
@@ -0,0 +1,9 @@
1
+ import type { FastifyReply, FastifyRequest } from 'fastify';
2
+ import type { ServerModule } from '@owlmeans/server-module';
3
+ import type { ServerConfig, ServerContext } from '@owlmeans/server-context';
4
+ type Config = ServerConfig;
5
+ interface Context<C extends Config = Config> extends ServerContext<C> {
6
+ }
7
+ export declare const authorize: <C extends Config, T extends Context<C>>(context: T, module: ServerModule<FastifyRequest>, req: FastifyRequest, reply: FastifyReply) => Promise<[T, ServerModule<FastifyRequest>]>;
8
+ export {};
9
+ //# sourceMappingURL=guards.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"guards.d.ts","sourceRoot":"","sources":["../../src/utils/guards.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,YAAY,EAAE,cAAc,EAAE,MAAM,SAAS,CAAA;AAC3D,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,yBAAyB,CAAA;AAG3D,OAAO,KAAK,EAAE,YAAY,EAAE,aAAa,EAAE,MAAM,0BAA0B,CAAA;AAK3E,KAAK,MAAM,GAAG,YAAY,CAAA;AAC1B,UAAU,OAAO,CAAC,CAAC,SAAS,MAAM,GAAG,MAAM,CAAE,SAAQ,aAAa,CAAC,CAAC,CAAC;CAAI;AAEzE,eAAO,MAAM,SAAS,GAAU,CAAC,SAAS,MAAM,EAAE,CAAC,SAAS,OAAO,CAAC,CAAC,CAAC,WAC3D,CAAC,UAAU,YAAY,CAAC,cAAc,CAAC,OAC3C,cAAc,SAAS,YAAY,KACvC,OAAO,CAAC,CAAC,CAAC,EAAE,YAAY,CAAC,cAAc,CAAC,CAAC,CA0D3C,CAAA"}
@@ -0,0 +1,57 @@
1
+ import { isContextWithoutIds, Layer } from '@owlmeans/context';
2
+ import { provideResponse } from '@owlmeans/module';
3
+ import { executeResponse, provideRequest } from './payload.js';
4
+ import { AuthFailedError } from '../errors.js';
5
+ export const authorize = async (context, module, req, reply) => {
6
+ const guards = module.getGuards();
7
+ if (guards.length > 0) {
8
+ const response = provideResponse(reply);
9
+ const request = provideRequest(module.alias, req);
10
+ let guard = undefined;
11
+ for (const alias of guards) {
12
+ const _guard = context.service(alias);
13
+ if (await _guard.match(request, response)) {
14
+ guard = _guard;
15
+ }
16
+ executeResponse(response, reply, true);
17
+ if (guard != null) {
18
+ break;
19
+ }
20
+ }
21
+ if (guard == null) {
22
+ throw new AuthFailedError();
23
+ }
24
+ const authResponse = provideResponse(reply);
25
+ if (!await guard.handle(request, authResponse)) {
26
+ throw new AuthFailedError(guard.alias);
27
+ }
28
+ executeResponse(authResponse, reply, true);
29
+ // Guard that returns true and does not provide an error is an optional guard
30
+ // if (authResponse.value == null) {
31
+ // throw SyntaxError(`Guard that returns true and does not provide an error, should provide authorization`)
32
+ // }
33
+ request.auth = authResponse.value;
34
+ if (request.auth != null) {
35
+ req._auth = request.auth;
36
+ }
37
+ if (request.auth?.entityId != null) {
38
+ // @TODO Probably we need to downgrade context in this case
39
+ if (!isContextWithoutIds(context)) {
40
+ throw SyntaxError(`Context should be without ids during authorization ${context.cfg.layer}:${context.cfg.layerId}`);
41
+ }
42
+ if (isContextWithoutIds(context) && context.cfg.layer !== Layer.Service) {
43
+ context = await context.updateContext(undefined, Layer.Service);
44
+ await context.waitForInitialized();
45
+ }
46
+ context = await context.updateContext(request.auth.entityId, Layer.Entity);
47
+ await context.waitForInitialized();
48
+ // We elevate module to the context level if it was changed
49
+ module = context.module(module.alias);
50
+ await module.resolve();
51
+ }
52
+ }
53
+ // Update context in request object
54
+ req._ctx = context;
55
+ return [context, module];
56
+ };
57
+ //# sourceMappingURL=guards.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"guards.js","sourceRoot":"","sources":["../../src/utils/guards.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,7 @@
1
+ export * from './error.js';
2
+ export * from './server.js';
3
+ export * from './payload.js';
4
+ export * from './server.js';
5
+ export * from './guards.js';
6
+ export * from './context.js';
7
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/utils/index.ts"],"names":[],"mappings":"AACA,cAAc,YAAY,CAAA;AAC1B,cAAc,aAAa,CAAA;AAC3B,cAAc,cAAc,CAAA;AAC5B,cAAc,aAAa,CAAA;AAC3B,cAAc,aAAa,CAAA;AAC3B,cAAc,cAAc,CAAA"}
@@ -0,0 +1,7 @@
1
+ export * from './error.js';
2
+ export * from './server.js';
3
+ export * from './payload.js';
4
+ export * from './server.js';
5
+ export * from './guards.js';
6
+ export * from './context.js';
7
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/utils/index.ts"],"names":[],"mappings":"AACA,cAAc,YAAY,CAAA;AAC1B,cAAc,aAAa,CAAA;AAC3B,cAAc,cAAc,CAAA;AAC5B,cAAc,aAAa,CAAA;AAC3B,cAAc,aAAa,CAAA;AAC3B,cAAc,cAAc,CAAA"}
@@ -0,0 +1,10 @@
1
+ import type { AbstractResponse, AbstractRequest } from '@owlmeans/module';
2
+ import type { Request, Response } from '../types.js';
3
+ import type { AnySchemaObject } from 'ajv';
4
+ export declare const provideRequest: (alias: string, req: Request, provision?: boolean) => AbstractRequest;
5
+ /**
6
+ * @throws {Error}
7
+ */
8
+ export declare const executeResponse: <T>(response: AbstractResponse<T>, reply: Response, throwOnError?: boolean) => void;
9
+ export declare const fixFormatDates: (schema: AnySchemaObject) => AnySchemaObject;
10
+ //# sourceMappingURL=payload.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"payload.d.ts","sourceRoot":"","sources":["../../src/utils/payload.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,gBAAgB,EAAE,eAAe,EAAE,MAAM,kBAAkB,CAAA;AACzE,OAAO,KAAK,EAAE,OAAO,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAA;AAEpD,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,KAAK,CAAA;AAE1C,eAAO,MAAM,cAAc,UAAW,MAAM,OAAO,OAAO,cAAc,OAAO,KAAG,eAYjF,CAAA;AAED;;GAEG;AACH,eAAO,MAAM,eAAe,GAAI,CAAC,YAAY,gBAAgB,CAAC,CAAC,CAAC,SAAS,QAAQ,iBAAiB,OAAO,SAmBxG,CAAA;AAGD,eAAO,MAAM,cAAc,WAAY,eAAe,oBAgBrD,CAAA"}
@@ -0,0 +1,55 @@
1
+ import { ModuleOutcome } from '@owlmeans/module';
2
+ import { ACCEPTED, CREATED, OK, SERVER_ERROR } from '@owlmeans/api';
3
+ export const provideRequest = (alias, req, provision) => {
4
+ provision = provision ?? false;
5
+ return {
6
+ alias,
7
+ auth: req._auth ?? undefined,
8
+ params: req.params,
9
+ body: req.body,
10
+ headers: req.headers,
11
+ query: req.query,
12
+ path: req.url,
13
+ original: provision ? req : undefined
14
+ };
15
+ };
16
+ /**
17
+ * @throws {Error}
18
+ */
19
+ export const executeResponse = (response, reply, throwOnError) => {
20
+ if (response.error != null) {
21
+ if (throwOnError ?? false) {
22
+ throw response.error;
23
+ }
24
+ reply.code(SERVER_ERROR).send(response.error.message);
25
+ }
26
+ else if (response.outcome != null) {
27
+ switch (response.outcome) {
28
+ case ModuleOutcome.Accepted:
29
+ reply.code(ACCEPTED).send(response.value);
30
+ break;
31
+ case ModuleOutcome.Created:
32
+ reply.code(CREATED).send(response.value);
33
+ break;
34
+ case ModuleOutcome.Ok:
35
+ default:
36
+ reply.code(OK).send(response.value);
37
+ }
38
+ }
39
+ };
40
+ export const fixFormatDates = (schema) => {
41
+ if (schema.type === 'object') {
42
+ if (schema.format === 'date-time') {
43
+ schema.type = 'string';
44
+ schema.format = 'date-time';
45
+ if (schema.required != null) {
46
+ delete schema.required;
47
+ }
48
+ }
49
+ else if (schema.properties != null) {
50
+ schema.properties = Object.fromEntries(Object.entries(schema.properties).map(([key, value]) => [key, fixFormatDates(value)]));
51
+ }
52
+ }
53
+ return schema;
54
+ };
55
+ //# sourceMappingURL=payload.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"payload.js","sourceRoot":"","sources":["../../src/utils/payload.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAA;AAGhD,OAAO,EAAE,QAAQ,EAAE,OAAO,EAAE,EAAE,EAAE,YAAY,EAAE,MAAM,eAAe,CAAA;AAGnE,MAAM,CAAC,MAAM,cAAc,GAAG,CAAC,KAAa,EAAE,GAAY,EAAE,SAAmB,EAAmB,EAAE;IAClG,SAAS,GAAG,SAAS,IAAI,KAAK,CAAA;IAC9B,OAAO;QACL,KAAK;QACL,IAAI,EAAG,GAAW,CAAC,KAAK,IAAI,SAAS;QACrC,MAAM,EAAE,GAAG,CAAC,MAA4D;QACxE,IAAI,EAAE,GAAG,CAAC,IAA2B;QACrC,OAAO,EAAE,GAAG,CAAC,OAAO;QACpB,KAAK,EAAE,GAAG,CAAC,KAA2D;QACtE,IAAI,EAAE,GAAG,CAAC,GAAG;QACb,QAAQ,EAAE,SAAS,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,SAAS;KACtC,CAAA;AACH,CAAC,CAAA;AAED;;GAEG;AACH,MAAM,CAAC,MAAM,eAAe,GAAG,CAAI,QAA6B,EAAE,KAAe,EAAE,YAAsB,EAAE,EAAE;IAC3G,IAAI,QAAQ,CAAC,KAAK,IAAI,IAAI,EAAE,CAAC;QAC3B,IAAI,YAAY,IAAI,KAAK,EAAE,CAAC;YAC1B,MAAM,QAAQ,CAAC,KAAK,CAAA;QACtB,CAAC;QACD,KAAK,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAC,KAAK,CAAC,OAAO,CAAC,CAAA;IACvD,CAAC;SAAM,IAAI,QAAQ,CAAC,OAAO,IAAI,IAAI,EAAE,CAAC;QACpC,QAAQ,QAAQ,CAAC,OAAO,EAAE,CAAC;YACzB,KAAK,aAAa,CAAC,QAAQ;gBACzB,KAAK,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAA;gBACzC,MAAK;YACP,KAAK,aAAa,CAAC,OAAO;gBACxB,KAAK,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAA;gBACxC,MAAK;YACP,KAAK,aAAa,CAAC,EAAE,CAAC;YACtB;gBACE,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAA;QACvC,CAAC;IACH,CAAC;AACH,CAAC,CAAA;AAGD,MAAM,CAAC,MAAM,cAAc,GAAG,CAAC,MAAuB,EAAE,EAAE;IACxD,IAAI,MAAM,CAAC,IAAI,KAAK,QAAQ,EAAE,CAAC;QAC7B,IAAI,MAAM,CAAC,MAAM,KAAK,WAAW,EAAE,CAAC;YAClC,MAAM,CAAC,IAAI,GAAG,QAAQ,CAAA;YACtB,MAAM,CAAC,MAAM,GAAG,WAAW,CAAA;YAC3B,IAAI,MAAM,CAAC,QAAQ,IAAI,IAAI,EAAE,CAAC;gBAC5B,OAAO,MAAM,CAAC,QAAQ,CAAA;YACxB,CAAC;QACH,CAAC;aAAM,IAAI,MAAM,CAAC,UAAU,IAAI,IAAI,EAAE,CAAC;YACrC,MAAM,CAAC,UAAU,GAAG,MAAM,CAAC,WAAW,CACpC,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC,UAAU,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,EAAE,KAAK,CAAC,EAAE,EAAE,CAAC,CAAC,GAAG,EAAE,cAAc,CAAC,KAAwB,CAAC,CAAC,CAAC,CACzG,CAAA;QACH,CAAC;IACH,CAAC;IAED,OAAO,MAAM,CAAA;AACf,CAAC,CAAA"}
@@ -0,0 +1,10 @@
1
+ import type { FastifyReply, FastifyRequest } from 'fastify';
2
+ import type { ServerModule } from '@owlmeans/server-module';
3
+ import type { CommonModule } from '@owlmeans/module';
4
+ import type { ServerContext, ServerConfig } from '@owlmeans/server-context';
5
+ type Config = ServerConfig;
6
+ type Context = ServerContext<Config>;
7
+ export declare const canServeModule: (context: Context, module: CommonModule) => module is ServerModule<unknown>;
8
+ export declare const createServerHandler: (module: ServerModule<FastifyRequest>, location: string) => (req: FastifyRequest, reply: FastifyReply) => Promise<void>;
9
+ export {};
10
+ //# sourceMappingURL=server.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../../src/utils/server.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,YAAY,EAAE,cAAc,EAAE,MAAM,SAAS,CAAA;AAE3D,OAAO,KAAK,EAAgB,YAAY,EAAE,MAAM,yBAAyB,CAAA;AACzE,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,kBAAkB,CAAA;AAGpD,OAAO,KAAK,EAAE,aAAa,EAAE,YAAY,EAAE,MAAM,0BAA0B,CAAA;AAQ3E,KAAK,MAAM,GAAG,YAAY,CAAA;AAC1B,KAAK,OAAO,GAAG,aAAa,CAAC,MAAM,CAAC,CAAA;AAEpC,eAAO,MAAM,cAAc,YAAa,OAAO,UAAU,YAAY,KAAG,MAAM,IAAI,YAAY,CAAC,OAAO,CAYrG,CAAA;AAED,eAAO,MAAM,mBAAmB,WAAY,YAAY,CAAC,cAAc,CAAC,YAAY,MAAM,WAC5E,cAAc,SAAS,YAAY,kBAoC9C,CAAA"}
@@ -0,0 +1,56 @@
1
+ import { AppType } from '@owlmeans/context';
2
+ import { assertContext } from '@owlmeans/context';
3
+ import { provideResponse } from '@owlmeans/module';
4
+ import { ResilientError } from '@owlmeans/error';
5
+ import { OK } from '@owlmeans/api';
6
+ import { handleError } from './error.js';
7
+ import { executeResponse, provideRequest } from './payload.js';
8
+ import { authorize } from './guards.js';
9
+ import { RouteProtocols } from '@owlmeans/route';
10
+ export const canServeModule = (context, module) => {
11
+ if (module.route.route.type !== AppType.Backend) {
12
+ return false;
13
+ }
14
+ if (module.route.route.service != null && module.route.route.service !== context.cfg.service) {
15
+ return false;
16
+ }
17
+ if (module.route.route.protocol === RouteProtocols.SOCKET) {
18
+ return false;
19
+ }
20
+ return 'isIntermediate' in module.route;
21
+ };
22
+ export const createServerHandler = (module, location) => async (req, reply) => {
23
+ // We passed context using fastify request object
24
+ let context = assertContext(req._ctx, location);
25
+ try {
26
+ const authorized = await authorize(context, module, req, reply);
27
+ context = authorized[0];
28
+ module = authorized[1];
29
+ const response = provideResponse(reply);
30
+ const request = provideRequest(module.alias, req, true);
31
+ const gates = module.getGates();
32
+ for (const [srv, params] of gates) {
33
+ const gate = context.service(srv);
34
+ await gate.assert(request, response, params);
35
+ executeResponse(response, reply, true);
36
+ }
37
+ await module.handle(request, response);
38
+ executeResponse(response, reply, true);
39
+ if (!reply.sent) {
40
+ console.warn(`SENDS DEFAULT RESPONSE: ${module.alias}`);
41
+ reply.code(OK).send(response.value);
42
+ }
43
+ }
44
+ catch (error) {
45
+ console.error(`Error in ${module.alias} (${location})`);
46
+ console.error(JSON.stringify(error, null, 2));
47
+ console.error(error);
48
+ if (module.fixer != null) {
49
+ const fixer = context.service(module.fixer);
50
+ fixer.handle(reply, ResilientError.ensure(error));
51
+ return;
52
+ }
53
+ handleError(error, reply);
54
+ }
55
+ };
56
+ //# sourceMappingURL=server.js.map