@rvoh/psychic 3.0.0-alpha.1 → 3.0.0-alpha.3
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/cjs/src/controller/index.js +17 -6
- package/dist/cjs/src/openapi-renderer/SerializerOpenapiRenderer.js +16 -4
- package/dist/cjs/src/openapi-renderer/endpoint.js +3 -1
- package/dist/cjs/src/psychic-app/index.js +1 -6
- package/dist/cjs/src/server/index.js +2 -2
- package/dist/esm/src/controller/index.js +17 -6
- package/dist/esm/src/openapi-renderer/SerializerOpenapiRenderer.js +16 -4
- package/dist/esm/src/openapi-renderer/endpoint.js +3 -1
- package/dist/esm/src/psychic-app/index.js +1 -6
- package/dist/esm/src/server/index.js +2 -2
- package/dist/types/src/openapi-renderer/endpoint.d.ts +7 -1
- package/package.json +4 -5
|
@@ -2,6 +2,7 @@ import { Dream, DreamApp } from '@rvoh/dream';
|
|
|
2
2
|
import { GlobalNameNotSet } from '@rvoh/dream/errors';
|
|
3
3
|
import { DreamSerializerBuilder, ObjectSerializerBuilder } from '@rvoh/dream/system';
|
|
4
4
|
import fastJsonStringify from 'fast-json-stringify';
|
|
5
|
+
import { debuglog } from 'node:util';
|
|
5
6
|
import ParamValidationError from '../error/controller/ParamValidationError.js';
|
|
6
7
|
import HttpStatusBadGateway from '../error/http/BadGateway.js';
|
|
7
8
|
import HttpStatusBadRequest from '../error/http/BadRequest.js';
|
|
@@ -607,7 +608,9 @@ export default class PsychicController {
|
|
|
607
608
|
return;
|
|
608
609
|
this.ctx.status = statusCode;
|
|
609
610
|
// Try to use fast-json-stringify if an OpenAPI schema exists for this endpoint
|
|
610
|
-
const stringifyFn = this.
|
|
611
|
+
const stringifyFn = this.currentOpenapiRenderer?.['disableFastJson']
|
|
612
|
+
? undefined
|
|
613
|
+
: this.getFastJsonStringifyFunction(statusCode);
|
|
611
614
|
if (stringifyFn) {
|
|
612
615
|
this.ctx.type = 'application/json';
|
|
613
616
|
this.ctx.body = stringifyFn(data);
|
|
@@ -644,15 +647,23 @@ export default class PsychicController {
|
|
|
644
647
|
const schemaWithComponents = validator.getResponseSchemaWithComponents(statusCode);
|
|
645
648
|
if (!schemaWithComponents)
|
|
646
649
|
continue;
|
|
647
|
-
// Generate cache key
|
|
648
650
|
const cacheKey = `${controllerClass.globalName}#${this.action}|${openapiName}|${statusCode}`;
|
|
649
|
-
// Check cache first
|
|
650
651
|
const cachedStringify = getCachedStringify(cacheKey);
|
|
651
652
|
if (cachedStringify)
|
|
652
653
|
return cachedStringify;
|
|
653
|
-
|
|
654
|
-
|
|
655
|
-
|
|
654
|
+
let stringifyFn;
|
|
655
|
+
if (debuglog('json').enabled) {
|
|
656
|
+
const result = fastJsonStringify(schemaWithComponents, {
|
|
657
|
+
mode: 'debug',
|
|
658
|
+
ajv: { validateFormats: false },
|
|
659
|
+
});
|
|
660
|
+
PsychicApp.log('fast-json-stringify code:', result.code);
|
|
661
|
+
// eslint-disable-next-line @typescript-eslint/no-unsafe-argument, @typescript-eslint/no-explicit-any
|
|
662
|
+
stringifyFn = fastJsonStringify.restore(result);
|
|
663
|
+
}
|
|
664
|
+
else {
|
|
665
|
+
stringifyFn = fastJsonStringify(schemaWithComponents, { ajv: { validateFormats: false } });
|
|
666
|
+
}
|
|
656
667
|
cacheStringify(cacheKey, stringifyFn);
|
|
657
668
|
return stringifyFn;
|
|
658
669
|
}
|
|
@@ -166,8 +166,8 @@ export default class SerializerOpenapiRenderer {
|
|
|
166
166
|
// rendersOnes //
|
|
167
167
|
//////////////////
|
|
168
168
|
case 'rendersOne': {
|
|
169
|
+
const outputAttributeName = this.setCase(attribute.options.as ?? attribute.name);
|
|
169
170
|
try {
|
|
170
|
-
const outputAttributeName = this.setCase(attribute.options.as ?? attribute.name);
|
|
171
171
|
const { associationOpts, referencedSerializersAndOpenapiSchemaBodyShorthand } = associationOpenapi(attribute, DataTypeForOpenapi, alreadyExtractedDescendantSerializers);
|
|
172
172
|
const optional = attribute.options.optional ?? associationOpts.optional;
|
|
173
173
|
newlyReferencedSerializers =
|
|
@@ -193,8 +193,14 @@ export default class SerializerOpenapiRenderer {
|
|
|
193
193
|
return accumulator;
|
|
194
194
|
}
|
|
195
195
|
catch (error) {
|
|
196
|
-
if (error instanceof CallingSerializersThrewError)
|
|
196
|
+
if (error instanceof CallingSerializersThrewError) {
|
|
197
|
+
accumulator[outputAttributeName] = {
|
|
198
|
+
type: 'object',
|
|
199
|
+
additionalProperties: true,
|
|
200
|
+
description: `Serializer ${this.serializer['globalName']} includes a rendersOne "${outputAttributeName}" with an OpenAPI shape that cannot be defined. This will break fast-json-stringify. Define the OpenAPI shape or disableFastJson on the endpoint.`,
|
|
201
|
+
};
|
|
197
202
|
return accumulator;
|
|
203
|
+
}
|
|
198
204
|
if (error instanceof AttemptedToDeriveDescendentSerializersFromNonSerializer)
|
|
199
205
|
throw new ExpectedSerializerForRendersOneOrManyOption('rendersOne', this.globalName, attribute);
|
|
200
206
|
throw error;
|
|
@@ -207,8 +213,8 @@ export default class SerializerOpenapiRenderer {
|
|
|
207
213
|
// rendersManys //
|
|
208
214
|
///////////////////
|
|
209
215
|
case 'rendersMany': {
|
|
216
|
+
const outputAttributeName = this.setCase(attribute.options.as ?? attribute.name);
|
|
210
217
|
try {
|
|
211
|
-
const outputAttributeName = this.setCase(attribute.options.as ?? attribute.name);
|
|
212
218
|
const { referencedSerializersAndOpenapiSchemaBodyShorthand } = associationOpenapi(attribute, DataTypeForOpenapi, alreadyExtractedDescendantSerializers);
|
|
213
219
|
newlyReferencedSerializers =
|
|
214
220
|
referencedSerializersAndOpenapiSchemaBodyShorthand.referencedSerializers;
|
|
@@ -219,8 +225,14 @@ export default class SerializerOpenapiRenderer {
|
|
|
219
225
|
return accumulator;
|
|
220
226
|
}
|
|
221
227
|
catch (error) {
|
|
222
|
-
if (error instanceof CallingSerializersThrewError)
|
|
228
|
+
if (error instanceof CallingSerializersThrewError) {
|
|
229
|
+
accumulator[outputAttributeName] = {
|
|
230
|
+
type: 'array',
|
|
231
|
+
items: { type: 'object', additionalProperties: true },
|
|
232
|
+
description: `Serializer ${this.serializer['globalName']} includes a rendersMany "${outputAttributeName}" with an OpenAPI shape that cannot be defined. This will break fast-json-stringify. Define the OpenAPI shape or disableFastJson on the endpoint.`,
|
|
233
|
+
};
|
|
223
234
|
return accumulator;
|
|
235
|
+
}
|
|
224
236
|
if (error instanceof AttemptedToDeriveDescendentSerializersFromNonSerializer)
|
|
225
237
|
throw new ExpectedSerializerForRendersOneOrManyOption('rendersMany', this.globalName, attribute);
|
|
226
238
|
throw error;
|
|
@@ -40,6 +40,7 @@ export default class OpenapiEndpointRenderer {
|
|
|
40
40
|
omitDefaultResponses;
|
|
41
41
|
defaultResponse;
|
|
42
42
|
validate = undefined;
|
|
43
|
+
disableFastJson = false;
|
|
43
44
|
/**
|
|
44
45
|
* instantiates a new OpenapiEndpointRenderer.
|
|
45
46
|
* This class is used by the `@Openapi` decorator
|
|
@@ -54,7 +55,7 @@ export default class OpenapiEndpointRenderer {
|
|
|
54
55
|
* const json = JSON.encode(openapiJsonContents, null, 2)
|
|
55
56
|
* ```
|
|
56
57
|
*/
|
|
57
|
-
constructor(dreamsOrSerializers, controllerClass, action, { requestBody, headers, many, paginate, cursorPaginate, scrollPaginate, query, responses, serializerKey, status, tags, security, pathParams, description, summary, omitDefaultHeaders, omitDefaultResponses, defaultResponse, validate, } = {}) {
|
|
58
|
+
constructor(dreamsOrSerializers, controllerClass, action, { requestBody, headers, many, paginate, cursorPaginate, scrollPaginate, query, responses, serializerKey, status, tags, security, pathParams, description, summary, omitDefaultHeaders, omitDefaultResponses, defaultResponse, validate, disableFastJson, } = {}) {
|
|
58
59
|
this.dreamsOrSerializers = dreamsOrSerializers;
|
|
59
60
|
this.controllerClass = controllerClass;
|
|
60
61
|
this.action = action;
|
|
@@ -83,6 +84,7 @@ export default class OpenapiEndpointRenderer {
|
|
|
83
84
|
: omitDefaultResponses;
|
|
84
85
|
this.defaultResponse = defaultResponse;
|
|
85
86
|
this.validate = validate;
|
|
87
|
+
this.disableFastJson = disableFastJson ?? false;
|
|
86
88
|
}
|
|
87
89
|
/**
|
|
88
90
|
* @internal
|
|
@@ -111,12 +111,7 @@ export default class PsychicApp {
|
|
|
111
111
|
*/
|
|
112
112
|
buildOpenapiCache() {
|
|
113
113
|
Object.keys(this.openapi).forEach(openapiName => {
|
|
114
|
-
|
|
115
|
-
this.cacheOpenapiDoc(openapiName);
|
|
116
|
-
}
|
|
117
|
-
else {
|
|
118
|
-
this.ignoreOpenapiDoc(openapiName);
|
|
119
|
-
}
|
|
114
|
+
this.cacheOpenapiDoc(openapiName);
|
|
120
115
|
});
|
|
121
116
|
}
|
|
122
117
|
/**
|
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
import { closeAllDbConnections } from '@rvoh/dream/db';
|
|
2
1
|
import cors from '@koa/cors';
|
|
2
|
+
import etag from '@koa/etag';
|
|
3
|
+
import { closeAllDbConnections } from '@rvoh/dream/db';
|
|
3
4
|
import Koa from 'koa';
|
|
4
5
|
import koaBodyparser from 'koa-bodyparser';
|
|
5
6
|
import conditional from 'koa-conditional-get';
|
|
6
|
-
import etag from 'koa-etag';
|
|
7
7
|
import logIfDevelopment from '../controller/helpers/logIfDevelopment.js';
|
|
8
8
|
import EnvInternal from '../helpers/EnvInternal.js';
|
|
9
9
|
import PsychicApp from '../psychic-app/index.js';
|
|
@@ -2,6 +2,7 @@ import { Dream, DreamApp } from '@rvoh/dream';
|
|
|
2
2
|
import { GlobalNameNotSet } from '@rvoh/dream/errors';
|
|
3
3
|
import { DreamSerializerBuilder, ObjectSerializerBuilder } from '@rvoh/dream/system';
|
|
4
4
|
import fastJsonStringify from 'fast-json-stringify';
|
|
5
|
+
import { debuglog } from 'node:util';
|
|
5
6
|
import ParamValidationError from '../error/controller/ParamValidationError.js';
|
|
6
7
|
import HttpStatusBadGateway from '../error/http/BadGateway.js';
|
|
7
8
|
import HttpStatusBadRequest from '../error/http/BadRequest.js';
|
|
@@ -607,7 +608,9 @@ export default class PsychicController {
|
|
|
607
608
|
return;
|
|
608
609
|
this.ctx.status = statusCode;
|
|
609
610
|
// Try to use fast-json-stringify if an OpenAPI schema exists for this endpoint
|
|
610
|
-
const stringifyFn = this.
|
|
611
|
+
const stringifyFn = this.currentOpenapiRenderer?.['disableFastJson']
|
|
612
|
+
? undefined
|
|
613
|
+
: this.getFastJsonStringifyFunction(statusCode);
|
|
611
614
|
if (stringifyFn) {
|
|
612
615
|
this.ctx.type = 'application/json';
|
|
613
616
|
this.ctx.body = stringifyFn(data);
|
|
@@ -644,15 +647,23 @@ export default class PsychicController {
|
|
|
644
647
|
const schemaWithComponents = validator.getResponseSchemaWithComponents(statusCode);
|
|
645
648
|
if (!schemaWithComponents)
|
|
646
649
|
continue;
|
|
647
|
-
// Generate cache key
|
|
648
650
|
const cacheKey = `${controllerClass.globalName}#${this.action}|${openapiName}|${statusCode}`;
|
|
649
|
-
// Check cache first
|
|
650
651
|
const cachedStringify = getCachedStringify(cacheKey);
|
|
651
652
|
if (cachedStringify)
|
|
652
653
|
return cachedStringify;
|
|
653
|
-
|
|
654
|
-
|
|
655
|
-
|
|
654
|
+
let stringifyFn;
|
|
655
|
+
if (debuglog('json').enabled) {
|
|
656
|
+
const result = fastJsonStringify(schemaWithComponents, {
|
|
657
|
+
mode: 'debug',
|
|
658
|
+
ajv: { validateFormats: false },
|
|
659
|
+
});
|
|
660
|
+
PsychicApp.log('fast-json-stringify code:', result.code);
|
|
661
|
+
// eslint-disable-next-line @typescript-eslint/no-unsafe-argument, @typescript-eslint/no-explicit-any
|
|
662
|
+
stringifyFn = fastJsonStringify.restore(result);
|
|
663
|
+
}
|
|
664
|
+
else {
|
|
665
|
+
stringifyFn = fastJsonStringify(schemaWithComponents, { ajv: { validateFormats: false } });
|
|
666
|
+
}
|
|
656
667
|
cacheStringify(cacheKey, stringifyFn);
|
|
657
668
|
return stringifyFn;
|
|
658
669
|
}
|
|
@@ -166,8 +166,8 @@ export default class SerializerOpenapiRenderer {
|
|
|
166
166
|
// rendersOnes //
|
|
167
167
|
//////////////////
|
|
168
168
|
case 'rendersOne': {
|
|
169
|
+
const outputAttributeName = this.setCase(attribute.options.as ?? attribute.name);
|
|
169
170
|
try {
|
|
170
|
-
const outputAttributeName = this.setCase(attribute.options.as ?? attribute.name);
|
|
171
171
|
const { associationOpts, referencedSerializersAndOpenapiSchemaBodyShorthand } = associationOpenapi(attribute, DataTypeForOpenapi, alreadyExtractedDescendantSerializers);
|
|
172
172
|
const optional = attribute.options.optional ?? associationOpts.optional;
|
|
173
173
|
newlyReferencedSerializers =
|
|
@@ -193,8 +193,14 @@ export default class SerializerOpenapiRenderer {
|
|
|
193
193
|
return accumulator;
|
|
194
194
|
}
|
|
195
195
|
catch (error) {
|
|
196
|
-
if (error instanceof CallingSerializersThrewError)
|
|
196
|
+
if (error instanceof CallingSerializersThrewError) {
|
|
197
|
+
accumulator[outputAttributeName] = {
|
|
198
|
+
type: 'object',
|
|
199
|
+
additionalProperties: true,
|
|
200
|
+
description: `Serializer ${this.serializer['globalName']} includes a rendersOne "${outputAttributeName}" with an OpenAPI shape that cannot be defined. This will break fast-json-stringify. Define the OpenAPI shape or disableFastJson on the endpoint.`,
|
|
201
|
+
};
|
|
197
202
|
return accumulator;
|
|
203
|
+
}
|
|
198
204
|
if (error instanceof AttemptedToDeriveDescendentSerializersFromNonSerializer)
|
|
199
205
|
throw new ExpectedSerializerForRendersOneOrManyOption('rendersOne', this.globalName, attribute);
|
|
200
206
|
throw error;
|
|
@@ -207,8 +213,8 @@ export default class SerializerOpenapiRenderer {
|
|
|
207
213
|
// rendersManys //
|
|
208
214
|
///////////////////
|
|
209
215
|
case 'rendersMany': {
|
|
216
|
+
const outputAttributeName = this.setCase(attribute.options.as ?? attribute.name);
|
|
210
217
|
try {
|
|
211
|
-
const outputAttributeName = this.setCase(attribute.options.as ?? attribute.name);
|
|
212
218
|
const { referencedSerializersAndOpenapiSchemaBodyShorthand } = associationOpenapi(attribute, DataTypeForOpenapi, alreadyExtractedDescendantSerializers);
|
|
213
219
|
newlyReferencedSerializers =
|
|
214
220
|
referencedSerializersAndOpenapiSchemaBodyShorthand.referencedSerializers;
|
|
@@ -219,8 +225,14 @@ export default class SerializerOpenapiRenderer {
|
|
|
219
225
|
return accumulator;
|
|
220
226
|
}
|
|
221
227
|
catch (error) {
|
|
222
|
-
if (error instanceof CallingSerializersThrewError)
|
|
228
|
+
if (error instanceof CallingSerializersThrewError) {
|
|
229
|
+
accumulator[outputAttributeName] = {
|
|
230
|
+
type: 'array',
|
|
231
|
+
items: { type: 'object', additionalProperties: true },
|
|
232
|
+
description: `Serializer ${this.serializer['globalName']} includes a rendersMany "${outputAttributeName}" with an OpenAPI shape that cannot be defined. This will break fast-json-stringify. Define the OpenAPI shape or disableFastJson on the endpoint.`,
|
|
233
|
+
};
|
|
223
234
|
return accumulator;
|
|
235
|
+
}
|
|
224
236
|
if (error instanceof AttemptedToDeriveDescendentSerializersFromNonSerializer)
|
|
225
237
|
throw new ExpectedSerializerForRendersOneOrManyOption('rendersMany', this.globalName, attribute);
|
|
226
238
|
throw error;
|
|
@@ -40,6 +40,7 @@ export default class OpenapiEndpointRenderer {
|
|
|
40
40
|
omitDefaultResponses;
|
|
41
41
|
defaultResponse;
|
|
42
42
|
validate = undefined;
|
|
43
|
+
disableFastJson = false;
|
|
43
44
|
/**
|
|
44
45
|
* instantiates a new OpenapiEndpointRenderer.
|
|
45
46
|
* This class is used by the `@Openapi` decorator
|
|
@@ -54,7 +55,7 @@ export default class OpenapiEndpointRenderer {
|
|
|
54
55
|
* const json = JSON.encode(openapiJsonContents, null, 2)
|
|
55
56
|
* ```
|
|
56
57
|
*/
|
|
57
|
-
constructor(dreamsOrSerializers, controllerClass, action, { requestBody, headers, many, paginate, cursorPaginate, scrollPaginate, query, responses, serializerKey, status, tags, security, pathParams, description, summary, omitDefaultHeaders, omitDefaultResponses, defaultResponse, validate, } = {}) {
|
|
58
|
+
constructor(dreamsOrSerializers, controllerClass, action, { requestBody, headers, many, paginate, cursorPaginate, scrollPaginate, query, responses, serializerKey, status, tags, security, pathParams, description, summary, omitDefaultHeaders, omitDefaultResponses, defaultResponse, validate, disableFastJson, } = {}) {
|
|
58
59
|
this.dreamsOrSerializers = dreamsOrSerializers;
|
|
59
60
|
this.controllerClass = controllerClass;
|
|
60
61
|
this.action = action;
|
|
@@ -83,6 +84,7 @@ export default class OpenapiEndpointRenderer {
|
|
|
83
84
|
: omitDefaultResponses;
|
|
84
85
|
this.defaultResponse = defaultResponse;
|
|
85
86
|
this.validate = validate;
|
|
87
|
+
this.disableFastJson = disableFastJson ?? false;
|
|
86
88
|
}
|
|
87
89
|
/**
|
|
88
90
|
* @internal
|
|
@@ -111,12 +111,7 @@ export default class PsychicApp {
|
|
|
111
111
|
*/
|
|
112
112
|
buildOpenapiCache() {
|
|
113
113
|
Object.keys(this.openapi).forEach(openapiName => {
|
|
114
|
-
|
|
115
|
-
this.cacheOpenapiDoc(openapiName);
|
|
116
|
-
}
|
|
117
|
-
else {
|
|
118
|
-
this.ignoreOpenapiDoc(openapiName);
|
|
119
|
-
}
|
|
114
|
+
this.cacheOpenapiDoc(openapiName);
|
|
120
115
|
});
|
|
121
116
|
}
|
|
122
117
|
/**
|
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
import { closeAllDbConnections } from '@rvoh/dream/db';
|
|
2
1
|
import cors from '@koa/cors';
|
|
2
|
+
import etag from '@koa/etag';
|
|
3
|
+
import { closeAllDbConnections } from '@rvoh/dream/db';
|
|
3
4
|
import Koa from 'koa';
|
|
4
5
|
import koaBodyparser from 'koa-bodyparser';
|
|
5
6
|
import conditional from 'koa-conditional-get';
|
|
6
|
-
import etag from 'koa-etag';
|
|
7
7
|
import logIfDevelopment from '../controller/helpers/logIfDevelopment.js';
|
|
8
8
|
import EnvInternal from '../helpers/EnvInternal.js';
|
|
9
9
|
import PsychicApp from '../psychic-app/index.js';
|
|
@@ -46,6 +46,7 @@ export default class OpenapiEndpointRenderer<DreamsOrSerializersOrViewModels ext
|
|
|
46
46
|
private omitDefaultResponses;
|
|
47
47
|
private defaultResponse;
|
|
48
48
|
private validate;
|
|
49
|
+
private disableFastJson;
|
|
49
50
|
/**
|
|
50
51
|
* instantiates a new OpenapiEndpointRenderer.
|
|
51
52
|
* This class is used by the `@Openapi` decorator
|
|
@@ -60,7 +61,7 @@ export default class OpenapiEndpointRenderer<DreamsOrSerializersOrViewModels ext
|
|
|
60
61
|
* const json = JSON.encode(openapiJsonContents, null, 2)
|
|
61
62
|
* ```
|
|
62
63
|
*/
|
|
63
|
-
constructor(dreamsOrSerializers: DreamsOrSerializersOrViewModels | null, controllerClass: typeof PsychicController, action: string, { requestBody, headers, many, paginate, cursorPaginate, scrollPaginate, query, responses, serializerKey, status, tags, security, pathParams, description, summary, omitDefaultHeaders, omitDefaultResponses, defaultResponse, validate, }?: OpenapiEndpointRendererOpts<DreamsOrSerializersOrViewModels, ForOption>);
|
|
64
|
+
constructor(dreamsOrSerializers: DreamsOrSerializersOrViewModels | null, controllerClass: typeof PsychicController, action: string, { requestBody, headers, many, paginate, cursorPaginate, scrollPaginate, query, responses, serializerKey, status, tags, security, pathParams, description, summary, omitDefaultHeaders, omitDefaultResponses, defaultResponse, validate, disableFastJson, }?: OpenapiEndpointRendererOpts<DreamsOrSerializersOrViewModels, ForOption>);
|
|
64
65
|
/**
|
|
65
66
|
* @internal
|
|
66
67
|
*
|
|
@@ -611,6 +612,11 @@ export interface OpenapiEndpointRendererOpts<I extends DreamSerializable | Dream
|
|
|
611
612
|
* ```
|
|
612
613
|
*/
|
|
613
614
|
validate?: OpenapiValidateOption | undefined;
|
|
615
|
+
/**
|
|
616
|
+
* The OpenAPI response body automatically enables fast-json-stringify.
|
|
617
|
+
* If you want to render via JSON.stringify instead, set `disableFastJson` to `true`.
|
|
618
|
+
*/
|
|
619
|
+
disableFastJson?: boolean;
|
|
614
620
|
}
|
|
615
621
|
export type OpenapiValidateOption = {
|
|
616
622
|
/**
|
package/package.json
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
"type": "module",
|
|
3
3
|
"name": "@rvoh/psychic",
|
|
4
4
|
"description": "Typescript web framework",
|
|
5
|
-
"version": "3.0.0-alpha.
|
|
5
|
+
"version": "3.0.0-alpha.3",
|
|
6
6
|
"author": "RVOHealth",
|
|
7
7
|
"repository": {
|
|
8
8
|
"type": "git",
|
|
@@ -66,6 +66,7 @@
|
|
|
66
66
|
"prepack": "pnpm build"
|
|
67
67
|
},
|
|
68
68
|
"dependencies": {
|
|
69
|
+
"@koa/etag": "^5.0.2",
|
|
69
70
|
"ajv": "^8.17.1",
|
|
70
71
|
"ajv-formats": "^3.0.1",
|
|
71
72
|
"commander": "^12.1.0",
|
|
@@ -84,7 +85,6 @@
|
|
|
84
85
|
"koa": "^2.15.3",
|
|
85
86
|
"koa-bodyparser": "^4.4.1",
|
|
86
87
|
"koa-conditional-get": "^3.0.0",
|
|
87
|
-
"koa-etag": "^5.0.0",
|
|
88
88
|
"openapi-typescript": "^7.8.0"
|
|
89
89
|
},
|
|
90
90
|
"devDependencies": {
|
|
@@ -94,7 +94,7 @@
|
|
|
94
94
|
"@rvoh/dream": "^2.3.1",
|
|
95
95
|
"@rvoh/dream-spec-helpers": "^2.1.1",
|
|
96
96
|
"@rvoh/psychic-spec-helpers": "^3.0.0-alpha.1",
|
|
97
|
-
"@types/koa": "^
|
|
97
|
+
"@types/koa": "^3.0.1",
|
|
98
98
|
"@types/koa-bodyparser": "^4.3.12",
|
|
99
99
|
"@types/koa-conditional-get": "^2.0.3",
|
|
100
100
|
"@types/koa-etag": "^3.0.3",
|
|
@@ -110,10 +110,9 @@
|
|
|
110
110
|
"@typescript/analyze-trace": "^0.10.1",
|
|
111
111
|
"eslint": "^9.39.1",
|
|
112
112
|
"jsdom": "^26.1.0",
|
|
113
|
-
"koa": "^
|
|
113
|
+
"koa": "^3.1.1",
|
|
114
114
|
"koa-bodyparser": "^4.4.1",
|
|
115
115
|
"koa-conditional-get": "^3.0.0",
|
|
116
|
-
"koa-etag": "^4.0.0",
|
|
117
116
|
"koa-passport": "^6.0.0",
|
|
118
117
|
"koa-session": "^7.0.2",
|
|
119
118
|
"kysely": "^0.28.5",
|