From 97f82b9dbbfef61793b843dd940c36494ce284b0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Barthelet?= Date: Wed, 21 Jul 2021 11:32:33 +0200 Subject: [PATCH] Add types definition for serverless.ts --- README.md | 2 ++ docs/serverless-types.md | 35 +++++++++++++++++++++++++++++++++++ package.json | 4 ++-- src/plugin.ts | 11 ++++++++--- 4 files changed, 47 insertions(+), 5 deletions(-) create mode 100644 docs/serverless-types.md diff --git a/README.md b/README.md index 44a08dd2..bf7328ca 100644 --- a/README.md +++ b/README.md @@ -131,6 +131,8 @@ To eject: - copy the parts you want to turn into CloudFormation and paste them in the [`resources` section of serverless.yml](https://www.serverless.com/framework/docs/providers/aws/guide/resources/) - don't forget to remove from `serverless.yml` the Lift constructs you have turned into CloudFormation +## [Types definition for Lift constructs](docs/serverless-types.md) + --- Lift is built and maintained with love ❤️ by diff --git a/docs/serverless-types.md b/docs/serverless-types.md new file mode 100644 index 00000000..a2ba112f --- /dev/null +++ b/docs/serverless-types.md @@ -0,0 +1,35 @@ +# Lift Typescript definitions + +While YAML remains the most popular declarative syntax for Serverless service file definition - a.k.a `serverless.yml` - you can also use Javascript/Typescript definitions - i.e. `serverless.js` and `serverless.ts`. You can find more information on using JS/TS service file in the [Serverless official documentation](https://www.serverless.com/framework/docs/providers/aws/guide/intro#services). + +Generated Typescript types for the service file from [@serverless/typescript](https://github.com/serverless/typescript) do NOT include `constructs` definition from Lift. + +In order to cope this issue, Lift exports a type definition you can use in conjonction with the official Serverless definition: + +_serverless.ts_ +```ts +import type { AWS } from '@serverless/typescript'; +import type { Lift } from "serverless-lift"; + +const serverlessConfiguration: AWS & Lift = { + service: 'myService', + frameworkVersion: '2', + plugins: ['serverless-lift'], + constructs: { + avatars: { + type: 'storage', + }, + }, + provider: { + name: 'aws', + runtime: 'nodejs14.x', + }, + functions: { + hello: { + handler: 'src/publisher.handler', + } + } +}; + +module.exports = serverlessConfiguration; +``` diff --git a/package.json b/package.json index dac8c06a..6c13e303 100644 --- a/package.json +++ b/package.json @@ -74,7 +74,7 @@ "lint": "eslint .", "check-format": "prettier --check .", "type": "tsc --noEmit", - "build": "etsc", + "build": "etsc && tsc --emitDeclarationOnly", "watch": "nodemon", "test": "jest", "prepare": "husky install && npm run build" @@ -87,7 +87,7 @@ "eslint --fix" ] }, - "types": "lib/index.d.ts", + "types": "dist/src/plugin.d.ts", "peerDependencies": { "serverless": "^2.36.0" } diff --git a/src/plugin.ts b/src/plugin.ts index baa57f04..f9bb1e22 100644 --- a/src/plugin.ts +++ b/src/plugin.ts @@ -5,6 +5,7 @@ import * as path from "path"; import { readFileSync } from "fs"; import { dump } from "js-yaml"; import { DefaultTokenResolver, Lazy, StringConcat, Tokenization } from "@aws-cdk/core"; +import { FromSchema } from "json-schema-to-ts"; import type { CommandsDefinition, DeprecatedVariableResolver, @@ -30,11 +31,11 @@ const CONSTRUCTS_DEFINITION = { }, required: ["type"], }, - ] as Record[], + ], }, }, additionalProperties: false, -}; +} as const; /** * Serverless plugin @@ -97,7 +98,7 @@ class LiftPlugin { } private registerConstructsSchema() { - this.schema.patternProperties[CONSTRUCT_ID_PATTERN].allOf.push({ + (this.schema.patternProperties[CONSTRUCT_ID_PATTERN].allOf as unknown as Record[]).push({ oneOf: this.getAllConstructClasses().map((Construct) => { return this.defineConstructSchema(Construct.type, Construct.schema); }), @@ -349,4 +350,8 @@ class LiftPlugin { } } +export type Lift = { + constructs: FromSchema; +}; + module.exports = LiftPlugin;