@cogenta/render 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/astro/integration.d.ts +57 -0
- package/dist/astro/integration.d.ts.map +1 -0
- package/dist/astro/integration.js +72 -0
- package/dist/astro/integration.js.map +1 -0
- package/dist/build/index.d.ts +7 -0
- package/dist/build/index.d.ts.map +1 -0
- package/dist/build/index.js +7 -0
- package/dist/build/index.js.map +1 -0
- package/dist/build/integration.d.ts +25 -0
- package/dist/build/integration.d.ts.map +1 -0
- package/dist/build/integration.js +41 -0
- package/dist/build/integration.js.map +1 -0
- package/dist/build/plan.d.ts +41 -0
- package/dist/build/plan.d.ts.map +1 -0
- package/dist/build/plan.js +48 -0
- package/dist/build/plan.js.map +1 -0
- package/dist/build/refusal.d.ts +14 -0
- package/dist/build/refusal.d.ts.map +1 -0
- package/dist/build/refusal.js +110 -0
- package/dist/build/refusal.js.map +1 -0
- package/dist/build/requirements.d.ts +59 -0
- package/dist/build/requirements.d.ts.map +1 -0
- package/dist/build/requirements.js +74 -0
- package/dist/build/requirements.js.map +1 -0
- package/dist/build/run-build.d.ts +43 -0
- package/dist/build/run-build.d.ts.map +1 -0
- package/dist/build/run-build.js +73 -0
- package/dist/build/run-build.js.map +1 -0
- package/dist/build/targets.d.ts +47 -0
- package/dist/build/targets.d.ts.map +1 -0
- package/dist/build/targets.js +69 -0
- package/dist/build/targets.js.map +1 -0
- package/dist/cache/index.d.ts +7 -0
- package/dist/cache/index.d.ts.map +1 -0
- package/dist/cache/index.js +4 -0
- package/dist/cache/index.js.map +1 -0
- package/dist/cache/page-cache.d.ts +64 -0
- package/dist/cache/page-cache.d.ts.map +1 -0
- package/dist/cache/page-cache.js +128 -0
- package/dist/cache/page-cache.js.map +1 -0
- package/dist/cache/recorder.d.ts +49 -0
- package/dist/cache/recorder.d.ts.map +1 -0
- package/dist/cache/recorder.js +77 -0
- package/dist/cache/recorder.js.map +1 -0
- package/dist/cache/tags.d.ts +55 -0
- package/dist/cache/tags.d.ts.map +1 -0
- package/dist/cache/tags.js +62 -0
- package/dist/cache/tags.js.map +1 -0
- package/dist/config.d.ts +48 -0
- package/dist/config.d.ts.map +1 -0
- package/dist/config.js +44 -0
- package/dist/config.js.map +1 -0
- package/dist/content/client.d.ts +35 -0
- package/dist/content/client.d.ts.map +1 -0
- package/dist/content/client.js +155 -0
- package/dist/content/client.js.map +1 -0
- package/dist/content/types.d.ts +104 -0
- package/dist/content/types.d.ts.map +1 -0
- package/dist/content/types.js +16 -0
- package/dist/content/types.js.map +1 -0
- package/dist/context/render-context.d.ts +31 -0
- package/dist/context/render-context.d.ts.map +1 -0
- package/dist/context/render-context.js +152 -0
- package/dist/context/render-context.js.map +1 -0
- package/dist/context/types.d.ts +49 -0
- package/dist/context/types.d.ts.map +1 -0
- package/dist/context/types.js +2 -0
- package/dist/context/types.js.map +1 -0
- package/dist/images/errors.d.ts +20 -0
- package/dist/images/errors.d.ts.map +1 -0
- package/dist/images/errors.js +58 -0
- package/dist/images/errors.js.map +1 -0
- package/dist/images/format.d.ts +18 -0
- package/dist/images/format.d.ts.map +1 -0
- package/dist/images/format.js +34 -0
- package/dist/images/format.js.map +1 -0
- package/dist/images/geometry.d.ts +46 -0
- package/dist/images/geometry.d.ts.map +1 -0
- package/dist/images/geometry.js +127 -0
- package/dist/images/geometry.js.map +1 -0
- package/dist/images/index.d.ts +29 -0
- package/dist/images/index.d.ts.map +1 -0
- package/dist/images/index.js +30 -0
- package/dist/images/index.js.map +1 -0
- package/dist/images/pipeline.d.ts +51 -0
- package/dist/images/pipeline.d.ts.map +1 -0
- package/dist/images/pipeline.js +105 -0
- package/dist/images/pipeline.js.map +1 -0
- package/dist/images/sharp.d.ts +57 -0
- package/dist/images/sharp.d.ts.map +1 -0
- package/dist/images/sharp.js +139 -0
- package/dist/images/sharp.js.map +1 -0
- package/dist/images/srcset.d.ts +33 -0
- package/dist/images/srcset.d.ts.map +1 -0
- package/dist/images/srcset.js +94 -0
- package/dist/images/srcset.js.map +1 -0
- package/dist/images/store.d.ts +32 -0
- package/dist/images/store.d.ts.map +1 -0
- package/dist/images/store.js +54 -0
- package/dist/images/store.js.map +1 -0
- package/dist/images/types.d.ts +128 -0
- package/dist/images/types.d.ts.map +1 -0
- package/dist/images/types.js +22 -0
- package/dist/images/types.js.map +1 -0
- package/dist/images/wasm.d.ts +43 -0
- package/dist/images/wasm.d.ts.map +1 -0
- package/dist/images/wasm.js +128 -0
- package/dist/images/wasm.js.map +1 -0
- package/dist/index.d.ts +29 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +29 -0
- package/dist/index.js.map +1 -0
- package/dist/pwa/build.d.ts +39 -0
- package/dist/pwa/build.d.ts.map +1 -0
- package/dist/pwa/build.js +38 -0
- package/dist/pwa/build.js.map +1 -0
- package/dist/pwa/client.d.ts +90 -0
- package/dist/pwa/client.d.ts.map +1 -0
- package/dist/pwa/client.js +76 -0
- package/dist/pwa/client.js.map +1 -0
- package/dist/pwa/index.d.ts +29 -0
- package/dist/pwa/index.d.ts.map +1 -0
- package/dist/pwa/index.js +22 -0
- package/dist/pwa/index.js.map +1 -0
- package/dist/pwa/manifest.d.ts +69 -0
- package/dist/pwa/manifest.d.ts.map +1 -0
- package/dist/pwa/manifest.js +108 -0
- package/dist/pwa/manifest.js.map +1 -0
- package/dist/pwa/offline.d.ts +44 -0
- package/dist/pwa/offline.d.ts.map +1 -0
- package/dist/pwa/offline.js +94 -0
- package/dist/pwa/offline.js.map +1 -0
- package/dist/pwa/service-worker.d.ts +71 -0
- package/dist/pwa/service-worker.d.ts.map +1 -0
- package/dist/pwa/service-worker.js +119 -0
- package/dist/pwa/service-worker.js.map +1 -0
- package/dist/pwa/strategy.d.ts +36 -0
- package/dist/pwa/strategy.d.ts.map +1 -0
- package/dist/pwa/strategy.js +180 -0
- package/dist/pwa/strategy.js.map +1 -0
- package/dist/pwa/sw-runtime.d.ts +109 -0
- package/dist/pwa/sw-runtime.d.ts.map +1 -0
- package/dist/pwa/sw-runtime.js +214 -0
- package/dist/pwa/sw-runtime.js.map +1 -0
- package/dist/pwa/types.d.ts +107 -0
- package/dist/pwa/types.d.ts.map +1 -0
- package/dist/pwa/types.js +18 -0
- package/dist/pwa/types.js.map +1 -0
- package/dist/pwa/version.d.ts +45 -0
- package/dist/pwa/version.d.ts.map +1 -0
- package/dist/pwa/version.js +89 -0
- package/dist/pwa/version.js.map +1 -0
- package/dist/skin/color.d.ts +50 -0
- package/dist/skin/color.d.ts.map +1 -0
- package/dist/skin/color.js +176 -0
- package/dist/skin/color.js.map +1 -0
- package/dist/skin/css.d.ts +19 -0
- package/dist/skin/css.d.ts.map +1 -0
- package/dist/skin/css.js +69 -0
- package/dist/skin/css.js.map +1 -0
- package/dist/skin/errors.d.ts +22 -0
- package/dist/skin/errors.d.ts.map +1 -0
- package/dist/skin/errors.js +59 -0
- package/dist/skin/errors.js.map +1 -0
- package/dist/skin/index.d.ts +15 -0
- package/dist/skin/index.d.ts.map +1 -0
- package/dist/skin/index.js +11 -0
- package/dist/skin/index.js.map +1 -0
- package/dist/skin/sheet.d.ts +42 -0
- package/dist/skin/sheet.d.ts.map +1 -0
- package/dist/skin/sheet.js +36 -0
- package/dist/skin/sheet.js.map +1 -0
- package/dist/skin/tokens.d.ts +90 -0
- package/dist/skin/tokens.d.ts.map +1 -0
- package/dist/skin/tokens.js +56 -0
- package/dist/skin/tokens.js.map +1 -0
- package/dist/skin/validate.d.ts +14 -0
- package/dist/skin/validate.d.ts.map +1 -0
- package/dist/skin/validate.js +272 -0
- package/dist/skin/validate.js.map +1 -0
- package/dist/theme/load-theme.d.ts +37 -0
- package/dist/theme/load-theme.d.ts.map +1 -0
- package/dist/theme/load-theme.js +102 -0
- package/dist/theme/load-theme.js.map +1 -0
- package/dist/theme/manifest.d.ts +48 -0
- package/dist/theme/manifest.d.ts.map +1 -0
- package/dist/theme/manifest.js +36 -0
- package/dist/theme/manifest.js.map +1 -0
- package/dist/theme/verify/forbidden.d.ts +39 -0
- package/dist/theme/verify/forbidden.d.ts.map +1 -0
- package/dist/theme/verify/forbidden.js +107 -0
- package/dist/theme/verify/forbidden.js.map +1 -0
- package/dist/theme/verify/scan-file.d.ts +15 -0
- package/dist/theme/verify/scan-file.d.ts.map +1 -0
- package/dist/theme/verify/scan-file.js +151 -0
- package/dist/theme/verify/scan-file.js.map +1 -0
- package/dist/theme/verify/scanner.d.ts +52 -0
- package/dist/theme/verify/scanner.d.ts.map +1 -0
- package/dist/theme/verify/scanner.js +304 -0
- package/dist/theme/verify/scanner.js.map +1 -0
- package/dist/theme/verify/verify-theme.d.ts +44 -0
- package/dist/theme/verify/verify-theme.d.ts.map +1 -0
- package/dist/theme/verify/verify-theme.js +179 -0
- package/dist/theme/verify/verify-theme.js.map +1 -0
- package/package.json +56 -0
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
import type { AstroIntegration } from 'astro';
|
|
2
|
+
import type { RenderConfig } from '../config.js';
|
|
3
|
+
import { type LoadedTheme, type LoadThemeOptions } from '../theme/load-theme.js';
|
|
4
|
+
/**
|
|
5
|
+
* The Astro integration that puts the active theme in front of Astro.
|
|
6
|
+
*
|
|
7
|
+
* Astro is the theme engine by ADR-0008, so this is where the configuration's
|
|
8
|
+
* `theme.name` becomes something Vite can resolve. Two things are exposed and
|
|
9
|
+
* no more:
|
|
10
|
+
*
|
|
11
|
+
* - the alias `@theme`, pointing at the theme's `src/`, so that a site's pages
|
|
12
|
+
* import `@theme/layouts/Base.astro` and a theme swap is a configuration
|
|
13
|
+
* change rather than a rewrite of every import;
|
|
14
|
+
* - the virtual module `virtual:cogenta/theme`, holding the manifest and the
|
|
15
|
+
* site block of the configuration.
|
|
16
|
+
*
|
|
17
|
+
* What is *not* exposed matters as much: the content token, the database URL
|
|
18
|
+
* and the rest of the Cogenta configuration never enter Vite's module graph,
|
|
19
|
+
* because everything in it is reachable from theme code.
|
|
20
|
+
*/
|
|
21
|
+
export declare const THEME_ALIAS = "@theme";
|
|
22
|
+
export declare const THEME_VIRTUAL_MODULE = "virtual:cogenta/theme";
|
|
23
|
+
export interface CogentaIntegrationOptions {
|
|
24
|
+
readonly config: RenderConfig;
|
|
25
|
+
/** Directory the theme is resolved from. Astro's project root by default. */
|
|
26
|
+
readonly cwd?: string | undefined;
|
|
27
|
+
/**
|
|
28
|
+
* Run the installation check before the build starts.
|
|
29
|
+
*
|
|
30
|
+
* Off by default because `cogenta theme install` already refused a theme
|
|
31
|
+
* that fails it; on for a site that installs themes out of band and wants
|
|
32
|
+
* the guarantee at build time too.
|
|
33
|
+
*/
|
|
34
|
+
readonly verify?: boolean | undefined;
|
|
35
|
+
readonly importManifest?: LoadThemeOptions['importManifest'];
|
|
36
|
+
}
|
|
37
|
+
/** What the theme exposes to the site, serialised into the virtual module. */
|
|
38
|
+
export interface ThemeModule {
|
|
39
|
+
readonly manifest: LoadedTheme['manifest'];
|
|
40
|
+
readonly site: RenderConfig['site'];
|
|
41
|
+
}
|
|
42
|
+
export declare function cogentaTheme(options: CogentaIntegrationOptions): AstroIntegration;
|
|
43
|
+
interface MinimalVitePlugin {
|
|
44
|
+
readonly name: string;
|
|
45
|
+
resolveId(id: string): string | undefined;
|
|
46
|
+
load(id: string): string | undefined;
|
|
47
|
+
}
|
|
48
|
+
/**
|
|
49
|
+
* Serialises the theme into a module the site can import.
|
|
50
|
+
*
|
|
51
|
+
* `JSON.stringify` rather than a builder: the manifest came from a third-party
|
|
52
|
+
* theme, and generating code from untrusted values is how a manifest becomes
|
|
53
|
+
* an injection.
|
|
54
|
+
*/
|
|
55
|
+
export declare function themeVirtualModule(module: ThemeModule): MinimalVitePlugin;
|
|
56
|
+
export {};
|
|
57
|
+
//# sourceMappingURL=integration.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"integration.d.ts","sourceRoot":"","sources":["../../src/astro/integration.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,OAAO,CAAA;AAC7C,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,cAAc,CAAA;AAChD,OAAO,EAAE,KAAK,WAAW,EAAE,KAAK,gBAAgB,EAAa,MAAM,wBAAwB,CAAA;AAE3F;;;;;;;;;;;;;;;;GAgBG;AAEH,eAAO,MAAM,WAAW,WAAW,CAAA;AACnC,eAAO,MAAM,oBAAoB,0BAA0B,CAAA;AAI3D,MAAM,WAAW,yBAAyB;IACxC,QAAQ,CAAC,MAAM,EAAE,YAAY,CAAA;IAC7B,6EAA6E;IAC7E,QAAQ,CAAC,GAAG,CAAC,EAAE,MAAM,GAAG,SAAS,CAAA;IACjC;;;;;;OAMG;IACH,QAAQ,CAAC,MAAM,CAAC,EAAE,OAAO,GAAG,SAAS,CAAA;IACrC,QAAQ,CAAC,cAAc,CAAC,EAAE,gBAAgB,CAAC,gBAAgB,CAAC,CAAA;CAC7D;AAED,8EAA8E;AAC9E,MAAM,WAAW,WAAW;IAC1B,QAAQ,CAAC,QAAQ,EAAE,WAAW,CAAC,UAAU,CAAC,CAAA;IAC1C,QAAQ,CAAC,IAAI,EAAE,YAAY,CAAC,MAAM,CAAC,CAAA;CACpC;AAED,wBAAgB,YAAY,CAAC,OAAO,EAAE,yBAAyB,GAAG,gBAAgB,CA2BjF;AAWD,UAAU,iBAAiB;IACzB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;IACrB,SAAS,CAAC,EAAE,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAAA;IACzC,IAAI,CAAC,EAAE,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAAA;CACrC;AAED;;;;;;GAMG;AACH,wBAAgB,kBAAkB,CAAC,MAAM,EAAE,WAAW,GAAG,iBAAiB,CAUzE"}
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
import { loadTheme } from '../theme/load-theme.js';
|
|
2
|
+
/**
|
|
3
|
+
* The Astro integration that puts the active theme in front of Astro.
|
|
4
|
+
*
|
|
5
|
+
* Astro is the theme engine by ADR-0008, so this is where the configuration's
|
|
6
|
+
* `theme.name` becomes something Vite can resolve. Two things are exposed and
|
|
7
|
+
* no more:
|
|
8
|
+
*
|
|
9
|
+
* - the alias `@theme`, pointing at the theme's `src/`, so that a site's pages
|
|
10
|
+
* import `@theme/layouts/Base.astro` and a theme swap is a configuration
|
|
11
|
+
* change rather than a rewrite of every import;
|
|
12
|
+
* - the virtual module `virtual:cogenta/theme`, holding the manifest and the
|
|
13
|
+
* site block of the configuration.
|
|
14
|
+
*
|
|
15
|
+
* What is *not* exposed matters as much: the content token, the database URL
|
|
16
|
+
* and the rest of the Cogenta configuration never enter Vite's module graph,
|
|
17
|
+
* because everything in it is reachable from theme code.
|
|
18
|
+
*/
|
|
19
|
+
export const THEME_ALIAS = '@theme';
|
|
20
|
+
export const THEME_VIRTUAL_MODULE = 'virtual:cogenta/theme';
|
|
21
|
+
const RESOLVED_VIRTUAL_MODULE = `\0${THEME_VIRTUAL_MODULE}`;
|
|
22
|
+
export function cogentaTheme(options) {
|
|
23
|
+
return {
|
|
24
|
+
name: '@cogenta/render',
|
|
25
|
+
hooks: {
|
|
26
|
+
'astro:config:setup': async ({ config, updateConfig, logger }) => {
|
|
27
|
+
const theme = await loadTheme({
|
|
28
|
+
theme: options.config.theme,
|
|
29
|
+
cwd: options.cwd ?? fileSystemPath(config.root),
|
|
30
|
+
importManifest: options.importManifest,
|
|
31
|
+
verify: options.verify ?? false,
|
|
32
|
+
});
|
|
33
|
+
logger.info(`theme ${theme.manifest.name}@${theme.manifest.version} (runtime: ${theme.manifest.runtime})`);
|
|
34
|
+
updateConfig({
|
|
35
|
+
vite: {
|
|
36
|
+
plugins: [themeVirtualModule({ manifest: theme.manifest, site: options.config.site })],
|
|
37
|
+
resolve: {
|
|
38
|
+
alias: { [THEME_ALIAS]: `${theme.root}/src` },
|
|
39
|
+
},
|
|
40
|
+
},
|
|
41
|
+
});
|
|
42
|
+
},
|
|
43
|
+
},
|
|
44
|
+
};
|
|
45
|
+
}
|
|
46
|
+
/** Astro hands roots as `URL`s; Vite wants paths. */
|
|
47
|
+
function fileSystemPath(root) {
|
|
48
|
+
const href = typeof root === 'string' ? root : root.href;
|
|
49
|
+
if (!href.startsWith('file:'))
|
|
50
|
+
return href;
|
|
51
|
+
const path = decodeURIComponent(new URL(href).pathname);
|
|
52
|
+
// A Windows path arrives as `/C:/…`; the leading slash is not part of it.
|
|
53
|
+
return /^\/[A-Za-z]:/u.test(path) ? path.slice(1) : path;
|
|
54
|
+
}
|
|
55
|
+
/**
|
|
56
|
+
* Serialises the theme into a module the site can import.
|
|
57
|
+
*
|
|
58
|
+
* `JSON.stringify` rather than a builder: the manifest came from a third-party
|
|
59
|
+
* theme, and generating code from untrusted values is how a manifest becomes
|
|
60
|
+
* an injection.
|
|
61
|
+
*/
|
|
62
|
+
export function themeVirtualModule(module) {
|
|
63
|
+
return {
|
|
64
|
+
name: 'cogenta:theme',
|
|
65
|
+
resolveId: (id) => (id === THEME_VIRTUAL_MODULE ? RESOLVED_VIRTUAL_MODULE : undefined),
|
|
66
|
+
load: (id) => id === RESOLVED_VIRTUAL_MODULE
|
|
67
|
+
? `export const manifest = ${JSON.stringify(module.manifest)}\n` +
|
|
68
|
+
`export const site = ${JSON.stringify(module.site)}\n`
|
|
69
|
+
: undefined,
|
|
70
|
+
};
|
|
71
|
+
}
|
|
72
|
+
//# sourceMappingURL=integration.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"integration.js","sourceRoot":"","sources":["../../src/astro/integration.ts"],"names":[],"mappings":"AAEA,OAAO,EAA2C,SAAS,EAAE,MAAM,wBAAwB,CAAA;AAE3F;;;;;;;;;;;;;;;;GAgBG;AAEH,MAAM,CAAC,MAAM,WAAW,GAAG,QAAQ,CAAA;AACnC,MAAM,CAAC,MAAM,oBAAoB,GAAG,uBAAuB,CAAA;AAE3D,MAAM,uBAAuB,GAAG,KAAK,oBAAoB,EAAE,CAAA;AAuB3D,MAAM,UAAU,YAAY,CAAC,OAAkC;IAC7D,OAAO;QACL,IAAI,EAAE,iBAAiB;QACvB,KAAK,EAAE;YACL,oBAAoB,EAAE,KAAK,EAAE,EAAE,MAAM,EAAE,YAAY,EAAE,MAAM,EAAE,EAAE,EAAE;gBAC/D,MAAM,KAAK,GAAG,MAAM,SAAS,CAAC;oBAC5B,KAAK,EAAE,OAAO,CAAC,MAAM,CAAC,KAAK;oBAC3B,GAAG,EAAE,OAAO,CAAC,GAAG,IAAI,cAAc,CAAC,MAAM,CAAC,IAAI,CAAC;oBAC/C,cAAc,EAAE,OAAO,CAAC,cAAc;oBACtC,MAAM,EAAE,OAAO,CAAC,MAAM,IAAI,KAAK;iBAChC,CAAC,CAAA;gBAEF,MAAM,CAAC,IAAI,CACT,SAAS,KAAK,CAAC,QAAQ,CAAC,IAAI,IAAI,KAAK,CAAC,QAAQ,CAAC,OAAO,cAAc,KAAK,CAAC,QAAQ,CAAC,OAAO,GAAG,CAC9F,CAAA;gBAED,YAAY,CAAC;oBACX,IAAI,EAAE;wBACJ,OAAO,EAAE,CAAC,kBAAkB,CAAC,EAAE,QAAQ,EAAE,KAAK,CAAC,QAAQ,EAAE,IAAI,EAAE,OAAO,CAAC,MAAM,CAAC,IAAI,EAAE,CAAC,CAAC;wBACtF,OAAO,EAAE;4BACP,KAAK,EAAE,EAAE,CAAC,WAAW,CAAC,EAAE,GAAG,KAAK,CAAC,IAAI,MAAM,EAAE;yBAC9C;qBACF;iBACF,CAAC,CAAA;YACJ,CAAC;SACF;KACF,CAAA;AACH,CAAC;AAED,qDAAqD;AACrD,SAAS,cAAc,CAAC,IAAkB;IACxC,MAAM,IAAI,GAAG,OAAO,IAAI,KAAK,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAA;IACxD,IAAI,CAAC,IAAI,CAAC,UAAU,CAAC,OAAO,CAAC;QAAE,OAAO,IAAI,CAAA;IAC1C,MAAM,IAAI,GAAG,kBAAkB,CAAC,IAAI,GAAG,CAAC,IAAI,CAAC,CAAC,QAAQ,CAAC,CAAA;IACvD,0EAA0E;IAC1E,OAAO,eAAe,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAA;AAC1D,CAAC;AAQD;;;;;;GAMG;AACH,MAAM,UAAU,kBAAkB,CAAC,MAAmB;IACpD,OAAO;QACL,IAAI,EAAE,eAAe;QACrB,SAAS,EAAE,CAAC,EAAE,EAAE,EAAE,CAAC,CAAC,EAAE,KAAK,oBAAoB,CAAC,CAAC,CAAC,uBAAuB,CAAC,CAAC,CAAC,SAAS,CAAC;QACtF,IAAI,EAAE,CAAC,EAAE,EAAE,EAAE,CACX,EAAE,KAAK,uBAAuB;YAC5B,CAAC,CAAC,2BAA2B,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,QAAQ,CAAC,IAAI;gBAC9D,uBAAuB,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,IAAI,CAAC,IAAI;YACxD,CAAC,CAAC,SAAS;KAChB,CAAA;AACH,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/build/index.ts"],"names":[],"mappings":"AAAA,cAAc,kBAAkB,CAAA;AAChC,cAAc,WAAW,CAAA;AACzB,cAAc,cAAc,CAAA;AAC5B,cAAc,mBAAmB,CAAA;AACjC,cAAc,gBAAgB,CAAA;AAC9B,cAAc,cAAc,CAAA"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/build/index.ts"],"names":[],"mappings":"AAAA,cAAc,kBAAkB,CAAA;AAChC,cAAc,WAAW,CAAA;AACzB,cAAc,cAAc,CAAA;AAC5B,cAAc,mBAAmB,CAAA;AACjC,cAAc,gBAAgB,CAAA;AAC9B,cAAc,cAAc,CAAA"}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import type { AstroIntegration } from 'astro';
|
|
2
|
+
import type { RuntimeRequirement } from './requirements.js';
|
|
3
|
+
import { type BuildTarget, type TargetCapability } from './targets.js';
|
|
4
|
+
/**
|
|
5
|
+
* The target, as an Astro integration.
|
|
6
|
+
*
|
|
7
|
+
* One theme codebase, three adapters (ADR-0008). This integration is the only
|
|
8
|
+
* place that knows which of the three is being built: it sets Astro's `output`
|
|
9
|
+
* and refuses the build if any declared runtime need cannot be honoured. The
|
|
10
|
+
* adapter itself stays in the site's `astro.config`, because an adapter is a
|
|
11
|
+
* dependency of the *deployment*, not of Cogenta — bundling one would force
|
|
12
|
+
* every static site to install a Node server it will never run.
|
|
13
|
+
*/
|
|
14
|
+
export interface BuildTargetOptions {
|
|
15
|
+
readonly target: BuildTarget | TargetCapability;
|
|
16
|
+
/**
|
|
17
|
+
* The runtime needs of this build, or a function producing them.
|
|
18
|
+
*
|
|
19
|
+
* A function, because the route list generally comes from the content API
|
|
20
|
+
* and the caller should not have to await it before declaring integrations.
|
|
21
|
+
*/
|
|
22
|
+
readonly requirements?: readonly RuntimeRequirement[] | (() => readonly RuntimeRequirement[] | Promise<readonly RuntimeRequirement[]>) | undefined;
|
|
23
|
+
}
|
|
24
|
+
export declare function cogentaBuildTarget(options: BuildTargetOptions): AstroIntegration;
|
|
25
|
+
//# sourceMappingURL=integration.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"integration.d.ts","sourceRoot":"","sources":["../../src/build/integration.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,OAAO,CAAA;AAE7C,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,mBAAmB,CAAA;AAC3D,OAAO,EAAE,KAAK,WAAW,EAAiB,KAAK,gBAAgB,EAAE,MAAM,cAAc,CAAA;AAErF;;;;;;;;;GASG;AAEH,MAAM,WAAW,kBAAkB;IACjC,QAAQ,CAAC,MAAM,EAAE,WAAW,GAAG,gBAAgB,CAAA;IAC/C;;;;;OAKG;IACH,QAAQ,CAAC,YAAY,CAAC,EAClB,SAAS,kBAAkB,EAAE,GAC7B,CAAC,MAAM,SAAS,kBAAkB,EAAE,GAAG,OAAO,CAAC,SAAS,kBAAkB,EAAE,CAAC,CAAC,GAC9E,SAAS,CAAA;CACd;AAED,wBAAgB,kBAAkB,CAAC,OAAO,EAAE,kBAAkB,GAAG,gBAAgB,CAyChF"}
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import { CogentaError } from '@cogenta/core';
|
|
2
|
+
import { assertRuntimeSatisfied } from './refusal.js';
|
|
3
|
+
import { resolveTarget } from './targets.js';
|
|
4
|
+
export function cogentaBuildTarget(options) {
|
|
5
|
+
const target = typeof options.target === 'string' ? resolveTarget(options.target) : options.target;
|
|
6
|
+
return {
|
|
7
|
+
name: '@cogenta/render:build-target',
|
|
8
|
+
hooks: {
|
|
9
|
+
'astro:config:setup': async ({ updateConfig, logger }) => {
|
|
10
|
+
const declared = options.requirements;
|
|
11
|
+
const requirements = typeof declared === 'function' ? await declared() : (declared ?? []);
|
|
12
|
+
// Before anything else Astro might do, and before a single page is
|
|
13
|
+
// rendered. A refusal after nine hundred pages is a refusal that cost
|
|
14
|
+
// an hour to arrive at.
|
|
15
|
+
assertRuntimeSatisfied(target, requirements);
|
|
16
|
+
logger.info(`target ${target.target} — astro output: ${target.astroOutput}`);
|
|
17
|
+
updateConfig({ output: target.astroOutput });
|
|
18
|
+
},
|
|
19
|
+
'astro:config:done': ({ config }) => {
|
|
20
|
+
if (target.adapter === null || config.adapter !== undefined)
|
|
21
|
+
return;
|
|
22
|
+
// Astro would fail on its own here, in its own words. Ours name the
|
|
23
|
+
// package to install, which is the difference between a fix and a
|
|
24
|
+
// search.
|
|
25
|
+
throw new CogentaError({
|
|
26
|
+
code: 'BUILD_TARGET_UNKNOWN',
|
|
27
|
+
message: `The ${target.label} target needs an Astro adapter, and astro.config declares none.`,
|
|
28
|
+
hint: `Install ${target.adapter.recommended}${target.adapter.alternatives.length === 0
|
|
29
|
+
? ''
|
|
30
|
+
: ` (or ${target.adapter.alternatives.join(', ')})`} and set it as \`adapter\` in astro.config. A static build needs no adapter — use --target static if that is what you meant.`,
|
|
31
|
+
details: {
|
|
32
|
+
target: target.target,
|
|
33
|
+
recommended: target.adapter.recommended,
|
|
34
|
+
alternatives: target.adapter.alternatives,
|
|
35
|
+
},
|
|
36
|
+
});
|
|
37
|
+
},
|
|
38
|
+
},
|
|
39
|
+
};
|
|
40
|
+
}
|
|
41
|
+
//# sourceMappingURL=integration.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"integration.js","sourceRoot":"","sources":["../../src/build/integration.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,eAAe,CAAA;AAE5C,OAAO,EAAE,sBAAsB,EAAE,MAAM,cAAc,CAAA;AAErD,OAAO,EAAoB,aAAa,EAAyB,MAAM,cAAc,CAAA;AA2BrF,MAAM,UAAU,kBAAkB,CAAC,OAA2B;IAC5D,MAAM,MAAM,GAAG,OAAO,OAAO,CAAC,MAAM,KAAK,QAAQ,CAAC,CAAC,CAAC,aAAa,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,MAAM,CAAA;IAElG,OAAO;QACL,IAAI,EAAE,8BAA8B;QACpC,KAAK,EAAE;YACL,oBAAoB,EAAE,KAAK,EAAE,EAAE,YAAY,EAAE,MAAM,EAAE,EAAE,EAAE;gBACvD,MAAM,QAAQ,GAAG,OAAO,CAAC,YAAY,CAAA;gBACrC,MAAM,YAAY,GAAG,OAAO,QAAQ,KAAK,UAAU,CAAC,CAAC,CAAC,MAAM,QAAQ,EAAE,CAAC,CAAC,CAAC,CAAC,QAAQ,IAAI,EAAE,CAAC,CAAA;gBAEzF,mEAAmE;gBACnE,sEAAsE;gBACtE,wBAAwB;gBACxB,sBAAsB,CAAC,MAAM,EAAE,YAAY,CAAC,CAAA;gBAE5C,MAAM,CAAC,IAAI,CAAC,UAAU,MAAM,CAAC,MAAM,oBAAoB,MAAM,CAAC,WAAW,EAAE,CAAC,CAAA;gBAC5E,YAAY,CAAC,EAAE,MAAM,EAAE,MAAM,CAAC,WAAW,EAAE,CAAC,CAAA;YAC9C,CAAC;YAED,mBAAmB,EAAE,CAAC,EAAE,MAAM,EAAE,EAAE,EAAE;gBAClC,IAAI,MAAM,CAAC,OAAO,KAAK,IAAI,IAAI,MAAM,CAAC,OAAO,KAAK,SAAS;oBAAE,OAAM;gBACnE,oEAAoE;gBACpE,kEAAkE;gBAClE,UAAU;gBACV,MAAM,IAAI,YAAY,CAAC;oBACrB,IAAI,EAAE,sBAAsB;oBAC5B,OAAO,EAAE,OAAO,MAAM,CAAC,KAAK,iEAAiE;oBAC7F,IAAI,EAAE,WAAW,MAAM,CAAC,OAAO,CAAC,WAAW,GACzC,MAAM,CAAC,OAAO,CAAC,YAAY,CAAC,MAAM,KAAK,CAAC;wBACtC,CAAC,CAAC,EAAE;wBACJ,CAAC,CAAC,QAAQ,MAAM,CAAC,OAAO,CAAC,YAAY,CAAC,IAAI,CAAC,IAAI,CAAC,GACpD,8HAA8H;oBAC9H,OAAO,EAAE;wBACP,MAAM,EAAE,MAAM,CAAC,MAAM;wBACrB,WAAW,EAAE,MAAM,CAAC,OAAO,CAAC,WAAW;wBACvC,YAAY,EAAE,MAAM,CAAC,OAAO,CAAC,YAAY;qBAC1C;iBACF,CAAC,CAAA;YACJ,CAAC;SACF;KACF,CAAA;AACH,CAAC"}
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import type { BlockRegistry } from '@cogenta/blocks';
|
|
2
|
+
import type { ThemeManifest } from '../theme/manifest.js';
|
|
3
|
+
import { type BuildRoute, type PluginRuntimeDeclaration, type RuntimeRequirement } from './requirements.js';
|
|
4
|
+
import { type BuildTarget, type TargetCapability } from './targets.js';
|
|
5
|
+
/**
|
|
6
|
+
* Deciding, before anything is rendered, how each route is produced.
|
|
7
|
+
*
|
|
8
|
+
* Two modes and no third: a route is either rendered ahead of time, or on
|
|
9
|
+
* request. Incremental rendering is explicitly out of this lot — the tag-based
|
|
10
|
+
* render cache has to be proven first — and leaving it out of the vocabulary
|
|
11
|
+
* here is what keeps it out of the build.
|
|
12
|
+
*/
|
|
13
|
+
export type RouteMode = 'prerendered' | 'on-demand';
|
|
14
|
+
export interface PlannedRoute {
|
|
15
|
+
readonly path: string;
|
|
16
|
+
readonly mode: RouteMode;
|
|
17
|
+
/** Names of the elements that forced `on-demand`. Empty for a prerendered route. */
|
|
18
|
+
readonly needs: readonly string[];
|
|
19
|
+
}
|
|
20
|
+
export interface BuildPlan {
|
|
21
|
+
readonly target: TargetCapability;
|
|
22
|
+
readonly routes: readonly PlannedRoute[];
|
|
23
|
+
/** Every declared need in this build, static ones included. */
|
|
24
|
+
readonly requirements: readonly RuntimeRequirement[];
|
|
25
|
+
}
|
|
26
|
+
export interface PlanBuildInput {
|
|
27
|
+
readonly target: BuildTarget | TargetCapability;
|
|
28
|
+
readonly routes: readonly BuildRoute[];
|
|
29
|
+
readonly blocks: BlockRegistry;
|
|
30
|
+
readonly theme?: Pick<ThemeManifest, 'name' | 'runtime'> | undefined;
|
|
31
|
+
readonly plugins?: readonly PluginRuntimeDeclaration[] | undefined;
|
|
32
|
+
}
|
|
33
|
+
/**
|
|
34
|
+
* Plans a build, or refuses it.
|
|
35
|
+
*
|
|
36
|
+
* The refusal happens here rather than at render time on purpose: the operator
|
|
37
|
+
* learns that the build cannot work before a single page is produced, instead
|
|
38
|
+
* of after nine hundred of them.
|
|
39
|
+
*/
|
|
40
|
+
export declare function planBuild(input: PlanBuildInput): BuildPlan;
|
|
41
|
+
//# sourceMappingURL=plan.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"plan.d.ts","sourceRoot":"","sources":["../../src/build/plan.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAA;AACpD,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAA;AAEzD,OAAO,EACL,KAAK,UAAU,EAEf,KAAK,wBAAwB,EAC7B,KAAK,kBAAkB,EACxB,MAAM,mBAAmB,CAAA;AAC1B,OAAO,EAAE,KAAK,WAAW,EAAiB,KAAK,gBAAgB,EAAE,MAAM,cAAc,CAAA;AAErF;;;;;;;GAOG;AAEH,MAAM,MAAM,SAAS,GAAG,aAAa,GAAG,WAAW,CAAA;AAEnD,MAAM,WAAW,YAAY;IAC3B,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;IACrB,QAAQ,CAAC,IAAI,EAAE,SAAS,CAAA;IACxB,oFAAoF;IACpF,QAAQ,CAAC,KAAK,EAAE,SAAS,MAAM,EAAE,CAAA;CAClC;AAED,MAAM,WAAW,SAAS;IACxB,QAAQ,CAAC,MAAM,EAAE,gBAAgB,CAAA;IACjC,QAAQ,CAAC,MAAM,EAAE,SAAS,YAAY,EAAE,CAAA;IACxC,+DAA+D;IAC/D,QAAQ,CAAC,YAAY,EAAE,SAAS,kBAAkB,EAAE,CAAA;CACrD;AAED,MAAM,WAAW,cAAc;IAC7B,QAAQ,CAAC,MAAM,EAAE,WAAW,GAAG,gBAAgB,CAAA;IAC/C,QAAQ,CAAC,MAAM,EAAE,SAAS,UAAU,EAAE,CAAA;IACtC,QAAQ,CAAC,MAAM,EAAE,aAAa,CAAA;IAC9B,QAAQ,CAAC,KAAK,CAAC,EAAE,IAAI,CAAC,aAAa,EAAE,MAAM,GAAG,SAAS,CAAC,GAAG,SAAS,CAAA;IACpE,QAAQ,CAAC,OAAO,CAAC,EAAE,SAAS,wBAAwB,EAAE,GAAG,SAAS,CAAA;CACnE;AAED;;;;;;GAMG;AACH,wBAAgB,SAAS,CAAC,KAAK,EAAE,cAAc,GAAG,SAAS,CAuC1D"}
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
import { assertRuntimeSatisfied } from './refusal.js';
|
|
2
|
+
import { collectRuntimeRequirements, } from './requirements.js';
|
|
3
|
+
import { resolveTarget } from './targets.js';
|
|
4
|
+
/**
|
|
5
|
+
* Plans a build, or refuses it.
|
|
6
|
+
*
|
|
7
|
+
* The refusal happens here rather than at render time on purpose: the operator
|
|
8
|
+
* learns that the build cannot work before a single page is produced, instead
|
|
9
|
+
* of after nine hundred of them.
|
|
10
|
+
*/
|
|
11
|
+
export function planBuild(input) {
|
|
12
|
+
const target = typeof input.target === 'string' ? resolveTarget(input.target) : input.target;
|
|
13
|
+
const requirements = collectRuntimeRequirements({
|
|
14
|
+
routes: input.routes,
|
|
15
|
+
blocks: input.blocks,
|
|
16
|
+
theme: input.theme,
|
|
17
|
+
plugins: input.plugins,
|
|
18
|
+
});
|
|
19
|
+
assertRuntimeSatisfied(target, requirements);
|
|
20
|
+
// Site-wide needs — the theme, a plugin — put every route on demand: there
|
|
21
|
+
// is no page they do not touch.
|
|
22
|
+
const siteWideNeeds = requirements
|
|
23
|
+
.filter((requirement) => requirement.origin !== 'block' && requirement.runtime !== 'static')
|
|
24
|
+
.map((requirement) => `${requirement.origin} ${requirement.name}`);
|
|
25
|
+
const blockNeedsByRoute = new Map();
|
|
26
|
+
for (const requirement of requirements) {
|
|
27
|
+
if (requirement.origin !== 'block' || requirement.runtime === 'static')
|
|
28
|
+
continue;
|
|
29
|
+
for (const placement of requirement.placements) {
|
|
30
|
+
const existing = blockNeedsByRoute.get(placement.route);
|
|
31
|
+
const need = `block ${requirement.name}`;
|
|
32
|
+
if (existing === undefined)
|
|
33
|
+
blockNeedsByRoute.set(placement.route, [need]);
|
|
34
|
+
else if (!existing.includes(need))
|
|
35
|
+
existing.push(need);
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
const routes = input.routes.map((route) => {
|
|
39
|
+
const needs = [...siteWideNeeds, ...(blockNeedsByRoute.get(route.path) ?? [])];
|
|
40
|
+
// On a static target this list is always empty — the refusal above
|
|
41
|
+
// guarantees it — so the branch reads the same for the three targets.
|
|
42
|
+
return needs.length === 0
|
|
43
|
+
? { path: route.path, mode: 'prerendered', needs: [] }
|
|
44
|
+
: { path: route.path, mode: 'on-demand', needs };
|
|
45
|
+
});
|
|
46
|
+
return { target, routes, requirements };
|
|
47
|
+
}
|
|
48
|
+
//# sourceMappingURL=plan.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"plan.js","sourceRoot":"","sources":["../../src/build/plan.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,sBAAsB,EAAE,MAAM,cAAc,CAAA;AACrD,OAAO,EAEL,0BAA0B,GAG3B,MAAM,mBAAmB,CAAA;AAC1B,OAAO,EAAoB,aAAa,EAAyB,MAAM,cAAc,CAAA;AAmCrF;;;;;;GAMG;AACH,MAAM,UAAU,SAAS,CAAC,KAAqB;IAC7C,MAAM,MAAM,GAAG,OAAO,KAAK,CAAC,MAAM,KAAK,QAAQ,CAAC,CAAC,CAAC,aAAa,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,MAAM,CAAA;IAE5F,MAAM,YAAY,GAAG,0BAA0B,CAAC;QAC9C,MAAM,EAAE,KAAK,CAAC,MAAM;QACpB,MAAM,EAAE,KAAK,CAAC,MAAM;QACpB,KAAK,EAAE,KAAK,CAAC,KAAK;QAClB,OAAO,EAAE,KAAK,CAAC,OAAO;KACvB,CAAC,CAAA;IAEF,sBAAsB,CAAC,MAAM,EAAE,YAAY,CAAC,CAAA;IAE5C,2EAA2E;IAC3E,gCAAgC;IAChC,MAAM,aAAa,GAAG,YAAY;SAC/B,MAAM,CAAC,CAAC,WAAW,EAAE,EAAE,CAAC,WAAW,CAAC,MAAM,KAAK,OAAO,IAAI,WAAW,CAAC,OAAO,KAAK,QAAQ,CAAC;SAC3F,GAAG,CAAC,CAAC,WAAW,EAAE,EAAE,CAAC,GAAG,WAAW,CAAC,MAAM,IAAI,WAAW,CAAC,IAAI,EAAE,CAAC,CAAA;IAEpE,MAAM,iBAAiB,GAAG,IAAI,GAAG,EAAoB,CAAA;IACrD,KAAK,MAAM,WAAW,IAAI,YAAY,EAAE,CAAC;QACvC,IAAI,WAAW,CAAC,MAAM,KAAK,OAAO,IAAI,WAAW,CAAC,OAAO,KAAK,QAAQ;YAAE,SAAQ;QAChF,KAAK,MAAM,SAAS,IAAI,WAAW,CAAC,UAAU,EAAE,CAAC;YAC/C,MAAM,QAAQ,GAAG,iBAAiB,CAAC,GAAG,CAAC,SAAS,CAAC,KAAK,CAAC,CAAA;YACvD,MAAM,IAAI,GAAG,SAAS,WAAW,CAAC,IAAI,EAAE,CAAA;YACxC,IAAI,QAAQ,KAAK,SAAS;gBAAE,iBAAiB,CAAC,GAAG,CAAC,SAAS,CAAC,KAAK,EAAE,CAAC,IAAI,CAAC,CAAC,CAAA;iBACrE,IAAI,CAAC,QAAQ,CAAC,QAAQ,CAAC,IAAI,CAAC;gBAAE,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,CAAA;QACxD,CAAC;IACH,CAAC;IAED,MAAM,MAAM,GAAG,KAAK,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,KAAK,EAAgB,EAAE;QACtD,MAAM,KAAK,GAAG,CAAC,GAAG,aAAa,EAAE,GAAG,CAAC,iBAAiB,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC,CAAC,CAAA;QAC9E,mEAAmE;QACnE,sEAAsE;QACtE,OAAO,KAAK,CAAC,MAAM,KAAK,CAAC;YACvB,CAAC,CAAC,EAAE,IAAI,EAAE,KAAK,CAAC,IAAI,EAAE,IAAI,EAAE,aAAa,EAAE,KAAK,EAAE,EAAE,EAAE;YACtD,CAAC,CAAC,EAAE,IAAI,EAAE,KAAK,CAAC,IAAI,EAAE,IAAI,EAAE,WAAW,EAAE,KAAK,EAAE,CAAA;IACpD,CAAC,CAAC,CAAA;IAEF,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,YAAY,EAAE,CAAA;AACzC,CAAC"}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { type RuntimeRequirement } from './requirements.js';
|
|
2
|
+
import { type TargetCapability } from './targets.js';
|
|
3
|
+
export declare function unsatisfiedRequirements(target: TargetCapability, requirements: readonly RuntimeRequirement[]): readonly RuntimeRequirement[];
|
|
4
|
+
/** Targets that would carry every one of these needs. Feeds option 1. */
|
|
5
|
+
export declare function targetsThatCanCarry(requirements: readonly RuntimeRequirement[], except: TargetCapability): readonly TargetCapability[];
|
|
6
|
+
/**
|
|
7
|
+
* The message a human reads. Kept separate from the error so it can be
|
|
8
|
+
* asserted verbatim in a test: a refusal whose wording drifts is a refusal
|
|
9
|
+
* nobody can act on, and this project treats the wording as the deliverable.
|
|
10
|
+
*/
|
|
11
|
+
export declare function formatRuntimeRefusal(target: TargetCapability, unsatisfied: readonly RuntimeRequirement[]): string;
|
|
12
|
+
/** Throws unless every declared runtime need is one this target can honour. */
|
|
13
|
+
export declare function assertRuntimeSatisfied(target: TargetCapability, requirements: readonly RuntimeRequirement[]): void;
|
|
14
|
+
//# sourceMappingURL=refusal.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"refusal.d.ts","sourceRoot":"","sources":["../../src/build/refusal.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,KAAK,kBAAkB,EAAY,MAAM,mBAAmB,CAAA;AACrE,OAAO,EAAsC,KAAK,gBAAgB,EAAE,MAAM,cAAc,CAAA;AAmBxF,wBAAgB,uBAAuB,CACrC,MAAM,EAAE,gBAAgB,EACxB,YAAY,EAAE,SAAS,kBAAkB,EAAE,GAC1C,SAAS,kBAAkB,EAAE,CAE/B;AAED,yEAAyE;AACzE,wBAAgB,mBAAmB,CACjC,YAAY,EAAE,SAAS,kBAAkB,EAAE,EAC3C,MAAM,EAAE,gBAAgB,GACvB,SAAS,gBAAgB,EAAE,CAM7B;AAyCD;;;;GAIG;AACH,wBAAgB,oBAAoB,CAClC,MAAM,EAAE,gBAAgB,EACxB,WAAW,EAAE,SAAS,kBAAkB,EAAE,GACzC,MAAM,CAkCR;AAED,+EAA+E;AAC/E,wBAAgB,sBAAsB,CACpC,MAAM,EAAE,gBAAgB,EACxB,YAAY,EAAE,SAAS,kBAAkB,EAAE,GAC1C,IAAI,CAoBN"}
|
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
import { CogentaError } from '@cogenta/core';
|
|
2
|
+
import { routesOf } from './requirements.js';
|
|
3
|
+
import { BUILD_TARGETS, TARGET_CAPABILITIES } from './targets.js';
|
|
4
|
+
/**
|
|
5
|
+
* The refusal.
|
|
6
|
+
*
|
|
7
|
+
* This is the most important text in the build. It is read by someone who has
|
|
8
|
+
* just been told their deploy failed, usually late, usually without the
|
|
9
|
+
* architecture document open. So it names three things and nothing else:
|
|
10
|
+
* **what** element is at fault, **why** the target cannot carry it, and the
|
|
11
|
+
* **three** ways out — an edge function, an external service, or removal.
|
|
12
|
+
*
|
|
13
|
+
* What it deliberately does not do is degrade. Rendering the page without the
|
|
14
|
+
* block, or freezing a snapshot of it at build time, would ship a site that is
|
|
15
|
+
* quietly wrong; the operator would find out from a reader.
|
|
16
|
+
*/
|
|
17
|
+
/** Beyond this, placements are counted rather than listed: a wall of paths is not read. */
|
|
18
|
+
const MAX_PLACEMENTS_SHOWN = 5;
|
|
19
|
+
export function unsatisfiedRequirements(target, requirements) {
|
|
20
|
+
return requirements.filter((requirement) => !target.satisfies.includes(requirement.runtime));
|
|
21
|
+
}
|
|
22
|
+
/** Targets that would carry every one of these needs. Feeds option 1. */
|
|
23
|
+
export function targetsThatCanCarry(requirements, except) {
|
|
24
|
+
return BUILD_TARGETS.map((name) => TARGET_CAPABILITIES[name]).filter((candidate) => candidate.target !== except.target &&
|
|
25
|
+
requirements.every((requirement) => candidate.satisfies.includes(requirement.runtime)));
|
|
26
|
+
}
|
|
27
|
+
/** Why a build-time-only target cannot carry this need, in the operator's terms. */
|
|
28
|
+
function reasonFor(requirement) {
|
|
29
|
+
const what = requirement.runtime === 'server'
|
|
30
|
+
? 'a server at request time'
|
|
31
|
+
: 'a function running at request time';
|
|
32
|
+
const noun = requirement.origin === 'block' ? 'This block' : `This ${requirement.origin}`;
|
|
33
|
+
return (`${noun} declares runtime: ${requirement.runtime}, meaning it needs ${what} — ` +
|
|
34
|
+
'it is rendered from data read when the page is asked for. A static build ' +
|
|
35
|
+
'renders every page once and then serves files, so the only thing it could ' +
|
|
36
|
+
'ship is a snapshot, wrong from the first content change after the build.');
|
|
37
|
+
}
|
|
38
|
+
function describePlacements(requirement) {
|
|
39
|
+
if (requirement.placements.length === 0) {
|
|
40
|
+
return 'Applies to the whole site.';
|
|
41
|
+
}
|
|
42
|
+
const shown = requirement.placements
|
|
43
|
+
.slice(0, MAX_PLACEMENTS_SHOWN)
|
|
44
|
+
.map((placement) => `${placement.route} (block ${placement.key})`);
|
|
45
|
+
const hidden = requirement.placements.length - shown.length;
|
|
46
|
+
const routes = routesOf(requirement).length;
|
|
47
|
+
const tail = hidden > 0 ? `, and ${hidden} more` : '';
|
|
48
|
+
return `Placed ${requirement.placements.length} time(s) on ${routes} route(s): ${shown.join(', ')}${tail}.`;
|
|
49
|
+
}
|
|
50
|
+
function removalFor(requirement) {
|
|
51
|
+
switch (requirement.origin) {
|
|
52
|
+
case 'block':
|
|
53
|
+
return `remove the "${requirement.name}" blocks listed above from their pages`;
|
|
54
|
+
case 'theme':
|
|
55
|
+
return `use a theme declaring runtime: static, or ask the author of "${requirement.name}" for one`;
|
|
56
|
+
case 'plugin':
|
|
57
|
+
return `uninstall the plugin "${requirement.name}"`;
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
/**
|
|
61
|
+
* The message a human reads. Kept separate from the error so it can be
|
|
62
|
+
* asserted verbatim in a test: a refusal whose wording drifts is a refusal
|
|
63
|
+
* nobody can act on, and this project treats the wording as the deliverable.
|
|
64
|
+
*/
|
|
65
|
+
export function formatRuntimeRefusal(target, unsatisfied) {
|
|
66
|
+
const capable = targetsThatCanCarry(unsatisfied, target);
|
|
67
|
+
const lines = [];
|
|
68
|
+
lines.push(`Build refused for the ${target.label} target: ${unsatisfied.length} element(s) need a runtime it cannot provide.`);
|
|
69
|
+
lines.push('');
|
|
70
|
+
for (const requirement of unsatisfied) {
|
|
71
|
+
lines.push(` ${requirement.origin} "${requirement.name}" — runtime: ${requirement.runtime}`);
|
|
72
|
+
lines.push(` Why: ${reasonFor(requirement)}`);
|
|
73
|
+
lines.push(` Where: ${describePlacements(requirement)}`);
|
|
74
|
+
lines.push('');
|
|
75
|
+
}
|
|
76
|
+
lines.push('Three ways out, and there is no fourth:');
|
|
77
|
+
lines.push('');
|
|
78
|
+
lines.push(capable.length === 0
|
|
79
|
+
? ' 1. Serve these pages from a request-time target. No configured target carries these needs, which means the need itself has to change.'
|
|
80
|
+
: ` 1. Build for a target that has a request: ${capable
|
|
81
|
+
.map((candidate) => `--target ${candidate.target}`)
|
|
82
|
+
.join(' or ')}. ` +
|
|
83
|
+
'Edge keeps the CDN in front and runs only these pages as functions; Node needs a process you keep alive.');
|
|
84
|
+
lines.push(' 2. Move the work to an external service the browser calls after load — a search endpoint, a comments service, a listing API. The page stays static and the element is replaced by that integration.');
|
|
85
|
+
lines.push(` 3. Remove the element from this site: ${unsatisfied.map(removalFor).join('; ')}. The content itself is untouched either way.`);
|
|
86
|
+
return lines.join('\n');
|
|
87
|
+
}
|
|
88
|
+
/** Throws unless every declared runtime need is one this target can honour. */
|
|
89
|
+
export function assertRuntimeSatisfied(target, requirements) {
|
|
90
|
+
const unsatisfied = unsatisfiedRequirements(target, requirements);
|
|
91
|
+
if (unsatisfied.length === 0)
|
|
92
|
+
return;
|
|
93
|
+
const runtimes = [...new Set(unsatisfied.map((requirement) => requirement.runtime))];
|
|
94
|
+
throw new CogentaError({
|
|
95
|
+
code: 'BUILD_RUNTIME_UNSATISFIED',
|
|
96
|
+
message: formatRuntimeRefusal(target, unsatisfied),
|
|
97
|
+
hint: 'Build for a target with a request (--target edge or --target node), replace the element with an external service, or remove it. The message above names each element and where it sits.',
|
|
98
|
+
details: {
|
|
99
|
+
target: target.target,
|
|
100
|
+
runtimes,
|
|
101
|
+
elements: unsatisfied.map((requirement) => ({
|
|
102
|
+
origin: requirement.origin,
|
|
103
|
+
name: requirement.name,
|
|
104
|
+
runtime: requirement.runtime,
|
|
105
|
+
routes: routesOf(requirement),
|
|
106
|
+
})),
|
|
107
|
+
},
|
|
108
|
+
});
|
|
109
|
+
}
|
|
110
|
+
//# sourceMappingURL=refusal.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"refusal.js","sourceRoot":"","sources":["../../src/build/refusal.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
import type { BlockRegistry, BlockRuntime } from '@cogenta/blocks';
|
|
2
|
+
import type { ThemeManifest } from '../theme/manifest.js';
|
|
3
|
+
/**
|
|
4
|
+
* The runtime-needs manifest of a build (ADR-0004, contract D "Besoins
|
|
5
|
+
* runtime").
|
|
6
|
+
*
|
|
7
|
+
* Three kinds of thing declare a runtime need — a block, the theme, a plugin —
|
|
8
|
+
* and all three are collected here, in one list, before any target is
|
|
9
|
+
* considered. Collecting first and judging afterwards is deliberate: a build
|
|
10
|
+
* that failed on the first offending block would send an operator round the
|
|
11
|
+
* loop once per block, at 23:00, one `git push` at a time.
|
|
12
|
+
*/
|
|
13
|
+
/** Where a block that needs a runtime actually sits, so the message can say so. */
|
|
14
|
+
export interface RuntimePlacement {
|
|
15
|
+
readonly route: string;
|
|
16
|
+
/** The block's `_key` — stable across reorders, so it stays quotable. */
|
|
17
|
+
readonly key: string;
|
|
18
|
+
}
|
|
19
|
+
export type RequirementOrigin = 'block' | 'theme' | 'plugin';
|
|
20
|
+
export interface RuntimeRequirement {
|
|
21
|
+
readonly origin: RequirementOrigin;
|
|
22
|
+
readonly name: string;
|
|
23
|
+
readonly runtime: BlockRuntime;
|
|
24
|
+
/** Empty for a theme or a plugin: those apply to the whole site. */
|
|
25
|
+
readonly placements: readonly RuntimePlacement[];
|
|
26
|
+
}
|
|
27
|
+
/** The minimum a build needs to know about a placed block. */
|
|
28
|
+
export interface BlockReference {
|
|
29
|
+
readonly _key: string;
|
|
30
|
+
readonly _type: string;
|
|
31
|
+
}
|
|
32
|
+
export interface BuildRoute {
|
|
33
|
+
/** The path a visitor requests, `/blog/hello`. */
|
|
34
|
+
readonly path: string;
|
|
35
|
+
readonly blocks: readonly BlockReference[];
|
|
36
|
+
}
|
|
37
|
+
export interface PluginRuntimeDeclaration {
|
|
38
|
+
readonly name: string;
|
|
39
|
+
readonly runtime: BlockRuntime;
|
|
40
|
+
}
|
|
41
|
+
export interface CollectRequirementsInput {
|
|
42
|
+
readonly routes: readonly BuildRoute[];
|
|
43
|
+
/** Resolves a block name to its definition. The vocabulary, plus what the site added. */
|
|
44
|
+
readonly blocks: BlockRegistry;
|
|
45
|
+
readonly theme?: Pick<ThemeManifest, 'name' | 'runtime'> | undefined;
|
|
46
|
+
readonly plugins?: readonly PluginRuntimeDeclaration[] | undefined;
|
|
47
|
+
}
|
|
48
|
+
/**
|
|
49
|
+
* Everything in this build that needs something at request time.
|
|
50
|
+
*
|
|
51
|
+
* `static` needs are included rather than filtered out here: a caller that
|
|
52
|
+
* wants only the problems asks for them against a target, and a caller that
|
|
53
|
+
* wants to display the site's runtime profile gets the whole picture. Filtering
|
|
54
|
+
* belongs to the judgement, not to the collection.
|
|
55
|
+
*/
|
|
56
|
+
export declare function collectRuntimeRequirements(input: CollectRequirementsInput): readonly RuntimeRequirement[];
|
|
57
|
+
/** The routes a given requirement makes impossible to render ahead of a request. */
|
|
58
|
+
export declare function routesOf(requirement: RuntimeRequirement): readonly string[];
|
|
59
|
+
//# sourceMappingURL=requirements.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"requirements.d.ts","sourceRoot":"","sources":["../../src/build/requirements.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAA;AAElE,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAA;AAEzD;;;;;;;;;GASG;AAEH,mFAAmF;AACnF,MAAM,WAAW,gBAAgB;IAC/B,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAA;IACtB,yEAAyE;IACzE,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAA;CACrB;AAED,MAAM,MAAM,iBAAiB,GAAG,OAAO,GAAG,OAAO,GAAG,QAAQ,CAAA;AAE5D,MAAM,WAAW,kBAAkB;IACjC,QAAQ,CAAC,MAAM,EAAE,iBAAiB,CAAA;IAClC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;IACrB,QAAQ,CAAC,OAAO,EAAE,YAAY,CAAA;IAC9B,oEAAoE;IACpE,QAAQ,CAAC,UAAU,EAAE,SAAS,gBAAgB,EAAE,CAAA;CACjD;AAED,8DAA8D;AAC9D,MAAM,WAAW,cAAc;IAC7B,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;IACrB,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAA;CACvB;AAED,MAAM,WAAW,UAAU;IACzB,kDAAkD;IAClD,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;IACrB,QAAQ,CAAC,MAAM,EAAE,SAAS,cAAc,EAAE,CAAA;CAC3C;AAED,MAAM,WAAW,wBAAwB;IACvC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;IACrB,QAAQ,CAAC,OAAO,EAAE,YAAY,CAAA;CAC/B;AAED,MAAM,WAAW,wBAAwB;IACvC,QAAQ,CAAC,MAAM,EAAE,SAAS,UAAU,EAAE,CAAA;IACtC,yFAAyF;IACzF,QAAQ,CAAC,MAAM,EAAE,aAAa,CAAA;IAC9B,QAAQ,CAAC,KAAK,CAAC,EAAE,IAAI,CAAC,aAAa,EAAE,MAAM,GAAG,SAAS,CAAC,GAAG,SAAS,CAAA;IACpE,QAAQ,CAAC,OAAO,CAAC,EAAE,SAAS,wBAAwB,EAAE,GAAG,SAAS,CAAA;CACnE;AAED;;;;;;;GAOG;AACH,wBAAgB,0BAA0B,CACxC,KAAK,EAAE,wBAAwB,GAC9B,SAAS,kBAAkB,EAAE,CA8D/B;AAED,oFAAoF;AACpF,wBAAgB,QAAQ,CAAC,WAAW,EAAE,kBAAkB,GAAG,SAAS,MAAM,EAAE,CAI3E"}
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
import { CogentaError } from '@cogenta/core';
|
|
2
|
+
/**
|
|
3
|
+
* Everything in this build that needs something at request time.
|
|
4
|
+
*
|
|
5
|
+
* `static` needs are included rather than filtered out here: a caller that
|
|
6
|
+
* wants only the problems asks for them against a target, and a caller that
|
|
7
|
+
* wants to display the site's runtime profile gets the whole picture. Filtering
|
|
8
|
+
* belongs to the judgement, not to the collection.
|
|
9
|
+
*/
|
|
10
|
+
export function collectRuntimeRequirements(input) {
|
|
11
|
+
const requirements = [];
|
|
12
|
+
if (input.theme !== undefined) {
|
|
13
|
+
requirements.push({
|
|
14
|
+
origin: 'theme',
|
|
15
|
+
name: input.theme.name,
|
|
16
|
+
runtime: input.theme.runtime,
|
|
17
|
+
placements: [],
|
|
18
|
+
});
|
|
19
|
+
}
|
|
20
|
+
for (const plugin of input.plugins ?? []) {
|
|
21
|
+
requirements.push({
|
|
22
|
+
origin: 'plugin',
|
|
23
|
+
name: plugin.name,
|
|
24
|
+
runtime: plugin.runtime,
|
|
25
|
+
placements: [],
|
|
26
|
+
});
|
|
27
|
+
}
|
|
28
|
+
// Grouped by block name, not by placement: "collectionList needs a server,
|
|
29
|
+
// and here are the eleven pages that place it" is one decision to take.
|
|
30
|
+
// Eleven separate lines would read as eleven problems.
|
|
31
|
+
const byBlock = new Map();
|
|
32
|
+
for (const route of input.routes) {
|
|
33
|
+
for (const block of route.blocks) {
|
|
34
|
+
const definition = input.blocks.get(block._type);
|
|
35
|
+
if (definition === undefined) {
|
|
36
|
+
// Not skipped: an unknown block is exactly the case where guessing a
|
|
37
|
+
// runtime would let a server-side block through a static build.
|
|
38
|
+
throw new CogentaError({
|
|
39
|
+
code: 'BLOCK_UNKNOWN',
|
|
40
|
+
message: `The block "${block._type}" on ${route.path} is not registered, so its runtime needs are unknown.`,
|
|
41
|
+
hint: `Register it — with a fallback, as contract B requires — before building. Known blocks: ${input.blocks.names().join(', ')}.`,
|
|
42
|
+
details: { block: block._type, key: block._key, route: route.path },
|
|
43
|
+
});
|
|
44
|
+
}
|
|
45
|
+
const entry = byBlock.get(definition.name);
|
|
46
|
+
if (entry === undefined) {
|
|
47
|
+
byBlock.set(definition.name, {
|
|
48
|
+
runtime: definition.runtime,
|
|
49
|
+
placements: [{ route: route.path, key: block._key }],
|
|
50
|
+
});
|
|
51
|
+
}
|
|
52
|
+
else {
|
|
53
|
+
entry.placements.push({ route: route.path, key: block._key });
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
for (const [name, entry] of byBlock) {
|
|
58
|
+
requirements.push({
|
|
59
|
+
origin: 'block',
|
|
60
|
+
name,
|
|
61
|
+
runtime: entry.runtime,
|
|
62
|
+
placements: entry.placements,
|
|
63
|
+
});
|
|
64
|
+
}
|
|
65
|
+
return requirements;
|
|
66
|
+
}
|
|
67
|
+
/** The routes a given requirement makes impossible to render ahead of a request. */
|
|
68
|
+
export function routesOf(requirement) {
|
|
69
|
+
const routes = new Set();
|
|
70
|
+
for (const placement of requirement.placements)
|
|
71
|
+
routes.add(placement.route);
|
|
72
|
+
return [...routes];
|
|
73
|
+
}
|
|
74
|
+
//# sourceMappingURL=requirements.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"requirements.js","sourceRoot":"","sources":["../../src/build/requirements.ts"],"names":[],"mappings":"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"}
|