Skip to content

Commit

Permalink
feat: Export all classes from one file
Browse files Browse the repository at this point in the history
close unlight#5
  • Loading branch information
unlight committed Jan 7, 2021
1 parent 1426c62 commit 92ca651
Show file tree
Hide file tree
Showing 8 changed files with 102 additions and 9 deletions.
2 changes: 2 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,8 @@ npx prisma generate
(default: `true`)
- `atomicNumberOperations` - Atomic number operations,
`false` - disabled (default), `true` - enabled
- `reExportAll` - create `index.ts` files for each directory with re-export,
`false` - disabled (default), `true` - enabled
- `types_*` - [flatten](https://github.com/hughsk/flat) map of types

- `types_{type}_fieldType` - TypeScript type name
Expand Down
51 changes: 48 additions & 3 deletions src/generate.spec.ts
Original file line number Diff line number Diff line change
@@ -1,22 +1,25 @@
import assert from 'assert';
import expect from 'expect';
import { PropertyDeclaration, SourceFile } from 'ts-morph';
import { Project, PropertyDeclaration, SourceFile } from 'ts-morph';

import { generate } from './generate';
import { reexport } from './generator-pipelines';
import { generatorOptions, getImportDeclarations, stringContains } from './testing';

describe('main generate', () => {
let property: PropertyDeclaration | undefined;
let sourceFile: SourceFile | undefined;
let sourceFiles: SourceFile[];
let sourceText: string;
let project: Project;
let resultGeneratorOptions: any;
async function getResult(args: { schema: string; options?: string[] }) {
const { schema, options } = args;
const generateOptions = {
resultGeneratorOptions = {
...(await generatorOptions(schema, options)),
fileExistsSync: () => false,
};
const project = await generate(generateOptions);
project = await generate(resultGeneratorOptions);
sourceFiles = project.getSourceFiles();
}

Expand Down Expand Up @@ -520,4 +523,46 @@ describe('main generate', () => {
const names = classFile.getProperties().map(p => p.getName());
expect(names).toStrictEqual([...new Set(names)]);
});

it('export all from index', async () => {
const checkpoints: any[] = [];
await getResult({
schema: `
model User {
id Int @id
posts Post[]
}
model Post {
id Int @id
author User? @relation(fields: [authorId], references: [id])
authorId Int?
}`,
});
await reexport(project);

sourceFile = project.getSourceFile('/user/index.ts')!;
expect(sourceFile.getText()).toContain(
`export { AggregateUser } from './aggregate-user.output'`,
);
expect(sourceFile.getText()).toContain(`export { User } from './user.model'`);
expect(sourceFile.getText()).toContain(
`export { UserCreateInput } from './user-create.input'`,
);

sourceFile = project.getSourceFile('/post/index.ts')!;
expect(sourceFile.getText()).toContain(
`export { AggregatePost } from './aggregate-post.output'`,
);
expect(sourceFile.getText()).toContain(`export { Post } from './post.model'`);
expect(sourceFile.getText()).toContain(
`export { PostCreateInput } from './post-create.input'`,
);

sourceFile = project.getSourceFile('/index.ts')!;
expect(sourceFile.getText()).toContain(
`export { BatchPayload, IntFilter, SortOrder } from './prisma'`,
);
expect(sourceFile.getText()).toContain(`from './user'`);
expect(sourceFile.getText()).toContain(`from './post'`);
});
});
5 changes: 3 additions & 2 deletions src/generate.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ import { generateInput } from './generate-input';
import { generateModel } from './generate-model';
import { Model } from './generate-property';
import { mutateFilters } from './mutate-filters';
import { PrismaDMMF } from './types';
import { GeneratorConfiguration, PrismaDMMF } from './types';
import {
createConfig,
featureName,
Expand All @@ -25,11 +25,12 @@ import {
type GenerateArgs = GeneratorOptions & {
prismaClientDmmf?: PrismaDMMF.Document;
fileExistsSync?: typeof existsSync;
config?: GeneratorConfiguration;
};

export async function generate(args: GenerateArgs) {
const { generator, otherGenerators } = args;
const config = createConfig(generator.config);
const config = args.config ?? createConfig(generator.config);
assert(generator.output, 'generator.output is empty');
const fileExistsSync = args.fileExistsSync ?? existsSync;
const prismaClientOutput = otherGenerators.find(
Expand Down
1 change: 1 addition & 0 deletions src/generator-pipelines/index.ts
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
export { reexport } from './reexport';
export { remove } from './remove';
export { update } from './update';
32 changes: 32 additions & 0 deletions src/generator-pipelines/reexport.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
import { Project, SourceFile } from 'ts-morph';

// eslint-disable-next-line @typescript-eslint/require-await
export async function reexport(project: Project) {
const nextFiles = new Set<SourceFile>();
for (const sourceFile of project.getSourceFiles()) {
const directoryPath = sourceFile.getDirectory().getPath();
const testIndexFile = `${directoryPath}/index.ts`;
const sourceIndexFile =
project.getSourceFile(testIndexFile) ||
project.createSourceFile(testIndexFile);
sourceIndexFile.addExportDeclaration({
namedExports: sourceFile
.getExportSymbols()
.map(s => ({ name: s.getName() })),
moduleSpecifier: `./${sourceFile.getBaseNameWithoutExtension()}`,
});

nextFiles.add(sourceIndexFile);
}

const sourceIndexFile = project.createSourceFile('/index.ts');
for (const sourceFile of nextFiles) {
const moduleSpecifier = `.${sourceFile.getDirectory().getPath()}`;
sourceIndexFile.addExportDeclaration({
namedExports: sourceFile
.getExportSymbols()
.map(s => ({ name: s.getName() })),
moduleSpecifier,
});
}
}
16 changes: 12 additions & 4 deletions src/index.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,19 @@
import { generatorHandler } from '@prisma/generator-helper';
import { generatorHandler, GeneratorOptions } from '@prisma/generator-helper';

import { generate } from './generate';
import { remove, update } from './generator-pipelines';
import { reexport, remove, update } from './generator-pipelines';
import { createConfig } from './utils';

generatorHandler({
async onGenerate(options) {
const project = await generate(options);
async onGenerate(options: GeneratorOptions) {
const config = createConfig(options.generator.config);
const project = await generate({
...options,
config,
});
if (config.reExportAll) {
await reexport(project);
}
await remove(project, options);
await update(project, options);
},
Expand Down
1 change: 1 addition & 0 deletions src/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,4 +12,5 @@ export type GeneratorConfiguration = {
combineScalarFilters: boolean;
atomicNumberOperations: boolean;
types: Record<string, TypeRecord>;
reExportAll: boolean;
};
3 changes: 3 additions & 0 deletions src/utils/create-config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,5 +28,8 @@ export function createConfig(
graphqlModule: 'graphql-type-json',
} as TypeRecord,
}),
reExportAll: ['true', '1', 'on'].includes(
(config.reExportAll as Nullable<string>) ?? 'false',
),
};
}

0 comments on commit 92ca651

Please sign in to comment.