Skip to content

Commit

Permalink
Merge pull request #22 from obytes/feat/add-cli
Browse files Browse the repository at this point in the history
Feat/add cli
  • Loading branch information
SihamBen committed Aug 16, 2023
2 parents cc09217 + 0a704b2 commit 416d2e2
Show file tree
Hide file tree
Showing 8 changed files with 247 additions and 2 deletions.
4 changes: 4 additions & 0 deletions cli/cli.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
#!/usr/bin/env node
import { parseArgument } from './parse-arguments';

parseArgument();
51 changes: 51 additions & 0 deletions cli/config-validation.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
import z from 'zod';
import path from 'path';
import { fromZodError } from 'zod-validation-error';
import chalk from 'chalk';
import type { Params } from '../types';

const HEX_COLOR_REGEX = /^#[0-9a-fA-F]{6}$/;

const Badge = z.discriminatedUnion('type', [
z.object({
type: z.literal('banner'),
text: z.string(),
position: z.union([z.literal('top'), z.literal('bottom')]).optional(),
color: z.union([z.literal('white'), z.literal('black')]).optional(),
background: z.string().regex(HEX_COLOR_REGEX).optional(),
}),
z.object({
type: z.literal('ribbon'),
text: z.string(),
position: z.union([z.literal('left'), z.literal('right')]).optional(),
color: z.union([z.literal('white'), z.literal('black')]).optional(),
background: z
.string({
invalid_type_error: 'background color should be in hex format',
})
.regex(HEX_COLOR_REGEX)
.optional(),
}),
]);

const configParamsSchema = z.object({
icon: z.string(),
dstPath: z.string().optional(),
badges: z.array(Badge),
isAdaptiveIcon: z.boolean().optional(),
});

const badgesArray = z.array(configParamsSchema);

export const validateConfig = (configs: Params[]) => {
try {
badgesArray.parse(configs);
} catch (err) {
if (err instanceof z.ZodError) {
const validationError = fromZodError(err);
console.error(chalk.red(validationError.message));
}
return false;
}
return true;
};
15 changes: 15 additions & 0 deletions cli/icon-config.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
import { Badge, Params } from '../types';

export class IconConfig {
icon: string;
dstPath?: string;
badges: Array<Badge>;
isAdaptiveIcon?: boolean;

constructor({ icon, dstPath, badges, isAdaptiveIcon }: Params) {
this.badges = badges;
this.icon = icon;
this.dstPath = dstPath;
this.isAdaptiveIcon = isAdaptiveIcon;
}
}
75 changes: 75 additions & 0 deletions cli/parse-arguments.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
import { parseBadgeJsonConfigFile } from './parse-badge-json-config-file';
import { IconConfig } from './icon-config';
import { addBadge } from '..';
import { Badge } from '../types';
import { Command, Option } from 'commander';

var version = require('../package.json').version;

const program = new Command();
program
.description('command line for app-icon-badge')
.name('app-icon-badge')
.version(version);

// default command
program
.addCommand(
new Command('add-badge')
.description('add badge to icon using add-badge by default')
.argument('<iconPath>')
.addOption(
new Option('-t, --type <type>', 'badge type')
.choices(['banner', 'ribbon'])
.makeOptionMandatory()
)
.addOption(
new Option('-x, --text <text>', 'badge text').makeOptionMandatory()
)
.addOption(
new Option(
'-p, --position <position>',
'badge position banner:top,bottom ribbon:left,right'
).choices(['top', 'left', 'right', 'bottom'])
)
.addOption(
new Option('-b, --background <background>', 'badge background color')
)
.addOption(
new Option('-c, --color <color>', 'badge color')
.choices(['white', 'black'])
.default('white')
)
.action((iconPath, opts) => {
program.setOptionValue('iconPath', iconPath);
program.setOptionValue('badge', opts);
}),
{
isDefault: true,
}
)
.showHelpAfterError();

program.addCommand(
new Command('use-config')
.description('use json file as a config')
.argument('<configPath>')
.action((configPath) => {
console.log(configPath);
})
);

