create-astro 0.14.2 → 0.15.1

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 CHANGED
@@ -3,8 +3,10 @@ import { execa, execaCommand } from "execa";
3
3
  import fs from "fs";
4
4
  import { bgCyan, black, bold, cyan, dim, gray, green, red, reset, yellow } from "kleur/colors";
5
5
  import ora from "ora";
6
+ import os from "os";
6
7
  import path from "path";
7
8
  import prompts from "prompts";
9
+ import url from "url";
8
10
  import detectPackageManager from "which-pm-runs";
9
11
  import yargs from "yargs-parser";
10
12
  import { loadWithRocketGradient, rocketAscii } from "./gradient.js";
@@ -58,35 +60,41 @@ ${bold("Welcome to Astro!")} ${gray(`(create-astro v${version})`)}`);
58
60
  let rejectProjectDir = ora({ color: "red", text: notEmptyMsg(cwd) });
59
61
  rejectProjectDir.fail();
60
62
  }
61
- const dirResponse = await prompts({
62
- type: "text",
63
- name: "directory",
64
- message: "Where would you like to create your new project?",
65
- initial: "./my-astro-site",
66
- validate(value) {
67
- if (!isEmpty(value)) {
68
- return notEmptyMsg(value);
63
+ const dirResponse = await prompts(
64
+ {
65
+ type: "text",
66
+ name: "directory",
67
+ message: "Where would you like to create your new project?",
68
+ initial: "./my-astro-site",
69
+ validate(value) {
70
+ if (!isEmpty(value)) {
71
+ return notEmptyMsg(value);
72
+ }
73
+ return true;
69
74
  }
70
- return true;
71
- }
72
- });
75
+ },
76
+ { onCancel: () => ora().info(dim("Operation cancelled. See you later, astronaut!")) }
77
+ );
73
78
  cwd = dirResponse.directory;
74
79
  }
75
80
  if (!cwd) {
76
81
  process.exit(1);
77
82
  }
78
- const options = await prompts([
79
- {
80
- type: "select",
81
- name: "template",
82
- message: "Which template would you like to use?",
83
- choices: TEMPLATES
84
- }
85
- ]);
83
+ const options = await prompts(
84
+ [
85
+ {
86
+ type: "select",
87
+ name: "template",
88
+ message: "Which template would you like to use?",
89
+ choices: TEMPLATES
90
+ }
91
+ ],
92
+ { onCancel: () => ora().info(dim("Operation cancelled. See you later, astronaut!")) }
93
+ );
86
94
  if (!options.template) {
87
95
  process.exit(1);
88
96
  }
89
- const templateSpinner = await loadWithRocketGradient("Copying project files...");
97
+ let templateSpinner = await loadWithRocketGradient("Copying project files...");
90
98
  const hash = args.commit ? `#${args.commit}` : "";
91
99
  const templateTarget = options.template.includes("/") ? options.template : `withastro/astro/examples/${options.template}#latest`;
92
100
  const emitter = degit(`${templateTarget}${hash}`, {
@@ -105,20 +113,42 @@ ${bold("Welcome to Astro!")} ${gray(`(create-astro v${version})`)}`);
105
113
  logger.debug(info.message);
106
114
  });
107
115
  await emitter.clone(cwd);
116
+ if (isEmpty(cwd)) {
117
+ fs.rmdirSync(cwd);
118
+ throw new Error(`Error: The provided template (${cyan(options.template)}) does not exist`);
119
+ }
108
120
  } catch (err) {
121
+ templateSpinner.fail();
109
122
  logger.debug(err);
110
123
  console.error(red(err.message));
111
- if (err.message === "zlib: unexpected end of file") {
124
+ if (err.message === "zlib: unexpected end of file" || err.message === "TAR_BAD_ARCHIVE: Unrecognized archive format") {
112
125
  console.log(
113
126
  yellow(
114
- "This seems to be a cache related problem. Remove the folder '~/.degit/github/withastro' to fix this error."
115
- )
116
- );
117
- console.log(
118
- yellow(
119
- "For more information check out this issue: https://github.com/withastro/astro/issues/655"
127
+ "Local degit cache seems to be corrupted. For more information check out this issue: https://github.com/withastro/astro/issues/655. "
120
128
  )
121
129
  );
130
+ const cacheIssueResponse = await prompts({
131
+ type: "confirm",
132
+ name: "cache",
133
+ message: "Would you like us to clear the cache and try again?",
134
+ initial: true
135
+ });
136
+ if (cacheIssueResponse.cache) {
137
+ const homeDirectory = os.homedir();
138
+ const cacheDir = path.join(homeDirectory, ".degit", "github", "withastro");
139
+ fs.rmSync(cacheDir, { recursive: true, force: true, maxRetries: 3 });
140
+ templateSpinner = await loadWithRocketGradient("Copying project files...");
141
+ try {
142
+ await emitter.clone(cwd);
143
+ } catch (e) {
144
+ logger.debug(e);
145
+ console.error(red(e.message));
146
+ }
147
+ } else {
148
+ console.log(
149
+ "Okay, no worries! To fix this manually, remove the folder '~/.degit/github/withastro' and rerun the command."
150
+ );
151
+ }
122
152
  }
123
153
  if (err.code === "MISSING_REF") {
124
154
  console.log(
@@ -132,7 +162,6 @@ ${bold("Welcome to Astro!")} ${gray(`(create-astro v${version})`)}`);
132
162
  )
