Add CLI package for consuming backend core API.master
@@ -0,0 +1,9 @@ | |||
{ | |||
"root": true, | |||
"extends": [ | |||
"lxsmnsyc/typescript" | |||
], | |||
"parserOptions": { | |||
"project": "./tsconfig.eslint.json" | |||
} | |||
} |
@@ -0,0 +1,107 @@ | |||
# Logs | |||
logs | |||
*.log | |||
npm-debug.log* | |||
yarn-debug.log* | |||
yarn-error.log* | |||
lerna-debug.log* | |||
# Diagnostic reports (https://nodejs.org/api/report.html) | |||
report.[0-9]*.[0-9]*.[0-9]*.[0-9]*.json | |||
# Runtime data | |||
pids | |||
*.pid | |||
*.seed | |||
*.pid.lock | |||
# Directory for instrumented libs generated by jscoverage/JSCover | |||
lib-cov | |||
# Coverage directory used by tools like istanbul | |||
coverage | |||
*.lcov | |||
# nyc test coverage | |||
.nyc_output | |||
# Grunt intermediate storage (https://gruntjs.com/creating-plugins#storing-task-files) | |||
.grunt | |||
# Bower dependency directory (https://bower.io/) | |||
bower_components | |||
# node-waf configuration | |||
.lock-wscript | |||
# Compiled binary addons (https://nodejs.org/api/addons.html) | |||
build/Release | |||
# Dependency directories | |||
node_modules/ | |||
jspm_packages/ | |||
# TypeScript v1 declaration files | |||
typings/ | |||
# TypeScript cache | |||
*.tsbuildinfo | |||
# Optional npm cache directory | |||
.npm | |||
# Optional eslint cache | |||
.eslintcache | |||
# Microbundle cache | |||
.rpt2_cache/ | |||
.rts2_cache_cjs/ | |||
.rts2_cache_es/ | |||
.rts2_cache_umd/ | |||
# Optional REPL history | |||
.node_repl_history | |||
# Output of 'npm pack' | |||
*.tgz | |||
# Yarn Integrity file | |||
.yarn-integrity | |||
# dotenv environment variables file | |||
.env | |||
.env.production | |||
.env.development | |||
# parcel-bundler cache (https://parceljs.org/) | |||
.cache | |||
# Next.js build output | |||
.next | |||
# Nuxt.js build / generate output | |||
.nuxt | |||
dist | |||
# Gatsby files | |||
.cache/ | |||
# Comment in the public line in if your project uses Gatsby and *not* Next.js | |||
# https://nextjs.org/blog/next-9-1#public-directory-support | |||
# public | |||
# vuepress build output | |||
.vuepress/dist | |||
# Serverless directories | |||
.serverless/ | |||
# FuseBox cache | |||
.fusebox/ | |||
# DynamoDB Local files | |||
.dynamodb/ | |||
# TernJS port file | |||
.tern-port | |||
.npmrc |
@@ -0,0 +1,72 @@ | |||
{ | |||
"name": "@modal-sh/cli", | |||
"version": "0.0.0", | |||
"files": [ | |||
"dist", | |||
"src" | |||
], | |||
"engines": { | |||
"node": ">=12" | |||
}, | |||
"license": "UNLICENSED", | |||
"keywords": [ | |||
"pridepack" | |||
], | |||
"devDependencies": { | |||
"@types/node": "^18.14.1", | |||
"@types/yargs": "^17.0.24", | |||
"eslint": "^8.35.0", | |||
"eslint-config-lxsmnsyc": "^0.5.0", | |||
"pridepack": "2.4.4", | |||
"tslib": "^2.5.0", | |||
"typescript": "^4.9.5", | |||
"vitest": "^0.28.1" | |||
}, | |||
"scripts": { | |||
"prepublishOnly": "pridepack clean && pridepack build", | |||
"build": "pridepack build", | |||
"type-check": "pridepack check", | |||
"lint": "pridepack lint", | |||
"clean": "pridepack clean", | |||
"watch": "pridepack watch", | |||
"start": "pridepack start", | |||
"dev": "pridepack dev", | |||
"test": "vitest" | |||
}, | |||
"private": true, | |||
"description": "CLI app.", | |||
"repository": { | |||
"url": "", | |||
"type": "git" | |||
}, | |||
"homepage": "", | |||
"bugs": { | |||
"url": "" | |||
}, | |||
"author": "TheoryOfNekomata <allan.crisostomo@outlook.com>", | |||
"publishConfig": { | |||
"access": "restricted" | |||
}, | |||
"types": "./dist/types/index.d.ts", | |||
"main": "./dist/cjs/production/index.js", | |||
"module": "./dist/esm/production/index.js", | |||
"exports": { | |||
".": { | |||
"development": { | |||
"require": "./dist/cjs/development/index.js", | |||
"import": "./dist/esm/development/index.js" | |||
}, | |||
"require": "./dist/cjs/production/index.js", | |||
"import": "./dist/esm/production/index.js", | |||
"types": "./dist/types/index.d.ts" | |||
} | |||
}, | |||
"typesVersions": { | |||
"*": {} | |||
}, | |||
"dependencies": { | |||
"@clack/core": "^0.3.2", | |||
"@modal-sh/core": "workspace:*", | |||
"yargs": "^17.7.2" | |||
} | |||
} |
@@ -0,0 +1,3 @@ | |||
{ | |||
"target": "es2018" | |||
} |
@@ -0,0 +1,5 @@ | |||
import yargs from 'yargs'; | |||
export const createCli = (argv: typeof process.argv) => { | |||
return yargs(argv); | |||
}; |
@@ -0,0 +1,15 @@ | |||
import yargs from 'yargs'; | |||
import { AdderController, AdderControllerImpl } from './modules/adder'; | |||
export const addCommands = (cli: yargs.Argv) => { | |||
const adderController: AdderController = new AdderControllerImpl(); | |||
cli.command({ | |||
aliases: ['a'], | |||
command: 'add <a> <b>', | |||
describe: 'Add two numbers', | |||
handler: adderController.addNumbers, | |||
}); | |||
return cli; | |||
}; |
@@ -0,0 +1,9 @@ | |||
import { addCommands } from '@/commands'; | |||
import { createCli } from '@/cli'; | |||
import { hideBin } from 'yargs/helpers'; | |||
const args = createCli(hideBin(process.argv)); | |||
addCommands(args); | |||
args.parse(); |
@@ -0,0 +1,42 @@ | |||
import { ArgumentsCamelCase } from 'yargs'; | |||
import { | |||
AdderService, | |||
AdderServiceImpl, | |||
ArgumentOutOfRangeError, | |||
InvalidArgumentTypeError, | |||
} from './adder.service'; | |||
export interface AdderController { | |||
addNumbers: (args: ArgumentsCamelCase<{ a: number, b: number }>) => void | Promise<void>; | |||
} | |||
export class AdderControllerImpl implements AdderController { | |||
constructor( | |||
private readonly adderService: AdderService = new AdderServiceImpl(), | |||
) { | |||
// noop | |||
} | |||
readonly addNumbers = async (args: ArgumentsCamelCase<{ a: number, b: number }>) => { | |||
const { a, b } = args; | |||
try { | |||
const response = this.adderService.addNumbers({a, b}); | |||
process.stdout.write(`${response}\n`); | |||
process.exit(0); | |||
} catch (errorRaw) { | |||
const error = errorRaw as Error; | |||
if (error instanceof InvalidArgumentTypeError) { | |||
process.stderr.write(`${error.message}\n`); | |||
process.exit(-1); | |||
return; | |||
} | |||
if (error instanceof ArgumentOutOfRangeError) { | |||
process.stderr.write(`${error.message}\n`); | |||
process.exit(-2); | |||
return; | |||
} | |||
process.stderr.write(`${error.message}\n`); | |||
process.exit(-3); | |||
} | |||
} | |||
} |
@@ -0,0 +1,21 @@ | |||
import { | |||
add, | |||
AddFunctionOptions, | |||
ArgumentOutOfRangeError, | |||
InvalidArgumentTypeError, | |||
} from '@modal-sh/core'; | |||
export interface AdderService { | |||
addNumbers(options: AddFunctionOptions): number; | |||
} | |||
export class AdderServiceImpl implements AdderService { | |||
addNumbers(options: AddFunctionOptions) { | |||
return add(options); | |||
} | |||
} | |||
export { | |||
ArgumentOutOfRangeError, | |||
InvalidArgumentTypeError, | |||
}; |
@@ -0,0 +1,2 @@ | |||
export * from './adder.controller'; | |||
export * from './adder.service'; |
@@ -0,0 +1,64 @@ | |||
import {describe, it, expect, vi, beforeAll, afterAll} from 'vitest'; | |||
import { createCli } from '../src/cli'; | |||
import { addCommands } from '../src/commands'; | |||
import yargs from 'yargs'; | |||
import { AdderServiceImpl, InvalidArgumentTypeError, ArgumentOutOfRangeError } from '../src/modules/adder'; | |||
vi.mock('process'); | |||
describe('blah', () => { | |||
let cli: yargs.Argv; | |||
let exit: vi.Mock<typeof process.exit>; | |||
let exitReal: typeof process.exit; | |||
beforeAll(() => { | |||
exitReal = process.exit.bind(process); | |||
const processMut = process as unknown as Record<string, unknown>; | |||
processMut.exit = exit = vi.fn(); | |||
}); | |||
afterAll(() => { | |||
process.exit = exitReal = process.exit.bind(process); | |||
}); | |||
it('returns result when successful', async () => { | |||
cli = createCli(['add', '1', '2']); | |||
addCommands(cli); | |||
await cli.parse(); | |||
expect(exit).toHaveBeenCalledWith(0); | |||
}); | |||
it('returns error when given invalid inputs', async () => { | |||
vi.spyOn(AdderServiceImpl.prototype, 'addNumbers').mockImplementationOnce(() => { | |||
throw new InvalidArgumentTypeError('Invalid input'); | |||
}); | |||
cli = createCli(['add', '1', '2']); | |||
addCommands(cli); | |||
await cli.parse(); | |||
expect(exit).toHaveBeenCalledWith(-1); | |||
}); | |||
it('returns error when given out-of-range inputs', async () => { | |||
vi.spyOn(AdderServiceImpl.prototype, 'addNumbers').mockImplementationOnce(() => { | |||
throw new ArgumentOutOfRangeError('Out of range'); | |||
}); | |||
cli = createCli(['add', '1', '2']); | |||
addCommands(cli); | |||
await cli.parse(); | |||
expect(exit).toHaveBeenCalledWith(-2); | |||
}); | |||
it('returns error when an unexpected error occurs', async () => { | |||
vi.spyOn(AdderServiceImpl.prototype, 'addNumbers').mockImplementationOnce(() => { | |||
throw new Error('Unexpected error'); | |||
}); | |||
cli = createCli(['add', '1', '2']); | |||
addCommands(cli); | |||
await cli.parse(); | |||
expect(exit).toHaveBeenCalledWith(-2); | |||
}); | |||
}); |
@@ -0,0 +1,24 @@ | |||
{ | |||
"exclude": ["node_modules"], | |||
"include": ["src", "types", "test"], | |||
"compilerOptions": { | |||
"module": "ESNext", | |||
"lib": ["ESNext"], | |||
"importHelpers": true, | |||
"declaration": true, | |||
"sourceMap": true, | |||
"rootDir": "./", | |||
"strict": true, | |||
"noUnusedLocals": true, | |||
"noUnusedParameters": true, | |||
"noImplicitReturns": true, | |||
"noFallthroughCasesInSwitch": true, | |||
"moduleResolution": "node", | |||
"jsx": "react", | |||
"esModuleInterop": true, | |||
"target": "es2018", | |||
"paths": { | |||
"@/*": ["./src/*"], | |||
} | |||
} | |||
} |
@@ -0,0 +1,24 @@ | |||
{ | |||
"exclude": ["node_modules"], | |||
"include": ["src", "types"], | |||
"compilerOptions": { | |||
"module": "ESNext", | |||
"lib": ["ESNext"], | |||
"importHelpers": true, | |||
"declaration": true, | |||
"sourceMap": true, | |||
"rootDir": "./src", | |||
"strict": true, | |||
"noUnusedLocals": true, | |||
"noUnusedParameters": true, | |||
"noImplicitReturns": true, | |||
"noFallthroughCasesInSwitch": true, | |||
"moduleResolution": "node", | |||
"jsx": "react", | |||
"esModuleInterop": true, | |||
"target": "es2018", | |||
"paths": { | |||
"@/*": ["./src/*"], | |||
} | |||
} | |||
} |
@@ -7,16 +7,27 @@ export interface AddFunction { | |||
(options: AddFunctionOptions): number; | |||
} | |||
export class InvalidArgumentTypeError extends TypeError { | |||
constructor(message: string) { | |||
super(message); | |||
this.name = 'InvalidArgumentTypeError'; | |||
} | |||
} | |||
export class ArgumentOutOfRangeError extends RangeError { | |||
constructor(message: string) { | |||
super(message); | |||
this.name = 'ArgumentOutOfRangeError'; | |||
} | |||
} | |||
export const add: AddFunction = (options: AddFunctionOptions): number => { | |||
if (process.env.NODE_ENV !== 'production') { | |||
console.log('This code would not appear on production builds'); | |||
} | |||
const { a, b } = options as unknown as Record<string, unknown>; | |||
if (typeof a !== 'number' || typeof b !== 'number') { | |||
throw new TypeError('a and b must be numbers'); | |||
throw new InvalidArgumentTypeError('a and b must be numbers'); | |||
} | |||
if (!Number.isFinite(a) || !Number.isFinite(b)) { | |||
throw new RangeError('a and b must be finite numbers'); | |||
throw new ArgumentOutOfRangeError('a and b must be finite numbers'); | |||
} | |||
return a + b; | |||
@@ -2,7 +2,15 @@ import { describe, it, expect } from 'vitest'; | |||
import { add } from '../src'; | |||
describe('blah', () => { | |||
it('works', () => { | |||
it('returns result', () => { | |||
expect(add({ a: 1, b: 1 })).toEqual(2); | |||
}); | |||
it('throws when given invalid argument types', () => { | |||
expect(() => add({ a: '1' as unknown as number, b: 1 })).toThrow(TypeError); | |||
}); | |||
it('throws when given out-of-range arguments', () => { | |||
expect(() => add({ a: Infinity, b: 1 })).toThrow(RangeError); | |||
}); | |||
}); |
@@ -50,5 +50,22 @@ | |||
"author": "TheoryOfNekomata <allan.crisostomo@outlook.com>", | |||
"publishConfig": { | |||
"access": "restricted" | |||
} | |||
}, | |||
"types": "./dist/types/index.d.ts", | |||
"main": "./dist/cjs/production/index.js", | |||
"module": "./dist/esm/production/index.js", | |||
"exports": { | |||
".": { | |||
"development": { | |||
"require": "./dist/cjs/development/index.js", | |||
"import": "./dist/esm/development/index.js" | |||
}, | |||
"require": "./dist/cjs/production/index.js", | |||
"import": "./dist/esm/production/index.js", | |||
"types": "./dist/types/index.d.ts" | |||
} | |||
}, | |||
"typesVersions": { | |||
"*": {} | |||
} | |||
} |
@@ -1,5 +1,6 @@ | |||
export namespace meta { | |||
export const host = process.env.HOST ?? '0.0.0.0'; | |||
export const port = Number(process.env.PORT ?? 8080); | |||
export const env = process.env.NODE_ENV ?? 'development'; | |||
@@ -2,10 +2,8 @@ import { createServer } from '@/server'; | |||
import { addRoutes } from '@/routes'; | |||
import * as config from '@/config'; | |||
const logger = config.meta.env !== 'test'; | |||
const server = createServer({ | |||
logger, | |||
logger: config.meta.env !== 'test', | |||
}); | |||
addRoutes(server); | |||
@@ -0,0 +1,39 @@ | |||
import { RouteHandlerMethod } from 'fastify'; | |||
import { | |||
AdderService, | |||
AdderServiceImpl, | |||
ArgumentOutOfRangeError, | |||
InvalidArgumentTypeError, | |||
} from '@/modules/adder/adder.service'; | |||
import { constants } from 'http2'; | |||
export interface AdderController { | |||
addNumbers: RouteHandlerMethod; | |||
} | |||
export class AdderControllerImpl implements AdderController { | |||
constructor( | |||
private readonly adderService: AdderService = new AdderServiceImpl(), | |||
) { | |||
// noop | |||
} | |||
readonly addNumbers: RouteHandlerMethod = async (request, reply) => { | |||
const { a, b } = request.body as { a: number; b: number }; | |||
try { | |||
const response = this.adderService.addNumbers({a, b}); | |||
reply.send(response); | |||
} catch (errorRaw) { | |||
if (errorRaw instanceof InvalidArgumentTypeError) { | |||
reply.status(constants.HTTP_STATUS_BAD_REQUEST).send(errorRaw.message); | |||
return; | |||
} | |||
if (errorRaw instanceof ArgumentOutOfRangeError) { | |||
reply.status(constants.HTTP_STATUS_BAD_REQUEST).send(errorRaw.message); | |||
return; | |||
} | |||
const error = errorRaw as Error; | |||
reply.status(constants.HTTP_STATUS_INTERNAL_SERVER_ERROR).send(error.message); | |||
} | |||
} | |||
} |
@@ -0,0 +1,21 @@ | |||
import { | |||
add, | |||
AddFunctionOptions, | |||
ArgumentOutOfRangeError, | |||
InvalidArgumentTypeError, | |||
} from '@modal-sh/core'; | |||
export interface AdderService { | |||
addNumbers(options: AddFunctionOptions): number; | |||
} | |||
export class AdderServiceImpl implements AdderService { | |||
addNumbers(options: AddFunctionOptions) { | |||
return add(options); | |||
} | |||
} | |||
export { | |||
ArgumentOutOfRangeError, | |||
InvalidArgumentTypeError, | |||
}; |
@@ -0,0 +1,2 @@ | |||
export * from './adder.controller'; | |||
export * from './adder.service'; |
@@ -1,22 +1,13 @@ | |||
import { FastifyInstance } from 'fastify'; | |||
import { add, AddFunctionOptions } from '@modal-sh/core'; | |||
import { AdderController, AdderControllerImpl } from '@/modules/adder'; | |||
export const addRoutes = (server: FastifyInstance) => { | |||
server.post('/', async (request, reply) => { | |||
const { a, b } = request.body as AddFunctionOptions; | |||
try { | |||
const response = add({a, b}); | |||
reply.send(response); | |||
} catch (errorRaw) { | |||
if (errorRaw instanceof TypeError) { | |||
reply.status(400).send(errorRaw.message); | |||
} else if (errorRaw instanceof RangeError) { | |||
reply.status(400).send(errorRaw.message); | |||
} else { | |||
const error = errorRaw as Error; | |||
reply.status(500).send(error.message); | |||
} | |||
} | |||
const adderController: AdderController = new AdderControllerImpl(); | |||
server.route({ | |||
method: 'POST', | |||
url: '/', | |||
handler: adderController.addNumbers, | |||
}); | |||
return server; | |||
@@ -5,30 +5,83 @@ import { | |||
expect, | |||
beforeAll, | |||
afterAll, | |||
vi, | |||
} from 'vitest'; | |||
import { constants } from 'http2'; | |||
import { createServer } from '../src/server'; | |||
import { addRoutes } from '../src/routes'; | |||
import { | |||
AdderServiceImpl, | |||
ArgumentOutOfRangeError, | |||
InvalidArgumentTypeError, | |||
} from '../src/modules/adder'; | |||
describe('Example', () => { | |||
let SERVER: FastifyInstance; | |||
let server: FastifyInstance; | |||
const body = { a: 1, b: 2 }; | |||
beforeAll(() => { | |||
SERVER = createServer(); | |||
addRoutes(SERVER); | |||
server = createServer(); | |||
addRoutes(server); | |||
}); | |||
afterAll(async () => { | |||
await SERVER.close(); | |||
await server.close(); | |||
}); | |||
it('should have the expected content', async () => { | |||
const response = await SERVER | |||
it('returns result when successful', async () => { | |||
const response = await server | |||
.inject() | |||
.post('/') | |||
.body({ a: 1, b: 2 }) | |||
.body(body) | |||
.headers({ | |||
'Accept': 'application/json', | |||
}); | |||
expect(response.statusCode).toBe(200); | |||
expect(response.statusCode).toBe(constants.HTTP_STATUS_OK); | |||
}); | |||
it('returns error when given invalid inputs', async () => { | |||
vi.spyOn(AdderServiceImpl.prototype, 'addNumbers').mockImplementationOnce(() => { | |||
throw new InvalidArgumentTypeError('Invalid input'); | |||
}); | |||
const response = await server | |||
.inject() | |||
.post('/') | |||
.body(body) | |||
.headers({ | |||
'Accept': 'application/json', | |||
}); | |||
expect(response.statusCode).toBe(constants.HTTP_STATUS_BAD_REQUEST); | |||
}); | |||
it('returns error when given out-of-range inputs', async () => { | |||
vi.spyOn(AdderServiceImpl.prototype, 'addNumbers').mockImplementationOnce(() => { | |||
throw new ArgumentOutOfRangeError('Out of range'); | |||
}); | |||
const response = await server | |||
.inject() | |||
.post('/') | |||
.body(body) | |||
.headers({ | |||
'Accept': 'application/json', | |||
}); | |||
expect(response.statusCode).toBe(constants.HTTP_STATUS_BAD_REQUEST); | |||
}); | |||
it('returns error when an unexpected error occurs', async () => { | |||
vi.spyOn(AdderServiceImpl.prototype, 'addNumbers').mockImplementationOnce(() => { | |||
throw new Error('Unexpected error'); | |||
}); | |||
const response = await server | |||
.inject() | |||
.post('/') | |||
.body({ a: 1, b: 2 }) | |||
.headers({ | |||
'Accept': 'application/json', | |||
}); | |||
expect(response.statusCode).toBe(constants.HTTP_STATUS_INTERNAL_SERVER_ERROR); | |||
}); | |||
}); |
@@ -6,6 +6,43 @@ settings: | |||
importers: | |||
packages/cli: | |||
dependencies: | |||
'@clack/core': | |||
specifier: ^0.3.2 | |||
version: 0.3.2 | |||
'@modal-sh/core': | |||
specifier: workspace:* | |||
version: link:../core | |||
yargs: | |||
specifier: ^17.7.2 | |||
version: 17.7.2 | |||
devDependencies: | |||
'@types/node': | |||
specifier: ^18.14.1 | |||
version: 18.14.1 | |||
'@types/yargs': | |||
specifier: ^17.0.24 | |||
version: 17.0.24 | |||
eslint: | |||
specifier: ^8.35.0 | |||
version: 8.35.0 | |||
eslint-config-lxsmnsyc: | |||
specifier: ^0.5.0 | |||
version: 0.5.0(eslint@8.35.0)(typescript@4.9.5) | |||
pridepack: | |||
specifier: 2.4.4 | |||
version: 2.4.4(eslint@8.35.0)(tslib@2.5.0)(typescript@4.9.5) | |||
tslib: | |||
specifier: ^2.5.0 | |||
version: 2.5.0 | |||
typescript: | |||
specifier: ^4.9.5 | |||
version: 4.9.5 | |||
vitest: | |||
specifier: ^0.28.1 | |||
version: 0.28.1 | |||
packages/core: | |||
devDependencies: | |||
'@types/node': | |||
@@ -332,6 +369,13 @@ packages: | |||
to-fast-properties: 2.0.0 | |||
dev: true | |||
/@clack/core@0.3.2: | |||
resolution: {integrity: sha512-FZnsNynwGDIDktx6PEZK1EuCkFpY4ldEX6VYvfl0dqeoLPb9Jpw1xoUXaVcGR8ExmYNm1w2vdGdJkEUYD/2pqg==} | |||
dependencies: | |||
picocolors: 1.0.0 | |||
sisteransi: 1.0.5 | |||
dev: false | |||
/@esbuild/android-arm64@0.17.19: | |||
resolution: {integrity: sha512-KBMWvEZooR7+kzY0BtbTQn0OAYY7CsiydT63pVEaPtVYF0hXbUaOyZog37DKxK7NF3XacBJOpYT4adIJh+avxA==} | |||
engines: {node: '>=12'} | |||
@@ -727,6 +771,16 @@ packages: | |||
resolution: {integrity: sha512-G8hZ6XJiHnuhQKR7ZmysCeJWE08o8T0AXtk5darsCaTVsYZhhgUrq53jizaR2FvsoeCwJhlmwTjkXBY5Pn/ZHw==} | |||
dev: true | |||
/@types/yargs-parser@21.0.0: | |||
resolution: {integrity: sha512-iO9ZQHkZxHn4mSakYV0vFHAVDyEOIJQrV2uZ06HxEPcx+mt8swXoZHIbaaJ2crJYFfErySgktuTZ3BeLz+XmFA==} | |||
dev: true | |||
/@types/yargs@17.0.24: | |||
resolution: {integrity: sha512-6i0aC7jV6QzQB8ne1joVZ0eSFIstHsCrobmOtghM11yGlH0j43FKL2UhWdELkyps0zuf7qVTUVCCR+tgSlyLLw==} | |||
dependencies: | |||
'@types/yargs-parser': 21.0.0 | |||
dev: true | |||
/@typescript-eslint/eslint-plugin@5.60.1(@typescript-eslint/parser@5.60.1)(eslint@8.35.0)(typescript@4.9.5): | |||
resolution: {integrity: sha512-KSWsVvsJsLJv3c4e73y/Bzt7OpqMCADUO846bHcuWYSYM19bldbAeDv7dYyV0jwkbMfJ2XdlzwjhXtuD7OY6bw==} | |||
engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} | |||
@@ -964,7 +1018,6 @@ packages: | |||
/ansi-regex@5.0.1: | |||
resolution: {integrity: sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==} | |||
engines: {node: '>=8'} | |||
dev: true | |||
/ansi-regex@6.0.1: | |||
resolution: {integrity: sha512-n5M855fKb2SsfMIiFFoVrABHJC8QtHwVx+mHWP3QcEqBHYienj5dHSgjbxtC0WEZXYt4wcD6zrQElDPhFuZgfA==} | |||
@@ -983,7 +1036,6 @@ packages: | |||
engines: {node: '>=8'} | |||
dependencies: | |||
color-convert: 2.0.1 | |||
dev: true | |||
/ansi-styles@5.2.0: | |||
resolution: {integrity: sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==} | |||
@@ -1280,7 +1332,6 @@ packages: | |||
string-width: 4.2.3 | |||
strip-ansi: 6.0.1 | |||
wrap-ansi: 7.0.0 | |||
dev: true | |||
/clone@1.0.4: | |||
resolution: {integrity: sha512-JQHZ2QMW6l3aH/j6xCqQThY/9OH4D/9ls34cgkUBiEeocRTU04tHfKPBsUK1PqZCUQM7GiA0IIXJSuXHI64Kbg==} | |||
@@ -1298,7 +1349,6 @@ packages: | |||
engines: {node: '>=7.0.0'} | |||
dependencies: | |||
color-name: 1.1.4 | |||
dev: true | |||
/color-name@1.1.3: | |||
resolution: {integrity: sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==} | |||
@@ -1306,7 +1356,6 @@ packages: | |||
/color-name@1.1.4: | |||
resolution: {integrity: sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==} | |||
dev: true | |||
/concat-map@0.0.1: | |||
resolution: {integrity: sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==} | |||
@@ -1500,7 +1549,6 @@ packages: | |||
/emoji-regex@8.0.0: | |||
resolution: {integrity: sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==} | |||
dev: true | |||
/emoji-regex@9.2.2: | |||
resolution: {integrity: sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==} | |||
@@ -1611,7 +1659,6 @@ packages: | |||
/escalade@3.1.1: | |||
resolution: {integrity: sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==} | |||
engines: {node: '>=6'} | |||
dev: true | |||
/escape-string-regexp@1.0.5: | |||
resolution: {integrity: sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==} | |||
@@ -2268,7 +2315,6 @@ packages: | |||
/get-caller-file@2.0.5: | |||
resolution: {integrity: sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==} | |||
engines: {node: 6.* || 8.* || >= 10.*} | |||
dev: true | |||
/get-func-name@2.0.0: | |||
resolution: {integrity: sha512-Hm0ixYtaSZ/V7C8FJrtZIuBBI+iSgL+1Aq82zSu8VQNB4S3Gk8e7Qs3VwBDJAhmRZcFqkl3tQu36g/Foh5I5ig==} | |||
@@ -2567,7 +2613,6 @@ packages: | |||
/is-fullwidth-code-point@3.0.0: | |||
resolution: {integrity: sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==} | |||
engines: {node: '>=8'} | |||
dev: true | |||
/is-fullwidth-code-point@4.0.0: | |||
resolution: {integrity: sha512-O4L094N2/dZ7xqVdrXhh9r1KODPJpFms8B5sGdJLPy664AgvXsreZUyCQQNItZRDlYug4xStLjNp/sz3HvBowQ==} | |||
@@ -3181,7 +3226,6 @@ packages: | |||
/picocolors@1.0.0: | |||
resolution: {integrity: sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==} | |||
dev: true | |||
/picomatch@2.3.1: | |||
resolution: {integrity: sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==} | |||
@@ -3383,7 +3427,6 @@ packages: | |||
/require-directory@2.1.1: | |||
resolution: {integrity: sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==} | |||
engines: {node: '>=0.10.0'} | |||
dev: true | |||
/require-from-string@2.0.2: | |||
resolution: {integrity: sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==} | |||
@@ -3555,7 +3598,6 @@ packages: | |||
/sisteransi@1.0.5: | |||
resolution: {integrity: sha512-bLGGlR1QxBcynn2d5YmDX4MGjlZvy2MRBDRNHLJ8VI6l6+9FUiyTFNJ0IveOSP0bcXgVDPRcfGqA0pjaqUpfVg==} | |||
dev: true | |||
/slash@3.0.0: | |||
resolution: {integrity: sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==} | |||
@@ -3625,7 +3667,6 @@ packages: | |||
emoji-regex: 8.0.0 | |||
is-fullwidth-code-point: 3.0.0 | |||
strip-ansi: 6.0.1 | |||
dev: true | |||
/string-width@5.1.2: | |||
resolution: {integrity: sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==} | |||
@@ -3685,7 +3726,6 @@ packages: | |||
engines: {node: '>=8'} | |||
dependencies: | |||
ansi-regex: 5.0.1 | |||
dev: true | |||
/strip-ansi@7.1.0: | |||
resolution: {integrity: sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==} | |||
@@ -4131,7 +4171,6 @@ packages: | |||
ansi-styles: 4.3.0 | |||
string-width: 4.2.3 | |||
strip-ansi: 6.0.1 | |||
dev: true | |||
/wrap-text@1.0.9: | |||
resolution: {integrity: sha512-NWfjspSgMDXQIMpKM56AwCQPI01OMFRYYJBh6dGNCfH7AOl+j/VqqbiopgJ4VuQfSluqLc+2ekqaPNpYAGZ/Vg==} | |||
@@ -4167,7 +4206,6 @@ packages: | |||
/y18n@5.0.8: | |||
resolution: {integrity: sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==} | |||
engines: {node: '>=10'} | |||
dev: true | |||
/yallist@3.1.1: | |||
resolution: {integrity: sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==} | |||
@@ -4187,7 +4225,6 @@ packages: | |||
/yargs-parser@21.1.1: | |||
resolution: {integrity: sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==} | |||
engines: {node: '>=12'} | |||
dev: true | |||
/yargs@15.4.1: | |||
resolution: {integrity: sha512-aePbxDmcYW++PaqBsJ+HYUFwCdv4LVvdnhBy78E57PIor8/OVvhMrADFFEDh8DHDFRv/O9i3lPhsENjO7QX0+A==} | |||
@@ -4217,7 +4254,6 @@ packages: | |||
string-width: 4.2.3 | |||
y18n: 5.0.8 | |||
yargs-parser: 21.1.1 | |||
dev: true | |||
/yocto-queue@0.1.0: | |||
resolution: {integrity: sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==} | |||