@stardeck-customer-apps/testing 0.25.1 → 0.26.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/SKILL.md +6 -0
- package/dist/index.d.mts +17 -1
- package/dist/index.d.ts +17 -1
- package/dist/index.js +39 -2
- package/dist/index.mjs +39 -2
- package/dist/next/headers-shim.js +1 -0
- package/dist/next/headers-shim.mjs +1 -0
- package/dist/setup.js +19 -2
- package/dist/setup.mjs +19 -2
- package/package.json +2 -1
package/SKILL.md
CHANGED
|
@@ -586,6 +586,12 @@ cursor, limit })`; `list()` intentionally keeps its previous array shape.
|
|
|
586
586
|
high request with no image input answers `effort: "low"` as production does;
|
|
587
587
|
pass `effort: "low"` in `app.starlens.mock(...)` to simulate an image production
|
|
588
588
|
could not decode.
|
|
589
|
+
- `wakeSchedule(key, at)` from the scheduling SDK — there is no scheduler in tests: each
|
|
590
|
+
wake is recorded in `app.schedules`. After a write that creates work for an adaptive job,
|
|
591
|
+
assert the job was asked for in time:
|
|
592
|
+
`expect(app.schedules.earliestWake("booking-janitor")!.getTime()).toBeLessThanOrEqual(dueAt.getTime())`.
|
|
593
|
+
`app.schedules.wakesFor(key)` lists them; `reset()` clears them. Run the job's handler
|
|
594
|
+
yourself to test what it does and the `nextRun()` it returns.
|
|
589
595
|
|
|
590
596
|
### Receipt layout and printer capabilities
|
|
591
597
|
|
package/dist/index.d.mts
CHANGED
|
@@ -652,6 +652,20 @@ interface TestStarlens {
|
|
|
652
652
|
clear(): void;
|
|
653
653
|
get count(): number;
|
|
654
654
|
}
|
|
655
|
+
/** A wake the app asked for: run `scheduleKey` by `at` (scheduling-sdk `wakeSchedule`). */
|
|
656
|
+
interface CapturedScheduleWake {
|
|
657
|
+
scheduleKey: string;
|
|
658
|
+
at: Date;
|
|
659
|
+
requestedAt: Date;
|
|
660
|
+
}
|
|
661
|
+
interface TestSchedules {
|
|
662
|
+
/** Every wake the app asked for, oldest first. */
|
|
663
|
+
get wakes(): CapturedScheduleWake[];
|
|
664
|
+
wakesFor(scheduleKey: string): CapturedScheduleWake[];
|
|
665
|
+
/** The earliest `at` any wake asked of `scheduleKey`, or undefined if none did. */
|
|
666
|
+
earliestWake(scheduleKey: string): Date | undefined;
|
|
667
|
+
clear(): void;
|
|
668
|
+
}
|
|
655
669
|
interface TestAppOptions {
|
|
656
670
|
/**
|
|
657
671
|
* The LIFF ID the platform forwards to the app for a LINE MINI App shop. It is
|
|
@@ -704,6 +718,8 @@ interface TestApp {
|
|
|
704
718
|
edge: TestEdge;
|
|
705
719
|
/** Scripted replies and captured calls for the Starlens SDK. */
|
|
706
720
|
starlens: TestStarlens;
|
|
721
|
+
/** Wakes the app asked of its adaptive schedules (`wakeSchedule`). */
|
|
722
|
+
schedules: TestSchedules;
|
|
707
723
|
/** Convenience for raw SQL: `app.query("SELECT ...", [param])`. */
|
|
708
724
|
query<T = Record<string, unknown>>(sql: string, params?: unknown[]): Promise<T[]>;
|
|
709
725
|
/**
|
|
@@ -774,4 +790,4 @@ declare const TEST_ENV_DEFAULTS: {
|
|
|
774
790
|
/** Default location of the DDL snapshot written by `generate-types`. */
|
|
775
791
|
declare const DEFAULT_SCHEMA_PATH = "./src/generated/data-store-schema.sql";
|
|
776
792
|
|
|
777
|
-
export { type BindingInfo, CONTROL_PLANE_TEST_URL, type CallRouteOptions, type CapturedCheckout, type CapturedDisplay, type CapturedDurablePrint, type CapturedEmail, type CapturedIdentity, type CapturedIdentityLink, type CapturedMessage, type CapturedPrint, type CapturedStarlensCall, type CapturedTestPrint, type CapturedUpload, DATA_STORE_TEST_HOST, DATA_STORE_TEST_URL, DEFAULT_SCHEMA_PATH, type DeviceInfo, type PaymentSimulatorFailure, type PaymentSimulatorOperation, type PeripheralInfo, STORAGE_TEST_HOST, STORAGE_TEST_URL, type SessionTokens, type SimBoltCharge, type SimBoltConnection, type SimBoltIntentRecord, type SimBoltIntentStatus, type SimulatedDurableOutcome, type StarlensReply, TEST_ENV_DEFAULTS, type TestApp, type TestAppOptions, TestDataStoreInput, type TestDirectory, type TestEdge, type TestInbox, type TestMessages, type TestPayments, type TestStarlens, type TestStorage, type TestUser, WORKFLOW_NAME_PREFIX, callRoute, createTestApp, describeWorkflow, parseWorkflowName };
|
|
793
|
+
export { type BindingInfo, CONTROL_PLANE_TEST_URL, type CallRouteOptions, type CapturedCheckout, type CapturedDisplay, type CapturedDurablePrint, type CapturedEmail, type CapturedIdentity, type CapturedIdentityLink, type CapturedMessage, type CapturedPrint, type CapturedScheduleWake, type CapturedStarlensCall, type CapturedTestPrint, type CapturedUpload, DATA_STORE_TEST_HOST, DATA_STORE_TEST_URL, DEFAULT_SCHEMA_PATH, type DeviceInfo, type PaymentSimulatorFailure, type PaymentSimulatorOperation, type PeripheralInfo, STORAGE_TEST_HOST, STORAGE_TEST_URL, type SessionTokens, type SimBoltCharge, type SimBoltConnection, type SimBoltIntentRecord, type SimBoltIntentStatus, type SimulatedDurableOutcome, type StarlensReply, TEST_ENV_DEFAULTS, type TestApp, type TestAppOptions, TestDataStoreInput, type TestDirectory, type TestEdge, type TestInbox, type TestMessages, type TestPayments, type TestSchedules, type TestStarlens, type TestStorage, type TestUser, WORKFLOW_NAME_PREFIX, callRoute, createTestApp, describeWorkflow, parseWorkflowName };
|
package/dist/index.d.ts
CHANGED
|
@@ -652,6 +652,20 @@ interface TestStarlens {
|
|
|
652
652
|
clear(): void;
|
|
653
653
|
get count(): number;
|
|
654
654
|
}
|
|
655
|
+
/** A wake the app asked for: run `scheduleKey` by `at` (scheduling-sdk `wakeSchedule`). */
|
|
656
|
+
interface CapturedScheduleWake {
|
|
657
|
+
scheduleKey: string;
|
|
658
|
+
at: Date;
|
|
659
|
+
requestedAt: Date;
|
|
660
|
+
}
|
|
661
|
+
interface TestSchedules {
|
|
662
|
+
/** Every wake the app asked for, oldest first. */
|
|
663
|
+
get wakes(): CapturedScheduleWake[];
|
|
664
|
+
wakesFor(scheduleKey: string): CapturedScheduleWake[];
|
|
665
|
+
/** The earliest `at` any wake asked of `scheduleKey`, or undefined if none did. */
|
|
666
|
+
earliestWake(scheduleKey: string): Date | undefined;
|
|
667
|
+
clear(): void;
|
|
668
|
+
}
|
|
655
669
|
interface TestAppOptions {
|
|
656
670
|
/**
|
|
657
671
|
* The LIFF ID the platform forwards to the app for a LINE MINI App shop. It is
|
|
@@ -704,6 +718,8 @@ interface TestApp {
|
|
|
704
718
|
edge: TestEdge;
|
|
705
719
|
/** Scripted replies and captured calls for the Starlens SDK. */
|
|
706
720
|
starlens: TestStarlens;
|
|
721
|
+
/** Wakes the app asked of its adaptive schedules (`wakeSchedule`). */
|
|
722
|
+
schedules: TestSchedules;
|
|
707
723
|
/** Convenience for raw SQL: `app.query("SELECT ...", [param])`. */
|
|
708
724
|
query<T = Record<string, unknown>>(sql: string, params?: unknown[]): Promise<T[]>;
|
|
709
725
|
/**
|
|
@@ -774,4 +790,4 @@ declare const TEST_ENV_DEFAULTS: {
|
|
|
774
790
|
/** Default location of the DDL snapshot written by `generate-types`. */
|
|
775
791
|
declare const DEFAULT_SCHEMA_PATH = "./src/generated/data-store-schema.sql";
|
|
776
792
|
|
|
777
|
-
export { type BindingInfo, CONTROL_PLANE_TEST_URL, type CallRouteOptions, type CapturedCheckout, type CapturedDisplay, type CapturedDurablePrint, type CapturedEmail, type CapturedIdentity, type CapturedIdentityLink, type CapturedMessage, type CapturedPrint, type CapturedStarlensCall, type CapturedTestPrint, type CapturedUpload, DATA_STORE_TEST_HOST, DATA_STORE_TEST_URL, DEFAULT_SCHEMA_PATH, type DeviceInfo, type PaymentSimulatorFailure, type PaymentSimulatorOperation, type PeripheralInfo, STORAGE_TEST_HOST, STORAGE_TEST_URL, type SessionTokens, type SimBoltCharge, type SimBoltConnection, type SimBoltIntentRecord, type SimBoltIntentStatus, type SimulatedDurableOutcome, type StarlensReply, TEST_ENV_DEFAULTS, type TestApp, type TestAppOptions, TestDataStoreInput, type TestDirectory, type TestEdge, type TestInbox, type TestMessages, type TestPayments, type TestStarlens, type TestStorage, type TestUser, WORKFLOW_NAME_PREFIX, callRoute, createTestApp, describeWorkflow, parseWorkflowName };
|
|
793
|
+
export { type BindingInfo, CONTROL_PLANE_TEST_URL, type CallRouteOptions, type CapturedCheckout, type CapturedDisplay, type CapturedDurablePrint, type CapturedEmail, type CapturedIdentity, type CapturedIdentityLink, type CapturedMessage, type CapturedPrint, type CapturedScheduleWake, type CapturedStarlensCall, type CapturedTestPrint, type CapturedUpload, DATA_STORE_TEST_HOST, DATA_STORE_TEST_URL, DEFAULT_SCHEMA_PATH, type DeviceInfo, type PaymentSimulatorFailure, type PaymentSimulatorOperation, type PeripheralInfo, STORAGE_TEST_HOST, STORAGE_TEST_URL, type SessionTokens, type SimBoltCharge, type SimBoltConnection, type SimBoltIntentRecord, type SimBoltIntentStatus, type SimulatedDurableOutcome, type StarlensReply, TEST_ENV_DEFAULTS, type TestApp, type TestAppOptions, TestDataStoreInput, type TestDirectory, type TestEdge, type TestInbox, type TestMessages, type TestPayments, type TestSchedules, type TestStarlens, type TestStorage, type TestUser, WORKFLOW_NAME_PREFIX, callRoute, createTestApp, describeWorkflow, parseWorkflowName };
|
package/dist/index.js
CHANGED
|
@@ -338,6 +338,7 @@ var state = globalSingleton("state", () => ({
|
|
|
338
338
|
identitySuppressClaimDelivery: false,
|
|
339
339
|
identityAllowedReturnOrigins: /* @__PURE__ */ new Set([APP_TEST_ORIGIN]),
|
|
340
340
|
checkouts: [],
|
|
341
|
+
scheduleWakes: [],
|
|
341
342
|
checkoutCounter: 0,
|
|
342
343
|
sessionStatuses: /* @__PURE__ */ new Map(),
|
|
343
344
|
idempotentCheckouts: /* @__PURE__ */ new Map(),
|
|
@@ -3626,6 +3627,32 @@ function createEdge() {
|
|
|
3626
3627
|
};
|
|
3627
3628
|
}
|
|
3628
3629
|
|
|
3630
|
+
// src/simulator/schedules.ts
|
|
3631
|
+
async function handleScheduleWake(request, scheduleKey) {
|
|
3632
|
+
if (request.method !== "POST") return failure(`Method ${request.method} not allowed`, 405);
|
|
3633
|
+
const body = await readJsonBody(request);
|
|
3634
|
+
const at = typeof body.at === "string" ? new Date(body.at) : null;
|
|
3635
|
+
if (!at || Number.isNaN(at.getTime())) return failure("`at` must be an ISO date-time", 400);
|
|
3636
|
+
state.scheduleWakes.push({ scheduleKey, at, requestedAt: /* @__PURE__ */ new Date() });
|
|
3637
|
+
return success({ woken: true });
|
|
3638
|
+
}
|
|
3639
|
+
function createSchedules() {
|
|
3640
|
+
return {
|
|
3641
|
+
get wakes() {
|
|
3642
|
+
return state.scheduleWakes;
|
|
3643
|
+
},
|
|
3644
|
+
wakesFor(scheduleKey) {
|
|
3645
|
+
return state.scheduleWakes.filter((wake) => wake.scheduleKey === scheduleKey);
|
|
3646
|
+
},
|
|
3647
|
+
earliestWake(scheduleKey) {
|
|
3648
|
+
return this.wakesFor(scheduleKey).map((wake) => wake.at).sort((a, b) => a.getTime() - b.getTime())[0];
|
|
3649
|
+
},
|
|
3650
|
+
clear() {
|
|
3651
|
+
state.scheduleWakes = [];
|
|
3652
|
+
}
|
|
3653
|
+
};
|
|
3654
|
+
}
|
|
3655
|
+
|
|
3629
3656
|
// src/simulator/starlens.ts
|
|
3630
3657
|
var LATEST_VERSION = "v2";
|
|
3631
3658
|
function starlensFailure(error, status, code) {
|
|
@@ -3790,8 +3817,10 @@ function requiresDeploymentHmac(request, url) {
|
|
|
3790
3817
|
);
|
|
3791
3818
|
const edgeMatch = url.pathname.match(/^\/api\/deployments\/[^/]+\/edge(\/.*)?$/);
|
|
3792
3819
|
const isStarlens = url.pathname === "/api/starlens/extract";
|
|
3793
|
-
|
|
3820
|
+
const scheduleWakeMatch = url.pathname.match(SCHEDULE_WAKE_PATH);
|
|
3821
|
+
return !!(isStarlens || scheduleWakeMatch || dataStoreMatch || isEmail || identitiesMatch || storeMatch || messagingMatch || edgeMatch);
|
|
3794
3822
|
}
|
|
3823
|
+
var SCHEDULE_WAKE_PATH = /^\/api\/deployments\/[^/]+\/schedules\/([^/]+)\/wake$/;
|
|
3795
3824
|
function deploymentIdFromPath(url) {
|
|
3796
3825
|
const match = url.pathname.match(/\/api\/deployments\/([^/]+)(?:\/|$)/);
|
|
3797
3826
|
if (!match) return null;
|
|
@@ -3856,6 +3885,10 @@ async function handleSimulatedRequest(request, url) {
|
|
|
3856
3885
|
if (edgeMatch) {
|
|
3857
3886
|
return handleEdgeRequest(request, edgeMatch[1] ?? "");
|
|
3858
3887
|
}
|
|
3888
|
+
const scheduleWakeMatch = url.pathname.match(SCHEDULE_WAKE_PATH);
|
|
3889
|
+
if (scheduleWakeMatch) {
|
|
3890
|
+
return handleScheduleWake(request, decodeURIComponent(scheduleWakeMatch[1]));
|
|
3891
|
+
}
|
|
3859
3892
|
if (url.pathname === "/api/starlens/extract" && request.method === "POST") {
|
|
3860
3893
|
return handleStarlensExtract(request, signedDeploymentId);
|
|
3861
3894
|
}
|
|
@@ -3880,7 +3913,7 @@ async function handleSimulatedRequest(request, url) {
|
|
|
3880
3913
|
}
|
|
3881
3914
|
}
|
|
3882
3915
|
return failure(
|
|
3883
|
-
`[stardeck-testing] No simulator for ${request.method} ${url.pathname}. Supported: data-store query/mutate/schema, email send, identities CRUD, payments store/checkout, storage upload/files, messaging send, edge print/display/bindings, starlens extract, auth verify/refresh, Neon /sql.`,
|
|
3916
|
+
`[stardeck-testing] No simulator for ${request.method} ${url.pathname}. Supported: data-store query/mutate/schema, email send, identities CRUD, payments store/checkout, storage upload/files, messaging send, edge print/display/bindings, starlens extract, schedule wakes, auth verify/refresh, Neon /sql.`,
|
|
3884
3917
|
404
|
|
3885
3918
|
);
|
|
3886
3919
|
}
|
|
@@ -4059,6 +4092,7 @@ async function createTestApp(options = {}) {
|
|
|
4059
4092
|
const messages = createMessages();
|
|
4060
4093
|
const edge = createEdge();
|
|
4061
4094
|
const starlens = createStarlens();
|
|
4095
|
+
const schedules = createSchedules();
|
|
4062
4096
|
const app = {
|
|
4063
4097
|
db,
|
|
4064
4098
|
inbox,
|
|
@@ -4068,6 +4102,7 @@ async function createTestApp(options = {}) {
|
|
|
4068
4102
|
messages,
|
|
4069
4103
|
edge,
|
|
4070
4104
|
starlens,
|
|
4105
|
+
schedules,
|
|
4071
4106
|
async query(sql, params = []) {
|
|
4072
4107
|
const result = await db.query(sql, params);
|
|
4073
4108
|
return result.rows;
|
|
@@ -4116,6 +4151,7 @@ async function createTestApp(options = {}) {
|
|
|
4116
4151
|
messages.clear();
|
|
4117
4152
|
edge.clear();
|
|
4118
4153
|
starlens.clear();
|
|
4154
|
+
schedules.clear();
|
|
4119
4155
|
},
|
|
4120
4156
|
async close() {
|
|
4121
4157
|
state.db = null;
|
|
@@ -4131,6 +4167,7 @@ async function createTestApp(options = {}) {
|
|
|
4131
4167
|
messages.clear();
|
|
4132
4168
|
edge.clear();
|
|
4133
4169
|
starlens.clear();
|
|
4170
|
+
schedules.clear();
|
|
4134
4171
|
uninstallFetchRouter();
|
|
4135
4172
|
await db.close();
|
|
4136
4173
|
}
|
package/dist/index.mjs
CHANGED
|
@@ -299,6 +299,7 @@ var state = globalSingleton("state", () => ({
|
|
|
299
299
|
identitySuppressClaimDelivery: false,
|
|
300
300
|
identityAllowedReturnOrigins: /* @__PURE__ */ new Set([APP_TEST_ORIGIN]),
|
|
301
301
|
checkouts: [],
|
|
302
|
+
scheduleWakes: [],
|
|
302
303
|
checkoutCounter: 0,
|
|
303
304
|
sessionStatuses: /* @__PURE__ */ new Map(),
|
|
304
305
|
idempotentCheckouts: /* @__PURE__ */ new Map(),
|
|
@@ -3587,6 +3588,32 @@ function createEdge() {
|
|
|
3587
3588
|
};
|
|
3588
3589
|
}
|
|
3589
3590
|
|
|
3591
|
+
// src/simulator/schedules.ts
|
|
3592
|
+
async function handleScheduleWake(request, scheduleKey) {
|
|
3593
|
+
if (request.method !== "POST") return failure(`Method ${request.method} not allowed`, 405);
|
|
3594
|
+
const body = await readJsonBody(request);
|
|
3595
|
+
const at = typeof body.at === "string" ? new Date(body.at) : null;
|
|
3596
|
+
if (!at || Number.isNaN(at.getTime())) return failure("`at` must be an ISO date-time", 400);
|
|
3597
|
+
state.scheduleWakes.push({ scheduleKey, at, requestedAt: /* @__PURE__ */ new Date() });
|
|
3598
|
+
return success({ woken: true });
|
|
3599
|
+
}
|
|
3600
|
+
function createSchedules() {
|
|
3601
|
+
return {
|
|
3602
|
+
get wakes() {
|
|
3603
|
+
return state.scheduleWakes;
|
|
3604
|
+
},
|
|
3605
|
+
wakesFor(scheduleKey) {
|
|
3606
|
+
return state.scheduleWakes.filter((wake) => wake.scheduleKey === scheduleKey);
|
|
3607
|
+
},
|
|
3608
|
+
earliestWake(scheduleKey) {
|
|
3609
|
+
return this.wakesFor(scheduleKey).map((wake) => wake.at).sort((a, b) => a.getTime() - b.getTime())[0];
|
|
3610
|
+
},
|
|
3611
|
+
clear() {
|
|
3612
|
+
state.scheduleWakes = [];
|
|
3613
|
+
}
|
|
3614
|
+
};
|
|
3615
|
+
}
|
|
3616
|
+
|
|
3590
3617
|
// src/simulator/starlens.ts
|
|
3591
3618
|
var LATEST_VERSION = "v2";
|
|
3592
3619
|
function starlensFailure(error, status, code) {
|
|
@@ -3751,8 +3778,10 @@ function requiresDeploymentHmac(request, url) {
|
|
|
3751
3778
|
);
|
|
3752
3779
|
const edgeMatch = url.pathname.match(/^\/api\/deployments\/[^/]+\/edge(\/.*)?$/);
|
|
3753
3780
|
const isStarlens = url.pathname === "/api/starlens/extract";
|
|
3754
|
-
|
|
3781
|
+
const scheduleWakeMatch = url.pathname.match(SCHEDULE_WAKE_PATH);
|
|
3782
|
+
return !!(isStarlens || scheduleWakeMatch || dataStoreMatch || isEmail || identitiesMatch || storeMatch || messagingMatch || edgeMatch);
|
|
3755
3783
|
}
|
|
3784
|
+
var SCHEDULE_WAKE_PATH = /^\/api\/deployments\/[^/]+\/schedules\/([^/]+)\/wake$/;
|
|
3756
3785
|
function deploymentIdFromPath(url) {
|
|
3757
3786
|
const match = url.pathname.match(/\/api\/deployments\/([^/]+)(?:\/|$)/);
|
|
3758
3787
|
if (!match) return null;
|
|
@@ -3817,6 +3846,10 @@ async function handleSimulatedRequest(request, url) {
|
|
|
3817
3846
|
if (edgeMatch) {
|
|
3818
3847
|
return handleEdgeRequest(request, edgeMatch[1] ?? "");
|
|
3819
3848
|
}
|
|
3849
|
+
const scheduleWakeMatch = url.pathname.match(SCHEDULE_WAKE_PATH);
|
|
3850
|
+
if (scheduleWakeMatch) {
|
|
3851
|
+
return handleScheduleWake(request, decodeURIComponent(scheduleWakeMatch[1]));
|
|
3852
|
+
}
|
|
3820
3853
|
if (url.pathname === "/api/starlens/extract" && request.method === "POST") {
|
|
3821
3854
|
return handleStarlensExtract(request, signedDeploymentId);
|
|
3822
3855
|
}
|
|
@@ -3841,7 +3874,7 @@ async function handleSimulatedRequest(request, url) {
|
|
|
3841
3874
|
}
|
|
3842
3875
|
}
|
|
3843
3876
|
return failure(
|
|
3844
|
-
`[stardeck-testing] No simulator for ${request.method} ${url.pathname}. Supported: data-store query/mutate/schema, email send, identities CRUD, payments store/checkout, storage upload/files, messaging send, edge print/display/bindings, starlens extract, auth verify/refresh, Neon /sql.`,
|
|
3877
|
+
`[stardeck-testing] No simulator for ${request.method} ${url.pathname}. Supported: data-store query/mutate/schema, email send, identities CRUD, payments store/checkout, storage upload/files, messaging send, edge print/display/bindings, starlens extract, schedule wakes, auth verify/refresh, Neon /sql.`,
|
|
3845
3878
|
404
|
|
3846
3879
|
);
|
|
3847
3880
|
}
|
|
@@ -4020,6 +4053,7 @@ async function createTestApp(options = {}) {
|
|
|
4020
4053
|
const messages = createMessages();
|
|
4021
4054
|
const edge = createEdge();
|
|
4022
4055
|
const starlens = createStarlens();
|
|
4056
|
+
const schedules = createSchedules();
|
|
4023
4057
|
const app = {
|
|
4024
4058
|
db,
|
|
4025
4059
|
inbox,
|
|
@@ -4029,6 +4063,7 @@ async function createTestApp(options = {}) {
|
|
|
4029
4063
|
messages,
|
|
4030
4064
|
edge,
|
|
4031
4065
|
starlens,
|
|
4066
|
+
schedules,
|
|
4032
4067
|
async query(sql, params = []) {
|
|
4033
4068
|
const result = await db.query(sql, params);
|
|
4034
4069
|
return result.rows;
|
|
@@ -4077,6 +4112,7 @@ async function createTestApp(options = {}) {
|
|
|
4077
4112
|
messages.clear();
|
|
4078
4113
|
edge.clear();
|
|
4079
4114
|
starlens.clear();
|
|
4115
|
+
schedules.clear();
|
|
4080
4116
|
},
|
|
4081
4117
|
async close() {
|
|
4082
4118
|
state.db = null;
|
|
@@ -4092,6 +4128,7 @@ async function createTestApp(options = {}) {
|
|
|
4092
4128
|
messages.clear();
|
|
4093
4129
|
edge.clear();
|
|
4094
4130
|
starlens.clear();
|
|
4131
|
+
schedules.clear();
|
|
4095
4132
|
uninstallFetchRouter();
|
|
4096
4133
|
await db.close();
|
|
4097
4134
|
}
|
|
@@ -60,6 +60,7 @@ var state = globalSingleton("state", () => ({
|
|
|
60
60
|
identitySuppressClaimDelivery: false,
|
|
61
61
|
identityAllowedReturnOrigins: /* @__PURE__ */ new Set([APP_TEST_ORIGIN]),
|
|
62
62
|
checkouts: [],
|
|
63
|
+
scheduleWakes: [],
|
|
63
64
|
checkoutCounter: 0,
|
|
64
65
|
sessionStatuses: /* @__PURE__ */ new Map(),
|
|
65
66
|
idempotentCheckouts: /* @__PURE__ */ new Map(),
|
|
@@ -33,6 +33,7 @@ var state = globalSingleton("state", () => ({
|
|
|
33
33
|
identitySuppressClaimDelivery: false,
|
|
34
34
|
identityAllowedReturnOrigins: /* @__PURE__ */ new Set([APP_TEST_ORIGIN]),
|
|
35
35
|
checkouts: [],
|
|
36
|
+
scheduleWakes: [],
|
|
36
37
|
checkoutCounter: 0,
|
|
37
38
|
sessionStatuses: /* @__PURE__ */ new Map(),
|
|
38
39
|
idempotentCheckouts: /* @__PURE__ */ new Map(),
|
package/dist/setup.js
CHANGED
|
@@ -65,6 +65,7 @@ var state = globalSingleton("state", () => ({
|
|
|
65
65
|
identitySuppressClaimDelivery: false,
|
|
66
66
|
identityAllowedReturnOrigins: /* @__PURE__ */ new Set([APP_TEST_ORIGIN]),
|
|
67
67
|
checkouts: [],
|
|
68
|
+
scheduleWakes: [],
|
|
68
69
|
checkoutCounter: 0,
|
|
69
70
|
sessionStatuses: /* @__PURE__ */ new Map(),
|
|
70
71
|
idempotentCheckouts: /* @__PURE__ */ new Map(),
|
|
@@ -2707,6 +2708,16 @@ async function handleEdgeRequest(request, subPath) {
|
|
|
2707
2708
|
return edgeFailure(`No edge simulator for ${method} .../edge${subPath}`, 404);
|
|
2708
2709
|
}
|
|
2709
2710
|
|
|
2711
|
+
// src/simulator/schedules.ts
|
|
2712
|
+
async function handleScheduleWake(request, scheduleKey) {
|
|
2713
|
+
if (request.method !== "POST") return failure(`Method ${request.method} not allowed`, 405);
|
|
2714
|
+
const body = await readJsonBody(request);
|
|
2715
|
+
const at = typeof body.at === "string" ? new Date(body.at) : null;
|
|
2716
|
+
if (!at || Number.isNaN(at.getTime())) return failure("`at` must be an ISO date-time", 400);
|
|
2717
|
+
state.scheduleWakes.push({ scheduleKey, at, requestedAt: /* @__PURE__ */ new Date() });
|
|
2718
|
+
return success({ woken: true });
|
|
2719
|
+
}
|
|
2720
|
+
|
|
2710
2721
|
// src/simulator/starlens.ts
|
|
2711
2722
|
var LATEST_VERSION = "v2";
|
|
2712
2723
|
function starlensFailure(error, status, code) {
|
|
@@ -2844,8 +2855,10 @@ function requiresDeploymentHmac(request, url) {
|
|
|
2844
2855
|
);
|
|
2845
2856
|
const edgeMatch = url.pathname.match(/^\/api\/deployments\/[^/]+\/edge(\/.*)?$/);
|
|
2846
2857
|
const isStarlens = url.pathname === "/api/starlens/extract";
|
|
2847
|
-
|
|
2858
|
+
const scheduleWakeMatch = url.pathname.match(SCHEDULE_WAKE_PATH);
|
|
2859
|
+
return !!(isStarlens || scheduleWakeMatch || dataStoreMatch || isEmail || identitiesMatch || storeMatch || messagingMatch || edgeMatch);
|
|
2848
2860
|
}
|
|
2861
|
+
var SCHEDULE_WAKE_PATH = /^\/api\/deployments\/[^/]+\/schedules\/([^/]+)\/wake$/;
|
|
2849
2862
|
function deploymentIdFromPath(url) {
|
|
2850
2863
|
const match = url.pathname.match(/\/api\/deployments\/([^/]+)(?:\/|$)/);
|
|
2851
2864
|
if (!match) return null;
|
|
@@ -2910,6 +2923,10 @@ async function handleSimulatedRequest(request, url) {
|
|
|
2910
2923
|
if (edgeMatch) {
|
|
2911
2924
|
return handleEdgeRequest(request, edgeMatch[1] ?? "");
|
|
2912
2925
|
}
|
|
2926
|
+
const scheduleWakeMatch = url.pathname.match(SCHEDULE_WAKE_PATH);
|
|
2927
|
+
if (scheduleWakeMatch) {
|
|
2928
|
+
return handleScheduleWake(request, decodeURIComponent(scheduleWakeMatch[1]));
|
|
2929
|
+
}
|
|
2913
2930
|
if (url.pathname === "/api/starlens/extract" && request.method === "POST") {
|
|
2914
2931
|
return handleStarlensExtract(request, signedDeploymentId);
|
|
2915
2932
|
}
|
|
@@ -2934,7 +2951,7 @@ async function handleSimulatedRequest(request, url) {
|
|
|
2934
2951
|
}
|
|
2935
2952
|
}
|
|
2936
2953
|
return failure(
|
|
2937
|
-
`[stardeck-testing] No simulator for ${request.method} ${url.pathname}. Supported: data-store query/mutate/schema, email send, identities CRUD, payments store/checkout, storage upload/files, messaging send, edge print/display/bindings, starlens extract, auth verify/refresh, Neon /sql.`,
|
|
2954
|
+
`[stardeck-testing] No simulator for ${request.method} ${url.pathname}. Supported: data-store query/mutate/schema, email send, identities CRUD, payments store/checkout, storage upload/files, messaging send, edge print/display/bindings, starlens extract, schedule wakes, auth verify/refresh, Neon /sql.`,
|
|
2938
2955
|
404
|
|
2939
2956
|
);
|
|
2940
2957
|
}
|
package/dist/setup.mjs
CHANGED
|
@@ -41,6 +41,7 @@ var state = globalSingleton("state", () => ({
|
|
|
41
41
|
identitySuppressClaimDelivery: false,
|
|
42
42
|
identityAllowedReturnOrigins: /* @__PURE__ */ new Set([APP_TEST_ORIGIN]),
|
|
43
43
|
checkouts: [],
|
|
44
|
+
scheduleWakes: [],
|
|
44
45
|
checkoutCounter: 0,
|
|
45
46
|
sessionStatuses: /* @__PURE__ */ new Map(),
|
|
46
47
|
idempotentCheckouts: /* @__PURE__ */ new Map(),
|
|
@@ -2683,6 +2684,16 @@ async function handleEdgeRequest(request, subPath) {
|
|
|
2683
2684
|
return edgeFailure(`No edge simulator for ${method} .../edge${subPath}`, 404);
|
|
2684
2685
|
}
|
|
2685
2686
|
|
|
2687
|
+
// src/simulator/schedules.ts
|
|
2688
|
+
async function handleScheduleWake(request, scheduleKey) {
|
|
2689
|
+
if (request.method !== "POST") return failure(`Method ${request.method} not allowed`, 405);
|
|
2690
|
+
const body = await readJsonBody(request);
|
|
2691
|
+
const at = typeof body.at === "string" ? new Date(body.at) : null;
|
|
2692
|
+
if (!at || Number.isNaN(at.getTime())) return failure("`at` must be an ISO date-time", 400);
|
|
2693
|
+
state.scheduleWakes.push({ scheduleKey, at, requestedAt: /* @__PURE__ */ new Date() });
|
|
2694
|
+
return success({ woken: true });
|
|
2695
|
+
}
|
|
2696
|
+
|
|
2686
2697
|
// src/simulator/starlens.ts
|
|
2687
2698
|
var LATEST_VERSION = "v2";
|
|
2688
2699
|
function starlensFailure(error, status, code) {
|
|
@@ -2820,8 +2831,10 @@ function requiresDeploymentHmac(request, url) {
|
|
|
2820
2831
|
);
|
|
2821
2832
|
const edgeMatch = url.pathname.match(/^\/api\/deployments\/[^/]+\/edge(\/.*)?$/);
|
|
2822
2833
|
const isStarlens = url.pathname === "/api/starlens/extract";
|
|
2823
|
-
|
|
2834
|
+
const scheduleWakeMatch = url.pathname.match(SCHEDULE_WAKE_PATH);
|
|
2835
|
+
return !!(isStarlens || scheduleWakeMatch || dataStoreMatch || isEmail || identitiesMatch || storeMatch || messagingMatch || edgeMatch);
|
|
2824
2836
|
}
|
|
2837
|
+
var SCHEDULE_WAKE_PATH = /^\/api\/deployments\/[^/]+\/schedules\/([^/]+)\/wake$/;
|
|
2825
2838
|
function deploymentIdFromPath(url) {
|
|
2826
2839
|
const match = url.pathname.match(/\/api\/deployments\/([^/]+)(?:\/|$)/);
|
|
2827
2840
|
if (!match) return null;
|
|
@@ -2886,6 +2899,10 @@ async function handleSimulatedRequest(request, url) {
|
|
|
2886
2899
|
if (edgeMatch) {
|
|
2887
2900
|
return handleEdgeRequest(request, edgeMatch[1] ?? "");
|
|
2888
2901
|
}
|
|
2902
|
+
const scheduleWakeMatch = url.pathname.match(SCHEDULE_WAKE_PATH);
|
|
2903
|
+
if (scheduleWakeMatch) {
|
|
2904
|
+
return handleScheduleWake(request, decodeURIComponent(scheduleWakeMatch[1]));
|
|
2905
|
+
}
|
|
2889
2906
|
if (url.pathname === "/api/starlens/extract" && request.method === "POST") {
|
|
2890
2907
|
return handleStarlensExtract(request, signedDeploymentId);
|
|
2891
2908
|
}
|
|
@@ -2910,7 +2927,7 @@ async function handleSimulatedRequest(request, url) {
|
|
|
2910
2927
|
}
|
|
2911
2928
|
}
|
|
2912
2929
|
return failure(
|
|
2913
|
-
`[stardeck-testing] No simulator for ${request.method} ${url.pathname}. Supported: data-store query/mutate/schema, email send, identities CRUD, payments store/checkout, storage upload/files, messaging send, edge print/display/bindings, starlens extract, auth verify/refresh, Neon /sql.`,
|
|
2930
|
+
`[stardeck-testing] No simulator for ${request.method} ${url.pathname}. Supported: data-store query/mutate/schema, email send, identities CRUD, payments store/checkout, storage upload/files, messaging send, edge print/display/bindings, starlens extract, schedule wakes, auth verify/refresh, Neon /sql.`,
|
|
2914
2931
|
404
|
|
2915
2932
|
);
|
|
2916
2933
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@stardeck-customer-apps/testing",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.26.0",
|
|
4
4
|
"description": "Vitest test harness for Stardeck customer apps — in-process Postgres (PGlite) plus a control-plane simulator so the real Stardeck SDKs run unmodified in tests",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"module": "dist/index.mjs",
|
|
@@ -100,6 +100,7 @@
|
|
|
100
100
|
"@stardeck-customer-apps/email-sdk": "*",
|
|
101
101
|
"@stardeck-customer-apps/integrations-sdk": "*",
|
|
102
102
|
"@stardeck-customer-apps/payments-sdk": "*",
|
|
103
|
+
"@stardeck-customer-apps/scheduling-sdk": "*",
|
|
103
104
|
"@stardeck-customer-apps/storage-sdk": "*",
|
|
104
105
|
"@stardeck-customer-apps/tsconfig": "*",
|
|
105
106
|
"@types/node": "^24.10.1",
|