diff --git a/packages/source-analysis/src/RoutesMonitor.ts b/packages/source-analysis/src/RoutesMonitor.ts index 097f9a575..2ccfc67ad 100644 --- a/packages/source-analysis/src/RoutesMonitor.ts +++ b/packages/source-analysis/src/RoutesMonitor.ts @@ -1,4 +1,5 @@ import { EventEmitter } from "node:events"; +import { statSync } from "node:fs"; import path from "node:path"; import { type FileRemovedEvent, @@ -13,9 +14,10 @@ import { getParsedTsConfig, getTsLib, startServer } from "./service"; import type { TsISnapShot, TsLanguageService, + TsPackageType, TsProgram, - TsType, } from "./types"; +import { debounce } from "./utils"; type AnalysisStarted = { type: "analysisStarted"; @@ -68,7 +70,7 @@ export class RoutesMonitor extends EventEmitter<AnalysisEvents> { /** * Reference to the users' typescript instance */ - private _ts: TsType; + private _ts: TsPackageType; /** * The language service used to analyze the routes @@ -109,7 +111,32 @@ export class RoutesMonitor extends EventEmitter<AnalysisEvents> { constructor(projectRoot: string) { super(); - this.projectRoot = projectRoot; + const folder = path.isAbsolute(projectRoot) + ? projectRoot + : path.resolve(projectRoot); + + // check if folder exists + try { + const isDirectory = statSync(folder).isDirectory(); + if (!isDirectory) { + throw new Error("Not a directory"); + } + } catch (e: unknown) { + if (e instanceof Error) { + logger.error(`Folder ${folder} does not exist. Error: ${e.message}`); + } else { + logger.error("Unknown error while checking folder", { + folder: projectRoot, + error: e, + }); + } + + logger.warn( + "This is likely to cause issues with the file watcher & source analysis", + ); + } + + this.projectRoot = folder; this._ts = getTsLib(this.projectRoot); // Use the tsconfig include option to determine which files/locations to watch @@ -185,7 +212,6 @@ export class RoutesMonitor extends EventEmitter<AnalysisEvents> { return; } - logger.debug("Starting to monitor", this.projectRoot); this.addEventListenersToFileWatcher(); await this.fileWatcher.start(); @@ -199,12 +225,52 @@ export class RoutesMonitor extends EventEmitter<AnalysisEvents> { readFile: this.readFile.bind(this), ts: this._ts, }); - this._program = this._service.getProgram() ?? null; + + await this.isCompilerReady(); + this._isRunning = true; } + private async isCompilerReady(): Promise<boolean> { + if (!this._service) { + throw new Error("Service not initialized"); + } + + // Sometimes the test suite failed (finding 0 routes) so now we check if all files + // we are watching are in the program before we continue + let retryCount = 0; + let valid = true; + do { + valid = true; + this._program = this._service.getProgram() ?? null; + const sourceFiles = this._program?.getSourceFiles(); + const sourceFileNames = sourceFiles?.map((sf) => sf.fileName); + for (const watchedFilePath of this.fileWatcher.knownFileNamesArray) { + if (sourceFileNames?.includes(watchedFilePath) !== true) { + const retryDelay = 100 + retryCount * 100; + logger.warn( + `File ${watchedFilePath} not (yet) available in the Typescript program, retrying...`, + { retryCount, retryDelay }, + ); + + valid = false; + await new Promise((resolve) => setTimeout(resolve, retryDelay)); + break; + } + } + } while (!valid && retryCount++ < 5); + + if (retryCount >= 5) { + logger.error( + `Failed to monitor all files after ${retryCount} retries. Code analysis might be incomplete.`, + ); + } + + return valid; + } + public updateRoutesResult() { - if (!this.isRunning) { + if (!this._isRunning) { throw new Error("Monitor not running"); } @@ -255,7 +321,6 @@ export class RoutesMonitor extends EventEmitter<AnalysisEvents> { return this._ts.sys.readFile(fileName); } - private getScriptSnapshot(fileName: string): TsISnapShot | undefined { if (this._aggressiveCaching) { const info = this.getFileInfo(fileName); @@ -314,7 +379,6 @@ export class RoutesMonitor extends EventEmitter<AnalysisEvents> { } }); } - public findHonoRoutes() { this.fileExistsCache = {}; @@ -367,20 +431,3 @@ export class RoutesMonitor extends EventEmitter<AnalysisEvents> { return Object.keys(this.fileMap); } } - -function debounce<T extends (...args: Array<unknown>) => void | Promise<void>>( - func: T, - wait: number, -): (...args: Parameters<T>) => void { - let timeout: ReturnType<typeof setTimeout> | null = null; - - return (...args: Parameters<T>) => { - if (timeout !== null) { - clearTimeout(timeout); - } - - timeout = setTimeout(() => { - func(...args); - }, wait); - }; -} diff --git a/packages/source-analysis/src/RoutesResult/RoutesResult.test.ts b/packages/source-analysis/src/RoutesResult/RoutesResult.test.ts index 9f6a5deeb..9288c09d7 100644 --- a/packages/source-analysis/src/RoutesResult/RoutesResult.test.ts +++ b/packages/source-analysis/src/RoutesResult/RoutesResult.test.ts @@ -126,3 +126,33 @@ test("multiple", async () => { monitor.stop(); } }); + +test("zod-openapi", async () => { + const absolutePath = path.join(__dirname, "../../test-cases/zod-openapi"); + const monitor = createRoutesMonitor(absolutePath); + monitor.autoCreateResult = false; + try { + await monitor.start(); + const factory = monitor.updateRoutesResult(); + assert(factory.rootId); + + let request = new Request("http://localhost/users", { method: "POST" }); + let response = await factory.currentApp.fetch(request); + expect(await response.text()).toEqual("Ok"); + expect(factory.getHistoryLength()).toBe(2); + expect(factory.hasVisited(factory.rootId)).toBeTruthy(); + expect(factory.getFilesForHistory()).toMatchSnapshot(); + + factory.resetHistory(); + // Try to visit another route + request = new Request("http://localhost/users", { method: "GET" }); + response = await factory.currentApp.fetch(request); + expect(await response.text()).toEqual("Ok"); + expect(factory.getHistoryLength()).toBe(2); + expect(factory.hasVisited(factory.rootId)).toBeTruthy(); + expect(factory.getFilesForHistory()).toMatchSnapshot(); + + } finally { + monitor.stop(); + } +}); diff --git a/packages/source-analysis/src/RoutesResult/__snapshots__/RoutesResult.test.ts.snap b/packages/source-analysis/src/RoutesResult/__snapshots__/RoutesResult.test.ts.snap index 6b7a9d5b3..be08d2634 100644 --- a/packages/source-analysis/src/RoutesResult/__snapshots__/RoutesResult.test.ts.snap +++ b/packages/source-analysis/src/RoutesResult/__snapshots__/RoutesResult.test.ts.snap @@ -168,3 +168,111 @@ const app = new Hono(); app.post("/hello-world", (c) => c.json({ hello: "world" }) /* EOF: other.ts */" `; + +exports[`zod-openapi 1`] = ` +"/* index.ts */ +import { createRoute,z,z } from "@hono/zod-openapi"; +import { basicAuth } from "hono/basic-auth"; +const app = new OpenAPIHono(); + +const NewUserSchema = z + .object({ + name: z.string().openapi({ + example: "John Doe", + description: "The name of the user", + }), + age: z.number().openapi({ + example: 42, + }), + }) + .openapi("NewUser") + +const UserSchema = z + .object({ + id: z.number().openapi({ + example: 123, + }), + name: z.string().openapi({ + example: "John Doe", + }), + age: z.number().openapi({ + example: 42, + }), + }) + .openapi("User") + +app.post("/users", const createUserRoute = createRoute({ + method: "post", + path: "/users", + middleware: [ + basicAuth({ + username: "goose", + password: "honkhonk", + }), + ] as const, // Use \`as const\` to ensure TypeScript infers the middleware's Context correctly + request: { + body: { + content: { + "application/json": { + schema: NewUserSchema, + }, + }, + }, + }, + responses: { + 201: { + content: { + "application/json": { + schema: UserSchema, + }, + }, + description: "Retrieve the user", + }, + }, +}) +/* EOF: index.ts */" +`; + +exports[`zod-openapi 2`] = ` +"/* index.ts */ +import { createRoute,z,z } from "@hono/zod-openapi"; +import { basicAuth } from "hono/basic-auth"; +const app = new OpenAPIHono(); + +const UserSchema = z + .object({ + id: z.number().openapi({ + example: 123, + }), + name: z.string().openapi({ + example: "John Doe", + }), + age: z.number().openapi({ + example: 42, + }), + }) + .openapi("User") + +app.get("/users", createRoute({ + method: "get", + path: "/users", + middleware: [ + basicAuth({ + username: "goose", + password: "honkhonk", + }), + ] as const, // Use \`as const\` to ensure TypeScript infers the middleware's Context correctly + request: {}, + responses: { + 20: { + content: { + "application/json": { + schema: z.Array(UserSchema), + }, + }, + description: "Retrieve all users", + }, + }, + }) +/* EOF: index.ts */" +`; diff --git a/packages/source-analysis/src/RoutesResult/generate.ts b/packages/source-analysis/src/RoutesResult/generate.ts index 938da1dcf..937f75f24 100644 --- a/packages/source-analysis/src/RoutesResult/generate.ts +++ b/packages/source-analysis/src/RoutesResult/generate.ts @@ -283,7 +283,7 @@ function extractRouteTreeContent(includeIds: boolean, resource: RouteTree) { ? `// id:${resource.id} ` : "" - }const ${resource.name} = new Hono();`; + }const ${resource.name} = new ${resource.library === "hono" ? "Hono" : "OpenAPIHono"}();`; if (resource.baseUrl) { content += `\n${resource.name}.baseUrl = "${resource.baseUrl}";`; } diff --git a/packages/source-analysis/src/routeTrees/__snapshots__/extractRouteTree.test.ts.snap b/packages/source-analysis/src/routeTrees/__snapshots__/extractRouteTree.test.ts.snap index 6e906dae4..b3f42b42a 100644 --- a/packages/source-analysis/src/routeTrees/__snapshots__/extractRouteTree.test.ts.snap +++ b/packages/source-analysis/src/routeTrees/__snapshots__/extractRouteTree.test.ts.snap @@ -77,6 +77,7 @@ exports[`run test 'barrel files' with location '../../test-cases/barrel-files' 1 ], "fileName": "index.ts", "id": "ROUTE_TREE:index.ts@102", + "library": "hono", "modules": Set {}, "name": "app", "position": 102, @@ -312,6 +313,7 @@ exports[`run test 'hono factory' with location '../../test-cases/hono-factory' 1 ], "fileName": "bye.ts", "id": "ROUTE_TREE:bye.ts@36", + "library": "hono", "modules": Set {}, "name": "bye", "position": 36, @@ -328,6 +330,7 @@ exports[`run test 'hono factory' with location '../../test-cases/hono-factory' 1 ], "fileName": "factory.ts", "id": "ROUTE_TREE:factory.ts@248", + "library": "hono", "modules": Set {}, "name": "app", "position": 248, @@ -342,6 +345,7 @@ exports[`run test 'hono factory' with location '../../test-cases/hono-factory' 1 ], "fileName": "index.ts", "id": "ROUTE_TREE:index.ts@101", + "library": "hono", "modules": Set {}, "name": "subHello", "position": 101, @@ -356,6 +360,7 @@ exports[`run test 'hono factory' with location '../../test-cases/hono-factory' 1 ], "fileName": "index.ts", "id": "ROUTE_TREE:index.ts@75", + "library": "hono", "modules": Set {}, "name": "app", "position": 75, @@ -369,6 +374,7 @@ exports[`run test 'hono factory' with location '../../test-cases/hono-factory' 1 ], "fileName": "panic.ts", "id": "ROUTE_TREE:panic.ts@36", + "library": "hono", "modules": Set {}, "name": "app", "position": 36, @@ -382,6 +388,7 @@ exports[`run test 'hono factory' with location '../../test-cases/hono-factory' 1 ], "fileName": "silence.ts", "id": "ROUTE_TREE:silence.ts@36", + "library": "hono", "modules": Set {}, "name": "silence", "position": 36, @@ -583,6 +590,7 @@ exports[`run test 'import as' with location '../../test-cases/import-as' 1`] = ` ], "fileName": "index.ts", "id": "ROUTE_TREE:index.ts@151", + "library": "hono", "modules": Set {}, "name": "app", "position": 151, @@ -798,6 +806,7 @@ exports[`run test 'module imports' with location '../../test-cases/module-import ], "fileName": "index.ts", "id": "ROUTE_TREE:index.ts@114", + "library": "hono", "modules": Set {}, "name": "app", "position": 114, @@ -1000,6 +1009,7 @@ exports[`run test 'multiple files' with location '../../test-cases/multiple' 1`] ], "fileName": "index.ts", "id": "ROUTE_TREE:index.ts@36", + "library": "hono", "modules": Set {}, "name": "app", "position": 36, @@ -1014,6 +1024,7 @@ exports[`run test 'multiple files' with location '../../test-cases/multiple' 1`] ], "fileName": "other.ts", "id": "ROUTE_TREE:other.ts@35", + "library": "hono", "modules": Set {}, "name": "app", "position": 35, @@ -1060,87 +1071,89 @@ exports[`run test 'multiple files' with location '../../test-cases/multiple' 1`] exports[`run test 'single file' with location '../../test-cases/single' 1`] = ` { - "ROUTE_ENTRY:index.ts@125": { + "ROUTE_ENTRY:index.ts@126": { "fileName": "index.ts", - "id": "ROUTE_ENTRY:index.ts@125", + "id": "ROUTE_ENTRY:index.ts@126", "method": "post", "modules": Set {}, "path": "/single-quote", - "position": 125, + "position": 126, "sources": Set { - "SOURCE_REFERENCE:index.ts@151", + "SOURCE_REFERENCE:index.ts@152", }, "type": "ROUTE_ENTRY", }, - "ROUTE_ENTRY:index.ts@185": { + "ROUTE_ENTRY:index.ts@186": { "fileName": "index.ts", - "id": "ROUTE_ENTRY:index.ts@185", + "id": "ROUTE_ENTRY:index.ts@186", "method": "put", "modules": Set {}, "path": "/literal-template-literal-stuff", - "position": 185, + "position": 186, "sources": Set { - "SOURCE_REFERENCE:index.ts@234", + "SOURCE_REFERENCE:index.ts@235", }, "type": "ROUTE_ENTRY", }, - "ROUTE_ENTRY:index.ts@80": { + "ROUTE_ENTRY:index.ts@81": { "fileName": "index.ts", - "id": "ROUTE_ENTRY:index.ts@80", + "id": "ROUTE_ENTRY:index.ts@81", "method": "get", "modules": Set {}, "path": "/", - "position": 80, + "position": 81, "sources": Set { - "SOURCE_REFERENCE:index.ts@93", + "SOURCE_REFERENCE:index.ts@94", }, "type": "ROUTE_ENTRY", }, "ROUTE_TREE:index.ts@36": { "baseUrl": "", "entries": [ - "ROUTE_ENTRY:index.ts@80", - "ROUTE_ENTRY:index.ts@125", - "ROUTE_ENTRY:index.ts@185", + "ROUTE_ENTRY:index.ts@81", + "ROUTE_ENTRY:index.ts@126", + "ROUTE_ENTRY:index.ts@186", ], "fileName": "index.ts", "id": "ROUTE_TREE:index.ts@36", + "library": "hono", "modules": Set {}, "name": "app", "position": 36, "sources": Set {}, "type": "ROUTE_TREE", }, - "SOURCE_REFERENCE:index.ts@151": { + "SOURCE_REFERENCE:index.ts@152": { "character": 26, "content": "(c) => c.text("Hello, 'Hono'!")", "fileName": "index.ts", - "id": "SOURCE_REFERENCE:index.ts@151", + "id": "SOURCE_REFERENCE:index.ts@152", "line": 5, "modules": Set {}, - "position": 151, + "position": 152, "references": Set {}, "type": "SOURCE_REFERENCE", }, - "SOURCE_REFERENCE:index.ts@234": { + "SOURCE_REFERENCE:index.ts@235": { "character": 49, - "content": "(c) => c.text("Hello, \`\${Hono}\`!")", + "content": "(c) => + c.text("Hello, \`\${Hono}\`!")", "fileName": "index.ts", - "id": "SOURCE_REFERENCE:index.ts@234", + "id": "SOURCE_REFERENCE:index.ts@235", "line": 6, "modules": Set {}, - "position": 234, + "position": 235, "references": Set {}, "type": "SOURCE_REFERENCE", }, - "SOURCE_REFERENCE:index.ts@93": { + "SOURCE_REFERENCE:index.ts@94": { "character": 13, "content": "(c) => c.text("Hello, Hono!")", "fileName": "index.ts", - "id": "SOURCE_REFERENCE:index.ts@93", + "id": "SOURCE_REFERENCE:index.ts@94", "line": 4, "modules": Set {}, - "position": 93, + "position": 94, "references": Set {}, "type": "SOURCE_REFERENCE", }, @@ -1249,6 +1262,7 @@ exports[`run test 'split routes' with location '../../test-cases/split-routes' 1 ], "fileName": "index.ts", "id": "ROUTE_TREE:index.ts@103", + "library": "hono", "modules": Set {}, "name": "projects", "position": 103, @@ -1264,6 +1278,7 @@ exports[`run test 'split routes' with location '../../test-cases/split-routes' 1 ], "fileName": "index.ts", "id": "ROUTE_TREE:index.ts@601", + "library": "hono", "modules": Set {}, "name": "app", "position": 601, @@ -1278,6 +1293,7 @@ exports[`run test 'split routes' with location '../../test-cases/split-routes' 1 ], "fileName": "projects.ts", "id": "ROUTE_TREE:projects.ts@36", + "library": "hono", "modules": Set {}, "name": "projects", "position": 36, @@ -1292,6 +1308,7 @@ exports[`run test 'split routes' with location '../../test-cases/split-routes' 1 ], "fileName": "users.ts", "id": "ROUTE_TREE:users.ts@36", + "library": "hono", "modules": Set {}, "name": "users", "position": 36, @@ -1493,3 +1510,230 @@ exports[`run test 'split routes' with location '../../test-cases/split-routes' 1 }, } `; + +exports[`run test 'zod-openapi' with location '../../test-cases/zod-openapi' 1`] = ` +{ + "MODULE_REFERENCE:%40hono%2Fzod-openapi@createRoute": { + "id": "MODULE_REFERENCE:%40hono%2Fzod-openapi@createRoute", + "import": "createRoute", + "importPath": "@hono/zod-openapi", + "name": "@hono/zod-openapi", + "pathId": "@hono/zod-openapi", + "type": "MODULE_REFERENCE", + "version": "0.18.3", + }, + "MODULE_REFERENCE:%40hono%2Fzod-openapi@z": { + "id": "MODULE_REFERENCE:%40hono%2Fzod-openapi@z", + "import": "z", + "importPath": "@hono/zod-openapi", + "name": "@hono/zod-openapi", + "pathId": "@hono/zod-openapi", + "type": "MODULE_REFERENCE", + "version": "0.18.3", + }, + "MODULE_REFERENCE:hono%2Fbasic-auth@basicAuth": { + "id": "MODULE_REFERENCE:hono%2Fbasic-auth@basicAuth", + "import": "basicAuth", + "importPath": "hono/basic-auth", + "name": "hono", + "pathId": "hono/basic-auth", + "type": "MODULE_REFERENCE", + "version": "4.6.9", + }, + "ROUTE_ENTRY:index.ts@1714": { + "fileName": "index.ts", + "id": "ROUTE_ENTRY:index.ts@1714", + "method": "post", + "modules": Set {}, + "path": "/users", + "position": 1714, + "sources": Set { + "SOURCE_REFERENCE:index.ts@949", + }, + "type": "ROUTE_ENTRY", + }, + "ROUTE_ENTRY:index.ts@1972": { + "fileName": "index.ts", + "id": "ROUTE_ENTRY:index.ts@1972", + "method": "get", + "modules": Set {}, + "path": "/users", + "position": 1972, + "sources": Set { + "SOURCE_REFERENCE:index.ts@1987", + }, + "type": "ROUTE_ENTRY", + }, + "ROUTE_ENTRY:index.ts@2980": { + "fileName": "index.ts", + "id": "ROUTE_ENTRY:index.ts@2980", + "method": "get", + "modules": Set {}, + "path": "/", + "position": 2980, + "sources": Set { + "SOURCE_REFERENCE:index.ts@2993", + }, + "type": "ROUTE_ENTRY", + }, + "ROUTE_TREE:index.ts@169": { + "baseUrl": "", + "entries": [ + "ROUTE_ENTRY:index.ts@1714", + "ROUTE_ENTRY:index.ts@1972", + "ROUTE_ENTRY:index.ts@2980", + ], + "fileName": "index.ts", + "id": "ROUTE_TREE:index.ts@169", + "library": "zod-openapi", + "modules": Set {}, + "name": "app", + "position": 169, + "sources": Set {}, + "type": "ROUTE_TREE", + }, + "SOURCE_REFERENCE:index.ts@1987": { + "character": 2, + "content": "createRoute({ + method: "get", + path: "/users", + middleware: [ + basicAuth({ + username: "goose", + password: "honkhonk", + }), + ] as const, // Use \`as const\` to ensure TypeScript infers the middleware's Context correctly + request: {}, + responses: { + 20: { + content: { + "application/json": { + schema: z.Array(UserSchema), + }, + }, + description: "Retrieve all users", + }, + }, + })", + "fileName": "index.ts", + "id": "SOURCE_REFERENCE:index.ts@1987", + "line": 83, + "modules": Set { + "MODULE_REFERENCE:%40hono%2Fzod-openapi@createRoute", + "MODULE_REFERENCE:hono%2Fbasic-auth@basicAuth", + "MODULE_REFERENCE:%40hono%2Fzod-openapi@z", + }, + "position": 1987, + "references": Set { + "SOURCE_REFERENCE:index.ts@621", + }, + "type": "SOURCE_REFERENCE", + }, + "SOURCE_REFERENCE:index.ts@267": { + "character": 6, + "content": "const NewUserSchema = z + .object({ + name: z.string().openapi({ + example: "John Doe", + description: "The name of the user", + }), + age: z.number().openapi({ + example: 42, + }), + }) + .openapi("NewUser")", + "fileName": "index.ts", + "id": "SOURCE_REFERENCE:index.ts@267", + "line": 7, + "modules": Set { + "MODULE_REFERENCE:%40hono%2Fzod-openapi@z", + }, + "position": 267, + "references": Set {}, + "type": "SOURCE_REFERENCE", + }, + "SOURCE_REFERENCE:index.ts@2993": { + "character": 13, + "content": "(c) => { + return c.text("Hello Hono OpenAPI!"); +}", + "fileName": "index.ts", + "id": "SOURCE_REFERENCE:index.ts@2993", + "line": 124, + "modules": Set {}, + "position": 2993, + "references": Set {}, + "type": "SOURCE_REFERENCE", + }, + "SOURCE_REFERENCE:index.ts@621": { + "character": 6, + "content": "const UserSchema = z + .object({ + id: z.number().openapi({ + example: 123, + }), + name: z.string().openapi({ + example: "John Doe", + }), + age: z.number().openapi({ + example: 42, + }), + }) + .openapi("User")", + "fileName": "index.ts", + "id": "SOURCE_REFERENCE:index.ts@621", + "line": 21, + "modules": Set { + "MODULE_REFERENCE:%40hono%2Fzod-openapi@z", + }, + "position": 621, + "references": Set {}, + "type": "SOURCE_REFERENCE", + }, + "SOURCE_REFERENCE:index.ts@949": { + "character": 24, + "content": "const createUserRoute = createRoute({ + method: "post", + path: "/users", + middleware: [ + basicAuth({ + username: "goose", + password: "honkhonk", + }), + ] as const, // Use \`as const\` to ensure TypeScript infers the middleware's Context correctly + request: { + body: { + content: { + "application/json": { + schema: NewUserSchema, + }, + }, + }, + }, + responses: { + 201: { + content: { + "application/json": { + schema: UserSchema, + }, + }, + description: "Retrieve the user", + }, + }, +})", + "fileName": "index.ts", + "id": "SOURCE_REFERENCE:index.ts@949", + "line": 36, + "modules": Set { + "MODULE_REFERENCE:%40hono%2Fzod-openapi@createRoute", + "MODULE_REFERENCE:hono%2Fbasic-auth@basicAuth", + }, + "position": 949, + "references": Set { + "SOURCE_REFERENCE:index.ts@267", + "SOURCE_REFERENCE:index.ts@621", + }, + "type": "SOURCE_REFERENCE", + }, +} +`; diff --git a/packages/source-analysis/src/routeTrees/extractRouteTree.test.ts b/packages/source-analysis/src/routeTrees/extractRouteTree.test.ts index 03bafef82..7780a2dd7 100644 --- a/packages/source-analysis/src/routeTrees/extractRouteTree.test.ts +++ b/packages/source-analysis/src/routeTrees/extractRouteTree.test.ts @@ -6,18 +6,22 @@ test.each([ { name: "single file", location: "../../test-cases/single", + expectedErrorCount: 0, }, { name: "multiple files", location: "../../test-cases/multiple", + expectedErrorCount: 0, }, { name: "module imports", location: "../../test-cases/module-imports", + expectedErrorCount: 0, }, { name: "barrel files", location: "../../test-cases/barrel-files", + expectedErrorCount: 0, }, // { // name: "bindings", @@ -26,6 +30,7 @@ test.each([ { name: "split routes", location: "../../test-cases/split-routes", + expectedErrorCount: 0, }, // { // name: "empty", @@ -34,10 +39,17 @@ test.each([ { name: "hono factory", location: "../../test-cases/hono-factory", + expectedErrorCount: 0, }, { name: "import as", location: "../../test-cases/import-as", + expectedErrorCount: 0, + }, + { + name: "zod-openapi", + location: "../../test-cases/zod-openapi", + expectedErrorCount: 2, }, // The projects below are larger projects which aren't @@ -53,7 +65,7 @@ test.each([ // }, ])( "run test $name with location $location", - async ({ location, name }) => { + async ({ location, name, expectedErrorCount }) => { // Get the exact location const absolutePath = path.join(__dirname, location); // Create a monitor for the routes @@ -65,7 +77,6 @@ test.each([ try { // Start monitoring the filesystem await monitor.start(); - const start = performance.now(); const result = monitor.findHonoRoutes(); console.log( @@ -73,7 +84,7 @@ test.each([ ); // Expect no errors - expect(result.errorCount).toBe(0); + expect(result.errorCount).toBe(expectedErrorCount); // Get all found resources const resources = result.resourceManager.getResources(); diff --git a/packages/source-analysis/src/routeTrees/extractRouteTrees.ts b/packages/source-analysis/src/routeTrees/extractRouteTrees.ts index 82df7ce10..1bdaa5b8d 100644 --- a/packages/source-analysis/src/routeTrees/extractRouteTrees.ts +++ b/packages/source-analysis/src/routeTrees/extractRouteTrees.ts @@ -8,6 +8,7 @@ import { type RouteTree, type RouteTreeReference, type SearchContext, + type SourceReference, type SourceReferenceId, type TsArrowFunction, type TsCallExpression, @@ -17,6 +18,7 @@ import { type TsLanguageService, type TsNode, type TsNodeArray, + type TsPackageType, type TsProgram, type TsReferenceEntry, type TsReturnStatement, @@ -32,19 +34,12 @@ import { findNodeAtPosition } from "./utils"; export function extractRouteTrees( service: TsLanguageService, program: TsProgram, - ts: TsType, + ts: TsPackageType, projectRoot: string, ): { errorCount?: number; resourceManager: ResourceManager; } { - // const now = performance.now(); - // const program = service.getProgram(); - // if (!program) { - // throw new Error("Program not found"); - // } - // logger.log('program', performance.now() - now) - const resourceManager = new ResourceManager(projectRoot); const checker = program.getTypeChecker(); @@ -69,7 +64,7 @@ export function extractRouteTrees( for (const sourceFile of files) { if (!sourceFile.isDeclarationFile) { ts.forEachChild(sourceFile, (node: TsNode) => { - visit(node, sourceFile.fileName, context); + visitToFindRouteTree(node, sourceFile.fileName, context); }); } } @@ -80,8 +75,32 @@ export function extractRouteTrees( }; } -function visit(node: TsNode, fileName: string, context: SearchContext) { - const { ts, checker, resourceManager, service } = context; +function getTypeErrorDetails(type: TsType): string { + const symbol = type.getSymbol(); + if (!symbol) { + return "No symbol found for type"; + } + const declarations = symbol.getDeclarations(); + if (!declarations || declarations.length === 0) { + return "No declarations found for symbol"; + } + return declarations + .map((declaration) => { + const sourceFile = declaration.getSourceFile(); + const { line, character } = sourceFile.getLineAndCharacterOfPosition( + declaration.getStart(), + ); + return `Error in ${sourceFile.fileName} at ${line + 1}:${character + 1}`; + }) + .join("\n"); +} + +function visitToFindRouteTree( + node: TsNode, + fileName: string, + context: SearchContext, +) { + const { ts, checker } = context; if (!ts.isVariableStatement(node)) { return; } @@ -94,68 +113,117 @@ function visit(node: TsNode, fileName: string, context: SearchContext) { if ("intrinsicName" in type && type.intrinsicName === "error") { context.errorCount++; - logger.error("Error in type check"); - logger.error("In: ", node.getSourceFile().fileName, node.kind); - logger.error("Node text:", node.getFullText()); - logger.error("type information", type.getSymbol()); + logger.info("Error in type check"); + const prettyLocation = node + .getSourceFile() + .getLineAndCharacterOfPosition(node.getStart()); + logger.info( + `Location: /${node.getSourceFile().fileName}:${prettyLocation.line + 1}:${prettyLocation.character + 1}`, + ); + logger.debug("Syntax kind:", ts.SyntaxKind[node.kind]); + logger.debug("Type error details:", getTypeErrorDetails(type)); } const typeName = checker.typeToString(type); if (typeName.startsWith("Hono<")) { - // TODO: use the type information to get the name of the hono instance - // TODO: (edge case) handle reassignments of the same variable. It's possible reuse a variable for different hono instances - const honoInstanceName = declaration.name.getText(); - const position = declaration.name.getStart(); - const params = { - type: "ROUTE_TREE" as const, - baseUrl: "", - name: honoInstanceName, - fileName: resourceManager.asRelativePath(node.getSourceFile().fileName), - position, - entries: [], - modules: new Set<ModuleReferenceId>(), - sources: new Set<SourceReferenceId>(), - }; + handleHonoAppInstance(declaration, node, fileName, context); + } else if (typeName.startsWith("OpenAPIHono<")) { + handleOpenApiHonoInstance(declaration, node, fileName, context); + } + } +} - const current = resourceManager.createRouteTree(params); - - // TODO: add support for late initialization of the hono instance - // What if people do something like: - // - // ``` ts - // let app: Hono; - // app = new Hono(); - // ``` - // - // Or have some other kind of initialization: - // - // ``` ts - // let app: Hono; - // app = createApp(); - // ``` - - if ( - declaration.initializer && - ts.isCallExpression(declaration.initializer) - ) { - handleInitializerCallExpression( - declaration.initializer, - current, - context, - ); - } +function handleOpenApiHonoInstance( + declaration: TsVariableDeclaration, + node: TsNode, + fileName: string, + context: SearchContext, +) { + const { ts, resourceManager, service } = context; + + const honoInstanceName = declaration.name.getText(); + const position = declaration.name.getStart(); + const params = { + type: "ROUTE_TREE" as const, + baseUrl: "", + name: honoInstanceName, + fileName: resourceManager.asRelativePath(node.getSourceFile().fileName), + position, + entries: [], + library: "zod-openapi" as const, + modules: new Set<ModuleReferenceId>(), + sources: new Set<SourceReferenceId>(), + }; - const references = ( - service.getReferencesAtPosition(fileName, position) ?? [] - ).filter( - (reference) => - reference.fileName === fileName && - reference.textSpan.start !== position, - ); - for (const entry of references) { - followReference(current, entry, context); - } - } + const current = resourceManager.createRouteTree(params); + if (declaration.initializer && ts.isCallExpression(declaration.initializer)) { + handleInitializerCallExpression(declaration.initializer, current, context); + } + + const references = ( + service.getReferencesAtPosition(fileName, position) ?? [] + ).filter( + (reference) => + reference.fileName === fileName && reference.textSpan.start !== position, + ); + + for (const entry of references) { + followReference(current, entry, context, handleOpenApiHonoMethodCall); + } +} + +function handleHonoAppInstance( + declaration: TsVariableDeclaration, + node: TsNode, + fileName: string, + context: SearchContext, +) { + const { ts, resourceManager, service } = context; + // TODO: use the type information to get the name of the hono instance + // TODO: (edge case) handle reassignments of the same variable. It's possible reuse a variable for different hono instances + const honoInstanceName = declaration.name.getText(); + const position = declaration.name.getStart(); + const params = { + type: "ROUTE_TREE" as const, + baseUrl: "", + name: honoInstanceName, + fileName: resourceManager.asRelativePath(node.getSourceFile().fileName), + position, + entries: [], + library: "hono" as const, + modules: new Set<ModuleReferenceId>(), + sources: new Set<SourceReferenceId>(), + }; + + const current = resourceManager.createRouteTree(params); + + // TODO: add support for late initialization of the hono instance + // What if people do something like: + // + // ``` ts + // let app: Hono; + // app = new Hono(); + // ``` + // + // Or have some other kind of initialization: + // + // ``` ts + // let app: Hono; + // app = createApp(); + // ``` + + if (declaration.initializer && ts.isCallExpression(declaration.initializer)) { + handleInitializerCallExpression(declaration.initializer, current, context); + } + + const references = ( + service.getReferencesAtPosition(fileName, position) ?? [] + ).filter( + (reference) => + reference.fileName === fileName && reference.textSpan.start !== position, + ); + for (const entry of references) { + followReference(current, entry, context, handleHonoMethodCall); } } @@ -194,7 +262,7 @@ function handleInitializerCallExpression( ) { const functionBody = functionNode.parent.body; functionBody.forEachChild((child) => { - visit(child, declarationFileName, context); + visitToFindRouteTree(child, declarationFileName, context); }); // Now find the return statements in the function body to construct the route tree reference @@ -232,6 +300,12 @@ function followReference( routeTree: RouteTree, reference: TsReferenceEntry, context: SearchContext, + handleMethodCall: ( + callExpression: TsCallExpression, + methodName: string, + routeTree: RouteTree, + context: SearchContext, + ) => void, ) { const { getFile, ts } = context; @@ -256,6 +330,92 @@ function followReference( ts.isCallExpression(callExpression) ) { const methodName = accessExpression.name.text; + handleMethodCall(callExpression, methodName, routeTree, context); + } +} +// function followHonoAppReference( +// routeTree: RouteTree, +// reference: TsReferenceEntry, +// context: SearchContext, +// ) { +// followReference(routeTree, reference, context, handleHonoMethodCall); +// } + +function handleOpenApiHonoMethodCall( + callExpression: TsCallExpression, + methodName: string, + routeTree: RouteTree, + context: SearchContext, +) { + const { ts, resourceManager } = context; + if (methodName === "openapi") { + const [firstArgument] = callExpression.arguments; + if (!firstArgument) { + return; + } + + if (ts.isIdentifier(firstArgument)) { + const symbol = context.checker.getSymbolAtLocation(firstArgument); + const declaration = symbol?.valueDeclaration; + if (declaration && ts.isVariableDeclaration(declaration)) { + const initializer = declaration.initializer; + if (!initializer || !ts.isCallExpression(initializer)) { + return; + } + + const { + method, + path, + sourceReferencesIds = new Set(), + } = getOpenApiRouteDetailsFromCallExpression(initializer, context); + if (path) { + const params: Omit<RouteEntry, "id"> = { + type: "ROUTE_ENTRY", + fileName: callExpression.getSourceFile().fileName, + position: callExpression.getStart(), + method: method && isHonoMethod(method) ? method : undefined, + path, + modules: new Set(), + sources: sourceReferencesIds, + }; + + const entry = resourceManager.createRouteEntry(params); + + // Add the tree node to the list of entries + // Later the entry will be filled with source references + routeTree.entries.push(entry.id); + } + } + } else if (ts.isCallExpression(firstArgument)) { + const { + method, + path, + sourceReferencesIds = new Set(), + } = getOpenApiRouteDetailsFromCallExpression(firstArgument, context); + if (path) { + const params: Omit<RouteEntry, "id"> = { + type: "ROUTE_ENTRY", + fileName: callExpression.getSourceFile().fileName, + position: callExpression.getStart(), + method: method && isHonoMethod(method) ? method : undefined, + path, + modules: new Set(), + sources: sourceReferencesIds, + }; + + const entry = resourceManager.createRouteEntry(params); + + // Add the tree node to the list of entries + // Later the entry will be filled with source references + routeTree.entries.push(entry.id); + } + } else { + logger.warn( + "Unsupported firstArgument", + ts.SyntaxKind[firstArgument.kind], + ); + } + } else { handleHonoMethodCall(callExpression, methodName, routeTree, context); } } @@ -266,7 +426,7 @@ function handleHonoMethodCall( routeTree: RouteTree, context: SearchContext, ) { - const { ts, resourceManager, checker } = context; + const { ts, resourceManager } = context; if (methodName === "route") { return handleRoute(callExpression, routeTree, context); @@ -330,18 +490,21 @@ function handleHonoMethodCall( function expandTemplateLiteral( template: TsNode, - context: SearchContext + context: SearchContext, ): string { - const { ts, checker } = context; + const { ts } = context; let result = ""; template.forEachChild((child) => { - if (ts.isTemplateHead(child) || ts.isTemplateMiddle(child) || ts.isTemplateTail(child)) { + if ( + ts.isTemplateHead(child) || + ts.isTemplateMiddle(child) || + ts.isTemplateTail(child) + ) { result += child.text; } else if (ts.isTemplateSpan(child)) { const expression = child.expression; const value = getExpressionValue(expression, context); - console.log('value', value) result += value; result += child.literal.text; } else if (ts.isExpression(child)) { @@ -353,11 +516,17 @@ function expandTemplateLiteral( return result; } -function getExpressionValue(expression: TsNode, context: SearchContext): string { +function getExpressionValue( + expression: TsNode, + context: SearchContext, +): string { const { checker, ts } = context; let constantValue: string | number | undefined; - console.log('expression', ts.SyntaxKind[expression.kind], expression.getText()); - if (ts.isPropertyAccessExpression(expression) || ts.isElementAccessExpression(expression) || ts.isEnumMember(expression)) { + if ( + ts.isPropertyAccessExpression(expression) || + ts.isElementAccessExpression(expression) || + ts.isEnumMember(expression) + ) { constantValue = checker.getConstantValue(expression); } @@ -556,7 +725,6 @@ function analyzeReturnStatement( if (ts.isIdentifier(node)) { const symbol = checker.getSymbolAtLocation(node); const declaration = symbol?.declarations?.[0]; - // logger.log('declaration', declaration && ts.SyntaxKind[declaration.kind]) if (declaration && ts.isVariableDeclaration(declaration)) { variables.push(declaration); } @@ -574,3 +742,66 @@ function analyzeReturnStatement( function isAlias(symbol: TsSymbol, context: SearchContext) { return symbol.flags === context.ts.SymbolFlags.Alias; } + +function getOpenApiRouteDetailsFromCallExpression( + callExpression: TsCallExpression, + context: SearchContext, +): { + method?: string | undefined; + path?: string | undefined; + sourceReferencesIds?: Set<SourceReferenceId>; +} { + const { ts } = context; + + let rootSourceReference: null | SourceReference = null; + + if ( + !ts.isIdentifier(callExpression.expression) || + callExpression.expression.text !== "createRoute" + ) { + logger.warn( + "Unsupported call expression for open api route declaration", + callExpression.getText(), + ); + return {}; + } + + const [routeConfig] = callExpression.arguments; + if (!routeConfig || !ts.isObjectLiteralExpression(routeConfig)) { + logger.warn( + "Unsupported route config parameter for open api route declaration", + routeConfig?.getText(), + ); + return {}; + } + + let method: string | undefined; + let path: string | undefined; + + for (const property of routeConfig.properties) { + if (!ts.isPropertyAssignment(property) || !ts.isIdentifier(property.name)) { + continue; + } + + const name = property.name.text; + if (name === "method" && ts.isStringLiteral(property.initializer)) { + method = property.initializer.text; + } else if (name === "path" && ts.isStringLiteral(property.initializer)) { + path = property.initializer.text; + } + } + rootSourceReference = createSourceReferenceForNode(callExpression, context); + + let sourceReferencesIds: Set<SourceReferenceId>; + if (rootSourceReference) { + sourceReferencesIds = new Set([rootSourceReference.id]); + } else { + sourceReferencesIds = new Set(); + } + + return { + method, + path, + sourceReferencesIds, + }; +} diff --git a/packages/source-analysis/src/routeTrees/utils.ts b/packages/source-analysis/src/routeTrees/utils.ts index 53a116658..c433acb3d 100644 --- a/packages/source-analysis/src/routeTrees/utils.ts +++ b/packages/source-analysis/src/routeTrees/utils.ts @@ -3,12 +3,12 @@ import type { ModuleReference, TsModuleResolutionHost, TsNode, + TsPackageType, TsSourceFile, - TsType, } from "../types"; export function findNodeAtPosition( - ts: TsType, + ts: TsPackageType, sourceFile: TsSourceFile, position: number, ): TsNode | undefined { diff --git a/packages/source-analysis/src/service.ts b/packages/source-analysis/src/service.ts index 219eb745c..1aed57a03 100644 --- a/packages/source-analysis/src/service.ts +++ b/packages/source-analysis/src/service.ts @@ -7,13 +7,14 @@ import type { TsCompilerOptions, TsISnapShot, TsLanguageServiceHost, - TsType, + TsPackageType, } from "./types"; + const relativeResolve = relative.sync; export function getParsedTsConfig( location: string, - ts: TsType, + ts: TsPackageType, ): ConfigFileContent { const configPath = ts.findConfigFile( location, @@ -38,7 +39,10 @@ export function getParsedTsConfig( }; } -export function getOptions(location: string, ts: TsType): TsCompilerOptions { +export function getOptions( + location: string, + ts: TsPackageType, +): TsCompilerOptions { const { options } = getParsedTsConfig(location, ts); if (!options.baseUrl) { options.baseUrl = location; @@ -81,7 +85,7 @@ export function startServer(params: { getScriptSnapshot: (fileName: string) => TsISnapShot | undefined; location: string; readFile: (fileName: string) => string | undefined; - ts: TsType; + ts: TsPackageType; }) { const { directoryExists, diff --git a/packages/source-analysis/src/types.ts b/packages/source-analysis/src/types.ts index 86c159ee7..15b7d6bf5 100644 --- a/packages/source-analysis/src/types.ts +++ b/packages/source-analysis/src/types.ts @@ -7,7 +7,7 @@ export const bundledTypescript = bundledTs; export const relativeResolve = relative.sync; // Alias some exported typescript types -export type TsType = typeof bundledTs; +export type TsPackageType = typeof bundledTs; export type TsArrowFunction = bundledTs.ArrowFunction; export type TsCallExpression = bundledTs.CallExpression; export type TsCompilerOptions = bundledTs.CompilerOptions; @@ -40,6 +40,7 @@ export type ConfigFileContent = Pick< > & { configPath?: string; }; +export type TsType = bundledTs.Type; export type RouteTreeId = Tagged<string, "RouteTreeId">; export type RouteTreeReferenceId = Tagged<string, "RouteTreeReferenceId">; @@ -76,6 +77,7 @@ export type RouteTree = { sources: Set<SourceReferenceId>; modules: Set<ModuleReferenceId>; + library: "hono" | "zod-openapi"; } & FileReference; export type RouteTreeReference = { @@ -211,7 +213,7 @@ export type LocalFileResourceId = LocalFileResource["id"]; export type SearchContext = { resourceManager: ResourceManager; service: TsLanguageService; - ts: TsType; + ts: TsPackageType; errorCount: number; program: TsProgram; checker: TsTypeChecker; diff --git a/packages/source-analysis/src/utils.ts b/packages/source-analysis/src/utils.ts index fca1330d4..b8d7722bf 100644 --- a/packages/source-analysis/src/utils.ts +++ b/packages/source-analysis/src/utils.ts @@ -1,6 +1,6 @@ import path from "node:path"; import { logger } from "./logger"; -import type { TsNode, TsType, TsTypeChecker } from "./types"; +import type { TsNode, TsPackageType, TsTypeChecker } from "./types"; /** * Gets the file uri to be used in the typescript language server @@ -39,7 +39,7 @@ export function isSubpath(parentPath: string, subPath: string): boolean { export function debugSymbolAtLocation( node: TsNode, checker: TsTypeChecker, - ts: TsType, + ts: TsPackageType, ) { function logSymbolInfo(node: TsNode, depth: number) { const symbol = checker.getSymbolAtLocation(node); @@ -56,3 +56,19 @@ export function debugSymbolAtLocation( logSymbolInfo(node, 8); // Adjust depth as needed } + +export function debounce< + T extends (...args: Array<unknown>) => void | Promise<void>, +>(func: T, wait: number): (...args: Parameters<T>) => void { + let timeout: ReturnType<typeof setTimeout> | null = null; + + return (...args: Parameters<T>) => { + if (timeout !== null) { + clearTimeout(timeout); + } + + timeout = setTimeout(() => { + func(...args); + }, wait); + }; +} diff --git a/packages/source-analysis/test-cases/single/index.ts b/packages/source-analysis/test-cases/single/index.ts index 7e626b02e..6abe869b5 100644 --- a/packages/source-analysis/test-cases/single/index.ts +++ b/packages/source-analysis/test-cases/single/index.ts @@ -1,9 +1,11 @@ import { Hono } from "hono"; const app = new Hono(); -const LITERAL = "literal" +const LITERAL = "literal"; app.get("/", (c) => c.text("Hello, Hono!")); -app.post('/single-quote', (c) => c.text("Hello, 'Hono'!")); -app.put(`/${LITERAL}-template-${LITERAL}-stuff`, (c) => c.text("Hello, `${Hono}`!")); +app.post("/single-quote", (c) => c.text("Hello, 'Hono'!")); +app.put(`/${LITERAL}-template-${LITERAL}-stuff`, (c) => + c.text("Hello, `${Hono}`!"), +); export default app; diff --git a/packages/source-analysis/test-cases/zod-openapi/index.ts b/packages/source-analysis/test-cases/zod-openapi/index.ts new file mode 100644 index 000000000..35de21730 --- /dev/null +++ b/packages/source-analysis/test-cases/zod-openapi/index.ts @@ -0,0 +1,129 @@ +import { instrument } from "@fiberplane/hono-otel"; +import { OpenAPIHono, createRoute, z } from "@hono/zod-openapi"; +import { basicAuth } from "hono/basic-auth"; + +const app = new OpenAPIHono(); + +// Schema that defines the body of a request to create a new user +const NewUserSchema = z + .object({ + name: z.string().openapi({ + example: "John Doe", + description: "The name of the user", + }), + age: z.number().openapi({ + example: 42, + }), + }) + .openapi("NewUser"); + +// Schema that defines the response of a request to get a user +// TODO - Figure out how to extend the NewUserSchema object +const UserSchema = z + .object({ + id: z.number().openapi({ + example: 123, + }), + name: z.string().openapi({ + example: "John Doe", + }), + age: z.number().openapi({ + example: 42, + }), + }) + .openapi("User"); + +// Define the request/response schema for a route to create a new user +const createUserRoute = createRoute({ + method: "post", + path: "/users", + middleware: [ + basicAuth({ + username: "goose", + password: "honkhonk", + }), + ] as const, // Use `as const` to ensure TypeScript infers the middleware's Context correctly + request: { + body: { + content: { + "application/json": { + schema: NewUserSchema, + }, + }, + }, + }, + responses: { + 201: { + content: { + "application/json": { + schema: UserSchema, + }, + }, + description: "Retrieve the user", + }, + }, +}); + +// Register the basic auth security scheme +app.openAPIRegistry.registerComponent("securitySchemes", "basicAuth", { + type: "http", + scheme: "basic", +}); + +// Define the handler for a route to create a new user +app.openapi(createUserRoute, async (c) => { + const { name, age } = c.req.valid("json"); + // Store the name and age in the database + // but for now, just return the input + const result = { name, age }; + return c.json(result, 201); +}); + +// List all users +app.openapi( + createRoute({ + method: "get", + path: "/users", + middleware: [ + basicAuth({ + username: "goose", + password: "honkhonk", + }), + ] as const, // Use `as const` to ensure TypeScript infers the middleware's Context correctly + request: {}, + responses: { + 20: { + content: { + "application/json": { + schema: z.Array(UserSchema), + }, + }, + description: "Retrieve all users", + }, + }, + }), + async (c) => { + const { name, age } = c.req.valid("json"); + // Store the name and age in the database + // but for now, just return the input + const result = { name, age }; + return c.json([result], 200); + }, +); + +// Mount the api documentation +// The OpenAPI documentation will be available at /doc +app.doc("/doc", { + openapi: "3.0.0", + info: { + version: "1.0.0", + title: "Simple Hono OpenAPI API", + }, +}); + +// Define a simple route to test the API (this is not part of the OpenAPI spec) +app.get("/", (c) => { + return c.text("Hello Hono OpenAPI!"); +}); + +export default instrument(app); diff --git a/packages/source-analysis/test-cases/zod-openapi/tsconfig.json b/packages/source-analysis/test-cases/zod-openapi/tsconfig.json new file mode 100644 index 000000000..1dbd49784 --- /dev/null +++ b/packages/source-analysis/test-cases/zod-openapi/tsconfig.json @@ -0,0 +1,19 @@ +{ + "compilerOptions": { + "target": "ES2020", + "module": "ESNext", + "moduleResolution": "Node", + "strict": true, + "skipLibCheck": true, + "lib": ["ESNext"], + "esModuleInterop": true, + "outDir": "./dist", + "rootDir": "./src", + "declaration": true, + "noUnusedLocals": true, + "noUnusedParameters": true, + "noUncheckedIndexedAccess": true, + "exactOptionalPropertyTypes": true, + "noPropertyAccessFromIndexSignature": true + }, +} diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index aa6ff961f..68c19ed89 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -22,7 +22,7 @@ importers: version: 5.5.4 wrangler: specifier: ^3.73.0 - version: 3.73.0(@cloudflare/workers-types@4.20241112.0) + version: 3.73.0(@cloudflare/workers-types@4.20241127.0) api: dependencies: @@ -256,14 +256,14 @@ importers: version: 16.4.5 drizzle-orm: specifier: ^0.36.0 - version: 0.36.4(@cloudflare/workers-types@4.20241112.0)(@libsql/client-wasm@0.14.0)(@libsql/client@0.14.0)(@neondatabase/serverless@0.10.1)(@opentelemetry/api@1.9.0)(@types/pg@8.11.10)(@types/react@18.3.3)(react@18.3.1) + version: 0.36.4(@cloudflare/workers-types@4.20241127.0)(@libsql/client-wasm@0.14.0)(@libsql/client@0.14.0)(@neondatabase/serverless@0.10.1)(@opentelemetry/api@1.9.0)(@types/pg@8.11.10)(@types/react@18.3.3)(react@18.3.1) hono: specifier: ^4.6.7 version: 4.6.9 devDependencies: '@cloudflare/workers-types': specifier: ^4.20241106.0 - version: 4.20241112.0 + version: 4.20241127.0 '@fiberplane/hono-otel': specifier: workspace:* version: link:../../../packages/client-library-otel @@ -272,7 +272,7 @@ importers: version: 4.19.2 wrangler: specifier: ^3.87.0 - version: 3.90.0(@cloudflare/workers-types@4.20241112.0) + version: 3.91.0(@cloudflare/workers-types@4.20241127.0) examples/service-bindings/woof: dependencies: @@ -281,14 +281,14 @@ importers: version: 16.4.5 drizzle-orm: specifier: ^0.36.0 - version: 0.36.4(@cloudflare/workers-types@4.20241112.0)(@libsql/client-wasm@0.14.0)(@libsql/client@0.14.0)(@neondatabase/serverless@0.10.1)(@opentelemetry/api@1.9.0)(@types/pg@8.11.10)(@types/react@18.3.3)(react@18.3.1) + version: 0.36.4(@cloudflare/workers-types@4.20241127.0)(@libsql/client-wasm@0.14.0)(@libsql/client@0.14.0)(@neondatabase/serverless@0.10.1)(@opentelemetry/api@1.9.0)(@types/pg@8.11.10)(@types/react@18.3.3)(react@18.3.1) devDependencies: '@cloudflare/workers-types': specifier: ^4.20241106.0 - version: 4.20241112.0 + version: 4.20241127.0 wrangler: specifier: ^3.87.0 - version: 3.90.0(@cloudflare/workers-types@4.20241112.0) + version: 3.91.0(@cloudflare/workers-types@4.20241127.0) examples/test-static-analysis: dependencies: @@ -334,7 +334,7 @@ importers: version: 0.14.0 ai: specifier: ^3.4.10 - version: 3.4.20(openai@4.68.4(encoding@0.1.13)(zod@3.23.8))(react@18.3.1)(sswr@2.1.0(svelte@4.2.19))(svelte@4.2.19)(vue@3.5.12(typescript@5.6.3))(zod@3.23.8) + version: 3.4.20(openai@4.68.4(encoding@0.1.13)(zod@3.23.8))(react@18.3.1)(sswr@2.1.0(svelte@4.2.19))(svelte@4.2.19)(vue@3.5.12(typescript@5.7.2))(zod@3.23.8) dotenv: specifier: ^16.4.5 version: 16.4.5 @@ -739,7 +739,7 @@ importers: devDependencies: '@darkobits/vite-plugin-favicons': specifier: ^0.3.2 - version: 0.3.2(typescript@5.6.3)(vite@5.4.10(@types/node@20.14.15)(lightningcss@1.28.1)) + version: 0.3.2(typescript@5.7.2)(vite@5.4.10(@types/node@20.14.15)(lightningcss@1.28.1)) '@iconify/react': specifier: ^5.0.2 version: 5.0.2(react@18.3.1) @@ -769,10 +769,10 @@ importers: version: 5.4.10(@types/node@20.14.15)(lightningcss@1.28.1) vite-plugin-svgr: specifier: ^4.2.0 - version: 4.2.0(rollup@4.24.0)(typescript@5.6.3)(vite@5.4.10(@types/node@20.14.15)(lightningcss@1.28.1)) + version: 4.2.0(rollup@4.24.0)(typescript@5.7.2)(vite@5.4.10(@types/node@20.14.15)(lightningcss@1.28.1)) vite-tsconfig-paths: specifier: ^4.3.2 - version: 4.3.2(typescript@5.6.3)(vite@5.4.10(@types/node@20.14.15)(lightningcss@1.28.1)) + version: 4.3.2(typescript@5.7.2)(vite@5.4.10(@types/node@20.14.15)(lightningcss@1.28.1)) vitest: specifier: ^1.6.0 version: 1.6.0(@types/node@20.14.15)(lightningcss@1.28.1) @@ -794,13 +794,13 @@ importers: devDependencies: '@cloudflare/workers-types': specifier: ^4.20241004.0 - version: 4.20241022.0 + version: 4.20241127.0 typescript: specifier: ^5.5.3 version: 5.5.4 wrangler: specifier: ^3.88.0 - version: 3.91.0(@cloudflare/workers-types@4.20241022.0) + version: 3.91.0(@cloudflare/workers-types@4.20241127.0) www: dependencies: @@ -858,7 +858,7 @@ importers: version: 0.14.1 wrangler: specifier: ^3.78.5 - version: 3.78.5(@cloudflare/workers-types@4.20241112.0) + version: 3.78.5(@cloudflare/workers-types@4.20241127.0) packages: @@ -1233,34 +1233,18 @@ packages: resolution: {integrity: sha512-gVPW8YLz92ZeCibQH2QUw96odJoiM3k/ZPH3f2HxptozmH6+OnyyvKXo/Egg39HAM230akarQKHf0W74UHlh0Q==} engines: {node: '>=16'} - '@babel/code-frame@7.24.7': - resolution: {integrity: sha512-BcYH1CVJBO9tvyIZ2jVeXgSIMvGZ2FDRvDdOIVQyuklNKSsx+eppDEBq/g47Ayw+RqNFE+URvOShmf+f/qwAlA==} - engines: {node: '>=6.9.0'} - '@babel/code-frame@7.26.0': resolution: {integrity: sha512-INCKxTtbXtcNbUZ3YXutwMpEleqttcswhAdee7dhuoVrD2cnuc3PqtERBtxkX5nziX9vnBL8WXmSGwv8CuPV6g==} engines: {node: '>=6.9.0'} - '@babel/compat-data@7.25.2': - resolution: {integrity: sha512-bYcppcpKBvX4znYaPEeFau03bp89ShqNMLs+rmdptMw+heSZh9+z84d2YG+K7cYLbWwzdjtDoW/uqZmPjulClQ==} - engines: {node: '>=6.9.0'} - '@babel/compat-data@7.26.0': resolution: {integrity: sha512-qETICbZSLe7uXv9VE8T/RWOdIE5qqyTucOt4zLYMafj2MRO271VGgLd4RACJMeBO37UPWhXiKMBk7YlJ0fOzQA==} engines: {node: '>=6.9.0'} - '@babel/core@7.25.2': - resolution: {integrity: sha512-BBt3opiCOxUr9euZ5/ro/Xv8/V7yJ5bjYMqG/C1YAo8MIKAnumZalCN+msbci3Pigy4lIQfPUpfMM27HMGaYEA==} - engines: {node: '>=6.9.0'} - '@babel/core@7.26.0': resolution: {integrity: sha512-i1SLeK+DzNnQ3LL/CswPCa/E5u4lh1k6IAEphON8F+cXt0t9euTshDru0q7/IqMa1PMPz5RnHuHscF8/ZJsStg==} engines: {node: '>=6.9.0'} - '@babel/generator@7.25.0': - resolution: {integrity: sha512-3LEEcj3PVW8pW2R1SR1M89g/qrYk/m/mB/tLqn7dn4sbBUQyTqnlod+II2U4dqiGtUmkcnAmkMDralTFZttRiw==} - engines: {node: '>=6.9.0'} - '@babel/generator@7.26.0': resolution: {integrity: sha512-/AIkAmInnWwgEAJGQr9vY0c66Mj6kjkE2ZPB1PurTRaRAh3U+J45sAQMjQDJdh4WbR3l0x5xkimXBKyBXXAu2w==} engines: {node: '>=6.9.0'} @@ -1269,28 +1253,14 @@ packages: resolution: {integrity: sha512-gv7320KBUFJz1RnylIg5WWYPRXKZ884AGkYpgpWW02TH66Dl+HaC1t1CKd0z3R4b6hdYEcmrNZHUmfCP+1u3/g==} engines: {node: '>=6.9.0'} - '@babel/helper-compilation-targets@7.25.2': - resolution: {integrity: sha512-U2U5LsSaZ7TAt3cfaymQ8WHh0pxvdHoEk6HVpaexxixjyEquMh0L0YNJNM6CTGKMXV1iksi0iZkGw4AcFkPaaw==} - engines: {node: '>=6.9.0'} - '@babel/helper-compilation-targets@7.25.9': resolution: {integrity: sha512-j9Db8Suy6yV/VHa4qzrj9yZfZxhLWQdVnRlXxmKLYlhWUVB1sB2G5sxuWYXk/whHD9iW76PmNzxZ4UCnTQTVEQ==} engines: {node: '>=6.9.0'} - '@babel/helper-module-imports@7.24.7': - resolution: {integrity: sha512-8AyH3C+74cgCVVXow/myrynrAGv+nTVg5vKu2nZph9x7RcRwzmh0VFallJuFTZ9mx6u4eSdXZfcOzSqTUm0HCA==} - engines: {node: '>=6.9.0'} - '@babel/helper-module-imports@7.25.9': resolution: {integrity: sha512-tnUA4RsrmflIM6W6RFTLFSXITtl0wKjgpnLgXyowocVPrbYrLUXSBXDgTs8BlbmIzIdlBySRQjINYs2BAkiLtw==} engines: {node: '>=6.9.0'} - '@babel/helper-module-transforms@7.25.2': - resolution: {integrity: sha512-BjyRAbix6j/wv83ftcVJmBt72QtHI56C7JXZoG2xATiLpmoC7dpd8WnkikExHDVPpi/3qCmO6WY1EaXOluiecQ==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0 - '@babel/helper-module-transforms@7.26.0': resolution: {integrity: sha512-xO+xu6B5K2czEnQye6BHA7DolFFmS3LB7stHZFaOLb1pAwO1HWLS8fXA+eh0A2yIvltPVmx3eNNDBJA2SLHXFw==} engines: {node: '>=6.9.0'} @@ -1301,51 +1271,22 @@ packages: resolution: {integrity: sha512-kSMlyUVdWe25rEsRGviIgOWnoT/nfABVWlqt9N19/dIPWViAOW2s9wznP5tURbs/IDuNk4gPy3YdYRgH3uxhBw==} engines: {node: '>=6.9.0'} - '@babel/helper-simple-access@7.24.7': - resolution: {integrity: sha512-zBAIvbCMh5Ts+b86r/CjU+4XGYIs+R1j951gxI3KmmxBMhCg4oQMsv6ZXQ64XOm/cvzfU1FmoCyt6+owc5QMYg==} - engines: {node: '>=6.9.0'} - - '@babel/helper-string-parser@7.24.8': - resolution: {integrity: sha512-pO9KhhRcuUyGnJWwyEgnRJTSIZHiT+vMD0kPeD+so0l7mxkMT19g3pjY9GTnHySck/hDzq+dtW/4VgnMkippsQ==} - engines: {node: '>=6.9.0'} - '@babel/helper-string-parser@7.25.9': resolution: {integrity: sha512-4A/SCr/2KLd5jrtOMFzaKjVtAei3+2r/NChoBNoZ3EyP/+GlhoaEGoWOZUmFmoITP7zOJyHIMm+DYRd8o3PvHA==} engines: {node: '>=6.9.0'} - '@babel/helper-validator-identifier@7.24.7': - resolution: {integrity: sha512-rR+PBcQ1SMQDDyF6X0wxtG8QyLCgUB0eRAGguqRLfkCA87l7yAP7ehq8SNj96OOGTO8OBV70KhuFYcIkHXOg0w==} - engines: {node: '>=6.9.0'} - '@babel/helper-validator-identifier@7.25.9': resolution: {integrity: sha512-Ed61U6XJc3CVRfkERJWDz4dJwKe7iLmmJsbOGu9wSloNSFttHV0I8g6UAgb7qnK5ly5bGLPd4oXZlxCdANBOWQ==} engines: {node: '>=6.9.0'} - '@babel/helper-validator-option@7.24.8': - resolution: {integrity: sha512-xb8t9tD1MHLungh/AIoWYN+gVHaB9kwlu8gffXGSt3FFEIT7RjS+xWbc2vUD1UTZdIpKj/ab3rdqJ7ufngyi2Q==} - engines: {node: '>=6.9.0'} - '@babel/helper-validator-option@7.25.9': resolution: {integrity: sha512-e/zv1co8pp55dNdEcCynfj9X7nyUKUXoUEwfXqaZt0omVOmDe9oOTdKStH4GmAw6zxMFs50ZayuMfHDKlO7Tfw==} engines: {node: '>=6.9.0'} - '@babel/helpers@7.25.0': - resolution: {integrity: sha512-MjgLZ42aCm0oGjJj8CtSM3DB8NOOf8h2l7DCTePJs29u+v7yO/RBX9nShlKMgFnRks/Q4tBAe7Hxnov9VkGwLw==} - engines: {node: '>=6.9.0'} - '@babel/helpers@7.26.0': resolution: {integrity: sha512-tbhNuIxNcVb21pInl3ZSjksLCvgdZy9KwJ8brv993QtIVKJBBkYXz4q4ZbAv31GdnC+R90np23L5FbEBlthAEw==} engines: {node: '>=6.9.0'} - '@babel/highlight@7.24.7': - resolution: {integrity: sha512-EStJpq4OuY8xYfhGVXngigBJRWxftKX9ksiGDnmlY3o7B/V7KIAc9X4oiK87uPJSc/vs5L869bem5fhZa8caZw==} - engines: {node: '>=6.9.0'} - - '@babel/parser@7.25.3': - resolution: {integrity: sha512-iLTJKDbJ4hMvFPgQwwsVoxtHyWpKKPBrxkANrSYewDPaPpT5py5yeVkgPIJ7XYXhndxJpaA3PyALSXQ7u8e/Dw==} - engines: {node: '>=6.0.0'} - hasBin: true - '@babel/parser@7.25.6': resolution: {integrity: sha512-trGdfBdbD0l1ZPmcJ83eNxB9rbEax4ALFTF7fN386TMYbeCQbyme5cOEXQhbGXKebwGaB/J52w1mrklMcbgy6Q==} engines: {node: '>=6.0.0'} @@ -1372,30 +1313,14 @@ packages: resolution: {integrity: sha512-DSgLeL/FNcpXuzav5wfYvHCGvynXkJbn3Zvc3823AEe9nPwW9IK4UoCSS5yGymmQzN0pCPvivtgS6/8U2kkm1w==} engines: {node: '>=6.9.0'} - '@babel/template@7.25.0': - resolution: {integrity: sha512-aOOgh1/5XzKvg1jvVz7AVrx2piJ2XBi227DHmbY6y+bM9H2FlN+IfecYu4Xl0cNiiVejlsCri89LUsbj8vJD9Q==} - engines: {node: '>=6.9.0'} - '@babel/template@7.25.9': resolution: {integrity: sha512-9DGttpmPvIxBb/2uwpVo3dqJ+O6RooAFOS+lB+xDqoE2PVCE8nfoHMdZLpfCQRLwvohzXISPZcgxt80xLfsuwg==} engines: {node: '>=6.9.0'} - '@babel/traverse@7.25.3': - resolution: {integrity: sha512-HefgyP1x754oGCsKmV5reSmtV7IXj/kpaE1XYY+D9G5PvKKoFfSbiS4M77MdjuwlZKDIKFCffq9rPU+H/s3ZdQ==} - engines: {node: '>=6.9.0'} - '@babel/traverse@7.25.9': resolution: {integrity: sha512-ZCuvfwOwlz/bawvAuvcj8rrithP2/N55Tzz342AkTvq4qaWbGfmCk/tKhNaV2cthijKrPAA8SRJV5WWe7IBMJw==} engines: {node: '>=6.9.0'} - '@babel/types@7.25.2': - resolution: {integrity: sha512-YTnYtra7W9e6/oAZEHj0bJehPRUlLH9/fbpT5LfB0NhQXyALCRkRs3zH9v07IYhkgpqX6Z78FnuccZr/l4Fs4Q==} - engines: {node: '>=6.9.0'} - - '@babel/types@7.25.6': - resolution: {integrity: sha512-/l42B1qxpG6RdfYf343Uw1vmDjeNhneUXtzhojE7pDgfpEypmRhI6j1kr17XCVv4Cgl9HdAiQY2x0GwKm7rWCw==} - engines: {node: '>=6.9.0'} - '@babel/types@7.26.0': resolution: {integrity: sha512-Z/yiTPj+lDVnF7lWeKCIJzaIkI0vYO87dMpZ4bg4TDrFe4XXLFWL1TbXU27gBP3QccxV9mZICCrnjnYlJjXHOA==} engines: {node: '>=6.9.0'} @@ -1594,10 +1519,6 @@ packages: resolution: {integrity: sha512-LLQRTqx7lKC7o2eCYMpyc5FXV8d0pUX6r3A+agzhqS9aoR5A6zCPefwQGcvbKx83ozX22ATZcemwxQXn12UofQ==} engines: {node: '>=16.7.0'} - '@cloudflare/workers-shared@0.8.0': - resolution: {integrity: sha512-1OvFkNtslaMZAJsaocTmbACApgmWv55uLpNj50Pn2MGcxdAjpqykXJFQw5tKc+lGV9TDZh9oO3Rsk17IEQDzIg==} - engines: {node: '>=16.7.0'} - '@cloudflare/workers-shared@0.9.0': resolution: {integrity: sha512-eP6Ir45uPbKnpADVzUCtkRUYxYxjB1Ew6n/whTJvHu8H4m93USHAceCMm736VBZdlxuhXXUjEP3fCUxKPn+cfw==} engines: {node: '>=16.7.0'} @@ -1611,8 +1532,8 @@ packages: '@cloudflare/workers-types@4.20241022.0': resolution: {integrity: sha512-1zOAw5QIDKItzGatzCrEpfLOB1AuMTwVqKmbw9B9eBfCUGRFNfJYMrJxIwcse9EmKahsQt2GruqU00pY/GyXgg==} - '@cloudflare/workers-types@4.20241112.0': - resolution: {integrity: sha512-Q4p9bAWZrX14bSCKY9to19xl0KMU7nsO5sJ2cTVspHoypsjPUMeQCsjHjmsO2C4Myo8/LPeDvmqFmkyNAPPYZw==} + '@cloudflare/workers-types@4.20241127.0': + resolution: {integrity: sha512-UqlvtqV8eI0CdPR7nxlbVlE52+lcjHvGdbYXEPwisy23+39RsFV7OOy0da0moJAhqnL2OhDmWTOaKdsVcPHiJQ==} '@codemirror/autocomplete@6.18.2': resolution: {integrity: sha512-wJGylKtMFR/Ds6Gh01+OovXE/pncPiKZNNBKuC39pKnH+XK5d9+WsNqcrdxPjFPFTigRBqse0rfxw9UxrfyhPg==} @@ -3980,15 +3901,6 @@ packages: resolution: {integrity: sha512-S45oynt/WH19bHbIXjtli6QmwNYvaz+vtnubvNpNDvUOoA/OWh6j1OikIP3G+v5GHdxyC6EXoChG3HgYGEUfcg==} engines: {node: '>=14.0.0'} - '@rollup/pluginutils@5.1.0': - resolution: {integrity: sha512-XTIWOPPcpvyKI6L1NHo0lFlCyznUEyPmPY1mc3KpPVDYulHSTvyeLNVW00QTLIAFNhR3kYnJTQHeGqU4M3n09g==} - engines: {node: '>=14.0.0'} - peerDependencies: - rollup: ^1.20.0||^2.0.0||^3.0.0||^4.0.0 - peerDependenciesMeta: - rollup: - optional: true - '@rollup/pluginutils@5.1.3': resolution: {integrity: sha512-Pnsb6f32CD2W3uCaLZIzDmeFyQ2b8UWMFI7xtwUezpcGBDVDW6y9XgAWIlARiGAo6eNF5FK5aQTr0LFyNyqq5A==} engines: {node: '>=14.0.0'} @@ -7017,11 +6929,6 @@ packages: resolution: {integrity: sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==} hasBin: true - jsesc@2.5.2: - resolution: {integrity: sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==} - engines: {node: '>=4'} - hasBin: true - jsesc@3.0.2: resolution: {integrity: sha512-xKqzzWXDttJuOcawBt4KnKHHIf5oQ/Cxax+0PWFG+DFDgHNAdi+TXECADI+RYiFUMmx8792xsMbbgXj4CwnP4g==} engines: {node: '>=6'} @@ -9215,10 +9122,6 @@ packages: to-arraybuffer@1.0.1: resolution: {integrity: sha512-okFlQcoGTi4LQBG/PgSYblw9VOyptsz2KJZqc6qtgGdes8VktzUQkj4BI2blit072iS8VODNcMA+tvnS9dnuMA==} - to-fast-properties@2.0.0: - resolution: {integrity: sha512-/OaKK0xYrs3DmxRYqL/yDc+FxFUVYhDlXMhRmv3z915w2HF1tnN1omB354j8VUGO/hbRzyD6Y3sA7v7GS/ceog==} - engines: {node: '>=4'} - to-regex-range@5.0.1: resolution: {integrity: sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==} engines: {node: '>=8.0'} @@ -9277,16 +9180,6 @@ packages: resolution: {integrity: sha512-Ibv4KAWfFkFdKJxnWfVtdOmB0Zi1RJVxcbPGiCDsFpCQSsmpWyuzHG3rQyI5YkobWwxFPEyQfu1hdo4qLG2zPw==} hasBin: true - tsconfck@3.1.1: - resolution: {integrity: sha512-00eoI6WY57SvZEVjm13stEVE90VkEdJAFGgpFLTsZbJyW/LwFQ7uQxJHWpZ2hzSWgCPKc9AnBnNP+0X7o3hAmQ==} - engines: {node: ^18 || >=20} - hasBin: true - peerDependencies: - typescript: ^5.0.0 - peerDependenciesMeta: - typescript: - optional: true - tsconfck@3.1.4: resolution: {integrity: sha512-kdqWFGVJqe+KGYvlSO9NIaWn9jT1Ny4oKVzAJsKii5eoE9snzTJzL4+MMVOMn+fikWGFmKEylcXL710V/kIPJQ==} engines: {node: ^18 || >=20} @@ -9389,6 +9282,11 @@ packages: engines: {node: '>=14.17'} hasBin: true + typescript@5.7.2: + resolution: {integrity: sha512-i5t66RHxDvVN40HfDd1PsEThGNnlMCMT3jMUuoh9/0TaqWevNontacunWyN02LA9/fIbEWlcHZcgTKb9QoaLfg==} + engines: {node: '>=14.17'} + hasBin: true + ufo@1.5.4: resolution: {integrity: sha512-UsUk3byDzKd04EyoZ7U4DOlxQaD14JUKQl6/P7wiX4FNvUfm3XL246n9W5AmqwW5RSFJ27NAuM0iLscAOYUiGQ==} @@ -9425,9 +9323,6 @@ packages: unenv-nightly@2.0.0-20241018-011344-e666fcf: resolution: {integrity: sha512-D00bYn8rzkCBOlLx+k1iHQlc69jvtJRT7Eek4yIGQ6461a2tUBjngGZdRpqsoXAJCz/qBW0NgPting7Zvg+ysg==} - unenv-nightly@2.0.0-20241111-080453-894aa31: - resolution: {integrity: sha512-0W39QQOQ9VE8kVVUpGwEG+pZcsCXk5wqNG6rDPE6Gr+fiA69LR0qERM61hW5KCOkC1/ArCFrfCGjwHyyv/bI0Q==} - unenv-nightly@2.0.0-20241121-161142-806b5c0: resolution: {integrity: sha512-RnFOasE/O0Q55gBkNB1b84OgKttgLEijGO0JCWpbn+O4XxpyCQg89NmcqQ5RGUiy4y+rMIrKzePTquQcLQF5pQ==} @@ -9956,16 +9851,6 @@ packages: '@cloudflare/workers-types': optional: true - wrangler@3.90.0: - resolution: {integrity: sha512-E/6E9ORAl987+3kP8wDiE3L1lj9r4vQ32/dl5toIxIkSMssmPRQVdxqwgMxbxJrytbFNo8Eo6swgjd4y4nUaLg==} - engines: {node: '>=16.17.0'} - hasBin: true - peerDependencies: - '@cloudflare/workers-types': ^4.20241106.0 - peerDependenciesMeta: - '@cloudflare/workers-types': - optional: true - wrangler@3.91.0: resolution: {integrity: sha512-Hdzn6wbY9cz5kL85ZUvWLwLIH7nPaEVRblfms40jhRf4qQO/Zf74aFlku8rQFbe8/2aVZFaxJVfBd6JQMeMSBQ==} engines: {node: '>=16.17.0'} @@ -10204,13 +10089,13 @@ snapshots: transitivePeerDependencies: - zod - '@ai-sdk/vue@0.0.57(vue@3.5.12(typescript@5.6.3))(zod@3.23.8)': + '@ai-sdk/vue@0.0.57(vue@3.5.12(typescript@5.7.2))(zod@3.23.8)': dependencies: '@ai-sdk/provider-utils': 1.0.22(zod@3.23.8) '@ai-sdk/ui-utils': 0.0.48(zod@3.23.8) - swrv: 1.0.4(vue@3.5.12(typescript@5.6.3)) + swrv: 1.0.4(vue@3.5.12(typescript@5.7.2)) optionalDependencies: - vue: 3.5.12(typescript@5.6.3) + vue: 3.5.12(typescript@5.7.2) transitivePeerDependencies: - zod @@ -11022,41 +10907,14 @@ snapshots: jsonwebtoken: 9.0.2 uuid: 8.3.2 - '@babel/code-frame@7.24.7': - dependencies: - '@babel/highlight': 7.24.7 - picocolors: 1.1.1 - '@babel/code-frame@7.26.0': dependencies: '@babel/helper-validator-identifier': 7.25.9 js-tokens: 4.0.0 picocolors: 1.1.1 - '@babel/compat-data@7.25.2': {} - '@babel/compat-data@7.26.0': {} - '@babel/core@7.25.2': - dependencies: - '@ampproject/remapping': 2.3.0 - '@babel/code-frame': 7.24.7 - '@babel/generator': 7.25.0 - '@babel/helper-compilation-targets': 7.25.2 - '@babel/helper-module-transforms': 7.25.2(@babel/core@7.25.2) - '@babel/helpers': 7.25.0 - '@babel/parser': 7.25.3 - '@babel/template': 7.25.0 - '@babel/traverse': 7.25.3 - '@babel/types': 7.25.6 - convert-source-map: 2.0.0 - debug: 4.3.7(supports-color@5.5.0) - gensync: 1.0.0-beta.2 - json5: 2.2.3 - semver: 6.3.1 - transitivePeerDependencies: - - supports-color - '@babel/core@7.26.0': dependencies: '@ampproject/remapping': 2.3.0 @@ -11077,13 +10935,6 @@ snapshots: transitivePeerDependencies: - supports-color - '@babel/generator@7.25.0': - dependencies: - '@babel/types': 7.25.6 - '@jridgewell/gen-mapping': 0.3.5 - '@jridgewell/trace-mapping': 0.3.25 - jsesc: 2.5.2 - '@babel/generator@7.26.0': dependencies: '@babel/parser': 7.26.0 @@ -11096,14 +10947,6 @@ snapshots: dependencies: '@babel/types': 7.26.0 - '@babel/helper-compilation-targets@7.25.2': - dependencies: - '@babel/compat-data': 7.25.2 - '@babel/helper-validator-option': 7.24.8 - browserslist: 4.24.2 - lru-cache: 5.1.1 - semver: 6.3.1 - '@babel/helper-compilation-targets@7.25.9': dependencies: '@babel/compat-data': 7.26.0 @@ -11112,13 +10955,6 @@ snapshots: lru-cache: 5.1.1 semver: 6.3.1 - '@babel/helper-module-imports@7.24.7': - dependencies: - '@babel/traverse': 7.25.3 - '@babel/types': 7.25.6 - transitivePeerDependencies: - - supports-color - '@babel/helper-module-imports@7.25.9': dependencies: '@babel/traverse': 7.25.9 @@ -11126,16 +10962,6 @@ snapshots: transitivePeerDependencies: - supports-color - '@babel/helper-module-transforms@7.25.2(@babel/core@7.25.2)': - dependencies: - '@babel/core': 7.25.2 - '@babel/helper-module-imports': 7.24.7 - '@babel/helper-simple-access': 7.24.7 - '@babel/helper-validator-identifier': 7.24.7 - '@babel/traverse': 7.25.3 - transitivePeerDependencies: - - supports-color - '@babel/helper-module-transforms@7.26.0(@babel/core@7.26.0)': dependencies: '@babel/core': 7.26.0 @@ -11147,46 +10973,17 @@ snapshots: '@babel/helper-plugin-utils@7.25.9': {} - '@babel/helper-simple-access@7.24.7': - dependencies: - '@babel/traverse': 7.25.3 - '@babel/types': 7.25.6 - transitivePeerDependencies: - - supports-color - - '@babel/helper-string-parser@7.24.8': {} - '@babel/helper-string-parser@7.25.9': {} - '@babel/helper-validator-identifier@7.24.7': {} - '@babel/helper-validator-identifier@7.25.9': {} - '@babel/helper-validator-option@7.24.8': {} - '@babel/helper-validator-option@7.25.9': {} - '@babel/helpers@7.25.0': - dependencies: - '@babel/template': 7.25.0 - '@babel/types': 7.25.6 - '@babel/helpers@7.26.0': dependencies: '@babel/template': 7.25.9 '@babel/types': 7.26.0 - '@babel/highlight@7.24.7': - dependencies: - '@babel/helper-validator-identifier': 7.24.7 - chalk: 2.4.2 - js-tokens: 4.0.0 - picocolors: 1.1.1 - - '@babel/parser@7.25.3': - dependencies: - '@babel/types': 7.25.6 - '@babel/parser@7.25.6': dependencies: '@babel/types': 7.26.0 @@ -11215,30 +11012,12 @@ snapshots: dependencies: regenerator-runtime: 0.14.1 - '@babel/template@7.25.0': - dependencies: - '@babel/code-frame': 7.24.7 - '@babel/parser': 7.25.3 - '@babel/types': 7.25.6 - '@babel/template@7.25.9': dependencies: '@babel/code-frame': 7.26.0 '@babel/parser': 7.26.0 '@babel/types': 7.26.0 - '@babel/traverse@7.25.3': - dependencies: - '@babel/code-frame': 7.24.7 - '@babel/generator': 7.25.0 - '@babel/parser': 7.25.3 - '@babel/template': 7.25.0 - '@babel/types': 7.25.6 - debug: 4.3.7(supports-color@5.5.0) - globals: 11.12.0 - transitivePeerDependencies: - - supports-color - '@babel/traverse@7.25.9': dependencies: '@babel/code-frame': 7.26.0 @@ -11251,18 +11030,6 @@ snapshots: transitivePeerDependencies: - supports-color - '@babel/types@7.25.2': - dependencies: - '@babel/helper-string-parser': 7.24.8 - '@babel/helper-validator-identifier': 7.24.7 - to-fast-properties: 2.0.0 - - '@babel/types@7.25.6': - dependencies: - '@babel/helper-string-parser': 7.24.8 - '@babel/helper-validator-identifier': 7.24.7 - to-fast-properties: 2.0.0 - '@babel/types@7.26.0': dependencies: '@babel/helper-string-parser': 7.25.9 @@ -11381,11 +11148,6 @@ snapshots: mime: 3.0.0 zod: 3.23.8 - '@cloudflare/workers-shared@0.8.0': - dependencies: - mime: 3.0.0 - zod: 3.23.8 - '@cloudflare/workers-shared@0.9.0': dependencies: mime: 3.0.0 @@ -11397,7 +11159,7 @@ snapshots: '@cloudflare/workers-types@4.20241022.0': {} - '@cloudflare/workers-types@4.20241112.0': {} + '@cloudflare/workers-types@4.20241127.0': {} '@codemirror/autocomplete@6.18.2(@codemirror/language@6.10.2)(@codemirror/state@6.4.1)(@codemirror/view@6.33.0)(@lezer/common@1.2.1)': dependencies: @@ -11518,21 +11280,21 @@ snapshots: dependencies: ms: 2.1.3 - '@darkobits/valida@0.1.6(typescript@5.6.3)': + '@darkobits/valida@0.1.6(typescript@5.7.2)': dependencies: deepmerge: 4.3.1 fastest-levenshtein: 1.0.16 is-plain-object: 5.0.0 ow: 0.28.1 ramda: 0.28.0 - ts-essentials: 9.4.2(typescript@5.6.3) + ts-essentials: 9.4.2(typescript@5.7.2) transitivePeerDependencies: - typescript - '@darkobits/vite-plugin-favicons@0.3.2(typescript@5.6.3)(vite@5.4.10(@types/node@20.14.15)(lightningcss@1.28.1))': + '@darkobits/vite-plugin-favicons@0.3.2(typescript@5.7.2)(vite@5.4.10(@types/node@20.14.15)(lightningcss@1.28.1))': dependencies: '@darkobits/log': 2.0.0-beta.16 - '@darkobits/valida': 0.1.6(typescript@5.6.3) + '@darkobits/valida': 0.1.6(typescript@5.7.2) cacache: 18.0.4 fast-json-stable-stringify: 2.1.0 favicons: 7.2.0 @@ -11540,7 +11302,7 @@ snapshots: fs-extra: 11.2.0 parse5: 7.1.2 ssri: 10.0.6 - ts-essentials: 9.4.2(typescript@5.6.3) + ts-essentials: 9.4.2(typescript@5.7.2) vite: 5.4.10(@types/node@20.14.15)(lightningcss@1.28.1) transitivePeerDependencies: - typescript @@ -12200,7 +11962,7 @@ snapshots: '@antfu/install-pkg': 0.4.1 '@antfu/utils': 0.7.10 '@iconify/types': 2.0.0 - debug: 4.3.6(supports-color@8.1.1) + debug: 4.3.7(supports-color@5.5.0) kolorist: 1.8.0 local-pkg: 0.5.0 mlly: 1.7.1 @@ -13688,14 +13450,6 @@ snapshots: '@remix-run/router@1.19.1': {} - '@rollup/pluginutils@5.1.0(rollup@4.24.0)': - dependencies: - '@types/estree': 1.0.6 - estree-walker: 2.0.2 - picomatch: 2.3.1 - optionalDependencies: - rollup: 4.24.0 - '@rollup/pluginutils@5.1.3(rollup@4.24.0)': dependencies: '@types/estree': 1.0.6 @@ -14159,56 +13913,56 @@ snapshots: '@smithy/types': 3.6.0 tslib: 2.6.3 - '@svgr/babel-plugin-add-jsx-attribute@8.0.0(@babel/core@7.25.2)': + '@svgr/babel-plugin-add-jsx-attribute@8.0.0(@babel/core@7.26.0)': dependencies: - '@babel/core': 7.25.2 + '@babel/core': 7.26.0 - '@svgr/babel-plugin-remove-jsx-attribute@8.0.0(@babel/core@7.25.2)': + '@svgr/babel-plugin-remove-jsx-attribute@8.0.0(@babel/core@7.26.0)': dependencies: - '@babel/core': 7.25.2 + '@babel/core': 7.26.0 - '@svgr/babel-plugin-remove-jsx-empty-expression@8.0.0(@babel/core@7.25.2)': + '@svgr/babel-plugin-remove-jsx-empty-expression@8.0.0(@babel/core@7.26.0)': dependencies: - '@babel/core': 7.25.2 + '@babel/core': 7.26.0 - '@svgr/babel-plugin-replace-jsx-attribute-value@8.0.0(@babel/core@7.25.2)': + '@svgr/babel-plugin-replace-jsx-attribute-value@8.0.0(@babel/core@7.26.0)': dependencies: - '@babel/core': 7.25.2 + '@babel/core': 7.26.0 - '@svgr/babel-plugin-svg-dynamic-title@8.0.0(@babel/core@7.25.2)': + '@svgr/babel-plugin-svg-dynamic-title@8.0.0(@babel/core@7.26.0)': dependencies: - '@babel/core': 7.25.2 + '@babel/core': 7.26.0 - '@svgr/babel-plugin-svg-em-dimensions@8.0.0(@babel/core@7.25.2)': + '@svgr/babel-plugin-svg-em-dimensions@8.0.0(@babel/core@7.26.0)': dependencies: - '@babel/core': 7.25.2 + '@babel/core': 7.26.0 - '@svgr/babel-plugin-transform-react-native-svg@8.1.0(@babel/core@7.25.2)': + '@svgr/babel-plugin-transform-react-native-svg@8.1.0(@babel/core@7.26.0)': dependencies: - '@babel/core': 7.25.2 + '@babel/core': 7.26.0 - '@svgr/babel-plugin-transform-svg-component@8.0.0(@babel/core@7.25.2)': + '@svgr/babel-plugin-transform-svg-component@8.0.0(@babel/core@7.26.0)': dependencies: - '@babel/core': 7.25.2 + '@babel/core': 7.26.0 - '@svgr/babel-preset@8.1.0(@babel/core@7.25.2)': + '@svgr/babel-preset@8.1.0(@babel/core@7.26.0)': dependencies: - '@babel/core': 7.25.2 - '@svgr/babel-plugin-add-jsx-attribute': 8.0.0(@babel/core@7.25.2) - '@svgr/babel-plugin-remove-jsx-attribute': 8.0.0(@babel/core@7.25.2) - '@svgr/babel-plugin-remove-jsx-empty-expression': 8.0.0(@babel/core@7.25.2) - '@svgr/babel-plugin-replace-jsx-attribute-value': 8.0.0(@babel/core@7.25.2) - '@svgr/babel-plugin-svg-dynamic-title': 8.0.0(@babel/core@7.25.2) - '@svgr/babel-plugin-svg-em-dimensions': 8.0.0(@babel/core@7.25.2) - '@svgr/babel-plugin-transform-react-native-svg': 8.1.0(@babel/core@7.25.2) - '@svgr/babel-plugin-transform-svg-component': 8.0.0(@babel/core@7.25.2) + '@babel/core': 7.26.0 + '@svgr/babel-plugin-add-jsx-attribute': 8.0.0(@babel/core@7.26.0) + '@svgr/babel-plugin-remove-jsx-attribute': 8.0.0(@babel/core@7.26.0) + '@svgr/babel-plugin-remove-jsx-empty-expression': 8.0.0(@babel/core@7.26.0) + '@svgr/babel-plugin-replace-jsx-attribute-value': 8.0.0(@babel/core@7.26.0) + '@svgr/babel-plugin-svg-dynamic-title': 8.0.0(@babel/core@7.26.0) + '@svgr/babel-plugin-svg-em-dimensions': 8.0.0(@babel/core@7.26.0) + '@svgr/babel-plugin-transform-react-native-svg': 8.1.0(@babel/core@7.26.0) + '@svgr/babel-plugin-transform-svg-component': 8.0.0(@babel/core@7.26.0) - '@svgr/core@8.1.0(typescript@5.6.3)': + '@svgr/core@8.1.0(typescript@5.7.2)': dependencies: - '@babel/core': 7.25.2 - '@svgr/babel-preset': 8.1.0(@babel/core@7.25.2) + '@babel/core': 7.26.0 + '@svgr/babel-preset': 8.1.0(@babel/core@7.26.0) camelcase: 6.3.0 - cosmiconfig: 8.3.6(typescript@5.6.3) + cosmiconfig: 8.3.6(typescript@5.7.2) snake-case: 3.0.4 transitivePeerDependencies: - supports-color @@ -14216,14 +13970,14 @@ snapshots: '@svgr/hast-util-to-babel-ast@8.0.0': dependencies: - '@babel/types': 7.25.2 + '@babel/types': 7.26.0 entities: 4.5.0 - '@svgr/plugin-jsx@8.1.0(@svgr/core@8.1.0(typescript@5.6.3))': + '@svgr/plugin-jsx@8.1.0(@svgr/core@8.1.0(typescript@5.7.2))': dependencies: - '@babel/core': 7.25.2 - '@svgr/babel-preset': 8.1.0(@babel/core@7.25.2) - '@svgr/core': 8.1.0(typescript@5.6.3) + '@babel/core': 7.26.0 + '@svgr/babel-preset': 8.1.0(@babel/core@7.26.0) + '@svgr/core': 8.1.0(typescript@5.7.2) '@svgr/hast-util-to-babel-ast': 8.0.0 svg-parser: 2.0.4 transitivePeerDependencies: @@ -14699,11 +14453,11 @@ snapshots: '@vue/shared': 3.5.12 vue: 3.5.12(typescript@5.6.2) - '@vue/server-renderer@3.5.12(vue@3.5.12(typescript@5.6.3))': + '@vue/server-renderer@3.5.12(vue@3.5.12(typescript@5.7.2))': dependencies: '@vue/compiler-ssr': 3.5.12 '@vue/shared': 3.5.12 - vue: 3.5.12(typescript@5.6.3) + vue: 3.5.12(typescript@5.7.2) '@vue/shared@3.5.12': {} @@ -14821,7 +14575,7 @@ snapshots: - solid-js - vue - ai@3.4.20(openai@4.68.4(encoding@0.1.13)(zod@3.23.8))(react@18.3.1)(sswr@2.1.0(svelte@4.2.19))(svelte@4.2.19)(vue@3.5.12(typescript@5.6.3))(zod@3.23.8): + ai@3.4.20(openai@4.68.4(encoding@0.1.13)(zod@3.23.8))(react@18.3.1)(sswr@2.1.0(svelte@4.2.19))(svelte@4.2.19)(vue@3.5.12(typescript@5.7.2))(zod@3.23.8): dependencies: '@ai-sdk/provider': 0.0.26 '@ai-sdk/provider-utils': 1.0.22(zod@3.23.8) @@ -14829,7 +14583,7 @@ snapshots: '@ai-sdk/solid': 0.0.52(zod@3.23.8) '@ai-sdk/svelte': 0.0.54(svelte@4.2.19)(zod@3.23.8) '@ai-sdk/ui-utils': 0.0.48(zod@3.23.8) - '@ai-sdk/vue': 0.0.57(vue@3.5.12(typescript@5.6.3))(zod@3.23.8) + '@ai-sdk/vue': 0.0.57(vue@3.5.12(typescript@5.7.2))(zod@3.23.8) '@opentelemetry/api': 1.9.0 eventsource-parser: 1.1.2 json-schema: 0.4.0 @@ -15322,7 +15076,7 @@ snapshots: parse5: 7.1.2 parse5-htmlparser2-tree-adapter: 7.0.0 parse5-parser-stream: 7.1.2 - undici: 6.19.7 + undici: 6.19.8 whatwg-mimetype: 4.0.0 chokidar@3.6.0: @@ -15548,14 +15302,14 @@ snapshots: core-util-is@1.0.3: {} - cosmiconfig@8.3.6(typescript@5.6.3): + cosmiconfig@8.3.6(typescript@5.7.2): dependencies: import-fresh: 3.3.0 js-yaml: 4.1.0 parse-json: 5.2.0 path-type: 4.0.0 optionalDependencies: - typescript: 5.6.3 + typescript: 5.7.2 crelt@1.0.6: {} @@ -15815,9 +15569,9 @@ snapshots: '@types/react': 18.3.3 react: 18.3.1 - drizzle-orm@0.36.4(@cloudflare/workers-types@4.20241112.0)(@libsql/client-wasm@0.14.0)(@libsql/client@0.14.0)(@neondatabase/serverless@0.10.1)(@opentelemetry/api@1.9.0)(@types/pg@8.11.10)(@types/react@18.3.3)(react@18.3.1): + drizzle-orm@0.36.4(@cloudflare/workers-types@4.20241127.0)(@libsql/client-wasm@0.14.0)(@libsql/client@0.14.0)(@neondatabase/serverless@0.10.1)(@opentelemetry/api@1.9.0)(@types/pg@8.11.10)(@types/react@18.3.3)(react@18.3.1): optionalDependencies: - '@cloudflare/workers-types': 4.20241112.0 + '@cloudflare/workers-types': 4.20241127.0 '@libsql/client': 0.14.0 '@libsql/client-wasm': 0.14.0 '@neondatabase/serverless': 0.10.1 @@ -17041,8 +16795,6 @@ snapshots: dependencies: argparse: 2.0.1 - jsesc@2.5.2: {} - jsesc@3.0.2: {} json-bigint@1.0.0: @@ -18508,7 +18260,7 @@ snapshots: parse-json@5.2.0: dependencies: - '@babel/code-frame': 7.24.7 + '@babel/code-frame': 7.26.0 error-ex: 1.3.2 json-parse-even-better-errors: 2.3.1 lines-and-columns: 1.2.4 @@ -19734,9 +19486,9 @@ snapshots: dependencies: vue: 3.5.12(typescript@5.6.2) - swrv@1.0.4(vue@3.5.12(typescript@5.6.3)): + swrv@1.0.4(vue@3.5.12(typescript@5.7.2)): dependencies: - vue: 3.5.12(typescript@5.6.3) + vue: 3.5.12(typescript@5.7.2) tailwind-merge@2.5.2: {} @@ -19901,8 +19653,6 @@ snapshots: to-arraybuffer@1.0.1: {} - to-fast-properties@2.0.0: {} - to-regex-range@5.0.1: dependencies: is-number: 7.0.0 @@ -19936,9 +19686,9 @@ snapshots: ts-error@1.0.6: {} - ts-essentials@9.4.2(typescript@5.6.3): + ts-essentials@9.4.2(typescript@5.7.2): optionalDependencies: - typescript: 5.6.3 + typescript: 5.7.2 ts-interface-checker@0.1.13: {} @@ -19972,14 +19722,14 @@ snapshots: normalize-path: 3.0.0 plimit-lit: 1.6.1 - tsconfck@3.1.1(typescript@5.6.3): - optionalDependencies: - typescript: 5.6.3 - tsconfck@3.1.4(typescript@5.6.2): optionalDependencies: typescript: 5.6.2 + tsconfck@3.1.4(typescript@5.7.2): + optionalDependencies: + typescript: 5.7.2 + tslib@1.14.1: {} tslib@2.6.3: {} @@ -20063,6 +19813,9 @@ snapshots: typescript@5.6.3: {} + typescript@5.7.2: + optional: true + ufo@1.5.4: {} undefsafe@2.0.5: {} @@ -20102,13 +19855,6 @@ snapshots: pathe: 1.1.2 ufo: 1.5.4 - unenv-nightly@2.0.0-20241111-080453-894aa31: - dependencies: - defu: 6.1.4 - ohash: 1.1.4 - pathe: 1.1.2 - ufo: 1.5.4 - unenv-nightly@2.0.0-20241121-161142-806b5c0: dependencies: defu: 6.1.4 @@ -20330,22 +20076,22 @@ snapshots: - supports-color - terser - vite-plugin-svgr@4.2.0(rollup@4.24.0)(typescript@5.6.3)(vite@5.4.10(@types/node@20.14.15)(lightningcss@1.28.1)): + vite-plugin-svgr@4.2.0(rollup@4.24.0)(typescript@5.7.2)(vite@5.4.10(@types/node@20.14.15)(lightningcss@1.28.1)): dependencies: - '@rollup/pluginutils': 5.1.0(rollup@4.24.0) - '@svgr/core': 8.1.0(typescript@5.6.3) - '@svgr/plugin-jsx': 8.1.0(@svgr/core@8.1.0(typescript@5.6.3)) + '@rollup/pluginutils': 5.1.3(rollup@4.24.0) + '@svgr/core': 8.1.0(typescript@5.7.2) + '@svgr/plugin-jsx': 8.1.0(@svgr/core@8.1.0(typescript@5.7.2)) vite: 5.4.10(@types/node@20.14.15)(lightningcss@1.28.1) transitivePeerDependencies: - rollup - supports-color - typescript - vite-tsconfig-paths@4.3.2(typescript@5.6.3)(vite@5.4.10(@types/node@20.14.15)(lightningcss@1.28.1)): + vite-tsconfig-paths@4.3.2(typescript@5.7.2)(vite@5.4.10(@types/node@20.14.15)(lightningcss@1.28.1)): dependencies: - debug: 4.3.6(supports-color@8.1.1) + debug: 4.3.7(supports-color@5.5.0) globrex: 0.1.2 - tsconfck: 3.1.1(typescript@5.6.3) + tsconfck: 3.1.4(typescript@5.7.2) optionalDependencies: vite: 5.4.10(@types/node@20.14.15)(lightningcss@1.28.1) transitivePeerDependencies: @@ -20600,15 +20346,15 @@ snapshots: optionalDependencies: typescript: 5.6.2 - vue@3.5.12(typescript@5.6.3): + vue@3.5.12(typescript@5.7.2): dependencies: '@vue/compiler-dom': 3.5.12 '@vue/compiler-sfc': 3.5.12 '@vue/runtime-dom': 3.5.12 - '@vue/server-renderer': 3.5.12(vue@3.5.12(typescript@5.6.3)) + '@vue/server-renderer': 3.5.12(vue@3.5.12(typescript@5.7.2)) '@vue/shared': 3.5.12 optionalDependencies: - typescript: 5.6.3 + typescript: 5.7.2 w3c-keyname@2.2.8: {} @@ -20754,7 +20500,7 @@ snapshots: '@cloudflare/workerd-linux-arm64': 1.20241106.1 '@cloudflare/workerd-windows-64': 1.20241106.1 - wrangler@3.73.0(@cloudflare/workers-types@4.20241112.0): + wrangler@3.73.0(@cloudflare/workers-types@4.20241127.0): dependencies: '@cloudflare/kv-asset-handler': 0.3.4 '@cloudflare/workers-shared': 0.4.1 @@ -20775,14 +20521,14 @@ snapshots: workerd: 1.20240821.1 xxhash-wasm: 1.0.2 optionalDependencies: - '@cloudflare/workers-types': 4.20241112.0 + '@cloudflare/workers-types': 4.20241127.0 fsevents: 2.3.3 transitivePeerDependencies: - bufferutil - supports-color - utf-8-validate - wrangler@3.78.5(@cloudflare/workers-types@4.20241112.0): + wrangler@3.78.5(@cloudflare/workers-types@4.20241127.0): dependencies: '@cloudflare/kv-asset-handler': 0.3.4 '@cloudflare/workers-shared': 0.5.3 @@ -20803,7 +20549,7 @@ snapshots: workerd: 1.20240909.0 xxhash-wasm: 1.0.2 optionalDependencies: - '@cloudflare/workers-types': 4.20241112.0 + '@cloudflare/workers-types': 4.20241127.0 fsevents: 2.3.3 transitivePeerDependencies: - bufferutil @@ -20868,36 +20614,7 @@ snapshots: - supports-color - utf-8-validate - wrangler@3.90.0(@cloudflare/workers-types@4.20241112.0): - dependencies: - '@cloudflare/kv-asset-handler': 0.3.4 - '@cloudflare/workers-shared': 0.8.0 - '@esbuild-plugins/node-globals-polyfill': 0.2.3(esbuild@0.17.19) - '@esbuild-plugins/node-modules-polyfill': 0.2.2(esbuild@0.17.19) - blake3-wasm: 2.1.5 - chokidar: 4.0.1 - date-fns: 4.1.0 - esbuild: 0.17.19 - itty-time: 1.0.6 - miniflare: 3.20241106.1 - nanoid: 3.3.7 - path-to-regexp: 6.3.0 - resolve: 1.22.8 - resolve.exports: 2.0.2 - selfsigned: 2.4.1 - source-map: 0.6.1 - unenv: unenv-nightly@2.0.0-20241111-080453-894aa31 - workerd: 1.20241106.1 - xxhash-wasm: 1.0.2 - optionalDependencies: - '@cloudflare/workers-types': 4.20241112.0 - fsevents: 2.3.3 - transitivePeerDependencies: - - bufferutil - - supports-color - - utf-8-validate - - wrangler@3.91.0(@cloudflare/workers-types@4.20241022.0): + wrangler@3.91.0(@cloudflare/workers-types@4.20241127.0): dependencies: '@cloudflare/kv-asset-handler': 0.3.4 '@cloudflare/workers-shared': 0.9.0 @@ -20919,7 +20636,7 @@ snapshots: workerd: 1.20241106.1 xxhash-wasm: 1.0.2 optionalDependencies: - '@cloudflare/workers-types': 4.20241022.0 + '@cloudflare/workers-types': 4.20241127.0 fsevents: 2.3.3 transitivePeerDependencies: - bufferutil