@pcg/cli-tools 1.0.0-alpha.2

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.
@@ -0,0 +1,16 @@
1
+
2
+ 
3
+ > @pcg/cli-tools@1.0.0-alpha.1 build /Users/vangolenko/node/pcg/packages/cli-tools
4
+ > tsdown
5
+
6
+ ℹ tsdown v0.15.12 powered by rolldown v1.0.0-beta.45
7
+ ℹ Using tsdown config: /Users/vangolenko/node/pcg/packages/cli-tools/tsdown.config.ts
8
+ ℹ entry: src/index.ts
9
+ ℹ tsconfig: tsconfig.lib.json
10
+ ℹ Build start
11
+ ℹ Cleaning 3 files
12
+ ℹ dist/index.js 4.84 kB │ gzip: 1.91 kB
13
+ ℹ dist/index.js.map 9.84 kB │ gzip: 3.44 kB
14
+ ℹ dist/index.d.ts 1.96 kB │ gzip: 0.76 kB
15
+ ℹ 3 files, total: 16.64 kB
16
+ ✔ Build complete in 1200ms
@@ -0,0 +1,4 @@
1
+
2
+ > @pcg/cli-tools@1.0.0-alpha.1 lint /Users/vangolenko/node/pcg/packages/cli-tools
3
+ > eslint "src/**/*.ts"
4
+
package/CHANGELOG.md ADDED
@@ -0,0 +1,7 @@
1
+ # @pcg/cli-tools
2
+
3
+ ## 1.0.0-alpha.2
4
+
5
+ ### Patch Changes
6
+
7
+ - 1e20e35: Creates `@pcg/cli-tools` package with reusable utilities for CLI applications:
@@ -0,0 +1,51 @@
1
+ import * as commander0 from "commander";
2
+ import knex from "knex";
3
+ import { Logger } from "winston";
4
+
5
+ //#region src/env.d.ts
6
+ declare enum Env {
7
+ LOCAL = "local",
8
+ DEV = "dev",
9
+ STAGE = "stage",
10
+ PROD = "prod",
11
+ }
12
+ //#endregion
13
+ //#region src/command.d.ts
14
+ interface CommandArgsWithEnv {
15
+ env: Env;
16
+ }
17
+ declare const createCommandWithEnv: (name: string) => commander0.Command;
18
+ //#endregion
19
+ //#region src/config.d.ts
20
+ interface DatabaseConfig {
21
+ host: string;
22
+ port: number;
23
+ user: string;
24
+ pass: string;
25
+ db: string;
26
+ }
27
+ interface WithEnv<T> {
28
+ local: T;
29
+ dev: T;
30
+ stage: T;
31
+ prod: T;
32
+ }
33
+ interface CliConfig {
34
+ database: WithEnv<DatabaseConfig>;
35
+ }
36
+ declare const getConfig: <T extends CliConfig>() => Promise<T>;
37
+ //#endregion
38
+ //#region src/database.d.ts
39
+ interface KnexClientOptions {
40
+ env: Env;
41
+ }
42
+ declare const createKnexClient: (opts: KnexClientOptions) => Promise<knex.Knex<any, unknown[]>>;
43
+ //#endregion
44
+ //#region src/logger.d.ts
45
+ interface UseCliLoggerOpts {
46
+ name: string;
47
+ }
48
+ declare const useLogger: (opts: UseCliLoggerOpts) => Logger;
49
+ //#endregion
50
+ export { CliConfig, CommandArgsWithEnv, DatabaseConfig, Env, UseCliLoggerOpts, WithEnv, createCommandWithEnv, createKnexClient, getConfig, useLogger };
51
+ //# sourceMappingURL=index.d.ts.map
package/dist/index.js ADDED
@@ -0,0 +1,80 @@
1
+ import { createCommand } from "commander";
2
+ import { readFile, stat } from "fs/promises";
3
+ import { join } from "path";
4
+ import { parse } from "yaml";
5
+ import knex from "knex";
6
+ import { isObject } from "@pcg/predicates";
7
+ import clc from "cli-color";
8
+ import { createLogger, format, transports } from "winston";
9
+
10
+ //#region src/env.ts
11
+ let Env = /* @__PURE__ */ function(Env$1) {
12
+ Env$1["LOCAL"] = "local";
13
+ Env$1["DEV"] = "dev";
14
+ Env$1["STAGE"] = "stage";
15
+ Env$1["PROD"] = "prod";
16
+ return Env$1;
17
+ }({});
18
+
19
+ //#endregion
20
+ //#region src/command.ts
21
+ const createCommandWithEnv = (name) => createCommand(name).option("--env <env>", "Environment where commands will be executed", Env.LOCAL);
22
+
23
+ //#endregion
24
+ //#region src/config.ts
25
+ let cliConfig;
26
+ const getConfig = async () => {
27
+ if (cliConfig) return cliConfig;
28
+ const localConfigFile = join(process.cwd(), "/config.yml");
29
+ let configFile = "";
30
+ try {
31
+ await stat(localConfigFile);
32
+ configFile = localConfigFile;
33
+ } catch {
34
+ throw new Error("Can`t find config.yml file in project root directory");
35
+ }
36
+ cliConfig = parse(await readFile(configFile, { encoding: "utf-8" }));
37
+ return cliConfig;
38
+ };
39
+
40
+ //#endregion
41
+ //#region src/database.ts
42
+ const createKnexClient = async (opts) => {
43
+ const dbConfig = (await getConfig()).database[opts.env];
44
+ return knex({
45
+ client: "pg",
46
+ connection: {
47
+ host: dbConfig.host,
48
+ port: dbConfig.port,
49
+ user: dbConfig.user,
50
+ password: dbConfig.pass,
51
+ database: dbConfig.db
52
+ }
53
+ });
54
+ };
55
+
56
+ //#endregion
57
+ //#region src/logger.ts
58
+ const colorScheme = {
59
+ info: clc.greenBright,
60
+ error: clc.red,
61
+ warn: clc.yellow,
62
+ debug: clc.magentaBright
63
+ };
64
+ const useLogger = (opts) => {
65
+ const { name } = opts;
66
+ const plainText = format.printf(({ level, message, timestamp }) => {
67
+ const color = colorScheme[level] || ((text) => text);
68
+ if (isObject(message)) message = JSON.stringify(message, null, 2);
69
+ return `${timestamp} ${color(level.toUpperCase().padEnd(5))} ${clc.yellow(`[${name}]`)} ${color(message)}`;
70
+ });
71
+ return createLogger({
72
+ level: "debug",
73
+ transports: [new transports.Console()],
74
+ format: format.combine(format.timestamp(), plainText)
75
+ });
76
+ };
77
+
78
+ //#endregion
79
+ export { Env, createCommandWithEnv, createKnexClient, getConfig, useLogger };
80
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","names":["cliConfig: CliConfig","colorScheme: Record<string, bare.Format>"],"sources":["../src/env.ts","../src/command.ts","../src/config.ts","../src/database.ts","../src/logger.ts"],"sourcesContent":["export enum Env {\n LOCAL = 'local',\n DEV = 'dev',\n STAGE = 'stage',\n PROD = 'prod',\n}\n","import { createCommand } from 'commander';\n\nimport { Env } from './env.js';\n\nexport interface CommandArgsWithEnv {\n env: Env;\n}\n\nexport const createCommandWithEnv = (name: string) => createCommand(name)\n .option('--env <env>', 'Environment where commands will be executed', Env.LOCAL);\n","import { readFile, stat } from 'fs/promises';\nimport { join } from 'path';\nimport { parse } from 'yaml';\n\nexport interface DatabaseConfig {\n host: string;\n port: number;\n user: string;\n pass: string;\n db: string;\n}\n\nexport interface WithEnv<T> {\n local: T;\n dev: T;\n stage: T;\n prod: T;\n}\n\nexport interface CliConfig {\n database: WithEnv<DatabaseConfig>;\n}\n\nlet cliConfig: CliConfig;\nexport const getConfig = async <T extends CliConfig>(): Promise<T> => {\n if (cliConfig) {\n return cliConfig as T;\n }\n\n const localConfigFile = join(process.cwd(), '/config.yml');\n\n let configFile = '';\n try {\n await stat(localConfigFile);\n configFile = localConfigFile;\n } catch {\n throw new Error('Can`t find config.yml file in project root directory');\n }\n\n cliConfig = parse(\n await readFile(configFile, {\n encoding: 'utf-8',\n }),\n );\n\n return cliConfig as T;\n};\n","/* eslint-disable @typescript-eslint/no-explicit-any */\nimport { default as knex } from 'knex';\n\nimport { getConfig } from './config.js';\nimport { Env } from './env.js';\n\ninterface KnexClientOptions {\n env: Env;\n}\n\nexport const createKnexClient = async (opts: KnexClientOptions) => {\n const appConfig = await getConfig();\n const dbConfig = appConfig.database[opts.env];\n\n return knex({\n client: 'pg',\n connection: {\n host: dbConfig.host,\n port: dbConfig.port,\n user: dbConfig.user,\n password: dbConfig.pass,\n database: dbConfig.db,\n },\n });\n};\n\n","import { isObject } from '@pcg/predicates';\nimport clc from 'cli-color';\nimport bare from 'cli-color/bare';\nimport {\n createLogger, format,\n Logger, transports,\n} from 'winston';\n\nconst colorScheme: Record<string, bare.Format> = {\n info: clc.greenBright,\n error: clc.red,\n warn: clc.yellow,\n debug: clc.magentaBright,\n};\n\nexport interface UseCliLoggerOpts {\n name: string;\n}\n\nexport const useLogger = (opts: UseCliLoggerOpts): Logger => {\n const { name } = opts;\n\n const plainText = format.printf(({\n level,\n message,\n timestamp,\n }) => {\n const color = colorScheme[level] || ((text: string): string => text);\n\n if (isObject(message)) {\n message = JSON.stringify(message, null, 2);\n }\n\n const sTimestamp = timestamp;\n const sLevel = color(level.toUpperCase().padEnd(5));\n const sName = clc.yellow(`[${name}]`);\n const sMessage = color(message);\n\n return `${sTimestamp} ${sLevel} ${sName} ${sMessage}`;\n });\n\n return createLogger({\n level: 'debug',\n transports: [\n new transports.Console(),\n ],\n format: format.combine(\n format.timestamp(),\n plainText,\n ),\n });\n};\n"],"mappings":";;;;;;;;;;AAAA,IAAY,sCAAL;AACL;AACA;AACA;AACA;;;;;;ACIF,MAAa,wBAAwB,SAAiB,cAAc,KAAK,CACtE,OAAO,eAAe,+CAA+C,IAAI,MAAM;;;;ACclF,IAAIA;AACJ,MAAa,YAAY,YAA6C;AACpE,KAAI,UACF,QAAO;CAGT,MAAM,kBAAkB,KAAK,QAAQ,KAAK,EAAE,cAAc;CAE1D,IAAI,aAAa;AACjB,KAAI;AACF,QAAM,KAAK,gBAAgB;AAC3B,eAAa;SACP;AACN,QAAM,IAAI,MAAM,uDAAuD;;AAGzE,aAAY,MACV,MAAM,SAAS,YAAY,EACzB,UAAU,SACX,CAAC,CACH;AAED,QAAO;;;;;ACnCT,MAAa,mBAAmB,OAAO,SAA4B;CAEjE,MAAM,YADY,MAAM,WAAW,EACR,SAAS,KAAK;AAEzC,QAAO,KAAK;EACV,QAAQ;EACR,YAAY;GACV,MAAM,SAAS;GACf,MAAM,SAAS;GACf,MAAM,SAAS;GACf,UAAU,SAAS;GACnB,UAAU,SAAS;GACpB;EACF,CAAC;;;;;ACfJ,MAAMC,cAA2C;CAC/C,MAAM,IAAI;CACV,OAAO,IAAI;CACX,MAAM,IAAI;CACV,OAAO,IAAI;CACZ;AAMD,MAAa,aAAa,SAAmC;CAC3D,MAAM,EAAE,SAAS;CAEjB,MAAM,YAAY,OAAO,QAAQ,EAC/B,OACA,SACA,gBACI;EACJ,MAAM,QAAQ,YAAY,YAAY,SAAyB;AAE/D,MAAI,SAAS,QAAQ,CACnB,WAAU,KAAK,UAAU,SAAS,MAAM,EAAE;AAQ5C,SAAO,GALY,UAKE,GAJN,MAAM,MAAM,aAAa,CAAC,OAAO,EAAE,CAAC,CAIpB,GAHjB,IAAI,OAAO,IAAI,KAAK,GAAG,CAGG,GAFvB,MAAM,QAAQ;GAG/B;AAEF,QAAO,aAAa;EAClB,OAAO;EACP,YAAY,CACV,IAAI,WAAW,SAAS,CACzB;EACD,QAAQ,OAAO,QACb,OAAO,WAAW,EAClB,UACD;EACF,CAAC"}
@@ -0,0 +1,14 @@
1
+ //
2
+ // @pkg 📦 DeepVision ESLint Config [NestJS]
3
+ // @version 📍 1.0.0
4
+ // @author 🐳 DeepVision Team <code@deepvision.team>
5
+ //
6
+ // Documentation reference: https://eslint.org/docs/user-guide/configuring/
7
+ // ESLint versions: https://eslint.org/blog/
8
+ //
9
+ // eslint-disable-next-line @typescript-eslint/no-require-imports, node/no-unpublished-require
10
+ const deep = require('@deepvision/eslint-plugin');
11
+
12
+ module.exports = [
13
+ ...deep.default.configs.node,
14
+ ];
@@ -0,0 +1,5 @@
1
+ import deepEslint, { defineConfig } from '@deepvision/eslint-plugin';
2
+
3
+ export default defineConfig([
4
+ deepEslint.configs.vue,
5
+ ]);
package/package.json ADDED
@@ -0,0 +1,29 @@
1
+ {
2
+ "name": "@pcg/cli-tools",
3
+ "version": "1.0.0-alpha.2",
4
+ "description": "CLI utilities for database, logging and configuration",
5
+ "type": "module",
6
+ "main": "dist/index.js",
7
+ "types": "dist/index.d.ts",
8
+ "dependencies": {
9
+ "cli-color": "^2.0.4",
10
+ "winston": "^3.19.0",
11
+ "yaml": "^2.8.0",
12
+ "@pcg/predicates": "1.0.0-alpha.1"
13
+ },
14
+ "devDependencies": {
15
+ "@types/cli-color": "^2.0.6",
16
+ "@types/pg": "^8.16.0",
17
+ "knex": "^3.1.0"
18
+ },
19
+ "peerDependencies": {
20
+ "commander": "^13.0.0",
21
+ "knex": "^3.1.0",
22
+ "pg": "^8.16.3"
23
+ },
24
+ "scripts": {
25
+ "dev": "tsdown --watch",
26
+ "build": "tsdown",
27
+ "lint": "eslint \"src/**/*.ts\" --fix"
28
+ }
29
+ }
package/src/command.ts ADDED
@@ -0,0 +1,10 @@
1
+ import { createCommand } from 'commander';
2
+
3
+ import { Env } from './env.js';
4
+
5
+ export interface CommandArgsWithEnv {
6
+ env: Env;
7
+ }
8
+
9
+ export const createCommandWithEnv = (name: string) => createCommand(name)
10
+ .option('--env <env>', 'Environment where commands will be executed', Env.LOCAL);
package/src/config.ts ADDED
@@ -0,0 +1,47 @@
1
+ import { readFile, stat } from 'fs/promises';
2
+ import { join } from 'path';
3
+ import { parse } from 'yaml';
4
+
5
+ export interface DatabaseConfig {
6
+ host: string;
7
+ port: number;
8
+ user: string;
9
+ pass: string;
10
+ db: string;
11
+ }
12
+
13
+ export interface WithEnv<T> {
14
+ local: T;
15
+ dev: T;
16
+ stage: T;
17
+ prod: T;
18
+ }
19
+
20
+ export interface CliConfig {
21
+ database: WithEnv<DatabaseConfig>;
22
+ }
23
+
24
+ let cliConfig: CliConfig | undefined;
25
+ export const getConfig = async <T extends CliConfig>(): Promise<T> => {
26
+ if (cliConfig) {
27
+ return cliConfig as T;
28
+ }
29
+
30
+ const localConfigFile = join(process.cwd(), '/config.yml');
31
+
32
+ let configFile = '';
33
+ try {
34
+ await stat(localConfigFile);
35
+ configFile = localConfigFile;
36
+ } catch {
37
+ throw new Error('Can`t find config.yml file in project root directory');
38
+ }
39
+
40
+ cliConfig = parse(
41
+ await readFile(configFile, {
42
+ encoding: 'utf-8',
43
+ }),
44
+ ) as CliConfig;
45
+
46
+ return cliConfig as T;
47
+ };
@@ -0,0 +1,24 @@
1
+ import { default as knex } from 'knex';
2
+
3
+ import { getConfig } from './config.js';
4
+ import { type Env } from './env.js';
5
+
6
+ interface KnexClientOptions {
7
+ env: Env;
8
+ }
9
+
10
+ export const createKnexClient = async (opts: KnexClientOptions) => {
11
+ const appConfig = await getConfig();
12
+ const dbConfig = appConfig.database[opts.env];
13
+
14
+ return knex({
15
+ client: 'pg',
16
+ connection: {
17
+ host: dbConfig.host,
18
+ port: dbConfig.port,
19
+ user: dbConfig.user,
20
+ password: dbConfig.pass,
21
+ database: dbConfig.db,
22
+ },
23
+ });
24
+ };
package/src/env.ts ADDED
@@ -0,0 +1,6 @@
1
+ export enum Env {
2
+ LOCAL = 'local',
3
+ DEV = 'dev',
4
+ STAGE = 'stage',
5
+ PROD = 'prod',
6
+ }
package/src/index.ts ADDED
@@ -0,0 +1,5 @@
1
+ export * from './command.js';
2
+ export * from './config.js';
3
+ export * from './database.js';
4
+ export * from './env.js';
5
+ export * from './logger.js';
package/src/logger.ts ADDED
@@ -0,0 +1,54 @@
1
+ import { isObject } from '@pcg/predicates';
2
+ import clc from 'cli-color';
3
+ import {
4
+ createLogger, format,
5
+ type Logger, transports,
6
+ } from 'winston';
7
+
8
+ type ColorFn = (text: string) => string;
9
+
10
+ const colorScheme: Record<string, ColorFn> = {
11
+ info: clc.greenBright as ColorFn,
12
+ error: clc.red as ColorFn,
13
+ warn: clc.yellow as ColorFn,
14
+ debug: clc.magentaBright as ColorFn,
15
+ };
16
+
17
+ export interface UseCliLoggerOpts {
18
+ name: string;
19
+ }
20
+
21
+ export const useLogger = (opts: UseCliLoggerOpts): Logger => {
22
+ const { name } = opts;
23
+
24
+ const plainText = format.printf(({
25
+ level,
26
+ message,
27
+ timestamp,
28
+ }) => {
29
+ const color: ColorFn = colorScheme[level] ?? ((text: string): string => text);
30
+
31
+ let msg: string = typeof message === 'string' ? message : '';
32
+ if (isObject(message)) {
33
+ msg = JSON.stringify(message, null, 2);
34
+ }
35
+
36
+ const sTimestamp = typeof timestamp === 'string' ? timestamp : '';
37
+ const sLevel = color(level.toUpperCase().padEnd(5));
38
+ const sName = (clc.yellow as ColorFn)(`[${name}]`);
39
+ const sMessage = color(msg);
40
+
41
+ return `${sTimestamp} ${sLevel} ${sName} ${sMessage}`;
42
+ });
43
+
44
+ return createLogger({
45
+ level: 'debug',
46
+ transports: [
47
+ new transports.Console(),
48
+ ],
49
+ format: format.combine(
50
+ format.timestamp(),
51
+ plainText,
52
+ ),
53
+ });
54
+ };
package/tsconfig.json ADDED
@@ -0,0 +1,9 @@
1
+ {
2
+ "extends": "../../tsconfig.base.json",
3
+ "compilerOptions": {
4
+ "outDir": "dist",
5
+ "moduleResolution": "bundler",
6
+ },
7
+ "include": ["src/**/*.ts"],
8
+ "exclude": ["node_modules", "dist"],
9
+ }
@@ -0,0 +1,9 @@
1
+ {
2
+ "extends": "../../tsconfig.base.json",
3
+ "compilerOptions": {
4
+ "outDir": "dist",
5
+ "moduleResolution": "bundler",
6
+ },
7
+ "include": ["src/**/*.ts"],
8
+ "exclude": ["node_modules", "dist"],
9
+ }
@@ -0,0 +1,11 @@
1
+ import { defineConfig } from 'tsdown';
2
+
3
+ export default defineConfig({
4
+ entry: ['src/index.ts'],
5
+ tsconfig: './tsconfig.lib.json',
6
+ outDir: 'dist',
7
+ dts: true,
8
+ clean: true,
9
+ sourcemap: true,
10
+ format: 'esm',
11
+ });