Skip to content

Commit

Permalink
fix: union type sorting and various dependency issues (#1)
Browse files Browse the repository at this point in the history
* fix: union type sorting

* contentful-export update

* chore: more upgrades

* more dependency updates

* more updates
  • Loading branch information
phawxby authored May 5, 2022
1 parent e597ae8 commit 7b7b6df
Show file tree
Hide file tree
Showing 12 changed files with 2,379 additions and 3,665 deletions.
4 changes: 3 additions & 1 deletion .eslintrc
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,9 @@
"indent": [
"error",
4
]
],
"unicorn/consistent-function-scoping": "off",
"unicorn/no-array-callback-reference": "off"
},
"extends": [
"oclif",
Expand Down
1 change: 0 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -256,4 +256,3 @@ const stringContent = new CFDefinitionsBuilder()
### Browser Usage
You can use `CFDefinitionsBuilder` also in a browser environment.
> Example: [TS Content Types Generator App](https://github.com/marcolink/cf-content-types-generator-app)
24 changes: 13 additions & 11 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -26,8 +26,8 @@
"@oclif/errors": "latest",
"@oclif/plugin-help": "^3",
"cli-ux": "^5.5.1",
"contentful": "^8.1.7",
"contentful-export": "^7.11.6",
"contentful": "^9.1.28",
"contentful-export": "^7.16.0",
"fs-extra": "^9.1.0",
"lodash": "^4.17.15",
"ts-morph": "9.1.0",
Expand All @@ -38,18 +38,15 @@
"@oclif/dev-cli": "^1",
"@oclif/test": "^1.2.5",
"@semantic-release/changelog": "^5.0.1",
"@types/chai": "^4",
"@types/fs-extra": "^9.0.1",
"@types/lodash": "^4.14.155",
"@types/mocha": "^8",
"chai": "^4",
"eslint": "^7.12",
"eslint-config-oclif": "^3.1",
"eslint-config-oclif-typescript": "^0.2",
"@typescript-eslint/eslint-plugin": "^5.22.0",
"eslint": "^8.14.0",
"eslint-config-oclif": "^4.0.0",
"eslint-config-oclif-typescript": "^1.0.2",
"eslint-plugin-unicorn": "^42.0.0",
"jest-fixtures": "^0.6.0",
"mocha": "^5",
"nyc": "^15",
"semantic-release": "^17.0.7",
"semantic-release": "^19.0.2",
"strip-indent": "^3.0.0",
"typescript": "4.2.2"
},
Expand Down Expand Up @@ -90,6 +87,11 @@
"@semantic-release/github"
]
},
"resolutions": {
"ansi-regex": ">=3.0.1 <6.0.0",
"minimist": ">=1.2.6",
"path-parse": ">=1.0.7"
},
"publishConfig": {
"registry": "https://npm.pkg.github.com/xeroxinteractive"
}
Expand Down
51 changes: 25 additions & 26 deletions src/cf-definitions-builder.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import {Field} from 'contentful';
import * as path from 'path';
import * as path from 'node:path';
import {
forEachStructureChild,
ImportDeclarationStructure,
Expand Down Expand Up @@ -52,7 +52,7 @@ export default class CFDefinitionsBuilder {

const interfaceDeclaration = this.createInterfaceDeclaration(file, moduleFieldsName(model.sys.id));

model.fields.forEach(field => this.addProperty(file, interfaceDeclaration, field));
for (const field of model.fields) this.addProperty(file, interfaceDeclaration, field);

this.addEntryTypeAlias(file, model.sys.id, moduleFieldsName(model.sys.id));

Expand Down Expand Up @@ -81,34 +81,33 @@ export default class CFDefinitionsBuilder {
const imports: OptionalKind<ImportDeclarationStructure>[] = [];
const types: string[] = [];

this.project.getSourceFiles()
.filter(sourceFile => sourceFile.getBaseNameWithoutExtension() !== mergeFileName)
.forEach(sourceFile => forEachStructureChild(sourceFile.getStructure(),
childStructure => {
switch (childStructure.kind) {
case StructureKind.ImportDeclaration:
imports.push(childStructure);
break;
case StructureKind.Interface:
types.push(childStructure.name);
mergeFile.addInterface(childStructure);
break;
case StructureKind.TypeAlias:
types.push(childStructure.name);
mergeFile.addTypeAlias(childStructure);
break;
default:
throw new Error(`Unhandled node type '${StructureKind[childStructure.kind]}'.`);
}
}));
for (const sourceFile of this.project.getSourceFiles()
.filter(sourceFile => sourceFile.getBaseNameWithoutExtension() !== mergeFileName)) forEachStructureChild(sourceFile.getStructure(),
childStructure => {
switch (childStructure.kind) {
case StructureKind.ImportDeclaration:
imports.push(childStructure);
break;
case StructureKind.Interface:
types.push(childStructure.name);
mergeFile.addInterface(childStructure);
break;
case StructureKind.TypeAlias:
types.push(childStructure.name);
mergeFile.addTypeAlias(childStructure);
break;
default:
throw new Error(`Unhandled node type '${StructureKind[childStructure.kind]}'.`);
}
});

// only import modules not present in merge file
imports.forEach(importD => {
for (const importD of imports) {
const name = importD.moduleSpecifier.slice(2);
if (!types.includes(name)) {
mergeFile.addImportDeclaration(importD);
}
});
}

mergeFile.organizeImports({
ensureNewLineAtEndOfFile: true,
Expand Down Expand Up @@ -154,7 +153,7 @@ export default class CFDefinitionsBuilder {
namedImports: ['CMSManagementEntry'],
});

files.forEach(fileName => {
for (const fileName of files) {
indexFile.addImportDeclaration({
isTypeOnly: true,
namedImports: [moduleName(fileName), moduleFieldsName(fileName)],
Expand All @@ -169,7 +168,7 @@ export default class CFDefinitionsBuilder {
moduleSpecifier: `./${fileName}`,
});
cmsEntries.push(moduleName(fileName));
});
}

indexFile.addTypeAlias({isExported: true, name: 'CMSEntries', type: renderUnionType(cmsEntries)});
indexFile.addTypeAlias({isExported: true, name: 'CMSManagementEntries', type: renderUnionType(cmsEntries.map(name => renderGenericType('CMSManagementEntry', name)))});
Expand Down
2 changes: 2 additions & 0 deletions src/cf-property-imports.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,10 +17,12 @@ export const propertyImports = (field: Field, ignoreModule?: string): OptionalKi
.filter(filterIgnoredModule)
.map(moduleImport) : [{moduleSpecifier: './index', namedImports: ['CMSEntries']}];
}

if (field.type === 'Array' && field.items) {
return field.items?.validations?.length > 0 ? linkContentTypeValidations(field.items)
.filter(filterIgnoredModule)
.map(moduleImport) : [{moduleSpecifier: './index', namedImports: ['CMSEntries']}];
}

return [];
};
2 changes: 2 additions & 0 deletions src/cf-property-types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,10 @@ export const anyType = (field: Field): string => {
) {
return renderLiteralType;
}

return (value: string) => value.toString();
};

return renderUnionType(includesValidation.in.map(mapper()));
}
}
Expand Down
9 changes: 8 additions & 1 deletion src/index.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,12 @@
import {Command, flags} from '@oclif/command';
import * as fs from 'fs-extra';
import {writeFile} from 'fs-extra';
import * as path from 'path';
import * as path from 'node:path';
import CFDefinitionsBuilder from './cf-definitions-builder';

