@zpress/core 0.4.0 → 0.5.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/index.d.ts +91 -1
- package/dist/index.mjs +85 -2
- package/package.json +1 -1
package/dist/index.d.ts
CHANGED
|
@@ -69,12 +69,22 @@ export declare interface CardConfig {
|
|
|
69
69
|
};
|
|
70
70
|
}
|
|
71
71
|
|
|
72
|
+
/**
|
|
73
|
+
* All valid color modes — used for validation.
|
|
74
|
+
*/
|
|
75
|
+
export declare const COLOR_MODES: readonly ColorMode[];
|
|
76
|
+
|
|
77
|
+
/**
|
|
78
|
+
* How dark/light mode is controlled.
|
|
79
|
+
*/
|
|
80
|
+
export declare type ColorMode = 'dark' | 'light' | 'toggle';
|
|
81
|
+
|
|
72
82
|
/**
|
|
73
83
|
* Error produced during config validation in `defineConfig`.
|
|
74
84
|
*/
|
|
75
85
|
export declare interface ConfigError {
|
|
76
86
|
readonly _tag: 'ConfigError';
|
|
77
|
-
readonly type: 'empty_sections' | 'missing_field' | 'duplicate_prefix' | 'invalid_icon' | 'invalid_entry';
|
|
87
|
+
readonly type: 'empty_sections' | 'missing_field' | 'duplicate_prefix' | 'invalid_icon' | 'invalid_entry' | 'invalid_theme';
|
|
78
88
|
readonly message: string;
|
|
79
89
|
}
|
|
80
90
|
|
|
@@ -513,6 +523,14 @@ export declare interface Paths {
|
|
|
513
523
|
readonly cacheDir: string;
|
|
514
524
|
}
|
|
515
525
|
|
|
526
|
+
/**
|
|
527
|
+
* Resolve the default color mode for a given theme name.
|
|
528
|
+
*
|
|
529
|
+
* @param theme - Built-in theme identifier
|
|
530
|
+
* @returns The theme's natural color mode
|
|
531
|
+
*/
|
|
532
|
+
export declare function resolveDefaultColorMode(theme: ThemeName): ColorMode;
|
|
533
|
+
|
|
516
534
|
/**
|
|
517
535
|
* Internal resolved node — produced by the resolver, consumed by copy + sidebar/nav generators.
|
|
518
536
|
*/
|
|
@@ -750,6 +768,73 @@ export declare interface SyncResult {
|
|
|
750
768
|
readonly elapsed: number;
|
|
751
769
|
}
|
|
752
770
|
|
|
771
|
+
/**
|
|
772
|
+
* All valid theme names — used for validation.
|
|
773
|
+
*/
|
|
774
|
+
export declare const THEME_NAMES: readonly ThemeName[];
|
|
775
|
+
|
|
776
|
+
/**
|
|
777
|
+
* Optional color overrides keyed to CSS custom properties.
|
|
778
|
+
*
|
|
779
|
+
* Each key maps to one or more `--zp-c-*` / `--rp-c-*` variables.
|
|
780
|
+
* Values must be valid CSS color strings (hex or rgba).
|
|
781
|
+
*/
|
|
782
|
+
export declare interface ThemeColors {
|
|
783
|
+
readonly brand?: string;
|
|
784
|
+
readonly brandLight?: string;
|
|
785
|
+
readonly brandDark?: string;
|
|
786
|
+
readonly brandSoft?: string;
|
|
787
|
+
readonly bg?: string;
|
|
788
|
+
readonly bgAlt?: string;
|
|
789
|
+
readonly bgElv?: string;
|
|
790
|
+
readonly bgSoft?: string;
|
|
791
|
+
readonly text1?: string;
|
|
792
|
+
readonly text2?: string;
|
|
793
|
+
readonly text3?: string;
|
|
794
|
+
readonly divider?: string;
|
|
795
|
+
readonly border?: string;
|
|
796
|
+
readonly homeBg?: string;
|
|
797
|
+
}
|
|
798
|
+
|
|
799
|
+
/**
|
|
800
|
+
* Top-level theme configuration for `zpress.config.ts`.
|
|
801
|
+
*/
|
|
802
|
+
export declare interface ThemeConfig {
|
|
803
|
+
/**
|
|
804
|
+
* Built-in theme to use.
|
|
805
|
+
* @default 'base'
|
|
806
|
+
*/
|
|
807
|
+
readonly name?: ThemeName;
|
|
808
|
+
/**
|
|
809
|
+
* Color mode behavior. Defaults to the theme's natural mode.
|
|
810
|
+
*/
|
|
811
|
+
readonly colorMode?: ColorMode;
|
|
812
|
+
/**
|
|
813
|
+
* Show the theme switcher dropdown in the nav bar.
|
|
814
|
+
* @default false
|
|
815
|
+
*/
|
|
816
|
+
readonly switcher?: boolean;
|
|
817
|
+
/**
|
|
818
|
+
* Partial color overrides applied in light mode (or base mode).
|
|
819
|
+
*/
|
|
820
|
+
readonly colors?: ThemeColors;
|
|
821
|
+
/**
|
|
822
|
+
* Partial color overrides applied only in dark mode.
|
|
823
|
+
*/
|
|
824
|
+
readonly darkColors?: ThemeColors;
|
|
825
|
+
}
|
|
826
|
+
|
|
827
|
+
/**
|
|
828
|
+
* Theme types and default resolution.
|
|
829
|
+
*
|
|
830
|
+
* Defines the built-in theme palette system: theme names, color modes,
|
|
831
|
+
* per-theme color overrides, and the top-level ThemeConfig shape.
|
|
832
|
+
*/
|
|
833
|
+
/**
|
|
834
|
+
* Built-in theme identifiers.
|
|
835
|
+
*/
|
|
836
|
+
export declare type ThemeName = 'base' | 'midnight' | 'arcade';
|
|
837
|
+
|
|
753
838
|
/**
|
|
754
839
|
* URL path (e.g. `"/guides/add-api-route"`)
|
|
755
840
|
*/
|
|
@@ -917,6 +1002,11 @@ export declare interface ZpressConfig {
|
|
|
917
1002
|
* Site meta description. Used as the hero headline on the home page.
|
|
918
1003
|
*/
|
|
919
1004
|
readonly description?: string;
|
|
1005
|
+
/**
|
|
1006
|
+
* Theme configuration.
|
|
1007
|
+
* Controls the visual theme, color mode, and optional color overrides.
|
|
1008
|
+
*/
|
|
1009
|
+
readonly theme?: ThemeConfig;
|
|
920
1010
|
/**
|
|
921
1011
|
* Path to a custom favicon file served from `.zpress/public/`.
|
|
922
1012
|
* When omitted, defaults to the auto-generated `/icon.svg`.
|
package/dist/index.mjs
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
|
+
import { P, match } from "ts-pattern";
|
|
1
2
|
import { loadConfig } from "c12";
|
|
2
3
|
import promises from "node:fs/promises";
|
|
3
4
|
import node_path from "node:path";
|
|
4
5
|
import { log } from "@clack/prompts";
|
|
5
|
-
import { P, match } from "ts-pattern";
|
|
6
6
|
import { capitalize, groupBy, isUndefined, omitBy, range, words } from "es-toolkit";
|
|
7
7
|
import { createHash } from "node:crypto";
|
|
8
8
|
import gray_matter from "gray-matter";
|
|
@@ -47,6 +47,19 @@ function collectResults(results) {
|
|
|
47
47
|
[]
|
|
48
48
|
]);
|
|
49
49
|
}
|
|
50
|
+
const THEME_NAMES = [
|
|
51
|
+
'base',
|
|
52
|
+
'midnight',
|
|
53
|
+
'arcade'
|
|
54
|
+
];
|
|
55
|
+
const COLOR_MODES = [
|
|
56
|
+
'dark',
|
|
57
|
+
'light',
|
|
58
|
+
'toggle'
|
|
59
|
+
];
|
|
60
|
+
function resolveDefaultColorMode(theme) {
|
|
61
|
+
return match(theme).with('base', ()=>'toggle').with('midnight', ()=>'dark').with('arcade', ()=>'dark').exhaustive();
|
|
62
|
+
}
|
|
50
63
|
function defineConfig(config) {
|
|
51
64
|
return config;
|
|
52
65
|
}
|
|
@@ -85,6 +98,11 @@ function validateConfig(config) {
|
|
|
85
98
|
featErr,
|
|
86
99
|
null
|
|
87
100
|
];
|
|
101
|
+
const [themeErr] = validateTheme(config.theme);
|
|
102
|
+
if (themeErr) return [
|
|
103
|
+
themeErr,
|
|
104
|
+
null
|
|
105
|
+
];
|
|
88
106
|
return [
|
|
89
107
|
null,
|
|
90
108
|
config
|
|
@@ -217,6 +235,71 @@ function validateFeature(feature) {
|
|
|
217
235
|
if (feature.icon && !feature.icon.includes(':')) return configError('invalid_icon', `Feature "${feature.text}": icon must be an Iconify identifier (e.g. "pixelarticons:speed-fast")`);
|
|
218
236
|
return null;
|
|
219
237
|
}
|
|
238
|
+
function validateThemeColors(colors, label) {
|
|
239
|
+
const colorPattern = /^(?:#(?:[0-9a-fA-F]{3}|[0-9a-fA-F]{6})|rgba?\([^)]*\))$/;
|
|
240
|
+
const keys = [
|
|
241
|
+
'brand',
|
|
242
|
+
'brandLight',
|
|
243
|
+
'brandDark',
|
|
244
|
+
'brandSoft',
|
|
245
|
+
'bg',
|
|
246
|
+
'bgAlt',
|
|
247
|
+
'bgElv',
|
|
248
|
+
'bgSoft',
|
|
249
|
+
'text1',
|
|
250
|
+
'text2',
|
|
251
|
+
'text3',
|
|
252
|
+
'divider',
|
|
253
|
+
'border',
|
|
254
|
+
'homeBg'
|
|
255
|
+
];
|
|
256
|
+
const firstError = keys.reduce((acc, key)=>{
|
|
257
|
+
if (acc) return acc;
|
|
258
|
+
const value = colors[key];
|
|
259
|
+
if (void 0 !== value && !colorPattern.test(value)) return configError('invalid_theme', `theme.${label}.${key}: "${value}" is not a valid color (use hex #xxx/#xxxxxx or rgba())`);
|
|
260
|
+
return null;
|
|
261
|
+
}, null);
|
|
262
|
+
if (firstError) return [
|
|
263
|
+
firstError,
|
|
264
|
+
null
|
|
265
|
+
];
|
|
266
|
+
return [
|
|
267
|
+
null,
|
|
268
|
+
true
|
|
269
|
+
];
|
|
270
|
+
}
|
|
271
|
+
function validateTheme(theme) {
|
|
272
|
+
if (void 0 === theme) return [
|
|
273
|
+
null,
|
|
274
|
+
true
|
|
275
|
+
];
|
|
276
|
+
if (void 0 !== theme.name && !THEME_NAMES.includes(theme.name)) return [
|
|
277
|
+
configError('invalid_theme', `theme.name: "${theme.name}" is not a valid theme (use ${THEME_NAMES.map((n)=>`"${n}"`).join(', ')})`),
|
|
278
|
+
null
|
|
279
|
+
];
|
|
280
|
+
if (void 0 !== theme.colorMode && !COLOR_MODES.includes(theme.colorMode)) return [
|
|
281
|
+
configError('invalid_theme', `theme.colorMode: "${theme.colorMode}" is not valid (use ${COLOR_MODES.map((m)=>`"${m}"`).join(', ')})`),
|
|
282
|
+
null
|
|
283
|
+
];
|
|
284
|
+
if (theme.colors) {
|
|
285
|
+
const [colorsErr] = validateThemeColors(theme.colors, 'colors');
|
|
286
|
+
if (colorsErr) return [
|
|
287
|
+
colorsErr,
|
|
288
|
+
null
|
|
289
|
+
];
|
|
290
|
+
}
|
|
291
|
+
if (theme.darkColors) {
|
|
292
|
+
const [darkErr] = validateThemeColors(theme.darkColors, 'darkColors');
|
|
293
|
+
if (darkErr) return [
|
|
294
|
+
darkErr,
|
|
295
|
+
null
|
|
296
|
+
];
|
|
297
|
+
}
|
|
298
|
+
return [
|
|
299
|
+
null,
|
|
300
|
+
true
|
|
301
|
+
];
|
|
302
|
+
}
|
|
220
303
|
async function config_loadConfig(dir) {
|
|
221
304
|
const { config } = await loadConfig({
|
|
222
305
|
cwd: dir,
|
|
@@ -2831,4 +2914,4 @@ function createPaths(dir) {
|
|
|
2831
2914
|
cacheDir: node_path.resolve(outputRoot, 'cache')
|
|
2832
2915
|
};
|
|
2833
2916
|
}
|
|
2834
|
-
export { configError, config_loadConfig as loadConfig, createPaths, defineConfig, generateAssets, generateBannerSvg, generateIconSvg, generateLogoSvg, hasGlobChars, loadManifest, resolveEntries, sync, syncError, validateConfig };
|
|
2917
|
+
export { COLOR_MODES, THEME_NAMES, configError, config_loadConfig as loadConfig, createPaths, defineConfig, generateAssets, generateBannerSvg, generateIconSvg, generateLogoSvg, hasGlobChars, loadManifest, resolveDefaultColorMode, resolveEntries, sync, syncError, validateConfig };
|