@doany-ai/sdk 0.2.8 → 0.3.0-alpha.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/client.js +53 -5
- package/dist/client.types.d.ts +60 -4
- package/dist/index.d.ts +8 -2
- package/dist/modules/auth.js +6 -0
- package/dist/modules/auth.types.d.ts +30 -0
- package/dist/modules/catalog.d.ts +9 -0
- package/dist/modules/catalog.js +62 -0
- package/dist/modules/catalog.types.d.ts +163 -0
- package/dist/modules/catalog.types.js +1 -0
- package/dist/modules/contacts.d.ts +9 -0
- package/dist/modules/contacts.js +42 -0
- package/dist/modules/contacts.types.d.ts +112 -0
- package/dist/modules/contacts.types.js +1 -0
- package/dist/modules/events.d.ts +9 -0
- package/dist/modules/events.js +15 -0
- package/dist/modules/events.types.d.ts +42 -0
- package/dist/modules/events.types.js +1 -0
- package/dist/modules/order-access.d.ts +20 -0
- package/dist/modules/order-access.js +84 -0
- package/dist/modules/orders.d.ts +25 -0
- package/dist/modules/orders.js +296 -0
- package/dist/modules/orders.types.d.ts +215 -0
- package/dist/modules/orders.types.js +1 -0
- package/dist/modules/payments.d.ts +2 -1
- package/dist/modules/payments.js +28 -1
- package/dist/modules/payments.types.d.ts +146 -0
- package/dist/modules/project.d.ts +31 -0
- package/dist/modules/project.js +52 -0
- package/dist/modules/project.types.d.ts +58 -0
- package/dist/modules/project.types.js +1 -0
- package/dist/modules/users.d.ts +7 -13
- package/dist/modules/users.js +24 -11
- package/dist/modules/users.types.d.ts +62 -0
- package/dist/modules/users.types.js +1 -0
- package/package.json +1 -1
package/dist/client.js
CHANGED
|
@@ -7,10 +7,15 @@ import { confirmAppUserConnection, createConnectorsModule, createUserConnectorsM
|
|
|
7
7
|
import { getAccessToken } from "./utils/auth-utils.js";
|
|
8
8
|
import { createFunctionsModule } from "./modules/functions.js";
|
|
9
9
|
import { createPaymentsModule } from "./modules/payments.js";
|
|
10
|
+
import { createCatalogModule } from "./modules/catalog.js";
|
|
11
|
+
import { createOrdersModule } from "./modules/orders.js";
|
|
10
12
|
import { createAgentsModule } from "./modules/agents.js";
|
|
11
13
|
import { createAiGatewayModule } from "./modules/ai-gateway.js";
|
|
12
14
|
import { createAppLogsModule } from "./modules/app-logs.js";
|
|
13
15
|
import { createUsersModule } from "./modules/users.js";
|
|
16
|
+
import { createContactsModule } from "./modules/contacts.js";
|
|
17
|
+
import { createEventsModule } from "./modules/events.js";
|
|
18
|
+
import { createProjectScope } from "./modules/project.js";
|
|
14
19
|
import { RoomsSocket } from "./utils/socket-utils.js";
|
|
15
20
|
import { createAnalyticsModule } from "./modules/analytics.js";
|
|
16
21
|
/**
|
|
@@ -52,7 +57,10 @@ import { createAnalyticsModule } from "./modules/analytics.js";
|
|
|
52
57
|
*/
|
|
53
58
|
export function createClient(config) {
|
|
54
59
|
var _a, _b;
|
|
55
|
-
const { serverUrl = "https://api.doany.ai", appId, token, serviceToken, requiresAuth = false, appBaseUrl, options, functionsVersion, headers: optionalHeaders, } = config;
|
|
60
|
+
const { serverUrl = "https://api.doany.ai", appId, token, serviceToken, requiresAuth = false, appBaseUrl, options, functionsVersion, headers: optionalHeaders, projectId, platformToken, operatorUserId, } = config;
|
|
61
|
+
if (platformToken && !projectId) {
|
|
62
|
+
throw new Error("createClient({ platformToken }) needs projectId: a platform client names the business it works on");
|
|
63
|
+
}
|
|
56
64
|
// Normalize appBaseUrl to always be a string (empty if not provided or invalid)
|
|
57
65
|
const normalizedAppBaseUrl = typeof appBaseUrl === "string" ? appBaseUrl : "";
|
|
58
66
|
const socketConfig = {
|
|
@@ -81,9 +89,17 @@ export function createClient(config) {
|
|
|
81
89
|
"Doany-Functions-Version": functionsVersion,
|
|
82
90
|
}
|
|
83
91
|
: headers;
|
|
92
|
+
// The platform's credential rides on the client's own requests only: not on
|
|
93
|
+
// function calls, and never on the service-role client, which is the app key's.
|
|
94
|
+
const platformHeaders = platformToken
|
|
95
|
+
? {
|
|
96
|
+
"x-doany-service-token": platformToken,
|
|
97
|
+
...(operatorUserId ? { "x-doany-operator-user-id": operatorUserId } : {}),
|
|
98
|
+
}
|
|
99
|
+
: {};
|
|
84
100
|
const axiosClient = createAxiosClient({
|
|
85
101
|
baseURL: `${serverUrl}/api`,
|
|
86
|
-
headers,
|
|
102
|
+
headers: { ...headers, ...platformHeaders },
|
|
87
103
|
token,
|
|
88
104
|
onError: options === null || options === void 0 ? void 0 : options.onError,
|
|
89
105
|
});
|
|
@@ -118,6 +134,12 @@ export function createClient(config) {
|
|
|
118
134
|
token: serviceToken,
|
|
119
135
|
interceptResponses: false,
|
|
120
136
|
});
|
|
137
|
+
// The business the site belongs to, for the /projects/{project_id}/...
|
|
138
|
+
// modules: as given, or read once from the site's public settings. Each
|
|
139
|
+
// client reads them with its own credential: a login-gated site refuses the
|
|
140
|
+
// read without one, and a backend function may hold only the service token.
|
|
141
|
+
const project = createProjectScope(axiosClient, appId, projectId);
|
|
142
|
+
const serviceProject = createProjectScope(serviceRoleAxiosClient, appId, projectId);
|
|
121
143
|
const userAuthModule = createAuthModule(axiosClient, functionsAxiosClient, appId, {
|
|
122
144
|
appBaseUrl: normalizedAppBaseUrl,
|
|
123
145
|
serverUrl,
|
|
@@ -139,7 +161,14 @@ export function createClient(config) {
|
|
|
139
161
|
getSocket,
|
|
140
162
|
}),
|
|
141
163
|
integrations: createIntegrationsModule(axiosClient, appId),
|
|
142
|
-
|
|
164
|
+
app: project.app,
|
|
165
|
+
payments: createPaymentsModule(axiosClient, appId, project),
|
|
166
|
+
catalog: createCatalogModule(axiosClient, appId, project),
|
|
167
|
+
// A platform client runs on a server for many operators: like the service
|
|
168
|
+
// role, it keeps no retry state between calls.
|
|
169
|
+
orders: createOrdersModule(axiosClient, appId, project, { rememberAttempts: !platformToken }),
|
|
170
|
+
contacts: createContactsModule(axiosClient, project),
|
|
171
|
+
events: createEventsModule(axiosClient, project),
|
|
143
172
|
connectors: createUserConnectorsModule(axiosClient, appId),
|
|
144
173
|
auth: userAuthModule,
|
|
145
174
|
functions: createFunctionsModule(functionsAxiosClient, appId, {
|
|
@@ -163,7 +192,7 @@ export function createClient(config) {
|
|
|
163
192
|
}),
|
|
164
193
|
aiGateway: createAiGatewayModule({ serverUrl, token, appId }),
|
|
165
194
|
appLogs: createAppLogsModule(axiosClient, appId),
|
|
166
|
-
users: createUsersModule(axiosClient, appId),
|
|
195
|
+
users: createUsersModule(axiosClient, appId, project),
|
|
167
196
|
analytics: createAnalyticsModule({
|
|
168
197
|
axiosClient,
|
|
169
198
|
serverUrl,
|
|
@@ -198,15 +227,34 @@ export function createClient(config) {
|
|
|
198
227
|
// actually there, and a function naming its own mode could charge a real
|
|
199
228
|
// card from a preview.
|
|
200
229
|
payments: (() => {
|
|
201
|
-
const full = createPaymentsModule(serviceRoleAxiosClient, appId);
|
|
230
|
+
const full = createPaymentsModule(serviceRoleAxiosClient, appId, serviceProject);
|
|
202
231
|
return {
|
|
203
232
|
getCheckoutSession: full.getCheckoutSession.bind(full),
|
|
204
233
|
getSubscription: full.getSubscription.bind(full),
|
|
205
234
|
// Reading the products is not a decision for any browser, and a
|
|
206
235
|
// fulfilment function often needs what it just sold.
|
|
207
236
|
products: full.products,
|
|
237
|
+
// An order's checkout (e.g. a payment link to send) and the payment
|
|
238
|
+
// records. Not getForOrder: a service caller may not use it
|
|
239
|
+
// (permissions `payments:get_for_order`); it reads payments with `get`.
|
|
240
|
+
checkout: full.checkout.bind(full),
|
|
241
|
+
list: full.list.bind(full),
|
|
242
|
+
get: full.get.bind(full),
|
|
208
243
|
};
|
|
209
244
|
})(),
|
|
245
|
+
catalog: createCatalogModule(serviceRoleAxiosClient, appId, serviceProject),
|
|
246
|
+
orders: createOrdersModule(serviceRoleAxiosClient, appId, serviceProject, { rememberAttempts: false }),
|
|
247
|
+
contacts: (() => {
|
|
248
|
+
// `me` is a signed-in account's own contact; the app key has none.
|
|
249
|
+
const { me: _me, updateMe: _updateMe, ...rest } = createContactsModule(serviceRoleAxiosClient, serviceProject);
|
|
250
|
+
return rest;
|
|
251
|
+
})(),
|
|
252
|
+
events: createEventsModule(serviceRoleAxiosClient, serviceProject),
|
|
253
|
+
users: (() => {
|
|
254
|
+
// The invite route requires a signed-in account; the app key alone gets a 401.
|
|
255
|
+
const { inviteUser: _invite, ...rest } = createUsersModule(serviceRoleAxiosClient, appId, serviceProject);
|
|
256
|
+
return rest;
|
|
257
|
+
})(),
|
|
210
258
|
functions: createFunctionsModule(serviceRoleFunctionsAxiosClient, appId, {
|
|
211
259
|
getAuthHeaders: () => {
|
|
212
260
|
const headers = {};
|
package/dist/client.types.d.ts
CHANGED
|
@@ -5,10 +5,16 @@ import type { SsoModule } from "./modules/sso.types.js";
|
|
|
5
5
|
import type { ConnectorsModule, UserConnectorsModule } from "./modules/connectors.types.js";
|
|
6
6
|
import type { FunctionsModule } from "./modules/functions.types.js";
|
|
7
7
|
import type { PaymentsModule } from "./modules/payments.types.js";
|
|
8
|
+
import type { CatalogModule } from "./modules/catalog.types.js";
|
|
9
|
+
import type { OrdersModule } from "./modules/orders.types.js";
|
|
8
10
|
import type { AgentsModule } from "./modules/agents.types.js";
|
|
9
11
|
import type { AiGatewayModule } from "./modules/ai-gateway.types.js";
|
|
10
12
|
import type { AppLogsModule } from "./modules/app-logs.types.js";
|
|
11
13
|
import type { AnalyticsModule } from "./modules/analytics.types.js";
|
|
14
|
+
import type { ContactsModule } from "./modules/contacts.types.js";
|
|
15
|
+
import type { EventsModule } from "./modules/events.types.js";
|
|
16
|
+
import type { UsersModule } from "./modules/users.types.js";
|
|
17
|
+
import type { AppModule } from "./modules/project.types.js";
|
|
12
18
|
/**
|
|
13
19
|
* Options for creating a Doany client.
|
|
14
20
|
*/
|
|
@@ -44,6 +50,12 @@ export interface CreateClientConfig {
|
|
|
44
50
|
* It's the string between `/apps/` and `/editor/`.
|
|
45
51
|
*/
|
|
46
52
|
appId: string;
|
|
53
|
+
/**
|
|
54
|
+
* The business (project) the app belongs to, for the catalog, orders,
|
|
55
|
+
* payments, contacts, events and users modules. Optional: left out, the SDK
|
|
56
|
+
* reads it once from the app's public settings.
|
|
57
|
+
*/
|
|
58
|
+
projectId?: string;
|
|
47
59
|
/**
|
|
48
60
|
* User authentication token. Used to authenticate as a specific user.
|
|
49
61
|
*
|
|
@@ -55,6 +67,18 @@ export interface CreateClientConfig {
|
|
|
55
67
|
* @internal
|
|
56
68
|
*/
|
|
57
69
|
serviceToken?: string;
|
|
70
|
+
/**
|
|
71
|
+
* The Doany platform's own credential (the platform website's server,
|
|
72
|
+
* Annie's tools), sent as `x-doany-service-token` on the client's requests.
|
|
73
|
+
* Needs `projectId`: a platform client names the business it works on.
|
|
74
|
+
*/
|
|
75
|
+
platformToken?: string;
|
|
76
|
+
/**
|
|
77
|
+
* The platform account a `platformToken` call is made for, sent as
|
|
78
|
+
* `x-doany-operator-user-id`: it must be allowed on the project, and it is
|
|
79
|
+
* who the business's history records.
|
|
80
|
+
*/
|
|
81
|
+
operatorUserId?: string;
|
|
58
82
|
/**
|
|
59
83
|
* Whether authentication is required. If true, redirects to login if not authenticated.
|
|
60
84
|
* @internal
|
|
@@ -101,6 +125,18 @@ export interface DoanyClient {
|
|
|
101
125
|
integrations: IntegrationsModule;
|
|
102
126
|
/** {@link PaymentsModule | Payments module} for taking card payments through Stripe. */
|
|
103
127
|
payments: PaymentsModule;
|
|
128
|
+
/** {@link CatalogModule | Catalog module} for reading what the business offers. */
|
|
129
|
+
catalog: CatalogModule;
|
|
130
|
+
/** {@link OrdersModule | Orders module} for placing and managing orders. */
|
|
131
|
+
orders: OrdersModule;
|
|
132
|
+
/** {@link ContactsModule | Contacts module} for the people the business knows. */
|
|
133
|
+
contacts: ContactsModule;
|
|
134
|
+
/** {@link EventsModule | Events module} for the business's timeline. */
|
|
135
|
+
events: EventsModule;
|
|
136
|
+
/** {@link UsersModule | Users module} for inviting and managing the site's accounts. */
|
|
137
|
+
users: UsersModule;
|
|
138
|
+
/** {@link AppModule | App module} for the site's public settings. */
|
|
139
|
+
app: AppModule;
|
|
104
140
|
/** Cleanup function to disconnect WebSocket connections. Call when you're done with the client. */
|
|
105
141
|
cleanup: () => void;
|
|
106
142
|
/**
|
|
@@ -150,11 +186,31 @@ export interface DoanyClient {
|
|
|
150
186
|
* service-role caller, so the ordinary client cannot resolve a mode and
|
|
151
187
|
* the read fails whatever the function forwards.
|
|
152
188
|
*
|
|
153
|
-
*
|
|
154
|
-
*
|
|
155
|
-
*
|
|
189
|
+
* The reads are here — the two above and the products — and, for
|
|
190
|
+
* orders, `checkout` (e.g. a payment link to send), `list` and `get`.
|
|
191
|
+
* Not `getForOrder`: a service caller reads payments with `get`.
|
|
192
|
+
*/
|
|
193
|
+
payments: Pick<PaymentsModule, "getCheckoutSession" | "getSubscription" | "products" | "checkout" | "list" | "get">;
|
|
194
|
+
/** {@link CatalogModule | Catalog module} with the service credential. */
|
|
195
|
+
catalog: CatalogModule;
|
|
196
|
+
/**
|
|
197
|
+
* {@link OrdersModule | Orders module} with the service credential. Unlike
|
|
198
|
+
* a page's client, nothing is remembered between calls: pass
|
|
199
|
+
* `idempotencyKey` to make a retry answer with the first order.
|
|
200
|
+
*/
|
|
201
|
+
orders: OrdersModule;
|
|
202
|
+
/**
|
|
203
|
+
* {@link ContactsModule | Contacts module} with the service credential. No
|
|
204
|
+
* `me` / `updateMe`: those are a signed-in account's own contact.
|
|
205
|
+
*/
|
|
206
|
+
contacts: Omit<ContactsModule, "me" | "updateMe">;
|
|
207
|
+
/** {@link EventsModule | Events module} with the service credential. */
|
|
208
|
+
events: EventsModule;
|
|
209
|
+
/**
|
|
210
|
+
* {@link UsersModule | Users module} with the service credential. No `inviteUser`: an invitation is sent by a
|
|
211
|
+
* signed-in account (the invite route requires one), not by the app key.
|
|
156
212
|
*/
|
|
157
|
-
|
|
213
|
+
users: Omit<UsersModule, "inviteUser">;
|
|
158
214
|
/** {@link SsoModule | SSO module} for generating SSO tokens.
|
|
159
215
|
* @internal
|
|
160
216
|
*/
|
package/dist/index.d.ts
CHANGED
|
@@ -5,13 +5,19 @@ export { createClient, createClientFromRequest, DoanyError, getAccessToken, save
|
|
|
5
5
|
export type { DoanyClient, CreateClientConfig, CreateClientOptions, DoanyErrorJSON, };
|
|
6
6
|
export * from "./types.js";
|
|
7
7
|
export type { DeleteManyResult, DeleteResult, EntitiesModule, EntityFilterOperators, EntityFilterQuery, EntityFilterValue, EntityHandler, EntityRecord, EntityTypeRegistry, ImportResult, RealtimeEventType, RealtimeEvent, RealtimeCallback, SortField, UpdateManyResult, } from "./modules/entities.types.js";
|
|
8
|
-
export type { AuthModule, LoginResponse, RegisterParams, VerifyOtpParams, ChangePasswordParams, ResetPasswordParams, User, } from "./modules/auth.types.js";
|
|
8
|
+
export type { AuthModule, LoginResponse, LoginSession, RegisterParams, VerifyOtpParams, ChangePasswordParams, ResetPasswordParams, User, } from "./modules/auth.types.js";
|
|
9
9
|
export type { IntegrationsModule, IntegrationEndpointFunction, CoreIntegrations, InvokeLLMParams, GenerateImageParams, GenerateImageResult, UploadFileParams, UploadFileResult, SendEmailParams, SendEmailResult, ExtractDataFromUploadedFileParams, ExtractDataFromUploadedFileResult, UploadPrivateFileParams, UploadPrivateFileResult, CreateFileSignedUrlParams, CreateFileSignedUrlResult, } from "./modules/integrations.types.js";
|
|
10
10
|
export type { FunctionsModule, FunctionName, FunctionNameRegistry, } from "./modules/functions.types.js";
|
|
11
11
|
export type { AgentsModule, AgentName, AgentNameRegistry, AgentConversation, AgentMessage, AgentMessageReasoning, AgentMessageToolCall, AgentMessageUsage, AgentMessageCustomContext, AgentMessageMetadata, CreateConversationParams, } from "./modules/agents.types.js";
|
|
12
12
|
export type { AiGatewayModule, AiGatewayConnection, } from "./modules/ai-gateway.types.js";
|
|
13
13
|
export type { AppLogsModule } from "./modules/app-logs.types.js";
|
|
14
|
-
export type { PaymentsModule, ProductsModule, Product, ProductQuery, ProductSort, CheckoutLineItem, CreateCheckoutParams, CreateCheckoutResult, CreateEmbeddedCheckoutResult, CheckoutSession, SubscriptionState, BillingPortalParams, } from "./modules/payments.types.js";
|
|
14
|
+
export type { PaymentsModule, ProductsModule, Product, ProductQuery, ProductSort, CheckoutLineItem, CreateCheckoutParams, CreateCheckoutResult, CreateEmbeddedCheckoutResult, CheckoutSession, SubscriptionState, BillingPortalParams, OrderCheckoutParams, OrderCheckout, OrderPayments, Payment, PaymentStatus, PaymentListParams, Refund, RefundStatus, } from "./modules/payments.types.js";
|
|
15
|
+
export type { CatalogModule, CatalogItem, CatalogItemKind, CatalogItemStatus, CatalogVariant, CatalogVariantStatus, CatalogListParams, CatalogVariantInput, CreateCatalogItemParams, UpdateCatalogItemParams, UpdateCatalogVariantParams, } from "./modules/catalog.types.js";
|
|
16
|
+
export type { OrdersModule, Order, OrderItem, OrderBuyer, OrderChannel, OrderSummary, OrderStatus, FulfillmentStatus, ShippingAddress, CreateOrderParams, CreateOrderOptions, CreateOrderResult, OrderListParams, OrderAccessOptions, UpdateOrderParams, } from "./modules/orders.types.js";
|
|
17
|
+
export type { ContactsModule, Contact, ContactDetail, ContactSource, ContactUserLink, ContactListParams, CreateContactParams, UpdateContactParams, } from "./modules/contacts.types.js";
|
|
18
|
+
export type { EventsModule, ProjectEvent, EventSubjectType, EventListParams, } from "./modules/events.types.js";
|
|
19
|
+
export type { UsersModule, UserRecord, UserListParams, } from "./modules/users.types.js";
|
|
20
|
+
export type { AppModule, AppPublicSettings, Address, Page, PageParams, VersionInput, CreateOptions, } from "./modules/project.types.js";
|
|
15
21
|
export type { SsoModule, SsoAccessTokenResponse } from "./modules/sso.types.js";
|
|
16
22
|
export type { ConnectorsModule, UserConnectorsModule, ConnectorApiRequest, ConnectorApiResponse, ConnectorProxyRawResponse, } from "./modules/connectors.types.js";
|
|
17
23
|
export type { CustomIntegrationsModule, CustomIntegrationCallParams, CustomIntegrationCallResponse, } from "./modules/custom-integrations.types.js";
|
package/dist/modules/auth.js
CHANGED
|
@@ -211,6 +211,12 @@ export function createAuthModule(axios, functionsAxiosClient, appId, options) {
|
|
|
211
211
|
otp_code: otpCode,
|
|
212
212
|
});
|
|
213
213
|
},
|
|
214
|
+
// Exchange the one-time code a sign-in redirect brought back for a token
|
|
215
|
+
async exchangeLoginCode(code) {
|
|
216
|
+
return (await axios.post(`/apps/${appId}/auth/session`, {
|
|
217
|
+
code,
|
|
218
|
+
}));
|
|
219
|
+
},
|
|
214
220
|
// Resend an OTP code to the user's email
|
|
215
221
|
resendOtp(email) {
|
|
216
222
|
return axios.post(`/apps/${appId}/auth/resend-otp`, { email });
|
|
@@ -42,6 +42,21 @@ export interface LoginResponse {
|
|
|
42
42
|
/** User information. */
|
|
43
43
|
user: User;
|
|
44
44
|
}
|
|
45
|
+
/** What the session endpoints answer with: the token and the account as the site sees it. */
|
|
46
|
+
export interface LoginSession {
|
|
47
|
+
access_token: string;
|
|
48
|
+
user: {
|
|
49
|
+
id: string;
|
|
50
|
+
email: string;
|
|
51
|
+
full_name: string | null;
|
|
52
|
+
role: string;
|
|
53
|
+
verified: boolean;
|
|
54
|
+
created_date: string | null;
|
|
55
|
+
updated_date: string | null;
|
|
56
|
+
/** The account's own custom fields. */
|
|
57
|
+
[field: string]: unknown;
|
|
58
|
+
};
|
|
59
|
+
}
|
|
45
60
|
/**
|
|
46
61
|
* Payload for user registration.
|
|
47
62
|
*/
|
|
@@ -514,4 +529,19 @@ export interface AuthModule {
|
|
|
514
529
|
* ```
|
|
515
530
|
*/
|
|
516
531
|
changePassword(params: ChangePasswordParams): Promise<any>;
|
|
532
|
+
/**
|
|
533
|
+
* Exchanges the one-time code a sign-in redirect (Google, SSO) brought back
|
|
534
|
+
* in the URL for an access token. The code is single-use and lives about a
|
|
535
|
+
* minute. Does not set the token: pass it to `doany.setToken()`.
|
|
536
|
+
*
|
|
537
|
+
* @example
|
|
538
|
+
* ```typescript
|
|
539
|
+
* const code = new URLSearchParams(window.location.search).get('code');
|
|
540
|
+
* if (code) {
|
|
541
|
+
* const { access_token } = await doany.auth.exchangeLoginCode(code);
|
|
542
|
+
* doany.setToken(access_token);
|
|
543
|
+
* }
|
|
544
|
+
* ```
|
|
545
|
+
*/
|
|
546
|
+
exchangeLoginCode(code: string): Promise<LoginSession>;
|
|
517
547
|
}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { AxiosInstance } from "axios";
|
|
2
|
+
import { CatalogModule } from "./catalog.types";
|
|
3
|
+
import { ProjectScope } from "./project.js";
|
|
4
|
+
/**
|
|
5
|
+
* Creates the catalog module: `/projects/{project_id}/catalog/...`.
|
|
6
|
+
*
|
|
7
|
+
* @internal
|
|
8
|
+
*/
|
|
9
|
+
export declare function createCatalogModule(axios: AxiosInstance, appId: string, project: ProjectScope): CatalogModule;
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
import { idempotencyHeaders, queryOf, seg } from "./project.js";
|
|
2
|
+
/**
|
|
3
|
+
* Creates the catalog module: `/projects/{project_id}/catalog/...`.
|
|
4
|
+
*
|
|
5
|
+
* @internal
|
|
6
|
+
*/
|
|
7
|
+
export function createCatalogModule(axios, appId, project) {
|
|
8
|
+
const items = (suffix = "") => project.path(`/catalog/items${suffix}`);
|
|
9
|
+
const variants = (suffix) => project.path(`/catalog/variants${suffix}`);
|
|
10
|
+
const post = async (url, data, headers) => (await axios.request({ method: "POST", url: await url, data, headers }));
|
|
11
|
+
return {
|
|
12
|
+
async list(params = {}) {
|
|
13
|
+
// A site lists what it sells unless told otherwise.
|
|
14
|
+
const query = queryOf({ ...params, app_id: params.app_id === undefined ? appId : params.app_id });
|
|
15
|
+
return (await axios.get(await items(), { params: query }));
|
|
16
|
+
},
|
|
17
|
+
async get(itemId, params = {}) {
|
|
18
|
+
return (await axios.get(await items(`/${seg(itemId)}`), {
|
|
19
|
+
params: queryOf(params),
|
|
20
|
+
}));
|
|
21
|
+
},
|
|
22
|
+
create(params, options) {
|
|
23
|
+
return post(items(), params, idempotencyHeaders(options === null || options === void 0 ? void 0 : options.idempotencyKey));
|
|
24
|
+
},
|
|
25
|
+
async update(itemId, params) {
|
|
26
|
+
return (await axios.patch(await items(`/${seg(itemId)}`), params));
|
|
27
|
+
},
|
|
28
|
+
publish(itemId, { version }) {
|
|
29
|
+
return post(items(`/${seg(itemId)}/publish`), { version });
|
|
30
|
+
},
|
|
31
|
+
archive(itemId, { version }) {
|
|
32
|
+
return post(items(`/${seg(itemId)}/archive`), { version });
|
|
33
|
+
},
|
|
34
|
+
restore(itemId, { version }) {
|
|
35
|
+
return post(items(`/${seg(itemId)}/restore`), { version });
|
|
36
|
+
},
|
|
37
|
+
async setDirectPurchase(itemId, { enabled, version }) {
|
|
38
|
+
return (await axios.put(await items(`/${seg(itemId)}/direct-purchase`), {
|
|
39
|
+
enabled,
|
|
40
|
+
version,
|
|
41
|
+
}));
|
|
42
|
+
},
|
|
43
|
+
async delete(itemId) {
|
|
44
|
+
await axios.delete(await items(`/${seg(itemId)}`));
|
|
45
|
+
},
|
|
46
|
+
createVariant(itemId, params, options) {
|
|
47
|
+
return post(items(`/${seg(itemId)}/variants`), params, idempotencyHeaders(options === null || options === void 0 ? void 0 : options.idempotencyKey));
|
|
48
|
+
},
|
|
49
|
+
async updateVariant(variantId, params) {
|
|
50
|
+
return (await axios.patch(await variants(`/${seg(variantId)}`), params));
|
|
51
|
+
},
|
|
52
|
+
archiveVariant(variantId, { version }) {
|
|
53
|
+
return post(variants(`/${seg(variantId)}/archive`), { version });
|
|
54
|
+
},
|
|
55
|
+
restoreVariant(variantId, { version }) {
|
|
56
|
+
return post(variants(`/${seg(variantId)}/restore`), { version });
|
|
57
|
+
},
|
|
58
|
+
async deleteVariant(variantId) {
|
|
59
|
+
await axios.delete(await variants(`/${seg(variantId)}`));
|
|
60
|
+
},
|
|
61
|
+
};
|
|
62
|
+
}
|
|
@@ -0,0 +1,163 @@
|
|
|
1
|
+
import type { CreateOptions, Page, PageParams, VersionInput } from "./project.types";
|
|
2
|
+
export type CatalogItemKind = "service" | "physical" | "digital";
|
|
3
|
+
export type CatalogItemStatus = "draft" | "active" | "archived";
|
|
4
|
+
export type CatalogVariantStatus = "active" | "archived";
|
|
5
|
+
/**
|
|
6
|
+
* One way an item is sold: a name, a price and, for services, a duration.
|
|
7
|
+
*/
|
|
8
|
+
export interface CatalogVariant {
|
|
9
|
+
id: string;
|
|
10
|
+
catalog_item_id: string;
|
|
11
|
+
status: CatalogVariantStatus;
|
|
12
|
+
name: string;
|
|
13
|
+
/** The business's own stock-keeping code. */
|
|
14
|
+
sku: string | null;
|
|
15
|
+
/** In the currency's smallest unit (cents). `null` when no price is set; `0` is free. */
|
|
16
|
+
price_amount: number | null;
|
|
17
|
+
/** Three upper-case letters, e.g. `"USD"`. `null` exactly when `price_amount` is. */
|
|
18
|
+
currency: string | null;
|
|
19
|
+
duration_minutes: number | null;
|
|
20
|
+
/** The variant to preselect. */
|
|
21
|
+
is_default: boolean;
|
|
22
|
+
sort_order: number;
|
|
23
|
+
version: number;
|
|
24
|
+
created_at: string;
|
|
25
|
+
updated_at: string;
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* Something the business offers, with the variants it is sold in.
|
|
29
|
+
*/
|
|
30
|
+
export interface CatalogItem {
|
|
31
|
+
id: string;
|
|
32
|
+
kind: CatalogItemKind;
|
|
33
|
+
/** `active` is shown; `draft` and `archived` are not. */
|
|
34
|
+
status: CatalogItemStatus;
|
|
35
|
+
/** The site that sells it; `null` when every site of the business does. */
|
|
36
|
+
app_id: string | null;
|
|
37
|
+
name: string;
|
|
38
|
+
description: string | null;
|
|
39
|
+
category: string | null;
|
|
40
|
+
image_url: string | null;
|
|
41
|
+
direct_purchase_enabled: boolean;
|
|
42
|
+
/**
|
|
43
|
+
* Whether it can be ordered right now with `doany.orders.create`: published,
|
|
44
|
+
* direct purchase on, and at least one active variant with a price.
|
|
45
|
+
*/
|
|
46
|
+
purchasable: boolean;
|
|
47
|
+
sort_order: number;
|
|
48
|
+
/** In display order. */
|
|
49
|
+
variants: CatalogVariant[];
|
|
50
|
+
version: number;
|
|
51
|
+
created_at: string;
|
|
52
|
+
updated_at: string;
|
|
53
|
+
}
|
|
54
|
+
export interface CatalogListParams extends PageParams {
|
|
55
|
+
/** `active` (default), `draft`, `archived` or `all`. A visitor only ever sees `active`. */
|
|
56
|
+
status?: CatalogItemStatus | "all";
|
|
57
|
+
/**
|
|
58
|
+
* The items a site sells: its own and those every site sells. Defaults to
|
|
59
|
+
* this client's app; `null` lists every item of the business.
|
|
60
|
+
*/
|
|
61
|
+
app_id?: string | null;
|
|
62
|
+
/** Only items that can be ordered right now. */
|
|
63
|
+
purchasable?: boolean;
|
|
64
|
+
/** Which variants come with each item: `active` (default) or `all`. */
|
|
65
|
+
variant_status?: "active" | "all";
|
|
66
|
+
/** Part of the name. */
|
|
67
|
+
q?: string;
|
|
68
|
+
category?: string;
|
|
69
|
+
kind?: CatalogItemKind;
|
|
70
|
+
}
|
|
71
|
+
export interface CatalogVariantInput {
|
|
72
|
+
name: string;
|
|
73
|
+
sku?: string | null;
|
|
74
|
+
price_amount?: number | null;
|
|
75
|
+
currency?: string | null;
|
|
76
|
+
duration_minutes?: number | null;
|
|
77
|
+
/** At most one per item; with none, the first variant is the default. */
|
|
78
|
+
is_default?: boolean;
|
|
79
|
+
sort_order?: number;
|
|
80
|
+
}
|
|
81
|
+
export interface CreateCatalogItemParams {
|
|
82
|
+
name: string;
|
|
83
|
+
/** `service` (default), `physical` or `digital`. Cannot change later. */
|
|
84
|
+
kind?: CatalogItemKind;
|
|
85
|
+
description?: string | null;
|
|
86
|
+
category?: string | null;
|
|
87
|
+
/** An `http(s)://` URL. */
|
|
88
|
+
image_url?: string | null;
|
|
89
|
+
sort_order?: number;
|
|
90
|
+
/** The one site that sells it; left out or `null`, every site does. */
|
|
91
|
+
app_id?: string | null;
|
|
92
|
+
variants?: CatalogVariantInput[];
|
|
93
|
+
}
|
|
94
|
+
export interface UpdateCatalogItemParams extends VersionInput {
|
|
95
|
+
name?: string;
|
|
96
|
+
description?: string | null;
|
|
97
|
+
category?: string | null;
|
|
98
|
+
image_url?: string | null;
|
|
99
|
+
sort_order?: number;
|
|
100
|
+
app_id?: string | null;
|
|
101
|
+
}
|
|
102
|
+
export interface UpdateCatalogVariantParams extends VersionInput {
|
|
103
|
+
name?: string;
|
|
104
|
+
sku?: string | null;
|
|
105
|
+
price_amount?: number | null;
|
|
106
|
+
currency?: string | null;
|
|
107
|
+
duration_minutes?: number | null;
|
|
108
|
+
/** `true` also unsets the item's previous default. */
|
|
109
|
+
is_default?: boolean;
|
|
110
|
+
sort_order?: number;
|
|
111
|
+
}
|
|
112
|
+
/**
|
|
113
|
+
* What the business offers: items and the variants they are sold in.
|
|
114
|
+
*
|
|
115
|
+
* Everyone can read what is published. Changing the catalog takes the site's
|
|
116
|
+
* admin account or a service credential (`asServiceRole`); others are refused
|
|
117
|
+
* with 403 (401 when nobody is signed in).
|
|
118
|
+
*
|
|
119
|
+
* Every change sends back the `version` it is based on; a stale one is
|
|
120
|
+
* refused with 409 `VERSION_CONFLICT` and `details.version` is the current one.
|
|
121
|
+
* A change that would leave a published, directly purchasable item without a
|
|
122
|
+
* priced variant, or mix currencies, is refused with 409 `NOT_PURCHASABLE`
|
|
123
|
+
* (`details.reason`).
|
|
124
|
+
*/
|
|
125
|
+
export interface CatalogModule {
|
|
126
|
+
/**
|
|
127
|
+
* The items this site sells.
|
|
128
|
+
*
|
|
129
|
+
* @example
|
|
130
|
+
* ```typescript
|
|
131
|
+
* const { data: items } = await doany.catalog.list({ purchasable: true });
|
|
132
|
+
* ```
|
|
133
|
+
*/
|
|
134
|
+
list(params?: CatalogListParams): Promise<Page<CatalogItem>>;
|
|
135
|
+
/** One item. Rejects with 404 when there is none, or the caller may not see it. */
|
|
136
|
+
get(itemId: string, params?: {
|
|
137
|
+
variant_status?: "active" | "all";
|
|
138
|
+
}): Promise<CatalogItem>;
|
|
139
|
+
/** A new item, as a `draft` with direct purchase off. */
|
|
140
|
+
create(params: CreateCatalogItemParams, options?: CreateOptions): Promise<CatalogItem>;
|
|
141
|
+
/** Changes the item's details. `status` and direct purchase have their own calls. */
|
|
142
|
+
update(itemId: string, params: UpdateCatalogItemParams): Promise<CatalogItem>;
|
|
143
|
+
/** `draft` → `active` (shown). */
|
|
144
|
+
publish(itemId: string, params: VersionInput): Promise<CatalogItem>;
|
|
145
|
+
/** → `archived`: no longer shown or sold; existing orders are unaffected. */
|
|
146
|
+
archive(itemId: string, params: VersionInput): Promise<CatalogItem>;
|
|
147
|
+
/** `archived` → `draft`, to be checked and published again. */
|
|
148
|
+
restore(itemId: string, params: VersionInput): Promise<CatalogItem>;
|
|
149
|
+
/** Turns ordering the item directly on the site on or off. */
|
|
150
|
+
setDirectPurchase(itemId: string, params: VersionInput & {
|
|
151
|
+
enabled: boolean;
|
|
152
|
+
}): Promise<CatalogItem>;
|
|
153
|
+
/** Deletes an item nothing refers to; otherwise 409 `IN_USE` (archive it instead). */
|
|
154
|
+
delete(itemId: string): Promise<void>;
|
|
155
|
+
/** A new variant of an item. */
|
|
156
|
+
createVariant(itemId: string, params: CatalogVariantInput, options?: CreateOptions): Promise<CatalogVariant>;
|
|
157
|
+
/** Changes a variant. A new price applies to orders placed from now on. */
|
|
158
|
+
updateVariant(variantId: string, params: UpdateCatalogVariantParams): Promise<CatalogVariant>;
|
|
159
|
+
archiveVariant(variantId: string, params: VersionInput): Promise<CatalogVariant>;
|
|
160
|
+
restoreVariant(variantId: string, params: VersionInput): Promise<CatalogVariant>;
|
|
161
|
+
/** Deletes a variant nothing refers to; otherwise 409 `IN_USE`. */
|
|
162
|
+
deleteVariant(variantId: string): Promise<void>;
|
|
163
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { AxiosInstance } from "axios";
|
|
2
|
+
import { ContactsModule } from "./contacts.types";
|
|
3
|
+
import { ProjectScope } from "./project.js";
|
|
4
|
+
/**
|
|
5
|
+
* Creates the contacts module: `/projects/{project_id}/contacts/...`.
|
|
6
|
+
*
|
|
7
|
+
* @internal
|
|
8
|
+
*/
|
|
9
|
+
export declare function createContactsModule(axios: AxiosInstance, project: ProjectScope): ContactsModule;
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import { idempotencyHeaders, queryOf, seg } from "./project.js";
|
|
2
|
+
/**
|
|
3
|
+
* Creates the contacts module: `/projects/{project_id}/contacts/...`.
|
|
4
|
+
*
|
|
5
|
+
* @internal
|
|
6
|
+
*/
|
|
7
|
+
export function createContactsModule(axios, project) {
|
|
8
|
+
const contacts = (suffix = "") => project.path(`/contacts${suffix}`);
|
|
9
|
+
const post = async (suffix, data, headers) => (await axios.request({ method: "POST", url: await contacts(suffix), data, headers }));
|
|
10
|
+
return {
|
|
11
|
+
async list(params = {}) {
|
|
12
|
+
return (await axios.get(await contacts(), { params: queryOf(params) }));
|
|
13
|
+
},
|
|
14
|
+
async get(contactId) {
|
|
15
|
+
return (await axios.get(await contacts(`/${seg(contactId)}`)));
|
|
16
|
+
},
|
|
17
|
+
async me() {
|
|
18
|
+
return (await axios.get(await contacts("/me")));
|
|
19
|
+
},
|
|
20
|
+
create(params, options) {
|
|
21
|
+
return post("", params, idempotencyHeaders(options === null || options === void 0 ? void 0 : options.idempotencyKey));
|
|
22
|
+
},
|
|
23
|
+
async update(contactId, params) {
|
|
24
|
+
return (await axios.patch(await contacts(`/${seg(contactId)}`), params));
|
|
25
|
+
},
|
|
26
|
+
async updateMe(params) {
|
|
27
|
+
return (await axios.patch(await contacts("/me"), params));
|
|
28
|
+
},
|
|
29
|
+
archive(contactId, { version }) {
|
|
30
|
+
return post(`/${seg(contactId)}/archive`, { version });
|
|
31
|
+
},
|
|
32
|
+
restore(contactId, { version }) {
|
|
33
|
+
return post(`/${seg(contactId)}/restore`, { version });
|
|
34
|
+
},
|
|
35
|
+
merge(contactId, { into_contact_id, version }) {
|
|
36
|
+
return post(`/${seg(contactId)}/merge`, { into_contact_id, version });
|
|
37
|
+
},
|
|
38
|
+
async delete(contactId) {
|
|
39
|
+
await axios.delete(await contacts(`/${seg(contactId)}`));
|
|
40
|
+
},
|
|
41
|
+
};
|
|
42
|
+
}
|