diff --git a/api/openapi/markdown/openapi-openapi.md b/api/openapi/markdown/openapi-openapi.md
index a649c2fa74f..7501e5d71a2 100644
--- a/api/openapi/markdown/openapi-openapi.md
+++ b/api/openapi/markdown/openapi-openapi.md
@@ -93,21 +93,7 @@ User-scoped operations
| 422 | Validation error | **application/json**: [ErrorBody](#errorbody)
|
| default | Error | **application/json**: [ErrorBody](#errorbody)
|
-### [GET] /apps/{app_id}/check-dependencies
-#### Parameters
-
-| Name | Located in | Description | Required | Schema |
-| ---- | ---------- | ----------- | -------- | ------ |
-| app_id | path | | Yes | string |
-
-#### Responses
-
-| Code | Description | Schema |
-| ---- | ----------- | ------ |
-| 200 | Dependencies checked | **application/json**: [CheckDependenciesResult](#checkdependenciesresult)
|
-| default | Error | **application/json**: [ErrorBody](#errorbody)
|
-
-### [GET] /apps/{app_id}/describe
+### [GET] /apps/{app_id}
#### Parameters
| Name | Located in | Description | Required | Schema |
@@ -123,7 +109,21 @@ User-scoped operations
| 422 | Validation error | **application/json**: [ErrorBody](#errorbody)
|
| default | Error | **application/json**: [ErrorBody](#errorbody)
|
-### [GET] /apps/{app_id}/export
+### [GET] /apps/{app_id}/dependencies
+#### Parameters
+
+| Name | Located in | Description | Required | Schema |
+| ---- | ---------- | ----------- | -------- | ------ |
+| app_id | path | | Yes | string |
+
+#### Responses
+
+| Code | Description | Schema |
+| ---- | ----------- | ------ |
+| 200 | Dependencies checked | **application/json**: [CheckDependenciesResult](#checkdependenciesresult)
|
+| default | Error | **application/json**: [ErrorBody](#errorbody)
|
+
+### [GET] /apps/{app_id}/dsl
#### Parameters
| Name | Located in | Description | Required | Schema |
@@ -140,7 +140,7 @@ User-scoped operations
| 422 | Validation error | **application/json**: [ErrorBody](#errorbody)
|
| default | Error | **application/json**: [ErrorBody](#errorbody)
|
-### [POST] /apps/{app_id}/files/upload
+### [POST] /apps/{app_id}/files
Upload a file to use as an input variable when running the app
#### Parameters
@@ -160,7 +160,7 @@ Upload a file to use as an input variable when running the app
| 415 | Unsupported file type or blocked extension | |
| default | Error | **application/json**: [ErrorBody](#errorbody)
|
-### [GET] /apps/{app_id}/form/human_input/{form_token}
+### [GET] /apps/{app_id}/human-input-forms/{form_token}
#### Parameters
| Name | Located in | Description | Required | Schema |
@@ -174,7 +174,7 @@ Upload a file to use as an input variable when running the app
| ---- | ----------- | ------ |
| 200 | Form definition | **application/json**: [HumanInputFormDefinitionResponse](#humaninputformdefinitionresponse)
|
-### [POST] /apps/{app_id}/form/human_input/{form_token}
+### [POST] /apps/{app_id}/human-input-forms/{form_token}:submit
#### Parameters
| Name | Located in | Description | Required | Schema |
@@ -196,7 +196,38 @@ Upload a file to use as an input variable when running the app
| 422 | Validation error | **application/json**: [ErrorBody](#errorbody)
|
| default | Error | **application/json**: [ErrorBody](#errorbody)
|
-### [POST] /apps/{app_id}/run
+### [GET] /apps/{app_id}/tasks/{task_id}/events
+#### Parameters
+
+| Name | Located in | Description | Required | Schema |
+| ---- | ---------- | ----------- | -------- | ------ |
+| continue_on_pause | query | Whether to keep the event stream open on pause | No | boolean |
+| include_state_snapshot | query | Whether to include workflow state snapshots | No | boolean |
+| app_id | path | | Yes | string |
+| task_id | path | | Yes | string |
+
+#### Responses
+
+| Code | Description | Schema |
+| ---- | ----------- | ------ |
+| 200 | SSE event stream | **application/json**: [EventStreamResponse](#eventstreamresponse)
|
+
+### [POST] /apps/{app_id}/tasks/{task_id}:stop
+#### Parameters
+
+| Name | Located in | Description | Required | Schema |
+| ---- | ---------- | ----------- | -------- | ------ |
+| app_id | path | | Yes | string |
+| task_id | path | | Yes | string |
+
+#### Responses
+
+| Code | Description | Schema |
+| ---- | ----------- | ------ |
+| 200 | Task stopped | **application/json**: [TaskStopResponse](#taskstopresponse)
|
+| default | Error | **application/json**: [ErrorBody](#errorbody)
|
+
+### [POST] /apps/{app_id}:run
#### Parameters
| Name | Located in | Description | Required | Schema |
@@ -216,37 +247,6 @@ Upload a file to use as an input variable when running the app
| 200 | Run result (SSE stream) | **application/json**: [EventStreamResponse](#eventstreamresponse)
|
| 422 | Validation error | **application/json**: [ErrorBody](#errorbody)
|
-### [GET] /apps/{app_id}/tasks/{task_id}/events
-#### Parameters
-
-| Name | Located in | Description | Required | Schema |
-| ---- | ---------- | ----------- | -------- | ------ |
-| continue_on_pause | query | Whether to keep the event stream open on pause | No | boolean |
-| include_state_snapshot | query | Whether to include workflow state snapshots | No | boolean |
-| app_id | path | | Yes | string |
-| task_id | path | | Yes | string |
-
-#### Responses
-
-| Code | Description | Schema |
-| ---- | ----------- | ------ |
-| 200 | SSE event stream | **application/json**: [EventStreamResponse](#eventstreamresponse)
|
-
-### [POST] /apps/{app_id}/tasks/{task_id}/stop
-#### Parameters
-
-| Name | Located in | Description | Required | Schema |
-| ---- | ---------- | ----------- | -------- | ------ |
-| app_id | path | | Yes | string |
-| task_id | path | | Yes | string |
-
-#### Responses
-
-| Code | Description | Schema |
-| ---- | ----------- | ------ |
-| 200 | Task stopped | **application/json**: [TaskStopResponse](#taskstopresponse)
|
-| default | Error | **application/json**: [ErrorBody](#errorbody)
|
-
### [POST] /oauth/device/approve
#### Request Body
@@ -330,7 +330,7 @@ Upload a file to use as an input variable when running the app
| 422 | Validation error | **application/json**: [ErrorBody](#errorbody)
|
| default | Error | **application/json**: [ErrorBody](#errorbody)
|
-### [GET] /permitted-external-apps/{app_id}/describe
+### [GET] /permitted-external-apps/{app_id}
#### Parameters
| Name | Located in | Description | Required | Schema |
@@ -391,7 +391,7 @@ Upload a file to use as an input variable when running the app
| 422 | Validation error | **application/json**: [ErrorBody](#errorbody)
|
| default | Error | **application/json**: [ErrorBody](#errorbody)
|
-### [POST] /workspaces/{workspace_id}/apps/imports/{import_id}/confirm
+### [POST] /workspaces/{workspace_id}/apps/imports/{import_id}:confirm
#### Parameters
| Name | Located in | Description | Required | Schema |
@@ -460,7 +460,7 @@ Upload a file to use as an input variable when running the app
| 200 | Member removed | **application/json**: [MemberActionResponse](#memberactionresponse)
|
| default | Error | **application/json**: [ErrorBody](#errorbody)
|
-### [PUT] /workspaces/{workspace_id}/members/{member_id}/role
+### [PATCH] /workspaces/{workspace_id}/members/{member_id}
#### Parameters
| Name | Located in | Description | Required | Schema |
@@ -482,7 +482,7 @@ Upload a file to use as an input variable when running the app
| 422 | Validation error | **application/json**: [ErrorBody](#errorbody)
|
| default | Error | **application/json**: [ErrorBody](#errorbody)
|
-### [POST] /workspaces/{workspace_id}/switch
+### [POST] /workspaces/{workspace_id}:switch
#### Parameters
| Name | Located in | Description | Required | Schema |
@@ -532,7 +532,7 @@ Upload a file to use as an input variable when running the app
#### AppDescribeQuery
-`?fields=` allow-list for GET /apps//describe.
+`?fields=` allow-list for GET /apps/.
Empty / omitted → all blocks. Unknown member → ValidationError → 422.
@@ -550,7 +550,7 @@ Empty / omitted → all blocks. Unknown member → ValidationError → 422.
#### AppDslExportQuery
-Query parameters for GET /apps//export.
+Query parameters for GET /apps//dsl.
| Name | Type | Description | Required |
| ---- | ---- | ----------- | -------- |
@@ -762,7 +762,7 @@ future server adds a code. Formatter tests pin emitted values to the enum.
#### FormSubmitResponse
-Empty 200 body for POST /apps//form/human_input/. `extra='forbid'`
+Empty 200 body for POST /apps//human-input-forms/:submit. `extra='forbid'`
pins `additionalProperties: false` so the generated contract is an exact `{}` rather
than an under-annotated open object.
@@ -1022,7 +1022,7 @@ generated CLI whitelist all derive from it.
#### TaskStopResponse
-200 body for POST /apps//tasks//stop. The handler always returns
+200 body for POST /apps//tasks/:stop. The handler always returns
{"result": "success"}, so `result` is required (no default) — the generated contract
types it as a required `'success'` rather than an optional field.
diff --git a/cli/src/api/app-dsl.test.ts b/cli/src/api/app-dsl.test.ts
index 66d4507317e..9056a228212 100644
--- a/cli/src/api/app-dsl.test.ts
+++ b/cli/src/api/app-dsl.test.ts
@@ -26,7 +26,7 @@ describe('AppDslClient.exportDsl', () => {
const yaml = await makeClient(stub.url).exportDsl('app-1')
expect(stub.captured.method).toBe('GET')
- expect(stub.captured.url?.split('?')[0]).toBe('/openapi/v1/apps/app-1/export')
+ expect(stub.captured.url?.split('?')[0]).toBe('/openapi/v1/apps/app-1/dsl')
expect(yaml).toBe(DSL_YAML)
})
@@ -90,7 +90,7 @@ describe('AppDslClient.confirmImport', () => {
const result = await makeClient(stub.url).confirmImport('ws-1', 'imp-1')
expect(stub.captured.method).toBe('POST')
- expect(stub.captured.url).toBe('/openapi/v1/workspaces/ws-1/apps/imports/imp-1/confirm')
+ expect(stub.captured.url).toBe('/openapi/v1/workspaces/ws-1/apps/imports/imp-1:confirm')
expect(result.status).toBe('completed')
})
})
@@ -107,7 +107,7 @@ describe('AppDslClient.checkDependencies', () => {
const result = await makeClient(stub.url).checkDependencies('app-1')
- expect(stub.captured.url?.split('?')[0]).toBe('/openapi/v1/apps/app-1/check-dependencies')
+ expect(stub.captured.url?.split('?')[0]).toBe('/openapi/v1/apps/app-1/dependencies')
expect(result.leaked_dependencies).toEqual([])
})
})
diff --git a/cli/src/api/app-dsl.ts b/cli/src/api/app-dsl.ts
index acb10a95351..733f1fa8fac 100644
--- a/cli/src/api/app-dsl.ts
+++ b/cli/src/api/app-dsl.ts
@@ -33,7 +33,7 @@ export class AppDslClient {
}
async exportDsl(appId: string, query?: ExportQuery): Promise {
- const resp = await this.orpc.apps.byAppId.export.get({
+ const resp = await this.orpc.apps.byAppId.dsl.get({
params: { app_id: appId },
query: query !== undefined
? {
@@ -52,7 +52,7 @@ export class AppDslClient {
}
async checkDependencies(appId: string): Promise {
- return this.orpc.apps.byAppId.checkDependencies.get({
+ return this.orpc.apps.byAppId.dependencies.get({
params: { app_id: appId },
})
}
diff --git a/cli/src/api/app-run.ts b/cli/src/api/app-run.ts
index cbd36de2049..a75b3f0c63a 100644
--- a/cli/src/api/app-run.ts
+++ b/cli/src/api/app-run.ts
@@ -54,7 +54,7 @@ export class AppRunClient {
body: Record,
opts: StreamOptions = {},
): Promise> {
- const res = await this.http.stream(`apps/${encodeURIComponent(appId)}/run`, {
+ const res = await this.http.stream(`apps/${encodeURIComponent(appId)}:run`, {
method: 'POST',
json: body,
headers: { Accept: 'text/event-stream' },
@@ -79,7 +79,7 @@ export class AppRunClient {
action: string,
inputs: Record,
): Promise {
- await this.orpc.apps.byAppId.form.humanInput.byFormToken.post({
+ await this.orpc.apps.byAppId.humanInputForms.byFormToken.submit.post({
params: { app_id: appId, form_token: formToken },
body: { action, inputs },
})
diff --git a/cli/src/api/apps.test.ts b/cli/src/api/apps.test.ts
index 861f60feb26..ba9126b7b98 100644
--- a/cli/src/api/apps.test.ts
+++ b/cli/src/api/apps.test.ts
@@ -82,12 +82,12 @@ describe('AppsClient.describe', () => {
await stub?.stop()
})
- it('hits /apps//describe, omits workspace_id and fields when not given', async () => {
+ it('hits /apps/, omits workspace_id and fields when not given', async () => {
stub = await startStubServer(cap => jsonResponder(200, DESCRIBE_BODY, cap))
const res = await makeClient(stub.url).describe('app-1')
- expect(stub.captured.url?.split('?')[0]).toBe('/openapi/v1/apps/app-1/describe')
+ expect(stub.captured.url?.split('?')[0]).toBe('/openapi/v1/apps/app-1')
const q = queryOf(stub.captured.url)
expect(q.has('workspace_id')).toBe(false)
expect(q.has('fields')).toBe(false)
@@ -107,6 +107,6 @@ describe('AppsClient.describe', () => {
await makeClient(stub.url).describe('app/with space')
- expect(stub.captured.url?.split('?')[0]).toBe('/openapi/v1/apps/app%2Fwith%20space/describe')
+ expect(stub.captured.url?.split('?')[0]).toBe('/openapi/v1/apps/app%2Fwith%20space')
})
})
diff --git a/cli/src/api/apps.ts b/cli/src/api/apps.ts
index 1189fdeaa06..fa29d66fd14 100644
--- a/cli/src/api/apps.ts
+++ b/cli/src/api/apps.ts
@@ -37,7 +37,7 @@ export class AppsClient implements AppReader {
}
async describe(appId: string, fields?: readonly string[]): Promise {
- return this.orpc.apps.byAppId.describe.get({
+ return this.orpc.apps.byAppId.get({
params: { app_id: appId },
query: {
fields: fields !== undefined && fields.length > 0 ? fields.join(',') : undefined,
diff --git a/cli/src/api/file-upload.test.ts b/cli/src/api/file-upload.test.ts
index 018389916b0..602cf351e60 100644
--- a/cli/src/api/file-upload.test.ts
+++ b/cli/src/api/file-upload.test.ts
@@ -41,7 +41,7 @@ describe('FileUploadClient.upload', () => {
const result = await makeClient(stub.url).upload('app-1', filePath)
expect(stub.captured.method).toBe('POST')
- expect(stub.captured.url).toBe('/openapi/v1/apps/app-1/files/upload')
+ expect(stub.captured.url).toBe('/openapi/v1/apps/app-1/files')
// The client must let fetch own the multipart Content-Type + boundary; it
// must NOT coerce this to application/json the way a json body would.
const contentType = stub.captured.headers?.['content-type'] ?? ''
@@ -61,7 +61,7 @@ describe('FileUploadClient.upload', () => {
await makeClient(stub.url).upload('app/with space', filePath)
- expect(stub.captured.url).toBe('/openapi/v1/apps/app%2Fwith%20space/files/upload')
+ expect(stub.captured.url).toBe('/openapi/v1/apps/app%2Fwith%20space/files')
})
it('propagates a server 413 as a classified BaseError', async () => {
diff --git a/cli/src/api/file-upload.ts b/cli/src/api/file-upload.ts
index 7a032737a59..011f898c74e 100644
--- a/cli/src/api/file-upload.ts
+++ b/cli/src/api/file-upload.ts
@@ -65,7 +65,7 @@ export class FileUploadClient {
form.append('file', blob, filename)
return this.http.post(
- `apps/${encodeURIComponent(appId)}/files/upload`,
+ `apps/${encodeURIComponent(appId)}/files`,
{ body: form, timeoutMs: 60_000 },
)
}
diff --git a/cli/src/api/members.test.ts b/cli/src/api/members.test.ts
index b4e01b76b24..a8fdc633f77 100644
--- a/cli/src/api/members.test.ts
+++ b/cli/src/api/members.test.ts
@@ -154,13 +154,13 @@ describe('MembersClient.updateRole', () => {
await stub?.stop()
})
- it('PUTs role payload to /role subresource', async () => {
+ it('PATCHes role payload to the member resource', async () => {
stub = await startStubServer(cap => jsonResponder(200, { result: 'success' }, cap))
const result = await makeClient(stub.url).updateRole('ws-1', 'm-1', { role: 'admin' })
- expect(stub.captured.method).toBe('PUT')
- expect(stub.captured.url).toBe('/openapi/v1/workspaces/ws-1/members/m-1/role')
+ expect(stub.captured.method).toBe('PATCH')
+ expect(stub.captured.url).toBe('/openapi/v1/workspaces/ws-1/members/m-1')
expect(JSON.parse(stub.captured.body ?? '{}')).toEqual({ role: 'admin' })
expect(result.result).toBe('success')
})
@@ -181,7 +181,7 @@ describe('WorkspacesClient.switch (integration with stub)', () => {
await stub?.stop()
})
- it('POSTs /workspaces//switch and returns workspace detail', async () => {
+ it('POSTs /workspaces/:switch and returns workspace detail', async () => {
stub = await startStubServer(cap =>
jsonResponder(
200,
@@ -200,7 +200,7 @@ describe('WorkspacesClient.switch (integration with stub)', () => {
const result = await client.switch('ws-1')
expect(stub.captured.method).toBe('POST')
- expect(stub.captured.url).toBe('/openapi/v1/workspaces/ws-1/switch')
+ expect(stub.captured.url).toBe('/openapi/v1/workspaces/ws-1:switch')
expect(result.current).toBe(true)
})
diff --git a/cli/src/api/members.ts b/cli/src/api/members.ts
index 7b1f80c08ff..8a9bc13081f 100644
--- a/cli/src/api/members.ts
+++ b/cli/src/api/members.ts
@@ -47,7 +47,7 @@ export class MembersClient {
memberId: string,
payload: MemberRoleUpdatePayload,
): Promise {
- return this.orpc.workspaces.byWorkspaceId.members.byMemberId.role.put({
+ return this.orpc.workspaces.byWorkspaceId.members.byMemberId.patch({
params: { workspace_id: workspaceId, member_id: memberId },
body: payload,
})
diff --git a/cli/src/api/permitted-external-apps.test.ts b/cli/src/api/permitted-external-apps.test.ts
index f6fa38cb3eb..58f47b4566f 100644
--- a/cli/src/api/permitted-external-apps.test.ts
+++ b/cli/src/api/permitted-external-apps.test.ts
@@ -12,15 +12,15 @@ describe('PermittedExternalAppsClient', () => {
it('list calls permittedExternalApps.get with paging/filter query', async () => {
const c = new PermittedExternalAppsClient(fakeHttp())
const get = vi.fn().mockResolvedValue({ page: 1, limit: 20, total: 0, has_more: false, data: [] })
- ;(c as unknown as WithOrpc).orpc = { permittedExternalApps: { get, byAppId: { describe: { get: vi.fn() } } } }
+ ;(c as unknown as WithOrpc).orpc = { permittedExternalApps: { get, byAppId: { get: vi.fn() } } }
await c.list({ workspaceId: '', page: 2, limit: 5, mode: undefined, name: 'a' })
expect(get).toHaveBeenCalledWith({ query: { page: 2, limit: 5, mode: undefined, name: 'a' } })
})
- it('describe calls permittedExternalApps.byAppId.describe.get with app_id + fields', async () => {
+ it('describe calls permittedExternalApps.byAppId.get with app_id + fields', async () => {
const c = new PermittedExternalAppsClient(fakeHttp())
const dget = vi.fn().mockResolvedValue({ info: null, parameters: null, input_schema: null })
- ;(c as unknown as WithOrpc).orpc = { permittedExternalApps: { get: vi.fn(), byAppId: { describe: { get: dget } } } }
+ ;(c as unknown as WithOrpc).orpc = { permittedExternalApps: { get: vi.fn(), byAppId: { get: dget } } }
await c.describe('app-1', ['info'])
expect(dget).toHaveBeenCalledWith({ params: { app_id: 'app-1' }, query: { fields: 'info' } })
})
diff --git a/cli/src/api/permitted-external-apps.ts b/cli/src/api/permitted-external-apps.ts
index 497c398d0ba..c0164d3c536 100644
--- a/cli/src/api/permitted-external-apps.ts
+++ b/cli/src/api/permitted-external-apps.ts
@@ -26,7 +26,7 @@ export class PermittedExternalAppsClient implements AppReader {
}
async describe(appId: string, fields?: readonly string[]): Promise {
- return this.orpc.permittedExternalApps.byAppId.describe.get({
+ return this.orpc.permittedExternalApps.byAppId.get({
params: { app_id: appId },
query: { fields: fields !== undefined && fields.length > 0 ? fields.join(',') : undefined },
})
diff --git a/cli/src/api/workspaces.ts b/cli/src/api/workspaces.ts
index 3ef587b574d..08495a01fce 100644
--- a/cli/src/api/workspaces.ts
+++ b/cli/src/api/workspaces.ts
@@ -19,7 +19,7 @@ export class WorkspacesClient {
/**
* Server-side workspace switch via OpenAPI POST
- * `/workspaces/{id}/switch` — the bearer-authed equivalent of the
+ * `/workspaces/{id}:switch` — the bearer-authed equivalent of the
* console's POST `/workspaces/switch`. The server updates the caller's
* `current` tenant_account_join row. Callers MUST refresh their local
* `hosts.yml` only after this resolves — never fall back to a local
diff --git a/cli/src/commands/resume/app/run.test.ts b/cli/src/commands/resume/app/run.test.ts
index a72b0a93b25..8e1882906ae 100644
--- a/cli/src/commands/resume/app/run.test.ts
+++ b/cli/src/commands/resume/app/run.test.ts
@@ -41,7 +41,7 @@ describe('resumeApp pre-flight subject strategy', () => {
const http = {
baseURL: 'http://localhost',
request: vi.fn().mockImplementation((opts: { path: string }) => {
- if (typeof opts.path === 'string' && opts.path.includes('form/human_input')) {
+ if (typeof opts.path === 'string' && opts.path.includes('human-input-forms')) {
return Promise.resolve(FORM_RESP)
}
// reconnect stream — return an async iterable that ends immediately
diff --git a/cli/src/commands/resume/app/run.ts b/cli/src/commands/resume/app/run.ts
index 1dc2855a118..0610f68d5e6 100644
--- a/cli/src/commands/resume/app/run.ts
+++ b/cli/src/commands/resume/app/run.ts
@@ -50,7 +50,7 @@ export async function resumeApp(opts: ResumeAppOptions, deps: ResumeAppDeps): Pr
let action = opts.action
if (action === undefined) {
const formResp = await deps.http.get<{ user_actions: { id: string }[] }>(
- `apps/${encodeURIComponent(opts.appId)}/form/human_input/${encodeURIComponent(opts.formToken)}`,
+ `apps/${encodeURIComponent(opts.appId)}/human-input-forms/${encodeURIComponent(opts.formToken)}`,
)
if (formResp.user_actions.length === 1) {
action = formResp.user_actions[0]?.id ?? ''
diff --git a/cli/src/commands/run/app/run.ts b/cli/src/commands/run/app/run.ts
index ab468678a72..c0598b0eab0 100644
--- a/cli/src/commands/run/app/run.ts
+++ b/cli/src/commands/run/app/run.ts
@@ -65,7 +65,7 @@ async function executeRun(
const m = await meta.get(opts.appId, [FieldInfo])
const mode = m.info?.mode ?? ''
if (mode === '')
- throw new Error(`app ${opts.appId}: mode missing from /describe`)
+ throw new Error(`app ${opts.appId}: mode missing from app metadata`)
if (mode === RUN_MODES.Workflow && opts.message !== undefined && opts.message !== '') {
throw new BaseError({
diff --git a/cli/src/commands/use/workspace/use.ts b/cli/src/commands/use/workspace/use.ts
index 3070a76aa3e..94f335c940e 100644
--- a/cli/src/commands/use/workspace/use.ts
+++ b/cli/src/commands/use/workspace/use.ts
@@ -27,7 +27,7 @@ export type UseWorkspaceDeps = {
* workspace list and let the caller pick one interactively (TTY only).
*
* The server-side switch is the source of truth: if POST
- * `/workspaces//switch` fails we abort before touching `hosts.yml`, so
+ * `/workspaces/:switch` fails we abort before touching `hosts.yml`, so
* local state never diverges from the server.
*/
export async function runUseWorkspace(
diff --git a/cli/src/http/client.test.ts b/cli/src/http/client.test.ts
index ae4448843a4..fa397852c98 100644
--- a/cli/src/http/client.test.ts
+++ b/cli/src/http/client.test.ts
@@ -184,7 +184,7 @@ describe('http client', () => {
const client = createHttpClient({ baseURL: base(mock.url), bearer: 'dfoa_test' })
let caught: unknown
try {
- await client.get('apps/nope/describe')
+ await client.get('apps/nope')
}
catch (err) { caught = err }
expect(isHttpClientError(caught)).toBe(true)
@@ -545,7 +545,7 @@ describe('empty / No-Content bodies', () => {
})
try {
const client = createHttpClient({ baseURL: stub.url, bearer: 'dfoa_test' })
- await expect(client.post('apps/app-1/tasks/t-1/stop', { json: {} })).resolves.toBeUndefined()
+ await expect(client.post('apps/app-1/tasks/t-1:stop', { json: {} })).resolves.toBeUndefined()
}
finally {
await stub.stop()
diff --git a/cli/src/http/error-mapper.test.ts b/cli/src/http/error-mapper.test.ts
index 3244222da07..610b24fcfe4 100644
--- a/cli/src/http/error-mapper.test.ts
+++ b/cli/src/http/error-mapper.test.ts
@@ -74,7 +74,7 @@ describe('classifyResponse — canonical ErrorBody', () => {
describe('classifyResponse 403', () => {
it('maps 403 to AccessDenied (exit 4 bucket)', async () => {
- const req403 = new Request('https://x/openapi/v1/apps/abc/export')
+ const req403 = new Request('https://x/openapi/v1/apps/abc/dsl')
const res403 = new Response(
JSON.stringify({ code: 'unsupported_token_type', message: 'unsupported_token_type', status: 403 }),
{ status: 403, headers: { 'content-type': 'application/json' } },
diff --git a/cli/test/e2e/suites/discovery/get-app-single.e2e.ts b/cli/test/e2e/suites/discovery/get-app-single.e2e.ts
index b620eb383ef..528c08c9fa0 100644
--- a/cli/test/e2e/suites/discovery/get-app-single.e2e.ts
+++ b/cli/test/e2e/suites/discovery/get-app-single.e2e.ts
@@ -3,7 +3,7 @@
*
* Test cases sourced from: Dify CLI Enhanced spec — Dify CLI/Discovery/Single App Query (22 cases)
*
- * Note: difyctl get app queries a single app via GET /apps//describe?fields=info.
+ * Note: difyctl get app queries a single app via GET /apps/?fields=info.
* The response is returned in list-envelope format {page,limit,total,data:[...]}.
*/
diff --git a/cli/test/fixtures/dify-mock/server.test.ts b/cli/test/fixtures/dify-mock/server.test.ts
index 7233f2a23b3..e80e20643c7 100644
--- a/cli/test/fixtures/dify-mock/server.test.ts
+++ b/cli/test/fixtures/dify-mock/server.test.ts
@@ -111,15 +111,15 @@ describe('dify-mock fixture server', () => {
expect(body.data.map(r => r.id).sort()).toEqual(['app-3', 'app-4'])
})
- it('GET /openapi/v1/apps/:id/describe returns 404 for unknown id', async () => {
- const r = await fetch(`${mock.url}/openapi/v1/apps/nope/describe?workspace_id=550e8400-e29b-41d4-a716-446655440000`, {
+ it('GET /openapi/v1/apps/:id returns 404 for unknown id', async () => {
+ const r = await fetch(`${mock.url}/openapi/v1/apps/nope?workspace_id=550e8400-e29b-41d4-a716-446655440000`, {
headers: { Authorization: 'Bearer dfoa_test' },
})
expect(r.status).toBe(404)
})
- it('GET /openapi/v1/apps/:id/describe returns the app for known id', async () => {
- const r = await fetch(`${mock.url}/openapi/v1/apps/app-1/describe?workspace_id=550e8400-e29b-41d4-a716-446655440000`, {
+ it('GET /openapi/v1/apps/:id returns the app for known id', async () => {
+ const r = await fetch(`${mock.url}/openapi/v1/apps/app-1?workspace_id=550e8400-e29b-41d4-a716-446655440000`, {
headers: { Authorization: 'Bearer dfoa_test' },
})
expect(r.status).toBe(200)
@@ -127,8 +127,8 @@ describe('dify-mock fixture server', () => {
expect(body.info.id).toBe('app-1')
})
- it('POST /openapi/v1/apps/:id/run returns SSE stream for chat app', async () => {
- const r = await fetch(`${mock.url}/openapi/v1/apps/app-1/run`, {
+ it('POST /openapi/v1/apps/:id:run returns SSE stream for chat app', async () => {
+ const r = await fetch(`${mock.url}/openapi/v1/apps/app-1:run`, {
method: 'POST',
headers: {
'Authorization': 'Bearer dfoa_test',
@@ -142,8 +142,8 @@ describe('dify-mock fixture server', () => {
expect(text).toContain('"answer":"echo: "')
})
- it('POST /openapi/v1/apps/:id/run returns SSE stream for workflow app', async () => {
- const r = await fetch(`${mock.url}/openapi/v1/apps/app-2/run`, {
+ it('POST /openapi/v1/apps/:id:run returns SSE stream for workflow app', async () => {
+ const r = await fetch(`${mock.url}/openapi/v1/apps/app-2:run`, {
method: 'POST',
headers: {
'Authorization': 'Bearer dfoa_test',
@@ -157,8 +157,8 @@ describe('dify-mock fixture server', () => {
expect(text).toContain('"workflow_finished"')
})
- it('GET /openapi/v1/apps/:id/describe?fields=info returns slim payload', async () => {
- const r = await fetch(`${mock.url}/openapi/v1/apps/app-1/describe?workspace_id=550e8400-e29b-41d4-a716-446655440000&fields=info`, {
+ it('GET /openapi/v1/apps/:id?fields=info returns slim payload', async () => {
+ const r = await fetch(`${mock.url}/openapi/v1/apps/app-1?workspace_id=550e8400-e29b-41d4-a716-446655440000&fields=info`, {
headers: { Authorization: 'Bearer dfoa_test' },
})
expect(r.status).toBe(200)
@@ -168,8 +168,8 @@ describe('dify-mock fixture server', () => {
expect(body.input_schema).toBeNull()
})
- it('GET /openapi/v1/apps/:id/describe full returns parameters when present', async () => {
- const r = await fetch(`${mock.url}/openapi/v1/apps/app-1/describe?workspace_id=550e8400-e29b-41d4-a716-446655440000`, {
+ it('GET /openapi/v1/apps/:id full returns parameters when present', async () => {
+ const r = await fetch(`${mock.url}/openapi/v1/apps/app-1?workspace_id=550e8400-e29b-41d4-a716-446655440000`, {
headers: { Authorization: 'Bearer dfoa_test' },
})
expect(r.status).toBe(200)
diff --git a/cli/test/fixtures/dify-mock/server.ts b/cli/test/fixtures/dify-mock/server.ts
index 766963cd0d5..9f612669d4a 100644
--- a/cli/test/fixtures/dify-mock/server.ts
+++ b/cli/test/fixtures/dify-mock/server.ts
@@ -15,9 +15,9 @@ export type DifyMock = {
scenario: Scenario
setScenario: (s: Scenario) => void
stop: () => Promise
- /** Body of the most recent POST to /apps/:id/run */
+ /** Body of the most recent POST to /apps/:id:run */
lastRunBody: Record | null
- /** Number of times POST /apps/:id/files/upload was called */
+ /** Number of times POST /apps/:id/files was called */
uploadCallCount: number
/** Body of the most recent POST to /workspaces/:id/apps/imports */
lastImportBody: Record | null
@@ -251,7 +251,7 @@ export function buildApp(getScenario: () => Scenario, state?: MockState): Hono {
})
})
- app.get('/openapi/v1/apps/:id/describe', (c) => {
+ app.get('/openapi/v1/apps/:id', (c) => {
const id = c.req.param('id')
const wsId = c.req.query('workspace_id')
const fieldsRaw = c.req.query('fields') ?? ''
@@ -279,7 +279,7 @@ export function buildApp(getScenario: () => Scenario, state?: MockState): Hono {
})
})
- app.get('/openapi/v1/permitted-external-apps/:id/describe', (c) => {
+ app.get('/openapi/v1/permitted-external-apps/:id', (c) => {
const id = c.req.param('id')
const fieldsRaw = c.req.query('fields') ?? ''
const fields = fieldsRaw === '' ? [] : fieldsRaw.split(',').map(s => s.trim()).filter(s => s !== '')
@@ -307,7 +307,7 @@ export function buildApp(getScenario: () => Scenario, state?: MockState): Hono {
})
})
- app.get('/openapi/v1/apps/:id/export', (c) => {
+ app.get('/openapi/v1/apps/:id/dsl', (c) => {
const id = c.req.param('id')
const found = APPS.find(a => a.id === id)
if (found === undefined)
@@ -315,7 +315,7 @@ export function buildApp(getScenario: () => Scenario, state?: MockState): Hono {
return c.json({ data: DSL_YAML })
})
- app.get('/openapi/v1/apps/:id/check-dependencies', (c) => {
+ app.get('/openapi/v1/apps/:id/dependencies', (c) => {
const id = c.req.param('id')
const found = APPS.find(a => a.id === id)
if (found === undefined)
@@ -335,12 +335,13 @@ export function buildApp(getScenario: () => Scenario, state?: MockState): Hono {
return c.json({ id: 'imp-1', status: 'completed', app_id: 'app-1', app_mode: 'chat' }, { status: 200 })
})
- app.post('/openapi/v1/workspaces/:wsId/apps/imports/:importId/confirm', (c) => {
+ app.post('/openapi/v1/workspaces/:wsId/apps/imports/:importId:confirm', (c) => {
return c.json({ id: 'imp-1', status: 'completed', app_id: 'app-1', app_mode: 'chat' }, { status: 200 })
})
- app.post('/openapi/v1/apps/:id/run', async (c) => {
- const id = c.req.param('id')
+ app.post('/openapi/v1/apps/:id:run', async (c) => {
+ // Hono drops the param adjacent to the `:run` literal; recover the app id from the path.
+ const id = c.req.path.replace(/^.*\/apps\//, '').replace(/:run$/, '')
const body = await c.req.json() as { query?: string, inputs?: unknown }
if (state !== undefined)
state.lastRunBody = body as Record
@@ -400,7 +401,7 @@ export function buildApp(getScenario: () => Scenario, state?: MockState): Hono {
return new Response(sse, { status: 200, headers: { 'content-type': 'text/event-stream' } })
})
- app.post('/openapi/v1/apps/:id/files/upload', async (c) => {
+ app.post('/openapi/v1/apps/:id/files', async (c) => {
if (state !== undefined)
state.uploadCallCount++
const form = await c.req.formData()
@@ -421,11 +422,11 @@ export function buildApp(getScenario: () => Scenario, state?: MockState): Hono {
)
})
- app.post('/openapi/v1/apps/:id/tasks/:taskId/stop', (c) => {
+ app.post('/openapi/v1/apps/:id/tasks/:taskId:stop', (c) => {
return c.json({ result: 'success' })
})
- app.post('/openapi/v1/apps/:id/form/human_input/:formToken', (c) => {
+ app.post('/openapi/v1/apps/:id/human-input-forms/:formToken:submit', (c) => {
return c.json({})
})
diff --git a/packages/contracts/generated/api/openapi/orpc.gen.ts b/packages/contracts/generated/api/openapi/orpc.gen.ts
index 47aa1b90d6a..b936a6b2e04 100644
--- a/packages/contracts/generated/api/openapi/orpc.gen.ts
+++ b/packages/contracts/generated/api/openapi/orpc.gen.ts
@@ -12,16 +12,16 @@ import {
zGetAccountResponse,
zGetAccountSessionsQuery,
zGetAccountSessionsResponse,
- zGetAppsByAppIdCheckDependenciesPath,
- zGetAppsByAppIdCheckDependenciesResponse,
- zGetAppsByAppIdDescribePath,
- zGetAppsByAppIdDescribeQuery,
- zGetAppsByAppIdDescribeResponse,
- zGetAppsByAppIdExportPath,
- zGetAppsByAppIdExportQuery,
- zGetAppsByAppIdExportResponse,
- zGetAppsByAppIdFormHumanInputByFormTokenPath,
- zGetAppsByAppIdFormHumanInputByFormTokenResponse,
+ zGetAppsByAppIdDependenciesPath,
+ zGetAppsByAppIdDependenciesResponse,
+ zGetAppsByAppIdDslPath,
+ zGetAppsByAppIdDslQuery,
+ zGetAppsByAppIdDslResponse,
+ zGetAppsByAppIdHumanInputFormsByFormTokenPath,
+ zGetAppsByAppIdHumanInputFormsByFormTokenResponse,
+ zGetAppsByAppIdPath,
+ zGetAppsByAppIdQuery,
+ zGetAppsByAppIdResponse,
zGetAppsByAppIdTasksByTaskIdEventsPath,
zGetAppsByAppIdTasksByTaskIdEventsQuery,
zGetAppsByAppIdTasksByTaskIdEventsResponse,
@@ -30,9 +30,9 @@ import {
zGetHealthResponse,
zGetOauthDeviceLookupQuery,
zGetOauthDeviceLookupResponse,
- zGetPermittedExternalAppsByAppIdDescribePath,
- zGetPermittedExternalAppsByAppIdDescribeQuery,
- zGetPermittedExternalAppsByAppIdDescribeResponse,
+ zGetPermittedExternalAppsByAppIdPath,
+ zGetPermittedExternalAppsByAppIdQuery,
+ zGetPermittedExternalAppsByAppIdResponse,
zGetPermittedExternalAppsQuery,
zGetPermittedExternalAppsResponse,
zGetVersionResponse,
@@ -42,11 +42,14 @@ import {
zGetWorkspacesByWorkspaceIdPath,
zGetWorkspacesByWorkspaceIdResponse,
zGetWorkspacesResponse,
- zPostAppsByAppIdFilesUploadPath,
- zPostAppsByAppIdFilesUploadResponse,
- zPostAppsByAppIdFormHumanInputByFormTokenBody,
- zPostAppsByAppIdFormHumanInputByFormTokenPath,
- zPostAppsByAppIdFormHumanInputByFormTokenResponse,
+ zPatchWorkspacesByWorkspaceIdMembersByMemberIdBody,
+ zPatchWorkspacesByWorkspaceIdMembersByMemberIdPath,
+ zPatchWorkspacesByWorkspaceIdMembersByMemberIdResponse,
+ zPostAppsByAppIdFilesPath,
+ zPostAppsByAppIdFilesResponse,
+ zPostAppsByAppIdHumanInputFormsByFormTokenSubmitBody,
+ zPostAppsByAppIdHumanInputFormsByFormTokenSubmitPath,
+ zPostAppsByAppIdHumanInputFormsByFormTokenSubmitResponse,
zPostAppsByAppIdRunBody,
zPostAppsByAppIdRunPath,
zPostAppsByAppIdRunResponse,
@@ -70,9 +73,6 @@ import {
zPostWorkspacesByWorkspaceIdMembersResponse,
zPostWorkspacesByWorkspaceIdSwitchPath,
zPostWorkspacesByWorkspaceIdSwitchResponse,
- zPutWorkspacesByWorkspaceIdMembersByMemberIdRoleBody,
- zPutWorkspacesByWorkspaceIdMembersByMemberIdRolePath,
- zPutWorkspacesByWorkspaceIdMembersByMemberIdRoleResponse,
} from './zod.gen'
export const get = oc
@@ -168,14 +168,14 @@ export const get5 = oc
.route({
inputStructure: 'detailed',
method: 'GET',
- operationId: 'getAppsByAppIdCheckDependencies',
- path: '/apps/{app_id}/check-dependencies',
+ operationId: 'getAppsByAppIdDependencies',
+ path: '/apps/{app_id}/dependencies',
tags: ['openapi'],
})
- .input(z.object({ params: zGetAppsByAppIdCheckDependenciesPath }))
- .output(zGetAppsByAppIdCheckDependenciesResponse)
+ .input(z.object({ params: zGetAppsByAppIdDependenciesPath }))
+ .output(zGetAppsByAppIdDependenciesResponse)
-export const checkDependencies = {
+export const dependencies = {
get: get5,
}
@@ -183,39 +183,17 @@ export const get6 = oc
.route({
inputStructure: 'detailed',
method: 'GET',
- operationId: 'getAppsByAppIdDescribe',
- path: '/apps/{app_id}/describe',
+ operationId: 'getAppsByAppIdDsl',
+ path: '/apps/{app_id}/dsl',
tags: ['openapi'],
})
- .input(
- z.object({
- params: zGetAppsByAppIdDescribePath,
- query: zGetAppsByAppIdDescribeQuery.optional(),
- }),
- )
- .output(zGetAppsByAppIdDescribeResponse)
+ .input(z.object({ params: zGetAppsByAppIdDslPath, query: zGetAppsByAppIdDslQuery.optional() }))
+ .output(zGetAppsByAppIdDslResponse)
-export const describe = {
+export const dsl = {
get: get6,
}
-export const get7 = oc
- .route({
- inputStructure: 'detailed',
- method: 'GET',
- operationId: 'getAppsByAppIdExport',
- path: '/apps/{app_id}/export',
- tags: ['openapi'],
- })
- .input(
- z.object({ params: zGetAppsByAppIdExportPath, query: zGetAppsByAppIdExportQuery.optional() }),
- )
- .output(zGetAppsByAppIdExportResponse)
-
-export const export_ = {
- get: get7,
-}
-
/**
* Upload a file to use as an input variable when running the app
*/
@@ -224,78 +202,59 @@ export const post = oc
description: 'Upload a file to use as an input variable when running the app',
inputStructure: 'detailed',
method: 'POST',
- operationId: 'postAppsByAppIdFilesUpload',
- path: '/apps/{app_id}/files/upload',
+ operationId: 'postAppsByAppIdFiles',
+ path: '/apps/{app_id}/files',
successStatus: 201,
tags: ['openapi'],
})
- .input(z.object({ params: zPostAppsByAppIdFilesUploadPath }))
- .output(zPostAppsByAppIdFilesUploadResponse)
-
-export const upload = {
- post,
-}
+ .input(z.object({ params: zPostAppsByAppIdFilesPath }))
+ .output(zPostAppsByAppIdFilesResponse)
export const files = {
- upload,
+ post,
}
-export const get8 = oc
- .route({
- inputStructure: 'detailed',
- method: 'GET',
- operationId: 'getAppsByAppIdFormHumanInputByFormToken',
- path: '/apps/{app_id}/form/human_input/{form_token}',
- tags: ['openapi'],
- })
- .input(z.object({ params: zGetAppsByAppIdFormHumanInputByFormTokenPath }))
- .output(zGetAppsByAppIdFormHumanInputByFormTokenResponse)
-
export const post2 = oc
.route({
inputStructure: 'detailed',
method: 'POST',
- operationId: 'postAppsByAppIdFormHumanInputByFormToken',
- path: '/apps/{app_id}/form/human_input/{form_token}',
+ operationId: 'postAppsByAppIdHumanInputFormsByFormTokenSubmit',
+ path: '/apps/{app_id}/human-input-forms/{form_token}:submit',
tags: ['openapi'],
})
.input(
z.object({
- body: zPostAppsByAppIdFormHumanInputByFormTokenBody,
- params: zPostAppsByAppIdFormHumanInputByFormTokenPath,
+ body: zPostAppsByAppIdHumanInputFormsByFormTokenSubmitBody,
+ params: zPostAppsByAppIdHumanInputFormsByFormTokenSubmitPath,
}),
)
- .output(zPostAppsByAppIdFormHumanInputByFormTokenResponse)
+ .output(zPostAppsByAppIdHumanInputFormsByFormTokenSubmitResponse)
-export const byFormToken = {
- get: get8,
+export const submit = {
post: post2,
}
-export const humanInput = {
+export const get7 = oc
+ .route({
+ inputStructure: 'detailed',
+ method: 'GET',
+ operationId: 'getAppsByAppIdHumanInputFormsByFormToken',
+ path: '/apps/{app_id}/human-input-forms/{form_token}',
+ tags: ['openapi'],
+ })
+ .input(z.object({ params: zGetAppsByAppIdHumanInputFormsByFormTokenPath }))
+ .output(zGetAppsByAppIdHumanInputFormsByFormTokenResponse)
+
+export const byFormToken = {
+ get: get7,
+ submit,
+}
+
+export const humanInputForms = {
byFormToken,
}
-export const form = {
- humanInput,
-}
-
-export const post3 = oc
- .route({
- inputStructure: 'detailed',
- method: 'POST',
- operationId: 'postAppsByAppIdRun',
- path: '/apps/{app_id}/run',
- tags: ['openapi'],
- })
- .input(z.object({ body: zPostAppsByAppIdRunBody, params: zPostAppsByAppIdRunPath }))
- .output(zPostAppsByAppIdRunResponse)
-
-export const run = {
- post: post3,
-}
-
-export const get9 = oc
+export const get8 = oc
.route({
inputStructure: 'detailed',
method: 'GET',
@@ -312,22 +271,22 @@ export const get9 = oc
.output(zGetAppsByAppIdTasksByTaskIdEventsResponse)
export const events = {
- get: get9,
+ get: get8,
}
-export const post4 = oc
+export const post3 = oc
.route({
inputStructure: 'detailed',
method: 'POST',
operationId: 'postAppsByAppIdTasksByTaskIdStop',
- path: '/apps/{app_id}/tasks/{task_id}/stop',
+ path: '/apps/{app_id}/tasks/{task_id}:stop',
tags: ['openapi'],
})
.input(z.object({ params: zPostAppsByAppIdTasksByTaskIdStopPath }))
.output(zPostAppsByAppIdTasksByTaskIdStopResponse)
export const stop = {
- post: post4,
+ post: post3,
}
export const byTaskId = {
@@ -339,14 +298,40 @@ export const tasks = {
byTaskId,
}
+export const post4 = oc
+ .route({
+ inputStructure: 'detailed',
+ method: 'POST',
+ operationId: 'postAppsByAppIdRun',
+ path: '/apps/{app_id}:run',
+ tags: ['openapi'],
+ })
+ .input(z.object({ body: zPostAppsByAppIdRunBody, params: zPostAppsByAppIdRunPath }))
+ .output(zPostAppsByAppIdRunResponse)
+
+export const run = {
+ post: post4,
+}
+
+export const get9 = oc
+ .route({
+ inputStructure: 'detailed',
+ method: 'GET',
+ operationId: 'getAppsByAppId',
+ path: '/apps/{app_id}',
+ tags: ['openapi'],
+ })
+ .input(z.object({ params: zGetAppsByAppIdPath, query: zGetAppsByAppIdQuery.optional() }))
+ .output(zGetAppsByAppIdResponse)
+
export const byAppId = {
- checkDependencies,
- describe,
- export: export_,
+ get: get9,
+ dependencies,
+ dsl,
files,
- form,
- run,
+ humanInputForms,
tasks,
+ run,
}
export const get10 = oc
@@ -456,24 +441,20 @@ export const get12 = oc
.route({
inputStructure: 'detailed',
method: 'GET',
- operationId: 'getPermittedExternalAppsByAppIdDescribe',
- path: '/permitted-external-apps/{app_id}/describe',
+ operationId: 'getPermittedExternalAppsByAppId',
+ path: '/permitted-external-apps/{app_id}',
tags: ['openapi'],
})
.input(
z.object({
- params: zGetPermittedExternalAppsByAppIdDescribePath,
- query: zGetPermittedExternalAppsByAppIdDescribeQuery.optional(),
+ params: zGetPermittedExternalAppsByAppIdPath,
+ query: zGetPermittedExternalAppsByAppIdQuery.optional(),
}),
)
- .output(zGetPermittedExternalAppsByAppIdDescribeResponse)
-
-export const describe2 = {
- get: get12,
-}
+ .output(zGetPermittedExternalAppsByAppIdResponse)
export const byAppId2 = {
- describe: describe2,
+ get: get12,
}
export const get13 = oc
@@ -497,7 +478,7 @@ export const post9 = oc
inputStructure: 'detailed',
method: 'POST',
operationId: 'postWorkspacesByWorkspaceIdAppsImportsByImportIdConfirm',
- path: '/workspaces/{workspace_id}/apps/imports/{import_id}/confirm',
+ path: '/workspaces/{workspace_id}/apps/imports/{import_id}:confirm',
tags: ['openapi'],
})
.input(z.object({ params: zPostWorkspacesByWorkspaceIdAppsImportsByImportIdConfirmPath }))
@@ -536,26 +517,6 @@ export const apps2 = {
imports,
}
-export const put = oc
- .route({
- inputStructure: 'detailed',
- method: 'PUT',
- operationId: 'putWorkspacesByWorkspaceIdMembersByMemberIdRole',
- path: '/workspaces/{workspace_id}/members/{member_id}/role',
- tags: ['openapi'],
- })
- .input(
- z.object({
- body: zPutWorkspacesByWorkspaceIdMembersByMemberIdRoleBody,
- params: zPutWorkspacesByWorkspaceIdMembersByMemberIdRolePath,
- }),
- )
- .output(zPutWorkspacesByWorkspaceIdMembersByMemberIdRoleResponse)
-
-export const role = {
- put,
-}
-
export const delete3 = oc
.route({
inputStructure: 'detailed',
@@ -567,9 +528,25 @@ export const delete3 = oc
.input(z.object({ params: zDeleteWorkspacesByWorkspaceIdMembersByMemberIdPath }))
.output(zDeleteWorkspacesByWorkspaceIdMembersByMemberIdResponse)
+export const patch = oc
+ .route({
+ inputStructure: 'detailed',
+ method: 'PATCH',
+ operationId: 'patchWorkspacesByWorkspaceIdMembersByMemberId',
+ path: '/workspaces/{workspace_id}/members/{member_id}',
+ tags: ['openapi'],
+ })
+ .input(
+ z.object({
+ body: zPatchWorkspacesByWorkspaceIdMembersByMemberIdBody,
+ params: zPatchWorkspacesByWorkspaceIdMembersByMemberIdPath,
+ }),
+ )
+ .output(zPatchWorkspacesByWorkspaceIdMembersByMemberIdResponse)
+
export const byMemberId = {
delete: delete3,
- role,
+ patch,
}
export const get14 = oc
@@ -616,7 +593,7 @@ export const post12 = oc
inputStructure: 'detailed',
method: 'POST',
operationId: 'postWorkspacesByWorkspaceIdSwitch',
- path: '/workspaces/{workspace_id}/switch',
+ path: '/workspaces/{workspace_id}:switch',
tags: ['openapi'],
})
.input(z.object({ params: zPostWorkspacesByWorkspaceIdSwitchPath }))
diff --git a/packages/contracts/generated/api/openapi/types.gen.ts b/packages/contracts/generated/api/openapi/types.gen.ts
index cd422cd1f92..fd0a7545afd 100644
--- a/packages/contracts/generated/api/openapi/types.gen.ts
+++ b/packages/contracts/generated/api/openapi/types.gen.ts
@@ -617,30 +617,7 @@ export type GetAppsResponses = {
export type GetAppsResponse = GetAppsResponses[keyof GetAppsResponses]
-export type GetAppsByAppIdCheckDependenciesData = {
- body?: never
- path: {
- app_id: string
- }
- query?: never
- url: '/apps/{app_id}/check-dependencies'
-}
-
-export type GetAppsByAppIdCheckDependenciesErrors = {
- default: ErrorBody
-}
-
-export type GetAppsByAppIdCheckDependenciesError
- = GetAppsByAppIdCheckDependenciesErrors[keyof GetAppsByAppIdCheckDependenciesErrors]
-
-export type GetAppsByAppIdCheckDependenciesResponses = {
- 200: CheckDependenciesResult
-}
-
-export type GetAppsByAppIdCheckDependenciesResponse
- = GetAppsByAppIdCheckDependenciesResponses[keyof GetAppsByAppIdCheckDependenciesResponses]
-
-export type GetAppsByAppIdDescribeData = {
+export type GetAppsByAppIdData = {
body?: never
path: {
app_id: string
@@ -648,25 +625,46 @@ export type GetAppsByAppIdDescribeData = {
query?: {
fields?: string
}
- url: '/apps/{app_id}/describe'
+ url: '/apps/{app_id}'
}
-export type GetAppsByAppIdDescribeErrors = {
+export type GetAppsByAppIdErrors = {
422: ErrorBody
default: ErrorBody
}
-export type GetAppsByAppIdDescribeError
- = GetAppsByAppIdDescribeErrors[keyof GetAppsByAppIdDescribeErrors]
+export type GetAppsByAppIdError = GetAppsByAppIdErrors[keyof GetAppsByAppIdErrors]
-export type GetAppsByAppIdDescribeResponses = {
+export type GetAppsByAppIdResponses = {
200: AppDescribeResponse
}
-export type GetAppsByAppIdDescribeResponse
- = GetAppsByAppIdDescribeResponses[keyof GetAppsByAppIdDescribeResponses]
+export type GetAppsByAppIdResponse = GetAppsByAppIdResponses[keyof GetAppsByAppIdResponses]
-export type GetAppsByAppIdExportData = {
+export type GetAppsByAppIdDependenciesData = {
+ body?: never
+ path: {
+ app_id: string
+ }
+ query?: never
+ url: '/apps/{app_id}/dependencies'
+}
+
+export type GetAppsByAppIdDependenciesErrors = {
+ default: ErrorBody
+}
+
+export type GetAppsByAppIdDependenciesError
+ = GetAppsByAppIdDependenciesErrors[keyof GetAppsByAppIdDependenciesErrors]
+
+export type GetAppsByAppIdDependenciesResponses = {
+ 200: CheckDependenciesResult
+}
+
+export type GetAppsByAppIdDependenciesResponse
+ = GetAppsByAppIdDependenciesResponses[keyof GetAppsByAppIdDependenciesResponses]
+
+export type GetAppsByAppIdDslData = {
body?: never
path: {
app_id: string
@@ -675,33 +673,32 @@ export type GetAppsByAppIdExportData = {
include_secret?: boolean
workflow_id?: string
}
- url: '/apps/{app_id}/export'
+ url: '/apps/{app_id}/dsl'
}
-export type GetAppsByAppIdExportErrors = {
+export type GetAppsByAppIdDslErrors = {
422: ErrorBody
default: ErrorBody
}
-export type GetAppsByAppIdExportError = GetAppsByAppIdExportErrors[keyof GetAppsByAppIdExportErrors]
+export type GetAppsByAppIdDslError = GetAppsByAppIdDslErrors[keyof GetAppsByAppIdDslErrors]
-export type GetAppsByAppIdExportResponses = {
+export type GetAppsByAppIdDslResponses = {
200: AppDslExportResponse
}
-export type GetAppsByAppIdExportResponse
- = GetAppsByAppIdExportResponses[keyof GetAppsByAppIdExportResponses]
+export type GetAppsByAppIdDslResponse = GetAppsByAppIdDslResponses[keyof GetAppsByAppIdDslResponses]
-export type PostAppsByAppIdFilesUploadData = {
+export type PostAppsByAppIdFilesData = {
body?: never
path: {
app_id: string
}
query?: never
- url: '/apps/{app_id}/files/upload'
+ url: '/apps/{app_id}/files'
}
-export type PostAppsByAppIdFilesUploadErrors = {
+export type PostAppsByAppIdFilesErrors = {
400: unknown
401: unknown
413: unknown
@@ -709,79 +706,56 @@ export type PostAppsByAppIdFilesUploadErrors = {
default: ErrorBody
}
-export type PostAppsByAppIdFilesUploadError
- = PostAppsByAppIdFilesUploadErrors[keyof PostAppsByAppIdFilesUploadErrors]
+export type PostAppsByAppIdFilesError = PostAppsByAppIdFilesErrors[keyof PostAppsByAppIdFilesErrors]
-export type PostAppsByAppIdFilesUploadResponses = {
+export type PostAppsByAppIdFilesResponses = {
201: FileResponse
}
-export type PostAppsByAppIdFilesUploadResponse
- = PostAppsByAppIdFilesUploadResponses[keyof PostAppsByAppIdFilesUploadResponses]
+export type PostAppsByAppIdFilesResponse
+ = PostAppsByAppIdFilesResponses[keyof PostAppsByAppIdFilesResponses]
-export type GetAppsByAppIdFormHumanInputByFormTokenData = {
+export type GetAppsByAppIdHumanInputFormsByFormTokenData = {
body?: never
path: {
app_id: string
form_token: string
}
query?: never
- url: '/apps/{app_id}/form/human_input/{form_token}'
+ url: '/apps/{app_id}/human-input-forms/{form_token}'
}
-export type GetAppsByAppIdFormHumanInputByFormTokenResponses = {
+export type GetAppsByAppIdHumanInputFormsByFormTokenResponses = {
200: HumanInputFormDefinitionResponse
}
-export type GetAppsByAppIdFormHumanInputByFormTokenResponse
- = GetAppsByAppIdFormHumanInputByFormTokenResponses[keyof GetAppsByAppIdFormHumanInputByFormTokenResponses]
+export type GetAppsByAppIdHumanInputFormsByFormTokenResponse
+ = GetAppsByAppIdHumanInputFormsByFormTokenResponses[keyof GetAppsByAppIdHumanInputFormsByFormTokenResponses]
-export type PostAppsByAppIdFormHumanInputByFormTokenData = {
+export type PostAppsByAppIdHumanInputFormsByFormTokenSubmitData = {
body: HumanInputFormSubmitPayload
path: {
app_id: string
form_token: string
}
query?: never
- url: '/apps/{app_id}/form/human_input/{form_token}'
+ url: '/apps/{app_id}/human-input-forms/{form_token}:submit'
}
-export type PostAppsByAppIdFormHumanInputByFormTokenErrors = {
+export type PostAppsByAppIdHumanInputFormsByFormTokenSubmitErrors = {
422: ErrorBody
default: ErrorBody
}
-export type PostAppsByAppIdFormHumanInputByFormTokenError
- = PostAppsByAppIdFormHumanInputByFormTokenErrors[keyof PostAppsByAppIdFormHumanInputByFormTokenErrors]
+export type PostAppsByAppIdHumanInputFormsByFormTokenSubmitError
+ = PostAppsByAppIdHumanInputFormsByFormTokenSubmitErrors[keyof PostAppsByAppIdHumanInputFormsByFormTokenSubmitErrors]
-export type PostAppsByAppIdFormHumanInputByFormTokenResponses = {
+export type PostAppsByAppIdHumanInputFormsByFormTokenSubmitResponses = {
200: FormSubmitResponse
}
-export type PostAppsByAppIdFormHumanInputByFormTokenResponse
- = PostAppsByAppIdFormHumanInputByFormTokenResponses[keyof PostAppsByAppIdFormHumanInputByFormTokenResponses]
-
-export type PostAppsByAppIdRunData = {
- body: AppRunRequest
- path: {
- app_id: string
- }
- query?: never
- url: '/apps/{app_id}/run'
-}
-
-export type PostAppsByAppIdRunErrors = {
- 422: ErrorBody
-}
-
-export type PostAppsByAppIdRunError = PostAppsByAppIdRunErrors[keyof PostAppsByAppIdRunErrors]
-
-export type PostAppsByAppIdRunResponses = {
- 200: EventStreamResponse
-}
-
-export type PostAppsByAppIdRunResponse
- = PostAppsByAppIdRunResponses[keyof PostAppsByAppIdRunResponses]
+export type PostAppsByAppIdHumanInputFormsByFormTokenSubmitResponse
+ = PostAppsByAppIdHumanInputFormsByFormTokenSubmitResponses[keyof PostAppsByAppIdHumanInputFormsByFormTokenSubmitResponses]
export type GetAppsByAppIdTasksByTaskIdEventsData = {
body?: never
@@ -810,7 +784,7 @@ export type PostAppsByAppIdTasksByTaskIdStopData = {
task_id: string
}
query?: never
- url: '/apps/{app_id}/tasks/{task_id}/stop'
+ url: '/apps/{app_id}/tasks/{task_id}:stop'
}
export type PostAppsByAppIdTasksByTaskIdStopErrors = {
@@ -827,6 +801,28 @@ export type PostAppsByAppIdTasksByTaskIdStopResponses = {
export type PostAppsByAppIdTasksByTaskIdStopResponse
= PostAppsByAppIdTasksByTaskIdStopResponses[keyof PostAppsByAppIdTasksByTaskIdStopResponses]
+export type PostAppsByAppIdRunData = {
+ body: AppRunRequest
+ path: {
+ app_id: string
+ }
+ query?: never
+ url: '/apps/{app_id}:run'
+}
+
+export type PostAppsByAppIdRunErrors = {
+ 422: ErrorBody
+}
+
+export type PostAppsByAppIdRunError = PostAppsByAppIdRunErrors[keyof PostAppsByAppIdRunErrors]
+
+export type PostAppsByAppIdRunResponses = {
+ 200: EventStreamResponse
+}
+
+export type PostAppsByAppIdRunResponse
+ = PostAppsByAppIdRunResponses[keyof PostAppsByAppIdRunResponses]
+
export type PostOauthDeviceApproveData = {
body: DeviceMutateRequest
path?: never
@@ -926,7 +922,7 @@ export type GetPermittedExternalAppsResponses = {
export type GetPermittedExternalAppsResponse
= GetPermittedExternalAppsResponses[keyof GetPermittedExternalAppsResponses]
-export type GetPermittedExternalAppsByAppIdDescribeData = {
+export type GetPermittedExternalAppsByAppIdData = {
body?: never
path: {
app_id: string
@@ -934,23 +930,23 @@ export type GetPermittedExternalAppsByAppIdDescribeData = {
query?: {
fields?: string
}
- url: '/permitted-external-apps/{app_id}/describe'
+ url: '/permitted-external-apps/{app_id}'
}
-export type GetPermittedExternalAppsByAppIdDescribeErrors = {
+export type GetPermittedExternalAppsByAppIdErrors = {
422: ErrorBody
default: ErrorBody
}
-export type GetPermittedExternalAppsByAppIdDescribeError
- = GetPermittedExternalAppsByAppIdDescribeErrors[keyof GetPermittedExternalAppsByAppIdDescribeErrors]
+export type GetPermittedExternalAppsByAppIdError
+ = GetPermittedExternalAppsByAppIdErrors[keyof GetPermittedExternalAppsByAppIdErrors]
-export type GetPermittedExternalAppsByAppIdDescribeResponses = {
+export type GetPermittedExternalAppsByAppIdResponses = {
200: AppDescribeResponse
}
-export type GetPermittedExternalAppsByAppIdDescribeResponse
- = GetPermittedExternalAppsByAppIdDescribeResponses[keyof GetPermittedExternalAppsByAppIdDescribeResponses]
+export type GetPermittedExternalAppsByAppIdResponse
+ = GetPermittedExternalAppsByAppIdResponses[keyof GetPermittedExternalAppsByAppIdResponses]
export type GetWorkspacesData = {
body?: never
@@ -1027,7 +1023,7 @@ export type PostWorkspacesByWorkspaceIdAppsImportsByImportIdConfirmData = {
workspace_id: string
}
query?: never
- url: '/workspaces/{workspace_id}/apps/imports/{import_id}/confirm'
+ url: '/workspaces/{workspace_id}/apps/imports/{import_id}:confirm'
}
export type PostWorkspacesByWorkspaceIdAppsImportsByImportIdConfirmErrors = {
@@ -1120,30 +1116,30 @@ export type DeleteWorkspacesByWorkspaceIdMembersByMemberIdResponses = {
export type DeleteWorkspacesByWorkspaceIdMembersByMemberIdResponse
= DeleteWorkspacesByWorkspaceIdMembersByMemberIdResponses[keyof DeleteWorkspacesByWorkspaceIdMembersByMemberIdResponses]
-export type PutWorkspacesByWorkspaceIdMembersByMemberIdRoleData = {
+export type PatchWorkspacesByWorkspaceIdMembersByMemberIdData = {
body: MemberRoleUpdatePayload
path: {
member_id: string
workspace_id: string
}
query?: never
- url: '/workspaces/{workspace_id}/members/{member_id}/role'
+ url: '/workspaces/{workspace_id}/members/{member_id}'
}
-export type PutWorkspacesByWorkspaceIdMembersByMemberIdRoleErrors = {
+export type PatchWorkspacesByWorkspaceIdMembersByMemberIdErrors = {
422: ErrorBody
default: ErrorBody
}
-export type PutWorkspacesByWorkspaceIdMembersByMemberIdRoleError
- = PutWorkspacesByWorkspaceIdMembersByMemberIdRoleErrors[keyof PutWorkspacesByWorkspaceIdMembersByMemberIdRoleErrors]
+export type PatchWorkspacesByWorkspaceIdMembersByMemberIdError
+ = PatchWorkspacesByWorkspaceIdMembersByMemberIdErrors[keyof PatchWorkspacesByWorkspaceIdMembersByMemberIdErrors]
-export type PutWorkspacesByWorkspaceIdMembersByMemberIdRoleResponses = {
+export type PatchWorkspacesByWorkspaceIdMembersByMemberIdResponses = {
200: MemberActionResponse
}
-export type PutWorkspacesByWorkspaceIdMembersByMemberIdRoleResponse
- = PutWorkspacesByWorkspaceIdMembersByMemberIdRoleResponses[keyof PutWorkspacesByWorkspaceIdMembersByMemberIdRoleResponses]
+export type PatchWorkspacesByWorkspaceIdMembersByMemberIdResponse
+ = PatchWorkspacesByWorkspaceIdMembersByMemberIdResponses[keyof PatchWorkspacesByWorkspaceIdMembersByMemberIdResponses]
export type PostWorkspacesByWorkspaceIdSwitchData = {
body?: never
@@ -1151,7 +1147,7 @@ export type PostWorkspacesByWorkspaceIdSwitchData = {
workspace_id: string
}
query?: never
- url: '/workspaces/{workspace_id}/switch'
+ url: '/workspaces/{workspace_id}:switch'
}
export type PostWorkspacesByWorkspaceIdSwitchErrors = {
diff --git a/packages/contracts/generated/api/openapi/zod.gen.ts b/packages/contracts/generated/api/openapi/zod.gen.ts
index 70ece880a68..0594a061547 100644
--- a/packages/contracts/generated/api/openapi/zod.gen.ts
+++ b/packages/contracts/generated/api/openapi/zod.gen.ts
@@ -27,7 +27,7 @@ export const zAppDescribeInfo = z.object({
/**
* AppDescribeQuery
*
- * `?fields=` allow-list for GET /apps//describe.
+ * `?fields=` allow-list for GET /apps/.
*
* Empty / omitted → all blocks. Unknown member → ValidationError → 422.
*/
@@ -47,7 +47,7 @@ export const zAppDescribeResponse = z.object({
/**
* AppDslExportQuery
*
- * Query parameters for GET /apps//export.
+ * Query parameters for GET /apps//dsl.
*/
export const zAppDslExportQuery = z.object({
include_secret: z.boolean().optional().default(false),
@@ -254,7 +254,7 @@ export const zFileResponse = z.object({
/**
* FormSubmitResponse
*
- * Empty 200 body for POST /apps//form/human_input/. `extra='forbid'`
+ * Empty 200 body for POST /apps//human-input-forms/:submit. `extra='forbid'`
* pins `additionalProperties: false` so the generated contract is an exact `{}` rather
* than an under-annotated open object.
*/
@@ -581,7 +581,7 @@ export const zPermittedExternalAppsListQuery = z.object({
/**
* TaskStopResponse
*
- * 200 body for POST /apps//tasks//stop. The handler always returns
+ * 200 body for POST /apps//tasks/:stop. The handler always returns
* {"result": "success"}, so `result` is required (no default) — the generated contract
* types it as a required `'success'` rather than an optional field.
*/
@@ -740,33 +740,33 @@ export const zGetAppsQuery = z.object({
*/
export const zGetAppsResponse = zAppListResponse
-export const zGetAppsByAppIdCheckDependenciesPath = z.object({
+export const zGetAppsByAppIdPath = z.object({
app_id: z.string(),
})
-/**
- * Dependencies checked
- */
-export const zGetAppsByAppIdCheckDependenciesResponse = zCheckDependenciesResult
-
-export const zGetAppsByAppIdDescribePath = z.object({
- app_id: z.string(),
-})
-
-export const zGetAppsByAppIdDescribeQuery = z.object({
+export const zGetAppsByAppIdQuery = z.object({
fields: z.string().optional(),
})
/**
* App description
*/
-export const zGetAppsByAppIdDescribeResponse = zAppDescribeResponse
+export const zGetAppsByAppIdResponse = zAppDescribeResponse
-export const zGetAppsByAppIdExportPath = z.object({
+export const zGetAppsByAppIdDependenciesPath = z.object({
app_id: z.string(),
})
-export const zGetAppsByAppIdExportQuery = z.object({
+/**
+ * Dependencies checked
+ */
+export const zGetAppsByAppIdDependenciesResponse = zCheckDependenciesResult
+
+export const zGetAppsByAppIdDslPath = z.object({
+ app_id: z.string(),
+})
+
+export const zGetAppsByAppIdDslQuery = z.object({
include_secret: z.boolean().optional().default(false),
workflow_id: z.string().optional(),
})
@@ -774,18 +774,18 @@ export const zGetAppsByAppIdExportQuery = z.object({
/**
* Export successful
*/
-export const zGetAppsByAppIdExportResponse = zAppDslExportResponse
+export const zGetAppsByAppIdDslResponse = zAppDslExportResponse
-export const zPostAppsByAppIdFilesUploadPath = z.object({
+export const zPostAppsByAppIdFilesPath = z.object({
app_id: z.string(),
})
/**
* File uploaded successfully
*/
-export const zPostAppsByAppIdFilesUploadResponse = zFileResponse
+export const zPostAppsByAppIdFilesResponse = zFileResponse
-export const zGetAppsByAppIdFormHumanInputByFormTokenPath = z.object({
+export const zGetAppsByAppIdHumanInputFormsByFormTokenPath = z.object({
app_id: z.string(),
form_token: z.string(),
})
@@ -793,11 +793,11 @@ export const zGetAppsByAppIdFormHumanInputByFormTokenPath = z.object({
/**
* Form definition
*/
-export const zGetAppsByAppIdFormHumanInputByFormTokenResponse = zHumanInputFormDefinitionResponse
+export const zGetAppsByAppIdHumanInputFormsByFormTokenResponse = zHumanInputFormDefinitionResponse
-export const zPostAppsByAppIdFormHumanInputByFormTokenBody = zHumanInputFormSubmitPayload
+export const zPostAppsByAppIdHumanInputFormsByFormTokenSubmitBody = zHumanInputFormSubmitPayload
-export const zPostAppsByAppIdFormHumanInputByFormTokenPath = z.object({
+export const zPostAppsByAppIdHumanInputFormsByFormTokenSubmitPath = z.object({
app_id: z.string(),
form_token: z.string(),
})
@@ -805,18 +805,7 @@ export const zPostAppsByAppIdFormHumanInputByFormTokenPath = z.object({
/**
* Form submitted
*/
-export const zPostAppsByAppIdFormHumanInputByFormTokenResponse = zFormSubmitResponse
-
-export const zPostAppsByAppIdRunBody = zAppRunRequest
-
-export const zPostAppsByAppIdRunPath = z.object({
- app_id: z.string(),
-})
-
-/**
- * Run result (SSE stream)
- */
-export const zPostAppsByAppIdRunResponse = zEventStreamResponse
+export const zPostAppsByAppIdHumanInputFormsByFormTokenSubmitResponse = zFormSubmitResponse
export const zGetAppsByAppIdTasksByTaskIdEventsPath = z.object({
app_id: z.string(),
@@ -843,6 +832,17 @@ export const zPostAppsByAppIdTasksByTaskIdStopPath = z.object({
*/
export const zPostAppsByAppIdTasksByTaskIdStopResponse = zTaskStopResponse
+export const zPostAppsByAppIdRunBody = zAppRunRequest
+
+export const zPostAppsByAppIdRunPath = z.object({
+ app_id: z.string(),
+})
+
+/**
+ * Run result (SSE stream)
+ */
+export const zPostAppsByAppIdRunResponse = zEventStreamResponse
+
export const zPostOauthDeviceApproveBody = zDeviceMutateRequest
/**
@@ -892,18 +892,18 @@ export const zGetPermittedExternalAppsQuery = z.object({
*/
export const zGetPermittedExternalAppsResponse = zPermittedExternalAppsListResponse
-export const zGetPermittedExternalAppsByAppIdDescribePath = z.object({
+export const zGetPermittedExternalAppsByAppIdPath = z.object({
app_id: z.string(),
})
-export const zGetPermittedExternalAppsByAppIdDescribeQuery = z.object({
+export const zGetPermittedExternalAppsByAppIdQuery = z.object({
fields: z.string().optional(),
})
/**
* Permitted external app description
*/
-export const zGetPermittedExternalAppsByAppIdDescribeResponse = zAppDescribeResponse
+export const zGetPermittedExternalAppsByAppIdResponse = zAppDescribeResponse
/**
* Workspace list
@@ -975,9 +975,9 @@ export const zDeleteWorkspacesByWorkspaceIdMembersByMemberIdPath = z.object({
*/
export const zDeleteWorkspacesByWorkspaceIdMembersByMemberIdResponse = zMemberActionResponse
-export const zPutWorkspacesByWorkspaceIdMembersByMemberIdRoleBody = zMemberRoleUpdatePayload
+export const zPatchWorkspacesByWorkspaceIdMembersByMemberIdBody = zMemberRoleUpdatePayload
-export const zPutWorkspacesByWorkspaceIdMembersByMemberIdRolePath = z.object({
+export const zPatchWorkspacesByWorkspaceIdMembersByMemberIdPath = z.object({
member_id: z.string(),
workspace_id: z.string(),
})
@@ -985,7 +985,7 @@ export const zPutWorkspacesByWorkspaceIdMembersByMemberIdRolePath = z.object({
/**
* Role updated
*/
-export const zPutWorkspacesByWorkspaceIdMembersByMemberIdRoleResponse = zMemberActionResponse
+export const zPatchWorkspacesByWorkspaceIdMembersByMemberIdResponse = zMemberActionResponse
export const zPostWorkspacesByWorkspaceIdSwitchPath = z.object({
workspace_id: z.string(),
diff --git a/packages/contracts/openapi-ts.api.config.ts b/packages/contracts/openapi-ts.api.config.ts
index efb1a226f1e..0fb424bcfb5 100644
--- a/packages/contracts/openapi-ts.api.config.ts
+++ b/packages/contracts/openapi-ts.api.config.ts
@@ -102,11 +102,11 @@ const segmentWords = (segment: string) => {
return toWords(segment)
}
+// Split on `:` too so custom methods nest as their own node (apps.byAppId.run), not apps.appIdRun.
+const routeNamingSegments = (routePath: string) => routePath.split(/[/:]/).filter(Boolean)
+
const routeWords = (routePath: string) => {
- return routePath
- .split('/')
- .filter(Boolean)
- .flatMap(segmentWords)
+ return routeNamingSegments(routePath).flatMap(segmentWords)
}
const operationId = (method: string, routePath: string) => {
@@ -114,10 +114,7 @@ const operationId = (method: string, routePath: string) => {
}
const contractPathSegments = (operation: ApiContractOperation) => {
- const segments = operation.path
- .split('/')
- .filter(Boolean)
- .map(segment => toCamelCase(segmentWords(segment)))
+ const segments = routeNamingSegments(operation.path).map(segment => toCamelCase(segmentWords(segment)))
return [...(segments.length > 0 ? segments : ['root']), operation.method.toLowerCase()]
}