gutterpress 0.0.0 → 0.9.0-alpha.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +21 -16
- package/dist/api/index.d.ts +6 -2
- package/dist/api/index.js +15 -3
- package/dist/{audit-1jrwwacz.js → audit-nhn2pjz3.js} +5 -5
- package/dist/{build-5s92kgpc.js → build-san7fv2z.js} +5 -5
- package/dist/checks/types.d.ts +6 -0
- package/dist/{cli-hvqjs342.js → cli-e5zhb0xs.js} +2 -2
- package/dist/{cli-7ykx7pp0.js → cli-k4bd06sd.js} +982 -331
- package/dist/{cli-h7phg3ka.js → cli-najycadg.js} +258 -258
- package/dist/{index-1tyj4bk3.js → cli-wchtvxvw.js} +4 -1
- package/dist/{cli-5bxx0c4y.js → cli-yzrh708h.js} +2 -2
- package/dist/cli.js +15 -15
- package/dist/{doctor-25zjt8dz.js → doctor-hrk0kxxz.js} +2 -2
- package/dist/{index-3h3fef7r.js → index-bynn850m.js} +1200 -410
- package/dist/{cli-1tyj4bk3.js → index-wchtvxvw.js} +4 -1
- package/dist/{index-5bxx0c4y.js → index-yzrh708h.js} +2 -2
- package/dist/index.js +15 -3
- package/dist/lib/asset-inline.d.ts +19 -0
- package/dist/lib/build-error.d.ts +0 -1
- package/dist/lib/build-fingerprint.d.ts +14 -0
- package/dist/lib/build-runner.d.ts +21 -1
- package/dist/lib/ghostscript.d.ts +0 -9
- package/dist/lib/manifest-config.d.ts +7 -0
- package/dist/lib/manifest.d.ts +8 -0
- package/dist/lib/markdown/assemble.d.ts +4 -6
- package/dist/lib/markdown/chapter-id.d.ts +1 -1
- package/dist/lib/markdown/index.d.ts +1 -2
- package/dist/lib/npm-plugin-installer.d.ts +1 -1
- package/dist/lib/output-paths.d.ts +0 -1
- package/dist/lib/pagination.d.ts +0 -20
- package/dist/lib/pdf-inspect.d.ts +2 -2
- package/dist/lib/pdf-parse.d.ts +2 -1
- package/dist/lib/plugin-manager.d.ts +0 -2
- package/dist/lib/presets.d.ts +36 -7
- package/dist/lib/project-scaffold.d.ts +39 -2
- package/dist/lib/project-source.d.ts +11 -9
- package/dist/lib/project-templates.d.ts +45 -7
- package/dist/lib/publish/providers/azure-swa.d.ts +0 -1
- package/dist/lib/publish/providers/itch.d.ts +0 -1
- package/dist/lib/publish/providers/shopify.d.ts +0 -1
- package/dist/lib/remote-auth/github-repos.d.ts +0 -2
- package/dist/lib/remote-auth/recovery/dispatch.d.ts +0 -5
- package/dist/lib/remote-auth/recovery/outcome-mapping.d.ts +3 -2
- package/dist/lib/remote-auth/recovery/recover-stale-lock.d.ts +0 -8
- package/dist/lib/remote-auth/sync.d.ts +2 -10
- package/dist/lib/remote-auth/test-access.d.ts +0 -2
- package/dist/lib/remote-auth/test-support/git-http-server.d.ts +0 -37
- package/dist/lib/source-provider.d.ts +0 -14
- package/dist/lib/static-serve.d.ts +39 -0
- package/dist/lib/style-resolver.d.ts +10 -1
- package/dist/lib/targets.d.ts +84 -0
- package/dist/lib/theme-import.d.ts +0 -2
- package/dist/lib/theme-manager.d.ts +1 -1
- package/dist/lib/validation-exec.d.ts +4 -3
- package/dist/{lint-f63nxjfj.js → lint-96j9hrj4.js} +5 -5
- package/dist/{manifest.schema-rn1dpdpn.json → manifest.schema-z61rzw44.json} +12 -6
- package/dist/new-8p38wavc.js +185 -0
- package/dist/{pagedjs-interface-80g3xa8p.js → pagedjs-interface-qxvzgwd7.js} +92 -33
- package/dist/{plugin-wf2cbmwc.js → plugin-ees6nhkc.js} +5 -5
- package/dist/{preflight-tg4mpz1h.js → preflight-1q6c2edh.js} +24 -29
- package/dist/preview/file-watcher.d.ts +48 -39
- package/dist/preview/http-server.d.ts +5 -2
- package/dist/preview/server-context.d.ts +24 -0
- package/dist/preview-shell-6dqexx1m.js +581 -0
- package/dist/{preview-h2bwbb2x.js → preview-y5a2zen1.js} +5 -5
- package/dist/{project-source-0tg0r6vm.js → project-source-p0gn1wd5.js} +3 -3
- package/dist/{publish-ztaet53r.js → publish-rm9yb3wh.js} +5 -5
- package/dist/render.js +10 -19
- package/dist/{repair-jkp4n3j8.js → repair-zgq7q2g6.js} +5 -5
- package/dist/schema/manifest.types.d.ts +14 -3
- package/dist/server.d.ts +2 -0
- package/dist/{source-provider-hp96b5jf.js → source-provider-c1rjm2c0.js} +2 -8
- package/dist/types.d.ts +0 -1
- package/dist/{validate-k2drs19j.js → validate-nr0xa6sa.js} +8 -8
- package/package.json +2 -2
- package/dist/chapter-01-jj8ftn4c.md +0 -29
- package/dist/lib/validation-profile.d.ts +0 -18
- package/dist/manifest-ryyg71nf.yaml +0 -9
- package/dist/new-7b08a42h.js +0 -105
- package/dist/preview-shell-rghtfmc8.js +0 -155
- package/dist/theme-0yzvthe8.css +0 -65
- package/dist/theme-6a2fngc8.json +0 -6
|
@@ -86,6 +86,9 @@ async function detectProjectSource(folderPath) {
|
|
|
86
86
|
}
|
|
87
87
|
return { type: "local-folder", path: folderPath };
|
|
88
88
|
}
|
|
89
|
+
function repoRootForSource(source, fallbackDir) {
|
|
90
|
+
return source.type === "local-git-folder" ? source.repoRoot || fallbackDir : fallbackDir;
|
|
91
|
+
}
|
|
89
92
|
function capabilitiesFor(source) {
|
|
90
93
|
switch (source.type) {
|
|
91
94
|
case "local-folder":
|
|
@@ -121,4 +124,4 @@ function capabilitiesFor(source) {
|
|
|
121
124
|
}
|
|
122
125
|
}
|
|
123
126
|
|
|
124
|
-
export {
|
|
127
|
+
export { syncRemoteFor, findEnclosingRepoDir, repoSubPath, detectProjectSource, repoRootForSource, capabilitiesFor };
|
|
@@ -2,7 +2,7 @@ import {
|
|
|
2
2
|
capabilitiesFor,
|
|
3
3
|
detectProjectSource,
|
|
4
4
|
findEnclosingRepoDir
|
|
5
|
-
} from "./index-
|
|
5
|
+
} from "./index-wchtvxvw.js";
|
|
6
6
|
|
|
7
7
|
// src/lib/source-provider.ts
|
|
8
8
|
import * as fs from "node:fs";
|
|
@@ -461,4 +461,4 @@ async function restoreVersionWithBackup(options) {
|
|
|
461
461
|
});
|
|
462
462
|
}
|
|
463
463
|
|
|
464
|
-
export { resolveLogger, shortOid, gitScopeFor, HISTORY_PAGE_LIMIT,
|
|
464
|
+
export { resolveLogger, shortOid, gitScopeFor, HISTORY_PAGE_LIMIT, withRepoLock, __repoLockQueueSizeForTests, resolveGitAuthor, listWorkdirChanges, stageChanges, hasPendingChanges, hasUncommittedChanges, snapshotWorkingTreeUnlocked, isNoChangesError, providerFor, gitDirFor, snapshotStagingMarkerPath, RESTORE_BACKUP_MESSAGE, AUTO_SNAPSHOT_MESSAGE, restoreVersionWithBackup };
|
package/dist/index.js
CHANGED
|
@@ -15,11 +15,15 @@ import {
|
|
|
15
15
|
GitHubAuthProvider,
|
|
16
16
|
MANIFEST_FILENAMES,
|
|
17
17
|
PLUGINS_DIR,
|
|
18
|
+
PRESETS,
|
|
19
|
+
PRESET_IDS,
|
|
18
20
|
PublishSelectionsStore,
|
|
19
21
|
RECOMMENDED_PLUGINS,
|
|
20
22
|
RepoNeedsRecoveryError,
|
|
21
23
|
SNIPPETS_DIR,
|
|
22
24
|
SYNC_SNAPSHOT_MESSAGE,
|
|
25
|
+
TARGETS,
|
|
26
|
+
TARGET_IDS,
|
|
23
27
|
THEMES_DIR,
|
|
24
28
|
addLocalPlugin,
|
|
25
29
|
addNpmPlugin,
|
|
@@ -91,6 +95,7 @@ import {
|
|
|
91
95
|
publishConnectionStatus,
|
|
92
96
|
publishCredentialKey,
|
|
93
97
|
publishProviderFor,
|
|
98
|
+
publishTargetFor,
|
|
94
99
|
pullChanges,
|
|
95
100
|
pushChanges,
|
|
96
101
|
readAppHeartbeat,
|
|
@@ -137,7 +142,7 @@ import {
|
|
|
137
142
|
validateProjectPlugins,
|
|
138
143
|
verifyRepoReadable,
|
|
139
144
|
writeAppHeartbeat
|
|
140
|
-
} from "./index-
|
|
145
|
+
} from "./index-bynn850m.js";
|
|
141
146
|
import {
|
|
142
147
|
AUTO_SNAPSHOT_MESSAGE,
|
|
143
148
|
HISTORY_PAGE_LIMIT,
|
|
@@ -147,13 +152,14 @@ import {
|
|
|
147
152
|
resolveLogger,
|
|
148
153
|
restoreVersionWithBackup,
|
|
149
154
|
shortOid
|
|
150
|
-
} from "./index-
|
|
155
|
+
} from "./index-yzrh708h.js";
|
|
151
156
|
import {
|
|
152
157
|
capabilitiesFor,
|
|
153
158
|
detectProjectSource,
|
|
154
159
|
findEnclosingRepoDir,
|
|
160
|
+
repoRootForSource,
|
|
155
161
|
repoSubPath
|
|
156
|
-
} from "./index-
|
|
162
|
+
} from "./index-wchtvxvw.js";
|
|
157
163
|
import"./index-yja077f6.js";
|
|
158
164
|
import"./index-37x76zdn.js";
|
|
159
165
|
export {
|
|
@@ -195,6 +201,7 @@ export {
|
|
|
195
201
|
resolveActiveStyles,
|
|
196
202
|
reportMissingTools,
|
|
197
203
|
repoSubPath,
|
|
204
|
+
repoRootForSource,
|
|
198
205
|
removeProjectTheme,
|
|
199
206
|
removeAppHeartbeat,
|
|
200
207
|
redactCredential,
|
|
@@ -207,6 +214,7 @@ export {
|
|
|
207
214
|
readAppHeartbeat,
|
|
208
215
|
pushChanges,
|
|
209
216
|
pullChanges,
|
|
217
|
+
publishTargetFor,
|
|
210
218
|
publishProviderFor,
|
|
211
219
|
publishCredentialKey,
|
|
212
220
|
publishConnectionStatus,
|
|
@@ -283,12 +291,16 @@ export {
|
|
|
283
291
|
addNpmPlugin,
|
|
284
292
|
addLocalPlugin,
|
|
285
293
|
THEMES_DIR,
|
|
294
|
+
TARGET_IDS,
|
|
295
|
+
TARGETS,
|
|
286
296
|
SYNC_SNAPSHOT_MESSAGE,
|
|
287
297
|
SNIPPETS_DIR,
|
|
288
298
|
RepoNeedsRecoveryError,
|
|
289
299
|
RESTORE_BACKUP_MESSAGE,
|
|
290
300
|
RECOMMENDED_PLUGINS,
|
|
291
301
|
PublishSelectionsStore,
|
|
302
|
+
PRESET_IDS,
|
|
303
|
+
PRESETS,
|
|
292
304
|
PLUGINS_DIR,
|
|
293
305
|
MANIFEST_FILENAMES,
|
|
294
306
|
HISTORY_PAGE_LIMIT,
|
|
@@ -36,6 +36,25 @@ export interface InlineStylesResult {
|
|
|
36
36
|
* Falls back to the raw string for a literal `%` in a filename.
|
|
37
37
|
*/
|
|
38
38
|
export declare function decodeRef(ref: string): string;
|
|
39
|
+
/**
|
|
40
|
+
* True when `absPath` resolves OUTSIDE `projectDir`. Separator-aware, so a
|
|
41
|
+
* project-root file whose NAME begins with two dots (`..cover.png`) is NOT
|
|
42
|
+
* treated as an escape, and the `isAbsolute` arm catches a cross-drive Windows
|
|
43
|
+
* path that `path.relative` returns absolute. THE one containment predicate for
|
|
44
|
+
* this module's "is this asset in the project" decisions.
|
|
45
|
+
*/
|
|
46
|
+
export declare function escapesProjectRoot(projectDir: string, absPath: string): boolean;
|
|
47
|
+
/**
|
|
48
|
+
* The build-failing reason a prose IMAGE ref cannot be used, or `null` when it
|
|
49
|
+
* is a usable in-project reference. THE single source of truth both
|
|
50
|
+
* `planImageCopies` (which rejects at build time) and the pre-build
|
|
51
|
+
* `source.links.local-refs` check consume, so validation and the build agree
|
|
52
|
+
* on the rule — an image referenced from Markdown prose must live inside the
|
|
53
|
+
* book folder — AND on the exact decode (`stripUrlSuffix(decodeRef(...))`) and
|
|
54
|
+
* wording. They previously hand-rolled this apart and had already drifted (the
|
|
55
|
+
* check decoded without stripping the `?query`/`#frag` suffix).
|
|
56
|
+
*/
|
|
57
|
+
export declare function proseImageRefError(ref: string, projectDir: string): string | null;
|
|
39
58
|
/**
|
|
40
59
|
* Inline the active stylesheets into one CSS string, IN ORDER — the manifest's
|
|
41
60
|
* `styles:` list is the cascade order (theme first, override second).
|
|
@@ -6,7 +6,21 @@ type PdfxFingerprintConfig = {
|
|
|
6
6
|
};
|
|
7
7
|
export type BuildFingerprintInput = {
|
|
8
8
|
command: "build";
|
|
9
|
+
/** Where the fingerprint FILE is written — the build's ephemeral work dir. */
|
|
9
10
|
outputDir: string;
|
|
11
|
+
/**
|
|
12
|
+
* The output dir to RECORD in `keyConfig.outputDir`. Defaults to
|
|
13
|
+
* {@link BuildFingerprintInput.outputDir}.
|
|
14
|
+
*
|
|
15
|
+
* These are the same for a caller that writes straight to its destination, but
|
|
16
|
+
* a build always assembles into a scratch work dir and only then publishes it
|
|
17
|
+
* atomically — so the file must be created in the work dir while the value
|
|
18
|
+
* anyone later reads has to be the delivered destination. One field served both
|
|
19
|
+
* roles, so shipped fingerprints recorded a scratch path
|
|
20
|
+
* (`.dist-build-a1b2c3…`, or an OS temp dir) that no longer existed
|
|
21
|
+
* (2026-07-29 audit).
|
|
22
|
+
*/
|
|
23
|
+
recordedOutputDir?: string;
|
|
10
24
|
sourceDir?: string;
|
|
11
25
|
args: Record<string, unknown>;
|
|
12
26
|
pdfx: PdfxFingerprintConfig;
|
|
@@ -75,7 +75,7 @@ export declare function splitOutPath(outArg: string | undefined, format: BuildFo
|
|
|
75
75
|
* variant that reaches different code, so no `--out` value can be deleted —
|
|
76
76
|
* there is no code path that would do it.
|
|
77
77
|
*/
|
|
78
|
-
|
|
78
|
+
type PublishTarget =
|
|
79
79
|
/** gutterpress's own `dist/<slug>/`. Replaced wholesale, so stale files vanish. */
|
|
80
80
|
{
|
|
81
81
|
kind: "project";
|
|
@@ -94,7 +94,27 @@ export type PublishTarget =
|
|
|
94
94
|
export interface BuildContext {
|
|
95
95
|
opts: BuildRunnerOptions;
|
|
96
96
|
format: BuildFormat;
|
|
97
|
+
/**
|
|
98
|
+
* The directory the author pointed at (`gutterpress build <dir>`). Recorded in
|
|
99
|
+
* the build fingerprint as the source dir; NOT an anchor for resolving
|
|
100
|
+
* manifest-relative paths — see {@link BuildContext.renderDir}.
|
|
101
|
+
*/
|
|
97
102
|
inputDir: string;
|
|
103
|
+
/**
|
|
104
|
+
* THE anchor every manifest-relative path resolves against: `styles:`,
|
|
105
|
+
* `source.files`, authored plugin `path:` entries, and the lint gate's own
|
|
106
|
+
* stylesheet resolution. Equal to {@link BuildContext.manifestDir}.
|
|
107
|
+
*
|
|
108
|
+
* These used to resolve against two different roots in one build (2026-07-29
|
|
109
|
+
* audit): plugins, the lint gate, and the output dir anchored on
|
|
110
|
+
* `manifestDir`, while `styles:`/`source.files` anchored on `inputDir`. They
|
|
111
|
+
* are identical in the normative layout (the manifest lives in the book
|
|
112
|
+
* folder) and diverge only under an explicit `--manifest` pointing outside
|
|
113
|
+
* `--input` — where the docs are unambiguous that both are manifest-relative,
|
|
114
|
+
* so the lint gate was checking a different set of stylesheets than the ones
|
|
115
|
+
* that shipped.
|
|
116
|
+
*/
|
|
117
|
+
renderDir: string;
|
|
98
118
|
outDir: string;
|
|
99
119
|
manifestDir: string;
|
|
100
120
|
config: ReturnType<typeof resolveConfig>;
|
|
@@ -17,15 +17,6 @@ export declare function resolveGhostscript(targetPlatform?: NodeJS.Platform, env
|
|
|
17
17
|
*/
|
|
18
18
|
export declare function stripAnnotations(pdfPath: string, stagingDir: string): Promise<void>;
|
|
19
19
|
type PdfxFlavor = "x1a" | "x3";
|
|
20
|
-
/**
|
|
21
|
-
* Generate the PostScript definition file for PDF/X output intent + GCR.
|
|
22
|
-
*/
|
|
23
|
-
export declare function makePdfxDefPs(params: {
|
|
24
|
-
iccPath: string;
|
|
25
|
-
pdfx: PdfxFlavor;
|
|
26
|
-
title: string;
|
|
27
|
-
maxTac?: number;
|
|
28
|
-
}): string;
|
|
29
20
|
/**
|
|
30
21
|
* Stamp the Creator metadata field on an existing PDF.
|
|
31
22
|
*
|
|
@@ -4,6 +4,13 @@ export interface ProjectConfigFields {
|
|
|
4
4
|
authors?: string[];
|
|
5
5
|
/** `source.files` — the markdown inputs (null means "all chapter files"). */
|
|
6
6
|
sourceFiles?: string[] | null;
|
|
7
|
+
/**
|
|
8
|
+
* `targets:` — the publish destinations this book is validated against
|
|
9
|
+
* (ADR 0008). An empty array is written as an explicit `targets: []`, the
|
|
10
|
+
* visible "no destination policies" opt-out; `undefined` in an update
|
|
11
|
+
* leaves the key untouched.
|
|
12
|
+
*/
|
|
13
|
+
targets?: string[];
|
|
7
14
|
}
|
|
8
15
|
/**
|
|
9
16
|
* Apply the author-facing manifest field updates in a single yaml round-trip.
|
package/dist/lib/manifest.d.ts
CHANGED
|
@@ -39,3 +39,11 @@ export declare function loadManifestWithPath(pathOrDir?: string, opts?: {
|
|
|
39
39
|
* Any field explicitly set in `cliOverrides` wins, then manifest, then preset.
|
|
40
40
|
*/
|
|
41
41
|
export declare function resolveConfig(cliOverrides: Partial<GutterpressManifest>, manifest: GutterpressManifest): ResolvedConfig;
|
|
42
|
+
/**
|
|
43
|
+
* Resolve the config AS ONE PUBLISH TARGET SEES IT (ADR 0008): the target's
|
|
44
|
+
* policy overlay is merged onto the preset before the manifest merges over
|
|
45
|
+
* both, giving the single precedence chain cli > manifest > target > preset.
|
|
46
|
+
* The author's explicit manifest values always beat the target's policy —
|
|
47
|
+
* the same sovereignty rule presets follow.
|
|
48
|
+
*/
|
|
49
|
+
export declare function resolveConfigForTarget(cliOverrides: Partial<GutterpressManifest>, manifest: GutterpressManifest, targetId: string): ResolvedConfig;
|
|
@@ -37,12 +37,10 @@ export interface AssembleBookHtmlOptions {
|
|
|
37
37
|
plugins?: LoadedPlugin[];
|
|
38
38
|
pluginCss?: string;
|
|
39
39
|
/**
|
|
40
|
-
*
|
|
41
|
-
*
|
|
42
|
-
*
|
|
43
|
-
*
|
|
44
|
-
* siblings, which can change pagination. Off by default; build output is
|
|
45
|
-
* unaffected.
|
|
40
|
+
* Wrap each source file in `<div class="gutterpress-chapter"
|
|
41
|
+
* data-chapter-src="<file>">`. Used only by incremental preview so one
|
|
42
|
+
* source can be paginated and replaced independently. Off by default; build
|
|
43
|
+
* output is unaffected.
|
|
46
44
|
*/
|
|
47
45
|
wrapChapters?: boolean;
|
|
48
46
|
/**
|
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
* boundary: project-root-relative, forward slashes, no `./` prefix, no
|
|
6
6
|
* duplicate slashes. This single form is used by:
|
|
7
7
|
*
|
|
8
|
-
* - preview source
|
|
8
|
+
* - preview source wrappers' `data-chapter-src` tagging
|
|
9
9
|
* (lib/markdown/assemble.ts assembleBookHtml — index.ts's renderChapters
|
|
10
10
|
* is now just the thin node:fs wrapper around it)
|
|
11
11
|
* - preview source inspection and chapter-scoped scroll restoration
|
|
@@ -2,7 +2,6 @@ import { type LayoutWarning } from "./assemble";
|
|
|
2
2
|
import { type AssetCopy } from "../asset-inline";
|
|
3
3
|
import type { LoadedPlugin } from "./renderer";
|
|
4
4
|
export type { LayoutWarning } from "./assemble";
|
|
5
|
-
export { createMarkdownRenderer } from "./renderer";
|
|
6
5
|
/**
|
|
7
6
|
* THE canonical "which markdown files make up this book, and in what order?"
|
|
8
7
|
* resolver — markdown's counterpart to `resolveActiveStyles` (style-resolver.ts).
|
|
@@ -38,7 +37,7 @@ export declare function renderChapters(inputDir: string, opts?: {
|
|
|
38
37
|
files?: string[] | null;
|
|
39
38
|
plugins?: LoadedPlugin[];
|
|
40
39
|
pluginCss?: string;
|
|
41
|
-
/**
|
|
40
|
+
/** Wrap each source file for incremental preview pagination. */
|
|
42
41
|
wrapChapters?: boolean;
|
|
43
42
|
/**
|
|
44
43
|
* ARCH finding #4: per-chapter author-mistake warnings computed by
|
|
@@ -10,7 +10,6 @@
|
|
|
10
10
|
*
|
|
11
11
|
* `--out` remains for per-invocation placement (CI, one-offs).
|
|
12
12
|
*/
|
|
13
|
-
export declare const DIST_DIRNAME = "dist";
|
|
14
13
|
/** The rendered book document. Fixed: the desktop and index.html load it by name. */
|
|
15
14
|
export declare const BOOK_HTML = "book.html";
|
|
16
15
|
/** Slug identifying one book. Falls back to `book` for an unsluggable title. */
|
package/dist/lib/pagination.d.ts
CHANGED
|
@@ -15,26 +15,6 @@ export interface ServerOverlay {
|
|
|
15
15
|
body: string | Buffer;
|
|
16
16
|
contentType: string;
|
|
17
17
|
}
|
|
18
|
-
/**
|
|
19
|
-
* Start a localhost static file server rooted at `dir`, with optional in-memory
|
|
20
|
-
* `overlays` keyed by URL path (e.g. `/book.html`).
|
|
21
|
-
*
|
|
22
|
-
* Overlays are what let the build paginate WITHOUT staging a second copy of the
|
|
23
|
-
* project. `outDir` is served directly; the Paged.js-patched `book.html` and the
|
|
24
|
-
* vendored polyfill are supplied from memory, so the engine never has to be
|
|
25
|
-
* written into the shipped artifact and no asset is copied twice. This mirrors
|
|
26
|
-
* the preview server, which has always served `/vendor/*` as a virtual overlay
|
|
27
|
-
* rather than copying it per project.
|
|
28
|
-
*
|
|
29
|
-
* Path-traversal protection, the MIME map, and the actual file response are
|
|
30
|
-
* the shared `./static-serve` primitives (`resolveStaticPath` + `serveFile`)
|
|
31
|
-
* also used by preview/http-server.ts — a request that resolves outside `dir`
|
|
32
|
-
* gets 403; a missing file gets 404 from `serveFile` itself.
|
|
33
|
-
*/
|
|
34
|
-
export declare function createStaticFileServer(dir: string, defaultFile: string, overlays?: Record<string, ServerOverlay>): Promise<{
|
|
35
|
-
port: number;
|
|
36
|
-
close: () => Promise<void>;
|
|
37
|
-
}>;
|
|
38
18
|
/** Input handed to a PDF renderer: a URL serving the staged HTML + assets. */
|
|
39
19
|
export interface PdfRenderInput {
|
|
40
20
|
/** URL of the staged HTML on a local HTTP server (assets resolve relative). */
|
|
@@ -87,7 +87,7 @@ interface TextPass {
|
|
|
87
87
|
}>;
|
|
88
88
|
}
|
|
89
89
|
export declare function getTextPass(doc: PDFDocumentProxy): Promise<TextPass>;
|
|
90
|
-
|
|
90
|
+
interface ImageRef {
|
|
91
91
|
/** XObject resource name (or "(inline)" for inline images). */
|
|
92
92
|
name: string;
|
|
93
93
|
/** Rendered width/height on the page, in points (from the CTM). */
|
|
@@ -96,7 +96,7 @@ export interface ImageRef {
|
|
|
96
96
|
/** 1-based page number. */
|
|
97
97
|
page: number;
|
|
98
98
|
}
|
|
99
|
-
|
|
99
|
+
interface FontRef {
|
|
100
100
|
name: string;
|
|
101
101
|
embedded: boolean;
|
|
102
102
|
}
|
package/dist/lib/pdf-parse.d.ts
CHANGED
|
@@ -25,7 +25,7 @@ export declare function parseInkCov(out: string): {
|
|
|
25
25
|
k: number;
|
|
26
26
|
sum: number;
|
|
27
27
|
}[];
|
|
28
|
-
|
|
28
|
+
interface InkCoveragePage {
|
|
29
29
|
page: number;
|
|
30
30
|
c: number;
|
|
31
31
|
m: number;
|
|
@@ -55,3 +55,4 @@ export type InkCoverageResult = {
|
|
|
55
55
|
* callers must surface the failure, not treat it as "0 pages measured".
|
|
56
56
|
*/
|
|
57
57
|
export declare function getPerPageInkCoverage(pdfPath: string): Promise<InkCoverageResult>;
|
|
58
|
+
export {};
|
|
@@ -22,8 +22,6 @@ interface PluginManagerInstallOptions extends NpmPluginInstallOptions {
|
|
|
22
22
|
exportName?: string;
|
|
23
23
|
__testFailBeforeManifestCommit?: () => void | Promise<void>;
|
|
24
24
|
}
|
|
25
|
-
/** Serialize all plugin filesystem + manifest mutations for one project. */
|
|
26
|
-
export declare function withPluginMutationLock<T>(projectDir: string, mutation: () => Promise<T>): Promise<T>;
|
|
27
25
|
/** Result of attempting to load one configured plugin. */
|
|
28
26
|
export interface PluginValidationResult {
|
|
29
27
|
ref: string;
|
package/dist/lib/presets.d.ts
CHANGED
|
@@ -1,5 +1,26 @@
|
|
|
1
1
|
import type { ResolvedConfig } from "../schema/manifest.types";
|
|
2
|
-
|
|
2
|
+
/**
|
|
3
|
+
* A preset is HOW THE BOOK IS DESIGNED (ADR 0008): the base defaults for the
|
|
4
|
+
* resolved config, chiefly page/trim geometry, plus the publish targets a
|
|
5
|
+
* book of this kind validates against when the manifest lists none. Where
|
|
6
|
+
* the book is PUBLISHED is a separate concern — see ./targets.ts.
|
|
7
|
+
*
|
|
8
|
+
* Every preset value is overridable from the manifest, leaf by leaf
|
|
9
|
+
* (resolveConfig's mergeShape; precedence cli > manifest > target > preset).
|
|
10
|
+
*/
|
|
11
|
+
export interface VendorPreset extends Omit<ResolvedConfig, "title" | "authors" | "targets" | "page"> {
|
|
12
|
+
/**
|
|
13
|
+
* Base page geometry in points, or `null` for `custom` — the one preset
|
|
14
|
+
* with no built-in trim, which therefore REQUIRES the manifest to supply
|
|
15
|
+
* `page.width` and `page.height` (resolveConfig enforces it).
|
|
16
|
+
*/
|
|
17
|
+
page: ResolvedConfig["page"] | null;
|
|
18
|
+
/** Publish-target ids validated by default when the manifest has no `targets:`. */
|
|
19
|
+
defaultTargets: readonly string[];
|
|
20
|
+
}
|
|
21
|
+
/** The built-in preset ids, in the order pickers should offer them. */
|
|
22
|
+
export declare const PRESET_IDS: readonly ["dtrpg", "book", "custom"];
|
|
23
|
+
export type PresetId = (typeof PRESET_IDS)[number];
|
|
3
24
|
export declare const DTRPG_PRESET: VendorPreset;
|
|
4
25
|
/**
|
|
5
26
|
* A neutral, vendor-agnostic default for authors who aren't targeting a
|
|
@@ -24,7 +45,14 @@ export declare const DTRPG_PRESET: VendorPreset;
|
|
|
24
45
|
* distribution.
|
|
25
46
|
*/
|
|
26
47
|
export declare const BOOK_PRESET: VendorPreset;
|
|
27
|
-
|
|
48
|
+
/**
|
|
49
|
+
* `custom` — the author supplies the trim. Policy defaults are the neutral
|
|
50
|
+
* `book` ones (no vendor TAC cap, no PDF/X forcing); geometry is `null`, so
|
|
51
|
+
* resolveConfig demands explicit `page.width`/`page.height` (points) and
|
|
52
|
+
* errors, naming the missing fields, when they are absent.
|
|
53
|
+
*/
|
|
54
|
+
export declare const CUSTOM_PRESET: VendorPreset;
|
|
55
|
+
export declare const PRESETS: Record<PresetId, VendorPreset>;
|
|
28
56
|
export declare function warnOnce(id: string, message: string, sink?: (msg: string) => void): void;
|
|
29
57
|
/** Test-only reset hook — clears all warn-once dedup state. */
|
|
30
58
|
export declare function resetWarnOnce(): void;
|
|
@@ -32,11 +60,12 @@ export declare function resetWarnOnce(): void;
|
|
|
32
60
|
* Resolve a manifest/CLI `preset` value to the {@link VendorPreset} it names
|
|
33
61
|
* (UX finding M48).
|
|
34
62
|
*
|
|
35
|
-
* - Unset (`undefined`): defaults to `dtrpg
|
|
36
|
-
*
|
|
37
|
-
*
|
|
38
|
-
*
|
|
39
|
-
*
|
|
63
|
+
* - Unset (`undefined`): defaults to `dtrpg`. That is the PRODUCT default,
|
|
64
|
+
* not a compatibility accident (ADR 0008): Gutterpress's primary audience
|
|
65
|
+
* is TTRPG authors producing print-on-demand content, and a preset-less
|
|
66
|
+
* manifest should come out print-ready for DriveThruRPG. Creation flows
|
|
67
|
+
* always write an explicit `preset:`, so this only applies to
|
|
68
|
+
* hand-written manifests — a one-line notice says which default applied.
|
|
40
69
|
* - Unknown (typo'd) value: throws a {@link UsageError} naming the known
|
|
41
70
|
* presets, instead of silently falling back to `dtrpg` — the previous
|
|
42
71
|
* behavior turned a typo'd `preset: a4` into 621x810pt DriveThruRPG
|
|
@@ -1,10 +1,11 @@
|
|
|
1
|
+
import { type PresetId } from "./presets.ts";
|
|
1
2
|
/**
|
|
2
3
|
* Which embedded starter template to scaffold from. Each id maps to a directory
|
|
3
4
|
* under `assets/templates/<id>/` (a `manifest.yaml` + a `chapter-01.md`), baked
|
|
4
5
|
* into the binary via `embedded-assets.ts`. `"book"` is the default; the others
|
|
5
6
|
* give non-technical authors a head start for common formats (#29).
|
|
6
7
|
*/
|
|
7
|
-
export type ProjectTemplateId = "book" | "
|
|
8
|
+
export type ProjectTemplateId = "book" | "zine" | "technical";
|
|
8
9
|
/**
|
|
9
10
|
* How (or whether) to put the new project under local version history.
|
|
10
11
|
*
|
|
@@ -40,9 +41,45 @@ export interface CreateProjectOptions {
|
|
|
40
41
|
* author picks a saved/imported template.
|
|
41
42
|
*/
|
|
42
43
|
templateDir?: string;
|
|
44
|
+
/**
|
|
45
|
+
* Which vendor preset the new book is designed for (ADR 0008). REQUIRED
|
|
46
|
+
* when scaffolding a built-in template — creation flows make the author
|
|
47
|
+
* choose; the resolveConfig dtrpg fallback exists for hand-written
|
|
48
|
+
* manifests, not for tooling. Written into the generated manifest as an
|
|
49
|
+
* explicit `preset:` line. Ignored with `templateDir`: a saved template's
|
|
50
|
+
* manifest carries its preset as part of the captured design.
|
|
51
|
+
*/
|
|
52
|
+
preset?: PresetId;
|
|
53
|
+
/**
|
|
54
|
+
* Publish-target ids written into the generated manifest as an explicit
|
|
55
|
+
* `targets:` list (ADR 0008). Defaults to the chosen preset's
|
|
56
|
+
* `defaultTargets`; pass `[]` to opt out of every destination policy
|
|
57
|
+
* (e.g. when the tools a destination's checks need aren't installed).
|
|
58
|
+
* Like `preset`, the creation flow always records the choice explicitly —
|
|
59
|
+
* the preset-derived fallback exists for hand-written manifests only.
|
|
60
|
+
* Ignored with `templateDir` (the saved template's manifest is kept).
|
|
61
|
+
*/
|
|
62
|
+
targets?: string[];
|
|
63
|
+
/**
|
|
64
|
+
* Page geometry written into the generated manifest (points; 72pt = 1in).
|
|
65
|
+
* REQUIRED when `preset` is `"custom"` (it has no built-in trim); allowed
|
|
66
|
+
* with any preset to override its trim. These are the validation bounds
|
|
67
|
+
* the built PDF is checked against — the actual trim comes from the
|
|
68
|
+
* stylesheet's `@page` rule, and the two should match.
|
|
69
|
+
*/
|
|
70
|
+
customPage?: CustomPageOptions;
|
|
43
71
|
/** Version-history mode for the new project. Defaults to `"local-git"`. */
|
|
44
72
|
versionHistory?: ProjectVersionHistoryMode;
|
|
45
73
|
}
|
|
74
|
+
/** Page bounds for {@link CreateProjectOptions.customPage}. */
|
|
75
|
+
export interface CustomPageOptions {
|
|
76
|
+
/** Trim width in points (72pt = 1in). */
|
|
77
|
+
width: number;
|
|
78
|
+
/** Trim height in points (72pt = 1in). */
|
|
79
|
+
height: number;
|
|
80
|
+
/** Allowed deviation in points when validating a built PDF. Default 0.5. */
|
|
81
|
+
tolerance?: number;
|
|
82
|
+
}
|
|
46
83
|
/** The result of a successful scaffold. */
|
|
47
84
|
export interface CreateProjectResult {
|
|
48
85
|
/** Absolute path of the created project directory. */
|
|
@@ -68,7 +105,7 @@ export interface CreateProjectResult {
|
|
|
68
105
|
* message and the CLI can choose an exit code. Scaffolding is fail-fast and
|
|
69
106
|
* NEVER deletes or overwrites anything that already exists.
|
|
70
107
|
*/
|
|
71
|
-
export type CreateProjectErrorCode = "parent-not-writable" | "target-exists" | "invalid-name" | "scaffold-io";
|
|
108
|
+
export type CreateProjectErrorCode = "parent-not-writable" | "target-exists" | "invalid-name" | "preset-required" | "custom-page-required" | "invalid-targets" | "scaffold-io";
|
|
72
109
|
export interface CreateProjectError extends Error {
|
|
73
110
|
code: CreateProjectErrorCode;
|
|
74
111
|
}
|
|
@@ -65,15 +65,6 @@ export interface ProjectCapabilities {
|
|
|
65
65
|
canRestoreSnapshot: boolean;
|
|
66
66
|
authManagedByApp: boolean;
|
|
67
67
|
}
|
|
68
|
-
/**
|
|
69
|
-
* The remote a project syncs against: `origin` when one exists, else the first
|
|
70
|
-
* remote. Pure pick over a `listRemotes` result — see {@link syncRemoteFor}
|
|
71
|
-
* for the I/O helper detection and the sync transport share.
|
|
72
|
-
*/
|
|
73
|
-
export declare function pickSyncRemote<T extends {
|
|
74
|
-
remote: string;
|
|
75
|
-
url?: string;
|
|
76
|
-
}>(remotes: T[]): T | undefined;
|
|
77
68
|
/**
|
|
78
69
|
* THE one answer to "which remote does this repo sync against, and what's its
|
|
79
70
|
* URL" — shared by detection (`detectProjectSource`) and the sync transport
|
|
@@ -123,6 +114,17 @@ export declare function repoSubPath(repoRoot: string, folderPath: string): strin
|
|
|
123
114
|
* `hasRemote: false`). Never returns `managed-github`.
|
|
124
115
|
*/
|
|
125
116
|
export declare function detectProjectSource(folderPath: string): Promise<ProjectSource>;
|
|
117
|
+
/**
|
|
118
|
+
* The repository root a project's git operations act on, or `fallbackDir` when
|
|
119
|
+
* the project has no repo. THE one answer to "given a classified source, what
|
|
120
|
+
* repo does its snapshot/sync/log belong to" (R9: a project is its git repo) —
|
|
121
|
+
* so callers stop re-deriving `source.type === "local-git-folder" ?
|
|
122
|
+
* source.repoRoot : dir` inline (it was hand-rolled, and double-cast to an
|
|
123
|
+
* ad-hoc `{ type?; repoRoot? }` in two SvelteKit routes that lacked the type).
|
|
124
|
+
* A `managed-github` source (never produced by {@link detectProjectSource})
|
|
125
|
+
* has no local repo root either, so it also falls back. Pure; no I/O.
|
|
126
|
+
*/
|
|
127
|
+
export declare function repoRootForSource(source: ProjectSource, fallbackDir: string): string;
|
|
126
128
|
/**
|
|
127
129
|
* Map a {@link ProjectSource} to the actions the UI may offer. Pure; no I/O.
|
|
128
130
|
*
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/** The built-in templates shipped as embedded assets. */
|
|
2
|
-
export declare const BUILT_IN_TEMPLATE_IDS: readonly ["book", "
|
|
2
|
+
export declare const BUILT_IN_TEMPLATE_IDS: readonly ["book", "zine", "technical"];
|
|
3
3
|
/** Author-friendly metadata for one template (built-in or custom). */
|
|
4
4
|
export interface TemplateInfo {
|
|
5
5
|
/** Stable id. For built-ins, the {@link ProjectTemplateId}; for custom, a slug. */
|
|
@@ -12,9 +12,36 @@ export interface TemplateInfo {
|
|
|
12
12
|
kind: "builtin" | "custom";
|
|
13
13
|
/** For custom templates: absolute directory the files live in. */
|
|
14
14
|
dir?: string;
|
|
15
|
+
/**
|
|
16
|
+
* The `preset:` this template's manifest declares (ADR 0008), when it has
|
|
17
|
+
* one. Creation flows use it as the starting point for the preset choice —
|
|
18
|
+
* the template says what kind of book it is, so choosing one seeds
|
|
19
|
+
* everything under it.
|
|
20
|
+
*/
|
|
21
|
+
preset?: string;
|
|
22
|
+
/** The `targets:` this template's manifest declares, when it has one. */
|
|
23
|
+
targets?: string[];
|
|
15
24
|
}
|
|
16
|
-
/**
|
|
25
|
+
/**
|
|
26
|
+
* List the built-in templates. The `preset`/`targets` each one starts a book
|
|
27
|
+
* from are read from that template's own embedded manifest — one source of
|
|
28
|
+
* truth, so changing a template's manifest changes what the wizard offers.
|
|
29
|
+
*/
|
|
17
30
|
export declare function listBuiltInTemplates(): Promise<TemplateInfo[]>;
|
|
31
|
+
/**
|
|
32
|
+
* What to do with manifest references that point OUTSIDE the captured book — a
|
|
33
|
+
* repo-nested book's `../../shared/...` styles and authored plugins, which
|
|
34
|
+
* would dangle once the template is scaffolded somewhere else.
|
|
35
|
+
*
|
|
36
|
+
* - `"vendor"` (default): copy the referenced files — for a stylesheet, its
|
|
37
|
+
* whole `@import`/`url()` closure — INTO the template book-local, preserving
|
|
38
|
+
* the layout so the CSS's own relative refs still resolve, and rewrite the
|
|
39
|
+
* manifest entries to the book-local paths. Keeps the look; the template is
|
|
40
|
+
* a self-contained fork of the shared design at save time.
|
|
41
|
+
* - `"exclude"`: drop the escaping entries (copy nothing), leaving a
|
|
42
|
+
* book-local-only template.
|
|
43
|
+
*/
|
|
44
|
+
export type SharedRefMode = "vendor" | "exclude";
|
|
18
45
|
export interface SaveProjectAsTemplateOptions {
|
|
19
46
|
/** Absolute path of the project to capture. */
|
|
20
47
|
projectDir: string;
|
|
@@ -22,15 +49,26 @@ export interface SaveProjectAsTemplateOptions {
|
|
|
22
49
|
name: string;
|
|
23
50
|
/** Absolute directory custom templates are stored under. */
|
|
24
51
|
templatesRoot: string;
|
|
52
|
+
/** How to handle out-of-book (`../../shared/...`) refs. Defaults to `"vendor"`. */
|
|
53
|
+
sharedRefs?: SharedRefMode;
|
|
54
|
+
}
|
|
55
|
+
/** The outcome of reconciling a captured book's out-of-book manifest refs. */
|
|
56
|
+
export interface SharedRefOutcome {
|
|
57
|
+
/** Book-local paths the escaping refs were vendored to (`"vendor"` mode). */
|
|
58
|
+
vendoredRefs: string[];
|
|
59
|
+
/** Manifest entries dropped because they pointed outside the book (`"exclude"` mode). */
|
|
60
|
+
excludedRefs: string[];
|
|
25
61
|
}
|
|
26
62
|
/**
|
|
27
63
|
* Capture an existing project as a reusable custom template. Copies the whole
|
|
28
|
-
* project tree (minus build/VCS dirs) into `<templatesRoot>/<slug(name)>/`,
|
|
29
|
-
*
|
|
30
|
-
*
|
|
31
|
-
*
|
|
64
|
+
* project tree (minus build/VCS dirs) into `<templatesRoot>/<slug(name)>/`,
|
|
65
|
+
* reconciles any out-of-book (`../../shared/...`) refs so the template is
|
|
66
|
+
* portable ({@link SharedRefMode} — vendor by default), then re-tokenises the
|
|
67
|
+
* project's title back to `{{TITLE}}` in the manifest so the saved template
|
|
68
|
+
* scaffolds cleanly for the next book. Refuses to overwrite an existing
|
|
69
|
+
* template directory (never deletes user data).
|
|
32
70
|
*/
|
|
33
|
-
export declare function saveProjectAsTemplate(options: SaveProjectAsTemplateOptions): Promise<TemplateInfo>;
|
|
71
|
+
export declare function saveProjectAsTemplate(options: SaveProjectAsTemplateOptions): Promise<TemplateInfo & SharedRefOutcome>;
|
|
34
72
|
/**
|
|
35
73
|
* List custom templates saved under `templatesRoot`. Returns `[]` when the root
|
|
36
74
|
* doesn't exist. Each subdirectory is a template; its label comes from the
|
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
import { type PublishProvider } from "../types.ts";
|
|
2
|
-
export declare const SHOPIFY_HOST = "shopify";
|
|
3
2
|
/** `gid://shopify/Product/123` → `123` (for admin deep links). */
|
|
4
3
|
export declare function shopifyLegacyId(gid: string): string;
|
|
5
4
|
export declare const shopifyProvider: PublishProvider;
|