diff --git a/examples/cross-integration/app-a/procedures/integrations/notification-service/notifications-list-rest.gen.ts b/examples/cross-integration/app-a/procedures/integrations/notification-service/notifications-list-rest.gen.ts deleted file mode 100644 index e5e43f7..0000000 --- a/examples/cross-integration/app-a/procedures/integrations/notification-service/notifications-list-rest.gen.ts +++ /dev/null @@ -1,57 +0,0 @@ -// This file is auto-generated by c4c integrate command -// Do not edit manually. - -import { applyPolicies, type Procedure, type Contract } from "@c4c/core"; -import { withOAuth, getOAuthHeaders } from "@c4c/policies"; -import * as sdk from "../../../generated/notification-service/sdk.gen.js"; -import { createClient, createConfig } from "@hey-api/client-fetch"; -import { z } from "zod"; - -export const NotificationsListRestContract: Contract = { - name: "notification-service.notifications.list.rest", - description: "List all notifications", - input: z.unknown(), - output: z.unknown(), - metadata: { - exposure: "external" as const, - roles: ["api-endpoint", "workflow-node"], - provider: "notification-service", - operation: "notificationsListRest", - tags: ["notification-service"], - }, -}; - -const notificationsListRestHandler = applyPolicies( - async (input, context) => { - const baseUrl = process.env.NOTIFICATION_SERVICE_URL || context.metadata?.['notification-serviceUrl'] as string | undefined; - if (!baseUrl) { - throw new Error(`NOTIFICATION_SERVICE_URL environment variable is not set`); - } - - const headers = getOAuthHeaders(context, "notification-service"); - - // Create custom client with proper baseURL configuration - const customClient = createClient(createConfig({ baseUrl })); - - const result = await sdk.notificationsListRest({ - body: input, - headers, - client: customClient - } as any); - - if (result && typeof result === "object" && "data" in result) { - return (result as { data: unknown }).data; - } - return result as unknown; - }, - withOAuth({ - provider: "notification-service", - metadataTokenKey: "notification-serviceToken", - envVar: "NOTIFICATION_SERVICE_TOKEN", - }) -); - -export const NotificationsListRestProcedure: Procedure = { - contract: NotificationsListRestContract, - handler: notificationsListRestHandler, -}; diff --git a/examples/cross-integration/app-a/procedures/integrations/notification-service/notifications-list.gen.ts b/examples/cross-integration/app-a/procedures/integrations/notification-service/notifications-list.gen.ts deleted file mode 100644 index 07d4127..0000000 --- a/examples/cross-integration/app-a/procedures/integrations/notification-service/notifications-list.gen.ts +++ /dev/null @@ -1,74 +0,0 @@ -// This file is auto-generated by c4c integrate command -// Do not edit manually. - -import { applyPolicies, type Procedure, type Contract } from "@c4c/core"; -import { withOAuth, getOAuthHeaders } from "@c4c/policies"; -import * as sdk from "../../../generated/notification-service/sdk.gen.js"; -import { createClient, createConfig } from "@hey-api/client-fetch"; -import { z } from "zod"; - -export const NotificationsListContract: Contract = { - name: "notification-service.notifications.list", - description: "List all notifications", - input: z.object({ - recipient: z.string().optional(), - status: z.enum(["pending", "sent", "failed"]).optional(), - limit: z.number().optional() -}), - output: z.object({ - notifications: z.array(z.object({ - id: z.string(), - message: z.string(), - recipient: z.string().optional(), - channel: z.enum(["email", "sms", "push", "webhook"]), - priority: z.enum(["low", "normal", "high", "urgent"]), - status: z.enum(["pending", "sent", "failed"]), - metadata: z.record(z.string(), z.unknown()).optional(), - sentAt: z.string().optional(), - createdAt: z.string() -})), - total: z.number() -}), - metadata: { - exposure: "external" as const, - roles: ["api-endpoint", "workflow-node"], - provider: "notification-service", - operation: "notificationsList", - tags: ["notification-service"], - }, -}; - -const notificationsListHandler = applyPolicies( - async (input, context) => { - const baseUrl = process.env.NOTIFICATION_SERVICE_URL || context.metadata?.['notification-serviceUrl'] as string | undefined; - if (!baseUrl) { - throw new Error(`NOTIFICATION_SERVICE_URL environment variable is not set`); - } - - const headers = getOAuthHeaders(context, "notification-service"); - - // Create custom client with proper baseURL configuration - const customClient = createClient(createConfig({ baseUrl })); - - const result = await sdk.notificationsList({ - body: input, - headers, - client: customClient - } as any); - - if (result && typeof result === "object" && "data" in result) { - return (result as { data: unknown }).data; - } - return result as unknown; - }, - withOAuth({ - provider: "notification-service", - metadataTokenKey: "notification-serviceToken", - envVar: "NOTIFICATION_SERVICE_TOKEN", - }) -); - -export const NotificationsListProcedure: Procedure = { - contract: NotificationsListContract, - handler: notificationsListHandler, -}; diff --git a/examples/cross-integration/app-a/procedures/integrations/notification-service/notifications-send.gen.ts b/examples/cross-integration/app-a/procedures/integrations/notification-service/notifications-send.gen.ts deleted file mode 100644 index e77c8cf..0000000 --- a/examples/cross-integration/app-a/procedures/integrations/notification-service/notifications-send.gen.ts +++ /dev/null @@ -1,73 +0,0 @@ -// This file is auto-generated by c4c integrate command -// Do not edit manually. - -import { applyPolicies, type Procedure, type Contract } from "@c4c/core"; -import { withOAuth, getOAuthHeaders } from "@c4c/policies"; -import * as sdk from "../../../generated/notification-service/sdk.gen.js"; -import { createClient, createConfig } from "@hey-api/client-fetch"; -import { z } from "zod"; - -export const NotificationsSendContract: Contract = { - name: "notification-service.notifications.send", - description: "Send a notification", - input: z.object({ - message: z.string().min(1), - recipient: z.string().optional(), - channel: z.enum(["email", "sms", "push", "webhook"]).optional(), - priority: z.enum(["low", "normal", "high", "urgent"]).optional(), - metadata: z.record(z.string(), z.unknown()).optional() -}), - output: z.object({ - id: z.string(), - message: z.string(), - recipient: z.string().optional(), - channel: z.enum(["email", "sms", "push", "webhook"]), - priority: z.enum(["low", "normal", "high", "urgent"]), - status: z.enum(["pending", "sent", "failed"]), - metadata: z.record(z.string(), z.unknown()).optional(), - sentAt: z.string().optional(), - createdAt: z.string() -}), - metadata: { - exposure: "external" as const, - roles: ["api-endpoint", "workflow-node"], - provider: "notification-service", - operation: "notificationsSend", - tags: ["notification-service"], - }, -}; - -const notificationsSendHandler = applyPolicies( - async (input, context) => { - const baseUrl = process.env.NOTIFICATION_SERVICE_URL || context.metadata?.['notification-serviceUrl'] as string | undefined; - if (!baseUrl) { - throw new Error(`NOTIFICATION_SERVICE_URL environment variable is not set`); - } - - const headers = getOAuthHeaders(context, "notification-service"); - - // Create custom client with proper baseURL configuration - const customClient = createClient(createConfig({ baseUrl })); - - const result = await sdk.notificationsSend({ - body: input, - headers, - client: customClient - } as any); - - if (result && typeof result === "object" && "data" in result) { - return (result as { data: unknown }).data; - } - return result as unknown; - }, - withOAuth({ - provider: "notification-service", - metadataTokenKey: "notification-serviceToken", - envVar: "NOTIFICATION_SERVICE_TOKEN", - }) -); - -export const NotificationsSendProcedure: Procedure = { - contract: NotificationsSendContract, - handler: notificationsSendHandler, -}; diff --git a/examples/cross-integration/app-a/procedures/integrations/notification-service/notifications-subscribe.gen.ts b/examples/cross-integration/app-a/procedures/integrations/notification-service/notifications-subscribe.gen.ts deleted file mode 100644 index 718dc0e..0000000 --- a/examples/cross-integration/app-a/procedures/integrations/notification-service/notifications-subscribe.gen.ts +++ /dev/null @@ -1,64 +0,0 @@ -// This file is auto-generated by c4c integrate command -// Do not edit manually. - -import { applyPolicies, type Procedure, type Contract } from "@c4c/core"; -import { withOAuth, getOAuthHeaders } from "@c4c/policies"; -import * as sdk from "../../../generated/notification-service/sdk.gen.js"; -import { createClient, createConfig } from "@hey-api/client-fetch"; -import { z } from "zod"; - -export const NotificationsSubscribeContract: Contract = { - name: "notification-service.notifications.subscribe", - description: "Subscribe to notifications on a topic", - input: z.object({ - topic: z.string(), - webhookUrl: z.string().url() -}), - output: z.object({ - success: z.boolean(), - subscriptionId: z.string(), - topic: z.string() -}), - metadata: { - exposure: "external" as const, - roles: ["api-endpoint", "workflow-node"], - provider: "notification-service", - operation: "notificationsSubscribe", - tags: ["notification-service"], - }, -}; - -const notificationsSubscribeHandler = applyPolicies( - async (input, context) => { - const baseUrl = process.env.NOTIFICATION_SERVICE_URL || context.metadata?.['notification-serviceUrl'] as string | undefined; - if (!baseUrl) { - throw new Error(`NOTIFICATION_SERVICE_URL environment variable is not set`); - } - - const headers = getOAuthHeaders(context, "notification-service"); - - // Create custom client with proper baseURL configuration - const customClient = createClient(createConfig({ baseUrl })); - - const result = await sdk.notificationsSubscribe({ - body: input, - headers, - client: customClient - } as any); - - if (result && typeof result === "object" && "data" in result) { - return (result as { data: unknown }).data; - } - return result as unknown; - }, - withOAuth({ - provider: "notification-service", - metadataTokenKey: "notification-serviceToken", - envVar: "NOTIFICATION_SERVICE_TOKEN", - }) -); - -export const NotificationsSubscribeProcedure: Procedure = { - contract: NotificationsSubscribeContract, - handler: notificationsSubscribeHandler, -}; diff --git a/examples/cross-integration/app-a/procedures/integrations/notification-service/triggers/notifications-trigger-sent.gen.ts b/examples/cross-integration/app-a/procedures/integrations/notification-service/triggers/notifications-trigger-sent.gen.ts deleted file mode 100644 index 6e42774..0000000 --- a/examples/cross-integration/app-a/procedures/integrations/notification-service/triggers/notifications-trigger-sent.gen.ts +++ /dev/null @@ -1,31 +0,0 @@ -// This file is auto-generated by c4c integrate command -// Do not edit manually. - -import type { Procedure, Contract } from "@c4c/core"; -import { z } from "zod"; - -export const NotificationsTriggerSentContract: Contract = { - name: "notification-service.notifications.trigger.sent", - description: "Webhook trigger that fires when a notification is sent", - input: z.record(z.string(), z.unknown()), - output: z.record(z.string(), z.unknown()), - metadata: { - exposure: "external" as const, - roles: ["workflow-node"], - provider: "notification-service", - operation: "notificationsTriggerSent", - tags: ["notification-service", "webhook"], - type: "trigger" as const, - trigger: { - type: "webhook", - }, - }, -}; - -// Webhook triggers don't have a handler - they are registered as event receivers -export const NotificationsTriggerSentProcedure: Procedure = { - contract: NotificationsTriggerSentContract, - handler: async () => { - throw new Error('Webhook triggers should not be called directly - they are invoked by the workflow engine'); - }, -}; diff --git a/examples/cross-integration/app-b/procedures/integrations/task-manager/tasks-create-rest.gen.ts b/examples/cross-integration/app-b/procedures/integrations/task-manager/tasks-create-rest.gen.ts deleted file mode 100644 index 6cc47b4..0000000 --- a/examples/cross-integration/app-b/procedures/integrations/task-manager/tasks-create-rest.gen.ts +++ /dev/null @@ -1,57 +0,0 @@ -// This file is auto-generated by c4c integrate command -// Do not edit manually. - -import { applyPolicies, type Procedure, type Contract } from "@c4c/core"; -import { withOAuth, getOAuthHeaders } from "@c4c/policies"; -import * as sdk from "../../../generated/task-manager/sdk.gen.js"; -import { createClient, createConfig } from "@hey-api/client-fetch"; -import { z } from "zod"; - -export const TasksCreateRestContract: Contract = { - name: "task-manager.tasks.create.rest", - description: "Create a new task", - input: z.unknown(), - output: z.unknown(), - metadata: { - exposure: "external" as const, - roles: ["api-endpoint", "workflow-node"], - provider: "task-manager", - operation: "tasksCreateRest", - tags: ["task-manager"], - }, -}; - -const tasksCreateRestHandler = applyPolicies( - async (input, context) => { - const baseUrl = process.env.TASK_MANAGER_URL || context.metadata?.['task-managerUrl'] as string | undefined; - if (!baseUrl) { - throw new Error(`TASK_MANAGER_URL environment variable is not set`); - } - - const headers = getOAuthHeaders(context, "task-manager"); - - // Create custom client with proper baseURL configuration - const customClient = createClient(createConfig({ baseUrl })); - - const result = await sdk.tasksCreateRest({ - body: input, - headers, - client: customClient - } as any); - - if (result && typeof result === "object" && "data" in result) { - return (result as { data: unknown }).data; - } - return result as unknown; - }, - withOAuth({ - provider: "task-manager", - metadataTokenKey: "task-managerToken", - envVar: "TASK_MANAGER_TOKEN", - }) -); - -export const TasksCreateRestProcedure: Procedure = { - contract: TasksCreateRestContract, - handler: tasksCreateRestHandler, -}; diff --git a/examples/cross-integration/app-b/procedures/integrations/task-manager/tasks-create.gen.ts b/examples/cross-integration/app-b/procedures/integrations/task-manager/tasks-create.gen.ts deleted file mode 100644 index f884b82..0000000 --- a/examples/cross-integration/app-b/procedures/integrations/task-manager/tasks-create.gen.ts +++ /dev/null @@ -1,74 +0,0 @@ -// This file is auto-generated by c4c integrate command -// Do not edit manually. - -import { applyPolicies, type Procedure, type Contract } from "@c4c/core"; -import { withOAuth, getOAuthHeaders } from "@c4c/policies"; -import * as sdk from "../../../generated/task-manager/sdk.gen.js"; -import { createClient, createConfig } from "@hey-api/client-fetch"; -import { z } from "zod"; - -export const TasksCreateContract: Contract = { - name: "task-manager.tasks.create", - description: "Create a new task", - input: z.object({ - title: z.string().min(1), - description: z.string().optional(), - status: z.enum(["todo", "in_progress", "done"]).optional(), - priority: z.enum(["low", "medium", "high"]).optional(), - assignee: z.string().optional(), - dueDate: z.string().optional() -}), - output: z.object({ - id: z.string(), - title: z.string(), - description: z.string().optional(), - status: z.enum(["todo", "in_progress", "done"]), - priority: z.enum(["low", "medium", "high"]).optional(), - assignee: z.string().optional(), - dueDate: z.string().optional(), - createdAt: z.string(), - updatedAt: z.string() -}), - metadata: { - exposure: "external" as const, - roles: ["api-endpoint", "workflow-node"], - provider: "task-manager", - operation: "tasksCreate", - tags: ["task-manager"], - }, -}; - -const tasksCreateHandler = applyPolicies( - async (input, context) => { - const baseUrl = process.env.TASK_MANAGER_URL || context.metadata?.['task-managerUrl'] as string | undefined; - if (!baseUrl) { - throw new Error(`TASK_MANAGER_URL environment variable is not set`); - } - - const headers = getOAuthHeaders(context, "task-manager"); - - // Create custom client with proper baseURL configuration - const customClient = createClient(createConfig({ baseUrl })); - - const result = await sdk.tasksCreate({ - body: input, - headers, - client: customClient - } as any); - - if (result && typeof result === "object" && "data" in result) { - return (result as { data: unknown }).data; - } - return result as unknown; - }, - withOAuth({ - provider: "task-manager", - metadataTokenKey: "task-managerToken", - envVar: "TASK_MANAGER_TOKEN", - }) -); - -export const TasksCreateProcedure: Procedure = { - contract: TasksCreateContract, - handler: tasksCreateHandler, -}; diff --git a/examples/cross-integration/app-b/procedures/integrations/task-manager/tasks-delete-rest.gen.ts b/examples/cross-integration/app-b/procedures/integrations/task-manager/tasks-delete-rest.gen.ts deleted file mode 100644 index 8ed99be..0000000 --- a/examples/cross-integration/app-b/procedures/integrations/task-manager/tasks-delete-rest.gen.ts +++ /dev/null @@ -1,57 +0,0 @@ -// This file is auto-generated by c4c integrate command -// Do not edit manually. - -import { applyPolicies, type Procedure, type Contract } from "@c4c/core"; -import { withOAuth, getOAuthHeaders } from "@c4c/policies"; -import * as sdk from "../../../generated/task-manager/sdk.gen.js"; -import { createClient, createConfig } from "@hey-api/client-fetch"; -import { z } from "zod"; - -export const TasksDeleteRestContract: Contract = { - name: "task-manager.tasks.delete.rest", - description: "Delete a task", - input: z.unknown(), - output: z.unknown(), - metadata: { - exposure: "external" as const, - roles: ["api-endpoint", "workflow-node"], - provider: "task-manager", - operation: "tasksDeleteRest", - tags: ["task-manager"], - }, -}; - -const tasksDeleteRestHandler = applyPolicies( - async (input, context) => { - const baseUrl = process.env.TASK_MANAGER_URL || context.metadata?.['task-managerUrl'] as string | undefined; - if (!baseUrl) { - throw new Error(`TASK_MANAGER_URL environment variable is not set`); - } - - const headers = getOAuthHeaders(context, "task-manager"); - - // Create custom client with proper baseURL configuration - const customClient = createClient(createConfig({ baseUrl })); - - const result = await sdk.tasksDeleteRest({ - body: input, - headers, - client: customClient - } as any); - - if (result && typeof result === "object" && "data" in result) { - return (result as { data: unknown }).data; - } - return result as unknown; - }, - withOAuth({ - provider: "task-manager", - metadataTokenKey: "task-managerToken", - envVar: "TASK_MANAGER_TOKEN", - }) -); - -export const TasksDeleteRestProcedure: Procedure = { - contract: TasksDeleteRestContract, - handler: tasksDeleteRestHandler, -}; diff --git a/examples/cross-integration/app-b/procedures/integrations/task-manager/tasks-delete.gen.ts b/examples/cross-integration/app-b/procedures/integrations/task-manager/tasks-delete.gen.ts deleted file mode 100644 index ea8eccc..0000000 --- a/examples/cross-integration/app-b/procedures/integrations/task-manager/tasks-delete.gen.ts +++ /dev/null @@ -1,62 +0,0 @@ -// This file is auto-generated by c4c integrate command -// Do not edit manually. - -import { applyPolicies, type Procedure, type Contract } from "@c4c/core"; -import { withOAuth, getOAuthHeaders } from "@c4c/policies"; -import * as sdk from "../../../generated/task-manager/sdk.gen.js"; -import { createClient, createConfig } from "@hey-api/client-fetch"; -import { z } from "zod"; - -export const TasksDeleteContract: Contract = { - name: "task-manager.tasks.delete", - description: "Delete a task", - input: z.object({ - id: z.string() -}), - output: z.object({ - success: z.boolean(), - id: z.string() -}), - metadata: { - exposure: "external" as const, - roles: ["api-endpoint", "workflow-node"], - provider: "task-manager", - operation: "tasksDelete", - tags: ["task-manager"], - }, -}; - -const tasksDeleteHandler = applyPolicies( - async (input, context) => { - const baseUrl = process.env.TASK_MANAGER_URL || context.metadata?.['task-managerUrl'] as string | undefined; - if (!baseUrl) { - throw new Error(`TASK_MANAGER_URL environment variable is not set`); - } - - const headers = getOAuthHeaders(context, "task-manager"); - - // Create custom client with proper baseURL configuration - const customClient = createClient(createConfig({ baseUrl })); - - const result = await sdk.tasksDelete({ - body: input, - headers, - client: customClient - } as any); - - if (result && typeof result === "object" && "data" in result) { - return (result as { data: unknown }).data; - } - return result as unknown; - }, - withOAuth({ - provider: "task-manager", - metadataTokenKey: "task-managerToken", - envVar: "TASK_MANAGER_TOKEN", - }) -); - -export const TasksDeleteProcedure: Procedure = { - contract: TasksDeleteContract, - handler: tasksDeleteHandler, -}; diff --git a/examples/cross-integration/app-b/procedures/integrations/task-manager/tasks-get-rest.gen.ts b/examples/cross-integration/app-b/procedures/integrations/task-manager/tasks-get-rest.gen.ts deleted file mode 100644 index cb68830..0000000 --- a/examples/cross-integration/app-b/procedures/integrations/task-manager/tasks-get-rest.gen.ts +++ /dev/null @@ -1,57 +0,0 @@ -// This file is auto-generated by c4c integrate command -// Do not edit manually. - -import { applyPolicies, type Procedure, type Contract } from "@c4c/core"; -import { withOAuth, getOAuthHeaders } from "@c4c/policies"; -import * as sdk from "../../../generated/task-manager/sdk.gen.js"; -import { createClient, createConfig } from "@hey-api/client-fetch"; -import { z } from "zod"; - -export const TasksGetRestContract: Contract = { - name: "task-manager.tasks.get.rest", - description: "Get a task by ID", - input: z.unknown(), - output: z.unknown(), - metadata: { - exposure: "external" as const, - roles: ["api-endpoint", "workflow-node"], - provider: "task-manager", - operation: "tasksGetRest", - tags: ["task-manager"], - }, -}; - -const tasksGetRestHandler = applyPolicies( - async (input, context) => { - const baseUrl = process.env.TASK_MANAGER_URL || context.metadata?.['task-managerUrl'] as string | undefined; - if (!baseUrl) { - throw new Error(`TASK_MANAGER_URL environment variable is not set`); - } - - const headers = getOAuthHeaders(context, "task-manager"); - - // Create custom client with proper baseURL configuration - const customClient = createClient(createConfig({ baseUrl })); - - const result = await sdk.tasksGetRest({ - body: input, - headers, - client: customClient - } as any); - - if (result && typeof result === "object" && "data" in result) { - return (result as { data: unknown }).data; - } - return result as unknown; - }, - withOAuth({ - provider: "task-manager", - metadataTokenKey: "task-managerToken", - envVar: "TASK_MANAGER_TOKEN", - }) -); - -export const TasksGetRestProcedure: Procedure = { - contract: TasksGetRestContract, - handler: tasksGetRestHandler, -}; diff --git a/examples/cross-integration/app-b/procedures/integrations/task-manager/tasks-get.gen.ts b/examples/cross-integration/app-b/procedures/integrations/task-manager/tasks-get.gen.ts deleted file mode 100644 index 43f6396..0000000 --- a/examples/cross-integration/app-b/procedures/integrations/task-manager/tasks-get.gen.ts +++ /dev/null @@ -1,69 +0,0 @@ -// This file is auto-generated by c4c integrate command -// Do not edit manually. - -import { applyPolicies, type Procedure, type Contract } from "@c4c/core"; -import { withOAuth, getOAuthHeaders } from "@c4c/policies"; -import * as sdk from "../../../generated/task-manager/sdk.gen.js"; -import { createClient, createConfig } from "@hey-api/client-fetch"; -import { z } from "zod"; - -export const TasksGetContract: Contract = { - name: "task-manager.tasks.get", - description: "Get a task by ID", - input: z.object({ - id: z.string() -}), - output: z.object({ - id: z.string(), - title: z.string(), - description: z.string().optional(), - status: z.enum(["todo", "in_progress", "done"]), - priority: z.enum(["low", "medium", "high"]).optional(), - assignee: z.string().optional(), - dueDate: z.string().optional(), - createdAt: z.string(), - updatedAt: z.string() -}), - metadata: { - exposure: "external" as const, - roles: ["api-endpoint", "workflow-node"], - provider: "task-manager", - operation: "tasksGet", - tags: ["task-manager"], - }, -}; - -const tasksGetHandler = applyPolicies( - async (input, context) => { - const baseUrl = process.env.TASK_MANAGER_URL || context.metadata?.['task-managerUrl'] as string | undefined; - if (!baseUrl) { - throw new Error(`TASK_MANAGER_URL environment variable is not set`); - } - - const headers = getOAuthHeaders(context, "task-manager"); - - // Create custom client with proper baseURL configuration - const customClient = createClient(createConfig({ baseUrl })); - - const result = await sdk.tasksGet({ - body: input, - headers, - client: customClient - } as any); - - if (result && typeof result === "object" && "data" in result) { - return (result as { data: unknown }).data; - } - return result as unknown; - }, - withOAuth({ - provider: "task-manager", - metadataTokenKey: "task-managerToken", - envVar: "TASK_MANAGER_TOKEN", - }) -); - -export const TasksGetProcedure: Procedure = { - contract: TasksGetContract, - handler: tasksGetHandler, -}; diff --git a/examples/cross-integration/app-b/procedures/integrations/task-manager/tasks-list-rest.gen.ts b/examples/cross-integration/app-b/procedures/integrations/task-manager/tasks-list-rest.gen.ts deleted file mode 100644 index 7d811b0..0000000 --- a/examples/cross-integration/app-b/procedures/integrations/task-manager/tasks-list-rest.gen.ts +++ /dev/null @@ -1,57 +0,0 @@ -// This file is auto-generated by c4c integrate command -// Do not edit manually. - -import { applyPolicies, type Procedure, type Contract } from "@c4c/core"; -import { withOAuth, getOAuthHeaders } from "@c4c/policies"; -import * as sdk from "../../../generated/task-manager/sdk.gen.js"; -import { createClient, createConfig } from "@hey-api/client-fetch"; -import { z } from "zod"; - -export const TasksListRestContract: Contract = { - name: "task-manager.tasks.list.rest", - description: "List all tasks with optional filters", - input: z.unknown(), - output: z.unknown(), - metadata: { - exposure: "external" as const, - roles: ["api-endpoint", "workflow-node"], - provider: "task-manager", - operation: "tasksListRest", - tags: ["task-manager"], - }, -}; - -const tasksListRestHandler = applyPolicies( - async (input, context) => { - const baseUrl = process.env.TASK_MANAGER_URL || context.metadata?.['task-managerUrl'] as string | undefined; - if (!baseUrl) { - throw new Error(`TASK_MANAGER_URL environment variable is not set`); - } - - const headers = getOAuthHeaders(context, "task-manager"); - - // Create custom client with proper baseURL configuration - const customClient = createClient(createConfig({ baseUrl })); - - const result = await sdk.tasksListRest({ - body: input, - headers, - client: customClient - } as any); - - if (result && typeof result === "object" && "data" in result) { - return (result as { data: unknown }).data; - } - return result as unknown; - }, - withOAuth({ - provider: "task-manager", - metadataTokenKey: "task-managerToken", - envVar: "TASK_MANAGER_TOKEN", - }) -); - -export const TasksListRestProcedure: Procedure = { - contract: TasksListRestContract, - handler: tasksListRestHandler, -}; diff --git a/examples/cross-integration/app-b/procedures/integrations/task-manager/tasks-list.gen.ts b/examples/cross-integration/app-b/procedures/integrations/task-manager/tasks-list.gen.ts deleted file mode 100644 index 9ec91cd..0000000 --- a/examples/cross-integration/app-b/procedures/integrations/task-manager/tasks-list.gen.ts +++ /dev/null @@ -1,74 +0,0 @@ -// This file is auto-generated by c4c integrate command -// Do not edit manually. - -import { applyPolicies, type Procedure, type Contract } from "@c4c/core"; -import { withOAuth, getOAuthHeaders } from "@c4c/policies"; -import * as sdk from "../../../generated/task-manager/sdk.gen.js"; -import { createClient, createConfig } from "@hey-api/client-fetch"; -import { z } from "zod"; - -export const TasksListContract: Contract = { - name: "task-manager.tasks.list", - description: "List all tasks with optional filters", - input: z.object({ - status: z.enum(["todo", "in_progress", "done"]).optional(), - assignee: z.string().optional(), - limit: z.number().optional() -}), - output: z.object({ - tasks: z.array(z.object({ - id: z.string(), - title: z.string(), - description: z.string().optional(), - status: z.enum(["todo", "in_progress", "done"]), - priority: z.enum(["low", "medium", "high"]).optional(), - assignee: z.string().optional(), - dueDate: z.string().optional(), - createdAt: z.string(), - updatedAt: z.string() -})), - total: z.number() -}), - metadata: { - exposure: "external" as const, - roles: ["api-endpoint", "workflow-node"], - provider: "task-manager", - operation: "tasksList", - tags: ["task-manager"], - }, -}; - -const tasksListHandler = applyPolicies( - async (input, context) => { - const baseUrl = process.env.TASK_MANAGER_URL || context.metadata?.['task-managerUrl'] as string | undefined; - if (!baseUrl) { - throw new Error(`TASK_MANAGER_URL environment variable is not set`); - } - - const headers = getOAuthHeaders(context, "task-manager"); - - // Create custom client with proper baseURL configuration - const customClient = createClient(createConfig({ baseUrl })); - - const result = await sdk.tasksList({ - body: input, - headers, - client: customClient - } as any); - - if (result && typeof result === "object" && "data" in result) { - return (result as { data: unknown }).data; - } - return result as unknown; - }, - withOAuth({ - provider: "task-manager", - metadataTokenKey: "task-managerToken", - envVar: "TASK_MANAGER_TOKEN", - }) -); - -export const TasksListProcedure: Procedure = { - contract: TasksListContract, - handler: tasksListHandler, -}; diff --git a/examples/cross-integration/app-b/procedures/integrations/task-manager/tasks-update-rest.gen.ts b/examples/cross-integration/app-b/procedures/integrations/task-manager/tasks-update-rest.gen.ts deleted file mode 100644 index db4911b..0000000 --- a/examples/cross-integration/app-b/procedures/integrations/task-manager/tasks-update-rest.gen.ts +++ /dev/null @@ -1,57 +0,0 @@ -// This file is auto-generated by c4c integrate command -// Do not edit manually. - -import { applyPolicies, type Procedure, type Contract } from "@c4c/core"; -import { withOAuth, getOAuthHeaders } from "@c4c/policies"; -import * as sdk from "../../../generated/task-manager/sdk.gen.js"; -import { createClient, createConfig } from "@hey-api/client-fetch"; -import { z } from "zod"; - -export const TasksUpdateRestContract: Contract = { - name: "task-manager.tasks.update.rest", - description: "Update a task", - input: z.unknown(), - output: z.unknown(), - metadata: { - exposure: "external" as const, - roles: ["api-endpoint", "workflow-node"], - provider: "task-manager", - operation: "tasksUpdateRest", - tags: ["task-manager"], - }, -}; - -const tasksUpdateRestHandler = applyPolicies( - async (input, context) => { - const baseUrl = process.env.TASK_MANAGER_URL || context.metadata?.['task-managerUrl'] as string | undefined; - if (!baseUrl) { - throw new Error(`TASK_MANAGER_URL environment variable is not set`); - } - - const headers = getOAuthHeaders(context, "task-manager"); - - // Create custom client with proper baseURL configuration - const customClient = createClient(createConfig({ baseUrl })); - - const result = await sdk.tasksUpdateRest({ - body: input, - headers, - client: customClient - } as any); - - if (result && typeof result === "object" && "data" in result) { - return (result as { data: unknown }).data; - } - return result as unknown; - }, - withOAuth({ - provider: "task-manager", - metadataTokenKey: "task-managerToken", - envVar: "TASK_MANAGER_TOKEN", - }) -); - -export const TasksUpdateRestProcedure: Procedure = { - contract: TasksUpdateRestContract, - handler: tasksUpdateRestHandler, -}; diff --git a/examples/cross-integration/app-b/procedures/integrations/task-manager/tasks-update.gen.ts b/examples/cross-integration/app-b/procedures/integrations/task-manager/tasks-update.gen.ts deleted file mode 100644 index d7b6a04..0000000 --- a/examples/cross-integration/app-b/procedures/integrations/task-manager/tasks-update.gen.ts +++ /dev/null @@ -1,75 +0,0 @@ -// This file is auto-generated by c4c integrate command -// Do not edit manually. - -import { applyPolicies, type Procedure, type Contract } from "@c4c/core"; -import { withOAuth, getOAuthHeaders } from "@c4c/policies"; -import * as sdk from "../../../generated/task-manager/sdk.gen.js"; -import { createClient, createConfig } from "@hey-api/client-fetch"; -import { z } from "zod"; - -export const TasksUpdateContract: Contract = { - name: "task-manager.tasks.update", - description: "Update a task", - input: z.object({ - id: z.string(), - title: z.string().optional(), - description: z.string().optional(), - status: z.enum(["todo", "in_progress", "done"]).optional(), - priority: z.enum(["low", "medium", "high"]).optional(), - assignee: z.string().optional(), - dueDate: z.string().optional() -}), - output: z.object({ - id: z.string(), - title: z.string(), - description: z.string().optional(), - status: z.enum(["todo", "in_progress", "done"]), - priority: z.enum(["low", "medium", "high"]).optional(), - assignee: z.string().optional(), - dueDate: z.string().optional(), - createdAt: z.string(), - updatedAt: z.string() -}), - metadata: { - exposure: "external" as const, - roles: ["api-endpoint", "workflow-node"], - provider: "task-manager", - operation: "tasksUpdate", - tags: ["task-manager"], - }, -}; - -const tasksUpdateHandler = applyPolicies( - async (input, context) => { - const baseUrl = process.env.TASK_MANAGER_URL || context.metadata?.['task-managerUrl'] as string | undefined; - if (!baseUrl) { - throw new Error(`TASK_MANAGER_URL environment variable is not set`); - } - - const headers = getOAuthHeaders(context, "task-manager"); - - // Create custom client with proper baseURL configuration - const customClient = createClient(createConfig({ baseUrl })); - - const result = await sdk.tasksUpdate({ - body: input, - headers, - client: customClient - } as any); - - if (result && typeof result === "object" && "data" in result) { - return (result as { data: unknown }).data; - } - return result as unknown; - }, - withOAuth({ - provider: "task-manager", - metadataTokenKey: "task-managerToken", - envVar: "TASK_MANAGER_TOKEN", - }) -); - -export const TasksUpdateProcedure: Procedure = { - contract: TasksUpdateContract, - handler: tasksUpdateHandler, -}; diff --git a/examples/cross-integration/app-b/procedures/integrations/task-manager/triggers/tasks-trigger-created.gen.ts b/examples/cross-integration/app-b/procedures/integrations/task-manager/triggers/tasks-trigger-created.gen.ts deleted file mode 100644 index 9050727..0000000 --- a/examples/cross-integration/app-b/procedures/integrations/task-manager/triggers/tasks-trigger-created.gen.ts +++ /dev/null @@ -1,31 +0,0 @@ -// This file is auto-generated by c4c integrate command -// Do not edit manually. - -import type { Procedure, Contract } from "@c4c/core"; -import { z } from "zod"; - -export const TasksTriggerCreatedContract: Contract = { - name: "task-manager.tasks.trigger.created", - description: "Webhook fired when a new task is created", - input: z.record(z.string(), z.unknown()), - output: z.record(z.string(), z.unknown()), - metadata: { - exposure: "external" as const, - roles: ["workflow-node"], - provider: "task-manager", - operation: "tasksTriggerCreated", - tags: ["task-manager", "webhook"], - type: "trigger" as const, - trigger: { - type: "webhook", - }, - }, -}; - -// Webhook triggers don't have a handler - they are registered as event receivers -export const TasksTriggerCreatedProcedure: Procedure = { - contract: TasksTriggerCreatedContract, - handler: async () => { - throw new Error('Webhook triggers should not be called directly - they are invoked by the workflow engine'); - }, -}; diff --git a/examples/cross-integration/app-b/procedures/integrations/task-manager/triggers/tasks-trigger-updated.gen.ts b/examples/cross-integration/app-b/procedures/integrations/task-manager/triggers/tasks-trigger-updated.gen.ts deleted file mode 100644 index dc52cdd..0000000 --- a/examples/cross-integration/app-b/procedures/integrations/task-manager/triggers/tasks-trigger-updated.gen.ts +++ /dev/null @@ -1,31 +0,0 @@ -// This file is auto-generated by c4c integrate command -// Do not edit manually. - -import type { Procedure, Contract } from "@c4c/core"; -import { z } from "zod"; - -export const TasksTriggerUpdatedContract: Contract = { - name: "task-manager.tasks.trigger.updated", - description: "Webhook fired when a task is updated", - input: z.record(z.string(), z.unknown()), - output: z.record(z.string(), z.unknown()), - metadata: { - exposure: "external" as const, - roles: ["workflow-node"], - provider: "task-manager", - operation: "tasksTriggerUpdated", - tags: ["task-manager", "webhook"], - type: "trigger" as const, - trigger: { - type: "webhook", - }, - }, -}; - -// Webhook triggers don't have a handler - they are registered as event receivers -export const TasksTriggerUpdatedProcedure: Procedure = { - contract: TasksTriggerUpdatedContract, - handler: async () => { - throw new Error('Webhook triggers should not be called directly - they are invoked by the workflow engine'); - }, -}; diff --git a/examples/integrations/generated/avito/authorization/client.gen.ts b/examples/integrations/generated/avito/authorization/client.gen.ts deleted file mode 100644 index a2b0b1d..0000000 --- a/examples/integrations/generated/avito/authorization/client.gen.ts +++ /dev/null @@ -1,27 +0,0 @@ -// This file is auto-generated by @hey-api/openapi-ts - -import type { ClientOptions } from './types.gen' -import { - type ClientOptions as DefaultClientOptions, - type Config, - createClient, - createConfig -} from './client' - -/** - * The `createClientConfig()` function will be called on client initialization - * and the returned object will become the client's initial configuration. - * - * You may want to initialize your client this way instead of calling - * `setConfig()`. This is useful for example if you're using Next.js - * to ensure your client always has the correct values. - */ -export type CreateClientConfig = ( - override?: Config -) => Config & T> - -export const client = createClient( - createConfig({ - baseUrl: 'https://api.avito.ru/' - }) -) diff --git a/examples/integrations/generated/avito/authorization/client/client.gen.ts b/examples/integrations/generated/avito/authorization/client/client.gen.ts deleted file mode 100644 index 4a4fc46..0000000 --- a/examples/integrations/generated/avito/authorization/client/client.gen.ts +++ /dev/null @@ -1,253 +0,0 @@ -// This file is auto-generated by @hey-api/openapi-ts - -import { createSseClient } from '../core/serverSentEvents.gen' -import type { HttpMethod } from '../core/types.gen' -import { getValidRequestBody } from '../core/utils.gen' -import type { Client, Config, RequestOptions, ResolvedRequestOptions } from './types.gen' -import { - buildUrl, - createConfig, - createInterceptors, - getParseAs, - mergeConfigs, - mergeHeaders, - setAuthParams -} from './utils.gen' - -type ReqInit = Omit & { - body?: any - headers: ReturnType -} - -export const createClient = (config: Config = {}): Client => { - let _config = mergeConfigs(createConfig(), config) - - const getConfig = (): Config => ({ ..._config }) - - const setConfig = (config: Config): Config => { - _config = mergeConfigs(_config, config) - return getConfig() - } - - const interceptors = createInterceptors() - - const beforeRequest = async (options: RequestOptions) => { - const opts = { - ..._config, - ...options, - fetch: options.fetch ?? _config.fetch ?? globalThis.fetch, - headers: mergeHeaders(_config.headers, options.headers), - serializedBody: undefined - } - - if (opts.security) { - await setAuthParams({ - ...opts, - security: opts.security - }) - } - - if (opts.requestValidator) { - await opts.requestValidator(opts) - } - - if (opts.body !== undefined && opts.bodySerializer) { - opts.serializedBody = opts.bodySerializer(opts.body) - } - - // remove Content-Type header if body is empty to avoid sending invalid requests - if (opts.body === undefined || opts.serializedBody === '') { - opts.headers.delete('Content-Type') - } - - const url = buildUrl(opts) - - return { opts, url } - } - - const request: Client['request'] = async (options) => { - // @ts-expect-error - const { opts, url } = await beforeRequest(options) - const requestInit: ReqInit = { - redirect: 'follow', - ...opts, - body: getValidRequestBody(opts) - } - - let request = new Request(url, requestInit) - - for (const fn of interceptors.request.fns) { - if (fn) { - request = await fn(request, opts) - } - } - - // fetch must be assigned here, otherwise it would throw the error: - // TypeError: Failed to execute 'fetch' on 'Window': Illegal invocation - const _fetch = opts.fetch! - let response = await _fetch(request) - - for (const fn of interceptors.response.fns) { - if (fn) { - response = await fn(response, request, opts) - } - } - - const result = { - request, - response - } - - if (response.ok) { - const parseAs = - (opts.parseAs === 'auto' - ? getParseAs(response.headers.get('Content-Type')) - : opts.parseAs) ?? 'json' - - if (response.status === 204 || response.headers.get('Content-Length') === '0') { - let emptyData: any - switch (parseAs) { - case 'arrayBuffer': - case 'blob': - case 'text': - emptyData = await response[parseAs]() - break - case 'formData': - emptyData = new FormData() - break - case 'stream': - emptyData = response.body - break - case 'json': - default: - emptyData = {} - break - } - return opts.responseStyle === 'data' - ? emptyData - : { - data: emptyData, - ...result - } - } - - let data: any - switch (parseAs) { - case 'arrayBuffer': - case 'blob': - case 'formData': - case 'json': - case 'text': - data = await response[parseAs]() - break - case 'stream': - return opts.responseStyle === 'data' - ? response.body - : { - data: response.body, - ...result - } - } - - if (parseAs === 'json') { - if (opts.responseValidator) { - await opts.responseValidator(data) - } - - if (opts.responseTransformer) { - data = await opts.responseTransformer(data) - } - } - - return opts.responseStyle === 'data' - ? data - : { - data, - ...result - } - } - - const textError = await response.text() - let jsonError: unknown - - try { - jsonError = JSON.parse(textError) - } catch { - // noop - } - - const error = jsonError ?? textError - let finalError = error - - for (const fn of interceptors.error.fns) { - if (fn) { - finalError = (await fn(error, response, request, opts)) as string - } - } - - finalError = finalError || ({} as string) - - if (opts.throwOnError) { - throw finalError - } - - // TODO: we probably want to return error and improve types - return opts.responseStyle === 'data' - ? undefined - : { - error: finalError, - ...result - } - } - - const makeMethodFn = (method: Uppercase) => (options: RequestOptions) => - request({ ...options, method }) - - const makeSseFn = (method: Uppercase) => async (options: RequestOptions) => { - const { opts, url } = await beforeRequest(options) - return createSseClient({ - ...opts, - body: opts.body as BodyInit | null | undefined, - headers: opts.headers as unknown as Record, - method, - onRequest: async (url, init) => { - let request = new Request(url, init) - for (const fn of interceptors.request.fns) { - if (fn) { - request = await fn(request, opts) - } - } - return request - }, - url - }) - } - - return { - buildUrl, - connect: makeMethodFn('CONNECT'), - delete: makeMethodFn('DELETE'), - get: makeMethodFn('GET'), - getConfig, - head: makeMethodFn('HEAD'), - interceptors, - options: makeMethodFn('OPTIONS'), - patch: makeMethodFn('PATCH'), - post: makeMethodFn('POST'), - put: makeMethodFn('PUT'), - request, - setConfig, - sse: { - connect: makeSseFn('CONNECT'), - delete: makeSseFn('DELETE'), - get: makeSseFn('GET'), - head: makeSseFn('HEAD'), - options: makeSseFn('OPTIONS'), - patch: makeSseFn('PATCH'), - post: makeSseFn('POST'), - put: makeSseFn('PUT'), - trace: makeSseFn('TRACE') - }, - trace: makeMethodFn('TRACE') - } as Client -} diff --git a/examples/integrations/generated/avito/authorization/client/types.gen.ts b/examples/integrations/generated/avito/authorization/client/types.gen.ts deleted file mode 100644 index b97f75e..0000000 --- a/examples/integrations/generated/avito/authorization/client/types.gen.ts +++ /dev/null @@ -1,226 +0,0 @@ -// This file is auto-generated by @hey-api/openapi-ts - -import type { Auth } from '../core/auth.gen' -import type { ServerSentEventsOptions, ServerSentEventsResult } from '../core/serverSentEvents.gen' -import type { Client as CoreClient, Config as CoreConfig } from '../core/types.gen' -import type { Middleware } from './utils.gen' - -export type ResponseStyle = 'data' | 'fields' - -export interface Config - extends Omit, - CoreConfig { - /** - * Base URL for all requests made by this client. - */ - baseUrl?: T['baseUrl'] - /** - * Fetch API implementation. You can use this option to provide a custom - * fetch instance. - * - * @default globalThis.fetch - */ - fetch?: typeof fetch - /** - * Please don't use the Fetch client for Next.js applications. The `next` - * options won't have any effect. - * - * Install {@link https://www.npmjs.com/package/@hey-api/client-next `@hey-api/client-next`} instead. - */ - next?: never - /** - * Return the response data parsed in a specified format. By default, `auto` - * will infer the appropriate method from the `Content-Type` response header. - * You can override this behavior with any of the {@link Body} methods. - * Select `stream` if you don't want to parse response data at all. - * - * @default 'auto' - */ - parseAs?: 'arrayBuffer' | 'auto' | 'blob' | 'formData' | 'json' | 'stream' | 'text' - /** - * Should we return only data or multiple fields (data, error, response, etc.)? - * - * @default 'fields' - */ - responseStyle?: ResponseStyle - /** - * Throw an error instead of returning it in the response? - * - * @default false - */ - throwOnError?: T['throwOnError'] -} - -export interface RequestOptions< - TData = unknown, - TResponseStyle extends ResponseStyle = 'fields', - ThrowOnError extends boolean = boolean, - Url extends string = string -> extends Config<{ - responseStyle: TResponseStyle - throwOnError: ThrowOnError - }>, - Pick< - ServerSentEventsOptions, - | 'onSseError' - | 'onSseEvent' - | 'sseDefaultRetryDelay' - | 'sseMaxRetryAttempts' - | 'sseMaxRetryDelay' - > { - /** - * Any body that you want to add to your request. - * - * {@link https://developer.mozilla.org/docs/Web/API/fetch#body} - */ - body?: unknown - path?: Record - query?: Record - /** - * Security mechanism(s) to use for the request. - */ - security?: ReadonlyArray - url: Url -} - -export interface ResolvedRequestOptions< - TResponseStyle extends ResponseStyle = 'fields', - ThrowOnError extends boolean = boolean, - Url extends string = string -> extends RequestOptions { - serializedBody?: string -} - -export type RequestResult< - TData = unknown, - TError = unknown, - ThrowOnError extends boolean = boolean, - TResponseStyle extends ResponseStyle = 'fields' -> = ThrowOnError extends true - ? Promise< - TResponseStyle extends 'data' - ? TData extends Record - ? TData[keyof TData] - : TData - : { - data: TData extends Record ? TData[keyof TData] : TData - request: Request - response: Response - } - > - : Promise< - TResponseStyle extends 'data' - ? (TData extends Record ? TData[keyof TData] : TData) | undefined - : ( - | { - data: TData extends Record ? TData[keyof TData] : TData - error: undefined - } - | { - data: undefined - error: TError extends Record ? TError[keyof TError] : TError - } - ) & { - request: Request - response: Response - } - > - -export interface ClientOptions { - baseUrl?: string - responseStyle?: ResponseStyle - throwOnError?: boolean -} - -type MethodFn = < - TData = unknown, - TError = unknown, - ThrowOnError extends boolean = false, - TResponseStyle extends ResponseStyle = 'fields' ->( - options: Omit, 'method'> -) => RequestResult - -type SseFn = < - TData = unknown, - TError = unknown, - ThrowOnError extends boolean = false, - TResponseStyle extends ResponseStyle = 'fields' ->( - options: Omit, 'method'> -) => Promise> - -type RequestFn = < - TData = unknown, - TError = unknown, - ThrowOnError extends boolean = false, - TResponseStyle extends ResponseStyle = 'fields' ->( - options: Omit, 'method'> & - Pick>, 'method'> -) => RequestResult - -type BuildUrlFn = < - TData extends { - body?: unknown - path?: Record - query?: Record - url: string - } ->( - options: Pick & Options -) => string - -export type Client = CoreClient & { - interceptors: Middleware -} - -/** - * The `createClientConfig()` function will be called on client initialization - * and the returned object will become the client's initial configuration. - * - * You may want to initialize your client this way instead of calling - * `setConfig()`. This is useful for example if you're using Next.js - * to ensure your client always has the correct values. - */ -export type CreateClientConfig = ( - override?: Config -) => Config & T> - -export interface TDataShape { - body?: unknown - headers?: unknown - path?: unknown - query?: unknown - url: string -} - -type OmitKeys = Pick> - -export type Options< - TData extends TDataShape = TDataShape, - ThrowOnError extends boolean = boolean, - TResponse = unknown, - TResponseStyle extends ResponseStyle = 'fields' -> = OmitKeys< - RequestOptions, - 'body' | 'path' | 'query' | 'url' -> & - Omit - -export type OptionsLegacyParser< - TData = unknown, - ThrowOnError extends boolean = boolean, - TResponseStyle extends ResponseStyle = 'fields' -> = TData extends { body?: any } - ? TData extends { headers?: any } - ? OmitKeys, 'body' | 'headers' | 'url'> & - TData - : OmitKeys, 'body' | 'url'> & - TData & - Pick, 'headers'> - : TData extends { headers?: any } - ? OmitKeys, 'headers' | 'url'> & - TData & - Pick, 'body'> - : OmitKeys, 'url'> & TData diff --git a/examples/integrations/generated/avito/authorization/client/utils.gen.ts b/examples/integrations/generated/avito/authorization/client/utils.gen.ts deleted file mode 100644 index b42b5d9..0000000 --- a/examples/integrations/generated/avito/authorization/client/utils.gen.ts +++ /dev/null @@ -1,315 +0,0 @@ -// This file is auto-generated by @hey-api/openapi-ts - -import { getAuthToken } from '../core/auth.gen' -import type { QuerySerializerOptions } from '../core/bodySerializer.gen' -import { jsonBodySerializer } from '../core/bodySerializer.gen' -import { - serializeArrayParam, - serializeObjectParam, - serializePrimitiveParam -} from '../core/pathSerializer.gen' -import { getUrl } from '../core/utils.gen' -import type { Client, ClientOptions, Config, RequestOptions } from './types.gen' - -export const createQuerySerializer = ({ - allowReserved, - array, - object -}: QuerySerializerOptions = {}) => { - const querySerializer = (queryParams: T) => { - const search: string[] = [] - if (queryParams && typeof queryParams === 'object') { - for (const name in queryParams) { - const value = queryParams[name] - - if (value === undefined || value === null) { - continue - } - - if (Array.isArray(value)) { - const serializedArray = serializeArrayParam({ - allowReserved, - explode: true, - name, - style: 'form', - value, - ...array - }) - if (serializedArray) search.push(serializedArray) - } else if (typeof value === 'object') { - const serializedObject = serializeObjectParam({ - allowReserved, - explode: true, - name, - style: 'deepObject', - value: value as Record, - ...object - }) - if (serializedObject) search.push(serializedObject) - } else { - const serializedPrimitive = serializePrimitiveParam({ - allowReserved, - name, - value: value as string - }) - if (serializedPrimitive) search.push(serializedPrimitive) - } - } - } - return search.join('&') - } - return querySerializer -} - -/** - * Infers parseAs value from provided Content-Type header. - */ -export const getParseAs = (contentType: string | null): Exclude => { - if (!contentType) { - // If no Content-Type header is provided, the best we can do is return the raw response body, - // which is effectively the same as the 'stream' option. - return 'stream' - } - - const cleanContent = contentType.split(';')[0]?.trim() - - if (!cleanContent) { - return - } - - if (cleanContent.startsWith('application/json') || cleanContent.endsWith('+json')) { - return 'json' - } - - if (cleanContent === 'multipart/form-data') { - return 'formData' - } - - if ( - ['application/', 'audio/', 'image/', 'video/'].some((type) => cleanContent.startsWith(type)) - ) { - return 'blob' - } - - if (cleanContent.startsWith('text/')) { - return 'text' - } - - return -} - -const checkForExistence = ( - options: Pick & { - headers: Headers - }, - name?: string -): boolean => { - if (!name) { - return false - } - if ( - options.headers.has(name) || - options.query?.[name] || - options.headers.get('Cookie')?.includes(`${name}=`) - ) { - return true - } - return false -} - -export const setAuthParams = async ({ - security, - ...options -}: Pick, 'security'> & - Pick & { - headers: Headers - }) => { - for (const auth of security) { - if (checkForExistence(options, auth.name)) { - continue - } - - const token = await getAuthToken(auth, options.auth) - - if (!token) { - continue - } - - const name = auth.name ?? 'Authorization' - - switch (auth.in) { - case 'query': - if (!options.query) { - options.query = {} - } - options.query[name] = token - break - case 'cookie': - options.headers.append('Cookie', `${name}=${token}`) - break - case 'header': - default: - options.headers.set(name, token) - break - } - } -} - -export const buildUrl: Client['buildUrl'] = (options) => - getUrl({ - baseUrl: options.baseUrl as string, - path: options.path, - query: options.query, - querySerializer: - typeof options.querySerializer === 'function' - ? options.querySerializer - : createQuerySerializer(options.querySerializer), - url: options.url - }) - -export const mergeConfigs = (a: Config, b: Config): Config => { - const config = { ...a, ...b } - if (config.baseUrl?.endsWith('/')) { - config.baseUrl = config.baseUrl.substring(0, config.baseUrl.length - 1) - } - config.headers = mergeHeaders(a.headers, b.headers) - return config -} - -const headersEntries = (headers: Headers): Array<[string, string]> => { - const entries: Array<[string, string]> = [] - headers.forEach((value, key) => { - entries.push([key, value]) - }) - return entries -} - -export const mergeHeaders = ( - ...headers: Array['headers'] | undefined> -): Headers => { - const mergedHeaders = new Headers() - for (const header of headers) { - if (!header) { - continue - } - - const iterator = header instanceof Headers ? headersEntries(header) : Object.entries(header) - - for (const [key, value] of iterator) { - if (value === null) { - mergedHeaders.delete(key) - } else if (Array.isArray(value)) { - for (const v of value) { - mergedHeaders.append(key, v as string) - } - } else if (value !== undefined) { - // assume object headers are meant to be JSON stringified, i.e. their - // content value in OpenAPI specification is 'application/json' - mergedHeaders.set( - key, - typeof value === 'object' ? JSON.stringify(value) : (value as string) - ) - } - } - } - return mergedHeaders -} - -type ErrInterceptor = ( - error: Err, - response: Res, - request: Req, - options: Options -) => Err | Promise - -type ReqInterceptor = (request: Req, options: Options) => Req | Promise - -type ResInterceptor = ( - response: Res, - request: Req, - options: Options -) => Res | Promise - -class Interceptors { - fns: Array = [] - - clear(): void { - this.fns = [] - } - - eject(id: number | Interceptor): void { - const index = this.getInterceptorIndex(id) - if (this.fns[index]) { - this.fns[index] = null - } - } - - exists(id: number | Interceptor): boolean { - const index = this.getInterceptorIndex(id) - return Boolean(this.fns[index]) - } - - getInterceptorIndex(id: number | Interceptor): number { - if (typeof id === 'number') { - return this.fns[id] ? id : -1 - } - return this.fns.indexOf(id) - } - - update(id: number | Interceptor, fn: Interceptor): number | Interceptor | false { - const index = this.getInterceptorIndex(id) - if (this.fns[index]) { - this.fns[index] = fn - return id - } - return false - } - - use(fn: Interceptor): number { - this.fns.push(fn) - return this.fns.length - 1 - } -} - -export interface Middleware { - error: Interceptors> - request: Interceptors> - response: Interceptors> -} - -export const createInterceptors = (): Middleware< - Req, - Res, - Err, - Options -> => ({ - error: new Interceptors>(), - request: new Interceptors>(), - response: new Interceptors>() -}) - -const defaultQuerySerializer = createQuerySerializer({ - allowReserved: false, - array: { - explode: true, - style: 'form' - }, - object: { - explode: true, - style: 'deepObject' - } -}) - -const defaultHeaders = { - 'Content-Type': 'application/json' -} - -export const createConfig = ( - override: Config & T> = {} -): Config & T> => ({ - ...jsonBodySerializer, - headers: defaultHeaders, - parseAs: 'auto', - querySerializer: defaultQuerySerializer, - ...override -}) diff --git a/examples/integrations/generated/avito/authorization/core/auth.gen.ts b/examples/integrations/generated/avito/authorization/core/auth.gen.ts deleted file mode 100644 index dc8ff61..0000000 --- a/examples/integrations/generated/avito/authorization/core/auth.gen.ts +++ /dev/null @@ -1,41 +0,0 @@ -// This file is auto-generated by @hey-api/openapi-ts - -export type AuthToken = string | undefined - -export interface Auth { - /** - * Which part of the request do we use to send the auth? - * - * @default 'header' - */ - in?: 'header' | 'query' | 'cookie' - /** - * Header or query parameter name. - * - * @default 'Authorization' - */ - name?: string - scheme?: 'basic' | 'bearer' - type: 'apiKey' | 'http' -} - -export const getAuthToken = async ( - auth: Auth, - callback: ((auth: Auth) => Promise | AuthToken) | AuthToken -): Promise => { - const token = typeof callback === 'function' ? await callback(auth) : callback - - if (!token) { - return - } - - if (auth.scheme === 'bearer') { - return `Bearer ${token}` - } - - if (auth.scheme === 'basic') { - return `Basic ${btoa(token)}` - } - - return token -} diff --git a/examples/integrations/generated/avito/authorization/core/bodySerializer.gen.ts b/examples/integrations/generated/avito/authorization/core/bodySerializer.gen.ts deleted file mode 100644 index e39c6a5..0000000 --- a/examples/integrations/generated/avito/authorization/core/bodySerializer.gen.ts +++ /dev/null @@ -1,76 +0,0 @@ -// This file is auto-generated by @hey-api/openapi-ts - -import type { ArrayStyle, ObjectStyle, SerializerOptions } from './pathSerializer.gen' - -export type QuerySerializer = (query: Record) => string - -export type BodySerializer = (body: any) => any - -export interface QuerySerializerOptions { - allowReserved?: boolean - array?: SerializerOptions - object?: SerializerOptions -} - -const serializeFormDataPair = (data: FormData, key: string, value: unknown): void => { - if (typeof value === 'string' || value instanceof Blob) { - data.append(key, value) - } else if (value instanceof Date) { - data.append(key, value.toISOString()) - } else { - data.append(key, JSON.stringify(value)) - } -} - -const serializeUrlSearchParamsPair = (data: URLSearchParams, key: string, value: unknown): void => { - if (typeof value === 'string') { - data.append(key, value) - } else { - data.append(key, JSON.stringify(value)) - } -} - -export const formDataBodySerializer = { - bodySerializer: | Array>>( - body: T - ): FormData => { - const data = new FormData() - - Object.entries(body).forEach(([key, value]) => { - if (value === undefined || value === null) { - return - } - if (Array.isArray(value)) { - value.forEach((v) => serializeFormDataPair(data, key, v)) - } else { - serializeFormDataPair(data, key, value) - } - }) - - return data - } -} - -export const jsonBodySerializer = { - bodySerializer: (body: T): string => - JSON.stringify(body, (_key, value) => (typeof value === 'bigint' ? value.toString() : value)) -} - -export const urlSearchParamsBodySerializer = { - bodySerializer: | Array>>(body: T): string => { - const data = new URLSearchParams() - - Object.entries(body).forEach(([key, value]) => { - if (value === undefined || value === null) { - return - } - if (Array.isArray(value)) { - value.forEach((v) => serializeUrlSearchParamsPair(data, key, v)) - } else { - serializeUrlSearchParamsPair(data, key, value) - } - }) - - return data.toString() - } -} diff --git a/examples/integrations/generated/avito/authorization/core/params.gen.ts b/examples/integrations/generated/avito/authorization/core/params.gen.ts deleted file mode 100644 index 34dddb5..0000000 --- a/examples/integrations/generated/avito/authorization/core/params.gen.ts +++ /dev/null @@ -1,144 +0,0 @@ -// This file is auto-generated by @hey-api/openapi-ts - -type Slot = 'body' | 'headers' | 'path' | 'query' - -export type Field = - | { - in: Exclude - /** - * Field name. This is the name we want the user to see and use. - */ - key: string - /** - * Field mapped name. This is the name we want to use in the request. - * If omitted, we use the same value as `key`. - */ - map?: string - } - | { - in: Extract - /** - * Key isn't required for bodies. - */ - key?: string - map?: string - } - -export interface Fields { - allowExtra?: Partial> - args?: ReadonlyArray -} - -export type FieldsConfig = ReadonlyArray - -const extraPrefixesMap: Record = { - $body_: 'body', - $headers_: 'headers', - $path_: 'path', - $query_: 'query' -} -const extraPrefixes = Object.entries(extraPrefixesMap) - -type KeyMap = Map< - string, - { - in: Slot - map?: string - } -> - -const buildKeyMap = (fields: FieldsConfig, map?: KeyMap): KeyMap => { - if (!map) { - map = new Map() - } - - for (const config of fields) { - if ('in' in config) { - if (config.key) { - map.set(config.key, { - in: config.in, - map: config.map - }) - } - } else if (config.args) { - buildKeyMap(config.args, map) - } - } - - return map -} - -interface Params { - body: unknown - headers: Record - path: Record - query: Record -} - -const stripEmptySlots = (params: Params) => { - for (const [slot, value] of Object.entries(params)) { - if (value && typeof value === 'object' && !Object.keys(value).length) { - delete params[slot as Slot] - } - } -} - -export const buildClientParams = (args: ReadonlyArray, fields: FieldsConfig) => { - const params: Params = { - body: {}, - headers: {}, - path: {}, - query: {} - } - - const map = buildKeyMap(fields) - - let config: FieldsConfig[number] | undefined - - for (const [index, arg] of args.entries()) { - if (fields[index]) { - config = fields[index] - } - - if (!config) { - continue - } - - if ('in' in config) { - if (config.key) { - const field = map.get(config.key)! - const name = field.map || config.key - ;(params[field.in] as Record)[name] = arg - } else { - params.body = arg - } - } else { - for (const [key, value] of Object.entries(arg ?? {})) { - const field = map.get(key) - - if (field) { - const name = field.map || key - ;(params[field.in] as Record)[name] = value - } else { - const extra = extraPrefixes.find(([prefix]) => key.startsWith(prefix)) - - if (extra) { - const [prefix, slot] = extra - ;(params[slot] as Record)[key.slice(prefix.length)] = value - } else { - for (const [slot, allowed] of Object.entries(config.allowExtra ?? {})) { - if (allowed) { - ;(params[slot as Slot] as Record)[key] = value - break - } - } - } - } - } - } - } - - stripEmptySlots(params) - - return params -} diff --git a/examples/integrations/generated/avito/authorization/core/pathSerializer.gen.ts b/examples/integrations/generated/avito/authorization/core/pathSerializer.gen.ts deleted file mode 100644 index acc1367..0000000 --- a/examples/integrations/generated/avito/authorization/core/pathSerializer.gen.ts +++ /dev/null @@ -1,171 +0,0 @@ -// This file is auto-generated by @hey-api/openapi-ts - -interface SerializeOptions extends SerializePrimitiveOptions, SerializerOptions {} - -interface SerializePrimitiveOptions { - allowReserved?: boolean - name: string -} - -export interface SerializerOptions { - /** - * @default true - */ - explode: boolean - style: T -} - -export type ArrayStyle = 'form' | 'spaceDelimited' | 'pipeDelimited' -export type ArraySeparatorStyle = ArrayStyle | MatrixStyle -type MatrixStyle = 'label' | 'matrix' | 'simple' -export type ObjectStyle = 'form' | 'deepObject' -type ObjectSeparatorStyle = ObjectStyle | MatrixStyle - -interface SerializePrimitiveParam extends SerializePrimitiveOptions { - value: string -} - -export const separatorArrayExplode = (style: ArraySeparatorStyle) => { - switch (style) { - case 'label': - return '.' - case 'matrix': - return ';' - case 'simple': - return ',' - default: - return '&' - } -} - -export const separatorArrayNoExplode = (style: ArraySeparatorStyle) => { - switch (style) { - case 'form': - return ',' - case 'pipeDelimited': - return '|' - case 'spaceDelimited': - return '%20' - default: - return ',' - } -} - -export const separatorObjectExplode = (style: ObjectSeparatorStyle) => { - switch (style) { - case 'label': - return '.' - case 'matrix': - return ';' - case 'simple': - return ',' - default: - return '&' - } -} - -export const serializeArrayParam = ({ - allowReserved, - explode, - name, - style, - value -}: SerializeOptions & { - value: unknown[] -}) => { - if (!explode) { - const joinedValues = ( - allowReserved ? value : value.map((v) => encodeURIComponent(v as string)) - ).join(separatorArrayNoExplode(style)) - switch (style) { - case 'label': - return `.${joinedValues}` - case 'matrix': - return `;${name}=${joinedValues}` - case 'simple': - return joinedValues - default: - return `${name}=${joinedValues}` - } - } - - const separator = separatorArrayExplode(style) - const joinedValues = value - .map((v) => { - if (style === 'label' || style === 'simple') { - return allowReserved ? v : encodeURIComponent(v as string) - } - - return serializePrimitiveParam({ - allowReserved, - name, - value: v as string - }) - }) - .join(separator) - return style === 'label' || style === 'matrix' ? separator + joinedValues : joinedValues -} - -export const serializePrimitiveParam = ({ - allowReserved, - name, - value -}: SerializePrimitiveParam) => { - if (value === undefined || value === null) { - return '' - } - - if (typeof value === 'object') { - throw new Error( - 'Deeply-nested arrays/objects aren’t supported. Provide your own `querySerializer()` to handle these.' - ) - } - - return `${name}=${allowReserved ? value : encodeURIComponent(value)}` -} - -export const serializeObjectParam = ({ - allowReserved, - explode, - name, - style, - value, - valueOnly -}: SerializeOptions & { - value: Record | Date - valueOnly?: boolean -}) => { - if (value instanceof Date) { - return valueOnly ? value.toISOString() : `${name}=${value.toISOString()}` - } - - if (style !== 'deepObject' && !explode) { - let values: string[] = [] - Object.entries(value).forEach(([key, v]) => { - values = [...values, key, allowReserved ? (v as string) : encodeURIComponent(v as string)] - }) - const joinedValues = values.join(',') - switch (style) { - case 'form': - return `${name}=${joinedValues}` - case 'label': - return `.${joinedValues}` - case 'matrix': - return `;${name}=${joinedValues}` - default: - return joinedValues - } - } - - const separator = separatorObjectExplode(style) - const joinedValues = Object.entries(value) - .map(([key, v]) => - serializePrimitiveParam({ - allowReserved, - name: style === 'deepObject' ? `${name}[${key}]` : key, - value: v as string - }) - ) - .join(separator) - return style === 'label' || style === 'matrix' ? separator + joinedValues : joinedValues -} diff --git a/examples/integrations/generated/avito/authorization/core/serverSentEvents.gen.ts b/examples/integrations/generated/avito/authorization/core/serverSentEvents.gen.ts deleted file mode 100644 index 372e50c..0000000 --- a/examples/integrations/generated/avito/authorization/core/serverSentEvents.gen.ts +++ /dev/null @@ -1,241 +0,0 @@ -// This file is auto-generated by @hey-api/openapi-ts - -import type { Config } from './types.gen' - -export type ServerSentEventsOptions = Omit & - Pick & { - /** - * Fetch API implementation. You can use this option to provide a custom - * fetch instance. - * - * @default globalThis.fetch - */ - fetch?: typeof fetch - /** - * Implementing clients can call request interceptors inside this hook. - */ - onRequest?: (url: string, init: RequestInit) => Promise - /** - * Callback invoked when a network or parsing error occurs during streaming. - * - * This option applies only if the endpoint returns a stream of events. - * - * @param error The error that occurred. - */ - onSseError?: (error: unknown) => void - /** - * Callback invoked when an event is streamed from the server. - * - * This option applies only if the endpoint returns a stream of events. - * - * @param event Event streamed from the server. - * @returns Nothing (void). - */ - onSseEvent?: (event: StreamEvent) => void - serializedBody?: RequestInit['body'] - /** - * Default retry delay in milliseconds. - * - * This option applies only if the endpoint returns a stream of events. - * - * @default 3000 - */ - sseDefaultRetryDelay?: number - /** - * Maximum number of retry attempts before giving up. - */ - sseMaxRetryAttempts?: number - /** - * Maximum retry delay in milliseconds. - * - * Applies only when exponential backoff is used. - * - * This option applies only if the endpoint returns a stream of events. - * - * @default 30000 - */ - sseMaxRetryDelay?: number - /** - * Optional sleep function for retry backoff. - * - * Defaults to using `setTimeout`. - */ - sseSleepFn?: (ms: number) => Promise - url: string - } - -export interface StreamEvent { - data: TData - event?: string - id?: string - retry?: number -} - -export type ServerSentEventsResult = { - stream: AsyncGenerator< - TData extends Record ? TData[keyof TData] : TData, - TReturn, - TNext - > -} - -export const createSseClient = ({ - onRequest, - onSseError, - onSseEvent, - responseTransformer, - responseValidator, - sseDefaultRetryDelay, - sseMaxRetryAttempts, - sseMaxRetryDelay, - sseSleepFn, - url, - ...options -}: ServerSentEventsOptions): ServerSentEventsResult => { - let lastEventId: string | undefined - - const sleep = sseSleepFn ?? ((ms: number) => new Promise((resolve) => setTimeout(resolve, ms))) - - const createStream = async function* () { - let retryDelay: number = sseDefaultRetryDelay ?? 3000 - let attempt = 0 - const signal = options.signal ?? new AbortController().signal - - while (true) { - if (signal.aborted) break - - attempt++ - - const headers = - options.headers instanceof Headers - ? options.headers - : new Headers(options.headers as Record | undefined) - - if (lastEventId !== undefined) { - headers.set('Last-Event-ID', lastEventId) - } - - try { - const requestInit: RequestInit = { - redirect: 'follow', - ...options, - body: options.serializedBody, - headers, - signal - } - let request = new Request(url, requestInit) - if (onRequest) { - request = await onRequest(url, requestInit) - } - // fetch must be assigned here, otherwise it would throw the error: - // TypeError: Failed to execute 'fetch' on 'Window': Illegal invocation - const _fetch = options.fetch ?? globalThis.fetch - const response = await _fetch(request) - - if (!response.ok) throw new Error(`SSE failed: ${response.status} ${response.statusText}`) - - if (!response.body) throw new Error('No body in SSE response') - - const reader = response.body.pipeThrough(new TextDecoderStream()).getReader() - - let buffer = '' - - const abortHandler = () => { - try { - reader.cancel() - } catch { - // noop - } - } - - signal.addEventListener('abort', abortHandler) - - try { - while (true) { - const { done, value } = await reader.read() - if (done) break - buffer += value - - const chunks = buffer.split('\n\n') - buffer = chunks.pop() ?? '' - - for (const chunk of chunks) { - const lines = chunk.split('\n') - const dataLines: Array = [] - let eventName: string | undefined - - for (const line of lines) { - if (line.startsWith('data:')) { - dataLines.push(line.replace(/^data:\s*/, '')) - } else if (line.startsWith('event:')) { - eventName = line.replace(/^event:\s*/, '') - } else if (line.startsWith('id:')) { - lastEventId = line.replace(/^id:\s*/, '') - } else if (line.startsWith('retry:')) { - const parsed = Number.parseInt(line.replace(/^retry:\s*/, ''), 10) - if (!Number.isNaN(parsed)) { - retryDelay = parsed - } - } - } - - let data: unknown - let parsedJson = false - - if (dataLines.length) { - const rawData = dataLines.join('\n') - try { - data = JSON.parse(rawData) - parsedJson = true - } catch { - data = rawData - } - } - - if (parsedJson) { - if (responseValidator) { - await responseValidator(data) - } - - if (responseTransformer) { - data = await responseTransformer(data) - } - } - - onSseEvent?.({ - data, - event: eventName, - id: lastEventId, - retry: retryDelay - }) - - if (dataLines.length) { - yield data as any - } - } - } - } finally { - signal.removeEventListener('abort', abortHandler) - reader.releaseLock() - } - - break // exit loop on normal completion - } catch (error) { - // connection failed or aborted; retry after delay - onSseError?.(error) - - if (sseMaxRetryAttempts !== undefined && attempt >= sseMaxRetryAttempts) { - break // stop after firing error - } - - // exponential backoff: double retry each attempt, cap at 30s - const backoff = Math.min(retryDelay * 2 ** (attempt - 1), sseMaxRetryDelay ?? 30000) - await sleep(backoff) - } - } - } - - const stream = createStream() - - return { stream } -} diff --git a/examples/integrations/generated/avito/authorization/core/types.gen.ts b/examples/integrations/generated/avito/authorization/core/types.gen.ts deleted file mode 100644 index 647ffcc..0000000 --- a/examples/integrations/generated/avito/authorization/core/types.gen.ts +++ /dev/null @@ -1,104 +0,0 @@ -// This file is auto-generated by @hey-api/openapi-ts - -import type { Auth, AuthToken } from './auth.gen' -import type { BodySerializer, QuerySerializer, QuerySerializerOptions } from './bodySerializer.gen' - -export type HttpMethod = - | 'connect' - | 'delete' - | 'get' - | 'head' - | 'options' - | 'patch' - | 'post' - | 'put' - | 'trace' - -export type Client< - RequestFn = never, - Config = unknown, - MethodFn = never, - BuildUrlFn = never, - SseFn = never -> = { - /** - * Returns the final request URL. - */ - buildUrl: BuildUrlFn - getConfig: () => Config - request: RequestFn - setConfig: (config: Config) => Config -} & { - [K in HttpMethod]: MethodFn -} & ([SseFn] extends [never] ? { sse?: never } : { sse: { [K in HttpMethod]: SseFn } }) - -export interface Config { - /** - * Auth token or a function returning auth token. The resolved value will be - * added to the request payload as defined by its `security` array. - */ - auth?: ((auth: Auth) => Promise | AuthToken) | AuthToken - /** - * A function for serializing request body parameter. By default, - * {@link JSON.stringify()} will be used. - */ - bodySerializer?: BodySerializer | null - /** - * An object containing any HTTP headers that you want to pre-populate your - * `Headers` object with. - * - * {@link https://developer.mozilla.org/docs/Web/API/Headers/Headers#init See more} - */ - headers?: - | RequestInit['headers'] - | Record< - string, - string | number | boolean | (string | number | boolean)[] | null | undefined | unknown - > - /** - * The request method. - * - * {@link https://developer.mozilla.org/docs/Web/API/fetch#method See more} - */ - method?: Uppercase - /** - * A function for serializing request query parameters. By default, arrays - * will be exploded in form style, objects will be exploded in deepObject - * style, and reserved characters are percent-encoded. - * - * This method will have no effect if the native `paramsSerializer()` Axios - * API function is used. - * - * {@link https://swagger.io/docs/specification/serialization/#query View examples} - */ - querySerializer?: QuerySerializer | QuerySerializerOptions - /** - * A function validating request data. This is useful if you want to ensure - * the request conforms to the desired shape, so it can be safely sent to - * the server. - */ - requestValidator?: (data: unknown) => Promise - /** - * A function transforming response data before it's returned. This is useful - * for post-processing data, e.g. converting ISO strings into Date objects. - */ - responseTransformer?: (data: unknown) => Promise - /** - * A function validating response data. This is useful if you want to ensure - * the response conforms to the desired shape, so it can be safely passed to - * the transformers and returned to the user. - */ - responseValidator?: (data: unknown) => Promise -} - -type IsExactlyNeverOrNeverUndefined = [T] extends [never] - ? true - : [T] extends [never | undefined] - ? [undefined] extends [T] - ? false - : true - : false - -export type OmitNever> = { - [K in keyof T as IsExactlyNeverOrNeverUndefined extends true ? never : K]: T[K] -} diff --git a/examples/integrations/generated/avito/authorization/core/utils.gen.ts b/examples/integrations/generated/avito/authorization/core/utils.gen.ts deleted file mode 100644 index bd078be..0000000 --- a/examples/integrations/generated/avito/authorization/core/utils.gen.ts +++ /dev/null @@ -1,140 +0,0 @@ -// This file is auto-generated by @hey-api/openapi-ts - -import type { BodySerializer, QuerySerializer } from './bodySerializer.gen' -import { - type ArraySeparatorStyle, - serializeArrayParam, - serializeObjectParam, - serializePrimitiveParam -} from './pathSerializer.gen' - -export interface PathSerializer { - path: Record - url: string -} - -export const PATH_PARAM_RE = /\{[^{}]+\}/g - -export const defaultPathSerializer = ({ path, url: _url }: PathSerializer) => { - let url = _url - const matches = _url.match(PATH_PARAM_RE) - if (matches) { - for (const match of matches) { - let explode = false - let name = match.substring(1, match.length - 1) - let style: ArraySeparatorStyle = 'simple' - - if (name.endsWith('*')) { - explode = true - name = name.substring(0, name.length - 1) - } - - if (name.startsWith('.')) { - name = name.substring(1) - style = 'label' - } else if (name.startsWith(';')) { - name = name.substring(1) - style = 'matrix' - } - - const value = path[name] - - if (value === undefined || value === null) { - continue - } - - if (Array.isArray(value)) { - url = url.replace(match, serializeArrayParam({ explode, name, style, value })) - continue - } - - if (typeof value === 'object') { - url = url.replace( - match, - serializeObjectParam({ - explode, - name, - style, - value: value as Record, - valueOnly: true - }) - ) - continue - } - - if (style === 'matrix') { - url = url.replace( - match, - `;${serializePrimitiveParam({ - name, - value: value as string - })}` - ) - continue - } - - const replaceValue = encodeURIComponent( - style === 'label' ? `.${value as string}` : (value as string) - ) - url = url.replace(match, replaceValue) - } - } - return url -} - -export const getUrl = ({ - baseUrl, - path, - query, - querySerializer, - url: _url -}: { - baseUrl?: string - path?: Record - query?: Record - querySerializer: QuerySerializer - url: string -}) => { - const pathUrl = _url.startsWith('/') ? _url : `/${_url}` - let url = (baseUrl ?? '') + pathUrl - if (path) { - url = defaultPathSerializer({ path, url }) - } - let search = query ? querySerializer(query) : '' - if (search.startsWith('?')) { - search = search.substring(1) - } - if (search) { - url += `?${search}` - } - return url -} - -export function getValidRequestBody(options: { - body?: unknown - bodySerializer?: BodySerializer | null - serializedBody?: unknown -}) { - const hasBody = options.body !== undefined - const isSerializedBody = hasBody && options.bodySerializer - - if (isSerializedBody) { - if ('serializedBody' in options) { - const hasSerializedBody = - options.serializedBody !== undefined && options.serializedBody !== '' - - return hasSerializedBody ? options.serializedBody : null - } - - // not all clients implement a serializedBody property (i.e. client-axios) - return options.body !== '' ? options.body : null - } - - // plain/text body - if (hasBody) { - return options.body - } - - // no body was provided - return undefined -} diff --git a/examples/integrations/generated/avito/authorization/schemas.gen.ts b/examples/integrations/generated/avito/authorization/schemas.gen.ts deleted file mode 100644 index f84f1f0..0000000 --- a/examples/integrations/generated/avito/authorization/schemas.gen.ts +++ /dev/null @@ -1,59 +0,0 @@ -// This file is auto-generated by @hey-api/openapi-ts - -export const GetTokenOAuthRequestSchema = { - properties: { - client_id: { - type: 'string' - }, - client_secret: { - type: 'string' - }, - code: { - type: 'string' - }, - grant_type: { - default: 'authorization_code', - type: 'string' - } - }, - required: ['grant_type', 'client_id', 'client_secret', 'code'], - type: 'object' -} as const - -export const GetTokenRequestSchema = { - properties: { - client_id: { - type: 'string' - }, - client_secret: { - type: 'string' - }, - grant_type: { - default: 'client_credentials', - type: 'string' - } - }, - required: ['grant_type', 'client_id', 'client_secret'], - type: 'object' -} as const - -export const RefreshRequestSchema = { - properties: { - client_id: { - type: 'string' - }, - client_secret: { - type: 'string' - }, - grant_type: { - default: 'refresh_token', - description: 'Тип OAuth flow. Строка refresh_token', - type: 'string' - }, - refresh_token: { - type: 'string' - } - }, - required: ['grant_type', 'client_id', 'client_secret', 'refresh_token'], - type: 'object' -} as const diff --git a/examples/integrations/generated/avito/authorization/sdk.gen.ts b/examples/integrations/generated/avito/authorization/sdk.gen.ts deleted file mode 100644 index 65969ef..0000000 --- a/examples/integrations/generated/avito/authorization/sdk.gen.ts +++ /dev/null @@ -1,44 +0,0 @@ -// This file is auto-generated by @hey-api/openapi-ts - -import { - type Options as ClientOptions, - type Client, - type TDataShape, - urlSearchParamsBodySerializer -} from './client' -import type { PostTokenData, PostTokenResponses } from './types.gen' -import { client } from './client.gen' - -export type Options< - TData extends TDataShape = TDataShape, - ThrowOnError extends boolean = boolean -> = ClientOptions & { - /** - * You can provide a client instance returned by `createClient()` instead of - * individual options. This might be also useful if you want to implement a - * custom client. - */ - client?: Client - /** - * You can pass arbitrary values through the `meta` object. This can be - * used to access values that aren't defined as part of the SDK function. - */ - meta?: Record -} - -/** - * Получение временного ключа для авторизации - */ -export const postToken = ( - options?: Options -) => { - return (options?.client ?? client).post({ - ...urlSearchParamsBodySerializer, - url: '/token', - ...options, - headers: { - 'Content-Type': 'application/x-www-form-urlencoded', - ...options?.headers - } - }) -} diff --git a/examples/integrations/generated/avito/authorization/types.gen.ts b/examples/integrations/generated/avito/authorization/types.gen.ts deleted file mode 100644 index 6874ce0..0000000 --- a/examples/integrations/generated/avito/authorization/types.gen.ts +++ /dev/null @@ -1,136 +0,0 @@ -// This file is auto-generated by @hey-api/openapi-ts - -export type GetTokenOAuthRequest = { - client_id: string - client_secret: string - code: string - grant_type: string -} - -export type GetTokenRequest = { - client_id: string - client_secret: string - grant_type: string -} - -export type RefreshRequest = { - client_id: string - client_secret: string - /** - * Тип OAuth flow. Строка refresh_token - */ - grant_type: string - refresh_token: string -} - -/** - * Токен для авторизации - */ -export type AuthHeader = string - -/** - * Идентификатор чата (клиента) - */ -export type ChatId = string - -export type ItemIds = string - -/** - * Количество сообщений на странице (положительное число больше 0 и меньше 100) - */ -export type Limit = number - -/** - * Идентификатор сообщения - */ -export type MessageId = string - -export type Offset = number - -/** - * Номер страницы - */ -export type Page = number - -/** - * Идентификатор объявления на сайте - */ -export type PathItemId = bigint - -/** - * Номер пользователя в Личном кабинете Авито - */ -export type PathUserId = bigint - -/** - * Идентификатор вакансии на сайте - */ -export type PathVacancyId = bigint - -/** - * Количество ресурсов на страницу - */ -export type PerPage = number - -export type UnreadOnly = boolean - -/** - * Идентификатор пользователя (клиента) - */ -export type UserId = bigint - -export type PostTokenData = { - body?: GetTokenRequest | GetTokenOAuthRequest | RefreshRequest - path?: never - query?: never - url: '/token' -} - -export type PostTokenResponses = { - /** - * Успешный ответ - */ - 200: - | { - /** - * Ключ для временной авторизации в системе - */ - access_token?: string - /** - * Время жизни ключа в секундах - */ - expires_in?: number - /** - * Тип ключа авторизации - */ - token_type?: string - } - | { - /** - * Ключ для временной авторизации в системе - */ - access_token?: string - /** - * Время жизни ключа в секундах - */ - expires_in?: number - /** - * Ключ для обновления токена доступа - */ - refresh_token?: string - /** - * Полученный скоуп - */ - scope?: string - /** - * Тип ключа авторизации - */ - token_type?: string - } -} - -export type PostTokenResponse = PostTokenResponses[keyof PostTokenResponses] - -export type ClientOptions = { - baseUrl: 'https://api.avito.ru/' | (string & {}) -} diff --git a/examples/integrations/generated/avito/authorization/zod.gen.ts b/examples/integrations/generated/avito/authorization/zod.gen.ts deleted file mode 100644 index ae1b7de..0000000 --- a/examples/integrations/generated/avito/authorization/zod.gen.ts +++ /dev/null @@ -1,103 +0,0 @@ -// This file is auto-generated by @hey-api/openapi-ts - -import { z } from 'zod' - -export const zGetTokenOAuthRequest = z.object({ - client_id: z.string(), - client_secret: z.string(), - code: z.string(), - grant_type: z.string().default('authorization_code') -}) - -export const zGetTokenRequest = z.object({ - client_id: z.string(), - client_secret: z.string(), - grant_type: z.string().default('client_credentials') -}) - -export const zRefreshRequest = z.object({ - client_id: z.string(), - client_secret: z.string(), - grant_type: z.string().default('refresh_token'), - refresh_token: z.string() -}) - -/** - * Токен для авторизации - */ -export const zAuthHeader = z.string() - -/** - * Идентификатор чата (клиента) - */ -export const zChatId = z.string() - -export const zItemIds = z.string() - -/** - * Количество сообщений на странице (положительное число больше 0 и меньше 100) - */ -export const zLimit = z.int().default(100) - -/** - * Идентификатор сообщения - */ -export const zMessageId = z.string() - -export const zOffset = z.int().default(0) - -/** - * Номер страницы - */ -export const zPage = z.int() - -/** - * Идентификатор объявления на сайте - */ -export const zPathItemId = z.coerce.bigint() - -/** - * Номер пользователя в Личном кабинете Авито - */ -export const zPathUserId = z.coerce.bigint() - -/** - * Идентификатор вакансии на сайте - */ -export const zPathVacancyId = z.coerce.bigint() - -/** - * Количество ресурсов на страницу - */ -export const zPerPage = z.int() - -export const zUnreadOnly = z.boolean() - -/** - * Идентификатор пользователя (клиента) - */ -export const zUserId = z.coerce.bigint() - -export const zPostTokenData = z.object({ - body: z.optional(z.union([zGetTokenRequest, zGetTokenOAuthRequest, zRefreshRequest])), - path: z.optional(z.never()), - query: z.optional(z.never()) -}) - -/** - * Успешный ответ - */ -export const zPostTokenResponse = z.union([ - z.object({ - access_token: z.optional(z.string()), - expires_in: z.optional(z.number()), - token_type: z.optional(z.string()) - }), - z.object({ - access_token: z.optional(z.string()), - expires_in: z.optional(z.number()), - refresh_token: z.optional(z.string()), - scope: z.optional(z.string()), - token_type: z.optional(z.string()) - }) -]) diff --git a/examples/integrations/generated/avito/items/client.gen.ts b/examples/integrations/generated/avito/items/client.gen.ts deleted file mode 100644 index a2b0b1d..0000000 --- a/examples/integrations/generated/avito/items/client.gen.ts +++ /dev/null @@ -1,27 +0,0 @@ -// This file is auto-generated by @hey-api/openapi-ts - -import type { ClientOptions } from './types.gen' -import { - type ClientOptions as DefaultClientOptions, - type Config, - createClient, - createConfig -} from './client' - -/** - * The `createClientConfig()` function will be called on client initialization - * and the returned object will become the client's initial configuration. - * - * You may want to initialize your client this way instead of calling - * `setConfig()`. This is useful for example if you're using Next.js - * to ensure your client always has the correct values. - */ -export type CreateClientConfig = ( - override?: Config -) => Config & T> - -export const client = createClient( - createConfig({ - baseUrl: 'https://api.avito.ru/' - }) -) diff --git a/examples/integrations/generated/avito/items/client/client.gen.ts b/examples/integrations/generated/avito/items/client/client.gen.ts deleted file mode 100644 index 4a4fc46..0000000 --- a/examples/integrations/generated/avito/items/client/client.gen.ts +++ /dev/null @@ -1,253 +0,0 @@ -// This file is auto-generated by @hey-api/openapi-ts - -import { createSseClient } from '../core/serverSentEvents.gen' -import type { HttpMethod } from '../core/types.gen' -import { getValidRequestBody } from '../core/utils.gen' -import type { Client, Config, RequestOptions, ResolvedRequestOptions } from './types.gen' -import { - buildUrl, - createConfig, - createInterceptors, - getParseAs, - mergeConfigs, - mergeHeaders, - setAuthParams -} from './utils.gen' - -type ReqInit = Omit & { - body?: any - headers: ReturnType -} - -export const createClient = (config: Config = {}): Client => { - let _config = mergeConfigs(createConfig(), config) - - const getConfig = (): Config => ({ ..._config }) - - const setConfig = (config: Config): Config => { - _config = mergeConfigs(_config, config) - return getConfig() - } - - const interceptors = createInterceptors() - - const beforeRequest = async (options: RequestOptions) => { - const opts = { - ..._config, - ...options, - fetch: options.fetch ?? _config.fetch ?? globalThis.fetch, - headers: mergeHeaders(_config.headers, options.headers), - serializedBody: undefined - } - - if (opts.security) { - await setAuthParams({ - ...opts, - security: opts.security - }) - } - - if (opts.requestValidator) { - await opts.requestValidator(opts) - } - - if (opts.body !== undefined && opts.bodySerializer) { - opts.serializedBody = opts.bodySerializer(opts.body) - } - - // remove Content-Type header if body is empty to avoid sending invalid requests - if (opts.body === undefined || opts.serializedBody === '') { - opts.headers.delete('Content-Type') - } - - const url = buildUrl(opts) - - return { opts, url } - } - - const request: Client['request'] = async (options) => { - // @ts-expect-error - const { opts, url } = await beforeRequest(options) - const requestInit: ReqInit = { - redirect: 'follow', - ...opts, - body: getValidRequestBody(opts) - } - - let request = new Request(url, requestInit) - - for (const fn of interceptors.request.fns) { - if (fn) { - request = await fn(request, opts) - } - } - - // fetch must be assigned here, otherwise it would throw the error: - // TypeError: Failed to execute 'fetch' on 'Window': Illegal invocation - const _fetch = opts.fetch! - let response = await _fetch(request) - - for (const fn of interceptors.response.fns) { - if (fn) { - response = await fn(response, request, opts) - } - } - - const result = { - request, - response - } - - if (response.ok) { - const parseAs = - (opts.parseAs === 'auto' - ? getParseAs(response.headers.get('Content-Type')) - : opts.parseAs) ?? 'json' - - if (response.status === 204 || response.headers.get('Content-Length') === '0') { - let emptyData: any - switch (parseAs) { - case 'arrayBuffer': - case 'blob': - case 'text': - emptyData = await response[parseAs]() - break - case 'formData': - emptyData = new FormData() - break - case 'stream': - emptyData = response.body - break - case 'json': - default: - emptyData = {} - break - } - return opts.responseStyle === 'data' - ? emptyData - : { - data: emptyData, - ...result - } - } - - let data: any - switch (parseAs) { - case 'arrayBuffer': - case 'blob': - case 'formData': - case 'json': - case 'text': - data = await response[parseAs]() - break - case 'stream': - return opts.responseStyle === 'data' - ? response.body - : { - data: response.body, - ...result - } - } - - if (parseAs === 'json') { - if (opts.responseValidator) { - await opts.responseValidator(data) - } - - if (opts.responseTransformer) { - data = await opts.responseTransformer(data) - } - } - - return opts.responseStyle === 'data' - ? data - : { - data, - ...result - } - } - - const textError = await response.text() - let jsonError: unknown - - try { - jsonError = JSON.parse(textError) - } catch { - // noop - } - - const error = jsonError ?? textError - let finalError = error - - for (const fn of interceptors.error.fns) { - if (fn) { - finalError = (await fn(error, response, request, opts)) as string - } - } - - finalError = finalError || ({} as string) - - if (opts.throwOnError) { - throw finalError - } - - // TODO: we probably want to return error and improve types - return opts.responseStyle === 'data' - ? undefined - : { - error: finalError, - ...result - } - } - - const makeMethodFn = (method: Uppercase) => (options: RequestOptions) => - request({ ...options, method }) - - const makeSseFn = (method: Uppercase) => async (options: RequestOptions) => { - const { opts, url } = await beforeRequest(options) - return createSseClient({ - ...opts, - body: opts.body as BodyInit | null | undefined, - headers: opts.headers as unknown as Record, - method, - onRequest: async (url, init) => { - let request = new Request(url, init) - for (const fn of interceptors.request.fns) { - if (fn) { - request = await fn(request, opts) - } - } - return request - }, - url - }) - } - - return { - buildUrl, - connect: makeMethodFn('CONNECT'), - delete: makeMethodFn('DELETE'), - get: makeMethodFn('GET'), - getConfig, - head: makeMethodFn('HEAD'), - interceptors, - options: makeMethodFn('OPTIONS'), - patch: makeMethodFn('PATCH'), - post: makeMethodFn('POST'), - put: makeMethodFn('PUT'), - request, - setConfig, - sse: { - connect: makeSseFn('CONNECT'), - delete: makeSseFn('DELETE'), - get: makeSseFn('GET'), - head: makeSseFn('HEAD'), - options: makeSseFn('OPTIONS'), - patch: makeSseFn('PATCH'), - post: makeSseFn('POST'), - put: makeSseFn('PUT'), - trace: makeSseFn('TRACE') - }, - trace: makeMethodFn('TRACE') - } as Client -} diff --git a/examples/integrations/generated/avito/items/client/types.gen.ts b/examples/integrations/generated/avito/items/client/types.gen.ts deleted file mode 100644 index b97f75e..0000000 --- a/examples/integrations/generated/avito/items/client/types.gen.ts +++ /dev/null @@ -1,226 +0,0 @@ -// This file is auto-generated by @hey-api/openapi-ts - -import type { Auth } from '../core/auth.gen' -import type { ServerSentEventsOptions, ServerSentEventsResult } from '../core/serverSentEvents.gen' -import type { Client as CoreClient, Config as CoreConfig } from '../core/types.gen' -import type { Middleware } from './utils.gen' - -export type ResponseStyle = 'data' | 'fields' - -export interface Config - extends Omit, - CoreConfig { - /** - * Base URL for all requests made by this client. - */ - baseUrl?: T['baseUrl'] - /** - * Fetch API implementation. You can use this option to provide a custom - * fetch instance. - * - * @default globalThis.fetch - */ - fetch?: typeof fetch - /** - * Please don't use the Fetch client for Next.js applications. The `next` - * options won't have any effect. - * - * Install {@link https://www.npmjs.com/package/@hey-api/client-next `@hey-api/client-next`} instead. - */ - next?: never - /** - * Return the response data parsed in a specified format. By default, `auto` - * will infer the appropriate method from the `Content-Type` response header. - * You can override this behavior with any of the {@link Body} methods. - * Select `stream` if you don't want to parse response data at all. - * - * @default 'auto' - */ - parseAs?: 'arrayBuffer' | 'auto' | 'blob' | 'formData' | 'json' | 'stream' | 'text' - /** - * Should we return only data or multiple fields (data, error, response, etc.)? - * - * @default 'fields' - */ - responseStyle?: ResponseStyle - /** - * Throw an error instead of returning it in the response? - * - * @default false - */ - throwOnError?: T['throwOnError'] -} - -export interface RequestOptions< - TData = unknown, - TResponseStyle extends ResponseStyle = 'fields', - ThrowOnError extends boolean = boolean, - Url extends string = string -> extends Config<{ - responseStyle: TResponseStyle - throwOnError: ThrowOnError - }>, - Pick< - ServerSentEventsOptions, - | 'onSseError' - | 'onSseEvent' - | 'sseDefaultRetryDelay' - | 'sseMaxRetryAttempts' - | 'sseMaxRetryDelay' - > { - /** - * Any body that you want to add to your request. - * - * {@link https://developer.mozilla.org/docs/Web/API/fetch#body} - */ - body?: unknown - path?: Record - query?: Record - /** - * Security mechanism(s) to use for the request. - */ - security?: ReadonlyArray - url: Url -} - -export interface ResolvedRequestOptions< - TResponseStyle extends ResponseStyle = 'fields', - ThrowOnError extends boolean = boolean, - Url extends string = string -> extends RequestOptions { - serializedBody?: string -} - -export type RequestResult< - TData = unknown, - TError = unknown, - ThrowOnError extends boolean = boolean, - TResponseStyle extends ResponseStyle = 'fields' -> = ThrowOnError extends true - ? Promise< - TResponseStyle extends 'data' - ? TData extends Record - ? TData[keyof TData] - : TData - : { - data: TData extends Record ? TData[keyof TData] : TData - request: Request - response: Response - } - > - : Promise< - TResponseStyle extends 'data' - ? (TData extends Record ? TData[keyof TData] : TData) | undefined - : ( - | { - data: TData extends Record ? TData[keyof TData] : TData - error: undefined - } - | { - data: undefined - error: TError extends Record ? TError[keyof TError] : TError - } - ) & { - request: Request - response: Response - } - > - -export interface ClientOptions { - baseUrl?: string - responseStyle?: ResponseStyle - throwOnError?: boolean -} - -type MethodFn = < - TData = unknown, - TError = unknown, - ThrowOnError extends boolean = false, - TResponseStyle extends ResponseStyle = 'fields' ->( - options: Omit, 'method'> -) => RequestResult - -type SseFn = < - TData = unknown, - TError = unknown, - ThrowOnError extends boolean = false, - TResponseStyle extends ResponseStyle = 'fields' ->( - options: Omit, 'method'> -) => Promise> - -type RequestFn = < - TData = unknown, - TError = unknown, - ThrowOnError extends boolean = false, - TResponseStyle extends ResponseStyle = 'fields' ->( - options: Omit, 'method'> & - Pick>, 'method'> -) => RequestResult - -type BuildUrlFn = < - TData extends { - body?: unknown - path?: Record - query?: Record - url: string - } ->( - options: Pick & Options -) => string - -export type Client = CoreClient & { - interceptors: Middleware -} - -/** - * The `createClientConfig()` function will be called on client initialization - * and the returned object will become the client's initial configuration. - * - * You may want to initialize your client this way instead of calling - * `setConfig()`. This is useful for example if you're using Next.js - * to ensure your client always has the correct values. - */ -export type CreateClientConfig = ( - override?: Config -) => Config & T> - -export interface TDataShape { - body?: unknown - headers?: unknown - path?: unknown - query?: unknown - url: string -} - -type OmitKeys = Pick> - -export type Options< - TData extends TDataShape = TDataShape, - ThrowOnError extends boolean = boolean, - TResponse = unknown, - TResponseStyle extends ResponseStyle = 'fields' -> = OmitKeys< - RequestOptions, - 'body' | 'path' | 'query' | 'url' -> & - Omit - -export type OptionsLegacyParser< - TData = unknown, - ThrowOnError extends boolean = boolean, - TResponseStyle extends ResponseStyle = 'fields' -> = TData extends { body?: any } - ? TData extends { headers?: any } - ? OmitKeys, 'body' | 'headers' | 'url'> & - TData - : OmitKeys, 'body' | 'url'> & - TData & - Pick, 'headers'> - : TData extends { headers?: any } - ? OmitKeys, 'headers' | 'url'> & - TData & - Pick, 'body'> - : OmitKeys, 'url'> & TData diff --git a/examples/integrations/generated/avito/items/client/utils.gen.ts b/examples/integrations/generated/avito/items/client/utils.gen.ts deleted file mode 100644 index b42b5d9..0000000 --- a/examples/integrations/generated/avito/items/client/utils.gen.ts +++ /dev/null @@ -1,315 +0,0 @@ -// This file is auto-generated by @hey-api/openapi-ts - -import { getAuthToken } from '../core/auth.gen' -import type { QuerySerializerOptions } from '../core/bodySerializer.gen' -import { jsonBodySerializer } from '../core/bodySerializer.gen' -import { - serializeArrayParam, - serializeObjectParam, - serializePrimitiveParam -} from '../core/pathSerializer.gen' -import { getUrl } from '../core/utils.gen' -import type { Client, ClientOptions, Config, RequestOptions } from './types.gen' - -export const createQuerySerializer = ({ - allowReserved, - array, - object -}: QuerySerializerOptions = {}) => { - const querySerializer = (queryParams: T) => { - const search: string[] = [] - if (queryParams && typeof queryParams === 'object') { - for (const name in queryParams) { - const value = queryParams[name] - - if (value === undefined || value === null) { - continue - } - - if (Array.isArray(value)) { - const serializedArray = serializeArrayParam({ - allowReserved, - explode: true, - name, - style: 'form', - value, - ...array - }) - if (serializedArray) search.push(serializedArray) - } else if (typeof value === 'object') { - const serializedObject = serializeObjectParam({ - allowReserved, - explode: true, - name, - style: 'deepObject', - value: value as Record, - ...object - }) - if (serializedObject) search.push(serializedObject) - } else { - const serializedPrimitive = serializePrimitiveParam({ - allowReserved, - name, - value: value as string - }) - if (serializedPrimitive) search.push(serializedPrimitive) - } - } - } - return search.join('&') - } - return querySerializer -} - -/** - * Infers parseAs value from provided Content-Type header. - */ -export const getParseAs = (contentType: string | null): Exclude => { - if (!contentType) { - // If no Content-Type header is provided, the best we can do is return the raw response body, - // which is effectively the same as the 'stream' option. - return 'stream' - } - - const cleanContent = contentType.split(';')[0]?.trim() - - if (!cleanContent) { - return - } - - if (cleanContent.startsWith('application/json') || cleanContent.endsWith('+json')) { - return 'json' - } - - if (cleanContent === 'multipart/form-data') { - return 'formData' - } - - if ( - ['application/', 'audio/', 'image/', 'video/'].some((type) => cleanContent.startsWith(type)) - ) { - return 'blob' - } - - if (cleanContent.startsWith('text/')) { - return 'text' - } - - return -} - -const checkForExistence = ( - options: Pick & { - headers: Headers - }, - name?: string -): boolean => { - if (!name) { - return false - } - if ( - options.headers.has(name) || - options.query?.[name] || - options.headers.get('Cookie')?.includes(`${name}=`) - ) { - return true - } - return false -} - -export const setAuthParams = async ({ - security, - ...options -}: Pick, 'security'> & - Pick & { - headers: Headers - }) => { - for (const auth of security) { - if (checkForExistence(options, auth.name)) { - continue - } - - const token = await getAuthToken(auth, options.auth) - - if (!token) { - continue - } - - const name = auth.name ?? 'Authorization' - - switch (auth.in) { - case 'query': - if (!options.query) { - options.query = {} - } - options.query[name] = token - break - case 'cookie': - options.headers.append('Cookie', `${name}=${token}`) - break - case 'header': - default: - options.headers.set(name, token) - break - } - } -} - -export const buildUrl: Client['buildUrl'] = (options) => - getUrl({ - baseUrl: options.baseUrl as string, - path: options.path, - query: options.query, - querySerializer: - typeof options.querySerializer === 'function' - ? options.querySerializer - : createQuerySerializer(options.querySerializer), - url: options.url - }) - -export const mergeConfigs = (a: Config, b: Config): Config => { - const config = { ...a, ...b } - if (config.baseUrl?.endsWith('/')) { - config.baseUrl = config.baseUrl.substring(0, config.baseUrl.length - 1) - } - config.headers = mergeHeaders(a.headers, b.headers) - return config -} - -const headersEntries = (headers: Headers): Array<[string, string]> => { - const entries: Array<[string, string]> = [] - headers.forEach((value, key) => { - entries.push([key, value]) - }) - return entries -} - -export const mergeHeaders = ( - ...headers: Array['headers'] | undefined> -): Headers => { - const mergedHeaders = new Headers() - for (const header of headers) { - if (!header) { - continue - } - - const iterator = header instanceof Headers ? headersEntries(header) : Object.entries(header) - - for (const [key, value] of iterator) { - if (value === null) { - mergedHeaders.delete(key) - } else if (Array.isArray(value)) { - for (const v of value) { - mergedHeaders.append(key, v as string) - } - } else if (value !== undefined) { - // assume object headers are meant to be JSON stringified, i.e. their - // content value in OpenAPI specification is 'application/json' - mergedHeaders.set( - key, - typeof value === 'object' ? JSON.stringify(value) : (value as string) - ) - } - } - } - return mergedHeaders -} - -type ErrInterceptor = ( - error: Err, - response: Res, - request: Req, - options: Options -) => Err | Promise - -type ReqInterceptor = (request: Req, options: Options) => Req | Promise - -type ResInterceptor = ( - response: Res, - request: Req, - options: Options -) => Res | Promise - -class Interceptors { - fns: Array = [] - - clear(): void { - this.fns = [] - } - - eject(id: number | Interceptor): void { - const index = this.getInterceptorIndex(id) - if (this.fns[index]) { - this.fns[index] = null - } - } - - exists(id: number | Interceptor): boolean { - const index = this.getInterceptorIndex(id) - return Boolean(this.fns[index]) - } - - getInterceptorIndex(id: number | Interceptor): number { - if (typeof id === 'number') { - return this.fns[id] ? id : -1 - } - return this.fns.indexOf(id) - } - - update(id: number | Interceptor, fn: Interceptor): number | Interceptor | false { - const index = this.getInterceptorIndex(id) - if (this.fns[index]) { - this.fns[index] = fn - return id - } - return false - } - - use(fn: Interceptor): number { - this.fns.push(fn) - return this.fns.length - 1 - } -} - -export interface Middleware { - error: Interceptors> - request: Interceptors> - response: Interceptors> -} - -export const createInterceptors = (): Middleware< - Req, - Res, - Err, - Options -> => ({ - error: new Interceptors>(), - request: new Interceptors>(), - response: new Interceptors>() -}) - -const defaultQuerySerializer = createQuerySerializer({ - allowReserved: false, - array: { - explode: true, - style: 'form' - }, - object: { - explode: true, - style: 'deepObject' - } -}) - -const defaultHeaders = { - 'Content-Type': 'application/json' -} - -export const createConfig = ( - override: Config & T> = {} -): Config & T> => ({ - ...jsonBodySerializer, - headers: defaultHeaders, - parseAs: 'auto', - querySerializer: defaultQuerySerializer, - ...override -}) diff --git a/examples/integrations/generated/avito/items/core/auth.gen.ts b/examples/integrations/generated/avito/items/core/auth.gen.ts deleted file mode 100644 index dc8ff61..0000000 --- a/examples/integrations/generated/avito/items/core/auth.gen.ts +++ /dev/null @@ -1,41 +0,0 @@ -// This file is auto-generated by @hey-api/openapi-ts - -export type AuthToken = string | undefined - -export interface Auth { - /** - * Which part of the request do we use to send the auth? - * - * @default 'header' - */ - in?: 'header' | 'query' | 'cookie' - /** - * Header or query parameter name. - * - * @default 'Authorization' - */ - name?: string - scheme?: 'basic' | 'bearer' - type: 'apiKey' | 'http' -} - -export const getAuthToken = async ( - auth: Auth, - callback: ((auth: Auth) => Promise | AuthToken) | AuthToken -): Promise => { - const token = typeof callback === 'function' ? await callback(auth) : callback - - if (!token) { - return - } - - if (auth.scheme === 'bearer') { - return `Bearer ${token}` - } - - if (auth.scheme === 'basic') { - return `Basic ${btoa(token)}` - } - - return token -} diff --git a/examples/integrations/generated/avito/items/core/bodySerializer.gen.ts b/examples/integrations/generated/avito/items/core/bodySerializer.gen.ts deleted file mode 100644 index e39c6a5..0000000 --- a/examples/integrations/generated/avito/items/core/bodySerializer.gen.ts +++ /dev/null @@ -1,76 +0,0 @@ -// This file is auto-generated by @hey-api/openapi-ts - -import type { ArrayStyle, ObjectStyle, SerializerOptions } from './pathSerializer.gen' - -export type QuerySerializer = (query: Record) => string - -export type BodySerializer = (body: any) => any - -export interface QuerySerializerOptions { - allowReserved?: boolean - array?: SerializerOptions - object?: SerializerOptions -} - -const serializeFormDataPair = (data: FormData, key: string, value: unknown): void => { - if (typeof value === 'string' || value instanceof Blob) { - data.append(key, value) - } else if (value instanceof Date) { - data.append(key, value.toISOString()) - } else { - data.append(key, JSON.stringify(value)) - } -} - -const serializeUrlSearchParamsPair = (data: URLSearchParams, key: string, value: unknown): void => { - if (typeof value === 'string') { - data.append(key, value) - } else { - data.append(key, JSON.stringify(value)) - } -} - -export const formDataBodySerializer = { - bodySerializer: | Array>>( - body: T - ): FormData => { - const data = new FormData() - - Object.entries(body).forEach(([key, value]) => { - if (value === undefined || value === null) { - return - } - if (Array.isArray(value)) { - value.forEach((v) => serializeFormDataPair(data, key, v)) - } else { - serializeFormDataPair(data, key, value) - } - }) - - return data - } -} - -export const jsonBodySerializer = { - bodySerializer: (body: T): string => - JSON.stringify(body, (_key, value) => (typeof value === 'bigint' ? value.toString() : value)) -} - -export const urlSearchParamsBodySerializer = { - bodySerializer: | Array>>(body: T): string => { - const data = new URLSearchParams() - - Object.entries(body).forEach(([key, value]) => { - if (value === undefined || value === null) { - return - } - if (Array.isArray(value)) { - value.forEach((v) => serializeUrlSearchParamsPair(data, key, v)) - } else { - serializeUrlSearchParamsPair(data, key, value) - } - }) - - return data.toString() - } -} diff --git a/examples/integrations/generated/avito/items/core/params.gen.ts b/examples/integrations/generated/avito/items/core/params.gen.ts deleted file mode 100644 index 34dddb5..0000000 --- a/examples/integrations/generated/avito/items/core/params.gen.ts +++ /dev/null @@ -1,144 +0,0 @@ -// This file is auto-generated by @hey-api/openapi-ts - -type Slot = 'body' | 'headers' | 'path' | 'query' - -export type Field = - | { - in: Exclude - /** - * Field name. This is the name we want the user to see and use. - */ - key: string - /** - * Field mapped name. This is the name we want to use in the request. - * If omitted, we use the same value as `key`. - */ - map?: string - } - | { - in: Extract - /** - * Key isn't required for bodies. - */ - key?: string - map?: string - } - -export interface Fields { - allowExtra?: Partial> - args?: ReadonlyArray -} - -export type FieldsConfig = ReadonlyArray - -const extraPrefixesMap: Record = { - $body_: 'body', - $headers_: 'headers', - $path_: 'path', - $query_: 'query' -} -const extraPrefixes = Object.entries(extraPrefixesMap) - -type KeyMap = Map< - string, - { - in: Slot - map?: string - } -> - -const buildKeyMap = (fields: FieldsConfig, map?: KeyMap): KeyMap => { - if (!map) { - map = new Map() - } - - for (const config of fields) { - if ('in' in config) { - if (config.key) { - map.set(config.key, { - in: config.in, - map: config.map - }) - } - } else if (config.args) { - buildKeyMap(config.args, map) - } - } - - return map -} - -interface Params { - body: unknown - headers: Record - path: Record - query: Record -} - -const stripEmptySlots = (params: Params) => { - for (const [slot, value] of Object.entries(params)) { - if (value && typeof value === 'object' && !Object.keys(value).length) { - delete params[slot as Slot] - } - } -} - -export const buildClientParams = (args: ReadonlyArray, fields: FieldsConfig) => { - const params: Params = { - body: {}, - headers: {}, - path: {}, - query: {} - } - - const map = buildKeyMap(fields) - - let config: FieldsConfig[number] | undefined - - for (const [index, arg] of args.entries()) { - if (fields[index]) { - config = fields[index] - } - - if (!config) { - continue - } - - if ('in' in config) { - if (config.key) { - const field = map.get(config.key)! - const name = field.map || config.key - ;(params[field.in] as Record)[name] = arg - } else { - params.body = arg - } - } else { - for (const [key, value] of Object.entries(arg ?? {})) { - const field = map.get(key) - - if (field) { - const name = field.map || key - ;(params[field.in] as Record)[name] = value - } else { - const extra = extraPrefixes.find(([prefix]) => key.startsWith(prefix)) - - if (extra) { - const [prefix, slot] = extra - ;(params[slot] as Record)[key.slice(prefix.length)] = value - } else { - for (const [slot, allowed] of Object.entries(config.allowExtra ?? {})) { - if (allowed) { - ;(params[slot as Slot] as Record)[key] = value - break - } - } - } - } - } - } - } - - stripEmptySlots(params) - - return params -} diff --git a/examples/integrations/generated/avito/items/core/pathSerializer.gen.ts b/examples/integrations/generated/avito/items/core/pathSerializer.gen.ts deleted file mode 100644 index acc1367..0000000 --- a/examples/integrations/generated/avito/items/core/pathSerializer.gen.ts +++ /dev/null @@ -1,171 +0,0 @@ -// This file is auto-generated by @hey-api/openapi-ts - -interface SerializeOptions extends SerializePrimitiveOptions, SerializerOptions {} - -interface SerializePrimitiveOptions { - allowReserved?: boolean - name: string -} - -export interface SerializerOptions { - /** - * @default true - */ - explode: boolean - style: T -} - -export type ArrayStyle = 'form' | 'spaceDelimited' | 'pipeDelimited' -export type ArraySeparatorStyle = ArrayStyle | MatrixStyle -type MatrixStyle = 'label' | 'matrix' | 'simple' -export type ObjectStyle = 'form' | 'deepObject' -type ObjectSeparatorStyle = ObjectStyle | MatrixStyle - -interface SerializePrimitiveParam extends SerializePrimitiveOptions { - value: string -} - -export const separatorArrayExplode = (style: ArraySeparatorStyle) => { - switch (style) { - case 'label': - return '.' - case 'matrix': - return ';' - case 'simple': - return ',' - default: - return '&' - } -} - -export const separatorArrayNoExplode = (style: ArraySeparatorStyle) => { - switch (style) { - case 'form': - return ',' - case 'pipeDelimited': - return '|' - case 'spaceDelimited': - return '%20' - default: - return ',' - } -} - -export const separatorObjectExplode = (style: ObjectSeparatorStyle) => { - switch (style) { - case 'label': - return '.' - case 'matrix': - return ';' - case 'simple': - return ',' - default: - return '&' - } -} - -export const serializeArrayParam = ({ - allowReserved, - explode, - name, - style, - value -}: SerializeOptions & { - value: unknown[] -}) => { - if (!explode) { - const joinedValues = ( - allowReserved ? value : value.map((v) => encodeURIComponent(v as string)) - ).join(separatorArrayNoExplode(style)) - switch (style) { - case 'label': - return `.${joinedValues}` - case 'matrix': - return `;${name}=${joinedValues}` - case 'simple': - return joinedValues - default: - return `${name}=${joinedValues}` - } - } - - const separator = separatorArrayExplode(style) - const joinedValues = value - .map((v) => { - if (style === 'label' || style === 'simple') { - return allowReserved ? v : encodeURIComponent(v as string) - } - - return serializePrimitiveParam({ - allowReserved, - name, - value: v as string - }) - }) - .join(separator) - return style === 'label' || style === 'matrix' ? separator + joinedValues : joinedValues -} - -export const serializePrimitiveParam = ({ - allowReserved, - name, - value -}: SerializePrimitiveParam) => { - if (value === undefined || value === null) { - return '' - } - - if (typeof value === 'object') { - throw new Error( - 'Deeply-nested arrays/objects aren’t supported. Provide your own `querySerializer()` to handle these.' - ) - } - - return `${name}=${allowReserved ? value : encodeURIComponent(value)}` -} - -export const serializeObjectParam = ({ - allowReserved, - explode, - name, - style, - value, - valueOnly -}: SerializeOptions & { - value: Record | Date - valueOnly?: boolean -}) => { - if (value instanceof Date) { - return valueOnly ? value.toISOString() : `${name}=${value.toISOString()}` - } - - if (style !== 'deepObject' && !explode) { - let values: string[] = [] - Object.entries(value).forEach(([key, v]) => { - values = [...values, key, allowReserved ? (v as string) : encodeURIComponent(v as string)] - }) - const joinedValues = values.join(',') - switch (style) { - case 'form': - return `${name}=${joinedValues}` - case 'label': - return `.${joinedValues}` - case 'matrix': - return `;${name}=${joinedValues}` - default: - return joinedValues - } - } - - const separator = separatorObjectExplode(style) - const joinedValues = Object.entries(value) - .map(([key, v]) => - serializePrimitiveParam({ - allowReserved, - name: style === 'deepObject' ? `${name}[${key}]` : key, - value: v as string - }) - ) - .join(separator) - return style === 'label' || style === 'matrix' ? separator + joinedValues : joinedValues -} diff --git a/examples/integrations/generated/avito/items/core/serverSentEvents.gen.ts b/examples/integrations/generated/avito/items/core/serverSentEvents.gen.ts deleted file mode 100644 index 372e50c..0000000 --- a/examples/integrations/generated/avito/items/core/serverSentEvents.gen.ts +++ /dev/null @@ -1,241 +0,0 @@ -// This file is auto-generated by @hey-api/openapi-ts - -import type { Config } from './types.gen' - -export type ServerSentEventsOptions = Omit & - Pick & { - /** - * Fetch API implementation. You can use this option to provide a custom - * fetch instance. - * - * @default globalThis.fetch - */ - fetch?: typeof fetch - /** - * Implementing clients can call request interceptors inside this hook. - */ - onRequest?: (url: string, init: RequestInit) => Promise - /** - * Callback invoked when a network or parsing error occurs during streaming. - * - * This option applies only if the endpoint returns a stream of events. - * - * @param error The error that occurred. - */ - onSseError?: (error: unknown) => void - /** - * Callback invoked when an event is streamed from the server. - * - * This option applies only if the endpoint returns a stream of events. - * - * @param event Event streamed from the server. - * @returns Nothing (void). - */ - onSseEvent?: (event: StreamEvent) => void - serializedBody?: RequestInit['body'] - /** - * Default retry delay in milliseconds. - * - * This option applies only if the endpoint returns a stream of events. - * - * @default 3000 - */ - sseDefaultRetryDelay?: number - /** - * Maximum number of retry attempts before giving up. - */ - sseMaxRetryAttempts?: number - /** - * Maximum retry delay in milliseconds. - * - * Applies only when exponential backoff is used. - * - * This option applies only if the endpoint returns a stream of events. - * - * @default 30000 - */ - sseMaxRetryDelay?: number - /** - * Optional sleep function for retry backoff. - * - * Defaults to using `setTimeout`. - */ - sseSleepFn?: (ms: number) => Promise - url: string - } - -export interface StreamEvent { - data: TData - event?: string - id?: string - retry?: number -} - -export type ServerSentEventsResult = { - stream: AsyncGenerator< - TData extends Record ? TData[keyof TData] : TData, - TReturn, - TNext - > -} - -export const createSseClient = ({ - onRequest, - onSseError, - onSseEvent, - responseTransformer, - responseValidator, - sseDefaultRetryDelay, - sseMaxRetryAttempts, - sseMaxRetryDelay, - sseSleepFn, - url, - ...options -}: ServerSentEventsOptions): ServerSentEventsResult => { - let lastEventId: string | undefined - - const sleep = sseSleepFn ?? ((ms: number) => new Promise((resolve) => setTimeout(resolve, ms))) - - const createStream = async function* () { - let retryDelay: number = sseDefaultRetryDelay ?? 3000 - let attempt = 0 - const signal = options.signal ?? new AbortController().signal - - while (true) { - if (signal.aborted) break - - attempt++ - - const headers = - options.headers instanceof Headers - ? options.headers - : new Headers(options.headers as Record | undefined) - - if (lastEventId !== undefined) { - headers.set('Last-Event-ID', lastEventId) - } - - try { - const requestInit: RequestInit = { - redirect: 'follow', - ...options, - body: options.serializedBody, - headers, - signal - } - let request = new Request(url, requestInit) - if (onRequest) { - request = await onRequest(url, requestInit) - } - // fetch must be assigned here, otherwise it would throw the error: - // TypeError: Failed to execute 'fetch' on 'Window': Illegal invocation - const _fetch = options.fetch ?? globalThis.fetch - const response = await _fetch(request) - - if (!response.ok) throw new Error(`SSE failed: ${response.status} ${response.statusText}`) - - if (!response.body) throw new Error('No body in SSE response') - - const reader = response.body.pipeThrough(new TextDecoderStream()).getReader() - - let buffer = '' - - const abortHandler = () => { - try { - reader.cancel() - } catch { - // noop - } - } - - signal.addEventListener('abort', abortHandler) - - try { - while (true) { - const { done, value } = await reader.read() - if (done) break - buffer += value - - const chunks = buffer.split('\n\n') - buffer = chunks.pop() ?? '' - - for (const chunk of chunks) { - const lines = chunk.split('\n') - const dataLines: Array = [] - let eventName: string | undefined - - for (const line of lines) { - if (line.startsWith('data:')) { - dataLines.push(line.replace(/^data:\s*/, '')) - } else if (line.startsWith('event:')) { - eventName = line.replace(/^event:\s*/, '') - } else if (line.startsWith('id:')) { - lastEventId = line.replace(/^id:\s*/, '') - } else if (line.startsWith('retry:')) { - const parsed = Number.parseInt(line.replace(/^retry:\s*/, ''), 10) - if (!Number.isNaN(parsed)) { - retryDelay = parsed - } - } - } - - let data: unknown - let parsedJson = false - - if (dataLines.length) { - const rawData = dataLines.join('\n') - try { - data = JSON.parse(rawData) - parsedJson = true - } catch { - data = rawData - } - } - - if (parsedJson) { - if (responseValidator) { - await responseValidator(data) - } - - if (responseTransformer) { - data = await responseTransformer(data) - } - } - - onSseEvent?.({ - data, - event: eventName, - id: lastEventId, - retry: retryDelay - }) - - if (dataLines.length) { - yield data as any - } - } - } - } finally { - signal.removeEventListener('abort', abortHandler) - reader.releaseLock() - } - - break // exit loop on normal completion - } catch (error) { - // connection failed or aborted; retry after delay - onSseError?.(error) - - if (sseMaxRetryAttempts !== undefined && attempt >= sseMaxRetryAttempts) { - break // stop after firing error - } - - // exponential backoff: double retry each attempt, cap at 30s - const backoff = Math.min(retryDelay * 2 ** (attempt - 1), sseMaxRetryDelay ?? 30000) - await sleep(backoff) - } - } - } - - const stream = createStream() - - return { stream } -} diff --git a/examples/integrations/generated/avito/items/core/types.gen.ts b/examples/integrations/generated/avito/items/core/types.gen.ts deleted file mode 100644 index 647ffcc..0000000 --- a/examples/integrations/generated/avito/items/core/types.gen.ts +++ /dev/null @@ -1,104 +0,0 @@ -// This file is auto-generated by @hey-api/openapi-ts - -import type { Auth, AuthToken } from './auth.gen' -import type { BodySerializer, QuerySerializer, QuerySerializerOptions } from './bodySerializer.gen' - -export type HttpMethod = - | 'connect' - | 'delete' - | 'get' - | 'head' - | 'options' - | 'patch' - | 'post' - | 'put' - | 'trace' - -export type Client< - RequestFn = never, - Config = unknown, - MethodFn = never, - BuildUrlFn = never, - SseFn = never -> = { - /** - * Returns the final request URL. - */ - buildUrl: BuildUrlFn - getConfig: () => Config - request: RequestFn - setConfig: (config: Config) => Config -} & { - [K in HttpMethod]: MethodFn -} & ([SseFn] extends [never] ? { sse?: never } : { sse: { [K in HttpMethod]: SseFn } }) - -export interface Config { - /** - * Auth token or a function returning auth token. The resolved value will be - * added to the request payload as defined by its `security` array. - */ - auth?: ((auth: Auth) => Promise | AuthToken) | AuthToken - /** - * A function for serializing request body parameter. By default, - * {@link JSON.stringify()} will be used. - */ - bodySerializer?: BodySerializer | null - /** - * An object containing any HTTP headers that you want to pre-populate your - * `Headers` object with. - * - * {@link https://developer.mozilla.org/docs/Web/API/Headers/Headers#init See more} - */ - headers?: - | RequestInit['headers'] - | Record< - string, - string | number | boolean | (string | number | boolean)[] | null | undefined | unknown - > - /** - * The request method. - * - * {@link https://developer.mozilla.org/docs/Web/API/fetch#method See more} - */ - method?: Uppercase - /** - * A function for serializing request query parameters. By default, arrays - * will be exploded in form style, objects will be exploded in deepObject - * style, and reserved characters are percent-encoded. - * - * This method will have no effect if the native `paramsSerializer()` Axios - * API function is used. - * - * {@link https://swagger.io/docs/specification/serialization/#query View examples} - */ - querySerializer?: QuerySerializer | QuerySerializerOptions - /** - * A function validating request data. This is useful if you want to ensure - * the request conforms to the desired shape, so it can be safely sent to - * the server. - */ - requestValidator?: (data: unknown) => Promise - /** - * A function transforming response data before it's returned. This is useful - * for post-processing data, e.g. converting ISO strings into Date objects. - */ - responseTransformer?: (data: unknown) => Promise - /** - * A function validating response data. This is useful if you want to ensure - * the response conforms to the desired shape, so it can be safely passed to - * the transformers and returned to the user. - */ - responseValidator?: (data: unknown) => Promise -} - -type IsExactlyNeverOrNeverUndefined = [T] extends [never] - ? true - : [T] extends [never | undefined] - ? [undefined] extends [T] - ? false - : true - : false - -export type OmitNever> = { - [K in keyof T as IsExactlyNeverOrNeverUndefined extends true ? never : K]: T[K] -} diff --git a/examples/integrations/generated/avito/items/core/utils.gen.ts b/examples/integrations/generated/avito/items/core/utils.gen.ts deleted file mode 100644 index bd078be..0000000 --- a/examples/integrations/generated/avito/items/core/utils.gen.ts +++ /dev/null @@ -1,140 +0,0 @@ -// This file is auto-generated by @hey-api/openapi-ts - -import type { BodySerializer, QuerySerializer } from './bodySerializer.gen' -import { - type ArraySeparatorStyle, - serializeArrayParam, - serializeObjectParam, - serializePrimitiveParam -} from './pathSerializer.gen' - -export interface PathSerializer { - path: Record - url: string -} - -export const PATH_PARAM_RE = /\{[^{}]+\}/g - -export const defaultPathSerializer = ({ path, url: _url }: PathSerializer) => { - let url = _url - const matches = _url.match(PATH_PARAM_RE) - if (matches) { - for (const match of matches) { - let explode = false - let name = match.substring(1, match.length - 1) - let style: ArraySeparatorStyle = 'simple' - - if (name.endsWith('*')) { - explode = true - name = name.substring(0, name.length - 1) - } - - if (name.startsWith('.')) { - name = name.substring(1) - style = 'label' - } else if (name.startsWith(';')) { - name = name.substring(1) - style = 'matrix' - } - - const value = path[name] - - if (value === undefined || value === null) { - continue - } - - if (Array.isArray(value)) { - url = url.replace(match, serializeArrayParam({ explode, name, style, value })) - continue - } - - if (typeof value === 'object') { - url = url.replace( - match, - serializeObjectParam({ - explode, - name, - style, - value: value as Record, - valueOnly: true - }) - ) - continue - } - - if (style === 'matrix') { - url = url.replace( - match, - `;${serializePrimitiveParam({ - name, - value: value as string - })}` - ) - continue - } - - const replaceValue = encodeURIComponent( - style === 'label' ? `.${value as string}` : (value as string) - ) - url = url.replace(match, replaceValue) - } - } - return url -} - -export const getUrl = ({ - baseUrl, - path, - query, - querySerializer, - url: _url -}: { - baseUrl?: string - path?: Record - query?: Record - querySerializer: QuerySerializer - url: string -}) => { - const pathUrl = _url.startsWith('/') ? _url : `/${_url}` - let url = (baseUrl ?? '') + pathUrl - if (path) { - url = defaultPathSerializer({ path, url }) - } - let search = query ? querySerializer(query) : '' - if (search.startsWith('?')) { - search = search.substring(1) - } - if (search) { - url += `?${search}` - } - return url -} - -export function getValidRequestBody(options: { - body?: unknown - bodySerializer?: BodySerializer | null - serializedBody?: unknown -}) { - const hasBody = options.body !== undefined - const isSerializedBody = hasBody && options.bodySerializer - - if (isSerializedBody) { - if ('serializedBody' in options) { - const hasSerializedBody = - options.serializedBody !== undefined && options.serializedBody !== '' - - return hasSerializedBody ? options.serializedBody : null - } - - // not all clients implement a serializedBody property (i.e. client-axios) - return options.body !== '' ? options.body : null - } - - // plain/text body - if (hasBody) { - return options.body - } - - // no body was provided - return undefined -} diff --git a/examples/integrations/generated/avito/items/schemas.gen.ts b/examples/integrations/generated/avito/items/schemas.gen.ts deleted file mode 100644 index 7039966..0000000 --- a/examples/integrations/generated/avito/items/schemas.gen.ts +++ /dev/null @@ -1,943 +0,0 @@ -// This file is auto-generated by @hey-api/openapi-ts - -export const AnalyticsRequestSchema = { - properties: { - dateFrom: { - description: 'Дата (в формате YYYY-MM-DD), с которой (включительно) надо получить статистику', - example: '2020-09-01', - format: 'date', - type: 'string' - }, - dateTo: { - description: - 'Дата (в формате YYYY-MM-DD), по которую (включительно) надо получить статистику', - example: '2021-10-15', - format: 'date', - type: 'string' - }, - filter: { - description: 'Набор ограничений, по которым нужно отфильтровать данные', - nullable: true, - properties: { - categoryIDs: { - description: - 'Идентификаторы категорий
[ Справочник идентификаторов категорий ](https://www.avito.st/s/openapi/catalog-categories.xml)', - example: [11, 12], - items: { - type: 'integer' - }, - nullable: true, - type: 'array' - }, - employeeIDs: { - description: - 'Идентификаторы сотрудников
[ Метод получения идентификаторов сотрудников ](https://developers.avito.ru/api-catalog/accounts-hierarchy/documentation#operation/getEmployeesV1)', - example: [41042142, 41042143], - items: { - type: 'integer' - }, - nullable: true, - type: 'array' - } - }, - type: 'object' - }, - grouping: { - $ref: '#/components/schemas/Groupings' - }, - limit: { - description: 'Инструмент пагинации для ограничения количества сущностей в response;', - example: 1000, - maximum: 1000, - minimum: 0, - nullable: true, - type: 'integer' - }, - metrics: { - description: 'Набор доступных показателей, которые должны присутствовать в ответе', - example: ['views', 'contacts', 'presenceSpending'], - items: { - type: 'string' - }, - type: 'array' - }, - offset: { - description: 'инструмент пагинации или смещение, с которого начинается выборка данных;', - example: 0, - minimum: 0, - nullable: true, - type: 'integer' - }, - sort: { - description: 'Сортировка по заданному показателю', - nullable: true, - properties: { - key: { - description: 'Показатель статистики, по которому нужно отсортировать;', - type: 'string' - }, - order: { - description: 'Порядок сортировки (asc, desc);', - enum: ['asc', 'desc'], - type: 'string' - } - }, - required: ['key', 'order'], - type: 'object' - } - }, - required: ['dateFrom', 'dateTo', 'metrics', 'grouping', 'limit', 'offset'], - type: 'object' -} as const - -export const AnalyticsResponseSchema = { - properties: { - result: { - properties: { - dataTotalCount: { - example: 1, - type: 'integer' - }, - groupings: { - example: [ - { - id: 1742860800, - metrics: [ - { - slug: 'views', - value: 100 - }, - { - slug: 'contacts', - value: 100 - }, - { - slug: 'presenceSpending', - value: 1000 - } - ], - type: 'dates' - } - ], - items: { - properties: { - id: { - type: 'integer' - }, - metrics: { - items: { - properties: { - slug: { - example: 'views', - type: 'string' - }, - value: { - format: 'float', - type: 'number' - } - }, - required: ['slug', 'value'], - type: 'object' - }, - type: 'array' - }, - type: { - $ref: '#/components/schemas/Groupings' - } - }, - type: 'object' - }, - type: 'array' - }, - timestamp: { - example: '2021-11-25 15:19:21', - type: 'string' - } - }, - type: 'object' - } - }, - type: 'object' -} as const - -export const ApplyVasRespSchema = { - properties: { - operationId: { - title: 'Уникальный идентификатор операции покупки', - type: 'integer' - } - }, - required: ['operationId'], - type: 'object' -} as const - -export const CallsStatsDaySchema = { - properties: { - answered: { - description: 'Отвеченные звонки', - type: 'integer' - }, - calls: { - description: 'Звонки всего', - type: 'integer' - }, - date: { - description: 'Дата (YYYY-MM-DD)', - type: 'string' - }, - new: { - description: 'Новые звонки', - type: 'integer' - }, - newAnswered: { - description: 'Новые и одновременно отвеченные звонки', - type: 'integer' - } - }, - type: 'object' -} as const - -export const CallsStatsItemSchema = { - properties: { - days: { - description: 'Массив статистики звонков объявления в разрезе дней', - items: { - $ref: '#/components/schemas/CallsStatsDay' - }, - type: 'array' - }, - employeeId: { - description: - 'Идентификатор сотрудника в сервисе иерархии аккаунтов (0 означает, что звонок не аттрибуцирован до сотрудника)', - type: 'integer' - }, - itemId: { - description: - 'Идентификатор объявления (0 означает, что звонок не аттрибуцирован до объявления)', - type: 'integer' - } - }, - required: ['employeeId', 'itemId'], - type: 'object' -} as const - -export const CallsStatsRequestSchema = { - properties: { - dateFrom: { - description: 'Начальная дата периода (YYYY-MM-DD)', - type: 'string' - }, - dateTo: { - description: 'Конечная дата периода (YYYY-MM-DD)', - type: 'string' - }, - itemIds: { - description: 'Идентификаторы объявлений', - items: { - type: 'integer' - }, - type: 'array' - } - }, - required: ['dateFrom', 'dateTo'], - type: 'object' -} as const - -export const CallsStatsResponseSchema = { - properties: { - result: { - properties: { - items: { - description: 'Массив статистики по объявлениям', - items: { - $ref: '#/components/schemas/CallsStatsItem' - }, - type: 'array' - } - }, - required: ['items'], - type: 'object' - } - }, - type: 'object' -} as const - -export const ErrorItemsVasSchema = { - description: - 'Список идентификаторов, которые не удалось обработать по разным причинам (например, они не принадлежат текущему пользователю)', - items: { - type: 'integer' - }, - type: 'array' -} as const - -export const ErrorResponseSchema = { - properties: { - error: { - properties: { - code: { - example: 123, - format: 'int32', - type: 'integer' - }, - message: { - example: 'message about error occurred', - type: 'string' - } - }, - required: ['message', 'code'], - type: 'object' - } - }, - type: 'object' -} as const - -export const FieldErrorSchema = { - properties: { - code: { - description: 'Код ошибки', - type: 'string' - }, - message: { - description: 'Описание ошибки', - type: 'string' - } - }, - required: ['code', 'message'], - type: 'object' -} as const - -export const GroupingsSchema = { - enum: ['day', 'week', 'month', 'item', 'totals'], - type: 'string' -} as const - -export const InfoVasSchema = { - properties: { - finish_time: { - description: 'Дата завершения услуги', - format: 'date-time', - nullable: true, - type: 'string' - }, - schedule: { - description: 'Информация о следующих применениях услуги', - items: { - description: 'Дата следующего применения услуги', - format: 'date-time', - type: 'string' - }, - nullable: true, - type: 'array' - }, - vas_id: { - description: 'Идентификатор услуги', - enum: ['vip', 'highlight', 'pushup', 'premium', 'xl'], - type: 'string' - } - }, - type: 'object' -} as const - -export const ItemInfoAvitoSchema = { - properties: { - autoload_item_id: { - description: - '[Идентификатор объявления](https://autoload.avito.ru/format/realty/#Id) из файла автозагрузки', - nullable: true, - type: 'string' - }, - finish_time: { - description: 'Дата завершения объявления', - format: 'date-time', - nullable: true, - type: 'string' - }, - start_time: { - description: 'Дата создания объявления', - format: 'date-time', - nullable: true, - type: 'string' - }, - status: { - description: 'Статус объявления на сайте', - enum: ['active', 'removed', 'old', 'blocked', 'rejected', 'not_found', 'another_user'], - type: 'string' - }, - url: { - description: 'URL-адрес объявления', - nullable: true, - type: 'string' - }, - vas: { - description: 'Список примененных платных услуг', - items: { - $ref: '#/components/schemas/InfoVas' - }, - nullable: true, - type: 'array' - } - }, - type: 'object' -} as const - -export const ItemVasPricesRespSchema = { - properties: { - itemId: { - description: 'Идентификатор объявления на сайте', - type: 'integer' - }, - stickers: { - items: { - $ref: '#/components/schemas/StickerResp' - }, - type: 'array' - }, - vas: { - items: { - $ref: '#/components/schemas/VasResp' - }, - type: 'array' - } - }, - required: ['vas'], - type: 'object' -} as const - -export const ItemsInfoWithCategoryAvitoSchema = { - properties: { - meta: { - properties: { - page: { - description: 'Номер страницы', - example: 1, - type: 'integer' - }, - per_page: { - description: 'Количество записей на странице', - example: 25, - type: 'integer' - } - }, - type: 'object' - }, - resources: { - items: { - properties: { - address: { - description: 'Адрес объявления', - example: 'Москва, Лесная улица 7', - type: 'string' - }, - category: { - properties: { - id: { - description: 'Идентификатор категории', - example: 111, - format: 'int32', - type: 'integer' - }, - name: { - description: 'Наименование категории', - example: 'Вакансии', - type: 'string' - } - }, - type: 'object' - }, - id: { - description: 'Идентификатор объявления', - example: 24122231, - format: 'int32', - type: 'integer' - }, - price: { - description: 'Цена объявления (null значение означает, что цена не указана)', - example: 35000, - nullable: true, - type: 'integer' - }, - status: { - description: 'Статус объявления на сайте', - enum: ['active', 'removed', 'old', 'blocked', 'rejected'], - type: 'string' - }, - title: { - description: 'Наименование объявления', - example: 'Продавец-кассир', - type: 'string' - }, - url: { - description: 'URL-адрес объявления', - example: 'https://www.avito.ru/rostov-na-donu/vakansii/prodavets_magazina_2142', - nullable: true, - type: 'string' - } - }, - type: 'object' - }, - type: 'array' - } - }, - type: 'object' -} as const - -export const StatisticsCountersSchema = { - items: { - properties: { - itemId: { - description: 'Идентификатор объявления', - format: 'int64', - type: 'integer' - }, - stats: { - items: { - properties: { - contacts: { - deprecated: true, - description: `__DEPRECATED (будет удалено в апреле 2021 г.).__ -__Используйте поле uniqContacts.__ -Запросы контактов объявления. -`, - type: 'integer' - }, - date: { - description: - 'Дата (в формате YYYY-MM-DD), за которую посчитаны статистические счетчики. Для группировок по периодам - дата начала периода.', - format: 'date', - type: 'string' - }, - favorites: { - deprecated: true, - description: - '__DEPRECATED (будет удалено в апреле 2021 г.).__ __Используйте поле uniqFavorites.__ Добавления объявления в избранное', - type: 'integer' - }, - uniqContacts: { - description: 'Уникальные пользователи, запрашивавшие контакты объявления', - type: 'integer' - }, - uniqFavorites: { - description: 'Уникальные пользователи, добавившие объявление в избранное', - type: 'integer' - }, - uniqViews: { - description: 'Уникальные пользователи, просматривавшие объявления', - type: 'integer' - }, - views: { - deprecated: true, - description: `__DEPRECATED (будет удалено в апреле 2021 г.).__ -__Используйте поле uniqViews.__ -Просмотры объявления. -`, - type: 'integer' - } - }, - required: ['date'], - type: 'object' - }, - type: 'array' - } - }, - type: 'object' - }, - type: 'array' -} as const - -export const StatisticsDateFromSchema = { - description: 'Дата (в формате YYYY-MM-DD), с которой (включительно) надо получить статистику', - example: '2020-01-01', - type: 'string' -} as const - -export const StatisticsDateToSchema = { - description: 'Дата (в формате YYYY-MM-DD), по которую (включительно) надо получить статистику', - example: '2020-01-01', - type: 'string' -} as const - -export const StatisticsFieldsSchema = { - description: 'Набор счетчиков, которые должны присутствовать в ответе', - items: { - enum: ['views', 'uniqViews', 'contacts', 'uniqContacts', 'favorites', 'uniqFavorites'], - type: 'string' - }, - type: 'array' -} as const - -export const StatisticsItemIDsSchema = { - description: 'Набор идентификаторов объявлений на сайте', - example: [123456789, 987654321], - items: { - type: 'integer' - }, - required: ['items'], - type: 'array' -} as const - -export const StatisticsPeriodGroupingSchema = { - description: 'Период группировки', - enum: ['day', 'week', 'month'], - type: 'string' -} as const - -export const StatisticsResponseSchema = { - properties: { - errors: { - type: 'object' - }, - result: { - description: 'Статистические счетчики объявления', - properties: { - items: { - $ref: '#/components/schemas/StatisticsCounters' - } - }, - type: 'object' - } - }, - type: 'object' -} as const - -export const StatisticsShallowRequestBodySchema = { - properties: { - dateFrom: { - $ref: '#/components/schemas/StatisticsDateFrom' - }, - dateTo: { - $ref: '#/components/schemas/StatisticsDateTo' - }, - fields: { - $ref: '#/components/schemas/StatisticsFields' - }, - itemIds: { - $ref: '#/components/schemas/StatisticsItemIDs' - }, - periodGrouping: { - $ref: '#/components/schemas/StatisticsPeriodGrouping' - } - }, - required: ['itemIds', 'dateFrom', 'dateTo'], - type: 'object' -} as const - -export const StickerRespSchema = { - description: 'Информация о значках для переданного списка объявлений', - properties: { - description: { - description: 'Описание значка', - type: 'string' - }, - id: { - description: 'Идентификатор значка', - type: 'integer' - }, - title: { - description: 'Название значка', - type: 'string' - } - }, - required: ['id', 'title', 'description'], - type: 'object' -} as const - -export const UpdatePriceRequestSchema = { - properties: { - price: { - description: 'Цена', - example: 100, - type: 'integer' - } - }, - required: ['price'], - type: 'object' -} as const - -export const UpdatePriceResponseSchema = { - properties: { - result: { - properties: { - success: { - type: 'boolean' - } - }, - type: 'object' - } - }, - required: ['result'], - type: 'object' -} as const - -export const VasAmountAvitoSchema = { - properties: { - amount: { - description: 'Сумма списания за применение услуги или пакета', - format: 'float', - type: 'number' - } - }, - type: 'object' -} as const - -export const VasApplyAvitoSchema = { - properties: { - amount: { - description: 'Сумма списания за применение услуги', - format: 'float', - type: 'number' - }, - vas: { - $ref: '#/components/schemas/InfoVas' - } - }, - type: 'object' -} as const - -export const VasPricesRespSchema = { - items: { - $ref: '#/components/schemas/ItemVasPricesResp' - }, - type: 'array' -} as const - -export const VasRespSchema = { - description: - 'Информация об услугах и пакетах дополнительных услуг для переданного списка объявлений', - properties: { - price: { - description: 'Цена со скидкой', - example: 200, - type: 'integer' - }, - priceOld: { - description: 'Цена до применения скидки', - example: 300, - type: 'integer' - }, - slug: { - description: 'Идентификатор услуги или пакета услуг', - example: 'x2_1', - type: 'string' - } - }, - required: ['slug', 'price', 'priceOld'], - type: 'object' -} as const - -export const authErrorSchema = { - properties: { - error: { - properties: { - code: { - description: 'Код ошибки', - example: 401, - format: 'int32', - type: 'integer' - }, - message: { - description: 'Сообщение об ошибке', - example: 'Unauthorized', - type: 'string' - } - }, - required: ['code', 'message'], - type: 'object' - } - }, - type: 'object' -} as const - -export const badRequestErrorSchema = { - properties: { - error: { - properties: { - code: { - description: 'Код ошибки', - example: 400, - format: 'int32', - type: 'integer' - }, - message: { - description: 'Сообщение об ошибке', - example: 'Bad Request', - type: 'string' - } - }, - required: ['code', 'message'], - type: 'object' - } - }, - type: 'object' -} as const - -export const itemIdsRequestBodySchema = { - properties: { - item_ids: { - description: 'Набор идентификаторов объявлений на сайте', - items: { - type: 'integer' - }, - type: 'array' - } - }, - required: ['item_ids'], - type: 'object' -} as const - -export const notFoundErrorSchema = { - properties: { - error: { - properties: { - code: { - description: 'Код ошибки', - example: 404, - format: 'int32', - type: 'integer' - }, - message: { - description: 'Сообщение об ошибке', - example: 'Not found', - type: 'string' - } - }, - required: ['code', 'message'], - type: 'object' - } - }, - type: 'object' -} as const - -export const packageIdRequestBodyV2Schema = { - properties: { - package_id: { - description: `Идентификатор пакета услуг, возможные варианты значения: -- \`x2_1\` - применение пакета До 2 раз больше просмотров на 1 день -- \`x2_7\` - применение пакета До 2 раз больше просмотров на 7 дней -- \`x5_1\` - применение пакета До 5 раз больше просмотров на 1 день -- \`x5_7\` - применение пакета До 5 раз больше просмотров на 7 дней -- \`x10_1\` - применение пакета До 10 раз больше просмотров на 1 день -- \`x10_7\` - применение пакета До 10 раз больше просмотров на 7 дней - -В некоторых регионах и категориях также доступны дополнительные варианты: -- \`x15_1\` - применение пакета До 15 раз больше просмотров на 1 день -- \`x15_7\` - применение пакета До 15 раз больше просмотров на 7 дней -- \`x20_1\` - применение пакета До 20 раз больше просмотров на 1 день -- \`x20_7\` - применение пакета До 20 раз больше просмотров на 7 дней - -Если попытаться применить эти пакеты в недоступных для них регионе и категории, оплата не пройдёт. -`, - enum: ['x2_1', 'x2_7', 'x5_1', 'x5_7', 'x10_1', 'x10_7', 'x15_1', 'x15_7', 'x20_1', 'x20_7'], - type: 'string' - } - }, - required: ['package_id'], - type: 'object' -} as const - -export const pricesItemIdsRequestBodySchema = { - properties: { - itemIds: { - description: 'Набор идентификаторов объявлений на сайте', - items: { - type: 'integer' - }, - type: 'array' - } - }, - required: ['itemIds'], - type: 'object' -} as const - -export const serviceErrorSchema = { - properties: { - error: { - properties: { - code: { - description: 'Код ошибки', - example: 500, - format: 'int32', - type: 'integer' - }, - message: { - description: 'Описание ошибки', - example: 'Error while processing request. Please, contact support', - type: 'string' - } - }, - required: ['code', 'message'], - type: 'object' - } - }, - type: 'object' -} as const - -export const serviceUnavailableErrorSchema = { - properties: { - error: { - properties: { - code: { - description: 'Код ошибки', - example: 503, - format: 'int32', - type: 'integer' - }, - message: { - description: 'Описание ошибки', - example: 'Service temporarily unavailable. Please, contact support', - type: 'string' - } - }, - required: ['code', 'message'], - type: 'object' - } - }, - type: 'object' -} as const - -export const tooManyRequestsSchema = { - type: 'object' -} as const - -export const validatingErrorSchema = { - properties: { - error: { - properties: { - code: { - description: 'Код ошибки', - example: 400, - format: 'int32', - type: 'integer' - }, - fields: { - description: 'Информация об ошибке валидации параметров в формате ключ-значение', - nullable: true, - type: 'object' - }, - message: { - description: 'Сообщение об ошибке', - example: 'Validation error', - type: 'string' - } - }, - required: ['code', 'message'], - type: 'object' - } - }, - type: 'object' -} as const - -export const vasIdRequestBodySchema = { - properties: { - vas_id: { - description: `Идентификатор услуги, возможные его варианты значения: -- \`highlight\` — [выделение объявления](https://support.avito.ru/articles/200026858) -- \`xl\` – [XL-объявление](https://support.avito.ru/articles/685) -`, - enum: ['highlight', 'xl'], - type: 'string' - } - }, - required: ['vas_id'], - type: 'object' -} as const diff --git a/examples/integrations/generated/avito/items/sdk.gen.ts b/examples/integrations/generated/avito/items/sdk.gen.ts deleted file mode 100644 index 603538f..0000000 --- a/examples/integrations/generated/avito/items/sdk.gen.ts +++ /dev/null @@ -1,515 +0,0 @@ -// This file is auto-generated by @hey-api/openapi-ts - -import type { Options as ClientOptions, Client, TDataShape } from './client' -import type { - VasPricesData, - VasPricesResponses, - VasPricesErrors, - PostCallsStatsData, - PostCallsStatsResponses, - PostCallsStatsErrors, - GetItemInfoData, - GetItemInfoResponses, - GetItemInfoErrors, - PutItemVasData, - PutItemVasResponses, - PutItemVasErrors, - GetItemsInfoData, - GetItemsInfoResponses, - GetItemsInfoErrors, - UpdatePriceData, - UpdatePriceResponses, - UpdatePriceErrors, - PutItemVasPackageV2Data, - PutItemVasPackageV2Responses, - PutItemVasPackageV2Errors, - ApplyVasData, - ApplyVasResponses, - ApplyVasErrors, - ItemStatsShallowData, - ItemStatsShallowResponses, - ItemStatsShallowErrors, - ItemAnalyticsData, - ItemAnalyticsResponses, - ItemAnalyticsErrors -} from './types.gen' -import { client } from './client.gen' -import { - getItemInfoResponseTransformer, - putItemVasResponseTransformer, - itemStatsShallowResponseTransformer -} from './transformers.gen' - -export type Options< - TData extends TDataShape = TDataShape, - ThrowOnError extends boolean = boolean -> = ClientOptions & { - /** - * You can provide a client instance returned by `createClient()` instead of - * individual options. This might be also useful if you want to implement a - * custom client. - */ - client?: Client - /** - * You can pass arbitrary values through the `meta` object. This can be - * used to access values that aren't defined as part of the SDK function. - */ - meta?: Record -} - -/** - * Получение информации о стоимости услуг продвижения и доступных значках - * Возвращает в ответ список объектов со следующей структурой: - * - `itemId` – идентификатор объявления - * - `vas` – список объектов, которые содержат информацию о стоимости дополнительных услуг и пакетов дополнительных услуг для каждого объявления. Структура объекта: - * - `slug` – идентификатор услуги или пакета услуг: - * - `highlight` — [услуга продвижения "Выделить"](https://support.avito.ru/articles/200026858) - * - `xl` – [услуга продвижения "XL-объявление"](https://support.avito.ru/articles/685) - * - `stickerpack_x1` – [1 значок на XL-объявлении](https://support.avito.ru/articles/2450) - * - `stickerpack_x2` – [2 значка на XL-объявлении](https://support.avito.ru/articles/2450) - * - `stickerpack_x3` – [3 значка на XL-объявлении](https://support.avito.ru/articles/2450) - * - * - `x2_1` – [пакет "до 2 раз больше просмотров на 1 день"](https://support.avito.ru/articles/1398) - * - `x2_7` – [пакет "до 2 раз больше просмотров на 7 дней"](https://support.avito.ru/articles/1398) - * - `x5_1` – [пакет "до 5 раз больше просмотров на 1 день"](https://support.avito.ru/articles/1398) - * - `x5_7` – [пакет "до 5 раз больше просмотров на 7 дней"](https://support.avito.ru/articles/1398) - * - `x10_1` – [пакет "до 10 раз больше просмотров на 1 день"](https://support.avito.ru/articles/1398) - * - `x10_7` – [пакет "до 10 раз больше просмотров на 7 дней"](https://support.avito.ru/articles/1398) - * - `x15_1` – [пакет "до 15 раз больше просмотров на 1 день"](https://support.avito.ru/articles/1398) - * - `x15_7` – [пакет "до 15 раз больше просмотров на 7 дней"](https://support.avito.ru/articles/1398) - * - `x20_1` – [пакет "до 20 раз больше просмотров на 1 день"](https://support.avito.ru/articles/1398) - * - `x20_7` – [пакет "до 20 раз больше просмотров на 7 дней"](https://support.avito.ru/articles/1398) - * - * - `price` – цена в рублях с учетом скидки - * - * - `priceOld` – цена в рублях до применения скидки - * - * - `stickers` – список объектов которые содержат доступные для объявления [значки](https://support.avito.ru/articles/2450) - * - `id` – идентификатор значка - * - `title` – название значка - * - `description` – описание значка - * - */ -export const vasPrices = ( - options: Options -) => { - return (options.client ?? client).post({ - security: [ - { - scheme: 'bearer', - type: 'http' - }, - { - scheme: 'bearer', - type: 'http' - } - ], - url: '/core/v1/accounts/{userId}/vas/prices', - ...options, - headers: { - 'Content-Type': 'application/json', - ...options.headers - } - }) -} - -/** - * Получение статистики по звонкам - * Получение агрегированной статистики звонков, полученных пользователем - * - */ -export const postCallsStats = ( - options: Options -) => { - return (options.client ?? client).post< - PostCallsStatsResponses, - PostCallsStatsErrors, - ThrowOnError - >({ - security: [ - { - scheme: 'bearer', - type: 'http' - }, - { - scheme: 'bearer', - type: 'http' - } - ], - url: '/core/v1/accounts/{user_id}/calls/stats/', - ...options - }) -} - -/** - * Получение информации по объявлению - * Возвращает данные об объявлении - его статус, список примененных услуг Максимальное количество запросов в минуту - 500 - * **Внимание:** для получения статистики объявления должен использоваться метод: - * [получение статистики по списку объявлений](#operation/itemStatsShallow) - * - */ -export const getItemInfo = ( - options: Options -) => { - return (options.client ?? client).get({ - responseTransformer: getItemInfoResponseTransformer, - security: [ - { - scheme: 'bearer', - type: 'http' - }, - { - scheme: 'bearer', - type: 'http' - } - ], - url: '/core/v1/accounts/{user_id}/items/{item_id}/', - ...options - }) -} - -/** - * Применение дополнительных услуг - * **Внимание:** метод объявлен устаревшим и больше не поддерживается. Вместо него используйте метод `/core/v2/items/{itemId}/vas/` - * - * Применение дополнительной услуги к объявлению, в ответе возвращает данные о примененной услуге и сумму списания. - * [Более подробная информация по дополнительным услугам](https://support.avito.ru/sections/200009758) - * - * **Внимание:** получение ошибки при выполнении этой операции не означает, что услуга точно не была куплена. - * В этом случае рекомендуется подождать несколько минут и проверить, что услуга отсутствует в списке применённых, а только затем повторить попытку. - * - */ -export const putItemVas = ( - options: Options -) => { - return (options.client ?? client).put({ - responseTransformer: putItemVasResponseTransformer, - security: [ - { - scheme: 'bearer', - type: 'http' - }, - { - scheme: 'bearer', - type: 'http' - } - ], - url: '/core/v1/accounts/{user_id}/items/{item_id}/vas', - ...options, - headers: { - 'Content-Type': 'application/json', - ...options.headers - } - }) -} - -/** - * Получение информации по объявлениям - * Возвращает список объявлений авторизованного пользователя - статус, категорию и ссылку на сайте. - * **Внимание! В настоящий момент этот метод не работает с объявлениями [сотрудников](https://pro.avito.ru/employees).** Он позволяет получить объявления только для пользователя, который указан владельцем этого объявления. В случае сотрудника это будет главный аккаунт компании, для авторизованного сотрудника вернётся пустой список объявлений. - * - */ -export const getItemsInfo = ( - options: Options -) => { - return (options.client ?? client).get({ - security: [ - { - scheme: 'bearer', - type: 'http' - }, - { - scheme: 'bearer', - type: 'http' - } - ], - url: '/core/v1/items', - ...options - }) -} - -/** - * Обновление цены объявления - * - * Обновляет цену товара по id. - * Максимальное количество запросов в минуту - 150. - * **Внимание! Доступно для категорий Товары, Запчасти, Авто, Недвижимость (кроме краткосрочной)** - * - */ -export const updatePrice = ( - options: Options -) => { - return (options.client ?? client).post({ - security: [ - { - scheme: 'bearer', - type: 'http' - }, - { - scheme: 'bearer', - type: 'http' - } - ], - url: '/core/v1/items/{item_id}/update_price', - ...options, - headers: { - 'Content-Type': 'application/json', - ...options.headers - } - }) -} - -/** - * Применение пакета дополнительных услуг - * **Внимание:** метод объявлен устаревшим и больше не поддерживается. Вместо него используйте метод `/core/v2/items/{itemId}/vas/` - * - * Применение пакета дополнительных услуг к объявлению, в ответе возвращает сумму списания. - * - * **Внимание:** получение ошибки при выполнении этой операции не означает, что пакет точно не была куплен. - * В этом случае рекомендуется подождать несколько минут и проверить, что пакет отсутствует в списке применённых, а только затем повторить попытку. - * - */ -export const putItemVasPackageV2 = ( - options: Options -) => { - return (options.client ?? client).put< - PutItemVasPackageV2Responses, - PutItemVasPackageV2Errors, - ThrowOnError - >({ - security: [ - { - scheme: 'bearer', - type: 'http' - }, - { - scheme: 'bearer', - type: 'http' - } - ], - url: '/core/v2/accounts/{user_id}/items/{item_id}/vas_packages', - ...options, - headers: { - 'Content-Type': 'application/json', - ...options.headers - } - }) -} - -/** - * Применение услуг продвижения - * С помощью этого метода вы можете применить к опубликованному объявлению одну или несколько услуг продвижения (например, «XL-объявление», «Выделение цветом» и «До 10 раз больше просмотров на 7 дней»). В рамках одного запроса услуга может быть применена только один раз. - * - * Если для вашего объявления доступны значки (такие как «Без ДТП», «Срочно», «1 владелец»), при подключении услуги «XL-объявление» вы можете передать их список (не более трёх значков). В этом случае добавьте соответствующую услугу на 1, 2 или 3 значка. - * - * [Подробнее об услугах продвижения](https://support.avito.ru/partitions/131) - * - * Чтобы получить список доступных услуг и значков, используйте метод `/core/v1/accounts/{userId}/vas/prices`. - * - * Если заказ сформирован успешно, в ответ вы получите уникальные идентификаторы операций покупки для каждой из применяемых услуг. Позже эти идентификаторы можно будет использовать, чтобы узнать статус выполнения заказа. - * - * В случае некорректного запроса метод вернет код ответа 400 и структуру, содержащую поле `code`. Возможные коды ошибок: - * - **1001** – один или несколько заголовков неправильно передаются; - * - **1002** – ошибка в URL; - * - **1003** – неверный идентификатор объявления из запроса; - * - **1004** – JSON из тела запроса не соответствует схеме или список идентификаторов услуг пустой; - * - **1005** – объявление, к которому вы хотите применить услуги, неактивно; - * - **1006** – неправильное количество выбранных значков для объявления. - * Убедитесь, что в списке идентификаторов услуг есть услуга для покупки значков и она совпадает с количеством выбранных значков. - * - stickerpack_x1 – 1 значок - * - stickerpack_x2 – 2 значка - * - stickerpack_x3 – 3 значка - * - **1007** – некоторые из выбранных услуг не могут быть применены; - * - **1008** – в объявлении появились обязательные поля, которые нужно заполнить. - * Отредактируйте объявление и попробуйте применить услугу снова. - * - **1009** – в кошельке не хватает средств для покупки услуг; - * - **1010** – вы пытались купить больше одной услуги увеличения просмотров; - * - **1011** – вы пытались купить значки, недоступные для выбранного объявления. - * - * В случае внутренней ошибки на стороне Авито вернётся код ответа 500 и структура, содержащая поле `code`. Возможные коды ошибок: - * - **1000** – ошибка на стороне Авито, попробуйте позже или [напишите в поддержку](https://support.avito.ru/request/659?eventData[contextId]=117); - * - * **Важно:** если ответ пришёл без кода ошибки или его значения нет в списке выше — возможно, услуга всё-таки была куплена. Подождите несколько минут: услуга продвижения появится в списке применённых, а если нет — попробуйте оформить её снова. - * - */ -export const applyVas = ( - options: Options -) => { - return (options.client ?? client).put({ - security: [ - { - scheme: 'bearer', - type: 'http' - }, - { - scheme: 'bearer', - type: 'http' - } - ], - url: '/core/v2/items/{itemId}/vas/', - ...options, - headers: { - 'Content-Type': 'application/json', - ...options.headers - } - }) -} - -/** - * Получение статистики по списку объявлений - * Получение счетчиков по переданному списку объявлений пользователя. - * - * **Внимание:** в запросе может быть передано не более 200 идентификаторов объявлений. - * - * **Внимание:** глубина такого запроса ограничена 270 днями. - * - * ### Счетчики - * * ~~views - общее число просмотров объявления;~~ __DEPRECATED (будет удалено в апреле 2021 г.).__ Используйте поле uniqViews. - * * uniqViews - число уникальных пользователей, просмотревших объявление; - * * ~~contacts - число контактов [1];~~ __DEPRECATED (будет удалено в апреле 2021 г.).__ Используйте поле uniqContacts. - * * uniqContacts - число уникальных пользователей, совершивших контакты [1]; - * * ~~favorites - число добавлений объявления в "избранное";~~ __DEPRECATED (будет удалено в апреле 2021 г.).__ Используйте поле uniqFavorites. - * * uniqFavorites - число уникальных пользователей, добавивших объявление в "избранное". - * - * ### Группировка счетчиков - * Счетчики могут быть сгруппированы [2] по: - * * дням; - * * неделям - в поле `date` соответствующей структуры будет первый день недели; - * * месяцам - в поле `date` соответствующей структуры будет первый день месяца. - * - * #### Период группировки - * Период группировки передается в теле запроса в поле `periodGrouping`. Доступные значения этого поля: - * * "day" (по умолчанию) - без группировки; - * * "week" - суммирование счетчиков за неделю; - * * "month" - суммирование счетчиков за месяц. - * - * ### Примечания - * * [1]: Под контактом понимаются: запросы телефона продавца, начатый чат с продавцом по конкретному объявлению, отклик на резюме и пр. - * * [2]: Группировка уникальных пользователей происходит только в рамках одного дня. - * - */ -export const itemStatsShallow = ( - options: Options -) => { - return (options.client ?? client).post< - ItemStatsShallowResponses, - ItemStatsShallowErrors, - ThrowOnError - >({ - responseTransformer: itemStatsShallowResponseTransformer, - security: [ - { - scheme: 'bearer', - type: 'http' - }, - { - scheme: 'bearer', - type: 'http' - } - ], - url: '/stats/v1/accounts/{user_id}/items', - ...options - }) -} - -/** - * Получение статистических показателей по профилю - * Получение статистических показателей по профилю. - * ### Группировки показателей - * Используйте группировки, чтобы получать конкретную статистику. Например, можете запросить только общие значения показателей, а если нужны подробности, — значения показателей по каждому объявлению или за определённый период. Доступные группировки: - * - * - **totals** — по общему значению показателя за определённый период, без детализации; - * - **item** — по объявлениям; - * - **day** — по дням; - * - **week** — по неделям; - * - **month** — по месяцам. - * - * - * ### Доступные показатели по объявлениям - * #### Основные - * - * - **views** - Просмотры. Сколько раз объявление показывалось в результатах поиска и рекомендациях. Несколько показов за сутки одному пользователю считаются как один. - * - **contacts** - Контакты. Количество пользователей, которые посмотрели ваш номер, написали в чат или откликнулись на скидку после рассылки. Несколько контактов за сутки от одного пользователя считаются как один. - * - **contactsShowPhone** - Посмотрели телефон. Количество пользователей, которые посмотрели ваш телефон или нажали «Позвонить». Несколько таких действий за сутки от одного пользователя считаются как один. - * - **contactsMessenger** - Написали в чат. Количество пользователей, которые написали вам. Несколько чатов за сутки от одного пользователя считаются как один. - * - **contactsShowPhoneAndMessenger** - Посмотрели телефон и написали в чат. Количество пользователей, которые и посмотрели ваш телефон, и написали в чат. Несколько таких действий за сутки от одного пользователя считаются как один. - * - **contactsSbcDiscount** - Откликнулись на скидку в чате. Количество пользователей, которые приняли ваше спецпредложение после рассылки. - * - **viewsToContactsConversion** - Конверсия из просмотров в контакты. Процент пользователей, которые после перехода в объявление посмотрели ваш телефон или написали в чат. - * - **favorites** - Добавили в избранное. Сколько раз объявление добавили в избранное. - * - **averageViewCost** - Средняя цена просмотра. Расходы на размещение и продвижение объявлений делятся на число просмотров. - * - **averageContactCost** - Средняя цена контакта. Расходы на размещение и продвижение объявлений делятся на число контактов. - * - **impressions** - Показы. Сколько раз объявление показывалось в результатах поиска и рекомендациях. Несколько показов за сутки одному пользователю считаются как один. - * - **impressionsToViewsConversion** - Конверсия из показов в просмотры. Процент пользователей, которые перешли в объявление после того, как оно показалось в результатах поиска и рекомендациях. - * - * - * #### Целевые действия - * - * - **clickPackages** - Целевые просмотры. Просмотры, которые оплачены из тарифа и считаются целевыми [по правилам Авито](https://www.avito.ru/legal/rules/paid_services/cost-per-action/#clicks). - * - **jobContacts** - Отклики на вакансии. Отклики, которые оплачены из тарифа и считаются целевыми [по правилам Авито](https://www.avito.ru/legal/rules/paid_services/cost-per-action/#clicks). - * - * - * #### Заказы с Авито Доставкой - * - * - **viewsToOrderedItemsConversion** - Конверсия из просмотров в заказанные товары. Процент пользователей, которые после перехода в объявление заказали товар. - * - **orderedItems** - Заказано товаров. Количество товаров, которые заказали с Авито Доставкой. - * - **orderedItemsPrice** - Стоимость заказанных товаров в копейках. Общая стоимость заказов. Это сумма, которую вы получите на руки, если клиенты примут заказы. - * - **deliveredItems** - Доставлено товаров. Количество товаров, которые заказали с Авито Доставкой и уже приняли. - * - **deliveredItemsPrice** - Стоимость доставленных товаров в копейках. Общая стоимость заказов, которые покупатели приняли. Это сумма, которую вы получаете на руки. - * - * - * #### Посуточная аренда - * - * - **bookingPlacedCount** - Получено заявок. Общее количество заявок на бронирование - * - **bookingPlacedPrice** - Стоимость полученных заявок в копейках. Общая стоимость бронирований. Это сумма, которую вы получите на руки, если гости заселятся. - * - **bookingApprovedCount** - Подтверждено заявок. Количество заявок на бронирование, которые вы подтвердили. - * - **bookingApprovedPrice** - Стоимость подтвержденных заявок в копейках. Общая стоимость бронирований, которые вы подтвердили. Это сумма, которую вы получите на руки, если гости заселятся. - * - **bookingAcceptedCount** - Заявки с заселением. Количество бронирований, по которым заселились гости. Заселение засчитывается в 15:00 по Москве на следующий день после заезда. - * - **bookingAcceptedPrice** - Стоимость заявок с заселением в копейках. Общая стоимость бронирований, по которым заселились гости. Это сумма, которую вы получаете на руки. - * - * - * #### Расходы - * - * - **allSpending** - Все расходы в копейках. Сколько всего денег и бонусов вы потратили на объявления. - * - **spending** - Расходы на объявления в копейках. Сколько денег вы потратили на размещение, продвижение, целевые действия и комиссию. - * - **presenceSpending** - Расходы на размещение и целевые действия в копейках. Сколько денег вы потратили на размещения и целевые действия — просмотры, чаты, звонки и отклики. - * - **promoSpending** - Расходы на продвижение в копейках. Сколько денег вы потратили на продвижение и на услуги, которые влияют на внешний вид объявления. - * - **restSpending** - Остальные расходы в копейках. Сколько денег вы потратили на чат-ботов и услуги, которые система не смогла распознать. - * - **commission** - Комиссия в копейках. Какую комиссию вы заплатили за заказы с Авито Доставкой, которые приняли покупатели, а также за бронирования жилья. - * - **spendingBonus** - Списано бонусов на объявления. Сколько бонусов вы потратили на размещение, продвижение, целевые действия и комиссию. - * - * - * #### Количество объявлений за период - * - * - **activeItems** - Активные объявления. Объявления, которые прошли проверку и появились в поиске. - * - **newActiveItems** - Новые и опубликованные заново объявления. Сколько объявлений опубликовано впервые или повторно. - * - **oldActiveItems** - Активны с прошлого периода. Сколько объявлений остаются опубликованными с предыдущего периода. - * - * - * ### Примечания - * - * * Из ручки возвращается не более чем по 1000 сущностей. Вы можете использовать поля запроса limit и offset для регулировки выбранного диапазона. - * * Глубина данных статистики такого запроса ограничена 270 днями. - * * В случае недоступности метрики для пользователя она не приходит в ответе. - * * Система позволяет делать не более одного запроса в минуту на данный метод. - * - */ -export const itemAnalytics = ( - options: Options -) => { - return (options.client ?? client).post( - { - security: [ - { - scheme: 'bearer', - type: 'http' - }, - { - scheme: 'bearer', - type: 'http' - } - ], - url: '/stats/v2/accounts/{user_id}/items', - ...options - } - ) -} diff --git a/examples/integrations/generated/avito/items/transformers.gen.ts b/examples/integrations/generated/avito/items/transformers.gen.ts deleted file mode 100644 index ec8c1ba..0000000 --- a/examples/integrations/generated/avito/items/transformers.gen.ts +++ /dev/null @@ -1,80 +0,0 @@ -// This file is auto-generated by @hey-api/openapi-ts - -import type { GetItemInfoResponse, PutItemVasResponse, ItemStatsShallowResponse } from './types.gen' - -const infoVasSchemaResponseTransformer = (data: any) => { - if (data.finish_time) { - data.finish_time = new Date(data.finish_time) - } - if (data.schedule) { - data.schedule = data.schedule.map((item: any) => { - new Date(item) - return item - }) - } - return data -} - -const itemInfoAvitoSchemaResponseTransformer = (data: any) => { - if (data.finish_time) { - data.finish_time = new Date(data.finish_time) - } - if (data.start_time) { - data.start_time = new Date(data.start_time) - } - if (data.vas) { - data.vas = data.vas.map((item: any) => { - return infoVasSchemaResponseTransformer(item) - }) - } - return data -} - -export const getItemInfoResponseTransformer = async (data: any): Promise => { - data = itemInfoAvitoSchemaResponseTransformer(data) - return data -} - -const vasApplyAvitoSchemaResponseTransformer = (data: any) => { - if (data.vas) { - data.vas = infoVasSchemaResponseTransformer(data.vas) - } - return data -} - -export const putItemVasResponseTransformer = async (data: any): Promise => { - data = vasApplyAvitoSchemaResponseTransformer(data) - return data -} - -const statisticsCountersSchemaResponseTransformer = (data: any) => { - data = data.map((item: any) => { - if (item.itemId) { - item.itemId = BigInt(item.itemId.toString()) - } - if (item.stats) { - item.stats = item.stats.map((item: any) => { - item.date = new Date(item.date) - return item - }) - } - return item - }) - return data -} - -const statisticsResponseSchemaResponseTransformer = (data: any) => { - if (data.result) { - if (data.result.items) { - data.result.items = statisticsCountersSchemaResponseTransformer(data.result.items) - } - } - return data -} - -export const itemStatsShallowResponseTransformer = async ( - data: any -): Promise => { - data = statisticsResponseSchemaResponseTransformer(data) - return data -} diff --git a/examples/integrations/generated/avito/items/types.gen.ts b/examples/integrations/generated/avito/items/types.gen.ts deleted file mode 100644 index 6e65efc..0000000 --- a/examples/integrations/generated/avito/items/types.gen.ts +++ /dev/null @@ -1,1136 +0,0 @@ -// This file is auto-generated by @hey-api/openapi-ts - -export type AnalyticsRequest = { - /** - * Дата (в формате YYYY-MM-DD), с которой (включительно) надо получить статистику - */ - dateFrom: Date - /** - * Дата (в формате YYYY-MM-DD), по которую (включительно) надо получить статистику - */ - dateTo: Date - /** - * Набор ограничений, по которым нужно отфильтровать данные - */ - filter?: { - /** - * Идентификаторы категорий
[ Справочник идентификаторов категорий ](https://www.avito.st/s/openapi/catalog-categories.xml) - */ - categoryIDs?: Array | null - /** - * Идентификаторы сотрудников
[ Метод получения идентификаторов сотрудников ](https://developers.avito.ru/api-catalog/accounts-hierarchy/documentation#operation/getEmployeesV1) - */ - employeeIDs?: Array | null - } | null - grouping: Groupings - /** - * Инструмент пагинации для ограничения количества сущностей в response; - */ - limit: number | null - /** - * Набор доступных показателей, которые должны присутствовать в ответе - */ - metrics: Array - /** - * инструмент пагинации или смещение, с которого начинается выборка данных; - */ - offset: number | null - /** - * Сортировка по заданному показателю - */ - sort?: { - /** - * Показатель статистики, по которому нужно отсортировать; - */ - key: string - /** - * Порядок сортировки (asc, desc); - */ - order: 'asc' | 'desc' - } | null -} - -export type AnalyticsResponse = { - result?: { - dataTotalCount?: number - groupings?: Array<{ - id?: number - metrics?: Array<{ - slug: string - value: number - }> - type?: Groupings - }> - timestamp?: string - } -} - -export type ApplyVasResp = { - /** - * Уникальный идентификатор операции покупки - */ - operationId: number -} - -export type CallsStatsDay = { - /** - * Отвеченные звонки - */ - answered?: number - /** - * Звонки всего - */ - calls?: number - /** - * Дата (YYYY-MM-DD) - */ - date?: string - /** - * Новые звонки - */ - new?: number - /** - * Новые и одновременно отвеченные звонки - */ - newAnswered?: number -} - -export type CallsStatsItem = { - /** - * Массив статистики звонков объявления в разрезе дней - */ - days?: Array - /** - * Идентификатор сотрудника в сервисе иерархии аккаунтов (0 означает, что звонок не аттрибуцирован до сотрудника) - */ - employeeId: number - /** - * Идентификатор объявления (0 означает, что звонок не аттрибуцирован до объявления) - */ - itemId: number -} - -export type CallsStatsRequest = { - /** - * Начальная дата периода (YYYY-MM-DD) - */ - dateFrom: string - /** - * Конечная дата периода (YYYY-MM-DD) - */ - dateTo: string - /** - * Идентификаторы объявлений - */ - itemIds?: Array -} - -export type CallsStatsResponse = { - result?: { - /** - * Массив статистики по объявлениям - */ - items: Array - } -} - -/** - * Список идентификаторов, которые не удалось обработать по разным причинам (например, они не принадлежат текущему пользователю) - */ -export type ErrorItemsVas = Array - -export type ErrorResponse = { - error?: { - code: number - message: string - } -} - -export type FieldError = { - /** - * Код ошибки - */ - code: string - /** - * Описание ошибки - */ - message: string -} - -export const Groupings = { - DAY: 'day', - WEEK: 'week', - MONTH: 'month', - ITEM: 'item', - TOTALS: 'totals' -} as const - -export type Groupings = (typeof Groupings)[keyof typeof Groupings] - -export type InfoVas = { - /** - * Дата завершения услуги - */ - finish_time?: Date | null - /** - * Информация о следующих применениях услуги - */ - schedule?: Array | null - /** - * Идентификатор услуги - */ - vas_id?: 'vip' | 'highlight' | 'pushup' | 'premium' | 'xl' -} - -export type ItemInfoAvito = { - /** - * [Идентификатор объявления](https://autoload.avito.ru/format/realty/#Id) из файла автозагрузки - */ - autoload_item_id?: string | null - /** - * Дата завершения объявления - */ - finish_time?: Date | null - /** - * Дата создания объявления - */ - start_time?: Date | null - /** - * Статус объявления на сайте - */ - status?: 'active' | 'removed' | 'old' | 'blocked' | 'rejected' | 'not_found' | 'another_user' - /** - * URL-адрес объявления - */ - url?: string | null - /** - * Список примененных платных услуг - */ - vas?: Array | null -} - -export type ItemVasPricesResp = { - /** - * Идентификатор объявления на сайте - */ - itemId?: number - stickers?: Array - vas: Array -} - -export type ItemsInfoWithCategoryAvito = { - meta?: { - /** - * Номер страницы - */ - page?: number - /** - * Количество записей на странице - */ - per_page?: number - } - resources?: Array<{ - /** - * Адрес объявления - */ - address?: string - category?: { - /** - * Идентификатор категории - */ - id?: number - /** - * Наименование категории - */ - name?: string - } - /** - * Идентификатор объявления - */ - id?: number - /** - * Цена объявления (null значение означает, что цена не указана) - */ - price?: number | null - /** - * Статус объявления на сайте - */ - status?: 'active' | 'removed' | 'old' | 'blocked' | 'rejected' - /** - * Наименование объявления - */ - title?: string - /** - * URL-адрес объявления - */ - url?: string | null - }> -} - -export type StatisticsCounters = Array<{ - /** - * Идентификатор объявления - */ - itemId?: bigint - stats?: Array<{ - /** - * __DEPRECATED (будет удалено в апреле 2021 г.).__ - * __Используйте поле uniqContacts.__ - * Запросы контактов объявления. - * - * @deprecated - */ - contacts?: number - /** - * Дата (в формате YYYY-MM-DD), за которую посчитаны статистические счетчики. Для группировок по периодам - дата начала периода. - */ - date: Date - /** - * __DEPRECATED (будет удалено в апреле 2021 г.).__ __Используйте поле uniqFavorites.__ Добавления объявления в избранное - * @deprecated - */ - favorites?: number - /** - * Уникальные пользователи, запрашивавшие контакты объявления - */ - uniqContacts?: number - /** - * Уникальные пользователи, добавившие объявление в избранное - */ - uniqFavorites?: number - /** - * Уникальные пользователи, просматривавшие объявления - */ - uniqViews?: number - /** - * __DEPRECATED (будет удалено в апреле 2021 г.).__ - * __Используйте поле uniqViews.__ - * Просмотры объявления. - * - * @deprecated - */ - views?: number - }> -}> - -/** - * Дата (в формате YYYY-MM-DD), с которой (включительно) надо получить статистику - */ -export type StatisticsDateFrom = string - -/** - * Дата (в формате YYYY-MM-DD), по которую (включительно) надо получить статистику - */ -export type StatisticsDateTo = string - -/** - * Набор счетчиков, которые должны присутствовать в ответе - */ -export type StatisticsFields = Array< - 'views' | 'uniqViews' | 'contacts' | 'uniqContacts' | 'favorites' | 'uniqFavorites' -> - -/** - * Набор идентификаторов объявлений на сайте - */ -export type StatisticsItemIds = Array - -/** - * Период группировки - */ -export const StatisticsPeriodGrouping = { - DAY: 'day', - WEEK: 'week', - MONTH: 'month' -} as const - -/** - * Период группировки - */ -export type StatisticsPeriodGrouping = - (typeof StatisticsPeriodGrouping)[keyof typeof StatisticsPeriodGrouping] - -export type StatisticsResponse = { - errors?: { - [key: string]: unknown - } - /** - * Статистические счетчики объявления - */ - result?: { - items?: StatisticsCounters - } -} - -export type StatisticsShallowRequestBody = { - dateFrom: StatisticsDateFrom - dateTo: StatisticsDateTo - fields?: StatisticsFields - itemIds: StatisticsItemIds - periodGrouping?: StatisticsPeriodGrouping -} - -/** - * Информация о значках для переданного списка объявлений - */ -export type StickerResp = { - /** - * Описание значка - */ - description: string - /** - * Идентификатор значка - */ - id: number - /** - * Название значка - */ - title: string -} - -export type UpdatePriceRequest = { - /** - * Цена - */ - price: number -} - -export type UpdatePriceResponse = { - result: { - success?: boolean - } -} - -export type VasAmountAvito = { - /** - * Сумма списания за применение услуги или пакета - */ - amount?: number -} - -export type VasApplyAvito = { - /** - * Сумма списания за применение услуги - */ - amount?: number - vas?: InfoVas -} - -export type VasPricesResp = Array - -/** - * Информация об услугах и пакетах дополнительных услуг для переданного списка объявлений - */ -export type VasResp = { - /** - * Цена со скидкой - */ - price: number - /** - * Цена до применения скидки - */ - priceOld: number - /** - * Идентификатор услуги или пакета услуг - */ - slug: string -} - -export type AuthError = { - error?: { - /** - * Код ошибки - */ - code: number - /** - * Сообщение об ошибке - */ - message: string - } -} - -export type BadRequestError = { - error?: { - /** - * Код ошибки - */ - code: number - /** - * Сообщение об ошибке - */ - message: string - } -} - -export type ItemIdsRequestBody = { - /** - * Набор идентификаторов объявлений на сайте - */ - item_ids: Array -} - -export type NotFoundError = { - error?: { - /** - * Код ошибки - */ - code: number - /** - * Сообщение об ошибке - */ - message: string - } -} - -export type PackageIdRequestBodyV2 = { - /** - * Идентификатор пакета услуг, возможные варианты значения: - * - `x2_1` - применение пакета До 2 раз больше просмотров на 1 день - * - `x2_7` - применение пакета До 2 раз больше просмотров на 7 дней - * - `x5_1` - применение пакета До 5 раз больше просмотров на 1 день - * - `x5_7` - применение пакета До 5 раз больше просмотров на 7 дней - * - `x10_1` - применение пакета До 10 раз больше просмотров на 1 день - * - `x10_7` - применение пакета До 10 раз больше просмотров на 7 дней - * - * В некоторых регионах и категориях также доступны дополнительные варианты: - * - `x15_1` - применение пакета До 15 раз больше просмотров на 1 день - * - `x15_7` - применение пакета До 15 раз больше просмотров на 7 дней - * - `x20_1` - применение пакета До 20 раз больше просмотров на 1 день - * - `x20_7` - применение пакета До 20 раз больше просмотров на 7 дней - * - * Если попытаться применить эти пакеты в недоступных для них регионе и категории, оплата не пройдёт. - * - */ - package_id: - | 'x2_1' - | 'x2_7' - | 'x5_1' - | 'x5_7' - | 'x10_1' - | 'x10_7' - | 'x15_1' - | 'x15_7' - | 'x20_1' - | 'x20_7' -} - -export type PricesItemIdsRequestBody = { - /** - * Набор идентификаторов объявлений на сайте - */ - itemIds: Array -} - -export type ServiceError = { - error?: { - /** - * Код ошибки - */ - code: number - /** - * Описание ошибки - */ - message: string - } -} - -export type ServiceUnavailableError = { - error?: { - /** - * Код ошибки - */ - code: number - /** - * Описание ошибки - */ - message: string - } -} - -export type TooManyRequests = { - [key: string]: unknown -} - -export type ValidatingError = { - error?: { - /** - * Код ошибки - */ - code: number - /** - * Информация об ошибке валидации параметров в формате ключ-значение - */ - fields?: { - [key: string]: unknown - } | null - /** - * Сообщение об ошибке - */ - message: string - } -} - -export type VasIdRequestBody = { - /** - * Идентификатор услуги, возможные его варианты значения: - * - `highlight` — [выделение объявления](https://support.avito.ru/articles/200026858) - * - `xl` – [XL-объявление](https://support.avito.ru/articles/685) - * - */ - vas_id: 'highlight' | 'xl' -} - -/** - * Тип данных запроса - */ -export const ApplicationJsonHeader = { - APPLICATION_JSON: 'application/json' -} as const - -/** - * Тип данных запроса - */ -export type ApplicationJsonHeader = - (typeof ApplicationJsonHeader)[keyof typeof ApplicationJsonHeader] - -/** - * Токен для авторизации - */ -export type AuthHeader = string - -/** - * Идентификатор чата (клиента) - */ -export type ChatId = string - -export type ItemIds = string - -/** - * Количество сообщений на странице (положительное число больше 0 и меньше 100) - */ -export type Limit = number - -/** - * Идентификатор сообщения - */ -export type MessageId = string - -export type Offset = number - -/** - * Номер страницы - */ -export type Page = number - -/** - * Идентификатор объявления на сайте - */ -export type PathItemId = bigint - -/** - * Номер пользователя в Личном кабинете Авито - */ -export type PathUserId = bigint - -/** - * Идентификатор вакансии на сайте - */ -export type PathVacancyId = bigint - -/** - * Количество ресурсов на страницу - */ -export type PerPage = number - -export type UnreadOnly = boolean - -/** - * Идентификатор пользователя (клиента) - */ -export type UserId = bigint - -export type VasPricesData = { - /** - * Набор идентификаторов объявлений на сайте - */ - body?: PricesItemIdsRequestBody - headers: { - /** - * Токен для авторизации - */ - Authorization: string - } - path: { - /** - * Номер пользователя в Личном кабинете Авито - */ - user_id: bigint - } - query?: never - url: '/core/v1/accounts/{userId}/vas/prices' -} - -export type VasPricesErrors = { - /** - * Информация об ошибке - */ - default: ValidatingError -} - -export type VasPricesError = VasPricesErrors[keyof VasPricesErrors] - -export type VasPricesResponses = { - /** - * Успешный ответ - */ - 200: VasPricesResp | BadRequestError | AuthError -} - -export type VasPricesResponse = VasPricesResponses[keyof VasPricesResponses] - -export type PostCallsStatsData = { - body: CallsStatsRequest - headers: { - /** - * Токен для авторизации - */ - Authorization: string - /** - * Тип данных запроса - */ - 'Content-Type': 'application/json' - } - path: { - /** - * Номер пользователя в Личном кабинете Авито - */ - user_id: bigint - } - query?: never - url: '/core/v1/accounts/{user_id}/calls/stats/' -} - -export type PostCallsStatsErrors = { - /** - * Неверный запрос - */ - 400: BadRequestError - /** - * Требуется аутентификация - */ - 401: AuthError - /** - * Неверный user_id в запросе - */ - 404: NotFoundError - /** - * Внутренняя ошибка метода API - */ - 500: ServiceError - /** - * Метод API временно недоступен - */ - 503: ServiceUnavailableError -} - -export type PostCallsStatsError = PostCallsStatsErrors[keyof PostCallsStatsErrors] - -export type PostCallsStatsResponses = { - /** - * Успешный ответ - */ - 200: CallsStatsResponse -} - -export type PostCallsStatsResponse = PostCallsStatsResponses[keyof PostCallsStatsResponses] - -export type GetItemInfoData = { - body?: never - headers: { - /** - * Токен для авторизации - */ - Authorization: string - } - path: { - /** - * Номер пользователя в Личном кабинете Авито - */ - user_id: bigint - /** - * Идентификатор объявления на сайте - */ - item_id: bigint - } - query?: never - url: '/core/v1/accounts/{user_id}/items/{item_id}/' -} - -export type GetItemInfoErrors = { - /** - * Превышено допустимое количество запросов - */ - 429: TooManyRequests - /** - * Информация об ошибке - */ - default: FieldError -} - -export type GetItemInfoError = GetItemInfoErrors[keyof GetItemInfoErrors] - -export type GetItemInfoResponses = { - /** - * Успешный ответ - */ - 200: ItemInfoAvito -} - -export type GetItemInfoResponse = GetItemInfoResponses[keyof GetItemInfoResponses] - -export type PutItemVasData = { - body?: VasIdRequestBody - headers: { - /** - * Токен для авторизации - */ - Authorization: string - } - path: { - /** - * Номер пользователя в Личном кабинете Авито - */ - user_id: bigint - /** - * Идентификатор объявления на сайте - */ - item_id: bigint - } - query?: never - url: '/core/v1/accounts/{user_id}/items/{item_id}/vas' -} - -export type PutItemVasErrors = { - /** - * Информация об ошибке - */ - default: ValidatingError -} - -export type PutItemVasError = PutItemVasErrors[keyof PutItemVasErrors] - -export type PutItemVasResponses = { - /** - * Успешный ответ - */ - 200: VasApplyAvito -} - -export type PutItemVasResponse = PutItemVasResponses[keyof PutItemVasResponses] - -export type GetItemsInfoData = { - body?: never - headers: { - /** - * Токен для авторизации - */ - Authorization: string - } - path?: never - query?: { - /** - * Количество записей на странице (целое число больше 0 и меньше 100) - */ - per_page?: number - /** - * Номер страницы (целое число больше 0) - */ - page?: number - /** - * Статус объявления на сайте (можно указать несколько значений через запятую) - */ - status?: 'active' | 'removed' | 'old' | 'blocked' | 'rejected' - /** - * Фильтр больше либо равно по дате обновления/редактирования объявления в формате YYYY-MM-DD - */ - updatedAtFrom?: string - /** - * Идентификатор категории объявления
см. возможные варианты категорий в [ справочнике ](https://www.avito.st/s/openapi/catalog-categories.xml) - * - */ - category?: number - } - url: '/core/v1/items' -} - -export type GetItemsInfoErrors = { - /** - * Информация об ошибке - */ - default: FieldError -} - -export type GetItemsInfoError = GetItemsInfoErrors[keyof GetItemsInfoErrors] - -export type GetItemsInfoResponses = { - /** - * Успешный ответ - */ - 200: ItemsInfoWithCategoryAvito -} - -export type GetItemsInfoResponse = GetItemsInfoResponses[keyof GetItemsInfoResponses] - -export type UpdatePriceData = { - /** - * Набор параметров в теле запроса. - */ - body?: UpdatePriceRequest - path: { - /** - * Идентификатор объявления на сайте - */ - item_id: bigint - } - query?: never - url: '/core/v1/items/{item_id}/update_price' -} - -export type UpdatePriceErrors = { - /** - * Неверный запрос - */ - 400: BadRequestError - /** - * Требуется аутентификация - */ - 401: AuthError - /** - * Неверный user_id в запросе - */ - 404: NotFoundError - /** - * Превышено количество запросов - */ - 429: TooManyRequests -} - -export type UpdatePriceError = UpdatePriceErrors[keyof UpdatePriceErrors] - -export type UpdatePriceResponses = { - /** - * Успешный ответ - */ - 200: UpdatePriceResponse -} - -export type UpdatePriceResponse2 = UpdatePriceResponses[keyof UpdatePriceResponses] - -export type PutItemVasPackageV2Data = { - body?: PackageIdRequestBodyV2 - headers: { - /** - * Токен для авторизации - */ - Authorization: string - } - path: { - /** - * Номер пользователя в Личном кабинете Авито - */ - user_id: bigint - /** - * Идентификатор объявления на сайте - */ - item_id: bigint - } - query?: never - url: '/core/v2/accounts/{user_id}/items/{item_id}/vas_packages' -} - -export type PutItemVasPackageV2Errors = { - /** - * Информация об ошибке - */ - default: ValidatingError -} - -export type PutItemVasPackageV2Error = PutItemVasPackageV2Errors[keyof PutItemVasPackageV2Errors] - -export type PutItemVasPackageV2Responses = { - /** - * Успешный ответ - */ - 200: VasAmountAvito -} - -export type PutItemVasPackageV2Response = - PutItemVasPackageV2Responses[keyof PutItemVasPackageV2Responses] - -export type ApplyVasData = { - body?: { - /** - * Список идентификаторов услуг - */ - slugs: Array - /** - * Список значков - */ - stickers?: Array - } - headers: { - /** - * Токен для авторизации - */ - Authorization: string - } - path: { - /** - * Идентификатор объявления на сайте - */ - item_id: bigint - } - query?: never - url: '/core/v2/items/{itemId}/vas/' -} - -export type ApplyVasErrors = { - /** - * Ответ с ошибкой - */ - 500: { - code: 1000 | 1001 | 1002 | 1003 | 1004 | 1005 | 1006 | 1007 | 1008 | 1009 | 1010 | 1011 - } -} - -export type ApplyVasError = ApplyVasErrors[keyof ApplyVasErrors] - -export type ApplyVasResponses = { - /** - * Успешный ответ - */ - 200: { - [key: string]: ApplyVasResp - } -} - -export type ApplyVasResponse = ApplyVasResponses[keyof ApplyVasResponses] - -export type ItemStatsShallowData = { - /** - * Набор параметров в теле запроса. - */ - body?: StatisticsShallowRequestBody - headers: { - /** - * Токен для авторизации - */ - Authorization: string - /** - * Тип данных запроса - */ - 'Content-Type': 'application/json' - } - path: { - /** - * Идентификатор пользователя (клиента) - */ - user_id: bigint - } - query?: never - url: '/stats/v1/accounts/{user_id}/items' -} - -export type ItemStatsShallowErrors = { - /** - * Неверный запрос - */ - 400: BadRequestError - /** - * Требуется аутентификация - */ - 401: AuthError - /** - * Неверный user_id в запросе - */ - 404: NotFoundError - /** - * Внутренняя ошибка метода API - */ - 500: ServiceError - /** - * Метод API временно недоступен - */ - 503: ServiceUnavailableError -} - -export type ItemStatsShallowError = ItemStatsShallowErrors[keyof ItemStatsShallowErrors] - -export type ItemStatsShallowResponses = { - /** - * Успешный ответ - */ - 200: StatisticsResponse -} - -export type ItemStatsShallowResponse = ItemStatsShallowResponses[keyof ItemStatsShallowResponses] - -export type ItemAnalyticsData = { - body: AnalyticsRequest - headers: { - /** - * Токен для авторизации - */ - Authorization: string - /** - * Тип данных запроса - */ - 'Content-Type': 'application/json' - } - path: { - /** - * Идентификатор пользователя (клиента) - */ - user_id: bigint - } - query?: never - url: '/stats/v2/accounts/{user_id}/items' -} - -export type ItemAnalyticsErrors = { - /** - * Неверный запрос - */ - 400: ErrorResponse - /** - * Требуется аутентификация - */ - 401: ErrorResponse - /** - * Доступ запрещен - */ - 403: ErrorResponse - /** - * Слишком много запросов - */ - 429: ErrorResponse - /** - * Error response - */ - 500: ErrorResponse -} - -export type ItemAnalyticsError = ItemAnalyticsErrors[keyof ItemAnalyticsErrors] - -export type ItemAnalyticsResponses = { - /** - * Successful response - */ - 200: AnalyticsResponse -} - -export type ItemAnalyticsResponse = ItemAnalyticsResponses[keyof ItemAnalyticsResponses] - -export type ClientOptions = { - baseUrl: 'https://api.avito.ru/' | (string & {}) -} diff --git a/examples/integrations/generated/avito/items/zod.gen.ts b/examples/integrations/generated/avito/items/zod.gen.ts deleted file mode 100644 index 2891be6..0000000 --- a/examples/integrations/generated/avito/items/zod.gen.ts +++ /dev/null @@ -1,579 +0,0 @@ -// This file is auto-generated by @hey-api/openapi-ts - -import { z } from 'zod' - -export const zGroupings = z.enum(['day', 'week', 'month', 'item', 'totals']) - -export const zAnalyticsRequest = z.object({ - dateFrom: z.iso.date(), - dateTo: z.iso.date(), - filter: z.optional( - z.union([ - z.object({ - categoryIDs: z.optional(z.union([z.array(z.int()), z.null()])), - employeeIDs: z.optional(z.union([z.array(z.int()), z.null()])) - }), - z.null() - ]) - ), - grouping: zGroupings, - limit: z.union([z.int().gte(0).lte(1000), z.null()]), - metrics: z.array(z.string()), - offset: z.union([z.int().gte(0), z.null()]), - sort: z.optional( - z.union([ - z.object({ - key: z.string(), - order: z.enum(['asc', 'desc']) - }), - z.null() - ]) - ) -}) - -export const zAnalyticsResponse = z.object({ - result: z.optional( - z.object({ - dataTotalCount: z.optional(z.int()), - groupings: z.optional( - z.array( - z.object({ - id: z.optional(z.int()), - metrics: z.optional( - z.array( - z.object({ - slug: z.string(), - value: z.number() - }) - ) - ), - type: z.optional(zGroupings) - }) - ) - ), - timestamp: z.optional(z.string()) - }) - ) -}) - -export const zApplyVasResp = z.object({ - operationId: z.int() -}) - -export const zCallsStatsDay = z.object({ - answered: z.optional(z.int()), - calls: z.optional(z.int()), - date: z.optional(z.string()), - new: z.optional(z.int()), - newAnswered: z.optional(z.int()) -}) - -export const zCallsStatsItem = z.object({ - days: z.optional(z.array(zCallsStatsDay)), - employeeId: z.int(), - itemId: z.int() -}) - -export const zCallsStatsRequest = z.object({ - dateFrom: z.string(), - dateTo: z.string(), - itemIds: z.optional(z.array(z.int())) -}) - -export const zCallsStatsResponse = z.object({ - result: z.optional( - z.object({ - items: z.array(zCallsStatsItem) - }) - ) -}) - -/** - * Список идентификаторов, которые не удалось обработать по разным причинам (например, они не принадлежат текущему пользователю) - */ -export const zErrorItemsVas = z.array(z.int()) - -export const zErrorResponse = z.object({ - error: z.optional( - z.object({ - code: z.int(), - message: z.string() - }) - ) -}) - -export const zFieldError = z.object({ - code: z.string(), - message: z.string() -}) - -export const zInfoVas = z.object({ - finish_time: z.optional(z.union([z.iso.datetime(), z.null()])), - schedule: z.optional(z.union([z.array(z.iso.datetime()), z.null()])), - vas_id: z.optional(z.enum(['vip', 'highlight', 'pushup', 'premium', 'xl'])) -}) - -export const zItemInfoAvito = z.object({ - autoload_item_id: z.optional(z.union([z.string(), z.null()])), - finish_time: z.optional(z.union([z.iso.datetime(), z.null()])), - start_time: z.optional(z.union([z.iso.datetime(), z.null()])), - status: z.optional( - z.enum(['active', 'removed', 'old', 'blocked', 'rejected', 'not_found', 'another_user']) - ), - url: z.optional(z.union([z.string(), z.null()])), - vas: z.optional(z.union([z.array(zInfoVas), z.null()])) -}) - -/** - * Информация о значках для переданного списка объявлений - */ -export const zStickerResp = z.object({ - description: z.string(), - id: z.int(), - title: z.string() -}) - -/** - * Информация об услугах и пакетах дополнительных услуг для переданного списка объявлений - */ -export const zVasResp = z.object({ - price: z.int(), - priceOld: z.int(), - slug: z.string() -}) - -export const zItemVasPricesResp = z.object({ - itemId: z.optional(z.int()), - stickers: z.optional(z.array(zStickerResp)), - vas: z.array(zVasResp) -}) - -export const zItemsInfoWithCategoryAvito = z.object({ - meta: z.optional( - z.object({ - page: z.optional(z.int()), - per_page: z.optional(z.int()) - }) - ), - resources: z.optional( - z.array( - z.object({ - address: z.optional(z.string()), - category: z.optional( - z.object({ - id: z.optional(z.int()), - name: z.optional(z.string()) - }) - ), - id: z.optional(z.int()), - price: z.optional(z.union([z.int(), z.null()])), - status: z.optional(z.enum(['active', 'removed', 'old', 'blocked', 'rejected'])), - title: z.optional(z.string()), - url: z.optional(z.union([z.string(), z.null()])) - }) - ) - ) -}) - -export const zStatisticsCounters = z.array( - z.object({ - itemId: z.optional(z.coerce.bigint()), - stats: z.optional( - z.array( - z.object({ - contacts: z.optional(z.int()), - date: z.iso.date(), - favorites: z.optional(z.int()), - uniqContacts: z.optional(z.int()), - uniqFavorites: z.optional(z.int()), - uniqViews: z.optional(z.int()), - views: z.optional(z.int()) - }) - ) - ) - }) -) - -/** - * Дата (в формате YYYY-MM-DD), с которой (включительно) надо получить статистику - */ -export const zStatisticsDateFrom = z.string() - -/** - * Дата (в формате YYYY-MM-DD), по которую (включительно) надо получить статистику - */ -export const zStatisticsDateTo = z.string() - -/** - * Набор счетчиков, которые должны присутствовать в ответе - */ -export const zStatisticsFields = z.array( - z.enum(['views', 'uniqViews', 'contacts', 'uniqContacts', 'favorites', 'uniqFavorites']) -) - -/** - * Набор идентификаторов объявлений на сайте - */ -export const zStatisticsItemIds = z.array(z.int()) - -/** - * Период группировки - */ -export const zStatisticsPeriodGrouping = z.enum(['day', 'week', 'month']) - -export const zStatisticsResponse = z.object({ - errors: z.optional(z.record(z.string(), z.unknown())), - result: z.optional( - z.object({ - items: z.optional(zStatisticsCounters) - }) - ) -}) - -export const zStatisticsShallowRequestBody = z.object({ - dateFrom: zStatisticsDateFrom, - dateTo: zStatisticsDateTo, - fields: z.optional(zStatisticsFields), - itemIds: zStatisticsItemIds, - periodGrouping: z.optional(zStatisticsPeriodGrouping) -}) - -export const zUpdatePriceRequest = z.object({ - price: z.int() -}) - -export const zUpdatePriceResponse = z.object({ - result: z.object({ - success: z.optional(z.boolean()) - }) -}) - -export const zVasAmountAvito = z.object({ - amount: z.optional(z.number()) -}) - -export const zVasApplyAvito = z.object({ - amount: z.optional(z.number()), - vas: z.optional(zInfoVas) -}) - -export const zVasPricesResp = z.array(zItemVasPricesResp) - -export const zAuthError = z.object({ - error: z.optional( - z.object({ - code: z.int(), - message: z.string() - }) - ) -}) - -export const zBadRequestError = z.object({ - error: z.optional( - z.object({ - code: z.int(), - message: z.string() - }) - ) -}) - -export const zItemIdsRequestBody = z.object({ - item_ids: z.array(z.int()) -}) - -export const zNotFoundError = z.object({ - error: z.optional( - z.object({ - code: z.int(), - message: z.string() - }) - ) -}) - -export const zPackageIdRequestBodyV2 = z.object({ - package_id: z.enum([ - 'x2_1', - 'x2_7', - 'x5_1', - 'x5_7', - 'x10_1', - 'x10_7', - 'x15_1', - 'x15_7', - 'x20_1', - 'x20_7' - ]) -}) - -export const zPricesItemIdsRequestBody = z.object({ - itemIds: z.array(z.int()) -}) - -export const zServiceError = z.object({ - error: z.optional( - z.object({ - code: z.int(), - message: z.string() - }) - ) -}) - -export const zServiceUnavailableError = z.object({ - error: z.optional( - z.object({ - code: z.int(), - message: z.string() - }) - ) -}) - -export const zTooManyRequests = z.record(z.string(), z.unknown()) - -export const zValidatingError = z.object({ - error: z.optional( - z.object({ - code: z.int(), - fields: z.optional(z.union([z.record(z.string(), z.unknown()), z.null()])), - message: z.string() - }) - ) -}) - -export const zVasIdRequestBody = z.object({ - vas_id: z.enum(['highlight', 'xl']) -}) - -/** - * Тип данных запроса - */ -export const zApplicationJsonHeader = z.enum(['application/json']) - -/** - * Токен для авторизации - */ -export const zAuthHeader = z.string() - -/** - * Идентификатор чата (клиента) - */ -export const zChatId = z.string() - -export const zItemIds = z.string() - -/** - * Количество сообщений на странице (положительное число больше 0 и меньше 100) - */ -export const zLimit = z.int().default(100) - -/** - * Идентификатор сообщения - */ -export const zMessageId = z.string() - -export const zOffset = z.int().default(0) - -/** - * Номер страницы - */ -export const zPage = z.int() - -/** - * Идентификатор объявления на сайте - */ -export const zPathItemId = z.coerce.bigint() - -/** - * Номер пользователя в Личном кабинете Авито - */ -export const zPathUserId = z.coerce.bigint() - -/** - * Идентификатор вакансии на сайте - */ -export const zPathVacancyId = z.coerce.bigint() - -/** - * Количество ресурсов на страницу - */ -export const zPerPage = z.int() - -export const zUnreadOnly = z.boolean() - -/** - * Идентификатор пользователя (клиента) - */ -export const zUserId = z.coerce.bigint() - -export const zVasPricesData = z.object({ - body: z.optional(zPricesItemIdsRequestBody), - path: z.object({ - user_id: z.coerce.bigint() - }), - query: z.optional(z.never()), - headers: z.object({ - Authorization: z.string() - }) -}) - -/** - * Успешный ответ - */ -export const zVasPricesResponse = z.union([zVasPricesResp, zBadRequestError, zAuthError]) - -export const zPostCallsStatsData = z.object({ - body: zCallsStatsRequest, - path: z.object({ - user_id: z.coerce.bigint() - }), - query: z.optional(z.never()), - headers: z.object({ - Authorization: z.string(), - 'Content-Type': z.enum(['application/json']) - }) -}) - -/** - * Успешный ответ - */ -export const zPostCallsStatsResponse = zCallsStatsResponse - -export const zGetItemInfoData = z.object({ - body: z.optional(z.never()), - path: z.object({ - user_id: z.coerce.bigint(), - item_id: z.coerce.bigint() - }), - query: z.optional(z.never()), - headers: z.object({ - Authorization: z.string() - }) -}) - -/** - * Успешный ответ - */ -export const zGetItemInfoResponse = zItemInfoAvito - -export const zPutItemVasData = z.object({ - body: z.optional(zVasIdRequestBody), - path: z.object({ - user_id: z.coerce.bigint(), - item_id: z.coerce.bigint() - }), - query: z.optional(z.never()), - headers: z.object({ - Authorization: z.string() - }) -}) - -/** - * Успешный ответ - */ -export const zPutItemVasResponse = zVasApplyAvito - -export const zGetItemsInfoData = z.object({ - body: z.optional(z.never()), - path: z.optional(z.never()), - query: z.optional( - z.object({ - per_page: z.optional(z.int()).default(25), - page: z.optional(z.int()).default(1), - status: z.optional(z.enum(['active', 'removed', 'old', 'blocked', 'rejected'])), - updatedAtFrom: z.optional(z.string()), - category: z.optional(z.int()) - }) - ), - headers: z.object({ - Authorization: z.string() - }) -}) - -/** - * Успешный ответ - */ -export const zGetItemsInfoResponse = zItemsInfoWithCategoryAvito - -export const zUpdatePriceData = z.object({ - body: z.optional(zUpdatePriceRequest), - path: z.object({ - item_id: z.coerce.bigint() - }), - query: z.optional(z.never()) -}) - -/** - * Успешный ответ - */ -export const zUpdatePriceResponse2 = zUpdatePriceResponse - -export const zPutItemVasPackageV2Data = z.object({ - body: z.optional(zPackageIdRequestBodyV2), - path: z.object({ - user_id: z.coerce.bigint(), - item_id: z.coerce.bigint() - }), - query: z.optional(z.never()), - headers: z.object({ - Authorization: z.string() - }) -}) - -/** - * Успешный ответ - */ -export const zPutItemVasPackageV2Response = zVasAmountAvito - -export const zApplyVasData = z.object({ - body: z.optional( - z.object({ - slugs: z.array(z.string()), - stickers: z.optional(z.array(z.int())) - }) - ), - path: z.object({ - item_id: z.coerce.bigint() - }), - query: z.optional(z.never()), - headers: z.object({ - Authorization: z.string() - }) -}) - -/** - * Успешный ответ - */ -export const zApplyVasResponse = z.record(z.string(), zApplyVasResp) - -export const zItemStatsShallowData = z.object({ - body: z.optional(zStatisticsShallowRequestBody), - path: z.object({ - user_id: z.coerce.bigint() - }), - query: z.optional(z.never()), - headers: z.object({ - Authorization: z.string(), - 'Content-Type': z.enum(['application/json']) - }) -}) - -/** - * Успешный ответ - */ -export const zItemStatsShallowResponse = zStatisticsResponse - -export const zItemAnalyticsData = z.object({ - body: zAnalyticsRequest, - path: z.object({ - user_id: z.coerce.bigint() - }), - query: z.optional(z.never()), - headers: z.object({ - Authorization: z.string(), - 'Content-Type': z.enum(['application/json']) - }) -}) - -/** - * Successful response - */ -export const zItemAnalyticsResponse = zAnalyticsResponse diff --git a/examples/integrations/generated/avito/messenger/client.gen.ts b/examples/integrations/generated/avito/messenger/client.gen.ts deleted file mode 100644 index a2b0b1d..0000000 --- a/examples/integrations/generated/avito/messenger/client.gen.ts +++ /dev/null @@ -1,27 +0,0 @@ -// This file is auto-generated by @hey-api/openapi-ts - -import type { ClientOptions } from './types.gen' -import { - type ClientOptions as DefaultClientOptions, - type Config, - createClient, - createConfig -} from './client' - -/** - * The `createClientConfig()` function will be called on client initialization - * and the returned object will become the client's initial configuration. - * - * You may want to initialize your client this way instead of calling - * `setConfig()`. This is useful for example if you're using Next.js - * to ensure your client always has the correct values. - */ -export type CreateClientConfig = ( - override?: Config -) => Config & T> - -export const client = createClient( - createConfig({ - baseUrl: 'https://api.avito.ru/' - }) -) diff --git a/examples/integrations/generated/avito/messenger/client/client.gen.ts b/examples/integrations/generated/avito/messenger/client/client.gen.ts deleted file mode 100644 index 4a4fc46..0000000 --- a/examples/integrations/generated/avito/messenger/client/client.gen.ts +++ /dev/null @@ -1,253 +0,0 @@ -// This file is auto-generated by @hey-api/openapi-ts - -import { createSseClient } from '../core/serverSentEvents.gen' -import type { HttpMethod } from '../core/types.gen' -import { getValidRequestBody } from '../core/utils.gen' -import type { Client, Config, RequestOptions, ResolvedRequestOptions } from './types.gen' -import { - buildUrl, - createConfig, - createInterceptors, - getParseAs, - mergeConfigs, - mergeHeaders, - setAuthParams -} from './utils.gen' - -type ReqInit = Omit & { - body?: any - headers: ReturnType -} - -export const createClient = (config: Config = {}): Client => { - let _config = mergeConfigs(createConfig(), config) - - const getConfig = (): Config => ({ ..._config }) - - const setConfig = (config: Config): Config => { - _config = mergeConfigs(_config, config) - return getConfig() - } - - const interceptors = createInterceptors() - - const beforeRequest = async (options: RequestOptions) => { - const opts = { - ..._config, - ...options, - fetch: options.fetch ?? _config.fetch ?? globalThis.fetch, - headers: mergeHeaders(_config.headers, options.headers), - serializedBody: undefined - } - - if (opts.security) { - await setAuthParams({ - ...opts, - security: opts.security - }) - } - - if (opts.requestValidator) { - await opts.requestValidator(opts) - } - - if (opts.body !== undefined && opts.bodySerializer) { - opts.serializedBody = opts.bodySerializer(opts.body) - } - - // remove Content-Type header if body is empty to avoid sending invalid requests - if (opts.body === undefined || opts.serializedBody === '') { - opts.headers.delete('Content-Type') - } - - const url = buildUrl(opts) - - return { opts, url } - } - - const request: Client['request'] = async (options) => { - // @ts-expect-error - const { opts, url } = await beforeRequest(options) - const requestInit: ReqInit = { - redirect: 'follow', - ...opts, - body: getValidRequestBody(opts) - } - - let request = new Request(url, requestInit) - - for (const fn of interceptors.request.fns) { - if (fn) { - request = await fn(request, opts) - } - } - - // fetch must be assigned here, otherwise it would throw the error: - // TypeError: Failed to execute 'fetch' on 'Window': Illegal invocation - const _fetch = opts.fetch! - let response = await _fetch(request) - - for (const fn of interceptors.response.fns) { - if (fn) { - response = await fn(response, request, opts) - } - } - - const result = { - request, - response - } - - if (response.ok) { - const parseAs = - (opts.parseAs === 'auto' - ? getParseAs(response.headers.get('Content-Type')) - : opts.parseAs) ?? 'json' - - if (response.status === 204 || response.headers.get('Content-Length') === '0') { - let emptyData: any - switch (parseAs) { - case 'arrayBuffer': - case 'blob': - case 'text': - emptyData = await response[parseAs]() - break - case 'formData': - emptyData = new FormData() - break - case 'stream': - emptyData = response.body - break - case 'json': - default: - emptyData = {} - break - } - return opts.responseStyle === 'data' - ? emptyData - : { - data: emptyData, - ...result - } - } - - let data: any - switch (parseAs) { - case 'arrayBuffer': - case 'blob': - case 'formData': - case 'json': - case 'text': - data = await response[parseAs]() - break - case 'stream': - return opts.responseStyle === 'data' - ? response.body - : { - data: response.body, - ...result - } - } - - if (parseAs === 'json') { - if (opts.responseValidator) { - await opts.responseValidator(data) - } - - if (opts.responseTransformer) { - data = await opts.responseTransformer(data) - } - } - - return opts.responseStyle === 'data' - ? data - : { - data, - ...result - } - } - - const textError = await response.text() - let jsonError: unknown - - try { - jsonError = JSON.parse(textError) - } catch { - // noop - } - - const error = jsonError ?? textError - let finalError = error - - for (const fn of interceptors.error.fns) { - if (fn) { - finalError = (await fn(error, response, request, opts)) as string - } - } - - finalError = finalError || ({} as string) - - if (opts.throwOnError) { - throw finalError - } - - // TODO: we probably want to return error and improve types - return opts.responseStyle === 'data' - ? undefined - : { - error: finalError, - ...result - } - } - - const makeMethodFn = (method: Uppercase) => (options: RequestOptions) => - request({ ...options, method }) - - const makeSseFn = (method: Uppercase) => async (options: RequestOptions) => { - const { opts, url } = await beforeRequest(options) - return createSseClient({ - ...opts, - body: opts.body as BodyInit | null | undefined, - headers: opts.headers as unknown as Record, - method, - onRequest: async (url, init) => { - let request = new Request(url, init) - for (const fn of interceptors.request.fns) { - if (fn) { - request = await fn(request, opts) - } - } - return request - }, - url - }) - } - - return { - buildUrl, - connect: makeMethodFn('CONNECT'), - delete: makeMethodFn('DELETE'), - get: makeMethodFn('GET'), - getConfig, - head: makeMethodFn('HEAD'), - interceptors, - options: makeMethodFn('OPTIONS'), - patch: makeMethodFn('PATCH'), - post: makeMethodFn('POST'), - put: makeMethodFn('PUT'), - request, - setConfig, - sse: { - connect: makeSseFn('CONNECT'), - delete: makeSseFn('DELETE'), - get: makeSseFn('GET'), - head: makeSseFn('HEAD'), - options: makeSseFn('OPTIONS'), - patch: makeSseFn('PATCH'), - post: makeSseFn('POST'), - put: makeSseFn('PUT'), - trace: makeSseFn('TRACE') - }, - trace: makeMethodFn('TRACE') - } as Client -} diff --git a/examples/integrations/generated/avito/messenger/client/types.gen.ts b/examples/integrations/generated/avito/messenger/client/types.gen.ts deleted file mode 100644 index b97f75e..0000000 --- a/examples/integrations/generated/avito/messenger/client/types.gen.ts +++ /dev/null @@ -1,226 +0,0 @@ -// This file is auto-generated by @hey-api/openapi-ts - -import type { Auth } from '../core/auth.gen' -import type { ServerSentEventsOptions, ServerSentEventsResult } from '../core/serverSentEvents.gen' -import type { Client as CoreClient, Config as CoreConfig } from '../core/types.gen' -import type { Middleware } from './utils.gen' - -export type ResponseStyle = 'data' | 'fields' - -export interface Config - extends Omit, - CoreConfig { - /** - * Base URL for all requests made by this client. - */ - baseUrl?: T['baseUrl'] - /** - * Fetch API implementation. You can use this option to provide a custom - * fetch instance. - * - * @default globalThis.fetch - */ - fetch?: typeof fetch - /** - * Please don't use the Fetch client for Next.js applications. The `next` - * options won't have any effect. - * - * Install {@link https://www.npmjs.com/package/@hey-api/client-next `@hey-api/client-next`} instead. - */ - next?: never - /** - * Return the response data parsed in a specified format. By default, `auto` - * will infer the appropriate method from the `Content-Type` response header. - * You can override this behavior with any of the {@link Body} methods. - * Select `stream` if you don't want to parse response data at all. - * - * @default 'auto' - */ - parseAs?: 'arrayBuffer' | 'auto' | 'blob' | 'formData' | 'json' | 'stream' | 'text' - /** - * Should we return only data or multiple fields (data, error, response, etc.)? - * - * @default 'fields' - */ - responseStyle?: ResponseStyle - /** - * Throw an error instead of returning it in the response? - * - * @default false - */ - throwOnError?: T['throwOnError'] -} - -export interface RequestOptions< - TData = unknown, - TResponseStyle extends ResponseStyle = 'fields', - ThrowOnError extends boolean = boolean, - Url extends string = string -> extends Config<{ - responseStyle: TResponseStyle - throwOnError: ThrowOnError - }>, - Pick< - ServerSentEventsOptions, - | 'onSseError' - | 'onSseEvent' - | 'sseDefaultRetryDelay' - | 'sseMaxRetryAttempts' - | 'sseMaxRetryDelay' - > { - /** - * Any body that you want to add to your request. - * - * {@link https://developer.mozilla.org/docs/Web/API/fetch#body} - */ - body?: unknown - path?: Record - query?: Record - /** - * Security mechanism(s) to use for the request. - */ - security?: ReadonlyArray - url: Url -} - -export interface ResolvedRequestOptions< - TResponseStyle extends ResponseStyle = 'fields', - ThrowOnError extends boolean = boolean, - Url extends string = string -> extends RequestOptions { - serializedBody?: string -} - -export type RequestResult< - TData = unknown, - TError = unknown, - ThrowOnError extends boolean = boolean, - TResponseStyle extends ResponseStyle = 'fields' -> = ThrowOnError extends true - ? Promise< - TResponseStyle extends 'data' - ? TData extends Record - ? TData[keyof TData] - : TData - : { - data: TData extends Record ? TData[keyof TData] : TData - request: Request - response: Response - } - > - : Promise< - TResponseStyle extends 'data' - ? (TData extends Record ? TData[keyof TData] : TData) | undefined - : ( - | { - data: TData extends Record ? TData[keyof TData] : TData - error: undefined - } - | { - data: undefined - error: TError extends Record ? TError[keyof TError] : TError - } - ) & { - request: Request - response: Response - } - > - -export interface ClientOptions { - baseUrl?: string - responseStyle?: ResponseStyle - throwOnError?: boolean -} - -type MethodFn = < - TData = unknown, - TError = unknown, - ThrowOnError extends boolean = false, - TResponseStyle extends ResponseStyle = 'fields' ->( - options: Omit, 'method'> -) => RequestResult - -type SseFn = < - TData = unknown, - TError = unknown, - ThrowOnError extends boolean = false, - TResponseStyle extends ResponseStyle = 'fields' ->( - options: Omit, 'method'> -) => Promise> - -type RequestFn = < - TData = unknown, - TError = unknown, - ThrowOnError extends boolean = false, - TResponseStyle extends ResponseStyle = 'fields' ->( - options: Omit, 'method'> & - Pick>, 'method'> -) => RequestResult - -type BuildUrlFn = < - TData extends { - body?: unknown - path?: Record - query?: Record - url: string - } ->( - options: Pick & Options -) => string - -export type Client = CoreClient & { - interceptors: Middleware -} - -/** - * The `createClientConfig()` function will be called on client initialization - * and the returned object will become the client's initial configuration. - * - * You may want to initialize your client this way instead of calling - * `setConfig()`. This is useful for example if you're using Next.js - * to ensure your client always has the correct values. - */ -export type CreateClientConfig = ( - override?: Config -) => Config & T> - -export interface TDataShape { - body?: unknown - headers?: unknown - path?: unknown - query?: unknown - url: string -} - -type OmitKeys = Pick> - -export type Options< - TData extends TDataShape = TDataShape, - ThrowOnError extends boolean = boolean, - TResponse = unknown, - TResponseStyle extends ResponseStyle = 'fields' -> = OmitKeys< - RequestOptions, - 'body' | 'path' | 'query' | 'url' -> & - Omit - -export type OptionsLegacyParser< - TData = unknown, - ThrowOnError extends boolean = boolean, - TResponseStyle extends ResponseStyle = 'fields' -> = TData extends { body?: any } - ? TData extends { headers?: any } - ? OmitKeys, 'body' | 'headers' | 'url'> & - TData - : OmitKeys, 'body' | 'url'> & - TData & - Pick, 'headers'> - : TData extends { headers?: any } - ? OmitKeys, 'headers' | 'url'> & - TData & - Pick, 'body'> - : OmitKeys, 'url'> & TData diff --git a/examples/integrations/generated/avito/messenger/client/utils.gen.ts b/examples/integrations/generated/avito/messenger/client/utils.gen.ts deleted file mode 100644 index b42b5d9..0000000 --- a/examples/integrations/generated/avito/messenger/client/utils.gen.ts +++ /dev/null @@ -1,315 +0,0 @@ -// This file is auto-generated by @hey-api/openapi-ts - -import { getAuthToken } from '../core/auth.gen' -import type { QuerySerializerOptions } from '../core/bodySerializer.gen' -import { jsonBodySerializer } from '../core/bodySerializer.gen' -import { - serializeArrayParam, - serializeObjectParam, - serializePrimitiveParam -} from '../core/pathSerializer.gen' -import { getUrl } from '../core/utils.gen' -import type { Client, ClientOptions, Config, RequestOptions } from './types.gen' - -export const createQuerySerializer = ({ - allowReserved, - array, - object -}: QuerySerializerOptions = {}) => { - const querySerializer = (queryParams: T) => { - const search: string[] = [] - if (queryParams && typeof queryParams === 'object') { - for (const name in queryParams) { - const value = queryParams[name] - - if (value === undefined || value === null) { - continue - } - - if (Array.isArray(value)) { - const serializedArray = serializeArrayParam({ - allowReserved, - explode: true, - name, - style: 'form', - value, - ...array - }) - if (serializedArray) search.push(serializedArray) - } else if (typeof value === 'object') { - const serializedObject = serializeObjectParam({ - allowReserved, - explode: true, - name, - style: 'deepObject', - value: value as Record, - ...object - }) - if (serializedObject) search.push(serializedObject) - } else { - const serializedPrimitive = serializePrimitiveParam({ - allowReserved, - name, - value: value as string - }) - if (serializedPrimitive) search.push(serializedPrimitive) - } - } - } - return search.join('&') - } - return querySerializer -} - -/** - * Infers parseAs value from provided Content-Type header. - */ -export const getParseAs = (contentType: string | null): Exclude => { - if (!contentType) { - // If no Content-Type header is provided, the best we can do is return the raw response body, - // which is effectively the same as the 'stream' option. - return 'stream' - } - - const cleanContent = contentType.split(';')[0]?.trim() - - if (!cleanContent) { - return - } - - if (cleanContent.startsWith('application/json') || cleanContent.endsWith('+json')) { - return 'json' - } - - if (cleanContent === 'multipart/form-data') { - return 'formData' - } - - if ( - ['application/', 'audio/', 'image/', 'video/'].some((type) => cleanContent.startsWith(type)) - ) { - return 'blob' - } - - if (cleanContent.startsWith('text/')) { - return 'text' - } - - return -} - -const checkForExistence = ( - options: Pick & { - headers: Headers - }, - name?: string -): boolean => { - if (!name) { - return false - } - if ( - options.headers.has(name) || - options.query?.[name] || - options.headers.get('Cookie')?.includes(`${name}=`) - ) { - return true - } - return false -} - -export const setAuthParams = async ({ - security, - ...options -}: Pick, 'security'> & - Pick & { - headers: Headers - }) => { - for (const auth of security) { - if (checkForExistence(options, auth.name)) { - continue - } - - const token = await getAuthToken(auth, options.auth) - - if (!token) { - continue - } - - const name = auth.name ?? 'Authorization' - - switch (auth.in) { - case 'query': - if (!options.query) { - options.query = {} - } - options.query[name] = token - break - case 'cookie': - options.headers.append('Cookie', `${name}=${token}`) - break - case 'header': - default: - options.headers.set(name, token) - break - } - } -} - -export const buildUrl: Client['buildUrl'] = (options) => - getUrl({ - baseUrl: options.baseUrl as string, - path: options.path, - query: options.query, - querySerializer: - typeof options.querySerializer === 'function' - ? options.querySerializer - : createQuerySerializer(options.querySerializer), - url: options.url - }) - -export const mergeConfigs = (a: Config, b: Config): Config => { - const config = { ...a, ...b } - if (config.baseUrl?.endsWith('/')) { - config.baseUrl = config.baseUrl.substring(0, config.baseUrl.length - 1) - } - config.headers = mergeHeaders(a.headers, b.headers) - return config -} - -const headersEntries = (headers: Headers): Array<[string, string]> => { - const entries: Array<[string, string]> = [] - headers.forEach((value, key) => { - entries.push([key, value]) - }) - return entries -} - -export const mergeHeaders = ( - ...headers: Array['headers'] | undefined> -): Headers => { - const mergedHeaders = new Headers() - for (const header of headers) { - if (!header) { - continue - } - - const iterator = header instanceof Headers ? headersEntries(header) : Object.entries(header) - - for (const [key, value] of iterator) { - if (value === null) { - mergedHeaders.delete(key) - } else if (Array.isArray(value)) { - for (const v of value) { - mergedHeaders.append(key, v as string) - } - } else if (value !== undefined) { - // assume object headers are meant to be JSON stringified, i.e. their - // content value in OpenAPI specification is 'application/json' - mergedHeaders.set( - key, - typeof value === 'object' ? JSON.stringify(value) : (value as string) - ) - } - } - } - return mergedHeaders -} - -type ErrInterceptor = ( - error: Err, - response: Res, - request: Req, - options: Options -) => Err | Promise - -type ReqInterceptor = (request: Req, options: Options) => Req | Promise - -type ResInterceptor = ( - response: Res, - request: Req, - options: Options -) => Res | Promise - -class Interceptors { - fns: Array = [] - - clear(): void { - this.fns = [] - } - - eject(id: number | Interceptor): void { - const index = this.getInterceptorIndex(id) - if (this.fns[index]) { - this.fns[index] = null - } - } - - exists(id: number | Interceptor): boolean { - const index = this.getInterceptorIndex(id) - return Boolean(this.fns[index]) - } - - getInterceptorIndex(id: number | Interceptor): number { - if (typeof id === 'number') { - return this.fns[id] ? id : -1 - } - return this.fns.indexOf(id) - } - - update(id: number | Interceptor, fn: Interceptor): number | Interceptor | false { - const index = this.getInterceptorIndex(id) - if (this.fns[index]) { - this.fns[index] = fn - return id - } - return false - } - - use(fn: Interceptor): number { - this.fns.push(fn) - return this.fns.length - 1 - } -} - -export interface Middleware { - error: Interceptors> - request: Interceptors> - response: Interceptors> -} - -export const createInterceptors = (): Middleware< - Req, - Res, - Err, - Options -> => ({ - error: new Interceptors>(), - request: new Interceptors>(), - response: new Interceptors>() -}) - -const defaultQuerySerializer = createQuerySerializer({ - allowReserved: false, - array: { - explode: true, - style: 'form' - }, - object: { - explode: true, - style: 'deepObject' - } -}) - -const defaultHeaders = { - 'Content-Type': 'application/json' -} - -export const createConfig = ( - override: Config & T> = {} -): Config & T> => ({ - ...jsonBodySerializer, - headers: defaultHeaders, - parseAs: 'auto', - querySerializer: defaultQuerySerializer, - ...override -}) diff --git a/examples/integrations/generated/avito/messenger/core/auth.gen.ts b/examples/integrations/generated/avito/messenger/core/auth.gen.ts deleted file mode 100644 index dc8ff61..0000000 --- a/examples/integrations/generated/avito/messenger/core/auth.gen.ts +++ /dev/null @@ -1,41 +0,0 @@ -// This file is auto-generated by @hey-api/openapi-ts - -export type AuthToken = string | undefined - -export interface Auth { - /** - * Which part of the request do we use to send the auth? - * - * @default 'header' - */ - in?: 'header' | 'query' | 'cookie' - /** - * Header or query parameter name. - * - * @default 'Authorization' - */ - name?: string - scheme?: 'basic' | 'bearer' - type: 'apiKey' | 'http' -} - -export const getAuthToken = async ( - auth: Auth, - callback: ((auth: Auth) => Promise | AuthToken) | AuthToken -): Promise => { - const token = typeof callback === 'function' ? await callback(auth) : callback - - if (!token) { - return - } - - if (auth.scheme === 'bearer') { - return `Bearer ${token}` - } - - if (auth.scheme === 'basic') { - return `Basic ${btoa(token)}` - } - - return token -} diff --git a/examples/integrations/generated/avito/messenger/core/bodySerializer.gen.ts b/examples/integrations/generated/avito/messenger/core/bodySerializer.gen.ts deleted file mode 100644 index e39c6a5..0000000 --- a/examples/integrations/generated/avito/messenger/core/bodySerializer.gen.ts +++ /dev/null @@ -1,76 +0,0 @@ -// This file is auto-generated by @hey-api/openapi-ts - -import type { ArrayStyle, ObjectStyle, SerializerOptions } from './pathSerializer.gen' - -export type QuerySerializer = (query: Record) => string - -export type BodySerializer = (body: any) => any - -export interface QuerySerializerOptions { - allowReserved?: boolean - array?: SerializerOptions - object?: SerializerOptions -} - -const serializeFormDataPair = (data: FormData, key: string, value: unknown): void => { - if (typeof value === 'string' || value instanceof Blob) { - data.append(key, value) - } else if (value instanceof Date) { - data.append(key, value.toISOString()) - } else { - data.append(key, JSON.stringify(value)) - } -} - -const serializeUrlSearchParamsPair = (data: URLSearchParams, key: string, value: unknown): void => { - if (typeof value === 'string') { - data.append(key, value) - } else { - data.append(key, JSON.stringify(value)) - } -} - -export const formDataBodySerializer = { - bodySerializer: | Array>>( - body: T - ): FormData => { - const data = new FormData() - - Object.entries(body).forEach(([key, value]) => { - if (value === undefined || value === null) { - return - } - if (Array.isArray(value)) { - value.forEach((v) => serializeFormDataPair(data, key, v)) - } else { - serializeFormDataPair(data, key, value) - } - }) - - return data - } -} - -export const jsonBodySerializer = { - bodySerializer: (body: T): string => - JSON.stringify(body, (_key, value) => (typeof value === 'bigint' ? value.toString() : value)) -} - -export const urlSearchParamsBodySerializer = { - bodySerializer: | Array>>(body: T): string => { - const data = new URLSearchParams() - - Object.entries(body).forEach(([key, value]) => { - if (value === undefined || value === null) { - return - } - if (Array.isArray(value)) { - value.forEach((v) => serializeUrlSearchParamsPair(data, key, v)) - } else { - serializeUrlSearchParamsPair(data, key, value) - } - }) - - return data.toString() - } -} diff --git a/examples/integrations/generated/avito/messenger/core/params.gen.ts b/examples/integrations/generated/avito/messenger/core/params.gen.ts deleted file mode 100644 index 34dddb5..0000000 --- a/examples/integrations/generated/avito/messenger/core/params.gen.ts +++ /dev/null @@ -1,144 +0,0 @@ -// This file is auto-generated by @hey-api/openapi-ts - -type Slot = 'body' | 'headers' | 'path' | 'query' - -export type Field = - | { - in: Exclude - /** - * Field name. This is the name we want the user to see and use. - */ - key: string - /** - * Field mapped name. This is the name we want to use in the request. - * If omitted, we use the same value as `key`. - */ - map?: string - } - | { - in: Extract - /** - * Key isn't required for bodies. - */ - key?: string - map?: string - } - -export interface Fields { - allowExtra?: Partial> - args?: ReadonlyArray -} - -export type FieldsConfig = ReadonlyArray - -const extraPrefixesMap: Record = { - $body_: 'body', - $headers_: 'headers', - $path_: 'path', - $query_: 'query' -} -const extraPrefixes = Object.entries(extraPrefixesMap) - -type KeyMap = Map< - string, - { - in: Slot - map?: string - } -> - -const buildKeyMap = (fields: FieldsConfig, map?: KeyMap): KeyMap => { - if (!map) { - map = new Map() - } - - for (const config of fields) { - if ('in' in config) { - if (config.key) { - map.set(config.key, { - in: config.in, - map: config.map - }) - } - } else if (config.args) { - buildKeyMap(config.args, map) - } - } - - return map -} - -interface Params { - body: unknown - headers: Record - path: Record - query: Record -} - -const stripEmptySlots = (params: Params) => { - for (const [slot, value] of Object.entries(params)) { - if (value && typeof value === 'object' && !Object.keys(value).length) { - delete params[slot as Slot] - } - } -} - -export const buildClientParams = (args: ReadonlyArray, fields: FieldsConfig) => { - const params: Params = { - body: {}, - headers: {}, - path: {}, - query: {} - } - - const map = buildKeyMap(fields) - - let config: FieldsConfig[number] | undefined - - for (const [index, arg] of args.entries()) { - if (fields[index]) { - config = fields[index] - } - - if (!config) { - continue - } - - if ('in' in config) { - if (config.key) { - const field = map.get(config.key)! - const name = field.map || config.key - ;(params[field.in] as Record)[name] = arg - } else { - params.body = arg - } - } else { - for (const [key, value] of Object.entries(arg ?? {})) { - const field = map.get(key) - - if (field) { - const name = field.map || key - ;(params[field.in] as Record)[name] = value - } else { - const extra = extraPrefixes.find(([prefix]) => key.startsWith(prefix)) - - if (extra) { - const [prefix, slot] = extra - ;(params[slot] as Record)[key.slice(prefix.length)] = value - } else { - for (const [slot, allowed] of Object.entries(config.allowExtra ?? {})) { - if (allowed) { - ;(params[slot as Slot] as Record)[key] = value - break - } - } - } - } - } - } - } - - stripEmptySlots(params) - - return params -} diff --git a/examples/integrations/generated/avito/messenger/core/pathSerializer.gen.ts b/examples/integrations/generated/avito/messenger/core/pathSerializer.gen.ts deleted file mode 100644 index acc1367..0000000 --- a/examples/integrations/generated/avito/messenger/core/pathSerializer.gen.ts +++ /dev/null @@ -1,171 +0,0 @@ -// This file is auto-generated by @hey-api/openapi-ts - -interface SerializeOptions extends SerializePrimitiveOptions, SerializerOptions {} - -interface SerializePrimitiveOptions { - allowReserved?: boolean - name: string -} - -export interface SerializerOptions { - /** - * @default true - */ - explode: boolean - style: T -} - -export type ArrayStyle = 'form' | 'spaceDelimited' | 'pipeDelimited' -export type ArraySeparatorStyle = ArrayStyle | MatrixStyle -type MatrixStyle = 'label' | 'matrix' | 'simple' -export type ObjectStyle = 'form' | 'deepObject' -type ObjectSeparatorStyle = ObjectStyle | MatrixStyle - -interface SerializePrimitiveParam extends SerializePrimitiveOptions { - value: string -} - -export const separatorArrayExplode = (style: ArraySeparatorStyle) => { - switch (style) { - case 'label': - return '.' - case 'matrix': - return ';' - case 'simple': - return ',' - default: - return '&' - } -} - -export const separatorArrayNoExplode = (style: ArraySeparatorStyle) => { - switch (style) { - case 'form': - return ',' - case 'pipeDelimited': - return '|' - case 'spaceDelimited': - return '%20' - default: - return ',' - } -} - -export const separatorObjectExplode = (style: ObjectSeparatorStyle) => { - switch (style) { - case 'label': - return '.' - case 'matrix': - return ';' - case 'simple': - return ',' - default: - return '&' - } -} - -export const serializeArrayParam = ({ - allowReserved, - explode, - name, - style, - value -}: SerializeOptions & { - value: unknown[] -}) => { - if (!explode) { - const joinedValues = ( - allowReserved ? value : value.map((v) => encodeURIComponent(v as string)) - ).join(separatorArrayNoExplode(style)) - switch (style) { - case 'label': - return `.${joinedValues}` - case 'matrix': - return `;${name}=${joinedValues}` - case 'simple': - return joinedValues - default: - return `${name}=${joinedValues}` - } - } - - const separator = separatorArrayExplode(style) - const joinedValues = value - .map((v) => { - if (style === 'label' || style === 'simple') { - return allowReserved ? v : encodeURIComponent(v as string) - } - - return serializePrimitiveParam({ - allowReserved, - name, - value: v as string - }) - }) - .join(separator) - return style === 'label' || style === 'matrix' ? separator + joinedValues : joinedValues -} - -export const serializePrimitiveParam = ({ - allowReserved, - name, - value -}: SerializePrimitiveParam) => { - if (value === undefined || value === null) { - return '' - } - - if (typeof value === 'object') { - throw new Error( - 'Deeply-nested arrays/objects aren’t supported. Provide your own `querySerializer()` to handle these.' - ) - } - - return `${name}=${allowReserved ? value : encodeURIComponent(value)}` -} - -export const serializeObjectParam = ({ - allowReserved, - explode, - name, - style, - value, - valueOnly -}: SerializeOptions & { - value: Record | Date - valueOnly?: boolean -}) => { - if (value instanceof Date) { - return valueOnly ? value.toISOString() : `${name}=${value.toISOString()}` - } - - if (style !== 'deepObject' && !explode) { - let values: string[] = [] - Object.entries(value).forEach(([key, v]) => { - values = [...values, key, allowReserved ? (v as string) : encodeURIComponent(v as string)] - }) - const joinedValues = values.join(',') - switch (style) { - case 'form': - return `${name}=${joinedValues}` - case 'label': - return `.${joinedValues}` - case 'matrix': - return `;${name}=${joinedValues}` - default: - return joinedValues - } - } - - const separator = separatorObjectExplode(style) - const joinedValues = Object.entries(value) - .map(([key, v]) => - serializePrimitiveParam({ - allowReserved, - name: style === 'deepObject' ? `${name}[${key}]` : key, - value: v as string - }) - ) - .join(separator) - return style === 'label' || style === 'matrix' ? separator + joinedValues : joinedValues -} diff --git a/examples/integrations/generated/avito/messenger/core/serverSentEvents.gen.ts b/examples/integrations/generated/avito/messenger/core/serverSentEvents.gen.ts deleted file mode 100644 index 372e50c..0000000 --- a/examples/integrations/generated/avito/messenger/core/serverSentEvents.gen.ts +++ /dev/null @@ -1,241 +0,0 @@ -// This file is auto-generated by @hey-api/openapi-ts - -import type { Config } from './types.gen' - -export type ServerSentEventsOptions = Omit & - Pick & { - /** - * Fetch API implementation. You can use this option to provide a custom - * fetch instance. - * - * @default globalThis.fetch - */ - fetch?: typeof fetch - /** - * Implementing clients can call request interceptors inside this hook. - */ - onRequest?: (url: string, init: RequestInit) => Promise - /** - * Callback invoked when a network or parsing error occurs during streaming. - * - * This option applies only if the endpoint returns a stream of events. - * - * @param error The error that occurred. - */ - onSseError?: (error: unknown) => void - /** - * Callback invoked when an event is streamed from the server. - * - * This option applies only if the endpoint returns a stream of events. - * - * @param event Event streamed from the server. - * @returns Nothing (void). - */ - onSseEvent?: (event: StreamEvent) => void - serializedBody?: RequestInit['body'] - /** - * Default retry delay in milliseconds. - * - * This option applies only if the endpoint returns a stream of events. - * - * @default 3000 - */ - sseDefaultRetryDelay?: number - /** - * Maximum number of retry attempts before giving up. - */ - sseMaxRetryAttempts?: number - /** - * Maximum retry delay in milliseconds. - * - * Applies only when exponential backoff is used. - * - * This option applies only if the endpoint returns a stream of events. - * - * @default 30000 - */ - sseMaxRetryDelay?: number - /** - * Optional sleep function for retry backoff. - * - * Defaults to using `setTimeout`. - */ - sseSleepFn?: (ms: number) => Promise - url: string - } - -export interface StreamEvent { - data: TData - event?: string - id?: string - retry?: number -} - -export type ServerSentEventsResult = { - stream: AsyncGenerator< - TData extends Record ? TData[keyof TData] : TData, - TReturn, - TNext - > -} - -export const createSseClient = ({ - onRequest, - onSseError, - onSseEvent, - responseTransformer, - responseValidator, - sseDefaultRetryDelay, - sseMaxRetryAttempts, - sseMaxRetryDelay, - sseSleepFn, - url, - ...options -}: ServerSentEventsOptions): ServerSentEventsResult => { - let lastEventId: string | undefined - - const sleep = sseSleepFn ?? ((ms: number) => new Promise((resolve) => setTimeout(resolve, ms))) - - const createStream = async function* () { - let retryDelay: number = sseDefaultRetryDelay ?? 3000 - let attempt = 0 - const signal = options.signal ?? new AbortController().signal - - while (true) { - if (signal.aborted) break - - attempt++ - - const headers = - options.headers instanceof Headers - ? options.headers - : new Headers(options.headers as Record | undefined) - - if (lastEventId !== undefined) { - headers.set('Last-Event-ID', lastEventId) - } - - try { - const requestInit: RequestInit = { - redirect: 'follow', - ...options, - body: options.serializedBody, - headers, - signal - } - let request = new Request(url, requestInit) - if (onRequest) { - request = await onRequest(url, requestInit) - } - // fetch must be assigned here, otherwise it would throw the error: - // TypeError: Failed to execute 'fetch' on 'Window': Illegal invocation - const _fetch = options.fetch ?? globalThis.fetch - const response = await _fetch(request) - - if (!response.ok) throw new Error(`SSE failed: ${response.status} ${response.statusText}`) - - if (!response.body) throw new Error('No body in SSE response') - - const reader = response.body.pipeThrough(new TextDecoderStream()).getReader() - - let buffer = '' - - const abortHandler = () => { - try { - reader.cancel() - } catch { - // noop - } - } - - signal.addEventListener('abort', abortHandler) - - try { - while (true) { - const { done, value } = await reader.read() - if (done) break - buffer += value - - const chunks = buffer.split('\n\n') - buffer = chunks.pop() ?? '' - - for (const chunk of chunks) { - const lines = chunk.split('\n') - const dataLines: Array = [] - let eventName: string | undefined - - for (const line of lines) { - if (line.startsWith('data:')) { - dataLines.push(line.replace(/^data:\s*/, '')) - } else if (line.startsWith('event:')) { - eventName = line.replace(/^event:\s*/, '') - } else if (line.startsWith('id:')) { - lastEventId = line.replace(/^id:\s*/, '') - } else if (line.startsWith('retry:')) { - const parsed = Number.parseInt(line.replace(/^retry:\s*/, ''), 10) - if (!Number.isNaN(parsed)) { - retryDelay = parsed - } - } - } - - let data: unknown - let parsedJson = false - - if (dataLines.length) { - const rawData = dataLines.join('\n') - try { - data = JSON.parse(rawData) - parsedJson = true - } catch { - data = rawData - } - } - - if (parsedJson) { - if (responseValidator) { - await responseValidator(data) - } - - if (responseTransformer) { - data = await responseTransformer(data) - } - } - - onSseEvent?.({ - data, - event: eventName, - id: lastEventId, - retry: retryDelay - }) - - if (dataLines.length) { - yield data as any - } - } - } - } finally { - signal.removeEventListener('abort', abortHandler) - reader.releaseLock() - } - - break // exit loop on normal completion - } catch (error) { - // connection failed or aborted; retry after delay - onSseError?.(error) - - if (sseMaxRetryAttempts !== undefined && attempt >= sseMaxRetryAttempts) { - break // stop after firing error - } - - // exponential backoff: double retry each attempt, cap at 30s - const backoff = Math.min(retryDelay * 2 ** (attempt - 1), sseMaxRetryDelay ?? 30000) - await sleep(backoff) - } - } - } - - const stream = createStream() - - return { stream } -} diff --git a/examples/integrations/generated/avito/messenger/core/types.gen.ts b/examples/integrations/generated/avito/messenger/core/types.gen.ts deleted file mode 100644 index 647ffcc..0000000 --- a/examples/integrations/generated/avito/messenger/core/types.gen.ts +++ /dev/null @@ -1,104 +0,0 @@ -// This file is auto-generated by @hey-api/openapi-ts - -import type { Auth, AuthToken } from './auth.gen' -import type { BodySerializer, QuerySerializer, QuerySerializerOptions } from './bodySerializer.gen' - -export type HttpMethod = - | 'connect' - | 'delete' - | 'get' - | 'head' - | 'options' - | 'patch' - | 'post' - | 'put' - | 'trace' - -export type Client< - RequestFn = never, - Config = unknown, - MethodFn = never, - BuildUrlFn = never, - SseFn = never -> = { - /** - * Returns the final request URL. - */ - buildUrl: BuildUrlFn - getConfig: () => Config - request: RequestFn - setConfig: (config: Config) => Config -} & { - [K in HttpMethod]: MethodFn -} & ([SseFn] extends [never] ? { sse?: never } : { sse: { [K in HttpMethod]: SseFn } }) - -export interface Config { - /** - * Auth token or a function returning auth token. The resolved value will be - * added to the request payload as defined by its `security` array. - */ - auth?: ((auth: Auth) => Promise | AuthToken) | AuthToken - /** - * A function for serializing request body parameter. By default, - * {@link JSON.stringify()} will be used. - */ - bodySerializer?: BodySerializer | null - /** - * An object containing any HTTP headers that you want to pre-populate your - * `Headers` object with. - * - * {@link https://developer.mozilla.org/docs/Web/API/Headers/Headers#init See more} - */ - headers?: - | RequestInit['headers'] - | Record< - string, - string | number | boolean | (string | number | boolean)[] | null | undefined | unknown - > - /** - * The request method. - * - * {@link https://developer.mozilla.org/docs/Web/API/fetch#method See more} - */ - method?: Uppercase - /** - * A function for serializing request query parameters. By default, arrays - * will be exploded in form style, objects will be exploded in deepObject - * style, and reserved characters are percent-encoded. - * - * This method will have no effect if the native `paramsSerializer()` Axios - * API function is used. - * - * {@link https://swagger.io/docs/specification/serialization/#query View examples} - */ - querySerializer?: QuerySerializer | QuerySerializerOptions - /** - * A function validating request data. This is useful if you want to ensure - * the request conforms to the desired shape, so it can be safely sent to - * the server. - */ - requestValidator?: (data: unknown) => Promise - /** - * A function transforming response data before it's returned. This is useful - * for post-processing data, e.g. converting ISO strings into Date objects. - */ - responseTransformer?: (data: unknown) => Promise - /** - * A function validating response data. This is useful if you want to ensure - * the response conforms to the desired shape, so it can be safely passed to - * the transformers and returned to the user. - */ - responseValidator?: (data: unknown) => Promise -} - -type IsExactlyNeverOrNeverUndefined = [T] extends [never] - ? true - : [T] extends [never | undefined] - ? [undefined] extends [T] - ? false - : true - : false - -export type OmitNever> = { - [K in keyof T as IsExactlyNeverOrNeverUndefined extends true ? never : K]: T[K] -} diff --git a/examples/integrations/generated/avito/messenger/core/utils.gen.ts b/examples/integrations/generated/avito/messenger/core/utils.gen.ts deleted file mode 100644 index bd078be..0000000 --- a/examples/integrations/generated/avito/messenger/core/utils.gen.ts +++ /dev/null @@ -1,140 +0,0 @@ -// This file is auto-generated by @hey-api/openapi-ts - -import type { BodySerializer, QuerySerializer } from './bodySerializer.gen' -import { - type ArraySeparatorStyle, - serializeArrayParam, - serializeObjectParam, - serializePrimitiveParam -} from './pathSerializer.gen' - -export interface PathSerializer { - path: Record - url: string -} - -export const PATH_PARAM_RE = /\{[^{}]+\}/g - -export const defaultPathSerializer = ({ path, url: _url }: PathSerializer) => { - let url = _url - const matches = _url.match(PATH_PARAM_RE) - if (matches) { - for (const match of matches) { - let explode = false - let name = match.substring(1, match.length - 1) - let style: ArraySeparatorStyle = 'simple' - - if (name.endsWith('*')) { - explode = true - name = name.substring(0, name.length - 1) - } - - if (name.startsWith('.')) { - name = name.substring(1) - style = 'label' - } else if (name.startsWith(';')) { - name = name.substring(1) - style = 'matrix' - } - - const value = path[name] - - if (value === undefined || value === null) { - continue - } - - if (Array.isArray(value)) { - url = url.replace(match, serializeArrayParam({ explode, name, style, value })) - continue - } - - if (typeof value === 'object') { - url = url.replace( - match, - serializeObjectParam({ - explode, - name, - style, - value: value as Record, - valueOnly: true - }) - ) - continue - } - - if (style === 'matrix') { - url = url.replace( - match, - `;${serializePrimitiveParam({ - name, - value: value as string - })}` - ) - continue - } - - const replaceValue = encodeURIComponent( - style === 'label' ? `.${value as string}` : (value as string) - ) - url = url.replace(match, replaceValue) - } - } - return url -} - -export const getUrl = ({ - baseUrl, - path, - query, - querySerializer, - url: _url -}: { - baseUrl?: string - path?: Record - query?: Record - querySerializer: QuerySerializer - url: string -}) => { - const pathUrl = _url.startsWith('/') ? _url : `/${_url}` - let url = (baseUrl ?? '') + pathUrl - if (path) { - url = defaultPathSerializer({ path, url }) - } - let search = query ? querySerializer(query) : '' - if (search.startsWith('?')) { - search = search.substring(1) - } - if (search) { - url += `?${search}` - } - return url -} - -export function getValidRequestBody(options: { - body?: unknown - bodySerializer?: BodySerializer | null - serializedBody?: unknown -}) { - const hasBody = options.body !== undefined - const isSerializedBody = hasBody && options.bodySerializer - - if (isSerializedBody) { - if ('serializedBody' in options) { - const hasSerializedBody = - options.serializedBody !== undefined && options.serializedBody !== '' - - return hasSerializedBody ? options.serializedBody : null - } - - // not all clients implement a serializedBody property (i.e. client-axios) - return options.body !== '' ? options.body : null - } - - // plain/text body - if (hasBody) { - return options.body - } - - // no body was provided - return undefined -} diff --git a/examples/integrations/generated/avito/messenger/schemas.gen.ts b/examples/integrations/generated/avito/messenger/schemas.gen.ts deleted file mode 100644 index bf05e07..0000000 --- a/examples/integrations/generated/avito/messenger/schemas.gen.ts +++ /dev/null @@ -1,849 +0,0 @@ -// This file is auto-generated by @hey-api/openapi-ts - -export const ChatSchema = { - properties: { - context: { - properties: { - type: { - example: 'item', - type: 'string' - }, - value: { - properties: { - id: { - description: 'ID объявления, если чат по объявлению', - example: 1768287444, - format: 'int32', - type: 'integer' - }, - images: { - properties: { - count: { - example: 4, - format: 'int32', - type: 'integer' - }, - main: { - properties: { - '140x105': { - example: 'https://01-img-staging-proxy.k.avito.ru/140x105/5815183159.jpg', - type: 'string' - } - }, - type: 'object' - } - }, - type: 'object' - }, - price_string: { - example: '300 000 ₽', - type: 'string' - }, - status_id: { - example: 10, - format: 'int32', - type: 'integer' - }, - title: { - example: 'Mazda 3 2008', - type: 'string' - }, - url: { - example: 'https://avito.ru/moskva/avtomobili/mazda_3_2008_1768287444', - type: 'string' - }, - user_id: { - description: 'ID автора объявления, если чат по объявлению', - example: 141906442, - format: 'int32', - type: 'integer' - } - }, - type: 'object' - } - }, - type: 'object' - }, - created: { - example: 1571412836, - format: 'int32', - type: 'integer' - }, - id: { - type: 'string' - }, - last_message: { - properties: { - author_id: { - example: 94235311, - format: 'int32', - type: 'integer' - }, - content: { - properties: { - link: { - properties: { - text: { - example: 'habr.com', - type: 'string' - }, - url: { - example: 'habr.com', - type: 'string' - } - }, - type: 'object' - } - }, - type: 'object' - }, - created: { - example: 1571654040, - format: 'int32', - type: 'integer' - }, - direction: { - example: 'out', - type: 'string' - }, - id: { - type: 'string' - }, - type: { - example: 'link', - type: 'string' - } - }, - type: 'object' - }, - updated: { - example: 1571654040, - format: 'int32', - type: 'integer' - }, - users: { - items: { - properties: { - id: { - example: 94235311, - format: 'int32', - type: 'integer' - }, - name: { - example: 'Guldan', - type: 'string' - }, - public_user_profile: { - properties: { - avatar: { - properties: { - default: { - example: 'https://www.avito.st/stub_avatars/_/14_256x256.png', - type: 'string' - }, - images: { - properties: { - '128x128': { - example: 'https://www.avito.st/stub_avatars/_/14_128x128.png', - type: 'string' - }, - '192x192': { - example: 'https://www.avito.st/stub_avatars/_/14_192x192.png', - type: 'string' - }, - '24x24': { - example: 'https://www.avito.st/stub_avatars/_/14_24x24.png', - type: 'string' - }, - '256x256': { - example: 'https://www.avito.st/stub_avatars/_/14_256x256.png', - type: 'string' - }, - '36x36': { - example: 'https://www.avito.st/stub_avatars/_/14_36x36.png', - type: 'string' - }, - '48x48': { - example: 'https://www.avito.st/stub_avatars/_/14_48x48.png', - type: 'string' - }, - '64x64': { - example: 'https://www.avito.st/stub_avatars/_/14_64x64.png', - type: 'string' - }, - '72x72': { - example: 'https://www.avito.st/stub_avatars/_/14_72x72.png', - type: 'string' - }, - '96x96': { - example: 'https://www.avito.st/stub_avatars/_/14_96x96.png', - type: 'string' - } - }, - type: 'object' - } - }, - type: 'object' - }, - item_id: { - example: 1768287444, - format: 'int32', - type: 'integer' - }, - url: { - example: - 'https://avito.ru/user/db65c00c946dc404e11f14755465453b/profile?id=1768287444&src=messenger', - type: 'string' - }, - user_id: { - example: 94235311, - format: 'int32', - type: 'integer' - } - }, - type: 'object' - } - }, - type: 'object' - }, - type: 'array' - } - }, - type: 'object' -} as const - -export const ChatsSchema = { - properties: { - chats: { - items: { - $ref: '#/components/schemas/Chat' - }, - type: 'array' - } - }, - type: 'object' -} as const - -export const MessageContentSchema = { - description: - 'Для сообщений типов "appCall" "file" "video" возвращается empty object (данные типы не поддерживаются)', - properties: { - call: { - nullable: true, - properties: { - status: { - enum: ['missed'], - type: 'string' - }, - target_user_id: { - example: 94235311, - format: 'int64', - type: 'integer' - } - }, - type: 'object' - }, - flow_id: { - example: 'flower_167071', - nullable: true, - type: 'string' - }, - image: { - nullable: true, - properties: { - sizes: { - description: - 'объект ключ-значение, где ключи - строки в формате "ШxВ" (ширина, высота), а значения - ссылки на изображения', - example: { - '1280x960': - 'https://img.k.avito.ru/chat/1280x960/5083651369.3e798a9bf88345ae8fe85ff891266b24.jpg', - '140x105': - 'https://img.k.avito.ru/chat/140x105/5083651369.3e798a9bf88345ae8fe85ff891266b24.jpg', - '32x32': - 'https://img.k.avito.ru/chat/32x32/5083651369.3e798a9bf88345ae8fe85ff891266b24.jpg', - '640x480': - 'https://img.k.avito.ru/chat/640x480/5083651369.3e798a9bf88345ae8fe85ff891266b24.jpg' - }, - type: 'object' - } - }, - type: 'object' - }, - item: { - nullable: true, - properties: { - image_url: { - example: 'https://avito.ru/image_url.webp', - type: 'string' - }, - item_url: { - example: 'https://avito.ru/item_url', - type: 'string' - }, - price_string: { - example: '1 232 323 ₽', - nullable: true, - type: 'string' - }, - title: { - example: 'Объявление', - type: 'string' - } - }, - type: 'object' - }, - link: { - nullable: true, - properties: { - preview: { - nullable: true, - properties: { - description: { - example: 'Лучшие публикации за последние 24 часа', - type: 'string' - }, - domain: { - example: 'habr.com', - type: 'string' - }, - images: { - description: - 'объект ключ-значение, где ключи - строки в формате "ШxВ" (ширина, высота), а значения - ссылки на изображения', - example: { - '1280x960': - 'https://img.k.avito.ru/chat/1280x960/5083651369.3e798a9bf88345ae8fe85ff891266b24.jpg', - '140x105': - 'https://img.k.avito.ru/chat/140x105/5083651369.3e798a9bf88345ae8fe85ff891266b24.jpg', - '32x32': - 'https://img.k.avito.ru/chat/32x32/5083651369.3e798a9bf88345ae8fe85ff891266b24.jpg', - '640x480': - 'https://img.k.avito.ru/chat/640x480/5083651369.3e798a9bf88345ae8fe85ff891266b24.jpg' - }, - nullable: true, - type: 'object' - }, - title: { - example: 'Лучшие публикации за сутки / Хабр', - type: 'string' - }, - url: { - example: 'https://habr.com/ru/', - type: 'string' - } - }, - type: 'object' - }, - text: { - example: 'habr.com', - type: 'string' - }, - url: { - example: 'habr.com', - type: 'string' - } - }, - type: 'object' - }, - location: { - nullable: true, - properties: { - kind: { - enum: ['house', 'street', 'area', '...'], - example: 'street', - type: 'string' - }, - lat: { - example: 55.599799, - format: 'float', - type: 'number' - }, - lon: { - example: 37.603954, - format: 'float', - type: 'number' - }, - text: { - example: 'Москва, Варшавское шоссе', - type: 'string' - }, - title: { - example: 'Москва, Варшавское шоссе', - type: 'string' - } - }, - type: 'object' - }, - text: { - example: 'привет!', - nullable: true, - type: 'string' - }, - voice: { - nullable: true, - properties: { - voice_id: { - type: 'string' - } - }, - type: 'object' - } - }, - type: 'object' -} as const - -export const MessageQuoteSchema = { - description: 'цитируемое сообщение', - properties: { - author_id: { - example: 94235311, - format: 'int64', - type: 'integer' - }, - content: { - $ref: '#/components/schemas/MessageContent' - }, - created: { - example: 1571654040, - format: 'int64', - type: 'integer' - }, - id: { - type: 'string' - }, - type: { - enum: ['text', 'image', 'link', 'item', 'location', 'call', 'deleted', 'voice'], - type: 'string' - } - }, - type: 'object' -} as const - -export const MessagesSchema = { - items: { - properties: { - author_id: { - example: 94235311, - format: 'int64', - type: 'integer' - }, - content: { - $ref: '#/components/schemas/MessageContent' - }, - created: { - example: 1571654040, - format: 'int64', - type: 'integer' - }, - direction: { - enum: ['in', 'out'], - example: 'out', - type: 'string' - }, - id: { - type: 'string' - }, - is_read: { - description: 'прочитано ли сообщение', - example: true, - type: 'boolean' - }, - quote: { - $ref: '#/components/schemas/MessageQuote' - }, - read: { - description: 'timestamp прочтения, если прочитано', - example: 123, - nullable: true, - type: 'integer' - }, - type: { - enum: ['text', 'image', 'link', 'item', 'location', 'call', 'deleted', 'voice'], - type: 'string' - } - }, - type: 'object' - }, - type: 'array' -} as const - -export const VoiceFilesSchema = { - properties: { - voices_urls: { - additionalProperties: { - example: 'https://avito.ru/voice_url', - format: 'uri', - type: 'string' - }, - type: 'object' - } - }, - type: 'object' -} as const - -export const WebhookMessageSchema = { - properties: { - id: { - example: '68df3c53-2b03-40e2-8a3f-85232e386e1b', - type: 'string' - }, - version: { - example: 'v3.0.0', - type: 'string' - }, - timestamp: { - description: 'timestamp отправки сообщения', - example: 1745311350, - type: 'integer' - }, - payload: { - properties: { - type: { - description: 'Тип события', - example: 'message', - type: 'string' - }, - value: { - properties: { - id: { - example: 'e6e4d654c8177be20f1c332aa33a3817', - type: 'string' - }, - chat_id: { - example: 'u2i-vfm2AigtnbtFB0q_vXjlYQ', - type: 'string' - }, - user_id: { - description: 'id получателя (текущий аккаунт)', - example: 115665232, - type: 'integer' - }, - author_id: { - description: 'id отправителя (ваш или собеседник)', - example: 255510721, - type: 'integer' - }, - created: { - description: 'timestamp отправки сообщения', - example: 1745311350, - type: 'integer' - }, - type: { - description: 'Тип сообщения', - enum: [ - 'text', - 'image', - 'system', - 'item', - 'call', - 'link', - 'location', - 'deleted', - 'appCall', - 'file', - 'video', - 'voice' - ], - example: 'text', - type: 'string' - }, - chat_type: { - description: 'Тип чата (u2i - чат по объявлению, u2u - чат по профилю пользователя)', - enum: ['u2i', 'u2u'], - example: 'u2i', - type: 'string' - }, - content: { - $ref: '#/components/schemas/MessageContent' - }, - item_id: { - description: 'id объявления в u2i-чате по которому пришло сообщение', - example: 943251642, - type: 'integer' - }, - published_at: { - description: 'Время публикации сообщения в формате ISO 8601', - example: '2025-04-22T08:42:30Z', - type: 'string' - }, - read: { - description: 'timestamp прочтения, если прочитано', - example: 123, - nullable: true, - type: 'integer' - } - }, - type: 'object' - } - }, - type: 'object' - } - }, - type: 'object' -} as const - -export const addBlacklistRequestBodySchema = { - properties: { - users: { - items: { - properties: { - context: { - properties: { - item_id: { - format: 'int64', - type: 'integer' - }, - reason_id: { - description: - 'причина, по которой блокируем пользователя, 1 - спам, 2 - мошенничество, 3 - оскорбления и хамство, 4 - другая причина', - enum: [1, 2, 3, 4], - type: 'integer' - } - }, - type: 'object' - }, - user_id: { - description: 'id пользователя которого хотим заблокировать', - example: 94235311, - format: 'int64', - type: 'integer' - } - }, - type: 'object' - }, - type: 'array' - } - }, - type: 'object' -} as const - -export const authErrorSchema = { - properties: { - error: { - properties: { - code: { - description: 'Код ошибки', - example: 401, - format: 'int32', - type: 'integer' - }, - message: { - description: 'Сообщение об ошибке', - example: 'Unauthorized', - type: 'string' - } - }, - required: ['code', 'message'], - type: 'object' - } - }, - type: 'object' -} as const - -export const badRequestErrorSchema = { - properties: { - error: { - properties: { - code: { - description: 'Код ошибки', - example: 400, - format: 'int32', - type: 'integer' - }, - message: { - description: 'Сообщение об ошибке', - example: 'Bad Request', - type: 'string' - } - }, - required: ['code', 'message'], - type: 'object' - } - }, - type: 'object' -} as const - -export const forbiddenErrorSchema = { - properties: { - error: { - properties: { - code: { - description: 'Код ошибки', - example: 403, - format: 'int32', - type: 'integer' - }, - message: { - description: 'Сообщение об ошибке', - example: 'Forbidden', - type: 'string' - } - }, - required: ['code', 'message'], - type: 'object' - } - }, - type: 'object' -} as const - -export const notFoundErrorSchema = { - properties: { - error: { - properties: { - code: { - description: 'Код ошибки', - example: 404, - format: 'int32', - type: 'integer' - }, - message: { - description: 'Сообщение об ошибке', - example: 'Not found', - type: 'string' - } - }, - required: ['code', 'message'], - type: 'object' - } - }, - type: 'object' -} as const - -export const purchasingErrorSchema = { - properties: { - error: { - properties: { - code: { - description: 'Код ошибки', - example: 402, - format: 'int32', - type: 'integer' - }, - message: { - description: 'Сообщение об ошибке', - example: 'Payment required', - type: 'string' - } - }, - required: ['code', 'message'], - type: 'object' - } - }, - type: 'object' -} as const - -export const sendImageMessageRequestBodySchema = { - properties: { - image_id: { - description: 'Идентификатор загруженного изображения', - type: 'string' - } - }, - required: ['image_id'], - type: 'object' -} as const - -export const sendMessageRequestBodySchema = { - properties: { - message: { - properties: { - text: { - description: 'Текст сообщения', - type: 'string' - } - }, - type: 'object' - }, - type: { - description: 'Тип сообщения', - enum: ['text'], - type: 'string' - } - }, - required: ['url'], - type: 'object' -} as const - -export const serviceErrorSchema = { - properties: { - error: { - properties: { - code: { - description: 'Код ошибки', - example: 500, - format: 'int32', - type: 'integer' - }, - message: { - description: 'Описание ошибки', - example: 'Error while processing request. Please, contact support', - type: 'string' - } - }, - required: ['code', 'message'], - type: 'object' - } - }, - type: 'object' -} as const - -export const serviceUnavailableErrorSchema = { - properties: { - error: { - properties: { - code: { - description: 'Код ошибки', - example: 503, - format: 'int32', - type: 'integer' - }, - message: { - description: 'Описание ошибки', - example: 'Service temporarily unavailable. Please, contact support', - type: 'string' - } - }, - required: ['code', 'message'], - type: 'object' - } - }, - type: 'object' -} as const - -export const validatingErrorSchema = { - properties: { - error: { - properties: { - code: { - description: 'Код ошибки', - example: 400, - format: 'int32', - type: 'integer' - }, - fields: { - description: 'Информация об ошибке валидации параметров в формате ключ-значение', - nullable: true, - type: 'object' - }, - message: { - description: 'Сообщение об ошибке', - example: 'Validation error', - type: 'string' - } - }, - required: ['code', 'message'], - type: 'object' - } - }, - type: 'object' -} as const - -export const webhookSubscribeRequestBodySchema = { - properties: { - url: { - description: 'Url на который будут отправляться нотификации', - type: 'string' - } - }, - required: ['url'], - type: 'object' -} as const diff --git a/examples/integrations/generated/avito/messenger/sdk.gen.ts b/examples/integrations/generated/avito/messenger/sdk.gen.ts deleted file mode 100644 index 0d81393..0000000 --- a/examples/integrations/generated/avito/messenger/sdk.gen.ts +++ /dev/null @@ -1,415 +0,0 @@ -// This file is auto-generated by @hey-api/openapi-ts - -import { - type Options as ClientOptions, - type Client, - type TDataShape, - formDataBodySerializer -} from './client' -import type { - PostSendMessageData, - PostSendMessageResponses, - PostSendImageMessageData, - PostSendImageMessageResponses, - DeleteMessageData, - DeleteMessageResponses, - ChatReadData, - ChatReadResponses, - GetVoiceFilesData, - GetVoiceFilesResponses, - UploadImagesData, - UploadImagesResponses, - GetSubscriptionsData, - GetSubscriptionsResponses, - PostWebhookUnsubscribeData, - PostWebhookUnsubscribeResponses, - PostBlacklistV2Data, - PostBlacklistV2Responses, - GetChatsV2Data, - GetChatsV2Responses, - GetChatByIdV2Data, - GetChatByIdV2Responses, - GetMessagesV3Data, - GetMessagesV3Responses, - PostWebhookV3Data, - PostWebhookV3Responses -} from './types.gen' -import { client } from './client.gen' -import { getMessagesV3ResponseTransformer } from './transformers.gen' - -export type Options< - TData extends TDataShape = TDataShape, - ThrowOnError extends boolean = boolean -> = ClientOptions & { - /** - * You can provide a client instance returned by `createClient()` instead of - * individual options. This might be also useful if you want to implement a - * custom client. - */ - client?: Client - /** - * You can pass arbitrary values through the `meta` object. This can be - * used to access values that aren't defined as part of the SDK function. - */ - meta?: Record -} - -/** - * Отправка сообщения - * На данный момент можно отправить только текстовое сообщение - * - */ -export const postSendMessage = ( - options: Options -) => { - return (options.client ?? client).post({ - security: [ - { - scheme: 'bearer', - type: 'http' - }, - { - scheme: 'bearer', - type: 'http' - } - ], - url: '/messenger/v1/accounts/{user_id}/chats/{chat_id}/messages', - ...options, - headers: { - 'Content-Type': 'application/json', - ...options.headers - } - }) -} - -/** - * Отправка сообщения с изображением - * Метод используется для отправки сообщения с изображением. - * - * Для отправки сообщения с изображением необходимо передать в запросе id изображения, полученного после загрузки. - * - */ -export const postSendImageMessage = ( - options: Options -) => { - return (options.client ?? client).post({ - security: [ - { - scheme: 'bearer', - type: 'http' - }, - { - scheme: 'bearer', - type: 'http' - } - ], - url: '/messenger/v1/accounts/{user_id}/chats/{chat_id}/messages/image', - ...options, - headers: { - 'Content-Type': 'application/json', - ...options.headers - } - }) -} - -/** - * Удаление сообщения - * Сообщение не пропадает из истории, а меняет свой тип на deleted. - * Удалять сообщения можно не позднее часа с момента их отправки. - * - */ -export const deleteMessage = ( - options: Options -) => { - return (options.client ?? client).post({ - security: [ - { - scheme: 'bearer', - type: 'http' - }, - { - scheme: 'bearer', - type: 'http' - } - ], - url: '/messenger/v1/accounts/{user_id}/chats/{chat_id}/messages/{message_id}', - ...options - }) -} - -/** - * Прочитать чат - * После успешного получения списка сообщений необходимо вызвать этот метод для того, чтобы чат стал прочитанным. - * - */ -export const chatRead = ( - options: Options -) => { - return (options.client ?? client).post({ - security: [ - { - scheme: 'bearer', - type: 'http' - }, - { - scheme: 'bearer', - type: 'http' - } - ], - url: '/messenger/v1/accounts/{user_id}/chats/{chat_id}/read', - ...options - }) -} - -/** - * Получение голосовых сообщений - * Метод используется для получения ссылки на файл с голосовым сообщением по идентификатору voice_id, получаемому из тела сообщения с типом voice. - * - * Особенности работы с голосовыми сообщениями: - * - Голосовые сообщения Авито используют кодек **[opus](https://ru.wikipedia.org/wiki/Opus_(%D0%BA%D0%BE%D0%B4%D0%B5%D0%BA))** внутри **.mp4** контейнера; - * - Ссылка на голосовое сообщение доступна в течение **одного часа** с момента запроса. Попытка получить файл по ссылке спустя это время приведёт к ошибке. Для восстановления доступа необходимо получить новую ссылку на файл; - * - Как и с обычными сообщениями, получение ссылки на файл доступно только для пользователей, находящихся в беседе, где голосовое сообщение было отправлено; - * - */ -export const getVoiceFiles = ( - options: Options -) => { - return (options.client ?? client).get({ - security: [ - { - scheme: 'bearer', - type: 'http' - }, - { - scheme: 'bearer', - type: 'http' - } - ], - url: '/messenger/v1/accounts/{user_id}/getVoiceFiles', - ...options - }) -} - -/** - * Загрузка изображений - * Метод используется для загрузки изображений в формате JPEG, HEIC, GIF, BMP или PNG. - * - * Особенности работы с загрузкой изображений: - * - Метод поддерживает только одиночные изображения; для загрузки нескольких картинок необходимо сделать несколько запросов; - * - Максимальный размер файла — 24 МБ; - * - Максимальное разрешение — 75 мегапиксилей; - * - */ -export const uploadImages = ( - options: Options -) => { - return (options.client ?? client).post({ - ...formDataBodySerializer, - security: [ - { - scheme: 'bearer', - type: 'http' - }, - { - scheme: 'bearer', - type: 'http' - } - ], - url: '/messenger/v1/accounts/{user_id}/uploadImages', - ...options, - headers: { - 'Content-Type': null, - ...options.headers - } - }) -} - -/** - * Получение подписок (webhooks) - * Получение списка подписок - * - */ -export const getSubscriptions = ( - options?: Options -) => { - return (options?.client ?? client).post({ - security: [ - { - scheme: 'bearer', - type: 'http' - }, - { - scheme: 'bearer', - type: 'http' - } - ], - url: '/messenger/v1/subscriptions', - ...options - }) -} - -/** - * Отключение уведомлений (webhooks) - * Отключение уведомлений - * - */ -export const postWebhookUnsubscribe = ( - options?: Options -) => { - return (options?.client ?? client).post({ - security: [ - { - scheme: 'bearer', - type: 'http' - }, - { - scheme: 'bearer', - type: 'http' - } - ], - url: '/messenger/v1/webhook/unsubscribe', - ...options, - headers: { - 'Content-Type': 'application/json', - ...options?.headers - } - }) -} - -/** - * Добавление пользователя в blacklist - * Добавление пользователя в blacklist - * - */ -export const postBlacklistV2 = ( - options: Options -) => { - return (options.client ?? client).post({ - security: [ - { - scheme: 'bearer', - type: 'http' - }, - { - scheme: 'bearer', - type: 'http' - } - ], - url: '/messenger/v2/accounts/{user_id}/blacklist', - ...options, - headers: { - 'Content-Type': 'application/json', - ...options.headers - } - }) -} - -/** - * Получение информации по чатам - * Возвращает список чатов - * - */ -export const getChatsV2 = ( - options: Options -) => { - return (options.client ?? client).get({ - security: [ - { - scheme: 'bearer', - type: 'http' - }, - { - scheme: 'bearer', - type: 'http' - } - ], - url: '/messenger/v2/accounts/{user_id}/chats', - ...options - }) -} - -/** - * Получение информации по чату - * Возвращает данные чата и последнее сообщение в нем - * - */ -export const getChatByIdV2 = ( - options: Options -) => { - return (options.client ?? client).get({ - security: [ - { - scheme: 'bearer', - type: 'http' - }, - { - scheme: 'bearer', - type: 'http' - } - ], - url: '/messenger/v2/accounts/{user_id}/chats/{chat_id}', - ...options - }) -} - -/** - * Получение списка сообщений V3 - * Получение списка сообщений. **Не помечает чат прочитанным.** - * После успешного получения списка сообщений необходимо вызвать [метод](https://api.avito.ru/docs/api.html#operation/chatRead), который сделает сообщения прочитанными. - * Для получения новых сообщений в реальном времени используйте [webhooks](https://api.avito.ru/docs/api.html#operation/postWebhookV3) - * - */ -export const getMessagesV3 = ( - options: Options -) => { - return (options.client ?? client).get({ - responseTransformer: getMessagesV3ResponseTransformer, - security: [ - { - scheme: 'bearer', - type: 'http' - }, - { - scheme: 'bearer', - type: 'http' - } - ], - url: '/messenger/v3/accounts/{user_id}/chats/{chat_id}/messages/', - ...options - }) -} - -/** - * Включение уведомлений V3 (webhooks) - * Включение webhook-уведомлений. - * - * Схему JSON приходящего в webhook сообщения можно увидеть в примерах ответов. - * - * После регистрации url'а для получения веб-хуков, убедитесь, что он доступен, работает и возвращает статус 200 ОК соблюдая timeout 2s, - * например, выполнив запрос: - * - * curl --connect-timeout 2 -i -d '{}' - * - */ -export const postWebhookV3 = ( - options?: Options -) => { - return (options?.client ?? client).post({ - security: [ - { - scheme: 'bearer', - type: 'http' - }, - { - scheme: 'bearer', - type: 'http' - } - ], - url: '/messenger/v3/webhook', - ...options, - headers: { - 'Content-Type': 'application/json', - ...options?.headers - } - }) -} diff --git a/examples/integrations/generated/avito/messenger/transformers.gen.ts b/examples/integrations/generated/avito/messenger/transformers.gen.ts deleted file mode 100644 index e8ca51b..0000000 --- a/examples/integrations/generated/avito/messenger/transformers.gen.ts +++ /dev/null @@ -1,51 +0,0 @@ -// This file is auto-generated by @hey-api/openapi-ts - -import type { GetMessagesV3Response } from './types.gen' - -const messageContentSchemaResponseTransformer = (data: any) => { - if (data.call) { - if (data.call.target_user_id) { - data.call.target_user_id = BigInt(data.call.target_user_id.toString()) - } - } - return data -} - -const messageQuoteSchemaResponseTransformer = (data: any) => { - if (data.author_id) { - data.author_id = BigInt(data.author_id.toString()) - } - if (data.content) { - data.content = messageContentSchemaResponseTransformer(data.content) - } - if (data.created) { - data.created = BigInt(data.created.toString()) - } - return data -} - -const messagesSchemaResponseTransformer = (data: any) => { - data = data.map((item: any) => { - if (item.author_id) { - item.author_id = BigInt(item.author_id.toString()) - } - if (item.content) { - item.content = messageContentSchemaResponseTransformer(item.content) - } - if (item.created) { - item.created = BigInt(item.created.toString()) - } - if (item.quote) { - item.quote = messageQuoteSchemaResponseTransformer(item.quote) - } - return item - }) - return data -} - -export const getMessagesV3ResponseTransformer = async ( - data: any -): Promise => { - data = messagesSchemaResponseTransformer(data) - return data -} diff --git a/examples/integrations/generated/avito/messenger/types.gen.ts b/examples/integrations/generated/avito/messenger/types.gen.ts deleted file mode 100644 index 089ae3d..0000000 --- a/examples/integrations/generated/avito/messenger/types.gen.ts +++ /dev/null @@ -1,900 +0,0 @@ -// This file is auto-generated by @hey-api/openapi-ts - -export type Chat = { - context?: { - type?: string - value?: { - /** - * ID объявления, если чат по объявлению - */ - id?: number - images?: { - count?: number - main?: { - '140x105'?: string - } - } - price_string?: string - status_id?: number - title?: string - url?: string - /** - * ID автора объявления, если чат по объявлению - */ - user_id?: number - } - } - created?: number - id?: string - last_message?: { - author_id?: number - content?: { - link?: { - text?: string - url?: string - } - } - created?: number - direction?: string - id?: string - type?: string - } - updated?: number - users?: Array<{ - id?: number - name?: string - public_user_profile?: { - avatar?: { - default?: string - images?: { - '128x128'?: string - '192x192'?: string - '24x24'?: string - '256x256'?: string - '36x36'?: string - '48x48'?: string - '64x64'?: string - '72x72'?: string - '96x96'?: string - } - } - item_id?: number - url?: string - user_id?: number - } - }> -} - -export type Chats = { - chats?: Array -} - -/** - * Для сообщений типов "appCall" "file" "video" возвращается empty object (данные типы не поддерживаются) - */ -export type MessageContent = { - call?: { - status?: 'missed' - target_user_id?: bigint - } | null - flow_id?: string | null - image?: { - /** - * объект ключ-значение, где ключи - строки в формате "ШxВ" (ширина, высота), а значения - ссылки на изображения - */ - sizes?: { - [key: string]: unknown - } - } | null - item?: { - image_url?: string - item_url?: string - price_string?: string | null - title?: string - } | null - link?: { - preview?: { - description?: string - domain?: string - /** - * объект ключ-значение, где ключи - строки в формате "ШxВ" (ширина, высота), а значения - ссылки на изображения - */ - images?: { - [key: string]: unknown - } | null - title?: string - url?: string - } | null - text?: string - url?: string - } | null - location?: { - kind?: 'house' | 'street' | 'area' | '...' - lat?: number - lon?: number - text?: string - title?: string - } | null - text?: string | null - voice?: { - voice_id?: string - } | null -} - -/** - * цитируемое сообщение - */ -export type MessageQuote = { - author_id?: bigint - content?: MessageContent - created?: bigint - id?: string - type?: 'text' | 'image' | 'link' | 'item' | 'location' | 'call' | 'deleted' | 'voice' -} - -export type Messages = Array<{ - author_id?: bigint - content?: MessageContent - created?: bigint - direction?: 'in' | 'out' - id?: string - /** - * прочитано ли сообщение - */ - is_read?: boolean - quote?: MessageQuote - /** - * timestamp прочтения, если прочитано - */ - read?: number | null - type?: 'text' | 'image' | 'link' | 'item' | 'location' | 'call' | 'deleted' | 'voice' -}> - -export type VoiceFiles = { - voices_urls?: { - [key: string]: string - } -} - -export type WebhookMessage = { - id?: string - version?: string - /** - * timestamp отправки сообщения - */ - timestamp?: number - payload?: { - /** - * Тип события - */ - type?: string - value?: { - id?: string - chat_id?: string - /** - * id получателя (текущий аккаунт) - */ - user_id?: number - /** - * id отправителя (ваш или собеседник) - */ - author_id?: number - /** - * timestamp отправки сообщения - */ - created?: number - /** - * Тип сообщения - */ - type?: - | 'text' - | 'image' - | 'system' - | 'item' - | 'call' - | 'link' - | 'location' - | 'deleted' - | 'appCall' - | 'file' - | 'video' - | 'voice' - /** - * Тип чата (u2i - чат по объявлению, u2u - чат по профилю пользователя) - */ - chat_type?: 'u2i' | 'u2u' - content?: MessageContent - /** - * id объявления в u2i-чате по которому пришло сообщение - */ - item_id?: number - /** - * Время публикации сообщения в формате ISO 8601 - */ - published_at?: string - /** - * timestamp прочтения, если прочитано - */ - read?: number | null - } - } -} - -export type AddBlacklistRequestBody = { - users?: Array<{ - context?: { - item_id?: bigint - /** - * причина, по которой блокируем пользователя, 1 - спам, 2 - мошенничество, 3 - оскорбления и хамство, 4 - другая причина - */ - reason_id?: 1 | 2 | 3 | 4 - } - /** - * id пользователя которого хотим заблокировать - */ - user_id?: bigint - }> -} - -export type AuthError = { - error?: { - /** - * Код ошибки - */ - code: number - /** - * Сообщение об ошибке - */ - message: string - } -} - -export type BadRequestError = { - error?: { - /** - * Код ошибки - */ - code: number - /** - * Сообщение об ошибке - */ - message: string - } -} - -export type ForbiddenError = { - error?: { - /** - * Код ошибки - */ - code: number - /** - * Сообщение об ошибке - */ - message: string - } -} - -export type NotFoundError = { - error?: { - /** - * Код ошибки - */ - code: number - /** - * Сообщение об ошибке - */ - message: string - } -} - -export type PurchasingError = { - error?: { - /** - * Код ошибки - */ - code: number - /** - * Сообщение об ошибке - */ - message: string - } -} - -export type SendImageMessageRequestBody = { - /** - * Идентификатор загруженного изображения - */ - image_id: string -} - -export type SendMessageRequestBody = { - message?: { - /** - * Текст сообщения - */ - text?: string - } - /** - * Тип сообщения - */ - type?: 'text' -} - -export type ServiceError = { - error?: { - /** - * Код ошибки - */ - code: number - /** - * Описание ошибки - */ - message: string - } -} - -export type ServiceUnavailableError = { - error?: { - /** - * Код ошибки - */ - code: number - /** - * Описание ошибки - */ - message: string - } -} - -export type ValidatingError = { - error?: { - /** - * Код ошибки - */ - code: number - /** - * Информация об ошибке валидации параметров в формате ключ-значение - */ - fields?: { - [key: string]: unknown - } | null - /** - * Сообщение об ошибке - */ - message: string - } -} - -export type WebhookSubscribeRequestBody = { - /** - * Url на который будут отправляться нотификации - */ - url: string -} - -/** - * Токен для авторизации - */ -export type AuthHeader = string - -/** - * Идентификатор чата (клиента) - */ -export type ChatId = string - -/** - * Фильтрация возвращаемых чатов. - * * u2i — чаты по объявлениям; - * * u2u — чаты между пользователями; - * - */ -export type ChatTypes = Array<'u2i' | 'u2u'> - -/** - * Идентификатор загруженного изображения - */ -export type ImageId = string - -/** - * Получение чатов только по объявлениям с указанными item_id - */ -export type ItemIds = Array - -/** - * Количество сообщений / чатов для запроса - */ -export type Limit = number - -/** - * Идентификатор сообщения - */ -export type MessageId = string - -/** - * Сдвиг сообщений / чатов для запроса - */ -export type Offset = number - -/** - * При значении true метод возвращает только непрочитанные чаты - */ -export type UnreadOnly = boolean - -/** - * Идентификатор пользователя (клиента) - */ -export type UserId = bigint - -/** - * Получение файлов голосовых сообщений с указанными voice_id - */ -export type VoiceIds = Array - -export type PostSendMessageData = { - /** - * Отправление сообщения - */ - body?: SendMessageRequestBody - headers?: { - /** - * Токен для авторизации - */ - Authorization?: string - } - path: { - /** - * Идентификатор пользователя (клиента) - */ - user_id: bigint - /** - * Идентификатор чата (клиента) - */ - chat_id: string - } - query?: never - url: '/messenger/v1/accounts/{user_id}/chats/{chat_id}/messages' -} - -export type PostSendMessageResponses = { - /** - * Успешный ответ - */ - 200: { - content?: { - text?: string - } - created?: number - direction?: string - id?: string - type?: string - } -} - -export type PostSendMessageResponse = PostSendMessageResponses[keyof PostSendMessageResponses] - -export type PostSendImageMessageData = { - /** - * Вложение с изображением - */ - body?: SendImageMessageRequestBody - headers?: { - /** - * Токен для авторизации - */ - Authorization?: string - } - path: { - /** - * Идентификатор пользователя (клиента) - */ - user_id: bigint - /** - * Идентификатор чата (клиента) - */ - chat_id: string - } - query?: never - url: '/messenger/v1/accounts/{user_id}/chats/{chat_id}/messages/image' -} - -export type PostSendImageMessageResponses = { - /** - * Успешный ответ - */ - 200: { - author_id?: number - content?: { - image?: { - sizes?: { - [key: string]: string - } - } - } - created?: number - direction?: string - id?: string - type?: string - } -} - -export type PostSendImageMessageResponse = - PostSendImageMessageResponses[keyof PostSendImageMessageResponses] - -export type DeleteMessageData = { - body?: never - headers?: { - /** - * Токен для авторизации - */ - Authorization?: string - } - path: { - /** - * Идентификатор пользователя (клиента) - */ - user_id: bigint - /** - * Идентификатор чата (клиента) - */ - chat_id: string - /** - * Идентификатор сообщения - */ - message_id: string - } - query?: never - url: '/messenger/v1/accounts/{user_id}/chats/{chat_id}/messages/{message_id}' -} - -export type DeleteMessageResponses = { - /** - * Успешный ответ - */ - 200: { - [key: string]: unknown - } -} - -export type DeleteMessageResponse = DeleteMessageResponses[keyof DeleteMessageResponses] - -export type ChatReadData = { - body?: never - headers?: { - /** - * Токен для авторизации - */ - Authorization?: string - } - path: { - /** - * Идентификатор пользователя (клиента) - */ - user_id: bigint - /** - * Идентификатор чата (клиента) - */ - chat_id: string - } - query?: never - url: '/messenger/v1/accounts/{user_id}/chats/{chat_id}/read' -} - -export type ChatReadResponses = { - /** - * Успешный ответ - */ - 200: { - ok?: boolean - } -} - -export type ChatReadResponse = ChatReadResponses[keyof ChatReadResponses] - -export type GetVoiceFilesData = { - body?: never - headers?: { - /** - * Токен для авторизации - */ - Authorization?: string - } - path: { - /** - * Идентификатор пользователя (клиента) - */ - user_id: bigint - } - query: { - /** - * Получение файлов голосовых сообщений с указанными voice_id - */ - voice_ids: Array - } - url: '/messenger/v1/accounts/{user_id}/getVoiceFiles' -} - -export type GetVoiceFilesResponses = { - /** - * Успешный ответ - */ - 200: VoiceFiles -} - -export type GetVoiceFilesResponse = GetVoiceFilesResponses[keyof GetVoiceFilesResponses] - -export type UploadImagesData = { - body?: { - 'uploadfile[]': Blob | File - } - headers?: { - /** - * Токен для авторизации - */ - Authorization?: string - } - path: { - /** - * Идентификатор пользователя (клиента) - */ - user_id: bigint - } - query?: never - url: '/messenger/v1/accounts/{user_id}/uploadImages' -} - -export type UploadImagesResponses = { - /** - * Успешный ответ - */ - 200: { - [key: string]: { - [key: string]: string - } - } -} - -export type UploadImagesResponse = UploadImagesResponses[keyof UploadImagesResponses] - -export type GetSubscriptionsData = { - body?: never - headers?: { - /** - * Токен для авторизации - */ - Authorization?: string - } - path?: never - query?: never - url: '/messenger/v1/subscriptions' -} - -export type GetSubscriptionsResponses = { - /** - * Успешный ответ - */ - 200: { - subscriptions: Array<{ - url: string - /** - * Версия метода, через который вебхук добавлен. Влияет на формат получаемых данных - */ - version: string - }> - } -} - -export type GetSubscriptionsResponse = GetSubscriptionsResponses[keyof GetSubscriptionsResponses] - -export type PostWebhookUnsubscribeData = { - /** - * Url, на который необходимо перестать слать уведомления - */ - body?: WebhookSubscribeRequestBody - headers?: { - /** - * Токен для авторизации - */ - Authorization?: string - } - path?: never - query?: never - url: '/messenger/v1/webhook/unsubscribe' -} - -export type PostWebhookUnsubscribeResponses = { - /** - * Успешный ответ - */ - 200: { - ok?: boolean - } -} - -export type PostWebhookUnsubscribeResponse = - PostWebhookUnsubscribeResponses[keyof PostWebhookUnsubscribeResponses] - -export type PostBlacklistV2Data = { - /** - * Добавление пользователя в blacklist - */ - body?: AddBlacklistRequestBody - headers?: { - /** - * Токен для авторизации - */ - Authorization?: string - } - path: { - /** - * Идентификатор пользователя (клиента) - */ - user_id: bigint - } - query?: never - url: '/messenger/v2/accounts/{user_id}/blacklist' -} - -export type PostBlacklistV2Responses = { - /** - * Успешный ответ - */ - 200: unknown -} - -export type GetChatsV2Data = { - body?: never - headers?: { - /** - * Токен для авторизации - */ - Authorization?: string - } - path: { - /** - * Идентификатор пользователя (клиента) - */ - user_id: bigint - } - query?: { - /** - * Получение чатов только по объявлениям с указанными item_id - */ - item_ids?: Array - /** - * При значении true метод возвращает только непрочитанные чаты - */ - unread_only?: boolean - /** - * Фильтрация возвращаемых чатов. - * * u2i — чаты по объявлениям; - * * u2u — чаты между пользователями; - * - */ - chat_types?: Array<'u2i' | 'u2u'> - /** - * Количество сообщений / чатов для запроса - */ - limit?: number - /** - * Сдвиг сообщений / чатов для запроса - */ - offset?: number - } - url: '/messenger/v2/accounts/{user_id}/chats' -} - -export type GetChatsV2Responses = { - /** - * Успешный ответ - */ - 200: Chats -} - -export type GetChatsV2Response = GetChatsV2Responses[keyof GetChatsV2Responses] - -export type GetChatByIdV2Data = { - body?: never - headers?: { - /** - * Токен для авторизации - */ - Authorization?: string - } - path: { - /** - * Идентификатор пользователя (клиента) - */ - user_id: bigint - /** - * Идентификатор чата (клиента) - */ - chat_id: string - } - query?: never - url: '/messenger/v2/accounts/{user_id}/chats/{chat_id}' -} - -export type GetChatByIdV2Responses = { - /** - * Успешный ответ - */ - 200: Chat -} - -export type GetChatByIdV2Response = GetChatByIdV2Responses[keyof GetChatByIdV2Responses] - -export type GetMessagesV3Data = { - body?: never - headers?: { - /** - * Токен для авторизации - */ - Authorization?: string - } - path: { - /** - * Идентификатор пользователя (клиента) - */ - user_id: bigint - /** - * Идентификатор чата (клиента) - */ - chat_id: string - } - query?: { - /** - * Количество сообщений / чатов для запроса - */ - limit?: number - /** - * Сдвиг сообщений / чатов для запроса - */ - offset?: number - } - url: '/messenger/v3/accounts/{user_id}/chats/{chat_id}/messages/' -} - -export type GetMessagesV3Responses = { - /** - * Успешный ответ - */ - 200: Messages -} - -export type GetMessagesV3Response = GetMessagesV3Responses[keyof GetMessagesV3Responses] - -export type PostWebhookV3Data = { - /** - * Url на который будут отправляться уведомления - */ - body?: WebhookSubscribeRequestBody - headers?: { - /** - * Токен для авторизации - */ - Authorization?: string - } - path?: never - query?: never - url: '/messenger/v3/webhook' -} - -export type PostWebhookV3Responses = { - /** - * Успешный ответ - */ - 200: { - ok?: boolean - } - /** - * JSON сообщения, который будет приходить в webhook - */ - 201: WebhookMessage -} - -export type PostWebhookV3Response = PostWebhookV3Responses[keyof PostWebhookV3Responses] - -export type ClientOptions = { - baseUrl: 'https://api.avito.ru/' | (string & {}) -} diff --git a/examples/integrations/generated/avito/messenger/zod.gen.ts b/examples/integrations/generated/avito/messenger/zod.gen.ts deleted file mode 100644 index 297651b..0000000 --- a/examples/integrations/generated/avito/messenger/zod.gen.ts +++ /dev/null @@ -1,692 +0,0 @@ -// This file is auto-generated by @hey-api/openapi-ts - -import { z } from 'zod' - -export const zChat = z.object({ - context: z.optional( - z.object({ - type: z.optional(z.string()), - value: z.optional( - z.object({ - id: z.optional(z.int()), - images: z.optional( - z.object({ - count: z.optional(z.int()), - main: z.optional( - z.object({ - '140x105': z.optional(z.string()) - }) - ) - }) - ), - price_string: z.optional(z.string()), - status_id: z.optional(z.int()), - title: z.optional(z.string()), - url: z.optional(z.string()), - user_id: z.optional(z.int()) - }) - ) - }) - ), - created: z.optional(z.int()), - id: z.optional(z.string()), - last_message: z.optional( - z.object({ - author_id: z.optional(z.int()), - content: z.optional( - z.object({ - link: z.optional( - z.object({ - text: z.optional(z.string()), - url: z.optional(z.string()) - }) - ) - }) - ), - created: z.optional(z.int()), - direction: z.optional(z.string()), - id: z.optional(z.string()), - type: z.optional(z.string()) - }) - ), - updated: z.optional(z.int()), - users: z.optional( - z.array( - z.object({ - id: z.optional(z.int()), - name: z.optional(z.string()), - public_user_profile: z.optional( - z.object({ - avatar: z.optional( - z.object({ - default: z.optional(z.string()), - images: z.optional( - z.object({ - '128x128': z.optional(z.string()), - '192x192': z.optional(z.string()), - '24x24': z.optional(z.string()), - '256x256': z.optional(z.string()), - '36x36': z.optional(z.string()), - '48x48': z.optional(z.string()), - '64x64': z.optional(z.string()), - '72x72': z.optional(z.string()), - '96x96': z.optional(z.string()) - }) - ) - }) - ), - item_id: z.optional(z.int()), - url: z.optional(z.string()), - user_id: z.optional(z.int()) - }) - ) - }) - ) - ) -}) - -export const zChats = z.object({ - chats: z.optional(z.array(zChat)) -}) - -/** - * Для сообщений типов "appCall" "file" "video" возвращается empty object (данные типы не поддерживаются) - */ -export const zMessageContent = z.object({ - call: z.optional( - z.union([ - z.object({ - status: z.optional(z.enum(['missed'])), - target_user_id: z.optional(z.coerce.bigint()) - }), - z.null() - ]) - ), - flow_id: z.optional(z.union([z.string(), z.null()])), - image: z.optional( - z.union([ - z.object({ - sizes: z.optional(z.record(z.string(), z.unknown())) - }), - z.null() - ]) - ), - item: z.optional( - z.union([ - z.object({ - image_url: z.optional(z.string()), - item_url: z.optional(z.string()), - price_string: z.optional(z.union([z.string(), z.null()])), - title: z.optional(z.string()) - }), - z.null() - ]) - ), - link: z.optional( - z.union([ - z.object({ - preview: z.optional( - z.union([ - z.object({ - description: z.optional(z.string()), - domain: z.optional(z.string()), - images: z.optional(z.union([z.record(z.string(), z.unknown()), z.null()])), - title: z.optional(z.string()), - url: z.optional(z.string()) - }), - z.null() - ]) - ), - text: z.optional(z.string()), - url: z.optional(z.string()) - }), - z.null() - ]) - ), - location: z.optional( - z.union([ - z.object({ - kind: z.optional(z.enum(['house', 'street', 'area', '...'])), - lat: z.optional(z.number()), - lon: z.optional(z.number()), - text: z.optional(z.string()), - title: z.optional(z.string()) - }), - z.null() - ]) - ), - text: z.optional(z.union([z.string(), z.null()])), - voice: z.optional( - z.union([ - z.object({ - voice_id: z.optional(z.string()) - }), - z.null() - ]) - ) -}) - -/** - * цитируемое сообщение - */ -export const zMessageQuote = z.object({ - author_id: z.optional(z.coerce.bigint()), - content: z.optional(zMessageContent), - created: z.optional(z.coerce.bigint()), - id: z.optional(z.string()), - type: z.optional( - z.enum(['text', 'image', 'link', 'item', 'location', 'call', 'deleted', 'voice']) - ) -}) - -export const zMessages = z.array( - z.object({ - author_id: z.optional(z.coerce.bigint()), - content: z.optional(zMessageContent), - created: z.optional(z.coerce.bigint()), - direction: z.optional(z.enum(['in', 'out'])), - id: z.optional(z.string()), - is_read: z.optional(z.boolean()), - quote: z.optional(zMessageQuote), - read: z.optional(z.union([z.int(), z.null()])), - type: z.optional( - z.enum(['text', 'image', 'link', 'item', 'location', 'call', 'deleted', 'voice']) - ) - }) -) - -export const zVoiceFiles = z.object({ - voices_urls: z.optional(z.record(z.string(), z.url())) -}) - -export const zWebhookMessage = z.object({ - id: z.optional(z.string()), - version: z.optional(z.string()), - timestamp: z.optional(z.int()), - payload: z.optional( - z.object({ - type: z.optional(z.string()), - value: z.optional( - z.object({ - id: z.optional(z.string()), - chat_id: z.optional(z.string()), - user_id: z.optional(z.int()), - author_id: z.optional(z.int()), - created: z.optional(z.int()), - type: z.optional( - z.enum([ - 'text', - 'image', - 'system', - 'item', - 'call', - 'link', - 'location', - 'deleted', - 'appCall', - 'file', - 'video', - 'voice' - ]) - ), - chat_type: z.optional(z.enum(['u2i', 'u2u'])), - content: z.optional(zMessageContent), - item_id: z.optional(z.int()), - published_at: z.optional(z.string()), - read: z.optional(z.union([z.int(), z.null()])) - }) - ) - }) - ) -}) - -export const zAddBlacklistRequestBody = z.object({ - users: z.optional( - z.array( - z.object({ - context: z.optional( - z.object({ - item_id: z.optional(z.coerce.bigint()), - reason_id: z.optional(z.unknown()) - }) - ), - user_id: z.optional(z.coerce.bigint()) - }) - ) - ) -}) - -export const zAuthError = z.object({ - error: z.optional( - z.object({ - code: z.int(), - message: z.string() - }) - ) -}) - -export const zBadRequestError = z.object({ - error: z.optional( - z.object({ - code: z.int(), - message: z.string() - }) - ) -}) - -export const zForbiddenError = z.object({ - error: z.optional( - z.object({ - code: z.int(), - message: z.string() - }) - ) -}) - -export const zNotFoundError = z.object({ - error: z.optional( - z.object({ - code: z.int(), - message: z.string() - }) - ) -}) - -export const zPurchasingError = z.object({ - error: z.optional( - z.object({ - code: z.int(), - message: z.string() - }) - ) -}) - -export const zSendImageMessageRequestBody = z.object({ - image_id: z.string() -}) - -export const zSendMessageRequestBody = z.object({ - message: z.optional( - z.object({ - text: z.optional(z.string()) - }) - ), - type: z.optional(z.enum(['text'])) -}) - -export const zServiceError = z.object({ - error: z.optional( - z.object({ - code: z.int(), - message: z.string() - }) - ) -}) - -export const zServiceUnavailableError = z.object({ - error: z.optional( - z.object({ - code: z.int(), - message: z.string() - }) - ) -}) - -export const zValidatingError = z.object({ - error: z.optional( - z.object({ - code: z.int(), - fields: z.optional(z.union([z.record(z.string(), z.unknown()), z.null()])), - message: z.string() - }) - ) -}) - -export const zWebhookSubscribeRequestBody = z.object({ - url: z.string() -}) - -/** - * Токен для авторизации - */ -export const zAuthHeader = z.string() - -/** - * Идентификатор чата (клиента) - */ -export const zChatId = z.string() - -/** - * Фильтрация возвращаемых чатов. - * * u2i — чаты по объявлениям; - * * u2u — чаты между пользователями; - * - */ -export const zChatTypes = z.array(z.enum(['u2i', 'u2u'])).default('u2i') - -/** - * Идентификатор загруженного изображения - */ -export const zImageId = z.string() - -/** - * Получение чатов только по объявлениям с указанными item_id - */ -export const zItemIds = z.array(z.coerce.bigint()) - -/** - * Количество сообщений / чатов для запроса - */ -export const zLimit = z.int().gte(1).lte(100).default(100) - -/** - * Идентификатор сообщения - */ -export const zMessageId = z.string() - -/** - * Сдвиг сообщений / чатов для запроса - */ -export const zOffset = z.int().default(0) - -/** - * При значении true метод возвращает только непрочитанные чаты - */ -export const zUnreadOnly = z.boolean().default(false) - -/** - * Идентификатор пользователя (клиента) - */ -export const zUserId = z.coerce.bigint() - -/** - * Получение файлов голосовых сообщений с указанными voice_id - */ -export const zVoiceIds = z.array(z.string()) - -export const zPostSendMessageData = z.object({ - body: z.optional(zSendMessageRequestBody), - path: z.object({ - user_id: z.coerce.bigint(), - chat_id: z.string() - }), - query: z.optional(z.never()), - headers: z.optional( - z.object({ - Authorization: z.optional(z.string()) - }) - ) -}) - -/** - * Успешный ответ - */ -export const zPostSendMessageResponse = z.object({ - content: z.optional( - z.object({ - text: z.optional(z.string()) - }) - ), - created: z.optional(z.int()), - direction: z.optional(z.string()), - id: z.optional(z.string()), - type: z.optional(z.string()) -}) - -export const zPostSendImageMessageData = z.object({ - body: z.optional(zSendImageMessageRequestBody), - path: z.object({ - user_id: z.coerce.bigint(), - chat_id: z.string() - }), - query: z.optional(z.never()), - headers: z.optional( - z.object({ - Authorization: z.optional(z.string()) - }) - ) -}) - -/** - * Успешный ответ - */ -export const zPostSendImageMessageResponse = z.object({ - author_id: z.optional(z.int()), - content: z.optional( - z.object({ - image: z.optional( - z.object({ - sizes: z.optional(z.record(z.string(), z.string())) - }) - ) - }) - ), - created: z.optional(z.int()), - direction: z.optional(z.string()), - id: z.optional(z.string()), - type: z.optional(z.string()) -}) - -export const zDeleteMessageData = z.object({ - body: z.optional(z.never()), - path: z.object({ - user_id: z.coerce.bigint(), - chat_id: z.string(), - message_id: z.string() - }), - query: z.optional(z.never()), - headers: z.optional( - z.object({ - Authorization: z.optional(z.string()) - }) - ) -}) - -/** - * Успешный ответ - */ -export const zDeleteMessageResponse = z.record(z.string(), z.unknown()) - -export const zChatReadData = z.object({ - body: z.optional(z.never()), - path: z.object({ - user_id: z.coerce.bigint(), - chat_id: z.string() - }), - query: z.optional(z.never()), - headers: z.optional( - z.object({ - Authorization: z.optional(z.string()) - }) - ) -}) - -/** - * Успешный ответ - */ -export const zChatReadResponse = z.object({ - ok: z.optional(z.boolean()) -}) - -export const zGetVoiceFilesData = z.object({ - body: z.optional(z.never()), - path: z.object({ - user_id: z.coerce.bigint() - }), - query: z.object({ - voice_ids: z.array(z.string()) - }), - headers: z.optional( - z.object({ - Authorization: z.optional(z.string()) - }) - ) -}) - -/** - * Успешный ответ - */ -export const zGetVoiceFilesResponse = zVoiceFiles - -export const zUploadImagesData = z.object({ - body: z.optional( - z.object({ - 'uploadfile[]': z.string() - }) - ), - path: z.object({ - user_id: z.coerce.bigint() - }), - query: z.optional(z.never()), - headers: z.optional( - z.object({ - Authorization: z.optional(z.string()) - }) - ) -}) - -/** - * Успешный ответ - */ -export const zUploadImagesResponse = z.record(z.string(), z.record(z.string(), z.string())) - -export const zGetSubscriptionsData = z.object({ - body: z.optional(z.never()), - path: z.optional(z.never()), - query: z.optional(z.never()), - headers: z.optional( - z.object({ - Authorization: z.optional(z.string()) - }) - ) -}) - -/** - * Успешный ответ - */ -export const zGetSubscriptionsResponse = z.object({ - subscriptions: z.array( - z.object({ - url: z.string(), - version: z.string() - }) - ) -}) - -export const zPostWebhookUnsubscribeData = z.object({ - body: z.optional(zWebhookSubscribeRequestBody), - path: z.optional(z.never()), - query: z.optional(z.never()), - headers: z.optional( - z.object({ - Authorization: z.optional(z.string()) - }) - ) -}) - -/** - * Успешный ответ - */ -export const zPostWebhookUnsubscribeResponse = z.object({ - ok: z.optional(z.boolean()) -}) - -export const zPostBlacklistV2Data = z.object({ - body: z.optional(zAddBlacklistRequestBody), - path: z.object({ - user_id: z.coerce.bigint() - }), - query: z.optional(z.never()), - headers: z.optional( - z.object({ - Authorization: z.optional(z.string()) - }) - ) -}) - -export const zGetChatsV2Data = z.object({ - body: z.optional(z.never()), - path: z.object({ - user_id: z.coerce.bigint() - }), - query: z.optional( - z.object({ - item_ids: z.optional(z.array(z.coerce.bigint())), - unread_only: z.optional(z.boolean()).default(false), - chat_types: z.optional(z.array(z.enum(['u2i', 'u2u']))).default('u2i'), - limit: z.optional(z.int().gte(1).lte(100)).default(100), - offset: z.optional(z.int()).default(0) - }) - ), - headers: z.optional( - z.object({ - Authorization: z.optional(z.string()) - }) - ) -}) - -/** - * Успешный ответ - */ -export const zGetChatsV2Response = zChats - -export const zGetChatByIdV2Data = z.object({ - body: z.optional(z.never()), - path: z.object({ - user_id: z.coerce.bigint(), - chat_id: z.string() - }), - query: z.optional(z.never()), - headers: z.optional( - z.object({ - Authorization: z.optional(z.string()) - }) - ) -}) - -/** - * Успешный ответ - */ -export const zGetChatByIdV2Response = zChat - -export const zGetMessagesV3Data = z.object({ - body: z.optional(z.never()), - path: z.object({ - user_id: z.coerce.bigint(), - chat_id: z.string() - }), - query: z.optional( - z.object({ - limit: z.optional(z.int().gte(1).lte(100)).default(100), - offset: z.optional(z.int()).default(0) - }) - ), - headers: z.optional( - z.object({ - Authorization: z.optional(z.string()) - }) - ) -}) - -/** - * Успешный ответ - */ -export const zGetMessagesV3Response = zMessages - -export const zPostWebhookV3Data = z.object({ - body: z.optional(zWebhookSubscribeRequestBody), - path: z.optional(z.never()), - query: z.optional(z.never()), - headers: z.optional( - z.object({ - Authorization: z.optional(z.string()) - }) - ) -}) - -export const zPostWebhookV3Response = z.union([ - z.object({ - ok: z.optional(z.boolean()) - }), - zWebhookMessage -]) diff --git a/examples/integrations/generated/google/authorization/client.gen.ts b/examples/integrations/generated/google/authorization/client.gen.ts deleted file mode 100644 index 49061d1..0000000 --- a/examples/integrations/generated/google/authorization/client.gen.ts +++ /dev/null @@ -1,27 +0,0 @@ -// This file is auto-generated by @hey-api/openapi-ts - -import type { ClientOptions } from './types.gen' -import { - type ClientOptions as DefaultClientOptions, - type Config, - createClient, - createConfig -} from './client' - -/** - * The `createClientConfig()` function will be called on client initialization - * and the returned object will become the client's initial configuration. - * - * You may want to initialize your client this way instead of calling - * `setConfig()`. This is useful for example if you're using Next.js - * to ensure your client always has the correct values. - */ -export type CreateClientConfig = ( - override?: Config -) => Config & T> - -export const client = createClient( - createConfig({ - baseUrl: 'https://www.googleapis.com/' - }) -) diff --git a/examples/integrations/generated/google/authorization/client/client.gen.ts b/examples/integrations/generated/google/authorization/client/client.gen.ts deleted file mode 100644 index 4a4fc46..0000000 --- a/examples/integrations/generated/google/authorization/client/client.gen.ts +++ /dev/null @@ -1,253 +0,0 @@ -// This file is auto-generated by @hey-api/openapi-ts - -import { createSseClient } from '../core/serverSentEvents.gen' -import type { HttpMethod } from '../core/types.gen' -import { getValidRequestBody } from '../core/utils.gen' -import type { Client, Config, RequestOptions, ResolvedRequestOptions } from './types.gen' -import { - buildUrl, - createConfig, - createInterceptors, - getParseAs, - mergeConfigs, - mergeHeaders, - setAuthParams -} from './utils.gen' - -type ReqInit = Omit & { - body?: any - headers: ReturnType -} - -export const createClient = (config: Config = {}): Client => { - let _config = mergeConfigs(createConfig(), config) - - const getConfig = (): Config => ({ ..._config }) - - const setConfig = (config: Config): Config => { - _config = mergeConfigs(_config, config) - return getConfig() - } - - const interceptors = createInterceptors() - - const beforeRequest = async (options: RequestOptions) => { - const opts = { - ..._config, - ...options, - fetch: options.fetch ?? _config.fetch ?? globalThis.fetch, - headers: mergeHeaders(_config.headers, options.headers), - serializedBody: undefined - } - - if (opts.security) { - await setAuthParams({ - ...opts, - security: opts.security - }) - } - - if (opts.requestValidator) { - await opts.requestValidator(opts) - } - - if (opts.body !== undefined && opts.bodySerializer) { - opts.serializedBody = opts.bodySerializer(opts.body) - } - - // remove Content-Type header if body is empty to avoid sending invalid requests - if (opts.body === undefined || opts.serializedBody === '') { - opts.headers.delete('Content-Type') - } - - const url = buildUrl(opts) - - return { opts, url } - } - - const request: Client['request'] = async (options) => { - // @ts-expect-error - const { opts, url } = await beforeRequest(options) - const requestInit: ReqInit = { - redirect: 'follow', - ...opts, - body: getValidRequestBody(opts) - } - - let request = new Request(url, requestInit) - - for (const fn of interceptors.request.fns) { - if (fn) { - request = await fn(request, opts) - } - } - - // fetch must be assigned here, otherwise it would throw the error: - // TypeError: Failed to execute 'fetch' on 'Window': Illegal invocation - const _fetch = opts.fetch! - let response = await _fetch(request) - - for (const fn of interceptors.response.fns) { - if (fn) { - response = await fn(response, request, opts) - } - } - - const result = { - request, - response - } - - if (response.ok) { - const parseAs = - (opts.parseAs === 'auto' - ? getParseAs(response.headers.get('Content-Type')) - : opts.parseAs) ?? 'json' - - if (response.status === 204 || response.headers.get('Content-Length') === '0') { - let emptyData: any - switch (parseAs) { - case 'arrayBuffer': - case 'blob': - case 'text': - emptyData = await response[parseAs]() - break - case 'formData': - emptyData = new FormData() - break - case 'stream': - emptyData = response.body - break - case 'json': - default: - emptyData = {} - break - } - return opts.responseStyle === 'data' - ? emptyData - : { - data: emptyData, - ...result - } - } - - let data: any - switch (parseAs) { - case 'arrayBuffer': - case 'blob': - case 'formData': - case 'json': - case 'text': - data = await response[parseAs]() - break - case 'stream': - return opts.responseStyle === 'data' - ? response.body - : { - data: response.body, - ...result - } - } - - if (parseAs === 'json') { - if (opts.responseValidator) { - await opts.responseValidator(data) - } - - if (opts.responseTransformer) { - data = await opts.responseTransformer(data) - } - } - - return opts.responseStyle === 'data' - ? data - : { - data, - ...result - } - } - - const textError = await response.text() - let jsonError: unknown - - try { - jsonError = JSON.parse(textError) - } catch { - // noop - } - - const error = jsonError ?? textError - let finalError = error - - for (const fn of interceptors.error.fns) { - if (fn) { - finalError = (await fn(error, response, request, opts)) as string - } - } - - finalError = finalError || ({} as string) - - if (opts.throwOnError) { - throw finalError - } - - // TODO: we probably want to return error and improve types - return opts.responseStyle === 'data' - ? undefined - : { - error: finalError, - ...result - } - } - - const makeMethodFn = (method: Uppercase) => (options: RequestOptions) => - request({ ...options, method }) - - const makeSseFn = (method: Uppercase) => async (options: RequestOptions) => { - const { opts, url } = await beforeRequest(options) - return createSseClient({ - ...opts, - body: opts.body as BodyInit | null | undefined, - headers: opts.headers as unknown as Record, - method, - onRequest: async (url, init) => { - let request = new Request(url, init) - for (const fn of interceptors.request.fns) { - if (fn) { - request = await fn(request, opts) - } - } - return request - }, - url - }) - } - - return { - buildUrl, - connect: makeMethodFn('CONNECT'), - delete: makeMethodFn('DELETE'), - get: makeMethodFn('GET'), - getConfig, - head: makeMethodFn('HEAD'), - interceptors, - options: makeMethodFn('OPTIONS'), - patch: makeMethodFn('PATCH'), - post: makeMethodFn('POST'), - put: makeMethodFn('PUT'), - request, - setConfig, - sse: { - connect: makeSseFn('CONNECT'), - delete: makeSseFn('DELETE'), - get: makeSseFn('GET'), - head: makeSseFn('HEAD'), - options: makeSseFn('OPTIONS'), - patch: makeSseFn('PATCH'), - post: makeSseFn('POST'), - put: makeSseFn('PUT'), - trace: makeSseFn('TRACE') - }, - trace: makeMethodFn('TRACE') - } as Client -} diff --git a/examples/integrations/generated/google/authorization/client/types.gen.ts b/examples/integrations/generated/google/authorization/client/types.gen.ts deleted file mode 100644 index b97f75e..0000000 --- a/examples/integrations/generated/google/authorization/client/types.gen.ts +++ /dev/null @@ -1,226 +0,0 @@ -// This file is auto-generated by @hey-api/openapi-ts - -import type { Auth } from '../core/auth.gen' -import type { ServerSentEventsOptions, ServerSentEventsResult } from '../core/serverSentEvents.gen' -import type { Client as CoreClient, Config as CoreConfig } from '../core/types.gen' -import type { Middleware } from './utils.gen' - -export type ResponseStyle = 'data' | 'fields' - -export interface Config - extends Omit, - CoreConfig { - /** - * Base URL for all requests made by this client. - */ - baseUrl?: T['baseUrl'] - /** - * Fetch API implementation. You can use this option to provide a custom - * fetch instance. - * - * @default globalThis.fetch - */ - fetch?: typeof fetch - /** - * Please don't use the Fetch client for Next.js applications. The `next` - * options won't have any effect. - * - * Install {@link https://www.npmjs.com/package/@hey-api/client-next `@hey-api/client-next`} instead. - */ - next?: never - /** - * Return the response data parsed in a specified format. By default, `auto` - * will infer the appropriate method from the `Content-Type` response header. - * You can override this behavior with any of the {@link Body} methods. - * Select `stream` if you don't want to parse response data at all. - * - * @default 'auto' - */ - parseAs?: 'arrayBuffer' | 'auto' | 'blob' | 'formData' | 'json' | 'stream' | 'text' - /** - * Should we return only data or multiple fields (data, error, response, etc.)? - * - * @default 'fields' - */ - responseStyle?: ResponseStyle - /** - * Throw an error instead of returning it in the response? - * - * @default false - */ - throwOnError?: T['throwOnError'] -} - -export interface RequestOptions< - TData = unknown, - TResponseStyle extends ResponseStyle = 'fields', - ThrowOnError extends boolean = boolean, - Url extends string = string -> extends Config<{ - responseStyle: TResponseStyle - throwOnError: ThrowOnError - }>, - Pick< - ServerSentEventsOptions, - | 'onSseError' - | 'onSseEvent' - | 'sseDefaultRetryDelay' - | 'sseMaxRetryAttempts' - | 'sseMaxRetryDelay' - > { - /** - * Any body that you want to add to your request. - * - * {@link https://developer.mozilla.org/docs/Web/API/fetch#body} - */ - body?: unknown - path?: Record - query?: Record - /** - * Security mechanism(s) to use for the request. - */ - security?: ReadonlyArray - url: Url -} - -export interface ResolvedRequestOptions< - TResponseStyle extends ResponseStyle = 'fields', - ThrowOnError extends boolean = boolean, - Url extends string = string -> extends RequestOptions { - serializedBody?: string -} - -export type RequestResult< - TData = unknown, - TError = unknown, - ThrowOnError extends boolean = boolean, - TResponseStyle extends ResponseStyle = 'fields' -> = ThrowOnError extends true - ? Promise< - TResponseStyle extends 'data' - ? TData extends Record - ? TData[keyof TData] - : TData - : { - data: TData extends Record ? TData[keyof TData] : TData - request: Request - response: Response - } - > - : Promise< - TResponseStyle extends 'data' - ? (TData extends Record ? TData[keyof TData] : TData) | undefined - : ( - | { - data: TData extends Record ? TData[keyof TData] : TData - error: undefined - } - | { - data: undefined - error: TError extends Record ? TError[keyof TError] : TError - } - ) & { - request: Request - response: Response - } - > - -export interface ClientOptions { - baseUrl?: string - responseStyle?: ResponseStyle - throwOnError?: boolean -} - -type MethodFn = < - TData = unknown, - TError = unknown, - ThrowOnError extends boolean = false, - TResponseStyle extends ResponseStyle = 'fields' ->( - options: Omit, 'method'> -) => RequestResult - -type SseFn = < - TData = unknown, - TError = unknown, - ThrowOnError extends boolean = false, - TResponseStyle extends ResponseStyle = 'fields' ->( - options: Omit, 'method'> -) => Promise> - -type RequestFn = < - TData = unknown, - TError = unknown, - ThrowOnError extends boolean = false, - TResponseStyle extends ResponseStyle = 'fields' ->( - options: Omit, 'method'> & - Pick>, 'method'> -) => RequestResult - -type BuildUrlFn = < - TData extends { - body?: unknown - path?: Record - query?: Record - url: string - } ->( - options: Pick & Options -) => string - -export type Client = CoreClient & { - interceptors: Middleware -} - -/** - * The `createClientConfig()` function will be called on client initialization - * and the returned object will become the client's initial configuration. - * - * You may want to initialize your client this way instead of calling - * `setConfig()`. This is useful for example if you're using Next.js - * to ensure your client always has the correct values. - */ -export type CreateClientConfig = ( - override?: Config -) => Config & T> - -export interface TDataShape { - body?: unknown - headers?: unknown - path?: unknown - query?: unknown - url: string -} - -type OmitKeys = Pick> - -export type Options< - TData extends TDataShape = TDataShape, - ThrowOnError extends boolean = boolean, - TResponse = unknown, - TResponseStyle extends ResponseStyle = 'fields' -> = OmitKeys< - RequestOptions, - 'body' | 'path' | 'query' | 'url' -> & - Omit - -export type OptionsLegacyParser< - TData = unknown, - ThrowOnError extends boolean = boolean, - TResponseStyle extends ResponseStyle = 'fields' -> = TData extends { body?: any } - ? TData extends { headers?: any } - ? OmitKeys, 'body' | 'headers' | 'url'> & - TData - : OmitKeys, 'body' | 'url'> & - TData & - Pick, 'headers'> - : TData extends { headers?: any } - ? OmitKeys, 'headers' | 'url'> & - TData & - Pick, 'body'> - : OmitKeys, 'url'> & TData diff --git a/examples/integrations/generated/google/authorization/client/utils.gen.ts b/examples/integrations/generated/google/authorization/client/utils.gen.ts deleted file mode 100644 index b42b5d9..0000000 --- a/examples/integrations/generated/google/authorization/client/utils.gen.ts +++ /dev/null @@ -1,315 +0,0 @@ -// This file is auto-generated by @hey-api/openapi-ts - -import { getAuthToken } from '../core/auth.gen' -import type { QuerySerializerOptions } from '../core/bodySerializer.gen' -import { jsonBodySerializer } from '../core/bodySerializer.gen' -import { - serializeArrayParam, - serializeObjectParam, - serializePrimitiveParam -} from '../core/pathSerializer.gen' -import { getUrl } from '../core/utils.gen' -import type { Client, ClientOptions, Config, RequestOptions } from './types.gen' - -export const createQuerySerializer = ({ - allowReserved, - array, - object -}: QuerySerializerOptions = {}) => { - const querySerializer = (queryParams: T) => { - const search: string[] = [] - if (queryParams && typeof queryParams === 'object') { - for (const name in queryParams) { - const value = queryParams[name] - - if (value === undefined || value === null) { - continue - } - - if (Array.isArray(value)) { - const serializedArray = serializeArrayParam({ - allowReserved, - explode: true, - name, - style: 'form', - value, - ...array - }) - if (serializedArray) search.push(serializedArray) - } else if (typeof value === 'object') { - const serializedObject = serializeObjectParam({ - allowReserved, - explode: true, - name, - style: 'deepObject', - value: value as Record, - ...object - }) - if (serializedObject) search.push(serializedObject) - } else { - const serializedPrimitive = serializePrimitiveParam({ - allowReserved, - name, - value: value as string - }) - if (serializedPrimitive) search.push(serializedPrimitive) - } - } - } - return search.join('&') - } - return querySerializer -} - -/** - * Infers parseAs value from provided Content-Type header. - */ -export const getParseAs = (contentType: string | null): Exclude => { - if (!contentType) { - // If no Content-Type header is provided, the best we can do is return the raw response body, - // which is effectively the same as the 'stream' option. - return 'stream' - } - - const cleanContent = contentType.split(';')[0]?.trim() - - if (!cleanContent) { - return - } - - if (cleanContent.startsWith('application/json') || cleanContent.endsWith('+json')) { - return 'json' - } - - if (cleanContent === 'multipart/form-data') { - return 'formData' - } - - if ( - ['application/', 'audio/', 'image/', 'video/'].some((type) => cleanContent.startsWith(type)) - ) { - return 'blob' - } - - if (cleanContent.startsWith('text/')) { - return 'text' - } - - return -} - -const checkForExistence = ( - options: Pick & { - headers: Headers - }, - name?: string -): boolean => { - if (!name) { - return false - } - if ( - options.headers.has(name) || - options.query?.[name] || - options.headers.get('Cookie')?.includes(`${name}=`) - ) { - return true - } - return false -} - -export const setAuthParams = async ({ - security, - ...options -}: Pick, 'security'> & - Pick & { - headers: Headers - }) => { - for (const auth of security) { - if (checkForExistence(options, auth.name)) { - continue - } - - const token = await getAuthToken(auth, options.auth) - - if (!token) { - continue - } - - const name = auth.name ?? 'Authorization' - - switch (auth.in) { - case 'query': - if (!options.query) { - options.query = {} - } - options.query[name] = token - break - case 'cookie': - options.headers.append('Cookie', `${name}=${token}`) - break - case 'header': - default: - options.headers.set(name, token) - break - } - } -} - -export const buildUrl: Client['buildUrl'] = (options) => - getUrl({ - baseUrl: options.baseUrl as string, - path: options.path, - query: options.query, - querySerializer: - typeof options.querySerializer === 'function' - ? options.querySerializer - : createQuerySerializer(options.querySerializer), - url: options.url - }) - -export const mergeConfigs = (a: Config, b: Config): Config => { - const config = { ...a, ...b } - if (config.baseUrl?.endsWith('/')) { - config.baseUrl = config.baseUrl.substring(0, config.baseUrl.length - 1) - } - config.headers = mergeHeaders(a.headers, b.headers) - return config -} - -const headersEntries = (headers: Headers): Array<[string, string]> => { - const entries: Array<[string, string]> = [] - headers.forEach((value, key) => { - entries.push([key, value]) - }) - return entries -} - -export const mergeHeaders = ( - ...headers: Array['headers'] | undefined> -): Headers => { - const mergedHeaders = new Headers() - for (const header of headers) { - if (!header) { - continue - } - - const iterator = header instanceof Headers ? headersEntries(header) : Object.entries(header) - - for (const [key, value] of iterator) { - if (value === null) { - mergedHeaders.delete(key) - } else if (Array.isArray(value)) { - for (const v of value) { - mergedHeaders.append(key, v as string) - } - } else if (value !== undefined) { - // assume object headers are meant to be JSON stringified, i.e. their - // content value in OpenAPI specification is 'application/json' - mergedHeaders.set( - key, - typeof value === 'object' ? JSON.stringify(value) : (value as string) - ) - } - } - } - return mergedHeaders -} - -type ErrInterceptor = ( - error: Err, - response: Res, - request: Req, - options: Options -) => Err | Promise - -type ReqInterceptor = (request: Req, options: Options) => Req | Promise - -type ResInterceptor = ( - response: Res, - request: Req, - options: Options -) => Res | Promise - -class Interceptors { - fns: Array = [] - - clear(): void { - this.fns = [] - } - - eject(id: number | Interceptor): void { - const index = this.getInterceptorIndex(id) - if (this.fns[index]) { - this.fns[index] = null - } - } - - exists(id: number | Interceptor): boolean { - const index = this.getInterceptorIndex(id) - return Boolean(this.fns[index]) - } - - getInterceptorIndex(id: number | Interceptor): number { - if (typeof id === 'number') { - return this.fns[id] ? id : -1 - } - return this.fns.indexOf(id) - } - - update(id: number | Interceptor, fn: Interceptor): number | Interceptor | false { - const index = this.getInterceptorIndex(id) - if (this.fns[index]) { - this.fns[index] = fn - return id - } - return false - } - - use(fn: Interceptor): number { - this.fns.push(fn) - return this.fns.length - 1 - } -} - -export interface Middleware { - error: Interceptors> - request: Interceptors> - response: Interceptors> -} - -export const createInterceptors = (): Middleware< - Req, - Res, - Err, - Options -> => ({ - error: new Interceptors>(), - request: new Interceptors>(), - response: new Interceptors>() -}) - -const defaultQuerySerializer = createQuerySerializer({ - allowReserved: false, - array: { - explode: true, - style: 'form' - }, - object: { - explode: true, - style: 'deepObject' - } -}) - -const defaultHeaders = { - 'Content-Type': 'application/json' -} - -export const createConfig = ( - override: Config & T> = {} -): Config & T> => ({ - ...jsonBodySerializer, - headers: defaultHeaders, - parseAs: 'auto', - querySerializer: defaultQuerySerializer, - ...override -}) diff --git a/examples/integrations/generated/google/authorization/core/auth.gen.ts b/examples/integrations/generated/google/authorization/core/auth.gen.ts deleted file mode 100644 index dc8ff61..0000000 --- a/examples/integrations/generated/google/authorization/core/auth.gen.ts +++ /dev/null @@ -1,41 +0,0 @@ -// This file is auto-generated by @hey-api/openapi-ts - -export type AuthToken = string | undefined - -export interface Auth { - /** - * Which part of the request do we use to send the auth? - * - * @default 'header' - */ - in?: 'header' | 'query' | 'cookie' - /** - * Header or query parameter name. - * - * @default 'Authorization' - */ - name?: string - scheme?: 'basic' | 'bearer' - type: 'apiKey' | 'http' -} - -export const getAuthToken = async ( - auth: Auth, - callback: ((auth: Auth) => Promise | AuthToken) | AuthToken -): Promise => { - const token = typeof callback === 'function' ? await callback(auth) : callback - - if (!token) { - return - } - - if (auth.scheme === 'bearer') { - return `Bearer ${token}` - } - - if (auth.scheme === 'basic') { - return `Basic ${btoa(token)}` - } - - return token -} diff --git a/examples/integrations/generated/google/authorization/core/bodySerializer.gen.ts b/examples/integrations/generated/google/authorization/core/bodySerializer.gen.ts deleted file mode 100644 index e39c6a5..0000000 --- a/examples/integrations/generated/google/authorization/core/bodySerializer.gen.ts +++ /dev/null @@ -1,76 +0,0 @@ -// This file is auto-generated by @hey-api/openapi-ts - -import type { ArrayStyle, ObjectStyle, SerializerOptions } from './pathSerializer.gen' - -export type QuerySerializer = (query: Record) => string - -export type BodySerializer = (body: any) => any - -export interface QuerySerializerOptions { - allowReserved?: boolean - array?: SerializerOptions - object?: SerializerOptions -} - -const serializeFormDataPair = (data: FormData, key: string, value: unknown): void => { - if (typeof value === 'string' || value instanceof Blob) { - data.append(key, value) - } else if (value instanceof Date) { - data.append(key, value.toISOString()) - } else { - data.append(key, JSON.stringify(value)) - } -} - -const serializeUrlSearchParamsPair = (data: URLSearchParams, key: string, value: unknown): void => { - if (typeof value === 'string') { - data.append(key, value) - } else { - data.append(key, JSON.stringify(value)) - } -} - -export const formDataBodySerializer = { - bodySerializer: | Array>>( - body: T - ): FormData => { - const data = new FormData() - - Object.entries(body).forEach(([key, value]) => { - if (value === undefined || value === null) { - return - } - if (Array.isArray(value)) { - value.forEach((v) => serializeFormDataPair(data, key, v)) - } else { - serializeFormDataPair(data, key, value) - } - }) - - return data - } -} - -export const jsonBodySerializer = { - bodySerializer: (body: T): string => - JSON.stringify(body, (_key, value) => (typeof value === 'bigint' ? value.toString() : value)) -} - -export const urlSearchParamsBodySerializer = { - bodySerializer: | Array>>(body: T): string => { - const data = new URLSearchParams() - - Object.entries(body).forEach(([key, value]) => { - if (value === undefined || value === null) { - return - } - if (Array.isArray(value)) { - value.forEach((v) => serializeUrlSearchParamsPair(data, key, v)) - } else { - serializeUrlSearchParamsPair(data, key, value) - } - }) - - return data.toString() - } -} diff --git a/examples/integrations/generated/google/authorization/core/params.gen.ts b/examples/integrations/generated/google/authorization/core/params.gen.ts deleted file mode 100644 index 34dddb5..0000000 --- a/examples/integrations/generated/google/authorization/core/params.gen.ts +++ /dev/null @@ -1,144 +0,0 @@ -// This file is auto-generated by @hey-api/openapi-ts - -type Slot = 'body' | 'headers' | 'path' | 'query' - -export type Field = - | { - in: Exclude - /** - * Field name. This is the name we want the user to see and use. - */ - key: string - /** - * Field mapped name. This is the name we want to use in the request. - * If omitted, we use the same value as `key`. - */ - map?: string - } - | { - in: Extract - /** - * Key isn't required for bodies. - */ - key?: string - map?: string - } - -export interface Fields { - allowExtra?: Partial> - args?: ReadonlyArray -} - -export type FieldsConfig = ReadonlyArray - -const extraPrefixesMap: Record = { - $body_: 'body', - $headers_: 'headers', - $path_: 'path', - $query_: 'query' -} -const extraPrefixes = Object.entries(extraPrefixesMap) - -type KeyMap = Map< - string, - { - in: Slot - map?: string - } -> - -const buildKeyMap = (fields: FieldsConfig, map?: KeyMap): KeyMap => { - if (!map) { - map = new Map() - } - - for (const config of fields) { - if ('in' in config) { - if (config.key) { - map.set(config.key, { - in: config.in, - map: config.map - }) - } - } else if (config.args) { - buildKeyMap(config.args, map) - } - } - - return map -} - -interface Params { - body: unknown - headers: Record - path: Record - query: Record -} - -const stripEmptySlots = (params: Params) => { - for (const [slot, value] of Object.entries(params)) { - if (value && typeof value === 'object' && !Object.keys(value).length) { - delete params[slot as Slot] - } - } -} - -export const buildClientParams = (args: ReadonlyArray, fields: FieldsConfig) => { - const params: Params = { - body: {}, - headers: {}, - path: {}, - query: {} - } - - const map = buildKeyMap(fields) - - let config: FieldsConfig[number] | undefined - - for (const [index, arg] of args.entries()) { - if (fields[index]) { - config = fields[index] - } - - if (!config) { - continue - } - - if ('in' in config) { - if (config.key) { - const field = map.get(config.key)! - const name = field.map || config.key - ;(params[field.in] as Record)[name] = arg - } else { - params.body = arg - } - } else { - for (const [key, value] of Object.entries(arg ?? {})) { - const field = map.get(key) - - if (field) { - const name = field.map || key - ;(params[field.in] as Record)[name] = value - } else { - const extra = extraPrefixes.find(([prefix]) => key.startsWith(prefix)) - - if (extra) { - const [prefix, slot] = extra - ;(params[slot] as Record)[key.slice(prefix.length)] = value - } else { - for (const [slot, allowed] of Object.entries(config.allowExtra ?? {})) { - if (allowed) { - ;(params[slot as Slot] as Record)[key] = value - break - } - } - } - } - } - } - } - - stripEmptySlots(params) - - return params -} diff --git a/examples/integrations/generated/google/authorization/core/pathSerializer.gen.ts b/examples/integrations/generated/google/authorization/core/pathSerializer.gen.ts deleted file mode 100644 index acc1367..0000000 --- a/examples/integrations/generated/google/authorization/core/pathSerializer.gen.ts +++ /dev/null @@ -1,171 +0,0 @@ -// This file is auto-generated by @hey-api/openapi-ts - -interface SerializeOptions extends SerializePrimitiveOptions, SerializerOptions {} - -interface SerializePrimitiveOptions { - allowReserved?: boolean - name: string -} - -export interface SerializerOptions { - /** - * @default true - */ - explode: boolean - style: T -} - -export type ArrayStyle = 'form' | 'spaceDelimited' | 'pipeDelimited' -export type ArraySeparatorStyle = ArrayStyle | MatrixStyle -type MatrixStyle = 'label' | 'matrix' | 'simple' -export type ObjectStyle = 'form' | 'deepObject' -type ObjectSeparatorStyle = ObjectStyle | MatrixStyle - -interface SerializePrimitiveParam extends SerializePrimitiveOptions { - value: string -} - -export const separatorArrayExplode = (style: ArraySeparatorStyle) => { - switch (style) { - case 'label': - return '.' - case 'matrix': - return ';' - case 'simple': - return ',' - default: - return '&' - } -} - -export const separatorArrayNoExplode = (style: ArraySeparatorStyle) => { - switch (style) { - case 'form': - return ',' - case 'pipeDelimited': - return '|' - case 'spaceDelimited': - return '%20' - default: - return ',' - } -} - -export const separatorObjectExplode = (style: ObjectSeparatorStyle) => { - switch (style) { - case 'label': - return '.' - case 'matrix': - return ';' - case 'simple': - return ',' - default: - return '&' - } -} - -export const serializeArrayParam = ({ - allowReserved, - explode, - name, - style, - value -}: SerializeOptions & { - value: unknown[] -}) => { - if (!explode) { - const joinedValues = ( - allowReserved ? value : value.map((v) => encodeURIComponent(v as string)) - ).join(separatorArrayNoExplode(style)) - switch (style) { - case 'label': - return `.${joinedValues}` - case 'matrix': - return `;${name}=${joinedValues}` - case 'simple': - return joinedValues - default: - return `${name}=${joinedValues}` - } - } - - const separator = separatorArrayExplode(style) - const joinedValues = value - .map((v) => { - if (style === 'label' || style === 'simple') { - return allowReserved ? v : encodeURIComponent(v as string) - } - - return serializePrimitiveParam({ - allowReserved, - name, - value: v as string - }) - }) - .join(separator) - return style === 'label' || style === 'matrix' ? separator + joinedValues : joinedValues -} - -export const serializePrimitiveParam = ({ - allowReserved, - name, - value -}: SerializePrimitiveParam) => { - if (value === undefined || value === null) { - return '' - } - - if (typeof value === 'object') { - throw new Error( - 'Deeply-nested arrays/objects aren’t supported. Provide your own `querySerializer()` to handle these.' - ) - } - - return `${name}=${allowReserved ? value : encodeURIComponent(value)}` -} - -export const serializeObjectParam = ({ - allowReserved, - explode, - name, - style, - value, - valueOnly -}: SerializeOptions & { - value: Record | Date - valueOnly?: boolean -}) => { - if (value instanceof Date) { - return valueOnly ? value.toISOString() : `${name}=${value.toISOString()}` - } - - if (style !== 'deepObject' && !explode) { - let values: string[] = [] - Object.entries(value).forEach(([key, v]) => { - values = [...values, key, allowReserved ? (v as string) : encodeURIComponent(v as string)] - }) - const joinedValues = values.join(',') - switch (style) { - case 'form': - return `${name}=${joinedValues}` - case 'label': - return `.${joinedValues}` - case 'matrix': - return `;${name}=${joinedValues}` - default: - return joinedValues - } - } - - const separator = separatorObjectExplode(style) - const joinedValues = Object.entries(value) - .map(([key, v]) => - serializePrimitiveParam({ - allowReserved, - name: style === 'deepObject' ? `${name}[${key}]` : key, - value: v as string - }) - ) - .join(separator) - return style === 'label' || style === 'matrix' ? separator + joinedValues : joinedValues -} diff --git a/examples/integrations/generated/google/authorization/core/serverSentEvents.gen.ts b/examples/integrations/generated/google/authorization/core/serverSentEvents.gen.ts deleted file mode 100644 index 372e50c..0000000 --- a/examples/integrations/generated/google/authorization/core/serverSentEvents.gen.ts +++ /dev/null @@ -1,241 +0,0 @@ -// This file is auto-generated by @hey-api/openapi-ts - -import type { Config } from './types.gen' - -export type ServerSentEventsOptions = Omit & - Pick & { - /** - * Fetch API implementation. You can use this option to provide a custom - * fetch instance. - * - * @default globalThis.fetch - */ - fetch?: typeof fetch - /** - * Implementing clients can call request interceptors inside this hook. - */ - onRequest?: (url: string, init: RequestInit) => Promise - /** - * Callback invoked when a network or parsing error occurs during streaming. - * - * This option applies only if the endpoint returns a stream of events. - * - * @param error The error that occurred. - */ - onSseError?: (error: unknown) => void - /** - * Callback invoked when an event is streamed from the server. - * - * This option applies only if the endpoint returns a stream of events. - * - * @param event Event streamed from the server. - * @returns Nothing (void). - */ - onSseEvent?: (event: StreamEvent) => void - serializedBody?: RequestInit['body'] - /** - * Default retry delay in milliseconds. - * - * This option applies only if the endpoint returns a stream of events. - * - * @default 3000 - */ - sseDefaultRetryDelay?: number - /** - * Maximum number of retry attempts before giving up. - */ - sseMaxRetryAttempts?: number - /** - * Maximum retry delay in milliseconds. - * - * Applies only when exponential backoff is used. - * - * This option applies only if the endpoint returns a stream of events. - * - * @default 30000 - */ - sseMaxRetryDelay?: number - /** - * Optional sleep function for retry backoff. - * - * Defaults to using `setTimeout`. - */ - sseSleepFn?: (ms: number) => Promise - url: string - } - -export interface StreamEvent { - data: TData - event?: string - id?: string - retry?: number -} - -export type ServerSentEventsResult = { - stream: AsyncGenerator< - TData extends Record ? TData[keyof TData] : TData, - TReturn, - TNext - > -} - -export const createSseClient = ({ - onRequest, - onSseError, - onSseEvent, - responseTransformer, - responseValidator, - sseDefaultRetryDelay, - sseMaxRetryAttempts, - sseMaxRetryDelay, - sseSleepFn, - url, - ...options -}: ServerSentEventsOptions): ServerSentEventsResult => { - let lastEventId: string | undefined - - const sleep = sseSleepFn ?? ((ms: number) => new Promise((resolve) => setTimeout(resolve, ms))) - - const createStream = async function* () { - let retryDelay: number = sseDefaultRetryDelay ?? 3000 - let attempt = 0 - const signal = options.signal ?? new AbortController().signal - - while (true) { - if (signal.aborted) break - - attempt++ - - const headers = - options.headers instanceof Headers - ? options.headers - : new Headers(options.headers as Record | undefined) - - if (lastEventId !== undefined) { - headers.set('Last-Event-ID', lastEventId) - } - - try { - const requestInit: RequestInit = { - redirect: 'follow', - ...options, - body: options.serializedBody, - headers, - signal - } - let request = new Request(url, requestInit) - if (onRequest) { - request = await onRequest(url, requestInit) - } - // fetch must be assigned here, otherwise it would throw the error: - // TypeError: Failed to execute 'fetch' on 'Window': Illegal invocation - const _fetch = options.fetch ?? globalThis.fetch - const response = await _fetch(request) - - if (!response.ok) throw new Error(`SSE failed: ${response.status} ${response.statusText}`) - - if (!response.body) throw new Error('No body in SSE response') - - const reader = response.body.pipeThrough(new TextDecoderStream()).getReader() - - let buffer = '' - - const abortHandler = () => { - try { - reader.cancel() - } catch { - // noop - } - } - - signal.addEventListener('abort', abortHandler) - - try { - while (true) { - const { done, value } = await reader.read() - if (done) break - buffer += value - - const chunks = buffer.split('\n\n') - buffer = chunks.pop() ?? '' - - for (const chunk of chunks) { - const lines = chunk.split('\n') - const dataLines: Array = [] - let eventName: string | undefined - - for (const line of lines) { - if (line.startsWith('data:')) { - dataLines.push(line.replace(/^data:\s*/, '')) - } else if (line.startsWith('event:')) { - eventName = line.replace(/^event:\s*/, '') - } else if (line.startsWith('id:')) { - lastEventId = line.replace(/^id:\s*/, '') - } else if (line.startsWith('retry:')) { - const parsed = Number.parseInt(line.replace(/^retry:\s*/, ''), 10) - if (!Number.isNaN(parsed)) { - retryDelay = parsed - } - } - } - - let data: unknown - let parsedJson = false - - if (dataLines.length) { - const rawData = dataLines.join('\n') - try { - data = JSON.parse(rawData) - parsedJson = true - } catch { - data = rawData - } - } - - if (parsedJson) { - if (responseValidator) { - await responseValidator(data) - } - - if (responseTransformer) { - data = await responseTransformer(data) - } - } - - onSseEvent?.({ - data, - event: eventName, - id: lastEventId, - retry: retryDelay - }) - - if (dataLines.length) { - yield data as any - } - } - } - } finally { - signal.removeEventListener('abort', abortHandler) - reader.releaseLock() - } - - break // exit loop on normal completion - } catch (error) { - // connection failed or aborted; retry after delay - onSseError?.(error) - - if (sseMaxRetryAttempts !== undefined && attempt >= sseMaxRetryAttempts) { - break // stop after firing error - } - - // exponential backoff: double retry each attempt, cap at 30s - const backoff = Math.min(retryDelay * 2 ** (attempt - 1), sseMaxRetryDelay ?? 30000) - await sleep(backoff) - } - } - } - - const stream = createStream() - - return { stream } -} diff --git a/examples/integrations/generated/google/authorization/core/types.gen.ts b/examples/integrations/generated/google/authorization/core/types.gen.ts deleted file mode 100644 index 647ffcc..0000000 --- a/examples/integrations/generated/google/authorization/core/types.gen.ts +++ /dev/null @@ -1,104 +0,0 @@ -// This file is auto-generated by @hey-api/openapi-ts - -import type { Auth, AuthToken } from './auth.gen' -import type { BodySerializer, QuerySerializer, QuerySerializerOptions } from './bodySerializer.gen' - -export type HttpMethod = - | 'connect' - | 'delete' - | 'get' - | 'head' - | 'options' - | 'patch' - | 'post' - | 'put' - | 'trace' - -export type Client< - RequestFn = never, - Config = unknown, - MethodFn = never, - BuildUrlFn = never, - SseFn = never -> = { - /** - * Returns the final request URL. - */ - buildUrl: BuildUrlFn - getConfig: () => Config - request: RequestFn - setConfig: (config: Config) => Config -} & { - [K in HttpMethod]: MethodFn -} & ([SseFn] extends [never] ? { sse?: never } : { sse: { [K in HttpMethod]: SseFn } }) - -export interface Config { - /** - * Auth token or a function returning auth token. The resolved value will be - * added to the request payload as defined by its `security` array. - */ - auth?: ((auth: Auth) => Promise | AuthToken) | AuthToken - /** - * A function for serializing request body parameter. By default, - * {@link JSON.stringify()} will be used. - */ - bodySerializer?: BodySerializer | null - /** - * An object containing any HTTP headers that you want to pre-populate your - * `Headers` object with. - * - * {@link https://developer.mozilla.org/docs/Web/API/Headers/Headers#init See more} - */ - headers?: - | RequestInit['headers'] - | Record< - string, - string | number | boolean | (string | number | boolean)[] | null | undefined | unknown - > - /** - * The request method. - * - * {@link https://developer.mozilla.org/docs/Web/API/fetch#method See more} - */ - method?: Uppercase - /** - * A function for serializing request query parameters. By default, arrays - * will be exploded in form style, objects will be exploded in deepObject - * style, and reserved characters are percent-encoded. - * - * This method will have no effect if the native `paramsSerializer()` Axios - * API function is used. - * - * {@link https://swagger.io/docs/specification/serialization/#query View examples} - */ - querySerializer?: QuerySerializer | QuerySerializerOptions - /** - * A function validating request data. This is useful if you want to ensure - * the request conforms to the desired shape, so it can be safely sent to - * the server. - */ - requestValidator?: (data: unknown) => Promise - /** - * A function transforming response data before it's returned. This is useful - * for post-processing data, e.g. converting ISO strings into Date objects. - */ - responseTransformer?: (data: unknown) => Promise - /** - * A function validating response data. This is useful if you want to ensure - * the response conforms to the desired shape, so it can be safely passed to - * the transformers and returned to the user. - */ - responseValidator?: (data: unknown) => Promise -} - -type IsExactlyNeverOrNeverUndefined = [T] extends [never] - ? true - : [T] extends [never | undefined] - ? [undefined] extends [T] - ? false - : true - : false - -export type OmitNever> = { - [K in keyof T as IsExactlyNeverOrNeverUndefined extends true ? never : K]: T[K] -} diff --git a/examples/integrations/generated/google/authorization/core/utils.gen.ts b/examples/integrations/generated/google/authorization/core/utils.gen.ts deleted file mode 100644 index bd078be..0000000 --- a/examples/integrations/generated/google/authorization/core/utils.gen.ts +++ /dev/null @@ -1,140 +0,0 @@ -// This file is auto-generated by @hey-api/openapi-ts - -import type { BodySerializer, QuerySerializer } from './bodySerializer.gen' -import { - type ArraySeparatorStyle, - serializeArrayParam, - serializeObjectParam, - serializePrimitiveParam -} from './pathSerializer.gen' - -export interface PathSerializer { - path: Record - url: string -} - -export const PATH_PARAM_RE = /\{[^{}]+\}/g - -export const defaultPathSerializer = ({ path, url: _url }: PathSerializer) => { - let url = _url - const matches = _url.match(PATH_PARAM_RE) - if (matches) { - for (const match of matches) { - let explode = false - let name = match.substring(1, match.length - 1) - let style: ArraySeparatorStyle = 'simple' - - if (name.endsWith('*')) { - explode = true - name = name.substring(0, name.length - 1) - } - - if (name.startsWith('.')) { - name = name.substring(1) - style = 'label' - } else if (name.startsWith(';')) { - name = name.substring(1) - style = 'matrix' - } - - const value = path[name] - - if (value === undefined || value === null) { - continue - } - - if (Array.isArray(value)) { - url = url.replace(match, serializeArrayParam({ explode, name, style, value })) - continue - } - - if (typeof value === 'object') { - url = url.replace( - match, - serializeObjectParam({ - explode, - name, - style, - value: value as Record, - valueOnly: true - }) - ) - continue - } - - if (style === 'matrix') { - url = url.replace( - match, - `;${serializePrimitiveParam({ - name, - value: value as string - })}` - ) - continue - } - - const replaceValue = encodeURIComponent( - style === 'label' ? `.${value as string}` : (value as string) - ) - url = url.replace(match, replaceValue) - } - } - return url -} - -export const getUrl = ({ - baseUrl, - path, - query, - querySerializer, - url: _url -}: { - baseUrl?: string - path?: Record - query?: Record - querySerializer: QuerySerializer - url: string -}) => { - const pathUrl = _url.startsWith('/') ? _url : `/${_url}` - let url = (baseUrl ?? '') + pathUrl - if (path) { - url = defaultPathSerializer({ path, url }) - } - let search = query ? querySerializer(query) : '' - if (search.startsWith('?')) { - search = search.substring(1) - } - if (search) { - url += `?${search}` - } - return url -} - -export function getValidRequestBody(options: { - body?: unknown - bodySerializer?: BodySerializer | null - serializedBody?: unknown -}) { - const hasBody = options.body !== undefined - const isSerializedBody = hasBody && options.bodySerializer - - if (isSerializedBody) { - if ('serializedBody' in options) { - const hasSerializedBody = - options.serializedBody !== undefined && options.serializedBody !== '' - - return hasSerializedBody ? options.serializedBody : null - } - - // not all clients implement a serializedBody property (i.e. client-axios) - return options.body !== '' ? options.body : null - } - - // plain/text body - if (hasBody) { - return options.body - } - - // no body was provided - return undefined -} diff --git a/examples/integrations/generated/google/authorization/schemas.gen.ts b/examples/integrations/generated/google/authorization/schemas.gen.ts deleted file mode 100644 index 22156b5..0000000 --- a/examples/integrations/generated/google/authorization/schemas.gen.ts +++ /dev/null @@ -1,117 +0,0 @@ -// This file is auto-generated by @hey-api/openapi-ts - -export const TokenResponseSchema = { - type: 'object', - properties: { - access_token: { - type: 'string', - description: 'The access token issued by the authorization server' - }, - token_type: { - type: 'string', - description: 'The type of the token issued' - }, - expires_in: { - type: 'integer', - description: 'The lifetime in seconds of the access token' - }, - refresh_token: { - type: 'string', - description: 'The refresh token issued by the authorization server' - }, - scope: { - type: 'string', - description: 'The scope of the access token' - } - }, - required: ['access_token', 'token_type', 'expires_in'] -} as const - -export const TokeninfoSchema = { - properties: { - audience: { - description: 'Who is the intended audience for this token. In general the same as issued_to.', - type: 'string' - }, - email: { - description: - 'The email address of the user. Present only if the email scope is present in the request.', - type: 'string' - }, - expires_in: { - description: 'The expiry time of the token, as number of seconds left until expiry.', - format: 'int32', - type: 'integer' - }, - issued_to: { - description: 'To whom was the token issued to. In general the same as audience.', - type: 'string' - }, - scope: { - description: 'The space separated list of scopes granted to this token.', - type: 'string' - }, - user_id: { - description: 'The obfuscated user id.', - type: 'string' - }, - verified_email: { - description: - 'Boolean flag which is true if the email address is verified. Present only if the email scope is present in the request.', - type: 'boolean' - } - }, - type: 'object' -} as const - -export const UserinfoSchema = { - properties: { - email: { - description: "The user's email address.", - type: 'string' - }, - family_name: { - description: "The user's last name.", - type: 'string' - }, - gender: { - description: "The user's gender.", - type: 'string' - }, - given_name: { - description: "The user's first name.", - type: 'string' - }, - hd: { - description: 'The hosted domain e.g. example.com if the user is Google apps user.', - type: 'string' - }, - id: { - description: 'The obfuscated ID of the user.', - type: 'string' - }, - link: { - description: 'URL of the profile page.', - type: 'string' - }, - locale: { - description: "The user's preferred locale.", - type: 'string' - }, - name: { - description: "The user's full name.", - type: 'string' - }, - picture: { - description: "URL of the user's picture image.", - type: 'string' - }, - verified_email: { - default: true, - description: - "Boolean flag which is true if the email address is verified. Always verified because we only return the user's primary email address.", - type: 'boolean' - } - }, - type: 'object' -} as const diff --git a/examples/integrations/generated/google/authorization/sdk.gen.ts b/examples/integrations/generated/google/authorization/sdk.gen.ts deleted file mode 100644 index f786743..0000000 --- a/examples/integrations/generated/google/authorization/sdk.gen.ts +++ /dev/null @@ -1,98 +0,0 @@ -// This file is auto-generated by @hey-api/openapi-ts - -import { - type Options as ClientOptions, - type Client, - type TDataShape, - urlSearchParamsBodySerializer -} from './client' -import type { - Oauth2TokenData, - Oauth2TokenResponses, - Oauth2TokenErrors, - Oauth2TokeninfoData, - Oauth2TokeninfoResponses, - Oauth2UserinfoGetData, - Oauth2UserinfoGetResponses, - Oauth2UserinfoV2MeGetData, - Oauth2UserinfoV2MeGetResponses -} from './types.gen' -import { client } from './client.gen' - -export type Options< - TData extends TDataShape = TDataShape, - ThrowOnError extends boolean = boolean -> = ClientOptions & { - /** - * You can provide a client instance returned by `createClient()` instead of - * individual options. This might be also useful if you want to implement a - * custom client. - */ - client?: Client - /** - * You can pass arbitrary values through the `meta` object. This can be - * used to access values that aren't defined as part of the SDK function. - */ - meta?: Record -} - -export const oauth2Token = ( - options?: Options -) => { - return (options?.client ?? client).post({ - ...urlSearchParamsBodySerializer, - url: '/oauth2/v4/token', - ...options, - headers: { - 'Content-Type': 'application/x-www-form-urlencoded', - ...options?.headers - } - }) -} - -export const oauth2Tokeninfo = ( - options?: Options -) => { - return (options?.client ?? client).post({ - url: '/oauth2/v2/tokeninfo', - ...options - }) -} - -export const oauth2UserinfoGet = ( - options?: Options -) => { - return (options?.client ?? client).get({ - security: [ - { - scheme: 'bearer', - type: 'http' - }, - { - scheme: 'bearer', - type: 'http' - } - ], - url: '/oauth2/v2/userinfo', - ...options - }) -} - -export const oauth2UserinfoV2MeGet = ( - options?: Options -) => { - return (options?.client ?? client).get({ - security: [ - { - scheme: 'bearer', - type: 'http' - }, - { - scheme: 'bearer', - type: 'http' - } - ], - url: '/userinfo/v2/me', - ...options - }) -} diff --git a/examples/integrations/generated/google/authorization/types.gen.ts b/examples/integrations/generated/google/authorization/types.gen.ts deleted file mode 100644 index b8f6c4c..0000000 --- a/examples/integrations/generated/google/authorization/types.gen.ts +++ /dev/null @@ -1,334 +0,0 @@ -// This file is auto-generated by @hey-api/openapi-ts - -export type TokenResponse = { - /** - * The access token issued by the authorization server - */ - access_token: string - /** - * The type of the token issued - */ - token_type: string - /** - * The lifetime in seconds of the access token - */ - expires_in: number - /** - * The refresh token issued by the authorization server - */ - refresh_token?: string - /** - * The scope of the access token - */ - scope?: string -} - -export type Tokeninfo = { - /** - * Who is the intended audience for this token. In general the same as issued_to. - */ - audience?: string - /** - * The email address of the user. Present only if the email scope is present in the request. - */ - email?: string - /** - * The expiry time of the token, as number of seconds left until expiry. - */ - expires_in?: number - /** - * To whom was the token issued to. In general the same as audience. - */ - issued_to?: string - /** - * The space separated list of scopes granted to this token. - */ - scope?: string - /** - * The obfuscated user id. - */ - user_id?: string - /** - * Boolean flag which is true if the email address is verified. Present only if the email scope is present in the request. - */ - verified_email?: boolean -} - -export type Userinfo = { - /** - * The user's email address. - */ - email?: string - /** - * The user's last name. - */ - family_name?: string - /** - * The user's gender. - */ - gender?: string - /** - * The user's first name. - */ - given_name?: string - /** - * The hosted domain e.g. example.com if the user is Google apps user. - */ - hd?: string - /** - * The obfuscated ID of the user. - */ - id?: string - /** - * URL of the profile page. - */ - link?: string - /** - * The user's preferred locale. - */ - locale?: string - /** - * The user's full name. - */ - name?: string - /** - * URL of the user's picture image. - */ - picture?: string - /** - * Boolean flag which is true if the email address is verified. Always verified because we only return the user's primary email address. - */ - verified_email?: boolean -} - -/** - * Data format for the response. - */ -export const Alt = { - JSON: 'json' -} as const - -/** - * Data format for the response. - */ -export type Alt = (typeof Alt)[keyof typeof Alt] - -/** - * Selector specifying which fields to include in a partial response. - */ -export type Fields = string - -/** - * API key. Your API key identifies your project and provides you with API access, quota, and reports. Required unless you provide an OAuth 2.0 token. - */ -export type Key = string - -/** - * OAuth 2.0 token for the current user. - */ -export type OauthToken = string - -/** - * Returns response with indentations and line breaks. - */ -export type PrettyPrint = boolean - -/** - * An opaque string that represents a user for quota purposes. Must not exceed 40 characters. - */ -export type QuotaUser = string - -/** - * Deprecated. Please use quotaUser instead. - */ -export type UserIp = string - -export type Oauth2TokenData = { - body?: { - /** - * Authorization code obtained from the authorization server - */ - code?: string - /** - * The client ID obtained from the Google API Console - */ - client_id: string - /** - * The client secret obtained from the Google API Console - */ - client_secret: string - /** - * The URI to redirect to after authorization - */ - redirect_uri?: string - /** - * The grant type for the request - */ - grant_type: 'authorization_code' | 'refresh_token' - /** - * The refresh token obtained from the authorization server - */ - refresh_token?: string - } - path?: never - query?: never - url: '/oauth2/v4/token' -} - -export type Oauth2TokenErrors = { - /** - * Bad Request - */ - 400: unknown -} - -export type Oauth2TokenResponses = { - /** - * Successful token response - */ - 200: TokenResponse -} - -export type Oauth2TokenResponse = Oauth2TokenResponses[keyof Oauth2TokenResponses] - -export type Oauth2TokeninfoData = { - body?: never - path?: never - query?: { - /** - * Data format for the response. - */ - alt?: 'json' - /** - * Selector specifying which fields to include in a partial response. - */ - fields?: string - /** - * API key. Your API key identifies your project and provides you with API access, quota, and reports. Required unless you provide an OAuth 2.0 token. - */ - key?: string - /** - * OAuth 2.0 token for the current user. - */ - oauth_token?: string - /** - * Returns response with indentations and line breaks. - */ - prettyPrint?: boolean - /** - * An opaque string that represents a user for quota purposes. Must not exceed 40 characters. - */ - quotaUser?: string - /** - * Deprecated. Please use quotaUser instead. - */ - userIp?: string - access_token?: string - id_token?: string - } - url: '/oauth2/v2/tokeninfo' -} - -export type Oauth2TokeninfoResponses = { - /** - * Successful response - */ - 200: Tokeninfo -} - -export type Oauth2TokeninfoResponse = Oauth2TokeninfoResponses[keyof Oauth2TokeninfoResponses] - -export type Oauth2UserinfoGetData = { - body?: never - path?: never - query?: { - /** - * Data format for the response. - */ - alt?: 'json' - /** - * Selector specifying which fields to include in a partial response. - */ - fields?: string - /** - * API key. Your API key identifies your project and provides you with API access, quota, and reports. Required unless you provide an OAuth 2.0 token. - */ - key?: string - /** - * OAuth 2.0 token for the current user. - */ - oauth_token?: string - /** - * Returns response with indentations and line breaks. - */ - prettyPrint?: boolean - /** - * An opaque string that represents a user for quota purposes. Must not exceed 40 characters. - */ - quotaUser?: string - /** - * Deprecated. Please use quotaUser instead. - */ - userIp?: string - } - url: '/oauth2/v2/userinfo' -} - -export type Oauth2UserinfoGetResponses = { - /** - * Successful response - */ - 200: Userinfo -} - -export type Oauth2UserinfoGetResponse = Oauth2UserinfoGetResponses[keyof Oauth2UserinfoGetResponses] - -export type Oauth2UserinfoV2MeGetData = { - body?: never - path?: never - query?: { - /** - * Data format for the response. - */ - alt?: 'json' - /** - * Selector specifying which fields to include in a partial response. - */ - fields?: string - /** - * API key. Your API key identifies your project and provides you with API access, quota, and reports. Required unless you provide an OAuth 2.0 token. - */ - key?: string - /** - * OAuth 2.0 token for the current user. - */ - oauth_token?: string - /** - * Returns response with indentations and line breaks. - */ - prettyPrint?: boolean - /** - * An opaque string that represents a user for quota purposes. Must not exceed 40 characters. - */ - quotaUser?: string - /** - * Deprecated. Please use quotaUser instead. - */ - userIp?: string - } - url: '/userinfo/v2/me' -} - -export type Oauth2UserinfoV2MeGetResponses = { - /** - * Successful response - */ - 200: Userinfo -} - -export type Oauth2UserinfoV2MeGetResponse = - Oauth2UserinfoV2MeGetResponses[keyof Oauth2UserinfoV2MeGetResponses] - -export type ClientOptions = { - baseUrl: 'https://www.googleapis.com/' | (string & {}) -} diff --git a/examples/integrations/generated/google/authorization/zod.gen.ts b/examples/integrations/generated/google/authorization/zod.gen.ts deleted file mode 100644 index cf9c457..0000000 --- a/examples/integrations/generated/google/authorization/zod.gen.ts +++ /dev/null @@ -1,155 +0,0 @@ -// This file is auto-generated by @hey-api/openapi-ts - -import { z } from 'zod' - -export const zTokenResponse = z.object({ - access_token: z.string(), - token_type: z.string(), - expires_in: z.int(), - refresh_token: z.optional(z.string()), - scope: z.optional(z.string()) -}) - -export const zTokeninfo = z.object({ - audience: z.optional(z.string()), - email: z.optional(z.string()), - expires_in: z.optional(z.int()), - issued_to: z.optional(z.string()), - scope: z.optional(z.string()), - user_id: z.optional(z.string()), - verified_email: z.optional(z.boolean()) -}) - -export const zUserinfo = z.object({ - email: z.optional(z.string()), - family_name: z.optional(z.string()), - gender: z.optional(z.string()), - given_name: z.optional(z.string()), - hd: z.optional(z.string()), - id: z.optional(z.string()), - link: z.optional(z.string()), - locale: z.optional(z.string()), - name: z.optional(z.string()), - picture: z.optional(z.string()), - verified_email: z.optional(z.boolean()).default(true) -}) - -/** - * Data format for the response. - */ -export const zAlt = z.enum(['json']) - -/** - * Selector specifying which fields to include in a partial response. - */ -export const zFields = z.string() - -/** - * API key. Your API key identifies your project and provides you with API access, quota, and reports. Required unless you provide an OAuth 2.0 token. - */ -export const zKey = z.string() - -/** - * OAuth 2.0 token for the current user. - */ -export const zOauthToken = z.string() - -/** - * Returns response with indentations and line breaks. - */ -export const zPrettyPrint = z.boolean() - -/** - * An opaque string that represents a user for quota purposes. Must not exceed 40 characters. - */ -export const zQuotaUser = z.string() - -/** - * Deprecated. Please use quotaUser instead. - */ -export const zUserIp = z.string() - -export const zOauth2TokenData = z.object({ - body: z.optional( - z.object({ - code: z.optional(z.string()), - client_id: z.string(), - client_secret: z.string(), - redirect_uri: z.optional(z.string()), - grant_type: z.enum(['authorization_code', 'refresh_token']), - refresh_token: z.optional(z.string()) - }) - ), - path: z.optional(z.never()), - query: z.optional(z.never()) -}) - -/** - * Successful token response - */ -export const zOauth2TokenResponse = zTokenResponse - -export const zOauth2TokeninfoData = z.object({ - body: z.optional(z.never()), - path: z.optional(z.never()), - query: z.optional( - z.object({ - alt: z.optional(z.enum(['json'])), - fields: z.optional(z.string()), - key: z.optional(z.string()), - oauth_token: z.optional(z.string()), - prettyPrint: z.optional(z.boolean()), - quotaUser: z.optional(z.string()), - userIp: z.optional(z.string()), - access_token: z.optional(z.string()), - id_token: z.optional(z.string()) - }) - ) -}) - -/** - * Successful response - */ -export const zOauth2TokeninfoResponse = zTokeninfo - -export const zOauth2UserinfoGetData = z.object({ - body: z.optional(z.never()), - path: z.optional(z.never()), - query: z.optional( - z.object({ - alt: z.optional(z.enum(['json'])), - fields: z.optional(z.string()), - key: z.optional(z.string()), - oauth_token: z.optional(z.string()), - prettyPrint: z.optional(z.boolean()), - quotaUser: z.optional(z.string()), - userIp: z.optional(z.string()) - }) - ) -}) - -/** - * Successful response - */ -export const zOauth2UserinfoGetResponse = zUserinfo - -export const zOauth2UserinfoV2MeGetData = z.object({ - body: z.optional(z.never()), - path: z.optional(z.never()), - query: z.optional( - z.object({ - alt: z.optional(z.enum(['json'])), - fields: z.optional(z.string()), - key: z.optional(z.string()), - oauth_token: z.optional(z.string()), - prettyPrint: z.optional(z.boolean()), - quotaUser: z.optional(z.string()), - userIp: z.optional(z.string()) - }) - ) -}) - -/** - * Successful response - */ -export const zOauth2UserinfoV2MeGetResponse = zUserinfo diff --git a/examples/integrations/generated/google/drive/client.gen.ts b/examples/integrations/generated/google/drive/client.gen.ts deleted file mode 100644 index 817bc04..0000000 --- a/examples/integrations/generated/google/drive/client.gen.ts +++ /dev/null @@ -1,27 +0,0 @@ -// This file is auto-generated by @hey-api/openapi-ts - -import type { ClientOptions } from './types.gen' -import { - type ClientOptions as DefaultClientOptions, - type Config, - createClient, - createConfig -} from './client' - -/** - * The `createClientConfig()` function will be called on client initialization - * and the returned object will become the client's initial configuration. - * - * You may want to initialize your client this way instead of calling - * `setConfig()`. This is useful for example if you're using Next.js - * to ensure your client always has the correct values. - */ -export type CreateClientConfig = ( - override?: Config -) => Config & T> - -export const client = createClient( - createConfig({ - baseUrl: 'https://www.googleapis.com/drive/v3' - }) -) diff --git a/examples/integrations/generated/google/drive/client/client.gen.ts b/examples/integrations/generated/google/drive/client/client.gen.ts deleted file mode 100644 index 4a4fc46..0000000 --- a/examples/integrations/generated/google/drive/client/client.gen.ts +++ /dev/null @@ -1,253 +0,0 @@ -// This file is auto-generated by @hey-api/openapi-ts - -import { createSseClient } from '../core/serverSentEvents.gen' -import type { HttpMethod } from '../core/types.gen' -import { getValidRequestBody } from '../core/utils.gen' -import type { Client, Config, RequestOptions, ResolvedRequestOptions } from './types.gen' -import { - buildUrl, - createConfig, - createInterceptors, - getParseAs, - mergeConfigs, - mergeHeaders, - setAuthParams -} from './utils.gen' - -type ReqInit = Omit & { - body?: any - headers: ReturnType -} - -export const createClient = (config: Config = {}): Client => { - let _config = mergeConfigs(createConfig(), config) - - const getConfig = (): Config => ({ ..._config }) - - const setConfig = (config: Config): Config => { - _config = mergeConfigs(_config, config) - return getConfig() - } - - const interceptors = createInterceptors() - - const beforeRequest = async (options: RequestOptions) => { - const opts = { - ..._config, - ...options, - fetch: options.fetch ?? _config.fetch ?? globalThis.fetch, - headers: mergeHeaders(_config.headers, options.headers), - serializedBody: undefined - } - - if (opts.security) { - await setAuthParams({ - ...opts, - security: opts.security - }) - } - - if (opts.requestValidator) { - await opts.requestValidator(opts) - } - - if (opts.body !== undefined && opts.bodySerializer) { - opts.serializedBody = opts.bodySerializer(opts.body) - } - - // remove Content-Type header if body is empty to avoid sending invalid requests - if (opts.body === undefined || opts.serializedBody === '') { - opts.headers.delete('Content-Type') - } - - const url = buildUrl(opts) - - return { opts, url } - } - - const request: Client['request'] = async (options) => { - // @ts-expect-error - const { opts, url } = await beforeRequest(options) - const requestInit: ReqInit = { - redirect: 'follow', - ...opts, - body: getValidRequestBody(opts) - } - - let request = new Request(url, requestInit) - - for (const fn of interceptors.request.fns) { - if (fn) { - request = await fn(request, opts) - } - } - - // fetch must be assigned here, otherwise it would throw the error: - // TypeError: Failed to execute 'fetch' on 'Window': Illegal invocation - const _fetch = opts.fetch! - let response = await _fetch(request) - - for (const fn of interceptors.response.fns) { - if (fn) { - response = await fn(response, request, opts) - } - } - - const result = { - request, - response - } - - if (response.ok) { - const parseAs = - (opts.parseAs === 'auto' - ? getParseAs(response.headers.get('Content-Type')) - : opts.parseAs) ?? 'json' - - if (response.status === 204 || response.headers.get('Content-Length') === '0') { - let emptyData: any - switch (parseAs) { - case 'arrayBuffer': - case 'blob': - case 'text': - emptyData = await response[parseAs]() - break - case 'formData': - emptyData = new FormData() - break - case 'stream': - emptyData = response.body - break - case 'json': - default: - emptyData = {} - break - } - return opts.responseStyle === 'data' - ? emptyData - : { - data: emptyData, - ...result - } - } - - let data: any - switch (parseAs) { - case 'arrayBuffer': - case 'blob': - case 'formData': - case 'json': - case 'text': - data = await response[parseAs]() - break - case 'stream': - return opts.responseStyle === 'data' - ? response.body - : { - data: response.body, - ...result - } - } - - if (parseAs === 'json') { - if (opts.responseValidator) { - await opts.responseValidator(data) - } - - if (opts.responseTransformer) { - data = await opts.responseTransformer(data) - } - } - - return opts.responseStyle === 'data' - ? data - : { - data, - ...result - } - } - - const textError = await response.text() - let jsonError: unknown - - try { - jsonError = JSON.parse(textError) - } catch { - // noop - } - - const error = jsonError ?? textError - let finalError = error - - for (const fn of interceptors.error.fns) { - if (fn) { - finalError = (await fn(error, response, request, opts)) as string - } - } - - finalError = finalError || ({} as string) - - if (opts.throwOnError) { - throw finalError - } - - // TODO: we probably want to return error and improve types - return opts.responseStyle === 'data' - ? undefined - : { - error: finalError, - ...result - } - } - - const makeMethodFn = (method: Uppercase) => (options: RequestOptions) => - request({ ...options, method }) - - const makeSseFn = (method: Uppercase) => async (options: RequestOptions) => { - const { opts, url } = await beforeRequest(options) - return createSseClient({ - ...opts, - body: opts.body as BodyInit | null | undefined, - headers: opts.headers as unknown as Record, - method, - onRequest: async (url, init) => { - let request = new Request(url, init) - for (const fn of interceptors.request.fns) { - if (fn) { - request = await fn(request, opts) - } - } - return request - }, - url - }) - } - - return { - buildUrl, - connect: makeMethodFn('CONNECT'), - delete: makeMethodFn('DELETE'), - get: makeMethodFn('GET'), - getConfig, - head: makeMethodFn('HEAD'), - interceptors, - options: makeMethodFn('OPTIONS'), - patch: makeMethodFn('PATCH'), - post: makeMethodFn('POST'), - put: makeMethodFn('PUT'), - request, - setConfig, - sse: { - connect: makeSseFn('CONNECT'), - delete: makeSseFn('DELETE'), - get: makeSseFn('GET'), - head: makeSseFn('HEAD'), - options: makeSseFn('OPTIONS'), - patch: makeSseFn('PATCH'), - post: makeSseFn('POST'), - put: makeSseFn('PUT'), - trace: makeSseFn('TRACE') - }, - trace: makeMethodFn('TRACE') - } as Client -} diff --git a/examples/integrations/generated/google/drive/client/types.gen.ts b/examples/integrations/generated/google/drive/client/types.gen.ts deleted file mode 100644 index b97f75e..0000000 --- a/examples/integrations/generated/google/drive/client/types.gen.ts +++ /dev/null @@ -1,226 +0,0 @@ -// This file is auto-generated by @hey-api/openapi-ts - -import type { Auth } from '../core/auth.gen' -import type { ServerSentEventsOptions, ServerSentEventsResult } from '../core/serverSentEvents.gen' -import type { Client as CoreClient, Config as CoreConfig } from '../core/types.gen' -import type { Middleware } from './utils.gen' - -export type ResponseStyle = 'data' | 'fields' - -export interface Config - extends Omit, - CoreConfig { - /** - * Base URL for all requests made by this client. - */ - baseUrl?: T['baseUrl'] - /** - * Fetch API implementation. You can use this option to provide a custom - * fetch instance. - * - * @default globalThis.fetch - */ - fetch?: typeof fetch - /** - * Please don't use the Fetch client for Next.js applications. The `next` - * options won't have any effect. - * - * Install {@link https://www.npmjs.com/package/@hey-api/client-next `@hey-api/client-next`} instead. - */ - next?: never - /** - * Return the response data parsed in a specified format. By default, `auto` - * will infer the appropriate method from the `Content-Type` response header. - * You can override this behavior with any of the {@link Body} methods. - * Select `stream` if you don't want to parse response data at all. - * - * @default 'auto' - */ - parseAs?: 'arrayBuffer' | 'auto' | 'blob' | 'formData' | 'json' | 'stream' | 'text' - /** - * Should we return only data or multiple fields (data, error, response, etc.)? - * - * @default 'fields' - */ - responseStyle?: ResponseStyle - /** - * Throw an error instead of returning it in the response? - * - * @default false - */ - throwOnError?: T['throwOnError'] -} - -export interface RequestOptions< - TData = unknown, - TResponseStyle extends ResponseStyle = 'fields', - ThrowOnError extends boolean = boolean, - Url extends string = string -> extends Config<{ - responseStyle: TResponseStyle - throwOnError: ThrowOnError - }>, - Pick< - ServerSentEventsOptions, - | 'onSseError' - | 'onSseEvent' - | 'sseDefaultRetryDelay' - | 'sseMaxRetryAttempts' - | 'sseMaxRetryDelay' - > { - /** - * Any body that you want to add to your request. - * - * {@link https://developer.mozilla.org/docs/Web/API/fetch#body} - */ - body?: unknown - path?: Record - query?: Record - /** - * Security mechanism(s) to use for the request. - */ - security?: ReadonlyArray - url: Url -} - -export interface ResolvedRequestOptions< - TResponseStyle extends ResponseStyle = 'fields', - ThrowOnError extends boolean = boolean, - Url extends string = string -> extends RequestOptions { - serializedBody?: string -} - -export type RequestResult< - TData = unknown, - TError = unknown, - ThrowOnError extends boolean = boolean, - TResponseStyle extends ResponseStyle = 'fields' -> = ThrowOnError extends true - ? Promise< - TResponseStyle extends 'data' - ? TData extends Record - ? TData[keyof TData] - : TData - : { - data: TData extends Record ? TData[keyof TData] : TData - request: Request - response: Response - } - > - : Promise< - TResponseStyle extends 'data' - ? (TData extends Record ? TData[keyof TData] : TData) | undefined - : ( - | { - data: TData extends Record ? TData[keyof TData] : TData - error: undefined - } - | { - data: undefined - error: TError extends Record ? TError[keyof TError] : TError - } - ) & { - request: Request - response: Response - } - > - -export interface ClientOptions { - baseUrl?: string - responseStyle?: ResponseStyle - throwOnError?: boolean -} - -type MethodFn = < - TData = unknown, - TError = unknown, - ThrowOnError extends boolean = false, - TResponseStyle extends ResponseStyle = 'fields' ->( - options: Omit, 'method'> -) => RequestResult - -type SseFn = < - TData = unknown, - TError = unknown, - ThrowOnError extends boolean = false, - TResponseStyle extends ResponseStyle = 'fields' ->( - options: Omit, 'method'> -) => Promise> - -type RequestFn = < - TData = unknown, - TError = unknown, - ThrowOnError extends boolean = false, - TResponseStyle extends ResponseStyle = 'fields' ->( - options: Omit, 'method'> & - Pick>, 'method'> -) => RequestResult - -type BuildUrlFn = < - TData extends { - body?: unknown - path?: Record - query?: Record - url: string - } ->( - options: Pick & Options -) => string - -export type Client = CoreClient & { - interceptors: Middleware -} - -/** - * The `createClientConfig()` function will be called on client initialization - * and the returned object will become the client's initial configuration. - * - * You may want to initialize your client this way instead of calling - * `setConfig()`. This is useful for example if you're using Next.js - * to ensure your client always has the correct values. - */ -export type CreateClientConfig = ( - override?: Config -) => Config & T> - -export interface TDataShape { - body?: unknown - headers?: unknown - path?: unknown - query?: unknown - url: string -} - -type OmitKeys = Pick> - -export type Options< - TData extends TDataShape = TDataShape, - ThrowOnError extends boolean = boolean, - TResponse = unknown, - TResponseStyle extends ResponseStyle = 'fields' -> = OmitKeys< - RequestOptions, - 'body' | 'path' | 'query' | 'url' -> & - Omit - -export type OptionsLegacyParser< - TData = unknown, - ThrowOnError extends boolean = boolean, - TResponseStyle extends ResponseStyle = 'fields' -> = TData extends { body?: any } - ? TData extends { headers?: any } - ? OmitKeys, 'body' | 'headers' | 'url'> & - TData - : OmitKeys, 'body' | 'url'> & - TData & - Pick, 'headers'> - : TData extends { headers?: any } - ? OmitKeys, 'headers' | 'url'> & - TData & - Pick, 'body'> - : OmitKeys, 'url'> & TData diff --git a/examples/integrations/generated/google/drive/client/utils.gen.ts b/examples/integrations/generated/google/drive/client/utils.gen.ts deleted file mode 100644 index b42b5d9..0000000 --- a/examples/integrations/generated/google/drive/client/utils.gen.ts +++ /dev/null @@ -1,315 +0,0 @@ -// This file is auto-generated by @hey-api/openapi-ts - -import { getAuthToken } from '../core/auth.gen' -import type { QuerySerializerOptions } from '../core/bodySerializer.gen' -import { jsonBodySerializer } from '../core/bodySerializer.gen' -import { - serializeArrayParam, - serializeObjectParam, - serializePrimitiveParam -} from '../core/pathSerializer.gen' -import { getUrl } from '../core/utils.gen' -import type { Client, ClientOptions, Config, RequestOptions } from './types.gen' - -export const createQuerySerializer = ({ - allowReserved, - array, - object -}: QuerySerializerOptions = {}) => { - const querySerializer = (queryParams: T) => { - const search: string[] = [] - if (queryParams && typeof queryParams === 'object') { - for (const name in queryParams) { - const value = queryParams[name] - - if (value === undefined || value === null) { - continue - } - - if (Array.isArray(value)) { - const serializedArray = serializeArrayParam({ - allowReserved, - explode: true, - name, - style: 'form', - value, - ...array - }) - if (serializedArray) search.push(serializedArray) - } else if (typeof value === 'object') { - const serializedObject = serializeObjectParam({ - allowReserved, - explode: true, - name, - style: 'deepObject', - value: value as Record, - ...object - }) - if (serializedObject) search.push(serializedObject) - } else { - const serializedPrimitive = serializePrimitiveParam({ - allowReserved, - name, - value: value as string - }) - if (serializedPrimitive) search.push(serializedPrimitive) - } - } - } - return search.join('&') - } - return querySerializer -} - -/** - * Infers parseAs value from provided Content-Type header. - */ -export const getParseAs = (contentType: string | null): Exclude => { - if (!contentType) { - // If no Content-Type header is provided, the best we can do is return the raw response body, - // which is effectively the same as the 'stream' option. - return 'stream' - } - - const cleanContent = contentType.split(';')[0]?.trim() - - if (!cleanContent) { - return - } - - if (cleanContent.startsWith('application/json') || cleanContent.endsWith('+json')) { - return 'json' - } - - if (cleanContent === 'multipart/form-data') { - return 'formData' - } - - if ( - ['application/', 'audio/', 'image/', 'video/'].some((type) => cleanContent.startsWith(type)) - ) { - return 'blob' - } - - if (cleanContent.startsWith('text/')) { - return 'text' - } - - return -} - -const checkForExistence = ( - options: Pick & { - headers: Headers - }, - name?: string -): boolean => { - if (!name) { - return false - } - if ( - options.headers.has(name) || - options.query?.[name] || - options.headers.get('Cookie')?.includes(`${name}=`) - ) { - return true - } - return false -} - -export const setAuthParams = async ({ - security, - ...options -}: Pick, 'security'> & - Pick & { - headers: Headers - }) => { - for (const auth of security) { - if (checkForExistence(options, auth.name)) { - continue - } - - const token = await getAuthToken(auth, options.auth) - - if (!token) { - continue - } - - const name = auth.name ?? 'Authorization' - - switch (auth.in) { - case 'query': - if (!options.query) { - options.query = {} - } - options.query[name] = token - break - case 'cookie': - options.headers.append('Cookie', `${name}=${token}`) - break - case 'header': - default: - options.headers.set(name, token) - break - } - } -} - -export const buildUrl: Client['buildUrl'] = (options) => - getUrl({ - baseUrl: options.baseUrl as string, - path: options.path, - query: options.query, - querySerializer: - typeof options.querySerializer === 'function' - ? options.querySerializer - : createQuerySerializer(options.querySerializer), - url: options.url - }) - -export const mergeConfigs = (a: Config, b: Config): Config => { - const config = { ...a, ...b } - if (config.baseUrl?.endsWith('/')) { - config.baseUrl = config.baseUrl.substring(0, config.baseUrl.length - 1) - } - config.headers = mergeHeaders(a.headers, b.headers) - return config -} - -const headersEntries = (headers: Headers): Array<[string, string]> => { - const entries: Array<[string, string]> = [] - headers.forEach((value, key) => { - entries.push([key, value]) - }) - return entries -} - -export const mergeHeaders = ( - ...headers: Array['headers'] | undefined> -): Headers => { - const mergedHeaders = new Headers() - for (const header of headers) { - if (!header) { - continue - } - - const iterator = header instanceof Headers ? headersEntries(header) : Object.entries(header) - - for (const [key, value] of iterator) { - if (value === null) { - mergedHeaders.delete(key) - } else if (Array.isArray(value)) { - for (const v of value) { - mergedHeaders.append(key, v as string) - } - } else if (value !== undefined) { - // assume object headers are meant to be JSON stringified, i.e. their - // content value in OpenAPI specification is 'application/json' - mergedHeaders.set( - key, - typeof value === 'object' ? JSON.stringify(value) : (value as string) - ) - } - } - } - return mergedHeaders -} - -type ErrInterceptor = ( - error: Err, - response: Res, - request: Req, - options: Options -) => Err | Promise - -type ReqInterceptor = (request: Req, options: Options) => Req | Promise - -type ResInterceptor = ( - response: Res, - request: Req, - options: Options -) => Res | Promise - -class Interceptors { - fns: Array = [] - - clear(): void { - this.fns = [] - } - - eject(id: number | Interceptor): void { - const index = this.getInterceptorIndex(id) - if (this.fns[index]) { - this.fns[index] = null - } - } - - exists(id: number | Interceptor): boolean { - const index = this.getInterceptorIndex(id) - return Boolean(this.fns[index]) - } - - getInterceptorIndex(id: number | Interceptor): number { - if (typeof id === 'number') { - return this.fns[id] ? id : -1 - } - return this.fns.indexOf(id) - } - - update(id: number | Interceptor, fn: Interceptor): number | Interceptor | false { - const index = this.getInterceptorIndex(id) - if (this.fns[index]) { - this.fns[index] = fn - return id - } - return false - } - - use(fn: Interceptor): number { - this.fns.push(fn) - return this.fns.length - 1 - } -} - -export interface Middleware { - error: Interceptors> - request: Interceptors> - response: Interceptors> -} - -export const createInterceptors = (): Middleware< - Req, - Res, - Err, - Options -> => ({ - error: new Interceptors>(), - request: new Interceptors>(), - response: new Interceptors>() -}) - -const defaultQuerySerializer = createQuerySerializer({ - allowReserved: false, - array: { - explode: true, - style: 'form' - }, - object: { - explode: true, - style: 'deepObject' - } -}) - -const defaultHeaders = { - 'Content-Type': 'application/json' -} - -export const createConfig = ( - override: Config & T> = {} -): Config & T> => ({ - ...jsonBodySerializer, - headers: defaultHeaders, - parseAs: 'auto', - querySerializer: defaultQuerySerializer, - ...override -}) diff --git a/examples/integrations/generated/google/drive/core/auth.gen.ts b/examples/integrations/generated/google/drive/core/auth.gen.ts deleted file mode 100644 index dc8ff61..0000000 --- a/examples/integrations/generated/google/drive/core/auth.gen.ts +++ /dev/null @@ -1,41 +0,0 @@ -// This file is auto-generated by @hey-api/openapi-ts - -export type AuthToken = string | undefined - -export interface Auth { - /** - * Which part of the request do we use to send the auth? - * - * @default 'header' - */ - in?: 'header' | 'query' | 'cookie' - /** - * Header or query parameter name. - * - * @default 'Authorization' - */ - name?: string - scheme?: 'basic' | 'bearer' - type: 'apiKey' | 'http' -} - -export const getAuthToken = async ( - auth: Auth, - callback: ((auth: Auth) => Promise | AuthToken) | AuthToken -): Promise => { - const token = typeof callback === 'function' ? await callback(auth) : callback - - if (!token) { - return - } - - if (auth.scheme === 'bearer') { - return `Bearer ${token}` - } - - if (auth.scheme === 'basic') { - return `Basic ${btoa(token)}` - } - - return token -} diff --git a/examples/integrations/generated/google/drive/core/bodySerializer.gen.ts b/examples/integrations/generated/google/drive/core/bodySerializer.gen.ts deleted file mode 100644 index e39c6a5..0000000 --- a/examples/integrations/generated/google/drive/core/bodySerializer.gen.ts +++ /dev/null @@ -1,76 +0,0 @@ -// This file is auto-generated by @hey-api/openapi-ts - -import type { ArrayStyle, ObjectStyle, SerializerOptions } from './pathSerializer.gen' - -export type QuerySerializer = (query: Record) => string - -export type BodySerializer = (body: any) => any - -export interface QuerySerializerOptions { - allowReserved?: boolean - array?: SerializerOptions - object?: SerializerOptions -} - -const serializeFormDataPair = (data: FormData, key: string, value: unknown): void => { - if (typeof value === 'string' || value instanceof Blob) { - data.append(key, value) - } else if (value instanceof Date) { - data.append(key, value.toISOString()) - } else { - data.append(key, JSON.stringify(value)) - } -} - -const serializeUrlSearchParamsPair = (data: URLSearchParams, key: string, value: unknown): void => { - if (typeof value === 'string') { - data.append(key, value) - } else { - data.append(key, JSON.stringify(value)) - } -} - -export const formDataBodySerializer = { - bodySerializer: | Array>>( - body: T - ): FormData => { - const data = new FormData() - - Object.entries(body).forEach(([key, value]) => { - if (value === undefined || value === null) { - return - } - if (Array.isArray(value)) { - value.forEach((v) => serializeFormDataPair(data, key, v)) - } else { - serializeFormDataPair(data, key, value) - } - }) - - return data - } -} - -export const jsonBodySerializer = { - bodySerializer: (body: T): string => - JSON.stringify(body, (_key, value) => (typeof value === 'bigint' ? value.toString() : value)) -} - -export const urlSearchParamsBodySerializer = { - bodySerializer: | Array>>(body: T): string => { - const data = new URLSearchParams() - - Object.entries(body).forEach(([key, value]) => { - if (value === undefined || value === null) { - return - } - if (Array.isArray(value)) { - value.forEach((v) => serializeUrlSearchParamsPair(data, key, v)) - } else { - serializeUrlSearchParamsPair(data, key, value) - } - }) - - return data.toString() - } -} diff --git a/examples/integrations/generated/google/drive/core/params.gen.ts b/examples/integrations/generated/google/drive/core/params.gen.ts deleted file mode 100644 index 34dddb5..0000000 --- a/examples/integrations/generated/google/drive/core/params.gen.ts +++ /dev/null @@ -1,144 +0,0 @@ -// This file is auto-generated by @hey-api/openapi-ts - -type Slot = 'body' | 'headers' | 'path' | 'query' - -export type Field = - | { - in: Exclude - /** - * Field name. This is the name we want the user to see and use. - */ - key: string - /** - * Field mapped name. This is the name we want to use in the request. - * If omitted, we use the same value as `key`. - */ - map?: string - } - | { - in: Extract - /** - * Key isn't required for bodies. - */ - key?: string - map?: string - } - -export interface Fields { - allowExtra?: Partial> - args?: ReadonlyArray -} - -export type FieldsConfig = ReadonlyArray - -const extraPrefixesMap: Record = { - $body_: 'body', - $headers_: 'headers', - $path_: 'path', - $query_: 'query' -} -const extraPrefixes = Object.entries(extraPrefixesMap) - -type KeyMap = Map< - string, - { - in: Slot - map?: string - } -> - -const buildKeyMap = (fields: FieldsConfig, map?: KeyMap): KeyMap => { - if (!map) { - map = new Map() - } - - for (const config of fields) { - if ('in' in config) { - if (config.key) { - map.set(config.key, { - in: config.in, - map: config.map - }) - } - } else if (config.args) { - buildKeyMap(config.args, map) - } - } - - return map -} - -interface Params { - body: unknown - headers: Record - path: Record - query: Record -} - -const stripEmptySlots = (params: Params) => { - for (const [slot, value] of Object.entries(params)) { - if (value && typeof value === 'object' && !Object.keys(value).length) { - delete params[slot as Slot] - } - } -} - -export const buildClientParams = (args: ReadonlyArray, fields: FieldsConfig) => { - const params: Params = { - body: {}, - headers: {}, - path: {}, - query: {} - } - - const map = buildKeyMap(fields) - - let config: FieldsConfig[number] | undefined - - for (const [index, arg] of args.entries()) { - if (fields[index]) { - config = fields[index] - } - - if (!config) { - continue - } - - if ('in' in config) { - if (config.key) { - const field = map.get(config.key)! - const name = field.map || config.key - ;(params[field.in] as Record)[name] = arg - } else { - params.body = arg - } - } else { - for (const [key, value] of Object.entries(arg ?? {})) { - const field = map.get(key) - - if (field) { - const name = field.map || key - ;(params[field.in] as Record)[name] = value - } else { - const extra = extraPrefixes.find(([prefix]) => key.startsWith(prefix)) - - if (extra) { - const [prefix, slot] = extra - ;(params[slot] as Record)[key.slice(prefix.length)] = value - } else { - for (const [slot, allowed] of Object.entries(config.allowExtra ?? {})) { - if (allowed) { - ;(params[slot as Slot] as Record)[key] = value - break - } - } - } - } - } - } - } - - stripEmptySlots(params) - - return params -} diff --git a/examples/integrations/generated/google/drive/core/pathSerializer.gen.ts b/examples/integrations/generated/google/drive/core/pathSerializer.gen.ts deleted file mode 100644 index acc1367..0000000 --- a/examples/integrations/generated/google/drive/core/pathSerializer.gen.ts +++ /dev/null @@ -1,171 +0,0 @@ -// This file is auto-generated by @hey-api/openapi-ts - -interface SerializeOptions extends SerializePrimitiveOptions, SerializerOptions {} - -interface SerializePrimitiveOptions { - allowReserved?: boolean - name: string -} - -export interface SerializerOptions { - /** - * @default true - */ - explode: boolean - style: T -} - -export type ArrayStyle = 'form' | 'spaceDelimited' | 'pipeDelimited' -export type ArraySeparatorStyle = ArrayStyle | MatrixStyle -type MatrixStyle = 'label' | 'matrix' | 'simple' -export type ObjectStyle = 'form' | 'deepObject' -type ObjectSeparatorStyle = ObjectStyle | MatrixStyle - -interface SerializePrimitiveParam extends SerializePrimitiveOptions { - value: string -} - -export const separatorArrayExplode = (style: ArraySeparatorStyle) => { - switch (style) { - case 'label': - return '.' - case 'matrix': - return ';' - case 'simple': - return ',' - default: - return '&' - } -} - -export const separatorArrayNoExplode = (style: ArraySeparatorStyle) => { - switch (style) { - case 'form': - return ',' - case 'pipeDelimited': - return '|' - case 'spaceDelimited': - return '%20' - default: - return ',' - } -} - -export const separatorObjectExplode = (style: ObjectSeparatorStyle) => { - switch (style) { - case 'label': - return '.' - case 'matrix': - return ';' - case 'simple': - return ',' - default: - return '&' - } -} - -export const serializeArrayParam = ({ - allowReserved, - explode, - name, - style, - value -}: SerializeOptions & { - value: unknown[] -}) => { - if (!explode) { - const joinedValues = ( - allowReserved ? value : value.map((v) => encodeURIComponent(v as string)) - ).join(separatorArrayNoExplode(style)) - switch (style) { - case 'label': - return `.${joinedValues}` - case 'matrix': - return `;${name}=${joinedValues}` - case 'simple': - return joinedValues - default: - return `${name}=${joinedValues}` - } - } - - const separator = separatorArrayExplode(style) - const joinedValues = value - .map((v) => { - if (style === 'label' || style === 'simple') { - return allowReserved ? v : encodeURIComponent(v as string) - } - - return serializePrimitiveParam({ - allowReserved, - name, - value: v as string - }) - }) - .join(separator) - return style === 'label' || style === 'matrix' ? separator + joinedValues : joinedValues -} - -export const serializePrimitiveParam = ({ - allowReserved, - name, - value -}: SerializePrimitiveParam) => { - if (value === undefined || value === null) { - return '' - } - - if (typeof value === 'object') { - throw new Error( - 'Deeply-nested arrays/objects aren’t supported. Provide your own `querySerializer()` to handle these.' - ) - } - - return `${name}=${allowReserved ? value : encodeURIComponent(value)}` -} - -export const serializeObjectParam = ({ - allowReserved, - explode, - name, - style, - value, - valueOnly -}: SerializeOptions & { - value: Record | Date - valueOnly?: boolean -}) => { - if (value instanceof Date) { - return valueOnly ? value.toISOString() : `${name}=${value.toISOString()}` - } - - if (style !== 'deepObject' && !explode) { - let values: string[] = [] - Object.entries(value).forEach(([key, v]) => { - values = [...values, key, allowReserved ? (v as string) : encodeURIComponent(v as string)] - }) - const joinedValues = values.join(',') - switch (style) { - case 'form': - return `${name}=${joinedValues}` - case 'label': - return `.${joinedValues}` - case 'matrix': - return `;${name}=${joinedValues}` - default: - return joinedValues - } - } - - const separator = separatorObjectExplode(style) - const joinedValues = Object.entries(value) - .map(([key, v]) => - serializePrimitiveParam({ - allowReserved, - name: style === 'deepObject' ? `${name}[${key}]` : key, - value: v as string - }) - ) - .join(separator) - return style === 'label' || style === 'matrix' ? separator + joinedValues : joinedValues -} diff --git a/examples/integrations/generated/google/drive/core/serverSentEvents.gen.ts b/examples/integrations/generated/google/drive/core/serverSentEvents.gen.ts deleted file mode 100644 index 372e50c..0000000 --- a/examples/integrations/generated/google/drive/core/serverSentEvents.gen.ts +++ /dev/null @@ -1,241 +0,0 @@ -// This file is auto-generated by @hey-api/openapi-ts - -import type { Config } from './types.gen' - -export type ServerSentEventsOptions = Omit & - Pick & { - /** - * Fetch API implementation. You can use this option to provide a custom - * fetch instance. - * - * @default globalThis.fetch - */ - fetch?: typeof fetch - /** - * Implementing clients can call request interceptors inside this hook. - */ - onRequest?: (url: string, init: RequestInit) => Promise - /** - * Callback invoked when a network or parsing error occurs during streaming. - * - * This option applies only if the endpoint returns a stream of events. - * - * @param error The error that occurred. - */ - onSseError?: (error: unknown) => void - /** - * Callback invoked when an event is streamed from the server. - * - * This option applies only if the endpoint returns a stream of events. - * - * @param event Event streamed from the server. - * @returns Nothing (void). - */ - onSseEvent?: (event: StreamEvent) => void - serializedBody?: RequestInit['body'] - /** - * Default retry delay in milliseconds. - * - * This option applies only if the endpoint returns a stream of events. - * - * @default 3000 - */ - sseDefaultRetryDelay?: number - /** - * Maximum number of retry attempts before giving up. - */ - sseMaxRetryAttempts?: number - /** - * Maximum retry delay in milliseconds. - * - * Applies only when exponential backoff is used. - * - * This option applies only if the endpoint returns a stream of events. - * - * @default 30000 - */ - sseMaxRetryDelay?: number - /** - * Optional sleep function for retry backoff. - * - * Defaults to using `setTimeout`. - */ - sseSleepFn?: (ms: number) => Promise - url: string - } - -export interface StreamEvent { - data: TData - event?: string - id?: string - retry?: number -} - -export type ServerSentEventsResult = { - stream: AsyncGenerator< - TData extends Record ? TData[keyof TData] : TData, - TReturn, - TNext - > -} - -export const createSseClient = ({ - onRequest, - onSseError, - onSseEvent, - responseTransformer, - responseValidator, - sseDefaultRetryDelay, - sseMaxRetryAttempts, - sseMaxRetryDelay, - sseSleepFn, - url, - ...options -}: ServerSentEventsOptions): ServerSentEventsResult => { - let lastEventId: string | undefined - - const sleep = sseSleepFn ?? ((ms: number) => new Promise((resolve) => setTimeout(resolve, ms))) - - const createStream = async function* () { - let retryDelay: number = sseDefaultRetryDelay ?? 3000 - let attempt = 0 - const signal = options.signal ?? new AbortController().signal - - while (true) { - if (signal.aborted) break - - attempt++ - - const headers = - options.headers instanceof Headers - ? options.headers - : new Headers(options.headers as Record | undefined) - - if (lastEventId !== undefined) { - headers.set('Last-Event-ID', lastEventId) - } - - try { - const requestInit: RequestInit = { - redirect: 'follow', - ...options, - body: options.serializedBody, - headers, - signal - } - let request = new Request(url, requestInit) - if (onRequest) { - request = await onRequest(url, requestInit) - } - // fetch must be assigned here, otherwise it would throw the error: - // TypeError: Failed to execute 'fetch' on 'Window': Illegal invocation - const _fetch = options.fetch ?? globalThis.fetch - const response = await _fetch(request) - - if (!response.ok) throw new Error(`SSE failed: ${response.status} ${response.statusText}`) - - if (!response.body) throw new Error('No body in SSE response') - - const reader = response.body.pipeThrough(new TextDecoderStream()).getReader() - - let buffer = '' - - const abortHandler = () => { - try { - reader.cancel() - } catch { - // noop - } - } - - signal.addEventListener('abort', abortHandler) - - try { - while (true) { - const { done, value } = await reader.read() - if (done) break - buffer += value - - const chunks = buffer.split('\n\n') - buffer = chunks.pop() ?? '' - - for (const chunk of chunks) { - const lines = chunk.split('\n') - const dataLines: Array = [] - let eventName: string | undefined - - for (const line of lines) { - if (line.startsWith('data:')) { - dataLines.push(line.replace(/^data:\s*/, '')) - } else if (line.startsWith('event:')) { - eventName = line.replace(/^event:\s*/, '') - } else if (line.startsWith('id:')) { - lastEventId = line.replace(/^id:\s*/, '') - } else if (line.startsWith('retry:')) { - const parsed = Number.parseInt(line.replace(/^retry:\s*/, ''), 10) - if (!Number.isNaN(parsed)) { - retryDelay = parsed - } - } - } - - let data: unknown - let parsedJson = false - - if (dataLines.length) { - const rawData = dataLines.join('\n') - try { - data = JSON.parse(rawData) - parsedJson = true - } catch { - data = rawData - } - } - - if (parsedJson) { - if (responseValidator) { - await responseValidator(data) - } - - if (responseTransformer) { - data = await responseTransformer(data) - } - } - - onSseEvent?.({ - data, - event: eventName, - id: lastEventId, - retry: retryDelay - }) - - if (dataLines.length) { - yield data as any - } - } - } - } finally { - signal.removeEventListener('abort', abortHandler) - reader.releaseLock() - } - - break // exit loop on normal completion - } catch (error) { - // connection failed or aborted; retry after delay - onSseError?.(error) - - if (sseMaxRetryAttempts !== undefined && attempt >= sseMaxRetryAttempts) { - break // stop after firing error - } - - // exponential backoff: double retry each attempt, cap at 30s - const backoff = Math.min(retryDelay * 2 ** (attempt - 1), sseMaxRetryDelay ?? 30000) - await sleep(backoff) - } - } - } - - const stream = createStream() - - return { stream } -} diff --git a/examples/integrations/generated/google/drive/core/types.gen.ts b/examples/integrations/generated/google/drive/core/types.gen.ts deleted file mode 100644 index 647ffcc..0000000 --- a/examples/integrations/generated/google/drive/core/types.gen.ts +++ /dev/null @@ -1,104 +0,0 @@ -// This file is auto-generated by @hey-api/openapi-ts - -import type { Auth, AuthToken } from './auth.gen' -import type { BodySerializer, QuerySerializer, QuerySerializerOptions } from './bodySerializer.gen' - -export type HttpMethod = - | 'connect' - | 'delete' - | 'get' - | 'head' - | 'options' - | 'patch' - | 'post' - | 'put' - | 'trace' - -export type Client< - RequestFn = never, - Config = unknown, - MethodFn = never, - BuildUrlFn = never, - SseFn = never -> = { - /** - * Returns the final request URL. - */ - buildUrl: BuildUrlFn - getConfig: () => Config - request: RequestFn - setConfig: (config: Config) => Config -} & { - [K in HttpMethod]: MethodFn -} & ([SseFn] extends [never] ? { sse?: never } : { sse: { [K in HttpMethod]: SseFn } }) - -export interface Config { - /** - * Auth token or a function returning auth token. The resolved value will be - * added to the request payload as defined by its `security` array. - */ - auth?: ((auth: Auth) => Promise | AuthToken) | AuthToken - /** - * A function for serializing request body parameter. By default, - * {@link JSON.stringify()} will be used. - */ - bodySerializer?: BodySerializer | null - /** - * An object containing any HTTP headers that you want to pre-populate your - * `Headers` object with. - * - * {@link https://developer.mozilla.org/docs/Web/API/Headers/Headers#init See more} - */ - headers?: - | RequestInit['headers'] - | Record< - string, - string | number | boolean | (string | number | boolean)[] | null | undefined | unknown - > - /** - * The request method. - * - * {@link https://developer.mozilla.org/docs/Web/API/fetch#method See more} - */ - method?: Uppercase - /** - * A function for serializing request query parameters. By default, arrays - * will be exploded in form style, objects will be exploded in deepObject - * style, and reserved characters are percent-encoded. - * - * This method will have no effect if the native `paramsSerializer()` Axios - * API function is used. - * - * {@link https://swagger.io/docs/specification/serialization/#query View examples} - */ - querySerializer?: QuerySerializer | QuerySerializerOptions - /** - * A function validating request data. This is useful if you want to ensure - * the request conforms to the desired shape, so it can be safely sent to - * the server. - */ - requestValidator?: (data: unknown) => Promise - /** - * A function transforming response data before it's returned. This is useful - * for post-processing data, e.g. converting ISO strings into Date objects. - */ - responseTransformer?: (data: unknown) => Promise - /** - * A function validating response data. This is useful if you want to ensure - * the response conforms to the desired shape, so it can be safely passed to - * the transformers and returned to the user. - */ - responseValidator?: (data: unknown) => Promise -} - -type IsExactlyNeverOrNeverUndefined = [T] extends [never] - ? true - : [T] extends [never | undefined] - ? [undefined] extends [T] - ? false - : true - : false - -export type OmitNever> = { - [K in keyof T as IsExactlyNeverOrNeverUndefined extends true ? never : K]: T[K] -} diff --git a/examples/integrations/generated/google/drive/core/utils.gen.ts b/examples/integrations/generated/google/drive/core/utils.gen.ts deleted file mode 100644 index bd078be..0000000 --- a/examples/integrations/generated/google/drive/core/utils.gen.ts +++ /dev/null @@ -1,140 +0,0 @@ -// This file is auto-generated by @hey-api/openapi-ts - -import type { BodySerializer, QuerySerializer } from './bodySerializer.gen' -import { - type ArraySeparatorStyle, - serializeArrayParam, - serializeObjectParam, - serializePrimitiveParam -} from './pathSerializer.gen' - -export interface PathSerializer { - path: Record - url: string -} - -export const PATH_PARAM_RE = /\{[^{}]+\}/g - -export const defaultPathSerializer = ({ path, url: _url }: PathSerializer) => { - let url = _url - const matches = _url.match(PATH_PARAM_RE) - if (matches) { - for (const match of matches) { - let explode = false - let name = match.substring(1, match.length - 1) - let style: ArraySeparatorStyle = 'simple' - - if (name.endsWith('*')) { - explode = true - name = name.substring(0, name.length - 1) - } - - if (name.startsWith('.')) { - name = name.substring(1) - style = 'label' - } else if (name.startsWith(';')) { - name = name.substring(1) - style = 'matrix' - } - - const value = path[name] - - if (value === undefined || value === null) { - continue - } - - if (Array.isArray(value)) { - url = url.replace(match, serializeArrayParam({ explode, name, style, value })) - continue - } - - if (typeof value === 'object') { - url = url.replace( - match, - serializeObjectParam({ - explode, - name, - style, - value: value as Record, - valueOnly: true - }) - ) - continue - } - - if (style === 'matrix') { - url = url.replace( - match, - `;${serializePrimitiveParam({ - name, - value: value as string - })}` - ) - continue - } - - const replaceValue = encodeURIComponent( - style === 'label' ? `.${value as string}` : (value as string) - ) - url = url.replace(match, replaceValue) - } - } - return url -} - -export const getUrl = ({ - baseUrl, - path, - query, - querySerializer, - url: _url -}: { - baseUrl?: string - path?: Record - query?: Record - querySerializer: QuerySerializer - url: string -}) => { - const pathUrl = _url.startsWith('/') ? _url : `/${_url}` - let url = (baseUrl ?? '') + pathUrl - if (path) { - url = defaultPathSerializer({ path, url }) - } - let search = query ? querySerializer(query) : '' - if (search.startsWith('?')) { - search = search.substring(1) - } - if (search) { - url += `?${search}` - } - return url -} - -export function getValidRequestBody(options: { - body?: unknown - bodySerializer?: BodySerializer | null - serializedBody?: unknown -}) { - const hasBody = options.body !== undefined - const isSerializedBody = hasBody && options.bodySerializer - - if (isSerializedBody) { - if ('serializedBody' in options) { - const hasSerializedBody = - options.serializedBody !== undefined && options.serializedBody !== '' - - return hasSerializedBody ? options.serializedBody : null - } - - // not all clients implement a serializedBody property (i.e. client-axios) - return options.body !== '' ? options.body : null - } - - // plain/text body - if (hasBody) { - return options.body - } - - // no body was provided - return undefined -} diff --git a/examples/integrations/generated/google/drive/schemas.gen.ts b/examples/integrations/generated/google/drive/schemas.gen.ts deleted file mode 100644 index 3ae2823..0000000 --- a/examples/integrations/generated/google/drive/schemas.gen.ts +++ /dev/null @@ -1,3069 +0,0 @@ -// This file is auto-generated by @hey-api/openapi-ts - -export const AboutSchema = { - description: "Information about the user, the user's Drive, and system capabilities.", - properties: { - appInstalled: { - description: 'Whether the user has installed the requesting app.', - type: 'boolean' - }, - canCreateDrives: { - description: 'Whether the user can create shared drives.', - type: 'boolean' - }, - canCreateTeamDrives: { - description: 'Deprecated - use canCreateDrives instead.', - type: 'boolean' - }, - driveThemes: { - description: 'A list of themes that are supported for shared drives.', - items: { - properties: { - backgroundImageLink: { - description: "A link to this theme's background image.", - type: 'string' - }, - colorRgb: { - description: 'The color of this theme as an RGB hex string.', - type: 'string' - }, - id: { - description: 'The ID of the theme.', - type: 'string' - } - }, - type: 'object' - }, - type: 'array' - }, - exportFormats: { - additionalProperties: { - items: { - type: 'string' - }, - type: 'array' - }, - description: 'A map of source MIME type to possible targets for all supported exports.', - type: 'object' - }, - folderColorPalette: { - description: 'The currently supported folder colors as RGB hex strings.', - items: { - type: 'string' - }, - type: 'array' - }, - importFormats: { - additionalProperties: { - items: { - type: 'string' - }, - type: 'array' - }, - description: 'A map of source MIME type to possible targets for all supported imports.', - type: 'object' - }, - kind: { - default: 'drive#about', - description: - 'Identifies what kind of resource this is. Value: the fixed string "drive#about".', - type: 'string' - }, - maxImportSizes: { - additionalProperties: { - format: 'int64', - type: 'string' - }, - description: 'A map of maximum import sizes by MIME type, in bytes.', - type: 'object' - }, - maxUploadSize: { - description: 'The maximum upload size in bytes.', - format: 'int64', - type: 'string' - }, - storageQuota: { - description: "The user's storage quota limits and usage. All fields are measured in bytes.", - properties: { - limit: { - description: - 'The usage limit, if applicable. This will not be present if the user has unlimited storage.', - format: 'int64', - type: 'string' - }, - usage: { - description: 'The total usage across all services.', - format: 'int64', - type: 'string' - }, - usageInDrive: { - description: 'The usage by all files in Google Drive.', - format: 'int64', - type: 'string' - }, - usageInDriveTrash: { - description: 'The usage by trashed files in Google Drive.', - format: 'int64', - type: 'string' - } - }, - type: 'object' - }, - teamDriveThemes: { - description: 'Deprecated - use driveThemes instead.', - items: { - properties: { - backgroundImageLink: { - description: 'Deprecated - use driveThemes/backgroundImageLink instead.', - type: 'string' - }, - colorRgb: { - description: 'Deprecated - use driveThemes/colorRgb instead.', - type: 'string' - }, - id: { - description: 'Deprecated - use driveThemes/id instead.', - type: 'string' - } - }, - type: 'object' - }, - type: 'array' - }, - user: { - $ref: '#/components/schemas/User', - description: 'The authenticated user.' - } - }, - type: 'object' -} as const - -export const ChangeSchema = { - description: 'A change to a file or shared drive.', - properties: { - changeType: { - description: 'The type of the change. Possible values are file and drive.', - type: 'string' - }, - drive: { - $ref: '#/components/schemas/Drive', - description: - 'The updated state of the shared drive. Present if the changeType is drive, the user is still a member of the shared drive, and the shared drive has not been deleted.' - }, - driveId: { - description: 'The ID of the shared drive associated with this change.', - type: 'string' - }, - file: { - $ref: '#/components/schemas/File', - description: - 'The updated state of the file. Present if the type is file and the file has not been removed from this list of changes.' - }, - fileId: { - description: 'The ID of the file which has changed.', - type: 'string' - }, - kind: { - default: 'drive#change', - description: - 'Identifies what kind of resource this is. Value: the fixed string "drive#change".', - type: 'string' - }, - removed: { - description: - 'Whether the file or shared drive has been removed from this list of changes, for example by deletion or loss of access.', - type: 'boolean' - }, - teamDrive: { - $ref: '#/components/schemas/TeamDrive', - description: 'Deprecated - use drive instead.' - }, - teamDriveId: { - description: 'Deprecated - use driveId instead.', - type: 'string' - }, - time: { - description: 'The time of this change (RFC 3339 date-time).', - format: 'date-time', - type: 'string' - }, - type: { - description: 'Deprecated - use changeType instead.', - type: 'string' - } - }, - type: 'object' -} as const - -export const ChangeListSchema = { - description: 'A list of changes for a user.', - properties: { - changes: { - description: - 'The list of changes. If nextPageToken is populated, then this list may be incomplete and an additional page of results should be fetched.', - items: { - $ref: '#/components/schemas/Change' - }, - type: 'array' - }, - kind: { - default: 'drive#changeList', - description: - 'Identifies what kind of resource this is. Value: the fixed string "drive#changeList".', - type: 'string' - }, - newStartPageToken: { - description: - 'The starting page token for future changes. This will be present only if the end of the current changes list has been reached.', - type: 'string' - }, - nextPageToken: { - description: - 'The page token for the next page of changes. This will be absent if the end of the changes list has been reached. If the token is rejected for any reason, it should be discarded, and pagination should be restarted from the first page of results.', - type: 'string' - } - }, - type: 'object' -} as const - -export const ChannelSchema = { - description: 'An notification channel used to watch for resource changes.', - properties: { - address: { - description: 'The address where notifications are delivered for this channel.', - type: 'string' - }, - expiration: { - description: - 'Date and time of notification channel expiration, expressed as a Unix timestamp, in milliseconds. Optional.', - format: 'int64', - type: 'string' - }, - id: { - description: 'A UUID or similar unique string that identifies this channel.', - type: 'string' - }, - kind: { - default: 'api#channel', - description: - 'Identifies this as a notification channel used to watch for changes to a resource, which is "api#channel".', - type: 'string' - }, - params: { - additionalProperties: { - description: 'Declares a new parameter by name.', - type: 'string' - }, - description: 'Additional parameters controlling delivery channel behavior. Optional.', - type: 'object' - }, - payload: { - description: 'A Boolean value to indicate whether payload is wanted. Optional.', - type: 'boolean' - }, - resourceId: { - description: - 'An opaque ID that identifies the resource being watched on this channel. Stable across different API versions.', - type: 'string' - }, - resourceUri: { - description: 'A version-specific identifier for the watched resource.', - type: 'string' - }, - token: { - description: - 'An arbitrary string delivered to the target address with each notification delivered over this channel. Optional.', - type: 'string' - }, - type: { - description: - 'The type of delivery mechanism used for this channel. Valid values are "web_hook" (or "webhook"). Both values refer to a channel where Http requests are used to deliver messages.', - type: 'string' - } - }, - type: 'object' -} as const - -export const CommentSchema = { - description: 'A comment on a file.', - properties: { - anchor: { - description: - 'A region of the document represented as a JSON string. For details on defining anchor properties, refer to Add comments and replies.', - type: 'string' - }, - author: { - $ref: '#/components/schemas/User', - description: - "The author of the comment. The author's email address and permission ID will not be populated." - }, - content: { - description: - 'The plain text content of the comment. This field is used for setting the content, while htmlContent should be displayed.', - type: 'string' - }, - createdTime: { - description: 'The time at which the comment was created (RFC 3339 date-time).', - format: 'date-time', - type: 'string' - }, - deleted: { - description: 'Whether the comment has been deleted. A deleted comment has no content.', - type: 'boolean' - }, - htmlContent: { - description: 'The content of the comment with HTML formatting.', - type: 'string' - }, - id: { - description: 'The ID of the comment.', - type: 'string' - }, - kind: { - default: 'drive#comment', - description: - 'Identifies what kind of resource this is. Value: the fixed string "drive#comment".', - type: 'string' - }, - modifiedTime: { - description: - 'The last time the comment or any of its replies was modified (RFC 3339 date-time).', - format: 'date-time', - type: 'string' - }, - quotedFileContent: { - description: - 'The file content to which the comment refers, typically within the anchor region. For a text file, for example, this would be the text at the location of the comment.', - properties: { - mimeType: { - description: 'The MIME type of the quoted content.', - type: 'string' - }, - value: { - description: - 'The quoted content itself. This is interpreted as plain text if set through the API.', - type: 'string' - } - }, - type: 'object' - }, - replies: { - description: 'The full list of replies to the comment in chronological order.', - items: { - $ref: '#/components/schemas/Reply' - }, - type: 'array' - }, - resolved: { - description: 'Whether the comment has been resolved by one of its replies.', - type: 'boolean' - } - }, - type: 'object' -} as const - -export const CommentListSchema = { - description: 'A list of comments on a file.', - properties: { - comments: { - description: - 'The list of comments. If nextPageToken is populated, then this list may be incomplete and an additional page of results should be fetched.', - items: { - $ref: '#/components/schemas/Comment' - }, - type: 'array' - }, - kind: { - default: 'drive#commentList', - description: - 'Identifies what kind of resource this is. Value: the fixed string "drive#commentList".', - type: 'string' - }, - nextPageToken: { - description: - 'The page token for the next page of comments. This will be absent if the end of the comments list has been reached. If the token is rejected for any reason, it should be discarded, and pagination should be restarted from the first page of results.', - type: 'string' - } - }, - type: 'object' -} as const - -export const ContentRestrictionSchema = { - description: 'A restriction for accessing the content of the file.', - properties: { - readOnly: { - description: - 'Whether the content of the file is read-only. If a file is read-only, a new revision of the file may not be added, comments may not be added or modified, and the title of the file may not be modified.', - type: 'boolean' - }, - reason: { - description: - 'Reason for why the content of the file is restricted. This is only mutable on requests that also set readOnly=true.', - type: 'string' - }, - restrictingUser: { - $ref: '#/components/schemas/User', - description: 'The user who set the content restriction. Only populated if readOnly is true.' - }, - restrictionTime: { - description: - 'The time at which the content restriction was set (formatted RFC 3339 timestamp). Only populated if readOnly is true.', - format: 'date-time', - type: 'string' - }, - type: { - description: - 'The type of the content restriction. Currently the only possible value is globalContentRestriction.', - type: 'string' - } - }, - type: 'object' -} as const - -export const DriveSchema = { - description: 'Representation of a shared drive.', - properties: { - backgroundImageFile: { - description: - "An image file and cropping parameters from which a background image for this shared drive is set. This is a write-only field; it can only be set on drive.drives.update requests that don't set themeId. When specified, all fields of the backgroundImageFile must be set.", - properties: { - id: { - description: 'The ID of an image file in Google Drive to use for the background image.', - type: 'string' - }, - width: { - description: - 'The width of the cropped image in the closed range of 0 to 1. This value represents the width of the cropped image divided by the width of the entire image. The height is computed by applying a width to height aspect ratio of 80 to 9. The resulting image must be at least 1280 pixels wide and 144 pixels high.', - format: 'float', - type: 'number' - }, - xCoordinate: { - description: - 'The X coordinate of the upper left corner of the cropping area in the background image. This is a value in the closed range of 0 to 1. This value represents the horizontal distance from the left side of the entire image to the left side of the cropping area divided by the width of the entire image.', - format: 'float', - type: 'number' - }, - yCoordinate: { - description: - 'The Y coordinate of the upper left corner of the cropping area in the background image. This is a value in the closed range of 0 to 1. This value represents the vertical distance from the top side of the entire image to the top side of the cropping area divided by the height of the entire image.', - format: 'float', - type: 'number' - } - }, - type: 'object' - }, - backgroundImageLink: { - description: "A short-lived link to this shared drive's background image.", - type: 'string' - }, - capabilities: { - description: 'Capabilities the current user has on this shared drive.', - properties: { - canAddChildren: { - description: 'Whether the current user can add children to folders in this shared drive.', - type: 'boolean' - }, - canChangeCopyRequiresWriterPermissionRestriction: { - description: - 'Whether the current user can change the copyRequiresWriterPermission restriction of this shared drive.', - type: 'boolean' - }, - canChangeDomainUsersOnlyRestriction: { - description: - 'Whether the current user can change the domainUsersOnly restriction of this shared drive.', - type: 'boolean' - }, - canChangeDriveBackground: { - description: 'Whether the current user can change the background of this shared drive.', - type: 'boolean' - }, - canChangeDriveMembersOnlyRestriction: { - description: - 'Whether the current user can change the driveMembersOnly restriction of this shared drive.', - type: 'boolean' - }, - canChangeSharingFoldersRequiresOrganizerPermissionRestriction: { - description: - 'Whether the current user can change the sharingFoldersRequiresOrganizerPermission restriction of this shared drive.', - type: 'boolean' - }, - canComment: { - description: 'Whether the current user can comment on files in this shared drive.', - type: 'boolean' - }, - canCopy: { - description: 'Whether the current user can copy files in this shared drive.', - type: 'boolean' - }, - canDeleteChildren: { - description: - 'Whether the current user can delete children from folders in this shared drive.', - type: 'boolean' - }, - canDeleteDrive: { - description: - 'Whether the current user can delete this shared drive. Attempting to delete the shared drive may still fail if there are untrashed items inside the shared drive.', - type: 'boolean' - }, - canDownload: { - description: 'Whether the current user can download files in this shared drive.', - type: 'boolean' - }, - canEdit: { - description: 'Whether the current user can edit files in this shared drive', - type: 'boolean' - }, - canListChildren: { - description: - 'Whether the current user can list the children of folders in this shared drive.', - type: 'boolean' - }, - canManageMembers: { - description: - 'Whether the current user can add members to this shared drive or remove them or change their role.', - type: 'boolean' - }, - canReadRevisions: { - description: - 'Whether the current user can read the revisions resource of files in this shared drive.', - type: 'boolean' - }, - canRename: { - description: 'Whether the current user can rename files or folders in this shared drive.', - type: 'boolean' - }, - canRenameDrive: { - description: 'Whether the current user can rename this shared drive.', - type: 'boolean' - }, - canResetDriveRestrictions: { - description: - 'Whether the current user can reset the shared drive restrictions to defaults.', - type: 'boolean' - }, - canShare: { - description: 'Whether the current user can share files or folders in this shared drive.', - type: 'boolean' - }, - canTrashChildren: { - description: - 'Whether the current user can trash children from folders in this shared drive.', - type: 'boolean' - } - }, - type: 'object' - }, - colorRgb: { - description: - "The color of this shared drive as an RGB hex string. It can only be set on drive.drives.update requests that don't set themeId.", - type: 'string' - }, - createdTime: { - description: 'The time at which the shared drive was created (RFC 3339 date-time).', - format: 'date-time', - type: 'string' - }, - hidden: { - description: 'Whether the shared drive is hidden from default view.', - type: 'boolean' - }, - id: { - description: - 'The ID of this shared drive which is also the ID of the top level folder of this shared drive.', - type: 'string' - }, - kind: { - default: 'drive#drive', - description: - 'Identifies what kind of resource this is. Value: the fixed string "drive#drive".', - type: 'string' - }, - name: { - description: 'The name of this shared drive.', - type: 'string' - }, - orgUnitId: { - description: - 'The organizational unit of this shared drive. This field is only populated on drives.list responses when the useDomainAdminAccess parameter is set to true.', - type: 'string' - }, - restrictions: { - description: - 'A set of restrictions that apply to this shared drive or items inside this shared drive.', - properties: { - adminManagedRestrictions: { - description: - 'Whether administrative privileges on this shared drive are required to modify restrictions.', - type: 'boolean' - }, - copyRequiresWriterPermission: { - description: - 'Whether the options to copy, print, or download files inside this shared drive, should be disabled for readers and commenters. When this restriction is set to true, it will override the similarly named field to true for any file inside this shared drive.', - type: 'boolean' - }, - domainUsersOnly: { - description: - 'Whether access to this shared drive and items inside this shared drive is restricted to users of the domain to which this shared drive belongs. This restriction may be overridden by other sharing policies controlled outside of this shared drive.', - type: 'boolean' - }, - driveMembersOnly: { - description: - 'Whether access to items inside this shared drive is restricted to its members.', - type: 'boolean' - }, - sharingFoldersRequiresOrganizerPermission: { - description: - 'If true, only users with the organizer role can share folders. If false, users with either the organizer role or the file organizer role can share folders.', - type: 'boolean' - } - }, - type: 'object' - }, - themeId: { - description: - "The ID of the theme from which the background image and color are set. The set of possible driveThemes can be retrieved from a drive.about.get response. When not specified on a drive.drives.create request, a random theme is chosen from which the background image and color are set. This is a write-only field; it can only be set on requests that don't set colorRgb or backgroundImageFile.", - type: 'string' - } - }, - type: 'object' -} as const - -export const DriveListSchema = { - description: 'A list of shared drives.', - properties: { - drives: { - description: - 'The list of shared drives. If nextPageToken is populated, then this list may be incomplete and an additional page of results should be fetched.', - items: { - $ref: '#/components/schemas/Drive' - }, - type: 'array' - }, - kind: { - default: 'drive#driveList', - description: - 'Identifies what kind of resource this is. Value: the fixed string "drive#driveList".', - type: 'string' - }, - nextPageToken: { - description: - 'The page token for the next page of shared drives. This will be absent if the end of the list has been reached. If the token is rejected for any reason, it should be discarded, and pagination should be restarted from the first page of results.', - type: 'string' - } - }, - type: 'object' -} as const - -export const FileSchema = { - description: 'The metadata for a file.', - properties: { - appProperties: { - additionalProperties: { - type: 'string' - }, - description: `A collection of arbitrary key-value pairs that are private to the requesting app. -Entries with null values are cleared in update and copy requests. These properties can only be retrieved using an authenticated request. An authenticated request uses an access token obtained with an OAuth 2 client ID. You cannot use an API key to retrieve private properties.`, - type: 'object' - }, - capabilities: { - description: - 'Capabilities the current user has on this file. Each capability corresponds to a fine-grained action that a user can take.', - properties: { - canAcceptOwnership: { - description: - 'Whether the current user is the pending owner of the file. Not populated for shared drive files.', - type: 'boolean' - }, - canAddChildren: { - description: - "Whether the current user can add children to this folder. This is always false when the item isn't a folder.", - type: 'boolean' - }, - canAddFolderFromAnotherDrive: { - description: - "Whether the current user can add a folder from another drive (different shared drive or My Drive) to this folder. This is false when the item isn't a folder. Only populated for items in shared drives.", - type: 'boolean' - }, - canAddMyDriveParent: { - description: - 'Whether the current user can add a parent for the item without removing an existing parent in the same request. Not populated for shared drive files.', - type: 'boolean' - }, - canChangeCopyRequiresWriterPermission: { - description: - 'Whether the current user can change the copyRequiresWriterPermission restriction of this file.', - type: 'boolean' - }, - canChangeSecurityUpdateEnabled: { - description: - 'Whether the current user can change the securityUpdateEnabled field on link share metadata.', - type: 'boolean' - }, - canChangeViewersCanCopyContent: { - description: 'Deprecated', - type: 'boolean' - }, - canComment: { - description: 'Whether the current user can comment on this file.', - type: 'boolean' - }, - canCopy: { - description: - "Whether the current user can copy this file. For an item in a shared drive, whether the current user can copy non-folder descendants of this item, or this item itself if it's not a folder.", - type: 'boolean' - }, - canDelete: { - description: 'Whether the current user can delete this file.', - type: 'boolean' - }, - canDeleteChildren: { - description: - "Whether the current user can delete children of this folder. This is false when the item isn't a folder. Only populated for items in shared drives.", - type: 'boolean' - }, - canDownload: { - description: 'Whether the current user can download this file.', - type: 'boolean' - }, - canEdit: { - description: - 'Whether the current user can edit this file. Other factors might limit the type of changes a user can make to a file. For example, see canChangeCopyRequiresWriterPermission or canModifyContent.', - type: 'boolean' - }, - canListChildren: { - description: - "Whether the current user can list the children of this folder. This is always false when the item isn't a folder.", - type: 'boolean' - }, - canModifyContent: { - description: 'Whether the current user can modify the content of this file.', - type: 'boolean' - }, - canModifyContentRestriction: { - description: 'Whether the current user can modify restrictions on content of this file.', - type: 'boolean' - }, - canModifyLabels: { - description: 'Whether the current user can modify the labels on this file.', - type: 'boolean' - }, - canMoveChildrenOutOfDrive: { - description: - "Whether the current user can move children of this folder outside of the shared drive. This is false when the item isn't a folder. Only populated for items in shared drives.", - type: 'boolean' - }, - canMoveChildrenOutOfTeamDrive: { - description: 'Deprecated - use canMoveChildrenOutOfDrive instead.', - type: 'boolean' - }, - canMoveChildrenWithinDrive: { - description: - "Whether the current user can move children of this folder within this shared drive or My Drive. This is false when the item isn't a folder. Note that a request to move the child might still fail depending on the current user's access to the child and to the destination folder.", - type: 'boolean' - }, - canMoveChildrenWithinTeamDrive: { - description: 'Deprecated - use canMoveChildrenWithinDrive instead.', - type: 'boolean' - }, - canMoveItemIntoTeamDrive: { - description: 'Deprecated - use canMoveItemOutOfDrive instead.', - type: 'boolean' - }, - canMoveItemOutOfDrive: { - description: - "Whether the current user can move this item outside of this shared drive or My Drive by changing its parent. Note that a request to change the parent of the item might still fail depending on the new parent that's being added.", - type: 'boolean' - }, - canMoveItemOutOfTeamDrive: { - description: 'Deprecated - use canMoveItemOutOfDrive instead.', - type: 'boolean' - }, - canMoveItemWithinDrive: { - description: - "Whether the current user can move this item within this shared drive or My Drive. Note that a request to change the parent of the item might still fail depending on the new parent that's being added and the parent that's being removed.", - type: 'boolean' - }, - canMoveItemWithinTeamDrive: { - description: 'Deprecated - use canMoveItemWithinDrive instead.', - type: 'boolean' - }, - canMoveTeamDriveItem: { - description: 'Deprecated - use canMoveItemWithinDrive or canMoveItemOutOfDrive instead.', - type: 'boolean' - }, - canReadDrive: { - description: - 'Whether the current user can read the shared drive to which this file belongs. Only populated for items in shared drives.', - type: 'boolean' - }, - canReadLabels: { - description: 'Whether the current user can read the labels on this file.', - type: 'boolean' - }, - canReadRevisions: { - description: - "Whether the current user can read the revisions resource of this file. For a shared drive item, whether revisions of non-folder descendants of this item, or this item itself if it's not a folder, can be read.", - type: 'boolean' - }, - canReadTeamDrive: { - description: 'Deprecated - use canReadDrive instead.', - type: 'boolean' - }, - canRemoveChildren: { - description: - "Whether the current user can remove children from this folder. This is always false when the item isn't a folder. For a folder in a shared drive, use canDeleteChildren or canTrashChildren instead.", - type: 'boolean' - }, - canRemoveMyDriveParent: { - description: - 'Whether the current user can remove a parent from the item without adding another parent in the same request. Not populated for shared drive files.', - type: 'boolean' - }, - canRename: { - description: 'Whether the current user can rename this file.', - type: 'boolean' - }, - canShare: { - description: 'Whether the current user can modify the sharing settings for this file.', - type: 'boolean' - }, - canTrash: { - description: 'Whether the current user can move this file to trash.', - type: 'boolean' - }, - canTrashChildren: { - description: - "Whether the current user can trash children of this folder. This is false when the item isn't a folder. Only populated for items in shared drives.", - type: 'boolean' - }, - canUntrash: { - description: 'Whether the current user can restore this file from trash.', - type: 'boolean' - } - }, - type: 'object' - }, - contentHints: { - description: - 'Additional information about the content of the file. These fields are never populated in responses.', - properties: { - indexableText: { - description: - 'Text to be indexed for the file to improve fullText queries. This is limited to 128 KB in length and might contain HTML elements. For more information, see Manage file metadata.', - type: 'string' - }, - thumbnail: { - description: - 'A thumbnail for the file. This will only be used if Google Drive cannot generate a standard thumbnail.', - properties: { - image: { - description: 'The thumbnail data encoded with URL-safe Base64 (RFC 4648 section 5).', - format: 'byte', - type: 'string' - }, - mimeType: { - description: 'The MIME type of the thumbnail.', - type: 'string' - } - }, - type: 'object' - } - }, - type: 'object' - }, - contentRestrictions: { - description: - 'Restrictions for accessing the content of the file. Only populated if such a restriction exists.', - items: { - $ref: '#/components/schemas/ContentRestriction' - }, - type: 'array' - }, - copyRequiresWriterPermission: { - description: - 'Whether the options to copy, print, or download this file, should be disabled for readers and commenters.', - type: 'boolean' - }, - createdTime: { - description: 'The time at which the file was created (RFC 3339 date-time).', - format: 'date-time', - type: 'string' - }, - description: { - description: 'A short description of the file.', - type: 'string' - }, - driveId: { - description: - 'ID of the shared drive the file resides in. Only populated for items in shared drives.', - type: 'string' - }, - explicitlyTrashed: { - description: - 'Whether the file has been explicitly trashed, as opposed to recursively trashed from a parent folder.', - type: 'boolean' - }, - exportLinks: { - additionalProperties: { - description: 'A mapping from export format to URL', - type: 'string' - }, - description: 'Links for exporting Docs Editors files to specific formats.', - readOnly: true, - type: 'object' - }, - fileExtension: { - description: - 'The final component of fullFileExtension. This is only available for files with binary content in Google Drive.', - type: 'string' - }, - folderColorRgb: { - description: `The color for a folder or shortcut to a folder as an RGB hex string. The supported colors are published in the folderColorPalette field of the About resource. -If an unsupported color is specified, the closest color in the palette will be used instead.`, - type: 'string' - }, - fullFileExtension: { - description: `The full file extension extracted from the name field. Can contain multiple concatenated extensions, such as "tar.gz". This is only available for files with binary content in Google Drive. -This is automatically updated when the name field changes, however it's not cleared if the new name does not contain a valid extension.`, - type: 'string' - }, - hasAugmentedPermissions: { - description: - 'Whether there are permissions directly on this file. This field is only populated for items in shared drives.', - type: 'boolean' - }, - hasThumbnail: { - description: - 'Whether this file has a thumbnail. This does not indicate whether the requesting app has access to the thumbnail. To check access, look for the presence of the thumbnailLink field.', - type: 'boolean' - }, - headRevisionId: { - description: - "The ID of the file's head revision. This is only available for files with binary content in Google Drive.", - type: 'string' - }, - iconLink: { - description: "A static, unauthenticated link to the file's icon.", - type: 'string' - }, - id: { - description: 'The ID of the file.', - type: 'string' - }, - imageMediaMetadata: { - description: 'Additional metadata about image media, if available.', - properties: { - aperture: { - description: 'The aperture used to create the photo (f-number).', - format: 'float', - type: 'number' - }, - cameraMake: { - description: 'The make of the camera used to create the photo.', - type: 'string' - }, - cameraModel: { - description: 'The model of the camera used to create the photo.', - type: 'string' - }, - colorSpace: { - description: 'The color space of the photo.', - type: 'string' - }, - exposureBias: { - description: 'The exposure bias of the photo (APEX value).', - format: 'float', - type: 'number' - }, - exposureMode: { - description: 'The exposure mode used to create the photo.', - type: 'string' - }, - exposureTime: { - description: 'The length of the exposure, in seconds.', - format: 'float', - type: 'number' - }, - flashUsed: { - description: 'Whether a flash was used to create the photo.', - type: 'boolean' - }, - focalLength: { - description: 'The focal length used to create the photo, in millimeters.', - format: 'float', - type: 'number' - }, - height: { - description: 'The height of the image in pixels.', - format: 'int32', - type: 'integer' - }, - isoSpeed: { - description: 'The ISO speed used to create the photo.', - format: 'int32', - type: 'integer' - }, - lens: { - description: 'The lens used to create the photo.', - type: 'string' - }, - location: { - description: 'Geographic location information stored in the image.', - properties: { - altitude: { - description: 'The altitude stored in the image.', - format: 'double', - type: 'number' - }, - latitude: { - description: 'The latitude stored in the image.', - format: 'double', - type: 'number' - }, - longitude: { - description: 'The longitude stored in the image.', - format: 'double', - type: 'number' - } - }, - type: 'object' - }, - maxApertureValue: { - description: - 'The smallest f-number of the lens at the focal length used to create the photo (APEX value).', - format: 'float', - type: 'number' - }, - meteringMode: { - description: 'The metering mode used to create the photo.', - type: 'string' - }, - rotation: { - description: - "The number of clockwise 90-degree rotations applied from the image's original orientation.", - format: 'int32', - type: 'integer' - }, - sensor: { - description: 'The type of sensor used to create the photo.', - type: 'string' - }, - subjectDistance: { - description: 'The distance to the subject of the photo, in meters.', - format: 'int32', - type: 'integer' - }, - time: { - description: 'The date and time the photo was taken (EXIF DateTime).', - type: 'string' - }, - whiteBalance: { - description: 'The white balance mode used to create the photo.', - type: 'string' - }, - width: { - description: 'The width of the image in pixels.', - format: 'int32', - type: 'integer' - } - }, - type: 'object' - }, - isAppAuthorized: { - description: 'Whether the requesting app created or opened the file.', - type: 'boolean' - }, - kind: { - default: 'drive#file', - description: - 'Identifies what kind of resource this is. Value: the fixed string "drive#file".', - type: 'string' - }, - labelInfo: { - description: 'An overview of the labels on the file.', - properties: { - labels: { - description: - 'The set of labels on the file as requested by the label IDs in the includeLabels parameter. By default, no labels are returned.', - items: { - $ref: '#/components/schemas/Label' - }, - type: 'array' - } - }, - type: 'object' - }, - lastModifyingUser: { - $ref: '#/components/schemas/User', - description: 'The last user to modify the file.' - }, - linkShareMetadata: { - description: - 'Contains details about the link URLs that clients are using to refer to this item.', - properties: { - securityUpdateEligible: { - description: 'Whether the file is eligible for security update.', - type: 'boolean' - }, - securityUpdateEnabled: { - description: 'Whether the security update is enabled for this file.', - type: 'boolean' - } - }, - type: 'object' - }, - md5Checksum: { - description: - 'The MD5 checksum for the content of the file. This is only applicable to files with binary content in Google Drive.', - type: 'string' - }, - mimeType: { - description: `The MIME type of the file. -Google Drive will attempt to automatically detect an appropriate value from uploaded content if no value is provided. The value cannot be changed unless a new revision is uploaded. -If a file is created with a Google Doc MIME type, the uploaded content will be imported if possible. The supported import formats are published in the About resource.`, - type: 'string' - }, - modifiedByMe: { - description: 'Whether this user has modified the file.', - type: 'boolean' - }, - modifiedByMeTime: { - description: 'The last time the user modified the file (RFC 3339 date-time).', - format: 'date-time', - type: 'string' - }, - modifiedTime: { - description: `The last time anyone modified the file (RFC 3339 date-time). -Note that setting modifiedTime will also update modifiedByMeTime for the user.`, - format: 'date-time', - type: 'string' - }, - name: { - description: - "The name of the file. This isn't necessarily unique within a folder. Note that for immutable items such as the top-level folders of shared drives, My Drive root folder, and Application Data folder the name is constant.", - type: 'string' - }, - originalFilename: { - description: - 'The original filename of the uploaded content if available, or else the original value of the name field. This is only available for files with binary content in Google Drive.', - type: 'string' - }, - ownedByMe: { - description: 'Whether the user owns the file. Not populated for items in shared drives.', - type: 'boolean' - }, - owners: { - description: - "The owner of this file. Only certain legacy files might have more than one owner. This field isn't populated for items in shared drives.", - items: { - $ref: '#/components/schemas/User' - }, - type: 'array' - }, - parents: { - description: `The IDs of the parent folders that contain the file. -If not specified as part of a create request, the file will be placed directly in the user's My Drive folder. If not specified as part of a copy request, the file will inherit any discoverable parents of the source file. Update requests must use the addParents and removeParents parameters to modify the parents list.`, - items: { - type: 'string' - }, - type: 'array' - }, - permissionIds: { - description: 'List of permission IDs for users with access to this file.', - items: { - type: 'string' - }, - type: 'array' - }, - permissions: { - description: - 'The full list of permissions for the file. This is only available if the requesting user can share the file. Not populated for items in shared drives.', - items: { - $ref: '#/components/schemas/Permission' - }, - type: 'array' - }, - properties: { - additionalProperties: { - type: 'string' - }, - description: `A collection of arbitrary key-value pairs that are visible to all apps. -Entries with null values are cleared in update and copy requests.`, - type: 'object' - }, - quotaBytesUsed: { - description: - 'The number of storage quota bytes used by the file. This includes the head revision as well as previous revisions with keepForever enabled.', - format: 'int64', - type: 'string' - }, - resourceKey: { - description: 'A key needed to access the item via a shared link.', - type: 'string' - }, - sha1Checksum: { - description: - "The SHA1 checksum associated with this file, if available. This field is only populated for files with content stored in Google Drive; it's not populated for Docs Editors or shortcut files.", - type: 'string' - }, - sha256Checksum: { - description: - "The SHA256 checksum associated with this file, if available. This field is only populated for files with content stored in Google Drive; it's not populated for Docs Editors or shortcut files.", - type: 'string' - }, - shared: { - description: 'Whether the file has been shared. Not populated for items in shared drives.', - type: 'boolean' - }, - sharedWithMeTime: { - description: - 'The time at which the file was shared with the user, if applicable (RFC 3339 date-time).', - format: 'date-time', - type: 'string' - }, - sharingUser: { - $ref: '#/components/schemas/User', - description: 'The user who shared the file with the requesting user, if applicable.' - }, - shortcutDetails: { - description: - 'Shortcut file details. Only populated for shortcut files, which have the mimeType field set to application/vnd.google-apps.shortcut.', - properties: { - targetId: { - description: 'The ID of the file that this shortcut points to.', - type: 'string' - }, - targetMimeType: { - description: - "The MIME type of the file that this shortcut points to. The value of this field is a snapshot of the target's MIME type, captured when the shortcut is created.", - type: 'string' - }, - targetResourceKey: { - description: 'The ResourceKey for the target file.', - type: 'string' - } - }, - type: 'object' - }, - size: { - description: - "The size of the file's content in bytes. This field is populated for files with binary content stored in Google Drive and for Docs Editors files; it's not populated for shortcuts or folders.", - format: 'int64', - type: 'string' - }, - spaces: { - description: - "The list of spaces that contain the file. The currently supported values are 'drive', 'appDataFolder' and 'photos'.", - items: { - type: 'string' - }, - type: 'array' - }, - starred: { - description: 'Whether the user has starred the file.', - type: 'boolean' - }, - teamDriveId: { - description: 'Deprecated - use driveId instead.', - type: 'string' - }, - thumbnailLink: { - description: - "A short-lived link to the file's thumbnail, if available. Typically lasts on the order of hours. Only populated when the requesting app can access the file's content. If the file isn't shared publicly, the URL returned in Files.thumbnailLink must be fetched using a credentialed request.", - type: 'string' - }, - thumbnailVersion: { - description: 'The thumbnail version for use in thumbnail cache invalidation.', - format: 'int64', - type: 'string' - }, - trashed: { - description: - 'Whether the file has been trashed, either explicitly or from a trashed parent folder. Only the owner can trash a file. The trashed item is excluded from all files.list responses returned for any user who does not own the file. However, all users with access to the file can see the trashed item metadata in an API response. All users with access can copy, download, export, and share the file.', - type: 'boolean' - }, - trashedTime: { - description: - 'The time that the item was trashed (RFC 3339 date-time). Only populated for items in shared drives.', - format: 'date-time', - type: 'string' - }, - trashingUser: { - $ref: '#/components/schemas/User', - description: - 'If the file has been explicitly trashed, the user who trashed it. Only populated for items in shared drives.' - }, - version: { - description: - 'A monotonically increasing version number for the file. This reflects every change made to the file on the server, even those not visible to the user.', - format: 'int64', - type: 'string' - }, - videoMediaMetadata: { - description: - 'Additional metadata about video media. This might not be available immediately upon upload.', - properties: { - durationMillis: { - description: 'The duration of the video in milliseconds.', - format: 'int64', - type: 'string' - }, - height: { - description: 'The height of the video in pixels.', - format: 'int32', - type: 'integer' - }, - width: { - description: 'The width of the video in pixels.', - format: 'int32', - type: 'integer' - } - }, - type: 'object' - }, - viewedByMe: { - description: 'Whether this user has viewed the file.', - type: 'boolean' - }, - viewedByMeTime: { - description: 'The last time the user viewed the file (RFC 3339 date-time).', - format: 'date-time', - type: 'string' - }, - viewersCanCopyContent: { - description: 'Deprecated - use copyRequiresWriterPermission instead.', - type: 'boolean' - }, - webContentLink: { - description: - 'A link for downloading the content of the file in a browser. This is only available for files with binary content in Google Drive.', - type: 'string' - }, - webViewLink: { - description: - 'A link for opening the file in a relevant Google editor or viewer in a browser.', - type: 'string' - }, - writersCanShare: { - description: - "Whether users with only writer permission can modify the file's permissions. Not populated for items in shared drives.", - type: 'boolean' - } - }, - type: 'object' -} as const - -export const FileListSchema = { - description: 'A list of files.', - properties: { - files: { - description: - 'The list of files. If nextPageToken is populated, then this list may be incomplete and an additional page of results should be fetched.', - items: { - $ref: '#/components/schemas/File' - }, - type: 'array' - }, - incompleteSearch: { - description: - 'Whether the search process was incomplete. If true, then some search results may be missing, since all documents were not searched. This may occur when searching multiple drives with the "allDrives" corpora, but all corpora could not be searched. When this happens, it is suggested that clients narrow their query by choosing a different corpus such as "user" or "drive".', - type: 'boolean' - }, - kind: { - default: 'drive#fileList', - description: - 'Identifies what kind of resource this is. Value: the fixed string "drive#fileList".', - type: 'string' - }, - nextPageToken: { - description: - 'The page token for the next page of files. This will be absent if the end of the files list has been reached. If the token is rejected for any reason, it should be discarded, and pagination should be restarted from the first page of results.', - type: 'string' - } - }, - type: 'object' -} as const - -export const GeneratedIdsSchema = { - description: 'A list of generated file IDs which can be provided in create requests.', - properties: { - ids: { - description: 'The IDs generated for the requesting user in the specified space.', - items: { - type: 'string' - }, - type: 'array' - }, - kind: { - default: 'drive#generatedIds', - description: - 'Identifies what kind of resource this is. Value: the fixed string "drive#generatedIds".', - type: 'string' - }, - space: { - description: 'The type of file that can be created with these IDs.', - type: 'string' - } - }, - type: 'object' -} as const - -export const LabelSchema = { - description: 'Representation of a label and its fields.', - properties: { - fields: { - additionalProperties: { - $ref: '#/components/schemas/LabelField' - }, - description: "A map of the label's fields keyed by the field ID.", - type: 'object' - }, - id: { - description: 'The ID of the label.', - type: 'string' - }, - kind: { - default: 'drive#label', - description: 'This is always drive#label', - type: 'string' - }, - revisionId: { - description: 'The revision ID of the label.', - type: 'string' - } - }, - type: 'object' -} as const - -export const LabelFieldSchema = { - description: 'Representation of a label field.', - properties: { - dateString: { - description: 'Only present if valueType is dateString. RFC 3339 formatted date: YYYY-MM-DD.', - items: { - format: 'date', - type: 'string' - }, - type: 'array' - }, - id: { - description: 'The identifier of this field.', - type: 'string' - }, - integer: { - description: 'Only present if valueType is integer.', - items: { - format: 'int64', - type: 'string' - }, - type: 'array' - }, - kind: { - default: 'drive#labelField', - description: 'This is always drive#labelField.', - type: 'string' - }, - selection: { - description: 'Only present if valueType is selection.', - items: { - type: 'string' - }, - type: 'array' - }, - text: { - description: 'Only present if valueType is text.', - items: { - type: 'string' - }, - type: 'array' - }, - user: { - description: 'Only present if valueType is user.', - items: { - $ref: '#/components/schemas/User' - }, - type: 'array' - }, - valueType: { - description: `The field type. While new values may be supported in the future, the following are currently allowed: -- dateString -- integer -- selection -- text -- user`, - type: 'string' - } - }, - type: 'object' -} as const - -export const LabelFieldModificationSchema = { - description: "A modification to a label's field.", - properties: { - fieldId: { - description: 'The ID of the Field to be modified.', - type: 'string' - }, - kind: { - default: 'drive#labelFieldModification', - description: 'This is always drive#labelFieldModification.', - type: 'string' - }, - setDateValues: { - description: - 'Replaces a dateString field with these new values. The values must be strings in the RFC 3339 full-date format: YYYY-MM-DD.', - items: { - format: 'date', - type: 'string' - }, - type: 'array' - }, - setIntegerValues: { - description: 'Replaces an integer field with these new values.', - items: { - format: 'int64', - type: 'string' - }, - type: 'array' - }, - setSelectionValues: { - description: 'Replaces a selection field with these new values.', - items: { - type: 'string' - }, - type: 'array' - }, - setTextValues: { - description: 'Replaces a text field with these new values.', - items: { - type: 'string' - }, - type: 'array' - }, - setUserValues: { - description: - 'Replaces a user field with these new values. The values must be valid email addresses.', - items: { - type: 'string' - }, - type: 'array' - }, - unsetValues: { - description: 'Unsets the values for this field.', - type: 'boolean' - } - }, - type: 'object' -} as const - -export const LabelListSchema = { - description: 'A list of labels.', - properties: { - kind: { - default: 'drive#labelList', - description: 'This is always drive#labelList', - type: 'string' - }, - labels: { - description: 'The list of labels.', - items: { - $ref: '#/components/schemas/Label' - }, - type: 'array' - }, - nextPageToken: { - description: - 'The page token for the next page of labels. This field will be absent if the end of the list has been reached. If the token is rejected for any reason, it should be discarded, and pagination should be restarted from the first page of results.', - type: 'string' - } - }, - type: 'object' -} as const - -export const LabelModificationSchema = { - description: - 'A modification to a label on a file. A LabelModification can be used to apply a label to a file, update an existing label on a file, or remove a label from a file.', - properties: { - fieldModifications: { - description: "The list of modifications to this label's fields.", - items: { - $ref: '#/components/schemas/LabelFieldModification' - }, - type: 'array' - }, - kind: { - default: 'drive#labelModification', - description: 'This is always drive#labelModification.', - type: 'string' - }, - labelId: { - description: 'The ID of the label to modify.', - type: 'string' - }, - removeLabel: { - description: 'If true, the label will be removed from the file.', - type: 'boolean' - } - }, - type: 'object' -} as const - -export const ModifyLabelsRequestSchema = { - description: - 'A request to modify the set of labels on a file. This request may contain many modifications that will either all succeed or all fail transactionally.', - properties: { - kind: { - default: 'drive#modifyLabelsRequest', - description: 'This is always drive#modifyLabelsRequest', - type: 'string' - }, - labelModifications: { - description: 'The list of modifications to apply to the labels on the file.', - items: { - $ref: '#/components/schemas/LabelModification' - }, - type: 'array' - } - }, - type: 'object' -} as const - -export const ModifyLabelsResponseSchema = { - description: - 'Response to a ModifyLabels request. This contains only those labels which were added or updated by the request.', - properties: { - kind: { - default: 'drive#modifyLabelsResponse', - description: 'This is always drive#modifyLabelsResponse', - type: 'string' - }, - modifiedLabels: { - description: 'The list of labels which were added or updated by the request.', - items: { - $ref: '#/components/schemas/Label' - }, - type: 'array' - } - }, - type: 'object' -} as const - -export const PermissionSchema = { - description: - 'A permission for a file. A permission grants a user, group, domain, or the world access to a file or a folder hierarchy.', - properties: { - allowFileDiscovery: { - description: - 'Whether the permission allows the file to be discovered through search. This is only applicable for permissions of type domain or anyone.', - type: 'boolean' - }, - deleted: { - description: - 'Whether the account associated with this permission has been deleted. This field only pertains to user and group permissions.', - type: 'boolean' - }, - displayName: { - description: `The "pretty" name of the value of the permission. The following is a list of examples for each type of permission: -- user - User's full name, as defined for their Google Account, such as "Joe Smith." -- group - Name of the Google Group, such as "The Company Administrators." -- domain - String domain name, such as "your-company.com." -- anyone - No displayName is present.`, - type: 'string' - }, - domain: { - description: `The domain to which this permission refers. The following options are currently allowed: -- The entire domain, such as "your-company.com." -- A target audience, such as "ID.audience.googledomains.com."`, - type: 'string' - }, - emailAddress: { - description: 'The email address of the user or group to which this permission refers.', - type: 'string' - }, - expirationTime: { - description: `The time at which this permission will expire (RFC 3339 date-time). Expiration times have the following restrictions: -- They cannot be set on shared drive items. -- They can only be set on user and group permissions. -- The time must be in the future. -- The time cannot be more than one year in the future.`, - format: 'date-time', - type: 'string' - }, - id: { - description: - 'The ID of this permission. This is a unique identifier for the grantee, and is published in User resources as permissionId. IDs should be treated as opaque values.', - type: 'string' - }, - kind: { - default: 'drive#permission', - description: - 'Identifies what kind of resource this is. Value: the fixed string "drive#permission".', - type: 'string' - }, - pendingOwner: { - description: - "Whether the account associated with this permission is a pending owner. Only populated for user type permissions for files that aren't in a shared drive.", - type: 'boolean' - }, - permissionDetails: { - description: - "Details of whether the permissions on this shared drive item are inherited or are directly on this item. This is an output-only field that's present only for shared drive items.", - items: { - properties: { - inherited: { - description: - 'Whether this permission is inherited. This field is always populated. This is an output-only field.', - type: 'boolean' - }, - inheritedFrom: { - description: - 'The ID of the item from which this permission is inherited. This is an output-only field.', - type: 'string' - }, - permissionType: { - description: `The permission type for this user. While new values may be added in future, the following are currently allowed: -- file -- member`, - type: 'string' - }, - role: { - description: `The primary role for this user. While new values may be added in the future, the following are currently allowed: -- organizer -- fileOrganizer -- writer -- commenter -- reader`, - type: 'string' - } - }, - type: 'object' - }, - readOnly: true, - type: 'array' - }, - photoLink: { - description: "A link to the user's profile photo, if available.", - type: 'string' - }, - role: { - description: `The role granted by this permission. While new values may be supported in the future, the following are currently allowed: -- owner -- organizer -- fileOrganizer -- writer -- commenter -- reader`, - type: 'string' - }, - teamDrivePermissionDetails: { - description: 'Deprecated - use permissionDetails instead.', - items: { - properties: { - inherited: { - description: 'Deprecated - use permissionDetails/inherited instead.', - type: 'boolean' - }, - inheritedFrom: { - description: 'Deprecated - use permissionDetails/inheritedFrom instead.', - type: 'string' - }, - role: { - description: 'Deprecated - use permissionDetails/role instead.', - type: 'string' - }, - teamDrivePermissionType: { - description: 'Deprecated - use permissionDetails/permissionType instead.', - type: 'string' - } - }, - type: 'object' - }, - readOnly: true, - type: 'array' - }, - type: { - description: `The type of the grantee. Valid values are: -- user -- group -- domain -- anyone When creating a permission, if type is user or group, you must provide an emailAddress for the user or group. When type is domain, you must provide a domain. There isn't extra information required for the anyone type.`, - type: 'string' - }, - view: { - description: - 'Indicates the view for this permission. Only populated for permissions that belong to a view. published is the only supported value.', - type: 'string' - } - }, - type: 'object' -} as const - -export const PermissionListSchema = { - description: 'A list of permissions for a file.', - properties: { - kind: { - default: 'drive#permissionList', - description: - 'Identifies what kind of resource this is. Value: the fixed string "drive#permissionList".', - type: 'string' - }, - nextPageToken: { - description: - 'The page token for the next page of permissions. This field will be absent if the end of the permissions list has been reached. If the token is rejected for any reason, it should be discarded, and pagination should be restarted from the first page of results.', - type: 'string' - }, - permissions: { - description: - 'The list of permissions. If nextPageToken is populated, then this list may be incomplete and an additional page of results should be fetched.', - items: { - $ref: '#/components/schemas/Permission' - }, - type: 'array' - } - }, - type: 'object' -} as const - -export const ReplySchema = { - description: 'A reply to a comment on a file.', - properties: { - action: { - description: `The action the reply performed to the parent comment. Valid values are: -- resolve -- reopen`, - type: 'string' - }, - author: { - $ref: '#/components/schemas/User', - description: - "The author of the reply. The author's email address and permission ID will not be populated." - }, - content: { - description: - 'The plain text content of the reply. This field is used for setting the content, while htmlContent should be displayed. This is required on creates if no action is specified.', - type: 'string' - }, - createdTime: { - description: 'The time at which the reply was created (RFC 3339 date-time).', - format: 'date-time', - type: 'string' - }, - deleted: { - description: 'Whether the reply has been deleted. A deleted reply has no content.', - type: 'boolean' - }, - htmlContent: { - description: 'The content of the reply with HTML formatting.', - type: 'string' - }, - id: { - description: 'The ID of the reply.', - type: 'string' - }, - kind: { - default: 'drive#reply', - description: - 'Identifies what kind of resource this is. Value: the fixed string "drive#reply".', - type: 'string' - }, - modifiedTime: { - description: 'The last time the reply was modified (RFC 3339 date-time).', - format: 'date-time', - type: 'string' - } - }, - type: 'object' -} as const - -export const ReplyListSchema = { - description: 'A list of replies to a comment on a file.', - properties: { - kind: { - default: 'drive#replyList', - description: - 'Identifies what kind of resource this is. Value: the fixed string "drive#replyList".', - type: 'string' - }, - nextPageToken: { - description: - 'The page token for the next page of replies. This will be absent if the end of the replies list has been reached. If the token is rejected for any reason, it should be discarded, and pagination should be restarted from the first page of results.', - type: 'string' - }, - replies: { - description: - 'The list of replies. If nextPageToken is populated, then this list may be incomplete and an additional page of results should be fetched.', - items: { - $ref: '#/components/schemas/Reply' - }, - type: 'array' - } - }, - type: 'object' -} as const - -export const RevisionSchema = { - description: 'The metadata for a revision to a file.', - properties: { - exportLinks: { - additionalProperties: { - description: 'A mapping from export format to URL', - type: 'string' - }, - description: 'Links for exporting Docs Editors files to specific formats.', - type: 'object' - }, - id: { - description: 'The ID of the revision.', - type: 'string' - }, - keepForever: { - description: `Whether to keep this revision forever, even if it is no longer the head revision. If not set, the revision will be automatically purged 30 days after newer content is uploaded. This can be set on a maximum of 200 revisions for a file. -This field is only applicable to files with binary content in Drive.`, - type: 'boolean' - }, - kind: { - default: 'drive#revision', - description: - 'Identifies what kind of resource this is. Value: the fixed string "drive#revision".', - type: 'string' - }, - lastModifyingUser: { - $ref: '#/components/schemas/User', - description: 'The last user to modify this revision.' - }, - md5Checksum: { - description: - "The MD5 checksum of the revision's content. This is only applicable to files with binary content in Drive.", - type: 'string' - }, - mimeType: { - description: 'The MIME type of the revision.', - type: 'string' - }, - modifiedTime: { - description: 'The last time the revision was modified (RFC 3339 date-time).', - format: 'date-time', - type: 'string' - }, - originalFilename: { - description: - 'The original filename used to create this revision. This is only applicable to files with binary content in Drive.', - type: 'string' - }, - publishAuto: { - description: - 'Whether subsequent revisions will be automatically republished. This is only applicable to Docs Editors files.', - type: 'boolean' - }, - published: { - description: - 'Whether this revision is published. This is only applicable to Docs Editors files.', - type: 'boolean' - }, - publishedLink: { - description: - 'A link to the published revision. This is only populated for Google Sites files.', - type: 'string' - }, - publishedOutsideDomain: { - description: - 'Whether this revision is published outside the domain. This is only applicable to Docs Editors files.', - type: 'boolean' - }, - size: { - description: - "The size of the revision's content in bytes. This is only applicable to files with binary content in Drive.", - format: 'int64', - type: 'string' - } - }, - type: 'object' -} as const - -export const RevisionListSchema = { - description: 'A list of revisions of a file.', - properties: { - kind: { - default: 'drive#revisionList', - description: - 'Identifies what kind of resource this is. Value: the fixed string "drive#revisionList".', - type: 'string' - }, - nextPageToken: { - description: - 'The page token for the next page of revisions. This will be absent if the end of the revisions list has been reached. If the token is rejected for any reason, it should be discarded, and pagination should be restarted from the first page of results.', - type: 'string' - }, - revisions: { - description: - 'The list of revisions. If nextPageToken is populated, then this list may be incomplete and an additional page of results should be fetched.', - items: { - $ref: '#/components/schemas/Revision' - }, - type: 'array' - } - }, - type: 'object' -} as const - -export const StartPageTokenSchema = { - properties: { - kind: { - default: 'drive#startPageToken', - description: - 'Identifies what kind of resource this is. Value: the fixed string "drive#startPageToken".', - type: 'string' - }, - startPageToken: { - description: 'The starting page token for listing changes.', - type: 'string' - } - }, - type: 'object' -} as const - -export const TeamDriveSchema = { - description: 'Deprecated: use the drive collection instead.', - properties: { - backgroundImageFile: { - description: - "An image file and cropping parameters from which a background image for this Team Drive is set. This is a write only field; it can only be set on drive.teamdrives.update requests that don't set themeId. When specified, all fields of the backgroundImageFile must be set.", - properties: { - id: { - description: 'The ID of an image file in Drive to use for the background image.', - type: 'string' - }, - width: { - description: - 'The width of the cropped image in the closed range of 0 to 1. This value represents the width of the cropped image divided by the width of the entire image. The height is computed by applying a width to height aspect ratio of 80 to 9. The resulting image must be at least 1280 pixels wide and 144 pixels high.', - format: 'float', - type: 'number' - }, - xCoordinate: { - description: - 'The X coordinate of the upper left corner of the cropping area in the background image. This is a value in the closed range of 0 to 1. This value represents the horizontal distance from the left side of the entire image to the left side of the cropping area divided by the width of the entire image.', - format: 'float', - type: 'number' - }, - yCoordinate: { - description: - 'The Y coordinate of the upper left corner of the cropping area in the background image. This is a value in the closed range of 0 to 1. This value represents the vertical distance from the top side of the entire image to the top side of the cropping area divided by the height of the entire image.', - format: 'float', - type: 'number' - } - }, - type: 'object' - }, - backgroundImageLink: { - description: "A short-lived link to this Team Drive's background image.", - type: 'string' - }, - capabilities: { - description: 'Capabilities the current user has on this Team Drive.', - properties: { - canAddChildren: { - description: 'Whether the current user can add children to folders in this Team Drive.', - type: 'boolean' - }, - canChangeCopyRequiresWriterPermissionRestriction: { - description: - 'Whether the current user can change the copyRequiresWriterPermission restriction of this Team Drive.', - type: 'boolean' - }, - canChangeDomainUsersOnlyRestriction: { - description: - 'Whether the current user can change the domainUsersOnly restriction of this Team Drive.', - type: 'boolean' - }, - canChangeSharingFoldersRequiresOrganizerPermissionRestriction: { - description: - 'Whether the current user can change the sharingFoldersRequiresOrganizerPermission restriction of this Team Drive.', - type: 'boolean' - }, - canChangeTeamDriveBackground: { - description: 'Whether the current user can change the background of this Team Drive.', - type: 'boolean' - }, - canChangeTeamMembersOnlyRestriction: { - description: - 'Whether the current user can change the teamMembersOnly restriction of this Team Drive.', - type: 'boolean' - }, - canComment: { - description: 'Whether the current user can comment on files in this Team Drive.', - type: 'boolean' - }, - canCopy: { - description: 'Whether the current user can copy files in this Team Drive.', - type: 'boolean' - }, - canDeleteChildren: { - description: - 'Whether the current user can delete children from folders in this Team Drive.', - type: 'boolean' - }, - canDeleteTeamDrive: { - description: - 'Whether the current user can delete this Team Drive. Attempting to delete the Team Drive may still fail if there are untrashed items inside the Team Drive.', - type: 'boolean' - }, - canDownload: { - description: 'Whether the current user can download files in this Team Drive.', - type: 'boolean' - }, - canEdit: { - description: 'Whether the current user can edit files in this Team Drive', - type: 'boolean' - }, - canListChildren: { - description: - 'Whether the current user can list the children of folders in this Team Drive.', - type: 'boolean' - }, - canManageMembers: { - description: - 'Whether the current user can add members to this Team Drive or remove them or change their role.', - type: 'boolean' - }, - canReadRevisions: { - description: - 'Whether the current user can read the revisions resource of files in this Team Drive.', - type: 'boolean' - }, - canRemoveChildren: { - description: 'Deprecated - use canDeleteChildren or canTrashChildren instead.', - type: 'boolean' - }, - canRename: { - description: 'Whether the current user can rename files or folders in this Team Drive.', - type: 'boolean' - }, - canRenameTeamDrive: { - description: 'Whether the current user can rename this Team Drive.', - type: 'boolean' - }, - canResetTeamDriveRestrictions: { - description: - 'Whether the current user can reset the Team Drive restrictions to defaults.', - type: 'boolean' - }, - canShare: { - description: 'Whether the current user can share files or folders in this Team Drive.', - type: 'boolean' - }, - canTrashChildren: { - description: - 'Whether the current user can trash children from folders in this Team Drive.', - type: 'boolean' - } - }, - type: 'object' - }, - colorRgb: { - description: - 'The color of this Team Drive as an RGB hex string. It can only be set on a drive.teamdrives.update request that does not set themeId.', - type: 'string' - }, - createdTime: { - description: 'The time at which the Team Drive was created (RFC 3339 date-time).', - format: 'date-time', - type: 'string' - }, - id: { - description: - 'The ID of this Team Drive which is also the ID of the top level folder of this Team Drive.', - type: 'string' - }, - kind: { - default: 'drive#teamDrive', - description: - 'Identifies what kind of resource this is. Value: the fixed string "drive#teamDrive".', - type: 'string' - }, - name: { - description: 'The name of this Team Drive.', - type: 'string' - }, - orgUnitId: { - description: - 'The organizational unit of this shared drive. This field is only populated on drives.list responses when the useDomainAdminAccess parameter is set to true.', - type: 'string' - }, - restrictions: { - description: - 'A set of restrictions that apply to this Team Drive or items inside this Team Drive.', - properties: { - adminManagedRestrictions: { - description: - 'Whether administrative privileges on this Team Drive are required to modify restrictions.', - type: 'boolean' - }, - copyRequiresWriterPermission: { - description: - 'Whether the options to copy, print, or download files inside this Team Drive, should be disabled for readers and commenters. When this restriction is set to true, it will override the similarly named field to true for any file inside this Team Drive.', - type: 'boolean' - }, - domainUsersOnly: { - description: - 'Whether access to this Team Drive and items inside this Team Drive is restricted to users of the domain to which this Team Drive belongs. This restriction may be overridden by other sharing policies controlled outside of this Team Drive.', - type: 'boolean' - }, - sharingFoldersRequiresOrganizerPermission: { - description: - 'If true, only users with the organizer role can share folders. If false, users with either the organizer role or the file organizer role can share folders.', - type: 'boolean' - }, - teamMembersOnly: { - description: - 'Whether access to items inside this Team Drive is restricted to members of this Team Drive.', - type: 'boolean' - } - }, - type: 'object' - }, - themeId: { - description: - "The ID of the theme from which the background image and color will be set. The set of possible teamDriveThemes can be retrieved from a drive.about.get response. When not specified on a drive.teamdrives.create request, a random theme is chosen from which the background image and color are set. This is a write-only field; it can only be set on requests that don't set colorRgb or backgroundImageFile.", - type: 'string' - } - }, - type: 'object' -} as const - -export const TeamDriveListSchema = { - description: 'A list of Team Drives.', - properties: { - kind: { - default: 'drive#teamDriveList', - description: - 'Identifies what kind of resource this is. Value: the fixed string "drive#teamDriveList".', - type: 'string' - }, - nextPageToken: { - description: - 'The page token for the next page of Team Drives. This will be absent if the end of the Team Drives list has been reached. If the token is rejected for any reason, it should be discarded, and pagination should be restarted from the first page of results.', - type: 'string' - }, - teamDrives: { - description: - 'The list of Team Drives. If nextPageToken is populated, then this list may be incomplete and an additional page of results should be fetched.', - items: { - $ref: '#/components/schemas/TeamDrive' - }, - type: 'array' - } - }, - type: 'object' -} as const - -export const UserSchema = { - description: 'Information about a Drive user.', - properties: { - displayName: { - description: 'A plain text displayable name for this user.', - type: 'string' - }, - emailAddress: { - description: - 'The email address of the user. This may not be present in certain contexts if the user has not made their email address visible to the requester.', - type: 'string' - }, - kind: { - default: 'drive#user', - description: - 'Identifies what kind of resource this is. Value: the fixed string "drive#user".', - type: 'string' - }, - me: { - description: 'Whether this user is the requesting user.', - type: 'boolean' - }, - permissionId: { - description: "The user's ID as visible in Permission resources.", - type: 'string' - }, - photoLink: { - description: "A link to the user's profile photo, if available.", - type: 'string' - } - }, - type: 'object' -} as const - -export const FileWritableSchema = { - description: 'The metadata for a file.', - properties: { - appProperties: { - additionalProperties: { - type: 'string' - }, - description: `A collection of arbitrary key-value pairs that are private to the requesting app. -Entries with null values are cleared in update and copy requests. These properties can only be retrieved using an authenticated request. An authenticated request uses an access token obtained with an OAuth 2 client ID. You cannot use an API key to retrieve private properties.`, - type: 'object' - }, - capabilities: { - description: - 'Capabilities the current user has on this file. Each capability corresponds to a fine-grained action that a user can take.', - properties: { - canAcceptOwnership: { - description: - 'Whether the current user is the pending owner of the file. Not populated for shared drive files.', - type: 'boolean' - }, - canAddChildren: { - description: - "Whether the current user can add children to this folder. This is always false when the item isn't a folder.", - type: 'boolean' - }, - canAddFolderFromAnotherDrive: { - description: - "Whether the current user can add a folder from another drive (different shared drive or My Drive) to this folder. This is false when the item isn't a folder. Only populated for items in shared drives.", - type: 'boolean' - }, - canAddMyDriveParent: { - description: - 'Whether the current user can add a parent for the item without removing an existing parent in the same request. Not populated for shared drive files.', - type: 'boolean' - }, - canChangeCopyRequiresWriterPermission: { - description: - 'Whether the current user can change the copyRequiresWriterPermission restriction of this file.', - type: 'boolean' - }, - canChangeSecurityUpdateEnabled: { - description: - 'Whether the current user can change the securityUpdateEnabled field on link share metadata.', - type: 'boolean' - }, - canChangeViewersCanCopyContent: { - description: 'Deprecated', - type: 'boolean' - }, - canComment: { - description: 'Whether the current user can comment on this file.', - type: 'boolean' - }, - canCopy: { - description: - "Whether the current user can copy this file. For an item in a shared drive, whether the current user can copy non-folder descendants of this item, or this item itself if it's not a folder.", - type: 'boolean' - }, - canDelete: { - description: 'Whether the current user can delete this file.', - type: 'boolean' - }, - canDeleteChildren: { - description: - "Whether the current user can delete children of this folder. This is false when the item isn't a folder. Only populated for items in shared drives.", - type: 'boolean' - }, - canDownload: { - description: 'Whether the current user can download this file.', - type: 'boolean' - }, - canEdit: { - description: - 'Whether the current user can edit this file. Other factors might limit the type of changes a user can make to a file. For example, see canChangeCopyRequiresWriterPermission or canModifyContent.', - type: 'boolean' - }, - canListChildren: { - description: - "Whether the current user can list the children of this folder. This is always false when the item isn't a folder.", - type: 'boolean' - }, - canModifyContent: { - description: 'Whether the current user can modify the content of this file.', - type: 'boolean' - }, - canModifyContentRestriction: { - description: 'Whether the current user can modify restrictions on content of this file.', - type: 'boolean' - }, - canModifyLabels: { - description: 'Whether the current user can modify the labels on this file.', - type: 'boolean' - }, - canMoveChildrenOutOfDrive: { - description: - "Whether the current user can move children of this folder outside of the shared drive. This is false when the item isn't a folder. Only populated for items in shared drives.", - type: 'boolean' - }, - canMoveChildrenOutOfTeamDrive: { - description: 'Deprecated - use canMoveChildrenOutOfDrive instead.', - type: 'boolean' - }, - canMoveChildrenWithinDrive: { - description: - "Whether the current user can move children of this folder within this shared drive or My Drive. This is false when the item isn't a folder. Note that a request to move the child might still fail depending on the current user's access to the child and to the destination folder.", - type: 'boolean' - }, - canMoveChildrenWithinTeamDrive: { - description: 'Deprecated - use canMoveChildrenWithinDrive instead.', - type: 'boolean' - }, - canMoveItemIntoTeamDrive: { - description: 'Deprecated - use canMoveItemOutOfDrive instead.', - type: 'boolean' - }, - canMoveItemOutOfDrive: { - description: - "Whether the current user can move this item outside of this shared drive or My Drive by changing its parent. Note that a request to change the parent of the item might still fail depending on the new parent that's being added.", - type: 'boolean' - }, - canMoveItemOutOfTeamDrive: { - description: 'Deprecated - use canMoveItemOutOfDrive instead.', - type: 'boolean' - }, - canMoveItemWithinDrive: { - description: - "Whether the current user can move this item within this shared drive or My Drive. Note that a request to change the parent of the item might still fail depending on the new parent that's being added and the parent that's being removed.", - type: 'boolean' - }, - canMoveItemWithinTeamDrive: { - description: 'Deprecated - use canMoveItemWithinDrive instead.', - type: 'boolean' - }, - canMoveTeamDriveItem: { - description: 'Deprecated - use canMoveItemWithinDrive or canMoveItemOutOfDrive instead.', - type: 'boolean' - }, - canReadDrive: { - description: - 'Whether the current user can read the shared drive to which this file belongs. Only populated for items in shared drives.', - type: 'boolean' - }, - canReadLabels: { - description: 'Whether the current user can read the labels on this file.', - type: 'boolean' - }, - canReadRevisions: { - description: - "Whether the current user can read the revisions resource of this file. For a shared drive item, whether revisions of non-folder descendants of this item, or this item itself if it's not a folder, can be read.", - type: 'boolean' - }, - canReadTeamDrive: { - description: 'Deprecated - use canReadDrive instead.', - type: 'boolean' - }, - canRemoveChildren: { - description: - "Whether the current user can remove children from this folder. This is always false when the item isn't a folder. For a folder in a shared drive, use canDeleteChildren or canTrashChildren instead.", - type: 'boolean' - }, - canRemoveMyDriveParent: { - description: - 'Whether the current user can remove a parent from the item without adding another parent in the same request. Not populated for shared drive files.', - type: 'boolean' - }, - canRename: { - description: 'Whether the current user can rename this file.', - type: 'boolean' - }, - canShare: { - description: 'Whether the current user can modify the sharing settings for this file.', - type: 'boolean' - }, - canTrash: { - description: 'Whether the current user can move this file to trash.', - type: 'boolean' - }, - canTrashChildren: { - description: - "Whether the current user can trash children of this folder. This is false when the item isn't a folder. Only populated for items in shared drives.", - type: 'boolean' - }, - canUntrash: { - description: 'Whether the current user can restore this file from trash.', - type: 'boolean' - } - }, - type: 'object' - }, - contentHints: { - description: - 'Additional information about the content of the file. These fields are never populated in responses.', - properties: { - indexableText: { - description: - 'Text to be indexed for the file to improve fullText queries. This is limited to 128 KB in length and might contain HTML elements. For more information, see Manage file metadata.', - type: 'string' - }, - thumbnail: { - description: - 'A thumbnail for the file. This will only be used if Google Drive cannot generate a standard thumbnail.', - properties: { - image: { - description: 'The thumbnail data encoded with URL-safe Base64 (RFC 4648 section 5).', - format: 'byte', - type: 'string' - }, - mimeType: { - description: 'The MIME type of the thumbnail.', - type: 'string' - } - }, - type: 'object' - } - }, - type: 'object' - }, - contentRestrictions: { - description: - 'Restrictions for accessing the content of the file. Only populated if such a restriction exists.', - items: { - $ref: '#/components/schemas/ContentRestriction' - }, - type: 'array' - }, - copyRequiresWriterPermission: { - description: - 'Whether the options to copy, print, or download this file, should be disabled for readers and commenters.', - type: 'boolean' - }, - createdTime: { - description: 'The time at which the file was created (RFC 3339 date-time).', - format: 'date-time', - type: 'string' - }, - description: { - description: 'A short description of the file.', - type: 'string' - }, - driveId: { - description: - 'ID of the shared drive the file resides in. Only populated for items in shared drives.', - type: 'string' - }, - explicitlyTrashed: { - description: - 'Whether the file has been explicitly trashed, as opposed to recursively trashed from a parent folder.', - type: 'boolean' - }, - fileExtension: { - description: - 'The final component of fullFileExtension. This is only available for files with binary content in Google Drive.', - type: 'string' - }, - folderColorRgb: { - description: `The color for a folder or shortcut to a folder as an RGB hex string. The supported colors are published in the folderColorPalette field of the About resource. -If an unsupported color is specified, the closest color in the palette will be used instead.`, - type: 'string' - }, - fullFileExtension: { - description: `The full file extension extracted from the name field. Can contain multiple concatenated extensions, such as "tar.gz". This is only available for files with binary content in Google Drive. -This is automatically updated when the name field changes, however it's not cleared if the new name does not contain a valid extension.`, - type: 'string' - }, - hasAugmentedPermissions: { - description: - 'Whether there are permissions directly on this file. This field is only populated for items in shared drives.', - type: 'boolean' - }, - hasThumbnail: { - description: - 'Whether this file has a thumbnail. This does not indicate whether the requesting app has access to the thumbnail. To check access, look for the presence of the thumbnailLink field.', - type: 'boolean' - }, - headRevisionId: { - description: - "The ID of the file's head revision. This is only available for files with binary content in Google Drive.", - type: 'string' - }, - iconLink: { - description: "A static, unauthenticated link to the file's icon.", - type: 'string' - }, - id: { - description: 'The ID of the file.', - type: 'string' - }, - imageMediaMetadata: { - description: 'Additional metadata about image media, if available.', - properties: { - aperture: { - description: 'The aperture used to create the photo (f-number).', - format: 'float', - type: 'number' - }, - cameraMake: { - description: 'The make of the camera used to create the photo.', - type: 'string' - }, - cameraModel: { - description: 'The model of the camera used to create the photo.', - type: 'string' - }, - colorSpace: { - description: 'The color space of the photo.', - type: 'string' - }, - exposureBias: { - description: 'The exposure bias of the photo (APEX value).', - format: 'float', - type: 'number' - }, - exposureMode: { - description: 'The exposure mode used to create the photo.', - type: 'string' - }, - exposureTime: { - description: 'The length of the exposure, in seconds.', - format: 'float', - type: 'number' - }, - flashUsed: { - description: 'Whether a flash was used to create the photo.', - type: 'boolean' - }, - focalLength: { - description: 'The focal length used to create the photo, in millimeters.', - format: 'float', - type: 'number' - }, - height: { - description: 'The height of the image in pixels.', - format: 'int32', - type: 'integer' - }, - isoSpeed: { - description: 'The ISO speed used to create the photo.', - format: 'int32', - type: 'integer' - }, - lens: { - description: 'The lens used to create the photo.', - type: 'string' - }, - location: { - description: 'Geographic location information stored in the image.', - properties: { - altitude: { - description: 'The altitude stored in the image.', - format: 'double', - type: 'number' - }, - latitude: { - description: 'The latitude stored in the image.', - format: 'double', - type: 'number' - }, - longitude: { - description: 'The longitude stored in the image.', - format: 'double', - type: 'number' - } - }, - type: 'object' - }, - maxApertureValue: { - description: - 'The smallest f-number of the lens at the focal length used to create the photo (APEX value).', - format: 'float', - type: 'number' - }, - meteringMode: { - description: 'The metering mode used to create the photo.', - type: 'string' - }, - rotation: { - description: - "The number of clockwise 90-degree rotations applied from the image's original orientation.", - format: 'int32', - type: 'integer' - }, - sensor: { - description: 'The type of sensor used to create the photo.', - type: 'string' - }, - subjectDistance: { - description: 'The distance to the subject of the photo, in meters.', - format: 'int32', - type: 'integer' - }, - time: { - description: 'The date and time the photo was taken (EXIF DateTime).', - type: 'string' - }, - whiteBalance: { - description: 'The white balance mode used to create the photo.', - type: 'string' - }, - width: { - description: 'The width of the image in pixels.', - format: 'int32', - type: 'integer' - } - }, - type: 'object' - }, - isAppAuthorized: { - description: 'Whether the requesting app created or opened the file.', - type: 'boolean' - }, - kind: { - default: 'drive#file', - description: - 'Identifies what kind of resource this is. Value: the fixed string "drive#file".', - type: 'string' - }, - labelInfo: { - description: 'An overview of the labels on the file.', - properties: { - labels: { - description: - 'The set of labels on the file as requested by the label IDs in the includeLabels parameter. By default, no labels are returned.', - items: { - $ref: '#/components/schemas/Label' - }, - type: 'array' - } - }, - type: 'object' - }, - lastModifyingUser: { - $ref: '#/components/schemas/User', - description: 'The last user to modify the file.' - }, - linkShareMetadata: { - description: - 'Contains details about the link URLs that clients are using to refer to this item.', - properties: { - securityUpdateEligible: { - description: 'Whether the file is eligible for security update.', - type: 'boolean' - }, - securityUpdateEnabled: { - description: 'Whether the security update is enabled for this file.', - type: 'boolean' - } - }, - type: 'object' - }, - md5Checksum: { - description: - 'The MD5 checksum for the content of the file. This is only applicable to files with binary content in Google Drive.', - type: 'string' - }, - mimeType: { - description: `The MIME type of the file. -Google Drive will attempt to automatically detect an appropriate value from uploaded content if no value is provided. The value cannot be changed unless a new revision is uploaded. -If a file is created with a Google Doc MIME type, the uploaded content will be imported if possible. The supported import formats are published in the About resource.`, - type: 'string' - }, - modifiedByMe: { - description: 'Whether this user has modified the file.', - type: 'boolean' - }, - modifiedByMeTime: { - description: 'The last time the user modified the file (RFC 3339 date-time).', - format: 'date-time', - type: 'string' - }, - modifiedTime: { - description: `The last time anyone modified the file (RFC 3339 date-time). -Note that setting modifiedTime will also update modifiedByMeTime for the user.`, - format: 'date-time', - type: 'string' - }, - name: { - description: - "The name of the file. This isn't necessarily unique within a folder. Note that for immutable items such as the top-level folders of shared drives, My Drive root folder, and Application Data folder the name is constant.", - type: 'string' - }, - originalFilename: { - description: - 'The original filename of the uploaded content if available, or else the original value of the name field. This is only available for files with binary content in Google Drive.', - type: 'string' - }, - ownedByMe: { - description: 'Whether the user owns the file. Not populated for items in shared drives.', - type: 'boolean' - }, - owners: { - description: - "The owner of this file. Only certain legacy files might have more than one owner. This field isn't populated for items in shared drives.", - items: { - $ref: '#/components/schemas/User' - }, - type: 'array' - }, - parents: { - description: `The IDs of the parent folders that contain the file. -If not specified as part of a create request, the file will be placed directly in the user's My Drive folder. If not specified as part of a copy request, the file will inherit any discoverable parents of the source file. Update requests must use the addParents and removeParents parameters to modify the parents list.`, - items: { - type: 'string' - }, - type: 'array' - }, - permissionIds: { - description: 'List of permission IDs for users with access to this file.', - items: { - type: 'string' - }, - type: 'array' - }, - permissions: { - description: - 'The full list of permissions for the file. This is only available if the requesting user can share the file. Not populated for items in shared drives.', - items: { - $ref: '#/components/schemas/PermissionWritable' - }, - type: 'array' - }, - properties: { - additionalProperties: { - type: 'string' - }, - description: `A collection of arbitrary key-value pairs that are visible to all apps. -Entries with null values are cleared in update and copy requests.`, - type: 'object' - }, - quotaBytesUsed: { - description: - 'The number of storage quota bytes used by the file. This includes the head revision as well as previous revisions with keepForever enabled.', - format: 'int64', - type: 'string' - }, - resourceKey: { - description: 'A key needed to access the item via a shared link.', - type: 'string' - }, - sha1Checksum: { - description: - "The SHA1 checksum associated with this file, if available. This field is only populated for files with content stored in Google Drive; it's not populated for Docs Editors or shortcut files.", - type: 'string' - }, - sha256Checksum: { - description: - "The SHA256 checksum associated with this file, if available. This field is only populated for files with content stored in Google Drive; it's not populated for Docs Editors or shortcut files.", - type: 'string' - }, - shared: { - description: 'Whether the file has been shared. Not populated for items in shared drives.', - type: 'boolean' - }, - sharedWithMeTime: { - description: - 'The time at which the file was shared with the user, if applicable (RFC 3339 date-time).', - format: 'date-time', - type: 'string' - }, - sharingUser: { - $ref: '#/components/schemas/User', - description: 'The user who shared the file with the requesting user, if applicable.' - }, - shortcutDetails: { - description: - 'Shortcut file details. Only populated for shortcut files, which have the mimeType field set to application/vnd.google-apps.shortcut.', - properties: { - targetId: { - description: 'The ID of the file that this shortcut points to.', - type: 'string' - }, - targetMimeType: { - description: - "The MIME type of the file that this shortcut points to. The value of this field is a snapshot of the target's MIME type, captured when the shortcut is created.", - type: 'string' - }, - targetResourceKey: { - description: 'The ResourceKey for the target file.', - type: 'string' - } - }, - type: 'object' - }, - size: { - description: - "The size of the file's content in bytes. This field is populated for files with binary content stored in Google Drive and for Docs Editors files; it's not populated for shortcuts or folders.", - format: 'int64', - type: 'string' - }, - spaces: { - description: - "The list of spaces that contain the file. The currently supported values are 'drive', 'appDataFolder' and 'photos'.", - items: { - type: 'string' - }, - type: 'array' - }, - starred: { - description: 'Whether the user has starred the file.', - type: 'boolean' - }, - teamDriveId: { - description: 'Deprecated - use driveId instead.', - type: 'string' - }, - thumbnailLink: { - description: - "A short-lived link to the file's thumbnail, if available. Typically lasts on the order of hours. Only populated when the requesting app can access the file's content. If the file isn't shared publicly, the URL returned in Files.thumbnailLink must be fetched using a credentialed request.", - type: 'string' - }, - thumbnailVersion: { - description: 'The thumbnail version for use in thumbnail cache invalidation.', - format: 'int64', - type: 'string' - }, - trashed: { - description: - 'Whether the file has been trashed, either explicitly or from a trashed parent folder. Only the owner can trash a file. The trashed item is excluded from all files.list responses returned for any user who does not own the file. However, all users with access to the file can see the trashed item metadata in an API response. All users with access can copy, download, export, and share the file.', - type: 'boolean' - }, - trashedTime: { - description: - 'The time that the item was trashed (RFC 3339 date-time). Only populated for items in shared drives.', - format: 'date-time', - type: 'string' - }, - trashingUser: { - $ref: '#/components/schemas/User', - description: - 'If the file has been explicitly trashed, the user who trashed it. Only populated for items in shared drives.' - }, - version: { - description: - 'A monotonically increasing version number for the file. This reflects every change made to the file on the server, even those not visible to the user.', - format: 'int64', - type: 'string' - }, - videoMediaMetadata: { - description: - 'Additional metadata about video media. This might not be available immediately upon upload.', - properties: { - durationMillis: { - description: 'The duration of the video in milliseconds.', - format: 'int64', - type: 'string' - }, - height: { - description: 'The height of the video in pixels.', - format: 'int32', - type: 'integer' - }, - width: { - description: 'The width of the video in pixels.', - format: 'int32', - type: 'integer' - } - }, - type: 'object' - }, - viewedByMe: { - description: 'Whether this user has viewed the file.', - type: 'boolean' - }, - viewedByMeTime: { - description: 'The last time the user viewed the file (RFC 3339 date-time).', - format: 'date-time', - type: 'string' - }, - viewersCanCopyContent: { - description: 'Deprecated - use copyRequiresWriterPermission instead.', - type: 'boolean' - }, - webContentLink: { - description: - 'A link for downloading the content of the file in a browser. This is only available for files with binary content in Google Drive.', - type: 'string' - }, - webViewLink: { - description: - 'A link for opening the file in a relevant Google editor or viewer in a browser.', - type: 'string' - }, - writersCanShare: { - description: - "Whether users with only writer permission can modify the file's permissions. Not populated for items in shared drives.", - type: 'boolean' - } - }, - type: 'object' -} as const - -export const PermissionWritableSchema = { - description: - 'A permission for a file. A permission grants a user, group, domain, or the world access to a file or a folder hierarchy.', - properties: { - allowFileDiscovery: { - description: - 'Whether the permission allows the file to be discovered through search. This is only applicable for permissions of type domain or anyone.', - type: 'boolean' - }, - deleted: { - description: - 'Whether the account associated with this permission has been deleted. This field only pertains to user and group permissions.', - type: 'boolean' - }, - displayName: { - description: `The "pretty" name of the value of the permission. The following is a list of examples for each type of permission: -- user - User's full name, as defined for their Google Account, such as "Joe Smith." -- group - Name of the Google Group, such as "The Company Administrators." -- domain - String domain name, such as "your-company.com." -- anyone - No displayName is present.`, - type: 'string' - }, - domain: { - description: `The domain to which this permission refers. The following options are currently allowed: -- The entire domain, such as "your-company.com." -- A target audience, such as "ID.audience.googledomains.com."`, - type: 'string' - }, - emailAddress: { - description: 'The email address of the user or group to which this permission refers.', - type: 'string' - }, - expirationTime: { - description: `The time at which this permission will expire (RFC 3339 date-time). Expiration times have the following restrictions: -- They cannot be set on shared drive items. -- They can only be set on user and group permissions. -- The time must be in the future. -- The time cannot be more than one year in the future.`, - format: 'date-time', - type: 'string' - }, - id: { - description: - 'The ID of this permission. This is a unique identifier for the grantee, and is published in User resources as permissionId. IDs should be treated as opaque values.', - type: 'string' - }, - kind: { - default: 'drive#permission', - description: - 'Identifies what kind of resource this is. Value: the fixed string "drive#permission".', - type: 'string' - }, - pendingOwner: { - description: - "Whether the account associated with this permission is a pending owner. Only populated for user type permissions for files that aren't in a shared drive.", - type: 'boolean' - }, - photoLink: { - description: "A link to the user's profile photo, if available.", - type: 'string' - }, - role: { - description: `The role granted by this permission. While new values may be supported in the future, the following are currently allowed: -- owner -- organizer -- fileOrganizer -- writer -- commenter -- reader`, - type: 'string' - }, - type: { - description: `The type of the grantee. Valid values are: -- user -- group -- domain -- anyone When creating a permission, if type is user or group, you must provide an emailAddress for the user or group. When type is domain, you must provide a domain. There isn't extra information required for the anyone type.`, - type: 'string' - }, - view: { - description: - 'Indicates the view for this permission. Only populated for permissions that belong to a view. published is the only supported value.', - type: 'string' - } - }, - type: 'object' -} as const diff --git a/examples/integrations/generated/google/drive/sdk.gen.ts b/examples/integrations/generated/google/drive/sdk.gen.ts deleted file mode 100644 index d56b688..0000000 --- a/examples/integrations/generated/google/drive/sdk.gen.ts +++ /dev/null @@ -1,1317 +0,0 @@ -// This file is auto-generated by @hey-api/openapi-ts - -import type { Options as ClientOptions, Client, TDataShape } from './client' -import type { - DriveAboutGetData, - DriveAboutGetResponses, - DriveChangesListData, - DriveChangesListResponses, - DriveChangesGetStartPageTokenData, - DriveChangesGetStartPageTokenResponses, - DriveChangesWatchData, - DriveChangesWatchResponses, - DriveChannelsStopData, - DriveChannelsStopResponses, - DriveDrivesListData, - DriveDrivesListResponses, - DriveDrivesCreateData, - DriveDrivesCreateResponses, - DriveDrivesDeleteData, - DriveDrivesDeleteResponses, - DriveDrivesGetData, - DriveDrivesGetResponses, - DriveDrivesUpdateData, - DriveDrivesUpdateResponses, - DriveDrivesHideData, - DriveDrivesHideResponses, - DriveDrivesUnhideData, - DriveDrivesUnhideResponses, - DriveFilesListData, - DriveFilesListResponses, - DriveFilesCreateData, - DriveFilesCreateResponses, - DriveFilesGenerateIdsData, - DriveFilesGenerateIdsResponses, - DriveFilesEmptyTrashData, - DriveFilesEmptyTrashResponses, - DriveFilesDeleteData, - DriveFilesDeleteResponses, - DriveFilesGetData, - DriveFilesGetResponses, - DriveFilesUpdateData, - DriveFilesUpdateResponses, - DriveCommentsListData, - DriveCommentsListResponses, - DriveCommentsCreateData, - DriveCommentsCreateResponses, - DriveCommentsDeleteData, - DriveCommentsDeleteResponses, - DriveCommentsGetData, - DriveCommentsGetResponses, - DriveCommentsUpdateData, - DriveCommentsUpdateResponses, - DriveRepliesListData, - DriveRepliesListResponses, - DriveRepliesCreateData, - DriveRepliesCreateResponses, - DriveRepliesDeleteData, - DriveRepliesDeleteResponses, - DriveRepliesGetData, - DriveRepliesGetResponses, - DriveRepliesUpdateData, - DriveRepliesUpdateResponses, - DriveFilesCopyData, - DriveFilesCopyResponses, - DriveFilesExportData, - DriveFilesExportResponses, - DriveFilesListLabelsData, - DriveFilesListLabelsResponses, - DriveFilesModifyLabelsData, - DriveFilesModifyLabelsResponses, - DrivePermissionsListData, - DrivePermissionsListResponses, - DrivePermissionsCreateData, - DrivePermissionsCreateResponses, - DrivePermissionsDeleteData, - DrivePermissionsDeleteResponses, - DrivePermissionsGetData, - DrivePermissionsGetResponses, - DrivePermissionsUpdateData, - DrivePermissionsUpdateResponses, - DriveRevisionsListData, - DriveRevisionsListResponses, - DriveRevisionsDeleteData, - DriveRevisionsDeleteResponses, - DriveRevisionsGetData, - DriveRevisionsGetResponses, - DriveRevisionsUpdateData, - DriveRevisionsUpdateResponses, - DriveFilesWatchData, - DriveFilesWatchResponses, - DriveTeamdrivesListData, - DriveTeamdrivesListResponses, - DriveTeamdrivesCreateData, - DriveTeamdrivesCreateResponses, - DriveTeamdrivesDeleteData, - DriveTeamdrivesDeleteResponses, - DriveTeamdrivesGetData, - DriveTeamdrivesGetResponses, - DriveTeamdrivesUpdateData, - DriveTeamdrivesUpdateResponses -} from './types.gen' -import { client } from './client.gen' -import { - driveChangesListResponseTransformer, - driveDrivesListResponseTransformer, - driveDrivesCreateResponseTransformer, - driveDrivesGetResponseTransformer, - driveDrivesUpdateResponseTransformer, - driveDrivesHideResponseTransformer, - driveDrivesUnhideResponseTransformer, - driveFilesListResponseTransformer, - driveFilesCreateResponseTransformer, - driveFilesGetResponseTransformer, - driveFilesUpdateResponseTransformer, - driveCommentsListResponseTransformer, - driveCommentsCreateResponseTransformer, - driveCommentsGetResponseTransformer, - driveCommentsUpdateResponseTransformer, - driveRepliesListResponseTransformer, - driveRepliesCreateResponseTransformer, - driveRepliesGetResponseTransformer, - driveRepliesUpdateResponseTransformer, - driveFilesCopyResponseTransformer, - drivePermissionsListResponseTransformer, - drivePermissionsCreateResponseTransformer, - drivePermissionsGetResponseTransformer, - drivePermissionsUpdateResponseTransformer, - driveRevisionsListResponseTransformer, - driveRevisionsGetResponseTransformer, - driveRevisionsUpdateResponseTransformer, - driveTeamdrivesListResponseTransformer, - driveTeamdrivesCreateResponseTransformer, - driveTeamdrivesGetResponseTransformer, - driveTeamdrivesUpdateResponseTransformer -} from './transformers.gen' - -export type Options< - TData extends TDataShape = TDataShape, - ThrowOnError extends boolean = boolean -> = ClientOptions & { - /** - * You can provide a client instance returned by `createClient()` instead of - * individual options. This might be also useful if you want to implement a - * custom client. - */ - client?: Client - /** - * You can pass arbitrary values through the `meta` object. This can be - * used to access values that aren't defined as part of the SDK function. - */ - meta?: Record -} - -/** - * Gets information about the user, the user's Drive, and system capabilities. - */ -export const driveAboutGet = ( - options?: Options -) => { - return (options?.client ?? client).get({ - security: [ - { - scheme: 'bearer', - type: 'http' - }, - { - scheme: 'bearer', - type: 'http' - } - ], - url: '/about', - ...options - }) -} - -/** - * Lists the changes for a user or shared drive. - */ -export const driveChangesList = ( - options: Options -) => { - return (options.client ?? client).get({ - responseTransformer: driveChangesListResponseTransformer, - security: [ - { - scheme: 'bearer', - type: 'http' - }, - { - scheme: 'bearer', - type: 'http' - } - ], - url: '/changes', - ...options - }) -} - -/** - * Gets the starting pageToken for listing future changes. - */ -export const driveChangesGetStartPageToken = ( - options?: Options -) => { - return (options?.client ?? client).get< - DriveChangesGetStartPageTokenResponses, - unknown, - ThrowOnError - >({ - security: [ - { - scheme: 'bearer', - type: 'http' - }, - { - scheme: 'bearer', - type: 'http' - } - ], - url: '/changes/startPageToken', - ...options - }) -} - -/** - * Subscribes to changes for a user. To use this method, you must include the pageToken query parameter. - */ -export const driveChangesWatch = ( - options: Options -) => { - return (options.client ?? client).post({ - security: [ - { - scheme: 'bearer', - type: 'http' - }, - { - scheme: 'bearer', - type: 'http' - } - ], - url: '/changes/watch', - ...options, - headers: { - 'Content-Type': 'application/json', - ...options.headers - } - }) -} - -/** - * Stop watching resources through this channel - */ -export const driveChannelsStop = ( - options?: Options -) => { - return (options?.client ?? client).post({ - security: [ - { - scheme: 'bearer', - type: 'http' - }, - { - scheme: 'bearer', - type: 'http' - } - ], - url: '/channels/stop', - ...options, - headers: { - 'Content-Type': 'application/json', - ...options?.headers - } - }) -} - -/** - * Lists the user's shared drives. - */ -export const driveDrivesList = ( - options?: Options -) => { - return (options?.client ?? client).get({ - responseTransformer: driveDrivesListResponseTransformer, - security: [ - { - scheme: 'bearer', - type: 'http' - }, - { - scheme: 'bearer', - type: 'http' - } - ], - url: '/drives', - ...options - }) -} - -/** - * Creates a shared drive. - */ -export const driveDrivesCreate = ( - options: Options -) => { - return (options.client ?? client).post({ - responseTransformer: driveDrivesCreateResponseTransformer, - security: [ - { - scheme: 'bearer', - type: 'http' - }, - { - scheme: 'bearer', - type: 'http' - } - ], - url: '/drives', - ...options, - headers: { - 'Content-Type': 'application/json', - ...options.headers - } - }) -} - -/** - * Permanently deletes a shared drive for which the user is an organizer. The shared drive cannot contain any untrashed items. - */ -export const driveDrivesDelete = ( - options: Options -) => { - return (options.client ?? client).delete({ - security: [ - { - scheme: 'bearer', - type: 'http' - }, - { - scheme: 'bearer', - type: 'http' - } - ], - url: '/drives/{driveId}', - ...options - }) -} - -/** - * Gets a shared drive's metadata by ID. - */ -export const driveDrivesGet = ( - options: Options -) => { - return (options.client ?? client).get({ - responseTransformer: driveDrivesGetResponseTransformer, - security: [ - { - scheme: 'bearer', - type: 'http' - }, - { - scheme: 'bearer', - type: 'http' - } - ], - url: '/drives/{driveId}', - ...options - }) -} - -/** - * Updates the metadata for a shared drive. - */ -export const driveDrivesUpdate = ( - options: Options -) => { - return (options.client ?? client).patch({ - responseTransformer: driveDrivesUpdateResponseTransformer, - security: [ - { - scheme: 'bearer', - type: 'http' - }, - { - scheme: 'bearer', - type: 'http' - } - ], - url: '/drives/{driveId}', - ...options, - headers: { - 'Content-Type': 'application/json', - ...options.headers - } - }) -} - -/** - * Hides a shared drive from the default view. - */ -export const driveDrivesHide = ( - options: Options -) => { - return (options.client ?? client).post({ - responseTransformer: driveDrivesHideResponseTransformer, - security: [ - { - scheme: 'bearer', - type: 'http' - }, - { - scheme: 'bearer', - type: 'http' - } - ], - url: '/drives/{driveId}/hide', - ...options - }) -} - -/** - * Restores a shared drive to the default view. - */ -export const driveDrivesUnhide = ( - options: Options -) => { - return (options.client ?? client).post({ - responseTransformer: driveDrivesUnhideResponseTransformer, - security: [ - { - scheme: 'bearer', - type: 'http' - }, - { - scheme: 'bearer', - type: 'http' - } - ], - url: '/drives/{driveId}/unhide', - ...options - }) -} - -/** - * Lists or searches files. - */ -export const driveFilesList = ( - options?: Options -) => { - return (options?.client ?? client).get({ - responseTransformer: driveFilesListResponseTransformer, - security: [ - { - scheme: 'bearer', - type: 'http' - }, - { - scheme: 'bearer', - type: 'http' - } - ], - url: '/files', - ...options - }) -} - -/** - * Creates a file. - */ -export const driveFilesCreate = ( - options?: Options -) => { - return (options?.client ?? client).post({ - bodySerializer: null, - responseTransformer: driveFilesCreateResponseTransformer, - security: [ - { - scheme: 'bearer', - type: 'http' - }, - { - scheme: 'bearer', - type: 'http' - } - ], - url: '/files', - ...options, - headers: { - 'Content-Type': 'application/octet-stream', - ...options?.headers - } - }) -} - -/** - * Generates a set of file IDs which can be provided in create or copy requests. - */ -export const driveFilesGenerateIds = ( - options?: Options -) => { - return (options?.client ?? client).get({ - security: [ - { - scheme: 'bearer', - type: 'http' - }, - { - scheme: 'bearer', - type: 'http' - } - ], - url: '/files/generateIds', - ...options - }) -} - -/** - * Permanently deletes all of the user's trashed files. - */ -export const driveFilesEmptyTrash = ( - options?: Options -) => { - return (options?.client ?? client).delete({ - security: [ - { - scheme: 'bearer', - type: 'http' - }, - { - scheme: 'bearer', - type: 'http' - } - ], - url: '/files/trash', - ...options - }) -} - -/** - * Permanently deletes a file owned by the user without moving it to the trash. If the file belongs to a shared drive the user must be an organizer on the parent. If the target is a folder, all descendants owned by the user are also deleted. - */ -export const driveFilesDelete = ( - options: Options -) => { - return (options.client ?? client).delete({ - security: [ - { - scheme: 'bearer', - type: 'http' - }, - { - scheme: 'bearer', - type: 'http' - } - ], - url: '/files/{fileId}', - ...options - }) -} - -/** - * Gets a file's metadata or content by ID. - */ -export const driveFilesGet = ( - options: Options -) => { - return (options.client ?? client).get({ - responseTransformer: driveFilesGetResponseTransformer, - security: [ - { - scheme: 'bearer', - type: 'http' - }, - { - scheme: 'bearer', - type: 'http' - } - ], - url: '/files/{fileId}', - ...options - }) -} - -/** - * Updates a file's metadata and/or content. When calling this method, only populate fields in the request that you want to modify. When updating fields, some fields might change automatically, such as modifiedDate. This method supports patch semantics. - */ -export const driveFilesUpdate = ( - options: Options -) => { - return (options.client ?? client).patch({ - bodySerializer: null, - responseTransformer: driveFilesUpdateResponseTransformer, - security: [ - { - scheme: 'bearer', - type: 'http' - }, - { - scheme: 'bearer', - type: 'http' - } - ], - url: '/files/{fileId}', - ...options, - headers: { - 'Content-Type': 'application/octet-stream', - ...options.headers - } - }) -} - -/** - * Lists a file's comments. - */ -export const driveCommentsList = ( - options: Options -) => { - return (options.client ?? client).get({ - responseTransformer: driveCommentsListResponseTransformer, - security: [ - { - scheme: 'bearer', - type: 'http' - }, - { - scheme: 'bearer', - type: 'http' - } - ], - url: '/files/{fileId}/comments', - ...options - }) -} - -/** - * Creates a comment on a file. - */ -export const driveCommentsCreate = ( - options: Options -) => { - return (options.client ?? client).post({ - responseTransformer: driveCommentsCreateResponseTransformer, - security: [ - { - scheme: 'bearer', - type: 'http' - }, - { - scheme: 'bearer', - type: 'http' - } - ], - url: '/files/{fileId}/comments', - ...options, - headers: { - 'Content-Type': 'application/json', - ...options.headers - } - }) -} - -/** - * Deletes a comment. - */ -export const driveCommentsDelete = ( - options: Options -) => { - return (options.client ?? client).delete({ - security: [ - { - scheme: 'bearer', - type: 'http' - }, - { - scheme: 'bearer', - type: 'http' - } - ], - url: '/files/{fileId}/comments/{commentId}', - ...options - }) -} - -/** - * Gets a comment by ID. - */ -export const driveCommentsGet = ( - options: Options -) => { - return (options.client ?? client).get({ - responseTransformer: driveCommentsGetResponseTransformer, - security: [ - { - scheme: 'bearer', - type: 'http' - }, - { - scheme: 'bearer', - type: 'http' - } - ], - url: '/files/{fileId}/comments/{commentId}', - ...options - }) -} - -/** - * Updates a comment with patch semantics. - */ -export const driveCommentsUpdate = ( - options: Options -) => { - return (options.client ?? client).patch({ - responseTransformer: driveCommentsUpdateResponseTransformer, - security: [ - { - scheme: 'bearer', - type: 'http' - }, - { - scheme: 'bearer', - type: 'http' - } - ], - url: '/files/{fileId}/comments/{commentId}', - ...options, - headers: { - 'Content-Type': 'application/json', - ...options.headers - } - }) -} - -/** - * Lists a comment's replies. - */ -export const driveRepliesList = ( - options: Options -) => { - return (options.client ?? client).get({ - responseTransformer: driveRepliesListResponseTransformer, - security: [ - { - scheme: 'bearer', - type: 'http' - }, - { - scheme: 'bearer', - type: 'http' - } - ], - url: '/files/{fileId}/comments/{commentId}/replies', - ...options - }) -} - -/** - * Creates a reply to a comment. - */ -export const driveRepliesCreate = ( - options: Options -) => { - return (options.client ?? client).post({ - responseTransformer: driveRepliesCreateResponseTransformer, - security: [ - { - scheme: 'bearer', - type: 'http' - }, - { - scheme: 'bearer', - type: 'http' - } - ], - url: '/files/{fileId}/comments/{commentId}/replies', - ...options, - headers: { - 'Content-Type': 'application/json', - ...options.headers - } - }) -} - -/** - * Deletes a reply. - */ -export const driveRepliesDelete = ( - options: Options -) => { - return (options.client ?? client).delete({ - security: [ - { - scheme: 'bearer', - type: 'http' - }, - { - scheme: 'bearer', - type: 'http' - } - ], - url: '/files/{fileId}/comments/{commentId}/replies/{replyId}', - ...options - }) -} - -/** - * Gets a reply by ID. - */ -export const driveRepliesGet = ( - options: Options -) => { - return (options.client ?? client).get({ - responseTransformer: driveRepliesGetResponseTransformer, - security: [ - { - scheme: 'bearer', - type: 'http' - }, - { - scheme: 'bearer', - type: 'http' - } - ], - url: '/files/{fileId}/comments/{commentId}/replies/{replyId}', - ...options - }) -} - -/** - * Updates a reply with patch semantics. - */ -export const driveRepliesUpdate = ( - options: Options -) => { - return (options.client ?? client).patch({ - responseTransformer: driveRepliesUpdateResponseTransformer, - security: [ - { - scheme: 'bearer', - type: 'http' - }, - { - scheme: 'bearer', - type: 'http' - } - ], - url: '/files/{fileId}/comments/{commentId}/replies/{replyId}', - ...options, - headers: { - 'Content-Type': 'application/json', - ...options.headers - } - }) -} - -/** - * Creates a copy of a file and applies any requested updates with patch semantics. Folders cannot be copied. - */ -export const driveFilesCopy = ( - options: Options -) => { - return (options.client ?? client).post({ - responseTransformer: driveFilesCopyResponseTransformer, - security: [ - { - scheme: 'bearer', - type: 'http' - }, - { - scheme: 'bearer', - type: 'http' - } - ], - url: '/files/{fileId}/copy', - ...options, - headers: { - 'Content-Type': 'application/json', - ...options.headers - } - }) -} - -/** - * Exports a Google Workspace document to the requested MIME type and returns exported byte content. Note that the exported content is limited to 10MB. - */ -export const driveFilesExport = ( - options: Options -) => { - return (options.client ?? client).get({ - security: [ - { - scheme: 'bearer', - type: 'http' - }, - { - scheme: 'bearer', - type: 'http' - } - ], - url: '/files/{fileId}/export', - ...options - }) -} - -/** - * Lists the labels on a file. - */ -export const driveFilesListLabels = ( - options: Options -) => { - return (options.client ?? client).get({ - security: [ - { - scheme: 'bearer', - type: 'http' - }, - { - scheme: 'bearer', - type: 'http' - } - ], - url: '/files/{fileId}/listLabels', - ...options - }) -} - -/** - * Modifies the set of labels on a file. - */ -export const driveFilesModifyLabels = ( - options: Options -) => { - return (options.client ?? client).post({ - security: [ - { - scheme: 'bearer', - type: 'http' - }, - { - scheme: 'bearer', - type: 'http' - } - ], - url: '/files/{fileId}/modifyLabels', - ...options, - headers: { - 'Content-Type': 'application/json', - ...options.headers - } - }) -} - -/** - * Lists a file's or shared drive's permissions. - */ -export const drivePermissionsList = ( - options: Options -) => { - return (options.client ?? client).get({ - responseTransformer: drivePermissionsListResponseTransformer, - security: [ - { - scheme: 'bearer', - type: 'http' - }, - { - scheme: 'bearer', - type: 'http' - } - ], - url: '/files/{fileId}/permissions', - ...options - }) -} - -/** - * Creates a permission for a file or shared drive. For more information on creating permissions, see Share files, folders & drives. - */ -export const drivePermissionsCreate = ( - options: Options -) => { - return (options.client ?? client).post({ - responseTransformer: drivePermissionsCreateResponseTransformer, - security: [ - { - scheme: 'bearer', - type: 'http' - }, - { - scheme: 'bearer', - type: 'http' - } - ], - url: '/files/{fileId}/permissions', - ...options, - headers: { - 'Content-Type': 'application/json', - ...options.headers - } - }) -} - -/** - * Deletes a permission. - */ -export const drivePermissionsDelete = ( - options: Options -) => { - return (options.client ?? client).delete({ - security: [ - { - scheme: 'bearer', - type: 'http' - }, - { - scheme: 'bearer', - type: 'http' - } - ], - url: '/files/{fileId}/permissions/{permissionId}', - ...options - }) -} - -/** - * Gets a permission by ID. - */ -export const drivePermissionsGet = ( - options: Options -) => { - return (options.client ?? client).get({ - responseTransformer: drivePermissionsGetResponseTransformer, - security: [ - { - scheme: 'bearer', - type: 'http' - }, - { - scheme: 'bearer', - type: 'http' - } - ], - url: '/files/{fileId}/permissions/{permissionId}', - ...options - }) -} - -/** - * Updates a permission with patch semantics. - */ -export const drivePermissionsUpdate = ( - options: Options -) => { - return (options.client ?? client).patch({ - responseTransformer: drivePermissionsUpdateResponseTransformer, - security: [ - { - scheme: 'bearer', - type: 'http' - }, - { - scheme: 'bearer', - type: 'http' - } - ], - url: '/files/{fileId}/permissions/{permissionId}', - ...options, - headers: { - 'Content-Type': 'application/json', - ...options.headers - } - }) -} - -/** - * Lists a file's revisions. - */ -export const driveRevisionsList = ( - options: Options -) => { - return (options.client ?? client).get({ - responseTransformer: driveRevisionsListResponseTransformer, - security: [ - { - scheme: 'bearer', - type: 'http' - }, - { - scheme: 'bearer', - type: 'http' - } - ], - url: '/files/{fileId}/revisions', - ...options - }) -} - -/** - * Permanently deletes a file version. You can only delete revisions for files with binary content in Google Drive, like images or videos. Revisions for other files, like Google Docs or Sheets, and the last remaining file version can't be deleted. - */ -export const driveRevisionsDelete = ( - options: Options -) => { - return (options.client ?? client).delete({ - security: [ - { - scheme: 'bearer', - type: 'http' - }, - { - scheme: 'bearer', - type: 'http' - } - ], - url: '/files/{fileId}/revisions/{revisionId}', - ...options - }) -} - -/** - * Gets a revision's metadata or content by ID. - */ -export const driveRevisionsGet = ( - options: Options -) => { - return (options.client ?? client).get({ - responseTransformer: driveRevisionsGetResponseTransformer, - security: [ - { - scheme: 'bearer', - type: 'http' - }, - { - scheme: 'bearer', - type: 'http' - } - ], - url: '/files/{fileId}/revisions/{revisionId}', - ...options - }) -} - -/** - * Updates a revision with patch semantics. - */ -export const driveRevisionsUpdate = ( - options: Options -) => { - return (options.client ?? client).patch({ - responseTransformer: driveRevisionsUpdateResponseTransformer, - security: [ - { - scheme: 'bearer', - type: 'http' - }, - { - scheme: 'bearer', - type: 'http' - } - ], - url: '/files/{fileId}/revisions/{revisionId}', - ...options, - headers: { - 'Content-Type': 'application/json', - ...options.headers - } - }) -} - -/** - * Subscribes to changes to a file. - */ -export const driveFilesWatch = ( - options: Options -) => { - return (options.client ?? client).post({ - security: [ - { - scheme: 'bearer', - type: 'http' - }, - { - scheme: 'bearer', - type: 'http' - } - ], - url: '/files/{fileId}/watch', - ...options, - headers: { - 'Content-Type': 'application/json', - ...options.headers - } - }) -} - -/** - * Deprecated use drives.list instead. - */ -export const driveTeamdrivesList = ( - options?: Options -) => { - return (options?.client ?? client).get({ - responseTransformer: driveTeamdrivesListResponseTransformer, - security: [ - { - scheme: 'bearer', - type: 'http' - }, - { - scheme: 'bearer', - type: 'http' - } - ], - url: '/teamdrives', - ...options - }) -} - -/** - * Deprecated use drives.create instead. - */ -export const driveTeamdrivesCreate = ( - options: Options -) => { - return (options.client ?? client).post({ - responseTransformer: driveTeamdrivesCreateResponseTransformer, - security: [ - { - scheme: 'bearer', - type: 'http' - }, - { - scheme: 'bearer', - type: 'http' - } - ], - url: '/teamdrives', - ...options, - headers: { - 'Content-Type': 'application/json', - ...options.headers - } - }) -} - -/** - * Deprecated use drives.delete instead. - */ -export const driveTeamdrivesDelete = ( - options: Options -) => { - return (options.client ?? client).delete({ - security: [ - { - scheme: 'bearer', - type: 'http' - }, - { - scheme: 'bearer', - type: 'http' - } - ], - url: '/teamdrives/{teamDriveId}', - ...options - }) -} - -/** - * Deprecated use drives.get instead. - */ -export const driveTeamdrivesGet = ( - options: Options -) => { - return (options.client ?? client).get({ - responseTransformer: driveTeamdrivesGetResponseTransformer, - security: [ - { - scheme: 'bearer', - type: 'http' - }, - { - scheme: 'bearer', - type: 'http' - } - ], - url: '/teamdrives/{teamDriveId}', - ...options - }) -} - -/** - * Deprecated use drives.update instead - */ -export const driveTeamdrivesUpdate = ( - options: Options -) => { - return (options.client ?? client).patch({ - responseTransformer: driveTeamdrivesUpdateResponseTransformer, - security: [ - { - scheme: 'bearer', - type: 'http' - }, - { - scheme: 'bearer', - type: 'http' - } - ], - url: '/teamdrives/{teamDriveId}', - ...options, - headers: { - 'Content-Type': 'application/json', - ...options.headers - } - }) -} diff --git a/examples/integrations/generated/google/drive/transformers.gen.ts b/examples/integrations/generated/google/drive/transformers.gen.ts deleted file mode 100644 index 063654f..0000000 --- a/examples/integrations/generated/google/drive/transformers.gen.ts +++ /dev/null @@ -1,432 +0,0 @@ -// This file is auto-generated by @hey-api/openapi-ts - -import type { - DriveChangesListResponse, - DriveDrivesListResponse, - DriveDrivesCreateResponse, - DriveDrivesGetResponse, - DriveDrivesUpdateResponse, - DriveDrivesHideResponse, - DriveDrivesUnhideResponse, - DriveFilesListResponse, - DriveFilesCreateResponse, - DriveFilesGetResponse, - DriveFilesUpdateResponse, - DriveCommentsListResponse, - DriveCommentsCreateResponse, - DriveCommentsGetResponse, - DriveCommentsUpdateResponse, - DriveRepliesListResponse, - DriveRepliesCreateResponse, - DriveRepliesGetResponse, - DriveRepliesUpdateResponse, - DriveFilesCopyResponse, - DrivePermissionsListResponse, - DrivePermissionsCreateResponse, - DrivePermissionsGetResponse, - DrivePermissionsUpdateResponse, - DriveRevisionsListResponse, - DriveRevisionsGetResponse, - DriveRevisionsUpdateResponse, - DriveTeamdrivesListResponse, - DriveTeamdrivesCreateResponse, - DriveTeamdrivesGetResponse, - DriveTeamdrivesUpdateResponse -} from './types.gen' - -const driveSchemaResponseTransformer = (data: any) => { - if (data.createdTime) { - data.createdTime = new Date(data.createdTime) - } - return data -} - -const contentRestrictionSchemaResponseTransformer = (data: any) => { - if (data.restrictionTime) { - data.restrictionTime = new Date(data.restrictionTime) - } - return data -} - -const permissionSchemaResponseTransformer = (data: any) => { - if (data.expirationTime) { - data.expirationTime = new Date(data.expirationTime) - } - return data -} - -const fileSchemaResponseTransformer = (data: any) => { - if (data.contentRestrictions) { - data.contentRestrictions = data.contentRestrictions.map((item: any) => { - return contentRestrictionSchemaResponseTransformer(item) - }) - } - if (data.createdTime) { - data.createdTime = new Date(data.createdTime) - } - if (data.modifiedByMeTime) { - data.modifiedByMeTime = new Date(data.modifiedByMeTime) - } - if (data.modifiedTime) { - data.modifiedTime = new Date(data.modifiedTime) - } - if (data.permissions) { - data.permissions = data.permissions.map((item: any) => { - return permissionSchemaResponseTransformer(item) - }) - } - if (data.sharedWithMeTime) { - data.sharedWithMeTime = new Date(data.sharedWithMeTime) - } - if (data.trashedTime) { - data.trashedTime = new Date(data.trashedTime) - } - if (data.viewedByMeTime) { - data.viewedByMeTime = new Date(data.viewedByMeTime) - } - return data -} - -const teamDriveSchemaResponseTransformer = (data: any) => { - if (data.createdTime) { - data.createdTime = new Date(data.createdTime) - } - return data -} - -const changeSchemaResponseTransformer = (data: any) => { - if (data.drive) { - data.drive = driveSchemaResponseTransformer(data.drive) - } - if (data.file) { - data.file = fileSchemaResponseTransformer(data.file) - } - if (data.teamDrive) { - data.teamDrive = teamDriveSchemaResponseTransformer(data.teamDrive) - } - if (data.time) { - data.time = new Date(data.time) - } - return data -} - -const changeListSchemaResponseTransformer = (data: any) => { - if (data.changes) { - data.changes = data.changes.map((item: any) => { - return changeSchemaResponseTransformer(item) - }) - } - return data -} - -export const driveChangesListResponseTransformer = async ( - data: any -): Promise => { - data = changeListSchemaResponseTransformer(data) - return data -} - -const driveListSchemaResponseTransformer = (data: any) => { - if (data.drives) { - data.drives = data.drives.map((item: any) => { - return driveSchemaResponseTransformer(item) - }) - } - return data -} - -export const driveDrivesListResponseTransformer = async ( - data: any -): Promise => { - data = driveListSchemaResponseTransformer(data) - return data -} - -export const driveDrivesCreateResponseTransformer = async ( - data: any -): Promise => { - data = driveSchemaResponseTransformer(data) - return data -} - -export const driveDrivesGetResponseTransformer = async ( - data: any -): Promise => { - data = driveSchemaResponseTransformer(data) - return data -} - -export const driveDrivesUpdateResponseTransformer = async ( - data: any -): Promise => { - data = driveSchemaResponseTransformer(data) - return data -} - -export const driveDrivesHideResponseTransformer = async ( - data: any -): Promise => { - data = driveSchemaResponseTransformer(data) - return data -} - -export const driveDrivesUnhideResponseTransformer = async ( - data: any -): Promise => { - data = driveSchemaResponseTransformer(data) - return data -} - -const fileListSchemaResponseTransformer = (data: any) => { - if (data.files) { - data.files = data.files.map((item: any) => { - return fileSchemaResponseTransformer(item) - }) - } - return data -} - -export const driveFilesListResponseTransformer = async ( - data: any -): Promise => { - data = fileListSchemaResponseTransformer(data) - return data -} - -export const driveFilesCreateResponseTransformer = async ( - data: any -): Promise => { - data = fileSchemaResponseTransformer(data) - return data -} - -export const driveFilesGetResponseTransformer = async ( - data: any -): Promise => { - data = fileSchemaResponseTransformer(data) - return data -} - -export const driveFilesUpdateResponseTransformer = async ( - data: any -): Promise => { - data = fileSchemaResponseTransformer(data) - return data -} - -const replySchemaResponseTransformer = (data: any) => { - if (data.createdTime) { - data.createdTime = new Date(data.createdTime) - } - if (data.modifiedTime) { - data.modifiedTime = new Date(data.modifiedTime) - } - return data -} - -const commentSchemaResponseTransformer = (data: any) => { - if (data.createdTime) { - data.createdTime = new Date(data.createdTime) - } - if (data.modifiedTime) { - data.modifiedTime = new Date(data.modifiedTime) - } - if (data.replies) { - data.replies = data.replies.map((item: any) => { - return replySchemaResponseTransformer(item) - }) - } - return data -} - -const commentListSchemaResponseTransformer = (data: any) => { - if (data.comments) { - data.comments = data.comments.map((item: any) => { - return commentSchemaResponseTransformer(item) - }) - } - return data -} - -export const driveCommentsListResponseTransformer = async ( - data: any -): Promise => { - data = commentListSchemaResponseTransformer(data) - return data -} - -export const driveCommentsCreateResponseTransformer = async ( - data: any -): Promise => { - data = commentSchemaResponseTransformer(data) - return data -} - -export const driveCommentsGetResponseTransformer = async ( - data: any -): Promise => { - data = commentSchemaResponseTransformer(data) - return data -} - -export const driveCommentsUpdateResponseTransformer = async ( - data: any -): Promise => { - data = commentSchemaResponseTransformer(data) - return data -} - -const replyListSchemaResponseTransformer = (data: any) => { - if (data.replies) { - data.replies = data.replies.map((item: any) => { - return replySchemaResponseTransformer(item) - }) - } - return data -} - -export const driveRepliesListResponseTransformer = async ( - data: any -): Promise => { - data = replyListSchemaResponseTransformer(data) - return data -} - -export const driveRepliesCreateResponseTransformer = async ( - data: any -): Promise => { - data = replySchemaResponseTransformer(data) - return data -} - -export const driveRepliesGetResponseTransformer = async ( - data: any -): Promise => { - data = replySchemaResponseTransformer(data) - return data -} - -export const driveRepliesUpdateResponseTransformer = async ( - data: any -): Promise => { - data = replySchemaResponseTransformer(data) - return data -} - -export const driveFilesCopyResponseTransformer = async ( - data: any -): Promise => { - data = fileSchemaResponseTransformer(data) - return data -} - -const permissionListSchemaResponseTransformer = (data: any) => { - if (data.permissions) { - data.permissions = data.permissions.map((item: any) => { - return permissionSchemaResponseTransformer(item) - }) - } - return data -} - -export const drivePermissionsListResponseTransformer = async ( - data: any -): Promise => { - data = permissionListSchemaResponseTransformer(data) - return data -} - -export const drivePermissionsCreateResponseTransformer = async ( - data: any -): Promise => { - data = permissionSchemaResponseTransformer(data) - return data -} - -export const drivePermissionsGetResponseTransformer = async ( - data: any -): Promise => { - data = permissionSchemaResponseTransformer(data) - return data -} - -export const drivePermissionsUpdateResponseTransformer = async ( - data: any -): Promise => { - data = permissionSchemaResponseTransformer(data) - return data -} - -const revisionSchemaResponseTransformer = (data: any) => { - if (data.modifiedTime) { - data.modifiedTime = new Date(data.modifiedTime) - } - return data -} - -const revisionListSchemaResponseTransformer = (data: any) => { - if (data.revisions) { - data.revisions = data.revisions.map((item: any) => { - return revisionSchemaResponseTransformer(item) - }) - } - return data -} - -export const driveRevisionsListResponseTransformer = async ( - data: any -): Promise => { - data = revisionListSchemaResponseTransformer(data) - return data -} - -export const driveRevisionsGetResponseTransformer = async ( - data: any -): Promise => { - data = revisionSchemaResponseTransformer(data) - return data -} - -export const driveRevisionsUpdateResponseTransformer = async ( - data: any -): Promise => { - data = revisionSchemaResponseTransformer(data) - return data -} - -const teamDriveListSchemaResponseTransformer = (data: any) => { - if (data.teamDrives) { - data.teamDrives = data.teamDrives.map((item: any) => { - return teamDriveSchemaResponseTransformer(item) - }) - } - return data -} - -export const driveTeamdrivesListResponseTransformer = async ( - data: any -): Promise => { - data = teamDriveListSchemaResponseTransformer(data) - return data -} - -export const driveTeamdrivesCreateResponseTransformer = async ( - data: any -): Promise => { - data = teamDriveSchemaResponseTransformer(data) - return data -} - -export const driveTeamdrivesGetResponseTransformer = async ( - data: any -): Promise => { - data = teamDriveSchemaResponseTransformer(data) - return data -} - -export const driveTeamdrivesUpdateResponseTransformer = async ( - data: any -): Promise => { - data = teamDriveSchemaResponseTransformer(data) - return data -} diff --git a/examples/integrations/generated/google/drive/types.gen.ts b/examples/integrations/generated/google/drive/types.gen.ts deleted file mode 100644 index 1d6de97..0000000 --- a/examples/integrations/generated/google/drive/types.gen.ts +++ /dev/null @@ -1,5484 +0,0 @@ -// This file is auto-generated by @hey-api/openapi-ts - -/** - * Information about the user, the user's Drive, and system capabilities. - */ -export type About = { - /** - * Whether the user has installed the requesting app. - */ - appInstalled?: boolean - /** - * Whether the user can create shared drives. - */ - canCreateDrives?: boolean - /** - * Deprecated - use canCreateDrives instead. - */ - canCreateTeamDrives?: boolean - /** - * A list of themes that are supported for shared drives. - */ - driveThemes?: Array<{ - /** - * A link to this theme's background image. - */ - backgroundImageLink?: string - /** - * The color of this theme as an RGB hex string. - */ - colorRgb?: string - /** - * The ID of the theme. - */ - id?: string - }> - /** - * A map of source MIME type to possible targets for all supported exports. - */ - exportFormats?: { - [key: string]: Array - } - /** - * The currently supported folder colors as RGB hex strings. - */ - folderColorPalette?: Array - /** - * A map of source MIME type to possible targets for all supported imports. - */ - importFormats?: { - [key: string]: Array - } - /** - * Identifies what kind of resource this is. Value: the fixed string "drive#about". - */ - kind?: string - /** - * A map of maximum import sizes by MIME type, in bytes. - */ - maxImportSizes?: { - [key: string]: string - } - /** - * The maximum upload size in bytes. - */ - maxUploadSize?: string - /** - * The user's storage quota limits and usage. All fields are measured in bytes. - */ - storageQuota?: { - /** - * The usage limit, if applicable. This will not be present if the user has unlimited storage. - */ - limit?: string - /** - * The total usage across all services. - */ - usage?: string - /** - * The usage by all files in Google Drive. - */ - usageInDrive?: string - /** - * The usage by trashed files in Google Drive. - */ - usageInDriveTrash?: string - } - /** - * Deprecated - use driveThemes instead. - */ - teamDriveThemes?: Array<{ - /** - * Deprecated - use driveThemes/backgroundImageLink instead. - */ - backgroundImageLink?: string - /** - * Deprecated - use driveThemes/colorRgb instead. - */ - colorRgb?: string - /** - * Deprecated - use driveThemes/id instead. - */ - id?: string - }> - user?: User -} - -/** - * A change to a file or shared drive. - */ -export type Change = { - /** - * The type of the change. Possible values are file and drive. - */ - changeType?: string - drive?: Drive - /** - * The ID of the shared drive associated with this change. - */ - driveId?: string - file?: File - /** - * The ID of the file which has changed. - */ - fileId?: string - /** - * Identifies what kind of resource this is. Value: the fixed string "drive#change". - */ - kind?: string - /** - * Whether the file or shared drive has been removed from this list of changes, for example by deletion or loss of access. - */ - removed?: boolean - teamDrive?: TeamDrive - /** - * Deprecated - use driveId instead. - */ - teamDriveId?: string - /** - * The time of this change (RFC 3339 date-time). - */ - time?: Date - /** - * Deprecated - use changeType instead. - */ - type?: string -} - -/** - * A list of changes for a user. - */ -export type ChangeList = { - /** - * The list of changes. If nextPageToken is populated, then this list may be incomplete and an additional page of results should be fetched. - */ - changes?: Array - /** - * Identifies what kind of resource this is. Value: the fixed string "drive#changeList". - */ - kind?: string - /** - * The starting page token for future changes. This will be present only if the end of the current changes list has been reached. - */ - newStartPageToken?: string - /** - * The page token for the next page of changes. This will be absent if the end of the changes list has been reached. If the token is rejected for any reason, it should be discarded, and pagination should be restarted from the first page of results. - */ - nextPageToken?: string -} - -/** - * An notification channel used to watch for resource changes. - */ -export type Channel = { - /** - * The address where notifications are delivered for this channel. - */ - address?: string - /** - * Date and time of notification channel expiration, expressed as a Unix timestamp, in milliseconds. Optional. - */ - expiration?: string - /** - * A UUID or similar unique string that identifies this channel. - */ - id?: string - /** - * Identifies this as a notification channel used to watch for changes to a resource, which is "api#channel". - */ - kind?: string - /** - * Additional parameters controlling delivery channel behavior. Optional. - */ - params?: { - [key: string]: string - } - /** - * A Boolean value to indicate whether payload is wanted. Optional. - */ - payload?: boolean - /** - * An opaque ID that identifies the resource being watched on this channel. Stable across different API versions. - */ - resourceId?: string - /** - * A version-specific identifier for the watched resource. - */ - resourceUri?: string - /** - * An arbitrary string delivered to the target address with each notification delivered over this channel. Optional. - */ - token?: string - /** - * The type of delivery mechanism used for this channel. Valid values are "web_hook" (or "webhook"). Both values refer to a channel where Http requests are used to deliver messages. - */ - type?: string -} - -/** - * A comment on a file. - */ -export type Comment = { - /** - * A region of the document represented as a JSON string. For details on defining anchor properties, refer to Add comments and replies. - */ - anchor?: string - author?: User - /** - * The plain text content of the comment. This field is used for setting the content, while htmlContent should be displayed. - */ - content?: string - /** - * The time at which the comment was created (RFC 3339 date-time). - */ - createdTime?: Date - /** - * Whether the comment has been deleted. A deleted comment has no content. - */ - deleted?: boolean - /** - * The content of the comment with HTML formatting. - */ - htmlContent?: string - /** - * The ID of the comment. - */ - id?: string - /** - * Identifies what kind of resource this is. Value: the fixed string "drive#comment". - */ - kind?: string - /** - * The last time the comment or any of its replies was modified (RFC 3339 date-time). - */ - modifiedTime?: Date - /** - * The file content to which the comment refers, typically within the anchor region. For a text file, for example, this would be the text at the location of the comment. - */ - quotedFileContent?: { - /** - * The MIME type of the quoted content. - */ - mimeType?: string - /** - * The quoted content itself. This is interpreted as plain text if set through the API. - */ - value?: string - } - /** - * The full list of replies to the comment in chronological order. - */ - replies?: Array - /** - * Whether the comment has been resolved by one of its replies. - */ - resolved?: boolean -} - -/** - * A list of comments on a file. - */ -export type CommentList = { - /** - * The list of comments. If nextPageToken is populated, then this list may be incomplete and an additional page of results should be fetched. - */ - comments?: Array - /** - * Identifies what kind of resource this is. Value: the fixed string "drive#commentList". - */ - kind?: string - /** - * The page token for the next page of comments. This will be absent if the end of the comments list has been reached. If the token is rejected for any reason, it should be discarded, and pagination should be restarted from the first page of results. - */ - nextPageToken?: string -} - -/** - * A restriction for accessing the content of the file. - */ -export type ContentRestriction = { - /** - * Whether the content of the file is read-only. If a file is read-only, a new revision of the file may not be added, comments may not be added or modified, and the title of the file may not be modified. - */ - readOnly?: boolean - /** - * Reason for why the content of the file is restricted. This is only mutable on requests that also set readOnly=true. - */ - reason?: string - restrictingUser?: User - /** - * The time at which the content restriction was set (formatted RFC 3339 timestamp). Only populated if readOnly is true. - */ - restrictionTime?: Date - /** - * The type of the content restriction. Currently the only possible value is globalContentRestriction. - */ - type?: string -} - -/** - * Representation of a shared drive. - */ -export type Drive = { - /** - * An image file and cropping parameters from which a background image for this shared drive is set. This is a write-only field; it can only be set on drive.drives.update requests that don't set themeId. When specified, all fields of the backgroundImageFile must be set. - */ - backgroundImageFile?: { - /** - * The ID of an image file in Google Drive to use for the background image. - */ - id?: string - /** - * The width of the cropped image in the closed range of 0 to 1. This value represents the width of the cropped image divided by the width of the entire image. The height is computed by applying a width to height aspect ratio of 80 to 9. The resulting image must be at least 1280 pixels wide and 144 pixels high. - */ - width?: number - /** - * The X coordinate of the upper left corner of the cropping area in the background image. This is a value in the closed range of 0 to 1. This value represents the horizontal distance from the left side of the entire image to the left side of the cropping area divided by the width of the entire image. - */ - xCoordinate?: number - /** - * The Y coordinate of the upper left corner of the cropping area in the background image. This is a value in the closed range of 0 to 1. This value represents the vertical distance from the top side of the entire image to the top side of the cropping area divided by the height of the entire image. - */ - yCoordinate?: number - } - /** - * A short-lived link to this shared drive's background image. - */ - backgroundImageLink?: string - /** - * Capabilities the current user has on this shared drive. - */ - capabilities?: { - /** - * Whether the current user can add children to folders in this shared drive. - */ - canAddChildren?: boolean - /** - * Whether the current user can change the copyRequiresWriterPermission restriction of this shared drive. - */ - canChangeCopyRequiresWriterPermissionRestriction?: boolean - /** - * Whether the current user can change the domainUsersOnly restriction of this shared drive. - */ - canChangeDomainUsersOnlyRestriction?: boolean - /** - * Whether the current user can change the background of this shared drive. - */ - canChangeDriveBackground?: boolean - /** - * Whether the current user can change the driveMembersOnly restriction of this shared drive. - */ - canChangeDriveMembersOnlyRestriction?: boolean - /** - * Whether the current user can change the sharingFoldersRequiresOrganizerPermission restriction of this shared drive. - */ - canChangeSharingFoldersRequiresOrganizerPermissionRestriction?: boolean - /** - * Whether the current user can comment on files in this shared drive. - */ - canComment?: boolean - /** - * Whether the current user can copy files in this shared drive. - */ - canCopy?: boolean - /** - * Whether the current user can delete children from folders in this shared drive. - */ - canDeleteChildren?: boolean - /** - * Whether the current user can delete this shared drive. Attempting to delete the shared drive may still fail if there are untrashed items inside the shared drive. - */ - canDeleteDrive?: boolean - /** - * Whether the current user can download files in this shared drive. - */ - canDownload?: boolean - /** - * Whether the current user can edit files in this shared drive - */ - canEdit?: boolean - /** - * Whether the current user can list the children of folders in this shared drive. - */ - canListChildren?: boolean - /** - * Whether the current user can add members to this shared drive or remove them or change their role. - */ - canManageMembers?: boolean - /** - * Whether the current user can read the revisions resource of files in this shared drive. - */ - canReadRevisions?: boolean - /** - * Whether the current user can rename files or folders in this shared drive. - */ - canRename?: boolean - /** - * Whether the current user can rename this shared drive. - */ - canRenameDrive?: boolean - /** - * Whether the current user can reset the shared drive restrictions to defaults. - */ - canResetDriveRestrictions?: boolean - /** - * Whether the current user can share files or folders in this shared drive. - */ - canShare?: boolean - /** - * Whether the current user can trash children from folders in this shared drive. - */ - canTrashChildren?: boolean - } - /** - * The color of this shared drive as an RGB hex string. It can only be set on drive.drives.update requests that don't set themeId. - */ - colorRgb?: string - /** - * The time at which the shared drive was created (RFC 3339 date-time). - */ - createdTime?: Date - /** - * Whether the shared drive is hidden from default view. - */ - hidden?: boolean - /** - * The ID of this shared drive which is also the ID of the top level folder of this shared drive. - */ - id?: string - /** - * Identifies what kind of resource this is. Value: the fixed string "drive#drive". - */ - kind?: string - /** - * The name of this shared drive. - */ - name?: string - /** - * The organizational unit of this shared drive. This field is only populated on drives.list responses when the useDomainAdminAccess parameter is set to true. - */ - orgUnitId?: string - /** - * A set of restrictions that apply to this shared drive or items inside this shared drive. - */ - restrictions?: { - /** - * Whether administrative privileges on this shared drive are required to modify restrictions. - */ - adminManagedRestrictions?: boolean - /** - * Whether the options to copy, print, or download files inside this shared drive, should be disabled for readers and commenters. When this restriction is set to true, it will override the similarly named field to true for any file inside this shared drive. - */ - copyRequiresWriterPermission?: boolean - /** - * Whether access to this shared drive and items inside this shared drive is restricted to users of the domain to which this shared drive belongs. This restriction may be overridden by other sharing policies controlled outside of this shared drive. - */ - domainUsersOnly?: boolean - /** - * Whether access to items inside this shared drive is restricted to its members. - */ - driveMembersOnly?: boolean - /** - * If true, only users with the organizer role can share folders. If false, users with either the organizer role or the file organizer role can share folders. - */ - sharingFoldersRequiresOrganizerPermission?: boolean - } - /** - * The ID of the theme from which the background image and color are set. The set of possible driveThemes can be retrieved from a drive.about.get response. When not specified on a drive.drives.create request, a random theme is chosen from which the background image and color are set. This is a write-only field; it can only be set on requests that don't set colorRgb or backgroundImageFile. - */ - themeId?: string -} - -/** - * A list of shared drives. - */ -export type DriveList = { - /** - * The list of shared drives. If nextPageToken is populated, then this list may be incomplete and an additional page of results should be fetched. - */ - drives?: Array - /** - * Identifies what kind of resource this is. Value: the fixed string "drive#driveList". - */ - kind?: string - /** - * The page token for the next page of shared drives. This will be absent if the end of the list has been reached. If the token is rejected for any reason, it should be discarded, and pagination should be restarted from the first page of results. - */ - nextPageToken?: string -} - -/** - * The metadata for a file. - */ -export type File = { - /** - * A collection of arbitrary key-value pairs that are private to the requesting app. - * Entries with null values are cleared in update and copy requests. These properties can only be retrieved using an authenticated request. An authenticated request uses an access token obtained with an OAuth 2 client ID. You cannot use an API key to retrieve private properties. - */ - appProperties?: { - [key: string]: string - } - /** - * Capabilities the current user has on this file. Each capability corresponds to a fine-grained action that a user can take. - */ - capabilities?: { - /** - * Whether the current user is the pending owner of the file. Not populated for shared drive files. - */ - canAcceptOwnership?: boolean - /** - * Whether the current user can add children to this folder. This is always false when the item isn't a folder. - */ - canAddChildren?: boolean - /** - * Whether the current user can add a folder from another drive (different shared drive or My Drive) to this folder. This is false when the item isn't a folder. Only populated for items in shared drives. - */ - canAddFolderFromAnotherDrive?: boolean - /** - * Whether the current user can add a parent for the item without removing an existing parent in the same request. Not populated for shared drive files. - */ - canAddMyDriveParent?: boolean - /** - * Whether the current user can change the copyRequiresWriterPermission restriction of this file. - */ - canChangeCopyRequiresWriterPermission?: boolean - /** - * Whether the current user can change the securityUpdateEnabled field on link share metadata. - */ - canChangeSecurityUpdateEnabled?: boolean - /** - * Deprecated - */ - canChangeViewersCanCopyContent?: boolean - /** - * Whether the current user can comment on this file. - */ - canComment?: boolean - /** - * Whether the current user can copy this file. For an item in a shared drive, whether the current user can copy non-folder descendants of this item, or this item itself if it's not a folder. - */ - canCopy?: boolean - /** - * Whether the current user can delete this file. - */ - canDelete?: boolean - /** - * Whether the current user can delete children of this folder. This is false when the item isn't a folder. Only populated for items in shared drives. - */ - canDeleteChildren?: boolean - /** - * Whether the current user can download this file. - */ - canDownload?: boolean - /** - * Whether the current user can edit this file. Other factors might limit the type of changes a user can make to a file. For example, see canChangeCopyRequiresWriterPermission or canModifyContent. - */ - canEdit?: boolean - /** - * Whether the current user can list the children of this folder. This is always false when the item isn't a folder. - */ - canListChildren?: boolean - /** - * Whether the current user can modify the content of this file. - */ - canModifyContent?: boolean - /** - * Whether the current user can modify restrictions on content of this file. - */ - canModifyContentRestriction?: boolean - /** - * Whether the current user can modify the labels on this file. - */ - canModifyLabels?: boolean - /** - * Whether the current user can move children of this folder outside of the shared drive. This is false when the item isn't a folder. Only populated for items in shared drives. - */ - canMoveChildrenOutOfDrive?: boolean - /** - * Deprecated - use canMoveChildrenOutOfDrive instead. - */ - canMoveChildrenOutOfTeamDrive?: boolean - /** - * Whether the current user can move children of this folder within this shared drive or My Drive. This is false when the item isn't a folder. Note that a request to move the child might still fail depending on the current user's access to the child and to the destination folder. - */ - canMoveChildrenWithinDrive?: boolean - /** - * Deprecated - use canMoveChildrenWithinDrive instead. - */ - canMoveChildrenWithinTeamDrive?: boolean - /** - * Deprecated - use canMoveItemOutOfDrive instead. - */ - canMoveItemIntoTeamDrive?: boolean - /** - * Whether the current user can move this item outside of this shared drive or My Drive by changing its parent. Note that a request to change the parent of the item might still fail depending on the new parent that's being added. - */ - canMoveItemOutOfDrive?: boolean - /** - * Deprecated - use canMoveItemOutOfDrive instead. - */ - canMoveItemOutOfTeamDrive?: boolean - /** - * Whether the current user can move this item within this shared drive or My Drive. Note that a request to change the parent of the item might still fail depending on the new parent that's being added and the parent that's being removed. - */ - canMoveItemWithinDrive?: boolean - /** - * Deprecated - use canMoveItemWithinDrive instead. - */ - canMoveItemWithinTeamDrive?: boolean - /** - * Deprecated - use canMoveItemWithinDrive or canMoveItemOutOfDrive instead. - */ - canMoveTeamDriveItem?: boolean - /** - * Whether the current user can read the shared drive to which this file belongs. Only populated for items in shared drives. - */ - canReadDrive?: boolean - /** - * Whether the current user can read the labels on this file. - */ - canReadLabels?: boolean - /** - * Whether the current user can read the revisions resource of this file. For a shared drive item, whether revisions of non-folder descendants of this item, or this item itself if it's not a folder, can be read. - */ - canReadRevisions?: boolean - /** - * Deprecated - use canReadDrive instead. - */ - canReadTeamDrive?: boolean - /** - * Whether the current user can remove children from this folder. This is always false when the item isn't a folder. For a folder in a shared drive, use canDeleteChildren or canTrashChildren instead. - */ - canRemoveChildren?: boolean - /** - * Whether the current user can remove a parent from the item without adding another parent in the same request. Not populated for shared drive files. - */ - canRemoveMyDriveParent?: boolean - /** - * Whether the current user can rename this file. - */ - canRename?: boolean - /** - * Whether the current user can modify the sharing settings for this file. - */ - canShare?: boolean - /** - * Whether the current user can move this file to trash. - */ - canTrash?: boolean - /** - * Whether the current user can trash children of this folder. This is false when the item isn't a folder. Only populated for items in shared drives. - */ - canTrashChildren?: boolean - /** - * Whether the current user can restore this file from trash. - */ - canUntrash?: boolean - } - /** - * Additional information about the content of the file. These fields are never populated in responses. - */ - contentHints?: { - /** - * Text to be indexed for the file to improve fullText queries. This is limited to 128 KB in length and might contain HTML elements. For more information, see Manage file metadata. - */ - indexableText?: string - /** - * A thumbnail for the file. This will only be used if Google Drive cannot generate a standard thumbnail. - */ - thumbnail?: { - /** - * The thumbnail data encoded with URL-safe Base64 (RFC 4648 section 5). - */ - image?: string - /** - * The MIME type of the thumbnail. - */ - mimeType?: string - } - } - /** - * Restrictions for accessing the content of the file. Only populated if such a restriction exists. - */ - contentRestrictions?: Array - /** - * Whether the options to copy, print, or download this file, should be disabled for readers and commenters. - */ - copyRequiresWriterPermission?: boolean - /** - * The time at which the file was created (RFC 3339 date-time). - */ - createdTime?: Date - /** - * A short description of the file. - */ - description?: string - /** - * ID of the shared drive the file resides in. Only populated for items in shared drives. - */ - driveId?: string - /** - * Whether the file has been explicitly trashed, as opposed to recursively trashed from a parent folder. - */ - explicitlyTrashed?: boolean - /** - * Links for exporting Docs Editors files to specific formats. - */ - readonly exportLinks?: { - [key: string]: string - } - /** - * The final component of fullFileExtension. This is only available for files with binary content in Google Drive. - */ - fileExtension?: string - /** - * The color for a folder or shortcut to a folder as an RGB hex string. The supported colors are published in the folderColorPalette field of the About resource. - * If an unsupported color is specified, the closest color in the palette will be used instead. - */ - folderColorRgb?: string - /** - * The full file extension extracted from the name field. Can contain multiple concatenated extensions, such as "tar.gz". This is only available for files with binary content in Google Drive. - * This is automatically updated when the name field changes, however it's not cleared if the new name does not contain a valid extension. - */ - fullFileExtension?: string - /** - * Whether there are permissions directly on this file. This field is only populated for items in shared drives. - */ - hasAugmentedPermissions?: boolean - /** - * Whether this file has a thumbnail. This does not indicate whether the requesting app has access to the thumbnail. To check access, look for the presence of the thumbnailLink field. - */ - hasThumbnail?: boolean - /** - * The ID of the file's head revision. This is only available for files with binary content in Google Drive. - */ - headRevisionId?: string - /** - * A static, unauthenticated link to the file's icon. - */ - iconLink?: string - /** - * The ID of the file. - */ - id?: string - /** - * Additional metadata about image media, if available. - */ - imageMediaMetadata?: { - /** - * The aperture used to create the photo (f-number). - */ - aperture?: number - /** - * The make of the camera used to create the photo. - */ - cameraMake?: string - /** - * The model of the camera used to create the photo. - */ - cameraModel?: string - /** - * The color space of the photo. - */ - colorSpace?: string - /** - * The exposure bias of the photo (APEX value). - */ - exposureBias?: number - /** - * The exposure mode used to create the photo. - */ - exposureMode?: string - /** - * The length of the exposure, in seconds. - */ - exposureTime?: number - /** - * Whether a flash was used to create the photo. - */ - flashUsed?: boolean - /** - * The focal length used to create the photo, in millimeters. - */ - focalLength?: number - /** - * The height of the image in pixels. - */ - height?: number - /** - * The ISO speed used to create the photo. - */ - isoSpeed?: number - /** - * The lens used to create the photo. - */ - lens?: string - /** - * Geographic location information stored in the image. - */ - location?: { - /** - * The altitude stored in the image. - */ - altitude?: number - /** - * The latitude stored in the image. - */ - latitude?: number - /** - * The longitude stored in the image. - */ - longitude?: number - } - /** - * The smallest f-number of the lens at the focal length used to create the photo (APEX value). - */ - maxApertureValue?: number - /** - * The metering mode used to create the photo. - */ - meteringMode?: string - /** - * The number of clockwise 90-degree rotations applied from the image's original orientation. - */ - rotation?: number - /** - * The type of sensor used to create the photo. - */ - sensor?: string - /** - * The distance to the subject of the photo, in meters. - */ - subjectDistance?: number - /** - * The date and time the photo was taken (EXIF DateTime). - */ - time?: string - /** - * The white balance mode used to create the photo. - */ - whiteBalance?: string - /** - * The width of the image in pixels. - */ - width?: number - } - /** - * Whether the requesting app created or opened the file. - */ - isAppAuthorized?: boolean - /** - * Identifies what kind of resource this is. Value: the fixed string "drive#file". - */ - kind?: string - /** - * An overview of the labels on the file. - */ - labelInfo?: { - /** - * The set of labels on the file as requested by the label IDs in the includeLabels parameter. By default, no labels are returned. - */ - labels?: Array