feat(openapi): улучшенный Swagger + TS-клиент через openapi-typescript (P1-19)
API: • SwaggerGen с OpenAPI info (title/version/description), Bearer security-scheme (через OpenIddict JWT), стабильные operationId = Controller_VerbAction (HTTP-verb включён чтобы избежать коллизии когда ASP.NET стрипает Async-суффикс — WipeAll и WipeAllAsync ранее давали одинаковый operationId); • CustomSchemaIds с префиксом из namespace (одноимённые nested record'ы в разных контроллерах больше не схлопываются — StockRow есть в Inventory_StockController и Reports_StockReportController). UI: • /swagger (UI) и /swagger/v1/swagger.json (документ) — только в Development. На prod не раскрываем (endpoint enumeration). Web: • Добавлен devDependency openapi-typescript@^7.5.2 + npm-script gen:api, читающий http://localhost:5081/swagger/v1/swagger.json. • src/lib/api.generated.ts — сгенерированные типы (~7700 строк, все схемы и operations). • src/lib/apiClient.ts — тонкая обёртка над axios api, использующая типы из generated. Подключена для пары контроллеров (Reports/Sales, Reports/ABC, Reports/Profit) как образец постепенной миграции. docs/openapi.md — workflow генерации (live API или Swashbuckle CLI), versioning, наставления для нового кода. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
parent
96fa4bf990
commit
dbd08f6fd2
59
docs/openapi.md
Normal file
59
docs/openapi.md
Normal file
|
|
@ -0,0 +1,59 @@
|
||||||
|
# OpenAPI / Swagger
|
||||||
|
|
||||||
|
API публикует OpenAPI-документ через `Swashbuckle.AspNetCore`. Описание
|
||||||
|
включает security-scheme `Bearer` (OpenIddict JWT), стабильные
|
||||||
|
`operationId = Controller_Action`, уникальные `schemaId` с префиксом из
|
||||||
|
неймспейса (одноимённые nested record'ы в разных контроллерах не схлопываются).
|
||||||
|
|
||||||
|
## Эндпоинты
|
||||||
|
|
||||||
|
| URL | Когда |
|
||||||
|
|---|---|
|
||||||
|
| `/swagger` | UI, только Development |
|
||||||
|
| `/swagger/v1/swagger.json` | JSON-документ, только Development |
|
||||||
|
|
||||||
|
На stage/prod swagger отключён — отдельный endpoint enumeration
|
||||||
|
не должен раскрываться неавторизованным клиентам. Если нужно — поднимать
|
||||||
|
локальный API из той же ветки.
|
||||||
|
|
||||||
|
## TypeScript-клиент
|
||||||
|
|
||||||
|
В `src/food-market.web` подключён `openapi-typescript` (devDependency).
|
||||||
|
Команда:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Терминал 1: поднять API
|
||||||
|
ASPNETCORE_ENVIRONMENT=Development dotnet run --project src/food-market.api
|
||||||
|
|
||||||
|
# Терминал 2: сгенерировать types
|
||||||
|
cd src/food-market.web
|
||||||
|
pnpm run gen:api # читает http://localhost:5081/swagger/v1/swagger.json
|
||||||
|
# → src/lib/api.generated.ts
|
||||||
|
```
|
||||||
|
|
||||||
|
Альтернативно (без живого API) — через `Swashbuckle.AspNetCore.Cli` (версия
|
||||||
|
должна совпадать с `Swashbuckle.AspNetCore`, у нас 6.9.0):
|
||||||
|
|
||||||
|
```bash
|
||||||
|
dotnet tool install --global Swashbuckle.AspNetCore.Cli --version 6.9.0
|
||||||
|
dotnet build src/food-market.api
|
||||||
|
swagger tofile --output /tmp/swagger.json \
|
||||||
|
src/food-market.api/bin/Debug/net8.0/foodmarket.Api.dll v1
|
||||||
|
cd src/food-market.web
|
||||||
|
pnpm exec openapi-typescript /tmp/swagger.json -o src/lib/api.generated.ts
|
||||||
|
```
|
||||||
|
|
||||||
|
## Использование
|
||||||
|
|
||||||
|
Тонкая обёртка в `src/food-market.web/src/lib/apiClient.ts` экспортирует
|
||||||
|
типизированные хелперы для отчётов (Reports/Sales, Reports/ABC,
|
||||||
|
Reports/Profit) — образец постепенной миграции с ручных типов в
|
||||||
|
`types.ts`. В новом коде использовать обёртку и переэкспортированные
|
||||||
|
типы; старые страницы переписывать по мере правок.
|
||||||
|
|
||||||
|
## Версионирование
|
||||||
|
|
||||||
|
Document `v1` — единственный. Если будут breaking changes — поднимаем
|
||||||
|
`v2` рядом, не ломая `v1`. У `operationId` стабильное имя
|
||||||
|
`Controller_Action` — переименование контроллера ломает TS-клиент,
|
||||||
|
относиться как к public API.
|
||||||
|
|
@ -158,7 +158,58 @@
|
||||||
o.Filters.AddService<foodmarket.Api.Infrastructure.Tenancy.SuperAdminEditAuditFilter>();
|
o.Filters.AddService<foodmarket.Api.Infrastructure.Tenancy.SuperAdminEditAuditFilter>();
|
||||||
});
|
});
|
||||||
builder.Services.AddEndpointsApiExplorer();
|
builder.Services.AddEndpointsApiExplorer();
|
||||||
builder.Services.AddSwaggerGen();
|
builder.Services.AddSwaggerGen(opts =>
|
||||||
|
{
|
||||||
|
opts.SwaggerDoc("v1", new Microsoft.OpenApi.Models.OpenApiInfo
|
||||||
|
{
|
||||||
|
Title = "food-market API",
|
||||||
|
Version = "v1",
|
||||||
|
Description = "Multi-tenant POS/inventory backend. Все запросы " +
|
||||||
|
"ограничены организацией текущего JWT (claim `org_id`).",
|
||||||
|
});
|
||||||
|
// Bearer JWT через OpenIddict. Swagger UI «Authorize» подставит в Authorization.
|
||||||
|
var bearer = new Microsoft.OpenApi.Models.OpenApiSecurityScheme
|
||||||
|
{
|
||||||
|
Type = Microsoft.OpenApi.Models.SecuritySchemeType.Http,
|
||||||
|
Scheme = "bearer",
|
||||||
|
BearerFormat = "JWT",
|
||||||
|
In = Microsoft.OpenApi.Models.ParameterLocation.Header,
|
||||||
|
Description = "Access token, полученный через POST /connect/token.",
|
||||||
|
};
|
||||||
|
opts.AddSecurityDefinition("Bearer", bearer);
|
||||||
|
opts.AddSecurityRequirement(new Microsoft.OpenApi.Models.OpenApiSecurityRequirement
|
||||||
|
{
|
||||||
|
[new Microsoft.OpenApi.Models.OpenApiSecurityScheme
|
||||||
|
{
|
||||||
|
Reference = new Microsoft.OpenApi.Models.OpenApiReference
|
||||||
|
{
|
||||||
|
Type = Microsoft.OpenApi.Models.ReferenceType.SecurityScheme,
|
||||||
|
Id = "Bearer",
|
||||||
|
},
|
||||||
|
}] = Array.Empty<string>(),
|
||||||
|
});
|
||||||
|
// Стабильные operationId для генерации TS-клиентов:
|
||||||
|
// <Controller>_<Verb><Action>. Verb включён чтобы избежать коллизии
|
||||||
|
// когда ASP.NET стрипает Async-суффикс и два метода (WipeAll, WipeAllAsync)
|
||||||
|
// получают одинаковое имя action → одинаковый operationId → duplicate.
|
||||||
|
opts.CustomOperationIds(api =>
|
||||||
|
{
|
||||||
|
var ctrl = api.ActionDescriptor.RouteValues["controller"];
|
||||||
|
var action = api.ActionDescriptor.RouteValues["action"];
|
||||||
|
var verb = api.HttpMethod is { Length: > 0 } m ? char.ToUpper(m[0]) + m[1..].ToLowerInvariant() : "";
|
||||||
|
return $"{ctrl}_{verb}{action}";
|
||||||
|
});
|
||||||
|
// У нас есть одноимённые nested record'ы в разных контроллерах
|
||||||
|
// (например, StockRow в StockController и StockReportController).
|
||||||
|
// Включаем имя контроллера в schemaId через FullName-suffix чтобы не
|
||||||
|
// словить duplicate schemaId — Swashbuckle падает на этом по умолчанию.
|
||||||
|
opts.CustomSchemaIds(t => t.FullName!
|
||||||
|
.Replace("foodmarket.Api.Controllers.", "")
|
||||||
|
.Replace("foodmarket.Application.", "")
|
||||||
|
.Replace("foodmarket.Domain.", "")
|
||||||
|
.Replace("+", "_")
|
||||||
|
.Replace(".", "_"));
|
||||||
|
});
|
||||||
|
|
||||||
// MoySklad import integration. Auto-decompress gzip responses from MoySklad's edge.
|
// MoySklad import integration. Auto-decompress gzip responses from MoySklad's edge.
|
||||||
// BaseAddress берётся из конфигурации (MoySklad:BaseUrl) с дефолтом на боевой
|
// BaseAddress берётся из конфигурации (MoySklad:BaseUrl) с дефолтом на боевой
|
||||||
|
|
@ -237,8 +288,15 @@
|
||||||
|
|
||||||
if (app.Environment.IsDevelopment())
|
if (app.Environment.IsDevelopment())
|
||||||
{
|
{
|
||||||
|
// Swagger/OpenAPI: только в Development. /swagger/v1/swagger.json — JSON-документ,
|
||||||
|
// /swagger — UI. На prod не раскрываем (sensitive endpoint enumeration), на dev
|
||||||
|
// используется фронтом для генерации TS-клиента (`pnpm run gen:api`).
|
||||||
app.UseSwagger();
|
app.UseSwagger();
|
||||||
app.UseSwaggerUI();
|
app.UseSwaggerUI(opts =>
|
||||||
|
{
|
||||||
|
opts.DocumentTitle = "food-market API";
|
||||||
|
opts.RoutePrefix = "swagger";
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
app.MapControllers();
|
app.MapControllers();
|
||||||
|
|
|
||||||
|
|
@ -7,7 +7,8 @@
|
||||||
"dev": "vite",
|
"dev": "vite",
|
||||||
"build": "tsc -b && vite build",
|
"build": "tsc -b && vite build",
|
||||||
"lint": "eslint .",
|
"lint": "eslint .",
|
||||||
"preview": "vite preview"
|
"preview": "vite preview",
|
||||||
|
"gen:api": "openapi-typescript http://localhost:5081/swagger/v1/swagger.json -o src/lib/api.generated.ts"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@hookform/resolvers": "^5.2.2",
|
"@hookform/resolvers": "^5.2.2",
|
||||||
|
|
@ -40,6 +41,7 @@
|
||||||
"eslint-plugin-react-hooks": "^7.1.1",
|
"eslint-plugin-react-hooks": "^7.1.1",
|
||||||
"eslint-plugin-react-refresh": "^0.5.2",
|
"eslint-plugin-react-refresh": "^0.5.2",
|
||||||
"globals": "^17.5.0",
|
"globals": "^17.5.0",
|
||||||
|
"openapi-typescript": "^7.5.2",
|
||||||
"postcss": "^8.5.10",
|
"postcss": "^8.5.10",
|
||||||
"tailwindcss": "^4.2.3",
|
"tailwindcss": "^4.2.3",
|
||||||
"typescript": "~6.0.2",
|
"typescript": "~6.0.2",
|
||||||
|
|
|
||||||
|
|
@ -93,6 +93,9 @@ importers:
|
||||||
globals:
|
globals:
|
||||||
specifier: ^17.5.0
|
specifier: ^17.5.0
|
||||||
version: 17.5.0
|
version: 17.5.0
|
||||||
|
openapi-typescript:
|
||||||
|
specifier: ^7.5.2
|
||||||
|
version: 7.13.0(typescript@6.0.3)
|
||||||
postcss:
|
postcss:
|
||||||
specifier: ^8.5.10
|
specifier: ^8.5.10
|
||||||
version: 8.5.10
|
version: 8.5.10
|
||||||
|
|
@ -296,6 +299,16 @@ packages:
|
||||||
'@oxc-project/types@0.126.0':
|
'@oxc-project/types@0.126.0':
|
||||||
resolution: {integrity: sha512-oGfVtjAgwQVVpfBrbtk4e1XDyWHRFta6BS3GWVzrF8xYBT2VGQAk39yJS/wFSMrZqoiCU4oghT3Ch0HaHGIHcQ==}
|
resolution: {integrity: sha512-oGfVtjAgwQVVpfBrbtk4e1XDyWHRFta6BS3GWVzrF8xYBT2VGQAk39yJS/wFSMrZqoiCU4oghT3Ch0HaHGIHcQ==}
|
||||||
|
|
||||||
|
'@redocly/ajv@8.11.2':
|
||||||
|
resolution: {integrity: sha512-io1JpnwtIcvojV7QKDUSIuMN/ikdOUd1ReEnUnMKGfDVridQZ31J0MmIuqwuRjWDZfmvr+Q0MqCcfHM2gTivOg==}
|
||||||
|
|
||||||
|
'@redocly/config@0.22.0':
|
||||||
|
resolution: {integrity: sha512-gAy93Ddo01Z3bHuVdPWfCwzgfaYgMdaZPcfL7JZ7hWJoK9V0lXDbigTWkhiPFAaLWzbOJ+kbUQG1+XwIm0KRGQ==}
|
||||||
|
|
||||||
|
'@redocly/openapi-core@1.34.15':
|
||||||
|
resolution: {integrity: sha512-HAwCnNyKcs5XGQqms+9t7OdAPM/5TDstmhF+0i7tdCFato2QKuYIlyWETwkXd8c5zbltr1oB+6y9NTeQLr2d6Q==}
|
||||||
|
engines: {node: '>=18.17.0', npm: '>=9.5.0'}
|
||||||
|
|
||||||
'@reduxjs/toolkit@2.11.2':
|
'@reduxjs/toolkit@2.11.2':
|
||||||
resolution: {integrity: sha512-Kd6kAHTA6/nUpp8mySPqj3en3dm0tdMIgbttnQ1xFMVpufoj+ADi8pXLBsd4xzTRHQa7t/Jv8W5UnCuW4kuWMQ==}
|
resolution: {integrity: sha512-Kd6kAHTA6/nUpp8mySPqj3en3dm0tdMIgbttnQ1xFMVpufoj+ADi8pXLBsd4xzTRHQa7t/Jv8W5UnCuW4kuWMQ==}
|
||||||
peerDependencies:
|
peerDependencies:
|
||||||
|
|
@ -657,9 +670,17 @@ packages:
|
||||||
engines: {node: '>=0.4.0'}
|
engines: {node: '>=0.4.0'}
|
||||||
hasBin: true
|
hasBin: true
|
||||||
|
|
||||||
|
agent-base@7.1.4:
|
||||||
|
resolution: {integrity: sha512-MnA+YT8fwfJPgBx3m60MNqakm30XOkyIoH1y6huTQvC0PwZG7ki8NacLBcrPbNoo8vEZy7Jpuk7+jMO+CUovTQ==}
|
||||||
|
engines: {node: '>= 14'}
|
||||||
|
|
||||||
ajv@6.14.0:
|
ajv@6.14.0:
|
||||||
resolution: {integrity: sha512-IWrosm/yrn43eiKqkfkHis7QioDleaXQHdDVPKg0FSwwd/DuvyX79TZnFOnYpB7dcsFAMmtFztZuXPDvSePkFw==}
|
resolution: {integrity: sha512-IWrosm/yrn43eiKqkfkHis7QioDleaXQHdDVPKg0FSwwd/DuvyX79TZnFOnYpB7dcsFAMmtFztZuXPDvSePkFw==}
|
||||||
|
|
||||||
|
ansi-colors@4.1.3:
|
||||||
|
resolution: {integrity: sha512-/6w/C21Pm1A7aZitlI5Ni/2J6FFQN8i1Cvz3kHABAAbw93v/NlvKdVOqz7CCWz/3iv/JplRSEEZ83XION15ovw==}
|
||||||
|
engines: {node: '>=6'}
|
||||||
|
|
||||||
ansi-styles@4.3.0:
|
ansi-styles@4.3.0:
|
||||||
resolution: {integrity: sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==}
|
resolution: {integrity: sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==}
|
||||||
engines: {node: '>=8'}
|
engines: {node: '>=8'}
|
||||||
|
|
@ -695,6 +716,9 @@ packages:
|
||||||
brace-expansion@1.1.14:
|
brace-expansion@1.1.14:
|
||||||
resolution: {integrity: sha512-MWPGfDxnyzKU7rNOW9SP/c50vi3xrmrua/+6hfPbCS2ABNWfx24vPidzvC7krjU/RTo235sV776ymlsMtGKj8g==}
|
resolution: {integrity: sha512-MWPGfDxnyzKU7rNOW9SP/c50vi3xrmrua/+6hfPbCS2ABNWfx24vPidzvC7krjU/RTo235sV776ymlsMtGKj8g==}
|
||||||
|
|
||||||
|
brace-expansion@2.1.1:
|
||||||
|
resolution: {integrity: sha512-WR1cURNjuvBLMZBMbqM0UoE+WAfdUcEV1ccD8PVBVOI+Z3ND4+SZbN8RsfT2bMuG1qwz5RFvPukSZm5fF2D5eA==}
|
||||||
|
|
||||||
brace-expansion@5.0.5:
|
brace-expansion@5.0.5:
|
||||||
resolution: {integrity: sha512-VZznLgtwhn+Mact9tfiwx64fA9erHH/MCXEUfB/0bX/6Fz6ny5EGTXYltMocqg4xFAQZtnO3DHWWXi8RiuN7cQ==}
|
resolution: {integrity: sha512-VZznLgtwhn+Mact9tfiwx64fA9erHH/MCXEUfB/0bX/6Fz6ny5EGTXYltMocqg4xFAQZtnO3DHWWXi8RiuN7cQ==}
|
||||||
engines: {node: 18 || 20 || >=22}
|
engines: {node: 18 || 20 || >=22}
|
||||||
|
|
@ -719,6 +743,9 @@ packages:
|
||||||
resolution: {integrity: sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==}
|
resolution: {integrity: sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==}
|
||||||
engines: {node: '>=10'}
|
engines: {node: '>=10'}
|
||||||
|
|
||||||
|
change-case@5.4.4:
|
||||||
|
resolution: {integrity: sha512-HRQyTk2/YPEkt9TnUPbOpr64Uw3KOicFWPVBb+xiHvd6eBx/qPr9xqfBFDT8P2vWsvvz4jbEkfDe71W3VyNu2w==}
|
||||||
|
|
||||||
class-variance-authority@0.7.1:
|
class-variance-authority@0.7.1:
|
||||||
resolution: {integrity: sha512-Ka+9Trutv7G8M6WT6SeiRWz792K5qEqIGEGzXKhAE6xOWAY6pPH8U+9IY3oCMv6kqTmLsv7Xh/2w2RigkePMsg==}
|
resolution: {integrity: sha512-Ka+9Trutv7G8M6WT6SeiRWz792K5qEqIGEGzXKhAE6xOWAY6pPH8U+9IY3oCMv6kqTmLsv7Xh/2w2RigkePMsg==}
|
||||||
|
|
||||||
|
|
@ -733,6 +760,9 @@ packages:
|
||||||
color-name@1.1.4:
|
color-name@1.1.4:
|
||||||
resolution: {integrity: sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==}
|
resolution: {integrity: sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==}
|
||||||
|
|
||||||
|
colorette@1.4.0:
|
||||||
|
resolution: {integrity: sha512-Y2oEozpomLn7Q3HFP7dpww7AtMJplbM9lGZP6RDfHqmbeRjiwRg4n6VM6j4KLmRke85uWEI7JqF17f3pqdRA0g==}
|
||||||
|
|
||||||
combined-stream@1.0.8:
|
combined-stream@1.0.8:
|
||||||
resolution: {integrity: sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==}
|
resolution: {integrity: sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==}
|
||||||
engines: {node: '>= 0.8'}
|
engines: {node: '>= 0.8'}
|
||||||
|
|
@ -1032,6 +1062,10 @@ packages:
|
||||||
hermes-parser@0.25.1:
|
hermes-parser@0.25.1:
|
||||||
resolution: {integrity: sha512-6pEjquH3rqaI6cYAXYPcz9MS4rY6R4ngRgrgfDshRptUZIc3lw0MCIJIGDj9++mfySOuPTHB4nrSW99BCvOPIA==}
|
resolution: {integrity: sha512-6pEjquH3rqaI6cYAXYPcz9MS4rY6R4ngRgrgfDshRptUZIc3lw0MCIJIGDj9++mfySOuPTHB4nrSW99BCvOPIA==}
|
||||||
|
|
||||||
|
https-proxy-agent@7.0.6:
|
||||||
|
resolution: {integrity: sha512-vK9P5/iUfdl95AI+JVyUuIcVtd4ofvtrOr3HNtM2yxC9bnMbEdp3x01OhQNnjb8IJYi38VlTE3mBXwcfvywuSw==}
|
||||||
|
engines: {node: '>= 14'}
|
||||||
|
|
||||||
ignore@5.3.2:
|
ignore@5.3.2:
|
||||||
resolution: {integrity: sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g==}
|
resolution: {integrity: sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g==}
|
||||||
engines: {node: '>= 4'}
|
engines: {node: '>= 4'}
|
||||||
|
|
@ -1054,6 +1088,10 @@ packages:
|
||||||
resolution: {integrity: sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==}
|
resolution: {integrity: sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==}
|
||||||
engines: {node: '>=0.8.19'}
|
engines: {node: '>=0.8.19'}
|
||||||
|
|
||||||
|
index-to-position@1.2.0:
|
||||||
|
resolution: {integrity: sha512-Yg7+ztRkqslMAS2iFaU+Oa4KTSidr63OsFGlOrJoW981kIYO3CGCS3wA95P1mUi/IVSJkn0D479KTJpVpvFNuw==}
|
||||||
|
engines: {node: '>=18'}
|
||||||
|
|
||||||
internmap@2.0.3:
|
internmap@2.0.3:
|
||||||
resolution: {integrity: sha512-5Hh7Y1wQbvY5ooGgPbDaL5iYLAPzMTUrjMulskHLH6wnv/A+1q5rgEaiuqEjB+oxGXIVZs1FF+R/KPN3ZSQYYg==}
|
resolution: {integrity: sha512-5Hh7Y1wQbvY5ooGgPbDaL5iYLAPzMTUrjMulskHLH6wnv/A+1q5rgEaiuqEjB+oxGXIVZs1FF+R/KPN3ZSQYYg==}
|
||||||
engines: {node: '>=12'}
|
engines: {node: '>=12'}
|
||||||
|
|
@ -1073,6 +1111,10 @@ packages:
|
||||||
resolution: {integrity: sha512-ekilCSN1jwRvIbgeg/57YFh8qQDNbwDb9xT/qu2DAHbFFZUicIl4ygVaAvzveMhMVr3LnpSKTNnwt8PoOfmKhQ==}
|
resolution: {integrity: sha512-ekilCSN1jwRvIbgeg/57YFh8qQDNbwDb9xT/qu2DAHbFFZUicIl4ygVaAvzveMhMVr3LnpSKTNnwt8PoOfmKhQ==}
|
||||||
hasBin: true
|
hasBin: true
|
||||||
|
|
||||||
|
js-levenshtein@1.1.6:
|
||||||
|
resolution: {integrity: sha512-X2BB11YZtrRqY4EnQcLX5Rh373zbK4alC1FW7D7MBhL2gtcC17cTnr6DmfHZeS0s2rTHjUTMMHfG7gO8SSdw+g==}
|
||||||
|
engines: {node: '>=0.10.0'}
|
||||||
|
|
||||||
js-tokens@4.0.0:
|
js-tokens@4.0.0:
|
||||||
resolution: {integrity: sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==}
|
resolution: {integrity: sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==}
|
||||||
|
|
||||||
|
|
@ -1091,6 +1133,9 @@ packages:
|
||||||
json-schema-traverse@0.4.1:
|
json-schema-traverse@0.4.1:
|
||||||
resolution: {integrity: sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==}
|
resolution: {integrity: sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==}
|
||||||
|
|
||||||
|
json-schema-traverse@1.0.0:
|
||||||
|
resolution: {integrity: sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==}
|
||||||
|
|
||||||
json-stable-stringify-without-jsonify@1.0.1:
|
json-stable-stringify-without-jsonify@1.0.1:
|
||||||
resolution: {integrity: sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==}
|
resolution: {integrity: sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==}
|
||||||
|
|
||||||
|
|
@ -1217,6 +1262,10 @@ packages:
|
||||||
minimatch@3.1.5:
|
minimatch@3.1.5:
|
||||||
resolution: {integrity: sha512-VgjWUsnnT6n+NUk6eZq77zeFdpW2LWDzP6zFGrCbHXiYNul5Dzqk2HHQ5uFH2DNW5Xbp8+jVzaeNt94ssEEl4w==}
|
resolution: {integrity: sha512-VgjWUsnnT6n+NUk6eZq77zeFdpW2LWDzP6zFGrCbHXiYNul5Dzqk2HHQ5uFH2DNW5Xbp8+jVzaeNt94ssEEl4w==}
|
||||||
|
|
||||||
|
minimatch@5.1.9:
|
||||||
|
resolution: {integrity: sha512-7o1wEA2RyMP7Iu7GNba9vc0RWWGACJOCZBJX2GJWip0ikV+wcOsgVuY9uE8CPiyQhkGFSlhuSkZPavN7u1c2Fw==}
|
||||||
|
engines: {node: '>=10'}
|
||||||
|
|
||||||
ms@2.1.3:
|
ms@2.1.3:
|
||||||
resolution: {integrity: sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==}
|
resolution: {integrity: sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==}
|
||||||
|
|
||||||
|
|
@ -1231,6 +1280,12 @@ packages:
|
||||||
node-releases@2.0.37:
|
node-releases@2.0.37:
|
||||||
resolution: {integrity: sha512-1h5gKZCF+pO/o3Iqt5Jp7wc9rH3eJJ0+nh/CIoiRwjRxde/hAHyLPXYN4V3CqKAbiZPSeJFSWHmJsbkicta0Eg==}
|
resolution: {integrity: sha512-1h5gKZCF+pO/o3Iqt5Jp7wc9rH3eJJ0+nh/CIoiRwjRxde/hAHyLPXYN4V3CqKAbiZPSeJFSWHmJsbkicta0Eg==}
|
||||||
|
|
||||||
|
openapi-typescript@7.13.0:
|
||||||
|
resolution: {integrity: sha512-EFP392gcqXS7ntPvbhBzbF8TyBA+baIYEm791Hy5YkjDYKTnk/Tn5OQeKm5BIZvJihpp8Zzr4hzx0Irde1LNGQ==}
|
||||||
|
hasBin: true
|
||||||
|
peerDependencies:
|
||||||
|
typescript: ^5.x
|
||||||
|
|
||||||
optionator@0.9.4:
|
optionator@0.9.4:
|
||||||
resolution: {integrity: sha512-6IpQ7mKUxRcZNLIObR0hz7lxsapSSIYNZJwXPGeF0mTVqGKFIXj1DQcMoT22S3ROcLyY/rz0PWaWZ9ayWmad9g==}
|
resolution: {integrity: sha512-6IpQ7mKUxRcZNLIObR0hz7lxsapSSIYNZJwXPGeF0mTVqGKFIXj1DQcMoT22S3ROcLyY/rz0PWaWZ9ayWmad9g==}
|
||||||
engines: {node: '>= 0.8.0'}
|
engines: {node: '>= 0.8.0'}
|
||||||
|
|
@ -1247,6 +1302,10 @@ packages:
|
||||||
resolution: {integrity: sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==}
|
resolution: {integrity: sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==}
|
||||||
engines: {node: '>=6'}
|
engines: {node: '>=6'}
|
||||||
|
|
||||||
|
parse-json@8.3.0:
|
||||||
|
resolution: {integrity: sha512-ybiGyvspI+fAoRQbIPRddCcSTV9/LsJbf0e/S85VLowVGzRmokfneg2kwVW/KU5rOXrPSbF1qAKPMgNTqqROQQ==}
|
||||||
|
engines: {node: '>=18'}
|
||||||
|
|
||||||
path-exists@4.0.0:
|
path-exists@4.0.0:
|
||||||
resolution: {integrity: sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==}
|
resolution: {integrity: sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==}
|
||||||
engines: {node: '>=8'}
|
engines: {node: '>=8'}
|
||||||
|
|
@ -1262,6 +1321,10 @@ packages:
|
||||||
resolution: {integrity: sha512-QP88BAKvMam/3NxH6vj2o21R6MjxZUAd6nlwAS/pnGvN9IVLocLHxGYIzFhg6fUQ+5th6P4dv4eW9jX3DSIj7A==}
|
resolution: {integrity: sha512-QP88BAKvMam/3NxH6vj2o21R6MjxZUAd6nlwAS/pnGvN9IVLocLHxGYIzFhg6fUQ+5th6P4dv4eW9jX3DSIj7A==}
|
||||||
engines: {node: '>=12'}
|
engines: {node: '>=12'}
|
||||||
|
|
||||||
|
pluralize@8.0.0:
|
||||||
|
resolution: {integrity: sha512-Nc3IT5yHzflTfbjgqWcCPpo7DaKy4FnpB0l/zCAW0Tc7jxAiuqSxHasntB3D7887LSrA93kDJ9IXovxJYxyLCA==}
|
||||||
|
engines: {node: '>=4'}
|
||||||
|
|
||||||
postcss-value-parser@4.2.0:
|
postcss-value-parser@4.2.0:
|
||||||
resolution: {integrity: sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ==}
|
resolution: {integrity: sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ==}
|
||||||
|
|
||||||
|
|
@ -1354,6 +1417,10 @@ packages:
|
||||||
redux@5.0.1:
|
redux@5.0.1:
|
||||||
resolution: {integrity: sha512-M9/ELqF6fy8FwmkpnF0S3YKOqMyoWJ4+CS5Efg2ct3oY9daQvd/Pc71FpGZsVsbl3Cpb+IIcjBDUnnyBdQbq4w==}
|
resolution: {integrity: sha512-M9/ELqF6fy8FwmkpnF0S3YKOqMyoWJ4+CS5Efg2ct3oY9daQvd/Pc71FpGZsVsbl3Cpb+IIcjBDUnnyBdQbq4w==}
|
||||||
|
|
||||||
|
require-from-string@2.0.2:
|
||||||
|
resolution: {integrity: sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==}
|
||||||
|
engines: {node: '>=0.10.0'}
|
||||||
|
|
||||||
reselect@5.1.1:
|
reselect@5.1.1:
|
||||||
resolution: {integrity: sha512-K/BG6eIky/SBpzfHZv/dd+9JBFiS4SWV7FIujVyJRux6e45+73RaUHXLmIR1f7WOMaQ0U1km6qwklRQxpJJY0w==}
|
resolution: {integrity: sha512-K/BG6eIky/SBpzfHZv/dd+9JBFiS4SWV7FIujVyJRux6e45+73RaUHXLmIR1f7WOMaQ0U1km6qwklRQxpJJY0w==}
|
||||||
|
|
||||||
|
|
@ -1397,6 +1464,10 @@ packages:
|
||||||
resolution: {integrity: sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==}
|
resolution: {integrity: sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==}
|
||||||
engines: {node: '>=8'}
|
engines: {node: '>=8'}
|
||||||
|
|
||||||
|
supports-color@10.2.2:
|
||||||
|
resolution: {integrity: sha512-SS+jx45GF1QjgEXQx4NJZV9ImqmO2NPz5FNsIHrsDjh2YsHnawpan7SNQ1o8NuhrbHZy9AZhIoCUiCeaW/C80g==}
|
||||||
|
engines: {node: '>=18'}
|
||||||
|
|
||||||
supports-color@7.2.0:
|
supports-color@7.2.0:
|
||||||
resolution: {integrity: sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==}
|
resolution: {integrity: sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==}
|
||||||
engines: {node: '>=8'}
|
engines: {node: '>=8'}
|
||||||
|
|
@ -1439,6 +1510,10 @@ packages:
|
||||||
resolution: {integrity: sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==}
|
resolution: {integrity: sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==}
|
||||||
engines: {node: '>= 0.8.0'}
|
engines: {node: '>= 0.8.0'}
|
||||||
|
|
||||||
|
type-fest@4.41.0:
|
||||||
|
resolution: {integrity: sha512-TeTSQ6H5YHvpqVwBRcnLDCBnDOHWYu7IvGbHT6N8AOymcr9PJGjc1GTtiWZTYg0NCgYwvnYWEkVChQAr9bjfwA==}
|
||||||
|
engines: {node: '>=16'}
|
||||||
|
|
||||||
typescript-eslint@8.59.0:
|
typescript-eslint@8.59.0:
|
||||||
resolution: {integrity: sha512-BU3ONW9X+v90EcCH9ZS6LMackcVtxRLlI3XrYyqZIwVSHIk7Qf7bFw1z0M9Q0IUxhTMZCf8piY9hTYaNEIASrw==}
|
resolution: {integrity: sha512-BU3ONW9X+v90EcCH9ZS6LMackcVtxRLlI3XrYyqZIwVSHIk7Qf7bFw1z0M9Q0IUxhTMZCf8piY9hTYaNEIASrw==}
|
||||||
engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
|
engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
|
||||||
|
|
@ -1460,6 +1535,9 @@ packages:
|
||||||
peerDependencies:
|
peerDependencies:
|
||||||
browserslist: '>= 4.21.0'
|
browserslist: '>= 4.21.0'
|
||||||
|
|
||||||
|
uri-js-replace@1.0.1:
|
||||||
|
resolution: {integrity: sha512-W+C9NWNLFOoBI2QWDp4UT9pv65r2w5Cx+3sTYFvtMdDBxkKt1syCqsUdSFAChbEe1uK5TfS04wt/nGwmaeIQ0g==}
|
||||||
|
|
||||||
uri-js@4.4.1:
|
uri-js@4.4.1:
|
||||||
resolution: {integrity: sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==}
|
resolution: {integrity: sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==}
|
||||||
|
|
||||||
|
|
@ -1526,6 +1604,13 @@ packages:
|
||||||
yallist@3.1.1:
|
yallist@3.1.1:
|
||||||
resolution: {integrity: sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==}
|
resolution: {integrity: sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==}
|
||||||
|
|
||||||
|
yaml-ast-parser@0.0.43:
|
||||||
|
resolution: {integrity: sha512-2PTINUwsRqSd+s8XxKaJWQlUuEMHJQyEuh2edBbW8KNJz0SJPwUSD2zRWqezFEdN7IzAgeuYHFUCF7o8zRdZ0A==}
|
||||||
|
|
||||||
|
yargs-parser@21.1.1:
|
||||||
|
resolution: {integrity: sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==}
|
||||||
|
engines: {node: '>=12'}
|
||||||
|
|
||||||
yocto-queue@0.1.0:
|
yocto-queue@0.1.0:
|
||||||
resolution: {integrity: sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==}
|
resolution: {integrity: sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==}
|
||||||
engines: {node: '>=10'}
|
engines: {node: '>=10'}
|
||||||
|
|
@ -1562,7 +1647,7 @@ snapshots:
|
||||||
'@babel/types': 7.29.0
|
'@babel/types': 7.29.0
|
||||||
'@jridgewell/remapping': 2.3.5
|
'@jridgewell/remapping': 2.3.5
|
||||||
convert-source-map: 2.0.0
|
convert-source-map: 2.0.0
|
||||||
debug: 4.4.3
|
debug: 4.4.3(supports-color@10.2.2)
|
||||||
gensync: 1.0.0-beta.2
|
gensync: 1.0.0-beta.2
|
||||||
json5: 2.2.3
|
json5: 2.2.3
|
||||||
semver: 6.3.1
|
semver: 6.3.1
|
||||||
|
|
@ -1632,7 +1717,7 @@ snapshots:
|
||||||
'@babel/parser': 7.29.2
|
'@babel/parser': 7.29.2
|
||||||
'@babel/template': 7.28.6
|
'@babel/template': 7.28.6
|
||||||
'@babel/types': 7.29.0
|
'@babel/types': 7.29.0
|
||||||
debug: 4.4.3
|
debug: 4.4.3(supports-color@10.2.2)
|
||||||
transitivePeerDependencies:
|
transitivePeerDependencies:
|
||||||
- supports-color
|
- supports-color
|
||||||
|
|
||||||
|
|
@ -1667,7 +1752,7 @@ snapshots:
|
||||||
'@eslint/config-array@0.21.2':
|
'@eslint/config-array@0.21.2':
|
||||||
dependencies:
|
dependencies:
|
||||||
'@eslint/object-schema': 2.1.7
|
'@eslint/object-schema': 2.1.7
|
||||||
debug: 4.4.3
|
debug: 4.4.3(supports-color@10.2.2)
|
||||||
minimatch: 3.1.5
|
minimatch: 3.1.5
|
||||||
transitivePeerDependencies:
|
transitivePeerDependencies:
|
||||||
- supports-color
|
- supports-color
|
||||||
|
|
@ -1683,7 +1768,7 @@ snapshots:
|
||||||
'@eslint/eslintrc@3.3.5':
|
'@eslint/eslintrc@3.3.5':
|
||||||
dependencies:
|
dependencies:
|
||||||
ajv: 6.14.0
|
ajv: 6.14.0
|
||||||
debug: 4.4.3
|
debug: 4.4.3(supports-color@10.2.2)
|
||||||
espree: 10.4.0
|
espree: 10.4.0
|
||||||
globals: 14.0.0
|
globals: 14.0.0
|
||||||
ignore: 5.3.2
|
ignore: 5.3.2
|
||||||
|
|
@ -1777,6 +1862,29 @@ snapshots:
|
||||||
|
|
||||||
'@oxc-project/types@0.126.0': {}
|
'@oxc-project/types@0.126.0': {}
|
||||||
|
|
||||||
|
'@redocly/ajv@8.11.2':
|
||||||
|
dependencies:
|
||||||
|
fast-deep-equal: 3.1.3
|
||||||
|
json-schema-traverse: 1.0.0
|
||||||
|
require-from-string: 2.0.2
|
||||||
|
uri-js-replace: 1.0.1
|
||||||
|
|
||||||
|
'@redocly/config@0.22.0': {}
|
||||||
|
|
||||||
|
'@redocly/openapi-core@1.34.15(supports-color@10.2.2)':
|
||||||
|
dependencies:
|
||||||
|
'@redocly/ajv': 8.11.2
|
||||||
|
'@redocly/config': 0.22.0
|
||||||
|
colorette: 1.4.0
|
||||||
|
https-proxy-agent: 7.0.6(supports-color@10.2.2)
|
||||||
|
js-levenshtein: 1.1.6
|
||||||
|
js-yaml: 4.1.1
|
||||||
|
minimatch: 5.1.9
|
||||||
|
pluralize: 8.0.0
|
||||||
|
yaml-ast-parser: 0.0.43
|
||||||
|
transitivePeerDependencies:
|
||||||
|
- supports-color
|
||||||
|
|
||||||
'@reduxjs/toolkit@2.11.2(react-redux@9.2.0(@types/react@19.2.14)(react@19.2.5)(redux@5.0.1))(react@19.2.5)':
|
'@reduxjs/toolkit@2.11.2(react-redux@9.2.0(@types/react@19.2.14)(react@19.2.5)(redux@5.0.1))(react@19.2.5)':
|
||||||
dependencies:
|
dependencies:
|
||||||
'@standard-schema/spec': 1.1.0
|
'@standard-schema/spec': 1.1.0
|
||||||
|
|
@ -1998,7 +2106,7 @@ snapshots:
|
||||||
'@typescript-eslint/types': 8.59.0
|
'@typescript-eslint/types': 8.59.0
|
||||||
'@typescript-eslint/typescript-estree': 8.59.0(typescript@6.0.3)
|
'@typescript-eslint/typescript-estree': 8.59.0(typescript@6.0.3)
|
||||||
'@typescript-eslint/visitor-keys': 8.59.0
|
'@typescript-eslint/visitor-keys': 8.59.0
|
||||||
debug: 4.4.3
|
debug: 4.4.3(supports-color@10.2.2)
|
||||||
eslint: 9.39.4(jiti@2.6.1)
|
eslint: 9.39.4(jiti@2.6.1)
|
||||||
typescript: 6.0.3
|
typescript: 6.0.3
|
||||||
transitivePeerDependencies:
|
transitivePeerDependencies:
|
||||||
|
|
@ -2008,7 +2116,7 @@ snapshots:
|
||||||
dependencies:
|
dependencies:
|
||||||
'@typescript-eslint/tsconfig-utils': 8.59.0(typescript@6.0.3)
|
'@typescript-eslint/tsconfig-utils': 8.59.0(typescript@6.0.3)
|
||||||
'@typescript-eslint/types': 8.59.0
|
'@typescript-eslint/types': 8.59.0
|
||||||
debug: 4.4.3
|
debug: 4.4.3(supports-color@10.2.2)
|
||||||
typescript: 6.0.3
|
typescript: 6.0.3
|
||||||
transitivePeerDependencies:
|
transitivePeerDependencies:
|
||||||
- supports-color
|
- supports-color
|
||||||
|
|
@ -2027,7 +2135,7 @@ snapshots:
|
||||||
'@typescript-eslint/types': 8.59.0
|
'@typescript-eslint/types': 8.59.0
|
||||||
'@typescript-eslint/typescript-estree': 8.59.0(typescript@6.0.3)
|
'@typescript-eslint/typescript-estree': 8.59.0(typescript@6.0.3)
|
||||||
'@typescript-eslint/utils': 8.59.0(eslint@9.39.4(jiti@2.6.1))(typescript@6.0.3)
|
'@typescript-eslint/utils': 8.59.0(eslint@9.39.4(jiti@2.6.1))(typescript@6.0.3)
|
||||||
debug: 4.4.3
|
debug: 4.4.3(supports-color@10.2.2)
|
||||||
eslint: 9.39.4(jiti@2.6.1)
|
eslint: 9.39.4(jiti@2.6.1)
|
||||||
ts-api-utils: 2.5.0(typescript@6.0.3)
|
ts-api-utils: 2.5.0(typescript@6.0.3)
|
||||||
typescript: 6.0.3
|
typescript: 6.0.3
|
||||||
|
|
@ -2042,7 +2150,7 @@ snapshots:
|
||||||
'@typescript-eslint/tsconfig-utils': 8.59.0(typescript@6.0.3)
|
'@typescript-eslint/tsconfig-utils': 8.59.0(typescript@6.0.3)
|
||||||
'@typescript-eslint/types': 8.59.0
|
'@typescript-eslint/types': 8.59.0
|
||||||
'@typescript-eslint/visitor-keys': 8.59.0
|
'@typescript-eslint/visitor-keys': 8.59.0
|
||||||
debug: 4.4.3
|
debug: 4.4.3(supports-color@10.2.2)
|
||||||
minimatch: 10.2.5
|
minimatch: 10.2.5
|
||||||
semver: 7.7.4
|
semver: 7.7.4
|
||||||
tinyglobby: 0.2.16
|
tinyglobby: 0.2.16
|
||||||
|
|
@ -2078,6 +2186,8 @@ snapshots:
|
||||||
|
|
||||||
acorn@8.16.0: {}
|
acorn@8.16.0: {}
|
||||||
|
|
||||||
|
agent-base@7.1.4: {}
|
||||||
|
|
||||||
ajv@6.14.0:
|
ajv@6.14.0:
|
||||||
dependencies:
|
dependencies:
|
||||||
fast-deep-equal: 3.1.3
|
fast-deep-equal: 3.1.3
|
||||||
|
|
@ -2085,6 +2195,8 @@ snapshots:
|
||||||
json-schema-traverse: 0.4.1
|
json-schema-traverse: 0.4.1
|
||||||
uri-js: 4.4.1
|
uri-js: 4.4.1
|
||||||
|
|
||||||
|
ansi-colors@4.1.3: {}
|
||||||
|
|
||||||
ansi-styles@4.3.0:
|
ansi-styles@4.3.0:
|
||||||
dependencies:
|
dependencies:
|
||||||
color-convert: 2.0.1
|
color-convert: 2.0.1
|
||||||
|
|
@ -2121,6 +2233,10 @@ snapshots:
|
||||||
balanced-match: 1.0.2
|
balanced-match: 1.0.2
|
||||||
concat-map: 0.0.1
|
concat-map: 0.0.1
|
||||||
|
|
||||||
|
brace-expansion@2.1.1:
|
||||||
|
dependencies:
|
||||||
|
balanced-match: 1.0.2
|
||||||
|
|
||||||
brace-expansion@5.0.5:
|
brace-expansion@5.0.5:
|
||||||
dependencies:
|
dependencies:
|
||||||
balanced-match: 4.0.4
|
balanced-match: 4.0.4
|
||||||
|
|
@ -2147,6 +2263,8 @@ snapshots:
|
||||||
ansi-styles: 4.3.0
|
ansi-styles: 4.3.0
|
||||||
supports-color: 7.2.0
|
supports-color: 7.2.0
|
||||||
|
|
||||||
|
change-case@5.4.4: {}
|
||||||
|
|
||||||
class-variance-authority@0.7.1:
|
class-variance-authority@0.7.1:
|
||||||
dependencies:
|
dependencies:
|
||||||
clsx: 2.1.1
|
clsx: 2.1.1
|
||||||
|
|
@ -2159,6 +2277,8 @@ snapshots:
|
||||||
|
|
||||||
color-name@1.1.4: {}
|
color-name@1.1.4: {}
|
||||||
|
|
||||||
|
colorette@1.4.0: {}
|
||||||
|
|
||||||
combined-stream@1.0.8:
|
combined-stream@1.0.8:
|
||||||
dependencies:
|
dependencies:
|
||||||
delayed-stream: 1.0.0
|
delayed-stream: 1.0.0
|
||||||
|
|
@ -2217,9 +2337,11 @@ snapshots:
|
||||||
|
|
||||||
date-fns@4.1.0: {}
|
date-fns@4.1.0: {}
|
||||||
|
|
||||||
debug@4.4.3:
|
debug@4.4.3(supports-color@10.2.2):
|
||||||
dependencies:
|
dependencies:
|
||||||
ms: 2.1.3
|
ms: 2.1.3
|
||||||
|
optionalDependencies:
|
||||||
|
supports-color: 10.2.2
|
||||||
|
|
||||||
decimal.js-light@2.5.1: {}
|
decimal.js-light@2.5.1: {}
|
||||||
|
|
||||||
|
|
@ -2306,7 +2428,7 @@ snapshots:
|
||||||
ajv: 6.14.0
|
ajv: 6.14.0
|
||||||
chalk: 4.1.2
|
chalk: 4.1.2
|
||||||
cross-spawn: 7.0.6
|
cross-spawn: 7.0.6
|
||||||
debug: 4.4.3
|
debug: 4.4.3(supports-color@10.2.2)
|
||||||
escape-string-regexp: 4.0.0
|
escape-string-regexp: 4.0.0
|
||||||
eslint-scope: 8.4.0
|
eslint-scope: 8.4.0
|
||||||
eslint-visitor-keys: 4.2.1
|
eslint-visitor-keys: 4.2.1
|
||||||
|
|
@ -2443,6 +2565,13 @@ snapshots:
|
||||||
dependencies:
|
dependencies:
|
||||||
hermes-estree: 0.25.1
|
hermes-estree: 0.25.1
|
||||||
|
|
||||||
|
https-proxy-agent@7.0.6(supports-color@10.2.2):
|
||||||
|
dependencies:
|
||||||
|
agent-base: 7.1.4
|
||||||
|
debug: 4.4.3(supports-color@10.2.2)
|
||||||
|
transitivePeerDependencies:
|
||||||
|
- supports-color
|
||||||
|
|
||||||
ignore@5.3.2: {}
|
ignore@5.3.2: {}
|
||||||
|
|
||||||
ignore@7.0.5: {}
|
ignore@7.0.5: {}
|
||||||
|
|
@ -2458,6 +2587,8 @@ snapshots:
|
||||||
|
|
||||||
imurmurhash@0.1.4: {}
|
imurmurhash@0.1.4: {}
|
||||||
|
|
||||||
|
index-to-position@1.2.0: {}
|
||||||
|
|
||||||
internmap@2.0.3: {}
|
internmap@2.0.3: {}
|
||||||
|
|
||||||
is-extglob@2.1.1: {}
|
is-extglob@2.1.1: {}
|
||||||
|
|
@ -2470,6 +2601,8 @@ snapshots:
|
||||||
|
|
||||||
jiti@2.6.1: {}
|
jiti@2.6.1: {}
|
||||||
|
|
||||||
|
js-levenshtein@1.1.6: {}
|
||||||
|
|
||||||
js-tokens@4.0.0: {}
|
js-tokens@4.0.0: {}
|
||||||
|
|
||||||
js-yaml@4.1.1:
|
js-yaml@4.1.1:
|
||||||
|
|
@ -2482,6 +2615,8 @@ snapshots:
|
||||||
|
|
||||||
json-schema-traverse@0.4.1: {}
|
json-schema-traverse@0.4.1: {}
|
||||||
|
|
||||||
|
json-schema-traverse@1.0.0: {}
|
||||||
|
|
||||||
json-stable-stringify-without-jsonify@1.0.1: {}
|
json-stable-stringify-without-jsonify@1.0.1: {}
|
||||||
|
|
||||||
json5@2.2.3: {}
|
json5@2.2.3: {}
|
||||||
|
|
@ -2578,6 +2713,10 @@ snapshots:
|
||||||
dependencies:
|
dependencies:
|
||||||
brace-expansion: 1.1.14
|
brace-expansion: 1.1.14
|
||||||
|
|
||||||
|
minimatch@5.1.9:
|
||||||
|
dependencies:
|
||||||
|
brace-expansion: 2.1.1
|
||||||
|
|
||||||
ms@2.1.3: {}
|
ms@2.1.3: {}
|
||||||
|
|
||||||
nanoid@3.3.11: {}
|
nanoid@3.3.11: {}
|
||||||
|
|
@ -2586,6 +2725,16 @@ snapshots:
|
||||||
|
|
||||||
node-releases@2.0.37: {}
|
node-releases@2.0.37: {}
|
||||||
|
|
||||||
|
openapi-typescript@7.13.0(typescript@6.0.3):
|
||||||
|
dependencies:
|
||||||
|
'@redocly/openapi-core': 1.34.15(supports-color@10.2.2)
|
||||||
|
ansi-colors: 4.1.3
|
||||||
|
change-case: 5.4.4
|
||||||
|
parse-json: 8.3.0
|
||||||
|
supports-color: 10.2.2
|
||||||
|
typescript: 6.0.3
|
||||||
|
yargs-parser: 21.1.1
|
||||||
|
|
||||||
optionator@0.9.4:
|
optionator@0.9.4:
|
||||||
dependencies:
|
dependencies:
|
||||||
deep-is: 0.1.4
|
deep-is: 0.1.4
|
||||||
|
|
@ -2607,6 +2756,12 @@ snapshots:
|
||||||
dependencies:
|
dependencies:
|
||||||
callsites: 3.1.0
|
callsites: 3.1.0
|
||||||
|
|
||||||
|
parse-json@8.3.0:
|
||||||
|
dependencies:
|
||||||
|
'@babel/code-frame': 7.29.0
|
||||||
|
index-to-position: 1.2.0
|
||||||
|
type-fest: 4.41.0
|
||||||
|
|
||||||
path-exists@4.0.0: {}
|
path-exists@4.0.0: {}
|
||||||
|
|
||||||
path-key@3.1.1: {}
|
path-key@3.1.1: {}
|
||||||
|
|
@ -2615,6 +2770,8 @@ snapshots:
|
||||||
|
|
||||||
picomatch@4.0.4: {}
|
picomatch@4.0.4: {}
|
||||||
|
|
||||||
|
pluralize@8.0.0: {}
|
||||||
|
|
||||||
postcss-value-parser@4.2.0: {}
|
postcss-value-parser@4.2.0: {}
|
||||||
|
|
||||||
postcss@8.5.10:
|
postcss@8.5.10:
|
||||||
|
|
@ -2699,6 +2856,8 @@ snapshots:
|
||||||
|
|
||||||
redux@5.0.1: {}
|
redux@5.0.1: {}
|
||||||
|
|
||||||
|
require-from-string@2.0.2: {}
|
||||||
|
|
||||||
reselect@5.1.1: {}
|
reselect@5.1.1: {}
|
||||||
|
|
||||||
resolve-from@4.0.0: {}
|
resolve-from@4.0.0: {}
|
||||||
|
|
@ -2742,6 +2901,8 @@ snapshots:
|
||||||
|
|
||||||
strip-json-comments@3.1.1: {}
|
strip-json-comments@3.1.1: {}
|
||||||
|
|
||||||
|
supports-color@10.2.2: {}
|
||||||
|
|
||||||
supports-color@7.2.0:
|
supports-color@7.2.0:
|
||||||
dependencies:
|
dependencies:
|
||||||
has-flag: 4.0.0
|
has-flag: 4.0.0
|
||||||
|
|
@ -2776,6 +2937,8 @@ snapshots:
|
||||||
dependencies:
|
dependencies:
|
||||||
prelude-ls: 1.2.1
|
prelude-ls: 1.2.1
|
||||||
|
|
||||||
|
type-fest@4.41.0: {}
|
||||||
|
|
||||||
typescript-eslint@8.59.0(eslint@9.39.4(jiti@2.6.1))(typescript@6.0.3):
|
typescript-eslint@8.59.0(eslint@9.39.4(jiti@2.6.1))(typescript@6.0.3):
|
||||||
dependencies:
|
dependencies:
|
||||||
'@typescript-eslint/eslint-plugin': 8.59.0(@typescript-eslint/parser@8.59.0(eslint@9.39.4(jiti@2.6.1))(typescript@6.0.3))(eslint@9.39.4(jiti@2.6.1))(typescript@6.0.3)
|
'@typescript-eslint/eslint-plugin': 8.59.0(@typescript-eslint/parser@8.59.0(eslint@9.39.4(jiti@2.6.1))(typescript@6.0.3))(eslint@9.39.4(jiti@2.6.1))(typescript@6.0.3)
|
||||||
|
|
@ -2797,6 +2960,8 @@ snapshots:
|
||||||
escalade: 3.2.0
|
escalade: 3.2.0
|
||||||
picocolors: 1.1.1
|
picocolors: 1.1.1
|
||||||
|
|
||||||
|
uri-js-replace@1.0.1: {}
|
||||||
|
|
||||||
uri-js@4.4.1:
|
uri-js@4.4.1:
|
||||||
dependencies:
|
dependencies:
|
||||||
punycode: 2.3.1
|
punycode: 2.3.1
|
||||||
|
|
@ -2842,6 +3007,10 @@ snapshots:
|
||||||
|
|
||||||
yallist@3.1.1: {}
|
yallist@3.1.1: {}
|
||||||
|
|
||||||
|
yaml-ast-parser@0.0.43: {}
|
||||||
|
|
||||||
|
yargs-parser@21.1.1: {}
|
||||||
|
|
||||||
yocto-queue@0.1.0: {}
|
yocto-queue@0.1.0: {}
|
||||||
|
|
||||||
zod-validation-error@4.0.2(zod@4.3.6):
|
zod-validation-error@4.0.2(zod@4.3.6):
|
||||||
|
|
|
||||||
7745
src/food-market.web/src/lib/api.generated.ts
Normal file
7745
src/food-market.web/src/lib/api.generated.ts
Normal file
File diff suppressed because it is too large
Load diff
53
src/food-market.web/src/lib/apiClient.ts
Normal file
53
src/food-market.web/src/lib/apiClient.ts
Normal file
|
|
@ -0,0 +1,53 @@
|
||||||
|
/**
|
||||||
|
* Тонкая обёртка над axios `api`, использующая типы из api.generated.ts
|
||||||
|
* (сгенерированы из /swagger/v1/swagger.json через openapi-typescript).
|
||||||
|
*
|
||||||
|
* Регенерация:
|
||||||
|
* 1. dotnet run --project src/food-market.api (или просто запущенный API в dev)
|
||||||
|
* 2. cd src/food-market.web && pnpm run gen:api
|
||||||
|
* → перезаписывает src/lib/api.generated.ts
|
||||||
|
*
|
||||||
|
* Эта обёртка демонстрирует подключение для пары контроллеров (reports/sales,
|
||||||
|
* reports/abc) как образец миграции с ручных типов. Остальные страницы
|
||||||
|
* пользуются явными типами из `types.ts` — постепенная миграция в новом коде.
|
||||||
|
*
|
||||||
|
* Multi-tenant: контроллеры на API-стороне применяют tenant query-filter
|
||||||
|
* автоматически, обёртка ничего не делает специального — только подставляет
|
||||||
|
* Authorization-токен (через axios interceptor в `api.ts`).
|
||||||
|
*/
|
||||||
|
import { api } from './api'
|
||||||
|
import type { components, paths } from './api.generated'
|
||||||
|
|
||||||
|
/** Типы DTO, переэкспорт из generated для удобства импорта на страницах. */
|
||||||
|
export type SalesReportRowDto = components['schemas']['Reports_SalesReportController_SalesRow']
|
||||||
|
export type AbcReportRowDto = components['schemas']['Reports_AbcReportController_AbcRow']
|
||||||
|
export type ProfitReportRowDto = components['schemas']['Reports_ProfitReportController_ProfitRow']
|
||||||
|
|
||||||
|
type SalesQuery = NonNullable<paths['/api/reports/sales']['get']['parameters']['query']>
|
||||||
|
type AbcQuery = NonNullable<paths['/api/reports/abc']['get']['parameters']['query']>
|
||||||
|
type ProfitQuery = NonNullable<paths['/api/reports/profit']['get']['parameters']['query']>
|
||||||
|
|
||||||
|
function qs(params: Record<string, unknown>): string {
|
||||||
|
const p = new URLSearchParams()
|
||||||
|
for (const [k, v] of Object.entries(params)) {
|
||||||
|
if (v == null || v === '') continue
|
||||||
|
p.set(k, v instanceof Date ? v.toISOString() : String(v))
|
||||||
|
}
|
||||||
|
return p.toString()
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Тонкие хелперы, типизированные через generated types. */
|
||||||
|
export const reports = {
|
||||||
|
async sales(params: SalesQuery): Promise<SalesReportRowDto[]> {
|
||||||
|
const { data } = await api.get<SalesReportRowDto[]>(`/api/reports/sales?${qs(params)}`)
|
||||||
|
return data
|
||||||
|
},
|
||||||
|
async abc(params: AbcQuery): Promise<AbcReportRowDto[]> {
|
||||||
|
const { data } = await api.get<AbcReportRowDto[]>(`/api/reports/abc?${qs(params)}`)
|
||||||
|
return data
|
||||||
|
},
|
||||||
|
async profit(params: ProfitQuery): Promise<ProfitReportRowDto[]> {
|
||||||
|
const { data } = await api.get<ProfitReportRowDto[]>(`/api/reports/profit?${qs(params)}`)
|
||||||
|
return data
|
||||||
|
},
|
||||||
|
}
|
||||||
Loading…
Reference in a new issue