fix(generators): Move generators and CLI to featherscloud/pinion (#3386)

This commit is contained in:
David Luecke 2024-01-22 08:56:39 -08:00 committed by GitHub
parent 59fb40b9eb
commit eb87c9922d
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
58 changed files with 4179 additions and 5966 deletions

View File

@ -1,5 +1,5 @@
import type { Callable, PinionContext } from '@feathershq/pinion' import type { Callable, PinionContext } from '@featherscloud/pinion'
import { generator, install, prompt, runGenerators, toFile } from '@feathershq/pinion' import { generator, install, prompt, runGenerators, toFile } from '@featherscloud/pinion'
export interface ModuleContext extends PinionContext { export interface ModuleContext extends PinionContext {
name: string name: string

View File

@ -1,4 +1,4 @@
import { generator, renderTemplate, toFile } from '@feathershq/pinion' import { generator, renderTemplate, toFile } from '@featherscloud/pinion'
import { ModuleContext } from '../package' import { ModuleContext } from '../package'
interface Context extends ModuleContext {} interface Context extends ModuleContext {}

View File

@ -1,4 +1,4 @@
import { generator, renderTemplate, toFile } from '@feathershq/pinion' import { generator, renderTemplate, toFile } from '@featherscloud/pinion'
import { ModuleContext } from '../package' import { ModuleContext } from '../package'
interface Context extends ModuleContext {} interface Context extends ModuleContext {}

View File

@ -1,4 +1,4 @@
import { generator, toFile, writeJSON } from '@feathershq/pinion' import { generator, toFile, writeJSON } from '@featherscloud/pinion'
import { ModuleContext } from '../package' import { ModuleContext } from '../package'
interface Context extends ModuleContext {} interface Context extends ModuleContext {}

View File

@ -1,4 +1,4 @@
import { generator, renderTemplate, toFile } from '@feathershq/pinion' import { generator, renderTemplate, toFile } from '@featherscloud/pinion'
import { ModuleContext } from '../package' import { ModuleContext } from '../package'
const template = ({ description, moduleName }: ModuleContext) => `# ${moduleName} const template = ({ description, moduleName }: ModuleContext) => `# ${moduleName}

View File

@ -1,4 +1,4 @@
import { generator, renderTemplate, toFile } from '@feathershq/pinion' import { generator, renderTemplate, toFile } from '@featherscloud/pinion'
import { ModuleContext } from '../package' import { ModuleContext } from '../package'
interface Context extends ModuleContext {} interface Context extends ModuleContext {}

View File

@ -1,4 +1,4 @@
import { generator, toFile, writeJSON } from '@feathershq/pinion' import { generator, toFile, writeJSON } from '@featherscloud/pinion'
import { ModuleContext } from '../package' import { ModuleContext } from '../package'
export const generate = (context: ModuleContext) => export const generate = (context: ModuleContext) =>

9435
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@ -38,14 +38,14 @@
"lint": "npm run prettier && npm run eslint", "lint": "npm run prettier && npm run eslint",
"compile": "lerna run compile", "compile": "lerna run compile",
"build:docs": "npm run build --workspace docs", "build:docs": "npm run build --workspace docs",
"update-dependencies": "ncu -u && npm exec --workspaces -- ncu -u --dep prod,dev,optional,peer -x node-fetch,chalk,\"@sinclair/typebox\"", "update-dependencies": "ncu -u && npm exec --workspaces -- ncu -u --dep prod,dev,optional,peer -x node-fetch,\"@sinclair/typebox\"",
"clean": "find . -name node_modules -exec rm -rf '{}' + && find . -name package-lock.json -exec rm -rf '{}' +", "clean": "find . -name node_modules -exec rm -rf '{}' + && find . -name package-lock.json -exec rm -rf '{}' +",
"test:deno": "deno test --config deno/tsconfig.json deno/test.ts", "test:deno": "deno test --config deno/tsconfig.json deno/test.ts",
"test": "npm run lint && npm run compile && c8 lerna run test --ignore @feathersjs/tests", "test": "npm run lint && npm run compile && c8 lerna run test --ignore @feathersjs/tests",
"generate:package": "pinion run generators/package.ts" "generate:package": "pinion run generators/package.ts"
}, },
"devDependencies": { "devDependencies": {
"@feathershq/pinion": "^0.4.0-pre.3", "@featherscloud/pinion": "^0.5.0",
"@typescript-eslint/eslint-plugin": "^6.19.0", "@typescript-eslint/eslint-plugin": "^6.19.0",
"@typescript-eslint/parser": "^6.19.0", "@typescript-eslint/parser": "^6.19.0",
"c8": "^9.1.0", "c8": "^9.1.0",

View File

@ -1,6 +1,6 @@
#!/usr/bin/env node #!/usr/bin/env node
'use strict' 'use strict'
const { program } = require('../lib') import { program } from '../lib/index.js'
program.parse() program.parse()

View File

@ -3,7 +3,8 @@
"description": "The command line interface for creating Feathers applications", "description": "The command line interface for creating Feathers applications",
"version": "5.0.14", "version": "5.0.14",
"homepage": "https://feathersjs.com", "homepage": "https://feathersjs.com",
"main": "lib/", "main": "lib/index.js",
"type": "module",
"bin": { "bin": {
"feathers": "./bin/feathers" "feathers": "./bin/feathers"
}, },
@ -45,7 +46,7 @@
"scripts": { "scripts": {
"prepublish": "npm run compile", "prepublish": "npm run compile",
"compile": "shx rm -rf lib/ && tsc", "compile": "shx rm -rf lib/ && tsc",
"mocha": "mocha --timeout 60000 --config ../../.mocharc.json --recursive test/**.test.ts test/**/*.test.ts", "mocha": "mocha --timeout 60000 --config ../../.mocharc.json --require tsx --recursive test/**.test.ts test/**/*.test.ts",
"test": "npm run compile && npm run mocha" "test": "npm run compile && npm run mocha"
}, },
"publishConfig": { "publishConfig": {
@ -53,7 +54,7 @@
}, },
"dependencies": { "dependencies": {
"@feathersjs/generators": "^5.0.14", "@feathersjs/generators": "^5.0.14",
"chalk": "^4.0.1", "chalk": "^5.3.0",
"commander": "^11.1.0" "commander": "^11.1.0"
}, },
"devDependencies": { "devDependencies": {

View File

@ -1,7 +1,7 @@
import chalk from 'chalk' import chalk from 'chalk'
import { Command } from 'commander' import { Command } from 'commander'
import { dirname } from 'path' import { dirname } from 'path'
import { generator, runGenerator, getContext, FeathersBaseContext, version } from '@feathersjs/generators' import { runGenerator, getContext, FeathersBaseContext, version } from '@feathersjs/generators'
export * from 'commander' export * from 'commander'
export { chalk } export { chalk }
@ -12,7 +12,7 @@ export const commandRunner = (name: string) => async (options: any) => {
...options ...options
}) })
await generator(ctx) await Promise.resolve(ctx)
.then(runGenerator(folder, name, 'index')) .then(runGenerator(folder, name, 'index'))
.catch((error) => { .catch((error) => {
const { logger } = ctx.pinion const { logger } = ctx.pinion

View File

@ -5,6 +5,7 @@
], ],
"compilerOptions": { "compilerOptions": {
"outDir": "lib", "outDir": "lib",
"resolveJsonModule": true "module": "ESNext",
"moduleResolution": "Node"
} }
} }

View File

@ -29,8 +29,9 @@
"engines": { "engines": {
"node": ">= 16" "node": ">= 16"
}, },
"main": "lib/", "main": "lib/index.js",
"types": "lib/", "types": "lib/",
"type": "module",
"files": [ "files": [
"CHANGELOG.md", "CHANGELOG.md",
"LICENSE", "LICENSE",
@ -43,7 +44,7 @@
"scripts": { "scripts": {
"prepublish": "npm run compile", "prepublish": "npm run compile",
"compile": "shx rm -rf lib/ && tsc && shx cp -r src/. lib/", "compile": "shx rm -rf lib/ && tsc && shx cp -r src/. lib/",
"test": "npm run compile && mocha --config ../../.mocharc.json --recursive test/**.test.ts test/**/*.test.ts" "test": "npm run compile && mocha --config ../../.mocharc.json --require tsx --recursive test/**.test.ts test/**/*.test.ts"
}, },
"directories": { "directories": {
"lib": "lib" "lib": "lib"
@ -52,8 +53,8 @@
"access": "public" "access": "public"
}, },
"dependencies": { "dependencies": {
"@feathershq/pinion": "^0.3.5", "@featherscloud/pinion": "^0.5.0",
"chalk": "^4.0.1", "chalk": "^5.3.0",
"lodash": "^4.17.21", "lodash": "^4.17.21",
"prettier": "^3.2.4", "prettier": "^3.2.4",
"typescript": "^5.3.3" "typescript": "^5.3.3"
@ -88,7 +89,7 @@
"pg": "^8.11.3", "pg": "^8.11.3",
"shx": "^0.3.4", "shx": "^0.3.4",
"sqlite3": "^5.1.7", "sqlite3": "^5.1.7",
"ts-node": "^10.9.2", "tsx": "^4.7.0",
"type-fest": "^4.9.0", "type-fest": "^4.9.0",
"typescript": "^5.3.3" "typescript": "^5.3.3"
}, },

View File

@ -1,8 +1,17 @@
import { sep } from 'path' import { sep, dirname } from 'path'
import chalk from 'chalk' import chalk from 'chalk'
import { generator, prompt, runGenerators, fromFile, install, copyFiles, toFile } from '@feathershq/pinion' import { prompt, runGenerators, fromFile, copyFiles, toFile } from '@featherscloud/pinion'
import { FeathersBaseContext, FeathersAppInfo, initializeBaseContext, addVersions } from '../commons' import {
import { generate as connectionGenerator, prompts as connectionPrompts } from '../connection' FeathersBaseContext,
FeathersAppInfo,
initializeBaseContext,
addVersions,
install
} from '../commons.js'
import { generate as connectionGenerator, prompts as connectionPrompts } from '../connection/index.js'
// Set __dirname in es module
const __dirname = dirname(new URL(import.meta.url).pathname)
export interface AppGeneratorData extends FeathersAppInfo { export interface AppGeneratorData extends FeathersAppInfo {
/** /**
@ -36,7 +45,7 @@ export type AppGeneratorContext = FeathersBaseContext &
export type AppGeneratorArguments = FeathersBaseContext & Partial<AppGeneratorData> export type AppGeneratorArguments = FeathersBaseContext & Partial<AppGeneratorData>
export const generate = (ctx: AppGeneratorArguments) => export const generate = (ctx: AppGeneratorArguments) =>
generator(ctx) Promise.resolve(ctx)
.then(initializeBaseContext()) .then(initializeBaseContext())
.then((ctx) => ({ .then((ctx) => ({
...ctx, ...ctx,
@ -44,7 +53,7 @@ export const generate = (ctx: AppGeneratorArguments) =>
devDependencies: [] devDependencies: []
})) }))
.then( .then(
prompt<AppGeneratorArguments, AppGeneratorContext>((ctx) => [ prompt((ctx) => [
{ {
name: 'language', name: 'language',
type: 'list', type: 'list',
@ -142,7 +151,7 @@ export const generate = (ctx: AppGeneratorArguments) =>
} }
}) })
.then( .then(
install<AppGeneratorContext>( install(
({ transports, framework, dependencyVersions, dependencies, schema }) => { ({ transports, framework, dependencyVersions, dependencies, schema }) => {
const hasSocketio = transports.includes('websockets') const hasSocketio = transports.includes('websockets')
@ -181,7 +190,7 @@ export const generate = (ctx: AppGeneratorArguments) =>
) )
) )
.then( .then(
install<AppGeneratorContext>( install(
({ language, devDependencies, dependencyVersions }) => { ({ language, devDependencies, dependencyVersions }) => {
devDependencies.push( devDependencies.push(
'nodemon', 'nodemon',

View File

@ -1,6 +1,6 @@
import { generator, toFile } from '@feathershq/pinion' import { toFile } from '@featherscloud/pinion'
import { renderSource } from '../../commons' import { renderSource } from '../../commons.js'
import { AppGeneratorContext } from '../index' import { AppGeneratorContext } from '../index.js'
const template = ({ const template = ({
lib lib
@ -47,4 +47,4 @@ describe('Feathers application tests', () => {
` `
export const generate = (ctx: AppGeneratorContext) => export const generate = (ctx: AppGeneratorContext) =>
generator(ctx).then(renderSource(template, toFile('test', 'app.test'))) Promise.resolve(ctx).then(renderSource(template, toFile('test', 'app.test')))

View File

@ -1,6 +1,6 @@
import { generator, toFile } from '@feathershq/pinion' import { toFile } from '@featherscloud/pinion'
import { renderSource } from '../../commons' import { renderSource } from '../../commons.js'
import { AppGeneratorContext } from '../index' import { AppGeneratorContext } from '../index.js'
const tsKoaApp = ({ const tsKoaApp = ({
transports, transports,
@ -133,7 +133,7 @@ const template = (ctx: AppGeneratorContext) =>
ctx.framework === 'express' ? tsExpressApp(ctx) : tsKoaApp(ctx) ctx.framework === 'express' ? tsExpressApp(ctx) : tsKoaApp(ctx)
export const generate = (ctx: AppGeneratorContext) => export const generate = (ctx: AppGeneratorContext) =>
generator(ctx).then( Promise.resolve(ctx).then(
renderSource( renderSource(
template, template,
toFile<AppGeneratorContext>(({ lib }) => lib, 'app') toFile<AppGeneratorContext>(({ lib }) => lib, 'app')

View File

@ -1,6 +1,6 @@
import { generator, toFile, when } from '@feathershq/pinion' import { toFile, when } from '@featherscloud/pinion'
import { renderSource } from '../../commons' import { renderSource } from '../../commons.js'
import { AppGeneratorContext } from '../index' import { AppGeneratorContext } from '../index.js'
const template = ({ const template = ({
language language
@ -43,7 +43,7 @@ export const channels = (app: Application) => {
` `
export const generate = (ctx: AppGeneratorContext) => export const generate = (ctx: AppGeneratorContext) =>
generator(ctx).then( Promise.resolve(ctx).then(
when<AppGeneratorContext>( when<AppGeneratorContext>(
({ transports }) => transports.includes('websockets'), ({ transports }) => transports.includes('websockets'),
renderSource( renderSource(

View File

@ -1,6 +1,6 @@
import { generator, toFile, when } from '@feathershq/pinion' import { toFile, when } from '@featherscloud/pinion'
import { renderSource } from '../../commons' import { renderSource } from '../../commons.js'
import { AppGeneratorContext } from '../index' import { AppGeneratorContext } from '../index.js'
const template = ({ lib }: AppGeneratorContext) => /* ts */ `import assert from 'assert' const template = ({ lib }: AppGeneratorContext) => /* ts */ `import assert from 'assert'
import axios from 'axios' import axios from 'axios'
@ -23,6 +23,6 @@ describe('client tests', () => {
` `
export const generate = (ctx: AppGeneratorContext) => export const generate = (ctx: AppGeneratorContext) =>
generator(ctx).then( Promise.resolve(ctx).then(
when<AppGeneratorContext>((ctx) => ctx.client, renderSource(template, toFile('test', 'client.test'))) when<AppGeneratorContext>((ctx) => ctx.client, renderSource(template, toFile('test', 'client.test')))
) )

View File

@ -1,6 +1,6 @@
import { generator, toFile, when } from '@feathershq/pinion' import { toFile, when } from '@featherscloud/pinion'
import { renderSource } from '../../commons' import { renderSource } from '../../commons.js'
import { AppGeneratorContext } from '../index' import { AppGeneratorContext } from '../index.js'
const template = ({ const template = ({
name, name,
@ -42,7 +42,7 @@ export const createClient = <Configuration = any> (
` `
export const generate = async (ctx: AppGeneratorContext) => export const generate = async (ctx: AppGeneratorContext) =>
generator(ctx).then( Promise.resolve(ctx).then(
when<AppGeneratorContext>( when<AppGeneratorContext>(
(ctx) => ctx.client, (ctx) => ctx.client,
renderSource( renderSource(

View File

@ -1,6 +1,6 @@
import { generator, toFile, when, writeJSON } from '@feathershq/pinion' import { toFile, when, writeJSON } from '@featherscloud/pinion'
import { renderSource } from '../../commons' import { renderSource } from '../../commons.js'
import { AppGeneratorContext } from '../index' import { AppGeneratorContext } from '../index.js'
const defaultConfig = ({}: AppGeneratorContext) => ({ const defaultConfig = ({}: AppGeneratorContext) => ({
host: 'localhost', host: 'localhost',
@ -73,7 +73,7 @@ export const configurationValidator = getValidator(configurationSchema, dataVali
` `
export const generate = (ctx: AppGeneratorContext) => export const generate = (ctx: AppGeneratorContext) =>
generator(ctx) Promise.resolve(ctx)
.then(writeJSON(defaultConfig, toFile('config', 'default.json'))) .then(writeJSON(defaultConfig, toFile('config', 'default.json')))
.then(writeJSON(testConfig, toFile('config', 'test.json'))) .then(writeJSON(testConfig, toFile('config', 'test.json')))
.then(writeJSON(customEnvironment, toFile('config', 'custom-environment-variables.json'))) .then(writeJSON(customEnvironment, toFile('config', 'custom-environment-variables.json')))

View File

@ -1,5 +1,5 @@
import { generator, toFile, when, renderTemplate } from '@feathershq/pinion' import { toFile, when, renderTemplate } from '@featherscloud/pinion'
import { AppGeneratorContext } from '../index' import { AppGeneratorContext } from '../index.js'
const template = ({ const template = ({
framework, framework,
@ -31,7 +31,7 @@ export type HookContext<S = any> = FeathersHookContext<Application, S>
` `
export const generate = (ctx: AppGeneratorContext) => export const generate = (ctx: AppGeneratorContext) =>
generator(ctx).then( Promise.resolve(ctx).then(
when<AppGeneratorContext>( when<AppGeneratorContext>(
({ language }) => language === 'ts', ({ language }) => language === 'ts',
renderTemplate( renderTemplate(

View File

@ -1,5 +1,5 @@
import { generator, renderTemplate, toFile } from '@feathershq/pinion' import { renderTemplate, toFile } from '@featherscloud/pinion'
import { AppGeneratorContext } from '../index' import { AppGeneratorContext } from '../index.js'
const template = ({ name, description }: AppGeneratorContext) => /* html */ `<!DOCTYPE html> const template = ({ name, description }: AppGeneratorContext) => /* html */ `<!DOCTYPE html>
<html lang="en"> <html lang="en">
@ -41,4 +41,4 @@ const template = ({ name, description }: AppGeneratorContext) => /* html */ `<!D
` `
export const generate = (ctx: AppGeneratorContext) => export const generate = (ctx: AppGeneratorContext) =>
generator(ctx).then(renderTemplate(template, toFile('public', 'index.html'))) Promise.resolve(ctx).then(renderTemplate(template, toFile('public', 'index.html')))

View File

@ -1,6 +1,6 @@
import { generator, toFile } from '@feathershq/pinion' import { toFile } from '@featherscloud/pinion'
import { renderSource } from '../../commons' import { renderSource } from '../../commons.js'
import { AppGeneratorContext } from '../index' import { AppGeneratorContext } from '../index.js'
const template = ({}: AppGeneratorContext) => /* ts */ `import { app } from './app' const template = ({}: AppGeneratorContext) => /* ts */ `import { app } from './app'
import { logger } from './logger' import { logger } from './logger'
@ -18,7 +18,7 @@ app.listen(port).then(() => {
` `
export const generate = (ctx: AppGeneratorContext) => export const generate = (ctx: AppGeneratorContext) =>
generator(ctx).then( Promise.resolve(ctx).then(
renderSource( renderSource(
template, template,
toFile<AppGeneratorContext>(({ lib }) => lib, 'index') toFile<AppGeneratorContext>(({ lib }) => lib, 'index')

View File

@ -1,6 +1,6 @@
import { generator, toFile } from '@feathershq/pinion' import { toFile } from '@featherscloud/pinion'
import { renderSource } from '../../commons' import { renderSource } from '../../commons.js'
import { AppGeneratorContext } from '../index' import { AppGeneratorContext } from '../index.js'
const template = const template =
({}: AppGeneratorContext) => /* ts */ `// For more information about this file see https://dove.feathersjs.com/guides/cli/logging.html ({}: AppGeneratorContext) => /* ts */ `// For more information about this file see https://dove.feathersjs.com/guides/cli/logging.html
@ -41,7 +41,7 @@ export const logError = async (context: HookContext, next: NextFunction) => {
` `
export const generate = (ctx: AppGeneratorContext) => export const generate = (ctx: AppGeneratorContext) =>
generator(ctx) Promise.resolve(ctx)
.then( .then(
renderSource( renderSource(
template, template,

View File

@ -1,5 +1,5 @@
import { generator, toFile, writeJSON } from '@feathershq/pinion' import { toFile, writeJSON } from '@featherscloud/pinion'
import { AppGeneratorContext } from '../index' import { AppGeneratorContext } from '../index.js'
const jsPackageJson = (lib: string) => ({ const jsPackageJson = (lib: string) => ({
type: 'module', type: 'module',
@ -75,4 +75,4 @@ const packageJson = ({
}) })
export const generate = (ctx: AppGeneratorContext) => export const generate = (ctx: AppGeneratorContext) =>
generator(ctx).then(writeJSON(packageJson, toFile('package.json'))) Promise.resolve(ctx).then(writeJSON(packageJson, toFile('package.json')))

View File

@ -1,9 +1,9 @@
import { generator, toFile, writeJSON } from '@feathershq/pinion' import { toFile, writeJSON } from '@featherscloud/pinion'
import { AppGeneratorContext } from '../index' import { AppGeneratorContext } from '../index.js'
import { PRETTIERRC } from '../../commons' import { PRETTIERRC } from '../../commons.js'
export const generate = (ctx: AppGeneratorContext) => export const generate = (ctx: AppGeneratorContext) =>
generator(ctx).then( Promise.resolve(ctx).then(
writeJSON<AppGeneratorContext>( writeJSON<AppGeneratorContext>(
(ctx) => ({ (ctx) => ({
...PRETTIERRC, ...PRETTIERRC,

View File

@ -1,5 +1,5 @@
import { generator, renderTemplate, toFile } from '@feathershq/pinion' import { renderTemplate, toFile } from '@featherscloud/pinion'
import { AppGeneratorContext } from '../index' import { AppGeneratorContext } from '../index.js'
const template = ({ name, description, language, database }: AppGeneratorContext) => /* md */ `# ${name} const template = ({ name, description, language, database }: AppGeneratorContext) => /* md */ `# ${name}
@ -54,4 +54,4 @@ For more information on all the things you can do with Feathers visit [docs.feat
` `
export const generate = (ctx: AppGeneratorContext) => export const generate = (ctx: AppGeneratorContext) =>
generator(ctx).then(renderTemplate(template, toFile('readme.md'))) Promise.resolve(ctx).then(renderTemplate(template, toFile('readme.md')))

View File

@ -1,6 +1,6 @@
import { generator, toFile } from '@feathershq/pinion' import { toFile } from '@featherscloud/pinion'
import { renderSource } from '../../commons' import { renderSource } from '../../commons.js'
import { AppGeneratorContext } from '../index' import { AppGeneratorContext } from '../index.js'
const template = const template =
({}: AppGeneratorContext) => /* ts */ `// For more information about this file see https://dove.feathersjs.com/guides/cli/application.html#configure-functions ({}: AppGeneratorContext) => /* ts */ `// For more information about this file see https://dove.feathersjs.com/guides/cli/application.html#configure-functions
@ -12,7 +12,7 @@ export const services = (app: Application) => {
` `
export const generate = (ctx: AppGeneratorContext) => export const generate = (ctx: AppGeneratorContext) =>
generator(ctx).then( Promise.resolve(ctx).then(
renderSource( renderSource(
template, template,
toFile<AppGeneratorContext>(({ lib }) => lib, 'services', 'index') toFile<AppGeneratorContext>(({ lib }) => lib, 'services', 'index')

View File

@ -1,8 +1,8 @@
import { generator, toFile, when, writeJSON } from '@feathershq/pinion' import { toFile, when, writeJSON } from '@featherscloud/pinion'
import { AppGeneratorContext } from '../index' import { AppGeneratorContext } from '../index.js'
export const generate = (ctx: AppGeneratorContext) => export const generate = (ctx: AppGeneratorContext) =>
generator(ctx).then( Promise.resolve(ctx).then(
when<AppGeneratorContext>( when<AppGeneratorContext>(
(ctx) => ctx.language === 'ts', (ctx) => ctx.language === 'ts',
writeJSON<AppGeneratorContext>( writeJSON<AppGeneratorContext>(

View File

@ -1,6 +1,6 @@
import { generator, toFile } from '@feathershq/pinion' import { toFile } from '@featherscloud/pinion'
import { renderSource } from '../../commons' import { renderSource } from '../../commons.js'
import { AppGeneratorContext } from '../index' import { AppGeneratorContext } from '../index.js'
const validatorTemplate = /* ts */ `// For more information about this file see https://dove.feathersjs.com/guides/cli/validators.html const validatorTemplate = /* ts */ `// For more information about this file see https://dove.feathersjs.com/guides/cli/validators.html
import { Ajv, addFormats } from '@feathersjs/schema' import { Ajv, addFormats } from '@feathersjs/schema'
@ -31,7 +31,7 @@ export const queryValidator: Ajv = addFormats(new Ajv({
` `
export const generate = (ctx: AppGeneratorContext) => export const generate = (ctx: AppGeneratorContext) =>
generator(ctx).then( Promise.resolve(ctx).then(
renderSource( renderSource(
validatorTemplate, validatorTemplate,
toFile<AppGeneratorContext>(({ lib }) => lib, 'validators') toFile<AppGeneratorContext>(({ lib }) => lib, 'validators')

View File

@ -1,7 +1,17 @@
import chalk from 'chalk' import chalk from 'chalk'
import { generator, runGenerators, prompt, install } from '@feathershq/pinion' import { dirname } from 'path'
import { addVersions, checkPreconditions, FeathersBaseContext, initializeBaseContext } from '../commons' import { runGenerators, prompt } from '@featherscloud/pinion'
import { generate as serviceGenerator, ServiceGeneratorContext } from '../service/index' import {
addVersions,
checkPreconditions,
FeathersBaseContext,
initializeBaseContext,
install
} from '../commons.js'
import { generate as serviceGenerator, ServiceGeneratorContext } from '../service/index.js'
// Set __dirname in es module
const __dirname = dirname(new URL(import.meta.url).pathname)
export interface AuthenticationGeneratorContext extends ServiceGeneratorContext { export interface AuthenticationGeneratorContext extends ServiceGeneratorContext {
service: string service: string
@ -14,62 +24,60 @@ export type AuthenticationGeneratorArguments = FeathersBaseContext &
Partial<Pick<AuthenticationGeneratorContext, 'service' | 'authStrategies' | 'path' | 'schema' | 'type'>> Partial<Pick<AuthenticationGeneratorContext, 'service' | 'authStrategies' | 'path' | 'schema' | 'type'>>
export const generate = (ctx: AuthenticationGeneratorArguments) => export const generate = (ctx: AuthenticationGeneratorArguments) =>
generator(ctx) Promise.resolve(ctx)
.then(initializeBaseContext()) .then(initializeBaseContext())
.then(checkPreconditions()) .then(checkPreconditions())
.then( .then(
prompt<AuthenticationGeneratorArguments, AuthenticationGeneratorContext>( prompt((ctx: AuthenticationGeneratorArguments) => [
(ctx: AuthenticationGeneratorArguments) => [ {
{ type: 'checkbox',
type: 'checkbox', name: 'authStrategies',
name: 'authStrategies', when: !ctx.authStrategies,
when: !ctx.authStrategies, message: 'Which authentication methods do you want to use?',
message: 'Which authentication methods do you want to use?', suffix: chalk.grey(' Other methods and providers can be added at any time.'),
suffix: chalk.grey(' Other methods and providers can be added at any time.'), choices: [
choices: [ {
{ name: 'Email + Password',
name: 'Email + Password', value: 'local',
value: 'local', checked: true
checked: true },
}, {
{ name: 'Google',
name: 'Google', value: 'google'
value: 'google' },
}, {
{ name: 'Facebook',
name: 'Facebook', value: 'facebook'
value: 'facebook' },
}, {
{ name: 'Twitter',
name: 'Twitter', value: 'twitter'
value: 'twitter' },
}, {
{ name: 'GitHub',
name: 'GitHub', value: 'github'
value: 'github' },
}, {
{ name: 'Auth0',
name: 'Auth0', value: 'auth0'
value: 'auth0' }
} ]
] },
}, {
{ name: 'service',
name: 'service', type: 'input',
type: 'input', when: !ctx.service,
when: !ctx.service, message: 'What is your authentication service name?',
message: 'What is your authentication service name?', default: 'user'
default: 'user' },
}, {
{ name: 'path',
name: 'path', type: 'input',
type: 'input', when: !ctx.path,
when: !ctx.path, message: 'What path should the service be registered on?',
message: 'What path should the service be registered on?', default: 'users'
default: 'users' }
} ])
]
)
) )
.then(async (ctx) => { .then(async (ctx) => {
const serviceContext = await serviceGenerator({ const serviceContext = await serviceGenerator({
@ -85,6 +93,7 @@ export const generate = (ctx: AuthenticationGeneratorArguments) =>
} }
}) })
.then(runGenerators(__dirname, 'templates')) .then(runGenerators(__dirname, 'templates'))
.then((ctx) => ctx as AuthenticationGeneratorContext)
.then((ctx) => { .then((ctx) => {
const dependencies: string[] = [] const dependencies: string[] = []

View File

@ -1,7 +1,7 @@
import { generator, before, toFile } from '@feathershq/pinion' import { before, toFile } from '@featherscloud/pinion'
import { injectSource, renderSource } from '../../commons' import { injectSource, renderSource } from '../../commons.js'
import { AuthenticationGeneratorContext } from '../index' import { AuthenticationGeneratorContext } from '../index.js'
import { localTemplate, oauthTemplate } from '../../commons' import { localTemplate, oauthTemplate } from '../../commons.js'
const template = ({ const template = ({
authStrategies authStrategies
@ -41,7 +41,7 @@ const configureTemplate = 'app.configure(authentication)'
const toAppFile = toFile<AuthenticationGeneratorContext>(({ lib }) => [lib, 'app']) const toAppFile = toFile<AuthenticationGeneratorContext>(({ lib }) => [lib, 'app'])
export const generate = (ctx: AuthenticationGeneratorContext) => export const generate = (ctx: AuthenticationGeneratorContext) =>
generator(ctx) Promise.resolve(ctx)
.then( .then(
renderSource( renderSource(
template, template,

View File

@ -1,7 +1,7 @@
import { generator, toFile, when } from '@feathershq/pinion' import { toFile, when } from '@featherscloud/pinion'
import { fileExists, renderSource } from '../../commons' import { fileExists, renderSource } from '../../commons.js'
import { AuthenticationGeneratorContext } from '../index' import { AuthenticationGeneratorContext } from '../index.js'
import { localTemplate } from '../../commons' import { localTemplate } from '../../commons.js'
const template = ({ const template = ({
authStrategies, authStrategies,
@ -66,7 +66,7 @@ describe('application client tests', () => {
` `
export const generate = (ctx: AuthenticationGeneratorContext) => export const generate = (ctx: AuthenticationGeneratorContext) =>
generator(ctx).then( Promise.resolve(ctx).then(
when<AuthenticationGeneratorContext>( when<AuthenticationGeneratorContext>(
({ lib, language }) => fileExists(lib, `client.${language}`), ({ lib, language }) => fileExists(lib, `client.${language}`),
renderSource( renderSource(

View File

@ -1,9 +1,9 @@
import crypto from 'crypto' import crypto from 'crypto'
import { generator, toFile, mergeJSON } from '@feathershq/pinion' import { toFile, mergeJSON } from '@featherscloud/pinion'
import { AuthenticationGeneratorContext } from '../index' import { AuthenticationGeneratorContext } from '../index.js'
export const generate = (ctx: AuthenticationGeneratorContext) => export const generate = (ctx: AuthenticationGeneratorContext) =>
generator(ctx) Promise.resolve(ctx)
.then( .then(
mergeJSON<AuthenticationGeneratorContext>( mergeJSON<AuthenticationGeneratorContext>(
({ authStrategies }) => { ({ authStrategies }) => {

View File

@ -1,5 +1,5 @@
import { generator, inject, before, toFile, when, append } from '@feathershq/pinion' import { inject, before, toFile, when, append } from '@featherscloud/pinion'
import { AuthenticationGeneratorContext } from '../index' import { AuthenticationGeneratorContext } from '../index.js'
const importTemplate = ({ const importTemplate = ({
upperName, upperName,
@ -24,7 +24,7 @@ declare module '@feathersjs/feathers' {
const toDeclarationFile = toFile<AuthenticationGeneratorContext>(({ lib }) => lib, 'declarations.ts') const toDeclarationFile = toFile<AuthenticationGeneratorContext>(({ lib }) => lib, 'declarations.ts')
export const generate = (ctx: AuthenticationGeneratorContext) => export const generate = (ctx: AuthenticationGeneratorContext) =>
generator(ctx) Promise.resolve(ctx)
.then( .then(
when( when(
(ctx) => ctx.language === 'ts', (ctx) => ctx.language === 'ts',

View File

@ -1,5 +1,5 @@
import fs from 'fs' import fs from 'fs'
import { join } from 'path' import { join, dirname } from 'path'
import { PackageJson } from 'type-fest' import { PackageJson } from 'type-fest'
import { readFile, writeFile } from 'fs/promises' import { readFile, writeFile } from 'fs/promises'
import { import {
@ -10,12 +10,16 @@ import {
getCallable, getCallable,
renderTemplate, renderTemplate,
inject, inject,
Location Location,
} from '@feathershq/pinion' exec
import * as ts from 'typescript' } from '@featherscloud/pinion'
import ts from 'typescript'
import prettier, { Options as PrettierOptions } from 'prettier' import prettier, { Options as PrettierOptions } from 'prettier'
import path from 'path' import path from 'path'
// Set __dirname in es module
const __dirname = dirname(new URL(import.meta.url).pathname)
export const { version } = JSON.parse(fs.readFileSync(join(__dirname, '..', 'package.json')).toString()) export const { version } = JSON.parse(fs.readFileSync(join(__dirname, '..', 'package.json')).toString())
export type DependencyVersions = { [key: string]: string } export type DependencyVersions = { [key: string]: string }
@ -251,6 +255,20 @@ export const renderSource =
return renderer(ctx).then(prettify(target)) return renderer(ctx).then(prettify(target))
} }
export const install =
<C extends PinionContext & { language: 'js' | 'ts' }>(
dependencies: Callable<string[], C>,
dev: Callable<boolean, C>,
packager: Callable<string, C>
) =>
async (ctx: C) => {
const dependencyList = await getCallable(dependencies, ctx)
const packageManager = await getCallable(packager, ctx)
const flags = dev ? [packageManager === 'yarn' ? '--dev' : '--save-dev'] : []
return exec(packager, [packageManager === 'yarn' ? 'add' : 'install', ...dependencyList, ...flags])(ctx)
}
/** /**
* Inject a source template as the language set in the context. * Inject a source template as the language set in the context.
* *

View File

@ -1,13 +1,18 @@
import { generator, runGenerator, prompt, install, mergeJSON, toFile, when } from '@feathershq/pinion' import { dirname } from 'path'
import { runGenerator, prompt, mergeJSON, toFile, when } from '@featherscloud/pinion'
import chalk from 'chalk' import chalk from 'chalk'
import { import {
install,
FeathersBaseContext, FeathersBaseContext,
DatabaseType, DatabaseType,
getDatabaseAdapter, getDatabaseAdapter,
addVersions, addVersions,
checkPreconditions, checkPreconditions,
initializeBaseContext initializeBaseContext
} from '../commons' } from '../commons.js'
// Set __dirname in es module
const __dirname = dirname(new URL(import.meta.url).pathname)
export interface ConnectionGeneratorContext extends FeathersBaseContext { export interface ConnectionGeneratorContext extends FeathersBaseContext {
name?: string name?: string
@ -74,10 +79,11 @@ export const getDatabaseClient = (database: DatabaseType) =>
database === 'other' ? null : DATABASE_CLIENTS[database] database === 'other' ? null : DATABASE_CLIENTS[database]
export const generate = (ctx: ConnectionGeneratorArguments) => export const generate = (ctx: ConnectionGeneratorArguments) =>
generator(ctx) Promise.resolve(ctx)
.then(initializeBaseContext()) .then(initializeBaseContext())
.then(checkPreconditions()) .then(checkPreconditions())
.then(prompt<ConnectionGeneratorArguments, ConnectionGeneratorContext>(prompts)) .then(prompt(prompts))
.then((ctx) => ctx as ConnectionGeneratorContext)
.then( .then(
when<ConnectionGeneratorContext>( when<ConnectionGeneratorContext>(
(ctx) => ctx.database !== 'other', (ctx) => ctx.database !== 'other',

View File

@ -1,6 +1,6 @@
import { generator, toFile, before, mergeJSON } from '@feathershq/pinion' import { toFile, before, mergeJSON } from '@featherscloud/pinion'
import { ConnectionGeneratorContext } from '../index' import { ConnectionGeneratorContext } from '../index.js'
import { injectSource, renderSource } from '../../commons' import { injectSource, renderSource } from '../../commons.js'
import { mkdir } from 'fs/promises' import { mkdir } from 'fs/promises'
import path from 'path' import path from 'path'
@ -45,7 +45,7 @@ const configureTemplate = ({ database }: ConnectionGeneratorContext) => `app.con
const toAppFile = toFile<ConnectionGeneratorContext>(({ lib }) => [lib, 'app']) const toAppFile = toFile<ConnectionGeneratorContext>(({ lib }) => [lib, 'app'])
export const generate = (ctx: ConnectionGeneratorContext) => export const generate = (ctx: ConnectionGeneratorContext) =>
generator(ctx) Promise.resolve(ctx)
.then( .then(
renderSource( renderSource(
template, template,

View File

@ -1,6 +1,6 @@
import { generator, toFile, before, prepend, append } from '@feathershq/pinion' import { toFile, before, prepend, append } from '@featherscloud/pinion'
import { ConnectionGeneratorContext } from '../index' import { ConnectionGeneratorContext } from '../index.js'
import { injectSource, renderSource } from '../../commons' import { injectSource, renderSource } from '../../commons.js'
const template = ({ const template = ({
database database
@ -37,7 +37,7 @@ const toAppFile = toFile<ConnectionGeneratorContext>(({ lib }) => [lib, 'app'])
const toValidatorFile = toFile<ConnectionGeneratorContext>(({ lib }) => [lib, 'validators']) const toValidatorFile = toFile<ConnectionGeneratorContext>(({ lib }) => [lib, 'validators'])
export const generate = (ctx: ConnectionGeneratorContext) => export const generate = (ctx: ConnectionGeneratorContext) =>
generator(ctx) Promise.resolve(ctx)
.then( .then(
renderSource( renderSource(
template, template,

View File

@ -1,6 +1,10 @@
import { generator, prompt, runGenerators } from '@feathershq/pinion' import { dirname } from 'path'
import { prompt, runGenerators } from '@featherscloud/pinion'
import _ from 'lodash' import _ from 'lodash'
import { checkPreconditions, FeathersBaseContext, initializeBaseContext } from '../commons' import { checkPreconditions, FeathersBaseContext, initializeBaseContext } from '../commons.js'
// Set __dirname in es module
const __dirname = dirname(new URL(import.meta.url).pathname)
export interface HookGeneratorContext extends FeathersBaseContext { export interface HookGeneratorContext extends FeathersBaseContext {
name: string name: string
@ -10,7 +14,7 @@ export interface HookGeneratorContext extends FeathersBaseContext {
} }
export const generate = (ctx: HookGeneratorContext) => export const generate = (ctx: HookGeneratorContext) =>
generator(ctx) Promise.resolve(ctx)
.then(initializeBaseContext()) .then(initializeBaseContext())
.then(checkPreconditions()) .then(checkPreconditions())
.then( .then(

View File

@ -1,6 +1,6 @@
import { generator, toFile } from '@feathershq/pinion' import { toFile } from '@featherscloud/pinion'
import { HookGeneratorContext } from '../index' import { HookGeneratorContext } from '../index.js'
import { renderSource } from '../../commons' import { renderSource } from '../../commons.js'
const aroundTemplate = ({ const aroundTemplate = ({
camelName, camelName,
@ -25,7 +25,7 @@ export const ${camelName} = async (context: HookContext) => {
}` }`
export const generate = (ctx: HookGeneratorContext) => export const generate = (ctx: HookGeneratorContext) =>
generator(ctx).then( Promise.resolve(ctx).then(
renderSource( renderSource(
(ctx) => (ctx.type === 'around' ? aroundTemplate(ctx) : regularTemplate(ctx)), (ctx) => (ctx.type === 'around' ? aroundTemplate(ctx) : regularTemplate(ctx)),
toFile<HookGeneratorContext>(({ lib, kebabName }) => [lib, 'hooks', kebabName]) toFile<HookGeneratorContext>(({ lib, kebabName }) => [lib, 'hooks', kebabName])

View File

@ -1,8 +1,8 @@
export * from '@feathershq/pinion' export * from '@featherscloud/pinion'
export * from './commons' export * from './commons.js'
export * as app from './app' export * as app from './app/index.js'
export * as authentication from './authentication' export * as authentication from './authentication/index.js'
export * as connection from './connection' export * as connection from './connection/index.js'
export * as hook from './hook' export * as hook from './hook/index.js'
export * as service from './service' export * as service from './service/index.js'

View File

@ -1,5 +1,10 @@
import { dirname } from 'path'
import _ from 'lodash' import _ from 'lodash'
import { generator, runGenerator, runGenerators, prompt } from '@feathershq/pinion' import { runGenerator, runGenerators, prompt } from '@featherscloud/pinion'
import chalk from 'chalk'
// Set __dirname in es module
const __dirname = dirname(new URL(import.meta.url).pathname)
import { import {
checkPreconditions, checkPreconditions,
@ -8,8 +13,7 @@ import {
fileExists, fileExists,
getDatabaseAdapter, getDatabaseAdapter,
initializeBaseContext initializeBaseContext
} from '../commons' } from '../commons.js'
import chalk from 'chalk'
export interface ServiceGeneratorContext extends FeathersBaseContext { export interface ServiceGeneratorContext extends FeathersBaseContext {
/** /**
@ -83,104 +87,102 @@ export type ServiceGeneratorArguments = FeathersBaseContext &
> >
export const generate = (ctx: ServiceGeneratorArguments) => export const generate = (ctx: ServiceGeneratorArguments) =>
generator(ctx) Promise.resolve(ctx)
.then(initializeBaseContext()) .then(initializeBaseContext())
.then(checkPreconditions()) .then(checkPreconditions())
.then( .then(
prompt<ServiceGeneratorArguments, ServiceGeneratorContext>( prompt(({ name, path, type, schema, authentication, isEntityService, feathers, lib, language }) => {
({ name, path, type, schema, authentication, isEntityService, feathers, lib, language }) => { const sqlDisabled = DATABASE_TYPES.every(
const sqlDisabled = DATABASE_TYPES.every( (name) => name === 'mongodb' || name === 'other' || !fileExists(lib, `${name}.${language}`)
(name) => name === 'mongodb' || name === 'other' || !fileExists(lib, `${name}.${language}`) )
) const mongodbDisabled = !fileExists(lib, `mongodb.${language}`)
const mongodbDisabled = !fileExists(lib, `mongodb.${language}`)
return [ return [
{ {
name: 'name', name: 'name',
type: 'input', type: 'input',
when: !name, when: !name,
message: 'What is the name of your service?', message: 'What is the name of your service?',
validate: (input) => { validate: (input: any) => {
if (!input || input === 'authentication') { if (!input || input === 'authentication') {
return 'Invalid service name' return 'Invalid service name'
}
return true
} }
},
{
name: 'path',
type: 'input',
when: !path,
message: 'Which path should the service be registered on?',
default: (answers: ServiceGeneratorArguments) => `${_.kebabCase(answers.name)}`,
validate: (input) => {
if (!input || input === 'authentication') {
return 'Invalid service path'
}
return true return true
}
},
{
name: 'authentication',
type: 'confirm',
when: authentication === undefined && !isEntityService,
message: 'Does this service require authentication?'
},
{
name: 'type',
type: 'list',
when: !type,
message: 'What database is the service using?',
default: getDatabaseAdapter(feathers?.database),
choices: [
{
value: 'knex',
name: `SQL${sqlDisabled ? chalk.gray(' (connection not available)') : ''}`,
disabled: sqlDisabled
},
{
value: 'mongodb',
name: `MongoDB${mongodbDisabled ? chalk.gray(' (connection not available)') : ''}`,
disabled: mongodbDisabled
},
{
value: 'custom',
name: 'A custom service'
}
]
},
{
name: 'schema',
type: 'list',
when: schema === undefined,
message: 'Which schema definition format do you want to use?',
suffix: chalk.grey(' Schemas allow to type, validate, secure and populate data'),
default: feathers?.schema,
choices: (answers: ServiceGeneratorContext) => [
{
value: 'typebox',
name: `TypeBox ${chalk.gray(' (recommended)')}`
},
{
value: 'json',
name: 'JSON schema'
},
{
value: false,
name: `No schema${
answers.type !== 'custom' ? chalk.gray(' (not recommended with a database)') : ''
}`
}
]
} }
] },
} {
) name: 'path',
type: 'input',
when: !path,
message: 'Which path should the service be registered on?',
default: (answers: ServiceGeneratorArguments) => `${_.kebabCase(answers.name)}`,
validate: (input: any) => {
if (!input || input === 'authentication') {
return 'Invalid service path'
}
return true
}
},
{
name: 'authentication',
type: 'confirm',
when: authentication === undefined && !isEntityService,
message: 'Does this service require authentication?'
},
{
name: 'type',
type: 'list',
when: !type,
message: 'What database is the service using?',
default: getDatabaseAdapter(feathers?.database),
choices: [
{
value: 'knex',
name: `SQL${sqlDisabled ? chalk.gray(' (connection not available)') : ''}`,
disabled: sqlDisabled
},
{
value: 'mongodb',
name: `MongoDB${mongodbDisabled ? chalk.gray(' (connection not available)') : ''}`,
disabled: mongodbDisabled
},
{
value: 'custom',
name: 'A custom service'
}
]
},
{
name: 'schema',
type: 'list',
when: schema === undefined,
message: 'Which schema definition format do you want to use?',
suffix: chalk.grey(' Schemas allow to type, validate, secure and populate data'),
default: feathers?.schema,
choices: (answers: ServiceGeneratorContext) => [
{
value: 'typebox',
name: `TypeBox ${chalk.gray(' (recommended)')}`
},
{
value: 'json',
name: 'JSON schema'
},
{
value: false,
name: `No schema${
answers.type !== 'custom' ? chalk.gray(' (not recommended with a database)') : ''
}`
}
]
}
]
})
) )
.then(async (ctx): Promise<ServiceGeneratorContext> => { .then(async (ctx): Promise<ServiceGeneratorContext> => {
const { name, path, type, authStrategies = [] } = ctx const { name, path, type, authStrategies = [] } = ctx as any as ServiceGeneratorContext
const kebabName = _.kebabCase(name) const kebabName = _.kebabCase(name)
const camelName = _.camelCase(name) const camelName = _.camelCase(name)
const upperName = _.upperFirst(camelName) const upperName = _.upperFirst(camelName)
@ -205,7 +207,7 @@ export const generate = (ctx: ServiceGeneratorArguments) =>
relative, relative,
authStrategies, authStrategies,
...ctx ...ctx
} } as ServiceGeneratorContext
}) })
.then(runGenerators<ServiceGeneratorContext>(__dirname, 'templates')) .then(runGenerators<ServiceGeneratorContext>(__dirname, 'templates'))
.then(runGenerator<ServiceGeneratorContext>(__dirname, 'type', ({ type }) => `${type}.tpl`)) .then(runGenerator<ServiceGeneratorContext>(__dirname, 'type', ({ type }) => `${type}.tpl`))

View File

@ -1,6 +1,6 @@
import { generator, toFile, after, before, when } from '@feathershq/pinion' import { toFile, after, before, when } from '@featherscloud/pinion'
import { fileExists, injectSource } from '../../commons' import { fileExists, injectSource } from '../../commons.js'
import { ServiceGeneratorContext } from '../index' import { ServiceGeneratorContext } from '../index.js'
const importTemplate = ({ upperName, folder, fileName, camelName }: ServiceGeneratorContext) => /* ts */ ` const importTemplate = ({ upperName, folder, fileName, camelName }: ServiceGeneratorContext) => /* ts */ `
import { ${camelName}Client } from './services/${folder.join('/')}/${fileName}.shared' import { ${camelName}Client } from './services/${folder.join('/')}/${fileName}.shared'
@ -18,7 +18,7 @@ const registrationTemplate = ({ camelName }: ServiceGeneratorContext) =>
const toClientFile = toFile<ServiceGeneratorContext>(({ lib }) => [lib, 'client']) const toClientFile = toFile<ServiceGeneratorContext>(({ lib }) => [lib, 'client'])
export const generate = async (ctx: ServiceGeneratorContext) => export const generate = async (ctx: ServiceGeneratorContext) =>
generator(ctx).then( Promise.resolve(ctx).then(
when<ServiceGeneratorContext>( when<ServiceGeneratorContext>(
({ lib, language }) => fileExists(lib, `client.${language}`), ({ lib, language }) => fileExists(lib, `client.${language}`),
injectSource(registrationTemplate, before('return client'), toClientFile), injectSource(registrationTemplate, before('return client'), toClientFile),

View File

@ -1,6 +1,6 @@
import { generator, toFile, when } from '@feathershq/pinion' import { toFile, when } from '@featherscloud/pinion'
import { fileExists, localTemplate, renderSource } from '../../commons' import { fileExists, localTemplate, renderSource } from '../../commons.js'
import { ServiceGeneratorContext } from '../index' import { ServiceGeneratorContext } from '../index.js'
const authFieldsTemplate = (authStrategies: string[]) => const authFieldsTemplate = (authStrategies: string[]) =>
authStrategies authStrategies
@ -127,7 +127,7 @@ export const ${camelName}QueryResolver = resolve<${upperName}Query, HookContext<
` `
export const generate = (ctx: ServiceGeneratorContext) => export const generate = (ctx: ServiceGeneratorContext) =>
generator(ctx).then( Promise.resolve(ctx).then(
when<ServiceGeneratorContext>( when<ServiceGeneratorContext>(
({ schema }) => schema === 'json', ({ schema }) => schema === 'json',
renderSource( renderSource(

View File

@ -1,6 +1,6 @@
import { generator, toFile, when } from '@feathershq/pinion' import { toFile, when } from '@featherscloud/pinion'
import { fileExists, localTemplate, renderSource } from '../../commons' import { fileExists, localTemplate, renderSource } from '../../commons.js'
import { ServiceGeneratorContext } from '../index' import { ServiceGeneratorContext } from '../index.js'
const authFieldsTemplate = (authStrategies: string[]) => const authFieldsTemplate = (authStrategies: string[]) =>
authStrategies authStrategies
@ -115,7 +115,7 @@ export const ${camelName}QueryResolver = resolve<${upperName}Query, HookContext<
` `
export const generate = (ctx: ServiceGeneratorContext) => export const generate = (ctx: ServiceGeneratorContext) =>
generator(ctx).then( Promise.resolve(ctx).then(
when<ServiceGeneratorContext>( when<ServiceGeneratorContext>(
({ schema }) => schema === 'typebox', ({ schema }) => schema === 'typebox',
renderSource( renderSource(

View File

@ -1,6 +1,6 @@
import { generator, toFile, after, prepend } from '@feathershq/pinion' import { toFile, after, prepend } from '@featherscloud/pinion'
import { fileExists, injectSource, renderSource } from '../../commons' import { fileExists, injectSource, renderSource } from '../../commons.js'
import { ServiceGeneratorContext } from '../index' import { ServiceGeneratorContext } from '../index.js'
export const template = ({ export const template = ({
camelName, camelName,
@ -132,7 +132,7 @@ declare module '${relative}/declarations' {
const toServiceIndex = toFile(({ lib }: ServiceGeneratorContext) => [lib, 'services', `index`]) const toServiceIndex = toFile(({ lib }: ServiceGeneratorContext) => [lib, 'services', `index`])
export const generate = (ctx: ServiceGeneratorContext) => export const generate = (ctx: ServiceGeneratorContext) =>
generator(ctx) Promise.resolve(ctx)
.then( .then(
renderSource( renderSource(
template, template,

View File

@ -1,6 +1,6 @@
import { generator, toFile, when } from '@feathershq/pinion' import { toFile, when } from '@featherscloud/pinion'
import { fileExists, renderSource } from '../../commons' import { fileExists, renderSource } from '../../commons.js'
import { ServiceGeneratorContext } from '../index' import { ServiceGeneratorContext } from '../index.js'
const sharedTemplate = ({ const sharedTemplate = ({
camelName, camelName,
@ -48,7 +48,7 @@ declare module '${relative}/client' {
` `
export const generate = async (ctx: ServiceGeneratorContext) => export const generate = async (ctx: ServiceGeneratorContext) =>
generator(ctx).then( Promise.resolve(ctx).then(
when<ServiceGeneratorContext>( when<ServiceGeneratorContext>(
({ lib, language }) => fileExists(lib, `client.${language}`), ({ lib, language }) => fileExists(lib, `client.${language}`),
renderSource( renderSource(

View File

@ -1,6 +1,6 @@
import { generator, toFile } from '@feathershq/pinion' import { toFile } from '@featherscloud/pinion'
import { renderSource } from '../../commons' import { renderSource } from '../../commons.js'
import { ServiceGeneratorContext } from '../index' import { ServiceGeneratorContext } from '../index.js'
const template = ({ const template = ({
relative, relative,
@ -20,7 +20,7 @@ describe('${path} service', () => {
` `
export const generate = (ctx: ServiceGeneratorContext) => export const generate = (ctx: ServiceGeneratorContext) =>
generator(ctx).then( Promise.resolve(ctx).then(
renderSource( renderSource(
template, template,
toFile<ServiceGeneratorContext>(({ test, folder, fileName }) => [ toFile<ServiceGeneratorContext>(({ test, folder, fileName }) => [

View File

@ -1,6 +1,6 @@
import { generator, toFile } from '@feathershq/pinion' import { toFile } from '@featherscloud/pinion'
import { renderSource } from '../../commons' import { renderSource } from '../../commons.js'
import { ServiceGeneratorContext } from '../index' import { ServiceGeneratorContext } from '../index.js'
export const template = ({ export const template = ({
className, className,
@ -99,7 +99,7 @@ export const getOptions = (app: Application) => {
` `
export const generate = (ctx: ServiceGeneratorContext) => export const generate = (ctx: ServiceGeneratorContext) =>
generator(ctx).then( Promise.resolve(ctx).then(
renderSource( renderSource(
template, template,
toFile<ServiceGeneratorContext>(({ lib, folder, fileName }) => [ toFile<ServiceGeneratorContext>(({ lib, folder, fileName }) => [

View File

@ -1,6 +1,6 @@
import { generator, toFile } from '@feathershq/pinion' import { toFile } from '@featherscloud/pinion'
import { renderSource, yyyymmddhhmmss } from '../../commons' import { renderSource, yyyymmddhhmmss } from '../../commons.js'
import { ServiceGeneratorContext } from '../index' import { ServiceGeneratorContext } from '../index.js'
const migrationTemplate = ({ const migrationTemplate = ({
kebabPath, kebabPath,
@ -85,7 +85,7 @@ export const getOptions = (app: Application): KnexAdapterOptions => {
` `
export const generate = (ctx: ServiceGeneratorContext) => export const generate = (ctx: ServiceGeneratorContext) =>
generator(ctx) Promise.resolve(ctx)
.then( .then(
renderSource( renderSource(
template, template,

View File

@ -1,6 +1,6 @@
import { generator, toFile } from '@feathershq/pinion' import { toFile } from '@featherscloud/pinion'
import { renderSource } from '../../commons' import { renderSource } from '../../commons.js'
import { ServiceGeneratorContext } from '../index' import { ServiceGeneratorContext } from '../index.js'
export const template = ({ export const template = ({
className, className,
@ -51,7 +51,7 @@ export const getOptions = (app: Application): MongoDBAdapterOptions => {
` `
export const generate = (ctx: ServiceGeneratorContext) => export const generate = (ctx: ServiceGeneratorContext) =>
generator(ctx).then( Promise.resolve(ctx).then(
renderSource( renderSource(
template, template,
toFile<ServiceGeneratorContext>(({ lib, folder, fileName }) => [ toFile<ServiceGeneratorContext>(({ lib, folder, fileName }) => [

View File

@ -1,5 +1,5 @@
import { strictEqual } from 'assert' import { strictEqual } from 'assert'
import { getJavaScript } from '../src/commons' import { getJavaScript } from '../lib/commons'
describe('common tests', () => { describe('common tests', () => {
it('getJavaScript returns transpiled JavaScript', () => { it('getJavaScript returns transpiled JavaScript', () => {

View File

@ -3,7 +3,7 @@ import os from 'os'
import path from 'path' import path from 'path'
import { mkdtemp } from 'fs/promises' import { mkdtemp } from 'fs/promises'
import assert from 'assert' import assert from 'assert'
import { getContext } from '@feathershq/pinion' import { getContext } from '@featherscloud/pinion'
import { AppGeneratorContext } from '../src/app' import { AppGeneratorContext } from '../src/app'
import { FeathersBaseContext } from '../src/commons' import { FeathersBaseContext } from '../src/commons'
@ -15,8 +15,8 @@ import { generate as generateApp } from '../lib/app'
import { generate as generateConnection } from '../lib/connection' import { generate as generateConnection } from '../lib/connection'
import { generate as generateAuthentication } from '../lib/authentication' import { generate as generateAuthentication } from '../lib/authentication'
import { generate as generateService } from '../lib/service' import { generate as generateService } from '../lib/service'
import { listAllFiles } from '@feathershq/pinion/lib/utils' import { listAllFiles } from '@featherscloud/pinion/lib/utils'
import { AuthenticationGeneratorArguments } from '../src/authentication' import { AuthenticationGeneratorArguments } from '../lib/authentication'
const matrix = { const matrix = {
language: ['js', 'ts'] as const, language: ['js', 'ts'] as const,

View File

@ -3,6 +3,9 @@ import pkg from '../package.json'
import { DependencyVersions } from '../src/commons' import { DependencyVersions } from '../src/commons'
import { readFileSync } from 'fs' import { readFileSync } from 'fs'
// Set __dirname in es module
const __dirname = path.dirname(new URL(import.meta.url).pathname)
export function combinate<O extends Record<string | number, any[]>>(obj: O) { export function combinate<O extends Record<string | number, any[]>>(obj: O) {
let combos: { [k in keyof O]: O[k][number] }[] = [] let combos: { [k in keyof O]: O[k][number] }[] = []
for (const key of Object.keys(obj)) { for (const key of Object.keys(obj)) {

View File

@ -5,6 +5,7 @@
], ],
"compilerOptions": { "compilerOptions": {
"outDir": "lib", "outDir": "lib",
"resolveJsonModule": true "module": "ESNext",
"moduleResolution": "Node"
} }
} }

View File

@ -322,7 +322,10 @@ export class KnexAdapter<
return result return result
}, {}) }, {})
await this.db(params).update(newObject, '*', { includeTriggerModifications: true }).where(this.id, id).catch(errorHandler) await this.db(params)
.update(newObject, '*', { includeTriggerModifications: true })
.where(this.id, id)
.catch(errorHandler)
return this._get(id, params) return this._get(id, params)
} }