@appmockup/cli 0.2.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/README.md +37 -0
- package/dist/index.js +178 -0
- package/dist/index.js.map +1 -0
- package/package.json +36 -0
package/README.md
ADDED
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
# @appmockup/cli
|
|
2
|
+
|
|
3
|
+
The `appmockup` command-line tool — generate App Store / Play Store screenshot mockups
|
|
4
|
+
from raw screenshots and a JSON config. Part of
|
|
5
|
+
[AppMockup](https://github.com/yakupbulbul/AppMockup).
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
npm i -g @appmockup/cli
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
## Commands
|
|
12
|
+
|
|
13
|
+
```bash
|
|
14
|
+
# Scaffold appmockup.json + screenshots/
|
|
15
|
+
appmockup init --name "My App"
|
|
16
|
+
|
|
17
|
+
# Validate a config (schema + a headline per language + screenshot files exist)
|
|
18
|
+
appmockup validate --config appmockup.json [--json]
|
|
19
|
+
|
|
20
|
+
# Render a single mockup (and optionally open it)
|
|
21
|
+
appmockup preview --config appmockup.json --screenshot 01 --language en [--size iPhone_6.7] [--open] [--json]
|
|
22
|
+
|
|
23
|
+
# Batch-render every size × language × screenshot into ./output
|
|
24
|
+
appmockup generate --config appmockup.json \
|
|
25
|
+
[--output-dir ./output] [--languages en,tr] [--screenshots 01,02] [--sizes iPhone_6.7] \
|
|
26
|
+
[--dry-run] [--json]
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
`--dry-run` lists the paths that would be written without rendering. `--json` emits
|
|
30
|
+
machine-readable output. Output layout: `output/<size>/<lang>/<prefix>_<lang>_<id>.png`.
|
|
31
|
+
|
|
32
|
+
See [docs/config-schema.md](../../docs/config-schema.md) for the config format and
|
|
33
|
+
[docs/local-usage.md](../../docs/local-usage.md) for a full walkthrough.
|
|
34
|
+
|
|
35
|
+
## License
|
|
36
|
+
|
|
37
|
+
MIT © Yakup Bülbül
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,178 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
// src/index.ts
|
|
4
|
+
import { Command } from "commander";
|
|
5
|
+
import { spawn } from "child_process";
|
|
6
|
+
import fs from "fs/promises";
|
|
7
|
+
import fssync from "fs";
|
|
8
|
+
import path from "path";
|
|
9
|
+
import {
|
|
10
|
+
loadConfigFile,
|
|
11
|
+
validateConfig,
|
|
12
|
+
generate,
|
|
13
|
+
renderOneToPng
|
|
14
|
+
} from "@appmockup/node-render";
|
|
15
|
+
var VERSION = "0.2.0";
|
|
16
|
+
function splitList(value) {
|
|
17
|
+
if (!value) return void 0;
|
|
18
|
+
const parts = value.split(",").map((s) => s.trim()).filter((s) => s.length > 0);
|
|
19
|
+
return parts.length > 0 ? parts : void 0;
|
|
20
|
+
}
|
|
21
|
+
function fail(message) {
|
|
22
|
+
console.error(`Error: ${message}`);
|
|
23
|
+
process.exit(1);
|
|
24
|
+
}
|
|
25
|
+
async function loadOrFail(configPath) {
|
|
26
|
+
return loadConfigFile(configPath).catch(
|
|
27
|
+
(e) => fail(`Failed to load config: ${e.message}`)
|
|
28
|
+
);
|
|
29
|
+
}
|
|
30
|
+
function plannedPaths(config, outputDir, f) {
|
|
31
|
+
const sizes = config.outputSizes.filter((s) => !f.sizes || f.sizes.includes(s.name));
|
|
32
|
+
const langs = config.languages.filter((l) => !f.languages || f.languages.includes(l));
|
|
33
|
+
const shots = config.screenshots.filter((s) => !f.screenshots || f.screenshots.includes(s.id));
|
|
34
|
+
const paths = [];
|
|
35
|
+
for (const size of sizes)
|
|
36
|
+
for (const lang of langs)
|
|
37
|
+
for (const shot of shots)
|
|
38
|
+
paths.push(
|
|
39
|
+
path.join(outputDir, size.name, lang, `${config.outputPrefix}_${lang}_${shot.id}.png`)
|
|
40
|
+
);
|
|
41
|
+
return paths;
|
|
42
|
+
}
|
|
43
|
+
function openFile(filePath) {
|
|
44
|
+
const cmd = process.platform === "darwin" ? "open" : process.platform === "win32" ? "cmd" : "xdg-open";
|
|
45
|
+
const args = process.platform === "win32" ? ["/c", "start", "", filePath] : [filePath];
|
|
46
|
+
spawn(cmd, args, { stdio: "ignore", detached: true }).unref();
|
|
47
|
+
}
|
|
48
|
+
var program = new Command();
|
|
49
|
+
program.name("appmockup").description("Generate App Store screenshot mockups from raw screenshots and a JSON config.").version(VERSION);
|
|
50
|
+
program.command("validate").description("Validate a config: schema, headlines per language, and screenshot files exist.").requiredOption("--config <path>", "Path to the JSON config file.").option("--json", "Emit machine-readable JSON.").action(async (opts) => {
|
|
51
|
+
const { config, configDir } = await loadOrFail(opts.config);
|
|
52
|
+
const problems = validateConfig({ config, configDir });
|
|
53
|
+
if (opts.json) {
|
|
54
|
+
console.log(JSON.stringify({ valid: problems.length === 0, problems }, null, 2));
|
|
55
|
+
} else if (problems.length === 0) {
|
|
56
|
+
console.log("OK \u2014 config is valid.");
|
|
57
|
+
} else {
|
|
58
|
+
console.error(`Config is invalid:
|
|
59
|
+
- ${problems.join("\n - ")}`);
|
|
60
|
+
}
|
|
61
|
+
if (problems.length > 0) process.exit(1);
|
|
62
|
+
});
|
|
63
|
+
program.command("generate").description("Generate mockups for all screenshots, languages, and sizes.").requiredOption("--config <path>", "Path to the JSON config file.").option("--output-dir <path>", "Output directory.", "./output").option("--languages <list>", "Comma-separated language filter.").option("--screenshots <list>", "Comma-separated screenshot ID filter.").option("--sizes <list>", "Comma-separated output size name filter.").option("--dry-run", "Validate and list the paths that would be written, without rendering.").option("--json", "Emit machine-readable JSON instead of progress output.").action(async (opts) => {
|
|
64
|
+
const { config, configDir } = await loadOrFail(opts.config);
|
|
65
|
+
const filters = {
|
|
66
|
+
languages: splitList(opts.languages),
|
|
67
|
+
screenshots: splitList(opts.screenshots),
|
|
68
|
+
sizes: splitList(opts.sizes)
|
|
69
|
+
};
|
|
70
|
+
const problems = validateConfig({ config, configDir });
|
|
71
|
+
if (problems.length > 0) {
|
|
72
|
+
fail(`Config is invalid:
|
|
73
|
+
- ${problems.join("\n - ")}`);
|
|
74
|
+
}
|
|
75
|
+
if (opts.dryRun) {
|
|
76
|
+
const paths2 = plannedPaths(config, opts.outputDir, filters);
|
|
77
|
+
if (opts.json) {
|
|
78
|
+
console.log(JSON.stringify({ dryRun: true, count: paths2.length, paths: paths2 }, null, 2));
|
|
79
|
+
} else {
|
|
80
|
+
console.log(`Would generate ${paths2.length} mockups:`);
|
|
81
|
+
for (const p of paths2) console.log(` ${p}`);
|
|
82
|
+
}
|
|
83
|
+
return;
|
|
84
|
+
}
|
|
85
|
+
const total = plannedPaths(config, opts.outputDir, filters).length;
|
|
86
|
+
let n = 0;
|
|
87
|
+
const paths = await generate({
|
|
88
|
+
config,
|
|
89
|
+
configDir,
|
|
90
|
+
outputDir: opts.outputDir,
|
|
91
|
+
...filters,
|
|
92
|
+
onProgress: (pct, p) => {
|
|
93
|
+
n += 1;
|
|
94
|
+
if (!opts.json) console.log(`[${n}/${total} ${pct}%] ${p}`);
|
|
95
|
+
}
|
|
96
|
+
});
|
|
97
|
+
if (opts.json) {
|
|
98
|
+
console.log(JSON.stringify({ count: paths.length, paths }, null, 2));
|
|
99
|
+
} else {
|
|
100
|
+
console.log(`
|
|
101
|
+
Generated ${paths.length} mockups in ${opts.outputDir}/`);
|
|
102
|
+
}
|
|
103
|
+
});
|
|
104
|
+
program.command("preview").description("Render a single mockup for quick preview.").requiredOption("--config <path>", "Path to the JSON config file.").requiredOption("--screenshot <id>", "Screenshot ID to render.").requiredOption("--language <code>", "Language code.").option("--size <name>", "Output size name (default: first in config).").option("--output-dir <path>", "Output directory.", "./output").option("--open", "Open the result after rendering.").option("--json", "Emit machine-readable JSON.").action(async (opts) => {
|
|
105
|
+
const { config, configDir } = await loadOrFail(opts.config);
|
|
106
|
+
const result = await renderOneToPng({
|
|
107
|
+
config,
|
|
108
|
+
configDir,
|
|
109
|
+
screenshotId: opts.screenshot,
|
|
110
|
+
language: opts.language,
|
|
111
|
+
sizeName: opts.size
|
|
112
|
+
}).catch((e) => fail(e.message));
|
|
113
|
+
const langDir = path.join(opts.outputDir, result.size.name, opts.language);
|
|
114
|
+
await fs.mkdir(langDir, { recursive: true });
|
|
115
|
+
const filename = `${config.outputPrefix}_${opts.language}_${result.entry.id}.png`;
|
|
116
|
+
const outputPath = path.join(langDir, filename);
|
|
117
|
+
await fs.writeFile(outputPath, result.buffer);
|
|
118
|
+
if (opts.json) {
|
|
119
|
+
console.log(JSON.stringify({ path: outputPath, size: result.size.name }, null, 2));
|
|
120
|
+
} else {
|
|
121
|
+
console.log(`Preview saved to: ${outputPath}`);
|
|
122
|
+
}
|
|
123
|
+
if (opts.open) openFile(outputPath);
|
|
124
|
+
});
|
|
125
|
+
program.command("init").description("Scaffold a starter config and screenshots folder.").option("--dir <path>", "Directory to scaffold into.", ".").option("--name <appName>", "App name.", "MyApp").action(async (opts) => {
|
|
126
|
+
const dir = path.resolve(opts.dir);
|
|
127
|
+
const configPath = path.join(dir, "appmockup.json");
|
|
128
|
+
if (fssync.existsSync(configPath)) {
|
|
129
|
+
fail(`${configPath} already exists.`);
|
|
130
|
+
}
|
|
131
|
+
await fs.mkdir(path.join(dir, "screenshots"), { recursive: true });
|
|
132
|
+
const starter = starterConfig(opts.name);
|
|
133
|
+
await fs.writeFile(configPath, `${JSON.stringify(starter, null, 2)}
|
|
134
|
+
`, "utf8");
|
|
135
|
+
console.log(`Created ${configPath}`);
|
|
136
|
+
console.log(`Created ${path.join(dir, "screenshots")}/`);
|
|
137
|
+
console.log(
|
|
138
|
+
`
|
|
139
|
+
Next: drop a screenshot at screenshots/01.png, then run:
|
|
140
|
+
appmockup preview --config ${configPath} --screenshot 01 --language en --open`
|
|
141
|
+
);
|
|
142
|
+
});
|
|
143
|
+
program.parseAsync(process.argv).catch((e) => fail(e.message));
|
|
144
|
+
function starterConfig(appName) {
|
|
145
|
+
return {
|
|
146
|
+
appName,
|
|
147
|
+
outputPrefix: appName.toLowerCase().replace(/\s+/g, "-"),
|
|
148
|
+
languages: ["en"],
|
|
149
|
+
outputSizes: [
|
|
150
|
+
{ name: "iPhone_6.7", width: 1290, height: 2796 },
|
|
151
|
+
{ name: "iPhone_6.5", width: 1242, height: 2688 },
|
|
152
|
+
{ name: "iPad_12.9", width: 2048, height: 2732 }
|
|
153
|
+
],
|
|
154
|
+
background: {
|
|
155
|
+
type: "gradient",
|
|
156
|
+
colors: ["#FBF8F2", "#F0E4CF"],
|
|
157
|
+
direction: "topToBottom"
|
|
158
|
+
},
|
|
159
|
+
headline: { fontWeight: "bold", color: "#1D2939", relativeSize: 0.05 },
|
|
160
|
+
subtitle: { text: appName, fontWeight: "medium", color: "#C9975B", relativeSize: 0.025 },
|
|
161
|
+
deviceFrame: {
|
|
162
|
+
style: "iPhone",
|
|
163
|
+
bezelColor: "#1D2939",
|
|
164
|
+
cornerRadius: 55,
|
|
165
|
+
bezelWidth: 12,
|
|
166
|
+
screenRelativeWidth: 0.75,
|
|
167
|
+
verticalOffset: 0.25
|
|
168
|
+
},
|
|
169
|
+
screenshots: [
|
|
170
|
+
{
|
|
171
|
+
id: "01",
|
|
172
|
+
file: "screenshots/01.png",
|
|
173
|
+
headlines: { en: "Your headline\ngoes here" }
|
|
174
|
+
}
|
|
175
|
+
]
|
|
176
|
+
};
|
|
177
|
+
}
|
|
178
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/index.ts"],"sourcesContent":["import { Command } from \"commander\";\nimport { spawn } from \"node:child_process\";\nimport fs from \"node:fs/promises\";\nimport fssync from \"node:fs\";\nimport path from \"node:path\";\nimport {\n loadConfigFile,\n validateConfig,\n generate,\n renderOneToPng,\n} from \"@appmockup/node-render\";\nimport type { MockupConfig } from \"@appmockup/core\";\n\nconst VERSION = \"0.2.0\";\n\nfunction splitList(value: string | undefined): string[] | undefined {\n if (!value) return undefined;\n const parts = value\n .split(\",\")\n .map((s) => s.trim())\n .filter((s) => s.length > 0);\n return parts.length > 0 ? parts : undefined;\n}\n\nfunction fail(message: string): never {\n console.error(`Error: ${message}`);\n process.exit(1);\n}\n\ninterface Filters {\n languages?: string[];\n screenshots?: string[];\n sizes?: string[];\n}\n\n/** Load a config file, exiting with a readable error on failure. */\nasync function loadOrFail(configPath: string) {\n return loadConfigFile(configPath).catch((e: unknown) =>\n fail(`Failed to load config: ${(e as Error).message}`),\n );\n}\n\n/**\n * Compute the output paths a `generate` run would write, without rendering — the\n * same `<outputDir>/<size>/<lang>/<prefix>_<lang>_<id>.png` layout and filter order\n * that @appmockup/node-render's generate() uses. Powers `--dry-run` and progress totals.\n */\nfunction plannedPaths(config: MockupConfig, outputDir: string, f: Filters): string[] {\n const sizes = config.outputSizes.filter((s) => !f.sizes || f.sizes.includes(s.name));\n const langs = config.languages.filter((l) => !f.languages || f.languages.includes(l));\n const shots = config.screenshots.filter((s) => !f.screenshots || f.screenshots.includes(s.id));\n const paths: string[] = [];\n for (const size of sizes)\n for (const lang of langs)\n for (const shot of shots)\n paths.push(\n path.join(outputDir, size.name, lang, `${config.outputPrefix}_${lang}_${shot.id}.png`),\n );\n return paths;\n}\n\nfunction openFile(filePath: string): void {\n const cmd =\n process.platform === \"darwin\"\n ? \"open\"\n : process.platform === \"win32\"\n ? \"cmd\"\n : \"xdg-open\";\n const args = process.platform === \"win32\" ? [\"/c\", \"start\", \"\", filePath] : [filePath];\n spawn(cmd, args, { stdio: \"ignore\", detached: true }).unref();\n}\n\nconst program = new Command();\nprogram\n .name(\"appmockup\")\n .description(\"Generate App Store screenshot mockups from raw screenshots and a JSON config.\")\n .version(VERSION);\n\nprogram\n .command(\"validate\")\n .description(\"Validate a config: schema, headlines per language, and screenshot files exist.\")\n .requiredOption(\"--config <path>\", \"Path to the JSON config file.\")\n .option(\"--json\", \"Emit machine-readable JSON.\")\n .action(async (opts) => {\n const { config, configDir } = await loadOrFail(opts.config);\n const problems = validateConfig({ config, configDir });\n if (opts.json) {\n console.log(JSON.stringify({ valid: problems.length === 0, problems }, null, 2));\n } else if (problems.length === 0) {\n console.log(\"OK — config is valid.\");\n } else {\n console.error(`Config is invalid:\\n - ${problems.join(\"\\n - \")}`);\n }\n if (problems.length > 0) process.exit(1);\n });\n\nprogram\n .command(\"generate\")\n .description(\"Generate mockups for all screenshots, languages, and sizes.\")\n .requiredOption(\"--config <path>\", \"Path to the JSON config file.\")\n .option(\"--output-dir <path>\", \"Output directory.\", \"./output\")\n .option(\"--languages <list>\", \"Comma-separated language filter.\")\n .option(\"--screenshots <list>\", \"Comma-separated screenshot ID filter.\")\n .option(\"--sizes <list>\", \"Comma-separated output size name filter.\")\n .option(\"--dry-run\", \"Validate and list the paths that would be written, without rendering.\")\n .option(\"--json\", \"Emit machine-readable JSON instead of progress output.\")\n .action(async (opts) => {\n const { config, configDir } = await loadOrFail(opts.config);\n const filters: Filters = {\n languages: splitList(opts.languages),\n screenshots: splitList(opts.screenshots),\n sizes: splitList(opts.sizes),\n };\n const problems = validateConfig({ config, configDir });\n if (problems.length > 0) {\n fail(`Config is invalid:\\n - ${problems.join(\"\\n - \")}`);\n }\n\n if (opts.dryRun) {\n const paths = plannedPaths(config, opts.outputDir, filters);\n if (opts.json) {\n console.log(JSON.stringify({ dryRun: true, count: paths.length, paths }, null, 2));\n } else {\n console.log(`Would generate ${paths.length} mockups:`);\n for (const p of paths) console.log(` ${p}`);\n }\n return;\n }\n\n const total = plannedPaths(config, opts.outputDir, filters).length;\n let n = 0;\n const paths = await generate({\n config,\n configDir,\n outputDir: opts.outputDir,\n ...filters,\n onProgress: (pct, p) => {\n n += 1;\n if (!opts.json) console.log(`[${n}/${total} ${pct}%] ${p}`);\n },\n });\n if (opts.json) {\n console.log(JSON.stringify({ count: paths.length, paths }, null, 2));\n } else {\n console.log(`\\nGenerated ${paths.length} mockups in ${opts.outputDir}/`);\n }\n });\n\nprogram\n .command(\"preview\")\n .description(\"Render a single mockup for quick preview.\")\n .requiredOption(\"--config <path>\", \"Path to the JSON config file.\")\n .requiredOption(\"--screenshot <id>\", \"Screenshot ID to render.\")\n .requiredOption(\"--language <code>\", \"Language code.\")\n .option(\"--size <name>\", \"Output size name (default: first in config).\")\n .option(\"--output-dir <path>\", \"Output directory.\", \"./output\")\n .option(\"--open\", \"Open the result after rendering.\")\n .option(\"--json\", \"Emit machine-readable JSON.\")\n .action(async (opts) => {\n const { config, configDir } = await loadOrFail(opts.config);\n const result = await renderOneToPng({\n config,\n configDir,\n screenshotId: opts.screenshot,\n language: opts.language,\n sizeName: opts.size,\n }).catch((e: unknown) => fail((e as Error).message));\n\n const langDir = path.join(opts.outputDir, result.size.name, opts.language);\n await fs.mkdir(langDir, { recursive: true });\n const filename = `${config.outputPrefix}_${opts.language}_${result.entry.id}.png`;\n const outputPath = path.join(langDir, filename);\n await fs.writeFile(outputPath, result.buffer);\n\n if (opts.json) {\n console.log(JSON.stringify({ path: outputPath, size: result.size.name }, null, 2));\n } else {\n console.log(`Preview saved to: ${outputPath}`);\n }\n if (opts.open) openFile(outputPath);\n });\n\nprogram\n .command(\"init\")\n .description(\"Scaffold a starter config and screenshots folder.\")\n .option(\"--dir <path>\", \"Directory to scaffold into.\", \".\")\n .option(\"--name <appName>\", \"App name.\", \"MyApp\")\n .action(async (opts) => {\n const dir = path.resolve(opts.dir);\n const configPath = path.join(dir, \"appmockup.json\");\n if (fssync.existsSync(configPath)) {\n fail(`${configPath} already exists.`);\n }\n await fs.mkdir(path.join(dir, \"screenshots\"), { recursive: true });\n const starter = starterConfig(opts.name);\n await fs.writeFile(configPath, `${JSON.stringify(starter, null, 2)}\\n`, \"utf8\");\n console.log(`Created ${configPath}`);\n console.log(`Created ${path.join(dir, \"screenshots\")}/`);\n console.log(\n \"\\nNext: drop a screenshot at screenshots/01.png, then run:\\n\" +\n ` appmockup preview --config ${configPath} --screenshot 01 --language en --open`,\n );\n });\n\nprogram.parseAsync(process.argv).catch((e: unknown) => fail((e as Error).message));\n\nfunction starterConfig(appName: string): MockupConfig {\n return {\n appName,\n outputPrefix: appName.toLowerCase().replace(/\\s+/g, \"-\"),\n languages: [\"en\"],\n outputSizes: [\n { name: \"iPhone_6.7\", width: 1290, height: 2796 },\n { name: \"iPhone_6.5\", width: 1242, height: 2688 },\n { name: \"iPad_12.9\", width: 2048, height: 2732 },\n ],\n background: {\n type: \"gradient\",\n colors: [\"#FBF8F2\", \"#F0E4CF\"],\n direction: \"topToBottom\",\n },\n headline: { fontWeight: \"bold\", color: \"#1D2939\", relativeSize: 0.05 },\n subtitle: { text: appName, fontWeight: \"medium\", color: \"#C9975B\", relativeSize: 0.025 },\n deviceFrame: {\n style: \"iPhone\",\n bezelColor: \"#1D2939\",\n cornerRadius: 55,\n bezelWidth: 12,\n screenRelativeWidth: 0.75,\n verticalOffset: 0.25,\n },\n screenshots: [\n {\n id: \"01\",\n file: \"screenshots/01.png\",\n headlines: { en: \"Your headline\\ngoes here\" },\n },\n ],\n };\n}\n"],"mappings":"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","names":["paths"]}
|
package/package.json
ADDED
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@appmockup/cli",
|
|
3
|
+
"version": "0.2.0",
|
|
4
|
+
"description": "The appmockup command-line tool — generate App Store screenshot mockups from a JSON config.",
|
|
5
|
+
"license": "MIT",
|
|
6
|
+
"author": "Yakup Bülbül",
|
|
7
|
+
"keywords": ["app-store", "screenshots", "mockup", "cli", "appmockup"],
|
|
8
|
+
"repository": {
|
|
9
|
+
"type": "git",
|
|
10
|
+
"url": "https://github.com/yakupbulbul/AppMockup.git",
|
|
11
|
+
"directory": "packages/cli"
|
|
12
|
+
},
|
|
13
|
+
"homepage": "https://github.com/yakupbulbul/AppMockup#readme",
|
|
14
|
+
"bugs": "https://github.com/yakupbulbul/AppMockup/issues",
|
|
15
|
+
"publishConfig": { "access": "public" },
|
|
16
|
+
"type": "module",
|
|
17
|
+
"bin": {
|
|
18
|
+
"appmockup": "./dist/index.js"
|
|
19
|
+
},
|
|
20
|
+
"files": ["dist"],
|
|
21
|
+
"scripts": {
|
|
22
|
+
"build": "tsup",
|
|
23
|
+
"dev": "tsup --watch",
|
|
24
|
+
"typecheck": "tsc --noEmit"
|
|
25
|
+
},
|
|
26
|
+
"dependencies": {
|
|
27
|
+
"@appmockup/core": "workspace:*",
|
|
28
|
+
"@appmockup/node-render": "workspace:*",
|
|
29
|
+
"commander": "^12.1.0"
|
|
30
|
+
},
|
|
31
|
+
"devDependencies": {
|
|
32
|
+
"@types/node": "^22.10.2",
|
|
33
|
+
"tsup": "^8.3.5",
|
|
34
|
+
"typescript": "^5.7.2"
|
|
35
|
+
}
|
|
36
|
+
}
|