Skip to content

Commit

Permalink
feat(types): allow types overriding
Browse files Browse the repository at this point in the history
Instead of relying on new types, this PR allow users to rely on types overriding for their endpoints.
That way, we can override Whook's types without having to change their names, especially in the various generators of code.
  • Loading branch information
nfroidure committed Oct 27, 2021
1 parent 0dcba31 commit 150a2c3
Show file tree
Hide file tree
Showing 27 changed files with 398 additions and 200 deletions.
27 changes: 21 additions & 6 deletions packages/whook-authorization/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -110,28 +110,43 @@ async function initWrappers(): Promise<WhookWrapper<any, any>[]> {
}
```

Declare this module types in your `src/whook.d.ts` type
definitions:
```diff
+ import type { WhookAuthorizationConfig } from '@whook/authorization';

declare module '@whook/whook' {

// ...

export interface WhookConfigs
- extends WhookBaseConfigs {}
+ extends WhookBaseConfigs, WhookAuthorizationConfig {}

// ...

}
```

Then add the config and the errors descriptors or provide your
own (usually in `src/config/common/config.js`):
```diff
import { DEFAULT_ERRORS_DESCRIPTORS } from '@whook/http-router';
+ import {
+ AUTHORIZATION_ERRORS_DESCRIPTORS,
+ WhookAuthorizationConfig
+ } from '@whook/authorization';
import type { WhookConfigs } from '@whook/whook';

// ...

export type AppConfigs = WhookConfigs &
+ WhookAuthorizationConfig &
APIConfig;

