dicebear 5.0.0-alpha.26 → 5.0.0-alpha.29

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/lib/index.js CHANGED
@@ -1,16 +1,16 @@
1
- import { Command } from 'commander';
2
1
  import updateNotifier from 'update-notifier';
3
2
  import * as collection from '@dicebear/collection';
3
+ import yargs from 'yargs';
4
+ import { hideBin } from 'yargs/helpers';
4
5
  import { getPackageJson } from './utils/getPackageJson.js';
5
- import { makeStyleCommand } from './command/makeStyleCommand.js';
6
+ import { addStyleCommand } from './utils/addStyleCommand.js';
6
7
  (async () => {
7
8
  const pkg = await getPackageJson();
8
- const program = new Command('dicebear');
9
9
  updateNotifier({ pkg }).notify();
10
- program.version(pkg.version, '-v, --version');
10
+ const cli = yargs(hideBin(process.argv));
11
11
  for (let name of Object.keys(collection)) {
12
12
  const style = collection[name];
13
- program.addCommand(await makeStyleCommand(name, style));
13
+ addStyleCommand(cli, name, style);
14
14
  }
15
- await program.parseAsync(process.argv);
15
+ cli.demandCommand().help().locale('en').parse();
16
16
  })();
@@ -0,0 +1,3 @@
1
+ import { Style } from '@dicebear/core';
2
+ import yargs from 'yargs';
3
+ export declare function addStyleCommand(cli: yargs.Argv<{}>, name: string, style: Style<any>): yargs.Argv<unknown>;
@@ -0,0 +1,59 @@
1
+ import { createAvatar } from '@dicebear/core';
2
+ import cliProgress from 'cli-progress';
3
+ import PQueue from 'p-queue';
4
+ import os from 'node:os';
5
+ import * as path from 'node:path';
6
+ import fs from 'fs-extra';
7
+ import { exiftool } from 'exiftool-vendored';
8
+ import { getStyleCommandSchema } from './getStyleCommandSchema.js';
9
+ import { getOptionsBySchema } from './getOptionsBySchema.js';
10
+ import { validateInputBySchema } from './validateInputBySchema.js';
11
+ import { outputStyleLicenseBanner } from './outputStyleLicenseBanner.js';
12
+ export function addStyleCommand(cli, name, style) {
13
+ const schema = getStyleCommandSchema(style);
14
+ return cli.command({
15
+ command: `${name} [outputPath]`,
16
+ describe: `Generate "${name}" avatar(s)`,
17
+ builder: (yargs) => {
18
+ return yargs
19
+ .default('outputPath', '.')
20
+ .options(getOptionsBySchema(schema));
21
+ },
22
+ handler: async (argv) => {
23
+ const bar = new cliProgress.SingleBar({}, cliProgress.Presets.shades_classic);
24
+ const validated = validateInputBySchema(argv, schema);
25
+ const count = validated.count;
26
+ const includeExif = validated.exif;
27
+ outputStyleLicenseBanner(name, style);
28
+ bar.start(count, 0);
29
+ const queue = new PQueue({ concurrency: os.cpus().length });
30
+ queue.on('next', () => {
31
+ bar.update(count - queue.size - queue.pending);
32
+ });
33
+ const outputPath = path.resolve(process.cwd(), argv.outputPath);
34
+ await fs.ensureDir(outputPath);
35
+ for (let i = 0; i < count; i++) {
36
+ queue.add(async () => {
37
+ const fileName = path.resolve(process.cwd(), outputPath, `${name}-${i}.${validated.format}`);
38
+ const avatar = createAvatar(style, validated);
39
+ switch (validated.format) {
40
+ case 'svg':
41
+ await avatar.toFile(fileName);
42
+ break;
43
+ case 'png':
44
+ await avatar.png({ includeExif }).toFile(fileName);
45
+ break;
46
+ case 'jpg':
47
+ case 'jpeg':
48
+ await avatar.jpeg({ includeExif }).toFile(fileName);
49
+ break;
50
+ }
51
+ bar.increment();
52
+ });
53
+ }
54
+ await queue.onIdle();
55
+ bar.stop();
56
+ exiftool.end();
57
+ },
58
+ });
59
+ }
@@ -1,3 +1,2 @@
1
- import { Option } from 'commander';
2
1
  import { JSONSchema7 } from 'json-schema';
