create-snappy 0.0.10 → 0.0.12
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.js +108 -75
- package/package.json +6 -6
package/dist/index.js
CHANGED
|
@@ -1,31 +1,38 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
|
|
3
3
|
// src/index.ts
|
|
4
|
-
import
|
|
5
|
-
import
|
|
6
|
-
import
|
|
7
|
-
import
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
4
|
+
import fs2 from "fs";
|
|
5
|
+
import path2 from "path";
|
|
6
|
+
import kleur2 from "kleur";
|
|
7
|
+
import prompts2 from "prompts";
|
|
8
|
+
|
|
9
|
+
// src/constants.ts
|
|
10
|
+
var SNAPPY_API_URL = "https://core.wicky.id";
|
|
11
|
+
var SNAPPY_TEMPLATE_REPO = "github.com/Snappy-Stack/Snappy_Template";
|
|
12
|
+
var SNAPPY_VERSION = "0.0.12";
|
|
13
|
+
var TEMPLATES = [
|
|
14
|
+
{ title: "Portfolio", value: "portfolio", description: "Personal branding & projects" },
|
|
15
|
+
{ title: "Portfolio + Services", value: "portfolio-services", description: "Portfolio with lead capture" },
|
|
16
|
+
{ title: "Institution", value: "institution", description: "Schools, NGOs, Organization" },
|
|
17
|
+
{ title: "Store", value: "store", description: "Simple e-commerce primitives" },
|
|
18
|
+
{ title: "Artist / Karya", value: "artist", description: "Musicians, singers, creatives" }
|
|
19
|
+
];
|
|
20
|
+
|
|
21
|
+
// src/api.ts
|
|
22
|
+
async function validateToken(token) {
|
|
23
|
+
const res = await fetch(`${SNAPPY_API_URL}/v1/heartbeat`, {
|
|
24
|
+
headers: { Authorization: `Bearer ${token}` }
|
|
25
|
+
});
|
|
26
|
+
if (!res.ok) {
|
|
27
|
+
throw new Error("Invalid SNAPPY_TOKEN");
|
|
27
28
|
}
|
|
28
|
-
|
|
29
|
+
return await res.json();
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
// src/prompts.ts
|
|
33
|
+
import prompts from "prompts";
|
|
34
|
+
async function askQuestions() {
|
|
35
|
+
return await prompts([
|
|
29
36
|
{
|
|
30
37
|
type: "text",
|
|
31
38
|
name: "projectName",
|
|
@@ -37,19 +44,14 @@ async function main() {
|
|
|
37
44
|
type: "select",
|
|
38
45
|
name: "template",
|
|
39
46
|
message: "Choose a starting template:",
|
|
40
|
-
choices:
|
|
41
|
-
{ title: "Portfolio", value: "portfolio", description: "Personal branding & projects" },
|
|
42
|
-
{ title: "Portfolio + Services", value: "portfolio-services", description: "Portfolio with lead capture" },
|
|
43
|
-
{ title: "Institution", value: "institution", description: "Schools, NGOs, Organization" },
|
|
44
|
-
{ title: "Store", value: "store", description: "Simple e-commerce primitives" }
|
|
45
|
-
],
|
|
47
|
+
choices: TEMPLATES,
|
|
46
48
|
initial: 0
|
|
47
49
|
},
|
|
48
50
|
{
|
|
49
51
|
type: "password",
|
|
50
52
|
name: "token",
|
|
51
53
|
message: "Enter your SNAPPY_TOKEN:",
|
|
52
|
-
validate: (value) => value.startsWith("
|
|
54
|
+
validate: (value) => value.startsWith("eyJ") || "Invalid SNAPPY_TOKEN format"
|
|
53
55
|
},
|
|
54
56
|
{
|
|
55
57
|
type: "text",
|
|
@@ -75,67 +77,98 @@ async function main() {
|
|
|
75
77
|
initial: 0
|
|
76
78
|
}
|
|
77
79
|
]);
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
// src/setup.ts
|
|
83
|
+
import fs from "fs";
|
|
84
|
+
import path from "path";
|
|
85
|
+
import { execSync } from "child_process";
|
|
86
|
+
import kleur from "kleur";
|
|
87
|
+
function runSetup(targetDir, options) {
|
|
88
|
+
const { projectName, template, token, domain, githubToken, locale } = options;
|
|
89
|
+
console.log(kleur.blue(`
|
|
90
|
+
\u{1F4E6} Cloning [${template}] template...`));
|
|
91
|
+
try {
|
|
92
|
+
const cloneUrl = `https://${githubToken}@${SNAPPY_TEMPLATE_REPO}`;
|
|
93
|
+
execSync(`git clone --depth 1 -b ${template} ${cloneUrl} "${targetDir}"`, { stdio: "inherit" });
|
|
94
|
+
fs.rmSync(path.join(targetDir, ".git"), { recursive: true, force: true });
|
|
95
|
+
const npmrcContent = `//npm.pkg.github.com/:_authToken=${githubToken}
|
|
96
|
+
@snappy:registry=https://npm.pkg.github.com`;
|
|
97
|
+
fs.writeFileSync(path.join(targetDir, ".npmrc"), npmrcContent);
|
|
98
|
+
const pkgPath = path.join(targetDir, "package.json");
|
|
99
|
+
if (fs.existsSync(pkgPath)) {
|
|
100
|
+
const pkg = JSON.parse(fs.readFileSync(pkgPath, "utf8"));
|
|
101
|
+
pkg.name = projectName.toLowerCase().replace(/\s+/g, "-");
|
|
102
|
+
fs.writeFileSync(pkgPath, JSON.stringify(pkg, null, 2));
|
|
103
|
+
}
|
|
104
|
+
const envContent = `# SNAPPY CMS - Site Configuration
|
|
105
|
+
SNAPPY_TOKEN="${token}"
|
|
106
|
+
SNAPPY_URL="${SNAPPY_API_URL}"
|
|
107
|
+
PUBLIC_LOCALE="${locale}"
|
|
108
|
+
PRIMARY_DOMAIN="${domain}"
|
|
109
|
+
`;
|
|
110
|
+
fs.writeFileSync(path.join(targetDir, ".env"), envContent);
|
|
111
|
+
const metadata = {
|
|
112
|
+
projectName,
|
|
113
|
+
template,
|
|
114
|
+
installedAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
115
|
+
version: "2.0.0"
|
|
116
|
+
};
|
|
117
|
+
fs.writeFileSync(path.join(targetDir, "snappy.json"), JSON.stringify(metadata, null, 2));
|
|
118
|
+
} catch (err) {
|
|
119
|
+
throw new Error(`Failed to setup project: ${err.message}`);
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
// src/index.ts
|
|
124
|
+
async function main() {
|
|
125
|
+
console.log(kleur2.cyan(`create-snappy v${SNAPPY_VERSION} by Wicky.ID`));
|
|
126
|
+
console.log(kleur2.white("wicky.id/snappy \u2014 hi@wicky.id"));
|
|
127
|
+
console.log("\u2500".repeat(44) + "\n");
|
|
128
|
+
const response = await askQuestions();
|
|
78
129
|
if (!response.projectName) {
|
|
79
|
-
console.log(
|
|
130
|
+
console.log(kleur2.yellow("Installation cancelled."));
|
|
80
131
|
process.exit(0);
|
|
81
132
|
}
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
const
|
|
133
|
+
console.log(kleur2.blue("\u{1F50D} Validating SNAPPY_TOKEN..."));
|
|
134
|
+
try {
|
|
135
|
+
const heartbeat = await validateToken(response.token);
|
|
136
|
+
console.log(kleur2.green(`\u2705 Token valid [Project: ${heartbeat.projectSlug || "Unknown"}]`));
|
|
137
|
+
} catch (err) {
|
|
138
|
+
console.error(kleur2.red(`\u274C Invalid SNAPPY_TOKEN: ${err.message}`));
|
|
139
|
+
process.exit(1);
|
|
140
|
+
}
|
|
141
|
+
const targetDir = path2.resolve(process.cwd(), response.projectName);
|
|
142
|
+
if (fs2.existsSync(targetDir)) {
|
|
143
|
+
const { overwrite } = await prompts2({
|
|
85
144
|
type: "confirm",
|
|
86
145
|
name: "overwrite",
|
|
87
146
|
message: `Directory ${response.projectName} already exists. Wipe and overwrite?`,
|
|
88
147
|
initial: false
|
|
89
148
|
});
|
|
90
149
|
if (!overwrite) {
|
|
91
|
-
console.log(
|
|
150
|
+
console.log(kleur2.red("Aborted."));
|
|
92
151
|
process.exit(0);
|
|
93
152
|
}
|
|
94
|
-
|
|
153
|
+
fs2.rmSync(targetDir, { recursive: true, force: true });
|
|
95
154
|
}
|
|
96
|
-
console.log(kleur.blue(`
|
|
97
|
-
\u{1F4E6} Cloning [${response.template}] template...`));
|
|
98
155
|
try {
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
const pkg = JSON.parse(fs.readFileSync(pkgPath, "utf8"));
|
|
108
|
-
pkg.name = response.projectName.toLowerCase().replace(/\s+/g, "-");
|
|
109
|
-
fs.writeFileSync(pkgPath, JSON.stringify(pkg, null, 2));
|
|
110
|
-
}
|
|
156
|
+
runSetup(targetDir, response);
|
|
157
|
+
console.log(kleur2.green("\n\u2705 Project initialized successfully!"));
|
|
158
|
+
console.log(`
|
|
159
|
+
Next steps:`);
|
|
160
|
+
console.log(kleur2.cyan(` cd ${response.projectName}`));
|
|
161
|
+
console.log(kleur2.cyan(` pnpm install`));
|
|
162
|
+
console.log(kleur2.cyan(` pnpm dev`));
|
|
163
|
+
console.log("\n");
|
|
111
164
|
} catch (err) {
|
|
112
|
-
console.error(
|
|
165
|
+
console.error(kleur2.red(`
|
|
166
|
+
\u274C Installation failed: ${err.message}`));
|
|
113
167
|
process.exit(1);
|
|
114
168
|
}
|
|
115
|
-
const envContent = `# SNAPPY CMS - Site Configuration
|
|
116
|
-
SNAPPY_TOKEN="${response.token}"
|
|
117
|
-
SNAPPY_URL="https://api.snappycore.com" # Default production API
|
|
118
|
-
PUBLIC_LOCALE="${response.locale}"
|
|
119
|
-
PRIMARY_DOMAIN="${response.domain}"
|
|
120
|
-
`;
|
|
121
|
-
fs.writeFileSync(path.join(targetDir, ".env"), envContent);
|
|
122
|
-
const metadata = {
|
|
123
|
-
projectName: response.projectName,
|
|
124
|
-
template: response.template,
|
|
125
|
-
installedAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
126
|
-
version: "2.0.0"
|
|
127
|
-
};
|
|
128
|
-
fs.writeFileSync(path.join(targetDir, "snappy.json"), JSON.stringify(metadata, null, 2));
|
|
129
|
-
console.log(kleur.green("\n\u2705 Project initialized successfully!"));
|
|
130
|
-
console.log(`
|
|
131
|
-
Next steps:`);
|
|
132
|
-
console.log(kleur.cyan(` cd ${response.projectName}`));
|
|
133
|
-
console.log(kleur.cyan(` pnpm install`));
|
|
134
|
-
console.log(kleur.cyan(` pnpm dev`));
|
|
135
|
-
console.log(kleur.white("\nTHERE IS NO MERCY IN PRODUCTION \u{1F479}\n"));
|
|
136
169
|
}
|
|
137
170
|
main().catch((err) => {
|
|
138
|
-
console.error(
|
|
139
|
-
\u274C
|
|
171
|
+
console.error(kleur2.red(`
|
|
172
|
+
\u274C Critical error: ${err.message}`));
|
|
140
173
|
process.exit(1);
|
|
141
174
|
});
|
package/package.json
CHANGED
|
@@ -1,12 +1,16 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "create-snappy",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.12",
|
|
4
4
|
"description": "The official SNAPPY Stack CLI for project initialization.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"private": false,
|
|
7
7
|
"bin": {
|
|
8
8
|
"create-snappy": "./dist/index.js"
|
|
9
9
|
},
|
|
10
|
+
"scripts": {
|
|
11
|
+
"build": "tsup src/index.ts --format esm --clean",
|
|
12
|
+
"dev": "tsup src/index.ts --format esm --watch"
|
|
13
|
+
},
|
|
10
14
|
"keywords": [
|
|
11
15
|
"snappy",
|
|
12
16
|
"cms",
|
|
@@ -33,9 +37,5 @@
|
|
|
33
37
|
"devDependencies": {
|
|
34
38
|
"tsup": "^8.0.0",
|
|
35
39
|
"typescript": "^5.0.0"
|
|
36
|
-
},
|
|
37
|
-
"scripts": {
|
|
38
|
-
"build": "tsup src/index.ts --format esm --clean",
|
|
39
|
-
"dev": "tsup src/index.ts --format esm --watch"
|
|
40
40
|
}
|
|
41
|
-
}
|
|
41
|
+
}
|