Skip to content

Generate types for UI extension intents#7342

Merged
JoviDeCroock merged 6 commits into
mainfrom
generate-types-for-ui-extension-intents
May 5, 2026
Merged

Generate types for UI extension intents#7342
JoviDeCroock merged 6 commits into
mainfrom
generate-types-for-ui-extension-intents

Conversation

@JoviDeCroock

@JoviDeCroock JoviDeCroock commented Apr 17, 2026

Copy link
Copy Markdown
Contributor

WHY are these changes introduced?

UI extensions can now declare intents — a
declarative way of saying "this target handles the create:application/email
intent" and shipping an input/output/value JSON Schema alongside it.

At runtime the host passes the intent payload to the extension via
shopify.intents.request, and the extension acknowledges it with
shopify.intents.response.ok(data). Without type generation, developers have no
way of knowing the shape of request.data, what request.value contains, or
what response.ok expects — they're back to any territory and have to cross-
reference the schema file by hand.

We already generate types for the related tools concept in the same
shopify.d.ts file. This PR brings intents to feature parity.

WHAT is this pull request doing?

For any UI-extension target that declares [[extensions.targeting.intents]]
entries with a schema file, the CLI now:

  1. Reads each referenced intent schema JSON file.
  2. Validates it against a zod schema (inputSchema required, value and
    outputSchema optional).
  3. Compiles each schema into a named TypeScript interface via
    json-schema-to-typescript, yielding (for e.g. create /
    application/email):
    • CreateApplicationEmailIntentInput
    • CreateApplicationEmailIntentValue
    • CreateApplicationEmailIntentOutput
    • CreateApplicationEmailIntentRequest — the discriminated request shape
      with literal action / type and a typed data / value.
  4. Emits two reusable helpers:
    • ShopifyGeneratedIntentResponse<Data> — the ok(data?: Data) handle.
    • ShopifyGeneratedIntentsApi<Request, ResponseData> — request/response
      pair, plus a ShopifyGeneratedIntentVariants union of every declared
      intent.
  5. Wires the generated types into the module's shopify declaration through a
    new WithGeneratedIntents<T> wrapper that merges them with whatever the
    target's own Api['intents'] already exposes (so base host properties like
    cancel, etc. survive augmentation).

The wrapper composes with the existing WithGeneratedTools<T>:

const shopify: WithGeneratedTools<
  WithGeneratedIntents<
    import('@shopify/ui-extensions/admin.app.intent.render').Api
  >
>;

Duplicate action:type pairs within a target throw an AbortError, matching
the existing behaviour for duplicate tool names. Missing / invalid schema files
emit a warning and skip generation rather than aborting, consistent with how
tools handles bad input.

Intent types are only emitted for the extension's entry-point file, not for any
file it imports (same behaviour as tools).

Edge cases to spot-check:

  • Removing the schema file: the CLI should outputWarn and regenerate
    shopify.d.ts without the intent types (no crash).
  • Duplicating an action:type pair within a single target: the CLI should
    abort with a clear error.
  • Intent schema with a root-level value key: the compiled
    *IntentValue interface should reflect that schema and be wired into
    request.value.

Tophatting

  • Create an intent action extension with shopify app generate extension
  • Run shopify app dev
  • Verify that types are generated for shopify.intents.response.ok() and shopify.intents.request.value

@JoviDeCroock JoviDeCroock force-pushed the generate-types-for-ui-extension-intents branch from 501d4be to eee043c Compare April 20, 2026 09:12
@JoviDeCroock JoviDeCroock marked this pull request as ready for review April 20, 2026 09:17
@JoviDeCroock JoviDeCroock requested a review from a team as a code owner April 20, 2026 09:17
Copilot AI review requested due to automatic review settings April 20, 2026 09:17

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Adds CLI support to generate TypeScript typings for UI extension intent schemas (similar to existing tools typing) and wires the generated types into the emitted shopify.d.ts module augmentations.

Changes:

  • Parse/validate intent schema JSON assets for UI extension targets and generate intent request/response/value/input/output types.
  • Extend createTypeDefinition to optionally wrap the base Api type with WithGeneratedIntents (and compose with WithGeneratedTools) plus supporting utility types.
  • Add/update Vitest coverage for intent type generation and updated shopify.d.ts output expectations.

Reviewed changes

Copilot reviewed 4 out of 4 changed files in this pull request and generated 2 comments.

File Description
packages/app/src/cli/models/extensions/specifications/ui_extension.ts Collects per-entrypoint intent definitions, reads/validates schema JSON, and passes generated intent typings into createTypeDefinition.
packages/app/src/cli/models/extensions/specifications/ui_extension.test.ts Updates expected shopify.d.ts output formatting and adds integration tests for intent typing generation behavior.
packages/app/src/cli/models/extensions/specifications/type-generation.ts Implements intent type generation (createIntentsTypeDefinition), adds WithGeneratedIntents (and related utility types), and updates how the shopify type is constructed.
packages/app/src/cli/models/extensions/specifications/type-generation.test.ts Adds unit tests for createIntentsTypeDefinition and keeps existing tools tests.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

@JoviDeCroock JoviDeCroock force-pushed the generate-types-for-ui-extension-intents branch 2 times, most recently from 03f0f5c to 3cbca04 Compare April 23, 2026 08:21
Comment thread packages/app/src/cli/models/extensions/specifications/type-generation.ts Outdated
@JoviDeCroock JoviDeCroock force-pushed the generate-types-for-ui-extension-intents branch 5 times, most recently from f6c4e49 to 88b18b8 Compare April 29, 2026 06:36
@github-actions github-actions Bot added the no-changelog This PR doesn't include a changeset entry. Is an internal only change not relevant to end users. label Apr 29, 2026

@gonzaloriestra gonzaloriestra left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I added some minor comments, but Copilot also left some good feedback.

Could you also add tophatting instructions? With AI the default PR template is now overwritten sometimes and it has some good points...

Comment thread packages/app/src/cli/models/extensions/specifications/type-generation.ts Outdated
Comment thread packages/app/src/cli/models/extensions/specifications/ui_extension.test.ts Outdated
@JoviDeCroock JoviDeCroock force-pushed the generate-types-for-ui-extension-intents branch from 88b18b8 to 392534b Compare April 29, 2026 11:17
@JoviDeCroock JoviDeCroock force-pushed the generate-types-for-ui-extension-intents branch from 392534b to 6a79ccf Compare May 1, 2026 07:52
@JoviDeCroock JoviDeCroock force-pushed the generate-types-for-ui-extension-intents branch from 6a79ccf to dd6da36 Compare May 5, 2026 06:24
@JoviDeCroock JoviDeCroock added this pull request to the merge queue May 5, 2026
Merged via the queue into main with commit 1a4e40e May 5, 2026
27 of 29 checks passed
@JoviDeCroock JoviDeCroock deleted the generate-types-for-ui-extension-intents branch May 5, 2026 09:24
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

no-changelog This PR doesn't include a changeset entry. Is an internal only change not relevant to end users.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants