@codepress/design-kit 0.1.0 → 0.1.1
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/package.json +6 -3
- package/src/kit.d.ts +81 -0
- package/src/kit.mjs +44 -12
package/package.json
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@codepress/design-kit",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.1",
|
|
4
4
|
"description": "Capture your Storybook and real app pages as a static design kit, and compose self-contained mockups from it",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|
|
7
|
-
"design-kit": "
|
|
7
|
+
"design-kit": "bin/design-kit.mjs"
|
|
8
8
|
},
|
|
9
9
|
"main": "./src/index.mjs",
|
|
10
10
|
"types": "./src/index.d.ts",
|
|
@@ -13,7 +13,10 @@
|
|
|
13
13
|
"types": "./src/index.d.ts",
|
|
14
14
|
"default": "./src/index.mjs"
|
|
15
15
|
},
|
|
16
|
-
"./kit":
|
|
16
|
+
"./kit": {
|
|
17
|
+
"types": "./src/kit.d.ts",
|
|
18
|
+
"default": "./src/kit.mjs"
|
|
19
|
+
},
|
|
17
20
|
"./schema.json": "./schema/design-kit.config.schema.json",
|
|
18
21
|
"./package.json": "./package.json"
|
|
19
22
|
},
|
package/src/kit.d.ts
ADDED
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
/** Types for `@codepress/design-kit/kit`, the kit tool's functions. */
|
|
2
|
+
|
|
3
|
+
/** One row of `index.json` (stories) or `routes.json` (pages). */
|
|
4
|
+
export interface KitRow {
|
|
5
|
+
id: string;
|
|
6
|
+
kind?: "story" | "route";
|
|
7
|
+
title?: string;
|
|
8
|
+
component?: string;
|
|
9
|
+
file: string;
|
|
10
|
+
width?: number;
|
|
11
|
+
height?: number;
|
|
12
|
+
bytes?: number;
|
|
13
|
+
slots?: string[];
|
|
14
|
+
source_file?: string;
|
|
15
|
+
body_class?: string;
|
|
16
|
+
html_attrs?: Record<string, string>;
|
|
17
|
+
body_attrs?: Record<string, string>;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
export interface KitManifest {
|
|
21
|
+
kit_version?: number;
|
|
22
|
+
sha?: string;
|
|
23
|
+
built_at?: string;
|
|
24
|
+
[key: string]: unknown;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
/** A loaded kit: its folder, manifest and rows, sorted and by id. */
|
|
28
|
+
export interface Kit {
|
|
29
|
+
dir: string;
|
|
30
|
+
manifest: KitManifest | null;
|
|
31
|
+
rows: KitRow[];
|
|
32
|
+
byId: Map<string, KitRow>;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
export function loadKit(dir: string): Kit;
|
|
36
|
+
|
|
37
|
+
/** Rows whose id, title, component or source file holds every word. */
|
|
38
|
+
export function find(kit: Kit, query: string): KitRow[];
|
|
39
|
+
|
|
40
|
+
/** Up to five candidates, closest first. */
|
|
41
|
+
export function nearMatches(wanted: string, candidates: string[]): string[];
|
|
42
|
+
|
|
43
|
+
/** A markup outline of at most `limit` bytes. */
|
|
44
|
+
export function outline(
|
|
45
|
+
html: string,
|
|
46
|
+
limit?: number,
|
|
47
|
+
): { lines: string[]; truncated: boolean };
|
|
48
|
+
|
|
49
|
+
/**
|
|
50
|
+
* One self-contained page. Throws an Error whose message starts with
|
|
51
|
+
* `unknown ` (and names near matches) for an unknown frame, slot or snippet,
|
|
52
|
+
* and with `too large: ` when snippets grow the page past `maxBytes`.
|
|
53
|
+
*/
|
|
54
|
+
export function compose(
|
|
55
|
+
kit: Kit,
|
|
56
|
+
options: {
|
|
57
|
+
frame: string;
|
|
58
|
+
slots?: { name: string; content: string }[];
|
|
59
|
+
theme?: "light" | "dark";
|
|
60
|
+
showNew?: boolean;
|
|
61
|
+
/** Bytes of markup the page may grow to through snippets. */
|
|
62
|
+
maxBytes?: number;
|
|
63
|
+
},
|
|
64
|
+
): string;
|
|
65
|
+
|
|
66
|
+
/** The default `maxBytes` of `compose`: 32 MB. */
|
|
67
|
+
export const COMPOSE_MAX_BYTES: number;
|
|
68
|
+
|
|
69
|
+
export function sanitizeMarkup(html: string): string;
|
|
70
|
+
export function sanitizeCss(css: string): string;
|
|
71
|
+
|
|
72
|
+
/** Runs one command line; returns the exit code. */
|
|
73
|
+
export function run(
|
|
74
|
+
argv: string[],
|
|
75
|
+
io?: { out(text: string): void; err(text: string): void },
|
|
76
|
+
env?: Record<string, string | undefined>,
|
|
77
|
+
defaultDir?: string,
|
|
78
|
+
): number;
|
|
79
|
+
|
|
80
|
+
/** Whether this file is the script node was started with. */
|
|
81
|
+
export function isMain(moduleUrl?: string, script?: string): boolean;
|
package/src/kit.mjs
CHANGED
|
@@ -19,6 +19,12 @@ import { fileURLToPath, pathToFileURL } from "node:url";
|
|
|
19
19
|
const FIND_LIMIT = 30;
|
|
20
20
|
const SHOW_LIMIT = 2048;
|
|
21
21
|
const SNIPPET_DEPTH = 8;
|
|
22
|
+
/**
|
|
23
|
+
* Bytes of markup one compose may read through <kit-snippet>s. Nesting is
|
|
24
|
+
* capped, but a file of many placeholders pointing at large rows would
|
|
25
|
+
* otherwise grow the page exponentially.
|
|
26
|
+
*/
|
|
27
|
+
export const COMPOSE_MAX_BYTES = 32 * 1024 * 1024;
|
|
22
28
|
|
|
23
29
|
class KitError extends Error {}
|
|
24
30
|
|
|
@@ -672,7 +678,7 @@ export function inlineAssets(kit, css, cssDir = join(kit.dir, "css")) {
|
|
|
672
678
|
|
|
673
679
|
// ── compose ─────────────────────────────────────────────────────────────────
|
|
674
680
|
|
|
675
|
-
function expandSnippets(kit, html, used, depth = 0) {
|
|
681
|
+
function expandSnippets(kit, html, used, budget, depth = 0) {
|
|
676
682
|
const found = elements(html).filter((e) => e.name === "kit-snippet");
|
|
677
683
|
if (!found.length) return html;
|
|
678
684
|
if (depth >= SNIPPET_DEPTH) {
|
|
@@ -689,10 +695,16 @@ function expandSnippets(kit, html, used, depth = 0) {
|
|
|
689
695
|
const row = requireRow(kit, id, "<kit-snippet id>");
|
|
690
696
|
used.add(rowSource(row));
|
|
691
697
|
let markup = readSnippet(kit, row);
|
|
698
|
+
budget.left -= markup.length;
|
|
699
|
+
if (budget.left < 0) {
|
|
700
|
+
throw new KitError(
|
|
701
|
+
`too large: the page grows past ${budget.max} bytes while expanding <kit-snippet> elements; use fewer or smaller snippets.`,
|
|
702
|
+
);
|
|
703
|
+
}
|
|
692
704
|
if (rowSource(row) === "stories") markup = unwrapStoryRoot(markup);
|
|
693
705
|
out +=
|
|
694
706
|
html.slice(i, element.start) +
|
|
695
|
-
expandSnippets(kit, markup, used, depth + 1);
|
|
707
|
+
expandSnippets(kit, markup, used, budget, depth + 1);
|
|
696
708
|
i = element.end;
|
|
697
709
|
}
|
|
698
710
|
return out + html.slice(i);
|
|
@@ -815,7 +827,13 @@ function attributes(captured, extraClass, theme, choice, target, fixed) {
|
|
|
815
827
|
*/
|
|
816
828
|
export function compose(
|
|
817
829
|
kit,
|
|
818
|
-
{
|
|
830
|
+
{
|
|
831
|
+
frame,
|
|
832
|
+
slots = [],
|
|
833
|
+
theme = "light",
|
|
834
|
+
showNew = false,
|
|
835
|
+
maxBytes = COMPOSE_MAX_BYTES,
|
|
836
|
+
},
|
|
819
837
|
) {
|
|
820
838
|
const row = requireRow(kit, frame, "frame");
|
|
821
839
|
if (theme !== "light" && theme !== "dark") {
|
|
@@ -823,7 +841,10 @@ export function compose(
|
|
|
823
841
|
}
|
|
824
842
|
const used = new Set([rowSource(row)]);
|
|
825
843
|
const filled = fillSlots(kit, row, readSnippet(kit, row), slots);
|
|
826
|
-
const body = expandSnippets(kit, filled, used
|
|
844
|
+
const body = expandSnippets(kit, filled, used, {
|
|
845
|
+
left: maxBytes - filled.length,
|
|
846
|
+
max: maxBytes,
|
|
847
|
+
});
|
|
827
848
|
|
|
828
849
|
const css = ["stories", "routes"]
|
|
829
850
|
.filter((source) => used.has(source))
|
|
@@ -1069,16 +1090,27 @@ export function run(
|
|
|
1069
1090
|
}
|
|
1070
1091
|
}
|
|
1071
1092
|
|
|
1072
|
-
/**
|
|
1073
|
-
|
|
1074
|
-
|
|
1093
|
+
/**
|
|
1094
|
+
* Whether this file is the script node was started with (symlinks resolved).
|
|
1095
|
+
* Only a file named `kit.mjs` can be: a bundler that inlines this module into
|
|
1096
|
+
* another program keeps `import.meta.url` pointing at that program, which is
|
|
1097
|
+
* also the script node started, and the program would then run the kit's
|
|
1098
|
+
* command line on its own arguments.
|
|
1099
|
+
*/
|
|
1100
|
+
export function isMain(moduleUrl = import.meta.url, script = process.argv[1]) {
|
|
1101
|
+
if (!script) return false;
|
|
1102
|
+
let self;
|
|
1075
1103
|
try {
|
|
1076
|
-
|
|
1077
|
-
|
|
1078
|
-
|
|
1079
|
-
|
|
1104
|
+
self = fileURLToPath(moduleUrl);
|
|
1105
|
+
} catch {
|
|
1106
|
+
// Not a file URL: an evaluated bundle, never the script node started.
|
|
1107
|
+
return false;
|
|
1108
|
+
}
|
|
1109
|
+
if (basename(self) !== "kit.mjs") return false;
|
|
1110
|
+
try {
|
|
1111
|
+
return realpathSync(self) === realpathSync(resolve(script));
|
|
1080
1112
|
} catch {
|
|
1081
|
-
return
|
|
1113
|
+
return moduleUrl === pathToFileURL(resolve(script)).href;
|
|
1082
1114
|
}
|
|
1083
1115
|
}
|
|
1084
1116
|
|