@navios/openapi-fastify 0.7.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 (42) hide show
  1. package/CHANGELOG.md +34 -0
  2. package/LICENSE +8 -0
  3. package/README.md +311 -0
  4. package/dist/src/index.d.mts +6 -0
  5. package/dist/src/index.d.mts.map +1 -0
  6. package/dist/src/openapi-fastify.plugin.d.mts +74 -0
  7. package/dist/src/openapi-fastify.plugin.d.mts.map +1 -0
  8. package/dist/src/schemas/index.d.mts +2 -0
  9. package/dist/src/schemas/index.d.mts.map +1 -0
  10. package/dist/src/schemas/openapi-fastify-options.schema.d.mts +113 -0
  11. package/dist/src/schemas/openapi-fastify-options.schema.d.mts.map +1 -0
  12. package/dist/src/utils/apply-global-prefix.util.d.mts +26 -0
  13. package/dist/src/utils/apply-global-prefix.util.d.mts.map +1 -0
  14. package/dist/src/utils/index.d.mts +2 -0
  15. package/dist/src/utils/index.d.mts.map +1 -0
  16. package/dist/tsconfig.lib.tsbuildinfo +1 -0
  17. package/dist/tsconfig.tsbuildinfo +1 -0
  18. package/dist/tsdown.config.d.mts +3 -0
  19. package/dist/tsdown.config.d.mts.map +1 -0
  20. package/dist/vitest.config.d.mts +3 -0
  21. package/dist/vitest.config.d.mts.map +1 -0
  22. package/lib/index.cjs +233 -0
  23. package/lib/index.cjs.map +1 -0
  24. package/lib/index.d.cts +214 -0
  25. package/lib/index.d.cts.map +1 -0
  26. package/lib/index.d.mts +214 -0
  27. package/lib/index.d.mts.map +1 -0
  28. package/lib/index.mjs +185 -0
  29. package/lib/index.mjs.map +1 -0
  30. package/package.json +48 -0
  31. package/project.json +66 -0
  32. package/src/index.mts +41 -0
  33. package/src/openapi-fastify.plugin.mts +167 -0
  34. package/src/schemas/index.mts +10 -0
  35. package/src/schemas/openapi-fastify-options.schema.mts +129 -0
  36. package/src/utils/apply-global-prefix.util.mts +52 -0
  37. package/src/utils/index.mts +1 -0
  38. package/tsconfig.json +14 -0
  39. package/tsconfig.lib.json +8 -0
  40. package/tsconfig.spec.json +7 -0
  41. package/tsdown.config.mts +35 -0
  42. package/vitest.config.mts +11 -0
