tempora-cli 0.1.2 → 0.1.4
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 +47 -0
- package/dist/index.js +79 -19
- package/dist/registry.json +26 -1
- package/package.json +3 -2
- package/registry.json +26 -1
package/README.md
ADDED
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
# tempora-cli
|
|
2
|
+
|
|
3
|
+
A fast, language-agnostic CLI that bootstraps your project from a curated vault of community templates — no setup, no guesswork.
|
|
4
|
+
|
|
5
|
+
## Install
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
npm install -g tempora-cli
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
## Usage
|
|
12
|
+
|
|
13
|
+
**Guided mode:**
|
|
14
|
+
```bash
|
|
15
|
+
tempora init
|
|
16
|
+
```
|
|
17
|
+
|
|
18
|
+
**Direct mode:**
|
|
19
|
+
```bash
|
|
20
|
+
tempora init next-tailwind my-app
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
**Scaffold into current folder:**
|
|
24
|
+
```bash
|
|
25
|
+
tempora init next-tailwind .
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
**Browse template info:**
|
|
29
|
+
```bash
|
|
30
|
+
tempora info next-tailwind
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
## Requirements
|
|
34
|
+
|
|
35
|
+
- Node.js 18+
|
|
36
|
+
- git
|
|
37
|
+
- npm
|
|
38
|
+
|
|
39
|
+
## Links
|
|
40
|
+
|
|
41
|
+
- [Documentation](https://tempora.vercel.app)
|
|
42
|
+
- [GitHub](https://github.com/DidIrb/tempora)
|
|
43
|
+
- [npm](https://www.npmjs.com/package/tempora-cli)
|
|
44
|
+
|
|
45
|
+
## License
|
|
46
|
+
|
|
47
|
+
MIT © Tempora
|
package/dist/index.js
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
// src/index.ts
|
|
4
4
|
import { Command } from "commander";
|
|
5
|
-
import { createRequire as
|
|
5
|
+
import { createRequire as createRequire3 } from "module";
|
|
6
6
|
|
|
7
7
|
// src/commands/init.ts
|
|
8
8
|
import ora from "ora";
|
|
@@ -19,6 +19,7 @@ var logger = {
|
|
|
19
19
|
|
|
20
20
|
// src/utils/versionCheck.ts
|
|
21
21
|
import { createRequire } from "module";
|
|
22
|
+
import pc2 from "picocolors";
|
|
22
23
|
var require2 = createRequire(import.meta.url);
|
|
23
24
|
var { version: current } = require2("../package.json");
|
|
24
25
|
async function checkVersion() {
|
|
@@ -33,9 +34,11 @@ async function checkVersion() {
|
|
|
33
34
|
const [latMajor, latMinor] = latest.split(".").map(Number);
|
|
34
35
|
const isMinorOrMajor = latMajor > curMajor || latMajor === curMajor && latMinor > curMinor;
|
|
35
36
|
if (!isMinorOrMajor) return;
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
37
|
+
console.log("");
|
|
38
|
+
console.log(" " + pc2.bgYellow(pc2.black(" UPDATE ")) + " " + pc2.dim(current) + " \u2192 " + pc2.green(pc2.bold(latest)));
|
|
39
|
+
console.log(" " + pc2.dim("Run: ") + pc2.cyan("npm install -g tempora-cli"));
|
|
40
|
+
console.log(" " + pc2.dim("https://www.npmjs.com/package/tempora-cli"));
|
|
41
|
+
console.log("");
|
|
39
42
|
} catch {
|
|
40
43
|
}
|
|
41
44
|
}
|
|
@@ -76,7 +79,7 @@ import { execSync } from "child_process";
|
|
|
76
79
|
import { fileURLToPath } from "url";
|
|
77
80
|
|
|
78
81
|
// src/config.ts
|
|
79
|
-
var org = "
|
|
82
|
+
var org = "DidIrb";
|
|
80
83
|
var repo = "tempora";
|
|
81
84
|
var branch = "main";
|
|
82
85
|
var config = {
|
|
@@ -96,11 +99,11 @@ var config = {
|
|
|
96
99
|
// src/utils/downloader.ts
|
|
97
100
|
var __dirname = path2.dirname(fileURLToPath(import.meta.url));
|
|
98
101
|
function findLocalTemplatesDir() {
|
|
99
|
-
let
|
|
102
|
+
let current3 = __dirname;
|
|
100
103
|
for (let i = 0; i < 6; i++) {
|
|
101
|
-
const candidate = path2.join(
|
|
104
|
+
const candidate = path2.join(current3, "templates");
|
|
102
105
|
if (fs2.existsSync(candidate)) return candidate;
|
|
103
|
-
|
|
106
|
+
current3 = path2.dirname(current3);
|
|
104
107
|
}
|
|
105
108
|
return null;
|
|
106
109
|
}
|
|
@@ -159,17 +162,20 @@ The template may have been moved or removed. Run "tempora init" to browse availa
|
|
|
159
162
|
fs2.rmSync(tmpDir, { recursive: true, force: true });
|
|
160
163
|
}
|
|
161
164
|
}
|
|
162
|
-
async function downloadTemplate(template, targetDir, overwrite) {
|
|
165
|
+
async function downloadTemplate(template, targetDir, overwrite, spinner) {
|
|
163
166
|
const localTemplatesDir = findLocalTemplatesDir();
|
|
164
167
|
if (localTemplatesDir) {
|
|
168
|
+
if (spinner) spinner.text = "Copying template from local...";
|
|
169
|
+
await new Promise((r) => setTimeout(r, 50));
|
|
165
170
|
const relativeParts = template.path.replace(/^templates\//, "").split("/");
|
|
166
171
|
const localSrc = path2.join(localTemplatesDir, ...relativeParts);
|
|
167
172
|
if (fs2.existsSync(localSrc)) {
|
|
168
173
|
copyDirLocal(localSrc, targetDir, overwrite);
|
|
169
174
|
return;
|
|
170
175
|
}
|
|
171
|
-
throw new Error(`Template "${template.id}" not found in local templates folder.`);
|
|
172
176
|
}
|
|
177
|
+
if (spinner) spinner.text = `Downloading ${template.name} from GitHub...`;
|
|
178
|
+
await new Promise((r) => setTimeout(r, 50));
|
|
173
179
|
cloneTemplateSparse(template.path, targetDir, overwrite);
|
|
174
180
|
}
|
|
175
181
|
|
|
@@ -198,7 +204,19 @@ import fs3 from "fs";
|
|
|
198
204
|
import path4 from "path";
|
|
199
205
|
import { fileURLToPath as fileURLToPath2 } from "url";
|
|
200
206
|
var __dirname2 = path4.dirname(fileURLToPath2(import.meta.url));
|
|
201
|
-
|
|
207
|
+
var REMOTE_REGISTRY_URL = "https://raw.githubusercontent.com/DidIrb/tempora/main/packages/cli/registry.json";
|
|
208
|
+
async function loadRegistry() {
|
|
209
|
+
try {
|
|
210
|
+
const res = await fetch(REMOTE_REGISTRY_URL, {
|
|
211
|
+
signal: AbortSignal.timeout(4e3)
|
|
212
|
+
});
|
|
213
|
+
if (res.ok) {
|
|
214
|
+
const data = await res.json();
|
|
215
|
+
return data;
|
|
216
|
+
}
|
|
217
|
+
} catch {
|
|
218
|
+
console.log("Failed");
|
|
219
|
+
}
|
|
202
220
|
const registryPath = path4.resolve(__dirname2, "./registry.json");
|
|
203
221
|
if (!fs3.existsSync(registryPath)) {
|
|
204
222
|
throw new Error("Registry not found. Please rebuild the CLI with npm run build.");
|
|
@@ -283,7 +301,7 @@ function registerInitCommand(program2) {
|
|
|
283
301
|
program2.command("init [template] [directory]").description("Scaffold a new project from a Tempora template").action(async (template, directory) => {
|
|
284
302
|
const spinner = ora();
|
|
285
303
|
try {
|
|
286
|
-
const registry = loadRegistry();
|
|
304
|
+
const registry = await loadRegistry();
|
|
287
305
|
let resolvedTemplate = template;
|
|
288
306
|
let resolvedDirectory = directory;
|
|
289
307
|
if (!resolvedTemplate) {
|
|
@@ -300,10 +318,12 @@ function registerInitCommand(program2) {
|
|
|
300
318
|
const result = await resolveTargetDir(resolvedDirectory);
|
|
301
319
|
if (!result) return;
|
|
302
320
|
const { targetDir, overwrite } = result;
|
|
303
|
-
|
|
304
|
-
|
|
321
|
+
await new Promise((r) => setTimeout(r, 100));
|
|
322
|
+
spinner.start();
|
|
323
|
+
await downloadTemplate(entry, targetDir, overwrite, spinner);
|
|
305
324
|
spinner.succeed(`${entry.name} scaffolded successfully!`);
|
|
306
325
|
printPostInstall(entry, targetDir);
|
|
326
|
+
await checkVersion();
|
|
307
327
|
} catch (err) {
|
|
308
328
|
spinner.stop();
|
|
309
329
|
logger.error(err instanceof Error ? err.message : "Something went wrong.");
|
|
@@ -314,9 +334,9 @@ function registerInitCommand(program2) {
|
|
|
314
334
|
|
|
315
335
|
// src/commands/info.ts
|
|
316
336
|
function registerInfoCommand(program2) {
|
|
317
|
-
program2.command("info <template>").description("Show details about a specific template").action((template) => {
|
|
337
|
+
program2.command("info <template>").description("Show details about a specific template").action(async (template) => {
|
|
318
338
|
try {
|
|
319
|
-
const registry = loadRegistry();
|
|
339
|
+
const registry = await loadRegistry();
|
|
320
340
|
const entry = registry.templates[template];
|
|
321
341
|
if (!entry) {
|
|
322
342
|
logger.error(`Template "${template}" not found.`);
|
|
@@ -340,6 +360,7 @@ function registerInfoCommand(program2) {
|
|
|
340
360
|
}
|
|
341
361
|
logger.log("");
|
|
342
362
|
}
|
|
363
|
+
await checkVersion();
|
|
343
364
|
} catch (err) {
|
|
344
365
|
logger.error(err instanceof Error ? err.message : "Something went wrong.");
|
|
345
366
|
process.exit(1);
|
|
@@ -347,9 +368,47 @@ function registerInfoCommand(program2) {
|
|
|
347
368
|
});
|
|
348
369
|
}
|
|
349
370
|
|
|
350
|
-
// src/
|
|
371
|
+
// src/commands/update.ts
|
|
372
|
+
import { createRequire as createRequire2 } from "module";
|
|
373
|
+
import pc3 from "picocolors";
|
|
351
374
|
var require3 = createRequire2(import.meta.url);
|
|
352
|
-
var { version } = require3("../package.json");
|
|
375
|
+
var { version: current2 } = require3("../package.json");
|
|
376
|
+
function registerUpdateCommand(program2) {
|
|
377
|
+
program2.command("update").description("Check for updates to the Tempora CLI").action(async () => {
|
|
378
|
+
try {
|
|
379
|
+
console.log("");
|
|
380
|
+
console.log(" Checking for updates...");
|
|
381
|
+
const res = await fetch("https://registry.npmjs.org/tempora-cli/latest", {
|
|
382
|
+
signal: AbortSignal.timeout(5e3)
|
|
383
|
+
});
|
|
384
|
+
if (!res.ok) {
|
|
385
|
+
console.log(" " + pc3.red("Could not reach npm registry. Check your connection."));
|
|
386
|
+
return;
|
|
387
|
+
}
|
|
388
|
+
const { version: latest } = await res.json();
|
|
389
|
+
if (current2 === latest) {
|
|
390
|
+
console.log(" " + pc3.green("\u2714") + " You are on the latest version " + pc3.bold(current2));
|
|
391
|
+
} else {
|
|
392
|
+
const [curMajor, curMinor] = current2.split(".").map(Number);
|
|
393
|
+
const [latMajor, latMinor] = latest.split(".").map(Number);
|
|
394
|
+
let type = "patch";
|
|
395
|
+
if (latMajor > curMajor) type = "major";
|
|
396
|
+
else if (latMinor > curMinor) type = "minor";
|
|
397
|
+
console.log("");
|
|
398
|
+
console.log(" " + pc3.bgYellow(pc3.black(` ${type.toUpperCase()} UPDATE `)) + " " + pc3.dim(current2) + " \u2192 " + pc3.green(pc3.bold(latest)));
|
|
399
|
+
console.log(" " + pc3.dim("Run: ") + pc3.cyan("npm install -g tempora-cli"));
|
|
400
|
+
console.log(" " + pc3.dim("https://www.npmjs.com/package/tempora-cli"));
|
|
401
|
+
}
|
|
402
|
+
console.log("");
|
|
403
|
+
} catch {
|
|
404
|
+
console.log(" " + pc3.red("Failed to check for updates."));
|
|
405
|
+
}
|
|
406
|
+
});
|
|
407
|
+
}
|
|
408
|
+
|
|
409
|
+
// src/index.ts
|
|
410
|
+
var require4 = createRequire3(import.meta.url);
|
|
411
|
+
var { version } = require4("../package.json");
|
|
353
412
|
var program = new Command();
|
|
354
413
|
program.name("tempora").description("Scaffold projects from curated templates").version(version, "-v, --version", "Show the current version").addHelpText("after", `
|
|
355
414
|
Examples:
|
|
@@ -357,8 +416,9 @@ Examples:
|
|
|
357
416
|
$ tempora init next-tailwind .
|
|
358
417
|
$ tempora init
|
|
359
418
|
$ tempora info next-tailwind
|
|
419
|
+
$ tempora update
|
|
360
420
|
`);
|
|
361
421
|
registerInitCommand(program);
|
|
362
422
|
registerInfoCommand(program);
|
|
363
|
-
|
|
423
|
+
registerUpdateCommand(program);
|
|
364
424
|
program.parse(process.argv);
|
package/dist/registry.json
CHANGED
|
@@ -1,7 +1,27 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": "1.0.0",
|
|
3
|
-
"updatedAt": "2026-06-
|
|
3
|
+
"updatedAt": "2026-06-28T12:24:42.600Z",
|
|
4
4
|
"templates": {
|
|
5
|
+
"angular-starter": {
|
|
6
|
+
"id": "angular-starter",
|
|
7
|
+
"name": "Angular Starter",
|
|
8
|
+
"language": "typescript",
|
|
9
|
+
"category": "frontend",
|
|
10
|
+
"library": "angular",
|
|
11
|
+
"description": "Angular 17 standalone components with TypeScript and Angular CLI preconfigured.",
|
|
12
|
+
"tags": [
|
|
13
|
+
"angular",
|
|
14
|
+
"typescript",
|
|
15
|
+
"frontend",
|
|
16
|
+
"spa"
|
|
17
|
+
],
|
|
18
|
+
"version": "1.0.0",
|
|
19
|
+
"nextSteps": [
|
|
20
|
+
"npm install",
|
|
21
|
+
"ng serve"
|
|
22
|
+
],
|
|
23
|
+
"path": "templates/typescript/frontend/angular/angular-starter"
|
|
24
|
+
},
|
|
5
25
|
"next-tailwind": {
|
|
6
26
|
"id": "next-tailwind",
|
|
7
27
|
"name": "Next.js + Tailwind",
|
|
@@ -45,12 +65,14 @@
|
|
|
45
65
|
},
|
|
46
66
|
"byLanguage": {
|
|
47
67
|
"typescript": [
|
|
68
|
+
"angular-starter",
|
|
48
69
|
"next-tailwind",
|
|
49
70
|
"nextjs-tailwind"
|
|
50
71
|
]
|
|
51
72
|
},
|
|
52
73
|
"byCategory": {
|
|
53
74
|
"frontend": [
|
|
75
|
+
"angular-starter",
|
|
54
76
|
"next-tailwind"
|
|
55
77
|
],
|
|
56
78
|
"fullstack": [
|
|
@@ -58,6 +80,9 @@
|
|
|
58
80
|
]
|
|
59
81
|
},
|
|
60
82
|
"byLibrary": {
|
|
83
|
+
"angular": [
|
|
84
|
+
"angular-starter"
|
|
85
|
+
],
|
|
61
86
|
"nextjs": [
|
|
62
87
|
"next-tailwind"
|
|
63
88
|
],
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "tempora-cli",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.4",
|
|
4
4
|
"description": "Tempora CLI — scaffold projects from curated templates",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"type": "module",
|
|
@@ -14,7 +14,8 @@
|
|
|
14
14
|
"files": [
|
|
15
15
|
"bin",
|
|
16
16
|
"dist",
|
|
17
|
-
"registry.json"
|
|
17
|
+
"registry.json",
|
|
18
|
+
"README.md"
|
|
18
19
|
],
|
|
19
20
|
"dependencies": {
|
|
20
21
|
"chalk": "^5.3.0",
|
package/registry.json
CHANGED
|
@@ -1,7 +1,27 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": "1.0.0",
|
|
3
|
-
"updatedAt": "2026-06-
|
|
3
|
+
"updatedAt": "2026-06-28T12:24:42.600Z",
|
|
4
4
|
"templates": {
|
|
5
|
+
"angular-starter": {
|
|
6
|
+
"id": "angular-starter",
|
|
7
|
+
"name": "Angular Starter",
|
|
8
|
+
"language": "typescript",
|
|
9
|
+
"category": "frontend",
|
|
10
|
+
"library": "angular",
|
|
11
|
+
"description": "Angular 17 standalone components with TypeScript and Angular CLI preconfigured.",
|
|
12
|
+
"tags": [
|
|
13
|
+
"angular",
|
|
14
|
+
"typescript",
|
|
15
|
+
"frontend",
|
|
16
|
+
"spa"
|
|
17
|
+
],
|
|
18
|
+
"version": "1.0.0",
|
|
19
|
+
"nextSteps": [
|
|
20
|
+
"npm install",
|
|
21
|
+
"ng serve"
|
|
22
|
+
],
|
|
23
|
+
"path": "templates/typescript/frontend/angular/angular-starter"
|
|
24
|
+
},
|
|
5
25
|
"next-tailwind": {
|
|
6
26
|
"id": "next-tailwind",
|
|
7
27
|
"name": "Next.js + Tailwind",
|
|
@@ -45,12 +65,14 @@
|
|
|
45
65
|
},
|
|
46
66
|
"byLanguage": {
|
|
47
67
|
"typescript": [
|
|
68
|
+
"angular-starter",
|
|
48
69
|
"next-tailwind",
|
|
49
70
|
"nextjs-tailwind"
|
|
50
71
|
]
|
|
51
72
|
},
|
|
52
73
|
"byCategory": {
|
|
53
74
|
"frontend": [
|
|
75
|
+
"angular-starter",
|
|
54
76
|
"next-tailwind"
|
|
55
77
|
],
|
|
56
78
|
"fullstack": [
|
|
@@ -58,6 +80,9 @@
|
|
|
58
80
|
]
|
|
59
81
|
},
|
|
60
82
|
"byLibrary": {
|
|
83
|
+
"angular": [
|
|
84
|
+
"angular-starter"
|
|
85
|
+
],
|
|
61
86
|
"nextjs": [
|
|
62
87
|
"next-tailwind"
|
|
63
88
|
],
|