@tycoworks/bon 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/bin/bon.js +2 -2
- package/dist/cli.d.ts +1 -0
- package/dist/cli.js +92 -0
- package/dist/config.d.ts +2 -0
- package/dist/config.js +3 -0
- package/dist/index.d.ts +6 -0
- package/dist/index.js +4 -0
- package/dist/manifest.d.ts +7 -0
- package/dist/manifest.js +53 -0
- package/dist/smoke.d.ts +2 -0
- package/dist/smoke.js +36 -0
- package/package.json +6 -3
- package/src/cli.ts +0 -98
- package/src/config.ts +0 -5
- package/src/index.ts +0 -17
- package/src/manifest.ts +0 -106
- package/src/smoke.ts +0 -34
- package/tsconfig.json +0 -19
package/bin/bon.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
#!/usr/bin/env node
|
|
2
|
-
import("../
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import("../dist/cli.js");
|
package/dist/cli.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
package/dist/cli.js
ADDED
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
import { copyFileSync, mkdirSync, readFileSync, writeFileSync } from "node:fs";
|
|
2
|
+
import { dirname, resolve } from "node:path";
|
|
3
|
+
import { fileURLToPath } from "node:url";
|
|
4
|
+
import { generate } from "@tycoworks/bon-core";
|
|
5
|
+
import { Command } from "commander";
|
|
6
|
+
import { generateManifest } from "./manifest.js";
|
|
7
|
+
import { smokeSteps } from "./smoke.js";
|
|
8
|
+
const DEFAULT_CONFIG = "theme.config.ts";
|
|
9
|
+
const DEFAULT_SMOKE_OUTPUT = "smoke-all.pptx";
|
|
10
|
+
const SKILL_DIR = "skills/slides";
|
|
11
|
+
const MANIFEST_FILE = "manifest.json";
|
|
12
|
+
const SKILL_FILE = "SKILL.md";
|
|
13
|
+
const BUILD_COMMAND = "npx bon build";
|
|
14
|
+
const sdkDir = dirname(fileURLToPath(import.meta.url));
|
|
15
|
+
const skillMdPath = resolve(sdkDir, "..", SKILL_FILE);
|
|
16
|
+
async function loadConfig(configPath) {
|
|
17
|
+
const abs = resolve(process.cwd(), configPath);
|
|
18
|
+
let mod;
|
|
19
|
+
try {
|
|
20
|
+
mod = await import(abs);
|
|
21
|
+
}
|
|
22
|
+
catch {
|
|
23
|
+
throw new Error(`Config file not found: ${configPath}`);
|
|
24
|
+
}
|
|
25
|
+
const raw = (mod.default ?? mod.config);
|
|
26
|
+
if (!raw) {
|
|
27
|
+
throw new Error(`${configPath} must export a default or named "config" of type ThemeConfig`);
|
|
28
|
+
}
|
|
29
|
+
return { ...raw, rootDir: dirname(abs) };
|
|
30
|
+
}
|
|
31
|
+
const program = new Command().name("bon").description("PPTX template engine CLI").version("0.1.0");
|
|
32
|
+
program
|
|
33
|
+
.command("build")
|
|
34
|
+
.description("Build a PPTX deck from a JSON spec")
|
|
35
|
+
.argument("<deck>", "path to deck JSON file")
|
|
36
|
+
.argument("[output]", "output PPTX filename")
|
|
37
|
+
.option(`-c, --config <path>`, "path to theme config file", DEFAULT_CONFIG)
|
|
38
|
+
.action(async (deckPath, output, opts) => {
|
|
39
|
+
const config = await loadConfig(opts.config);
|
|
40
|
+
let deck;
|
|
41
|
+
try {
|
|
42
|
+
const raw = readFileSync(resolve(process.cwd(), deckPath), "utf-8");
|
|
43
|
+
deck = JSON.parse(raw);
|
|
44
|
+
}
|
|
45
|
+
catch (err) {
|
|
46
|
+
throw new Error(`Failed to read deck file: ${deckPath} (${err.message})`);
|
|
47
|
+
}
|
|
48
|
+
if (output)
|
|
49
|
+
deck.output = output;
|
|
50
|
+
await generate(deck, config);
|
|
51
|
+
});
|
|
52
|
+
program
|
|
53
|
+
.command("manifest")
|
|
54
|
+
.description("Generate manifest.json from theme config")
|
|
55
|
+
.option(`-c, --config <path>`, "path to theme config file", DEFAULT_CONFIG)
|
|
56
|
+
.option(`-o, --out <file>`, "write to file instead of stdout")
|
|
57
|
+
.action(async (opts) => {
|
|
58
|
+
const config = await loadConfig(opts.config);
|
|
59
|
+
const json = generateManifest(config, { build: { command: BUILD_COMMAND } });
|
|
60
|
+
if (opts.out) {
|
|
61
|
+
writeFileSync(resolve(process.cwd(), opts.out), `${json}\n`);
|
|
62
|
+
console.log(`WROTE ${opts.out}`);
|
|
63
|
+
}
|
|
64
|
+
else {
|
|
65
|
+
process.stdout.write(`${json}\n`);
|
|
66
|
+
}
|
|
67
|
+
});
|
|
68
|
+
program
|
|
69
|
+
.command("smoke")
|
|
70
|
+
.description("Generate one smoke-test slide per layout")
|
|
71
|
+
.option(`-c, --config <path>`, "path to theme config file", DEFAULT_CONFIG)
|
|
72
|
+
.option(`-o, --out <file>`, "output PPTX filename", DEFAULT_SMOKE_OUTPUT)
|
|
73
|
+
.action(async (opts) => {
|
|
74
|
+
const config = await loadConfig(opts.config);
|
|
75
|
+
const steps = smokeSteps(config);
|
|
76
|
+
await generate({ output: opts.out, steps }, config);
|
|
77
|
+
});
|
|
78
|
+
program
|
|
79
|
+
.command("plugin")
|
|
80
|
+
.description("Generate plugin package (manifest.json + SKILL.md) for AI agents")
|
|
81
|
+
.option(`-c, --config <path>`, "path to theme config file", DEFAULT_CONFIG)
|
|
82
|
+
.action(async (opts) => {
|
|
83
|
+
const config = await loadConfig(opts.config);
|
|
84
|
+
const outDir = resolve(process.cwd(), SKILL_DIR);
|
|
85
|
+
mkdirSync(outDir, { recursive: true });
|
|
86
|
+
const json = generateManifest(config, { build: { command: BUILD_COMMAND } });
|
|
87
|
+
writeFileSync(resolve(outDir, MANIFEST_FILE), `${json}\n`);
|
|
88
|
+
console.log(`WROTE ${SKILL_DIR}/${MANIFEST_FILE}`);
|
|
89
|
+
copyFileSync(skillMdPath, resolve(outDir, SKILL_FILE));
|
|
90
|
+
console.log(`WROTE ${SKILL_DIR}/${SKILL_FILE}`);
|
|
91
|
+
});
|
|
92
|
+
await program.parseAsync(process.argv);
|
package/dist/config.d.ts
ADDED
package/dist/config.js
ADDED
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
export type { AssetCatalog, AssetEntry, AssetSlot, Config, ContentSlot, Deck, DeckStep, Layout, ParagraphSelector, ThemeConfig, } from "@tycoworks/bon-core";
|
|
2
|
+
export { AssetType, Fit, generate, SlotType } from "@tycoworks/bon-core";
|
|
3
|
+
export { defineConfig } from "./config.js";
|
|
4
|
+
export type { ManifestOptions } from "./manifest.js";
|
|
5
|
+
export { generateManifest } from "./manifest.js";
|
|
6
|
+
export { smokeSteps } from "./smoke.js";
|
package/dist/index.js
ADDED
package/dist/manifest.js
ADDED
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
function stripContentSlot(slot) {
|
|
2
|
+
const result = { key: slot.key, type: slot.type };
|
|
3
|
+
if (slot.limit) {
|
|
4
|
+
result.limit = slot.limit;
|
|
5
|
+
}
|
|
6
|
+
return result;
|
|
7
|
+
}
|
|
8
|
+
function stripAssetSlot(slot) {
|
|
9
|
+
const result = { key: slot.key, accepts: slot.accepts };
|
|
10
|
+
if (slot.required) {
|
|
11
|
+
result.required = true;
|
|
12
|
+
}
|
|
13
|
+
return result;
|
|
14
|
+
}
|
|
15
|
+
export function generateManifest(config, options) {
|
|
16
|
+
const layouts = config.layouts.map((layout) => ({
|
|
17
|
+
name: layout.name,
|
|
18
|
+
description: layout.description,
|
|
19
|
+
whenToUse: layout.whenToUse,
|
|
20
|
+
whenNotToUse: layout.whenNotToUse,
|
|
21
|
+
contentSlots: layout.contentSlots.map(stripContentSlot),
|
|
22
|
+
assetSlots: (layout.assetSlots ?? []).map(stripAssetSlot),
|
|
23
|
+
}));
|
|
24
|
+
const assets = {};
|
|
25
|
+
for (const [category, entries] of Object.entries(config.assets)) {
|
|
26
|
+
assets[category] = {};
|
|
27
|
+
for (const [name, entry] of Object.entries(entries)) {
|
|
28
|
+
const manifestEntry = {
|
|
29
|
+
path: entry.path,
|
|
30
|
+
type: entry.type,
|
|
31
|
+
description: entry.description,
|
|
32
|
+
};
|
|
33
|
+
if (entry.whenToUse) {
|
|
34
|
+
manifestEntry.whenToUse = entry.whenToUse;
|
|
35
|
+
}
|
|
36
|
+
assets[category][name] = manifestEntry;
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
const manifest = {
|
|
40
|
+
version: 1,
|
|
41
|
+
layouts,
|
|
42
|
+
assets,
|
|
43
|
+
build: {
|
|
44
|
+
command: options?.build?.command ?? "npx bon build",
|
|
45
|
+
deckFormat: "json",
|
|
46
|
+
deckSchema: {
|
|
47
|
+
output: "string",
|
|
48
|
+
steps: "array of { layout, content, assets }",
|
|
49
|
+
},
|
|
50
|
+
},
|
|
51
|
+
};
|
|
52
|
+
return JSON.stringify(manifest, null, 2);
|
|
53
|
+
}
|
package/dist/smoke.d.ts
ADDED
package/dist/smoke.js
ADDED
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import { SlotType } from "@tycoworks/bon-core";
|
|
2
|
+
function pickAsset(config, slot) {
|
|
3
|
+
for (const group of Object.values(config.assets)) {
|
|
4
|
+
for (const entry of Object.values(group)) {
|
|
5
|
+
if (entry.type === slot.accepts)
|
|
6
|
+
return entry.path;
|
|
7
|
+
}
|
|
8
|
+
}
|
|
9
|
+
return undefined;
|
|
10
|
+
}
|
|
11
|
+
export function smokeSteps(config) {
|
|
12
|
+
return config.layouts.map((layout) => {
|
|
13
|
+
const content = {};
|
|
14
|
+
for (const s of layout.contentSlots) {
|
|
15
|
+
if (s.type === SlotType.Prose) {
|
|
16
|
+
content[s.key] = ["Sample intro line for this block.", "- First point", "- Second point"];
|
|
17
|
+
}
|
|
18
|
+
else if (s.type === SlotType.Lines) {
|
|
19
|
+
content[s.key] = ["Sample Name", "Sample Role, Company"];
|
|
20
|
+
}
|
|
21
|
+
else if (s.key.includes("value")) {
|
|
22
|
+
content[s.key] = "42%";
|
|
23
|
+
}
|
|
24
|
+
else {
|
|
25
|
+
content[s.key] = `Sample ${s.key.replace(/_/g, " ")}`;
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
const assets = {};
|
|
29
|
+
for (const a of layout.assetSlots ?? []) {
|
|
30
|
+
const path = pickAsset(config, a);
|
|
31
|
+
if (path)
|
|
32
|
+
assets[a.key] = path;
|
|
33
|
+
}
|
|
34
|
+
return { layout: layout.name, content, assets };
|
|
35
|
+
});
|
|
36
|
+
}
|
package/package.json
CHANGED
|
@@ -1,16 +1,19 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@tycoworks/bon",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.1",
|
|
4
4
|
"type": "module",
|
|
5
|
-
"main": "
|
|
5
|
+
"main": "dist/index.js",
|
|
6
|
+
"types": "dist/index.d.ts",
|
|
6
7
|
"bin": {
|
|
7
8
|
"bon": "bin/bon.js"
|
|
8
9
|
},
|
|
10
|
+
"files": ["dist", "bin", "SKILL.md"],
|
|
9
11
|
"scripts": {
|
|
12
|
+
"build": "tsc --build",
|
|
10
13
|
"typecheck": "tsc --noEmit"
|
|
11
14
|
},
|
|
12
15
|
"dependencies": {
|
|
13
|
-
"@tycoworks/bon-core": "^0.1.
|
|
16
|
+
"@tycoworks/bon-core": "^0.1.1",
|
|
14
17
|
"commander": "^15.0.0"
|
|
15
18
|
},
|
|
16
19
|
"devDependencies": {
|
package/src/cli.ts
DELETED
|
@@ -1,98 +0,0 @@
|
|
|
1
|
-
import { copyFileSync, mkdirSync, readFileSync, writeFileSync } from "node:fs";
|
|
2
|
-
import { dirname, resolve } from "node:path";
|
|
3
|
-
import { fileURLToPath } from "node:url";
|
|
4
|
-
import type { Config, ThemeConfig } from "@tycoworks/bon-core";
|
|
5
|
-
import { generate } from "@tycoworks/bon-core";
|
|
6
|
-
import { Command } from "commander";
|
|
7
|
-
import { generateManifest } from "./manifest.ts";
|
|
8
|
-
import { smokeSteps } from "./smoke.ts";
|
|
9
|
-
|
|
10
|
-
const DEFAULT_CONFIG = "theme.config.ts";
|
|
11
|
-
const DEFAULT_SMOKE_OUTPUT = "smoke-all.pptx";
|
|
12
|
-
const SKILL_DIR = "skills/slides";
|
|
13
|
-
const MANIFEST_FILE = "manifest.json";
|
|
14
|
-
const SKILL_FILE = "SKILL.md";
|
|
15
|
-
const BUILD_COMMAND = "npx bon build";
|
|
16
|
-
|
|
17
|
-
const sdkDir = dirname(fileURLToPath(import.meta.url));
|
|
18
|
-
const skillMdPath = resolve(sdkDir, "..", SKILL_FILE);
|
|
19
|
-
|
|
20
|
-
async function loadConfig(configPath: string): Promise<Config> {
|
|
21
|
-
const abs = resolve(process.cwd(), configPath);
|
|
22
|
-
let mod: Record<string, unknown>;
|
|
23
|
-
try {
|
|
24
|
-
mod = await import(abs);
|
|
25
|
-
} catch {
|
|
26
|
-
throw new Error(`Config file not found: ${configPath}`);
|
|
27
|
-
}
|
|
28
|
-
const raw = (mod.default ?? mod.config) as ThemeConfig | undefined;
|
|
29
|
-
if (!raw) {
|
|
30
|
-
throw new Error(`${configPath} must export a default or named "config" of type ThemeConfig`);
|
|
31
|
-
}
|
|
32
|
-
return { ...raw, rootDir: dirname(abs) };
|
|
33
|
-
}
|
|
34
|
-
|
|
35
|
-
const program = new Command().name("bon").description("PPTX template engine CLI").version("0.1.0");
|
|
36
|
-
|
|
37
|
-
program
|
|
38
|
-
.command("build")
|
|
39
|
-
.description("Build a PPTX deck from a JSON spec")
|
|
40
|
-
.argument("<deck>", "path to deck JSON file")
|
|
41
|
-
.argument("[output]", "output PPTX filename")
|
|
42
|
-
.option(`-c, --config <path>`, "path to theme config file", DEFAULT_CONFIG)
|
|
43
|
-
.action(async (deckPath: string, output: string | undefined, opts: { config: string }) => {
|
|
44
|
-
const config = await loadConfig(opts.config);
|
|
45
|
-
let deck: Record<string, unknown>;
|
|
46
|
-
try {
|
|
47
|
-
const raw = readFileSync(resolve(process.cwd(), deckPath), "utf-8");
|
|
48
|
-
deck = JSON.parse(raw);
|
|
49
|
-
} catch (err) {
|
|
50
|
-
throw new Error(`Failed to read deck file: ${deckPath} (${(err as Error).message})`);
|
|
51
|
-
}
|
|
52
|
-
if (output) deck.output = output;
|
|
53
|
-
await generate(deck as any, config);
|
|
54
|
-
});
|
|
55
|
-
|
|
56
|
-
program
|
|
57
|
-
.command("manifest")
|
|
58
|
-
.description("Generate manifest.json from theme config")
|
|
59
|
-
.option(`-c, --config <path>`, "path to theme config file", DEFAULT_CONFIG)
|
|
60
|
-
.option(`-o, --out <file>`, "write to file instead of stdout")
|
|
61
|
-
.action(async (opts: { config: string; out?: string }) => {
|
|
62
|
-
const config = await loadConfig(opts.config);
|
|
63
|
-
const json = generateManifest(config, { build: { command: BUILD_COMMAND } });
|
|
64
|
-
if (opts.out) {
|
|
65
|
-
writeFileSync(resolve(process.cwd(), opts.out), `${json}\n`);
|
|
66
|
-
console.log(`WROTE ${opts.out}`);
|
|
67
|
-
} else {
|
|
68
|
-
process.stdout.write(`${json}\n`);
|
|
69
|
-
}
|
|
70
|
-
});
|
|
71
|
-
|
|
72
|
-
program
|
|
73
|
-
.command("smoke")
|
|
74
|
-
.description("Generate one smoke-test slide per layout")
|
|
75
|
-
.option(`-c, --config <path>`, "path to theme config file", DEFAULT_CONFIG)
|
|
76
|
-
.option(`-o, --out <file>`, "output PPTX filename", DEFAULT_SMOKE_OUTPUT)
|
|
77
|
-
.action(async (opts: { config: string; out: string }) => {
|
|
78
|
-
const config = await loadConfig(opts.config);
|
|
79
|
-
const steps = smokeSteps(config);
|
|
80
|
-
await generate({ output: opts.out, steps }, config);
|
|
81
|
-
});
|
|
82
|
-
|
|
83
|
-
program
|
|
84
|
-
.command("plugin")
|
|
85
|
-
.description("Generate plugin package (manifest.json + SKILL.md) for AI agents")
|
|
86
|
-
.option(`-c, --config <path>`, "path to theme config file", DEFAULT_CONFIG)
|
|
87
|
-
.action(async (opts: { config: string }) => {
|
|
88
|
-
const config = await loadConfig(opts.config);
|
|
89
|
-
const outDir = resolve(process.cwd(), SKILL_DIR);
|
|
90
|
-
mkdirSync(outDir, { recursive: true });
|
|
91
|
-
const json = generateManifest(config, { build: { command: BUILD_COMMAND } });
|
|
92
|
-
writeFileSync(resolve(outDir, MANIFEST_FILE), `${json}\n`);
|
|
93
|
-
console.log(`WROTE ${SKILL_DIR}/${MANIFEST_FILE}`);
|
|
94
|
-
copyFileSync(skillMdPath, resolve(outDir, SKILL_FILE));
|
|
95
|
-
console.log(`WROTE ${SKILL_DIR}/${SKILL_FILE}`);
|
|
96
|
-
});
|
|
97
|
-
|
|
98
|
-
await program.parseAsync(process.argv);
|
package/src/config.ts
DELETED
package/src/index.ts
DELETED
|
@@ -1,17 +0,0 @@
|
|
|
1
|
-
export type {
|
|
2
|
-
AssetCatalog,
|
|
3
|
-
AssetEntry,
|
|
4
|
-
AssetSlot,
|
|
5
|
-
Config,
|
|
6
|
-
ContentSlot,
|
|
7
|
-
Deck,
|
|
8
|
-
DeckStep,
|
|
9
|
-
Layout,
|
|
10
|
-
ParagraphSelector,
|
|
11
|
-
ThemeConfig,
|
|
12
|
-
} from "@tycoworks/bon-core";
|
|
13
|
-
export { AssetType, Fit, generate, SlotType } from "@tycoworks/bon-core";
|
|
14
|
-
export { defineConfig } from "./config.ts";
|
|
15
|
-
export type { ManifestOptions } from "./manifest.ts";
|
|
16
|
-
export { generateManifest } from "./manifest.ts";
|
|
17
|
-
export { smokeSteps } from "./smoke.ts";
|
package/src/manifest.ts
DELETED
|
@@ -1,106 +0,0 @@
|
|
|
1
|
-
import type { Config } from "@tycoworks/bon-core";
|
|
2
|
-
|
|
3
|
-
export type ManifestOptions = {
|
|
4
|
-
build?: { command: string };
|
|
5
|
-
};
|
|
6
|
-
|
|
7
|
-
type ManifestContentSlot = {
|
|
8
|
-
key: string;
|
|
9
|
-
type: string;
|
|
10
|
-
limit?: { maxChars?: number; maxLines?: number; maxItems?: number };
|
|
11
|
-
};
|
|
12
|
-
|
|
13
|
-
type ManifestAssetSlot = {
|
|
14
|
-
key: string;
|
|
15
|
-
accepts: string;
|
|
16
|
-
required?: true;
|
|
17
|
-
};
|
|
18
|
-
|
|
19
|
-
type ManifestLayout = {
|
|
20
|
-
name: string;
|
|
21
|
-
description: string;
|
|
22
|
-
whenToUse: string;
|
|
23
|
-
whenNotToUse: string;
|
|
24
|
-
contentSlots: ManifestContentSlot[];
|
|
25
|
-
assetSlots: ManifestAssetSlot[];
|
|
26
|
-
};
|
|
27
|
-
|
|
28
|
-
type ManifestAssetEntry = {
|
|
29
|
-
path: string;
|
|
30
|
-
type: string;
|
|
31
|
-
description: string;
|
|
32
|
-
whenToUse?: string;
|
|
33
|
-
};
|
|
34
|
-
|
|
35
|
-
type Manifest = {
|
|
36
|
-
version: 1;
|
|
37
|
-
layouts: ManifestLayout[];
|
|
38
|
-
assets: Record<string, Record<string, ManifestAssetEntry>>;
|
|
39
|
-
build: {
|
|
40
|
-
command: string;
|
|
41
|
-
deckFormat: "json";
|
|
42
|
-
deckSchema: {
|
|
43
|
-
output: "string";
|
|
44
|
-
steps: "array of { layout, content, assets }";
|
|
45
|
-
};
|
|
46
|
-
};
|
|
47
|
-
};
|
|
48
|
-
|
|
49
|
-
function stripContentSlot(slot: { key: string; type: string; limit?: object }): ManifestContentSlot {
|
|
50
|
-
const result: ManifestContentSlot = { key: slot.key, type: slot.type };
|
|
51
|
-
if (slot.limit) {
|
|
52
|
-
result.limit = slot.limit;
|
|
53
|
-
}
|
|
54
|
-
return result;
|
|
55
|
-
}
|
|
56
|
-
|
|
57
|
-
function stripAssetSlot(slot: { key: string; accepts: string; required?: boolean }): ManifestAssetSlot {
|
|
58
|
-
const result: ManifestAssetSlot = { key: slot.key, accepts: slot.accepts };
|
|
59
|
-
if (slot.required) {
|
|
60
|
-
result.required = true;
|
|
61
|
-
}
|
|
62
|
-
return result;
|
|
63
|
-
}
|
|
64
|
-
|
|
65
|
-
export function generateManifest(config: Config, options?: ManifestOptions): string {
|
|
66
|
-
const layouts: ManifestLayout[] = config.layouts.map((layout) => ({
|
|
67
|
-
name: layout.name,
|
|
68
|
-
description: layout.description,
|
|
69
|
-
whenToUse: layout.whenToUse,
|
|
70
|
-
whenNotToUse: layout.whenNotToUse,
|
|
71
|
-
contentSlots: layout.contentSlots.map(stripContentSlot),
|
|
72
|
-
assetSlots: (layout.assetSlots ?? []).map(stripAssetSlot),
|
|
73
|
-
}));
|
|
74
|
-
|
|
75
|
-
const assets: Record<string, Record<string, ManifestAssetEntry>> = {};
|
|
76
|
-
for (const [category, entries] of Object.entries(config.assets)) {
|
|
77
|
-
assets[category] = {};
|
|
78
|
-
for (const [name, entry] of Object.entries(entries)) {
|
|
79
|
-
const manifestEntry: ManifestAssetEntry = {
|
|
80
|
-
path: entry.path,
|
|
81
|
-
type: entry.type,
|
|
82
|
-
description: entry.description,
|
|
83
|
-
};
|
|
84
|
-
if (entry.whenToUse) {
|
|
85
|
-
manifestEntry.whenToUse = entry.whenToUse;
|
|
86
|
-
}
|
|
87
|
-
assets[category][name] = manifestEntry;
|
|
88
|
-
}
|
|
89
|
-
}
|
|
90
|
-
|
|
91
|
-
const manifest: Manifest = {
|
|
92
|
-
version: 1,
|
|
93
|
-
layouts,
|
|
94
|
-
assets,
|
|
95
|
-
build: {
|
|
96
|
-
command: options?.build?.command ?? "npx bon build",
|
|
97
|
-
deckFormat: "json",
|
|
98
|
-
deckSchema: {
|
|
99
|
-
output: "string",
|
|
100
|
-
steps: "array of { layout, content, assets }",
|
|
101
|
-
},
|
|
102
|
-
},
|
|
103
|
-
};
|
|
104
|
-
|
|
105
|
-
return JSON.stringify(manifest, null, 2);
|
|
106
|
-
}
|
package/src/smoke.ts
DELETED
|
@@ -1,34 +0,0 @@
|
|
|
1
|
-
import type { Config, DeckStep } from "@tycoworks/bon-core";
|
|
2
|
-
import { SlotType } from "@tycoworks/bon-core";
|
|
3
|
-
|
|
4
|
-
function pickAsset(config: Config, slot: { key: string; accepts: string }): string | undefined {
|
|
5
|
-
for (const group of Object.values(config.assets)) {
|
|
6
|
-
for (const entry of Object.values(group)) {
|
|
7
|
-
if (entry.type === slot.accepts) return entry.path;
|
|
8
|
-
}
|
|
9
|
-
}
|
|
10
|
-
return undefined;
|
|
11
|
-
}
|
|
12
|
-
|
|
13
|
-
export function smokeSteps(config: Config): DeckStep[] {
|
|
14
|
-
return config.layouts.map((layout) => {
|
|
15
|
-
const content: Record<string, string | string[]> = {};
|
|
16
|
-
for (const s of layout.contentSlots) {
|
|
17
|
-
if (s.type === SlotType.Prose) {
|
|
18
|
-
content[s.key] = ["Sample intro line for this block.", "- First point", "- Second point"];
|
|
19
|
-
} else if (s.type === SlotType.Lines) {
|
|
20
|
-
content[s.key] = ["Sample Name", "Sample Role, Company"];
|
|
21
|
-
} else if (s.key.includes("value")) {
|
|
22
|
-
content[s.key] = "42%";
|
|
23
|
-
} else {
|
|
24
|
-
content[s.key] = `Sample ${s.key.replace(/_/g, " ")}`;
|
|
25
|
-
}
|
|
26
|
-
}
|
|
27
|
-
const assets: Record<string, string> = {};
|
|
28
|
-
for (const a of layout.assetSlots ?? []) {
|
|
29
|
-
const path = pickAsset(config, a);
|
|
30
|
-
if (path) assets[a.key] = path;
|
|
31
|
-
}
|
|
32
|
-
return { layout: layout.name, content, assets };
|
|
33
|
-
});
|
|
34
|
-
}
|
package/tsconfig.json
DELETED
|
@@ -1,19 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"compilerOptions": {
|
|
3
|
-
"target": "es2022",
|
|
4
|
-
"lib": ["es2023"],
|
|
5
|
-
"module": "nodenext",
|
|
6
|
-
"moduleResolution": "nodenext",
|
|
7
|
-
"allowImportingTsExtensions": true,
|
|
8
|
-
"verbatimModuleSyntax": true,
|
|
9
|
-
"erasableSyntaxOnly": true,
|
|
10
|
-
"declaration": true,
|
|
11
|
-
"declarationDir": "dist",
|
|
12
|
-
"emitDeclarationOnly": true,
|
|
13
|
-
"strict": true,
|
|
14
|
-
"skipLibCheck": true,
|
|
15
|
-
"composite": true
|
|
16
|
-
},
|
|
17
|
-
"include": ["src/**/*.ts"],
|
|
18
|
-
"references": [{ "path": "../core" }]
|
|
19
|
-
}
|