@@ -0,0 +1,214 @@
1
+ import { ApiDeprecated, ApiDeprecatedOptions, ApiExclude, ApiOperation, ApiOperationOptions, ApiSecurity, ApiSecurityRequirement, ApiStream, ApiStreamOptions, ApiSummary, ApiTag, ApiTagOptions, OpenApiEndpointMetadata, OpenApiGeneratorOptions, OpenApiGeneratorOptions as OpenApiGeneratorOptions$1 } from "@navios/openapi";
2
+ import { z } from "zod";
3
+ import { NaviosPlugin, PluginContext, PluginDefinition } from "@navios/core";
4
+
5
+ //#region src/schemas/openapi-fastify-options.schema.d.mts
6
+ /**
7
+ * Zod schema for Scalar UI theme options
8
+ */
9
+ declare const scalarThemeSchema: z.ZodEnum<{
10
+ default: "default";
11
+ alternate: "alternate";
12
+ moon: "moon";
13
+ purple: "purple";
14
+ solarized: "solarized";
15
+ bluePlanet: "bluePlanet";
16
+ saturn: "saturn";
17
+ kepler: "kepler";
18
+ mars: "mars";
19
+ deepSpace: "deepSpace";
20
+ laserwave: "laserwave";
21
+ elysiajs: "elysiajs";
22
+ fastify: "fastify";
23
+ none: "none";
24
+ }>;
25
+ /**
26
+ * Zod schema for Scalar UI metadata
27
+ */
28
+ declare const scalarMetaDataSchema: z.ZodOptional<z.ZodObject<{
29
+ title: z.ZodOptional<z.ZodString>;
30
+ description: z.ZodOptional<z.ZodString>;
31
+ ogDescription: z.ZodOptional<z.ZodString>;
32
+ ogTitle: z.ZodOptional<z.ZodString>;
33
+ ogImage: z.ZodOptional<z.ZodString>;
34
+ twitterCard: z.ZodOptional<z.ZodString>;
35
+ }, z.core.$strip>>;
36
+ /**
37
+ * Zod schema for Scalar UI configuration options
38
+ */
39
+ declare const scalarOptionsSchema: z.ZodObject<{
40
+ theme: z.ZodOptional<z.ZodEnum<{
41
+ default: "default";
42
+ alternate: "alternate";
43
+ moon: "moon";
44
+ purple: "purple";
45
+ solarized: "solarized";
46
+ bluePlanet: "bluePlanet";
47
+ saturn: "saturn";
48
+ kepler: "kepler";
49
+ mars: "mars";
50
+ deepSpace: "deepSpace";
51
+ laserwave: "laserwave";
52
+ elysiajs: "elysiajs";
53
+ fastify: "fastify";
54
+ none: "none";
55
+ }>>;
56
+ favicon: z.ZodOptional<z.ZodString>;
57
+ logo: z.ZodOptional<z.ZodString>;
58
+ hideDownloadButton: z.ZodOptional<z.ZodBoolean>;
59
+ hideSearch: z.ZodOptional<z.ZodBoolean>;
60
+ customCss: z.ZodOptional<z.ZodString>;
61
+ metaData: z.ZodOptional<z.ZodObject<{
62
+ title: z.ZodOptional<z.ZodString>;
63
+ description: z.ZodOptional<z.ZodString>;
64
+ ogDescription: z.ZodOptional<z.ZodString>;
65
+ ogTitle: z.ZodOptional<z.ZodString>;
66
+ ogImage: z.ZodOptional<z.ZodString>;
67
+ twitterCard: z.ZodOptional<z.ZodString>;
68
+ }, z.core.$strip>>;
69
+ cdn: z.ZodOptional<z.ZodString>;
70
+ }, z.core.$strip>;
71
+ /**
72
+ * Zod schema for Fastify OpenAPI plugin options
73
+ */
74
+ declare const fastifyOpenApiPluginOptionsSchema: z.ZodObject<{
75
+ jsonPath: z.ZodDefault<z.ZodOptional<z.ZodString>>;
76
+ yamlPath: z.ZodDefault<z.ZodOptional<z.ZodString>>;
77
+ docsPath: z.ZodDefault<z.ZodOptional<z.ZodString>>;
78
+ scalar: z.ZodOptional<z.ZodObject<{
79
+ theme: z.ZodOptional<z.ZodEnum<{
80
+ default: "default";
81
+ alternate: "alternate";
82
+ moon: "moon";
83
+ purple: "purple";
84
+ solarized: "solarized";
85
+ bluePlanet: "bluePlanet";
86
+ saturn: "saturn";
87
+ kepler: "kepler";
88
+ mars: "mars";
89
+ deepSpace: "deepSpace";
90
+ laserwave: "laserwave";
91
+ elysiajs: "elysiajs";
92
+ fastify: "fastify";
93
+ none: "none";
94
+ }>>;
95
+ favicon: z.ZodOptional<z.ZodString>;
96
+ logo: z.ZodOptional<z.ZodString>;
97
+ hideDownloadButton: z.ZodOptional<z.ZodBoolean>;
98
+ hideSearch: z.ZodOptional<z.ZodBoolean>;
99
+ customCss: z.ZodOptional<z.ZodString>;
100
+ metaData: z.ZodOptional<z.ZodObject<{
101
+ title: z.ZodOptional<z.ZodString>;
102
+ description: z.ZodOptional<z.ZodString>;
103
+ ogDescription: z.ZodOptional<z.ZodString>;
104
+ ogTitle: z.ZodOptional<z.ZodString>;
105
+ ogImage: z.ZodOptional<z.ZodString>;
106
+ twitterCard: z.ZodOptional<z.ZodString>;
107
+ }, z.core.$strip>>;
108
+ cdn: z.ZodOptional<z.ZodString>;
109
+ }, z.core.$strip>>;
110
+ disableScalar: z.ZodDefault<z.ZodOptional<z.ZodBoolean>>;
111
+ disableYaml: z.ZodDefault<z.ZodOptional<z.ZodBoolean>>;
112
+ }, z.core.$strip>;
113
+ type ScalarTheme = z.infer<typeof scalarThemeSchema>;
114
+ type ScalarOptions = z.infer<typeof scalarOptionsSchema>;
115
+ type FastifyOpenApiPluginOptionsBase = z.infer<typeof fastifyOpenApiPluginOptionsSchema>;
116
+ //#endregion
117
+ //#region src/openapi-fastify.plugin.d.mts
118
+ /**
119
+ * Combined options for the Fastify OpenAPI plugin.
120
+ * Extends OpenApiGeneratorOptions with Fastify-specific settings.
121
+ */
122
+ interface FastifyOpenApiPluginOptions extends OpenApiGeneratorOptions$1, Partial<FastifyOpenApiPluginOptionsBase> {}
123
+ /**
124
+ * Class-based OpenAPI Fastify plugin that integrates with Navios plugin system.
125
+ *
126
+ * This plugin:
127
+ * - Scans all registered modules for endpoints
128
+ * - Generates an OpenAPI 3.1 document
129
+ * - Serves the document as JSON and optionally YAML
130
+ * - Provides Scalar UI for interactive documentation
131
+ */
132
+ declare class OpenApiFastifyPlugin implements NaviosPlugin<FastifyOpenApiPluginOptions> {
133
+ readonly name = "openapi-fastify";
134
+ register(context: PluginContext, options: FastifyOpenApiPluginOptions): Promise<void>;
135
+ /**
136
+ * Generates the Scalar API Reference HTML document.
137
+ *
138
+ * @param specUrl - URL to the OpenAPI JSON specification
139
+ * @param options - Scalar UI configuration options
140
+ * @returns Complete HTML document string
141
+ */
142
+ private generateScalarHtml;
143
+ }
144
+ /**
145
+ * Creates a plugin definition for the OpenAPI Fastify plugin.
146
+ *
147
+ * @param options - Plugin configuration options
148
+ * @returns Plugin definition to pass to `app.usePlugin()`
149
+ *
150
+ * @example
151
+ * ```typescript
152
+ * import { NaviosFactory } from '@navios/core'
153
+ * import { defineFastifyEnvironment } from '@navios/adapter-fastify'
154
+ * import { defineOpenApiPlugin } from '@navios/openapi-fastify'
155
+ *
156
+ * const app = await NaviosFactory.create(AppModule, {
157
+ * adapter: defineFastifyEnvironment(),
158
+ * })
159
+ *
160
+ * app.usePlugin(defineOpenApiPlugin({
161
+ * info: {
162
+ * title: 'My API',
163
+ * version: '1.0.0',
164
+ * description: 'API documentation',
165
+ * },
166
+ * servers: [
167
+ * { url: 'http://localhost:3000', description: 'Development' },
168
+ * ],
169
+ * securitySchemes: {
170
+ * bearerAuth: {
171
+ * type: 'http',
172
+ * scheme: 'bearer',
173
+ * bearerFormat: 'JWT',
174
+ * },
175
+ * },
176
+ * scalar: {
177
+ * theme: 'purple',
178
+ * },
179
+ * }))
180
+ *
181
+ * await app.listen({ port: 3000 })
182
+ * // API docs available at http://localhost:3000/docs
183
+ * ```
184
+ */
185
+ declare function defineOpenApiPlugin(options: FastifyOpenApiPluginOptions): PluginDefinition<FastifyOpenApiPluginOptions>;
186
+ //#endregion
187
+ //#region src/utils/apply-global-prefix.util.d.mts
188
+ /**
189
+ * OpenAPI document shape (minimal interface for typing)
190
+ */
191
+ interface OpenAPIDocument {
192
+ openapi: string;
193
+ info: {
194
+ title: string;
195
+ version: string;
196
+ };
197
+ paths?: Record<string, unknown>;
198
+ servers?: Array<{
199
+ url: string;
200
+ description?: string;
201
+ }>;
202
+ }
203
+ /**
204
+ * Applies global prefix to OpenAPI servers if needed.
205
+ *
206
+ * @param document - The OpenAPI document to modify
207
+ * @param globalPrefix - The global route prefix (e.g., '/api/v1')
208
+ * @param options - Plugin options that may contain server configuration
209
+ * @returns The document with servers array updated if applicable
210
+ */
211
+ declare function applyGlobalPrefix<T extends OpenAPIDocument>(document: T, globalPrefix: string, options: OpenApiGeneratorOptions$1): T;
212
+ //#endregion
213
+ export { ApiDeprecated, type ApiDeprecatedOptions, ApiExclude, ApiOperation, type ApiOperationOptions, ApiSecurity, type ApiSecurityRequirement, ApiStream, type ApiStreamOptions, ApiSummary, ApiTag, type ApiTagOptions, type FastifyOpenApiPluginOptions, type OpenApiEndpointMetadata, OpenApiFastifyPlugin, type OpenApiGeneratorOptions, type ScalarOptions, type ScalarTheme, applyGlobalPrefix, defineOpenApiPlugin, fastifyOpenApiPluginOptionsSchema, scalarMetaDataSchema, scalarOptionsSchema, scalarThemeSchema };
214
+ //# sourceMappingURL=index.d.mts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.mts","names":[],"sources":["../src/schemas/openapi-fastify-options.schema.mts","../src/openapi-fastify.plugin.mts","../src/utils/apply-global-prefix.util.mts"],"sourcesContent":[],"mappings":";;;;;;;;cAKa,mBAAiB,CAAA,CAAA;EAAjB,OAAA,EAAA,SAAA;EAoBA,SAAA,EAAA,WAAA;;;;;;;;;;;;;;;;;AAcA,cAdA,oBA0DX,EA1D+B,CAAA,CAAA,WA0D/B,CA1D+B,CAAA,CAAA,SA0D/B,CAAA;;;;;;;;;;;cA5CW,qBAAmB,CAAA,CAAA;;;;;;;;;;;;;;;;;;;;EAAA,UAAA,eAAA,aAAA,CAAA;EAAA,SAAA,eAAA,YAAA,CAAA;EAiDnB,QAAA,eAAA,YAAA,CAmCX;;;;;;;;;;;;;cAnCW,mCAAiC,CAAA,CAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAAA,aAAA,cAAA,cAAA,aAAA,CAAA,CAAA;EAAA,WAAA,cAAA,cAAA,aAAA,CAAA,CAAA;AAqC9C,CAAA,eAAY,CAAA;AAEA,KAFA,WAAA,GAAc,CAAA,CAAE,KAEe,CAAA,OAFF,iBAEX,CAAA;KAAlB,aAAA,GAAgB,CAAA,CAAE,aAAa;KAC/B,+BAAA,GAAkC,CAAA,CAAE,aAAa;;;;;AA3H7D;AAoBA;UCCiB,2BAAA,SACP,2BAAyB,QAAQ;;;;;;;;;;cAW9B,oBAAA,YAAgC,aAAa;;EDbzB,QAAA,CAAA,OAAA,ECiBpB,aDjBoB,EAAA,OAAA,ECkBpB,2BDlBoB,CAAA,ECmB5B,ODnB4B,CAAA,IAAA,CAAA;EAAA;;AAcjC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAiDA;;;;;;;;;;;;;;;iBCoEgB,mBAAA,UACL,8BACR,iBAAiB;;;;;;UCzJH,eAAA;EFAJ,OAAA,EAAA,MAAA;EAoBA,IAAA,EAAA;;;;UEdH;YACE;;;;;;;;;;;;AF2BZ;iBEbgB,4BAA4B,2BAChC,kCAED,4BACR"}
package/lib/index.mjs ADDED
@@ -0,0 +1,185 @@
1
+ import { ApiDeprecated, ApiExclude, ApiOperation, ApiSecurity, ApiStream, ApiSummary, ApiTag, OpenApiGeneratorService } from "@navios/openapi";
2
+ import { getHtmlDocument } from "@scalar/core/libs/html-rendering";
3
+ import { stringify } from "yaml";
4
+ import { z } from "zod";
5
+
6
+ //#region src/schemas/openapi-fastify-options.schema.mts
7
+ /**
8
+ * Zod schema for Scalar UI theme options
9
+ */ const scalarThemeSchema = z.enum([
10
+ "default",
11
+ "alternate",
12
+ "moon",
13
+ "purple",
14
+ "solarized",
15
+ "bluePlanet",
16
+ "saturn",
17
+ "kepler",
18
+ "mars",
19
+ "deepSpace",
20
+ "laserwave",
21
+ "elysiajs",
22
+ "fastify",
23
+ "none"
24
+ ]);
25
+ /**
26
+ * Zod schema for Scalar UI metadata
27
+ */ const scalarMetaDataSchema = z.object({
28
+ title: z.string().optional(),
29
+ description: z.string().optional(),
30
+ ogDescription: z.string().optional(),
31
+ ogTitle: z.string().optional(),
32
+ ogImage: z.string().optional(),
33
+ twitterCard: z.string().optional()
34
+ }).optional();
35
+ /**
36
+ * Zod schema for Scalar UI configuration options
37
+ */ const scalarOptionsSchema = z.object({
38
+ theme: scalarThemeSchema.optional(),
39
+ favicon: z.string().optional(),
40
+ logo: z.string().optional(),
41
+ hideDownloadButton: z.boolean().optional(),
42
+ hideSearch: z.boolean().optional(),
43
+ customCss: z.string().optional(),
44
+ metaData: scalarMetaDataSchema,
45
+ cdn: z.string().optional()
46
+ });
47
+ /**
48
+ * Zod schema for Fastify OpenAPI plugin options
49
+ */ const fastifyOpenApiPluginOptionsSchema = z.object({
50
+ jsonPath: z.string().optional().default("/openapi.json"),
51
+ yamlPath: z.string().optional().default("/openapi.yaml"),
52
+ docsPath: z.string().optional().default("/docs"),
53
+ scalar: scalarOptionsSchema.optional(),
54
+ disableScalar: z.boolean().optional().default(false),
55
+ disableYaml: z.boolean().optional().default(true)
56
+ });
57
+
58
+ //#endregion
59
+ //#region src/utils/apply-global-prefix.util.mts
60
+ /**
61
+ * Applies global prefix to OpenAPI servers if needed.
62
+ *
63
+ * @param document - The OpenAPI document to modify
64
+ * @param globalPrefix - The global route prefix (e.g., '/api/v1')
65
+ * @param options - Plugin options that may contain server configuration
66
+ * @returns The document with servers array updated if applicable
67
+ */ function applyGlobalPrefix(document, globalPrefix, options) {
68
+ if (options.servers && options.servers.length > 0) return document;
69
+ if (!globalPrefix) return document;
70
+ return {
71
+ ...document,
72
+ servers: [{
73
+ url: globalPrefix,
74
+ description: "API with global prefix"
75
+ }]
76
+ };
77
+ }
78
+
79
+ //#endregion
80
+ //#region src/openapi-fastify.plugin.mts
81
+ /**
82
+ * Class-based OpenAPI Fastify plugin that integrates with Navios plugin system.
83
+ *
84
+ * This plugin:
85
+ * - Scans all registered modules for endpoints
86
+ * - Generates an OpenAPI 3.1 document
87
+ * - Serves the document as JSON and optionally YAML
88
+ * - Provides Scalar UI for interactive documentation
89
+ */ var OpenApiFastifyPlugin = class {
90
+ name = "openapi-fastify";
91
+ async register(context, options) {
92
+ const fastify = context.server;
93
+ const parsedOptions = fastifyOpenApiPluginOptionsSchema.parse(options);
94
+ const documentWithServers = applyGlobalPrefix((await context.container.get(OpenApiGeneratorService)).generate(context.modules, options), context.globalPrefix, options);
95
+ const jsonPath = parsedOptions.jsonPath;
96
+ fastify.get(jsonPath, async (_request, reply) => {
97
+ return reply.send(documentWithServers);
98
+ });
99
+ if (!parsedOptions.disableYaml) {
100
+ const yamlPath = parsedOptions.yamlPath;
101
+ fastify.get(yamlPath, async (_request, reply) => {
102
+ reply.type("text/yaml");
103
+ return reply.send(stringify(documentWithServers));
104
+ });
105
+ }
106
+ if (!parsedOptions.disableScalar) {
107
+ const docsPath = parsedOptions.docsPath;
108
+ const scalarOptions = options.scalar ?? {};
109
+ const html = this.generateScalarHtml(jsonPath, scalarOptions);
110
+ fastify.get(docsPath, async (_request, reply) => {
111
+ reply.type("text/html");
112
+ return reply.send(html);
113
+ });
114
+ }
115
+ }
116
+ /**
117
+ * Generates the Scalar API Reference HTML document.
118
+ *
119
+ * @param specUrl - URL to the OpenAPI JSON specification
120
+ * @param options - Scalar UI configuration options
121
+ * @returns Complete HTML document string
122
+ */ generateScalarHtml(specUrl, options) {
123
+ return getHtmlDocument({
124
+ url: specUrl,
125
+ theme: options.theme ?? "default",
126
+ favicon: options.favicon,
127
+ customCss: options.customCss,
128
+ hideDownloadButton: options.hideDownloadButton,
129
+ hideSearch: options.hideSearch,
130
+ metaData: options.metaData,
131
+ cdn: options.cdn,
132
+ pageTitle: options.metaData?.title ?? "API Reference"
133
+ });
134
+ }
135
+ };
136
+ /**
137
+ * Creates a plugin definition for the OpenAPI Fastify plugin.
138
+ *
139
+ * @param options - Plugin configuration options
140
+ * @returns Plugin definition to pass to `app.usePlugin()`
141
+ *
142
+ * @example
143
+ * ```typescript
144
+ * import { NaviosFactory } from '@navios/core'
145
+ * import { defineFastifyEnvironment } from '@navios/adapter-fastify'
146
+ * import { defineOpenApiPlugin } from '@navios/openapi-fastify'
147
+ *
148
+ * const app = await NaviosFactory.create(AppModule, {
149
+ * adapter: defineFastifyEnvironment(),
150
+ * })
151
+ *
152
+ * app.usePlugin(defineOpenApiPlugin({
153
+ * info: {
154
+ * title: 'My API',
155
+ * version: '1.0.0',
156
+ * description: 'API documentation',
157
+ * },
158
+ * servers: [
159
+ * { url: 'http://localhost:3000', description: 'Development' },
160
+ * ],
161
+ * securitySchemes: {
162
+ * bearerAuth: {
163
+ * type: 'http',
164
+ * scheme: 'bearer',
165
+ * bearerFormat: 'JWT',
166
+ * },
167
+ * },
168
+ * scalar: {
169
+ * theme: 'purple',
170
+ * },
171
+ * }))
172
+ *
173
+ * await app.listen({ port: 3000 })
174
+ * // API docs available at http://localhost:3000/docs
175
+ * ```
176
+ */ function defineOpenApiPlugin(options) {
177
+ return {
178
+ plugin: new OpenApiFastifyPlugin(),
179
+ options
180
+ };
181
+ }
182
+
183
+ //#endregion
184
+ export { ApiDeprecated, ApiExclude, ApiOperation, ApiSecurity, ApiStream, ApiSummary, ApiTag, OpenApiFastifyPlugin, applyGlobalPrefix, defineOpenApiPlugin, fastifyOpenApiPluginOptionsSchema, scalarMetaDataSchema, scalarOptionsSchema, scalarThemeSchema };
185
+ //# sourceMappingURL=index.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.mjs","names":["z","scalarThemeSchema","enum","scalarMetaDataSchema","object","title","string","optional","description","ogDescription","ogTitle","ogImage","twitterCard","scalarOptionsSchema","theme","favicon","logo","hideDownloadButton","boolean","hideSearch","customCss","metaData","cdn","fastifyOpenApiPluginOptionsSchema","jsonPath","default","yamlPath","docsPath","scalar","disableScalar","disableYaml","applyGlobalPrefix","document","globalPrefix","options","servers","length","url","description","OpenApiGeneratorService","getHtmlDocument","stringify","yamlStringify","fastifyOpenApiPluginOptionsSchema","applyGlobalPrefix","OpenApiFastifyPlugin","name","register","context","options","fastify","server","parsedOptions","parse","generator","container","get","document","generate","modules","documentWithServers","globalPrefix","jsonPath","_request","reply","send","disableYaml","yamlPath","type","disableScalar","docsPath","scalarOptions","scalar","html","generateScalarHtml","specUrl","url","theme","favicon","customCss","hideDownloadButton","hideSearch","metaData","cdn","pageTitle","title","defineOpenApiPlugin","plugin"],"sources":["../src/schemas/openapi-fastify-options.schema.mts","../src/utils/apply-global-prefix.util.mts","../src/openapi-fastify.plugin.mts"],"sourcesContent":["import { z } from 'zod'\n\n/**\n * Zod schema for Scalar UI theme options\n */\nexport const scalarThemeSchema = z.enum([\n 'default',\n 'alternate',\n 'moon',\n 'purple',\n 'solarized',\n 'bluePlanet',\n 'saturn',\n 'kepler',\n 'mars',\n 'deepSpace',\n 'laserwave',\n 'elysiajs',\n 'fastify',\n 'none',\n])\n\n/**\n * Zod schema for Scalar UI metadata\n */\nexport const scalarMetaDataSchema = z\n .object({\n title: z.string().optional(),\n description: z.string().optional(),\n ogDescription: z.string().optional(),\n ogTitle: z.string().optional(),\n ogImage: z.string().optional(),\n twitterCard: z.string().optional(),\n })\n .optional()\n\n/**\n * Zod schema for Scalar UI configuration options\n */\nexport const scalarOptionsSchema = z.object({\n /**\n * Theme for Scalar UI\n * @default 'default'\n */\n theme: scalarThemeSchema.optional(),\n\n /**\n * Custom favicon URL\n */\n favicon: z.string().optional(),\n\n /**\n * Custom logo URL\n */\n logo: z.string().optional(),\n\n /**\n * Hide the \"Download OpenAPI Spec\" button\n * @default false\n */\n hideDownloadButton: z.boolean().optional(),\n\n /**\n * Hide the \"Search\" input\n * @default false\n */\n hideSearch: z.boolean().optional(),\n\n /**\n * Custom CSS to inject\n */\n customCss: z.string().optional(),\n\n /**\n * Meta data for the HTML page\n */\n metaData: scalarMetaDataSchema,\n\n /**\n * CDN URL for Scalar API Reference\n * @default 'https://cdn.jsdelivr.net/npm/@scalar/api-reference'\n */\n cdn: z.string().optional(),\n})\n\n/**\n * Zod schema for Fastify OpenAPI plugin options\n */\nexport const fastifyOpenApiPluginOptionsSchema = z.object({\n /**\n * Path to serve OpenAPI JSON\n * @default '/openapi.json'\n */\n jsonPath: z.string().optional().default('/openapi.json'),\n\n /**\n * Path to serve OpenAPI YAML\n * @default '/openapi.yaml'\n */\n yamlPath: z.string().optional().default('/openapi.yaml'),\n\n /**\n * Path to serve Scalar UI\n * @default '/docs'\n */\n docsPath: z.string().optional().default('/docs'),\n\n /**\n * Scalar UI configuration\n */\n scalar: scalarOptionsSchema.optional(),\n\n /**\n * Disable Scalar UI (only serve JSON/YAML)\n * @default false\n */\n disableScalar: z.boolean().optional().default(false),\n\n /**\n * Disable YAML endpoint\n * @default true\n */\n disableYaml: z.boolean().optional().default(true),\n})\n\nexport type ScalarTheme = z.infer<typeof scalarThemeSchema>\nexport type ScalarMetaData = z.infer<typeof scalarMetaDataSchema>\nexport type ScalarOptions = z.infer<typeof scalarOptionsSchema>\nexport type FastifyOpenApiPluginOptionsBase = z.infer<typeof fastifyOpenApiPluginOptionsSchema>\n","import type { OpenApiGeneratorOptions } from '@navios/openapi'\n\n/**\n * OpenAPI document shape (minimal interface for typing)\n */\nexport interface OpenAPIDocument {\n openapi: string\n info: {\n title: string\n version: string\n }\n paths?: Record<string, unknown>\n servers?: Array<{\n url: string\n description?: string\n }>\n}\n\n/**\n * Applies global prefix to OpenAPI servers if needed.\n *\n * @param document - The OpenAPI document to modify\n * @param globalPrefix - The global route prefix (e.g., '/api/v1')\n * @param options - Plugin options that may contain server configuration\n * @returns The document with servers array updated if applicable\n */\nexport function applyGlobalPrefix<T extends OpenAPIDocument>(\n document: T,\n globalPrefix: string,\n options: OpenApiGeneratorOptions,\n): T {\n // If servers are already defined, don't modify\n if (options.servers && options.servers.length > 0) {\n return document\n }\n\n // If no global prefix, return as-is\n if (!globalPrefix) {\n return document\n }\n\n // Add a default server with the global prefix\n return {\n ...document,\n servers: [\n {\n url: globalPrefix,\n description: 'API with global prefix',\n },\n ],\n }\n}\n","import type {\n NaviosPlugin,\n PluginContext,\n PluginDefinition,\n} from '@navios/core'\nimport type { OpenApiGeneratorOptions } from '@navios/openapi'\nimport type { FastifyInstance } from 'fastify'\n\nimport { OpenApiGeneratorService } from '@navios/openapi'\n\nimport { getHtmlDocument } from '@scalar/core/libs/html-rendering'\nimport { stringify as yamlStringify } from 'yaml'\n\nimport type {\n FastifyOpenApiPluginOptionsBase,\n ScalarOptions,\n ScalarTheme,\n} from './schemas/index.mjs'\n\nimport { fastifyOpenApiPluginOptionsSchema } from './schemas/index.mjs'\nimport { applyGlobalPrefix } from './utils/index.mjs'\n\n/**\n * Combined options for the Fastify OpenAPI plugin.\n * Extends OpenApiGeneratorOptions with Fastify-specific settings.\n */\nexport interface FastifyOpenApiPluginOptions\n extends OpenApiGeneratorOptions, Partial<FastifyOpenApiPluginOptionsBase> {}\n\n/**\n * Class-based OpenAPI Fastify plugin that integrates with Navios plugin system.\n *\n * This plugin:\n * - Scans all registered modules for endpoints\n * - Generates an OpenAPI 3.1 document\n * - Serves the document as JSON and optionally YAML\n * - Provides Scalar UI for interactive documentation\n */\nexport class OpenApiFastifyPlugin implements NaviosPlugin<FastifyOpenApiPluginOptions> {\n readonly name = 'openapi-fastify'\n\n async register(\n context: PluginContext,\n options: FastifyOpenApiPluginOptions,\n ): Promise<void> {\n const fastify = context.server as FastifyInstance\n\n // Parse and validate options with defaults\n const parsedOptions = fastifyOpenApiPluginOptionsSchema.parse(options)\n\n // Get the generator service from the container\n const generator = await context.container.get(OpenApiGeneratorService)\n\n // Generate OpenAPI document from discovered endpoints\n const document = generator.generate(context.modules, options)\n\n // Apply global prefix to servers if not already set\n const documentWithServers = applyGlobalPrefix(\n document,\n context.globalPrefix,\n options,\n )\n\n // Register JSON endpoint\n const jsonPath = parsedOptions.jsonPath\n fastify.get(jsonPath, async (_request, reply) => {\n return reply.send(documentWithServers)\n })\n\n // Register YAML endpoint (disabled by default)\n if (!parsedOptions.disableYaml) {\n const yamlPath = parsedOptions.yamlPath\n fastify.get(yamlPath, async (_request, reply) => {\n reply.type('text/yaml')\n return reply.send(yamlStringify(documentWithServers))\n })\n }\n\n // Register Scalar UI (unless disabled)\n if (!parsedOptions.disableScalar) {\n const docsPath = parsedOptions.docsPath\n const scalarOptions = options.scalar ?? {}\n\n // Generate HTML document using @scalar/core\n const html = this.generateScalarHtml(jsonPath, scalarOptions)\n\n fastify.get(docsPath, async (_request, reply) => {\n reply.type('text/html')\n return reply.send(html)\n })\n }\n }\n\n /**\n * Generates the Scalar API Reference HTML document.\n *\n * @param specUrl - URL to the OpenAPI JSON specification\n * @param options - Scalar UI configuration options\n * @returns Complete HTML document string\n */\n private generateScalarHtml(specUrl: string, options: ScalarOptions): string {\n return getHtmlDocument({\n url: specUrl,\n theme: options.theme ?? 'default',\n favicon: options.favicon,\n customCss: options.customCss,\n hideDownloadButton: options.hideDownloadButton,\n hideSearch: options.hideSearch,\n metaData: options.metaData,\n cdn: options.cdn,\n pageTitle: options.metaData?.title ?? 'API Reference',\n })\n }\n}\n\n/**\n * Creates a plugin definition for the OpenAPI Fastify plugin.\n *\n * @param options - Plugin configuration options\n * @returns Plugin definition to pass to `app.usePlugin()`\n *\n * @example\n * ```typescript\n * import { NaviosFactory } from '@navios/core'\n * import { defineFastifyEnvironment } from '@navios/adapter-fastify'\n * import { defineOpenApiPlugin } from '@navios/openapi-fastify'\n *\n * const app = await NaviosFactory.create(AppModule, {\n * adapter: defineFastifyEnvironment(),\n * })\n *\n * app.usePlugin(defineOpenApiPlugin({\n * info: {\n * title: 'My API',\n * version: '1.0.0',\n * description: 'API documentation',\n * },\n * servers: [\n * { url: 'http://localhost:3000', description: 'Development' },\n * ],\n * securitySchemes: {\n * bearerAuth: {\n * type: 'http',\n * scheme: 'bearer',\n * bearerFormat: 'JWT',\n * },\n * },\n * scalar: {\n * theme: 'purple',\n * },\n * }))\n *\n * await app.listen({ port: 3000 })\n * // API docs available at http://localhost:3000/docs\n * ```\n */\nexport function defineOpenApiPlugin(\n options: FastifyOpenApiPluginOptions,\n): PluginDefinition<FastifyOpenApiPluginOptions> {\n return {\n plugin: new OpenApiFastifyPlugin(),\n options,\n }\n}\n\n// Re-export types for convenience\nexport type { ScalarOptions, ScalarTheme }\n"],"mappings":"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"}
package/package.json ADDED
@@ -0,0 +1,48 @@
1
+ {
2
+ "name": "@navios/openapi-fastify",
3
+ "version": "0.7.0",
4
+ "author": {
5
+ "name": "Oleksandr Hanzha",
6
+ "email": "alex@granted.name"
7
+ },
8
+ "repository": {
9
+ "directory": "packages/openapi-fastify",
10
+ "type": "git",
11
+ "url": "https://github.com/Arilas/navios.git"
12
+ },
13
+ "license": "MIT",
14
+ "peerDependencies": {
15
+ "@navios/adapter-fastify": "^0.7.1",
16
+ "@navios/core": "^0.7.1",
17
+ "@navios/openapi": "^0.7.0",
18
+ "fastify": "^5.0.0",
19
+ "zod": "^3.25.0 || ^4.0.0"
20
+ },
21
+ "typings": "./lib/index.d.mts",
22
+ "main": "./lib/index.cjs",
23
+ "module": "./lib/index.mjs",
24
+ "exports": {
25
+ ".": {
26
+ "import": {
27
+ "types": "./lib/index.d.mts",
28
+ "default": "./lib/index.mjs"
29
+ },
30
+ "require": {
31
+ "types": "./lib/index.d.cts",
32
+ "default": "./lib/index.cjs"
33
+ }
34
+ }
35
+ },
36
+ "devDependencies": {
37
+ "@navios/adapter-fastify": "^0.7.1",
38
+ "@navios/core": "^0.7.1",
39
+ "@navios/openapi": "^0.7.0",
40
+ "fastify": "^5.6.2",
41
+ "typescript": "^5.9.3",
42
+ "zod": "^4.2.1"
43
+ },
44
+ "dependencies": {
45
+ "@scalar/core": "^0.3.28",
46
+ "yaml": "^2.8.2"
47
+ }
48
+ }
package/project.json ADDED
@@ -0,0 +1,66 @@
1
+ {
2
+ "name": "@navios/openapi-fastify",
3
+ "$schema": "../../node_modules/nx/schemas/project-schema.json",
4
+ "sourceRoot": "packages/openapi-fastify/src",
5
+ "prefix": "openapi-fastify",
6
+ "tags": [],
7
+ "projectType": "library",
8
+ "targets": {
9
+ "check": {
10
+ "executor": "nx:run-commands",
11
+ "outputs": ["{projectRoot}/dist"],
12
+ "inputs": [
13
+ "^projectSources",
14
+ "projectSources",
15
+ "{projectRoot}/tsconfig.json",
16
+ "{projectRoot}/tsconfig.lib.json"
17
+ ],
18
+ "options": {
19
+ "command": ["tsc -b"],
20
+ "cwd": "packages/openapi-fastify"
21
+ }
22
+ },
23
+ "lint": {
24
+ "executor": "nx:run-commands",
25
+ "inputs": ["^projectSources", "project"],
26
+ "options": {
27
+ "command": "oxlint --fix",
28
+ "cwd": "packages/openapi-fastify"
29
+ }
30
+ },
31
+ "test:ci": {
32
+ "executor": "nx:run-commands",
33
+ "inputs": ["^projectSources", "project"],
34
+ "options": {
35
+ "command": "vitest run",
36
+ "cwd": "packages/openapi-fastify"
37
+ }
38
+ },
39
+ "build": {
40
+ "executor": "nx:run-commands",
41
+ "inputs": ["projectSources", "{projectRoot}/tsdown.config.mts"],
42
+ "outputs": ["{projectRoot}/lib"],
43
+ "dependsOn": ["check", "lint"],
44
+ "options": {
45
+ "command": "tsdown",
46
+ "cwd": "packages/openapi-fastify"
47
+ }
48
+ },
49
+ "publish": {
50
+ "executor": "nx:run-commands",
51
+ "dependsOn": ["build"],
52
+ "options": {
53
+ "command": "yarn npm publish --access public",
54
+ "cwd": "packages/openapi-fastify"
55
+ }
56
+ },
57
+ "publish:next": {
58
+ "executor": "nx:run-commands",
59
+ "dependsOn": ["build"],
60
+ "options": {
61
+ "command": "yarn npm publish --access public --tag next",
62
+ "cwd": "packages/openapi-fastify"
63
+ }
64
+ }
65
+ }
66
+ }
package/src/index.mts ADDED
@@ -0,0 +1,41 @@
1
+ // Plugin
2
+ export {
3
+ defineOpenApiPlugin,
4
+ OpenApiFastifyPlugin,
5
+ type FastifyOpenApiPluginOptions,
6
+ type ScalarOptions,
7
+ type ScalarTheme,
8
+ } from './openapi-fastify.plugin.mjs'
9
+
10
+ // Schemas
11
+ export {
12
+ fastifyOpenApiPluginOptionsSchema,
13
+ scalarOptionsSchema,
14
+ scalarThemeSchema,
15
+ scalarMetaDataSchema,
16
+ } from './schemas/index.mjs'
17
+
18
+ // Utils
19
+ export { applyGlobalPrefix } from './utils/index.mjs'
20
+
21
+ // Re-export core OpenAPI types for convenience
22
+ export type {
23
+ OpenApiGeneratorOptions,
24
+ OpenApiEndpointMetadata,
25
+ ApiOperationOptions,
26
+ ApiTagOptions,
27
+ ApiStreamOptions,
28
+ ApiDeprecatedOptions,
29
+ ApiSecurityRequirement,
30
+ } from '@navios/openapi'
31
+
32
+ // Re-export decorators for convenience
33
+ export {
34
+ ApiTag,
35
+ ApiOperation,
36
+ ApiSummary,
37
+ ApiDeprecated,
38
+ ApiSecurity,
39
+ ApiExclude,
40
+ ApiStream,
41
+ } from '@navios/openapi'