export async function parseArgument() {
if (process.argv.length <= 2) {
program.help();
return;
}
const opts = program.parse().opts();
if (opts.iconPath) {
const badges: Badge = opts.badge;
const icon = new IconConfig({ icon: opts.iconPath, badges: [badges] });
addBadge(icon);
} else if (opts.badges_config) {
parseBadgeJsonConfigFile(opts.badges_config);
}
}
30 changes: 30 additions & 0 deletions cli/parse-badge-json-config-file.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
import fs from 'fs';
import type { Params } from '../types';
import { validateConfig } from './config-validation';
import path from 'path';
import chalk from 'chalk';
import { addBadge } from '../index';

export function parseBadgeJsonConfigFile(filePath: string) {
const resolvedPath = path.resolve(filePath);
if (!fs.existsSync(resolvedPath)) {
console.error(
chalk.red(`'${resolvedPath}'`, 'File does not exist in this path')
);
return false;
}
let badgeConfig: Params[] | null = null;
try {
const data = fs.readFileSync(filePath, 'utf8');
badgeConfig = JSON.parse(data);
if (badgeConfig && validateConfig(badgeConfig)) {
badgeConfig.forEach((config: Params) => {
addBadge(config);
});
}
} catch (err) {
console.error(err);
return false;
}
return true;
}
24 changes: 24 additions & 0 deletions cli/types.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
export type Banner = {
type: 'banner';
text: string;
position?: 'top' | 'bottom';
color?: 'white' | 'black';
background?: string;
};

export type Ribbon = {
type: 'ribbon';
text: string;
position?: 'left' | 'right';
color?: 'white' | 'black';
background?: string;
};

export type Badge = Banner | Ribbon;

export type Params = {
icon: string;
dstPath?: string;
badges: Array<Badge>;
isAdaptiveIcon?: boolean;
};
13 changes: 11 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -12,14 +12,18 @@
"app.plugin.js"
],
"scripts": {
"build": "tsup index.ts --format cjs,esm --dts && cp -r assets dist && tsup app.plugin.ts --format cjs && mv dist/app.plugin.js .",
"build": "tsup index.ts --format cjs,esm --dts && cp -r assets dist && tsup app.plugin.ts --format cjs && mv dist/app.plugin.js . && tsup cli/cli.ts",
"start": "nodemon --exec ts-node --files example/index.ts",
"start-cli": "nodemon --exec ts-node --files cli/cli.ts",
"type-check": "tsc --noEmit",
"format": "prettier --write \"**/*.{ts,md,json}\" --ignore-path .gitignore",
"np": "pnpm build && np --no-cleanup --no-release-draft",
"test": "echo \"no test specified\"",
"prepare": "husky install"
},
"bin": {
"obytes-icon-cli": "dist/cli.js"
},
"repository": {
"type": "git",
"url": "git+https://github.com/obytes/app-icon-badge.git"
Expand All @@ -31,19 +35,24 @@
"homepage": "https://github.com/obytes/app-icon-badge#readme",
"dependencies": {
"color-convert": "^2.0.1",
"commander": "^11.0.0",
"delta-e": "^0.0.8",
"jimp": "^0.22.7"
},
"devDependencies": {
"@commitlint/cli": "^17.4.4",
"@commitlint/config-conventional": "^17.4.4",
"@types/node": "^18.15.11",
"ajv": "^8.12.0",
"chalk": "^4.1.2",
"husky": "^8.0.3",
"nodemon": "^2.0.22",
"np": "^7.7.0",
"prettier": "2.8.7",
"ts-node": "^10.9.1",
"tsup": "^6.5.0",
"typescript": "^4.9.4"
"typescript": "^4.9.4",
"zod": "^3.21.4",
"zod-validation-error": "^1.3.1"
}
}
37 changes: 37 additions & 0 deletions pnpm-lock.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

0 comments on commit 416d2e2

Please sign in to comment.