Skip to content

Commit 7b52d21

Browse files
committed
Upgrade to Serverless Framework v3 and the new design
1 parent a367dcd commit 7b52d21

File tree

5 files changed

+86
-22
lines changed

5 files changed

+86
-22
lines changed

package.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -62,12 +62,13 @@
6262
"typescript": "^3.9.10"
6363
},
6464
"dependencies": {
65+
"@serverless/utils": "^5.20.0",
6566
"fs-extra": "^7.0.1",
6667
"globby": "^10.0.2",
6768
"lodash": "^4.17.21"
6869
},
6970
"peerDependencies": {
70-
"serverless": "2",
71+
"serverless": "pre-3",
7172
"typescript": ">=2.2.2"
7273
},
7374
"jest": {

src/Serverless.d.ts

Lines changed: 32 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,38 @@ declare namespace Serverless {
4646
individually?: boolean
4747
}
4848

49+
interface Progress {
50+
update(message?: string): void
51+
remove(): void
52+
}
53+
54+
interface Utils {
55+
log: ((message: string) => void) & {
56+
verbose(message: string): void
57+
}
58+
progress: {
59+
create(opts?: { message?: string }): Progress;
60+
}
61+
}
62+
63+
type CommandsDefinition = Record<
64+
string,
65+
{
66+
lifecycleEvents?: string[]
67+
commands?: CommandsDefinition
68+
usage?: string
69+
options?: {
70+
[name: string]: {
71+
type: string
72+
usage: string
73+
required?: boolean
74+
shortcut?: string
75+
}
76+
}
77+
}
78+
>
79+
4980
interface PluginManager {
5081
spawn(command: string): Promise<void>
5182
}
52-
}
83+
}

src/index.ts

