@trypattern/sdk 0.1.19 → 0.1.20

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.
@@ -5,5 +5,11 @@ export type AuthService = {
5
5
  exchange: (code: string) => Promise<ExchangeReply | undefined>;
6
6
  sendCode: (request: SendCodeRequest) => Promise<SendCodeReply | undefined>;
7
7
  verifyCode: (request: VerifyCodeRequest) => Promise<VerifiedIdentity | undefined>;
8
+ noteOwner: (note: OwnerNote) => Promise<boolean>;
9
+ };
10
+ export type OwnerNote = {
11
+ subject: string;
12
+ text: string;
8
13
  };
9
14
  export declare function authServiceFor(env: ServerBindings): AuthService | undefined;
15
+ export declare function notifyOwner(env: ServerBindings, note: OwnerNote): Promise<boolean>;
@@ -1,3 +1,4 @@
1
+ import { z } from 'zod';
1
2
  import { exchangeReply, sendCodeReply, verifyCodeReply } from "./signInWire.js";
2
3
  export const AUTH_URL = 'https://auth.trypattern.ai';
3
4
  function httpAuthService(secret) {
@@ -18,7 +19,9 @@ function httpAuthService(secret) {
18
19
  return {
19
20
  exchange: (code) => post('/exchange', { code }, exchangeReply),
20
21
  sendCode: (request) => post('/email/send', request, sendCodeReply),
21
- verifyCode: async (request) => (await post('/email/verify', request, verifyCodeReply))?.identity
22
+ verifyCode: async (request) => (await post('/email/verify', request, verifyCodeReply))?.identity,
23
+ noteOwner: async (note) => (await post('/owner-note', note, z.object({ ok: z.literal(true) }))) !==
24
+ undefined
22
25
  };
23
26
  }
24
27
  const devCodes = new Map();
@@ -41,6 +44,10 @@ const devAuthService = {
41
44
  return undefined;
42
45
  devCodes.delete(challenge);
43
46
  return { email: sent.email, name: null, avatarUrl: null, via: 'email' };
47
+ },
48
+ noteOwner: async ({ subject, text }) => {
49
+ console.log(`Email to the owner: ${subject}\n${text}`);
50
+ return true;
44
51
  }
45
52
  };
46
53
  export function authServiceFor(env) {
@@ -48,3 +55,11 @@ export function authServiceFor(env) {
48
55
  return httpAuthService(env.AUTH_SECRET);
49
56
  return import.meta.env.DEV ? devAuthService : undefined;
50
57
  }
58
+ export async function notifyOwner(env, note) {
59
+ try {
60
+ return (await authServiceFor(env)?.noteOwner(note)) ?? false;
61
+ }
62
+ catch {
63
+ return false;
64
+ }
65
+ }
@@ -1,5 +1,6 @@
1
1
  import { FULL, RULES_ID, UNAVAILABLE, bookingBlackout, bookingRequests, bookingRules, bookingServices, bookingTables, daysOf, isValidTimezone, rulesOf, rulesProblem, slotFor, takenKey, windowsOn } from "../bookings.js";
2
2
  import { refused } from "../services.js";
3
+ import { notifyOwner } from "./authService.js";
3
4
  import { serveServices } from "./services.js";
4
5
  import { readRow, readRows } from "./tables.js";
5
6
  const HOLDING_SQL = "status IN ('requested', 'accepted')";
@@ -9,6 +10,24 @@ export async function sendBookingEmail(c, email) {
9
10
  const to = email.kind === 'requested' ? 'the owner' : email.request.email;
10
11
  console.log(`Booking email (${email.kind}) to ${to} from ${new URL(c.req.url).host}: ${email.request.name}, ${email.request.date} ${email.request.window}`);
11
12
  }
13
+ function ownerNoteOf(request) {
14
+ const lines = [
15
+ `${request.name} asked to book ${request.offering} on ${request.date}, ${request.window}.`,
16
+ '',
17
+ `Email: ${request.email}`,
18
+ ...(request.phone === '' ? [] : [`Phone: ${request.phone}`]),
19
+ ...(request.address === '' ? [] : [`Address: ${request.address}`]),
20
+ ...(request.notes === '' ? [] : ['', request.notes]),
21
+ '',
22
+ request.status === 'accepted'
23
+ ? 'It is booked: your booking rules accept requests on their own.'
24
+ : 'Accept or decline it on your site.'
25
+ ];
26
+ return {
27
+ subject: `New booking request from ${request.name}`,
28
+ text: lines.join('\n')
29
+ };
30
+ }
12
31
  function requireAdmin(c) {
13
32
  const viewer = c.get('viewer');
14
33
  if (viewer === null)
@@ -97,6 +116,7 @@ export function bookings({ timezone }) {
97
116
  const saved = await readRequest(c.env.DB, id);
98
117
  if (saved === undefined)
99
118
  throw new Error('The request was not saved');
119
+ await notifyOwner(c.env, ownerNoteOf(saved));
100
120
  await sendBookingEmail(c, {
101
121
  kind: status === 'accepted' ? 'accepted' : 'requested',
102
122
  request: saved
@@ -1,5 +1,7 @@
1
1
  export { createServer } from './createServer.ts';
2
2
  export type { ServerBindings, ServerBlock, ServerEnv, Viewer } from './env.ts';
3
+ export { notifyOwner } from './authService.ts';
4
+ export type { OwnerNote } from './authService.ts';
3
5
  export { bookings } from './bookings.ts';
4
6
  export type { BookingsOptions } from './bookings.ts';
5
7
  export { seedSql, serveTables, sqlTable, sqlTables } from './tables.ts';
@@ -1,4 +1,5 @@
1
1
  export { createServer } from "./createServer.js";
2
+ export { notifyOwner } from "./authService.js";
2
3
  export { bookings } from "./bookings.js";
3
4
  export { seedSql, serveTables, sqlTable, sqlTables } from "./tables.js";
4
5
  export { refused } from "../services.js";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@trypattern/sdk",
3
- "version": "0.1.19",
3
+ "version": "0.1.20",
4
4
  "type": "module",
5
5
  "files": [
6
6
  "dist",