// Does not appear to work as an import, not sure why and I'm just clearing up the audit
// quickly so don't want to spent time messing about if it works.
// eslint-disable-next-line unicorn/prefer-module
const contentfulExport = require('contentful-export');

class ContentfulMdg extends Command {
Expand Down Expand Up @@ -43,6 +46,7 @@ class ContentfulMdg extends Command {
spaceId: flags.spaceId,
managementToken: flags.token,
environmentId: flags.environment,
// https://github.com/contentful/contentful-export/issues/966
skipEditorInterfaces: true,
skipContent: true,
skipRoles: true,
Expand All @@ -52,13 +56,16 @@ class ContentfulMdg extends Command {
}

const builder = new CFDefinitionsBuilder();

// eslint-disable-next-line unicorn/no-array-for-each
content.contentTypes.forEach(builder.appendType);

if (flags.out) {
const outDir = path.resolve(flags.out);
if (!flags.preserve && fs.existsSync(outDir)) {
await fs.remove(outDir);
}

await fs.ensureDir(outDir);
await builder.write(flags.out, writeFile);
} else {
Expand Down
1 change: 1 addition & 0 deletions src/renderer/cf-render-prop-array.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ export const renderPropArray = (field: Field): string => {
if (validation?.length > 0) {
return `(${renderUnionType(validation.map(renderLiteralType))})[]`;
}

return 'Contentful.EntryFields.Symbol[]';
}

Expand Down
2 changes: 2 additions & 0 deletions src/renderer/cf-render-prop-link.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,10 @@ export const renderPropLink = (field: Pick<Field, 'validations' | 'linkType'>) =
if (field.linkType === 'Entry') {
return linkContentType(field);
}

if (field.linkType === 'Asset') {
return 'AssetLink';
}

return 'Contentful.' + field.linkType!;
};
2 changes: 1 addition & 1 deletion src/renderer/render-union-type.ts
Original file line number Diff line number Diff line change
@@ -1 +1 @@
export const renderUnionType = (types: string[]): string => types.join(' | ');
export const renderUnionType = (types: string[]): string => types.sort().join(' | ');
3 changes: 2 additions & 1 deletion src/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,12 +23,13 @@ export const moduleTypeIdName = (name: string): string => camelCase(moduleName(n
type WithValidations = Pick<FieldItem, 'validations'>;

const validation = (node: WithValidations, field: keyof FieldValidation): any => {
if (node.validations && node.validations.length !== 0) {
if (node.validations && node.validations.length > 0) {
const linkContentValidation = node.validations.find(value => value[field]);
if (linkContentValidation) {
return linkContentValidation[field] || [];
}
}

return [];
};

Expand Down
Loading

0 comments on commit 7b7b6df

Please sign in to comment.