@byline/cli 0.1.1
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/LICENSE +373 -0
- package/README.md +23 -0
- package/dist/cli.d.ts +3 -0
- package/dist/cli.d.ts.map +1 -0
- package/dist/cli.js +72 -0
- package/dist/cli.js.map +1 -0
- package/dist/commands/doctor.d.ts +2 -0
- package/dist/commands/doctor.d.ts.map +1 -0
- package/dist/commands/doctor.js +36 -0
- package/dist/commands/doctor.js.map +1 -0
- package/dist/commands/init.d.ts +16 -0
- package/dist/commands/init.d.ts.map +1 -0
- package/dist/commands/init.js +76 -0
- package/dist/commands/init.js.map +1 -0
- package/dist/context.d.ts +38 -0
- package/dist/context.d.ts.map +1 -0
- package/dist/context.js +37 -0
- package/dist/context.js.map +1 -0
- package/dist/index.d.ts +5 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +4 -0
- package/dist/index.js.map +1 -0
- package/dist/lib/pg-url.d.ts +11 -0
- package/dist/lib/pg-url.d.ts.map +1 -0
- package/dist/lib/pg-url.js +22 -0
- package/dist/lib/pg-url.js.map +1 -0
- package/dist/manifest/deps.d.ts +29 -0
- package/dist/manifest/deps.d.ts.map +1 -0
- package/dist/manifest/deps.js +97 -0
- package/dist/manifest/deps.js.map +1 -0
- package/dist/manifest/env.d.ts +18 -0
- package/dist/manifest/env.d.ts.map +1 -0
- package/dist/manifest/env.js +38 -0
- package/dist/manifest/env.js.map +1 -0
- package/dist/phases/db-init.d.ts +3 -0
- package/dist/phases/db-init.d.ts.map +1 -0
- package/dist/phases/db-init.js +163 -0
- package/dist/phases/db-init.js.map +1 -0
- package/dist/phases/db.d.ts +11 -0
- package/dist/phases/db.d.ts.map +1 -0
- package/dist/phases/db.js +93 -0
- package/dist/phases/db.js.map +1 -0
- package/dist/phases/deps.d.ts +3 -0
- package/dist/phases/deps.d.ts.map +1 -0
- package/dist/phases/deps.js +115 -0
- package/dist/phases/deps.js.map +1 -0
- package/dist/phases/env.d.ts +3 -0
- package/dist/phases/env.d.ts.map +1 -0
- package/dist/phases/env.js +172 -0
- package/dist/phases/env.js.map +1 -0
- package/dist/phases/host.d.ts +3 -0
- package/dist/phases/host.d.ts.map +1 -0
- package/dist/phases/host.js +99 -0
- package/dist/phases/host.js.map +1 -0
- package/dist/phases/index.d.ts +7 -0
- package/dist/phases/index.d.ts.map +1 -0
- package/dist/phases/index.js +40 -0
- package/dist/phases/index.js.map +1 -0
- package/dist/phases/preflight.d.ts +4 -0
- package/dist/phases/preflight.d.ts.map +1 -0
- package/dist/phases/preflight.js +81 -0
- package/dist/phases/preflight.js.map +1 -0
- package/dist/phases/routes.d.ts +3 -0
- package/dist/phases/routes.d.ts.map +1 -0
- package/dist/phases/routes.js +145 -0
- package/dist/phases/routes.js.map +1 -0
- package/dist/phases/scaffold.d.ts +3 -0
- package/dist/phases/scaffold.d.ts.map +1 -0
- package/dist/phases/scaffold.js +113 -0
- package/dist/phases/scaffold.js.map +1 -0
- package/dist/phases/stub.d.ts +3 -0
- package/dist/phases/stub.d.ts.map +1 -0
- package/dist/phases/stub.js +25 -0
- package/dist/phases/stub.js.map +1 -0
- package/dist/phases/ui.d.ts +3 -0
- package/dist/phases/ui.d.ts.map +1 -0
- package/dist/phases/ui.js +93 -0
- package/dist/phases/ui.js.map +1 -0
- package/dist/phases/wire/index.d.ts +3 -0
- package/dist/phases/wire/index.d.ts.map +1 -0
- package/dist/phases/wire/index.js +67 -0
- package/dist/phases/wire/index.js.map +1 -0
- package/dist/phases/wire/root-tsx.d.ts +3 -0
- package/dist/phases/wire/root-tsx.d.ts.map +1 -0
- package/dist/phases/wire/root-tsx.js +57 -0
- package/dist/phases/wire/root-tsx.js.map +1 -0
- package/dist/phases/wire/server-ts.d.ts +3 -0
- package/dist/phases/wire/server-ts.d.ts.map +1 -0
- package/dist/phases/wire/server-ts.js +54 -0
- package/dist/phases/wire/server-ts.js.map +1 -0
- package/dist/phases/wire/shared.d.ts +34 -0
- package/dist/phases/wire/shared.d.ts.map +1 -0
- package/dist/phases/wire/shared.js +2 -0
- package/dist/phases/wire/shared.js.map +1 -0
- package/dist/phases/wire/start-ts.d.ts +3 -0
- package/dist/phases/wire/start-ts.d.ts.map +1 -0
- package/dist/phases/wire/start-ts.js +149 -0
- package/dist/phases/wire/start-ts.js.map +1 -0
- package/dist/phases/wire/tsconfig.d.ts +3 -0
- package/dist/phases/wire/tsconfig.d.ts.map +1 -0
- package/dist/phases/wire/tsconfig.js +105 -0
- package/dist/phases/wire/tsconfig.js.map +1 -0
- package/dist/phases/wire/vite-config.d.ts +3 -0
- package/dist/phases/wire/vite-config.d.ts.map +1 -0
- package/dist/phases/wire/vite-config.js +46 -0
- package/dist/phases/wire/vite-config.js.map +1 -0
- package/dist/prompts.d.ts +34 -0
- package/dist/prompts.d.ts.map +1 -0
- package/dist/prompts.js +49 -0
- package/dist/prompts.js.map +1 -0
- package/dist/runner.d.ts +5 -0
- package/dist/runner.d.ts.map +1 -0
- package/dist/runner.js +91 -0
- package/dist/runner.js.map +1 -0
- package/dist/state.d.ts +18 -0
- package/dist/state.d.ts.map +1 -0
- package/dist/state.js +68 -0
- package/dist/state.js.map +1 -0
- package/dist/templates/byline/admin.config.ts +41 -0
- package/dist/templates/byline/i18n.ts +47 -0
- package/dist/templates/byline/routes.ts +28 -0
- package/dist/templates/byline/seed.ts +19 -0
- package/dist/templates/byline/seeds/admin.ts +62 -0
- package/dist/templates/byline/server.config.ts +92 -0
- package/dist/templates/byline-examples/admin.config.ts +74 -0
- package/dist/templates/byline-examples/blocks/photo-block.ts +59 -0
- package/dist/templates/byline-examples/blocks/richtext-block.ts +35 -0
- package/dist/templates/byline-examples/collections/doc-example-flat-locale-all.ts +373 -0
- package/dist/templates/byline-examples/collections/doc-example-flat-locale-en.ts +283 -0
- package/dist/templates/byline-examples/collections/doc-example-tree-locale-all.ts +278 -0
- package/dist/templates/byline-examples/collections/doc-example-tree-locale-en.ts +205 -0
- package/dist/templates/byline-examples/collections/docs/admin.tsx +204 -0
- package/dist/templates/byline-examples/collections/docs/components/.gitkeep +0 -0
- package/dist/templates/byline-examples/collections/docs/components/feature-formatter.tsx +10 -0
- package/dist/templates/byline-examples/collections/docs/hooks/.gitkeep +0 -0
- package/dist/templates/byline-examples/collections/docs/index.ts +10 -0
- package/dist/templates/byline-examples/collections/docs/schema.ts +209 -0
- package/dist/templates/byline-examples/collections/docs-categories/admin.tsx +78 -0
- package/dist/templates/byline-examples/collections/docs-categories/components/.gitkeep +0 -0
- package/dist/templates/byline-examples/collections/docs-categories/hooks/.gitkeep +0 -0
- package/dist/templates/byline-examples/collections/docs-categories/index.ts +10 -0
- package/dist/templates/byline-examples/collections/docs-categories/schema.ts +33 -0
- package/dist/templates/byline-examples/collections/media/admin.tsx +188 -0
- package/dist/templates/byline-examples/collections/media/components/media-list-view.tsx +330 -0
- package/dist/templates/byline-examples/collections/media/components/media-thumbnail.tsx +63 -0
- package/dist/templates/byline-examples/collections/media/hooks/.gitkeep +0 -0
- package/dist/templates/byline-examples/collections/media/index.ts +10 -0
- package/dist/templates/byline-examples/collections/media/schema.ts +157 -0
- package/dist/templates/byline-examples/collections/news/admin.tsx +192 -0
- package/dist/templates/byline-examples/collections/news/components/.gitkeep +0 -0
- package/dist/templates/byline-examples/collections/news/hooks/.gitkeep +0 -0
- package/dist/templates/byline-examples/collections/news/index.ts +10 -0
- package/dist/templates/byline-examples/collections/news/schema.ts +91 -0
- package/dist/templates/byline-examples/collections/news-categories/admin.tsx +78 -0
- package/dist/templates/byline-examples/collections/news-categories/components/.gitkeep +0 -0
- package/dist/templates/byline-examples/collections/news-categories/hooks/.gitkeep +0 -0
- package/dist/templates/byline-examples/collections/news-categories/index.ts +10 -0
- package/dist/templates/byline-examples/collections/news-categories/schema.ts +33 -0
- package/dist/templates/byline-examples/collections/pages/admin.tsx +183 -0
- package/dist/templates/byline-examples/collections/pages/components/.gitkeep +0 -0
- package/dist/templates/byline-examples/collections/pages/hooks/.gitkeep +0 -0
- package/dist/templates/byline-examples/collections/pages/index.ts +10 -0
- package/dist/templates/byline-examples/collections/pages/schema.ts +96 -0
- package/dist/templates/byline-examples/components/length-indicator.tsx +138 -0
- package/dist/templates/byline-examples/components/pill.tsx +38 -0
- package/dist/templates/byline-examples/components/summary-length.tsx +39 -0
- package/dist/templates/byline-examples/fields/available-languages-field.ts +90 -0
- package/dist/templates/byline-examples/fields/lexical-richtext-compact.ts +88 -0
- package/dist/templates/byline-examples/i18n.ts +47 -0
- package/dist/templates/byline-examples/routes.ts +28 -0
- package/dist/templates/byline-examples/scripts/regenerate-media.ts +275 -0
- package/dist/templates/byline-examples/seed.ts +25 -0
- package/dist/templates/byline-examples/seeds/admin.ts +62 -0
- package/dist/templates/byline-examples/seeds/doc-categories.ts +71 -0
- package/dist/templates/byline-examples/seeds/docs.ts +293 -0
- package/dist/templates/byline-examples/seeds/news-categories.ts +71 -0
- package/dist/templates/byline-examples/server.config.ts +179 -0
- package/dist/templates/host/vite.config.ts +41 -0
- package/dist/templates/migrations/0000_condemned_kronos.sql +324 -0
- package/dist/templates/migrations/0001_sudden_phantom_reporter.sql +1 -0
- package/dist/templates/migrations/meta/0000_snapshot.json +2793 -0
- package/dist/templates/migrations/meta/0001_snapshot.json +2799 -0
- package/dist/templates/migrations/meta/_journal.json +20 -0
- package/dist/templates/routes/(byline)/admin/account/index.tsx +11 -0
- package/dist/templates/routes/(byline)/admin/collections/$collection/$id/api.tsx +16 -0
- package/dist/templates/routes/(byline)/admin/collections/$collection/$id/history.tsx +19 -0
- package/dist/templates/routes/(byline)/admin/collections/$collection/$id/index.tsx +16 -0
- package/dist/templates/routes/(byline)/admin/collections/$collection/create.tsx +11 -0
- package/dist/templates/routes/(byline)/admin/collections/$collection/index.tsx +11 -0
- package/dist/templates/routes/(byline)/admin/index.tsx +11 -0
- package/dist/templates/routes/(byline)/admin/permissions/index.tsx +11 -0
- package/dist/templates/routes/(byline)/admin/roles/$id/index.tsx +11 -0
- package/dist/templates/routes/(byline)/admin/roles/index.tsx +11 -0
- package/dist/templates/routes/(byline)/admin/route.tsx +11 -0
- package/dist/templates/routes/(byline)/admin/users/$id/index.tsx +11 -0
- package/dist/templates/routes/(byline)/admin/users/index.tsx +11 -0
- package/dist/templates/routes/(byline)/sign-in.tsx +11 -0
- package/dist/templates/ui-byline/blocks/photo-block/index.tsx +80 -0
- package/dist/templates/ui-byline/blocks/richtext-block/index.tsx +46 -0
- package/dist/templates/ui-byline/components/admonition/index.tsx +40 -0
- package/dist/templates/ui-byline/components/code/code-serializer.tsx +20 -0
- package/dist/templates/ui-byline/components/code/code.tsx +50 -0
- package/dist/templates/ui-byline/components/code/index.module.scss +137 -0
- package/dist/templates/ui-byline/components/code/index.ts +2 -0
- package/dist/templates/ui-byline/components/code/types.ts +5 -0
- package/dist/templates/ui-byline/components/code/utils.ts +20 -0
- package/dist/templates/ui-byline/components/heading-anchor/heading-anchor.tsx +69 -0
- package/dist/templates/ui-byline/components/heading-anchor/index.ts +1 -0
- package/dist/templates/ui-byline/components/heading-anchor/utils.ts +15 -0
- package/dist/templates/ui-byline/components/inline-image/index.tsx +109 -0
- package/dist/templates/ui-byline/components/layout/index.tsx +63 -0
- package/dist/templates/ui-byline/components/link/lang-link.tsx +70 -0
- package/dist/templates/ui-byline/components/link/link-field.tsx +298 -0
- package/dist/templates/ui-byline/components/link/link-lexical.tsx +191 -0
- package/dist/templates/ui-byline/components/list/index.ts +2 -0
- package/dist/templates/ui-byline/components/list/list-item.tsx +32 -0
- package/dist/templates/ui-byline/components/list/list.tsx +17 -0
- package/dist/templates/ui-byline/components/responsive-image/index.tsx +205 -0
- package/dist/templates/ui-byline/components/richtext-lexical/index.tsx +31 -0
- package/dist/templates/ui-byline/components/richtext-lexical/serialize/index.tsx +249 -0
- package/dist/templates/ui-byline/components/richtext-lexical/serialize/richtext-node-formats.ts +66 -0
- package/dist/templates/ui-byline/components/richtext-lexical/serialize/types.ts +48 -0
- package/dist/templates/ui-byline/components/richtext-lexical/serialize/utils.ts +15 -0
- package/dist/templates/ui-byline/components/table-cell/index.tsx +36 -0
- package/dist/templates/ui-byline/components/vimeo/index.tsx +21 -0
- package/dist/templates/ui-byline/components/youtube/index.tsx +22 -0
- package/dist/templates/ui-byline/render-blocks.tsx +71 -0
- package/dist/templates/ui-byline/types/i18n.ts +14 -0
- package/dist/templates/ui-byline/utils/image-sources.ts +102 -0
- package/dist/templates/ui-byline/utils/to-kebab-case.ts +5 -0
- package/dist/types.d.ts +54 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +2 -0
- package/dist/types.js.map +1 -0
- package/dist/ui/diff.d.ts +4 -0
- package/dist/ui/diff.d.ts.map +1 -0
- package/dist/ui/diff.js +23 -0
- package/dist/ui/diff.js.map +1 -0
- package/dist/ui/grid.d.ts +7 -0
- package/dist/ui/grid.d.ts.map +1 -0
- package/dist/ui/grid.js +24 -0
- package/dist/ui/grid.js.map +1 -0
- package/dist/ui/logger.d.ts +14 -0
- package/dist/ui/logger.d.ts.map +1 -0
- package/dist/ui/logger.js +30 -0
- package/dist/ui/logger.js.map +1 -0
- package/dist/ui/snippet.d.ts +2 -0
- package/dist/ui/snippet.d.ts.map +1 -0
- package/dist/ui/snippet.js +7 -0
- package/dist/ui/snippet.js.map +1 -0
- package/package.json +69 -0
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import type { Prompter } from './prompts.js';
|
|
2
|
+
import type { StateStore } from './state.js';
|
|
3
|
+
import type { PackageManager } from './types.js';
|
|
4
|
+
import type { Logger } from './ui/logger.js';
|
|
5
|
+
export interface ContextOptions {
|
|
6
|
+
cwd: string;
|
|
7
|
+
apply: boolean;
|
|
8
|
+
dryRun: boolean;
|
|
9
|
+
yes: boolean;
|
|
10
|
+
reset: boolean;
|
|
11
|
+
resetConfirmed: boolean;
|
|
12
|
+
pm?: PackageManager;
|
|
13
|
+
cliFlags: Record<string, string | boolean | undefined>;
|
|
14
|
+
logger: Logger;
|
|
15
|
+
prompter: Prompter;
|
|
16
|
+
state: StateStore;
|
|
17
|
+
}
|
|
18
|
+
export interface Secrets {
|
|
19
|
+
dbPassword?: string;
|
|
20
|
+
}
|
|
21
|
+
export declare class Context {
|
|
22
|
+
readonly cwd: string;
|
|
23
|
+
readonly apply: boolean;
|
|
24
|
+
readonly dryRun: boolean;
|
|
25
|
+
readonly yes: boolean;
|
|
26
|
+
readonly reset: boolean;
|
|
27
|
+
readonly resetConfirmed: boolean;
|
|
28
|
+
pm: PackageManager;
|
|
29
|
+
readonly cliFlags: Record<string, string | boolean | undefined>;
|
|
30
|
+
readonly logger: Logger;
|
|
31
|
+
readonly prompter: Prompter;
|
|
32
|
+
readonly state: StateStore;
|
|
33
|
+
readonly secrets: Secrets;
|
|
34
|
+
constructor(opts: ContextOptions);
|
|
35
|
+
resolve(...parts: string[]): string;
|
|
36
|
+
templatesDir(): string;
|
|
37
|
+
}
|
|
38
|
+
//# sourceMappingURL=context.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"context.d.ts","sourceRoot":"","sources":["../src/context.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,cAAc,CAAA;AAC5C,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,YAAY,CAAA;AAC5C,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,YAAY,CAAA;AAChD,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,gBAAgB,CAAA;AAE5C,MAAM,WAAW,cAAc;IAC7B,GAAG,EAAE,MAAM,CAAA;IACX,KAAK,EAAE,OAAO,CAAA;IACd,MAAM,EAAE,OAAO,CAAA;IACf,GAAG,EAAE,OAAO,CAAA;IACZ,KAAK,EAAE,OAAO,CAAA;IACd,cAAc,EAAE,OAAO,CAAA;IACvB,EAAE,CAAC,EAAE,cAAc,CAAA;IACnB,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,GAAG,SAAS,CAAC,CAAA;IACtD,MAAM,EAAE,MAAM,CAAA;IACd,QAAQ,EAAE,QAAQ,CAAA;IAClB,KAAK,EAAE,UAAU,CAAA;CAClB;AAED,MAAM,WAAW,OAAO;IACtB,UAAU,CAAC,EAAE,MAAM,CAAA;CACpB;AAED,qBAAa,OAAO;IAClB,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAA;IACpB,QAAQ,CAAC,KAAK,EAAE,OAAO,CAAA;IACvB,QAAQ,CAAC,MAAM,EAAE,OAAO,CAAA;IACxB,QAAQ,CAAC,GAAG,EAAE,OAAO,CAAA;IACrB,QAAQ,CAAC,KAAK,EAAE,OAAO,CAAA;IACvB,QAAQ,CAAC,cAAc,EAAE,OAAO,CAAA;IAChC,EAAE,EAAE,cAAc,CAAA;IAClB,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,GAAG,SAAS,CAAC,CAAA;IAC/D,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAA;IACvB,QAAQ,CAAC,QAAQ,EAAE,QAAQ,CAAA;IAC3B,QAAQ,CAAC,KAAK,EAAE,UAAU,CAAA;IAC1B,QAAQ,CAAC,OAAO,EAAE,OAAO,CAAK;gBAElB,IAAI,EAAE,cAAc;IAchC,OAAO,CAAC,GAAG,KAAK,EAAE,MAAM,EAAE,GAAG,MAAM;IAInC,YAAY,IAAI,MAAM;CAIvB"}
|
package/dist/context.js
ADDED
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import { dirname, resolve } from 'node:path';
|
|
2
|
+
import { fileURLToPath } from 'node:url';
|
|
3
|
+
export class Context {
|
|
4
|
+
cwd;
|
|
5
|
+
apply;
|
|
6
|
+
dryRun;
|
|
7
|
+
yes;
|
|
8
|
+
reset;
|
|
9
|
+
resetConfirmed;
|
|
10
|
+
pm;
|
|
11
|
+
cliFlags;
|
|
12
|
+
logger;
|
|
13
|
+
prompter;
|
|
14
|
+
state;
|
|
15
|
+
secrets = {};
|
|
16
|
+
constructor(opts) {
|
|
17
|
+
this.cwd = opts.cwd;
|
|
18
|
+
this.apply = opts.apply;
|
|
19
|
+
this.dryRun = opts.dryRun;
|
|
20
|
+
this.yes = opts.yes;
|
|
21
|
+
this.reset = opts.reset;
|
|
22
|
+
this.resetConfirmed = opts.resetConfirmed;
|
|
23
|
+
this.pm = opts.pm ?? 'pnpm';
|
|
24
|
+
this.cliFlags = opts.cliFlags;
|
|
25
|
+
this.logger = opts.logger;
|
|
26
|
+
this.prompter = opts.prompter;
|
|
27
|
+
this.state = opts.state;
|
|
28
|
+
}
|
|
29
|
+
resolve(...parts) {
|
|
30
|
+
return resolve(this.cwd, ...parts);
|
|
31
|
+
}
|
|
32
|
+
templatesDir() {
|
|
33
|
+
const here = dirname(fileURLToPath(import.meta.url));
|
|
34
|
+
return resolve(here, './templates');
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
//# sourceMappingURL=context.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"context.js","sourceRoot":"","sources":["../src/context.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAA;AAC5C,OAAO,EAAE,aAAa,EAAE,MAAM,UAAU,CAAA;AAyBxC,MAAM,OAAO,OAAO;IACT,GAAG,CAAQ;IACX,KAAK,CAAS;IACd,MAAM,CAAS;IACf,GAAG,CAAS;IACZ,KAAK,CAAS;IACd,cAAc,CAAS;IAChC,EAAE,CAAgB;IACT,QAAQ,CAA8C;IACtD,MAAM,CAAQ;IACd,QAAQ,CAAU;IAClB,KAAK,CAAY;IACjB,OAAO,GAAY,EAAE,CAAA;IAE9B,YAAY,IAAoB;QAC9B,IAAI,CAAC,GAAG,GAAG,IAAI,CAAC,GAAG,CAAA;QACnB,IAAI,CAAC,KAAK,GAAG,IAAI,CAAC,KAAK,CAAA;QACvB,IAAI,CAAC,MAAM,GAAG,IAAI,CAAC,MAAM,CAAA;QACzB,IAAI,CAAC,GAAG,GAAG,IAAI,CAAC,GAAG,CAAA;QACnB,IAAI,CAAC,KAAK,GAAG,IAAI,CAAC,KAAK,CAAA;QACvB,IAAI,CAAC,cAAc,GAAG,IAAI,CAAC,cAAc,CAAA;QACzC,IAAI,CAAC,EAAE,GAAG,IAAI,CAAC,EAAE,IAAI,MAAM,CAAA;QAC3B,IAAI,CAAC,QAAQ,GAAG,IAAI,CAAC,QAAQ,CAAA;QAC7B,IAAI,CAAC,MAAM,GAAG,IAAI,CAAC,MAAM,CAAA;QACzB,IAAI,CAAC,QAAQ,GAAG,IAAI,CAAC,QAAQ,CAAA;QAC7B,IAAI,CAAC,KAAK,GAAG,IAAI,CAAC,KAAK,CAAA;IACzB,CAAC;IAED,OAAO,CAAC,GAAG,KAAe;QACxB,OAAO,OAAO,CAAC,IAAI,CAAC,GAAG,EAAE,GAAG,KAAK,CAAC,CAAA;IACpC,CAAC;IAED,YAAY;QACV,MAAM,IAAI,GAAG,OAAO,CAAC,aAAa,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAA;QACpD,OAAO,OAAO,CAAC,IAAI,EAAE,aAAa,CAAC,CAAA;IACrC,CAAC;CACF"}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,sBAAsB,CAAA;AAChD,OAAO,EAAE,OAAO,EAAE,MAAM,oBAAoB,CAAA;AAC5C,OAAO,EAAE,SAAS,EAAE,MAAM,EAAE,MAAM,mBAAmB,CAAA;AACrD,YAAY,EAAE,KAAK,EAAE,OAAO,EAAE,UAAU,EAAE,IAAI,EAAE,MAAM,YAAY,CAAA"}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,sBAAsB,CAAA;AAChD,OAAO,EAAE,OAAO,EAAE,MAAM,oBAAoB,CAAA;AAC5C,OAAO,EAAE,SAAS,EAAE,MAAM,EAAE,MAAM,mBAAmB,CAAA"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
export interface PgConn {
|
|
2
|
+
host: string;
|
|
3
|
+
port: number;
|
|
4
|
+
user: string;
|
|
5
|
+
password: string;
|
|
6
|
+
database: string;
|
|
7
|
+
}
|
|
8
|
+
export declare function buildPgUrl(c: PgConn): string;
|
|
9
|
+
export declare function parsePgUrl(raw: string): PgConn;
|
|
10
|
+
export declare function withDatabase(c: PgConn, database: string): PgConn;
|
|
11
|
+
//# sourceMappingURL=pg-url.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"pg-url.d.ts","sourceRoot":"","sources":["../../src/lib/pg-url.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,MAAM;IACrB,IAAI,EAAE,MAAM,CAAA;IACZ,IAAI,EAAE,MAAM,CAAA;IACZ,IAAI,EAAE,MAAM,CAAA;IACZ,QAAQ,EAAE,MAAM,CAAA;IAChB,QAAQ,EAAE,MAAM,CAAA;CACjB;AAED,wBAAgB,UAAU,CAAC,CAAC,EAAE,MAAM,GAAG,MAAM,CAI5C;AAED,wBAAgB,UAAU,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAY9C;AAED,wBAAgB,YAAY,CAAC,CAAC,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,MAAM,CAEhE"}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
export function buildPgUrl(c) {
|
|
2
|
+
const u = encodeURIComponent(c.user);
|
|
3
|
+
const p = encodeURIComponent(c.password);
|
|
4
|
+
return `postgresql://${u}:${p}@${c.host}:${c.port}/${encodeURIComponent(c.database)}`;
|
|
5
|
+
}
|
|
6
|
+
export function parsePgUrl(raw) {
|
|
7
|
+
const url = new URL(raw);
|
|
8
|
+
if (url.protocol !== 'postgresql:' && url.protocol !== 'postgres:') {
|
|
9
|
+
throw new Error(`expected postgresql:// URL, got ${url.protocol}`);
|
|
10
|
+
}
|
|
11
|
+
return {
|
|
12
|
+
host: url.hostname,
|
|
13
|
+
port: url.port ? Number(url.port) : 5432,
|
|
14
|
+
user: decodeURIComponent(url.username),
|
|
15
|
+
password: decodeURIComponent(url.password),
|
|
16
|
+
database: url.pathname.replace(/^\//, '') || 'postgres',
|
|
17
|
+
};
|
|
18
|
+
}
|
|
19
|
+
export function withDatabase(c, database) {
|
|
20
|
+
return { ...c, database };
|
|
21
|
+
}
|
|
22
|
+
//# sourceMappingURL=pg-url.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"pg-url.js","sourceRoot":"","sources":["../../src/lib/pg-url.ts"],"names":[],"mappings":"AAQA,MAAM,UAAU,UAAU,CAAC,CAAS;IAClC,MAAM,CAAC,GAAG,kBAAkB,CAAC,CAAC,CAAC,IAAI,CAAC,CAAA;IACpC,MAAM,CAAC,GAAG,kBAAkB,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAA;IACxC,OAAO,gBAAgB,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,IAAI,IAAI,CAAC,CAAC,IAAI,IAAI,kBAAkB,CAAC,CAAC,CAAC,QAAQ,CAAC,EAAE,CAAA;AACvF,CAAC;AAED,MAAM,UAAU,UAAU,CAAC,GAAW;IACpC,MAAM,GAAG,GAAG,IAAI,GAAG,CAAC,GAAG,CAAC,CAAA;IACxB,IAAI,GAAG,CAAC,QAAQ,KAAK,aAAa,IAAI,GAAG,CAAC,QAAQ,KAAK,WAAW,EAAE,CAAC;QACnE,MAAM,IAAI,KAAK,CAAC,mCAAmC,GAAG,CAAC,QAAQ,EAAE,CAAC,CAAA;IACpE,CAAC;IACD,OAAO;QACL,IAAI,EAAE,GAAG,CAAC,QAAQ;QAClB,IAAI,EAAE,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI;QACxC,IAAI,EAAE,kBAAkB,CAAC,GAAG,CAAC,QAAQ,CAAC;QACtC,QAAQ,EAAE,kBAAkB,CAAC,GAAG,CAAC,QAAQ,CAAC;QAC1C,QAAQ,EAAE,GAAG,CAAC,QAAQ,CAAC,OAAO,CAAC,KAAK,EAAE,EAAE,CAAC,IAAI,UAAU;KACxD,CAAA;AACH,CAAC;AAED,MAAM,UAAU,YAAY,CAAC,CAAS,EAAE,QAAgB;IACtD,OAAO,EAAE,GAAG,CAAC,EAAE,QAAQ,EAAE,CAAA;AAC3B,CAAC"}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Single source of truth for the npm packages a Byline-on-TanStack-Start
|
|
3
|
+
* install needs in the host application's `package.json`. Consumed by the
|
|
4
|
+
* `deps` phase (to install missing entries) and by `doctor` (to report
|
|
5
|
+
* what's missing without re-running the install).
|
|
6
|
+
*
|
|
7
|
+
* Versioning policy: `@byline/*` packages are released in lockstep, so
|
|
8
|
+
* they share `BYLINE_VERSION`. `@byline/host-tanstack-start` rides its
|
|
9
|
+
* own `1.x` line because its API surface (route stubs, integrations) is
|
|
10
|
+
* stable across Byline minor bumps and consumers pin against it
|
|
11
|
+
* separately.
|
|
12
|
+
*
|
|
13
|
+
* Scope: this list is intentionally minimal — only packages that are
|
|
14
|
+
* directly imported by files we drop into the user's tree (`byline/`,
|
|
15
|
+
* `src/routes/(byline)/`, `src/ui/byline/`). Transitive deps reach the
|
|
16
|
+
* user via the `@byline/*` package boundary and don't need declaring.
|
|
17
|
+
*/
|
|
18
|
+
export type DepGroup = 'byline' | 'runtime' | 'dev';
|
|
19
|
+
export interface DepSpec {
|
|
20
|
+
name: string;
|
|
21
|
+
version: string;
|
|
22
|
+
group: DepGroup;
|
|
23
|
+
/** Short human-readable reason this is on the list. */
|
|
24
|
+
note: string;
|
|
25
|
+
}
|
|
26
|
+
export declare const BYLINE_VERSION = "^0.10.0";
|
|
27
|
+
export declare const HOST_TANSTACK_VERSION = "^1.0.0";
|
|
28
|
+
export declare const DEP_SPECS: readonly DepSpec[];
|
|
29
|
+
//# sourceMappingURL=deps.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"deps.d.ts","sourceRoot":"","sources":["../../src/manifest/deps.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AAEH,MAAM,MAAM,QAAQ,GAAG,QAAQ,GAAG,SAAS,GAAG,KAAK,CAAA;AAEnD,MAAM,WAAW,OAAO;IACtB,IAAI,EAAE,MAAM,CAAA;IACZ,OAAO,EAAE,MAAM,CAAA;IACf,KAAK,EAAE,QAAQ,CAAA;IACf,uDAAuD;IACvD,IAAI,EAAE,MAAM,CAAA;CACb;AAED,eAAO,MAAM,cAAc,YAAY,CAAA;AACvC,eAAO,MAAM,qBAAqB,WAAW,CAAA;AAE7C,eAAO,MAAM,SAAS,EAAE,SAAS,OAAO,EA8E9B,CAAA"}
|
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Single source of truth for the npm packages a Byline-on-TanStack-Start
|
|
3
|
+
* install needs in the host application's `package.json`. Consumed by the
|
|
4
|
+
* `deps` phase (to install missing entries) and by `doctor` (to report
|
|
5
|
+
* what's missing without re-running the install).
|
|
6
|
+
*
|
|
7
|
+
* Versioning policy: `@byline/*` packages are released in lockstep, so
|
|
8
|
+
* they share `BYLINE_VERSION`. `@byline/host-tanstack-start` rides its
|
|
9
|
+
* own `1.x` line because its API surface (route stubs, integrations) is
|
|
10
|
+
* stable across Byline minor bumps and consumers pin against it
|
|
11
|
+
* separately.
|
|
12
|
+
*
|
|
13
|
+
* Scope: this list is intentionally minimal — only packages that are
|
|
14
|
+
* directly imported by files we drop into the user's tree (`byline/`,
|
|
15
|
+
* `src/routes/(byline)/`, `src/ui/byline/`). Transitive deps reach the
|
|
16
|
+
* user via the `@byline/*` package boundary and don't need declaring.
|
|
17
|
+
*/
|
|
18
|
+
export const BYLINE_VERSION = '^0.10.0';
|
|
19
|
+
export const HOST_TANSTACK_VERSION = '^1.0.0';
|
|
20
|
+
export const DEP_SPECS = [
|
|
21
|
+
// ---- @byline/* — released in lockstep at BYLINE_VERSION -----------------
|
|
22
|
+
{
|
|
23
|
+
name: '@byline/admin',
|
|
24
|
+
version: BYLINE_VERSION,
|
|
25
|
+
group: 'byline',
|
|
26
|
+
note: 'admin user / role / permission modules + JwtSessionProvider',
|
|
27
|
+
},
|
|
28
|
+
{
|
|
29
|
+
name: '@byline/auth',
|
|
30
|
+
version: BYLINE_VERSION,
|
|
31
|
+
group: 'byline',
|
|
32
|
+
note: 'actor primitives, RequestContext, AbilityRegistry',
|
|
33
|
+
},
|
|
34
|
+
{
|
|
35
|
+
name: '@byline/client',
|
|
36
|
+
version: BYLINE_VERSION,
|
|
37
|
+
group: 'byline',
|
|
38
|
+
note: 'in-process SDK over storage primitives + document lifecycle',
|
|
39
|
+
},
|
|
40
|
+
{
|
|
41
|
+
name: '@byline/core',
|
|
42
|
+
version: BYLINE_VERSION,
|
|
43
|
+
group: 'byline',
|
|
44
|
+
note: 'types, config, patches, workflow, Zod schema builder',
|
|
45
|
+
},
|
|
46
|
+
{
|
|
47
|
+
name: '@byline/db-postgres',
|
|
48
|
+
version: BYLINE_VERSION,
|
|
49
|
+
group: 'byline',
|
|
50
|
+
note: 'Postgres adapter (Drizzle ORM)',
|
|
51
|
+
},
|
|
52
|
+
{
|
|
53
|
+
name: '@byline/host-tanstack-start',
|
|
54
|
+
version: HOST_TANSTACK_VERSION,
|
|
55
|
+
group: 'byline',
|
|
56
|
+
note: 'TanStack Start integrations + route stubs',
|
|
57
|
+
},
|
|
58
|
+
{
|
|
59
|
+
name: '@byline/richtext-lexical',
|
|
60
|
+
version: BYLINE_VERSION,
|
|
61
|
+
group: 'byline',
|
|
62
|
+
note: 'Lexical-backed richtext field + server populate',
|
|
63
|
+
},
|
|
64
|
+
{
|
|
65
|
+
name: '@byline/storage-local',
|
|
66
|
+
version: BYLINE_VERSION,
|
|
67
|
+
group: 'byline',
|
|
68
|
+
note: 'local-filesystem storage provider (default)',
|
|
69
|
+
},
|
|
70
|
+
{
|
|
71
|
+
name: '@byline/ui',
|
|
72
|
+
version: BYLINE_VERSION,
|
|
73
|
+
group: 'byline',
|
|
74
|
+
note: 'shared UI components used by admin route group',
|
|
75
|
+
},
|
|
76
|
+
// ---- Runtime third-party ------------------------------------------------
|
|
77
|
+
{
|
|
78
|
+
name: 'lodash-es',
|
|
79
|
+
version: '^4.17.21',
|
|
80
|
+
group: 'runtime',
|
|
81
|
+
note: 'used by byline/ config helpers',
|
|
82
|
+
},
|
|
83
|
+
// ---- Dev ---------------------------------------------------------------
|
|
84
|
+
{
|
|
85
|
+
name: '@types/lodash-es',
|
|
86
|
+
version: '^4.17.12',
|
|
87
|
+
group: 'dev',
|
|
88
|
+
note: 'types for lodash-es',
|
|
89
|
+
},
|
|
90
|
+
{
|
|
91
|
+
name: 'tsx',
|
|
92
|
+
version: '^4.21.0',
|
|
93
|
+
group: 'dev',
|
|
94
|
+
note: 'runs byline/seed.ts and byline/scripts/* without a build step',
|
|
95
|
+
},
|
|
96
|
+
];
|
|
97
|
+
//# sourceMappingURL=deps.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"deps.js","sourceRoot":"","sources":["../../src/manifest/deps.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AAYH,MAAM,CAAC,MAAM,cAAc,GAAG,SAAS,CAAA;AACvC,MAAM,CAAC,MAAM,qBAAqB,GAAG,QAAQ,CAAA;AAE7C,MAAM,CAAC,MAAM,SAAS,GAAuB;IAC3C,4EAA4E;IAC5E;QACE,IAAI,EAAE,eAAe;QACrB,OAAO,EAAE,cAAc;QACvB,KAAK,EAAE,QAAQ;QACf,IAAI,EAAE,6DAA6D;KACpE;IACD;QACE,IAAI,EAAE,cAAc;QACpB,OAAO,EAAE,cAAc;QACvB,KAAK,EAAE,QAAQ;QACf,IAAI,EAAE,mDAAmD;KAC1D;IACD;QACE,IAAI,EAAE,gBAAgB;QACtB,OAAO,EAAE,cAAc;QACvB,KAAK,EAAE,QAAQ;QACf,IAAI,EAAE,6DAA6D;KACpE;IACD;QACE,IAAI,EAAE,cAAc;QACpB,OAAO,EAAE,cAAc;QACvB,KAAK,EAAE,QAAQ;QACf,IAAI,EAAE,sDAAsD;KAC7D;IACD;QACE,IAAI,EAAE,qBAAqB;QAC3B,OAAO,EAAE,cAAc;QACvB,KAAK,EAAE,QAAQ;QACf,IAAI,EAAE,gCAAgC;KACvC;IACD;QACE,IAAI,EAAE,6BAA6B;QACnC,OAAO,EAAE,qBAAqB;QAC9B,KAAK,EAAE,QAAQ;QACf,IAAI,EAAE,2CAA2C;KAClD;IACD;QACE,IAAI,EAAE,0BAA0B;QAChC,OAAO,EAAE,cAAc;QACvB,KAAK,EAAE,QAAQ;QACf,IAAI,EAAE,iDAAiD;KACxD;IACD;QACE,IAAI,EAAE,uBAAuB;QAC7B,OAAO,EAAE,cAAc;QACvB,KAAK,EAAE,QAAQ;QACf,IAAI,EAAE,6CAA6C;KACpD;IACD;QACE,IAAI,EAAE,YAAY;QAClB,OAAO,EAAE,cAAc;QACvB,KAAK,EAAE,QAAQ;QACf,IAAI,EAAE,gDAAgD;KACvD;IAED,4EAA4E;IAC5E;QACE,IAAI,EAAE,WAAW;QACjB,OAAO,EAAE,UAAU;QACnB,KAAK,EAAE,SAAS;QAChB,IAAI,EAAE,gCAAgC;KACvC;IAED,2EAA2E;IAC3E;QACE,IAAI,EAAE,kBAAkB;QACxB,OAAO,EAAE,UAAU;QACnB,KAAK,EAAE,KAAK;QACZ,IAAI,EAAE,qBAAqB;KAC5B;IACD;QACE,IAAI,EAAE,KAAK;QACX,OAAO,EAAE,SAAS;QAClB,KAAK,EAAE,KAAK;QACZ,IAAI,EAAE,+DAA+D;KACtE;CACO,CAAA"}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Single source of truth for the environment variables Byline expects in the
|
|
3
|
+
* host application's `.env`. Consumed by the `env` phase (to render `.env`)
|
|
4
|
+
* and by `doctor` (to report which keys are missing).
|
|
5
|
+
*
|
|
6
|
+
* Each entry describes what the key is for. How its value is obtained
|
|
7
|
+
* (default, prompt, generated, computed from db answers) is the env phase's
|
|
8
|
+
* concern — keep that logic in `phases/env.ts`, not here.
|
|
9
|
+
*/
|
|
10
|
+
export type EnvKey = 'VITE_SERVER_URL' | 'DB_CONNECTION_STRING' | 'BYLINE_JWT_SECRET' | 'BYLINE_SUPERADMIN_EMAIL' | 'BYLINE_SUPERADMIN_PASSWORD';
|
|
11
|
+
export interface EnvSpec {
|
|
12
|
+
key: EnvKey;
|
|
13
|
+
description: string;
|
|
14
|
+
group: 'app' | 'database' | 'auth';
|
|
15
|
+
}
|
|
16
|
+
export declare const ENV_SPECS: readonly EnvSpec[];
|
|
17
|
+
export declare const ENV_KEYS: readonly EnvKey[];
|
|
18
|
+
//# sourceMappingURL=env.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"env.d.ts","sourceRoot":"","sources":["../../src/manifest/env.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,MAAM,MAAM,MAAM,GACd,iBAAiB,GACjB,sBAAsB,GACtB,mBAAmB,GACnB,yBAAyB,GACzB,4BAA4B,CAAA;AAEhC,MAAM,WAAW,OAAO;IACtB,GAAG,EAAE,MAAM,CAAA;IACX,WAAW,EAAE,MAAM,CAAA;IACnB,KAAK,EAAE,KAAK,GAAG,UAAU,GAAG,MAAM,CAAA;CACnC;AAED,eAAO,MAAM,SAAS,EAAE,SAAS,OAAO,EA0B9B,CAAA;AAEV,eAAO,MAAM,QAAQ,EAAE,SAAS,MAAM,EAAgC,CAAA"}
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Single source of truth for the environment variables Byline expects in the
|
|
3
|
+
* host application's `.env`. Consumed by the `env` phase (to render `.env`)
|
|
4
|
+
* and by `doctor` (to report which keys are missing).
|
|
5
|
+
*
|
|
6
|
+
* Each entry describes what the key is for. How its value is obtained
|
|
7
|
+
* (default, prompt, generated, computed from db answers) is the env phase's
|
|
8
|
+
* concern — keep that logic in `phases/env.ts`, not here.
|
|
9
|
+
*/
|
|
10
|
+
export const ENV_SPECS = [
|
|
11
|
+
{
|
|
12
|
+
key: 'VITE_SERVER_URL',
|
|
13
|
+
description: 'Public origin used by SSR and the admin UI',
|
|
14
|
+
group: 'app',
|
|
15
|
+
},
|
|
16
|
+
{
|
|
17
|
+
key: 'DB_CONNECTION_STRING',
|
|
18
|
+
description: 'Postgres connection string consumed by @byline/db-postgres',
|
|
19
|
+
group: 'database',
|
|
20
|
+
},
|
|
21
|
+
{
|
|
22
|
+
key: 'BYLINE_JWT_SECRET',
|
|
23
|
+
description: 'Signing secret for the built-in JwtSessionProvider (>= 32 bytes of entropy)',
|
|
24
|
+
group: 'auth',
|
|
25
|
+
},
|
|
26
|
+
{
|
|
27
|
+
key: 'BYLINE_SUPERADMIN_EMAIL',
|
|
28
|
+
description: 'Bootstrap super-admin email seeded by byline/seed.ts',
|
|
29
|
+
group: 'auth',
|
|
30
|
+
},
|
|
31
|
+
{
|
|
32
|
+
key: 'BYLINE_SUPERADMIN_PASSWORD',
|
|
33
|
+
description: 'Bootstrap super-admin password seeded by byline/seed.ts',
|
|
34
|
+
group: 'auth',
|
|
35
|
+
},
|
|
36
|
+
];
|
|
37
|
+
export const ENV_KEYS = ENV_SPECS.map((s) => s.key);
|
|
38
|
+
//# sourceMappingURL=env.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"env.js","sourceRoot":"","sources":["../../src/manifest/env.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAeH,MAAM,CAAC,MAAM,SAAS,GAAuB;IAC3C;QACE,GAAG,EAAE,iBAAiB;QACtB,WAAW,EAAE,4CAA4C;QACzD,KAAK,EAAE,KAAK;KACb;IACD;QACE,GAAG,EAAE,sBAAsB;QAC3B,WAAW,EAAE,4DAA4D;QACzE,KAAK,EAAE,UAAU;KAClB;IACD;QACE,GAAG,EAAE,mBAAmB;QACxB,WAAW,EAAE,6EAA6E;QAC1F,KAAK,EAAE,MAAM;KACd;IACD;QACE,GAAG,EAAE,yBAAyB;QAC9B,WAAW,EAAE,sDAAsD;QACnE,KAAK,EAAE,MAAM;KACd;IACD;QACE,GAAG,EAAE,4BAA4B;QACjC,WAAW,EAAE,yDAAyD;QACtE,KAAK,EAAE,MAAM;KACd;CACO,CAAA;AAEV,MAAM,CAAC,MAAM,QAAQ,GAAsB,SAAS,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,CAAA"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"db-init.d.ts","sourceRoot":"","sources":["../../src/phases/db-init.ts"],"names":[],"mappings":"AASA,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,aAAa,CAAA;AAIxC,eAAO,MAAM,WAAW,EAAE,KA2EzB,CAAA"}
|
|
@@ -0,0 +1,163 @@
|
|
|
1
|
+
import { resolve } from 'node:path';
|
|
2
|
+
import { drizzle } from 'drizzle-orm/node-postgres';
|
|
3
|
+
import { migrate } from 'drizzle-orm/node-postgres/migrator';
|
|
4
|
+
import { Client } from 'pg';
|
|
5
|
+
import { buildPgUrl, parsePgUrl, withDatabase } from '../lib/pg-url.js';
|
|
6
|
+
import { isValidIdentifier } from './db.js';
|
|
7
|
+
const REQUIRED_EXTENSIONS = ['pgcrypto'];
|
|
8
|
+
export const dbInitPhase = {
|
|
9
|
+
id: 'db-init',
|
|
10
|
+
title: 'Database initialization — provision role + database, install extensions, run migrations',
|
|
11
|
+
defaultMode: 'confirm',
|
|
12
|
+
async detect(ctx) {
|
|
13
|
+
if (ctx.state.isComplete('db-init'))
|
|
14
|
+
return 'done';
|
|
15
|
+
const a = ctx.state.get().answers;
|
|
16
|
+
if (!a.superuserUrl || !a.dbName || !a.dbUser)
|
|
17
|
+
return 'blocked';
|
|
18
|
+
return 'pending';
|
|
19
|
+
},
|
|
20
|
+
async plan(ctx) {
|
|
21
|
+
const a = ctx.state.get().answers;
|
|
22
|
+
const notes = [];
|
|
23
|
+
if (a.dbName)
|
|
24
|
+
notes.push(`provision database "${a.dbName}"`);
|
|
25
|
+
if (a.dbUser)
|
|
26
|
+
notes.push(`provision role "${a.dbUser}" (CREATE IF NOT EXISTS)`);
|
|
27
|
+
if (ctx.reset) {
|
|
28
|
+
notes.push('--reset: existing database will be DROPPED if present');
|
|
29
|
+
}
|
|
30
|
+
else {
|
|
31
|
+
notes.push('non-destructive: existing database/role will be reused');
|
|
32
|
+
}
|
|
33
|
+
notes.push(`install extensions: ${REQUIRED_EXTENSIONS.join(', ')}`);
|
|
34
|
+
notes.push('run drizzle migrations from bundled @byline/cli templates');
|
|
35
|
+
return { writes: [], commands: [], notes };
|
|
36
|
+
},
|
|
37
|
+
async apply(_plan, ctx) {
|
|
38
|
+
const a = ctx.state.get().answers;
|
|
39
|
+
if (!a.superuserUrl || !a.dbName || !a.dbUser) {
|
|
40
|
+
ctx.logger.error('db-init prerequisites missing — run the db phase first');
|
|
41
|
+
return { state: 'blocked' };
|
|
42
|
+
}
|
|
43
|
+
if (!isValidIdentifier(a.dbName) || !isValidIdentifier(a.dbUser)) {
|
|
44
|
+
ctx.logger.error('invalid identifier — internal state is corrupt; clear .byline-install.json');
|
|
45
|
+
return { state: 'blocked' };
|
|
46
|
+
}
|
|
47
|
+
const password = await resolveAppPassword(ctx);
|
|
48
|
+
if (!password)
|
|
49
|
+
return { state: 'blocked' };
|
|
50
|
+
ctx.secrets.dbPassword = password;
|
|
51
|
+
const sup = parsePgUrl(a.superuserUrl);
|
|
52
|
+
if (ctx.reset && !ctx.resetConfirmed) {
|
|
53
|
+
const ok = await ctx.prompter.confirm({
|
|
54
|
+
message: `RESET will DROP database "${a.dbName}" if it exists. Continue?`,
|
|
55
|
+
defaultValue: false,
|
|
56
|
+
});
|
|
57
|
+
if (!ok) {
|
|
58
|
+
ctx.logger.info('reset cancelled');
|
|
59
|
+
return { state: 'blocked' };
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
await provisionRoleAndDatabase(ctx, {
|
|
63
|
+
sup,
|
|
64
|
+
dbName: a.dbName,
|
|
65
|
+
dbUser: a.dbUser,
|
|
66
|
+
password,
|
|
67
|
+
reset: ctx.reset,
|
|
68
|
+
});
|
|
69
|
+
await installExtensions(ctx, withDatabase(sup, a.dbName));
|
|
70
|
+
await runMigrations(ctx, {
|
|
71
|
+
host: sup.host,
|
|
72
|
+
port: sup.port,
|
|
73
|
+
user: a.dbUser,
|
|
74
|
+
password,
|
|
75
|
+
database: a.dbName,
|
|
76
|
+
});
|
|
77
|
+
return { state: 'done' };
|
|
78
|
+
},
|
|
79
|
+
};
|
|
80
|
+
async function resolveAppPassword(ctx) {
|
|
81
|
+
const fromEnv = process.env.BYLINE_DB_PASSWORD;
|
|
82
|
+
if (fromEnv) {
|
|
83
|
+
ctx.logger.info('using app role password from BYLINE_DB_PASSWORD');
|
|
84
|
+
return fromEnv;
|
|
85
|
+
}
|
|
86
|
+
const pw = await ctx.prompter.password({
|
|
87
|
+
message: 'Choose a password for the application database role',
|
|
88
|
+
});
|
|
89
|
+
if (!pw || pw.length < 8) {
|
|
90
|
+
ctx.logger.error('password must be at least 8 characters');
|
|
91
|
+
return null;
|
|
92
|
+
}
|
|
93
|
+
return pw;
|
|
94
|
+
}
|
|
95
|
+
async function provisionRoleAndDatabase(ctx, args) {
|
|
96
|
+
const { sup, dbName, dbUser, password, reset } = args;
|
|
97
|
+
const client = new Client({ connectionString: buildPgUrl(sup) });
|
|
98
|
+
await client.connect();
|
|
99
|
+
try {
|
|
100
|
+
const dbUserIdent = client.escapeIdentifier(dbUser);
|
|
101
|
+
const dbNameIdent = client.escapeIdentifier(dbName);
|
|
102
|
+
const roleExists = await client.query('SELECT 1 FROM pg_roles WHERE rolname = $1', [dbUser]);
|
|
103
|
+
if ((roleExists.rowCount ?? 0) === 0) {
|
|
104
|
+
ctx.logger.step(`creating role ${dbUser}`);
|
|
105
|
+
await client.query(`CREATE ROLE ${dbUserIdent} WITH LOGIN`);
|
|
106
|
+
}
|
|
107
|
+
else {
|
|
108
|
+
ctx.logger.step(`role ${dbUser} already exists`);
|
|
109
|
+
}
|
|
110
|
+
await client.query(`ALTER ROLE ${dbUserIdent} WITH PASSWORD ${client.escapeLiteral(password)}`);
|
|
111
|
+
if (reset) {
|
|
112
|
+
ctx.logger.step(`terminating connections to ${dbName}`);
|
|
113
|
+
await client.query(`SELECT pg_terminate_backend(pid)
|
|
114
|
+
FROM pg_stat_activity
|
|
115
|
+
WHERE datname = $1 AND pid <> pg_backend_pid()`, [dbName]);
|
|
116
|
+
ctx.logger.step(`dropping database ${dbName}`);
|
|
117
|
+
await client.query(`DROP DATABASE IF EXISTS ${dbNameIdent}`);
|
|
118
|
+
}
|
|
119
|
+
const dbExists = await client.query('SELECT 1 FROM pg_database WHERE datname = $1', [dbName]);
|
|
120
|
+
if ((dbExists.rowCount ?? 0) === 0) {
|
|
121
|
+
ctx.logger.step(`creating database ${dbName}`);
|
|
122
|
+
await client.query(`CREATE DATABASE ${dbNameIdent} WITH OWNER ${dbUserIdent}`);
|
|
123
|
+
}
|
|
124
|
+
else {
|
|
125
|
+
ctx.logger.step(`database ${dbName} already exists — reusing`);
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
finally {
|
|
129
|
+
await client.end().catch(() => { });
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
async function installExtensions(ctx, conn) {
|
|
133
|
+
const client = new Client({ connectionString: buildPgUrl(conn) });
|
|
134
|
+
await client.connect();
|
|
135
|
+
try {
|
|
136
|
+
for (const ext of REQUIRED_EXTENSIONS) {
|
|
137
|
+
const ident = client.escapeIdentifier(ext);
|
|
138
|
+
ctx.logger.step(`CREATE EXTENSION IF NOT EXISTS ${ext}`);
|
|
139
|
+
await client.query(`CREATE EXTENSION IF NOT EXISTS ${ident}`);
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
finally {
|
|
143
|
+
await client.end().catch(() => { });
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
async function runMigrations(ctx, args) {
|
|
147
|
+
const migrationsFolder = resolve(ctx.templatesDir(), 'migrations');
|
|
148
|
+
ctx.logger.step(`running migrations from ${migrationsFolder}`);
|
|
149
|
+
const client = new Client({ connectionString: buildPgUrl(args) });
|
|
150
|
+
await client.connect();
|
|
151
|
+
try {
|
|
152
|
+
const db = drizzle(client);
|
|
153
|
+
await migrate(db, { migrationsFolder });
|
|
154
|
+
const r = await client.query(`SELECT count(*)::text AS count
|
|
155
|
+
FROM information_schema.tables
|
|
156
|
+
WHERE table_schema = 'public'`);
|
|
157
|
+
ctx.logger.success(`migrations applied — ${r.rows[0]?.count} tables in public schema`);
|
|
158
|
+
}
|
|
159
|
+
finally {
|
|
160
|
+
await client.end().catch(() => { });
|
|
161
|
+
}
|
|
162
|
+
}
|
|
163
|
+
//# sourceMappingURL=db-init.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"db-init.js","sourceRoot":"","sources":["../../src/phases/db-init.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import type { Phase } from '../types.js';
|
|
2
|
+
export declare const dbPhase: Phase;
|
|
3
|
+
export declare function isValidIdentifier(s: string): boolean;
|
|
4
|
+
export declare function buildAppConnUrl(opts: {
|
|
5
|
+
host: string;
|
|
6
|
+
port: number;
|
|
7
|
+
user: string;
|
|
8
|
+
password: string;
|
|
9
|
+
database: string;
|
|
10
|
+
}): string;
|
|
11
|
+
//# sourceMappingURL=db.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"db.d.ts","sourceRoot":"","sources":["../../src/phases/db.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,aAAa,CAAA;AAExC,eAAO,MAAM,OAAO,EAAE,KAsFrB,CAAA;AAED,wBAAgB,iBAAiB,CAAC,CAAC,EAAE,MAAM,GAAG,OAAO,CAEpD;AAED,wBAAgB,eAAe,CAAC,IAAI,EAAE;IACpC,IAAI,EAAE,MAAM,CAAA;IACZ,IAAI,EAAE,MAAM,CAAA;IACZ,IAAI,EAAE,MAAM,CAAA;IACZ,QAAQ,EAAE,MAAM,CAAA;IAChB,QAAQ,EAAE,MAAM,CAAA;CACjB,GAAG,MAAM,CAET"}
|
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
import { Client } from 'pg';
|
|
2
|
+
import { buildPgUrl, parsePgUrl } from '../lib/pg-url.js';
|
|
3
|
+
export const dbPhase = {
|
|
4
|
+
id: 'db',
|
|
5
|
+
title: 'Database — choose strategy and verify connection',
|
|
6
|
+
defaultMode: 'confirm',
|
|
7
|
+
async detect(ctx) {
|
|
8
|
+
return ctx.state.isComplete('db') ? 'done' : 'pending';
|
|
9
|
+
},
|
|
10
|
+
async plan(ctx) {
|
|
11
|
+
const a = ctx.state.get().answers;
|
|
12
|
+
const notes = [];
|
|
13
|
+
if (a.dbStrategy)
|
|
14
|
+
notes.push(`strategy: ${a.dbStrategy}`);
|
|
15
|
+
if (a.dbHost)
|
|
16
|
+
notes.push(`host: ${a.dbHost}:${a.dbPort}`);
|
|
17
|
+
if (a.dbName)
|
|
18
|
+
notes.push(`database: ${a.dbName}`);
|
|
19
|
+
if (a.dbUser)
|
|
20
|
+
notes.push(`role: ${a.dbUser}`);
|
|
21
|
+
if (notes.length === 0)
|
|
22
|
+
notes.push('will prompt for database connection details');
|
|
23
|
+
return { writes: [], commands: [], notes };
|
|
24
|
+
},
|
|
25
|
+
async apply(_plan, ctx) {
|
|
26
|
+
const strategy = await ctx.prompter.select({
|
|
27
|
+
message: 'How will Byline connect to Postgres?',
|
|
28
|
+
options: [
|
|
29
|
+
{ value: 'existing', label: 'I have a running Postgres I will provide credentials for' },
|
|
30
|
+
{ value: 'docker', label: 'Use the bundled docker-compose to spin one up' },
|
|
31
|
+
],
|
|
32
|
+
});
|
|
33
|
+
if (strategy === 'docker') {
|
|
34
|
+
ctx.logger.warn('docker strategy is stubbed for v1 — please use --strategy existing for now');
|
|
35
|
+
return { state: 'blocked' };
|
|
36
|
+
}
|
|
37
|
+
const superuserUrl = await ctx.prompter.text({
|
|
38
|
+
message: 'Postgres superuser connection URL (used for role/database creation)',
|
|
39
|
+
placeholder: 'postgresql://postgres:postgres@127.0.0.1:5432/postgres',
|
|
40
|
+
defaultValue: 'postgresql://postgres:postgres@127.0.0.1:5432/postgres',
|
|
41
|
+
});
|
|
42
|
+
const dbName = await ctx.prompter.text({
|
|
43
|
+
message: 'Database name to create',
|
|
44
|
+
defaultValue: 'byline',
|
|
45
|
+
});
|
|
46
|
+
if (!isValidIdentifier(dbName)) {
|
|
47
|
+
ctx.logger.error(`invalid db name "${dbName}" — must match /^[a-z_][a-z0-9_]{0,62}$/`);
|
|
48
|
+
return { state: 'blocked' };
|
|
49
|
+
}
|
|
50
|
+
const dbUser = await ctx.prompter.text({
|
|
51
|
+
message: 'Application role (database user)',
|
|
52
|
+
defaultValue: 'byline',
|
|
53
|
+
});
|
|
54
|
+
if (!isValidIdentifier(dbUser)) {
|
|
55
|
+
ctx.logger.error(`invalid role "${dbUser}" — must match /^[a-z_][a-z0-9_]{0,62}$/`);
|
|
56
|
+
return { state: 'blocked' };
|
|
57
|
+
}
|
|
58
|
+
const sup = parsePgUrl(superuserUrl);
|
|
59
|
+
const spinner = ctx.prompter.spinner();
|
|
60
|
+
spinner.start(`testing superuser connection to ${sup.host}:${sup.port}`);
|
|
61
|
+
const client = new Client({ connectionString: superuserUrl });
|
|
62
|
+
try {
|
|
63
|
+
await client.connect();
|
|
64
|
+
const r = await client.query('SELECT version()');
|
|
65
|
+
spinner.stop(`connected — ${r.rows[0]?.version.split(' ').slice(0, 2).join(' ')}`);
|
|
66
|
+
}
|
|
67
|
+
catch (e) {
|
|
68
|
+
spinner.stop('connection failed');
|
|
69
|
+
ctx.logger.error(e.message);
|
|
70
|
+
return { state: 'blocked' };
|
|
71
|
+
}
|
|
72
|
+
finally {
|
|
73
|
+
await client.end().catch(() => { });
|
|
74
|
+
}
|
|
75
|
+
ctx.state.patchAnswers({
|
|
76
|
+
dbStrategy: strategy,
|
|
77
|
+
dbHost: sup.host,
|
|
78
|
+
dbPort: sup.port,
|
|
79
|
+
dbName,
|
|
80
|
+
dbUser,
|
|
81
|
+
superuserUrl,
|
|
82
|
+
});
|
|
83
|
+
ctx.logger.info(`will provision database "${dbName}" owned by role "${dbUser}"`);
|
|
84
|
+
return { state: 'done' };
|
|
85
|
+
},
|
|
86
|
+
};
|
|
87
|
+
export function isValidIdentifier(s) {
|
|
88
|
+
return /^[a-z_][a-z0-9_]{0,62}$/.test(s);
|
|
89
|
+
}
|
|
90
|
+
export function buildAppConnUrl(opts) {
|
|
91
|
+
return buildPgUrl(opts);
|
|
92
|
+
}
|
|
93
|
+
//# sourceMappingURL=db.js.map
|