@stardeck-customer-apps/testing 0.7.1 → 0.9.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/LICENSE +21 -0
- package/SKILL.md +56 -4
- package/dist/index.d.mts +75 -1
- package/dist/index.d.ts +75 -1
- package/dist/index.js +365 -3
- package/dist/index.mjs +365 -3
- package/dist/next/headers-shim.js +7 -0
- package/dist/next/headers-shim.mjs +7 -0
- package/dist/setup.js +292 -3
- package/dist/setup.mjs +292 -3
- package/package.json +2 -2
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Stardeck Inc.
|
|
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/SKILL.md
CHANGED
|
@@ -93,6 +93,47 @@ await app.payments.deliverStripeEvent(POST, {
|
|
|
93
93
|
data: { object: { id: session.id } },
|
|
94
94
|
});
|
|
95
95
|
|
|
96
|
+
// Bolt+ terminal: create intent → approve → webhook (same deliverBeamEvent path)
|
|
97
|
+
// Simulator intents are real-shaped (bolti_<n>, isVirtual: false) — not bolti_emu_*.
|
|
98
|
+
// createBoltIntent validates like production: amount > 0, expiryDurationInSec 90–600,
|
|
99
|
+
// paymentMethod enum, deploymentId UUID, boltConnectionId required.
|
|
100
|
+
const connection = await payments.createBoltConnection({ pairingCode: "PAIR01" });
|
|
101
|
+
const intent = await payments.createBoltIntent({
|
|
102
|
+
amount: 10000,
|
|
103
|
+
boltConnectionId: connection.beamConnectionId,
|
|
104
|
+
paymentMethod: "CARD",
|
|
105
|
+
expiryDurationInSec: 300,
|
|
106
|
+
referenceId: "order-1",
|
|
107
|
+
});
|
|
108
|
+
expect(app.payments.getBoltIntent(intent.id)?.status).toBe("PENDING");
|
|
109
|
+
expect(app.payments.getBoltIntent(intent.id)?.isVirtual).toBe(false);
|
|
110
|
+
|
|
111
|
+
const charge = app.payments.approveBoltIntent(intent.id);
|
|
112
|
+
expect(app.payments.getBoltIntent(intent.id)?.status).toBe("PAID");
|
|
113
|
+
|
|
114
|
+
const { POST: beamPost } = paymentsHandler({
|
|
115
|
+
provider: "beam",
|
|
116
|
+
onBeamWebhook: async (event) => {
|
|
117
|
+
if (event.type === "charge.succeeded") {
|
|
118
|
+
await fulfillOrder(String(event.payload.referenceId ?? ""));
|
|
119
|
+
}
|
|
120
|
+
},
|
|
121
|
+
});
|
|
122
|
+
await app.payments.deliverBeamEvent(beamPost, {
|
|
123
|
+
type: "charge.succeeded",
|
|
124
|
+
payload: {
|
|
125
|
+
id: charge.id,
|
|
126
|
+
sourceId: intent.id,
|
|
127
|
+
referenceId: "order-1",
|
|
128
|
+
amount: 10000,
|
|
129
|
+
currency: "THB",
|
|
130
|
+
status: "SUCCEEDED",
|
|
131
|
+
},
|
|
132
|
+
});
|
|
133
|
+
// declineBoltIntent / expireBoltIntent deliver NO webhook — Beam has no
|
|
134
|
+
// charge-failure or expiry event for bolt payments.
|
|
135
|
+
// EXPIRED is derived from expiresAt on read, never stored.
|
|
136
|
+
|
|
96
137
|
// File upload
|
|
97
138
|
const storage = new StorageClient();
|
|
98
139
|
await storage.upload(new File(["hi"], "note.txt", { type: "text/plain" }));
|
|
@@ -169,7 +210,16 @@ externalId })` helper models a trusted platform/channel link, and
|
|
|
169
210
|
- `app.payments` — checkouts created through payments-sdk:
|
|
170
211
|
`.checkouts`, `.latest()`, `.setProducts()`, `.markPaid(id)`,
|
|
171
212
|
`.deliverStripeEvent(handler, event)`, `.deliverBeamEvent(handler, event)`,
|
|
172
|
-
`.
|
|
213
|
+
Bolt+ controls: `.approveBoltIntent(id)`, `.declineBoltIntent(id)`,
|
|
214
|
+
`.expireBoltIntent(id)`, `.listBoltIntents()`, `.getBoltIntent(id)`,
|
|
215
|
+
`.count`, `.clear()`. Approve marks PAID and records a charge; deliver the
|
|
216
|
+
`charge.succeeded` webhook yourself via `.deliverBeamEvent` (same signing
|
|
217
|
+
path as payment links). Decline and expire deliver no webhook. `EXPIRED` is
|
|
218
|
+
derived from `expiresAt` whenever an intent is read — it is never stored.
|
|
219
|
+
Simulator-created intents use real Beam id shapes (`bolti_<n>`) with
|
|
220
|
+
`isVirtual: false`; create/list validation matches the control plane
|
|
221
|
+
(expiry 90–600s, amount positive int, payment-method enum, deploymentId UUID,
|
|
222
|
+
list `limit` 1–100, status filter values).
|
|
173
223
|
- `app.storage` — uploads through storage-sdk: `.uploads`, `.latest()`, `.count`, `.clear()`.
|
|
174
224
|
- `app.messages` — outbound Slack/LINE/Facebook sends:
|
|
175
225
|
`.all()`, `.latest()`, `.to(recipient)`, `.channel("line")`, `.count`, `.clear()`.
|
|
@@ -235,9 +285,11 @@ true })` remains source-compatible but the simulator (like the control plane)
|
|
|
235
285
|
- For merge-correct reads, request aliases in batches and include every id in
|
|
236
286
|
the returned canonical set. Page directory UIs through `search({ query,
|
|
237
287
|
cursor, limit })`; `list()` intentionally keeps its previous array shape.
|
|
238
|
-
- `PaymentsServerClient` (Stripe checkout + Beam payment links
|
|
239
|
-
captured in `app.payments`;
|
|
240
|
-
`
|
|
288
|
+
- `PaymentsServerClient` (Stripe checkout + Beam payment links + Bolt+
|
|
289
|
+
connections/intents/charges, product list) — captured in `app.payments`;
|
|
290
|
+
fulfill checkout via `markPaid` (poll) or `deliverStripeEvent` /
|
|
291
|
+
`deliverBeamEvent` (webhook push). Drive a terminal without hardware via
|
|
292
|
+
`approveBoltIntent` / `declineBoltIntent` / `expireBoltIntent`.
|
|
241
293
|
- `StorageClient` (upload/list/get/patch/delete, presigned upload) — captured
|
|
242
294
|
in `app.storage` against the simulated `STORAGE_URL` host.
|
|
243
295
|
- `client.slack` / `client.line` / `client.facebook` send endpoints — captured
|
package/dist/index.d.mts
CHANGED
|
@@ -131,6 +131,53 @@ interface CapturedCheckout {
|
|
|
131
131
|
metadata?: Record<string, string>;
|
|
132
132
|
createdAt: Date;
|
|
133
133
|
}
|
|
134
|
+
/** Simulated Bolt+ connection as returned by the control-plane store API. */
|
|
135
|
+
interface SimBoltConnection {
|
|
136
|
+
id: string;
|
|
137
|
+
projectId: string;
|
|
138
|
+
beamConnectionId: string;
|
|
139
|
+
displayName: string | null;
|
|
140
|
+
pairingCode: string;
|
|
141
|
+
status: string;
|
|
142
|
+
isSandbox: boolean;
|
|
143
|
+
environments: Array<"sandbox" | "preview" | "production">;
|
|
144
|
+
createdAt: string;
|
|
145
|
+
updatedAt: string;
|
|
146
|
+
}
|
|
147
|
+
type SimBoltIntentStoredStatus = "PENDING" | "PAID" | "FAILED" | "CANCELED";
|
|
148
|
+
type SimBoltIntentStatus = SimBoltIntentStoredStatus | "EXPIRED";
|
|
149
|
+
/**
|
|
150
|
+
* Stored Bolt+ intent. `EXPIRED` is never written — derive it from
|
|
151
|
+
* `expiresAt` on read, matching the real control plane.
|
|
152
|
+
*/
|
|
153
|
+
type SimBoltPaymentMethod = _stardeck_customer_apps_payments_sdk.BeamBoltPaymentMethod;
|
|
154
|
+
/** Bolt intent as returned by list/get helpers (timestamps ISO; nullables are null). */
|
|
155
|
+
interface SimBoltIntentRecord {
|
|
156
|
+
id: string;
|
|
157
|
+
beamIntentId: string;
|
|
158
|
+
boltConnectionId: string;
|
|
159
|
+
amount: number;
|
|
160
|
+
currency: string;
|
|
161
|
+
paymentMethodType: SimBoltPaymentMethod;
|
|
162
|
+
referenceId: string | null;
|
|
163
|
+
internalNote: string | null;
|
|
164
|
+
status: SimBoltIntentStatus;
|
|
165
|
+
isVirtual: boolean;
|
|
166
|
+
environment: "sandbox" | "preview" | "production";
|
|
167
|
+
expiresAt: string;
|
|
168
|
+
settledAt: string | null;
|
|
169
|
+
chargeId: string | null;
|
|
170
|
+
failureReason: string | null;
|
|
171
|
+
createdAt: string;
|
|
172
|
+
}
|
|
173
|
+
interface SimBoltCharge {
|
|
174
|
+
id: string;
|
|
175
|
+
status: "SUCCEEDED" | "FAILED" | "PENDING";
|
|
176
|
+
amount?: number;
|
|
177
|
+
currency?: string;
|
|
178
|
+
sourceId?: string;
|
|
179
|
+
createdAt?: string;
|
|
180
|
+
}
|
|
134
181
|
interface TestPayments {
|
|
135
182
|
get checkouts(): CapturedCheckout[];
|
|
136
183
|
latest(): CapturedCheckout | undefined;
|
|
@@ -153,6 +200,30 @@ interface TestPayments {
|
|
|
153
200
|
path?: string;
|
|
154
201
|
deploymentSecret?: string;
|
|
155
202
|
}): Promise<Response>;
|
|
203
|
+
/**
|
|
204
|
+
* Mark a PENDING bolt intent PAID and record a SUCCEEDED charge. Does not
|
|
205
|
+
* deliver a webhook — call `deliverBeamEvent` with `charge.succeeded` (reuse
|
|
206
|
+
* the existing signing path) after approving, the same way `markPaid` pairs
|
|
207
|
+
* with `deliverStripeEvent` / `deliverBeamEvent`.
|
|
208
|
+
*/
|
|
209
|
+
approveBoltIntent(intentId: string, options?: {
|
|
210
|
+
chargeId?: string;
|
|
211
|
+
}): SimBoltCharge;
|
|
212
|
+
/**
|
|
213
|
+
* Mark a PENDING bolt intent FAILED and record a FAILED charge.
|
|
214
|
+
* Delivers no webhook: Beam's catalog has no charge-failure event for bolt
|
|
215
|
+
* payments, and the real product notifies the app of nothing on decline.
|
|
216
|
+
*/
|
|
217
|
+
declineBoltIntent(intentId: string, options?: {
|
|
218
|
+
failureReason?: string;
|
|
219
|
+
}): SimBoltCharge;
|
|
220
|
+
/**
|
|
221
|
+
* Backdate `expiresAt` so the intent derives as EXPIRED on the next read.
|
|
222
|
+
* Delivers no webhook: Beam does not notify apps when a bolt intent expires.
|
|
223
|
+
*/
|
|
224
|
+
expireBoltIntent(intentId: string): void;
|
|
225
|
+
listBoltIntents(): SimBoltIntentRecord[];
|
|
226
|
+
getBoltIntent(intentId: string): SimBoltIntentRecord | undefined;
|
|
156
227
|
clear(): void;
|
|
157
228
|
get count(): number;
|
|
158
229
|
}
|
|
@@ -241,6 +312,9 @@ type ReceiptBlock = {
|
|
|
241
312
|
format: "qr" | "code128";
|
|
242
313
|
data: string;
|
|
243
314
|
align?: ReceiptAlign;
|
|
315
|
+
/** QR width as a percentage of the printable width (5–100). Omitted →
|
|
316
|
+
* the printer's default cell size. Mirrors the edge SDK. */
|
|
317
|
+
widthPercent?: number;
|
|
244
318
|
};
|
|
245
319
|
interface ReceiptPayload {
|
|
246
320
|
paperWidth?: "58mm" | "80mm";
|
|
@@ -457,4 +531,4 @@ declare const TEST_ENV_DEFAULTS: {
|
|
|
457
531
|
/** Default location of the DDL snapshot written by `generate-types`. */
|
|
458
532
|
declare const DEFAULT_SCHEMA_PATH = "./src/generated/data-store-schema.sql";
|
|
459
533
|
|
|
460
|
-
export { type BindingInfo, CONTROL_PLANE_TEST_URL, type CallRouteOptions, type CapturedCheckout, type CapturedDisplay, type CapturedEmail, type CapturedIdentity, type CapturedIdentityLink, type CapturedMessage, type CapturedPrint, type CapturedTestPrint, type CapturedUpload, DATA_STORE_TEST_HOST, DEFAULT_SCHEMA_PATH, type DeviceInfo, type PeripheralInfo, STORAGE_TEST_HOST, STORAGE_TEST_URL, type SessionTokens, TEST_ENV_DEFAULTS, type TestApp, type TestAppOptions, type TestDirectory, type TestEdge, type TestInbox, type TestMessages, type TestPayments, type TestStorage, type TestUser, WORKFLOW_NAME_PREFIX, callRoute, createTestApp, describeWorkflow, parseWorkflowName };
|
|
534
|
+
export { type BindingInfo, CONTROL_PLANE_TEST_URL, type CallRouteOptions, type CapturedCheckout, type CapturedDisplay, type CapturedEmail, type CapturedIdentity, type CapturedIdentityLink, type CapturedMessage, type CapturedPrint, type CapturedTestPrint, type CapturedUpload, DATA_STORE_TEST_HOST, DEFAULT_SCHEMA_PATH, type DeviceInfo, type PeripheralInfo, STORAGE_TEST_HOST, STORAGE_TEST_URL, type SessionTokens, type SimBoltCharge, type SimBoltConnection, type SimBoltIntentRecord, type SimBoltIntentStatus, TEST_ENV_DEFAULTS, type TestApp, type TestAppOptions, type TestDirectory, type TestEdge, type TestInbox, type TestMessages, type TestPayments, type TestStorage, type TestUser, WORKFLOW_NAME_PREFIX, callRoute, createTestApp, describeWorkflow, parseWorkflowName };
|
package/dist/index.d.ts
CHANGED
|
@@ -131,6 +131,53 @@ interface CapturedCheckout {
|
|
|
131
131
|
metadata?: Record<string, string>;
|
|
132
132
|
createdAt: Date;
|
|
133
133
|
}
|
|
134
|
+
/** Simulated Bolt+ connection as returned by the control-plane store API. */
|
|
135
|
+
interface SimBoltConnection {
|
|
136
|
+
id: string;
|
|
137
|
+
projectId: string;
|
|
138
|
+
beamConnectionId: string;
|
|
139
|
+
displayName: string | null;
|
|
140
|
+
pairingCode: string;
|
|
141
|
+
status: string;
|
|
142
|
+
isSandbox: boolean;
|
|
143
|
+
environments: Array<"sandbox" | "preview" | "production">;
|
|
144
|
+
createdAt: string;
|
|
145
|
+
updatedAt: string;
|
|
146
|
+
}
|
|
147
|
+
type SimBoltIntentStoredStatus = "PENDING" | "PAID" | "FAILED" | "CANCELED";
|
|
148
|
+
type SimBoltIntentStatus = SimBoltIntentStoredStatus | "EXPIRED";
|
|
149
|
+
/**
|
|
150
|
+
* Stored Bolt+ intent. `EXPIRED` is never written — derive it from
|
|
151
|
+
* `expiresAt` on read, matching the real control plane.
|
|
152
|
+
*/
|
|
153
|
+
type SimBoltPaymentMethod = _stardeck_customer_apps_payments_sdk.BeamBoltPaymentMethod;
|
|
154
|
+
/** Bolt intent as returned by list/get helpers (timestamps ISO; nullables are null). */
|
|
155
|
+
interface SimBoltIntentRecord {
|
|
156
|
+
id: string;
|
|
157
|
+
beamIntentId: string;
|
|
158
|
+
boltConnectionId: string;
|
|
159
|
+
amount: number;
|
|
160
|
+
currency: string;
|
|
161
|
+
paymentMethodType: SimBoltPaymentMethod;
|
|
162
|
+
referenceId: string | null;
|
|
163
|
+
internalNote: string | null;
|
|
164
|
+
status: SimBoltIntentStatus;
|
|
165
|
+
isVirtual: boolean;
|
|
166
|
+
environment: "sandbox" | "preview" | "production";
|
|
167
|
+
expiresAt: string;
|
|
168
|
+
settledAt: string | null;
|
|
169
|
+
chargeId: string | null;
|
|
170
|
+
failureReason: string | null;
|
|
171
|
+
createdAt: string;
|
|
172
|
+
}
|
|
173
|
+
interface SimBoltCharge {
|
|
174
|
+
id: string;
|
|
175
|
+
status: "SUCCEEDED" | "FAILED" | "PENDING";
|
|
176
|
+
amount?: number;
|
|
177
|
+
currency?: string;
|
|
178
|
+
sourceId?: string;
|
|
179
|
+
createdAt?: string;
|
|
180
|
+
}
|
|
134
181
|
interface TestPayments {
|
|
135
182
|
get checkouts(): CapturedCheckout[];
|
|
136
183
|
latest(): CapturedCheckout | undefined;
|
|
@@ -153,6 +200,30 @@ interface TestPayments {
|
|
|
153
200
|
path?: string;
|
|
154
201
|
deploymentSecret?: string;
|
|
155
202
|
}): Promise<Response>;
|
|
203
|
+
/**
|
|
204
|
+
* Mark a PENDING bolt intent PAID and record a SUCCEEDED charge. Does not
|
|
205
|
+
* deliver a webhook — call `deliverBeamEvent` with `charge.succeeded` (reuse
|
|
206
|
+
* the existing signing path) after approving, the same way `markPaid` pairs
|
|
207
|
+
* with `deliverStripeEvent` / `deliverBeamEvent`.
|
|
208
|
+
*/
|
|
209
|
+
approveBoltIntent(intentId: string, options?: {
|
|
210
|
+
chargeId?: string;
|
|
211
|
+
}): SimBoltCharge;
|
|
212
|
+
/**
|
|
213
|
+
* Mark a PENDING bolt intent FAILED and record a FAILED charge.
|
|
214
|
+
* Delivers no webhook: Beam's catalog has no charge-failure event for bolt
|
|
215
|
+
* payments, and the real product notifies the app of nothing on decline.
|
|
216
|
+
*/
|
|
217
|
+
declineBoltIntent(intentId: string, options?: {
|
|
218
|
+
failureReason?: string;
|
|
219
|
+
}): SimBoltCharge;
|
|
220
|
+
/**
|
|
221
|
+
* Backdate `expiresAt` so the intent derives as EXPIRED on the next read.
|
|
222
|
+
* Delivers no webhook: Beam does not notify apps when a bolt intent expires.
|
|
223
|
+
*/
|
|
224
|
+
expireBoltIntent(intentId: string): void;
|
|
225
|
+
listBoltIntents(): SimBoltIntentRecord[];
|
|
226
|
+
getBoltIntent(intentId: string): SimBoltIntentRecord | undefined;
|
|
156
227
|
clear(): void;
|
|
157
228
|
get count(): number;
|
|
158
229
|
}
|
|
@@ -241,6 +312,9 @@ type ReceiptBlock = {
|
|
|
241
312
|
format: "qr" | "code128";
|
|
242
313
|
data: string;
|
|
243
314
|
align?: ReceiptAlign;
|
|
315
|
+
/** QR width as a percentage of the printable width (5–100). Omitted →
|
|
316
|
+
* the printer's default cell size. Mirrors the edge SDK. */
|
|
317
|
+
widthPercent?: number;
|
|
244
318
|
};
|
|
245
319
|
interface ReceiptPayload {
|
|
246
320
|
paperWidth?: "58mm" | "80mm";
|
|
@@ -457,4 +531,4 @@ declare const TEST_ENV_DEFAULTS: {
|
|
|
457
531
|
/** Default location of the DDL snapshot written by `generate-types`. */
|
|
458
532
|
declare const DEFAULT_SCHEMA_PATH = "./src/generated/data-store-schema.sql";
|
|
459
533
|
|
|
460
|
-
export { type BindingInfo, CONTROL_PLANE_TEST_URL, type CallRouteOptions, type CapturedCheckout, type CapturedDisplay, type CapturedEmail, type CapturedIdentity, type CapturedIdentityLink, type CapturedMessage, type CapturedPrint, type CapturedTestPrint, type CapturedUpload, DATA_STORE_TEST_HOST, DEFAULT_SCHEMA_PATH, type DeviceInfo, type PeripheralInfo, STORAGE_TEST_HOST, STORAGE_TEST_URL, type SessionTokens, TEST_ENV_DEFAULTS, type TestApp, type TestAppOptions, type TestDirectory, type TestEdge, type TestInbox, type TestMessages, type TestPayments, type TestStorage, type TestUser, WORKFLOW_NAME_PREFIX, callRoute, createTestApp, describeWorkflow, parseWorkflowName };
|
|
534
|
+
export { type BindingInfo, CONTROL_PLANE_TEST_URL, type CallRouteOptions, type CapturedCheckout, type CapturedDisplay, type CapturedEmail, type CapturedIdentity, type CapturedIdentityLink, type CapturedMessage, type CapturedPrint, type CapturedTestPrint, type CapturedUpload, DATA_STORE_TEST_HOST, DEFAULT_SCHEMA_PATH, type DeviceInfo, type PeripheralInfo, STORAGE_TEST_HOST, STORAGE_TEST_URL, type SessionTokens, type SimBoltCharge, type SimBoltConnection, type SimBoltIntentRecord, type SimBoltIntentStatus, TEST_ENV_DEFAULTS, type TestApp, type TestAppOptions, type TestDirectory, type TestEdge, type TestInbox, type TestMessages, type TestPayments, type TestStorage, type TestUser, WORKFLOW_NAME_PREFIX, callRoute, createTestApp, describeWorkflow, parseWorkflowName };
|