@aligent/nx-openapi 0.1.3 → 2.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +1 -1
- package/src/generators/client/client-specific-files/client.ts.template +53 -0
- package/src/generators/client/files/README.md.template +29 -1
- package/src/generators/client/files/eslint.config.mjs.template +3 -0
- package/src/generators/client/files/package.json.template +19 -0
- package/src/generators/client/files/src/index.ts.template +1 -22
- package/src/generators/client/files/tsconfig.json.template +2 -15
- package/src/generators/client/generator.js +39 -20
- package/src/generators/client/schema.json +2 -1
- package/src/helpers/generate-openapi-types.js +0 -1
- package/src/helpers/utilities.d.ts +45 -16
- package/src/helpers/utilities.js +75 -34
- package/src/generators/client/files/tsconfig.lib.json.template +0 -9
package/package.json
CHANGED
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Example client demonstrating how to use the generated API types.
|
|
3
|
+
* Adjust middlewares usage according to your need.
|
|
4
|
+
*
|
|
5
|
+
* - Check out Aligent's middlewares: https://github.com/aligent/microservice-development-utilities
|
|
6
|
+
* - For more information about openapi-fetch middlewares: https://openapi-ts.dev/openapi-fetch/middleware-auth#middleware
|
|
7
|
+
*/
|
|
8
|
+
import {
|
|
9
|
+
apiKeyAuthMiddleware,
|
|
10
|
+
fetchSsmParams,
|
|
11
|
+
retryMiddleware,
|
|
12
|
+
} from '@aligent/microservice-util-lib';
|
|
13
|
+
import createClient, { Client, ClientOptions } from 'openapi-fetch';
|
|
14
|
+
import { paths } from './generated-types';
|
|
15
|
+
|
|
16
|
+
export class <%= className %> {
|
|
17
|
+
private credential: string | null = null;
|
|
18
|
+
public readonly client: Client<paths, `${string}/${string}`>;
|
|
19
|
+
|
|
20
|
+
constructor(options: ClientOptions, credentialPath: string) {
|
|
21
|
+
this.client = createClient<paths>(options);
|
|
22
|
+
|
|
23
|
+
/**
|
|
24
|
+
* The order in which middleware are registered matters.
|
|
25
|
+
* - For requests, onRequest() will be called in the order registered
|
|
26
|
+
* - For responses, onResponse() will be called in reverse order.
|
|
27
|
+
*/
|
|
28
|
+
this.client.use(
|
|
29
|
+
apiKeyAuthMiddleware({
|
|
30
|
+
header: 'Authorization',
|
|
31
|
+
value: async () => {
|
|
32
|
+
if (!this.credential) {
|
|
33
|
+
const param = await fetchSsmParams(credentialPath);
|
|
34
|
+
if (!param?.Value) {
|
|
35
|
+
throw new Error('Unable to fetch API client credential');
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
this.credential = param.Value;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
return `Bearer ${this.credential}`;
|
|
42
|
+
},
|
|
43
|
+
})
|
|
44
|
+
);
|
|
45
|
+
|
|
46
|
+
this.client.use(
|
|
47
|
+
retryMiddleware({
|
|
48
|
+
onRetry: ({ attempt, error }) =>
|
|
49
|
+
console.log(`Retrying...${attempt} due to ${String(error)}`),
|
|
50
|
+
})
|
|
51
|
+
);
|
|
52
|
+
}
|
|
53
|
+
}
|
|
@@ -1 +1,29 @@
|
|
|
1
|
-
|
|
1
|
+
# Generated OpenAPI REST API Clients
|
|
2
|
+
|
|
3
|
+
This folder contains TypeScript API clients generated from OpenAPI specifications using Nx generators and `openapi-typescript`. Each client exposes strongly typed request and response types under `generated-types` and a ready-to-use `openapi-fetch` client class.
|
|
4
|
+
|
|
5
|
+
## Usage
|
|
6
|
+
- Import the generated client into your code.
|
|
7
|
+
- Instantiate the client with appropriate ClientOptions (base URL, fetch implementation, etc.) and call the typed endpoints.
|
|
8
|
+
|
|
9
|
+
## Example
|
|
10
|
+
```typescript
|
|
11
|
+
import { MyApiClient } from 'clients'; // Adjust the import name as necessary
|
|
12
|
+
|
|
13
|
+
const client = new MyApiClient(
|
|
14
|
+
{ baseUrl: 'https://my-api-client.base-url', signal: AbortSignal.timeout(30000) },
|
|
15
|
+
'/my/api/client/access-token/path'
|
|
16
|
+
).client;
|
|
17
|
+
|
|
18
|
+
// Example of calling a typed endpoint
|
|
19
|
+
async function fetchData() {
|
|
20
|
+
try {
|
|
21
|
+
const response = await client.GET('/path/to/endpoint'); // Replace with actual endpoint method
|
|
22
|
+
console.log(response);
|
|
23
|
+
} catch (error) {
|
|
24
|
+
console.error('Error fetching data:', error);
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
fetchData();
|
|
29
|
+
```
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "clients",
|
|
3
|
+
"type": "module",
|
|
4
|
+
"main": "./src/index.ts",
|
|
5
|
+
"types": "./src/index.ts",
|
|
6
|
+
"exports": {
|
|
7
|
+
".": {
|
|
8
|
+
"types": "./src/index.ts",
|
|
9
|
+
"import": "./src/index.ts",
|
|
10
|
+
"default": "./src/index.ts"
|
|
11
|
+
},
|
|
12
|
+
"./package.json": "./package.json"
|
|
13
|
+
},
|
|
14
|
+
"nx": {
|
|
15
|
+
"tags": [
|
|
16
|
+
"scope:libs"
|
|
17
|
+
]
|
|
18
|
+
}
|
|
19
|
+
}
|
|
@@ -1,22 +1 @@
|
|
|
1
|
-
//
|
|
2
|
-
import { paths } from '../generated';
|
|
3
|
-
import createClient from 'openapi-fetch';
|
|
4
|
-
|
|
5
|
-
// This type is an example of what is initialised using the types generated in the paths interface which is created when generation occurs.
|
|
6
|
-
// Its worth looking into that paths interface, to see the the types that were generated for your client.
|
|
7
|
-
type ExampleResponse =
|
|
8
|
-
paths['/customers']['get']['responses']['200']['content']['application/json'];
|
|
9
|
-
|
|
10
|
-
// Using openapi-fetch we can create a fully typed REST client by passing in paths as a generic.
|
|
11
|
-
// If you wish however, you can use any api client you want (axios, basic fetch etc.) and use the paths separately to maintain type safety in your client.
|
|
12
|
-
const client = createClient<paths>({
|
|
13
|
-
baseUrl: '',
|
|
14
|
-
signal: AbortSignal.timeout(10000),
|
|
15
|
-
});
|
|
16
|
-
|
|
17
|
-
// Client getters are then fully typed. Try deleting '/customers' and seeing what routes you can use!
|
|
18
|
-
const response = client.GET('/customers', {
|
|
19
|
-
params: {
|
|
20
|
-
query: {},
|
|
21
|
-
},
|
|
22
|
-
});
|
|
1
|
+
// When a client is generated, its added as an export to this index file. This makes sure that your entire application has access to all of your clients.
|
|
@@ -1,19 +1,6 @@
|
|
|
1
1
|
{
|
|
2
|
-
"extends": "
|
|
3
|
-
"compilerOptions": {
|
|
4
|
-
"forceConsistentCasingInFileNames": true,
|
|
5
|
-
"strict": true,
|
|
6
|
-
"importHelpers": true,
|
|
7
|
-
"noImplicitOverride": true,
|
|
8
|
-
"noImplicitReturns": true,
|
|
9
|
-
"noFallthroughCasesInSwitch": true,
|
|
10
|
-
"noPropertyAccessFromIndexSignature": true
|
|
11
|
-
},
|
|
2
|
+
"extends": "@aligent/ts-code-standards/tsconfigs-extend",
|
|
12
3
|
"files": [],
|
|
13
4
|
"include": [],
|
|
14
|
-
"references": [
|
|
15
|
-
{
|
|
16
|
-
"path": "./tsconfig.lib.json"
|
|
17
|
-
}
|
|
18
|
-
]
|
|
5
|
+
"references": []
|
|
19
6
|
}
|
|
@@ -5,35 +5,54 @@ const devkit_1 = require("@nx/devkit");
|
|
|
5
5
|
const generate_openapi_types_1 = require("../../helpers/generate-openapi-types");
|
|
6
6
|
const utilities_1 = require("../../helpers/utilities");
|
|
7
7
|
const VALID_EXTENSIONS = ['yaml', 'yml', 'json'];
|
|
8
|
+
// We also use this as the project root for all generated clients
|
|
9
|
+
const PROJECT_NAME = 'clients';
|
|
8
10
|
async function clientGenerator(tree, options) {
|
|
9
|
-
const { name, schemaPath, importPath = `@clients
|
|
11
|
+
const { name, schemaPath, importPath = `@clients`, skipValidate, override } = options;
|
|
10
12
|
const ext = schemaPath.split('.').pop() || '';
|
|
11
13
|
if (!VALID_EXTENSIONS.includes(ext)) {
|
|
12
14
|
throw new Error(`Invalid schema file extension: ${ext}`);
|
|
13
15
|
}
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
throw new Error('Schema validation failed!');
|
|
18
|
-
}
|
|
16
|
+
const hasError = await (0, generate_openapi_types_1.validateSchema)(schemaPath);
|
|
17
|
+
if (!skipValidate && hasError) {
|
|
18
|
+
throw new Error('Schema validation failed!');
|
|
19
19
|
}
|
|
20
|
-
const projectRoot =
|
|
21
|
-
const
|
|
22
|
-
const
|
|
23
|
-
const
|
|
24
|
-
if (!
|
|
25
|
-
|
|
26
|
-
return;
|
|
20
|
+
const projectRoot = PROJECT_NAME;
|
|
21
|
+
const apiClientDest = `${projectRoot}/src/${name}`;
|
|
22
|
+
const schemaDest = `${apiClientDest}/schema.${ext}`;
|
|
23
|
+
const typesDest = `${apiClientDest}/generated-types.ts`;
|
|
24
|
+
if (!override && tree.exists(apiClientDest)) {
|
|
25
|
+
throw new Error(`Directory "${name}" already exists. If you want to override the current api client in this directory use "--override"`);
|
|
27
26
|
}
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
devkit_1.logger.info(`Creating new project at ${projectRoot}`);
|
|
32
|
-
// Generate other files
|
|
27
|
+
const existingProject = (0, utilities_1.getExistingProject)(tree, PROJECT_NAME);
|
|
28
|
+
if (!existingProject) {
|
|
29
|
+
devkit_1.logger.warn(`Creating new project ${PROJECT_NAME} at ${projectRoot}`);
|
|
33
30
|
(0, devkit_1.generateFiles)(tree, (0, devkit_1.joinPathFragments)(__dirname, './files'), projectRoot, options);
|
|
34
|
-
|
|
35
|
-
|
|
31
|
+
const tsConfigFile = (0, utilities_1.getRootTsConfigPathInTree)(tree);
|
|
32
|
+
if (tsConfigFile === 'tsconfig.json') {
|
|
33
|
+
(0, utilities_1.addTsConfigReference)(tree, tsConfigFile, `./${projectRoot}`);
|
|
34
|
+
}
|
|
35
|
+
else {
|
|
36
|
+
const lookupPath = (0, devkit_1.joinPathFragments)(projectRoot, './src', 'index.ts');
|
|
37
|
+
(0, utilities_1.addTsConfigPath)(tree, tsConfigFile, importPath, [lookupPath]);
|
|
38
|
+
}
|
|
36
39
|
}
|
|
40
|
+
await (0, generate_openapi_types_1.copySchema)(tree, schemaDest, schemaPath);
|
|
41
|
+
await (0, generate_openapi_types_1.generateOpenApiTypes)(tree, schemaDest, typesDest);
|
|
42
|
+
/**
|
|
43
|
+
* Each time we add new API client, we actually add a new class into `clients` project (if it exists).
|
|
44
|
+
* This add a new example client class to `apiClientDest` folder
|
|
45
|
+
*/
|
|
46
|
+
(0, devkit_1.generateFiles)(tree, (0, devkit_1.joinPathFragments)(__dirname, './client-specific-files'), apiClientDest, {
|
|
47
|
+
className: (0, utilities_1.toClassName)(name),
|
|
48
|
+
});
|
|
49
|
+
/**
|
|
50
|
+
* The `clients` project expose all the API clients via `src/index.ts` file.
|
|
51
|
+
* As a result, we need to append new client to the list of exporting;
|
|
52
|
+
*/
|
|
53
|
+
(0, utilities_1.appendToIndexFile)(tree, projectRoot, name);
|
|
37
54
|
await (0, devkit_1.formatFiles)(tree);
|
|
55
|
+
devkit_1.logger.info(`Successfully generated ${name} API client`);
|
|
56
|
+
devkit_1.logger.info(`Next step: Run "nx affected -t lint" to fix any linting issues that may arise from the generated code.`);
|
|
38
57
|
}
|
|
39
58
|
exports.default = clientGenerator;
|
|
@@ -6,6 +6,7 @@
|
|
|
6
6
|
"properties": {
|
|
7
7
|
"name": {
|
|
8
8
|
"type": "string",
|
|
9
|
+
"pattern": "^[a-z0-9-]+$",
|
|
9
10
|
"description": "Name of the api client.",
|
|
10
11
|
"$default": {
|
|
11
12
|
"$source": "argv",
|
|
@@ -37,7 +38,7 @@
|
|
|
37
38
|
},
|
|
38
39
|
"override": {
|
|
39
40
|
"type": "boolean",
|
|
40
|
-
"description": "Override existing
|
|
41
|
+
"description": "Override existing files during generation",
|
|
41
42
|
"default": false
|
|
42
43
|
}
|
|
43
44
|
},
|
|
@@ -103,7 +103,6 @@ async function copySchema(tree, destination, schemaPath) {
|
|
|
103
103
|
async function validateSchema(path) {
|
|
104
104
|
let hasError = false;
|
|
105
105
|
try {
|
|
106
|
-
// TODO: MI-203 - Support private schema endpoint
|
|
107
106
|
const config = await (0, openapi_core_1.loadConfig)();
|
|
108
107
|
const results = await (0, openapi_core_1.lint)({ ref: path, config });
|
|
109
108
|
results.forEach(result => {
|
|
@@ -1,26 +1,55 @@
|
|
|
1
1
|
import { Tree } from '@nx/devkit';
|
|
2
2
|
/**
|
|
3
|
-
*
|
|
3
|
+
* Get existing project by name.
|
|
4
|
+
* If the project exists, it returns project configuration or undefined otherwise.
|
|
4
5
|
*
|
|
5
|
-
*
|
|
6
|
-
*
|
|
6
|
+
* @param tree - The file system tree representing the current project.
|
|
7
|
+
* @param projectName - The name of the project to add.
|
|
8
|
+
* @returns - The project configuration.
|
|
9
|
+
*/
|
|
10
|
+
export declare function getExistingProject(tree: Tree, projectName: string): import("@nx/devkit").ProjectConfiguration | undefined;
|
|
11
|
+
/**
|
|
12
|
+
* The utility functions below are only exported by '@nx/js', not '@nx/devkit'
|
|
13
|
+
* They're simple so we recreate them here instead of adding '@nx/js' as a dependency
|
|
14
|
+
* Source: {@link https://github.com/nrwl/nx/blob/master/packages/js/src/utils/typescript/ts-config.ts}
|
|
15
|
+
*/
|
|
16
|
+
export declare function getRootTsConfigPathInTree(tree: Tree): string;
|
|
17
|
+
/**
|
|
18
|
+
* Adds a new path mapping to the `compilerOptions.paths` property in the root TypeScript configuration file.
|
|
19
|
+
* If the import path already exists, an error is thrown.
|
|
7
20
|
*
|
|
8
|
-
* @param
|
|
9
|
-
* @param
|
|
10
|
-
* @param
|
|
11
|
-
* @
|
|
12
|
-
* @throws
|
|
21
|
+
* @param tree - The file system tree representing the current project.
|
|
22
|
+
* @param tsConfigFile - The root TypeScript configuration file path.
|
|
23
|
+
* @param importPath - The import path to add to the `paths` property.
|
|
24
|
+
* @param lookupPaths - The array of paths to associate with the import path.
|
|
25
|
+
* @throws - If the import path already exists in the `paths` property.
|
|
13
26
|
*/
|
|
14
|
-
export declare function
|
|
27
|
+
export declare function addTsConfigPath(tree: Tree, tsConfigFile: string, importPath: string, lookupPaths: string[]): void;
|
|
15
28
|
/**
|
|
16
|
-
* Adds a new path
|
|
29
|
+
* Adds a new referencing path to the `references` property in the root TypeScript configuration file.
|
|
30
|
+
* If the referencing path already exists, an error is thrown.
|
|
17
31
|
*
|
|
18
|
-
*
|
|
19
|
-
*
|
|
32
|
+
* @param tree - The file system tree representing the current project.
|
|
33
|
+
* @param tsConfigFile - The root TypeScript configuration file path.
|
|
34
|
+
* @param referencePath - The referencing path.
|
|
35
|
+
* @throws - If the import path already exists in the `paths` property.
|
|
36
|
+
*/
|
|
37
|
+
export declare function addTsConfigReference(tree: Tree, tsConfigFile: string, referencePath: string): void;
|
|
38
|
+
/**
|
|
39
|
+
* Appends a new export statement to the index file.
|
|
40
|
+
*
|
|
41
|
+
* This function reads the content of the index file and appends a new export statement
|
|
42
|
+
* for the specified client.
|
|
20
43
|
*
|
|
21
44
|
* @param {Tree} tree - The file system tree representing the current project.
|
|
22
|
-
* @param {string}
|
|
23
|
-
|
|
24
|
-
|
|
45
|
+
* @param {string} clientName - The name of the client to export.
|
|
46
|
+
*/
|
|
47
|
+
export declare function appendToIndexFile(tree: Tree, projectRoot: string, clientName: string): void;
|
|
48
|
+
/**
|
|
49
|
+
* Convert a lower-case alphanumeric string (may include hyphens) into a PascalCase string.
|
|
50
|
+
*
|
|
51
|
+
* @param input - The input string to convert.
|
|
52
|
+
* @example:
|
|
53
|
+
* - "my-client" -> "MyClient"
|
|
25
54
|
*/
|
|
26
|
-
export declare function
|
|
55
|
+
export declare function toClassName(input: string): string;
|
package/src/helpers/utilities.js
CHANGED
|
@@ -1,36 +1,27 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.
|
|
3
|
+
exports.getExistingProject = getExistingProject;
|
|
4
|
+
exports.getRootTsConfigPathInTree = getRootTsConfigPathInTree;
|
|
4
5
|
exports.addTsConfigPath = addTsConfigPath;
|
|
6
|
+
exports.addTsConfigReference = addTsConfigReference;
|
|
7
|
+
exports.appendToIndexFile = appendToIndexFile;
|
|
8
|
+
exports.toClassName = toClassName;
|
|
5
9
|
const devkit_1 = require("@nx/devkit");
|
|
6
10
|
/**
|
|
7
|
-
*
|
|
11
|
+
* Get existing project by name.
|
|
12
|
+
* If the project exists, it returns project configuration or undefined otherwise.
|
|
8
13
|
*
|
|
9
|
-
*
|
|
10
|
-
*
|
|
11
|
-
*
|
|
12
|
-
* @param {Tree} tree - The file system tree representing the current project.
|
|
13
|
-
* @param {string} name - The name of the project to add.
|
|
14
|
-
* @param {string} projectRoot - The root directory of the project.
|
|
15
|
-
* @returns {boolean} `true` if the project configuration was added successfully, `false` if the project already exists.
|
|
16
|
-
* @throws {Error} If an error occurs that is not related to the project already existing.
|
|
14
|
+
* @param tree - The file system tree representing the current project.
|
|
15
|
+
* @param projectName - The name of the project to add.
|
|
16
|
+
* @returns - The project configuration.
|
|
17
17
|
*/
|
|
18
|
-
function
|
|
18
|
+
function getExistingProject(tree, projectName) {
|
|
19
19
|
try {
|
|
20
|
-
(0, devkit_1.
|
|
21
|
-
root: projectRoot,
|
|
22
|
-
projectType: 'library',
|
|
23
|
-
sourceRoot: `${projectRoot}/src`,
|
|
24
|
-
targets: {},
|
|
25
|
-
tags: ['client', name],
|
|
26
|
-
});
|
|
27
|
-
return true;
|
|
20
|
+
return (0, devkit_1.readProjectConfiguration)(tree, projectName);
|
|
28
21
|
}
|
|
29
|
-
catch (
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
}
|
|
33
|
-
throw err;
|
|
22
|
+
catch (error) {
|
|
23
|
+
devkit_1.logger.debug(`Project ${projectName} doesn't exist`, String(error));
|
|
24
|
+
return undefined;
|
|
34
25
|
}
|
|
35
26
|
}
|
|
36
27
|
/**
|
|
@@ -47,18 +38,17 @@ function getRootTsConfigPathInTree(tree) {
|
|
|
47
38
|
return 'tsconfig.base.json';
|
|
48
39
|
}
|
|
49
40
|
/**
|
|
50
|
-
* Adds a new path mapping to the `paths` property in the root TypeScript configuration file.
|
|
51
|
-
*
|
|
52
|
-
* This function updates the `tsconfig.base.json` or `tsconfig.json` file to include a new path mapping
|
|
53
|
-
* for the specified import path. If the import path already exists, an error is thrown.
|
|
41
|
+
* Adds a new path mapping to the `compilerOptions.paths` property in the root TypeScript configuration file.
|
|
42
|
+
* If the import path already exists, an error is thrown.
|
|
54
43
|
*
|
|
55
|
-
* @param
|
|
56
|
-
* @param
|
|
57
|
-
* @param
|
|
58
|
-
* @
|
|
44
|
+
* @param tree - The file system tree representing the current project.
|
|
45
|
+
* @param tsConfigFile - The root TypeScript configuration file path.
|
|
46
|
+
* @param importPath - The import path to add to the `paths` property.
|
|
47
|
+
* @param lookupPaths - The array of paths to associate with the import path.
|
|
48
|
+
* @throws - If the import path already exists in the `paths` property.
|
|
59
49
|
*/
|
|
60
|
-
function addTsConfigPath(tree, importPath, lookupPaths) {
|
|
61
|
-
(0, devkit_1.updateJson)(tree,
|
|
50
|
+
function addTsConfigPath(tree, tsConfigFile, importPath, lookupPaths) {
|
|
51
|
+
(0, devkit_1.updateJson)(tree, tsConfigFile, json => {
|
|
62
52
|
json.compilerOptions ??= {};
|
|
63
53
|
const c = json.compilerOptions;
|
|
64
54
|
c.paths ??= {};
|
|
@@ -69,3 +59,54 @@ function addTsConfigPath(tree, importPath, lookupPaths) {
|
|
|
69
59
|
return json;
|
|
70
60
|
});
|
|
71
61
|
}
|
|
62
|
+
/**
|
|
63
|
+
* Adds a new referencing path to the `references` property in the root TypeScript configuration file.
|
|
64
|
+
* If the referencing path already exists, an error is thrown.
|
|
65
|
+
*
|
|
66
|
+
* @param tree - The file system tree representing the current project.
|
|
67
|
+
* @param tsConfigFile - The root TypeScript configuration file path.
|
|
68
|
+
* @param referencePath - The referencing path.
|
|
69
|
+
* @throws - If the import path already exists in the `paths` property.
|
|
70
|
+
*/
|
|
71
|
+
function addTsConfigReference(tree, tsConfigFile, referencePath) {
|
|
72
|
+
(0, devkit_1.updateJson)(tree, tsConfigFile, json => {
|
|
73
|
+
json.references ??= [];
|
|
74
|
+
if (json.references.some((r) => r.path === referencePath)) {
|
|
75
|
+
throw new Error(`You already have a library using the import path "${referencePath}". Make sure to specify a unique one.`);
|
|
76
|
+
}
|
|
77
|
+
json.references.push({
|
|
78
|
+
path: referencePath,
|
|
79
|
+
});
|
|
80
|
+
return json;
|
|
81
|
+
});
|
|
82
|
+
}
|
|
83
|
+
/**
|
|
84
|
+
* Appends a new export statement to the index file.
|
|
85
|
+
*
|
|
86
|
+
* This function reads the content of the index file and appends a new export statement
|
|
87
|
+
* for the specified client.
|
|
88
|
+
*
|
|
89
|
+
* @param {Tree} tree - The file system tree representing the current project.
|
|
90
|
+
* @param {string} clientName - The name of the client to export.
|
|
91
|
+
*/
|
|
92
|
+
function appendToIndexFile(tree, projectRoot, clientName) {
|
|
93
|
+
const indexPath = `${projectRoot}/src/index.ts`;
|
|
94
|
+
const newLine = `export * from "./${clientName}/client";\n`;
|
|
95
|
+
const indexContent = tree.read(indexPath, 'utf-8');
|
|
96
|
+
tree.write(indexPath, indexContent + newLine);
|
|
97
|
+
}
|
|
98
|
+
/**
|
|
99
|
+
* Convert a lower-case alphanumeric string (may include hyphens) into a PascalCase string.
|
|
100
|
+
*
|
|
101
|
+
* @param input - The input string to convert.
|
|
102
|
+
* @example:
|
|
103
|
+
* - "my-client" -> "MyClient"
|
|
104
|
+
*/
|
|
105
|
+
function toClassName(input) {
|
|
106
|
+
return input
|
|
107
|
+
.trim()
|
|
108
|
+
.toLowerCase()
|
|
109
|
+
.split('-')
|
|
110
|
+
.map(c => c.charAt(0).toUpperCase() + c.slice(1))
|
|
111
|
+
.join('');
|
|
112
|
+
}
|