@pocketboss/core 0.2.0 → 0.2.1
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/README.md +198 -45
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -1,67 +1,220 @@
|
|
|
1
1
|
# @pocketboss/core
|
|
2
2
|
|
|
3
|
-
Framework-neutral
|
|
3
|
+
Framework-neutral TypeScript client for PocketBoss Bridge protocol v1. It provides the vanilla JavaScript entry point, typed bridge requests, browser file inputs, and the shared REST client and custom element for order comments.
|
|
4
4
|
|
|
5
|
-
|
|
6
|
-
import { PocketBossClient } from '@pocketboss/core';
|
|
5
|
+
The npm packages are not yet released to the public registry. Use the repository workspace quickstart below for a runnable local app. Public installation is available after the package release gates in the [SDK publishing guide](https://github.com/benogroupltd/PocketBoss/blob/main/docs/SDK_PUBLISHING.md) are satisfied.
|
|
7
6
|
|
|
8
|
-
|
|
9
|
-
if (client.isAvailable) {
|
|
10
|
-
await client.connect();
|
|
11
|
-
const info = await client.getInfo();
|
|
12
|
-
console.log(info.platform);
|
|
13
|
-
}
|
|
14
|
-
client.close();
|
|
15
|
-
```
|
|
16
|
-
|
|
17
|
-
Use browser file controls for ordinary user-selected files and photos. These are standard HTML file inputs exposed as helpers; they do not call `file.pick` or `camera.capture` on the PocketBoss bridge.
|
|
18
|
-
|
|
19
|
-
```ts
|
|
20
|
-
import { captureDevicePhoto, pickDeviceFiles } from '@pocketboss/core';
|
|
7
|
+
## Runnable vanilla quickstart
|
|
21
8
|
|
|
22
|
-
|
|
23
|
-
const files = await pickDeviceFiles({ accept: 'image/*', multiple: true });
|
|
24
|
-
const photo = await captureDevicePhoto({ facingMode: 'environment' });
|
|
9
|
+
Requirements: Node.js 24.21.0 and npm 11.19.0. From the repository root:
|
|
25
10
|
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
```
|
|
32
|
-
|
|
33
|
-
`pickDeviceFiles()` returns browser `File` objects and resolves to `[]` on cancellation. `captureDevicePhoto()` returns the first selected image or `null`; `capture` is a best-effort hint and the OS may show a chooser instead of opening a camera. React, Vue, Angular, and Ionic mini-apps can import these helpers from `@pocketboss/core`.
|
|
11
|
+
~~~sh
|
|
12
|
+
npm ci
|
|
13
|
+
npm run build:core
|
|
14
|
+
npx vite packages/sdk-core/examples/vanilla --host 127.0.0.1
|
|
15
|
+
~~~
|
|
34
16
|
|
|
35
|
-
The
|
|
17
|
+
Open <http://127.0.0.1:5173>. The fixture reports standalone browser mode. Open <http://127.0.0.1:5173/?mock=1> to exercise its explicit mock handler. The mock is only a development response; it does not demonstrate a native permission or authenticated launch.
|
|
36
18
|
|
|
37
|
-
|
|
19
|
+
After a public release, install with <code>npm install @pocketboss/core</code>. Import from <code>@pocketboss/core</code>, <code>@pocketboss/core/comments</code>, or <code>@pocketboss/core/mock</code>. The same package can be used by any JavaScript framework.
|
|
38
20
|
|
|
39
|
-
|
|
21
|
+
## Bridge lifecycle
|
|
40
22
|
|
|
41
|
-
|
|
23
|
+
Create one client for the Mini App document. Connect after startup, check each launch's capabilities before showing a host action, and close the client when the document is destroyed.
|
|
42
24
|
|
|
43
|
-
|
|
25
|
+
~~~ts
|
|
26
|
+
import { BridgeError, PocketBossClient } from '@pocketboss/core';
|
|
44
27
|
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
28
|
+
const client = new PocketBossClient();
|
|
29
|
+
try {
|
|
30
|
+
const ready = await client.connect();
|
|
31
|
+
if (ready.capabilities.some((item) =>
|
|
32
|
+
item.name === 'runtime.getInfo' && item.version === 1)) {
|
|
33
|
+
const info = await client.getInfo({ timeoutMs: 5000 });
|
|
34
|
+
document.querySelector('#status')!.textContent =
|
|
35
|
+
info.platform + ' ' + info.runtimeVersion;
|
|
36
|
+
}
|
|
37
|
+
} catch (error) {
|
|
38
|
+
const code = error instanceof BridgeError ? error.code : 'INTERNAL';
|
|
39
|
+
document.querySelector('#status')!.textContent = 'Bridge error: ' + code;
|
|
40
|
+
}
|
|
41
|
+
window.addEventListener('pagehide', () => client.close(), { once: true });
|
|
42
|
+
~~~
|
|
43
|
+
|
|
44
|
+
<code>isAvailable</code> is false in a normal browser; <code>isMock</code> identifies an explicitly supplied mock transport. <code>connect()</code> rejects with <code>UNAVAILABLE</code> outside a native host, <code>TIMEOUT</code> when the handshake expires, <code>CANCELLED</code> when its signal is aborted, and <code>UNSUPPORTED_PLATFORM</code> when the host protocol is incompatible. A successful handshake returns the launch, app, release, runtime, capability, limits, and expiry context.
|
|
45
|
+
|
|
46
|
+
### Bridge client exports
|
|
47
|
+
|
|
48
|
+
| Export | Parameters and return value | Errors and behavior |
|
|
49
|
+
| --- | --- | --- |
|
|
50
|
+
| <code>PocketBossClient</code> | <code>new PocketBossClient(transport?: BridgeTransport \| null)</code>; defaults to the browser transport. | A null or missing host produces unavailable state. |
|
|
51
|
+
| <code>isAvailable</code>, <code>isMock</code>, <code>snapshot</code>, <code>getSnapshot()</code> | Read native/mock availability or a <code>BridgeSnapshot</code> containing state, capabilities, and ready message. | Snapshot is empty until ready; getters do not connect. |
|
|
52
|
+
| <code>subscribeState(listener: () => void)</code> | Returns an unsubscribe function. Listener reads the latest snapshot. | No network request. |
|
|
53
|
+
| <code>on(event, listener)</code> | Event name string and <code>(BridgeEvent) => void</code>; returns unsubscribe function. | Unknown event names simply receive no event. |
|
|
54
|
+
| <code>connect(options?: RequestOptions)</code> | Resolves <code>Promise<ReadyMessage></code>; default timeout 15 seconds, clamped to 1–60 seconds. | Rejects with <code>BridgeError</code>; see error codes below. |
|
|
55
|
+
| <code>request(method, payload, options?)</code> | Method is a <code>BridgeMethod</code>; payload and <code>Promise<MethodResponse<M>></code> are inferred from the method map. | Rejects for invalid payload, missing capability, consent/permission denial, expiry, timeout, cancellation, host error, message/pending limits, or unavailable host. |
|
|
56
|
+
| <code>getInfo(options?)</code> | <code>Promise<{platform: 'android' \| 'ios'; runtimeVersion: string; protocolVersion: 1}></code>. | Requires <code>runtime.getInfo@1</code>. |
|
|
57
|
+
| <code>openExternal(url, options?)</code> | URL string; <code>Promise<{opened: true}></code>. | Requires an approved <code>navigation.openExternal@1</code> capability and an approved URL origin. |
|
|
58
|
+
| <code>closeMiniApp(options?)</code> | <code>Promise<{closed: true}></code>; asks the native shell to close this Mini App. | Requires <code>navigation.close@1</code>. This is distinct from local <code>close()</code>. |
|
|
59
|
+
| <code>share(payload, options?)</code> | Optional <code>title</code>, <code>text</code>, <code>url</code>; resolves <code>{presented: true}</code>. | Requires <code>share.open@1</code>; user dismissing the native sheet is not a bridge error. |
|
|
60
|
+
| <code>pickFiles(payload?, options?)</code> | Optional <code>mimeTypes: string[]</code>, <code>multiple: boolean</code>; resolves file handle metadata. | Requires <code>file.pick@1</code>; currently not advertised by native. Use browser <code>pickDeviceFiles</code> for actual file content. |
|
|
61
|
+
| <code>capturePhoto(options?)</code> | Resolves <code>{file: {handle, name, mimeType, sizeBytes, expiresAtMs}}</code>. | Requires <code>camera.capture@1</code>; currently not advertised by native. Use browser <code>captureDevicePhoto</code> for a <code>File</code>. |
|
|
62
|
+
| <code>getAssertion(options?)</code> | Resolves <code>{assertion, expiresAtMs}</code> with a short-lived customer identity assertion. | Requires <code>identity.getAssertion@1</code> and user consent. It does not prove business ownership or staff authority. |
|
|
63
|
+
| <code>getCurrentLocation(accuracy, options?)</code> | Accuracy is <code>'approximate' \| 'precise'</code>; resolves latitude, longitude, accuracy in meters, and capture time. | Requires <code>location.getCurrent@1</code>, approval, and platform permission. Device validation remains a release gate. |
|
|
64
|
+
| <code>subscribeNotifications(options?)</code> | Resolves <code>{subscribed: true}</code>. | Typed but not advertised by the current native host. App-scoped subscription and delivery are not implemented. |
|
|
65
|
+
| <code>sendNotification(payload, options?)</code> | Required title/body and optional path; resolves <code>{queued: true}</code>. | Typed but not advertised by the current native host; do not treat it as a push service. |
|
|
66
|
+
| <code>close()</code> | No parameters; returns <code>void</code>. | Idempotently stops listeners, clears state, and rejects pending work with <code>CANCELLED</code>. It does not log the user out of the Mini App backend. |
|
|
67
|
+
|
|
68
|
+
Bridge method request and response contracts are:
|
|
69
|
+
|
|
70
|
+
| Method | Request | Response |
|
|
71
|
+
| --- | --- | --- |
|
|
72
|
+
| <code>runtime.getInfo</code> | <code>{}</code> | platform, runtimeVersion, protocolVersion |
|
|
73
|
+
| <code>navigation.openExternal</code> | <code>{url: string}</code> | <code>{opened: true}</code> |
|
|
74
|
+
| <code>navigation.close</code> | <code>{}</code> | <code>{closed: true}</code> |
|
|
75
|
+
| <code>share.open</code> | optional title, text, url | <code>{presented: true}</code> |
|
|
76
|
+
| <code>identity.getAssertion</code> | <code>{}</code> | assertion and expiry in epoch milliseconds |
|
|
77
|
+
| <code>location.getCurrent</code> | accuracy: approximate or precise | latitude, longitude, accuracyMeters, capturedAtMs |
|
|
78
|
+
| <code>file.pick</code> | optional mimeTypes and multiple | file handle metadata array |
|
|
79
|
+
| <code>camera.capture</code> | <code>{}</code> | one file handle and metadata |
|
|
80
|
+
| <code>notifications.subscribe</code> | <code>{}</code> | <code>{subscribed: true}</code> |
|
|
81
|
+
| <code>notifications.send</code> | title, body, optional path | <code>{queued: true}</code> |
|
|
82
|
+
|
|
83
|
+
An SDK method being typed does not mean a host exposes it. Runtime info, external navigation, close, share, and identity have Android/iOS handlers but still depend on release approval and, for identity, consent. Location is implemented but its device validation is pending. File/camera and notifications are not advertised. Payments are not part of this SDK.
|
|
84
|
+
|
|
85
|
+
### Bridge types and error behavior
|
|
86
|
+
|
|
87
|
+
The public type exports are <code>BridgeCapability</code> ({name, version}), <code>BridgeLimits</code> ({maxMessageBytes, maxPendingRequests, defaultTimeoutMs}), <code>ReadyMessage</code> ({protocolVersion, type, launchId, appId, releaseId, runtimeVersion, selectedProtocolVersion, capabilities, limits, serverTimeMs, sessionExpiresAtMs}), <code>BridgeEvent</code> ({protocolVersion, type, launchId, appId, event, sequence, payload}), <code>BridgeSnapshot</code> ({state, isAvailable, isMock, capabilities, ready}), <code>BridgeState</code> (unavailable, idle, connecting, ready, expired, closed), <code>BridgeTransport</code>, <code>BridgeMethod</code>, <code>BridgeMethodMap</code>, <code>MethodRequest<M></code>, <code>MethodResponse<M></code>, and <code>RequestOptions</code> ({signal?, timeoutMs?}). They describe the v1 handshake, events, launch-scoped state, text transport, generated method payloads/results, and cancellation/timeout options. A custom transport implements <code>kind: 'native' | 'mock'</code>, <code>postMessage(serializedMessage)</code>, and <code>subscribe(listener)</code>; application code should normally use the default transport.
|
|
88
|
+
|
|
89
|
+
<code>BridgeError</code> extends <code>Error</code> and exposes <code>code: BridgeErrorCode</code> and optional structured <code>details</code>. The stable codes are <code>UNAVAILABLE</code>, <code>UNSUPPORTED_PLATFORM</code>, <code>NOT_DECLARED</code>, <code>NOT_APPROVED</code>, <code>CONSENT_REQUIRED</code>, <code>DENIED</code>, <code>CANCELLED</code>, <code>TIMEOUT</code>, <code>INVALID_ARGUMENT</code>, <code>RATE_LIMITED</code>, <code>SESSION_EXPIRED</code>, and <code>INTERNAL</code>. Check the code, not message text. Never auto-retry a denied request. A cancelled request may already have reached the native host.
|
|
90
|
+
|
|
91
|
+
### Browser media exports
|
|
92
|
+
|
|
93
|
+
| Export | Parameters and return value | Errors and behavior |
|
|
94
|
+
| --- | --- | --- |
|
|
95
|
+
| <code>CaptureFacingMode</code> | Type union <code>'user' \| 'environment'</code>. | Browser and OS may ignore the camera preference. |
|
|
96
|
+
| <code>DeviceFilePickerOptions</code> | Optional <code>accept</code> (browser input accept string), <code>multiple</code>, and <code>capture</code>. | These are HTML input hints, not bridge capabilities or authorization. |
|
|
97
|
+
| <code>pickDeviceFiles(options?)</code> | Returns <code>Promise<File[]></code>; call directly from a click/tap handler. | Cancellation resolves <code>[]</code>; unavailable document/input failure rejects. |
|
|
98
|
+
| <code>captureDevicePhoto({facingMode?})</code> | Returns <code>Promise<File \| null></code>. | Cancellation resolves null; capture is best effort and a chooser may appear. |
|
|
99
|
+
|
|
100
|
+
Files are normal browser <code>File</code> objects. The Mini App backend still validates size, type, authentication, and authorization.
|
|
101
|
+
|
|
102
|
+
## Order comments
|
|
103
|
+
|
|
104
|
+
Comments use PocketBoss REST APIs, independently of the native bridge. The Mini App backend authenticates its owner/staff user, checks active membership and order access, then obtains a short-lived order-scoped session from PocketBoss. The browser receives only that scoped token. Never put a long-lived integration credential in JavaScript or a widget option.
|
|
105
|
+
|
|
106
|
+
The widget's <code>orderId</code> is the canonical PocketBoss order ULID returned after server-side order synchronization, not the Mini App's external order ID. The backend maps the external ID to that ULID before creating a session. <code>workspaceKey</code> is a UI/context key; it is not proof of a business or staff identity.
|
|
107
|
+
|
|
108
|
+
~~~ts
|
|
48
109
|
import { registerOrderCommentsElement } from '@pocketboss/core/comments';
|
|
49
|
-
|
|
110
|
+
|
|
111
|
+
const sessions = {
|
|
112
|
+
async create() {
|
|
113
|
+
const response = await fetch('/api/business/order-comments/session', {
|
|
114
|
+
method: 'POST',
|
|
115
|
+
credentials: 'same-origin',
|
|
116
|
+
cache: 'no-store',
|
|
117
|
+
headers: {
|
|
118
|
+
'Content-Type': 'application/json',
|
|
119
|
+
'Idempotency-Key': crypto.randomUUID(),
|
|
120
|
+
},
|
|
121
|
+
body: JSON.stringify({ externalOrderId: 'shop-order-2048' }),
|
|
122
|
+
});
|
|
123
|
+
if (!response.ok) throw new Error('Could not authorize comments.');
|
|
124
|
+
return response.json();
|
|
125
|
+
},
|
|
126
|
+
async revoke(sessionId: string) {
|
|
127
|
+
const response = await fetch('/api/business/order-comments/session', {
|
|
128
|
+
method: 'DELETE',
|
|
129
|
+
credentials: 'same-origin',
|
|
130
|
+
cache: 'no-store',
|
|
131
|
+
headers: { 'Content-Type': 'application/json' },
|
|
132
|
+
body: JSON.stringify({ sessionId }),
|
|
133
|
+
});
|
|
134
|
+
if (!response.ok) throw new Error('Could not revoke comments session.');
|
|
135
|
+
},
|
|
136
|
+
};
|
|
50
137
|
|
|
51
138
|
registerOrderCommentsElement();
|
|
52
|
-
const element = document.querySelector('pb-order-comments')
|
|
139
|
+
const element = document.querySelector('pb-order-comments')!;
|
|
53
140
|
element.options = {
|
|
54
141
|
apiBaseUrl: 'https://api.example.test/api/v1',
|
|
55
142
|
orderId: pocketBossOrderId,
|
|
56
143
|
workspaceKey: businessId,
|
|
57
|
-
sessions,
|
|
58
|
-
placement: 'inline',
|
|
59
|
-
renderMessage(message
|
|
60
|
-
const
|
|
61
|
-
|
|
62
|
-
return
|
|
144
|
+
sessions,
|
|
145
|
+
placement: 'inline',
|
|
146
|
+
renderMessage(message) {
|
|
147
|
+
const node = document.createElement('article');
|
|
148
|
+
node.textContent = message.text;
|
|
149
|
+
return node;
|
|
63
150
|
},
|
|
64
151
|
};
|
|
65
|
-
|
|
152
|
+
~~~
|
|
153
|
+
|
|
154
|
+
The route names above are the sample Mini App backend's example, not SDK-managed routes. Adapt the callback to your authenticated same-origin server and its actual route.
|
|
155
|
+
|
|
156
|
+
### Comments client exports and results
|
|
157
|
+
|
|
158
|
+
| Export | Parameters and return value | Errors and behavior |
|
|
159
|
+
| --- | --- | --- |
|
|
160
|
+
| <code>OrderCommentsSession</code> | {sessionId, token, expiresAt, scopes?}; expiry is an ISO date string. | Client rejects missing/invalid ID, non-<code>pbcs_</code> token, or expired value. |
|
|
161
|
+
| <code>OrderCommentsSessionProvider</code> | <code>create(): Promise<OrderCommentsSession></code>; <code>revoke(sessionId: string): Promise<void></code>. | Create failure becomes <code>COMMENTS_SESSION_EXPIRED</code>; revoke failure is surfaced during close. |
|
|
162
|
+
| <code>OrderCommentsClientOptions</code> | Required <code>apiBaseUrl</code>, PocketBoss <code>orderId</code>, <code>sessions</code>; optional Fetch-compatible <code>fetcher</code> for tests. | Constructor rejects malformed URL or non-ULID order ID. |
|
|
163
|
+
| <code>OrderCommentMessage</code> | messageId, conversationId, orderId, participantSide customer/business, text, deliveryState sent, createdAt ISO string. | Malformed server response rejects with <code>OrderCommentsError</code>. |
|
|
164
|
+
| <code>OrderCommentPage</code> | messages, nextCursor or null, unreadCount. | Malformed page rejects. |
|
|
165
|
+
| <code>OrderCommentsError</code> | Extends <code>Error</code>; exposes <code>status: number \| null</code> and <code>code: string \| null</code>. | Network, HTTP, JSON shape, validation and session failures use this type. |
|
|
166
|
+
| <code>OrderCommentsClient(options)</code> | Owns one order-scoped REST session; lazy session creation; <code>active</code> is a boolean getter. | Does not grant access; backend and PocketBoss authorize every session/request. |
|
|
167
|
+
| <code>messages(cursor?, limit = 50)</code> | Returns <code>Promise<OrderCommentPage></code>; limit is clamped to 1–50. | HTTP and invalid response errors reject. |
|
|
168
|
+
| <code>send(text, clientMessageId?)</code> | Trims text, 1–5000 characters; optional UUID idempotency key; returns <code>Promise<OrderCommentMessage></code>. | Invalid text/key rejects 422; default key requires secure browser randomness. |
|
|
169
|
+
| <code>markRead(messageId)</code> | PocketBoss message ULID; returns <code>Promise<void></code>. | Invalid ID rejects 422; HTTP errors reject. |
|
|
170
|
+
| <code>close()</code> | Returns <code>Promise<void></code>; aborts requests and invokes session revoke. | Rejects with <code>COMMENTS_SESSION_CLOSE_FAILED</code> when a session cannot be revoked. Treat a failed close as protected content still blocked. |
|
|
171
|
+
|
|
172
|
+
On HTTP 401 or 410 the client requests a replacement session and retries once. Other non-2xx responses preserve server <code>status</code> and error <code>code</code>. Network failure rejects with <code>OrderCommentsError</code>. The bearer is memory-only, requests omit ambient credentials and redirects, and no session is written to browser storage.
|
|
173
|
+
|
|
174
|
+
### Comments custom-element exports
|
|
175
|
+
|
|
176
|
+
| Export | Parameters and return value | Errors and behavior |
|
|
177
|
+
| --- | --- | --- |
|
|
178
|
+
| <code>OrderCommentsPlacement</code> | <code>inline</code>, <code>modal</code>, <code>bottom-sheet</code>, <code>full-page</code>, <code>headless</code>. | Modal and bottom sheet open on user action; headless supplies only the client. |
|
|
179
|
+
| <code>OrderCommentsThemeMode</code>, <code>OrderCommentsTheme</code> | mode light/dark/auto; optional accent, surface, text, muted, border, customer/business bubble and text colors, fontFamily, spacing, radius. | Presentation only; no effect on authorization. |
|
|
180
|
+
| <code>OrderCommentsElementOptions</code> | Client options plus required <code>workspaceKey</code>, optional placement/theme/title/language and <code>renderMessage(message): HTMLElement</code>. | Constructor/client validation errors surface through the client/element. Render user text with <code>textContent</code>, never HTML interpolation. |
|
|
181
|
+
| <code>registerOrderCommentsElement(tagName = 'pb-order-comments')</code> | Returns <code>void</code>; idempotent and safe during SSR. | No-op when custom elements are unavailable. |
|
|
182
|
+
| <code>mountOrderCommentsElement(element, options)</code> | Mounts typed options and returns <code>PocketBossOrderCommentsElement</code>. | Client/session errors surface from load/open methods. |
|
|
183
|
+
| <code>PocketBossOrderCommentsElement</code> | <code>options</code> setter/getter; <code>commentsClient</code> getter; <code>loadComments(): Promise<void></code>; <code>openCommentsClient(): Promise<OrderCommentsClient></code>. | Reading options before setting them throws; load/open reject for session/API failures. |
|
|
184
|
+
|
|
185
|
+
### Mock exports
|
|
186
|
+
|
|
187
|
+
Import <code>MockBridgeTransport</code>, <code>createMockTransport</code>, <code>MockHandlers</code>, and <code>MockHostOptions</code> from <code>@pocketboss/core/mock</code>. Provide a v1 <code>ready</code> message and typed method handlers. <code>createMockTransport(options)</code> returns a transport with <code>kind: 'mock'</code>; it always reports <code>isMock</code> true and native <code>isAvailable</code> false. Missing handlers reject <code>NOT_APPROVED</code>; unrecognized handler failures map to <code>INTERNAL</code>. Use only in local development and tests.
|
|
188
|
+
|
|
189
|
+
## Authentication, access modes, orders, and security
|
|
190
|
+
|
|
191
|
+
The SDK does not sign users in, select a business workspace, register a business, bind staff identities, synchronize orders, or verify server assertions. Keep these responsibilities in the Mini App backend and PocketBoss APIs:
|
|
192
|
+
|
|
193
|
+
| Access mode | Backend responsibility |
|
|
194
|
+
| --- | --- |
|
|
195
|
+
| Guest | Permit only public guest behavior; guest SSO session lookup may return 401. |
|
|
196
|
+
| Personal | Read the same-origin PocketBoss SSO session and use the app-pairwise subject. |
|
|
197
|
+
| Business | Validate the selected workspace and current PocketBoss roles for each protected action. |
|
|
198
|
+
| Mixed | Authorize each route/action from the backend session; never infer a mode from a query string or browser-supplied business ID. |
|
|
199
|
+
|
|
200
|
+
Customer <code>identity.getAssertion</code> is an optional, consented bridge capability. Send the unmodified assertion to your same-origin backend for PocketBoss verification; do not decode it and trust its claims. It does not establish business ownership or staff authority. Business registration needs verified ownership, and staff access needs a verified invitation/identity binding. Order writes use a signed server-to-server integration, an app-scoped customer reference, source versions, idempotency, and a transactional outbox. Keep the PocketBoss order ULID for comments.
|
|
201
|
+
|
|
202
|
+
Call the Mini App backend's logout endpoint and await server revocation when ending or switching an authenticated workspace, then clear the workspace WebView storage according to the host contract. <code>client.close()</code> releases only this SDK client; it does not clear cookies, backend sessions, or native WebView state.
|
|
203
|
+
|
|
204
|
+
The integration private key, signing material, and long-lived PocketBoss credential stay on the server. Use HTTPS, least-privilege scopes, nonce/timestamp replay protection, idempotency, rotation, audit logging, and current membership checks. See [Authentication](https://pocket-boss.beno.co.tz/developer/identity/authentication), [business registration](https://pocket-boss.beno.co.tz/developer/business/registration), [server integration](https://pocket-boss.beno.co.tz/developer/integration/server-api), [orders](https://pocket-boss.beno.co.tz/developer/orders/synchronization), and [comments](https://pocket-boss.beno.co.tz/developer/messaging/order-comments).
|
|
205
|
+
|
|
206
|
+
## Build, test, and package contents
|
|
207
|
+
|
|
208
|
+
From the repository root:
|
|
209
|
+
|
|
210
|
+
~~~sh
|
|
211
|
+
npm run build:core
|
|
212
|
+
npm test -w @pocketboss/core
|
|
213
|
+
(cd packages/sdk-core && npm pack --dry-run --json)
|
|
214
|
+
~~~
|
|
215
|
+
|
|
216
|
+
The package whitelist is <code>dist</code> plus this README; npm adds package metadata. Inspect the dry-run file list after building. It does not publish. The npm manifest currently has no approved license metadata or license file, so this archive is not publication-ready; resolve the project license decision before a release.
|
|
217
|
+
|
|
218
|
+
## Developer Portal
|
|
66
219
|
|
|
67
|
-
|
|
220
|
+
Continue with the [Vanilla JavaScript guide](https://pocket-boss.beno.co.tz/developer/sdk/vanilla), [bridge reference](https://pocket-boss.beno.co.tz/developer/bridge/capabilities), [quickstart](https://pocket-boss.beno.co.tz/developer/getting-started/quickstart), and the identity, business, orders, and comments guides linked above.
|