3
- export declare function getOptionsBySchema(schema: JSONSchema7): Promise<Option[]>;
2
+ export declare function getOptionsBySchema(schema: JSONSchema7): Record<string, any>;
@@ -1,29 +1,39 @@
1
- import { Option } from 'commander';
2
- export async function getOptionsBySchema(schema) {
3
- const result = [];
1
+ export function getOptionsBySchema(schema) {
2
+ const result = {};
4
3
  for (var key in schema.properties) {
5
4
  if (false === schema.properties.hasOwnProperty(key)) {
6
5
  continue;
7
6
  }
8
7
  const property = schema.properties[key];
9
8
  if (typeof property === 'object') {
10
- const option = new Option(`--${key} <value>`);
11
- let description = [property.title, property.description].filter((v) => v).join(' - ');
12
- let choices = [];
9
+ const option = {
10
+ type: property.type,
11
+ };
12
+ if (option.type === 'integer') {
13
+ option.type = 'number';
14
+ }
15
+ option.choices = [];
13
16
  if (property.enum) {
14
- choices.push(...property.enum.filter((v) => typeof v === 'string'));
17
+ option.choices.push(...property.enum.filter((v) => typeof v === 'string'));
15
18
  }
16
- if (typeof property.items === 'object' && 'enum' in property.items && property.items.enum) {
17
- choices.push(...property.items.enum.filter((v) => typeof v === 'string'));
19
+ if (typeof property.items === 'object' &&
20
+ 'enum' in property.items &&
21
+ property.items.enum) {
22
+ option.choices.push(...property.items.enum.filter((v) => typeof v === 'string'));
18
23
  }
19
- if (choices.length > 0) {
20
- description += ` (choices: "${choices.join('", "')})`;
24
+ if (option.choices.length === 0) {
25
+ delete option.choices;
21
26
  }
22
27
  if (property.default !== undefined && property.default !== null) {
23
- option.default(typeof property.default === 'boolean' ? property.default : property.default.toString());
28
+ option.default =
29
+ typeof property.default === 'boolean'
30
+ ? property.default
31
+ : property.default;
32
+ }
33
+ if (property.description) {
34
+ option.description = property.description;
24
35
  }
25
- option.description = description;
26
- result.push(option);
36
+ result[key] = option;
27
37
  }
28
38
  }
29
39
  return result;
@@ -0,0 +1,3 @@
1
+ import type { Style } from '@dicebear/core';
2
+ import type { JSONSchema7 } from 'json-schema';
3
+ export declare function getStyleCommandSchema(style: Style<any>): JSONSchema7;
@@ -0,0 +1,30 @@
1
+ import { schema as coreSchema } from '@dicebear/core';
2
+ import mergeAllOf from 'json-schema-merge-allof';
3
+ export function getStyleCommandSchema(style) {
4
+ return mergeAllOf({
5
+ allOf: [
6
+ {
7
+ properties: {
8
+ count: {
9
+ description: 'Defines how many avatars to create.',
10
+ type: 'number',
11
+ default: 1,
12
+ },
13
+ format: {
14
+ type: 'string',
15
+ enum: ['svg', 'png', 'jpg', 'jpeg'],
16
+ default: 'svg',
17
+ },
18
+ exif: {
19
+ description: 'Include Exif Metadata',
20
+ type: 'boolean',
21
+ default: false,
22
+ },
23
+ },
24
+ },
25
+ coreSchema,
26
+ style.schema,
27
+ ],
28
+ additionalItems: true,
29
+ }, { ignoreAdditionalProperties: true });
30
+ }
@@ -1,2 +1,3 @@
1
1
  import { JSONSchema7 } from 'json-schema';
2
- export declare function validateInputBySchema(input: Record<string, string | number>, schema: JSONSchema7): Record<string, string | number | boolean | string[] | number[] | boolean[]>;
2
+ import { ArgumentsCamelCase } from 'yargs';
3
+ export declare function validateInputBySchema(input: ArgumentsCamelCase<unknown>, schema: JSONSchema7): any;
@@ -7,20 +7,7 @@ export function validateInputBySchema(input, schema) {
7
7
  removeAdditional: true,
8
8
  });
9
9
  const validate = validator.compile(schema);
10
- const data = {};
11
- for (var key in input) {
12
- if (false === input.hasOwnProperty(key)) {
13
- continue;
14
- }
15
- if (schema.properties && key in schema.properties) {
16
- const property = schema.properties[key];
17
- if (typeof property === 'object' && property.type === 'array') {
18
- data[key] = input[key].toString().split(',');
19
- continue;
20
- }
21
- }
22
- data[key] = input[key];
23
- }
10
+ const data = JSON.parse(JSON.stringify(input));
24
11
  if (false === validate(data)) {
25
12
  if (validate.errors) {
26
13
  for (var error of validate.errors) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "dicebear",
3
- "version": "5.0.0-alpha.26",
3
+ "version": "5.0.0-alpha.29",
4
4
  "private": false,
5
5
  "description": "CLI for DiceBear - An avatar library for designers and developers",
6
6
  "homepage": "https://github.com/dicebear/dicebear",
@@ -25,20 +25,20 @@
25
25
  "prepublishOnly": "npm run build"
26
26
  },
27
27
  "dependencies": {
28
- "@dicebear/collection": "^5.0.0-alpha.26",
29
- "@dicebear/core": "^5.0.0-alpha.26",
30
- "@resvg/resvg-js": "^1.4.0",
28
+ "@dicebear/collection": "^5.0.0-alpha.29",
29
+ "@dicebear/core": "^5.0.0-alpha.29",
30
+ "@resvg/resvg-js": "^2.0.0",
31
31
  "ajv": "^8.11.0",
32
32
  "chalk": "^5.0.1",
33
33
  "chalk-template": "^0.4.0",
34
34
  "cli-progress": "^3.10.0",
35
- "commander": "^9.2.0",
36
35
  "exiftool-vendored": "^16.3.0",
37
36
  "fs-extra": "^10.1.0",
38
37
  "json-schema-merge-allof": "^0.8.1",
39
38
  "p-queue": "^7.2.0",
40
39
  "sharp": "^0.30.4",
41
- "update-notifier": "^5.1.0"
40
+ "update-notifier": "^5.1.0",
41
+ "yargs": "^17.4.1"
42
42
  },
43
43
  "devDependencies": {
44
44
  "@tsconfig/recommended": "^1.0.1",
@@ -47,11 +47,12 @@
47
47
  "@types/json-schema": "^7.0.11",
48
48
  "@types/json-schema-merge-allof": "^0.6.1",
49
49
  "@types/update-notifier": "^5.1.0",
50
+ "@types/yargs": "^17.0.10",
50
51
  "del-cli": "^4.0.1",
51
52
  "typescript": "^4.6.3"
52
53
  },
53
54
  "engines": {
54
55
  "node": "^12.20.0 || ^14.13.1 || >=16.0.0"
55
56
  },
56
- "gitHead": "68a91a6c5fa46dd8317fe066803657ac0bf59f68"
57
+ "gitHead": "775410bda059fa21dcb79b38c72ebadb80896243"
57
58
  }
@@ -1,3 +0,0 @@
1
- import type { Style } from '@dicebear/core';
2
- import { Command } from 'commander';
3
- export declare function makeStyleCommand(name: string, style: Style<any>): Promise<Command>;
@@ -1,84 +0,0 @@
1
- import { createAvatar, schema as coreSchema } from '@dicebear/core';
2
- import { Command } from 'commander';
3
- import * as path from 'node:path';
4
- import fs from 'fs-extra';
5
- import cliProgress from 'cli-progress';
6
- import { validateInputBySchema } from '../utils/validateInputBySchema.js';
7
- import { outputStyleLicenseBanner } from '../utils/outputStyleLicenseBanner.js';
8
- import { getOptionsBySchema } from '../utils/getOptionsBySchema.js';
9
- import mergeAllOf from 'json-schema-merge-allof';
10
- import PQueue from 'p-queue';
11
- import os from 'node:os';
12
- import { exiftool } from 'exiftool-vendored';
13
- export async function makeStyleCommand(name, style) {
14
- const schema = mergeAllOf({
15
- allOf: [
16
- {
17
- properties: {
18
- count: {
19
- title: 'Count',
20
- description: 'Defines how many avatars to create. Does not work in combination with a "seed".',
21
- type: 'number',
22
- default: 1,
23
- },
24
- format: {
25
- title: 'Format',
26
- type: 'string',
27
- enum: ['svg', 'png', 'jpg', 'jpeg'],
28
- default: 'svg',
29
- },
30
- exif: {
31
- title: 'Include Exif Metadata',
32
- type: 'boolean',
33
- default: false,
34
- },
35
- },
36
- },
37
- coreSchema,
38
- style.schema,
39
- ],
40
- additionalItems: true,
41
- }, { ignoreAdditionalProperties: true });
42
- const cmd = new Command(name);
43
- cmd.arguments('[outputPath]');
44
- for (let option of await getOptionsBySchema(schema)) {
45
- cmd.addOption(option);
46
- }
47
- cmd.action(async (outputPath = '.', options = {}) => {
48
- const bar = new cliProgress.SingleBar({}, cliProgress.Presets.shades_classic);
49
- const validated = validateInputBySchema(options, schema);
50
- const count = validated.count;
51
- const includeExif = validated.exif;
52
- outputStyleLicenseBanner(name, style);
53
- bar.start(count, 0);
54
- const queue = new PQueue({ concurrency: os.cpus().length });
55
- queue.on('next', () => {
56
- bar.update(count - queue.size - queue.pending);
57
- });
58
- outputPath = path.resolve(process.cwd(), outputPath);
59
- await fs.ensureDir(outputPath);
60
- for (let i = 0; i < count; i++) {
61
- queue.add(async () => {
62
- const fileName = path.resolve(process.cwd(), outputPath, `${name}-${i}.${validated.format}`);
63
- const avatar = createAvatar(style, validated);
64
- switch (validated.format) {
65
- case 'svg':
66
- await avatar.toFile(fileName);
67
- break;
68
- case 'png':
69
- await avatar.png({ includeExif }).toFile(fileName);
70
- break;
71
- case 'jpg':
72
- case 'jpeg':
73
- await avatar.jpeg({ includeExif }).toFile(fileName);
74
- break;
75
- }
76
- bar.increment();
77
- });
78
- }
79
- await queue.onIdle();
80
- bar.stop();
81
- exiftool.end();
82
- });
83
- return cmd;
84
- }