@youcan/create-app 2.1.4 → 2.2.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.
@@ -1,11 +1,11 @@
1
- import { Cli } from '@youcan/cli-kit';
2
- export default class Init extends Cli.Command {
3
- static aliases: string[];
4
- static description: string;
5
- static flags: {
6
- path: import("@oclif/core/lib/interfaces").OptionFlag<string, import("@oclif/core/lib/interfaces/parser").CustomOptions>;
7
- 'no-color': import("@oclif/core/lib/interfaces").BooleanFlag<boolean>;
8
- verbose: import("@oclif/core/lib/interfaces").BooleanFlag<boolean>;
9
- };
10
- run(): Promise<void>;
11
- }
1
+ import { Cli } from '@youcan/cli-kit';
2
+ export default class Init extends Cli.Command {
3
+ static aliases: string[];
4
+ static description: string;
5
+ static flags: {
6
+ path: import("@oclif/core/lib/interfaces").OptionFlag<string, import("@oclif/core/lib/interfaces/parser").CustomOptions>;
7
+ 'no-color': import("@oclif/core/lib/interfaces").BooleanFlag<boolean>;
8
+ verbose: import("@oclif/core/lib/interfaces").BooleanFlag<boolean>;
9
+ };
10
+ run(): Promise<void>;
11
+ }
@@ -1,31 +1,37 @@
1
1
  import { cwd } from 'node:process';
2
2
  import { Flags } from '@oclif/core';
3
- import { Cli, Path } from '@youcan/cli-kit';
3
+ import { Cli, Path, System } from '@youcan/cli-kit';
4
4
  import initPrompt from '../prompts/init.js';
5
5
  import initService from '../services/init.js';
6
6
 
