Problem/Motivation

Found while building four new paragraph bundles (tab group/item, table/row) on a graphql_compose site. The README describes listing "every node (and paragraph) bundle", and paragraph bundles are where scaffold boilerplate is heaviest (inline fragment + TS type + renderer switch case + component stub per bundle).

Actual behavior: drush gqcc:inspect lists only node bundles (paragraph mentions in its output are just DrupalParagraph[] field types on node bundles), and drush gqcc:generate --help says "Generates TypeScript scaffold artefacts for node bundles." New paragraph bundles produce no scaffold; the frontend fragments/types/renderer cases must be hand-written.

Steps to reproduce

1. Enable a paragraph bundle in graphql_compose entity_config (enabled + query_load_enabled) with at least one field in field_config.
2. Run drush gqcc:inspect — the paragraph bundle does not appear.
3. Run drush gqcc:generate — no scaffold artefacts for the bundle.

Proposed resolution

Treat paragraph bundles as first-class scaffold targets:
- an inline-fragment entry suitable for a shared PARAGRAPH_FRAGMENTS-style block
- a TS type joining a paragraph union type
- a switch-case stub for a ParagraphRenderer
- a component stub per bundle

One trap worth handling in the generator: when two paragraph bundles select the same field name (e.g. items) and their subfield nullability differs (required vs optional), GraphQL forbids merging the shared response key — the generator should emit an alias (e.g. tabItems: items) in that case.

Mirrored from the GitHub development repo: https://github.com/Wilkes-Liberty/graphql_compose_codegen/issues/14

Comments

jmcerda created an issue. See original summary.

jmcerda’s picture

Status: Active » Needs review
StatusFileSize
new62.72 KB

Implemented on the GitHub development repo: https://github.com/Wilkes-Liberty/graphql_compose_codegen/pull/15 (branch 3613218-paragraph-scaffolding, targeting 1.x). Patch against 1.x attached.

What it does:

- gqcc:inspect lists paragraph bundles enabled in graphql_compose (entity_config enabled + query_load_enabled, per-field field_config enablement), in the same visual style as the node listing. Both the 2.x config name (graphql_compose.settings) and the 3.x per-server names (graphql_compose.settings.<server_id>) are read. Bundles that only appear nested inside other paragraphs are marked nested-only. Sites without any graphql_compose config keep the previous list-everything behaviour.

- gqcc:generate emits four paragraph artefacts mirroring the node set: paragraphs/types.generated.d.ts (types joining the DrupalParagraph union), paragraphs/fragments.generated.ts (the PARAGRAPH_FRAGMENTS block), paragraphs/paragraph-renderer-cases.generated.tsx (new: switch on __typename, data prop, default: return null), and one {Name}Paragraph component stub per bundle.

- The response-key merge trap from the issue summary is handled: collisions are detected across all enabled bundles and the later bundle's field is aliased (tabItems: items), with the TS property named after the alias. Aliases stay stable when generating a subset with --bundles. A kernel fixture reproduces the exact p_faq_group / p_tab_group case (optional vs required title/body).

- Nested paragraph references (entity_reference_revisions) emit nested inline fragments for handler_settings.target_bundles, one level deep, with bundle-specific TS types (DrupalParagraphPFaqItem[]). Previously the paragraph fragments emitted ${PARAGRAPH_FRAGMENTS} inside the PARAGRAPH_FRAGMENTS literal itself.

- --bundles now filters paragraph bundles for generate / diff / validate / inspect; a paragraph-only run no longer aborts with "No matching node bundles found" (and no longer overwrites node artefacts with empty ones), which also makes the schema-change dblog tips correct for paragraph bundles and fields.

Verified on a site with 21 enabled paragraph bundles (including the faq/tab/table nested pairs): the generated fragments and types match the hand-written frontend files the module should have generated, including both hand-written aliases (tabItems: items, noticeTitle: title). phpcs and phpstan pass; the test suite grows from 20 to 33 (kernel fixture + unit coverage), with drupal/paragraphs added to require-dev and both CI pipelines.

Known follow-up for a separate issue: the contrib webform field type has no field-type mapper yet, so field_webform scaffolds as webform # TODO: add sub-selection for type unknown.

jmcerda’s picture

The implementation PR merged to the 1.x development branch on GitHub (https://github.com/Wilkes-Liberty/graphql_compose_codegen/pull/15). Two follow-ups before the next release:

- https://github.com/Wilkes-Liberty/graphql_compose_codegen/pull/17 adds kernel coverage for the schema-change log notices from this change (the suggested drush command in each notice is asserted verbatim).
- The webform mapper gap noted in #2 is now #3613232 (implemented, Needs review).

Leaving this at Needs review until the change reaches the drupal.org repo with the next tag, at which point it can go to Fixed.

  • jmcerda committed 35b5ff1f on 1.x
    Issue #3613218: Add kernel coverage for the schema-change log notices...

  • jmcerda committed cd282d89 on 1.x
    Issue #3613218: Add paragraph bundle scaffolding to inspect and generate...
jmcerda’s picture

Status: Needs review » Fixed

Shipped in 1.1.0 (commits on 1.x, tag 1.1.0). The follow-up test coverage (GitHub PR #17) is included in the same release.

Now that this issue is closed, review the contribution record.

As a contributor, attribute any organization that helped you, or if you volunteered your own time.

Maintainers, credit people who helped resolve this issue.

Status: Fixed » Closed (fixed)

Automatically closed - issue fixed for 2 weeks with no activity.