@extk/expressive 0.8.0 → 0.9.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.
- package/README.md +456 -453
- package/dist/index.d.mts +52 -44
- package/dist/index.d.ts +52 -44
- package/dist/index.js +43 -22
- package/dist/index.mjs +43 -22
- package/package.json +3 -3
package/dist/index.d.mts
CHANGED
|
@@ -4,6 +4,7 @@ import * as express_serve_static_core from 'express-serve-static-core';
|
|
|
4
4
|
import { RouteParameters } from 'express-serve-static-core';
|
|
5
5
|
import { HelmetOptions } from 'helmet';
|
|
6
6
|
import morgan from 'morgan';
|
|
7
|
+
import { SwaggerUiOptions, SwaggerOptions } from 'swagger-ui-express';
|
|
7
8
|
|
|
8
9
|
type ExpressRoute = string;
|
|
9
10
|
type ExpressLocalsObj = Record<string, any>;
|
|
@@ -187,14 +188,59 @@ type SwaggerConfig = {
|
|
|
187
188
|
security?: AuthMethod[];
|
|
188
189
|
};
|
|
189
190
|
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
191
|
+
declare class SwaggerBuilder {
|
|
192
|
+
private swaggerDoc;
|
|
193
|
+
constructor(swaggerDoc: SwaggerConfig);
|
|
194
|
+
withInfo(info: SwaggerConfig['info']): this;
|
|
195
|
+
withServers(servers: Servers): this;
|
|
196
|
+
withSecuritySchemes(schemes: Record<string, SecurityScheme>): this;
|
|
197
|
+
withSchemas(schemas: Record<string, Schema>): this;
|
|
198
|
+
withDefaultSecurity(globalAuthMethods: AuthMethod[]): this;
|
|
199
|
+
}
|
|
200
|
+
declare function singleFileSchema(field?: string, required?: boolean): Content;
|
|
201
|
+
declare function formDataSchema(schema: Schema): Content;
|
|
202
|
+
declare function jsonSchema(schema: Schema): Content;
|
|
203
|
+
declare function jsonSchemaRef(name: string): Content;
|
|
204
|
+
declare function param(inP: Param['in'], id: string, schema: Schema, required?: boolean, description?: string, name?: string): Param;
|
|
205
|
+
declare function pathParam(id: string, schema: Schema, required?: boolean, description?: string, name?: string): Param;
|
|
206
|
+
declare function queryParam(id: string, schema: Schema, required?: boolean, description?: string, name?: string): Param;
|
|
207
|
+
declare function headerParam(id: string, schema: Schema, required?: boolean, description?: string, name?: string): Param;
|
|
208
|
+
declare const SWG: {
|
|
209
|
+
param: typeof param;
|
|
210
|
+
pathParam: typeof pathParam;
|
|
211
|
+
queryParam: typeof queryParam;
|
|
212
|
+
headerParam: typeof headerParam;
|
|
213
|
+
formDataSchema: typeof formDataSchema;
|
|
214
|
+
jsonSchema: typeof jsonSchema;
|
|
215
|
+
jsonSchemaRef: typeof jsonSchemaRef;
|
|
216
|
+
singleFileSchema: typeof singleFileSchema;
|
|
217
|
+
security: (name: string) => AuthMethod;
|
|
218
|
+
securitySchemes: {
|
|
219
|
+
readonly BasicAuth: () => SecurityScheme;
|
|
220
|
+
readonly BearerAuth: () => SecurityScheme;
|
|
221
|
+
readonly ApiKeyAuth: (headerName: string) => SecurityScheme;
|
|
222
|
+
readonly OpenID: (openIdConnectUrl: string) => SecurityScheme;
|
|
223
|
+
readonly OAuth2: (authorizationUrl: string, tokenUrl: string, scopes: Record<string, string>) => SecurityScheme;
|
|
224
|
+
};
|
|
225
|
+
};
|
|
226
|
+
|
|
227
|
+
type SwaggerRef = {
|
|
228
|
+
doc: SwaggerConfig | null;
|
|
229
|
+
};
|
|
230
|
+
type ExpressiveSwaggerOptions = {
|
|
231
|
+
path: ExpressRoute;
|
|
232
|
+
uiOpts?: SwaggerUiOptions;
|
|
233
|
+
options?: SwaggerOptions;
|
|
234
|
+
customCss?: string;
|
|
235
|
+
customfavIcon?: string;
|
|
236
|
+
swaggerUrl?: string;
|
|
237
|
+
customSiteTitle?: string;
|
|
193
238
|
};
|
|
194
239
|
declare class ServerBuilder {
|
|
195
240
|
private app;
|
|
196
241
|
private container;
|
|
197
|
-
|
|
242
|
+
private swaggerRef;
|
|
243
|
+
constructor(app: express__default.Express, container: Container, swaggerRef: SwaggerRef);
|
|
198
244
|
build(): express__default.Express;
|
|
199
245
|
withHelmet(options?: Readonly<HelmetOptions>): this;
|
|
200
246
|
withQs(): this;
|
|
@@ -205,7 +251,7 @@ declare class ServerBuilder {
|
|
|
205
251
|
* Helper function for fluent design
|
|
206
252
|
*/
|
|
207
253
|
with(fn: (app: express__default.Express, container: Container) => void): this;
|
|
208
|
-
withSwagger(
|
|
254
|
+
withSwagger(configure: (builder: SwaggerBuilder) => void, opts: ExpressiveSwaggerOptions, ...handlers: ExpressHandler[]): this;
|
|
209
255
|
}
|
|
210
256
|
|
|
211
257
|
declare class ApiError extends Error {
|
|
@@ -252,43 +298,6 @@ declare class UserUnauthorizedError extends ApiError {
|
|
|
252
298
|
constructor(message?: string);
|
|
253
299
|
}
|
|
254
300
|
|
|
255
|
-
declare class SwaggerBuilder {
|
|
256
|
-
private swaggerDoc;
|
|
257
|
-
constructor(swaggerDoc: SwaggerConfig);
|
|
258
|
-
withInfo(info: SwaggerConfig['info']): this;
|
|
259
|
-
withServers(servers: Servers): this;
|
|
260
|
-
withSecuritySchemes(schemes: Record<string, SecurityScheme>): this;
|
|
261
|
-
withSchemas(schemas: Record<string, Schema>): this;
|
|
262
|
-
withDefaultSecurity(globalAuthMethods: AuthMethod[]): this;
|
|
263
|
-
build(): SwaggerConfig;
|
|
264
|
-
}
|
|
265
|
-
declare function singleFileSchema(field?: string, required?: boolean): Content;
|
|
266
|
-
declare function formDataSchema(schema: Schema): Content;
|
|
267
|
-
declare function jsonSchema(schema: Schema): Content;
|
|
268
|
-
declare function jsonSchemaRef(name: string): Content;
|
|
269
|
-
declare function param(inP: Param['in'], id: string, schema: Schema, required?: boolean, description?: string, name?: string): Param;
|
|
270
|
-
declare function pathParam(id: string, schema: Schema, required?: boolean, description?: string, name?: string): Param;
|
|
271
|
-
declare function queryParam(id: string, schema: Schema, required?: boolean, description?: string, name?: string): Param;
|
|
272
|
-
declare function headerParam(id: string, schema: Schema, required?: boolean, description?: string, name?: string): Param;
|
|
273
|
-
declare const SWG: {
|
|
274
|
-
param: typeof param;
|
|
275
|
-
pathParam: typeof pathParam;
|
|
276
|
-
queryParam: typeof queryParam;
|
|
277
|
-
headerParam: typeof headerParam;
|
|
278
|
-
formDataSchema: typeof formDataSchema;
|
|
279
|
-
jsonSchema: typeof jsonSchema;
|
|
280
|
-
jsonSchemaRef: typeof jsonSchemaRef;
|
|
281
|
-
singleFileSchema: typeof singleFileSchema;
|
|
282
|
-
security: (name: string) => AuthMethod;
|
|
283
|
-
securitySchemes: {
|
|
284
|
-
readonly BasicAuth: () => SecurityScheme;
|
|
285
|
-
readonly BearerAuth: () => SecurityScheme;
|
|
286
|
-
readonly ApiKeyAuth: (headerName: string) => SecurityScheme;
|
|
287
|
-
readonly OpenID: (openIdConnectUrl: string) => SecurityScheme;
|
|
288
|
-
readonly OAuth2: (authorizationUrl: string, tokenUrl: string, scopes: Record<string, string>) => SecurityScheme;
|
|
289
|
-
};
|
|
290
|
-
};
|
|
291
|
-
|
|
292
301
|
declare function parsePositiveInteger<T>(v: T, defaultValue: number, max?: number): number;
|
|
293
302
|
declare function parseIdOrFail(v: unknown): number;
|
|
294
303
|
declare function slugify(text: string): string;
|
|
@@ -317,7 +326,6 @@ declare class ApiResponse<T = undefined> {
|
|
|
317
326
|
}
|
|
318
327
|
|
|
319
328
|
declare function bootstrap(container: Container): {
|
|
320
|
-
swaggerBuilder: () => SwaggerBuilder;
|
|
321
329
|
silently: (fn: () => Promise<void> | void) => Promise<void>;
|
|
322
330
|
getGlobalNotFoundMiddleware: (content?: string) => (_req: express.Request, res: express.Response, _next: express.NextFunction) => void;
|
|
323
331
|
getApiNotFoundMiddleware: () => (req: express.Request, res: express.Response, _next: express.NextFunction) => void;
|
|
@@ -348,4 +356,4 @@ declare function bootstrap(container: Container): {
|
|
|
348
356
|
};
|
|
349
357
|
};
|
|
350
358
|
|
|
351
|
-
export { type AlertHandler, ApiError, ApiErrorResponse, ApiResponse, type AuthMethod, BadRequestError, type Container, type Content, type ContentType, DuplicateError, type Env, type ExpressHandler, type ExpressLocalsObj, type ExpressRoute, FileTooBigError, ForbiddenError, type HttpMethod, InternalError, InvalidCredentialsError, InvalidFileTypeError, type Logger, NotFoundError, type OtherString, type OtherUnknown, type Pagination, type PaginationQuery, type Param, type PathItem, SWG, type Schema, SchemaValidationError, type SecurityScheme, type Servers, type SwaggerConfig, TokenExpiredError, TooManyRequestsError, UserUnauthorizedError, bootstrap, getEnvVar, getTmpDir, getTmpPath, isDev, isProd, parseDefaultPagination, parseIdOrFail, parsePositiveInteger, slugify };
|
|
359
|
+
export { type AlertHandler, ApiError, ApiErrorResponse, ApiResponse, type AuthMethod, BadRequestError, type Container, type Content, type ContentType, DuplicateError, type Env, type ExpressHandler, type ExpressLocalsObj, type ExpressRoute, FileTooBigError, ForbiddenError, type HttpMethod, InternalError, InvalidCredentialsError, InvalidFileTypeError, type Logger, NotFoundError, type OtherString, type OtherUnknown, type Pagination, type PaginationQuery, type Param, type PathItem, SWG, type Schema, SchemaValidationError, type SecurityScheme, type Servers, SwaggerBuilder, type SwaggerConfig, TokenExpiredError, TooManyRequestsError, UserUnauthorizedError, bootstrap, getEnvVar, getTmpDir, getTmpPath, isDev, isProd, parseDefaultPagination, parseIdOrFail, parsePositiveInteger, slugify };
|
package/dist/index.d.ts
CHANGED
|
@@ -4,6 +4,7 @@ import * as express_serve_static_core from 'express-serve-static-core';
|
|
|
4
4
|
import { RouteParameters } from 'express-serve-static-core';
|
|
5
5
|
import { HelmetOptions } from 'helmet';
|
|
6
6
|
import morgan from 'morgan';
|
|
7
|
+
import { SwaggerUiOptions, SwaggerOptions } from 'swagger-ui-express';
|
|
7
8
|
|
|
8
9
|
type ExpressRoute = string;
|
|
9
10
|
type ExpressLocalsObj = Record<string, any>;
|
|
@@ -187,14 +188,59 @@ type SwaggerConfig = {
|
|
|
187
188
|
security?: AuthMethod[];
|
|
188
189
|
};
|
|
189
190
|
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
191
|
+
declare class SwaggerBuilder {
|
|
192
|
+
private swaggerDoc;
|
|
193
|
+
constructor(swaggerDoc: SwaggerConfig);
|
|
194
|
+
withInfo(info: SwaggerConfig['info']): this;
|
|
195
|
+
withServers(servers: Servers): this;
|
|
196
|
+
withSecuritySchemes(schemes: Record<string, SecurityScheme>): this;
|
|
197
|
+
withSchemas(schemas: Record<string, Schema>): this;
|
|
198
|
+
withDefaultSecurity(globalAuthMethods: AuthMethod[]): this;
|
|
199
|
+
}
|
|
200
|
+
declare function singleFileSchema(field?: string, required?: boolean): Content;
|
|
201
|
+
declare function formDataSchema(schema: Schema): Content;
|
|
202
|
+
declare function jsonSchema(schema: Schema): Content;
|
|
203
|
+
declare function jsonSchemaRef(name: string): Content;
|
|
204
|
+
declare function param(inP: Param['in'], id: string, schema: Schema, required?: boolean, description?: string, name?: string): Param;
|
|
205
|
+
declare function pathParam(id: string, schema: Schema, required?: boolean, description?: string, name?: string): Param;
|
|
206
|
+
declare function queryParam(id: string, schema: Schema, required?: boolean, description?: string, name?: string): Param;
|
|
207
|
+
declare function headerParam(id: string, schema: Schema, required?: boolean, description?: string, name?: string): Param;
|
|
208
|
+
declare const SWG: {
|
|
209
|
+
param: typeof param;
|
|
210
|
+
pathParam: typeof pathParam;
|
|
211
|
+
queryParam: typeof queryParam;
|
|
212
|
+
headerParam: typeof headerParam;
|
|
213
|
+
formDataSchema: typeof formDataSchema;
|
|
214
|
+
jsonSchema: typeof jsonSchema;
|
|
215
|
+
jsonSchemaRef: typeof jsonSchemaRef;
|
|
216
|
+
singleFileSchema: typeof singleFileSchema;
|
|
217
|
+
security: (name: string) => AuthMethod;
|
|
218
|
+
securitySchemes: {
|
|
219
|
+
readonly BasicAuth: () => SecurityScheme;
|
|
220
|
+
readonly BearerAuth: () => SecurityScheme;
|
|
221
|
+
readonly ApiKeyAuth: (headerName: string) => SecurityScheme;
|
|
222
|
+
readonly OpenID: (openIdConnectUrl: string) => SecurityScheme;
|
|
223
|
+
readonly OAuth2: (authorizationUrl: string, tokenUrl: string, scopes: Record<string, string>) => SecurityScheme;
|
|
224
|
+
};
|
|
225
|
+
};
|
|
226
|
+
|
|
227
|
+
type SwaggerRef = {
|
|
228
|
+
doc: SwaggerConfig | null;
|
|
229
|
+
};
|
|
230
|
+
type ExpressiveSwaggerOptions = {
|
|
231
|
+
path: ExpressRoute;
|
|
232
|
+
uiOpts?: SwaggerUiOptions;
|
|
233
|
+
options?: SwaggerOptions;
|
|
234
|
+
customCss?: string;
|
|
235
|
+
customfavIcon?: string;
|
|
236
|
+
swaggerUrl?: string;
|
|
237
|
+
customSiteTitle?: string;
|
|
193
238
|
};
|
|
194
239
|
declare class ServerBuilder {
|
|
195
240
|
private app;
|
|
196
241
|
private container;
|
|
197
|
-
|
|
242
|
+
private swaggerRef;
|
|
243
|
+
constructor(app: express__default.Express, container: Container, swaggerRef: SwaggerRef);
|
|
198
244
|
build(): express__default.Express;
|
|
199
245
|
withHelmet(options?: Readonly<HelmetOptions>): this;
|
|
200
246
|
withQs(): this;
|
|
@@ -205,7 +251,7 @@ declare class ServerBuilder {
|
|
|
205
251
|
* Helper function for fluent design
|
|
206
252
|
*/
|
|
207
253
|
with(fn: (app: express__default.Express, container: Container) => void): this;
|
|
208
|
-
withSwagger(
|
|
254
|
+
withSwagger(configure: (builder: SwaggerBuilder) => void, opts: ExpressiveSwaggerOptions, ...handlers: ExpressHandler[]): this;
|
|
209
255
|
}
|
|
210
256
|
|
|
211
257
|
declare class ApiError extends Error {
|
|
@@ -252,43 +298,6 @@ declare class UserUnauthorizedError extends ApiError {
|
|
|
252
298
|
constructor(message?: string);
|
|
253
299
|
}
|
|
254
300
|
|
|
255
|
-
declare class SwaggerBuilder {
|
|
256
|
-
private swaggerDoc;
|
|
257
|
-
constructor(swaggerDoc: SwaggerConfig);
|
|
258
|
-
withInfo(info: SwaggerConfig['info']): this;
|
|
259
|
-
withServers(servers: Servers): this;
|
|
260
|
-
withSecuritySchemes(schemes: Record<string, SecurityScheme>): this;
|
|
261
|
-
withSchemas(schemas: Record<string, Schema>): this;
|
|
262
|
-
withDefaultSecurity(globalAuthMethods: AuthMethod[]): this;
|
|
263
|
-
build(): SwaggerConfig;
|
|
264
|
-
}
|
|
265
|
-
declare function singleFileSchema(field?: string, required?: boolean): Content;
|
|
266
|
-
declare function formDataSchema(schema: Schema): Content;
|
|
267
|
-
declare function jsonSchema(schema: Schema): Content;
|
|
268
|
-
declare function jsonSchemaRef(name: string): Content;
|
|
269
|
-
declare function param(inP: Param['in'], id: string, schema: Schema, required?: boolean, description?: string, name?: string): Param;
|
|
270
|
-
declare function pathParam(id: string, schema: Schema, required?: boolean, description?: string, name?: string): Param;
|
|
271
|
-
declare function queryParam(id: string, schema: Schema, required?: boolean, description?: string, name?: string): Param;
|
|
272
|
-
declare function headerParam(id: string, schema: Schema, required?: boolean, description?: string, name?: string): Param;
|
|
273
|
-
declare const SWG: {
|
|
274
|
-
param: typeof param;
|
|
275
|
-
pathParam: typeof pathParam;
|
|
276
|
-
queryParam: typeof queryParam;
|
|
277
|
-
headerParam: typeof headerParam;
|
|
278
|
-
formDataSchema: typeof formDataSchema;
|
|
279
|
-
jsonSchema: typeof jsonSchema;
|
|
280
|
-
jsonSchemaRef: typeof jsonSchemaRef;
|
|
281
|
-
singleFileSchema: typeof singleFileSchema;
|
|
282
|
-
security: (name: string) => AuthMethod;
|
|
283
|
-
securitySchemes: {
|
|
284
|
-
readonly BasicAuth: () => SecurityScheme;
|
|
285
|
-
readonly BearerAuth: () => SecurityScheme;
|
|
286
|
-
readonly ApiKeyAuth: (headerName: string) => SecurityScheme;
|
|
287
|
-
readonly OpenID: (openIdConnectUrl: string) => SecurityScheme;
|
|
288
|
-
readonly OAuth2: (authorizationUrl: string, tokenUrl: string, scopes: Record<string, string>) => SecurityScheme;
|
|
289
|
-
};
|
|
290
|
-
};
|
|
291
|
-
|
|
292
301
|
declare function parsePositiveInteger<T>(v: T, defaultValue: number, max?: number): number;
|
|
293
302
|
declare function parseIdOrFail(v: unknown): number;
|
|
294
303
|
declare function slugify(text: string): string;
|
|
@@ -317,7 +326,6 @@ declare class ApiResponse<T = undefined> {
|
|
|
317
326
|
}
|
|
318
327
|
|
|
319
328
|
declare function bootstrap(container: Container): {
|
|
320
|
-
swaggerBuilder: () => SwaggerBuilder;
|
|
321
329
|
silently: (fn: () => Promise<void> | void) => Promise<void>;
|
|
322
330
|
getGlobalNotFoundMiddleware: (content?: string) => (_req: express.Request, res: express.Response, _next: express.NextFunction) => void;
|
|
323
331
|
getApiNotFoundMiddleware: () => (req: express.Request, res: express.Response, _next: express.NextFunction) => void;
|
|
@@ -348,4 +356,4 @@ declare function bootstrap(container: Container): {
|
|
|
348
356
|
};
|
|
349
357
|
};
|
|
350
358
|
|
|
351
|
-
export { type AlertHandler, ApiError, ApiErrorResponse, ApiResponse, type AuthMethod, BadRequestError, type Container, type Content, type ContentType, DuplicateError, type Env, type ExpressHandler, type ExpressLocalsObj, type ExpressRoute, FileTooBigError, ForbiddenError, type HttpMethod, InternalError, InvalidCredentialsError, InvalidFileTypeError, type Logger, NotFoundError, type OtherString, type OtherUnknown, type Pagination, type PaginationQuery, type Param, type PathItem, SWG, type Schema, SchemaValidationError, type SecurityScheme, type Servers, type SwaggerConfig, TokenExpiredError, TooManyRequestsError, UserUnauthorizedError, bootstrap, getEnvVar, getTmpDir, getTmpPath, isDev, isProd, parseDefaultPagination, parseIdOrFail, parsePositiveInteger, slugify };
|
|
359
|
+
export { type AlertHandler, ApiError, ApiErrorResponse, ApiResponse, type AuthMethod, BadRequestError, type Container, type Content, type ContentType, DuplicateError, type Env, type ExpressHandler, type ExpressLocalsObj, type ExpressRoute, FileTooBigError, ForbiddenError, type HttpMethod, InternalError, InvalidCredentialsError, InvalidFileTypeError, type Logger, NotFoundError, type OtherString, type OtherUnknown, type Pagination, type PaginationQuery, type Param, type PathItem, SWG, type Schema, SchemaValidationError, type SecurityScheme, type Servers, SwaggerBuilder, type SwaggerConfig, TokenExpiredError, TooManyRequestsError, UserUnauthorizedError, bootstrap, getEnvVar, getTmpDir, getTmpPath, isDev, isProd, parseDefaultPagination, parseIdOrFail, parsePositiveInteger, slugify };
|
package/dist/index.js
CHANGED
|
@@ -91,9 +91,6 @@ var SwaggerBuilder = class {
|
|
|
91
91
|
this.swaggerDoc.security = globalAuthMethods;
|
|
92
92
|
return this;
|
|
93
93
|
}
|
|
94
|
-
build() {
|
|
95
|
-
return this.swaggerDoc;
|
|
96
|
-
}
|
|
97
94
|
};
|
|
98
95
|
var securitySchemes = {
|
|
99
96
|
BasicAuth: () => ({
|
|
@@ -211,11 +208,13 @@ var SWG = {
|
|
|
211
208
|
|
|
212
209
|
// src/expressive.ts
|
|
213
210
|
var ServerBuilder = class {
|
|
214
|
-
constructor(app, container) {
|
|
211
|
+
constructor(app, container, swaggerRef) {
|
|
215
212
|
this.app = app;
|
|
216
213
|
this.container = container;
|
|
214
|
+
this.swaggerRef = swaggerRef;
|
|
217
215
|
}
|
|
218
216
|
build() {
|
|
217
|
+
this.swaggerRef.doc = null;
|
|
219
218
|
return this.app;
|
|
220
219
|
}
|
|
221
220
|
withHelmet(options) {
|
|
@@ -233,6 +232,7 @@ var ServerBuilder = class {
|
|
|
233
232
|
withMorgan(format, options) {
|
|
234
233
|
this.app.use((0, import_morgan.default)(
|
|
235
234
|
format ?? ":req[x-real-ip] :method :url :status :res[content-length] - :response-time ms",
|
|
235
|
+
// TODO: ip or x-real-ip; also, default to json?
|
|
236
236
|
options ?? { stream: { write: (message) => {
|
|
237
237
|
this.container.logger.info(message.trim());
|
|
238
238
|
} } }
|
|
@@ -250,18 +250,45 @@ var ServerBuilder = class {
|
|
|
250
250
|
fn(this.app, this.container);
|
|
251
251
|
return this;
|
|
252
252
|
}
|
|
253
|
-
withSwagger(
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
253
|
+
withSwagger(configure, opts, ...handlers) {
|
|
254
|
+
const config = this.swaggerRef.doc;
|
|
255
|
+
if (!config) throw new Error("withSwagger must be called before build()");
|
|
256
|
+
configure(new SwaggerBuilder(config));
|
|
257
|
+
const { path: path2, uiOpts, options, customCss, customfavIcon, swaggerUrl, customSiteTitle } = opts;
|
|
258
|
+
const uiOptsWithDefaults = {
|
|
259
|
+
customSiteTitle: config.info?.title,
|
|
260
|
+
...uiOpts
|
|
261
|
+
};
|
|
262
|
+
this.app.use(
|
|
263
|
+
path2,
|
|
264
|
+
...handlers,
|
|
265
|
+
import_swagger_ui_express.default.serve,
|
|
266
|
+
import_swagger_ui_express.default.setup(
|
|
267
|
+
config,
|
|
268
|
+
uiOptsWithDefaults,
|
|
269
|
+
options,
|
|
270
|
+
customCss,
|
|
271
|
+
customfavIcon,
|
|
272
|
+
swaggerUrl,
|
|
273
|
+
customSiteTitle
|
|
274
|
+
)
|
|
275
|
+
);
|
|
257
276
|
return this;
|
|
258
277
|
}
|
|
259
278
|
};
|
|
260
|
-
function buildExpressive(container
|
|
279
|
+
function buildExpressive(container) {
|
|
280
|
+
const swaggerRef = {
|
|
281
|
+
doc: {
|
|
282
|
+
openapi: "3.1.0",
|
|
283
|
+
info: {},
|
|
284
|
+
paths: {},
|
|
285
|
+
components: {}
|
|
286
|
+
}
|
|
287
|
+
};
|
|
261
288
|
return {
|
|
262
289
|
expressiveServer(configs) {
|
|
263
290
|
const app = configs?.app ?? (0, import_express.default)();
|
|
264
|
-
return new ServerBuilder(app, container);
|
|
291
|
+
return new ServerBuilder(app, container, swaggerRef);
|
|
265
292
|
},
|
|
266
293
|
expressiveRouter(configs) {
|
|
267
294
|
const router = import_express.default.Router();
|
|
@@ -304,10 +331,12 @@ function buildExpressive(container, swaggerDoc) {
|
|
|
304
331
|
} else {
|
|
305
332
|
pathItem.parameters.push(...tryParsePathParameters(route));
|
|
306
333
|
}
|
|
307
|
-
if (
|
|
308
|
-
|
|
334
|
+
if (swaggerRef.doc) {
|
|
335
|
+
if (!swaggerRef.doc.paths[route]) {
|
|
336
|
+
swaggerRef.doc.paths[route] = {};
|
|
337
|
+
}
|
|
338
|
+
swaggerRef.doc.paths[route][context.method] = pathItem;
|
|
309
339
|
}
|
|
310
|
-
swaggerDoc.paths[route][context.method] = pathItem;
|
|
311
340
|
return router;
|
|
312
341
|
}
|
|
313
342
|
};
|
|
@@ -545,17 +574,9 @@ var ApiResponse = class {
|
|
|
545
574
|
|
|
546
575
|
// src/index.ts
|
|
547
576
|
function bootstrap(container) {
|
|
548
|
-
const swaggerDoc = {
|
|
549
|
-
openapi: "3.1.0",
|
|
550
|
-
// TODO
|
|
551
|
-
info: {},
|
|
552
|
-
paths: {},
|
|
553
|
-
components: {}
|
|
554
|
-
};
|
|
555
577
|
return {
|
|
556
|
-
...buildExpressive(container
|
|
578
|
+
...buildExpressive(container),
|
|
557
579
|
...buildMiddleware(container),
|
|
558
|
-
swaggerBuilder: () => new SwaggerBuilder(swaggerDoc),
|
|
559
580
|
silently: async (fn) => {
|
|
560
581
|
try {
|
|
561
582
|
await fn();
|
package/dist/index.mjs
CHANGED
|
@@ -30,9 +30,6 @@ var SwaggerBuilder = class {
|
|
|
30
30
|
this.swaggerDoc.security = globalAuthMethods;
|
|
31
31
|
return this;
|
|
32
32
|
}
|
|
33
|
-
build() {
|
|
34
|
-
return this.swaggerDoc;
|
|
35
|
-
}
|
|
36
33
|
};
|
|
37
34
|
var securitySchemes = {
|
|
38
35
|
BasicAuth: () => ({
|
|
@@ -150,11 +147,13 @@ var SWG = {
|
|
|
150
147
|
|
|
151
148
|
// src/expressive.ts
|
|
152
149
|
var ServerBuilder = class {
|
|
153
|
-
constructor(app, container) {
|
|
150
|
+
constructor(app, container, swaggerRef) {
|
|
154
151
|
this.app = app;
|
|
155
152
|
this.container = container;
|
|
153
|
+
this.swaggerRef = swaggerRef;
|
|
156
154
|
}
|
|
157
155
|
build() {
|
|
156
|
+
this.swaggerRef.doc = null;
|
|
158
157
|
return this.app;
|
|
159
158
|
}
|
|
160
159
|
withHelmet(options) {
|
|
@@ -172,6 +171,7 @@ var ServerBuilder = class {
|
|
|
172
171
|
withMorgan(format, options) {
|
|
173
172
|
this.app.use(morgan(
|
|
174
173
|
format ?? ":req[x-real-ip] :method :url :status :res[content-length] - :response-time ms",
|
|
174
|
+
// TODO: ip or x-real-ip; also, default to json?
|
|
175
175
|
options ?? { stream: { write: (message) => {
|
|
176
176
|
this.container.logger.info(message.trim());
|
|
177
177
|
} } }
|
|
@@ -189,18 +189,45 @@ var ServerBuilder = class {
|
|
|
189
189
|
fn(this.app, this.container);
|
|
190
190
|
return this;
|
|
191
191
|
}
|
|
192
|
-
withSwagger(
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
192
|
+
withSwagger(configure, opts, ...handlers) {
|
|
193
|
+
const config = this.swaggerRef.doc;
|
|
194
|
+
if (!config) throw new Error("withSwagger must be called before build()");
|
|
195
|
+
configure(new SwaggerBuilder(config));
|
|
196
|
+
const { path: path2, uiOpts, options, customCss, customfavIcon, swaggerUrl, customSiteTitle } = opts;
|
|
197
|
+
const uiOptsWithDefaults = {
|
|
198
|
+
customSiteTitle: config.info?.title,
|
|
199
|
+
...uiOpts
|
|
200
|
+
};
|
|
201
|
+
this.app.use(
|
|
202
|
+
path2,
|
|
203
|
+
...handlers,
|
|
204
|
+
swaggerUi.serve,
|
|
205
|
+
swaggerUi.setup(
|
|
206
|
+
config,
|
|
207
|
+
uiOptsWithDefaults,
|
|
208
|
+
options,
|
|
209
|
+
customCss,
|
|
210
|
+
customfavIcon,
|
|
211
|
+
swaggerUrl,
|
|
212
|
+
customSiteTitle
|
|
213
|
+
)
|
|
214
|
+
);
|
|
196
215
|
return this;
|
|
197
216
|
}
|
|
198
217
|
};
|
|
199
|
-
function buildExpressive(container
|
|
218
|
+
function buildExpressive(container) {
|
|
219
|
+
const swaggerRef = {
|
|
220
|
+
doc: {
|
|
221
|
+
openapi: "3.1.0",
|
|
222
|
+
info: {},
|
|
223
|
+
paths: {},
|
|
224
|
+
components: {}
|
|
225
|
+
}
|
|
226
|
+
};
|
|
200
227
|
return {
|
|
201
228
|
expressiveServer(configs) {
|
|
202
229
|
const app = configs?.app ?? express();
|
|
203
|
-
return new ServerBuilder(app, container);
|
|
230
|
+
return new ServerBuilder(app, container, swaggerRef);
|
|
204
231
|
},
|
|
205
232
|
expressiveRouter(configs) {
|
|
206
233
|
const router = express.Router();
|
|
@@ -243,10 +270,12 @@ function buildExpressive(container, swaggerDoc) {
|
|
|
243
270
|
} else {
|
|
244
271
|
pathItem.parameters.push(...tryParsePathParameters(route));
|
|
245
272
|
}
|
|
246
|
-
if (
|
|
247
|
-
|
|
273
|
+
if (swaggerRef.doc) {
|
|
274
|
+
if (!swaggerRef.doc.paths[route]) {
|
|
275
|
+
swaggerRef.doc.paths[route] = {};
|
|
276
|
+
}
|
|
277
|
+
swaggerRef.doc.paths[route][context.method] = pathItem;
|
|
248
278
|
}
|
|
249
|
-
swaggerDoc.paths[route][context.method] = pathItem;
|
|
250
279
|
return router;
|
|
251
280
|
}
|
|
252
281
|
};
|
|
@@ -484,17 +513,9 @@ var ApiResponse = class {
|
|
|
484
513
|
|
|
485
514
|
// src/index.ts
|
|
486
515
|
function bootstrap(container) {
|
|
487
|
-
const swaggerDoc = {
|
|
488
|
-
openapi: "3.1.0",
|
|
489
|
-
// TODO
|
|
490
|
-
info: {},
|
|
491
|
-
paths: {},
|
|
492
|
-
components: {}
|
|
493
|
-
};
|
|
494
516
|
return {
|
|
495
|
-
...buildExpressive(container
|
|
517
|
+
...buildExpressive(container),
|
|
496
518
|
...buildMiddleware(container),
|
|
497
|
-
swaggerBuilder: () => new SwaggerBuilder(swaggerDoc),
|
|
498
519
|
silently: async (fn) => {
|
|
499
520
|
try {
|
|
500
521
|
await fn();
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@extk/expressive",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.9.0",
|
|
4
4
|
"type": "commonjs",
|
|
5
5
|
"publishConfig": {
|
|
6
6
|
"access": "public"
|
|
@@ -25,7 +25,7 @@
|
|
|
25
25
|
"lint": "eslint ./"
|
|
26
26
|
},
|
|
27
27
|
"devDependencies": {
|
|
28
|
-
"@extk/eslint-config": "^0.
|
|
28
|
+
"@extk/eslint-config": "^0.3.0",
|
|
29
29
|
"@extk/tsconfig": "0.1.1",
|
|
30
30
|
"@types/chance": "^1.1.7",
|
|
31
31
|
"@types/express": "^5.0.1",
|
|
@@ -33,7 +33,7 @@
|
|
|
33
33
|
"@types/node": "^20.9.3",
|
|
34
34
|
"@types/swagger-ui-express": "^4.1.8",
|
|
35
35
|
"chance": "^1.1.13",
|
|
36
|
-
"eslint": "^
|
|
36
|
+
"eslint": "^10.0.3",
|
|
37
37
|
"tsup": "^8.5.0",
|
|
38
38
|
"tsx": "^4.20.3",
|
|
39
39
|
"typescript": "^5.9.2"
|