7
- class Init extends Cli.Command {
8
- static aliases = ['create-app'];
9
- static description = 'bootstaps a new youcan app';
10
- static flags = {
11
- ...Cli.commonFlags,
12
- path: Flags.string({
13
- char: 'p',
14
- env: 'YC_FLAG_PATH',
15
- parse: async (input) => Path.resolve(input),
16
- default: async () => cwd(),
17
- hidden: false,
18
- }),
19
- };
20
- async run() {
21
- const { flags } = await this.parse(Init);
22
- const response = await initPrompt(this);
23
- await initService(this, {
24
- name: response.name,
25
- directory: flags.path,
26
- template: response.template,
27
- });
28
- }
7
+ class Init extends Cli.Command {
8
+ static aliases = ['create-app'];
9
+ static description = 'bootstraps a new youcan app';
10
+ static flags = {
11
+ ...Cli.commonFlags,
12
+ path: Flags.string({
13
+ char: 'p',
14
+ env: 'YC_FLAG_PATH',
15
+ parse: async (input) => Path.resolve(input),
16
+ default: async () => cwd(),
17
+ hidden: false,
18
+ }),
19
+ };
20
+ async run() {
21
+ const { flags } = await this.parse(Init);
22
+ const response = await initPrompt(this);
23
+ if (typeof response.name === 'undefined'
24
+ || typeof response.template === 'undefined') {
25
+ this.log('Operation cancelled');
26
+ this.exit(130);
27
+ }
28
+ await initService(this, {
29
+ name: response.name,
30
+ directory: flags.path,
31
+ template: response.template,
32
+ packageManager: System.inferUserPackageManager(),
33
+ });
34
+ }
29
35
  }
30
36
 
31
37
  export { Init as default };
package/dist/index.d.ts CHANGED
@@ -1,2 +1,2 @@
1
- declare function execCreateAppCli(development: boolean): Promise<void>;
2
- export default execCreateAppCli;
1
+ declare function execCreateAppCli(development: boolean): Promise<void>;
2
+ export default execCreateAppCli;
package/dist/index.js CHANGED
@@ -1,10 +1,10 @@
1
1
  import { Cli } from '@youcan/cli-kit';
2
2
 
3
- async function execCreateAppCli(development) {
4
- await Cli.execCreate('app', {
5
- moduleUrl: import.meta.url,
6
- development,
7
- });
3
+ async function execCreateAppCli(development) {
4
+ await Cli.execCreate('app', {
5
+ moduleUrl: import.meta.url,
6
+ development,
7
+ });
8
8
  }
9
9
 
10
10
  export { execCreateAppCli as default };
@@ -1,11 +1,11 @@
1
- import type { Cli } from '@youcan/cli-kit';
2
- interface InitOutput {
3
- name: string;
4
- template: string;
5
- }
6
- export declare const TEMPLATES: Record<string, {
7
- label: string;
8
- url?: string;
9
- }>;
10
- declare function initPrompt(command: Cli.Command): Promise<InitOutput>;
11
- export default initPrompt;
1
+ import type { Cli } from '@youcan/cli-kit';
2
+ interface InitOutput {
3
+ name?: string;
4
+ template?: string;
5
+ }
6
+ export declare const TEMPLATES: Record<string, {
7
+ label: string;
8
+ url?: string;
9
+ }>;
10
+ declare function initPrompt(command: Cli.Command): Promise<InitOutput>;
11
+ export default initPrompt;
@@ -1,49 +1,49 @@
1
- const TEMPLATES = {
2
- 'nuxt': {
3
- label: 'Start with Nuxt (recommended)',
4
- url: 'https://github.com/youcan-shop/shop-app-template-nuxt',
5
- },
6
- 'extension-only': {
7
- label: 'Start with an extension only',
8
- url: 'https://github.com/youcan-shop/shop-app-template-none',
9
- },
10
- 'none': {
11
- label: 'A blank canvas',
12
- },
13
- };
14
- async function initPrompt(command) {
15
- const defaults = {
16
- name: 'my-youcan-shop-app',
17
- template: TEMPLATES.nuxt.url,
18
- };
19
- command.log('\nHello! Start by picking a name for your app.');
20
- const response = await command.prompt([
21
- {
22
- name: 'name',
23
- type: 'text',
24
- initial: defaults.name,
25
- message: 'Your app\'s name',
26
- validate: (v) => {
27
- if (!v.length) {
28
- return 'App name cannot be empty';
29
- }
30
- if (v.length > 32) {
31
- return 'App name cannot exceed 32 characters';
32
- }
33
- return true;
34
- },
35
- },
36
- {
37
- type: 'select',
38
- name: 'template',
39
- message: 'Your app\'s starting template',
40
- format: v => TEMPLATES[v]?.url,
41
- choices: Object
42
- .entries(TEMPLATES)
43
- .map(([k, v]) => ({ title: v.label, value: k })),
44
- },
45
- ]);
46
- return response;
1
+ const TEMPLATES = {
2
+ 'nuxt': {
3
+ label: 'Start with Nuxt (recommended)',
4
+ url: 'https://github.com/youcan-shop/shop-app-template-nuxt',
5
+ },
6
+ 'extension-only': {
7
+ label: 'Start with an extension only',
8
+ url: 'https://github.com/youcan-shop/shop-app-template-none',
9
+ },
10
+ 'none': {
11
+ label: 'A blank canvas',
12
+ },
13
+ };
14
+ async function initPrompt(command) {
15
+ const defaults = {
16
+ name: 'my-youcan-shop-app',
17
+ template: TEMPLATES.nuxt.url,
18
+ };
19
+ command.log('\nHello! Start by picking a name for your app.');
20
+ const response = await command.prompt([
21
+ {
22
+ name: 'name',
23
+ type: 'text',
24
+ initial: defaults.name,
25
+ message: 'Your app\'s name',
26
+ validate: (v) => {
27
+ if (!v.length) {
28
+ return 'App name cannot be empty';
29
+ }
30
+ if (v.length > 32) {
31
+ return 'App name cannot exceed 32 characters';
32
+ }
33
+ return true;
34
+ },
35
+ },
36
+ {
37
+ type: 'select',
38
+ name: 'template',
39
+ message: 'Your app\'s starting template',
40
+ format: v => TEMPLATES[v]?.url,
41
+ choices: Object
42
+ .entries(TEMPLATES)
43
+ .map(([k, v]) => ({ title: v.label, value: k })),
44
+ },
45
+ ]);
46
+ return response;
47
47
  }
48
48
 
49
49
  export { TEMPLATES, initPrompt as default };
@@ -1,8 +1,10 @@
1
- import type { Cli } from '@youcan/cli-kit';
2
- interface InitServiceOptions {
3
- name: string;
4
- directory: string;
5
- template?: string;
6
- }
7
- declare function initService(command: Cli.Command, options: InitServiceOptions): Promise<void>;
8
- export default initService;
1
+ import type { Cli } from '@youcan/cli-kit';
2
+ import { System } from '@youcan/cli-kit';
3
+ interface InitServiceOptions {
4
+ name: string;
5
+ directory: string;
6
+ template?: string;
7
+ packageManager: System.PackageManagerType;
8
+ }
9
+ declare function initService(command: Cli.Command, options: InitServiceOptions): Promise<void>;
10
+ export default initService;
@@ -1,54 +1,69 @@
1
- import { String, Path, Github, Filesystem, Tasks, Git } from '@youcan/cli-kit';
1
+ import path from 'node:path';
2
+ import { String, Path, Github, Filesystem, Tasks, Git, System } from '@youcan/cli-kit';
2
3
 
3
- async function initService(command, options) {
4
- const slug = String.hyphenate(options.name);
5
- const outdir = Path.join(options.directory, slug);
6
- await assertDirectoryAvailability(outdir, slug);
7
- const repo = options.template
8
- ? Github.parseRepositoryReference(options.template)
9
- : null;
10
- await Filesystem.tapIntoTmp(async (tmp) => {
11
- const templateDownloadDirectory = Path.join(tmp, 'download');
12
- await Filesystem.mkdir(templateDownloadDirectory);
13
- await Tasks.run({}, [
14
- {
15
- title: 'Closing app template...',
16
- skip: () => repo == null,
17
- task: async () => {
18
- const url = repo.branch
19
- ? `${repo.baseUrl}#${repo.branch}`
20
- : repo.baseUrl;
21
- await Git.clone({
22
- url,
23
- shallow: true,
24
- destination: templateDownloadDirectory,
25
- });
26
- },
27
- },
28
- {
29
- title: 'Configuring app...',
30
- task: async () => {
31
- await Filesystem.writeJsonFile(Path.join(templateDownloadDirectory, 'youcan.app.json'), { name: slug });
32
- },
33
- },
34
- {
35
- title: `Copying files to ${outdir}...`,
36
- task: async () => {
37
- await Filesystem.move(templateDownloadDirectory, outdir);
38
- },
39
- },
40
- ]);
41
- });
42
- command.output.info(`${slug} is ready for your to develop! Head to the docs for more information`);
43
- command.output.info(' Developer Docs: https://developer.youcan.shop\n\n');
44
- command.output.info(' To preview your app, run `pnpm dev`');
45
- command.output.info(' For an overview of all the command, run `pnpm youcan app help`');
46
- }
47
- async function assertDirectoryAvailability(directory, name) {
48
- const exists = await Filesystem.exists(directory);
49
- if (exists) {
50
- throw new Error(`\nThe directory \`${name}\` already exists, please choose a new name for your app`);
51
- }
4
+ async function initService(command, options) {
5
+ const slug = String.hyphenate(options.name);
6
+ const outdir = Path.join(options.directory, slug);
7
+ const relativeOutdir = path.relative(process.cwd(), outdir);
8
+ await assertDirectoryAvailability(outdir, slug);
9
+ const repo = options.template
10
+ ? Github.parseRepositoryReference(options.template)
11
+ : null;
12
+ await Filesystem.tapIntoTmp(async (tmp) => {
13
+ const templateDownloadDirectory = Path.join(tmp, 'download');
14
+ await Filesystem.mkdir(templateDownloadDirectory);
15
+ await Tasks.run({}, [
16
+ {
17
+ title: 'Closing app template...',
18
+ skip: () => repo == null,
19
+ task: async () => {
20
+ const url = repo.branch
21
+ ? `${repo.baseUrl}#${repo.branch}`
22
+ : repo.baseUrl;
23
+ await Git.clone({
24
+ url,
25
+ shallow: true,
26
+ destination: templateDownloadDirectory,
27
+ });
28
+ },
29
+ },
30
+ {
31
+ title: 'Configuring app...',
32
+ task: async () => {
33
+ await Filesystem.writeJsonFile(Path.join(templateDownloadDirectory, 'youcan.app.json'), { name: slug });
34
+ },
35
+ },
36
+ {
37
+ title: `Copying files to ${relativeOutdir}...`,
38
+ task: async () => {
39
+ await Filesystem.move(templateDownloadDirectory, outdir);
40
+ },
41
+ },
42
+ {
43
+ title: 'Installing dependencies...',
44
+ loadable: false,
45
+ task: async () => {
46
+ await System.exec(options.packageManager, ['install'], {
47
+ stdout: 'inherit',
48
+ stderr: 'inherit',
49
+ cwd: outdir,
50
+ });
51
+ },
52
+ },
53
+ ]);
54
+ });
55
+ command.output.info(`${slug} is ready for your to develop! Head to the docs for more information`);
56
+ command.output.info(' Developer Docs: https://developer.youcan.shop\n\n');
57
+ command.output.info(' To preview your app, run');
58
+ command.output.info(` cd ${relativeOutdir}`);
59
+ command.output.info(` ${options.packageManager} dev`);
60
+ command.output.info(' For an overview of all the command, run `pnpm youcan app help`');
61
+ }
62
+ async function assertDirectoryAvailability(directory, name) {
63
+ const exists = await Filesystem.exists(directory);
64
+ if (exists) {
65
+ throw new Error(`\nThe directory \`${name}\` already exists, please choose a new name for your app`);
66
+ }
52
67
  }
53
68
 
54
69
  export { initService as default };
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@youcan/create-app",
3
3
  "type": "module",
4
- "version": "2.1.4",
4
+ "version": "2.2.0",
5
5
  "description": "A CLI for creating YouCan Shop apps",
6
6
  "author": "YouCan <contact@youcan.shop> (https://youcan.shop)",
7
7
  "license": "MIT",
@@ -23,7 +23,7 @@
23
23
  ],
24
24
  "dependencies": {
25
25
  "@oclif/core": "^2.15.0",
26
- "@youcan/cli-kit": "2.1.4"
26
+ "@youcan/cli-kit": "2.2.0"
27
27
  },
28
28
  "devDependencies": {
29
29
  "@oclif/plugin-legacy": "^1.3.0",