133
163
  );
134
164
  }
135
- templateSpinner.fail();
136
165
  process.exit(1);
137
166
  }
138
167
  await Promise.all(
@@ -146,12 +175,26 @@ ${bold("Welcome to Astro!")} ${gray(`(create-astro v${version})`)}`);
146
175
  }
147
176
  templateSpinner.text = green("Template copied!");
148
177
  templateSpinner.succeed();
149
- const installResponse = await prompts({
150
- type: "confirm",
151
- name: "install",
152
- message: `Would you like to install ${pkgManager} dependencies? ${reset(dim("(recommended)"))}`,
153
- initial: true
154
- });
178
+ const installResponse = await prompts(
179
+ {
180
+ type: "confirm",
181
+ name: "install",
182
+ message: `Would you like to install ${pkgManager} dependencies? ${reset(
183
+ dim("(recommended)")
184
+ )}`,
185
+ initial: true
186
+ },
187
+ {
188
+ onCancel: () => {
189
+ ora().info(
190
+ dim(
191
+ "Operation cancelled. Your project folder has already been created, however no dependencies have been installed"
192
+ )
193
+ );
194
+ process.exit(1);
195
+ }
196
+ }
197
+ );
155
198
  if (args.dryRun) {
156
199
  ora().info(dim(`--dry-run enabled, skipping.`));
157
200
  } else if (installResponse.install) {
@@ -174,19 +217,94 @@ ${bold(
174
217
  } else {
175
218
  ora().info(dim(`No problem! Remember to install dependencies after setup.`));
176
219
  }
177
- const gitResponse = await prompts({
178
- type: "confirm",
179
- name: "git",
180
- message: `Would you like to initialize a new git repository? ${reset(dim("(optional)"))}`,
181
- initial: true
182
- });
220
+ const gitResponse = await prompts(
221
+ {
222
+ type: "confirm",
223
+ name: "git",
224
+ message: `Would you like to initialize a new git repository? ${reset(dim("(optional)"))}`,
225
+ initial: true
226
+ },
227
+ {
228
+ onCancel: () => {
229
+ ora().info(
230
+ dim("Operation cancelled. No worries, your project folder has already been created")
231
+ );
232
+ process.exit(1);
233
+ }
234
+ }
235
+ );
183
236
  if (args.dryRun) {
184
237
  ora().info(dim(`--dry-run enabled, skipping.`));
185
238
  } else if (gitResponse.git) {
186
239
  await execaCommand("git init", { cwd });
240
+ ora().succeed("Git repository created!");
187
241
  } else {
188
242
  ora().info(dim(`Sounds good! You can come back and run ${cyan(`git init`)} later.`));
189
243
  }
244
+ const tsResponse = await prompts(
245
+ {
246
+ type: "select",
247
+ name: "typescript",
248
+ message: "How would you like to setup TypeScript?",
249
+ choices: [
250
+ {
251
+ title: "Relaxed",
252
+ value: "default"
253
+ },
254
+ {
255
+ title: "Strict (recommended)",
256
+ description: "Enable `strict` typechecking rules",
257
+ value: "strict"
258
+ },
259
+ {
260
+ title: "Strictest",
261
+ description: "Enable all typechecking rules",
262
+ value: "stricter"
263
+ },
264
+ {
265
+ title: "I prefer not to use TypeScript",
266
+ description: `That's cool too!`,
267
+ value: "optout"
268
+ }
269
+ ]
270
+ },
271
+ {
272
+ onCancel: () => {
273
+ ora().info(
274
+ dim(
275
+ "Operation cancelled. Your project folder has been created but no TypeScript configuration file was created."
276
+ )
277
+ );
278
+ process.exit(1);
279
+ }
280
+ }
281
+ );
282
+ if (tsResponse.typescript === "optout") {
283
+ console.log(``);
284
+ ora().warn(yellow(bold(`Astro \u2764\uFE0F TypeScript!`)));
285
+ console.log(` Astro supports TypeScript inside of ".astro" component scripts, so`);
286
+ console.log(` we still need to create some TypeScript-related files in your project.`);
287
+ console.log(` You can safely ignore these files, but don't delete them!`);
288
+ console.log(dim(" (ex: tsconfig.json, src/types.d.ts)"));
289
+ console.log(``);
290
+ tsResponse.typescript = "default";
291
+ await wait(300);
292
+ }
293
+ if (args.dryRun) {
294
+ ora().info(dim(`--dry-run enabled, skipping.`));
295
+ } else if (tsResponse.typescript) {
296
+ if (tsResponse.typescript !== "default") {
297
+ fs.copyFileSync(
298
+ path.join(
299
+ url.fileURLToPath(new URL("..", import.meta.url)),
300
+ "tsconfigs",
301
+ `tsconfig.${tsResponse.typescript}.json`
302
+ ),
303
+ path.join(cwd, "tsconfig.json")
304
+ );
305
+ }
306
+ ora().succeed("TypeScript settings applied!");
307
+ }
190
308
  ora().succeed("Setup complete.");
