From 3693617372ced1054d3d0fe6545f09c46a8afae1 Mon Sep 17 00:00:00 2001 From: daffl Date: Mon, 20 Jun 2022 14:12:30 -0700 Subject: [PATCH 1/6] feat(cli): Add generators for new Knex SQL database adapter --- packages/cli/package.json | 1 + packages/cli/src/app/index.ts | 66 ++--------- packages/cli/src/app/static/.gitignore | 1 + packages/cli/src/app/templates/config.tpl.ts | 1 - .../src/app/templates/configuration.tpl.ts | 3 +- .../cli/src/app/templates/package.json.tpl.ts | 7 +- packages/cli/src/authentication/index.ts | 110 +++++++++--------- .../templates/knex-migration.tpl.ts | 42 +++++++ .../templates/user.schema.tpl.ts | 2 +- packages/cli/src/commons.ts | 15 ++- packages/cli/src/connection/index.ts | 106 ++++++++++++----- .../cli/src/connection/templates/knex.tpl.ts | 78 +++++++++++++ .../src/connection/templates/mongodb.tpl.ts | 20 +++- packages/cli/src/service/index.ts | 13 +-- packages/cli/src/service/type/knex.tpl.ts | 62 ++++++++++ packages/cli/src/service/type/mongodb.tpl.ts | 2 +- packages/cli/test/generators.test.ts | 7 +- 17 files changed, 371 insertions(+), 165 deletions(-) create mode 100644 packages/cli/src/authentication/templates/knex-migration.tpl.ts create mode 100644 packages/cli/src/connection/templates/knex.tpl.ts create mode 100644 packages/cli/src/service/type/knex.tpl.ts diff --git a/packages/cli/package.json b/packages/cli/package.json index e6b5da2b8e..6672ea7b02 100644 --- a/packages/cli/package.json +++ b/packages/cli/package.json @@ -69,6 +69,7 @@ "@feathersjs/feathers": "^5.0.0-pre.22", "@feathersjs/koa": "^5.0.0-pre.22", "@feathersjs/mongodb": "^5.0.0-pre.22", + "@feathersjs/knex": "^5.0.0-pre.22", "@feathersjs/schema": "^5.0.0-pre.22", "@feathersjs/socketio": "^5.0.0-pre.22", "@feathersjs/transport-commons": "^5.0.0-pre.22", diff --git a/packages/cli/src/app/index.ts b/packages/cli/src/app/index.ts index 8cc917ec78..54b9b9d666 100644 --- a/packages/cli/src/app/index.ts +++ b/packages/cli/src/app/index.ts @@ -13,8 +13,8 @@ import { when } from '@feathershq/pinion' import { FeathersBaseContext, FeathersAppInfo, initializeBaseContext } from '../commons' -import { generate as authenticationGenerator } from '../authentication' -import { generate as connectionGenerator } from '../connection' +import { generate as authenticationGenerator, prompts as authenticationPrompts } from '../authentication' +import { generate as connectionGenerator, prompts as connectionPrompts } from '../connection' export type DependencyVersions = { [key: string]: string } @@ -124,58 +124,12 @@ export const generate = (ctx: AppGeneratorArguments) => { value: 'yarn', name: 'Yarn' } ] }, - { - name: 'database', - type: 'list', - when: !ctx.database, - message: 'What is your main database?', - suffix: chalk.grey(' Other databases can be added at any time'), - choices: [ - { value: 'mongodb', name: 'MongoDB' }, - { value: 'knex', name: 'SQL (PostgreSQL, SQLite etc.)', disabled: true } - ] - }, - { - name: 'connectionString', - type: 'input', - when: (answers: AppGeneratorArguments) => !ctx.connectionString && answers.database !== 'custom', - message: 'Enter your database connection string', - default: (answers: AppGeneratorArguments) => `mongodb://localhost:27017/${answers.name}` - }, - { - type: 'checkbox', - name: 'authStrategies', - when: !ctx.authStrategies, - message: 'Which user authentication methods do you want to use?', - suffix: chalk.grey(' Other methods and providers can be added at any time.'), - choices: [ - { - name: 'Email + Password', - value: 'local', - checked: true - }, - { - name: 'Google', - value: 'google' - }, - { - name: 'Facebook', - value: 'facebook' - }, - { - name: 'Twitter', - value: 'twitter' - }, - { - name: 'GitHub', - value: 'github' - }, - { - name: 'Auth0', - value: 'auth0' - } - ] - } + ...connectionPrompts(ctx), + ...authenticationPrompts({ + ...ctx, + service: 'users', + entity: 'user' + }) ]) ) .then(runGenerators(__dirname, 'templates')) @@ -183,7 +137,7 @@ export const generate = (ctx: AppGeneratorArguments) => .then(initializeBaseContext()) .then( when( - ({ authStrategies, database }) => authStrategies.length > 0 && database !== 'custom', + ({ authStrategies }) => authStrategies.length > 0, async (ctx) => { const { dependencies } = await connectionGenerator(ctx) @@ -242,7 +196,7 @@ export const generate = (ctx: AppGeneratorArguments) => ) .then( install(({ language, framework, devDependencies, dependencyVersions }) => { - devDependencies.push('nodemon', 'axios', 'mocha') + devDependencies.push('nodemon', 'axios', 'mocha', 'cross-env') if (language === 'ts') { devDependencies.push( diff --git a/packages/cli/src/app/static/.gitignore b/packages/cli/src/app/static/.gitignore index fdaa93b186..82cf9aa04b 100644 --- a/packages/cli/src/app/static/.gitignore +++ b/packages/cli/src/app/static/.gitignore @@ -116,5 +116,6 @@ dist .yarn/build-state.yml .yarn/install-state.gz .pnp.* +.sqlite lib/ diff --git a/packages/cli/src/app/templates/config.tpl.ts b/packages/cli/src/app/templates/config.tpl.ts index 55179efe66..bbd16df21f 100644 --- a/packages/cli/src/app/templates/config.tpl.ts +++ b/packages/cli/src/app/templates/config.tpl.ts @@ -5,7 +5,6 @@ const defaultConfig = ({}: AppGeneratorContext) => ({ host: 'localhost', port: 3030, public: './public/', - database: 'type://yourconnectionstring', paginate: { default: 10, max: 50 diff --git a/packages/cli/src/app/templates/configuration.tpl.ts b/packages/cli/src/app/templates/configuration.tpl.ts index 31c6480546..fd1d317128 100644 --- a/packages/cli/src/app/templates/configuration.tpl.ts +++ b/packages/cli/src/app/templates/configuration.tpl.ts @@ -11,12 +11,11 @@ export const configurationSchema = schema({ $id: 'ApplicationConfiguration', type: 'object', additionalProperties: false, - required: [ 'database', 'host', 'port', 'public', 'paginate' ], + required: [ 'host', 'port', 'public', 'paginate' ], properties: { host: { type: 'string' }, port: { type: 'number' }, public: { type: 'string' }, - database: { type: 'string' }, authentication: authenticationSettingsSchema, paginate: { type: 'object', diff --git a/packages/cli/src/app/templates/package.json.tpl.ts b/packages/cli/src/app/templates/package.json.tpl.ts index 0708f85fc2..dc65e07c39 100644 --- a/packages/cli/src/app/templates/package.json.tpl.ts +++ b/packages/cli/src/app/templates/package.json.tpl.ts @@ -6,7 +6,8 @@ const jsPackageJson = (lib: string) => ({ scripts: { start: `node ${lib}`, dev: `nodemon ${lib}/`, - test: 'mocha test/ --recursive --exit' + mocha: 'cross-env NODE_ENV=test mocha test/ --recursive --exit', + test: 'npm run mocha' } }) @@ -15,7 +16,9 @@ const tsPackageJson = (lib: string) => ({ dev: `nodemon -x ts-node ${lib}/index.ts`, compile: 'shx rm -rf dist/ && tsc', start: 'npm run compile && node dist/', - test: 'mocha test/ --require ts-node/register --recursive --extension .ts --exit' + mocha: + 'cross-env NODE_ENV=test mocha test/ --require ts-node/register --recursive --extension .ts --exit', + test: 'npm run mocha' } }) diff --git a/packages/cli/src/authentication/index.ts b/packages/cli/src/authentication/index.ts index 3181ba6eea..9eb1b1f974 100644 --- a/packages/cli/src/authentication/index.ts +++ b/packages/cli/src/authentication/index.ts @@ -1,6 +1,6 @@ import chalk from 'chalk' import { generator, runGenerators, prompt, install } from '@feathershq/pinion' -import { FeathersBaseContext } from '../commons' +import { FeathersBaseContext, getDatabaseAdapter } from '../commons' import { generate as serviceGenerator, ServiceGeneratorContext } from '../service/index' export interface AuthenticationGeneratorContext extends ServiceGeneratorContext { @@ -13,68 +13,68 @@ export interface AuthenticationGeneratorContext extends ServiceGeneratorContext export type AuthenticationGeneratorArguments = FeathersBaseContext & Partial> +export const prompts = (ctx: AuthenticationGeneratorArguments) => [ + { + type: 'checkbox', + name: 'authStrategies', + when: !ctx.authStrategies, + message: 'Which authentication methods do you want to use?', + suffix: chalk.grey(' Other methods and providers can be added at any time.'), + choices: [ + { + name: 'Email + Password', + value: 'local', + checked: true + }, + { + name: 'Google', + value: 'google' + }, + { + name: 'Facebook', + value: 'facebook' + }, + { + name: 'Twitter', + value: 'twitter' + }, + { + name: 'GitHub', + value: 'github' + }, + { + name: 'Auth0', + value: 'auth0' + } + ] + }, + { + name: 'service', + type: 'input', + when: !ctx.service, + message: 'What is your authentication service name?', + default: 'users' + }, + { + name: 'entity', + type: 'input', + when: !ctx.entity, + message: 'What is your authenticated entity name?', + suffix: chalk.grey(' Will be available in params (e.g. params.user)'), + default: 'user' + } +] + export const generate = (ctx: AuthenticationGeneratorArguments) => generator(ctx) - .then( - prompt((ctx) => [ - { - type: 'checkbox', - name: 'authStrategies', - when: !ctx.authStrategies, - message: 'Which authentication methods do you want to use?', - suffix: chalk.grey(' Other methods and providers can be added at any time.'), - choices: [ - { - name: 'Email + Password', - value: 'local', - checked: true - }, - { - name: 'Google', - value: 'google' - }, - { - name: 'Facebook', - value: 'facebook' - }, - { - name: 'Twitter', - value: 'twitter' - }, - { - name: 'GitHub', - value: 'github' - }, - { - name: 'Auth0', - value: 'auth0' - } - ] - }, - { - name: 'service', - type: 'input', - when: !ctx.service, - message: 'What is your authentication service name?', - default: 'users' - }, - { - name: 'entity', - type: 'input', - when: !ctx.entity, - message: 'What is your authenticated entity name?', - suffix: chalk.grey(' Will be available in params (e.g. params.user)'), - default: 'user' - } - ]) - ) + .then(prompt(prompts)) .then(async (ctx) => { const serviceContext = await serviceGenerator({ ...ctx, name: ctx.service, path: ctx.service, isEntityService: true, - type: ctx.feathers.database + type: getDatabaseAdapter(ctx.feathers.database) }) return { diff --git a/packages/cli/src/authentication/templates/knex-migration.tpl.ts b/packages/cli/src/authentication/templates/knex-migration.tpl.ts new file mode 100644 index 0000000000..24472a3037 --- /dev/null +++ b/packages/cli/src/authentication/templates/knex-migration.tpl.ts @@ -0,0 +1,42 @@ +import { generator, when, toFile } from '@feathershq/pinion' +import { getDatabaseAdapter, renderSource } from '../../commons' +import { AuthenticationGeneratorContext } from '../index' + +const migrationTemplate = ({ kebabName }: AuthenticationGeneratorContext) => `import type { Knex } from 'knex' + +export async function up(knex: Knex): Promise { + await knex.schema.alterTable('${kebabName}', function (table) { + table.dropColumn('text') + table.string('email').unique() + table.string('password') + }) +} + +export async function down(knex: Knex): Promise { + await knex.schema.alterTable('${kebabName}', function (table) { + table.string('text') + table.dropColumn('email') + table.dropColumn('password') + }) +} +` + +export const generate = (ctx: AuthenticationGeneratorContext) => + generator(ctx).then( + when( + (ctx) => getDatabaseAdapter(ctx.feathers.database) === 'knex', + renderSource( + migrationTemplate, + toFile( + toFile('migrations', () => { + const now = new Date() + const migrationDate = + `${now.getUTCFullYear()}${now.getUTCMonth()}${now.getUTCDay()}` + + `${now.getUTCHours()}${now.getUTCMinutes()}${now.getUTCSeconds() + 1}` + + return `${migrationDate}_authentication` + }) + ) + ) + ) + ) diff --git a/packages/cli/src/authentication/templates/user.schema.tpl.ts b/packages/cli/src/authentication/templates/user.schema.tpl.ts index a8082bb60e..9043b1f241 100644 --- a/packages/cli/src/authentication/templates/user.schema.tpl.ts +++ b/packages/cli/src/authentication/templates/user.schema.tpl.ts @@ -22,7 +22,7 @@ export const ${camelName}DataSchema = schema({ password: { type: 'string' }` - : `${name}Id: { + : ` ${name}Id: { type: 'string' }` ) diff --git a/packages/cli/src/commons.ts b/packages/cli/src/commons.ts index 0d9aaf4605..1ba95ca393 100644 --- a/packages/cli/src/commons.ts +++ b/packages/cli/src/commons.ts @@ -3,6 +3,19 @@ import { Callable, PinionContext, loadJSON, fromFile, getCallable, renderTemplat import * as ts from 'typescript' import prettier from 'prettier' +/** + * The database types supported by this generator + */ +export type DatabaseType = 'mongodb' | 'mysql' | 'postgresql' | 'sqlite' | 'mssql' + +/** + * Returns the name of the Feathers database adapter for a supported database type + * + * @param database The type of the database + * @returns The name of the adapter + */ +export const getDatabaseAdapter = (database: DatabaseType) => (database === 'mongodb' ? 'mongodb' : 'knex') + export type FeathersAppInfo = { /** * The application language @@ -11,7 +24,7 @@ export type FeathersAppInfo = { /** * The main database */ - database: 'knex' | 'mongodb' | 'custom' + database: DatabaseType /** * The package manager used */ diff --git a/packages/cli/src/connection/index.ts b/packages/cli/src/connection/index.ts index 8651bc8216..45b9209e23 100644 --- a/packages/cli/src/connection/index.ts +++ b/packages/cli/src/connection/index.ts @@ -1,9 +1,9 @@ import { generator, runGenerator, prompt, install, mergeJSON, toFile } from '@feathershq/pinion' import chalk from 'chalk' -import { FeathersBaseContext } from '../commons' +import { FeathersBaseContext, DatabaseType, getDatabaseAdapter } from '../commons' export interface ConnectionGeneratorContext extends FeathersBaseContext { - database: string + database: DatabaseType connectionString: string dependencies: string[] } @@ -11,51 +11,93 @@ export interface ConnectionGeneratorContext extends FeathersBaseContext { export type ConnectionGeneratorArguments = FeathersBaseContext & Partial> +export const defaultConnectionString = (type: DatabaseType, name: string) => { + const connectionStrings = { + mongodb: `mongodb://localhost:27017/${name}`, + mysql: `mysql://root:@localhost:3306/${name}`, + postgresql: `postgres://postgres:@localhost:5432/${name}`, + sqlite: `${name}.sqlite`, + mssql: `mssql://root:password@localhost:1433/${name}` + } + + return connectionStrings[type] +} + +export const prompts = ({ database, connectionString, pkg }: ConnectionGeneratorArguments) => [ + { + name: 'database', + type: 'list', + when: !database, + message: 'Which database are you connecting to?', + suffix: chalk.grey(' Other databases can be added at any time'), + choices: [ + { value: 'sqlite', name: 'SQLite' }, + { value: 'mongodb', name: 'MongoDB' }, + { value: 'postgresql', name: 'PostgreSQL' }, + { value: 'mysql', name: 'MySQL/MariaDB' }, + { value: 'mssql', name: 'Microsoft SQL' } + ] + }, + { + name: 'connectionString', + type: 'input', + when: !connectionString, + message: 'Enter your database connection string', + default: (answers: { name?: string; database: DatabaseType }) => + defaultConnectionString(answers.database, answers.name || pkg.name) + } +] + +export const DATABASE_CLIENTS = { + mongodb: 'mongodb', + sqlite: 'sqlite3', + postgresql: 'pg', + mysql: 'mysql', + mssql: 'tedious' +} + +export const getDatabaseClient = (database: DatabaseType) => DATABASE_CLIENTS[database] + export const generate = (ctx: ConnectionGeneratorArguments) => generator(ctx) + .then(prompt(prompts)) .then( - prompt( - ({ database, connectionString, pkg }) => [ - { - name: 'database', - type: 'list', - when: !database, - message: 'Which database are you connecting to?', - suffix: chalk.grey(' Other databases can be added at any time'), - choices: [ - { value: 'mongodb', name: 'MongoDB' }, - { value: 'knex', name: 'SQL (PostgreSQL, SQLite etc.)', disabled: true } - ] - }, - { - name: 'connectionString', - type: 'input', - when: (answers: ConnectionGeneratorArguments) => - !connectionString && answers.database !== 'custom', - message: 'Enter your database connection string', - default: `mongodb://localhost:27017/${pkg.name}` - } - ] + runGenerator( + __dirname, + 'templates', + ({ database }) => `${getDatabaseAdapter(database)}.tpl` ) ) - .then( - runGenerator(__dirname, 'templates', ({ database }) => `${database}.tpl`) - ) .then( mergeJSON( - ({ connectionString }) => ({ - database: connectionString - }), + ({ connectionString, database }) => + getDatabaseAdapter(database) === 'knex' + ? { + [database]: { + client: getDatabaseClient(database), + connection: connectionString, + ...(database === 'sqlite' ? { useNullAsDefault: true } : {}) + } + } + : { + [database]: connectionString + }, toFile('config', 'default.json') ) ) .then((ctx: ConnectionGeneratorContext) => { const dependencies: string[] = [] + const adapter = getDatabaseAdapter(ctx.database) + const dbClient = getDatabaseClient(ctx.database) - if (ctx.database === 'mongodb') { - dependencies.push('@feathersjs/mongodb', 'mongodb') + dependencies.push(`@feathersjs/${adapter}`) + + if (adapter === 'knex') { + dependencies.push('knex') } + dependencies.push(dbClient) + if (ctx.dependencies) { return { ...ctx, diff --git a/packages/cli/src/connection/templates/knex.tpl.ts b/packages/cli/src/connection/templates/knex.tpl.ts new file mode 100644 index 0000000000..16ef3e7fd3 --- /dev/null +++ b/packages/cli/src/connection/templates/knex.tpl.ts @@ -0,0 +1,78 @@ +import { generator, toFile, inject, before, mergeJSON } from '@feathershq/pinion' +import { ConnectionGeneratorContext } from '../index' +import { getSource, renderSource } from '../../commons' + +const template = ({ database }: ConnectionGeneratorContext) => + `import knex from 'knex' +import type { Knex } from 'knex' +import type { Application } from './declarations' + +declare module './declarations' { + interface Configuration { + ${database}Client: Knex + } +} + +export const ${database} = (app: Application) => { + const config = app.get('${database}') + const db = knex(config!) + + app.set('${database}Client', db); +} +` + +const knexfile = ({ lib, database }: ConnectionGeneratorContext) => ` +import { app } from './${lib}/app' + +// Load our database connection info from the app configuration +const config = app.get('${database}') + +module.exports = config +` + +const configurationTemplate = ({ database }: ConnectionGeneratorContext) => ` ${database}: { + type: 'object', + properties: { + client: { type: 'string' }, + connection: { type: 'string' } + } + },` + +const importTemplate = ({ database }: ConnectionGeneratorContext) => + `import { ${database} } from './${database}'` +const configureTemplate = ({ database }: ConnectionGeneratorContext) => `app.configure(${database})` +const toAppFile = toFile(({ lib, language }) => [lib, `app.${language}`]) + +export const generate = (ctx: ConnectionGeneratorContext) => + generator(ctx) + .then( + renderSource( + template, + toFile(({ lib, database }) => [lib, database]) + ) + ) + .then(renderSource(knexfile, toFile('knexfile'))) + .then( + mergeJSON( + { + scripts: { + migrate: 'knex migrate:latest', + test: 'npm run migrate && npm run mocha' + } + }, + toFile('package.json') + ) + ) + .then( + inject( + configurationTemplate, + before('authentication: authenticationSettingsSchema'), + toFile(({ lib, language }) => [ + lib, + 'schemas', + `configuration.schema.${language}` + ]) + ) + ) + .then(inject(getSource(importTemplate), before('import { services } from'), toAppFile)) + .then(inject(getSource(configureTemplate), before('app.configure(services)'), toAppFile)) diff --git a/packages/cli/src/connection/templates/mongodb.tpl.ts b/packages/cli/src/connection/templates/mongodb.tpl.ts index e1bc31db81..61a5a2d38d 100644 --- a/packages/cli/src/connection/templates/mongodb.tpl.ts +++ b/packages/cli/src/connection/templates/mongodb.tpl.ts @@ -9,20 +9,21 @@ import type { Application } from './declarations' declare module './declarations' { interface Configuration { - mongoClient: Promise + mongodbClient: Promise } } export const mongodb = (app: Application) => { - const connection = app.get('database') + const connection = app.get('mongodb') as string const database = connection.substring(connection.lastIndexOf('/') + 1) const mongoClient = MongoClient.connect(connection) .then(client => client.db(database)) - app.set('mongoClient', mongoClient) + app.set('mongodbClient', mongoClient) } ` - +const configurationTemplate = ({ database }: ConnectionGeneratorContext) => + ` ${database}: { type: 'string' },` const importTemplate = "import { mongodb } from './mongodb'" const configureTemplate = 'app.configure(mongodb)' const toAppFile = toFile(({ lib, language }) => [lib, `app.${language}`]) @@ -35,5 +36,16 @@ export const generate = (ctx: ConnectionGeneratorContext) => toFile(({ lib }) => lib, 'mongodb') ) ) + .then( + inject( + configurationTemplate, + before('authentication: authenticationSettingsSchema'), + toFile(({ lib, language }) => [ + lib, + 'schemas', + `configuration.schema.${language}` + ]) + ) + ) .then(inject(getSource(importTemplate), before('import { services } from'), toAppFile)) .then(inject(getSource(configureTemplate), before('app.configure(services)'), toAppFile)) diff --git a/packages/cli/src/service/index.ts b/packages/cli/src/service/index.ts index 1c9ef08ece..d9490c1dbf 100644 --- a/packages/cli/src/service/index.ts +++ b/packages/cli/src/service/index.ts @@ -1,7 +1,7 @@ import _ from 'lodash' import { generator, runGenerator, runGenerators, prompt } from '@feathershq/pinion' -import { FeathersBaseContext } from '../commons' +import { FeathersBaseContext, getDatabaseAdapter } from '../commons' export interface ServiceGeneratorContext extends FeathersBaseContext { /** @@ -93,16 +93,15 @@ export const generate = (ctx: ServiceGeneratorArguments) => type: 'list', when: !type, message: 'What kind of service is it?', - default: ctx.feathers.database, + default: getDatabaseAdapter(ctx.feathers.database), choices: [ { - value: 'mongodb', - name: 'MongoDB' + value: 'knex', + name: 'SQL' }, { - value: 'knex', - name: 'SQL', - disabled: false + value: 'mongodb', + name: 'MongoDB' }, { value: 'custom', diff --git a/packages/cli/src/service/type/knex.tpl.ts b/packages/cli/src/service/type/knex.tpl.ts new file mode 100644 index 0000000000..5d1de1a12f --- /dev/null +++ b/packages/cli/src/service/type/knex.tpl.ts @@ -0,0 +1,62 @@ +import { generator, inject, toFile, before, after, prepend } from '@feathershq/pinion' +import { getSource, renderSource } from '../../commons' +import { ServiceGeneratorContext } from '../index' + +const migrationTemplate = ({ kebabName }: ServiceGeneratorContext) => `import type { Knex } from 'knex' + +export async function up(knex: Knex): Promise { + await knex.schema.createTable('${kebabName}', table => { + table.increments('id') + table.string('text') + }) +} + +export async function down(knex: Knex): Promise { + await knex.schema.dropTable('${kebabName}') +} +` + +export const importTemplate = `import { KnexService } from \'@feathersjs/knex\' +import type { KnexAdapterParams } from \'@feathersjs/knex\'` + +export const classCode = ({ className, upperName }: ServiceGeneratorContext) => + `export interface ${upperName}Params extends KnexAdapterParams<${upperName}Query> { +} + +// By default calls the standard Knex adapter service methods but can be customized with your own functionality. +export class ${className} extends KnexService<${upperName}Result, ${upperName}Data, ${upperName}Params> { +} +` + +export const optionTemplate = ({ kebabName, feathers }: ServiceGeneratorContext) => + ` paginate: app.get('paginate'), + Model: app.get('${feathers.database}Client'), + name: '${kebabName}'` + +const toServiceFile = toFile(({ lib, folder, kebabName, language }) => [ + lib, + 'services', + ...folder, + `${kebabName}.${language}` +]) + +export const generate = (ctx: ServiceGeneratorContext) => + generator(ctx) + .then( + inject(getSource(classCode), before('export const hooks ='), toServiceFile) + ) + .then(inject(getSource(importTemplate), prepend(), toServiceFile)) + .then(inject(optionTemplate, after('const options ='), toServiceFile)) + .then( + renderSource( + migrationTemplate, + toFile('migrations', ({ kebabName }) => { + const now = new Date() + const migrationDate = + `${now.getUTCFullYear()}${now.getUTCMonth()}${now.getUTCDay()}` + + `${now.getUTCHours()}${now.getUTCMinutes()}${now.getUTCSeconds()}` + + return `${migrationDate}_${kebabName}` + }) + ) + ) diff --git a/packages/cli/src/service/type/mongodb.tpl.ts b/packages/cli/src/service/type/mongodb.tpl.ts index 88d141e18b..4377e1e93e 100644 --- a/packages/cli/src/service/type/mongodb.tpl.ts +++ b/packages/cli/src/service/type/mongodb.tpl.ts @@ -16,7 +16,7 @@ export class ${className} extends MongoDBService<${upperName}Result, ${upperName const optionTemplate = ({ kebabName }: ServiceGeneratorContext) => ` paginate: app.get('paginate'), - Model: app.get('mongoClient').then(db => db.collection('${kebabName}'))` + Model: app.get('mongodbClient').then(db => db.collection('${kebabName}'))` const toServiceFile = toFile(({ lib, folder, kebabName, language }) => [ lib, diff --git a/packages/cli/test/generators.test.ts b/packages/cli/test/generators.test.ts index 7f25a79586..4541ea6910 100644 --- a/packages/cli/test/generators.test.ts +++ b/packages/cli/test/generators.test.ts @@ -23,7 +23,7 @@ function combinate>(obj: O) { let combos: { [k in keyof O]: O[k][number] }[] = [] for (const key of Object.keys(obj)) { const values = obj[key] - const all = [] + const all: any[] = [] for (let i = 0; i < values.length; i++) { for (let j = 0; j < (combos.length || 1); j++) { const newCombo = { ...combos[j], [key]: values[i] } @@ -53,6 +53,7 @@ describe('@feathersjs/cli', () => { it(`generates ${language} ${framework} app and passes tests`, async () => { const name = `feathers_${language}_${framework}` const cwd = await mkdtemp(path.join(os.tmpdir(), name + '-')) + console.log(cwd) const settings: AppGeneratorData = { name, framework, @@ -61,8 +62,8 @@ describe('@feathersjs/cli', () => { lib: 'src', description: 'A Feathers test app', packager: 'npm', - database: 'mongodb', - connectionString: 'mongodb://localhost:27017/feathersapp', + database: 'sqlite', + connectionString: `${name}.sqlite`, transports: ['rest', 'websockets'], authStrategies: ['local', 'github'] } From 1c43354a554f35687ed2ac52ad14dec9d2fcf26c Mon Sep 17 00:00:00 2001 From: daffl Date: Mon, 20 Jun 2022 16:02:44 -0700 Subject: [PATCH 2/6] Make generator more solid and add further tests --- packages/cli/src/app/index.ts | 31 +---- .../cli/src/app/templates/channels.tpl.ts | 4 +- packages/cli/src/authentication/index.ts | 6 +- .../{knex-migration.tpl.ts => knex.tpl.ts} | 27 +++- packages/cli/src/commons.ts | 35 ++++- packages/cli/src/connection/index.ts | 4 +- .../cli/src/connection/templates/knex.tpl.ts | 6 +- packages/cli/src/service/index.ts | 4 +- .../cli/src/service/templates/resolver.tpl.ts | 4 +- packages/cli/test/generators.test.ts | 129 ++++++++++-------- packages/cli/test/utils.ts | 29 ++++ 11 files changed, 179 insertions(+), 100 deletions(-) rename packages/cli/src/authentication/templates/{knex-migration.tpl.ts => knex.tpl.ts} (66%) create mode 100644 packages/cli/test/utils.ts diff --git a/packages/cli/src/app/index.ts b/packages/cli/src/app/index.ts index 54b9b9d666..07eca6d67f 100644 --- a/packages/cli/src/app/index.ts +++ b/packages/cli/src/app/index.ts @@ -1,26 +1,19 @@ -import { sep, join } from 'path' -import { PackageJson } from 'type-fest' +import { sep } from 'path' import chalk from 'chalk' import { generator, prompt, runGenerators, - loadJSON, fromFile, install, copyFiles, toFile, when } from '@feathershq/pinion' -import { FeathersBaseContext, FeathersAppInfo, initializeBaseContext } from '../commons' +import { FeathersBaseContext, FeathersAppInfo, initializeBaseContext, addVersions } from '../commons' import { generate as authenticationGenerator, prompts as authenticationPrompts } from '../authentication' import { generate as connectionGenerator, prompts as connectionPrompts } from '../connection' -export type DependencyVersions = { [key: string]: string } - -const addVersions = (dependencies: string[], versions: DependencyVersions) => - dependencies.map((dep) => `${dep}@${versions[dep] ? versions[dep] : 'latest'}`) - export interface AppGeneratorData extends FeathersAppInfo { /** * The application name @@ -42,11 +35,6 @@ export interface AppGeneratorData extends FeathersAppInfo { * The source folder where files are put */ lib: string - /** - * A list dependencies that should be installed with a certain version. - * Used for installing development dependencies during testing. - */ - dependencyVersions?: DependencyVersions } export type AppGeneratorContext = FeathersBaseContext & @@ -59,16 +47,11 @@ export type AppGeneratorArguments = FeathersBaseContext & Partial generator(ctx) - .then( - loadJSON(join(__dirname, '..', '..', 'package.json'), (pkg: PackageJson) => ({ - dependencyVersions: { - ...pkg.devDependencies, - ...ctx.dependencyVersions - }, - dependencies: [], - devDependencies: [] - })) - ) + .then((ctx) => ({ + ...ctx, + dependencies: [], + devDependencies: [] + })) .then( prompt((ctx) => [ { diff --git a/packages/cli/src/app/templates/channels.tpl.ts b/packages/cli/src/app/templates/channels.tpl.ts index 8847ba3782..3e910f5bd2 100644 --- a/packages/cli/src/app/templates/channels.tpl.ts +++ b/packages/cli/src/app/templates/channels.tpl.ts @@ -2,7 +2,7 @@ import { generator, toFile } from '@feathershq/pinion' import { renderSource } from '../../commons' import { AppGeneratorContext } from '../index' -const template = ({}: AppGeneratorContext) => +const template = ({ language }: AppGeneratorContext) => `import '@feathersjs/transport-commons' import type { Application, HookContext } from './declarations' import { logger } from './logger' @@ -13,7 +13,7 @@ export const channels = (app: Application) => { return } - logger.warn('Publishing all events to all authenticated users. See \`channels.js\` and https://docs.feathersjs.com/api/channels.html for more information.') + logger.warn('Publishing all events to all authenticated users. See \`channels.${language}\` and https://docs.feathersjs.com/api/channels.html for more information.') app.on('connection', (connection: any) => { // On a new real-time connection, add it to the anonymous channel diff --git a/packages/cli/src/authentication/index.ts b/packages/cli/src/authentication/index.ts index 9eb1b1f974..8577312216 100644 --- a/packages/cli/src/authentication/index.ts +++ b/packages/cli/src/authentication/index.ts @@ -1,6 +1,6 @@ import chalk from 'chalk' import { generator, runGenerators, prompt, install } from '@feathershq/pinion' -import { FeathersBaseContext, getDatabaseAdapter } from '../commons' +import { addVersions, FeathersBaseContext, getDatabaseAdapter } from '../commons' import { generate as serviceGenerator, ServiceGeneratorContext } from '../service/index' export interface AuthenticationGeneratorContext extends ServiceGeneratorContext { @@ -99,7 +99,5 @@ export const generate = (ctx: AuthenticationGeneratorArguments) => } } - const installer = install(dependencies) - - return installer(ctx) + return install(addVersions(dependencies, ctx.dependencyVersions))(ctx) }) diff --git a/packages/cli/src/authentication/templates/knex-migration.tpl.ts b/packages/cli/src/authentication/templates/knex.tpl.ts similarity index 66% rename from packages/cli/src/authentication/templates/knex-migration.tpl.ts rename to packages/cli/src/authentication/templates/knex.tpl.ts index 24472a3037..b66e16b520 100644 --- a/packages/cli/src/authentication/templates/knex-migration.tpl.ts +++ b/packages/cli/src/authentication/templates/knex.tpl.ts @@ -2,21 +2,38 @@ import { generator, when, toFile } from '@feathershq/pinion' import { getDatabaseAdapter, renderSource } from '../../commons' import { AuthenticationGeneratorContext } from '../index' -const migrationTemplate = ({ kebabName }: AuthenticationGeneratorContext) => `import type { Knex } from 'knex' +const migrationTemplate = ({ + kebabName, + authStrategies +}: AuthenticationGeneratorContext) => `import type { Knex } from 'knex' export async function up(knex: Knex): Promise { await knex.schema.alterTable('${kebabName}', function (table) { - table.dropColumn('text') + table.dropColumn('text')${authStrategies + .map((name) => + name === 'local' + ? ` table.string('email').unique() - table.string('password') + table.string('password')` + : ` + table.string('${name}Id')` + ) + .join('\n')} }) } export async function down(knex: Knex): Promise { await knex.schema.alterTable('${kebabName}', function (table) { - table.string('text') + table.string('text')${authStrategies + .map((name) => + name === 'local' + ? ` table.dropColumn('email') - table.dropColumn('password') + table.dropColumn('password')` + : ` + table.dropColumn('${name}Id')` + ) + .join(',\n')} }) } ` diff --git a/packages/cli/src/commons.ts b/packages/cli/src/commons.ts index 1ba95ca393..d2dd8a975f 100644 --- a/packages/cli/src/commons.ts +++ b/packages/cli/src/commons.ts @@ -2,6 +2,9 @@ import { PackageJson } from 'type-fest' import { Callable, PinionContext, loadJSON, fromFile, getCallable, renderTemplate } from '@feathershq/pinion' import * as ts from 'typescript' import prettier from 'prettier' +import path from 'path' + +export type DependencyVersions = { [key: string]: string } /** * The database types supported by this generator @@ -65,8 +68,23 @@ export interface FeathersBaseContext extends PinionContext { * The language the app is generated in */ language: 'js' | 'ts' + /** + * A list dependencies that should be installed with a certain version. + * Used for installing development dependencies during testing. + */ + dependencyVersions?: DependencyVersions } +/** + * Returns dependencies with the versions from the context attached (if available) + * + * @param dependencies The dependencies to install + * @param versions The dependency version list + * @returns A list of dependencies with their versions + */ +export const addVersions = (dependencies: string[], versions: DependencyVersions) => + dependencies.map((dep) => `${dep}@${versions[dep] ? versions[dep] : 'latest'}`) + /** * Loads the application package.json and populates information like the library and test directory * and Feathers app specific information. @@ -78,11 +96,19 @@ export const initializeBaseContext = (ctx: C) => Promise.resolve(ctx) .then(loadJSON(fromFile('package.json'), (pkg) => ({ pkg }), {})) + .then( + loadJSON(path.join(__dirname, '..', 'package.json'), (pkg: PackageJson) => ({ + dependencyVersions: { + ...pkg.devDependencies, + ...ctx.dependencyVersions + } + })) + ) .then((ctx) => ({ ...ctx, lib: ctx.pkg?.directories?.lib || 'src', test: ctx.pkg?.directories?.test || 'test', - language: ctx.pkg?.feathers?.language || 'ts', + language: ctx.language || ctx.pkg?.feathers?.language, feathers: ctx.pkg?.feathers })) @@ -91,6 +117,13 @@ const escapeNewLines = (code: string) => code.replace(/\n\n/g, '\n/* :newline: * const restoreNewLines = (code: string) => code.replace(/\/\* :newline: \*\//g, '\n') const fixLocalImports = (code: string) => code.replace(importRegex, "from '$1.js'") +/** + * Returns the transpiled and prettified JavaScript for a TypeScript source code + * + * @param typescript The TypeScript source code + * @param options TypeScript transpilation options + * @returns The formatted JavaScript source code + */ export const getJavaScript = (typescript: string, options: ts.TranspileOptions = {}) => { const source = escapeNewLines(typescript) const transpiled = ts.transpileModule(source, { diff --git a/packages/cli/src/connection/index.ts b/packages/cli/src/connection/index.ts index 45b9209e23..f94cbb4fcb 100644 --- a/packages/cli/src/connection/index.ts +++ b/packages/cli/src/connection/index.ts @@ -1,6 +1,6 @@ import { generator, runGenerator, prompt, install, mergeJSON, toFile } from '@feathershq/pinion' import chalk from 'chalk' -import { FeathersBaseContext, DatabaseType, getDatabaseAdapter } from '../commons' +import { FeathersBaseContext, DatabaseType, getDatabaseAdapter, addVersions } from '../commons' export interface ConnectionGeneratorContext extends FeathersBaseContext { database: DatabaseType @@ -105,5 +105,5 @@ export const generate = (ctx: ConnectionGeneratorArguments) => } } - return install(dependencies)(ctx) + return install(addVersions(dependencies, ctx.dependencyVersions))(ctx) }) diff --git a/packages/cli/src/connection/templates/knex.tpl.ts b/packages/cli/src/connection/templates/knex.tpl.ts index 16ef3e7fd3..6a424bd996 100644 --- a/packages/cli/src/connection/templates/knex.tpl.ts +++ b/packages/cli/src/connection/templates/knex.tpl.ts @@ -21,13 +21,13 @@ export const ${database} = (app: Application) => { } ` -const knexfile = ({ lib, database }: ConnectionGeneratorContext) => ` +const knexfile = ({ lib, language, database }: ConnectionGeneratorContext) => ` import { app } from './${lib}/app' // Load our database connection info from the app configuration const config = app.get('${database}') -module.exports = config +${language === 'js' ? 'export default config' : 'module.exports = config'} ` const configurationTemplate = ({ database }: ConnectionGeneratorContext) => ` ${database}: { @@ -56,7 +56,7 @@ export const generate = (ctx: ConnectionGeneratorContext) => mergeJSON( { scripts: { - migrate: 'knex migrate:latest', + migrate: `knex migrate:latest`, test: 'npm run migrate && npm run mocha' } }, diff --git a/packages/cli/src/service/index.ts b/packages/cli/src/service/index.ts index d9490c1dbf..c3889fe6f3 100644 --- a/packages/cli/src/service/index.ts +++ b/packages/cli/src/service/index.ts @@ -122,8 +122,8 @@ export const generate = (ctx: ServiceGeneratorArguments) => const pathElements = path.split('/').filter((el) => el !== '') const relative = pathElements.map(() => '..').join('/') const folder = _.initial(pathElements) - const schemaPath = `schemas/${folder.join('/')}${kebabName}.schema` - const resolverPath = `resolvers/${folder.join('/')}${kebabName}.resolver` + const schemaPath = ['schemas', ...folder, `${kebabName}.schema`].join('/') + const resolverPath = ['resolvers', ...folder, `${kebabName}.resolver`].join('/') return { name, diff --git a/packages/cli/src/service/templates/resolver.tpl.ts b/packages/cli/src/service/templates/resolver.tpl.ts index 41f033643e..69556f44c6 100644 --- a/packages/cli/src/service/templates/resolver.tpl.ts +++ b/packages/cli/src/service/templates/resolver.tpl.ts @@ -11,13 +11,13 @@ import type { ${upperName}Patch, ${upperName}Result, ${upperName}Query, -} from '../${schemaPath}' +} from '${relative}/${schemaPath}' import { ${camelName}DataSchema, ${camelName}PatchSchema, ${camelName}ResultSchema, ${camelName}QuerySchema -} from '../${schemaPath}' +} from '${relative}/${schemaPath}' // Resolver for the basic data model (e.g. creating new entries) diff --git a/packages/cli/test/generators.test.ts b/packages/cli/test/generators.test.ts index 4541ea6910..9d6d6b9f8c 100644 --- a/packages/cli/test/generators.test.ts +++ b/packages/cli/test/generators.test.ts @@ -5,9 +5,12 @@ import { mkdtemp } from 'fs/promises' import assert from 'assert' import { getContext } from '@feathershq/pinion' -import { AppGeneratorData, AppGeneratorContext, DependencyVersions } from '../src/app' +import { AppGeneratorContext } from '../src/app' import { generate } from '../lib' -import pkg from '../package.json' +import { FeathersBaseContext } from '../src/commons' +import { ConnectionGeneratorArguments } from '../src/connection' +import { ServiceGeneratorArguments } from '../src/service' +import { combinate, dependencyVersions } from './utils' const matrix = { language: ['js', 'ts'] as const, @@ -19,66 +22,82 @@ const defaultCombination = { framework: process.env.FEATHERS_FRAMEWORK || 'koa' } -function combinate>(obj: O) { - let combos: { [k in keyof O]: O[k][number] }[] = [] - for (const key of Object.keys(obj)) { - const values = obj[key] - const all: any[] = [] - for (let i = 0; i < values.length; i++) { - for (let j = 0; j < (combos.length || 1); j++) { - const newCombo = { ...combos[j], [key]: values[i] } - all.push(newCombo) - } - } - combos = all - } - return combos -} - const combinations = process.version > 'v16.0.0' ? (process.env.CI ? combinate(matrix as any) : [defaultCombination]) : [] -// Use local packages for testing instead of the versions from npm -const dependencyVersions = Object.keys(pkg.devDependencies) - .filter((dep) => dep.startsWith('@feathersjs/')) - .reduce((acc, dep) => { - const [, name] = dep.split('/') - - acc[dep] = `file://${path.join(__dirname, '..', '..', name)}` - - return acc - }, {} as DependencyVersions) describe('@feathersjs/cli', () => { for (const { language, framework } of combinations) { - it(`generates ${language} ${framework} app and passes tests`, async () => { + describe(`${language} ${framework} app`, () => { const name = `feathers_${language}_${framework}` - const cwd = await mkdtemp(path.join(os.tmpdir(), name + '-')) - console.log(cwd) - const settings: AppGeneratorData = { - name, - framework, - language, - dependencyVersions, - lib: 'src', - description: 'A Feathers test app', - packager: 'npm', - database: 'sqlite', - connectionString: `${name}.sqlite`, - transports: ['rest', 'websockets'], - authStrategies: ['local', 'github'] - } - const context = getContext( - { - ...settings, - _: ['generate', 'app'] - }, - { cwd } - ) - const finalContext = await generate(context) - const testResult = await context.pinion.exec('npm', ['test'], { cwd }) - assert.ok(finalContext) - assert.strictEqual(testResult, 0) + let context: FeathersBaseContext + let cwd: string + + before(async () => { + cwd = await mkdtemp(path.join(os.tmpdir(), name + '-')) + console.log(cwd) + + context = await generate( + getContext( + { + name, + framework, + language, + dependencyVersions, + lib: 'src', + description: 'A Feathers test app', + packager: 'npm', + database: 'sqlite', + connectionString: `${name}.sqlite`, + transports: ['rest', 'websockets'], + authStrategies: ['local', 'github'], + _: ['generate', 'app'] + }, + { cwd } + ) + ) + }) + + it('generated app with SQLite and passes tests', async () => { + const testResult = await context.pinion.exec('npm', ['test'], { cwd }) + + assert.ok(context) + assert.strictEqual(testResult, 0) + }) + + it('generates a MongoDB connection and service and passes tests', async () => { + const connectionContext = await generate( + getContext( + { + database: 'mongodb' as const, + connectionString: `mongodb://localhost:27017/${name}`, + _: ['generate', 'connection'] + }, + { cwd } + ) + ) + const mongoServiceContext = await generate( + getContext( + { + name: 'testing', + path: 'path/to/testing', + authentication: true, + type: 'mongodb', + _: ['generate', 'service'] + }, + { cwd } + ) + ) + const testResult = await context.pinion.exec('npm', ['test'], { cwd }) + + assert.ok(connectionContext) + assert.ok(mongoServiceContext) + assert.strictEqual(testResult, 0) + }) + + // it('generates a custom service and passes tests', async () => { + + // }) }) } }) diff --git a/packages/cli/test/utils.ts b/packages/cli/test/utils.ts new file mode 100644 index 0000000000..16dc2c6764 --- /dev/null +++ b/packages/cli/test/utils.ts @@ -0,0 +1,29 @@ +import path from 'path' +import pkg from '../package.json' +import { DependencyVersions } from '../src/commons' + +export function combinate>(obj: O) { + let combos: { [k in keyof O]: O[k][number] }[] = [] + for (const key of Object.keys(obj)) { + const values = obj[key] + const all: any[] = [] + for (let i = 0; i < values.length; i++) { + for (let j = 0; j < (combos.length || 1); j++) { + const newCombo = { ...combos[j], [key]: values[i] } + all.push(newCombo) + } + } + combos = all + } + return combos +} + +export const dependencyVersions = Object.keys(pkg.devDependencies as any) + .filter((dep) => dep.startsWith('@feathersjs/')) + .reduce((acc, dep) => { + const [, name] = dep.split('/') + + acc[dep] = `file://${path.join(__dirname, '..', '..', name)}` + + return acc + }, {} as DependencyVersions) From 959c307613b0c26b6c3f5a617b09f25b5a94f6fe Mon Sep 17 00:00:00 2001 From: daffl Date: Mon, 20 Jun 2022 19:51:40 -0700 Subject: [PATCH 3/6] Fix tests and some more refactoring --- packages/cli/src/index.ts | 1 + packages/cli/src/service/index.ts | 10 ++- .../cli/src/service/templates/resolver.tpl.ts | 4 +- .../cli/src/service/templates/schema.tpl.ts | 4 +- .../cli/src/service/templates/service.tpl.ts | 7 +- packages/cli/src/service/type/custom.tpl.ts | 66 ++++++++++++------- packages/cli/src/service/type/knex.tpl.ts | 4 +- packages/cli/src/service/type/mongodb.tpl.ts | 4 +- packages/cli/test/generators.test.ts | 25 +++++-- 9 files changed, 80 insertions(+), 45 deletions(-) diff --git a/packages/cli/src/index.ts b/packages/cli/src/index.ts index 256c125e44..6bc849aa54 100644 --- a/packages/cli/src/index.ts +++ b/packages/cli/src/index.ts @@ -20,6 +20,7 @@ export const command = (yargs: Argv) => yarg .command('app', 'Generate a new app', commandRunner) .command('service', 'Generate a service', commandRunner) + .command('connection', 'Connect to a different database', commandRunner) .command('hook', 'Generate a hook', commandRunner) ) .usage('Usage: $0 [options]') diff --git a/packages/cli/src/service/index.ts b/packages/cli/src/service/index.ts index c3889fe6f3..ec1b58e79d 100644 --- a/packages/cli/src/service/index.ts +++ b/packages/cli/src/service/index.ts @@ -32,6 +32,10 @@ export interface ServiceGeneratorContext extends FeathersBaseContext { * A kebab-cased (filename friendly) version of the service name */ kebabName: string + /** + * The actual filename (the last element of the path) + */ + fileName: string /** * Indicates how many file paths we should go up to import other things (e.g. `../../`) */ @@ -122,14 +126,16 @@ export const generate = (ctx: ServiceGeneratorArguments) => const pathElements = path.split('/').filter((el) => el !== '') const relative = pathElements.map(() => '..').join('/') const folder = _.initial(pathElements) - const schemaPath = ['schemas', ...folder, `${kebabName}.schema`].join('/') - const resolverPath = ['resolvers', ...folder, `${kebabName}.resolver`].join('/') + const fileName = _.last(pathElements) + const schemaPath = ['schemas', ...folder, `${fileName}.schema`].join('/') + const resolverPath = ['resolvers', ...folder, `${fileName}.resolver`].join('/') return { name, type, path, folder, + fileName, upperName, className, kebabName, diff --git a/packages/cli/src/service/templates/resolver.tpl.ts b/packages/cli/src/service/templates/resolver.tpl.ts index 69556f44c6..7750afd74d 100644 --- a/packages/cli/src/service/templates/resolver.tpl.ts +++ b/packages/cli/src/service/templates/resolver.tpl.ts @@ -68,11 +68,11 @@ export const generate = (ctx: ServiceGeneratorContext) => generator(ctx).then( renderSource( template, - toFile(({ lib, folder, kebabName }: ServiceGeneratorContext) => [ + toFile(({ lib, folder, fileName }: ServiceGeneratorContext) => [ lib, 'resolvers', ...folder, - `${kebabName}.resolver` + `${fileName}.resolver` ]) ) ) diff --git a/packages/cli/src/service/templates/schema.tpl.ts b/packages/cli/src/service/templates/schema.tpl.ts index b160476d3a..de5093c8ff 100644 --- a/packages/cli/src/service/templates/schema.tpl.ts +++ b/packages/cli/src/service/templates/schema.tpl.ts @@ -70,11 +70,11 @@ export const generate = (ctx: ServiceGeneratorContext) => generator(ctx).then( renderSource( template, - toFile(({ lib, folder, kebabName }: ServiceGeneratorContext) => [ + toFile(({ lib, folder, fileName }: ServiceGeneratorContext) => [ lib, 'schemas', ...folder, - `${kebabName}.schema` + `${fileName}.schema` ]) ) ) diff --git a/packages/cli/src/service/templates/service.tpl.ts b/packages/cli/src/service/templates/service.tpl.ts index f3d95d253e..ab9093f9e3 100644 --- a/packages/cli/src/service/templates/service.tpl.ts +++ b/packages/cli/src/service/templates/service.tpl.ts @@ -110,12 +110,7 @@ export const generate = (ctx: ServiceGeneratorContext) => .then( renderSource( template, - toFile(({ lib, folder, kebabName }) => [ - lib, - 'services', - ...folder, - kebabName - ]) + toFile(({ lib, folder, fileName }) => [lib, 'services', ...folder, fileName]) ) ) .then(inject(getSource(importTemplate), prepend(), toServiceIndex)) diff --git a/packages/cli/src/service/type/custom.tpl.ts b/packages/cli/src/service/type/custom.tpl.ts index c415be2629..fe47fb7f06 100644 --- a/packages/cli/src/service/type/custom.tpl.ts +++ b/packages/cli/src/service/type/custom.tpl.ts @@ -1,4 +1,4 @@ -import { generator, inject, toFile, after, prepend } from '@feathershq/pinion' +import { generator, inject, toFile, after, before, prepend } from '@feathershq/pinion' import { getSource } from '../../commons' import { ServiceGeneratorContext } from '../index' @@ -7,59 +7,75 @@ export const template = ({ className, upperName }: ServiceGeneratorContext) => app: Application } -export class ${className} implements ServiceInterface<${upperName}Result, ${upperName}Data> { +export interface ${upperName}Params extends Params<${upperName}Query> { + +} + +// This is a skeleton for a custom service class. Remove or add the methods you need here +export class ${className} { constructor (public options: ${className}Options) { } - async find (params?: Params) { - return []; + async find (_params?: ${upperName}Params): Promise<${upperName}Result[]> { + return [] } - async get (id: Id, params?: Params) { + async get (id: Id, _params?: ${upperName}Params): Promise<${upperName}Result> { return { - id, text: \`A new message with ID: \${id}!\` + id: \`\${id}\`, + text: \`A new message with ID: \${id}!\` }; } - async create (data: Data, params?: Params) { + async create (data: ${upperName}Data, params?: ${upperName}Params): Promise<${upperName}Result> + async create (data: ${upperName}Data[], params?: ${upperName}Params): Promise<${upperName}Result[]> + async create (data: ${upperName}Data|${upperName}Data[], params?: ${upperName}Params): Promise<${upperName}Result|${upperName}Result[]> { if (Array.isArray(data)) { return Promise.all(data.map(current => this.create(current, params))); } - return data; + return { + id: 'created', + ...data + }; } - async update (id: NullableId, data: Data, params?: Params) { - return data; + async update (id: NullableId, data: ${upperName}Data, _params?: ${upperName}Params): Promise<${upperName}Result> { + return { + id: \`\${id}\`, + ...data + }; } - async patch (id: NullableId, data: Data, params?: Params) { - return data; + async patch (id: NullableId, data: ${upperName}Data, _params?: ${upperName}Params): Promise<${upperName}Result> { + return { + id: \`\${id}\`, + ...data + }; } - async remove (id: NullableId, params?: Params) { - return { id }; + async remove (id: NullableId, _params?: ${upperName}Params): Promise<${upperName}Result> { + return { + id: \`\${id}\`, + text: 'removed' + }; } } ` -export const importTemplate = - "import type { Id, NullableId, Params, ServiceMethods } from '@feathersjs/feathers'" +export const importTemplate = "import type { Id, NullableId, Params } from '@feathersjs/feathers'" + +const optionTemplate = ({}: ServiceGeneratorContext) => ` app` -const toServiceFile = toFile(({ lib, folder, kebabName }) => [ +const toServiceFile = toFile(({ lib, language, folder, fileName }) => [ lib, 'services', ...folder, - `${kebabName}.ts` + `${fileName}.${language}` ]) export const generate = (ctx: ServiceGeneratorContext) => generator(ctx) - .then( - inject( - getSource(template), - after(({ className }) => `// The ${className} service class`), - toServiceFile - ) - ) + .then(inject(getSource(template), before('export const hooks ='), toServiceFile)) .then(inject(getSource(importTemplate), prepend(), toServiceFile)) + .then(inject(optionTemplate, after('const options ='), toServiceFile)) diff --git a/packages/cli/src/service/type/knex.tpl.ts b/packages/cli/src/service/type/knex.tpl.ts index 5d1de1a12f..268a8fc035 100644 --- a/packages/cli/src/service/type/knex.tpl.ts +++ b/packages/cli/src/service/type/knex.tpl.ts @@ -33,11 +33,11 @@ export const optionTemplate = ({ kebabName, feathers }: ServiceGeneratorContext) Model: app.get('${feathers.database}Client'), name: '${kebabName}'` -const toServiceFile = toFile(({ lib, folder, kebabName, language }) => [ +const toServiceFile = toFile(({ lib, folder, fileName, language }) => [ lib, 'services', ...folder, - `${kebabName}.${language}` + `${fileName}.${language}` ]) export const generate = (ctx: ServiceGeneratorContext) => diff --git a/packages/cli/src/service/type/mongodb.tpl.ts b/packages/cli/src/service/type/mongodb.tpl.ts index 4377e1e93e..b4d9959f72 100644 --- a/packages/cli/src/service/type/mongodb.tpl.ts +++ b/packages/cli/src/service/type/mongodb.tpl.ts @@ -18,11 +18,11 @@ const optionTemplate = ({ kebabName }: ServiceGeneratorContext) => ` paginate: app.get('paginate'), Model: app.get('mongodbClient').then(db => db.collection('${kebabName}'))` -const toServiceFile = toFile(({ lib, folder, kebabName, language }) => [ +const toServiceFile = toFile(({ lib, folder, fileName, language }) => [ lib, 'services', ...folder, - `${kebabName}.${language}` + `${fileName}.${language}` ]) export const generate = (ctx: ServiceGeneratorContext) => diff --git a/packages/cli/test/generators.test.ts b/packages/cli/test/generators.test.ts index 9d6d6b9f8c..59599cd554 100644 --- a/packages/cli/test/generators.test.ts +++ b/packages/cli/test/generators.test.ts @@ -36,7 +36,6 @@ describe('@feathersjs/cli', () => { before(async () => { cwd = await mkdtemp(path.join(os.tmpdir(), name + '-')) console.log(cwd) - context = await generate( getContext( { @@ -69,6 +68,7 @@ describe('@feathersjs/cli', () => { const connectionContext = await generate( getContext( { + dependencyVersions, database: 'mongodb' as const, connectionString: `mongodb://localhost:27017/${name}`, _: ['generate', 'connection'] @@ -79,8 +79,9 @@ describe('@feathersjs/cli', () => { const mongoServiceContext = await generate( getContext( { + dependencyVersions, name: 'testing', - path: 'path/to/testing', + path: 'path/to/test', authentication: true, type: 'mongodb', _: ['generate', 'service'] @@ -95,9 +96,25 @@ describe('@feathersjs/cli', () => { assert.strictEqual(testResult, 0) }) - // it('generates a custom service and passes tests', async () => { + it('generates a custom service and passes tests', async () => { + const customServiceContext = await generate( + getContext( + { + dependencyVersions, + name: 'Custom Service', + path: 'custom', + authentication: false, + type: 'custom', + _: ['generate', 'service'] + }, + { cwd } + ) + ) + const testResult = await context.pinion.exec('npm', ['test'], { cwd }) - // }) + assert.ok(customServiceContext) + assert.strictEqual(testResult, 0) + }) }) } }) From 4e06bdf97124b0471519363ac31c7c442c0c649e Mon Sep 17 00:00:00 2001 From: daffl Date: Mon, 20 Jun 2022 20:02:20 -0700 Subject: [PATCH 4/6] Add migration create script --- packages/cli/src/connection/templates/knex.tpl.ts | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/packages/cli/src/connection/templates/knex.tpl.ts b/packages/cli/src/connection/templates/knex.tpl.ts index 6a424bd996..e5ab9c6499 100644 --- a/packages/cli/src/connection/templates/knex.tpl.ts +++ b/packages/cli/src/connection/templates/knex.tpl.ts @@ -56,8 +56,9 @@ export const generate = (ctx: ConnectionGeneratorContext) => mergeJSON( { scripts: { - migrate: `knex migrate:latest`, - test: 'npm run migrate && npm run mocha' + migrate: 'knex migrate:latest', + 'migrate:create': 'knex migrate:create', + test: 'cross-env NODE_ENV=test npm run migrate && npm run mocha' } }, toFile('package.json') From ba5edac6fcb0a992e5f12cc31118387e609ac11a Mon Sep 17 00:00:00 2001 From: daffl Date: Mon, 20 Jun 2022 20:43:16 -0700 Subject: [PATCH 5/6] Update dependencies --- package-lock.json | 400 ++++++++++++++++++-------------------- package.json | 4 +- packages/cli/package.json | 2 +- 3 files changed, 196 insertions(+), 210 deletions(-) diff --git a/package-lock.json b/package-lock.json index 3f764a86ba..110f211f21 100644 --- a/package-lock.json +++ b/package-lock.json @@ -9,7 +9,7 @@ "dependencies": { "@babel/core": "^7.18.2", "@babel/preset-env": "^7.18.2", - "@feathershq/pinion": "^0.3.1", + "@feathershq/pinion": "^0.3.2", "@feathersjs/hooks": "^0.7.5", "@types/axios": "^0.14.0", "@types/bcryptjs": "^2.4.2", @@ -1773,9 +1773,9 @@ "dev": true }, "node_modules/@feathershq/pinion": { - "version": "0.3.1", - "resolved": "https://registry.npmjs.org/@feathershq/pinion/-/pinion-0.3.1.tgz", - "integrity": "sha512-wrfaWB4S+DkJASaW4gbfkk+x2SrTM0ORi/Rzm5ZWeHPu8fMOiX69rpokXYQRVgb5QyaAisP3QhQZcAv2C1qFIw==", + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/@feathershq/pinion/-/pinion-0.3.2.tgz", + "integrity": "sha512-shM4tplTR+kque5JAHN6P/fQzLjmGy6XjhBXOVeYcVkfIDHVd/5E4jggGABnjUNF45aTE+m6HclaN7a8KOXUOg==", "dependencies": { "@types/inquirer": "^8.2.0", "@types/yargs": "^17.0.8", @@ -3162,9 +3162,9 @@ } }, "node_modules/@npmcli/arborist/node_modules/make-fetch-happen": { - "version": "10.1.7", - "resolved": "https://registry.npmjs.org/make-fetch-happen/-/make-fetch-happen-10.1.7.tgz", - "integrity": "sha512-J/2xa2+7zlIUKqfyXDCXFpH3ypxO4k3rgkZHPSZkyUYcBT/hM80M3oyKLM/9dVriZFiGeGGS2Ei+0v2zfhqj3Q==", + "version": "10.1.8", + "resolved": "https://registry.npmjs.org/make-fetch-happen/-/make-fetch-happen-10.1.8.tgz", + "integrity": "sha512-0ASJbG12Au6+N5I84W+8FhGS6iM8MyzvZady+zaQAu+6IOaESFzCLLD0AR1sAFF3Jufi8bxm586ABN6hWd3k7g==", "dev": true, "dependencies": { "agentkeepalive": "^4.2.1", @@ -3495,9 +3495,9 @@ } }, "node_modules/@octokit/openapi-types": { - "version": "12.1.0", - "resolved": "https://registry.npmjs.org/@octokit/openapi-types/-/openapi-types-12.1.0.tgz", - "integrity": "sha512-kQzJh3ZUv3lDpi6M+uekMRHULvf9DlWoI1XgKN6nPeGDzkSgtkhVq1MMz3bFKQ6H6GbdC3ZqG/a6VzKhIx0VeA==", + "version": "12.4.0", + "resolved": "https://registry.npmjs.org/@octokit/openapi-types/-/openapi-types-12.4.0.tgz", + "integrity": "sha512-Npcb7Pv30b33U04jvcD7l75yLU0mxhuX2Xqrn51YyZ5WTkF04bpbxLaZ6GcaTqu03WZQHoO/Gbfp95NGRueDUA==", "dev": true }, "node_modules/@octokit/plugin-enterprise-rest": { @@ -3507,12 +3507,12 @@ "dev": true }, "node_modules/@octokit/plugin-paginate-rest": { - "version": "2.18.0", - "resolved": "https://registry.npmjs.org/@octokit/plugin-paginate-rest/-/plugin-paginate-rest-2.18.0.tgz", - "integrity": "sha512-n5/AzIoy5Wzp85gqzSbR+dWQDHlyHZrGijnDfLh452547Ynu0hCvszH7EfRE0eqM5ZjfkplO0k+q+P8AAIIJEA==", + "version": "2.19.0", + "resolved": "https://registry.npmjs.org/@octokit/plugin-paginate-rest/-/plugin-paginate-rest-2.19.0.tgz", + "integrity": "sha512-hQ4Qysg2hNmEMuZeJkvyzM4eSZiTifOKqYAMsW8FnxFKowhuwWICSgBQ9Gn9GpUmgKB7qaf1hFvMjYaTAg5jQA==", "dev": true, "dependencies": { - "@octokit/types": "^6.35.0" + "@octokit/types": "^6.36.0" }, "peerDependencies": { "@octokit/core": ">=2" @@ -3528,12 +3528,12 @@ } }, "node_modules/@octokit/plugin-rest-endpoint-methods": { - "version": "5.14.0", - "resolved": "https://registry.npmjs.org/@octokit/plugin-rest-endpoint-methods/-/plugin-rest-endpoint-methods-5.14.0.tgz", - "integrity": "sha512-MRnMs4Dcm1OSaz/g/RLr4YY9otgysS7vN5SUkHGd7t+R8323cHsHFoEWHYPSmgUC0BieHRhvnCRWb4i3Pl+Lgg==", + "version": "5.15.0", + "resolved": "https://registry.npmjs.org/@octokit/plugin-rest-endpoint-methods/-/plugin-rest-endpoint-methods-5.15.0.tgz", + "integrity": "sha512-Gsw9+Xm56jVhfbJoy4pt6eOOyf8/3K6CAnx1Sl7U2GhZWcg8MR6YgXWnpfdF69S2ViMXLA7nfvTDAsZpFlkLRw==", "dev": true, "dependencies": { - "@octokit/types": "^6.35.0", + "@octokit/types": "^6.36.0", "deprecation": "^2.3.1" }, "peerDependencies": { @@ -3578,12 +3578,12 @@ } }, "node_modules/@octokit/types": { - "version": "6.35.0", - "resolved": "https://registry.npmjs.org/@octokit/types/-/types-6.35.0.tgz", - "integrity": "sha512-DhLfdUuv3H37u6jBDfkwamypx3HflHg29b26nbA6iVFYkAlZ5cMEtu/9pQoihGnQE5M7jJFnNo25Rr1UwQNF8Q==", + "version": "6.37.0", + "resolved": "https://registry.npmjs.org/@octokit/types/-/types-6.37.0.tgz", + "integrity": "sha512-BXWQhFKRkjX4dVW5L2oYa0hzWOAqsEsujXsQLSdepPoDZfYdubrD1KDGpyNldGXtR8QM/WezDcxcIN1UKJMGPA==", "dev": true, "dependencies": { - "@octokit/openapi-types": "^12.1.0" + "@octokit/openapi-types": "^12.4.0" } }, "node_modules/@sindresorhus/is": { @@ -4001,14 +4001,14 @@ "integrity": "sha512-iO9ZQHkZxHn4mSakYV0vFHAVDyEOIJQrV2uZ06HxEPcx+mt8swXoZHIbaaJ2crJYFfErySgktuTZ3BeLz+XmFA==" }, "node_modules/@typescript-eslint/eslint-plugin": { - "version": "5.28.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-5.28.0.tgz", - "integrity": "sha512-DXVU6Cg29H2M6EybqSg2A+x8DgO9TCUBRp4QEXQHJceLS7ogVDP0g3Lkg/SZCqcvkAP/RruuQqK0gdlkgmhSUA==", + "version": "5.29.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-5.29.0.tgz", + "integrity": "sha512-kgTsISt9pM53yRFQmLZ4npj99yGl3x3Pl7z4eA66OuTzAGC4bQB5H5fuLwPnqTKU3yyrrg4MIhjF17UYnL4c0w==", "dev": true, "dependencies": { - "@typescript-eslint/scope-manager": "5.28.0", - "@typescript-eslint/type-utils": "5.28.0", - "@typescript-eslint/utils": "5.28.0", + "@typescript-eslint/scope-manager": "5.29.0", + "@typescript-eslint/type-utils": "5.29.0", + "@typescript-eslint/utils": "5.29.0", "debug": "^4.3.4", "functional-red-black-tree": "^1.0.1", "ignore": "^5.2.0", @@ -4034,14 +4034,14 @@ } }, "node_modules/@typescript-eslint/parser": { - "version": "5.28.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-5.28.0.tgz", - "integrity": "sha512-ekqoNRNK1lAcKhZESN/PdpVsWbP9jtiNqzFWkp/yAUdZvJalw2heCYuqRmM5eUJSIYEkgq5sGOjq+ZqsLMjtRA==", + "version": "5.29.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-5.29.0.tgz", + "integrity": "sha512-ruKWTv+x0OOxbzIw9nW5oWlUopvP/IQDjB5ZqmTglLIoDTctLlAJpAQFpNPJP/ZI7hTT9sARBosEfaKbcFuECw==", "dev": true, "dependencies": { - "@typescript-eslint/scope-manager": "5.28.0", - "@typescript-eslint/types": "5.28.0", - "@typescript-eslint/typescript-estree": "5.28.0", + "@typescript-eslint/scope-manager": "5.29.0", + "@typescript-eslint/types": "5.29.0", + "@typescript-eslint/typescript-estree": "5.29.0", "debug": "^4.3.4" }, "engines": { @@ -4061,13 +4061,13 @@ } }, "node_modules/@typescript-eslint/scope-manager": { - "version": "5.28.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-5.28.0.tgz", - "integrity": "sha512-LeBLTqF/he1Z+boRhSqnso6YrzcKMTQ8bO/YKEe+6+O/JGof9M0g3IJlIsqfrK/6K03MlFIlycbf1uQR1IjE+w==", + "version": "5.29.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-5.29.0.tgz", + "integrity": "sha512-etbXUT0FygFi2ihcxDZjz21LtC+Eps9V2xVx09zFoN44RRHPrkMflidGMI+2dUs821zR1tDS6Oc9IXxIjOUZwA==", "dev": true, "dependencies": { - "@typescript-eslint/types": "5.28.0", - "@typescript-eslint/visitor-keys": "5.28.0" + "@typescript-eslint/types": "5.29.0", + "@typescript-eslint/visitor-keys": "5.29.0" }, "engines": { "node": "^12.22.0 || ^14.17.0 || >=16.0.0" @@ -4078,12 +4078,12 @@ } }, "node_modules/@typescript-eslint/type-utils": { - "version": "5.28.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-5.28.0.tgz", - "integrity": "sha512-SyKjKh4CXPglueyC6ceAFytjYWMoPHMswPQae236zqe1YbhvCVQyIawesYywGiu98L9DwrxsBN69vGIVxJ4mQQ==", + "version": "5.29.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-5.29.0.tgz", + "integrity": "sha512-JK6bAaaiJozbox3K220VRfCzLa9n0ib/J+FHIwnaV3Enw/TO267qe0pM1b1QrrEuy6xun374XEAsRlA86JJnyg==", "dev": true, "dependencies": { - "@typescript-eslint/utils": "5.28.0", + "@typescript-eslint/utils": "5.29.0", "debug": "^4.3.4", "tsutils": "^3.21.0" }, @@ -4104,9 +4104,9 @@ } }, "node_modules/@typescript-eslint/types": { - "version": "5.28.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.28.0.tgz", - "integrity": "sha512-2OOm8ZTOQxqkPbf+DAo8oc16sDlVR5owgJfKheBkxBKg1vAfw2JsSofH9+16VPlN9PWtv8Wzhklkqw3k/zCVxA==", + "version": "5.29.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.29.0.tgz", + "integrity": "sha512-X99VbqvAXOMdVyfFmksMy3u8p8yoRGITgU1joBJPzeYa0rhdf5ok9S56/itRoUSh99fiDoMtarSIJXo7H/SnOg==", "dev": true, "engines": { "node": "^12.22.0 || ^14.17.0 || >=16.0.0" @@ -4117,13 +4117,13 @@ } }, "node_modules/@typescript-eslint/typescript-estree": { - "version": "5.28.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-5.28.0.tgz", - "integrity": "sha512-9GX+GfpV+F4hdTtYc6OV9ZkyYilGXPmQpm6AThInpBmKJEyRSIjORJd1G9+bknb7OTFYL+Vd4FBJAO6T78OVqA==", + "version": "5.29.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-5.29.0.tgz", + "integrity": "sha512-mQvSUJ/JjGBdvo+1LwC+GY2XmSYjK1nAaVw2emp/E61wEVYEyibRHCqm1I1vEKbXCpUKuW4G7u9ZCaZhJbLoNQ==", "dev": true, "dependencies": { - "@typescript-eslint/types": "5.28.0", - "@typescript-eslint/visitor-keys": "5.28.0", + "@typescript-eslint/types": "5.29.0", + "@typescript-eslint/visitor-keys": "5.29.0", "debug": "^4.3.4", "globby": "^11.1.0", "is-glob": "^4.0.3", @@ -4144,15 +4144,15 @@ } }, "node_modules/@typescript-eslint/utils": { - "version": "5.28.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-5.28.0.tgz", - "integrity": "sha512-E60N5L0fjv7iPJV3UGc4EC+A3Lcj4jle9zzR0gW7vXhflO7/J29kwiTGITA2RlrmPokKiZbBy2DgaclCaEUs6g==", + "version": "5.29.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-5.29.0.tgz", + "integrity": "sha512-3Eos6uP1nyLOBayc/VUdKZikV90HahXE5Dx9L5YlSd/7ylQPXhLk1BYb29SDgnBnTp+jmSZUU0QxUiyHgW4p7A==", "dev": true, "dependencies": { "@types/json-schema": "^7.0.9", - "@typescript-eslint/scope-manager": "5.28.0", - "@typescript-eslint/types": "5.28.0", - "@typescript-eslint/typescript-estree": "5.28.0", + "@typescript-eslint/scope-manager": "5.29.0", + "@typescript-eslint/types": "5.29.0", + "@typescript-eslint/typescript-estree": "5.29.0", "eslint-scope": "^5.1.1", "eslint-utils": "^3.0.0" }, @@ -4168,12 +4168,12 @@ } }, "node_modules/@typescript-eslint/visitor-keys": { - "version": "5.28.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.28.0.tgz", - "integrity": "sha512-BtfP1vCor8cWacovzzPFOoeW4kBQxzmhxGoOpt0v1SFvG+nJ0cWaVdJk7cky1ArTcFHHKNIxyo2LLr3oNkSuXA==", + "version": "5.29.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.29.0.tgz", + "integrity": "sha512-Hpb/mCWsjILvikMQoZIE3voc9wtQcS0A9FUw3h8bhr9UxBdtI/tw1ZDZUOXHXLOVMedKCH5NxyzATwnU78bWCQ==", "dev": true, "dependencies": { - "@typescript-eslint/types": "5.28.0", + "@typescript-eslint/types": "5.29.0", "eslint-visitor-keys": "^3.3.0" }, "engines": { @@ -6567,9 +6567,9 @@ } }, "node_modules/caniuse-lite": { - "version": "1.0.30001356", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001356.tgz", - "integrity": "sha512-/30854bktMLhxtjieIxsrJBfs2gTM1pel6MXKF3K+RdIVJZcsn2A2QdhsuR4/p9+R204fZw0zCBBhktX8xWuyQ==", + "version": "1.0.30001357", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001357.tgz", + "integrity": "sha512-b+KbWHdHePp+ZpNj+RDHFChZmuN+J5EvuQUlee9jOQIUAdhv9uvAZeEtUeLAknXbkiu1uxjQ9NLp1ie894CuWg==", "funding": [ { "type": "opencollective", @@ -7253,9 +7253,9 @@ "hasInstallScript": true }, "node_modules/core-js-compat": { - "version": "3.23.1", - "resolved": "https://registry.npmjs.org/core-js-compat/-/core-js-compat-3.23.1.tgz", - "integrity": "sha512-KeYrEc8t6FJsKYB2qnDwRHWaC0cJNaqlHfCpMe5q3j/W1nje3moib/txNklddLPCtGb+etcBIyJ8zuMa/LN5/A==", + "version": "3.23.2", + "resolved": "https://registry.npmjs.org/core-js-compat/-/core-js-compat-3.23.2.tgz", + "integrity": "sha512-lrgZvxFwbQp9v7E8mX0rJ+JX7Bvh4eGULZXA1IAyjlsnWvCdw6TF8Tg6xtaSUSJMrSrMaLdpmk+V54LM1dvfOA==", "dependencies": { "browserslist": "^4.20.4", "semver": "7.0.0" @@ -7695,9 +7695,9 @@ "integrity": "sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==" }, "node_modules/electron-to-chromium": { - "version": "1.4.161", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.161.tgz", - "integrity": "sha512-sTjBRhqh6wFodzZtc5Iu8/R95OkwaPNn7tj/TaDU5nu/5EFiQDtADGAXdR4tJcTEHlYfJpHqigzJqHvPgehP8A==" + "version": "1.4.163", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.163.tgz", + "integrity": "sha512-c9q94pUVqIdc8hyr7jZDB4bNEoNF3QJ7y35lnddMD+mXtiv5GsL1bT/RmfW/KEOmvlNg5Oy1qioiy4tA7e864Q==" }, "node_modules/elliptic": { "version": "6.5.4", @@ -12442,9 +12442,9 @@ } }, "node_modules/minipass": { - "version": "3.1.6", - "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.1.6.tgz", - "integrity": "sha512-rty5kpw9/z8SX9dmxblFA6edItUmwJgMeYDZRrwlIVN27i8gysGbznJwUggw2V/FVqFSDdWy040ZPS811DYAqQ==", + "version": "3.3.3", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.3.3.tgz", + "integrity": "sha512-N0BOsdFAlNRfmwMhjAsLVWOk7Ljmeb39iqFlsV1At+jqRhSUP9yeof8FyJu4imaJiSUp8vQebWD/guZwGQC8iA==", "dependencies": { "yallist": "^4.0.0" }, @@ -13026,12 +13026,12 @@ } }, "node_modules/mongodb-memory-server": { - "version": "8.6.1", - "resolved": "https://registry.npmjs.org/mongodb-memory-server/-/mongodb-memory-server-8.6.1.tgz", - "integrity": "sha512-X/jlNQnsv1+lTMetg9UAxyOG1soJcfS7bQp0WGQ9bi1J97+OyIWiFR7Tx9wwX3A6eQRBL3B1P+5XFIwLk6XZtg==", + "version": "8.7.0", + "resolved": "https://registry.npmjs.org/mongodb-memory-server/-/mongodb-memory-server-8.7.0.tgz", + "integrity": "sha512-xn8RvdqeNfqLsv7LQIFy/VyDLE3AzylddcMGpQzZnVdHVuHEA09m+uGWplU4CkduGyvZTCFP9cbj+kFSX79BDA==", "hasInstallScript": true, "dependencies": { - "mongodb-memory-server-core": "8.6.1", + "mongodb-memory-server-core": "8.7.0", "tslib": "^2.4.0" }, "engines": { @@ -13039,9 +13039,9 @@ } }, "node_modules/mongodb-memory-server-core": { - "version": "8.6.1", - "resolved": "https://registry.npmjs.org/mongodb-memory-server-core/-/mongodb-memory-server-core-8.6.1.tgz", - "integrity": "sha512-GOe2AOYzqUg9DsSJFA7wbWaqt4pbaulXhM1lgs19s+H0Q/VkFtvB3RpOvnWVLAV5PADg9zTY22ecVI2txTxGow==", + "version": "8.7.0", + "resolved": "https://registry.npmjs.org/mongodb-memory-server-core/-/mongodb-memory-server-core-8.7.0.tgz", + "integrity": "sha512-dYJ+u9ZP4koCcMzxTwAUDxsG92evcJdXt70spMXrRUVQL7PI5Q83yLOHdqKhjevwfzJwyE8pFCGDGU+Qxs/cUA==", "dependencies": { "@types/tmp": "^0.2.3", "async-mutex": "^0.3.2", @@ -13051,8 +13051,8 @@ "get-port": "^5.1.1", "https-proxy-agent": "^5.0.1", "md5-file": "^5.0.0", - "mongodb": "^4.5.0", - "new-find-package-json": "^1.1.0", + "mongodb": "^4.7.0", + "new-find-package-json": "^2.0.0", "semver": "^7.3.7", "tar-stream": "^2.1.4", "tmp": "^0.2.1", @@ -13165,22 +13165,16 @@ "integrity": "sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw==" }, "node_modules/new-find-package-json": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/new-find-package-json/-/new-find-package-json-1.2.0.tgz", - "integrity": "sha512-Z4v/wBxApGh1cCGEhNmq4p8wjDvM6R6vEuYzlAhzOlXBKLJfjyMvwd+ZHR9fyYKVvXfEn4Z3YX6MD470PxpVbQ==", + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/new-find-package-json/-/new-find-package-json-2.0.0.tgz", + "integrity": "sha512-lDcBsjBSMlj3LXH2v/FW3txlh2pYTjmbOXPYJD93HI5EwuLzI11tdHSIpUMmfq/IOsldj4Ps8M8flhm+pCK4Ew==", "dependencies": { - "debug": "^4.3.4", - "tslib": "^2.4.0" + "debug": "^4.3.4" }, "engines": { "node": ">=12.22.0" } }, - "node_modules/new-find-package-json/node_modules/tslib": { - "version": "2.4.0", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.4.0.tgz", - "integrity": "sha512-d6xOpEDfsi2CZVlPQzGeux8XMwLT9hssAsaPYExaQMuYskwb+x1x7J371tWlbBdWHroy99KnVB6qIkUbs5X3UQ==" - }, "node_modules/node-addon-api": { "version": "4.3.0", "resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-4.3.0.tgz", @@ -14157,9 +14151,9 @@ } }, "node_modules/pacote/node_modules/make-fetch-happen": { - "version": "10.1.7", - "resolved": "https://registry.npmjs.org/make-fetch-happen/-/make-fetch-happen-10.1.7.tgz", - "integrity": "sha512-J/2xa2+7zlIUKqfyXDCXFpH3ypxO4k3rgkZHPSZkyUYcBT/hM80M3oyKLM/9dVriZFiGeGGS2Ei+0v2zfhqj3Q==", + "version": "10.1.8", + "resolved": "https://registry.npmjs.org/make-fetch-happen/-/make-fetch-happen-10.1.8.tgz", + "integrity": "sha512-0ASJbG12Au6+N5I84W+8FhGS6iM8MyzvZady+zaQAu+6IOaESFzCLLD0AR1sAFF3Jufi8bxm586ABN6hWd3k7g==", "dev": true, "dependencies": { "agentkeepalive": "^4.2.1", @@ -15730,11 +15724,11 @@ "integrity": "sha512-IqSUtOVP4ksd1C/ej5zeEh/BIP2ajqpn8c5x+q99gvcIG/Qf0cud5raVnE/Dwd0ua9TXYDoDc0RE5hBSdz22Ug==" }, "node_modules/resolve": { - "version": "1.22.0", - "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.0.tgz", - "integrity": "sha512-Hhtrw0nLeSrFQ7phPp4OOcVjLPIeMnRlr5mcnVuMe7M/7eBn98A3hmFRLoFo3DLZkivSYwhRUJTyPyWAk56WLw==", + "version": "1.22.1", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.1.tgz", + "integrity": "sha512-nBpuuYuY5jFsli/JIs1oldw6fOQCBioohqWZg/2hiaOybXOft4lonv85uDOKXdf8rhyK159cxU5cDcK/NKk8zw==", "dependencies": { - "is-core-module": "^2.8.1", + "is-core-module": "^2.9.0", "path-parse": "^1.0.7", "supports-preserve-symlinks-flag": "^1.0.0" }, @@ -17496,12 +17490,12 @@ "integrity": "sha512-wa7YjyUGfNZngI/vtK0UHAN+lgDCxBPCylVXGp0zu59Fz5aiGtNXaq3DhIov063MorB+VfufLh3JlF2KdTK3xg==" }, "node_modules/v8-to-istanbul": { - "version": "9.0.0", - "resolved": "https://registry.npmjs.org/v8-to-istanbul/-/v8-to-istanbul-9.0.0.tgz", - "integrity": "sha512-HcvgY/xaRm7isYmyx+lFKA4uQmfUbN0J4M0nNItvzTvH/iQ9kW5j/t4YSR+Ge323/lrgDAWJoF46tzGQHwBHFw==", + "version": "9.0.1", + "resolved": "https://registry.npmjs.org/v8-to-istanbul/-/v8-to-istanbul-9.0.1.tgz", + "integrity": "sha512-74Y4LqY74kLE6IFyIjPtkSTWzUZmj8tdHT9Ii/26dvQ6K9Dl2NbEfj0XgU2sHCtKgt5VupqhlO/5aWuqS+IY1w==", "dev": true, "dependencies": { - "@jridgewell/trace-mapping": "^0.3.7", + "@jridgewell/trace-mapping": "^0.3.12", "@types/istanbul-lib-coverage": "^2.0.1", "convert-source-map": "^1.6.0" }, @@ -19335,9 +19329,9 @@ } }, "@feathershq/pinion": { - "version": "0.3.1", - "resolved": "https://registry.npmjs.org/@feathershq/pinion/-/pinion-0.3.1.tgz", - "integrity": "sha512-wrfaWB4S+DkJASaW4gbfkk+x2SrTM0ORi/Rzm5ZWeHPu8fMOiX69rpokXYQRVgb5QyaAisP3QhQZcAv2C1qFIw==", + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/@feathershq/pinion/-/pinion-0.3.2.tgz", + "integrity": "sha512-shM4tplTR+kque5JAHN6P/fQzLjmGy6XjhBXOVeYcVkfIDHVd/5E4jggGABnjUNF45aTE+m6HclaN7a8KOXUOg==", "requires": { "@types/inquirer": "^8.2.0", "@types/yargs": "^17.0.8", @@ -20472,9 +20466,9 @@ } }, "make-fetch-happen": { - "version": "10.1.7", - "resolved": "https://registry.npmjs.org/make-fetch-happen/-/make-fetch-happen-10.1.7.tgz", - "integrity": "sha512-J/2xa2+7zlIUKqfyXDCXFpH3ypxO4k3rgkZHPSZkyUYcBT/hM80M3oyKLM/9dVriZFiGeGGS2Ei+0v2zfhqj3Q==", + "version": "10.1.8", + "resolved": "https://registry.npmjs.org/make-fetch-happen/-/make-fetch-happen-10.1.8.tgz", + "integrity": "sha512-0ASJbG12Au6+N5I84W+8FhGS6iM8MyzvZady+zaQAu+6IOaESFzCLLD0AR1sAFF3Jufi8bxm586ABN6hWd3k7g==", "dev": true, "requires": { "agentkeepalive": "^4.2.1", @@ -20750,9 +20744,9 @@ } }, "@octokit/openapi-types": { - "version": "12.1.0", - "resolved": "https://registry.npmjs.org/@octokit/openapi-types/-/openapi-types-12.1.0.tgz", - "integrity": "sha512-kQzJh3ZUv3lDpi6M+uekMRHULvf9DlWoI1XgKN6nPeGDzkSgtkhVq1MMz3bFKQ6H6GbdC3ZqG/a6VzKhIx0VeA==", + "version": "12.4.0", + "resolved": "https://registry.npmjs.org/@octokit/openapi-types/-/openapi-types-12.4.0.tgz", + "integrity": "sha512-Npcb7Pv30b33U04jvcD7l75yLU0mxhuX2Xqrn51YyZ5WTkF04bpbxLaZ6GcaTqu03WZQHoO/Gbfp95NGRueDUA==", "dev": true }, "@octokit/plugin-enterprise-rest": { @@ -20762,12 +20756,12 @@ "dev": true }, "@octokit/plugin-paginate-rest": { - "version": "2.18.0", - "resolved": "https://registry.npmjs.org/@octokit/plugin-paginate-rest/-/plugin-paginate-rest-2.18.0.tgz", - "integrity": "sha512-n5/AzIoy5Wzp85gqzSbR+dWQDHlyHZrGijnDfLh452547Ynu0hCvszH7EfRE0eqM5ZjfkplO0k+q+P8AAIIJEA==", + "version": "2.19.0", + "resolved": "https://registry.npmjs.org/@octokit/plugin-paginate-rest/-/plugin-paginate-rest-2.19.0.tgz", + "integrity": "sha512-hQ4Qysg2hNmEMuZeJkvyzM4eSZiTifOKqYAMsW8FnxFKowhuwWICSgBQ9Gn9GpUmgKB7qaf1hFvMjYaTAg5jQA==", "dev": true, "requires": { - "@octokit/types": "^6.35.0" + "@octokit/types": "^6.36.0" } }, "@octokit/plugin-request-log": { @@ -20778,12 +20772,12 @@ "requires": {} }, "@octokit/plugin-rest-endpoint-methods": { - "version": "5.14.0", - "resolved": "https://registry.npmjs.org/@octokit/plugin-rest-endpoint-methods/-/plugin-rest-endpoint-methods-5.14.0.tgz", - "integrity": "sha512-MRnMs4Dcm1OSaz/g/RLr4YY9otgysS7vN5SUkHGd7t+R8323cHsHFoEWHYPSmgUC0BieHRhvnCRWb4i3Pl+Lgg==", + "version": "5.15.0", + "resolved": "https://registry.npmjs.org/@octokit/plugin-rest-endpoint-methods/-/plugin-rest-endpoint-methods-5.15.0.tgz", + "integrity": "sha512-Gsw9+Xm56jVhfbJoy4pt6eOOyf8/3K6CAnx1Sl7U2GhZWcg8MR6YgXWnpfdF69S2ViMXLA7nfvTDAsZpFlkLRw==", "dev": true, "requires": { - "@octokit/types": "^6.35.0", + "@octokit/types": "^6.36.0", "deprecation": "^2.3.1" } }, @@ -20825,12 +20819,12 @@ } }, "@octokit/types": { - "version": "6.35.0", - "resolved": "https://registry.npmjs.org/@octokit/types/-/types-6.35.0.tgz", - "integrity": "sha512-DhLfdUuv3H37u6jBDfkwamypx3HflHg29b26nbA6iVFYkAlZ5cMEtu/9pQoihGnQE5M7jJFnNo25Rr1UwQNF8Q==", + "version": "6.37.0", + "resolved": "https://registry.npmjs.org/@octokit/types/-/types-6.37.0.tgz", + "integrity": "sha512-BXWQhFKRkjX4dVW5L2oYa0hzWOAqsEsujXsQLSdepPoDZfYdubrD1KDGpyNldGXtR8QM/WezDcxcIN1UKJMGPA==", "dev": true, "requires": { - "@octokit/openapi-types": "^12.1.0" + "@octokit/openapi-types": "^12.4.0" } }, "@sindresorhus/is": { @@ -21237,14 +21231,14 @@ "integrity": "sha512-iO9ZQHkZxHn4mSakYV0vFHAVDyEOIJQrV2uZ06HxEPcx+mt8swXoZHIbaaJ2crJYFfErySgktuTZ3BeLz+XmFA==" }, "@typescript-eslint/eslint-plugin": { - "version": "5.28.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-5.28.0.tgz", - "integrity": "sha512-DXVU6Cg29H2M6EybqSg2A+x8DgO9TCUBRp4QEXQHJceLS7ogVDP0g3Lkg/SZCqcvkAP/RruuQqK0gdlkgmhSUA==", + "version": "5.29.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-5.29.0.tgz", + "integrity": "sha512-kgTsISt9pM53yRFQmLZ4npj99yGl3x3Pl7z4eA66OuTzAGC4bQB5H5fuLwPnqTKU3yyrrg4MIhjF17UYnL4c0w==", "dev": true, "requires": { - "@typescript-eslint/scope-manager": "5.28.0", - "@typescript-eslint/type-utils": "5.28.0", - "@typescript-eslint/utils": "5.28.0", + "@typescript-eslint/scope-manager": "5.29.0", + "@typescript-eslint/type-utils": "5.29.0", + "@typescript-eslint/utils": "5.29.0", "debug": "^4.3.4", "functional-red-black-tree": "^1.0.1", "ignore": "^5.2.0", @@ -21254,52 +21248,52 @@ } }, "@typescript-eslint/parser": { - "version": "5.28.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-5.28.0.tgz", - "integrity": "sha512-ekqoNRNK1lAcKhZESN/PdpVsWbP9jtiNqzFWkp/yAUdZvJalw2heCYuqRmM5eUJSIYEkgq5sGOjq+ZqsLMjtRA==", + "version": "5.29.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-5.29.0.tgz", + "integrity": "sha512-ruKWTv+x0OOxbzIw9nW5oWlUopvP/IQDjB5ZqmTglLIoDTctLlAJpAQFpNPJP/ZI7hTT9sARBosEfaKbcFuECw==", "dev": true, "requires": { - "@typescript-eslint/scope-manager": "5.28.0", - "@typescript-eslint/types": "5.28.0", - "@typescript-eslint/typescript-estree": "5.28.0", + "@typescript-eslint/scope-manager": "5.29.0", + "@typescript-eslint/types": "5.29.0", + "@typescript-eslint/typescript-estree": "5.29.0", "debug": "^4.3.4" } }, "@typescript-eslint/scope-manager": { - "version": "5.28.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-5.28.0.tgz", - "integrity": "sha512-LeBLTqF/he1Z+boRhSqnso6YrzcKMTQ8bO/YKEe+6+O/JGof9M0g3IJlIsqfrK/6K03MlFIlycbf1uQR1IjE+w==", + "version": "5.29.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-5.29.0.tgz", + "integrity": "sha512-etbXUT0FygFi2ihcxDZjz21LtC+Eps9V2xVx09zFoN44RRHPrkMflidGMI+2dUs821zR1tDS6Oc9IXxIjOUZwA==", "dev": true, "requires": { - "@typescript-eslint/types": "5.28.0", - "@typescript-eslint/visitor-keys": "5.28.0" + "@typescript-eslint/types": "5.29.0", + "@typescript-eslint/visitor-keys": "5.29.0" } }, "@typescript-eslint/type-utils": { - "version": "5.28.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-5.28.0.tgz", - "integrity": "sha512-SyKjKh4CXPglueyC6ceAFytjYWMoPHMswPQae236zqe1YbhvCVQyIawesYywGiu98L9DwrxsBN69vGIVxJ4mQQ==", + "version": "5.29.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-5.29.0.tgz", + "integrity": "sha512-JK6bAaaiJozbox3K220VRfCzLa9n0ib/J+FHIwnaV3Enw/TO267qe0pM1b1QrrEuy6xun374XEAsRlA86JJnyg==", "dev": true, "requires": { - "@typescript-eslint/utils": "5.28.0", + "@typescript-eslint/utils": "5.29.0", "debug": "^4.3.4", "tsutils": "^3.21.0" } }, "@typescript-eslint/types": { - "version": "5.28.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.28.0.tgz", - "integrity": "sha512-2OOm8ZTOQxqkPbf+DAo8oc16sDlVR5owgJfKheBkxBKg1vAfw2JsSofH9+16VPlN9PWtv8Wzhklkqw3k/zCVxA==", + "version": "5.29.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.29.0.tgz", + "integrity": "sha512-X99VbqvAXOMdVyfFmksMy3u8p8yoRGITgU1joBJPzeYa0rhdf5ok9S56/itRoUSh99fiDoMtarSIJXo7H/SnOg==", "dev": true }, "@typescript-eslint/typescript-estree": { - "version": "5.28.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-5.28.0.tgz", - "integrity": "sha512-9GX+GfpV+F4hdTtYc6OV9ZkyYilGXPmQpm6AThInpBmKJEyRSIjORJd1G9+bknb7OTFYL+Vd4FBJAO6T78OVqA==", + "version": "5.29.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-5.29.0.tgz", + "integrity": "sha512-mQvSUJ/JjGBdvo+1LwC+GY2XmSYjK1nAaVw2emp/E61wEVYEyibRHCqm1I1vEKbXCpUKuW4G7u9ZCaZhJbLoNQ==", "dev": true, "requires": { - "@typescript-eslint/types": "5.28.0", - "@typescript-eslint/visitor-keys": "5.28.0", + "@typescript-eslint/types": "5.29.0", + "@typescript-eslint/visitor-keys": "5.29.0", "debug": "^4.3.4", "globby": "^11.1.0", "is-glob": "^4.0.3", @@ -21308,26 +21302,26 @@ } }, "@typescript-eslint/utils": { - "version": "5.28.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-5.28.0.tgz", - "integrity": "sha512-E60N5L0fjv7iPJV3UGc4EC+A3Lcj4jle9zzR0gW7vXhflO7/J29kwiTGITA2RlrmPokKiZbBy2DgaclCaEUs6g==", + "version": "5.29.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-5.29.0.tgz", + "integrity": "sha512-3Eos6uP1nyLOBayc/VUdKZikV90HahXE5Dx9L5YlSd/7ylQPXhLk1BYb29SDgnBnTp+jmSZUU0QxUiyHgW4p7A==", "dev": true, "requires": { "@types/json-schema": "^7.0.9", - "@typescript-eslint/scope-manager": "5.28.0", - "@typescript-eslint/types": "5.28.0", - "@typescript-eslint/typescript-estree": "5.28.0", + "@typescript-eslint/scope-manager": "5.29.0", + "@typescript-eslint/types": "5.29.0", + "@typescript-eslint/typescript-estree": "5.29.0", "eslint-scope": "^5.1.1", "eslint-utils": "^3.0.0" } }, "@typescript-eslint/visitor-keys": { - "version": "5.28.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.28.0.tgz", - "integrity": "sha512-BtfP1vCor8cWacovzzPFOoeW4kBQxzmhxGoOpt0v1SFvG+nJ0cWaVdJk7cky1ArTcFHHKNIxyo2LLr3oNkSuXA==", + "version": "5.29.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.29.0.tgz", + "integrity": "sha512-Hpb/mCWsjILvikMQoZIE3voc9wtQcS0A9FUw3h8bhr9UxBdtI/tw1ZDZUOXHXLOVMedKCH5NxyzATwnU78bWCQ==", "dev": true, "requires": { - "@typescript-eslint/types": "5.28.0", + "@typescript-eslint/types": "5.29.0", "eslint-visitor-keys": "^3.3.0" } }, @@ -23342,9 +23336,9 @@ } }, "caniuse-lite": { - "version": "1.0.30001356", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001356.tgz", - "integrity": "sha512-/30854bktMLhxtjieIxsrJBfs2gTM1pel6MXKF3K+RdIVJZcsn2A2QdhsuR4/p9+R204fZw0zCBBhktX8xWuyQ==" + "version": "1.0.30001357", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001357.tgz", + "integrity": "sha512-b+KbWHdHePp+ZpNj+RDHFChZmuN+J5EvuQUlee9jOQIUAdhv9uvAZeEtUeLAknXbkiu1uxjQ9NLp1ie894CuWg==" }, "center-align": { "version": "0.1.3", @@ -23874,9 +23868,9 @@ "integrity": "sha512-Kb2wC0fvsWfQrgk8HU5lW6U/Lcs8+9aaYcy4ZFc6DDlo4nZ7n70dEgE5rtR0oG6ufKDUnrwfWL1mXR5ljDatrQ==" }, "core-js-compat": { - "version": "3.23.1", - "resolved": "https://registry.npmjs.org/core-js-compat/-/core-js-compat-3.23.1.tgz", - "integrity": "sha512-KeYrEc8t6FJsKYB2qnDwRHWaC0cJNaqlHfCpMe5q3j/W1nje3moib/txNklddLPCtGb+etcBIyJ8zuMa/LN5/A==", + "version": "3.23.2", + "resolved": "https://registry.npmjs.org/core-js-compat/-/core-js-compat-3.23.2.tgz", + "integrity": "sha512-lrgZvxFwbQp9v7E8mX0rJ+JX7Bvh4eGULZXA1IAyjlsnWvCdw6TF8Tg6xtaSUSJMrSrMaLdpmk+V54LM1dvfOA==", "requires": { "browserslist": "^4.20.4", "semver": "7.0.0" @@ -24220,9 +24214,9 @@ "integrity": "sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==" }, "electron-to-chromium": { - "version": "1.4.161", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.161.tgz", - "integrity": "sha512-sTjBRhqh6wFodzZtc5Iu8/R95OkwaPNn7tj/TaDU5nu/5EFiQDtADGAXdR4tJcTEHlYfJpHqigzJqHvPgehP8A==" + "version": "1.4.163", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.163.tgz", + "integrity": "sha512-c9q94pUVqIdc8hyr7jZDB4bNEoNF3QJ7y35lnddMD+mXtiv5GsL1bT/RmfW/KEOmvlNg5Oy1qioiy4tA7e864Q==" }, "elliptic": { "version": "6.5.4", @@ -27938,9 +27932,9 @@ } }, "minipass": { - "version": "3.1.6", - "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.1.6.tgz", - "integrity": "sha512-rty5kpw9/z8SX9dmxblFA6edItUmwJgMeYDZRrwlIVN27i8gysGbznJwUggw2V/FVqFSDdWy040ZPS811DYAqQ==", + "version": "3.3.3", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.3.3.tgz", + "integrity": "sha512-N0BOsdFAlNRfmwMhjAsLVWOk7Ljmeb39iqFlsV1At+jqRhSUP9yeof8FyJu4imaJiSUp8vQebWD/guZwGQC8iA==", "requires": { "yallist": "^4.0.0" } @@ -28395,11 +28389,11 @@ } }, "mongodb-memory-server": { - "version": "8.6.1", - "resolved": "https://registry.npmjs.org/mongodb-memory-server/-/mongodb-memory-server-8.6.1.tgz", - "integrity": "sha512-X/jlNQnsv1+lTMetg9UAxyOG1soJcfS7bQp0WGQ9bi1J97+OyIWiFR7Tx9wwX3A6eQRBL3B1P+5XFIwLk6XZtg==", + "version": "8.7.0", + "resolved": "https://registry.npmjs.org/mongodb-memory-server/-/mongodb-memory-server-8.7.0.tgz", + "integrity": "sha512-xn8RvdqeNfqLsv7LQIFy/VyDLE3AzylddcMGpQzZnVdHVuHEA09m+uGWplU4CkduGyvZTCFP9cbj+kFSX79BDA==", "requires": { - "mongodb-memory-server-core": "8.6.1", + "mongodb-memory-server-core": "8.7.0", "tslib": "^2.4.0" }, "dependencies": { @@ -28411,9 +28405,9 @@ } }, "mongodb-memory-server-core": { - "version": "8.6.1", - "resolved": "https://registry.npmjs.org/mongodb-memory-server-core/-/mongodb-memory-server-core-8.6.1.tgz", - "integrity": "sha512-GOe2AOYzqUg9DsSJFA7wbWaqt4pbaulXhM1lgs19s+H0Q/VkFtvB3RpOvnWVLAV5PADg9zTY22ecVI2txTxGow==", + "version": "8.7.0", + "resolved": "https://registry.npmjs.org/mongodb-memory-server-core/-/mongodb-memory-server-core-8.7.0.tgz", + "integrity": "sha512-dYJ+u9ZP4koCcMzxTwAUDxsG92evcJdXt70spMXrRUVQL7PI5Q83yLOHdqKhjevwfzJwyE8pFCGDGU+Qxs/cUA==", "requires": { "@types/tmp": "^0.2.3", "async-mutex": "^0.3.2", @@ -28423,8 +28417,8 @@ "get-port": "^5.1.1", "https-proxy-agent": "^5.0.1", "md5-file": "^5.0.0", - "mongodb": "^4.5.0", - "new-find-package-json": "^1.1.0", + "mongodb": "^4.7.0", + "new-find-package-json": "^2.0.0", "semver": "^7.3.7", "tar-stream": "^2.1.4", "tmp": "^0.2.1", @@ -28506,19 +28500,11 @@ "integrity": "sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw==" }, "new-find-package-json": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/new-find-package-json/-/new-find-package-json-1.2.0.tgz", - "integrity": "sha512-Z4v/wBxApGh1cCGEhNmq4p8wjDvM6R6vEuYzlAhzOlXBKLJfjyMvwd+ZHR9fyYKVvXfEn4Z3YX6MD470PxpVbQ==", + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/new-find-package-json/-/new-find-package-json-2.0.0.tgz", + "integrity": "sha512-lDcBsjBSMlj3LXH2v/FW3txlh2pYTjmbOXPYJD93HI5EwuLzI11tdHSIpUMmfq/IOsldj4Ps8M8flhm+pCK4Ew==", "requires": { - "debug": "^4.3.4", - "tslib": "^2.4.0" - }, - "dependencies": { - "tslib": { - "version": "2.4.0", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.4.0.tgz", - "integrity": "sha512-d6xOpEDfsi2CZVlPQzGeux8XMwLT9hssAsaPYExaQMuYskwb+x1x7J371tWlbBdWHroy99KnVB6qIkUbs5X3UQ==" - } + "debug": "^4.3.4" } }, "node-addon-api": { @@ -29270,9 +29256,9 @@ } }, "make-fetch-happen": { - "version": "10.1.7", - "resolved": "https://registry.npmjs.org/make-fetch-happen/-/make-fetch-happen-10.1.7.tgz", - "integrity": "sha512-J/2xa2+7zlIUKqfyXDCXFpH3ypxO4k3rgkZHPSZkyUYcBT/hM80M3oyKLM/9dVriZFiGeGGS2Ei+0v2zfhqj3Q==", + "version": "10.1.8", + "resolved": "https://registry.npmjs.org/make-fetch-happen/-/make-fetch-happen-10.1.8.tgz", + "integrity": "sha512-0ASJbG12Au6+N5I84W+8FhGS6iM8MyzvZady+zaQAu+6IOaESFzCLLD0AR1sAFF3Jufi8bxm586ABN6hWd3k7g==", "dev": true, "requires": { "agentkeepalive": "^4.2.1", @@ -30496,11 +30482,11 @@ "integrity": "sha512-IqSUtOVP4ksd1C/ej5zeEh/BIP2ajqpn8c5x+q99gvcIG/Qf0cud5raVnE/Dwd0ua9TXYDoDc0RE5hBSdz22Ug==" }, "resolve": { - "version": "1.22.0", - "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.0.tgz", - "integrity": "sha512-Hhtrw0nLeSrFQ7phPp4OOcVjLPIeMnRlr5mcnVuMe7M/7eBn98A3hmFRLoFo3DLZkivSYwhRUJTyPyWAk56WLw==", + "version": "1.22.1", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.1.tgz", + "integrity": "sha512-nBpuuYuY5jFsli/JIs1oldw6fOQCBioohqWZg/2hiaOybXOft4lonv85uDOKXdf8rhyK159cxU5cDcK/NKk8zw==", "requires": { - "is-core-module": "^2.8.1", + "is-core-module": "^2.9.0", "path-parse": "^1.0.7", "supports-preserve-symlinks-flag": "^1.0.0" } @@ -31819,12 +31805,12 @@ "integrity": "sha512-wa7YjyUGfNZngI/vtK0UHAN+lgDCxBPCylVXGp0zu59Fz5aiGtNXaq3DhIov063MorB+VfufLh3JlF2KdTK3xg==" }, "v8-to-istanbul": { - "version": "9.0.0", - "resolved": "https://registry.npmjs.org/v8-to-istanbul/-/v8-to-istanbul-9.0.0.tgz", - "integrity": "sha512-HcvgY/xaRm7isYmyx+lFKA4uQmfUbN0J4M0nNItvzTvH/iQ9kW5j/t4YSR+Ge323/lrgDAWJoF46tzGQHwBHFw==", + "version": "9.0.1", + "resolved": "https://registry.npmjs.org/v8-to-istanbul/-/v8-to-istanbul-9.0.1.tgz", + "integrity": "sha512-74Y4LqY74kLE6IFyIjPtkSTWzUZmj8tdHT9Ii/26dvQ6K9Dl2NbEfj0XgU2sHCtKgt5VupqhlO/5aWuqS+IY1w==", "dev": true, "requires": { - "@jridgewell/trace-mapping": "^0.3.7", + "@jridgewell/trace-mapping": "^0.3.12", "@types/istanbul-lib-coverage": "^2.0.1", "convert-source-map": "^1.6.0" } diff --git a/package.json b/package.json index 656e0bc14e..1342d17658 100644 --- a/package.json +++ b/package.json @@ -20,14 +20,14 @@ "url": "https://github.com/feathersjs/feathers/issues" }, "engines": { - "node": ">= 12" + "node": ">= 14" }, "scripts": { "install": "lerna bootstrap", "publish": "lerna publish && git commit -am \"chore: Update changelog\" && git push origin", "publish:premajor": "lerna publish premajor --preid pre --pre-dist-tag pre && git commit -am \"chore: Update version and changelog\" && git push origin", "publish:prerelease": "lerna publish prerelease --preid pre --pre-dist-tag pre --dist-tag pre --force-publish && git commit -am \"chore: Update version and changelog\" && git push origin", - "prettier": "npx prettier \"packages/{,!(node_modules)/**/(src|test|generators)/**/}*.ts\" --write", + "prettier": "npx prettier \"packages/{,!(node_modules)/**/(src|test)/**/}*.ts\" --write", "eslint": "eslint \"packages/**/*.ts\" --fix", "lint": "npm run prettier && npm run eslint", "update-dependencies": "ncu -u && lerna exec -- ncu -u -x node-fetch", diff --git a/packages/cli/package.json b/packages/cli/package.json index 6672ea7b02..f7aa9c7c9d 100644 --- a/packages/cli/package.json +++ b/packages/cli/package.json @@ -54,7 +54,7 @@ "access": "public" }, "dependencies": { - "@feathershq/pinion": "^0.3.1", + "@feathershq/pinion": "^0.3.2", "chalk": "^4.0.1", "lodash": "^4.17.21", "prettier": "^2.7.1" From 26411e8dbfbd98ed566c144c568c4ee1dd53543a Mon Sep 17 00:00:00 2001 From: daffl Date: Mon, 20 Jun 2022 21:38:23 -0700 Subject: [PATCH 6/6] Update dependencies --- package-lock.json | 16 ++++++++-------- packages/cli/package.json | 2 +- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/package-lock.json b/package-lock.json index 110f211f21..10417aebd6 100644 --- a/package-lock.json +++ b/package-lock.json @@ -9,7 +9,7 @@ "dependencies": { "@babel/core": "^7.18.2", "@babel/preset-env": "^7.18.2", - "@feathershq/pinion": "^0.3.2", + "@feathershq/pinion": "^0.3.3", "@feathersjs/hooks": "^0.7.5", "@types/axios": "^0.14.0", "@types/bcryptjs": "^2.4.2", @@ -89,7 +89,7 @@ "typescript": "^4.7.3" }, "engines": { - "node": ">= 12" + "node": ">= 14" }, "funding": { "type": "github", @@ -1773,9 +1773,9 @@ "dev": true }, "node_modules/@feathershq/pinion": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/@feathershq/pinion/-/pinion-0.3.2.tgz", - "integrity": "sha512-shM4tplTR+kque5JAHN6P/fQzLjmGy6XjhBXOVeYcVkfIDHVd/5E4jggGABnjUNF45aTE+m6HclaN7a8KOXUOg==", + "version": "0.3.3", + "resolved": "https://registry.npmjs.org/@feathershq/pinion/-/pinion-0.3.3.tgz", + "integrity": "sha512-JXe55z59oc4uRT8XkYMlWYoj9ZKL39N5aIIHGnwSAVQbgQgatvTZpaPzZ0cgziN6XTl/QhJO4FRed+bPTInnvA==", "dependencies": { "@types/inquirer": "^8.2.0", "@types/yargs": "^17.0.8", @@ -19329,9 +19329,9 @@ } }, "@feathershq/pinion": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/@feathershq/pinion/-/pinion-0.3.2.tgz", - "integrity": "sha512-shM4tplTR+kque5JAHN6P/fQzLjmGy6XjhBXOVeYcVkfIDHVd/5E4jggGABnjUNF45aTE+m6HclaN7a8KOXUOg==", + "version": "0.3.3", + "resolved": "https://registry.npmjs.org/@feathershq/pinion/-/pinion-0.3.3.tgz", + "integrity": "sha512-JXe55z59oc4uRT8XkYMlWYoj9ZKL39N5aIIHGnwSAVQbgQgatvTZpaPzZ0cgziN6XTl/QhJO4FRed+bPTInnvA==", "requires": { "@types/inquirer": "^8.2.0", "@types/yargs": "^17.0.8", diff --git a/packages/cli/package.json b/packages/cli/package.json index f7aa9c7c9d..4844246665 100644 --- a/packages/cli/package.json +++ b/packages/cli/package.json @@ -54,7 +54,7 @@ "access": "public" }, "dependencies": { - "@feathershq/pinion": "^0.3.2", + "@feathershq/pinion": "^0.3.3", "chalk": "^4.0.1", "lodash": "^4.17.21", "prettier": "^2.7.1"