diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 20bcf7c..e9514c3 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -15,10 +15,8 @@ jobs: docker run test-runner - name: Extract artifacts run: | - docker cp extract:/bin/deno amz-deno docker cp extract:/src/runtime/deno-lambda-layer.zip deno-lambda-layer.zip docker cp extract:/src/runtime/deno-lambda-example.zip deno-lambda-example.zip - gzip -9 amz-deno test_example: runs-on: ubuntu-latest @@ -26,7 +24,7 @@ jobs: - uses: actions/checkout@v2 - uses: denolib/setup-deno@master with: - deno-version: 1.6.0 + deno-version: 1.6.1 - name: start a local dynamodb run: | mkdir dyno diff --git a/.github/workflows/fmt_lint.yml b/.github/workflows/fmt_lint.yml new file mode 100644 index 0000000..5b3a845 --- /dev/null +++ b/.github/workflows/fmt_lint.yml @@ -0,0 +1,19 @@ +name: Test +on: [push, pull_request] +jobs: + build: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v2 + - uses: denolib/setup-deno@master + with: + deno-version: 1.6.0 + - name: Run fmt + run: | + deno fmt --check + - name: Run lint + run: | + deno lint --unstable hello.ts tests + deno lint --unstable examples-aws-cdk + deno lint --unstable example-sam --ignore=example-sam/.aws-sam + deno lint --unstable example-serverless --ignore=example-serverless/node_modules,example-serverless/.deno_dir diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml index 84870d6..c65835e 100644 --- a/.github/workflows/publish.yml +++ b/.github/workflows/publish.yml @@ -15,10 +15,8 @@ jobs: docker run test-runner - name: Extract artifacts run: | - docker cp extract:/bin/deno amz-deno docker cp extract:/src/runtime/deno-lambda-layer.zip deno-lambda-layer.zip docker cp extract:/src/runtime/deno-lambda-example.zip deno-lambda-example.zip - gzip -9 amz-deno - name: Verify Release Version Matches Deno Version if: startsWith(github.ref, 'refs/tags/') && github.repository == 'hayd/deno-lambda' run: | @@ -31,7 +29,6 @@ jobs: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} with: files: | - amz-deno.gz deno-lambda-layer.zip deno-lambda-example.zip draft: true diff --git a/.gitignore b/.gitignore index 6e5382f..b288ee7 100644 --- a/.gitignore +++ b/.gitignore @@ -2,4 +2,5 @@ .serverless node_modules package-lock.json -*.zip \ No newline at end of file +*.zip +example-sam/.aws-sam/* diff --git a/README.md b/README.md index 7c11ef5..32de197 100644 --- a/README.md +++ b/README.md @@ -175,7 +175,7 @@ Now, from the directory of your application: # replace LAYER_DIR with the directory you unzipped the layer to e.g. $PWD/layer # replace hello.handler with your file/handler function # replace '{}' with the json to pass to the handler -$ docker run -it --rm -v "$PWD":/var/task:ro,delegated -v "LAYER_DIR":/opt:ro,delegated lambci/lambda:provided hello.handler '{}' +$ docker run -it --rm -v "$PWD":/var/task:ro,delegated -v "LAYER_DIR":/opt:ro,delegated lambci/lambda:provided.al2 hello.handler '{}' # handler response from goes to stdout ``` To execute multiple times AKA "stay-open" API mode: @@ -183,7 +183,7 @@ To execute multiple times AKA "stay-open" API mode: ```sh # replace LAYER_DIR with the directory you unzipped to e.g. $PWD/layer # replace hello.handler with your file.handler function -$ docker run -e DOCKER_LAMBDA_STAY_OPEN=1 -p 9001:9001 -it --rm -v "$PWD":/var/task:ro,delegated -v "LAYER_DIR":/opt:ro,delegated lambci/lambda:provided hello.handler +$ docker run -e DOCKER_LAMBDA_STAY_OPEN=1 -p 9001:9001 -it --rm -v "$PWD":/var/task:ro,delegated -v "LAYER_DIR":/opt:ro,delegated lambci/lambda:provided.al2 hello.handler Lambda API listening on port 9001... ``` and in another terminal: diff --git a/SAR/blueprint/template.yml b/SAR/blueprint/template.yml index 3e89943..1fb82f5 100644 --- a/SAR/blueprint/template.yml +++ b/SAR/blueprint/template.yml @@ -19,7 +19,7 @@ Resources: Key: deno-lambda-example_DENO_LAMBDA_VERSION.zip MemorySize: 128 Handler: hello.handler - Runtime: provided + Runtime: provided.al2 Layers: - !GetAtt Deno.Outputs.LayerArn Events: diff --git a/example-aws-cdk/README.md b/example-aws-cdk/README.md index 9e095c6..15fa039 100644 --- a/example-aws-cdk/README.md +++ b/example-aws-cdk/README.md @@ -18,4 +18,4 @@ cdk deploy --- -[Example borrowed from AWS-SAMPLES](https://github.com/aws-samples/aws-cdk-examples/blob/master/typescript/lambda-api-ci/lib/lambda-api-stack.ts) \ No newline at end of file +[Example borrowed from AWS-SAMPLES](https://github.com/aws-samples/aws-cdk-examples/blob/master/typescript/lambda-api-ci/lib/lambda-api-stack.ts) diff --git a/example-aws-cdk/bin/example-aws-cdk.ts b/example-aws-cdk/bin/example-aws-cdk.ts index 54cb860..3f17e3d 100644 --- a/example-aws-cdk/bin/example-aws-cdk.ts +++ b/example-aws-cdk/bin/example-aws-cdk.ts @@ -1,7 +1,7 @@ #!/usr/bin/env node -import 'source-map-support/register'; -import * as cdk from '@aws-cdk/core'; -import { ExampleAwsCdkStack } from '../cdk/example-aws-cdk-stack'; +import "source-map-support/register"; +import * as cdk from "@aws-cdk/core"; +import { ExampleAwsCdkStack } from "../cdk/example-aws-cdk-stack"; const app = new cdk.App(); -new ExampleAwsCdkStack(app, 'ExampleAwsCdkStack'); +new ExampleAwsCdkStack(app, "ExampleAwsCdkStack"); diff --git a/example-aws-cdk/cdk/example-aws-cdk-stack.ts b/example-aws-cdk/cdk/example-aws-cdk-stack.ts index 501869b..c3588c2 100644 --- a/example-aws-cdk/cdk/example-aws-cdk-stack.ts +++ b/example-aws-cdk/cdk/example-aws-cdk-stack.ts @@ -1,34 +1,37 @@ -import * as cdk from '@aws-cdk/core'; -import * as lambda from '@aws-cdk/aws-lambda'; -import * as apigw from '@aws-cdk/aws-apigateway'; -import { CfnApplication } from '@aws-cdk/aws-sam' +import * as cdk from "@aws-cdk/core"; +import * as lambda from "@aws-cdk/aws-lambda"; +import * as apigw from "@aws-cdk/aws-apigateway"; +import { CfnApplication } from "@aws-cdk/aws-sam"; export class ExampleAwsCdkStack extends cdk.Stack { - constructor(scope: cdk.App, id: string, props?: cdk.StackProps) { - super(scope, id, props); + constructor(scope: cdk.App, id: string, props?: cdk.StackProps) { + super(scope, id, props); + const denoRuntime = new CfnApplication(this, "DenoRuntime", { + location: { + applicationId: + "arn:aws:serverlessrepo:us-east-1:390065572566:applications/deno", + semanticVersion: "1.6.1", + }, + }); - const denoRuntime = new CfnApplication(this, 'DenoRuntime', { - location: { - applicationId: 'arn:aws:serverlessrepo:us-east-1:390065572566:applications/deno', - semanticVersion: '1.6.0' - } - }); + // Deno Layer + const layer = lambda.LayerVersion.fromLayerVersionArn( + this, + "denoRuntimeLayer", + denoRuntime.getAtt("Outputs.LayerArn").toString(), + ); - // Deno Layer - const layer = lambda.LayerVersion.fromLayerVersionArn(this, 'denoRuntimeLayer', denoRuntime.getAtt('Outputs.LayerArn').toString()) + const name = new lambda.Function(this, "HelloHandler", { + runtime: lambda.Runtime.PROVIDED_AL2, + code: lambda.Code.fromAsset("src"), + handler: "hello.handler", + layers: [layer], + }); - const name = new lambda.Function(this, 'HelloHandler', { - runtime: lambda.Runtime.PROVIDED, - code: lambda.Code.fromAsset('src'), - handler: 'hello.handler', - layers: [layer], - }) - - // API Gateway - new apigw.LambdaRestApi(this, 'Endpoint', { - handler: name - }); - - } + // API Gateway + new apigw.LambdaRestApi(this, "Endpoint", { + handler: name, + }); + } } diff --git a/example-aws-cdk/src/hello.ts b/example-aws-cdk/src/hello.ts index 7871cba..46e2a11 100644 --- a/example-aws-cdk/src/hello.ts +++ b/example-aws-cdk/src/hello.ts @@ -1,16 +1,16 @@ import { - APIGatewayProxyEvent, - APIGatewayProxyResult, - Context + APIGatewayProxyEvent, + APIGatewayProxyResult, + Context, } from "https://deno.land/x/lambda/mod.ts"; export async function handler( - event: APIGatewayProxyEvent, - context: Context, + event: APIGatewayProxyEvent, + context: Context, ): Promise { - return { - statusCode: 200, - headers: { "content-type": "text/html;charset=utf8" }, - body: `Hello World! Sent from AWS CDK deno ${Deno.version.deno} 🦕`, - }; -} \ No newline at end of file + return { + statusCode: 200, + headers: { "content-type": "text/html;charset=utf8" }, + body: `Hello World! Sent from AWS CDK deno ${Deno.version.deno} 🦕`, + }; +} diff --git a/example-sam/hello.ts b/example-sam/hello.ts index 4b575a4..80d7b4c 100644 --- a/example-sam/hello.ts +++ b/example-sam/hello.ts @@ -1,9 +1,10 @@ import { APIGatewayProxyEvent, APIGatewayProxyResult, - Context + Context, } from "https://deno.land/x/lambda/mod.ts"; +// deno-lint-ignore require-await export async function handler( event: APIGatewayProxyEvent, context: Context, diff --git a/example-sam/template.yml b/example-sam/template.yml index dada00a..78f976a 100644 --- a/example-sam/template.yml +++ b/example-sam/template.yml @@ -11,7 +11,7 @@ Resources: Properties: Location: ApplicationId: arn:aws:serverlessrepo:us-east-1:390065572566:applications/deno - SemanticVersion: 1.6.0 + SemanticVersion: 1.6.1 HelloWorldFunction: Type: AWS::Serverless::Function @@ -19,7 +19,7 @@ Resources: CodeUri: . MemorySize: 128 Handler: hello.handler - Runtime: provided + Runtime: provided.al2 Layers: - !GetAtt Deno.Outputs.LayerArn Events: diff --git a/example-serverless/api/candidate.ts b/example-serverless/api/candidate.ts index 3dc10ed..6d0422d 100644 --- a/example-serverless/api/candidate.ts +++ b/example-serverless/api/candidate.ts @@ -1,6 +1,6 @@ import { APIGatewayProxyEvent, - Context + Context, } from "https://deno.land/x/lambda/mod.ts"; import { client } from "../client.ts"; @@ -8,13 +8,13 @@ import { Doc, uuid } from "../deps.ts"; export const TableName = "candidates"; -function ok(body: any, statusCode: number = 200) { +function ok(body: unknown, statusCode = 200) { return { statusCode, body: JSON.stringify(body), }; } -function error(message: string, statusCode: number = 500) { +function error(message: string, statusCode = 500) { return ok({ message: message }, statusCode); } @@ -48,7 +48,7 @@ export async function list(event: APIGatewayProxyEvent, context: Context) { TableName, ProjectionExpression: "id, fullname, email", }; - let result: any; + let result: unknown; try { result = await client.scan(params); } catch (e) { @@ -58,11 +58,11 @@ export async function list(event: APIGatewayProxyEvent, context: Context) { // FIXME better way to handle this?? const items = []; try { - for await (const page of result) { + for await (const page of result as AsyncIterableIterator) { items.push(...page.Items); } } catch { - items.push(...result.Items); + items.push(...(result as Doc).Items); } return ok({ candidates: items }); } catch (e) { diff --git a/example-serverless/client.ts b/example-serverless/client.ts index c4bcbd4..a2fdb08 100644 --- a/example-serverless/client.ts +++ b/example-serverless/client.ts @@ -1,3 +1,3 @@ -import { DynamoDBClient, createClient } from "./deps.ts"; +import { createClient, DynamoDBClient } from "./deps.ts"; export const client: DynamoDBClient = createClient(); diff --git a/example-serverless/deps.ts b/example-serverless/deps.ts index 6502bb4..f89be2f 100644 --- a/example-serverless/deps.ts +++ b/example-serverless/deps.ts @@ -4,5 +4,5 @@ export type { DynamoDBClient, } from "https://raw.githubusercontent.com/chiefbiiko/dynamodb/8d7cd9f1c7ce028dbf0ad15d6b90665e40d30953/mod.ts"; -import { v4 } from "https://deno.land/std@0.77.0/uuid/mod.ts"; +import { v4 } from "https://deno.land/std@0.80.0/uuid/mod.ts"; export const uuid = v4.generate; diff --git a/example-serverless/serverless.yml b/example-serverless/serverless.yml index 9ace94c..7e2c145 100644 --- a/example-serverless/serverless.yml +++ b/example-serverless/serverless.yml @@ -3,7 +3,7 @@ frameworkVersion: ">=1.1.1 <2.0.0" provider: name: aws - runtime: provided + runtime: provided.al2 stage: dev region: ${env:AWS_DEFAULT_REGION, 'us-east-1'} iamRoleStatements: @@ -64,7 +64,7 @@ resources: Properties: Location: ApplicationId: arn:aws:serverlessrepo:us-east-1:390065572566:applications/deno - SemanticVersion: 1.6.0 + SemanticVersion: 1.6.1 candidatesTable: Type: AWS::DynamoDB::Table diff --git a/example-serverless/test.ts b/example-serverless/test.ts index 5d49aea..48ec209 100644 --- a/example-serverless/test.ts +++ b/example-serverless/test.ts @@ -4,19 +4,19 @@ // You must also pass a access key/secret environment variables, but these don't have to be real e.g. // AWS_ACCESS_KEY_ID=fakeMyKeyId AWS_SECRET_ACCESS_KEY=fakeSecretAccessKey AWS_DEFAULT_REGION=local deno run --allow-env --allow-net -import { assertEquals } from "https://deno.land/std@0.77.0/testing/asserts.ts"; +import { assertEquals } from "https://deno.land/std@0.80.0/testing/asserts.ts"; import { APIGatewayProxyEvent, - Context + Context, } from "https://deno.land/x/lambda/mod.ts"; import { client } from "./client.ts"; import { test } from "./test_util.ts"; import { - list as listCandidate, get as getCandidate, + list as listCandidate, submit as submitCandidate, - TableName + TableName, } from "./api/candidate.ts"; test({ diff --git a/hello.ts b/hello.ts index 942d758..eb7b3bd 100644 --- a/hello.ts +++ b/hello.ts @@ -1,9 +1,10 @@ import { APIGatewayProxyEvent, APIGatewayProxyResult, - Context + Context, } from "https://deno.land/x/lambda/mod.ts"; +// deno-lint-ignore require-await export async function handler( event: APIGatewayProxyEvent, context: Context, diff --git a/runtime/artifacts b/runtime/artifacts index a0a72d0..edadd2e 100644 --- a/runtime/artifacts +++ b/runtime/artifacts @@ -24,6 +24,6 @@ DENO_DIR=/src/runtime/.deno_dir ./bin/deno bundle hello.ts hello.bundle.js rm -rf .deno_dir mkdir -p .deno_dir/deps/https/deno.land/x/lambda/ cp mod.ts .deno_dir/deps/https/deno.land/x/lambda/mod.ts -DENO_DIR=/src/runtime/.deno_dir ./bin/deno cache pad.ts +DENO_DIR=/src/runtime/.deno_dir ./bin/deno cache lock.ts cp -R .deno_dir/gen/file/$PWD/. .deno_dir/LAMBDA_TASK_ROOT -zip -qq pad.zip -x '.deno_dir/gen/file/*' -r .deno_dir pad.ts +zip -qq lock.zip -x '.deno_dir/gen/file/*' -r .deno_dir lock.ts diff --git a/runtime/bootstrap b/runtime/bootstrap index cc87a84..99f8798 100755 --- a/runtime/bootstrap +++ b/runtime/bootstrap @@ -5,6 +5,9 @@ SCRIPT_DIR=$(cd $(dirname $0); pwd) HANDLER_NAME=$(echo "$_HANDLER" | cut -d. -f2) HANDLER_FILE=$(echo "$_HANDLER" | cut -d. -f1) +# support deno in the /bin directory of the function (not only the layer) +PATH=$SCRIPT_DIR/bin:$PATH + API_ROOT=http://${AWS_LAMBDA_RUNTIME_API}/2018-06-01/runtime/ # If this ENV variable is set then copy that directory as DENO_DIR (default = .deno_dir). @@ -15,9 +18,8 @@ if [[ -z "$DENO_DIR" ]]; then fi # Potentially this could be overwritten HOWEVER several permissions are required for bootstrap. -# FIXME should this simply be -A? -# FIXME can plugins work?? (If so, it should be documented.) -DENO_FLAGS="-A" +# Note: Do can plugins work?? (If so, it should be documented.) +DENO_FLAGS="-A --no-check" DENO_CACHE_FLAGS="" # For unstable flags we must pass --unstable @@ -72,7 +74,10 @@ function investigate { [ -f $SCRIPT_DIR/bin/deno ] \ || error "missing deno executable" - deno eval 'Deno.version.deno' \ + type -P deno &> /dev/null \ + || error "deno executable not found in PATH" + + DENO_DIR=/tmp/deno_dir NO_COLOR=true deno eval 'Deno.version.deno' \ || error "bad deno executable" [ -f $LAMBDA_TASK_ROOT/$HANDLER_FILE ] \ @@ -86,14 +91,10 @@ function investigate { || error "lock file error: $(cat /tmp/lock.out)" fi - DENO_DIR=/tmp/deno_dir NO_COLOR=true deno cache $DENO_CACHE_FLAGS $LAMBDA_TASK_ROOT/$HANDLER_FILE 2> /dev/null \ + DENO_DIR=/tmp/deno_dir NO_COLOR=true deno cache $DENO_CACHE_FLAGS $LAMBDA_TASK_ROOT/$HANDLER_FILE &> /dev/null \ || error "unable to compile $HANDLER_FILE" - echo "import { $HANDLER_NAME } from '$LAMBDA_TASK_ROOT/$HANDLER_FILE';" > /tmp/runtime-test.js - DENO_DIR=/tmp/deno_dir NO_COLOR=true deno run $DENO_IMPORTMAP /tmp/runtime-test.js 2> /dev/null \ - || error "$HANDLER_FILE must export a function named '$HANDLER_NAME'"; - - # FIXME perhaps a bug in bootstrap? Should we always exit 1? Or not? + # e.g. the HANDLER_FILE threw an error or did not import HANDLER_NAME error "deno exited" } @@ -223,14 +224,15 @@ mkdir -p /tmp/deno_dir/gen/file$LAMBDA_TASK_ROOT # We cp first from the deno-lambda-layer. cp -R /opt/.deno_dir/gen/. /tmp/deno_dir/gen &> /dev/null \ && cp -R /opt/.deno_dir/deps/. /tmp/deno_dir/deps &> /dev/null \ - && cp -R /opt/.deno_dir/LAMBDA_TASK_ROOT/. /tmp/deno_dir/gen/file$LAMBDA_TASK_ROOT &> /dev/null \ || true # Then we overwrite with from the DENO_DIR in the function code. cp -R $LAMBDA_TASK_ROOT/$DENO_DIR/gen/. /tmp/deno_dir/gen &> /dev/null \ && cp -R $LAMBDA_TASK_ROOT/$DENO_DIR/deps/. /tmp/deno_dir/deps &> /dev/null \ && cp -R $LAMBDA_TASK_ROOT/$DENO_DIR/gen/. /tmp/deno_dir/gen &> /dev/null \ && cp -R $LAMBDA_TASK_ROOT/$DENO_DIR/LAMBDA_TASK_ROOT/. /tmp/deno_dir/gen/file$LAMBDA_TASK_ROOT &> /dev/null \ + || expr match "$HANDLER_FILE" ".*bundle.js" &> /dev/null \ || echo "warn: unable to import '$DENO_DIR/' as DENO_DIR" +# Note: We skip printing this warning if the filename endswith bundle.js. # FIXME remove DENO_FLAGS=DENO_FLAGS environment variable setting (used in testing only). DENO_DIR=/tmp/deno_dir DENO_PREFIX=$DENO_PREFIX DENO_FLAGS=$DENO_FLAGS NO_COLOR=true deno run $DENO_FLAGS /tmp/runtime.js \ diff --git a/runtime/generate_types.ts b/runtime/generate_types.ts index deeddb9..164fc3f 100644 --- a/runtime/generate_types.ts +++ b/runtime/generate_types.ts @@ -1,4 +1,4 @@ -import { assert } from "https://deno.land/std@0.77.0/testing/asserts.ts"; +import { assert } from "https://deno.land/std@0.80.0/testing/asserts.ts"; const unpkg = "https://unpkg.com/@types/aws-lambda@8.10.63/"; diff --git a/runtime/types.d.ts b/runtime/types.d.ts index b82d89e..b7522f4 100644 --- a/runtime/types.d.ts +++ b/runtime/types.d.ts @@ -1009,12 +1009,11 @@ export interface CodeBuildStateEventDetail { }; } -export interface CodeBuildCloudWatchStateEvent - extends - EventBridgeEvent< - "CodeBuild Build State Change", - CodeBuildStateEventDetail - > { +export interface CodeBuildCloudWatchStateEvent extends + EventBridgeEvent< + "CodeBuild Build State Change", + CodeBuildStateEventDetail + > { source: "aws.codebuild"; } diff --git a/tests/Dockerfile b/tests/Dockerfile index 7c64492..3355e10 100644 --- a/tests/Dockerfile +++ b/tests/Dockerfile @@ -1,11 +1,23 @@ # Note: This must be built in the .. context -FROM hayd/amazonlinux1-deno:1.6.0 -# This is the runtime used by AWS Lambda -# plus a compatible deno executable /bin/deno. -# https://github.com/hayd/deno_docker +FROM amazonlinux:2.0.20200722.0 +# This is _close to_ the Amazon Linux 2 AMI/image used by AWS Lambda. -RUN yum install -y unzip zip +ENV DENO_VERSION=1.6.1 + +# Note: We make the deno binary private (via _) so that it's not available in the PATH. +# In order for `deno` to be made available in the PATH it must be inserted into ./bin/ + +RUN yum makecache \ + && yum install unzip zip -y \ + && curl -fsSL https://github.com/denoland/deno/releases/download/v${DENO_VERSION}/deno-x86_64-unknown-linux-gnu.zip \ + --output deno.zip \ + && unzip deno.zip \ + && rm deno.zip \ + && chmod 777 deno \ + && mv deno /bin/_deno \ + && yum clean all \ + && rm -rf /var/cache/yum ENV AWS_LAMBDA_RUNTIME_API=127.0.0.1:1993 \ AWS_LAMBDA_FUNCTION_NAME=test \ @@ -21,16 +33,16 @@ ENV AWS_LAMBDA_RUNTIME_API=127.0.0.1:1993 \ # /var/task has function code # /opt has the layer code RUN mkdir -p /src/runtime/bin /src/tests/bin /var/task /opt \ - && cp /bin/deno /src/runtime/bin/deno \ - && cp /bin/deno /src/tests/bin/deno + && cp /bin/_deno /src/runtime/bin/deno \ + && cp /bin/_deno /src/tests/bin/deno ADD tests/deps.ts /src/tests/deps.ts -RUN deno cache /src/tests/deps.ts +RUN _deno cache /src/tests/deps.ts ADD hello.ts /src/runtime/hello.ts ADD hello.ts /src/tests/hello.ts -ADD tests/pad.ts /src/runtime/pad.ts -ADD tests/pad.ts /src/tests/pad.ts +ADD tests/lock.ts /src/runtime/lock.ts +ADD tests/lock.ts /src/tests/lock.ts ADD runtime /src/runtime WORKDIR /src/runtime @@ -40,16 +52,16 @@ RUN sh artifacts \ WORKDIR /src/tests # Note: We have to run since fetch doesn't write! -RUN deno cache --lock-write --lock=lock.json pad.ts \ +RUN _deno cache --lock-write --lock=lock.json lock.ts \ && echo {} > badlock.json ADD tests/server.ts server.ts -RUN deno cache server.ts +RUN _deno cache server.ts ADD tests/test.ts test.ts -RUN deno cache test.ts +RUN _deno cache test.ts ADD tests . -CMD ["test", "-A", "--unstable"] +CMD ["_deno", "test", "-A", "--unstable"] diff --git a/tests/compile_error.ts b/tests/compile_error.ts index b2de430..35655c2 100644 --- a/tests/compile_error.ts +++ b/tests/compile_error.ts @@ -1 +1 @@ -import { missing_import } from "./mod.ts"; +import { missingImport } from "./mod.ts"; diff --git a/tests/decorate.ts b/tests/decorate.ts index 5d75698..186de0d 100644 --- a/tests/decorate.ts +++ b/tests/decorate.ts @@ -1,15 +1,15 @@ import type { APIGatewayProxyEvent, - Context + Context, } from "https://deno.land/x/lambda/mod.ts"; -function decorate(target: any) {} +function decorate(target: unknown) {} @decorate class Foo { } -export async function handler(event: APIGatewayProxyEvent, context: Context) { +export function handler(event: APIGatewayProxyEvent, context: Context) { return { statusCode: 200, body: `decorated 🦕`, diff --git a/tests/deps.ts b/tests/deps.ts index 624bc2e..bb6f311 100644 --- a/tests/deps.ts +++ b/tests/deps.ts @@ -1,5 +1,5 @@ export { assert, assertEquals, -} from "https://deno.land/std@0.77.0/testing/asserts.ts"; -export { serve } from "https://deno.land/std@0.77.0/http/server.ts"; +} from "https://deno.land/std@0.80.0/testing/asserts.ts"; +export { serve } from "https://deno.land/std@0.80.0/http/server.ts"; diff --git a/tests/handlers.ts b/tests/handlers.ts index 5bf5640..279a2db 100644 --- a/tests/handlers.ts +++ b/tests/handlers.ts @@ -1,6 +1,6 @@ import type { + APIGatewayProxyEvent, Context, - APIGatewayProxyEvent } from "https://deno.land/x/lambda/mod.ts"; class MyError extends Error { @@ -10,16 +10,17 @@ class MyError extends Error { } } -export async function error(event: APIGatewayProxyEvent, context: Context) { +export function error(event: APIGatewayProxyEvent, context: Context) { throw new MyError("error thrown"); } -export async function foo(event: any, context: Context) { +// deno-lint-ignore no-explicit-any +export function foo(event: any, context: Context) { // is there a foo attribute?! who knows! return event.foo || "a string"; } -export async function withContext( +export function withContext( event: APIGatewayProxyEvent, context: Context, ) { @@ -33,13 +34,15 @@ export async function withContext( // Note: This is evaluated prior to the redefinition of console.log in bootstrap. // This is a devious trick to catch the output of console.log and friends. -let LOGGED: any[] = []; +let LOGGED: unknown[] = []; const _log = console.log; console.log = (...args) => { LOGGED.push(args); _log(args); }; -export async function log(event: any, context: Context) { + +// deno-lint-ignore no-explicit-any +export function log(event: any, context: Context) { LOGGED = []; // pretty print with newlines const message = JSON.stringify({ message: event.hello }, null, 2); @@ -48,40 +51,41 @@ export async function log(event: any, context: Context) { console.error("uh oh"); return { log: LOGGED.map((v) => { - if (v.length !== 1) { + if ((v as string[]).length !== 1) { throw new Error("expected only one string passed to console.log"); } - return v[0].replace(/[0-9]/g, "0"); + return (v as string)[0].replace(/[0-9]/g, "0"); }), }; } -export async function badPrefix(event: any, context: Context) { +// deno-lint-ignore no-explicit-any +export function badPrefix(event: any, context: Context) { // assert warning message on init: console.log(event.hello); const log = LOGGED.map((args) => { - // @ts-ignore + // @ts-ignore // to use Deno.internal return Deno[Deno.internal].inspectArgs(args); }); LOGGED = []; return { log: log }; } -export async function noArgs() { +export function noArgs() { return {}; } export async function runDeno(event: APIGatewayProxyEvent, context: Context) { const r = Deno.run({ cmd: ["deno", "--version"], stdout: "piped" }); const out = await r.output(); - const version = new TextDecoder().decode(out).split("\n")[0]; + const version = new TextDecoder().decode(out).split("\n")[0].split(" ")[1]; return { out: version }; } -export async function wrongArgs(a: number, b: number, c: number) { +export function wrongArgs(a: number, b: number, c: number) { return { result: a * b * c }; } -export async function xray(event: APIGatewayProxyEvent, context: Context) { +export function xray(event: APIGatewayProxyEvent, context: Context) { return { _X_AMZN_TRACE_ID: Deno.env.get("_X_AMZN_TRACE_ID") }; } diff --git a/tests/hello.js b/tests/hello.js index 4caf4cc..7b4680d 100644 --- a/tests/hello.js +++ b/tests/hello.js @@ -1,4 +1,4 @@ -export async function handler(event, context) { +export function handler(event, context) { return { statusCode: 200, body: `Welcome to deno ${Deno.version.deno} 🦕`, diff --git a/tests/importmap.json b/tests/importmap.json index b4795e1..10d85d3 100644 --- a/tests/importmap.json +++ b/tests/importmap.json @@ -1,5 +1,5 @@ { "imports": { - "std/": "https://deno.land/std@0.38.0/" + "std/": "https://deno.land/std@0.80.0/" } } diff --git a/tests/importmap.ts b/tests/importmap.ts index bf29197..14b9420 100644 --- a/tests/importmap.ts +++ b/tests/importmap.ts @@ -1,11 +1,10 @@ import type { APIGatewayProxyEvent, - Context + Context, } from "https://deno.land/x/lambda/mod.ts"; -// FIXME use a different file here (see also pad.ts) -import { pad } from "std/strings/pad.ts"; +import { delay } from "std/async/delay.ts"; -export function handler(event: any, context: Context) { - const strLen: number = Number(event.strLen) || 5; - return pad("deno", strLen); +export async function handler(event: unknown, context: Context) { + await delay(10); + return "deno"; } diff --git a/tests/lock.ts b/tests/lock.ts new file mode 100644 index 0000000..d288226 --- /dev/null +++ b/tests/lock.ts @@ -0,0 +1,20 @@ +// delay.ts was chosen since it has no dependencies. +// i.e. importing downloads precisely one file from deno.land. +import { delay } from "https://deno.land/std@0.80.0/async/delay.ts"; + +export async function handler(event: unknown, context: unknown) { + await delay(10); + return "deno"; +} + +// This is here as we want to require the file have a locked dependency. +export function assertLock(event: unknown, context: unknown) { + // assert --lock was passed + // FIXME remove this env hack and pull out the actual cli args from Deno itself. + // (we shouldn't need to set DENO_FLAGS for deno in bootstrap.) + const flags: string = Deno.env.get("DENO_FLAGS")!; + if (/--lock=lock\.json/.test(flags)) { + return {}; + } + throw new Error("--lock=lock.json not passed to deno run " + flags); +} diff --git a/tests/pad.ts b/tests/pad.ts deleted file mode 100644 index dac1115..0000000 --- a/tests/pad.ts +++ /dev/null @@ -1,23 +0,0 @@ -// pad.ts was chosen since it has no dependencies. -// i.e. we must download precisely one file from deno.land. -// FIXME: it has since been removed from std so this should be refactored. -// (see also importmap.ts) -import { pad } from "https://deno.land/std@0.38.0/strings/pad.ts"; - -export function handler(event: any, context: any) { - const strLen: number = Number(event.strLen) || 5; - return pad("deno", strLen); -} - -// FIXME why is this function in pad.ts? -export async function assertLock(event: any, context: any) { - // assert --lock was passed - // Note: This is a file with external imports in order for -lock to be used. - // FIXME remove this env hack and pull out the actual cli args from Deno itself. - // (we shouldn't need to set DENO_FLAGS for deno in bootstrap.) - const flags: string = Deno.env.get("DENO_FLAGS")!; - if (/--lock=lock\.json/.test(flags)) { - return {}; - } - throw new Error("--lock=lock.json not passed to deno run " + flags); -} diff --git a/tests/server.ts b/tests/server.ts index 478e874..e4e6d22 100644 --- a/tests/server.ts +++ b/tests/server.ts @@ -16,8 +16,8 @@ export interface TestJson { function bootstrap(testJson: TestJson) { const bootstrapScript = [...Deno.readDirSync("/var/task/")] - .map((x) => x.name) - .includes("bootstrap") + .map((x) => x.name) + .includes("bootstrap") ? "/var/task/bootstrap" : "/opt/bootstrap"; @@ -79,7 +79,7 @@ export async function serveEvents(testJson: TestJson) { "lambda-runtime-deadline-ms": (Date.now() + 300000).toString(), }); if (testJson.headers) { - for (let [k, v] of Object.entries(testJson.headers)) { + for (const [k, v] of Object.entries(testJson.headers)) { const vv = typeof v === "string" ? v : JSON.stringify(v); assert(typeof vv === "string"); headers.append(k, vv); diff --git a/tests/test_badlock.json b/tests/test_badlock.json index f726231..839c507 100644 --- a/tests/test_badlock.json +++ b/tests/test_badlock.json @@ -1,12 +1,12 @@ { - "env": { "_HANDLER": "pad.assertLock", "DENO_LOCK": "badlock.json" }, + "env": { "_HANDLER": "lock.assertLock", "DENO_LOCK": "badlock.json" }, "events": [{ "hello": "deno" }], "expected": [ { "status": "error", - "content": "{\"errorMessage\" : \"lock file error: The source code is invalid, as it does not match the expected hash in the lock file.\n Specifier: https://deno.land/std@0.38.0/strings/pad.ts\n Lock file: badlock.json\", \"errorType\" : \"InitException\"}" + "content": "{\"errorMessage\" : \"lock file error: The source code is invalid, as it does not match the expected hash in the lock file.\n Specifier: https://deno.land/std@0.80.0/async/delay.ts\n Lock file: badlock.json\", \"errorType\" : \"InitException\"}" } ], - "files": ["pad.ts", "badlock.json"], + "files": ["lock.ts", "badlock.json"], "layer": "deno-lambda-layer.zip" } diff --git a/tests/test_bundle.json b/tests/test_bundle.json index 2f619f3..9ddc807 100644 --- a/tests/test_bundle.json +++ b/tests/test_bundle.json @@ -7,11 +7,11 @@ "expected": [ { "status": "ok", - "content": "{\"statusCode\":200,\"headers\":{\"content-type\":\"text/html;charset=utf8\"},\"body\":\"Welcome to deno 1.6.0 🦕\"}" + "content": "{\"statusCode\":200,\"headers\":{\"content-type\":\"text/html;charset=utf8\"},\"body\":\"Welcome to deno 1.6.1 🦕\"}" }, { "status": "ok", - "content": "{\"statusCode\":200,\"headers\":{\"content-type\":\"text/html;charset=utf8\"},\"body\":\"Welcome to deno 1.6.0 🦕\"}" + "content": "{\"statusCode\":200,\"headers\":{\"content-type\":\"text/html;charset=utf8\"},\"body\":\"Welcome to deno 1.6.1 🦕\"}" } ], "files": ["hello.bundle.js"], diff --git a/tests/test_denodir.json b/tests/test_denodir.json index 018ee85..e86d3b6 100644 --- a/tests/test_denodir.json +++ b/tests/test_denodir.json @@ -1,18 +1,18 @@ { "env": { - "_HANDLER": "pad.handler" + "_HANDLER": "lock.handler" }, "events": [{ "hello": "deno" }, { "strLen": "6" }], "expected": [ { "status": "ok", - "content": "\" deno\"" + "content": "\"deno\"" }, { "status": "ok", - "content": "\" deno\"" + "content": "\"deno\"" } ], - "files": "pad.zip", + "files": "lock.zip", "layer": "deno-lambda-layer.zip" } diff --git a/tests/test_example_zip.json b/tests/test_example_zip.json index 619d0af..b708c86 100644 --- a/tests/test_example_zip.json +++ b/tests/test_example_zip.json @@ -4,11 +4,11 @@ "expected": [ { "status": "ok", - "content": "{\"statusCode\":200,\"headers\":{\"content-type\":\"text/html;charset=utf8\"},\"body\":\"Welcome to deno 1.6.0 🦕\"}" + "content": "{\"statusCode\":200,\"headers\":{\"content-type\":\"text/html;charset=utf8\"},\"body\":\"Welcome to deno 1.6.1 🦕\"}" }, { "status": "ok", - "content": "{\"statusCode\":200,\"headers\":{\"content-type\":\"text/html;charset=utf8\"},\"body\":\"Welcome to deno 1.6.0 🦕\"}" + "content": "{\"statusCode\":200,\"headers\":{\"content-type\":\"text/html;charset=utf8\"},\"body\":\"Welcome to deno 1.6.1 🦕\"}" } ], "files": "deno-lambda-example.zip", diff --git a/tests/test_importmap.json b/tests/test_importmap.json index 48e431b..b901bc4 100644 --- a/tests/test_importmap.json +++ b/tests/test_importmap.json @@ -7,7 +7,7 @@ "expected": [ { "status": "ok", - "content": "\" deno\"" + "content": "\"deno\"" } ], "files": ["importmap.ts", "importmap.json"], diff --git a/tests/test_js.json b/tests/test_js.json index 722c048..2778cd4 100644 --- a/tests/test_js.json +++ b/tests/test_js.json @@ -4,11 +4,11 @@ "expected": [ { "status": "ok", - "content": "{\"statusCode\":200,\"body\":\"Welcome to deno 1.6.0 🦕\"}" + "content": "{\"statusCode\":200,\"body\":\"Welcome to deno 1.6.1 🦕\"}" }, { "status": "ok", - "content": "{\"statusCode\":200,\"body\":\"Welcome to deno 1.6.0 🦕\"}" + "content": "{\"statusCode\":200,\"body\":\"Welcome to deno 1.6.1 🦕\"}" } ], "files": ["hello.js"], diff --git a/tests/test_lock.json b/tests/test_lock.json index 9d9662e..40b02a5 100644 --- a/tests/test_lock.json +++ b/tests/test_lock.json @@ -1,5 +1,5 @@ { - "env": { "_HANDLER": "pad.assertLock", "DENO_LOCK": "lock.json" }, + "env": { "_HANDLER": "lock.assertLock", "DENO_LOCK": "lock.json" }, "events": [{ "hello": "deno" }], "expected": [ { @@ -7,6 +7,6 @@ "content": "{}" } ], - "files": ["pad.ts", "lock.json"], + "files": ["lock.ts", "lock.json"], "layer": "deno-lambda-layer.zip" } diff --git a/tests/test_missing_handler.json b/tests/test_missing_handler.json index 86ff737..baa9c9a 100644 --- a/tests/test_missing_handler.json +++ b/tests/test_missing_handler.json @@ -4,7 +4,7 @@ "expected": [ { "status": "error", - "content": "{\"errorMessage\" : \"handlers.ts must export a function named 'missing'\", \"errorType\" : \"InitException\"}" + "content": "{\"errorMessage\" : \"deno exited\", \"errorType\" : \"InitException\"}" } ], "files": ["handlers.ts"], diff --git a/tests/test_run_deno.json b/tests/test_run_deno.json index feb342e..7487f33 100644 --- a/tests/test_run_deno.json +++ b/tests/test_run_deno.json @@ -4,11 +4,11 @@ "expected": [ { "status": "ok", - "content": "{\"out\":\"deno 1.6.0 (release, x86_64-unknown-linux-gnu)\"}" + "content": "{\"out\":\"1.6.1\"}" }, { "status": "ok", - "content": "{\"out\":\"deno 1.6.0 (release, x86_64-unknown-linux-gnu)\"}" + "content": "{\"out\":\"1.6.1\"}" } ], "files": ["handlers.ts"], diff --git a/tests/test_self_contained.json b/tests/test_self_contained.json index 0d0044e..ab7905f 100644 --- a/tests/test_self_contained.json +++ b/tests/test_self_contained.json @@ -4,11 +4,11 @@ "expected": [ { "status": "ok", - "content": "{\"statusCode\":200,\"headers\":{\"content-type\":\"text/html;charset=utf8\"},\"body\":\"Welcome to deno 1.6.0 🦕\"}" + "content": "{\"statusCode\":200,\"headers\":{\"content-type\":\"text/html;charset=utf8\"},\"body\":\"Welcome to deno 1.6.1 🦕\"}" }, { "status": "ok", - "content": "{\"statusCode\":200,\"headers\":{\"content-type\":\"text/html;charset=utf8\"},\"body\":\"Welcome to deno 1.6.0 🦕\"}" + "content": "{\"statusCode\":200,\"headers\":{\"content-type\":\"text/html;charset=utf8\"},\"body\":\"Welcome to deno 1.6.1 🦕\"}" } ], "files": ["hello.ts", "bootstrap", "bin/deno"] diff --git a/tests/test_simple.json b/tests/test_simple.json index e870ffa..b9544cc 100644 --- a/tests/test_simple.json +++ b/tests/test_simple.json @@ -4,11 +4,11 @@ "expected": [ { "status": "ok", - "content": "{\"statusCode\":200,\"headers\":{\"content-type\":\"text/html;charset=utf8\"},\"body\":\"Welcome to deno 1.6.0 🦕\"}" + "content": "{\"statusCode\":200,\"headers\":{\"content-type\":\"text/html;charset=utf8\"},\"body\":\"Welcome to deno 1.6.1 🦕\"}" }, { "status": "ok", - "content": "{\"statusCode\":200,\"headers\":{\"content-type\":\"text/html;charset=utf8\"},\"body\":\"Welcome to deno 1.6.0 🦕\"}" + "content": "{\"statusCode\":200,\"headers\":{\"content-type\":\"text/html;charset=utf8\"},\"body\":\"Welcome to deno 1.6.1 🦕\"}" } ], "files": ["hello.ts"],