@trypattern/sdk 0.1.18 → 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.
- package/dist/cli/publishing.js +8 -3
- package/dist/publishWire.d.ts +1 -0
- package/dist/publishWire.js +2 -1
- package/dist/server/authService.d.ts +6 -0
- package/dist/server/authService.js +16 -1
- package/dist/server/bookings.js +20 -0
- package/dist/server/index.d.ts +2 -0
- package/dist/server/index.js +1 -0
- package/dist/vite/projectFile.d.ts +2 -0
- package/dist/vite/projectFile.js +8 -2
- package/package.json +1 -1
package/dist/cli/publishing.js
CHANGED
|
@@ -6,7 +6,7 @@ import { z } from 'zod';
|
|
|
6
6
|
import { DASHBOARD_URL, UPLOAD, appSummary, isPrivatePath, loginPoll, loginStarted, mediaRow, nameProblem, publishMessage, publishSummary, setupCodeExchanged, sourcePathProblem } from "../publishWire.js";
|
|
7
7
|
import { appInfo } from "../appTitle.js";
|
|
8
8
|
import { SESSION_COOKIE } from "../auth/user.js";
|
|
9
|
-
import { PROJECT_FILE, blueprintOf, readProjectFile } from "../vite/projectFile.js";
|
|
9
|
+
import { PROJECT_FILE, blueprintOf, readProjectFile, rememberVersion } from "../vite/projectFile.js";
|
|
10
10
|
const CONFIG_DIR = join(homedir(), '.config', 'pattern');
|
|
11
11
|
const CREDENTIALS_FILE = join(CONFIG_DIR, 'credentials.json');
|
|
12
12
|
const PENDING_FILE = join(CONFIG_DIR, 'pending-login.json');
|
|
@@ -324,7 +324,8 @@ export async function pull(io, name, cwd, setupCode) {
|
|
|
324
324
|
if (existsSync(join(target, LAUNCHER)))
|
|
325
325
|
chmodSync(join(target, LAUNCHER), 0o755);
|
|
326
326
|
const blueprint = blueprintOf(target);
|
|
327
|
-
|
|
327
|
+
const version = Number(result.number);
|
|
328
|
+
writeFileSync(join(target, PROJECT_FILE), `${JSON.stringify({ name, title: result.title, ...(blueprint === undefined ? {} : { blueprint }), ...(Number.isInteger(version) ? { version } : {}) }, null, 2)}\n`);
|
|
328
329
|
io.say(`✓ Downloaded ${files} files of version ${result.number}`);
|
|
329
330
|
if (!(await ensurePnpm(io, target))) {
|
|
330
331
|
return {
|
|
@@ -491,7 +492,7 @@ async function followPublish(io, name, started) {
|
|
|
491
492
|
export async function publish(io, root, isStarter, message, starter) {
|
|
492
493
|
try {
|
|
493
494
|
sayHost(io);
|
|
494
|
-
const { name, blueprint } = readProjectFile(root);
|
|
495
|
+
const { name, blueprint, version } = readProjectFile(root);
|
|
495
496
|
if (isStarter && blueprint === undefined) {
|
|
496
497
|
throw new Error(`${PROJECT_FILE} needs "blueprint" ("website" or "web-app") to publish the starter for it`);
|
|
497
498
|
}
|
|
@@ -503,6 +504,8 @@ export async function publish(io, root, isStarter, message, starter) {
|
|
|
503
504
|
if (isStarter && blueprint !== undefined) {
|
|
504
505
|
form.append(UPLOAD.blueprint, blueprint);
|
|
505
506
|
}
|
|
507
|
+
if (!isStarter)
|
|
508
|
+
form.append(UPLOAD.version, String(version ?? 0));
|
|
506
509
|
const said = publishMessage(message ?? '');
|
|
507
510
|
if (said !== null)
|
|
508
511
|
form.append(UPLOAD.message, said);
|
|
@@ -530,6 +533,7 @@ export async function publish(io, root, isStarter, message, starter) {
|
|
|
530
533
|
text: `✓ Published the ${blueprint} starter for SDK ${io.sdkVersion}`
|
|
531
534
|
};
|
|
532
535
|
}
|
|
536
|
+
rememberVersion(root, result.number);
|
|
533
537
|
return await followPublish(io, name, result);
|
|
534
538
|
}
|
|
535
539
|
catch (error) {
|
|
@@ -589,6 +593,7 @@ export async function restore(io, root, number) {
|
|
|
589
593
|
const result = await signedIn(io, `app restore ${number}`, () => callJson(`/api/apps/${name}/publishes/${number}/restore`, publishSummary, { method: 'POST' }));
|
|
590
594
|
if (isOutcome(result))
|
|
591
595
|
return result;
|
|
596
|
+
rememberVersion(root, result.number);
|
|
592
597
|
return await followPublish(io, name, result);
|
|
593
598
|
}
|
|
594
599
|
catch (error) {
|
package/dist/publishWire.d.ts
CHANGED
|
@@ -23,6 +23,7 @@ export declare const UPLOAD: {
|
|
|
23
23
|
readonly runWorkerFirst: "runWorkerFirst";
|
|
24
24
|
readonly starter: "starter";
|
|
25
25
|
readonly blueprint: "blueprint";
|
|
26
|
+
readonly version: "version";
|
|
26
27
|
};
|
|
27
28
|
export declare const BLUEPRINTS: readonly ["website", "web-app"];
|
|
28
29
|
export declare const blueprintName: z.ZodEnum<{
|
package/dist/publishWire.js
CHANGED
|
@@ -94,7 +94,8 @@ export const UPLOAD = {
|
|
|
94
94
|
message: 'message',
|
|
95
95
|
runWorkerFirst: 'runWorkerFirst',
|
|
96
96
|
starter: 'starter',
|
|
97
|
-
blueprint: 'blueprint'
|
|
97
|
+
blueprint: 'blueprint',
|
|
98
|
+
version: 'version'
|
|
98
99
|
};
|
|
99
100
|
export const BLUEPRINTS = ['website', 'web-app'];
|
|
100
101
|
export const blueprintName = z.enum(BLUEPRINTS);
|
|
@@ -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
|
+
}
|
package/dist/server/bookings.js
CHANGED
|
@@ -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
|
package/dist/server/index.d.ts
CHANGED
|
@@ -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';
|
package/dist/server/index.js
CHANGED
|
@@ -7,8 +7,10 @@ declare const projectFile: z.ZodObject<{
|
|
|
7
7
|
website: "website";
|
|
8
8
|
"web-app": "web-app";
|
|
9
9
|
}>>;
|
|
10
|
+
version: z.ZodOptional<z.ZodNumber>;
|
|
10
11
|
}, z.core.$strip>;
|
|
11
12
|
export type ProjectFile = z.output<typeof projectFile>;
|
|
12
13
|
export declare function readProjectFile(root: string): ProjectFile;
|
|
13
14
|
export declare function blueprintOf(root: string): "website" | "web-app" | undefined;
|
|
15
|
+
export declare function rememberVersion(root: string, version: number): void;
|
|
14
16
|
export {};
|
package/dist/vite/projectFile.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { existsSync, readFileSync } from 'node:fs';
|
|
1
|
+
import { existsSync, readFileSync, writeFileSync } from 'node:fs';
|
|
2
2
|
import { join } from 'node:path';
|
|
3
3
|
import { z } from 'zod';
|
|
4
4
|
import { appTitle } from "../appTitle.js";
|
|
@@ -7,7 +7,8 @@ export const PROJECT_FILE = 'pattern.json';
|
|
|
7
7
|
const projectFile = z.object({
|
|
8
8
|
name: z.string().min(1),
|
|
9
9
|
title: appTitle,
|
|
10
|
-
blueprint: blueprintName.optional()
|
|
10
|
+
blueprint: blueprintName.optional(),
|
|
11
|
+
version: z.number().int().min(0).optional()
|
|
11
12
|
});
|
|
12
13
|
export function readProjectFile(root) {
|
|
13
14
|
const path = join(root, PROJECT_FILE);
|
|
@@ -33,3 +34,8 @@ export function blueprintOf(root) {
|
|
|
33
34
|
return undefined;
|
|
34
35
|
}
|
|
35
36
|
}
|
|
37
|
+
export function rememberVersion(root, version) {
|
|
38
|
+
const path = join(root, PROJECT_FILE);
|
|
39
|
+
const raw = JSON.parse(readFileSync(path, 'utf8'));
|
|
40
|
+
writeFileSync(path, `${JSON.stringify({ ...Object(raw), version }, null, 2)}\n`);
|
|
41
|
+
}
|