Skip to content

Commit e7a04be

Browse files
authored
feat(api): make the AIP TypeScript SDK release-ready (#4687)
1 parent 54551be commit e7a04be

126 files changed

Lines changed: 6664 additions & 1421 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.github/workflows/aip-npm-release.yaml

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,12 @@ jobs:
6060
cache-dependency-path: api/spec/pnpm-lock.yaml
6161
registry-url: "https://registry.npmjs.org"
6262

63+
# Publish gate: the SDK conformance suite and emitter checks must pass on
64+
# the exact checkout being published, so a broken build can never reach npm
65+
# even though this workflow runs independently of the CI workflow.
66+
- name: Run SDK and emitter tests
67+
run: make -C api/spec test
68+
6369
- name: Publish NPM package
6470
run: make -C api/spec publish-aip-sdk
6571
env:

.github/workflows/ci.yaml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -542,6 +542,10 @@ jobs:
542542
run: |
543543
nix develop --impure .#ci -c make lint-api-spec
544544
545+
- name: Run tests - api spec SDK
546+
run: |
547+
nix develop --impure .#ci -c make test-api-spec
548+
545549
- name: Run linters - openapi
546550
run: |
547551
nix develop --impure .#ci -c make lint-openapi

AGENTS.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -96,9 +96,9 @@ All generated files have `// Code generated by X, DO NOT EDIT.` headers — neve
9696
2. Run `make gen-api` to regenerate OpenAPI spec and SDKs
9797
3. Run `make generate` to regenerate Go server/client code
9898

99-
The TypeSpec JS client emitted from `api/spec/packages/aip` now lands in `api/spec/packages/aip-client-javascript/`. The emitter regenerates `src/` and `README.md` only; `package.json` is **stable, hand-maintained, and committed** (the emitter's `writeOutput` only writes the paths it lists, so the manifest survives regeneration). Keep hand-written Playwright config, tests, and helpers outside `src/`, and put test-runner dependencies/scripts in the `api/spec/package.json` workspace root rather than the client package manifest. Static publish metadata (`name`, `license`, `homepage`, `repository`) lives directly in the client `package.json`; only the per-release `version` is injected at publish time.
99+
The TypeSpec JS client emitted from `api/spec/packages/aip` now lands in `api/spec/packages/aip-client-javascript/`. The emitter regenerates `src/`, `README.md`, and five conformance test files (`tests/client.spec.ts`, `tests/meters.spec.ts`, `tests/errors.spec.ts`, `tests/nesting.spec.ts`, `tests/internal.spec.ts`); every regenerated file carries a `Code generated by @openmeter/typespec-typescript. DO NOT EDIT.` header — treat files without that header as hand-written. `package.json` is **stable, hand-maintained, and committed** (the emitter's `writeOutput` only writes the paths it lists, so the manifest survives regeneration). The test suite is vitest + `@fetch-mock/vitest`; keep hand-written tests and helpers in `tests/` (never `src/`), and put test-runner dependencies/scripts in the `api/spec/package.json` workspace root rather than the client package manifest. Static publish metadata (`name`, `license`, `homepage`, `repository`) lives directly in the client `package.json`; only the per-release `version` is injected at publish time. Operations marked `x-private` in the TypeSpec source are omitted from the generated SDK (they stay in the OpenAPI output); operations marked `x-internal` (without `x-private`) are emitted but quarantined under `client.internal.<group>.<method>` (`src/sdk/internal.ts`, an `Internal` aggregate with `Internal<Group>` facade classes; internal ops share their group's `funcs/` and `models/operations/` modules, a group whose ops are all internal gets no public facade, and the `Internal` class is deliberately not re-exported from the package root — the name belongs to the Internal Server Error model). Removing an operation from the spec (or marking it private) leaves stale generated files behind — the emitter never deletes outputs, so `git rm` them.
100100

101-
The emitted `api/spec/packages/aip-client-javascript/src/openMeterClient.ts` exposes aggregated sub-client getters on `OpenMeterClient` (e.g. `meters`, `customers`, `features`, `productCatalog`, `subscriptions`, `billing`, `entitlements`). Access operations through those getters, e.g. `sdk.meters.list()`, `sdk.customers.create(...)`, `sdk.productCatalog.createPlan(...)`. Note that resources are grouped by tag, so some operations live under a grouped client rather than a same-named top-level getter (for example plan operations are `sdk.productCatalog.createPlan`, not `sdk.plans.create`).
101+
The emitted `api/spec/packages/aip-client-javascript/src/sdk/sdk.ts` exposes aggregated sub-client getters on the `OpenMeter` class (e.g. `events`, `meters`, `customers`, `entitlements`, `subscriptions`, `billing`, `features`, `plans`, `addons`, `planAddons`, `tax`, `defaults`). Access operations through those getters, e.g. `sdk.meters.list()`, `sdk.customers.create(...)`, `sdk.plans.create(...)`. These grouped-client methods throw `HTTPError` on failure; the same operations are also available as tree-shakeable standalone functions under `src/funcs/` that return a `Result` instead of throwing.
102102

103103
**Workflow for changing Go types/DI:**
104104

Makefile

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -260,6 +260,11 @@ lint-api-spec: ## Lint OpenAPI spec
260260
$(call print-target)
261261
$(MAKE) -C api/spec lint
262262

263+
.PHONY: test-api-spec
264+
test-api-spec: ## Run AIP TypeScript SDK and emitter tests
265+
$(call print-target)
266+
$(MAKE) -C api/spec test
267+
263268
.PHONY: lint-openapi
264269
lint-openapi: ## Lint OpenAPI spec
265270
$(call print-target)

0 commit comments

Comments
 (0)