const CONFIG: AppConfigs = {
const CONFIG: WhookConfigs = {
// ...
- ERRORS_DESCRIPTORS: DEFAULT_ERRORS_DESCRIPTORS,
+ ERRORS_DESCRIPTORS: {
+ ...DEFAULT_ERRORS_DESCRIPTORS,
+ ...AUTHORIZATION_ERRORS_DESCRIPTORS,
+ },
+ DEFAULT_MECHANISM: 'bearer',
// ...
};

Expand Down
52 changes: 37 additions & 15 deletions packages/whook-aws-lambda/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -108,35 +108,57 @@ export async function prepareBuildEnvironment(
}
```

And add the AWS Lambda config (usually in `src/config/common/config.js`):

Declare this module types in your `src/whook.d.ts` type
definitions:
```diff
+ import type { WhookCompilerConfig } from '@whook/whook';
+ import type {
+ WhookAPIOperationGCPFunctionConfig
+ WhookAPIOperationAWSLambdaConfig
+ } from '@whook/aws-lambda';

// ...
declare module '@whook/whook' {

// ...

export interface WhookConfigs
- extends WhookBaseConfigs {}
+ extends WhookBaseConfigs, WhookCompilerConfig {}

// ...

export interface WhookAPIHandlerDefinition<
T extends Record<string, unknown> = Record<string, unknown>,
U extends {
[K in keyof U]: K extends `x-${string}` ? Record<string, unknown> : never;
} = unknown,
> extends WhookBaseAPIHandlerDefinition<T, U> {
operation: U & WhookAPIOperation<
T &
+ WhookAPIOperationAWSLambdaConfig<{
+ myCronBodyProp: string,
+ }> &
WhookAPIOperationCORSConfig
>;
}

export type AppConfigs = WhookConfigs &
+ WhookCompilerConfig &
APIConfig;
}
```

const CONFIG: AppConfigs = {
And add the AWS Lambda config (usually in `src/config/common/config.js`):

```diff
import type { WhookConfigs } from '@whook/whook';

// ...

const CONFIG: WhookConfigs = {
// ...
+ COMPILER_OPTIONS: {
+ externalModules: [],
+ ignoredModules: [],
+ target: '14',
+ },
};

// Export custom handlers definitions
export type APIHandlerDefinition = WhookAPIHandlerDefinition<
+ WhookAPIOperationAWSLambdaConfig &
WhookAPIOperationSwaggerConfig
>;

export default CONFIG;
```

Expand Down
76 changes: 52 additions & 24 deletions packages/whook-aws-lambda/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -64,34 +64,61 @@ export type WhookBuildConfig = {
BUILD_OPTIONS?: BuildOptions;
BUILD_PARALLELISM?: number;
};
export type WhookAPIOperationAWSLambdaConfig<
T extends {
type?:
| 'http'
| 'cron'
| 'consumer'
| 'transformer'
| 'kafka'
| 's3'
| 'log';
} = {
type?:
| 'http'
| 'cron'
| 'consumer'
| 'transformer'
| 'kafka'
| 's3'
| 'log';
},
> = {
export type WhookAWSLambdaBaseConfiguration = {
sourceOperationId?: string;
staticFiles?: string[];
compilerOptions?: WhookCompilerOptions;
suffix?: string;
memory?: number;
timeout?: number;
} & T;
};
export type WhookAWSLambdaBaseHTTPConfiguration = {
type: 'http';
};
export type WhookAWSLambdaBaseCronConfiguration<
T extends Record<string, unknown>,
> = {
type: 'cron';
schedules: {
rule: string;
body?: T;
enabled: boolean;
}[];
};
export type WhookAWSLambdaBaseConsumerConfiguration = {
type: 'consumer';
enabled: boolean;
};
export type WhookAWSLambdaBaseTransformerConfiguration = {
type: 'transformer';
enabled: boolean;
};
export type WhookAWSLambdaBaseKafkaConsumerConfiguration = {
type: 'kafka';
enabled: boolean;
};
export type WhookAWSLambdaBaseLogSubscriberConfiguration = {
type: 'log';
enabled: boolean;
};
export type WhookAWSLambdaBaseS3Configuration = {
type: 's3';
enabled: boolean;
};
export type WhookAWSLambdaConfiguration<
T extends Record<string, unknown> = Record<string, unknown>,
> =
| WhookAWSLambdaBaseHTTPConfiguration
| WhookAWSLambdaBaseCronConfiguration<T>
| WhookAWSLambdaBaseConsumerConfiguration
| WhookAWSLambdaBaseTransformerConfiguration
| WhookAWSLambdaBaseKafkaConsumerConfiguration
| WhookAWSLambdaBaseLogSubscriberConfiguration
| WhookAWSLambdaBaseS3Configuration;

export type WhookAPIOperationAWSLambdaConfig<
T extends Record<string, unknown> = Record<string, unknown>,
> = WhookAWSLambdaBaseConfiguration & WhookAWSLambdaConfiguration<T>;

const readFileAsync = util.promisify(fs.readFile) as (
path: string,
Expand Down Expand Up @@ -354,8 +381,9 @@ async function buildAnyLambda(
const { operationId } = operation;

try {
const whookConfig: WhookAPIOperationAWSLambdaConfig =
operation['x-whook'] || {};
const whookConfig: WhookAPIOperationAWSLambdaConfig = operation[
'x-whook'
] || { type: 'http' };
const operationType = whookConfig.type || 'http';
const sourceOperationId = whookConfig.sourceOperationId;
const entryPoint = operationId;
Expand Down
46 changes: 33 additions & 13 deletions packages/whook-cors/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -37,21 +37,44 @@ async function initWrappers(): Promise<WhookWrapper<any, any>[]> {
}
```

And add the CORS config (usually in `src/config/common/config.js`):

Declare this module types in your `src/whook.d.ts` type
definitions:
```diff
+ import type {
+ CORSConfig,
+ WhookAPIOperationCORSConfig,
+ } from '@whook/cors';

// ...
declare module '@whook/whook' {

// ...

export interface WhookConfigs
- extends WhookBaseConfigs {}
+ extends WhookBaseConfigs, CORSConfig {}

// ...

export type AppConfigs = WhookConfigs &
+ CORSConfig &
APIConfig;
export interface WhookAPIHandlerDefinition<
T extends Record<string, unknown> = Record<string, unknown>,
U extends {
[K in keyof U]: K extends `x-${string}` ? Record<string, unknown> : never;
} = unknown,
> extends WhookBaseAPIHandlerDefinition<T, U> {
operation: U & WhookAPIOperation<
T &
WhookAPIOperationSwaggerConfig & WhookAPIOperationCORSConfig
>;
}
}
```

And add the CORS config (usually in `src/config/common/config.js`):

const CONFIG: AppConfigs = {
```diff
import type { WhookConfigs } from '@whook/whook';

const CONFIG: WhookConfigs = {
// ...
+ CORS: {
+ 'Access-Control-Allow-Origin': '*',
Expand All @@ -70,12 +93,6 @@ const CONFIG: AppConfigs = {
+ },
};

// Export custom handlers definitions
export type APIHandlerDefinition = WhookAPIHandlerDefinition<
+ WhookAPIOperationCORSConfig &
WhookAPIOperationSwaggerConfig
>;

export default CONFIG;
```

Expand Down Expand Up @@ -128,6 +145,9 @@ async function initAPI({
To see a real example have a look at the
[`@whook/example`](https://github.com/nfroidure/whook/tree/master/packages/whook-example).

Note that you can define individual CORS values on the
handler definitions usins the `x-whook` property.

[//]: # (::contents:end)

# API
Expand Down
35 changes: 2 additions & 33 deletions packages/whook-example/src/config/common/config.ts
Original file line number Diff line number Diff line change
@@ -1,13 +1,5 @@
import { DEFAULT_ERRORS_DESCRIPTORS } from '@whook/http-router';
import type { WhookAuthorizationConfig } from '@whook/authorization';
import type {
WhookAPIOperationSwaggerConfig,
WhookSwaggerUIConfig,
} from '@whook/swagger-ui';
import type { WhookAPIOperationCORSConfig, WhookCORSConfig } from '@whook/cors';
import type { WhookAPIHandlerDefinition, WhookConfigs } from '@whook/whook';
import type { APIConfig } from '../../services/API';
import type { JWTServiceConfig } from 'jwt-service';
import type { WhookConfigs } from '@whook/whook';

/* Architecture Note #2: Configuration
Expand All @@ -23,40 +15,17 @@ const packageConf = require('../../../package');
const DEBUG_NODE_ENVS = ['test', 'development', 'staging'];
const NODE_ENVS = [...DEBUG_NODE_ENVS, 'uat', 'production'];

/* Architecture Note #2.1: Typings
The configuration is typed so that you are sure you cannot
produce a bad configuration for your API.
*/
export type AppConfigs = WhookConfigs &
WhookAuthorizationConfig &
WhookSwaggerUIConfig &
WhookCORSConfig &
APIConfig &
JWTServiceConfig;

/* Architecture Note #3.2.3: Typings
Here we export a custom handler definition type in order
to allow using the various plugins installed that deal
with the handlers.
*/
export type APIHandlerDefinition = WhookAPIHandlerDefinition<
WhookAPIOperationCORSConfig & WhookAPIOperationSwaggerConfig
>;

/* Architecture Note #2.2: Exporting
Each configuration file then create a configuration object
and export it for the configuration service to load it.
See the [Whook Config Service](https://github.com/nfroidure/whook/blob/7dce55291a81628a0e95a07ce1e978a276b99578/packages/whook/src/services/CONFIGS.ts#L56).
*/
const CONFIG: AppConfigs = {
const CONFIG: Omit<WhookConfigs, 'HOST'> = {
BASE_ENV: {},
API_VERSION: packageConf.version,
BASE_PATH: `/v${packageConf.version.split('.')[0]}`,
HOST: 'localhost',
CONFIG: {
name: packageConf.name,
description: packageConf.description || '',
Expand Down
5 changes: 3 additions & 2 deletions packages/whook-example/src/config/development/config.ts
Original file line number Diff line number Diff line change
@@ -1,14 +1,15 @@
import COMMON_CONFIG from '../common/config';
import type { AppConfigs } from '../common/config';
import type { WhookConfigs } from '@whook/whook';

/* Architecture Note #2.3: Overriding
Finally the configuration file for a given environnment
may reuse or override the custom configuration file
like here for the development configuration.
*/
const CONFIG: AppConfigs = {
const CONFIG: WhookConfigs = {
...COMMON_CONFIG,
HOST: 'localhost',
DEV_ACCESS_TOKEN: 'admin|1|1',
DEFAULT_MECHANISM: 'Fake',
// This allows you to map service names depending on
Expand Down
5 changes: 3 additions & 2 deletions packages/whook-example/src/config/production/config.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
import COMMON_CONFIG from '../common/config';
import type { AppConfigs } from '../common/config';
import type { WhookConfigs } from '@whook/whook';

const CONFIG: AppConfigs = {
const CONFIG: WhookConfigs = {
...COMMON_CONFIG,
HOST: 'api.example.com',
};

export default CONFIG;
5 changes: 3 additions & 2 deletions packages/whook-example/src/config/staging/config.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
import COMMON_CONFIG from '../common/config';
import type { AppConfigs } from '../common/config';
import type { WhookConfigs } from '@whook/whook';

const CONFIG: AppConfigs = {
const CONFIG: WhookConfigs = {
...COMMON_CONFIG,
HOST: 'staging.example.com',
};

export default CONFIG;
Loading

0 comments on commit 150a2c3

Please sign in to comment.