diff --git a/spec/project/select-modules-in-sources.spec.ts b/spec/project/select-modules-in-sources.spec.ts index 96b9508d..c5c84f70 100644 --- a/spec/project/select-modules-in-sources.spec.ts +++ b/spec/project/select-modules-in-sources.spec.ts @@ -182,6 +182,53 @@ describe('selectModulesInProjectSource', () => { expect(result.getModel().modules).to.deep.equal([]); }); + it('removes files that become comment-only', () => { + const project = new Project({ + sources: [ + new ProjectSource( + 'modules.json', + JSON.stringify({ + modules: ['module1', 'module2', 'module3', 'extra1', 'extra2'], + }), + ), + gql` + # a comment in the keeper file + type Keeper @rootEntity @modules(in: "module1", includeAllFields: true) { + key: String @key + } + `.loc!.source, + gql` + # a comment in the discard file + type Discard @rootEntity @modules(in: "extra2", includeAllFields: true) { + key: String @key + } + `.loc!.source, + // will also remove this one because we're throwing away comment-only file when + // parsing a project. Documenting that behavior in this test case, but it's + // probably fine either way + { + name: 'empty.graphqls', + body: "# a file that's already comment-only", + }, + ], + modelOptions: { withModuleDefinitions: true }, + }); + expectToBeValid(project); + + const result = project.withModuleSelection(['module1', 'module2'], { + removeModuleDeclarations: true, + }); + expectToBeValid(result); + expect(result.sources.map((s) => s.body)).to.deep.equal([ + ` + # a comment in the keeper file + type Keeper @rootEntity { + key: String @key + } + `, + ]); + }); + it('removes the modules part in an object file with modules and something else', () => { const project = new Project({ sources: [ @@ -207,6 +254,85 @@ describe('selectModulesInProjectSource', () => { }`); expect(result.getModel().modules).to.deep.equal([]); }); + + it('works in a more complicated case', () => { + const result = run( + gql` + # The IciDocument is deprecated because it will be replaced by general DocumentMeta - DocumentContent structure + type IciDocument + @rootEntity #(permissionProfile: "users") + @modules(in: ["module1", "module2"], includeAllFields: true) { + id: ID @key + + accessGroup: String + + name: String + mimeType: String + + "The base64 encoded binary contents" + body: String + } + + type InternationalCustomsData + @suppress(warnings: UNUSED) + @entityExtension + @modules(in: ["module1", "module2"], includeAllFields: true) { + requestData: InternationalCustomsRequestData + resultData: InternationalCustomsResultData + } + + type InternationalCustomsRequestData + @entityExtension + @modules(in: ["module1", "module2"], includeAllFields: true) { + isInternationalCustomsRelevant: Boolean + @defaultValue(value: false) + @suppress(infos: NO_TYPE_CHECKS) + } + + type InternationalCustomsResultData + @entityExtension + @modules(in: ["module1", "module2"], includeAllFields: true) { + internationalCustomsTransmittedTS: DateTime + iciConsignmentId: String + iciDeclarationId: String + customsRegistrationNumber: String + attachments: [IciAttachments] + } + + type IciAttachments + @valueObject + @modules(in: ["module1", "module2"], includeAllFields: true) { + attachmentId: ID + attachment: IciDocument @reference(keyField: "attachmentId") + } + + # Used by app ici-result-sync to control sync status with ici. + type SyncId + @rootEntity + @modules(in: ["module1", "module2"], includeAllFields: true) { + systemKey: String @key + syncId: String + } + `, + [], + { removeModuleDeclarations: true }, + ); + expect(result).to.equal(` + type OneAndTwo @rootEntity { + all: String + two: String + extra1: String + + } + + type Two @rootEntity { + all: String + one: String + } + + + `); + }); }); }); diff --git a/src/project/select-modules-in-sources.ts b/src/project/select-modules-in-sources.ts index 81c6ce45..e09ac0d3 100644 --- a/src/project/select-modules-in-sources.ts +++ b/src/project/select-modules-in-sources.ts @@ -21,6 +21,7 @@ import { findDirectiveWithName } from '../schema/schema-utils'; import { Project, ProjectOptions } from './project'; import { ProjectSource } from './source'; import { isReadonlyArray } from '../utils/utils'; +import { isCommentOnlySource } from '../graphql/is-comment-only-source'; export interface ModuleSelectionOptions { /** @@ -255,6 +256,10 @@ function selectModulesInGraphQLSource({ } } + if (!changes) { + return source.body; + } + let currentPosition = 0; let output = ''; for (let i = 0; i <= changes.length; i++) { @@ -275,6 +280,11 @@ function selectModulesInGraphQLSource({ } } + // if we removed everything except comments, delete the file + if (isCommentOnlySource(output)) { + return undefined; + } + return output; }