@palbase/backend 0.7.0 → 0.10.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/dist/chunk-4J3F32SH.js +96 -0
- package/dist/chunk-4J3F32SH.js.map +1 -0
- package/dist/db/index.cjs +12 -12
- package/dist/db/index.cjs.map +1 -1
- package/dist/db/index.d.cts +3 -70
- package/dist/db/index.d.ts +3 -70
- package/dist/db/index.js +11 -83
- package/dist/db/index.js.map +1 -1
- package/dist/endpoint-6LeBP-eb.d.cts +1435 -0
- package/dist/endpoint-BbbU1hE1.d.ts +1435 -0
- package/dist/index.cjs +132 -0
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +12 -20
- package/dist/index.d.ts +12 -20
- package/dist/index.js +50 -0
- package/dist/index.js.map +1 -1
- package/dist/schema-zk-a0Dv7.d.cts +133 -0
- package/dist/schema-zk-a0Dv7.d.ts +133 -0
- package/dist/test/index.cjs +174 -13
- package/dist/test/index.cjs.map +1 -1
- package/dist/test/index.d.cts +2 -1
- package/dist/test/index.d.ts +2 -1
- package/dist/test/index.js +174 -13
- package/dist/test/index.js.map +1 -1
- package/package.json +3 -1
- package/dist/endpoint-tZi55HU8.d.cts +0 -115
- package/dist/endpoint-tZi55HU8.d.ts +0 -115
package/dist/test/index.cjs
CHANGED
|
@@ -33,7 +33,10 @@ function createMockDB() {
|
|
|
33
33
|
updated: /* @__PURE__ */ new Map(),
|
|
34
34
|
deleted: /* @__PURE__ */ new Map()
|
|
35
35
|
};
|
|
36
|
-
|
|
36
|
+
const ops = {
|
|
37
|
+
async query(_sql, _params) {
|
|
38
|
+
return [];
|
|
39
|
+
},
|
|
37
40
|
async insert(table, data) {
|
|
38
41
|
const record = { id: crypto.randomUUID(), ...data };
|
|
39
42
|
if (!store.has(table)) store.set(table, []);
|
|
@@ -70,6 +73,12 @@ function createMockDB() {
|
|
|
70
73
|
return rows.filter(
|
|
71
74
|
(row) => Object.entries(query).every(([key, val]) => row[key] === val)
|
|
72
75
|
);
|
|
76
|
+
}
|
|
77
|
+
};
|
|
78
|
+
return {
|
|
79
|
+
...ops,
|
|
80
|
+
transaction(fn) {
|
|
81
|
+
return fn(ops);
|
|
73
82
|
},
|
|
74
83
|
inserted(table) {
|
|
75
84
|
return tracked.inserted.get(table) ?? [];
|
|
@@ -105,28 +114,173 @@ function createMockLogger(logs) {
|
|
|
105
114
|
}
|
|
106
115
|
function createMockCache() {
|
|
107
116
|
const store = /* @__PURE__ */ new Map();
|
|
117
|
+
const get = async (key) => {
|
|
118
|
+
return store.has(key) ? store.get(key) : null;
|
|
119
|
+
};
|
|
120
|
+
const set = async (key, value, _ttl) => {
|
|
121
|
+
store.set(key, value);
|
|
122
|
+
};
|
|
108
123
|
return {
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
},
|
|
112
|
-
async set(key, value, _ttl) {
|
|
113
|
-
store.set(key, value);
|
|
114
|
-
},
|
|
124
|
+
get,
|
|
125
|
+
set,
|
|
115
126
|
async del(key) {
|
|
116
127
|
store.delete(key);
|
|
117
128
|
},
|
|
118
129
|
async incr(key) {
|
|
119
|
-
const
|
|
130
|
+
const raw = store.get(key);
|
|
131
|
+
const current = typeof raw === "number" ? raw : parseInt(String(raw ?? "0"), 10);
|
|
120
132
|
const next = current + 1;
|
|
121
|
-
store.set(key,
|
|
133
|
+
store.set(key, next);
|
|
122
134
|
return next;
|
|
135
|
+
},
|
|
136
|
+
async getOrSet(key, ttl, fn) {
|
|
137
|
+
const hit = await get(key);
|
|
138
|
+
if (hit !== null) {
|
|
139
|
+
return hit;
|
|
140
|
+
}
|
|
141
|
+
const value = await fn();
|
|
142
|
+
await set(key, value, ttl);
|
|
143
|
+
return value;
|
|
123
144
|
}
|
|
124
145
|
};
|
|
125
146
|
}
|
|
126
|
-
function
|
|
147
|
+
function createMockModuleClients() {
|
|
148
|
+
const notImpl = (label) => {
|
|
149
|
+
throw new Error(
|
|
150
|
+
`${label} not configured in test mock \u2014 override ctx.${label.split(".")[0]} on the returned context`
|
|
151
|
+
);
|
|
152
|
+
};
|
|
153
|
+
const docs = {
|
|
154
|
+
collection: () => notImpl("docs.collection"),
|
|
155
|
+
doc: () => notImpl("docs.doc")
|
|
156
|
+
};
|
|
157
|
+
const auth = {
|
|
158
|
+
verifyUserToken: () => notImpl("auth.verifyUserToken"),
|
|
159
|
+
getSession: () => notImpl("auth.getSession"),
|
|
160
|
+
mfa: {
|
|
161
|
+
enroll: () => notImpl("auth.mfa.enroll"),
|
|
162
|
+
verifyEnrollment: () => notImpl("auth.mfa.verifyEnrollment"),
|
|
163
|
+
challenge: () => notImpl("auth.mfa.challenge"),
|
|
164
|
+
recovery: () => notImpl("auth.mfa.recovery"),
|
|
165
|
+
listFactors: () => notImpl("auth.mfa.listFactors"),
|
|
166
|
+
removeFactor: () => notImpl("auth.mfa.removeFactor"),
|
|
167
|
+
regenerateRecoveryCodes: () => notImpl("auth.mfa.regenerateRecoveryCodes"),
|
|
168
|
+
emailEnroll: () => notImpl("auth.mfa.emailEnroll"),
|
|
169
|
+
emailChallenge: () => notImpl("auth.mfa.emailChallenge"),
|
|
170
|
+
emailVerify: () => notImpl("auth.mfa.emailVerify")
|
|
171
|
+
},
|
|
172
|
+
device: {
|
|
173
|
+
generateChallenge: () => notImpl("auth.device.generateChallenge"),
|
|
174
|
+
attestAndroid: () => notImpl("auth.device.attestAndroid"),
|
|
175
|
+
attestiOS: () => notImpl("auth.device.attestiOS"),
|
|
176
|
+
bind: () => notImpl("auth.device.bind"),
|
|
177
|
+
list: () => notImpl("auth.device.list"),
|
|
178
|
+
delete: () => notImpl("auth.device.delete"),
|
|
179
|
+
verifyRequestSignature: () => notImpl("auth.device.verifyRequestSignature"),
|
|
180
|
+
getToken: () => notImpl("auth.device.getToken"),
|
|
181
|
+
get isActive() {
|
|
182
|
+
return notImpl("auth.device.isActive");
|
|
183
|
+
},
|
|
184
|
+
setCachedToken: () => notImpl("auth.device.setCachedToken"),
|
|
185
|
+
dispose: () => notImpl("auth.device.dispose")
|
|
186
|
+
}
|
|
187
|
+
};
|
|
188
|
+
const storage = {
|
|
189
|
+
bucket: () => notImpl("storage.bucket")
|
|
190
|
+
};
|
|
191
|
+
const realtime = {
|
|
192
|
+
channel: () => notImpl("realtime.channel"),
|
|
193
|
+
removeChannel: () => notImpl("realtime.removeChannel"),
|
|
194
|
+
removeAllChannels: () => notImpl("realtime.removeAllChannels")
|
|
195
|
+
};
|
|
196
|
+
const functions = {
|
|
197
|
+
invoke: () => notImpl("functions.invoke")
|
|
198
|
+
};
|
|
199
|
+
const flags = {
|
|
200
|
+
isEnabled: () => notImpl("flags.isEnabled"),
|
|
201
|
+
getVariant: () => notImpl("flags.getVariant"),
|
|
202
|
+
getAll: () => notImpl("flags.getAll")
|
|
203
|
+
};
|
|
204
|
+
const notifications = {
|
|
205
|
+
push: { send: () => notImpl("notifications.push.send") },
|
|
206
|
+
email: { send: () => notImpl("notifications.email.send") },
|
|
207
|
+
sms: { send: () => notImpl("notifications.sms.send") },
|
|
208
|
+
inbox: {
|
|
209
|
+
send: () => notImpl("notifications.inbox.send"),
|
|
210
|
+
list: () => notImpl("notifications.inbox.list"),
|
|
211
|
+
unreadCount: () => notImpl("notifications.inbox.unreadCount"),
|
|
212
|
+
markRead: () => notImpl("notifications.inbox.markRead"),
|
|
213
|
+
markAllRead: () => notImpl("notifications.inbox.markAllRead"),
|
|
214
|
+
archive: () => notImpl("notifications.inbox.archive")
|
|
215
|
+
},
|
|
216
|
+
preferences: {
|
|
217
|
+
get: () => notImpl("notifications.preferences.get"),
|
|
218
|
+
update: () => notImpl("notifications.preferences.update")
|
|
219
|
+
},
|
|
220
|
+
templates: {
|
|
221
|
+
email: {
|
|
222
|
+
list: () => notImpl("notifications.templates.email.list"),
|
|
223
|
+
get: () => notImpl("notifications.templates.email.get"),
|
|
224
|
+
create: () => notImpl("notifications.templates.email.create"),
|
|
225
|
+
update: () => notImpl("notifications.templates.email.update"),
|
|
226
|
+
delete: () => notImpl("notifications.templates.email.delete")
|
|
227
|
+
},
|
|
228
|
+
sms: {
|
|
229
|
+
list: () => notImpl("notifications.templates.sms.list"),
|
|
230
|
+
get: () => notImpl("notifications.templates.sms.get"),
|
|
231
|
+
create: () => notImpl("notifications.templates.sms.create"),
|
|
232
|
+
update: () => notImpl("notifications.templates.sms.update"),
|
|
233
|
+
delete: () => notImpl("notifications.templates.sms.delete")
|
|
234
|
+
}
|
|
235
|
+
},
|
|
236
|
+
registerDevice: () => notImpl("notifications.registerDevice"),
|
|
237
|
+
unregisterDevice: () => notImpl("notifications.unregisterDevice")
|
|
238
|
+
};
|
|
239
|
+
const analytics = {
|
|
240
|
+
capture: () => notImpl("analytics.capture"),
|
|
241
|
+
identify: () => notImpl("analytics.identify"),
|
|
242
|
+
screen: () => notImpl("analytics.screen"),
|
|
243
|
+
query: {
|
|
244
|
+
count: () => notImpl("analytics.query.count"),
|
|
245
|
+
events: () => notImpl("analytics.query.events"),
|
|
246
|
+
properties: () => notImpl("analytics.query.properties"),
|
|
247
|
+
users: () => notImpl("analytics.query.users"),
|
|
248
|
+
funnel: () => notImpl("analytics.query.funnel"),
|
|
249
|
+
retention: () => notImpl("analytics.query.retention"),
|
|
250
|
+
cohort: () => notImpl("analytics.query.cohort")
|
|
251
|
+
},
|
|
252
|
+
management: {
|
|
253
|
+
overview: () => notImpl("analytics.management.overview"),
|
|
254
|
+
eventNames: () => notImpl("analytics.management.eventNames"),
|
|
255
|
+
userDetail: () => notImpl("analytics.management.userDetail"),
|
|
256
|
+
deleteUser: () => notImpl("analytics.management.deleteUser")
|
|
257
|
+
}
|
|
258
|
+
};
|
|
259
|
+
const links = {
|
|
260
|
+
create: () => notImpl("links.create"),
|
|
261
|
+
list: () => notImpl("links.list"),
|
|
262
|
+
get: () => notImpl("links.get"),
|
|
263
|
+
update: () => notImpl("links.update"),
|
|
264
|
+
delete: () => notImpl("links.delete"),
|
|
265
|
+
analytics: () => notImpl("links.analytics"),
|
|
266
|
+
qrCode: () => notImpl("links.qrCode"),
|
|
267
|
+
match: () => notImpl("links.match")
|
|
268
|
+
};
|
|
269
|
+
const cms = {
|
|
270
|
+
find: () => notImpl("cms.find"),
|
|
271
|
+
findOne: () => notImpl("cms.findOne")
|
|
272
|
+
};
|
|
127
273
|
return {
|
|
128
|
-
auth
|
|
129
|
-
storage
|
|
274
|
+
auth,
|
|
275
|
+
storage,
|
|
276
|
+
docs,
|
|
277
|
+
realtime,
|
|
278
|
+
functions,
|
|
279
|
+
flags,
|
|
280
|
+
notifications,
|
|
281
|
+
analytics,
|
|
282
|
+
links,
|
|
283
|
+
cms
|
|
130
284
|
};
|
|
131
285
|
}
|
|
132
286
|
function createTestContext(options = {}) {
|
|
@@ -137,17 +291,24 @@ function createTestContext(options = {}) {
|
|
|
137
291
|
db.seed(table, data);
|
|
138
292
|
}
|
|
139
293
|
}
|
|
294
|
+
const mockQueue = {
|
|
295
|
+
push: async (_worker, _payload) => ({ jobId: "" })
|
|
296
|
+
};
|
|
140
297
|
const ctx = {
|
|
141
298
|
input: options.input ?? {},
|
|
142
299
|
params: options.params ?? {},
|
|
143
300
|
query: options.query ?? {},
|
|
144
301
|
headers: options.headers ?? {},
|
|
145
302
|
user: options.user ?? null,
|
|
303
|
+
method: "POST",
|
|
304
|
+
endpointPath: "/test",
|
|
305
|
+
file: null,
|
|
146
306
|
db,
|
|
147
307
|
env: options.env ?? {},
|
|
148
308
|
log: createMockLogger(logs),
|
|
149
309
|
cache: createMockCache(),
|
|
150
|
-
|
|
310
|
+
queue: mockQueue,
|
|
311
|
+
...createMockModuleClients(),
|
|
151
312
|
requestId: "req_test_000000000000",
|
|
152
313
|
projectId: "proj_test_000000000000",
|
|
153
314
|
environmentId: "env_test_000000000000",
|
package/dist/test/index.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/test/index.ts","../../src/test/mock-db.ts","../../src/test/context.ts"],"sourcesContent":["export { createTestContext } from \"./context.js\";\nexport type { TestContextOptions, TestContext, LogEntry } from \"./context.js\";\nexport { createMockDB } from \"./mock-db.js\";\nexport type { MockDBClient } from \"./mock-db.js\";\n","import type { DBClient } from \"../endpoint.js\";\n\n/** Tracked records for assertions. */\ninterface TrackedRecords {\n inserted: Map<string, Record<string, unknown>[]>;\n updated: Map<string, Record<string, unknown>[]>;\n deleted: Map<string, string[]>;\n}\n\n/** Mock DB client with tracking and seed data support. */\nexport interface MockDBClient extends DBClient {\n /** Get records inserted into a table. */\n inserted(table: string): Record<string, unknown>[];\n /** Get records updated in a table. */\n updated(table: string): Record<string, unknown>[];\n /** Get IDs deleted from a table. */\n deleted(table: string): string[];\n /** Pre-seed data into a table for findById/findMany. */\n seed(table: string, data: Record<string, unknown>[]): void;\n}\n\n/** Create a mock DB client with in-memory tracking. */\nexport function createMockDB(): MockDBClient {\n const store = new Map<string, Record<string, unknown>[]>();\n const tracked: TrackedRecords = {\n inserted: new Map(),\n updated: new Map(),\n deleted: new Map(),\n };\n\n return {\n async insert(table: string, data: Record<string, unknown>) {\n const record = { id: crypto.randomUUID(), ...data };\n if (!store.has(table)) store.set(table, []);\n store.get(table)!.push(record);\n if (!tracked.inserted.has(table)) tracked.inserted.set(table, []);\n tracked.inserted.get(table)!.push(record);\n return record;\n },\n\n async update(table: string, id: string, data: Record<string, unknown>) {\n const rows = store.get(table) ?? [];\n const idx = rows.findIndex((r) => r[\"id\"] === id);\n const updated = idx >= 0\n ? { ...rows[idx], ...data }\n : { id, ...data };\n if (idx >= 0) {\n rows[idx] = updated;\n }\n if (!tracked.updated.has(table)) tracked.updated.set(table, []);\n tracked.updated.get(table)!.push(updated);\n return updated;\n },\n\n async delete(table: string, id: string) {\n const rows = store.get(table) ?? [];\n const idx = rows.findIndex((r) => r[\"id\"] === id);\n if (idx >= 0) rows.splice(idx, 1);\n if (!tracked.deleted.has(table)) tracked.deleted.set(table, []);\n tracked.deleted.get(table)!.push(id);\n },\n\n async findById(table: string, id: string) {\n const rows = store.get(table) ?? [];\n return rows.find((r) => r[\"id\"] === id) ?? null;\n },\n\n async findMany(table: string, query?: Record<string, unknown>) {\n const rows = store.get(table) ?? [];\n if (!query) return rows;\n return rows.filter((row) =>\n Object.entries(query).every(([key, val]) => row[key] === val),\n );\n },\n\n inserted(table: string) {\n return tracked.inserted.get(table) ?? [];\n },\n\n updated(table: string) {\n return tracked.updated.get(table) ?? [];\n },\n\n deleted(table: string) {\n return tracked.deleted.get(table) ?? [];\n },\n\n seed(table: string, data: Record<string, unknown>[]) {\n store.set(table, [...data]);\n },\n };\n}\n","import type {\n CacheClient,\n EndpointContext,\n Logger,\n PalbaseBindings,\n} from \"../endpoint.js\";\nimport type { User } from \"../types.js\";\nimport { createMockDB, type MockDBClient } from \"./mock-db.js\";\n\n/** Options for creating a test context. */\nexport interface TestContextOptions<TInput = unknown> {\n user?: User | null;\n input?: TInput;\n params?: Record<string, string>;\n query?: Record<string, string>;\n headers?: Record<string, string>;\n env?: Record<string, string>;\n db?: { seed?: Record<string, Record<string, unknown>[]> };\n}\n\n/** Log entry captured by the mock logger. */\nexport interface LogEntry {\n level: \"info\" | \"warn\" | \"error\" | \"debug\";\n message: string;\n args: unknown[];\n}\n\n/** Test context with mock helpers exposed. */\nexport interface TestContext<TInput = unknown> extends EndpointContext<TInput> {\n db: MockDBClient;\n /** Captured log entries. */\n logs: LogEntry[];\n}\n\n/** Create a mock logger that captures entries. */\nfunction createMockLogger(logs: LogEntry[]): Logger {\n return {\n info(message: string, ...args: unknown[]) {\n logs.push({ level: \"info\", message, args });\n },\n warn(message: string, ...args: unknown[]) {\n logs.push({ level: \"warn\", message, args });\n },\n error(message: string, ...args: unknown[]) {\n logs.push({ level: \"error\", message, args });\n },\n debug(message: string, ...args: unknown[]) {\n logs.push({ level: \"debug\", message, args });\n },\n };\n}\n\n/** Create a mock in-memory cache. */\nfunction createMockCache(): CacheClient {\n const store = new Map<string, string>();\n\n return {\n async get(key: string) {\n return store.get(key) ?? null;\n },\n async set(key: string, value: string, _ttl?: number) {\n store.set(key, value);\n },\n async del(key: string) {\n store.delete(key);\n },\n async incr(key: string) {\n const current = parseInt(store.get(key) ?? \"0\", 10);\n const next = current + 1;\n store.set(key, String(next));\n return next;\n },\n };\n}\n\n/** Create a mock Palbase service bindings. */\nfunction createMockPalbase(): PalbaseBindings {\n return {\n auth: {},\n storage: {},\n };\n}\n\n/** Create a fully mocked EndpointContext for testing user endpoints. */\nexport function createTestContext<TInput = unknown>(\n options: TestContextOptions<TInput> = {},\n): TestContext<TInput> {\n const logs: LogEntry[] = [];\n const db = createMockDB();\n\n // Seed data if provided\n if (options.db?.seed) {\n for (const [table, data] of Object.entries(options.db.seed)) {\n db.seed(table, data);\n }\n }\n\n const ctx: TestContext<TInput> = {\n input: (options.input ?? {}) as TInput,\n params: options.params ?? {},\n query: options.query ?? {},\n headers: options.headers ?? {},\n user: options.user ?? null,\n db,\n env: options.env ?? {},\n log: createMockLogger(logs),\n cache: createMockCache(),\n palbase: createMockPalbase(),\n requestId: \"req_test_000000000000\",\n projectId: \"proj_test_000000000000\",\n environmentId: \"env_test_000000000000\",\n logs,\n };\n\n return ctx;\n}\n"],"mappings":"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","names":[]}
|
|
1
|
+
{"version":3,"sources":["../../src/test/index.ts","../../src/test/mock-db.ts","../../src/test/context.ts"],"sourcesContent":["export { createTestContext } from \"./context.js\";\nexport type { TestContextOptions, TestContext, LogEntry } from \"./context.js\";\nexport { createMockDB } from \"./mock-db.js\";\nexport type { MockDBClient } from \"./mock-db.js\";\n","import type { DBClient, TxClient } from \"../endpoint.js\";\n\n/** Tracked records for assertions. */\ninterface TrackedRecords {\n inserted: Map<string, Record<string, unknown>[]>;\n updated: Map<string, Record<string, unknown>[]>;\n deleted: Map<string, string[]>;\n}\n\n/** Mock DB client with tracking and seed data support. */\nexport interface MockDBClient extends DBClient {\n /** Get records inserted into a table. */\n inserted(table: string): Record<string, unknown>[];\n /** Get records updated in a table. */\n updated(table: string): Record<string, unknown>[];\n /** Get IDs deleted from a table. */\n deleted(table: string): string[];\n /** Pre-seed data into a table for findById/findMany. */\n seed(table: string, data: Record<string, unknown>[]): void;\n}\n\n/** Create a mock DB client with in-memory tracking. */\nexport function createMockDB(): MockDBClient {\n const store = new Map<string, Record<string, unknown>[]>();\n const tracked: TrackedRecords = {\n inserted: new Map(),\n updated: new Map(),\n deleted: new Map(),\n };\n\n // Build the op surface first (TxClient = the five DB ops + query). The\n // transaction below reuses this same `ops` object as the tx-scoped client,\n // so writes inside a transaction land in the same in-memory store and\n // tracking maps — exactly the semantics a user endpoint test expects.\n const ops: TxClient = {\n async query(_sql: string, _params?: unknown[]) {\n return [];\n },\n\n async insert(table: string, data: Record<string, unknown>) {\n const record = { id: crypto.randomUUID(), ...data };\n if (!store.has(table)) store.set(table, []);\n store.get(table)!.push(record);\n if (!tracked.inserted.has(table)) tracked.inserted.set(table, []);\n tracked.inserted.get(table)!.push(record);\n return record;\n },\n\n async update(table: string, id: string, data: Record<string, unknown>) {\n const rows = store.get(table) ?? [];\n const idx = rows.findIndex((r) => r[\"id\"] === id);\n const updated = idx >= 0\n ? { ...rows[idx], ...data }\n : { id, ...data };\n if (idx >= 0) {\n rows[idx] = updated;\n }\n if (!tracked.updated.has(table)) tracked.updated.set(table, []);\n tracked.updated.get(table)!.push(updated);\n return updated;\n },\n\n async delete(table: string, id: string) {\n const rows = store.get(table) ?? [];\n const idx = rows.findIndex((r) => r[\"id\"] === id);\n if (idx >= 0) rows.splice(idx, 1);\n if (!tracked.deleted.has(table)) tracked.deleted.set(table, []);\n tracked.deleted.get(table)!.push(id);\n },\n\n async findById(table: string, id: string) {\n const rows = store.get(table) ?? [];\n return rows.find((r) => r[\"id\"] === id) ?? null;\n },\n\n async findMany(table: string, query?: Record<string, unknown>) {\n const rows = store.get(table) ?? [];\n if (!query) return rows;\n return rows.filter((row) =>\n Object.entries(query).every(([key, val]) => row[key] === val),\n );\n },\n };\n\n return {\n ...ops,\n\n transaction<T>(fn: (tx: TxClient) => Promise<T>): Promise<T> {\n return fn(ops);\n },\n\n inserted(table: string) {\n return tracked.inserted.get(table) ?? [];\n },\n\n updated(table: string) {\n return tracked.updated.get(table) ?? [];\n },\n\n deleted(table: string) {\n return tracked.deleted.get(table) ?? [];\n },\n\n seed(table: string, data: Record<string, unknown>[]) {\n store.set(table, [...data]);\n },\n };\n}\n","import type {\n CacheClient,\n EndpointContext,\n Logger,\n PalbaseModuleClients,\n QueueClient,\n} from \"../endpoint.js\";\nimport type {\n PalbaseAuthClient,\n PalbaseStorageClient,\n PalbaseRealtimeClient,\n PalbaseFunctionsClient,\n PalbaseFlagsClient,\n PalbaseNotificationsClient,\n PalbaseAnalyticsClient,\n PalbaseLinksClient,\n PalbaseCmsClient,\n} from \"../clients.js\";\nimport type { User } from \"../types.js\";\nimport { createMockDB, type MockDBClient } from \"./mock-db.js\";\n\n/** Options for creating a test context. */\nexport interface TestContextOptions<TInput = unknown> {\n user?: User | null;\n input?: TInput;\n params?: Record<string, string>;\n query?: Record<string, string>;\n headers?: Record<string, string>;\n env?: Record<string, string>;\n db?: { seed?: Record<string, Record<string, unknown>[]> };\n}\n\n/** Log entry captured by the mock logger. */\nexport interface LogEntry {\n level: \"info\" | \"warn\" | \"error\" | \"debug\";\n message: string;\n args: unknown[];\n}\n\n/** Test context with mock helpers exposed. */\nexport interface TestContext<TInput = unknown> extends EndpointContext<TInput> {\n db: MockDBClient;\n /** Captured log entries. */\n logs: LogEntry[];\n}\n\n/** Create a mock logger that captures entries. */\nfunction createMockLogger(logs: LogEntry[]): Logger {\n return {\n info(message: string, ...args: unknown[]) {\n logs.push({ level: \"info\", message, args });\n },\n warn(message: string, ...args: unknown[]) {\n logs.push({ level: \"warn\", message, args });\n },\n error(message: string, ...args: unknown[]) {\n logs.push({ level: \"error\", message, args });\n },\n debug(message: string, ...args: unknown[]) {\n logs.push({ level: \"debug\", message, args });\n },\n };\n}\n\n/** Create a mock in-memory cache.\n *\n * Mirrors the runtime's JSON-typed semantics (values are arbitrary JSON, not\n * just strings). getOrSet is single-process here, so it does not need the\n * distributed lock the real runtime uses — it is just get-miss → fn → set.\n * The cross-replica stampede protection is covered by the worker.js tests.\n */\nfunction createMockCache(): CacheClient {\n const store = new Map<string, unknown>();\n\n const get = async <T = unknown>(key: string): Promise<T | null> => {\n return store.has(key) ? (store.get(key) as T) : null;\n };\n const set = async (key: string, value: unknown, _ttl?: number): Promise<void> => {\n store.set(key, value);\n };\n\n return {\n get,\n set,\n async del(key: string) {\n store.delete(key);\n },\n async incr(key: string) {\n const raw = store.get(key);\n const current = typeof raw === \"number\" ? raw : parseInt(String(raw ?? \"0\"), 10);\n const next = current + 1;\n store.set(key, next);\n return next;\n },\n async getOrSet<T>(key: string, ttl: number, fn: () => Promise<T> | T): Promise<T> {\n const hit = await get<T>(key);\n if (hit !== null) {\n return hit;\n }\n const value = await fn();\n await set(key, value, ttl);\n return value;\n },\n };\n}\n\n/** Create mock Palbase module clients (ctx.docs, ctx.storage, …).\n *\n * Every slot throws with a descriptive error so tests that access a\n * module client surface without configuring it fail loudly rather than\n * silently returning undefined. Override individual clients on the\n * returned context for tests that need them:\n * const ctx = createTestContext();\n * ctx.flags = { isEnabled: vi.fn().mockResolvedValue({ data: true, error: null }) };\n */\nfunction createMockModuleClients(): PalbaseModuleClients {\n const notImpl = (label: string): never => {\n throw new Error(\n `${label} not configured in test mock — override ctx.${label.split(\".\")[0]} on the returned context`,\n );\n };\n\n const docs: PalbaseModuleClients[\"docs\"] = {\n collection: () => notImpl(\"docs.collection\"),\n doc: () => notImpl(\"docs.doc\"),\n };\n\n const auth: PalbaseAuthClient = {\n verifyUserToken: () => notImpl(\"auth.verifyUserToken\"),\n getSession: () => notImpl(\"auth.getSession\"),\n mfa: {\n enroll: () => notImpl(\"auth.mfa.enroll\"),\n verifyEnrollment: () => notImpl(\"auth.mfa.verifyEnrollment\"),\n challenge: () => notImpl(\"auth.mfa.challenge\"),\n recovery: () => notImpl(\"auth.mfa.recovery\"),\n listFactors: () => notImpl(\"auth.mfa.listFactors\"),\n removeFactor: () => notImpl(\"auth.mfa.removeFactor\"),\n regenerateRecoveryCodes: () => notImpl(\"auth.mfa.regenerateRecoveryCodes\"),\n emailEnroll: () => notImpl(\"auth.mfa.emailEnroll\"),\n emailChallenge: () => notImpl(\"auth.mfa.emailChallenge\"),\n emailVerify: () => notImpl(\"auth.mfa.emailVerify\"),\n },\n device: {\n generateChallenge: () => notImpl(\"auth.device.generateChallenge\"),\n attestAndroid: () => notImpl(\"auth.device.attestAndroid\"),\n attestiOS: () => notImpl(\"auth.device.attestiOS\"),\n bind: () => notImpl(\"auth.device.bind\"),\n list: () => notImpl(\"auth.device.list\"),\n delete: () => notImpl(\"auth.device.delete\"),\n verifyRequestSignature: () => notImpl(\"auth.device.verifyRequestSignature\"),\n getToken: () => notImpl(\"auth.device.getToken\"),\n get isActive(): never {\n return notImpl(\"auth.device.isActive\");\n },\n setCachedToken: () => notImpl(\"auth.device.setCachedToken\"),\n dispose: () => notImpl(\"auth.device.dispose\"),\n },\n };\n\n const storage: PalbaseStorageClient = {\n bucket: () => notImpl(\"storage.bucket\"),\n };\n\n const realtime: PalbaseRealtimeClient = {\n channel: () => notImpl(\"realtime.channel\"),\n removeChannel: () => notImpl(\"realtime.removeChannel\"),\n removeAllChannels: () => notImpl(\"realtime.removeAllChannels\"),\n };\n\n const functions: PalbaseFunctionsClient = {\n invoke: () => notImpl(\"functions.invoke\"),\n };\n\n const flags: PalbaseFlagsClient = {\n isEnabled: () => notImpl(\"flags.isEnabled\"),\n getVariant: () => notImpl(\"flags.getVariant\"),\n getAll: () => notImpl(\"flags.getAll\"),\n };\n\n const notifications: PalbaseNotificationsClient = {\n push: { send: () => notImpl(\"notifications.push.send\") },\n email: { send: () => notImpl(\"notifications.email.send\") },\n sms: { send: () => notImpl(\"notifications.sms.send\") },\n inbox: {\n send: () => notImpl(\"notifications.inbox.send\"),\n list: () => notImpl(\"notifications.inbox.list\"),\n unreadCount: () => notImpl(\"notifications.inbox.unreadCount\"),\n markRead: () => notImpl(\"notifications.inbox.markRead\"),\n markAllRead: () => notImpl(\"notifications.inbox.markAllRead\"),\n archive: () => notImpl(\"notifications.inbox.archive\"),\n },\n preferences: {\n get: () => notImpl(\"notifications.preferences.get\"),\n update: () => notImpl(\"notifications.preferences.update\"),\n },\n templates: {\n email: {\n list: () => notImpl(\"notifications.templates.email.list\"),\n get: () => notImpl(\"notifications.templates.email.get\"),\n create: () => notImpl(\"notifications.templates.email.create\"),\n update: () => notImpl(\"notifications.templates.email.update\"),\n delete: () => notImpl(\"notifications.templates.email.delete\"),\n },\n sms: {\n list: () => notImpl(\"notifications.templates.sms.list\"),\n get: () => notImpl(\"notifications.templates.sms.get\"),\n create: () => notImpl(\"notifications.templates.sms.create\"),\n update: () => notImpl(\"notifications.templates.sms.update\"),\n delete: () => notImpl(\"notifications.templates.sms.delete\"),\n },\n },\n registerDevice: () => notImpl(\"notifications.registerDevice\"),\n unregisterDevice: () => notImpl(\"notifications.unregisterDevice\"),\n };\n\n const analytics: PalbaseAnalyticsClient = {\n capture: () => notImpl(\"analytics.capture\"),\n identify: () => notImpl(\"analytics.identify\"),\n screen: () => notImpl(\"analytics.screen\"),\n query: {\n count: () => notImpl(\"analytics.query.count\"),\n events: () => notImpl(\"analytics.query.events\"),\n properties: () => notImpl(\"analytics.query.properties\"),\n users: () => notImpl(\"analytics.query.users\"),\n funnel: () => notImpl(\"analytics.query.funnel\"),\n retention: () => notImpl(\"analytics.query.retention\"),\n cohort: () => notImpl(\"analytics.query.cohort\"),\n },\n management: {\n overview: () => notImpl(\"analytics.management.overview\"),\n eventNames: () => notImpl(\"analytics.management.eventNames\"),\n userDetail: () => notImpl(\"analytics.management.userDetail\"),\n deleteUser: () => notImpl(\"analytics.management.deleteUser\"),\n },\n };\n\n const links: PalbaseLinksClient = {\n create: () => notImpl(\"links.create\"),\n list: () => notImpl(\"links.list\"),\n get: () => notImpl(\"links.get\"),\n update: () => notImpl(\"links.update\"),\n delete: () => notImpl(\"links.delete\"),\n analytics: () => notImpl(\"links.analytics\"),\n qrCode: () => notImpl(\"links.qrCode\"),\n match: () => notImpl(\"links.match\"),\n };\n\n const cms: PalbaseCmsClient = {\n find: () => notImpl(\"cms.find\"),\n findOne: () => notImpl(\"cms.findOne\"),\n };\n\n return {\n auth,\n storage,\n docs,\n realtime,\n functions,\n flags,\n notifications,\n analytics,\n links,\n cms,\n };\n}\n\n/** Create a fully mocked EndpointContext for testing user endpoints. */\nexport function createTestContext<TInput = unknown>(\n options: TestContextOptions<TInput> = {},\n): TestContext<TInput> {\n const logs: LogEntry[] = [];\n const db = createMockDB();\n\n // Seed data if provided\n if (options.db?.seed) {\n for (const [table, data] of Object.entries(options.db.seed)) {\n db.seed(table, data);\n }\n }\n\n const mockQueue: QueueClient = {\n push: async (_worker: string, _payload: unknown) => ({ jobId: \"\" }),\n };\n\n const ctx: TestContext<TInput> = {\n input: (options.input ?? {}) as TInput,\n params: options.params ?? {},\n query: options.query ?? {},\n headers: options.headers ?? {},\n user: options.user ?? null,\n method: \"POST\",\n endpointPath: \"/test\",\n file: null,\n db,\n env: options.env ?? {},\n log: createMockLogger(logs),\n cache: createMockCache(),\n queue: mockQueue,\n ...createMockModuleClients(),\n requestId: \"req_test_000000000000\",\n projectId: \"proj_test_000000000000\",\n environmentId: \"env_test_000000000000\",\n logs,\n };\n\n return ctx;\n}\n"],"mappings":"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","names":[]}
|
package/dist/test/index.d.cts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
|
-
import { D as DBClient, E as EndpointContext,
|
|
1
|
+
import { D as DBClient, E as EndpointContext, aT as User } from '../endpoint-6LeBP-eb.cjs';
|
|
2
2
|
import 'zod';
|
|
3
|
+
import '../schema-zk-a0Dv7.cjs';
|
|
3
4
|
|
|
4
5
|
/** Mock DB client with tracking and seed data support. */
|
|
5
6
|
interface MockDBClient extends DBClient {
|
package/dist/test/index.d.ts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
|
-
import { D as DBClient, E as EndpointContext,
|
|
1
|
+
import { D as DBClient, E as EndpointContext, aT as User } from '../endpoint-BbbU1hE1.js';
|
|
2
2
|
import 'zod';
|
|
3
|
+
import '../schema-zk-a0Dv7.js';
|
|
3
4
|
|
|
4
5
|
/** Mock DB client with tracking and seed data support. */
|
|
5
6
|
interface MockDBClient extends DBClient {
|
package/dist/test/index.js
CHANGED
|
@@ -6,7 +6,10 @@ function createMockDB() {
|
|
|
6
6
|
updated: /* @__PURE__ */ new Map(),
|
|
7
7
|
deleted: /* @__PURE__ */ new Map()
|
|
8
8
|
};
|
|
9
|
-
|
|
9
|
+
const ops = {
|
|
10
|
+
async query(_sql, _params) {
|
|
11
|
+
return [];
|
|
12
|
+
},
|
|
10
13
|
async insert(table, data) {
|
|
11
14
|
const record = { id: crypto.randomUUID(), ...data };
|
|
12
15
|
if (!store.has(table)) store.set(table, []);
|
|
@@ -43,6 +46,12 @@ function createMockDB() {
|
|
|
43
46
|
return rows.filter(
|
|
44
47
|
(row) => Object.entries(query).every(([key, val]) => row[key] === val)
|
|
45
48
|
);
|
|
49
|
+
}
|
|
50
|
+
};
|
|
51
|
+
return {
|
|
52
|
+
...ops,
|
|
53
|
+
transaction(fn) {
|
|
54
|
+
return fn(ops);
|
|
46
55
|
},
|
|
47
56
|
inserted(table) {
|
|
48
57
|
return tracked.inserted.get(table) ?? [];
|
|
@@ -78,28 +87,173 @@ function createMockLogger(logs) {
|
|
|
78
87
|
}
|
|
79
88
|
function createMockCache() {
|
|
80
89
|
const store = /* @__PURE__ */ new Map();
|
|
90
|
+
const get = async (key) => {
|
|
91
|
+
return store.has(key) ? store.get(key) : null;
|
|
92
|
+
};
|
|
93
|
+
const set = async (key, value, _ttl) => {
|
|
94
|
+
store.set(key, value);
|
|
95
|
+
};
|
|
81
96
|
return {
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
},
|
|
85
|
-
async set(key, value, _ttl) {
|
|
86
|
-
store.set(key, value);
|
|
87
|
-
},
|
|
97
|
+
get,
|
|
98
|
+
set,
|
|
88
99
|
async del(key) {
|
|
89
100
|
store.delete(key);
|
|
90
101
|
},
|
|
91
102
|
async incr(key) {
|
|
92
|
-
const
|
|
103
|
+
const raw = store.get(key);
|
|
104
|
+
const current = typeof raw === "number" ? raw : parseInt(String(raw ?? "0"), 10);
|
|
93
105
|
const next = current + 1;
|
|
94
|
-
store.set(key,
|
|
106
|
+
store.set(key, next);
|
|
95
107
|
return next;
|
|
108
|
+
},
|
|
109
|
+
async getOrSet(key, ttl, fn) {
|
|
110
|
+
const hit = await get(key);
|
|
111
|
+
if (hit !== null) {
|
|
112
|
+
return hit;
|
|
113
|
+
}
|
|
114
|
+
const value = await fn();
|
|
115
|
+
await set(key, value, ttl);
|
|
116
|
+
return value;
|
|
96
117
|
}
|
|
97
118
|
};
|
|
98
119
|
}
|
|
99
|
-
function
|
|
120
|
+
function createMockModuleClients() {
|
|
121
|
+
const notImpl = (label) => {
|
|
122
|
+
throw new Error(
|
|
123
|
+
`${label} not configured in test mock \u2014 override ctx.${label.split(".")[0]} on the returned context`
|
|
124
|
+
);
|
|
125
|
+
};
|
|
126
|
+
const docs = {
|
|
127
|
+
collection: () => notImpl("docs.collection"),
|
|
128
|
+
doc: () => notImpl("docs.doc")
|
|
129
|
+
};
|
|
130
|
+
const auth = {
|
|
131
|
+
verifyUserToken: () => notImpl("auth.verifyUserToken"),
|
|
132
|
+
getSession: () => notImpl("auth.getSession"),
|
|
133
|
+
mfa: {
|
|
134
|
+
enroll: () => notImpl("auth.mfa.enroll"),
|
|
135
|
+
verifyEnrollment: () => notImpl("auth.mfa.verifyEnrollment"),
|
|
136
|
+
challenge: () => notImpl("auth.mfa.challenge"),
|
|
137
|
+
recovery: () => notImpl("auth.mfa.recovery"),
|
|
138
|
+
listFactors: () => notImpl("auth.mfa.listFactors"),
|
|
139
|
+
removeFactor: () => notImpl("auth.mfa.removeFactor"),
|
|
140
|
+
regenerateRecoveryCodes: () => notImpl("auth.mfa.regenerateRecoveryCodes"),
|
|
141
|
+
emailEnroll: () => notImpl("auth.mfa.emailEnroll"),
|
|
142
|
+
emailChallenge: () => notImpl("auth.mfa.emailChallenge"),
|
|
143
|
+
emailVerify: () => notImpl("auth.mfa.emailVerify")
|
|
144
|
+
},
|
|
145
|
+
device: {
|
|
146
|
+
generateChallenge: () => notImpl("auth.device.generateChallenge"),
|
|
147
|
+
attestAndroid: () => notImpl("auth.device.attestAndroid"),
|
|
148
|
+
attestiOS: () => notImpl("auth.device.attestiOS"),
|
|
149
|
+
bind: () => notImpl("auth.device.bind"),
|
|
150
|
+
list: () => notImpl("auth.device.list"),
|
|
151
|
+
delete: () => notImpl("auth.device.delete"),
|
|
152
|
+
verifyRequestSignature: () => notImpl("auth.device.verifyRequestSignature"),
|
|
153
|
+
getToken: () => notImpl("auth.device.getToken"),
|
|
154
|
+
get isActive() {
|
|
155
|
+
return notImpl("auth.device.isActive");
|
|
156
|
+
},
|
|
157
|
+
setCachedToken: () => notImpl("auth.device.setCachedToken"),
|
|
158
|
+
dispose: () => notImpl("auth.device.dispose")
|
|
159
|
+
}
|
|
160
|
+
};
|
|
161
|
+
const storage = {
|
|
162
|
+
bucket: () => notImpl("storage.bucket")
|
|
163
|
+
};
|
|
164
|
+
const realtime = {
|
|
165
|
+
channel: () => notImpl("realtime.channel"),
|
|
166
|
+
removeChannel: () => notImpl("realtime.removeChannel"),
|
|
167
|
+
removeAllChannels: () => notImpl("realtime.removeAllChannels")
|
|
168
|
+
};
|
|
169
|
+
const functions = {
|
|
170
|
+
invoke: () => notImpl("functions.invoke")
|
|
171
|
+
};
|
|
172
|
+
const flags = {
|
|
173
|
+
isEnabled: () => notImpl("flags.isEnabled"),
|
|
174
|
+
getVariant: () => notImpl("flags.getVariant"),
|
|
175
|
+
getAll: () => notImpl("flags.getAll")
|
|
176
|
+
};
|
|
177
|
+
const notifications = {
|
|
178
|
+
push: { send: () => notImpl("notifications.push.send") },
|
|
179
|
+
email: { send: () => notImpl("notifications.email.send") },
|
|
180
|
+
sms: { send: () => notImpl("notifications.sms.send") },
|
|
181
|
+
inbox: {
|
|
182
|
+
send: () => notImpl("notifications.inbox.send"),
|
|
183
|
+
list: () => notImpl("notifications.inbox.list"),
|
|
184
|
+
unreadCount: () => notImpl("notifications.inbox.unreadCount"),
|
|
185
|
+
markRead: () => notImpl("notifications.inbox.markRead"),
|
|
186
|
+
markAllRead: () => notImpl("notifications.inbox.markAllRead"),
|
|
187
|
+
archive: () => notImpl("notifications.inbox.archive")
|
|
188
|
+
},
|
|
189
|
+
preferences: {
|
|
190
|
+
get: () => notImpl("notifications.preferences.get"),
|
|
191
|
+
update: () => notImpl("notifications.preferences.update")
|
|
192
|
+
},
|
|
193
|
+
templates: {
|
|
194
|
+
email: {
|
|
195
|
+
list: () => notImpl("notifications.templates.email.list"),
|
|
196
|
+
get: () => notImpl("notifications.templates.email.get"),
|
|
197
|
+
create: () => notImpl("notifications.templates.email.create"),
|
|
198
|
+
update: () => notImpl("notifications.templates.email.update"),
|
|
199
|
+
delete: () => notImpl("notifications.templates.email.delete")
|
|
200
|
+
},
|
|
201
|
+
sms: {
|
|
202
|
+
list: () => notImpl("notifications.templates.sms.list"),
|
|
203
|
+
get: () => notImpl("notifications.templates.sms.get"),
|
|
204
|
+
create: () => notImpl("notifications.templates.sms.create"),
|
|
205
|
+
update: () => notImpl("notifications.templates.sms.update"),
|
|
206
|
+
delete: () => notImpl("notifications.templates.sms.delete")
|
|
207
|
+
}
|
|
208
|
+
},
|
|
209
|
+
registerDevice: () => notImpl("notifications.registerDevice"),
|
|
210
|
+
unregisterDevice: () => notImpl("notifications.unregisterDevice")
|
|
211
|
+
};
|
|
212
|
+
const analytics = {
|
|
213
|
+
capture: () => notImpl("analytics.capture"),
|
|
214
|
+
identify: () => notImpl("analytics.identify"),
|
|
215
|
+
screen: () => notImpl("analytics.screen"),
|
|
216
|
+
query: {
|
|
217
|
+
count: () => notImpl("analytics.query.count"),
|
|
218
|
+
events: () => notImpl("analytics.query.events"),
|
|
219
|
+
properties: () => notImpl("analytics.query.properties"),
|
|
220
|
+
users: () => notImpl("analytics.query.users"),
|
|
221
|
+
funnel: () => notImpl("analytics.query.funnel"),
|
|
222
|
+
retention: () => notImpl("analytics.query.retention"),
|
|
223
|
+
cohort: () => notImpl("analytics.query.cohort")
|
|
224
|
+
},
|
|
225
|
+
management: {
|
|
226
|
+
overview: () => notImpl("analytics.management.overview"),
|
|
227
|
+
eventNames: () => notImpl("analytics.management.eventNames"),
|
|
228
|
+
userDetail: () => notImpl("analytics.management.userDetail"),
|
|
229
|
+
deleteUser: () => notImpl("analytics.management.deleteUser")
|
|
230
|
+
}
|
|
231
|
+
};
|
|
232
|
+
const links = {
|
|
233
|
+
create: () => notImpl("links.create"),
|
|
234
|
+
list: () => notImpl("links.list"),
|
|
235
|
+
get: () => notImpl("links.get"),
|
|
236
|
+
update: () => notImpl("links.update"),
|
|
237
|
+
delete: () => notImpl("links.delete"),
|
|
238
|
+
analytics: () => notImpl("links.analytics"),
|
|
239
|
+
qrCode: () => notImpl("links.qrCode"),
|
|
240
|
+
match: () => notImpl("links.match")
|
|
241
|
+
};
|
|
242
|
+
const cms = {
|
|
243
|
+
find: () => notImpl("cms.find"),
|
|
244
|
+
findOne: () => notImpl("cms.findOne")
|
|
245
|
+
};
|
|
100
246
|
return {
|
|
101
|
-
auth
|
|
102
|
-
storage
|
|
247
|
+
auth,
|
|
248
|
+
storage,
|
|
249
|
+
docs,
|
|
250
|
+
realtime,
|
|
251
|
+
functions,
|
|
252
|
+
flags,
|
|
253
|
+
notifications,
|
|
254
|
+
analytics,
|
|
255
|
+
links,
|
|
256
|
+
cms
|
|
103
257
|
};
|
|
104
258
|
}
|
|
105
259
|
function createTestContext(options = {}) {
|
|
@@ -110,17 +264,24 @@ function createTestContext(options = {}) {
|
|
|
110
264
|
db.seed(table, data);
|
|
111
265
|
}
|
|
112
266
|
}
|
|
267
|
+
const mockQueue = {
|
|
268
|
+
push: async (_worker, _payload) => ({ jobId: "" })
|
|
269
|
+
};
|
|
113
270
|
const ctx = {
|
|
114
271
|
input: options.input ?? {},
|
|
115
272
|
params: options.params ?? {},
|
|
116
273
|
query: options.query ?? {},
|
|
117
274
|
headers: options.headers ?? {},
|
|
118
275
|
user: options.user ?? null,
|
|
276
|
+
method: "POST",
|
|
277
|
+
endpointPath: "/test",
|
|
278
|
+
file: null,
|
|
119
279
|
db,
|
|
120
280
|
env: options.env ?? {},
|
|
121
281
|
log: createMockLogger(logs),
|
|
122
282
|
cache: createMockCache(),
|
|
123
|
-
|
|
283
|
+
queue: mockQueue,
|
|
284
|
+
...createMockModuleClients(),
|
|
124
285
|
requestId: "req_test_000000000000",
|
|
125
286
|
projectId: "proj_test_000000000000",
|
|
126
287
|
environmentId: "env_test_000000000000",
|
package/dist/test/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/test/mock-db.ts","../../src/test/context.ts"],"sourcesContent":["import type { DBClient } from \"../endpoint.js\";\n\n/** Tracked records for assertions. */\ninterface TrackedRecords {\n inserted: Map<string, Record<string, unknown>[]>;\n updated: Map<string, Record<string, unknown>[]>;\n deleted: Map<string, string[]>;\n}\n\n/** Mock DB client with tracking and seed data support. */\nexport interface MockDBClient extends DBClient {\n /** Get records inserted into a table. */\n inserted(table: string): Record<string, unknown>[];\n /** Get records updated in a table. */\n updated(table: string): Record<string, unknown>[];\n /** Get IDs deleted from a table. */\n deleted(table: string): string[];\n /** Pre-seed data into a table for findById/findMany. */\n seed(table: string, data: Record<string, unknown>[]): void;\n}\n\n/** Create a mock DB client with in-memory tracking. */\nexport function createMockDB(): MockDBClient {\n const store = new Map<string, Record<string, unknown>[]>();\n const tracked: TrackedRecords = {\n inserted: new Map(),\n updated: new Map(),\n deleted: new Map(),\n };\n\n return {\n async insert(table: string, data: Record<string, unknown>) {\n const record = { id: crypto.randomUUID(), ...data };\n if (!store.has(table)) store.set(table, []);\n store.get(table)!.push(record);\n if (!tracked.inserted.has(table)) tracked.inserted.set(table, []);\n tracked.inserted.get(table)!.push(record);\n return record;\n },\n\n async update(table: string, id: string, data: Record<string, unknown>) {\n const rows = store.get(table) ?? [];\n const idx = rows.findIndex((r) => r[\"id\"] === id);\n const updated = idx >= 0\n ? { ...rows[idx], ...data }\n : { id, ...data };\n if (idx >= 0) {\n rows[idx] = updated;\n }\n if (!tracked.updated.has(table)) tracked.updated.set(table, []);\n tracked.updated.get(table)!.push(updated);\n return updated;\n },\n\n async delete(table: string, id: string) {\n const rows = store.get(table) ?? [];\n const idx = rows.findIndex((r) => r[\"id\"] === id);\n if (idx >= 0) rows.splice(idx, 1);\n if (!tracked.deleted.has(table)) tracked.deleted.set(table, []);\n tracked.deleted.get(table)!.push(id);\n },\n\n async findById(table: string, id: string) {\n const rows = store.get(table) ?? [];\n return rows.find((r) => r[\"id\"] === id) ?? null;\n },\n\n async findMany(table: string, query?: Record<string, unknown>) {\n const rows = store.get(table) ?? [];\n if (!query) return rows;\n return rows.filter((row) =>\n Object.entries(query).every(([key, val]) => row[key] === val),\n );\n },\n\n inserted(table: string) {\n return tracked.inserted.get(table) ?? [];\n },\n\n updated(table: string) {\n return tracked.updated.get(table) ?? [];\n },\n\n deleted(table: string) {\n return tracked.deleted.get(table) ?? [];\n },\n\n seed(table: string, data: Record<string, unknown>[]) {\n store.set(table, [...data]);\n },\n };\n}\n","import type {\n CacheClient,\n EndpointContext,\n Logger,\n PalbaseBindings,\n} from \"../endpoint.js\";\nimport type { User } from \"../types.js\";\nimport { createMockDB, type MockDBClient } from \"./mock-db.js\";\n\n/** Options for creating a test context. */\nexport interface TestContextOptions<TInput = unknown> {\n user?: User | null;\n input?: TInput;\n params?: Record<string, string>;\n query?: Record<string, string>;\n headers?: Record<string, string>;\n env?: Record<string, string>;\n db?: { seed?: Record<string, Record<string, unknown>[]> };\n}\n\n/** Log entry captured by the mock logger. */\nexport interface LogEntry {\n level: \"info\" | \"warn\" | \"error\" | \"debug\";\n message: string;\n args: unknown[];\n}\n\n/** Test context with mock helpers exposed. */\nexport interface TestContext<TInput = unknown> extends EndpointContext<TInput> {\n db: MockDBClient;\n /** Captured log entries. */\n logs: LogEntry[];\n}\n\n/** Create a mock logger that captures entries. */\nfunction createMockLogger(logs: LogEntry[]): Logger {\n return {\n info(message: string, ...args: unknown[]) {\n logs.push({ level: \"info\", message, args });\n },\n warn(message: string, ...args: unknown[]) {\n logs.push({ level: \"warn\", message, args });\n },\n error(message: string, ...args: unknown[]) {\n logs.push({ level: \"error\", message, args });\n },\n debug(message: string, ...args: unknown[]) {\n logs.push({ level: \"debug\", message, args });\n },\n };\n}\n\n/** Create a mock in-memory cache. */\nfunction createMockCache(): CacheClient {\n const store = new Map<string, string>();\n\n return {\n async get(key: string) {\n return store.get(key) ?? null;\n },\n async set(key: string, value: string, _ttl?: number) {\n store.set(key, value);\n },\n async del(key: string) {\n store.delete(key);\n },\n async incr(key: string) {\n const current = parseInt(store.get(key) ?? \"0\", 10);\n const next = current + 1;\n store.set(key, String(next));\n return next;\n },\n };\n}\n\n/** Create a mock Palbase service bindings. */\nfunction createMockPalbase(): PalbaseBindings {\n return {\n auth: {},\n storage: {},\n };\n}\n\n/** Create a fully mocked EndpointContext for testing user endpoints. */\nexport function createTestContext<TInput = unknown>(\n options: TestContextOptions<TInput> = {},\n): TestContext<TInput> {\n const logs: LogEntry[] = [];\n const db = createMockDB();\n\n // Seed data if provided\n if (options.db?.seed) {\n for (const [table, data] of Object.entries(options.db.seed)) {\n db.seed(table, data);\n }\n }\n\n const ctx: TestContext<TInput> = {\n input: (options.input ?? {}) as TInput,\n params: options.params ?? {},\n query: options.query ?? {},\n headers: options.headers ?? {},\n user: options.user ?? null,\n db,\n env: options.env ?? {},\n log: createMockLogger(logs),\n cache: createMockCache(),\n palbase: createMockPalbase(),\n requestId: \"req_test_000000000000\",\n projectId: \"proj_test_000000000000\",\n environmentId: \"env_test_000000000000\",\n logs,\n };\n\n return ctx;\n}\n"],"mappings":"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","names":[]}
|
|
1
|
+
{"version":3,"sources":["../../src/test/mock-db.ts","../../src/test/context.ts"],"sourcesContent":["import type { DBClient, TxClient } from \"../endpoint.js\";\n\n/** Tracked records for assertions. */\ninterface TrackedRecords {\n inserted: Map<string, Record<string, unknown>[]>;\n updated: Map<string, Record<string, unknown>[]>;\n deleted: Map<string, string[]>;\n}\n\n/** Mock DB client with tracking and seed data support. */\nexport interface MockDBClient extends DBClient {\n /** Get records inserted into a table. */\n inserted(table: string): Record<string, unknown>[];\n /** Get records updated in a table. */\n updated(table: string): Record<string, unknown>[];\n /** Get IDs deleted from a table. */\n deleted(table: string): string[];\n /** Pre-seed data into a table for findById/findMany. */\n seed(table: string, data: Record<string, unknown>[]): void;\n}\n\n/** Create a mock DB client with in-memory tracking. */\nexport function createMockDB(): MockDBClient {\n const store = new Map<string, Record<string, unknown>[]>();\n const tracked: TrackedRecords = {\n inserted: new Map(),\n updated: new Map(),\n deleted: new Map(),\n };\n\n // Build the op surface first (TxClient = the five DB ops + query). The\n // transaction below reuses this same `ops` object as the tx-scoped client,\n // so writes inside a transaction land in the same in-memory store and\n // tracking maps — exactly the semantics a user endpoint test expects.\n const ops: TxClient = {\n async query(_sql: string, _params?: unknown[]) {\n return [];\n },\n\n async insert(table: string, data: Record<string, unknown>) {\n const record = { id: crypto.randomUUID(), ...data };\n if (!store.has(table)) store.set(table, []);\n store.get(table)!.push(record);\n if (!tracked.inserted.has(table)) tracked.inserted.set(table, []);\n tracked.inserted.get(table)!.push(record);\n return record;\n },\n\n async update(table: string, id: string, data: Record<string, unknown>) {\n const rows = store.get(table) ?? [];\n const idx = rows.findIndex((r) => r[\"id\"] === id);\n const updated = idx >= 0\n ? { ...rows[idx], ...data }\n : { id, ...data };\n if (idx >= 0) {\n rows[idx] = updated;\n }\n if (!tracked.updated.has(table)) tracked.updated.set(table, []);\n tracked.updated.get(table)!.push(updated);\n return updated;\n },\n\n async delete(table: string, id: string) {\n const rows = store.get(table) ?? [];\n const idx = rows.findIndex((r) => r[\"id\"] === id);\n if (idx >= 0) rows.splice(idx, 1);\n if (!tracked.deleted.has(table)) tracked.deleted.set(table, []);\n tracked.deleted.get(table)!.push(id);\n },\n\n async findById(table: string, id: string) {\n const rows = store.get(table) ?? [];\n return rows.find((r) => r[\"id\"] === id) ?? null;\n },\n\n async findMany(table: string, query?: Record<string, unknown>) {\n const rows = store.get(table) ?? [];\n if (!query) return rows;\n return rows.filter((row) =>\n Object.entries(query).every(([key, val]) => row[key] === val),\n );\n },\n };\n\n return {\n ...ops,\n\n transaction<T>(fn: (tx: TxClient) => Promise<T>): Promise<T> {\n return fn(ops);\n },\n\n inserted(table: string) {\n return tracked.inserted.get(table) ?? [];\n },\n\n updated(table: string) {\n return tracked.updated.get(table) ?? [];\n },\n\n deleted(table: string) {\n return tracked.deleted.get(table) ?? [];\n },\n\n seed(table: string, data: Record<string, unknown>[]) {\n store.set(table, [...data]);\n },\n };\n}\n","import type {\n CacheClient,\n EndpointContext,\n Logger,\n PalbaseModuleClients,\n QueueClient,\n} from \"../endpoint.js\";\nimport type {\n PalbaseAuthClient,\n PalbaseStorageClient,\n PalbaseRealtimeClient,\n PalbaseFunctionsClient,\n PalbaseFlagsClient,\n PalbaseNotificationsClient,\n PalbaseAnalyticsClient,\n PalbaseLinksClient,\n PalbaseCmsClient,\n} from \"../clients.js\";\nimport type { User } from \"../types.js\";\nimport { createMockDB, type MockDBClient } from \"./mock-db.js\";\n\n/** Options for creating a test context. */\nexport interface TestContextOptions<TInput = unknown> {\n user?: User | null;\n input?: TInput;\n params?: Record<string, string>;\n query?: Record<string, string>;\n headers?: Record<string, string>;\n env?: Record<string, string>;\n db?: { seed?: Record<string, Record<string, unknown>[]> };\n}\n\n/** Log entry captured by the mock logger. */\nexport interface LogEntry {\n level: \"info\" | \"warn\" | \"error\" | \"debug\";\n message: string;\n args: unknown[];\n}\n\n/** Test context with mock helpers exposed. */\nexport interface TestContext<TInput = unknown> extends EndpointContext<TInput> {\n db: MockDBClient;\n /** Captured log entries. */\n logs: LogEntry[];\n}\n\n/** Create a mock logger that captures entries. */\nfunction createMockLogger(logs: LogEntry[]): Logger {\n return {\n info(message: string, ...args: unknown[]) {\n logs.push({ level: \"info\", message, args });\n },\n warn(message: string, ...args: unknown[]) {\n logs.push({ level: \"warn\", message, args });\n },\n error(message: string, ...args: unknown[]) {\n logs.push({ level: \"error\", message, args });\n },\n debug(message: string, ...args: unknown[]) {\n logs.push({ level: \"debug\", message, args });\n },\n };\n}\n\n/** Create a mock in-memory cache.\n *\n * Mirrors the runtime's JSON-typed semantics (values are arbitrary JSON, not\n * just strings). getOrSet is single-process here, so it does not need the\n * distributed lock the real runtime uses — it is just get-miss → fn → set.\n * The cross-replica stampede protection is covered by the worker.js tests.\n */\nfunction createMockCache(): CacheClient {\n const store = new Map<string, unknown>();\n\n const get = async <T = unknown>(key: string): Promise<T | null> => {\n return store.has(key) ? (store.get(key) as T) : null;\n };\n const set = async (key: string, value: unknown, _ttl?: number): Promise<void> => {\n store.set(key, value);\n };\n\n return {\n get,\n set,\n async del(key: string) {\n store.delete(key);\n },\n async incr(key: string) {\n const raw = store.get(key);\n const current = typeof raw === \"number\" ? raw : parseInt(String(raw ?? \"0\"), 10);\n const next = current + 1;\n store.set(key, next);\n return next;\n },\n async getOrSet<T>(key: string, ttl: number, fn: () => Promise<T> | T): Promise<T> {\n const hit = await get<T>(key);\n if (hit !== null) {\n return hit;\n }\n const value = await fn();\n await set(key, value, ttl);\n return value;\n },\n };\n}\n\n/** Create mock Palbase module clients (ctx.docs, ctx.storage, …).\n *\n * Every slot throws with a descriptive error so tests that access a\n * module client surface without configuring it fail loudly rather than\n * silently returning undefined. Override individual clients on the\n * returned context for tests that need them:\n * const ctx = createTestContext();\n * ctx.flags = { isEnabled: vi.fn().mockResolvedValue({ data: true, error: null }) };\n */\nfunction createMockModuleClients(): PalbaseModuleClients {\n const notImpl = (label: string): never => {\n throw new Error(\n `${label} not configured in test mock — override ctx.${label.split(\".\")[0]} on the returned context`,\n );\n };\n\n const docs: PalbaseModuleClients[\"docs\"] = {\n collection: () => notImpl(\"docs.collection\"),\n doc: () => notImpl(\"docs.doc\"),\n };\n\n const auth: PalbaseAuthClient = {\n verifyUserToken: () => notImpl(\"auth.verifyUserToken\"),\n getSession: () => notImpl(\"auth.getSession\"),\n mfa: {\n enroll: () => notImpl(\"auth.mfa.enroll\"),\n verifyEnrollment: () => notImpl(\"auth.mfa.verifyEnrollment\"),\n challenge: () => notImpl(\"auth.mfa.challenge\"),\n recovery: () => notImpl(\"auth.mfa.recovery\"),\n listFactors: () => notImpl(\"auth.mfa.listFactors\"),\n removeFactor: () => notImpl(\"auth.mfa.removeFactor\"),\n regenerateRecoveryCodes: () => notImpl(\"auth.mfa.regenerateRecoveryCodes\"),\n emailEnroll: () => notImpl(\"auth.mfa.emailEnroll\"),\n emailChallenge: () => notImpl(\"auth.mfa.emailChallenge\"),\n emailVerify: () => notImpl(\"auth.mfa.emailVerify\"),\n },\n device: {\n generateChallenge: () => notImpl(\"auth.device.generateChallenge\"),\n attestAndroid: () => notImpl(\"auth.device.attestAndroid\"),\n attestiOS: () => notImpl(\"auth.device.attestiOS\"),\n bind: () => notImpl(\"auth.device.bind\"),\n list: () => notImpl(\"auth.device.list\"),\n delete: () => notImpl(\"auth.device.delete\"),\n verifyRequestSignature: () => notImpl(\"auth.device.verifyRequestSignature\"),\n getToken: () => notImpl(\"auth.device.getToken\"),\n get isActive(): never {\n return notImpl(\"auth.device.isActive\");\n },\n setCachedToken: () => notImpl(\"auth.device.setCachedToken\"),\n dispose: () => notImpl(\"auth.device.dispose\"),\n },\n };\n\n const storage: PalbaseStorageClient = {\n bucket: () => notImpl(\"storage.bucket\"),\n };\n\n const realtime: PalbaseRealtimeClient = {\n channel: () => notImpl(\"realtime.channel\"),\n removeChannel: () => notImpl(\"realtime.removeChannel\"),\n removeAllChannels: () => notImpl(\"realtime.removeAllChannels\"),\n };\n\n const functions: PalbaseFunctionsClient = {\n invoke: () => notImpl(\"functions.invoke\"),\n };\n\n const flags: PalbaseFlagsClient = {\n isEnabled: () => notImpl(\"flags.isEnabled\"),\n getVariant: () => notImpl(\"flags.getVariant\"),\n getAll: () => notImpl(\"flags.getAll\"),\n };\n\n const notifications: PalbaseNotificationsClient = {\n push: { send: () => notImpl(\"notifications.push.send\") },\n email: { send: () => notImpl(\"notifications.email.send\") },\n sms: { send: () => notImpl(\"notifications.sms.send\") },\n inbox: {\n send: () => notImpl(\"notifications.inbox.send\"),\n list: () => notImpl(\"notifications.inbox.list\"),\n unreadCount: () => notImpl(\"notifications.inbox.unreadCount\"),\n markRead: () => notImpl(\"notifications.inbox.markRead\"),\n markAllRead: () => notImpl(\"notifications.inbox.markAllRead\"),\n archive: () => notImpl(\"notifications.inbox.archive\"),\n },\n preferences: {\n get: () => notImpl(\"notifications.preferences.get\"),\n update: () => notImpl(\"notifications.preferences.update\"),\n },\n templates: {\n email: {\n list: () => notImpl(\"notifications.templates.email.list\"),\n get: () => notImpl(\"notifications.templates.email.get\"),\n create: () => notImpl(\"notifications.templates.email.create\"),\n update: () => notImpl(\"notifications.templates.email.update\"),\n delete: () => notImpl(\"notifications.templates.email.delete\"),\n },\n sms: {\n list: () => notImpl(\"notifications.templates.sms.list\"),\n get: () => notImpl(\"notifications.templates.sms.get\"),\n create: () => notImpl(\"notifications.templates.sms.create\"),\n update: () => notImpl(\"notifications.templates.sms.update\"),\n delete: () => notImpl(\"notifications.templates.sms.delete\"),\n },\n },\n registerDevice: () => notImpl(\"notifications.registerDevice\"),\n unregisterDevice: () => notImpl(\"notifications.unregisterDevice\"),\n };\n\n const analytics: PalbaseAnalyticsClient = {\n capture: () => notImpl(\"analytics.capture\"),\n identify: () => notImpl(\"analytics.identify\"),\n screen: () => notImpl(\"analytics.screen\"),\n query: {\n count: () => notImpl(\"analytics.query.count\"),\n events: () => notImpl(\"analytics.query.events\"),\n properties: () => notImpl(\"analytics.query.properties\"),\n users: () => notImpl(\"analytics.query.users\"),\n funnel: () => notImpl(\"analytics.query.funnel\"),\n retention: () => notImpl(\"analytics.query.retention\"),\n cohort: () => notImpl(\"analytics.query.cohort\"),\n },\n management: {\n overview: () => notImpl(\"analytics.management.overview\"),\n eventNames: () => notImpl(\"analytics.management.eventNames\"),\n userDetail: () => notImpl(\"analytics.management.userDetail\"),\n deleteUser: () => notImpl(\"analytics.management.deleteUser\"),\n },\n };\n\n const links: PalbaseLinksClient = {\n create: () => notImpl(\"links.create\"),\n list: () => notImpl(\"links.list\"),\n get: () => notImpl(\"links.get\"),\n update: () => notImpl(\"links.update\"),\n delete: () => notImpl(\"links.delete\"),\n analytics: () => notImpl(\"links.analytics\"),\n qrCode: () => notImpl(\"links.qrCode\"),\n match: () => notImpl(\"links.match\"),\n };\n\n const cms: PalbaseCmsClient = {\n find: () => notImpl(\"cms.find\"),\n findOne: () => notImpl(\"cms.findOne\"),\n };\n\n return {\n auth,\n storage,\n docs,\n realtime,\n functions,\n flags,\n notifications,\n analytics,\n links,\n cms,\n };\n}\n\n/** Create a fully mocked EndpointContext for testing user endpoints. */\nexport function createTestContext<TInput = unknown>(\n options: TestContextOptions<TInput> = {},\n): TestContext<TInput> {\n const logs: LogEntry[] = [];\n const db = createMockDB();\n\n // Seed data if provided\n if (options.db?.seed) {\n for (const [table, data] of Object.entries(options.db.seed)) {\n db.seed(table, data);\n }\n }\n\n const mockQueue: QueueClient = {\n push: async (_worker: string, _payload: unknown) => ({ jobId: \"\" }),\n };\n\n const ctx: TestContext<TInput> = {\n input: (options.input ?? {}) as TInput,\n params: options.params ?? {},\n query: options.query ?? {},\n headers: options.headers ?? {},\n user: options.user ?? null,\n method: \"POST\",\n endpointPath: \"/test\",\n file: null,\n db,\n env: options.env ?? {},\n log: createMockLogger(logs),\n cache: createMockCache(),\n queue: mockQueue,\n ...createMockModuleClients(),\n requestId: \"req_test_000000000000\",\n projectId: \"proj_test_000000000000\",\n environmentId: \"env_test_000000000000\",\n logs,\n };\n\n return ctx;\n}\n"],"mappings":"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","names":[]}
|