Skip to content

Commit

Permalink
fix: type guard types in merge file [NONE] (#227)
Browse files Browse the repository at this point in the history
  • Loading branch information
marcolink authored Mar 3, 2023
1 parent 4bc6577 commit 51647b5
Show file tree
Hide file tree
Showing 4 changed files with 85 additions and 7 deletions.
11 changes: 10 additions & 1 deletion src/cf-definitions-builder.ts
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,7 @@ export default class CFDefinitionsBuilder {

const writePromises = this.project.getSourceFiles().map((file) => {
const targetPath = `${dir}${file.getFilePath()}`;
file.formatText();
return writeCallback(targetPath, file.getFullText());
});
await Promise.all(writePromises);
Expand Down Expand Up @@ -100,6 +101,9 @@ export default class CFDefinitionsBuilder {
types.push(childStructure.name);
mergeFile.addTypeAlias(childStructure);
break;
case StructureKind.Function:
mergeFile.addFunction(childStructure);
break;
default:
throw new Error(`Unhandled node type '${StructureKind[childStructure.kind]}'.`);
}
Expand All @@ -116,7 +120,10 @@ export default class CFDefinitionsBuilder {

// only import modules not present in merge file and not present in additional files
for (const importD of imports) {
const name = importD.moduleSpecifier.slice(2);
const name = importD.moduleSpecifier.startsWith('./')
? importD.moduleSpecifier.slice(2)
: importD.moduleSpecifier;
// This check relies on the fact that module and file name match
if (!types.includes(name) && !additionalFileNames.has(name)) {
mergeFile.addImportDeclaration(importD);
}
Expand All @@ -126,6 +133,8 @@ export default class CFDefinitionsBuilder {
ensureNewLineAtEndOfFile: true,
});

mergeFile.formatText();

const fullText = mergeFile.getFullText();
this.project.removeSourceFile(mergeFile);

Expand Down
16 changes: 12 additions & 4 deletions src/renderer/type/type-guard-renderer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,13 @@ export class TypeGuardRenderer extends BaseContentTypeRenderer {

public override setup(project: Project): void {
super.setup(project);
const file = project.createSourceFile(`TypeGuardTypes.ts`, undefined, {
overwrite: true,
});
const file = project.createSourceFile(
`${TypeGuardRenderer.WithContentTypeLink}.ts`,
undefined,
{
overwrite: true,
},
);

file.addTypeAlias({
name: TypeGuardRenderer.WithContentTypeLink,
Expand All @@ -31,7 +35,7 @@ export class TypeGuardRenderer extends BaseContentTypeRenderer {
const entryInterfaceName = moduleName(contentType.sys.id);

file.addImportDeclaration({
moduleSpecifier: 'TypeGuardTypes',
moduleSpecifier: `./${TypeGuardRenderer.WithContentTypeLink}`,
namedImports: [TypeGuardRenderer.WithContentTypeLink],
isTypeOnly: true,
});
Expand All @@ -55,4 +59,8 @@ export class TypeGuardRenderer extends BaseContentTypeRenderer {

file.formatText();
};

public override additionalFiles(): SourceFile[] {
return this.files;
}
}
63 changes: 62 additions & 1 deletion test/cf-definitions-builder.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,11 @@ import { writeFile } from 'fs-extra';
import { cleanupTempDirs, createTempDir } from 'jest-fixtures';
import * as path from 'path';

import CFDefinitionsBuilder from '../src';
import CFDefinitionsBuilder, {
DefaultContentTypeRenderer,
LocalizedContentTypeRenderer,
TypeGuardRenderer,
} from '../src';
import stripIndent = require('strip-indent');

describe('A Contentful definitions builder', () => {
Expand Down Expand Up @@ -523,4 +527,61 @@ describe('A Contentful definitions builder', () => {
expect(beforeResult).toEqual(afterResult);
expect(beforeWriteResult).toEqual(afterWriteResult);
});

it("'return single file contents with localized renderer", async () => {
builder = new CFDefinitionsBuilder([
new DefaultContentTypeRenderer(),
new LocalizedContentTypeRenderer(),
]);

builder.appendType(modelType);

expect('\n' + builder.toString()).toEqual(
stripIndent(`
import type { Entry } from "contentful";
export type LocalizedFields<Fields, Locales extends keyof any> = {
[FieldName in keyof Fields]?: {
[LocaleName in Locales]?: Fields[FieldName];
}
};
export type LocalizedEntry<EntryType, Locales extends keyof any> = {
[Key in keyof EntryType]:
Key extends 'fields'
? LocalizedFields<EntryType[Key], Locales>
: EntryType[Key]
};
export interface TypeSysIdFields {
}
export type TypeSysId = Entry<TypeSysIdFields>;
export type LocalizedTypeSysIdFields<Locales extends keyof any> = LocalizedFields<TypeSysIdFields, Locales>;
export type LocalizedTypeSysId<Locales extends keyof any> = LocalizedEntry<TypeSysId, Locales>;
`),
);
});

it('exports type guard functions', async () => {
builder = new CFDefinitionsBuilder([new DefaultContentTypeRenderer(), new TypeGuardRenderer()]);

builder.appendType(modelType);

expect('\n' + builder.toString()).toEqual(
stripIndent(`
import type { Entry } from "contentful";
export interface TypeSysIdFields {
}
export type TypeSysId = Entry<TypeSysIdFields>;
export function isTypeSysId(entry: WithContentTypeLink): entry is TypeSysId {
return entry.sys.contentType.sys.id === 'sysId'
}
export type WithContentTypeLink = { sys: { contentType: { sys: { id: string } } } };
`),
);
});
});
2 changes: 1 addition & 1 deletion test/renderer/type/type-guard-renderer.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ describe('A content type type guard renderer class', () => {
expect('\n' + testFile.getFullText()).toEqual(
stripIndent(`
import type { Entry, EntryFields } from "contentful";
import type { WithContentTypeLink } from "TypeGuardTypes";
import type { WithContentTypeLink } from "./WithContentTypeLink";
export interface TypeAnimalFields {
bread: EntryFields.Symbol;
Expand Down

0 comments on commit 51647b5

Please sign in to comment.