@makemind/sdk 0.1.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/CHANGELOG.md +68 -0
- package/LICENSE +21 -0
- package/README.md +550 -0
- package/dist/index.d.mts +3080 -0
- package/dist/index.d.ts +3080 -0
- package/dist/index.js +4131 -0
- package/dist/index.mjs +4074 -0
- package/package.json +66 -0
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,3080 @@
|
|
|
1
|
+
import { FirebaseApp } from 'firebase/app';
|
|
2
|
+
|
|
3
|
+
interface ApiClientConfig {
|
|
4
|
+
baseUrl: string;
|
|
5
|
+
apiKey: string;
|
|
6
|
+
applicationId: string;
|
|
7
|
+
/** Gateway API version segment. Defaults to 'v1'. */
|
|
8
|
+
apiVersion?: string;
|
|
9
|
+
getAuthToken: () => string | null;
|
|
10
|
+
getTenantId: () => string | null;
|
|
11
|
+
/**
|
|
12
|
+
* Optional App Check token provider. When set, its resolved value is attached
|
|
13
|
+
* as the `X-Firebase-AppCheck` header on every request so first-party apps can
|
|
14
|
+
* pass App Check enforcement on the pre-login gateway endpoints. Async because
|
|
15
|
+
* the Firebase App Check SDK returns the token as a promise; returns null when
|
|
16
|
+
* App Check is not configured (the header is then simply omitted).
|
|
17
|
+
*/
|
|
18
|
+
getAppCheckToken?: () => Promise<string | null>;
|
|
19
|
+
}
|
|
20
|
+
interface ApiRequestOptions {
|
|
21
|
+
method?: 'GET' | 'POST' | 'PUT' | 'PATCH' | 'DELETE';
|
|
22
|
+
body?: unknown;
|
|
23
|
+
headers?: Record<string, string>;
|
|
24
|
+
skipAuth?: boolean;
|
|
25
|
+
}
|
|
26
|
+
declare class ApiClient {
|
|
27
|
+
private baseUrl;
|
|
28
|
+
private apiVersion;
|
|
29
|
+
private apiKey;
|
|
30
|
+
private applicationId;
|
|
31
|
+
private getAuthToken;
|
|
32
|
+
private getTenantId;
|
|
33
|
+
private getAppCheckToken?;
|
|
34
|
+
constructor(config: ApiClientConfig);
|
|
35
|
+
request<T>(endpoint: string, options?: ApiRequestOptions): Promise<T>;
|
|
36
|
+
private handleErrorResponse;
|
|
37
|
+
private mapStatusToCode;
|
|
38
|
+
get<T>(endpoint: string, options?: Omit<ApiRequestOptions, 'method' | 'body'>): Promise<T>;
|
|
39
|
+
post<T>(endpoint: string, body?: unknown, options?: Omit<ApiRequestOptions, 'method' | 'body'>): Promise<T>;
|
|
40
|
+
put<T>(endpoint: string, body?: unknown, options?: Omit<ApiRequestOptions, 'method' | 'body'>): Promise<T>;
|
|
41
|
+
patch<T>(endpoint: string, body?: unknown, options?: Omit<ApiRequestOptions, 'method' | 'body'>): Promise<T>;
|
|
42
|
+
delete<T>(endpoint: string, options?: Omit<ApiRequestOptions, 'method' | 'body'>): Promise<T>;
|
|
43
|
+
/**
|
|
44
|
+
* Execute a tenant-defined logic function by name via the logic service.
|
|
45
|
+
* This is NOT the gateway RPC dispatch — use `dispatch()` for Callable operations.
|
|
46
|
+
*/
|
|
47
|
+
call<T>(functionName: string, data?: unknown): Promise<T>;
|
|
48
|
+
/**
|
|
49
|
+
* Invoke a platform Callable operation through the gateway RPC dispatch route
|
|
50
|
+
* (`POST /api/v<version>/call/:operation`). The operation key is the deployed
|
|
51
|
+
* Callable name (`<domain>-<name>` for namespaced groups, bare name for flat
|
|
52
|
+
* exports). The gateway expects the payload under a `data` envelope.
|
|
53
|
+
*/
|
|
54
|
+
dispatch<T>(operation: string, payload?: unknown): Promise<T>;
|
|
55
|
+
/**
|
|
56
|
+
* Get the version-qualified base URL for direct API calls (e.g. streaming),
|
|
57
|
+
* including the `/api/<version>` segment.
|
|
58
|
+
*/
|
|
59
|
+
getBaseUrl(): string;
|
|
60
|
+
/**
|
|
61
|
+
* Get auth headers for direct API calls (e.g., streaming)
|
|
62
|
+
*/
|
|
63
|
+
getAuthHeaders(): Record<string, string>;
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
interface MAKEMINDSettlementConfig extends MAKEMINDConfig {
|
|
67
|
+
apiClient: ApiClient;
|
|
68
|
+
tenantId: () => string | null;
|
|
69
|
+
}
|
|
70
|
+
type SubscriptionStatus = 'active' | 'trialing' | 'past_due' | 'paused' | 'cancelled' | 'expired';
|
|
71
|
+
type BillingCycle = 'daily' | 'weekly' | 'monthly' | 'yearly' | 'oneTime';
|
|
72
|
+
interface Subscription {
|
|
73
|
+
id: string;
|
|
74
|
+
tenantId: string;
|
|
75
|
+
planId: string;
|
|
76
|
+
planName: string;
|
|
77
|
+
status: SubscriptionStatus;
|
|
78
|
+
billingCycle: BillingCycle;
|
|
79
|
+
currentPeriodStart: Date;
|
|
80
|
+
currentPeriodEnd: Date;
|
|
81
|
+
cancelAtPeriodEnd: boolean;
|
|
82
|
+
canceledAt?: Date;
|
|
83
|
+
pausedAt?: Date;
|
|
84
|
+
pauseUntil?: Date;
|
|
85
|
+
trialEnd?: Date;
|
|
86
|
+
discount?: {
|
|
87
|
+
couponCode: string;
|
|
88
|
+
percentOff?: number;
|
|
89
|
+
amountOff?: number;
|
|
90
|
+
expiresAt?: Date;
|
|
91
|
+
};
|
|
92
|
+
createdAt: Date;
|
|
93
|
+
updatedAt: Date;
|
|
94
|
+
}
|
|
95
|
+
interface SubscribeOptions {
|
|
96
|
+
planId: string;
|
|
97
|
+
billingCycle?: BillingCycle;
|
|
98
|
+
paymentMethodId?: string;
|
|
99
|
+
couponCode?: string;
|
|
100
|
+
startImmediately?: boolean;
|
|
101
|
+
trialDays?: number;
|
|
102
|
+
}
|
|
103
|
+
interface UpdateSubscriptionOptions {
|
|
104
|
+
planId?: string;
|
|
105
|
+
billingCycle?: BillingCycle;
|
|
106
|
+
prorate?: boolean;
|
|
107
|
+
}
|
|
108
|
+
interface CancelSubscriptionOptions {
|
|
109
|
+
reason?: string;
|
|
110
|
+
/** When false, cancels immediately. When true (default), cancels at period end. */
|
|
111
|
+
cancelAtPeriodEnd?: boolean;
|
|
112
|
+
}
|
|
113
|
+
interface PauseSubscriptionOptions {
|
|
114
|
+
reason?: string;
|
|
115
|
+
}
|
|
116
|
+
interface SubscriptionHistoryEntry {
|
|
117
|
+
id: string;
|
|
118
|
+
action: 'created' | 'updated' | 'canceled' | 'paused' | 'resumed' | 'reactivated';
|
|
119
|
+
previousPlanId?: string;
|
|
120
|
+
newPlanId?: string;
|
|
121
|
+
previousStatus?: SubscriptionStatus;
|
|
122
|
+
newStatus?: SubscriptionStatus;
|
|
123
|
+
reason?: string;
|
|
124
|
+
metadata?: Record<string, unknown>;
|
|
125
|
+
createdAt: Date;
|
|
126
|
+
}
|
|
127
|
+
interface SubscriptionChangePreview {
|
|
128
|
+
currentPlan: {
|
|
129
|
+
id: string;
|
|
130
|
+
name: string;
|
|
131
|
+
price: number;
|
|
132
|
+
};
|
|
133
|
+
newPlan: {
|
|
134
|
+
id: string;
|
|
135
|
+
name: string;
|
|
136
|
+
price: number;
|
|
137
|
+
};
|
|
138
|
+
proratedCredit: number;
|
|
139
|
+
proratedCharge: number;
|
|
140
|
+
immediateCharge: number;
|
|
141
|
+
nextBillingAmount: number;
|
|
142
|
+
nextBillingDate: Date;
|
|
143
|
+
}
|
|
144
|
+
type PaymentProvider = 'stripe' | 'paypal' | 'toss' | 'kakaoPay' | 'lemonSqueezy' | 'paddle' | 'apple' | 'google' | 'manual';
|
|
145
|
+
interface AddPaymentMethodData {
|
|
146
|
+
provider: PaymentProvider;
|
|
147
|
+
stripe?: {
|
|
148
|
+
customerId: string;
|
|
149
|
+
accountId: string;
|
|
150
|
+
};
|
|
151
|
+
manual?: {
|
|
152
|
+
externalRef: string;
|
|
153
|
+
label?: string;
|
|
154
|
+
metadata?: Record<string, unknown>;
|
|
155
|
+
};
|
|
156
|
+
toss?: {
|
|
157
|
+
customerKey: string;
|
|
158
|
+
authKey: string;
|
|
159
|
+
};
|
|
160
|
+
kakaoPay?: {
|
|
161
|
+
pgToken: string;
|
|
162
|
+
tid: string;
|
|
163
|
+
partnerUserId: string;
|
|
164
|
+
};
|
|
165
|
+
}
|
|
166
|
+
type AddPaymentMethodResponse = {
|
|
167
|
+
kind: 'stripeSetupIntent';
|
|
168
|
+
clientSecret: string;
|
|
169
|
+
setupIntentId: string;
|
|
170
|
+
customerId: string;
|
|
171
|
+
} | {
|
|
172
|
+
kind: 'redirect';
|
|
173
|
+
url: string;
|
|
174
|
+
provider: PaymentProvider;
|
|
175
|
+
} | {
|
|
176
|
+
kind: 'billingKey';
|
|
177
|
+
paymentAccountId: string;
|
|
178
|
+
provider: PaymentProvider;
|
|
179
|
+
} | {
|
|
180
|
+
kind: 'manualCreated';
|
|
181
|
+
paymentAccountId: string;
|
|
182
|
+
} | {
|
|
183
|
+
kind: 'inAppPurchase';
|
|
184
|
+
provider: 'apple' | 'google';
|
|
185
|
+
message: string;
|
|
186
|
+
};
|
|
187
|
+
declare class MAKEMINDSettlement {
|
|
188
|
+
private apiClient;
|
|
189
|
+
private getTenantId;
|
|
190
|
+
constructor(config: MAKEMINDSettlementConfig);
|
|
191
|
+
private get tenantId();
|
|
192
|
+
recordUsage(options: UsageEventOptions): Promise<void>;
|
|
193
|
+
/**
|
|
194
|
+
* Record a sale and distribute it to n recipients in one atomic posting.
|
|
195
|
+
*
|
|
196
|
+
* The revenue leg and every share leg commit together or not at all. Do not
|
|
197
|
+
* emulate this by recording the sale and then each share separately — that
|
|
198
|
+
* makes every partial-failure combination yours to recover, and a
|
|
199
|
+
* half-distributed sale cannot be repaired from outside the ledger.
|
|
200
|
+
*
|
|
201
|
+
* The split rule is the caller's: send the recipients and amounts you
|
|
202
|
+
* computed. Each cut is either a percentage or a fixed amount, and the two
|
|
203
|
+
* may be mixed; the combined claim may not exceed the sale. Recipients are settlement accounts, so the same call serves an
|
|
204
|
+
* End User seller, another party in the tenant, or a platform cut.
|
|
205
|
+
*
|
|
206
|
+
* Shares are floored to the currency's minor unit; the remainder stays with
|
|
207
|
+
* the receiving party. A share too small to express posts no leg and comes
|
|
208
|
+
* back as `0` / `null`.
|
|
209
|
+
*/
|
|
210
|
+
recordSaleWithShares(options: {
|
|
211
|
+
provider: string;
|
|
212
|
+
providerTransactionId: string;
|
|
213
|
+
amount: number;
|
|
214
|
+
currency: string;
|
|
215
|
+
referenceType?: string;
|
|
216
|
+
referenceId?: string;
|
|
217
|
+
idempotencyKey?: string;
|
|
218
|
+
shares?: Array<{
|
|
219
|
+
toAccountId: string;
|
|
220
|
+
/** A proportional cut, `(0, 100]`. Exactly one of this or shareAmount. */
|
|
221
|
+
sharePercent?: number;
|
|
222
|
+
/** A fixed amount in the sale's currency. Does not scale with the sale. */
|
|
223
|
+
shareAmount?: number;
|
|
224
|
+
description?: string;
|
|
225
|
+
metadata?: Record<string, unknown>;
|
|
226
|
+
}>;
|
|
227
|
+
}): Promise<{
|
|
228
|
+
transactionId: string;
|
|
229
|
+
shareTransactionIds: (string | null)[];
|
|
230
|
+
shareAmounts: number[];
|
|
231
|
+
residue: number;
|
|
232
|
+
idempotent: boolean;
|
|
233
|
+
}>;
|
|
234
|
+
/**
|
|
235
|
+
* Reverse a split sale, clawing back each recipient's share in the same
|
|
236
|
+
* posting. Partial refunds claw back proportionally (floored, so a claw-back
|
|
237
|
+
* never exceeds what the recipient received; the difference is yours).
|
|
238
|
+
*
|
|
239
|
+
* Use this rather than a plain refund for anything recorded with
|
|
240
|
+
* `recordSaleWithShares` — otherwise the buyer is refunded while the shares
|
|
241
|
+
* stay paid out, and the ledger is short by exactly the shares.
|
|
242
|
+
*/
|
|
243
|
+
reverseSaleWithShares(options: {
|
|
244
|
+
transactionId: string;
|
|
245
|
+
amount?: number;
|
|
246
|
+
reason?: string;
|
|
247
|
+
idempotencyKey: string;
|
|
248
|
+
}): Promise<{
|
|
249
|
+
refundTransactionId: string;
|
|
250
|
+
shareReversalIds: string[];
|
|
251
|
+
shareReversalAmounts: number[];
|
|
252
|
+
tenantBorne: number;
|
|
253
|
+
idempotent: boolean;
|
|
254
|
+
}>;
|
|
255
|
+
getUsageStats(options?: {
|
|
256
|
+
startDate?: string;
|
|
257
|
+
endDate?: string;
|
|
258
|
+
metric?: string;
|
|
259
|
+
}): Promise<UsageStats>;
|
|
260
|
+
getBillingSummary(): Promise<BillingSummary>;
|
|
261
|
+
getQuotaStatus(_resourceType?: string): Promise<{
|
|
262
|
+
quotas: Array<{
|
|
263
|
+
resource: string;
|
|
264
|
+
limit: number;
|
|
265
|
+
used: number;
|
|
266
|
+
remaining: number;
|
|
267
|
+
usagePercent: number;
|
|
268
|
+
}>;
|
|
269
|
+
}>;
|
|
270
|
+
listInvoices(options?: {
|
|
271
|
+
status?: 'draft' | 'pending' | 'paid' | 'overdue' | 'cancelled' | 'refunded';
|
|
272
|
+
limit?: number;
|
|
273
|
+
}): Promise<Invoice[]>;
|
|
274
|
+
getInvoice(invoiceId: string): Promise<Invoice>;
|
|
275
|
+
downloadInvoice(_invoiceId: string): Promise<{
|
|
276
|
+
url: string;
|
|
277
|
+
expiresIn: number;
|
|
278
|
+
}>;
|
|
279
|
+
getCurrentPlan(): Promise<{
|
|
280
|
+
id: string;
|
|
281
|
+
name: string;
|
|
282
|
+
features: string[];
|
|
283
|
+
limits: Record<string, number>;
|
|
284
|
+
}>;
|
|
285
|
+
listPlans(): Promise<Array<{
|
|
286
|
+
id: string;
|
|
287
|
+
name: string;
|
|
288
|
+
description: string;
|
|
289
|
+
price: number;
|
|
290
|
+
currency: string;
|
|
291
|
+
features: string[];
|
|
292
|
+
limits: Record<string, number>;
|
|
293
|
+
}>>;
|
|
294
|
+
changePlan(planId: string): Promise<void>;
|
|
295
|
+
/**
|
|
296
|
+
* Get current subscription details
|
|
297
|
+
*/
|
|
298
|
+
getCurrentSubscription(): Promise<Subscription | null>;
|
|
299
|
+
/**
|
|
300
|
+
* Subscribe to a plan
|
|
301
|
+
*/
|
|
302
|
+
subscribe(options: SubscribeOptions): Promise<Subscription>;
|
|
303
|
+
/**
|
|
304
|
+
* Update current subscription (e.g., change plan, billing cycle).
|
|
305
|
+
* The backend has no in-place PATCH; a plan update is implemented by creating
|
|
306
|
+
* a new subscription (which cancels the current one server-side). billingCycle
|
|
307
|
+
* and prorate are forwarded as metadata but only planId is acted upon today.
|
|
308
|
+
*/
|
|
309
|
+
updateSubscription(options: UpdateSubscriptionOptions): Promise<Subscription>;
|
|
310
|
+
/**
|
|
311
|
+
* Cancel current subscription.
|
|
312
|
+
* Resolves the active subscriptionId first, then dispatches to
|
|
313
|
+
* settlement-cancelSubscription. Backend field is cancelImmediately (not
|
|
314
|
+
* cancelAtPeriodEnd); meaning is inverted — SDK default cancelAtPeriodEnd=true
|
|
315
|
+
* maps to cancelImmediately=false.
|
|
316
|
+
*/
|
|
317
|
+
cancelSubscription(options?: CancelSubscriptionOptions): Promise<void>;
|
|
318
|
+
/**
|
|
319
|
+
* Pause subscription (if supported by plan).
|
|
320
|
+
* Backend accepts only { subscriptionId }; pauseUntil is not supported yet.
|
|
321
|
+
*/
|
|
322
|
+
pauseSubscription(_options?: PauseSubscriptionOptions): Promise<void>;
|
|
323
|
+
/**
|
|
324
|
+
* Resume a paused subscription.
|
|
325
|
+
*/
|
|
326
|
+
resumeSubscription(): Promise<Subscription>;
|
|
327
|
+
/**
|
|
328
|
+
* Reactivate a canceled subscription (before period end).
|
|
329
|
+
* Routes to settlement-resumeSubscription: fetches the most-recently-canceled
|
|
330
|
+
* subscription and resumes it. This is semantically equivalent for the
|
|
331
|
+
* cancel-at-period-end case where the subscription is still within its period.
|
|
332
|
+
*/
|
|
333
|
+
reactivateSubscription(): Promise<Subscription>;
|
|
334
|
+
/**
|
|
335
|
+
* Get subscription history.
|
|
336
|
+
* TODO(gateway): no dedicated subscription history table/function exists in the
|
|
337
|
+
* backend. Requires a new settlement_subscription_events table or equivalent
|
|
338
|
+
* audit trail (scope: schema + backfill trigger + query function).
|
|
339
|
+
*/
|
|
340
|
+
getSubscriptionHistory(_options?: {
|
|
341
|
+
limit?: number;
|
|
342
|
+
offset?: number;
|
|
343
|
+
}): Promise<SubscriptionHistoryEntry[]>;
|
|
344
|
+
/**
|
|
345
|
+
* Preview subscription change (get prorated amounts).
|
|
346
|
+
* TODO(gateway): proration calculation requires billing period overlap logic
|
|
347
|
+
* that is not yet implemented in the backend (scope: period credits, immediate
|
|
348
|
+
* charge delta, next-billing projection — needs a new onCall or REST endpoint).
|
|
349
|
+
*/
|
|
350
|
+
previewSubscriptionChange(_newPlanId: string): Promise<SubscriptionChangePreview>;
|
|
351
|
+
/**
|
|
352
|
+
* Apply a coupon to current subscription.
|
|
353
|
+
* TODO(gateway): coupon engine (validation, redemption ledger, discount
|
|
354
|
+
* application) is not yet implemented (scope: coupon collection + validation
|
|
355
|
+
* function + subscription discount field update).
|
|
356
|
+
*/
|
|
357
|
+
applyCoupon(_couponCode: string): Promise<{
|
|
358
|
+
success: boolean;
|
|
359
|
+
discount: number;
|
|
360
|
+
message: string;
|
|
361
|
+
}>;
|
|
362
|
+
getPaymentMethods(): Promise<Array<{
|
|
363
|
+
id: string;
|
|
364
|
+
type: 'card' | 'bankAccount';
|
|
365
|
+
last4: string;
|
|
366
|
+
isDefault: boolean;
|
|
367
|
+
}>>;
|
|
368
|
+
addPaymentMethod(data: AddPaymentMethodData): Promise<AddPaymentMethodResponse>;
|
|
369
|
+
removePaymentMethod(paymentAccountId: string): Promise<void>;
|
|
370
|
+
setDefaultPaymentMethod(paymentAccountId: string): Promise<void>;
|
|
371
|
+
recordProductCreation(productId: string): Promise<void>;
|
|
372
|
+
recordDocumentUpload(documentId: string, fileSizeMb: number): Promise<void>;
|
|
373
|
+
recordEcoSubmission(ecoId: string): Promise<void>;
|
|
374
|
+
recordMarketplaceBid(bidId: string, requestId: string): Promise<void>;
|
|
375
|
+
recordParticipantAdded(productId: string, participantTenantId: string): Promise<void>;
|
|
376
|
+
}
|
|
377
|
+
|
|
378
|
+
interface MAKEMINDConfig {
|
|
379
|
+
applicationId: string;
|
|
380
|
+
environment?: 'development' | 'staging' | 'production';
|
|
381
|
+
}
|
|
382
|
+
interface AuthUser {
|
|
383
|
+
uid: string;
|
|
384
|
+
email: string | null;
|
|
385
|
+
displayName: string | null;
|
|
386
|
+
photoURL: string | null;
|
|
387
|
+
tenantId: string;
|
|
388
|
+
roles: string[];
|
|
389
|
+
scopes: string[];
|
|
390
|
+
}
|
|
391
|
+
interface TenantClaims {
|
|
392
|
+
id: string;
|
|
393
|
+
roles: string[];
|
|
394
|
+
scopes: string[];
|
|
395
|
+
}
|
|
396
|
+
interface AuthStateCallback {
|
|
397
|
+
(user: AuthUser | null): void;
|
|
398
|
+
}
|
|
399
|
+
interface Tenant {
|
|
400
|
+
id: string;
|
|
401
|
+
name: string;
|
|
402
|
+
plan: string;
|
|
403
|
+
status: 'active' | 'suspended' | 'deleted';
|
|
404
|
+
settings?: Record<string, unknown>;
|
|
405
|
+
createdAt?: Date;
|
|
406
|
+
updatedAt?: Date;
|
|
407
|
+
}
|
|
408
|
+
interface TenantMember {
|
|
409
|
+
id: string;
|
|
410
|
+
userId: string;
|
|
411
|
+
tenantId: string;
|
|
412
|
+
role: string;
|
|
413
|
+
scopes: string[];
|
|
414
|
+
status: 'active' | 'invited' | 'suspended';
|
|
415
|
+
joinedAt?: Date;
|
|
416
|
+
}
|
|
417
|
+
interface Workspace {
|
|
418
|
+
id: string;
|
|
419
|
+
name: string;
|
|
420
|
+
description?: string;
|
|
421
|
+
parentId?: string;
|
|
422
|
+
createdAt?: Date;
|
|
423
|
+
}
|
|
424
|
+
interface QueryCondition {
|
|
425
|
+
field: string;
|
|
426
|
+
op: '==' | '!=' | '<' | '<=' | '>' | '>=' | 'in' | 'not-in' | 'array-contains' | 'array-contains-any';
|
|
427
|
+
value: unknown;
|
|
428
|
+
}
|
|
429
|
+
interface OrderBy {
|
|
430
|
+
field: string;
|
|
431
|
+
direction: 'asc' | 'desc';
|
|
432
|
+
}
|
|
433
|
+
interface QueryOptions {
|
|
434
|
+
collection: string;
|
|
435
|
+
where?: QueryCondition[];
|
|
436
|
+
orderBy?: OrderBy[];
|
|
437
|
+
limit?: number;
|
|
438
|
+
startAfter?: string;
|
|
439
|
+
}
|
|
440
|
+
interface QueryResult<T> {
|
|
441
|
+
data: T[];
|
|
442
|
+
metadata?: {
|
|
443
|
+
hasMore: boolean;
|
|
444
|
+
lastDocId?: string;
|
|
445
|
+
totalCount?: number;
|
|
446
|
+
};
|
|
447
|
+
}
|
|
448
|
+
interface DocumentResult<T> {
|
|
449
|
+
data: T;
|
|
450
|
+
id: string;
|
|
451
|
+
}
|
|
452
|
+
interface CreateOptions {
|
|
453
|
+
collection: string;
|
|
454
|
+
data: Record<string, unknown>;
|
|
455
|
+
documentId?: string;
|
|
456
|
+
}
|
|
457
|
+
interface UpdateOptions {
|
|
458
|
+
collection: string;
|
|
459
|
+
documentId: string;
|
|
460
|
+
data: Record<string, unknown>;
|
|
461
|
+
}
|
|
462
|
+
interface DeleteOptions {
|
|
463
|
+
collection: string;
|
|
464
|
+
documentId: string;
|
|
465
|
+
}
|
|
466
|
+
interface GetOptions {
|
|
467
|
+
collection: string;
|
|
468
|
+
documentId: string;
|
|
469
|
+
}
|
|
470
|
+
type SnapshotCallback<T> = (data: T | null) => void;
|
|
471
|
+
type CollectionSnapshotCallback<T> = (data: T[]) => void;
|
|
472
|
+
type Unsubscribe = () => void;
|
|
473
|
+
interface LogicCallResult {
|
|
474
|
+
executionId: string;
|
|
475
|
+
status: 'completed' | 'running' | 'failed';
|
|
476
|
+
output?: unknown;
|
|
477
|
+
error?: {
|
|
478
|
+
code: string;
|
|
479
|
+
message: string;
|
|
480
|
+
};
|
|
481
|
+
}
|
|
482
|
+
interface WorkflowTransitionOptions {
|
|
483
|
+
workflowName: string;
|
|
484
|
+
documentId: string;
|
|
485
|
+
action: string;
|
|
486
|
+
data?: Record<string, unknown>;
|
|
487
|
+
}
|
|
488
|
+
interface SendMessageOptions {
|
|
489
|
+
template: string;
|
|
490
|
+
recipients: string[];
|
|
491
|
+
data: Record<string, unknown>;
|
|
492
|
+
channels?: ('push' | 'email' | 'sms')[];
|
|
493
|
+
}
|
|
494
|
+
interface Notification {
|
|
495
|
+
id: string;
|
|
496
|
+
title: string;
|
|
497
|
+
body: string;
|
|
498
|
+
data?: Record<string, unknown>;
|
|
499
|
+
read: boolean;
|
|
500
|
+
createdAt: Date;
|
|
501
|
+
}
|
|
502
|
+
interface UsageEventOptions {
|
|
503
|
+
eventType: string;
|
|
504
|
+
resourceId: string;
|
|
505
|
+
quantity?: number;
|
|
506
|
+
metadata?: Record<string, unknown>;
|
|
507
|
+
}
|
|
508
|
+
interface UsageStats {
|
|
509
|
+
period: string;
|
|
510
|
+
events: Record<string, number>;
|
|
511
|
+
totalUsage: number;
|
|
512
|
+
}
|
|
513
|
+
interface BillingSummary {
|
|
514
|
+
currentBalance: number;
|
|
515
|
+
pendingCharges: number;
|
|
516
|
+
currency: string;
|
|
517
|
+
plan: string;
|
|
518
|
+
}
|
|
519
|
+
interface Invoice {
|
|
520
|
+
id: string;
|
|
521
|
+
amount: number;
|
|
522
|
+
currency: string;
|
|
523
|
+
status: 'draft' | 'pending' | 'paid' | 'overdue' | 'cancelled' | 'refunded';
|
|
524
|
+
periodStart: Date;
|
|
525
|
+
periodEnd: Date;
|
|
526
|
+
createdAt: Date;
|
|
527
|
+
}
|
|
528
|
+
interface PlatformErrorDetails {
|
|
529
|
+
code: string;
|
|
530
|
+
message: string;
|
|
531
|
+
details?: Record<string, unknown>;
|
|
532
|
+
}
|
|
533
|
+
|
|
534
|
+
interface MAKEMINDAuthConfig extends MAKEMINDConfig {
|
|
535
|
+
apiClient: ApiClient;
|
|
536
|
+
onAuthStateChange: (user: AuthUser | null) => void;
|
|
537
|
+
setAuthToken: (token: string | null) => void;
|
|
538
|
+
}
|
|
539
|
+
interface TenantMembership {
|
|
540
|
+
tenantId: string;
|
|
541
|
+
tenantName: string;
|
|
542
|
+
tenantDisplayName: string;
|
|
543
|
+
roles: string[];
|
|
544
|
+
status: string;
|
|
545
|
+
}
|
|
546
|
+
declare class MAKEMINDAuth {
|
|
547
|
+
private apiClient;
|
|
548
|
+
private applicationId;
|
|
549
|
+
private onAuthStateChange;
|
|
550
|
+
private setAuthToken;
|
|
551
|
+
private _currentUser;
|
|
552
|
+
private _memberships;
|
|
553
|
+
private refreshToken;
|
|
554
|
+
private authStateCallbacks;
|
|
555
|
+
constructor(config: MAKEMINDAuthConfig);
|
|
556
|
+
private restoreSession;
|
|
557
|
+
private persistSession;
|
|
558
|
+
private clearStoredSession;
|
|
559
|
+
get currentUser(): AuthUser | null;
|
|
560
|
+
get memberships(): TenantMembership[];
|
|
561
|
+
/**
|
|
562
|
+
* Set the session directly from an externally-obtained token — e.g. a Firebase
|
|
563
|
+
* ID token from Google sign-in, which the gateway accepts as a Bearer. Mirrors
|
|
564
|
+
* the post-authentication state update of signInWithEmail (set token, persist
|
|
565
|
+
* to localStorage, notify auth-state listeners) without a /auth/signin
|
|
566
|
+
* round-trip. Also used by the console's token-refresh bridge to swap in a
|
|
567
|
+
* freshly-refreshed Firebase token. Existing memberships are preserved when
|
|
568
|
+
* `memberships` is omitted.
|
|
569
|
+
*/
|
|
570
|
+
setSession(user: AuthUser, token: string, refreshToken: string, memberships?: TenantMembership[]): void;
|
|
571
|
+
/**
|
|
572
|
+
* Load the caller's tenant memberships into the session.
|
|
573
|
+
*
|
|
574
|
+
* `signInWithEmail` gets them in its response, but a session established from
|
|
575
|
+
* an external credential (a Firebase ID token from a Google popup) has no
|
|
576
|
+
* such response — it arrives with claims only. Claims carry the *current*
|
|
577
|
+
* tenant, not the list, and a platform admin's claims carry no tenant roles
|
|
578
|
+
* at all, so a console that gates its navigation on `admin`/`owner` shows an
|
|
579
|
+
* almost empty menu until this runs.
|
|
580
|
+
*
|
|
581
|
+
* @return {Promise<TenantMembership[]>} The loaded memberships.
|
|
582
|
+
*/
|
|
583
|
+
loadMemberships(): Promise<TenantMembership[]>;
|
|
584
|
+
signInWithEmail(email: string, password: string): Promise<AuthUser>;
|
|
585
|
+
signInWithEmailAndPassword(email: string, password: string): Promise<AuthUser>;
|
|
586
|
+
signUp(email: string, password: string, options?: {
|
|
587
|
+
displayName?: string;
|
|
588
|
+
phoneNumber?: string;
|
|
589
|
+
}): Promise<AuthUser>;
|
|
590
|
+
signOut(): Promise<void>;
|
|
591
|
+
sendPasswordResetEmail(email: string): Promise<void>;
|
|
592
|
+
onAuthStateChanged(callback: AuthStateCallback): () => void;
|
|
593
|
+
private notifyAuthStateCallbacks;
|
|
594
|
+
refreshAuthToken(): Promise<void>;
|
|
595
|
+
switchTenant(tenantId: string): Promise<AuthUser>;
|
|
596
|
+
getUserMemberships(): Promise<{
|
|
597
|
+
tenantId: string;
|
|
598
|
+
tenantName: string;
|
|
599
|
+
roles: string[];
|
|
600
|
+
status: string;
|
|
601
|
+
}[]>;
|
|
602
|
+
hasScope(scope: string): boolean;
|
|
603
|
+
hasRole(role: string): boolean;
|
|
604
|
+
hasAnyRole(roles: string[]): boolean;
|
|
605
|
+
hasAllScopes(scopes: string[]): boolean;
|
|
606
|
+
/**
|
|
607
|
+
* Get the current ID token for use with external services
|
|
608
|
+
*/
|
|
609
|
+
getIdToken(forceRefresh?: boolean): Promise<string | null>;
|
|
610
|
+
/**
|
|
611
|
+
* Update the current user's password.
|
|
612
|
+
* Backend dispatch 'updatePassword' → data { currentPassword, newPassword }.
|
|
613
|
+
*/
|
|
614
|
+
updatePassword(currentPassword: string, newPassword: string): Promise<void>;
|
|
615
|
+
/**
|
|
616
|
+
* Send email verification.
|
|
617
|
+
* Backend dispatch 'resendVerificationEmail' — uid resolved from auth context, no payload needed.
|
|
618
|
+
*/
|
|
619
|
+
sendEmailVerification(): Promise<void>;
|
|
620
|
+
/**
|
|
621
|
+
* Verify email with code
|
|
622
|
+
*/
|
|
623
|
+
verifyEmail(code: string): Promise<void>;
|
|
624
|
+
/**
|
|
625
|
+
* Confirm password reset with code
|
|
626
|
+
*/
|
|
627
|
+
confirmPasswordReset(code: string, newPassword: string): Promise<void>;
|
|
628
|
+
/**
|
|
629
|
+
* OAuth redirect-based sign-in is NOT supported by this backend.
|
|
630
|
+
* The backend has no /oauth/initiate or /oauth/callback routes.
|
|
631
|
+
* Use signInWithOAuthToken() with a provider-issued ID token instead,
|
|
632
|
+
* or use the Firebase Client SDK directly for OAuth redirect flows.
|
|
633
|
+
*/
|
|
634
|
+
signInWithOAuth(_provider: 'google' | 'apple' | 'github' | 'microsoft'): Promise<{
|
|
635
|
+
redirectUrl: string;
|
|
636
|
+
}>;
|
|
637
|
+
/**
|
|
638
|
+
* OAuth redirect callback handling is NOT supported by this backend.
|
|
639
|
+
* Use signInWithOAuthToken() with a provider-issued ID token instead,
|
|
640
|
+
* or use the Firebase Client SDK directly for OAuth redirect flows.
|
|
641
|
+
*/
|
|
642
|
+
handleOAuthCallback(_code: string, _state: string): Promise<AuthUser>;
|
|
643
|
+
/**
|
|
644
|
+
* Sign in with OAuth ID token directly (for native apps)
|
|
645
|
+
* Use this when you have already obtained the ID token from the OAuth provider
|
|
646
|
+
*/
|
|
647
|
+
signInWithOAuthToken(provider: 'google' | 'apple' | 'github' | 'microsoft', idToken: string): Promise<AuthUser>;
|
|
648
|
+
/**
|
|
649
|
+
* OAuth redirect-based account linking is NOT supported by this backend.
|
|
650
|
+
* The backend has no /oauth/link/initiate route.
|
|
651
|
+
* Use the Firebase Client SDK linkWithRedirect() or linkWithPopup() instead.
|
|
652
|
+
*/
|
|
653
|
+
linkWithOAuth(_provider: 'google' | 'apple' | 'github' | 'microsoft'): Promise<{
|
|
654
|
+
redirectUrl: string;
|
|
655
|
+
}>;
|
|
656
|
+
/**
|
|
657
|
+
* OAuth redirect link callback is NOT supported by this backend.
|
|
658
|
+
* The backend has no /oauth/link/callback route.
|
|
659
|
+
* Use the Firebase Client SDK for OAuth redirect link flows.
|
|
660
|
+
*/
|
|
661
|
+
handleOAuthLinkCallback(_code: string, _state: string): Promise<void>;
|
|
662
|
+
/**
|
|
663
|
+
* Unlink OAuth provider from current account
|
|
664
|
+
*/
|
|
665
|
+
unlinkOAuth(provider: 'google' | 'apple' | 'github' | 'microsoft'): Promise<void>;
|
|
666
|
+
/**
|
|
667
|
+
* Get linked OAuth providers for current user
|
|
668
|
+
*/
|
|
669
|
+
getLinkedProviders(): Promise<string[]>;
|
|
670
|
+
updateCurrentUser(userData: {
|
|
671
|
+
uid: string;
|
|
672
|
+
email: string;
|
|
673
|
+
displayName?: string | null;
|
|
674
|
+
tenantId: string;
|
|
675
|
+
roles: string[];
|
|
676
|
+
scopes: string[];
|
|
677
|
+
}, membership?: TenantMembership): void;
|
|
678
|
+
}
|
|
679
|
+
|
|
680
|
+
interface MAKEMINDDataConfig extends MAKEMINDConfig {
|
|
681
|
+
apiClient: ApiClient;
|
|
682
|
+
tenantId: () => string | null;
|
|
683
|
+
}
|
|
684
|
+
declare class MAKEMINDData {
|
|
685
|
+
private apiClient;
|
|
686
|
+
private applicationId;
|
|
687
|
+
private getTenantId;
|
|
688
|
+
private subscriptions;
|
|
689
|
+
constructor(config: MAKEMINDDataConfig);
|
|
690
|
+
private get tenantId();
|
|
691
|
+
query<T = Record<string, unknown>>(options: QueryOptions): Promise<QueryResult<T>>;
|
|
692
|
+
get<T = Record<string, unknown>>(options: GetOptions): Promise<DocumentResult<T> | null>;
|
|
693
|
+
create<T = Record<string, unknown>>(options: CreateOptions): Promise<DocumentResult<T>>;
|
|
694
|
+
update(options: UpdateOptions): Promise<void>;
|
|
695
|
+
delete(options: DeleteOptions): Promise<void>;
|
|
696
|
+
onSnapshot<T = Record<string, unknown>>(options: GetOptions, callback: SnapshotCallback<T>): Unsubscribe;
|
|
697
|
+
onCollectionSnapshot<T = Record<string, unknown>>(options: QueryOptions, callback: CollectionSnapshotCallback<T>): Unsubscribe;
|
|
698
|
+
private createSubscription;
|
|
699
|
+
private createCollectionSubscription;
|
|
700
|
+
private pollForUpdates;
|
|
701
|
+
private closeSubscription;
|
|
702
|
+
collectionGroupQuery<T = Record<string, unknown>>(_options: Omit<QueryOptions, 'collection'> & {
|
|
703
|
+
collection: string;
|
|
704
|
+
}): Promise<QueryResult<T>>;
|
|
705
|
+
queryTenant<T = Record<string, unknown>>(collectionName: string, additionalConditions?: QueryCondition[], orderByOptions?: OrderBy[], limitCount?: number): Promise<QueryResult<T>>;
|
|
706
|
+
batchCreate<T = Record<string, unknown>>(collection: string, documents: Array<{
|
|
707
|
+
data: Record<string, unknown>;
|
|
708
|
+
documentId?: string;
|
|
709
|
+
}>): Promise<Array<DocumentResult<T>>>;
|
|
710
|
+
batchUpdate(collection: string, updates: Array<{
|
|
711
|
+
documentId: string;
|
|
712
|
+
data: Record<string, unknown>;
|
|
713
|
+
}>): Promise<void>;
|
|
714
|
+
batchDelete(collection: string, documentIds: string[]): Promise<void>;
|
|
715
|
+
exportCollection(options: {
|
|
716
|
+
collection: string;
|
|
717
|
+
format?: 'json' | 'csv';
|
|
718
|
+
filter?: Record<string, unknown>;
|
|
719
|
+
}): Promise<{
|
|
720
|
+
jobId: string;
|
|
721
|
+
status: string;
|
|
722
|
+
}>;
|
|
723
|
+
importCollection(options: {
|
|
724
|
+
collection: string;
|
|
725
|
+
sourcePath: string;
|
|
726
|
+
format?: 'json' | 'csv';
|
|
727
|
+
upsert?: boolean;
|
|
728
|
+
}): Promise<{
|
|
729
|
+
jobId: string;
|
|
730
|
+
status: string;
|
|
731
|
+
}>;
|
|
732
|
+
getExportStatus(jobId: string): Promise<{
|
|
733
|
+
jobId: string;
|
|
734
|
+
status: 'pending' | 'running' | 'completed' | 'failed';
|
|
735
|
+
documentCount?: number;
|
|
736
|
+
downloadUrl?: string;
|
|
737
|
+
error?: string;
|
|
738
|
+
completedAt?: unknown;
|
|
739
|
+
}>;
|
|
740
|
+
getImportStatus(jobId: string): Promise<{
|
|
741
|
+
jobId: string;
|
|
742
|
+
status: 'pending' | 'validating' | 'running' | 'completed' | 'failed';
|
|
743
|
+
totalRecords?: number;
|
|
744
|
+
processedRecords?: number;
|
|
745
|
+
skippedRecords?: number;
|
|
746
|
+
failedRecords?: number;
|
|
747
|
+
error?: string;
|
|
748
|
+
completedAt?: unknown;
|
|
749
|
+
}>;
|
|
750
|
+
aggregate(options: {
|
|
751
|
+
collection: string;
|
|
752
|
+
filters?: QueryCondition[];
|
|
753
|
+
aggregations: Array<{
|
|
754
|
+
type: 'count' | 'sum' | 'avg' | 'min' | 'max';
|
|
755
|
+
field?: string;
|
|
756
|
+
alias: string;
|
|
757
|
+
}>;
|
|
758
|
+
}): Promise<{
|
|
759
|
+
results: Record<string, unknown>;
|
|
760
|
+
documentCount: number;
|
|
761
|
+
}>;
|
|
762
|
+
search<T = Record<string, unknown>>(options: {
|
|
763
|
+
collection: string;
|
|
764
|
+
query: string;
|
|
765
|
+
fields: string[];
|
|
766
|
+
limit?: number;
|
|
767
|
+
}): Promise<{
|
|
768
|
+
results: Array<T & {
|
|
769
|
+
_score: number;
|
|
770
|
+
}>;
|
|
771
|
+
total: number;
|
|
772
|
+
}>;
|
|
773
|
+
}
|
|
774
|
+
|
|
775
|
+
interface MAKEMINDLogicConfig extends MAKEMINDConfig {
|
|
776
|
+
apiClient: ApiClient;
|
|
777
|
+
tenantId: () => string | null;
|
|
778
|
+
}
|
|
779
|
+
interface FlowDefinition {
|
|
780
|
+
id?: string;
|
|
781
|
+
name: string;
|
|
782
|
+
description: string;
|
|
783
|
+
mode: 'form' | 'code';
|
|
784
|
+
trigger: {
|
|
785
|
+
type: 'event' | 'schedule' | 'manual' | 'webhook' | 'data';
|
|
786
|
+
[key: string]: unknown;
|
|
787
|
+
};
|
|
788
|
+
definition: unknown;
|
|
789
|
+
variables?: Record<string, unknown>;
|
|
790
|
+
}
|
|
791
|
+
/**
|
|
792
|
+
* A row of `GET /logic/flows`, as the gateway actually answers it.
|
|
793
|
+
*
|
|
794
|
+
* This declared six fields while the route returns eighteen, so every consumer
|
|
795
|
+
* that needed `publicExecution` or `mode` cast the row to read them — the
|
|
796
|
+
* portal does exactly that. A type that under-describes a payload does not
|
|
797
|
+
* protect the caller; it just moves the reading of it out of the type system.
|
|
798
|
+
*
|
|
799
|
+
* `status` said `'active'`, which the route never sends: a published flow is
|
|
800
|
+
* stored and returned as `'published'` (logic/service/flows.ts). Consumers
|
|
801
|
+
* translating `'active' -> 'published'` were translating a value that never
|
|
802
|
+
* arrives.
|
|
803
|
+
*/
|
|
804
|
+
interface ListFlowsParams {
|
|
805
|
+
status?: 'draft' | 'published' | 'disabled' | 'archived';
|
|
806
|
+
mode?: 'form' | 'code' | 'hybrid';
|
|
807
|
+
/** Rows per page. The gateway caps this at 100 and defaults to it. */
|
|
808
|
+
limit?: number;
|
|
809
|
+
/** `nextCursor` from a previous page. */
|
|
810
|
+
cursor?: string;
|
|
811
|
+
}
|
|
812
|
+
interface ListFlowsResult {
|
|
813
|
+
flows: FlowListItem[];
|
|
814
|
+
/** True when the server had more rows than this page carries. */
|
|
815
|
+
hasMore: boolean;
|
|
816
|
+
nextCursor?: string;
|
|
817
|
+
}
|
|
818
|
+
interface FlowListItem {
|
|
819
|
+
id: string;
|
|
820
|
+
name: string;
|
|
821
|
+
description: string;
|
|
822
|
+
status: 'draft' | 'published' | 'archived';
|
|
823
|
+
mode?: 'form' | 'code' | 'hybrid';
|
|
824
|
+
trigger?: unknown;
|
|
825
|
+
definition?: unknown;
|
|
826
|
+
variables?: unknown;
|
|
827
|
+
isSubflow?: boolean;
|
|
828
|
+
inputSchema?: unknown;
|
|
829
|
+
outputSchema?: unknown;
|
|
830
|
+
/** Whether the flow may be executed from a published app without a session. */
|
|
831
|
+
publicExecution?: boolean;
|
|
832
|
+
partyInput?: unknown;
|
|
833
|
+
durable?: boolean;
|
|
834
|
+
currentVersion?: number;
|
|
835
|
+
publishedVersion?: number;
|
|
836
|
+
createdAt: Date;
|
|
837
|
+
updatedAt: Date;
|
|
838
|
+
}
|
|
839
|
+
declare class MAKEMINDLogic {
|
|
840
|
+
private apiClient;
|
|
841
|
+
private getTenantId;
|
|
842
|
+
constructor(config: MAKEMINDLogicConfig);
|
|
843
|
+
transition(options: WorkflowTransitionOptions): Promise<LogicCallResult>;
|
|
844
|
+
call(functionName: string, input?: unknown): Promise<LogicCallResult>;
|
|
845
|
+
executeFlow(flowId: string, input?: unknown, options?: {
|
|
846
|
+
idempotencyKey?: string;
|
|
847
|
+
}): Promise<LogicCallResult>;
|
|
848
|
+
getExecution(executionId: string): Promise<{
|
|
849
|
+
id: string;
|
|
850
|
+
flowId: string;
|
|
851
|
+
status: string;
|
|
852
|
+
startedAt: Date;
|
|
853
|
+
completedAt?: Date;
|
|
854
|
+
output?: unknown;
|
|
855
|
+
error?: {
|
|
856
|
+
code: string;
|
|
857
|
+
message: string;
|
|
858
|
+
};
|
|
859
|
+
}>;
|
|
860
|
+
listExecutions(options?: {
|
|
861
|
+
flowId?: string;
|
|
862
|
+
status?: string;
|
|
863
|
+
limit?: number;
|
|
864
|
+
startAfter?: string;
|
|
865
|
+
}): Promise<{
|
|
866
|
+
executions: Array<{
|
|
867
|
+
id: string;
|
|
868
|
+
flowId: string;
|
|
869
|
+
status: string;
|
|
870
|
+
startedAt: Date;
|
|
871
|
+
completedAt?: Date;
|
|
872
|
+
}>;
|
|
873
|
+
nextCursor?: string;
|
|
874
|
+
hasMore: boolean;
|
|
875
|
+
}>;
|
|
876
|
+
sendSignal(executionId: string, signalName: string, payload?: unknown): Promise<{
|
|
877
|
+
success: boolean;
|
|
878
|
+
}>;
|
|
879
|
+
/**
|
|
880
|
+
* Cancel a running workflow execution
|
|
881
|
+
*/
|
|
882
|
+
cancelWorkflow(executionId: string, reason?: string): Promise<{
|
|
883
|
+
success: boolean;
|
|
884
|
+
}>;
|
|
885
|
+
/**
|
|
886
|
+
* Retry a failed workflow execution
|
|
887
|
+
*/
|
|
888
|
+
retryWorkflow(executionId: string): Promise<{
|
|
889
|
+
success: boolean;
|
|
890
|
+
newExecutionId: string;
|
|
891
|
+
}>;
|
|
892
|
+
/**
|
|
893
|
+
* Pause a running workflow execution
|
|
894
|
+
*/
|
|
895
|
+
pauseWorkflow(executionId: string): Promise<{
|
|
896
|
+
success: boolean;
|
|
897
|
+
}>;
|
|
898
|
+
/**
|
|
899
|
+
* Resume a paused workflow execution
|
|
900
|
+
*/
|
|
901
|
+
resumeWorkflow(executionId: string): Promise<{
|
|
902
|
+
success: boolean;
|
|
903
|
+
}>;
|
|
904
|
+
ecoTransition(ecoId: string, action: 'submit' | 'approve' | 'reject' | 'implement' | 'recall', data?: Record<string, unknown>): Promise<LogicCallResult>;
|
|
905
|
+
ncrTransition(issueId: string, action: 'assignContainment' | 'analyze' | 'defineCorrective' | 'implement' | 'verifyEffective' | 'close', data?: Record<string, unknown>): Promise<LogicCallResult>;
|
|
906
|
+
bidTransition(requestId: string, bidId: string, action: 'submit' | 'approve' | 'reject' | 'withdraw', data?: Record<string, unknown>): Promise<LogicCallResult>;
|
|
907
|
+
gateApproval(productId: string, gate: 'production' | 'sales' | 'custom', action: 'approve' | 'reject', comment?: string): Promise<LogicCallResult>;
|
|
908
|
+
accessDocument(documentId: string, action: 'view' | 'download' | 'print'): Promise<{
|
|
909
|
+
url: string;
|
|
910
|
+
expiresIn: number;
|
|
911
|
+
}>;
|
|
912
|
+
createFlow(flow: Omit<FlowDefinition, 'id'>): Promise<{
|
|
913
|
+
id: string;
|
|
914
|
+
}>;
|
|
915
|
+
updateFlow(flowId: string, updates: Partial<FlowDefinition>): Promise<void>;
|
|
916
|
+
publishFlow(flowId: string): Promise<void>;
|
|
917
|
+
archiveFlow(flowId: string): Promise<void>;
|
|
918
|
+
/**
|
|
919
|
+
* A page of the tenant's flows.
|
|
920
|
+
*
|
|
921
|
+
* Took no arguments and returned a bare array, so a caller wanting one
|
|
922
|
+
* state — published flows, to offer as event handlers — pulled every state
|
|
923
|
+
* and filtered locally. The server has always been able to filter; asking
|
|
924
|
+
* it to means the page is spent on rows the caller wants.
|
|
925
|
+
*
|
|
926
|
+
* `hasMore` is returned rather than implied. A full page and a truncated
|
|
927
|
+
* one are the same array, and a caller that cannot tell them apart quietly
|
|
928
|
+
* drops whatever did not fit.
|
|
929
|
+
*/
|
|
930
|
+
listFlows(params?: ListFlowsParams): Promise<ListFlowsResult>;
|
|
931
|
+
getFlow(flowId: string): Promise<FlowDefinition>;
|
|
932
|
+
testFlow(flowId: string, testInput: unknown): Promise<LogicCallResult>;
|
|
933
|
+
cloneFlow(flowId: string, newName: string): Promise<{
|
|
934
|
+
id: string;
|
|
935
|
+
}>;
|
|
936
|
+
listVariables(): Promise<Array<{
|
|
937
|
+
id: string;
|
|
938
|
+
name: string;
|
|
939
|
+
type: 'string' | 'number' | 'boolean' | 'json' | 'secret';
|
|
940
|
+
value?: unknown;
|
|
941
|
+
isSecret: boolean;
|
|
942
|
+
createdAt: Date;
|
|
943
|
+
updatedAt: Date;
|
|
944
|
+
}>>;
|
|
945
|
+
getVariable(variableId: string): Promise<{
|
|
946
|
+
id: string;
|
|
947
|
+
name: string;
|
|
948
|
+
type: 'string' | 'number' | 'boolean' | 'json' | 'secret';
|
|
949
|
+
value?: unknown;
|
|
950
|
+
isSecret: boolean;
|
|
951
|
+
}>;
|
|
952
|
+
createVariable(data: {
|
|
953
|
+
name: string;
|
|
954
|
+
type: 'string' | 'number' | 'boolean' | 'json' | 'secret';
|
|
955
|
+
value: unknown;
|
|
956
|
+
description?: string;
|
|
957
|
+
}): Promise<{
|
|
958
|
+
id: string;
|
|
959
|
+
}>;
|
|
960
|
+
updateVariable(variableId: string, data: {
|
|
961
|
+
value?: unknown;
|
|
962
|
+
description?: string;
|
|
963
|
+
}): Promise<void>;
|
|
964
|
+
deleteVariable(variableId: string): Promise<void>;
|
|
965
|
+
listTemplates(): Promise<Array<{
|
|
966
|
+
id: string;
|
|
967
|
+
name: string;
|
|
968
|
+
description: string;
|
|
969
|
+
category: string;
|
|
970
|
+
isPublic: boolean;
|
|
971
|
+
createdAt: Date;
|
|
972
|
+
}>>;
|
|
973
|
+
getTemplate(templateId: string): Promise<{
|
|
974
|
+
id: string;
|
|
975
|
+
name: string;
|
|
976
|
+
description: string;
|
|
977
|
+
definition: unknown;
|
|
978
|
+
variables: Array<{
|
|
979
|
+
name: string;
|
|
980
|
+
type: string;
|
|
981
|
+
defaultValue?: unknown;
|
|
982
|
+
}>;
|
|
983
|
+
}>;
|
|
984
|
+
createFlowFromTemplate(templateId: string, data: {
|
|
985
|
+
name: string;
|
|
986
|
+
description?: string;
|
|
987
|
+
variables?: Record<string, unknown>;
|
|
988
|
+
}): Promise<{
|
|
989
|
+
flowId: string;
|
|
990
|
+
}>;
|
|
991
|
+
listWebhooks(): Promise<Array<{
|
|
992
|
+
id: string;
|
|
993
|
+
name: string;
|
|
994
|
+
url: string;
|
|
995
|
+
flowId: string;
|
|
996
|
+
isActive: boolean;
|
|
997
|
+
createdAt: Date;
|
|
998
|
+
}>>;
|
|
999
|
+
createWebhook(data: {
|
|
1000
|
+
name: string;
|
|
1001
|
+
flowId: string;
|
|
1002
|
+
description?: string;
|
|
1003
|
+
}): Promise<{
|
|
1004
|
+
id: string;
|
|
1005
|
+
url: string;
|
|
1006
|
+
secret: string;
|
|
1007
|
+
}>;
|
|
1008
|
+
deleteWebhook(webhookId: string): Promise<void>;
|
|
1009
|
+
rotateWebhookSecret(webhookId: string): Promise<{
|
|
1010
|
+
secret: string;
|
|
1011
|
+
}>;
|
|
1012
|
+
listPendingApprovals(): Promise<Array<{
|
|
1013
|
+
id: string;
|
|
1014
|
+
executionId: string;
|
|
1015
|
+
flowName: string;
|
|
1016
|
+
requestedBy: string;
|
|
1017
|
+
requestedAt: Date;
|
|
1018
|
+
expiresAt?: Date;
|
|
1019
|
+
}>>;
|
|
1020
|
+
approveRequest(approvalId: string, comment?: string): Promise<void>;
|
|
1021
|
+
rejectRequest(approvalId: string, reason: string): Promise<void>;
|
|
1022
|
+
listDataTriggers(): Promise<Array<{
|
|
1023
|
+
id: string;
|
|
1024
|
+
name: string;
|
|
1025
|
+
collection: string;
|
|
1026
|
+
operation: 'create' | 'update' | 'delete';
|
|
1027
|
+
flowId: string;
|
|
1028
|
+
isActive: boolean;
|
|
1029
|
+
}>>;
|
|
1030
|
+
createDataTrigger(data: {
|
|
1031
|
+
name: string;
|
|
1032
|
+
collection: string;
|
|
1033
|
+
operation: 'create' | 'update' | 'delete';
|
|
1034
|
+
flowId: string;
|
|
1035
|
+
conditions?: Array<{
|
|
1036
|
+
field: string;
|
|
1037
|
+
operator: string;
|
|
1038
|
+
value: unknown;
|
|
1039
|
+
}>;
|
|
1040
|
+
}): Promise<{
|
|
1041
|
+
id: string;
|
|
1042
|
+
}>;
|
|
1043
|
+
deleteDataTrigger(triggerId: string): Promise<void>;
|
|
1044
|
+
toggleDataTrigger(triggerId: string, isActive: boolean): Promise<void>;
|
|
1045
|
+
generateFlowFromPrompt(prompt: string): Promise<{
|
|
1046
|
+
suggestedFlow: FlowDefinition;
|
|
1047
|
+
explanation: string;
|
|
1048
|
+
}>;
|
|
1049
|
+
explainFlow(flowId: string): Promise<{
|
|
1050
|
+
summary: string;
|
|
1051
|
+
steps: Array<{
|
|
1052
|
+
step: number;
|
|
1053
|
+
description: string;
|
|
1054
|
+
}>;
|
|
1055
|
+
suggestedImprovements?: string[];
|
|
1056
|
+
}>;
|
|
1057
|
+
}
|
|
1058
|
+
|
|
1059
|
+
interface MAKEMINDTenantConfig extends MAKEMINDConfig {
|
|
1060
|
+
apiClient: ApiClient;
|
|
1061
|
+
tenantId: () => string | null;
|
|
1062
|
+
/**
|
|
1063
|
+
* Called after a tenant is created so the client can activate the new tenant
|
|
1064
|
+
* context (set the active tenant id and refresh the session token so the new
|
|
1065
|
+
* tenant's claims take effect immediately).
|
|
1066
|
+
*/
|
|
1067
|
+
onTenantCreated?: (tenantId: string, customToken?: string) => Promise<void>;
|
|
1068
|
+
}
|
|
1069
|
+
declare class MAKEMINDTenant {
|
|
1070
|
+
private apiClient;
|
|
1071
|
+
private getTenantId;
|
|
1072
|
+
private onTenantCreated?;
|
|
1073
|
+
constructor(config: MAKEMINDTenantConfig);
|
|
1074
|
+
private get tenantId();
|
|
1075
|
+
createTenant(data: {
|
|
1076
|
+
name: string;
|
|
1077
|
+
plan?: string;
|
|
1078
|
+
industryType?: string;
|
|
1079
|
+
/**
|
|
1080
|
+
* 'test' creates a sandbox tenant: usage is recorded non-billable and rate
|
|
1081
|
+
* limits are capped at the sandbox tier — use it to run conformance/
|
|
1082
|
+
* integration checks without incurring cost. Defaults to 'live'.
|
|
1083
|
+
*/
|
|
1084
|
+
mode?: 'test' | 'live';
|
|
1085
|
+
settings?: {
|
|
1086
|
+
displayName?: string;
|
|
1087
|
+
type?: string;
|
|
1088
|
+
[key: string]: unknown;
|
|
1089
|
+
};
|
|
1090
|
+
}): Promise<{
|
|
1091
|
+
id: string;
|
|
1092
|
+
name: string;
|
|
1093
|
+
workspaceId: string;
|
|
1094
|
+
status: string;
|
|
1095
|
+
user?: {
|
|
1096
|
+
uid: string;
|
|
1097
|
+
email: string;
|
|
1098
|
+
displayName: string | null;
|
|
1099
|
+
tenantId: string;
|
|
1100
|
+
roles: string[];
|
|
1101
|
+
scopes: string[];
|
|
1102
|
+
};
|
|
1103
|
+
customToken?: string;
|
|
1104
|
+
}>;
|
|
1105
|
+
getCurrent(): Promise<Tenant | null>;
|
|
1106
|
+
getTenant(tenantId: string): Promise<Tenant | null>;
|
|
1107
|
+
onTenantSnapshot(callback: (tenant: Tenant | null) => void): Unsubscribe;
|
|
1108
|
+
updateTenant(updates: {
|
|
1109
|
+
displayName?: string;
|
|
1110
|
+
settings?: Record<string, unknown>;
|
|
1111
|
+
}): Promise<void>;
|
|
1112
|
+
listMembers(): Promise<TenantMember[]>;
|
|
1113
|
+
inviteMember(data: {
|
|
1114
|
+
email: string;
|
|
1115
|
+
roles: string[];
|
|
1116
|
+
scopes?: string[];
|
|
1117
|
+
}): Promise<void>;
|
|
1118
|
+
updateMember(userId: string, updates: {
|
|
1119
|
+
roles?: string[];
|
|
1120
|
+
scopes?: string[];
|
|
1121
|
+
}): Promise<void>;
|
|
1122
|
+
removeMember(userId: string): Promise<void>;
|
|
1123
|
+
listWorkspaces(): Promise<Workspace[]>;
|
|
1124
|
+
createWorkspace(data: {
|
|
1125
|
+
name: string;
|
|
1126
|
+
displayName: string;
|
|
1127
|
+
settings?: Record<string, unknown>;
|
|
1128
|
+
type?: 'default' | 'development' | 'staging' | 'production';
|
|
1129
|
+
}): Promise<{
|
|
1130
|
+
workspaceId: string;
|
|
1131
|
+
}>;
|
|
1132
|
+
updateWorkspace(workspaceId: string, updates: {
|
|
1133
|
+
displayName?: string;
|
|
1134
|
+
settings?: Record<string, unknown>;
|
|
1135
|
+
}): Promise<{
|
|
1136
|
+
success: boolean;
|
|
1137
|
+
}>;
|
|
1138
|
+
deleteWorkspace(workspaceId: string): Promise<{
|
|
1139
|
+
success: boolean;
|
|
1140
|
+
}>;
|
|
1141
|
+
}
|
|
1142
|
+
|
|
1143
|
+
interface RegisterDeviceOptions {
|
|
1144
|
+
platform: 'ios' | 'android' | 'web';
|
|
1145
|
+
deviceId?: string;
|
|
1146
|
+
}
|
|
1147
|
+
interface PushMessage {
|
|
1148
|
+
messageId: string;
|
|
1149
|
+
title?: string;
|
|
1150
|
+
body: string;
|
|
1151
|
+
data?: Record<string, string>;
|
|
1152
|
+
}
|
|
1153
|
+
interface MAKEMINDMessagingConfig extends MAKEMINDConfig {
|
|
1154
|
+
apiClient: ApiClient;
|
|
1155
|
+
tenantId: () => string | null;
|
|
1156
|
+
userId: () => string | null;
|
|
1157
|
+
firebaseApp?: FirebaseApp;
|
|
1158
|
+
vapidKey?: string;
|
|
1159
|
+
}
|
|
1160
|
+
declare class MAKEMINDMessaging {
|
|
1161
|
+
private apiClient;
|
|
1162
|
+
private applicationId;
|
|
1163
|
+
private getTenantId;
|
|
1164
|
+
private getUserId;
|
|
1165
|
+
private firebaseApp?;
|
|
1166
|
+
private vapidKey?;
|
|
1167
|
+
private messaging?;
|
|
1168
|
+
private currentDeviceId?;
|
|
1169
|
+
constructor(config: MAKEMINDMessagingConfig);
|
|
1170
|
+
private get tenantId();
|
|
1171
|
+
private get userId();
|
|
1172
|
+
private getMessaging;
|
|
1173
|
+
private generateDeviceId;
|
|
1174
|
+
/**
|
|
1175
|
+
* Send a message using a template via the sendBatchMessages onCall.
|
|
1176
|
+
* Maps SDK SendMessageOptions to the batch service: one call per channel.
|
|
1177
|
+
*/
|
|
1178
|
+
send(options: SendMessageOptions): Promise<{
|
|
1179
|
+
messageId: string;
|
|
1180
|
+
}>;
|
|
1181
|
+
/**
|
|
1182
|
+
* Send notification to specific users across channels.
|
|
1183
|
+
* Uses sendBatchMessages onCall (one dispatch per channel).
|
|
1184
|
+
*/
|
|
1185
|
+
notify(userIds: string[], notification: {
|
|
1186
|
+
title: string;
|
|
1187
|
+
body: string;
|
|
1188
|
+
data?: Record<string, unknown>;
|
|
1189
|
+
channels?: ('push' | 'email' | 'sms')[];
|
|
1190
|
+
}): Promise<{
|
|
1191
|
+
messageId: string;
|
|
1192
|
+
}>;
|
|
1193
|
+
/**
|
|
1194
|
+
* Register device for push notifications.
|
|
1195
|
+
* SDK internally handles token acquisition (Firebase FCM).
|
|
1196
|
+
* Uses the REST /messaging/devices route (already correct).
|
|
1197
|
+
*/
|
|
1198
|
+
registerDevice(options: RegisterDeviceOptions): Promise<{
|
|
1199
|
+
deviceId: string;
|
|
1200
|
+
}>;
|
|
1201
|
+
/**
|
|
1202
|
+
* Internal: Acquire push token from the platform's push service.
|
|
1203
|
+
* Currently uses Firebase FCM, abstracted for future cloud-agnostic support.
|
|
1204
|
+
*/
|
|
1205
|
+
private acquirePushToken;
|
|
1206
|
+
/**
|
|
1207
|
+
* Unregister device from push notifications.
|
|
1208
|
+
* Uses the REST DELETE /messaging/devices/:token route.
|
|
1209
|
+
* The route key is the raw FCM token (server base64-encodes it to deviceId).
|
|
1210
|
+
*/
|
|
1211
|
+
unregisterDevice(deviceId: string): Promise<void>;
|
|
1212
|
+
/**
|
|
1213
|
+
* Listen for foreground push messages.
|
|
1214
|
+
*/
|
|
1215
|
+
onPushMessage(callback: (message: PushMessage) => void): Unsubscribe;
|
|
1216
|
+
/**
|
|
1217
|
+
* Get in-app notifications for the current user.
|
|
1218
|
+
* Dispatch op: messaging-getInAppNotifications
|
|
1219
|
+
* Service contract: { userId?, unreadOnly?, limit?, cursor? }
|
|
1220
|
+
* Response: { notifications, hasMore, nextCursor }
|
|
1221
|
+
*/
|
|
1222
|
+
getNotifications(options?: {
|
|
1223
|
+
unreadOnly?: boolean;
|
|
1224
|
+
limit?: number;
|
|
1225
|
+
cursor?: string;
|
|
1226
|
+
}): Promise<{
|
|
1227
|
+
notifications: Notification[];
|
|
1228
|
+
nextCursor?: string;
|
|
1229
|
+
}>;
|
|
1230
|
+
/**
|
|
1231
|
+
* Get in-app notifications stream (polling-based).
|
|
1232
|
+
*/
|
|
1233
|
+
onNotifications(callback: (notifications: Notification[]) => void, options?: {
|
|
1234
|
+
unreadOnly?: boolean;
|
|
1235
|
+
limitCount?: number;
|
|
1236
|
+
}): Unsubscribe;
|
|
1237
|
+
/**
|
|
1238
|
+
* Get unread notification count.
|
|
1239
|
+
* Dispatch op: messaging-getUnreadNotificationCount (the verified onCall service).
|
|
1240
|
+
* Response: { userId, unreadCount }
|
|
1241
|
+
*/
|
|
1242
|
+
getUnreadCount(): Promise<number>;
|
|
1243
|
+
/**
|
|
1244
|
+
* Get unread notification count stream (polling-based).
|
|
1245
|
+
*/
|
|
1246
|
+
onUnreadCount(callback: (count: number) => void): Unsubscribe;
|
|
1247
|
+
/**
|
|
1248
|
+
* Mark a notification as read.
|
|
1249
|
+
* Dispatch op: messaging-markNotificationRead
|
|
1250
|
+
* Service contract: { notificationId } or { notificationIds }
|
|
1251
|
+
*/
|
|
1252
|
+
markAsRead(notificationId: string): Promise<void>;
|
|
1253
|
+
/**
|
|
1254
|
+
* Mark all notifications as read for the current user.
|
|
1255
|
+
* Dispatch op: messaging-markAllNotificationsRead (new onCall — no existing match).
|
|
1256
|
+
* Implemented in backend send.ts + service/send.ts below.
|
|
1257
|
+
*/
|
|
1258
|
+
markAllAsRead(): Promise<void>;
|
|
1259
|
+
/**
|
|
1260
|
+
* Notify ECO reviewers.
|
|
1261
|
+
*/
|
|
1262
|
+
notifyEcoReviewers(eco: {
|
|
1263
|
+
requestNumber: string;
|
|
1264
|
+
title: string;
|
|
1265
|
+
priority: string;
|
|
1266
|
+
productCode?: string;
|
|
1267
|
+
}, reviewerIds: string[]): Promise<{
|
|
1268
|
+
messageId: string;
|
|
1269
|
+
}>;
|
|
1270
|
+
/**
|
|
1271
|
+
* Notify quality issue critical.
|
|
1272
|
+
*/
|
|
1273
|
+
notifyQualityCritical(issue: {
|
|
1274
|
+
issueNumber: string;
|
|
1275
|
+
title: string;
|
|
1276
|
+
severity: string;
|
|
1277
|
+
}, recipientIds: string[]): Promise<{
|
|
1278
|
+
messageId: string;
|
|
1279
|
+
}>;
|
|
1280
|
+
/**
|
|
1281
|
+
* Notify bid received.
|
|
1282
|
+
*/
|
|
1283
|
+
notifyBidReceived(request: {
|
|
1284
|
+
requestNumber: string;
|
|
1285
|
+
title: string;
|
|
1286
|
+
}, bidder: {
|
|
1287
|
+
name: string;
|
|
1288
|
+
}, ownerId: string): Promise<{
|
|
1289
|
+
messageId: string;
|
|
1290
|
+
}>;
|
|
1291
|
+
/**
|
|
1292
|
+
* List available message templates.
|
|
1293
|
+
* Dispatch op: messaging-msgGetTemplates (the verified onCall service).
|
|
1294
|
+
* Service contract: { channelType? }
|
|
1295
|
+
* Response: { templates }
|
|
1296
|
+
*/
|
|
1297
|
+
listTemplates(options?: {
|
|
1298
|
+
channel?: 'push' | 'email' | 'sms';
|
|
1299
|
+
status?: 'active' | 'draft';
|
|
1300
|
+
}): Promise<MessageTemplate[]>;
|
|
1301
|
+
/**
|
|
1302
|
+
* Get a specific template by ID.
|
|
1303
|
+
* Dispatch op: messaging-msgGetTemplate
|
|
1304
|
+
* Service contract: { templateId }
|
|
1305
|
+
* Response: template document (FirebaseFirestore.DocumentData)
|
|
1306
|
+
*/
|
|
1307
|
+
getTemplate(templateId: string): Promise<MessageTemplate>;
|
|
1308
|
+
/**
|
|
1309
|
+
* Create a new message template.
|
|
1310
|
+
* Dispatch op: messaging-msgCreateTemplate
|
|
1311
|
+
* Service contract: { name, channelType, subject?, body, bodyHtml?, language?, variables?, description? }
|
|
1312
|
+
* Response: { templateId }
|
|
1313
|
+
* Note: backend returns { templateId }; SDK surface returns full MessageTemplate.
|
|
1314
|
+
* We re-fetch the created template to satisfy the return type.
|
|
1315
|
+
*/
|
|
1316
|
+
createTemplate(template: CreateTemplateOptions): Promise<MessageTemplate>;
|
|
1317
|
+
/**
|
|
1318
|
+
* Update an existing template.
|
|
1319
|
+
* Dispatch op: messaging-msgUpdateTemplate
|
|
1320
|
+
* Service contract: { templateId, subject?, body?, bodyHtml?, language?, variables?, description? }
|
|
1321
|
+
* Response: { success }
|
|
1322
|
+
* We re-fetch the updated template to satisfy the return type.
|
|
1323
|
+
*/
|
|
1324
|
+
updateTemplate(templateId: string, updates: Partial<CreateTemplateOptions>): Promise<MessageTemplate>;
|
|
1325
|
+
/**
|
|
1326
|
+
* Delete a template.
|
|
1327
|
+
* Dispatch op: messaging-msgDeleteTemplate
|
|
1328
|
+
* Service contract: { templateId }
|
|
1329
|
+
* Response: { success }
|
|
1330
|
+
*/
|
|
1331
|
+
deleteTemplate(templateId: string): Promise<void>;
|
|
1332
|
+
/**
|
|
1333
|
+
* Subscribe to a topic for push notifications.
|
|
1334
|
+
* Dispatch op: messaging-subscribeToTopic
|
|
1335
|
+
* Service contract: { token, topic, tenantId }
|
|
1336
|
+
* Token is acquired from the current device registration.
|
|
1337
|
+
* If no token is available, the subscription request is sent with userId context only.
|
|
1338
|
+
*/
|
|
1339
|
+
subscribeToTopic(topic: string): Promise<void>;
|
|
1340
|
+
/**
|
|
1341
|
+
* Unsubscribe from a topic.
|
|
1342
|
+
* Dispatch op: messaging-unsubscribeFromTopic
|
|
1343
|
+
* Service contract: { token, topic, tenantId }
|
|
1344
|
+
*/
|
|
1345
|
+
unsubscribeFromTopic(topic: string): Promise<void>;
|
|
1346
|
+
/**
|
|
1347
|
+
* List subscribed topics for the current user.
|
|
1348
|
+
* Dispatch op: messaging-getMyTopics
|
|
1349
|
+
* Service contract: { tenantId? }
|
|
1350
|
+
* Response: { topics: Array<{ topic, fullTopic, tenantId, subscribedAt }> }
|
|
1351
|
+
*/
|
|
1352
|
+
listSubscribedTopics(): Promise<string[]>;
|
|
1353
|
+
/**
|
|
1354
|
+
* Send message to a topic.
|
|
1355
|
+
* Dispatch op: messaging-sendTopicMessage
|
|
1356
|
+
* Service contract: { topic, subject?, body, imageUrl?, data? }
|
|
1357
|
+
* Response: { messageId, fcmMessageId }
|
|
1358
|
+
*/
|
|
1359
|
+
sendToTopic(topic: string, message: {
|
|
1360
|
+
title: string;
|
|
1361
|
+
body: string;
|
|
1362
|
+
data?: Record<string, string>;
|
|
1363
|
+
}): Promise<{
|
|
1364
|
+
messageId: string;
|
|
1365
|
+
}>;
|
|
1366
|
+
/**
|
|
1367
|
+
* Get message history for this tenant.
|
|
1368
|
+
* Dispatch op: messaging-getMessages
|
|
1369
|
+
* Service contract: { channelType?, status?, limit? }
|
|
1370
|
+
* Response: { messages }
|
|
1371
|
+
*/
|
|
1372
|
+
getMessageHistory(options?: {
|
|
1373
|
+
channel?: 'push' | 'email' | 'sms';
|
|
1374
|
+
status?: 'sent' | 'delivered' | 'failed';
|
|
1375
|
+
limit?: number;
|
|
1376
|
+
cursor?: string;
|
|
1377
|
+
}): Promise<{
|
|
1378
|
+
messages: MessageHistoryItem[];
|
|
1379
|
+
nextCursor?: string;
|
|
1380
|
+
}>;
|
|
1381
|
+
/**
|
|
1382
|
+
* Get full details of a single message.
|
|
1383
|
+
* Dispatch op: messaging-getMessage
|
|
1384
|
+
* Service contract: { messageId }
|
|
1385
|
+
* Response: full message document (FirebaseFirestore.DocumentData)
|
|
1386
|
+
*/
|
|
1387
|
+
getMessageDetails(messageId: string): Promise<MessageDetails>;
|
|
1388
|
+
/**
|
|
1389
|
+
* Retry a failed message.
|
|
1390
|
+
* No backend messaging onCall exists for retry (confirmed: two searches — grep
|
|
1391
|
+
* across messaging/service/* and messaging/*.ts both returned no match).
|
|
1392
|
+
* Dispatch op: messaging-retryFailedMessage (new onCall implemented below).
|
|
1393
|
+
*/
|
|
1394
|
+
retryMessage(messageId: string): Promise<{
|
|
1395
|
+
messageId: string;
|
|
1396
|
+
}>;
|
|
1397
|
+
}
|
|
1398
|
+
interface MessageTemplate {
|
|
1399
|
+
id: string;
|
|
1400
|
+
name: string;
|
|
1401
|
+
channel: 'push' | 'email' | 'sms';
|
|
1402
|
+
subject?: string;
|
|
1403
|
+
body: string;
|
|
1404
|
+
variables: string[];
|
|
1405
|
+
status: 'active' | 'draft';
|
|
1406
|
+
language?: string;
|
|
1407
|
+
createdAt: Date;
|
|
1408
|
+
updatedAt: Date;
|
|
1409
|
+
}
|
|
1410
|
+
interface CreateTemplateOptions {
|
|
1411
|
+
name: string;
|
|
1412
|
+
channel: 'push' | 'email' | 'sms';
|
|
1413
|
+
subject?: string;
|
|
1414
|
+
body: string;
|
|
1415
|
+
variables?: string[];
|
|
1416
|
+
status?: 'active' | 'draft';
|
|
1417
|
+
language?: string;
|
|
1418
|
+
}
|
|
1419
|
+
interface MessageHistoryItem {
|
|
1420
|
+
id: string;
|
|
1421
|
+
channel: 'push' | 'email' | 'sms';
|
|
1422
|
+
template?: string;
|
|
1423
|
+
recipientCount: number;
|
|
1424
|
+
status: 'sent' | 'delivered' | 'failed' | 'partial';
|
|
1425
|
+
sentAt: Date;
|
|
1426
|
+
}
|
|
1427
|
+
interface MessageDetails {
|
|
1428
|
+
id: string;
|
|
1429
|
+
channel: 'push' | 'email' | 'sms';
|
|
1430
|
+
template?: string;
|
|
1431
|
+
recipients: Array<{
|
|
1432
|
+
userId: string;
|
|
1433
|
+
status: 'sent' | 'delivered' | 'failed';
|
|
1434
|
+
deliveredAt?: Date;
|
|
1435
|
+
error?: string;
|
|
1436
|
+
}>;
|
|
1437
|
+
subject?: string;
|
|
1438
|
+
body: string;
|
|
1439
|
+
data?: Record<string, unknown>;
|
|
1440
|
+
sentAt: Date;
|
|
1441
|
+
}
|
|
1442
|
+
|
|
1443
|
+
interface MAKEMINDPartnersConfig extends MAKEMINDConfig {
|
|
1444
|
+
apiClient: ApiClient;
|
|
1445
|
+
tenantId: () => string | null;
|
|
1446
|
+
}
|
|
1447
|
+
type CommissionRate = {
|
|
1448
|
+
kind: 'flatPercent';
|
|
1449
|
+
percent: number;
|
|
1450
|
+
} | {
|
|
1451
|
+
kind: 'fixedPerTransaction';
|
|
1452
|
+
amount: number;
|
|
1453
|
+
currency: string;
|
|
1454
|
+
} | {
|
|
1455
|
+
kind: 'excluded';
|
|
1456
|
+
};
|
|
1457
|
+
/** One row of a partner's rate card. revenueType '*' is the default. */
|
|
1458
|
+
interface CommissionTerm {
|
|
1459
|
+
revenueType: string;
|
|
1460
|
+
rate: CommissionRate;
|
|
1461
|
+
}
|
|
1462
|
+
interface PartnerAttribution {
|
|
1463
|
+
scope: 'tenantMargin' | 'layer1';
|
|
1464
|
+
base: 'margin' | 'gmv';
|
|
1465
|
+
/** Rate card: per-product rates, with an optional '*' default and exclusions. */
|
|
1466
|
+
terms: CommissionTerm[];
|
|
1467
|
+
validFrom: string | Date;
|
|
1468
|
+
validUntil: string | Date | null;
|
|
1469
|
+
status: 'active' | 'paused' | 'ended';
|
|
1470
|
+
}
|
|
1471
|
+
interface CommissionStatementLine {
|
|
1472
|
+
sourceId: string;
|
|
1473
|
+
sourceName: string | null;
|
|
1474
|
+
currency: string;
|
|
1475
|
+
accrued: number;
|
|
1476
|
+
paid: number;
|
|
1477
|
+
owed: number;
|
|
1478
|
+
}
|
|
1479
|
+
interface PartnerCommissionStatement {
|
|
1480
|
+
partnerId: string;
|
|
1481
|
+
lines: CommissionStatementLine[];
|
|
1482
|
+
totalsByCurrency: Array<{
|
|
1483
|
+
currency: string;
|
|
1484
|
+
accrued: number;
|
|
1485
|
+
paid: number;
|
|
1486
|
+
owed: number;
|
|
1487
|
+
}>;
|
|
1488
|
+
}
|
|
1489
|
+
/**
|
|
1490
|
+
* Partner commission overlay client. The same API backs both the central portal
|
|
1491
|
+
* and a tenant's own admin (a tenant embeds partner management in its SaaS via
|
|
1492
|
+
* these tenant-admin methods); Guild consumes the platform-admin methods to
|
|
1493
|
+
* manage the partners of our own SaaSes.
|
|
1494
|
+
*/
|
|
1495
|
+
declare class MAKEMINDPartners {
|
|
1496
|
+
private apiClient;
|
|
1497
|
+
constructor(config: MAKEMINDPartnersConfig);
|
|
1498
|
+
/** Register the signed-in individual as a partner (requires a verified email). */
|
|
1499
|
+
registerSelf(displayName?: string): Promise<{
|
|
1500
|
+
partnerId: string;
|
|
1501
|
+
}>;
|
|
1502
|
+
/** Browse the open partner-program directory. */
|
|
1503
|
+
listPrograms(): Promise<{
|
|
1504
|
+
programs: unknown[];
|
|
1505
|
+
}>;
|
|
1506
|
+
/** Apply to a tenant's program (creates a pending registration). */
|
|
1507
|
+
apply(tenantId: string): Promise<{
|
|
1508
|
+
registration: unknown;
|
|
1509
|
+
}>;
|
|
1510
|
+
/** Auto-attribute a subject to a partner via a referral code (at checkout/entry). */
|
|
1511
|
+
registerReferral(input: {
|
|
1512
|
+
code: string;
|
|
1513
|
+
subjectType: 'endCustomer' | 'tenant' | 'sale';
|
|
1514
|
+
subjectId: string;
|
|
1515
|
+
expiresAt?: string | null;
|
|
1516
|
+
}): Promise<{
|
|
1517
|
+
referral: unknown;
|
|
1518
|
+
}>;
|
|
1519
|
+
/** Derive commission for a settled sale for any partner that referred the subject. */
|
|
1520
|
+
deriveCommission(input: {
|
|
1521
|
+
subjectId: string;
|
|
1522
|
+
revenueType: string;
|
|
1523
|
+
baseAmount: number;
|
|
1524
|
+
currency: string;
|
|
1525
|
+
saleId: string;
|
|
1526
|
+
tenantId?: string;
|
|
1527
|
+
}): Promise<{
|
|
1528
|
+
entries: unknown[];
|
|
1529
|
+
}>;
|
|
1530
|
+
/**
|
|
1531
|
+
* Canonical settlement intake: report a revenue event; the engine derives the
|
|
1532
|
+
* full line set (tax + commission + net waterfall) and records partner
|
|
1533
|
+
* commissions when a saleId is given.
|
|
1534
|
+
*/
|
|
1535
|
+
deriveSettlementForEvent(input: {
|
|
1536
|
+
revenue: {
|
|
1537
|
+
category: string;
|
|
1538
|
+
amount: number;
|
|
1539
|
+
currency: string;
|
|
1540
|
+
priceTaxMode: 'inclusive' | 'exclusive';
|
|
1541
|
+
supplyType?: string;
|
|
1542
|
+
recognition?: 'pointInTime' | 'overTime';
|
|
1543
|
+
};
|
|
1544
|
+
seller: {
|
|
1545
|
+
role: 'seller';
|
|
1546
|
+
country?: string;
|
|
1547
|
+
};
|
|
1548
|
+
buyer: {
|
|
1549
|
+
role: 'buyer';
|
|
1550
|
+
country?: string;
|
|
1551
|
+
isBusiness?: boolean;
|
|
1552
|
+
taxId?: string;
|
|
1553
|
+
taxIdValidated?: boolean;
|
|
1554
|
+
};
|
|
1555
|
+
fees?: Array<{
|
|
1556
|
+
category: string;
|
|
1557
|
+
amount: number;
|
|
1558
|
+
treatment: 'deductFromProceeds' | 'addToCost';
|
|
1559
|
+
}>;
|
|
1560
|
+
platformFee?: number;
|
|
1561
|
+
saleId?: string;
|
|
1562
|
+
subjectId?: string;
|
|
1563
|
+
at?: string;
|
|
1564
|
+
tenantId?: string;
|
|
1565
|
+
}): Promise<{
|
|
1566
|
+
lines: unknown[];
|
|
1567
|
+
waterfall: unknown;
|
|
1568
|
+
taxRate: number;
|
|
1569
|
+
reverseCharge: boolean;
|
|
1570
|
+
}>;
|
|
1571
|
+
/** Publish/update the tenant's partner program (directory listing). */
|
|
1572
|
+
publishProgram(input: {
|
|
1573
|
+
description: string;
|
|
1574
|
+
offeredTerms: CommissionTerm[];
|
|
1575
|
+
status?: 'open' | 'closed';
|
|
1576
|
+
scope?: 'tenantMargin' | 'layer1';
|
|
1577
|
+
tenantId?: string;
|
|
1578
|
+
}): Promise<{
|
|
1579
|
+
program: unknown;
|
|
1580
|
+
}>;
|
|
1581
|
+
/** Approve a pending/invited registration (optionally overriding the rate). */
|
|
1582
|
+
approve(input: {
|
|
1583
|
+
partnerId: string;
|
|
1584
|
+
attribution?: PartnerAttribution;
|
|
1585
|
+
tenantId?: string;
|
|
1586
|
+
}): Promise<{
|
|
1587
|
+
ok: true;
|
|
1588
|
+
}>;
|
|
1589
|
+
/** Add an already-registered partner directly by id (arranged relationship). */
|
|
1590
|
+
addById(input: {
|
|
1591
|
+
partnerId: string;
|
|
1592
|
+
attribution: PartnerAttribution;
|
|
1593
|
+
tenantId?: string;
|
|
1594
|
+
}): Promise<{
|
|
1595
|
+
ok: true;
|
|
1596
|
+
}>;
|
|
1597
|
+
/** Invite a partner by email (fallback for someone not yet self-registered). */
|
|
1598
|
+
invite(input: {
|
|
1599
|
+
email: string;
|
|
1600
|
+
attribution: PartnerAttribution;
|
|
1601
|
+
tenantId?: string;
|
|
1602
|
+
}): Promise<{
|
|
1603
|
+
partnerId: string;
|
|
1604
|
+
}>;
|
|
1605
|
+
/** List the partners registered in the current tenant. */
|
|
1606
|
+
list(tenantId?: string): Promise<{
|
|
1607
|
+
registrations: unknown[];
|
|
1608
|
+
}>;
|
|
1609
|
+
/** Update a registration's rate and/or status. */
|
|
1610
|
+
update(input: {
|
|
1611
|
+
partnerId: string;
|
|
1612
|
+
attribution?: PartnerAttribution;
|
|
1613
|
+
status?: 'active' | 'paused' | 'ended';
|
|
1614
|
+
tenantId?: string;
|
|
1615
|
+
}): Promise<{
|
|
1616
|
+
ok: true;
|
|
1617
|
+
}>;
|
|
1618
|
+
/** Record a commission accrual for the current tenant (idempotent on idempotencyKey). */
|
|
1619
|
+
recordCommission(input: {
|
|
1620
|
+
partnerId: string;
|
|
1621
|
+
amount: number;
|
|
1622
|
+
currency: string;
|
|
1623
|
+
idempotencyKey: string;
|
|
1624
|
+
scope?: 'tenantMargin' | 'layer1';
|
|
1625
|
+
sourceRef?: string | null;
|
|
1626
|
+
tenantId?: string;
|
|
1627
|
+
}): Promise<{
|
|
1628
|
+
entry: unknown;
|
|
1629
|
+
}>;
|
|
1630
|
+
/** Claw back a commission entry. */
|
|
1631
|
+
reverseCommission(entryId: string): Promise<{
|
|
1632
|
+
reversal: unknown;
|
|
1633
|
+
}>;
|
|
1634
|
+
/** Record a manual payout against a partner's owed commission. */
|
|
1635
|
+
recordPayout(input: {
|
|
1636
|
+
partnerId: string;
|
|
1637
|
+
tenantId: string | null;
|
|
1638
|
+
amount: number;
|
|
1639
|
+
currency: string;
|
|
1640
|
+
ref?: string | null;
|
|
1641
|
+
}): Promise<{
|
|
1642
|
+
payout: unknown;
|
|
1643
|
+
}>;
|
|
1644
|
+
/** Accept an invitation, claiming the partner identity (requires a verified email). */
|
|
1645
|
+
acceptInvitation(partnerId: string, tenantId: string): Promise<{
|
|
1646
|
+
partnerId: string;
|
|
1647
|
+
tenantId: string;
|
|
1648
|
+
}>;
|
|
1649
|
+
/** The signed-in partner's own cross-tenant commission statement (union). */
|
|
1650
|
+
myCommissions(): Promise<{
|
|
1651
|
+
statement: PartnerCommissionStatement;
|
|
1652
|
+
}>;
|
|
1653
|
+
/** Any partner's statement (platform admin only). */
|
|
1654
|
+
commissionsOf(partnerId: string): Promise<{
|
|
1655
|
+
statement: PartnerCommissionStatement;
|
|
1656
|
+
}>;
|
|
1657
|
+
}
|
|
1658
|
+
|
|
1659
|
+
interface MAKEMINDStorageConfig extends MAKEMINDConfig {
|
|
1660
|
+
apiClient: ApiClient;
|
|
1661
|
+
tenantId: () => string | null;
|
|
1662
|
+
}
|
|
1663
|
+
interface UploadOptions {
|
|
1664
|
+
path: string;
|
|
1665
|
+
file: File | Blob;
|
|
1666
|
+
metadata?: Record<string, string>;
|
|
1667
|
+
onProgress?: (progress: number) => void;
|
|
1668
|
+
}
|
|
1669
|
+
interface UploadResult {
|
|
1670
|
+
path: string;
|
|
1671
|
+
url: string;
|
|
1672
|
+
size: number;
|
|
1673
|
+
contentType: string;
|
|
1674
|
+
metadata?: Record<string, string>;
|
|
1675
|
+
}
|
|
1676
|
+
interface FileMetadata {
|
|
1677
|
+
name: string;
|
|
1678
|
+
path: string;
|
|
1679
|
+
size: number;
|
|
1680
|
+
contentType: string;
|
|
1681
|
+
createdAt: Date;
|
|
1682
|
+
updatedAt: Date;
|
|
1683
|
+
metadata?: Record<string, string>;
|
|
1684
|
+
}
|
|
1685
|
+
interface ListFilesOptions {
|
|
1686
|
+
prefix?: string;
|
|
1687
|
+
maxResults?: number;
|
|
1688
|
+
pageToken?: string;
|
|
1689
|
+
}
|
|
1690
|
+
interface ListFilesResult {
|
|
1691
|
+
files: FileMetadata[];
|
|
1692
|
+
nextPageToken?: string;
|
|
1693
|
+
}
|
|
1694
|
+
declare class MAKEMINDStorage {
|
|
1695
|
+
private apiClient;
|
|
1696
|
+
private getTenantId;
|
|
1697
|
+
constructor(config: MAKEMINDStorageConfig);
|
|
1698
|
+
private get tenantId();
|
|
1699
|
+
/**
|
|
1700
|
+
* Encode a storage object path for use as a path parameter, preserving the
|
|
1701
|
+
* `/` separators (the gateway captures the full sub-path via a wildcard).
|
|
1702
|
+
*/
|
|
1703
|
+
private encodePath;
|
|
1704
|
+
/**
|
|
1705
|
+
* Upload a file
|
|
1706
|
+
*/
|
|
1707
|
+
upload(options: UploadOptions): Promise<UploadResult>;
|
|
1708
|
+
private uploadToSignedUrl;
|
|
1709
|
+
/**
|
|
1710
|
+
* Get download URL for a file
|
|
1711
|
+
*/
|
|
1712
|
+
getDownloadUrl(path: string): Promise<string>;
|
|
1713
|
+
/**
|
|
1714
|
+
* Download a file directly
|
|
1715
|
+
* Returns the file as a Blob
|
|
1716
|
+
*/
|
|
1717
|
+
download(path: string): Promise<Blob>;
|
|
1718
|
+
/**
|
|
1719
|
+
* Download a file and trigger browser download
|
|
1720
|
+
*/
|
|
1721
|
+
downloadToFile(path: string, filename?: string): Promise<void>;
|
|
1722
|
+
/**
|
|
1723
|
+
* Get file metadata
|
|
1724
|
+
*/
|
|
1725
|
+
getMetadata(path: string): Promise<FileMetadata>;
|
|
1726
|
+
/**
|
|
1727
|
+
* Update file metadata
|
|
1728
|
+
*/
|
|
1729
|
+
updateMetadata(path: string, metadata: Record<string, string>): Promise<void>;
|
|
1730
|
+
/**
|
|
1731
|
+
* List files in a directory
|
|
1732
|
+
*/
|
|
1733
|
+
listFiles(options?: ListFilesOptions): Promise<ListFilesResult>;
|
|
1734
|
+
/**
|
|
1735
|
+
* Delete a file
|
|
1736
|
+
*/
|
|
1737
|
+
delete(path: string): Promise<void>;
|
|
1738
|
+
/**
|
|
1739
|
+
* Delete multiple files
|
|
1740
|
+
*/
|
|
1741
|
+
deleteMany(paths: string[]): Promise<void>;
|
|
1742
|
+
/**
|
|
1743
|
+
* Copy a file
|
|
1744
|
+
*/
|
|
1745
|
+
copy(sourcePath: string, destinationPath: string): Promise<UploadResult>;
|
|
1746
|
+
/**
|
|
1747
|
+
* Move a file
|
|
1748
|
+
*/
|
|
1749
|
+
move(sourcePath: string, destinationPath: string): Promise<UploadResult>;
|
|
1750
|
+
/**
|
|
1751
|
+
* Upload a document for a product
|
|
1752
|
+
*/
|
|
1753
|
+
uploadProductDocument(productId: string, file: File, options?: {
|
|
1754
|
+
documentType?: string;
|
|
1755
|
+
version?: string;
|
|
1756
|
+
onProgress?: (progress: number) => void;
|
|
1757
|
+
}): Promise<UploadResult>;
|
|
1758
|
+
/**
|
|
1759
|
+
* Upload an ECO attachment
|
|
1760
|
+
*/
|
|
1761
|
+
uploadEcoAttachment(ecoId: string, file: File, onProgress?: (progress: number) => void): Promise<UploadResult>;
|
|
1762
|
+
/**
|
|
1763
|
+
* Upload a quality issue attachment
|
|
1764
|
+
*/
|
|
1765
|
+
uploadQualityAttachment(issueId: string, file: File, onProgress?: (progress: number) => void): Promise<UploadResult>;
|
|
1766
|
+
/**
|
|
1767
|
+
* Get all documents for a product
|
|
1768
|
+
*/
|
|
1769
|
+
getProductDocuments(productId: string): Promise<FileMetadata[]>;
|
|
1770
|
+
/**
|
|
1771
|
+
* List all buckets for the tenant
|
|
1772
|
+
*/
|
|
1773
|
+
listBuckets(): Promise<BucketInfo[]>;
|
|
1774
|
+
/**
|
|
1775
|
+
* Create a new bucket.
|
|
1776
|
+
*
|
|
1777
|
+
* The REST route expects { name, settings } where settings carries the
|
|
1778
|
+
* bucket policy fields. publicAccess, corsConfig, and lifecycleRules from
|
|
1779
|
+
* CreateBucketOptions are folded into the settings envelope so the backend
|
|
1780
|
+
* handler can read them from req.body.settings.
|
|
1781
|
+
*/
|
|
1782
|
+
createBucket(options: CreateBucketOptions): Promise<BucketInfo>;
|
|
1783
|
+
/**
|
|
1784
|
+
* Get bucket info
|
|
1785
|
+
*/
|
|
1786
|
+
getBucket(bucketId: string): Promise<BucketInfo>;
|
|
1787
|
+
/**
|
|
1788
|
+
* Update bucket settings.
|
|
1789
|
+
*
|
|
1790
|
+
* The REST route reads { settings } from req.body. Flatten the
|
|
1791
|
+
* CreateBucketOptions partial into a settings envelope so the backend
|
|
1792
|
+
* merges the diff correctly.
|
|
1793
|
+
*/
|
|
1794
|
+
updateBucket(bucketId: string, updates: Partial<CreateBucketOptions>): Promise<BucketInfo>;
|
|
1795
|
+
/**
|
|
1796
|
+
* Delete a bucket (must be empty)
|
|
1797
|
+
*/
|
|
1798
|
+
deleteBucket(bucketId: string): Promise<void>;
|
|
1799
|
+
/**
|
|
1800
|
+
* Get a pre-signed URL for direct upload (bypassing SDK)
|
|
1801
|
+
*/
|
|
1802
|
+
getUploadUrl(path: string, options?: {
|
|
1803
|
+
contentType?: string;
|
|
1804
|
+
expiresIn?: number;
|
|
1805
|
+
}): Promise<{
|
|
1806
|
+
uploadUrl: string;
|
|
1807
|
+
fileId: string;
|
|
1808
|
+
}>;
|
|
1809
|
+
/**
|
|
1810
|
+
* Check if a file exists
|
|
1811
|
+
*/
|
|
1812
|
+
exists(path: string): Promise<boolean>;
|
|
1813
|
+
/**
|
|
1814
|
+
* Get storage usage statistics
|
|
1815
|
+
*/
|
|
1816
|
+
getUsageStats(): Promise<StorageUsageStats>;
|
|
1817
|
+
}
|
|
1818
|
+
interface BucketInfo {
|
|
1819
|
+
id: string;
|
|
1820
|
+
name: string;
|
|
1821
|
+
tenantId: string;
|
|
1822
|
+
publicAccess: boolean;
|
|
1823
|
+
createdAt: Date;
|
|
1824
|
+
updatedAt: Date;
|
|
1825
|
+
storageUsed: number;
|
|
1826
|
+
fileCount: number;
|
|
1827
|
+
}
|
|
1828
|
+
interface CreateBucketOptions {
|
|
1829
|
+
name: string;
|
|
1830
|
+
publicAccess?: boolean;
|
|
1831
|
+
corsConfig?: CorsConfig;
|
|
1832
|
+
lifecycleRules?: LifecycleRule[];
|
|
1833
|
+
}
|
|
1834
|
+
interface CorsConfig {
|
|
1835
|
+
allowedOrigins: string[];
|
|
1836
|
+
allowedMethods: string[];
|
|
1837
|
+
allowedHeaders?: string[];
|
|
1838
|
+
maxAgeSeconds?: number;
|
|
1839
|
+
}
|
|
1840
|
+
interface LifecycleRule {
|
|
1841
|
+
action: 'delete' | 'archive';
|
|
1842
|
+
conditions: {
|
|
1843
|
+
ageInDays?: number;
|
|
1844
|
+
prefix?: string;
|
|
1845
|
+
};
|
|
1846
|
+
}
|
|
1847
|
+
interface StorageUsageStats {
|
|
1848
|
+
totalBytes: number;
|
|
1849
|
+
fileCount: number;
|
|
1850
|
+
bucketCount: number;
|
|
1851
|
+
lastUpdated: Date;
|
|
1852
|
+
}
|
|
1853
|
+
|
|
1854
|
+
interface MAKEMINDAIConfig extends MAKEMINDConfig {
|
|
1855
|
+
apiClient: ApiClient;
|
|
1856
|
+
tenantId: () => string | null;
|
|
1857
|
+
}
|
|
1858
|
+
interface ChatMessage {
|
|
1859
|
+
role: 'user' | 'assistant' | 'system';
|
|
1860
|
+
content: string;
|
|
1861
|
+
}
|
|
1862
|
+
interface ChatOptions {
|
|
1863
|
+
model?: string;
|
|
1864
|
+
temperature?: number;
|
|
1865
|
+
maxTokens?: number;
|
|
1866
|
+
systemPrompt?: string;
|
|
1867
|
+
}
|
|
1868
|
+
interface ChatResponse {
|
|
1869
|
+
message: ChatMessage;
|
|
1870
|
+
usage: {
|
|
1871
|
+
promptTokens: number;
|
|
1872
|
+
completionTokens: number;
|
|
1873
|
+
totalTokens: number;
|
|
1874
|
+
};
|
|
1875
|
+
}
|
|
1876
|
+
interface EmbeddingOptions {
|
|
1877
|
+
model?: string;
|
|
1878
|
+
}
|
|
1879
|
+
interface VisionOptions {
|
|
1880
|
+
model?: string;
|
|
1881
|
+
maxTokens?: number;
|
|
1882
|
+
}
|
|
1883
|
+
interface ToolCall {
|
|
1884
|
+
name: string;
|
|
1885
|
+
arguments: Record<string, unknown>;
|
|
1886
|
+
}
|
|
1887
|
+
interface ToolDefinition {
|
|
1888
|
+
name: string;
|
|
1889
|
+
description: string;
|
|
1890
|
+
parameters: Record<string, unknown>;
|
|
1891
|
+
}
|
|
1892
|
+
declare class MAKEMINDAI {
|
|
1893
|
+
private apiClient;
|
|
1894
|
+
private getTenantId;
|
|
1895
|
+
constructor(config: MAKEMINDAIConfig);
|
|
1896
|
+
chat(messages: ChatMessage[], options?: ChatOptions): Promise<ChatResponse>;
|
|
1897
|
+
/**
|
|
1898
|
+
* Stream chat completion via the aiStreamChat onCall backend.
|
|
1899
|
+
*
|
|
1900
|
+
* The backend writes chunks progressively to Firestore
|
|
1901
|
+
* (aiStreamChunks/{streamId}/chunks). This method polls the stream
|
|
1902
|
+
* document until the status reaches 'completed' or 'failed', invoking
|
|
1903
|
+
* onChunk for each content chunk in order. Callers that need real-time
|
|
1904
|
+
* granularity should subscribe to the Firestore collection directly using
|
|
1905
|
+
* the returned streamId from aiStreamChat.
|
|
1906
|
+
*
|
|
1907
|
+
* @param messages - Chat messages
|
|
1908
|
+
* @param onChunk - Callback for each streamed content chunk
|
|
1909
|
+
* @param options - Chat options and optional onDone callback
|
|
1910
|
+
* @returns Promise that resolves when streaming is complete
|
|
1911
|
+
*/
|
|
1912
|
+
chatStream(messages: ChatMessage[], onChunk: (chunk: string) => void, options?: ChatOptions & {
|
|
1913
|
+
onDone?: (response: ChatResponse) => void;
|
|
1914
|
+
}): Promise<ChatResponse>;
|
|
1915
|
+
/**
|
|
1916
|
+
* Stream chat using async generator for easier consumption.
|
|
1917
|
+
* Yields content deltas via polling on aiGetStreamResult.
|
|
1918
|
+
*/
|
|
1919
|
+
streamChat(messages: ChatMessage[], options?: ChatOptions): AsyncGenerator<string, ChatResponse, unknown>;
|
|
1920
|
+
createEmbedding(text: string | string[], options?: EmbeddingOptions): Promise<{
|
|
1921
|
+
embeddings: number[][];
|
|
1922
|
+
usage: {
|
|
1923
|
+
totalTokens: number;
|
|
1924
|
+
};
|
|
1925
|
+
}>;
|
|
1926
|
+
/**
|
|
1927
|
+
* Vector search over a tenant knowledge collection.
|
|
1928
|
+
* Routes to the knowledge domain dispatch (knowledge-knowledgeSearch),
|
|
1929
|
+
* which performs semantic search with embeddings over indexed documents.
|
|
1930
|
+
*/
|
|
1931
|
+
vectorSearch(collection: string, query: string, options?: {
|
|
1932
|
+
limit?: number;
|
|
1933
|
+
filter?: Record<string, unknown>;
|
|
1934
|
+
}): Promise<Array<{
|
|
1935
|
+
id: string;
|
|
1936
|
+
score: number;
|
|
1937
|
+
data: Record<string, unknown>;
|
|
1938
|
+
}>>;
|
|
1939
|
+
/**
|
|
1940
|
+
* Vision analysis for a publicly accessible image URL.
|
|
1941
|
+
* Routes to ai-aiVision (aiVision onCall). The image is passed as a
|
|
1942
|
+
* ChatCompletionRequest message using the imageUrl ContentPart type.
|
|
1943
|
+
*/
|
|
1944
|
+
analyzeImage(imageUrl: string, prompt: string, options?: VisionOptions): Promise<{
|
|
1945
|
+
content: string;
|
|
1946
|
+
usage: {
|
|
1947
|
+
totalTokens: number;
|
|
1948
|
+
};
|
|
1949
|
+
}>;
|
|
1950
|
+
/**
|
|
1951
|
+
* Vision analysis for a base64-encoded image.
|
|
1952
|
+
* The image is embedded as a data URI in the imageUrl ContentPart.
|
|
1953
|
+
*/
|
|
1954
|
+
analyzeImageBase64(base64Image: string, mimeType: string, prompt: string, options?: VisionOptions): Promise<{
|
|
1955
|
+
content: string;
|
|
1956
|
+
usage: {
|
|
1957
|
+
totalTokens: number;
|
|
1958
|
+
};
|
|
1959
|
+
}>;
|
|
1960
|
+
/**
|
|
1961
|
+
* Chat completion with tool definitions (function calling).
|
|
1962
|
+
* Routes to ai-aiChat — the aiChat onCall natively supports the tools field
|
|
1963
|
+
* in ChatCompletionRequest, no separate endpoint required.
|
|
1964
|
+
*/
|
|
1965
|
+
chatWithTools(messages: ChatMessage[], tools: ToolDefinition[], options?: ChatOptions): Promise<{
|
|
1966
|
+
message: ChatMessage;
|
|
1967
|
+
toolCalls?: ToolCall[];
|
|
1968
|
+
usage: {
|
|
1969
|
+
promptTokens: number;
|
|
1970
|
+
completionTokens: number;
|
|
1971
|
+
totalTokens: number;
|
|
1972
|
+
};
|
|
1973
|
+
}>;
|
|
1974
|
+
/**
|
|
1975
|
+
* Document analysis (summary, field extraction, or QA).
|
|
1976
|
+
* No dedicated onCall exists in the ai domain; implemented via ai-aiChat
|
|
1977
|
+
* with a structured system prompt that targets the requested analysis type.
|
|
1978
|
+
* The document content must be fetched by the caller and passed as text —
|
|
1979
|
+
* the backend has no URL-fetch / OCR pipeline for onCall yet.
|
|
1980
|
+
*/
|
|
1981
|
+
analyzeDocument(documentUrl: string, analysisType: 'summary' | 'extract' | 'qa', options?: {
|
|
1982
|
+
question?: string;
|
|
1983
|
+
extractFields?: string[];
|
|
1984
|
+
}): Promise<{
|
|
1985
|
+
result: string | Record<string, unknown>;
|
|
1986
|
+
usage: {
|
|
1987
|
+
totalTokens: number;
|
|
1988
|
+
};
|
|
1989
|
+
}>;
|
|
1990
|
+
generate(prompt: string, options?: ChatOptions): Promise<{
|
|
1991
|
+
text: string;
|
|
1992
|
+
usage: {
|
|
1993
|
+
totalTokens: number;
|
|
1994
|
+
};
|
|
1995
|
+
}>;
|
|
1996
|
+
/**
|
|
1997
|
+
* Text summarization via ai-aiChat.
|
|
1998
|
+
* No dedicated onCall exists; implemented as a structured chat request
|
|
1999
|
+
* with a summarization system prompt.
|
|
2000
|
+
*/
|
|
2001
|
+
summarize(text: string, options?: {
|
|
2002
|
+
maxLength?: number;
|
|
2003
|
+
style?: 'bullet' | 'paragraph';
|
|
2004
|
+
}): Promise<{
|
|
2005
|
+
summary: string;
|
|
2006
|
+
usage: {
|
|
2007
|
+
totalTokens: number;
|
|
2008
|
+
};
|
|
2009
|
+
}>;
|
|
2010
|
+
/**
|
|
2011
|
+
* Text translation via ai-aiChat.
|
|
2012
|
+
* No dedicated onCall exists; implemented as a structured chat request
|
|
2013
|
+
* with a translation system prompt.
|
|
2014
|
+
*/
|
|
2015
|
+
translate(text: string, targetLanguage: string, sourceLanguage?: string): Promise<{
|
|
2016
|
+
translation: string;
|
|
2017
|
+
detectedLanguage?: string;
|
|
2018
|
+
usage: {
|
|
2019
|
+
totalTokens: number;
|
|
2020
|
+
};
|
|
2021
|
+
}>;
|
|
2022
|
+
}
|
|
2023
|
+
|
|
2024
|
+
interface MAKEMINDSearchConfig extends MAKEMINDConfig {
|
|
2025
|
+
apiClient: ApiClient;
|
|
2026
|
+
tenantId: () => string | null;
|
|
2027
|
+
}
|
|
2028
|
+
interface SearchResult {
|
|
2029
|
+
hits: Array<{
|
|
2030
|
+
document: Record<string, unknown>;
|
|
2031
|
+
highlights?: Array<{
|
|
2032
|
+
field: string;
|
|
2033
|
+
snippet: string;
|
|
2034
|
+
}>;
|
|
2035
|
+
score: number;
|
|
2036
|
+
}>;
|
|
2037
|
+
found: number;
|
|
2038
|
+
page: number;
|
|
2039
|
+
totalPages: number;
|
|
2040
|
+
}
|
|
2041
|
+
interface SearchQueryOptions {
|
|
2042
|
+
q: string;
|
|
2043
|
+
collections?: string[];
|
|
2044
|
+
page?: number;
|
|
2045
|
+
perPage?: number;
|
|
2046
|
+
}
|
|
2047
|
+
interface AdvancedSearchOptions {
|
|
2048
|
+
query: string;
|
|
2049
|
+
collection: string;
|
|
2050
|
+
facets?: string[];
|
|
2051
|
+
filters?: Record<string, unknown>;
|
|
2052
|
+
sortBy?: string;
|
|
2053
|
+
page?: number;
|
|
2054
|
+
perPage?: number;
|
|
2055
|
+
highlightFields?: string[];
|
|
2056
|
+
groupBy?: string;
|
|
2057
|
+
}
|
|
2058
|
+
interface SearchSuggestionOptions {
|
|
2059
|
+
prefix: string;
|
|
2060
|
+
collection: string;
|
|
2061
|
+
limit?: number;
|
|
2062
|
+
}
|
|
2063
|
+
interface BulkReindexOptions {
|
|
2064
|
+
collection?: string;
|
|
2065
|
+
recreateCollections?: boolean;
|
|
2066
|
+
}
|
|
2067
|
+
interface ReindexStatus {
|
|
2068
|
+
jobId: string;
|
|
2069
|
+
status: 'queued' | 'processing' | 'completed' | 'failed';
|
|
2070
|
+
progress?: number;
|
|
2071
|
+
error?: string;
|
|
2072
|
+
}
|
|
2073
|
+
declare class MAKEMINDSearch {
|
|
2074
|
+
private apiClient;
|
|
2075
|
+
private getTenantId;
|
|
2076
|
+
constructor(config: MAKEMINDSearchConfig);
|
|
2077
|
+
query(options: SearchQueryOptions): Promise<SearchResult>;
|
|
2078
|
+
advanced(options: AdvancedSearchOptions): Promise<SearchResult>;
|
|
2079
|
+
suggestions(options: SearchSuggestionOptions): Promise<string[]>;
|
|
2080
|
+
getAnalytics(options?: {
|
|
2081
|
+
startDate?: string;
|
|
2082
|
+
endDate?: string;
|
|
2083
|
+
}): Promise<Record<string, unknown>>;
|
|
2084
|
+
bulkReindex(options?: BulkReindexOptions): Promise<{
|
|
2085
|
+
jobId: string;
|
|
2086
|
+
}>;
|
|
2087
|
+
getBulkReindexStatus(options: {
|
|
2088
|
+
jobId: string;
|
|
2089
|
+
}): Promise<ReindexStatus>;
|
|
2090
|
+
}
|
|
2091
|
+
|
|
2092
|
+
/**
|
|
2093
|
+
* MAKEMINDApps - App Builder SDK Service
|
|
2094
|
+
*
|
|
2095
|
+
* SDK service for the App Builder feature.
|
|
2096
|
+
* Provides methods for managing apps, pages, publishing, and domains.
|
|
2097
|
+
*
|
|
2098
|
+
* @see docs/03_DDD/ui-tenant-portal/08-app-builder.md
|
|
2099
|
+
*/
|
|
2100
|
+
|
|
2101
|
+
type AppStatus = 'draft' | 'published' | 'archived';
|
|
2102
|
+
type LayoutType = 'blank' | 'sidebar' | 'topnav' | 'dashboard' | 'centered';
|
|
2103
|
+
type SSLStatus = 'pending' | 'provisioning' | 'active' | 'expired' | 'failed';
|
|
2104
|
+
type CustomDomainStatus = 'pending' | 'verifying' | 'active' | 'failed';
|
|
2105
|
+
/** Where a hostname's traffic is routed once it reaches the domain-serving edge. */
|
|
2106
|
+
type DomainTargetKind = 'marketplace-server' | 'tenant-home' | 'external-url' | 'relay';
|
|
2107
|
+
/**
|
|
2108
|
+
* Optional generic reverse-proxy routing target for a hostname: a
|
|
2109
|
+
* marketplace server, a tenant's own home app, an external URL, or a relay.
|
|
2110
|
+
* Passed to `addSubdomain`, `addCustomDomain`, and
|
|
2111
|
+
* `registerDomainForSubTenant`; a registered domain with no `target` is
|
|
2112
|
+
* still a valid entry, just unresolvable for proxying until one is set.
|
|
2113
|
+
*
|
|
2114
|
+
* Requires domain-service activation. The control-plane call is live, but a
|
|
2115
|
+
* registered domain/target does not serve traffic until the domain-serving
|
|
2116
|
+
* edge is provisioned (Phase 2). Custom and nested (sub-tenant) domains
|
|
2117
|
+
* additionally require an active domain entitlement (paid SKU); pricing is
|
|
2118
|
+
* not yet set. Subdomains are free.
|
|
2119
|
+
*/
|
|
2120
|
+
/** An address that opens an MCP origin, as returned by the entry operations. */
|
|
2121
|
+
interface WebEntrySummary {
|
|
2122
|
+
/** The hostname the platform minted and reserved. */
|
|
2123
|
+
host: string;
|
|
2124
|
+
/** The address a visitor opens. */
|
|
2125
|
+
url: string;
|
|
2126
|
+
/** What the renderer connects to once it boots. */
|
|
2127
|
+
origin: {
|
|
2128
|
+
kind: 'app' | 'server' | 'bundle';
|
|
2129
|
+
ref: string;
|
|
2130
|
+
};
|
|
2131
|
+
/** Who owns the entry. A parameter, not a fixed scope. */
|
|
2132
|
+
party: {
|
|
2133
|
+
kind: 'tenant' | 'euid' | 'ref';
|
|
2134
|
+
id: string;
|
|
2135
|
+
};
|
|
2136
|
+
/** Feeds both the share metadata and the boot declaration. */
|
|
2137
|
+
display?: {
|
|
2138
|
+
name?: string;
|
|
2139
|
+
description?: string;
|
|
2140
|
+
iconUrl?: string;
|
|
2141
|
+
};
|
|
2142
|
+
status: string;
|
|
2143
|
+
}
|
|
2144
|
+
interface DomainTarget {
|
|
2145
|
+
kind: DomainTargetKind;
|
|
2146
|
+
ref: string;
|
|
2147
|
+
}
|
|
2148
|
+
interface ThemeConfig {
|
|
2149
|
+
mode: 'light' | 'dark' | 'system';
|
|
2150
|
+
primaryColor: string;
|
|
2151
|
+
secondaryColor: string;
|
|
2152
|
+
fontFamily: string;
|
|
2153
|
+
borderRadius: 'none' | 'sm' | 'md' | 'lg' | 'full';
|
|
2154
|
+
density: 'compact' | 'normal' | 'comfortable';
|
|
2155
|
+
logoUrl?: string;
|
|
2156
|
+
faviconUrl?: string;
|
|
2157
|
+
customCss?: string;
|
|
2158
|
+
}
|
|
2159
|
+
interface AuthConfig {
|
|
2160
|
+
enabled: boolean;
|
|
2161
|
+
providers: ('email' | 'google' | 'apple' | 'microsoft' | 'saml')[];
|
|
2162
|
+
signupEnabled: boolean;
|
|
2163
|
+
requireEmailVerification: boolean;
|
|
2164
|
+
mfaEnabled: boolean;
|
|
2165
|
+
sessionTimeout: number;
|
|
2166
|
+
}
|
|
2167
|
+
interface PWAConfig {
|
|
2168
|
+
enabled: boolean;
|
|
2169
|
+
name: string;
|
|
2170
|
+
shortName: string;
|
|
2171
|
+
description: string;
|
|
2172
|
+
themeColor: string;
|
|
2173
|
+
backgroundColor: string;
|
|
2174
|
+
display: 'standalone' | 'fullscreen' | 'minimal-ui' | 'browser';
|
|
2175
|
+
orientation: 'portrait' | 'landscape' | 'any';
|
|
2176
|
+
offlineEnabled: boolean;
|
|
2177
|
+
pushEnabled: boolean;
|
|
2178
|
+
}
|
|
2179
|
+
interface AppSettings {
|
|
2180
|
+
theme?: Partial<ThemeConfig>;
|
|
2181
|
+
auth?: Partial<AuthConfig>;
|
|
2182
|
+
pwa?: Partial<PWAConfig>;
|
|
2183
|
+
seo?: {
|
|
2184
|
+
title?: string;
|
|
2185
|
+
description?: string;
|
|
2186
|
+
ogImage?: string;
|
|
2187
|
+
};
|
|
2188
|
+
localization?: {
|
|
2189
|
+
defaultLocale?: string;
|
|
2190
|
+
supportedLocales?: string[];
|
|
2191
|
+
};
|
|
2192
|
+
}
|
|
2193
|
+
interface DomainConfig {
|
|
2194
|
+
subdomain: string;
|
|
2195
|
+
customDomain: string | null;
|
|
2196
|
+
customDomainStatus: CustomDomainStatus;
|
|
2197
|
+
sslStatus: SSLStatus;
|
|
2198
|
+
}
|
|
2199
|
+
interface App {
|
|
2200
|
+
id: string;
|
|
2201
|
+
tenantId: string;
|
|
2202
|
+
name: string;
|
|
2203
|
+
displayName: string;
|
|
2204
|
+
description: string;
|
|
2205
|
+
icon: string;
|
|
2206
|
+
status: AppStatus;
|
|
2207
|
+
version: number;
|
|
2208
|
+
publishedVersion: number | null;
|
|
2209
|
+
domain: DomainConfig;
|
|
2210
|
+
settings: AppSettings;
|
|
2211
|
+
createdAt: string;
|
|
2212
|
+
createdBy: string;
|
|
2213
|
+
updatedAt: string;
|
|
2214
|
+
updatedBy: string;
|
|
2215
|
+
}
|
|
2216
|
+
interface LayoutConfig {
|
|
2217
|
+
sidebarWidth?: number;
|
|
2218
|
+
sidebarCollapsible?: boolean;
|
|
2219
|
+
headerHeight?: number;
|
|
2220
|
+
footerHeight?: number;
|
|
2221
|
+
contentMaxWidth?: number;
|
|
2222
|
+
}
|
|
2223
|
+
interface PageSEO {
|
|
2224
|
+
title: string;
|
|
2225
|
+
description: string;
|
|
2226
|
+
ogImage?: string;
|
|
2227
|
+
noIndex?: boolean;
|
|
2228
|
+
}
|
|
2229
|
+
/**
|
|
2230
|
+
* A node of a builder page, as stored and as the API returns it.
|
|
2231
|
+
*
|
|
2232
|
+
* This described nine of the tree's fields while the editor writes fifteen:
|
|
2233
|
+
* `dataBinding`, `validation`, `a11y` and `conditions.className` were absent
|
|
2234
|
+
* entirely. TypeScript does not delete what it cannot see, so a round trip
|
|
2235
|
+
* through `getPage`/`updatePage` kept them — but a consumer BUILDING a node
|
|
2236
|
+
* from this type had no way to express a binding or a validation rule, and
|
|
2237
|
+
* one rebuilding a node field-by-field dropped them silently.
|
|
2238
|
+
*
|
|
2239
|
+
* `type` stays `string` rather than the editor's 108-member union: this
|
|
2240
|
+
* describes a REST payload, and the palette must be able to grow without
|
|
2241
|
+
* every SDK consumer needing a new release to accept the new type.
|
|
2242
|
+
*
|
|
2243
|
+
* Kept in step with `@makemind/app-builder-ui`'s `ComponentNode` by
|
|
2244
|
+
* `src/__tests__/component-node-parity.test.ts`.
|
|
2245
|
+
*/
|
|
2246
|
+
interface ComponentNode {
|
|
2247
|
+
id: string;
|
|
2248
|
+
type: string;
|
|
2249
|
+
name: string;
|
|
2250
|
+
props: Record<string, unknown>;
|
|
2251
|
+
styles: Record<string, unknown>;
|
|
2252
|
+
children?: ComponentNode[];
|
|
2253
|
+
conditions?: {
|
|
2254
|
+
visible?: string;
|
|
2255
|
+
enabled?: string;
|
|
2256
|
+
className?: string;
|
|
2257
|
+
};
|
|
2258
|
+
events?: Record<string, unknown[]>;
|
|
2259
|
+
dataBinding?: {
|
|
2260
|
+
source: string;
|
|
2261
|
+
field: string;
|
|
2262
|
+
transform?: string;
|
|
2263
|
+
};
|
|
2264
|
+
validation?: Array<{
|
|
2265
|
+
type: string;
|
|
2266
|
+
value?: unknown;
|
|
2267
|
+
message: string;
|
|
2268
|
+
}>;
|
|
2269
|
+
a11y?: {
|
|
2270
|
+
label?: string;
|
|
2271
|
+
description?: string;
|
|
2272
|
+
role?: string;
|
|
2273
|
+
};
|
|
2274
|
+
}
|
|
2275
|
+
interface DataSource {
|
|
2276
|
+
id: string;
|
|
2277
|
+
name: string;
|
|
2278
|
+
type: 'query' | 'document' | 'api' | 'flow' | 'variable' | 'realtime';
|
|
2279
|
+
config: Record<string, unknown>;
|
|
2280
|
+
}
|
|
2281
|
+
interface PageVariable {
|
|
2282
|
+
name: string;
|
|
2283
|
+
type: 'string' | 'number' | 'boolean' | 'object' | 'array';
|
|
2284
|
+
defaultValue: unknown;
|
|
2285
|
+
}
|
|
2286
|
+
interface Page {
|
|
2287
|
+
id: string;
|
|
2288
|
+
appId: string;
|
|
2289
|
+
name: string;
|
|
2290
|
+
path: string;
|
|
2291
|
+
title: string;
|
|
2292
|
+
description: string;
|
|
2293
|
+
isHomePage: boolean;
|
|
2294
|
+
isPublic: boolean;
|
|
2295
|
+
accessRoles: string[];
|
|
2296
|
+
layout: {
|
|
2297
|
+
type: LayoutType;
|
|
2298
|
+
config: LayoutConfig;
|
|
2299
|
+
};
|
|
2300
|
+
components: ComponentNode[];
|
|
2301
|
+
dataSources: DataSource[];
|
|
2302
|
+
variables: PageVariable[];
|
|
2303
|
+
seo: PageSEO;
|
|
2304
|
+
order: number;
|
|
2305
|
+
createdAt: string;
|
|
2306
|
+
updatedAt: string;
|
|
2307
|
+
}
|
|
2308
|
+
interface AppVersion {
|
|
2309
|
+
id: string;
|
|
2310
|
+
appId: string;
|
|
2311
|
+
version: number;
|
|
2312
|
+
changelog: string;
|
|
2313
|
+
createdAt: string;
|
|
2314
|
+
createdBy: string;
|
|
2315
|
+
}
|
|
2316
|
+
interface DNSRecord {
|
|
2317
|
+
type: 'CNAME' | 'TXT' | 'A' | 'AAAA';
|
|
2318
|
+
name: string;
|
|
2319
|
+
value: string;
|
|
2320
|
+
ttl: number;
|
|
2321
|
+
}
|
|
2322
|
+
interface DomainStatus {
|
|
2323
|
+
domain: string;
|
|
2324
|
+
type: 'subdomain' | 'custom';
|
|
2325
|
+
status: string;
|
|
2326
|
+
sslStatus: SSLStatus;
|
|
2327
|
+
}
|
|
2328
|
+
/** Registry status of a delegated (sub-tenant) domain entry. */
|
|
2329
|
+
type SubTenantDomainStatus = 'pending' | 'verifying' | 'active' | 'suspended' | 'deleted';
|
|
2330
|
+
/**
|
|
2331
|
+
* A Firestore Timestamp as it crosses the wire — JSON has no native
|
|
2332
|
+
* timestamp type, so the Admin SDK's `Timestamp` class serializes to this
|
|
2333
|
+
* `{ _seconds, _nanoseconds }` shape.
|
|
2334
|
+
*/
|
|
2335
|
+
interface SerializedTimestamp {
|
|
2336
|
+
_seconds: number;
|
|
2337
|
+
_nanoseconds: number;
|
|
2338
|
+
}
|
|
2339
|
+
/** One entry returned by `listSubTenantDomains`. */
|
|
2340
|
+
interface SubTenantDomainSummary {
|
|
2341
|
+
domain: string;
|
|
2342
|
+
type: 'subdomain' | 'custom';
|
|
2343
|
+
appId: string;
|
|
2344
|
+
subTenantId?: string;
|
|
2345
|
+
status: SubTenantDomainStatus;
|
|
2346
|
+
sslStatus: SSLStatus;
|
|
2347
|
+
createdAt: SerializedTimestamp;
|
|
2348
|
+
}
|
|
2349
|
+
interface AppAnalytics {
|
|
2350
|
+
appId: string;
|
|
2351
|
+
period: string;
|
|
2352
|
+
pageViews: number;
|
|
2353
|
+
uniqueVisitors: number;
|
|
2354
|
+
apiCalls: number;
|
|
2355
|
+
errors: number;
|
|
2356
|
+
avgLoadTime: number;
|
|
2357
|
+
topPages: Array<{
|
|
2358
|
+
path: string;
|
|
2359
|
+
views: number;
|
|
2360
|
+
}>;
|
|
2361
|
+
}
|
|
2362
|
+
interface CreateAppParams {
|
|
2363
|
+
name: string;
|
|
2364
|
+
displayName?: string;
|
|
2365
|
+
description?: string;
|
|
2366
|
+
icon?: string;
|
|
2367
|
+
type?: 'web' | 'mobile' | 'backend' | 'agent';
|
|
2368
|
+
}
|
|
2369
|
+
interface UpdateAppParams {
|
|
2370
|
+
name?: string;
|
|
2371
|
+
displayName?: string;
|
|
2372
|
+
description?: string;
|
|
2373
|
+
icon?: string;
|
|
2374
|
+
status?: AppStatus;
|
|
2375
|
+
settings?: AppSettings;
|
|
2376
|
+
}
|
|
2377
|
+
interface ListAppsParams {
|
|
2378
|
+
status?: AppStatus;
|
|
2379
|
+
limit?: number;
|
|
2380
|
+
startAfter?: string;
|
|
2381
|
+
}
|
|
2382
|
+
interface CreatePageParams {
|
|
2383
|
+
name: string;
|
|
2384
|
+
path: string;
|
|
2385
|
+
title?: string;
|
|
2386
|
+
description?: string;
|
|
2387
|
+
isHomePage?: boolean;
|
|
2388
|
+
isPublic?: boolean;
|
|
2389
|
+
layout?: {
|
|
2390
|
+
type: LayoutType;
|
|
2391
|
+
config?: LayoutConfig;
|
|
2392
|
+
};
|
|
2393
|
+
}
|
|
2394
|
+
interface UpdatePageParams {
|
|
2395
|
+
name?: string;
|
|
2396
|
+
path?: string;
|
|
2397
|
+
title?: string;
|
|
2398
|
+
description?: string;
|
|
2399
|
+
isHomePage?: boolean;
|
|
2400
|
+
isPublic?: boolean;
|
|
2401
|
+
accessRoles?: string[];
|
|
2402
|
+
layout?: {
|
|
2403
|
+
type: LayoutType;
|
|
2404
|
+
config?: LayoutConfig;
|
|
2405
|
+
};
|
|
2406
|
+
components?: ComponentNode[];
|
|
2407
|
+
dataSources?: DataSource[];
|
|
2408
|
+
variables?: PageVariable[];
|
|
2409
|
+
seo?: PageSEO;
|
|
2410
|
+
}
|
|
2411
|
+
interface MAKEMINDAppsConfig extends MAKEMINDConfig {
|
|
2412
|
+
apiClient: ApiClient;
|
|
2413
|
+
tenantId: () => string | null;
|
|
2414
|
+
}
|
|
2415
|
+
declare class MAKEMINDApps {
|
|
2416
|
+
private apiClient;
|
|
2417
|
+
private getTenantId;
|
|
2418
|
+
constructor(config: MAKEMINDAppsConfig);
|
|
2419
|
+
private get tenantId();
|
|
2420
|
+
createApp(params: CreateAppParams): Promise<{
|
|
2421
|
+
appId: string;
|
|
2422
|
+
}>;
|
|
2423
|
+
getApp(appId: string): Promise<App | null>;
|
|
2424
|
+
listApps(params?: ListAppsParams): Promise<{
|
|
2425
|
+
apps: App[];
|
|
2426
|
+
hasMore: boolean;
|
|
2427
|
+
nextCursor?: string;
|
|
2428
|
+
}>;
|
|
2429
|
+
updateApp(appId: string, params: UpdateAppParams): Promise<void>;
|
|
2430
|
+
deleteApp(appId: string, hardDelete?: boolean): Promise<void>;
|
|
2431
|
+
duplicateApp(appId: string, newName: string): Promise<{
|
|
2432
|
+
appId: string;
|
|
2433
|
+
}>;
|
|
2434
|
+
onAppSnapshot(appId: string, callback: (app: App | null) => void): Unsubscribe;
|
|
2435
|
+
createPage(appId: string, params: CreatePageParams): Promise<{
|
|
2436
|
+
pageId: string;
|
|
2437
|
+
}>;
|
|
2438
|
+
getPage(appId: string, pageId: string): Promise<Page | null>;
|
|
2439
|
+
listPages(appId: string): Promise<Page[]>;
|
|
2440
|
+
updatePage(appId: string, pageId: string, params: UpdatePageParams): Promise<void>;
|
|
2441
|
+
deletePage(appId: string, pageId: string): Promise<void>;
|
|
2442
|
+
reorderPages(appId: string, order: string[]): Promise<void>;
|
|
2443
|
+
duplicatePage(appId: string, pageId: string, newName?: string, newPath?: string): Promise<{
|
|
2444
|
+
pageId: string;
|
|
2445
|
+
}>;
|
|
2446
|
+
publish(appId: string, changelog?: string): Promise<{
|
|
2447
|
+
success: boolean;
|
|
2448
|
+
version: number;
|
|
2449
|
+
publishedAt: string;
|
|
2450
|
+
}>;
|
|
2451
|
+
unpublish(appId: string): Promise<void>;
|
|
2452
|
+
rollback(appId: string, targetVersion: number): Promise<{
|
|
2453
|
+
success: boolean;
|
|
2454
|
+
currentVersion: number;
|
|
2455
|
+
}>;
|
|
2456
|
+
getVersions(appId: string, limit?: number): Promise<AppVersion[]>;
|
|
2457
|
+
getVersionDetail(appId: string, versionId: string): Promise<AppVersion & {
|
|
2458
|
+
snapshot: Record<string, unknown>;
|
|
2459
|
+
}>;
|
|
2460
|
+
compareVersions(appId: string, version1: number, version2: number): Promise<{
|
|
2461
|
+
version1: {
|
|
2462
|
+
version: number;
|
|
2463
|
+
changelog: string;
|
|
2464
|
+
createdAt: string;
|
|
2465
|
+
};
|
|
2466
|
+
version2: {
|
|
2467
|
+
version: number;
|
|
2468
|
+
changelog: string;
|
|
2469
|
+
createdAt: string;
|
|
2470
|
+
};
|
|
2471
|
+
changes: {
|
|
2472
|
+
pagesAdded: number;
|
|
2473
|
+
pagesRemoved: number;
|
|
2474
|
+
pagesModified: number;
|
|
2475
|
+
addedPageNames: string[];
|
|
2476
|
+
removedPageNames: string[];
|
|
2477
|
+
};
|
|
2478
|
+
}>;
|
|
2479
|
+
/**
|
|
2480
|
+
* Add a platform subdomain (`<subdomain>.<platform-host>`) for an app.
|
|
2481
|
+
* `target` is an optional generic reverse-proxy routing target.
|
|
2482
|
+
*
|
|
2483
|
+
* Requires domain-service activation. The control-plane call is live, but
|
|
2484
|
+
* a registered domain/target does not serve traffic until the
|
|
2485
|
+
* domain-serving edge is provisioned (Phase 2). Custom and nested
|
|
2486
|
+
* (sub-tenant) domains additionally require an active domain entitlement
|
|
2487
|
+
* (paid SKU); pricing is not yet set. Subdomains are free.
|
|
2488
|
+
*/
|
|
2489
|
+
addSubdomain(appId: string, subdomain: string, target?: DomainTarget): Promise<{
|
|
2490
|
+
success: boolean;
|
|
2491
|
+
domain: string;
|
|
2492
|
+
}>;
|
|
2493
|
+
/**
|
|
2494
|
+
* Add a custom (BYO) domain for an app. Returns a verification token and
|
|
2495
|
+
* DNS records the caller must publish before `verifyDomain` will pass.
|
|
2496
|
+
* `target` is an optional generic reverse-proxy routing target.
|
|
2497
|
+
*
|
|
2498
|
+
* Requires domain-service activation. The control-plane call is live, but
|
|
2499
|
+
* a registered domain/target does not serve traffic until the
|
|
2500
|
+
* domain-serving edge is provisioned (Phase 2). Custom and nested
|
|
2501
|
+
* (sub-tenant) domains additionally require an active domain entitlement
|
|
2502
|
+
* (paid SKU); pricing is not yet set. Subdomains are free.
|
|
2503
|
+
*/
|
|
2504
|
+
addCustomDomain(appId: string, domain: string, target?: DomainTarget): Promise<{
|
|
2505
|
+
success: boolean;
|
|
2506
|
+
verificationToken: string;
|
|
2507
|
+
dnsRecords: DNSRecord[];
|
|
2508
|
+
}>;
|
|
2509
|
+
verifyDomain(appId: string, domain: string): Promise<{
|
|
2510
|
+
verified: boolean;
|
|
2511
|
+
sslStatus: SSLStatus;
|
|
2512
|
+
error?: string;
|
|
2513
|
+
}>;
|
|
2514
|
+
removeDomain(appId: string, domain: string): Promise<void>;
|
|
2515
|
+
getDomainStatus(appId: string): Promise<DomainStatus[]>;
|
|
2516
|
+
/**
|
|
2517
|
+
* Mint an address for an app.
|
|
2518
|
+
*
|
|
2519
|
+
* The caller proposes a **label**, not a hostname: the platform derives and
|
|
2520
|
+
* reserves the host under its own uniqueness and reserved-name rules. A
|
|
2521
|
+
* caller cannot claim a hostname it does not own, and the origin is derived
|
|
2522
|
+
* from the app being bound rather than supplied — the whole capability rests
|
|
2523
|
+
* on the issuer deciding the origin, and a free-text URL field is exactly how
|
|
2524
|
+
* that property gets lost.
|
|
2525
|
+
*
|
|
2526
|
+
* `display` feeds both the share metadata (`og:*`) and the boot declaration,
|
|
2527
|
+
* so a link preview and the running app cannot disagree.
|
|
2528
|
+
*/
|
|
2529
|
+
mintWebEntry(params: {
|
|
2530
|
+
label: string;
|
|
2531
|
+
/**
|
|
2532
|
+
* `app` is the resident case: `ref` is an appId and the platform derives
|
|
2533
|
+
* its own MCP endpoint from it, so there is no address for a caller to
|
|
2534
|
+
* supply — and therefore none to point elsewhere. `server` binds an
|
|
2535
|
+
* external endpoint the party has proven it controls.
|
|
2536
|
+
*/
|
|
2537
|
+
origin: {
|
|
2538
|
+
kind: 'app' | 'server' | 'bundle';
|
|
2539
|
+
ref: string;
|
|
2540
|
+
};
|
|
2541
|
+
/**
|
|
2542
|
+
* Who the address is for. **Required, and not defaulted anywhere.**
|
|
2543
|
+
*
|
|
2544
|
+
* An address states its party, and a payment served from it pays that
|
|
2545
|
+
* party. The platform used to fill this in from the calling tenant, which
|
|
2546
|
+
* meant an address selling on a seller's behalf collected for the tenant
|
|
2547
|
+
* because nobody said otherwise. Sending nothing is refused; a shop
|
|
2548
|
+
* selling its own goods says `{ kind: 'tenant', id: '<its id>' }`.
|
|
2549
|
+
*/
|
|
2550
|
+
party: {
|
|
2551
|
+
kind: 'tenant' | 'euid' | 'ref';
|
|
2552
|
+
id: string;
|
|
2553
|
+
};
|
|
2554
|
+
display?: {
|
|
2555
|
+
name?: string;
|
|
2556
|
+
description?: string;
|
|
2557
|
+
iconUrl?: string;
|
|
2558
|
+
};
|
|
2559
|
+
}): Promise<WebEntrySummary>;
|
|
2560
|
+
/** Read one entry the caller owns. Requires `domains:read`. */
|
|
2561
|
+
getWebEntry(host: string): Promise<WebEntrySummary>;
|
|
2562
|
+
/** List the caller's entries, optionally narrowed to one party. Requires `domains:read`. */
|
|
2563
|
+
listWebEntries(params?: {
|
|
2564
|
+
party?: {
|
|
2565
|
+
kind: 'tenant' | 'euid' | 'ref';
|
|
2566
|
+
id: string;
|
|
2567
|
+
};
|
|
2568
|
+
}): Promise<{
|
|
2569
|
+
entries: WebEntrySummary[];
|
|
2570
|
+
}>;
|
|
2571
|
+
/**
|
|
2572
|
+
* Repoint an entry at a different (still proven) origin, or change how it
|
|
2573
|
+
* appears when shared. The address itself is immutable — a different address
|
|
2574
|
+
* is a different entry.
|
|
2575
|
+
*/
|
|
2576
|
+
updateWebEntry(params: {
|
|
2577
|
+
host: string;
|
|
2578
|
+
origin?: {
|
|
2579
|
+
kind: 'app' | 'server' | 'bundle';
|
|
2580
|
+
ref: string;
|
|
2581
|
+
};
|
|
2582
|
+
display?: {
|
|
2583
|
+
name?: string;
|
|
2584
|
+
description?: string;
|
|
2585
|
+
iconUrl?: string;
|
|
2586
|
+
};
|
|
2587
|
+
}): Promise<WebEntrySummary>;
|
|
2588
|
+
/** Retire an entry — the address stops serving immediately. Requires `domains:write`. */
|
|
2589
|
+
retireWebEntry(host: string): Promise<{
|
|
2590
|
+
success: true;
|
|
2591
|
+
host: string;
|
|
2592
|
+
}>;
|
|
2593
|
+
/**
|
|
2594
|
+
* Register a custom domain on behalf of one of the caller tenant's
|
|
2595
|
+
* sub-tenants ("custom domains for your customers"). `parentTenantId`,
|
|
2596
|
+
* when provided, must equal the caller's own tenantId — the server never
|
|
2597
|
+
* trusts a client-supplied parent tenant for cross-tenant registration.
|
|
2598
|
+
* Requires API key scope `domains:write`.
|
|
2599
|
+
*
|
|
2600
|
+
* Requires domain-service activation. The control-plane call is live, but
|
|
2601
|
+
* a registered domain/target does not serve traffic until the
|
|
2602
|
+
* domain-serving edge is provisioned (Phase 2). Custom and nested
|
|
2603
|
+
* (sub-tenant) domains additionally require an active domain entitlement
|
|
2604
|
+
* (paid SKU); pricing is not yet set. Subdomains are free.
|
|
2605
|
+
*/
|
|
2606
|
+
registerDomainForSubTenant(params: {
|
|
2607
|
+
appId: string;
|
|
2608
|
+
domain: string;
|
|
2609
|
+
subTenantId: string;
|
|
2610
|
+
parentTenantId?: string;
|
|
2611
|
+
target?: DomainTarget;
|
|
2612
|
+
}): Promise<{
|
|
2613
|
+
success: boolean;
|
|
2614
|
+
domain: string;
|
|
2615
|
+
subTenantId: string;
|
|
2616
|
+
verificationToken: string;
|
|
2617
|
+
dnsRecords: DNSRecord[];
|
|
2618
|
+
}>;
|
|
2619
|
+
/**
|
|
2620
|
+
* Verify a delegated sub-tenant domain's DNS configuration.
|
|
2621
|
+
* Requires API key scope `domains:write`.
|
|
2622
|
+
*
|
|
2623
|
+
* Requires domain-service activation. The control-plane call is live, but
|
|
2624
|
+
* a registered domain/target does not serve traffic until the
|
|
2625
|
+
* domain-serving edge is provisioned (Phase 2). Custom and nested
|
|
2626
|
+
* (sub-tenant) domains additionally require an active domain entitlement
|
|
2627
|
+
* (paid SKU); pricing is not yet set. Subdomains are free.
|
|
2628
|
+
*/
|
|
2629
|
+
verifyDomainForSubTenant(domain: string): Promise<{
|
|
2630
|
+
verified: boolean;
|
|
2631
|
+
sslStatus: SSLStatus;
|
|
2632
|
+
error?: string;
|
|
2633
|
+
}>;
|
|
2634
|
+
/**
|
|
2635
|
+
* List the caller tenant's delegated sub-tenant domains, optionally
|
|
2636
|
+
* filtered to one `subTenantId`. Requires API key scope `domains:read`.
|
|
2637
|
+
*
|
|
2638
|
+
* Requires domain-service activation. The control-plane call is live, but
|
|
2639
|
+
* a registered domain/target does not serve traffic until the
|
|
2640
|
+
* domain-serving edge is provisioned (Phase 2). Custom and nested
|
|
2641
|
+
* (sub-tenant) domains additionally require an active domain entitlement
|
|
2642
|
+
* (paid SKU); pricing is not yet set. Subdomains are free.
|
|
2643
|
+
*/
|
|
2644
|
+
listSubTenantDomains(subTenantId?: string): Promise<{
|
|
2645
|
+
domains: SubTenantDomainSummary[];
|
|
2646
|
+
}>;
|
|
2647
|
+
/**
|
|
2648
|
+
* Remove a delegated sub-tenant domain. Requires API key scope
|
|
2649
|
+
* `domains:write`.
|
|
2650
|
+
*
|
|
2651
|
+
* Requires domain-service activation. The control-plane call is live, but
|
|
2652
|
+
* a registered domain/target does not serve traffic until the
|
|
2653
|
+
* domain-serving edge is provisioned (Phase 2). Custom and nested
|
|
2654
|
+
* (sub-tenant) domains additionally require an active domain entitlement
|
|
2655
|
+
* (paid SKU); pricing is not yet set. Subdomains are free.
|
|
2656
|
+
*/
|
|
2657
|
+
removeSubTenantDomain(domain: string): Promise<{
|
|
2658
|
+
success: boolean;
|
|
2659
|
+
}>;
|
|
2660
|
+
getAnalytics(appId: string, params?: {
|
|
2661
|
+
startDate?: string;
|
|
2662
|
+
endDate?: string;
|
|
2663
|
+
}): Promise<AppAnalytics>;
|
|
2664
|
+
generateUI(prompt: string, context?: Record<string, unknown>, appId?: string): Promise<{
|
|
2665
|
+
components: ComponentNode[];
|
|
2666
|
+
}>;
|
|
2667
|
+
suggestActions(appId: string, componentType?: string, context?: Record<string, unknown>): Promise<{
|
|
2668
|
+
actions: unknown[];
|
|
2669
|
+
}>;
|
|
2670
|
+
startSession(appId: string, pageId: string): Promise<{
|
|
2671
|
+
sessionToken: string;
|
|
2672
|
+
wsEndpoint: string;
|
|
2673
|
+
}>;
|
|
2674
|
+
addComment(appId: string, pageId: string, componentId: string, content: string, threadId?: string): Promise<{
|
|
2675
|
+
commentId: string;
|
|
2676
|
+
}>;
|
|
2677
|
+
resolveComment(appId: string, pageId: string, commentId: string): Promise<void>;
|
|
2678
|
+
}
|
|
2679
|
+
|
|
2680
|
+
/**
|
|
2681
|
+
* MAKEMIND SDK - Marketplace Service
|
|
2682
|
+
*
|
|
2683
|
+
* Client-side SDK for the SaaS Marketplace feature.
|
|
2684
|
+
* Provides methods for browsing, installing, and publishing marketplace apps.
|
|
2685
|
+
*
|
|
2686
|
+
* @see docs/03_DDD/infra-sdk.md
|
|
2687
|
+
*/
|
|
2688
|
+
|
|
2689
|
+
interface MAKEMINDMarketplaceConfig extends MAKEMINDConfig {
|
|
2690
|
+
apiClient: ApiClient;
|
|
2691
|
+
tenantId: () => string | null;
|
|
2692
|
+
}
|
|
2693
|
+
interface SearchOptions {
|
|
2694
|
+
query?: string;
|
|
2695
|
+
category?: string;
|
|
2696
|
+
tags?: string[];
|
|
2697
|
+
pricingModel?: string[];
|
|
2698
|
+
sortBy?: 'relevance' | 'rating' | 'installs' | 'newest' | 'price_asc' | 'price_desc';
|
|
2699
|
+
page?: number;
|
|
2700
|
+
limit?: number;
|
|
2701
|
+
}
|
|
2702
|
+
interface InstallResult {
|
|
2703
|
+
bindingId: string;
|
|
2704
|
+
status: string;
|
|
2705
|
+
trialExpiresAt?: string;
|
|
2706
|
+
}
|
|
2707
|
+
interface ReviewInput {
|
|
2708
|
+
listingId: string;
|
|
2709
|
+
rating: number;
|
|
2710
|
+
title?: string;
|
|
2711
|
+
body?: string;
|
|
2712
|
+
}
|
|
2713
|
+
interface PublisherProfileInput {
|
|
2714
|
+
displayName: string;
|
|
2715
|
+
description: string;
|
|
2716
|
+
logoUrl: string;
|
|
2717
|
+
websiteUrl?: string;
|
|
2718
|
+
supportEmail: string;
|
|
2719
|
+
}
|
|
2720
|
+
declare class MAKEMINDMarketplace {
|
|
2721
|
+
private apiClient;
|
|
2722
|
+
private getTenantId;
|
|
2723
|
+
constructor(config: MAKEMINDMarketplaceConfig);
|
|
2724
|
+
search(options?: SearchOptions): Promise<unknown>;
|
|
2725
|
+
getDetail(listingId: string): Promise<unknown>;
|
|
2726
|
+
browseCategory(categorySlug: string, options?: Omit<SearchOptions, 'category'>): Promise<unknown>;
|
|
2727
|
+
getFeatured(): Promise<unknown>;
|
|
2728
|
+
getTrending(): Promise<unknown>;
|
|
2729
|
+
getRecommendations(): Promise<unknown>;
|
|
2730
|
+
listCategories(): Promise<unknown>;
|
|
2731
|
+
install(listingId: string): Promise<InstallResult>;
|
|
2732
|
+
uninstall(listingId: string, cleanupData?: boolean): Promise<unknown>;
|
|
2733
|
+
listInstalled(options?: {
|
|
2734
|
+
status?: string;
|
|
2735
|
+
page?: number;
|
|
2736
|
+
limit?: number;
|
|
2737
|
+
}): Promise<unknown>;
|
|
2738
|
+
updateApp(listingId: string): Promise<unknown>;
|
|
2739
|
+
proxy(bindingId: string, options: {
|
|
2740
|
+
method: string;
|
|
2741
|
+
path: string;
|
|
2742
|
+
body?: unknown;
|
|
2743
|
+
query?: Record<string, string>;
|
|
2744
|
+
}): Promise<unknown>;
|
|
2745
|
+
getApiSpec(bindingId: string): Promise<unknown>;
|
|
2746
|
+
getConfig(bindingId: string): Promise<unknown>;
|
|
2747
|
+
updateConfig(bindingId: string, updates: Record<string, unknown>): Promise<unknown>;
|
|
2748
|
+
issueCredentials(bindingId: string): Promise<unknown>;
|
|
2749
|
+
revokeCredentials(bindingId: string): Promise<unknown>;
|
|
2750
|
+
createReview(input: ReviewInput): Promise<unknown>;
|
|
2751
|
+
updateReview(reviewId: string, listingId: string, updates: {
|
|
2752
|
+
rating?: number;
|
|
2753
|
+
title?: string;
|
|
2754
|
+
body?: string;
|
|
2755
|
+
}): Promise<unknown>;
|
|
2756
|
+
deleteReview(reviewId: string, listingId: string): Promise<unknown>;
|
|
2757
|
+
listReviews(listingId: string, options?: {
|
|
2758
|
+
sortBy?: string;
|
|
2759
|
+
page?: number;
|
|
2760
|
+
limit?: number;
|
|
2761
|
+
}): Promise<unknown>;
|
|
2762
|
+
replyToReview(reviewId: string, listingId: string, body: string): Promise<unknown>;
|
|
2763
|
+
reportReview(reviewId: string, listingId: string, reason: string): Promise<unknown>;
|
|
2764
|
+
voteHelpful(reviewId: string, listingId: string): Promise<unknown>;
|
|
2765
|
+
createPublisherProfile(input: PublisherProfileInput): Promise<unknown>;
|
|
2766
|
+
updatePublisherProfile(updates: Partial<PublisherProfileInput>): Promise<unknown>;
|
|
2767
|
+
getDashboard(): Promise<unknown>;
|
|
2768
|
+
createListing(input: Record<string, unknown>): Promise<unknown>;
|
|
2769
|
+
updateListing(listingId: string, updates: Record<string, unknown>): Promise<unknown>;
|
|
2770
|
+
submitForReview(listingId: string): Promise<unknown>;
|
|
2771
|
+
publishListing(listingId: string): Promise<unknown>;
|
|
2772
|
+
archiveListing(listingId: string): Promise<unknown>;
|
|
2773
|
+
reactivateListing(listingId: string): Promise<unknown>;
|
|
2774
|
+
createVersion(listingId: string, version: string, changelog: string, appVersionId: string, breakingChanges?: boolean): Promise<unknown>;
|
|
2775
|
+
approveListing(listingId: string): Promise<unknown>;
|
|
2776
|
+
rejectListing(listingId: string, reason: string): Promise<unknown>;
|
|
2777
|
+
suspendListing(listingId: string, reason: string): Promise<unknown>;
|
|
2778
|
+
approveVersion(listingId: string, versionId: string): Promise<unknown>;
|
|
2779
|
+
verifyPublisher(tenantId: string): Promise<unknown>;
|
|
2780
|
+
suspendPublisher(tenantId: string, reason: string): Promise<unknown>;
|
|
2781
|
+
reactivatePublisher(tenantId: string): Promise<unknown>;
|
|
2782
|
+
adminCreateCategory(data: {
|
|
2783
|
+
name: string;
|
|
2784
|
+
slug: string;
|
|
2785
|
+
parentId?: string;
|
|
2786
|
+
sortOrder?: number;
|
|
2787
|
+
}): Promise<unknown>;
|
|
2788
|
+
adminUpdateCategory(categoryId: string, data: Record<string, unknown>): Promise<unknown>;
|
|
2789
|
+
adminDeleteCategory(categoryId: string): Promise<unknown>;
|
|
2790
|
+
getAnalytics(params?: {
|
|
2791
|
+
startDate?: string;
|
|
2792
|
+
endDate?: string;
|
|
2793
|
+
granularity?: string;
|
|
2794
|
+
}): Promise<unknown>;
|
|
2795
|
+
getPendingListings(params?: {
|
|
2796
|
+
status?: string;
|
|
2797
|
+
page?: number;
|
|
2798
|
+
limit?: number;
|
|
2799
|
+
}): Promise<unknown>;
|
|
2800
|
+
listPublishers(params?: {
|
|
2801
|
+
status?: string;
|
|
2802
|
+
page?: number;
|
|
2803
|
+
limit?: number;
|
|
2804
|
+
}): Promise<unknown>;
|
|
2805
|
+
}
|
|
2806
|
+
|
|
2807
|
+
interface MAKEMINDClientConfig {
|
|
2808
|
+
apiKey: string;
|
|
2809
|
+
applicationId: string;
|
|
2810
|
+
environment?: 'development' | 'staging' | 'production';
|
|
2811
|
+
baseUrl?: string;
|
|
2812
|
+
/** Gateway API version segment. Defaults to 'v1'. */
|
|
2813
|
+
apiVersion?: string;
|
|
2814
|
+
/**
|
|
2815
|
+
* Optional App Check token provider (first-party apps only). When set, its
|
|
2816
|
+
* token is attached as `X-Firebase-AppCheck` on every gateway call so the app
|
|
2817
|
+
* passes App Check enforcement on pre-login endpoints. Omit for M2M/API-key
|
|
2818
|
+
* integrations — those are exempt from App Check server-side.
|
|
2819
|
+
*/
|
|
2820
|
+
getAppCheckToken?: () => Promise<string | null>;
|
|
2821
|
+
}
|
|
2822
|
+
declare class MAKEMINDClient {
|
|
2823
|
+
private apiClient;
|
|
2824
|
+
private applicationId;
|
|
2825
|
+
private environment;
|
|
2826
|
+
private _auth;
|
|
2827
|
+
private _data;
|
|
2828
|
+
private _logic;
|
|
2829
|
+
private _tenant;
|
|
2830
|
+
private _messaging;
|
|
2831
|
+
private _settlement;
|
|
2832
|
+
private _partners;
|
|
2833
|
+
private _storage;
|
|
2834
|
+
private _ai;
|
|
2835
|
+
private _search;
|
|
2836
|
+
private _apps;
|
|
2837
|
+
private _marketplace;
|
|
2838
|
+
private currentTenantId;
|
|
2839
|
+
private currentUserId;
|
|
2840
|
+
private authToken;
|
|
2841
|
+
constructor(config: MAKEMINDClientConfig);
|
|
2842
|
+
setAuthToken(token: string): void;
|
|
2843
|
+
setUserContext(userId: string, tenantId: string | null): void;
|
|
2844
|
+
get tenantId(): string | null;
|
|
2845
|
+
get userId(): string | null;
|
|
2846
|
+
setTenantContext(tenantId: string): void;
|
|
2847
|
+
getApiClient(): ApiClient;
|
|
2848
|
+
/**
|
|
2849
|
+
* Invoke a platform Callable operation through the gateway RPC dispatch
|
|
2850
|
+
* (`POST /api/v1/call/:operation`). The operation name matches the deployed
|
|
2851
|
+
* Callable key (namespaced groups use `<prefix>-<name>`, e.g.
|
|
2852
|
+
* `settlement-getMRR`; flat exports use the bare name, e.g. `createTenant`).
|
|
2853
|
+
*
|
|
2854
|
+
* This is the platform-operation channel, distinct from `logic.call()` which
|
|
2855
|
+
* runs a tenant-defined logic function. Each operation enforces its own
|
|
2856
|
+
* authorization server-side (platform roles / tenant scopes), so exposing
|
|
2857
|
+
* this method does not bypass access control. Returns the operation's result
|
|
2858
|
+
* value directly (the `{ data }` envelope is already unwrapped).
|
|
2859
|
+
*/
|
|
2860
|
+
call<T = unknown>(operation: string, input?: unknown): Promise<T>;
|
|
2861
|
+
get auth(): MAKEMINDAuth;
|
|
2862
|
+
get data(): MAKEMINDData;
|
|
2863
|
+
get logic(): MAKEMINDLogic;
|
|
2864
|
+
get tenant(): MAKEMINDTenant;
|
|
2865
|
+
get messaging(): MAKEMINDMessaging;
|
|
2866
|
+
get settlement(): MAKEMINDSettlement;
|
|
2867
|
+
get partners(): MAKEMINDPartners;
|
|
2868
|
+
get storage(): MAKEMINDStorage;
|
|
2869
|
+
get ai(): MAKEMINDAI;
|
|
2870
|
+
get search(): MAKEMINDSearch;
|
|
2871
|
+
get apps(): MAKEMINDApps;
|
|
2872
|
+
get marketplace(): MAKEMINDMarketplace;
|
|
2873
|
+
}
|
|
2874
|
+
declare function initializeMAKEMIND(config: MAKEMINDClientConfig): MAKEMINDClient;
|
|
2875
|
+
declare function getMAKEMIND(): MAKEMINDClient;
|
|
2876
|
+
|
|
2877
|
+
/**
|
|
2878
|
+
* The expert guest door — the one SDK surface that carries no credential.
|
|
2879
|
+
*
|
|
2880
|
+
* Deliberately not built on `ApiClient`. That client attaches `X-API-Key` to
|
|
2881
|
+
* every request by construction, and a key in a browser carries
|
|
2882
|
+
* `expert:execute` over the tenant's whole budget. A page embedding an expert
|
|
2883
|
+
* must not be able to ship one by accident, so this talks to the public routes
|
|
2884
|
+
* with its own fetch that has no credential to attach.
|
|
2885
|
+
*
|
|
2886
|
+
* The only attestation is App Check, which the tenant's own web app produces.
|
|
2887
|
+
*
|
|
2888
|
+
* What a guest holds instead of an account is a capability: a token minted on
|
|
2889
|
+
* the first turn and returned once. Whoever holds it holds the thread; losing
|
|
2890
|
+
* it loses the thread, and nothing recovers it — there is no account to recover
|
|
2891
|
+
* into. Say that on any page that opens one.
|
|
2892
|
+
*
|
|
2893
|
+
* @see docs/03_DDD/feat-expert/20-public-consumption-surfaces.md
|
|
2894
|
+
*/
|
|
2895
|
+
interface MAKEMINDExpertsConfig {
|
|
2896
|
+
/** Gateway origin, e.g. `https://api.makemind.app`. */
|
|
2897
|
+
baseUrl: string;
|
|
2898
|
+
/** The tenant whose expert is being consulted. */
|
|
2899
|
+
tenantId: string;
|
|
2900
|
+
/** Supplies an App Check token. Omit only where the tenant has none configured. */
|
|
2901
|
+
appCheck?: () => string | null | Promise<string | null>;
|
|
2902
|
+
/** Injected in tests; defaults to the global. */
|
|
2903
|
+
fetchImpl?: typeof fetch;
|
|
2904
|
+
}
|
|
2905
|
+
interface ExpertAccess {
|
|
2906
|
+
token: string;
|
|
2907
|
+
expiresAt?: unknown;
|
|
2908
|
+
}
|
|
2909
|
+
interface ConsultationConclusion {
|
|
2910
|
+
value: string;
|
|
2911
|
+
origin: 'rule' | 'model';
|
|
2912
|
+
}
|
|
2913
|
+
interface ExpertConsultation {
|
|
2914
|
+
id: string;
|
|
2915
|
+
status: string;
|
|
2916
|
+
/** Present when the expert declined; it is an answer, not a failure. */
|
|
2917
|
+
refusal?: string;
|
|
2918
|
+
synthesis?: {
|
|
2919
|
+
answer?: string;
|
|
2920
|
+
confidence?: number;
|
|
2921
|
+
conclusions?: Record<string, ConsultationConclusion>;
|
|
2922
|
+
};
|
|
2923
|
+
budget?: {
|
|
2924
|
+
tokensUsed: number;
|
|
2925
|
+
tokensMax: number;
|
|
2926
|
+
};
|
|
2927
|
+
[key: string]: unknown;
|
|
2928
|
+
}
|
|
2929
|
+
interface ConsultResult extends ExpertConsultation {
|
|
2930
|
+
access?: ExpertAccess;
|
|
2931
|
+
}
|
|
2932
|
+
interface ExpertTurn {
|
|
2933
|
+
question: string;
|
|
2934
|
+
answer?: string;
|
|
2935
|
+
consultationId: string;
|
|
2936
|
+
}
|
|
2937
|
+
interface ExpertSession {
|
|
2938
|
+
id: string;
|
|
2939
|
+
turns: ExpertTurn[];
|
|
2940
|
+
[key: string]: unknown;
|
|
2941
|
+
}
|
|
2942
|
+
/** The platform's refusal, surfaced with its own name rather than a generic failure. */
|
|
2943
|
+
declare class ExpertDoorError extends Error {
|
|
2944
|
+
readonly code: string;
|
|
2945
|
+
readonly status: number;
|
|
2946
|
+
constructor(code: string, message: string, status: number);
|
|
2947
|
+
}
|
|
2948
|
+
declare class MAKEMINDExperts {
|
|
2949
|
+
private readonly baseUrl;
|
|
2950
|
+
private readonly tenantId;
|
|
2951
|
+
private readonly appCheck?;
|
|
2952
|
+
private readonly fetchImpl;
|
|
2953
|
+
constructor(config: MAKEMINDExpertsConfig);
|
|
2954
|
+
private post;
|
|
2955
|
+
/** One question, one answer, and the capability to read it back. */
|
|
2956
|
+
consult(options: {
|
|
2957
|
+
expertId: string;
|
|
2958
|
+
question: string;
|
|
2959
|
+
facts?: Record<string, unknown>;
|
|
2960
|
+
}): Promise<ConsultResult>;
|
|
2961
|
+
/**
|
|
2962
|
+
* Open a conversation, or resume one whose capability the caller kept.
|
|
2963
|
+
* @param {Object} options The expert to open, or a thread to resume.
|
|
2964
|
+
* @return {ExpertChat} A thread that carries its own capability.
|
|
2965
|
+
*/
|
|
2966
|
+
chat(options: {
|
|
2967
|
+
expertId: string;
|
|
2968
|
+
sessionId?: string;
|
|
2969
|
+
accessToken?: string;
|
|
2970
|
+
}): ExpertChat;
|
|
2971
|
+
/** @internal */
|
|
2972
|
+
converse(body: Record<string, unknown>): Promise<{
|
|
2973
|
+
sessionId: string;
|
|
2974
|
+
consultation: ExpertConsultation;
|
|
2975
|
+
access?: ExpertAccess;
|
|
2976
|
+
}>;
|
|
2977
|
+
getConsultation(options: {
|
|
2978
|
+
consultationId: string;
|
|
2979
|
+
accessToken: string;
|
|
2980
|
+
}): Promise<ExpertConsultation>;
|
|
2981
|
+
getSession(options: {
|
|
2982
|
+
sessionId: string;
|
|
2983
|
+
accessToken: string;
|
|
2984
|
+
}): Promise<ExpertSession>;
|
|
2985
|
+
}
|
|
2986
|
+
/**
|
|
2987
|
+
* A thread and the capability that names it.
|
|
2988
|
+
*
|
|
2989
|
+
* The first `ask` opens the thread and takes the token from the answer; every
|
|
2990
|
+
* later one presents it. Callers that want a visitor's thread to survive a
|
|
2991
|
+
* reload persist `sessionId` and `accessToken` themselves and hand them back to
|
|
2992
|
+
* `chat()` — the SDK does not reach into storage on its own.
|
|
2993
|
+
*/
|
|
2994
|
+
declare class ExpertChat {
|
|
2995
|
+
private readonly api;
|
|
2996
|
+
private readonly expertId;
|
|
2997
|
+
private session?;
|
|
2998
|
+
private token?;
|
|
2999
|
+
private readonly turns;
|
|
3000
|
+
constructor(api: MAKEMINDExperts, options: {
|
|
3001
|
+
expertId: string;
|
|
3002
|
+
sessionId?: string;
|
|
3003
|
+
accessToken?: string;
|
|
3004
|
+
});
|
|
3005
|
+
get sessionId(): string | undefined;
|
|
3006
|
+
get accessToken(): string | undefined;
|
|
3007
|
+
get history(): ExpertTurn[];
|
|
3008
|
+
/**
|
|
3009
|
+
* Ask, and keep whatever the thread needs to be continued.
|
|
3010
|
+
* @param {string} question What the visitor asked.
|
|
3011
|
+
* @param {Object} [facts] Structured facts the rules read.
|
|
3012
|
+
* @return {Promise<ExpertConsultation>} The turn's record. A refusal comes
|
|
3013
|
+
* back as an answer with `refusal` set; only a closed door throws.
|
|
3014
|
+
*/
|
|
3015
|
+
ask(question: string, facts?: Record<string, unknown>): Promise<ExpertConsultation>;
|
|
3016
|
+
}
|
|
3017
|
+
|
|
3018
|
+
interface ExpertChatWidgetOptions extends MAKEMINDExpertsConfig {
|
|
3019
|
+
expertId: string;
|
|
3020
|
+
/** Shown above the thread. */
|
|
3021
|
+
title?: string;
|
|
3022
|
+
placeholder?: string;
|
|
3023
|
+
/**
|
|
3024
|
+
* Where the thread is remembered across reloads. Defaults to `localStorage`
|
|
3025
|
+
* when the page has one. Pass `null` to remember nothing — a visitor on a
|
|
3026
|
+
* shared machine leaves nothing behind, at the cost of the thread.
|
|
3027
|
+
*/
|
|
3028
|
+
storage?: Pick<Storage, 'getItem' | 'setItem' | 'removeItem'> | null;
|
|
3029
|
+
/**
|
|
3030
|
+
* The line that tells a visitor the link is the only way back. Overridable
|
|
3031
|
+
* for wording and translation; removing it is the embedder's decision to
|
|
3032
|
+
* make, and their visitor's to regret.
|
|
3033
|
+
*/
|
|
3034
|
+
bearerNotice?: string;
|
|
3035
|
+
}
|
|
3036
|
+
interface ExpertChatWidget {
|
|
3037
|
+
/** Ask programmatically — the same path the input takes. */
|
|
3038
|
+
ask(question: string): Promise<void>;
|
|
3039
|
+
/** Remove the UI and stop. The remembered thread is left alone. */
|
|
3040
|
+
destroy(): void;
|
|
3041
|
+
/** What the page would need to re-open this thread elsewhere. */
|
|
3042
|
+
readonly thread: {
|
|
3043
|
+
sessionId?: string;
|
|
3044
|
+
accessToken?: string;
|
|
3045
|
+
};
|
|
3046
|
+
}
|
|
3047
|
+
/**
|
|
3048
|
+
* Mount a chat into an element.
|
|
3049
|
+
* @param {HTMLElement} el Where it goes. Its contents are replaced.
|
|
3050
|
+
* @param {ExpertChatWidgetOptions} options Tenant, expert and presentation.
|
|
3051
|
+
* @return {ExpertChatWidget} A handle to ask, read the thread, or remove it.
|
|
3052
|
+
*/
|
|
3053
|
+
declare function mountExpertChat(el: HTMLElement, options: ExpertChatWidgetOptions): ExpertChatWidget;
|
|
3054
|
+
|
|
3055
|
+
declare class MAKEMINDError extends Error {
|
|
3056
|
+
code: string;
|
|
3057
|
+
details?: Record<string, unknown>;
|
|
3058
|
+
constructor(code: string, message: string, details?: Record<string, unknown>);
|
|
3059
|
+
static fromApiError(error: unknown): MAKEMINDError;
|
|
3060
|
+
static fromHttpStatus(status: number, body?: unknown): MAKEMINDError;
|
|
3061
|
+
toJSON(): PlatformErrorDetails;
|
|
3062
|
+
}
|
|
3063
|
+
declare const ErrorCodes: {
|
|
3064
|
+
readonly UNAUTHENTICATED: "UNAUTHENTICATED";
|
|
3065
|
+
readonly PERMISSION_DENIED: "PERMISSION_DENIED";
|
|
3066
|
+
readonly INVALID_TOKEN: "INVALID_TOKEN";
|
|
3067
|
+
readonly NOT_FOUND: "NOT_FOUND";
|
|
3068
|
+
readonly ALREADY_EXISTS: "ALREADY_EXISTS";
|
|
3069
|
+
readonly VALIDATION_ERROR: "VALIDATION_ERROR";
|
|
3070
|
+
readonly TENANT_NOT_FOUND: "TENANT_NOT_FOUND";
|
|
3071
|
+
readonly TENANT_SUSPENDED: "TENANT_SUSPENDED";
|
|
3072
|
+
readonly NOT_A_MEMBER: "NOT_A_MEMBER";
|
|
3073
|
+
readonly QUOTA_EXCEEDED: "QUOTA_EXCEEDED";
|
|
3074
|
+
readonly STORAGE_ERROR: "STORAGE_ERROR";
|
|
3075
|
+
readonly INTERNAL_ERROR: "INTERNAL_ERROR";
|
|
3076
|
+
readonly SERVICE_UNAVAILABLE: "SERVICE_UNAVAILABLE";
|
|
3077
|
+
readonly UNKNOWN_ERROR: "UNKNOWN_ERROR";
|
|
3078
|
+
};
|
|
3079
|
+
|
|
3080
|
+
export { ApiClient, type ApiClientConfig, type ApiRequestOptions, type AuthStateCallback, type AuthUser, type BillingSummary, type CollectionSnapshotCallback, type ConsultResult, type ConsultationConclusion, type CreateOptions, type DeleteOptions, type DocumentResult, ErrorCodes, type ExpertAccess, ExpertChat, type ExpertChatWidget, type ExpertChatWidgetOptions, type ExpertConsultation, ExpertDoorError, type ExpertSession, type ExpertTurn, type FileMetadata, type FlowListItem, type GetOptions, type Invoice, type ListFilesOptions, type ListFilesResult, type ListFlowsParams, type ListFlowsResult, type LogicCallResult, MAKEMINDAI, type MAKEMINDAIConfig, MAKEMINDApps, type MAKEMINDAppsConfig, MAKEMINDAuth, type MAKEMINDAuthConfig, MAKEMINDClient, type MAKEMINDClientConfig, type MAKEMINDConfig, MAKEMINDData, type MAKEMINDDataConfig, MAKEMINDError, MAKEMINDExperts, type MAKEMINDExpertsConfig, MAKEMINDLogic, type MAKEMINDLogicConfig, MAKEMINDMarketplace, type MAKEMINDMarketplaceConfig, MAKEMINDMessaging, type MAKEMINDMessagingConfig, MAKEMINDSearch, type MAKEMINDSearchConfig, MAKEMINDSettlement, type MAKEMINDSettlementConfig, MAKEMINDStorage, type MAKEMINDStorageConfig, MAKEMINDTenant, type MAKEMINDTenantConfig, type Notification, type OrderBy, type PlatformErrorDetails, type QueryCondition, type QueryOptions, type QueryResult, type SendMessageOptions, type SnapshotCallback, type Tenant, type TenantClaims, type TenantMember, type Unsubscribe, type UpdateOptions, type UploadOptions, type UploadResult, type UsageEventOptions, type UsageStats, type WorkflowTransitionOptions, type Workspace, getMAKEMIND, initializeMAKEMIND, mountExpertChat };
|