Skip to content

EPILIBS-201 Wrap API Endpoints#164

Open
zephyr-c wants to merge 13 commits into
masterfrom
zephyr-rock
Open

EPILIBS-201 Wrap API Endpoints#164
zephyr-c wants to merge 13 commits into
masterfrom
zephyr-rock

Conversation

@zephyr-c

@zephyr-c zephyr-c commented Jun 24, 2026

Copy link
Copy Markdown
Contributor

EPILIBS-201

Wrapped several API endpoints in new adapters using Claude code.

Add adapters for pipeline, encyclopedia, file, registration, and docket APIs

Summary

This branch adds five new epicenter-libs adapters wrapping the corresponding Forio API services, along with their types, unit tests, and export wiring. Each adapter follows the existing Router-based conventions (typed optionals intersected with RoutingOptions, .then(({ body }) => body) unwrapping, per-adapter *ReadOutView/*CreateInView types) and is backed by the API documentation in epicenter-api/*.json as the source of truth.

What's included

Adapter Functions Endpoints covered
pipeline getImages, execute GET /pipeline/npm/images, POST /pipeline/execute (clean/copy/git/npm operation union)
encyclopedia listServices, getResource, translate GET /encyclopedia/v{version}, /v{version}/{api}, /as/{translator}/v{version}/{api}
file list, upload, create, remove, download, listByFilter, compress, explode, move, createDirectory Full /file CRUD (± path), download, glob filter, compress/explode, move, directory creation
registration getSelfRegistrationInfo, completeSelfRegistration, sendSelfRegistrationInvite, getInviteRegistrationInfo, completeInviteRegistration, sendInvite, getTeamRegistrationInfo, sendTeamInvite, getSsoRegistration (deprecated), getSsoAdminRegistration, getSsoUserRegistration Self / invite / team registration flows + SSO registration
docket create POST /docket — schedules a deferred scale operation via a cron/date/offset trigger

Notes

  • Type fidelity: Discriminated unions are modeled to match the OpenAPI oneOf/discriminator schemas — pipeline operations (clean/copy/git/npm), file File/Directory entries, and docket payloads/triggers. The docket adapter reuses TaskTriggerCreateInView from task.ts rather than redefining the cron/date/offset trigger union.
  • Deprecation handling: registrationAdapter.getSsoRegistration is marked @deprecated and emits a runtime warning, matching the spec's deprecated: true flag; callers are pointed to getSsoAdminRegistration / getSsoUserRegistration.
  • Binary endpoints: file.download/file.compress and encyclopedia.translate document that the shared Router only handles JSON responses; JSDoc notes call out where direct fetch is needed for binary/non-JSON content types.
  • Exports: All five adapters are registered as namespace imports in src/adapters/index.ts and src/epicenter.ts, and their public types are re-exported from src/types.ts.

Testing

  • New spec files: pipeline.spec.js, encyclopedia.spec.js, file.spec.js, registration.spec.js, docket.spec.js119 tests, all passing, asserting HTTP method, URL/path construction, query params, and request bodies.
  • tsc --noEmit passes with no errors.
Test Files  5 passed (5)
     Tests  119 passed (119)

🤖 Generated with Claude Code

zephyr-c and others added 7 commits May 15, 2026 14:53
Implements wrappers for the pipeline API endpoints: getImages() to
retrieve available NPM node images, and execute() to run build pipelines
with clean, copy, git, and npm operations.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Implements wrappers for the encyclopedia API endpoints: listServices()
to retrieve known API services for a given version, getResource() to
fetch documented endpoints and definitions for a specific service, and
translate() to retrieve documentation in ASCIIDOC, ASCIIDOC_TO_HTML,
or OPENAPI format.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Implements wrappers for the file API: list() to browse files and
directories at root or a path, upload() (PUT) and create() (POST) for
multipart file uploads, remove() for deletion, download() to fetch raw
file content, listByFilter() for glob-pattern filtering, compress() and
explode() for archive operations, move() to relocate files, and
createDirectory() to create new directories.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- file: drop unused body params from compress/explode (backend ignores them);
  document content-type limitations on download/compress (router only accepts
  application/json responses)
- encyclopedia: document translate content-type limitations (only OPENAPI
  works through the router); widen return type to unknown
- pipeline: document getImages requires system authorization
- registration: tighten RegistrationResult.whoAmI to a discriminated-base
  WhoAmI interface; align deprecation warning with project convention; add
  example blocks to every function; document Accept-Language header support

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

@gemini-code-assist gemini-code-assist Bot 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.

Code Review

This pull request introduces several new adapters (docket, encyclopedia, file, pipeline, and registration) along with comprehensive unit tests, type definitions, and package exports. Feedback on the changes highlights the need to URL-encode path parameters (such as filePath, api, translator, and token) to safely handle special characters. Additionally, in the file adapter, the reviewer notes that calling .withSearchParams({ depth }) when depth is undefined will serialize it as depth=undefined in the query string, which may cause backend validation errors, and suggests conditionally applying the search parameters only when defined.

Important

The consumer version of Gemini Code Assist on GitHub is being sunset. Starting June 18, 2026, new organization installations will be blocked, and all code review activity will officially cease on July 17, 2026.
For more details on the timeline and next steps, please review the Help Documentation.

Comment thread src/adapters/file.ts
Comment thread src/adapters/file.ts
Comment thread src/adapters/file.ts
Comment thread src/adapters/file.ts
Comment thread src/adapters/file.ts
Comment thread src/adapters/file.ts
Comment thread src/adapters/encyclopedia.ts
Comment thread src/adapters/encyclopedia.ts
Comment thread src/adapters/registration.ts
Comment thread src/adapters/registration.ts
@zephyr-c

Copy link
Copy Markdown
Contributor Author

Resolution summary:

  • Accepted: URL-encoding for all file-adapter path params (filePath + filter), via a shared segment-wise encodePath helper that preserves /. File paths are free-form user input, so this is a real correctness fix. Added 2 tests.
  • Declined (not applicable): the depth=undefined reports — our Router.parseQuery already strips nullish query keys (src/utils/router.ts:128-131); added a test asserting depth is omitted when absent.
  • Declined (convention): encoding encyclopedia translator/api and registration token — these are closed enums / known service names / opaque URL-safe tokens, the same class of identifier every adapter interpolates raw.

@zephyr-c zephyr-c requested a review from sparklerfish June 24, 2026 22:57

@sparklerfish sparklerfish 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.

Overall excellent contribution, I verified all adapters against the platform source for correctness, and the adapter implementation is solid and well-aligned with existing libs conventions. The only major change is the pipelineAdapter -- unfortunately it looks like it went through a pretty major refactor on the platform side in the time since this was written, so the adapter will now need a bunch of changes to match. The only other requests are a couple minor improvements/fixes to the accuracy of the jsdocs, nothing wrong in the actual code.

Comment thread src/adapters/pipeline.ts

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.

It looks like the PipelineResource went through a significant refactor since this PR and the endpoints are now different. Current resource surface (@Path("/s3/{accountShortName}/{projectShortName}/pipeline")):

Method Path Returns
GET /npm/images boolean (buildNPMImages, @System)
POST /{configName} PipelineAuditReadOutView (executeConfig)
GET /with/{configName} Page<PipelineAuditReadOutView> (listAudits)
GET /{executionKey} PipelineAuditReadOutView (getExecution)
DELETE /{executionKey} boolean (deleteAudit)

What this changes for the adapter:

  1. execute: the endpoint and its whole contract changed
    Execution is now keyed by a stored config: the pipeline to run is identified by a configName path segment, and the operations are read server-side from that config file (.cfg1 / V1PipelineConfig.getOperations()). They are no longer sent in the request. The request body is now a single attribute map (@EntityParam("attributes")) used to pass step inputs such as credentials (e.g. the git token under the "git" key). There is no log parameter anymore. The endpoint returns the newly created audit record in its initial RUNNING state (the worker updates it on completion). So execute should take a config name + an optional attributes object, POST to /pipeline/{configName}, and return a typed audit view — not accept an operations array. Suggestion for revised shape:
export async function execute(
    configName: string,
    attributes: Record<string, unknown> = {},
    optionals: RoutingOptions = {},
): Promise<PipelineAuditReadOutView> {
    return await new Router()
        .post(`/pipeline/${encodeURIComponent(configName)}`, {
            body: { attributes },
            ...optionals,
        }).then(({ body }) => body);
}
  1. getImages: wrong semantics and return type
    The path is still correct, but GET /pipeline/npm/images maps to buildNPMImages(), which builds the NPM Docker images and returns a boolean; it's @System-only. There is no "list available images" endpoint. This should be renamed to reflect that it triggers a build, typed to return boolean, and the JSDoc updated (the system-authorization note is already right).

  2. Missing endpoints from the refactor
    The new resource added three read/delete operations that are worth wrapping so the whole API is covered in one pass: fetching a single audit by execution key (GET /pipeline/{executionKey}), listing audit history for a config name (GET /pipeline/with/{configName}, paginated via first/max -- use the existing paginated: true / Page<> pattern like the other paged adapters), and deleting an audit by execution key (DELETE /pipeline/{executionKey}, @System, returns boolean).

  3. Add a PipelineAuditReadOutView type
    All four non-boolean endpoints return this shape (generated from the PipelineAudit entity's read view). Its OUT fields are: status (RUNNING | SUCCEEDED | FAILED), started, finished, executionKey, accountShortName, projectShortName, configName, and the virtual creator (the triggering admin's display name). adminId is not part of the read view.

  4. The PipelineOperation types don't belong on this adapter
    They model the config file (Doppelganger purposes = "file"), not the API, so once execute stops taking operations they're unused here. They also have field-level mismatches against the current Java, so I'd suggest dropping them from this adapter rather than carrying them forward. If we want typed config-file authoring later, that can be its own module/ticket — and it should fix these first:

  • GitOperation has no password field (only force/confirmed); the git credential travels in the execution attributes map, not on the operation.
  • CopyItem.location is the required enum CopyLocation (INTERFACE | PROXY | MODEL | DATA), not unknown.
  • NPMOperation.commands is a required string[]; nodeVersion and directory are enums (NodeVersion, BuildDirectory), not free strings.
  • The registered polymorphic union is clean/copy/git/npm; configure exists as an OperationType but isn't in the @Polymorphic(subClasses=...) list, so confirm before relying on it.
  • These enums serialize through custom EnumXmlAdapters, so the exact wire strings would need to be checked against those adapters before settling on string-literal unions.

Related changes:

  • types.ts: remove the PipelineOperation / operation interfaces from the pipeline re-export block; add PipelineExecutionStatus and PipelineAuditReadOutView.
  • pipeline.spec.js: the current tests assert POST /pipeline/execute with an operations body, so they'll need to be rewritten for the five endpoints above (path/method, the {attributes} envelope, the paginated listAudits, and the boolean returns).
  • Since the mocked tests only assert what the adapter sends, they'll pass against whatever we write — so it's worth one sanity check against a live Encyclopedia v3 dump for pipeline (particularly to confirm the attributes body envelope key) before merging.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Rewound the adapter to the refactored resource: buildImages (GET /npm/images → boolean), execute (POST /{configName}, { attributes } body → audit), getExecution (GET /{executionKey}), listAudits (GET /with/{configName}, paginated Page<>), deleteAudit (DELETE /{executionKey} → boolean). Dropped the config-file PipelineOperation types and added PipelineExecutionStatus + PipelineAuditReadOutView (with virtual creator, no adminId). types.ts and the spec updated.

Confirmed against a live /encyclopedia/v3/pipeline dump: the POST body is the { attributes } envelope (JsonMap), and PipelineAuditReadOutView matches field-for-field (8 fields, enum status, no adminId) — no changes needed to execute/getExecution/listAudits or the types. The two @System endpoints (buildImages, deleteAudit) weren't in this dump because it was pulled with an AUTHOR-level token, which filters System endpoints; I don't think I have system level access so can't generate a dump that includes these, but they match your Java description.

Comment thread src/adapters/file.ts
Comment thread src/adapters/encyclopedia.ts
@zephyr-c zephyr-c requested a review from sparklerfish July 9, 2026 17:46
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants