@scalar/nextjs-openapi 0.2.33 → 0.2.35

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -1,5 +1,26 @@
1
1
  # @scalar/nextjs-openapi
2
2
 
3
+ ## 0.2.35
4
+
5
+ ### Patch Changes
6
+
7
+ - [#7666](https://github.com/scalar/scalar/pull/7666): fix: export public API via named exports
8
+
9
+ #### Updated Dependencies
10
+
11
+ - **@scalar/nextjs-api-reference@0.9.9**
12
+
13
+ ## 0.2.34
14
+
15
+ ### Patch Changes
16
+
17
+ #### Updated Dependencies
18
+
19
+ - **@scalar/types@0.5.6**
20
+ - [#7661](https://github.com/scalar/scalar/pull/7661): fix: all issues for client modal v2 preparation
21
+
22
+ - **@scalar/nextjs-api-reference@0.9.9**
23
+
3
24
  ## 0.2.33
4
25
 
5
26
  ### Patch Changes
package/dist/index.d.ts CHANGED
@@ -1,2 +1,3 @@
1
- export * from './openapi.js';
1
+ export type { OpenAPIConfig } from './openapi.js';
2
+ export { OpenAPI } from './openapi.js';
2
3
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,WAAW,CAAA"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,YAAY,EAAE,aAAa,EAAE,MAAM,WAAW,CAAA;AAC9C,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAA"}
package/dist/index.js CHANGED
@@ -1,2 +1,5 @@
1
- export * from "./openapi.js";
1
+ import { OpenAPI } from "./openapi.js";
2
+ export {
3
+ OpenAPI
4
+ };
2
5
  //# sourceMappingURL=index.js.map
package/dist/index.js.map CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../src/index.ts"],
4
- "sourcesContent": ["export * from './openapi'\n"],
5
- "mappings": "AAAA,cAAc;",
4
+ "sourcesContent": ["export type { OpenAPIConfig } from './openapi'\nexport { OpenAPI } from './openapi'\n"],
5
+ "mappings": "AACA,SAAS,eAAe;",
6
6
  "names": []
7
7
  }
@@ -1 +1 @@
1
- {"version":3,"file":"openapi.d.ts","sourceRoot":"","sources":["../src/openapi.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,yBAAyB,EAAE,MAAM,6BAA6B,CAAA;AAE5E,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,aAAa,CAAA;AAa9C;;GAEG;AACH,MAAM,MAAM,aAAa,GAAG;IAC1B;;;OAGG;IACH,YAAY,CAAC,EAAE,MAAM,CAAA;CACtB,GAAG,OAAO,CAAC,yBAAyB,CAAC,CAAA;AA+BtC;;;;;;;;;GASG;AACH,eAAO,MAAM,OAAO,GAAI,SAAQ,aAAkB;eAoC7B,WAAW;CAe/B,CAAA"}
1
+ {"version":3,"file":"openapi.d.ts","sourceRoot":"","sources":["../src/openapi.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,yBAAyB,EAAE,MAAM,6BAA6B,CAAA;AAE5E,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,aAAa,CAAA;AAa9C;;GAEG;AACH,MAAM,MAAM,aAAa,GAAG;IAC1B;;;OAGG;IACH,YAAY,CAAC,EAAE,MAAM,CAAA;CACtB,GAAG,OAAO,CAAC,yBAAyB,CAAC,CAAA;AA+BtC;;;;;;;;;GASG;AACH,eAAO,MAAM,OAAO,GAAI,SAAQ,aAAkB;eAoC7B,WAAW;CAe/B,CAAA"}
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../src/openapi.ts"],
4
- "sourcesContent": ["import { readFileSync } from 'node:fs'\nimport { ApiReference } from '@scalar/nextjs-api-reference'\nimport type { ApiReferenceConfiguration } from '@scalar/types/api-reference'\nimport { sync } from 'fast-glob'\nimport type { NextRequest } from 'next/server'\nimport type { OpenAPIV3_1 } from 'openapi-types'\nimport {\n type CompilerHost,\n JSDocParsingMode,\n ScriptKind,\n ScriptTarget,\n createProgram,\n createSourceFile,\n} from 'typescript'\n\nimport { getPathSchema } from './path'\n\n/**\n * Scalar OpenAPI config\n */\nexport type OpenAPIConfig = {\n /**\n * The base directory for your API files\n * @default 'app/api'\n */\n apiDirectory?: string\n} & Partial<ApiReferenceConfiguration>\n\n// TODO switch to watcher\n// @see https://github.com/microsoft/TypeScript-wiki/blob/main/Using-the-Compiler-API.md#writing-an-incremental-program-watcher\nconst compilerHost: CompilerHost = {\n fileExists: () => true,\n getCanonicalFileName: (filename) => filename,\n getCurrentDirectory: () => '',\n getDefaultLibFileName: () => '',\n getNewLine: () => '\\n',\n getSourceFile: (filename) =>\n createSourceFile(filename, readFileSync(filename).toString(), ScriptTarget.Latest, false, ScriptKind.TS),\n jsDocParsingMode: JSDocParsingMode.ParseAll,\n readFile: () => undefined,\n useCaseSensitiveFileNames: () => true,\n writeFile: () => null,\n}\n\n/** OpenAPI 3.1.0 Spec */\nconst spec: OpenAPIV3_1.Document = {\n openapi: '3.1.0',\n info: {\n title: `${process.env.npm_package_name} - Next.js OpenAPI Spec by Scalar`,\n description:\n process.env.npm_package_description ||\n 'This file has been autogenerated, check out the docs to see how to customize these options',\n version: process.env.npm_package_version || '0.0.0',\n },\n paths: {},\n}\n\n/**\n * Scalar Next.js OpenAPI schema generation\n *\n * Handles both the schema generation as well as the references\n *\n * TODO:\n * - Docs\n * - file watcher\n * - caching\n */\nexport const OpenAPI = (config: OpenAPIConfig = {}) => {\n const apiDirectory = config.apiDirectory ?? 'app/api'\n /** All ts files required for the schema */\n const programFileNames = sync(apiDirectory + '/**/*.ts')\n /** Specific route files to generate paths */\n const routeFileNames = sync(apiDirectory + '/**/route.ts')\n\n const program = createProgram(\n programFileNames,\n {\n noResolve: true,\n target: ScriptTarget.Latest,\n },\n compilerHost,\n )\n\n // Loop over all non scalar files to extract openapi data using AST\n routeFileNames.forEach((fileName) => {\n const sourceFile = program.getSourceFile(fileName)\n\n if (sourceFile) {\n const resp = getPathSchema(sourceFile, program)\n\n // Grab the path from the fileName\n const rawPath = fileName\n .replace(/^(?:src\\/)?app|\\/route\\.ts$/g, '')\n .replace(/\\[/g, '{')\n .replace(/\\/\\(\\w+\\)/g, '')\n .replace(/]/g, '}')\n const path = rawPath.startsWith('/') ? rawPath : '/' + rawPath\n\n spec.paths[path] = resp\n }\n })\n\n return {\n GET: async (req: NextRequest) => {\n // OpenAPI Schema JSON\n if (req.nextUrl.pathname.endsWith('.json')) {\n // Just grabbing the origin here but we can be smarter and look for the greatest common few segments\n spec.servers = [{ url: req.nextUrl.origin }]\n\n return Response.json(spec)\n }\n // References\n\n return await ApiReference({\n url: req.nextUrl.pathname + '/schema.json',\n })()\n },\n }\n}\n"],
5
- "mappings": "AAAA,SAAS,oBAAoB;AAC7B,SAAS,oBAAoB;AAE7B,SAAS,YAAY;AAGrB;AAAA,EAEE;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,OACK;AAEP,SAAS,qBAAqB;AAe9B,MAAM,eAA6B;AAAA,EACjC,YAAY,MAAM;AAAA,EAClB,sBAAsB,CAAC,aAAa;AAAA,EACpC,qBAAqB,MAAM;AAAA,EAC3B,uBAAuB,MAAM;AAAA,EAC7B,YAAY,MAAM;AAAA,EAClB,eAAe,CAAC,aACd,iBAAiB,UAAU,aAAa,QAAQ,EAAE,SAAS,GAAG,aAAa,QAAQ,OAAO,WAAW,EAAE;AAAA,EACzG,kBAAkB,iBAAiB;AAAA,EACnC,UAAU,MAAM;AAAA,EAChB,2BAA2B,MAAM;AAAA,EACjC,WAAW,MAAM;AACnB;AAGA,MAAM,OAA6B;AAAA,EACjC,SAAS;AAAA,EACT,MAAM;AAAA,IACJ,OAAO,GAAG,QAAQ,IAAI,gBAAgB;AAAA,IACtC,aACE,QAAQ,IAAI,2BACZ;AAAA,IACF,SAAS,QAAQ,IAAI,uBAAuB;AAAA,EAC9C;AAAA,EACA,OAAO,CAAC;AACV;AAYO,MAAM,UAAU,CAAC,SAAwB,CAAC,MAAM;AACrD,QAAM,eAAe,OAAO,gBAAgB;AAE5C,QAAM,mBAAmB,KAAK,eAAe,UAAU;AAEvD,QAAM,iBAAiB,KAAK,eAAe,cAAc;AAEzD,QAAM,UAAU;AAAA,IACd;AAAA,IACA;AAAA,MACE,WAAW;AAAA,MACX,QAAQ,aAAa;AAAA,IACvB;AAAA,IACA;AAAA,EACF;AAGA,iBAAe,QAAQ,CAAC,aAAa;AACnC,UAAM,aAAa,QAAQ,cAAc,QAAQ;AAEjD,QAAI,YAAY;AACd,YAAM,OAAO,cAAc,YAAY,OAAO;AAG9C,YAAM,UAAU,SACb,QAAQ,gCAAgC,EAAE,EAC1C,QAAQ,OAAO,GAAG,EAClB,QAAQ,cAAc,EAAE,EACxB,QAAQ,MAAM,GAAG;AACpB,YAAM,OAAO,QAAQ,WAAW,GAAG,IAAI,UAAU,MAAM;AAEvD,WAAK,MAAM,IAAI,IAAI;AAAA,IACrB;AAAA,EACF,CAAC;AAED,SAAO;AAAA,IACL,KAAK,OAAO,QAAqB;AAE/B,UAAI,IAAI,QAAQ,SAAS,SAAS,OAAO,GAAG;AAE1C,aAAK,UAAU,CAAC,EAAE,KAAK,IAAI,QAAQ,OAAO,CAAC;AAE3C,eAAO,SAAS,KAAK,IAAI;AAAA,MAC3B;AAGA,aAAO,MAAM,aAAa;AAAA,QACxB,KAAK,IAAI,QAAQ,WAAW;AAAA,MAC9B,CAAC,EAAE;AAAA,IACL;AAAA,EACF;AACF;",
4
+ "sourcesContent": ["import { readFileSync } from 'node:fs'\n\nimport { ApiReference } from '@scalar/nextjs-api-reference'\nimport type { ApiReferenceConfiguration } from '@scalar/types/api-reference'\nimport { sync } from 'fast-glob'\nimport type { NextRequest } from 'next/server'\nimport type { OpenAPIV3_1 } from 'openapi-types'\nimport {\n type CompilerHost,\n JSDocParsingMode,\n ScriptKind,\n ScriptTarget,\n createProgram,\n createSourceFile,\n} from 'typescript'\n\nimport { getPathSchema } from './path'\n\n/**\n * Scalar OpenAPI config\n */\nexport type OpenAPIConfig = {\n /**\n * The base directory for your API files\n * @default 'app/api'\n */\n apiDirectory?: string\n} & Partial<ApiReferenceConfiguration>\n\n// TODO switch to watcher\n// @see https://github.com/microsoft/TypeScript-wiki/blob/main/Using-the-Compiler-API.md#writing-an-incremental-program-watcher\nconst compilerHost: CompilerHost = {\n fileExists: () => true,\n getCanonicalFileName: (filename) => filename,\n getCurrentDirectory: () => '',\n getDefaultLibFileName: () => '',\n getNewLine: () => '\\n',\n getSourceFile: (filename) =>\n createSourceFile(filename, readFileSync(filename).toString(), ScriptTarget.Latest, false, ScriptKind.TS),\n jsDocParsingMode: JSDocParsingMode.ParseAll,\n readFile: () => undefined,\n useCaseSensitiveFileNames: () => true,\n writeFile: () => null,\n}\n\n/** OpenAPI 3.1.0 Spec */\nconst spec: OpenAPIV3_1.Document = {\n openapi: '3.1.0',\n info: {\n title: `${process.env.npm_package_name} - Next.js OpenAPI Spec by Scalar`,\n description:\n process.env.npm_package_description ||\n 'This file has been autogenerated, check out the docs to see how to customize these options',\n version: process.env.npm_package_version || '0.0.0',\n },\n paths: {},\n}\n\n/**\n * Scalar Next.js OpenAPI schema generation\n *\n * Handles both the schema generation as well as the references\n *\n * TODO:\n * - Docs\n * - file watcher\n * - caching\n */\nexport const OpenAPI = (config: OpenAPIConfig = {}) => {\n const apiDirectory = config.apiDirectory ?? 'app/api'\n /** All ts files required for the schema */\n const programFileNames = sync(apiDirectory + '/**/*.ts')\n /** Specific route files to generate paths */\n const routeFileNames = sync(apiDirectory + '/**/route.ts')\n\n const program = createProgram(\n programFileNames,\n {\n noResolve: true,\n target: ScriptTarget.Latest,\n },\n compilerHost,\n )\n\n // Loop over all non scalar files to extract openapi data using AST\n routeFileNames.forEach((fileName) => {\n const sourceFile = program.getSourceFile(fileName)\n\n if (sourceFile) {\n const resp = getPathSchema(sourceFile, program)\n\n // Grab the path from the fileName\n const rawPath = fileName\n .replace(/^(?:src\\/)?app|\\/route\\.ts$/g, '')\n .replace(/\\[/g, '{')\n .replace(/\\/\\(\\w+\\)/g, '')\n .replace(/]/g, '}')\n const path = rawPath.startsWith('/') ? rawPath : '/' + rawPath\n\n spec.paths[path] = resp\n }\n })\n\n return {\n GET: async (req: NextRequest) => {\n // OpenAPI Schema JSON\n if (req.nextUrl.pathname.endsWith('.json')) {\n // Just grabbing the origin here but we can be smarter and look for the greatest common few segments\n spec.servers = [{ url: req.nextUrl.origin }]\n\n return Response.json(spec)\n }\n // References\n\n return await ApiReference({\n url: req.nextUrl.pathname + '/schema.json',\n })()\n },\n }\n}\n"],
5
+ "mappings": "AAAA,SAAS,oBAAoB;AAE7B,SAAS,oBAAoB;AAE7B,SAAS,YAAY;AAGrB;AAAA,EAEE;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,OACK;AAEP,SAAS,qBAAqB;AAe9B,MAAM,eAA6B;AAAA,EACjC,YAAY,MAAM;AAAA,EAClB,sBAAsB,CAAC,aAAa;AAAA,EACpC,qBAAqB,MAAM;AAAA,EAC3B,uBAAuB,MAAM;AAAA,EAC7B,YAAY,MAAM;AAAA,EAClB,eAAe,CAAC,aACd,iBAAiB,UAAU,aAAa,QAAQ,EAAE,SAAS,GAAG,aAAa,QAAQ,OAAO,WAAW,EAAE;AAAA,EACzG,kBAAkB,iBAAiB;AAAA,EACnC,UAAU,MAAM;AAAA,EAChB,2BAA2B,MAAM;AAAA,EACjC,WAAW,MAAM;AACnB;AAGA,MAAM,OAA6B;AAAA,EACjC,SAAS;AAAA,EACT,MAAM;AAAA,IACJ,OAAO,GAAG,QAAQ,IAAI,gBAAgB;AAAA,IACtC,aACE,QAAQ,IAAI,2BACZ;AAAA,IACF,SAAS,QAAQ,IAAI,uBAAuB;AAAA,EAC9C;AAAA,EACA,OAAO,CAAC;AACV;AAYO,MAAM,UAAU,CAAC,SAAwB,CAAC,MAAM;AACrD,QAAM,eAAe,OAAO,gBAAgB;AAE5C,QAAM,mBAAmB,KAAK,eAAe,UAAU;AAEvD,QAAM,iBAAiB,KAAK,eAAe,cAAc;AAEzD,QAAM,UAAU;AAAA,IACd;AAAA,IACA;AAAA,MACE,WAAW;AAAA,MACX,QAAQ,aAAa;AAAA,IACvB;AAAA,IACA;AAAA,EACF;AAGA,iBAAe,QAAQ,CAAC,aAAa;AACnC,UAAM,aAAa,QAAQ,cAAc,QAAQ;AAEjD,QAAI,YAAY;AACd,YAAM,OAAO,cAAc,YAAY,OAAO;AAG9C,YAAM,UAAU,SACb,QAAQ,gCAAgC,EAAE,EAC1C,QAAQ,OAAO,GAAG,EAClB,QAAQ,cAAc,EAAE,EACxB,QAAQ,MAAM,GAAG;AACpB,YAAM,OAAO,QAAQ,WAAW,GAAG,IAAI,UAAU,MAAM;AAEvD,WAAK,MAAM,IAAI,IAAI;AAAA,IACrB;AAAA,EACF,CAAC;AAED,SAAO;AAAA,IACL,KAAK,OAAO,QAAqB;AAE/B,UAAI,IAAI,QAAQ,SAAS,SAAS,OAAO,GAAG;AAE1C,aAAK,UAAU,CAAC,EAAE,KAAK,IAAI,QAAQ,OAAO,CAAC;AAE3C,eAAO,SAAS,KAAK,IAAI;AAAA,MAC3B;AAGA,aAAO,MAAM,aAAa;AAAA,QACxB,KAAK,IAAI,QAAQ,WAAW;AAAA,MAC9B,CAAC,EAAE;AAAA,IACL;AAAA,EACF;AACF;",
6
6
  "names": []
7
7
  }
package/dist/path.d.ts CHANGED
@@ -3,5 +3,5 @@ import { type Program, type SourceFile } from 'typescript';
3
3
  /**
4
4
  * Traverse the typescript file and extract as much info as we can for the openapi spec
5
5
  */
6
- export declare const getPathSchema: (sourceFile: SourceFile, program: Program) => OpenAPIV3_1.PathsObject<{}, {}>;
6
+ export declare const getPathSchema: (sourceFile: SourceFile, program: Program) => OpenAPIV3_1.PathsObject;
7
7
  //# sourceMappingURL=path.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"path.d.ts","sourceRoot":"","sources":["../src/path.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,eAAe,CAAA;AAEhD,OAAO,EAGL,KAAK,OAAO,EACZ,KAAK,UAAU,EAOhB,MAAM,YAAY,CAAA;AAoDnB;;GAEG;AACH,eAAO,MAAM,aAAa,GAAI,YAAY,UAAU,EAAE,SAAS,OAAO,oCAuCrE,CAAA"}
1
+ {"version":3,"file":"path.d.ts","sourceRoot":"","sources":["../src/path.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,eAAe,CAAA;AAChD,OAAO,EAGL,KAAK,OAAO,EACZ,KAAK,UAAU,EAOhB,MAAM,YAAY,CAAA;AAoDnB;;GAEG;AACH,eAAO,MAAM,aAAa,GAAI,YAAY,UAAU,EAAE,SAAS,OAAO,KAAG,WAAW,CAAC,WAuCpF,CAAA"}
package/dist/path.js CHANGED
@@ -1,5 +1,5 @@
1
- import { generateResponses, getJSDocFromNode, getSchemaFromTypeNode } from "@scalar/ts-to-openapi";
2
1
  import { extname, join } from "node:path";
2
+ import { generateResponses, getJSDocFromNode, getSchemaFromTypeNode } from "@scalar/ts-to-openapi";
3
3
  import {
4
4
  isFunctionDeclaration,
5
5
  isIdentifier,
package/dist/path.js.map CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../src/path.ts"],
4
- "sourcesContent": ["import { generateResponses, getJSDocFromNode, getSchemaFromTypeNode } from '@scalar/ts-to-openapi'\nimport type { OpenAPIV3_1 } from 'openapi-types'\nimport { extname, join } from 'node:path'\nimport {\n type Identifier,\n type ParameterDeclaration,\n type Program,\n type SourceFile,\n isFunctionDeclaration,\n isIdentifier,\n isParameter,\n isPropertySignature,\n isTypeLiteralNode,\n isVariableStatement,\n} from 'typescript'\n\n/** Check if identifier is a supported http method */\nconst checkForMethod = (identifier: Pick<Identifier, 'escapedText'> | undefined) => {\n const method = identifier?.escapedText?.toLowerCase()\n\n return method?.match(/^(get|post|put|patch|delete|head|options)$/) ? (method as OpenAPIV3_1.HttpMethods) : null\n}\n\nconst fileNameResolver = (source: string, target: string) => {\n const sourceExt = extname(source)\n const targetExt = extname(target)\n\n const targetRelative = target + (targetExt ? '' : sourceExt)\n const targetPath = join(source.replace(/\\/([^/]+)$/, ''), targetRelative)\n\n return targetPath\n}\n\n/**\n * Takes a parameter node and returns a path parameter schema\n */\nconst extractPathParams = (node: ParameterDeclaration | undefined, program: Program): OpenAPIV3_1.ParameterObject[] => {\n // Traverse to the params with type guards\n if (\n node &&\n isParameter(node) &&\n node.type &&\n isTypeLiteralNode(node.type) &&\n node.type.members[0] &&\n isPropertySignature(node.type.members[0]) &&\n isIdentifier(node.type.members[0].name) &&\n node.type.members[0].name.escapedText === 'params' &&\n node.type.members[0].type &&\n isTypeLiteralNode(node.type.members[0].type)\n ) {\n return node.type.members[0].type?.members.flatMap((member) => {\n if (!isPropertySignature(member) || !member.type) {\n return []\n }\n\n return {\n name: member.name?.getText(),\n schema: getSchemaFromTypeNode(member.type, program, fileNameResolver),\n in: 'path',\n } as OpenAPIV3_1.ParameterObject\n })\n }\n\n return []\n}\n\n/**\n * Traverse the typescript file and extract as much info as we can for the openapi spec\n */\nexport const getPathSchema = (sourceFile: SourceFile, program: Program) => {\n const path: OpenAPIV3_1.PathsObject = {}\n const typeChecker = program.getTypeChecker()\n\n sourceFile.statements.forEach((statement) => {\n // Function\n if (isFunctionDeclaration(statement) && statement.name) {\n const method = checkForMethod(statement.name)\n if (method) {\n const { title, description } = getJSDocFromNode(statement)\n const parameters = extractPathParams(statement.parameters[1], program)\n const responses = generateResponses(statement.body, typeChecker)\n\n path[method] = {\n summary: title,\n description,\n parameters,\n responses,\n } as OpenAPIV3_1.OperationObject\n }\n }\n\n // TODO: variables\n else if (isVariableStatement(statement)) {\n // TODO: Remove this typecast. It looks totally incompatible\n const method = checkForMethod(statement.declarationList.declarations[0]?.name as Identifier)\n if (method) {\n const { title, description } = getJSDocFromNode(statement)\n const responses = generateResponses(statement, typeChecker)\n path[method] = {\n summary: title,\n description,\n responses,\n } as OpenAPIV3_1.OperationObject\n }\n }\n })\n\n return path\n}\n"],
5
- "mappings": "AAAA,SAAS,mBAAmB,kBAAkB,6BAA6B;AAE3E,SAAS,SAAS,YAAY;AAC9B;AAAA,EAKE;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,OACK;AAGP,MAAM,iBAAiB,CAAC,eAA4D;AAClF,QAAM,SAAS,YAAY,aAAa,YAAY;AAEpD,SAAO,QAAQ,MAAM,4CAA4C,IAAK,SAAqC;AAC7G;AAEA,MAAM,mBAAmB,CAAC,QAAgB,WAAmB;AAC3D,QAAM,YAAY,QAAQ,MAAM;AAChC,QAAM,YAAY,QAAQ,MAAM;AAEhC,QAAM,iBAAiB,UAAU,YAAY,KAAK;AAClD,QAAM,aAAa,KAAK,OAAO,QAAQ,cAAc,EAAE,GAAG,cAAc;AAExE,SAAO;AACT;AAKA,MAAM,oBAAoB,CAAC,MAAwC,YAAoD;AAErH,MACE,QACA,YAAY,IAAI,KAChB,KAAK,QACL,kBAAkB,KAAK,IAAI,KAC3B,KAAK,KAAK,QAAQ,CAAC,KACnB,oBAAoB,KAAK,KAAK,QAAQ,CAAC,CAAC,KACxC,aAAa,KAAK,KAAK,QAAQ,CAAC,EAAE,IAAI,KACtC,KAAK,KAAK,QAAQ,CAAC,EAAE,KAAK,gBAAgB,YAC1C,KAAK,KAAK,QAAQ,CAAC,EAAE,QACrB,kBAAkB,KAAK,KAAK,QAAQ,CAAC,EAAE,IAAI,GAC3C;AACA,WAAO,KAAK,KAAK,QAAQ,CAAC,EAAE,MAAM,QAAQ,QAAQ,CAAC,WAAW;AAC5D,UAAI,CAAC,oBAAoB,MAAM,KAAK,CAAC,OAAO,MAAM;AAChD,eAAO,CAAC;AAAA,MACV;AAEA,aAAO;AAAA,QACL,MAAM,OAAO,MAAM,QAAQ;AAAA,QAC3B,QAAQ,sBAAsB,OAAO,MAAM,SAAS,gBAAgB;AAAA,QACpE,IAAI;AAAA,MACN;AAAA,IACF,CAAC;AAAA,EACH;AAEA,SAAO,CAAC;AACV;AAKO,MAAM,gBAAgB,CAAC,YAAwB,YAAqB;AACzE,QAAM,OAAgC,CAAC;AACvC,QAAM,cAAc,QAAQ,eAAe;AAE3C,aAAW,WAAW,QAAQ,CAAC,cAAc;AAE3C,QAAI,sBAAsB,SAAS,KAAK,UAAU,MAAM;AACtD,YAAM,SAAS,eAAe,UAAU,IAAI;AAC5C,UAAI,QAAQ;AACV,cAAM,EAAE,OAAO,YAAY,IAAI,iBAAiB,SAAS;AACzD,cAAM,aAAa,kBAAkB,UAAU,WAAW,CAAC,GAAG,OAAO;AACrE,cAAM,YAAY,kBAAkB,UAAU,MAAM,WAAW;AAE/D,aAAK,MAAM,IAAI;AAAA,UACb,SAAS;AAAA,UACT;AAAA,UACA;AAAA,UACA;AAAA,QACF;AAAA,MACF;AAAA,IACF,WAGS,oBAAoB,SAAS,GAAG;AAEvC,YAAM,SAAS,eAAe,UAAU,gBAAgB,aAAa,CAAC,GAAG,IAAkB;AAC3F,UAAI,QAAQ;AACV,cAAM,EAAE,OAAO,YAAY,IAAI,iBAAiB,SAAS;AACzD,cAAM,YAAY,kBAAkB,WAAW,WAAW;AAC1D,aAAK,MAAM,IAAI;AAAA,UACb,SAAS;AAAA,UACT;AAAA,UACA;AAAA,QACF;AAAA,MACF;AAAA,IACF;AAAA,EACF,CAAC;AAED,SAAO;AACT;",
4
+ "sourcesContent": ["import { extname, join } from 'node:path'\n\nimport { generateResponses, getJSDocFromNode, getSchemaFromTypeNode } from '@scalar/ts-to-openapi'\nimport type { OpenAPIV3_1 } from 'openapi-types'\nimport {\n type Identifier,\n type ParameterDeclaration,\n type Program,\n type SourceFile,\n isFunctionDeclaration,\n isIdentifier,\n isParameter,\n isPropertySignature,\n isTypeLiteralNode,\n isVariableStatement,\n} from 'typescript'\n\n/** Check if identifier is a supported http method */\nconst checkForMethod = (identifier: Pick<Identifier, 'escapedText'> | undefined): OpenAPIV3_1.HttpMethods | null => {\n const method = identifier?.escapedText?.toLowerCase()\n\n return method?.match(/^(get|post|put|patch|delete|head|options)$/) ? (method as OpenAPIV3_1.HttpMethods) : null\n}\n\nconst fileNameResolver = (source: string, target: string): string => {\n const sourceExt = extname(source)\n const targetExt = extname(target)\n\n const targetRelative = target + (targetExt ? '' : sourceExt)\n const targetPath = join(source.replace(/\\/([^/]+)$/, ''), targetRelative)\n\n return targetPath\n}\n\n/**\n * Takes a parameter node and returns a path parameter schema\n */\nconst extractPathParams = (node: ParameterDeclaration | undefined, program: Program): OpenAPIV3_1.ParameterObject[] => {\n // Traverse to the params with type guards\n if (\n node &&\n isParameter(node) &&\n node.type &&\n isTypeLiteralNode(node.type) &&\n node.type.members[0] &&\n isPropertySignature(node.type.members[0]) &&\n isIdentifier(node.type.members[0].name) &&\n node.type.members[0].name.escapedText === 'params' &&\n node.type.members[0].type &&\n isTypeLiteralNode(node.type.members[0].type)\n ) {\n return node.type.members[0].type?.members.flatMap((member) => {\n if (!isPropertySignature(member) || !member.type) {\n return []\n }\n\n return {\n name: member.name?.getText(),\n schema: getSchemaFromTypeNode(member.type, program, fileNameResolver),\n in: 'path',\n } as OpenAPIV3_1.ParameterObject\n })\n }\n\n return []\n}\n\n/**\n * Traverse the typescript file and extract as much info as we can for the openapi spec\n */\nexport const getPathSchema = (sourceFile: SourceFile, program: Program): OpenAPIV3_1.PathsObject => {\n const path: OpenAPIV3_1.PathsObject = {}\n const typeChecker = program.getTypeChecker()\n\n sourceFile.statements.forEach((statement) => {\n // Function\n if (isFunctionDeclaration(statement) && statement.name) {\n const method = checkForMethod(statement.name)\n if (method) {\n const { title, description } = getJSDocFromNode(statement)\n const parameters = extractPathParams(statement.parameters[1], program)\n const responses = generateResponses(statement.body, typeChecker)\n\n path[method] = {\n summary: title,\n description,\n parameters,\n responses,\n } as OpenAPIV3_1.OperationObject\n }\n }\n\n // TODO: variables\n else if (isVariableStatement(statement)) {\n // TODO: Remove this typecast. It looks totally incompatible\n const method = checkForMethod(statement.declarationList.declarations[0]?.name as Identifier)\n if (method) {\n const { title, description } = getJSDocFromNode(statement)\n const responses = generateResponses(statement, typeChecker)\n path[method] = {\n summary: title,\n description,\n responses,\n } as OpenAPIV3_1.OperationObject\n }\n }\n })\n\n return path\n}\n"],
5
+ "mappings": "AAAA,SAAS,SAAS,YAAY;AAE9B,SAAS,mBAAmB,kBAAkB,6BAA6B;AAE3E;AAAA,EAKE;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,OACK;AAGP,MAAM,iBAAiB,CAAC,eAA4F;AAClH,QAAM,SAAS,YAAY,aAAa,YAAY;AAEpD,SAAO,QAAQ,MAAM,4CAA4C,IAAK,SAAqC;AAC7G;AAEA,MAAM,mBAAmB,CAAC,QAAgB,WAA2B;AACnE,QAAM,YAAY,QAAQ,MAAM;AAChC,QAAM,YAAY,QAAQ,MAAM;AAEhC,QAAM,iBAAiB,UAAU,YAAY,KAAK;AAClD,QAAM,aAAa,KAAK,OAAO,QAAQ,cAAc,EAAE,GAAG,cAAc;AAExE,SAAO;AACT;AAKA,MAAM,oBAAoB,CAAC,MAAwC,YAAoD;AAErH,MACE,QACA,YAAY,IAAI,KAChB,KAAK,QACL,kBAAkB,KAAK,IAAI,KAC3B,KAAK,KAAK,QAAQ,CAAC,KACnB,oBAAoB,KAAK,KAAK,QAAQ,CAAC,CAAC,KACxC,aAAa,KAAK,KAAK,QAAQ,CAAC,EAAE,IAAI,KACtC,KAAK,KAAK,QAAQ,CAAC,EAAE,KAAK,gBAAgB,YAC1C,KAAK,KAAK,QAAQ,CAAC,EAAE,QACrB,kBAAkB,KAAK,KAAK,QAAQ,CAAC,EAAE,IAAI,GAC3C;AACA,WAAO,KAAK,KAAK,QAAQ,CAAC,EAAE,MAAM,QAAQ,QAAQ,CAAC,WAAW;AAC5D,UAAI,CAAC,oBAAoB,MAAM,KAAK,CAAC,OAAO,MAAM;AAChD,eAAO,CAAC;AAAA,MACV;AAEA,aAAO;AAAA,QACL,MAAM,OAAO,MAAM,QAAQ;AAAA,QAC3B,QAAQ,sBAAsB,OAAO,MAAM,SAAS,gBAAgB;AAAA,QACpE,IAAI;AAAA,MACN;AAAA,IACF,CAAC;AAAA,EACH;AAEA,SAAO,CAAC;AACV;AAKO,MAAM,gBAAgB,CAAC,YAAwB,YAA8C;AAClG,QAAM,OAAgC,CAAC;AACvC,QAAM,cAAc,QAAQ,eAAe;AAE3C,aAAW,WAAW,QAAQ,CAAC,cAAc;AAE3C,QAAI,sBAAsB,SAAS,KAAK,UAAU,MAAM;AACtD,YAAM,SAAS,eAAe,UAAU,IAAI;AAC5C,UAAI,QAAQ;AACV,cAAM,EAAE,OAAO,YAAY,IAAI,iBAAiB,SAAS;AACzD,cAAM,aAAa,kBAAkB,UAAU,WAAW,CAAC,GAAG,OAAO;AACrE,cAAM,YAAY,kBAAkB,UAAU,MAAM,WAAW;AAE/D,aAAK,MAAM,IAAI;AAAA,UACb,SAAS;AAAA,UACT;AAAA,UACA;AAAA,UACA;AAAA,QACF;AAAA,MACF;AAAA,IACF,WAGS,oBAAoB,SAAS,GAAG;AAEvC,YAAM,SAAS,eAAe,UAAU,gBAAgB,aAAa,CAAC,GAAG,IAAkB;AAC3F,UAAI,QAAQ;AACV,cAAM,EAAE,OAAO,YAAY,IAAI,iBAAiB,SAAS;AACzD,cAAM,YAAY,kBAAkB,WAAW,WAAW;AAC1D,aAAK,MAAM,IAAI;AAAA,UACb,SAAS;AAAA,UACT;AAAA,UACA;AAAA,QACF;AAAA,MACF;AAAA,IACF;AAAA,EACF,CAAC;AAED,SAAO;AACT;",
6
6
  "names": []
7
7
  }
package/package.json CHANGED
@@ -16,7 +16,7 @@
16
16
  "scalar",
17
17
  "references"
18
18
  ],
19
- "version": "0.2.33",
19
+ "version": "0.2.35",
20
20
  "engines": {
21
21
  "node": ">=20"
22
22
  },
@@ -34,9 +34,9 @@
34
34
  ],
35
35
  "dependencies": {
36
36
  "fast-glob": "^3.3.2",
37
- "@scalar/nextjs-api-reference": "0.9.8",
38
- "@scalar/types": "0.5.5",
39
- "@scalar/ts-to-openapi": "0.1.2"
37
+ "@scalar/nextjs-api-reference": "0.9.9",
38
+ "@scalar/ts-to-openapi": "0.1.2",
39
+ "@scalar/types": "0.5.6"
40
40
  },
41
41
  "devDependencies": {
42
42
  "@types/node": "^22.9.0",