Skip to content

chore: regenerate schema from upstream spec - #34

Merged
cubehouse merged 1 commit into
mainfrom
automated/spec-drift
Sep 8, 2026
Merged

cubehouse merged 1 commit into
mainfrom
automated/spec-drift

Conversation

@github-actions

@github-actions github-actions Bot commented Sep 2, 2026

Copy link
Copy Markdown
Contributor

Automated schema regeneration from the api.themeparks.wiki OpenAPI spec.

  • build: success
  • live smoke tests: success

A build failure here means the upstream contract changed in a way
this client cannot absorb automatically. Do not merge until it is
green.

@cubehouse

Copy link
Copy Markdown
Member

Please hold this one. The regeneration is faithful to the published spec, but the published spec now under-describes GET /v1/entity/{id}/schedule, so merging would ship weaker types than the client has today.

The defect is upstream, in the spec

v1.yaml currently defines two schedule-entry schemas for the same payload:

EntityScheduleEntry:        # used by EntityScheduleResponse.schedule
  required: [date, type, openingTime, closingTime]
  properties:
    type: {type: string}    # no enum
    # no purchases
  additionalProperties: true

PricedScheduleEntry:        # used by ParkSchedule.schedule
  required: [date, openingTime, closingTime, type]
  properties:
    type:
      enum: [OPERATING, TICKETED_EVENT, PRIVATE_EVENT, EXTRA_HOURS, INFO]
    purchases:
      items: {$ref: SchedulePriceObject}

EntityScheduleResponse.schedule points at the loose one, ParkSchedule.schedule at the precise one. So the same data is described two different ways depending on whether you fetched a park directly or got it nested under its destination.

The loose one is wrong. Asking for a park's own schedule today:

GET /v1/entity/{Magic Kingdom}/schedule
  78 entries, types = [OPERATING, TICKETED_EVENT]
  27 entries carry `purchases`, purchase types = [ATTRACTION, PACKAGE]

Identical content to what comes back nested under the destination, which the spec types precisely.

What that costs consumers

Merging as-is would, on client.entity(id).schedule():

Today After
type: "OPERATING" | "TICKETED_EVENT" | "PRIVATE_EVENT" | "EXTRA_HOURS" | "INFO" type: string
purchases?: SchedulePriceObject[] gone, absorbed into [key: string]: unknown
price.amount: number | null price.amount: number
TagData.value?: string | number | Record<string, never> value?: unknown

The third is the one I would call a bug rather than a downgrade: the type would assert non-null for a field that has been nullable.

Everything else here is good

To be clear about what is not the problem. The rest of the regeneration is an improvement and should land once the spec is fixed:

  • paths/operations renames (/destinations → /v1/destinations, getDestinations → getAllDestinations) are inert. This client hand-writes its URLs in src/raw.ts and imports only components['schemas'], so nothing resolves through paths.
  • The internal renames (DestinationEntry → Destination, DestinationParkEntry → Park, ScheduleEntry → EntityScheduleEntry) do not reach consumers. components is not exported; only the aliases in src/index.ts, and all five keep their names.
  • Destination and Park correctly tighten id/name/parks from optional to required.
  • Descriptions arrive on nearly every field, which is a genuine gain for IDE hover.

Verified locally on this branch: npm ci, typecheck, build, 64 unit tests and the 4 live smoke tests all pass. It is not broken — it is just a step backwards on one endpoint.

Suggested order

  1. Fix EntityScheduleResponse.schedule in the spec to reference PricedScheduleEntry (or unify the two), and restore amount's nullability.
  2. Re-run the drift job.
  3. Merge the result.

Separately: this PR can never turn green on its own

main requires Test (Node 18), Test (Node 20) and Test (Node 22), and this PR has zero check runs. The drift job opens the PR with GITHUB_TOKEN, and GitHub does not trigger workflows from GITHUB_TOKEN-authored events. The required checks will therefore never report, whatever the diff contains. The same applies to ThemeParks_Python#19. That needs its own fix, or every future drift PR is stuck on arrival.

@cubehouse

Copy link
Copy Markdown
Member

One more thing, and it moves this from "a downgrade" to "a revert".

CHANGELOG.md for 7.1.0, released 2026-09-01, six days before this PR:

Fixed

  • PriceData.amount is now number | null, matching the API spec, which has declared this field nullable for some time. The API returns null when a paid queue exists but the provider does not publish a price; 0 is reserved for a queue that is genuinely free. The two were previously conflated as 0.

    This is a compile break for strict TypeScript consumers.