Lines changed: 35 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -16,10 +16,29 @@ export class TypeScriptPlugin {
1616
serverless: Serverless.Instance
1717
options: Serverless.Options
1818
hooks: { [key: string]: Function }
19+
utils: Serverless.Utils
20+
commands: Serverless.CommandsDefinition
21+
watchProgress?: Serverless.Progress
1922

20-
constructor(serverless: Serverless.Instance, options: Serverless.Options) {
23+
constructor(serverless: Serverless.Instance, options: Serverless.Options, utils) {
2124
this.serverless = serverless
2225
this.options = options
26+
this.utils = utils
27+
28+
this.commands = {
29+
invoke: {
30+
commands: {
31+
local: {
32+
options: {
33+
watch: {
34+
type: 'boolean',
35+
usage: 'Watch file changes and re-invoke automatically the function'
36+
}
37+
}
38+
}
39+
}
40+
}
41+
}
2342

2443
this.hooks = {
2544
'before:run:run': async () => {
@@ -65,11 +84,17 @@ export class TypeScriptPlugin {
6584
delete require.cache[module]
6685
})
6786
}
87+
this.watchProgress = this.watchProgress ?? this.utils.progress.create()
6888
},
69-
'after:invoke:local:invoke': () => {
89+
'after:invoke:local:invoke': async () => {
7090
if (this.options.watch) {
91+
if (this.watchProgress) {
92+
this.watchProgress.update('Watching for TypeScript changes')
93+
}
7194
this.watchFunction()
72-
this.serverless.cli.log('Waiting for changes...')
95+
return new Promise(() => {
96+
// return an unresolved promise to keep the command active (else the CLI shuts down)
97+
})
7398
}
7499
}
75100
}
@@ -116,7 +141,7 @@ export class TypeScriptPlugin {
116141
return
117142
}
118143

119-
this.serverless.cli.log(`Watch function ${this.options.function}...`)
144+
this.utils.log.verbose(`Watching function ${this.options.function}`)
120145

121146
this.isWatching = true
122147
watchFiles(this.rootFileNames, this.originalServicePath, () => {
@@ -129,15 +154,17 @@ export class TypeScriptPlugin {
129154
return
130155
}
131156

132-
this.serverless.cli.log(`Watching typescript files...`)
157+
this.utils.log.verbose(`Watching typescript files`)
133158

134159
this.isWatching = true
135160
watchFiles(this.rootFileNames, this.originalServicePath, this.compileTs.bind(this))
136161
}
137162

138163
async compileTs(): Promise<string[]> {
139164
this.prepare()
140-
this.serverless.cli.log('Compiling with Typescript...')
165+
const progress = this.utils.progress.create({
166+
message: 'Compiling TypeScript code'
167+
})
141168

142169
if (!this.originalServicePath) {
143170
// Save original service path and functions
@@ -155,13 +182,13 @@ export class TypeScriptPlugin {
155182
const tsconfig = typescript.getTypescriptConfig(
156183
this.originalServicePath,
157184
tsConfigFileLocation,
158-
this.isWatching ? null : this.serverless.cli
185+
!this.isWatching
159186
)
160187

161188
tsconfig.outDir = BUILD_FOLDER
162189

163190
const emitedFiles = await typescript.run(this.rootFileNames, tsconfig)
164-
this.serverless.cli.log('Typescript compiled.')
191+
progress.remove()
165192
return emitedFiles
166193
}
167194

src/serverless-logs.d.ts

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
declare module '@serverless/utils/log' {
2+
export const log: ((message: string) => void) & {
3+
verbose(message: string): void
4+
warning(message: string): void
5+
}
6+
}

src/typescript.ts

Lines changed: 11 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ import * as ts from 'typescript'
22
import * as fs from 'fs-extra'
33
import * as _ from 'lodash'
44
import * as path from 'path'
5+
import {log} from '@serverless/utils/log'
56

67
export function makeDefaultTypescriptConfig() {
78
const defaultTypescriptConfig: ts.CompilerOptions = {
@@ -38,8 +39,7 @@ export function extractFileNames(cwd: string, provider: string, functions?: { [k
3839

3940
// Check that the file indeed exists.
4041
if (!fs.existsSync(path.join(cwd, main))) {
41-
console.log(`Cannot locate entrypoint, ${main} not found`)
42-
throw new Error('Typescript compilation failed')
42+
throw new Error(`Typescript compilation failed: Cannot locate entrypoint, ${main} not found`)
4343
}
4444

4545
return [main]
@@ -65,8 +65,7 @@ export function extractFileNames(cwd: string, provider: string, functions?: { [k
6565
}
6666

6767
// Can't find the files. Watch will have an exception anyway. So throw one with error.
68-
console.log(`Cannot locate handler - ${fileName} not found`)
69-
throw new Error('Typescript compilation failed. Please ensure handlers exists with ext .ts or .js')
68+
throw new Error(`Typescript compilation failed. Please ensure handlers exists with ext .ts or .js.\nCannot locate handler: ${fileName} not found.`)
7069
})
7170
}
7271

@@ -80,15 +79,15 @@ export async function run(fileNames: string[], options: ts.CompilerOptions): Pro
8079

8180
allDiagnostics.forEach(diagnostic => {
8281
if (!diagnostic.file) {
83-
console.log(diagnostic)
82+
log.verbose(JSON.stringify(diagnostic))
8483
}
8584
const {line, character} = diagnostic.file.getLineAndCharacterOfPosition(diagnostic.start)
8685
const message = ts.flattenDiagnosticMessageText(diagnostic.messageText, '\n')
87-
console.log(`${diagnostic.file.fileName} (${line + 1},${character + 1}): ${message}`)
86+
log.verbose(`${diagnostic.file.fileName} (${line + 1},${character + 1}): ${message}`)
8887
})
8988

9089
if (emitResult.emitSkipped) {
91-
throw new Error('Typescript compilation failed')
90+
throw new Error('TypeScript compilation failed')
9291
}
9392

9493
return emitResult.emittedFiles.filter(filename => filename.endsWith('.js'))
@@ -113,7 +112,7 @@ export function getSourceFiles(
113112
export function getTypescriptConfig(
114113
cwd: string,
115114
tsConfigFileLocation: string = 'tsconfig.json',
116-
logger?: { log: (str: string) => void }
115+
shouldLog?: boolean
117116
): ts.CompilerOptions {
118117
const configFilePath = path.join(cwd, tsConfigFileLocation)
119118

@@ -133,13 +132,13 @@ export function getTypescriptConfig(
133132
throw new Error(JSON.stringify(configParseResult.errors))
134133
}
135134

136-
if (logger) {
137-
logger.log(`Using local tsconfig.json - ${tsConfigFileLocation}`)
135+
if (shouldLog) {
136+
log.verbose(`Using local tsconfig.json - ${tsConfigFileLocation}`)
138137
}
139138

140139
// disallow overrriding rootDir
141-
if (configParseResult.options.rootDir && path.resolve(configParseResult.options.rootDir) !== path.resolve(cwd) && logger) {
142-
logger.log('Warning: "rootDir" from local tsconfig.json is overriden')
140+
if (configParseResult.options.rootDir && path.resolve(configParseResult.options.rootDir) !== path.resolve(cwd) && log) {
141+
log.warning('Typescript: "rootDir" from local tsconfig.json is overridden')
143142
}
144143
configParseResult.options.rootDir = cwd
145144

0 commit comments

Comments
 (0)