diff --git a/.editorconfig b/.editorconfig deleted file mode 100644 index 1db4a53..0000000 --- a/.editorconfig +++ /dev/null @@ -1,14 +0,0 @@ -# top-most EditorConfig file -root = true - -[*] -end_of_line = lf -charset = utf-8 -insert_final_newline = true -indent_style = space -indent_size = 2 - -[Makefile] -indent_style = tab -indent_size = 4 -insert_final_newline = false diff --git a/.eslintrc.cjs b/.eslintrc.cjs deleted file mode 100644 index deb120a..0000000 --- a/.eslintrc.cjs +++ /dev/null @@ -1,29 +0,0 @@ -/** @type {import('eslint').Linter.Config} */ -module.exports = { - root: true, - extends: [ - '@block65/eslint-config/javascript', - '@block65/eslint-config/typescript', - ], - parserOptions: { - project: ['./tsconfig.json'], - }, - - overrides: [ - { - files: ['**/*.test.ts', '**/*.test.tsx', '**/test/*.ts'], - rules: { - '@typescript-eslint/no-import-type-side-effects': 'error', - '@typescript-eslint/consistent-type-imports': 'off', - 'import/no-extraneous-dependencies': 'off', - }, - }, - - { - files: ['*.config.js', '*.config.ts', '*.workspace.ts'], - rules: { - 'import/no-extraneous-dependencies': 'off', - }, - }, - ], -}; diff --git a/.fallowrc.jsonc b/.fallowrc.jsonc new file mode 100644 index 0000000..fe5dadf --- /dev/null +++ b/.fallowrc.jsonc @@ -0,0 +1,25 @@ +{ + "extends": ["npm:@block65/shared-config/lib/fallow/fallow.jsonc"], + + "entry": [ + "lib/index.ts", + "examples/example.ts", + "oxfmt.config.ts", + "oxlint.config.ts" + ], + + // Constructs are reached through node.children and a type guard, which + // fallow does not follow, so these members read as unused + "usedClassMembers": [ + { + "extends": "Construct", + "members": ["synth", "contentType", "hasOperationId"] + } + ], + + "duplicates": { + // Header and Parameter synth() differ in how they emit explode and + // required, so sharing one body would change the output + "ignoredClones": ["dup:6f87acd9:2"] + } +} diff --git a/.git-blame-ignore-revs b/.git-blame-ignore-revs new file mode 100644 index 0000000..063bd6f --- /dev/null +++ b/.git-blame-ignore-revs @@ -0,0 +1,6 @@ +# Revisions listed here are skipped by `git blame`. +# Enable locally with: +# git config blame.ignoreRevsFile .git-blame-ignore-revs + +# style: reformat with oxfmt, drop .editorconfig +7a481d1e5f3b38916ea2f1a8e19e51ae13865c0b diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml new file mode 100644 index 0000000..de664ce --- /dev/null +++ b/.github/workflows/ci.yml @@ -0,0 +1,41 @@ +name: CI + +on: + workflow_dispatch: {} + push: + branches: ["canary", "master"] + pull_request: + branches: ["canary", "master"] + +permissions: + contents: read + +jobs: + check: + strategy: + matrix: + version: [24, 26] + os: [ubuntu-latest] + + runs-on: ${{ matrix.os }} + + steps: + - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 + + - uses: pnpm/action-setup@ea17c68df8912ef543352723c149a84f56e3d413 # v6.1.0 + + - uses: actions/setup-node@820762786026740c76f36085b0efc47a31fe5020 # v7.0.0 + with: + node-version: ${{ matrix.version }} + cache: "pnpm" + + # The package scripts call just, so it is needed before install + - uses: extractions/setup-just@53165ef7e734c5c07cb06b3c8e7b647c5aa16db3 # v4.0.0 + + - run: pnpm install --frozen-lockfile + + - run: just typecheck + - run: just lint-ci + - run: just fmt-check + - run: just test + - run: just dead-code diff --git a/.github/workflows/deploy.yml b/.github/workflows/deploy.yml index e567803..44f9374 100644 --- a/.github/workflows/deploy.yml +++ b/.github/workflows/deploy.yml @@ -13,16 +13,24 @@ jobs: id-token: write attestations: write steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 - - uses: pnpm/action-setup@v4 + - uses: pnpm/action-setup@ea17c68df8912ef543352723c149a84f56e3d413 # v6.1.0 - - uses: actions/setup-node@v4 + - uses: actions/setup-node@820762786026740c76f36085b0efc47a31fe5020 # v7.0.0 with: - node-version: 24 + node-version: 26 registry-url: https://registry.npmjs.org/ - cache: 'pnpm' + cache: "pnpm" - - run: make + # The package scripts call just, so it is needed before install + - uses: extractions/setup-just@53165ef7e734c5c07cb06b3c8e7b647c5aa16db3 # v4.0.0 - - run: pnpm publish --access=public --no-git-checks --provenance + - run: pnpm install --frozen-lockfile + + - run: just typecheck + + # the trusted publisher grants "npm stage publish", so this uploads for + # review rather than going live. approve it with pnpm stage approve. + # provenance is attached automatically when publishing over oidc + - run: pnpm stage publish --access public --no-git-checks diff --git a/.github/workflows/pr.yml b/.github/workflows/pr.yml deleted file mode 100644 index 19eadf8..0000000 --- a/.github/workflows/pr.yml +++ /dev/null @@ -1,26 +0,0 @@ -name: Unit Tests (PR) - -on: - pull_request: - branches: ['canary', 'master'] - -jobs: - test: - strategy: - matrix: - version: [24] - os: [ubuntu-latest] - - runs-on: ${{ matrix.os }} - - steps: - - uses: actions/checkout@v4 - - - uses: pnpm/action-setup@v4 - - - uses: actions/setup-node@v4 - with: - node-version: ${{ matrix.version }} - cache: 'pnpm' - - - run: make test diff --git a/.node-version b/.node-version index 209e3ef..6f4247a 100644 --- a/.node-version +++ b/.node-version @@ -1 +1 @@ -20 +26 diff --git a/.prettierignore b/.prettierignore deleted file mode 100644 index c31eb7f..0000000 --- a/.prettierignore +++ /dev/null @@ -1,7 +0,0 @@ -dist -build -coverage -tmp -.vscode -.idea -pnpm-lock.yaml diff --git a/Makefile b/Makefile deleted file mode 100644 index edcda9f..0000000 --- a/Makefile +++ /dev/null @@ -1,13 +0,0 @@ - -SRCS = $(wildcard lib/**) - -all: node_modules - pnpm exec tsc - -.PHONY: test -test: node_modules - pnpm exec tsc - pnpm exec vitest - -node_modules: package.json - pnpm install diff --git a/README.md b/README.md index 63ab7ae..715955f 100644 --- a/README.md +++ b/README.md @@ -6,206 +6,206 @@ An experimental AWS Constructs based Open API schema builder ```typescript import { - Api, - OpenApiVersion, - Parameter, - Path, - Reference, - Response, - Schema, - SecurityRequirement, - SecurityScheme, - Server, - Tag, -} from '@block65/openapi-constructs'; + Api, + OpenApiVersion, + Parameter, + Path, + Reference, + Response, + Schema, + SecurityRequirement, + SecurityScheme, + Server, + Tag, +} from "@block65/openapi-constructs"; const api = new Api({ - openapi: OpenApiVersion.V3_1, - info: { - title: 'Example REST API', - version: '1.0.0', - }, + openapi: OpenApiVersion.V3_1, + info: { + title: "Example REST API", + version: "1.0.0", + }, }); -new Server(api, 'ExampleServer', { - url: new URL('https://api.example.com'), +new Server(api, "ExampleServer", { + url: new URL("https://api.example.com"), }); -const httpBearerJwtScheme = new SecurityScheme(api, 'HttpBearerJwtScheme', { - type: 'http', - scheme: 'bearer', - bearerFormat: 'JWT', +const httpBearerJwtScheme = new SecurityScheme(api, "HttpBearerJwtScheme", { + type: "http", + scheme: "bearer", + bearerFormat: "JWT", }); -new SecurityRequirement(api, 'AllScopes', { - securityScheme: httpBearerJwtScheme, - scopes: [], +new SecurityRequirement(api, "AllScopes", { + securityScheme: httpBearerJwtScheme, + scopes: [], }); -const userTag = new Tag(api, 'UserTag', { - name: 'user', +const userTag = new Tag(api, "UserTag", { + name: "user", }); -const userDeleteScopeReq = new SecurityRequirement(api, 'UserDeleteScope', { - securityScheme: httpBearerJwtScheme, - scopes: ['users.delete'], +const userDeleteScopeReq = new SecurityRequirement(api, "UserDeleteScope", { + securityScheme: httpBearerJwtScheme, + scopes: ["users.delete"], }); -const noSecurityRequirement = new SecurityRequirement(api, 'NoSecurity'); - -const addressSchema = new Schema(api, 'Address', { - schema: { - type: 'object', - required: ['name'], - additionalProperties: false, - properties: { - postcode: { - type: 'integer', - format: 'int32', - minimum: 1000, - maximum: 9999, - }, - }, - }, +const noSecurityRequirement = new SecurityRequirement(api, "NoSecurity"); + +const addressSchema = new Schema(api, "Address", { + schema: { + type: "object", + required: ["name"], + additionalProperties: false, + properties: { + postcode: { + type: "integer", + format: "int32", + minimum: 1000, + maximum: 9999, + }, + }, + }, }); -const idSchema = new Schema(api, 'Id', { - schema: { - type: 'string', - minLength: 6, - maxLength: 6, - }, +const idSchema = new Schema(api, "Id", { + schema: { + type: "string", + minLength: 6, + maxLength: 6, + }, }); -const user = new Schema(api, 'User', { - schema: { - type: 'object', - required: ['name'], - additionalProperties: false, - properties: { - userId: idSchema.referenceObject(), - name: { - type: 'string', - }, - address: addressSchema.referenceObject(), - age: { - type: 'integer', - format: 'int32', - minimum: 0, - }, - }, - }, +const user = new Schema(api, "User", { + schema: { + type: "object", + required: ["name"], + additionalProperties: false, + properties: { + userId: idSchema.referenceObject(), + name: { + type: "string", + }, + address: addressSchema.referenceObject(), + age: { + type: "integer", + format: "int32", + minimum: 0, + }, + }, + }, }); -const updateUserRequest = new Schema(api, 'UpdateUserRequest', { - schema: { - type: 'object', - minProperties: 1, - additionalProperties: false, - properties: { - address: addressSchema.referenceObject(), - age: { - type: 'integer', - format: 'int32', - minimum: 0, - }, - }, - }, +const updateUserRequest = new Schema(api, "UpdateUserRequest", { + schema: { + type: "object", + minProperties: 1, + additionalProperties: false, + properties: { + address: addressSchema.referenceObject(), + age: { + type: "integer", + format: "int32", + minimum: 0, + }, + }, + }, }); -const createUserRequest = new Reference(user, 'CreateUserRequest'); +const createUserRequest = new Reference(user, "CreateUserRequest"); -const users = new Schema(api, 'Users', { - schema: { - type: 'array', - uniqueItems: true, - items: user.referenceObject(), - }, +const users = new Schema(api, "Users", { + schema: { + type: "array", + uniqueItems: true, + items: user.referenceObject(), + }, }); -const userIdParameter = new Parameter(api, 'UserId', { - name: 'userId', - in: 'path', - required: true, - schema: idSchema, +const userIdParameter = new Parameter(api, "UserId", { + name: "userId", + in: "path", + required: true, + schema: idSchema, }); new Path(api, { - path: '/users', - tags: new Set([userTag]), + path: "/users", + tags: new Set([userTag]), }) - .addOperation("GET", { - operationId: 'listUsersCommand', - responses: { - 200: new Response(api, 'ListUsersResponse', { - description: 'User 200 response', - content: { - contentType: 'application/json', - schema: users, - }, - }), - }, - }) - .addOperation("POST", { - operationId: 'createUserCommand', - requestBody: { - content: { - contentType: 'application/json', - schema: createUserRequest, - }, - }, - responses: { - 200: new Response(api, 'CreateUserResponse', { - description: 'User 200 response', - content: { - contentType: 'application/json', - schema: users, - }, - }), - }, - }); + .addOperation("GET", { + operationId: "listUsersCommand", + responses: { + 200: new Response(api, "ListUsersResponse", { + description: "User 200 response", + content: { + contentType: "application/json", + schema: users, + }, + }), + }, + }) + .addOperation("POST", { + operationId: "createUserCommand", + requestBody: { + content: { + contentType: "application/json", + schema: createUserRequest, + }, + }, + responses: { + 200: new Response(api, "CreateUserResponse", { + description: "User 200 response", + content: { + contentType: "application/json", + schema: users, + }, + }), + }, + }); new Path(api, { - path: '/users/{userId}', - parameters: [userIdParameter], + path: "/users/{userId}", + parameters: [userIdParameter], }) - .addOperation("GET", { - operationId: 'getUserByIdCommand', - responses: { - 200: new Response(api, 'GetUserById', { - description: 'User 200 response', - content: { - contentType: 'application/json', - schema: user, - }, - }), - }, - }) - .addOperation("DELETE", { - operationId: 'deleteUserByIdCommand', - security: userDeleteScopeReq, - }) - .addOperation("HEAD", { - operationId: 'checkUserIdAvailableCommand', - security: noSecurityRequirement, - }) - .addOperation("POST", { - operationId: 'updateUserCommand', - requestBody: { - content: { - contentType: 'application/json', - schema: updateUserRequest, - }, - }, - responses: { - 200: new Response(api, 'UpdateUserResponse', { - content: { - contentType: 'application/json', - schema: user, - }, - }), - }, - }); + .addOperation("GET", { + operationId: "getUserByIdCommand", + responses: { + 200: new Response(api, "GetUserById", { + description: "User 200 response", + content: { + contentType: "application/json", + schema: user, + }, + }), + }, + }) + .addOperation("DELETE", { + operationId: "deleteUserByIdCommand", + security: userDeleteScopeReq, + }) + .addOperation("HEAD", { + operationId: "checkUserIdAvailableCommand", + security: noSecurityRequirement, + }) + .addOperation("POST", { + operationId: "updateUserCommand", + requestBody: { + content: { + contentType: "application/json", + schema: updateUserRequest, + }, + }, + responses: { + 200: new Response(api, "UpdateUserResponse", { + content: { + contentType: "application/json", + schema: user, + }, + }), + }, + }); process.stdout.write(JSON.stringify(api.synth(), null, 2)); ``` diff --git a/__tests__/__snapshots__/openapi-schema.test.ts.snap b/__tests__/__snapshots__/openapi-schema.test.ts.snap index d91ac6d..752660f 100644 --- a/__tests__/__snapshots__/openapi-schema.test.ts.snap +++ b/__tests__/__snapshots__/openapi-schema.test.ts.snap @@ -374,1269 +374,7 @@ exports[`Example > OpenAPI 1`] = ` } `; -exports[`Example > Swagger Parser validate 1`] = ` -{ - "components": { - "headers": { - "x-rate-limit": { - "description": "Number of requests allowed per hour", - "required": true, - "schema": { - "format": "int32", - "minimum": 0, - "type": "integer", - }, - }, - "x-rate-limit-remaining": { - "description": "Number of requests remaining in the current window", - "schema": { - "format": "int32", - "minimum": 0, - "type": "integer", - }, - }, - }, - "parameters": { - "UserId": { - "in": "path", - "name": "userId", - "required": true, - "schema": { - "type": "string", - }, - }, - }, - "schemas": { - "Address": { - "additionalProperties": false, - "properties": { - "postcode": { - "format": "int32", - "maximum": 9999, - "minimum": 1000, - "type": "integer", - }, - }, - "required": [ - "postcode", - ], - "type": "object", - }, - "Binary": { - "format": "binary", - "type": "string", - }, - "CreateUserRequest": { - "additionalProperties": false, - "properties": { - "address": { - "additionalProperties": false, - "properties": { - "postcode": { - "format": "int32", - "maximum": 9999, - "minimum": 1000, - "type": "integer", - }, - }, - "required": [ - "postcode", - ], - "type": "object", - }, - "age": { - "anyOf": [ - { - "format": "int32", - "minimum": 0, - "type": "integer", - }, - { - "type": "null", - }, - ], - }, - "name": { - "type": "string", - }, - "userId": { - "type": "string", - }, - }, - "required": [ - "name", - ], - "type": "object", - }, - "Id": { - "type": "string", - }, - "RateLimit": { - "format": "int32", - "minimum": 0, - "type": "integer", - }, - "UpdateUserRequest": { - "additionalProperties": false, - "minProperties": 1, - "properties": { - "address": { - "additionalProperties": false, - "properties": { - "postcode": { - "format": "int32", - "maximum": 9999, - "minimum": 1000, - "type": "integer", - }, - }, - "required": [ - "postcode", - ], - "type": "object", - }, - "age": { - "format": "int32", - "minimum": 0, - "type": "integer", - }, - }, - "type": "object", - }, - "User": { - "additionalProperties": false, - "properties": { - "address": { - "additionalProperties": false, - "properties": { - "postcode": { - "format": "int32", - "maximum": 9999, - "minimum": 1000, - "type": "integer", - }, - }, - "required": [ - "postcode", - ], - "type": "object", - }, - "age": { - "anyOf": [ - { - "format": "int32", - "minimum": 0, - "type": "integer", - }, - { - "type": "null", - }, - ], - }, - "name": { - "type": "string", - }, - "userId": { - "type": "string", - }, - }, - "required": [ - "name", - ], - "type": "object", - }, - "Users": { - "items": { - "additionalProperties": false, - "properties": { - "address": { - "additionalProperties": false, - "properties": { - "postcode": { - "format": "int32", - "maximum": 9999, - "minimum": 1000, - "type": "integer", - }, - }, - "required": [ - "postcode", - ], - "type": "object", - }, - "age": { - "anyOf": [ - { - "format": "int32", - "minimum": 0, - "type": "integer", - }, - { - "type": "null", - }, - ], - }, - "name": { - "type": "string", - }, - "userId": { - "type": "string", - }, - }, - "required": [ - "name", - ], - "type": "object", - }, - "type": "array", - "uniqueItems": true, - }, - }, - "securitySchemes": { - "HttpBearerJwtScheme": { - "bearerFormat": "JWT", - "scheme": "bearer", - "type": "http", - }, - }, - }, - "info": { - "title": "Example REST API", - "version": "1.0.0", - }, - "openapi": "3.1.0", - "paths": { - "/users": { - "get": { - "operationId": "listUsersCommand", - "responses": { - "200": { - "content": { - "application/json": { - "schema": { - "items": { - "additionalProperties": false, - "properties": { - "address": { - "additionalProperties": false, - "properties": { - "postcode": { - "format": "int32", - "maximum": 9999, - "minimum": 1000, - "type": "integer", - }, - }, - "required": [ - "postcode", - ], - "type": "object", - }, - "age": { - "anyOf": [ - { - "format": "int32", - "minimum": 0, - "type": "integer", - }, - { - "type": "null", - }, - ], - }, - "name": { - "type": "string", - }, - "userId": { - "type": "string", - }, - }, - "required": [ - "name", - ], - "type": "object", - }, - "type": "array", - "uniqueItems": true, - }, - }, - }, - "description": "User 200 response", - "headers": { - "x-rate-limit": { - "description": "Number of requests allowed per hour", - "required": true, - "schema": { - "format": "int32", - "minimum": 0, - "type": "integer", - }, - }, - "x-rate-limit-remaining": { - "description": "Number of requests remaining in the current window", - "schema": { - "format": "int32", - "minimum": 0, - "type": "integer", - }, - }, - }, - }, - }, - "tags": [ - "user", - ], - }, - "post": { - "operationId": "createUserCommand", - "requestBody": { - "content": { - "application/json": { - "schema": { - "additionalProperties": false, - "properties": { - "address": { - "additionalProperties": false, - "properties": { - "postcode": { - "format": "int32", - "maximum": 9999, - "minimum": 1000, - "type": "integer", - }, - }, - "required": [ - "postcode", - ], - "type": "object", - }, - "age": { - "anyOf": [ - { - "format": "int32", - "minimum": 0, - "type": "integer", - }, - { - "type": "null", - }, - ], - }, - "name": { - "type": "string", - }, - "userId": { - "type": "string", - }, - }, - "required": [ - "name", - ], - "type": "object", - }, - }, - }, - "description": "", - "required": true, - }, - "responses": { - "200": { - "content": { - "application/json": { - "schema": { - "items": { - "additionalProperties": false, - "properties": { - "address": { - "additionalProperties": false, - "properties": { - "postcode": { - "format": "int32", - "maximum": 9999, - "minimum": 1000, - "type": "integer", - }, - }, - "required": [ - "postcode", - ], - "type": "object", - }, - "age": { - "anyOf": [ - { - "format": "int32", - "minimum": 0, - "type": "integer", - }, - { - "type": "null", - }, - ], - }, - "name": { - "type": "string", - }, - "userId": { - "type": "string", - }, - }, - "required": [ - "name", - ], - "type": "object", - }, - "type": "array", - "uniqueItems": true, - }, - }, - }, - "description": "User 200 response", - }, - }, - "tags": [ - "user", - "random", - ], - }, - }, - "/users/{userId}": { - "delete": { - "operationId": "deleteUserByIdCommand", - "security": [ - { - "HttpBearerJwtScheme": [ - "users.delete", - ], - }, - ], - "tags": [ - "user", - "random", - ], - }, - "get": { - "operationId": "getUserByIdCommand", - "responses": { - "200": { - "content": { - "application/json": { - "schema": { - "additionalProperties": false, - "properties": { - "address": { - "additionalProperties": false, - "properties": { - "postcode": { - "format": "int32", - "maximum": 9999, - "minimum": 1000, - "type": "integer", - }, - }, - "required": [ - "postcode", - ], - "type": "object", - }, - "age": { - "anyOf": [ - { - "format": "int32", - "minimum": 0, - "type": "integer", - }, - { - "type": "null", - }, - ], - }, - "name": { - "type": "string", - }, - "userId": { - "type": "string", - }, - }, - "required": [ - "name", - ], - "type": "object", - }, - }, - }, - "description": "User 200 response", - }, - }, - "tags": [], - }, - "head": { - "operationId": "checkUserIdAvailableCommand", - "security": [ - {}, - ], - "tags": [], - }, - "parameters": [ - { - "in": "path", - "name": "userId", - "required": true, - "schema": { - "type": "string", - }, - }, - ], - "post": { - "operationId": "updateUserCommand", - "requestBody": { - "content": { - "application/json": { - "schema": { - "additionalProperties": false, - "minProperties": 1, - "properties": { - "address": { - "additionalProperties": false, - "properties": { - "postcode": { - "format": "int32", - "maximum": 9999, - "minimum": 1000, - "type": "integer", - }, - }, - "required": [ - "postcode", - ], - "type": "object", - }, - "age": { - "format": "int32", - "minimum": 0, - "type": "integer", - }, - }, - "type": "object", - }, - }, - }, - "description": "", - "required": true, - }, - "responses": { - "200": { - "content": { - "application/json": { - "schema": { - "additionalProperties": false, - "properties": { - "address": { - "additionalProperties": false, - "properties": { - "postcode": { - "format": "int32", - "maximum": 9999, - "minimum": 1000, - "type": "integer", - }, - }, - "required": [ - "postcode", - ], - "type": "object", - }, - "age": { - "anyOf": [ - { - "format": "int32", - "minimum": 0, - "type": "integer", - }, - { - "type": "null", - }, - ], - }, - "name": { - "type": "string", - }, - "userId": { - "type": "string", - }, - }, - "required": [ - "name", - ], - "type": "object", - }, - }, - }, - "description": "Successful response", - }, - }, - "tags": [], - }, - }, - "/users/{userId}/avatar": { - "get": { - "description": "Download user avatar as JSON metadata or raw binary", - "operationId": "getUserAvatarCommand", - "responses": { - "200": { - "content": { - "application/json": { - "schema": { - "additionalProperties": false, - "properties": { - "address": { - "additionalProperties": false, - "properties": { - "postcode": { - "format": "int32", - "maximum": 9999, - "minimum": 1000, - "type": "integer", - }, - }, - "required": [ - "postcode", - ], - "type": "object", - }, - "age": { - "anyOf": [ - { - "format": "int32", - "minimum": 0, - "type": "integer", - }, - { - "type": "null", - }, - ], - }, - "name": { - "type": "string", - }, - "userId": { - "type": "string", - }, - }, - "required": [ - "name", - ], - "type": "object", - }, - }, - "application/octet-stream": { - "schema": { - "format": "binary", - "type": "string", - }, - }, - }, - "description": "Avatar response", - }, - }, - "tags": [], - }, - "parameters": [ - { - "in": "path", - "name": "userId", - "required": true, - "schema": { - "type": "string", - }, - }, - ], - "put": { - "description": "Upload user avatar as binary", - "operationId": "uploadUserAvatarCommand", - "requestBody": { - "content": { - "application/octet-stream": { - "schema": { - "format": "binary", - "type": "string", - }, - }, - }, - "description": "", - "required": true, - }, - "responses": { - "200": { - "content": { - "application/json": { - "schema": { - "additionalProperties": false, - "properties": { - "address": { - "additionalProperties": false, - "properties": { - "postcode": { - "format": "int32", - "maximum": 9999, - "minimum": 1000, - "type": "integer", - }, - }, - "required": [ - "postcode", - ], - "type": "object", - }, - "age": { - "anyOf": [ - { - "format": "int32", - "minimum": 0, - "type": "integer", - }, - { - "type": "null", - }, - ], - }, - "name": { - "type": "string", - }, - "userId": { - "type": "string", - }, - }, - "required": [ - "name", - ], - "type": "object", - }, - }, - }, - "description": "Successful response", - }, - }, - "tags": [], - }, - }, - }, - "security": [ - { - "HttpBearerJwtScheme": [], - }, - { - "HttpBearerJwtScheme": [ - "users.delete", - ], - }, - {}, - ], - "servers": [ - { - "url": "https://api.example.com/", - }, - ], - "tags": [ - { - "name": "user", - }, - { - "name": "random", - }, - ], -} -`; - -exports[`Note Taking > OpenAPI 1`] = ` -{ - "components": { - "headers": {}, - "parameters": { - "NoteId": { - "in": "path", - "name": "noteId", - "required": true, - "schema": { - "$ref": "#/components/schemas/Id", - }, - }, - "NoteUserId": { - "in": "path", - "name": "userId", - "required": true, - "schema": { - "$ref": "#/components/schemas/Id", - }, - }, - "UserId": { - "in": "path", - "name": "userId", - "required": true, - "schema": { - "$ref": "#/components/schemas/Id", - }, - }, - }, - "schemas": { - "Address": { - "additionalProperties": false, - "properties": { - "postcode": { - "format": "int32", - "maximum": 9999, - "minimum": 1000, - "type": "integer", - }, - }, - "required": [ - "postcode", - ], - "type": "object", - }, - "CreateNoteRequest": { - "additionalProperties": false, - "properties": { - "content": { - "type": "string", - }, - "labels": { - "items": { - "maxLength": 256, - "minLength": 1, - "type": "string", - }, - "type": "array", - }, - "title": { - "type": "string", - }, - }, - "required": [ - "title", - "content", - ], - "type": "object", - }, - "CreateUserRequest": { - "additionalProperties": false, - "properties": { - "address": { - "$ref": "#/components/schemas/Address", - }, - "age": { - "format": "int32", - "minimum": 0, - "type": "integer", - }, - "name": { - "type": "string", - }, - "userId": { - "$ref": "#/components/schemas/Id", - }, - }, - "required": [ - "name", - ], - "type": "object", - }, - "Id": { - "maxLength": 6, - "minLength": 6, - "type": "string", - }, - "Note": { - "additionalProperties": false, - "properties": { - "content": { - "type": "string", - }, - "labels": { - "items": { - "maxLength": 256, - "minLength": 1, - "type": "string", - }, - "type": "array", - }, - "title": { - "type": "string", - }, - }, - "required": [ - "title", - "content", - ], - "type": "object", - }, - "Notes": { - "items": { - "$ref": "#/components/schemas/Note", - }, - "type": "array", - "uniqueItems": true, - }, - "UpdateNoteRequest": { - "additionalProperties": false, - "minProperties": 1, - "properties": { - "content": { - "type": "string", - }, - "labels": { - "items": { - "maxLength": 256, - "minLength": 1, - "type": "string", - }, - "type": "array", - }, - "title": { - "type": "string", - }, - }, - "type": "object", - }, - "UpdateUserRequest": { - "additionalProperties": false, - "minProperties": 1, - "properties": { - "address": { - "$ref": "#/components/schemas/Address", - }, - "age": { - "format": "int32", - "minimum": 0, - "type": "integer", - }, - }, - "type": "object", - }, - "User": { - "additionalProperties": false, - "properties": { - "address": { - "$ref": "#/components/schemas/Address", - }, - "age": { - "format": "int32", - "minimum": 0, - "type": "integer", - }, - "name": { - "type": "string", - }, - "userId": { - "$ref": "#/components/schemas/Id", - }, - }, - "required": [ - "name", - ], - "type": "object", - }, - "Users": { - "items": { - "$ref": "#/components/schemas/User", - }, - "type": "array", - "uniqueItems": true, - }, - }, - "securitySchemes": { - "HttpBearerJwtScheme": { - "bearerFormat": "JWT", - "scheme": "bearer", - "type": "http", - }, - }, - }, - "info": { - "title": "Example REST API", - "version": "1.0.0", - }, - "openapi": "3.1.0", - "paths": { - "/users": { - "get": { - "operationId": "listUsersCommand", - "responses": { - "200": { - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/Users", - }, - }, - }, - "description": "User 200 response", - }, - }, - "tags": [ - "user", - ], - }, - "post": { - "operationId": "createUserCommand", - "requestBody": { - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/CreateUserRequest", - }, - }, - }, - "description": "", - "required": true, - }, - "responses": { - "200": { - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/Users", - }, - }, - }, - "description": "User 200 response", - }, - }, - "tags": [ - "user", - ], - }, - }, - "/users/{userId}": { - "delete": { - "operationId": "deleteUserByIdCommand", - "security": [ - { - "HttpBearerJwtScheme": [ - "users.delete", - ], - }, - ], - "tags": [], - }, - "get": { - "operationId": "getUserByIdCommand", - "responses": { - "200": { - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/User", - }, - }, - }, - "description": "User 200 response", - }, - }, - "tags": [], - }, - "head": { - "operationId": "checkUserIdAvailableCommand", - "responses": { - "204": { - "content": {}, - "description": "Successful response", - }, - "404": { - "content": {}, - "description": "Successful response", - }, - }, - "security": [ - {}, - ], - "tags": [], - }, - "parameters": [ - { - "$ref": "#/components/parameters/UserId", - }, - ], - "post": { - "operationId": "updateUserCommand", - "requestBody": { - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/UpdateUserRequest", - }, - }, - }, - "description": "", - "required": true, - }, - "responses": { - "200": { - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/User", - }, - }, - }, - "description": "Successful response", - }, - }, - "tags": [], - }, - }, - "/users/{userId}/notes": { - "get": { - "description": "List all of the notes", - "operationId": "listNotesCommand", - "responses": { - "200": { - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/Notes", - }, - }, - }, - "description": "Notes 200 response", - }, - }, - "summary": "List notes", - "tags": [ - "user", - ], - }, - "parameters": [ - { - "$ref": "#/components/parameters/NoteUserId", - }, - ], - "post": { - "deprecated": true, - "operationId": "createNoteCommand", - "requestBody": { - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/CreateNoteRequest", - }, - }, - }, - "description": "", - "required": true, - }, - "responses": { - "200": { - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/Note", - }, - }, - }, - "description": "Note created 200 response", - }, - }, - "tags": [ - "user", - ], - }, - }, - "/users/{userId}/notes/{noteId}": { - "delete": { - "operationId": "deleteNoteCommand", - "security": [ - { - "HttpBearerJwtScheme": [ - "notes.delete", - ], - }, - ], - "tags": [], - }, - "get": { - "operationId": "getNoteCommand", - "responses": { - "200": { - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/Note", - }, - }, - }, - "description": "Note 200 response", - }, - }, - "tags": [], - }, - "parameters": [ - { - "$ref": "#/components/parameters/NoteUserId", - }, - { - "$ref": "#/components/parameters/NoteId", - }, - ], - "post": { - "operationId": "updateNoteCommand", - "requestBody": { - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/UpdateNoteRequest", - }, - }, - }, - "description": "", - "required": true, - }, - "responses": { - "200": { - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/Note", - }, - }, - }, - "description": "Successful response", - }, - }, - "tags": [], - }, - }, - }, - "security": [ - { - "HttpBearerJwtScheme": [], - }, - { - "HttpBearerJwtScheme": [ - "users.delete", - ], - }, - {}, - { - "HttpBearerJwtScheme": [ - "notes.delete", - ], - }, - ], - "servers": [ - { - "url": "https://api.example.com/", - }, - ], - "tags": [ - { - "name": "user", - }, - ], -} -`; - -exports[`Note Taking > Swagger Parser validate 1`] = ` +exports[`Note Taking > OpenAPI 1`] = ` { "components": { "headers": {}, @@ -1646,9 +384,7 @@ exports[`Note Taking > Swagger Parser validate 1`] = ` "name": "noteId", "required": true, "schema": { - "maxLength": 6, - "minLength": 6, - "type": "string", + "$ref": "#/components/schemas/Id", }, }, "NoteUserId": { @@ -1656,9 +392,7 @@ exports[`Note Taking > Swagger Parser validate 1`] = ` "name": "userId", "required": true, "schema": { - "maxLength": 6, - "minLength": 6, - "type": "string", + "$ref": "#/components/schemas/Id", }, }, "UserId": { @@ -1666,9 +400,7 @@ exports[`Note Taking > Swagger Parser validate 1`] = ` "name": "userId", "required": true, "schema": { - "maxLength": 6, - "minLength": 6, - "type": "string", + "$ref": "#/components/schemas/Id", }, }, }, @@ -1716,19 +448,7 @@ exports[`Note Taking > Swagger Parser validate 1`] = ` "additionalProperties": false, "properties": { "address": { - "additionalProperties": false, - "properties": { - "postcode": { - "format": "int32", - "maximum": 9999, - "minimum": 1000, - "type": "integer", - }, - }, - "required": [ - "postcode", - ], - "type": "object", + "$ref": "#/components/schemas/Address", }, "age": { "format": "int32", @@ -1739,9 +459,7 @@ exports[`Note Taking > Swagger Parser validate 1`] = ` "type": "string", }, "userId": { - "maxLength": 6, - "minLength": 6, - "type": "string", + "$ref": "#/components/schemas/Id", }, }, "required": [ @@ -1780,28 +498,7 @@ exports[`Note Taking > Swagger Parser validate 1`] = ` }, "Notes": { "items": { - "additionalProperties": false, - "properties": { - "content": { - "type": "string", - }, - "labels": { - "items": { - "maxLength": 256, - "minLength": 1, - "type": "string", - }, - "type": "array", - }, - "title": { - "type": "string", - }, - }, - "required": [ - "title", - "content", - ], - "type": "object", + "$ref": "#/components/schemas/Note", }, "type": "array", "uniqueItems": true, @@ -1832,19 +529,7 @@ exports[`Note Taking > Swagger Parser validate 1`] = ` "minProperties": 1, "properties": { "address": { - "additionalProperties": false, - "properties": { - "postcode": { - "format": "int32", - "maximum": 9999, - "minimum": 1000, - "type": "integer", - }, - }, - "required": [ - "postcode", - ], - "type": "object", + "$ref": "#/components/schemas/Address", }, "age": { "format": "int32", @@ -1858,19 +543,7 @@ exports[`Note Taking > Swagger Parser validate 1`] = ` "additionalProperties": false, "properties": { "address": { - "additionalProperties": false, - "properties": { - "postcode": { - "format": "int32", - "maximum": 9999, - "minimum": 1000, - "type": "integer", - }, - }, - "required": [ - "postcode", - ], - "type": "object", + "$ref": "#/components/schemas/Address", }, "age": { "format": "int32", @@ -1881,9 +554,7 @@ exports[`Note Taking > Swagger Parser validate 1`] = ` "type": "string", }, "userId": { - "maxLength": 6, - "minLength": 6, - "type": "string", + "$ref": "#/components/schemas/Id", }, }, "required": [ @@ -1893,41 +564,7 @@ exports[`Note Taking > Swagger Parser validate 1`] = ` }, "Users": { "items": { - "additionalProperties": false, - "properties": { - "address": { - "additionalProperties": false, - "properties": { - "postcode": { - "format": "int32", - "maximum": 9999, - "minimum": 1000, - "type": "integer", - }, - }, - "required": [ - "postcode", - ], - "type": "object", - }, - "age": { - "format": "int32", - "minimum": 0, - "type": "integer", - }, - "name": { - "type": "string", - }, - "userId": { - "maxLength": 6, - "minLength": 6, - "type": "string", - }, - }, - "required": [ - "name", - ], - "type": "object", + "$ref": "#/components/schemas/User", }, "type": "array", "uniqueItems": true, @@ -1955,45 +592,7 @@ exports[`Note Taking > Swagger Parser validate 1`] = ` "content": { "application/json": { "schema": { - "items": { - "additionalProperties": false, - "properties": { - "address": { - "additionalProperties": false, - "properties": { - "postcode": { - "format": "int32", - "maximum": 9999, - "minimum": 1000, - "type": "integer", - }, - }, - "required": [ - "postcode", - ], - "type": "object", - }, - "age": { - "format": "int32", - "minimum": 0, - "type": "integer", - }, - "name": { - "type": "string", - }, - "userId": { - "maxLength": 6, - "minLength": 6, - "type": "string", - }, - }, - "required": [ - "name", - ], - "type": "object", - }, - "type": "array", - "uniqueItems": true, + "$ref": "#/components/schemas/Users", }, }, }, @@ -2010,41 +609,7 @@ exports[`Note Taking > Swagger Parser validate 1`] = ` "content": { "application/json": { "schema": { - "additionalProperties": false, - "properties": { - "address": { - "additionalProperties": false, - "properties": { - "postcode": { - "format": "int32", - "maximum": 9999, - "minimum": 1000, - "type": "integer", - }, - }, - "required": [ - "postcode", - ], - "type": "object", - }, - "age": { - "format": "int32", - "minimum": 0, - "type": "integer", - }, - "name": { - "type": "string", - }, - "userId": { - "maxLength": 6, - "minLength": 6, - "type": "string", - }, - }, - "required": [ - "name", - ], - "type": "object", + "$ref": "#/components/schemas/CreateUserRequest", }, }, }, @@ -2056,45 +621,7 @@ exports[`Note Taking > Swagger Parser validate 1`] = ` "content": { "application/json": { "schema": { - "items": { - "additionalProperties": false, - "properties": { - "address": { - "additionalProperties": false, - "properties": { - "postcode": { - "format": "int32", - "maximum": 9999, - "minimum": 1000, - "type": "integer", - }, - }, - "required": [ - "postcode", - ], - "type": "object", - }, - "age": { - "format": "int32", - "minimum": 0, - "type": "integer", - }, - "name": { - "type": "string", - }, - "userId": { - "maxLength": 6, - "minLength": 6, - "type": "string", - }, - }, - "required": [ - "name", - ], - "type": "object", - }, - "type": "array", - "uniqueItems": true, + "$ref": "#/components/schemas/Users", }, }, }, @@ -2125,41 +652,7 @@ exports[`Note Taking > Swagger Parser validate 1`] = ` "content": { "application/json": { "schema": { - "additionalProperties": false, - "properties": { - "address": { - "additionalProperties": false, - "properties": { - "postcode": { - "format": "int32", - "maximum": 9999, - "minimum": 1000, - "type": "integer", - }, - }, - "required": [ - "postcode", - ], - "type": "object", - }, - "age": { - "format": "int32", - "minimum": 0, - "type": "integer", - }, - "name": { - "type": "string", - }, - "userId": { - "maxLength": 6, - "minLength": 6, - "type": "string", - }, - }, - "required": [ - "name", - ], - "type": "object", + "$ref": "#/components/schemas/User", }, }, }, @@ -2187,14 +680,7 @@ exports[`Note Taking > Swagger Parser validate 1`] = ` }, "parameters": [ { - "in": "path", - "name": "userId", - "required": true, - "schema": { - "maxLength": 6, - "minLength": 6, - "type": "string", - }, + "$ref": "#/components/parameters/UserId", }, ], "post": { @@ -2203,31 +689,7 @@ exports[`Note Taking > Swagger Parser validate 1`] = ` "content": { "application/json": { "schema": { - "additionalProperties": false, - "minProperties": 1, - "properties": { - "address": { - "additionalProperties": false, - "properties": { - "postcode": { - "format": "int32", - "maximum": 9999, - "minimum": 1000, - "type": "integer", - }, - }, - "required": [ - "postcode", - ], - "type": "object", - }, - "age": { - "format": "int32", - "minimum": 0, - "type": "integer", - }, - }, - "type": "object", + "$ref": "#/components/schemas/UpdateUserRequest", }, }, }, @@ -2239,41 +701,7 @@ exports[`Note Taking > Swagger Parser validate 1`] = ` "content": { "application/json": { "schema": { - "additionalProperties": false, - "properties": { - "address": { - "additionalProperties": false, - "properties": { - "postcode": { - "format": "int32", - "maximum": 9999, - "minimum": 1000, - "type": "integer", - }, - }, - "required": [ - "postcode", - ], - "type": "object", - }, - "age": { - "format": "int32", - "minimum": 0, - "type": "integer", - }, - "name": { - "type": "string", - }, - "userId": { - "maxLength": 6, - "minLength": 6, - "type": "string", - }, - }, - "required": [ - "name", - ], - "type": "object", + "$ref": "#/components/schemas/User", }, }, }, @@ -2292,32 +720,7 @@ exports[`Note Taking > Swagger Parser validate 1`] = ` "content": { "application/json": { "schema": { - "items": { - "additionalProperties": false, - "properties": { - "content": { - "type": "string", - }, - "labels": { - "items": { - "maxLength": 256, - "minLength": 1, - "type": "string", - }, - "type": "array", - }, - "title": { - "type": "string", - }, - }, - "required": [ - "title", - "content", - ], - "type": "object", - }, - "type": "array", - "uniqueItems": true, + "$ref": "#/components/schemas/Notes", }, }, }, @@ -2331,14 +734,7 @@ exports[`Note Taking > Swagger Parser validate 1`] = ` }, "parameters": [ { - "in": "path", - "name": "userId", - "required": true, - "schema": { - "maxLength": 6, - "minLength": 6, - "type": "string", - }, + "$ref": "#/components/parameters/NoteUserId", }, ], "post": { @@ -2348,28 +744,7 @@ exports[`Note Taking > Swagger Parser validate 1`] = ` "content": { "application/json": { "schema": { - "additionalProperties": false, - "properties": { - "content": { - "type": "string", - }, - "labels": { - "items": { - "maxLength": 256, - "minLength": 1, - "type": "string", - }, - "type": "array", - }, - "title": { - "type": "string", - }, - }, - "required": [ - "title", - "content", - ], - "type": "object", + "$ref": "#/components/schemas/CreateNoteRequest", }, }, }, @@ -2381,28 +756,7 @@ exports[`Note Taking > Swagger Parser validate 1`] = ` "content": { "application/json": { "schema": { - "additionalProperties": false, - "properties": { - "content": { - "type": "string", - }, - "labels": { - "items": { - "maxLength": 256, - "minLength": 1, - "type": "string", - }, - "type": "array", - }, - "title": { - "type": "string", - }, - }, - "required": [ - "title", - "content", - ], - "type": "object", + "$ref": "#/components/schemas/Note", }, }, }, @@ -2433,28 +787,7 @@ exports[`Note Taking > Swagger Parser validate 1`] = ` "content": { "application/json": { "schema": { - "additionalProperties": false, - "properties": { - "content": { - "type": "string", - }, - "labels": { - "items": { - "maxLength": 256, - "minLength": 1, - "type": "string", - }, - "type": "array", - }, - "title": { - "type": "string", - }, - }, - "required": [ - "title", - "content", - ], - "type": "object", + "$ref": "#/components/schemas/Note", }, }, }, @@ -2465,24 +798,10 @@ exports[`Note Taking > Swagger Parser validate 1`] = ` }, "parameters": [ { - "in": "path", - "name": "userId", - "required": true, - "schema": { - "maxLength": 6, - "minLength": 6, - "type": "string", - }, + "$ref": "#/components/parameters/NoteUserId", }, { - "in": "path", - "name": "noteId", - "required": true, - "schema": { - "maxLength": 6, - "minLength": 6, - "type": "string", - }, + "$ref": "#/components/parameters/NoteId", }, ], "post": { @@ -2491,25 +810,7 @@ exports[`Note Taking > Swagger Parser validate 1`] = ` "content": { "application/json": { "schema": { - "additionalProperties": false, - "minProperties": 1, - "properties": { - "content": { - "type": "string", - }, - "labels": { - "items": { - "maxLength": 256, - "minLength": 1, - "type": "string", - }, - "type": "array", - }, - "title": { - "type": "string", - }, - }, - "type": "object", + "$ref": "#/components/schemas/UpdateNoteRequest", }, }, }, @@ -2521,28 +822,7 @@ exports[`Note Taking > Swagger Parser validate 1`] = ` "content": { "application/json": { "schema": { - "additionalProperties": false, - "properties": { - "content": { - "type": "string", - }, - "labels": { - "items": { - "maxLength": 256, - "minLength": 1, - "type": "string", - }, - "type": "array", - }, - "title": { - "type": "string", - }, - }, - "required": [ - "title", - "content", - ], - "type": "object", + "$ref": "#/components/schemas/Note", }, }, }, diff --git a/__tests__/fixtures/apis/example.ts b/__tests__/fixtures/apis/example.ts index 5208c14..f8407ef 100644 --- a/__tests__/fixtures/apis/example.ts +++ b/__tests__/fixtures/apis/example.ts @@ -1,333 +1,297 @@ -/* eslint-disable no-new */ +// oxlint-disable no-new -- constructs attach to their scope when built import { - Api, - Header, - Schema, - Parameter, - Path, - Reference, - Response, - SecurityRequirement, - SecurityScheme, - Server, - Tag, -} from '@block65/openapi-constructs'; + Api, + Header, + Schema, + Parameter, + Path, + Reference, + Response, + SecurityRequirement, + SecurityScheme, + Server, + Tag, +} from "@block65/openapi-constructs"; export const exampleApi = new Api({ - openapi: "3.1.0", - info: { - title: 'Example REST API', - version: '1.0.0', - }, + openapi: "3.1.0", + info: { + title: "Example REST API", + version: "1.0.0", + }, }); -new Server(exampleApi, 'ExampleServer', { - url: new URL('https://api.example.com'), +new Server(exampleApi, "ExampleServer", { + url: new URL("https://api.example.com"), }); const httpBearerJwtScheme = new SecurityScheme( - exampleApi, - 'HttpBearerJwtScheme', - { - type: 'http', - scheme: 'bearer', - bearerFormat: 'JWT', - }, + exampleApi, + "HttpBearerJwtScheme", + { + type: "http", + scheme: "bearer", + bearerFormat: "JWT", + }, ); -new SecurityRequirement(exampleApi, 'AllScopes', { - securityScheme: httpBearerJwtScheme, - scopes: [], +new SecurityRequirement(exampleApi, "AllScopes", { + securityScheme: httpBearerJwtScheme, + scopes: [], }); -const userTag = new Tag(exampleApi, 'UserTag', { - name: 'user', +const userTag = new Tag(exampleApi, "UserTag", { + name: "user", }); -const randomTag = new Tag(exampleApi, 'RandomTag', { - name: 'random', +const randomTag = new Tag(exampleApi, "RandomTag", { + name: "random", }); const userDeleteScopeReq = new SecurityRequirement( - exampleApi, - 'UserReadScope', - { - securityScheme: httpBearerJwtScheme, - scopes: ['users.delete'], - }, + exampleApi, + "UserReadScope", + { + securityScheme: httpBearerJwtScheme, + scopes: ["users.delete"], + }, ); -const noSecurityRequirement = new SecurityRequirement(exampleApi, 'NoSecurity'); +const noSecurityRequirement = new SecurityRequirement(exampleApi, "NoSecurity"); -const addressSchema = new Schema(exampleApi, 'Address', { - schema: { - type: 'object', - required: ['postcode'], - additionalProperties: false, - properties: { - postcode: { - type: 'integer', - format: 'int32', - minimum: 1000, - maximum: 9999, - }, - }, - }, +const addressSchema = new Schema(exampleApi, "Address", { + schema: { + type: "object", + required: ["postcode"], + additionalProperties: false, + properties: { + postcode: { + type: "integer", + format: "int32", + minimum: 1000, + maximum: 9999, + }, + }, + }, }); -const idSchema = new Schema(exampleApi, 'Id', { - schema: { - type: 'string', - }, +const idSchema = new Schema(exampleApi, "Id", { + schema: { + type: "string", + }, }); -const user = new Schema(exampleApi, 'User', { - schema: { - type: 'object', - required: ['name'], - additionalProperties: false, - properties: { - userId: idSchema.referenceObject(), - name: { - type: 'string', - }, - address: addressSchema.referenceObject(), - age: { - anyOf: [ - { - type: 'integer', - format: 'int32', - minimum: 0, - }, - { - type: 'null', - }, - ], - }, - }, - }, +const user = new Schema(exampleApi, "User", { + schema: { + type: "object", + required: ["name"], + additionalProperties: false, + properties: { + userId: idSchema.referenceObject(), + name: { + type: "string", + }, + address: addressSchema.referenceObject(), + age: { + anyOf: [ + { + type: "integer", + format: "int32", + minimum: 0, + }, + { + type: "null", + }, + ], + }, + }, + }, }); -const updateUserRequest = new Schema(exampleApi, 'UpdateUserRequest', { - schema: { - type: 'object', - minProperties: 1, - additionalProperties: false, - properties: { - address: addressSchema.referenceObject(), - age: { - type: 'integer', - format: 'int32', - minimum: 0, - }, - }, - }, +const updateUserRequest = new Schema(exampleApi, "UpdateUserRequest", { + schema: { + type: "object", + minProperties: 1, + additionalProperties: false, + properties: { + address: addressSchema.referenceObject(), + age: { + type: "integer", + format: "int32", + minimum: 0, + }, + }, + }, }); -const createUserRequest = new Reference(user, 'CreateUserRequest'); +const createUserRequest = new Reference(user, "CreateUserRequest"); -const users = new Schema(exampleApi, 'Users', { - schema: { - type: 'array', - // additionalItems: false, - uniqueItems: true, - items: user.referenceObject(), - }, +const users = new Schema(exampleApi, "Users", { + schema: { + type: "array", + uniqueItems: true, + items: user.referenceObject(), + }, }); -/* const errorSchema = new Schema(api, 'ErrorSchema', { - schema: { - type: 'object', - required: ['name'], - additionalProperties: false, - properties: { - name: { - type: 'string', - }, - }, - }, -}); */ - -/* const idParameter = new Parameter(api, 'IdParam', { - name: 'userId', - in: 'path', - required: true, - schema: idSchema, -}); */ - -const rateLimitSchema = new Schema(exampleApi, 'RateLimit', { - schema: { - type: 'integer', - format: 'int32', - minimum: 0, - }, +const rateLimitSchema = new Schema(exampleApi, "RateLimit", { + schema: { + type: "integer", + format: "int32", + minimum: 0, + }, }); -const rateLimitHeader = new Header(exampleApi, 'x-rate-limit', { - description: 'Number of requests allowed per hour', - required: true, - schema: rateLimitSchema, +const rateLimitHeader = new Header(exampleApi, "x-rate-limit", { + description: "Number of requests allowed per hour", + required: true, + schema: rateLimitSchema, }); -const rateLimitRemainingHeader = new Header(exampleApi, 'x-rate-limit-remaining', { - description: 'Number of requests remaining in the current window', - schema: rateLimitSchema, -}); +const rateLimitRemainingHeader = new Header( + exampleApi, + "x-rate-limit-remaining", + { + description: "Number of requests remaining in the current window", + schema: rateLimitSchema, + }, +); -const binarySchema = new Schema(exampleApi, 'Binary', { - schema: { - type: 'string', - format: 'binary', - }, +const binarySchema = new Schema(exampleApi, "Binary", { + schema: { + type: "string", + format: "binary", + }, }); -const userIdParameter = new Parameter(exampleApi, 'UserId', { - name: 'userId', - in: 'path', - required: true, - schema: idSchema, +const userIdParameter = new Parameter(exampleApi, "UserId", { + name: "userId", + in: "path", + required: true, + schema: idSchema, }); -/* const userIdentifiersSchema = new Schema(api, 'UserIdentifiers', { - schema: { - type: 'object', - additionalProperties: false, - required: ['userId'], - properties: { - userId: userIdParameter.referenceObject(), - }, - }, -}); */ - -/* const errorResponse = new Response(api, 'ErrorResponse', { - description: 'Error response', - content: new MediaType(api, 'Error', { - contentType: 'application/json', - schema: errorSchema, - }), -}); */ - new Path(exampleApi, { - path: '/users', - tags: new Set([userTag]), + path: "/users", + tags: new Set([userTag]), }) - .addOperation("get", { - operationId: 'listUsersCommand', - responses: { - 200: new Response(exampleApi, 'ListUsers200Response', { - description: 'User 200 response', - content: { - contentType: 'application/json', - schema: users, - }, - headers: { - 'x-rate-limit': rateLimitHeader, - 'x-rate-limit-remaining': rateLimitRemainingHeader, - }, - }), - }, - }) - .addOperation("post", { - operationId: 'createUserCommand', - tags: new Set([randomTag]), - requestBody: { - content: { - contentType: 'application/json', - schema: createUserRequest, - }, - }, - responses: { - 200: new Response(exampleApi, 'CreateUser200Response', { - description: 'User 200 response', - content: { - contentType: 'application/json', - schema: users, - }, - }), - }, - }); + .addOperation("get", { + operationId: "listUsersCommand", + responses: { + 200: new Response(exampleApi, "ListUsers200Response", { + description: "User 200 response", + content: { + contentType: "application/json", + schema: users, + }, + headers: { + "x-rate-limit": rateLimitHeader, + "x-rate-limit-remaining": rateLimitRemainingHeader, + }, + }), + }, + }) + .addOperation("post", { + operationId: "createUserCommand", + tags: new Set([randomTag]), + requestBody: { + content: { + contentType: "application/json", + schema: createUserRequest, + }, + }, + responses: { + 200: new Response(exampleApi, "CreateUser200Response", { + description: "User 200 response", + content: { + contentType: "application/json", + schema: users, + }, + }), + }, + }); new Path(exampleApi, { - path: '/users/{userId}', - parameters: [userIdParameter], + path: "/users/{userId}", + parameters: [userIdParameter], }) - .addOperation("get", { - operationId: 'getUserByIdCommand', - responses: { - 200: new Response(exampleApi, 'GetUserById', { - description: 'User 200 response', - content: { - contentType: 'application/json', - schema: user, - }, - }), - }, - }) - .addOperation("delete", { - operationId: 'deleteUserByIdCommand', - security: userDeleteScopeReq, - tags: new Set([userTag, randomTag]), - }) - .addOperation("head", { - operationId: 'checkUserIdAvailableCommand', - security: noSecurityRequirement, - }) - .addOperation("post", { - operationId: 'updateUserCommand', - requestBody: { - content: { - contentType: 'application/json', - schema: updateUserRequest, - }, - }, - responses: { - 200: new Response(exampleApi, 'UpdateUserResponse200', { - content: { - contentType: 'application/json', - schema: user, - }, - }), - }, - }); + .addOperation("get", { + operationId: "getUserByIdCommand", + responses: { + 200: new Response(exampleApi, "GetUserById", { + description: "User 200 response", + content: { + contentType: "application/json", + schema: user, + }, + }), + }, + }) + .addOperation("delete", { + operationId: "deleteUserByIdCommand", + security: userDeleteScopeReq, + tags: new Set([userTag, randomTag]), + }) + .addOperation("head", { + operationId: "checkUserIdAvailableCommand", + security: noSecurityRequirement, + }) + .addOperation("post", { + operationId: "updateUserCommand", + requestBody: { + content: { + contentType: "application/json", + schema: updateUserRequest, + }, + }, + responses: { + 200: new Response(exampleApi, "UpdateUserResponse200", { + content: { + contentType: "application/json", + schema: user, + }, + }), + }, + }); new Path(exampleApi, { - path: '/users/{userId}/avatar', - parameters: [userIdParameter], + path: "/users/{userId}/avatar", + parameters: [userIdParameter], }) - .addOperation("get", { - operationId: 'getUserAvatarCommand', - description: 'Download user avatar as JSON metadata or raw binary', - responses: { - 200: new Response(exampleApi, 'GetUserAvatar200Response', { - description: 'Avatar response', - content: [ - { - contentType: 'application/json', - schema: user, - }, - { - contentType: 'application/octet-stream', - schema: binarySchema, - }, - ], - }), - }, - }) - .addOperation("put", { - operationId: 'uploadUserAvatarCommand', - description: 'Upload user avatar as binary', - requestBody: { - content: { - contentType: 'application/octet-stream', - schema: binarySchema, - }, - }, - responses: { - 200: new Response(exampleApi, 'UploadUserAvatar200Response', { - content: { - contentType: 'application/json', - schema: user, - }, - }), - }, - }); + .addOperation("get", { + operationId: "getUserAvatarCommand", + description: "Download user avatar as JSON metadata or raw binary", + responses: { + 200: new Response(exampleApi, "GetUserAvatar200Response", { + description: "Avatar response", + content: [ + { + contentType: "application/json", + schema: user, + }, + { + contentType: "application/octet-stream", + schema: binarySchema, + }, + ], + }), + }, + }) + .addOperation("put", { + operationId: "uploadUserAvatarCommand", + description: "Upload user avatar as binary", + requestBody: { + content: { + contentType: "application/octet-stream", + schema: binarySchema, + }, + }, + responses: { + 200: new Response(exampleApi, "UploadUserAvatar200Response", { + content: { + contentType: "application/json", + schema: user, + }, + }), + }, + }); diff --git a/__tests__/fixtures/apis/note-taking.ts b/__tests__/fixtures/apis/note-taking.ts index bc38c8c..7c15a7d 100644 --- a/__tests__/fixtures/apis/note-taking.ts +++ b/__tests__/fixtures/apis/note-taking.ts @@ -1,375 +1,375 @@ -/* eslint-disable no-new */ +// oxlint-disable no-new -- constructs attach to their scope when built import { - Api, - Parameter, - Path, - Reference, - Response, - Schema, - SecurityRequirement, - SecurityScheme, - Server, - Tag, -} from '@block65/openapi-constructs'; + Api, + Parameter, + Path, + Reference, + Response, + Schema, + SecurityRequirement, + SecurityScheme, + Server, + Tag, +} from "@block65/openapi-constructs"; export const noteTakingApi = new Api({ - openapi: "3.1.0", - info: { - title: 'Example REST API', - version: '1.0.0', - }, + openapi: "3.1.0", + info: { + title: "Example REST API", + version: "1.0.0", + }, }); -new Server(noteTakingApi, 'ExampleServer', { - url: new URL('https://api.example.com'), +new Server(noteTakingApi, "ExampleServer", { + url: new URL("https://api.example.com"), }); const httpBearerJwtScheme = new SecurityScheme( - noteTakingApi, - 'HttpBearerJwtScheme', - { - type: 'http', - scheme: 'bearer', - bearerFormat: 'JWT', - }, + noteTakingApi, + "HttpBearerJwtScheme", + { + type: "http", + scheme: "bearer", + bearerFormat: "JWT", + }, ); -new SecurityRequirement(noteTakingApi, 'AllScopes', { - securityScheme: httpBearerJwtScheme, - scopes: [], +new SecurityRequirement(noteTakingApi, "AllScopes", { + securityScheme: httpBearerJwtScheme, + scopes: [], }); -const userApiTag = new Tag(noteTakingApi, 'UserApiTag', { - name: 'user', +const userApiTag = new Tag(noteTakingApi, "UserApiTag", { + name: "user", }); const userDeleteScopeReq = new SecurityRequirement( - noteTakingApi, - 'UserDeleteScope', - { - securityScheme: httpBearerJwtScheme, - scopes: ['users.delete'], - }, + noteTakingApi, + "UserDeleteScope", + { + securityScheme: httpBearerJwtScheme, + scopes: ["users.delete"], + }, ); const noSecurityRequirement = new SecurityRequirement( - noteTakingApi, - 'NoSecurity', + noteTakingApi, + "NoSecurity", ); -const addressSchema = new Schema(noteTakingApi, 'Address', { - schema: { - type: 'object', - required: ['postcode'], - additionalProperties: false, - properties: { - postcode: { - type: 'integer', - format: 'int32', - minimum: 1000, - maximum: 9999, - }, - }, - }, +const addressSchema = new Schema(noteTakingApi, "Address", { + schema: { + type: "object", + required: ["postcode"], + additionalProperties: false, + properties: { + postcode: { + type: "integer", + format: "int32", + minimum: 1000, + maximum: 9999, + }, + }, + }, }); -const idSchema = new Schema(noteTakingApi, 'Id', { - schema: { - type: 'string', - minLength: 6, - maxLength: 6, - }, +const idSchema = new Schema(noteTakingApi, "Id", { + schema: { + type: "string", + minLength: 6, + maxLength: 6, + }, }); -const user = new Schema(noteTakingApi, 'User', { - schema: { - type: 'object', - required: ['name'], - additionalProperties: false, - properties: { - userId: idSchema.referenceObject(), - name: { - type: 'string', - }, - address: addressSchema.referenceObject(), - age: { - type: 'integer', - format: 'int32', - minimum: 0, - }, - }, - }, +const user = new Schema(noteTakingApi, "User", { + schema: { + type: "object", + required: ["name"], + additionalProperties: false, + properties: { + userId: idSchema.referenceObject(), + name: { + type: "string", + }, + address: addressSchema.referenceObject(), + age: { + type: "integer", + format: "int32", + minimum: 0, + }, + }, + }, }); -const updateUserRequest = new Schema(noteTakingApi, 'UpdateUserRequest', { - schema: { - type: 'object', - minProperties: 1, - additionalProperties: false, - properties: { - address: addressSchema.referenceObject(), - age: { - type: 'integer', - format: 'int32', - minimum: 0, - }, - }, - }, +const updateUserRequest = new Schema(noteTakingApi, "UpdateUserRequest", { + schema: { + type: "object", + minProperties: 1, + additionalProperties: false, + properties: { + address: addressSchema.referenceObject(), + age: { + type: "integer", + format: "int32", + minimum: 0, + }, + }, + }, }); -const createUserRequest = new Reference(user, 'CreateUserRequest'); +const createUserRequest = new Reference(user, "CreateUserRequest"); -const users = new Schema(noteTakingApi, 'Users', { - schema: { - type: 'array', - uniqueItems: true, - items: user.referenceObject(), - }, +const users = new Schema(noteTakingApi, "Users", { + schema: { + type: "array", + uniqueItems: true, + items: user.referenceObject(), + }, }); -const userIdParameter = new Parameter(noteTakingApi, 'UserId', { - name: 'userId', - in: 'path', - required: true, - schema: idSchema, +const userIdParameter = new Parameter(noteTakingApi, "UserId", { + name: "userId", + in: "path", + required: true, + schema: idSchema, }); new Path(noteTakingApi, { - path: '/users', - tags: new Set([userApiTag]), + path: "/users", + tags: new Set([userApiTag]), }) - .addOperation("get", { - operationId: 'listUsersCommand', - responses: { - 200: new Response(noteTakingApi, 'ListUsersResponse', { - description: 'User 200 response', - content: { - contentType: 'application/json', - schema: users, - }, - }), - }, - }) - .addOperation("post", { - operationId: 'createUserCommand', - requestBody: { - content: { - contentType: 'application/json', - schema: createUserRequest, - }, - }, - responses: { - 200: new Response(noteTakingApi, 'CreateUserResponse', { - description: 'User 200 response', - content: { - contentType: 'application/json', - schema: users, - }, - }), - }, - }); + .addOperation("get", { + operationId: "listUsersCommand", + responses: { + 200: new Response(noteTakingApi, "ListUsersResponse", { + description: "User 200 response", + content: { + contentType: "application/json", + schema: users, + }, + }), + }, + }) + .addOperation("post", { + operationId: "createUserCommand", + requestBody: { + content: { + contentType: "application/json", + schema: createUserRequest, + }, + }, + responses: { + 200: new Response(noteTakingApi, "CreateUserResponse", { + description: "User 200 response", + content: { + contentType: "application/json", + schema: users, + }, + }), + }, + }); new Path(noteTakingApi, { - path: '/users/{userId}', - parameters: [userIdParameter], + path: "/users/{userId}", + parameters: [userIdParameter], }) - .addOperation("get", { - operationId: 'getUserByIdCommand', - responses: { - 200: new Response(noteTakingApi, 'GetUserById', { - description: 'User 200 response', - content: { - contentType: 'application/json', - schema: user, - }, - }), - }, - }) - .addOperation("delete", { - operationId: 'deleteUserByIdCommand', - security: userDeleteScopeReq, - }) - .addOperation("head", { - operationId: 'checkUserIdAvailableCommand', - security: noSecurityRequirement, - responses: { - 204: new Response(noteTakingApi, 'HeadUserResponseFound'), - 404: new Response(noteTakingApi, 'HeadUserResponseNotFound'), - }, - }) - .addOperation("post", { - operationId: 'updateUserCommand', - requestBody: { - content: { - contentType: 'application/json', - schema: updateUserRequest, - }, - }, - responses: { - 200: new Response(noteTakingApi, 'UpdateUserResponse', { - content: { - contentType: 'application/json', - schema: user, - }, - }), - }, - }); + .addOperation("get", { + operationId: "getUserByIdCommand", + responses: { + 200: new Response(noteTakingApi, "GetUserById", { + description: "User 200 response", + content: { + contentType: "application/json", + schema: user, + }, + }), + }, + }) + .addOperation("delete", { + operationId: "deleteUserByIdCommand", + security: userDeleteScopeReq, + }) + .addOperation("head", { + operationId: "checkUserIdAvailableCommand", + security: noSecurityRequirement, + responses: { + 204: new Response(noteTakingApi, "HeadUserResponseFound"), + 404: new Response(noteTakingApi, "HeadUserResponseNotFound"), + }, + }) + .addOperation("post", { + operationId: "updateUserCommand", + requestBody: { + content: { + contentType: "application/json", + schema: updateUserRequest, + }, + }, + responses: { + 200: new Response(noteTakingApi, "UpdateUserResponse", { + content: { + contentType: "application/json", + schema: user, + }, + }), + }, + }); -const noteSchema = new Schema(noteTakingApi, 'Note', { - schema: { - type: 'object', - required: ['title', 'content'], - additionalProperties: false, - properties: { - title: { - type: 'string', - }, - content: { - type: 'string', - }, - labels: { - type: 'array', - items: { - type: 'string', - minLength: 1, - maxLength: 256, - }, - }, - }, - }, +const noteSchema = new Schema(noteTakingApi, "Note", { + schema: { + type: "object", + required: ["title", "content"], + additionalProperties: false, + properties: { + title: { + type: "string", + }, + content: { + type: "string", + }, + labels: { + type: "array", + items: { + type: "string", + minLength: 1, + maxLength: 256, + }, + }, + }, + }, }); -const createNoteRequest = new Reference(noteSchema, 'CreateNoteRequest'); +const createNoteRequest = new Reference(noteSchema, "CreateNoteRequest"); -const notes = new Schema(noteTakingApi, 'Notes', { - schema: { - type: 'array', - uniqueItems: true, - items: noteSchema.referenceObject(), - }, +const notes = new Schema(noteTakingApi, "Notes", { + schema: { + type: "array", + uniqueItems: true, + items: noteSchema.referenceObject(), + }, }); -const noteUserIdParameter = new Parameter(noteTakingApi, 'NoteUserId', { - name: 'userId', - in: 'path', - required: true, - schema: idSchema, +const noteUserIdParameter = new Parameter(noteTakingApi, "NoteUserId", { + name: "userId", + in: "path", + required: true, + schema: idSchema, }); -const noteIdParameter = new Parameter(noteTakingApi, 'NoteId', { - name: 'noteId', - in: 'path', - required: true, - schema: idSchema, +const noteIdParameter = new Parameter(noteTakingApi, "NoteId", { + name: "noteId", + in: "path", + required: true, + schema: idSchema, }); new Path(noteTakingApi, { - path: '/users/{userId}/notes', - tags: new Set([userApiTag]), - parameters: [noteUserIdParameter], + path: "/users/{userId}/notes", + tags: new Set([userApiTag]), + parameters: [noteUserIdParameter], }) - .addOperation("get", { - operationId: 'listNotesCommand', - description: 'List all of the notes', - summary: 'List notes', - responses: { - 200: new Response(noteTakingApi, 'ListNotesResponse', { - description: 'Notes 200 response', - content: { - contentType: 'application/json', - schema: notes, - }, - }), - }, - }) - .addOperation("post", { - operationId: 'createNoteCommand', - deprecated: true, - requestBody: { - required: true, - content: { - contentType: 'application/json', - schema: createNoteRequest, - }, - }, - responses: { - 200: new Response(noteTakingApi, 'CreateNoteResponse', { - description: 'Note created 200 response', - content: { - contentType: 'application/json', - schema: noteSchema, - }, - }), - }, - }); + .addOperation("get", { + operationId: "listNotesCommand", + description: "List all of the notes", + summary: "List notes", + responses: { + 200: new Response(noteTakingApi, "ListNotesResponse", { + description: "Notes 200 response", + content: { + contentType: "application/json", + schema: notes, + }, + }), + }, + }) + .addOperation("post", { + operationId: "createNoteCommand", + deprecated: true, + requestBody: { + required: true, + content: { + contentType: "application/json", + schema: createNoteRequest, + }, + }, + responses: { + 200: new Response(noteTakingApi, "CreateNoteResponse", { + description: "Note created 200 response", + content: { + contentType: "application/json", + schema: noteSchema, + }, + }), + }, + }); -const updateNoteRequest = new Schema(noteTakingApi, 'UpdateNoteRequest', { - schema: { - type: 'object', - minProperties: 1, - additionalProperties: false, - properties: { - title: { - type: 'string', - }, - content: { - type: 'string', - }, - labels: { - type: 'array', - items: { - type: 'string', - minLength: 1, - maxLength: 256, - }, - }, - }, - }, +const updateNoteRequest = new Schema(noteTakingApi, "UpdateNoteRequest", { + schema: { + type: "object", + minProperties: 1, + additionalProperties: false, + properties: { + title: { + type: "string", + }, + content: { + type: "string", + }, + labels: { + type: "array", + items: { + type: "string", + minLength: 1, + maxLength: 256, + }, + }, + }, + }, }); const noteDeleteScopeReq = new SecurityRequirement( - noteTakingApi, - 'NoteDeleteScope', - { - securityScheme: httpBearerJwtScheme, - scopes: ['notes.delete'], - }, + noteTakingApi, + "NoteDeleteScope", + { + securityScheme: httpBearerJwtScheme, + scopes: ["notes.delete"], + }, ); new Path(noteTakingApi, { - path: '/users/{userId}/notes/{noteId}', - parameters: [noteUserIdParameter, noteIdParameter], + path: "/users/{userId}/notes/{noteId}", + parameters: [noteUserIdParameter, noteIdParameter], }) - .addOperation("get", { - operationId: 'getNoteCommand', - responses: { - 200: new Response(noteTakingApi, 'GetNote', { - description: 'Note 200 response', - content: { - contentType: 'application/json', - schema: noteSchema, - }, - }), - }, - }) - .addOperation("delete", { - operationId: 'deleteNoteCommand', - security: noteDeleteScopeReq, - }) - .addOperation("post", { - operationId: 'updateNoteCommand', - requestBody: { - content: { - contentType: 'application/json', - schema: updateNoteRequest, - }, - }, - responses: { - 200: new Response(noteTakingApi, 'UpdateNoteResponse', { - content: { - contentType: 'application/json', - schema: noteSchema, - }, - }), - }, - }); + .addOperation("get", { + operationId: "getNoteCommand", + responses: { + 200: new Response(noteTakingApi, "GetNote", { + description: "Note 200 response", + content: { + contentType: "application/json", + schema: noteSchema, + }, + }), + }, + }) + .addOperation("delete", { + operationId: "deleteNoteCommand", + security: noteDeleteScopeReq, + }) + .addOperation("post", { + operationId: "updateNoteCommand", + requestBody: { + content: { + contentType: "application/json", + schema: updateNoteRequest, + }, + }, + responses: { + 200: new Response(noteTakingApi, "UpdateNoteResponse", { + content: { + contentType: "application/json", + schema: noteSchema, + }, + }), + }, + }); diff --git a/__tests__/fixtures/oas31.json b/__tests__/fixtures/oas31.json deleted file mode 100644 index 9e14a91..0000000 --- a/__tests__/fixtures/oas31.json +++ /dev/null @@ -1,1277 +0,0 @@ -{ - "$id": "https://spec.openapis.org/oas/3.1/schema/2022-10-07", - "$schema": "https://json-schema.org/draft/2020-12/schema", - "description": "The description of OpenAPI v3.1.x documents without schema validation, as defined by https://spec.openapis.org/oas/v3.1.0", - "type": "object", - "properties": { - "openapi": { - "type": "string", - "pattern": "^3\\.1\\.\\d+(-.+)?$" - }, - "info": { - "$ref": "#/$defs/info" - }, - "jsonSchemaDialect": { - "type": "string", - "format": "uri", - "default": "https://spec.openapis.org/oas/3.1/dialect/base" - }, - "servers": { - "type": "array", - "items": { - "$ref": "#/$defs/server" - }, - "default": [ - { - "url": "/" - } - ] - }, - "paths": { - "$ref": "#/$defs/paths" - }, - "webhooks": { - "type": "object", - "additionalProperties": { - "$ref": "#/$defs/path-item-or-reference" - } - }, - "components": { - "$ref": "#/$defs/components" - }, - "security": { - "type": "array", - "items": { - "$ref": "#/$defs/security-requirement" - } - }, - "tags": { - "type": "array", - "items": { - "$ref": "#/$defs/tag" - } - }, - "externalDocs": { - "$ref": "#/$defs/external-documentation" - } - }, - "required": ["openapi", "info"], - "anyOf": [ - { - "required": ["paths"] - }, - { - "required": ["components"] - }, - { - "required": ["webhooks"] - } - ], - "$ref": "#/$defs/specification-extensions", - "unevaluatedProperties": false, - "$defs": { - "info": { - "$comment": "https://spec.openapis.org/oas/v3.1.0#info-object", - "type": "object", - "properties": { - "title": { - "type": "string" - }, - "summary": { - "type": "string" - }, - "description": { - "type": "string" - }, - "termsOfService": { - "type": "string", - "format": "uri" - }, - "contact": { - "$ref": "#/$defs/contact" - }, - "license": { - "$ref": "#/$defs/license" - }, - "version": { - "type": "string" - } - }, - "required": ["title", "version"], - "$ref": "#/$defs/specification-extensions", - "unevaluatedProperties": false - }, - "contact": { - "$comment": "https://spec.openapis.org/oas/v3.1.0#contact-object", - "type": "object", - "properties": { - "name": { - "type": "string" - }, - "url": { - "type": "string", - "format": "uri" - }, - "email": { - "type": "string", - "format": "email" - } - }, - "$ref": "#/$defs/specification-extensions", - "unevaluatedProperties": false - }, - "license": { - "$comment": "https://spec.openapis.org/oas/v3.1.0#license-object", - "type": "object", - "properties": { - "name": { - "type": "string" - }, - "identifier": { - "type": "string" - }, - "url": { - "type": "string", - "format": "uri" - } - }, - "required": ["name"], - "dependentSchemas": { - "identifier": { - "not": { - "required": ["url"] - } - } - }, - "$ref": "#/$defs/specification-extensions", - "unevaluatedProperties": false - }, - "server": { - "$comment": "https://spec.openapis.org/oas/v3.1.0#server-object", - "type": "object", - "properties": { - "url": { - "type": "string", - "format": "uri-reference" - }, - "description": { - "type": "string" - }, - "variables": { - "type": "object", - "additionalProperties": { - "$ref": "#/$defs/server-variable" - } - } - }, - "required": ["url"], - "$ref": "#/$defs/specification-extensions", - "unevaluatedProperties": false - }, - "server-variable": { - "$comment": "https://spec.openapis.org/oas/v3.1.0#server-variable-object", - "type": "object", - "properties": { - "enum": { - "type": "array", - "items": { - "type": "string" - }, - "minItems": 1 - }, - "default": { - "type": "string" - }, - "description": { - "type": "string" - } - }, - "required": ["default"], - "$ref": "#/$defs/specification-extensions", - "unevaluatedProperties": false - }, - "components": { - "$comment": "https://spec.openapis.org/oas/v3.1.0#components-object", - "type": "object", - "properties": { - "schemas": { - "type": "object", - "additionalProperties": { - "$dynamicRef": "#meta" - } - }, - "responses": { - "type": "object", - "additionalProperties": { - "$ref": "#/$defs/response-or-reference" - } - }, - "parameters": { - "type": "object", - "additionalProperties": { - "$ref": "#/$defs/parameter-or-reference" - } - }, - "examples": { - "type": "object", - "additionalProperties": { - "$ref": "#/$defs/example-or-reference" - } - }, - "requestBodies": { - "type": "object", - "additionalProperties": { - "$ref": "#/$defs/request-body-or-reference" - } - }, - "headers": { - "type": "object", - "additionalProperties": { - "$ref": "#/$defs/header-or-reference" - } - }, - "securitySchemes": { - "type": "object", - "additionalProperties": { - "$ref": "#/$defs/security-scheme-or-reference" - } - }, - "links": { - "type": "object", - "additionalProperties": { - "$ref": "#/$defs/link-or-reference" - } - }, - "callbacks": { - "type": "object", - "additionalProperties": { - "$ref": "#/$defs/callbacks-or-reference" - } - }, - "pathItems": { - "type": "object", - "additionalProperties": { - "$ref": "#/$defs/path-item-or-reference" - } - } - }, - "patternProperties": { - "^(schemas|responses|parameters|examples|requestBodies|headers|securitySchemes|links|callbacks|pathItems)$": { - "$comment": "Enumerating all of the property names in the regex above is necessary for unevaluatedProperties to work as expected", - "propertyNames": { - "pattern": "^[a-zA-Z0-9._-]+$" - } - } - }, - "$ref": "#/$defs/specification-extensions", - "unevaluatedProperties": false - }, - "paths": { - "$comment": "https://spec.openapis.org/oas/v3.1.0#paths-object", - "type": "object", - "patternProperties": { - "^/": { - "$ref": "#/$defs/path-item" - } - }, - "$ref": "#/$defs/specification-extensions", - "unevaluatedProperties": false - }, - "path-item": { - "$comment": "https://spec.openapis.org/oas/v3.1.0#path-item-object", - "type": "object", - "properties": { - "summary": { - "type": "string" - }, - "description": { - "type": "string" - }, - "servers": { - "type": "array", - "items": { - "$ref": "#/$defs/server" - } - }, - "parameters": { - "type": "array", - "items": { - "$ref": "#/$defs/parameter-or-reference" - } - }, - "get": { - "$ref": "#/$defs/operation" - }, - "put": { - "$ref": "#/$defs/operation" - }, - "post": { - "$ref": "#/$defs/operation" - }, - "delete": { - "$ref": "#/$defs/operation" - }, - "options": { - "$ref": "#/$defs/operation" - }, - "head": { - "$ref": "#/$defs/operation" - }, - "patch": { - "$ref": "#/$defs/operation" - }, - "trace": { - "$ref": "#/$defs/operation" - } - }, - "$ref": "#/$defs/specification-extensions", - "unevaluatedProperties": false - }, - "path-item-or-reference": { - "if": { - "type": "object", - "required": ["$ref"] - }, - "then": { - "$ref": "#/$defs/reference" - }, - "else": { - "$ref": "#/$defs/path-item" - } - }, - "operation": { - "$comment": "https://spec.openapis.org/oas/v3.1.0#operation-object", - "type": "object", - "properties": { - "tags": { - "type": "array", - "items": { - "type": "string" - } - }, - "summary": { - "type": "string" - }, - "description": { - "type": "string" - }, - "externalDocs": { - "$ref": "#/$defs/external-documentation" - }, - "operationId": { - "type": "string" - }, - "parameters": { - "type": "array", - "items": { - "$ref": "#/$defs/parameter-or-reference" - } - }, - "requestBody": { - "$ref": "#/$defs/request-body-or-reference" - }, - "responses": { - "$ref": "#/$defs/responses" - }, - "callbacks": { - "type": "object", - "additionalProperties": { - "$ref": "#/$defs/callbacks-or-reference" - } - }, - "deprecated": { - "default": false, - "type": "boolean" - }, - "security": { - "type": "array", - "items": { - "$ref": "#/$defs/security-requirement" - } - }, - "servers": { - "type": "array", - "items": { - "$ref": "#/$defs/server" - } - } - }, - "$ref": "#/$defs/specification-extensions", - "unevaluatedProperties": false - }, - "external-documentation": { - "$comment": "https://spec.openapis.org/oas/v3.1.0#external-documentation-object", - "type": "object", - "properties": { - "description": { - "type": "string" - }, - "url": { - "type": "string", - "format": "uri" - } - }, - "required": ["url"], - "$ref": "#/$defs/specification-extensions", - "unevaluatedProperties": false - }, - "parameter": { - "$comment": "https://spec.openapis.org/oas/v3.1.0#parameter-object", - "type": "object", - "properties": { - "name": { - "type": "string" - }, - "in": { - "enum": ["query", "header", "path", "cookie"] - }, - "description": { - "type": "string" - }, - "required": { - "default": false, - "type": "boolean" - }, - "deprecated": { - "default": false, - "type": "boolean" - }, - "schema": { - "$dynamicRef": "#meta" - }, - "content": { - "$ref": "#/$defs/content", - "minProperties": 1, - "maxProperties": 1 - } - }, - "required": ["name", "in"], - "oneOf": [ - { - "required": ["schema"] - }, - { - "required": ["content"] - } - ], - "if": { - "properties": { - "in": { - "const": "query" - } - }, - "required": ["in"] - }, - "then": { - "properties": { - "allowEmptyValue": { - "default": false, - "type": "boolean" - } - } - }, - "dependentSchemas": { - "schema": { - "properties": { - "style": { - "type": "string" - }, - "explode": { - "type": "boolean" - } - }, - "allOf": [ - { - "$ref": "#/$defs/examples" - }, - { - "$ref": "#/$defs/parameter/dependentSchemas/schema/$defs/styles-for-path" - }, - { - "$ref": "#/$defs/parameter/dependentSchemas/schema/$defs/styles-for-header" - }, - { - "$ref": "#/$defs/parameter/dependentSchemas/schema/$defs/styles-for-query" - }, - { - "$ref": "#/$defs/parameter/dependentSchemas/schema/$defs/styles-for-cookie" - }, - { - "$ref": "#/$defs/styles-for-form" - } - ], - "$defs": { - "styles-for-path": { - "if": { - "properties": { - "in": { - "const": "path" - } - }, - "required": ["in"] - }, - "then": { - "properties": { - "style": { - "default": "simple", - "enum": ["matrix", "label", "simple"] - }, - "required": { - "const": true - } - }, - "required": ["required"] - } - }, - "styles-for-header": { - "if": { - "properties": { - "in": { - "const": "header" - } - }, - "required": ["in"] - }, - "then": { - "properties": { - "style": { - "default": "simple", - "const": "simple" - } - } - } - }, - "styles-for-query": { - "if": { - "properties": { - "in": { - "const": "query" - } - }, - "required": ["in"] - }, - "then": { - "properties": { - "style": { - "default": "form", - "enum": [ - "form", - "spaceDelimited", - "pipeDelimited", - "deepObject" - ] - }, - "allowReserved": { - "default": false, - "type": "boolean" - } - } - } - }, - "styles-for-cookie": { - "if": { - "properties": { - "in": { - "const": "cookie" - } - }, - "required": ["in"] - }, - "then": { - "properties": { - "style": { - "default": "form", - "const": "form" - } - } - } - } - } - } - }, - "$ref": "#/$defs/specification-extensions", - "unevaluatedProperties": false - }, - "parameter-or-reference": { - "if": { - "type": "object", - "required": ["$ref"] - }, - "then": { - "$ref": "#/$defs/reference" - }, - "else": { - "$ref": "#/$defs/parameter" - } - }, - "request-body": { - "$comment": "https://spec.openapis.org/oas/v3.1.0#request-body-object", - "type": "object", - "properties": { - "description": { - "type": "string" - }, - "content": { - "$ref": "#/$defs/content" - }, - "required": { - "default": false, - "type": "boolean" - } - }, - "required": ["content"], - "$ref": "#/$defs/specification-extensions", - "unevaluatedProperties": false - }, - "request-body-or-reference": { - "if": { - "type": "object", - "required": ["$ref"] - }, - "then": { - "$ref": "#/$defs/reference" - }, - "else": { - "$ref": "#/$defs/request-body" - } - }, - "content": { - "$comment": "https://spec.openapis.org/oas/v3.1.0#fixed-fields-10", - "type": "object", - "additionalProperties": { - "$ref": "#/$defs/media-type" - }, - "propertyNames": { - "format": "media-range" - } - }, - "media-type": { - "$comment": "https://spec.openapis.org/oas/v3.1.0#media-type-object", - "type": "object", - "properties": { - "schema": { - "$dynamicRef": "#meta" - }, - "encoding": { - "type": "object", - "additionalProperties": { - "$ref": "#/$defs/encoding" - } - } - }, - "allOf": [ - { - "$ref": "#/$defs/specification-extensions" - }, - { - "$ref": "#/$defs/examples" - } - ], - "unevaluatedProperties": false - }, - "encoding": { - "$comment": "https://spec.openapis.org/oas/v3.1.0#encoding-object", - "type": "object", - "properties": { - "contentType": { - "type": "string", - "format": "media-range" - }, - "headers": { - "type": "object", - "additionalProperties": { - "$ref": "#/$defs/header-or-reference" - } - }, - "style": { - "default": "form", - "enum": ["form", "spaceDelimited", "pipeDelimited", "deepObject"] - }, - "explode": { - "type": "boolean" - }, - "allowReserved": { - "default": false, - "type": "boolean" - } - }, - "allOf": [ - { - "$ref": "#/$defs/specification-extensions" - }, - { - "$ref": "#/$defs/styles-for-form" - } - ], - "unevaluatedProperties": false - }, - "responses": { - "$comment": "https://spec.openapis.org/oas/v3.1.0#responses-object", - "type": "object", - "properties": { - "default": { - "$ref": "#/$defs/response-or-reference" - } - }, - "patternProperties": { - "^[1-5](?:[0-9]{2}|XX)$": { - "$ref": "#/$defs/response-or-reference" - } - }, - "minProperties": 1, - "$ref": "#/$defs/specification-extensions", - "unevaluatedProperties": false, - "if": { - "$comment": "either default, or at least one response code property must exist", - "patternProperties": { - "^[1-5](?:[0-9]{2}|XX)$": false - } - }, - "then": { - "required": ["default"] - } - }, - "response": { - "$comment": "https://spec.openapis.org/oas/v3.1.0#response-object", - "type": "object", - "properties": { - "description": { - "type": "string" - }, - "headers": { - "type": "object", - "additionalProperties": { - "$ref": "#/$defs/header-or-reference" - } - }, - "content": { - "$ref": "#/$defs/content" - }, - "links": { - "type": "object", - "additionalProperties": { - "$ref": "#/$defs/link-or-reference" - } - } - }, - "required": ["description"], - "$ref": "#/$defs/specification-extensions", - "unevaluatedProperties": false - }, - "response-or-reference": { - "if": { - "type": "object", - "required": ["$ref"] - }, - "then": { - "$ref": "#/$defs/reference" - }, - "else": { - "$ref": "#/$defs/response" - } - }, - "callbacks": { - "$comment": "https://spec.openapis.org/oas/v3.1.0#callback-object", - "type": "object", - "$ref": "#/$defs/specification-extensions", - "additionalProperties": { - "$ref": "#/$defs/path-item-or-reference" - } - }, - "callbacks-or-reference": { - "if": { - "type": "object", - "required": ["$ref"] - }, - "then": { - "$ref": "#/$defs/reference" - }, - "else": { - "$ref": "#/$defs/callbacks" - } - }, - "example": { - "$comment": "https://spec.openapis.org/oas/v3.1.0#example-object", - "type": "object", - "properties": { - "summary": { - "type": "string" - }, - "description": { - "type": "string" - }, - "value": true, - "externalValue": { - "type": "string", - "format": "uri" - } - }, - "not": { - "required": ["value", "externalValue"] - }, - "$ref": "#/$defs/specification-extensions", - "unevaluatedProperties": false - }, - "example-or-reference": { - "if": { - "type": "object", - "required": ["$ref"] - }, - "then": { - "$ref": "#/$defs/reference" - }, - "else": { - "$ref": "#/$defs/example" - } - }, - "link": { - "$comment": "https://spec.openapis.org/oas/v3.1.0#link-object", - "type": "object", - "properties": { - "operationRef": { - "type": "string", - "format": "uri-reference" - }, - "operationId": { - "type": "string" - }, - "parameters": { - "$ref": "#/$defs/map-of-strings" - }, - "requestBody": true, - "description": { - "type": "string" - }, - "body": { - "$ref": "#/$defs/server" - } - }, - "oneOf": [ - { - "required": ["operationRef"] - }, - { - "required": ["operationId"] - } - ], - "$ref": "#/$defs/specification-extensions", - "unevaluatedProperties": false - }, - "link-or-reference": { - "if": { - "type": "object", - "required": ["$ref"] - }, - "then": { - "$ref": "#/$defs/reference" - }, - "else": { - "$ref": "#/$defs/link" - } - }, - "header": { - "$comment": "https://spec.openapis.org/oas/v3.1.0#header-object", - "type": "object", - "properties": { - "description": { - "type": "string" - }, - "required": { - "default": false, - "type": "boolean" - }, - "deprecated": { - "default": false, - "type": "boolean" - }, - "schema": { - "$dynamicRef": "#meta" - }, - "content": { - "$ref": "#/$defs/content", - "minProperties": 1, - "maxProperties": 1 - } - }, - "oneOf": [ - { - "required": ["schema"] - }, - { - "required": ["content"] - } - ], - "dependentSchemas": { - "schema": { - "properties": { - "style": { - "default": "simple", - "const": "simple" - }, - "explode": { - "default": false, - "type": "boolean" - } - }, - "$ref": "#/$defs/examples" - } - }, - "$ref": "#/$defs/specification-extensions", - "unevaluatedProperties": false - }, - "header-or-reference": { - "if": { - "type": "object", - "required": ["$ref"] - }, - "then": { - "$ref": "#/$defs/reference" - }, - "else": { - "$ref": "#/$defs/header" - } - }, - "tag": { - "$comment": "https://spec.openapis.org/oas/v3.1.0#tag-object", - "type": "object", - "properties": { - "name": { - "type": "string" - }, - "description": { - "type": "string" - }, - "externalDocs": { - "$ref": "#/$defs/external-documentation" - } - }, - "required": ["name"], - "$ref": "#/$defs/specification-extensions", - "unevaluatedProperties": false - }, - "reference": { - "$comment": "https://spec.openapis.org/oas/v3.1.0#reference-object", - "type": "object", - "properties": { - "$ref": { - "type": "string", - "format": "uri-reference" - }, - "summary": { - "type": "string" - }, - "description": { - "type": "string" - } - } - }, - "schema": { - "$comment": "https://spec.openapis.org/oas/v3.1.0#schema-object", - "$dynamicAnchor": "meta", - "type": ["object", "boolean"] - }, - "security-scheme": { - "$comment": "https://spec.openapis.org/oas/v3.1.0#security-scheme-object", - "type": "object", - "properties": { - "type": { - "enum": ["apiKey", "http", "mutualTLS", "oauth2", "openIdConnect"] - }, - "description": { - "type": "string" - } - }, - "required": ["type"], - "allOf": [ - { - "$ref": "#/$defs/specification-extensions" - }, - { - "$ref": "#/$defs/security-scheme/$defs/type-apikey" - }, - { - "$ref": "#/$defs/security-scheme/$defs/type-http" - }, - { - "$ref": "#/$defs/security-scheme/$defs/type-http-bearer" - }, - { - "$ref": "#/$defs/security-scheme/$defs/type-oauth2" - }, - { - "$ref": "#/$defs/security-scheme/$defs/type-oidc" - } - ], - "unevaluatedProperties": false, - "$defs": { - "type-apikey": { - "if": { - "properties": { - "type": { - "const": "apiKey" - } - }, - "required": ["type"] - }, - "then": { - "properties": { - "name": { - "type": "string" - }, - "in": { - "enum": ["query", "header", "cookie"] - } - }, - "required": ["name", "in"] - } - }, - "type-http": { - "if": { - "properties": { - "type": { - "const": "http" - } - }, - "required": ["type"] - }, - "then": { - "properties": { - "scheme": { - "type": "string" - } - }, - "required": ["scheme"] - } - }, - "type-http-bearer": { - "if": { - "properties": { - "type": { - "const": "http" - }, - "scheme": { - "type": "string", - "pattern": "^[Bb][Ee][Aa][Rr][Ee][Rr]$" - } - }, - "required": ["type", "scheme"] - }, - "then": { - "properties": { - "bearerFormat": { - "type": "string" - } - } - } - }, - "type-oauth2": { - "if": { - "properties": { - "type": { - "const": "oauth2" - } - }, - "required": ["type"] - }, - "then": { - "properties": { - "flows": { - "$ref": "#/$defs/oauth-flows" - } - }, - "required": ["flows"] - } - }, - "type-oidc": { - "if": { - "properties": { - "type": { - "const": "openIdConnect" - } - }, - "required": ["type"] - }, - "then": { - "properties": { - "openIdConnectUrl": { - "type": "string", - "format": "uri" - } - }, - "required": ["openIdConnectUrl"] - } - } - } - }, - "security-scheme-or-reference": { - "if": { - "type": "object", - "required": ["$ref"] - }, - "then": { - "$ref": "#/$defs/reference" - }, - "else": { - "$ref": "#/$defs/security-scheme" - } - }, - "oauth-flows": { - "type": "object", - "properties": { - "implicit": { - "$ref": "#/$defs/oauth-flows/$defs/implicit" - }, - "password": { - "$ref": "#/$defs/oauth-flows/$defs/password" - }, - "clientCredentials": { - "$ref": "#/$defs/oauth-flows/$defs/client-credentials" - }, - "authorizationCode": { - "$ref": "#/$defs/oauth-flows/$defs/authorization-code" - } - }, - "$ref": "#/$defs/specification-extensions", - "unevaluatedProperties": false, - "$defs": { - "implicit": { - "type": "object", - "properties": { - "authorizationUrl": { - "type": "string", - "format": "uri" - }, - "refreshUrl": { - "type": "string", - "format": "uri" - }, - "scopes": { - "$ref": "#/$defs/map-of-strings" - } - }, - "required": ["authorizationUrl", "scopes"], - "$ref": "#/$defs/specification-extensions", - "unevaluatedProperties": false - }, - "password": { - "type": "object", - "properties": { - "tokenUrl": { - "type": "string", - "format": "uri" - }, - "refreshUrl": { - "type": "string", - "format": "uri" - }, - "scopes": { - "$ref": "#/$defs/map-of-strings" - } - }, - "required": ["tokenUrl", "scopes"], - "$ref": "#/$defs/specification-extensions", - "unevaluatedProperties": false - }, - "client-credentials": { - "type": "object", - "properties": { - "tokenUrl": { - "type": "string", - "format": "uri" - }, - "refreshUrl": { - "type": "string", - "format": "uri" - }, - "scopes": { - "$ref": "#/$defs/map-of-strings" - } - }, - "required": ["tokenUrl", "scopes"], - "$ref": "#/$defs/specification-extensions", - "unevaluatedProperties": false - }, - "authorization-code": { - "type": "object", - "properties": { - "authorizationUrl": { - "type": "string", - "format": "uri" - }, - "tokenUrl": { - "type": "string", - "format": "uri" - }, - "refreshUrl": { - "type": "string", - "format": "uri" - }, - "scopes": { - "$ref": "#/$defs/map-of-strings" - } - }, - "required": ["authorizationUrl", "tokenUrl", "scopes"], - "$ref": "#/$defs/specification-extensions", - "unevaluatedProperties": false - } - } - }, - "security-requirement": { - "$comment": "https://spec.openapis.org/oas/v3.1.0#security-requirement-object", - "type": "object", - "additionalProperties": { - "type": "array", - "items": { - "type": "string" - } - } - }, - "specification-extensions": { - "$comment": "https://spec.openapis.org/oas/v3.1.0#specification-extensions", - "patternProperties": { - "^x-": true - } - }, - "examples": { - "properties": { - "example": true, - "examples": { - "type": "object", - "additionalProperties": { - "$ref": "#/$defs/example-or-reference" - } - } - } - }, - "map-of-strings": { - "type": "object", - "additionalProperties": { - "type": "string" - } - }, - "styles-for-form": { - "if": { - "properties": { - "style": { - "const": "form" - } - }, - "required": ["style"] - }, - "then": { - "properties": { - "explode": { - "default": true - } - } - }, - "else": { - "properties": { - "explode": { - "default": false - } - } - } - } - } -} diff --git a/__tests__/json-schema.test.ts b/__tests__/json-schema.test.ts index 230dc0f..12be246 100644 --- a/__tests__/json-schema.test.ts +++ b/__tests__/json-schema.test.ts @@ -1,31 +1,36 @@ -/* eslint-disable no-new */ -import { Ajv } from 'ajv'; -import { test, expect, describe } from 'vitest'; -import { exampleApi } from './fixtures/apis/example.ts'; -import { noteTakingApi } from './fixtures/apis/note-taking.ts'; +import { validate } from "@hyperjump/json-schema/draft-07"; +import { describe, expect, test } from "vitest"; +import { exampleApi } from "./fixtures/apis/example.ts"; +import { noteTakingApi } from "./fixtures/apis/note-taking.ts"; +import { toJson } from "./json.ts"; -describe('Example', () => { - const jsonSchema = exampleApi.synthJsonSchema(); +describe.each([ + ["Example", exampleApi], + ["Note Taking", noteTakingApi], +])("%s", (_, api) => { + const jsonSchema = api.synthJsonSchema(); - test('JSON Schema snapshot', async () => { - expect(jsonSchema).toMatchSnapshot(); - }); + test("JSON Schema snapshot", () => { + expect(jsonSchema).toMatchSnapshot(); + }); - test('JSON Schema AJV validate', async () => { - const ajv = new Ajv(); - expect(ajv.validateSchema(jsonSchema)).toBeTruthy(); - }); -}); + test("JSON Schema validates against the dialect it declares", async () => { + const output = await validate( + jsonSchema.$schema, + toJson(jsonSchema), + "BASIC", + ); -describe('Note Taking', () => { - const jsonSchema = noteTakingApi.synthJsonSchema(); + expect(output).toStrictEqual({ valid: true }); + }); - test('JSON Schema snapshot', async () => { - expect(jsonSchema).toMatchSnapshot(); - }); + test("JSON Schema dialect rejects an invalid type", async () => { + const output = await validate( + jsonSchema.$schema, + toJson({ ...jsonSchema, definitions: { Invalid: { type: "nope" } } }), + "BASIC", + ); - test('JSON Schema AJV validate', async () => { - const ajv = new Ajv(); - expect(ajv.validateSchema(jsonSchema)).toBeTruthy(); - }); + expect(output.valid).toBe(false); + }); }); diff --git a/__tests__/json.ts b/__tests__/json.ts new file mode 100644 index 0000000..fc8ac53 --- /dev/null +++ b/__tests__/json.ts @@ -0,0 +1,31 @@ +import type { Validator } from "@hyperjump/json-schema/openapi-3-1"; + +type Json = Parameters[0]; + +/** + * Checks each value, since the construct types admit values JSON cannot hold + */ +export function toJson(value: unknown): Json { + if ( + value === null || + typeof value === "string" || + typeof value === "number" || + typeof value === "boolean" + ) { + return value; + } + + if (Array.isArray(value)) { + return value.map((item: unknown) => toJson(item)); + } + + if (typeof value === "object") { + return Object.fromEntries( + Object.entries(value) + .filter(([, item]) => item !== undefined) + .map(([key, item]) => [key, toJson(item)]), + ); + } + + throw new TypeError(`A ${typeof value} is not JSON`); +} diff --git a/__tests__/openapi-schema.test.ts b/__tests__/openapi-schema.test.ts index 62294c8..5dcdbee 100644 --- a/__tests__/openapi-schema.test.ts +++ b/__tests__/openapi-schema.test.ts @@ -1,34 +1,35 @@ -import SwaggerParser from '@apidevtools/swagger-parser'; -import { test, expect, describe } from 'vitest'; -import { exampleApi } from './fixtures/apis/example.ts'; -import { noteTakingApi } from './fixtures/apis/note-taking.ts'; +import { validate } from "@hyperjump/json-schema/openapi-3-1"; +import { describe, expect, test } from "vitest"; +import { exampleApi } from "./fixtures/apis/example.ts"; +import { noteTakingApi } from "./fixtures/apis/note-taking.ts"; +import { toJson } from "./json.ts"; -describe('Example', () => { - test('OpenAPI', async () => { - const document = exampleApi.synth(); - expect(document).toMatchSnapshot(); - }); +// schema-base also checks each Schema Object against the OpenAPI 3.1 dialect +const oas31SchemaBase = "https://spec.openapis.org/oas/3.1/schema-base"; - test('Swagger Parser validate', async () => { - const document = exampleApi.synth(); - // WARN: this function mutates the input - // @ts-expect-error openapi3-ts and openapi-types have incompatible types under exactOptionalPropertyTypes - const result = await SwaggerParser.validate(structuredClone(document)); - expect(result).toMatchSnapshot(); - }); -}); +describe.each([ + ["Example", exampleApi], + ["Note Taking", noteTakingApi], +])("%s", (_, api) => { + const document = api.synth(); + + test("OpenAPI", () => { + expect(document).toMatchSnapshot(); + }); + + test("OpenAPI 3.1 schema validate", async () => { + const output = await validate(oas31SchemaBase, toJson(document), "BASIC"); + + expect(output).toStrictEqual({ valid: true }); + }); -describe('Note Taking', () => { - test('OpenAPI', async () => { - const document = noteTakingApi.synth(); - expect(document).toMatchSnapshot(); - }); + test("OpenAPI 3.1 schema rejects an unknown top-level key", async () => { + const output = await validate( + oas31SchemaBase, + toJson({ ...document, bogus: true }), + "BASIC", + ); - test('Swagger Parser validate', async () => { - const document = noteTakingApi.synth(); - // WARN: this function mutates the input - // @ts-expect-error openapi3-ts and openapi-types have incompatible types under exactOptionalPropertyTypes - const result = await SwaggerParser.validate(structuredClone(document)); - expect(result).toMatchSnapshot(); - }); + expect(output.valid).toBe(false); + }); }); diff --git a/__tests__/parameter-types.test-d.ts b/__tests__/parameter-types.test-d.ts index fea21b0..aead901 100644 --- a/__tests__/parameter-types.test-d.ts +++ b/__tests__/parameter-types.test-d.ts @@ -1,42 +1,42 @@ -import { expectTypeOf } from 'vitest'; -import type { Parameter } from '../lib/parameter.ts'; -import type { ValidParameter } from '../lib/types.ts'; +import { expectTypeOf } from "vitest"; +import type { Parameter } from "../lib/parameter.ts"; +import type { ValidParameter } from "../lib/types.ts"; // Test that only matching path param names are allowed -type PathParams = ValidParameter<'/users/{userId}'>; -expectTypeOf>().toExtend(); +type PathParams = ValidParameter<"/users/{userId}">; +expectTypeOf>().toExtend(); -// @ts-expect-error path parameter with wrong name is not allowed -expectTypeOf>().toExtend(); +// path parameter with wrong name is not allowed +expectTypeOf>().not.toExtend(); // Test that query parameters can be any string -expectTypeOf>().toExtend< - ValidParameter<'/users/{userId}'> +expectTypeOf>().toExtend< + ValidParameter<"/users/{userId}"> >(); // Test that lowercase header parameters are allowed -expectTypeOf>().toExtend< - ValidParameter<'/users/{userId}'> +expectTypeOf>().toExtend< + ValidParameter<"/users/{userId}"> >(); -// @ts-expect-error uppercase header parameter names are not allowed (HTTP/2) -expectTypeOf>().toExtend< - ValidParameter<'/users/{userId}'> +// uppercase header parameter names are not allowed (HTTP/2) +expectTypeOf>().not.toExtend< + ValidParameter<"/users/{userId}"> >(); // Test that cookie parameters can be any string -expectTypeOf>().toExtend< - ValidParameter<'/users/{userId}'> +expectTypeOf>().toExtend< + ValidParameter<"/users/{userId}"> >(); // Test multi-param routes -type MultiParamRoute = ValidParameter<'/users/{userId}/notes/{noteId}'>; -expectTypeOf>().toExtend(); -expectTypeOf>().toExtend(); +type MultiParamRoute = ValidParameter<"/users/{userId}/notes/{noteId}">; +expectTypeOf>().toExtend(); +expectTypeOf>().toExtend(); -// @ts-expect-error path parameter not in route -expectTypeOf>().toExtend(); +// path parameter not in route +expectTypeOf>().not.toExtend(); // Test that non-path parameters work for any route -expectTypeOf>().toExtend(); -expectTypeOf>().toExtend(); +expectTypeOf>().toExtend(); +expectTypeOf>().toExtend(); diff --git a/__tests__/regression.test.ts b/__tests__/regression.test.ts index d2d6ed9..9cf0919 100644 --- a/__tests__/regression.test.ts +++ b/__tests__/regression.test.ts @@ -1,52 +1,54 @@ -/* eslint-disable no-new */ -import { test } from 'vitest'; -import { Api, Schema } from '@block65/openapi-constructs'; +import { Api, Schema } from "@block65/openapi-constructs"; +import { expect, test } from "vitest"; -test('Regression', async () => { - const api = new Api({ - openapi: '3.1.0', - info: { - title: 'Example', - version: '1.0.0', - }, - }); +test("Regression", async () => { + const api = new Api({ + openapi: "3.1.0", + info: { + title: "Example", + version: "1.0.0", + }, + }); - const schema1 = new Schema(api, 'Test1', { - schema: { - type: 'object', - additionalProperties: false, - minProperties: 1, - properties: { - description: { - oneOf: [ - { - type: ['string', 'null'], - minLength: 1, - maxLength: 1024, - }, - { - type: 'null', - }, - ], - }, - }, - }, - }); + const schema1 = new Schema(api, "Test1", { + schema: { + type: "object", + additionalProperties: false, + minProperties: 1, + properties: { + description: { + oneOf: [ + { + type: ["string", "null"], + minLength: 1, + maxLength: 1024, + }, + { + type: "null", + }, + ], + }, + }, + }, + }); - new Schema(api, 'Test2', { - schema: { - allOf: [ - schema1.schema, - { - type: 'object', - required: ['name'], - properties: { - name: { - type: 'string', - }, - }, - }, - ], - }, - }); + expect( + () => + new Schema(api, "Test2", { + schema: { + allOf: [ + schema1.schema, + { + type: "object", + required: ["name"], + properties: { + name: { + type: "string", + }, + }, + }, + ], + }, + }), + ).not.toThrow(); }); diff --git a/examples/example.ts b/examples/example.ts index abf7a40..e6c495c 100644 --- a/examples/example.ts +++ b/examples/example.ts @@ -1,205 +1,205 @@ -/* eslint-disable no-new */ +// oxlint-disable no-new -- constructs attach to their scope when built import { - Api, - Parameter, - Path, - Reference, - Response, - Schema, - SecurityRequirement, - SecurityScheme, - Server, - Tag, -} from '@block65/openapi-constructs'; + Api, + Parameter, + Path, + Reference, + Response, + Schema, + SecurityRequirement, + SecurityScheme, + Server, + Tag, +} from "@block65/openapi-constructs"; const api = new Api({ - openapi: "3.1.0", - info: { - title: 'Example REST API', - version: '1.0.0', - }, + openapi: "3.1.0", + info: { + title: "Example REST API", + version: "1.0.0", + }, }); -new Server(api, 'ExampleServer', { - url: new URL('https://api.example.com'), +new Server(api, "ExampleServer", { + url: new URL("https://api.example.com"), }); -const httpBearerJwtScheme = new SecurityScheme(api, 'HttpBearerJwtScheme', { - type: 'http', - scheme: 'bearer', - bearerFormat: 'JWT', +const httpBearerJwtScheme = new SecurityScheme(api, "HttpBearerJwtScheme", { + type: "http", + scheme: "bearer", + bearerFormat: "JWT", }); -new SecurityRequirement(api, 'AllScopes', { - securityScheme: httpBearerJwtScheme, - scopes: [], +new SecurityRequirement(api, "AllScopes", { + securityScheme: httpBearerJwtScheme, + scopes: [], }); -const userTag = new Tag(api, 'UserTag', { - name: 'user', +const userTag = new Tag(api, "UserTag", { + name: "user", }); -const userDeleteScopeReq = new SecurityRequirement(api, 'UserDeleteScope', { - securityScheme: httpBearerJwtScheme, - scopes: ['users.delete'], +const userDeleteScopeReq = new SecurityRequirement(api, "UserDeleteScope", { + securityScheme: httpBearerJwtScheme, + scopes: ["users.delete"], }); -const noSecurityRequirement = new SecurityRequirement(api, 'NoSecurity'); - -const addressSchema = new Schema(api, 'Address', { - schema: { - type: 'object', - required: ['postcode'], - additionalProperties: false, - properties: { - postcode: { - type: 'integer', - format: 'int32', - minimum: 1000, - maximum: 9999, - }, - }, - }, +const noSecurityRequirement = new SecurityRequirement(api, "NoSecurity"); + +const addressSchema = new Schema(api, "Address", { + schema: { + type: "object", + required: ["postcode"], + additionalProperties: false, + properties: { + postcode: { + type: "integer", + format: "int32", + minimum: 1000, + maximum: 9999, + }, + }, + }, }); -const idSchema = new Schema(api, 'Id', { - schema: { - type: 'string', - minLength: 6, - maxLength: 6, - }, +const idSchema = new Schema(api, "Id", { + schema: { + type: "string", + minLength: 6, + maxLength: 6, + }, }); -const user = new Schema(api, 'User', { - schema: { - type: 'object', - required: ['name'], - additionalProperties: false, - properties: { - userId: idSchema.referenceObject(), - name: { - type: 'string', - }, - address: addressSchema.referenceObject(), - age: { - type: 'integer', - format: 'int32', - minimum: 0, - }, - }, - }, +const user = new Schema(api, "User", { + schema: { + type: "object", + required: ["name"], + additionalProperties: false, + properties: { + userId: idSchema.referenceObject(), + name: { + type: "string", + }, + address: addressSchema.referenceObject(), + age: { + type: "integer", + format: "int32", + minimum: 0, + }, + }, + }, }); -const updateUserRequest = new Schema(api, 'UpdateUserRequest', { - schema: { - type: 'object', - minProperties: 1, - additionalProperties: false, - properties: { - address: addressSchema.referenceObject(), - age: { - type: 'integer', - format: 'int32', - minimum: 0, - }, - }, - examples: [{ age: 10, address: { postcode: 2000 } }], - }, +const updateUserRequest = new Schema(api, "UpdateUserRequest", { + schema: { + type: "object", + minProperties: 1, + additionalProperties: false, + properties: { + address: addressSchema.referenceObject(), + age: { + type: "integer", + format: "int32", + minimum: 0, + }, + }, + examples: [{ age: 10, address: { postcode: 2000 } }], + }, }); -const createUserRequest = new Reference(user, 'CreateUserRequest'); +const createUserRequest = new Reference(user, "CreateUserRequest"); -const users = new Schema(api, 'Users', { - schema: { - type: 'array', - uniqueItems: true, - items: user.referenceObject(), - examples: [[1, 2, 3]], - }, +const users = new Schema(api, "Users", { + schema: { + type: "array", + uniqueItems: true, + items: user.referenceObject(), + examples: [[1, 2, 3]], + }, }); -const userIdParameter = new Parameter(api, 'UserId', { - name: 'userId', - in: 'path', - required: true, - schema: idSchema, +const userIdParameter = new Parameter(api, "UserId", { + name: "userId", + in: "path", + required: true, + schema: idSchema, }); new Path(api, { - path: '/users', - tags: new Set([userTag]), + path: "/users", + tags: new Set([userTag]), }) - .addOperation("get", { - operationId: 'listUsersCommand', - responses: { - 200: new Response(api, 'ListUsersResponse', { - description: 'User 200 response', - content: { - contentType: 'application/json', - schema: users, - }, - }), - }, - }) - .addOperation("post", { - operationId: 'createUserCommand', - requestBody: { - content: { - contentType: 'application/json', - schema: createUserRequest, - }, - }, - responses: { - 200: new Response(api, 'CreateUserResponse', { - description: 'User 200 response', - content: { - contentType: 'application/json', - schema: users, - }, - }), - }, - }); + .addOperation("get", { + operationId: "listUsersCommand", + responses: { + 200: new Response(api, "ListUsersResponse", { + description: "User 200 response", + content: { + contentType: "application/json", + schema: users, + }, + }), + }, + }) + .addOperation("post", { + operationId: "createUserCommand", + requestBody: { + content: { + contentType: "application/json", + schema: createUserRequest, + }, + }, + responses: { + 200: new Response(api, "CreateUserResponse", { + description: "User 200 response", + content: { + contentType: "application/json", + schema: users, + }, + }), + }, + }); new Path(api, { - path: '/users/{userId}', - parameters: [userIdParameter], + path: "/users/{userId}", + parameters: [userIdParameter], }) - .addOperation("get", { - operationId: 'getUserByIdCommand', - responses: { - 200: new Response(api, 'GetUserById', { - description: 'User 200 response', - content: { - contentType: 'application/json', - schema: user, - }, - }), - }, - }) - .addOperation("delete", { - operationId: 'deleteUserByIdCommand', - security: userDeleteScopeReq, - }) - .addOperation("head", { - operationId: 'checkUserIdAvailableCommand', - security: noSecurityRequirement, - }) - .addOperation("post", { - operationId: 'updateUserCommand', - requestBody: { - content: { - contentType: 'application/json', - schema: updateUserRequest, - }, - }, - responses: { - 200: new Response(api, 'UpdateUserResponse', { - content: { - contentType: 'application/json', - schema: user, - }, - }), - }, - }); - -process.stdout.write(JSON.stringify(api.synth(), null, 2)); + .addOperation("get", { + operationId: "getUserByIdCommand", + responses: { + 200: new Response(api, "GetUserById", { + description: "User 200 response", + content: { + contentType: "application/json", + schema: user, + }, + }), + }, + }) + .addOperation("delete", { + operationId: "deleteUserByIdCommand", + security: userDeleteScopeReq, + }) + .addOperation("head", { + operationId: "checkUserIdAvailableCommand", + security: noSecurityRequirement, + }) + .addOperation("post", { + operationId: "updateUserCommand", + requestBody: { + content: { + contentType: "application/json", + schema: updateUserRequest, + }, + }, + responses: { + 200: new Response(api, "UpdateUserResponse", { + content: { + contentType: "application/json", + schema: user, + }, + }), + }, + }); + +process.stdout.write(JSON.stringify(api.synth(), undefined, 2)); diff --git a/justfile b/justfile new file mode 100644 index 0000000..0d9a582 --- /dev/null +++ b/justfile @@ -0,0 +1,29 @@ +check: typecheck lint fmt-check test dead-code + +typecheck: + pnpm exec oxlint --type-aware --type-check + +lint: + pnpm exec oxlint + +# CI reads the annotations, which only this format writes +lint-ci: + pnpm exec oxlint --format=github + +fmt: + pnpm exec oxfmt + +fmt-check: + pnpm exec oxfmt --check + +test: + pnpm exec vitest run + +dead-code: + pnpm exec fallow + +clean: + rm -rf node_modules + +# no build, so just alias and keep the standard +dist-clean: clean diff --git a/lib/ApiLowLevel.ts b/lib/ApiLowLevel.ts deleted file mode 100644 index 2ab0e77..0000000 --- a/lib/ApiLowLevel.ts +++ /dev/null @@ -1,15 +0,0 @@ -import { Construct, type IConstruct } from 'constructs'; -import type { Api } from './api.ts'; - -export class ApiLowLevel extends Construct { - public static of(c: IConstruct): Api { - const { scope } = c.node; - - if (!scope) { - // Api is the only construct without a scope. - return c as Api; - } - - return ApiLowLevel.of(scope); - } -} diff --git a/lib/api-low-level.ts b/lib/api-low-level.ts new file mode 100644 index 0000000..51377dd --- /dev/null +++ b/lib/api-low-level.ts @@ -0,0 +1,16 @@ +import { RootConstruct, type IConstruct } from "constructs"; + +export class ApiLowLevel extends RootConstruct { + public static of( + this: abstract new (...args: never[]) => T, + c: IConstruct, + ): T { + const { root } = c.node; + + if (root instanceof this) { + return root; + } + + throw new TypeError(`${c.node.path} is not in a ${this.name} tree`); + } +} diff --git a/lib/api.ts b/lib/api.ts index 2cae57a..8c12545 100644 --- a/lib/api.ts +++ b/lib/api.ts @@ -1,93 +1,92 @@ -import type { JSONSchema7 } from 'json-schema'; -import type { oas31 } from 'openapi3-ts'; -import { ApiLowLevel } from './ApiLowLevel.ts'; -import { Header } from './header.ts'; -import { Parameter } from './parameter.ts'; -import { Path } from './path.ts'; -import { Reference } from './reference.ts'; -import { Schema } from './schema.ts'; -import { SecurityRequirement } from './security-requirement.ts'; -import { SecurityScheme } from './security-scheme.ts'; -import { Server } from './server.ts'; -import { Tag } from './tag.ts'; +import type { JSONSchema7 } from "json-schema"; +import type { oas31 } from "openapi3-ts"; +import { ApiLowLevel } from "./api-low-level.ts"; +import { Header } from "./header.ts"; +import { Parameter } from "./parameter.ts"; +import { Path } from "./path.ts"; +import { Reference } from "./reference.ts"; +import { Schema } from "./schema.ts"; +import { SecurityRequirement } from "./security-requirement.ts"; +import { SecurityScheme } from "./security-scheme.ts"; +import { Server } from "./server.ts"; +import { Tag } from "./tag.ts"; -export type OpenApiVersion = '3.0' | '3.1.0'; +export type OpenApiVersion = "3.0" | "3.1.0"; -export interface ApiOptions { - openapi: OpenApiVersion; - info: oas31.InfoObject; -} +export type ApiOptions = { + openapi: OpenApiVersion; + info: oas31.InfoObject; +}; export class Api extends ApiLowLevel { - private options: ApiOptions; + private options: ApiOptions; - constructor(options: ApiOptions) { - // eslint-disable-next-line @typescript-eslint/no-unsafe-argument, @typescript-eslint/no-explicit-any - super(undefined as any, ''); + constructor(options: ApiOptions) { + super(""); - this.options = options; - } + this.options = options; + } - public synth() { - return { - openapi: this.options.openapi, - info: this.options.info, - servers: this.node.children - .filter((child): child is Server => child instanceof Server) - .map((child) => child.synth()), - tags: this.node.children - .filter((child): child is Tag => child instanceof Tag) - .map((child) => child.synth()), - components: { - schemas: Object.fromEntries( - this.node.children - .filter( - (child): child is Schema | Reference => - child instanceof Schema || child instanceof Reference, - ) - .map((child) => [child.schemaKey, child.synth()]), - ), - parameters: Object.fromEntries( - this.node.children - .filter((child): child is Parameter => child instanceof Parameter) - .map((child) => [child.schemaKey, child.synth()]), - ), - securitySchemes: Object.fromEntries( - this.node.children - .filter( - (child): child is SecurityScheme => - child instanceof SecurityScheme, - ) - .map((child) => [child.schemaKey, child.synth()]), - ), - headers: Object.fromEntries( - this.node.children - .filter((child): child is Header => child instanceof Header) - .map((child) => [child.schemaKey, child.synth()]), - ), - }, - paths: Object.fromEntries( - this.node.children - .filter((child): child is Path => child instanceof Path) - .map((child) => [child.schemaKey, child.synth()]), - ), - security: this.node.children - .filter( - (child): child is SecurityRequirement => - child instanceof SecurityRequirement, - ) - .map((child) => child.synth()), - } satisfies oas31.OpenAPIObject; - } + public synth() { + return { + openapi: this.options.openapi, + info: this.options.info, + servers: this.node.children + .filter((child): child is Server => child instanceof Server) + .map((child) => child.synth()), + tags: this.node.children + .filter((child): child is Tag => child instanceof Tag) + .map((child) => child.synth()), + components: { + schemas: Object.fromEntries( + this.node.children + .filter( + (child): child is Schema | Reference => + child instanceof Schema || child instanceof Reference, + ) + .map((child) => [child.schemaKey, child.synth()]), + ), + parameters: Object.fromEntries( + this.node.children + .filter((child): child is Parameter => child instanceof Parameter) + .map((child) => [child.schemaKey, child.synth()]), + ), + securitySchemes: Object.fromEntries( + this.node.children + .filter( + (child): child is SecurityScheme => + child instanceof SecurityScheme, + ) + .map((child) => [child.schemaKey, child.synth()]), + ), + headers: Object.fromEntries( + this.node.children + .filter((child): child is Header => child instanceof Header) + .map((child) => [child.schemaKey, child.synth()]), + ), + }, + paths: Object.fromEntries( + this.node.children + .filter((child): child is Path => child instanceof Path) + .map((child) => [child.schemaKey, child.synth()]), + ), + security: this.node.children + .filter( + (child): child is SecurityRequirement => + child instanceof SecurityRequirement, + ) + .map((child) => child.synth()), + } satisfies oas31.OpenAPIObject; + } - public synthJsonSchema() { - return { - $schema: 'http://json-schema.org/draft-07/schema#', - definitions: Object.fromEntries( - this.node.children - .filter((child): child is Schema => child instanceof Schema) - .map((child) => [child.schemaKey, child.synth()]), - ), - } satisfies JSONSchema7; - } + public synthJsonSchema() { + return { + $schema: "http://json-schema.org/draft-07/schema#", + definitions: Object.fromEntries( + this.node.children + .filter((child): child is Schema => child instanceof Schema) + .map((child) => [child.schemaKey, child.synth()]), + ), + } satisfies JSONSchema7; + } } diff --git a/lib/header.ts b/lib/header.ts index 3ae9b80..d636eaa 100644 --- a/lib/header.ts +++ b/lib/header.ts @@ -1,66 +1,70 @@ -import { Construct } from 'constructs'; -import type { oas31 } from 'openapi3-ts'; -import type { Schema } from './schema.ts'; +import { Construct } from "constructs"; +import type { oas31 } from "openapi3-ts"; +import type { Schema } from "./schema.ts"; -interface HeaderOptions { - description?: string; - required?: boolean; - deprecated?: boolean; - allowEmptyValue?: boolean; - style?: 'simple'; - explode?: boolean; - allowReserved?: boolean; - schema: Schema; -} +type HeaderOptions = { + description?: string; + required?: boolean; + deprecated?: boolean; + allowEmptyValue?: boolean; + style?: "simple"; + explode?: boolean; + allowReserved?: boolean; + schema: Schema; +}; export class Header extends Construct { - private options: HeaderOptions; + private options: HeaderOptions; - constructor(scope: Construct, id: TName & Lowercase, options: HeaderOptions) { - super(scope, id); - this.options = options; - } + constructor( + scope: Construct, + id: TName & Lowercase, + options: HeaderOptions, + ) { + super(scope, id); + this.options = options; + } - public referenceObject(): oas31.ReferenceObject { - return { - $ref: this.jsonPointer(), - }; - } + public referenceObject(): oas31.ReferenceObject { + return { + $ref: this.jsonPointer(), + }; + } - public get schemaKey() { - return this.node.id; - } + public get schemaKey() { + return this.node.id; + } - public jsonPointer(): string { - return `#/components/headers/${this.schemaKey}`; - } + public jsonPointer(): string { + return `#/components/headers/${this.schemaKey}`; + } - public synth() { - return { - ...(this.options.description && { - description: this.options.description, - }), - ...(this.options.required && { - required: this.options.required, - }), - ...(this.options.deprecated && { - deprecated: this.options.deprecated, - }), - ...(this.options.allowEmptyValue && { - allowEmptyValue: this.options.allowEmptyValue, - }), - ...(this.options.style && { - style: this.options.style, - }), - ...(this.options.explode && { - explode: this.options.explode, - }), - ...(this.options.allowReserved && { - allowReserved: this.options.allowReserved, - }), - ...(this.options.schema && { - schema: this.options.schema.referenceObject(), - }), - } satisfies oas31.HeaderObject; - } + public synth() { + return { + ...(this.options.description && { + description: this.options.description, + }), + ...(this.options.required && { + required: this.options.required, + }), + ...(this.options.deprecated && { + deprecated: this.options.deprecated, + }), + ...(this.options.allowEmptyValue && { + allowEmptyValue: this.options.allowEmptyValue, + }), + ...(this.options.style && { + style: this.options.style, + }), + ...(this.options.explode && { + explode: this.options.explode, + }), + ...(this.options.allowReserved && { + allowReserved: this.options.allowReserved, + }), + ...(this.options.schema && { + schema: this.options.schema.referenceObject(), + }), + } satisfies oas31.HeaderObject; + } } diff --git a/lib/http-method.ts b/lib/http-method.ts index c8664c2..377e928 100644 --- a/lib/http-method.ts +++ b/lib/http-method.ts @@ -1 +1,9 @@ -export type HttpMethod = "get" | "put" | "post" | "delete" | "options" | "head" | "patch" | "trace"; \ No newline at end of file +export type HttpMethod = + | "get" + | "put" + | "post" + | "delete" + | "options" + | "head" + | "patch" + | "trace"; diff --git a/lib/index.ts b/lib/index.ts index a2e1133..386aa28 100644 --- a/lib/index.ts +++ b/lib/index.ts @@ -1,21 +1,20 @@ -/* eslint-disable max-classes-per-file */ -import { Construct } from 'constructs'; - -// export the version of Constructs we are using to ensure we're -// everyone is using the same version -export { Construct }; - -export { Api } from './api.ts'; -export { Header } from './header.ts'; -export { Parameter } from './parameter.ts'; -export { Path } from './path.ts'; -export { Reference } from './reference.ts'; -export { Response } from './response.ts'; -export { Schema, type SchemaOptions } from './schema.ts'; -export { SecurityRequirement } from './security-requirement.ts'; -export { SecurityScheme } from './security-scheme.ts'; -export { Server } from './server.ts'; -export { Tag } from './tag.ts'; +import { Construct } from "constructs"; + +// consumers build on this copy of constructs, so their constructs and ours +// share one class +export { Construct } from "constructs"; + +export { Api } from "./api.ts"; +export { Header } from "./header.ts"; +export { Parameter } from "./parameter.ts"; +export { Path } from "./path.ts"; +export { Reference } from "./reference.ts"; +export { Response } from "./response.ts"; +export { Schema, type SchemaOptions } from "./schema.ts"; +export { SecurityRequirement } from "./security-requirement.ts"; +export { SecurityScheme } from "./security-scheme.ts"; +export { Server } from "./server.ts"; +export { Tag } from "./tag.ts"; export class ServerVariable extends Construct {} diff --git a/lib/media-type.ts b/lib/media-type.ts index 063f0fc..ed21847 100644 --- a/lib/media-type.ts +++ b/lib/media-type.ts @@ -1,40 +1,40 @@ -import { Construct } from 'constructs'; -import type { oas31 } from 'openapi3-ts'; -import { Reference } from './reference.ts'; -import type { Schema } from './schema.ts'; +import { Construct } from "constructs"; +import type { oas31 } from "openapi3-ts"; +import { Reference } from "./reference.ts"; +import type { Schema } from "./schema.ts"; type ContentType = - | 'application/json' - | 'application/octet-stream' - | 'application/x-www-form-urlencoded' - | 'multipart/form-data' - | 'text/plain' - | 'image/*' - | (string & {}); + | "application/json" + | "application/octet-stream" + | "application/x-www-form-urlencoded" + | "multipart/form-data" + | "text/plain" + | "image/*" + | (string & {}); -export interface MediaTypeOptions { - contentType: ContentType; - schema: Schema | Reference; -} +export type MediaTypeOptions = { + contentType: ContentType; + schema: Schema | Reference; +}; export class MediaType extends Construct { - private options: MediaTypeOptions; + private options: MediaTypeOptions; - public get contentType() { - return this.options.contentType; - } + public get contentType() { + return this.options.contentType; + } - constructor(scope: Construct, id: string, options: MediaTypeOptions) { - super(scope, id); - this.options = options; - } + constructor(scope: Construct, id: string, options: MediaTypeOptions) { + super(scope, id); + this.options = options; + } - public synth(): oas31.MediaTypeObject { - return { - schema: - this.options.schema instanceof Reference - ? this.options.schema.synth() - : this.options.schema.referenceObject(), - }; - } + public synth(): oas31.MediaTypeObject { + return { + schema: + this.options.schema instanceof Reference + ? this.options.schema.synth() + : this.options.schema.referenceObject(), + }; + } } diff --git a/lib/operation.ts b/lib/operation.ts index 596be4d..c1b1c23 100644 --- a/lib/operation.ts +++ b/lib/operation.ts @@ -1,105 +1,104 @@ -import { Construct } from 'constructs'; -import type { oas31 } from 'openapi3-ts'; -import { RequestBody, type RequestBodyOptions } from './request-body.ts'; -import type { Response } from './response.ts'; -import type { SecurityRequirement } from './security-requirement.ts'; -import type { Tag } from './tag.ts'; -import type { ValidParameter } from './types.ts'; -import { stripUndefined } from './utils.ts'; -import type { HttpMethod } from './http-method.ts'; +import { Construct } from "constructs"; +import type { oas31 } from "openapi3-ts"; +import type { HttpMethod } from "./http-method.ts"; +import { RequestBody, type RequestBodyOptions } from "./request-body.ts"; +import type { Response } from "./response.ts"; +import type { SecurityRequirement } from "./security-requirement.ts"; +import type { Tag } from "./tag.ts"; +import type { ValidParameter } from "./types.ts"; -export interface OperationOptions { - operationId: string; - summary?: string; - description?: string; - tags?: Set; - deprecated?: boolean; - parameters?: ValidParameter[]; - security?: SecurityRequirement; - responses?: { - [statusCode: string | number]: Response; - }; - requestBody?: RequestBody | RequestBodyOptions; - order?: number; -} - -export class Operation extends Construct { - private readonly options: OperationOptions; +export type OperationOptions = { + operationId: string; + summary?: string; + description?: string; + tags?: Set; + deprecated?: boolean; + parameters?: ValidParameter[]; + security?: SecurityRequirement; + responses?: { + [statusCode: string | number]: Response; + }; + requestBody?: RequestBody | RequestBodyOptions; + order?: number; +}; - public readonly method: HttpMethod; +export class Operation extends Construct { + private readonly options: OperationOptions; - public readonly order: number; + public readonly method: HttpMethod; - private requestBody?: RequestBody; + public readonly order: number; - public hasOperationId(operationId: OperationOptions['operationId']): boolean { - return this.options.operationId === operationId; - } + private requestBody?: RequestBody; - constructor( - scope: Construct, - method: HttpMethod, - options: OperationOptions, - ) { - super(scope, method); - this.method = method; - this.options = options; + public hasOperationId(operationId: OperationOptions["operationId"]): boolean { + return this.options.operationId === operationId; + } - this.order = options.order || 0; + constructor( + scope: Construct, + method: HttpMethod, + options: OperationOptions, + ) { + super(scope, method); + this.method = method; + this.options = options; - if (options.requestBody) { - this.requestBody = - options.requestBody instanceof RequestBody - ? options.requestBody - : new RequestBody(this, method, options.requestBody); - } - } + this.order = options.order || 0; - public validate() { - // const api = Api.of(this).node.findChild; + if (options.requestBody) { + this.requestBody = + options.requestBody instanceof RequestBody + ? options.requestBody + : new RequestBody(this, method, options.requestBody); + } + } - const duplicateOperation = this.node.scope?.node.children - .filter( - (child): child is Operation => - child instanceof Operation && child !== this, - ) - .find((child) => child.hasOperationId(this.options.operationId)); + public validate() { + const duplicateOperation = this.node.scope?.node.children + .filter( + (child): child is Operation => + child instanceof Operation && child !== this, + ) + .find((child) => child.hasOperationId(this.options.operationId)); - if (duplicateOperation) { - return [`Duplicate operationId ${this.options.operationId}`]; - } + if (duplicateOperation) { + return [`Duplicate operationId ${this.options.operationId}`]; + } - return []; - } + return []; + } - public synth() { - return stripUndefined({ - operationId: this.options.operationId, - description: this.options.description || undefined, - summary: this.options.summary || undefined, - tags: - this.options.tags && [...this.options.tags].map((child) => child.name), - deprecated: this.options.deprecated, - ...(this.options.parameters && { - parameters: this.options.parameters.map((child) => child.synth()), - }), - ...(this.options.security && { - security: [this.options.security.synth()], - }), - ...(this.options.tags && { - tags: Array.from(this.options.tags).map((child) => child.name), - }), - ...(this.requestBody && { - requestBody: this.requestBody.synth(), - }), - ...(this.options.responses && { - responses: Object.fromEntries( - Object.entries(this.options.responses).map(([statusCode, child]) => [ - statusCode.toString(), - child.synth(), - ]), - ), - }), - }) satisfies oas31.OperationObject; - } + public synth() { + return { + operationId: this.options.operationId, + ...(this.options.description && { + description: this.options.description, + }), + ...(this.options.summary && { summary: this.options.summary }), + ...(this.options.tags && { + tags: [...this.options.tags].map((child) => child.name), + }), + ...(this.options.deprecated !== undefined && { + deprecated: this.options.deprecated, + }), + ...(this.options.parameters && { + parameters: this.options.parameters.map((child) => child.synth()), + }), + ...(this.options.security && { + security: [this.options.security.synth()], + }), + ...(this.requestBody && { + requestBody: this.requestBody.synth(), + }), + ...(this.options.responses && { + responses: Object.fromEntries( + Object.entries(this.options.responses).map(([statusCode, child]) => [ + statusCode, + child.synth(), + ]), + ), + }), + } satisfies oas31.OperationObject; + } } diff --git a/lib/parameter.ts b/lib/parameter.ts index 6387c4f..5ead005 100644 --- a/lib/parameter.ts +++ b/lib/parameter.ts @@ -1,90 +1,92 @@ -import { Construct } from 'constructs'; -import type { oas31 } from 'openapi3-ts'; -import type { Api } from './api.ts'; -import type { Schema } from './schema.ts'; +import { Construct } from "constructs"; +import type { oas31 } from "openapi3-ts"; +import type { Api } from "./api.ts"; +import type { Schema } from "./schema.ts"; -type StyleForIn = - TIn extends 'path' - ? 'matrix' | 'label' | 'simple' - : TIn extends 'query' - ? 'form' | 'spaceDelimited' | 'pipeDelimited' | 'deepObject' - : TIn extends 'header' - ? 'simple' - : TIn extends 'cookie' - ? 'form' - : never; +type StyleForIn = + TIn extends "path" + ? "matrix" | "label" | "simple" + : TIn extends "query" + ? "form" | "spaceDelimited" | "pipeDelimited" | "deepObject" + : TIn extends "header" + ? "simple" + : TIn extends "cookie" + ? "form" + : never; type ParameterName< - TName extends string | number | symbol, - TIn extends 'query' | 'header' | 'path' | 'cookie', -> = TIn extends 'header' ? TName & Lowercase : TName; + TName extends string | number | symbol, + TIn extends "query" | "header" | "path" | "cookie", +> = TIn extends "header" ? TName & Lowercase : TName; -interface ParameterOptionsBase< - TName extends string | number | symbol, - TIn extends 'query' | 'header' | 'path' | 'cookie', -> { - name: ParameterName; - in: TIn; - required: boolean; - description?: string; - deprecated?: boolean; - allowEmptyValue?: boolean; - allowReserved?: boolean; - style?: StyleForIn; - explode?: boolean; -} +type ParameterOptionsBase< + TName extends string | number | symbol, + TIn extends "query" | "header" | "path" | "cookie", +> = { + name: ParameterName; + in: TIn; + required: boolean; + description?: string; + deprecated?: boolean; + allowEmptyValue?: boolean; + allowReserved?: boolean; + style?: StyleForIn; + explode?: boolean; +}; interface ParameterOptions< - TName extends string | number | symbol, - TIn extends 'query' | 'header' | 'path' | 'cookie', + TName extends string | number | symbol, + TIn extends "query" | "header" | "path" | "cookie", > extends ParameterOptionsBase { - schema: Schema; + schema: Schema; } export class Parameter< - TName extends string | number | symbol = '', - TIn extends 'query' | 'header' | 'path' | 'cookie' = 'query', + TName extends string | number | symbol = "", + TIn extends "query" | "header" | "path" | "cookie" = "query", > extends Construct { - private options: ParameterOptions; + private options: ParameterOptions; - constructor(scope: Api, id: string, options: ParameterOptions) { - super(scope, id); - this.options = options; - } + constructor(scope: Api, id: string, options: ParameterOptions) { + super(scope, id); + this.options = options; + } - public referenceObject(): oas31.ReferenceObject { - return { - $ref: this.jsonPointer(), - }; - } + public referenceObject(): oas31.ReferenceObject { + return { + $ref: this.jsonPointer(), + }; + } - public get schemaKey() { - return this.node.id; - } + public get schemaKey() { + return this.node.id; + } - public jsonPointer(): string { - return `#/components/parameters/${this.schemaKey}`; - } + public jsonPointer(): string { + return `#/components/parameters/${this.schemaKey}`; + } - public synth() { - return { - name: this.options.name.toString(), - in: this.options.in, - ...(this.options.description && { - description: this.options.description, - }), - ...(this.options.allowReserved && { - allowReserved: this.options.allowReserved, - }), - required: this.options.required, - ...(this.options.allowEmptyValue && { - allowEmptyValue: this.options.allowEmptyValue, - }), - ...(this.options.style && { style: this.options.style }), - ...(this.options.explode != null && { explode: this.options.explode }), - ...(this.options.schema && { - schema: this.options.schema.referenceObject(), - }), - } satisfies oas31.ParameterObject | oas31.ReferenceObject; - } + public synth() { + return { + name: this.options.name.toString(), + in: this.options.in, + ...(this.options.description && { + description: this.options.description, + }), + ...(this.options.allowReserved && { + allowReserved: this.options.allowReserved, + }), + required: this.options.required, + ...(this.options.allowEmptyValue && { + allowEmptyValue: this.options.allowEmptyValue, + }), + ...(this.options.style && { style: this.options.style }), + ...(this.options.explode !== undefined && { + explode: this.options.explode, + }), + ...(this.options.schema && { + schema: this.options.schema.referenceObject(), + }), + } satisfies oas31.ParameterObject | oas31.ReferenceObject; + } } diff --git a/lib/path.ts b/lib/path.ts index c465ea0..7bbd331 100644 --- a/lib/path.ts +++ b/lib/path.ts @@ -1,67 +1,64 @@ -import { Construct } from 'constructs'; -import type { oas31 } from 'openapi3-ts'; -import type { Api } from './api.ts'; -import type { HttpMethod } from './http-method.ts'; -import { Operation, type OperationOptions } from './operation.ts'; -import type { Server } from './server.ts'; -import type { Tag } from './tag.ts'; -import type { ValidParameter } from './types.ts'; +import { Construct } from "constructs"; +import type { oas31 } from "openapi3-ts"; +import type { Api } from "./api.ts"; +import type { HttpMethod } from "./http-method.ts"; +import { Operation, type OperationOptions } from "./operation.ts"; +import type { Server } from "./server.ts"; +import type { Tag } from "./tag.ts"; +import type { ValidParameter } from "./types.ts"; -interface PathOptions { - path: TPath; - summary?: string; - servers?: Server[]; - parameters?: ValidParameter[]; - tags?: Set; -} - -export class Path extends Construct { - public options: PathOptions; +type PathOptions = { + path: TPath; + summary?: string; + servers?: Server[]; + parameters?: ValidParameter[]; + tags?: Set; +}; - constructor(scope: Api, options: PathOptions) { - super(scope, options.path); - this.options = options; - } +export class Path extends Construct { + public options: PathOptions; - public addOperation( - method: HttpMethod, - options: OperationOptions, - ): this { - // make sure we are not duplicating tags - // options.tags?.forEach((tag) => strict(!this.options.tags?.has(tag))); + constructor(scope: Api, options: PathOptions) { + super(scope, options.path); + this.options = options; + } - // eslint-disable-next-line no-new - new Operation(this, method, { - ...options, - tags: new Set([...(this.options.tags || []), ...(options.tags || [])]), - }); - return this; - } + public addOperation( + method: HttpMethod, + options: OperationOptions, + ): this { + // oxlint-disable-next-line no-new -- it attaches itself to this path + new Operation(this, method, { + ...options, + tags: new Set([...(this.options.tags || []), ...(options.tags || [])]), + }); + return this; + } - public get schemaKey() { - return this.options.path; - } + public get schemaKey() { + return this.options.path; + } - public synth() { - return { - ...Object.fromEntries( - this.node - .findAll() - .filter( - (child): child is Operation => child instanceof Operation, - ) - .sort((a, b) => a.order - b.order) - .map((child) => [child.method, child.synth()]), - ), - ...(this.options.servers && { - servers: this.options.servers.map((child) => child.synth()), - }), - ...(this.options.parameters && { - parameters: this.options.parameters.map((child) => - child.referenceObject(), - ), - }), - ...(this.options.summary && { summary: this.options.summary }), - } satisfies oas31.PathItemObject; - } + public synth() { + return { + ...Object.fromEntries( + this.node + .findAll() + .filter( + (child): child is Operation => child instanceof Operation, + ) + .toSorted((a, b) => a.order - b.order) + .map((child) => [child.method, child.synth()]), + ), + ...(this.options.servers && { + servers: this.options.servers.map((child) => child.synth()), + }), + ...(this.options.parameters && { + parameters: this.options.parameters.map((child) => + child.referenceObject(), + ), + }), + ...(this.options.summary && { summary: this.options.summary }), + } satisfies oas31.PathItemObject; + } } diff --git a/lib/reference.ts b/lib/reference.ts index dfe3e35..48c895a 100644 --- a/lib/reference.ts +++ b/lib/reference.ts @@ -1,28 +1,29 @@ -import { Construct } from 'constructs'; -import type { oas31 } from 'openapi3-ts'; -import { ApiLowLevel } from './ApiLowLevel.ts'; -import { Schema } from './schema.ts'; +import { Construct } from "constructs"; +import type { oas31 } from "openapi3-ts"; +import { ApiLowLevel } from "./api-low-level.ts"; +import { Schema } from "./schema.ts"; -type Target = Schema; // | Parameter; +type Target = Schema; export class Reference extends Construct { - private schema: Schema; + private schema: Schema; - constructor(target: T, id: string) { - super(target, id); - // NOTE: Api.of causes a circular dependency - this.schema = new Schema(ApiLowLevel.of(this), id, { - // NOTE: synth because refs are not valid as #/component/schemas - // if it did, we could use referenceObject here instead - schema: target.synth(), - }); - } + constructor(target: T, id: string) { + super(target, id); - public get schemaKey() { - return this.schema.schemaKey; - } + // NOTE: Api.of causes a circular dependency + this.schema = new Schema(ApiLowLevel.of(this), id, { + // NOTE: synth because refs are not valid as #/component/schemas + // if it did, we could use referenceObject here instead + schema: target.synth(), + }); + } - public synth(): oas31.ReferenceObject { - return this.schema.referenceObject(); - } + public get schemaKey() { + return this.schema.schemaKey; + } + + public synth(): oas31.ReferenceObject { + return this.schema.referenceObject(); + } } diff --git a/lib/request-body.ts b/lib/request-body.ts index fdcfd5a..f15f833 100644 --- a/lib/request-body.ts +++ b/lib/request-body.ts @@ -1,46 +1,43 @@ -import { Construct } from 'constructs'; -import type { oas31 } from 'openapi3-ts'; -import { MediaType, type MediaTypeOptions } from './media-type.ts'; +import { Construct } from "constructs"; +import type { oas31 } from "openapi3-ts"; +import { MediaType, type MediaTypeOptions } from "./media-type.ts"; -export interface RequestBodyOptions { - content: MediaType | MediaTypeOptions | (MediaType | MediaTypeOptions)[]; - description?: string; - required?: boolean; -} +export type RequestBodyOptions = { + content: MediaType | MediaTypeOptions | (MediaType | MediaTypeOptions)[]; + description?: string; + required?: boolean; +}; export class RequestBody extends Construct { - private options: RequestBodyOptions; + private options: RequestBodyOptions; - private contentEntries: MediaType[]; + private contentEntries: MediaType[]; - constructor(scope: Construct, id: string, options: RequestBodyOptions) { - super(scope, id); - this.options = { - required: true, - ...options, - }; + constructor(scope: Construct, id: string, options: RequestBodyOptions) { + super(scope, id); + this.options = { + required: true, + ...options, + }; - const items = Array.isArray(options.content) - ? options.content - : [options.content]; + const items = Array.isArray(options.content) + ? options.content + : [options.content]; - this.contentEntries = items.map((item, index) => - item instanceof MediaType - ? item - : new MediaType(this, `${id}${index}`, item), - ); - } + this.contentEntries = items.map((item, index) => + item instanceof MediaType + ? item + : new MediaType(this, `${id}${index}`, item), + ); + } - public synth(): oas31.RequestBodyObject { - return { - description: this.options.description || '', - content: Object.fromEntries( - this.contentEntries.map((entry) => [ - entry.contentType, - entry.synth(), - ]), - ), - ...(this.options.required && { required: this.options.required }), - }; - } + public synth(): oas31.RequestBodyObject { + return { + description: this.options.description || "", + content: Object.fromEntries( + this.contentEntries.map((entry) => [entry.contentType, entry.synth()]), + ), + ...(this.options.required && { required: this.options.required }), + }; + } } diff --git a/lib/response.ts b/lib/response.ts index d604b19..0dd91b3 100644 --- a/lib/response.ts +++ b/lib/response.ts @@ -1,53 +1,47 @@ -import { Construct } from 'constructs'; -import type { oas31 } from 'openapi3-ts'; -import type { Header } from './header.ts'; -import { MediaType, type MediaTypeOptions } from './media-type.ts'; +import { Construct } from "constructs"; +import type { oas31 } from "openapi3-ts"; +import type { Header } from "./header.ts"; +import { MediaType, type MediaTypeOptions } from "./media-type.ts"; -interface ResponseOptions { - content?: MediaType | MediaTypeOptions | (MediaType | MediaTypeOptions)[]; - description?: string; - headers?: Record, Header>; -} +type ResponseOptions = { + content?: MediaType | MediaTypeOptions | (MediaType | MediaTypeOptions)[]; + description?: string; + headers?: Record, Header>; +}; export class Response extends Construct { - private options: ResponseOptions; + private options: ResponseOptions; - private contentEntries: MediaType[]; + private contentEntries: MediaType[]; - constructor(scope: Construct, id: string, options: ResponseOptions = {}) { - super(scope, id); - this.options = options; + constructor(scope: Construct, id: string, options: ResponseOptions = {}) { + super(scope, id); + this.options = options; - const items = options.content - ? Array.isArray(options.content) - ? options.content - : [options.content] - : []; + const { content = [] } = options; + const items = Array.isArray(content) ? content : [content]; - this.contentEntries = items.map((item, index) => - item instanceof MediaType - ? item - : new MediaType(this, `${id}MediaType${index}`, item), - ); - } + this.contentEntries = items.map((item, index) => + item instanceof MediaType + ? item + : new MediaType(this, `${id}MediaType${index}`, item), + ); + } - public synth() { - return { - description: this.options.description || 'Successful response', - content: Object.fromEntries( - this.contentEntries.map((entry) => [ - entry.contentType, - entry.synth(), - ]), - ), - ...(this.options.headers && { - headers: Object.fromEntries( - Object.entries(this.options.headers).map(([name, header]) => [ - name, - header.synth(), - ]), - ), - }), - } satisfies oas31.ResponseObject; - } + public synth() { + return { + description: this.options.description || "Successful response", + content: Object.fromEntries( + this.contentEntries.map((entry) => [entry.contentType, entry.synth()]), + ), + ...(this.options.headers && { + headers: Object.fromEntries( + Object.entries(this.options.headers).map(([name, header]) => [ + name, + header.synth(), + ]), + ), + }), + } satisfies oas31.ResponseObject; + } } diff --git a/lib/schema.ts b/lib/schema.ts index c124f72..7ad81ef 100644 --- a/lib/schema.ts +++ b/lib/schema.ts @@ -1,76 +1,83 @@ -import { Construct } from 'constructs'; -import type { oas31 } from 'openapi3-ts'; +import { Construct } from "constructs"; +import type { oas31 } from "openapi3-ts"; -type InferExample = TSchema extends oas31.ReferenceObject - ? any - : TSchema extends { - type: 'string'; - } - ? string - : TSchema extends { - type: 'number' | 'integer'; - } - ? number - : TSchema extends { - type: 'boolean'; - } - ? boolean - : TSchema extends oas31.SchemaObject & { type: 'object' } - ? { - [K in keyof TSchema['properties']]: TStopRecurse extends true ? unknown : InferExample; - } - : TSchema extends oas31.SchemaObject & { type: 'array' } - ? TStopRecurse extends true ? unknown : InferExample[] - : any; +type InferExample< + TSchema, + TStopRecurse extends boolean = false, +> = TSchema extends oas31.ReferenceObject + ? unknown + : TSchema extends { + type: "string"; + } + ? string + : TSchema extends { + type: "number" | "integer"; + } + ? number + : TSchema extends { + type: "boolean"; + } + ? boolean + : TSchema extends oas31.SchemaObject & { type: "object" } + ? { + [K in keyof TSchema["properties"]]: TStopRecurse extends true + ? unknown + : InferExample; + } + : TSchema extends oas31.SchemaObject & { type: "array" } + ? TStopRecurse extends true + ? unknown + : InferExample[] + : unknown; - -export type SchemaOptions> = { - schema: T & { - examples?: InferExample[]; - required?: T extends { type: 'object', properties: infer P } ? (keyof P)[] : string[]; - }; +export type SchemaOptions> = { + schema: T & { + examples?: InferExample[]; + required?: T extends { type: "object"; properties: infer P } + ? (keyof P)[] + : string[]; + }; }; export class Schema< - const T extends oas31.SchemaObject = oas31.SchemaObject, + const T extends oas31.SchemaObject = oas31.SchemaObject, > extends Construct { - private options: SchemaOptions; + private options: SchemaOptions; - constructor(scope: Construct, id: string, options: SchemaOptions) { - super(scope, id); + constructor(scope: Construct, id: string, options: SchemaOptions) { + super(scope, id); - this.options = options; - } + this.options = options; + } - public get schema() { - return this.options.schema; - } + public get schema() { + return this.options.schema; + } - public get schemaKey() { - return this.node.id; - } + public get schemaKey() { + return this.node.id; + } - public jsonPointer() { - return `#/components/schemas/${this.schemaKey}`; - } + public jsonPointer() { + return `#/components/schemas/${this.schemaKey}`; + } - public referenceObject(): oas31.ReferenceObject { - return { - $ref: this.jsonPointer(), - }; - } + public referenceObject(): oas31.ReferenceObject { + return { + $ref: this.jsonPointer(), + }; + } - // eslint-disable-next-line class-methods-use-this - public validate() { - return []; - } + public validate() { + return []; + } - public synth() { - return { - // default to disallow additional properties on objects - ...(this.options.schema.type === 'object' && { - additionalProperties: false, - }), - ...this.options.schema, - }; - } + public synth() { + return { + // default to disallow additional properties on objects + ...(this.options.schema.type === "object" && { + additionalProperties: false, + }), + ...this.options.schema, + }; + } } diff --git a/lib/security-requirement.ts b/lib/security-requirement.ts index 72a3c92..d7fb22f 100644 --- a/lib/security-requirement.ts +++ b/lib/security-requirement.ts @@ -1,30 +1,30 @@ -import { Construct } from 'constructs'; -import type { oas31 } from 'openapi3-ts'; -import type { Api } from './api.ts'; -import type { SecurityScheme } from './security-scheme.ts'; +import { Construct } from "constructs"; +import type { oas31 } from "openapi3-ts"; +import type { Api } from "./api.ts"; +import type { SecurityScheme } from "./security-scheme.ts"; -interface SecurityRequirementOptions { - securityScheme?: SecurityScheme; - scopes?: string[]; -} +type SecurityRequirementOptions = { + securityScheme?: SecurityScheme; + scopes?: string[]; +}; export class SecurityRequirement extends Construct { - private options: SecurityRequirementOptions; + private options: SecurityRequirementOptions; - constructor( - scope: Api, - id: string, - options: SecurityRequirementOptions = {}, - ) { - super(scope, id); - this.options = options; - } + constructor( + scope: Api, + id: string, + options: SecurityRequirementOptions = {}, + ) { + super(scope, id); + this.options = options; + } - public synth(): oas31.SecurityRequirementObject { - return this.options.securityScheme - ? { - [this.options.securityScheme.node.id]: this.options.scopes || [], - } - : {}; - } + public synth(): oas31.SecurityRequirementObject { + return this.options.securityScheme + ? { + [this.options.securityScheme.node.id]: this.options.scopes || [], + } + : {}; + } } diff --git a/lib/security-scheme.ts b/lib/security-scheme.ts index fd56904..eb3b793 100644 --- a/lib/security-scheme.ts +++ b/lib/security-scheme.ts @@ -1,23 +1,23 @@ -import { Construct } from 'constructs'; -import type { oas31 } from 'openapi3-ts'; +import { Construct } from "constructs"; +import type { oas31 } from "openapi3-ts"; export class SecurityScheme extends Construct { - private options: oas31.SecuritySchemeObject; + private options: oas31.SecuritySchemeObject; - constructor( - scope: Construct, - id: string, - options: oas31.SecuritySchemeObject, - ) { - super(scope, id); - this.options = options; - } + constructor( + scope: Construct, + id: string, + options: oas31.SecuritySchemeObject, + ) { + super(scope, id); + this.options = options; + } - public get schemaKey() { - return this.node.id; - } + public get schemaKey() { + return this.node.id; + } - public synth(): oas31.SecuritySchemeObject { - return this.options; - } + public synth(): oas31.SecuritySchemeObject { + return this.options; + } } diff --git a/lib/server.ts b/lib/server.ts index 99bf162..2154baa 100644 --- a/lib/server.ts +++ b/lib/server.ts @@ -1,26 +1,26 @@ -import { Construct } from 'constructs'; -import type { oas31 } from 'openapi3-ts'; -import type { Api } from './api.ts'; +import { Construct } from "constructs"; +import type { oas31 } from "openapi3-ts"; +import type { Api } from "./api.ts"; -interface ServerOptions { - url: URL; - description?: string; -} +type ServerOptions = { + url: URL; + description?: string; +}; export class Server extends Construct { - private options: ServerOptions; + private options: ServerOptions; - constructor(scope: Api, id: string, options: ServerOptions) { - super(scope, id); - this.options = options; - } + constructor(scope: Api, id: string, options: ServerOptions) { + super(scope, id); + this.options = options; + } - public synth(): oas31.ServerObject { - return { - url: this.options.url.toString(), - ...(this.options.description && { - description: this.options.description, - }), - }; - } + public synth(): oas31.ServerObject { + return { + url: this.options.url.toString(), + ...(this.options.description && { + description: this.options.description, + }), + }; + } } diff --git a/lib/tag.ts b/lib/tag.ts index 631bdd6..0574475 100644 --- a/lib/tag.ts +++ b/lib/tag.ts @@ -1,21 +1,21 @@ -import { Construct } from 'constructs'; -import type { oas31 } from 'openapi3-ts'; +import { Construct } from "constructs"; +import type { oas31 } from "openapi3-ts"; export class Tag< - T extends oas31.TagObject = oas31.TagObject, + T extends oas31.TagObject = oas31.TagObject, > extends Construct { - private options: T; + private options: T; - public get name() { - return this.options.name; - } + public get name() { + return this.options.name; + } - constructor(scope: Construct, id: string, options: T) { - super(scope, id); - this.options = options; - } + constructor(scope: Construct, id: string, options: T) { + super(scope, id); + this.options = options; + } - public synth() { - return this.options; - } + public synth() { + return this.options; + } } diff --git a/lib/types.ts b/lib/types.ts index 79c55ea..9697183 100644 --- a/lib/types.ts +++ b/lib/types.ts @@ -1,16 +1,15 @@ -import type { Parameter } from './parameter.ts'; +import type { Parameter } from "./parameter.ts"; -/* eslint-disable @typescript-eslint/no-unused-vars */ export type ExtractRouteParams = string extends T - ? Record - : T extends `${infer _Start}{${infer Param}}/${infer Rest}` - ? { [k in Param | keyof ExtractRouteParams]: string } - : T extends `${infer _Start}{${infer Param}}` - ? { [k in Param]: string } - : Record; + ? Record + : T extends `${infer _Start}{${infer Param}}/${infer Rest}` + ? { [k in Param | keyof ExtractRouteParams]: string } + : T extends `${infer _Start}{${infer Param}}` + ? { [k in Param]: string } + : Record; export type ValidParameter = - | Parameter, 'path'> - | Parameter - | Parameter, 'header'> - | Parameter; + | Parameter, "path"> + | Parameter + | Parameter, "header"> + | Parameter; diff --git a/lib/utils.ts b/lib/utils.ts deleted file mode 100644 index b1efeb5..0000000 --- a/lib/utils.ts +++ /dev/null @@ -1,14 +0,0 @@ -export type WithoutUndefinedProperties = { - [P in keyof T]: Exclude; -}; - -export type OptionalToUndefined = { - [P in keyof T]: undefined extends T[P] ? T[P] | undefined : T[P]; -}; - -// this is a better version that uses Object.fromEntries -export function stripUndefined(obj: OptionalToUndefined) { - return Object.fromEntries( - Object.entries(obj).filter(([, v]) => typeof v !== 'undefined'), - ) as WithoutUndefinedProperties; -} diff --git a/oxfmt.config.ts b/oxfmt.config.ts new file mode 100644 index 0000000..e8f3d52 --- /dev/null +++ b/oxfmt.config.ts @@ -0,0 +1,3 @@ +import { defineConfig } from "@block65/shared-config/oxfmt"; + +export default defineConfig(); diff --git a/oxlint.config.ts b/oxlint.config.ts new file mode 100644 index 0000000..6c0d0dd --- /dev/null +++ b/oxlint.config.ts @@ -0,0 +1,5 @@ +import { defineConfig } from "@block65/shared-config/oxlint"; + +export default defineConfig({ + groups: { vitest: "on" }, +}); diff --git a/package.json b/package.json index 830ec31..5ecb773 100644 --- a/package.json +++ b/package.json @@ -1,45 +1,45 @@ { - "name": "@block65/openapi-constructs", - "version": "6.0.0", - "private": false, - "license": "UNLICENSED", - "repository": { - "type": "git", - "url": "https://github.com/block65/openapi-constructs" - }, - "sideEffects": false, - "type": "module", - "exports": { - ".": "./lib/index.ts" - }, - "files": [ - "lib" - ], - "scripts": { - "preversion": "make test" - }, - "dependencies": { - "yaml": "^2.8.2" - }, - "devDependencies": { - "@apidevtools/swagger-parser": "^12.1.0", - "@tsconfig/node24": "^24.0.4", - "@tsconfig/strictest": "^2.0.8", - "@types/json-schema": "^7.0.15", - "@types/node": "^24.0.0", - "ajv": "^8.17.1", - "constructs": "^10.4.5", - "json-schema-to-typescript": "^15.0.4", - "type-fest": "^5.0.0", - "typescript": "^5.8.0", - "vitest": "^3.0.0" - }, - "peerDependencies": { - "constructs": "^10.4.4", - "openapi3-ts": "^4.4.0" - }, - "engines": { - "node": ">=24.0.0" - }, - "packageManager": "pnpm@10.30.3" + "name": "@block65/openapi-constructs", + "version": "6.0.0", + "private": false, + "license": "UNLICENSED", + "repository": { + "type": "git", + "url": "https://github.com/block65/openapi-constructs" + }, + "files": [ + "lib" + ], + "type": "module", + "sideEffects": false, + "exports": { + ".": "./lib/index.ts" + }, + "scripts": { + "preversion": "just check" + }, + "devDependencies": { + "@block65/shared-config": "^0.5.0", + "@block65/tsconfig": "^0.3.1", + "@hyperjump/json-schema": "^1.17.8", + "@types/json-schema": "^7.0.15", + "@types/node": "^26.6.2", + "constructs": "^10.8.1", + "fallow": "^3.28.0", + "openapi3-ts": "^4.6.1", + "oxfmt": "^0.70.0", + "oxlint": "^1.83.0", + "oxlint-tsgolint": "^7.0.2002", + "typescript": "^7.0.2", + "vite": "^8.3.0", + "vitest": "^5.0.1" + }, + "peerDependencies": { + "constructs": "^10.4.4", + "openapi3-ts": "^4.4.0" + }, + "engines": { + "node": ">=24.0.0" + }, + "packageManager": "pnpm@12.5.1" } diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 62bd59b..6279ed0 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -1,75 +1,293 @@ +--- +lockfileVersion: '9.0' + +importers: + + .: + configDependencies: {} + packageManagerDependencies: + pnpm: + specifier: 12.5.1 + version: 12.5.1 + +packages: + + '@pnpm/exe.android-arm64@12.5.1': + resolution: {integrity: sha512-6LGBmQuDzUmgpHSuy+haG0jrmkwFNa4EuShDZqK3cIBv4Wfb75CzjJmowkzr+iJg40vnBKMQ62t4Ko6mwsId7A==} + cpu: [arm64] + os: [android] + + '@pnpm/exe.android-x64@12.5.1': + resolution: {integrity: sha512-091oCltP3Rx89yxL1Wh5rXkUXEyFzyxIzSHKRFDyDFlQkb8Ox8FaDcm+M8PNkMyqnLA+qeGOLzY7Rjj9izl1Ww==} + cpu: [x64] + os: [android] + + '@pnpm/exe.darwin-arm64@12.5.1': + resolution: {integrity: sha512-r1vEMQPVjRexZMyL2HonxJoo3+nuB/+G+tg+f2PK6faRdXX1TDwevKXOxJAfqlPInTy6W/pm912+s+m0NcR4BQ==} + cpu: [arm64] + os: [darwin] + + '@pnpm/exe.darwin-x64@12.5.1': + resolution: {integrity: sha512-YHwI1g2B+Y2cAEylOR31r781GWijdJL7Gy7TEn/ZpZ5v/Cuwp5/Pz0EFCgo0M2MKLafAbL/laUMGvOpAdnerAw==} + cpu: [x64] + os: [darwin] + + '@pnpm/exe.freebsd-x64@12.5.1': + resolution: {integrity: sha512-sFUMHiYFs6q5syFwgaVppzhQSmqnXoJIz/YwTXIOXTDE76ndIpTRpDGAnBCBKjsaEBnqjJA/2l6hpJcNDNoMiA==} + cpu: [x64] + os: [freebsd] + + '@pnpm/exe.linux-arm64-musl@12.5.1': + resolution: {integrity: sha512-zupuxYZBuBEGjUz805/4/Asq01UNziFADANt8yp+LdUjU9bbMa3xY78Bx1PsGDqBy7aiad4sdUMK8ZxH4n4gmQ==} + cpu: [arm64] + os: [linux] + libc: [musl] + + '@pnpm/exe.linux-arm64@12.5.1': + resolution: {integrity: sha512-6hbMWW2/eQo1b5wvQPe/ndLHVTH88Rav6N+ffD4/h6IuFMjWCgasFYYsFv0GrvpqREAx3SwmZSvli+0NFXqbxA==} + cpu: [arm64] + os: [linux] + libc: [glibc] + + '@pnpm/exe.linux-ppc64@12.5.1': + resolution: {integrity: sha512-Gg3maDzaE/ZFMV9HIx/BwMN0Y6QbEs13URfxmiYHtKjjLAs5wEQZRMUP87YNLYO7cNaEfbM8GRbS9vPosyD9Gw==} + cpu: [ppc64] + os: [linux] + libc: [glibc] + + '@pnpm/exe.linux-riscv64@12.5.1': + resolution: {integrity: sha512-6fgWxXYMBMsWQ8DAiRevscX4QZQjwh+FsyCj8ZOk8pMXvqeq84MqBLCmS6KckvnbdqJ+HlSVQ7fs/kd0ldwfhA==} + cpu: [riscv64] + os: [linux] + libc: [glibc] + + '@pnpm/exe.linux-s390x@12.5.1': + resolution: {integrity: sha512-nzMZruRvxDhEfYUhzu+7EmM39+82Dgagc/6hPFPqGqzXNGcIG0anuxbUxfeNtI64SHt91KuuYUmCB/inlM+Pag==} + cpu: [s390x] + os: [linux] + libc: [glibc] + + '@pnpm/exe.linux-x64-musl@12.5.1': + resolution: {integrity: sha512-kHCbegdTNHpzmPtUD4S5fqkVkqgdQR47spF9p2VPP3dIIkZl6Ytk8w0vhlAsAGgge8FmucfwX+vvPKgm0NtOCQ==} + cpu: [x64] + os: [linux] + libc: [musl] + + '@pnpm/exe.linux-x64@12.5.1': + resolution: {integrity: sha512-3PkUBYo5z4dgtlnTNIFj7QGpcDUAuqXz9WGVigPDCeccEnhGiRkWmA5102TmYJHtwJP3LfmE+ZF9PGeWhn8p9Q==} + cpu: [x64] + os: [linux] + libc: [glibc] + + '@pnpm/exe.win32-arm64@12.5.1': + resolution: {integrity: sha512-49NvjZIXHly56/PLoEDD7VphbO4N8dwMXoApElDFCpVGDNGeKlwlib1tXtnpTF6i2/XIsAj7GgatHB5KHXgBnA==} + cpu: [arm64] + os: [win32] + + '@pnpm/exe.win32-x64@12.5.1': + resolution: {integrity: sha512-ePUmQFPAPJFNMwg1lelDx2PdjHqYRiF0yfg5e6qeDbPNOu97QNo557Ru/SxmCrmt8ydQWNuZXWpdEp019md5vw==} + cpu: [x64] + os: [win32] + + pnpm@12.5.1: + resolution: {integrity: sha512-4/MFvHhKK8ifWtO2E4iJRw+ujSr182thIW7JHCw9ZAiXdfneOKrDMQROpA8kXLDVZmOS399lgk4ZB+9qLGLeXw==} + engines: {node: '>=18.*'} + hasBin: true + +snapshots: + + '@pnpm/exe.android-arm64@12.5.1': + optional: true + + '@pnpm/exe.android-x64@12.5.1': + optional: true + + '@pnpm/exe.darwin-arm64@12.5.1': + optional: true + + '@pnpm/exe.darwin-x64@12.5.1': + optional: true + + '@pnpm/exe.freebsd-x64@12.5.1': + optional: true + + '@pnpm/exe.linux-arm64-musl@12.5.1': + optional: true + + '@pnpm/exe.linux-arm64@12.5.1': + optional: true + + '@pnpm/exe.linux-ppc64@12.5.1': + optional: true + + '@pnpm/exe.linux-riscv64@12.5.1': + optional: true + + '@pnpm/exe.linux-s390x@12.5.1': + optional: true + + '@pnpm/exe.linux-x64-musl@12.5.1': + optional: true + + '@pnpm/exe.linux-x64@12.5.1': + optional: true + + '@pnpm/exe.win32-arm64@12.5.1': + optional: true + + '@pnpm/exe.win32-x64@12.5.1': + optional: true + + pnpm@12.5.1: + optionalDependencies: + '@pnpm/exe.android-arm64': 12.5.1 + '@pnpm/exe.android-x64': 12.5.1 + '@pnpm/exe.darwin-arm64': 12.5.1 + '@pnpm/exe.darwin-x64': 12.5.1 + '@pnpm/exe.freebsd-x64': 12.5.1 + '@pnpm/exe.linux-arm64': 12.5.1 + '@pnpm/exe.linux-arm64-musl': 12.5.1 + '@pnpm/exe.linux-ppc64': 12.5.1 + '@pnpm/exe.linux-riscv64': 12.5.1 + '@pnpm/exe.linux-s390x': 12.5.1 + '@pnpm/exe.linux-x64': 12.5.1 + '@pnpm/exe.linux-x64-musl': 12.5.1 + '@pnpm/exe.win32-arm64': 12.5.1 + '@pnpm/exe.win32-x64': 12.5.1 + +--- lockfileVersion: '9.0' settings: autoInstallPeers: true excludeLinksFromLockfile: false +overrides: + oxlint: npm:@block65/oxlint@>=1.83.0 + oxlint-tsgolint: npm:@block65/oxlint-tsgolint@>=7.0.200200 + importers: .: - dependencies: - openapi3-ts: - specifier: ^4.4.0 - version: 4.5.0 - yaml: - specifier: ^2.8.2 - version: 2.8.2 devDependencies: - '@apidevtools/swagger-parser': - specifier: ^12.1.0 - version: 12.1.0(openapi-types@12.1.3) - '@tsconfig/node24': - specifier: ^24.0.4 - version: 24.0.4 - '@tsconfig/strictest': - specifier: ^2.0.8 - version: 2.0.8 + '@block65/shared-config': + specifier: ^0.5.0 + version: 0.5.0(@block65/oxlint-tsgolint@7.0.200200)(@block65/oxlint@1.83.0(@block65/oxlint-tsgolint@7.0.200200))(eslint@10.11.0)(fallow@3.28.0)(oxfmt@0.70.0) + '@block65/tsconfig': + specifier: ^0.3.1 + version: 0.3.1 + '@hyperjump/json-schema': + specifier: ^1.17.8 + version: 1.17.8(@hyperjump/browser@1.5.0) '@types/json-schema': specifier: ^7.0.15 version: 7.0.15 '@types/node': - specifier: ^24.0.0 - version: 24.12.0 - ajv: - specifier: ^8.17.1 - version: 8.18.0 + specifier: ^26.6.2 + version: 26.6.2 constructs: - specifier: ^10.4.5 - version: 10.5.1 - json-schema-to-typescript: - specifier: ^15.0.4 - version: 15.0.4 - type-fest: - specifier: ^5.0.0 - version: 5.4.4 + specifier: ^10.8.1 + version: 10.8.1 + fallow: + specifier: ^3.28.0 + version: 3.28.0 + openapi3-ts: + specifier: ^4.6.1 + version: 4.6.1 + oxfmt: + specifier: ^0.70.0 + version: 0.70.0 + oxlint: + specifier: npm:@block65/oxlint@>=1.83.0 + version: '@block65/oxlint@1.83.0(@block65/oxlint-tsgolint@7.0.200200)' + oxlint-tsgolint: + specifier: npm:@block65/oxlint-tsgolint@>=7.0.200200 + version: '@block65/oxlint-tsgolint@7.0.200200' typescript: - specifier: ^5.8.0 - version: 5.9.3 + specifier: ^7.0.2 + version: 7.0.2 + vite: + specifier: ^8.3.0 + version: 8.3.0(@types/node@26.6.2)(esbuild@0.27.3)(yaml@2.8.2) vitest: - specifier: ^3.0.0 - version: 3.2.4(@types/node@24.12.0)(yaml@2.8.2) + specifier: ^5.0.1 + version: 5.0.1(@types/node@26.6.2)(vite@8.3.0(@types/node@26.6.2)(esbuild@0.27.3)(yaml@2.8.2)) packages: - '@apidevtools/json-schema-ref-parser@11.9.3': - resolution: {integrity: sha512-60vepv88RwcJtSHrD6MjIL6Ta3SOYbgfnkHb+ppAVK+o9mXprRtulx7VlRl3lN3bbvysAfCS7WMVfhUYemB0IQ==} - engines: {node: '>= 16'} + '@block65/oxlint-binding-linux-arm64-gnu@1.83.0': + resolution: {integrity: sha512-iH3ufhqCxiemK1JIQj8Er/Z//L4fNawO9Mb8CzCou6p84l+HWAWkHVV2vWd+Wk8zaMm2m5vs2ONy0CBzrus3Qw==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [arm64] + os: [linux] + libc: [glibc] + + '@block65/oxlint-binding-linux-x64-gnu@1.83.0': + resolution: {integrity: sha512-zQ+L+Jpv2m/1DDqZr56WMirvz483ULuGROq1+ka4iqfG2vJh14KNxgWUXaahmnXGSvBnQCH1y0Q0kfMvtqqc8w==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [x64] + os: [linux] + libc: [glibc] - '@apidevtools/json-schema-ref-parser@14.0.1': - resolution: {integrity: sha512-Oc96zvmxx1fqoSEdUmfmvvb59/KDOnUoJ7s2t7bISyAn0XEz57LCCw8k2Y4Pf3mwKaZLMciESALORLgfe2frCw==} - engines: {node: '>= 16'} + '@block65/oxlint-plugin@0.11.0': + resolution: {integrity: sha512-68MuNjQkloeKt4B4rQdW5jYoWK/e+6WB11uOmPC66R/sZdMMgi7yqA+YCG8wJRJPy4/NSK7zAdt1JiRoOBp+kA==} + engines: {node: '>=24'} + peerDependencies: + oxlint: ^1.83.0 - '@apidevtools/openapi-schemas@2.1.0': - resolution: {integrity: sha512-Zc1AlqrJlX3SlpupFGpiLi2EbteyP7fXmUOGup6/DnkRgjP9bgMM/ag+n91rsv0U1Gpz0H3VILA/o3bW7Ua6BQ==} - engines: {node: '>=10'} + '@block65/oxlint-tsgolint-linux-arm64@7.0.200200': + resolution: {integrity: sha512-BRTbnw/wRUQePD6sKup3cyPoN5jc7GnAOyyJ6TE5lXp5B8cr1zbt3OVjoksoYnceqZpeO5g36PecgauSMNO+Pg==} + cpu: [arm64] + os: [linux] + + '@block65/oxlint-tsgolint-linux-x64@7.0.200200': + resolution: {integrity: sha512-Jj6CpfCqkioWv1kOtDBOFF1BS2OJ9KLWoowfOwPB635VnR1mLsi+utWh/6C0rkxxM6luunX5cB15g1rQ+OaGOA==} + cpu: [x64] + os: [linux] - '@apidevtools/swagger-methods@3.0.2': - resolution: {integrity: sha512-QAkD5kK2b1WfjDS/UQn/qQkbwF31uqRjPTrsCs5ZG9BQGAkjwvqGFjjPqAuzac/IYzpPtRzjCP1WrTuAIjMrXg==} + '@block65/oxlint-tsgolint@7.0.200200': + resolution: {integrity: sha512-UZ/b6cEl7ahIygTXKaQKcsb7Abt2a8GW1BvZb4JVNJjwEcDXp/k1iL1u/yeUedLzKRQQvqmLHOzXPd6cl82WyQ==} + hasBin: true + + '@block65/oxlint@1.83.0': + resolution: {integrity: sha512-5TR+kgM82dZXxA9WXa+sF1S4bUy5JZzCxeU83ItD/EifhTO1EHiEZ9Pnhf9YD7fjukDb7z7nji5D3CN9i8utvw==} + engines: {node: ^20.19.0 || >=22.12.0} + hasBin: true + peerDependencies: + oxlint-tsgolint: '>=7.0.2001' + vite-plus: '*' + peerDependenciesMeta: + oxlint-tsgolint: + optional: true + vite-plus: + optional: true - '@apidevtools/swagger-parser@12.1.0': - resolution: {integrity: sha512-e5mJoswsnAX0jG+J09xHFYQXb/bUc5S3pLpMxUuRUA2H8T2kni3yEoyz2R3Dltw5f4A6j6rPNMpWTK+iVDFlng==} + '@block65/shared-config@0.5.0': + resolution: {integrity: sha512-f7iXlaPc0GozRwUHzGxZ9hMrBGC6Ay07zTLt96A2zJ0YXsfyq0NkSOYe58nupTyu5P4rk/+lxjZPearGL/ORVg==} + engines: {node: '>=24'} peerDependencies: - openapi-types: '>=7' + fallow: ^3.27.0 + oxfmt: '>=0.68.0 <1.0.0' + oxlint: ^1.83.0 + oxlint-tsgolint: ^7.0.2002 + peerDependenciesMeta: + fallow: + optional: true + oxfmt: + optional: true + oxlint: + optional: true + oxlint-tsgolint: + optional: true + + '@block65/tsconfig@0.3.1': + resolution: {integrity: sha512-eDuYELFtiXrjYo/V6N6UQbBx4MKOJD2FZ/mzy2fuypyoNNPRxIaf5FxTl/xavO5y4+5FN2h5kQs81B+ko8MUWw==} + + '@cacheable/memory@2.2.0': + resolution: {integrity: sha512-CTLKqLItRCEixEAewD3/j9DB3/o96gpTPD4eJ1v+DGOlxZRZncRQkGYqqnAGCscYd6RNeXfGeiuCphsPtqyIfQ==} + + '@cacheable/utils@2.5.0': + resolution: {integrity: sha512-buipgOVDkkPXNR5+xBpDw7Zk2n1EvU7qBJCNUcL7rhQ//kfpOXPAvQ511Os0vpLYJ1pZnvudNytkQt2hst3wqA==} '@esbuild/aix-ppc64@0.27.3': resolution: {integrity: sha512-9fJMTNFTWZMh5qwrBItuziu834eOCUcEqymSH7pY+zoMVEZg3gcPuBNxH1EvfVYe9h0x/Ptw8KBzv7qxb7l8dg==} @@ -227,238 +445,597 @@ packages: cpu: [x64] os: [win32] + '@eslint-community/eslint-utils@4.10.1': + resolution: {integrity: sha512-cuadcxVFE8sDK6iWJbs8Sn0av2Nrh2QSGQhVlBW9AaAHqHwjWsZHT8LJ4hFGPh7ASBV2deFdM7H/DPjulmh8rg==} + engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + peerDependencies: + eslint: ^6.0.0 || ^7.0.0 || >=8.0.0 + + '@eslint-community/regexpp@4.12.2': + resolution: {integrity: sha512-EriSTlt5OC9/7SXkRSCAhfSxxoSUgBm33OH+IkwbdpgoqsSsUg7y3uh+IICI/Qg4BBWr3U2i39RpmycbxMq4ew==} + engines: {node: ^12.0.0 || ^14.0.0 || >=16.0.0} + + '@eslint/config-array@0.23.5': + resolution: {integrity: sha512-Y3kKLvC1dvTOT+oGlqNQ1XLqK6D1HU2YXPc52NmAlJZbMMWDzGYXMiPRJ8TYD39muD/OTjlZmNJ4ib7dvSrMBA==} + engines: {node: ^20.19.0 || ^22.13.0 || >=24} + + '@eslint/config-helpers@0.7.0': + resolution: {integrity: sha512-DObd/KKUsU+FaFv4PLxSRenpXfQWmPXXP3pPZ6/K1PCrMu2vQpMDMuQe/BqYeoLcz8ro0bVDF1RxOJgfVEdhUw==} + engines: {node: ^20.19.0 || ^22.13.0 || >=24} + + '@eslint/core@1.2.1': + resolution: {integrity: sha512-MwcE1P+AZ4C6DWlpin/OmOA54mmIZ/+xZuJiQd4SyB29oAJjN30UW9wkKNptW2ctp4cEsvhlLY/CsQ1uoHDloQ==} + engines: {node: ^20.19.0 || ^22.13.0 || >=24} + + '@eslint/css-tree@4.1.1': + resolution: {integrity: sha512-A+s89eP+yDAPkKjnIOfjlkGifg5J7GPn01nWx14UjBVWktfkxOU4975F9ZZ13xNxkGiblNcBaAqgKhnQrW6SWA==} + engines: {node: ^20.19.0 || ^22.13.0 || >=24} + + '@eslint/object-schema@3.0.5': + resolution: {integrity: sha512-vqTaUEgxzm+YDSdElad6PiRoX4t8VGDjCtt05zn4nU810UIx/uNEV7/lZJ6KwFThKZOzOxzXy48da+No7HZaMw==} + engines: {node: ^20.19.0 || ^22.13.0 || >=24} + + '@eslint/plugin-kit@0.7.3': + resolution: {integrity: sha512-IkO+/KEUvwbVpiURZg+P7zF74z5Jxe0UgJxVni+RtoHQ6IZieXaO02kmadomap/q+l6bc/jdPGGqTjhuZnuz1Q==} + engines: {node: ^20.19.0 || ^22.13.0 || >=24} + + '@fallow-cli/darwin-arm64@3.28.0': + resolution: {integrity: sha512-gsNF3u1brFaQDPgUPbIli7EwMNy/mLMwKK2vuZUzY786F06bPlTNNVd75ZcIzRowTtBfSm7beISusXJCPSwP3Q==} + cpu: [arm64] + os: [darwin] + + '@fallow-cli/darwin-x64@3.28.0': + resolution: {integrity: sha512-1lLxI8MIKUa9A3E5eGTY9Za4iovGPDCmsiph3OSjIvXAsey3C4iqygs+mIH307mu1yd5r3PqGHVKAdBOScZW4A==} + cpu: [x64] + os: [darwin] + + '@fallow-cli/linux-arm64-gnu@3.28.0': + resolution: {integrity: sha512-GSKMesFLtA41HqhwApqACd1hCerdUCZ/GTuRoraVBtbl0p6Y5gZZpUWeARy/akAi0twbIBV1k7hCLy/sPv5B3w==} + cpu: [arm64] + os: [linux] + + '@fallow-cli/linux-arm64-musl@3.28.0': + resolution: {integrity: sha512-KyLtUIUjFTa5r6ra/Y7omzVxK4lb3k/zBQ7l6PRakhfNwQKjX4/+ULU2lrXyEuA2Jmp4h0ZyE7hMhbOqp/1vlQ==} + cpu: [arm64] + os: [linux] + + '@fallow-cli/linux-x64-gnu@3.28.0': + resolution: {integrity: sha512-UYDgdjuzk9c8YMRtq6GPIrVAk3k8CccdaA9qFQ2Cin7xakp3JAWSep0aMP2kiCr9QZ/hKxxE8Ev+Q6joqbBbtw==} + cpu: [x64] + os: [linux] + + '@fallow-cli/linux-x64-musl@3.28.0': + resolution: {integrity: sha512-ZaFDgMEVMiujrJHCU7kn83yUeC5JkbB9ucOPG24lPqCRLelyd7fhLaEZ8P3zqP+yTYrAi3/KFgQjlVweFQZv6g==} + cpu: [x64] + os: [linux] + + '@fallow-cli/win32-arm64-msvc@3.28.0': + resolution: {integrity: sha512-ZKEFEp4CUnTkBZRjCMqN5GSJjzbmry9ZAjAawQPlwpzsaMlqBjSuZ1rBS/OsaiSHjZW3zXbtL/mc1+I+o2OEgA==} + cpu: [arm64] + os: [win32] + + '@fallow-cli/win32-x64-msvc@3.28.0': + resolution: {integrity: sha512-w8/QvEHLTbu+4DtHF6gd6bAIGEgGxy6zSOhd0F79Hqg3Ydx4NuyQFE7/sTsE8PEKIuYDbMpNy/Dx65W2lWeGWQ==} + cpu: [x64] + os: [win32] + + '@humanfs/core@0.19.2': + resolution: {integrity: sha512-UhXNm+CFMWcbChXywFwkmhqjs3PRCmcSa/hfBgLIb7oQ5HNb1wS0icWsGtSAUNgefHeI+eBrA8I1fxmbHsGdvA==} + engines: {node: '>=18.18.0'} + + '@humanfs/node@0.16.8': + resolution: {integrity: sha512-gE1eQNZ3R++kTzFUpdGlpmy8kDZD/MLyHqDwqjkVQI0JMdI1D51sy1H958PNXYkM2rAac7e5/CnIKZrHtPh3BQ==} + engines: {node: '>=18.18.0'} + + '@humanfs/types@0.15.0': + resolution: {integrity: sha512-ZZ1w0aoQkwuUuC7Yf+7sdeaNfqQiiLcSRbfI08oAxqLtpXQr9AIVX7Ay7HLDuiLYAaFPu8oBYNq/QIi9URHJ3Q==} + engines: {node: '>=18.18.0'} + + '@humanwhocodes/module-importer@1.0.1': + resolution: {integrity: sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==} + engines: {node: '>=12.22'} + + '@humanwhocodes/retry@0.4.3': + resolution: {integrity: sha512-bV0Tgo9K4hfPCek+aMAn81RppFKv2ySDQeMoSZuvTASywNTnVJCArCZE2FWqpvIatKu7VMRLWlR1EazvVhDyhQ==} + engines: {node: '>=18.18'} + + '@hyperjump/browser@1.5.0': + resolution: {integrity: sha512-h+fGXfmMOAxYjd2aZ4Y5jpP2WRi0TAkBmKNtoNJKcJLOahNrurwHEUgd1/jO2Hs2j/b/G1EhX0edX8ntXkH2MA==} + engines: {node: '>=18.0.0'} + + '@hyperjump/json-pointer@1.1.2': + resolution: {integrity: sha512-zPNgu1zdhtjQHFNLGzvEsLDsLOEvhRj6u6ktIQmlz7YPESv5uF8SnAe3Dq0oL6gZ6OGWSLq2n7pphRNF6Hpg6w==} + + '@hyperjump/json-schema-formats@1.0.7': + resolution: {integrity: sha512-5KmK9p/KbHYcDYA+Fqbfgk0IEwiv72MCMm5mzXPf4oQBDXRiy21v8iZPckeqb/KHO+lk8fKKcHL+3cftmHei6g==} + + '@hyperjump/json-schema@1.17.8': + resolution: {integrity: sha512-XOqbR9GRNHaH4JEXHdbsm7xfYwudZG7HVDq3qPZUb1gi+ZQPklgNvhMi6zf0Plf433qR61MK+xeeprUwUUvGPg==} + peerDependencies: + '@hyperjump/browser': ^1.1.0 + + '@hyperjump/pact@1.4.0': + resolution: {integrity: sha512-01Q7VY6BcAkp9W31Fv+ciiZycxZHGlR2N6ba9BifgyclHYHdbaZgITo0U6QMhYRlem4k8pf8J31/tApxvqAz8A==} + + '@hyperjump/uri@1.3.6': + resolution: {integrity: sha512-9a2/wOIp666Veq1a8QctYPRtyFHH0p1yw8Nt/DEf06M+eDpwBpeuc2rGqqjBthENTOy1NyJ/xhSiDtkjU5LfKA==} + + '@jridgewell/resolve-uri@3.1.2': + resolution: {integrity: sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==} + engines: {node: '>=6.0.0'} + '@jridgewell/sourcemap-codec@1.5.5': resolution: {integrity: sha512-cYQ9310grqxueWbl+WuIUIaiUaDcj7WOq5fVhEljNVgRfOUhY9fy2zTvfoqWsnebh8Sl70VScFbICvJnLKB0Og==} - '@jsdevtools/ono@7.1.3': - resolution: {integrity: sha512-4JQNk+3mVzK3xh2rqd6RB4J46qUR19azEHBneZyTZM+c456qOrbbM/5xcR8huNCCcbVt7+UmizG6GuUvPvKUYg==} + '@jridgewell/sourcemap-codec@1.6.0': + resolution: {integrity: sha512-T7jf+5zgsZHwNJ4lvQ7/aezbyk0nNX+zJVWpmHA7VYsEx7a7qr5Rg5IbtJFqkgze5Y2sruq1RUY8Q837Od7iFw==} + + '@jridgewell/trace-mapping@0.3.31': + resolution: {integrity: sha512-zzNR+SdQSDJzc8joaeP8QQoCQr8NuYx2dIIytl1QeBEZHJ9uW6hebsrYgbz8hJwUQao3TWCMtmfV8Nu1twOLAw==} + + '@keyv/bigmap@1.3.1': + resolution: {integrity: sha512-WbzE9sdmQtKy8vrNPa9BRnwZh5UF4s1KTmSK0KUVLo3eff5BlQNNWDnFOouNpKfPKDnms9xynJjsMYjMaT/aFQ==} + engines: {node: '>= 18'} + peerDependencies: + keyv: ^5.6.0 + + '@keyv/serialize@1.1.1': + resolution: {integrity: sha512-dXn3FZhPv0US+7dtJsIi2R+c7qWYiReoEh5zUntWCf4oSpMNib8FDhSoed6m3QyZdx5hK7iLFkYk3rNxwt8vTA==} - '@rollup/rollup-android-arm-eabi@4.59.0': - resolution: {integrity: sha512-upnNBkA6ZH2VKGcBj9Fyl9IGNPULcjXRlg0LLeaioQWueH30p6IXtJEbKAgvyv+mJaMxSm1l6xwDXYjpEMiLMg==} + '@oxc-project/types@0.150.0': + resolution: {integrity: sha512-rDS5/31E9HfPl/CIzGrn0DOlvBbXFseQ5URJ9sYMfstbKLD/c6Gm9vmRzRGDdAXyOIL4zmO37lc9RIwYqVruZw==} + + '@oxfmt/binding-android-arm-eabi@0.70.0': + resolution: {integrity: sha512-Xd7YO4/T2axEj6FTLcj4Why3mTBqFMg+x24xtorT4Lb2+1g82090GH0a/4U1m0pABGYiix2bq1pqkYrmV3f0Sw==} + engines: {node: ^20.19.0 || >=22.12.0} cpu: [arm] os: [android] - '@rollup/rollup-android-arm64@4.59.0': - resolution: {integrity: sha512-hZ+Zxj3SySm4A/DylsDKZAeVg0mvi++0PYVceVyX7hemkw7OreKdCvW2oQ3T1FMZvCaQXqOTHb8qmBShoqk69Q==} + '@oxfmt/binding-android-arm64@0.70.0': + resolution: {integrity: sha512-x9rlMYyKXdgKdYyUJzGsK1ZV8P4di/J32ipzcS6Jet6p9r9UAh28neXIMtdlSaJJycdi61Z4YkcLKLpk8ueFjg==} + engines: {node: ^20.19.0 || >=22.12.0} cpu: [arm64] os: [android] - '@rollup/rollup-darwin-arm64@4.59.0': - resolution: {integrity: sha512-W2Psnbh1J8ZJw0xKAd8zdNgF9HRLkdWwwdWqubSVk0pUuQkoHnv7rx4GiF9rT4t5DIZGAsConRE3AxCdJ4m8rg==} + '@oxfmt/binding-darwin-arm64@0.70.0': + resolution: {integrity: sha512-IUTUPvrBVYy7POh4stXzRdz4IVC/1QSaviCWoyenSlOhGu0X9j5K07vCTM9biLjAA2Zs31l0Rj5vvRpj9n95wA==} + engines: {node: ^20.19.0 || >=22.12.0} cpu: [arm64] os: [darwin] - '@rollup/rollup-darwin-x64@4.59.0': - resolution: {integrity: sha512-ZW2KkwlS4lwTv7ZVsYDiARfFCnSGhzYPdiOU4IM2fDbL+QGlyAbjgSFuqNRbSthybLbIJ915UtZBtmuLrQAT/w==} + '@oxfmt/binding-darwin-x64@0.70.0': + resolution: {integrity: sha512-vw745q870oTd6J517O24asoX4/E+eK0nxYIFoedSLqgJ+nI5En7+ZS82iZSHZ69zevQrnOXiyHP01dA+t8xD8w==} + engines: {node: ^20.19.0 || >=22.12.0} cpu: [x64] os: [darwin] - '@rollup/rollup-freebsd-arm64@4.59.0': - resolution: {integrity: sha512-EsKaJ5ytAu9jI3lonzn3BgG8iRBjV4LxZexygcQbpiU0wU0ATxhNVEpXKfUa0pS05gTcSDMKpn3Sx+QB9RlTTA==} - cpu: [arm64] - os: [freebsd] - - '@rollup/rollup-freebsd-x64@4.59.0': - resolution: {integrity: sha512-d3DuZi2KzTMjImrxoHIAODUZYoUUMsuUiY4SRRcJy6NJoZ6iIqWnJu9IScV9jXysyGMVuW+KNzZvBLOcpdl3Vg==} + '@oxfmt/binding-freebsd-x64@0.70.0': + resolution: {integrity: sha512-NO14EgSM9dFkcg+MfGPxvsKqXYs9LKaxPrOKXpv1R0rLokGGFDcCq6dBMq18dE4wlpFOovX0UZY2uh1P30O7QA==} + engines: {node: ^20.19.0 || >=22.12.0} cpu: [x64] os: [freebsd] - '@rollup/rollup-linux-arm-gnueabihf@4.59.0': - resolution: {integrity: sha512-t4ONHboXi/3E0rT6OZl1pKbl2Vgxf9vJfWgmUoCEVQVxhW6Cw/c8I6hbbu7DAvgp82RKiH7TpLwxnJeKv2pbsw==} + '@oxfmt/binding-linux-arm-gnueabihf@0.70.0': + resolution: {integrity: sha512-139OEhHarj9CYoJ/i9gXlPv4KLBGtLj2toseOWYFf09QwlhklaZk+wW3aOvlqoeZtuayvkoSNVWra7WJ21s3VQ==} + engines: {node: ^20.19.0 || >=22.12.0} cpu: [arm] os: [linux] - libc: [glibc] - '@rollup/rollup-linux-arm-musleabihf@4.59.0': - resolution: {integrity: sha512-CikFT7aYPA2ufMD086cVORBYGHffBo4K8MQ4uPS/ZnY54GKj36i196u8U+aDVT2LX4eSMbyHtyOh7D7Zvk2VvA==} + '@oxfmt/binding-linux-arm-musleabihf@0.70.0': + resolution: {integrity: sha512-GEh2PY3IWTE0M24eNhTduountANSbWyDmMnzFSQE/nGg/bjPugbUgiGuFu+xdqcQSd/HKSwH80/F2yVVD48yhA==} + engines: {node: ^20.19.0 || >=22.12.0} cpu: [arm] os: [linux] - libc: [musl] - '@rollup/rollup-linux-arm64-gnu@4.59.0': - resolution: {integrity: sha512-jYgUGk5aLd1nUb1CtQ8E+t5JhLc9x5WdBKew9ZgAXg7DBk0ZHErLHdXM24rfX+bKrFe+Xp5YuJo54I5HFjGDAA==} + '@oxfmt/binding-linux-arm64-gnu@0.70.0': + resolution: {integrity: sha512-En5i+UJmZSPxuSf47F2Hl5YOzKB0bicQLnGQkeTCMQ35cWLtbrSwACJKfiLqRZrk05DwSnsJkhBRaM3OURtIaA==} + engines: {node: ^20.19.0 || >=22.12.0} cpu: [arm64] os: [linux] libc: [glibc] - '@rollup/rollup-linux-arm64-musl@4.59.0': - resolution: {integrity: sha512-peZRVEdnFWZ5Bh2KeumKG9ty7aCXzzEsHShOZEFiCQlDEepP1dpUl/SrUNXNg13UmZl+gzVDPsiCwnV1uI0RUA==} + '@oxfmt/binding-linux-arm64-musl@0.70.0': + resolution: {integrity: sha512-WWOoV5W9Im3flVwOVrWn/2DUlOF8v5vcCip+kcNuaMpulRCh6nzzt1Su2vcL2F908YJIXNV3HvegbBHuyLwKHg==} + engines: {node: ^20.19.0 || >=22.12.0} cpu: [arm64] os: [linux] libc: [musl] - '@rollup/rollup-linux-loong64-gnu@4.59.0': - resolution: {integrity: sha512-gbUSW/97f7+r4gHy3Jlup8zDG190AuodsWnNiXErp9mT90iCy9NKKU0Xwx5k8VlRAIV2uU9CsMnEFg/xXaOfXg==} - cpu: [loong64] - os: [linux] - libc: [glibc] - - '@rollup/rollup-linux-loong64-musl@4.59.0': - resolution: {integrity: sha512-yTRONe79E+o0FWFijasoTjtzG9EBedFXJMl888NBEDCDV9I2wGbFFfJQQe63OijbFCUZqxpHz1GzpbtSFikJ4Q==} - cpu: [loong64] - os: [linux] - libc: [musl] - - '@rollup/rollup-linux-ppc64-gnu@4.59.0': - resolution: {integrity: sha512-sw1o3tfyk12k3OEpRddF68a1unZ5VCN7zoTNtSn2KndUE+ea3m3ROOKRCZxEpmT9nsGnogpFP9x6mnLTCaoLkA==} + '@oxfmt/binding-linux-ppc64-gnu@0.70.0': + resolution: {integrity: sha512-YUouneIqW+5n7aE8xx/zeZ6/utr/KH7oykcGoFyd8Uz8uh591T1oKlnoWA3BsRq/ZR42oY1w4MUYvS/0e/MQOA==} + engines: {node: ^20.19.0 || >=22.12.0} cpu: [ppc64] os: [linux] libc: [glibc] - '@rollup/rollup-linux-ppc64-musl@4.59.0': - resolution: {integrity: sha512-+2kLtQ4xT3AiIxkzFVFXfsmlZiG5FXYW7ZyIIvGA7Bdeuh9Z0aN4hVyXS/G1E9bTP/vqszNIN/pUKCk/BTHsKA==} - cpu: [ppc64] - os: [linux] - libc: [musl] - - '@rollup/rollup-linux-riscv64-gnu@4.59.0': - resolution: {integrity: sha512-NDYMpsXYJJaj+I7UdwIuHHNxXZ/b/N2hR15NyH3m2qAtb/hHPA4g4SuuvrdxetTdndfj9b1WOmy73kcPRoERUg==} + '@oxfmt/binding-linux-riscv64-gnu@0.70.0': + resolution: {integrity: sha512-iEnMf21S5aGVa4hViDGY8sAQ/AHyCu2JPyrQF8P06wtHhSkD1YJBeT4m/KiGewgf7+a5XCYSCRIPcRQa1xwEoQ==} + engines: {node: ^20.19.0 || >=22.12.0} cpu: [riscv64] os: [linux] libc: [glibc] - '@rollup/rollup-linux-riscv64-musl@4.59.0': - resolution: {integrity: sha512-nLckB8WOqHIf1bhymk+oHxvM9D3tyPndZH8i8+35p/1YiVoVswPid2yLzgX7ZJP0KQvnkhM4H6QZ5m0LzbyIAg==} + '@oxfmt/binding-linux-riscv64-musl@0.70.0': + resolution: {integrity: sha512-91Sdniaj20fQzyMeCxMDzTP4c9s4RB8dGQ308xHhDR0n6U7+1Xq7N9klE7mfXq8iV3lRmIGSXi5X23Hn/0XX/g==} + engines: {node: ^20.19.0 || >=22.12.0} cpu: [riscv64] os: [linux] libc: [musl] - '@rollup/rollup-linux-s390x-gnu@4.59.0': - resolution: {integrity: sha512-oF87Ie3uAIvORFBpwnCvUzdeYUqi2wY6jRFWJAy1qus/udHFYIkplYRW+wo+GRUP4sKzYdmE1Y3+rY5Gc4ZO+w==} + '@oxfmt/binding-linux-s390x-gnu@0.70.0': + resolution: {integrity: sha512-uUV30M6E+2TKKGMaKiwfeL4RZrviHXlUxsrYJ/jFBb+1EZy+pnFT+hF73eeWdzh5NqPOAnw0iiMAIqjqiLZPFg==} + engines: {node: ^20.19.0 || >=22.12.0} cpu: [s390x] os: [linux] libc: [glibc] - '@rollup/rollup-linux-x64-gnu@4.59.0': - resolution: {integrity: sha512-3AHmtQq/ppNuUspKAlvA8HtLybkDflkMuLK4DPo77DfthRb71V84/c4MlWJXixZz4uruIH4uaa07IqoAkG64fg==} + '@oxfmt/binding-linux-x64-gnu@0.70.0': + resolution: {integrity: sha512-ivMcX6kNDPhqtbOaBt/ItFlLlTlXNHLgRuNmxP6Na6UuYXRT10llpJcAPbGeRgjjb3Qzv4jwPp3fB0hui50WNQ==} + engines: {node: ^20.19.0 || >=22.12.0} cpu: [x64] os: [linux] libc: [glibc] - '@rollup/rollup-linux-x64-musl@4.59.0': - resolution: {integrity: sha512-2UdiwS/9cTAx7qIUZB/fWtToJwvt0Vbo0zmnYt7ED35KPg13Q0ym1g442THLC7VyI6JfYTP4PiSOWyoMdV2/xg==} + '@oxfmt/binding-linux-x64-musl@0.70.0': + resolution: {integrity: sha512-w+S+fERxYmlZSyZlJK/U292FjyBoH8cCEj21/tYJX6atX5kNSn+HDkhlFQKT2zcMwUW0uAtUL/bOrlwJZwqRdA==} + engines: {node: ^20.19.0 || >=22.12.0} cpu: [x64] os: [linux] libc: [musl] - '@rollup/rollup-openbsd-x64@4.59.0': - resolution: {integrity: sha512-M3bLRAVk6GOwFlPTIxVBSYKUaqfLrn8l0psKinkCFxl4lQvOSz8ZrKDz2gxcBwHFpci0B6rttydI4IpS4IS/jQ==} - cpu: [x64] - os: [openbsd] - - '@rollup/rollup-openharmony-arm64@4.59.0': - resolution: {integrity: sha512-tt9KBJqaqp5i5HUZzoafHZX8b5Q2Fe7UjYERADll83O4fGqJ49O1FsL6LpdzVFQcpwvnyd0i+K/VSwu/o/nWlA==} + '@oxfmt/binding-openharmony-arm64@0.70.0': + resolution: {integrity: sha512-Zlom1Xkx257R8bk4ZI4zJsrGno2opknz1+5v5baka3nn4FPyvNSdh8JUL4CdN1S1OWRMvJ9UJQ+RfIqGGCUEfA==} + engines: {node: ^20.19.0 || >=22.12.0} cpu: [arm64] os: [openharmony] - '@rollup/rollup-win32-arm64-msvc@4.59.0': - resolution: {integrity: sha512-V5B6mG7OrGTwnxaNUzZTDTjDS7F75PO1ae6MJYdiMu60sq0CqN5CVeVsbhPxalupvTX8gXVSU9gq+Rx1/hvu6A==} + '@oxfmt/binding-win32-arm64-msvc@0.70.0': + resolution: {integrity: sha512-FQgPW5R17vzt7cgrJ8eG/dqX00o2xHsqFeLfw4xzA9FRHpN/DjFo9YDonvIIXGxiEuS9F/jZPnGO+KHNKuCo4Q==} + engines: {node: ^20.19.0 || >=22.12.0} cpu: [arm64] os: [win32] - '@rollup/rollup-win32-ia32-msvc@4.59.0': - resolution: {integrity: sha512-UKFMHPuM9R0iBegwzKF4y0C4J9u8C6MEJgFuXTBerMk7EJ92GFVFYBfOZaSGLu6COf7FxpQNqhNS4c4icUPqxA==} + '@oxfmt/binding-win32-ia32-msvc@0.70.0': + resolution: {integrity: sha512-ZfZublNhZ+XBndMiXhkiLlPE+XyGRDa0CweeTL6t1fZypfCh1LTg7e5CvnOeTBunq15MskOcRempumSPGAaCQA==} + engines: {node: ^20.19.0 || >=22.12.0} cpu: [ia32] os: [win32] - '@rollup/rollup-win32-x64-gnu@4.59.0': - resolution: {integrity: sha512-laBkYlSS1n2L8fSo1thDNGrCTQMmxjYY5G0WFWjFFYZkKPjsMBsgJfGf4TLxXrF6RyhI60L8TMOjBMvXiTcxeA==} - cpu: [x64] - os: [win32] - - '@rollup/rollup-win32-x64-msvc@4.59.0': - resolution: {integrity: sha512-2HRCml6OztYXyJXAvdDXPKcawukWY2GpR5/nxKp4iBgiO3wcoEGkAaqctIbZcNB6KlUQBIqt8VYkNSj2397EfA==} + '@oxfmt/binding-win32-x64-msvc@0.70.0': + resolution: {integrity: sha512-HlIZEn+WzLQL0DszNzldiRl/DPRCX5R0Vkt6qeUPR1YHwy52hZZo4x6HoTOVmKRP2wUiwPGtKsihNY/f8KRaBg==} + engines: {node: ^20.19.0 || >=22.12.0} cpu: [x64] os: [win32] - '@tsconfig/node24@24.0.4': - resolution: {integrity: sha512-2A933l5P5oCbv6qSxHs7ckKwobs8BDAe9SJ/Xr2Hy+nDlwmLE1GhFh/g/vXGRZWgxBg9nX/5piDtHR9Dkw/XuA==} - - '@tsconfig/strictest@2.0.8': - resolution: {integrity: sha512-XnQ7vNz5HRN0r88GYf1J9JJjqtZPiHt2woGJOo2dYqyHGGcd6OLGqSlBB6p1j9mpzja6Oe5BoPqWmeDx6X9rLw==} + '@rolldown/binding-android-arm-eabi@1.2.9': + resolution: {integrity: sha512-tNISae1QEf/vkb3xkRcjV5SEdzPE97We5IVaa2Z8jSszQPZ8U60B/YCYpw4QI7VidYsBtKavczXf+DyDs9WGxw==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [arm] + os: [android] - '@types/chai@5.2.3': - resolution: {integrity: sha512-Mw558oeA9fFbv65/y4mHtXDs9bPnFMZAL/jxdPFUpOHHIXX91mcgEHbS5Lahr+pwZFR8A7GQleRWeI6cGFC2UA==} + '@rolldown/binding-android-arm64@1.2.9': + resolution: {integrity: sha512-YC8YsI30o606GTZi0VyzYlsDKFP8W61i/QzayHDkLbNEz/IShqAmTa+hsJRj13xTHA0H+6fk4b2UmGn+Q/cMlg==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [arm64] + os: [android] - '@types/deep-eql@4.0.2': - resolution: {integrity: sha512-c9h9dVVMigMPc4bwTvC5dxqtqJZwQPePsWjPlpSOnojbor6pGqdk541lfA7AqFQr5pB1BRdq0juY9db81BwyFw==} + '@rolldown/binding-darwin-arm64@1.2.9': + resolution: {integrity: sha512-IwhlH3qK5urrY8hZiEgGkHKEFN901p/p2bjxCxJlr4GyNnF7wYpUvK+Y43uaRYuC4hpfjzbR3SJC3arX1jGvmw==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [arm64] + os: [darwin] - '@types/estree@1.0.8': - resolution: {integrity: sha512-dWHzHa2WqEXI/O1E9OjrocMTKJl2mSrEolh1Iomrv6U+JuNwaHXsXx9bLu5gG7BUWFIN0skIQJQ/L1rIex4X6w==} + '@rolldown/binding-darwin-x64@1.2.9': + resolution: {integrity: sha512-XxpJfVzFh+jilRxIXUqcfYAYcunIc/XEzIizsOL1fcJee5Sf7H3mH8WlLmfHfluz5amqR88QQo9izKtmMlavAw==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [x64] + os: [darwin] - '@types/json-schema@7.0.15': - resolution: {integrity: sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==} + '@rolldown/binding-freebsd-x64@1.2.9': + resolution: {integrity: sha512-kSfvhmgeWyfkbT3p/1s5vSgboogoah2zkm9fX2zjg2hHxSV7T4KhMWRUUaRk4OXNqoD3QAUeRqLcs1aZOK4U1g==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [x64] + os: [freebsd] - '@types/lodash@4.17.24': - resolution: {integrity: sha512-gIW7lQLZbue7lRSWEFql49QJJWThrTFFeIMJdp3eH4tKoxm1OvEPg02rm4wCCSHS0cL3/Fizimb35b7k8atwsQ==} + '@rolldown/binding-linux-arm-gnueabihf@1.2.9': + resolution: {integrity: sha512-1RVzG17pxqbTfYLC352JlLt6kKLG+6Hr30n8DlIJqsnV5luUDd2Qdx9Ayw1Cabfyb1K9k0jXEZ7evxkRoT+uiw==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [arm] + os: [linux] - '@types/node@24.12.0': - resolution: {integrity: sha512-GYDxsZi3ChgmckRT9HPU0WEhKLP08ev/Yfcq2AstjrDASOYCSXeyjDsHg4v5t4jOj7cyDX3vmprafKlWIG9MXQ==} + '@rolldown/binding-linux-arm64-gnu@1.2.9': + resolution: {integrity: sha512-BXqPvZ2drqVD+/Z8UpKwcs4Mp7grM+eGFku4CAEKrEtcbAsUpzREphK1sogCRZGreVPiMkiiBtw0n3TPteuqvw==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [arm64] + os: [linux] + libc: [glibc] - '@vitest/expect@3.2.4': - resolution: {integrity: sha512-Io0yyORnB6sikFlt8QW5K7slY4OjqNX9jmJQ02QDda8lyM6B5oNgVWoSoKPac8/kgnCUzuHQKrSLtu/uOqqrig==} + '@rolldown/binding-linux-arm64-musl@1.2.9': + resolution: {integrity: sha512-11vWvo8YDwLzukt27J3aYDWU+gg2P7J+ZOmiJ0hkF5BXZDW7pVya7r40MXDy6ya0i9KamoENSVKIugvJNgFXIA==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [arm64] + os: [linux] + libc: [musl] - '@vitest/mocker@3.2.4': - resolution: {integrity: sha512-46ryTE9RZO/rfDd7pEqFl7etuyzekzEhUbTW3BvmeO/BcCMEgq59BKhek3dXDWgAj4oMK6OZi+vRr1wPW6qjEQ==} + '@rolldown/binding-linux-ppc64-gnu@1.2.9': + resolution: {integrity: sha512-a1tijMkdwsIARtc0F39ApURROkf3NwqinI6TOiSSWCTR7dT96dffNvMUtDHnq64wKNTIZOIlzKrFvvFUznJiyw==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [ppc64] + os: [linux] + libc: [glibc] + + '@rolldown/binding-linux-s390x-gnu@1.2.9': + resolution: {integrity: sha512-x6SQNdAvv4c3hWqTMaWuawzMX9myaCs/yEmlGsxJzkdClnHW7FbrjQuSiRDhuSYzEYoEMhsaJy9qHG/XNemJPQ==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [s390x] + os: [linux] + libc: [glibc] + + '@rolldown/binding-linux-x64-gnu@1.2.9': + resolution: {integrity: sha512-9s0AZ8BFK5/n7B/TBoa2yJE3gI3KURrbXcPBlsAsvjU4VeJKgE90y1YtNxyEUIcHPQkg6/yfF3qihUrcM/Kf0Q==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [x64] + os: [linux] + libc: [glibc] + + '@rolldown/binding-linux-x64-musl@1.2.9': + resolution: {integrity: sha512-P7VWAmV+WdJluH7ovnRGoiv2i8To7GAZ+kGzfGup635cyL7SyYl3lSUaA3Gp5THf0n/Co5EyEqb2zbqq+nMOHQ==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [x64] + os: [linux] + libc: [musl] + + '@rolldown/binding-openharmony-arm64@1.2.9': + resolution: {integrity: sha512-1qixtsE4BK8h+yS3BfmZ09UhA7O/N4IACva6YBr7EBvCJraByTuRcgOTaiA62Tm0vey3UcKXLOaoGHtYmNGEVg==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [arm64] + os: [openharmony] + + '@rolldown/binding-win32-arm64-msvc@1.2.9': + resolution: {integrity: sha512-ok8IQjcEPs1AKZfuEUznVBrJw+gK4soq+bx8b1X2XoMqVClarc1q5JDmVtWXY1xfr6ZuHTAsPXHTgTrqKTZeww==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [arm64] + os: [win32] + + '@rolldown/binding-win32-x64-msvc@1.2.9': + resolution: {integrity: sha512-Ip2mXoU0hM0boq3Rf+ekuT653OROSo6aSYcPT1VHE4q52KvyxgFkQgrgb/IEsxOuvQ2fZZbs8khJAyCEPM24/g==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [x64] + os: [win32] + + '@rolldown/pluginutils@1.0.1': + resolution: {integrity: sha512-2j9bGt5Jh8hj+vPtgzPtl72j0yRxHAyumoo6TNfAjsLB04UtpSvPbPcDcBMxz7n+9CYB0c1GxQFxYRg2jimqGw==} + + '@types/chai@5.2.3': + resolution: {integrity: sha512-Mw558oeA9fFbv65/y4mHtXDs9bPnFMZAL/jxdPFUpOHHIXX91mcgEHbS5Lahr+pwZFR8A7GQleRWeI6cGFC2UA==} + + '@types/deep-eql@4.0.2': + resolution: {integrity: sha512-c9h9dVVMigMPc4bwTvC5dxqtqJZwQPePsWjPlpSOnojbor6pGqdk541lfA7AqFQr5pB1BRdq0juY9db81BwyFw==} + + '@types/esrecurse@4.3.1': + resolution: {integrity: sha512-xJBAbDifo5hpffDBuHl0Y8ywswbiAp/Wi7Y/GtAgSlZyIABppyurxVueOPE8LUQOxdlgi6Zqce7uoEpqNTeiUw==} + + '@types/estree@1.0.8': + resolution: {integrity: sha512-dWHzHa2WqEXI/O1E9OjrocMTKJl2mSrEolh1Iomrv6U+JuNwaHXsXx9bLu5gG7BUWFIN0skIQJQ/L1rIex4X6w==} + + '@types/json-schema@7.0.15': + resolution: {integrity: sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==} + + '@types/node@26.6.2': + resolution: {integrity: sha512-X1P21scMv4zGKLYqjdGjaKa7COa0RKVYYZZN/NfvLQ1JegxFhdhpZG/Lyn8AXx6CDUavKAd11v6BvfpkDByK8g==} + + '@typescript/typescript-aix-ppc64@7.0.2': + resolution: {integrity: sha512-MTKKkWB7p/0E9xi1d1tHtZ5PiLkGEMIq88pK2CubZjOsLtYTLqhgIgi6zepFa+9GHZ6h05NMCkQxGKiPXMxXtQ==} + engines: {node: '>=16.20.0'} + cpu: [ppc64] + os: [aix] + + '@typescript/typescript-darwin-arm64@7.0.2': + resolution: {integrity: sha512-gowzar9MwS/aRWp6f3a4KUqzRjAZjOsmGNCM6LcTgXum+dBfgsBVMN+AgvOCCbguXyick6LJhpBszxMebJ8syA==} + engines: {node: '>=16.20.0'} + cpu: [arm64] + os: [darwin] + + '@typescript/typescript-darwin-x64@7.0.2': + resolution: {integrity: sha512-SZ9xZInqApNlNGc9s0W1VSsktYSOe9cFqNOIqmN1Gs8SmkjKZYFt017G4VwPxASInODuAdbTW7sXiFUf893RgA==} + engines: {node: '>=16.20.0'} + cpu: [x64] + os: [darwin] + + '@typescript/typescript-freebsd-arm64@7.0.2': + resolution: {integrity: sha512-W5NH4y/J0plIIS5b2xvTEkU7JFxyqdMAOgf+Ilhl0vHQXKO5dZoxd+C/jEtq56c4F3wk71RB4BMRQ2XdI+bwYQ==} + engines: {node: '>=16.20.0'} + cpu: [arm64] + os: [freebsd] + + '@typescript/typescript-freebsd-x64@7.0.2': + resolution: {integrity: sha512-UMGDx5sTpzNw3WiPebH7l90IWfJggEd+egHt/q6p7/Cm3zqoV7VxkGXt+3DxPIw8CcmvAB0j3sVVfbhX+M4Tpw==} + engines: {node: '>=16.20.0'} + cpu: [x64] + os: [freebsd] + + '@typescript/typescript-linux-arm64@7.0.2': + resolution: {integrity: sha512-Qh4eU4/y3yDjnfjjyPYihMj5/ODIlmt+Bzu17OI+fiSRDW57QmU5SiN63exPRNJPKUzcc1INa1NXdrJ+MqHjUQ==} + engines: {node: '>=16.20.0'} + cpu: [arm64] + os: [linux] + + '@typescript/typescript-linux-arm@7.0.2': + resolution: {integrity: sha512-gffT3xPz9sR7j/YJExkyPntrI0P2EP9XbOyWzth2/Gs0RstK+90RBcO0ncXoXy/beYll1SXw846Nf2zdnEz0QQ==} + engines: {node: '>=16.20.0'} + cpu: [arm] + os: [linux] + + '@typescript/typescript-linux-loong64@7.0.2': + resolution: {integrity: sha512-uEHck9i8hoAzXPiYRib1O7miOnz23SxIeVl6F4LXox+qov1K35jHcEW6VHKvZI+pyvl7fZEP4MCU5LYvIq1GuQ==} + engines: {node: '>=16.20.0'} + cpu: [loong64] + os: [linux] + + '@typescript/typescript-linux-mips64el@7.0.2': + resolution: {integrity: sha512-R4KvAMnE43W5Qeqb0Ly56O3mWMWIAgsMyz36DCaycd5nbg/9kzm0liw3JocfRqyJY0KPmzFjbswozXyW0DnIYA==} + engines: {node: '>=16.20.0'} + cpu: [mips64el] + os: [linux] + + '@typescript/typescript-linux-ppc64@7.0.2': + resolution: {integrity: sha512-DORx5b3sd/4S7eayxm4FQv+A7CrkUIGRaHiwI8oiHTAI1fAPWhF4J0vAlkC8biAlHSVVwxMQ3tjZ2/DVbnQiiA==} + engines: {node: '>=16.20.0'} + cpu: [ppc64] + os: [linux] + + '@typescript/typescript-linux-riscv64@7.0.2': + resolution: {integrity: sha512-wf0jqEDOjrPRnKwYRyyJDRo11KMbvMFrU+q4zqKyChODBzvlkbhNQfKvLxQCcwTpdDaXSHZTVuh0JoCrKCUMHQ==} + engines: {node: '>=16.20.0'} + cpu: [riscv64] + os: [linux] + + '@typescript/typescript-linux-s390x@7.0.2': + resolution: {integrity: sha512-IkwJc3L7yhytWd/ewjyxNDfOmswCm9GWMJT/ue/dU4aZNbwZeYAetq42VyLmsmSjvoX7z74X6ZaYCtzAr0EuGw==} + engines: {node: '>=16.20.0'} + cpu: [s390x] + os: [linux] + + '@typescript/typescript-linux-x64@7.0.2': + resolution: {integrity: sha512-EYdf2cNg7rgCWJnxCdJ+F3V39O8ihb37eHAu1LK8oAFizgTQbPOK7zHHXbPt8rX24COqODXeI3sIf0fCXG7H/A==} + engines: {node: '>=16.20.0'} + cpu: [x64] + os: [linux] + + '@typescript/typescript-netbsd-arm64@7.0.2': + resolution: {integrity: sha512-+polYF4MF04aPpO5FTkHran9yUQDSXqy5GiSDKpsll5jy3l3+g9QLhpf39T+ePtefhXLOGrLl0QIjkQP6VnelA==} + engines: {node: '>=16.20.0'} + cpu: [arm64] + os: [netbsd] + + '@typescript/typescript-netbsd-x64@7.0.2': + resolution: {integrity: sha512-8YIT0EHM/3dq10ZOVF/A7pc/YSMtbcecct4rWtexrnSCHOPcpC2KTLXfTCR6vDpnSiY12heNb1GiN/wu+T/FyA==} + engines: {node: '>=16.20.0'} + cpu: [x64] + os: [netbsd] + + '@typescript/typescript-openbsd-arm64@7.0.2': + resolution: {integrity: sha512-APT8+ClYnuYm1u9+kgGXoMj2VzWzcymwh2gNSQVySHfkRDGOTVkoWLjCmOQSaO+PoqQ57B0flRp9SA+7GnnkzQ==} + engines: {node: '>=16.20.0'} + cpu: [arm64] + os: [openbsd] + + '@typescript/typescript-openbsd-x64@7.0.2': + resolution: {integrity: sha512-yX7s+Q0Dln0Dt9tEzZsAjXXR/+ytBM7AlglaqyeMPxQszJ1JhlJdZ6jLA+IzldHtflX81em7lDao1xXu+aRRkg==} + engines: {node: '>=16.20.0'} + cpu: [x64] + os: [openbsd] + + '@typescript/typescript-sunos-x64@7.0.2': + resolution: {integrity: sha512-dLJDGaLZ1D4HPQn62u1n8mBDkJREwMsAkCdkwd4Ieqw+x3TUyTsqY0YiBCtE6H6OzzgGk3iuZ3vFWRS+E8/d1g==} + engines: {node: '>=16.20.0'} + cpu: [x64] + os: [sunos] + + '@typescript/typescript-win32-arm64@7.0.2': + resolution: {integrity: sha512-Gyl1Vy6OsWesLzmq+EP0Fb7b4Nid5232AvcA2SFcdYreldpNtYFFofPjnt62y9hQy7VTaZp65ICJjuAQRaVcIQ==} + engines: {node: '>=16.20.0'} + cpu: [arm64] + os: [win32] + + '@typescript/typescript-win32-x64@7.0.2': + resolution: {integrity: sha512-0BQ3HkAHHlKLSp1qRvf3SUhGpGsDuhB/jgFw75guyqbxJqEaS0Cw/VFO8i2nHglJUzQCRtMMR/IBAKE3ETMC4g==} + engines: {node: '>=16.20.0'} + cpu: [x64] + os: [win32] + + '@vitest/mocker@5.0.1': + resolution: {integrity: sha512-6K1DoBNAPGvuOcSsGA4D6x+5zEEff/KmOOP3uetT2TrGpVfI+HRHRnJJfKi5ib/g1vx8IYHQD8s0pbJz8WQI7Q==} peerDependencies: msw: ^2.4.9 - vite: ^5.0.0 || ^6.0.0 || ^7.0.0-0 + vite: ^6.0.0 || ^7.0.0 || ^8.0.0 peerDependenciesMeta: msw: optional: true vite: optional: true - '@vitest/pretty-format@3.2.4': - resolution: {integrity: sha512-IVNZik8IVRJRTr9fxlitMKeJeXFFFN0JaB9PHPGQ8NKQbGpfjlTx9zO4RefN8gp7eqjNy8nyK3NZmBzOPeIxtA==} - - '@vitest/runner@3.2.4': - resolution: {integrity: sha512-oukfKT9Mk41LreEW09vt45f8wx7DordoWUZMYdY/cyAk7w5TWkTRCNZYF7sX7n2wB7jyGAl74OxgwhPgKaqDMQ==} - - '@vitest/snapshot@3.2.4': - resolution: {integrity: sha512-dEYtS7qQP2CjU27QBC5oUOxLE/v5eLkGqPE0ZKEIDGMs4vKWe7IjgLOeauHsR0D5YuuycGRO5oSRXnwnmA78fQ==} - - '@vitest/spy@3.2.4': - resolution: {integrity: sha512-vAfasCOe6AIK70iP5UD11Ac4siNUNJ9i/9PZ3NKx07sG6sUxeag1LWdNrMWeKKYBLlzuK+Gn65Yd5nyL6ds+nw==} + '@vitest/spy@5.0.1': + resolution: {integrity: sha512-rbto/mF/SGERxEgYOek7Xm6B9b+y+mVoo+f4b2LymYO8zM1b7uB5nHuhVMTP2hxdzgxvGiZYGxGIaMvL5y180Q==} - '@vitest/utils@3.2.4': - resolution: {integrity: sha512-fB2V0JFrQSMsCo9HiSq3Ezpdv4iYaXRG1Sx8edX3MwxfyNn83mKiGzOcH+Fkxt4MHxr3y42fQi1oeAInqgX2QA==} - - ajv-draft-04@1.0.0: - resolution: {integrity: sha512-mv00Te6nmYbRp5DCwclxtt7yV/joXJPGS7nM+97GdxvuttCOfgI3K4U25zboyeX0O+myI8ERluxQe5wljMmVIw==} + acorn-jsx@5.3.2: + resolution: {integrity: sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==} peerDependencies: - ajv: ^8.5.0 - peerDependenciesMeta: - ajv: - optional: true + acorn: ^6.0.0 || ^7.0.0 || ^8.0.0 - ajv@8.18.0: - resolution: {integrity: sha512-PlXPeEWMXMZ7sPYOHqmDyCJzcfNrUr3fGNKtezX14ykXOEIvyK81d+qydx89KY5O71FKMPaQ2vBfBFI5NHR63A==} + acorn@8.18.0: + resolution: {integrity: sha512-lGq+9yr1/GuAWaVYIHRjvvySG5/4VfKIvC8EWxStPdcDh/Ka7FG3twP6v4d5BkravUilhIAsG4Qj83t02LWUPQ==} + engines: {node: '>=0.4.0'} + hasBin: true - argparse@2.0.1: - resolution: {integrity: sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==} + ajv@6.15.0: + resolution: {integrity: sha512-fgFx7Hfoq60ytK2c7DhnF8jIvzYgOMxfugjLOSMHjLIPgenqa7S7oaagATUq99mV6IYvN2tRmC0wnTYX6iPbMw==} assertion-error@2.0.1: resolution: {integrity: sha512-Izi8RQcffqCeNVgFigKli1ssklIbpHnCYc6AknXGYoB6grJqyeby7jv12JUQgmTAnIDnbck1uxksT4dzN3PWBA==} engines: {node: '>=12'} - cac@6.7.14: - resolution: {integrity: sha512-b6Ilus+c3RrdDk+JhLKUAQfzzgLEPy6wcXqS7f/xe1EETvsDP6GORG7SFuOs6cID5YkqchW/LXZbX5bc8j7ZcQ==} - engines: {node: '>=8'} + balanced-match@4.0.4: + resolution: {integrity: sha512-BLrgEcRTwX2o6gGxGOCNyMvGSp35YofuYzw9h1IMTRmKqttAZZVU67bdb9Pr2vUHA8+j3i2tJfjO6C6+4myGTA==} + engines: {node: 18 || 20 || >=22} + + baseline-browser-mapping@2.11.25: + resolution: {integrity: sha512-gMmEShwwq7FJqMwvfRwvCl00v4kN+KOfJqXn+f4nrufak5gNHJOksd/60Dvjuz7sI8Y5WiSFBa8FEYr+zoyqCw==} + engines: {node: '>=6.0.0'} + hasBin: true + + brace-expansion@5.0.12: + resolution: {integrity: sha512-YovQ3rzhaLMIrDjNDMkNS01tea93qhEhG5xy8f6+R0l+dw3Ki+5sCoIoI942iuLZTHWogWktgwVDhU09iNEimQ==} + engines: {node: 20 || >=22} + + browserslist@4.29.0: + resolution: {integrity: sha512-3GSvyjvDI4Dur1Meg2BekJquu5uF+9R9a1+5M1Mde192eZoXbeXjzgOsgqPS2V8D5wrrip0gR5Hf/GhWQ9ZzaA==} + engines: {node: ^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7} + hasBin: true - call-me-maybe@1.0.2: - resolution: {integrity: sha512-HpX65o1Hnr9HH25ojC1YGs7HCQLq0GCOibSaWER0eNpgJ/Z1MZv2mTc7+xh6WOPxbRVcmgbv4hGU+uSQ/2xFZQ==} + builtin-modules@5.4.0: + resolution: {integrity: sha512-JCWSCdun+4Ovd9BhM/Vtlmwb7oD6Wl4YiPRXXwhAuwlPhW1un/MKgXn7GZoFm53ginnoNzus69V8JWx0K393jg==} + engines: {node: '>=18.20'} - chai@5.3.3: - resolution: {integrity: sha512-4zNhdJD/iOjSH0A05ea+Ke6MU5mmpQcbQsSOkgdaUMJ9zTlDTD/GYlwohmIE2u0gaxHYiVHEn1Fw9mZ/ktJWgw==} + cacheable@2.5.0: + resolution: {integrity: sha512-60cyAOytib/OzBw1JNSoSV/boK1AtHryDIjvVBk7XbN4ugfkM3+Sry7fEjNgPMGgOjuaZPAp8ruZ0Cxafwyq9g==} + + caniuse-lite@1.0.30001810: + resolution: {integrity: sha512-TITQPUkaz+aVk5GL6NhOdwk1aEaNTSDPsGFWrTuhKGtjTF70jL/Oht2W4c6rXUe5fu7Ie19VIahAXHIIiWWNeg==} + + chai@6.2.2: + resolution: {integrity: sha512-NUPRluOfOiTKBKvWPtSD4PhFvWCqOi0BGStNWs57X9js7XGTprSmFoz5F0tWhR4WPjNeR9jXqdC7/UpSJTnlRg==} engines: {node: '>=18'} - check-error@2.1.3: - resolution: {integrity: sha512-PAJdDJusoxnwm1VwW07VWwUN1sl7smmC3OKggvndJFadxxDRyFJBX/ggnu/KE4kQAB7a3Dp8f/YXC1FlUprWmA==} - engines: {node: '>= 16'} + change-case@5.4.4: + resolution: {integrity: sha512-HRQyTk2/YPEkt9TnUPbOpr64Uw3KOicFWPVBb+xiHvd6eBx/qPr9xqfBFDT8P2vWsvvz4jbEkfDe71W3VyNu2w==} + + ci-info@4.4.0: + resolution: {integrity: sha512-77PSwercCZU2Fc4sX94eF8k8Pxte6JAwL4/ICZLFjJLqegs7kCuAsqqj/70NQF6TvDpgFjkubQB2FW2ZZddvQg==} + engines: {node: '>=8'} + + constructs@10.8.1: + resolution: {integrity: sha512-98yGXYyhePqPYh3cYu8nzBERmAhC0DONe3UD03okK0nehZ7hYP4wgZuf02a04+uOWxnTJ5Rpp5m0GRNpwyLGGA==} + + content-type@1.0.5: + resolution: {integrity: sha512-nTjqfcBFEipKdXCv4YDQWCfmcLZKm81ldF0pAopTvyrFGVbcR6P/VAAd5G7N+0tTr8QqiU0tFadD6FK4NtJwOA==} + engines: {node: '>= 0.6'} + + convert-hrtime@5.0.0: + resolution: {integrity: sha512-lOETlkIeYSJWcbbcvjRKGxVMXJR+8+OQb/mTPbA4ObPMytYIsUbuOE0Jzy60hjARYszq1id0j8KgVhC+WGZVTg==} + engines: {node: '>=12'} + + core-js-compat@3.50.0: + resolution: {integrity: sha512-XGpFGbMLHwSt74YLTKho7Ib242qi6O8MSX+sRokV4oz7iKXvQWGYZthjIhjRGMxjzVkAubBO512dKGYcefmX3Q==} + engines: {node: '>=6.4.0'} - constructs@10.5.1: - resolution: {integrity: sha512-f/TfFXiS3G/yVIXDjOQn9oTlyu9Wo7Fxyjj7lb8r92iO81jR2uST+9MstxZTmDGx/CgIbxCXkFXgupnLTNxQZg==} + cross-spawn@7.0.6: + resolution: {integrity: sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==} + engines: {node: '>= 8'} + + css-tree@3.2.1: + resolution: {integrity: sha512-X7sjQzceUhu1u7Y/ylrRZFU2FS6LRiFVp6rKLPg23y3x3c3DOKAwuXGDp+PAGjh6CSnCjYeAul8pcT8bAl+lSA==} + engines: {node: ^10 || ^12.20.0 || ^14.13.0 || >=15.0.0} debug@4.4.3: resolution: {integrity: sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==} @@ -469,30 +1046,113 @@ packages: supports-color: optional: true - deep-eql@5.0.2: - resolution: {integrity: sha512-h5k/5U50IJJFpzfL6nO9jaaumfjO/f2NjK/oYB2Djzm4p9L+3T9qWpZqZ2hAbLPuuYq9wrU08WQyBTL5GbPk5Q==} - engines: {node: '>=6'} + deep-is@0.1.4: + resolution: {integrity: sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==} + + detect-indent@7.0.2: + resolution: {integrity: sha512-y+8xyqdGLL+6sh0tVeHcfP/QDd8gUgbasolJJpY7NgeQGSZ739bDtSiaiDgtoicy+mtYB81dKLxO9xRhCyIB3A==} + engines: {node: '>=12.20'} + + detect-libc@2.1.2: + resolution: {integrity: sha512-Btj2BOOO83o3WyH59e8MgXsxEQVcarkUOpEYrubB0urwnN10yQ364rsiByU11nZlqWYZm05i/of7io4mzihBtQ==} + engines: {node: '>=8'} + + electron-to-chromium@1.5.434: + resolution: {integrity: sha512-7EeFW9OLf1NN9NKQP9xdOE/XKqjxv7JDPP6AEAkHli11+Fae1OaLoNuAf13hQv1PPNtuES0pLQSPk2+fS3s8ww==} + + entities@8.1.0: + resolution: {integrity: sha512-kxL7msIffSuh9aaFAMD7rxAIuTRMAHMeBtgHW2yUdWw732ZNh4MehkF2gdjvtdmikkaIP9bFDDJOPlsvm7avrA==} + engines: {node: '>=20.19.0'} - es-module-lexer@1.7.0: - resolution: {integrity: sha512-jEQoCwk8hyb2AZziIOLhDqpm5+2ww5uIE6lkO/6jcOCusfk6LhMHpXXfBLXTZ7Ydyt0j4VoUQv6uGNYbdW+kBA==} + es-module-lexer@2.3.2: + resolution: {integrity: sha512-poHGpORABojJJucnV9KbOavETW8lBVnphkW77ER5/BQ5Fz7oXSoCNek7IH3vR5nRjdsEz926ibFYX8KtLQmdyw==} esbuild@0.27.3: resolution: {integrity: sha512-8VwMnyGCONIs6cWue2IdpHxHnAjzxnw2Zr7MkVxB2vjmQ2ivqGFb4LEG3SMnv0Gb2F/G/2yA8zUaiL1gywDCCg==} engines: {node: '>=18'} hasBin: true + escalade@3.2.0: + resolution: {integrity: sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==} + engines: {node: '>=6'} + + escape-string-regexp@4.0.0: + resolution: {integrity: sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==} + engines: {node: '>=10'} + + eslint-plugin-unicorn@74.0.0: + resolution: {integrity: sha512-AGnsGi2SxHg1HEAXxn9nSnZfyjvTWkxm8E8hpd/9tD6dLjBUdcD7+D6ZN64HmmCXTSXlrwVyUqe20Uyb2CaurA==} + engines: {node: '>=22'} + peerDependencies: + eslint: '>=10.4' + + eslint-scope@9.1.2: + resolution: {integrity: sha512-xS90H51cKw0jltxmvmHy2Iai1LIqrfbw57b79w/J7MfvDfkIkFZ+kj6zC3BjtUwh150HsSSdxXZcsuv72miDFQ==} + engines: {node: ^20.19.0 || ^22.13.0 || >=24} + + eslint-visitor-keys@3.4.3: + resolution: {integrity: sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==} + engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + + eslint-visitor-keys@5.0.1: + resolution: {integrity: sha512-tD40eHxA35h0PEIZNeIjkHoDR4YjjJp34biM0mDvplBe//mB+IHCqHDGV7pxF+7MklTvighcCPPZC7ynWyjdTA==} + engines: {node: ^20.19.0 || ^22.13.0 || >=24} + + eslint@10.11.0: + resolution: {integrity: sha512-P7a6UEEqb9G95MYAtqkmsTbVXIYyzIfl6NGOIJk162PaahFxFyeGcrlXYFSiagECg4sEm8IseJdZBKR3rx6MsQ==} + engines: {node: ^20.19.0 || ^22.13.0 || >=24} + hasBin: true + peerDependencies: + jiti: '*' + peerDependenciesMeta: + jiti: + optional: true + + espree@11.2.0: + resolution: {integrity: sha512-7p3DrVEIopW1B1avAGLuCSh1jubc01H2JHc8B4qqGblmg5gI9yumBgACjWo4JlIc04ufug4xJ3SQI8HkS/Rgzw==} + engines: {node: ^20.19.0 || ^22.13.0 || >=24} + + esquery@1.7.0: + resolution: {integrity: sha512-Ap6G0WQwcU/LHsvLwON1fAQX9Zp0A2Y6Y/cJBl9r/JbW90Zyg4/zbG6zzKa2OTALELarYHmKu0GhpM5EO+7T0g==} + engines: {node: '>=0.10'} + + esrecurse@4.3.0: + resolution: {integrity: sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==} + engines: {node: '>=4.0'} + + estraverse@5.3.0: + resolution: {integrity: sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==} + engines: {node: '>=4.0'} + estree-walker@3.0.3: resolution: {integrity: sha512-7RUKfXgSMMkzt6ZuXmqapOurLGPPfgj6l9uRZ7lRGolvk0y2yocc35LdcxKC5PQZdn2DMqioAQ2NoWcrTKmm6g==} - expect-type@1.3.0: - resolution: {integrity: sha512-knvyeauYhqjOYvQ66MznSMs83wmHrCycNEN6Ao+2AeYEfxUIkuiVxdEa1qlGEPK+We3n0THiDciYSsCcgW/DoA==} + esutils@2.0.3: + resolution: {integrity: sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==} + engines: {node: '>=0.10.0'} + + expect-type@1.4.0: + resolution: {integrity: sha512-KfYbmpRm0VbLjEvVa9yGwCi9GI34xvi7A/HXYWQO65CSD2u3MczUJSuwXKFIxlGsgBQizV9q5J9NHj4VG0n+pA==} engines: {node: '>=12.0.0'} + fallow-type-aware@3.28.0: + resolution: {integrity: sha512-QazEIGu/D2aicBobtzbVt9IvK/YMzbQWBhs3rcDFfXKzWjBMiiOHmn70Fluod3N7BjE4zh5QM65mqGvBHjylAw==} + engines: {node: '>=20'} + hasBin: true + + fallow@3.28.0: + resolution: {integrity: sha512-8rUgXb+lep5zi/Ss0C/GajxKldsG5zyRm1EenQRdDDhIuMGeMeV/HKi6TyaAFezBeEt9aIob0YO5EvxvNC3emg==} + engines: {node: '>=22'} + hasBin: true + fast-deep-equal@3.1.3: resolution: {integrity: sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==} - fast-uri@3.1.0: - resolution: {integrity: sha512-iPeeDKJSWf4IEOasVVrknXpaBV0IApz/gp7S2bb7Z4Lljbl2MGJRqInZiUrQwV16cpzw/D3S5j5Julj/gT52AA==} + fast-json-stable-stringify@2.1.0: + resolution: {integrity: sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==} + + fast-levenshtein@2.0.6: + resolution: {integrity: sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==} fdir@6.5.0: resolution: {integrity: sha512-tIbYtZbucOs0BRGqPJkshJUYdL+SDH7dVM8gjy+ERp3WAUjLEFJE+02kanyHtwjWOnwrKYBiwAmM0p4kLJAnXg==} @@ -503,11 +1163,74 @@ packages: picomatch: optional: true + file-entry-cache@11.1.5: + resolution: {integrity: sha512-+PFTHITI08JIGhnNpGNI8T8inUpgZfk3GNEqfT9R2zZV2iFXg3CvqzSl/uEhs7TSGujYRELEANyDvS8Fj7+S7Q==} + + find-up-simple@1.0.1: + resolution: {integrity: sha512-afd4O7zpqHeRyg4PfDQsXmlDe2PfdHtJt6Akt8jOWaApLOZk5JXs6VMR29lz03pRe9mpykrRCYIYxaJYcfpncQ==} + engines: {node: '>=18'} + + find-up@5.0.0: + resolution: {integrity: sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==} + engines: {node: '>=10'} + + flat-cache@6.1.23: + resolution: {integrity: sha512-f++BY9pTk+983xK1FLzlLpmM0i0z+jHmx3QESGkURMXujQZz1k5wzwX6hjnQ8goaD0B+sYnDK1yZ6MTyZfUaqA==} + + flatted@3.4.4: + resolution: {integrity: sha512-5+ybhBZANEJxaH3X5evAFatUxLfEHSr7n6kYJ+1Qd0mUqr4eu9gIf6GDbWHf8RJijHrjjO8G+la14SlL2SeS1Q==} + fsevents@2.3.3: resolution: {integrity: sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==} engines: {node: ^8.16.0 || ^10.6.0 || >=11.0.0} os: [darwin] + function-timeout@1.0.2: + resolution: {integrity: sha512-939eZS4gJ3htTHAldmyyuzlrD58P03fHG49v2JfFXbV6OhvZKRC9j2yAtdHw/zrp2zXHuv05zMIy40F0ge7spA==} + engines: {node: '>=18'} + + glob-parent@6.0.2: + resolution: {integrity: sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==} + engines: {node: '>=10.13.0'} + + globals@17.12.0: + resolution: {integrity: sha512-cezEd/DTyyht9cvSSURyygXPfy04GtWO/5e6ZPvH7fCtjKz9PYOmuawphw1Ctd1f6C+5JypXfGD7ahNMXvevBA==} + engines: {node: '>=18'} + + hashery@1.5.1: + resolution: {integrity: sha512-iZyKG96/JwPz1N55vj2Ie2vXbhu440zfUfJvSwEqEbeLluk7NnapfGqa7LH0mOsnDxTF85Mx8/dyR6HfqcbmbQ==} + engines: {node: '>=20'} + + hookified@1.15.1: + resolution: {integrity: sha512-MvG/clsADq1GPM2KGo2nyfaWVyn9naPiXrqIe4jYjXNZQt238kWyOGrsyc/DmRAQ+Re6yeo6yX/yoNCG5KAEVg==} + + hookified@2.2.0: + resolution: {integrity: sha512-p/LgFzRN5FeoD3DLS6bkUapeye6E4SI6yJs6KetENd18S+FBthqYq2amJUWpt5z0EQwwHemidjY5OqJGEKm5uA==} + + identifier-regex@1.1.0: + resolution: {integrity: sha512-SLX4H/vtcYlYnL7XqnuJKHU7Z8517TgsW9nmQiGOgMCjQ8V/deLYu6bEmbGoXe7WMMhc9+EUGyFFneHja8KabA==} + engines: {node: '>=18'} + + idn-hostname@15.1.19: + resolution: {integrity: sha512-pRGRbFpQWCptOBWw9Gn5DXtPdern5/XtdkcXdoEavjd+sh72jNm2eVI1eeysp64UisXPfaqoQrnLUKpSN4hJWw==} + engines: {node: '>=20.12.0 <21 || >=22.0.0'} + + ignore@5.3.2: + resolution: {integrity: sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g==} + engines: {node: '>= 4'} + + imurmurhash@0.1.4: + resolution: {integrity: sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==} + engines: {node: '>=0.8.19'} + + indent-string@5.0.0: + resolution: {integrity: sha512-m6FAo/spmsW2Ab2fU35JTYwtOKa2yAwXSwgjSv1TJzh4Mh7mC3lzAOVLBprb72XsTrgkEIsl7YrFNAiDiRhIGg==} + engines: {node: '>=12'} + + is-builtin-module@5.0.0: + resolution: {integrity: sha512-f4RqJKBUe5rQkJ2eJEJBXSticB3hGbN9j0yxxMQFqIW89Jp9WYFtzfTcRlstDKVUTRzSOTLKRfO9vIztenwtxA==} + engines: {node: '>=18.20'} + is-extglob@2.1.1: resolution: {integrity: sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==} engines: {node: '>=0.10.0'} @@ -516,79 +1239,253 @@ packages: resolution: {integrity: sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==} engines: {node: '>=0.10.0'} - js-tokens@9.0.1: - resolution: {integrity: sha512-mxa9E9ITFOt0ban3j6L5MpjwegGz6lBQmM1IJkWeBZGcMxto50+eWdjC/52xDbS2vy0k7vIMK0Fe2wfL9OQSpQ==} + is-identifier@1.1.0: + resolution: {integrity: sha512-NhOds0mDx9lJu+1lBRO0xbwFo5nobA7GCk/0e5xjr6+6XugX985+0OyGX35BNrTkPAsdLcIKg02HUQJOK8D8kw==} + engines: {node: '>=18'} - js-yaml@4.1.1: - resolution: {integrity: sha512-qQKT4zQxXl8lLwBtHMWwaTcGfFOZviOJet3Oy/xmGk2gZH677CJM9EvtfdSkgWcATZhj/55JZ0rmy3myCT5lsA==} - hasBin: true + isexe@2.0.0: + resolution: {integrity: sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==} - json-schema-to-typescript@15.0.4: - resolution: {integrity: sha512-Su9oK8DR4xCmDsLlyvadkXzX6+GGXJpbhwoLtOGArAG61dvbW4YQmSEno2y66ahpIdmLMg6YUf/QHLgiwvkrHQ==} - engines: {node: '>=16.0.0'} + jsesc@3.1.0: + resolution: {integrity: sha512-/sM3dO2FOzXjKQhJuo0Q173wf2KOo8t4I8vHy6lF9poUp7bKT0/NHE8fPX23PwfhnykfqnC2xRxOnVw5XuGIaA==} + engines: {node: '>=6'} hasBin: true - json-schema-traverse@1.0.0: - resolution: {integrity: sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==} + json-schema-traverse@0.4.1: + resolution: {integrity: sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==} + + json-stable-stringify-without-jsonify@1.0.1: + resolution: {integrity: sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==} - lodash@4.17.23: - resolution: {integrity: sha512-LgVTMpQtIopCi79SJeDiP0TfWi5CNEc/L/aRdTh3yIvmZXTnheWpKjSZhnvMl8iXbC1tFg9gdHHDMLoV7CnG+w==} + json-stringify-deterministic@1.0.16: + resolution: {integrity: sha512-barjhF/wL0ot1i7AVA3gDDfuBIS1Iz7dlYmO6fZnVDUXtB/EJKjqREA/FUndo+kCGYLI67jH3hXKQMwuTFhbpQ==} + engines: {node: '>= 4'} - loupe@3.2.1: - resolution: {integrity: sha512-CdzqowRJCeLU72bHvWqwRBBlLcMEtIvGrlvef74kMnV2AolS9Y8xUv1I0U/MNAWMhBlKIoyuEgoJ0t/bbwHbLQ==} + just-curry-it@5.3.0: + resolution: {integrity: sha512-silMIRiFjUWlfaDhkgSzpuAyQ6EX/o09Eu8ZBfmFwQMbax7+LQzeIU2CBrICT6Ne4l86ITCGvUCBpCubWYy0Yw==} - magic-string@0.30.21: - resolution: {integrity: sha512-vd2F4YUyEXKGcLHoq+TEyCjxueSeHnFxyyjNp80yg0XV4vUhnDer/lvvlqM/arB5bXQN5K2/3oinyCRyx8T2CQ==} + keyv@5.6.0: + resolution: {integrity: sha512-CYDD3SOtsHtyXeEORYRx2qBtpDJFjRTGXUtmNEMGyzYOKj1TE3tycdlho7kA1Ufx9OYWZzg52QFBGALTirzDSw==} - minimist@1.2.8: - resolution: {integrity: sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==} + levn@0.4.1: + resolution: {integrity: sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==} + engines: {node: '>= 0.8.0'} + + lightningcss-android-arm64@1.33.0: + resolution: {integrity: sha512-gEpRTalKdosp4Bb8qWtc2iOgE5SeIHlpS1up9bFq2wAyYhl1UdTObYiHe98zEM9SQvSoqQZ1IQD0JNpg3Ml5pg==} + engines: {node: '>= 12.0.0'} + cpu: [arm64] + os: [android] + + lightningcss-darwin-arm64@1.33.0: + resolution: {integrity: sha512-Sciaz8eenNTKn9b3t7+xr0ipTp9YxKQY4npwQ3mrRuL0BAVHBLyZxofhaKBAVtzmtRZ/zTyo0/to4B1uWG/Djg==} + engines: {node: '>= 12.0.0'} + cpu: [arm64] + os: [darwin] + + lightningcss-darwin-x64@1.33.0: + resolution: {integrity: sha512-Z5UPAxzrjlWNNyGy6i65cJzzvgJ5D3T6wMvs+gWpY9d7qRhANrxqAp6LhxIgZhWEw18RfJTGcRxjuLIBr+m8XQ==} + engines: {node: '>= 12.0.0'} + cpu: [x64] + os: [darwin] + + lightningcss-freebsd-x64@1.33.0: + resolution: {integrity: sha512-QQM/Ti/hQajJwCY+RiWuCZ9sdtI/XQk7nDK5vC8kkdwixezOlDgvDx7+RT+QjK6FcFT4MpsuoBnHIo/O3StRRg==} + engines: {node: '>= 12.0.0'} + cpu: [x64] + os: [freebsd] + + lightningcss-linux-arm-gnueabihf@1.33.0: + resolution: {integrity: sha512-N7FVBe6iS24MlM6R/4RBTxGhQheZGs7tiQ9U32UtF75NzP5Q7xWPRqLBCKxlRQRk3rY1jCIPLzx7WzOhuUIRLQ==} + engines: {node: '>= 12.0.0'} + cpu: [arm] + os: [linux] + + lightningcss-linux-arm64-gnu@1.33.0: + resolution: {integrity: sha512-j2v/itmy4HlNxlc6voKXYgBqNi0Ng2LShg4z7GufpEgs05P+2suBVyi9I6YHq5uoVFx9ETin3eCEhLVyXGQnKg==} + engines: {node: '>= 12.0.0'} + cpu: [arm64] + os: [linux] + libc: [glibc] + + lightningcss-linux-arm64-musl@1.33.0: + resolution: {integrity: sha512-yiO5ROMuYQgXbC60yjZU5CYSFZGKXL0HFATXt9mHJn1+zW55oCtMI9NfcVhYLMFDL7gV7oBPon/EmMMGg2OvtQ==} + engines: {node: '>= 12.0.0'} + cpu: [arm64] + os: [linux] + libc: [musl] + + lightningcss-linux-x64-gnu@1.33.0: + resolution: {integrity: sha512-ar+Ju7LmcN0Jo4FpL4hpFybwNG9/3A/Br5KW2n2jyODg3MEZXaDYADdemoNS+BDNfMgKvylJLj4S5tyRActuAg==} + engines: {node: '>= 12.0.0'} + cpu: [x64] + os: [linux] + libc: [glibc] + + lightningcss-linux-x64-musl@1.33.0: + resolution: {integrity: sha512-RYiYbkokw0trfKqqzfF55lginwEPrD3OJDfTuJzFs1MK6iFnDenaz1fqLLtX4ITG3OktJQXOeTaw1awrBAlZPw==} + engines: {node: '>= 12.0.0'} + cpu: [x64] + os: [linux] + libc: [musl] + + lightningcss-win32-arm64-msvc@1.33.0: + resolution: {integrity: sha512-1K+MPfLSFVpphzpdbfkhlWk6wBrTObBzS2T6db10PNOZgR9GoVsAWzwNyuhUYYbTp23j+4RrncfujZ4uAzXvwA==} + engines: {node: '>= 12.0.0'} + cpu: [arm64] + os: [win32] + + lightningcss-win32-x64-msvc@1.33.0: + resolution: {integrity: sha512-OlEICDx/Xl0FqSp4bry8zFnCvGpig3Gl4gCquvYwHuqJKEC1+n9NgDniFvqHGmMv1ZkqDJrDqKKSykTDX+ehuA==} + engines: {node: '>= 12.0.0'} + cpu: [x64] + os: [win32] + + lightningcss@1.33.0: + resolution: {integrity: sha512-WkUDrojuJs0xkgGf2udWxa3yGBRxPtxUkB79i6aCZLRgc7PM8fZe9TosfPDcvEpQZbuFASnHYmRLBLUbmLOIIA==} + engines: {node: '>= 12.0.0'} + + locate-path@6.0.0: + resolution: {integrity: sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==} + engines: {node: '>=10'} + + magic-string@1.4.1: + resolution: {integrity: sha512-8lyCu36ErXR0J9uaGKlKQoiLZKmtI63YGLE8G2o9jyRPdr4X47LusSOwgOJOzcVtp81fTAAjxR7BwKz682Jhow==} + + make-asynchronous@1.1.0: + resolution: {integrity: sha512-ayF7iT+44LXdxJLTrTd3TLQpFDDvPCBxXxbv+pMUSuHA5Q8zyAfwkRP6aHHwNVFBUFWtxAHqwNJxF8vMZLAbVg==} + engines: {node: '>=18'} + + mdn-data@2.27.1: + resolution: {integrity: sha512-9Yubnt3e8A0OKwxYSXyhLymGW4sCufcLG6VdiDdUGVkPhpqLxlvP5vl1983gQjJl3tqbrM731mjaZaP68AgosQ==} + + mdn-data@2.35.0: + resolution: {integrity: sha512-k+1+dEIm2z/BEfdvYzT/fIyAGeDBo/1AJNJI4ilFXJRYoxP/3Ds+GP8shAOIq8jYXY9N5nGB3Ag104NsagmLAA==} + + minimatch@10.2.6: + resolution: {integrity: sha512-vpLQEs+VLCr1nU0BXS07maYoFwlDAH0gngQuuttxIwutDFEMHq2blX+8vpgxDdK3J1PwjCJiep77OitTZ4Ll1A==} + engines: {node: 18 || 20 || >=22} ms@2.1.3: resolution: {integrity: sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==} - nanoid@3.3.11: - resolution: {integrity: sha512-N8SpfPUnUp1bK+PMYW8qSWdl9U+wwNWI4QKxOYDy9JAro3WMX7p2OeVRF9v+347pnakNevPmiHhNmZ2HbFA76w==} + nanoid@3.3.19: + resolution: {integrity: sha512-Y2tUNy4ouw6tq5oDSKeQYGOyhkUBhNOcGV/02KC+6kd9eDGqdZd++mjMiIDilrBYvjEnCYvVtsuHCuP+okSfug==} engines: {node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1} hasBin: true - openapi-types@12.1.3: - resolution: {integrity: sha512-N4YtSYJqghVu4iek2ZUvcN/0aqH1kRDuNqzcycDxhOUpg7GdvLa2F3DgS6yBNhInhv2r/6I0Flkn7CqL8+nIcw==} + natural-compare@1.4.0: + resolution: {integrity: sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==} + + node-releases@2.0.56: + resolution: {integrity: sha512-x0InOIyzgdk+eyaWaRJFH5snEtiImgBgblZ2CyPrLmqqcuMQkEvcDPHbzqbD8eDsSeJbVOjn+crzyzHaM4D+/A==} + engines: {node: '>=18'} + + obug@2.2.1: + resolution: {integrity: sha512-XrsrhT5sybtKI6wakr2SPOlGZWWYbUXZ7a0jT8/QOeAPau+1X/bSegNe5YR75oJmEZQbKningirmGOEJCIk61Q==} + engines: {node: '>=12.20.0'} + + openapi3-ts@4.6.1: + resolution: {integrity: sha512-XW9MOldkhoICNeXVzzmXzmOW5G73ppOEGmh7fLCqHjgfdEYCGGN+00MlVCeUZgovjjfC56j9tvtDt1zGabNjjA==} + + optionator@0.9.4: + resolution: {integrity: sha512-6IpQ7mKUxRcZNLIObR0hz7lxsapSSIYNZJwXPGeF0mTVqGKFIXj1DQcMoT22S3ROcLyY/rz0PWaWZ9ayWmad9g==} + engines: {node: '>= 0.8.0'} + + oxfmt@0.70.0: + resolution: {integrity: sha512-IsHxZ4y0wQLLMhnrJblBJgZsLDzfULrJnAw5j/QqsTlMa/m3AqsbToi+W71uhBGaqlqq/PbbjvHc09TJwdv3Tw==} + engines: {node: ^20.19.0 || >=22.12.0} + hasBin: true + peerDependencies: + svelte: ^5.0.0 + vite-plus: '*' + peerDependenciesMeta: + svelte: + optional: true + vite-plus: + optional: true + + p-event@6.0.1: + resolution: {integrity: sha512-Q6Bekk5wpzW5qIyUP4gdMEujObYstZl6DMMOSenwBvV0BlE5LkDwkjs5yHbZmdCEq2o4RJx4tE1vwxFVf2FG1w==} + engines: {node: '>=16.17'} - openapi3-ts@4.5.0: - resolution: {integrity: sha512-jaL+HgTq2Gj5jRcfdutgRGLosCy/hT8sQf6VOy+P+g36cZOjI1iukdPnijC+4CmeRzg/jEllJUboEic2FhxhtQ==} + p-limit@3.1.0: + resolution: {integrity: sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==} + engines: {node: '>=10'} - pathe@2.0.3: - resolution: {integrity: sha512-WUjGcAqP1gQacoQe+OBJsFA7Ld4DyXuUIjZ5cc75cLHvJ7dtNsTugphxIADwspS+AraAUePCKrSVtPLFj/F88w==} + p-locate@5.0.0: + resolution: {integrity: sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==} + engines: {node: '>=10'} - pathval@2.0.1: - resolution: {integrity: sha512-//nshmD55c46FuFw26xV/xFAaB5HF9Xdap7HJBBnrKdAd6/GxDBaNA1870O79+9ueg61cZLSVc+OaFlfmObYVQ==} - engines: {node: '>= 14.16'} + p-timeout@6.1.4: + resolution: {integrity: sha512-MyIV3ZA/PmyBN/ud8vV9XzwTrNtR4jFrObymZYnZqMmW0zA8Z17vnT0rBgFE/TlohB+YCHqXMgZzb3Csp49vqg==} + engines: {node: '>=14.16'} + + path-exists@4.0.0: + resolution: {integrity: sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==} + engines: {node: '>=8'} + + path-key@3.1.1: + resolution: {integrity: sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==} + engines: {node: '>=8'} picocolors@1.1.1: resolution: {integrity: sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==} - picomatch@4.0.3: - resolution: {integrity: sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==} + picomatch@4.0.7: + resolution: {integrity: sha512-qcJu88Q2IWqJsDD529JKMdwGm/dvInW4HvQnRwiH9JtihJvzGOscDtHE3x1pBKeUOTysQ8kVmLnJ2kJu7yhcGA==} engines: {node: '>=12'} - postcss@8.5.8: - resolution: {integrity: sha512-OW/rX8O/jXnm82Ey1k44pObPtdblfiuWnrd8X7GJ7emImCOstunGbXUpp7HdBrFQX6rJzn3sPT397Wp5aCwCHg==} + pluralize@8.0.0: + resolution: {integrity: sha512-Nc3IT5yHzflTfbjgqWcCPpo7DaKy4FnpB0l/zCAW0Tc7jxAiuqSxHasntB3D7887LSrA93kDJ9IXovxJYxyLCA==} + engines: {node: '>=4'} + + postcss@8.5.28: + resolution: {integrity: sha512-RRuzqDtt5Y9h3quz5hWhK+TPnsmVs6WwSU6LkJMeY4HstUEDuYTG8UJSdawMRzmzAtV+KEoG8N3Qg2qLy5vM/A==} engines: {node: ^10 || ^12 || >=14} - prettier@3.8.1: - resolution: {integrity: sha512-UOnG6LftzbdaHZcKoPFtOcCKztrQ57WkHDeRD9t/PTQtmT0NHSeWWepj6pS0z/N7+08BHFDQVUrfmfMRcZwbMg==} - engines: {node: '>=14'} + prelude-ls@1.2.1: + resolution: {integrity: sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==} + engines: {node: '>= 0.8.0'} + + punycode@2.3.1: + resolution: {integrity: sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==} + engines: {node: '>=6'} + + qified@0.10.1: + resolution: {integrity: sha512-+Owyggi9IxT1ePKGafcI87ubSmxol6smwJ+RAHDQlx9+9cPwFWDiKFFCPuWhr9ignlGpZ9vDQLw67N4dcTVFEA==} + engines: {node: '>=20'} + + quote-js-string@0.1.0: + resolution: {integrity: sha512-Y3NoRtprEEZQD8RfxMCfS0ZTqc4e+i18OrXEXAvpM6TfC/3y+0L5rNbZiSnbBBEkDfFzbpd8o+cE8q3/anjMGA==} + engines: {node: '>=22'} + + regjsparser@0.13.3: + resolution: {integrity: sha512-ycwFAS14Jw4mppvmK4GR/J6u3WpWpjkEApehuHtLc/8VpPNpDMbQ4WjqwplXifGeyKOzHSFLmSPqzksDQE2Sfg==} hasBin: true - require-from-string@2.0.2: - resolution: {integrity: sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==} - engines: {node: '>=0.10.0'} + reserved-identifiers@1.2.0: + resolution: {integrity: sha512-yE7KUfFvaBFzGPs5H3Ops1RevfUEsDc5Iz65rOwWg4lE8HJSYtle77uul3+573457oHvBKuHYDl/xqUkKpEEdw==} + engines: {node: '>=18'} - rollup@4.59.0: - resolution: {integrity: sha512-2oMpl67a3zCH9H79LeMcbDhXW/UmWG/y2zuqnF2jQq5uq9TbM9TVyXvA4+t+ne2IIkBdrLpAaRQAvo7YI/Yyeg==} - engines: {node: '>=18.0.0', npm: '>=8.0.0'} + rolldown@1.2.9: + resolution: {integrity: sha512-hx/Pv0N1haXRb11qkfnK5MXB/iqr7i0yjWQqmO9uHqZpBgQSqzc8UsSnEpalsh+j1I8qQ2CkXAkJC8Br3dKSlg==} + engines: {node: ^20.19.0 || >=22.12.0} + hasBin: true + + semver@7.8.5: + resolution: {integrity: sha512-Y7/KDsb8LjooZpwaqGyulO6DQlksgCncchHGk+sZIY4SBvUocMBEFH5Ur1fI4dV+Jvl0w6cjvucaIi40puRioA==} + engines: {node: '>=10'} hasBin: true + shebang-command@2.0.0: + resolution: {integrity: sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==} + engines: {node: '>=8'} + + shebang-regex@3.0.0: + resolution: {integrity: sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==} + engines: {node: '>=8'} + siginfo@2.0.0: resolution: {integrity: sha512-ybx0WO1/8bSBLEWXZvEd7gMW3Sn3JFlW3TvX1nREbDLRNQNaeNN8WK0meBwPdAaOI7TtRRRJn/Es1zhrrCHu7g==} @@ -599,64 +1496,76 @@ packages: stackback@0.0.2: resolution: {integrity: sha512-1XMJE5fQo1jGH6Y/7ebnwPOBEkIEnT4QF32d5R1+VXdXveM0IBMJt8zfaxX1P3QhVwrYe+576+jkANtSS2mBbw==} - std-env@3.10.0: - resolution: {integrity: sha512-5GS12FdOZNliM5mAOxFRg7Ir0pWz8MdpYm6AY6VPkGpbA7ZzmbzNcBJQ0GPvvyWgcY7QAhCgf9Uy89I03faLkg==} + std-env@4.2.0: + resolution: {integrity: sha512-oCUKSupKTHX53EyjDtuZQ64pjLJ6yYCtpmEw0goYxtjG9KpbRe8KAsl2tBUGU9DyMcJ0RwJ8GqJAFzMXcXW1Rw==} - strip-literal@3.1.0: - resolution: {integrity: sha512-8r3mkIM/2+PpjHoOtiAW8Rg3jJLHaV7xPwG+YRGrv6FP0wwk/toTpATxWYOW0BKdWwl82VT2tFYi5DlROa0Mxg==} + strip-indent@4.1.1: + resolution: {integrity: sha512-SlyRoSkdh1dYP0PzclLE7r0M9sgbFKKMFXpFRUMNuKhQSbC6VQIGzq3E0qsfvGJaUFJPGv6Ws1NZ/haTAjfbMA==} + engines: {node: '>=12'} - tagged-tag@1.0.0: - resolution: {integrity: sha512-yEFYrVhod+hdNyx7g5Bnkkb0G6si8HJurOoOEgC8B/O0uXLHlaey/65KRv6cuWBNhBgHKAROVpc7QyYqE5gFng==} - engines: {node: '>=20'} + super-regex@1.1.0: + resolution: {integrity: sha512-WHkws2ZflZe41zj6AolvvmaTrWds/VuyeYr9iPVv/oQeaIoVxMKaushfFWpOGDT+GuBrM/sVqF8KUCYQlSSTdQ==} + engines: {node: '>=18'} - tinybench@2.9.0: - resolution: {integrity: sha512-0+DUvqWMValLmha6lr4kD8iAMK1HzV0/aKnCtWb9v9641TnP/MFb7Pc2bxoxQjTXAErryXVgUOfv2YqNllqGeg==} + time-span@5.1.0: + resolution: {integrity: sha512-75voc/9G4rDIJleOo4jPvN4/YC4GRZrY8yy1uU4lwrB3XEQbWve8zXoO5No4eFrGcTAMYyoY67p8jRQdtA1HbA==} + engines: {node: '>=12'} - tinyexec@0.3.2: - resolution: {integrity: sha512-KQQR9yN7R5+OSwaK0XQoj22pwHoTlgYqmUscPYoknOoWCWfj/5/ABTMRi69FrKU5ffPVh5QcFikpWJI/P1ocHA==} + tinybench@6.1.4: + resolution: {integrity: sha512-9APumHG7r4yOk4X4WlkmE71aZcv1gvin1czO3OQ1U9iJcFA5Ja/ygyb0vPOVHTthFozUYs8CLoLUlM8grb2lTQ==} + engines: {node: '>=20.0.0'} - tinyglobby@0.2.15: - resolution: {integrity: sha512-j2Zq4NyQYG5XMST4cbs02Ak8iJUdxRM0XI5QyxXuZOzKOINmWurp3smXu3y5wDcJrptwpSjgXHzIQxR0omXljQ==} + tinyexec@1.3.0: + resolution: {integrity: sha512-QKAl9m8gWWGHV8jZcPeym6j+XULi6tOf1mT83WYJ4Lk2ytW/uwAWkrP0uFsdoYMdueVJ0qs26wZ+23xeB4ibNQ==} + engines: {node: '>=18'} + + tinyglobby@0.2.17: + resolution: {integrity: sha512-wXR/dYpcqKmfWpEdZjiKJOwCNFndD0DMnrW/cYjVGttEkBfVgcLFHoNrlj47mjOVic9yyNu65alsgF4NQyTa2g==} engines: {node: '>=12.0.0'} - tinypool@1.1.1: - resolution: {integrity: sha512-Zba82s87IFq9A9XmjiX5uZA/ARWDrB03OHlq+Vw1fSdt0I+4/Kutwy8BP4Y/y/aORMo61FQ0vIb5j44vSo5Pkg==} - engines: {node: ^18.0.0 || >=20.0.0} + tinypool@2.1.2: + resolution: {integrity: sha512-9YodfrxS9g9IbFr/KOjE5bAeJ0p61n3bW6mqvy0jtoeKd1kTW1Cxm0oulm6KX2lyM9Gl6WIe8nEbY7LWv5ZJww==} + engines: {node: ^20.0.0 || >=22.0.0} - tinyrainbow@2.0.0: - resolution: {integrity: sha512-op4nsTR47R6p0vMUUoYl/a+ljLFVtlfaXkLQmqfLR1qHma1h/ysYk4hEXZ880bf2CYgTskvTa/e196Vd5dDQXw==} - engines: {node: '>=14.0.0'} + type-check@0.4.0: + resolution: {integrity: sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==} + engines: {node: '>= 0.8.0'} - tinyspy@4.0.4: - resolution: {integrity: sha512-azl+t0z7pw/z958Gy9svOTuzqIk6xq+NSheJzn5MMWtWTFywIacg2wUlzKFGtt3cthx0r2SxMK0yzJOR0IES7Q==} - engines: {node: '>=14.0.0'} + type-fest@4.41.0: + resolution: {integrity: sha512-TeTSQ6H5YHvpqVwBRcnLDCBnDOHWYu7IvGbHT6N8AOymcr9PJGjc1GTtiWZTYg0NCgYwvnYWEkVChQAr9bjfwA==} + engines: {node: '>=16'} - type-fest@5.4.4: - resolution: {integrity: sha512-JnTrzGu+zPV3aXIUhnyWJj4z/wigMsdYajGLIYakqyOW1nPllzXEJee0QQbHj+CTIQtXGlAjuK0UY+2xTyjVAw==} - engines: {node: '>=20'} + typescript@7.0.2: + resolution: {integrity: sha512-8FYau96o3NKOhbjKi/qNvG/W5jhzxkbdm5sj9AbZ/5T5sWqn3hJgLfGx27sRKZWTvyzCP8dLRBTf5tBTSRVUNA==} + engines: {node: '>=16.20.0'} + hasBin: true - typescript@5.9.3: - resolution: {integrity: sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw==} - engines: {node: '>=14.17'} + undici-types@8.9.0: + resolution: {integrity: sha512-KTDyRTYX8sWmKXAikPHHSyc63CRPETMctyjKFupcC6OBLXT3xsN0e9aF7m+mIXutFWpUXuedtowG7iLOzp0kQg==} + + update-browserslist-db@1.3.3: + resolution: {integrity: sha512-pJ2sYawQS0R/WI928Gj5GlPhTGzbMelq0+4INtSYNDV9ErKJcX6xjGWkoG/VnB3dpUm00zALaqkrUD77pO5TDQ==} hasBin: true + peerDependencies: + browserslist: '>= 4.21.0' - undici-types@7.16.0: - resolution: {integrity: sha512-Zz+aZWSj8LE6zoxD+xrjh4VfkIG8Ya6LvYkZqtUQGJPZjYl53ypCaUwWqo7eI0x66KBGeRo+mlBEkMSeSZ38Nw==} + uri-js@4.4.1: + resolution: {integrity: sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==} - vite-node@3.2.4: - resolution: {integrity: sha512-EbKSKh+bh1E1IFxeO0pg1n4dvoOTt0UDiXMd/qn++r98+jPO1xtJilvXldeuQ8giIB5IkpjCgMleHMNEsGH6pg==} - engines: {node: ^18.0.0 || ^20.0.0 || >=22.0.0} + uuid@14.0.2: + resolution: {integrity: sha512-xZe/16rV4aa+HGSOCiY2YeLT1OybRLrrkL/Rqaq7p7GMVXjFh+6wN4oMYgjFmnSnhY8t6Xpdl2l9qmnHYuMHwQ==} hasBin: true - vite@7.3.1: - resolution: {integrity: sha512-w+N7Hifpc3gRjZ63vYBXA56dvvRlNWRczTdmCBBa+CotUzAPf5b7YMdMR/8CQoeYE5LX3W4wj6RYTgonm1b9DA==} + vite@8.3.0: + resolution: {integrity: sha512-lhZBVvEHefgE+HQZC9O7EBJgCU/nVzFNl7vkS4RE0APtWLP02/8QVIkQtzBxPquh7lq5/78NHipTj7ODQ6XuyQ==} engines: {node: ^20.19.0 || >=22.12.0} hasBin: true peerDependencies: '@types/node': ^20.19.0 || >=22.12.0 + '@vitejs/devtools': ^0.7.1 + esbuild: ^0.27.0 || ^0.28.0 jiti: '>=1.21.0' less: ^4.0.0 - lightningcss: ^1.21.0 sass: ^1.70.0 sass-embedded: ^1.70.0 stylus: '>=0.54.8' @@ -667,12 +1576,14 @@ packages: peerDependenciesMeta: '@types/node': optional: true + '@vitejs/devtools': + optional: true + esbuild: + optional: true jiti: optional: true less: optional: true - lightningcss: - optional: true sass: optional: true sass-embedded: @@ -688,26 +1599,39 @@ packages: yaml: optional: true - vitest@3.2.4: - resolution: {integrity: sha512-LUCP5ev3GURDysTWiP47wRRUpLKMOfPh+yKTx3kVIEiu5KOMeqzpnYNsKyOoVrULivR8tLcks4+lga33Whn90A==} - engines: {node: ^18.0.0 || ^20.0.0 || >=22.0.0} + vitest@5.0.1: + resolution: {integrity: sha512-iA95lQbKEkvrtTkdAgnWbXfbipWiiWe/hDl2P5tMi6WFwD76G0NxXAGp/M9EOcYupeGJRr6wppMc7CoA41TQjg==} + engines: {node: ^22.12.0 || ^24.0.0 || >=26.0.0} hasBin: true peerDependencies: '@edge-runtime/vm': '*' - '@types/debug': ^4.1.12 - '@types/node': ^18.0.0 || ^20.0.0 || >=22.0.0 - '@vitest/browser': 3.2.4 - '@vitest/ui': 3.2.4 + '@opentelemetry/api': ^1.9.0 + '@types/node': ^22.0.0 || >=24.0.0 + '@vitest/browser-playwright': 5.0.1 + '@vitest/browser-preview': 5.0.1 + '@vitest/browser-webdriverio': ^5.0.0-beta.5 || >=5.0.0 + '@vitest/coverage-istanbul': 5.0.1 + '@vitest/coverage-v8': 5.0.1 + '@vitest/ui': 5.0.1 happy-dom: '*' jsdom: '*' + vite: ^6.4.0 || ^7.0.0 || ^8.0.0 peerDependenciesMeta: '@edge-runtime/vm': optional: true - '@types/debug': + '@opentelemetry/api': optional: true '@types/node': optional: true - '@vitest/browser': + '@vitest/browser-playwright': + optional: true + '@vitest/browser-preview': + optional: true + '@vitest/browser-webdriverio': + optional: true + '@vitest/coverage-istanbul': + optional: true + '@vitest/coverage-v8': optional: true '@vitest/ui': optional: true @@ -716,301 +1640,576 @@ packages: jsdom: optional: true + web-worker@1.5.0: + resolution: {integrity: sha512-RiMReJrTAiA+mBjGONMnjVDP2u3p9R1vkcGz6gDIrOMT3oGuYwX2WRMYI9ipkphSuE5XKEhydbhNEJh4NY9mlw==} + + which@2.0.2: + resolution: {integrity: sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==} + engines: {node: '>= 8'} + hasBin: true + why-is-node-running@2.3.0: resolution: {integrity: sha512-hUrmaWBdVDcxvYqnyh09zunKzROWjbZTiNy8dBEjkS7ehEDQibXJ7XvlmtbwuTclUiIyN+CyXQD4Vmko8fNm8w==} engines: {node: '>=8'} hasBin: true + word-wrap@1.2.5: + resolution: {integrity: sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA==} + engines: {node: '>=0.10.0'} + yaml@2.8.2: resolution: {integrity: sha512-mplynKqc1C2hTVYxd0PU2xQAc22TI1vShAYGksCCfxbn/dFwnHTNi1bvYsBTkhdUNtGIf5xNOg938rrSSYvS9A==} engines: {node: '>= 14.6'} hasBin: true + yaml@2.9.1: + resolution: {integrity: sha512-3NxN8+78OdzbT7C/WjGsyfPAtJaN3FNDsWxv7Y7mcDsT/oOmgW8BpyQQFFBnvZE3j9Y2Sdz1ULFLezL7Eb2yFw==} + engines: {node: '>= 14.6'} + hasBin: true + + yocto-queue@0.1.0: + resolution: {integrity: sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==} + engines: {node: '>=10'} + snapshots: - '@apidevtools/json-schema-ref-parser@11.9.3': + '@block65/oxlint-binding-linux-arm64-gnu@1.83.0': + optional: true + + '@block65/oxlint-binding-linux-x64-gnu@1.83.0': + optional: true + + '@block65/oxlint-plugin@0.11.0(@block65/oxlint@1.83.0(@block65/oxlint-tsgolint@7.0.200200))(eslint@10.11.0)': dependencies: - '@jsdevtools/ono': 7.1.3 - '@types/json-schema': 7.0.15 - js-yaml: 4.1.1 + css-tree: 3.2.1 + eslint-plugin-unicorn: 74.0.0(eslint@10.11.0) + oxlint: '@block65/oxlint@1.83.0(@block65/oxlint-tsgolint@7.0.200200)' + transitivePeerDependencies: + - eslint + + '@block65/oxlint-tsgolint-linux-arm64@7.0.200200': + optional: true + + '@block65/oxlint-tsgolint-linux-x64@7.0.200200': + optional: true + + '@block65/oxlint-tsgolint@7.0.200200': + optionalDependencies: + '@block65/oxlint-tsgolint-linux-arm64': 7.0.200200 + '@block65/oxlint-tsgolint-linux-x64': 7.0.200200 + + '@block65/oxlint@1.83.0(@block65/oxlint-tsgolint@7.0.200200)': + optionalDependencies: + '@block65/oxlint-binding-linux-arm64-gnu': 1.83.0 + '@block65/oxlint-binding-linux-x64-gnu': 1.83.0 + oxlint-tsgolint: '@block65/oxlint-tsgolint@7.0.200200' + + '@block65/shared-config@0.5.0(@block65/oxlint-tsgolint@7.0.200200)(@block65/oxlint@1.83.0(@block65/oxlint-tsgolint@7.0.200200))(eslint@10.11.0)(fallow@3.28.0)(oxfmt@0.70.0)': + dependencies: + '@block65/oxlint-plugin': 0.11.0(@block65/oxlint@1.83.0(@block65/oxlint-tsgolint@7.0.200200))(eslint@10.11.0) + optionalDependencies: + fallow: 3.28.0 + oxfmt: 0.70.0 + oxlint: '@block65/oxlint@1.83.0(@block65/oxlint-tsgolint@7.0.200200)' + oxlint-tsgolint: '@block65/oxlint-tsgolint@7.0.200200' + transitivePeerDependencies: + - eslint + + '@block65/tsconfig@0.3.1': {} + + '@cacheable/memory@2.2.0': + dependencies: + '@cacheable/utils': 2.5.0 + '@keyv/bigmap': 1.3.1(keyv@5.6.0) + hookified: 1.15.1 + keyv: 5.6.0 + + '@cacheable/utils@2.5.0': + dependencies: + hashery: 1.5.1 + keyv: 5.6.0 + + '@esbuild/aix-ppc64@0.27.3': + optional: true + + '@esbuild/android-arm64@0.27.3': + optional: true + + '@esbuild/android-arm@0.27.3': + optional: true + + '@esbuild/android-x64@0.27.3': + optional: true + + '@esbuild/darwin-arm64@0.27.3': + optional: true + + '@esbuild/darwin-x64@0.27.3': + optional: true + + '@esbuild/freebsd-arm64@0.27.3': + optional: true + + '@esbuild/freebsd-x64@0.27.3': + optional: true + + '@esbuild/linux-arm64@0.27.3': + optional: true + + '@esbuild/linux-arm@0.27.3': + optional: true + + '@esbuild/linux-ia32@0.27.3': + optional: true + + '@esbuild/linux-loong64@0.27.3': + optional: true + + '@esbuild/linux-mips64el@0.27.3': + optional: true + + '@esbuild/linux-ppc64@0.27.3': + optional: true + + '@esbuild/linux-riscv64@0.27.3': + optional: true + + '@esbuild/linux-s390x@0.27.3': + optional: true + + '@esbuild/linux-x64@0.27.3': + optional: true + + '@esbuild/netbsd-arm64@0.27.3': + optional: true + + '@esbuild/netbsd-x64@0.27.3': + optional: true + + '@esbuild/openbsd-arm64@0.27.3': + optional: true + + '@esbuild/openbsd-x64@0.27.3': + optional: true + + '@esbuild/openharmony-arm64@0.27.3': + optional: true + + '@esbuild/sunos-x64@0.27.3': + optional: true + + '@esbuild/win32-arm64@0.27.3': + optional: true + + '@esbuild/win32-ia32@0.27.3': + optional: true + + '@esbuild/win32-x64@0.27.3': + optional: true + + '@eslint-community/eslint-utils@4.10.1(eslint@10.11.0)': + dependencies: + eslint: 10.11.0 + eslint-visitor-keys: 3.4.3 + + '@eslint-community/regexpp@4.12.2': {} + + '@eslint/config-array@0.23.5': + dependencies: + '@eslint/object-schema': 3.0.5 + debug: 4.4.3 + minimatch: 10.2.6 + transitivePeerDependencies: + - supports-color + + '@eslint/config-helpers@0.7.0': + dependencies: + '@eslint/core': 1.2.1 - '@apidevtools/json-schema-ref-parser@14.0.1': + '@eslint/core@1.2.1': dependencies: '@types/json-schema': 7.0.15 - js-yaml: 4.1.1 - '@apidevtools/openapi-schemas@2.1.0': {} + '@eslint/css-tree@4.1.1': + dependencies: + mdn-data: 2.35.0 + source-map-js: 1.2.1 - '@apidevtools/swagger-methods@3.0.2': {} + '@eslint/object-schema@3.0.5': {} - '@apidevtools/swagger-parser@12.1.0(openapi-types@12.1.3)': + '@eslint/plugin-kit@0.7.3': dependencies: - '@apidevtools/json-schema-ref-parser': 14.0.1 - '@apidevtools/openapi-schemas': 2.1.0 - '@apidevtools/swagger-methods': 3.0.2 - ajv: 8.18.0 - ajv-draft-04: 1.0.0(ajv@8.18.0) - call-me-maybe: 1.0.2 - openapi-types: 12.1.3 + '@eslint/core': 1.2.1 + levn: 0.4.1 - '@esbuild/aix-ppc64@0.27.3': + '@fallow-cli/darwin-arm64@3.28.0': optional: true - '@esbuild/android-arm64@0.27.3': + '@fallow-cli/darwin-x64@3.28.0': optional: true - '@esbuild/android-arm@0.27.3': + '@fallow-cli/linux-arm64-gnu@3.28.0': optional: true - '@esbuild/android-x64@0.27.3': + '@fallow-cli/linux-arm64-musl@3.28.0': optional: true - '@esbuild/darwin-arm64@0.27.3': + '@fallow-cli/linux-x64-gnu@3.28.0': optional: true - '@esbuild/darwin-x64@0.27.3': + '@fallow-cli/linux-x64-musl@3.28.0': optional: true - '@esbuild/freebsd-arm64@0.27.3': + '@fallow-cli/win32-arm64-msvc@3.28.0': optional: true - '@esbuild/freebsd-x64@0.27.3': + '@fallow-cli/win32-x64-msvc@3.28.0': optional: true - '@esbuild/linux-arm64@0.27.3': + '@humanfs/core@0.19.2': + dependencies: + '@humanfs/types': 0.15.0 + + '@humanfs/node@0.16.8': + dependencies: + '@humanfs/core': 0.19.2 + '@humanfs/types': 0.15.0 + '@humanwhocodes/retry': 0.4.3 + + '@humanfs/types@0.15.0': {} + + '@humanwhocodes/module-importer@1.0.1': {} + + '@humanwhocodes/retry@0.4.3': {} + + '@hyperjump/browser@1.5.0': + dependencies: + '@hyperjump/json-pointer': 1.1.2 + '@hyperjump/uri': 1.3.6 + content-type: 1.0.5 + just-curry-it: 5.3.0 + + '@hyperjump/json-pointer@1.1.2': {} + + '@hyperjump/json-schema-formats@1.0.7': + dependencies: + '@hyperjump/uri': 1.3.6 + idn-hostname: 15.1.19 + + '@hyperjump/json-schema@1.17.8(@hyperjump/browser@1.5.0)': + dependencies: + '@hyperjump/browser': 1.5.0 + '@hyperjump/json-pointer': 1.1.2 + '@hyperjump/json-schema-formats': 1.0.7 + '@hyperjump/pact': 1.4.0 + '@hyperjump/uri': 1.3.6 + content-type: 1.0.5 + json-stringify-deterministic: 1.0.16 + just-curry-it: 5.3.0 + uuid: 14.0.2 + + '@hyperjump/pact@1.4.0': {} + + '@hyperjump/uri@1.3.6': {} + + '@jridgewell/resolve-uri@3.1.2': {} + + '@jridgewell/sourcemap-codec@1.5.5': {} + + '@jridgewell/sourcemap-codec@1.6.0': {} + + '@jridgewell/trace-mapping@0.3.31': + dependencies: + '@jridgewell/resolve-uri': 3.1.2 + '@jridgewell/sourcemap-codec': 1.5.5 + + '@keyv/bigmap@1.3.1(keyv@5.6.0)': + dependencies: + hashery: 1.5.1 + hookified: 1.15.1 + keyv: 5.6.0 + + '@keyv/serialize@1.1.1': {} + + '@oxc-project/types@0.150.0': {} + + '@oxfmt/binding-android-arm-eabi@0.70.0': optional: true - '@esbuild/linux-arm@0.27.3': + '@oxfmt/binding-android-arm64@0.70.0': optional: true - '@esbuild/linux-ia32@0.27.3': + '@oxfmt/binding-darwin-arm64@0.70.0': optional: true - '@esbuild/linux-loong64@0.27.3': + '@oxfmt/binding-darwin-x64@0.70.0': optional: true - '@esbuild/linux-mips64el@0.27.3': + '@oxfmt/binding-freebsd-x64@0.70.0': optional: true - '@esbuild/linux-ppc64@0.27.3': + '@oxfmt/binding-linux-arm-gnueabihf@0.70.0': optional: true - '@esbuild/linux-riscv64@0.27.3': + '@oxfmt/binding-linux-arm-musleabihf@0.70.0': optional: true - '@esbuild/linux-s390x@0.27.3': + '@oxfmt/binding-linux-arm64-gnu@0.70.0': optional: true - '@esbuild/linux-x64@0.27.3': + '@oxfmt/binding-linux-arm64-musl@0.70.0': optional: true - '@esbuild/netbsd-arm64@0.27.3': + '@oxfmt/binding-linux-ppc64-gnu@0.70.0': optional: true - '@esbuild/netbsd-x64@0.27.3': + '@oxfmt/binding-linux-riscv64-gnu@0.70.0': optional: true - '@esbuild/openbsd-arm64@0.27.3': + '@oxfmt/binding-linux-riscv64-musl@0.70.0': optional: true - '@esbuild/openbsd-x64@0.27.3': + '@oxfmt/binding-linux-s390x-gnu@0.70.0': optional: true - '@esbuild/openharmony-arm64@0.27.3': + '@oxfmt/binding-linux-x64-gnu@0.70.0': optional: true - '@esbuild/sunos-x64@0.27.3': + '@oxfmt/binding-linux-x64-musl@0.70.0': optional: true - '@esbuild/win32-arm64@0.27.3': + '@oxfmt/binding-openharmony-arm64@0.70.0': optional: true - '@esbuild/win32-ia32@0.27.3': + '@oxfmt/binding-win32-arm64-msvc@0.70.0': optional: true - '@esbuild/win32-x64@0.27.3': + '@oxfmt/binding-win32-ia32-msvc@0.70.0': optional: true - '@jridgewell/sourcemap-codec@1.5.5': {} + '@oxfmt/binding-win32-x64-msvc@0.70.0': + optional: true - '@jsdevtools/ono@7.1.3': {} + '@rolldown/binding-android-arm-eabi@1.2.9': + optional: true - '@rollup/rollup-android-arm-eabi@4.59.0': + '@rolldown/binding-android-arm64@1.2.9': optional: true - '@rollup/rollup-android-arm64@4.59.0': + '@rolldown/binding-darwin-arm64@1.2.9': optional: true - '@rollup/rollup-darwin-arm64@4.59.0': + '@rolldown/binding-darwin-x64@1.2.9': optional: true - '@rollup/rollup-darwin-x64@4.59.0': + '@rolldown/binding-freebsd-x64@1.2.9': optional: true - '@rollup/rollup-freebsd-arm64@4.59.0': + '@rolldown/binding-linux-arm-gnueabihf@1.2.9': optional: true - '@rollup/rollup-freebsd-x64@4.59.0': + '@rolldown/binding-linux-arm64-gnu@1.2.9': optional: true - '@rollup/rollup-linux-arm-gnueabihf@4.59.0': + '@rolldown/binding-linux-arm64-musl@1.2.9': optional: true - '@rollup/rollup-linux-arm-musleabihf@4.59.0': + '@rolldown/binding-linux-ppc64-gnu@1.2.9': optional: true - '@rollup/rollup-linux-arm64-gnu@4.59.0': + '@rolldown/binding-linux-s390x-gnu@1.2.9': optional: true - '@rollup/rollup-linux-arm64-musl@4.59.0': + '@rolldown/binding-linux-x64-gnu@1.2.9': optional: true - '@rollup/rollup-linux-loong64-gnu@4.59.0': + '@rolldown/binding-linux-x64-musl@1.2.9': optional: true - '@rollup/rollup-linux-loong64-musl@4.59.0': + '@rolldown/binding-openharmony-arm64@1.2.9': optional: true - '@rollup/rollup-linux-ppc64-gnu@4.59.0': + '@rolldown/binding-win32-arm64-msvc@1.2.9': optional: true - '@rollup/rollup-linux-ppc64-musl@4.59.0': + '@rolldown/binding-win32-x64-msvc@1.2.9': optional: true - '@rollup/rollup-linux-riscv64-gnu@4.59.0': + '@rolldown/pluginutils@1.0.1': {} + + '@types/chai@5.2.3': + dependencies: + '@types/deep-eql': 4.0.2 + assertion-error: 2.0.1 + + '@types/deep-eql@4.0.2': {} + + '@types/esrecurse@4.3.1': {} + + '@types/estree@1.0.8': {} + + '@types/json-schema@7.0.15': {} + + '@types/node@26.6.2': + dependencies: + undici-types: 8.9.0 + + '@typescript/typescript-aix-ppc64@7.0.2': optional: true - '@rollup/rollup-linux-riscv64-musl@4.59.0': + '@typescript/typescript-darwin-arm64@7.0.2': optional: true - '@rollup/rollup-linux-s390x-gnu@4.59.0': + '@typescript/typescript-darwin-x64@7.0.2': optional: true - '@rollup/rollup-linux-x64-gnu@4.59.0': + '@typescript/typescript-freebsd-arm64@7.0.2': optional: true - '@rollup/rollup-linux-x64-musl@4.59.0': + '@typescript/typescript-freebsd-x64@7.0.2': optional: true - '@rollup/rollup-openbsd-x64@4.59.0': + '@typescript/typescript-linux-arm64@7.0.2': optional: true - '@rollup/rollup-openharmony-arm64@4.59.0': + '@typescript/typescript-linux-arm@7.0.2': optional: true - '@rollup/rollup-win32-arm64-msvc@4.59.0': + '@typescript/typescript-linux-loong64@7.0.2': optional: true - '@rollup/rollup-win32-ia32-msvc@4.59.0': + '@typescript/typescript-linux-mips64el@7.0.2': optional: true - '@rollup/rollup-win32-x64-gnu@4.59.0': + '@typescript/typescript-linux-ppc64@7.0.2': optional: true - '@rollup/rollup-win32-x64-msvc@4.59.0': + '@typescript/typescript-linux-riscv64@7.0.2': optional: true - '@tsconfig/node24@24.0.4': {} + '@typescript/typescript-linux-s390x@7.0.2': + optional: true - '@tsconfig/strictest@2.0.8': {} + '@typescript/typescript-linux-x64@7.0.2': + optional: true - '@types/chai@5.2.3': - dependencies: - '@types/deep-eql': 4.0.2 - assertion-error: 2.0.1 + '@typescript/typescript-netbsd-arm64@7.0.2': + optional: true - '@types/deep-eql@4.0.2': {} + '@typescript/typescript-netbsd-x64@7.0.2': + optional: true - '@types/estree@1.0.8': {} + '@typescript/typescript-openbsd-arm64@7.0.2': + optional: true - '@types/json-schema@7.0.15': {} + '@typescript/typescript-openbsd-x64@7.0.2': + optional: true - '@types/lodash@4.17.24': {} + '@typescript/typescript-sunos-x64@7.0.2': + optional: true - '@types/node@24.12.0': - dependencies: - undici-types: 7.16.0 + '@typescript/typescript-win32-arm64@7.0.2': + optional: true - '@vitest/expect@3.2.4': - dependencies: - '@types/chai': 5.2.3 - '@vitest/spy': 3.2.4 - '@vitest/utils': 3.2.4 - chai: 5.3.3 - tinyrainbow: 2.0.0 + '@typescript/typescript-win32-x64@7.0.2': + optional: true - '@vitest/mocker@3.2.4(vite@7.3.1(@types/node@24.12.0)(yaml@2.8.2))': + '@vitest/mocker@5.0.1(vite@8.3.0(@types/node@26.6.2)(esbuild@0.27.3)(yaml@2.8.2))': dependencies: - '@vitest/spy': 3.2.4 + '@jridgewell/trace-mapping': 0.3.31 + '@vitest/spy': 5.0.1 estree-walker: 3.0.3 - magic-string: 0.30.21 + magic-string: 1.4.1 optionalDependencies: - vite: 7.3.1(@types/node@24.12.0)(yaml@2.8.2) + vite: 8.3.0(@types/node@26.6.2)(esbuild@0.27.3)(yaml@2.8.2) - '@vitest/pretty-format@3.2.4': - dependencies: - tinyrainbow: 2.0.0 + '@vitest/spy@5.0.1': {} - '@vitest/runner@3.2.4': + acorn-jsx@5.3.2(acorn@8.18.0): dependencies: - '@vitest/utils': 3.2.4 - pathe: 2.0.3 - strip-literal: 3.1.0 + acorn: 8.18.0 + + acorn@8.18.0: {} - '@vitest/snapshot@3.2.4': + ajv@6.15.0: dependencies: - '@vitest/pretty-format': 3.2.4 - magic-string: 0.30.21 - pathe: 2.0.3 + fast-deep-equal: 3.1.3 + fast-json-stable-stringify: 2.1.0 + json-schema-traverse: 0.4.1 + uri-js: 4.4.1 + + assertion-error@2.0.1: {} + + balanced-match@4.0.4: {} - '@vitest/spy@3.2.4': + baseline-browser-mapping@2.11.25: {} + + brace-expansion@5.0.12: dependencies: - tinyspy: 4.0.4 + balanced-match: 4.0.4 - '@vitest/utils@3.2.4': + browserslist@4.29.0: dependencies: - '@vitest/pretty-format': 3.2.4 - loupe: 3.2.1 - tinyrainbow: 2.0.0 + baseline-browser-mapping: 2.11.25 + caniuse-lite: 1.0.30001810 + electron-to-chromium: 1.5.434 + node-releases: 2.0.56 + update-browserslist-db: 1.3.3(browserslist@4.29.0) - ajv-draft-04@1.0.0(ajv@8.18.0): - optionalDependencies: - ajv: 8.18.0 + builtin-modules@5.4.0: {} - ajv@8.18.0: + cacheable@2.5.0: dependencies: - fast-deep-equal: 3.1.3 - fast-uri: 3.1.0 - json-schema-traverse: 1.0.0 - require-from-string: 2.0.2 + '@cacheable/memory': 2.2.0 + '@cacheable/utils': 2.5.0 + hookified: 1.15.1 + keyv: 5.6.0 + qified: 0.10.1 - argparse@2.0.1: {} + caniuse-lite@1.0.30001810: {} - assertion-error@2.0.1: {} + chai@6.2.2: {} + + change-case@5.4.4: {} + + ci-info@4.4.0: {} - cac@6.7.14: {} + constructs@10.8.1: {} - call-me-maybe@1.0.2: {} + content-type@1.0.5: {} - chai@5.3.3: + convert-hrtime@5.0.0: {} + + core-js-compat@3.50.0: dependencies: - assertion-error: 2.0.1 - check-error: 2.1.3 - deep-eql: 5.0.2 - loupe: 3.2.1 - pathval: 2.0.1 + browserslist: 4.29.0 - check-error@2.1.3: {} + cross-spawn@7.0.6: + dependencies: + path-key: 3.1.1 + shebang-command: 2.0.0 + which: 2.0.2 - constructs@10.5.1: {} + css-tree@3.2.1: + dependencies: + mdn-data: 2.27.1 + source-map-js: 1.2.1 debug@4.4.3: dependencies: ms: 2.1.3 - deep-eql@5.0.2: {} + deep-is@0.1.4: {} + + detect-indent@7.0.2: {} + + detect-libc@2.1.2: {} + + electron-to-chromium@1.5.434: {} - es-module-lexer@1.7.0: {} + entities@8.1.0: {} + + es-module-lexer@2.3.2: {} esbuild@0.27.3: optionalDependencies: @@ -1040,118 +2239,415 @@ snapshots: '@esbuild/win32-arm64': 0.27.3 '@esbuild/win32-ia32': 0.27.3 '@esbuild/win32-x64': 0.27.3 + optional: true + + escalade@3.2.0: {} + + escape-string-regexp@4.0.0: {} + + eslint-plugin-unicorn@74.0.0(eslint@10.11.0): + dependencies: + '@eslint-community/eslint-utils': 4.10.1(eslint@10.11.0) + '@eslint/css-tree': 4.1.1 + browserslist: 4.29.0 + change-case: 5.4.4 + ci-info: 4.4.0 + core-js-compat: 3.50.0 + detect-indent: 7.0.2 + entities: 8.1.0 + eslint: 10.11.0 + find-up-simple: 1.0.1 + globals: 17.12.0 + indent-string: 5.0.0 + is-builtin-module: 5.0.0 + is-identifier: 1.1.0 + pluralize: 8.0.0 + quote-js-string: 0.1.0 + regjsparser: 0.13.3 + reserved-identifiers: 1.2.0 + semver: 7.8.5 + strip-indent: 4.1.1 + yaml: 2.9.1 + + eslint-scope@9.1.2: + dependencies: + '@types/esrecurse': 4.3.1 + '@types/estree': 1.0.8 + esrecurse: 4.3.0 + estraverse: 5.3.0 + + eslint-visitor-keys@3.4.3: {} + + eslint-visitor-keys@5.0.1: {} + + eslint@10.11.0: + dependencies: + '@eslint-community/eslint-utils': 4.10.1(eslint@10.11.0) + '@eslint-community/regexpp': 4.12.2 + '@eslint/config-array': 0.23.5 + '@eslint/config-helpers': 0.7.0 + '@eslint/core': 1.2.1 + '@eslint/plugin-kit': 0.7.3 + '@humanfs/node': 0.16.8 + '@humanwhocodes/module-importer': 1.0.1 + '@humanwhocodes/retry': 0.4.3 + '@types/estree': 1.0.8 + ajv: 6.15.0 + cross-spawn: 7.0.6 + debug: 4.4.3 + escape-string-regexp: 4.0.0 + eslint-scope: 9.1.2 + eslint-visitor-keys: 5.0.1 + espree: 11.2.0 + esquery: 1.7.0 + esutils: 2.0.3 + fast-deep-equal: 3.1.3 + file-entry-cache: 11.1.5 + find-up: 5.0.0 + glob-parent: 6.0.2 + ignore: 5.3.2 + imurmurhash: 0.1.4 + is-glob: 4.0.3 + json-stable-stringify-without-jsonify: 1.0.1 + minimatch: 10.2.6 + natural-compare: 1.4.0 + optionator: 0.9.4 + transitivePeerDependencies: + - supports-color + + espree@11.2.0: + dependencies: + acorn: 8.18.0 + acorn-jsx: 5.3.2(acorn@8.18.0) + eslint-visitor-keys: 5.0.1 + + esquery@1.7.0: + dependencies: + estraverse: 5.3.0 + + esrecurse@4.3.0: + dependencies: + estraverse: 5.3.0 + + estraverse@5.3.0: {} estree-walker@3.0.3: dependencies: '@types/estree': 1.0.8 - expect-type@1.3.0: {} + esutils@2.0.3: {} + + expect-type@1.4.0: {} + + fallow-type-aware@3.28.0: + dependencies: + typescript: 7.0.2 + optional: true + + fallow@3.28.0: + dependencies: + detect-libc: 2.1.2 + optionalDependencies: + '@fallow-cli/darwin-arm64': 3.28.0 + '@fallow-cli/darwin-x64': 3.28.0 + '@fallow-cli/linux-arm64-gnu': 3.28.0 + '@fallow-cli/linux-arm64-musl': 3.28.0 + '@fallow-cli/linux-x64-gnu': 3.28.0 + '@fallow-cli/linux-x64-musl': 3.28.0 + '@fallow-cli/win32-arm64-msvc': 3.28.0 + '@fallow-cli/win32-x64-msvc': 3.28.0 + fallow-type-aware: 3.28.0 fast-deep-equal@3.1.3: {} - fast-uri@3.1.0: {} + fast-json-stable-stringify@2.1.0: {} - fdir@6.5.0(picomatch@4.0.3): + fast-levenshtein@2.0.6: {} + + fdir@6.5.0(picomatch@4.0.7): optionalDependencies: - picomatch: 4.0.3 + picomatch: 4.0.7 + + file-entry-cache@11.1.5: + dependencies: + flat-cache: 6.1.23 + + find-up-simple@1.0.1: {} + + find-up@5.0.0: + dependencies: + locate-path: 6.0.0 + path-exists: 4.0.0 + + flat-cache@6.1.23: + dependencies: + cacheable: 2.5.0 + flatted: 3.4.4 + hookified: 1.15.1 + + flatted@3.4.4: {} fsevents@2.3.3: optional: true + function-timeout@1.0.2: {} + + glob-parent@6.0.2: + dependencies: + is-glob: 4.0.3 + + globals@17.12.0: {} + + hashery@1.5.1: + dependencies: + hookified: 1.15.1 + + hookified@1.15.1: {} + + hookified@2.2.0: {} + + identifier-regex@1.1.0: + dependencies: + reserved-identifiers: 1.2.0 + + idn-hostname@15.1.19: + dependencies: + punycode: 2.3.1 + + ignore@5.3.2: {} + + imurmurhash@0.1.4: {} + + indent-string@5.0.0: {} + + is-builtin-module@5.0.0: + dependencies: + builtin-modules: 5.4.0 + is-extglob@2.1.1: {} is-glob@4.0.3: dependencies: is-extglob: 2.1.1 - js-tokens@9.0.1: {} + is-identifier@1.1.0: + dependencies: + identifier-regex: 1.1.0 + super-regex: 1.1.0 + + isexe@2.0.0: {} + + jsesc@3.1.0: {} + + json-schema-traverse@0.4.1: {} + + json-stable-stringify-without-jsonify@1.0.1: {} - js-yaml@4.1.1: + json-stringify-deterministic@1.0.16: {} + + just-curry-it@5.3.0: {} + + keyv@5.6.0: dependencies: - argparse: 2.0.1 + '@keyv/serialize': 1.1.1 - json-schema-to-typescript@15.0.4: + levn@0.4.1: dependencies: - '@apidevtools/json-schema-ref-parser': 11.9.3 - '@types/json-schema': 7.0.15 - '@types/lodash': 4.17.24 - is-glob: 4.0.3 - js-yaml: 4.1.1 - lodash: 4.17.23 - minimist: 1.2.8 - prettier: 3.8.1 - tinyglobby: 0.2.15 + prelude-ls: 1.2.1 + type-check: 0.4.0 + + lightningcss-android-arm64@1.33.0: + optional: true + + lightningcss-darwin-arm64@1.33.0: + optional: true + + lightningcss-darwin-x64@1.33.0: + optional: true + + lightningcss-freebsd-x64@1.33.0: + optional: true + + lightningcss-linux-arm-gnueabihf@1.33.0: + optional: true + + lightningcss-linux-arm64-gnu@1.33.0: + optional: true - json-schema-traverse@1.0.0: {} + lightningcss-linux-arm64-musl@1.33.0: + optional: true + + lightningcss-linux-x64-gnu@1.33.0: + optional: true + + lightningcss-linux-x64-musl@1.33.0: + optional: true - lodash@4.17.23: {} + lightningcss-win32-arm64-msvc@1.33.0: + optional: true - loupe@3.2.1: {} + lightningcss-win32-x64-msvc@1.33.0: + optional: true - magic-string@0.30.21: + lightningcss@1.33.0: dependencies: - '@jridgewell/sourcemap-codec': 1.5.5 + detect-libc: 2.1.2 + optionalDependencies: + lightningcss-android-arm64: 1.33.0 + lightningcss-darwin-arm64: 1.33.0 + lightningcss-darwin-x64: 1.33.0 + lightningcss-freebsd-x64: 1.33.0 + lightningcss-linux-arm-gnueabihf: 1.33.0 + lightningcss-linux-arm64-gnu: 1.33.0 + lightningcss-linux-arm64-musl: 1.33.0 + lightningcss-linux-x64-gnu: 1.33.0 + lightningcss-linux-x64-musl: 1.33.0 + lightningcss-win32-arm64-msvc: 1.33.0 + lightningcss-win32-x64-msvc: 1.33.0 + + locate-path@6.0.0: + dependencies: + p-locate: 5.0.0 + + magic-string@1.4.1: + dependencies: + '@jridgewell/sourcemap-codec': 1.6.0 + + make-asynchronous@1.1.0: + dependencies: + p-event: 6.0.1 + type-fest: 4.41.0 + web-worker: 1.5.0 + + mdn-data@2.27.1: {} + + mdn-data@2.35.0: {} - minimist@1.2.8: {} + minimatch@10.2.6: + dependencies: + brace-expansion: 5.0.12 ms@2.1.3: {} - nanoid@3.3.11: {} + nanoid@3.3.19: {} + + natural-compare@1.4.0: {} - openapi-types@12.1.3: {} + node-releases@2.0.56: {} - openapi3-ts@4.5.0: + obug@2.2.1: {} + + openapi3-ts@4.6.1: dependencies: - yaml: 2.8.2 + yaml: 2.9.1 + + optionator@0.9.4: + dependencies: + deep-is: 0.1.4 + fast-levenshtein: 2.0.6 + levn: 0.4.1 + prelude-ls: 1.2.1 + type-check: 0.4.0 + word-wrap: 1.2.5 + + oxfmt@0.70.0: + dependencies: + tinypool: 2.1.2 + optionalDependencies: + '@oxfmt/binding-android-arm-eabi': 0.70.0 + '@oxfmt/binding-android-arm64': 0.70.0 + '@oxfmt/binding-darwin-arm64': 0.70.0 + '@oxfmt/binding-darwin-x64': 0.70.0 + '@oxfmt/binding-freebsd-x64': 0.70.0 + '@oxfmt/binding-linux-arm-gnueabihf': 0.70.0 + '@oxfmt/binding-linux-arm-musleabihf': 0.70.0 + '@oxfmt/binding-linux-arm64-gnu': 0.70.0 + '@oxfmt/binding-linux-arm64-musl': 0.70.0 + '@oxfmt/binding-linux-ppc64-gnu': 0.70.0 + '@oxfmt/binding-linux-riscv64-gnu': 0.70.0 + '@oxfmt/binding-linux-riscv64-musl': 0.70.0 + '@oxfmt/binding-linux-s390x-gnu': 0.70.0 + '@oxfmt/binding-linux-x64-gnu': 0.70.0 + '@oxfmt/binding-linux-x64-musl': 0.70.0 + '@oxfmt/binding-openharmony-arm64': 0.70.0 + '@oxfmt/binding-win32-arm64-msvc': 0.70.0 + '@oxfmt/binding-win32-ia32-msvc': 0.70.0 + '@oxfmt/binding-win32-x64-msvc': 0.70.0 + + p-event@6.0.1: + dependencies: + p-timeout: 6.1.4 + + p-limit@3.1.0: + dependencies: + yocto-queue: 0.1.0 + + p-locate@5.0.0: + dependencies: + p-limit: 3.1.0 + + p-timeout@6.1.4: {} - pathe@2.0.3: {} + path-exists@4.0.0: {} - pathval@2.0.1: {} + path-key@3.1.1: {} picocolors@1.1.1: {} - picomatch@4.0.3: {} + picomatch@4.0.7: {} - postcss@8.5.8: + pluralize@8.0.0: {} + + postcss@8.5.28: dependencies: - nanoid: 3.3.11 + nanoid: 3.3.19 picocolors: 1.1.1 source-map-js: 1.2.1 - prettier@3.8.1: {} + prelude-ls@1.2.1: {} - require-from-string@2.0.2: {} + punycode@2.3.1: {} - rollup@4.59.0: + qified@0.10.1: dependencies: - '@types/estree': 1.0.8 + hookified: 2.2.0 + + quote-js-string@0.1.0: {} + + regjsparser@0.13.3: + dependencies: + jsesc: 3.1.0 + + reserved-identifiers@1.2.0: {} + + rolldown@1.2.9: + dependencies: + '@oxc-project/types': 0.150.0 + '@rolldown/pluginutils': 1.0.1 optionalDependencies: - '@rollup/rollup-android-arm-eabi': 4.59.0 - '@rollup/rollup-android-arm64': 4.59.0 - '@rollup/rollup-darwin-arm64': 4.59.0 - '@rollup/rollup-darwin-x64': 4.59.0 - '@rollup/rollup-freebsd-arm64': 4.59.0 - '@rollup/rollup-freebsd-x64': 4.59.0 - '@rollup/rollup-linux-arm-gnueabihf': 4.59.0 - '@rollup/rollup-linux-arm-musleabihf': 4.59.0 - '@rollup/rollup-linux-arm64-gnu': 4.59.0 - '@rollup/rollup-linux-arm64-musl': 4.59.0 - '@rollup/rollup-linux-loong64-gnu': 4.59.0 - '@rollup/rollup-linux-loong64-musl': 4.59.0 - '@rollup/rollup-linux-ppc64-gnu': 4.59.0 - '@rollup/rollup-linux-ppc64-musl': 4.59.0 - '@rollup/rollup-linux-riscv64-gnu': 4.59.0 - '@rollup/rollup-linux-riscv64-musl': 4.59.0 - '@rollup/rollup-linux-s390x-gnu': 4.59.0 - '@rollup/rollup-linux-x64-gnu': 4.59.0 - '@rollup/rollup-linux-x64-musl': 4.59.0 - '@rollup/rollup-openbsd-x64': 4.59.0 - '@rollup/rollup-openharmony-arm64': 4.59.0 - '@rollup/rollup-win32-arm64-msvc': 4.59.0 - '@rollup/rollup-win32-ia32-msvc': 4.59.0 - '@rollup/rollup-win32-x64-gnu': 4.59.0 - '@rollup/rollup-win32-x64-msvc': 4.59.0 - fsevents: 2.3.3 + '@rolldown/binding-android-arm-eabi': 1.2.9 + '@rolldown/binding-android-arm64': 1.2.9 + '@rolldown/binding-darwin-arm64': 1.2.9 + '@rolldown/binding-darwin-x64': 1.2.9 + '@rolldown/binding-freebsd-x64': 1.2.9 + '@rolldown/binding-linux-arm-gnueabihf': 1.2.9 + '@rolldown/binding-linux-arm64-gnu': 1.2.9 + '@rolldown/binding-linux-arm64-musl': 1.2.9 + '@rolldown/binding-linux-ppc64-gnu': 1.2.9 + '@rolldown/binding-linux-s390x-gnu': 1.2.9 + '@rolldown/binding-linux-x64-gnu': 1.2.9 + '@rolldown/binding-linux-x64-musl': 1.2.9 + '@rolldown/binding-openharmony-arm64': 1.2.9 + '@rolldown/binding-win32-arm64-msvc': 1.2.9 + '@rolldown/binding-win32-x64-msvc': 1.2.9 + + semver@7.8.5: {} + + shebang-command@2.0.0: + dependencies: + shebang-regex: 3.0.0 + + shebang-regex@3.0.0: {} siginfo@2.0.0: {} @@ -1159,115 +2655,124 @@ snapshots: stackback@0.0.2: {} - std-env@3.10.0: {} + std-env@4.2.0: {} + + strip-indent@4.1.1: {} - strip-literal@3.1.0: + super-regex@1.1.0: dependencies: - js-tokens: 9.0.1 + function-timeout: 1.0.2 + make-asynchronous: 1.1.0 + time-span: 5.1.0 - tagged-tag@1.0.0: {} + time-span@5.1.0: + dependencies: + convert-hrtime: 5.0.0 - tinybench@2.9.0: {} + tinybench@6.1.4: {} - tinyexec@0.3.2: {} + tinyexec@1.3.0: {} - tinyglobby@0.2.15: + tinyglobby@0.2.17: dependencies: - fdir: 6.5.0(picomatch@4.0.3) - picomatch: 4.0.3 - - tinypool@1.1.1: {} + fdir: 6.5.0(picomatch@4.0.7) + picomatch: 4.0.7 - tinyrainbow@2.0.0: {} + tinypool@2.1.2: {} - tinyspy@4.0.4: {} - - type-fest@5.4.4: + type-check@0.4.0: dependencies: - tagged-tag: 1.0.0 + prelude-ls: 1.2.1 - typescript@5.9.3: {} + type-fest@4.41.0: {} - undici-types@7.16.0: {} + typescript@7.0.2: + optionalDependencies: + '@typescript/typescript-aix-ppc64': 7.0.2 + '@typescript/typescript-darwin-arm64': 7.0.2 + '@typescript/typescript-darwin-x64': 7.0.2 + '@typescript/typescript-freebsd-arm64': 7.0.2 + '@typescript/typescript-freebsd-x64': 7.0.2 + '@typescript/typescript-linux-arm': 7.0.2 + '@typescript/typescript-linux-arm64': 7.0.2 + '@typescript/typescript-linux-loong64': 7.0.2 + '@typescript/typescript-linux-mips64el': 7.0.2 + '@typescript/typescript-linux-ppc64': 7.0.2 + '@typescript/typescript-linux-riscv64': 7.0.2 + '@typescript/typescript-linux-s390x': 7.0.2 + '@typescript/typescript-linux-x64': 7.0.2 + '@typescript/typescript-netbsd-arm64': 7.0.2 + '@typescript/typescript-netbsd-x64': 7.0.2 + '@typescript/typescript-openbsd-arm64': 7.0.2 + '@typescript/typescript-openbsd-x64': 7.0.2 + '@typescript/typescript-sunos-x64': 7.0.2 + '@typescript/typescript-win32-arm64': 7.0.2 + '@typescript/typescript-win32-x64': 7.0.2 + + undici-types@8.9.0: {} + + update-browserslist-db@1.3.3(browserslist@4.29.0): + dependencies: + browserslist: 4.29.0 + escalade: 3.2.0 + picocolors: 1.1.1 - vite-node@3.2.4(@types/node@24.12.0)(yaml@2.8.2): + uri-js@4.4.1: dependencies: - cac: 6.7.14 - debug: 4.4.3 - es-module-lexer: 1.7.0 - pathe: 2.0.3 - vite: 7.3.1(@types/node@24.12.0)(yaml@2.8.2) - transitivePeerDependencies: - - '@types/node' - - jiti - - less - - lightningcss - - sass - - sass-embedded - - stylus - - sugarss - - supports-color - - terser - - tsx - - yaml + punycode: 2.3.1 + + uuid@14.0.2: {} - vite@7.3.1(@types/node@24.12.0)(yaml@2.8.2): + vite@8.3.0(@types/node@26.6.2)(esbuild@0.27.3)(yaml@2.8.2): dependencies: - esbuild: 0.27.3 - fdir: 6.5.0(picomatch@4.0.3) - picomatch: 4.0.3 - postcss: 8.5.8 - rollup: 4.59.0 - tinyglobby: 0.2.15 + lightningcss: 1.33.0 + picomatch: 4.0.7 + postcss: 8.5.28 + rolldown: 1.2.9 + tinyglobby: 0.2.17 optionalDependencies: - '@types/node': 24.12.0 + '@types/node': 26.6.2 + esbuild: 0.27.3 fsevents: 2.3.3 yaml: 2.8.2 - vitest@3.2.4(@types/node@24.12.0)(yaml@2.8.2): + vitest@5.0.1(@types/node@26.6.2)(vite@8.3.0(@types/node@26.6.2)(esbuild@0.27.3)(yaml@2.8.2)): dependencies: '@types/chai': 5.2.3 - '@vitest/expect': 3.2.4 - '@vitest/mocker': 3.2.4(vite@7.3.1(@types/node@24.12.0)(yaml@2.8.2)) - '@vitest/pretty-format': 3.2.4 - '@vitest/runner': 3.2.4 - '@vitest/snapshot': 3.2.4 - '@vitest/spy': 3.2.4 - '@vitest/utils': 3.2.4 - chai: 5.3.3 - debug: 4.4.3 - expect-type: 1.3.0 - magic-string: 0.30.21 - pathe: 2.0.3 - picomatch: 4.0.3 - std-env: 3.10.0 - tinybench: 2.9.0 - tinyexec: 0.3.2 - tinyglobby: 0.2.15 - tinypool: 1.1.1 - tinyrainbow: 2.0.0 - vite: 7.3.1(@types/node@24.12.0)(yaml@2.8.2) - vite-node: 3.2.4(@types/node@24.12.0)(yaml@2.8.2) + '@vitest/mocker': 5.0.1(vite@8.3.0(@types/node@26.6.2)(esbuild@0.27.3)(yaml@2.8.2)) + chai: 6.2.2 + es-module-lexer: 2.3.2 + expect-type: 1.4.0 + magic-string: 1.4.1 + obug: 2.2.1 + picomatch: 4.0.7 + std-env: 4.2.0 + tinybench: 6.1.4 + tinyexec: 1.3.0 + tinyglobby: 0.2.17 + vite: 8.3.0(@types/node@26.6.2)(esbuild@0.27.3)(yaml@2.8.2) why-is-node-running: 2.3.0 optionalDependencies: - '@types/node': 24.12.0 + '@types/node': 26.6.2 transitivePeerDependencies: - - jiti - - less - - lightningcss - msw - - sass - - sass-embedded - - stylus - - sugarss - - supports-color - - terser - - tsx - - yaml + + web-worker@1.5.0: {} + + which@2.0.2: + dependencies: + isexe: 2.0.0 why-is-node-running@2.3.0: dependencies: siginfo: 2.0.0 stackback: 0.0.2 - yaml@2.8.2: {} + word-wrap@1.2.5: {} + + yaml@2.8.2: + optional: true + + yaml@2.9.1: {} + + yocto-queue@0.1.0: {} diff --git a/pnpm-workspace.yaml b/pnpm-workspace.yaml new file mode 100644 index 0000000..922a3ac --- /dev/null +++ b/pnpm-workspace.yaml @@ -0,0 +1,16 @@ +allowBuilds: + esbuild: false + +minimumReleaseAgeExclude: + - "@block65/oxlint-binding-linux-arm64-gnu@1.83.0" + - "@block65/oxlint-binding-linux-x64-gnu@1.83.0" + - "@block65/oxlint-tsgolint-linux-arm64@7.0.200200" + - "@block65/oxlint-tsgolint-linux-x64@7.0.200200" + - "@block65/oxlint-tsgolint@7.0.200200" + - "@block65/oxlint@1.83.0" + - "@block65/oxlint-plugin@0.11.0" + - "@block65/shared-config@0.5.0" + +overrides: + oxlint: npm:@block65/oxlint@>=1.83.0 + oxlint-tsgolint: npm:@block65/oxlint-tsgolint@>=7.0.200200 diff --git a/tsconfig.json b/tsconfig.json index aaa9712..ac66423 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -1,11 +1,15 @@ { - "extends": ["@tsconfig/node24/tsconfig.json", "@tsconfig/strictest/tsconfig.json"], - "compilerOptions": { - "allowImportingTsExtensions": true, - "verbatimModuleSyntax": true, - "noEmit": true, - "skipLibCheck": true - }, - "include": ["./lib", "./examples", "./__tests__"], - "exclude": ["./dist", "node_modules"] + "extends": ["@block65/tsconfig/vanilla", "@block65/tsconfig/noprojref"], + + "compilerOptions": { + "types": ["node"] + }, + + "include": [ + "lib", + "examples", + "__tests__", + "oxlint.config.ts", + "oxfmt.config.ts" + ] }