@kensio/colophon 2.1.0 → 2.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 +608 -34
- package/dist/cli/args.d.ts +14 -0
- package/dist/cli/args.d.ts.map +1 -0
- package/dist/cli/args.js +67 -0
- package/dist/cli/args.js.map +1 -0
- package/dist/cli/config.d.ts +12 -0
- package/dist/cli/config.d.ts.map +1 -0
- package/dist/cli/config.js +43 -0
- package/dist/cli/config.js.map +1 -0
- package/dist/cli/index.d.ts +3 -0
- package/dist/cli/index.d.ts.map +1 -0
- package/dist/cli/index.js +35 -0
- package/dist/cli/index.js.map +1 -0
- package/dist/cli.js +34 -6
- package/dist/cli.js.map +1 -1
- package/dist/config/defaults.d.ts +64 -0
- package/dist/config/defaults.d.ts.map +1 -0
- package/dist/config/defaults.js +64 -0
- package/dist/config/defaults.js.map +1 -0
- package/dist/config/index.d.ts +22 -0
- package/dist/config/index.d.ts.map +1 -0
- package/dist/config/index.js +52 -0
- package/dist/config/index.js.map +1 -0
- package/dist/config/resolve.d.ts +24 -0
- package/dist/config/resolve.d.ts.map +1 -0
- package/dist/config/resolve.js +66 -0
- package/dist/config/resolve.js.map +1 -0
- package/dist/config/size.d.ts +20 -0
- package/dist/config/size.d.ts.map +1 -0
- package/dist/config/size.js +46 -0
- package/dist/config/size.js.map +1 -0
- package/dist/config.d.ts +33 -2
- package/dist/config.d.ts.map +1 -1
- package/dist/config.js +94 -4
- package/dist/config.js.map +1 -1
- package/dist/content/index.d.ts +5 -51
- package/dist/content/index.d.ts.map +1 -1
- package/dist/content/index.js +3 -115
- package/dist/content/index.js.map +1 -1
- package/dist/content/props.d.ts +15 -0
- package/dist/content/props.d.ts.map +1 -0
- package/dist/content/props.js +71 -0
- package/dist/content/props.js.map +1 -0
- package/dist/content/slug.d.ts +23 -0
- package/dist/content/slug.d.ts.map +1 -0
- package/dist/content/slug.js +52 -0
- package/dist/content/slug.js.map +1 -0
- package/dist/content/walk.d.ts +17 -0
- package/dist/content/walk.d.ts.map +1 -0
- package/dist/content/walk.js +57 -0
- package/dist/content/walk.js.map +1 -0
- package/dist/fonts/index.d.ts +10 -0
- package/dist/fonts/index.d.ts.map +1 -0
- package/dist/fonts/index.js +11 -0
- package/dist/fonts/index.js.map +1 -0
- package/dist/fonts/materialise.d.ts +7 -0
- package/dist/fonts/materialise.d.ts.map +1 -0
- package/dist/fonts/materialise.js +47 -0
- package/dist/fonts/materialise.js.map +1 -0
- package/dist/fonts/resolve.d.ts +7 -0
- package/dist/fonts/resolve.d.ts.map +1 -0
- package/dist/fonts/resolve.js +50 -0
- package/dist/fonts/resolve.js.map +1 -0
- package/dist/fonts.d.ts +18 -0
- package/dist/fonts.d.ts.map +1 -0
- package/dist/fonts.js +102 -0
- package/dist/fonts.js.map +1 -0
- package/dist/generate/extra.d.ts +16 -0
- package/dist/generate/extra.d.ts.map +1 -0
- package/dist/generate/extra.js +60 -0
- package/dist/generate/extra.js.map +1 -0
- package/dist/generate/index.d.ts +19 -0
- package/dist/generate/index.d.ts.map +1 -0
- package/dist/generate/index.js +46 -0
- package/dist/generate/index.js.map +1 -0
- package/dist/generate/job.d.ts +35 -0
- package/dist/generate/job.d.ts.map +1 -0
- package/dist/generate/job.js +2 -0
- package/dist/generate/job.js.map +1 -0
- package/dist/generate/options.d.ts +56 -0
- package/dist/generate/options.d.ts.map +1 -0
- package/dist/generate/options.js +17 -0
- package/dist/generate/options.js.map +1 -0
- package/dist/generate/output-path.d.ts +12 -0
- package/dist/generate/output-path.d.ts.map +1 -0
- package/dist/generate/output-path.js +18 -0
- package/dist/generate/output-path.js.map +1 -0
- package/dist/generate/outputs.d.ts +28 -0
- package/dist/generate/outputs.d.ts.map +1 -0
- package/dist/generate/outputs.js +71 -0
- package/dist/generate/outputs.js.map +1 -0
- package/dist/generate/plan.d.ts +21 -0
- package/dist/generate/plan.d.ts.map +1 -0
- package/dist/generate/plan.js +72 -0
- package/dist/generate/plan.js.map +1 -0
- package/dist/generate/render-image.d.ts +11 -0
- package/dist/generate/render-image.d.ts.map +1 -0
- package/dist/generate/render-image.js +27 -0
- package/dist/generate/render-image.js.map +1 -0
- package/dist/generate.d.ts +27 -6
- package/dist/generate.d.ts.map +1 -1
- package/dist/generate.js +77 -15
- package/dist/generate.js.map +1 -1
- package/dist/highlight/color.d.ts +9 -0
- package/dist/highlight/color.d.ts.map +1 -0
- package/dist/highlight/color.js +15 -0
- package/dist/highlight/color.js.map +1 -0
- package/dist/highlight/grid.d.ts +14 -0
- package/dist/highlight/grid.d.ts.map +1 -0
- package/dist/highlight/grid.js +36 -0
- package/dist/highlight/grid.js.map +1 -0
- package/dist/highlight/index.d.ts +12 -0
- package/dist/highlight/index.d.ts.map +1 -0
- package/dist/highlight/index.js +31 -0
- package/dist/highlight/index.js.map +1 -0
- package/dist/highlight/language.d.ts +14 -0
- package/dist/highlight/language.d.ts.map +1 -0
- package/dist/highlight/language.js +42 -0
- package/dist/highlight/language.js.map +1 -0
- package/dist/highlight/normalise.d.ts +17 -0
- package/dist/highlight/normalise.d.ts.map +1 -0
- package/dist/highlight/normalise.js +37 -0
- package/dist/highlight/normalise.js.map +1 -0
- package/dist/highlight/types.d.ts +40 -0
- package/dist/highlight/types.d.ts.map +1 -0
- package/dist/highlight/types.js +2 -0
- package/dist/highlight/types.js.map +1 -0
- package/dist/highlight.d.ts +10 -0
- package/dist/highlight.d.ts.map +1 -1
- package/dist/highlight.js +25 -2
- package/dist/highlight.js.map +1 -1
- package/dist/index.d.ts +15 -9
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +9 -5
- package/dist/index.js.map +1 -1
- package/dist/manifest/build.d.ts +14 -0
- package/dist/manifest/build.d.ts.map +1 -0
- package/dist/manifest/build.js +43 -0
- package/dist/manifest/build.js.map +1 -0
- package/dist/manifest/index.d.ts +27 -0
- package/dist/manifest/index.d.ts.map +1 -0
- package/dist/manifest/index.js +31 -0
- package/dist/manifest/index.js.map +1 -0
- package/dist/manifest/order.d.ts +12 -0
- package/dist/manifest/order.d.ts.map +1 -0
- package/dist/manifest/order.js +17 -0
- package/dist/manifest/order.js.map +1 -0
- package/dist/manifest/page.d.ts +24 -0
- package/dist/manifest/page.d.ts.map +1 -0
- package/dist/manifest/page.js +55 -0
- package/dist/manifest/page.js.map +1 -0
- package/dist/meta/html.d.ts +14 -0
- package/dist/meta/html.d.ts.map +1 -0
- package/dist/meta/html.js +24 -0
- package/dist/meta/html.js.map +1 -0
- package/dist/meta/index.d.ts +11 -0
- package/dist/meta/index.d.ts.map +1 -0
- package/dist/meta/index.js +11 -0
- package/dist/meta/index.js.map +1 -0
- package/dist/meta/tags.d.ts +21 -0
- package/dist/meta/tags.d.ts.map +1 -0
- package/dist/meta/tags.js +72 -0
- package/dist/meta/tags.js.map +1 -0
- package/dist/meta/url.d.ts +15 -0
- package/dist/meta/url.d.ts.map +1 -0
- package/dist/meta/url.js +34 -0
- package/dist/meta/url.js.map +1 -0
- package/dist/placement/check.d.ts +16 -0
- package/dist/placement/check.d.ts.map +1 -0
- package/dist/placement/check.js +40 -0
- package/dist/placement/check.js.map +1 -0
- package/dist/placement/index.d.ts +29 -0
- package/dist/placement/index.d.ts.map +1 -0
- package/dist/placement/index.js +61 -0
- package/dist/placement/index.js.map +1 -0
- package/dist/placement/relative.d.ts +31 -0
- package/dist/placement/relative.d.ts.map +1 -0
- package/dist/placement/relative.js +53 -0
- package/dist/placement/relative.js.map +1 -0
- package/dist/pool.d.ts +18 -0
- package/dist/pool.d.ts.map +1 -0
- package/dist/pool.js +56 -0
- package/dist/pool.js.map +1 -0
- package/dist/render/index.d.ts +10 -0
- package/dist/render/index.d.ts.map +1 -0
- package/dist/render/index.js +27 -0
- package/dist/render/index.js.map +1 -0
- package/dist/render/png.d.ts +10 -0
- package/dist/render/png.d.ts.map +1 -0
- package/dist/render/png.js +30 -0
- package/dist/render/png.js.map +1 -0
- package/dist/render/svg.d.ts +10 -0
- package/dist/render/svg.d.ts.map +1 -0
- package/dist/render/svg.js +20 -0
- package/dist/render/svg.js.map +1 -0
- package/dist/render/template.d.ts +9 -0
- package/dist/render/template.d.ts.map +1 -0
- package/dist/render/template.js +17 -0
- package/dist/render/template.js.map +1 -0
- package/dist/render.d.ts +6 -2
- package/dist/render.d.ts.map +1 -1
- package/dist/render.js +31 -10
- package/dist/render.js.map +1 -1
- package/dist/stamp/chunk.d.ts +16 -0
- package/dist/stamp/chunk.d.ts.map +1 -0
- package/dist/stamp/chunk.js +46 -0
- package/dist/stamp/chunk.js.map +1 -0
- package/dist/stamp/config-digest.d.ts +11 -0
- package/dist/stamp/config-digest.d.ts.map +1 -0
- package/dist/stamp/config-digest.js +43 -0
- package/dist/stamp/config-digest.js.map +1 -0
- package/dist/stamp/digest.d.ts +8 -0
- package/dist/stamp/digest.d.ts.map +1 -0
- package/dist/stamp/digest.js +20 -0
- package/dist/stamp/digest.js.map +1 -0
- package/dist/stamp/index.d.ts +20 -0
- package/dist/stamp/index.d.ts.map +1 -0
- package/dist/stamp/index.js +40 -0
- package/dist/stamp/index.js.map +1 -0
- package/dist/stamp/read.d.ts +7 -0
- package/dist/stamp/read.d.ts.map +1 -0
- package/dist/stamp/read.js +62 -0
- package/dist/stamp/read.js.map +1 -0
- package/dist/stamp.d.ts +29 -0
- package/dist/stamp.d.ts.map +1 -0
- package/dist/stamp.js +198 -0
- package/dist/stamp.js.map +1 -0
- package/dist/templates/banner/badge.d.ts +7 -0
- package/dist/templates/banner/badge.d.ts.map +1 -0
- package/dist/templates/banner/badge.js +24 -0
- package/dist/templates/banner/badge.js.map +1 -0
- package/dist/templates/banner/index.d.ts +9 -0
- package/dist/templates/banner/index.d.ts.map +1 -0
- package/dist/templates/banner/index.js +66 -0
- package/dist/templates/banner/index.js.map +1 -0
- package/dist/templates/banner/lines.d.ts +27 -0
- package/dist/templates/banner/lines.d.ts.map +1 -0
- package/dist/templates/banner/lines.js +46 -0
- package/dist/templates/banner/lines.js.map +1 -0
- package/dist/templates/card/index.d.ts +7 -0
- package/dist/templates/card/index.d.ts.map +1 -0
- package/dist/templates/card/index.js +43 -0
- package/dist/templates/card/index.js.map +1 -0
- package/dist/templates/card/lines.d.ts +17 -0
- package/dist/templates/card/lines.d.ts.map +1 -0
- package/dist/templates/card/lines.js +32 -0
- package/dist/templates/card/lines.js.map +1 -0
- package/dist/templates/code/chrome.d.ts +9 -0
- package/dist/templates/code/chrome.d.ts.map +1 -0
- package/dist/templates/code/chrome.js +32 -0
- package/dist/templates/code/chrome.js.map +1 -0
- package/dist/templates/code/clip.d.ts +18 -0
- package/dist/templates/code/clip.d.ts.map +1 -0
- package/dist/templates/code/clip.js +44 -0
- package/dist/templates/code/clip.js.map +1 -0
- package/dist/templates/code/ellipsis.d.ts +3 -0
- package/dist/templates/code/ellipsis.d.ts.map +1 -0
- package/dist/templates/code/ellipsis.js +3 -0
- package/dist/templates/code/ellipsis.js.map +1 -0
- package/dist/templates/code/fit.d.ts +27 -0
- package/dist/templates/code/fit.d.ts.map +1 -0
- package/dist/templates/code/fit.js +59 -0
- package/dist/templates/code/fit.js.map +1 -0
- package/dist/templates/code/index.d.ts +12 -0
- package/dist/templates/code/index.d.ts.map +1 -0
- package/dist/templates/code/index.js +64 -0
- package/dist/templates/code/index.js.map +1 -0
- package/dist/templates/code/layout.d.ts +21 -0
- package/dist/templates/code/layout.d.ts.map +1 -0
- package/dist/templates/code/layout.js +21 -0
- package/dist/templates/code/layout.js.map +1 -0
- package/dist/templates/code/panel.d.ts +17 -0
- package/dist/templates/code/panel.d.ts.map +1 -0
- package/dist/templates/code/panel.js +20 -0
- package/dist/templates/code/panel.js.map +1 -0
- package/dist/templates/code/plate.d.ts +15 -0
- package/dist/templates/code/plate.d.ts.map +1 -0
- package/dist/templates/code/plate.js +32 -0
- package/dist/templates/code/plate.js.map +1 -0
- package/dist/templates/code/spans.d.ts +19 -0
- package/dist/templates/code/spans.d.ts.map +1 -0
- package/dist/templates/code/spans.js +36 -0
- package/dist/templates/code/spans.js.map +1 -0
- package/dist/templates/code/warn.d.ts +11 -0
- package/dist/templates/code/warn.d.ts.map +1 -0
- package/dist/templates/code/warn.js +24 -0
- package/dist/templates/code/warn.js.map +1 -0
- package/dist/templates/code.d.ts.map +1 -1
- package/dist/templates/code.js +101 -29
- package/dist/templates/code.js.map +1 -1
- package/dist/templates/footer.d.ts +21 -0
- package/dist/templates/footer.d.ts.map +1 -0
- package/dist/templates/footer.js +25 -0
- package/dist/templates/footer.js.map +1 -0
- package/dist/templates/index.d.ts +3 -3
- package/dist/templates/index.d.ts.map +1 -1
- package/dist/templates/index.js +6 -6
- package/dist/templates/index.js.map +1 -1
- package/dist/text/element.d.ts +18 -0
- package/dist/text/element.d.ts.map +1 -0
- package/dist/text/element.js +19 -0
- package/dist/text/element.js.map +1 -0
- package/dist/text/escape.d.ts +5 -0
- package/dist/text/escape.d.ts.map +1 -0
- package/dist/text/escape.js +12 -0
- package/dist/text/escape.js.map +1 -0
- package/dist/text/index.d.ts +7 -0
- package/dist/text/index.d.ts.map +1 -0
- package/dist/text/index.js +5 -0
- package/dist/text/index.js.map +1 -0
- package/dist/text/stack.d.ts +24 -0
- package/dist/text/stack.d.ts.map +1 -0
- package/dist/text/stack.js +18 -0
- package/dist/text/stack.js.map +1 -0
- package/dist/text/wrap.d.ts +12 -0
- package/dist/text/wrap.d.ts.map +1 -0
- package/dist/text/wrap.js +33 -0
- package/dist/text/wrap.js.map +1 -0
- package/dist/types.d.ts +345 -6
- package/dist/types.d.ts.map +1 -1
- package/dist/validate/check.d.ts +13 -0
- package/dist/validate/check.d.ts.map +1 -0
- package/dist/validate/check.js +34 -0
- package/dist/validate/check.js.map +1 -0
- package/dist/validate/index.d.ts +15 -0
- package/dist/validate/index.d.ts.map +1 -0
- package/dist/validate/index.js +41 -0
- package/dist/validate/index.js.map +1 -0
- package/dist/validate/keys.d.ts +58 -0
- package/dist/validate/keys.d.ts.map +1 -0
- package/dist/validate/keys.js +166 -0
- package/dist/validate/keys.js.map +1 -0
- package/dist/validate/overrides.d.ts +5 -0
- package/dist/validate/overrides.d.ts.map +1 -0
- package/dist/validate/overrides.js +43 -0
- package/dist/validate/overrides.js.map +1 -0
- package/dist/validate/placement.d.ts +10 -0
- package/dist/validate/placement.d.ts.map +1 -0
- package/dist/validate/placement.js +38 -0
- package/dist/validate/placement.js.map +1 -0
- package/dist/validate/sizes.d.ts +9 -0
- package/dist/validate/sizes.d.ts.map +1 -0
- package/dist/validate/sizes.js +27 -0
- package/dist/validate/sizes.js.map +1 -0
- package/dist/validate/suggest.d.ts +10 -0
- package/dist/validate/suggest.d.ts.map +1 -0
- package/dist/validate/suggest.js +55 -0
- package/dist/validate/suggest.js.map +1 -0
- package/dist/validate/values.d.ts +21 -0
- package/dist/validate/values.d.ts.map +1 -0
- package/dist/validate/values.js +57 -0
- package/dist/validate/values.js.map +1 -0
- package/dist/validate.d.ts +15 -0
- package/dist/validate.d.ts.map +1 -0
- package/dist/validate.js +300 -0
- package/dist/validate.js.map +1 -0
- package/package.json +14 -7
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import type { MetaImageProps, OutputSize, ResolvedConfig } from "../types.js";
|
|
2
|
+
/**
|
|
3
|
+
* One image to render: what to draw, how big, where it goes, and the config it
|
|
4
|
+
* is drawn with. A content file becomes one job per size; a config `extra`
|
|
5
|
+
* becomes a single job of its own.
|
|
6
|
+
*
|
|
7
|
+
* Working the paths and configs out while planning is what lets the two
|
|
8
|
+
* sources meet: by the time anything is rendered there are only jobs, and
|
|
9
|
+
* nothing downstream has to ask which kind of image it is holding.
|
|
10
|
+
*/
|
|
11
|
+
export interface RenderJob {
|
|
12
|
+
/**
|
|
13
|
+
* The content file this image came from, relative to the content root.
|
|
14
|
+
* `undefined` for an extra image, which has no content file.
|
|
15
|
+
*/
|
|
16
|
+
readonly contentPath: string | undefined;
|
|
17
|
+
/**
|
|
18
|
+
* The slug the page is addressed by, and the key it appears under in the
|
|
19
|
+
* manifest. `undefined` for an extra image, which is not a page.
|
|
20
|
+
*/
|
|
21
|
+
readonly slug: string | undefined;
|
|
22
|
+
readonly props: MetaImageProps;
|
|
23
|
+
readonly size: OutputSize;
|
|
24
|
+
readonly outputPath: string;
|
|
25
|
+
/** Where the image is served, if the placement knows. */
|
|
26
|
+
readonly url: string | undefined;
|
|
27
|
+
/**
|
|
28
|
+
* The digest of everything this image is drawn from. An image on disk
|
|
29
|
+
* carrying the same one is already up to date, and a placement that hashes
|
|
30
|
+
* filenames names the file after it.
|
|
31
|
+
*/
|
|
32
|
+
readonly stamp: string;
|
|
33
|
+
readonly config: ResolvedConfig;
|
|
34
|
+
}
|
|
35
|
+
//# sourceMappingURL=job.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"job.d.ts","sourceRoot":"","sources":["../../src/generate/job.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,UAAU,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAE9E;;;;;;;;GAQG;AACH,MAAM,WAAW,SAAS;IACxB;;;OAGG;IACH,QAAQ,CAAC,WAAW,EAAE,MAAM,GAAG,SAAS,CAAC;IACzC;;;OAGG;IACH,QAAQ,CAAC,IAAI,EAAE,MAAM,GAAG,SAAS,CAAC;IAClC,QAAQ,CAAC,KAAK,EAAE,cAAc,CAAC;IAC/B,QAAQ,CAAC,IAAI,EAAE,UAAU,CAAC;IAC1B,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IAC5B,yDAAyD;IACzD,QAAQ,CAAC,GAAG,EAAE,MAAM,GAAG,SAAS,CAAC;IACjC;;;;OAIG;IACH,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,MAAM,EAAE,cAAc,CAAC;CACjC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"job.js","sourceRoot":"","sources":["../../src/generate/job.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
import type { ContentFile, WalkOptions } from "../content/index.js";
|
|
2
|
+
import type { ColophonConfig, OutputSize } from "../types.js";
|
|
3
|
+
/**
|
|
4
|
+
* Outcome for one generated (or skipped) image.
|
|
5
|
+
*/
|
|
6
|
+
export interface GeneratedImage {
|
|
7
|
+
/**
|
|
8
|
+
* The content file this image came from, relative to the content root.
|
|
9
|
+
* `undefined` for a config `extra` image: there is no post behind it, and
|
|
10
|
+
* naming one — the output path, say — would quietly break anything grouping
|
|
11
|
+
* results by the post they belong to.
|
|
12
|
+
*/
|
|
13
|
+
readonly contentPath: string | undefined;
|
|
14
|
+
readonly size: OutputSize;
|
|
15
|
+
readonly outputPath: string;
|
|
16
|
+
/**
|
|
17
|
+
* Where the image is served, from the configured placement. `undefined`
|
|
18
|
+
* when nothing says: no `urlBase`, an image placed by `outputPath`, or an
|
|
19
|
+
* `extra` that named its own path.
|
|
20
|
+
*/
|
|
21
|
+
readonly url: string | undefined;
|
|
22
|
+
/** True when an up-to-date image was left in place (no `overwrite`). */
|
|
23
|
+
readonly skipped: boolean;
|
|
24
|
+
}
|
|
25
|
+
/**
|
|
26
|
+
* Options for `generate`.
|
|
27
|
+
*/
|
|
28
|
+
export interface GenerateOptions {
|
|
29
|
+
/** Root content directory to walk. */
|
|
30
|
+
readonly contentDir: string;
|
|
31
|
+
readonly config?: ColophonConfig;
|
|
32
|
+
/** Extra walk options (props key, template field, slug field, extensions). */
|
|
33
|
+
readonly walk?: Omit<WalkOptions, "dir">;
|
|
34
|
+
/** Override where each image is written. */
|
|
35
|
+
readonly outputPath?: (file: ContentFile, size: OutputSize) => string;
|
|
36
|
+
/**
|
|
37
|
+
* Re-render every image, ignoring the stamps that would otherwise mark them
|
|
38
|
+
* as up to date. Default `false`.
|
|
39
|
+
*/
|
|
40
|
+
readonly overwrite?: boolean;
|
|
41
|
+
/**
|
|
42
|
+
* How many images to render at once. Defaults to the number of CPUs the
|
|
43
|
+
* process can use. Must be a positive integer.
|
|
44
|
+
*/
|
|
45
|
+
readonly concurrency?: number;
|
|
46
|
+
/** Called after each image is written or skipped. */
|
|
47
|
+
readonly onResult?: (result: GeneratedImage) => void;
|
|
48
|
+
}
|
|
49
|
+
/**
|
|
50
|
+
* How many images to render at once when nothing is configured: one per CPU
|
|
51
|
+
* the process can actually use. Rasterising is CPU-bound, so starting more
|
|
52
|
+
* than that only queues the work up while holding every pending image in
|
|
53
|
+
* memory.
|
|
54
|
+
*/
|
|
55
|
+
export declare function resolveConcurrency(concurrency: number | undefined): number;
|
|
56
|
+
//# sourceMappingURL=options.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"options.d.ts","sourceRoot":"","sources":["../../src/generate/options.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,WAAW,EAAE,WAAW,EAAE,MAAM,qBAAqB,CAAC;AACpE,OAAO,KAAK,EAAE,cAAc,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAE9D;;GAEG;AACH,MAAM,WAAW,cAAc;IAC7B;;;;;OAKG;IACH,QAAQ,CAAC,WAAW,EAAE,MAAM,GAAG,SAAS,CAAC;IACzC,QAAQ,CAAC,IAAI,EAAE,UAAU,CAAC;IAC1B,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IAC5B;;;;OAIG;IACH,QAAQ,CAAC,GAAG,EAAE,MAAM,GAAG,SAAS,CAAC;IACjC,wEAAwE;IACxE,QAAQ,CAAC,OAAO,EAAE,OAAO,CAAC;CAC3B;AAED;;GAEG;AACH,MAAM,WAAW,eAAe;IAC9B,sCAAsC;IACtC,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IAC5B,QAAQ,CAAC,MAAM,CAAC,EAAE,cAAc,CAAC;IACjC,8EAA8E;IAC9E,QAAQ,CAAC,IAAI,CAAC,EAAE,IAAI,CAAC,WAAW,EAAE,KAAK,CAAC,CAAC;IACzC,4CAA4C;IAC5C,QAAQ,CAAC,UAAU,CAAC,EAAE,CAAC,IAAI,EAAE,WAAW,EAAE,IAAI,EAAE,UAAU,KAAK,MAAM,CAAC;IACtE;;;OAGG;IACH,QAAQ,CAAC,SAAS,CAAC,EAAE,OAAO,CAAC;IAC7B;;;OAGG;IACH,QAAQ,CAAC,WAAW,CAAC,EAAE,MAAM,CAAC;IAC9B,qDAAqD;IACrD,QAAQ,CAAC,QAAQ,CAAC,EAAE,CAAC,MAAM,EAAE,cAAc,KAAK,IAAI,CAAC;CACtD;AAED;;;;;GAKG;AACH,wBAAgB,kBAAkB,CAAC,WAAW,EAAE,MAAM,GAAG,SAAS,GAAG,MAAM,CAY1E"}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { availableParallelism } from "node:os";
|
|
2
|
+
/**
|
|
3
|
+
* How many images to render at once when nothing is configured: one per CPU
|
|
4
|
+
* the process can actually use. Rasterising is CPU-bound, so starting more
|
|
5
|
+
* than that only queues the work up while holding every pending image in
|
|
6
|
+
* memory.
|
|
7
|
+
*/
|
|
8
|
+
export function resolveConcurrency(concurrency) {
|
|
9
|
+
if (concurrency === undefined) {
|
|
10
|
+
return availableParallelism();
|
|
11
|
+
}
|
|
12
|
+
if (!Number.isSafeInteger(concurrency) || concurrency < 1) {
|
|
13
|
+
throw new Error(`Invalid concurrency ${String(concurrency)}; expected a positive integer.`);
|
|
14
|
+
}
|
|
15
|
+
return concurrency;
|
|
16
|
+
}
|
|
17
|
+
//# sourceMappingURL=options.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"options.js","sourceRoot":"","sources":["../../src/generate/options.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,oBAAoB,EAAE,MAAM,SAAS,CAAC;AAqD/C;;;;;GAKG;AACH,MAAM,UAAU,kBAAkB,CAAC,WAA+B;IAChE,IAAI,WAAW,KAAK,SAAS,EAAE,CAAC;QAC9B,OAAO,oBAAoB,EAAE,CAAC;IAChC,CAAC;IAED,IAAI,CAAC,MAAM,CAAC,aAAa,CAAC,WAAW,CAAC,IAAI,WAAW,GAAG,CAAC,EAAE,CAAC;QAC1D,MAAM,IAAI,KAAK,CACb,uBAAuB,MAAM,CAAC,WAAW,CAAC,gCAAgC,CAC3E,CAAC;IACJ,CAAC;IAED,OAAO,WAAW,CAAC;AACrB,CAAC"}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import type { ContentFile, OutputSize } from "../types.js";
|
|
2
|
+
/**
|
|
3
|
+
* Default output path: named `<slug>-<size>.png`, alongside the content file.
|
|
4
|
+
*
|
|
5
|
+
* This is the `beside-content` placement reached without a content root to
|
|
6
|
+
* place from, so it takes the root off the file itself. It stays its own
|
|
7
|
+
* export because it is what `generate`'s `outputPath` callback replaces, and
|
|
8
|
+
* a caller wrapping the default has to be able to call it. It never hashes:
|
|
9
|
+
* a hash names one rendering of an image, and this has no way to know which.
|
|
10
|
+
*/
|
|
11
|
+
export declare function defaultOutputPath(file: ContentFile, size: OutputSize): string;
|
|
12
|
+
//# sourceMappingURL=output-path.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"output-path.d.ts","sourceRoot":"","sources":["../../src/generate/output-path.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,WAAW,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAE3D;;;;;;;;GAQG;AACH,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,WAAW,EAAE,IAAI,EAAE,UAAU,GAAG,MAAM,CAS7E"}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import path from "node:path";
|
|
2
|
+
import { besideContent } from "../placement/index.js";
|
|
3
|
+
/**
|
|
4
|
+
* Default output path: named `<slug>-<size>.png`, alongside the content file.
|
|
5
|
+
*
|
|
6
|
+
* This is the `beside-content` placement reached without a content root to
|
|
7
|
+
* place from, so it takes the root off the file itself. It stays its own
|
|
8
|
+
* export because it is what `generate`'s `outputPath` callback replaces, and
|
|
9
|
+
* a caller wrapping the default has to be able to call it. It never hashes:
|
|
10
|
+
* a hash names one rendering of an image, and this has no way to know which.
|
|
11
|
+
*/
|
|
12
|
+
export function defaultOutputPath(file, size) {
|
|
13
|
+
// `absolutePath` ends with `contentPath` by construction, so dropping it
|
|
14
|
+
// leaves the directory the walk started from.
|
|
15
|
+
const root = file.absolutePath.slice(0, file.absolutePath.length - file.contentPath.length);
|
|
16
|
+
return path.join(root, ...besideContent(file, size, undefined).split("/"));
|
|
17
|
+
}
|
|
18
|
+
//# sourceMappingURL=output-path.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"output-path.js","sourceRoot":"","sources":["../../src/generate/output-path.ts"],"names":[],"mappings":"AAAA,OAAO,IAAI,MAAM,WAAW,CAAC;AAE7B,OAAO,EAAE,aAAa,EAAE,MAAM,uBAAuB,CAAC;AAGtD;;;;;;;;GAQG;AACH,MAAM,UAAU,iBAAiB,CAAC,IAAiB,EAAE,IAAgB;IACnE,yEAAyE;IACzE,8CAA8C;IAC9C,MAAM,IAAI,GAAG,IAAI,CAAC,YAAY,CAAC,KAAK,CAClC,CAAC,EACD,IAAI,CAAC,YAAY,CAAC,MAAM,GAAG,IAAI,CAAC,WAAW,CAAC,MAAM,CACnD,CAAC;IAEF,OAAO,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,GAAG,aAAa,CAAC,IAAI,EAAE,IAAI,EAAE,SAAS,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC;AAC7E,CAAC"}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import type { RenderJob } from "./job.js";
|
|
2
|
+
/**
|
|
3
|
+
* Reject a manifest written over one of the images it describes.
|
|
4
|
+
*
|
|
5
|
+
* The manifest is written last, so it wins: the image is replaced by JSON, and
|
|
6
|
+
* — its stamp gone with it — rendered again on every build afterwards. It is
|
|
7
|
+
* the same collision as two images sharing a path, so it is answered here,
|
|
8
|
+
* where a path is already compared the way the filesystem would.
|
|
9
|
+
*/
|
|
10
|
+
export declare function assertManifestIsNotAnImage(manifestPath: string | undefined, jobs: readonly RenderJob[]): void;
|
|
11
|
+
/**
|
|
12
|
+
* Reject a build in which two images would be written to one path.
|
|
13
|
+
*
|
|
14
|
+
* They do not merely lose an image between them: each stamps the file with its
|
|
15
|
+
* own digest, so every later build finds a stamp that does not match and
|
|
16
|
+
* renders both again, for ever.
|
|
17
|
+
*
|
|
18
|
+
* Every job is checked, posts included. That used to be older ground worth
|
|
19
|
+
* leaving alone — two posts collided only if they shared a directory and a
|
|
20
|
+
* slug — but `public-dir` gathers a whole tree into one directory, where every
|
|
21
|
+
* post sharing a basename with another lands on it. Naming both sides is what
|
|
22
|
+
* makes that worth reporting: the path alone does not say which two posts.
|
|
23
|
+
*
|
|
24
|
+
* Paths are compared resolved, since a placement names an absolute path and an
|
|
25
|
+
* extra names whatever the config wrote.
|
|
26
|
+
*/
|
|
27
|
+
export declare function assertDistinctOutputs(jobs: readonly RenderJob[]): void;
|
|
28
|
+
//# sourceMappingURL=outputs.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"outputs.d.ts","sourceRoot":"","sources":["../../src/generate/outputs.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,UAAU,CAAC;AA0B1C;;;;;;;GAOG;AACH,wBAAgB,0BAA0B,CACxC,YAAY,EAAE,MAAM,GAAG,SAAS,EAChC,IAAI,EAAE,SAAS,SAAS,EAAE,GACzB,IAAI,CAeN;AAED;;;;;;;;;;;;;;;GAeG;AACH,wBAAgB,qBAAqB,CAAC,IAAI,EAAE,SAAS,SAAS,EAAE,GAAG,IAAI,CAiBtE"}
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
import path from "node:path";
|
|
2
|
+
/**
|
|
3
|
+
* Whether the filesystem underneath treats `Card.png` and `card.png` as one
|
|
4
|
+
* file. Read off the platform rather than probed: a case-sensitive volume on
|
|
5
|
+
* macOS would have two images it could have kept told to rename one of them,
|
|
6
|
+
* which is a rare config and an obvious fix, where missing a real collision
|
|
7
|
+
* leaves a build re-rendering for ever.
|
|
8
|
+
*/
|
|
9
|
+
const isCaseInsensitive = process.platform === "darwin" || process.platform === "win32";
|
|
10
|
+
/**
|
|
11
|
+
* How a path is compared, which is not always how it is written: where case
|
|
12
|
+
* does not distinguish two files, it must not distinguish two jobs either.
|
|
13
|
+
*/
|
|
14
|
+
function comparable(outputPath) {
|
|
15
|
+
const absolute = path.resolve(outputPath);
|
|
16
|
+
return isCaseInsensitive ? absolute.toLowerCase() : absolute;
|
|
17
|
+
}
|
|
18
|
+
/** What to call a job in a message: the post it came from, or its path. */
|
|
19
|
+
function describe(job) {
|
|
20
|
+
return job.contentPath ?? `extra "${job.outputPath}"`;
|
|
21
|
+
}
|
|
22
|
+
/**
|
|
23
|
+
* Reject a manifest written over one of the images it describes.
|
|
24
|
+
*
|
|
25
|
+
* The manifest is written last, so it wins: the image is replaced by JSON, and
|
|
26
|
+
* — its stamp gone with it — rendered again on every build afterwards. It is
|
|
27
|
+
* the same collision as two images sharing a path, so it is answered here,
|
|
28
|
+
* where a path is already compared the way the filesystem would.
|
|
29
|
+
*/
|
|
30
|
+
export function assertManifestIsNotAnImage(manifestPath, jobs) {
|
|
31
|
+
if (manifestPath === undefined) {
|
|
32
|
+
return;
|
|
33
|
+
}
|
|
34
|
+
const key = comparable(manifestPath);
|
|
35
|
+
const clash = jobs.find((job) => comparable(job.outputPath) === key);
|
|
36
|
+
if (clash !== undefined) {
|
|
37
|
+
throw new Error(`The manifest path "${manifestPath}" is where ${describe(clash)} is` +
|
|
38
|
+
` written. The manifest is written last, so it would replace the` +
|
|
39
|
+
` image; give one of them a path of its own.`);
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
/**
|
|
43
|
+
* Reject a build in which two images would be written to one path.
|
|
44
|
+
*
|
|
45
|
+
* They do not merely lose an image between them: each stamps the file with its
|
|
46
|
+
* own digest, so every later build finds a stamp that does not match and
|
|
47
|
+
* renders both again, for ever.
|
|
48
|
+
*
|
|
49
|
+
* Every job is checked, posts included. That used to be older ground worth
|
|
50
|
+
* leaving alone — two posts collided only if they shared a directory and a
|
|
51
|
+
* slug — but `public-dir` gathers a whole tree into one directory, where every
|
|
52
|
+
* post sharing a basename with another lands on it. Naming both sides is what
|
|
53
|
+
* makes that worth reporting: the path alone does not say which two posts.
|
|
54
|
+
*
|
|
55
|
+
* Paths are compared resolved, since a placement names an absolute path and an
|
|
56
|
+
* extra names whatever the config wrote.
|
|
57
|
+
*/
|
|
58
|
+
export function assertDistinctOutputs(jobs) {
|
|
59
|
+
const taken = new Map();
|
|
60
|
+
for (const job of jobs) {
|
|
61
|
+
const key = comparable(job.outputPath);
|
|
62
|
+
const first = taken.get(key);
|
|
63
|
+
if (first !== undefined) {
|
|
64
|
+
throw new Error(`Two images would be written to "${job.outputPath}":` +
|
|
65
|
+
` ${describe(first)} and ${describe(job)}. Each image needs a path` +
|
|
66
|
+
` of its own, or one is lost and both re-render on every build.`);
|
|
67
|
+
}
|
|
68
|
+
taken.set(key, job);
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
//# sourceMappingURL=outputs.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"outputs.js","sourceRoot":"","sources":["../../src/generate/outputs.ts"],"names":[],"mappings":"AAAA,OAAO,IAAI,MAAM,WAAW,CAAC;AAI7B;;;;;;GAMG;AACH,MAAM,iBAAiB,GACrB,OAAO,CAAC,QAAQ,KAAK,QAAQ,IAAI,OAAO,CAAC,QAAQ,KAAK,OAAO,CAAC;AAEhE;;;GAGG;AACH,SAAS,UAAU,CAAC,UAAkB;IACpC,MAAM,QAAQ,GAAG,IAAI,CAAC,OAAO,CAAC,UAAU,CAAC,CAAC;IAC1C,OAAO,iBAAiB,CAAC,CAAC,CAAC,QAAQ,CAAC,WAAW,EAAE,CAAC,CAAC,CAAC,QAAQ,CAAC;AAC/D,CAAC;AAED,2EAA2E;AAC3E,SAAS,QAAQ,CAAC,GAAc;IAC9B,OAAO,GAAG,CAAC,WAAW,IAAI,UAAU,GAAG,CAAC,UAAU,GAAG,CAAC;AACxD,CAAC;AAED;;;;;;;GAOG;AACH,MAAM,UAAU,0BAA0B,CACxC,YAAgC,EAChC,IAA0B;IAE1B,IAAI,YAAY,KAAK,SAAS,EAAE,CAAC;QAC/B,OAAO;IACT,CAAC;IAED,MAAM,GAAG,GAAG,UAAU,CAAC,YAAY,CAAC,CAAC;IACrC,MAAM,KAAK,GAAG,IAAI,CAAC,IAAI,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,UAAU,CAAC,GAAG,CAAC,UAAU,CAAC,KAAK,GAAG,CAAC,CAAC;IAErE,IAAI,KAAK,KAAK,SAAS,EAAE,CAAC;QACxB,MAAM,IAAI,KAAK,CACb,sBAAsB,YAAY,cAAc,QAAQ,CAAC,KAAK,CAAC,KAAK;YAClE,iEAAiE;YACjE,6CAA6C,CAChD,CAAC;IACJ,CAAC;AACH,CAAC;AAED;;;;;;;;;;;;;;;GAeG;AACH,MAAM,UAAU,qBAAqB,CAAC,IAA0B;IAC9D,MAAM,KAAK,GAAG,IAAI,GAAG,EAAqB,CAAC;IAE3C,KAAK,MAAM,GAAG,IAAI,IAAI,EAAE,CAAC;QACvB,MAAM,GAAG,GAAG,UAAU,CAAC,GAAG,CAAC,UAAU,CAAC,CAAC;QACvC,MAAM,KAAK,GAAG,KAAK,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;QAE7B,IAAI,KAAK,KAAK,SAAS,EAAE,CAAC;YACxB,MAAM,IAAI,KAAK,CACb,mCAAmC,GAAG,CAAC,UAAU,IAAI;gBACnD,IAAI,QAAQ,CAAC,KAAK,CAAC,QAAQ,QAAQ,CAAC,GAAG,CAAC,2BAA2B;gBACnE,gEAAgE,CACnE,CAAC;QACJ,CAAC;QAED,KAAK,CAAC,GAAG,CAAC,GAAG,EAAE,GAAG,CAAC,CAAC;IACtB,CAAC;AACH,CAAC"}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import type { PlannedManifest } from "../manifest/index.js";
|
|
2
|
+
import type { Stamper } from "../stamp/index.js";
|
|
3
|
+
import type { RenderJob } from "./job.js";
|
|
4
|
+
import type { GenerateOptions } from "./options.js";
|
|
5
|
+
/**
|
|
6
|
+
* Everything a build needs before it starts rendering: one job per image, and
|
|
7
|
+
* the stamper that says which of them can be skipped.
|
|
8
|
+
*/
|
|
9
|
+
export interface BuildPlan {
|
|
10
|
+
readonly jobs: readonly RenderJob[];
|
|
11
|
+
readonly stamper: Stamper;
|
|
12
|
+
/** What to write down about the build, where a config asked for it. */
|
|
13
|
+
readonly manifest: PlannedManifest | undefined;
|
|
14
|
+
}
|
|
15
|
+
/**
|
|
16
|
+
* Work out what a build has to render. The per-size configs are resolved once
|
|
17
|
+
* rather than once per image: the overrides are the same for every post, and
|
|
18
|
+
* resolving re-reads the configured font files.
|
|
19
|
+
*/
|
|
20
|
+
export declare function planBuild(options: GenerateOptions): Promise<BuildPlan>;
|
|
21
|
+
//# sourceMappingURL=plan.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"plan.d.ts","sourceRoot":"","sources":["../../src/generate/plan.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,sBAAsB,CAAC;AAE5D,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,mBAAmB,CAAC;AAKjD,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,UAAU,CAAC;AAC1C,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,cAAc,CAAC;AAMpD;;;GAGG;AACH,MAAM,WAAW,SAAS;IACxB,QAAQ,CAAC,IAAI,EAAE,SAAS,SAAS,EAAE,CAAC;IACpC,QAAQ,CAAC,OAAO,EAAE,OAAO,CAAC;IAC1B,uEAAuE;IACvE,QAAQ,CAAC,QAAQ,EAAE,eAAe,GAAG,SAAS,CAAC;CAChD;AAqBD;;;;GAIG;AACH,wBAAsB,SAAS,CAAC,OAAO,EAAE,eAAe,GAAG,OAAO,CAAC,SAAS,CAAC,CAmD5E"}
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
import { resolveConfig } from "../config/index.js";
|
|
2
|
+
import { resolveConfigForSize } from "../config/size.js";
|
|
3
|
+
import { walkContent } from "../content/index.js";
|
|
4
|
+
import { planManifest } from "../manifest/index.js";
|
|
5
|
+
import { createStamper } from "../stamp/index.js";
|
|
6
|
+
import { createPlacer } from "../placement/index.js";
|
|
7
|
+
import { extraJobs } from "./extra.js";
|
|
8
|
+
import { assertDistinctOutputs, assertManifestIsNotAnImage, } from "./outputs.js";
|
|
9
|
+
/**
|
|
10
|
+
* How this build places its images: the configured placement, or `outputPath`
|
|
11
|
+
* where a caller passed one.
|
|
12
|
+
*
|
|
13
|
+
* `outputPath` is the programmatic equivalent of a `custom` placement and wins
|
|
14
|
+
* for the same reason `walk` beats `config.content`. The URL then comes from
|
|
15
|
+
* nowhere: the placement no longer describes where the file went, and the one
|
|
16
|
+
* it would have named is not where the image is.
|
|
17
|
+
*/
|
|
18
|
+
function placer(options) {
|
|
19
|
+
const override = options.outputPath;
|
|
20
|
+
if (override === undefined) {
|
|
21
|
+
return createPlacer(options.config?.placement, options.contentDir);
|
|
22
|
+
}
|
|
23
|
+
return (file, size) => ({ path: override(file, size), url: undefined });
|
|
24
|
+
}
|
|
25
|
+
/**
|
|
26
|
+
* Work out what a build has to render. The per-size configs are resolved once
|
|
27
|
+
* rather than once per image: the overrides are the same for every post, and
|
|
28
|
+
* resolving re-reads the configured font files.
|
|
29
|
+
*/
|
|
30
|
+
export async function planBuild(options) {
|
|
31
|
+
const resolved = resolveConfig(options.config);
|
|
32
|
+
const place = placer(options);
|
|
33
|
+
const configBySize = new Map(resolved.sizes.map((size) => [
|
|
34
|
+
size.name,
|
|
35
|
+
resolveConfigForSize(options.config, size),
|
|
36
|
+
]));
|
|
37
|
+
const [stamper, files] = await Promise.all([
|
|
38
|
+
createStamper(resolved),
|
|
39
|
+
// Content options can come from the config module, which is the only route
|
|
40
|
+
// a CLI user has to them; `walk` is the programmatic override and wins.
|
|
41
|
+
walkContent({
|
|
42
|
+
dir: options.contentDir,
|
|
43
|
+
...options.config?.content,
|
|
44
|
+
...options.walk,
|
|
45
|
+
}),
|
|
46
|
+
]);
|
|
47
|
+
const jobs = files.flatMap((file) => resolved.sizes.map((size) => {
|
|
48
|
+
// Stamped before it is placed, not after: a hashed filename is built
|
|
49
|
+
// from the stamp, so the name cannot be known before the digest is.
|
|
50
|
+
const stamp = stamper.stamp(file.props, size);
|
|
51
|
+
const placed = place(file, size, stamp);
|
|
52
|
+
return {
|
|
53
|
+
contentPath: file.contentPath,
|
|
54
|
+
slug: file.slug,
|
|
55
|
+
props: file.props,
|
|
56
|
+
size,
|
|
57
|
+
outputPath: placed.path,
|
|
58
|
+
url: placed.url,
|
|
59
|
+
stamp,
|
|
60
|
+
config: configBySize.get(size.name) ?? resolved,
|
|
61
|
+
};
|
|
62
|
+
}));
|
|
63
|
+
const all = [...jobs, ...extraJobs(options.config, resolved, stamper)];
|
|
64
|
+
assertDistinctOutputs(all);
|
|
65
|
+
assertManifestIsNotAnImage(options.config?.manifest, all);
|
|
66
|
+
return {
|
|
67
|
+
jobs: all,
|
|
68
|
+
stamper,
|
|
69
|
+
manifest: planManifest(options.config?.manifest, all),
|
|
70
|
+
};
|
|
71
|
+
}
|
|
72
|
+
//# sourceMappingURL=plan.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"plan.js","sourceRoot":"","sources":["../../src/generate/plan.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AACnD,OAAO,EAAE,oBAAoB,EAAE,MAAM,mBAAmB,CAAC;AACzD,OAAO,EAAE,WAAW,EAAE,MAAM,qBAAqB,CAAC;AAElD,OAAO,EAAE,YAAY,EAAE,MAAM,sBAAsB,CAAC;AAEpD,OAAO,EAAE,aAAa,EAAE,MAAM,mBAAmB,CAAC;AAElD,OAAO,EAAE,YAAY,EAAE,MAAM,uBAAuB,CAAC;AACrD,OAAO,EAAE,SAAS,EAAE,MAAM,YAAY,CAAC;AAGvC,OAAO,EACL,qBAAqB,EACrB,0BAA0B,GAC3B,MAAM,cAAc,CAAC;AAatB;;;;;;;;GAQG;AACH,SAAS,MAAM,CAAC,OAAwB;IACtC,MAAM,QAAQ,GAAG,OAAO,CAAC,UAAU,CAAC;IAEpC,IAAI,QAAQ,KAAK,SAAS,EAAE,CAAC;QAC3B,OAAO,YAAY,CAAC,OAAO,CAAC,MAAM,EAAE,SAAS,EAAE,OAAO,CAAC,UAAU,CAAC,CAAC;IACrE,CAAC;IAED,OAAO,CAAC,IAAI,EAAE,IAAI,EAAE,EAAE,CAAC,CAAC,EAAE,IAAI,EAAE,QAAQ,CAAC,IAAI,EAAE,IAAI,CAAC,EAAE,GAAG,EAAE,SAAS,EAAE,CAAC,CAAC;AAC1E,CAAC;AAED;;;;GAIG;AACH,MAAM,CAAC,KAAK,UAAU,SAAS,CAAC,OAAwB;IACtD,MAAM,QAAQ,GAAG,aAAa,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC;IAC/C,MAAM,KAAK,GAAG,MAAM,CAAC,OAAO,CAAC,CAAC;IAE9B,MAAM,YAAY,GAAG,IAAI,GAAG,CAC1B,QAAQ,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC;QAC3B,IAAI,CAAC,IAAI;QACT,oBAAoB,CAAC,OAAO,CAAC,MAAM,EAAE,IAAI,CAAC;KAC3C,CAAC,CACH,CAAC;IAEF,MAAM,CAAC,OAAO,EAAE,KAAK,CAAC,GAAG,MAAM,OAAO,CAAC,GAAG,CAAC;QACzC,aAAa,CAAC,QAAQ,CAAC;QACvB,2EAA2E;QAC3E,wEAAwE;QACxE,WAAW,CAAC;YACV,GAAG,EAAE,OAAO,CAAC,UAAU;YACvB,GAAG,OAAO,CAAC,MAAM,EAAE,OAAO;YAC1B,GAAG,OAAO,CAAC,IAAI;SAChB,CAAC;KACH,CAAC,CAAC;IAEH,MAAM,IAAI,GAAG,KAAK,CAAC,OAAO,CAAC,CAAC,IAAI,EAAE,EAAE,CAClC,QAAQ,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE;QAC1B,qEAAqE;QACrE,oEAAoE;QACpE,MAAM,KAAK,GAAG,OAAO,CAAC,KAAK,CAAC,IAAI,CAAC,KAAK,EAAE,IAAI,CAAC,CAAC;QAC9C,MAAM,MAAM,GAAG,KAAK,CAAC,IAAI,EAAE,IAAI,EAAE,KAAK,CAAC,CAAC;QAExC,OAAO;YACL,WAAW,EAAE,IAAI,CAAC,WAAW;YAC7B,IAAI,EAAE,IAAI,CAAC,IAAI;YACf,KAAK,EAAE,IAAI,CAAC,KAAK;YACjB,IAAI;YACJ,UAAU,EAAE,MAAM,CAAC,IAAI;YACvB,GAAG,EAAE,MAAM,CAAC,GAAG;YACf,KAAK;YACL,MAAM,EAAE,YAAY,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,QAAQ;SAChD,CAAC;IACJ,CAAC,CAAC,CACH,CAAC;IAEF,MAAM,GAAG,GAAG,CAAC,GAAG,IAAI,EAAE,GAAG,SAAS,CAAC,OAAO,CAAC,MAAM,EAAE,QAAQ,EAAE,OAAO,CAAC,CAAC,CAAC;IACvE,qBAAqB,CAAC,GAAG,CAAC,CAAC;IAC3B,0BAA0B,CAAC,OAAO,CAAC,MAAM,EAAE,QAAQ,EAAE,GAAG,CAAC,CAAC;IAE1D,OAAO;QACL,IAAI,EAAE,GAAG;QACT,OAAO;QACP,QAAQ,EAAE,YAAY,CAAC,OAAO,CAAC,MAAM,EAAE,QAAQ,EAAE,GAAG,CAAC;KACtD,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import type { RenderJob } from "./job.js";
|
|
2
|
+
/**
|
|
3
|
+
* Render one image and write it, stamped, to its output path, creating
|
|
4
|
+
* whatever directories that path needs.
|
|
5
|
+
*
|
|
6
|
+
* Warnings name the image they came from: a build renders many, and "shorten
|
|
7
|
+
* the sample" is no use without knowing which sample. An extra image has no
|
|
8
|
+
* content file to name, so it is named by where it is being written.
|
|
9
|
+
*/
|
|
10
|
+
export declare function renderImage(job: RenderJob, stamp: string): Promise<void>;
|
|
11
|
+
//# sourceMappingURL=render-image.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"render-image.d.ts","sourceRoot":"","sources":["../../src/generate/render-image.ts"],"names":[],"mappings":"AAMA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,UAAU,CAAC;AAE1C;;;;;;;GAOG;AACH,wBAAsB,WAAW,CAC/B,GAAG,EAAE,SAAS,EACd,KAAK,EAAE,MAAM,GACZ,OAAO,CAAC,IAAI,CAAC,CAef"}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import { mkdir, writeFile } from "node:fs/promises";
|
|
2
|
+
import path from "node:path";
|
|
3
|
+
import { buildSvg, renderSvgToPng } from "../render/index.js";
|
|
4
|
+
import { stampPng } from "../stamp/index.js";
|
|
5
|
+
/**
|
|
6
|
+
* Render one image and write it, stamped, to its output path, creating
|
|
7
|
+
* whatever directories that path needs.
|
|
8
|
+
*
|
|
9
|
+
* Warnings name the image they came from: a build renders many, and "shorten
|
|
10
|
+
* the sample" is no use without knowing which sample. An extra image has no
|
|
11
|
+
* content file to name, so it is named by where it is being written.
|
|
12
|
+
*/
|
|
13
|
+
export async function renderImage(job, stamp) {
|
|
14
|
+
const dimensions = { width: job.size.width, height: job.size.height };
|
|
15
|
+
const source = job.contentPath ?? job.outputPath;
|
|
16
|
+
const config = {
|
|
17
|
+
...job.config,
|
|
18
|
+
onWarning: (message) => {
|
|
19
|
+
job.config.onWarning(`${source}: ${message}`);
|
|
20
|
+
},
|
|
21
|
+
};
|
|
22
|
+
const svg = await buildSvg(job.props, config, dimensions);
|
|
23
|
+
const png = await renderSvgToPng(svg, dimensions, config);
|
|
24
|
+
await mkdir(path.dirname(job.outputPath), { recursive: true });
|
|
25
|
+
await writeFile(job.outputPath, stampPng(png, stamp));
|
|
26
|
+
}
|
|
27
|
+
//# sourceMappingURL=render-image.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"render-image.js","sourceRoot":"","sources":["../../src/generate/render-image.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAC;AACpD,OAAO,IAAI,MAAM,WAAW,CAAC;AAE7B,OAAO,EAAE,QAAQ,EAAE,cAAc,EAAE,MAAM,oBAAoB,CAAC;AAC9D,OAAO,EAAE,QAAQ,EAAE,MAAM,mBAAmB,CAAC;AAI7C;;;;;;;GAOG;AACH,MAAM,CAAC,KAAK,UAAU,WAAW,CAC/B,GAAc,EACd,KAAa;IAEb,MAAM,UAAU,GAAG,EAAE,KAAK,EAAE,GAAG,CAAC,IAAI,CAAC,KAAK,EAAE,MAAM,EAAE,GAAG,CAAC,IAAI,CAAC,MAAM,EAAE,CAAC;IACtE,MAAM,MAAM,GAAG,GAAG,CAAC,WAAW,IAAI,GAAG,CAAC,UAAU,CAAC;IACjD,MAAM,MAAM,GAAmB;QAC7B,GAAG,GAAG,CAAC,MAAM;QACb,SAAS,EAAE,CAAC,OAAe,EAAQ,EAAE;YACnC,GAAG,CAAC,MAAM,CAAC,SAAS,CAAC,GAAG,MAAM,KAAK,OAAO,EAAE,CAAC,CAAC;QAChD,CAAC;KACF,CAAC;IAEF,MAAM,GAAG,GAAG,MAAM,QAAQ,CAAC,GAAG,CAAC,KAAK,EAAE,MAAM,EAAE,UAAU,CAAC,CAAC;IAC1D,MAAM,GAAG,GAAG,MAAM,cAAc,CAAC,GAAG,EAAE,UAAU,EAAE,MAAM,CAAC,CAAC;IAE1D,MAAM,KAAK,CAAC,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,UAAU,CAAC,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;IAC/D,MAAM,SAAS,CAAC,GAAG,CAAC,UAAU,EAAE,QAAQ,CAAC,GAAG,EAAE,KAAK,CAAC,CAAC,CAAC;AACxD,CAAC"}
|
package/dist/generate.d.ts
CHANGED
|
@@ -7,7 +7,7 @@ export interface GeneratedImage {
|
|
|
7
7
|
readonly contentPath: string;
|
|
8
8
|
readonly size: OutputSize;
|
|
9
9
|
readonly outputPath: string;
|
|
10
|
-
/** True when an
|
|
10
|
+
/** True when an up-to-date image was left in place (no `overwrite`). */
|
|
11
11
|
readonly skipped: boolean;
|
|
12
12
|
}
|
|
13
13
|
/**
|
|
@@ -21,22 +21,43 @@ export interface GenerateOptions {
|
|
|
21
21
|
readonly walk?: Omit<WalkOptions, "dir">;
|
|
22
22
|
/** Override where each image is written. */
|
|
23
23
|
readonly outputPath?: (file: ContentFile, size: OutputSize) => string;
|
|
24
|
-
/**
|
|
24
|
+
/**
|
|
25
|
+
* Re-render every image, ignoring the stamps that would otherwise mark them
|
|
26
|
+
* as up to date. Default `false`.
|
|
27
|
+
*/
|
|
25
28
|
readonly overwrite?: boolean;
|
|
29
|
+
/**
|
|
30
|
+
* How many images to render at once. Defaults to the number of CPUs the
|
|
31
|
+
* process can use. Must be a positive integer.
|
|
32
|
+
*/
|
|
33
|
+
readonly concurrency?: number;
|
|
26
34
|
/** Called after each image is written or skipped. */
|
|
27
35
|
readonly onResult?: (result: GeneratedImage) => void;
|
|
28
36
|
}
|
|
29
37
|
/**
|
|
30
|
-
* Default output path:
|
|
38
|
+
* Default output path: named `<slug>-<size>.png`, alongside the content file.
|
|
31
39
|
* The slug carries the post's keywords into the filename and the size name
|
|
32
40
|
* keeps every image distinct (e.g. `my-post-og.png`, `my-post-square.png`).
|
|
41
|
+
*
|
|
42
|
+
* A slug carrying directories of its own — what the `route` strategy produces,
|
|
43
|
+
* and what a frontmatter `slug` of `docs/intro` means — is written from the
|
|
44
|
+
* content root instead, so its path mirrors the route. Resolving it beside the
|
|
45
|
+
* file would repeat the directories that are already in the slug, putting
|
|
46
|
+
* `services/iam` under `content/services/iam/`.
|
|
33
47
|
*/
|
|
34
48
|
export declare function defaultOutputPath(file: ContentFile, size: OutputSize): string;
|
|
35
49
|
/**
|
|
36
50
|
* Walk a content tree and render meta images for every file that declares
|
|
37
|
-
* props, writing PNGs to disk.
|
|
38
|
-
*
|
|
39
|
-
*
|
|
51
|
+
* props, writing PNGs to disk.
|
|
52
|
+
*
|
|
53
|
+
* Each image is stamped with a digest of the props, config and size it came
|
|
54
|
+
* from, so a rebuild renders only what has actually changed: an image whose
|
|
55
|
+
* stamp still matches is left alone, and one whose title, colours or template
|
|
56
|
+
* has moved on is rendered again. `overwrite` ignores the stamps and renders
|
|
57
|
+
* everything. Sizes with no image to render are never rasterised.
|
|
58
|
+
*
|
|
59
|
+
* Rendering runs `concurrency` images at a time rather than all of them, so a
|
|
60
|
+
* large tree does not start hundreds of rasterisations at once.
|
|
40
61
|
*/
|
|
41
62
|
export declare function generate(options: GenerateOptions): Promise<GeneratedImage[]>;
|
|
42
63
|
//# sourceMappingURL=generate.d.ts.map
|
package/dist/generate.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"generate.d.ts","sourceRoot":"","sources":["../src/generate.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,WAAW,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;
|
|
1
|
+
{"version":3,"file":"generate.d.ts","sourceRoot":"","sources":["../src/generate.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,WAAW,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AAKnE,OAAO,KAAK,EAAE,cAAc,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AAE7D;;GAEG;AACH,MAAM,WAAW,cAAc;IAC7B,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAC7B,QAAQ,CAAC,IAAI,EAAE,UAAU,CAAC;IAC1B,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IAC5B,wEAAwE;IACxE,QAAQ,CAAC,OAAO,EAAE,OAAO,CAAC;CAC3B;AAED;;GAEG;AACH,MAAM,WAAW,eAAe;IAC9B,sCAAsC;IACtC,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IAC5B,QAAQ,CAAC,MAAM,CAAC,EAAE,cAAc,CAAC;IACjC,8EAA8E;IAC9E,QAAQ,CAAC,IAAI,CAAC,EAAE,IAAI,CAAC,WAAW,EAAE,KAAK,CAAC,CAAC;IACzC,4CAA4C;IAC5C,QAAQ,CAAC,UAAU,CAAC,EAAE,CAAC,IAAI,EAAE,WAAW,EAAE,IAAI,EAAE,UAAU,KAAK,MAAM,CAAC;IACtE;;;OAGG;IACH,QAAQ,CAAC,SAAS,CAAC,EAAE,OAAO,CAAC;IAC7B;;;OAGG;IACH,QAAQ,CAAC,WAAW,CAAC,EAAE,MAAM,CAAC;IAC9B,qDAAqD;IACrD,QAAQ,CAAC,QAAQ,CAAC,EAAE,CAAC,MAAM,EAAE,cAAc,KAAK,IAAI,CAAC;CACtD;AAsBD;;;;;;;;;;GAUG;AACH,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,WAAW,EAAE,IAAI,EAAE,UAAU,GAAG,MAAM,CAc7E;AAED;;;;;;;;;;;;GAYG;AACH,wBAAsB,QAAQ,CAC5B,OAAO,EAAE,eAAe,GACvB,OAAO,CAAC,cAAc,EAAE,CAAC,CA2D3B"}
|
package/dist/generate.js
CHANGED
|
@@ -1,38 +1,100 @@
|
|
|
1
|
-
import { existsSync } from "node:fs";
|
|
2
1
|
import { mkdir, writeFile } from "node:fs/promises";
|
|
2
|
+
import { availableParallelism } from "node:os";
|
|
3
3
|
import path from "node:path";
|
|
4
|
-
import { resolveConfig } from "./config.js";
|
|
4
|
+
import { resolveConfig, resolveConfigForSize } from "./config.js";
|
|
5
5
|
import { walkContent } from "./content/index.js";
|
|
6
|
+
import { mapConcurrent } from "./pool.js";
|
|
6
7
|
import { buildSvg, renderSvgToPng } from "./render.js";
|
|
8
|
+
import { createStamper, readPngStamp, stampPng } from "./stamp.js";
|
|
7
9
|
/**
|
|
8
|
-
*
|
|
10
|
+
* How many images to render at once when nothing is configured: one per CPU
|
|
11
|
+
* the process can actually use. Rasterising is CPU-bound, so starting more
|
|
12
|
+
* than that only queues the work up while holding every pending image in
|
|
13
|
+
* memory.
|
|
14
|
+
*/
|
|
15
|
+
function resolveConcurrency(concurrency) {
|
|
16
|
+
if (concurrency === undefined) {
|
|
17
|
+
return availableParallelism();
|
|
18
|
+
}
|
|
19
|
+
if (!Number.isSafeInteger(concurrency) || concurrency < 1) {
|
|
20
|
+
throw new Error(`Invalid concurrency ${String(concurrency)}; expected a positive integer.`);
|
|
21
|
+
}
|
|
22
|
+
return concurrency;
|
|
23
|
+
}
|
|
24
|
+
/**
|
|
25
|
+
* Default output path: named `<slug>-<size>.png`, alongside the content file.
|
|
9
26
|
* The slug carries the post's keywords into the filename and the size name
|
|
10
27
|
* keeps every image distinct (e.g. `my-post-og.png`, `my-post-square.png`).
|
|
28
|
+
*
|
|
29
|
+
* A slug carrying directories of its own — what the `route` strategy produces,
|
|
30
|
+
* and what a frontmatter `slug` of `docs/intro` means — is written from the
|
|
31
|
+
* content root instead, so its path mirrors the route. Resolving it beside the
|
|
32
|
+
* file would repeat the directories that are already in the slug, putting
|
|
33
|
+
* `services/iam` under `content/services/iam/`.
|
|
11
34
|
*/
|
|
12
35
|
export function defaultOutputPath(file, size) {
|
|
13
|
-
const
|
|
14
|
-
|
|
36
|
+
const name = `${file.slug}-${size.name}.png`;
|
|
37
|
+
if (!file.slug.includes("/")) {
|
|
38
|
+
return path.join(path.dirname(file.absolutePath), name);
|
|
39
|
+
}
|
|
40
|
+
// `absolutePath` ends with `contentPath` by construction, so dropping it
|
|
41
|
+
// leaves the directory the walk started from.
|
|
42
|
+
const root = file.absolutePath.slice(0, file.absolutePath.length - file.contentPath.length);
|
|
43
|
+
return path.join(root, name);
|
|
15
44
|
}
|
|
16
45
|
/**
|
|
17
46
|
* Walk a content tree and render meta images for every file that declares
|
|
18
|
-
* props, writing PNGs to disk.
|
|
19
|
-
*
|
|
20
|
-
*
|
|
47
|
+
* props, writing PNGs to disk.
|
|
48
|
+
*
|
|
49
|
+
* Each image is stamped with a digest of the props, config and size it came
|
|
50
|
+
* from, so a rebuild renders only what has actually changed: an image whose
|
|
51
|
+
* stamp still matches is left alone, and one whose title, colours or template
|
|
52
|
+
* has moved on is rendered again. `overwrite` ignores the stamps and renders
|
|
53
|
+
* everything. Sizes with no image to render are never rasterised.
|
|
54
|
+
*
|
|
55
|
+
* Rendering runs `concurrency` images at a time rather than all of them, so a
|
|
56
|
+
* large tree does not start hundreds of rasterisations at once.
|
|
21
57
|
*/
|
|
22
58
|
export async function generate(options) {
|
|
23
59
|
const resolved = resolveConfig(options.config);
|
|
60
|
+
const concurrency = resolveConcurrency(options.concurrency);
|
|
24
61
|
const toOutputPath = options.outputPath ?? defaultOutputPath;
|
|
25
|
-
|
|
62
|
+
// Resolved once per size rather than once per image: the overrides are the
|
|
63
|
+
// same for every post, and resolving re-reads the configured font files.
|
|
64
|
+
const configBySize = new Map(resolved.sizes.map((size) => [
|
|
65
|
+
size.name,
|
|
66
|
+
resolveConfigForSize(options.config, size),
|
|
67
|
+
]));
|
|
68
|
+
const [stamper, files] = await Promise.all([
|
|
69
|
+
createStamper(resolved),
|
|
70
|
+
// Content options can come from the config module, which is the only route
|
|
71
|
+
// a CLI user has to them; `walk` is the programmatic override and wins.
|
|
72
|
+
walkContent({
|
|
73
|
+
dir: options.contentDir,
|
|
74
|
+
...options.config?.content,
|
|
75
|
+
...options.walk,
|
|
76
|
+
}),
|
|
77
|
+
]);
|
|
26
78
|
const jobs = files.flatMap((file) => resolved.sizes.map((size) => ({ file, size })));
|
|
27
|
-
return
|
|
79
|
+
return mapConcurrent(jobs, concurrency, async ({ file, size }) => {
|
|
28
80
|
const outputPath = toOutputPath(file, size);
|
|
29
|
-
const
|
|
81
|
+
const stamp = stamper.stamp(file.props, size);
|
|
82
|
+
const isSkipped = options.overwrite !== true && (await readPngStamp(outputPath)) === stamp;
|
|
30
83
|
if (!isSkipped) {
|
|
31
84
|
const dimensions = { width: size.width, height: size.height };
|
|
32
|
-
const
|
|
33
|
-
|
|
85
|
+
const sizeConfig = configBySize.get(size.name) ?? resolved;
|
|
86
|
+
// Warnings name the post they came from: a build renders many images,
|
|
87
|
+
// and "shorten the sample" is no use without knowing which sample.
|
|
88
|
+
const config = {
|
|
89
|
+
...sizeConfig,
|
|
90
|
+
onWarning: (message) => {
|
|
91
|
+
resolved.onWarning(`${file.contentPath}: ${message}`);
|
|
92
|
+
},
|
|
93
|
+
};
|
|
94
|
+
const svg = await buildSvg(file.props, config, dimensions);
|
|
95
|
+
const png = await renderSvgToPng(svg, dimensions, config);
|
|
34
96
|
await mkdir(path.dirname(outputPath), { recursive: true });
|
|
35
|
-
await writeFile(outputPath, png);
|
|
97
|
+
await writeFile(outputPath, stampPng(png, stamp));
|
|
36
98
|
}
|
|
37
99
|
const result = {
|
|
38
100
|
contentPath: file.contentPath,
|
|
@@ -42,6 +104,6 @@ export async function generate(options) {
|
|
|
42
104
|
};
|
|
43
105
|
options.onResult?.(result);
|
|
44
106
|
return result;
|
|
45
|
-
})
|
|
107
|
+
});
|
|
46
108
|
}
|
|
47
109
|
//# sourceMappingURL=generate.js.map
|