vendure-ecommerce/vendure

Specifying `internal` Administrator custom field without also specifying `readonly` causes crash

Closed this issue · 0 comments

Describe the bug

When specifying an internal custom field for the Administrator entity, Vendure crashes on startup. The error is:

Error: Unknown type "UpdateAdministratorCustomFieldsInput". Did you mean "UpdateAdministratorInput" or "CreateAdministratorInput"?
    at assertValidSDLExtension (/home/projects/vendure-starter/node_modules/graphql/validation/validate.js:149:11)
    at extendSchema (/home/projects/vendure-starter/node_modules/graphql/utilities/extendSchema.js:63:43)
    at addActiveAdministratorCustomFields (/home/projects/vendure-starter/node_modules/@vendure/core/src/api/config/graphql-custom-fields.ts:299:24)
    at buildSchemaForApi (/home/projects/vendure-starter/node_modules/@vendure/core/src/api/config/configure-graphql-module.ts:171:56)
    at async createGraphQLOptions (/home/projects/vendure-starter/node_modules/@vendure/core/src/api/config/configure-graphql-module.ts:93:25)
    at async InstanceWrapper.useFactory [as metatype] (/home/projects/vendure-starter/node_modules/@nestjs/graphql/dist/graphql.module.js:89:48)
    at async Injector.instantiateClass (/home/projects/vendure-starter/node_modules/@nestjs/core/injector/injector.js:369:37)
    at async callback (/home/projects/vendure-starter/node_modules/@nestjs/core/injector/injector.js:65:34)
    at async Injector.resolveConstructorParams (/home/projects/vendure-starter/node_modules/@nestjs/core/injector/injector.js:144:24)
    at async Injector.loadInstance (/home/projects/vendure-starter/node_modules/@nestjs/core/injector/injector.js:70:13) 

To Reproduce

  1. Add the following to customFields in vendure-config.ts:
Administrator: [{
      name: 'testField',
      type: 'string',
      public: false,
      internal: true
}]
  1. (Optional; the problem happens either way) Run npx vendure migrate and generate a migration for the new custom field.
  2. Run npm run dev
  3. It will crash.

Here is a reproduction in Stackblitz, forked from an existing Vendure example and with all the Vendure dependencies updated:
https://stackblitz.com/edit/vendure-starter-kspu5w?file=src%2Fvendure-config.ts

Expected behavior
The app would start and the custom internal field would be available on the Administrator entity (exclusively within plugins, in TypeScript.)

Environment (please complete the following information):

  • @vendure/core version: 3.0.5
  • Nodejs version: v18.20.3 and v20.14.0
  • Database (mysql/postgres etc): It happens at least with SQLite and Postgres

Additional context

It works as soon as I take away internal: true, so I assume that that's the problem. It seems like when the custom field is internal, the UpdateAdministratorCustomFieldsInput type is not created in GraphQL, which makes sense, but some code somewhere still expects it to exist just because there is a custom field.

More specifically, it seems like the problem is here:

const writableCustomFields = administratorCustomFields?.filter(field => field.readonly !== true);
const extension = `
extend input UpdateActiveAdministratorInput {
customFields: ${
0 < writableCustomFields?.length ? 'UpdateAdministratorCustomFieldsInput' : 'JSON'
}
}
`;
return extendSchema(schema, parse(extension));

Just because there is a non-readonly custom field, the UpdateActiveAdministratorInput type is being extended with the assumption that the UpdateAdministratorCustomFieldsInput exists. However, because the field is internal, which from my reading of the docs should act as a superset of readonly, the administrator custom fields input type was apparently not created, so the schema is invalid.

I have not checked if the same problem occurs with entities other than Administrator.