@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.
Files changed (46) hide show
  1. package/CHANGELOG.md +6 -0
  2. package/lib/app/index.js +1 -2
  3. package/lib/app/index.js.map +1 -1
  4. package/lib/app/templates/gitignore.tpl.d.ts +5 -0
  5. package/lib/app/templates/gitignore.tpl.js +125 -0
  6. package/lib/app/templates/gitignore.tpl.js.map +1 -0
  7. package/package.json +20 -21
  8. package/lib/app/index.ts +0 -215
  9. package/lib/app/templates/app.test.tpl.ts +0 -50
  10. package/lib/app/templates/app.tpl.ts +0 -141
  11. package/lib/app/templates/channels.tpl.ts +0 -54
  12. package/lib/app/templates/client.test.tpl.ts +0 -28
  13. package/lib/app/templates/client.tpl.ts +0 -53
  14. package/lib/app/templates/configuration.tpl.ts +0 -89
  15. package/lib/app/templates/declarations.tpl.ts +0 -42
  16. package/lib/app/templates/index.html.tpl.ts +0 -44
  17. package/lib/app/templates/index.tpl.ts +0 -26
  18. package/lib/app/templates/logger.tpl.ts +0 -56
  19. package/lib/app/templates/package.json.tpl.ts +0 -78
  20. package/lib/app/templates/prettierrc.tpl.ts +0 -14
  21. package/lib/app/templates/readme.md.tpl.ts +0 -57
  22. package/lib/app/templates/services.tpl.ts +0 -20
  23. package/lib/app/templates/tsconfig.json.tpl.ts +0 -29
  24. package/lib/app/templates/validators.tpl.ts +0 -39
  25. package/lib/authentication/index.ts +0 -119
  26. package/lib/authentication/templates/authentication.tpl.ts +0 -52
  27. package/lib/authentication/templates/client.test.tpl.ts +0 -78
  28. package/lib/authentication/templates/config.tpl.ts +0 -60
  29. package/lib/authentication/templates/declarations.tpl.ts +0 -38
  30. package/lib/commons.ts +0 -346
  31. package/lib/connection/index.ts +0 -138
  32. package/lib/connection/templates/knex.tpl.ts +0 -73
  33. package/lib/connection/templates/mongodb.tpl.ts +0 -50
  34. package/lib/hook/index.ts +0 -52
  35. package/lib/hook/templates/hook.tpl.ts +0 -33
  36. package/lib/index.ts +0 -8
  37. package/lib/service/index.ts +0 -214
  38. package/lib/service/templates/client.tpl.ts +0 -33
  39. package/lib/service/templates/schema.json.tpl.ts +0 -143
  40. package/lib/service/templates/schema.typebox.tpl.ts +0 -131
  41. package/lib/service/templates/service.tpl.ts +0 -161
  42. package/lib/service/templates/shared.tpl.ts +0 -64
  43. package/lib/service/templates/test.tpl.ts +0 -33
  44. package/lib/service/type/custom.tpl.ts +0 -112
  45. package/lib/service/type/knex.tpl.ts +0 -105
  46. package/lib/service/type/mongodb.tpl.ts +0 -64
