bunsane 0.1.2 → 0.1.4
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/TODO.md +1 -1
- package/bun.lock +156 -150
- package/core/App.ts +188 -31
- package/core/ArcheType.ts +1044 -26
- package/core/ComponentRegistry.ts +172 -29
- package/core/Components.ts +102 -24
- package/core/Decorators.ts +0 -1
- package/core/Entity.ts +55 -7
- package/core/EntityInterface.ts +4 -0
- package/core/EntityManager.ts +4 -4
- package/core/Query.ts +169 -3
- package/core/RequestLoaders.ts +101 -12
- package/core/SchedulerManager.ts +3 -4
- package/core/metadata/definitions/ArcheType.ts +9 -0
- package/core/metadata/definitions/Component.ts +16 -0
- package/core/metadata/definitions/gqlObject.ts +10 -0
- package/core/metadata/getMetadataStorage.ts +14 -0
- package/core/metadata/index.ts +17 -0
- package/core/metadata/metadata-storage.ts +81 -0
- package/database/DatabaseHelper.ts +22 -20
- package/database/index.ts +6 -1
- package/database/sqlHelpers.ts +0 -2
- package/gql/ArchetypeOperations.ts +281 -0
- package/gql/Generator.ts +252 -62
- package/gql/helpers.ts +5 -5
- package/gql/index.ts +19 -17
- package/gql/types.ts +58 -11
- package/index.ts +93 -82
- package/package.json +39 -37
- package/plugins/index.ts +13 -0
- package/scheduler/index.ts +87 -0
- package/service/Service.ts +4 -0
- package/service/ServiceRegistry.ts +5 -1
- package/service/index.ts +1 -1
- package/swagger/decorators.ts +65 -0
- package/swagger/generator.ts +100 -0
- package/swagger/index.ts +2 -0
- package/tests/bench/insert.bench.ts +1 -0
- package/tests/bench/relations.bench.ts +1 -0
- package/tests/bench/sorting.bench.ts +1 -0
- package/tests/component-hooks-simple.test.ts +117 -0
- package/tests/component-hooks.test.ts +83 -31
- package/tests/component.test.ts +1 -0
- package/tests/hooks.test.ts +1 -0
- package/tests/query.test.ts +46 -4
- package/tests/relations.test.ts +1 -0
- package/types/app.types.ts +0 -0
- package/upload/index.ts +0 -2
- package/core/processors/ImageProcessor.ts +0 -423
package/index.ts
CHANGED
|
@@ -1,90 +1,101 @@
|
|
|
1
|
-
import App from "./core/App";
|
|
2
|
-
import ServiceRegistry from "./service/ServiceRegistry";
|
|
3
|
-
import BaseService from "./service/Service";
|
|
4
|
-
import { Component, CompData, BaseComponent } from "./core/Components";
|
|
5
|
-
import { Entity } from "./core/Entity";
|
|
6
|
-
import
|
|
7
|
-
import
|
|
8
|
-
import
|
|
9
|
-
import {
|
|
10
|
-
import {
|
|
11
|
-
import {
|
|
12
|
-
import {
|
|
13
|
-
import
|
|
14
|
-
//
|
|
15
|
-
import
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
1
|
+
// import App from "./core/App";
|
|
2
|
+
// import ServiceRegistry from "./service/ServiceRegistry";
|
|
3
|
+
// import BaseService from "./service/Service";
|
|
4
|
+
// import { Component, CompData, BaseComponent } from "./core/Components";
|
|
5
|
+
// import { Entity } from "./core/Entity";
|
|
6
|
+
// import type { IEntity } from "./core/EntityInterface";
|
|
7
|
+
// import BaseArcheType, { ArcheType} from "./core/ArcheType";
|
|
8
|
+
// import Query from "./core/Query";
|
|
9
|
+
// import {logger} from "./core/Logger";
|
|
10
|
+
// import { handleGraphQLError, responseError } from "./core/ErrorHandler";
|
|
11
|
+
// import { type Plugin } from "graphql-yoga";
|
|
12
|
+
// import { BatchLoader } from "./core/BatchLoader";
|
|
13
|
+
// import { createRequestContextPlugin } from "./core/RequestContext";
|
|
14
|
+
// import type { RequestLoaders } from "./core/RequestLoaders";
|
|
15
|
+
// import BasePlugin from "./plugins";
|
|
16
|
+
// // Hook system exports
|
|
17
|
+
// import EntityHookManager from "./core/EntityHookManager";
|
|
18
|
+
// import {
|
|
19
|
+
// EntityHook,
|
|
20
|
+
// ComponentHook,
|
|
21
|
+
// LifecycleHook,
|
|
22
|
+
// ComponentTargetHook,
|
|
23
|
+
// registerDecoratedHooks
|
|
24
|
+
// } from "./core/decorators/EntityHooks";
|
|
25
|
+
// import type {
|
|
26
|
+
// EntityHookCallback,
|
|
27
|
+
// ComponentHookCallback,
|
|
28
|
+
// LifecycleHookCallback,
|
|
29
|
+
// HookOptions,
|
|
30
|
+
// ComponentTargetConfig
|
|
31
|
+
// } from "./core/EntityHookManager";
|
|
32
|
+
// import type {
|
|
33
|
+
// EntityLifecycleEvent,
|
|
34
|
+
// EntityCreatedEvent,
|
|
35
|
+
// EntityUpdatedEvent,
|
|
36
|
+
// EntityDeletedEvent,
|
|
37
|
+
// ComponentLifecycleEvent,
|
|
38
|
+
// ComponentAddedEvent,
|
|
39
|
+
// ComponentUpdatedEvent,
|
|
40
|
+
// ComponentRemovedEvent
|
|
41
|
+
// } from "./core/events/EntityLifecycleEvents";
|
|
42
|
+
// import { ScheduledTask } from "./core/decorators/ScheduledTask";
|
|
43
|
+
// import { ScheduleInterval } from "./types/scheduler.types";
|
|
44
|
+
// // Swagger exports
|
|
45
|
+
// import { ApiDocs, ApiTags } from "./swagger";
|
|
42
46
|
|
|
43
|
-
export {
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
47
|
+
// export {
|
|
48
|
+
// App,
|
|
49
|
+
// BaseArcheType,
|
|
50
|
+
// ArcheType,
|
|
51
|
+
// ServiceRegistry,
|
|
52
|
+
// BaseService,
|
|
53
|
+
// BaseComponent,
|
|
54
|
+
// Component,
|
|
55
|
+
// CompData,
|
|
56
|
+
// Entity,
|
|
57
|
+
// type IEntity,
|
|
58
|
+
// BatchLoader,
|
|
53
59
|
|
|
54
|
-
|
|
60
|
+
// Query,
|
|
55
61
|
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
62
|
+
// // Scheduler exports
|
|
63
|
+
// ScheduleInterval,
|
|
64
|
+
// ScheduledTask,
|
|
59
65
|
|
|
60
|
-
|
|
66
|
+
// // Swagger exports
|
|
67
|
+
// ApiDocs,
|
|
68
|
+
// ApiTags,
|
|
61
69
|
|
|
62
|
-
|
|
70
|
+
// logger,
|
|
63
71
|
|
|
64
|
-
|
|
65
|
-
|
|
72
|
+
// BasePlugin,
|
|
73
|
+
// type Plugin,
|
|
66
74
|
|
|
67
|
-
|
|
68
|
-
|
|
75
|
+
// responseError,
|
|
76
|
+
// handleGraphQLError,
|
|
69
77
|
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
78
|
+
// createRequestContextPlugin,
|
|
79
|
+
// type RequestLoaders,
|
|
80
|
+
|
|
81
|
+
// // Hook system exports
|
|
82
|
+
// EntityHookManager,
|
|
83
|
+
// EntityHook,
|
|
84
|
+
// ComponentHook,
|
|
85
|
+
// LifecycleHook,
|
|
86
|
+
// ComponentTargetHook,
|
|
87
|
+
// registerDecoratedHooks,
|
|
88
|
+
// type EntityHookCallback,
|
|
89
|
+
// type ComponentHookCallback,
|
|
90
|
+
// type LifecycleHookCallback,
|
|
91
|
+
// type HookOptions,
|
|
92
|
+
// type ComponentTargetConfig,
|
|
93
|
+
// type EntityLifecycleEvent,
|
|
94
|
+
// type EntityCreatedEvent,
|
|
95
|
+
// type EntityUpdatedEvent,
|
|
96
|
+
// type EntityDeletedEvent,
|
|
97
|
+
// type ComponentLifecycleEvent,
|
|
98
|
+
// type ComponentAddedEvent,
|
|
99
|
+
// type ComponentUpdatedEvent,
|
|
100
|
+
// type ComponentRemovedEvent
|
|
101
|
+
// };
|
package/package.json
CHANGED
|
@@ -1,37 +1,39 @@
|
|
|
1
|
-
{
|
|
2
|
-
"name": "bunsane",
|
|
3
|
-
"version": "0.1.
|
|
4
|
-
"author": {
|
|
5
|
-
"name": "yaaruu"
|
|
6
|
-
},
|
|
7
|
-
"keywords": [
|
|
8
|
-
"bun",
|
|
9
|
-
"framework",
|
|
10
|
-
"entity-component-system",
|
|
11
|
-
"ecs",
|
|
12
|
-
"graphql",
|
|
13
|
-
"typescript"
|
|
14
|
-
],
|
|
15
|
-
"module": "index.ts",
|
|
16
|
-
"type": "module",
|
|
17
|
-
"devDependencies": {
|
|
18
|
-
"@types/bun": "latest"
|
|
19
|
-
},
|
|
20
|
-
"peerDependencies": {
|
|
21
|
-
"typescript": "^5"
|
|
22
|
-
},
|
|
23
|
-
"dependencies": {
|
|
24
|
-
"
|
|
25
|
-
"
|
|
26
|
-
"
|
|
27
|
-
"
|
|
28
|
-
"
|
|
29
|
-
"
|
|
30
|
-
"
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
}
|
|
1
|
+
{
|
|
2
|
+
"name": "bunsane",
|
|
3
|
+
"version": "0.1.4",
|
|
4
|
+
"author": {
|
|
5
|
+
"name": "yaaruu"
|
|
6
|
+
},
|
|
7
|
+
"keywords": [
|
|
8
|
+
"bun",
|
|
9
|
+
"framework",
|
|
10
|
+
"entity-component-system",
|
|
11
|
+
"ecs",
|
|
12
|
+
"graphql",
|
|
13
|
+
"typescript"
|
|
14
|
+
],
|
|
15
|
+
"module": "index.ts",
|
|
16
|
+
"type": "module",
|
|
17
|
+
"devDependencies": {
|
|
18
|
+
"@types/bun": "latest"
|
|
19
|
+
},
|
|
20
|
+
"peerDependencies": {
|
|
21
|
+
"typescript": "^5"
|
|
22
|
+
},
|
|
23
|
+
"dependencies": {
|
|
24
|
+
"@gqloom/core": "^0.12.0",
|
|
25
|
+
"@gqloom/zod": "^0.12.2",
|
|
26
|
+
"dataloader": "2.2.2",
|
|
27
|
+
"graphql": "16.11.0",
|
|
28
|
+
"graphql-yoga": "5.15.1",
|
|
29
|
+
"pino": "9.9.0",
|
|
30
|
+
"pino-pretty": "13.1.1",
|
|
31
|
+
"reflect-metadata": "0.2.2",
|
|
32
|
+
"zod": "4.1.5"
|
|
33
|
+
},
|
|
34
|
+
"repository": {
|
|
35
|
+
"type": "git",
|
|
36
|
+
"url": "https://github.com/yaaruu/bunsane.git"
|
|
37
|
+
},
|
|
38
|
+
"license": "MIT"
|
|
39
|
+
}
|
package/plugins/index.ts
ADDED
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import type App from "core/App";
|
|
2
|
+
import type { ApplicationPhase } from "core/ApplicationLifecycle";
|
|
3
|
+
|
|
4
|
+
abstract class BasePlugin {
|
|
5
|
+
name!: string;
|
|
6
|
+
version!: string;
|
|
7
|
+
|
|
8
|
+
abstract init?(app: App): Promise<void> | void;
|
|
9
|
+
onPhaseChange?(phase: ApplicationPhase, app: App): Promise<void> | void;
|
|
10
|
+
onComponentRegistered?(componentName: string, componentCtor: new () => any, app: App): void;
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
export default BasePlugin;
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
import { ScheduleInterval } from "../types/scheduler.types";
|
|
2
|
+
import type { ScheduledTaskOptions } from "../types/scheduler.types";
|
|
3
|
+
import { SchedulerManager } from "core/SchedulerManager";
|
|
4
|
+
import { logger } from "core/Logger";
|
|
5
|
+
import type { ComponentTargetConfig } from "core/EntityHookManager";
|
|
6
|
+
const loggerInstance = logger.child({ scope: "ScheduledTaskDecorator" });
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* Decorator for registering scheduled tasks
|
|
10
|
+
* @param options Task configuration options including interval and component target
|
|
11
|
+
*/
|
|
12
|
+
export function ScheduledTask(
|
|
13
|
+
options: ScheduledTaskOptions & {
|
|
14
|
+
interval: ScheduleInterval;
|
|
15
|
+
componentTarget?: ComponentTargetConfig
|
|
16
|
+
}
|
|
17
|
+
) {
|
|
18
|
+
return function (target: any, propertyKey: string, descriptor: PropertyDescriptor) {
|
|
19
|
+
const originalMethod = descriptor.value;
|
|
20
|
+
|
|
21
|
+
// Generate task ID if not provided
|
|
22
|
+
const taskId = options.id || `${target.constructor.name}.${propertyKey}`;
|
|
23
|
+
|
|
24
|
+
// Store task info for later registration
|
|
25
|
+
if (!target.constructor.__scheduledTasks) {
|
|
26
|
+
target.constructor.__scheduledTasks = [];
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
const taskInfo = {
|
|
30
|
+
id: taskId,
|
|
31
|
+
name: options.name || `${target.constructor.name}.${propertyKey}`,
|
|
32
|
+
componentTarget: options.componentTarget, // Legacy support
|
|
33
|
+
interval: options.interval,
|
|
34
|
+
options: {
|
|
35
|
+
runOnStart: options.runOnStart ?? false,
|
|
36
|
+
timeout: options.timeout ?? 30000,
|
|
37
|
+
enableLogging: options.enableLogging ?? true,
|
|
38
|
+
...options
|
|
39
|
+
},
|
|
40
|
+
service: null, // Will be set when service is instantiated
|
|
41
|
+
methodName: propertyKey,
|
|
42
|
+
nextExecution: new Date(),
|
|
43
|
+
executionCount: 0,
|
|
44
|
+
isRunning: false,
|
|
45
|
+
enabled: true
|
|
46
|
+
};
|
|
47
|
+
|
|
48
|
+
target.constructor.__scheduledTasks.push(taskInfo);
|
|
49
|
+
|
|
50
|
+
// Return the original descriptor to maintain method functionality
|
|
51
|
+
return descriptor;
|
|
52
|
+
};
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
/**
|
|
56
|
+
* Function to manually register decorated tasks for a service instance
|
|
57
|
+
* This is useful when services are instantiated outside the normal decorator flow
|
|
58
|
+
*/
|
|
59
|
+
export function registerScheduledTasks(service: any): void {
|
|
60
|
+
const constructor = service.constructor;
|
|
61
|
+
|
|
62
|
+
if (!constructor.__scheduledTasks) {
|
|
63
|
+
return;
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
const scheduler = SchedulerManager.getInstance();
|
|
67
|
+
|
|
68
|
+
for (const task of constructor.__scheduledTasks) {
|
|
69
|
+
const taskWithService = {
|
|
70
|
+
...task,
|
|
71
|
+
service: service
|
|
72
|
+
};
|
|
73
|
+
|
|
74
|
+
try {
|
|
75
|
+
scheduler.registerTask(taskWithService);
|
|
76
|
+
if (loggerInstance.isLevelEnabled('info')) {
|
|
77
|
+
loggerInstance.info(`Manually registered scheduled task: ${task.name} (${task.id})`);
|
|
78
|
+
}
|
|
79
|
+
} catch (error) {
|
|
80
|
+
loggerInstance.error(`Failed to manually register scheduled task ${task.name}: ${error instanceof Error ? error.message : String(error)}`);
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
export {
|
|
86
|
+
ScheduleInterval
|
|
87
|
+
}
|
package/service/Service.ts
CHANGED
|
@@ -19,7 +19,10 @@ class ServiceRegistry {
|
|
|
19
19
|
switch(event.detail) {
|
|
20
20
|
case ApplicationPhase.SYSTEM_REGISTERING: {
|
|
21
21
|
const servicesArray = Array.from(this.services.values());
|
|
22
|
-
|
|
22
|
+
// Disable auto-generated archetype operations to avoid conflicts with manual operations
|
|
23
|
+
const { schema } = generateGraphQLSchema(servicesArray, {
|
|
24
|
+
enableArchetypeOperations: false
|
|
25
|
+
});
|
|
23
26
|
this.schema = schema;
|
|
24
27
|
ApplicationLifecycle.setPhase(ApplicationPhase.SYSTEM_READY);
|
|
25
28
|
break;
|
|
@@ -41,6 +44,7 @@ class ServiceRegistry {
|
|
|
41
44
|
if(!this.services.has(service.constructor.name)) {
|
|
42
45
|
this.services.set(service.constructor.name, service);
|
|
43
46
|
}
|
|
47
|
+
return service;
|
|
44
48
|
}
|
|
45
49
|
|
|
46
50
|
public getServices(): BaseService[] {
|
package/service/index.ts
CHANGED
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
import type { HTTPMethod } from "../rest";
|
|
2
|
+
|
|
3
|
+
export interface OpenAPIOperation {
|
|
4
|
+
summary?: string;
|
|
5
|
+
description?: string;
|
|
6
|
+
tags?: string[];
|
|
7
|
+
parameters?: OpenAPIParameter[];
|
|
8
|
+
requestBody?: OpenAPIRequestBody;
|
|
9
|
+
responses?: Record<string, OpenAPIResponse>;
|
|
10
|
+
security?: any[];
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
export interface OpenAPIParameter {
|
|
14
|
+
name: string;
|
|
15
|
+
in: 'query' | 'header' | 'path' | 'cookie';
|
|
16
|
+
description?: string;
|
|
17
|
+
required?: boolean;
|
|
18
|
+
schema: any;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
export interface OpenAPIRequestBody {
|
|
22
|
+
description?: string;
|
|
23
|
+
required?: boolean;
|
|
24
|
+
content: Record<string, { schema: any }>;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
export interface OpenAPIResponse {
|
|
28
|
+
description: string;
|
|
29
|
+
content?: Record<string, { schema: any }>;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
export interface SwaggerEndpointMetadata {
|
|
33
|
+
method: HTTPMethod;
|
|
34
|
+
path: string;
|
|
35
|
+
operation: OpenAPIOperation;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
/**
|
|
39
|
+
* Annotations for OpenAPI/Swagger documentation
|
|
40
|
+
* - @ApiOperation: Describes an API operation (endpoint)
|
|
41
|
+
* - @ApiTags: Assigns tags to group operations in the documentation
|
|
42
|
+
*
|
|
43
|
+
*/
|
|
44
|
+
|
|
45
|
+
export function ApiDocs(operation: OpenAPIOperation) {
|
|
46
|
+
return function (target: any, propertyKey: string, descriptor: PropertyDescriptor) {
|
|
47
|
+
// Store the operation on the function itself
|
|
48
|
+
(descriptor.value as any).swaggerOperation = operation;
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
export function ApiTags(...tags: string[]) {
|
|
53
|
+
return function (target: any, propertyKey?: string) {
|
|
54
|
+
if (propertyKey) {
|
|
55
|
+
// Method decorator
|
|
56
|
+
if (!target.constructor.swaggerMethodTags) {
|
|
57
|
+
target.constructor.swaggerMethodTags = {};
|
|
58
|
+
}
|
|
59
|
+
target.constructor.swaggerMethodTags[propertyKey] = tags;
|
|
60
|
+
} else {
|
|
61
|
+
// Class decorator
|
|
62
|
+
target.swaggerClassTags = tags;
|
|
63
|
+
}
|
|
64
|
+
};
|
|
65
|
+
}
|
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
import type { SwaggerEndpointMetadata } from "./decorators";
|
|
2
|
+
import {logger as MainLogger} from "core/Logger";
|
|
3
|
+
const logger = MainLogger.child({ scope: "OpenAPISpecGenerator" });
|
|
4
|
+
export interface OpenAPISpec {
|
|
5
|
+
openapi: string;
|
|
6
|
+
info: {
|
|
7
|
+
title: string;
|
|
8
|
+
version: string;
|
|
9
|
+
description?: string;
|
|
10
|
+
};
|
|
11
|
+
servers?: Array<{
|
|
12
|
+
url: string;
|
|
13
|
+
description?: string;
|
|
14
|
+
}>;
|
|
15
|
+
paths: Record<string, Record<string, any>>;
|
|
16
|
+
components?: {
|
|
17
|
+
schemas?: Record<string, any>;
|
|
18
|
+
securitySchemes?: Record<string, any>;
|
|
19
|
+
};
|
|
20
|
+
tags?: Array<{
|
|
21
|
+
name: string;
|
|
22
|
+
description?: string;
|
|
23
|
+
}>;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
export class OpenAPISpecGenerator {
|
|
27
|
+
private spec: OpenAPISpec;
|
|
28
|
+
|
|
29
|
+
constructor(title: string = "API Documentation", version: string = "1.0.0") {
|
|
30
|
+
this.spec = {
|
|
31
|
+
openapi: "3.0.0",
|
|
32
|
+
info: {
|
|
33
|
+
title,
|
|
34
|
+
version
|
|
35
|
+
},
|
|
36
|
+
paths: {},
|
|
37
|
+
components: {
|
|
38
|
+
securitySchemes: {
|
|
39
|
+
BearerAuth: {
|
|
40
|
+
type: "http",
|
|
41
|
+
scheme: "bearer",
|
|
42
|
+
bearerFormat: "JWT"
|
|
43
|
+
}
|
|
44
|
+
},
|
|
45
|
+
}
|
|
46
|
+
};
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
addEndpoint(metadata: SwaggerEndpointMetadata) {
|
|
50
|
+
const { method, path, operation } = metadata;
|
|
51
|
+
logger.trace(`Adding endpoint to OpenAPI spec: [${method}] ${path}`);
|
|
52
|
+
if (!this.spec.paths[path]) {
|
|
53
|
+
this.spec.paths[path] = {};
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
this.spec.paths[path][method.toLowerCase()] = {
|
|
57
|
+
...operation,
|
|
58
|
+
responses: operation.responses || {
|
|
59
|
+
"200": {
|
|
60
|
+
description: "Success"
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
};
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
addServer(url: string, description?: string) {
|
|
67
|
+
if (!this.spec.servers) {
|
|
68
|
+
this.spec.servers = [];
|
|
69
|
+
}
|
|
70
|
+
this.spec.servers.push({ url, description });
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
addSecurityScheme(name: string, scheme: any) {
|
|
74
|
+
if (!this.spec.components) {
|
|
75
|
+
this.spec.components = {};
|
|
76
|
+
}
|
|
77
|
+
if (!this.spec.components.securitySchemes) {
|
|
78
|
+
this.spec.components.securitySchemes = {};
|
|
79
|
+
}
|
|
80
|
+
this.spec.components.securitySchemes[name] = scheme;
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
addSchema(name: string, schema: any) {
|
|
84
|
+
if (!this.spec.components) {
|
|
85
|
+
this.spec.components = {};
|
|
86
|
+
}
|
|
87
|
+
if (!this.spec.components.schemas) {
|
|
88
|
+
this.spec.components.schemas = {};
|
|
89
|
+
}
|
|
90
|
+
this.spec.components.schemas[name] = schema;
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
generate(): OpenAPISpec {
|
|
94
|
+
return this.spec;
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
toJSON(): string {
|
|
98
|
+
return JSON.stringify(this.spec, null, 2);
|
|
99
|
+
}
|
|
100
|
+
}
|
package/swagger/index.ts
ADDED