Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
109 changes: 109 additions & 0 deletions API.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,115 @@
# API Reference <a name="API Reference" id="api-reference"></a>


## Structs <a name="Structs" id="Structs"></a>

### TypeScriptCompilerPlugins <a name="TypeScriptCompilerPlugins" id="@functionless/projen.TypeScriptCompilerPlugins"></a>

Extends the {@link TypeScriptCompilerOptions} interface with the {@link plugins} property for configuring Language Service Plugins and ts-patch plugins.

> [https://github.com/projen/projen/issues/1482](https://github.com/projen/projen/issues/1482)

#### Initializer <a name="Initializer" id="@functionless/projen.TypeScriptCompilerPlugins.Initializer"></a>

```typescript
import { TypeScriptCompilerPlugins } from '@functionless/projen'

const typeScriptCompilerPlugins: TypeScriptCompilerPlugins = { ... }
```

#### Properties <a name="Properties" id="Properties"></a>

| **Name** | **Type** | **Description** |
| --- | --- | --- |
| <code><a href="#@functionless/projen.TypeScriptCompilerPlugins.property.plugins">plugins</a></code> | <code><a href="#@functionless/projen.TypeScriptPlugin">TypeScriptPlugin</a>[]</code> | A list of Language Service and ts-patch plugins to run as part of TypeScript compilation. |

---

##### `plugins`<sup>Optional</sup> <a name="plugins" id="@functionless/projen.TypeScriptCompilerPlugins.property.plugins"></a>

```typescript
public readonly plugins: TypeScriptPlugin[];
```

- *Type:* <a href="#@functionless/projen.TypeScriptPlugin">TypeScriptPlugin</a>[]

A list of Language Service and ts-patch plugins to run as part of TypeScript compilation.

---

### TypeScriptPlugin <a name="TypeScriptPlugin" id="@functionless/projen.TypeScriptPlugin"></a>

Configures a Language Service or Transformer Plugin to run as part of TypeScript compilation.

> [https://github.com/microsoft/TypeScript/wiki/Writing-a-Language-Service-Plugin](https://github.com/microsoft/TypeScript/wiki/Writing-a-Language-Service-Plugin)

#### Initializer <a name="Initializer" id="@functionless/projen.TypeScriptPlugin.Initializer"></a>

```typescript
import { TypeScriptPlugin } from '@functionless/projen'

const typeScriptPlugin: TypeScriptPlugin = { ... }
```

#### Properties <a name="Properties" id="Properties"></a>

| **Name** | **Type** | **Description** |
| --- | --- | --- |
| <code><a href="#@functionless/projen.TypeScriptPlugin.property.name">name</a></code> | <code>string</code> | Name of a NPM module that implements the TypeScript Language Service Plugin interface. |
| <code><a href="#@functionless/projen.TypeScriptPlugin.property.transform">transform</a></code> | <code>string</code> | Path to a module implementing the ts-patch Transformer Plugin interface. |

---

##### `name`<sup>Optional</sup> <a name="name" id="@functionless/projen.TypeScriptPlugin.property.name"></a>

```typescript
public readonly name: string;
```

- *Type:* string

Name of a NPM module that implements the TypeScript Language Service Plugin interface.

It must be the name of a NPM module and cannot be a path to an individual JS file.

Valid:
```ts
{
name: "@functionless/language-service"
}
```

Invalid:
```ts
{
name: "@functionless/language-service/lib/plugin"
}
```

> [https://github.com/microsoft/TypeScript/wiki/Writing-a-Language-Service-Plugin](https://github.com/microsoft/TypeScript/wiki/Writing-a-Language-Service-Plugin)

---

##### `transform`<sup>Optional</sup> <a name="transform" id="@functionless/projen.TypeScriptPlugin.property.transform"></a>

```typescript
public readonly transform: string;
```

- *Type:* string

Path to a module implementing the ts-patch Transformer Plugin interface.

Example:
```ts
{
transform: "functionless/lib/compile"
}
```

> [https://github.com/nonara/ts-patch](https://github.com/nonara/ts-patch)

---

## Classes <a name="Classes" id="Classes"></a>

Expand Down
120 changes: 105 additions & 15 deletions src/component.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,80 @@
import { Component } from "projen";
import {
TypescriptConfig,
TypeScriptCompilerOptions,
} from "projen/lib/javascript";
import { TypeScriptProject } from "projen/lib/typescript";

/**
* Extends the {@link TypeScriptCompilerOptions} interface with the {@link plugins} property
* for configuring Language Service Plugins and ts-patch plugins.
*
* @see https://github.com/projen/projen/issues/1482
*/
export interface TypeScriptCompilerPlugins {
/**
* A list of Language Service and ts-patch plugins to run as part of TypeScript compilation.
*/
readonly plugins?: TypeScriptPlugin[];
}

/**
* Configures a Language Service or Transformer Plugin to run as part of TypeScript compilation.
*
* @see https://github.com/nonara/ts-patch
* @see https://github.com/microsoft/TypeScript/wiki/Writing-a-Language-Service-Plugin
*/
export interface TypeScriptPlugin {
/**
* Path to a module implementing the ts-patch Transformer Plugin interface.
*
* Example:
* ```ts
* {
* transform: "functionless/lib/compile"
* }
* ```
*
* @see https://github.com/nonara/ts-patch
*/
readonly transform?: string;
/**
* Name of a NPM module that implements the TypeScript Language Service Plugin interface
*
* It must be the name of a NPM module and cannot be a path to an individual JS file.
*
* Valid:
* ```ts
* {
* name: "@functionless/language-service"
* }
* ```
*
* Invalid:
* ```ts
* {
* name: "@functionless/language-service/lib/plugin"
* }
* ```
*
* @see https://github.com/microsoft/TypeScript/wiki/Writing-a-Language-Service-Plugin
*/
readonly name?: string;
/**
* Optional configuration data for the plugin.
*
* Example:
* ```ts
* {
* name: "@functionless/language-service",
* // configuration property will be passed to the language service plugin
* verbose: true
* }
* ```
*/
readonly [key: string]: any;
}

/**
* Component that configures a TypeScript project to use Functionless by adding the
* necessary dependencies and setting up ts-patch.
Expand All @@ -23,21 +97,37 @@ export class Functionless extends Component {
this.tsProject.addDevDeps(...Functionless.devDependencies);
this.tsProject.addDeps(...Functionless.dependencies);

// TODO: when optional?
if (this.tsProject.tsconfig) {
// https://github.com/projen/projen/issues/1482
// TODO: type
const compilerOptions = this.tsProject.tsconfig.compilerOptions as any;
const plugins: any[] = compilerOptions.plugins ?? [];

plugins.push({
transform: `${Functionless.coreDependency}/lib/compile`,
});
plugins.push({
name: Functionless.languageServiceDependency,
});

compilerOptions.plugins = plugins;
const transformerPlugin = {
transform: `${Functionless.coreDependency}/lib/compile`,
};

const languageServicePlugin = {
name: Functionless.languageServiceDependency,
};

configureTsConfig(this.tsProject.tsconfig, [
transformerPlugin,
languageServicePlugin,
]);
configureTsConfig(this.tsProject.tsconfigDev, [transformerPlugin]);

function configureTsConfig(
config:
| undefined
| (TypescriptConfig & {
compilerOptions: TypeScriptCompilerOptions &
TypeScriptCompilerPlugins;
}),
plugins: TypeScriptPlugin[]
) {
if (config) {
// @ts-ignore - hack: write to readonly field (JSII forces us to use readonly)
config.compilerOptions.plugins = config.compilerOptions.plugins
? // copy the array because tsconfig and tsconfigDev are sharing the same data
// we don't want to rely on that always being true
[...config.compilerOptions.plugins, ...plugins]
: [...plugins];
}
}

this.tsProject.addTask("prepare", {
Expand Down
4 changes: 4 additions & 0 deletions test/component.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -31,4 +31,8 @@ test("add dependency and ts plugin", () => {
{ transform: `${Functionless.coreDependency}/lib/compile` },
{ name: Functionless.languageServiceDependency },
]);
expect((project.tsconfigDev!.compilerOptions as any).plugins).toEqual([
{ transform: "some other transform" },
{ transform: `${Functionless.coreDependency}/lib/compile` },
]);
});