@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/CHANGELOG.md
ADDED
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
All notable changes to `@makemind/sdk` will be documented in this file.
|
|
4
|
+
|
|
5
|
+
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
|
|
6
|
+
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
7
|
+
|
|
8
|
+
## 0.1.0
|
|
9
|
+
|
|
10
|
+
First release. The public surface is not frozen: while this package is 0.x, a minor bump may change it.
|
|
11
|
+
|
|
12
|
+
### Added
|
|
13
|
+
|
|
14
|
+
### Corrected before first release
|
|
15
|
+
|
|
16
|
+
- `FlowListItem` described six fields while `GET /logic/flows` returns
|
|
17
|
+
eighteen, so consumers cast the row to read `publicExecution` or `mode`. It
|
|
18
|
+
now describes the payload.
|
|
19
|
+
- `FlowListItem.status` declared `'active'`, a value the route never sends: a
|
|
20
|
+
published flow is stored and returned as `'published'`.
|
|
21
|
+
- `ComponentNode` omitted `dataBinding`, `validation`, `a11y` and
|
|
22
|
+
`conditions.className`. A consumer building a node from this type could not
|
|
23
|
+
express a data binding at all. Kept in step with the App Builder's own
|
|
24
|
+
declaration by `component-node-parity.test.ts`.
|
|
25
|
+
- `listFlows()` took no arguments and returned a bare array. It now accepts
|
|
26
|
+
`status`, `mode`, `limit` and `cursor` — the gateway has always supported
|
|
27
|
+
them — and returns `{ flows, hasMore, nextCursor }`, so a truncated page is
|
|
28
|
+
distinguishable from a complete one.
|
|
29
|
+
|
|
30
|
+
- `initializeMAKEMIND()` / `getMAKEMIND()` entry points for configuring the SDK
|
|
31
|
+
with an API key, application ID, environment, and optional gateway `baseUrl`
|
|
32
|
+
override.
|
|
33
|
+
- Optional Firebase App Check integration (`getAppCheckToken`) attached as the
|
|
34
|
+
`X-Firebase-AppCheck` header on every gateway call.
|
|
35
|
+
- Eleven typed platform services, each a thin client over the MAKEMIND API
|
|
36
|
+
gateway:
|
|
37
|
+
- `auth` — email/password sign-in and sign-up, auth state subscription,
|
|
38
|
+
tenant memberships, tenant switching, sign-out.
|
|
39
|
+
- `data` — tenant-isolated document query/get/create/update and real-time
|
|
40
|
+
collection subscriptions.
|
|
41
|
+
- `logic` — workflow transitions (ECO, NCR, marketplace bid, gate approval)
|
|
42
|
+
and generic flow execution.
|
|
43
|
+
- `tenant` — tenant profile, settings, members, invitations, and
|
|
44
|
+
workspaces.
|
|
45
|
+
- `messaging` — notification send, real-time notification subscription,
|
|
46
|
+
and mark-as-read.
|
|
47
|
+
- `settlement` — usage-event recording, usage stats, billing summary,
|
|
48
|
+
quota status, and invoices.
|
|
49
|
+
- `storage` — file upload/download, metadata, listing, copy/move/delete,
|
|
50
|
+
PLM document helpers, and bucket management.
|
|
51
|
+
- `ai` — chat completion (including streaming and tool calling),
|
|
52
|
+
embeddings, vector search, vision analysis, and text
|
|
53
|
+
generate/summarize/translate helpers.
|
|
54
|
+
- `search` — full-text query, advanced faceted search, autocomplete
|
|
55
|
+
suggestions, analytics, and bulk reindexing.
|
|
56
|
+
- `apps` — App Builder app/page CRUD, publishing and versioning, domain
|
|
57
|
+
management, AI-assisted UI generation, and live-edit collaboration
|
|
58
|
+
sessions.
|
|
59
|
+
- `marketplace` — listing discovery/search, install/uninstall, app
|
|
60
|
+
runtime proxying, reviews, and the publisher/admin publishing
|
|
61
|
+
lifecycle.
|
|
62
|
+
- `call(operation, input)` generic RPC dispatch for platform Callable
|
|
63
|
+
operations that do not yet have a dedicated typed service method.
|
|
64
|
+
- `MAKEMINDError` / `ErrorCodes` for structured error handling across all
|
|
65
|
+
services.
|
|
66
|
+
- `firebase` as an **optional** peer dependency. It is loaded on demand by the
|
|
67
|
+
push-notification methods and by App Check token retrieval; the SDK imports
|
|
68
|
+
and every gateway call work with `firebase` absent.
|
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 MAKEMIND
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,550 @@
|
|
|
1
|
+
# @makemind/sdk
|
|
2
|
+
|
|
3
|
+
MAKEMIND Platform SDK for Web Applications (React, Vue, Angular, etc.)
|
|
4
|
+
|
|
5
|
+
## Installation
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
npm install @makemind/sdk
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
The SDK talks to the MAKEMIND API gateway over HTTPS. Installing it pulls in
|
|
12
|
+
nothing else: you only need an API key and your application ID.
|
|
13
|
+
|
|
14
|
+
`firebase` is an **optional** peer. Two features load it on demand and only
|
|
15
|
+
when you use them — web push (`messaging.registerDevice`,
|
|
16
|
+
`messaging.onPushMessage`) and App Check tokens. Everything else, including
|
|
17
|
+
every gateway call, works with `firebase` absent.
|
|
18
|
+
|
|
19
|
+
## Quick Start
|
|
20
|
+
|
|
21
|
+
```typescript
|
|
22
|
+
import { initializeMAKEMIND, getMAKEMIND } from '@makemind/sdk';
|
|
23
|
+
|
|
24
|
+
// Initialize MAKEMIND SDK
|
|
25
|
+
initializeMAKEMIND({
|
|
26
|
+
apiKey: 'your-api-key',
|
|
27
|
+
applicationId: 'plm', // Your application ID
|
|
28
|
+
environment: 'development',
|
|
29
|
+
// Optional: override the gateway base URL (defaults to https://api.makemind.app).
|
|
30
|
+
// Point this at a locally running gateway during development.
|
|
31
|
+
baseUrl: 'http://127.0.0.1:5001/<project-id>/us-central1/apiGateway',
|
|
32
|
+
});
|
|
33
|
+
|
|
34
|
+
// Use the SDK
|
|
35
|
+
const makemind = getMAKEMIND();
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
`initializeMAKEMIND` accepts `{ apiKey, applicationId, environment?, baseUrl?, apiVersion?, getAppCheckToken? }`.
|
|
39
|
+
All service calls are issued against `${baseUrl}/api/${apiVersion}` (`apiVersion`
|
|
40
|
+
defaults to `v1`).
|
|
41
|
+
|
|
42
|
+
### App Check (first-party apps only)
|
|
43
|
+
|
|
44
|
+
Pass `getAppCheckToken` — an async provider returning a Firebase App Check
|
|
45
|
+
token — to have the SDK attach it as `X-Firebase-AppCheck` on every gateway
|
|
46
|
+
call. This lets browser/mobile apps pass App Check enforcement on the pre-login
|
|
47
|
+
endpoints (signin/signup/password-reset/oauth). Backward-compatible: omit it for
|
|
48
|
+
M2M / API-key integrations (exempt from App Check server-side), and a provider
|
|
49
|
+
returning `null` simply omits the header.
|
|
50
|
+
|
|
51
|
+
```typescript
|
|
52
|
+
import { getToken } from 'firebase/app-check';
|
|
53
|
+
initializeMAKEMIND({
|
|
54
|
+
apiKey, applicationId,
|
|
55
|
+
getAppCheckToken: async () => (await getToken(appCheck, false)).token,
|
|
56
|
+
});
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
## Authentication
|
|
60
|
+
|
|
61
|
+
```typescript
|
|
62
|
+
const makemind = getMAKEMIND();
|
|
63
|
+
|
|
64
|
+
// Sign in with email + password
|
|
65
|
+
const user = await makemind.auth.signInWithEmail(email, password);
|
|
66
|
+
|
|
67
|
+
// Sign up a new user
|
|
68
|
+
const newUser = await makemind.auth.signUp(email, password, {
|
|
69
|
+
displayName: 'Jane Doe',
|
|
70
|
+
});
|
|
71
|
+
|
|
72
|
+
// Listen to auth state changes
|
|
73
|
+
const unsubscribe = makemind.auth.onAuthStateChanged((user) => {
|
|
74
|
+
if (user) {
|
|
75
|
+
console.log('User signed in:', user.uid);
|
|
76
|
+
console.log('Tenant:', user.tenantId);
|
|
77
|
+
console.log('Roles:', user.roles);
|
|
78
|
+
}
|
|
79
|
+
});
|
|
80
|
+
|
|
81
|
+
// Sign out
|
|
82
|
+
await makemind.auth.signOut();
|
|
83
|
+
|
|
84
|
+
// Get user memberships (tenants user belongs to)
|
|
85
|
+
const memberships = await makemind.auth.getUserMemberships();
|
|
86
|
+
|
|
87
|
+
// Switch tenant
|
|
88
|
+
await makemind.auth.switchTenant('new-tenant-id');
|
|
89
|
+
```
|
|
90
|
+
|
|
91
|
+
## Data Operations
|
|
92
|
+
|
|
93
|
+
```typescript
|
|
94
|
+
const makemind = getMAKEMIND();
|
|
95
|
+
|
|
96
|
+
// Query with tenant isolation
|
|
97
|
+
const { data: products } = await makemind.data.query({
|
|
98
|
+
collection: 'plm_products',
|
|
99
|
+
where: [
|
|
100
|
+
{ field: 'tenant_id', op: '==', value: makemind.tenantId },
|
|
101
|
+
{ field: 'status', op: '==', value: 'active' },
|
|
102
|
+
],
|
|
103
|
+
orderBy: [{ field: 'created_at', direction: 'desc' }],
|
|
104
|
+
limit: 20,
|
|
105
|
+
});
|
|
106
|
+
|
|
107
|
+
// Get single document
|
|
108
|
+
const product = await makemind.data.get({
|
|
109
|
+
collection: 'plm_products',
|
|
110
|
+
documentId: 'product-id',
|
|
111
|
+
});
|
|
112
|
+
|
|
113
|
+
// Create document (tenant_id auto-added)
|
|
114
|
+
const result = await makemind.data.create({
|
|
115
|
+
collection: 'plm_products',
|
|
116
|
+
data: {
|
|
117
|
+
product_code: 'PRD-001',
|
|
118
|
+
product_name: 'Sample Product',
|
|
119
|
+
status: 'development',
|
|
120
|
+
},
|
|
121
|
+
});
|
|
122
|
+
|
|
123
|
+
// Update document
|
|
124
|
+
await makemind.data.update({
|
|
125
|
+
collection: 'plm_products',
|
|
126
|
+
documentId: 'product-id',
|
|
127
|
+
data: { status: 'active' },
|
|
128
|
+
});
|
|
129
|
+
|
|
130
|
+
// Real-time subscription
|
|
131
|
+
const unsubscribe = makemind.data.onCollectionSnapshot(
|
|
132
|
+
{
|
|
133
|
+
collection: 'plm_products',
|
|
134
|
+
where: [{ field: 'tenant_id', op: '==', value: makemind.tenantId }],
|
|
135
|
+
},
|
|
136
|
+
(products) => {
|
|
137
|
+
console.log('Products updated:', products);
|
|
138
|
+
}
|
|
139
|
+
);
|
|
140
|
+
|
|
141
|
+
// Cleanup
|
|
142
|
+
unsubscribe();
|
|
143
|
+
```
|
|
144
|
+
|
|
145
|
+
## Logic / Workflows
|
|
146
|
+
|
|
147
|
+
```typescript
|
|
148
|
+
const makemind = getMAKEMIND();
|
|
149
|
+
|
|
150
|
+
// ECO workflow transition
|
|
151
|
+
await makemind.logic.ecoTransition('eco-id', 'submit');
|
|
152
|
+
await makemind.logic.ecoTransition('eco-id', 'approve', {
|
|
153
|
+
comments: 'Approved for implementation',
|
|
154
|
+
});
|
|
155
|
+
|
|
156
|
+
// NCR workflow
|
|
157
|
+
await makemind.logic.ncrTransition('issue-id', 'assignContainment', {
|
|
158
|
+
assignedTo: 'user-id',
|
|
159
|
+
containmentAction: 'Quarantine affected parts',
|
|
160
|
+
});
|
|
161
|
+
|
|
162
|
+
// Marketplace bid
|
|
163
|
+
await makemind.logic.bidTransition('request-id', 'bid-id', 'submit');
|
|
164
|
+
|
|
165
|
+
// Gate approval
|
|
166
|
+
await makemind.logic.gateApproval('product-id', 'production', 'approve');
|
|
167
|
+
|
|
168
|
+
// Generic flow execution
|
|
169
|
+
const result = await makemind.logic.executeFlow('flow-id', {
|
|
170
|
+
input: 'data',
|
|
171
|
+
});
|
|
172
|
+
```
|
|
173
|
+
|
|
174
|
+
## Tenant Management
|
|
175
|
+
|
|
176
|
+
```typescript
|
|
177
|
+
const makemind = getMAKEMIND();
|
|
178
|
+
|
|
179
|
+
// Get current tenant
|
|
180
|
+
const tenant = await makemind.tenant.getCurrent();
|
|
181
|
+
|
|
182
|
+
// Update tenant settings
|
|
183
|
+
await makemind.tenant.updateTenant({
|
|
184
|
+
settings: { industryType: 'electronics' },
|
|
185
|
+
});
|
|
186
|
+
|
|
187
|
+
// List members
|
|
188
|
+
const members = await makemind.tenant.listMembers();
|
|
189
|
+
|
|
190
|
+
// Invite member
|
|
191
|
+
await makemind.tenant.inviteMember({
|
|
192
|
+
email: 'new@example.com',
|
|
193
|
+
role: 'manager',
|
|
194
|
+
});
|
|
195
|
+
|
|
196
|
+
// Workspaces
|
|
197
|
+
const workspaces = await makemind.tenant.listWorkspaces();
|
|
198
|
+
await makemind.tenant.createWorkspace({
|
|
199
|
+
name: 'Development Team',
|
|
200
|
+
description: 'R&D workspace',
|
|
201
|
+
});
|
|
202
|
+
```
|
|
203
|
+
|
|
204
|
+
## Messaging / Notifications
|
|
205
|
+
|
|
206
|
+
```typescript
|
|
207
|
+
const makemind = getMAKEMIND();
|
|
208
|
+
|
|
209
|
+
// Send notification
|
|
210
|
+
await makemind.messaging.send({
|
|
211
|
+
template: 'ecoReviewRequest',
|
|
212
|
+
recipients: ['user-1', 'user-2'],
|
|
213
|
+
data: {
|
|
214
|
+
ecoNumber: 'ECO-2024-001',
|
|
215
|
+
title: 'Design Change Request',
|
|
216
|
+
},
|
|
217
|
+
channels: ['push', 'email'],
|
|
218
|
+
});
|
|
219
|
+
|
|
220
|
+
// Listen to notifications
|
|
221
|
+
const unsubscribe = makemind.messaging.onNotifications(
|
|
222
|
+
(notifications) => {
|
|
223
|
+
console.log('Notifications:', notifications);
|
|
224
|
+
},
|
|
225
|
+
{ unreadOnly: true }
|
|
226
|
+
);
|
|
227
|
+
|
|
228
|
+
// Mark as read
|
|
229
|
+
await makemind.messaging.markAsRead('notification-id');
|
|
230
|
+
```
|
|
231
|
+
|
|
232
|
+
## Settlement / Billing
|
|
233
|
+
|
|
234
|
+
```typescript
|
|
235
|
+
const makemind = getMAKEMIND();
|
|
236
|
+
|
|
237
|
+
// Record usage event
|
|
238
|
+
await makemind.settlement.recordProductCreation('product-id');
|
|
239
|
+
await makemind.settlement.recordDocumentUpload('doc-id', 2.5); // 2.5 MB
|
|
240
|
+
|
|
241
|
+
// Get usage stats
|
|
242
|
+
const stats = await makemind.settlement.getUsageStats('currentMonth');
|
|
243
|
+
|
|
244
|
+
// Get billing summary
|
|
245
|
+
const billing = await makemind.settlement.getBillingSummary();
|
|
246
|
+
|
|
247
|
+
// Check quotas
|
|
248
|
+
const quotas = await makemind.settlement.getQuotaStatus();
|
|
249
|
+
|
|
250
|
+
// List invoices
|
|
251
|
+
const invoices = await makemind.settlement.listInvoices({ status: 'pending' });
|
|
252
|
+
```
|
|
253
|
+
|
|
254
|
+
## Storage
|
|
255
|
+
|
|
256
|
+
```typescript
|
|
257
|
+
const makemind = getMAKEMIND();
|
|
258
|
+
|
|
259
|
+
// Upload a file
|
|
260
|
+
const uploaded = await makemind.storage.upload({
|
|
261
|
+
path: 'products/product-id/documents/spec.pdf',
|
|
262
|
+
file: fileFromInput, // File | Blob
|
|
263
|
+
metadata: { documentType: 'spec' },
|
|
264
|
+
onProgress: (progress) => console.log(`${progress.toFixed(0)}%`),
|
|
265
|
+
});
|
|
266
|
+
|
|
267
|
+
// Get a download URL / download directly
|
|
268
|
+
const url = await makemind.storage.getDownloadUrl('products/product-id/documents/spec.pdf');
|
|
269
|
+
const blob = await makemind.storage.download('products/product-id/documents/spec.pdf');
|
|
270
|
+
|
|
271
|
+
// List, copy, move, delete
|
|
272
|
+
const { files } = await makemind.storage.listFiles({ prefix: 'products/product-id/documents/' });
|
|
273
|
+
await makemind.storage.copy('a.pdf', 'b.pdf');
|
|
274
|
+
await makemind.storage.move('a.pdf', 'archive/a.pdf');
|
|
275
|
+
await makemind.storage.delete('a.pdf');
|
|
276
|
+
|
|
277
|
+
// PLM-specific helpers
|
|
278
|
+
await makemind.storage.uploadProductDocument('product-id', file, { documentType: 'drawing' });
|
|
279
|
+
await makemind.storage.uploadEcoAttachment('eco-id', file);
|
|
280
|
+
await makemind.storage.uploadQualityAttachment('issue-id', file);
|
|
281
|
+
const productDocs = await makemind.storage.getProductDocuments('product-id');
|
|
282
|
+
|
|
283
|
+
// Bucket management
|
|
284
|
+
const buckets = await makemind.storage.listBuckets();
|
|
285
|
+
await makemind.storage.createBucket({ name: 'reports', publicAccess: false });
|
|
286
|
+
const stats = await makemind.storage.getUsageStats();
|
|
287
|
+
```
|
|
288
|
+
|
|
289
|
+
## AI
|
|
290
|
+
|
|
291
|
+
```typescript
|
|
292
|
+
const makemind = getMAKEMIND();
|
|
293
|
+
|
|
294
|
+
// Chat completion
|
|
295
|
+
const { message, usage } = await makemind.ai.chat([
|
|
296
|
+
{ role: 'user', content: 'Summarize this ECO for a release note.' },
|
|
297
|
+
]);
|
|
298
|
+
|
|
299
|
+
// Streaming (polling-based; delivers content deltas as they arrive)
|
|
300
|
+
await makemind.ai.chatStream(
|
|
301
|
+
[{ role: 'user', content: 'Draft a quality report.' }],
|
|
302
|
+
(chunk) => process.stdout.write(chunk),
|
|
303
|
+
{ onDone: (response) => console.log('done', response.usage) }
|
|
304
|
+
);
|
|
305
|
+
|
|
306
|
+
// Or consume as an async generator
|
|
307
|
+
for await (const delta of makemind.ai.streamChat([{ role: 'user', content: 'Hi' }])) {
|
|
308
|
+
console.log(delta);
|
|
309
|
+
}
|
|
310
|
+
|
|
311
|
+
// Embeddings
|
|
312
|
+
const { embeddings } = await makemind.ai.createEmbedding(['spec text', 'another doc']);
|
|
313
|
+
|
|
314
|
+
// Vector search over a tenant knowledge collection
|
|
315
|
+
const hits = await makemind.ai.vectorSearch('specs', 'torque tolerance', { limit: 5 });
|
|
316
|
+
|
|
317
|
+
// Vision
|
|
318
|
+
await makemind.ai.analyzeImage('https://example.com/part.png', 'Describe this part.');
|
|
319
|
+
await makemind.ai.analyzeImageBase64(base64Data, 'image/png', 'Describe this part.');
|
|
320
|
+
|
|
321
|
+
// Tool calling
|
|
322
|
+
const { toolCalls } = await makemind.ai.chatWithTools(
|
|
323
|
+
[{ role: 'user', content: 'Look up product PRD-001.' }],
|
|
324
|
+
[{ name: 'getProduct', description: 'Fetch a product by code', parameters: { type: 'object' } }]
|
|
325
|
+
);
|
|
326
|
+
|
|
327
|
+
// Convenience helpers
|
|
328
|
+
const { text } = await makemind.ai.generate('Write a one-line changelog entry.');
|
|
329
|
+
const { summary } = await makemind.ai.summarize(longText, { style: 'bullet', maxLength: 100 });
|
|
330
|
+
const { translation } = await makemind.ai.translate('Hello world', 'ko');
|
|
331
|
+
```
|
|
332
|
+
|
|
333
|
+
## Search
|
|
334
|
+
|
|
335
|
+
```typescript
|
|
336
|
+
const makemind = getMAKEMIND();
|
|
337
|
+
|
|
338
|
+
// Simple query
|
|
339
|
+
const results = await makemind.search.query({ q: 'bracket', collections: ['plm_products'], perPage: 20 });
|
|
340
|
+
|
|
341
|
+
// Advanced query with facets/filters/highlighting
|
|
342
|
+
const advanced = await makemind.search.advanced({
|
|
343
|
+
query: 'bracket',
|
|
344
|
+
collection: 'plm_products',
|
|
345
|
+
facets: ['status', 'category'],
|
|
346
|
+
filters: { status: 'active' },
|
|
347
|
+
highlightFields: ['product_name'],
|
|
348
|
+
});
|
|
349
|
+
|
|
350
|
+
// Autocomplete suggestions
|
|
351
|
+
const suggestions = await makemind.search.suggestions({ prefix: 'brac', collection: 'plm_products' });
|
|
352
|
+
|
|
353
|
+
// Analytics and reindexing
|
|
354
|
+
const analytics = await makemind.search.getAnalytics({ startDate: '2026-01-01' });
|
|
355
|
+
const { jobId } = await makemind.search.bulkReindex({ collection: 'plm_products' });
|
|
356
|
+
const status = await makemind.search.getBulkReindexStatus({ jobId });
|
|
357
|
+
```
|
|
358
|
+
|
|
359
|
+
## Apps (App Builder)
|
|
360
|
+
|
|
361
|
+
```typescript
|
|
362
|
+
const makemind = getMAKEMIND();
|
|
363
|
+
|
|
364
|
+
// Create and manage apps
|
|
365
|
+
const { appId } = await makemind.apps.createApp({ name: 'field-service', displayName: 'Field Service' });
|
|
366
|
+
const app = await makemind.apps.getApp(appId);
|
|
367
|
+
const { apps } = await makemind.apps.listApps({ status: 'draft' });
|
|
368
|
+
await makemind.apps.updateApp(appId, { settings: { theme: { mode: 'dark' } } });
|
|
369
|
+
|
|
370
|
+
// Pages
|
|
371
|
+
const { pageId } = await makemind.apps.createPage(appId, { name: 'Home', path: '/', isHomePage: true });
|
|
372
|
+
await makemind.apps.updatePage(appId, pageId, { title: 'Home' });
|
|
373
|
+
const pages = await makemind.apps.listPages(appId);
|
|
374
|
+
|
|
375
|
+
// Publishing & versioning
|
|
376
|
+
await makemind.apps.publish(appId, 'Initial release');
|
|
377
|
+
const versions = await makemind.apps.getVersions(appId);
|
|
378
|
+
await makemind.apps.rollback(appId, versions[0].version);
|
|
379
|
+
|
|
380
|
+
// Domains
|
|
381
|
+
await makemind.apps.addSubdomain(appId, 'field-service');
|
|
382
|
+
const { verificationToken, dnsRecords } = await makemind.apps.addCustomDomain(appId, 'app.example.com');
|
|
383
|
+
|
|
384
|
+
// AI-assisted UI generation
|
|
385
|
+
const { components } = await makemind.apps.generateUI('A form to log a quality issue');
|
|
386
|
+
|
|
387
|
+
// Live-edit collaboration
|
|
388
|
+
const { sessionToken, wsEndpoint } = await makemind.apps.startSession(appId, pageId);
|
|
389
|
+
```
|
|
390
|
+
|
|
391
|
+
## Marketplace
|
|
392
|
+
|
|
393
|
+
```typescript
|
|
394
|
+
const makemind = getMAKEMIND();
|
|
395
|
+
|
|
396
|
+
// Discovery
|
|
397
|
+
const results = await makemind.marketplace.search({ query: 'inventory', category: 'operations' });
|
|
398
|
+
const listing = await makemind.marketplace.getDetail('listing-id');
|
|
399
|
+
const featured = await makemind.marketplace.getFeatured();
|
|
400
|
+
|
|
401
|
+
// Installation
|
|
402
|
+
const { bindingId } = await makemind.marketplace.install('listing-id');
|
|
403
|
+
const installed = await makemind.marketplace.listInstalled();
|
|
404
|
+
await makemind.marketplace.uninstall('listing-id');
|
|
405
|
+
|
|
406
|
+
// App runtime (proxy calls through the installed binding)
|
|
407
|
+
const config = await makemind.marketplace.getConfig(bindingId);
|
|
408
|
+
await makemind.marketplace.proxy(bindingId, { method: 'GET', path: 'items' });
|
|
409
|
+
|
|
410
|
+
// Reviews
|
|
411
|
+
await makemind.marketplace.createReview({ listingId: 'listing-id', rating: 5, body: 'Great app' });
|
|
412
|
+
const reviews = await makemind.marketplace.listReviews('listing-id');
|
|
413
|
+
|
|
414
|
+
// Publishing (for publisher tenants)
|
|
415
|
+
await makemind.marketplace.createPublisherProfile({
|
|
416
|
+
displayName: 'Acme Apps',
|
|
417
|
+
description: 'Field service tools',
|
|
418
|
+
logoUrl: 'https://example.com/logo.png',
|
|
419
|
+
supportEmail: 'support@acme.example',
|
|
420
|
+
});
|
|
421
|
+
const newListing = await makemind.marketplace.createListing({ name: 'Inventory Sync' });
|
|
422
|
+
await makemind.marketplace.submitForReview((newListing as { listingId: string }).listingId);
|
|
423
|
+
```
|
|
424
|
+
|
|
425
|
+
## Platform Operations (Generic Dispatch)
|
|
426
|
+
|
|
427
|
+
Every typed service method (`data.*`, `tenant.*`, `messaging.*`, ...) is a thin
|
|
428
|
+
wrapper around the gateway's RPC dispatch route. When a backend operation does
|
|
429
|
+
not yet have a typed service method, call it directly with `makemind.call()`:
|
|
430
|
+
|
|
431
|
+
```typescript
|
|
432
|
+
const makemind = getMAKEMIND();
|
|
433
|
+
|
|
434
|
+
// call<T>(operation, input) -> POST /api/v<version>/call/:operation
|
|
435
|
+
// The `{ data }` response envelope is already unwrapped.
|
|
436
|
+
const result = await makemind.call('updateMyProfile', { displayName: 'Jane Doe' });
|
|
437
|
+
```
|
|
438
|
+
|
|
439
|
+
`call(operation, input)` invokes a platform Callable operation through the
|
|
440
|
+
gateway RPC dispatch route. The operation key is the deployed Callable name:
|
|
441
|
+
namespaced groups use `<prefix>-<name>` (e.g. `settlement-getMRR`,
|
|
442
|
+
`marketplace-listPublisherListings`); flat exports use the bare name (e.g.
|
|
443
|
+
`createTenant`, `updateMyProfile`). Each operation enforces its own
|
|
444
|
+
authorization server-side (platform roles / tenant scopes), so calling an
|
|
445
|
+
operation you are not authorized for still fails with `PERMISSION_DENIED` —
|
|
446
|
+
`call()` does not bypass access control.
|
|
447
|
+
|
|
448
|
+
This is distinct from `logic.call(functionName, input)`, which executes a
|
|
449
|
+
tenant-defined *logic* function (`POST /logic/call`), not a platform Callable.
|
|
450
|
+
|
|
451
|
+
Some illustrative operations reachable only through `call()` (no dedicated
|
|
452
|
+
typed method yet):
|
|
453
|
+
|
|
454
|
+
```typescript
|
|
455
|
+
await makemind.call('platformGetAuditLogs', { limit: 50 });
|
|
456
|
+
await makemind.call('updateMyProfile', { displayName: 'Jane Doe' });
|
|
457
|
+
await makemind.call('endusers-listEndUsers', { limit: 20 });
|
|
458
|
+
await makemind.call('knowledge-knowledgeCreateUploadUrl', { fileName: 'spec.pdf' });
|
|
459
|
+
await makemind.call('getBillingContact', {});
|
|
460
|
+
await makemind.call('updateBillingContact', { email: 'billing@example.com' });
|
|
461
|
+
await makemind.call('getMyLoginHistory', { limit: 10 });
|
|
462
|
+
await makemind.call('createBrandingLogoUploadUrl', { fileName: 'logo.png' });
|
|
463
|
+
await makemind.call('marketplace-listPublisherListings', {});
|
|
464
|
+
```
|
|
465
|
+
|
|
466
|
+
## React Integration Example
|
|
467
|
+
|
|
468
|
+
```tsx
|
|
469
|
+
// src/lib/makemind.ts
|
|
470
|
+
import { initializeMAKEMIND } from '@makemind/sdk';
|
|
471
|
+
|
|
472
|
+
export const makemind = initializeMAKEMIND({
|
|
473
|
+
apiKey: import.meta.env.VITE_MAKEMIND_API_KEY,
|
|
474
|
+
applicationId: 'plm',
|
|
475
|
+
environment: import.meta.env.DEV ? 'development' : 'production',
|
|
476
|
+
baseUrl: import.meta.env.VITE_MAKEMIND_BASE_URL, // optional gateway override
|
|
477
|
+
});
|
|
478
|
+
|
|
479
|
+
// src/hooks/useProducts.ts
|
|
480
|
+
import { useQuery, useMutation, useQueryClient } from '@tanstack/react-query';
|
|
481
|
+
import { getMAKEMIND } from '@makemind/sdk';
|
|
482
|
+
|
|
483
|
+
export function useProducts() {
|
|
484
|
+
const makemind = getMAKEMIND();
|
|
485
|
+
|
|
486
|
+
return useQuery({
|
|
487
|
+
queryKey: ['plm_products', makemind.tenantId],
|
|
488
|
+
queryFn: async () => {
|
|
489
|
+
const result = await makemind.data.query({
|
|
490
|
+
collection: 'plm_products',
|
|
491
|
+
where: [
|
|
492
|
+
{ field: 'tenant_id', op: '==', value: makemind.tenantId! },
|
|
493
|
+
],
|
|
494
|
+
orderBy: [{ field: 'updated_at', direction: 'desc' }],
|
|
495
|
+
});
|
|
496
|
+
return result.data;
|
|
497
|
+
},
|
|
498
|
+
enabled: !!makemind.tenantId,
|
|
499
|
+
});
|
|
500
|
+
}
|
|
501
|
+
|
|
502
|
+
export function useCreateProduct() {
|
|
503
|
+
const queryClient = useQueryClient();
|
|
504
|
+
const makemind = getMAKEMIND();
|
|
505
|
+
|
|
506
|
+
return useMutation({
|
|
507
|
+
mutationFn: async (data: CreateProductInput) => {
|
|
508
|
+
const result = await makemind.data.create({
|
|
509
|
+
collection: 'plm_products',
|
|
510
|
+
data,
|
|
511
|
+
});
|
|
512
|
+
|
|
513
|
+
// Record usage
|
|
514
|
+
await makemind.settlement.recordProductCreation(result.id);
|
|
515
|
+
|
|
516
|
+
return result;
|
|
517
|
+
},
|
|
518
|
+
onSuccess: () => {
|
|
519
|
+
queryClient.invalidateQueries({ queryKey: ['plm_products'] });
|
|
520
|
+
},
|
|
521
|
+
});
|
|
522
|
+
}
|
|
523
|
+
```
|
|
524
|
+
|
|
525
|
+
## Error Handling
|
|
526
|
+
|
|
527
|
+
```typescript
|
|
528
|
+
import { MAKEMINDError, ErrorCodes } from '@makemind/sdk';
|
|
529
|
+
|
|
530
|
+
try {
|
|
531
|
+
await makemind.data.create({ ... });
|
|
532
|
+
} catch (error) {
|
|
533
|
+
if (error instanceof MAKEMINDError) {
|
|
534
|
+
switch (error.code) {
|
|
535
|
+
case ErrorCodes.PERMISSION_DENIED:
|
|
536
|
+
console.error('Access denied');
|
|
537
|
+
break;
|
|
538
|
+
case ErrorCodes.QUOTA_EXCEEDED:
|
|
539
|
+
console.error('Quota exceeded');
|
|
540
|
+
break;
|
|
541
|
+
default:
|
|
542
|
+
console.error('Error:', error.message);
|
|
543
|
+
}
|
|
544
|
+
}
|
|
545
|
+
}
|
|
546
|
+
```
|
|
547
|
+
|
|
548
|
+
## License
|
|
549
|
+
|
|
550
|
+
MIT
|