@@ -1,119 +0,0 @@
1
- import chalk from 'chalk'
2
- import { dirname } from 'path'
3
- import { runGenerators, prompt } from '@featherscloud/pinion'
4
- import { fileURLToPath } from 'url'
5
- import {
6
- addVersions,
7
- checkPreconditions,
8
- FeathersBaseContext,
9
- initializeBaseContext,
10
- install
11
- } from '../commons.js'
12
- import { generate as serviceGenerator, ServiceGeneratorContext } from '../service/index.js'
13
-
14
- // Set __dirname in es module
15
- const __dirname = dirname(fileURLToPath(import.meta.url))
16
-
17
- export interface AuthenticationGeneratorContext extends ServiceGeneratorContext {
18
- service: string
19
- entity: string
20
- authStrategies: string[]
21
- dependencies: string[]
22
- }
23
-
24
- export type AuthenticationGeneratorArguments = FeathersBaseContext &
25
- Partial<Pick<AuthenticationGeneratorContext, 'service' | 'authStrategies' | 'path' | 'schema' | 'type'>>
26
-
27
- export const generate = (ctx: AuthenticationGeneratorArguments) =>
28
- Promise.resolve(ctx)
29
- .then(initializeBaseContext())
30
- .then(checkPreconditions())
31
- .then(
32
- prompt((ctx: AuthenticationGeneratorArguments) => [
33
- {
34
- type: 'checkbox',
35
- name: 'authStrategies',
36
- when: !ctx.authStrategies,
37
- message: 'Which authentication methods do you want to use?',
38
- suffix: chalk.grey(' Other methods and providers can be added at any time.'),
39
- choices: [
40
- {
41
- name: 'Email + Password',
42
- value: 'local',
43
- checked: true
44
- },
45
- {
46
- name: 'Google',
47
- value: 'google'
48
- },
49
- {
50
- name: 'Facebook',
51
- value: 'facebook'
52
- },
53
- {
54
- name: 'Twitter',
55
- value: 'twitter'
56
- },
57
- {
58
- name: 'GitHub',
59
- value: 'github'
60
- },
61
- {
62
- name: 'Auth0',
63
- value: 'auth0'
64
- }
65
- ]
66
- },
67
- {
68
- name: 'service',
69
- type: 'input',
70
- when: !ctx.service,
71
- message: 'What is your authentication service name?',
72
- default: 'user'
73
- },
74
- {
75
- name: 'path',
76
- type: 'input',
77
- when: !ctx.path,
78
- message: 'What path should the service be registered on?',
79
- default: 'users'
80
- }
81
- ])
82
- )
83
- .then(async (ctx) => {
84
- const serviceContext = await serviceGenerator({
85
- ...ctx,
86
- name: ctx.service,
87
- isEntityService: true
88
- })
89
-
90
- return {
91
- ...ctx,
92
- entity: ctx.service,
93
- ...serviceContext
94
- }
95
- })
96
- .then(runGenerators(__dirname, 'templates'))
97
- .then((ctx) => ctx as AuthenticationGeneratorContext)
98
- .then((ctx) => {
99
- const dependencies: string[] = []
100
-
101
- dependencies.push('@feathersjs/authentication-oauth')
102
-
103
- if (ctx.authStrategies.includes('local')) {
104
- dependencies.push('@feathersjs/authentication-local')
105
- }
106
-
107
- if (ctx.dependencies) {
108
- return {
109
- ...ctx,
110
- dependencies: [...ctx.dependencies, ...dependencies]
111
- }
112
- }
113
-
114
- return install<AuthenticationGeneratorContext>(
115
- addVersions(dependencies, ctx.dependencyVersions),
116
- false,
117
- ctx.feathers.packager
118
- )(ctx)
119
- })
@@ -1,52 +0,0 @@
1
- import { before, toFile } from '@featherscloud/pinion'
2
- import { injectSource, renderSource } from '../../commons.js'
3
- import { AuthenticationGeneratorContext } from '../index.js'
4
- import { localTemplate, oauthTemplate } from '../../commons.js'
5
-
6
- const template = ({
7
- authStrategies
8
- }: AuthenticationGeneratorContext) => /* ts */ `// For more information about this file see https://dove.feathersjs.com/guides/cli/authentication.html
9
- import { AuthenticationService, JWTStrategy } from '@feathersjs/authentication'
10
- ${localTemplate(authStrategies, `import { LocalStrategy } from '@feathersjs/authentication-local'`)}
11
- ${oauthTemplate(authStrategies, `import { oauth, OAuthStrategy } from '@feathersjs/authentication-oauth'`)}
12
-
13
- import type { Application } from './declarations'
14
-
15
- declare module './declarations' {
16
- interface ServiceTypes {
17
- 'authentication': AuthenticationService
18
- }
19
- }
20
-
21
- export const authentication = (app: Application) => {
22
- const authentication = new AuthenticationService(app)
23
-
24
- authentication.register('jwt', new JWTStrategy())
25
- ${authStrategies
26
- .map(
27
- (strategy) =>
28
- ` authentication.register('${strategy}', ${
29
- strategy === 'local' ? `new LocalStrategy()` : `new OAuthStrategy()`
30
- })`
31
- )
32
- .join('\n')}
33
-
34
- app.use('authentication', authentication)
35
- ${oauthTemplate(authStrategies, `app.configure(oauth())`)}
36
- }
37
- `
38
-
39
- const importTemplate = "import { authentication } from './authentication'"
40
- const configureTemplate = 'app.configure(authentication)'
41
- const toAppFile = toFile<AuthenticationGeneratorContext>(({ lib }) => [lib, 'app'])
42
-
43
- export const generate = (ctx: AuthenticationGeneratorContext) =>
44
- Promise.resolve(ctx)
45
- .then(
46
- renderSource(
47
- template,
48
- toFile<AuthenticationGeneratorContext>(({ lib }) => lib, 'authentication')
49
- )
50
- )
51
- .then(injectSource(importTemplate, before('import { services } from'), toAppFile))
52
- .then(injectSource(configureTemplate, before('app.configure(services)'), toAppFile))
@@ -1,78 +0,0 @@
1
- import { toFile, when } from '@featherscloud/pinion'
2
- import { fileExists, renderSource } from '../../commons.js'
3
- import { AuthenticationGeneratorContext } from '../index.js'
4
- import { localTemplate } from '../../commons.js'
5
-
6
- const template = ({
7
- authStrategies,
8
- upperName,
9
- type,
10
- lib
11
- }: AuthenticationGeneratorContext) => /* ts */ `// For more information about this file see https://dove.feathersjs.com/guides/cli/client.test.html
12
- import assert from 'assert'
13
- import axios from 'axios'
14
-
15
- import rest from '@feathersjs/rest-client'
16
- ${localTemplate(authStrategies, `import authenticationClient from '@feathersjs/authentication-client'`)}
17
- import { app } from '../${lib}/app'
18
- import { createClient } from '../${lib}/client'
19
- ${localTemplate(authStrategies, `import type { ${upperName}Data } from '../${lib}/client'`)}
20
-
21
- const port = app.get('port')
22
- const appUrl = \`http://\${app.get('host')}:\${port}\`
23
-
24
- describe('application client tests', () => {
25
- const client = createClient(rest(appUrl).axios(axios))
26
-
27
- before(async () => {
28
- await app.listen(port)
29
- })
30
-
31
- after(async () => {
32
- await app.teardown()
33
- })
34
-
35
- it('initialized the client', () => {
36
- assert.ok(client)
37
- })
38
-
39
- ${localTemplate(
40
- authStrategies,
41
- `
42
- it('creates and authenticates a user with email and password', async () => {
43
- const userData: ${upperName}Data = {
44
- email: 'someone@example.com',
45
- password: 'supersecret'
46
- }
47
-
48
- await client.service('users').create(userData)
49
-
50
- const { user, accessToken } = await client.authenticate({
51
- strategy: 'local',
52
- ...userData
53
- })
54
-
55
- assert.ok(accessToken, 'Created access token for user')
56
- assert.ok(user, 'Includes user in authentication data')
57
- assert.strictEqual(user.password, undefined, 'Password is hidden to clients')
58
-
59
- await client.logout()
60
-
61
- // Remove the test user on the server
62
- await app.service('users').remove(user.${type === 'mongodb' ? '_id' : 'id'})
63
- })`
64
- )}
65
- })
66
- `
67
-
68
- export const generate = (ctx: AuthenticationGeneratorContext) =>
69
- Promise.resolve(ctx).then(
70
- when<AuthenticationGeneratorContext>(
71
- ({ lib, language }) => fileExists(lib, `client.${language}`),
72
- renderSource(
73
- template,
74
- toFile<AuthenticationGeneratorContext>(({ test }) => test, 'client.test'),
75
- { force: true }
76
- )
77
- )
78
- )
@@ -1,60 +0,0 @@
1
- import crypto from 'crypto'
2
- import { toFile, mergeJSON } from '@featherscloud/pinion'
3
- import { AuthenticationGeneratorContext } from '../index.js'
4
-
5
- export const generate = (ctx: AuthenticationGeneratorContext) =>
6
- Promise.resolve(ctx)
7
- .then(
8
- mergeJSON<AuthenticationGeneratorContext>(
9
- ({ authStrategies }) => {
10
- const authentication: any = {
11
- entity: ctx.entity,
12
- service: ctx.path,
13
- secret: crypto.randomBytes(24).toString('base64'),
14
- authStrategies: ['jwt'],
15
- jwtOptions: {
16
- header: {
17
- typ: 'access'
18
- },
19
- audience: 'https://yourdomain.com',
20
- algorithm: 'HS256',
21
- expiresIn: '1d'
22
- }
23
- }
24
-
25
- if (authStrategies.includes('local')) {
26
- authentication.authStrategies.push('local')
27
- authentication.local = {
28
- usernameField: 'email',
29
- passwordField: 'password'
30
- }
31
- }
32
-
33
- const oauthStrategies = authStrategies.filter((name) => name !== 'local')
34
-
35
- if (oauthStrategies.length) {
36
- authentication.oauth = oauthStrategies.reduce((oauth, name) => {
37
- oauth[name] = {
38
- key: '<Client ID>',
39
- secret: '<Client secret>'
40
- }
41
-
42
- return oauth
43
- }, {} as any)
44
- }
45
-
46
- return { authentication }
47
- },
48
- toFile('config', 'default.json')
49
- )
50
- )
51
- .then(
52
- mergeJSON<AuthenticationGeneratorContext>(
53
- {
54
- authentication: {
55
- secret: 'FEATHERS_SECRET'
56
- }
57
- },
58
- toFile('config', 'custom-environment-variables.json')
59
- )
60
- )
@@ -1,38 +0,0 @@
1
- import { inject, before, toFile, when, append } from '@featherscloud/pinion'
2
- import { AuthenticationGeneratorContext } from '../index.js'
3
-
4
- const importTemplate = ({
5
- upperName,
6
- folder,
7
- fileName
8
- }: AuthenticationGeneratorContext) => /* ts */ `import { ${upperName} } from './services/${folder.join(
9
- '/'
10
- )}/${fileName}'
11
- `
12
-
13
- const paramsTemplate = ({
14
- entity,
15
- upperName
16
- }: AuthenticationGeneratorContext) => /* ts */ `// Add the ${entity} as an optional property to all params
17
- declare module '@feathersjs/feathers' {
18
- interface Params {
19
- ${entity}?: ${upperName}
20
- }
21
- }
22
- `
23
-
24
- const toDeclarationFile = toFile<AuthenticationGeneratorContext>(({ lib }) => lib, 'declarations.ts')
25
-
26
- export const generate = (ctx: AuthenticationGeneratorContext) =>
27
- Promise.resolve(ctx)
28
- .then(
29
- when(
30
- (ctx) => ctx.language === 'ts',
31
- inject(
32
- importTemplate,
33
- before(/export \{ NextFunction \}|export type \{ NextFunction \}/),
34
- toDeclarationFile
35
- )
36
- )
37
- )
38
- .then(when((ctx) => ctx.language === 'ts', inject(paramsTemplate, append(), toDeclarationFile)))
package/lib/commons.ts DELETED
@@ -1,346 +0,0 @@
1
- import fs from 'fs'
2
- import { join, dirname } from 'path'
3
- import { PackageJson } from 'type-fest'
4
- import { readFile, writeFile } from 'fs/promises'
5
- import {
6
- Callable,
7
- PinionContext,
8
- loadJSON,
9
- fromFile,
10
- getCallable,
11
- renderTemplate,
12
- inject,
13
- Location,
14
- exec
15
- } from '@featherscloud/pinion'
16
- import ts from 'typescript'
17
- import prettier, { Options as PrettierOptions } from 'prettier'
18
- import path from 'path'
19
- import { fileURLToPath } from 'url'
20
-
21
- // Set __dirname in es module
22
- const __dirname = dirname(fileURLToPath(import.meta.url))
23
-
24
- export const { version } = JSON.parse(fs.readFileSync(join(__dirname, '..', 'package.json')).toString())
25
-
26
- export type DependencyVersions = { [key: string]: string }
27
-
28
- export const DATABASE_TYPES = ['mongodb', 'mysql', 'postgresql', 'sqlite', 'mssql', 'other'] as const
29
-
30
- /**
31
- * The database types supported by this generator
32
- */
33
- export type DatabaseType = (typeof DATABASE_TYPES)[number]
34
-
35
- /**
36
- * Returns the name of the Feathers database adapter for a supported database type
37
- *
38
- * @param database The type of the database
39
- * @returns The name of the adapter
40
- */
41
- export const getDatabaseAdapter = (database: DatabaseType) => (database === 'mongodb' ? 'mongodb' : 'knex')
42
-
43
- export type FeathersAppInfo = {
44
- /**
45
- * The application language
46
- */
47
- language: 'ts' | 'js'
48
- /**
49
- * The main database
50
- */
51
- database: DatabaseType
52
- /**
53
- * The package manager used
54
- */
55
- packager: 'yarn' | 'npm' | 'pnpm'
56
- /**
57
- * A list of all chosen transports
58
- */
59
- transports: ('rest' | 'websockets')[]
60
- /**
61
- * The HTTP framework used
62
- */
63
- framework: 'koa' | 'express'
64
- /**
65
- * The main schema definition format
66
- */
67
- schema: 'typebox' | 'json' | false
68
- }
69
-
70
- export interface AppPackageJson extends PackageJson {
71
- feathers?: FeathersAppInfo
72
- }
73
-
74
- export interface FeathersBaseContext extends PinionContext {
75
- /**
76
- * Information about the Feathers application (like chosen language, database etc.)
77
- * usually taken from `package.json`
78
- */
79
- feathers: FeathersAppInfo
80
- /**
81
- * The package.json file
82
- */
83
- pkg: AppPackageJson
84
- /**
85
- * The folder where source files are put
86
- */
87
- lib: string
88
- /**
89
- * The folder where test files are put
90
- */
91
- test: string
92
- /**
93
- * The language the app is generated in
94
- */
95
- language: 'js' | 'ts'
96
- /**
97
- * A list dependencies that should be installed with a certain version.
98
- * Used for installing development dependencies during testing.
99
- */
100
- dependencyVersions?: DependencyVersions
101
- }
102
-
103
- /**
104
- * Returns dependencies with the versions from the context attached (if available)
105
- *
106
- * @param dependencies The dependencies to install
107
- * @param versions The dependency version list
108
- * @returns A list of dependencies with their versions
109
- */
110
- export const addVersions = (dependencies: string[], versions: DependencyVersions) =>
111
- dependencies.map((dep) => `${dep}@${versions[dep] ? versions[dep] : 'latest'}`)
112
-
113
- /**
114
- * Loads the application package.json and populates information like the library and test directory
115
- * and Feathers app specific information.
116
- *
117
- * @returns The updated context
118
- */
119
- export const initializeBaseContext =
120
- () =>
121
- <C extends FeathersBaseContext>(ctx: C) =>
122
- Promise.resolve(ctx)
123
- .then(loadJSON(fromFile('package.json'), (pkg) => ({ pkg }), {}))
124
- .then(
125
- loadJSON(path.join(__dirname, '..', 'package.json'), (pkg: PackageJson) => ({
126
- dependencyVersions: {
127
- ...pkg.devDependencies,
128
- ...ctx.dependencyVersions,
129
- '@feathersjs/cli': version
130
- }
131
- }))
132
- )
133
- .then((ctx) => ({
134
- ...ctx,
135
- lib: ctx.pkg?.directories?.lib || 'src',
136
- test: ctx.pkg?.directories?.test || 'test',
137
- language: ctx.language || ctx.pkg?.feathers?.language,
138
- feathers: ctx.pkg?.feathers
139
- }))
140
-
141
- /**
142
- * Checks if the current context contains a valid generated application. This is necesary for most
143
- * generators (besides the app generator).
144
- *
145
- * @param ctx The context to check against
146
- * @returns Throws an error or returns the original context
147
- */
148
- export const checkPreconditions =
149
- () =>
150
- async <T extends FeathersBaseContext>(ctx: T) => {
151
- if (!ctx.feathers) {
152
- throw new Error(`Can not run generator since the current folder does not appear to be a Feathers application.
153
- Either your package.json is missing or it does not have \`feathers\` property.
154
- `)
155
- }
156
-
157
- return ctx
158
- }
159
-
160
- const importRegex = /from '(\..*)'/g
161
- const escapeNewLines = (code: string) => code.replace(/\n\n/g, '\n/* :newline: */')
162
- const restoreNewLines = (code: string) => code.replace(/\/\* :newline: \*\//g, '\n')
163
- const fixLocalImports = (code: string) => code.replace(importRegex, "from '$1.js'")
164
-
165
- /**
166
- * Returns the transpiled and prettified JavaScript for a TypeScript source code
167
- *
168
- * @param typescript The TypeScript source code
169
- * @param options TypeScript transpilation options
170
- * @returns The formatted JavaScript source code
171
- */
172
- export const getJavaScript = (typescript: string, options: ts.TranspileOptions = {}) => {
173
- const source = escapeNewLines(typescript)
174
- const transpiled = ts.transpileModule(source, {
175
- ...options,
176
- compilerOptions: {
177
- module: ts.ModuleKind.ESNext,
178
- target: ts.ScriptTarget.ES2020,
179
- preserveValueImports: true,
180
- ...options.compilerOptions
181
- }
182
- })
183
- const { outputText } = transpiled
184
-
185
- if (outputText.startsWith('export {}') && typescript.startsWith('import')) {
186
- return fixLocalImports(typescript)
187
- }
188
-
189
- return fixLocalImports(restoreNewLines(transpiled.outputText))
190
- }
191
-
192
- const getFileName = async <C extends PinionContext & { language: 'js' | 'ts' }>(
193
- target: Callable<string, C>,
194
- ctx: C
195
- ) => `${await getCallable(target, ctx)}.${ctx.language}`
196
-
197
- /**
198
- * The default configuration for prettifying files
199
- */
200
- export const PRETTIERRC: PrettierOptions = {
201
- tabWidth: 2,
202
- useTabs: false,
203
- printWidth: 110,
204
- semi: false,
205
- trailingComma: 'none',
206
- singleQuote: true
207
- }
208
-
209
- /*
210
- * Format a source file using Prettier. Will use the local configuration, the settings set in
211
- * `options` or a default configuration
212
- *
213
- * @param target The file to prettify
214
- * @param options The Prettier options
215
- * @returns The updated context
216
- */
217
- export const prettify =
218
- <C extends PinionContext & { language: 'js' | 'ts' }>(
219
- target: Callable<string, C>,
220
- options: PrettierOptions = PRETTIERRC
221
- ) =>
222
- async (ctx: C) => {
223
- const fileName = await getFileName(target, ctx)
224
- const config = (await prettier.resolveConfig(ctx.cwd)) || options
225
- const content = (await readFile(fileName)).toString()
226
-
227
- try {
228
- await writeFile(
229
- fileName,
230
- await prettier.format(content, {
231
- parser: ctx.language === 'ts' ? 'typescript' : 'babel',
232
- ...config
233
- })
234
- )
235
- } catch (error: any) {
236
- throw new Error(`Error prettifying ${fileName}: ${error.message}`)
237
- }
238
-
239
- return ctx
240
- }
241
-
242
- /**
243
- * Render a source file template for the language set in the context.
244
- *
245
- * @param templates The JavaScript and TypeScript template to render
246
- * @param target The target filename without extension (will be added based on language)
247
- * @returns The updated context
248
- */
249
- export const renderSource =
250
- <C extends PinionContext & { language: 'js' | 'ts' }>(
251
- template: Callable<string, C>,
252
- target: Callable<string, C>,
253
- options?: { force: boolean }
254
- ) =>
255
- async (ctx: C) => {
256
- const { language } = ctx
257
- const fileName = await getFileName(target, ctx)
258
- const content = language === 'js' ? getJavaScript(await getCallable<string, C>(template, ctx)) : template
259
- const renderer = renderTemplate(content, fileName, options)
260
-
261
- return renderer(ctx).then(prettify(target))
262
- }
263
-
264
- export const install =
265
- <C extends PinionContext & { language: 'js' | 'ts' }>(
266
- dependencies: Callable<string[], C>,
267
- dev: Callable<boolean, C>,
268
- packager: Callable<string, C>
269
- ) =>
270
- async (ctx: C) => {
271
- const dependencyList = await getCallable(dependencies, ctx)
272
- const packageManager = await getCallable(packager, ctx)
273
- const flags = dev ? [packageManager === 'yarn' ? '--dev' : '--save-dev'] : []
274
-
275
- return exec(packager, [packageManager === 'yarn' ? 'add' : 'install', ...dependencyList, ...flags])(ctx)
276
- }
277
-
278
- /**
279
- * Inject a source template as the language set in the context.
280
- *
281
- * @param template The source template to render
282
- * @param location The location to inject the code to. Must use the target language.
283
- * @param target The target file name
284
- * @param transpile Set to `false` if the code should not be transpiled to JavaScript
285
- * @returns
286
- */
287
- export const injectSource =
288
- <C extends PinionContext & { language: 'js' | 'ts' }>(
289
- template: Callable<string, C>,
290
- location: Location<C>,
291
- target: Callable<string, C>,
292
- transpile = true
293
- ) =>
294
- async (ctx: C) => {
295
- const { language } = ctx
296
- const source =
297
- language === 'js' && transpile ? getJavaScript(await getCallable<string, C>(template, ctx)) : template
298
- const fileName = await getFileName(target, ctx)
299
- const injector = inject(source, location, fileName)
300
-
301
- return injector(ctx).then(prettify(target))
302
- }
303
-
304
- /**
305
- * Synchronously checks if a file exits
306
- * @param context The base context
307
- * @param filenames The filenames to check
308
- * @returns Wether the file exists or not
309
- */
310
- export const fileExists = (...filenames: string[]) => fs.existsSync(join(...filenames))
311
-
312
- /**
313
- * The helper used by Knex to create migration names
314
- * @returns The current date and time in the format `YYYYMMDDHHMMSS`
315
- */
316
- export const yyyymmddhhmmss = (offset = 0) => {
317
- const now = new Date(Date.now() + offset)
318
-
319
- return (
320
- now.getUTCFullYear().toString() +
321
- (now.getUTCMonth() + 1).toString().padStart(2, '0') +
322
- now.getUTCDate().toString().padStart(2, '0') +
323
- now.getUTCHours().toString().padStart(2, '0') +
324
- now.getUTCMinutes().toString().padStart(2, '0') +
325
- now.getUTCSeconds().toString().padStart(2, '0')
326
- )
327
- }
328
-
329
- /**
330
- * Render a template if `local` authentication strategy has been selected
331
- * @param authStrategies The list of selected authentication strategies
332
- * @param content The content to render if `local` is selected
333
- * @param alt The content to render if `local` is not selected
334
- * @returns
335
- */
336
- export const localTemplate = (authStrategies: string[], content: string, alt = '') =>
337
- authStrategies.includes('local') ? content : alt
338
-
339
- /**
340
- * Render a template if an `oauth` authentication strategy has been selected
341
- * @param authStrategies
342
- * @param content
343
- * @returns
344
- */
345
- export const oauthTemplate = (authStrategies: string[], content: string) =>
346
- authStrategies.filter((s) => s !== 'local').length > 0 ? content : ''