diff --git a/packages/cli/src/app/templates/app.tpl.ts b/packages/cli/src/app/templates/app.tpl.ts index 257651d807..867aee7f6d 100644 --- a/packages/cli/src/app/templates/app.tpl.ts +++ b/packages/cli/src/app/templates/app.tpl.ts @@ -10,7 +10,7 @@ import { koa, rest, bodyParser, errorHandler, parseAuthentication } from '@feath ${transports.includes('websockets') ? "import socketio from '@feathersjs/socketio'" : ''} import type { Application } from './declarations' -import { configurationSchema } from './schemas/configuration.schema' +import { configurationSchema } from './configuration' import { logErrorHook } from './logger' import { services } from './services/index' import { channels } from './channels' @@ -63,7 +63,7 @@ import configuration from '@feathersjs/configuration' ${transports.includes('websockets') ? "import socketio from '@feathersjs/socketio'" : ''} import type { Application } from './declarations' -import { configurationSchema } from './schemas/configuration.schema' +import { configurationSchema } from './configuration' import { logger, logErrorHook } from './logger' import { services } from './services/index' import { channels } from './channels' diff --git a/packages/cli/src/app/templates/configuration.tpl.ts b/packages/cli/src/app/templates/configuration.tpl.ts index fd1d317128..6846058fe2 100644 --- a/packages/cli/src/app/templates/configuration.tpl.ts +++ b/packages/cli/src/app/templates/configuration.tpl.ts @@ -7,27 +7,30 @@ const template = ({}: AppGeneratorContext) => import type { Infer } from '@feathersjs/schema' import { authenticationSettingsSchema } from '@feathersjs/authentication' -export const configurationSchema = schema({ - $id: 'ApplicationConfiguration', - type: 'object', - additionalProperties: false, - required: [ 'host', 'port', 'public', 'paginate' ], - properties: { - host: { type: 'string' }, - port: { type: 'number' }, - public: { type: 'string' }, - authentication: authenticationSettingsSchema, - paginate: { - type: 'object', - additionalProperties: false, - required: [ 'default', 'max' ], - properties: { - default: { type: 'number' }, - max: { type: 'number' } +export const configurationSchema = schema( + { + $id: 'ApplicationConfiguration', + type: 'object', + additionalProperties: false, + required: [ 'host', 'port', 'public', 'paginate' ], + properties: { + host: { type: 'string' }, + port: { type: 'number' }, + public: { type: 'string' }, + authentication: authenticationSettingsSchema, + paginate: { + type: 'object', + additionalProperties: false, + required: [ 'default', 'max' ], + properties: { + default: { type: 'number' }, + max: { type: 'number' } + } } } - } -} as const, new Ajv()) + } as const, + new Ajv() +) export type ConfigurationSchema = Infer ` @@ -36,6 +39,6 @@ export const generate = (ctx: AppGeneratorContext) => generator(ctx).then( renderSource( template, - toFile(({ lib }) => lib, 'schemas', 'configuration.schema') + toFile(({ lib }) => lib, 'configuration') ) ) diff --git a/packages/cli/src/app/templates/declarations.tpl.ts b/packages/cli/src/app/templates/declarations.tpl.ts index e064af27c3..404637734c 100644 --- a/packages/cli/src/app/templates/declarations.tpl.ts +++ b/packages/cli/src/app/templates/declarations.tpl.ts @@ -4,7 +4,7 @@ import { AppGeneratorContext } from '../index' const template = ({ framework }: AppGeneratorContext) => `import { HookContext as FeathersHookContext, NextFunction } from '@feathersjs/feathers' import { Application as FeathersApplication } from '@feathersjs/${framework}' -import { ConfigurationSchema } from './schemas/configuration.schema' +import { ConfigurationSchema } from './configuration' export { NextFunction } diff --git a/packages/cli/src/authentication/templates/authentication.tpl.ts b/packages/cli/src/authentication/templates/authentication.tpl.ts index 4e3e74336f..6bce402858 100644 --- a/packages/cli/src/authentication/templates/authentication.tpl.ts +++ b/packages/cli/src/authentication/templates/authentication.tpl.ts @@ -1,5 +1,5 @@ -import { generator, inject, before, toFile } from '@feathershq/pinion' -import { getSource, renderSource } from '../../commons' +import { generator, before, toFile } from '@feathershq/pinion' +import { injectSource, renderSource } from '../../commons' import { AuthenticationGeneratorContext } from '../index' const template = ({ authStrategies, feathers }: AuthenticationGeneratorContext) => @@ -39,7 +39,7 @@ export const authentication = (app: Application) => { const importTemplate = "import { authentication } from './authentication'" const configureTemplate = 'app.configure(authentication)' -const toAppFile = toFile(({ lib, language }) => [lib, `app.${language}`]) +const toAppFile = toFile(({ lib }) => [lib, 'app']) export const generate = (ctx: AuthenticationGeneratorContext) => generator(ctx) @@ -49,5 +49,5 @@ export const generate = (ctx: AuthenticationGeneratorContext) => toFile(({ lib }) => lib, 'authentication') ) ) - .then(inject(getSource(importTemplate), before('import { services } from'), toAppFile)) - .then(inject(getSource(configureTemplate), before('app.configure(services)'), toAppFile)) + .then(injectSource(importTemplate, before('import { services } from'), toAppFile)) + .then(injectSource(configureTemplate, before('app.configure(services)'), toAppFile)) diff --git a/packages/cli/src/authentication/templates/declarations.tpl.ts b/packages/cli/src/authentication/templates/declarations.tpl.ts index 8ac0316ca3..633187d7c1 100644 --- a/packages/cli/src/authentication/templates/declarations.tpl.ts +++ b/packages/cli/src/authentication/templates/declarations.tpl.ts @@ -1,8 +1,8 @@ import { generator, inject, before, toFile, when, append } from '@feathershq/pinion' import { AuthenticationGeneratorContext } from '../index' -const importTemplate = ({ upperName, schemaPath }: AuthenticationGeneratorContext) => - `import { ${upperName}Result } from './${schemaPath}' +const importTemplate = ({ upperName, folder, fileName }: AuthenticationGeneratorContext) => + `import { ${upperName}Result } from './services/${folder.join('/')}/${fileName}.schema' ` const paramsTemplate = ({ diff --git a/packages/cli/src/authentication/templates/test.tpl.ts b/packages/cli/src/authentication/templates/test.tpl.ts index d7bddc5486..d6f6127b36 100644 --- a/packages/cli/src/authentication/templates/test.tpl.ts +++ b/packages/cli/src/authentication/templates/test.tpl.ts @@ -2,9 +2,9 @@ import { generator, toFile } from '@feathershq/pinion' import { renderSource } from '../../commons' import { AuthenticationGeneratorContext } from '../index' -const template = ({ authStrategies, relative, lib }: AuthenticationGeneratorContext) => +const template = ({ authStrategies, lib }: AuthenticationGeneratorContext) => `import assert from 'assert'; -import { app } from '${relative}/${lib}/app'; +import { app } from '../${lib}/app'; describe('authentication', () => { ${ diff --git a/packages/cli/src/authentication/templates/user.resolver.tpl.ts b/packages/cli/src/authentication/templates/user.resolver.tpl.ts index 35f87eb08c..948edcbf50 100644 --- a/packages/cli/src/authentication/templates/user.resolver.tpl.ts +++ b/packages/cli/src/authentication/templates/user.resolver.tpl.ts @@ -8,7 +8,7 @@ const template = ({ relative, authStrategies, type, - schemaPath + fileName }: AuthenticationGeneratorContext) => `import { resolve } from '@feathersjs/schema' ${authStrategies.includes('local') ? `import { passwordHash } from '@feathersjs/authentication-local'` : ''} @@ -18,13 +18,13 @@ import type { ${upperName}Patch, ${upperName}Result, ${upperName}Query, -} from '../${schemaPath}' +} from './${fileName}.schema' import { ${camelName}DataSchema, ${camelName}PatchSchema, ${camelName}ResultSchema, ${camelName}QuerySchema -} from '../${schemaPath}' +} from './${fileName}.schema' // Resolver for the basic data model (e.g. creating new entries) @@ -98,11 +98,11 @@ export const generate = (ctx: AuthenticationGeneratorContext) => generator(ctx).then( renderSource( template, - toFile(({ lib, folder, kebabName }: AuthenticationGeneratorContext) => [ + toFile(({ lib, folder, fileName }: AuthenticationGeneratorContext) => [ lib, - 'resolvers', + 'services', ...folder, - `${kebabName}.resolver` + `${fileName}.resolver` ]), { force: true } ) diff --git a/packages/cli/src/authentication/templates/user.schema.tpl.ts b/packages/cli/src/authentication/templates/user.schema.tpl.ts index a5ee5d6fb0..807e2d8fbf 100644 --- a/packages/cli/src/authentication/templates/user.schema.tpl.ts +++ b/packages/cli/src/authentication/templates/user.schema.tpl.ts @@ -76,11 +76,11 @@ export const generate = (ctx: AuthenticationGeneratorContext) => generator(ctx).then( renderSource( template, - toFile(({ lib, folder, kebabName }: AuthenticationGeneratorContext) => [ + toFile(({ lib, folder, fileName }: AuthenticationGeneratorContext) => [ lib, - 'schemas', + 'services', ...folder, - `${kebabName}.schema` + `${fileName}.schema` ]), { force: true } ) diff --git a/packages/cli/src/commons.ts b/packages/cli/src/commons.ts index d2dd8a975f..bcae020a9b 100644 --- a/packages/cli/src/commons.ts +++ b/packages/cli/src/commons.ts @@ -1,5 +1,14 @@ import { PackageJson } from 'type-fest' -import { Callable, PinionContext, loadJSON, fromFile, getCallable, renderTemplate } from '@feathershq/pinion' +import { + Callable, + PinionContext, + loadJSON, + fromFile, + getCallable, + renderTemplate, + inject, + Location +} from '@feathershq/pinion' import * as ts from 'typescript' import prettier from 'prettier' import path from 'path' @@ -145,8 +154,7 @@ export const getJavaScript = (typescript: string, options: ts.TranspileOptions = } /** - * Render a source file template for the language set in the context. Will do nothing - * it there is no template for the selected language. + * Render a source file template for the language set in the context. * * @param templates The JavaScript and TypeScript template to render * @param toFile The target filename without extension (will be added based on language) @@ -159,10 +167,6 @@ export const renderSource = options?: { force: boolean } ) => async (ctx: C) => { - if (!template) { - return ctx - } - const { language } = ctx const fileName = await getCallable(toFile, ctx) const content = language === 'js' ? getJavaScript(await getCallable(template, ctx)) : template @@ -172,16 +176,27 @@ export const renderSource = } /** - * Returns the TypeScript or transpiled JavaScript source code + * Inject a source template as the language set in the context. * - * @param template The source template + * @param template The source template to render + * @param location The location to inject the code to. Must use the target language. + * @param target The target file name + * @param transpile Set to `false` if the code should not be transpiled to JavaScript * @returns */ -export const getSource = - (template: Callable) => - async (ctx: T) => { +export const injectSource = + ( + template: Callable, + location: Location, + target: Callable, + transpile = true + ) => + async (ctx: C) => { const { language } = ctx - const source = await getCallable(template, ctx) + const source = + language === 'js' && transpile ? getJavaScript(await getCallable(template, ctx)) : template + const toFile = await getCallable(target, ctx) + const injector = inject(source, location, `${toFile}.${language}`) - return language === 'js' ? getJavaScript(source) : source + return injector(ctx) } diff --git a/packages/cli/src/connection/templates/knex.tpl.ts b/packages/cli/src/connection/templates/knex.tpl.ts index cded328fc6..a3e1e50145 100644 --- a/packages/cli/src/connection/templates/knex.tpl.ts +++ b/packages/cli/src/connection/templates/knex.tpl.ts @@ -1,6 +1,6 @@ -import { generator, toFile, inject, before, mergeJSON } from '@feathershq/pinion' +import { generator, toFile, before, mergeJSON } from '@feathershq/pinion' import { ConnectionGeneratorContext } from '../index' -import { getSource, renderSource } from '../../commons' +import { injectSource, renderSource } from '../../commons' const template = ({ database }: ConnectionGeneratorContext) => `import knex from 'knex' @@ -30,18 +30,18 @@ const config = app.get('${database}') ${language === 'js' ? 'export default config' : 'module.exports = config'} ` -const configurationTemplate = ({ database }: ConnectionGeneratorContext) => ` ${database}: { - type: 'object', - properties: { - client: { type: 'string' }, - connection: { type: 'string' } - } - },` +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}`]) +const toAppFile = toFile(({ lib }) => [lib, 'app']) export const generate = (ctx: ConnectionGeneratorContext) => generator(ctx) @@ -65,15 +65,12 @@ export const generate = (ctx: ConnectionGeneratorContext) => ) ) .then( - inject( + injectSource( configurationTemplate, before('authentication: authenticationSettingsSchema'), - toFile(({ lib, language }) => [ - lib, - 'schemas', - `configuration.schema.${language}` - ]) + toFile(({ lib }) => [lib, 'configuration']), + false ) ) - .then(inject(getSource(importTemplate), before('import { services } from'), toAppFile)) - .then(inject(getSource(configureTemplate), before('app.configure(services)'), toAppFile)) + .then(injectSource(importTemplate, before('import { services } from'), toAppFile)) + .then(injectSource(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 61a5a2d38d..ebaad5452d 100644 --- a/packages/cli/src/connection/templates/mongodb.tpl.ts +++ b/packages/cli/src/connection/templates/mongodb.tpl.ts @@ -1,6 +1,6 @@ -import { generator, toFile, inject, before } from '@feathershq/pinion' +import { generator, toFile, before } from '@feathershq/pinion' import { ConnectionGeneratorContext } from '../index' -import { getSource, renderSource } from '../../commons' +import { injectSource, renderSource } from '../../commons' const template = ({}: ConnectionGeneratorContext) => `import { MongoClient } from 'mongodb' @@ -22,11 +22,12 @@ export const mongodb = (app: Application) => { app.set('mongodbClient', mongoClient) } ` + const configurationTemplate = ({ database }: ConnectionGeneratorContext) => - ` ${database}: { type: 'string' },` + ` ${database}: { type: 'string' },` const importTemplate = "import { mongodb } from './mongodb'" const configureTemplate = 'app.configure(mongodb)' -const toAppFile = toFile(({ lib, language }) => [lib, `app.${language}`]) +const toAppFile = toFile(({ lib }) => [lib, 'app']) export const generate = (ctx: ConnectionGeneratorContext) => generator(ctx) @@ -37,15 +38,12 @@ export const generate = (ctx: ConnectionGeneratorContext) => ) ) .then( - inject( + injectSource( configurationTemplate, before('authentication: authenticationSettingsSchema'), - toFile(({ lib, language }) => [ - lib, - 'schemas', - `configuration.schema.${language}` - ]) + toFile(({ lib }) => [lib, 'configuration']), + false ) ) - .then(inject(getSource(importTemplate), before('import { services } from'), toAppFile)) - .then(inject(getSource(configureTemplate), before('app.configure(services)'), toAppFile)) + .then(injectSource(importTemplate, before('import { services } from'), toAppFile)) + .then(injectSource(configureTemplate, before('app.configure(services)'), toAppFile)) diff --git a/packages/cli/src/service/index.ts b/packages/cli/src/service/index.ts index ec1b58e79d..578bee305d 100644 --- a/packages/cli/src/service/index.ts +++ b/packages/cli/src/service/index.ts @@ -52,14 +52,6 @@ export interface ServiceGeneratorContext extends FeathersBaseContext { * Set to true if this service is for an authentication entity */ isEntityService?: boolean - /** - * The name of the schema file - */ - schemaPath: string - /** - * The name of the resolver file - */ - resolverPath: string } /** @@ -123,12 +115,9 @@ export const generate = (ctx: ServiceGeneratorArguments) => const upperName = _.upperFirst(camelName) const className = `${upperName}Service` - const pathElements = path.split('/').filter((el) => el !== '') - const relative = pathElements.map(() => '..').join('/') - const folder = _.initial(pathElements) - const fileName = _.last(pathElements) - const schemaPath = ['schemas', ...folder, `${fileName}.schema`].join('/') - const resolverPath = ['resolvers', ...folder, `${fileName}.resolver`].join('/') + const folder = path.split('/').filter((el) => el !== '') + const relative = ['', ...folder].map(() => '..').join('/') + const fileName = _.last(folder) return { name, @@ -141,8 +130,6 @@ export const generate = (ctx: ServiceGeneratorArguments) => kebabName, camelName, relative, - resolverPath, - schemaPath, ...ctx } }) diff --git a/packages/cli/src/service/templates/class.tpl.ts b/packages/cli/src/service/templates/class.tpl.ts new file mode 100644 index 0000000000..86d8e30f6a --- /dev/null +++ b/packages/cli/src/service/templates/class.tpl.ts @@ -0,0 +1,79 @@ +import { generator, toFile } from '@feathershq/pinion' +import { renderSource } from '../../commons' +import { ServiceGeneratorContext } from '../index' + +const template = ({ + camelName, + upperName, + fileName, + isEntityService, + authentication +}: ServiceGeneratorContext) => + `import { resolveAll } from '@feathersjs/schema' +${isEntityService || authentication ? `import { authenticate } from '@feathersjs/authentication'` : ''} +import type { + ${upperName}Data, + ${upperName}Result, + ${upperName}Query, +} from './${fileName}.schema' +import { ${camelName}Resolvers } from './${fileName}.resolver' + +export const ${camelName}Hooks = { + around: { + all: [${ + authentication + ? ` + authenticate('jwt'),` + : '' + } ${ + !isEntityService + ? ` + resolveAll(${camelName}Resolvers)` + : '' + } + ]${ + isEntityService + ? `, + get: [ + authenticate('jwt'), + resolveAll(${camelName}Resolvers) + ], + find: [ + authenticate('jwt'), + resolveAll(${camelName}Resolvers) + ], + create: [ + resolveAll(${camelName}Resolvers) + ], + patch: [ + authenticate('jwt'), + resolveAll(${camelName}Resolvers) + ], + update: [ + authenticate('jwt'), + resolveAll(${camelName}Resolvers) + ], + remove: [ + authenticate('jwt'), + resolveAll(${camelName}Resolvers) + ]` + : '' + } + }, + before: {}, + after: {}, + error: {} +} +` +export const generate = (ctx: ServiceGeneratorContext) => + generator(ctx).then( + renderSource( + template, + toFile(({ lib, folder, fileName }) => [ + lib, + 'services', + ...folder, + `${fileName}.class` + ]) + ) + ) diff --git a/packages/cli/src/service/templates/client.tpl.ts b/packages/cli/src/service/templates/client.tpl.ts index f3a3fd4b18..0f74de323a 100644 --- a/packages/cli/src/service/templates/client.tpl.ts +++ b/packages/cli/src/service/templates/client.tpl.ts @@ -1,27 +1,22 @@ import { generator, inject, toFile, when, after } from '@feathershq/pinion' import { ServiceGeneratorContext } from '../index' -const schemaImports = ({ upperName, schemaPath }: ServiceGeneratorContext) => `import type { +const schemaImports = ({ upperName, folder, fileName }: ServiceGeneratorContext) => `import type { ${upperName}Data, ${upperName}Result, ${upperName}Query, -} from './${schemaPath}'` +} from './services/${folder.join('/')}/${fileName}.schema'` + const declarationTemplate = ({ path, upperName }: ServiceGeneratorContext) => ` '${path}': Service<${upperName}Data, ${upperName}Result, Params<${upperName}Query>>` -const toClientFile = toFile(({ lib, language }) => [lib, `client.${language}`]) +const toClientFile = toFile(({ lib }) => [lib, 'client.ts']) export const generate = async (ctx: ServiceGeneratorContext) => - generator(ctx) - .then( - when( - (ctx) => ctx.language === 'ts', - inject(schemaImports, after("from '@feathersjs/feathers'"), toClientFile) - ) - ) - .then( - when( - (ctx) => ctx.language === 'ts', - inject(declarationTemplate, after('export interface ServiceTypes'), toClientFile) - ) + generator(ctx).then( + when( + (ctx) => ctx.language === 'ts', + inject(schemaImports, after("from '@feathersjs/feathers'"), toClientFile), + inject(declarationTemplate, after('export interface ServiceTypes'), toClientFile) ) + ) diff --git a/packages/cli/src/service/templates/resolver.tpl.ts b/packages/cli/src/service/templates/resolver.tpl.ts index 7750afd74d..0691a20cff 100644 --- a/packages/cli/src/service/templates/resolver.tpl.ts +++ b/packages/cli/src/service/templates/resolver.tpl.ts @@ -2,7 +2,7 @@ import { generator, toFile } from '@feathershq/pinion' import { renderSource } from '../../commons' import { ServiceGeneratorContext } from '../index' -const template = ({ camelName, upperName, relative, schemaPath }: ServiceGeneratorContext) => +const template = ({ camelName, upperName, relative, fileName }: ServiceGeneratorContext) => `import { resolve } from '@feathersjs/schema' import type { HookContext } from '${relative}/declarations' @@ -11,13 +11,13 @@ import type { ${upperName}Patch, ${upperName}Result, ${upperName}Query, -} from '${relative}/${schemaPath}' +} from './${fileName}.schema' import { ${camelName}DataSchema, ${camelName}PatchSchema, ${camelName}ResultSchema, ${camelName}QuerySchema -} from '${relative}/${schemaPath}' +} from './${fileName}.schema' // Resolver for the basic data model (e.g. creating new entries) @@ -70,7 +70,7 @@ export const generate = (ctx: ServiceGeneratorContext) => template, toFile(({ lib, folder, fileName }: ServiceGeneratorContext) => [ lib, - 'resolvers', + 'services', ...folder, `${fileName}.resolver` ]) diff --git a/packages/cli/src/service/templates/schema.tpl.ts b/packages/cli/src/service/templates/schema.tpl.ts index 3152af8124..1dcbadf711 100644 --- a/packages/cli/src/service/templates/schema.tpl.ts +++ b/packages/cli/src/service/templates/schema.tpl.ts @@ -72,7 +72,7 @@ export const generate = (ctx: ServiceGeneratorContext) => template, toFile(({ lib, folder, fileName }: ServiceGeneratorContext) => [ lib, - 'schemas', + 'services', ...folder, `${fileName}.schema` ]) diff --git a/packages/cli/src/service/templates/service.tpl.ts b/packages/cli/src/service/templates/service.tpl.ts index ab9093f9e3..8210a5f4b2 100644 --- a/packages/cli/src/service/templates/service.tpl.ts +++ b/packages/cli/src/service/templates/service.tpl.ts @@ -1,74 +1,11 @@ -import { generator, inject, prepend, toFile, after } from '@feathershq/pinion' -import { getSource, renderSource } from '../../commons' +import { generator, prepend, toFile, after } from '@feathershq/pinion' +import { injectSource, renderSource } from '../../commons' import { ServiceGeneratorContext } from '../index' -const template = ({ - relative, - path, - className, - schemaPath, - resolverPath, - camelName, - upperName, - isEntityService, - authentication -}: ServiceGeneratorContext) => - `import { resolveAll } from '@feathersjs/schema' -${isEntityService || authentication ? `import { authenticate } from '@feathersjs/authentication'` : ''} -import type { Application } from '${relative}/declarations' -import type { - ${upperName}Data, - ${upperName}Result, - ${upperName}Query, -} from '${relative}/${schemaPath}' -import { ${camelName}Resolvers } from '${relative}/${resolverPath}' +const template = ({ relative, path, className, camelName, fileName }: ServiceGeneratorContext) => + `import type { Application } from '${relative}/declarations' -export const hooks = { - around: { - all: [${ - authentication - ? ` - authenticate('jwt'),` - : '' - } ${ - !isEntityService - ? ` - resolveAll(${camelName}Resolvers)` - : '' - } - ]${ - isEntityService - ? `, - get: [ - authenticate('jwt'), - resolveAll(${camelName}Resolvers) - ], - find: [ - authenticate('jwt'), - resolveAll(${camelName}Resolvers) - ], - create: [ - resolveAll(${camelName}Resolvers) - ], - patch: [ - authenticate('jwt'), - resolveAll(${camelName}Resolvers) - ], - update: [ - authenticate('jwt'), - resolveAll(${camelName}Resolvers) - ], - remove: [ - authenticate('jwt'), - resolveAll(${camelName}Resolvers) - ]` - : '' - } - }, - before: {}, - after: {}, - error: {} -} +import { ${className}, ${camelName}Hooks } from './${fileName}.class' // A configure function that registers the service and its hooks via \`app.configure\` export function ${camelName} (app: Application) { @@ -83,7 +20,7 @@ export function ${camelName} (app: Application) { events: [] }) // Initialize hooks - app.service('${path}').hooks(hooks) + app.service('${path}').hooks(${camelName}Hooks) } // Add this service to the service type index @@ -94,24 +31,25 @@ declare module '${relative}/declarations' { } ` -const importTemplate = ({ camelName, path }: ServiceGeneratorContext) => - `import { ${camelName} } from './${path}'` +const importTemplate = ({ camelName, folder, fileName }: ServiceGeneratorContext) => + `import { ${camelName} } from './${folder.join('/')}/${fileName}.service'` const configureTemplate = ({ camelName }: ServiceGeneratorContext) => ` app.configure(${camelName})` -const toServiceIndex = toFile(({ lib, language }: ServiceGeneratorContext) => [ - lib, - 'services', - `index.${language}` -]) +const toServiceIndex = toFile(({ lib }: ServiceGeneratorContext) => [lib, 'services', `index`]) export const generate = (ctx: ServiceGeneratorContext) => generator(ctx) .then( renderSource( template, - toFile(({ lib, folder, fileName }) => [lib, 'services', ...folder, fileName]) + toFile(({ lib, folder, fileName }) => [ + lib, + 'services', + ...folder, + `${fileName}.service` + ]) ) ) - .then(inject(getSource(importTemplate), prepend(), toServiceIndex)) - .then(inject(configureTemplate, after('export const services'), toServiceIndex)) + .then(injectSource(importTemplate, prepend(), toServiceIndex)) + .then(injectSource(configureTemplate, after('export const services'), toServiceIndex)) diff --git a/packages/cli/src/service/templates/test.tpl.ts b/packages/cli/src/service/templates/test.tpl.ts index e86ac195b3..3918574879 100644 --- a/packages/cli/src/service/templates/test.tpl.ts +++ b/packages/cli/src/service/templates/test.tpl.ts @@ -2,11 +2,11 @@ import { generator, toFile } from '@feathershq/pinion' import { renderSource } from '../../commons' import { ServiceGeneratorContext } from '../index' -const template = ({ relative, lib, path, name }: ServiceGeneratorContext) => +const template = ({ relative, lib, path }: ServiceGeneratorContext) => `import assert from 'assert' import { app } from '../${relative}/${lib}/app' -describe('${name} service', () => { +describe('${path} service', () => { it('registered the service', () => { const service = app.service('${path}') @@ -19,11 +19,11 @@ export const generate = (ctx: ServiceGeneratorContext) => generator(ctx).then( renderSource( template, - toFile(({ test, folder, kebabName }) => [ + toFile(({ test, folder, fileName }) => [ test, 'services', ...folder, - `${kebabName}.test` + `${fileName}.test` ]) ) ) diff --git a/packages/cli/src/service/type/custom.tpl.ts b/packages/cli/src/service/type/custom.tpl.ts index 2145d0321d..49f6e583fb 100644 --- a/packages/cli/src/service/type/custom.tpl.ts +++ b/packages/cli/src/service/type/custom.tpl.ts @@ -1,9 +1,11 @@ -import { generator, inject, toFile, after, before, prepend } from '@feathershq/pinion' -import { getSource } from '../../commons' +import { generator, toFile, after, prepend, append } from '@feathershq/pinion' +import { injectSource } from '../../commons' import { ServiceGeneratorContext } from '../index' -export const template = ({ className, upperName }: ServiceGeneratorContext) => - `export interface ${className}Options { +export const template = ({ className, upperName, relative }: ServiceGeneratorContext) => + `import type { Application } from '${relative}/declarations' + +export interface ${className}Options { app: Application } @@ -67,15 +69,22 @@ export const importTemplate = "import type { Id, NullableId, Params } from '@fea const optionTemplate = ({}: ServiceGeneratorContext) => ` app` -const toServiceFile = toFile(({ lib, language, folder, fileName }) => [ +const toServiceFile = toFile(({ lib, folder, fileName }) => [ lib, 'services', ...folder, - `${fileName}.${language}` + `${fileName}.service` +]) + +const toClassFile = toFile(({ lib, folder, fileName }) => [ + lib, + 'services', + ...folder, + `${fileName}.class` ]) export const generate = (ctx: ServiceGeneratorContext) => generator(ctx) - .then(inject(getSource(template), before('export const hooks ='), toServiceFile)) - .then(inject(getSource(importTemplate), prepend(), toServiceFile)) - .then(inject(optionTemplate, after('const options ='), toServiceFile)) + .then(injectSource(template, append(), toClassFile)) + .then(injectSource(importTemplate, prepend(), toClassFile)) + .then(injectSource(optionTemplate, after('const options ='), toServiceFile, false)) diff --git a/packages/cli/src/service/type/knex.tpl.ts b/packages/cli/src/service/type/knex.tpl.ts index 69f4e04aa9..5ad4c7c7ca 100644 --- a/packages/cli/src/service/type/knex.tpl.ts +++ b/packages/cli/src/service/type/knex.tpl.ts @@ -1,5 +1,5 @@ -import { generator, inject, toFile, before, after, prepend } from '@feathershq/pinion' -import { getSource, renderSource } from '../../commons' +import { generator, toFile, after, prepend, append } from '@feathershq/pinion' +import { injectSource, renderSource } from '../../commons' import { ServiceGeneratorContext } from '../index' const migrationTemplate = ({ kebabName }: ServiceGeneratorContext) => `import type { Knex } from 'knex' @@ -33,20 +33,25 @@ export const optionTemplate = ({ kebabName, feathers }: ServiceGeneratorContext) Model: app.get('${feathers.database}Client'), name: '${kebabName}'` -const toServiceFile = toFile(({ lib, folder, fileName, language }) => [ +const toServiceFile = toFile(({ lib, folder, fileName }) => [ lib, 'services', ...folder, - `${fileName}.${language}` + `${fileName}.service` +]) + +const toClassFile = toFile(({ lib, folder, fileName }) => [ + lib, + 'services', + ...folder, + `${fileName}.class` ]) 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(injectSource(classCode, append(), toClassFile)) + .then(injectSource(importTemplate, prepend(), toClassFile)) + .then(injectSource(optionTemplate, after('const options ='), toServiceFile, false)) .then( renderSource( migrationTemplate, diff --git a/packages/cli/src/service/type/mongodb.tpl.ts b/packages/cli/src/service/type/mongodb.tpl.ts index b4d9959f72..3f21dcf9ab 100644 --- a/packages/cli/src/service/type/mongodb.tpl.ts +++ b/packages/cli/src/service/type/mongodb.tpl.ts @@ -1,5 +1,5 @@ -import { generator, inject, toFile, before, after, prepend } from '@feathershq/pinion' -import { getSource } from '../../commons' +import { generator, toFile, after, prepend, append } from '@feathershq/pinion' +import { injectSource } from '../../commons' import { ServiceGeneratorContext } from '../index' export const importTemplate = `import { MongoDBService } from \'@feathersjs/mongodb\' @@ -18,17 +18,22 @@ const optionTemplate = ({ kebabName }: ServiceGeneratorContext) => ` paginate: app.get('paginate'), Model: app.get('mongodbClient').then(db => db.collection('${kebabName}'))` -const toServiceFile = toFile(({ lib, folder, fileName, language }) => [ +const toServiceFile = toFile(({ lib, folder, fileName }) => [ lib, 'services', ...folder, - `${fileName}.${language}` + `${fileName}.service` +]) + +const toClassFile = toFile(({ lib, folder, fileName }) => [ + lib, + 'services', + ...folder, + `${fileName}.class` ]) 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(injectSource(classCode, append(), toClassFile)) + .then(injectSource(importTemplate, prepend(), toClassFile)) + .then(injectSource(optionTemplate, after('const options ='), toServiceFile, false))