191
309
  ora({ text: green("Ready for liftoff!") }).succeed();
192
310
  await wait(300);
@@ -195,9 +313,11 @@ ${bgCyan(black(" Next steps "))}
195
313
  `);
196
314
  let projectDir = path.relative(process.cwd(), cwd);
197
315
  const devCmd = pkgManager === "npm" ? "npm run dev" : `${pkgManager} dev`;
198
- await logAndWait(
199
- `You can now ${bold(cyan("cd"))} into the ${bold(cyan(projectDir))} project directory.`
200
- );
316
+ if (projectDir !== "/") {
317
+ await logAndWait(
318
+ `You can now ${bold(cyan("cd"))} into the ${bold(cyan(projectDir))} project directory.`
319
+ );
320
+ }
201
321
  await logAndWait(
202
322
  `Run ${bold(cyan(devCmd))} to start the Astro dev server. ${bold(cyan("CTRL-C"))} to close.`
203
323
  );
@@ -207,7 +327,7 @@ ${bgCyan(black(" Next steps "))}
207
327
  )} to your project using ${bold(cyan("astro add"))}`
208
328
  );
209
329
  await logAndWait("");
210
- await logAndWait(`Stuck? Come join us at ${bold(cyan("https://astro.build/chat"))}`, 1e3);
330
+ await logAndWait(`Stuck? Come join us at ${bold(cyan("https://astro.build/chat"))}`, 750);
211
331
  await logAndWait(dim("Good luck out there, astronaut."));
212
332
  await logAndWait("", 300);
213
333
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "create-astro",
3
- "version": "0.14.2",
3
+ "version": "0.15.1",
4
4
  "type": "module",
5
5
  "author": "withastro",
6
6
  "license": "MIT",
@@ -19,7 +19,8 @@
19
19
  },
20
20
  "files": [
21
21
  "dist",
22
- "create-astro.js"
22
+ "create-astro.js",
23
+ "tsconfigs"
23
24
  ],
24
25
  "dependencies": {
25
26
  "chalk": "^5.0.1",
@@ -0,0 +1,19 @@
1
+ {
2
+ "compilerOptions": {
3
+ // Enable top-level await, and other modern ESM features.
4
+ "target": "ESNext",
5
+ "module": "ESNext",
6
+ // Enable node-style module resolution, for things like npm package imports.
7
+ "moduleResolution": "node",
8
+ // Enable JSON imports.
9
+ "resolveJsonModule": true,
10
+ // Enable stricter transpilation for better output.
11
+ "isolatedModules": true,
12
+ // Astro will directly run your TypeScript code, no transpilation needed.
13
+ "noEmit": true,
14
+ // Enable strict type checking.
15
+ "strict": true,
16
+ // Error when a value import is only used as a type.
17
+ "importsNotUsedAsValues": "error"
18
+ }
19
+ }
@@ -0,0 +1,33 @@
1
+ {
2
+ "compilerOptions": {
3
+ // Enable top-level await, and other modern ESM features.
4
+ "target": "ESNext",
5
+ "module": "ESNext",
6
+ // Enable node-style module resolution, for things like npm package imports.
7
+ "moduleResolution": "node",
8
+ // Enable JSON imports.
9
+ "resolveJsonModule": true,
10
+ // Enable stricter transpilation for better output.
11
+ "isolatedModules": true,
12
+ // Astro will directly run your TypeScript code, no transpilation needed.
13
+ "noEmit": true,
14
+ // Enable strict type checking.
15
+ "strict": true,
16
+ // Error when a value import is only used as a type.
17
+ "importsNotUsedAsValues": "error",
18
+ // Report errors for fallthrough cases in switch statements
19
+ "noFallthroughCasesInSwitch": true,
20
+ // Force functions designed to override their parent class to be specified as `override`.
21
+ "noImplicitOverride": true,
22
+ // Force functions to specify that they can return `undefined` if a possibe code path does not return a value.
23
+ "noImplicitReturns": true,
24
+ // Report an error when a variable is declared but never used.
25
+ "noUnusedLocals": true,
26
+ // Report an error when a parameter is declared but never used.
27
+ "noUnusedParameters": true,
28
+ // Force the usage of the indexed syntax to access fields declared using an index signature.
29
+ "noUncheckedIndexedAccess": true,
30
+ // Report an error when the value `undefined` is given to an optional property that doesn't specify `undefined` as a valid value.
31
+ "exactOptionalPropertyTypes": true
32
+ }
33
+ }