@trypattern/sdk 0.1.0 → 0.1.2
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/api.d.ts +17 -7
- package/dist/api.js +34 -8
- package/dist/app.d.ts +12 -3
- package/dist/app.js +49 -7
- package/dist/appInfo.d.ts +35 -0
- package/dist/appInfo.js +67 -0
- package/dist/appTitle.d.ts +6 -0
- package/dist/appTitle.js +3 -0
- package/dist/auth/sessionApi.js +2 -1
- package/dist/builtins/AppSettings.d.ts +12 -0
- package/dist/builtins/AppSettings.js +31 -0
- package/dist/builtins/Toasts.d.ts +1 -1
- package/dist/builtins/Toasts.js +2 -1
- package/dist/cli/app.js +91 -14
- package/dist/cli/publishing.d.ts +21 -0
- package/dist/cli/publishing.js +502 -0
- package/dist/clock.d.ts +6 -0
- package/dist/clock.js +31 -0
- package/dist/components/AppFrame.js +3 -3
- package/dist/components/Button.d.ts +2 -1
- package/dist/components/Button.js +6 -3
- package/dist/components/CopyButton.d.ts +11 -0
- package/dist/components/CopyButton.js +16 -0
- package/dist/components/Divider.d.ts +2 -1
- package/dist/components/Divider.js +19 -4
- package/dist/components/IconButton.js +2 -2
- package/dist/components/Link.d.ts +8 -3
- package/dist/components/Link.js +11 -2
- package/dist/components/ListRow.js +2 -2
- package/dist/components/Menu.js +2 -2
- package/dist/components/RadioGroup.d.ts +18 -0
- package/dist/components/RadioGroup.js +85 -0
- package/dist/components/SegmentedControl.js +2 -2
- package/dist/components/Sidebar.js +2 -3
- package/dist/components/SignInScreen.js +3 -3
- package/dist/components/Switch.js +2 -1
- package/dist/components/controlLook.d.ts +10 -0
- package/dist/components/controlLook.js +14 -1
- package/dist/components/icons.d.ts +4 -3
- package/dist/components/icons.js +9 -3
- package/dist/components/interaction.d.ts +1 -1
- package/dist/flows/accessFlows.js +19 -3
- package/dist/flows/browser.d.ts +3 -1
- package/dist/flows/browser.js +6 -3
- package/dist/flows/flowBrowser.d.ts +3 -1
- package/dist/flows/flowBrowser.js +4 -2
- package/dist/flows/flows.d.ts +6 -0
- package/dist/flows/flows.js +32 -5
- package/dist/hooks/appContext.d.ts +2 -1
- package/dist/index.d.ts +6 -2
- package/dist/index.js +4 -2
- package/dist/publishWire.d.ts +271 -0
- package/dist/publishWire.js +168 -0
- package/dist/react.d.ts +3 -0
- package/dist/react.js +2 -0
- package/dist/registered.d.ts +6 -0
- package/dist/registered.js +2 -0
- package/dist/rules/checkAllFiles.js +10 -2
- package/dist/rules/lintPlugin.js +2 -0
- package/dist/rules/messages.d.ts +2 -2
- package/dist/rules/messages.js +2 -2
- package/dist/schema.d.ts +2 -0
- package/dist/schema.js +1 -0
- package/dist/server/auth.js +8 -2
- package/dist/server/createServer.d.ts +48 -3
- package/dist/server/createServer.js +25 -5
- package/dist/server/env.d.ts +2 -2
- package/dist/server/index.d.ts +6 -1
- package/dist/server/index.js +5 -1
- package/dist/server/services.d.ts +9 -0
- package/dist/server/services.js +47 -0
- package/dist/server/session.d.ts +1 -0
- package/dist/server/session.js +11 -0
- package/dist/server/settings.d.ts +49 -0
- package/dist/server/settings.js +25 -0
- package/dist/server/signInWire.d.ts +1 -0
- package/dist/server/signInWire.js +2 -1
- package/dist/serviceClients.d.ts +5 -0
- package/dist/serviceClients.js +70 -0
- package/dist/services.d.ts +53 -0
- package/dist/services.js +30 -0
- package/dist/start.js +30 -6
- package/dist/store.d.ts +5 -3
- package/dist/store.js +13 -3
- package/dist/table.d.ts +1 -1
- package/dist/vite/localWorker.d.ts +1 -1
- package/dist/vite/localWorker.js +5 -4
- package/dist/vite/projectFile.d.ts +9 -0
- package/dist/vite/projectFile.js +17 -0
- package/dist/vite/vite.d.ts +2 -1
- package/dist/vite/vite.js +10 -3
- package/package.json +5 -1
- package/presets/register.d.ts +2 -0
package/dist/flows/flows.js
CHANGED
|
@@ -2,6 +2,7 @@ import { createMemoryRouter } from 'react-router';
|
|
|
2
2
|
import { afterAll, expect, inject, test } from 'vitest';
|
|
3
3
|
import { apiCalls, memoryApi } from "../api.js";
|
|
4
4
|
import { Cache } from "../cache.js";
|
|
5
|
+
import { manualClock } from "../clock.js";
|
|
5
6
|
import { Gate } from "../gate.js";
|
|
6
7
|
import { routeObjects } from "../routes.js";
|
|
7
8
|
import { screenshotNameProblem } from "./screenshotName.js";
|
|
@@ -47,6 +48,12 @@ async function runSteps(name, steps, run) {
|
|
|
47
48
|
else if ('restart' in step) {
|
|
48
49
|
await run.restart();
|
|
49
50
|
}
|
|
51
|
+
else if ('tick' in step) {
|
|
52
|
+
await run.tick();
|
|
53
|
+
}
|
|
54
|
+
else if ('world' in step) {
|
|
55
|
+
await run.world(step.world);
|
|
56
|
+
}
|
|
50
57
|
else {
|
|
51
58
|
expect(await run.snapshot(), `step ${index + 1} of "${name}": expected ${JSON.stringify(step.expect)}`).toMatchObject(step.expect);
|
|
52
59
|
}
|
|
@@ -61,18 +68,30 @@ function withTestParams(path, failing, held) {
|
|
|
61
68
|
return `${path}?${params.toString()}`;
|
|
62
69
|
}
|
|
63
70
|
export function defineFlow({ App }) {
|
|
64
|
-
const { tables, routes } = App.definition;
|
|
71
|
+
const { tables, routes, services, memory } = App.definition;
|
|
65
72
|
const seed = (inject('patternSeed') ?? {});
|
|
66
73
|
const admins = inject('patternAdmins') ?? [];
|
|
67
|
-
const
|
|
74
|
+
const title = inject('patternTitle') ?? '';
|
|
75
|
+
const startingWorld = inject('patternWorld') ?? {};
|
|
76
|
+
const calls = apiCalls(tables, services);
|
|
68
77
|
const router = (path) => createMemoryRouter(routeObjects(routes), { initialEntries: [path] });
|
|
69
78
|
function headless(name, steps, startAt, failing, signedInAs) {
|
|
70
79
|
test(name, async () => {
|
|
71
80
|
const gate = new Gate(failing);
|
|
81
|
+
const world = structuredClone(startingWorld);
|
|
72
82
|
const deps = {
|
|
73
|
-
api: memoryApi(tables, seed, {
|
|
83
|
+
api: memoryApi(tables, seed, {
|
|
84
|
+
gate,
|
|
85
|
+
signedInAs,
|
|
86
|
+
admins,
|
|
87
|
+
title,
|
|
88
|
+
world,
|
|
89
|
+
...(services === undefined ? {} : { services }),
|
|
90
|
+
...(memory === undefined ? {} : { memory })
|
|
91
|
+
}),
|
|
74
92
|
cache: Cache.memory(),
|
|
75
|
-
gate
|
|
93
|
+
gate,
|
|
94
|
+
clock: manualClock()
|
|
76
95
|
};
|
|
77
96
|
let app = new App(router(startAt), deps);
|
|
78
97
|
await runSteps(name, steps, {
|
|
@@ -86,6 +105,12 @@ export function defineFlow({ App }) {
|
|
|
86
105
|
release: async (call) => gate.release(call),
|
|
87
106
|
restart: async () => {
|
|
88
107
|
app = new App(router(app.getSnapshot().path), deps);
|
|
108
|
+
},
|
|
109
|
+
tick: async () => {
|
|
110
|
+
app.tick();
|
|
111
|
+
},
|
|
112
|
+
world: async (patch) => {
|
|
113
|
+
Object.assign(Object(world), patch);
|
|
89
114
|
}
|
|
90
115
|
});
|
|
91
116
|
await app.whenIdle();
|
|
@@ -109,7 +134,7 @@ export function defineFlow({ App }) {
|
|
|
109
134
|
test(`${name} [${viewport}]`, async () => {
|
|
110
135
|
const { openFlowPage } = await import("./flowBrowser.js");
|
|
111
136
|
const held = new Set();
|
|
112
|
-
const page = await openFlowPage(visual, viewport, withTestParams(startAt, failing, held), signedInAs, seed, admins);
|
|
137
|
+
const page = await openFlowPage(visual, viewport, withTestParams(startAt, failing, held), signedInAs, seed, admins, startingWorld);
|
|
113
138
|
let stepFailure;
|
|
114
139
|
try {
|
|
115
140
|
await runSteps(name, steps, {
|
|
@@ -124,6 +149,8 @@ export function defineFlow({ App }) {
|
|
|
124
149
|
held.delete(call);
|
|
125
150
|
await page.release(call);
|
|
126
151
|
},
|
|
152
|
+
tick: page.tick,
|
|
153
|
+
world: page.world,
|
|
127
154
|
restart: async () => {
|
|
128
155
|
const snapshot = await page.snapshot();
|
|
129
156
|
const path = typeof snapshot === 'object' && snapshot !== null
|
|
@@ -1,11 +1,12 @@
|
|
|
1
1
|
import type { Toasts } from '../builtins/Toasts.ts';
|
|
2
|
+
import type { AppStore } from '../appInfo.ts';
|
|
2
3
|
import type { AppModels } from '../registered.ts';
|
|
3
4
|
import type { AppProviderOf, UseModel } from './appHooks.ts';
|
|
4
5
|
export type ReactApp = {
|
|
5
|
-
readonly name: string;
|
|
6
6
|
readonly models: AppModels;
|
|
7
7
|
readonly stores: {
|
|
8
8
|
readonly toasts: Toasts;
|
|
9
|
+
readonly app: AppStore;
|
|
9
10
|
};
|
|
10
11
|
pressKey(key: string): Promise<void> | undefined;
|
|
11
12
|
};
|
package/dist/index.d.ts
CHANGED
|
@@ -18,8 +18,12 @@ export { userSchema } from './auth/user.ts';
|
|
|
18
18
|
export type { User } from './auth/user.ts';
|
|
19
19
|
export type { AppClass, AppDefinition, AppDependencies, AppSnapshotShape, DataRouter, ModelServicesOf, NavigateCommand, PressKeyCommand, PublicStores, PlainJsonModel, RunningApp, StoreClasses, StoreInstances, StoresOf, TableStores } from './app.ts';
|
|
20
20
|
export { defineRoutes } from './routes.ts';
|
|
21
|
+
export { ServiceRefused, refused } from './services.ts';
|
|
22
|
+
export type { ServiceClient, ServiceMemory } from './services.ts';
|
|
23
|
+
export { manualClock, realClock } from './clock.ts';
|
|
24
|
+
export type { Clock } from './clock.ts';
|
|
21
25
|
export type { PageOf, PathOf, RouteDefinition } from './routes.ts';
|
|
22
|
-
export { Model, action, appPath, defineActions } from './registered.ts';
|
|
26
|
+
export { Model, Store, action, appPath, defineActions } from './registered.ts';
|
|
23
27
|
export type { ActionContext, AppAction, AppActionGroup, AppCommand, AppModels, AppPage, AppPath, AppSnapshot, AppStores, ModelServices, Register } from './registered.ts';
|
|
24
28
|
export { Cache, Cached } from './cache.ts';
|
|
25
29
|
export type { CacheStorage } from './cache.ts';
|
|
@@ -28,7 +32,7 @@ export type { Entity, EntityApi, EntityCall, EntityDeps, EntitySnapshot, Pending
|
|
|
28
32
|
export { Gate } from './gate.ts';
|
|
29
33
|
export { MemoryEntityApi, MemoryServer } from './memoryApi.ts';
|
|
30
34
|
export type { MemoryApiOptions } from './memoryApi.ts';
|
|
31
|
-
export {
|
|
35
|
+
export { StoreBase, keepEqualParts, snapshotsOf } from './store.ts';
|
|
32
36
|
export type { Snapshots, StoreClass, StoreConfig } from './store.ts';
|
|
33
37
|
export type { Json, Persisted, StateOf, StateSpec } from './state.ts';
|
|
34
38
|
export { defineTables } from './table.ts';
|
package/dist/index.js
CHANGED
|
@@ -8,12 +8,14 @@ export { SessionStore } from "./auth/sessionStore.js";
|
|
|
8
8
|
export { HttpSessionApi, MemorySessionApi } from "./auth/sessionApi.js";
|
|
9
9
|
export { userSchema } from "./auth/user.js";
|
|
10
10
|
export { defineRoutes } from "./routes.js";
|
|
11
|
-
export {
|
|
11
|
+
export { ServiceRefused, refused } from "./services.js";
|
|
12
|
+
export { manualClock, realClock } from "./clock.js";
|
|
13
|
+
export { Model, Store, action, appPath, defineActions } from "./registered.js";
|
|
12
14
|
export { Cache, Cached } from "./cache.js";
|
|
13
15
|
export { EntityStore, WriteRefused, entityCalls } from "./entityStore.js";
|
|
14
16
|
export { Gate } from "./gate.js";
|
|
15
17
|
export { MemoryEntityApi, MemoryServer } from "./memoryApi.js";
|
|
16
|
-
export {
|
|
18
|
+
export { StoreBase, keepEqualParts, snapshotsOf } from "./store.js";
|
|
17
19
|
export { defineTables } from "./table.js";
|
|
18
20
|
export { HttpTableApi, MemoryTableApi, PublicTableStore, TableStore, httpTables, memoryTables, publicStoreName, tableCalls } from "./tables.js";
|
|
19
21
|
export { ModelBase, command, commandsOf, createModels, modelSnapshotsOf, parseMessage, sendMessage, splitType } from "./model.js";
|
|
@@ -0,0 +1,271 @@
|
|
|
1
|
+
import { z } from 'zod';
|
|
2
|
+
import { appTitle } from './appTitle.ts';
|
|
3
|
+
export { appTitle };
|
|
4
|
+
export declare const DASHBOARD_URL = "https://onpattern.app";
|
|
5
|
+
export declare const APPS_DOMAIN = "onpattern.app";
|
|
6
|
+
export declare const UPLOAD_LIMIT_BYTES: number;
|
|
7
|
+
export declare const UPLOAD_LIMIT_PARTS = 5000;
|
|
8
|
+
export declare function nameProblem(name: string): string | undefined;
|
|
9
|
+
export declare const appName: z.ZodString;
|
|
10
|
+
export declare function hostnameOf(name: string): string;
|
|
11
|
+
export declare function isPrivatePath(path: string): boolean;
|
|
12
|
+
export declare function sourcePathProblem(path: string): string | undefined;
|
|
13
|
+
export declare const UPLOAD: {
|
|
14
|
+
readonly worker: "worker/";
|
|
15
|
+
readonly client: "client/";
|
|
16
|
+
readonly migrations: "migrations/";
|
|
17
|
+
readonly source: "source/";
|
|
18
|
+
readonly compatibilityDate: "compatibilityDate";
|
|
19
|
+
readonly sdkVersion: "sdkVersion";
|
|
20
|
+
};
|
|
21
|
+
export declare const publishStep: z.ZodEnum<{
|
|
22
|
+
publish: "publish";
|
|
23
|
+
reserve: "reserve";
|
|
24
|
+
database: "database";
|
|
25
|
+
"sign-in": "sign-in";
|
|
26
|
+
}>;
|
|
27
|
+
export type PublishStep = z.output<typeof publishStep>;
|
|
28
|
+
export declare const publishStatus: z.ZodEnum<{
|
|
29
|
+
failed: "failed";
|
|
30
|
+
running: "running";
|
|
31
|
+
live: "live";
|
|
32
|
+
}>;
|
|
33
|
+
export declare const publishSummary: z.ZodObject<{
|
|
34
|
+
number: z.ZodNumber;
|
|
35
|
+
status: z.ZodEnum<{
|
|
36
|
+
failed: "failed";
|
|
37
|
+
running: "running";
|
|
38
|
+
live: "live";
|
|
39
|
+
}>;
|
|
40
|
+
step: z.ZodEnum<{
|
|
41
|
+
publish: "publish";
|
|
42
|
+
reserve: "reserve";
|
|
43
|
+
database: "database";
|
|
44
|
+
"sign-in": "sign-in";
|
|
45
|
+
}>;
|
|
46
|
+
error: z.ZodNullable<z.ZodString>;
|
|
47
|
+
byEmail: z.ZodString;
|
|
48
|
+
restoredFrom: z.ZodNullable<z.ZodNumber>;
|
|
49
|
+
isStarter: z.ZodBoolean;
|
|
50
|
+
startedAt: z.ZodString;
|
|
51
|
+
finishedAt: z.ZodNullable<z.ZodString>;
|
|
52
|
+
}, z.core.$strip>;
|
|
53
|
+
export type PublishSummary = z.output<typeof publishSummary>;
|
|
54
|
+
export declare const appSummary: z.ZodObject<{
|
|
55
|
+
name: z.ZodString;
|
|
56
|
+
title: z.ZodString;
|
|
57
|
+
url: z.ZodString;
|
|
58
|
+
pulledAt: z.ZodNullable<z.ZodString>;
|
|
59
|
+
latest: z.ZodNullable<z.ZodObject<{
|
|
60
|
+
number: z.ZodNumber;
|
|
61
|
+
status: z.ZodEnum<{
|
|
62
|
+
failed: "failed";
|
|
63
|
+
running: "running";
|
|
64
|
+
live: "live";
|
|
65
|
+
}>;
|
|
66
|
+
step: z.ZodEnum<{
|
|
67
|
+
publish: "publish";
|
|
68
|
+
reserve: "reserve";
|
|
69
|
+
database: "database";
|
|
70
|
+
"sign-in": "sign-in";
|
|
71
|
+
}>;
|
|
72
|
+
error: z.ZodNullable<z.ZodString>;
|
|
73
|
+
byEmail: z.ZodString;
|
|
74
|
+
restoredFrom: z.ZodNullable<z.ZodNumber>;
|
|
75
|
+
isStarter: z.ZodBoolean;
|
|
76
|
+
startedAt: z.ZodString;
|
|
77
|
+
finishedAt: z.ZodNullable<z.ZodString>;
|
|
78
|
+
}, z.core.$strip>>;
|
|
79
|
+
}, z.core.$strip>;
|
|
80
|
+
export type AppSummary = z.output<typeof appSummary>;
|
|
81
|
+
export declare const nameSuggestion: z.ZodObject<{
|
|
82
|
+
name: z.ZodString;
|
|
83
|
+
available: z.ZodBoolean;
|
|
84
|
+
problem: z.ZodNullable<z.ZodString>;
|
|
85
|
+
}, z.core.$strip>;
|
|
86
|
+
export type NameSuggestion = z.output<typeof nameSuggestion>;
|
|
87
|
+
export declare const loginStarted: z.ZodObject<{
|
|
88
|
+
secret: z.ZodString;
|
|
89
|
+
code: z.ZodString;
|
|
90
|
+
url: z.ZodString;
|
|
91
|
+
}, z.core.$strip>;
|
|
92
|
+
export declare const loginPoll: z.ZodUnion<readonly [z.ZodObject<{
|
|
93
|
+
status: z.ZodLiteral<"waiting">;
|
|
94
|
+
}, z.core.$strip>, z.ZodObject<{
|
|
95
|
+
status: z.ZodLiteral<"approved">;
|
|
96
|
+
cookie: z.ZodString;
|
|
97
|
+
}, z.core.$strip>]>;
|
|
98
|
+
export declare const loginToApprove: z.ZodObject<{
|
|
99
|
+
code: z.ZodString;
|
|
100
|
+
label: z.ZodString;
|
|
101
|
+
}, z.core.$strip>;
|
|
102
|
+
export declare const publishServices: {
|
|
103
|
+
readonly apps: {
|
|
104
|
+
readonly list: NoInfer<import("./services.ts").ServiceCall<"/apps", {}, z.ZodArray<z.ZodObject<{
|
|
105
|
+
name: z.ZodString;
|
|
106
|
+
title: z.ZodString;
|
|
107
|
+
url: z.ZodString;
|
|
108
|
+
pulledAt: z.ZodNullable<z.ZodString>;
|
|
109
|
+
latest: z.ZodNullable<z.ZodObject<{
|
|
110
|
+
number: z.ZodNumber;
|
|
111
|
+
status: z.ZodEnum<{
|
|
112
|
+
failed: "failed";
|
|
113
|
+
running: "running";
|
|
114
|
+
live: "live";
|
|
115
|
+
}>;
|
|
116
|
+
step: z.ZodEnum<{
|
|
117
|
+
publish: "publish";
|
|
118
|
+
reserve: "reserve";
|
|
119
|
+
database: "database";
|
|
120
|
+
"sign-in": "sign-in";
|
|
121
|
+
}>;
|
|
122
|
+
error: z.ZodNullable<z.ZodString>;
|
|
123
|
+
byEmail: z.ZodString;
|
|
124
|
+
restoredFrom: z.ZodNullable<z.ZodNumber>;
|
|
125
|
+
isStarter: z.ZodBoolean;
|
|
126
|
+
startedAt: z.ZodString;
|
|
127
|
+
finishedAt: z.ZodNullable<z.ZodString>;
|
|
128
|
+
}, z.core.$strip>>;
|
|
129
|
+
}, z.core.$strip>>>>;
|
|
130
|
+
readonly read: NoInfer<import("./services.ts").ServiceCall<"/apps/:name", {}, z.ZodObject<{
|
|
131
|
+
name: z.ZodString;
|
|
132
|
+
title: z.ZodString;
|
|
133
|
+
url: z.ZodString;
|
|
134
|
+
pulledAt: z.ZodNullable<z.ZodString>;
|
|
135
|
+
latest: z.ZodNullable<z.ZodObject<{
|
|
136
|
+
number: z.ZodNumber;
|
|
137
|
+
status: z.ZodEnum<{
|
|
138
|
+
failed: "failed";
|
|
139
|
+
running: "running";
|
|
140
|
+
live: "live";
|
|
141
|
+
}>;
|
|
142
|
+
step: z.ZodEnum<{
|
|
143
|
+
publish: "publish";
|
|
144
|
+
reserve: "reserve";
|
|
145
|
+
database: "database";
|
|
146
|
+
"sign-in": "sign-in";
|
|
147
|
+
}>;
|
|
148
|
+
error: z.ZodNullable<z.ZodString>;
|
|
149
|
+
byEmail: z.ZodString;
|
|
150
|
+
restoredFrom: z.ZodNullable<z.ZodNumber>;
|
|
151
|
+
isStarter: z.ZodBoolean;
|
|
152
|
+
startedAt: z.ZodString;
|
|
153
|
+
finishedAt: z.ZodNullable<z.ZodString>;
|
|
154
|
+
}, z.core.$strip>>;
|
|
155
|
+
}, z.core.$strip>>>;
|
|
156
|
+
readonly create: NoInfer<import("./services.ts").ServiceCall<"/apps", {
|
|
157
|
+
name: z.ZodString;
|
|
158
|
+
title: z.ZodString;
|
|
159
|
+
}, z.ZodObject<{
|
|
160
|
+
name: z.ZodString;
|
|
161
|
+
title: z.ZodString;
|
|
162
|
+
url: z.ZodString;
|
|
163
|
+
pulledAt: z.ZodNullable<z.ZodString>;
|
|
164
|
+
latest: z.ZodNullable<z.ZodObject<{
|
|
165
|
+
number: z.ZodNumber;
|
|
166
|
+
status: z.ZodEnum<{
|
|
167
|
+
failed: "failed";
|
|
168
|
+
running: "running";
|
|
169
|
+
live: "live";
|
|
170
|
+
}>;
|
|
171
|
+
step: z.ZodEnum<{
|
|
172
|
+
publish: "publish";
|
|
173
|
+
reserve: "reserve";
|
|
174
|
+
database: "database";
|
|
175
|
+
"sign-in": "sign-in";
|
|
176
|
+
}>;
|
|
177
|
+
error: z.ZodNullable<z.ZodString>;
|
|
178
|
+
byEmail: z.ZodString;
|
|
179
|
+
restoredFrom: z.ZodNullable<z.ZodNumber>;
|
|
180
|
+
isStarter: z.ZodBoolean;
|
|
181
|
+
startedAt: z.ZodString;
|
|
182
|
+
finishedAt: z.ZodNullable<z.ZodString>;
|
|
183
|
+
}, z.core.$strip>>;
|
|
184
|
+
}, z.core.$strip>>>;
|
|
185
|
+
};
|
|
186
|
+
readonly names: {
|
|
187
|
+
readonly suggest: NoInfer<import("./services.ts").ServiceCall<"/names", {
|
|
188
|
+
title: z.ZodString;
|
|
189
|
+
}, z.ZodArray<z.ZodObject<{
|
|
190
|
+
name: z.ZodString;
|
|
191
|
+
available: z.ZodBoolean;
|
|
192
|
+
problem: z.ZodNullable<z.ZodString>;
|
|
193
|
+
}, z.core.$strip>>>>;
|
|
194
|
+
readonly check: NoInfer<import("./services.ts").ServiceCall<"/names/:name", {}, z.ZodObject<{
|
|
195
|
+
name: z.ZodString;
|
|
196
|
+
available: z.ZodBoolean;
|
|
197
|
+
problem: z.ZodNullable<z.ZodString>;
|
|
198
|
+
}, z.core.$strip>>>;
|
|
199
|
+
};
|
|
200
|
+
readonly publishes: {
|
|
201
|
+
readonly list: NoInfer<import("./services.ts").ServiceCall<"/apps/:name/publishes", {}, z.ZodArray<z.ZodObject<{
|
|
202
|
+
number: z.ZodNumber;
|
|
203
|
+
status: z.ZodEnum<{
|
|
204
|
+
failed: "failed";
|
|
205
|
+
running: "running";
|
|
206
|
+
live: "live";
|
|
207
|
+
}>;
|
|
208
|
+
step: z.ZodEnum<{
|
|
209
|
+
publish: "publish";
|
|
210
|
+
reserve: "reserve";
|
|
211
|
+
database: "database";
|
|
212
|
+
"sign-in": "sign-in";
|
|
213
|
+
}>;
|
|
214
|
+
error: z.ZodNullable<z.ZodString>;
|
|
215
|
+
byEmail: z.ZodString;
|
|
216
|
+
restoredFrom: z.ZodNullable<z.ZodNumber>;
|
|
217
|
+
isStarter: z.ZodBoolean;
|
|
218
|
+
startedAt: z.ZodString;
|
|
219
|
+
finishedAt: z.ZodNullable<z.ZodString>;
|
|
220
|
+
}, z.core.$strip>>>>;
|
|
221
|
+
readonly read: NoInfer<import("./services.ts").ServiceCall<"/apps/:name/publishes/:number", {}, z.ZodObject<{
|
|
222
|
+
number: z.ZodNumber;
|
|
223
|
+
status: z.ZodEnum<{
|
|
224
|
+
failed: "failed";
|
|
225
|
+
running: "running";
|
|
226
|
+
live: "live";
|
|
227
|
+
}>;
|
|
228
|
+
step: z.ZodEnum<{
|
|
229
|
+
publish: "publish";
|
|
230
|
+
reserve: "reserve";
|
|
231
|
+
database: "database";
|
|
232
|
+
"sign-in": "sign-in";
|
|
233
|
+
}>;
|
|
234
|
+
error: z.ZodNullable<z.ZodString>;
|
|
235
|
+
byEmail: z.ZodString;
|
|
236
|
+
restoredFrom: z.ZodNullable<z.ZodNumber>;
|
|
237
|
+
isStarter: z.ZodBoolean;
|
|
238
|
+
startedAt: z.ZodString;
|
|
239
|
+
finishedAt: z.ZodNullable<z.ZodString>;
|
|
240
|
+
}, z.core.$strip>>>;
|
|
241
|
+
readonly retry: NoInfer<import("./services.ts").ServiceCall<"/apps/:name/publishes/:number/retry", {}, z.ZodObject<{
|
|
242
|
+
number: z.ZodNumber;
|
|
243
|
+
status: z.ZodEnum<{
|
|
244
|
+
failed: "failed";
|
|
245
|
+
running: "running";
|
|
246
|
+
live: "live";
|
|
247
|
+
}>;
|
|
248
|
+
step: z.ZodEnum<{
|
|
249
|
+
publish: "publish";
|
|
250
|
+
reserve: "reserve";
|
|
251
|
+
database: "database";
|
|
252
|
+
"sign-in": "sign-in";
|
|
253
|
+
}>;
|
|
254
|
+
error: z.ZodNullable<z.ZodString>;
|
|
255
|
+
byEmail: z.ZodString;
|
|
256
|
+
restoredFrom: z.ZodNullable<z.ZodNumber>;
|
|
257
|
+
isStarter: z.ZodBoolean;
|
|
258
|
+
startedAt: z.ZodString;
|
|
259
|
+
finishedAt: z.ZodNullable<z.ZodString>;
|
|
260
|
+
}, z.core.$strip>>>;
|
|
261
|
+
};
|
|
262
|
+
readonly logins: {
|
|
263
|
+
readonly read: NoInfer<import("./services.ts").ServiceCall<"/cli/logins/:approval", {}, z.ZodObject<{
|
|
264
|
+
code: z.ZodString;
|
|
265
|
+
label: z.ZodString;
|
|
266
|
+
}, z.core.$strip>>>;
|
|
267
|
+
readonly approve: NoInfer<import("./services.ts").ServiceCall<"/cli/logins/:approval/approve", {}, z.ZodObject<{
|
|
268
|
+
ok: z.ZodBoolean;
|
|
269
|
+
}, z.core.$strip>>>;
|
|
270
|
+
};
|
|
271
|
+
};
|
|
@@ -0,0 +1,168 @@
|
|
|
1
|
+
import { z } from 'zod';
|
|
2
|
+
import { appTitle } from "./appTitle.js";
|
|
3
|
+
export { appTitle };
|
|
4
|
+
import { call, defineServices } from "./services.js";
|
|
5
|
+
export const DASHBOARD_URL = 'https://onpattern.app';
|
|
6
|
+
export const APPS_DOMAIN = 'onpattern.app';
|
|
7
|
+
export const UPLOAD_LIMIT_BYTES = 50 * 1024 * 1024;
|
|
8
|
+
export const UPLOAD_LIMIT_PARTS = 5000;
|
|
9
|
+
const RESERVED_NAMES = new Set([
|
|
10
|
+
'auth',
|
|
11
|
+
'www',
|
|
12
|
+
'api',
|
|
13
|
+
'admin',
|
|
14
|
+
'app',
|
|
15
|
+
'apps',
|
|
16
|
+
'dashboard',
|
|
17
|
+
'deploy',
|
|
18
|
+
'publish',
|
|
19
|
+
'onpattern',
|
|
20
|
+
'trypattern',
|
|
21
|
+
'mail',
|
|
22
|
+
'login',
|
|
23
|
+
'help',
|
|
24
|
+
'docs',
|
|
25
|
+
'status',
|
|
26
|
+
'support',
|
|
27
|
+
'blog',
|
|
28
|
+
'dev',
|
|
29
|
+
'test',
|
|
30
|
+
'staging',
|
|
31
|
+
'cdn',
|
|
32
|
+
'static',
|
|
33
|
+
'assets',
|
|
34
|
+
'dispatch',
|
|
35
|
+
'start',
|
|
36
|
+
'approve'
|
|
37
|
+
]);
|
|
38
|
+
export function nameProblem(name) {
|
|
39
|
+
if (!/^[a-z][a-z0-9-]{1,28}[a-z0-9]$/.test(name)) {
|
|
40
|
+
return 'Use 3 to 30 lowercase letters, numbers and hyphens, starting with a letter.';
|
|
41
|
+
}
|
|
42
|
+
if (name.includes('--'))
|
|
43
|
+
return 'Use one hyphen at a time.';
|
|
44
|
+
if (RESERVED_NAMES.has(name) || name.startsWith('pattern')) {
|
|
45
|
+
return 'That address is reserved.';
|
|
46
|
+
}
|
|
47
|
+
return undefined;
|
|
48
|
+
}
|
|
49
|
+
export const appName = z.string().superRefine((name, context) => {
|
|
50
|
+
const problem = nameProblem(name);
|
|
51
|
+
if (problem !== undefined)
|
|
52
|
+
context.addIssue({ code: 'custom', message: problem });
|
|
53
|
+
});
|
|
54
|
+
export function hostnameOf(name) {
|
|
55
|
+
return `${name}.${APPS_DOMAIN}`;
|
|
56
|
+
}
|
|
57
|
+
const PRIVATE_NAMES = new Set([
|
|
58
|
+
'.git',
|
|
59
|
+
'node_modules',
|
|
60
|
+
'dist',
|
|
61
|
+
'.dev',
|
|
62
|
+
'.wrangler',
|
|
63
|
+
'.dev.vars',
|
|
64
|
+
'.DS_Store'
|
|
65
|
+
]);
|
|
66
|
+
export function isPrivatePath(path) {
|
|
67
|
+
return path.split('/').some((part) => {
|
|
68
|
+
if (PRIVATE_NAMES.has(part))
|
|
69
|
+
return true;
|
|
70
|
+
if (part.startsWith('.env') && part !== '.env.example')
|
|
71
|
+
return true;
|
|
72
|
+
return part.endsWith('.local') || part.endsWith('.log');
|
|
73
|
+
});
|
|
74
|
+
}
|
|
75
|
+
export function sourcePathProblem(path) {
|
|
76
|
+
if (path === '' || path.startsWith('/') || path.includes('\\')) {
|
|
77
|
+
return `${path} is not a relative path`;
|
|
78
|
+
}
|
|
79
|
+
if (path.split('/').some((part) => part === '' || part === '.' || part === '..')) {
|
|
80
|
+
return `${path} leaves the project`;
|
|
81
|
+
}
|
|
82
|
+
if (isPrivatePath(path))
|
|
83
|
+
return `${path} must never leave the laptop`;
|
|
84
|
+
return undefined;
|
|
85
|
+
}
|
|
86
|
+
export const UPLOAD = {
|
|
87
|
+
worker: 'worker/',
|
|
88
|
+
client: 'client/',
|
|
89
|
+
migrations: 'migrations/',
|
|
90
|
+
source: 'source/',
|
|
91
|
+
compatibilityDate: 'compatibilityDate',
|
|
92
|
+
sdkVersion: 'sdkVersion'
|
|
93
|
+
};
|
|
94
|
+
export const publishStep = z.enum(['reserve', 'database', 'sign-in', 'publish']);
|
|
95
|
+
export const publishStatus = z.enum(['running', 'live', 'failed']);
|
|
96
|
+
export const publishSummary = z.object({
|
|
97
|
+
number: z.number(),
|
|
98
|
+
status: publishStatus,
|
|
99
|
+
step: publishStep,
|
|
100
|
+
error: z.string().nullable(),
|
|
101
|
+
byEmail: z.string(),
|
|
102
|
+
restoredFrom: z.number().nullable(),
|
|
103
|
+
isStarter: z.boolean(),
|
|
104
|
+
startedAt: z.string(),
|
|
105
|
+
finishedAt: z.string().nullable()
|
|
106
|
+
});
|
|
107
|
+
export const appSummary = z.object({
|
|
108
|
+
name: z.string(),
|
|
109
|
+
title: z.string(),
|
|
110
|
+
url: z.string(),
|
|
111
|
+
pulledAt: z.string().nullable(),
|
|
112
|
+
latest: publishSummary.nullable()
|
|
113
|
+
});
|
|
114
|
+
export const nameSuggestion = z.object({
|
|
115
|
+
name: z.string(),
|
|
116
|
+
available: z.boolean(),
|
|
117
|
+
problem: z.string().nullable()
|
|
118
|
+
});
|
|
119
|
+
export const loginStarted = z.object({
|
|
120
|
+
secret: z.string(),
|
|
121
|
+
code: z.string(),
|
|
122
|
+
url: z.string()
|
|
123
|
+
});
|
|
124
|
+
export const loginPoll = z.union([
|
|
125
|
+
z.object({ status: z.literal('waiting') }),
|
|
126
|
+
z.object({ status: z.literal('approved'), cookie: z.string() })
|
|
127
|
+
]);
|
|
128
|
+
export const loginToApprove = z.object({ code: z.string(), label: z.string() });
|
|
129
|
+
export const publishServices = defineServices({
|
|
130
|
+
apps: {
|
|
131
|
+
list: call({ get: '/apps', reply: z.array(appSummary) }),
|
|
132
|
+
read: call({ get: '/apps/:name', reply: appSummary }),
|
|
133
|
+
create: call({
|
|
134
|
+
post: '/apps',
|
|
135
|
+
input: { name: appName, title: appTitle },
|
|
136
|
+
reply: appSummary
|
|
137
|
+
})
|
|
138
|
+
},
|
|
139
|
+
names: {
|
|
140
|
+
suggest: call({
|
|
141
|
+
get: '/names',
|
|
142
|
+
input: { title: z.string() },
|
|
143
|
+
reply: z.array(nameSuggestion)
|
|
144
|
+
}),
|
|
145
|
+
check: call({ get: '/names/:name', reply: nameSuggestion })
|
|
146
|
+
},
|
|
147
|
+
publishes: {
|
|
148
|
+
list: call({
|
|
149
|
+
get: '/apps/:name/publishes',
|
|
150
|
+
reply: z.array(publishSummary)
|
|
151
|
+
}),
|
|
152
|
+
read: call({
|
|
153
|
+
get: '/apps/:name/publishes/:number',
|
|
154
|
+
reply: publishSummary
|
|
155
|
+
}),
|
|
156
|
+
retry: call({
|
|
157
|
+
post: '/apps/:name/publishes/:number/retry',
|
|
158
|
+
reply: publishSummary
|
|
159
|
+
})
|
|
160
|
+
},
|
|
161
|
+
logins: {
|
|
162
|
+
read: call({ get: '/cli/logins/:approval', reply: loginToApprove }),
|
|
163
|
+
approve: call({
|
|
164
|
+
post: '/cli/logins/:approval/approve',
|
|
165
|
+
reply: z.object({ ok: z.boolean() })
|
|
166
|
+
})
|
|
167
|
+
}
|
|
168
|
+
});
|
package/dist/react.d.ts
CHANGED
|
@@ -10,6 +10,7 @@ export { CommandPalette } from './components/CommandPalette.tsx';
|
|
|
10
10
|
export type { CommandMenuItem } from './components/CommandMenu.tsx';
|
|
11
11
|
export { Content } from './components/Content.tsx';
|
|
12
12
|
export { ContextMenu } from './components/ContextMenu.tsx';
|
|
13
|
+
export { CopyButton } from './components/CopyButton.tsx';
|
|
13
14
|
export { Dialog } from './components/Dialog.tsx';
|
|
14
15
|
export { Divider } from './components/Divider.tsx';
|
|
15
16
|
export { EmptyState } from './components/EmptyState.tsx';
|
|
@@ -26,6 +27,8 @@ export type { MenuEntry } from './components/MenuItems.tsx';
|
|
|
26
27
|
export type { SidebarLink } from './components/Sidebar.tsx';
|
|
27
28
|
export type { Placement } from './components/Placement.ts';
|
|
28
29
|
export { PropertyRow } from './components/PropertyRow.tsx';
|
|
30
|
+
export { RadioGroup } from './components/RadioGroup.tsx';
|
|
31
|
+
export type { RadioOption } from './components/RadioGroup.tsx';
|
|
29
32
|
export { Row } from './components/Row.tsx';
|
|
30
33
|
export { Screen } from './components/Screen.tsx';
|
|
31
34
|
export { ScrollArea } from './components/ScrollArea.tsx';
|
package/dist/react.js
CHANGED
|
@@ -9,6 +9,7 @@ export { CommandMenu } from "./components/CommandMenu.js";
|
|
|
9
9
|
export { CommandPalette } from "./components/CommandPalette.js";
|
|
10
10
|
export { Content } from "./components/Content.js";
|
|
11
11
|
export { ContextMenu } from "./components/ContextMenu.js";
|
|
12
|
+
export { CopyButton } from "./components/CopyButton.js";
|
|
12
13
|
export { Dialog } from "./components/Dialog.js";
|
|
13
14
|
export { Divider } from "./components/Divider.js";
|
|
14
15
|
export { EmptyState } from "./components/EmptyState.js";
|
|
@@ -21,6 +22,7 @@ export { ListRow } from "./components/ListRow.js";
|
|
|
21
22
|
export { LoadingRows } from "./components/LoadingRows.js";
|
|
22
23
|
export { Menu } from "./components/Menu.js";
|
|
23
24
|
export { PropertyRow } from "./components/PropertyRow.js";
|
|
25
|
+
export { RadioGroup } from "./components/RadioGroup.js";
|
|
24
26
|
export { Row } from "./components/Row.js";
|
|
25
27
|
export { Screen } from "./components/Screen.js";
|
|
26
28
|
export { ScrollArea } from "./components/ScrollArea.js";
|
package/dist/registered.d.ts
CHANGED
|
@@ -1,9 +1,11 @@
|
|
|
1
1
|
import type { AppSnapshotShape, ModelServicesOf, NavigateCommand, PressKeyCommand, StoreClasses, StoreInstances, StoresOf } from './app.ts';
|
|
2
2
|
import { z } from 'zod';
|
|
3
3
|
import type { Action, DefineActions } from './actions.ts';
|
|
4
|
+
import type { ServiceClient, Services } from './services.ts';
|
|
4
5
|
import type { Instances, MessagesOf, ModelClassLike, ModelSnapshots } from './model.ts';
|
|
5
6
|
import type { BUILT_IN_GROUPS } from './builtins/actions.ts';
|
|
6
7
|
import type { Account } from './builtins/Account.ts';
|
|
8
|
+
import type { AppSettings } from './builtins/AppSettings.ts';
|
|
7
9
|
import type { Palette } from './builtins/Palette.ts';
|
|
8
10
|
import type { SignIn } from './builtins/SignIn.ts';
|
|
9
11
|
import type { IconName } from './components/icons.ts';
|
|
@@ -16,6 +18,8 @@ type Empty = Record<never, never>;
|
|
|
16
18
|
type RegisteredModels = Registered<'models', Empty> extends infer Classes extends Record<string, ModelClassLike> ? Classes : Empty;
|
|
17
19
|
type RegisteredTables = Registered<'tables', Empty> extends infer Group extends Tables ? Group : Empty;
|
|
18
20
|
type RegisteredStores = Registered<'stores', Empty> extends infer Classes extends StoreClasses ? Classes : Empty;
|
|
21
|
+
type RegisteredServices = Registered<'services', Empty> extends infer Group extends Services ? Group : Empty;
|
|
22
|
+
export type AppServices = ServiceClient<RegisteredServices>;
|
|
19
23
|
type RegisteredActionGroups = Registered<'actionGroups', readonly string[]> extends infer Groups extends readonly string[] ? Groups : readonly string[];
|
|
20
24
|
export type AppActionGroup = RegisteredActionGroups[number] | (typeof BUILT_IN_GROUPS)[number];
|
|
21
25
|
export type AppAction = Action & {
|
|
@@ -28,6 +32,7 @@ type RegisteredIcons = Registered<'icons', Empty> extends infer Icons extends Re
|
|
|
28
32
|
export type AppIconName = keyof RegisteredIcons & string;
|
|
29
33
|
export type BuiltInModels = {
|
|
30
34
|
account: typeof Account;
|
|
35
|
+
appSettings: typeof AppSettings;
|
|
31
36
|
palette: typeof Palette;
|
|
32
37
|
signIn: typeof SignIn;
|
|
33
38
|
};
|
|
@@ -43,6 +48,7 @@ export type ActionContext = {
|
|
|
43
48
|
};
|
|
44
49
|
export type ModelServices = ModelServicesOf<AppPath>;
|
|
45
50
|
export declare const Model: <S extends import("./state.ts").StateSpec = Record<never, never>, const P extends readonly (keyof S & string)[] = []>(config?: import("./model.ts").ModelConfig<S, P>) => import("./model.ts").ModelClass<AppStores, ModelServices, S, P>;
|
|
51
|
+
export declare const Store: <S extends import("./state.ts").StateSpec = Record<never, never>, const P extends readonly (keyof S & string)[] = []>(config: import("./store.ts").StoreConfig<S, P>) => import("./store.ts").StoreClass<S, P, ServiceClient<Empty>>;
|
|
46
52
|
export declare const defineActions: DefineActions<ActionContext, RegisteredAction, AppCommand>;
|
|
47
53
|
export declare const appPath: z.ZodCustom<AppPath, AppPath>;
|
|
48
54
|
type ActionInput = Pick<AppAction, 'id' | 'label' | 'group' | 'icon'> & Partial<Pick<AppAction, 'keys' | 'keywords' | 'isDanger' | 'isSearchOnly' | 'isHidden'>> & {
|
package/dist/registered.js
CHANGED
|
@@ -1,8 +1,10 @@
|
|
|
1
1
|
import { z } from 'zod';
|
|
2
2
|
import { bindActions } from "./actions.js";
|
|
3
3
|
import { defineModel } from "./model.js";
|
|
4
|
+
import { defineStore } from "./store.js";
|
|
4
5
|
import { isRoutedPath } from "./routes.js";
|
|
5
6
|
export const Model = defineModel();
|
|
7
|
+
export const Store = defineStore();
|
|
6
8
|
export const defineActions = bindActions();
|
|
7
9
|
export const appPath = z.custom((value) => typeof value === 'string' && isRoutedPath(value), { error: 'Not a page in src/routes.tsx' });
|
|
8
10
|
export function action(input) {
|