Skip to content
This repository has been archived by the owner on May 22, 2024. It is now read-only.

Commit

Permalink
feat: support v2 API for TypeScript (#1478)
Browse files Browse the repository at this point in the history
* feat: support v2 api with typescript

* fix: resolve some test todos by enabling flags

* chore: prettier

* fix: ensure that all .ts files are transpiled

* fix: make default bundler understand typescript

* refactor: remove join import
  • Loading branch information
Skn0tt authored Jun 28, 2023
1 parent 646c1cc commit 16972c2
Show file tree
Hide file tree
Showing 4 changed files with 59 additions and 6 deletions.
10 changes: 9 additions & 1 deletion src/runtimes/node/bundlers/esbuild/bundler_target.ts
Original file line number Diff line number Diff line change
Expand Up @@ -35,9 +35,17 @@ const getModuleFormat = async (
}

if (featureFlags.zisi_pure_esm) {
const packageJsonFile = await getClosestPackageJson(srcDir)
const nodeSupport = getNodeSupportMatrix(configVersion)

if (extension.includes('ts') && nodeSupport.esm) {
return {
includedFiles: [],
moduleFormat: MODULE_FORMAT.ESM,
}
}

const packageJsonFile = await getClosestPackageJson(srcDir)

if (packageJsonFile?.contents.type === 'module' && nodeSupport.esm) {
return {
includedFiles: [packageJsonFile.path],
Expand Down
10 changes: 9 additions & 1 deletion src/runtimes/node/bundlers/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,15 @@ const getDefaultBundler = async ({
featureFlags: FeatureFlags
runtimeAPIVersion: number
}): Promise<NodeBundlerName> => {
if ((extension === MODULE_FILE_EXTENSION.MJS && featureFlags.zisi_pure_esm_mjs) || runtimeAPIVersion === 2) {
if (runtimeAPIVersion === 2) {
if (ESBUILD_EXTENSIONS.has(extension)) {
return NODE_BUNDLER.ESBUILD
}

return NODE_BUNDLER.NFT
}

if (extension === MODULE_FILE_EXTENSION.MJS && featureFlags.zisi_pure_esm_mjs) {
return NODE_BUNDLER.NFT
}

Expand Down
5 changes: 5 additions & 0 deletions tests/fixtures/v2-api-ts/ts-function.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
export default async (req: Request) => new Response("<h1>Hello world from Typescript</h1>", {
headers: {
"content-type": "text/html"
}
})
40 changes: 36 additions & 4 deletions tests/v2api.test.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
import { version as nodeVersion } from 'process'
import { promisify } from 'util'

import merge from 'deepmerge'
import glob from 'glob'
import semver from 'semver'
import { afterEach, describe, expect, vi } from 'vitest'

Expand All @@ -10,6 +12,8 @@ import { invokeLambda, readAsBuffer } from './helpers/lambda.js'
import { zipFixture, unzipFiles, importFunctionFile } from './helpers/main.js'
import { testMany } from './helpers/test_many.js'

const pGlob = promisify(glob)

vi.mock('../src/utils/shell.js', () => ({ shellUtils: { runCommand: vi.fn() } }))

describe.runIf(semver.gte(nodeVersion, '18.13.0'))('V2 functions API', () => {
Expand All @@ -19,10 +23,12 @@ describe.runIf(semver.gte(nodeVersion, '18.13.0'))('V2 functions API', () => {

testMany(
'Handles a basic JavaScript function',
['bundler_default', 'todo:bundler_esbuild', 'todo:bundler_esbuild_zisi', 'bundler_default_nft', 'bundler_nft'],
['bundler_default', 'bundler_esbuild', 'bundler_esbuild_zisi', 'bundler_default_nft', 'bundler_nft'],
async (options) => {
const { files } = await zipFixture('v2-api', {
opts: merge(options, { featureFlags: { zisi_functions_api_v2: true } }),
opts: merge(options, {
featureFlags: { zisi_functions_api_v2: true, zisi_pure_esm: true, zisi_pure_esm_mjs: true },
}),
})
const unzippedFunctions = await unzipFiles(files)

Expand All @@ -38,12 +44,12 @@ describe.runIf(semver.gte(nodeVersion, '18.13.0'))('V2 functions API', () => {

testMany(
'Handles a basic JavaScript function with archiveFormat set to `none`',
['bundler_default', 'todo:bundler_esbuild', 'todo:bundler_esbuild_zisi', 'bundler_default_nft', 'bundler_nft'],
['bundler_default', 'bundler_esbuild', 'bundler_esbuild_zisi', 'bundler_default_nft', 'bundler_nft'],
async (options) => {
const { files, tmpDir } = await zipFixture('v2-api', {
opts: merge(options, {
archiveFormat: ARCHIVE_FORMAT.NONE,
featureFlags: { zisi_functions_api_v2: true },
featureFlags: { zisi_functions_api_v2: true, zisi_pure_esm: true, zisi_pure_esm_mjs: true },
}),
})

Expand All @@ -57,4 +63,30 @@ describe.runIf(semver.gte(nodeVersion, '18.13.0'))('V2 functions API', () => {
expect(statusCode).toBe(200)
},
)

testMany(
'Handles a basic TypeScript function',
['bundler_default', 'bundler_esbuild', 'bundler_esbuild_zisi', 'bundler_default_nft', 'todo:bundler_nft'],
async (options) => {
const { files, tmpDir } = await zipFixture('v2-api-ts', {
opts: merge(options, {
archiveFormat: ARCHIVE_FORMAT.NONE,
featureFlags: { zisi_pure_esm: true, zisi_functions_api_v2: true },
}),
})

const [{ name: archive, entryFilename, path }] = files

const untranspiledFiles = await pGlob(`${path}/**/*.ts`)
expect(untranspiledFiles).toEqual([])

const func = await importFunctionFile(`${tmpDir}/${archive}/${entryFilename}`)
const { body: bodyStream, headers = {}, statusCode } = await invokeLambda(func)
const body = await readAsBuffer(bodyStream)

expect(body).toBe('<h1>Hello world from Typescript</h1>')
expect(headers['content-type']).toBe('text/html')
expect(statusCode).toBe(200)
},
)
})

1 comment on commit 16972c2

@github-actions
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⏱ Benchmark results

  • largeDepsEsbuild: 3.6s
  • largeDepsNft: 12.4s
  • largeDepsZisi: 21.9s

Please sign in to comment.