@youcan/cli 1.0.1 → 1.0.3

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 CHANGED
@@ -15,4 +15,4 @@ npm install -g @youcan/cli
15
15
  ## Help
16
16
 
17
17
  - [Open a GitHub issue](https://github.com/youcan-shop/youcan-cli/issues) - For bug reports and feature requests, you can open an issue in the YouCan CLI repository.
18
- - [CLI documentation - Theme development](https://developer.youcan.shop/themes/cli/introduction.html) - Visit our forums to connect with the community and learn more about Shopify CLI development.
18
+ - [CLI documentation - Theme development](https://developer.youcan.shop/themes/cli/introduction.html) - Visit our documentation for guides on getting started with YouCan Theme development.
package/bin/index.js CHANGED
@@ -1 +1,2 @@
1
+ #!/usr/bin/env node
1
2
  import('../dist/index.js')
@@ -4,5 +4,6 @@ export { default as InitCommand } from './theme/init.js';
4
4
  export { default as DevCommand } from './theme/dev.js';
5
5
  export { default as DeleteCommand } from './theme/delete.js';
6
6
  export { default as PullCommand } from './theme/pull.js';
7
+ export { default as PackCommand } from './theme/pack.js';
7
8
 
8
9
  // auth
@@ -5,7 +5,7 @@ import { fileFromPath } from 'formdata-node/file-from-path';
5
5
  import config from '../../../config/index.js';
6
6
  import cloneRepository from '../../../utils/git/cloneRepository.js';
7
7
  import stdout from '../../../utils/system/stdout.js';
8
- import zipFolder from '../../../utils/system/zipFolder.js';
8
+ import { zipFolder } from '../../../utils/system/zipFolder.js';
9
9
  import writeToFile from '../../../utils/system/writeToFile.js';
10
10
  import deleteFile from '../../../utils/system/deleteFile.js';
11
11
  import messages from '../../../config/messages.js';
@@ -0,0 +1,28 @@
1
+ import { cwd } from 'process';
2
+ import stdout from '../../../utils/system/stdout.js';
3
+ import { getCurrentThemeId, getCurrentDate, LoadingSpinner } from '../../../utils/common.js';
4
+ import messages from '../../../config/messages.js';
5
+ import { zipDirectory } from '../../../utils/system/zipFolder.js';
6
+
7
+ function command(cli) {
8
+ return {
9
+ name: 'pack',
10
+ group: 'theme',
11
+ description: 'Package a theme',
12
+ options: [],
13
+ action: async () => {
14
+ if (!cli.client.isAuthenticated())
15
+ return stdout.error(messages.AUTH_USER_NOT_LOGGED_IN);
16
+ if (!await getCurrentThemeId(cwd()))
17
+ return stdout.error('No theme found in the current directory');
18
+ const loading = new LoadingSpinner('📦 Packaging your theme');
19
+ loading.start();
20
+ const exportFolder = `theme_${getCurrentDate()}`;
21
+ await zipDirectory(cwd(), exportFolder);
22
+ loading.stop();
23
+ return stdout.info(`your theme was successfully packaged to ${exportFolder}`);
24
+ },
25
+ };
26
+ }
27
+
28
+ export { command as default };
@@ -4,3 +4,4 @@ export { default as InitCommand } from './theme/init';
4
4
  export { default as DevCommand } from './theme/dev';
5
5
  export { default as DeleteCommand } from './theme/delete';
6
6
  export { default as PullCommand } from './theme/pull';
7
+ export { default as PackCommand } from './theme/pack';
@@ -0,0 +1,2 @@
1
+ import type { CLI, CommandDefinition } from '../types';
2
+ export default function command(cli: CLI): CommandDefinition;
@@ -5,7 +5,7 @@ declare const cli: {
5
5
  client: Client;
6
6
  handler: import("cac").CAC;
7
7
  registerCommand(command: (cli: typeof this) => CommandDefinition): void;
8
- getAvailableCommands(): (typeof commands.LoginCommand | typeof commands.LogoutCommand | typeof commands.InitCommand | typeof commands.DevCommand | typeof commands.DeleteCommand | typeof commands.PullCommand)[];
8
+ getAvailableCommands(): (typeof commands.LoginCommand | typeof commands.LogoutCommand | typeof commands.InitCommand | typeof commands.DevCommand | typeof commands.DeleteCommand | typeof commands.PullCommand | typeof commands.PackCommand)[];
9
9
  init(): Promise<void>;
10
10
  prepareClient(): Promise<void>;
11
11
  };
@@ -19,3 +19,4 @@ export declare class LoadingSpinner {
19
19
  static exec(message: string, closure: (spinner: LoadingSpinner) => Promise<void>): Promise<void>;
20
20
  }
21
21
  export declare function delay(ms: number): Promise<void>;
22
+ export declare function getCurrentDate(): string;
@@ -0,0 +1 @@
1
+ export declare function lsDir(path: string): string[];
@@ -1,4 +1,5 @@
1
1
  /**
2
2
  * Zip folder and save it to a given path and return zip folder path
3
3
  */
4
- export default function zipFolder(folderPath: string, folderName: string): Promise<string>;
4
+ export declare function zipFolder(folderPath: string, folderName: string): Promise<string>;
5
+ export declare function zipDirectory(dirPath: string, folderName: string): Promise<unknown>;
@@ -52,6 +52,13 @@ class LoadingSpinner {
52
52
  }
53
53
  function delay(ms) {
54
54
  return new Promise(resolve => setTimeout(resolve, ms));
55
+ }
56
+ function getCurrentDate() {
57
+ const date = new Date();
58
+ const day = date.getDate();
59
+ const month = date.getMonth() + 1;
60
+ const year = date.getFullYear();
61
+ return `${day}-${month}-${year}`;
55
62
  }
56
63
 
57
- export { LoadingSpinner, delay, getCurrentThemeId };
64
+ export { LoadingSpinner, delay, getCurrentDate, getCurrentThemeId };
@@ -0,0 +1,9 @@
1
+ import { readdirSync, statSync } from 'fs';
2
+
3
+ function lsDir(path) {
4
+ return readdirSync(path).filter((file) => {
5
+ return statSync(`${path}/${file}`).isDirectory() && file[0] !== '.';
6
+ });
7
+ }
8
+
9
+ export { lsDir };
@@ -1,6 +1,7 @@
1
1
  import fs from 'fs';
2
2
  import path from 'path';
3
3
  import archiver from 'archiver';
4
+ import { lsDir } from './ls.js';
4
5
 
5
6
  /**
6
7
  * Zip folder and save it to a given path and return zip folder path
@@ -27,6 +28,30 @@ async function zipFolder(folderPath, folderName) {
27
28
  reject(err);
28
29
  }
29
30
  });
31
+ }
32
+ async function zipDirectory(dirPath, folderName) {
33
+ const ls = lsDir(dirPath);
34
+ return new Promise((resolve, reject) => {
35
+ try {
36
+ const zip = path.resolve(dirPath, `${folderName}.zip`);
37
+ const output = fs.createWriteStream(zip);
38
+ const archive = archiver('zip', {
39
+ zlib: { level: 9 },
40
+ });
41
+ output.on('close', () => {
42
+ resolve(zip);
43
+ });
44
+ archive.on('error', (err) => {
45
+ reject(err);
46
+ });
47
+ archive.pipe(output);
48
+ ls.forEach(folder => archive.directory(path.resolve(dirPath, folder), folder));
49
+ archive.finalize();
50
+ }
51
+ catch (err) {
52
+ reject(err);
53
+ }
54
+ });
30
55
  }
31
56
 
32
- export { zipFolder as default };
57
+ export { zipDirectory, zipFolder };
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@youcan/cli",
3
3
  "type": "module",
4
- "version": "1.0.1",
4
+ "version": "1.0.3",
5
5
  "description": "YouCan CLI for developers.",
6
6
  "author": "YouCan <contact@youcan.shop> (https://youcan.shop)",
7
7
  "keywords": [],
@@ -20,6 +20,15 @@
20
20
  "bin",
21
21
  "dist"
22
22
  ],
23
+ "scripts": {
24
+ "build": "tsc --noEmit && rollup --config rollup.config.js",
25
+ "dev": "rollup --config rollup.config.js --watch",
26
+ "lint": "eslint .",
27
+ "release": "bumpp && pnpm publish",
28
+ "typecheck": "tsc --noEmit",
29
+ "test": "vitest",
30
+ "check": "pnpm typecheck && pnpm lint && pnpm run test"
31
+ },
23
32
  "dependencies": {
24
33
  "archiver": "^5.3.1",
25
34
  "cac": "^6.7.14",
@@ -57,14 +66,5 @@
57
66
  "typescript": "^4.8.4",
58
67
  "vite": "^3.2.4",
59
68
  "vitest": "^0.24.5"
60
- },
61
- "scripts": {
62
- "build": "tsc --noEmit && rollup --config rollup.config.js",
63
- "dev": "rollup --config rollup.config.js --watch",
64
- "lint": "eslint .",
65
- "release": "bumpp && pnpm publish",
66
- "typecheck": "tsc --noEmit",
67
- "test": "vitest",
68
- "check": "pnpm typecheck && pnpm lint && pnpm run test"
69
69
  }
70
- }
70
+ }