create-backbone-template 0.1.0
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/README.md +33 -0
- package/bin/create-backbone-template.js +5 -0
- package/package.json +30 -0
- package/src/create-backbone-template.js +204 -0
- package/template/.agents/skills/agent-browser/SKILL.md +55 -0
- package/template/.agents/skills/create-plan/SKILL.md +52 -0
- package/template/.agents/skills/create-plan/agents/openai.yaml +4 -0
- package/template/.agents/skills/create-pr-presentation/SKILL.md +86 -0
- package/template/.agents/skills/create-pr-presentation/agents/openai.yaml +4 -0
- package/template/.agents/skills/implement-plan/SKILL.md +26 -0
- package/template/.agents/skills/implement-plan/agents/openai.yaml +4 -0
- package/template/.agents/skills/review-plan/SKILL.md +38 -0
- package/template/.agents/skills/review-plan/agents/openai.yaml +4 -0
- package/template/.env.schema +30 -0
- package/template/.env.test +6 -0
- package/template/.oxlintrc.json +67 -0
- package/template/.vscode/extensions.json +3 -0
- package/template/.vscode/settings.json +23 -0
- package/template/AGENTS.md +55 -0
- package/template/Cargo.lock +2648 -0
- package/template/Cargo.toml +29 -0
- package/template/Justfile +140 -0
- package/template/README.md +72 -0
- package/template/TODO.md +1 -0
- package/template/_gitignore +12 -0
- package/template/buf.gen.yaml +7 -0
- package/template/buf.yaml +10 -0
- package/template/client/.oxfmtrc.json +8 -0
- package/template/client/.oxlintrc.json +57 -0
- package/template/client/README.md +19 -0
- package/template/client/_gitignore +5 -0
- package/template/client/index.html +12 -0
- package/template/client/package.json +47 -0
- package/template/client/packages/design-system/package.json +19 -0
- package/template/client/packages/design-system/src/index.ts +2 -0
- package/template/client/packages/design-system-basic/package.json +18 -0
- package/template/client/packages/design-system-basic/src/button.stories.tsx +50 -0
- package/template/client/packages/design-system-basic/src/button.tsx +26 -0
- package/template/client/packages/design-system-basic/src/empty-state.stories.tsx +18 -0
- package/template/client/packages/design-system-basic/src/empty-state.tsx +17 -0
- package/template/client/packages/design-system-basic/src/form-field.stories.tsx +15 -0
- package/template/client/packages/design-system-basic/src/form-field.tsx +10 -0
- package/template/client/packages/design-system-basic/src/form.stories.tsx +27 -0
- package/template/client/packages/design-system-basic/src/form.tsx +9 -0
- package/template/client/packages/design-system-basic/src/heading.stories.tsx +14 -0
- package/template/client/packages/design-system-basic/src/heading.tsx +25 -0
- package/template/client/packages/design-system-basic/src/index.tsx +15 -0
- package/template/client/packages/design-system-basic/src/inline.stories.tsx +13 -0
- package/template/client/packages/design-system-basic/src/inline.tsx +5 -0
- package/template/client/packages/design-system-basic/src/layout.stories.tsx +24 -0
- package/template/client/packages/design-system-basic/src/layout.tsx +14 -0
- package/template/client/packages/design-system-basic/src/loader.stories.tsx +8 -0
- package/template/client/packages/design-system-basic/src/loader.tsx +11 -0
- package/template/client/packages/design-system-basic/src/navigation.stories.tsx +16 -0
- package/template/client/packages/design-system-basic/src/navigation.tsx +18 -0
- package/template/client/packages/design-system-basic/src/notice.stories.tsx +13 -0
- package/template/client/packages/design-system-basic/src/notice.tsx +5 -0
- package/template/client/packages/design-system-basic/src/stack.stories.tsx +17 -0
- package/template/client/packages/design-system-basic/src/stack.tsx +5 -0
- package/template/client/packages/design-system-basic/src/styles.css +254 -0
- package/template/client/packages/design-system-basic/src/text-input.stories.tsx +13 -0
- package/template/client/packages/design-system-basic/src/text-input.tsx +5 -0
- package/template/client/packages/design-system-basic/src/text.stories.tsx +21 -0
- package/template/client/packages/design-system-basic/src/text.tsx +5 -0
- package/template/client/packages/design-system-contract/package.json +15 -0
- package/template/client/packages/design-system-contract/src/button.ts +10 -0
- package/template/client/packages/design-system-contract/src/empty-state.ts +9 -0
- package/template/client/packages/design-system-contract/src/form-field.ts +9 -0
- package/template/client/packages/design-system-contract/src/form.ts +9 -0
- package/template/client/packages/design-system-contract/src/heading.ts +9 -0
- package/template/client/packages/design-system-contract/src/index.ts +13 -0
- package/template/client/packages/design-system-contract/src/inline.ts +7 -0
- package/template/client/packages/design-system-contract/src/layout.ts +8 -0
- package/template/client/packages/design-system-contract/src/loader.ts +7 -0
- package/template/client/packages/design-system-contract/src/navigation.ts +13 -0
- package/template/client/packages/design-system-contract/src/notice.ts +8 -0
- package/template/client/packages/design-system-contract/src/stack.ts +8 -0
- package/template/client/packages/design-system-contract/src/text-input.ts +5 -0
- package/template/client/packages/design-system-contract/src/text.ts +9 -0
- package/template/client/packages/design-system-lint/fixtures/invalid/external-ui-import.tsx +5 -0
- package/template/client/packages/design-system-lint/fixtures/invalid/raw-dom-jsx.tsx +3 -0
- package/template/client/packages/design-system-lint/fixtures/invalid/two-violations.tsx +7 -0
- package/template/client/packages/design-system-lint/fixtures/valid/design-system-only.tsx +13 -0
- package/template/client/packages/design-system-lint/package.json +23 -0
- package/template/client/packages/design-system-lint/src/check-design-system-architecture.ts +22 -0
- package/template/client/packages/design-system-lint/src/design-system-architecture.ts +286 -0
- package/template/client/packages/design-system-lint/src/oxlint-plugin.ts +11 -0
- package/template/client/packages/design-system-lint/src/page-architecture.ts +382 -0
- package/template/client/packages/design-system-lint/src/rules.ts +111 -0
- package/template/client/packages/design-system-lint/test/design-system-architecture.test.ts +243 -0
- package/template/client/packages/design-system-lint/test/oxlint-fixtures.test.ts +159 -0
- package/template/client/packages/design-system-lint/test/page-architecture.test.ts +175 -0
- package/template/client/packages/design-system-lint/test/rules.test.ts +65 -0
- package/template/client/packages/design-system-lint/tsconfig.json +29 -0
- package/template/client/src/App.tsx +77 -0
- package/template/client/src/design-system-components.test.tsx +75 -0
- package/template/client/src/gen/helloworld/v1/helloworld_pb.ts +63 -0
- package/template/client/src/main.tsx +18 -0
- package/template/client/src/pages/hello/hello-page.stories.tsx +20 -0
- package/template/client/src/pages/hello/hello-page.test.tsx +90 -0
- package/template/client/src/pages/hello/hello-page.tsx +126 -0
- package/template/client/src/pages/page.ts +20 -0
- package/template/client/src/testing/create-preview-events.test.ts +36 -0
- package/template/client/src/testing/create-preview-events.ts +30 -0
- package/template/client/src/vite-env.d.ts +1 -0
- package/template/client/tsconfig.json +32 -0
- package/template/client/vite.config.ts +21 -0
- package/template/client/vite.ladle.config.ts +5 -0
- package/template/e2e/.gherkin-lintrc +20 -0
- package/template/e2e/.oxfmtrc.json +15 -0
- package/template/e2e/.oxlintrc.json +37 -0
- package/template/e2e/_gitignore +4 -0
- package/template/e2e/features/helloworld.feature +10 -0
- package/template/e2e/package.json +42 -0
- package/template/e2e/playwright.config.ts +16 -0
- package/template/e2e/support/app-gherkin.ts +4 -0
- package/template/e2e/support/fixtures.ts +236 -0
- package/template/e2e/support/gherkin-fixtures/duplicate-id.feature +9 -0
- package/template/e2e/support/gherkin-fixtures/duplicate-id.spec.ts +7 -0
- package/template/e2e/support/gherkin-fixtures/extra-implementation.spec.ts +7 -0
- package/template/e2e/support/gherkin-fixtures/extra-step.spec.ts +10 -0
- package/template/e2e/support/gherkin-fixtures/happy-path.spec.ts +4 -0
- package/template/e2e/support/gherkin-fixtures/missing-id.feature +4 -0
- package/template/e2e/support/gherkin-fixtures/missing-id.spec.ts +7 -0
- package/template/e2e/support/gherkin-fixtures/missing-implementation.spec.ts +7 -0
- package/template/e2e/support/gherkin-fixtures/missing-step.spec.ts +7 -0
- package/template/e2e/support/gherkin-fixtures/playwright.config.ts +7 -0
- package/template/e2e/support/gherkin-fixtures/scenario-outline.feature +9 -0
- package/template/e2e/support/gherkin-fixtures/scenario-outline.spec.ts +7 -0
- package/template/e2e/support/gherkin-fixtures/step-mismatch.spec.ts +9 -0
- package/template/e2e/support/gherkin-fixtures/valid-implementations.ts +23 -0
- package/template/e2e/support/gherkin-fixtures/valid-scenarios.feature +26 -0
- package/template/e2e/support/gherkin.test.ts +184 -0
- package/template/e2e/support/gherkin.ts +321 -0
- package/template/e2e/support/oxlint-plugin.test.ts +328 -0
- package/template/e2e/support/oxlint-plugin.ts +485 -0
- package/template/e2e/tests/helloworld.spec.ts +39 -0
- package/template/e2e/tsconfig.json +26 -0
- package/template/e2e/tsconfig.oxlint-plugin.json +12 -0
- package/template/package.json +9 -0
- package/template/pnpm-lock.yaml +10723 -0
- package/template/pnpm-workspace.yaml +8 -0
- package/template/pr-slide/README.md +95 -0
- package/template/pr-slide/package.json +23 -0
- package/template/pr-slide/src/cli.js +262 -0
- package/template/pr-slide/src/generate-pr-deck.js +833 -0
- package/template/pr-slide/src/git-context.js +91 -0
- package/template/pr-slide/src/presentation-paths.js +9 -0
- package/template/pr-slide/src/presentations.js +53 -0
- package/template/pr-slide/test/generate-pr-deck.test.js +118 -0
- package/template/pr-slide/test/presentation-paths.test.js +14 -0
- package/template/pr-slide/test/presentations.test.js +50 -0
- package/template/proto/helloworld/v1/helloworld.proto +15 -0
- package/template/scripts/run-e2e.sh +10 -0
- package/template/server/Cargo.toml +26 -0
- package/template/server/build.rs +9 -0
- package/template/server/dylint/backbone_server_lints/.cargo/config.toml +6 -0
- package/template/server/dylint/backbone_server_lints/Cargo.lock +1581 -0
- package/template/server/dylint/backbone_server_lints/Cargo.toml +21 -0
- package/template/server/dylint/backbone_server_lints/README.md +5 -0
- package/template/server/dylint/backbone_server_lints/_gitignore +1 -0
- package/template/server/dylint/backbone_server_lints/rust-toolchain +3 -0
- package/template/server/dylint/backbone_server_lints/src/lib.rs +612 -0
- package/template/server/dylint/backbone_server_lints/ui/lib.rs +4 -0
- package/template/server/dylint/backbone_server_lints/ui/lib.stderr +10 -0
- package/template/server/dylint/backbone_server_lints/ui/long_file.rs +303 -0
- package/template/server/dylint/backbone_server_lints/ui/long_file.stderr +6 -0
- package/template/server/dylint/backbone_server_lints/ui/main.rs +59 -0
- package/template/server/dylint/backbone_server_lints/ui/main.stderr +85 -0
- package/template/server/migrations/20260520120000_create_projects.sql +12 -0
- package/template/server/migrations/20260524160000_create_hello_world_inputs.sql +12 -0
- package/template/server/src/config.rs +27 -0
- package/template/server/src/db/hello_world.rs +34 -0
- package/template/server/src/db/hello_world_tests.rs +11 -0
- package/template/server/src/db/mod.rs +39 -0
- package/template/server/src/lib.rs +10 -0
- package/template/server/src/main.rs +43 -0
- package/template/server/src/rpc/greeter/mod.rs +31 -0
- package/template/server/src/rpc/greeter/say_hello.rs +27 -0
- package/template/server/src/rpc/mod.rs +8 -0
- package/template/server/src/state.rs +13 -0
- package/template/skills-lock.json +11 -0
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
# PR Slide
|
|
2
|
+
|
|
3
|
+
Slidev workspace for generating and watching PR presentations from the current branch.
|
|
4
|
+
|
|
5
|
+
## Generate The Deck
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
just pr-slide-generate
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
This creates:
|
|
12
|
+
|
|
13
|
+
```text
|
|
14
|
+
.agents/pr-presentation/<branch-name>/slides.md
|
|
15
|
+
.agents/pr-presentation/<branch-name>/manifest.json
|
|
16
|
+
```
|
|
17
|
+
|
|
18
|
+
Branch names are normalized into one directory. For example, `feat/hello-history` becomes:
|
|
19
|
+
|
|
20
|
+
```text
|
|
21
|
+
.agents/pr-presentation/feat-hello-history/slides.md
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
## Watch The Presentation
|
|
25
|
+
|
|
26
|
+
```bash
|
|
27
|
+
just pr-slide
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
This regenerates the current branch deck and starts Slidev dev mode. The terminal prints the local URLs, usually:
|
|
31
|
+
|
|
32
|
+
```text
|
|
33
|
+
http://localhost:3030/
|
|
34
|
+
http://localhost:3030/presenter/
|
|
35
|
+
http://localhost:3030/overview/
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
You can pass Slidev options through pnpm when needed:
|
|
39
|
+
|
|
40
|
+
```bash
|
|
41
|
+
pnpm --filter @backbone/pr-slide run dev -- --port 3031
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
## List Presentations
|
|
45
|
+
|
|
46
|
+
```bash
|
|
47
|
+
just pr-slide-list
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
This prints every generated deck under:
|
|
51
|
+
|
|
52
|
+
```text
|
|
53
|
+
.agents/pr-presentation/
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
## Open A Specific Presentation
|
|
57
|
+
|
|
58
|
+
```bash
|
|
59
|
+
just pr-slide-open feat-hello-history
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
This opens an existing deck without regenerating the current branch deck.
|
|
63
|
+
|
|
64
|
+
You can pass Slidev options through the lower-level command:
|
|
65
|
+
|
|
66
|
+
```bash
|
|
67
|
+
pnpm --filter @backbone/pr-slide run open -- feat-hello-history --port 3031
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
## Edit The Slides
|
|
71
|
+
|
|
72
|
+
Edit the generated `slides.md` directly:
|
|
73
|
+
|
|
74
|
+
```text
|
|
75
|
+
.agents/pr-presentation/<branch-name>/slides.md
|
|
76
|
+
```
|
|
77
|
+
|
|
78
|
+
Regenerating will overwrite the deck, so keep manual polish for the final pass after the generated structure looks right.
|
|
79
|
+
|
|
80
|
+
## Export
|
|
81
|
+
|
|
82
|
+
```bash
|
|
83
|
+
pnpm --filter @backbone/pr-slide run export -- --format pptx
|
|
84
|
+
```
|
|
85
|
+
|
|
86
|
+
Other useful export formats are `pdf`, `png`, and `md`.
|
|
87
|
+
|
|
88
|
+
## Generator Options
|
|
89
|
+
|
|
90
|
+
```bash
|
|
91
|
+
pnpm --filter @backbone/pr-slide run generate -- --title "Catchy PR Title"
|
|
92
|
+
pnpm --filter @backbone/pr-slide run generate -- --purpose "What reviewers should remember."
|
|
93
|
+
pnpm --filter @backbone/pr-slide run generate -- --git-base main
|
|
94
|
+
pnpm --filter @backbone/pr-slide run generate -- --deck-out .agents/pr-presentation/custom-name
|
|
95
|
+
```
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@backbone/pr-slide",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"private": true,
|
|
5
|
+
"type": "module",
|
|
6
|
+
"scripts": {
|
|
7
|
+
"generate": "node src/cli.js generate",
|
|
8
|
+
"list": "node src/cli.js list",
|
|
9
|
+
"open": "node src/cli.js open",
|
|
10
|
+
"dev": "node src/cli.js dev",
|
|
11
|
+
"build": "node src/cli.js build",
|
|
12
|
+
"export": "node src/cli.js export",
|
|
13
|
+
"test": "vitest run"
|
|
14
|
+
},
|
|
15
|
+
"dependencies": {
|
|
16
|
+
"@slidev/cli": "^52.4.0",
|
|
17
|
+
"@slidev/theme-default": "^0.25.0"
|
|
18
|
+
},
|
|
19
|
+
"devDependencies": {
|
|
20
|
+
"vitest": "^4.0.14"
|
|
21
|
+
},
|
|
22
|
+
"packageManager": "pnpm@10.22.0"
|
|
23
|
+
}
|
|
@@ -0,0 +1,262 @@
|
|
|
1
|
+
import { existsSync, mkdirSync, readFileSync, writeFileSync } from "node:fs";
|
|
2
|
+
import { dirname, join, resolve } from "node:path";
|
|
3
|
+
import { fileURLToPath } from "node:url";
|
|
4
|
+
import { spawnSync } from "node:child_process";
|
|
5
|
+
|
|
6
|
+
import { buildDeck } from "./generate-pr-deck.js";
|
|
7
|
+
import { collectGitContext } from "./git-context.js";
|
|
8
|
+
import { branchToPresentationDirName } from "./presentation-paths.js";
|
|
9
|
+
import {
|
|
10
|
+
listPresentations,
|
|
11
|
+
resolvePresentationSlidesPath,
|
|
12
|
+
} from "./presentations.js";
|
|
13
|
+
|
|
14
|
+
const packageRoot = dirname(dirname(fileURLToPath(import.meta.url)));
|
|
15
|
+
const repoRoot = resolve(packageRoot, "..");
|
|
16
|
+
const presentationRoot = join(repoRoot, ".agents", "pr-presentation");
|
|
17
|
+
const command = process.argv[2] ?? "dev";
|
|
18
|
+
const args = process.argv.slice(3);
|
|
19
|
+
|
|
20
|
+
if (command === "generate") {
|
|
21
|
+
const output = writeCurrentDeck(parseOptions(args));
|
|
22
|
+
console.log(output.slidesPath);
|
|
23
|
+
} else if (command === "list") {
|
|
24
|
+
printPresentations();
|
|
25
|
+
} else if (command === "open") {
|
|
26
|
+
openPresentation(args);
|
|
27
|
+
} else if (command === "dev" || command === "build" || command === "export") {
|
|
28
|
+
const output = writeCurrentDeck(parseOptions(args));
|
|
29
|
+
runSlidev(command, output.slidesPath, args);
|
|
30
|
+
} else {
|
|
31
|
+
console.error(`Unknown command: ${command}`);
|
|
32
|
+
process.exit(1);
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
export function writeCurrentDeck(options = {}) {
|
|
36
|
+
const context = collectGitContext(options);
|
|
37
|
+
const deckDir = resolve(
|
|
38
|
+
repoRoot,
|
|
39
|
+
options.out ??
|
|
40
|
+
join(presentationRoot, branchToPresentationDirName(context.branch)),
|
|
41
|
+
);
|
|
42
|
+
enrichContextWithAssets(context, deckDir);
|
|
43
|
+
const markdown = buildDeck(context);
|
|
44
|
+
const slidesPath = join(deckDir, "slides.md");
|
|
45
|
+
const manifestPath = join(deckDir, "manifest.json");
|
|
46
|
+
|
|
47
|
+
mkdirSync(deckDir, { recursive: true });
|
|
48
|
+
writeFileSync(slidesPath, markdown);
|
|
49
|
+
writeFileSync(
|
|
50
|
+
manifestPath,
|
|
51
|
+
JSON.stringify(
|
|
52
|
+
{
|
|
53
|
+
title: context.title,
|
|
54
|
+
branch: context.branch,
|
|
55
|
+
base: context.base,
|
|
56
|
+
generatedAt: context.generatedAt.toISOString(),
|
|
57
|
+
changedFiles: context.changedFiles,
|
|
58
|
+
},
|
|
59
|
+
null,
|
|
60
|
+
2,
|
|
61
|
+
) + "\n",
|
|
62
|
+
);
|
|
63
|
+
|
|
64
|
+
return { slidesPath, manifestPath };
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
function enrichContextWithAssets(context, deckDir) {
|
|
68
|
+
const sections = context.sections ?? {};
|
|
69
|
+
|
|
70
|
+
for (const items of Object.values(sections)) {
|
|
71
|
+
for (const item of items) {
|
|
72
|
+
const asset = findItemAsset(deckDir, item);
|
|
73
|
+
|
|
74
|
+
if (asset) {
|
|
75
|
+
item.image = asset;
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
enrichItemFromFile(item);
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
function enrichItemFromFile(item) {
|
|
84
|
+
if (!item.detail || !existsSync(join(repoRoot, item.detail))) {
|
|
85
|
+
return;
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
if (item.detail.endsWith(".proto")) {
|
|
89
|
+
item.protoServices = parseProtoServices(readFileSync(join(repoRoot, item.detail), "utf8"));
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
if (item.detail.includes("/migrations/") && item.detail.endsWith(".sql")) {
|
|
93
|
+
item.migrationSummary = summarizeMigrationSql(
|
|
94
|
+
readFileSync(join(repoRoot, item.detail), "utf8"),
|
|
95
|
+
);
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
function parseProtoServices(source) {
|
|
100
|
+
const services = [];
|
|
101
|
+
const servicePattern = /service\s+(\w+)\s*\{([\s\S]*?)\}/g;
|
|
102
|
+
|
|
103
|
+
for (const match of source.matchAll(servicePattern)) {
|
|
104
|
+
const [, name, body] = match;
|
|
105
|
+
const rpcs = [...body.matchAll(/rpc\s+(\w+)\s*\((\w+)\)\s+returns\s+\((\w+)\)/g)].map(
|
|
106
|
+
(rpcMatch) => ({
|
|
107
|
+
name: rpcMatch[1],
|
|
108
|
+
request: rpcMatch[2],
|
|
109
|
+
response: rpcMatch[3],
|
|
110
|
+
description: describeRpc(rpcMatch[1]),
|
|
111
|
+
}),
|
|
112
|
+
);
|
|
113
|
+
|
|
114
|
+
services.push({ name, rpcs });
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
return services;
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
function describeRpc(name) {
|
|
121
|
+
const descriptions = {
|
|
122
|
+
SayHello: "returns a greeting for the submitted name.",
|
|
123
|
+
};
|
|
124
|
+
|
|
125
|
+
return descriptions[name] ?? `${humanizeIdentifier(name).toLowerCase()}.`;
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
function summarizeMigrationSql(source) {
|
|
129
|
+
const statements = [];
|
|
130
|
+
|
|
131
|
+
for (const match of source.matchAll(/ALTER TABLE\s+(\w+)\s+ADD COLUMN\s+(\w+)/gi)) {
|
|
132
|
+
statements.push(`Adds \`${match[2]}\` to \`${match[1]}\`.`);
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
for (const match of source.matchAll(/UPDATE\s+(\w+)\s+SET\s+([^;]+)/gi)) {
|
|
136
|
+
statements.push(`Backfills \`${match[1]}\` rows with ${match[2].trim().replace(/\s+/g, " ")}.`);
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
return statements.length > 0 ? statements : ["Updates the database schema for this PR."];
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
function humanizeIdentifier(value) {
|
|
143
|
+
return value
|
|
144
|
+
.replace(/([a-z0-9])([A-Z])/g, "$1 $2")
|
|
145
|
+
.replace(/_/g, " ")
|
|
146
|
+
.trim();
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
function findItemAsset(deckDir, item) {
|
|
150
|
+
const candidates = [
|
|
151
|
+
item.label,
|
|
152
|
+
item.label.replace(/:.*$/, ""),
|
|
153
|
+
item.detail?.split("/").at(-1)?.replace(/\.[^.]+$/, ""),
|
|
154
|
+
].filter(Boolean);
|
|
155
|
+
|
|
156
|
+
for (const candidate of candidates) {
|
|
157
|
+
const relativePath = `assets/${slug(candidate)}.png`;
|
|
158
|
+
|
|
159
|
+
if (existsSync(join(deckDir, relativePath))) {
|
|
160
|
+
return `./${relativePath}`;
|
|
161
|
+
}
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
return undefined;
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
function slug(value) {
|
|
168
|
+
return value
|
|
169
|
+
.toLowerCase()
|
|
170
|
+
.replace(/[^a-z0-9]+/g, "-")
|
|
171
|
+
.replace(/^-+|-+$/g, "");
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
function printPresentations() {
|
|
175
|
+
const presentations = listPresentations(presentationRoot);
|
|
176
|
+
|
|
177
|
+
if (presentations.length === 0) {
|
|
178
|
+
console.log("No PR presentations found.");
|
|
179
|
+
return;
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
for (const presentation of presentations) {
|
|
183
|
+
const branch = presentation.branch ? ` (${presentation.branch})` : "";
|
|
184
|
+
console.log(`${presentation.name}${branch} - ${presentation.title}`);
|
|
185
|
+
}
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
function openPresentation(values) {
|
|
189
|
+
const openArgs = values[0] === "--" ? values.slice(1) : values;
|
|
190
|
+
const name = openArgs[0];
|
|
191
|
+
|
|
192
|
+
if (!name) {
|
|
193
|
+
console.error("Usage: pnpm --filter @backbone/pr-slide run open -- <name>");
|
|
194
|
+
process.exit(1);
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
const slidesPath = resolvePresentationSlidesPath(presentationRoot, name);
|
|
198
|
+
runSlidev("dev", slidesPath, openArgs.slice(1));
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
function runSlidev(slidevCommand, slidesPath, originalArgs) {
|
|
202
|
+
const passthrough = stripLocalOptions(originalArgs);
|
|
203
|
+
const themeArgs = passthrough.includes("--theme")
|
|
204
|
+
? []
|
|
205
|
+
: ["--theme", join(packageRoot, "node_modules", "@slidev", "theme-default")];
|
|
206
|
+
const commandArgs =
|
|
207
|
+
slidevCommand === "dev" ? [slidesPath] : [slidevCommand, slidesPath];
|
|
208
|
+
const result = spawnSync(
|
|
209
|
+
"pnpm",
|
|
210
|
+
["exec", "slidev", ...commandArgs, ...themeArgs, ...passthrough],
|
|
211
|
+
{
|
|
212
|
+
cwd: packageRoot,
|
|
213
|
+
stdio: "inherit",
|
|
214
|
+
},
|
|
215
|
+
);
|
|
216
|
+
|
|
217
|
+
process.exit(result.status ?? 1);
|
|
218
|
+
}
|
|
219
|
+
|
|
220
|
+
function parseOptions(values) {
|
|
221
|
+
const options = {};
|
|
222
|
+
|
|
223
|
+
for (let index = 0; index < values.length; index += 1) {
|
|
224
|
+
const value = values[index];
|
|
225
|
+
|
|
226
|
+
if (value === "--git-base") {
|
|
227
|
+
options.base = values[index + 1];
|
|
228
|
+
index += 1;
|
|
229
|
+
} else if (value === "--title") {
|
|
230
|
+
options.title = values[index + 1];
|
|
231
|
+
index += 1;
|
|
232
|
+
} else if (value === "--purpose") {
|
|
233
|
+
options.purpose = values[index + 1];
|
|
234
|
+
index += 1;
|
|
235
|
+
} else if (value === "--deck-out") {
|
|
236
|
+
options.out = values[index + 1];
|
|
237
|
+
index += 1;
|
|
238
|
+
}
|
|
239
|
+
}
|
|
240
|
+
|
|
241
|
+
return options;
|
|
242
|
+
}
|
|
243
|
+
|
|
244
|
+
function stripLocalOptions(values) {
|
|
245
|
+
const stripped = [];
|
|
246
|
+
|
|
247
|
+
for (let index = 0; index < values.length; index += 1) {
|
|
248
|
+
const value = values[index];
|
|
249
|
+
|
|
250
|
+
if (value === "--") {
|
|
251
|
+
continue;
|
|
252
|
+
}
|
|
253
|
+
|
|
254
|
+
if (["--git-base", "--title", "--purpose", "--deck-out"].includes(value)) {
|
|
255
|
+
index += 1;
|
|
256
|
+
} else {
|
|
257
|
+
stripped.push(value);
|
|
258
|
+
}
|
|
259
|
+
}
|
|
260
|
+
|
|
261
|
+
return stripped;
|
|
262
|
+
}
|