@nextwebwg/htmlkit 1.0.0-alpha.50 → 1.0.0-alpha.51
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/components/breadcrumbs.html +1 -1
- package/components/nav.html +17 -4
- package/components/pager.html +2 -2
- package/dist/application.d.ts.map +1 -1
- package/dist/application.js +116 -17
- package/dist/application.js.map +1 -1
- package/dist/build.d.ts.map +1 -1
- package/dist/build.js +26 -8
- package/dist/build.js.map +1 -1
- package/dist/cli.js +2 -20
- package/dist/cli.js.map +1 -1
- package/dist/config.d.ts +11 -1
- package/dist/config.d.ts.map +1 -1
- package/dist/config.js +30 -2
- package/dist/config.js.map +1 -1
- package/dist/document.d.ts +9 -0
- package/dist/document.d.ts.map +1 -1
- package/dist/document.js +10 -0
- package/dist/document.js.map +1 -1
- package/dist/index.d.ts +2 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -1
- package/dist/index.js.map +1 -1
- package/dist/resource.d.ts +2 -0
- package/dist/resource.d.ts.map +1 -1
- package/dist/resource.js +4 -2
- package/dist/resource.js.map +1 -1
- package/dist/routes.d.ts +10 -2
- package/dist/routes.d.ts.map +1 -1
- package/dist/routes.js +128 -33
- package/dist/routes.js.map +1 -1
- package/dist/types.d.ts +73 -4
- package/dist/types.d.ts.map +1 -1
- package/package.json +2 -2
package/dist/config.d.ts
CHANGED
|
@@ -1,4 +1,9 @@
|
|
|
1
|
-
import type { ApplicationOptions, HtmlKitPlugin } from "./types.js";
|
|
1
|
+
import type { ApplicationOptions, HtmlKitPlugin, RouteLayer } from "./types.js";
|
|
2
|
+
/**
|
|
3
|
+
* The options htmlkit.config.ts (or .js) at root exports by default, loaded through Vite as the CLI
|
|
4
|
+
* loads them; {} without a config file.
|
|
5
|
+
*/
|
|
6
|
+
export declare function loadConfig(root?: string): Promise<ApplicationOptions>;
|
|
2
7
|
export declare class HtmlKitError extends Error {
|
|
3
8
|
readonly source?: string | undefined;
|
|
4
9
|
constructor(message: string, source?: string | undefined);
|
|
@@ -11,6 +16,11 @@ export declare function configure(options: ApplicationOptions): {
|
|
|
11
16
|
outDir: string;
|
|
12
17
|
prefetch: import("./types.js").PrefetchPolicy;
|
|
13
18
|
};
|
|
19
|
+
/** Plugins' named layouts, kept apart from the site's: a site's app/layouts/<name>.html wins over them. */
|
|
20
|
+
export declare const pluginLayouts: unique symbol;
|
|
21
|
+
export type PluginOptions = ApplicationOptions & {
|
|
22
|
+
readonly [pluginLayouts]?: Readonly<Record<string, RouteLayer>>;
|
|
23
|
+
};
|
|
14
24
|
/** Merge each plugin's config() once; options already merged pass through, so nested entry points don't repeat hooks. */
|
|
15
25
|
export declare function withPlugins(options: ApplicationOptions): Promise<ApplicationOptions>;
|
|
16
26
|
/** Run each plugin's hook in order; a failure names the plugin and the hook. */
|
package/dist/config.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,kBAAkB,EAAE,aAAa,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AAEhF;;;GAGG;AACH,wBAAsB,UAAU,CAAC,IAAI,SAAgB,GAAG,OAAO,CAAC,kBAAkB,CAAC,CAWlF;AAED,qBAAa,YAAa,SAAQ,KAAK;IACR,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM;IAArD,YAAY,OAAO,EAAE,MAAM,EAAW,MAAM,CAAC,EAAE,MAAM,YAAA,EAGpD;CACF;AACD,wBAAgB,MAAM,CAAC,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,OAAO,CAG7D;AACD,wBAAgB,SAAS,CAAC,OAAO,EAAE,kBAAkB;;;;;;EAkBpD;AAED,2GAA2G;AAC3G,eAAO,MAAM,aAAa,eAAkC,CAAC;AAC7D,MAAM,MAAM,aAAa,GAAG,kBAAkB,GAAG;IAAE,QAAQ,CAAC,CAAC,aAAa,CAAC,CAAC,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,UAAU,CAAC,CAAC,CAAA;CAAE,CAAC;AAGrH,yHAAyH;AACzH,wBAAsB,WAAW,CAAC,OAAO,EAAE,kBAAkB,GAAG,OAAO,CAAC,kBAAkB,CAAC,CAgB1F;AAED,gFAAgF;AAChF,wBAAsB,OAAO,CAAC,IAAI,SAAS,YAAY,GAAG,UAAU,EAAE,OAAO,EAAE,kBAAkB,EAAE,IAAI,EAAE,IAAI,EAC3G,OAAO,EAAE,UAAU,CAAC,WAAW,CAAC,aAAa,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC,CASzE;AAED,2FAA2F;AAC3F,wBAAgB,SAAS,CAAC,IAAI,EAAE,MAAM;;;IAErC;AAED,8DAA8D;AAC9D,wBAAgB,iBAAiB,CAAC,OAAO,EAAE,kBAAkB,EAAE,IAAI,EAAE,MAAM,GAAG,SAAS,MAAM,EAAE,CAE9F"}
|
package/dist/config.js
CHANGED
|
@@ -1,5 +1,29 @@
|
|
|
1
|
+
import { existsSync } from "node:fs";
|
|
1
2
|
import { isAbsolute, relative, resolve, sep } from "node:path";
|
|
2
|
-
import { normalizePath } from "vite";
|
|
3
|
+
import { createServer, normalizePath } from "vite";
|
|
4
|
+
/**
|
|
5
|
+
* The options htmlkit.config.ts (or .js) at root exports by default, loaded through Vite as the CLI
|
|
6
|
+
* loads them; {} without a config file.
|
|
7
|
+
*/
|
|
8
|
+
export async function loadConfig(root = process.cwd()) {
|
|
9
|
+
const files = ["ts", "js"].map(ext => resolve(root, `htmlkit.config.${ext}`)).filter(existsSync);
|
|
10
|
+
if (files.length > 1)
|
|
11
|
+
throw new HtmlKitError("Choose one htmlkit.config.ts or .js.", resolve(root));
|
|
12
|
+
if (files[0] === undefined)
|
|
13
|
+
return {};
|
|
14
|
+
const loader = await createServer({ root: resolve(root), configFile: false, appType: "custom", logLevel: "silent",
|
|
15
|
+
server: { middlewareMode: true, watch: null, hmr: false }, optimizeDeps: { noDiscovery: true, include: [] } });
|
|
16
|
+
let configured;
|
|
17
|
+
try {
|
|
18
|
+
configured = (await loader.ssrLoadModule(files[0])).default;
|
|
19
|
+
}
|
|
20
|
+
finally {
|
|
21
|
+
await loader.close();
|
|
22
|
+
}
|
|
23
|
+
if (configured === null || typeof configured !== "object")
|
|
24
|
+
throw new HtmlKitError("Configuration must export a default ApplicationOptions object.", files[0]);
|
|
25
|
+
return configured;
|
|
26
|
+
}
|
|
3
27
|
export class HtmlKitError extends Error {
|
|
4
28
|
source;
|
|
5
29
|
constructor(message, source) {
|
|
@@ -34,6 +58,8 @@ export function configure(options) {
|
|
|
34
58
|
throw new HtmlKitError('prefetch must be "interaction", "visible", or "none".');
|
|
35
59
|
return { root, base, origin: origin.origin, outDir, prefetch };
|
|
36
60
|
}
|
|
61
|
+
/** Plugins' named layouts, kept apart from the site's: a site's app/layouts/<name>.html wins over them. */
|
|
62
|
+
export const pluginLayouts = Symbol("htmlkit.pluginLayouts");
|
|
37
63
|
const pluginsApplied = new WeakSet();
|
|
38
64
|
/** Merge each plugin's config() once; options already merged pass through, so nested entry points don't repeat hooks. */
|
|
39
65
|
export async function withPlugins(options) {
|
|
@@ -41,11 +67,13 @@ export async function withPlugins(options) {
|
|
|
41
67
|
return options;
|
|
42
68
|
let merged = options;
|
|
43
69
|
for (const plugin of options.plugins) {
|
|
44
|
-
const added = await plugin.config?.(merged) ?? {};
|
|
70
|
+
const { layouts, ...added } = await plugin.config?.(merged) ?? {};
|
|
45
71
|
// Page folders, stylesheets, and routes add to the application's own; app/pages stays the default folder.
|
|
46
72
|
merged = { ...merged, ...added, plugins: options.plugins,
|
|
47
73
|
...(added.pages === undefined ? {} : { pages: [...merged.pages ?? [{ dir: "app/pages", optional: true }], ...added.pages] }),
|
|
48
74
|
...(added.css === undefined ? {} : { css: [...merged.css ?? [], ...added.css] }),
|
|
75
|
+
// An earlier plugin's named layout wins over a later plugin's of the same name.
|
|
76
|
+
...(layouts === undefined ? {} : { [pluginLayouts]: { ...layouts, ...merged[pluginLayouts] } }),
|
|
49
77
|
...(added.routes === undefined ? {} : { routes: [...merged.routes ?? [], ...added.routes] }) };
|
|
50
78
|
}
|
|
51
79
|
merged = { ...merged };
|
package/dist/config.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"config.js","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,QAAQ,EAAE,OAAO,EAAE,GAAG,EAAE,MAAM,WAAW,CAAC;AAC/D,OAAO,EAAE,aAAa,EAAE,MAAM,MAAM,CAAC;
|
|
1
|
+
{"version":3,"file":"config.js","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;AACrC,OAAO,EAAE,UAAU,EAAE,QAAQ,EAAE,OAAO,EAAE,GAAG,EAAE,MAAM,WAAW,CAAC;AAC/D,OAAO,EAAE,YAAY,EAAE,aAAa,EAAE,MAAM,MAAM,CAAC;AAGnD;;;GAGG;AACH,MAAM,CAAC,KAAK,UAAU,UAAU,CAAC,IAAI,GAAG,OAAO,CAAC,GAAG,EAAE;IACnD,MAAM,KAAK,GAAG,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,CAAC,OAAO,CAAC,IAAI,EAAE,kBAAkB,GAAG,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC,UAAU,CAAC,CAAC;IACjG,IAAI,KAAK,CAAC,MAAM,GAAG,CAAC;QAAE,MAAM,IAAI,YAAY,CAAC,sCAAsC,EAAE,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC;IACpG,IAAI,KAAK,CAAC,CAAC,CAAC,KAAK,SAAS;QAAE,OAAO,EAAE,CAAC;IACtC,MAAM,MAAM,GAAG,MAAM,YAAY,CAAC,EAAE,IAAI,EAAE,OAAO,CAAC,IAAI,CAAC,EAAE,UAAU,EAAE,KAAK,EAAE,OAAO,EAAE,QAAQ,EAAE,QAAQ,EAAE,QAAQ;QAC/G,MAAM,EAAE,EAAE,cAAc,EAAE,IAAI,EAAE,KAAK,EAAE,IAAI,EAAE,GAAG,EAAE,KAAK,EAAE,EAAE,YAAY,EAAE,EAAE,WAAW,EAAE,IAAI,EAAE,OAAO,EAAE,EAAE,EAAE,EAAE,CAAC,CAAC;IACjH,IAAI,UAAmB,CAAC;IACxB,IAAI,CAAC;QAAC,UAAU,GAAG,CAAC,MAAM,MAAM,CAAC,aAAa,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC;IAAC,CAAC;YAC5D,CAAC;QAAC,MAAM,MAAM,CAAC,KAAK,EAAE,CAAC;IAAC,CAAC;IACjC,IAAI,UAAU,KAAK,IAAI,IAAI,OAAO,UAAU,KAAK,QAAQ;QAAE,MAAM,IAAI,YAAY,CAAC,gEAAgE,EAAE,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC;IAC9J,OAAO,UAAgC,CAAC;AAC1C,CAAC;AAED,MAAM,OAAO,YAAa,SAAQ,KAAK;IACC,MAAM;IAA5C,YAAY,OAAe,EAAW,MAAe;QACnD,KAAK,CAAC,MAAM,KAAK,SAAS,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,GAAG,MAAM,KAAK,OAAO,EAAE,CAAC,CAAC;sBAD5B,MAAM;QAE1C,IAAI,CAAC,IAAI,GAAG,cAAc,CAAC;IAC7B,CAAC;CACF;AACD,MAAM,UAAU,MAAM,CAAC,MAAc,EAAE,KAAa;IAClD,MAAM,IAAI,GAAG,QAAQ,CAAC,MAAM,EAAE,KAAK,CAAC,CAAC;IACrC,OAAO,IAAI,KAAK,EAAE,IAAI,CAAC,CAAC,UAAU,CAAC,IAAI,CAAC,IAAI,IAAI,KAAK,IAAI,IAAI,CAAC,IAAI,CAAC,UAAU,CAAC,KAAK,GAAG,EAAE,CAAC,CAAC,CAAC;AAC7F,CAAC;AACD,MAAM,UAAU,SAAS,CAAC,OAA2B;IACnD,mGAAmG;IACnG,IAAI,eAAe,IAAI,OAAO;QAAE,MAAM,IAAI,YAAY,CAAC,2FAA2F,CAAC,CAAC;IACpJ,MAAM,IAAI,GAAG,OAAO,CAAC,OAAO,CAAC,IAAI,IAAI,OAAO,CAAC,GAAG,EAAE,CAAC,CAAC;IACpD,MAAM,IAAI,GAAG,OAAO,CAAC,IAAI,IAAI,GAAG,CAAC;IACjC,IAAI,CAAC,2BAA2B,CAAC,IAAI,CAAC,IAAI,CAAC;QAAE,MAAM,IAAI,YAAY,CAAC,0EAA0E,CAAC,CAAC;IAChJ,MAAM,MAAM,GAAG,IAAI,GAAG,CAAC,OAAO,CAAC,MAAM,IAAI,kBAAkB,CAAC,CAAC;IAC7D,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,IAAI,MAAM,CAAC,QAAQ,IAAI,MAAM,CAAC,QAAQ,IAAI,MAAM,CAAC,QAAQ,KAAK,GAAG,IAAI,MAAM,CAAC,MAAM,IAAI,MAAM,CAAC,IAAI,EAAE,CAAC;QACxI,MAAM,IAAI,YAAY,CAAC,mFAAmF,CAAC,CAAC;IAC9G,CAAC;IACD,MAAM,MAAM,GAAG,OAAO,CAAC,IAAI,EAAE,OAAO,CAAC,MAAM,IAAI,MAAM,CAAC,CAAC;IACvD,gFAAgF;IAChF,IAAI,MAAM,CAAC,MAAM,EAAE,IAAI,CAAC,IAAI,CAAC,KAAK,EAAE,KAAK,EAAE,QAAQ,EAAE,cAAc,EAAE,MAAM,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,MAAM,CAAC,OAAO,CAAC,IAAI,EAAE,IAAI,CAAC,EAAE,MAAM,CAAC,CAAC,EAAE,CAAC;QAC/H,MAAM,IAAI,YAAY,CAAC,0EAA0E,EAAE,MAAM,CAAC,CAAC;IAC7G,CAAC;IACD,MAAM,QAAQ,GAAG,OAAO,CAAC,QAAQ,IAAI,aAAa,CAAC;IACnD,IAAI,CAAC,CAAC,aAAa,EAAE,SAAS,EAAE,MAAM,CAAC,CAAC,QAAQ,CAAC,QAAQ,CAAC;QAAE,MAAM,IAAI,YAAY,CAAC,uDAAuD,CAAC,CAAC;IAC5I,OAAO,EAAE,IAAI,EAAE,IAAI,EAAE,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,EAAE,QAAQ,EAAE,CAAC;AACjE,CAAC;AAED,2GAA2G;AAC3G,MAAM,CAAC,MAAM,aAAa,GAAG,MAAM,CAAC,uBAAuB,CAAC,CAAC;AAG7D,MAAM,cAAc,GAAG,IAAI,OAAO,EAAsB,CAAC;AACzD,yHAAyH;AACzH,MAAM,CAAC,KAAK,UAAU,WAAW,CAAC,OAA2B;IAC3D,IAAI,cAAc,CAAC,GAAG,CAAC,OAAO,CAAC,IAAI,OAAO,CAAC,OAAO,KAAK,SAAS;QAAE,OAAO,OAAO,CAAC;IACjF,IAAI,MAAM,GAAkB,OAAO,CAAC;IACpC,KAAK,MAAM,MAAM,IAAI,OAAO,CAAC,OAAO,EAAE,CAAC;QACrC,MAAM,EAAE,OAAO,EAAE,GAAG,KAAK,EAAE,GAAG,MAAM,MAAM,CAAC,MAAM,EAAE,CAAC,MAAM,CAAC,IAAI,EAAE,CAAC;QAClE,0GAA0G;QAC1G,MAAM,GAAG,EAAE,GAAG,MAAM,EAAE,GAAG,KAAK,EAAE,OAAO,EAAE,OAAO,CAAC,OAAO;YACtD,GAAG,CAAC,KAAK,CAAC,KAAK,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,CAAC,GAAG,MAAM,CAAC,KAAK,IAAI,CAAC,EAAE,GAAG,EAAE,WAAW,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAC,EAAE,GAAG,KAAK,CAAC,KAAK,CAAC,EAAE,CAAC;YAC5H,GAAG,CAAC,KAAK,CAAC,GAAG,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,GAAG,EAAE,CAAC,GAAG,MAAM,CAAC,GAAG,IAAI,EAAE,EAAE,GAAG,KAAK,CAAC,GAAG,CAAC,EAAE,CAAC;YAChF,gFAAgF;YAChF,GAAG,CAAC,OAAO,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,aAAa,CAAC,EAAE,EAAE,GAAG,OAAO,EAAE,GAAG,MAAM,CAAC,aAAa,CAAC,EAAE,EAAE,CAAC;YAC/F,GAAG,CAAC,KAAK,CAAC,MAAM,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,GAAG,MAAM,CAAC,MAAM,IAAI,EAAE,EAAE,GAAG,KAAK,CAAC,MAAM,CAAC,EAAE,CAAC,EAAE,CAAC;IACnG,CAAC;IACD,MAAM,GAAG,EAAE,GAAG,MAAM,EAAE,CAAC;IACvB,cAAc,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;IAC3B,OAAO,MAAM,CAAC;AAChB,CAAC;AAED,gFAAgF;AAChF,MAAM,CAAC,KAAK,UAAU,OAAO,CAAyC,OAA2B,EAAE,IAAU,EAC3G,OAAwD;IACxD,KAAK,MAAM,MAAM,IAAI,OAAO,CAAC,OAAO,IAAI,EAAE,EAAE,CAAC;QAC3C,IAAI,CAAC;YAAC,MAAO,MAAM,CAAC,IAAI,CAAiD,EAAE,IAAI,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;QAAC,CAAC;QACnG,OAAO,KAAK,EAAE,CAAC;YACb,MAAM,OAAO,GAAG,IAAI,YAAY,CAAC,UAAU,MAAM,CAAC,IAAI,cAAc,IAAI,KAAK,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC;YACvI,OAAO,CAAC,KAAK,GAAG,KAAK,CAAC;YACtB,MAAM,OAAO,CAAC;QAChB,CAAC;IACH,CAAC;AACH,CAAC;AAED,2FAA2F;AAC3F,MAAM,UAAU,SAAS,CAAC,IAAY;IACpC,OAAO,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,WAAW,EAAE,aAAa,CAAC,IAAI,CAAC,GAAG,GAAG,EAAE,CAAC,CAAC;AACpE,CAAC;AAED,8DAA8D;AAC9D,MAAM,UAAU,iBAAiB,CAAC,OAA2B,EAAE,IAAY;IACzE,OAAO,CAAC,OAAO,CAAC,GAAG,IAAI,EAAE,CAAC,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC,OAAO,CAAC,IAAI,EAAE,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC;AACtG,CAAC"}
|
package/dist/document.d.ts
CHANGED
|
@@ -7,6 +7,15 @@ export interface PageAssets {
|
|
|
7
7
|
}
|
|
8
8
|
export declare function escapeHTML(value: string): string;
|
|
9
9
|
export declare function documentHTML(body: string, head: RenderedHead, assets?: PageAssets): string;
|
|
10
|
+
/**
|
|
11
|
+
* The page at a redirect's old URL, for static hosts without server redirects: a meta refresh and a
|
|
12
|
+
* canonical link to the Location, and a plain link for readers that don't refresh.
|
|
13
|
+
*/
|
|
14
|
+
export declare function redirectPage(location: string): {
|
|
15
|
+
head: RenderedHead;
|
|
16
|
+
body: string;
|
|
17
|
+
html: string;
|
|
18
|
+
};
|
|
10
19
|
/**
|
|
11
20
|
* A page's payload URL: its route path under the reserved _htmlkit/pages/ tree, which no route or
|
|
12
21
|
* public file may use, so it never collides with an application's own files.
|
package/dist/document.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"document.d.ts","sourceRoot":"","sources":["../src/document.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,YAAY,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAC1E,eAAO,MAAM,mBAAmB,EAAE,SAAS,WAAW,EAGrD,CAAC;AACF,iGAAiG;AACjG,MAAM,WAAW,UAAU;IAAG,QAAQ,CAAC,MAAM,EAAE,SAAS,MAAM,EAAE,CAAC;IAAC,QAAQ,CAAC,OAAO,EAAE,SAAS,MAAM,EAAE,CAAA;CAAE;AACvG,wBAAgB,UAAU,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAEhD;AACD,wBAAgB,YAAY,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,YAAY,EAAE,MAAM,GAAE,UAAwC,GAAG,MAAM,CAavH;AAED;;;GAGG;AACH,wBAAgB,WAAW,CAAC,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,MAAM,CAElE;AAYD;;;;;GAKG;AACH,wBAAgB,WAAW,CAAC,IAAI,EAAE,YAAY,EAAE,MAAM,EAAE,UAAU;;;;;;;;;;;cAKjE"}
|
|
1
|
+
{"version":3,"file":"document.d.ts","sourceRoot":"","sources":["../src/document.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,YAAY,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAC1E,eAAO,MAAM,mBAAmB,EAAE,SAAS,WAAW,EAGrD,CAAC;AACF,iGAAiG;AACjG,MAAM,WAAW,UAAU;IAAG,QAAQ,CAAC,MAAM,EAAE,SAAS,MAAM,EAAE,CAAC;IAAC,QAAQ,CAAC,OAAO,EAAE,SAAS,MAAM,EAAE,CAAA;CAAE;AACvG,wBAAgB,UAAU,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAEhD;AACD,wBAAgB,YAAY,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,YAAY,EAAE,MAAM,GAAE,UAAwC,GAAG,MAAM,CAavH;AAED;;;GAGG;AACH,wBAAgB,YAAY,CAAC,QAAQ,EAAE,MAAM;;;;EAK5C;AAED;;;GAGG;AACH,wBAAgB,WAAW,CAAC,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,MAAM,CAElE;AAYD;;;;;GAKG;AACH,wBAAgB,WAAW,CAAC,IAAI,EAAE,YAAY,EAAE,MAAM,EAAE,UAAU;;;;;;;;;;;cAKjE"}
|
package/dist/document.js
CHANGED
|
@@ -18,6 +18,16 @@ export function documentHTML(body, head, assets = { styles: [], modules: [] }) {
|
|
|
18
18
|
assets.modules.map(src => `<script type="module" src="${escapeHTML(src)}"></script>`).join("") +
|
|
19
19
|
`</head><body>${body}</body></html>`;
|
|
20
20
|
}
|
|
21
|
+
/**
|
|
22
|
+
* The page at a redirect's old URL, for static hosts without server redirects: a meta refresh and a
|
|
23
|
+
* canonical link to the Location, and a plain link for readers that don't refresh.
|
|
24
|
+
*/
|
|
25
|
+
export function redirectPage(location) {
|
|
26
|
+
const head = { title: "Redirecting", elements: [...defaultHeadElements,
|
|
27
|
+
{ tag: "meta", attributes: { "http-equiv": "refresh", content: `0; url=${location}` } }, { tag: "link", attributes: { rel: "canonical", href: location } }] };
|
|
28
|
+
const body = `<main><p>This page is now at <a href="${escapeHTML(location)}">${escapeHTML(location)}</a>.</p></main>`;
|
|
29
|
+
return { head, body, html: documentHTML(body, head) };
|
|
30
|
+
}
|
|
21
31
|
/**
|
|
22
32
|
* A page's payload URL: its route path under the reserved _htmlkit/pages/ tree, which no route or
|
|
23
33
|
* public file may use, so it never collides with an application's own files.
|
package/dist/document.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"document.js","sourceRoot":"","sources":["../src/document.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"document.js","sourceRoot":"","sources":["../src/document.ts"],"names":[],"mappings":"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"}
|
package/dist/index.d.ts
CHANGED
|
@@ -2,9 +2,9 @@ export { createApplication } from "./application.js";
|
|
|
2
2
|
export { buildApplication, readManifest } from "./build.js";
|
|
3
3
|
export { devApplication, previewApplication } from "./serve.js";
|
|
4
4
|
export { discoverRoutes } from "./routes.js";
|
|
5
|
-
export { HtmlKitError } from "./config.js";
|
|
5
|
+
export { HtmlKitError, loadConfig } from "./config.js";
|
|
6
6
|
import type { ApplicationOptions } from "./types.js";
|
|
7
7
|
/** Type-check an htmlkit.config.ts file without changing its values. */
|
|
8
8
|
export declare function defineConfig(options: ApplicationOptions): ApplicationOptions;
|
|
9
|
-
export type { Application, ApplicationOptions, ApplicationRoute, ApplicationServer, BrowserDefinition, BuildEndContext, BuildManifest, BuildResult, BuildStartContext, HtmlKitPlugin, PageContext, PageDirectory, HeadElement, LoadContext, LoaderResult, ManifestPage, NavigationItem, NavigationQuery, PagerLinks, PageHead, PrefetchPolicy, RenderedHead, RenderedLayer, RenderedPage, RouteInput, RouteLayer, ServerModule, ServerOptions } from "./types.js";
|
|
9
|
+
export type { Application, ApplicationOptions, ApplicationRoute, ApplicationServer, BrowserDefinition, BuildEndContext, BuildManifest, BuildResult, BuildStartContext, HtmlKitPlugin, PageContext, PageDirectory, HeadElement, LoadContext, LoaderResult, ManifestPage, ManifestRedirect, NavigationItem, NavigationNode, NavigationQuery, PagerLinks, PageHead, PrefetchPolicy, RedirectStatus, RenderedHead, RenderedLayer, RenderedPage, RouteGroup, RouteInput, RouteLayer, RouteParam, ServerModule, ServerOptions } from "./types.js";
|
|
10
10
|
//# sourceMappingURL=index.d.ts.map
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,iBAAiB,EAAE,MAAM,kBAAkB,CAAC;AACrD,OAAO,EAAE,gBAAgB,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAC5D,OAAO,EAAE,cAAc,EAAE,kBAAkB,EAAE,MAAM,YAAY,CAAC;AAChE,OAAO,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAC7C,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,iBAAiB,EAAE,MAAM,kBAAkB,CAAC;AACrD,OAAO,EAAE,gBAAgB,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAC5D,OAAO,EAAE,cAAc,EAAE,kBAAkB,EAAE,MAAM,YAAY,CAAC;AAChE,OAAO,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAC7C,OAAO,EAAE,YAAY,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AACvD,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,YAAY,CAAC;AACrD,wEAAwE;AACxE,wBAAgB,YAAY,CAAC,OAAO,EAAE,kBAAkB,GAAG,kBAAkB,CAAoB;AACjG,YAAY,EAAE,WAAW,EAAE,kBAAkB,EAAE,gBAAgB,EAAE,iBAAiB,EAAE,iBAAiB,EAAE,eAAe,EAAE,aAAa,EAAE,WAAW,EAAE,iBAAiB,EAAE,aAAa,EAAE,WAAW,EAAE,aAAa,EAC9M,WAAW,EAAE,WAAW,EAAE,YAAY,EAAE,YAAY,EAAE,gBAAgB,EAAE,cAAc,EAAE,cAAc,EAAE,eAAe,EAAE,UAAU,EAAE,QAAQ,EAAE,cAAc,EAAE,cAAc,EAAE,YAAY,EAAE,aAAa,EAAE,YAAY,EACxN,UAAU,EAAE,UAAU,EAAE,UAAU,EAAE,UAAU,EAAE,YAAY,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC"}
|
package/dist/index.js
CHANGED
|
@@ -2,7 +2,7 @@ export { createApplication } from "./application.js";
|
|
|
2
2
|
export { buildApplication, readManifest } from "./build.js";
|
|
3
3
|
export { devApplication, previewApplication } from "./serve.js";
|
|
4
4
|
export { discoverRoutes } from "./routes.js";
|
|
5
|
-
export { HtmlKitError } from "./config.js";
|
|
5
|
+
export { HtmlKitError, loadConfig } from "./config.js";
|
|
6
6
|
/** Type-check an htmlkit.config.ts file without changing its values. */
|
|
7
7
|
export function defineConfig(options) { return options; }
|
|
8
8
|
//# sourceMappingURL=index.js.map
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,iBAAiB,EAAE,MAAM,kBAAkB,CAAC;AACrD,OAAO,EAAE,gBAAgB,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAC5D,OAAO,EAAE,cAAc,EAAE,kBAAkB,EAAE,MAAM,YAAY,CAAC;AAChE,OAAO,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAC7C,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,iBAAiB,EAAE,MAAM,kBAAkB,CAAC;AACrD,OAAO,EAAE,gBAAgB,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAC5D,OAAO,EAAE,cAAc,EAAE,kBAAkB,EAAE,MAAM,YAAY,CAAC;AAChE,OAAO,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAC7C,OAAO,EAAE,YAAY,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAEvD,wEAAwE;AACxE,MAAM,UAAU,YAAY,CAAC,OAA2B,IAAwB,OAAO,OAAO,CAAC,CAAC,CAAC"}
|
package/dist/resource.d.ts
CHANGED
|
@@ -2,6 +2,8 @@ import { type ComponentDefinition } from "@nextwebwg/html-next";
|
|
|
2
2
|
interface ComponentMetadata {
|
|
3
3
|
readonly layout?: string;
|
|
4
4
|
readonly label?: string;
|
|
5
|
+
/** hk:order, the page's place among its neighbours, as a number-and-dot prefix gives it. */
|
|
6
|
+
readonly order?: string;
|
|
5
7
|
readonly hidden?: boolean;
|
|
6
8
|
/** Extra route patterns for a page, relative to its page directory's prefix. */
|
|
7
9
|
readonly aliases: readonly string[];
|
package/dist/resource.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"resource.d.ts","sourceRoot":"","sources":["../src/resource.ts"],"names":[],"mappings":"AAAA,OAAO,EAA0B,KAAK,mBAAmB,EAAE,MAAM,sBAAsB,CAAC;AAIxF,UAAU,iBAAiB;IACzB,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,KAAK,CAAC,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,MAAM,CAAC,EAAE,OAAO,CAAC;IAC1B,gFAAgF;IAChF,QAAQ,CAAC,OAAO,EAAE,SAAS,MAAM,EAAE,CAAC;IACpC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,gBAAgB,EAAE,MAAM,CAAC;CACnC;AAOD,sFAAsF;AACtF,wBAAgB,mBAAmB,CAAC,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM;;;;;
|
|
1
|
+
{"version":3,"file":"resource.d.ts","sourceRoot":"","sources":["../src/resource.ts"],"names":[],"mappings":"AAAA,OAAO,EAA0B,KAAK,mBAAmB,EAAE,MAAM,sBAAsB,CAAC;AAIxF,UAAU,iBAAiB;IACzB,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,KAAK,CAAC,EAAE,MAAM,CAAC;IACxB,4FAA4F;IAC5F,QAAQ,CAAC,KAAK,CAAC,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,MAAM,CAAC,EAAE,OAAO,CAAC;IAC1B,gFAAgF;IAChF,QAAQ,CAAC,OAAO,EAAE,SAAS,MAAM,EAAE,CAAC;IACpC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,gBAAgB,EAAE,MAAM,CAAC;CACnC;AAOD,sFAAsF;AACtF,wBAAgB,mBAAmB,CAAC,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM;;;;;EA+C/D;AAED,wBAAgB,cAAc,CAAC,QAAQ,EAAE,UAAU,CAAC,OAAO,mBAAmB,CAAC,EAAE,IAAI,EAAE,MAAM,GAAG,mBAAmB,CAQlH"}
|
package/dist/resource.js
CHANGED
|
@@ -50,13 +50,15 @@ export function applicationResource(source, file) {
|
|
|
50
50
|
aliases.push(content);
|
|
51
51
|
continue;
|
|
52
52
|
}
|
|
53
|
-
const key = { "hk:layout": "layout", "hk:label": "label", "hk:navigation": "hidden" }[name];
|
|
53
|
+
const key = { "hk:layout": "layout", "hk:label": "label", "hk:order": "order", "hk:navigation": "hidden" }[name];
|
|
54
54
|
if (key === undefined)
|
|
55
|
-
throw new HtmlKitError(`Component configuration is hk:layout, hk:label, hk:navigation, or hk:alias; hk:page belongs outside the carrier (${name}).`, file);
|
|
55
|
+
throw new HtmlKitError(`Component configuration is hk:layout, hk:label, hk:order, hk:navigation, or hk:alias; hk:page belongs outside the carrier (${name}).`, file);
|
|
56
56
|
if (configuration[key] !== undefined)
|
|
57
57
|
throw new HtmlKitError(`Declare ${name} once per component.`, file);
|
|
58
58
|
if (key === "hidden" && content !== "hidden")
|
|
59
59
|
throw new HtmlKitError('hk:navigation accepts only content="hidden".', file);
|
|
60
|
+
if (key === "order" && !/^\d+$/.test(content))
|
|
61
|
+
throw new HtmlKitError("hk:order needs a whole number, such as content=\"3\".", file);
|
|
60
62
|
if (key === "hidden")
|
|
61
63
|
configuration.hidden = true;
|
|
62
64
|
else
|
package/dist/resource.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"resource.js","sourceRoot":"","sources":["../src/resource.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,sBAAsB,EAA4B,MAAM,sBAAsB,CAAC;AACxF,OAAO,EAAE,aAAa,EAAE,cAAc,EAA8B,MAAM,QAAQ,CAAC;AACnF,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;
|
|
1
|
+
{"version":3,"file":"resource.js","sourceRoot":"","sources":["../src/resource.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,sBAAsB,EAA4B,MAAM,sBAAsB,CAAC;AACxF,OAAO,EAAE,aAAa,EAAE,cAAc,EAA8B,MAAM,QAAQ,CAAC;AACnF,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAc3C,uFAAuF;AACvF,SAAS,OAAO,CAAC,IAAwB,EAAE,IAAY;IACrD,IAAI,IAAI,EAAE,UAAU,CAAC,UAAU,CAAC;QAAE,MAAM,IAAI,YAAY,CAAC,+CAA+C,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,eAAe,IAAI,GAAG,EAAE,IAAI,CAAC,CAAC;AAC7J,CAAC;AAED,sFAAsF;AACtF,MAAM,UAAU,mBAAmB,CAAC,MAAc,EAAE,IAAY;IAC9D,MAAM,MAAM,GAAG,sBAAsB,CAAC,MAAM,EAAE,IAAI,CAAC,CAAC;IACpD,MAAM,aAAa,GAAG,IAAI,GAAG,EAAkB,CAAC;IAChD,MAAM,UAAU,GAAG,IAAI,GAAG,EAA6B,CAAC;IACxD,MAAM,QAAQ,GAAG,aAAa,CAAC,MAAM,CAAC,CAAC;IACvC,KAAK,MAAM,IAAI,IAAI,QAAQ,CAAC,UAAU,EAAE,CAAC;QACvC,IAAI,CAAC,CAAC,SAAS,IAAI,IAAI,CAAC,IAAI,CAAC,CAAC,MAAM,EAAE,OAAO,EAAE,MAAM,CAAC,CAAC,QAAQ,CAAC,IAAI,CAAC,OAAO,CAAC;YAAE,SAAS;QACxF,MAAM,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,SAAS,CAAC,EAAE,CAAC,SAAS,CAAC,IAAI,KAAK,MAAM,CAAC,EAAE,KAAK,CAAC;QAC5E,OAAO,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC;QACpB,IAAI,IAAI,CAAC,OAAO,KAAK,MAAM,IAAI,IAAI,KAAK,SAAS,EAAE,CAAC;YAClD,MAAM,OAAO,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,SAAS,CAAC,EAAE,CAAC,SAAS,CAAC,IAAI,KAAK,SAAS,CAAC,EAAE,KAAK,CAAC;YAClF,IAAI,CAAC,OAAO,IAAI,aAAa,CAAC,GAAG,CAAC,IAAI,CAAC;gBAAE,MAAM,IAAI,YAAY,CAAC,WAAW,IAAI,8BAA8B,EAAE,IAAI,CAAC,CAAC;YACrH,aAAa,CAAC,GAAG,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC;QACnC,CAAC;aAAM,IAAI,IAAI,CAAC,OAAO,KAAK,MAAM,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,SAAS,CAAC,EAAE,CAAC,SAAS,CAAC,IAAI,KAAK,KAAK,CAAC,EAAE,KAAK,CAAC,WAAW,EAAE,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,QAAQ,CAAC,WAAW,CAAC,EAAE,CAAC;YACtJ,MAAM,IAAI,YAAY,CAAC,0HAA0H,EAAE,IAAI,CAAC,CAAC;QAC3J,CAAC;IACH,CAAC;IACD,KAAK,MAAM,IAAI,IAAI,QAAQ,CAAC,UAAU,EAAE,CAAC;QACvC,IAAI,CAAC,CAAC,SAAS,IAAI,IAAI,CAAC;YAAE,SAAS;QACnC,MAAM,GAAG,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,SAAS,CAAC,EAAE,CAAC,SAAS,CAAC,IAAI,KAAK,WAAW,CAAC,EAAE,KAAK,CAAC;QAChF,IAAI,IAAI,CAAC,OAAO,KAAK,UAAU,IAAI,GAAG,KAAK,SAAS;YAAE,SAAS;QAC/D,MAAM,QAAQ,GAAI,IAA0C,CAAC,OAAO,CAAC,UAAU,CAAC;QAChF,MAAM,aAAa,GAA0E,EAAE,CAAC;QAChG,MAAM,OAAO,GAAa,EAAE,CAAC;QAC7B,MAAM,IAAI,GAAa,EAAE,CAAC;QAC1B,KAAK,MAAM,KAAK,IAAI,QAAQ,EAAE,CAAC;YAC7B,IAAI,CAAC,CAAC,SAAS,IAAI,KAAK,CAAC,IAAI,CAAC,CAAC,MAAM,EAAE,OAAO,EAAE,MAAM,CAAC,CAAC,QAAQ,CAAC,KAAK,CAAC,OAAO,CAAC;gBAAE,SAAS;YAC1F,MAAM,IAAI,GAAG,KAAK,CAAC,KAAK,CAAC,IAAI,CAAC,SAAS,CAAC,EAAE,CAAC,SAAS,CAAC,IAAI,KAAK,MAAM,CAAC,EAAE,KAAK,CAAC;YAC7E,OAAO,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC;YACpB,IAAI,KAAK,CAAC,OAAO,KAAK,MAAM,IAAI,IAAI,EAAE,UAAU,CAAC,KAAK,CAAC,EAAE,CAAC;gBACxD,MAAM,OAAO,GAAG,KAAK,CAAC,KAAK,CAAC,IAAI,CAAC,SAAS,CAAC,EAAE,CAAC,SAAS,CAAC,IAAI,KAAK,SAAS,CAAC,EAAE,KAAK,CAAC;gBACnF,IAAI,CAAC,OAAO;oBAAE,MAAM,IAAI,YAAY,CAAC,WAAW,IAAI,yBAAyB,EAAE,IAAI,CAAC,CAAC;gBACrF,IAAI,IAAI,KAAK,UAAU,EAAE,CAAC;oBAAC,OAAO,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;oBAAC,SAAS;gBAAC,CAAC;gBAC7D,MAAM,GAAG,GAAI,EAAE,WAAW,EAAE,QAAQ,EAAE,UAAU,EAAE,OAAO,EAAE,UAAU,EAAE,OAAO,EAAE,eAAe,EAAE,QAAQ,EAAY,CAAC,IAAI,CAAC,CAAC;gBAC5H,IAAI,GAAG,KAAK,SAAS;oBAAE,MAAM,IAAI,YAAY,CAAC,8HAA8H,IAAI,IAAI,EAAE,IAAI,CAAC,CAAC;gBAC5L,IAAI,aAAa,CAAC,GAAG,CAAC,KAAK,SAAS;oBAAE,MAAM,IAAI,YAAY,CAAC,WAAW,IAAI,sBAAsB,EAAE,IAAI,CAAC,CAAC;gBAC1G,IAAI,GAAG,KAAK,QAAQ,IAAI,OAAO,KAAK,QAAQ;oBAAE,MAAM,IAAI,YAAY,CAAC,8CAA8C,EAAE,IAAI,CAAC,CAAC;gBAC3H,IAAI,GAAG,KAAK,OAAO,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,OAAO,CAAC;oBAAE,MAAM,IAAI,YAAY,CAAC,uDAAuD,EAAE,IAAI,CAAC,CAAC;gBACrI,IAAI,GAAG,KAAK,QAAQ;oBAAE,aAAa,CAAC,MAAM,GAAG,IAAI,CAAC;;oBAAM,aAAa,CAAC,GAAG,CAAC,GAAG,OAAO,CAAC;YACvF,CAAC;;gBAAM,IAAI,CAAC,IAAI,CAAC,cAAc,CAAC,KAAK,CAAC,CAAC,CAAC;QAC1C,CAAC;QACD,MAAM,IAAI,GAAG,QAAQ,CAAC,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC,SAAS,IAAI,KAAK,IAAI,KAAK,CAAC,OAAO,KAAK,MAAM,CAAC,CAAC;QACpF,MAAM,gBAAgB,GAAG,IAAI,KAAK,SAAS,IAAI,YAAY,IAAI,IAAI,CAAC,CAAC;YACnE,IAAI,CAAC,UAAU,CAAC,MAAM,CAAC,KAAK,CAAC,EAAE,CAAC,SAAS,IAAI,KAAK,IAAI,KAAK,CAAC,OAAO,KAAK,MAAM,CAAC,CAAC,GAAG,CAAC,KAAK,CAAC,EAAE,CAAC,cAAc,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;QACpI,UAAU,CAAC,GAAG,CAAC,GAAG,EAAE,EAAE,GAAG,aAAa,EAAE,OAAO,EAAE,IAAI,EAAE,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,EAAE,gBAAgB,EAAE,CAAC,CAAC;IAC5F,CAAC;IACD,OAAO,EAAE,WAAW,EAAE,MAAM,CAAC,WAAW,EAAE,YAAY,EAAE,MAAM,CAAC,YAAY,EAAE,aAAa,EAAE,UAAU,EAAE,CAAC;AAC3G,CAAC;AAED,MAAM,UAAU,cAAc,CAAC,QAAgD,EAAE,IAAY;IAC3F,MAAM,QAAQ,GAAG,QAAQ,CAAC,aAAa,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC;IACvD,IAAI,QAAQ,KAAK,SAAS,IAAI,QAAQ,CAAC,WAAW,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QAChE,MAAM,IAAI,YAAY,CAAC,4EAA4E,EAAE,IAAI,CAAC,CAAC;IAC7G,CAAC;IACD,MAAM,UAAU,GAAG,QAAQ,KAAK,SAAS,CAAC,CAAC,CAAC,QAAQ,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,WAAW,CAAC,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC,KAAK,CAAC,QAAQ,CAAC,GAAG,KAAK,QAAQ,CAAC,CAAC;IAC1I,IAAI,UAAU,KAAK,SAAS;QAAE,MAAM,IAAI,YAAY,CAAC,0BAA0B,QAAQ,GAAG,EAAE,IAAI,CAAC,CAAC;IAClG,OAAO,UAAU,CAAC;AACpB,CAAC"}
|
package/dist/routes.d.ts
CHANGED
|
@@ -1,7 +1,15 @@
|
|
|
1
1
|
import type { ApplicationOptions, ApplicationRoute } from "./types.js";
|
|
2
|
+
/** The name of a [name], [...name] catch-all, or [[...name]] optional catch-all segment. */
|
|
2
3
|
export declare function parameter(segment: string): string | undefined;
|
|
4
|
+
/** How broadly a segment matches: 0 a literal, 1 [name], 2 [...name], 3 [[...name]]. A missing segment is -1. */
|
|
5
|
+
export declare function breadth(segment: string | undefined): number;
|
|
3
6
|
export declare function validSegment(value: unknown): value is string;
|
|
4
|
-
|
|
7
|
+
export declare const redirectStatuses: readonly number[];
|
|
8
|
+
/** A redirect's Location: an application path, under base, or an absolute http(s) URL. */
|
|
9
|
+
export declare function redirectLocation(base: string, to: unknown, source: string): string;
|
|
10
|
+
/** The redirects option by deployment pathname, each to its Location. */
|
|
11
|
+
export declare function redirectTable(base: string, redirects?: Readonly<Record<string, string>>): ReadonlyMap<string, string>;
|
|
12
|
+
type DiscoveryOptions = Pick<ApplicationOptions, "base" | "routes" | "fileRoutes" | "pages" | "layout" | "layouts" | "layoutDefaults" | "plugins">;
|
|
5
13
|
export declare function discoverRoutes(root?: string, options?: DiscoveryOptions): Promise<readonly ApplicationRoute[]>;
|
|
6
14
|
/**
|
|
7
15
|
* Routes plus what page plugins produced: compiled page sources by component path, and the files
|
|
@@ -15,7 +23,7 @@ export declare function discover(root: string, options: DiscoveryOptions): Promi
|
|
|
15
23
|
}>;
|
|
16
24
|
export declare function matchRoute(routes: readonly ApplicationRoute[], pathname: string, base: string): {
|
|
17
25
|
route: ApplicationRoute;
|
|
18
|
-
params: Readonly<Record<string, string>>;
|
|
26
|
+
params: Readonly<Record<string, string | readonly string[]>>;
|
|
19
27
|
} | undefined;
|
|
20
28
|
export {};
|
|
21
29
|
//# sourceMappingURL=routes.d.ts.map
|
package/dist/routes.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"routes.d.ts","sourceRoot":"","sources":["../src/routes.ts"],"names":[],"mappings":"AAOA,OAAO,KAAK,EAAE,kBAAkB,EAAE,gBAAgB,
|
|
1
|
+
{"version":3,"file":"routes.d.ts","sourceRoot":"","sources":["../src/routes.ts"],"names":[],"mappings":"AAOA,OAAO,KAAK,EAAE,kBAAkB,EAAE,gBAAgB,EAAqD,MAAM,YAAY,CAAC;AAE1H,4FAA4F;AAC5F,wBAAgB,SAAS,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAG7D;AACD,iHAAiH;AACjH,wBAAgB,OAAO,CAAC,OAAO,EAAE,MAAM,GAAG,SAAS,GAAG,MAAM,CAG3D;AACD,wBAAgB,YAAY,CAAC,KAAK,EAAE,OAAO,GAAG,KAAK,IAAI,MAAM,CAE5D;AACD,eAAO,MAAM,gBAAgB,EAAE,SAAS,MAAM,EAA8B,CAAC;AAC7E,0FAA0F;AAC1F,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,MAAM,EAAE,EAAE,EAAE,OAAO,EAAE,MAAM,EAAE,MAAM,GAAG,MAAM,CAIlF;AACD,yEAAyE;AACzE,wBAAgB,aAAa,CAAC,IAAI,EAAE,MAAM,EAAE,SAAS,GAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAM,GAAG,WAAW,CAAC,MAAM,EAAE,MAAM,CAAC,CAUzH;AACD,KAAK,gBAAgB,GAAG,IAAI,CAAC,kBAAkB,EAAE,MAAM,GAAG,QAAQ,GAAG,YAAY,GAAG,OAAO,GAAG,QAAQ,GAAG,SAAS,GAAG,gBAAgB,GAAG,SAAS,CAAC,CAAC;AAEnJ,wBAAsB,cAAc,CAAC,IAAI,SAAgB,EAAE,OAAO,GAAE,gBAAqB,GAAG,OAAO,CAAC,SAAS,gBAAgB,EAAE,CAAC,CAE/H;AAED;;;GAGG;AACH,wBAAsB,QAAQ,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,gBAAgB;;;;;GA2OrE;AACD,wBAAgB,UAAU,CAAC,MAAM,EAAE,SAAS,gBAAgB,EAAE,EAAE,QAAQ,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM;;;cAgC7F"}
|
package/dist/routes.js
CHANGED
|
@@ -3,12 +3,46 @@ import { realpathSync, statSync } from "node:fs";
|
|
|
3
3
|
import { readFile, readdir, realpath, stat } from "node:fs/promises";
|
|
4
4
|
import { basename, join, relative, resolve, sep } from "node:path";
|
|
5
5
|
import { pathToFileURL } from "node:url";
|
|
6
|
-
import { HtmlKitError, within } from "./config.js";
|
|
6
|
+
import { HtmlKitError, pluginLayouts, within } from "./config.js";
|
|
7
7
|
import { applicationResource, pageDefinition } from "./resource.js";
|
|
8
|
-
|
|
8
|
+
/** The name of a [name], [...name] catch-all, or [[...name]] optional catch-all segment. */
|
|
9
|
+
export function parameter(segment) {
|
|
10
|
+
const match = /^\[(?:\.\.\.)?([A-Za-z][A-Za-z0-9_]*)\]$|^\[\[\.\.\.([A-Za-z][A-Za-z0-9_]*)\]\]$/.exec(segment);
|
|
11
|
+
return match?.[1] ?? match?.[2];
|
|
12
|
+
}
|
|
13
|
+
/** How broadly a segment matches: 0 a literal, 1 [name], 2 [...name], 3 [[...name]]. A missing segment is -1. */
|
|
14
|
+
export function breadth(segment) {
|
|
15
|
+
if (segment === undefined)
|
|
16
|
+
return -1;
|
|
17
|
+
return parameter(segment) === undefined ? 0 : segment.startsWith("[[") ? 3 : segment.startsWith("[...") ? 2 : 1;
|
|
18
|
+
}
|
|
9
19
|
export function validSegment(value) {
|
|
10
20
|
return typeof value === "string" && value.length > 0 && value !== "." && value !== ".." && !value.includes("/") && !/[\\\0?#]/.test(value);
|
|
11
21
|
}
|
|
22
|
+
export const redirectStatuses = [301, 302, 303, 307, 308];
|
|
23
|
+
/** A redirect's Location: an application path, under base, or an absolute http(s) URL. */
|
|
24
|
+
export function redirectLocation(base, to, source) {
|
|
25
|
+
if (typeof to === "string" && /^\/(?![/\\])/.test(to))
|
|
26
|
+
return base + to.slice(1);
|
|
27
|
+
try {
|
|
28
|
+
if (typeof to === "string" && /^https?:$/.test(new URL(to).protocol))
|
|
29
|
+
return new URL(to).href;
|
|
30
|
+
}
|
|
31
|
+
catch { /* Reported below. */ }
|
|
32
|
+
throw new HtmlKitError(`Redirect target ${String(to)} must be an application path starting with / or an http(s) URL.`, source);
|
|
33
|
+
}
|
|
34
|
+
/** The redirects option by deployment pathname, each to its Location. */
|
|
35
|
+
export function redirectTable(base, redirects = {}) {
|
|
36
|
+
const table = new Map();
|
|
37
|
+
for (const [from, to] of Object.entries(redirects)) {
|
|
38
|
+
const segments = from.slice(1, -1).split("/").filter(Boolean);
|
|
39
|
+
if (!/^\/(?:[^/]+\/)*$/.test(from) || segments[0] === "_htmlkit" || !segments.every(validSegment)) {
|
|
40
|
+
throw new HtmlKitError("Redirects need application paths with leading and trailing slashes, outside _htmlkit.", from);
|
|
41
|
+
}
|
|
42
|
+
table.set(new URL(base + from.slice(1), "http://localhost").pathname, redirectLocation(base, to, from));
|
|
43
|
+
}
|
|
44
|
+
return table;
|
|
45
|
+
}
|
|
12
46
|
export async function discoverRoutes(root = process.cwd(), options = {}) {
|
|
13
47
|
return (await discover(root, options)).routes;
|
|
14
48
|
}
|
|
@@ -31,7 +65,7 @@ export async function discover(root, options) {
|
|
|
31
65
|
// Each route remembers its page directory's prefix, which page aliases are relative to.
|
|
32
66
|
// folderLayouts are the _layout.html files from the page directory down to the page, outermost first.
|
|
33
67
|
const routes = [];
|
|
34
|
-
const add = (input, prefix, order, directoryLayout, folderLayouts = []) => {
|
|
68
|
+
const add = (input, prefix, order, directoryLayout, folderLayouts = [], groups = []) => {
|
|
35
69
|
if (!/^\/(?:[^/]+\/)*$/.test(input.pattern))
|
|
36
70
|
throw new HtmlKitError("Route patterns require leading and trailing slashes.", input.component);
|
|
37
71
|
const segments = input.pattern.slice(1, -1).split("/").filter(Boolean);
|
|
@@ -40,15 +74,17 @@ export async function discover(root, options) {
|
|
|
40
74
|
if (segments.some(segment => parameter(segment) === undefined && !/^[A-Za-z0-9_-]+$/.test(segment))) {
|
|
41
75
|
throw new HtmlKitError("Route segments must be URL slugs or [named] parameters.", input.component);
|
|
42
76
|
}
|
|
77
|
+
if (segments.slice(0, -1).some(segment => breadth(segment) > 1))
|
|
78
|
+
throw new HtmlKitError("A [...catch-all] parameter must be the last route segment.", input.component);
|
|
43
79
|
const params = segments.flatMap(segment => parameter(segment) ?? []);
|
|
44
80
|
if (new Set(params).size !== params.length)
|
|
45
81
|
throw new HtmlKitError("Route parameter names must be unique.", input.component);
|
|
46
82
|
const absolute = (layer) => ({ component: resolve(root, layer.component),
|
|
47
83
|
...(layer.server === undefined ? {} : { server: typeof layer.server === "string" ? resolve(root, layer.server) : layer.server }) });
|
|
48
84
|
routes.push({ ...absolute(input), pattern: input.pattern, segments, params, layouts: (input.layouts ?? []).map(absolute), prefix, folderLayouts,
|
|
49
|
-
...(directoryLayout === undefined ? {} : { directoryLayout }),
|
|
85
|
+
...(directoryLayout === undefined ? {} : { directoryLayout }), ...(groups.length === 0 ? {} : { groups }),
|
|
50
86
|
...(order === undefined ? {} : { order }), ...(input.canonical === undefined ? {} : { canonical: input.canonical }),
|
|
51
|
-
...(input.notFound ? { notFound: true } : {}) });
|
|
87
|
+
...(input.notFound ? { notFound: true } : {}), ...(input.index ? { index: true } : {}) });
|
|
52
88
|
};
|
|
53
89
|
// A number and a dot ("01.guide") order a file or directory and stay out of its URL. Route
|
|
54
90
|
// segments cannot contain dots, so the prefix is never part of a name.
|
|
@@ -58,9 +94,10 @@ export async function discover(root, options) {
|
|
|
58
94
|
throw new HtmlKitError("Ordering prefix leaves an empty route segment.", source);
|
|
59
95
|
return { slug: prefix?.[2] ?? name, rank: prefix?.[1] ?? null };
|
|
60
96
|
};
|
|
61
|
-
const visit = async (directory, prefix, segments, order, directoryLayout, outer) => {
|
|
97
|
+
const visit = async (directory, prefix, segments, order, directoryLayout, outer, groups) => {
|
|
62
98
|
const files = await readdir(directory, { withFileTypes: true });
|
|
63
99
|
const names = new Set(files.filter(file => file.isFile()).map(file => file.name));
|
|
100
|
+
const prefixDepth = prefix.split("/").filter(Boolean).length;
|
|
64
101
|
const layer = (name, stem) => {
|
|
65
102
|
const servers = ["ts", "js"].filter(ext => names.has(`${stem}.server.${ext}`));
|
|
66
103
|
if (servers.length > 1)
|
|
@@ -76,18 +113,29 @@ export async function discover(root, options) {
|
|
|
76
113
|
const stem = name.slice(0, -extension.length);
|
|
77
114
|
const { slug, rank } = ordered(stem, join(directory, name));
|
|
78
115
|
const parts = slug === "index" ? segments : [...segments, slug];
|
|
79
|
-
// A 404 page at the root of
|
|
80
|
-
|
|
81
|
-
|
|
116
|
+
// A 404 page at the root of a page directory is never a route: at the / prefix it is the
|
|
117
|
+
// not-found page, and at any other prefix the site's not-found page serves those URLs too.
|
|
118
|
+
const notFound = slug === "404" && parts.length === prefixDepth + 1;
|
|
119
|
+
if (notFound && prefix !== "/")
|
|
120
|
+
continue;
|
|
121
|
+
add({ ...layer(name, stem), pattern: `/${parts.length === 0 ? "" : parts.join("/") + "/"}`, ...(notFound ? { notFound: true } : {}), ...(slug === "index" ? { index: true } : {}) }, prefix, slug === "index" ? order : [...order, rank], directoryLayout, folderLayouts, groups);
|
|
82
122
|
}
|
|
83
123
|
for (const file of files.sort((a, b) => a.name.localeCompare(b.name))) {
|
|
84
124
|
if (!file.isDirectory() || file.name.startsWith(".") || file.name.startsWith("_"))
|
|
85
125
|
continue;
|
|
86
126
|
const { slug, rank } = ordered(file.name, join(directory, file.name));
|
|
127
|
+
// A (group) folder orders and labels its pages and adds no URL segment.
|
|
128
|
+
const label = /^\(([^()]*)\)$/.exec(slug)?.[1];
|
|
129
|
+
if (label !== undefined) {
|
|
130
|
+
if (label.trim() === "")
|
|
131
|
+
throw new HtmlKitError("A route group needs a label inside its parentheses.", join(directory, file.name));
|
|
132
|
+
await visit(join(directory, file.name), prefix, segments, order, directoryLayout, folderLayouts, [...groups, { label, order: rank, depth: segments.length }]);
|
|
133
|
+
continue;
|
|
134
|
+
}
|
|
87
135
|
if (parameter(slug) === undefined && !/^[A-Za-z0-9_-]+$/.test(slug)) {
|
|
88
|
-
throw new HtmlKitError("Route directories must be URL slugs
|
|
136
|
+
throw new HtmlKitError("Route directories must be URL slugs, [named] parameters, or (groups).", join(directory, file.name));
|
|
89
137
|
}
|
|
90
|
-
await visit(join(directory, file.name), prefix, [...segments, slug], [...order, rank], directoryLayout, folderLayouts);
|
|
138
|
+
await visit(join(directory, file.name), prefix, [...segments, slug], [...order, rank], directoryLayout, folderLayouts, groups);
|
|
91
139
|
}
|
|
92
140
|
};
|
|
93
141
|
if (options.fileRoutes !== false) {
|
|
@@ -111,7 +159,7 @@ export async function discover(root, options) {
|
|
|
111
159
|
throw new HtmlKitError("Page directory does not exist.", directory);
|
|
112
160
|
const segments = prefix.split("/").filter(Boolean);
|
|
113
161
|
if (present)
|
|
114
|
-
await visit(directory, prefix, segments, segments.map(() => null), layout, []);
|
|
162
|
+
await visit(directory, prefix, segments, segments.map(() => null), layout, [], []);
|
|
115
163
|
}
|
|
116
164
|
}
|
|
117
165
|
for (const route of options.routes ?? [])
|
|
@@ -181,7 +229,7 @@ export async function discover(root, options) {
|
|
|
181
229
|
}
|
|
182
230
|
const patterns = new Map();
|
|
183
231
|
for (const route of routes) {
|
|
184
|
-
const normalized = route.segments.map(segment =>
|
|
232
|
+
const normalized = route.segments.map(segment => ["", "[]", "[...]", "[[...]]"][breadth(segment)] || segment.toLowerCase()).join("/");
|
|
185
233
|
if (patterns.has(normalized))
|
|
186
234
|
throw new HtmlKitError(`Route conflict: ${patterns.get(normalized)} and ${route.component} (${route.pattern}).`, route.component);
|
|
187
235
|
patterns.set(normalized, `${route.component} (${route.pattern})`);
|
|
@@ -189,8 +237,25 @@ export async function discover(root, options) {
|
|
|
189
237
|
const pageNames = new Map();
|
|
190
238
|
const discovered = [];
|
|
191
239
|
let notFound;
|
|
240
|
+
const folderOrders = [];
|
|
192
241
|
const layoutDefaults = Object.entries(options.layoutDefaults ?? {}).sort(([a], [b]) => b.length - a.length);
|
|
193
|
-
|
|
242
|
+
// A layout name is the site's layouts entry, then its app/layouts/<name>.html (the name itself),
|
|
243
|
+
// then a plugin's entry, so a site overrides a plugin's layout with a file of the same name.
|
|
244
|
+
const named = async (name) => {
|
|
245
|
+
if (options.layouts !== undefined && Object.hasOwn(options.layouts, name))
|
|
246
|
+
return options.layouts[name];
|
|
247
|
+
try {
|
|
248
|
+
await stat(resolve(root, `app/layouts/${name}.html`));
|
|
249
|
+
return name;
|
|
250
|
+
}
|
|
251
|
+
catch (error) {
|
|
252
|
+
if (error.code !== "ENOENT")
|
|
253
|
+
throw error;
|
|
254
|
+
}
|
|
255
|
+
const plugins = options[pluginLayouts];
|
|
256
|
+
return plugins !== undefined && Object.hasOwn(plugins, name) ? plugins[name] : undefined;
|
|
257
|
+
};
|
|
258
|
+
for (const { prefix: _prefix, directoryLayout, folderLayouts, notFound: isNotFound, index, ...route } of routes) {
|
|
194
259
|
const { identity, resource } = await resourceOf(route.component);
|
|
195
260
|
const pageName = pageDefinition(resource, route.component).contract.tag;
|
|
196
261
|
const previous = pageNames.get(pageName);
|
|
@@ -202,15 +267,17 @@ export async function discover(root, options) {
|
|
|
202
267
|
// An alias is a further URL for its page, so it takes the layout of the page's own URL.
|
|
203
268
|
const directory = layoutDefaults.find(([prefix]) => (route.canonical ?? route.pattern).startsWith(prefix));
|
|
204
269
|
let selected = metadata.layout ?? directoryLayout ?? directory?.[1] ?? options.layout;
|
|
205
|
-
if (selected === undefined && route.layouts.length === 0)
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
270
|
+
if (selected === undefined && route.layouts.length === 0 && await named("default") !== undefined)
|
|
271
|
+
selected = "default";
|
|
272
|
+
if (typeof selected === "string" && selected !== "none") {
|
|
273
|
+
if (!/^[A-Za-z0-9_-]+$/.test(selected))
|
|
274
|
+
throw new HtmlKitError("Layout names must be filename slugs.", route.component);
|
|
275
|
+
const found = await named(selected);
|
|
276
|
+
if (found === undefined) {
|
|
277
|
+
throw new HtmlKitError(`Layout ${selected} needs ${resolve(root, `app/layouts/${selected}.html`)} or a layouts entry named ${selected}.`, route.component);
|
|
213
278
|
}
|
|
279
|
+
if (typeof found === "object")
|
|
280
|
+
selected = found;
|
|
214
281
|
}
|
|
215
282
|
let layouts = route.layouts;
|
|
216
283
|
if (selected === false || selected === "none")
|
|
@@ -220,10 +287,7 @@ export async function discover(root, options) {
|
|
|
220
287
|
...(selected.server === undefined ? {} : { server: typeof selected.server === "string" ? resolve(root, selected.server) : selected.server }) }];
|
|
221
288
|
}
|
|
222
289
|
else if (selected !== undefined) {
|
|
223
|
-
if (!/^[A-Za-z0-9_-]+$/.test(selected))
|
|
224
|
-
throw new HtmlKitError("Layout names must be filename slugs.", route.component);
|
|
225
290
|
const component = resolve(root, `app/layouts/${selected}.html`);
|
|
226
|
-
await stat(component);
|
|
227
291
|
const servers = [];
|
|
228
292
|
for (const extension of ["ts", "js"]) {
|
|
229
293
|
const candidate = resolve(root, `app/layouts/${selected}.server.${extension}`);
|
|
@@ -243,13 +307,37 @@ export async function discover(root, options) {
|
|
|
243
307
|
// The selected layout is outermost and folder layouts nest inside it; none drops them all.
|
|
244
308
|
if (selected !== false && selected !== "none")
|
|
245
309
|
layouts = [...layouts, ...folderLayouts];
|
|
246
|
-
|
|
247
|
-
|
|
310
|
+
// hk:order takes the place of the number-and-dot prefix on the page's own last segment.
|
|
311
|
+
// hk:order takes the place of the number-and-dot prefix on the page's own last segment; on a
|
|
312
|
+
// folder's index page, that segment is the folder's, so it orders the folder (below).
|
|
313
|
+
let order = route.order;
|
|
314
|
+
if (metadata.order !== undefined && route.canonical === undefined && !isNotFound) {
|
|
315
|
+
if (route.segments.length === 0)
|
|
316
|
+
throw new HtmlKitError("hk:order on the site's home page has no folder to order; it orders a page among its folder's pages.", route.component);
|
|
317
|
+
order = [...route.segments.slice(0, -1).map((_, i) => route.order?.[i] ?? null), metadata.order];
|
|
318
|
+
if (index)
|
|
319
|
+
folderOrders.push({ segments: route.segments, rank: metadata.order });
|
|
320
|
+
}
|
|
321
|
+
// A static <title> labels the page's folder in navigation trees when hk:label doesn't.
|
|
322
|
+
const title = /^<title>([^<{]*)<\/title>$/m.exec(metadata.head.replaceAll("><", ">\n<"))?.[1]?.trim()
|
|
323
|
+
.replace(/&(lt|gt|quot|#39|amp);/g, (_, name) => ({ lt: "<", gt: ">", quot: '"', "#39": "'", amp: "&" })[name]);
|
|
324
|
+
const discoveredRoute = { ...route, layouts, pageName, ...(order === undefined ? {} : { order }), ...(metadata.label === undefined ? {} : { label: metadata.label }),
|
|
325
|
+
...(title ? { title } : {}), ...(metadata.hidden ? { hidden: true } : {}) };
|
|
248
326
|
if (isNotFound)
|
|
249
327
|
notFound = discoveredRoute;
|
|
250
328
|
else
|
|
251
329
|
discovered.push(discoveredRoute);
|
|
252
330
|
}
|
|
331
|
+
// Every page in a folder whose index page sets hk:order takes that rank for the folder's segment.
|
|
332
|
+
for (const { segments, rank } of folderOrders) {
|
|
333
|
+
for (const [i, route] of discovered.entries()) {
|
|
334
|
+
if (route.canonical !== undefined || route.segments.length < segments.length || segments.some((segment, j) => route.segments[j] !== segment))
|
|
335
|
+
continue;
|
|
336
|
+
const order = route.segments.map((_, j) => route.order?.[j] ?? null);
|
|
337
|
+
order[segments.length - 1] = rank;
|
|
338
|
+
discovered[i] = { ...route, order };
|
|
339
|
+
}
|
|
340
|
+
}
|
|
253
341
|
return { routes: discovered, ...(notFound === undefined ? {} : { notFound }), sources, files };
|
|
254
342
|
}
|
|
255
343
|
export function matchRoute(routes, pathname, base) {
|
|
@@ -264,27 +352,34 @@ export function matchRoute(routes, pathname, base) {
|
|
|
264
352
|
}
|
|
265
353
|
if (segments.some(segment => !validSegment(segment)))
|
|
266
354
|
return undefined;
|
|
267
|
-
//
|
|
355
|
+
// Segment by segment, a literal precedes [name], which precedes [...name], which precedes
|
|
356
|
+
// [[...name]]; never depend on filesystem order.
|
|
268
357
|
const sorted = [...routes].sort((a, b) => {
|
|
269
|
-
for (let i = 0; i < Math.
|
|
270
|
-
const difference =
|
|
358
|
+
for (let i = 0; i < Math.max(a.segments.length, b.segments.length); i++) {
|
|
359
|
+
const difference = breadth(a.segments[i]) - breadth(b.segments[i]);
|
|
271
360
|
if (difference !== 0)
|
|
272
361
|
return difference;
|
|
273
362
|
}
|
|
274
363
|
return a.pattern.localeCompare(b.pattern);
|
|
275
364
|
});
|
|
276
365
|
for (const route of sorted) {
|
|
277
|
-
|
|
366
|
+
// A catch-all takes the remaining segments: at least one, or any number for [[...name]].
|
|
367
|
+
const rest = Math.max(0, breadth(route.segments.at(-1)) - 1);
|
|
368
|
+
const fixed = rest === 0 ? route.segments.length : route.segments.length - 1;
|
|
369
|
+
if (rest === 0 ? segments.length !== fixed : segments.length < fixed + 2 - rest)
|
|
278
370
|
continue;
|
|
279
371
|
const params = {};
|
|
280
|
-
if (route.segments.every((segment, index) => {
|
|
372
|
+
if (route.segments.slice(0, fixed).every((segment, index) => {
|
|
281
373
|
const name = parameter(segment);
|
|
282
374
|
if (name === undefined)
|
|
283
375
|
return segment === segments[index];
|
|
284
376
|
params[name] = segments[index];
|
|
285
377
|
return true;
|
|
286
|
-
}))
|
|
378
|
+
})) {
|
|
379
|
+
if (rest > 0)
|
|
380
|
+
params[parameter(route.segments.at(-1))] = Object.freeze(segments.slice(fixed));
|
|
287
381
|
return { route, params: Object.freeze(params) };
|
|
382
|
+
}
|
|
288
383
|
}
|
|
289
384
|
return undefined;
|
|
290
385
|
}
|