Skip to content

Commit d79ed42

Browse files
feat: migrate to TypeScript (#150)
* feat: setup typescript * chore: make typescript files out of declaration files * chore: please linter by ordering right * chore: remove unused type * chore: migrate builder to typescript * chore: migrate consts to typescript * chore: migrate main to typescript * chore: extend eslint to typescript * chore: extend prettier to typescript files * chore: fix tests * Update package.json Co-authored-by: Eduardo Bouças <[email protected]> * chore: add missing npm-run-all dependency Co-authored-by: Netlify Team Account 1 <[email protected]> Co-authored-by: Eduardo Bouças <[email protected]>
1 parent 3686a7e commit d79ed42

17 files changed

+188
-91
lines changed

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,3 +10,4 @@ node_modules
1010
/coverage
1111
/build
1212
.vscode
13+
dist

package-lock.json

Lines changed: 3 additions & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 13 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,16 @@
11
{
22
"name": "@netlify/functions",
3-
"main": "./src/main.js",
4-
"types": "./src/main.d.ts",
3+
"main": "./dist/main.js",
4+
"types": "./dist/main.d.ts",
55
"version": "0.7.2",
66
"description": "JavaScript utilities for Netlify Functions",
77
"files": [
8-
"src/**/*.js",
9-
"src/**/*.ts",
10-
"!src/**/*.test.js"
8+
"dist/**/*.js",
9+
"dist/**/*.d.ts"
1110
],
1211
"scripts": {
12+
"build": "tsc",
13+
"prepack": "npm run build",
1314
"prepublishOnly": "npm ci && npm test",
1415
"test": "run-s format test:dev",
1516
"format": "run-s format:check-fix:*",
@@ -20,14 +21,14 @@
2021
"format:check-fix:prettier": "run-e format:check:prettier format:fix:prettier",
2122
"format:check:prettier": "cross-env-shell prettier --check $npm_package_config_prettier",
2223
"format:fix:prettier": "cross-env-shell prettier --write $npm_package_config_prettier",
23-
"test:dev": "run-s test:dev:*",
24-
"test:ci": "run-s test:ci:*",
24+
"test:dev": "run-s build test:dev:*",
25+
"test:ci": "run-s build test:ci:*",
2526
"test:dev:ava": "ava",
2627
"test:ci:ava": "nyc -r lcovonly -r text -r json ava"
2728
},
2829
"config": {
29-
"eslint": "--ignore-pattern README.md --ignore-path .gitignore --cache --format=codeframe --max-warnings=0 \"{src,scripts,.github}/**/*.{js,md,html}\" \"*.{js,md,html}\" \".*.{js,md,html}\"",
30-
"prettier": "--ignore-path .gitignore --loglevel=warn \"{src,scripts,.github}/**/*.{js,md,yml,json,html}\" \"*.{js,yml,json,html}\" \".*.{js,yml,json,html}\" \"!**/package-lock.json\" \"!package-lock.json\""
30+
"eslint": "--ignore-pattern README.md --ignore-path .gitignore --cache --format=codeframe --max-warnings=0 \"{src,scripts,.github}/**/*.{ts,js,md,html}\" \"*.{ts,js,md,html}\" \".*.{ts,js,md,html}\"",
31+
"prettier": "--ignore-path .gitignore --loglevel=warn \"{src,scripts,.github}/**/*.{ts,js,md,yml,json,html}\" \"*.{ts,js,yml,json,html}\" \".*.{ts,js,yml,json,html}\" \"!**/package-lock.json\" \"!package-lock.json\""
3132
},
3233
"ava": {
3334
"files": [
@@ -60,7 +61,9 @@
6061
"@netlify/eslint-config-node": "^3.3.4",
6162
"ava": "^2.4.0",
6263
"husky": "^4.3.8",
63-
"nyc": "^15.0.0"
64+
"npm-run-all": "^4.1.5",
65+
"nyc": "^15.0.0",
66+
"typescript": "^4.4.4"
6467
},
6568
"engines": {
6669
"node": ">=8.3.0"

src/function/context.d.ts renamed to src/function/context.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,6 @@
1+
// eslint-disable-next-line eslint-comments/disable-enable-pair
2+
/* eslint-disable @typescript-eslint/no-explicit-any */
3+
14
// From https://docs.aws.amazon.com/lambda/latest/dg/nodejs-prog-model-context.html.
25
export interface Context {
36
callbackWaitsForEmptyEventLoop: boolean
Lines changed: 13 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,3 @@
1-
export interface Event {
2-
rawUrl: string
3-
rawQuery: string
4-
path: string
5-
httpMethod: string
6-
headers: EventHeaders
7-
multiValueHeaders: EventMultiValueHeaders
8-
queryStringParameters: EventQueryStringParameters | null
9-
multiValueQueryStringParameters: EventMultiValueQueryStringParameters | null
10-
body: string | null
11-
isBase64Encoded: boolean
12-
}
13-
141
interface EventHeaders {
152
[name: string]: string | undefined
163
}
@@ -19,14 +6,23 @@ interface EventMultiValueHeaders {
196
[name: string]: string[] | undefined
207
}
218

22-
interface EventPathParameters {
23-
[name: string]: string | undefined
24-
}
25-
269
interface EventQueryStringParameters {
2710
[name: string]: string | undefined
2811
}
2912

3013
interface EventMultiValueQueryStringParameters {
3114
[name: string]: string[] | undefined
3215
}
16+
17+
export interface Event {
18+
rawUrl: string
19+
rawQuery: string
20+
path: string
21+
httpMethod: string
22+
headers: EventHeaders
23+
multiValueHeaders: EventMultiValueHeaders
24+
queryStringParameters: EventQueryStringParameters | null
25+
multiValueQueryStringParameters: EventMultiValueQueryStringParameters | null
26+
body: string | null
27+
isBase64Encoded: boolean
28+
}

src/function/handler.d.ts renamed to src/function/handler.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ import type { Event } from './event'
33
import type { Response } from './response'
44

55
export interface HandlerCallback {
6+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
67
(error: any, response: Response): void
78
}
89

File renamed without changes.
File renamed without changes.

src/lib/builder.d.ts

Lines changed: 0 additions & 7 deletions
This file was deleted.

src/lib/builder.js

Lines changed: 0 additions & 44 deletions
This file was deleted.

src/lib/builder.ts

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
import isPromise from 'is-promise'
2+
3+
import { Handler } from '../function/handler'
4+
import { Response } from '../function/response'
5+
6+
import { BUILDER_FUNCTIONS_FLAG, HTTP_STATUS_METHOD_NOT_ALLOWED, HTTP_STATUS_OK, METADATA_VERSION } from './consts'
7+
8+
const augmentResponse = (response: Response) => {
9+
if (!response || response.statusCode !== HTTP_STATUS_OK) {
10+
return response
11+
}
12+
13+
return {
14+
...response,
15+
metadata: { version: METADATA_VERSION, builder_function: BUILDER_FUNCTIONS_FLAG },
16+
}
17+
}
18+
19+
const wrapHandler =
20+
(handler: Handler): Handler =>
21+
// eslint-disable-next-line promise/prefer-await-to-callbacks
22+
(event, context, callback) => {
23+
if (event.httpMethod !== 'GET' && event.httpMethod !== 'HEAD') {
24+
return Promise.resolve({
25+
body: 'Method Not Allowed',
26+
statusCode: HTTP_STATUS_METHOD_NOT_ALLOWED,
27+
})
28+
}
29+
30+
// Removing query string parameters from the builder function.
31+
const modifiedEvent = {
32+
...event,
33+
multiValueQueryStringParameters: {},
34+
queryStringParameters: {},
35+
}
36+
37+
// eslint-disable-next-line promise/prefer-await-to-callbacks
38+
const wrappedCallback = (error: unknown, response: Response) => callback(error, augmentResponse(response))
39+
const execution = handler(modifiedEvent, context, wrappedCallback)
40+
41+
if (isPromise(execution)) {
42+
// eslint-disable-next-line promise/prefer-await-to-then
43+
return execution.then(augmentResponse)
44+
}
45+
46+
return execution
47+
}
48+
49+
export { wrapHandler as builder }

src/lib/consts.js renamed to src/lib/consts.ts

Lines changed: 1 addition & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,4 @@ const HTTP_STATUS_METHOD_NOT_ALLOWED = 405
33
const HTTP_STATUS_OK = 200
44
const METADATA_VERSION = 1
55

6-
module.exports = {
7-
BUILDER_FUNCTIONS_FLAG,
8-
HTTP_STATUS_METHOD_NOT_ALLOWED,
9-
HTTP_STATUS_OK,
10-
METADATA_VERSION,
11-
}
6+
export { BUILDER_FUNCTIONS_FLAG, HTTP_STATUS_METHOD_NOT_ALLOWED, HTTP_STATUS_OK, METADATA_VERSION }

src/main.d.ts

Lines changed: 0 additions & 2 deletions
This file was deleted.

src/main.js

Lines changed: 0 additions & 3 deletions
This file was deleted.

src/main.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
export { builder } from './lib/builder'
2+
export * from './function'

test/builder.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
const test = require('ava')
22

3-
const { builder } = require('../src/lib/builder')
3+
const { builder } = require('../dist/lib/builder')
44

55
const { invokeLambda } = require('./helpers/main')
66

tsconfig.json

Lines changed: 101 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,101 @@
1+
{
2+
"compilerOptions": {
3+
/* Visit https://aka.ms/tsconfig.json to read more about this file */
4+
5+
/* Projects */
6+
// "incremental": true, /* Enable incremental compilation */
7+
// "composite": true, /* Enable constraints that allow a TypeScript project to be used with project references. */
8+
// "tsBuildInfoFile": "./", /* Specify the folder for .tsbuildinfo incremental compilation files. */
9+
// "disableSourceOfProjectReferenceRedirect": true, /* Disable preferring source files instead of declaration files when referencing composite projects */
10+
// "disableSolutionSearching": true, /* Opt a project out of multi-project reference checking when editing. */
11+
// "disableReferencedProjectLoad": true, /* Reduce the number of projects loaded automatically by TypeScript. */
12+
13+
/* Language and Environment */
14+
"target": "es5" /* Set the JavaScript language version for emitted JavaScript and include compatible library declarations. */,
15+
// "lib": [], /* Specify a set of bundled library declaration files that describe the target runtime environment. */
16+
// "jsx": "preserve", /* Specify what JSX code is generated. */
17+
// "experimentalDecorators": true, /* Enable experimental support for TC39 stage 2 draft decorators. */
18+
// "emitDecoratorMetadata": true, /* Emit design-type metadata for decorated declarations in source files. */
19+
// "jsxFactory": "", /* Specify the JSX factory function used when targeting React JSX emit, e.g. 'React.createElement' or 'h' */
20+
// "jsxFragmentFactory": "", /* Specify the JSX Fragment reference used for fragments when targeting React JSX emit e.g. 'React.Fragment' or 'Fragment'. */
21+
// "jsxImportSource": "", /* Specify module specifier used to import the JSX factory functions when using `jsx: react-jsx*`.` */
22+
// "reactNamespace": "", /* Specify the object invoked for `createElement`. This only applies when targeting `react` JSX emit. */
23+
// "noLib": true, /* Disable including any library files, including the default lib.d.ts. */
24+
// "useDefineForClassFields": true, /* Emit ECMAScript-standard-compliant class fields. */
25+
26+
/* Modules */
27+
"module": "commonjs" /* Specify what module code is generated. */,
28+
"rootDir": "./src" /* Specify the root folder within your source files. */,
29+
// "moduleResolution": "node", /* Specify how TypeScript looks up a file from a given module specifier. */
30+
// "baseUrl": "./", /* Specify the base directory to resolve non-relative module names. */
31+
// "paths": {}, /* Specify a set of entries that re-map imports to additional lookup locations. */
32+
// "rootDirs": [], /* Allow multiple folders to be treated as one when resolving modules. */
33+
// "typeRoots": [], /* Specify multiple folders that act like `./node_modules/@types`. */
34+
// "types": [], /* Specify type package names to be included without being referenced in a source file. */
35+
// "allowUmdGlobalAccess": true, /* Allow accessing UMD globals from modules. */
36+
// "resolveJsonModule": true, /* Enable importing .json files */
37+
// "noResolve": true, /* Disallow `import`s, `require`s or `<reference>`s from expanding the number of files TypeScript should add to a project. */
38+
39+
/* JavaScript Support */
40+
"allowJs": true /* Allow JavaScript files to be a part of your program. Use the `checkJS` option to get errors from these files. */,
41+
// "checkJs": true, /* Enable error reporting in type-checked JavaScript files. */
42+
// "maxNodeModuleJsDepth": 1, /* Specify the maximum folder depth used for checking JavaScript files from `node_modules`. Only applicable with `allowJs`. */
43+
44+
/* Emit */
45+
"declaration": true /* Generate .d.ts files from TypeScript and JavaScript files in your project. */,
46+
// "declarationMap": true, /* Create sourcemaps for d.ts files. */
47+
// "emitDeclarationOnly": true, /* Only output d.ts files and not JavaScript files. */
48+
// "sourceMap": true, /* Create source map files for emitted JavaScript files. */
49+
// "outFile": "./", /* Specify a file that bundles all outputs into one JavaScript file. If `declaration` is true, also designates a file that bundles all .d.ts output. */
50+
"outDir": "./dist" /* Specify an output folder for all emitted files. */,
51+
// "removeComments": true, /* Disable emitting comments. */
52+
// "noEmit": true, /* Disable emitting files from a compilation. */
53+
// "importHelpers": true, /* Allow importing helper functions from tslib once per project, instead of including them per-file. */
54+
// "importsNotUsedAsValues": "remove", /* Specify emit/checking behavior for imports that are only used for types */
55+
// "downlevelIteration": true, /* Emit more compliant, but verbose and less performant JavaScript for iteration. */
56+
// "sourceRoot": "", /* Specify the root path for debuggers to find the reference source code. */
57+
// "mapRoot": "", /* Specify the location where debugger should locate map files instead of generated locations. */
58+
// "inlineSourceMap": true, /* Include sourcemap files inside the emitted JavaScript. */
59+
// "inlineSources": true, /* Include source code in the sourcemaps inside the emitted JavaScript. */
60+
// "emitBOM": true, /* Emit a UTF-8 Byte Order Mark (BOM) in the beginning of output files. */
61+
// "newLine": "crlf", /* Set the newline character for emitting files. */
62+
// "stripInternal": true, /* Disable emitting declarations that have `@internal` in their JSDoc comments. */
63+
// "noEmitHelpers": true, /* Disable generating custom helper functions like `__extends` in compiled output. */
64+
// "noEmitOnError": true, /* Disable emitting files if any type checking errors are reported. */
65+
// "preserveConstEnums": true, /* Disable erasing `const enum` declarations in generated code. */
66+
// "declarationDir": "./", /* Specify the output directory for generated declaration files. */
67+
68+
/* Interop Constraints */
69+
// "isolatedModules": true, /* Ensure that each file can be safely transpiled without relying on other imports. */
70+
// "allowSyntheticDefaultImports": true, /* Allow 'import x from y' when a module doesn't have a default export. */
71+
"esModuleInterop": true /* Emit additional JavaScript to ease support for importing CommonJS modules. This enables `allowSyntheticDefaultImports` for type compatibility. */,
72+
// "preserveSymlinks": true, /* Disable resolving symlinks to their realpath. This correlates to the same flag in node. */
73+
"forceConsistentCasingInFileNames": true /* Ensure that casing is correct in imports. */,
74+
75+
/* Type Checking */
76+
"strict": true /* Enable all strict type-checking options. */,
77+
// "noImplicitAny": true, /* Enable error reporting for expressions and declarations with an implied `any` type.. */
78+
// "strictNullChecks": true, /* When type checking, take into account `null` and `undefined`. */
79+
// "strictFunctionTypes": true, /* When assigning functions, check to ensure parameters and the return values are subtype-compatible. */
80+
// "strictBindCallApply": true, /* Check that the arguments for `bind`, `call`, and `apply` methods match the original function. */
81+
// "strictPropertyInitialization": true, /* Check for class properties that are declared but not set in the constructor. */
82+
// "noImplicitThis": true, /* Enable error reporting when `this` is given the type `any`. */
83+
// "useUnknownInCatchVariables": true, /* Type catch clause variables as 'unknown' instead of 'any'. */
84+
// "alwaysStrict": true, /* Ensure 'use strict' is always emitted. */
85+
// "noUnusedLocals": true, /* Enable error reporting when a local variables aren't read. */
86+
// "noUnusedParameters": true, /* Raise an error when a function parameter isn't read */
87+
// "exactOptionalPropertyTypes": true, /* Interpret optional property types as written, rather than adding 'undefined'. */
88+
// "noImplicitReturns": true, /* Enable error reporting for codepaths that do not explicitly return in a function. */
89+
// "noFallthroughCasesInSwitch": true, /* Enable error reporting for fallthrough cases in switch statements. */
90+
// "noUncheckedIndexedAccess": true, /* Include 'undefined' in index signature results */
91+
// "noImplicitOverride": true, /* Ensure overriding members in derived classes are marked with an override modifier. */
92+
// "noPropertyAccessFromIndexSignature": true, /* Enforces using indexed accessors for keys declared using an indexed type */
93+
// "allowUnusedLabels": true, /* Disable error reporting for unused labels. */
94+
// "allowUnreachableCode": true, /* Disable error reporting for unreachable code. */
95+
96+
/* Completeness */
97+
// "skipDefaultLibCheck": true, /* Skip type checking .d.ts files that are included with TypeScript. */
98+
"skipLibCheck": true /* Skip type checking all .d.ts files. */
99+
},
100+
"include": ["src"]
101+
}

0 commit comments

Comments
 (0)