A TypeScript utility that creates mappings between GraphQL types and TypeScript implementations for GraphQL Code Generator.
npm i -D https://github.com/ifeanyi-ugwu/codegen-mappers-loader.gitIn your codegen configuration file:
import type { CodegenConfig } from "@graphql-codegen/cli";
import { loadMappers } from "codegen-mappers-loader";
const mappers = loadMappers("src/types");
const config: CodegenConfig = {
// ... other config options
generates: {
"src/types/resolvers-types.generated.ts": {
config: {
mappers,
// ... other config options
},
plugins: ["typescript", "typescript-resolvers"],
},
},
};
export default config;Create files with the .mappers.ts extension and export your mappers:
// user.mappers.ts
export { IUserDocument as UserMapper } from "./models";This exports IUserDocument under the name UserMapper. The loadMappers function will create a mapping between the User GraphQL type and the UserMapper implementation.
The loadMappers function scans a specified directory (current working directory by default) for .mappers.ts files. It looks for:
- Interfaces, type aliases, or class declarations with names ending in
Mapper. - Named exports with names ending in
Mapper.
For each found mapper, it creates an entry in the mappers object. The key is the name without the Mapper suffix, and the value is the relative path to the file and the exported name. This generated mapper object can be directly used in your GraphQL Code Generator configuration.
The loadMappers function accepts two parameters:
This is the directory where the GraphQL Code Generator outputs the generated files, such as the resolver type definitions. The paths in the mappers object will be relative to this directory.
For example:
- If
outputDiris"src/types", the generated mappers will look like"./user.mappers#UserMapper", assuminguser.mappers.tsis in the same directory as the output file. - If the
.mappers.tsfile is located in"src/models", the path in themappersobject will correctly adjust to"../models/user.mappers#UserMapper".
An object with the following properties:
| Option | Type | Default | Description |
|---|---|---|---|
currentDir |
string | process.cwd() |
Directory to start scanning for .mappers.ts files. |
ignoreList |
string[] | [".git", ".vscode", "node_modules"] |
Directories to ignore during the scan. |
removeExtension |
boolean | true |
Whether to remove the .ts extension from file paths in the mappers object. |
mapperFilesPattern |
RegExp | /\.mappers\.ts$/ |
Pattern to match mapper files. |
mapperSuffixPattern |
RegExp | /Mapper$/ |
Pattern to identify valid mapper names in interfaces, type aliases, or named exports. |
import { loadMappers } from "codegen-mappers-loader";
const outputDir = "src/types"; // Directory where Codegen outputs files
const options = {
currentDir: "src/models", // Start scanning in src/models
ignoreList: [".git", ".vscode", "node_modules", "tests"], // Ignore these directories
removeExtension: false, // Keep the .ts extension in generated paths
};
const mappers = loadMappers(outputDir, options);Suppose you have the following directory structure:
src/
├── types/
│ ├── resolvers-types.generated.ts
│ └── user.mappers.ts
├── models/
│ ├── order.mappers.ts
│ └── product.mappers.ts
- If
outputDiris"src/types", the generated mappers will look like:User: "./user.mappers#UserMapper"Order: "../models/order.mappers#OrderMapper"Product: "../models/product.mappers#ProductMapper"
If removeExtension is set to false, the paths will retain the .ts extension:
User: "./user.mappers.ts#UserMapper"
-
For interfaces, type aliases, or classes:
// order.mappers.ts export interface OrderMapper { ... }
The mapper key will be
Order, and the value will include the relative path and the export name:{ "Order": "./order.mappers#OrderMapper" } -
For named exports:
// product.mappers.ts export { IProductDocument as ProductMapper } from "./models";
The mapper key will be
Product, and the value will reflect the export:{ "Product": "./product.mappers#ProductMapper" }
MIT License - see the LICENSE file for details.