So nullable amount was not an accident of the old spec. It was a deliberate fix, shipped knowingly as a compile break, to stop "price not published" being silently read as "free".

The regenerated schema declares:

price:
  type: object
  properties:
    amount: {type: number}
  required: [amount, currency]

Merging would put amount: number back and re-conflate the two cases — undoing a breaking change that consumers were asked to absorb a week ago, without a changelog entry, in a PR titled "regenerate schema from upstream spec".

That makes the spec fix in the upstream tracker a correctness item rather than a polish one. Same conclusion, more firmly: fix v1.yaml first, then regenerate.

@cubehouse

Copy link
Copy Markdown
Member

Checked the rest of the nullability, as suggested. One field is provably wrong against production right now; the others are fine.

price.amount is null in live data today. Tokyo Disneyland, GET /v1/entity/{id}/live, six Premier Access rows:

Monsters, Inc. Ride & Go Seek!        PAID_RETURN_TIME  {"amount": null, "currency": "JPY"}
Splash Mountain                       PAID_RETURN_TIME  {"amount": null, "currency": "JPY"}
Big Thunder Mountain                  PAID_RETURN_TIME  {"amount": null, "currency": "JPY"}
Enchanted Tale of Beauty and the Beast PAID_RETURN_TIME {"amount": null, "currency": "JPY"}
Pooh's Hunny Hunt                     PAID_RETURN_TIME  {"amount": null, "currency": "JPY"}
The Happy Ride with Baymax            PAID_RETURN_TIME  {"amount": null, "currency": "JPY"}

Exactly the case the 7.1.0 CHANGELOG describes — a paid queue exists, the provider does not publish a price. The spec declares amount a required number. It is serving null to anyone who asks, at this moment.

The other nullability changes are safe, checked across 5 parks:

Field Old New Live evidence
children[].location {...} | null non-null EntityLocation 412 children sampled: 412 present, 0 null, 0 absent — tightening is correct
SchedulePriceObject.type ... | null SchedulePriceType enum 255 purchases sampled: only ATTRACTION and PACKAGE, never null
Destination.slug / .externalId string string | null gains nullability rather than losing it
EntityLocation.latitude / .longitude number number | null gains nullability

So the scope is narrower than feared: one wrong field, not a systematic loss. Fix amount back to nullable and point EntityScheduleResponse.schedule at PricedScheduleEntry, and the regeneration is a clean win.

@github-actions
github-actions Bot force-pushed the automated/spec-drift branch from fa9e987 to bf1a5d3 Compare September 8, 2026 11:22
cubehouse added a commit that referenced this pull request Sep 8, 2026
The drift job opened its PR with GITHUB_TOKEN. GitHub does not start workflow
runs from GITHUB_TOKEN-raised events, so the required Test (Node ...) checks
never reported and the PR was blocked on a report it could not receive. #34
has sat that way since 2026-09-02 while its body said 'build: success'.

Fixed by minting a short-lived installation token from the tpw-drift app and
handing it to create-pull-request. The push then comes from the app's identity
rather than GITHUB_TOKEN, pull_request fires normally, and CI reports. The app
holds contents:write and pull_requests:write on two repos and nothing else —
notably not workflows:write, so it cannot alter CI.

The create-an-issue steps keep GITHUB_TOKEN deliberately. They open issues on
failure, an issue does not need to trigger anything, and there is no reason to
widen the app's reach.

Also corrects the comment left on ci.yml's workflow_dispatch trigger by the
previous attempt. workflow_dispatch is genuinely a documented exception to the
no-runs rule, and it does start a run — but that run's check runs do not
satisfy branch protection. Measured, not assumed: on one PR, a dispatched run
put three successful check runs with the exact required names on the head SHA
and left it BLOCKED with an empty rollup for two minutes, while a push-event
run on the next commit cleared it at once. The trigger is kept because
re-running CI against a ref by hand is useful; the claim that it fixes drift
is removed.

Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
@tpw-drift
tpw-drift Bot force-pushed the automated/spec-drift branch from bf1a5d3 to c00d9f5 Compare September 8, 2026 13:16
@cubehouse
cubehouse merged commit cab0dd9 into main Sep 8, 2026
3 checks passed
@cubehouse
cubehouse deleted the automated/spec-drift branch September 8, 2026 13:31
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant