create-tina-app 0.0.0-d9487bf-20251119052214 → 0.0.0-db7231c-20251216055550
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/bin/create-tina-app +1 -1
- package/dist/index.js +445 -196
- package/dist/templates.d.ts +6 -0
- package/dist/util/asciiArt.d.ts +1 -0
- package/dist/util/fetchPosthogConfig.d.ts +5 -0
- package/dist/util/isNpm.d.ts +16 -0
- package/dist/util/posthog.d.ts +4 -0
- package/dist/util/textstyles.d.ts +17 -8
- package/package.json +6 -5
package/bin/create-tina-app
CHANGED
package/dist/index.js
CHANGED
|
@@ -1,127 +1,40 @@
|
|
|
1
|
-
var __create = Object.create;
|
|
2
|
-
var __defProp = Object.defineProperty;
|
|
3
|
-
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
|
-
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
5
|
-
var __getProtoOf = Object.getPrototypeOf;
|
|
6
|
-
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
7
|
-
var __commonJS = (cb, mod) => function __require() {
|
|
8
|
-
return mod || (0, cb[__getOwnPropNames(cb)[0]])((mod = { exports: {} }).exports, mod), mod.exports;
|
|
9
|
-
};
|
|
10
|
-
var __export = (target, all) => {
|
|
11
|
-
for (var name2 in all)
|
|
12
|
-
__defProp(target, name2, { get: all[name2], enumerable: true });
|
|
13
|
-
};
|
|
14
|
-
var __copyProps = (to, from, except, desc) => {
|
|
15
|
-
if (from && typeof from === "object" || typeof from === "function") {
|
|
16
|
-
for (let key of __getOwnPropNames(from))
|
|
17
|
-
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
18
|
-
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
19
|
-
}
|
|
20
|
-
return to;
|
|
21
|
-
};
|
|
22
|
-
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
|
|
23
|
-
// If the importer is in node compatibility mode or this is not an ESM
|
|
24
|
-
// file that has been converted to a CommonJS file using a Babel-
|
|
25
|
-
// compatible transform (i.e. "__esModule" has not been set), then set
|
|
26
|
-
// "default" to the CommonJS "module.exports" for node compatibility.
|
|
27
|
-
isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
|
|
28
|
-
mod
|
|
29
|
-
));
|
|
30
|
-
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
31
|
-
|
|
32
|
-
// package.json
|
|
33
|
-
var require_package = __commonJS({
|
|
34
|
-
"package.json"(exports2, module2) {
|
|
35
|
-
module2.exports = {
|
|
36
|
-
name: "create-tina-app",
|
|
37
|
-
version: "1.6.0",
|
|
38
|
-
main: "dist/index.js",
|
|
39
|
-
files: [
|
|
40
|
-
"dist",
|
|
41
|
-
"examples",
|
|
42
|
-
"bin/*"
|
|
43
|
-
],
|
|
44
|
-
bin: "bin/create-tina-app",
|
|
45
|
-
typings: "dist/index.d.ts",
|
|
46
|
-
license: "Apache-2.0",
|
|
47
|
-
buildConfig: {
|
|
48
|
-
entryPoints: [
|
|
49
|
-
{
|
|
50
|
-
name: "src/index.ts",
|
|
51
|
-
target: "node"
|
|
52
|
-
}
|
|
53
|
-
]
|
|
54
|
-
},
|
|
55
|
-
engines: {
|
|
56
|
-
node: ">=18.18.0"
|
|
57
|
-
},
|
|
58
|
-
scripts: {
|
|
59
|
-
types: "pnpm tsc",
|
|
60
|
-
build: "tinacms-scripts build",
|
|
61
|
-
"test-run-bin": "pnpm create-tina-app"
|
|
62
|
-
},
|
|
63
|
-
publishConfig: {
|
|
64
|
-
registry: "https://registry.npmjs.org"
|
|
65
|
-
},
|
|
66
|
-
repository: {
|
|
67
|
-
url: "https://github.com/tinacms/tinacms.git",
|
|
68
|
-
directory: "packages/create-tina-app"
|
|
69
|
-
},
|
|
70
|
-
devDependencies: {
|
|
71
|
-
"@tinacms/scripts": "workspace:*",
|
|
72
|
-
"@types/cross-spawn": "catalog:",
|
|
73
|
-
"@types/fs-extra": "^11.0.4",
|
|
74
|
-
"@types/node": "^22.13.1",
|
|
75
|
-
"@types/prompts": "catalog:",
|
|
76
|
-
"@types/tar": "catalog:",
|
|
77
|
-
typescript: "^5.7.3"
|
|
78
|
-
},
|
|
79
|
-
dependencies: {
|
|
80
|
-
"@tinacms/metrics": "workspace:*",
|
|
81
|
-
chalk: "4.1.2",
|
|
82
|
-
commander: "^12.1.0",
|
|
83
|
-
"cross-spawn": "catalog:",
|
|
84
|
-
"fs-extra": "catalog:",
|
|
85
|
-
ora: "catalog:",
|
|
86
|
-
prompts: "catalog:",
|
|
87
|
-
tar: "catalog:",
|
|
88
|
-
"validate-npm-package-name": "catalog:"
|
|
89
|
-
}
|
|
90
|
-
};
|
|
91
|
-
}
|
|
92
|
-
});
|
|
93
|
-
|
|
94
1
|
// src/index.ts
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
}
|
|
99
|
-
module.exports = __toCommonJS(index_exports);
|
|
100
|
-
var import_metrics = require("@tinacms/metrics");
|
|
101
|
-
var import_prompts = __toESM(require("prompts"));
|
|
102
|
-
var import_node_path = __toESM(require("node:path"));
|
|
2
|
+
import { Telemetry } from "@tinacms/metrics";
|
|
3
|
+
import prompts from "prompts";
|
|
4
|
+
import path4 from "node:path";
|
|
5
|
+
import { createRequire } from "node:module";
|
|
103
6
|
|
|
104
7
|
// src/util/fileUtil.ts
|
|
105
|
-
|
|
106
|
-
|
|
8
|
+
import fs from "fs-extra";
|
|
9
|
+
import path from "path";
|
|
107
10
|
|
|
108
11
|
// src/util/textstyles.ts
|
|
109
|
-
|
|
12
|
+
import chalk from "chalk";
|
|
110
13
|
var TextStyles = {
|
|
111
|
-
tinaOrange:
|
|
112
|
-
link: (url) => `\x1B]8;;${url}\x07${
|
|
113
|
-
cmd:
|
|
114
|
-
info:
|
|
115
|
-
success:
|
|
116
|
-
warn:
|
|
117
|
-
err:
|
|
118
|
-
bold:
|
|
14
|
+
tinaOrange: chalk.hex("#EC4816"),
|
|
15
|
+
link: (url) => `\x1B]8;;${url}\x07${chalk.cyan.underline(url)}\x1B]8;;\x07`,
|
|
16
|
+
cmd: chalk.bgBlackBright.bold.white,
|
|
17
|
+
info: chalk.blue,
|
|
18
|
+
success: chalk.green,
|
|
19
|
+
warn: chalk.yellow,
|
|
20
|
+
err: chalk.red,
|
|
21
|
+
bold: chalk.bold
|
|
22
|
+
};
|
|
23
|
+
var TextStylesBold = {
|
|
24
|
+
tinaOrange: chalk.hex("#EC4816").bold,
|
|
25
|
+
link: (url) => `\x1B]8;;${url}\x07${chalk.cyan.underline(url)}\x1B]8;;\x07`,
|
|
26
|
+
cmd: chalk.bgBlackBright.bold.white,
|
|
27
|
+
info: chalk.blue,
|
|
28
|
+
success: chalk.green,
|
|
29
|
+
warn: chalk.yellow,
|
|
30
|
+
err: chalk.red,
|
|
31
|
+
bold: chalk.bold
|
|
119
32
|
};
|
|
120
33
|
|
|
121
34
|
// src/util/fileUtil.ts
|
|
122
35
|
async function isWriteable(directory) {
|
|
123
36
|
try {
|
|
124
|
-
await
|
|
37
|
+
await fs.promises.access(directory, (fs.constants || fs).W_OK);
|
|
125
38
|
return true;
|
|
126
39
|
} catch (err) {
|
|
127
40
|
return false;
|
|
@@ -148,12 +61,12 @@ function folderContainsInstallConflicts(root) {
|
|
|
148
61
|
"yarn-debug.log",
|
|
149
62
|
"yarn-error.log"
|
|
150
63
|
];
|
|
151
|
-
const conflicts =
|
|
64
|
+
const conflicts = fs.readdirSync(root).filter((file) => !validFiles.includes(file)).filter((file) => !/\.iml$/.test(file));
|
|
152
65
|
return conflicts;
|
|
153
66
|
}
|
|
154
67
|
async function setupProjectDirectory(dir) {
|
|
155
|
-
const appName =
|
|
156
|
-
await
|
|
68
|
+
const appName = path.basename(dir);
|
|
69
|
+
await fs.mkdirp(dir);
|
|
157
70
|
process.chdir(dir);
|
|
158
71
|
const conflicts = folderContainsInstallConflicts(dir);
|
|
159
72
|
if (conflicts.length > 0) {
|
|
@@ -162,7 +75,7 @@ async function setupProjectDirectory(dir) {
|
|
|
162
75
|
];
|
|
163
76
|
for (const file of conflicts) {
|
|
164
77
|
try {
|
|
165
|
-
const stats =
|
|
78
|
+
const stats = fs.lstatSync(path.join(dir, file));
|
|
166
79
|
if (stats.isDirectory()) {
|
|
167
80
|
errorMessageLines.push(` - ${TextStyles.info(file)}/`);
|
|
168
81
|
} else {
|
|
@@ -177,36 +90,36 @@ async function setupProjectDirectory(dir) {
|
|
|
177
90
|
return appName;
|
|
178
91
|
}
|
|
179
92
|
function updateProjectPackageName(dir, name2) {
|
|
180
|
-
const packageJsonPath =
|
|
181
|
-
const packageJson = JSON.parse(
|
|
93
|
+
const packageJsonPath = path.join(dir, "package.json");
|
|
94
|
+
const packageJson = JSON.parse(fs.readFileSync(packageJsonPath, "utf8"));
|
|
182
95
|
packageJson.name = name2;
|
|
183
|
-
|
|
96
|
+
fs.writeFileSync(packageJsonPath, JSON.stringify(packageJson, null, 2));
|
|
184
97
|
}
|
|
185
98
|
function updateProjectPackageVersion(dir, version2) {
|
|
186
|
-
const packageJsonPath =
|
|
187
|
-
const packageJson = JSON.parse(
|
|
99
|
+
const packageJsonPath = path.join(dir, "package.json");
|
|
100
|
+
const packageJson = JSON.parse(fs.readFileSync(packageJsonPath, "utf8"));
|
|
188
101
|
packageJson.version = version2;
|
|
189
|
-
|
|
102
|
+
fs.writeFileSync(packageJsonPath, JSON.stringify(packageJson, null, 2));
|
|
190
103
|
}
|
|
191
104
|
async function updateThemeSettings(dir, selectedTheme) {
|
|
192
|
-
const settingsDir =
|
|
193
|
-
const configPath =
|
|
194
|
-
await
|
|
105
|
+
const settingsDir = path.join(dir, "content", "settings");
|
|
106
|
+
const configPath = path.join(settingsDir, "config.json");
|
|
107
|
+
await fs.mkdirp(settingsDir);
|
|
195
108
|
let config = {};
|
|
196
109
|
try {
|
|
197
|
-
const existingConfig = await
|
|
110
|
+
const existingConfig = await fs.readFile(configPath, "utf8");
|
|
198
111
|
config = JSON.parse(existingConfig);
|
|
199
112
|
} catch (error) {
|
|
200
113
|
}
|
|
201
114
|
config.selectedTheme = selectedTheme;
|
|
202
|
-
await
|
|
115
|
+
await fs.writeFile(configPath, JSON.stringify(config, null, 2));
|
|
203
116
|
}
|
|
204
117
|
|
|
205
118
|
// src/util/install.ts
|
|
206
|
-
|
|
119
|
+
import spawn from "cross-spawn";
|
|
207
120
|
function install(packageManager, verboseOutput) {
|
|
208
121
|
return new Promise((resolve, reject) => {
|
|
209
|
-
const child = (
|
|
122
|
+
const child = spawn(packageManager, ["install"], {
|
|
210
123
|
stdio: verboseOutput ? "inherit" : "ignore",
|
|
211
124
|
env: { ...process.env, ADBLOCK: "1", DISABLE_OPENCOLLECTIVE: "1" }
|
|
212
125
|
});
|
|
@@ -221,12 +134,12 @@ function install(packageManager, verboseOutput) {
|
|
|
221
134
|
}
|
|
222
135
|
|
|
223
136
|
// src/util/git.ts
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
137
|
+
import { execSync } from "child_process";
|
|
138
|
+
import path2 from "path";
|
|
139
|
+
import fs2 from "fs-extra";
|
|
227
140
|
function isInGitRepository() {
|
|
228
141
|
try {
|
|
229
|
-
|
|
142
|
+
execSync("git rev-parse --is-inside-work-tree", { stdio: "ignore" });
|
|
230
143
|
return true;
|
|
231
144
|
} catch (_) {
|
|
232
145
|
}
|
|
@@ -234,7 +147,7 @@ function isInGitRepository() {
|
|
|
234
147
|
}
|
|
235
148
|
function isInMercurialRepository() {
|
|
236
149
|
try {
|
|
237
|
-
|
|
150
|
+
execSync("hg --cwd . root", { stdio: "ignore" });
|
|
238
151
|
return true;
|
|
239
152
|
} catch (_) {
|
|
240
153
|
}
|
|
@@ -242,27 +155,27 @@ function isInMercurialRepository() {
|
|
|
242
155
|
}
|
|
243
156
|
function makeFirstCommit(root) {
|
|
244
157
|
try {
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
158
|
+
execSync("git checkout -b main", { stdio: "ignore" });
|
|
159
|
+
execSync("git add -A", { stdio: "ignore" });
|
|
160
|
+
execSync('git commit -m "Initial commit from Create Tina App"', {
|
|
248
161
|
stdio: "ignore"
|
|
249
162
|
});
|
|
250
163
|
} catch (err) {
|
|
251
|
-
|
|
164
|
+
fs2.removeSync(path2.join(root, ".git"));
|
|
252
165
|
throw err;
|
|
253
166
|
}
|
|
254
167
|
}
|
|
255
168
|
function initializeGit(spinner) {
|
|
256
|
-
|
|
169
|
+
execSync("git --version", { stdio: "ignore" });
|
|
257
170
|
if (isInGitRepository() || isInMercurialRepository()) {
|
|
258
171
|
spinner.warn("Already in a Git repository, skipping.");
|
|
259
172
|
return false;
|
|
260
173
|
}
|
|
261
|
-
if (!
|
|
174
|
+
if (!fs2.existsSync(".gitignore")) {
|
|
262
175
|
spinner.warn(
|
|
263
176
|
"There is no .gitignore file in this repository, creating one..."
|
|
264
177
|
);
|
|
265
|
-
|
|
178
|
+
fs2.writeFileSync(
|
|
266
179
|
".gitignore",
|
|
267
180
|
`node_modules
|
|
268
181
|
.yarn/*
|
|
@@ -272,14 +185,14 @@ function initializeGit(spinner) {
|
|
|
272
185
|
`
|
|
273
186
|
);
|
|
274
187
|
}
|
|
275
|
-
|
|
188
|
+
execSync("git init", { stdio: "ignore" });
|
|
276
189
|
return true;
|
|
277
190
|
}
|
|
278
191
|
|
|
279
192
|
// src/util/examples.ts
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
193
|
+
import { Readable } from "node:stream";
|
|
194
|
+
import { pipeline } from "node:stream/promises";
|
|
195
|
+
import { x } from "tar";
|
|
283
196
|
async function getRepoInfo(url, examplePath) {
|
|
284
197
|
const [, username, name2, t, _branch, ...file] = url.pathname.split("/");
|
|
285
198
|
const filePath = examplePath ? examplePath.replace(/^\//, "") : file.join("/");
|
|
@@ -314,14 +227,14 @@ async function downloadTarStream(url) {
|
|
|
314
227
|
if (!res.body) {
|
|
315
228
|
throw new Error(`Failed to download: ${url}`);
|
|
316
229
|
}
|
|
317
|
-
return
|
|
230
|
+
return Readable.fromWeb(res.body);
|
|
318
231
|
}
|
|
319
232
|
async function downloadAndExtractRepo(root, { username, name: name2, branch, filePath }) {
|
|
320
|
-
await
|
|
233
|
+
await pipeline(
|
|
321
234
|
await downloadTarStream(
|
|
322
235
|
`https://codeload.github.com/${username}/${name2}/tar.gz/${branch}`
|
|
323
236
|
),
|
|
324
|
-
|
|
237
|
+
x({
|
|
325
238
|
cwd: root,
|
|
326
239
|
strip: filePath ? filePath.split("/").length + 1 : 1,
|
|
327
240
|
filter: (p) => p.startsWith(
|
|
@@ -332,14 +245,28 @@ async function downloadAndExtractRepo(root, { username, name: name2, branch, fil
|
|
|
332
245
|
}
|
|
333
246
|
|
|
334
247
|
// src/templates.ts
|
|
335
|
-
|
|
336
|
-
|
|
248
|
+
import { copy } from "fs-extra";
|
|
249
|
+
import path3 from "path";
|
|
337
250
|
var TEMPLATES = [
|
|
338
251
|
{
|
|
339
252
|
title: "\u2B50 NextJS starter",
|
|
340
253
|
description: "Kickstart your project with Next.js \u2013 our top recommendation for a seamless, performant, and versatile web experience.",
|
|
341
254
|
value: "tina-nextjs-starter",
|
|
342
255
|
isInternal: false,
|
|
256
|
+
features: [
|
|
257
|
+
{
|
|
258
|
+
name: "Visual Editing",
|
|
259
|
+
description: "\u2705"
|
|
260
|
+
},
|
|
261
|
+
{
|
|
262
|
+
name: "ISR",
|
|
263
|
+
description: "\u2705"
|
|
264
|
+
},
|
|
265
|
+
{
|
|
266
|
+
name: "SSG",
|
|
267
|
+
description: "\u2705"
|
|
268
|
+
}
|
|
269
|
+
],
|
|
343
270
|
gitURL: "https://github.com/tinacms/tina-nextjs-starter",
|
|
344
271
|
devUrl: "http://localhost:3000"
|
|
345
272
|
},
|
|
@@ -348,6 +275,20 @@ var TEMPLATES = [
|
|
|
348
275
|
description: "Get your documentation site up and running with TinaCMS and Next.js in minutes.",
|
|
349
276
|
value: "tina-docs",
|
|
350
277
|
isInternal: false,
|
|
278
|
+
features: [
|
|
279
|
+
{
|
|
280
|
+
name: "Visual Editing",
|
|
281
|
+
description: "\u2705"
|
|
282
|
+
},
|
|
283
|
+
{
|
|
284
|
+
name: "ISR",
|
|
285
|
+
description: "\u2705"
|
|
286
|
+
},
|
|
287
|
+
{
|
|
288
|
+
name: "SSG",
|
|
289
|
+
description: "\u2705"
|
|
290
|
+
}
|
|
291
|
+
],
|
|
351
292
|
gitURL: "https://github.com/tinacms/tina-docs",
|
|
352
293
|
devUrl: "http://localhost:3000"
|
|
353
294
|
},
|
|
@@ -356,6 +297,20 @@ var TEMPLATES = [
|
|
|
356
297
|
description: "Get started with Astro - a modern static site generator designed for fast, lightweight, and flexible web projects.",
|
|
357
298
|
value: "tina-astro-starter",
|
|
358
299
|
isInternal: false,
|
|
300
|
+
features: [
|
|
301
|
+
{
|
|
302
|
+
name: "Visual Editing",
|
|
303
|
+
description: "\u274C"
|
|
304
|
+
},
|
|
305
|
+
{
|
|
306
|
+
name: "ISR",
|
|
307
|
+
description: "\u274C"
|
|
308
|
+
},
|
|
309
|
+
{
|
|
310
|
+
name: "SSG",
|
|
311
|
+
description: "\u2705"
|
|
312
|
+
}
|
|
313
|
+
],
|
|
359
314
|
gitURL: "https://github.com/tinacms/tina-astro-starter",
|
|
360
315
|
devUrl: "http://localhost:4321"
|
|
361
316
|
},
|
|
@@ -364,6 +319,20 @@ var TEMPLATES = [
|
|
|
364
319
|
description: "With Hugo, you wield the power of lightning-fast site generation, crafting web experiences at the speed of thought.",
|
|
365
320
|
value: "tina-hugo-starter",
|
|
366
321
|
isInternal: false,
|
|
322
|
+
features: [
|
|
323
|
+
{
|
|
324
|
+
name: "Visual Editing",
|
|
325
|
+
description: "\u274C"
|
|
326
|
+
},
|
|
327
|
+
{
|
|
328
|
+
name: "ISR",
|
|
329
|
+
description: "\u274C"
|
|
330
|
+
},
|
|
331
|
+
{
|
|
332
|
+
name: "SSG",
|
|
333
|
+
description: "\u2705"
|
|
334
|
+
}
|
|
335
|
+
],
|
|
367
336
|
gitURL: "https://github.com/tinacms/tina-hugo-starter",
|
|
368
337
|
devUrl: "http://localhost:1313"
|
|
369
338
|
},
|
|
@@ -372,6 +341,20 @@ var TEMPLATES = [
|
|
|
372
341
|
description: "Dive into Remix to orchestrate seamless, interactive user journeys like a maestro of the web.",
|
|
373
342
|
value: "tina-remix-starter",
|
|
374
343
|
isInternal: false,
|
|
344
|
+
features: [
|
|
345
|
+
{
|
|
346
|
+
name: "Visual Editing",
|
|
347
|
+
description: "\u274C"
|
|
348
|
+
},
|
|
349
|
+
{
|
|
350
|
+
name: "ISR",
|
|
351
|
+
description: "\u274C"
|
|
352
|
+
},
|
|
353
|
+
{
|
|
354
|
+
name: "SSG",
|
|
355
|
+
description: "\u26A0\uFE0F Requires adapter"
|
|
356
|
+
}
|
|
357
|
+
],
|
|
375
358
|
gitURL: "https://github.com/tinacms/tina-remix-starter",
|
|
376
359
|
devUrl: "http://localhost:3000"
|
|
377
360
|
},
|
|
@@ -380,14 +363,42 @@ var TEMPLATES = [
|
|
|
380
363
|
description: "Docusaurus empowers you to build and evolve documentation like crafting a living, breathing knowledge repository.",
|
|
381
364
|
value: "tinasaurus",
|
|
382
365
|
isInternal: false,
|
|
366
|
+
features: [
|
|
367
|
+
{
|
|
368
|
+
name: "Visual Editing",
|
|
369
|
+
description: "\u274C"
|
|
370
|
+
},
|
|
371
|
+
{
|
|
372
|
+
name: "ISR",
|
|
373
|
+
description: "\u274C"
|
|
374
|
+
},
|
|
375
|
+
{
|
|
376
|
+
name: "SSR",
|
|
377
|
+
description: "\u2705"
|
|
378
|
+
}
|
|
379
|
+
],
|
|
383
380
|
gitURL: "https://github.com/tinacms/tinasaurus",
|
|
384
381
|
devUrl: "http://localhost:3000"
|
|
385
382
|
},
|
|
386
383
|
{
|
|
387
384
|
title: "Bare bones starter",
|
|
388
|
-
description: "Stripped down to essentials, this starter is the canvas for pure, unadulterated code creativity.",
|
|
385
|
+
description: "Stripped down to essentials, this starter is the canvas for pure, unadulterated code creativity. Built with Next.js.",
|
|
389
386
|
value: "basic",
|
|
390
387
|
isInternal: false,
|
|
388
|
+
features: [
|
|
389
|
+
{
|
|
390
|
+
name: "Visual Editing",
|
|
391
|
+
description: "\u2705"
|
|
392
|
+
},
|
|
393
|
+
{
|
|
394
|
+
name: "ISR",
|
|
395
|
+
description: "\u2705"
|
|
396
|
+
},
|
|
397
|
+
{
|
|
398
|
+
name: "SSG",
|
|
399
|
+
description: "\u2705"
|
|
400
|
+
}
|
|
401
|
+
],
|
|
391
402
|
gitURL: "https://github.com/tinacms/tina-barebones-starter",
|
|
392
403
|
devUrl: "http://localhost:3000"
|
|
393
404
|
}
|
|
@@ -404,8 +415,8 @@ async function downloadTemplate(template, root, spinner) {
|
|
|
404
415
|
)}`;
|
|
405
416
|
await downloadAndExtractRepo(root, repoInfo);
|
|
406
417
|
} else {
|
|
407
|
-
const templateFile =
|
|
408
|
-
await
|
|
418
|
+
const templateFile = path3.join(__dirname, "..", "examples", template.value);
|
|
419
|
+
await copy(`${templateFile}/`, "./");
|
|
409
420
|
}
|
|
410
421
|
}
|
|
411
422
|
|
|
@@ -429,11 +440,11 @@ function preRunChecks(spinner) {
|
|
|
429
440
|
}
|
|
430
441
|
|
|
431
442
|
// src/util/checkPkgManagers.ts
|
|
432
|
-
|
|
443
|
+
import { exec } from "child_process";
|
|
433
444
|
async function checkPackageExists(name2) {
|
|
434
445
|
try {
|
|
435
446
|
await new Promise((resolve, reject) => {
|
|
436
|
-
|
|
447
|
+
exec(`${name2} -v`, (error, stdout, stderr) => {
|
|
437
448
|
if (error) {
|
|
438
449
|
reject(stderr);
|
|
439
450
|
}
|
|
@@ -447,11 +458,14 @@ async function checkPackageExists(name2) {
|
|
|
447
458
|
}
|
|
448
459
|
|
|
449
460
|
// src/index.ts
|
|
450
|
-
|
|
461
|
+
import { exit } from "node:process";
|
|
451
462
|
|
|
452
463
|
// src/util/options.ts
|
|
453
|
-
|
|
454
|
-
|
|
464
|
+
import { Command } from "commander";
|
|
465
|
+
|
|
466
|
+
// package.json
|
|
467
|
+
var name = "create-tina-app";
|
|
468
|
+
var version = "2.0.0";
|
|
455
469
|
|
|
456
470
|
// src/util/packageManagers.ts
|
|
457
471
|
var PKG_MANAGERS = ["npm", "yarn", "pnpm", "bun"];
|
|
@@ -459,8 +473,8 @@ var PKG_MANAGERS = ["npm", "yarn", "pnpm", "bun"];
|
|
|
459
473
|
// src/util/options.ts
|
|
460
474
|
function extractOptions(args) {
|
|
461
475
|
let projectName = "";
|
|
462
|
-
const program = new
|
|
463
|
-
program.version(
|
|
476
|
+
const program = new Command(name);
|
|
477
|
+
program.version(version).option(
|
|
464
478
|
"-t, --template <template>",
|
|
465
479
|
`Choose which template to start from. Valid templates are: ${TEMPLATES.map(
|
|
466
480
|
(x2) => x2.value
|
|
@@ -485,11 +499,111 @@ function extractOptions(args) {
|
|
|
485
499
|
return opts;
|
|
486
500
|
}
|
|
487
501
|
|
|
488
|
-
// src/
|
|
489
|
-
|
|
502
|
+
// src/util/isNpm.js
|
|
503
|
+
import { builtinModules as builtins } from "node:module";
|
|
504
|
+
function validate(name2) {
|
|
505
|
+
if (name2 === null) {
|
|
506
|
+
return {
|
|
507
|
+
message: "name cannot be null",
|
|
508
|
+
isError: true
|
|
509
|
+
};
|
|
510
|
+
}
|
|
511
|
+
if (name2 === void 0) {
|
|
512
|
+
return {
|
|
513
|
+
message: "name cannot be undefined",
|
|
514
|
+
isError: true
|
|
515
|
+
};
|
|
516
|
+
}
|
|
517
|
+
if (typeof name2 !== "string") {
|
|
518
|
+
return {
|
|
519
|
+
message: "name must be a string",
|
|
520
|
+
isError: true
|
|
521
|
+
};
|
|
522
|
+
}
|
|
523
|
+
if (!name2.length) {
|
|
524
|
+
return {
|
|
525
|
+
message: "name length must be greater than zero",
|
|
526
|
+
isError: true
|
|
527
|
+
};
|
|
528
|
+
}
|
|
529
|
+
if (name2.startsWith(".")) {
|
|
530
|
+
return {
|
|
531
|
+
message: "name cannot start with a period",
|
|
532
|
+
isError: true
|
|
533
|
+
};
|
|
534
|
+
}
|
|
535
|
+
if (name2.match(/^_/)) {
|
|
536
|
+
return {
|
|
537
|
+
message: "name cannot start with an underscore",
|
|
538
|
+
isError: true
|
|
539
|
+
};
|
|
540
|
+
}
|
|
541
|
+
if (name2.trim() !== name2) {
|
|
542
|
+
return {
|
|
543
|
+
message: "name cannot contain leading or trailing spaces",
|
|
544
|
+
isError: true
|
|
545
|
+
};
|
|
546
|
+
}
|
|
547
|
+
const exclusionList = ["node_modules", "favicon.ico"];
|
|
548
|
+
exclusionList.forEach(function(excludedName) {
|
|
549
|
+
if (name2.toLowerCase() === excludedName) {
|
|
550
|
+
return {
|
|
551
|
+
message: excludedName + " is not a valid package name",
|
|
552
|
+
isError: true
|
|
553
|
+
};
|
|
554
|
+
}
|
|
555
|
+
});
|
|
556
|
+
if (builtins.includes(name2.toLowerCase())) {
|
|
557
|
+
return {
|
|
558
|
+
message: name2 + " is a core module name",
|
|
559
|
+
isError: true
|
|
560
|
+
};
|
|
561
|
+
}
|
|
562
|
+
if (name2.length > 214) {
|
|
563
|
+
return {
|
|
564
|
+
message: "name can no longer contain more than 214 characters",
|
|
565
|
+
isError: true
|
|
566
|
+
};
|
|
567
|
+
}
|
|
568
|
+
if (name2.toLowerCase() !== name2) {
|
|
569
|
+
return {
|
|
570
|
+
message: "name can no longer contain capital letters",
|
|
571
|
+
isError: true
|
|
572
|
+
};
|
|
573
|
+
}
|
|
574
|
+
if (/[~'!()*]/.test(name2.split("/").slice(-1)[0])) {
|
|
575
|
+
return {
|
|
576
|
+
message: `name can no longer contain special characters ("~'!()*")`,
|
|
577
|
+
isError: true
|
|
578
|
+
};
|
|
579
|
+
}
|
|
580
|
+
if (encodeURIComponent(name2) !== name2) {
|
|
581
|
+
const scopedPackagePattern = new RegExp("^(?:@([^/]+?)[/])?([^/]+?)$");
|
|
582
|
+
const nameMatch = name2.match(scopedPackagePattern);
|
|
583
|
+
if (nameMatch) {
|
|
584
|
+
const user = nameMatch[1];
|
|
585
|
+
const pkg = nameMatch[2];
|
|
586
|
+
if (pkg.startsWith(".")) {
|
|
587
|
+
return {
|
|
588
|
+
message: "name cannot start with a period",
|
|
589
|
+
isError: true
|
|
590
|
+
};
|
|
591
|
+
}
|
|
592
|
+
if (encodeURIComponent(user) === user && encodeURIComponent(pkg) === pkg) {
|
|
593
|
+
return { message: null, isError: false };
|
|
594
|
+
}
|
|
595
|
+
}
|
|
596
|
+
return {
|
|
597
|
+
message: "name can only contain URL-friendly characters",
|
|
598
|
+
isError: true
|
|
599
|
+
};
|
|
600
|
+
}
|
|
601
|
+
return { message: null, isError: false };
|
|
602
|
+
}
|
|
490
603
|
|
|
491
604
|
// src/util/asciiArt.ts
|
|
492
605
|
var llama = " :--=: \n :-===- \n -=====- \n -=======. \n .=========-. \n :===========--:\n -=============.\n .==========-:. \n :=========-. \n -=========- \n .==========- \n -==========- \n :===========- \n -=============. \n :==============: \n :===============- \n .:-================- \n ..::---==================== \n ....::::::::::-------============================. \n .---=================================================: \n .-=====================================================- \n:=======================================================. \n .-====================================================. \n .-=================================================. \n :=============================================- \n -============================================. \n .============-:. -==========- \n :=========-: .. -==========. \n -========: :-=- -=========- \n .========. .-==== :=========: \n -=======: :=====. -========: \n -======- -====- -=======: \n -=====: -====: :======. \n .=====. -====. .-====- \n :==== -===- -====: \n -==- :===- :====. ";
|
|
606
|
+
var errorArt = " ++++++++++++++\u2260 \n +++++++++\u2248 \u03C0+++++++++\u2260 \n ++++ ++++ \n +++ +++\u2248 \n +++ +++ \n \u03C0++ +++ \n ++ ++ \n +- +\u03C0 \n ++\xD7 +++++++++ \u2260+++++++++ \u221A+++++++++ ++ \n + ++ \u2248+++ ++ ++ ++++ +\u221E \n ++ ++ ++ ++ ++ ++ + \n ++ ++ ++ ++ ++ ++ ++ \n ++ ++-+++++++- ++ ++ +++++++- + \n \u221A+ ++\xF7+++++ ++ ++++++++ ++ \n ++ ++ \u221E++ ++ ++ ++ \n ++ ++ +++ ++ ++ ++ \n ++ ++ +++ \u2260+++++++++ ++ \u2260+ \n ++ ++ ++ +\u2260\u221E\u221A\u221A\u2260\xD7+\u03C0 ++ \u2260+ \n ++ \u2260+ \n ++ \u2260+ \n ++ +++ \u2260+ \n ++ ++++ \u2260+ \n ++ ++++++++ \u2260+ \n ++ ++++++++++ =+ \n ++ ++++++ =+ \n ++ \u2248++++++ =+ \n ++ +++++++ \u2260+ \n ++ +++++++ \u2260+ \n ++ +++++++ =+ \n ++ ++++++++ =+ \n ++ \u221E++++++++++++ \u2260+ \n ++ \u221E++++++++++++++++++++++++++++++- =+ \n ++ +++++++++++++++++++++++++++++++++ \u2260+ \n ++ +++++++++++++++++++++++++++++++++ \u2260+ \n ++ ++++++++++++++++++++++++++++++ \u2260+ \n ++ +++++++++++++++++++++++++++++ \u2260+ \n ++ ++++++++++++++++++++++++++++ \u2260+ \n ++ ++++++++\u2260\u2260++++++=\u221A ++++++++ \u2260+ \n ++ ++++++ + +++++++ \u2260+ \n ++ +++++ \u221E+++ \xF7++++++ \u2260+ \n ++ ++++ +++ +++++\u221A \u2260+ \n ++ +++= +++\u221A ++++ \u2260+ \n ++ ++\u221E =++ +++ \u2260+ \n ++ ++\u2248 +++ ++\xF7 =+ \n ++ +++ +++\u2260 +++ =+ \n ++ \u2260+ \n ++ + \n \u2248+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ \n ++ +\u2260 \n ++ +++++++++ ++++++++ +++++++ ++++++ ++++++++ +\u2260 \n ++ ++ ++ ++ + ++ ++ ++ ++ ++ +\u2260 \n ++ ++ ++ ++ + ++ ++ ++ ++ ++ +\u2260 \n ++ ++++++++ ++++++++ ++++++++ ++ ++ ++++++++ +\u2260 \n ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ +\u2260 \n ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ +\u2260 \n ++ +++++++++ ++ ++ ++ ++ +++++++ ++ ++ +\u2260 \n ++ +\u2260 \n ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ \n \n ";
|
|
493
607
|
var tinaCms = "\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2557\u2588\u2588\u2557\u2588\u2588\u2588\u2557 \u2588\u2588\u2557 \u2588\u2588\u2588\u2588\u2588\u2557 \u2588\u2588\u2588\u2588\u2588\u2588\u2557\u2588\u2588\u2588\u2557 \u2588\u2588\u2588\u2557\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2557\n\u255A\u2550\u2550\u2588\u2588\u2554\u2550\u2550\u255D\u2588\u2588\u2551\u2588\u2588\u2588\u2588\u2557 \u2588\u2588\u2551\u2588\u2588\u2554\u2550\u2550\u2588\u2588\u2557\u2588\u2588\u2554\u2550\u2550\u2550\u2550\u255D\u2588\u2588\u2588\u2588\u2557 \u2588\u2588\u2588\u2588\u2551\u2588\u2588\u2554\u2550\u2550\u2550\u2550\u255D\n \u2588\u2588\u2551 \u2588\u2588\u2551\u2588\u2588\u2554\u2588\u2588\u2557 \u2588\u2588\u2551\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2551\u2588\u2588\u2551 \u2588\u2588\u2554\u2588\u2588\u2588\u2588\u2554\u2588\u2588\u2551\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2557\n \u2588\u2588\u2551 \u2588\u2588\u2551\u2588\u2588\u2551\u255A\u2588\u2588\u2557\u2588\u2588\u2551\u2588\u2588\u2554\u2550\u2550\u2588\u2588\u2551\u2588\u2588\u2551 \u2588\u2588\u2551\u255A\u2588\u2588\u2554\u255D\u2588\u2588\u2551\u255A\u2550\u2550\u2550\u2550\u2588\u2588\u2551\n \u2588\u2588\u2551 \u2588\u2588\u2551\u2588\u2588\u2551 \u255A\u2588\u2588\u2588\u2588\u2551\u2588\u2588\u2551 \u2588\u2588\u2551\u255A\u2588\u2588\u2588\u2588\u2588\u2588\u2557\u2588\u2588\u2551 \u255A\u2550\u255D \u2588\u2588\u2551\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2551\n \u255A\u2550\u255D \u255A\u2550\u255D\u255A\u2550\u255D \u255A\u2550\u2550\u2550\u255D\u255A\u2550\u255D \u255A\u2550\u255D \u255A\u2550\u2550\u2550\u2550\u2550\u255D\u255A\u2550\u255D \u255A\u2550\u255D\u255A\u2550\u2550\u2550\u2550\u2550\u2550\u255D";
|
|
494
608
|
|
|
495
609
|
// src/themes.ts
|
|
@@ -527,6 +641,92 @@ var THEMES = [
|
|
|
527
641
|
];
|
|
528
642
|
|
|
529
643
|
// src/index.ts
|
|
644
|
+
import { PostHog } from "posthog-node";
|
|
645
|
+
|
|
646
|
+
// src/util/posthog.ts
|
|
647
|
+
var CreateTinaAppStartedEvent = "create-tina-app-started";
|
|
648
|
+
var CreateTinaAppFinishedEvent = "create-tina-app-finished";
|
|
649
|
+
function postHogCapture(client, event, properties) {
|
|
650
|
+
if (process.env.TINA_DEV === "true") return;
|
|
651
|
+
if (!client) {
|
|
652
|
+
console.error(`PostHog client not initialized`);
|
|
653
|
+
return;
|
|
654
|
+
}
|
|
655
|
+
try {
|
|
656
|
+
client.capture({
|
|
657
|
+
distinctId: "create-tina-app",
|
|
658
|
+
event,
|
|
659
|
+
properties: {
|
|
660
|
+
...properties,
|
|
661
|
+
system: "tinacms/create-tina-app"
|
|
662
|
+
}
|
|
663
|
+
});
|
|
664
|
+
} catch (error) {
|
|
665
|
+
console.error("Error capturing event:", error);
|
|
666
|
+
}
|
|
667
|
+
}
|
|
668
|
+
|
|
669
|
+
// src/util/fetchPosthogConfig.tsx
|
|
670
|
+
async function fetchPostHogConfig(endpointUrl) {
|
|
671
|
+
try {
|
|
672
|
+
const response = await fetch(endpointUrl, {
|
|
673
|
+
method: "GET",
|
|
674
|
+
headers: {
|
|
675
|
+
"Content-Type": "application/json"
|
|
676
|
+
}
|
|
677
|
+
});
|
|
678
|
+
if (!response.ok) {
|
|
679
|
+
throw new Error(`Failed to fetch PostHog config: ${response.statusText}`);
|
|
680
|
+
}
|
|
681
|
+
const config = await response.json();
|
|
682
|
+
return {
|
|
683
|
+
POSTHOG_API_KEY: config.api_key,
|
|
684
|
+
POSTHOG_ENDPOINT: config.host
|
|
685
|
+
};
|
|
686
|
+
} catch (error) {
|
|
687
|
+
console.warn(
|
|
688
|
+
`Failed to fetch PostHog config from endpoint: ${error instanceof Error ? error.message : "Unknown error"}`
|
|
689
|
+
);
|
|
690
|
+
return {};
|
|
691
|
+
}
|
|
692
|
+
}
|
|
693
|
+
|
|
694
|
+
// src/index.ts
|
|
695
|
+
import os from "node:os";
|
|
696
|
+
var posthogClient = null;
|
|
697
|
+
async function initializePostHog(configEndpoint) {
|
|
698
|
+
let apiKey;
|
|
699
|
+
let endpoint;
|
|
700
|
+
if (configEndpoint) {
|
|
701
|
+
const config = await fetchPostHogConfig(configEndpoint);
|
|
702
|
+
apiKey = config.POSTHOG_API_KEY;
|
|
703
|
+
endpoint = config.POSTHOG_ENDPOINT;
|
|
704
|
+
}
|
|
705
|
+
if (!apiKey) {
|
|
706
|
+
console.warn(
|
|
707
|
+
"PostHog API key not found. PostHog tracking will be disabled."
|
|
708
|
+
);
|
|
709
|
+
return null;
|
|
710
|
+
}
|
|
711
|
+
return new PostHog(apiKey, {
|
|
712
|
+
host: endpoint
|
|
713
|
+
});
|
|
714
|
+
}
|
|
715
|
+
function formatTemplateChoice(template) {
|
|
716
|
+
let description = template.description || "";
|
|
717
|
+
if (template.features && template.features.length > 0) {
|
|
718
|
+
const featuresText = template.features.map((feature) => ` \u2022 ${feature.name}: ${feature.description}`).join("\n");
|
|
719
|
+
description = `${description}
|
|
720
|
+
|
|
721
|
+
Features:
|
|
722
|
+
${featuresText}`;
|
|
723
|
+
}
|
|
724
|
+
return {
|
|
725
|
+
title: template.title,
|
|
726
|
+
value: template.value,
|
|
727
|
+
description
|
|
728
|
+
};
|
|
729
|
+
}
|
|
530
730
|
async function run() {
|
|
531
731
|
const ora = (await import("ora")).default;
|
|
532
732
|
let packageManagerInstallationHadError = false;
|
|
@@ -536,12 +736,34 @@ async function run() {
|
|
|
536
736
|
} else {
|
|
537
737
|
console.log(TextStyles.tinaOrange(`\u{1F999} TinaCMS`));
|
|
538
738
|
}
|
|
539
|
-
const
|
|
739
|
+
const require2 = createRequire(import.meta.url);
|
|
740
|
+
const version2 = require2("../package.json").version;
|
|
540
741
|
console.log(`Create Tina App v${version2}`);
|
|
742
|
+
const opts = extractOptions(process.argv);
|
|
743
|
+
if (!opts.noTelemetry) {
|
|
744
|
+
console.log(`
|
|
745
|
+
${TextStylesBold.bold("Telemetry Notice")}`);
|
|
746
|
+
console.log(
|
|
747
|
+
`To help the TinaCMS team improve the developer experience, create-tina-app collects anonymous usage statistics. This data helps us understand which environments and features are most important to support. Usage analytics may include: Operating system and version, package manager name and version (local only), Node.js version (local only), and the selected TinaCMS starter template.
|
|
748
|
+
No personal or project-specific code is ever collected. You can opt out at any time by passing the --noTelemetry flag.
|
|
749
|
+
`
|
|
750
|
+
);
|
|
751
|
+
}
|
|
752
|
+
if (!opts.noTelemetry) {
|
|
753
|
+
posthogClient = await initializePostHog(
|
|
754
|
+
"https://identity-v2.tinajs.io/v2/posthog-token"
|
|
755
|
+
);
|
|
756
|
+
}
|
|
541
757
|
const spinner = ora();
|
|
542
758
|
preRunChecks(spinner);
|
|
543
|
-
|
|
544
|
-
|
|
759
|
+
if (!opts.noTelemetry && posthogClient) {
|
|
760
|
+
postHogCapture(posthogClient, CreateTinaAppStartedEvent, {
|
|
761
|
+
"node-version": process.version,
|
|
762
|
+
"os-version": os.version(),
|
|
763
|
+
"os-platform": os.platform()
|
|
764
|
+
});
|
|
765
|
+
}
|
|
766
|
+
const telemetry = new Telemetry({ disabled: opts?.noTelemetry });
|
|
545
767
|
let template = null;
|
|
546
768
|
if (opts.template) {
|
|
547
769
|
template = TEMPLATES.find((_template) => _template.value === opts.template);
|
|
@@ -551,7 +773,7 @@ async function run() {
|
|
|
551
773
|
(x2) => x2.value
|
|
552
774
|
)}`
|
|
553
775
|
);
|
|
554
|
-
|
|
776
|
+
exit(1);
|
|
555
777
|
}
|
|
556
778
|
}
|
|
557
779
|
let pkgManager = opts.pkgManager;
|
|
@@ -560,7 +782,7 @@ async function run() {
|
|
|
560
782
|
spinner.fail(
|
|
561
783
|
`The provided package manager '${opts.pkgManager}' is not supported. Please provide one of the following: ${PKG_MANAGERS}`
|
|
562
784
|
);
|
|
563
|
-
|
|
785
|
+
exit(1);
|
|
564
786
|
}
|
|
565
787
|
}
|
|
566
788
|
if (!pkgManager) {
|
|
@@ -574,9 +796,9 @@ async function run() {
|
|
|
574
796
|
spinner.fail(
|
|
575
797
|
`You have no supported package managers installed. Please install one of the following: ${PKG_MANAGERS}`
|
|
576
798
|
);
|
|
577
|
-
|
|
799
|
+
exit(1);
|
|
578
800
|
}
|
|
579
|
-
const res = await (
|
|
801
|
+
const res = await prompts({
|
|
580
802
|
message: "Which package manager would you like to use?",
|
|
581
803
|
name: "packageManager",
|
|
582
804
|
type: "select",
|
|
@@ -584,46 +806,46 @@ async function run() {
|
|
|
584
806
|
return { title: manager, value: manager };
|
|
585
807
|
})
|
|
586
808
|
});
|
|
587
|
-
if (!Object.hasOwn(res, "packageManager"))
|
|
809
|
+
if (!Object.hasOwn(res, "packageManager")) exit(1);
|
|
588
810
|
pkgManager = res.packageManager;
|
|
589
811
|
}
|
|
590
812
|
let projectName = opts.projectName;
|
|
591
813
|
if (!projectName) {
|
|
592
|
-
const res = await (
|
|
814
|
+
const res = await prompts({
|
|
593
815
|
name: "name",
|
|
594
816
|
type: "text",
|
|
595
817
|
message: "What is your project named?",
|
|
596
818
|
initial: "my-tina-app",
|
|
597
819
|
validate: (name2) => {
|
|
598
|
-
const {
|
|
599
|
-
|
|
820
|
+
const { message, isError } = validate(
|
|
821
|
+
path4.basename(path4.resolve(name2))
|
|
600
822
|
);
|
|
601
|
-
if (
|
|
602
|
-
return
|
|
823
|
+
if (isError) return `Invalid project name: ${message}`;
|
|
824
|
+
return true;
|
|
603
825
|
}
|
|
604
826
|
});
|
|
605
|
-
if (!Object.hasOwn(res, "name"))
|
|
827
|
+
if (!Object.hasOwn(res, "name")) exit(1);
|
|
606
828
|
projectName = res.name;
|
|
607
829
|
}
|
|
608
830
|
if (!template) {
|
|
609
|
-
const res = await (
|
|
831
|
+
const res = await prompts({
|
|
610
832
|
name: "template",
|
|
611
833
|
type: "select",
|
|
612
834
|
message: "What starter code would you like to use?",
|
|
613
|
-
choices: TEMPLATES
|
|
835
|
+
choices: TEMPLATES.map(formatTemplateChoice)
|
|
614
836
|
});
|
|
615
|
-
if (!Object.hasOwn(res, "template"))
|
|
837
|
+
if (!Object.hasOwn(res, "template")) exit(1);
|
|
616
838
|
template = TEMPLATES.find((_template) => _template.value === res.template);
|
|
617
839
|
}
|
|
618
840
|
let themeChoice;
|
|
619
841
|
if (template.value === "tina-docs") {
|
|
620
|
-
const res = await (
|
|
842
|
+
const res = await prompts({
|
|
621
843
|
name: "theme",
|
|
622
844
|
type: "select",
|
|
623
845
|
message: "What theme would you like to use?",
|
|
624
846
|
choices: THEMES
|
|
625
847
|
});
|
|
626
|
-
if (!Object.hasOwn(res, "theme"))
|
|
848
|
+
if (!Object.hasOwn(res, "theme")) exit(1);
|
|
627
849
|
themeChoice = res.theme;
|
|
628
850
|
}
|
|
629
851
|
await telemetry.submitRecord({
|
|
@@ -633,8 +855,8 @@ async function run() {
|
|
|
633
855
|
pkgManager
|
|
634
856
|
}
|
|
635
857
|
});
|
|
636
|
-
const rootDir =
|
|
637
|
-
if (!await isWriteable(
|
|
858
|
+
const rootDir = path4.join(process.cwd(), projectName);
|
|
859
|
+
if (!await isWriteable(path4.dirname(rootDir))) {
|
|
638
860
|
spinner.fail(
|
|
639
861
|
"The application path is not writable, please check folder permissions and try again. It is likely you do not have write permissions for this folder."
|
|
640
862
|
);
|
|
@@ -645,10 +867,9 @@ async function run() {
|
|
|
645
867
|
appName = await setupProjectDirectory(rootDir);
|
|
646
868
|
} catch (err) {
|
|
647
869
|
spinner.fail(err.message);
|
|
648
|
-
|
|
870
|
+
exit(1);
|
|
649
871
|
}
|
|
650
872
|
try {
|
|
651
|
-
await downloadTemplate(template, rootDir, spinner);
|
|
652
873
|
if (themeChoice) {
|
|
653
874
|
await updateThemeSettings(rootDir, themeChoice);
|
|
654
875
|
}
|
|
@@ -661,7 +882,7 @@ async function run() {
|
|
|
661
882
|
spinner.succeed();
|
|
662
883
|
} catch (err) {
|
|
663
884
|
spinner.fail(`Failed to download template: ${err.message}`);
|
|
664
|
-
|
|
885
|
+
exit(1);
|
|
665
886
|
}
|
|
666
887
|
spinner.start("Installing packages.");
|
|
667
888
|
try {
|
|
@@ -684,7 +905,9 @@ async function run() {
|
|
|
684
905
|
`);
|
|
685
906
|
if (template.value === "tina-hugo-starter") {
|
|
686
907
|
spinner.warn(
|
|
687
|
-
`Hugo is required for this starter. Install it via ${TextStyles.link(
|
|
908
|
+
`Hugo is required for this starter. Install it via ${TextStyles.link(
|
|
909
|
+
"https://gohugo.io/installation/"
|
|
910
|
+
)}
|
|
688
911
|
`
|
|
689
912
|
);
|
|
690
913
|
}
|
|
@@ -693,28 +916,54 @@ async function run() {
|
|
|
693
916
|
|
|
694
917
|
${padCommand(`cd ${appName}`)}# move into your project directory${packageManagerInstallationHadError ? `
|
|
695
918
|
${padCommand(`${pkgManager} install`)}# install dependencies` : ""}
|
|
696
|
-
${padCommand(
|
|
919
|
+
${padCommand(
|
|
920
|
+
`${pkgManager} run dev`
|
|
921
|
+
)}# start the dev server ${TextStyles.link(template.devUrl)}
|
|
697
922
|
${padCommand(`${pkgManager} run build`)}# build the app for production
|
|
698
923
|
`);
|
|
699
924
|
console.log("Next steps:");
|
|
700
925
|
console.log(
|
|
701
|
-
` \u2022 \u{1F4DD} Edit some content: ${TextStyles.link(
|
|
926
|
+
` \u2022 \u{1F4DD} Edit some content: ${TextStyles.link(
|
|
927
|
+
"https://tina.io/docs/using-tina-editor"
|
|
928
|
+
)}`
|
|
702
929
|
);
|
|
703
930
|
console.log(
|
|
704
|
-
` \u2022 \u{1F4D6} Learn the basics: ${TextStyles.link(
|
|
931
|
+
` \u2022 \u{1F4D6} Learn the basics: ${TextStyles.link(
|
|
932
|
+
"https://tina.io/docs/schema/"
|
|
933
|
+
)}`
|
|
705
934
|
);
|
|
706
935
|
console.log(
|
|
707
|
-
` \u2022 \u{1F58C}\uFE0F Extend Tina with custom field components: ${TextStyles.link(
|
|
936
|
+
` \u2022 \u{1F58C}\uFE0F Extend Tina with custom field components: ${TextStyles.link(
|
|
937
|
+
"https://tina.io/docs/advanced/extending-tina/"
|
|
938
|
+
)}`
|
|
708
939
|
);
|
|
709
940
|
console.log(
|
|
710
|
-
` \u2022 \u{1F680} Deploy to Production: ${TextStyles.link(
|
|
941
|
+
` \u2022 \u{1F680} Deploy to Production: ${TextStyles.link(
|
|
942
|
+
"https://tina.io/docs/tinacloud/"
|
|
943
|
+
)}`
|
|
711
944
|
);
|
|
945
|
+
if (!opts.noTelemetry && posthogClient) {
|
|
946
|
+
postHogCapture(posthogClient, CreateTinaAppFinishedEvent, {
|
|
947
|
+
template: template.value,
|
|
948
|
+
"package-manager": pkgManager,
|
|
949
|
+
"node-version": process.version,
|
|
950
|
+
"app-name": appName,
|
|
951
|
+
"os-version": os.version(),
|
|
952
|
+
"os-platform": os.platform()
|
|
953
|
+
});
|
|
954
|
+
}
|
|
712
955
|
}
|
|
713
956
|
run().catch((error) => {
|
|
957
|
+
if (process.stdout.columns >= 60) {
|
|
958
|
+
console.log(TextStyles.tinaOrange(`${errorArt}`));
|
|
959
|
+
}
|
|
714
960
|
console.error("Error running create-tina-app:", error);
|
|
715
961
|
process.exit(1);
|
|
962
|
+
}).then(async () => {
|
|
963
|
+
if (posthogClient) {
|
|
964
|
+
await posthogClient.shutdown();
|
|
965
|
+
}
|
|
716
966
|
});
|
|
717
|
-
|
|
718
|
-
0 && (module.exports = {
|
|
967
|
+
export {
|
|
719
968
|
run
|
|
720
|
-
}
|
|
969
|
+
};
|
package/dist/templates.d.ts
CHANGED
|
@@ -1,7 +1,12 @@
|
|
|
1
1
|
import { Ora } from 'ora';
|
|
2
|
+
type Feature = {
|
|
3
|
+
name: string;
|
|
4
|
+
description: string;
|
|
5
|
+
};
|
|
2
6
|
export type BaseExample = {
|
|
3
7
|
title: string;
|
|
4
8
|
description?: string;
|
|
9
|
+
features?: Feature[];
|
|
5
10
|
value: string;
|
|
6
11
|
devUrl: string;
|
|
7
12
|
};
|
|
@@ -15,3 +20,4 @@ export type ExternalTemplate = BaseExample & {
|
|
|
15
20
|
export type Template = InternalTemplate | ExternalTemplate;
|
|
16
21
|
export declare const TEMPLATES: Template[];
|
|
17
22
|
export declare function downloadTemplate(template: Template, root: string, spinner: Ora): Promise<void>;
|
|
23
|
+
export {};
|
package/dist/util/asciiArt.d.ts
CHANGED
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @typedef {Object} ValidationResult
|
|
3
|
+
* @property {string | null} message
|
|
4
|
+
* @property {boolean} isError
|
|
5
|
+
*/
|
|
6
|
+
/**
|
|
7
|
+
* Validates whether the provided name is valid on NPM.
|
|
8
|
+
*
|
|
9
|
+
* @param {string} name
|
|
10
|
+
* @returns {ValidationResult}
|
|
11
|
+
*/
|
|
12
|
+
export default function validate(name: string): ValidationResult;
|
|
13
|
+
export type ValidationResult = {
|
|
14
|
+
message: string | null;
|
|
15
|
+
isError: boolean;
|
|
16
|
+
};
|
|
@@ -1,11 +1,20 @@
|
|
|
1
|
-
import chalk from 'chalk';
|
|
2
1
|
export declare const TextStyles: {
|
|
3
|
-
tinaOrange: chalk.
|
|
2
|
+
tinaOrange: import("chalk").ChalkInstance;
|
|
4
3
|
link: (url: string) => string;
|
|
5
|
-
cmd: chalk.
|
|
6
|
-
info: chalk.
|
|
7
|
-
success: chalk.
|
|
8
|
-
warn: chalk.
|
|
9
|
-
err: chalk.
|
|
10
|
-
bold: chalk.
|
|
4
|
+
cmd: import("chalk").ChalkInstance;
|
|
5
|
+
info: import("chalk").ChalkInstance;
|
|
6
|
+
success: import("chalk").ChalkInstance;
|
|
7
|
+
warn: import("chalk").ChalkInstance;
|
|
8
|
+
err: import("chalk").ChalkInstance;
|
|
9
|
+
bold: import("chalk").ChalkInstance;
|
|
10
|
+
};
|
|
11
|
+
export declare const TextStylesBold: {
|
|
12
|
+
tinaOrange: import("chalk").ChalkInstance;
|
|
13
|
+
link: (url: string) => string;
|
|
14
|
+
cmd: import("chalk").ChalkInstance;
|
|
15
|
+
info: import("chalk").ChalkInstance;
|
|
16
|
+
success: import("chalk").ChalkInstance;
|
|
17
|
+
warn: import("chalk").ChalkInstance;
|
|
18
|
+
err: import("chalk").ChalkInstance;
|
|
19
|
+
bold: import("chalk").ChalkInstance;
|
|
11
20
|
};
|
package/package.json
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "create-tina-app",
|
|
3
|
-
"version": "0.0.0-
|
|
3
|
+
"version": "0.0.0-db7231c-20251216055550",
|
|
4
|
+
"type": "module",
|
|
4
5
|
"main": "dist/index.js",
|
|
5
6
|
"files": [
|
|
6
7
|
"dist",
|
|
@@ -35,18 +36,18 @@
|
|
|
35
36
|
"@types/prompts": "^2.4.9",
|
|
36
37
|
"@types/tar": "6.1.13",
|
|
37
38
|
"typescript": "^5.7.3",
|
|
38
|
-
"@tinacms/scripts": "
|
|
39
|
+
"@tinacms/scripts": "1.4.2"
|
|
39
40
|
},
|
|
40
41
|
"dependencies": {
|
|
41
|
-
"chalk": "4.1
|
|
42
|
+
"chalk": "^5.4.1",
|
|
42
43
|
"commander": "^12.1.0",
|
|
43
44
|
"cross-spawn": "^7.0.6",
|
|
44
45
|
"fs-extra": "^11.3.0",
|
|
45
46
|
"ora": "^8.2.0",
|
|
47
|
+
"posthog-node": "^5.17.2",
|
|
46
48
|
"prompts": "^2.4.2",
|
|
47
49
|
"tar": "7.4.0",
|
|
48
|
-
"
|
|
49
|
-
"@tinacms/metrics": "1.1.0"
|
|
50
|
+
"@tinacms/metrics": "2.0.1"
|
|
50
51
|
},
|
|
51
52
|
"scripts": {
|
|
52
53
|
"types": "pnpm tsc",
|