@phpsandbox/sdk 0.4.0 → 0.6.0-canary.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.
@@ -0,0 +1,430 @@
1
+ import { z } from 'zod';
2
+ import type { Client } from './index.js';
3
+ declare const customerConfigurationSchema: z.ZodObject<{
4
+ funnel: z.ZodNullable<z.ZodObject<{
5
+ title: z.ZodString;
6
+ stages: z.ZodArray<z.ZodDiscriminatedUnion<[z.ZodObject<{
7
+ id: z.ZodString;
8
+ label: z.ZodString;
9
+ measure: z.ZodLiteral<"event">;
10
+ event: z.ZodString;
11
+ }, z.core.$strip>, z.ZodObject<{
12
+ id: z.ZodString;
13
+ label: z.ZodString;
14
+ measure: z.ZodLiteral<"first_payment">;
15
+ }, z.core.$strip>, z.ZodObject<{
16
+ id: z.ZodString;
17
+ label: z.ZodString;
18
+ measure: z.ZodLiteral<"event_after_payment">;
19
+ event: z.ZodString;
20
+ }, z.core.$strip>], "measure">>;
21
+ }, z.core.$strip>>;
22
+ followUp: z.ZodNullable<z.ZodObject<{
23
+ label: z.ZodString;
24
+ triggerEvent: z.ZodString;
25
+ prerequisiteEvent: z.ZodNullable<z.ZodString>;
26
+ stopOnPayment: z.ZodBoolean;
27
+ }, z.core.$strip>>;
28
+ }, z.core.$strip>;
29
+ export type CustomerConfiguration = z.infer<typeof customerConfigurationSchema>;
30
+ export declare const customerModeSchema: z.ZodEnum<{
31
+ test: "test";
32
+ live: "live";
33
+ }>;
34
+ export type CustomerMode = z.infer<typeof customerModeSchema>;
35
+ export declare const customerSchema: z.ZodObject<{
36
+ id: z.ZodString;
37
+ externalId: z.ZodString;
38
+ email: z.ZodString;
39
+ name: z.ZodNullable<z.ZodString>;
40
+ source: z.ZodNullable<z.ZodString>;
41
+ marketingSubscribed: z.ZodBoolean;
42
+ communicationBasis: z.ZodOptional<z.ZodEnum<{
43
+ unknown: "unknown";
44
+ legacy_account: "legacy_account";
45
+ explicit_opt_in: "explicit_opt_in";
46
+ unsubscribed: "unsubscribed";
47
+ }>>;
48
+ legacyPolicy: z.ZodOptional<z.ZodNullable<z.ZodString>>;
49
+ joinedAt: z.ZodOptional<z.ZodNullable<z.ZodString>>;
50
+ importedAt: z.ZodOptional<z.ZodNullable<z.ZodString>>;
51
+ lastActiveAt: z.ZodOptional<z.ZodNullable<z.ZodString>>;
52
+ billingStatus: z.ZodOptional<z.ZodEnum<{
53
+ unknown: "unknown";
54
+ paid: "paid";
55
+ free: "free";
56
+ }>>;
57
+ suppressionReason: z.ZodNullable<z.ZodString>;
58
+ activatedAt: z.ZodNullable<z.ZodString>;
59
+ createdAt: z.ZodNullable<z.ZodString>;
60
+ }, z.core.$strip>;
61
+ export type CustomerData = z.infer<typeof customerSchema>;
62
+ declare const spaceSchema: z.ZodObject<{
63
+ id: z.ZodString;
64
+ mode: z.ZodEnum<{
65
+ test: "test";
66
+ live: "live";
67
+ }>;
68
+ enabled: z.ZodBoolean;
69
+ senderName: z.ZodNullable<z.ZodString>;
70
+ senderEmail: z.ZodNullable<z.ZodString>;
71
+ replyTo: z.ZodNullable<z.ZodString>;
72
+ senderVerified: z.ZodBoolean;
73
+ domainRecords: z.ZodNullable<z.ZodString>;
74
+ configuration: z.ZodOptional<z.ZodObject<{
75
+ funnel: z.ZodNullable<z.ZodObject<{
76
+ title: z.ZodString;
77
+ stages: z.ZodArray<z.ZodDiscriminatedUnion<[z.ZodObject<{
78
+ id: z.ZodString;
79
+ label: z.ZodString;
80
+ measure: z.ZodLiteral<"event">;
81
+ event: z.ZodString;
82
+ }, z.core.$strip>, z.ZodObject<{
83
+ id: z.ZodString;
84
+ label: z.ZodString;
85
+ measure: z.ZodLiteral<"first_payment">;
86
+ }, z.core.$strip>, z.ZodObject<{
87
+ id: z.ZodString;
88
+ label: z.ZodString;
89
+ measure: z.ZodLiteral<"event_after_payment">;
90
+ event: z.ZodString;
91
+ }, z.core.$strip>], "measure">>;
92
+ }, z.core.$strip>>;
93
+ followUp: z.ZodNullable<z.ZodObject<{
94
+ label: z.ZodString;
95
+ triggerEvent: z.ZodString;
96
+ prerequisiteEvent: z.ZodNullable<z.ZodString>;
97
+ stopOnPayment: z.ZodBoolean;
98
+ }, z.core.$strip>>;
99
+ }, z.core.$strip>>;
100
+ emailTemplate: z.ZodOptional<z.ZodNullable<z.ZodString>>;
101
+ provisionedAt: z.ZodOptional<z.ZodNullable<z.ZodString>>;
102
+ lastRequestAt: z.ZodOptional<z.ZodNullable<z.ZodString>>;
103
+ processedAt: z.ZodOptional<z.ZodNullable<z.ZodString>>;
104
+ }, z.core.$strip>;
105
+ export type CustomerSpaceData = z.infer<typeof spaceSchema>;
106
+ declare const journeyInputSchema: z.ZodObject<{
107
+ enabled: z.ZodBoolean;
108
+ subject: z.ZodString;
109
+ body: z.ZodString;
110
+ delayMinutes: z.ZodNumber;
111
+ activationEvent: z.ZodString;
112
+ }, z.core.$strip>;
113
+ export type CustomerJourneyInput = z.infer<typeof journeyInputSchema>;
114
+ declare const journeySchema: z.ZodObject<{
115
+ enabled: z.ZodBoolean;
116
+ subject: z.ZodString;
117
+ body: z.ZodString;
118
+ delayMinutes: z.ZodNumber;
119
+ activationEvent: z.ZodString;
120
+ kind: z.ZodEnum<{
121
+ setup: "setup";
122
+ welcome: "welcome";
123
+ purchase: "purchase";
124
+ credit_limit: "credit_limit";
125
+ }>;
126
+ version: z.ZodOptional<z.ZodNumber>;
127
+ startsAt: z.ZodOptional<z.ZodNullable<z.ZodString>>;
128
+ draft: z.ZodOptional<z.ZodNullable<z.ZodObject<{
129
+ enabled: z.ZodBoolean;
130
+ subject: z.ZodString;
131
+ body: z.ZodString;
132
+ delayMinutes: z.ZodNumber;
133
+ activationEvent: z.ZodString;
134
+ }, z.core.$strip>>>;
135
+ }, z.core.$strip>;
136
+ export type CustomerJourneyData = z.infer<typeof journeySchema>;
137
+ declare const messageSchema: z.ZodObject<{
138
+ id: z.ZodString;
139
+ customerId: z.ZodNullable<z.ZodString>;
140
+ recipient: z.ZodString;
141
+ subject: z.ZodString;
142
+ body: z.ZodString;
143
+ status: z.ZodString;
144
+ error: z.ZodNullable<z.ZodString>;
145
+ dueAt: z.ZodOptional<z.ZodNullable<z.ZodString>>;
146
+ attemptedAt: z.ZodOptional<z.ZodNullable<z.ZodString>>;
147
+ receivedAt: z.ZodOptional<z.ZodNullable<z.ZodString>>;
148
+ journeyKind: z.ZodOptional<z.ZodNullable<z.ZodEnum<{
149
+ setup: "setup";
150
+ welcome: "welcome";
151
+ purchase: "purchase";
152
+ credit_limit: "credit_limit";
153
+ }>>>;
154
+ journeyVersion: z.ZodOptional<z.ZodNullable<z.ZodNumber>>;
155
+ category: z.ZodOptional<z.ZodEnum<{
156
+ marketing: "marketing";
157
+ service: "service";
158
+ }>>;
159
+ from: z.ZodOptional<z.ZodNullable<z.ZodString>>;
160
+ replyTo: z.ZodOptional<z.ZodNullable<z.ZodString>>;
161
+ renderedText: z.ZodOptional<z.ZodNullable<z.ZodString>>;
162
+ renderedHtml: z.ZodOptional<z.ZodNullable<z.ZodString>>;
163
+ unsubscribeUrl: z.ZodOptional<z.ZodNullable<z.ZodString>>;
164
+ createdAt: z.ZodNullable<z.ZodString>;
165
+ }, z.core.$strip>;
166
+ export type CustomerMessageData = z.infer<typeof messageSchema>;
167
+ declare const overviewSchema: z.ZodObject<{
168
+ funnel: z.ZodOptional<z.ZodNullable<z.ZodObject<{
169
+ title: z.ZodString;
170
+ stages: z.ZodArray<z.ZodObject<{
171
+ id: z.ZodString;
172
+ label: z.ZodString;
173
+ count: z.ZodNumber;
174
+ }, z.core.$strip>>;
175
+ }, z.core.$strip>>>;
176
+ space: z.ZodNullable<z.ZodObject<{
177
+ id: z.ZodString;
178
+ mode: z.ZodEnum<{
179
+ test: "test";
180
+ live: "live";
181
+ }>;
182
+ enabled: z.ZodBoolean;
183
+ senderName: z.ZodNullable<z.ZodString>;
184
+ senderEmail: z.ZodNullable<z.ZodString>;
185
+ replyTo: z.ZodNullable<z.ZodString>;
186
+ senderVerified: z.ZodBoolean;
187
+ domainRecords: z.ZodNullable<z.ZodString>;
188
+ configuration: z.ZodOptional<z.ZodObject<{
189
+ funnel: z.ZodNullable<z.ZodObject<{
190
+ title: z.ZodString;
191
+ stages: z.ZodArray<z.ZodDiscriminatedUnion<[z.ZodObject<{
192
+ id: z.ZodString;
193
+ label: z.ZodString;
194
+ measure: z.ZodLiteral<"event">;
195
+ event: z.ZodString;
196
+ }, z.core.$strip>, z.ZodObject<{
197
+ id: z.ZodString;
198
+ label: z.ZodString;
199
+ measure: z.ZodLiteral<"first_payment">;
200
+ }, z.core.$strip>, z.ZodObject<{
201
+ id: z.ZodString;
202
+ label: z.ZodString;
203
+ measure: z.ZodLiteral<"event_after_payment">;
204
+ event: z.ZodString;
205
+ }, z.core.$strip>], "measure">>;
206
+ }, z.core.$strip>>;
207
+ followUp: z.ZodNullable<z.ZodObject<{
208
+ label: z.ZodString;
209
+ triggerEvent: z.ZodString;
210
+ prerequisiteEvent: z.ZodNullable<z.ZodString>;
211
+ stopOnPayment: z.ZodBoolean;
212
+ }, z.core.$strip>>;
213
+ }, z.core.$strip>>;
214
+ emailTemplate: z.ZodOptional<z.ZodNullable<z.ZodString>>;
215
+ provisionedAt: z.ZodOptional<z.ZodNullable<z.ZodString>>;
216
+ lastRequestAt: z.ZodOptional<z.ZodNullable<z.ZodString>>;
217
+ processedAt: z.ZodOptional<z.ZodNullable<z.ZodString>>;
218
+ }, z.core.$strip>>;
219
+ customers: z.ZodArray<z.ZodObject<{
220
+ id: z.ZodString;
221
+ externalId: z.ZodString;
222
+ email: z.ZodString;
223
+ name: z.ZodNullable<z.ZodString>;
224
+ source: z.ZodNullable<z.ZodString>;
225
+ marketingSubscribed: z.ZodBoolean;
226
+ communicationBasis: z.ZodOptional<z.ZodEnum<{
227
+ unknown: "unknown";
228
+ legacy_account: "legacy_account";
229
+ explicit_opt_in: "explicit_opt_in";
230
+ unsubscribed: "unsubscribed";
231
+ }>>;
232
+ legacyPolicy: z.ZodOptional<z.ZodNullable<z.ZodString>>;
233
+ joinedAt: z.ZodOptional<z.ZodNullable<z.ZodString>>;
234
+ importedAt: z.ZodOptional<z.ZodNullable<z.ZodString>>;
235
+ lastActiveAt: z.ZodOptional<z.ZodNullable<z.ZodString>>;
236
+ billingStatus: z.ZodOptional<z.ZodEnum<{
237
+ unknown: "unknown";
238
+ paid: "paid";
239
+ free: "free";
240
+ }>>;
241
+ suppressionReason: z.ZodNullable<z.ZodString>;
242
+ activatedAt: z.ZodNullable<z.ZodString>;
243
+ createdAt: z.ZodNullable<z.ZodString>;
244
+ }, z.core.$strip>>;
245
+ journeys: z.ZodArray<z.ZodObject<{
246
+ enabled: z.ZodBoolean;
247
+ subject: z.ZodString;
248
+ body: z.ZodString;
249
+ delayMinutes: z.ZodNumber;
250
+ activationEvent: z.ZodString;
251
+ kind: z.ZodEnum<{
252
+ setup: "setup";
253
+ welcome: "welcome";
254
+ purchase: "purchase";
255
+ credit_limit: "credit_limit";
256
+ }>;
257
+ version: z.ZodOptional<z.ZodNumber>;
258
+ startsAt: z.ZodOptional<z.ZodNullable<z.ZodString>>;
259
+ draft: z.ZodOptional<z.ZodNullable<z.ZodObject<{
260
+ enabled: z.ZodBoolean;
261
+ subject: z.ZodString;
262
+ body: z.ZodString;
263
+ delayMinutes: z.ZodNumber;
264
+ activationEvent: z.ZodString;
265
+ }, z.core.$strip>>>;
266
+ }, z.core.$strip>>;
267
+ messages: z.ZodArray<z.ZodObject<{
268
+ id: z.ZodString;
269
+ customerId: z.ZodNullable<z.ZodString>;
270
+ recipient: z.ZodString;
271
+ subject: z.ZodString;
272
+ body: z.ZodString;
273
+ status: z.ZodString;
274
+ error: z.ZodNullable<z.ZodString>;
275
+ dueAt: z.ZodOptional<z.ZodNullable<z.ZodString>>;
276
+ attemptedAt: z.ZodOptional<z.ZodNullable<z.ZodString>>;
277
+ receivedAt: z.ZodOptional<z.ZodNullable<z.ZodString>>;
278
+ journeyKind: z.ZodOptional<z.ZodNullable<z.ZodEnum<{
279
+ setup: "setup";
280
+ welcome: "welcome";
281
+ purchase: "purchase";
282
+ credit_limit: "credit_limit";
283
+ }>>>;
284
+ journeyVersion: z.ZodOptional<z.ZodNullable<z.ZodNumber>>;
285
+ category: z.ZodOptional<z.ZodEnum<{
286
+ marketing: "marketing";
287
+ service: "service";
288
+ }>>;
289
+ from: z.ZodOptional<z.ZodNullable<z.ZodString>>;
290
+ replyTo: z.ZodOptional<z.ZodNullable<z.ZodString>>;
291
+ renderedText: z.ZodOptional<z.ZodNullable<z.ZodString>>;
292
+ renderedHtml: z.ZodOptional<z.ZodNullable<z.ZodString>>;
293
+ unsubscribeUrl: z.ZodOptional<z.ZodNullable<z.ZodString>>;
294
+ createdAt: z.ZodNullable<z.ZodString>;
295
+ }, z.core.$strip>>;
296
+ total: z.ZodNumber;
297
+ messageTotal: z.ZodOptional<z.ZodNumber>;
298
+ events: z.ZodOptional<z.ZodArray<z.ZodString>>;
299
+ }, z.core.$strip>;
300
+ export type CustomersOverview = z.infer<typeof overviewSchema>;
301
+ export interface IdentifyCustomerInput {
302
+ externalId: string;
303
+ email: string;
304
+ name?: string | null;
305
+ source?: string;
306
+ billingStatus?: 'unknown' | 'free' | 'paid';
307
+ /** Original registration time, independent of the Customers record creation time. */
308
+ joinedAt?: string;
309
+ lastActiveAt?: string;
310
+ /** Historical synchronization never enrolls signup journeys. */
311
+ historical?: boolean;
312
+ /** Explicit eligibility policy for accounts with unknown preferences; this does not record consent. */
313
+ legacyPolicy?: string;
314
+ /** Import known suppressions. Identification can never clear an existing suppression. */
315
+ suppressionReason?: string;
316
+ /** Preserve a known unsubscribe atomically during account identification. Never clears an unsubscribe. */
317
+ unsubscribed?: true;
318
+ /** Original known unsubscribe time. A later explicit opt-in remains authoritative. */
319
+ unsubscribedAt?: string;
320
+ }
321
+ export interface CustomerEventInput {
322
+ eventId: string;
323
+ name: string;
324
+ organizationExternalId?: string;
325
+ occurredAt?: string;
326
+ /** Preserve activity history without activating or enrolling a customer. */
327
+ historical?: boolean;
328
+ properties?: Record<string, string | number | boolean | null>;
329
+ }
330
+ export interface CustomerOrganizationInput {
331
+ externalId: string;
332
+ name: string;
333
+ ownerExternalId: string;
334
+ /** Complete current membership snapshot. The owner is always included. */
335
+ members: {
336
+ externalId: string;
337
+ role: string;
338
+ }[];
339
+ }
340
+ export interface CustomerPaymentInput {
341
+ paymentId: string;
342
+ amountMinor: number;
343
+ currency: string;
344
+ paidAt: string;
345
+ historical?: boolean;
346
+ }
347
+ declare const customerOrganizationSchema: z.ZodObject<{
348
+ id: z.ZodString;
349
+ externalId: z.ZodString;
350
+ name: z.ZodString;
351
+ ownerCustomerId: z.ZodString;
352
+ firstPaidAt: z.ZodNullable<z.ZodString>;
353
+ activatedAt: z.ZodNullable<z.ZodString>;
354
+ }, z.core.$strip>;
355
+ export type CustomerOrganizationData = z.infer<typeof customerOrganizationSchema>;
356
+ export interface SendCustomerMessageInput {
357
+ requestId: string;
358
+ subject: string;
359
+ body: string;
360
+ category: 'service' | 'marketing';
361
+ }
362
+ /** Use only from trusted app servers with a dedicated Customers credential. */
363
+ export declare class CustomerRuntime {
364
+ private readonly client;
365
+ constructor(client: Client);
366
+ /** Configure this application's event funnel and follow-up rules. Does not activate messaging. */
367
+ configure(input: CustomerConfiguration & {
368
+ emailTemplate?: string | null;
369
+ }): Promise<CustomerConfiguration>;
370
+ /** Inspect the workspace and environment selected by this app credential. */
371
+ context(): Promise<{
372
+ id: string;
373
+ notebookId: string;
374
+ mode: CustomerMode;
375
+ }>;
376
+ /** Pull due conversion follow-ups, then recheck authoritative billing, credit and access. */
377
+ pendingFollowUps(): Promise<{
378
+ messageId: string;
379
+ organizationExternalId: string;
380
+ actorExternalId: string;
381
+ }[]>;
382
+ /** Eligible deliveries run immediately; expired checks are never reused by a later worker. */
383
+ resolveFollowUp(messageId: string, resolution: 'eligible' | 'ineligible' | 'paid' | 'credits_available' | 'access_changed'): Promise<CustomerMessageData>;
384
+ organization(input: CustomerOrganizationInput): Promise<CustomerOrganizationData>;
385
+ /** Report only server-confirmed positive payments from your existing billing integration. */
386
+ confirmPayment(organizationExternalId: string, input: CustomerPaymentInput): Promise<CustomerOrganizationData>;
387
+ identify(input: IdentifyCustomerInput): Promise<CustomerData>;
388
+ linkIdentity(customerId: string, externalId: string): Promise<CustomerData>;
389
+ get(customerId: string): Promise<CustomerData>;
390
+ event(customerId: string, input: CustomerEventInput): Promise<{
391
+ id: string;
392
+ name: string;
393
+ }>;
394
+ preferences(customerId: string, input: {
395
+ subscribed: boolean;
396
+ source: string;
397
+ occurredAt?: string;
398
+ }): Promise<CustomerData>;
399
+ send(customerId: string, input: SendCustomerMessageInput): Promise<CustomerMessageData>;
400
+ }
401
+ export declare class CustomersApi {
402
+ private readonly client;
403
+ readonly runtime: CustomerRuntime;
404
+ constructor(client: Client);
405
+ forNotebook(notebookId: string): NotebookCustomers;
406
+ }
407
+ export declare class NotebookCustomers {
408
+ private readonly notebookId;
409
+ private readonly client;
410
+ constructor(notebookId: string, client: Client);
411
+ list(mode?: CustomerMode, query?: {
412
+ search?: string;
413
+ page?: number;
414
+ messagePage?: number;
415
+ }): Promise<CustomersOverview>;
416
+ connect(mode?: CustomerMode): Promise<CustomerSpaceData>;
417
+ provision(mode?: CustomerMode): Promise<CustomerSpaceData>;
418
+ disable(mode?: CustomerMode): Promise<CustomerSpaceData>;
419
+ resume(mode?: CustomerMode): Promise<CustomerSpaceData>;
420
+ rotate(mode?: CustomerMode): Promise<CustomerSpaceData>;
421
+ sender(input: {
422
+ senderName: string;
423
+ senderEmail: string;
424
+ replyTo: string;
425
+ }, mode?: CustomerMode): Promise<CustomerSpaceData>;
426
+ verifySender(mode?: CustomerMode): Promise<CustomerSpaceData>;
427
+ journey(kind: CustomerJourneyData['kind'], input: CustomerJourneyInput, mode?: CustomerMode): Promise<CustomerJourneyData>;
428
+ private path;
429
+ }
430
+ export {};
@@ -0,0 +1,242 @@
1
+ // credit_limit is retained as the compatibility identifier for the application-configured event follow-up.
2
+ import { z } from 'zod';
3
+ const eventName = z.string().trim().min(1).max(100);
4
+ const customerConfigurationSchema = z.object({
5
+ funnel: z
6
+ .object({
7
+ title: z.string().trim().min(1).max(100),
8
+ stages: z
9
+ .array(z.discriminatedUnion('measure', [
10
+ z.object({
11
+ id: z
12
+ .string()
13
+ .regex(/^[a-zA-Z0-9_-]+$/)
14
+ .max(50),
15
+ label: z.string().trim().min(1).max(100),
16
+ measure: z.literal('event'),
17
+ event: eventName,
18
+ }),
19
+ z.object({
20
+ id: z
21
+ .string()
22
+ .regex(/^[a-zA-Z0-9_-]+$/)
23
+ .max(50),
24
+ label: z.string().trim().min(1).max(100),
25
+ measure: z.literal('first_payment'),
26
+ }),
27
+ z.object({
28
+ id: z
29
+ .string()
30
+ .regex(/^[a-zA-Z0-9_-]+$/)
31
+ .max(50),
32
+ label: z.string().trim().min(1).max(100),
33
+ measure: z.literal('event_after_payment'),
34
+ event: eventName,
35
+ }),
36
+ ]))
37
+ .max(12),
38
+ })
39
+ .nullable(),
40
+ followUp: z
41
+ .object({
42
+ label: z.string().trim().min(1).max(100),
43
+ triggerEvent: eventName,
44
+ prerequisiteEvent: eventName.nullable(),
45
+ stopOnPayment: z.boolean(),
46
+ })
47
+ .nullable(),
48
+ });
49
+ export const customerModeSchema = z.enum(['test', 'live']);
50
+ export const customerSchema = z.object({
51
+ id: z.string(),
52
+ externalId: z.string(),
53
+ email: z.string(),
54
+ name: z.string().nullable(),
55
+ source: z.string().nullable(),
56
+ marketingSubscribed: z.boolean(),
57
+ communicationBasis: z.enum(['unknown', 'legacy_account', 'explicit_opt_in', 'unsubscribed']).optional(),
58
+ legacyPolicy: z.string().nullable().optional(),
59
+ joinedAt: z.string().nullable().optional(),
60
+ importedAt: z.string().nullable().optional(),
61
+ lastActiveAt: z.string().nullable().optional(),
62
+ billingStatus: z.enum(['unknown', 'free', 'paid']).optional(),
63
+ suppressionReason: z.string().nullable(),
64
+ activatedAt: z.string().nullable(),
65
+ createdAt: z.string().nullable(),
66
+ });
67
+ const spaceSchema = z.object({
68
+ id: z.string(),
69
+ mode: customerModeSchema,
70
+ enabled: z.boolean(),
71
+ senderName: z.string().nullable(),
72
+ senderEmail: z.string().nullable(),
73
+ replyTo: z.string().nullable(),
74
+ senderVerified: z.boolean(),
75
+ domainRecords: z.string().nullable(),
76
+ configuration: customerConfigurationSchema.optional(),
77
+ emailTemplate: z.string().nullable().optional(),
78
+ provisionedAt: z.string().nullable().optional(),
79
+ lastRequestAt: z.string().nullable().optional(),
80
+ processedAt: z.string().nullable().optional(),
81
+ });
82
+ const journeyInputSchema = z.object({
83
+ enabled: z.boolean(),
84
+ subject: z.string(),
85
+ body: z.string(),
86
+ delayMinutes: z.number(),
87
+ activationEvent: z.string(),
88
+ });
89
+ const journeySchema = journeyInputSchema.extend({
90
+ kind: z.enum(['welcome', 'setup', 'purchase', 'credit_limit']),
91
+ version: z.number().int().optional(),
92
+ startsAt: z.string().nullable().optional(),
93
+ draft: journeyInputSchema.nullable().optional(),
94
+ });
95
+ const messageSchema = z.object({
96
+ id: z.string(),
97
+ customerId: z.string().nullable(),
98
+ recipient: z.string(),
99
+ subject: z.string(),
100
+ body: z.string(),
101
+ status: z.string(),
102
+ error: z.string().nullable(),
103
+ dueAt: z.string().nullable().optional(),
104
+ attemptedAt: z.string().nullable().optional(),
105
+ receivedAt: z.string().nullable().optional(),
106
+ journeyKind: z.enum(['welcome', 'setup', 'purchase', 'credit_limit']).nullable().optional(),
107
+ journeyVersion: z.number().int().nullable().optional(),
108
+ category: z.enum(['marketing', 'service']).optional(),
109
+ from: z.string().nullable().optional(),
110
+ replyTo: z.string().nullable().optional(),
111
+ renderedText: z.string().nullable().optional(),
112
+ renderedHtml: z.string().nullable().optional(),
113
+ unsubscribeUrl: z.string().nullable().optional(),
114
+ createdAt: z.string().nullable(),
115
+ });
116
+ const overviewSchema = z.object({
117
+ funnel: z
118
+ .object({ title: z.string(), stages: z.array(z.object({ id: z.string(), label: z.string(), count: z.number() })) })
119
+ .nullable()
120
+ .optional(),
121
+ space: spaceSchema.nullable(),
122
+ customers: z.array(customerSchema),
123
+ journeys: z.array(journeySchema),
124
+ messages: z.array(messageSchema),
125
+ total: z.number(),
126
+ messageTotal: z.number().optional(),
127
+ events: z.array(z.string()).optional(),
128
+ });
129
+ const customerOrganizationSchema = z.object({
130
+ id: z.string(),
131
+ externalId: z.string(),
132
+ name: z.string(),
133
+ ownerCustomerId: z.string(),
134
+ firstPaidAt: z.string().nullable(),
135
+ activatedAt: z.string().nullable(),
136
+ });
137
+ /** Use only from trusted app servers with a dedicated Customers credential. */
138
+ export class CustomerRuntime {
139
+ constructor(client) {
140
+ this.client = client;
141
+ }
142
+ /** Configure this application's event funnel and follow-up rules. Does not activate messaging. */
143
+ async configure(input) {
144
+ const configuration = customerConfigurationSchema.parse(input);
145
+ return customerConfigurationSchema.parse((await this.client.put('/platform/customers/runtime/configuration', {
146
+ ...configuration,
147
+ ...(input.emailTemplate !== undefined ? { emailTemplate: input.emailTemplate } : {}),
148
+ })).data);
149
+ }
150
+ /** Inspect the workspace and environment selected by this app credential. */
151
+ async context() {
152
+ return z
153
+ .object({ id: z.string(), notebookId: z.string(), mode: customerModeSchema })
154
+ .parse((await this.client.get('/platform/customers/runtime/context')).data);
155
+ }
156
+ /** Pull due conversion follow-ups, then recheck authoritative billing, credit and access. */
157
+ async pendingFollowUps() {
158
+ return z
159
+ .array(z.object({ messageId: z.string(), organizationExternalId: z.string(), actorExternalId: z.string() }))
160
+ .parse((await this.client.get('/platform/customers/runtime/follow-ups')).data);
161
+ }
162
+ /** Eligible deliveries run immediately; expired checks are never reused by a later worker. */
163
+ async resolveFollowUp(messageId, resolution) {
164
+ return messageSchema.parse((await this.client.post(`/platform/customers/runtime/follow-ups/${encodeURIComponent(messageId)}/resolve`, {
165
+ resolution,
166
+ })).data);
167
+ }
168
+ async organization(input) {
169
+ return customerOrganizationSchema.parse((await this.client.put('/platform/customers/runtime/organizations', input)).data);
170
+ }
171
+ /** Report only server-confirmed positive payments from your existing billing integration. */
172
+ async confirmPayment(organizationExternalId, input) {
173
+ return customerOrganizationSchema.parse((await this.client.post(`/platform/customers/runtime/organizations/${encodeURIComponent(organizationExternalId)}/payments`, input)).data);
174
+ }
175
+ async identify(input) {
176
+ return customerSchema.parse((await this.client.post('/platform/customers/runtime/identify', input)).data);
177
+ }
178
+ async linkIdentity(customerId, externalId) {
179
+ return customerSchema.parse((await this.client.post(`/platform/customers/runtime/${encodeURIComponent(customerId)}/identities`, {
180
+ externalId,
181
+ })).data);
182
+ }
183
+ async get(customerId) {
184
+ return customerSchema.parse((await this.client.get(`/platform/customers/runtime/${encodeURIComponent(customerId)}`)).data);
185
+ }
186
+ async event(customerId, input) {
187
+ return z
188
+ .object({ id: z.string(), name: z.string() })
189
+ .parse((await this.client.post(`/platform/customers/runtime/${encodeURIComponent(customerId)}/events`, input)).data);
190
+ }
191
+ async preferences(customerId, input) {
192
+ return customerSchema.parse((await this.client.put(`/platform/customers/runtime/${encodeURIComponent(customerId)}/preferences`, input)).data);
193
+ }
194
+ async send(customerId, input) {
195
+ return messageSchema.parse((await this.client.post(`/platform/customers/runtime/${encodeURIComponent(customerId)}/messages`, input)).data);
196
+ }
197
+ }
198
+ export class CustomersApi {
199
+ constructor(client) {
200
+ this.client = client;
201
+ this.runtime = new CustomerRuntime(client);
202
+ }
203
+ forNotebook(notebookId) {
204
+ return new NotebookCustomers(notebookId, this.client);
205
+ }
206
+ }
207
+ export class NotebookCustomers {
208
+ constructor(notebookId, client) {
209
+ this.notebookId = notebookId;
210
+ this.client = client;
211
+ }
212
+ async list(mode = 'test', query = {}) {
213
+ return overviewSchema.parse((await this.client.get(`${this.path(mode)}?${new URLSearchParams(Object.entries(query).map(([key, value]) => [key, String(value)])).toString()}`)).data);
214
+ }
215
+ async connect(mode = 'test') {
216
+ return spaceSchema.parse((await this.client.put(this.path(mode), {})).data);
217
+ }
218
+ async provision(mode = 'test') {
219
+ return spaceSchema.parse((await this.client.post(`${this.path(mode)}/provision`, {})).data);
220
+ }
221
+ async disable(mode = 'test') {
222
+ return spaceSchema.parse((await this.client.post(`${this.path(mode)}/disable`, {})).data);
223
+ }
224
+ async resume(mode = 'test') {
225
+ return spaceSchema.parse((await this.client.post(`${this.path(mode)}/resume`, {})).data);
226
+ }
227
+ async rotate(mode = 'test') {
228
+ return spaceSchema.parse((await this.client.post(`${this.path(mode)}/rotate`, {})).data);
229
+ }
230
+ async sender(input, mode = 'test') {
231
+ return spaceSchema.parse((await this.client.put(`${this.path(mode)}/sender`, input)).data);
232
+ }
233
+ async verifySender(mode = 'test') {
234
+ return spaceSchema.parse((await this.client.post(`${this.path(mode)}/sender/verify`, {})).data);
235
+ }
236
+ async journey(kind, input, mode = 'test') {
237
+ return journeySchema.parse((await this.client.put(`${this.path(mode)}/journeys/${kind}`, input)).data);
238
+ }
239
+ path(mode) {
240
+ return `/platform/customers/sandboxes/${encodeURIComponent(this.notebookId)}/${mode}`;
241
+ }
242
+ }