ソースを参照

Implement CLI package

Add CLI package for consuming backend core API.
master
コミット
1ce787f448
24個のファイルの変更626行の追加52行の削除
  1. +9
    -0
      packages/cli/.eslintrc
  2. +107
    -0
      packages/cli/.gitignore
  3. +72
    -0
      packages/cli/package.json
  4. +3
    -0
      packages/cli/pridepack.json
  5. +5
    -0
      packages/cli/src/cli.ts
  6. +15
    -0
      packages/cli/src/commands.ts
  7. +9
    -0
      packages/cli/src/index.ts
  8. +42
    -0
      packages/cli/src/modules/adder/adder.controller.ts
  9. +21
    -0
      packages/cli/src/modules/adder/adder.service.ts
  10. +2
    -0
      packages/cli/src/modules/adder/index.ts
  11. +64
    -0
      packages/cli/test/index.test.ts
  12. +24
    -0
      packages/cli/tsconfig.eslint.json
  13. +24
    -0
      packages/cli/tsconfig.json
  14. +16
    -5
      packages/core/src/index.ts
  15. +9
    -1
      packages/core/test/index.test.ts
  16. +18
    -1
      packages/web-api/package.json
  17. +1
    -0
      packages/web-api/src/config.ts
  18. +1
    -3
      packages/web-api/src/index.ts
  19. +39
    -0
      packages/web-api/src/modules/adder/adder.controller.ts
  20. +21
    -0
      packages/web-api/src/modules/adder/adder.service.ts
  21. +2
    -0
      packages/web-api/src/modules/adder/index.ts
  22. +7
    -16
      packages/web-api/src/routes.ts
  23. +61
    -8
      packages/web-api/test/index.test.ts
  24. +54
    -18
      pnpm-lock.yaml

+ 9
- 0
packages/cli/.eslintrc ファイルの表示

@@ -0,0 +1,9 @@
{
"root": true,
"extends": [
"lxsmnsyc/typescript"
],
"parserOptions": {
"project": "./tsconfig.eslint.json"
}
}

+ 107
- 0
packages/cli/.gitignore ファイルの表示

@@ -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

+ 72
- 0
packages/cli/package.json ファイルの表示

@@ -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"
}
}

+ 3
- 0
packages/cli/pridepack.json ファイルの表示

@@ -0,0 +1,3 @@
{
"target": "es2018"
}

+ 5
- 0
packages/cli/src/cli.ts ファイルの表示

@@ -0,0 +1,5 @@
import yargs from 'yargs';

export const createCli = (argv: typeof process.argv) => {
return yargs(argv);
};

+ 15
- 0
packages/cli/src/commands.ts ファイルの表示

@@ -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;
};

+ 9
- 0
packages/cli/src/index.ts ファイルの表示

@@ -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();

+ 42
- 0
packages/cli/src/modules/adder/adder.controller.ts ファイルの表示

@@ -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);
}
}
}

+ 21
- 0
packages/cli/src/modules/adder/adder.service.ts ファイルの表示

@@ -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,
};

+ 2
- 0
packages/cli/src/modules/adder/index.ts ファイルの表示

@@ -0,0 +1,2 @@
export * from './adder.controller';
export * from './adder.service';

+ 64
- 0
packages/cli/test/index.test.ts ファイルの表示

@@ -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);
});
});

+ 24
- 0
packages/cli/tsconfig.eslint.json ファイルの表示

@@ -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/*"],
}
}
}

+ 24
- 0
packages/cli/tsconfig.json ファイルの表示

@@ -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/*"],
}
}
}

+ 16
- 5
packages/core/src/index.ts ファイルの表示

@@ -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;


+ 9
- 1
packages/core/test/index.test.ts ファイルの表示

@@ -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);
});
});

+ 18
- 1
packages/web-api/package.json ファイルの表示

@@ -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
- 0
packages/web-api/src/config.ts ファイルの表示

@@ -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';


+ 1
- 3
packages/web-api/src/index.ts ファイルの表示

@@ -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);


+ 39
- 0
packages/web-api/src/modules/adder/adder.controller.ts ファイルの表示

@@ -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);
}
}
}

+ 21
- 0
packages/web-api/src/modules/adder/adder.service.ts ファイルの表示

@@ -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,
};

+ 2
- 0
packages/web-api/src/modules/adder/index.ts ファイルの表示

@@ -0,0 +1,2 @@
export * from './adder.controller';
export * from './adder.service';

+ 7
- 16
packages/web-api/src/routes.ts ファイルの表示

@@ -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;


+ 61
- 8
packages/web-api/test/index.test.ts ファイルの表示

@@ -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);
});
});

+ 54
- 18
pnpm-lock.yaml ファイルの表示

@@ -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==}


読み込み中…
キャンセル
保存