@feathersjs/generators 5.0.28 → 5.0.29
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +6 -0
- package/lib/app/index.js +1 -2
- package/lib/app/index.js.map +1 -1
- package/lib/app/templates/gitignore.tpl.d.ts +5 -0
- package/lib/app/templates/gitignore.tpl.js +125 -0
- package/lib/app/templates/gitignore.tpl.js.map +1 -0
- package/package.json +20 -21
- package/lib/app/index.ts +0 -215
- package/lib/app/templates/app.test.tpl.ts +0 -50
- package/lib/app/templates/app.tpl.ts +0 -141
- package/lib/app/templates/channels.tpl.ts +0 -54
- package/lib/app/templates/client.test.tpl.ts +0 -28
- package/lib/app/templates/client.tpl.ts +0 -53
- package/lib/app/templates/configuration.tpl.ts +0 -89
- package/lib/app/templates/declarations.tpl.ts +0 -42
- package/lib/app/templates/index.html.tpl.ts +0 -44
- package/lib/app/templates/index.tpl.ts +0 -26
- package/lib/app/templates/logger.tpl.ts +0 -56
- package/lib/app/templates/package.json.tpl.ts +0 -78
- package/lib/app/templates/prettierrc.tpl.ts +0 -14
- package/lib/app/templates/readme.md.tpl.ts +0 -57
- package/lib/app/templates/services.tpl.ts +0 -20
- package/lib/app/templates/tsconfig.json.tpl.ts +0 -29
- package/lib/app/templates/validators.tpl.ts +0 -39
- package/lib/authentication/index.ts +0 -119
- package/lib/authentication/templates/authentication.tpl.ts +0 -52
- package/lib/authentication/templates/client.test.tpl.ts +0 -78
- package/lib/authentication/templates/config.tpl.ts +0 -60
- package/lib/authentication/templates/declarations.tpl.ts +0 -38
- package/lib/commons.ts +0 -346
- package/lib/connection/index.ts +0 -138
- package/lib/connection/templates/knex.tpl.ts +0 -73
- package/lib/connection/templates/mongodb.tpl.ts +0 -50
- package/lib/hook/index.ts +0 -52
- package/lib/hook/templates/hook.tpl.ts +0 -33
- package/lib/index.ts +0 -8
- package/lib/service/index.ts +0 -214
- package/lib/service/templates/client.tpl.ts +0 -33
- package/lib/service/templates/schema.json.tpl.ts +0 -143
- package/lib/service/templates/schema.typebox.tpl.ts +0 -131
- package/lib/service/templates/service.tpl.ts +0 -161
- package/lib/service/templates/shared.tpl.ts +0 -64
- package/lib/service/templates/test.tpl.ts +0 -33
- package/lib/service/type/custom.tpl.ts +0 -112
- package/lib/service/type/knex.tpl.ts +0 -105
- package/lib/service/type/mongodb.tpl.ts +0 -64
package/lib/connection/index.ts
DELETED
|
@@ -1,138 +0,0 @@
|
|
|
1
|
-
import { dirname } from 'path'
|
|
2
|
-
import { runGenerator, prompt, mergeJSON, toFile, when } from '@featherscloud/pinion'
|
|
3
|
-
import { fileURLToPath } from 'url'
|
|
4
|
-
import chalk from 'chalk'
|
|
5
|
-
import {
|
|
6
|
-
install,
|
|
7
|
-
FeathersBaseContext,
|
|
8
|
-
DatabaseType,
|
|
9
|
-
getDatabaseAdapter,
|
|
10
|
-
addVersions,
|
|
11
|
-
checkPreconditions,
|
|
12
|
-
initializeBaseContext
|
|
13
|
-
} from '../commons.js'
|
|
14
|
-
|
|
15
|
-
// Set __dirname in es module
|
|
16
|
-
const __dirname = dirname(fileURLToPath(import.meta.url))
|
|
17
|
-
|
|
18
|
-
export interface ConnectionGeneratorContext extends FeathersBaseContext {
|
|
19
|
-
name?: string
|
|
20
|
-
database: DatabaseType
|
|
21
|
-
connectionString: string
|
|
22
|
-
dependencies: string[]
|
|
23
|
-
}
|
|
24
|
-
|
|
25
|
-
export type ConnectionGeneratorArguments = FeathersBaseContext &
|
|
26
|
-
Partial<Pick<ConnectionGeneratorContext, 'database' | 'connectionString' | 'name'>>
|
|
27
|
-
|
|
28
|
-
export const defaultConnectionString = (type: DatabaseType, name: string) => {
|
|
29
|
-
const connectionStrings = {
|
|
30
|
-
mongodb: `mongodb://127.0.0.1:27017/${name}`,
|
|
31
|
-
mysql: `mysql://root:@localhost:3306/${name}`,
|
|
32
|
-
postgresql: `postgres://postgres:@localhost:5432/${name}`,
|
|
33
|
-
sqlite: `${name}.sqlite`,
|
|
34
|
-
mssql: `mssql://root:password@localhost:1433/${name}`,
|
|
35
|
-
other: ''
|
|
36
|
-
}
|
|
37
|
-
|
|
38
|
-
return connectionStrings[type]
|
|
39
|
-
}
|
|
40
|
-
|
|
41
|
-
export const prompts = ({ database, connectionString, pkg, name }: ConnectionGeneratorArguments) => [
|
|
42
|
-
{
|
|
43
|
-
name: 'database',
|
|
44
|
-
type: 'list',
|
|
45
|
-
when: !database,
|
|
46
|
-
message: 'Which database are you connecting to?',
|
|
47
|
-
suffix: chalk.grey(' Databases can be added at any time'),
|
|
48
|
-
choices: [
|
|
49
|
-
{ value: 'sqlite', name: 'SQLite' },
|
|
50
|
-
{ value: 'mongodb', name: 'MongoDB' },
|
|
51
|
-
{ value: 'postgresql', name: 'PostgreSQL' },
|
|
52
|
-
{ value: 'mysql', name: 'MySQL/MariaDB' },
|
|
53
|
-
{ value: 'mssql', name: 'Microsoft SQL' },
|
|
54
|
-
{
|
|
55
|
-
value: 'other',
|
|
56
|
-
name: `Another database ${chalk.grey('(not configured automatically, use with custom services)')}`
|
|
57
|
-
}
|
|
58
|
-
]
|
|
59
|
-
},
|
|
60
|
-
{
|
|
61
|
-
name: 'connectionString',
|
|
62
|
-
type: 'input',
|
|
63
|
-
when: (answers: ConnectionGeneratorContext) =>
|
|
64
|
-
!connectionString && database !== 'other' && answers.database !== 'other',
|
|
65
|
-
message: 'Enter your database connection string',
|
|
66
|
-
default: (answers: ConnectionGeneratorContext) =>
|
|
67
|
-
defaultConnectionString(answers.database, answers.name || name || pkg.name)
|
|
68
|
-
}
|
|
69
|
-
]
|
|
70
|
-
|
|
71
|
-
export const DATABASE_CLIENTS = {
|
|
72
|
-
mongodb: 'mongodb',
|
|
73
|
-
sqlite: 'sqlite3',
|
|
74
|
-
postgresql: 'pg',
|
|
75
|
-
mysql: 'mysql',
|
|
76
|
-
mssql: 'mssql'
|
|
77
|
-
}
|
|
78
|
-
|
|
79
|
-
export const getDatabaseClient = (database: DatabaseType) =>
|
|
80
|
-
database === 'other' ? null : DATABASE_CLIENTS[database]
|
|
81
|
-
|
|
82
|
-
export const generate = (ctx: ConnectionGeneratorArguments) =>
|
|
83
|
-
Promise.resolve(ctx)
|
|
84
|
-
.then(initializeBaseContext())
|
|
85
|
-
.then(checkPreconditions())
|
|
86
|
-
.then(prompt(prompts))
|
|
87
|
-
.then((ctx) => ctx as ConnectionGeneratorContext)
|
|
88
|
-
.then(
|
|
89
|
-
when<ConnectionGeneratorContext>(
|
|
90
|
-
(ctx) => ctx.database !== 'other',
|
|
91
|
-
runGenerator<ConnectionGeneratorContext>(
|
|
92
|
-
__dirname,
|
|
93
|
-
'templates',
|
|
94
|
-
({ database }) => `${getDatabaseAdapter(database)}.tpl.js`
|
|
95
|
-
),
|
|
96
|
-
mergeJSON<ConnectionGeneratorContext>(
|
|
97
|
-
({ connectionString, database }) =>
|
|
98
|
-
getDatabaseAdapter(database) === 'knex'
|
|
99
|
-
? {
|
|
100
|
-
[database]: {
|
|
101
|
-
client: getDatabaseClient(database),
|
|
102
|
-
connection: connectionString,
|
|
103
|
-
...(database === 'sqlite' ? { useNullAsDefault: true } : {})
|
|
104
|
-
}
|
|
105
|
-
}
|
|
106
|
-
: {
|
|
107
|
-
[database]: connectionString
|
|
108
|
-
},
|
|
109
|
-
toFile('config', 'default.json')
|
|
110
|
-
),
|
|
111
|
-
async (ctx: ConnectionGeneratorContext) => {
|
|
112
|
-
const dependencies: string[] = []
|
|
113
|
-
const adapter = getDatabaseAdapter(ctx.database)
|
|
114
|
-
const dbClient = getDatabaseClient(ctx.database)
|
|
115
|
-
|
|
116
|
-
dependencies.push(`@feathersjs/${adapter}`)
|
|
117
|
-
|
|
118
|
-
if (adapter === 'knex') {
|
|
119
|
-
dependencies.push('knex')
|
|
120
|
-
}
|
|
121
|
-
|
|
122
|
-
dependencies.push(dbClient)
|
|
123
|
-
|
|
124
|
-
if (ctx.dependencies) {
|
|
125
|
-
return {
|
|
126
|
-
...ctx,
|
|
127
|
-
dependencies: [...ctx.dependencies, ...dependencies]
|
|
128
|
-
}
|
|
129
|
-
}
|
|
130
|
-
|
|
131
|
-
return install<ConnectionGeneratorContext>(
|
|
132
|
-
addVersions(dependencies, ctx.dependencyVersions),
|
|
133
|
-
false,
|
|
134
|
-
ctx.feathers.packager
|
|
135
|
-
)(ctx)
|
|
136
|
-
}
|
|
137
|
-
)
|
|
138
|
-
)
|
|
@@ -1,73 +0,0 @@
|
|
|
1
|
-
import { toFile, before, mergeJSON } from '@featherscloud/pinion'
|
|
2
|
-
import { ConnectionGeneratorContext } from '../index.js'
|
|
3
|
-
import { injectSource, renderSource } from '../../commons.js'
|
|
4
|
-
import { mkdir } from 'fs/promises'
|
|
5
|
-
import path from 'path'
|
|
6
|
-
|
|
7
|
-
const template = ({
|
|
8
|
-
database
|
|
9
|
-
}: ConnectionGeneratorContext) => /* ts */ `// For more information about this file see https://dove.feathersjs.com/guides/cli/databases.html
|
|
10
|
-
import knex from 'knex'
|
|
11
|
-
import type { Knex } from 'knex'
|
|
12
|
-
import type { Application } from './declarations'
|
|
13
|
-
|
|
14
|
-
declare module './declarations' {
|
|
15
|
-
interface Configuration {
|
|
16
|
-
${database}Client: Knex
|
|
17
|
-
}
|
|
18
|
-
}
|
|
19
|
-
|
|
20
|
-
export const ${database} = (app: Application) => {
|
|
21
|
-
const config = app.get('${database}')
|
|
22
|
-
const db = knex(config!)
|
|
23
|
-
|
|
24
|
-
app.set('${database}Client', db)
|
|
25
|
-
}
|
|
26
|
-
`
|
|
27
|
-
|
|
28
|
-
const knexfile = ({
|
|
29
|
-
lib,
|
|
30
|
-
language,
|
|
31
|
-
database
|
|
32
|
-
}: ConnectionGeneratorContext) => /* ts */ `// For more information about this file see https://dove.feathersjs.com/guides/cli/databases.html
|
|
33
|
-
import { app } from './${lib}/app'
|
|
34
|
-
|
|
35
|
-
// Load our database connection info from the app configuration
|
|
36
|
-
const config = app.get('${database}')
|
|
37
|
-
|
|
38
|
-
${language === 'js' ? 'export default config' : 'module.exports = config'}
|
|
39
|
-
`
|
|
40
|
-
|
|
41
|
-
const importTemplate = ({ database }: ConnectionGeneratorContext) =>
|
|
42
|
-
`import { ${database} } from './${database}'`
|
|
43
|
-
const configureTemplate = ({ database }: ConnectionGeneratorContext) => `app.configure(${database})`
|
|
44
|
-
|
|
45
|
-
const toAppFile = toFile<ConnectionGeneratorContext>(({ lib }) => [lib, 'app'])
|
|
46
|
-
|
|
47
|
-
export const generate = (ctx: ConnectionGeneratorContext) =>
|
|
48
|
-
Promise.resolve(ctx)
|
|
49
|
-
.then(
|
|
50
|
-
renderSource(
|
|
51
|
-
template,
|
|
52
|
-
toFile<ConnectionGeneratorContext>(({ lib, database }) => [lib, database])
|
|
53
|
-
)
|
|
54
|
-
)
|
|
55
|
-
.then(renderSource(knexfile, toFile('knexfile')))
|
|
56
|
-
.then(
|
|
57
|
-
mergeJSON<ConnectionGeneratorContext>(
|
|
58
|
-
(ctx) => ({
|
|
59
|
-
scripts: {
|
|
60
|
-
migrate: 'knex migrate:latest',
|
|
61
|
-
'migrate:make': 'knex migrate:make' + (ctx.language === 'js' ? ' -x mjs' : ''),
|
|
62
|
-
test: 'cross-env NODE_ENV=test npm run migrate && npm run mocha'
|
|
63
|
-
}
|
|
64
|
-
}),
|
|
65
|
-
toFile('package.json')
|
|
66
|
-
)
|
|
67
|
-
)
|
|
68
|
-
.then(injectSource(importTemplate, before('import { services } from'), toAppFile))
|
|
69
|
-
.then(injectSource(configureTemplate, before('app.configure(services)'), toAppFile))
|
|
70
|
-
.then(async (ctx) => {
|
|
71
|
-
await mkdir(path.join(ctx.cwd, 'migrations'))
|
|
72
|
-
return ctx
|
|
73
|
-
})
|
|
@@ -1,50 +0,0 @@
|
|
|
1
|
-
import { toFile, before, prepend, append } from '@featherscloud/pinion'
|
|
2
|
-
import { ConnectionGeneratorContext } from '../index.js'
|
|
3
|
-
import { injectSource, renderSource } from '../../commons.js'
|
|
4
|
-
|
|
5
|
-
const template = ({
|
|
6
|
-
database
|
|
7
|
-
}: ConnectionGeneratorContext) => /* ts */ `// For more information about this file see https://dove.feathersjs.com/guides/cli/databases.html
|
|
8
|
-
import { MongoClient } from 'mongodb'
|
|
9
|
-
import type { Db } from 'mongodb'
|
|
10
|
-
import type { Application } from './declarations'
|
|
11
|
-
|
|
12
|
-
declare module './declarations' {
|
|
13
|
-
interface Configuration {
|
|
14
|
-
${database}Client: Promise<Db>
|
|
15
|
-
}
|
|
16
|
-
}
|
|
17
|
-
|
|
18
|
-
export const ${database} = (app: Application) => {
|
|
19
|
-
const connection = app.get('${database}') as string
|
|
20
|
-
const database = new URL(connection).pathname.substring(1)
|
|
21
|
-
const mongoClient = MongoClient.connect(connection)
|
|
22
|
-
.then(client => client.db(database))
|
|
23
|
-
|
|
24
|
-
app.set('${database}Client', mongoClient)
|
|
25
|
-
}
|
|
26
|
-
`
|
|
27
|
-
|
|
28
|
-
const keywordImport = `import { keywordObjectId } from '@feathersjs/mongodb'`
|
|
29
|
-
|
|
30
|
-
const keywordTemplate = `dataValidator.addKeyword(keywordObjectId)
|
|
31
|
-
queryValidator.addKeyword(keywordObjectId)`
|
|
32
|
-
|
|
33
|
-
const importTemplate = ({ database }: ConnectionGeneratorContext) =>
|
|
34
|
-
`import { ${database} } from './${database}'`
|
|
35
|
-
const configureTemplate = ({ database }: ConnectionGeneratorContext) => `app.configure(${database})`
|
|
36
|
-
const toAppFile = toFile<ConnectionGeneratorContext>(({ lib }) => [lib, 'app'])
|
|
37
|
-
const toValidatorFile = toFile<ConnectionGeneratorContext>(({ lib }) => [lib, 'validators'])
|
|
38
|
-
|
|
39
|
-
export const generate = (ctx: ConnectionGeneratorContext) =>
|
|
40
|
-
Promise.resolve(ctx)
|
|
41
|
-
.then(
|
|
42
|
-
renderSource(
|
|
43
|
-
template,
|
|
44
|
-
toFile<ConnectionGeneratorContext>(({ lib, database }) => [lib, database])
|
|
45
|
-
)
|
|
46
|
-
)
|
|
47
|
-
.then(injectSource(importTemplate, before('import { services } from'), toAppFile))
|
|
48
|
-
.then(injectSource(configureTemplate, before('app.configure(services)'), toAppFile))
|
|
49
|
-
.then(injectSource(keywordImport, prepend(), toValidatorFile))
|
|
50
|
-
.then(injectSource(keywordTemplate, append(), toValidatorFile))
|
package/lib/hook/index.ts
DELETED
|
@@ -1,52 +0,0 @@
|
|
|
1
|
-
import { dirname } from 'path'
|
|
2
|
-
import { fileURLToPath } from 'url'
|
|
3
|
-
import { prompt, runGenerators } from '@featherscloud/pinion'
|
|
4
|
-
import _ from 'lodash'
|
|
5
|
-
import { checkPreconditions, FeathersBaseContext, initializeBaseContext } from '../commons.js'
|
|
6
|
-
|
|
7
|
-
// Set __dirname in es module
|
|
8
|
-
const __dirname = dirname(fileURLToPath(import.meta.url))
|
|
9
|
-
|
|
10
|
-
export interface HookGeneratorContext extends FeathersBaseContext {
|
|
11
|
-
name: string
|
|
12
|
-
camelName: string
|
|
13
|
-
kebabName: string
|
|
14
|
-
type: 'regular' | 'around'
|
|
15
|
-
}
|
|
16
|
-
|
|
17
|
-
export const generate = (ctx: HookGeneratorContext) =>
|
|
18
|
-
Promise.resolve(ctx)
|
|
19
|
-
.then(initializeBaseContext())
|
|
20
|
-
.then(checkPreconditions())
|
|
21
|
-
.then(
|
|
22
|
-
prompt<HookGeneratorContext>(({ type, name }) => [
|
|
23
|
-
{
|
|
24
|
-
type: 'input',
|
|
25
|
-
name: 'name',
|
|
26
|
-
message: 'What is the name of the hook?',
|
|
27
|
-
when: !name
|
|
28
|
-
},
|
|
29
|
-
{
|
|
30
|
-
name: 'type',
|
|
31
|
-
type: 'list',
|
|
32
|
-
when: !type,
|
|
33
|
-
message: 'What kind of hook is it?',
|
|
34
|
-
choices: [
|
|
35
|
-
{ value: 'around', name: 'Around' },
|
|
36
|
-
{ value: 'regular', name: 'Before, After or Error' }
|
|
37
|
-
]
|
|
38
|
-
}
|
|
39
|
-
])
|
|
40
|
-
)
|
|
41
|
-
.then((ctx) => {
|
|
42
|
-
const { name } = ctx
|
|
43
|
-
const kebabName = _.kebabCase(name)
|
|
44
|
-
const camelName = _.camelCase(name)
|
|
45
|
-
|
|
46
|
-
return {
|
|
47
|
-
...ctx,
|
|
48
|
-
kebabName,
|
|
49
|
-
camelName
|
|
50
|
-
}
|
|
51
|
-
})
|
|
52
|
-
.then(runGenerators(__dirname, 'templates'))
|
|
@@ -1,33 +0,0 @@
|
|
|
1
|
-
import { toFile } from '@featherscloud/pinion'
|
|
2
|
-
import { HookGeneratorContext } from '../index.js'
|
|
3
|
-
import { renderSource } from '../../commons.js'
|
|
4
|
-
|
|
5
|
-
const aroundTemplate = ({
|
|
6
|
-
camelName,
|
|
7
|
-
name
|
|
8
|
-
}: HookGeneratorContext) => /* ts */ `// For more information about this file see https://dove.feathersjs.com/guides/cli/hook.html
|
|
9
|
-
import type { HookContext, NextFunction } from '../declarations'
|
|
10
|
-
|
|
11
|
-
export const ${camelName} = async (context: HookContext, next: NextFunction) => {
|
|
12
|
-
console.log(\`Running hook ${name} on \${context.path}\.\${context.method}\`)
|
|
13
|
-
await next()
|
|
14
|
-
}
|
|
15
|
-
`
|
|
16
|
-
|
|
17
|
-
const regularTemplate = ({
|
|
18
|
-
camelName,
|
|
19
|
-
name
|
|
20
|
-
}: HookGeneratorContext) => /* ts */ `// For more information about this file see https://dove.feathersjs.com/guides/cli/hook.html
|
|
21
|
-
import type { HookContext } from '../declarations'
|
|
22
|
-
|
|
23
|
-
export const ${camelName} = async (context: HookContext) => {
|
|
24
|
-
console.log(\`Running hook ${name} on \${context.path}\.\${context.method}\`)
|
|
25
|
-
}`
|
|
26
|
-
|
|
27
|
-
export const generate = (ctx: HookGeneratorContext) =>
|
|
28
|
-
Promise.resolve(ctx).then(
|
|
29
|
-
renderSource(
|
|
30
|
-
(ctx) => (ctx.type === 'around' ? aroundTemplate(ctx) : regularTemplate(ctx)),
|
|
31
|
-
toFile<HookGeneratorContext>(({ lib, kebabName }) => [lib, 'hooks', kebabName])
|
|
32
|
-
)
|
|
33
|
-
)
|
package/lib/index.ts
DELETED
|
@@ -1,8 +0,0 @@
|
|
|
1
|
-
export * from '@featherscloud/pinion'
|
|
2
|
-
|
|
3
|
-
export * from './commons.js'
|
|
4
|
-
export * as app from './app/index.js'
|
|
5
|
-
export * as authentication from './authentication/index.js'
|
|
6
|
-
export * as connection from './connection/index.js'
|
|
7
|
-
export * as hook from './hook/index.js'
|
|
8
|
-
export * as service from './service/index.js'
|
package/lib/service/index.ts
DELETED
|
@@ -1,214 +0,0 @@
|
|
|
1
|
-
import { dirname } from 'path'
|
|
2
|
-
import _ from 'lodash'
|
|
3
|
-
import { runGenerator, runGenerators, prompt } from '@featherscloud/pinion'
|
|
4
|
-
import { fileURLToPath } from 'url'
|
|
5
|
-
import chalk from 'chalk'
|
|
6
|
-
|
|
7
|
-
import {
|
|
8
|
-
checkPreconditions,
|
|
9
|
-
DATABASE_TYPES,
|
|
10
|
-
FeathersBaseContext,
|
|
11
|
-
fileExists,
|
|
12
|
-
getDatabaseAdapter,
|
|
13
|
-
initializeBaseContext
|
|
14
|
-
} from '../commons.js'
|
|
15
|
-
|
|
16
|
-
// Set __dirname in es module
|
|
17
|
-
const __dirname = dirname(fileURLToPath(import.meta.url))
|
|
18
|
-
|
|
19
|
-
export interface ServiceGeneratorContext extends FeathersBaseContext {
|
|
20
|
-
/**
|
|
21
|
-
* The chosen service name
|
|
22
|
-
*/
|
|
23
|
-
name: string
|
|
24
|
-
/**
|
|
25
|
-
* The path the service is registered on
|
|
26
|
-
*/
|
|
27
|
-
path: string
|
|
28
|
-
/**
|
|
29
|
-
* The list of subfolders this service is in
|
|
30
|
-
*/
|
|
31
|
-
folder: string[]
|
|
32
|
-
/**
|
|
33
|
-
* The `camelCase` service name starting with a lowercase letter
|
|
34
|
-
*/
|
|
35
|
-
camelName: string
|
|
36
|
-
/**
|
|
37
|
-
* The `CamelCase` service name starting with an uppercase letter
|
|
38
|
-
*/
|
|
39
|
-
upperName: string
|
|
40
|
-
/**
|
|
41
|
-
* The service class name combined as `CamelCaseService`
|
|
42
|
-
*/
|
|
43
|
-
className: string
|
|
44
|
-
/**
|
|
45
|
-
* A kebab-cased (filename friendly) version of the service name
|
|
46
|
-
*/
|
|
47
|
-
kebabName: string
|
|
48
|
-
/**
|
|
49
|
-
* The actual filename (the last element of the path)
|
|
50
|
-
*/
|
|
51
|
-
fileName: string
|
|
52
|
-
/**
|
|
53
|
-
* The kebab-cased name of the path. Will be used for e.g. database names
|
|
54
|
-
*/
|
|
55
|
-
kebabPath: string
|
|
56
|
-
/**
|
|
57
|
-
* Indicates how many file paths we should go up to import other things (e.g. `../../`)
|
|
58
|
-
*/
|
|
59
|
-
relative: string
|
|
60
|
-
/**
|
|
61
|
-
* The chosen service type
|
|
62
|
-
*/
|
|
63
|
-
type: 'knex' | 'mongodb' | 'custom'
|
|
64
|
-
/**
|
|
65
|
-
* Which schema definition format to use
|
|
66
|
-
*/
|
|
67
|
-
schema: 'typebox' | 'json' | false
|
|
68
|
-
/**
|
|
69
|
-
* Wether this service uses authentication
|
|
70
|
-
*/
|
|
71
|
-
authentication: boolean
|
|
72
|
-
/**
|
|
73
|
-
* Set to true if this service is for an authentication entity
|
|
74
|
-
*/
|
|
75
|
-
isEntityService?: boolean
|
|
76
|
-
/**
|
|
77
|
-
* The authentication strategies (if it is an entity service)
|
|
78
|
-
*/
|
|
79
|
-
authStrategies: string[]
|
|
80
|
-
}
|
|
81
|
-
|
|
82
|
-
/**
|
|
83
|
-
* Parameters the generator is called with
|
|
84
|
-
*/
|
|
85
|
-
export type ServiceGeneratorArguments = FeathersBaseContext &
|
|
86
|
-
Partial<
|
|
87
|
-
Pick<ServiceGeneratorContext, 'name' | 'path' | 'type' | 'authentication' | 'isEntityService' | 'schema'>
|
|
88
|
-
>
|
|
89
|
-
|
|
90
|
-
export const generate = (ctx: ServiceGeneratorArguments) =>
|
|
91
|
-
Promise.resolve(ctx)
|
|
92
|
-
.then(initializeBaseContext())
|
|
93
|
-
.then(checkPreconditions())
|
|
94
|
-
.then(
|
|
95
|
-
prompt(({ name, path, type, schema, authentication, isEntityService, feathers, lib, language }) => {
|
|
96
|
-
const sqlDisabled = DATABASE_TYPES.every(
|
|
97
|
-
(name) => name === 'mongodb' || name === 'other' || !fileExists(lib, `${name}.${language}`)
|
|
98
|
-
)
|
|
99
|
-
const mongodbDisabled = !fileExists(lib, `mongodb.${language}`)
|
|
100
|
-
|
|
101
|
-
return [
|
|
102
|
-
{
|
|
103
|
-
name: 'name',
|
|
104
|
-
type: 'input',
|
|
105
|
-
when: !name,
|
|
106
|
-
message: 'What is the name of your service?',
|
|
107
|
-
validate: (input: any) => {
|
|
108
|
-
if (!input || input === 'authentication') {
|
|
109
|
-
return 'Invalid service name'
|
|
110
|
-
}
|
|
111
|
-
|
|
112
|
-
return true
|
|
113
|
-
}
|
|
114
|
-
},
|
|
115
|
-
{
|
|
116
|
-
name: 'path',
|
|
117
|
-
type: 'input',
|
|
118
|
-
when: !path,
|
|
119
|
-
message: 'Which path should the service be registered on?',
|
|
120
|
-
default: (answers: ServiceGeneratorArguments) => `${_.kebabCase(answers.name)}`,
|
|
121
|
-
validate: (input: any) => {
|
|
122
|
-
if (!input || input === 'authentication') {
|
|
123
|
-
return 'Invalid service path'
|
|
124
|
-
}
|
|
125
|
-
|
|
126
|
-
return true
|
|
127
|
-
}
|
|
128
|
-
},
|
|
129
|
-
{
|
|
130
|
-
name: 'authentication',
|
|
131
|
-
type: 'confirm',
|
|
132
|
-
when: authentication === undefined && !isEntityService,
|
|
133
|
-
message: 'Does this service require authentication?'
|
|
134
|
-
},
|
|
135
|
-
{
|
|
136
|
-
name: 'type',
|
|
137
|
-
type: 'list',
|
|
138
|
-
when: !type,
|
|
139
|
-
message: 'What database is the service using?',
|
|
140
|
-
default: getDatabaseAdapter(feathers?.database),
|
|
141
|
-
choices: [
|
|
142
|
-
{
|
|
143
|
-
value: 'knex',
|
|
144
|
-
name: `SQL${sqlDisabled ? chalk.gray(' (connection not available)') : ''}`,
|
|
145
|
-
disabled: sqlDisabled
|
|
146
|
-
},
|
|
147
|
-
{
|
|
148
|
-
value: 'mongodb',
|
|
149
|
-
name: `MongoDB${mongodbDisabled ? chalk.gray(' (connection not available)') : ''}`,
|
|
150
|
-
disabled: mongodbDisabled
|
|
151
|
-
},
|
|
152
|
-
{
|
|
153
|
-
value: 'custom',
|
|
154
|
-
name: 'A custom service'
|
|
155
|
-
}
|
|
156
|
-
]
|
|
157
|
-
},
|
|
158
|
-
{
|
|
159
|
-
name: 'schema',
|
|
160
|
-
type: 'list',
|
|
161
|
-
when: schema === undefined,
|
|
162
|
-
message: 'Which schema definition format do you want to use?',
|
|
163
|
-
suffix: chalk.grey(' Schemas allow to type, validate, secure and populate data'),
|
|
164
|
-
default: feathers?.schema,
|
|
165
|
-
choices: (answers: ServiceGeneratorContext) => [
|
|
166
|
-
{
|
|
167
|
-
value: 'typebox',
|
|
168
|
-
name: `TypeBox ${chalk.gray(' (recommended)')}`
|
|
169
|
-
},
|
|
170
|
-
{
|
|
171
|
-
value: 'json',
|
|
172
|
-
name: 'JSON schema'
|
|
173
|
-
},
|
|
174
|
-
{
|
|
175
|
-
value: false,
|
|
176
|
-
name: `No schema${
|
|
177
|
-
answers.type !== 'custom' ? chalk.gray(' (not recommended with a database)') : ''
|
|
178
|
-
}`
|
|
179
|
-
}
|
|
180
|
-
]
|
|
181
|
-
}
|
|
182
|
-
]
|
|
183
|
-
})
|
|
184
|
-
)
|
|
185
|
-
.then(async (ctx): Promise<ServiceGeneratorContext> => {
|
|
186
|
-
const { name, path, type, authStrategies = [] } = ctx as any as ServiceGeneratorContext
|
|
187
|
-
const kebabName = _.kebabCase(name)
|
|
188
|
-
const camelName = _.camelCase(name)
|
|
189
|
-
const upperName = _.upperFirst(camelName)
|
|
190
|
-
const className = `${upperName}Service`
|
|
191
|
-
|
|
192
|
-
const folder = path.split('/').filter((el) => el !== '')
|
|
193
|
-
const relative = ['', ...folder].map(() => '..').join('/')
|
|
194
|
-
const fileName = _.last(folder)
|
|
195
|
-
const kebabPath = _.kebabCase(path)
|
|
196
|
-
|
|
197
|
-
return {
|
|
198
|
-
name,
|
|
199
|
-
type,
|
|
200
|
-
path,
|
|
201
|
-
folder,
|
|
202
|
-
fileName,
|
|
203
|
-
upperName,
|
|
204
|
-
className,
|
|
205
|
-
kebabName,
|
|
206
|
-
camelName,
|
|
207
|
-
kebabPath,
|
|
208
|
-
relative,
|
|
209
|
-
authStrategies,
|
|
210
|
-
...ctx
|
|
211
|
-
} as ServiceGeneratorContext
|
|
212
|
-
})
|
|
213
|
-
.then(runGenerators<ServiceGeneratorContext>(__dirname, 'templates'))
|
|
214
|
-
.then(runGenerator<ServiceGeneratorContext>(__dirname, 'type', ({ type }) => `${type}.tpl.js`))
|
|
@@ -1,33 +0,0 @@
|
|
|
1
|
-
import { toFile, after, before, when } from '@featherscloud/pinion'
|
|
2
|
-
import { fileExists, injectSource } from '../../commons.js'
|
|
3
|
-
import { ServiceGeneratorContext } from '../index.js'
|
|
4
|
-
|
|
5
|
-
const importTemplate = ({ upperName, folder, fileName, camelName }: ServiceGeneratorContext) => /* ts */ `
|
|
6
|
-
import { ${camelName}Client } from './services/${folder.join('/')}/${fileName}.shared'
|
|
7
|
-
export type {
|
|
8
|
-
${upperName},
|
|
9
|
-
${upperName}Data,
|
|
10
|
-
${upperName}Query,
|
|
11
|
-
${upperName}Patch
|
|
12
|
-
} from './services/${folder.join('/')}/${fileName}.shared'
|
|
13
|
-
`
|
|
14
|
-
|
|
15
|
-
const registrationTemplate = ({ camelName }: ServiceGeneratorContext) =>
|
|
16
|
-
` client.configure(${camelName}Client)`
|
|
17
|
-
|
|
18
|
-
const toClientFile = toFile<ServiceGeneratorContext>(({ lib }) => [lib, 'client'])
|
|
19
|
-
|
|
20
|
-
export const generate = async (ctx: ServiceGeneratorContext) =>
|
|
21
|
-
Promise.resolve(ctx).then(
|
|
22
|
-
when<ServiceGeneratorContext>(
|
|
23
|
-
({ lib, language }) => fileExists(lib, `client.${language}`),
|
|
24
|
-
injectSource(registrationTemplate, before('return client'), toClientFile),
|
|
25
|
-
injectSource(
|
|
26
|
-
importTemplate,
|
|
27
|
-
after<ServiceGeneratorContext>(({ language }) =>
|
|
28
|
-
language === 'ts' ? 'import type { AuthenticationClientOptions }' : 'import authenticationClient'
|
|
29
|
-
),
|
|
30
|
-
toClientFile
|
|
31
|
-
)
|
|
32
|
-
)
|
|
33
|
-
)
|