@juangadm/pre-post 1.1.0 → 1.3.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 +123 -7
- package/dist/baseline.d.ts +183 -0
- package/dist/baseline.d.ts.map +1 -1
- package/dist/baseline.js +485 -16
- package/dist/baseline.js.map +1 -1
- package/dist/bin/cli.js +28 -2
- package/dist/bin/cli.js.map +1 -1
- package/dist/browser.d.ts +7 -2
- package/dist/browser.d.ts.map +1 -1
- package/dist/browser.js +66 -5
- package/dist/browser.js.map +1 -1
- package/dist/commands/doctor.d.ts.map +1 -1
- package/dist/commands/doctor.js +2 -3
- package/dist/commands/doctor.js.map +1 -1
- package/dist/commands/pr.d.ts +13 -1
- package/dist/commands/pr.d.ts.map +1 -1
- package/dist/commands/pr.js +158 -59
- package/dist/commands/pr.js.map +1 -1
- package/dist/comparison.d.ts +9 -0
- package/dist/comparison.d.ts.map +1 -1
- package/dist/comparison.js +44 -16
- package/dist/comparison.js.map +1 -1
- package/dist/errors.d.ts +7 -0
- package/dist/errors.d.ts.map +1 -1
- package/dist/errors.js +7 -0
- package/dist/errors.js.map +1 -1
- package/dist/github.d.ts +34 -3
- package/dist/github.d.ts.map +1 -1
- package/dist/github.js +102 -11
- package/dist/github.js.map +1 -1
- package/dist/report.d.ts +7 -0
- package/dist/report.d.ts.map +1 -1
- package/dist/report.js +41 -6
- package/dist/report.js.map +1 -1
- package/dist/run.d.ts.map +1 -1
- package/dist/run.js +12 -4
- package/dist/run.js.map +1 -1
- package/dist/sheet.d.ts +24 -0
- package/dist/sheet.d.ts.map +1 -0
- package/dist/sheet.js +94 -0
- package/dist/sheet.js.map +1 -0
- package/dist/timings.d.ts +46 -0
- package/dist/timings.d.ts.map +1 -0
- package/dist/timings.js +108 -0
- package/dist/timings.js.map +1 -0
- package/dist/types.d.ts +41 -0
- package/dist/types.d.ts.map +1 -1
- package/dist/types.js +17 -0
- package/dist/types.js.map +1 -1
- package/package.json +1 -1
- package/skill/SKILL.md +21 -6
package/README.md
CHANGED
|
@@ -96,25 +96,82 @@ Comment: https://github.com/acme/web/pull/42
|
|
|
96
96
|
ago, but note that it commits a deletion rather than rewriting history: the older commits
|
|
97
97
|
still hold the blobs, so a link handed out earlier keeps working. Treat anything captured
|
|
98
98
|
as permanent, and think twice before pointing pre-post at a preview holding real data.
|
|
99
|
+
See [Screenshot storage](#screenshot-storage) for how fast the branch grows.
|
|
99
100
|
6. **Describe.** The images go in a delimited block at the top of the PR description,
|
|
100
101
|
replaced in place on every run and leaving your own text untouched. Changed routes show
|
|
101
102
|
a Pre/Post crop with the full page collapsed underneath; unchanged routes fold into a
|
|
102
|
-
single line.
|
|
103
|
+
single line. A pure layout shift — nothing changed once the move is undone — has no
|
|
104
|
+
region to crop, so it shows the full pages directly under the `Content shifted down 40px.
|
|
105
|
+
Nothing else changed.` line, with no collapsed section repeating them. If the PR cannot be edited — a fork, a read-only token — it falls back to
|
|
103
106
|
one sticky comment.
|
|
104
107
|
|
|
105
108
|
## Install
|
|
106
109
|
|
|
107
|
-
|
|
108
|
-
use, the Chromium headless shell (~80 MB). You need Node 20+ and a GitHub token: either
|
|
109
|
-
`gh auth login` or `GH_TOKEN`.
|
|
110
|
+
Two ways. Neither installs anything permanently.
|
|
110
111
|
|
|
111
|
-
|
|
112
|
+
### Claude Code — easiest
|
|
112
113
|
|
|
113
114
|
```bash
|
|
114
115
|
npx skills add juangadm/pre-post -y
|
|
115
116
|
```
|
|
116
117
|
|
|
117
|
-
Then say `/pre-post` after
|
|
118
|
+
Then say `/pre-post` after a UI change. Install once, never type a flag. No npm
|
|
119
|
+
knowledge needed.
|
|
120
|
+
|
|
121
|
+
### Terminal
|
|
122
|
+
|
|
123
|
+
```bash
|
|
124
|
+
npx -y @juangadm/pre-post@latest pr
|
|
125
|
+
```
|
|
126
|
+
|
|
127
|
+
Run it on a branch with an open PR. No install step.
|
|
128
|
+
|
|
129
|
+
### Both need
|
|
130
|
+
|
|
131
|
+
| | |
|
|
132
|
+
|---|---|
|
|
133
|
+
| **Node 20+** | The one hard requirement. Check with `node --version`. |
|
|
134
|
+
| **A GitHub token** | `gh auth login`, or set `GH_TOKEN`. Needs write access — it publishes images and edits the PR. |
|
|
135
|
+
| **An open PR** | Where the images go. Without one, pre-post prints the markdown to paste. |
|
|
136
|
+
|
|
137
|
+
First run also pulls a Chromium headless shell (~80 MB), then reuses it. Stuck? Run
|
|
138
|
+
`npx -y @juangadm/pre-post@latest doctor`.
|
|
139
|
+
|
|
140
|
+
### GitHub Action: every PR, no tokens
|
|
141
|
+
|
|
142
|
+
For a team, or for work done in cloud agent sessions: GitHub runs pre-post on each push to a
|
|
143
|
+
PR and posts with the job's own token. Nobody sets up anything per person, and there are no
|
|
144
|
+
secrets to add. Add `.github/workflows/pre-post.yml`:
|
|
145
|
+
|
|
146
|
+
```yaml
|
|
147
|
+
name: pre-post
|
|
148
|
+
on: pull_request
|
|
149
|
+
permissions: { contents: write, pull-requests: write }
|
|
150
|
+
concurrency: { group: 'pre-post-${{ github.event.pull_request.number }}', cancel-in-progress: true }
|
|
151
|
+
jobs:
|
|
152
|
+
pre-post:
|
|
153
|
+
if: github.event.pull_request.head.repo.full_name == github.repository
|
|
154
|
+
runs-on: ubuntu-latest
|
|
155
|
+
steps:
|
|
156
|
+
- uses: actions/checkout@v4
|
|
157
|
+
with: { ref: '${{ github.event.pull_request.head.sha }}', fetch-depth: 0 }
|
|
158
|
+
- uses: juangadm/pre-post@v1
|
|
159
|
+
```
|
|
160
|
+
|
|
161
|
+
The runner builds the base commit and the PR's commit and serves both, the same way pre-post
|
|
162
|
+
does on a laptop with nothing deployed. No preview deployment is involved, so Vercel's
|
|
163
|
+
Deployment Protection never gets in the way.
|
|
164
|
+
|
|
165
|
+
- **Your app must start with its dev script without secrets.** If it needs environment
|
|
166
|
+
variables, give them to the job with `env:`.
|
|
167
|
+
- **pnpm or yarn** comes from the `packageManager` field in package.json. Without one, set
|
|
168
|
+
it up before the pre-post step (e.g. `pnpm/action-setup`), as any other job would.
|
|
169
|
+
- **Fork PRs are skipped:** their token cannot write, so there is nowhere to post.
|
|
170
|
+
- **Flags** go in `with: { args: '--responsive' }`.
|
|
171
|
+
- **The run's images**, including `sheet.png`, are kept as a workflow artifact even when
|
|
172
|
+
posting fails.
|
|
173
|
+
- **Pinned:** `@v1` runs the pre-post version released with that tag, never whatever npm
|
|
174
|
+
calls `latest`.
|
|
118
175
|
|
|
119
176
|
## Usage
|
|
120
177
|
|
|
@@ -156,6 +213,45 @@ Results go into a delimited block at the top of the PR description, which re-run
|
|
|
156
213
|
place, leaving your own text untouched. If the PR cannot be edited — a fork, a read-only
|
|
157
214
|
token — it falls back to a single sticky comment.
|
|
158
215
|
|
|
216
|
+
## Screenshot storage
|
|
217
|
+
|
|
218
|
+
Every real run adds one commit to the `pre-post-assets` branch holding that run's images —
|
|
219
|
+
roughly 100–200 KB for a small PR, and again on every re-run. As a rough guide, 20 PRs a
|
|
220
|
+
week at 3 runs each is about 9 MB a week, or ~450 MB a year.
|
|
221
|
+
|
|
222
|
+
Two things to know before that adds up:
|
|
223
|
+
|
|
224
|
+
- **`prune` tidies the branch; it does not shrink the repository.** It commits a deletion,
|
|
225
|
+
so the images stay in history and every link already posted in a PR keeps working. The
|
|
226
|
+
repository's size only ever grows.
|
|
227
|
+
- **A plain `git clone` downloads every branch**, screenshots included. Teammates who never
|
|
228
|
+
look at them can skip the branch in an existing clone (git 2.29+):
|
|
229
|
+
|
|
230
|
+
```bash
|
|
231
|
+
git config --add remote.origin.fetch '^refs/heads/pre-post-assets'
|
|
232
|
+
```
|
|
233
|
+
|
|
234
|
+
A weekly prune keeps the branch's own listing short. As a scheduled workflow:
|
|
235
|
+
|
|
236
|
+
```yaml
|
|
237
|
+
# .github/workflows/pre-post-prune.yml
|
|
238
|
+
on:
|
|
239
|
+
schedule: [{ cron: '17 6 * * 1' }] # Mondays
|
|
240
|
+
workflow_dispatch:
|
|
241
|
+
permissions: { contents: write, pull-requests: read }
|
|
242
|
+
jobs:
|
|
243
|
+
prune:
|
|
244
|
+
runs-on: ubuntu-latest
|
|
245
|
+
steps:
|
|
246
|
+
- uses: actions/checkout@v4
|
|
247
|
+
- run: npx -y @juangadm/pre-post@latest prune --days 90
|
|
248
|
+
env: { GITHUB_TOKEN: '${{ secrets.GITHUB_TOKEN }}' }
|
|
249
|
+
```
|
|
250
|
+
|
|
251
|
+
It removes folders for PRs closed more than 90 days ago, and runs made before a PR was
|
|
252
|
+
opened once they are that old. Actually reclaiming the space means rewriting the branch's
|
|
253
|
+
history, which also breaks the images in those older PRs — so it is left as your call.
|
|
254
|
+
|
|
159
255
|
## Configuration
|
|
160
256
|
|
|
161
257
|
Optional `.pre-post.json` in the repo root:
|
|
@@ -174,14 +270,34 @@ Optional `.pre-post.json` in the repo root:
|
|
|
174
270
|
"maxRoutes": 6,
|
|
175
271
|
"ignore": ["apps/docs"],
|
|
176
272
|
"headers": {},
|
|
177
|
-
"assetsBranch": "pre-post-assets"
|
|
273
|
+
"assetsBranch": "pre-post-assets",
|
|
274
|
+
"baselineSetup": "pnpm run build:packages"
|
|
178
275
|
}
|
|
179
276
|
```
|
|
180
277
|
|
|
278
|
+
`baselineSetup` runs in the app directory between the install and the dev server when the
|
|
279
|
+
baseline is built from source. Use it for whatever the app needs before it can boot — a
|
|
280
|
+
workspace build, a codegen step. In a turborepo it is inferred: `turbo run build
|
|
281
|
+
--filter=<app>^...`, which builds the packages the app imports and leaves the app to the
|
|
282
|
+
dev server. Setting it turns the guess off.
|
|
283
|
+
|
|
284
|
+
A command that fails stops the run with one instruction, rather than quietly comparing
|
|
285
|
+
against something else.
|
|
286
|
+
|
|
287
|
+
Env files copied into the baseline's worktree get their origin variables rewritten to the
|
|
288
|
+
port the baseline actually listens on, before the setup step runs so a build cannot bake in
|
|
289
|
+
the old one. Without this an auth-gated app rejects its own callbacks and every capture is a
|
|
290
|
+
loading skeleton. The names rewritten are the ones that can only mean the app's own address
|
|
291
|
+
— `BETTER_AUTH_URL`, `NEXTAUTH_URL`, `AUTH_URL`, `APP_URL`, `SITE_URL`, `CANONICAL_URL` and
|
|
292
|
+
their `_ORIGIN`/`_BASE_URL` forms, with a `NEXT_PUBLIC_` / `VITE_` / `PUBLIC_` prefix
|
|
293
|
+
optional. Generic names are left alone: `BASE_URL`, `SERVER_URL` and `PUBLIC_URL` are as
|
|
294
|
+
often a backend on another port or a path prefix, and `DATABASE_URL` is never an origin.
|
|
295
|
+
|
|
181
296
|
Environment:
|
|
182
297
|
|
|
183
298
|
| Variable | Purpose |
|
|
184
299
|
|---|---|
|
|
300
|
+
| `PRE_POST_GH_TOKEN` | GitHub token read before the two below. Use it where a hosted environment sets `GH_TOKEN` itself |
|
|
185
301
|
| `GH_TOKEN` / `GITHUB_TOKEN` | GitHub token (default: `gh auth token`) |
|
|
186
302
|
| `VERCEL_AUTOMATION_BYPASS_SECRET` | Bypass Vercel Deployment Protection on preview and production URLs |
|
|
187
303
|
| `PRE_POST_CONCURRENCY` | Parallel pages (default 6) |
|
package/dist/baseline.d.ts
CHANGED
|
@@ -11,6 +11,8 @@
|
|
|
11
11
|
* The cost is time: a checkout, an install and a dev-server boot. So callers
|
|
12
12
|
* reach for it after a reachable deployment, not before one.
|
|
13
13
|
*/
|
|
14
|
+
import { NeedsHumanError } from './errors.js';
|
|
15
|
+
import { Stopwatch } from './timings.js';
|
|
14
16
|
export interface LocalBaseline {
|
|
15
17
|
url: string;
|
|
16
18
|
/** Stop the dev server and delete the worktree. Safe to call twice. */
|
|
@@ -21,6 +23,26 @@ interface PackageManager {
|
|
|
21
23
|
install: string[];
|
|
22
24
|
/** Build `run <script>` argv, appending extra args the way this manager wants. */
|
|
23
25
|
run: (script: string, args: string[]) => string[];
|
|
26
|
+
/**
|
|
27
|
+
* A second install to try, and the failure that earns it — or undefined when
|
|
28
|
+
* this manager has no looser mode.
|
|
29
|
+
*
|
|
30
|
+
* Both halves together, because apart they drift: a predicate matching npm's
|
|
31
|
+
* `ERESOLVE` sitting at module scope would be applied to whichever managers
|
|
32
|
+
* happened to have a retry argv, which is right today only because npm is
|
|
33
|
+
* the only one that does.
|
|
34
|
+
*
|
|
35
|
+
* Only npm needs one. npm 7+ treats a peer range as a hard constraint and
|
|
36
|
+
* aborts the whole install over a single lagging package; pnpm, yarn and bun
|
|
37
|
+
* warn and carry on. A React 19 app with one dependency whose peer range
|
|
38
|
+
* still says <=18 is an ordinary, temporary state of a real repository — and
|
|
39
|
+
* it took the local baseline, the fallback that is supposed to always work,
|
|
40
|
+
* down with it.
|
|
41
|
+
*/
|
|
42
|
+
retry?: {
|
|
43
|
+
argv: string[];
|
|
44
|
+
when: (output: string) => boolean;
|
|
45
|
+
};
|
|
24
46
|
}
|
|
25
47
|
/**
|
|
26
48
|
* Which package manager this tree *declares*, from its `packageManager` field
|
|
@@ -84,19 +106,180 @@ export declare function servableDir(treeRoot: string, appPrefix?: string): {
|
|
|
84
106
|
* are exactly the ones that hold secrets.
|
|
85
107
|
*/
|
|
86
108
|
export declare function copyEnvFiles(from: string, to: string, appPrefix?: string): string[];
|
|
109
|
+
/** Does this variable name the app's own origin? */
|
|
110
|
+
export declare function isOriginKey(key: string): boolean;
|
|
111
|
+
/** One env file's text with every origin variable pointed at `origin`. */
|
|
112
|
+
export declare function rewriteEnvOrigins(text: string, origin: string): {
|
|
113
|
+
text: string;
|
|
114
|
+
keys: string[];
|
|
115
|
+
};
|
|
116
|
+
/**
|
|
117
|
+
* Point the worktree's copied env files at the baseline's real origin.
|
|
118
|
+
*
|
|
119
|
+
* The copies name the port the developer's own dev server uses, and the
|
|
120
|
+
* baseline is on an ephemeral one. An app whose auth library is told it lives
|
|
121
|
+
* at :3000 while it is answering on :51234 rejects its own callbacks: the page
|
|
122
|
+
* renders, the session never resolves, and every capture is a loading
|
|
123
|
+
* skeleton. That reads as success — a screenshot came back — which is the
|
|
124
|
+
* failure mode this whole file exists to avoid.
|
|
125
|
+
*
|
|
126
|
+
* Same constraint as the copy: only ever writes inside `dir`, and returns
|
|
127
|
+
* names, never values.
|
|
128
|
+
*/
|
|
129
|
+
export declare function pointEnvFilesAt(dir: string, origin: string, appPrefix?: string): string[];
|
|
87
130
|
/** An OS-assigned free port. */
|
|
88
131
|
export declare function freePort(): Promise<number>;
|
|
132
|
+
/**
|
|
133
|
+
* How a package manager's install ended, and what it said.
|
|
134
|
+
*
|
|
135
|
+
* The output is kept because it is the only thing that can answer "why". The
|
|
136
|
+
* old path discarded it (`stdio: 'ignore'`) and told the reader to run the
|
|
137
|
+
* install themselves in their checkout — advice that could not reproduce the
|
|
138
|
+
* failure, because the install had run in a throwaway worktree that was
|
|
139
|
+
* already deleted by the time they read it.
|
|
140
|
+
*/
|
|
141
|
+
export interface InstallAttempt {
|
|
142
|
+
argv: string[];
|
|
143
|
+
ok: boolean;
|
|
144
|
+
/** The tail of the manager's own stdout+stderr. */
|
|
145
|
+
output: string;
|
|
146
|
+
}
|
|
147
|
+
export interface InstallResult {
|
|
148
|
+
ok: boolean;
|
|
149
|
+
/** In order. Length 2 when a first failure earned a retry. */
|
|
150
|
+
attempts: InstallAttempt[];
|
|
151
|
+
}
|
|
152
|
+
export type InstallRunner = (bin: string, argv: string[], cwd: string, timeoutMs: number, signal?: AbortSignal) => Promise<InstallAttempt>;
|
|
153
|
+
/**
|
|
154
|
+
* Does this look like npm refusing to resolve a peer range?
|
|
155
|
+
*
|
|
156
|
+
* Matched on npm's own error code rather than on prose, so it does not depend
|
|
157
|
+
* on the wording of a given npm release. The second pattern is the same
|
|
158
|
+
* failure as reported by older npm, which does not always print the code.
|
|
159
|
+
*/
|
|
160
|
+
export declare function isPeerConflict(output: string): boolean;
|
|
161
|
+
/**
|
|
162
|
+
* Install this app's dependencies, retrying once past a peer-dependency wall.
|
|
163
|
+
*
|
|
164
|
+
* The retry is deliberately narrow: only on the specific failure that a looser
|
|
165
|
+
* resolver would not have had, and only for a manager that has a looser mode.
|
|
166
|
+
* A baseline installed with `--legacy-peer-deps` is not a perfect reproduction
|
|
167
|
+
* of the branch's own install — but the alternative is no baseline at all, and
|
|
168
|
+
* the comparison this tool exists to make is between two renders of the same
|
|
169
|
+
* app, not between two dependency trees.
|
|
170
|
+
*/
|
|
171
|
+
export declare function installDeps(pm: PackageManager, cwd: string, timeoutMs: number, run?: InstallRunner, signal?: AbortSignal): Promise<InstallResult>;
|
|
172
|
+
/**
|
|
173
|
+
* The install failed and nothing else can rescue this run.
|
|
174
|
+
*
|
|
175
|
+
* Its own error rather than a quiet null, for the reason docs/portability.md
|
|
176
|
+
* §1 gives about base resolution: a run that compared nothing must not exit
|
|
177
|
+
* clean. A null here fell through to "no baseline", and on a repository with a
|
|
178
|
+
* configured production URL it fell through to comparing against that instead
|
|
179
|
+
* — a different answer to a different question, published as if it were this
|
|
180
|
+
* one.
|
|
181
|
+
*/
|
|
182
|
+
/**
|
|
183
|
+
* What a reader has to do about a failed install, in one sentence.
|
|
184
|
+
*
|
|
185
|
+
* One sentence because that is what `NeedsHumanError` is for (AGENTS.md): the
|
|
186
|
+
* CLI prints the whole message for exit 3, so pasting a screen of package
|
|
187
|
+
* manager output here would bury the instruction inside it. The output is
|
|
188
|
+
* still the thing that answers "why", so it goes to the log instead — above
|
|
189
|
+
* this line, where it reads as diagnostics rather than as the remedy.
|
|
190
|
+
*
|
|
191
|
+
* The command names the caller's own directory, never the worktree: by the
|
|
192
|
+
* time anyone reads this, cleanup has deleted the worktree, so telling them to
|
|
193
|
+
* run it there would be an instruction they cannot follow.
|
|
194
|
+
*/
|
|
195
|
+
export declare function installFailureHint(where: string, ranIn: string): string;
|
|
196
|
+
export declare class BaselineInstallError extends NeedsHumanError {
|
|
197
|
+
readonly result: InstallResult;
|
|
198
|
+
constructor(result: InstallResult, where: string, ranIn: string);
|
|
199
|
+
}
|
|
200
|
+
/** A command to run between the install and the dev server. */
|
|
201
|
+
export interface SetupStep {
|
|
202
|
+
/** The command as a reader would type it, for the log. */
|
|
203
|
+
label: string;
|
|
204
|
+
bin: string;
|
|
205
|
+
argv: string[];
|
|
206
|
+
cwd: string;
|
|
207
|
+
/** Run through a shell, for a command a human wrote as one string. */
|
|
208
|
+
shell?: boolean;
|
|
209
|
+
}
|
|
210
|
+
/**
|
|
211
|
+
* Build the workspace packages the app imports, before the dev server starts.
|
|
212
|
+
*
|
|
213
|
+
* A monorepo app depends on sibling packages that ship compiled output, and a
|
|
214
|
+
* fresh install does not produce it — `turbo dev` normally would, but the dev
|
|
215
|
+
* script this file runs is the app's own. So the app boots against a package
|
|
216
|
+
* with no `dist`, and the baseline is an error page or a shell.
|
|
217
|
+
*
|
|
218
|
+
* `^...` is turbo's "dependencies of, excluding itself": the siblings get
|
|
219
|
+
* built, the app is left to the dev server.
|
|
220
|
+
*/
|
|
221
|
+
export declare function turboDependencyBuild(treeRoot: string, appDir: string): SetupStep | null;
|
|
222
|
+
/**
|
|
223
|
+
* What to run between install and dev: `baselineSetup` if the repository
|
|
224
|
+
* configured one, else turbo's dependency build when this is a turborepo.
|
|
225
|
+
*
|
|
226
|
+
* The configured command wins outright. It is the general answer — one line in
|
|
227
|
+
* `.pre-post.json` for a repository whose baseline needs a codegen step, a
|
|
228
|
+
* prisma generate, a build this tool has never heard of — and a repository
|
|
229
|
+
* that names one has already told us the guess is not wanted.
|
|
230
|
+
*/
|
|
231
|
+
export declare function setupStep(treeRoot: string, appDir: string, configured?: string): SetupStep | null;
|
|
232
|
+
/**
|
|
233
|
+
* The configured setup command failed, and nothing else can rescue this run.
|
|
234
|
+
*
|
|
235
|
+
* One sentence, and the output goes to the log above it, for the reason
|
|
236
|
+
* `installFailureHint` gives. The directory named is the caller's own, never
|
|
237
|
+
* the worktree: cleanup has deleted the worktree by the time anyone reads it.
|
|
238
|
+
*/
|
|
239
|
+
export declare function setupFailureHint(label: string, ranIn: string): string;
|
|
240
|
+
export declare class BaselineSetupError extends NeedsHumanError {
|
|
241
|
+
constructor(label: string, ranIn: string);
|
|
242
|
+
}
|
|
243
|
+
/**
|
|
244
|
+
* Can the base commit use the dependencies this checkout already installed?
|
|
245
|
+
*
|
|
246
|
+
* Only when no install input differs between the base and the working tree,
|
|
247
|
+
* uncommitted edits included, and a lockfile is tracked (without one there is
|
|
248
|
+
* nothing to prove the trees match). Returns the package directories whose
|
|
249
|
+
* node_modules to bring across, or null to install as usual. Once the diff is
|
|
250
|
+
* clean, the index lists the same package.json files the base has, so it
|
|
251
|
+
* answers that without walking the base commit's whole tree.
|
|
252
|
+
*/
|
|
253
|
+
export declare function reusableInstall(repoRoot: string, sha: string): Promise<string[] | null>;
|
|
254
|
+
/**
|
|
255
|
+
* Bring this checkout's installed dependencies into the base worktree.
|
|
256
|
+
* True when every one was copied; on any failure the partial copies are
|
|
257
|
+
* removed so the normal install starts from a clean tree.
|
|
258
|
+
*/
|
|
259
|
+
export declare function reuseInstall(repoRoot: string, worktree: string, dirs: string[]): Promise<boolean>;
|
|
89
260
|
export interface BaselineOptions {
|
|
90
261
|
repoRoot: string;
|
|
91
262
|
/** Commit to serve. Omit to serve the working tree as it stands. */
|
|
92
263
|
sha?: string;
|
|
93
264
|
/** Directory holding the app's package.json, relative to the repo root. */
|
|
94
265
|
appPrefix?: string;
|
|
266
|
+
/**
|
|
267
|
+
* Command to run between the install and the dev server, from
|
|
268
|
+
* `.pre-post.json`. Omit to let a turborepo's dependency build be inferred.
|
|
269
|
+
*/
|
|
270
|
+
setup?: string;
|
|
95
271
|
/** Budget for install + boot. */
|
|
96
272
|
timeoutMs?: number;
|
|
97
273
|
/** Injectable for tests; defaults to a real PATH scan. */
|
|
98
274
|
pathHas?: (bin: string) => boolean;
|
|
99
275
|
log?: (msg: string) => void;
|
|
276
|
+
/** Records how long each step took, under `pre.*` or `post.*`. */
|
|
277
|
+
timings?: Stopwatch;
|
|
278
|
+
/**
|
|
279
|
+
* Abort the boot: the caller no longer needs this side. Whatever it started
|
|
280
|
+
* is stopped and cleaned up, and it resolves null.
|
|
281
|
+
*/
|
|
282
|
+
signal?: AbortSignal;
|
|
100
283
|
}
|
|
101
284
|
/**
|
|
102
285
|
* Check out `sha` into a throwaway worktree, install, and start its dev server.
|
package/dist/baseline.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"baseline.d.ts","sourceRoot":"","sources":["../src/baseline.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;
|
|
1
|
+
{"version":3,"file":"baseline.d.ts","sourceRoot":"","sources":["../src/baseline.ts"],"names":[],"mappings":"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"}
|