@trypattern/sdk 0.1.33 → 0.1.35
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/app.d.ts +6 -2
- package/dist/app.js +6 -1
- package/dist/blocks.js +11 -3
- package/dist/bookings.d.ts +78 -0
- package/dist/bookings.js +7 -1
- package/dist/bookingsStore.d.ts +78 -0
- package/dist/cli/app.js +17 -2
- package/dist/cli/requests.d.ts +5 -0
- package/dist/cli/requests.js +115 -0
- package/dist/components/AppFrame.js +12 -2
- package/dist/components/Icon.js +1 -1
- package/dist/components/MenuItems.d.ts +1 -0
- package/dist/components/MenuItems.js +13 -2
- package/dist/components/SegmentedControl.d.ts +1 -0
- package/dist/components/SegmentedControl.js +9 -2
- package/dist/components/Sidebar.d.ts +1 -0
- package/dist/components/Sidebar.js +18 -2
- package/dist/components/TableRow.d.ts +2 -1
- package/dist/components/TableRow.js +5 -2
- package/dist/components/icons.js +1 -2
- package/dist/index.d.ts +2 -0
- package/dist/index.js +1 -0
- package/dist/inquiriesStore.d.ts +134 -0
- package/dist/inquiriesStore.js +64 -0
- package/dist/patternAccess.d.ts +8 -2
- package/dist/patternAccess.js +17 -5
- package/dist/publishWire.d.ts +866 -0
- package/dist/publishWire.js +78 -0
- package/dist/requests.d.ts +361 -0
- package/dist/requests.js +180 -0
- package/dist/schema.d.ts +2 -0
- package/dist/schema.js +1 -0
- package/dist/server/authService.d.ts +1 -0
- package/dist/server/bookings.d.ts +2 -9
- package/dist/server/bookings.js +149 -31
- package/dist/server/createServer.js +4 -0
- package/dist/server/env.d.ts +3 -0
- package/dist/server/index.d.ts +1 -0
- package/dist/server/index.js +1 -0
- package/dist/server/inquiries.d.ts +9 -0
- package/dist/server/inquiries.js +150 -0
- package/dist/server/patternViewer.js +7 -1
- package/dist/server/requests.d.ts +76 -0
- package/dist/server/requests.js +328 -0
- package/dist/server/services.js +9 -1
- package/package.json +1 -1
|
@@ -4,11 +4,11 @@ import * as stylex from '@stylexjs/stylex';
|
|
|
4
4
|
import { borders, colors, space } from "../theme/tokens.stylex.js";
|
|
5
5
|
import { focusRing } from "./controlLook.js";
|
|
6
6
|
import { interact } from "./interaction.js";
|
|
7
|
-
export function TableRow({ label, isCurrent = false, onClick, children }) {
|
|
7
|
+
export function TableRow({ label, isCurrent = false, size = 'md', onClick, children }) {
|
|
8
8
|
return (_jsx(BaseButton, { "aria-label": label, "aria-pressed": isCurrent, onClick: () => {
|
|
9
9
|
interact({ primitive: 'TableRow', event: 'click', label });
|
|
10
10
|
onClick();
|
|
11
|
-
}, className: stylex.props(styles.row, isCurrent && styles.current, focusRing.visible, focusRing.inside).className, children: children }));
|
|
11
|
+
}, className: stylex.props(styles.row, size === 'lg' && styles.large, isCurrent && styles.current, focusRing.visible, focusRing.inside).className, children: children }));
|
|
12
12
|
}
|
|
13
13
|
const styles = stylex.create({
|
|
14
14
|
row: {
|
|
@@ -30,6 +30,9 @@ const styles = stylex.create({
|
|
|
30
30
|
borderBottomStyle: 'solid',
|
|
31
31
|
borderBottomWidth: borders.thin
|
|
32
32
|
},
|
|
33
|
+
large: {
|
|
34
|
+
height: `calc(${space.xxxl} + ${space.sm})`
|
|
35
|
+
},
|
|
33
36
|
current: {
|
|
34
37
|
backgroundColor: colors.transparentHover
|
|
35
38
|
}
|
package/dist/components/icons.js
CHANGED
|
@@ -102,8 +102,7 @@ const builtInIcons = {
|
|
|
102
102
|
],
|
|
103
103
|
arrowDown: 'M12 5v14M6 13l6 6 6-6',
|
|
104
104
|
logOut: [
|
|
105
|
-
'
|
|
106
|
-
'M19.5 12H10M16 8.5l3.5 3.5-3.5 3.5'
|
|
105
|
+
'M20.25 12L9 12M20.25 12L15.75 16.5M20.25 12L15.75 7.5M11.25 20.25H5.75C4.64543 20.25 3.75 19.3546 3.75 18.25L3.75 5.75C3.75 4.64543 4.64543 3.75 5.75 3.75L11.25 3.75'
|
|
107
106
|
],
|
|
108
107
|
today: 'M11.998 3.291V1.768M5.84 18.159L4.763 19.236M11.998 22.233V20.709M19.233 4.765L18.156 5.842M20.707 12H22.23M18.156 18.159L19.233 19.236M1.766 12H3.289M4.763 4.765L5.84 5.842M15.71 8.288C17.761 10.338 17.761 13.662 15.71 15.712C13.66 17.763 10.336 17.763 8.286 15.712C6.235 13.662 6.235 10.338 8.286 8.288C10.336 6.238 13.66 6.238 15.71 8.288Z',
|
|
109
108
|
checklist: 'M11.75 16.25H20.25M11.75 7.75H20.25M3.75 8.625L5.417 9.75L8.75 5.25M3.75 17.625L5.417 18.75L8.75 14.25',
|
package/dist/index.d.ts
CHANGED
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
export { defineApp } from './app.ts';
|
|
2
2
|
export { Bookings, bookings } from './bookingsStore.ts';
|
|
3
3
|
export type { BookingsWorld } from './bookingsMemory.ts';
|
|
4
|
+
export { Inquiries, inquiries } from './inquiriesStore.ts';
|
|
5
|
+
export type { InquiriesWorld } from './inquiriesStore.ts';
|
|
4
6
|
export type { AppBlock } from './blocks.ts';
|
|
5
7
|
export { ActionsStore, bindActions, rankActions } from './actions.ts';
|
|
6
8
|
export type { Action, ActionsBuilder } from './actions.ts';
|
package/dist/index.js
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
export { defineApp } from "./app.js";
|
|
2
2
|
export { Bookings, bookings } from "./bookingsStore.js";
|
|
3
|
+
export { Inquiries, inquiries } from "./inquiriesStore.js";
|
|
3
4
|
export { ActionsStore, bindActions, rankActions } from "./actions.js";
|
|
4
5
|
export { startApp } from "./start.js";
|
|
5
6
|
export { appearance } from "./appearance.js";
|
|
@@ -0,0 +1,134 @@
|
|
|
1
|
+
import { z } from 'zod';
|
|
2
|
+
import type { WriteOutcome } from './access.ts';
|
|
3
|
+
import { inquiryValue } from './requests.ts';
|
|
4
|
+
import type { ServiceClient, ServiceMemory } from './services.ts';
|
|
5
|
+
type Fields = Readonly<Record<string, z.output<typeof inquiryValue>>>;
|
|
6
|
+
export type InquiriesWorld = {
|
|
7
|
+
sent?: {
|
|
8
|
+
source: string;
|
|
9
|
+
id: string;
|
|
10
|
+
fields: Fields;
|
|
11
|
+
}[];
|
|
12
|
+
sources?: string[];
|
|
13
|
+
};
|
|
14
|
+
declare const Inquiries_base: import("./store.ts").StoreClass<{
|
|
15
|
+
sent: z.ZodDefault<z.ZodNullable<z.ZodObject<{
|
|
16
|
+
source: z.ZodString;
|
|
17
|
+
id: z.ZodString;
|
|
18
|
+
}, z.core.$strip>>>;
|
|
19
|
+
isSending: z.ZodDefault<z.ZodBoolean>;
|
|
20
|
+
}, [], ServiceClient<{
|
|
21
|
+
readonly inquiries: {
|
|
22
|
+
readonly send: NoInfer<import("./services.ts").ServiceCall<"/requests/:source", {
|
|
23
|
+
fields: z.ZodRecord<z.ZodString, z.ZodUnion<readonly [z.ZodString, z.ZodNumber, z.ZodBoolean, z.ZodNull]>>;
|
|
24
|
+
}, z.ZodObject<{
|
|
25
|
+
id: z.ZodString;
|
|
26
|
+
}, z.core.$strip>, false>>;
|
|
27
|
+
};
|
|
28
|
+
}>>;
|
|
29
|
+
export declare class Inquiries extends Inquiries_base {
|
|
30
|
+
send(source: string, fields: Fields): Promise<WriteOutcome>;
|
|
31
|
+
}
|
|
32
|
+
export declare const inquiries: {
|
|
33
|
+
readonly name: "inquiries";
|
|
34
|
+
readonly tables: {
|
|
35
|
+
requestStates: import("./table.ts").TableOf<"requestStates", {
|
|
36
|
+
readonly columns: {
|
|
37
|
+
readonly source: z.ZodString;
|
|
38
|
+
readonly requestId: z.ZodString;
|
|
39
|
+
readonly state: z.ZodEnum<{
|
|
40
|
+
done: "done";
|
|
41
|
+
open: "open";
|
|
42
|
+
}>;
|
|
43
|
+
readonly revision: z.ZodNumber;
|
|
44
|
+
readonly sequence: z.ZodNumber;
|
|
45
|
+
readonly updatedAt: z.ZodString;
|
|
46
|
+
};
|
|
47
|
+
readonly access: {
|
|
48
|
+
readonly read: "server";
|
|
49
|
+
readonly create: "server";
|
|
50
|
+
readonly update: "server";
|
|
51
|
+
readonly delete: "server";
|
|
52
|
+
};
|
|
53
|
+
readonly writes: "confirmed";
|
|
54
|
+
}>;
|
|
55
|
+
requestEvents: import("./table.ts").TableOf<"requestEvents", {
|
|
56
|
+
readonly columns: {
|
|
57
|
+
readonly source: z.ZodString;
|
|
58
|
+
readonly requestId: z.ZodString;
|
|
59
|
+
readonly kind: z.ZodEnum<{
|
|
60
|
+
done: "done";
|
|
61
|
+
accepted: "accepted";
|
|
62
|
+
declined: "declined";
|
|
63
|
+
replied: "replied";
|
|
64
|
+
received: "received";
|
|
65
|
+
}>;
|
|
66
|
+
};
|
|
67
|
+
readonly access: {
|
|
68
|
+
readonly read: "server";
|
|
69
|
+
readonly create: "server";
|
|
70
|
+
readonly update: "server";
|
|
71
|
+
readonly delete: "server";
|
|
72
|
+
};
|
|
73
|
+
readonly writes: "confirmed";
|
|
74
|
+
}>;
|
|
75
|
+
requestOutbox: import("./table.ts").TableOf<"requestOutbox", {
|
|
76
|
+
readonly columns: {
|
|
77
|
+
readonly source: z.ZodString;
|
|
78
|
+
readonly requestId: z.ZodString;
|
|
79
|
+
readonly subject: z.ZodString;
|
|
80
|
+
readonly text: z.ZodString;
|
|
81
|
+
readonly replyTo: z.ZodString;
|
|
82
|
+
readonly status: z.ZodEnum<{
|
|
83
|
+
failed: "failed";
|
|
84
|
+
pending: "pending";
|
|
85
|
+
sent: "sent";
|
|
86
|
+
sending: "sending";
|
|
87
|
+
}>;
|
|
88
|
+
readonly attempts: z.ZodNumber;
|
|
89
|
+
readonly nextAt: z.ZodNullable<z.ZodString>;
|
|
90
|
+
readonly sentAt: z.ZodNullable<z.ZodString>;
|
|
91
|
+
readonly claimedAt: z.ZodNullable<z.ZodString>;
|
|
92
|
+
};
|
|
93
|
+
readonly access: {
|
|
94
|
+
readonly read: "server";
|
|
95
|
+
readonly create: "server";
|
|
96
|
+
readonly update: "server";
|
|
97
|
+
readonly delete: "server";
|
|
98
|
+
};
|
|
99
|
+
readonly writes: "confirmed";
|
|
100
|
+
}>;
|
|
101
|
+
requestOperations: import("./table.ts").TableOf<"requestOperations", {
|
|
102
|
+
readonly columns: {
|
|
103
|
+
readonly result: z.ZodString;
|
|
104
|
+
};
|
|
105
|
+
readonly access: {
|
|
106
|
+
readonly read: "server";
|
|
107
|
+
readonly create: "server";
|
|
108
|
+
readonly update: "server";
|
|
109
|
+
readonly delete: "server";
|
|
110
|
+
};
|
|
111
|
+
readonly writes: "confirmed";
|
|
112
|
+
}>;
|
|
113
|
+
};
|
|
114
|
+
readonly services: {
|
|
115
|
+
readonly inquiries: {
|
|
116
|
+
readonly send: NoInfer<import("./services.ts").ServiceCall<"/requests/:source", {
|
|
117
|
+
fields: z.ZodRecord<z.ZodString, z.ZodUnion<readonly [z.ZodString, z.ZodNumber, z.ZodBoolean, z.ZodNull]>>;
|
|
118
|
+
}, z.ZodObject<{
|
|
119
|
+
id: z.ZodString;
|
|
120
|
+
}, z.core.$strip>, false>>;
|
|
121
|
+
};
|
|
122
|
+
};
|
|
123
|
+
readonly memory: ServiceMemory<{
|
|
124
|
+
readonly inquiries: {
|
|
125
|
+
readonly send: NoInfer<import("./services.ts").ServiceCall<"/requests/:source", {
|
|
126
|
+
fields: z.ZodRecord<z.ZodString, z.ZodUnion<readonly [z.ZodString, z.ZodNumber, z.ZodBoolean, z.ZodNull]>>;
|
|
127
|
+
}, z.ZodObject<{
|
|
128
|
+
id: z.ZodString;
|
|
129
|
+
}, z.core.$strip>, false>>;
|
|
130
|
+
};
|
|
131
|
+
}, unknown>;
|
|
132
|
+
readonly Store: typeof Inquiries;
|
|
133
|
+
};
|
|
134
|
+
export {};
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
import { z } from 'zod';
|
|
2
|
+
import { inquiryServices, inquiryValue, requestTables } from "./requests.js";
|
|
3
|
+
import { ServiceRefused, refused } from "./services.js";
|
|
4
|
+
import { defineStore } from "./store.js";
|
|
5
|
+
const Store = defineStore();
|
|
6
|
+
function worldOf(world) {
|
|
7
|
+
const found = Reflect.get(Object(world), 'inquiries');
|
|
8
|
+
return typeof found === 'object' && found !== null ? found : {};
|
|
9
|
+
}
|
|
10
|
+
const inquiryMemory = {
|
|
11
|
+
inquiries: {
|
|
12
|
+
send: (world, { source, fields }) => {
|
|
13
|
+
const current = worldOf(world);
|
|
14
|
+
if (current.sources !== undefined && !current.sources.includes(source)) {
|
|
15
|
+
throw refused(404, 'No such form');
|
|
16
|
+
}
|
|
17
|
+
const sent = current.sent ?? [];
|
|
18
|
+
const id = `${source}-${sent.length + 1}`;
|
|
19
|
+
Reflect.set(Object(world), 'inquiries', {
|
|
20
|
+
...current,
|
|
21
|
+
sent: [...sent, { source, id, fields }]
|
|
22
|
+
});
|
|
23
|
+
return { id };
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
};
|
|
27
|
+
function outcomeOf(error) {
|
|
28
|
+
if (!(error instanceof ServiceRefused))
|
|
29
|
+
return 'failed';
|
|
30
|
+
if (error.status === 400 || error.status === 404)
|
|
31
|
+
return 'forbidden';
|
|
32
|
+
return error.status === 409 ? 'conflict' : 'failed';
|
|
33
|
+
}
|
|
34
|
+
export class Inquiries extends Store({
|
|
35
|
+
state: {
|
|
36
|
+
sent: z
|
|
37
|
+
.object({ source: z.string(), id: z.string() })
|
|
38
|
+
.nullable()
|
|
39
|
+
.default(null),
|
|
40
|
+
isSending: z.boolean().default(false)
|
|
41
|
+
}
|
|
42
|
+
}) {
|
|
43
|
+
async send(source, fields) {
|
|
44
|
+
this.set({ isSending: true });
|
|
45
|
+
try {
|
|
46
|
+
const { id } = await this.services.inquiries.send({ source, fields });
|
|
47
|
+
this.set({ sent: { source, id } });
|
|
48
|
+
return 'saved';
|
|
49
|
+
}
|
|
50
|
+
catch (error) {
|
|
51
|
+
return outcomeOf(error);
|
|
52
|
+
}
|
|
53
|
+
finally {
|
|
54
|
+
this.set({ isSending: false });
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
export const inquiries = {
|
|
59
|
+
name: 'inquiries',
|
|
60
|
+
tables: requestTables,
|
|
61
|
+
services: inquiryServices,
|
|
62
|
+
memory: inquiryMemory,
|
|
63
|
+
Store: Inquiries
|
|
64
|
+
};
|
package/dist/patternAccess.d.ts
CHANGED
|
@@ -2,6 +2,8 @@ import { z } from 'zod';
|
|
|
2
2
|
export declare const TABLES_READ = "tables:read";
|
|
3
3
|
export declare const MEDIA_WRITE = "media:write";
|
|
4
4
|
export declare const TABLES_WRITE = "tables:write";
|
|
5
|
+
export declare const REQUESTS_READ = "requests:read";
|
|
6
|
+
export declare const REQUESTS_ACT = "requests:act";
|
|
5
7
|
export declare const ASSERTION_SECONDS = 60;
|
|
6
8
|
export declare const NEXT_PAGE_HEADER = "x-pattern-next";
|
|
7
9
|
export declare const assertionKey: z.ZodObject<{
|
|
@@ -16,17 +18,21 @@ declare const assertionScope: z.ZodEnum<{
|
|
|
16
18
|
"tables:read": "tables:read";
|
|
17
19
|
"media:write": "media:write";
|
|
18
20
|
"tables:write": "tables:write";
|
|
21
|
+
"requests:read": "requests:read";
|
|
22
|
+
"requests:act": "requests:act";
|
|
19
23
|
}>;
|
|
20
24
|
export type AssertionScope = z.output<typeof assertionScope>;
|
|
21
|
-
export declare function signAssertion(key: AssertionKey, { sub, aud, scope }: {
|
|
25
|
+
export declare function signAssertion(key: AssertionKey, { sub, aud, scope, bound }: {
|
|
22
26
|
sub: string;
|
|
23
27
|
aud: string;
|
|
24
28
|
scope: AssertionScope;
|
|
29
|
+
bound?: string;
|
|
25
30
|
}, now: number): Promise<string>;
|
|
26
|
-
export declare function verifiedAssertion(token: string, { hostname, keys, now, scope }: {
|
|
31
|
+
export declare function verifiedAssertion(token: string, { hostname, keys, now, scope, bound }: {
|
|
27
32
|
hostname: string;
|
|
28
33
|
keys: Readonly<Record<string, string>>;
|
|
29
34
|
now: number;
|
|
30
35
|
scope: AssertionScope;
|
|
36
|
+
bound?: string;
|
|
31
37
|
}): Promise<string | undefined>;
|
|
32
38
|
export {};
|
package/dist/patternAccess.js
CHANGED
|
@@ -2,6 +2,8 @@ import { z } from 'zod';
|
|
|
2
2
|
export const TABLES_READ = 'tables:read';
|
|
3
3
|
export const MEDIA_WRITE = 'media:write';
|
|
4
4
|
export const TABLES_WRITE = 'tables:write';
|
|
5
|
+
export const REQUESTS_READ = 'requests:read';
|
|
6
|
+
export const REQUESTS_ACT = 'requests:act';
|
|
5
7
|
export const ASSERTION_SECONDS = 60;
|
|
6
8
|
export const NEXT_PAGE_HEADER = 'x-pattern-next';
|
|
7
9
|
const CLOCK_SKEW_SECONDS = 30;
|
|
@@ -13,7 +15,13 @@ export const assertionKey = z.object({
|
|
|
13
15
|
x: z.string(),
|
|
14
16
|
d: z.string()
|
|
15
17
|
});
|
|
16
|
-
const assertionScope = z.enum([
|
|
18
|
+
const assertionScope = z.enum([
|
|
19
|
+
TABLES_READ,
|
|
20
|
+
TABLES_WRITE,
|
|
21
|
+
MEDIA_WRITE,
|
|
22
|
+
REQUESTS_READ,
|
|
23
|
+
REQUESTS_ACT
|
|
24
|
+
]);
|
|
17
25
|
const assertionHeader = z.object({
|
|
18
26
|
alg: z.literal('EdDSA'),
|
|
19
27
|
typ: z.literal('JWT'),
|
|
@@ -24,7 +32,8 @@ const assertionClaims = z.object({
|
|
|
24
32
|
aud: z.string(),
|
|
25
33
|
scope: assertionScope,
|
|
26
34
|
iat: z.int(),
|
|
27
|
-
exp: z.int()
|
|
35
|
+
exp: z.int(),
|
|
36
|
+
bnd: z.string().optional()
|
|
28
37
|
});
|
|
29
38
|
const encoder = new TextEncoder();
|
|
30
39
|
function base64url(bytes) {
|
|
@@ -56,14 +65,15 @@ function jsonOf(text) {
|
|
|
56
65
|
function encoded(value) {
|
|
57
66
|
return base64url(encoder.encode(JSON.stringify(value)));
|
|
58
67
|
}
|
|
59
|
-
export async function signAssertion(key, { sub, aud, scope }, now) {
|
|
68
|
+
export async function signAssertion(key, { sub, aud, scope, bound }, now) {
|
|
60
69
|
const privateKey = await crypto.subtle.importKey('jwk', { kty: key.kty, crv: key.crv, x: key.x, d: key.d }, ED25519, false, ['sign']);
|
|
61
70
|
const signed = `${encoded({ alg: 'EdDSA', typ: 'JWT', kid: key.kid })}.${encoded({
|
|
62
71
|
sub,
|
|
63
72
|
aud,
|
|
64
73
|
scope,
|
|
65
74
|
iat: now,
|
|
66
|
-
exp: now + ASSERTION_SECONDS
|
|
75
|
+
exp: now + ASSERTION_SECONDS,
|
|
76
|
+
...(bound === undefined ? {} : { bnd: bound })
|
|
67
77
|
})}`;
|
|
68
78
|
const signature = await crypto.subtle.sign(ED25519, privateKey, encoder.encode(signed));
|
|
69
79
|
return `${signed}.${base64url(new Uint8Array(signature))}`;
|
|
@@ -83,7 +93,7 @@ async function isSignedBy(publicKey, signed, signature) {
|
|
|
83
93
|
return false;
|
|
84
94
|
}
|
|
85
95
|
}
|
|
86
|
-
export async function verifiedAssertion(token, { hostname, keys, now, scope }) {
|
|
96
|
+
export async function verifiedAssertion(token, { hostname, keys, now, scope, bound }) {
|
|
87
97
|
const [header, claims, signature, ...rest] = token.split('.');
|
|
88
98
|
if (header === undefined ||
|
|
89
99
|
claims === undefined ||
|
|
@@ -107,6 +117,8 @@ export async function verifiedAssertion(token, { hostname, keys, now, scope }) {
|
|
|
107
117
|
const { sub, aud, iat, exp } = parsed.data;
|
|
108
118
|
if (parsed.data.scope !== scope)
|
|
109
119
|
return undefined;
|
|
120
|
+
if (bound !== undefined && parsed.data.bnd !== bound)
|
|
121
|
+
return undefined;
|
|
110
122
|
const isFresh = exp > iat &&
|
|
111
123
|
exp - iat <= ASSERTION_SECONDS &&
|
|
112
124
|
iat <= now + CLOCK_SKEW_SECONDS &&
|