@pikku/core 0.6.18 → 0.6.20
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/CHANGELOG.md +12 -0
- package/dist/errors/error-handler.d.ts +0 -1
- package/dist/errors/error-handler.js +3 -4
- package/dist/handle-error.d.ts +1 -1
- package/dist/handle-error.js +7 -3
- package/dist/http/http-route-runner.js +7 -7
- package/dist/pikku-state.d.ts +2 -1
- package/dist/pikku-state.js +3 -3
- package/dist/scheduler/scheduler-runner.js +0 -3
- package/dist/schema.d.ts +0 -10
- package/dist/schema.js +5 -26
- package/lcov.info +268 -295
- package/package.json +1 -1
- package/src/errors/error-handler.ts +3 -5
- package/src/handle-error.ts +9 -4
- package/src/http/http-route-runner.ts +8 -6
- package/src/pikku-state.ts +5 -4
- package/src/scheduler/scheduler-runner.ts +0 -4
- package/src/schema.ts +5 -28
- package/tsconfig.tsbuildinfo +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,17 @@
|
|
|
1
1
|
## 0.6
|
|
2
2
|
|
|
3
|
+
## 0.6.20
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- 1d43a9a: feat: adding context to allow middleware to set values (not typed)
|
|
8
|
+
|
|
9
|
+
## 0.6.19
|
|
10
|
+
|
|
11
|
+
### Patch Changes
|
|
12
|
+
|
|
13
|
+
- 9fb2b99: refactor: moving schemas to pikku state
|
|
14
|
+
|
|
3
15
|
## 0.6.18
|
|
4
16
|
|
|
5
17
|
### Patch Changes
|
|
@@ -13,14 +13,13 @@ export class PikkuError extends Error {
|
|
|
13
13
|
Object.setPrototypeOf(this, new.target.prototype);
|
|
14
14
|
}
|
|
15
15
|
}
|
|
16
|
-
export const getErrors = () => pikkuState('errors', 'errors');
|
|
17
16
|
/**
|
|
18
17
|
* Adds an error to the API errors map.
|
|
19
18
|
* @param error - The error to add.
|
|
20
19
|
* @param details - The details of the error.
|
|
21
20
|
*/
|
|
22
21
|
export const addError = (error, { status, message }) => {
|
|
23
|
-
pikkuState('
|
|
22
|
+
pikkuState('misc', 'errors').set(error, { status, message });
|
|
24
23
|
};
|
|
25
24
|
/**
|
|
26
25
|
* Adds multiple errors to the API errors map.
|
|
@@ -37,10 +36,10 @@ export const addErrors = (errors) => {
|
|
|
37
36
|
* @returns An object containing the status and message, or undefined if the error is not found.
|
|
38
37
|
*/
|
|
39
38
|
export const getErrorResponse = (error) => {
|
|
40
|
-
const errors = Array.from(pikkuState('
|
|
39
|
+
const errors = Array.from(pikkuState('misc', 'errors').entries());
|
|
41
40
|
const foundError = errors.find(([e]) => e.name === error.constructor.name);
|
|
42
41
|
if (foundError) {
|
|
43
42
|
return foundError[1];
|
|
44
43
|
}
|
|
45
|
-
return pikkuState('
|
|
44
|
+
return pikkuState('misc', 'errors').get(error);
|
|
46
45
|
};
|
package/dist/handle-error.d.ts
CHANGED
|
@@ -11,4 +11,4 @@ import { PikkuHTTP } from './http/http-routes.types.js';
|
|
|
11
11
|
* @param {boolean} respondWith404 - Whether to respond with 404 for NotFoundError
|
|
12
12
|
* @param {boolean} bubbleError - Whether to throw the error after handling
|
|
13
13
|
*/
|
|
14
|
-
export declare const handleError: (e: any, http: PikkuHTTP | undefined, trackerId: string, logger: Logger, logWarningsForStatusCodes: number[], respondWith404: boolean, bubbleError: boolean) => void;
|
|
14
|
+
export declare const handleError: (e: any, http: PikkuHTTP | undefined, trackerId: string | undefined, logger: Logger, logWarningsForStatusCodes: number[], respondWith404: boolean, bubbleError: boolean) => void;
|
package/dist/handle-error.js
CHANGED
|
@@ -28,16 +28,20 @@ export const handleError = (e, http, trackerId, logger, logWarningsForStatusCode
|
|
|
28
28
|
});
|
|
29
29
|
// Log certain status codes as warnings
|
|
30
30
|
if (logWarningsForStatusCodes.includes(errorResponse.status)) {
|
|
31
|
-
|
|
31
|
+
if (trackerId) {
|
|
32
|
+
logger.warn(`Warning id: ${trackerId}`);
|
|
33
|
+
}
|
|
32
34
|
logger.warn(e);
|
|
33
35
|
}
|
|
34
36
|
}
|
|
35
37
|
else {
|
|
36
38
|
// Handle unexpected errors
|
|
37
|
-
logger.warn(`Error id: ${trackerId}`);
|
|
38
39
|
logger.error(e);
|
|
39
40
|
http?.response?.setStatus(500);
|
|
40
|
-
|
|
41
|
+
if (trackerId) {
|
|
42
|
+
logger.warn(`Error id: ${trackerId}`);
|
|
43
|
+
http?.response?.setJson({ errorId: trackerId });
|
|
44
|
+
}
|
|
41
45
|
}
|
|
42
46
|
// Handle 404 errors specifically
|
|
43
47
|
if (e instanceof NotFoundError) {
|
|
@@ -3,7 +3,6 @@ import { match } from 'path-to-regexp';
|
|
|
3
3
|
import { PikkuHTTPAbstractRequest } from './pikku-http-abstract-request.js';
|
|
4
4
|
import { PikkuHTTPAbstractResponse } from './pikku-http-abstract-response.js';
|
|
5
5
|
import { ForbiddenError, MissingSessionError, NotFoundError, } from '../errors/errors.js';
|
|
6
|
-
import crypto from 'crypto';
|
|
7
6
|
import { closeSessionServices } from '../utils.js';
|
|
8
7
|
import { coerceQueryStringToArray, validateSchema } from '../schema.js';
|
|
9
8
|
import { LocalUserSessionService } from '../services/user-session-service.js';
|
|
@@ -111,7 +110,7 @@ export const createHTTPInteraction = (request, response) => {
|
|
|
111
110
|
*/
|
|
112
111
|
const executeRouteWithMiddleware = async (services, matchedRoute, http, options) => {
|
|
113
112
|
const { matchedPath, params, route, middleware, schemaName } = matchedRoute;
|
|
114
|
-
const { singletonServices, userSessionService, createSessionServices, skipUserSession, } = services;
|
|
113
|
+
const { singletonServices, userSessionService, context, createSessionServices, skipUserSession, } = services;
|
|
115
114
|
const requiresSession = route.auth !== false;
|
|
116
115
|
let sessionServices;
|
|
117
116
|
let result;
|
|
@@ -132,8 +131,8 @@ const executeRouteWithMiddleware = async (services, matchedRoute, http, options)
|
|
|
132
131
|
throw new MissingSessionError();
|
|
133
132
|
}
|
|
134
133
|
// Create session services
|
|
135
|
-
sessionServices = await createSessionServices(singletonServices, { http }, session);
|
|
136
|
-
const allServices = { ...singletonServices, ...sessionServices,
|
|
134
|
+
sessionServices = await createSessionServices({ ...singletonServices, context }, { http }, session);
|
|
135
|
+
const allServices = { ...singletonServices, ...sessionServices, context };
|
|
137
136
|
const data = await http?.request?.getData();
|
|
138
137
|
// Validate schema
|
|
139
138
|
validateSchema(singletonServices.logger, singletonServices.schemaService, schemaName, data);
|
|
@@ -158,7 +157,7 @@ const executeRouteWithMiddleware = async (services, matchedRoute, http, options)
|
|
|
158
157
|
http?.response?.end();
|
|
159
158
|
return result;
|
|
160
159
|
};
|
|
161
|
-
await runMiddleware({ ...singletonServices, userSessionService }, { http }, middleware, runMain);
|
|
160
|
+
await runMiddleware({ ...singletonServices, context, userSessionService }, { http }, middleware, runMain);
|
|
162
161
|
return sessionServices ? { result, sessionServices } : { result };
|
|
163
162
|
};
|
|
164
163
|
/**
|
|
@@ -169,7 +168,7 @@ const executeRouteWithMiddleware = async (services, matchedRoute, http, options)
|
|
|
169
168
|
* @ignore
|
|
170
169
|
*/
|
|
171
170
|
export const runHTTPRoute = async ({ singletonServices, request, response, createSessionServices, route: apiRoute, method: apiType, skipUserSession = false, respondWith404 = true, logWarningsForStatusCodes = [], coerceToArray = false, bubbleErrors = false, }) => {
|
|
172
|
-
const
|
|
171
|
+
const context = new Map();
|
|
173
172
|
const userSessionService = new LocalUserSessionService();
|
|
174
173
|
let sessionServices;
|
|
175
174
|
let result;
|
|
@@ -192,6 +191,7 @@ export const runHTTPRoute = async ({ singletonServices, request, response, creat
|
|
|
192
191
|
({ result, sessionServices } = await executeRouteWithMiddleware({
|
|
193
192
|
singletonServices,
|
|
194
193
|
userSessionService,
|
|
194
|
+
context,
|
|
195
195
|
createSessionServices,
|
|
196
196
|
skipUserSession,
|
|
197
197
|
}, matchedRoute, http, { coerceToArray }));
|
|
@@ -199,7 +199,7 @@ export const runHTTPRoute = async ({ singletonServices, request, response, creat
|
|
|
199
199
|
}
|
|
200
200
|
catch (e) {
|
|
201
201
|
// Handle and possibly bubble the error
|
|
202
|
-
handleError(e, http,
|
|
202
|
+
handleError(e, http, context.get('trackingId'), singletonServices.logger, logWarningsForStatusCodes, respondWith404, bubbleErrors);
|
|
203
203
|
}
|
|
204
204
|
finally {
|
|
205
205
|
// Clean up session services
|
package/dist/pikku-state.d.ts
CHANGED
|
@@ -20,8 +20,9 @@ interface PikkuState {
|
|
|
20
20
|
tasks: Map<string, CoreScheduledTask>;
|
|
21
21
|
meta: ScheduledTasksMeta;
|
|
22
22
|
};
|
|
23
|
-
|
|
23
|
+
misc: {
|
|
24
24
|
errors: Map<PikkuError, ErrorDetails>;
|
|
25
|
+
schemas: Map<string, any>;
|
|
25
26
|
};
|
|
26
27
|
}
|
|
27
28
|
export declare const resetPikkuState: () => void;
|
package/dist/pikku-state.js
CHANGED
|
@@ -13,9 +13,9 @@ export const resetPikkuState = () => {
|
|
|
13
13
|
tasks: new Map(),
|
|
14
14
|
meta: [],
|
|
15
15
|
},
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
16
|
+
misc: {
|
|
17
|
+
errors: globalThis.pikkuState?.misc?.errors || new Map(),
|
|
18
|
+
schemas: globalThis.pikkuState?.misc?.schema || new Map(),
|
|
19
19
|
},
|
|
20
20
|
};
|
|
21
21
|
};
|
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
import crypto from 'crypto';
|
|
2
1
|
import { getErrorResponse } from '../errors/error-handler.js';
|
|
3
2
|
import { closeSessionServices } from '../utils.js';
|
|
4
3
|
import { pikkuState } from '../pikku-state.js';
|
|
@@ -16,7 +15,6 @@ class ScheduledTaskNotFoundError extends Error {
|
|
|
16
15
|
}
|
|
17
16
|
export async function runScheduledTask({ name, session, singletonServices, createSessionServices, }) {
|
|
18
17
|
let sessionServices;
|
|
19
|
-
const trackerId = crypto.randomUUID().toString();
|
|
20
18
|
try {
|
|
21
19
|
const task = pikkuState('scheduler', 'tasks').get(name);
|
|
22
20
|
if (!task) {
|
|
@@ -33,7 +31,6 @@ export async function runScheduledTask({ name, session, singletonServices, creat
|
|
|
33
31
|
catch (e) {
|
|
34
32
|
const errorResponse = getErrorResponse(e);
|
|
35
33
|
if (errorResponse != null) {
|
|
36
|
-
singletonServices.logger.warn(`Error id: ${trackerId}`);
|
|
37
34
|
singletonServices.logger.error(e);
|
|
38
35
|
}
|
|
39
36
|
throw e;
|
package/dist/schema.d.ts
CHANGED
|
@@ -1,15 +1,5 @@
|
|
|
1
1
|
import { Logger } from './services/logger.js';
|
|
2
2
|
import { SchemaService } from './services/schema-service.js';
|
|
3
|
-
/**
|
|
4
|
-
* Retrieves the global schemas map.
|
|
5
|
-
* @returns A map of schemas.
|
|
6
|
-
*/
|
|
7
|
-
export declare const getSchemas: () => any;
|
|
8
|
-
/**
|
|
9
|
-
* Retrieves a schema from the schemas map.
|
|
10
|
-
* @returns A schema.
|
|
11
|
-
*/
|
|
12
|
-
export declare const getSchema: (schemaName: string) => any;
|
|
13
3
|
/**
|
|
14
4
|
* Adds a schema to the global schemas map.
|
|
15
5
|
* @param name - The name of the schema.
|
package/dist/schema.js
CHANGED
|
@@ -1,27 +1,5 @@
|
|
|
1
1
|
import { UnprocessableContentError } from './errors/errors.js';
|
|
2
2
|
import { pikkuState } from './pikku-state.js';
|
|
3
|
-
/**
|
|
4
|
-
* Retrieves the global schemas map.
|
|
5
|
-
* @returns A map of schemas.
|
|
6
|
-
*/
|
|
7
|
-
export const getSchemas = () => {
|
|
8
|
-
if (!global.pikkuSchemas) {
|
|
9
|
-
global.pikkuSchemas = new Map();
|
|
10
|
-
}
|
|
11
|
-
return global.pikkuSchemas;
|
|
12
|
-
};
|
|
13
|
-
/**
|
|
14
|
-
* Retrieves a schema from the schemas map.
|
|
15
|
-
* @returns A schema.
|
|
16
|
-
*/
|
|
17
|
-
export const getSchema = (schemaName) => {
|
|
18
|
-
const schemas = getSchemas();
|
|
19
|
-
const schema = schemas.get(schemaName);
|
|
20
|
-
if (!schema) {
|
|
21
|
-
throw new Error(`Schema not found: ${schemaName}`);
|
|
22
|
-
}
|
|
23
|
-
return schema;
|
|
24
|
-
};
|
|
25
3
|
/**
|
|
26
4
|
* Adds a schema to the global schemas map.
|
|
27
5
|
* @param name - The name of the schema.
|
|
@@ -29,7 +7,7 @@ export const getSchema = (schemaName) => {
|
|
|
29
7
|
* @ignore
|
|
30
8
|
*/
|
|
31
9
|
export const addSchema = (name, value) => {
|
|
32
|
-
|
|
10
|
+
pikkuState('misc', 'schemas').set(name, value);
|
|
33
11
|
};
|
|
34
12
|
/**
|
|
35
13
|
* Loads a schema and compiles it into a validator.
|
|
@@ -39,7 +17,8 @@ export const compileAllSchemas = (logger, schemaService) => {
|
|
|
39
17
|
if (!schemaService) {
|
|
40
18
|
throw new Error('SchemaService needs to be defined to load schemas');
|
|
41
19
|
}
|
|
42
|
-
|
|
20
|
+
const schemas = pikkuState('misc', 'schemas');
|
|
21
|
+
for (const [name, schema] of schemas) {
|
|
43
22
|
schemaService.compileSchema(name, schema);
|
|
44
23
|
}
|
|
45
24
|
validateAllSchemasLoaded(logger, schemaService);
|
|
@@ -64,7 +43,7 @@ const validateAllSchemasLoaded = (logger, schemaService) => {
|
|
|
64
43
|
}
|
|
65
44
|
};
|
|
66
45
|
export const coerceQueryStringToArray = (schemaName, data) => {
|
|
67
|
-
const schema =
|
|
46
|
+
const schema = pikkuState('misc', 'schemas').get(schemaName);
|
|
68
47
|
for (const key in schema.properties) {
|
|
69
48
|
const property = schema.properties[key];
|
|
70
49
|
if (typeof property === 'boolean') {
|
|
@@ -90,7 +69,7 @@ export const validateSchema = async (logger, schemaService, schemaName, data) =>
|
|
|
90
69
|
return;
|
|
91
70
|
}
|
|
92
71
|
}
|
|
93
|
-
const schema =
|
|
72
|
+
const schema = pikkuState('misc', 'schemas').get(schemaName);
|
|
94
73
|
await schemaService.compileSchema(schemaName, schema);
|
|
95
74
|
await schemaService.validateSchema(schemaName, data);
|
|
96
75
|
}
|