create-asciitorium 0.1.5
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 +2 -0
- package/dist/index.js +77 -0
- package/dist/index.js.map +1 -0
- package/dist/scaffold.d.ts +16 -0
- package/dist/scaffold.js +103 -0
- package/dist/scaffold.js.map +1 -0
- package/dist/templates/base/index.css +26 -0
- package/dist/templates/base/index.html +13 -0
- package/dist/templates/base/main.tsx +33 -0
- package/dist/templates/base/package.json +21 -0
- package/dist/templates/base/src/main.tsx +67 -0
- package/dist/templates/base/src/vite-env.d.ts +1 -0
- package/dist/templates/base/tsconfig.json +16 -0
- package/dist/templates/base/vite-env.d.ts +1 -0
- package/dist/templates/base/vite.config.ts +10 -0
- package/package.json +40 -0
package/dist/index.d.ts
ADDED
package/dist/index.js
ADDED
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
// @ts-ignore
|
|
3
|
+
import path from 'node:path';
|
|
4
|
+
import fs from 'node:fs/promises';
|
|
5
|
+
import minimist from 'minimist';
|
|
6
|
+
import prompts from 'prompts';
|
|
7
|
+
import { green, cyan, yellow, dim, red } from 'kolorist';
|
|
8
|
+
import { scaffold } from './scaffold.js';
|
|
9
|
+
async function main() {
|
|
10
|
+
const argv = minimist(process.argv.slice(2), {
|
|
11
|
+
string: ['template', 'pm'],
|
|
12
|
+
boolean: ['git', 'install'],
|
|
13
|
+
default: { git: true, install: true },
|
|
14
|
+
});
|
|
15
|
+
let target = argv._[0];
|
|
16
|
+
if (!target) {
|
|
17
|
+
const res = await prompts({
|
|
18
|
+
type: 'text',
|
|
19
|
+
name: 'name',
|
|
20
|
+
message: 'Project name:',
|
|
21
|
+
initial: 'my-asciitorium-app',
|
|
22
|
+
});
|
|
23
|
+
target = res.name;
|
|
24
|
+
}
|
|
25
|
+
if (!target) {
|
|
26
|
+
console.log(red('✖') + ' No project name provided. Aborting.');
|
|
27
|
+
process.exit(1);
|
|
28
|
+
}
|
|
29
|
+
const projectDir = path.resolve(process.cwd(), target);
|
|
30
|
+
try {
|
|
31
|
+
await fs.mkdir(projectDir, { recursive: false });
|
|
32
|
+
}
|
|
33
|
+
catch {
|
|
34
|
+
console.log(red(`✖ Directory "${target}" already exists.`));
|
|
35
|
+
process.exit(1);
|
|
36
|
+
}
|
|
37
|
+
const pm = argv.pm ?? process.env.npm_config_user_agent?.split('/')[0] ?? 'pnpm';
|
|
38
|
+
const template = argv.template ?? 'base';
|
|
39
|
+
const useGit = Boolean(argv.git);
|
|
40
|
+
const doInstall = Boolean(argv.install);
|
|
41
|
+
console.log(`${green('✔')} Creating ${cyan(target)} with template ${yellow(template)}…`);
|
|
42
|
+
await scaffold({ projectDir, template });
|
|
43
|
+
if (useGit) {
|
|
44
|
+
try {
|
|
45
|
+
const { execa } = await import('execa');
|
|
46
|
+
await execa('git', ['init'], { cwd: projectDir });
|
|
47
|
+
await execa('git', ['add', '-A'], { cwd: projectDir });
|
|
48
|
+
await execa('git', ['commit', '-m', 'chore: init asciitorium app'], {
|
|
49
|
+
cwd: projectDir,
|
|
50
|
+
});
|
|
51
|
+
console.log(green('✔ ') + 'Initialized git repository.');
|
|
52
|
+
}
|
|
53
|
+
catch {
|
|
54
|
+
console.log(dim('…skipping git init (git not found)'));
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
if (doInstall) {
|
|
58
|
+
try {
|
|
59
|
+
const { execa } = await import('execa');
|
|
60
|
+
const installCmd = pm === 'yarn' ? 'install' : 'i';
|
|
61
|
+
await execa(pm, [installCmd], { cwd: projectDir, stdio: 'inherit' });
|
|
62
|
+
}
|
|
63
|
+
catch {
|
|
64
|
+
console.log(dim(`…skipping install (unable to run ${pm})`));
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
const runDev = pm === 'npm' ? 'npm run dev' : `${pm} dev`;
|
|
68
|
+
console.log(`\n${green('Done!')} Next steps:\n`);
|
|
69
|
+
console.log(` cd ${target}`);
|
|
70
|
+
console.log(` ${runDev}\n`);
|
|
71
|
+
console.log(dim('Web dev server on http://localhost:5173 , CLI: `node dist/main.cjs` after build.'));
|
|
72
|
+
}
|
|
73
|
+
main().catch((e) => {
|
|
74
|
+
console.error(e);
|
|
75
|
+
process.exit(1);
|
|
76
|
+
});
|
|
77
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AACA,aAAa;AACb,OAAO,IAAI,MAAM,WAAW,CAAC;AAC7B,OAAO,EAAE,MAAM,kBAAkB,CAAC;AAClC,OAAO,QAAQ,MAAM,UAAU,CAAC;AAChC,OAAO,OAAO,MAAM,SAAS,CAAC;AAC9B,OAAO,EAAE,KAAK,EAAE,IAAI,EAAE,MAAM,EAAE,GAAG,EAAE,GAAG,EAAE,MAAM,UAAU,CAAC;AACzD,OAAO,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC;AAEzC,KAAK,UAAU,IAAI;IACjB,MAAM,IAAI,GAAG,QAAQ,CAAC,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE;QAC3C,MAAM,EAAE,CAAC,UAAU,EAAE,IAAI,CAAC;QAC1B,OAAO,EAAE,CAAC,KAAK,EAAE,SAAS,CAAC;QAC3B,OAAO,EAAE,EAAE,GAAG,EAAE,IAAI,EAAE,OAAO,EAAE,IAAI,EAAE;KACtC,CAAC,CAAC;IAEH,IAAI,MAAM,GAAG,IAAI,CAAC,CAAC,CAAC,CAAC,CAAuB,CAAC;IAC7C,IAAI,CAAC,MAAM,EAAE,CAAC;QACZ,MAAM,GAAG,GAAG,MAAM,OAAO,CAAC;YACxB,IAAI,EAAE,MAAM;YACZ,IAAI,EAAE,MAAM;YACZ,OAAO,EAAE,eAAe;YACxB,OAAO,EAAE,oBAAoB;SAC9B,CAAC,CAAC;QACH,MAAM,GAAG,GAAG,CAAC,IAAI,CAAC;IACpB,CAAC;IACD,IAAI,CAAC,MAAM,EAAE,CAAC;QACZ,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,sCAAsC,CAAC,CAAC;QAC/D,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;IAED,MAAM,UAAU,GAAG,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,GAAG,EAAE,EAAE,MAAM,CAAC,CAAC;IACvD,IAAI,CAAC;QACH,MAAM,EAAE,CAAC,KAAK,CAAC,UAAU,EAAE,EAAE,SAAS,EAAE,KAAK,EAAE,CAAC,CAAC;IACnD,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,gBAAgB,MAAM,mBAAmB,CAAC,CAAC,CAAC;QAC5D,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;IAED,MAAM,EAAE,GACN,IAAI,CAAC,EAAE,IAAI,OAAO,CAAC,GAAG,CAAC,qBAAqB,EAAE,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,MAAM,CAAC;IACxE,MAAM,QAAQ,GAAG,IAAI,CAAC,QAAQ,IAAI,MAAM,CAAC;IACzC,MAAM,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;IACjC,MAAM,SAAS,GAAG,OAAO,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;IAExC,OAAO,CAAC,GAAG,CACT,GAAG,KAAK,CAAC,GAAG,CAAC,aAAa,IAAI,CAAC,MAAM,CAAC,kBAAkB,MAAM,CAAC,QAAQ,CAAC,GAAG,CAC5E,CAAC;IAEF,MAAM,QAAQ,CAAC,EAAE,UAAU,EAAE,QAAQ,EAAE,CAAC,CAAC;IAEzC,IAAI,MAAM,EAAE,CAAC;QACX,IAAI,CAAC;YACH,MAAM,EAAE,KAAK,EAAE,GAAG,MAAM,MAAM,CAAC,OAAO,CAAC,CAAC;YACxC,MAAM,KAAK,CAAC,KAAK,EAAE,CAAC,MAAM,CAAC,EAAE,EAAE,GAAG,EAAE,UAAU,EAAE,CAAC,CAAC;YAClD,MAAM,KAAK,CAAC,KAAK,EAAE,CAAC,KAAK,EAAE,IAAI,CAAC,EAAE,EAAE,GAAG,EAAE,UAAU,EAAE,CAAC,CAAC;YACvD,MAAM,KAAK,CAAC,KAAK,EAAE,CAAC,QAAQ,EAAE,IAAI,EAAE,6BAA6B,CAAC,EAAE;gBAClE,GAAG,EAAE,UAAU;aAChB,CAAC,CAAC;YACH,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,GAAG,6BAA6B,CAAC,CAAC;QAC3D,CAAC;QAAC,MAAM,CAAC;YACP,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,oCAAoC,CAAC,CAAC,CAAC;QACzD,CAAC;IACH,CAAC;IAED,IAAI,SAAS,EAAE,CAAC;QACd,IAAI,CAAC;YACH,MAAM,EAAE,KAAK,EAAE,GAAG,MAAM,MAAM,CAAC,OAAO,CAAC,CAAC;YACxC,MAAM,UAAU,GAAG,EAAE,KAAK,MAAM,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,GAAG,CAAC;YACnD,MAAM,KAAK,CAAC,EAAE,EAAE,CAAC,UAAU,CAAC,EAAE,EAAE,GAAG,EAAE,UAAU,EAAE,KAAK,EAAE,SAAS,EAAE,CAAC,CAAC;QACvE,CAAC;QAAC,MAAM,CAAC;YACP,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,oCAAoC,EAAE,GAAG,CAAC,CAAC,CAAC;QAC9D,CAAC;IACH,CAAC;IAED,MAAM,MAAM,GAAG,EAAE,KAAK,KAAK,CAAC,CAAC,CAAC,aAAa,CAAC,CAAC,CAAC,GAAG,EAAE,MAAM,CAAC;IAC1D,OAAO,CAAC,GAAG,CAAC,KAAK,KAAK,CAAC,OAAO,CAAC,gBAAgB,CAAC,CAAC;IACjD,OAAO,CAAC,GAAG,CAAC,QAAQ,MAAM,EAAE,CAAC,CAAC;IAC9B,OAAO,CAAC,GAAG,CAAC,KAAK,MAAM,IAAI,CAAC,CAAC;IAC7B,OAAO,CAAC,GAAG,CACT,GAAG,CACD,kFAAkF,CACnF,CACF,CAAC;AACJ,CAAC;AAED,IAAI,EAAE,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,EAAE;IACjB,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;IACjB,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AAClB,CAAC,CAAC,CAAC"}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
export interface ScaffoldOptions {
|
|
2
|
+
projectDir: string;
|
|
3
|
+
template: string;
|
|
4
|
+
install?: boolean;
|
|
5
|
+
initGit?: boolean;
|
|
6
|
+
packageManager?: 'pnpm' | 'npm' | 'yarn';
|
|
7
|
+
}
|
|
8
|
+
/**
|
|
9
|
+
* High-level scaffold:
|
|
10
|
+
* 1) Copy template into projectDir
|
|
11
|
+
* 2) Move _gitignore -> .gitignore
|
|
12
|
+
* 3) Pin latest published asciitorium version in package.json
|
|
13
|
+
* 4) Optionally run install
|
|
14
|
+
* 5) Optionally init git
|
|
15
|
+
*/
|
|
16
|
+
export declare function scaffold(opts: ScaffoldOptions): Promise<void>;
|
package/dist/scaffold.js
ADDED
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
// packages/create-asciitorium/src/scaffold.ts
|
|
2
|
+
import path from 'node:path';
|
|
3
|
+
import fs from 'node:fs/promises';
|
|
4
|
+
import { fileURLToPath } from 'node:url';
|
|
5
|
+
import { execa } from 'execa';
|
|
6
|
+
const __dirname = path.dirname(fileURLToPath(import.meta.url));
|
|
7
|
+
/**
|
|
8
|
+
* High-level scaffold:
|
|
9
|
+
* 1) Copy template into projectDir
|
|
10
|
+
* 2) Move _gitignore -> .gitignore
|
|
11
|
+
* 3) Pin latest published asciitorium version in package.json
|
|
12
|
+
* 4) Optionally run install
|
|
13
|
+
* 5) Optionally init git
|
|
14
|
+
*/
|
|
15
|
+
export async function scaffold(opts) {
|
|
16
|
+
const { projectDir, template, install = true, initGit = true, packageManager = 'pnpm', } = opts;
|
|
17
|
+
const templateDir = path.join(__dirname, 'templates', template);
|
|
18
|
+
// 1) Copy all template files
|
|
19
|
+
await copyDir(templateDir, projectDir);
|
|
20
|
+
// 2) Rename _gitignore if present
|
|
21
|
+
await renameGitignore(projectDir);
|
|
22
|
+
// 3) Pin latest asciitorium into the generated package.json
|
|
23
|
+
await pinLatestAsciitorium(projectDir);
|
|
24
|
+
// 4) Install dependencies (default: pnpm)
|
|
25
|
+
if (install) {
|
|
26
|
+
await runInstall(projectDir, packageManager);
|
|
27
|
+
}
|
|
28
|
+
// 5) Initialize git (if not already inside a repo)
|
|
29
|
+
if (initGit) {
|
|
30
|
+
await initGitRepo(projectDir);
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
/* ----------------- Helpers ----------------- */
|
|
34
|
+
async function copyDir(src, dest) {
|
|
35
|
+
await fs.mkdir(dest, { recursive: true });
|
|
36
|
+
const entries = await fs.readdir(src, { withFileTypes: true });
|
|
37
|
+
for (const e of entries) {
|
|
38
|
+
const s = path.join(src, e.name);
|
|
39
|
+
const d = path.join(dest, e.name);
|
|
40
|
+
if (e.isDirectory()) {
|
|
41
|
+
await copyDir(s, d);
|
|
42
|
+
}
|
|
43
|
+
else {
|
|
44
|
+
await fs.copyFile(s, d);
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
async function renameGitignore(projectDir) {
|
|
49
|
+
const from = path.join(projectDir, '_gitignore');
|
|
50
|
+
const to = path.join(projectDir, '.gitignore');
|
|
51
|
+
try {
|
|
52
|
+
await fs.rename(from, to);
|
|
53
|
+
}
|
|
54
|
+
catch {
|
|
55
|
+
// ignore if not present
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
async function pinLatestAsciitorium(appDir) {
|
|
59
|
+
const pkgPath = path.join(appDir, 'package.json');
|
|
60
|
+
let pkg;
|
|
61
|
+
try {
|
|
62
|
+
const raw = await fs.readFile(pkgPath, 'utf8');
|
|
63
|
+
pkg = JSON.parse(raw);
|
|
64
|
+
}
|
|
65
|
+
catch (err) {
|
|
66
|
+
throw new Error(`package.json not found or unreadable at ${pkgPath}. Did the template include it?`);
|
|
67
|
+
}
|
|
68
|
+
// Fetch the latest published version from the registry
|
|
69
|
+
const { stdout } = await execa('pnpm', ['view', 'asciitorium', 'version']);
|
|
70
|
+
const latest = stdout.trim();
|
|
71
|
+
if (!pkg.dependencies)
|
|
72
|
+
pkg.dependencies = {};
|
|
73
|
+
pkg.dependencies['asciitorium'] = `^${latest}`;
|
|
74
|
+
await fs.writeFile(pkgPath, JSON.stringify(pkg, null, 2) + '\n', 'utf8');
|
|
75
|
+
}
|
|
76
|
+
async function runInstall(appDir, pm) {
|
|
77
|
+
const cmd = pm === 'pnpm' ? ['install'] : pm === 'npm' ? ['install'] : ['install']; // yarn
|
|
78
|
+
try {
|
|
79
|
+
await execa(pm, cmd, { cwd: appDir, stdio: 'inherit' });
|
|
80
|
+
}
|
|
81
|
+
catch (err) {
|
|
82
|
+
throw new Error(`Dependency install failed with ${pm}. You can retry manually in ${appDir}.`);
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
async function initGitRepo(appDir) {
|
|
86
|
+
// Quick check: if .git exists, skip
|
|
87
|
+
try {
|
|
88
|
+
await fs.stat(path.join(appDir, '.git'));
|
|
89
|
+
return;
|
|
90
|
+
}
|
|
91
|
+
catch {
|
|
92
|
+
// not a git repo yet
|
|
93
|
+
}
|
|
94
|
+
try {
|
|
95
|
+
await execa('git', ['init'], { cwd: appDir, stdio: 'ignore' });
|
|
96
|
+
await execa('git', ['add', '-A'], { cwd: appDir, stdio: 'ignore' });
|
|
97
|
+
await execa('git', ['commit', '-m', 'chore: scaffold project with create-asciitorium'], { cwd: appDir, stdio: 'ignore' });
|
|
98
|
+
}
|
|
99
|
+
catch {
|
|
100
|
+
// If git isn't available or commit fails, it's non-fatal — just continue
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
//# sourceMappingURL=scaffold.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"scaffold.js","sourceRoot":"","sources":["../src/scaffold.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
@font-face {
|
|
2
|
+
font-family: 'PrintChar21';
|
|
3
|
+
src:
|
|
4
|
+
url('/fonts/PrintChar21.woff2') format('woff2'),
|
|
5
|
+
url('/fonts/PrintChar21.woff') format('woff'),
|
|
6
|
+
url('/fonts/PrintChar21.ttf') format('truetype');
|
|
7
|
+
font-weight: normal;
|
|
8
|
+
font-style: normal;
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
body {
|
|
12
|
+
font-family: 'Courier New', Courier, monospace;
|
|
13
|
+
margin: 10;
|
|
14
|
+
background: black;
|
|
15
|
+
color: #3fff00;
|
|
16
|
+
|
|
17
|
+
/* Center the screen horizontally */
|
|
18
|
+
display: flex;
|
|
19
|
+
justify-content: center;
|
|
20
|
+
height: 100vh; /* Full viewport height */
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
.inverted {
|
|
24
|
+
background-color: #3fff00;
|
|
25
|
+
color: black;
|
|
26
|
+
}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
<!doctype html>
|
|
2
|
+
<html lang="en">
|
|
3
|
+
<head>
|
|
4
|
+
<meta charset="UTF-8" />
|
|
5
|
+
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
|
6
|
+
<title>asciitorium app</title>
|
|
7
|
+
<link rel="stylesheet" href="index.css" />
|
|
8
|
+
</head>
|
|
9
|
+
<body>
|
|
10
|
+
<div id="screen"></div>
|
|
11
|
+
<script type="module" src="src/main.tsx"></script>
|
|
12
|
+
</body>
|
|
13
|
+
</html>
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
/** Single entry that runs on Web (DOM) and CLI (Terminal) */
|
|
2
|
+
import {
|
|
3
|
+
Asciitorium,
|
|
4
|
+
Text,
|
|
5
|
+
HorizontalLine,
|
|
6
|
+
ProgressBar,
|
|
7
|
+
State,
|
|
8
|
+
bootstrap,
|
|
9
|
+
} from 'asciitorium';
|
|
10
|
+
|
|
11
|
+
// --- Simple stateful demo ---
|
|
12
|
+
const message = new State('Hello asciitorium!');
|
|
13
|
+
const loading = new State(0);
|
|
14
|
+
|
|
15
|
+
const app = (
|
|
16
|
+
<Asciitorium width={64} height={24} padding={1}>
|
|
17
|
+
<Text text="asciitorium starter" />
|
|
18
|
+
<HorizontalLine />
|
|
19
|
+
<Text text={message} />
|
|
20
|
+
<ProgressBar value={loading} width={40} />
|
|
21
|
+
</Asciitorium>
|
|
22
|
+
);
|
|
23
|
+
|
|
24
|
+
// Auto-detect renderer inside bootstrap(): DOM in browser, Terminal in Node
|
|
25
|
+
bootstrap(app);
|
|
26
|
+
|
|
27
|
+
// Tiny fake loader so something moves
|
|
28
|
+
let t = 0;
|
|
29
|
+
setInterval(() => {
|
|
30
|
+
t = (t + 1) % 101;
|
|
31
|
+
loading.value = t;
|
|
32
|
+
if (t === 100) message.value = 'Loaded!';
|
|
33
|
+
}, 60);
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "my-asciitorium-app",
|
|
3
|
+
"version": "0.0.0",
|
|
4
|
+
"private": true,
|
|
5
|
+
"type": "module",
|
|
6
|
+
"scripts": {
|
|
7
|
+
"web": "vite",
|
|
8
|
+
"build": "vite build",
|
|
9
|
+
"preview": "vite preview",
|
|
10
|
+
"cli": "tsx src/main.tsx"
|
|
11
|
+
},
|
|
12
|
+
"devDependencies": {
|
|
13
|
+
"typescript": "^5.5.4",
|
|
14
|
+
"vite": "^5.4.0",
|
|
15
|
+
"tslib": "^2.6.3",
|
|
16
|
+
"tsx": "^4.19.0"
|
|
17
|
+
},
|
|
18
|
+
"dependencies": {
|
|
19
|
+
"asciitorium": "^0.1.6"
|
|
20
|
+
}
|
|
21
|
+
}
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
/** Single entry that runs on Web (DOM) and CLI (Terminal) */
|
|
2
|
+
import {
|
|
3
|
+
Text,
|
|
4
|
+
State,
|
|
5
|
+
AsciiArt,
|
|
6
|
+
TextInput,
|
|
7
|
+
Asciitorium,
|
|
8
|
+
ProgressBar,
|
|
9
|
+
CelticBorder,
|
|
10
|
+
HorizontalLine,
|
|
11
|
+
HorizontalLayout,
|
|
12
|
+
loadAsciiAsset,
|
|
13
|
+
bootstrap,
|
|
14
|
+
} from 'asciitorium';
|
|
15
|
+
|
|
16
|
+
const appWidth = 64;
|
|
17
|
+
const appHeight = 26;
|
|
18
|
+
|
|
19
|
+
const loading = new State(0);
|
|
20
|
+
const helloWorld = new State('Hello, World!');
|
|
21
|
+
|
|
22
|
+
// Load the title ASCII art
|
|
23
|
+
const titleArt = await loadAsciiAsset('./art/asciitorium.txt');
|
|
24
|
+
|
|
25
|
+
// Construct the app
|
|
26
|
+
const app = (
|
|
27
|
+
<Asciitorium width={appWidth} height={appHeight}>
|
|
28
|
+
<CelticBorder corner="topLeft" fixed x={0} y={0} />
|
|
29
|
+
<CelticBorder corner="topRight" fixed x={appWidth - 8} y={0} />
|
|
30
|
+
<CelticBorder corner="bottomLeft" fixed x={0} y={appHeight - 8} />
|
|
31
|
+
<CelticBorder
|
|
32
|
+
corner="bottomRight"
|
|
33
|
+
fixed
|
|
34
|
+
x={appWidth - 8}
|
|
35
|
+
y={appHeight - 8}
|
|
36
|
+
/>
|
|
37
|
+
|
|
38
|
+
<Text value="" align="center" height={2} comment="vertical spacing" />
|
|
39
|
+
<AsciiArt content={titleArt} align="center" />
|
|
40
|
+
<HorizontalLine length={36} align="center" />
|
|
41
|
+
<Text value="a ui framework for cli and web" align="top" height={5} />
|
|
42
|
+
|
|
43
|
+
<HorizontalLayout width={appWidth - 22} height={3} align="center">
|
|
44
|
+
<Text value="Text Input:" align="center" />
|
|
45
|
+
<TextInput width={30} value={helloWorld} />
|
|
46
|
+
</HorizontalLayout>
|
|
47
|
+
|
|
48
|
+
<Text value={helloWorld} width={appWidth - 24} align="center" height={4} />
|
|
49
|
+
|
|
50
|
+
<HorizontalLayout width={appWidth - 24} height={4} align="center">
|
|
51
|
+
<Text value="loading:" align="center" />
|
|
52
|
+
<ProgressBar width={30} percent={loading} align="center" showPercentage />
|
|
53
|
+
</HorizontalLayout>
|
|
54
|
+
</Asciitorium>
|
|
55
|
+
);
|
|
56
|
+
|
|
57
|
+
await bootstrap(app);
|
|
58
|
+
|
|
59
|
+
// --- Demo: Set progress to a random value every 10s ---
|
|
60
|
+
const randInt = (min: number, max: number) =>
|
|
61
|
+
Math.floor(Math.random() * (max - min + 1)) + min;
|
|
62
|
+
|
|
63
|
+
setInterval(() => {
|
|
64
|
+
const newLoadingvalue = randInt(0, 100);
|
|
65
|
+
console.log(`Loading... ${newLoadingvalue}%`);
|
|
66
|
+
loading.value = newLoadingvalue;
|
|
67
|
+
}, 5_000);
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
/// <reference types="vite/client" />
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
{
|
|
2
|
+
"compilerOptions": {
|
|
3
|
+
"target": "ES2020",
|
|
4
|
+
"lib": ["ES2020", "DOM"],
|
|
5
|
+
"module": "esnext",
|
|
6
|
+
"moduleResolution": "bundler",
|
|
7
|
+
"resolveJsonModule": true,
|
|
8
|
+
"strict": true,
|
|
9
|
+
"jsx": "react-jsx",
|
|
10
|
+
"jsxImportSource": "asciitorium",
|
|
11
|
+
"outDir": "dist",
|
|
12
|
+
"noEmit": true,
|
|
13
|
+
"types": ["vite/client"]
|
|
14
|
+
},
|
|
15
|
+
"include": ["src"]
|
|
16
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
/// <reference types="vite/client" />
|
package/package.json
ADDED
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "create-asciitorium",
|
|
3
|
+
"version": "0.1.5",
|
|
4
|
+
"description": "Scaffold a Vite + TypeScript project prewired for asciitorium (web + cli).",
|
|
5
|
+
"bin": {
|
|
6
|
+
"create-asciitorium": "dist/index.js"
|
|
7
|
+
},
|
|
8
|
+
"type": "module",
|
|
9
|
+
"license": "MIT",
|
|
10
|
+
"files": [
|
|
11
|
+
"dist",
|
|
12
|
+
"README.md",
|
|
13
|
+
"LICENSE"
|
|
14
|
+
],
|
|
15
|
+
"dependencies": {
|
|
16
|
+
"asciitorium": "__ASCIITORIUM_VERSION__",
|
|
17
|
+
"execa": "^9.3.0",
|
|
18
|
+
"kolorist": "^1.8.0",
|
|
19
|
+
"minimist": "^1.2.8",
|
|
20
|
+
"prompts": "^2.4.2"
|
|
21
|
+
},
|
|
22
|
+
"devDependencies": {
|
|
23
|
+
"@types/minimist": "^1.2.5",
|
|
24
|
+
"@types/node": "^24.0.12",
|
|
25
|
+
"@types/prompts": "^2.4.9",
|
|
26
|
+
"tsx": "^4.19.0",
|
|
27
|
+
"typescript": "^5.5.4"
|
|
28
|
+
},
|
|
29
|
+
"engines": {
|
|
30
|
+
"node": ">=18.0.0"
|
|
31
|
+
},
|
|
32
|
+
"publishConfig": {
|
|
33
|
+
"access": "public"
|
|
34
|
+
},
|
|
35
|
+
"scripts": {
|
|
36
|
+
"build": "tsc -p tsconfig.json",
|
|
37
|
+
"postbuild": "cp -r templates dist/",
|
|
38
|
+
"dev": "tsx watch src/index.ts"
|
|
39
|
+
}
|
|
40
|
+
}
|