@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/cli/app.js
CHANGED
|
@@ -14,6 +14,7 @@ import { delimiter, dirname, extname, join, relative, resolve } from 'node:path'
|
|
|
14
14
|
import { pathToFileURL } from 'node:url';
|
|
15
15
|
import { createHash } from 'node:crypto';
|
|
16
16
|
import { resetLocalDatabase } from "../vite/localWorker.js";
|
|
17
|
+
import { login, publish, pull, restore, versions as listVersions } from "./publishing.js";
|
|
17
18
|
import { toolBin } from "./tools.js";
|
|
18
19
|
function dependsOnPattern(directory) {
|
|
19
20
|
try {
|
|
@@ -36,15 +37,14 @@ function findRoot() {
|
|
|
36
37
|
let directory = process.cwd();
|
|
37
38
|
while (!dependsOnPattern(directory)) {
|
|
38
39
|
const parent = dirname(directory);
|
|
39
|
-
if (parent === directory)
|
|
40
|
-
|
|
41
|
-
process.exit(2);
|
|
42
|
-
}
|
|
40
|
+
if (parent === directory)
|
|
41
|
+
return undefined;
|
|
43
42
|
directory = parent;
|
|
44
43
|
}
|
|
45
44
|
return directory;
|
|
46
45
|
}
|
|
47
|
-
const
|
|
46
|
+
const FOUND_ROOT = findRoot();
|
|
47
|
+
const ROOT = FOUND_ROOT ?? process.cwd();
|
|
48
48
|
const SDK_SOURCE = resolve(import.meta.dirname, '..');
|
|
49
49
|
const SDK_EXTENSION = extname(import.meta.filename);
|
|
50
50
|
const FORMATTED_PATHS = [
|
|
@@ -182,7 +182,7 @@ Works while the dev server runs; reload the page to see the new rows.`,
|
|
|
182
182
|
migration: {
|
|
183
183
|
summary: 'Write a database migration for the tables in schema.ts',
|
|
184
184
|
details: `app migration add_due_dates
|
|
185
|
-
Compares the tables in schema.ts (plus Pattern's users and
|
|
185
|
+
Compares the tables in schema.ts (plus Pattern's users, sessions and settings tables) with server/migrations and writes the
|
|
186
186
|
SQL that moves the database from one to the other, named <number>_<name>.sql. app start applies new
|
|
187
187
|
migrations to the local database. Prints "No schema changes" when the migrations already match.`,
|
|
188
188
|
run: migration,
|
|
@@ -252,9 +252,52 @@ dev server (app check proves the production build has none). Sign out with app s
|
|
|
252
252
|
})),
|
|
253
253
|
takesArgument: true
|
|
254
254
|
},
|
|
255
|
+
login: {
|
|
256
|
+
summary: 'Let this computer publish: approve it once in the browser',
|
|
257
|
+
details: `Opens onpattern.app in the browser with a short code (like FOX-7421) and prints the same
|
|
258
|
+
code. The person checks the codes match and clicks Allow; run app login again and it finishes.
|
|
259
|
+
The session lasts 30 days and lives in ~/.config/pattern/credentials.json. pull, publish, versions
|
|
260
|
+
and restore sign in the same way when they need to, so this is rarely run on its own.`,
|
|
261
|
+
run: () => login(publishingIo()),
|
|
262
|
+
runsAnywhere: true
|
|
263
|
+
},
|
|
264
|
+
pull: {
|
|
265
|
+
summary: 'Download a site from onpattern.app and install it, ready for app start',
|
|
266
|
+
details: `app pull sundayparty
|
|
267
|
+
Downloads the source of the site's latest live version into this folder when it is empty, or into
|
|
268
|
+
./<name> otherwise, writes pattern.json, installs, and runs app setup. Never needs git; when the
|
|
269
|
+
Command Line Tools are installed it also makes a first commit. Signs in first if needed (see app login).`,
|
|
270
|
+
run: (argument) => pull(publishingIo(), argument, process.cwd()),
|
|
271
|
+
takesArgument: true,
|
|
272
|
+
runsAnywhere: true
|
|
273
|
+
},
|
|
274
|
+
publish: {
|
|
275
|
+
summary: 'Build this app and put it live at <name>.onpattern.app',
|
|
276
|
+
details: `Builds (vite build), then uploads the build, server/migrations and the source (every file
|
|
277
|
+
git would keep, never .dev.vars, .env, node_modules, dist or .dev) to onpattern.app, and waits
|
|
278
|
+
until the new version answers at https://<name>.onpattern.app, printing each step. The database
|
|
279
|
+
moves forward with any new migrations; nothing is ever deleted from it. If a step fails, the site
|
|
280
|
+
keeps running the previous version and the error says why. Run app check first.
|
|
281
|
+
--starter (Pattern's admins only) publishes this project as the starter every new site begins from.`,
|
|
282
|
+
run: (_argument, options) => publish(publishingIo(), ROOT, options.has('--starter')),
|
|
283
|
+
flags: ['--starter']
|
|
284
|
+
},
|
|
285
|
+
versions: {
|
|
286
|
+
summary: 'List the versions that went live, newest first',
|
|
287
|
+
details: 'Each version with its number, whether it went live, when, and who published it. app restore <number> puts one back.',
|
|
288
|
+
run: () => listVersions(publishingIo(), ROOT)
|
|
289
|
+
},
|
|
290
|
+
restore: {
|
|
291
|
+
summary: 'Put an earlier version back live (app restore <number>)',
|
|
292
|
+
details: `app restore 3
|
|
293
|
+
Publishes version 3's build again as a new version. The database is not rolled back: it keeps
|
|
294
|
+
every row and column added since, which version 3's code ignores.`,
|
|
295
|
+
run: (argument) => restore(publishingIo(), ROOT, argument),
|
|
296
|
+
takesArgument: true
|
|
297
|
+
},
|
|
255
298
|
setup: {
|
|
256
|
-
summary: 'Verify Node/pnpm
|
|
257
|
-
details: `Idempotent. Fails
|
|
299
|
+
summary: 'Verify Node/pnpm major versions, pnpm install, install the global `app` shim',
|
|
300
|
+
details: `Idempotent. Fails unless Node and pnpm have the major versions in .nvmrc and package.json "packageManager".
|
|
258
301
|
Then runs \`pnpm install\` and installs ${SHIM_PATH}, a tiny shim that walks up from the
|
|
259
302
|
current directory to the nearest project launcher (an executable ./app containing the line
|
|
260
303
|
${LAUNCHER_MARKER_LINE}) and runs it, so each project's CLI lives in its repo and the shim
|
|
@@ -270,6 +313,29 @@ existing ${SHIM_PATH} that was not installed by Pattern.`,
|
|
|
270
313
|
};
|
|
271
314
|
let jsonMode = false;
|
|
272
315
|
let openBrowser = false;
|
|
316
|
+
function sdkVersion() {
|
|
317
|
+
const manifest = JSON.parse(readText(resolve(SDK_SOURCE, '..', 'package.json')));
|
|
318
|
+
return String(Reflect.get(Object(manifest), 'version') ?? '');
|
|
319
|
+
}
|
|
320
|
+
function publishingIo() {
|
|
321
|
+
return {
|
|
322
|
+
say,
|
|
323
|
+
openUrl,
|
|
324
|
+
build,
|
|
325
|
+
sdkVersion: sdkVersion(),
|
|
326
|
+
run: (bin, args, cwd) => new Promise((done) => {
|
|
327
|
+
let output = '';
|
|
328
|
+
const child = spawn(bin, args, {
|
|
329
|
+
cwd,
|
|
330
|
+
stdio: ['ignore', 'pipe', 'pipe']
|
|
331
|
+
});
|
|
332
|
+
child.stdout.on('data', (chunk) => (output += chunk.toString()));
|
|
333
|
+
child.stderr.on('data', (chunk) => (output += chunk.toString()));
|
|
334
|
+
child.on('error', (err) => done({ code: 127, output: `failed to run ${bin}: ${err.message}` }));
|
|
335
|
+
child.on('close', (code) => done({ code: code ?? 1, output }));
|
|
336
|
+
})
|
|
337
|
+
};
|
|
338
|
+
}
|
|
273
339
|
function progressStream() {
|
|
274
340
|
return jsonMode ? process.stderr : process.stdout;
|
|
275
341
|
}
|
|
@@ -1059,10 +1125,11 @@ async function writeDatabaseSchema() {
|
|
|
1059
1125
|
writeFileSync(file, [
|
|
1060
1126
|
`import { sqlTable } from ${JSON.stringify(join(server, `tables${SDK_EXTENSION}`))}`,
|
|
1061
1127
|
`import { sessions } from ${JSON.stringify(join(server, `sessions${SDK_EXTENSION}`))}`,
|
|
1128
|
+
`import { settings } from ${JSON.stringify(join(server, `settings${SDK_EXTENSION}`))}`,
|
|
1062
1129
|
`import { users } from ${JSON.stringify(join(server, `users${SDK_EXTENSION}`))}`,
|
|
1063
1130
|
`import { tables } from ${JSON.stringify(join(ROOT, 'schema.ts'))}`,
|
|
1064
1131
|
'',
|
|
1065
|
-
'export { sessions, users }',
|
|
1132
|
+
'export { sessions, settings, users }',
|
|
1066
1133
|
...keys.map((key) => `export const ${key} = sqlTable(tables[${JSON.stringify(key)}])`),
|
|
1067
1134
|
''
|
|
1068
1135
|
].join('\n'));
|
|
@@ -1147,6 +1214,9 @@ async function build() {
|
|
|
1147
1214
|
: `✗ Build failed\n\n${indent(output.trimEnd())}`
|
|
1148
1215
|
};
|
|
1149
1216
|
}
|
|
1217
|
+
function majorOf(version) {
|
|
1218
|
+
return version.split('.')[0] ?? '';
|
|
1219
|
+
}
|
|
1150
1220
|
function readPins() {
|
|
1151
1221
|
const node = readText(join(ROOT, '.nvmrc')).trim().replace(/^v/, '');
|
|
1152
1222
|
const pkg = JSON.parse(readText(join(ROOT, 'package.json')));
|
|
@@ -1186,11 +1256,11 @@ async function setup() {
|
|
|
1186
1256
|
});
|
|
1187
1257
|
const havePnpm = (pnpmVersion.stdout ?? '').trim();
|
|
1188
1258
|
const problems = [];
|
|
1189
|
-
if (haveNode !== pins.node) {
|
|
1190
|
-
problems.push(`Node ${haveNode}
|
|
1259
|
+
if (majorOf(haveNode) !== majorOf(pins.node)) {
|
|
1260
|
+
problems.push(`Node ${haveNode} is not Node ${majorOf(pins.node)} (.nvmrc says ${pins.node})\n fix pnpm env use --global ${majorOf(pins.node)}`);
|
|
1191
1261
|
}
|
|
1192
|
-
if (havePnpm !== pins.pnpm) {
|
|
1193
|
-
problems.push(`pnpm ${havePnpm || '(not found)'}
|
|
1262
|
+
if (majorOf(havePnpm) !== majorOf(pins.pnpm)) {
|
|
1263
|
+
problems.push(`pnpm ${havePnpm || '(not found)'} is not pnpm ${majorOf(pins.pnpm)} (package.json packageManager says ${pins.pnpm})\n fix curl -fsSL https://get.pnpm.io/install.sh | sh -`);
|
|
1194
1264
|
}
|
|
1195
1265
|
const versions = { node: haveNode, pnpm: havePnpm, expected: pins };
|
|
1196
1266
|
if (problems.length > 0) {
|
|
@@ -1200,7 +1270,7 @@ async function setup() {
|
|
|
1200
1270
|
text: problems.map((p) => `✗ ${p}`).join('\n')
|
|
1201
1271
|
};
|
|
1202
1272
|
}
|
|
1203
|
-
say(`✓ Node ${haveNode} and pnpm ${havePnpm} match the
|
|
1273
|
+
say(`✓ Node ${haveNode} and pnpm ${havePnpm} match the pinned major versions`);
|
|
1204
1274
|
const install = await capture('pnpm', ['install']);
|
|
1205
1275
|
if (install.code !== 0) {
|
|
1206
1276
|
return {
|
|
@@ -1301,6 +1371,13 @@ async function main(argv) {
|
|
|
1301
1371
|
text: `app: ${problem}\n${usage.text}`
|
|
1302
1372
|
};
|
|
1303
1373
|
}
|
|
1374
|
+
else if (FOUND_ROOT === undefined && command.runsAnywhere !== true) {
|
|
1375
|
+
outcome = {
|
|
1376
|
+
code: 2,
|
|
1377
|
+
data: { error: 'no Pattern project here' },
|
|
1378
|
+
text: 'app: no Pattern project here. Run app inside a project that depends on @trypattern/sdk, or app pull <name> to download one.'
|
|
1379
|
+
};
|
|
1380
|
+
}
|
|
1304
1381
|
else if (wantsHelp) {
|
|
1305
1382
|
outcome = {
|
|
1306
1383
|
code: 0,
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
type Outcome = {
|
|
2
|
+
code: number;
|
|
3
|
+
data: Record<string, unknown>;
|
|
4
|
+
text: string;
|
|
5
|
+
};
|
|
6
|
+
export type PublishingIo = {
|
|
7
|
+
say: (line: string) => void;
|
|
8
|
+
openUrl: (url: string) => void;
|
|
9
|
+
run: (bin: string, args: readonly string[], cwd: string) => Promise<{
|
|
10
|
+
code: number;
|
|
11
|
+
output: string;
|
|
12
|
+
}>;
|
|
13
|
+
build: () => Promise<Outcome>;
|
|
14
|
+
sdkVersion: string;
|
|
15
|
+
};
|
|
16
|
+
export declare function login(io: PublishingIo): Promise<Outcome>;
|
|
17
|
+
export declare function pull(io: PublishingIo, name: string | undefined, cwd: string): Promise<Outcome>;
|
|
18
|
+
export declare function publish(io: PublishingIo, root: string, isStarter: boolean): Promise<Outcome>;
|
|
19
|
+
export declare function versions(io: PublishingIo, root: string): Promise<Outcome>;
|
|
20
|
+
export declare function restore(io: PublishingIo, root: string, number: string | undefined): Promise<Outcome>;
|
|
21
|
+
export {};
|