1
0

feat(sdk): enhance authentication and account management API endpoints

- Added new authentication routes for user sign-in, sign-up, and password reset functionalities.
- Updated account management routes to include bulk delete and validation for accounts.
- Refactored type definitions to utilize utility functions for better type safety and clarity.
- Introduced new methods for handling user authentication and account operations in the SDK.
This commit is contained in:
Ahmed Bouhuolia
2026-03-05 01:07:14 +02:00
parent 8960ea1ca2
commit ac8dcfed67
42 changed files with 1362 additions and 960 deletions
+176
View File
@@ -62,6 +62,182 @@
]
}
},
"/api/auth/signin": {
"post": {
"operationId": "AuthController_signin",
"summary": "Sign in a user",
"parameters": [],
"requestBody": {
"required": true,
"content": {
"application/json": {
"schema": {
"type": "object",
"required": ["email", "password"],
"properties": {
"email": { "type": "string", "example": "user@example.com", "description": "User email address" },
"password": { "type": "string", "example": "password123", "description": "User password" }
}
}
}
}
},
"responses": {
"200": {
"description": "Sign-in successful",
"content": {
"application/json": {
"schema": {
"type": "object",
"properties": {
"accessToken": { "type": "string", "description": "JWT access token" },
"organizationId": { "type": "string", "description": "Organization ID" },
"tenantId": { "type": "number", "description": "Tenant ID" },
"userId": { "type": "number", "description": "User ID" }
}
}
}
}
}
},
"tags": ["Auth"]
}
},
"/api/auth/signup": {
"post": {
"operationId": "AuthController_signup",
"summary": "Sign up a new user",
"parameters": [],
"requestBody": {
"required": true,
"content": {
"application/json": {
"schema": {
"type": "object",
"required": ["firstName", "lastName", "email", "password"],
"properties": {
"firstName": { "type": "string", "example": "John", "description": "User first name" },
"lastName": { "type": "string", "example": "Doe", "description": "User last name" },
"email": { "type": "string", "format": "email", "example": "john.doe@example.com", "description": "User email address" },
"password": { "type": "string", "example": "password123", "description": "User password" }
}
}
}
}
},
"responses": {
"201": { "description": "Sign-up initiated. Check email for confirmation." }
},
"tags": ["Auth"]
}
},
"/api/auth/signup/verify": {
"post": {
"operationId": "AuthController_signupConfirm",
"summary": "Confirm user signup",
"parameters": [],
"requestBody": {
"required": true,
"content": {
"application/json": {
"schema": {
"type": "object",
"required": ["email", "token"],
"properties": {
"email": { "type": "string", "example": "user@example.com", "description": "User email address" },
"token": { "type": "string", "example": "confirmation-token", "description": "Signup confirmation token from email" }
}
}
}
}
},
"responses": {
"200": { "description": "Signup confirmed successfully." }
},
"tags": ["Auth"]
}
},
"/api/auth/send_reset_password": {
"post": {
"operationId": "AuthController_sendResetPassword",
"summary": "Send reset password email",
"parameters": [],
"requestBody": {
"required": true,
"content": {
"application/json": {
"schema": {
"type": "object",
"required": ["email"],
"properties": {
"email": { "type": "string", "example": "user@example.com", "description": "User email address to send reset link to" }
}
}
}
}
},
"responses": {
"200": { "description": "Reset password email sent if the account exists." }
},
"tags": ["Auth"]
}
},
"/api/auth/reset_password/{token}": {
"post": {
"operationId": "AuthController_resetPassword",
"summary": "Reset password using token",
"parameters": [
{
"name": "token",
"in": "path",
"required": true,
"description": "Reset password token from email link",
"schema": { "type": "string" }
}
],
"requestBody": {
"required": true,
"content": {
"application/json": {
"schema": {
"type": "object",
"required": ["password"],
"properties": {
"password": { "type": "string", "example": "new-password", "description": "New password" }
}
}
}
}
},
"responses": {
"200": { "description": "Password reset successfully." }
},
"tags": ["Auth"]
}
},
"/api/auth/meta": {
"get": {
"operationId": "AuthController_meta",
"summary": "Get auth metadata (e.g. signup disabled)",
"parameters": [],
"responses": {
"200": {
"description": "Auth metadata for the login/signup page",
"content": {
"application/json": {
"schema": {
"type": "object",
"properties": {
"signupDisabled": { "type": "boolean", "description": "Whether signup is disabled" }
}
}
}
}
}
},
"tags": ["Auth"]
}
},
"/api/api-keys/generate": {
"post": {
"operationId": "AuthApiKeysController_generate",
+11 -19
View File
@@ -1,5 +1,6 @@
import type { ApiFetcher } from './fetch-utils';
import type { paths } from './schema';
import { paths } from './schema';
import { OpForPath, OpQueryParams, OpRequestBody, OpResponseBody } from './utils';
export const ACCOUNTS_ROUTES = {
LIST: '/api/accounts',
@@ -12,24 +13,15 @@ export const ACCOUNTS_ROUTES = {
INACTIVATE: '/api/accounts/{id}/inactivate',
} as const satisfies Record<string, keyof paths>;
type GetAccounts = paths[typeof ACCOUNTS_ROUTES.LIST]['get'];
type GetAccount = paths[typeof ACCOUNTS_ROUTES.BY_ID]['get'];
type GetAccountTypes = paths[typeof ACCOUNTS_ROUTES.TYPES]['get'];
type GetAccountTransactions = paths[typeof ACCOUNTS_ROUTES.TRANSACTIONS]['get'];
type CreateAccount = paths[typeof ACCOUNTS_ROUTES.LIST]['post'];
type EditAccount = paths[typeof ACCOUNTS_ROUTES.BY_ID]['put'];
type BulkDeleteAccounts = paths[typeof ACCOUNTS_ROUTES.BULK_DELETE]['post'];
type ValidateBulkDelete = paths[typeof ACCOUNTS_ROUTES.VALIDATE_BULK_DELETE]['post'];
export type AccountsList = GetAccounts['responses'][200]['content']['application/json'];
export type Account = GetAccount['responses'][200]['content']['application/json'];
export type AccountTypesList = GetAccountTypes['responses'][200]['content']['application/json'];
export type AccountTransactionsList = GetAccountTransactions['responses'][200]['content']['application/json'];
export type CreateAccountBody = CreateAccount['requestBody']['content']['application/json'];
export type EditAccountBody = EditAccount['requestBody']['content']['application/json'];
export type BulkDeleteBody = BulkDeleteAccounts['requestBody']['content']['application/json'];
export type ValidateBulkDeleteResponse = ValidateBulkDelete['responses'][200]['content']['application/json'];
export type GetAccountsQuery = NonNullable<GetAccounts['parameters']['query']>;
export type AccountsList = OpResponseBody<OpForPath<typeof ACCOUNTS_ROUTES.LIST, 'get'>>;
export type Account = OpResponseBody<OpForPath<typeof ACCOUNTS_ROUTES.BY_ID, 'get'>>;
export type AccountTypesList = OpResponseBody<OpForPath<typeof ACCOUNTS_ROUTES.TYPES, 'get'>>;
export type AccountTransactionsList = OpResponseBody<OpForPath<typeof ACCOUNTS_ROUTES.TRANSACTIONS, 'get'>>;
export type CreateAccountBody = OpRequestBody<OpForPath<typeof ACCOUNTS_ROUTES.LIST, 'post'>>;
export type EditAccountBody = OpRequestBody<OpForPath<typeof ACCOUNTS_ROUTES.BY_ID, 'put'>>;
export type BulkDeleteBody = OpRequestBody<OpForPath<typeof ACCOUNTS_ROUTES.BULK_DELETE, 'post'>>;
export type ValidateBulkDeleteResponse = OpResponseBody<OpForPath<typeof ACCOUNTS_ROUTES.VALIDATE_BULK_DELETE, 'post'>>;
export type GetAccountsQuery = OpQueryParams<OpForPath<typeof ACCOUNTS_ROUTES.LIST, 'get'>>;
function normalizeAccountsResponse(
data: AccountsList | { accounts: AccountsList }
+4 -7
View File
@@ -1,5 +1,6 @@
import type { ApiFetcher } from './fetch-utils';
import type { paths } from './schema';
import { paths } from './schema';
import { OpForPath, OpRequestBody, OpResponseBody } from './utils';
export const API_KEYS_ROUTES = {
LIST: '/api/api-keys',
@@ -7,12 +8,8 @@ export const API_KEYS_ROUTES = {
REVOKE: '/api/api-keys/{id}/revoke',
} as const satisfies Record<string, keyof paths>;
type GetApiKeys = paths[typeof API_KEYS_ROUTES.LIST]['get'];
type GenerateApiKey = paths[typeof API_KEYS_ROUTES.GENERATE]['post'];
type RevokeApiKey = paths[typeof API_KEYS_ROUTES.REVOKE]['put'];
export type ApiKeysList = GetApiKeys['responses'][200]['content']['application/json'];
export type GenerateApiKeyBody = GenerateApiKey['requestBody']['content']['application/json'];
export type ApiKeysList = OpResponseBody<OpForPath<typeof API_KEYS_ROUTES.LIST, 'get'>>;
export type GenerateApiKeyBody = OpRequestBody<OpForPath<typeof API_KEYS_ROUTES.GENERATE, 'post'>>;
export async function fetchApiKeys(fetcher: ApiFetcher): Promise<ApiKeysList> {
const get = fetcher.path(API_KEYS_ROUTES.LIST).method('get').create();
+32 -1
View File
@@ -1,11 +1,42 @@
import type { ApiFetcher } from './fetch-utils';
import type { paths } from './schema';
import { paths } from './schema';
export const ATTACHMENTS_ROUTES = {
LIST: '/api/attachments',
BY_ID: '/api/attachments/{id}',
PRESIGNED_URL: '/api/attachments/{id}/presigned-url',
} as const satisfies Record<string, keyof paths>;
/** Response shape from POST /api/attachments (upload). Schema may not define it; server returns { data }. */
export interface UploadAttachmentResponse {
id: number;
key: string;
mimeType: string;
originName: string;
size: number;
createdAt: string;
}
/**
* Upload an attachment via multipart/form-data. Uses the fetcher's baseUrl and init (headers).
* The OpenAPI client may not support FormData, so we use fetch with the same config.
*/
export async function uploadAttachment(
fetcher: ApiFetcher,
formData: FormData
): Promise<UploadAttachmentResponse> {
const post = fetcher.path(ATTACHMENTS_ROUTES.LIST).method('post').create();
// Generated client expects typed body; FormData is valid for multipart/form-data at runtime
const res = await (
post as unknown as (body: FormData) => Promise<{ data?: { data?: UploadAttachmentResponse } }>
)(formData);
const data = (res as { data?: { data?: UploadAttachmentResponse } })?.data?.data;
if (!data) {
throw new Error('Upload attachment: no data in response');
}
return data;
}
export async function deleteAttachment(fetcher: ApiFetcher, id: string): Promise<void> {
const del = fetcher.path(ATTACHMENTS_ROUTES.BY_ID).method('delete').create();
await del({ id });
+141 -5
View File
@@ -1,18 +1,154 @@
import type { ApiFetcher } from './fetch-utils';
import type { paths } from './schema';
import { paths } from './schema';
import { OpForPath, OpRequestBody, OpResponseBody } from './utils';
// All auth routes (schema paths). After running generate:sdk-types, these match the OpenAPI spec.
export const AUTH_ROUTES = {
ACCOUNT: '/api/auth/account',
RESEND_SIGNUP: '/api/auth/signup/verify/resend',
SIGNIN: '/api/auth/signin',
SIGNUP: '/api/auth/signup',
SIGNUP_VERIFY: '/api/auth/signup/verify',
SEND_RESET_PASSWORD: '/api/auth/send_reset_password',
RESET_PASSWORD: '/api/auth/reset_password/{token}',
META: '/api/auth/meta',
} as const satisfies Record<string, keyof paths>;
type GetAuthedAccount = paths[typeof AUTH_ROUTES.ACCOUNT]['get'];
// Schema-derived types (from paths/operations). No manual interfaces.
export type AuthedAccount = OpResponseBody<
OpForPath<typeof AUTH_ROUTES.ACCOUNT, 'get'>
>;
type GetAuthedAccount200 = GetAuthedAccount['responses'][200];
export type AuthedAccount = GetAuthedAccount200 extends { content?: { 'application/json': infer J } } ? J : unknown;
export type ResendSignupConfirmBody = OpRequestBody<
OpForPath<typeof AUTH_ROUTES.RESEND_SIGNUP, 'post'>
>;
export async function fetchAuthedAccount(fetcher: ApiFetcher): Promise<AuthedAccount> {
export type AuthSigninBody = OpRequestBody<
OpForPath<typeof AUTH_ROUTES.SIGNIN, 'post'>
>;
export type AuthSigninResponse = OpResponseBody<
OpForPath<typeof AUTH_ROUTES.SIGNIN, 'post'>
>;
export type AuthSignupBody = OpRequestBody<
OpForPath<typeof AUTH_ROUTES.SIGNUP, 'post'>
>;
export type AuthSignupVerifyBody = OpRequestBody<
OpForPath<typeof AUTH_ROUTES.SIGNUP_VERIFY, 'post'>
>;
export type AuthSendResetPasswordBody = OpRequestBody<
OpForPath<typeof AUTH_ROUTES.SEND_RESET_PASSWORD, 'post'>
>;
export type AuthResetPasswordBody = OpRequestBody<
OpForPath<typeof AUTH_ROUTES.RESET_PASSWORD, 'post'>
>;
export type AuthMetaResponse = OpResponseBody<
OpForPath<typeof AUTH_ROUTES.META, 'get'>
>;
/**
* Fetches the authenticated account (requires auth token).
*/
export async function fetchAuthedAccount(
fetcher: ApiFetcher
): Promise<AuthedAccount> {
const get = fetcher.path(AUTH_ROUTES.ACCOUNT).method('get').create();
const { data } = await get({});
return data as AuthedAccount;
}
/**
* Resends the signup confirmation message.
*/
export async function resendSignupConfirm(
fetcher: ApiFetcher,
body?: ResendSignupConfirmBody
): Promise<void> {
const post = fetcher.path(AUTH_ROUTES.RESEND_SIGNUP).method('post').create();
await post(body ?? ({} as ResendSignupConfirmBody));
}
/**
* Sign in with email and password.
*/
export async function signin(
fetcher: ApiFetcher,
body: AuthSigninBody
): Promise<AuthSigninResponse> {
const post = fetcher.path(AUTH_ROUTES.SIGNIN).method('post').create();
const { data } = await post(body as never);
return data as AuthSigninResponse;
}
/**
* Sign up a new user.
*/
export async function signup(
fetcher: ApiFetcher,
body: AuthSignupBody
): Promise<unknown> {
const post = fetcher.path(AUTH_ROUTES.SIGNUP).method('post').create();
const { data } = await post(body as never);
return data;
}
/**
* Confirm user signup with email and token.
*/
export async function signupConfirm(
fetcher: ApiFetcher,
body: AuthSignupVerifyBody
): Promise<unknown> {
const post = fetcher
.path(AUTH_ROUTES.SIGNUP_VERIFY)
.method('post')
.create();
const { data } = await post(body as never);
return data;
}
/**
* Send reset password email.
*/
export async function sendResetPassword(
fetcher: ApiFetcher,
body: AuthSendResetPasswordBody
): Promise<unknown> {
const post = fetcher
.path(AUTH_ROUTES.SEND_RESET_PASSWORD)
.method('post')
.create();
const { data } = await post(body as never);
return data;
}
/**
* Reset password using token (from email link).
*/
export async function resetPassword(
fetcher: ApiFetcher,
token: string,
body: AuthResetPasswordBody
): Promise<unknown> {
const post = fetcher
.path(AUTH_ROUTES.RESET_PASSWORD)
.method('post')
.create();
const { data } = await post({ token, ...(body as object) } as never);
return data;
}
/**
* Get auth metadata (e.g. for login page).
*/
export async function fetchAuthMeta(
fetcher: ApiFetcher
): Promise<AuthMetaResponse> {
const get = fetcher.path(AUTH_ROUTES.META).method('get').create();
const { data } = await get({});
return data as AuthMetaResponse;
}
+34 -27
View File
@@ -1,11 +1,14 @@
import type { ApiFetcher } from './fetch-utils';
import type { paths } from './schema';
import { paths } from './schema';
import { OpForPath, OpRequestBody, OpResponseBody } from './utils';
export const BANK_RULES_ROUTES = {
RULES: '/api/banking/rules',
RULE_BY_ID: '/api/banking/rules/{id}',
ACCOUNTS_DISCONNECT: '/api/banking/accounts/{id}/disconnect',
ACCOUNTS_REFRESH: '/api/banking/accounts/{id}/refresh',
ACCOUNTS_PAUSE: '/api/banking/accounts/{id}/pause',
ACCOUNTS_RESUME: '/api/banking/accounts/{id}/resume',
MATCHING_MATCHED: '/api/banking/matching/matched',
MATCHING_MATCH: '/api/banking/matching/match',
MATCHING_UNMATCH: '/api/banking/matching/unmatch/{uncategorizedTransactionId}',
@@ -18,33 +21,15 @@ export const BANK_RULES_ROUTES = {
UNCATEGORIZED_AUTOFILL: '/api/banking/uncategorized/autofill',
} as const satisfies Record<string, keyof paths>;
type GetBankRules = paths[typeof BANK_RULES_ROUTES.RULES]['get'];
type GetBankRule = paths[typeof BANK_RULES_ROUTES.RULE_BY_ID]['get'];
type CreateBankRule = paths[typeof BANK_RULES_ROUTES.RULES]['post'];
type EditBankRule = paths[typeof BANK_RULES_ROUTES.RULE_BY_ID]['put'];
type DeleteBankRule = paths[typeof BANK_RULES_ROUTES.RULE_BY_ID]['delete'];
export type BankRulesListResponse = OpResponseBody<OpForPath<typeof BANK_RULES_ROUTES.RULES, 'get'>>;
export type BankRuleResponse = OpResponseBody<OpForPath<typeof BANK_RULES_ROUTES.RULE_BY_ID, 'get'>>;
export type CreateBankRuleBody = OpRequestBody<OpForPath<typeof BANK_RULES_ROUTES.RULES, 'post'>>;
export type EditBankRuleBody = OpRequestBody<OpForPath<typeof BANK_RULES_ROUTES.RULE_BY_ID, 'put'>>;
export type CreateBankRuleResponse = OpResponseBody<OpForPath<typeof BANK_RULES_ROUTES.RULES, 'post'>>;
type GetBankRules200 = GetBankRules['responses'][200];
type GetBankRule200 = GetBankRule['responses'][200];
type CreateBankRule201 = CreateBankRule['responses'][201];
export type BankRulesListResponse = GetBankRules200 extends {
content?: { 'application/json': infer J };
}
? J
: unknown;
export type BankRuleResponse = GetBankRule200 extends {
content?: { 'application/json': infer J };
}
? J
: unknown;
export type CreateBankRuleBody = CreateBankRule['requestBody']['content']['application/json'];
export type EditBankRuleBody = EditBankRule['requestBody']['content']['application/json'];
export type CreateBankRuleResponse = CreateBankRule201 extends {
content?: { 'application/json': infer J };
}
? J
: unknown;
/** Path params for pause/resume bank account (id = bankAccountId). */
export type PauseBankAccountParams = OpForPath<typeof BANK_RULES_ROUTES.ACCOUNTS_PAUSE, 'post'> extends { parameters: { path: infer P } } ? P : never;
export type ResumeBankAccountParams = OpForPath<typeof BANK_RULES_ROUTES.ACCOUNTS_RESUME, 'post'> extends { parameters: { path: infer P } } ? P : never;
export async function fetchBankRules(fetcher: ApiFetcher): Promise<BankRulesListResponse> {
const get = fetcher.path(BANK_RULES_ROUTES.RULES).method('get').create();
@@ -106,6 +91,28 @@ export async function refreshBankAccount(
await post({ id });
}
export async function pauseBankAccount(
fetcher: ApiFetcher,
id: number
): Promise<void> {
const post = fetcher
.path(BANK_RULES_ROUTES.ACCOUNTS_PAUSE)
.method('post')
.create();
await post({ id });
}
export async function resumeBankAccount(
fetcher: ApiFetcher,
id: number
): Promise<void> {
const post = fetcher
.path(BANK_RULES_ROUTES.ACCOUNTS_RESUME)
.method('post')
.create();
await post({ id });
}
export async function fetchMatchedTransactions(
fetcher: ApiFetcher,
uncategorizedTransactionIds: number[]
+14 -15
View File
@@ -1,5 +1,6 @@
import type { ApiFetcher } from './fetch-utils';
import type { paths } from './schema';
import { paths } from './schema';
import { OpForPath, OpQueryParams, OpRequestBody, OpResponseBody } from './utils';
export const BILLS_ROUTES = {
LIST: '/api/bills',
@@ -11,22 +12,20 @@ export const BILLS_ROUTES = {
BULK_DELETE: '/api/bills/bulk-delete',
} as const satisfies Record<string, keyof paths>;
type GetBills = paths[typeof BILLS_ROUTES.LIST]['get'];
type GetBill = paths[typeof BILLS_ROUTES.BY_ID]['get'];
type CreateBill = paths[typeof BILLS_ROUTES.LIST]['post'];
type EditBill = paths[typeof BILLS_ROUTES.BY_ID]['put'];
type DeleteBill = paths[typeof BILLS_ROUTES.BY_ID]['delete'];
export type BillsListResponse = OpResponseBody<OpForPath<typeof BILLS_ROUTES.LIST, 'get'>>;
export type Bill = OpResponseBody<OpForPath<typeof BILLS_ROUTES.BY_ID, 'get'>>;
export type CreateBillBody = OpRequestBody<OpForPath<typeof BILLS_ROUTES.LIST, 'post'>>;
export type EditBillBody = OpRequestBody<OpForPath<typeof BILLS_ROUTES.BY_ID, 'put'>>;
export type GetBillsQuery = OpQueryParams<OpForPath<typeof BILLS_ROUTES.LIST, 'get'>>;
export type BillsListResponse = GetBills['responses'][200]['content']['application/json'];
export type Bill = GetBill['responses'][200]['content']['application/json'];
export type CreateBillBody = CreateBill['requestBody']['content']['application/json'];
export type EditBillBody = EditBill['requestBody']['content']['application/json'];
export async function fetchBills(fetcher: ApiFetcher): Promise<BillsListResponse> {
export async function fetchBills(
fetcher: ApiFetcher,
query?: GetBillsQuery
): Promise<BillsListResponse> {
const get = fetcher.path(BILLS_ROUTES.LIST).method('get').create();
// Schema incorrectly marks path.id on list endpoint; route has no {id}
// eslint-disable-next-line @typescript-eslint/no-explicit-any
const { data } = await (get as (params?: any) => Promise<{ data: BillsListResponse }>)({});
const { data } = await (
get as unknown as (params?: GetBillsQuery) => Promise<{ data: BillsListResponse }>
)(query ?? {});
return data;
}
+6 -11
View File
@@ -1,5 +1,6 @@
import type { ApiFetcher } from './fetch-utils';
import type { paths } from './schema';
import { paths } from './schema';
import { OpForPath, OpRequestBody, OpResponseBody } from './utils';
export const BRANCHES_ROUTES = {
LIST: '/api/branches',
@@ -8,16 +9,10 @@ export const BRANCHES_ROUTES = {
MARK_AS_PRIMARY: '/api/branches/{id}/mark-as-primary',
} as const satisfies Record<string, keyof paths>;
type GetBranches = paths[typeof BRANCHES_ROUTES.LIST]['get'];
type GetBranch = paths[typeof BRANCHES_ROUTES.BY_ID]['get'];
type CreateBranch = paths[typeof BRANCHES_ROUTES.LIST]['post'];
type EditBranch = paths[typeof BRANCHES_ROUTES.BY_ID]['put'];
type DeleteBranch = paths[typeof BRANCHES_ROUTES.BY_ID]['delete'];
export type BranchesListResponse = GetBranches['responses'][200]['content']['application/json'];
export type Branch = GetBranch['responses'][200]['content']['application/json'];
export type CreateBranchBody = CreateBranch['requestBody']['content']['application/json'];
export type EditBranchBody = EditBranch['requestBody']['content']['application/json'];
export type BranchesListResponse = OpResponseBody<OpForPath<typeof BRANCHES_ROUTES.LIST, 'get'>>;
export type Branch = OpResponseBody<OpForPath<typeof BRANCHES_ROUTES.BY_ID, 'get'>>;
export type CreateBranchBody = OpRequestBody<OpForPath<typeof BRANCHES_ROUTES.LIST, 'post'>>;
export type EditBranchBody = OpRequestBody<OpForPath<typeof BRANCHES_ROUTES.BY_ID, 'put'>>;
export async function fetchBranches(fetcher: ApiFetcher): Promise<BranchesListResponse> {
const get = fetcher.path(BRANCHES_ROUTES.LIST).method('get').create();
+3 -5
View File
@@ -1,15 +1,13 @@
import type { ApiFetcher } from './fetch-utils';
import type { paths } from './schema';
import { paths } from './schema';
import { OpForPath, OpResponseBody } from './utils';
export const BANKING_ACCOUNTS_ROUTES = {
LIST: '/api/banking/accounts',
SUMMARY: '/api/banking/accounts/{bankAccountId}/summary',
} as const satisfies Record<string, keyof paths>;
type GetBankingAccounts = paths[typeof BANKING_ACCOUNTS_ROUTES.LIST]['get'];
type GetBankingAccounts200 = GetBankingAccounts['responses'][200];
export type BankingAccountsListResponse = GetBankingAccounts200 extends { content?: { 'application/json': infer J } } ? J : unknown;
export type BankingAccountsListResponse = OpResponseBody<OpForPath<typeof BANKING_ACCOUNTS_ROUTES.LIST, 'get'>>;
export async function fetchBankingAccounts(fetcher: ApiFetcher): Promise<BankingAccountsListResponse> {
const get = fetcher.path(BANKING_ACCOUNTS_ROUTES.LIST).method('get').create();
+3 -5
View File
@@ -1,5 +1,6 @@
import type { ApiFetcher } from './fetch-utils';
import type { paths } from './schema';
import { paths } from './schema';
import { OpForPath, OpResponseBody } from './utils';
export const CONTACTS_ROUTES = {
AUTO_COMPLETE: '/api/contacts/auto-complete',
@@ -7,10 +8,7 @@ export const CONTACTS_ROUTES = {
INACTIVATE: '/api/contacts/{id}/inactivate',
} as const satisfies Record<string, keyof paths>;
type AutoComplete = paths[typeof CONTACTS_ROUTES.AUTO_COMPLETE]['get'];
type AutoComplete200 = AutoComplete['responses'][200];
export type ContactsAutoCompleteResponse = AutoComplete200 extends { content?: { 'application/json': infer J } } ? J : unknown;
export type ContactsAutoCompleteResponse = OpResponseBody<OpForPath<typeof CONTACTS_ROUTES.AUTO_COMPLETE, 'get'>>;
export async function fetchContactsAutoComplete(fetcher: ApiFetcher): Promise<ContactsAutoCompleteResponse> {
const get = fetcher.path(CONTACTS_ROUTES.AUTO_COMPLETE).method('get').create();
+19 -29
View File
@@ -1,5 +1,6 @@
import type { ApiFetcher } from './fetch-utils';
import type { paths } from './schema';
import { paths } from './schema';
import { OpForPath, OpQueryParams, OpRequestBody, OpResponseBody } from './utils';
export const CREDIT_NOTES_ROUTES = {
LIST: '/api/credit-notes',
@@ -15,36 +16,25 @@ export const CREDIT_NOTES_ROUTES = {
APPLIED_INVOICE_BY_ID: '/api/credit-notes/applied-invoices/{applyCreditToInvoicesId}',
} as const satisfies Record<string, keyof paths>;
type GetCreditNotes = paths[typeof CREDIT_NOTES_ROUTES.LIST]['get'];
type GetCreditNote = paths[typeof CREDIT_NOTES_ROUTES.BY_ID]['get'];
type GetCreditNoteState = paths[typeof CREDIT_NOTES_ROUTES.STATE]['get'];
type CreateCreditNote = paths[typeof CREDIT_NOTES_ROUTES.LIST]['post'];
type EditCreditNote = paths[typeof CREDIT_NOTES_ROUTES.BY_ID]['put'];
type DeleteCreditNote = paths[typeof CREDIT_NOTES_ROUTES.BY_ID]['delete'];
type OpenCreditNote = paths[typeof CREDIT_NOTES_ROUTES.OPEN]['put'];
type ValidateBulkDeleteCreditNotes = paths[typeof CREDIT_NOTES_ROUTES.VALIDATE_BULK_DELETE]['post'];
type BulkDeleteCreditNotes = paths[typeof CREDIT_NOTES_ROUTES.BULK_DELETE]['post'];
type GetCreditNoteRefunds = paths[typeof CREDIT_NOTES_ROUTES.REFUNDS]['get'];
type CreateRefundCreditNote = paths[typeof CREDIT_NOTES_ROUTES.REFUNDS]['post'];
type DeleteRefundCreditNote = paths[typeof CREDIT_NOTES_ROUTES.REFUND_BY_ID]['delete'];
type GetAppliedInvoices = paths[typeof CREDIT_NOTES_ROUTES.APPLIED_INVOICES]['get'];
type GetApplyInvoices = paths[typeof CREDIT_NOTES_ROUTES.APPLY_INVOICES]['get'];
type ApplyCreditNoteToInvoices = paths[typeof CREDIT_NOTES_ROUTES.APPLY_INVOICES]['post'];
type DeleteApplyCreditNoteToInvoices = paths[typeof CREDIT_NOTES_ROUTES.APPLIED_INVOICE_BY_ID]['delete'];
export type CreditNotesListResponse = OpResponseBody<OpForPath<typeof CREDIT_NOTES_ROUTES.LIST, 'get'>>;
export type CreditNote = OpResponseBody<OpForPath<typeof CREDIT_NOTES_ROUTES.BY_ID, 'get'>>;
export type CreateCreditNoteBody = OpRequestBody<OpForPath<typeof CREDIT_NOTES_ROUTES.LIST, 'post'>>;
export type EditCreditNoteBody = OpRequestBody<OpForPath<typeof CREDIT_NOTES_ROUTES.BY_ID, 'put'>>;
export type ValidateBulkDeleteCreditNotesBody = OpRequestBody<OpForPath<typeof CREDIT_NOTES_ROUTES.VALIDATE_BULK_DELETE, 'post'>>;
export type ValidateBulkDeleteCreditNotesResponse = OpResponseBody<OpForPath<typeof CREDIT_NOTES_ROUTES.VALIDATE_BULK_DELETE, 'post'>>;
export type BulkDeleteCreditNotesBody = OpRequestBody<OpForPath<typeof CREDIT_NOTES_ROUTES.BULK_DELETE, 'post'>>;
export type CreateRefundCreditNoteBody = OpRequestBody<OpForPath<typeof CREDIT_NOTES_ROUTES.REFUNDS, 'post'>>;
export type ApplyCreditNoteToInvoicesBody = OpRequestBody<OpForPath<typeof CREDIT_NOTES_ROUTES.APPLY_INVOICES, 'post'>>;
export type GetCreditNotesQuery = OpQueryParams<OpForPath<typeof CREDIT_NOTES_ROUTES.LIST, 'get'>>;
export type CreditNotesListResponse = GetCreditNotes['responses'][200]['content']['application/json'];
export type CreditNote = GetCreditNote['responses'][200]['content']['application/json'];
export type CreateCreditNoteBody = CreateCreditNote['requestBody']['content']['application/json'];
export type EditCreditNoteBody = EditCreditNote['requestBody']['content']['application/json'];
export type ValidateBulkDeleteCreditNotesBody = ValidateBulkDeleteCreditNotes['requestBody']['content']['application/json'];
export type ValidateBulkDeleteCreditNotesResponse = ValidateBulkDeleteCreditNotes['responses'][200]['content']['application/json'];
export type BulkDeleteCreditNotesBody = BulkDeleteCreditNotes['requestBody']['content']['application/json'];
export type CreateRefundCreditNoteBody = CreateRefundCreditNote['requestBody']['content']['application/json'];
export type ApplyCreditNoteToInvoicesBody = ApplyCreditNoteToInvoices['requestBody']['content']['application/json'];
export async function fetchCreditNotes(fetcher: ApiFetcher): Promise<CreditNotesListResponse> {
export async function fetchCreditNotes(
fetcher: ApiFetcher,
query?: GetCreditNotesQuery
): Promise<CreditNotesListResponse> {
const getCreditNotes = fetcher.path(CREDIT_NOTES_ROUTES.LIST).method('get').create();
const { data } = await getCreditNotes({});
const { data } = await (
getCreditNotes as (params: GetCreditNotesQuery) => Promise<{ data: CreditNotesListResponse }>
)(query ?? {});
return data;
}
+6 -13
View File
@@ -1,5 +1,6 @@
import type { ApiFetcher } from './fetch-utils';
import type { paths } from './schema';
import { paths } from './schema';
import { OpForPath, OpRequestBody, OpResponseBody } from './utils';
export const CURRENCIES_ROUTES = {
LIST: '/api/currencies',
@@ -8,18 +9,10 @@ export const CURRENCIES_ROUTES = {
BY_CURRENCY_CODE: '/api/currencies/{currencyCode}',
} as const satisfies Record<string, keyof paths>;
type GetCurrencies = paths[typeof CURRENCIES_ROUTES.LIST]['get'];
type GetCurrencyByCode = paths[typeof CURRENCIES_ROUTES.BY_CURRENCY_CODE]['get'];
type CreateCurrency = paths[typeof CURRENCIES_ROUTES.LIST]['post'];
type EditCurrency = paths[typeof CURRENCIES_ROUTES.BY_ID]['put'];
type DeleteCurrency = paths[typeof CURRENCIES_ROUTES.BY_CODE]['delete'];
type GetCurrencies200 = GetCurrencies['responses'][200];
type GetCurrencyByCode200 = GetCurrencyByCode['responses'][200];
export type CurrenciesListResponse = GetCurrencies200 extends { content?: { 'application/json': infer J } } ? J : unknown;
export type Currency = GetCurrencyByCode200 extends { content?: { 'application/json': infer J } } ? J : unknown;
export type CreateCurrencyBody = CreateCurrency extends { requestBody: { content: { 'application/json': infer J } } } ? J : Record<string, unknown>;
export type EditCurrencyBody = EditCurrency extends { requestBody: { content: { 'application/json': infer J } } } ? J : Record<string, unknown>;
export type CurrenciesListResponse = OpResponseBody<OpForPath<typeof CURRENCIES_ROUTES.LIST, 'get'>>;
export type Currency = OpResponseBody<OpForPath<typeof CURRENCIES_ROUTES.BY_CURRENCY_CODE, 'get'>>;
export type CreateCurrencyBody = OpRequestBody<OpForPath<typeof CURRENCIES_ROUTES.LIST, 'post'>>;
export type EditCurrencyBody = OpRequestBody<OpForPath<typeof CURRENCIES_ROUTES.BY_ID, 'put'>>;
export async function fetchCurrencies(fetcher: ApiFetcher): Promise<CurrenciesListResponse> {
const get = fetcher.path(CURRENCIES_ROUTES.LIST).method('get').create();
+16 -17
View File
@@ -1,5 +1,6 @@
import type { ApiFetcher } from './fetch-utils';
import type { paths } from './schema';
import { paths } from './schema';
import { OpForPath, OpQueryParams, OpRequestBody, OpResponseBody } from './utils';
export const CUSTOMERS_ROUTES = {
LIST: '/api/customers',
@@ -9,24 +10,22 @@ export const CUSTOMERS_ROUTES = {
BULK_DELETE: '/api/customers/bulk-delete',
} as const satisfies Record<string, keyof paths>;
type GetCustomers = paths[typeof CUSTOMERS_ROUTES.LIST]['get'];
type GetCustomer = paths[typeof CUSTOMERS_ROUTES.BY_ID]['get'];
type CreateCustomer = paths[typeof CUSTOMERS_ROUTES.LIST]['post'];
type EditCustomer = paths[typeof CUSTOMERS_ROUTES.BY_ID]['put'];
type DeleteCustomer = paths[typeof CUSTOMERS_ROUTES.BY_ID]['delete'];
type ValidateBulkDelete = paths[typeof CUSTOMERS_ROUTES.VALIDATE_BULK_DELETE]['post'];
type BulkDelete = paths[typeof CUSTOMERS_ROUTES.BULK_DELETE]['post'];
export type CustomersListResponse = OpResponseBody<OpForPath<typeof CUSTOMERS_ROUTES.LIST, 'get'>>;
export type Customer = OpResponseBody<OpForPath<typeof CUSTOMERS_ROUTES.BY_ID, 'get'>>;
export type CreateCustomerBody = OpRequestBody<OpForPath<typeof CUSTOMERS_ROUTES.LIST, 'post'>>;
export type EditCustomerBody = OpRequestBody<OpForPath<typeof CUSTOMERS_ROUTES.BY_ID, 'put'>>;
export type ValidateBulkDeleteCustomersResponse = OpResponseBody<OpForPath<typeof CUSTOMERS_ROUTES.VALIDATE_BULK_DELETE, 'post'>>;
export type BulkDeleteCustomersBody = OpRequestBody<OpForPath<typeof CUSTOMERS_ROUTES.BULK_DELETE, 'post'>>;
export type GetCustomersQuery = OpQueryParams<OpForPath<typeof CUSTOMERS_ROUTES.LIST, 'get'>>;
export type CustomersListResponse = GetCustomers['responses'][200]['content']['application/json'];
export type Customer = GetCustomer['responses'][200]['content']['application/json'];
export type CreateCustomerBody = CreateCustomer['requestBody']['content']['application/json'];
export type EditCustomerBody = EditCustomer['requestBody']['content']['application/json'];
export type ValidateBulkDeleteCustomersResponse = ValidateBulkDelete['responses'][200]['content']['application/json'];
export type BulkDeleteCustomersBody = BulkDelete['requestBody']['content']['application/json'];
export async function fetchCustomers(fetcher: ApiFetcher): Promise<CustomersListResponse> {
export async function fetchCustomers(
fetcher: ApiFetcher,
query?: GetCustomersQuery
): Promise<CustomersListResponse> {
const get = fetcher.path(CUSTOMERS_ROUTES.LIST).method('get').create();
const { data } = await get({});
const { data } = await (get as (params: GetCustomersQuery) => Promise<{ data: CustomersListResponse }>)(
query ?? {}
);
return data;
}
+14 -15
View File
@@ -1,5 +1,6 @@
import type { ApiFetcher } from './fetch-utils';
import type { paths } from './schema';
import { paths } from './schema';
import { OpForPath, OpQueryParams, OpRequestBody, OpResponseBody } from './utils';
export const EXPENSES_ROUTES = {
LIST: '/api/expenses',
@@ -9,22 +10,20 @@ export const EXPENSES_ROUTES = {
BULK_DELETE: '/api/expenses/bulk-delete',
} as const satisfies Record<string, keyof paths>;
type GetExpenses = paths[typeof EXPENSES_ROUTES.LIST]['get'];
type GetExpense = paths[typeof EXPENSES_ROUTES.BY_ID]['get'];
type CreateExpense = paths[typeof EXPENSES_ROUTES.LIST]['post'];
type EditExpense = paths[typeof EXPENSES_ROUTES.BY_ID]['put'];
type DeleteExpense = paths[typeof EXPENSES_ROUTES.BY_ID]['delete'];
export type ExpensesListResponse = OpResponseBody<OpForPath<typeof EXPENSES_ROUTES.LIST, 'get'>>;
export type Expense = OpResponseBody<OpForPath<typeof EXPENSES_ROUTES.BY_ID, 'get'>>;
export type CreateExpenseBody = OpRequestBody<OpForPath<typeof EXPENSES_ROUTES.LIST, 'post'>>;
export type EditExpenseBody = OpRequestBody<OpForPath<typeof EXPENSES_ROUTES.BY_ID, 'put'>>;
export type GetExpensesQuery = OpQueryParams<OpForPath<typeof EXPENSES_ROUTES.LIST, 'get'>>;
type GetExpenses200 = GetExpenses['responses'][200];
type GetExpense200 = GetExpense['responses'][200];
export type ExpensesListResponse = GetExpenses200 extends { content?: { 'application/json': infer J } } ? J : unknown;
export type Expense = GetExpense200 extends { content?: { 'application/json': infer J } } ? J : unknown;
export type CreateExpenseBody = CreateExpense['requestBody']['content']['application/json'];
export type EditExpenseBody = EditExpense['requestBody']['content']['application/json'];
export async function fetchExpenses(fetcher: ApiFetcher): Promise<ExpensesListResponse> {
export async function fetchExpenses(
fetcher: ApiFetcher,
query?: GetExpensesQuery
): Promise<ExpensesListResponse> {
const get = fetcher.path(EXPENSES_ROUTES.LIST).method('get').create();
const { data } = await get({});
const { data } = await (get as (params?: GetExpensesQuery) => Promise<{ data: ExpensesListResponse }>)(
query ?? {}
);
return data;
}
+3 -5
View File
@@ -1,14 +1,12 @@
import type { ApiFetcher } from './fetch-utils';
import type { paths } from './schema';
import { paths } from './schema';
import { OpForPath, OpResponseBody } from './utils';
export const GENERIC_RESOURCE_ROUTES = {
META: '/api/resources/{resourceModel}/meta',
} as const satisfies Record<string, keyof paths>;
type GetResourceMeta = paths[typeof GENERIC_RESOURCE_ROUTES.META]['get'];
type GetResourceMeta200 = GetResourceMeta['responses'][200];
export type ResourceMetaResponse = GetResourceMeta200 extends { content?: { 'application/json': infer J } } ? J : unknown;
export type ResourceMetaResponse = OpResponseBody<OpForPath<typeof GENERIC_RESOURCE_ROUTES.META, 'get'>>;
export async function fetchResourceMeta(
fetcher: ApiFetcher,
+45 -518
View File
@@ -2,521 +2,48 @@
* Re-export OpenAPI-generated types for use by server and webapp.
* Run `pnpm run generate:sdk-types` from repo root to regenerate schema from the server OpenAPI spec.
*/
export type { paths, components, operations } from './schema';
export type { ApiFetcher, CreateApiFetcherConfig } from './fetch-utils';
export { normalizeApiPath, createApiFetcher } from './fetch-utils';
export {
ACCOUNTS_ROUTES,
fetchAccounts,
fetchAccount,
fetchAccountTypes,
fetchAccountTransactions,
createAccount,
editAccount,
deleteAccount,
activateAccount,
inactivateAccount,
bulkDeleteAccounts,
validateBulkDeleteAccounts,
} from './accounts';
export type {
AccountsList,
Account,
AccountTypesList,
AccountTransactionsList,
CreateAccountBody,
EditAccountBody,
BulkDeleteBody,
ValidateBulkDeleteResponse,
GetAccountsQuery,
} from './accounts';
export {
CREDIT_NOTES_ROUTES,
fetchCreditNotes,
fetchCreditNote,
fetchCreditNoteState,
createCreditNote,
editCreditNote,
deleteCreditNote,
openCreditNote,
validateBulkDeleteCreditNotes,
bulkDeleteCreditNotes,
fetchCreditNoteRefunds,
createRefundCreditNote,
deleteRefundCreditNote,
fetchAppliedInvoices,
fetchCreditNoteAssociatedInvoicesToApply,
applyCreditNoteToInvoices,
deleteApplyCreditNoteToInvoices,
} from './credit-notes';
export type {
CreditNotesListResponse,
CreditNote,
CreateCreditNoteBody,
EditCreditNoteBody,
ValidateBulkDeleteCreditNotesBody,
ValidateBulkDeleteCreditNotesResponse,
BulkDeleteCreditNotesBody,
CreateRefundCreditNoteBody,
ApplyCreditNoteToInvoicesBody,
} from './credit-notes';
export {
API_KEYS_ROUTES,
fetchApiKeys,
generateApiKey,
revokeApiKey,
} from './api-keys';
export type { ApiKeysList, GenerateApiKeyBody } from './api-keys';
export {
SALE_INVOICES_ROUTES,
fetchSaleInvoices,
fetchSaleInvoice,
createSaleInvoice,
editSaleInvoice,
deleteSaleInvoice,
} from './sale-invoices';
export type {
SaleInvoicesListResponse,
SaleInvoice,
CreateSaleInvoiceBody,
EditSaleInvoiceBody,
} from './sale-invoices';
export {
CUSTOMERS_ROUTES,
fetchCustomers,
fetchCustomer,
createCustomer,
editCustomer,
deleteCustomer,
validateBulkDeleteCustomers,
bulkDeleteCustomers,
} from './customers';
export type {
CustomersListResponse,
Customer,
CreateCustomerBody,
EditCustomerBody,
ValidateBulkDeleteCustomersResponse,
BulkDeleteCustomersBody,
} from './customers';
export {
VENDORS_ROUTES,
fetchVendors,
fetchVendor,
createVendor,
editVendor,
deleteVendor,
validateBulkDeleteVendors,
bulkDeleteVendors,
} from './vendors';
export type {
VendorsListResponse,
Vendor,
CreateVendorBody,
EditVendorBody,
ValidateBulkDeleteVendorsResponse,
BulkDeleteVendorsBody,
} from './vendors';
export {
BILLS_ROUTES,
fetchBills,
fetchBill,
createBill,
editBill,
deleteBill,
} from './bills';
export type {
BillsListResponse,
Bill,
CreateBillBody,
EditBillBody,
} from './bills';
export {
ITEMS_ROUTES,
fetchItems,
fetchItem,
createItem,
editItem,
deleteItem,
inactivateItem,
activateItem,
validateBulkDeleteItems,
bulkDeleteItems,
} from './items';
export type {
ItemsListResponse,
Item,
CreateItemBody,
EditItemBody,
BulkDeleteItemsBody,
ValidateBulkDeleteItemsResponse,
} from './items';
export {
BRANCHES_ROUTES,
fetchBranches,
fetchBranch,
createBranch,
editBranch,
deleteBranch,
activateBranches,
markBranchAsPrimary,
} from './branches';
export type {
BranchesListResponse,
Branch,
CreateBranchBody,
EditBranchBody,
} from './branches';
export {
WAREHOUSES_ROUTES,
fetchWarehouses,
fetchWarehouse,
createWarehouse,
editWarehouse,
deleteWarehouse,
activateWarehouses,
markWarehousePrimary,
} from './warehouses';
export type {
WarehousesListResponse,
Warehouse,
CreateWarehouseBody,
EditWarehouseBody,
} from './warehouses';
export {
EXPENSES_ROUTES,
fetchExpenses,
fetchExpense,
createExpense,
editExpense,
deleteExpense,
publishExpense,
} from './expenses';
export type {
ExpensesListResponse,
Expense,
CreateExpenseBody,
EditExpenseBody,
} from './expenses';
export {
MANUAL_JOURNALS_ROUTES,
fetchManualJournals,
fetchManualJournal,
createManualJournal,
editManualJournal,
deleteManualJournal,
publishManualJournal,
} from './manual-journals';
export type {
ManualJournalsListResponse,
ManualJournal,
CreateManualJournalBody,
EditManualJournalBody,
} from './manual-journals';
export {
ROLES_ROUTES,
fetchRoles,
fetchRole,
createRole,
editRole,
deleteRole,
fetchRolePermissionsSchema,
} from './roles';
export type {
RolesListResponse,
Role,
CreateRoleBody,
EditRoleBody,
RolePermissionsSchema,
} from './roles';
export {
USERS_ROUTES,
fetchUsers,
fetchUser,
editUser,
deleteUser,
activateUser,
inactivateUser,
} from './users';
export type {
UsersListResponse,
User,
EditUserBody,
GetUsersQuery,
} from './users';
export {
SETTINGS_ROUTES,
fetchSettings,
saveSettings,
} from './settings';
export type { SettingsResponse, SaveSettingsBody } from './settings';
export {
ORGANIZATION_ROUTES,
fetchOrganizationCurrent,
fetchOrganization,
updateOrganization,
} from './organization';
export type {
OrganizationCurrent,
Organization,
UpdateOrganizationBody,
} from './organization';
export {
SUBSCRIPTION_ROUTES,
fetchSubscriptions,
cancelSubscription,
resumeSubscription,
} from './subscription';
export type { SubscriptionsListResponse } from './subscription';
export {
CURRENCIES_ROUTES,
fetchCurrencies,
fetchCurrency,
fetchCurrencyByCode,
createCurrency,
editCurrency,
deleteCurrency,
} from './currencies';
export type {
CurrenciesListResponse,
Currency,
CreateCurrencyBody,
EditCurrencyBody,
} from './currencies';
export {
TAX_RATES_ROUTES,
fetchTaxRates,
fetchTaxRate,
createTaxRate,
editTaxRate,
deleteTaxRate,
activateTaxRate,
inactivateTaxRate,
} from './tax-rates';
export type {
TaxRatesListResponse,
TaxRate,
CreateTaxRateBody,
EditTaxRateBody,
} from './tax-rates';
export {
ATTACHMENTS_ROUTES,
deleteAttachment,
fetchAttachmentPresignedUrl,
} from './attachments';
export {
INVITE_ROUTES,
inviteUser,
resendInvite,
acceptInvite,
fetchInviteCheck,
} from './invite';
export type { InviteUserBody, AcceptInviteBody } from './invite';
export {
AUTH_ROUTES,
fetchAuthedAccount,
} from './authentication';
export type { AuthedAccount } from './authentication';
export {
CONTACTS_ROUTES,
fetchContactsAutoComplete,
activateContact,
inactivateContact,
} from './contacts';
export type { ContactsAutoCompleteResponse } from './contacts';
export {
ITEMS_CATEGORIES_ROUTES,
fetchItemCategories,
fetchItemCategory,
createItemCategory,
editItemCategory,
deleteItemCategory,
} from './items-categories';
export type {
ItemCategoriesListResponse,
ItemCategory,
CreateItemCategoryBody,
EditItemCategoryBody,
} from './items-categories';
export {
VIEWS_ROUTES,
fetchResourceView,
} from './views';
export type { ResourceViewResponse } from './views';
export {
TRANSACTIONS_LOCKING_ROUTES,
fetchTransactionsLocking,
fetchTransactionsLockingByModule,
lockTransactions,
cancelLockTransactions,
unlockPartialTransactions,
cancelUnlockPartialTransactions,
} from './transactions-locking';
export type { TransactionsLockingListResponse } from './transactions-locking';
export {
VENDOR_CREDITS_ROUTES,
fetchVendorCredits,
fetchVendorCredit,
createVendorCredit,
editVendorCredit,
deleteVendorCredit,
openVendorCredit,
} from './vendor-credits';
export type {
VendorCreditsListResponse,
VendorCredit,
CreateVendorCreditBody,
EditVendorCreditBody,
} from './vendor-credits';
export {
SALE_ESTIMATES_ROUTES,
fetchSaleEstimates,
fetchSaleEstimate,
createSaleEstimate,
editSaleEstimate,
deleteSaleEstimate,
bulkDeleteSaleEstimates,
validateBulkDeleteSaleEstimates,
deliverSaleEstimate,
approveSaleEstimate,
rejectSaleEstimate,
notifySaleEstimateBySms,
fetchSaleEstimateSmsDetails,
fetchSaleEstimateMail,
sendSaleEstimateMail,
fetchSaleEstimatesState,
} from './sale-estimates';
export type {
SaleEstimatesListResponse,
SaleEstimate,
CreateSaleEstimateBody,
EditSaleEstimateBody,
BulkDeleteEstimatesBody,
ValidateBulkDeleteEstimatesResponse,
} from './sale-estimates';
export {
SALE_RECEIPTS_ROUTES,
fetchSaleReceipts,
fetchSaleReceipt,
createSaleReceipt,
editSaleReceipt,
deleteSaleReceipt,
} from './sale-receipts';
export type {
SaleReceiptsListResponse,
SaleReceipt,
CreateSaleReceiptBody,
EditSaleReceiptBody,
} from './sale-receipts';
export {
PAYMENTS_RECEIVED_ROUTES,
fetchPaymentsReceived,
fetchPaymentReceived,
createPaymentReceived,
editPaymentReceived,
deletePaymentReceived,
bulkDeletePaymentsReceived,
validateBulkDeletePaymentsReceived,
fetchPaymentReceiveEditPage,
fetchPaymentReceiveMail,
sendPaymentReceiveMail,
fetchPaymentReceivedState,
} from './payment-receives';
export type {
PaymentsReceivedListResponse,
PaymentReceived,
CreatePaymentReceivedBody,
EditPaymentReceivedBody,
BulkDeletePaymentsReceivedBody,
ValidateBulkDeletePaymentsReceivedResponse,
} from './payment-receives';
export {
BILL_PAYMENTS_ROUTES,
fetchBillPayments,
fetchBillPayment,
createBillPayment,
editBillPayment,
deleteBillPayment,
fetchBillPaymentEditPage,
} from './payment-mades';
export type {
BillPaymentsListResponse,
BillPayment,
CreateBillPaymentBody,
EditBillPaymentBody,
} from './payment-mades';
export {
INVENTORY_ADJUSTMENTS_ROUTES,
fetchInventoryAdjustments,
fetchInventoryAdjustment,
createQuickInventoryAdjustment,
deleteInventoryAdjustment,
publishInventoryAdjustment,
} from './inventory-adjustments';
export type {
InventoryAdjustmentsListResponse,
InventoryAdjustment,
CreateQuickInventoryAdjustmentBody,
} from './inventory-adjustments';
export {
WAREHOUSE_TRANSFERS_ROUTES,
fetchWarehouseTransfers,
fetchWarehouseTransfer,
createWarehouseTransfer,
editWarehouseTransfer,
deleteWarehouseTransfer,
initiateWarehouseTransfer,
transferredWarehouseTransfer,
} from './warehouse-transfers';
export type {
WarehouseTransfersListResponse,
WarehouseTransfer,
CreateWarehouseTransferBody,
EditWarehouseTransferBody,
} from './warehouse-transfers';
export {
LANDED_COST_ROUTES,
fetchLandedCostTransactions,
} from './landed-cost';
export type { LandedCostTransactionsResponse } from './landed-cost';
export {
GENERIC_RESOURCE_ROUTES,
fetchResourceMeta,
} from './generic-resource';
export type { ResourceMetaResponse } from './generic-resource';
export {
BANKING_ACCOUNTS_ROUTES,
fetchBankingAccounts,
fetchBankingAccountSummary,
} from './cashflow-accounts';
export type { BankingAccountsListResponse } from './cashflow-accounts';
export {
BANK_RULES_ROUTES,
fetchBankRules,
fetchBankRule,
createBankRule,
editBankRule,
deleteBankRule,
disconnectBankAccount,
refreshBankAccount,
fetchMatchedTransactions,
matchTransaction,
unmatchMatchedTransaction,
excludeBankTransaction,
unexcludeBankTransaction,
excludeBankTransactionsBulk,
unexcludeBankTransactionsBulk,
fetchRecognizedTransaction,
fetchRecognizedTransactions,
fetchExcludedBankTransactions,
fetchPendingTransactions,
fetchAutofillCategorizeTransaction,
} from './bank-rules';
export type {
BankRulesListResponse,
BankRuleResponse,
CreateBankRuleBody,
EditBankRuleBody,
CreateBankRuleResponse,
MatchTransactionBody,
} from './bank-rules';
export type * from './schema';
export * from './fetch-utils';
export * from './accounts';
export * from './credit-notes';
export * from './api-keys';
export * from './sale-invoices';
export * from './customers';
export * from './vendors';
export * from './bills';
export * from './items';
export * from './branches';
export * from './warehouses';
export * from './expenses';
export * from './manual-journals';
export * from './roles';
export * from './users';
export * from './settings';
export * from './organization';
export * from './subscription';
export * from './currencies';
export * from './tax-rates';
export * from './attachments';
export * from './pdf-templates';
export * from './invite';
export * from './authentication';
export * from './contacts';
export * from './items-categories';
export * from './views';
export * from './transactions-locking';
export * from './vendor-credits';
export * from './sale-estimates';
export * from './sale-receipts';
export * from './payment-receives';
export * from './payment-mades';
export * from './inventory-adjustments';
export * from './warehouse-transfers';
export * from './landed-cost';
export * from './generic-resource';
export * from './cashflow-accounts';
export * from './bank-rules';
/**
* Utility types for request/response types from schema paths.
*/
export * from './utils';
+5 -11
View File
@@ -1,5 +1,6 @@
import type { ApiFetcher } from './fetch-utils';
import type { paths } from './schema';
import { paths } from './schema';
import { OpForPath, OpRequestBody, OpResponseBody } from './utils';
export const INVENTORY_ADJUSTMENTS_ROUTES = {
LIST: '/api/inventory-adjustments',
@@ -8,16 +9,9 @@ export const INVENTORY_ADJUSTMENTS_ROUTES = {
PUBLISH: '/api/inventory-adjustments/{id}/publish',
} as const satisfies Record<string, keyof paths>;
type GetInventoryAdjustments = paths[typeof INVENTORY_ADJUSTMENTS_ROUTES.LIST]['get'];
type GetInventoryAdjustment = paths[typeof INVENTORY_ADJUSTMENTS_ROUTES.BY_ID]['get'];
type CreateQuick = paths[typeof INVENTORY_ADJUSTMENTS_ROUTES.QUICK]['post'];
type DeleteInventoryAdjustment = paths[typeof INVENTORY_ADJUSTMENTS_ROUTES.BY_ID]['delete'];
type GetInventoryAdjustments200 = GetInventoryAdjustments['responses'][200];
type GetInventoryAdjustment200 = GetInventoryAdjustment['responses'][200];
export type InventoryAdjustmentsListResponse = GetInventoryAdjustments200 extends { content?: { 'application/json': infer J } } ? J : unknown;
export type InventoryAdjustment = GetInventoryAdjustment200 extends { content?: { 'application/json': infer J } } ? J : unknown;
export type CreateQuickInventoryAdjustmentBody = CreateQuick['requestBody']['content']['application/json'];
export type InventoryAdjustmentsListResponse = OpResponseBody<OpForPath<typeof INVENTORY_ADJUSTMENTS_ROUTES.LIST, 'get'>>;
export type InventoryAdjustment = OpResponseBody<OpForPath<typeof INVENTORY_ADJUSTMENTS_ROUTES.BY_ID, 'get'>>;
export type CreateQuickInventoryAdjustmentBody = OpRequestBody<OpForPath<typeof INVENTORY_ADJUSTMENTS_ROUTES.QUICK, 'post'>>;
export async function fetchInventoryAdjustments(fetcher: ApiFetcher): Promise<InventoryAdjustmentsListResponse> {
const get = fetcher.path(INVENTORY_ADJUSTMENTS_ROUTES.LIST).method('get').create();
+4 -8
View File
@@ -1,5 +1,6 @@
import type { ApiFetcher } from './fetch-utils';
import type { paths } from './schema';
import { paths } from './schema';
import { OpForPath, OpRequestBody } from './utils';
export const INVITE_ROUTES = {
INVITE: '/api/invite',
@@ -8,13 +9,8 @@ export const INVITE_ROUTES = {
CHECK: '/api/invite/check/{token}',
} as const satisfies Record<string, keyof paths>;
type InviteUser = paths[typeof INVITE_ROUTES.INVITE]['patch'];
type ResendInvite = paths[typeof INVITE_ROUTES.RESEND]['post'];
type AcceptInvite = paths[typeof INVITE_ROUTES.ACCEPT]['post'];
type CheckInvite = paths[typeof INVITE_ROUTES.CHECK]['get'];
export type InviteUserBody = InviteUser['requestBody']['content']['application/json'];
export type AcceptInviteBody = AcceptInvite extends { requestBody: { content: { 'application/json': infer J } } } ? J : Record<string, unknown>;
export type InviteUserBody = OpRequestBody<OpForPath<typeof INVITE_ROUTES.INVITE, 'patch'>>;
export type AcceptInviteBody = OpRequestBody<OpForPath<typeof INVITE_ROUTES.ACCEPT, 'post'>>;
export async function acceptInvite(
fetcher: ApiFetcher,
+6 -13
View File
@@ -1,23 +1,16 @@
import type { ApiFetcher } from './fetch-utils';
import type { paths } from './schema';
import { paths } from './schema';
import { OpForPath, OpRequestBody, OpResponseBody } from './utils';
export const ITEMS_CATEGORIES_ROUTES = {
LIST: '/api/item-categories',
BY_ID: '/api/item-categories/{id}',
} as const satisfies Record<string, keyof paths>;
type GetItemCategories = paths[typeof ITEMS_CATEGORIES_ROUTES.LIST]['get'];
type GetItemCategory = paths[typeof ITEMS_CATEGORIES_ROUTES.BY_ID]['get'];
type CreateItemCategory = paths[typeof ITEMS_CATEGORIES_ROUTES.LIST]['post'];
type EditItemCategory = paths[typeof ITEMS_CATEGORIES_ROUTES.BY_ID]['put'];
type DeleteItemCategory = paths[typeof ITEMS_CATEGORIES_ROUTES.BY_ID]['delete'];
type GetItemCategories200 = GetItemCategories['responses'][200];
type GetItemCategory200 = GetItemCategory['responses'][200];
export type ItemCategoriesListResponse = GetItemCategories200 extends { content?: { 'application/json': infer J } } ? J : unknown;
export type ItemCategory = GetItemCategory200 extends { content?: { 'application/json': infer J } } ? J : unknown;
export type CreateItemCategoryBody = CreateItemCategory['requestBody']['content']['application/json'];
export type EditItemCategoryBody = EditItemCategory['requestBody']['content']['application/json'];
export type ItemCategoriesListResponse = OpResponseBody<OpForPath<typeof ITEMS_CATEGORIES_ROUTES.LIST, 'get'>>;
export type ItemCategory = OpResponseBody<OpForPath<typeof ITEMS_CATEGORIES_ROUTES.BY_ID, 'get'>>;
export type CreateItemCategoryBody = OpRequestBody<OpForPath<typeof ITEMS_CATEGORIES_ROUTES.LIST, 'post'>>;
export type EditItemCategoryBody = OpRequestBody<OpForPath<typeof ITEMS_CATEGORIES_ROUTES.BY_ID, 'put'>>;
export async function fetchItemCategories(fetcher: ApiFetcher): Promise<ItemCategoriesListResponse> {
const get = fetcher.path(ITEMS_CATEGORIES_ROUTES.LIST).method('get').create();
+46 -17
View File
@@ -1,5 +1,6 @@
import type { ApiFetcher } from './fetch-utils';
import type { paths } from './schema';
import { paths } from './schema';
import { OpForPath, OpQueryParams, OpRequestBody, OpResponseBody } from './utils';
export const ITEMS_ROUTES = {
LIST: '/api/items',
@@ -15,24 +16,22 @@ export const ITEMS_ROUTES = {
WAREHOUSES: '/api/items/{id}/warehouses',
} as const satisfies Record<string, keyof paths>;
type GetItems = paths[typeof ITEMS_ROUTES.LIST]['get'];
type GetItem = paths[typeof ITEMS_ROUTES.BY_ID]['get'];
type CreateItem = paths[typeof ITEMS_ROUTES.LIST]['post'];
type EditItem = paths[typeof ITEMS_ROUTES.BY_ID]['put'];
type DeleteItem = paths[typeof ITEMS_ROUTES.BY_ID]['delete'];
type BulkDelete = paths[typeof ITEMS_ROUTES.BULK_DELETE]['post'];
type ValidateBulkDelete = paths[typeof ITEMS_ROUTES.VALIDATE_BULK_DELETE]['post'];
export type ItemsListResponse = OpResponseBody<OpForPath<typeof ITEMS_ROUTES.LIST, 'get'>>;
export type Item = OpResponseBody<OpForPath<typeof ITEMS_ROUTES.BY_ID, 'get'>>;
export type CreateItemBody = OpRequestBody<OpForPath<typeof ITEMS_ROUTES.LIST, 'post'>>;
export type EditItemBody = OpRequestBody<OpForPath<typeof ITEMS_ROUTES.BY_ID, 'put'>>;
export type BulkDeleteItemsBody = OpRequestBody<OpForPath<typeof ITEMS_ROUTES.BULK_DELETE, 'post'>>;
export type ValidateBulkDeleteItemsResponse = OpResponseBody<OpForPath<typeof ITEMS_ROUTES.VALIDATE_BULK_DELETE, 'post'>>;
export type GetItemsQuery = OpQueryParams<OpForPath<typeof ITEMS_ROUTES.LIST, 'get'>>;
export type ItemsListResponse = GetItems['responses'][200]['content']['application/json'];
export type Item = GetItem['responses'][200]['content']['application/json'];
export type CreateItemBody = CreateItem['requestBody']['content']['application/json'];
export type EditItemBody = EditItem['requestBody']['content']['application/json'];
export type BulkDeleteItemsBody = BulkDelete['requestBody']['content']['application/json'];
export type ValidateBulkDeleteItemsResponse = ValidateBulkDelete['responses'][200]['content']['application/json'];
export async function fetchItems(fetcher: ApiFetcher): Promise<ItemsListResponse> {
export async function fetchItems(
fetcher: ApiFetcher,
query?: GetItemsQuery
): Promise<ItemsListResponse> {
const get = fetcher.path(ITEMS_ROUTES.LIST).method('get').create();
const { data } = await get({});
const { data } = await (get as (params?: GetItemsQuery) => Promise<{ data: ItemsListResponse }>)(
query ?? {}
);
return data;
}
@@ -90,3 +89,33 @@ export async function bulkDeleteItems(
const post = fetcher.path(ITEMS_ROUTES.BULK_DELETE).method('post').create();
await post(body);
}
export async function fetchItemInvoices(fetcher: ApiFetcher, id: number): Promise<unknown[]> {
const get = fetcher.path(ITEMS_ROUTES.INVOICES).method('get').create();
const { data } = await get({ id });
return (data as { data?: unknown[] })?.data ?? [];
}
export async function fetchItemBills(fetcher: ApiFetcher, id: number): Promise<unknown[]> {
const get = fetcher.path(ITEMS_ROUTES.BILLS).method('get').create();
const { data } = await get({ id });
return (data as { data?: unknown[] })?.data ?? [];
}
export async function fetchItemEstimates(fetcher: ApiFetcher, id: number): Promise<unknown[]> {
const get = fetcher.path(ITEMS_ROUTES.ESTIMATES).method('get').create();
const { data } = await get({ id });
return (data as { data?: unknown[] })?.data ?? [];
}
export async function fetchItemReceipts(fetcher: ApiFetcher, id: number): Promise<unknown[]> {
const get = fetcher.path(ITEMS_ROUTES.RECEIPTS).method('get').create();
const { data } = await get({ id });
return (data as { data?: unknown[] })?.data ?? [];
}
export async function fetchItemWarehouses(fetcher: ApiFetcher, id: number): Promise<unknown[]> {
const get = fetcher.path(ITEMS_ROUTES.WAREHOUSES).method('get').create();
const { data } = await get({ id });
return (data as { item_warehouses?: unknown[] })?.item_warehouses ?? [];
}
+11 -7
View File
@@ -1,5 +1,6 @@
import type { ApiFetcher } from './fetch-utils';
import type { paths } from './schema';
import { paths } from './schema';
import { OpForPath, OpQueryParams, OpResponseBody } from './utils';
export const LANDED_COST_ROUTES = {
TRANSACTIONS: '/api/landed-cost/transactions',
@@ -8,13 +9,16 @@ export const LANDED_COST_ROUTES = {
BILL_TRANSACTIONS: '/api/landed-cost/bills/{billId}/transactions',
} as const satisfies Record<string, keyof paths>;
type GetLandedCostTransactions = paths[typeof LANDED_COST_ROUTES.TRANSACTIONS]['get'];
export type LandedCostTransactionsResponse = OpResponseBody<OpForPath<typeof LANDED_COST_ROUTES.TRANSACTIONS, 'get'>>;
export type GetLandedCostTransactionsQuery = OpQueryParams<OpForPath<typeof LANDED_COST_ROUTES.TRANSACTIONS, 'get'>>;
type GetLandedCostTransactions200 = GetLandedCostTransactions['responses'][200];
export type LandedCostTransactionsResponse = GetLandedCostTransactions200 extends { content?: { 'application/json': infer J } } ? J : unknown;
export async function fetchLandedCostTransactions(fetcher: ApiFetcher): Promise<LandedCostTransactionsResponse> {
export async function fetchLandedCostTransactions(
fetcher: ApiFetcher,
query?: GetLandedCostTransactionsQuery
): Promise<LandedCostTransactionsResponse> {
const get = fetcher.path(LANDED_COST_ROUTES.TRANSACTIONS).method('get').create();
const { data } = await get({});
const { data } = await (
get as (params?: GetLandedCostTransactionsQuery) => Promise<{ data: LandedCostTransactionsResponse }>
)(query ?? {});
return data;
}
+33 -15
View File
@@ -1,5 +1,6 @@
import type { ApiFetcher } from './fetch-utils';
import type { paths } from './schema';
import { paths } from './schema';
import { OpForPath, OpQueryParams, OpRequestBody, OpResponseBody } from './utils';
export const MANUAL_JOURNALS_ROUTES = {
LIST: '/api/manual-journals',
@@ -9,22 +10,22 @@ export const MANUAL_JOURNALS_ROUTES = {
BULK_DELETE: '/api/manual-journals/bulk-delete',
} as const satisfies Record<string, keyof paths>;
type GetManualJournals = paths[typeof MANUAL_JOURNALS_ROUTES.LIST]['get'];
type GetManualJournal = paths[typeof MANUAL_JOURNALS_ROUTES.BY_ID]['get'];
type CreateManualJournal = paths[typeof MANUAL_JOURNALS_ROUTES.LIST]['post'];
type EditManualJournal = paths[typeof MANUAL_JOURNALS_ROUTES.BY_ID]['put'];
type DeleteManualJournal = paths[typeof MANUAL_JOURNALS_ROUTES.BY_ID]['delete'];
export type ManualJournalsListResponse = OpResponseBody<OpForPath<typeof MANUAL_JOURNALS_ROUTES.LIST, 'get'>>;
export type ManualJournal = OpResponseBody<OpForPath<typeof MANUAL_JOURNALS_ROUTES.BY_ID, 'get'>>;
export type CreateManualJournalBody = OpRequestBody<OpForPath<typeof MANUAL_JOURNALS_ROUTES.LIST, 'post'>>;
export type EditManualJournalBody = OpRequestBody<OpForPath<typeof MANUAL_JOURNALS_ROUTES.BY_ID, 'put'>>;
export type BulkDeleteManualJournalsBody = OpRequestBody<OpForPath<typeof MANUAL_JOURNALS_ROUTES.BULK_DELETE, 'post'>>;
export type ValidateBulkDeleteManualJournalsResponse = OpResponseBody<OpForPath<typeof MANUAL_JOURNALS_ROUTES.VALIDATE_BULK_DELETE, 'post'>>;
export type ManualJournalsListQuery = OpQueryParams<OpForPath<typeof MANUAL_JOURNALS_ROUTES.LIST, 'get'>>;
type GetManualJournals200 = GetManualJournals['responses'][200];
type GetManualJournal200 = GetManualJournal['responses'][200];
export type ManualJournalsListResponse = GetManualJournals200 extends { content?: { 'application/json': infer J } } ? J : unknown;
export type ManualJournal = GetManualJournal200 extends { content?: { 'application/json': infer J } } ? J : unknown;
export type CreateManualJournalBody = CreateManualJournal['requestBody']['content']['application/json'];
export type EditManualJournalBody = EditManualJournal['requestBody']['content']['application/json'];
export async function fetchManualJournals(fetcher: ApiFetcher): Promise<ManualJournalsListResponse> {
export async function fetchManualJournals(
fetcher: ApiFetcher,
query?: ManualJournalsListQuery
): Promise<ManualJournalsListResponse> {
const get = fetcher.path(MANUAL_JOURNALS_ROUTES.LIST).method('get').create();
const { data } = await get({});
const { data } = await (
get as unknown as (params?: ManualJournalsListQuery) => Promise<{ data: ManualJournalsListResponse }>
)(query ?? {});
return data;
}
@@ -60,3 +61,20 @@ export async function publishManualJournal(fetcher: ApiFetcher, id: number): Pro
const patch = fetcher.path(MANUAL_JOURNALS_ROUTES.PUBLISH).method('patch').create();
await patch({ id });
}
export async function bulkDeleteManualJournals(
fetcher: ApiFetcher,
body: BulkDeleteManualJournalsBody
): Promise<void> {
const post = fetcher.path(MANUAL_JOURNALS_ROUTES.BULK_DELETE).method('post').create();
await post({ ids: body.ids, skipUndeletable: body.skipUndeletable ?? false });
}
export async function validateBulkDeleteManualJournals(
fetcher: ApiFetcher,
body: { ids: number[] }
): Promise<ValidateBulkDeleteManualJournalsResponse> {
const post = fetcher.path(MANUAL_JOURNALS_ROUTES.VALIDATE_BULK_DELETE).method('post').create();
const { data } = await post({ ids: body.ids, skipUndeletable: false });
return data;
}
+4 -7
View File
@@ -1,5 +1,6 @@
import type { ApiFetcher } from './fetch-utils';
import type { paths } from './schema';
import { paths } from './schema';
import { OpForPath, OpRequestBody, OpResponseBody } from './utils';
export const ORGANIZATION_ROUTES = {
CURRENT: '/api/organization/current',
@@ -9,12 +10,8 @@ export const ORGANIZATION_ROUTES = {
UPDATE: '/api/organization',
} as const satisfies Record<string, keyof paths>;
type GetCurrent = paths[typeof ORGANIZATION_ROUTES.CURRENT]['get'];
type UpdateOrganization = paths[typeof ORGANIZATION_ROUTES.UPDATE]['put'];
type GetCurrent200 = GetCurrent['responses'][200];
export type OrganizationCurrent = GetCurrent200 extends { content?: { 'application/json': infer J } } ? J : unknown;
export type UpdateOrganizationBody = UpdateOrganization['requestBody']['content']['application/json'];
export type OrganizationCurrent = OpResponseBody<OpForPath<typeof ORGANIZATION_ROUTES.CURRENT, 'get'>>;
export type UpdateOrganizationBody = OpRequestBody<OpForPath<typeof ORGANIZATION_ROUTES.UPDATE, 'put'>>;
export async function fetchOrganizationCurrent(fetcher: ApiFetcher): Promise<OrganizationCurrent> {
const get = fetcher.path(ORGANIZATION_ROUTES.CURRENT).method('get').create();
+6 -13
View File
@@ -1,5 +1,6 @@
import type { ApiFetcher } from './fetch-utils';
import type { paths } from './schema';
import { paths } from './schema';
import { OpForPath, OpRequestBody, OpResponseBody } from './utils';
export const BILL_PAYMENTS_ROUTES = {
LIST: '/api/bill-payments',
@@ -9,18 +10,10 @@ export const BILL_PAYMENTS_ROUTES = {
EDIT_PAGE: '/api/bill-payments/{billPaymentId}/edit-page',
} as const satisfies Record<string, keyof paths>;
type GetBillPayments = paths[typeof BILL_PAYMENTS_ROUTES.LIST]['get'];
type GetBillPayment = paths[typeof BILL_PAYMENTS_ROUTES.BY_ID]['get'];
type CreateBillPayment = paths[typeof BILL_PAYMENTS_ROUTES.LIST]['post'];
type EditBillPayment = paths[typeof BILL_PAYMENTS_ROUTES.BY_ID]['put'];
type DeleteBillPayment = paths[typeof BILL_PAYMENTS_ROUTES.BY_ID]['delete'];
type GetBillPayments200 = GetBillPayments['responses'][200];
type GetBillPayment200 = GetBillPayment['responses'][200];
export type BillPaymentsListResponse = GetBillPayments200 extends { content?: { 'application/json': infer J } } ? J : unknown;
export type BillPayment = GetBillPayment200 extends { content?: { 'application/json': infer J } } ? J : unknown;
export type CreateBillPaymentBody = CreateBillPayment['requestBody']['content']['application/json'];
export type EditBillPaymentBody = EditBillPayment['requestBody']['content']['application/json'];
export type BillPaymentsListResponse = OpResponseBody<OpForPath<typeof BILL_PAYMENTS_ROUTES.LIST, 'get'>>;
export type BillPayment = OpResponseBody<OpForPath<typeof BILL_PAYMENTS_ROUTES.BY_ID, 'get'>>;
export type CreateBillPaymentBody = OpRequestBody<OpForPath<typeof BILL_PAYMENTS_ROUTES.LIST, 'post'>>;
export type EditBillPaymentBody = OpRequestBody<OpForPath<typeof BILL_PAYMENTS_ROUTES.BY_ID, 'put'>>;
export async function fetchBillPayments(fetcher: ApiFetcher): Promise<BillPaymentsListResponse> {
const get = fetcher.path(BILL_PAYMENTS_ROUTES.LIST).method('get').create();
+6 -13
View File
@@ -1,5 +1,6 @@
import type { ApiFetcher } from './fetch-utils';
import type { paths } from './schema';
import { paths } from './schema';
import { OpForPath, OpRequestBody, OpResponseBody } from './utils';
export const PAYMENTS_RECEIVED_ROUTES = {
LIST: '/api/payments-received',
@@ -11,18 +12,10 @@ export const PAYMENTS_RECEIVED_ROUTES = {
MAIL: '/api/payments-received/{id}/mail',
} as const satisfies Record<string, keyof paths>;
type GetPaymentsReceived = paths[typeof PAYMENTS_RECEIVED_ROUTES.LIST]['get'];
type GetPaymentReceived = paths[typeof PAYMENTS_RECEIVED_ROUTES.BY_ID]['get'];
type CreatePaymentReceived = paths[typeof PAYMENTS_RECEIVED_ROUTES.LIST]['post'];
type EditPaymentReceived = paths[typeof PAYMENTS_RECEIVED_ROUTES.BY_ID]['put'];
type DeletePaymentReceived = paths[typeof PAYMENTS_RECEIVED_ROUTES.BY_ID]['delete'];
type GetPaymentsReceived200 = GetPaymentsReceived['responses'][200];
type GetPaymentReceived200 = GetPaymentReceived['responses'][200];
export type PaymentsReceivedListResponse = GetPaymentsReceived200 extends { content?: { 'application/json': infer J } } ? J : unknown;
export type PaymentReceived = GetPaymentReceived200 extends { content?: { 'application/json': infer J } } ? J : unknown;
export type CreatePaymentReceivedBody = CreatePaymentReceived['requestBody']['content']['application/json'];
export type EditPaymentReceivedBody = EditPaymentReceived['requestBody']['content']['application/json'];
export type PaymentsReceivedListResponse = OpResponseBody<OpForPath<typeof PAYMENTS_RECEIVED_ROUTES.LIST, 'get'>>;
export type PaymentReceived = OpResponseBody<OpForPath<typeof PAYMENTS_RECEIVED_ROUTES.BY_ID, 'get'>>;
export type CreatePaymentReceivedBody = OpRequestBody<OpForPath<typeof PAYMENTS_RECEIVED_ROUTES.LIST, 'post'>>;
export type EditPaymentReceivedBody = OpRequestBody<OpForPath<typeof PAYMENTS_RECEIVED_ROUTES.BY_ID, 'put'>>;
export async function fetchPaymentsReceived(fetcher: ApiFetcher): Promise<PaymentsReceivedListResponse> {
const get = fetcher.path(PAYMENTS_RECEIVED_ROUTES.LIST).method('get').create();
+106
View File
@@ -0,0 +1,106 @@
import type { ApiFetcher } from './fetch-utils';
import type { paths } from './schema';
export const PDF_TEMPLATES_ROUTES = {
LIST: '/api/pdf-templates',
BY_ID: '/api/pdf-templates/{id}',
STATE: '/api/pdf-templates/state',
ASSIGN_DEFAULT: '/api/pdf-templates/{id}/assign-default',
} as const satisfies Record<string, keyof paths>;
// Schema does not define request/response content for PDF template operations; use explicit types.
export interface CreatePdfTemplateBody {
templateName: string;
resource: string;
attributes: Record<string, unknown>;
}
export interface EditPdfTemplateBody {
templateName: string;
attributes: Record<string, unknown>;
}
export interface PdfTemplateResponse {
templateName: string;
companyLogoUri?: string | null;
attributes: Record<string, unknown>;
predefined: boolean;
default: boolean;
createdAt: string;
updatedAt: string | null;
}
export interface PdfTemplatesListResponse {
templates?: PdfTemplateResponse[];
[key: string]: unknown;
}
export interface PdfTemplateBrandingStateResponse {
companyName: string;
companyAddress: string;
companyLogoUri: string;
companyLogoKey: string;
primaryColor: string;
}
export interface GetPdfTemplatesQuery {
resource?: string;
}
export async function fetchPdfTemplates(
fetcher: ApiFetcher,
query?: GetPdfTemplatesQuery
): Promise<PdfTemplatesListResponse> {
const get = fetcher.path(PDF_TEMPLATES_ROUTES.LIST).method('get').create();
const { data } = await (get as (params?: GetPdfTemplatesQuery) => Promise<{ data: PdfTemplatesListResponse }>)(
query ?? {}
);
return data;
}
export async function fetchPdfTemplate(
fetcher: ApiFetcher,
id: number
): Promise<PdfTemplateResponse> {
const get = fetcher.path(PDF_TEMPLATES_ROUTES.BY_ID).method('get').create();
const { data } = await (get as (params: { id: number }) => Promise<{ data: PdfTemplateResponse }>)({ id });
return data;
}
export async function createPdfTemplate(
fetcher: ApiFetcher,
values: CreatePdfTemplateBody
): Promise<void> {
const post = fetcher.path(PDF_TEMPLATES_ROUTES.LIST).method('post').create();
await (post as (body: CreatePdfTemplateBody) => Promise<unknown>)(values);
}
export async function editPdfTemplate(
fetcher: ApiFetcher,
id: number,
values: EditPdfTemplateBody
): Promise<void> {
const put = fetcher.path(PDF_TEMPLATES_ROUTES.BY_ID).method('put').create();
await (put as (params: { id: number } & EditPdfTemplateBody) => Promise<unknown>)({ id, ...values });
}
export async function deletePdfTemplate(fetcher: ApiFetcher, id: number): Promise<void> {
const del = fetcher.path(PDF_TEMPLATES_ROUTES.BY_ID).method('delete').create();
await del({ id });
}
export async function assignPdfTemplateAsDefault(
fetcher: ApiFetcher,
id: number
): Promise<void> {
const put = fetcher.path(PDF_TEMPLATES_ROUTES.ASSIGN_DEFAULT).method('put').create();
await put({ id });
}
export async function fetchPdfTemplateBrandingState(
fetcher: ApiFetcher
): Promise<PdfTemplateBrandingStateResponse> {
const get = fetcher.path(PDF_TEMPLATES_ROUTES.STATE).method('get').create();
const { data } = await (get as (params?: object) => Promise<{ data: PdfTemplateBrandingStateResponse }>)({});
return data;
}
+7 -16
View File
@@ -1,5 +1,6 @@
import type { ApiFetcher } from './fetch-utils';
import type { paths } from './schema';
import { paths } from './schema';
import { OpForPath, OpRequestBody, OpResponseBody } from './utils';
export const ROLES_ROUTES = {
LIST: '/api/roles',
@@ -7,21 +8,11 @@ export const ROLES_ROUTES = {
PERMISSIONS_SCHEMA: '/api/roles/permissions/schema',
} as const satisfies Record<string, keyof paths>;
type GetRoles = paths[typeof ROLES_ROUTES.LIST]['get'];
type GetRole = paths[typeof ROLES_ROUTES.BY_ID]['get'];
type CreateRole = paths[typeof ROLES_ROUTES.LIST]['post'];
type EditRole = paths[typeof ROLES_ROUTES.BY_ID]['put'];
type DeleteRole = paths[typeof ROLES_ROUTES.BY_ID]['delete'];
type GetPermissionsSchema = paths[typeof ROLES_ROUTES.PERMISSIONS_SCHEMA]['get'];
type GetRoles200 = GetRoles['responses'][200];
type GetRole200 = GetRole['responses'][200];
type GetPermissionsSchema200 = GetPermissionsSchema['responses'][200];
export type RolesListResponse = GetRoles200 extends { content?: { 'application/json': infer J } } ? J : unknown;
export type Role = GetRole200 extends { content?: { 'application/json': infer J } } ? J : unknown;
export type CreateRoleBody = CreateRole['requestBody']['content']['application/json'];
export type EditRoleBody = EditRole['requestBody']['content']['application/json'];
export type RolePermissionsSchema = GetPermissionsSchema200 extends { content?: { 'application/json': infer J } } ? J : unknown;
export type RolesListResponse = OpResponseBody<OpForPath<typeof ROLES_ROUTES.LIST, 'get'>>;
export type Role = OpResponseBody<OpForPath<typeof ROLES_ROUTES.BY_ID, 'get'>>;
export type CreateRoleBody = OpRequestBody<OpForPath<typeof ROLES_ROUTES.LIST, 'post'>>;
export type EditRoleBody = OpRequestBody<OpForPath<typeof ROLES_ROUTES.BY_ID, 'put'>>;
export type RolePermissionsSchema = OpResponseBody<OpForPath<typeof ROLES_ROUTES.PERMISSIONS_SCHEMA, 'get'>>;
export async function fetchRoles(fetcher: ApiFetcher): Promise<RolesListResponse> {
const get = fetcher.path(ROLES_ROUTES.LIST).method('get').create();
+6 -13
View File
@@ -1,5 +1,6 @@
import type { ApiFetcher } from './fetch-utils';
import type { paths } from './schema';
import { paths } from './schema';
import { OpForPath, OpRequestBody, OpResponseBody } from './utils';
export const SALE_ESTIMATES_ROUTES = {
LIST: '/api/sale-estimates',
@@ -15,18 +16,10 @@ export const SALE_ESTIMATES_ROUTES = {
MAIL: '/api/sale-estimates/{id}/mail',
} as const satisfies Record<string, keyof paths>;
type GetSaleEstimates = paths[typeof SALE_ESTIMATES_ROUTES.LIST]['get'];
type GetSaleEstimate = paths[typeof SALE_ESTIMATES_ROUTES.BY_ID]['get'];
type CreateSaleEstimate = paths[typeof SALE_ESTIMATES_ROUTES.LIST]['post'];
type EditSaleEstimate = paths[typeof SALE_ESTIMATES_ROUTES.BY_ID]['put'];
type DeleteSaleEstimate = paths[typeof SALE_ESTIMATES_ROUTES.BY_ID]['delete'];
type GetSaleEstimates200 = GetSaleEstimates['responses'][200];
type GetSaleEstimate200 = GetSaleEstimate['responses'][200];
export type SaleEstimatesListResponse = GetSaleEstimates200 extends { content?: { 'application/json': infer J } } ? J : unknown;
export type SaleEstimate = GetSaleEstimate200 extends { content?: { 'application/json': infer J } } ? J : unknown;
export type CreateSaleEstimateBody = CreateSaleEstimate['requestBody']['content']['application/json'];
export type EditSaleEstimateBody = EditSaleEstimate['requestBody']['content']['application/json'];
export type SaleEstimatesListResponse = OpResponseBody<OpForPath<typeof SALE_ESTIMATES_ROUTES.LIST, 'get'>>;
export type SaleEstimate = OpResponseBody<OpForPath<typeof SALE_ESTIMATES_ROUTES.BY_ID, 'get'>>;
export type CreateSaleEstimateBody = OpRequestBody<OpForPath<typeof SALE_ESTIMATES_ROUTES.LIST, 'post'>>;
export type EditSaleEstimateBody = OpRequestBody<OpForPath<typeof SALE_ESTIMATES_ROUTES.BY_ID, 'put'>>;
export async function fetchSaleEstimates(fetcher: ApiFetcher): Promise<SaleEstimatesListResponse> {
const get = fetcher.path(SALE_ESTIMATES_ROUTES.LIST).method('get').create();
+117 -13
View File
@@ -1,5 +1,6 @@
import type { ApiFetcher } from './fetch-utils';
import type { paths } from './schema';
import { paths } from './schema';
import { OpForPath, OpQueryParams, OpRequestBody, OpResponseBody } from './utils';
export const SALE_INVOICES_ROUTES = {
LIST: '/api/sale-invoices',
@@ -17,20 +18,23 @@ export const SALE_INVOICES_ROUTES = {
BULK_DELETE: '/api/sale-invoices/bulk-delete',
} as const satisfies Record<string, keyof paths>;
type GetSaleInvoices = paths[typeof SALE_INVOICES_ROUTES.LIST]['get'];
type GetSaleInvoice = paths[typeof SALE_INVOICES_ROUTES.BY_ID]['get'];
type CreateSaleInvoice = paths[typeof SALE_INVOICES_ROUTES.LIST]['post'];
type EditSaleInvoice = paths[typeof SALE_INVOICES_ROUTES.BY_ID]['put'];
type DeleteSaleInvoice = paths[typeof SALE_INVOICES_ROUTES.BY_ID]['delete'];
export type SaleInvoicesListResponse = OpResponseBody<OpForPath<typeof SALE_INVOICES_ROUTES.LIST, 'get'>>;
export type SaleInvoice = OpResponseBody<OpForPath<typeof SALE_INVOICES_ROUTES.BY_ID, 'get'>>;
export type CreateSaleInvoiceBody = OpRequestBody<OpForPath<typeof SALE_INVOICES_ROUTES.LIST, 'post'>>;
export type EditSaleInvoiceBody = OpRequestBody<OpForPath<typeof SALE_INVOICES_ROUTES.BY_ID, 'put'>>;
export type BulkDeleteSaleInvoicesBody = OpRequestBody<OpForPath<typeof SALE_INVOICES_ROUTES.BULK_DELETE, 'post'>>;
export type ValidateBulkDeleteSaleInvoicesResponse = OpResponseBody<OpForPath<typeof SALE_INVOICES_ROUTES.VALIDATE_BULK_DELETE, 'post'>>;
export type SaleInvoiceStateResponse = OpResponseBody<OpForPath<typeof SALE_INVOICES_ROUTES.STATE, 'get'>>;
export type GetSaleInvoicesQuery = OpQueryParams<OpForPath<typeof SALE_INVOICES_ROUTES.LIST, 'get'>>;
export type SaleInvoicesListResponse = GetSaleInvoices['responses'][200]['content']['application/json'];
export type SaleInvoice = GetSaleInvoice['responses'][200]['content']['application/json'];
export type CreateSaleInvoiceBody = CreateSaleInvoice['requestBody']['content']['application/json'];
export type EditSaleInvoiceBody = EditSaleInvoice['requestBody']['content']['application/json'];
export async function fetchSaleInvoices(fetcher: ApiFetcher): Promise<SaleInvoicesListResponse> {
export async function fetchSaleInvoices(
fetcher: ApiFetcher,
query?: GetSaleInvoicesQuery
): Promise<SaleInvoicesListResponse> {
const get = fetcher.path(SALE_INVOICES_ROUTES.LIST).method('get').create();
const { data } = await get({});
const { data } = await (
get as (params?: GetSaleInvoicesQuery) => Promise<{ data: SaleInvoicesListResponse }>
)(query ?? {});
return data;
}
@@ -61,3 +65,103 @@ export async function deleteSaleInvoice(fetcher: ApiFetcher, id: number): Promis
const del = fetcher.path(SALE_INVOICES_ROUTES.BY_ID).method('delete').create();
await del({ id });
}
export async function bulkDeleteSaleInvoices(
fetcher: ApiFetcher,
body: BulkDeleteSaleInvoicesBody
): Promise<void> {
const post = fetcher.path(SALE_INVOICES_ROUTES.BULK_DELETE).method('post').create();
await post({ ids: body.ids, skipUndeletable: body.skipUndeletable ?? false } as never);
}
export async function validateBulkDeleteSaleInvoices(
fetcher: ApiFetcher,
ids: number[]
): Promise<ValidateBulkDeleteSaleInvoicesResponse> {
const post = fetcher.path(SALE_INVOICES_ROUTES.VALIDATE_BULK_DELETE).method('post').create();
const { data } = await post({ ids, skipUndeletable: false } as never);
return data as ValidateBulkDeleteSaleInvoicesResponse;
}
export async function deliverSaleInvoice(fetcher: ApiFetcher, id: number): Promise<void> {
const put = fetcher.path(SALE_INVOICES_ROUTES.DELIVER).method('put').create();
await put({ id });
}
export async function writeOffSaleInvoice(
fetcher: ApiFetcher,
id: number,
body?: Record<string, unknown>
): Promise<void> {
const post = fetcher.path(SALE_INVOICES_ROUTES.WRITEOFF).method('post').create();
await post({ id, ...(body ?? {}) } as never);
}
export async function cancelWrittenOffSaleInvoice(fetcher: ApiFetcher, id: number): Promise<void> {
const post = fetcher.path(SALE_INVOICES_ROUTES.CANCEL_WRITEOFF).method('post').create();
await post({ id });
}
export async function fetchReceivableSaleInvoices(
fetcher: ApiFetcher,
customerId?: number
): Promise<unknown> {
const get = fetcher.path(SALE_INVOICES_ROUTES.RECEIVABLE).method('get').create();
const { data } = await (get as (params?: { customerId?: number }) => Promise<{ data: unknown }>)(
customerId != null ? { customerId } : {}
);
return data;
}
export async function fetchSaleInvoiceMailState(
fetcher: ApiFetcher,
id: number
): Promise<unknown> {
const get = fetcher.path(SALE_INVOICES_ROUTES.MAIL).method('get').create();
const { data } = await get({ id });
return data;
}
export async function sendSaleInvoiceMail(
fetcher: ApiFetcher,
id: number,
body?: Record<string, unknown>
): Promise<void> {
const post = fetcher.path(SALE_INVOICES_ROUTES.MAIL).method('post').create();
await post({ id, ...(body ?? {}) } as never);
}
export async function fetchSaleInvoiceState(
fetcher: ApiFetcher
): Promise<SaleInvoiceStateResponse> {
const get = fetcher.path(SALE_INVOICES_ROUTES.STATE).method('get').create();
const { data } = await (get as (params?: object) => Promise<{ data: SaleInvoiceStateResponse }>)({});
return data;
}
export async function fetchInvoicePayments(
fetcher: ApiFetcher,
id: number
): Promise<unknown> {
const get = fetcher.path(SALE_INVOICES_ROUTES.PAYMENTS).method('get').create();
const { data } = await get({ id });
return data;
}
export async function fetchSaleInvoiceHtml(
fetcher: ApiFetcher,
id: number
): Promise<{ htmlContent: string }> {
const get = fetcher.path(SALE_INVOICES_ROUTES.HTML).method('get').create();
const { data } = await (get as (params: { id: number }) => Promise<{ data: { htmlContent: string } }>)({ id });
return data as { htmlContent: string };
}
export async function generateSaleInvoiceSharableLink(
fetcher: ApiFetcher,
id: number
): Promise<{ link: string }> {
const post = fetcher.path(SALE_INVOICES_ROUTES.GENERATE_LINK).method('post').create();
const { data } = await (post as (params: { id: number }) => Promise<{ data: { link: string } }>)({ id });
return data as { link: string };
}
+67 -15
View File
@@ -1,5 +1,6 @@
import type { ApiFetcher } from './fetch-utils';
import type { paths } from './schema';
import { paths } from './schema';
import { OpForPath, OpQueryParams, OpRequestBody, OpResponseBody } from './utils';
export const SALE_RECEIPTS_ROUTES = {
LIST: '/api/sale-receipts',
@@ -7,24 +8,27 @@ export const SALE_RECEIPTS_ROUTES = {
STATE: '/api/sale-receipts/state',
VALIDATE_BULK_DELETE: '/api/sale-receipts/validate-bulk-delete',
BULK_DELETE: '/api/sale-receipts/bulk-delete',
CLOSE: '/api/sale-receipts/{id}/close',
MAIL: '/api/sale-receipts/{id}/mail',
} as const satisfies Record<string, keyof paths>;
type GetSaleReceipts = paths[typeof SALE_RECEIPTS_ROUTES.LIST]['get'];
type GetSaleReceipt = paths[typeof SALE_RECEIPTS_ROUTES.BY_ID]['get'];
type CreateSaleReceipt = paths[typeof SALE_RECEIPTS_ROUTES.LIST]['post'];
type EditSaleReceipt = paths[typeof SALE_RECEIPTS_ROUTES.BY_ID]['put'];
type DeleteSaleReceipt = paths[typeof SALE_RECEIPTS_ROUTES.BY_ID]['delete'];
export type SaleReceiptsListResponse = OpResponseBody<OpForPath<typeof SALE_RECEIPTS_ROUTES.LIST, 'get'>>;
export type SaleReceipt = OpResponseBody<OpForPath<typeof SALE_RECEIPTS_ROUTES.BY_ID, 'get'>>;
export type CreateSaleReceiptBody = OpRequestBody<OpForPath<typeof SALE_RECEIPTS_ROUTES.LIST, 'post'>>;
export type EditSaleReceiptBody = OpRequestBody<OpForPath<typeof SALE_RECEIPTS_ROUTES.BY_ID, 'put'>>;
export type BulkDeleteReceiptsBody = OpRequestBody<OpForPath<typeof SALE_RECEIPTS_ROUTES.BULK_DELETE, 'post'>>;
export type ValidateBulkDeleteReceiptsResponse = OpResponseBody<OpForPath<typeof SALE_RECEIPTS_ROUTES.VALIDATE_BULK_DELETE, 'post'>>;
export type SaleReceiptStateResponse = OpResponseBody<OpForPath<typeof SALE_RECEIPTS_ROUTES.STATE, 'get'>>;
export type GetSaleReceiptsQuery = OpQueryParams<OpForPath<typeof SALE_RECEIPTS_ROUTES.LIST, 'get'>>;
type GetSaleReceipts200 = GetSaleReceipts['responses'][200];
type GetSaleReceipt200 = GetSaleReceipt['responses'][200];
export type SaleReceiptsListResponse = GetSaleReceipts200 extends { content?: { 'application/json': infer J } } ? J : unknown;
export type SaleReceipt = GetSaleReceipt200 extends { content?: { 'application/json': infer J } } ? J : unknown;
export type CreateSaleReceiptBody = CreateSaleReceipt['requestBody']['content']['application/json'];
export type EditSaleReceiptBody = EditSaleReceipt['requestBody']['content']['application/json'];
export async function fetchSaleReceipts(fetcher: ApiFetcher): Promise<SaleReceiptsListResponse> {
export async function fetchSaleReceipts(
fetcher: ApiFetcher,
query?: GetSaleReceiptsQuery
): Promise<SaleReceiptsListResponse> {
const get = fetcher.path(SALE_RECEIPTS_ROUTES.LIST).method('get').create();
const { data } = await get({});
const { data } = await (
get as (params?: GetSaleReceiptsQuery) => Promise<{ data: SaleReceiptsListResponse }>
)(query ?? {});
return data;
}
@@ -55,3 +59,51 @@ export async function deleteSaleReceipt(fetcher: ApiFetcher, id: number): Promis
const del = fetcher.path(SALE_RECEIPTS_ROUTES.BY_ID).method('delete').create();
await del({ id });
}
export async function bulkDeleteSaleReceipts(
fetcher: ApiFetcher,
body: BulkDeleteReceiptsBody
): Promise<void> {
const post = fetcher.path(SALE_RECEIPTS_ROUTES.BULK_DELETE).method('post').create();
await post({ ids: body.ids, skipUndeletable: body.skipUndeletable ?? false } as never);
}
export async function validateBulkDeleteSaleReceipts(
fetcher: ApiFetcher,
ids: number[]
): Promise<ValidateBulkDeleteReceiptsResponse> {
const post = fetcher.path(SALE_RECEIPTS_ROUTES.VALIDATE_BULK_DELETE).method('post').create();
const { data } = await post({ ids, skipUndeletable: false } as never);
return data as ValidateBulkDeleteReceiptsResponse;
}
export async function closeSaleReceipt(fetcher: ApiFetcher, id: number): Promise<void> {
const post = fetcher.path(SALE_RECEIPTS_ROUTES.CLOSE).method('post').create();
await post({ id });
}
export async function fetchSaleReceiptMail(
fetcher: ApiFetcher,
id: number
): Promise<unknown> {
const get = fetcher.path(SALE_RECEIPTS_ROUTES.MAIL).method('get').create();
const { data } = await get({ id });
return data;
}
export async function sendSaleReceiptMail(
fetcher: ApiFetcher,
id: number,
body?: Record<string, unknown>
): Promise<void> {
const post = fetcher.path(SALE_RECEIPTS_ROUTES.MAIL).method('post').create();
await post({ id, ...(body ?? {}) } as never);
}
export async function fetchSaleReceiptState(
fetcher: ApiFetcher
): Promise<SaleReceiptStateResponse> {
const get = fetcher.path(SALE_RECEIPTS_ROUTES.STATE).method('get').create();
const { data } = await (get as (params?: object) => Promise<{ data: SaleReceiptStateResponse }>)({});
return data;
}
+305
View File
@@ -54,6 +54,108 @@ export interface paths {
patch?: never;
trace?: never;
};
"/api/auth/signin": {
parameters: {
query?: never;
header?: never;
path?: never;
cookie?: never;
};
get?: never;
put?: never;
/** Sign in a user */
post: operations["AuthController_signin"];
delete?: never;
options?: never;
head?: never;
patch?: never;
trace?: never;
};
"/api/auth/signup": {
parameters: {
query?: never;
header?: never;
path?: never;
cookie?: never;
};
get?: never;
put?: never;
/** Sign up a new user */
post: operations["AuthController_signup"];
delete?: never;
options?: never;
head?: never;
patch?: never;
trace?: never;
};
"/api/auth/signup/verify": {
parameters: {
query?: never;
header?: never;
path?: never;
cookie?: never;
};
get?: never;
put?: never;
/** Confirm user signup */
post: operations["AuthController_signupConfirm"];
delete?: never;
options?: never;
head?: never;
patch?: never;
trace?: never;
};
"/api/auth/send_reset_password": {
parameters: {
query?: never;
header?: never;
path?: never;
cookie?: never;
};
get?: never;
put?: never;
/** Send reset password email */
post: operations["AuthController_sendResetPassword"];
delete?: never;
options?: never;
head?: never;
patch?: never;
trace?: never;
};
"/api/auth/reset_password/{token}": {
parameters: {
query?: never;
header?: never;
path?: never;
cookie?: never;
};
get?: never;
put?: never;
/** Reset password using token */
post: operations["AuthController_resetPassword"];
delete?: never;
options?: never;
head?: never;
patch?: never;
trace?: never;
};
"/api/auth/meta": {
parameters: {
query?: never;
header?: never;
path?: never;
cookie?: never;
};
/** Get auth metadata (e.g. signup disabled) */
get: operations["AuthController_meta"];
put?: never;
post?: never;
delete?: never;
options?: never;
head?: never;
patch?: never;
trace?: never;
};
"/api/api-keys/generate": {
parameters: {
query?: never;
@@ -11919,6 +12021,209 @@ export interface operations {
};
};
};
AuthController_signin: {
parameters: {
query?: never;
header?: never;
path?: never;
cookie?: never;
};
requestBody: {
content: {
"application/json": {
/**
* @description User email address
* @example user@example.com
*/
email: string;
/**
* @description User password
* @example password123
*/
password: string;
};
};
};
responses: {
/** @description Sign-in successful */
200: {
headers: {
[name: string]: unknown;
};
content: {
"application/json": {
/** @description JWT access token */
accessToken?: string;
/** @description Organization ID */
organizationId?: string;
/** @description Tenant ID */
tenantId?: number;
/** @description User ID */
userId?: number;
};
};
};
};
};
AuthController_signup: {
parameters: {
query?: never;
header?: never;
path?: never;
cookie?: never;
};
requestBody: {
content: {
"application/json": {
/**
* @description User first name
* @example John
*/
firstName: string;
/**
* @description User last name
* @example Doe
*/
lastName: string;
/**
* Format: email
* @description User email address
* @example john.doe@example.com
*/
email: string;
/**
* @description User password
* @example password123
*/
password: string;
};
};
};
responses: {
/** @description Sign-up initiated. Check email for confirmation. */
201: {
headers: {
[name: string]: unknown;
};
content?: never;
};
};
};
AuthController_signupConfirm: {
parameters: {
query?: never;
header?: never;
path?: never;
cookie?: never;
};
requestBody: {
content: {
"application/json": {
/**
* @description User email address
* @example user@example.com
*/
email: string;
/**
* @description Signup confirmation token from email
* @example confirmation-token
*/
token: string;
};
};
};
responses: {
/** @description Signup confirmed successfully. */
200: {
headers: {
[name: string]: unknown;
};
content?: never;
};
};
};
AuthController_sendResetPassword: {
parameters: {
query?: never;
header?: never;
path?: never;
cookie?: never;
};
requestBody: {
content: {
"application/json": {
/**
* @description User email address to send reset link to
* @example user@example.com
*/
email: string;
};
};
};
responses: {
/** @description Reset password email sent if the account exists. */
200: {
headers: {
[name: string]: unknown;
};
content?: never;
};
};
};
AuthController_resetPassword: {
parameters: {
query?: never;
header?: never;
path: {
/** @description Reset password token from email link */
token: string;
};
cookie?: never;
};
requestBody: {
content: {
"application/json": {
/**
* @description New password
* @example new-password
*/
password: string;
};
};
};
responses: {
/** @description Password reset successfully. */
200: {
headers: {
[name: string]: unknown;
};
content?: never;
};
};
};
AuthController_meta: {
parameters: {
query?: never;
header?: never;
path?: never;
cookie?: never;
};
requestBody?: never;
responses: {
/** @description Auth metadata for the login/signup page */
200: {
headers: {
[name: string]: unknown;
};
content: {
"application/json": {
/** @description Whether signup is disabled */
signupDisabled?: boolean;
};
};
};
};
};
AuthApiKeysController_generate: {
parameters: {
query?: never;
+12 -10
View File
@@ -1,21 +1,23 @@
import type { ApiFetcher } from './fetch-utils';
import type { paths } from './schema';
import { paths } from './schema';
import { OpForPath, OpQueryParams, OpRequestBody, OpResponseBody } from './utils';
export const SETTINGS_ROUTES = {
GET_SAVE: '/api/settings',
} as const satisfies Record<string, keyof paths>;
type GetSettings = paths[typeof SETTINGS_ROUTES.GET_SAVE]['get'];
type SaveSettings = paths[typeof SETTINGS_ROUTES.GET_SAVE]['put'];
export type SettingsResponse = OpResponseBody<OpForPath<typeof SETTINGS_ROUTES.GET_SAVE, 'get'>>;
export type SaveSettingsBody = OpRequestBody<OpForPath<typeof SETTINGS_ROUTES.GET_SAVE, 'put'>>;
export type GetSettingsQuery = OpQueryParams<OpForPath<typeof SETTINGS_ROUTES.GET_SAVE, 'get'>>;
type GetSettings200 = GetSettings['responses'][200];
type SaveSettingsRequestBody = SaveSettings extends { requestBody: { content: { 'application/json': infer J } } } ? J : Record<string, unknown>;
export type SettingsResponse = GetSettings200 extends { content?: { 'application/json': infer J } } ? J : unknown;
export type SaveSettingsBody = SaveSettingsRequestBody;
export async function fetchSettings(fetcher: ApiFetcher): Promise<SettingsResponse> {
export async function fetchSettings(
fetcher: ApiFetcher,
query?: GetSettingsQuery
): Promise<SettingsResponse> {
const get = fetcher.path(SETTINGS_ROUTES.GET_SAVE).method('get').create();
const { data } = await get({});
const { data } = await (get as (params?: GetSettingsQuery) => Promise<{ data: SettingsResponse }>)(
query ?? {}
);
return data;
}
+3 -5
View File
@@ -1,5 +1,6 @@
import type { ApiFetcher } from './fetch-utils';
import type { paths } from './schema';
import { paths } from './schema';
import { OpForPath, OpResponseBody } from './utils';
export const SUBSCRIPTION_ROUTES = {
LIST: '/api/subscription',
@@ -9,10 +10,7 @@ export const SUBSCRIPTION_ROUTES = {
CHANGE: '/api/subscription/change',
} as const satisfies Record<string, keyof paths>;
type GetSubscriptions = paths[typeof SUBSCRIPTION_ROUTES.LIST]['get'];
type GetSubscriptions200 = GetSubscriptions['responses'][200];
export type SubscriptionsListResponse = GetSubscriptions200 extends { content?: { 'application/json': infer J } } ? J : unknown;
export type SubscriptionsListResponse = OpResponseBody<OpForPath<typeof SUBSCRIPTION_ROUTES.LIST, 'get'>>;
export async function fetchSubscriptions(fetcher: ApiFetcher): Promise<SubscriptionsListResponse> {
const get = fetcher.path(SUBSCRIPTION_ROUTES.LIST).method('get').create();
+6 -13
View File
@@ -1,5 +1,6 @@
import type { ApiFetcher } from './fetch-utils';
import type { paths } from './schema';
import { paths } from './schema';
import { OpForPath, OpRequestBody, OpResponseBody } from './utils';
export const TAX_RATES_ROUTES = {
LIST: '/api/tax-rates',
@@ -8,18 +9,10 @@ export const TAX_RATES_ROUTES = {
INACTIVATE: '/api/tax-rates/{id}/inactivate',
} as const satisfies Record<string, keyof paths>;
type GetTaxRates = paths[typeof TAX_RATES_ROUTES.LIST]['get'];
type GetTaxRate = paths[typeof TAX_RATES_ROUTES.BY_ID]['get'];
type CreateTaxRate = paths[typeof TAX_RATES_ROUTES.LIST]['post'];
type EditTaxRate = paths[typeof TAX_RATES_ROUTES.BY_ID]['put'];
type DeleteTaxRate = paths[typeof TAX_RATES_ROUTES.BY_ID]['delete'];
type GetTaxRates200 = GetTaxRates['responses'][200];
type GetTaxRate200 = GetTaxRate['responses'][200];
export type TaxRatesListResponse = GetTaxRates200 extends { content?: { 'application/json': infer J } } ? J : unknown;
export type TaxRate = GetTaxRate200 extends { content?: { 'application/json': infer J } } ? J : unknown;
export type CreateTaxRateBody = CreateTaxRate extends { requestBody: { content: { 'application/json': infer J } } } ? J : Record<string, unknown>;
export type EditTaxRateBody = EditTaxRate extends { requestBody: { content: { 'application/json': infer J } } } ? J : Record<string, unknown>;
export type TaxRatesListResponse = OpResponseBody<OpForPath<typeof TAX_RATES_ROUTES.LIST, 'get'>>;
export type TaxRate = OpResponseBody<OpForPath<typeof TAX_RATES_ROUTES.BY_ID, 'get'>>;
export type CreateTaxRateBody = OpRequestBody<OpForPath<typeof TAX_RATES_ROUTES.LIST, 'post'>>;
export type EditTaxRateBody = OpRequestBody<OpForPath<typeof TAX_RATES_ROUTES.BY_ID, 'put'>>;
export async function fetchTaxRates(fetcher: ApiFetcher): Promise<TaxRatesListResponse> {
const get = fetcher.path(TAX_RATES_ROUTES.LIST).method('get').create();
+3 -2
View File
@@ -1,5 +1,6 @@
import type { ApiFetcher } from './fetch-utils';
import type { paths } from './schema';
import { paths } from './schema';
import { OpForPath, OpResponseBody } from './utils';
export const TRANSACTIONS_LOCKING_ROUTES = {
LOCK: '/api/transactions-locking/lock',
@@ -10,7 +11,7 @@ export const TRANSACTIONS_LOCKING_ROUTES = {
BY_MODULE: '/api/transactions-locking/{module}',
} as const satisfies Record<string, keyof paths>;
export type TransactionsLockingListResponse = unknown;
export type TransactionsLockingListResponse = OpResponseBody<OpForPath<typeof TRANSACTIONS_LOCKING_ROUTES.LIST, 'get'>>;
export async function fetchTransactionsLocking(fetcher: ApiFetcher): Promise<TransactionsLockingListResponse> {
const get = fetcher.path(TRANSACTIONS_LOCKING_ROUTES.LIST).method('get').create();
+6 -12
View File
@@ -1,5 +1,6 @@
import type { ApiFetcher } from './fetch-utils';
import type { paths } from './schema';
import { paths } from './schema';
import { OpForPath, OpQueryParams, OpRequestBody, OpResponseBody } from './utils';
export const USERS_ROUTES = {
LIST: '/api/users',
@@ -8,17 +9,10 @@ export const USERS_ROUTES = {
INACTIVATE: '/api/users/{id}/inactivate',
} as const satisfies Record<string, keyof paths>;
type GetUsers = paths[typeof USERS_ROUTES.LIST]['get'];
type GetUser = paths[typeof USERS_ROUTES.BY_ID]['get'];
type EditUser = paths[typeof USERS_ROUTES.BY_ID]['put'];
type GetUsers200 = GetUsers['responses'][200];
type GetUser200 = GetUser['responses'][200];
export type UsersListResponse = GetUsers200 extends { content?: { 'application/json': infer J } } ? J : unknown;
export type User = GetUser200 extends { content?: { 'application/json': infer J } } ? J : unknown;
export type EditUserBody = EditUser['requestBody']['content']['application/json'];
export type GetUsersQuery = GetUsers['parameters']['query'];
export type UsersListResponse = OpResponseBody<OpForPath<typeof USERS_ROUTES.LIST, 'get'>>;
export type User = OpResponseBody<OpForPath<typeof USERS_ROUTES.BY_ID, 'get'>>;
export type EditUserBody = OpRequestBody<OpForPath<typeof USERS_ROUTES.BY_ID, 'put'>>;
export type GetUsersQuery = OpQueryParams<OpForPath<typeof USERS_ROUTES.LIST, 'get'>>;
export async function fetchUsers(
fetcher: ApiFetcher,
+30
View File
@@ -0,0 +1,30 @@
import { paths } from "../schema";
type HttpMethod = 'get' | 'post' | 'put' | 'delete' | 'patch';
// Helpers: derive request/response types from schema paths (single source of truth).
// When a path exists in the schema we get the real types; otherwise a safe fallback.
export type OpForPath<P extends string, M extends HttpMethod> = P extends keyof paths
? paths[P] extends Record<M, infer O>
? O
: never
: never;
/** Query params for a GET (or other) operation. Use with OpForPath<Route, 'get'>. */
export type OpQueryParams<O> = O extends { parameters: { query?: infer Q } }
? (Q extends undefined ? Record<string, unknown> : NonNullable<Q>)
: Record<string, unknown>;
export type OpRequestBody<O> = [O] extends [
{ requestBody: { content: { 'application/json': infer B } } },
]
? B
: Record<string, unknown>;
export type OpResponseBody<O> = O extends {
responses: { 200: { content: { 'application/json': infer R } } };
}
? R
: O extends { responses: { 201: { content: { 'application/json': infer R } } } }
? R
: unknown;
+6 -13
View File
@@ -1,5 +1,6 @@
import type { ApiFetcher } from './fetch-utils';
import type { paths } from './schema';
import { paths } from './schema';
import { OpForPath, OpRequestBody, OpResponseBody } from './utils';
export const VENDOR_CREDITS_ROUTES = {
LIST: '/api/vendor-credits',
@@ -9,18 +10,10 @@ export const VENDOR_CREDITS_ROUTES = {
BULK_DELETE: '/api/vendor-credits/bulk-delete',
} as const satisfies Record<string, keyof paths>;
type GetVendorCredits = paths[typeof VENDOR_CREDITS_ROUTES.LIST]['get'];
type GetVendorCredit = paths[typeof VENDOR_CREDITS_ROUTES.BY_ID]['get'];
type CreateVendorCredit = paths[typeof VENDOR_CREDITS_ROUTES.LIST]['post'];
type EditVendorCredit = paths[typeof VENDOR_CREDITS_ROUTES.BY_ID]['put'];
type DeleteVendorCredit = paths[typeof VENDOR_CREDITS_ROUTES.BY_ID]['delete'];
type GetVendorCredits200 = GetVendorCredits['responses'][200];
type GetVendorCredit200 = GetVendorCredit['responses'][200];
export type VendorCreditsListResponse = GetVendorCredits200 extends { content?: { 'application/json': infer J } } ? J : unknown;
export type VendorCredit = GetVendorCredit200 extends { content?: { 'application/json': infer J } } ? J : unknown;
export type CreateVendorCreditBody = CreateVendorCredit['requestBody']['content']['application/json'];
export type EditVendorCreditBody = EditVendorCredit['requestBody']['content']['application/json'];
export type VendorCreditsListResponse = OpResponseBody<OpForPath<typeof VENDOR_CREDITS_ROUTES.LIST, 'get'>>;
export type VendorCredit = OpResponseBody<OpForPath<typeof VENDOR_CREDITS_ROUTES.BY_ID, 'get'>>;
export type CreateVendorCreditBody = OpRequestBody<OpForPath<typeof VENDOR_CREDITS_ROUTES.LIST, 'post'>>;
export type EditVendorCreditBody = OpRequestBody<OpForPath<typeof VENDOR_CREDITS_ROUTES.BY_ID, 'put'>>;
export async function fetchVendorCredits(fetcher: ApiFetcher): Promise<VendorCreditsListResponse> {
const get = fetcher.path(VENDOR_CREDITS_ROUTES.LIST).method('get').create();
+16 -18
View File
@@ -1,5 +1,6 @@
import type { ApiFetcher } from './fetch-utils';
import type { paths } from './schema';
import { paths } from './schema';
import { OpForPath, OpQueryParams, OpRequestBody, OpResponseBody } from './utils';
export const VENDORS_ROUTES = {
LIST: '/api/vendors',
@@ -9,25 +10,22 @@ export const VENDORS_ROUTES = {
BULK_DELETE: '/api/vendors/bulk-delete',
} as const satisfies Record<string, keyof paths>;
type GetVendors = paths[typeof VENDORS_ROUTES.LIST]['get'];
type GetVendor = paths[typeof VENDORS_ROUTES.BY_ID]['get'];
type CreateVendor = paths[typeof VENDORS_ROUTES.LIST]['post'];
type EditVendor = paths[typeof VENDORS_ROUTES.BY_ID]['put'];
type ValidateBulkDelete = paths[typeof VENDORS_ROUTES.VALIDATE_BULK_DELETE]['post'];
type BulkDelete = paths[typeof VENDORS_ROUTES.BULK_DELETE]['post'];
export type VendorsListResponse = OpResponseBody<OpForPath<typeof VENDORS_ROUTES.LIST, 'get'>>;
export type Vendor = OpResponseBody<OpForPath<typeof VENDORS_ROUTES.BY_ID, 'get'>>;
export type CreateVendorBody = OpRequestBody<OpForPath<typeof VENDORS_ROUTES.LIST, 'post'>>;
export type EditVendorBody = OpRequestBody<OpForPath<typeof VENDORS_ROUTES.BY_ID, 'put'>>;
export type ValidateBulkDeleteVendorsResponse = OpResponseBody<OpForPath<typeof VENDORS_ROUTES.VALIDATE_BULK_DELETE, 'post'>>;
export type BulkDeleteVendorsBody = OpRequestBody<OpForPath<typeof VENDORS_ROUTES.BULK_DELETE, 'post'>>;
export type GetVendorsQuery = OpQueryParams<OpForPath<typeof VENDORS_ROUTES.LIST, 'get'>>;
type GetVendors200 = GetVendors['responses'][200];
type GetVendor200 = GetVendor['responses'][200];
export type VendorsListResponse = GetVendors200 extends { content?: { 'application/json': infer J } } ? J : unknown;
export type Vendor = GetVendor200 extends { content?: { 'application/json': infer J } } ? J : unknown;
export type CreateVendorBody = CreateVendor['requestBody']['content']['application/json'];
export type EditVendorBody = EditVendor['requestBody']['content']['application/json'];
export type ValidateBulkDeleteVendorsResponse = ValidateBulkDelete['responses'][200]['content']['application/json'];
export type BulkDeleteVendorsBody = BulkDelete['requestBody']['content']['application/json'];
export async function fetchVendors(fetcher: ApiFetcher): Promise<VendorsListResponse> {
export async function fetchVendors(
fetcher: ApiFetcher,
query?: GetVendorsQuery
): Promise<VendorsListResponse> {
const get = fetcher.path(VENDORS_ROUTES.LIST).method('get').create();
const { data } = await get({});
const { data } = await (get as (params: GetVendorsQuery) => Promise<{ data: VendorsListResponse }>)(
query ?? {}
);
return data;
}
+3 -5
View File
@@ -1,14 +1,12 @@
import type { ApiFetcher } from './fetch-utils';
import type { paths } from './schema';
import { paths } from './schema';
import { OpForPath, OpResponseBody } from './utils';
export const VIEWS_ROUTES = {
RESOURCE: '/api/views/resource/{resourceModel}',
} as const satisfies Record<string, keyof paths>;
type GetResourceView = paths[typeof VIEWS_ROUTES.RESOURCE]['get'];
type GetResourceView200 = GetResourceView['responses'][200];
export type ResourceViewResponse = GetResourceView200 extends { content?: { 'application/json': infer J } } ? J : unknown;
export type ResourceViewResponse = OpResponseBody<OpForPath<typeof VIEWS_ROUTES.RESOURCE, 'get'>>;
export async function fetchResourceView(
fetcher: ApiFetcher,
+15 -18
View File
@@ -1,5 +1,6 @@
import type { ApiFetcher } from './fetch-utils';
import type { paths } from './schema';
import { paths } from './schema';
import { OpForPath, OpQueryParams, OpRequestBody, OpResponseBody } from './utils';
export const WAREHOUSE_TRANSFERS_ROUTES = {
LIST: '/api/warehouse-transfers',
@@ -8,24 +9,20 @@ export const WAREHOUSE_TRANSFERS_ROUTES = {
TRANSFERRED: '/api/warehouse-transfers/{id}/transferred',
} as const satisfies Record<string, keyof paths>;
type GetWarehouseTransfers = paths[typeof WAREHOUSE_TRANSFERS_ROUTES.LIST]['get'];
type GetWarehouseTransfer = paths[typeof WAREHOUSE_TRANSFERS_ROUTES.BY_ID]['get'];
type CreateWarehouseTransfer = paths[typeof WAREHOUSE_TRANSFERS_ROUTES.LIST]['post'];
type EditWarehouseTransfer = paths[typeof WAREHOUSE_TRANSFERS_ROUTES.BY_ID]['put'];
type DeleteWarehouseTransfer = paths[typeof WAREHOUSE_TRANSFERS_ROUTES.BY_ID]['delete'];
export type WarehouseTransfersListResponse = OpResponseBody<OpForPath<typeof WAREHOUSE_TRANSFERS_ROUTES.LIST, 'get'>>;
export type WarehouseTransfer = OpResponseBody<OpForPath<typeof WAREHOUSE_TRANSFERS_ROUTES.BY_ID, 'get'>>;
export type CreateWarehouseTransferBody = OpRequestBody<OpForPath<typeof WAREHOUSE_TRANSFERS_ROUTES.LIST, 'post'>>;
export type EditWarehouseTransferBody = OpRequestBody<OpForPath<typeof WAREHOUSE_TRANSFERS_ROUTES.BY_ID, 'put'>>;
export type GetWarehouseTransfersQuery = OpQueryParams<OpForPath<typeof WAREHOUSE_TRANSFERS_ROUTES.LIST, 'get'>>;
type GetWarehouseTransfers200 = GetWarehouseTransfers['responses'][200];
type GetWarehouseTransfer200 = GetWarehouseTransfer['responses'][200];
export type WarehouseTransfersListResponse = GetWarehouseTransfers200 extends { content?: { 'application/json': infer J } } ? J : unknown;
export type WarehouseTransfer = GetWarehouseTransfer200 extends { content?: { 'application/json': infer J } } ? J : unknown;
export type CreateBody = CreateWarehouseTransfer extends { requestBody: { content: { 'application/json': infer J } } } ? J : Record<string, unknown>;
type EditBody = EditWarehouseTransfer extends { requestBody: { content: { 'application/json': infer J } } } ? J : Record<string, unknown>;
export type CreateWarehouseTransferBody = CreateBody;
export type EditWarehouseTransferBody = EditBody;
export async function fetchWarehouseTransfers(fetcher: ApiFetcher): Promise<WarehouseTransfersListResponse> {
export async function fetchWarehouseTransfers(
fetcher: ApiFetcher,
query?: GetWarehouseTransfersQuery
): Promise<WarehouseTransfersListResponse> {
const get = fetcher.path(WAREHOUSE_TRANSFERS_ROUTES.LIST).method('get').create();
const { data } = await get({});
const { data } = await (get as (params: GetWarehouseTransfersQuery) => Promise<{ data: WarehouseTransfersListResponse }>)(
query ?? {}
);
return data;
}
@@ -49,7 +46,7 @@ export async function editWarehouseTransfer(
values: EditWarehouseTransferBody
): Promise<void> {
const put = fetcher.path(WAREHOUSE_TRANSFERS_ROUTES.BY_ID).method('put').create();
await (put as unknown as (params: { id: number } & EditWarehouseTransferBody) => Promise<void>)({ id, ...values });
await put({ id, ...(values as object) } as never);
}
export async function deleteWarehouseTransfer(fetcher: ApiFetcher, id: number): Promise<void> {
+6 -11
View File
@@ -1,5 +1,6 @@
import type { ApiFetcher } from './fetch-utils';
import type { paths } from './schema';
import { paths } from './schema';
import { OpForPath, OpRequestBody, OpResponseBody } from './utils';
export const WAREHOUSES_ROUTES = {
LIST: '/api/warehouses',
@@ -8,16 +9,10 @@ export const WAREHOUSES_ROUTES = {
MARK_PRIMARY: '/api/warehouses/{id}/mark-primary',
} as const satisfies Record<string, keyof paths>;
type GetWarehouses = paths[typeof WAREHOUSES_ROUTES.LIST]['get'];
type GetWarehouse = paths[typeof WAREHOUSES_ROUTES.BY_ID]['get'];
type CreateWarehouse = paths[typeof WAREHOUSES_ROUTES.LIST]['post'];
type EditWarehouse = paths[typeof WAREHOUSES_ROUTES.BY_ID]['put'];
type DeleteWarehouse = paths[typeof WAREHOUSES_ROUTES.BY_ID]['delete'];
export type WarehousesListResponse = GetWarehouses['responses'][200]['content']['application/json'];
export type Warehouse = GetWarehouse['responses'][200]['content']['application/json'];
export type CreateWarehouseBody = CreateWarehouse['requestBody']['content']['application/json'];
export type EditWarehouseBody = EditWarehouse['requestBody']['content']['application/json'];
export type WarehousesListResponse = OpResponseBody<OpForPath<typeof WAREHOUSES_ROUTES.LIST, 'get'>>;
export type Warehouse = OpResponseBody<OpForPath<typeof WAREHOUSES_ROUTES.BY_ID, 'get'>>;
export type CreateWarehouseBody = OpRequestBody<OpForPath<typeof WAREHOUSES_ROUTES.LIST, 'post'>>;
export type EditWarehouseBody = OpRequestBody<OpForPath<typeof WAREHOUSES_ROUTES.BY_ID, 'put'>>;
export async function fetchWarehouses(fetcher: ApiFetcher): Promise<WarehousesListResponse> {
const get = fetcher.path(WAREHOUSES_ROUTES.LIST).method('get').create();