create-olmo-front 0.1.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 +46 -0
- package/index.js +155 -0
- package/package.json +39 -0
package/README.md
ADDED
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
# create-olmo-front
|
|
2
|
+
|
|
3
|
+
Scaffold a new [Olmo](https://gitlab.com/olmocms) Next.js frontend from
|
|
4
|
+
[`olmo-front-template`](https://gitlab.com/olmocms/olmo-front-template), with
|
|
5
|
+
[`@olmocms/front`](https://www.npmjs.com/package/@olmocms/front) preinstalled.
|
|
6
|
+
|
|
7
|
+
## Usage
|
|
8
|
+
|
|
9
|
+
```bash
|
|
10
|
+
npx create-olmo-front my-site
|
|
11
|
+
# or
|
|
12
|
+
npm create olmo-front@latest my-site
|
|
13
|
+
```
|
|
14
|
+
|
|
15
|
+
Then:
|
|
16
|
+
|
|
17
|
+
```bash
|
|
18
|
+
cd my-site
|
|
19
|
+
# edit .env.local — set OLMO_TOKEN, OLMO_FORM_TOKEN, API URLs
|
|
20
|
+
npm run dev
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
## What it does
|
|
24
|
+
|
|
25
|
+
1. Downloads the template from the **public** GitLab repo (via `giget` — no auth needed).
|
|
26
|
+
2. Sets your project name in `package.json`.
|
|
27
|
+
3. Seeds a gitignored `.env.local` from `.env.example`.
|
|
28
|
+
Staging & production env vars belong in the **Vercel dashboard**, not the repo.
|
|
29
|
+
4. `git init` + first commit.
|
|
30
|
+
5. `npm install` (pulls `@olmocms/front` and the rest).
|
|
31
|
+
|
|
32
|
+
## Options
|
|
33
|
+
|
|
34
|
+
| Flag | Description |
|
|
35
|
+
| --- | --- |
|
|
36
|
+
| `--ref <branch\|tag>` | Template ref to fetch (default: `main`) |
|
|
37
|
+
| `--no-install` | Skip installing dependencies |
|
|
38
|
+
| `--no-git` | Skip git init + first commit |
|
|
39
|
+
| `-h`, `--help` | Show help |
|
|
40
|
+
|
|
41
|
+
## Releasing
|
|
42
|
+
|
|
43
|
+
The template repo is the single source of truth — this CLI just fetches it.
|
|
44
|
+
Pin a template tag for reproducible scaffolds by publishing a tag on
|
|
45
|
+
`olmo-front-template` and passing `--ref vX.Y.Z` (or bump `DEFAULT_REF` in
|
|
46
|
+
`index.js`).
|
package/index.js
ADDED
|
@@ -0,0 +1,155 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
// create-olmo-front — scaffold a new Olmo Next.js frontend from olmo-front-template.
|
|
3
|
+
//
|
|
4
|
+
// Usage:
|
|
5
|
+
// npx create-olmo-front my-site
|
|
6
|
+
// npm create olmo-front@latest my-site
|
|
7
|
+
//
|
|
8
|
+
// Flags:
|
|
9
|
+
// --ref <branch|tag> template ref to fetch (default: main)
|
|
10
|
+
// --no-install skip `npm install`
|
|
11
|
+
// --no-git skip `git init` + first commit
|
|
12
|
+
// -h, --help show help
|
|
13
|
+
|
|
14
|
+
import { existsSync, readdirSync, readFileSync, writeFileSync, copyFileSync } from 'node:fs';
|
|
15
|
+
import { basename, join, resolve } from 'node:path';
|
|
16
|
+
import { spawnSync } from 'node:child_process';
|
|
17
|
+
import { downloadTemplate } from 'giget';
|
|
18
|
+
import prompts from 'prompts';
|
|
19
|
+
import pc from 'picocolors';
|
|
20
|
+
|
|
21
|
+
// The template lives in a PUBLIC GitLab repo, so giget can fetch it with no auth.
|
|
22
|
+
const TEMPLATE = 'gitlab:olmocms/olmo-front-template';
|
|
23
|
+
const DEFAULT_REF = 'v0.1.0';
|
|
24
|
+
|
|
25
|
+
function parseArgs(argv) {
|
|
26
|
+
const opts = { dir: undefined, ref: DEFAULT_REF, install: true, git: true, help: false };
|
|
27
|
+
for (let i = 0; i < argv.length; i++) {
|
|
28
|
+
const a = argv[i];
|
|
29
|
+
if (a === '--help' || a === '-h') opts.help = true;
|
|
30
|
+
else if (a === '--no-install') opts.install = false;
|
|
31
|
+
else if (a === '--no-git') opts.git = false;
|
|
32
|
+
else if (a === '--ref') opts.ref = argv[++i];
|
|
33
|
+
else if (!a.startsWith('-') && opts.dir === undefined) opts.dir = a;
|
|
34
|
+
}
|
|
35
|
+
return opts;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
function printHelp() {
|
|
39
|
+
console.log(`
|
|
40
|
+
${pc.bold('create-olmo-front')} — scaffold an Olmo Next.js frontend
|
|
41
|
+
|
|
42
|
+
${pc.bold('Usage')}
|
|
43
|
+
${pc.cyan('npx create-olmo-front')} ${pc.green('<project-directory>')} [options]
|
|
44
|
+
|
|
45
|
+
${pc.bold('Options')}
|
|
46
|
+
--ref <branch|tag> template ref to fetch (default: ${DEFAULT_REF})
|
|
47
|
+
--no-install skip installing dependencies
|
|
48
|
+
--no-git skip git init + first commit
|
|
49
|
+
-h, --help show this help
|
|
50
|
+
`);
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
// Derive a valid npm "name" field from the target directory.
|
|
54
|
+
function toPackageName(name) {
|
|
55
|
+
return name
|
|
56
|
+
.toLowerCase()
|
|
57
|
+
.replace(/[^a-z0-9-~._]+/g, '-')
|
|
58
|
+
.replace(/^[-_.]+|[-_.]+$/g, '')
|
|
59
|
+
.slice(0, 214) || 'olmo-front-app';
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
function run(cmd, args, cwd) {
|
|
63
|
+
const r = spawnSync(cmd, args, { cwd, stdio: 'inherit', shell: process.platform === 'win32' });
|
|
64
|
+
return r.status === 0;
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
async function main() {
|
|
68
|
+
const opts = parseArgs(process.argv.slice(2));
|
|
69
|
+
if (opts.help) return printHelp();
|
|
70
|
+
|
|
71
|
+
console.log(`\n${pc.green('◆')} ${pc.bold('create-olmo-front')}\n`);
|
|
72
|
+
|
|
73
|
+
// 1. Resolve the target directory (prompt if not given).
|
|
74
|
+
let dir = opts.dir;
|
|
75
|
+
if (!dir) {
|
|
76
|
+
const res = await prompts({
|
|
77
|
+
type: 'text',
|
|
78
|
+
name: 'dir',
|
|
79
|
+
message: 'Project directory',
|
|
80
|
+
initial: 'my-olmo-site',
|
|
81
|
+
});
|
|
82
|
+
dir = res.dir;
|
|
83
|
+
}
|
|
84
|
+
if (!dir) {
|
|
85
|
+
console.log(pc.red('✖ No project directory given. Aborting.'));
|
|
86
|
+
process.exit(1);
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
const target = resolve(process.cwd(), dir);
|
|
90
|
+
const appName = toPackageName(basename(target));
|
|
91
|
+
|
|
92
|
+
// Refuse to write into a non-empty directory.
|
|
93
|
+
if (existsSync(target) && readdirSync(target).length > 0) {
|
|
94
|
+
console.log(pc.red(`✖ Directory ${pc.bold(dir)} already exists and is not empty.`));
|
|
95
|
+
process.exit(1);
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
// 2. Download the template from the public GitLab repo.
|
|
99
|
+
console.log(`${pc.dim('›')} Fetching template ${pc.cyan(`${TEMPLATE}#${opts.ref}`)} …`);
|
|
100
|
+
try {
|
|
101
|
+
await downloadTemplate(`${TEMPLATE}#${opts.ref}`, { dir: target, force: false });
|
|
102
|
+
} catch (err) {
|
|
103
|
+
console.log(pc.red(`✖ Failed to download template: ${err.message}`));
|
|
104
|
+
process.exit(1);
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
// 3. Personalize package.json (name + reset version). Keep "private": true — it's an app.
|
|
108
|
+
const pkgPath = join(target, 'package.json');
|
|
109
|
+
try {
|
|
110
|
+
const pkg = JSON.parse(readFileSync(pkgPath, 'utf8'));
|
|
111
|
+
pkg.name = appName;
|
|
112
|
+
pkg.version = '0.1.0';
|
|
113
|
+
writeFileSync(pkgPath, JSON.stringify(pkg, null, 2) + '\n');
|
|
114
|
+
} catch {
|
|
115
|
+
/* non-fatal: leave package.json as-is if it can't be parsed */
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
// 4. Seed a local, gitignored env file from the example (staging/prod live in Vercel).
|
|
119
|
+
const example = join(target, '.env.example');
|
|
120
|
+
const local = join(target, '.env.local');
|
|
121
|
+
if (existsSync(example) && !existsSync(local)) {
|
|
122
|
+
copyFileSync(example, local);
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
// 5. git init + first commit.
|
|
126
|
+
if (opts.git) {
|
|
127
|
+
console.log(`${pc.dim('›')} Initializing git repository …`);
|
|
128
|
+
if (run('git', ['init', '-q'], target)) {
|
|
129
|
+
run('git', ['add', '-A'], target);
|
|
130
|
+
run('git', ['commit', '-q', '-m', 'Initial commit from create-olmo-front'], target);
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
// 6. Install dependencies (pulls @olmocms/front and the rest).
|
|
135
|
+
if (opts.install) {
|
|
136
|
+
console.log(`${pc.dim('›')} Installing dependencies (this pulls ${pc.cyan('@olmocms/front')}) …\n`);
|
|
137
|
+
if (!run('npm', ['install'], target)) {
|
|
138
|
+
console.log(pc.yellow('\n! Dependency install failed — you can run `npm install` yourself.'));
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
// 7. Next steps.
|
|
143
|
+
console.log(`\n${pc.green('✔')} Created ${pc.bold(appName)} in ${pc.dim(target)}\n`);
|
|
144
|
+
console.log(pc.bold('Next steps:'));
|
|
145
|
+
console.log(` cd ${dir}`);
|
|
146
|
+
if (!opts.install) console.log(' npm install');
|
|
147
|
+
console.log(` ${pc.dim('# edit .env.local — set OLMO_TOKEN, OLMO_FORM_TOKEN, API URLs')}`);
|
|
148
|
+
console.log(' npm run dev\n');
|
|
149
|
+
console.log(pc.dim('Staging & production env vars belong in the Vercel dashboard, not in the repo.\n'));
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
main().catch((err) => {
|
|
153
|
+
console.error(pc.red(err?.stack || String(err)));
|
|
154
|
+
process.exit(1);
|
|
155
|
+
});
|
package/package.json
ADDED
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "create-olmo-front",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "Scaffold a new Olmo Next.js frontend from olmo-front-template, with @olmocms/front preinstalled.",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"bin": {
|
|
7
|
+
"create-olmo-front": "index.js"
|
|
8
|
+
},
|
|
9
|
+
"files": [
|
|
10
|
+
"index.js"
|
|
11
|
+
],
|
|
12
|
+
"engines": {
|
|
13
|
+
"node": ">=18"
|
|
14
|
+
},
|
|
15
|
+
"keywords": [
|
|
16
|
+
"olmo",
|
|
17
|
+
"olmocms",
|
|
18
|
+
"next",
|
|
19
|
+
"nextjs",
|
|
20
|
+
"create",
|
|
21
|
+
"template",
|
|
22
|
+
"scaffold",
|
|
23
|
+
"starter"
|
|
24
|
+
],
|
|
25
|
+
"author": "Acanto",
|
|
26
|
+
"license": "MIT",
|
|
27
|
+
"repository": {
|
|
28
|
+
"type": "git",
|
|
29
|
+
"url": "git+https://gitlab.com/olmocms/create-olmo-front.git"
|
|
30
|
+
},
|
|
31
|
+
"publishConfig": {
|
|
32
|
+
"access": "public"
|
|
33
|
+
},
|
|
34
|
+
"dependencies": {
|
|
35
|
+
"giget": "^1.2.5",
|
|
36
|
+
"picocolors": "^1.1.1",
|
|
37
|
+
"prompts": "^2.4.2"
|
|
38
|
+
}
|
|
39
|
+
}
|