create-macroscope 0.0.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 +10 -0
- package/dist/index.d.ts +15 -0
- package/dist/index.js +101 -0
- package/dist/index.js.map +1 -0
- package/package.json +33 -0
- package/templates/default/.macroscope/config.yaml +8 -0
- package/templates/default/README.md +10 -0
- package/templates/default/blocks/sample/README.md +5 -0
- package/templates/default/blocks/sample/macroscope.yaml +7 -0
- package/templates/default/package.json +12 -0
package/README.md
ADDED
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
interface ScaffoldOptions {
|
|
3
|
+
target: string;
|
|
4
|
+
template: string;
|
|
5
|
+
force: boolean;
|
|
6
|
+
json: boolean;
|
|
7
|
+
}
|
|
8
|
+
declare function scaffold(opts: ScaffoldOptions): Promise<{
|
|
9
|
+
ok: boolean;
|
|
10
|
+
target: string;
|
|
11
|
+
files: string[];
|
|
12
|
+
}>;
|
|
13
|
+
declare function main(argv?: string[]): Promise<void>;
|
|
14
|
+
|
|
15
|
+
export { main, scaffold };
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
// src/index.ts
|
|
4
|
+
import { existsSync, realpathSync } from "fs";
|
|
5
|
+
import { cp, mkdir } from "fs/promises";
|
|
6
|
+
import { dirname, join, resolve } from "path";
|
|
7
|
+
import { fileURLToPath } from "url";
|
|
8
|
+
import { Command } from "commander";
|
|
9
|
+
var here = dirname(fileURLToPath(import.meta.url));
|
|
10
|
+
var TEMPLATES_DIR = resolve(here, "..", "templates");
|
|
11
|
+
async function scaffold(opts) {
|
|
12
|
+
const target = resolve(opts.target);
|
|
13
|
+
const templateDir = join(TEMPLATES_DIR, opts.template);
|
|
14
|
+
if (!existsSync(templateDir)) {
|
|
15
|
+
throw new Error(`Template not found: ${opts.template} (looked in ${templateDir})`);
|
|
16
|
+
}
|
|
17
|
+
if (existsSync(target) && !opts.force) {
|
|
18
|
+
if (existsSync(join(target, ".macroscope"))) {
|
|
19
|
+
throw new Error(
|
|
20
|
+
`Target already contains a .macroscope directory: ${target}. Pass --force to overwrite.`
|
|
21
|
+
);
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
await mkdir(target, { recursive: true });
|
|
25
|
+
await cp(templateDir, target, { recursive: true, force: opts.force });
|
|
26
|
+
const files = await listFilesRecursive(target);
|
|
27
|
+
return { ok: true, target, files };
|
|
28
|
+
}
|
|
29
|
+
async function listFilesRecursive(dir) {
|
|
30
|
+
const { readdir, stat } = await import("fs/promises");
|
|
31
|
+
const out = [];
|
|
32
|
+
async function walk(d, prefix) {
|
|
33
|
+
const entries = await readdir(d);
|
|
34
|
+
for (const entry of entries) {
|
|
35
|
+
const full = join(d, entry);
|
|
36
|
+
const rel = prefix ? `${prefix}/${entry}` : entry;
|
|
37
|
+
const s = await stat(full);
|
|
38
|
+
if (s.isDirectory()) {
|
|
39
|
+
await walk(full, rel);
|
|
40
|
+
} else {
|
|
41
|
+
out.push(rel);
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
await walk(dir, "");
|
|
46
|
+
return out.sort();
|
|
47
|
+
}
|
|
48
|
+
async function main(argv = process.argv) {
|
|
49
|
+
const program = new Command();
|
|
50
|
+
program.name("create-macroscope").description("Scaffold a macroscope-enabled project").argument("[target]", "target directory (defaults to current dir)", ".").option("-t, --template <name>", "template to use", "default").option("-f, --force", "overwrite existing files", false).option("--json", "output machine-readable JSON", false).action(async (target, opts) => {
|
|
51
|
+
try {
|
|
52
|
+
const result = await scaffold({
|
|
53
|
+
target,
|
|
54
|
+
template: opts.template,
|
|
55
|
+
force: opts.force,
|
|
56
|
+
json: opts.json
|
|
57
|
+
});
|
|
58
|
+
if (opts.json) {
|
|
59
|
+
process.stdout.write(`${JSON.stringify(result)}
|
|
60
|
+
`);
|
|
61
|
+
} else {
|
|
62
|
+
process.stdout.write(`Scaffolded macroscope project at ${result.target}
|
|
63
|
+
`);
|
|
64
|
+
process.stdout.write(` ${result.files.length} files created
|
|
65
|
+
`);
|
|
66
|
+
process.stdout.write(
|
|
67
|
+
`Next: cd ${result.target} && npm install && npm run macroscope ui
|
|
68
|
+
`
|
|
69
|
+
);
|
|
70
|
+
}
|
|
71
|
+
} catch (err) {
|
|
72
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
73
|
+
if (opts.json) {
|
|
74
|
+
process.stderr.write(`${JSON.stringify({ ok: false, error: msg })}
|
|
75
|
+
`);
|
|
76
|
+
} else {
|
|
77
|
+
process.stderr.write(`create-macroscope: ${msg}
|
|
78
|
+
`);
|
|
79
|
+
}
|
|
80
|
+
process.exit(1);
|
|
81
|
+
}
|
|
82
|
+
});
|
|
83
|
+
await program.parseAsync(argv);
|
|
84
|
+
}
|
|
85
|
+
var invokedDirectly = (() => {
|
|
86
|
+
const entry = process.argv[1];
|
|
87
|
+
if (!entry) return false;
|
|
88
|
+
try {
|
|
89
|
+
return realpathSync(entry) === fileURLToPath(import.meta.url);
|
|
90
|
+
} catch {
|
|
91
|
+
return false;
|
|
92
|
+
}
|
|
93
|
+
})();
|
|
94
|
+
if (invokedDirectly) {
|
|
95
|
+
main();
|
|
96
|
+
}
|
|
97
|
+
export {
|
|
98
|
+
main,
|
|
99
|
+
scaffold
|
|
100
|
+
};
|
|
101
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/index.ts"],"sourcesContent":["#!/usr/bin/env node\nimport { existsSync, realpathSync } from 'node:fs';\nimport { cp, mkdir, readFile, writeFile } from 'node:fs/promises';\nimport { dirname, join, resolve } from 'node:path';\nimport { fileURLToPath } from 'node:url';\nimport { Command } from 'commander';\n\nconst here = dirname(fileURLToPath(import.meta.url));\nconst TEMPLATES_DIR = resolve(here, '..', 'templates');\n\ninterface ScaffoldOptions {\n target: string;\n template: string;\n force: boolean;\n json: boolean;\n}\n\nexport async function scaffold(\n opts: ScaffoldOptions,\n): Promise<{ ok: boolean; target: string; files: string[] }> {\n const target = resolve(opts.target);\n const templateDir = join(TEMPLATES_DIR, opts.template);\n\n if (!existsSync(templateDir)) {\n throw new Error(`Template not found: ${opts.template} (looked in ${templateDir})`);\n }\n\n if (existsSync(target) && !opts.force) {\n if (existsSync(join(target, '.macroscope'))) {\n throw new Error(\n `Target already contains a .macroscope directory: ${target}. Pass --force to overwrite.`,\n );\n }\n }\n\n await mkdir(target, { recursive: true });\n await cp(templateDir, target, { recursive: true, force: opts.force });\n\n // Discover what was copied so tests + JSON output can assert it.\n const files = await listFilesRecursive(target);\n return { ok: true, target, files };\n}\n\nasync function listFilesRecursive(dir: string): Promise<string[]> {\n const { readdir, stat } = await import('node:fs/promises');\n const out: string[] = [];\n async function walk(d: string, prefix: string): Promise<void> {\n const entries = await readdir(d);\n for (const entry of entries) {\n const full = join(d, entry);\n const rel = prefix ? `${prefix}/${entry}` : entry;\n const s = await stat(full);\n if (s.isDirectory()) {\n await walk(full, rel);\n } else {\n out.push(rel);\n }\n }\n }\n await walk(dir, '');\n return out.sort();\n}\n\nexport async function main(argv: string[] = process.argv): Promise<void> {\n const program = new Command();\n\n program\n .name('create-macroscope')\n .description('Scaffold a macroscope-enabled project')\n .argument('[target]', 'target directory (defaults to current dir)', '.')\n .option('-t, --template <name>', 'template to use', 'default')\n .option('-f, --force', 'overwrite existing files', false)\n .option('--json', 'output machine-readable JSON', false)\n .action(async (target: string, opts: { template: string; force: boolean; json: boolean }) => {\n try {\n const result = await scaffold({\n target,\n template: opts.template,\n force: opts.force,\n json: opts.json,\n });\n if (opts.json) {\n process.stdout.write(`${JSON.stringify(result)}\\n`);\n } else {\n process.stdout.write(`Scaffolded macroscope project at ${result.target}\\n`);\n process.stdout.write(` ${result.files.length} files created\\n`);\n process.stdout.write(\n `Next: cd ${result.target} && npm install && npm run macroscope ui\\n`,\n );\n }\n } catch (err) {\n const msg = err instanceof Error ? err.message : String(err);\n if (opts.json) {\n process.stderr.write(`${JSON.stringify({ ok: false, error: msg })}\\n`);\n } else {\n process.stderr.write(`create-macroscope: ${msg}\\n`);\n }\n process.exit(1);\n }\n });\n\n await program.parseAsync(argv);\n}\n\nconst invokedDirectly = (() => {\n const entry = process.argv[1];\n if (!entry) return false;\n try {\n return realpathSync(entry) === fileURLToPath(import.meta.url);\n } catch {\n return false;\n }\n})();\n\nif (invokedDirectly) {\n main();\n}\n"],"mappings":"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","names":[]}
|
package/package.json
ADDED
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "create-macroscope",
|
|
3
|
+
"version": "0.0.0",
|
|
4
|
+
"publishConfig": {
|
|
5
|
+
"access": "public",
|
|
6
|
+
"provenance": true
|
|
7
|
+
},
|
|
8
|
+
"description": "Scaffold a macroscope-enabled project (run via `npm create macroscope`)",
|
|
9
|
+
"license": "MIT",
|
|
10
|
+
"type": "module",
|
|
11
|
+
"engines": {
|
|
12
|
+
"node": ">=20"
|
|
13
|
+
},
|
|
14
|
+
"bin": {
|
|
15
|
+
"create-macroscope": "dist/index.js"
|
|
16
|
+
},
|
|
17
|
+
"files": ["dist", "templates", "README.md"],
|
|
18
|
+
"scripts": {
|
|
19
|
+
"build": "tsup",
|
|
20
|
+
"dev": "tsup --watch",
|
|
21
|
+
"test": "vitest run",
|
|
22
|
+
"typecheck": "tsc --noEmit"
|
|
23
|
+
},
|
|
24
|
+
"dependencies": {
|
|
25
|
+
"commander": "^12.1.0"
|
|
26
|
+
},
|
|
27
|
+
"devDependencies": {
|
|
28
|
+
"@types/node": "^22.7.0",
|
|
29
|
+
"tsup": "^8.3.0",
|
|
30
|
+
"typescript": "^5.6.0",
|
|
31
|
+
"vitest": "^2.1.0"
|
|
32
|
+
}
|
|
33
|
+
}
|