@adobe/spacecat-shared-project-engine-client 1.12.0 → 1.13.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@adobe/spacecat-shared-project-engine-client",
3
- "version": "1.12.0",
3
+ "version": "1.13.0",
4
4
  "description": "Shared modules of the Spacecat Services - Semrush Project Engine client and generated types",
5
5
  "type": "module",
6
6
  "main": "src/index.js",
package/src/index.d.ts CHANGED
@@ -10,7 +10,8 @@
10
10
  * governing permissions and limitations under the License.
11
11
  */
12
12
 
13
- import type { Client } from 'openapi-fetch';
13
+ import type { Client, FetchResponse, MaybeOptionalInit, MediaType } from 'openapi-fetch';
14
+ import type { RequiredKeysOf } from 'openapi-typescript-helpers';
14
15
  import type { paths, components } from './generated/types.js';
15
16
 
16
17
  /** Supplies the caller's IMS JWT — forwarded verbatim, never minted or exchanged. */
@@ -73,5 +74,284 @@ export declare function createSerenityProjectEngineApiClient(
73
74
  options: SerenityProjectEngineApiClientOptions,
74
75
  ): SerenityProjectEngineApiClient;
75
76
 
77
+ // ───────────────────────────────────────────────────────────────────────────
78
+ // Intent-named facade (transport) over the raw client.
79
+ //
80
+ // The three helpers below derive every facade method's parameter and return type
81
+ // straight from the generated `paths` contract, so the surface stays strictly
82
+ // in-spec and never degrades to `any`. They are internal to this declaration.
83
+ // ───────────────────────────────────────────────────────────────────────────
84
+
85
+ /**
86
+ * The openapi-fetch `init` argument (params.path/query, body) accepted for a given
87
+ * path `P` + HTTP method `M`, derived from the generated contract.
88
+ */
89
+ type TransportInit<P extends keyof paths, M extends keyof paths[P]> = MaybeOptionalInit<
90
+ paths[P],
91
+ M
92
+ >;
93
+
94
+ /**
95
+ * Mirror of openapi-fetch's own (unexported) `InitParam`: the `init` argument is
96
+ * OPTIONAL when nothing in it is required (no path/query params, no required body),
97
+ * and REQUIRED otherwise — so `listLanguages()` needs no argument while
98
+ * `createProject({ params, body })` enforces its params + body at the call site.
99
+ */
100
+ type TransportInitParam<Init> = RequiredKeysOf<Init> extends never
101
+ ? [init?: Init]
102
+ : [init: Init];
103
+
104
+ /**
105
+ * The value a facade method resolves with: the parsed 2xx body for path `P` +
106
+ * method `M`, or `null` for an empty body (e.g. a 204 / empty-body ack). Non-2xx
107
+ * responses never resolve — they throw at the single `unwrap` error seam.
108
+ */
109
+ type TransportData<P extends keyof paths, M extends keyof paths[P]> =
110
+ | NonNullable<FetchResponse<paths[P][M], TransportInit<P, M>, MediaType>['data']>
111
+ | null;
112
+
113
+ /**
114
+ * Intent-named facade over {@link SerenityProjectEngineApiClient}. Wraps the 28 in-spec
115
+ * Project Engine operations spacecat-api-service consumes behind verb+resource methods, so
116
+ * consumers depend on this seam rather than the raw client's literal path strings. Each method
117
+ * is THIN: it forwards the caller's openapi-fetch `init` to the underlying client and resolves
118
+ * with the unwrapped 2xx body (or throws on a non-2xx / network error at a single seam). No
119
+ * caching, redaction, error→HTTP translation, or composite methods — all consumer-owned per
120
+ * ADR-0001. The remaining generated operations stay reachable via the raw client.
121
+ */
122
+ export interface SerenityProjectEngineTransport {
123
+ /** GET /v1/languages — projects-admin-list-languages */
124
+ listLanguages(
125
+ ...init: TransportInitParam<TransportInit<'/v1/languages', 'get'>>
126
+ ): Promise<TransportData<'/v1/languages', 'get'>>;
127
+ /** GET /v1/ai_models — ai-list-global-models */
128
+ listGlobalAiModels(
129
+ ...init: TransportInitParam<TransportInit<'/v1/ai_models', 'get'>>
130
+ ): Promise<TransportData<'/v1/ai_models', 'get'>>;
131
+
132
+ /** GET /v1/workspaces/{id}/projects — projects-list-projects */
133
+ listProjects(
134
+ ...init: TransportInitParam<TransportInit<'/v1/workspaces/{id}/projects', 'get'>>
135
+ ): Promise<TransportData<'/v1/workspaces/{id}/projects', 'get'>>;
136
+ /** POST /v1/workspaces/{id}/projects — projects-post-project */
137
+ createProject(
138
+ ...init: TransportInitParam<TransportInit<'/v1/workspaces/{id}/projects', 'post'>>
139
+ ): Promise<TransportData<'/v1/workspaces/{id}/projects', 'post'>>;
140
+ /** GET /v1/workspaces/{id}/projects/{project_id} — projects-get-project */
141
+ getProject(
142
+ ...init: TransportInitParam<TransportInit<'/v1/workspaces/{id}/projects/{project_id}', 'get'>>
143
+ ): Promise<TransportData<'/v1/workspaces/{id}/projects/{project_id}', 'get'>>;
144
+ /** PATCH /v1/workspaces/{id}/projects/{project_id} — projects-patch-project */
145
+ updateProject(
146
+ ...init: TransportInitParam<TransportInit<'/v1/workspaces/{id}/projects/{project_id}', 'patch'>>
147
+ ): Promise<TransportData<'/v1/workspaces/{id}/projects/{project_id}', 'patch'>>;
148
+ /** DELETE /v1/workspaces/{id}/projects/{project_id} — projects-delete-project */
149
+ deleteProject(
150
+ ...init: TransportInitParam<
151
+ TransportInit<'/v1/workspaces/{id}/projects/{project_id}', 'delete'>
152
+ >
153
+ ): Promise<TransportData<'/v1/workspaces/{id}/projects/{project_id}', 'delete'>>;
154
+ /** POST /v1/workspaces/{id}/projects/{project_id}/publish — projects-publish-project */
155
+ publishProject(
156
+ ...init: TransportInitParam<
157
+ TransportInit<'/v1/workspaces/{id}/projects/{project_id}/publish', 'post'>
158
+ >
159
+ ): Promise<TransportData<'/v1/workspaces/{id}/projects/{project_id}/publish', 'post'>>;
160
+
161
+ /** GET /v1/workspaces/{id}/projects/{project_id}/ai_models — ai-list-models */
162
+ listAiModels(
163
+ ...init: TransportInitParam<
164
+ TransportInit<'/v1/workspaces/{id}/projects/{project_id}/ai_models', 'get'>
165
+ >
166
+ ): Promise<TransportData<'/v1/workspaces/{id}/projects/{project_id}/ai_models', 'get'>>;
167
+ /** DELETE /v1/workspaces/{id}/projects/{project_id}/ai_models — ai-delete-models */
168
+ deleteAiModels(
169
+ ...init: TransportInitParam<
170
+ TransportInit<'/v1/workspaces/{id}/projects/{project_id}/ai_models', 'delete'>
171
+ >
172
+ ): Promise<TransportData<'/v1/workspaces/{id}/projects/{project_id}/ai_models', 'delete'>>;
173
+ /** GET /v1/workspaces/{id}/projects/{project_id}/ai_models/benchmarks — ai-list-benchmarks */
174
+ listBenchmarks(
175
+ ...init: TransportInitParam<
176
+ TransportInit<'/v1/workspaces/{id}/projects/{project_id}/ai_models/benchmarks', 'get'>
177
+ >
178
+ ): Promise<
179
+ TransportData<'/v1/workspaces/{id}/projects/{project_id}/ai_models/benchmarks', 'get'>
180
+ >;
181
+ /** DELETE /v1/workspaces/{id}/projects/{project_id}/ai_models/benchmarks — ai-delete-benchmarks */
182
+ deleteBenchmarks(
183
+ ...init: TransportInitParam<
184
+ TransportInit<'/v1/workspaces/{id}/projects/{project_id}/ai_models/benchmarks', 'delete'>
185
+ >
186
+ ): Promise<
187
+ TransportData<'/v1/workspaces/{id}/projects/{project_id}/ai_models/benchmarks', 'delete'>
188
+ >;
189
+ /**
190
+ * PUT /v1/workspaces/{id}/projects/{project_id}/ai_models/benchmarks/{benchmark_id}
191
+ * — ai-update-benchmark
192
+ */
193
+ updateBenchmark(
194
+ ...init: TransportInitParam<
195
+ TransportInit<
196
+ '/v1/workspaces/{id}/projects/{project_id}/ai_models/benchmarks/{benchmark_id}',
197
+ 'put'
198
+ >
199
+ >
200
+ ): Promise<
201
+ TransportData<
202
+ '/v1/workspaces/{id}/projects/{project_id}/ai_models/benchmarks/{benchmark_id}',
203
+ 'put'
204
+ >
205
+ >;
206
+ /** PUT /v1/workspaces/{id}/projects/{project_id}/ci/competitors — ci-update-competitors */
207
+ updateCompetitors(
208
+ ...init: TransportInitParam<
209
+ TransportInit<'/v1/workspaces/{id}/projects/{project_id}/ci/competitors', 'put'>
210
+ >
211
+ ): Promise<TransportData<'/v1/workspaces/{id}/projects/{project_id}/ci/competitors', 'put'>>;
212
+
213
+ /** POST /v2/workspaces/{id}/projects/{project_id}/ai_models — aio-project-create-model */
214
+ createAioModel(
215
+ ...init: TransportInitParam<
216
+ TransportInit<'/v2/workspaces/{id}/projects/{project_id}/ai_models', 'post'>
217
+ >
218
+ ): Promise<TransportData<'/v2/workspaces/{id}/projects/{project_id}/ai_models', 'post'>>;
219
+ /** POST /v2/workspaces/{id}/projects/{project_id}/ai_models/benchmarks — ai-create-benchmarks-v2 */
220
+ createBenchmarks(
221
+ ...init: TransportInitParam<
222
+ TransportInit<'/v2/workspaces/{id}/projects/{project_id}/ai_models/benchmarks', 'post'>
223
+ >
224
+ ): Promise<
225
+ TransportData<'/v2/workspaces/{id}/projects/{project_id}/ai_models/benchmarks', 'post'>
226
+ >;
227
+
228
+ /**
229
+ * GET /v2/workspaces/{id}/projects/{project_id}/aio/benchmarks/{benchmark_id}/brand_urls
230
+ * — aio-list-brand-urls
231
+ */
232
+ listBrandUrls(
233
+ ...init: TransportInitParam<
234
+ TransportInit<
235
+ '/v2/workspaces/{id}/projects/{project_id}/aio/benchmarks/{benchmark_id}/brand_urls',
236
+ 'get'
237
+ >
238
+ >
239
+ ): Promise<
240
+ TransportData<
241
+ '/v2/workspaces/{id}/projects/{project_id}/aio/benchmarks/{benchmark_id}/brand_urls',
242
+ 'get'
243
+ >
244
+ >;
245
+ /**
246
+ * POST /v2/workspaces/{id}/projects/{project_id}/aio/benchmarks/{benchmark_id}/brand_urls
247
+ * — aio-create-brand-urls
248
+ */
249
+ createBrandUrls(
250
+ ...init: TransportInitParam<
251
+ TransportInit<
252
+ '/v2/workspaces/{id}/projects/{project_id}/aio/benchmarks/{benchmark_id}/brand_urls',
253
+ 'post'
254
+ >
255
+ >
256
+ ): Promise<
257
+ TransportData<
258
+ '/v2/workspaces/{id}/projects/{project_id}/aio/benchmarks/{benchmark_id}/brand_urls',
259
+ 'post'
260
+ >
261
+ >;
262
+ /**
263
+ * DELETE /v2/workspaces/{id}/projects/{project_id}/aio/benchmarks/{benchmark_id}/brand_urls
264
+ * — aio-delete-brand-urls
265
+ */
266
+ deleteBrandUrls(
267
+ ...init: TransportInitParam<
268
+ TransportInit<
269
+ '/v2/workspaces/{id}/projects/{project_id}/aio/benchmarks/{benchmark_id}/brand_urls',
270
+ 'delete'
271
+ >
272
+ >
273
+ ): Promise<
274
+ TransportData<
275
+ '/v2/workspaces/{id}/projects/{project_id}/aio/benchmarks/{benchmark_id}/brand_urls',
276
+ 'delete'
277
+ >
278
+ >;
279
+
280
+ /**
281
+ * GET /v2/workspaces/{id}/projects/{project_id}/aio/init_status
282
+ * — aio-get-project-init-status-v2
283
+ */
284
+ getProjectInitStatus(
285
+ ...init: TransportInitParam<
286
+ TransportInit<'/v2/workspaces/{id}/projects/{project_id}/aio/init_status', 'get'>
287
+ >
288
+ ): Promise<TransportData<'/v2/workspaces/{id}/projects/{project_id}/aio/init_status', 'get'>>;
289
+ /** POST /v2/workspaces/{id}/projects/{project_id}/aio/prompts — aio-create-prompt-v2 */
290
+ createPrompts(
291
+ ...init: TransportInitParam<
292
+ TransportInit<'/v2/workspaces/{id}/projects/{project_id}/aio/prompts', 'post'>
293
+ >
294
+ ): Promise<TransportData<'/v2/workspaces/{id}/projects/{project_id}/aio/prompts', 'post'>>;
295
+ /** DELETE /v2/workspaces/{id}/projects/{project_id}/aio/prompts — aio-delete-prompt-by-ids-v2 */
296
+ deletePromptsByIds(
297
+ ...init: TransportInitParam<
298
+ TransportInit<'/v2/workspaces/{id}/projects/{project_id}/aio/prompts', 'delete'>
299
+ >
300
+ ): Promise<TransportData<'/v2/workspaces/{id}/projects/{project_id}/aio/prompts', 'delete'>>;
301
+ /**
302
+ * POST /v2/workspaces/{id}/projects/{project_id}/aio/prompts/by_tags
303
+ * — aio-list-prompts-by-tag-ids
304
+ */
305
+ listPromptsByTagIds(
306
+ ...init: TransportInitParam<
307
+ TransportInit<'/v2/workspaces/{id}/projects/{project_id}/aio/prompts/by_tags', 'post'>
308
+ >
309
+ ): Promise<TransportData<'/v2/workspaces/{id}/projects/{project_id}/aio/prompts/by_tags', 'post'>>;
310
+ /** PUT /v2/workspaces/{id}/projects/{project_id}/aio/prompts/tags — aio-update-prompts-batch */
311
+ updatePromptTags(
312
+ ...init: TransportInitParam<
313
+ TransportInit<'/v2/workspaces/{id}/projects/{project_id}/aio/prompts/tags', 'put'>
314
+ >
315
+ ): Promise<TransportData<'/v2/workspaces/{id}/projects/{project_id}/aio/prompts/tags', 'put'>>;
316
+ /**
317
+ * POST /v2/workspaces/{id}/projects/{project_id}/aio/prompts/{prompt_id}/rename
318
+ * — aio-rename-prompt
319
+ */
320
+ renamePrompt(
321
+ ...init: TransportInitParam<
322
+ TransportInit<'/v2/workspaces/{id}/projects/{project_id}/aio/prompts/{prompt_id}/rename', 'post'>
323
+ >
324
+ ): Promise<
325
+ TransportData<'/v2/workspaces/{id}/projects/{project_id}/aio/prompts/{prompt_id}/rename', 'post'>
326
+ >;
327
+ /** GET /v2/workspaces/{id}/projects/{project_id}/aio/tags — aio-get-project-tags */
328
+ listProjectTags(
329
+ ...init: TransportInitParam<
330
+ TransportInit<'/v2/workspaces/{id}/projects/{project_id}/aio/tags', 'get'>
331
+ >
332
+ ): Promise<TransportData<'/v2/workspaces/{id}/projects/{project_id}/aio/tags', 'get'>>;
333
+ /** POST /v2/workspaces/{id}/projects/{project_id}/aio/tags — aio-create-project-tags */
334
+ createProjectTags(
335
+ ...init: TransportInitParam<
336
+ TransportInit<'/v2/workspaces/{id}/projects/{project_id}/aio/tags', 'post'>
337
+ >
338
+ ): Promise<TransportData<'/v2/workspaces/{id}/projects/{project_id}/aio/tags', 'post'>>;
339
+ /** PATCH /v2/workspaces/{id}/projects/{project_id}/aio/tags/{tag_id} — aio-update-tag */
340
+ updateProjectTag(
341
+ ...init: TransportInitParam<
342
+ TransportInit<'/v2/workspaces/{id}/projects/{project_id}/aio/tags/{tag_id}', 'patch'>
343
+ >
344
+ ): Promise<TransportData<'/v2/workspaces/{id}/projects/{project_id}/aio/tags/{tag_id}', 'patch'>>;
345
+ }
346
+
347
+ /**
348
+ * Builds the {@link SerenityProjectEngineTransport} facade. Takes the SAME options as
349
+ * {@link createSerenityProjectEngineApiClient} (it builds that client internally and adds no
350
+ * options of its own).
351
+ */
352
+ export declare function createSerenityProjectEngineTransport(
353
+ options: SerenityProjectEngineApiClientOptions,
354
+ ): SerenityProjectEngineTransport;
355
+
76
356
  // Re-export the generated contract types for consumers that want them directly.
77
357
  export type { paths, components };
package/src/index.js CHANGED
@@ -13,3 +13,4 @@
13
13
  // @ts-check
14
14
 
15
15
  export { createSerenityProjectEngineApiClient } from './client.js';
16
+ export { createSerenityProjectEngineTransport } from './rest-transport.js';
@@ -0,0 +1,229 @@
1
+ /*
2
+ * Copyright 2026 Adobe. All rights reserved.
3
+ * This file is licensed to you under the Apache License, Version 2.0 (the "License");
4
+ * you may not use this file except in compliance with the License. You may obtain a copy
5
+ * of the License at http://www.apache.org/licenses/LICENSE-2.0
6
+ *
7
+ * Unless required by applicable law or agreed to in writing, software distributed under
8
+ * the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS
9
+ * OF ANY KIND, either express or implied. See the License for the specific language
10
+ * governing permissions and limitations under the License.
11
+ */
12
+
13
+ // @ts-check
14
+
15
+ import { createSerenityProjectEngineApiClient } from './client.js';
16
+
17
+ /**
18
+ * @typedef {import('./client.js').SerenityProjectEngineApiClientOptions}
19
+ * SerenityProjectEngineApiClientOptions
20
+ */
21
+
22
+ /**
23
+ * Intent-named facade over the raw {@link createSerenityProjectEngineApiClient} openapi-fetch
24
+ * client. It wraps ONLY the 28 in-spec Project Engine operations that spacecat-api-service
25
+ * consumes, behind verb+resource method names, so consumers depend on this seam rather than the
26
+ * raw client and its literal path strings. Each method is THIN: it forwards the caller's
27
+ * openapi-fetch `init` (params.path/query, body) to `client.<METHOD>('<literal path>', init)` and
28
+ * routes the result through the single {@link unwrap} error seam. There is deliberately NO caching,
29
+ * redaction, error→HTTP translation, or composite/convenience method here — all consumer-owned per
30
+ * ADR-0001. The remaining generated operations stay reachable via the raw client; add a facade
31
+ * method only when a real second consumer needs one.
32
+ *
33
+ * @param {SerenityProjectEngineApiClientOptions} options The SAME options as the raw client — the
34
+ * facade adds none of its own. Builds the underlying client via
35
+ * {@link createSerenityProjectEngineApiClient}.
36
+ * @returns {import('./index.js').SerenityProjectEngineTransport}
37
+ */
38
+ export function createSerenityProjectEngineTransport(options) {
39
+ const client = createSerenityProjectEngineApiClient(options);
40
+
41
+ /**
42
+ * The SINGLE seam where a failed call becomes a throw. It awaits the openapi-fetch result
43
+ * promise here (so a network/timeout rejection also flows through this one point), and on a
44
+ * non-2xx response throws. The typed client never throws on an HTTP error — it resolves to
45
+ * `{ data, error, response }` with the parsed error body in `error` — so a non-2xx is turned
46
+ * into a throw here; a 2xx returns the parsed body (or null for an empty body).
47
+ *
48
+ * `status`, `method`, and the normalized `body` are computed locally at this site FIRST so the
49
+ * follow-up ticket LLMO-5978 can swap ONLY the `new Error(...)` line below for
50
+ * `new ProjectEngineApiError(status, method, body)` without reshaping anything else here.
51
+ *
52
+ * @template T
53
+ * @param {string} method the HTTP method, for the error message
54
+ * @param {Promise<{ data?: T, error?: unknown, response: Response }>} resultPromise the pending
55
+ * openapi-fetch result
56
+ * @returns {Promise<NonNullable<T> | null>} the parsed success body, or null for an empty body
57
+ * (an empty-body operation resolves with null, never undefined)
58
+ */
59
+ async function unwrap(method, resultPromise) {
60
+ const { data, error, response } = await resultPromise;
61
+ if (!response.ok) {
62
+ const { status } = response;
63
+ // openapi-fetch surfaces an empty error body as '' (not undefined); normalise it to null.
64
+ const rawBody = error ?? data ?? null;
65
+ // `body` is computed here but not consumed by the plain Error below. LLMO-5978 swaps ONLY
66
+ // the `new Error(...)` line for `new ProjectEngineApiError(status, method, body)` — status,
67
+ // method, and this normalized body are all already in scope, so nothing else here changes.
68
+ // eslint-disable-next-line no-unused-vars
69
+ const body = rawBody === '' ? null : rawBody;
70
+ // Message deliberately omits the request URL: it embeds path-param ids (workspace/
71
+ // project/etc.) that error-reporter and log consumers should not receive by default.
72
+ throw new Error(`Project Engine ${method} failed: ${status}`);
73
+ }
74
+ return data ?? null;
75
+ }
76
+
77
+ return {
78
+ // ─── /v1 catalog ────────────────────────────────────────────────────────
79
+ /** GET /v1/languages — projects-admin-list-languages */
80
+ listLanguages(init) {
81
+ return unwrap('GET', client.GET('/v1/languages', init));
82
+ },
83
+ /** GET /v1/ai_models — ai-list-global-models */
84
+ listGlobalAiModels(init) {
85
+ return unwrap('GET', client.GET('/v1/ai_models', init));
86
+ },
87
+
88
+ // ─── /v1 projects ───────────────────────────────────────────────────────
89
+ /** GET /v1/workspaces/{id}/projects — projects-list-projects */
90
+ listProjects(init) {
91
+ return unwrap('GET', client.GET('/v1/workspaces/{id}/projects', init));
92
+ },
93
+ /** POST /v1/workspaces/{id}/projects — projects-post-project */
94
+ createProject(init) {
95
+ return unwrap('POST', client.POST('/v1/workspaces/{id}/projects', init));
96
+ },
97
+ /** GET /v1/workspaces/{id}/projects/{project_id} — projects-get-project */
98
+ getProject(init) {
99
+ return unwrap('GET', client.GET('/v1/workspaces/{id}/projects/{project_id}', init));
100
+ },
101
+ /** PATCH /v1/workspaces/{id}/projects/{project_id} — projects-patch-project */
102
+ updateProject(init) {
103
+ return unwrap('PATCH', client.PATCH('/v1/workspaces/{id}/projects/{project_id}', init));
104
+ },
105
+ /** DELETE /v1/workspaces/{id}/projects/{project_id} — projects-delete-project */
106
+ deleteProject(init) {
107
+ return unwrap('DELETE', client.DELETE('/v1/workspaces/{id}/projects/{project_id}', init));
108
+ },
109
+ /** POST /v1/workspaces/{id}/projects/{project_id}/publish — projects-publish-project */
110
+ publishProject(init) {
111
+ return unwrap('POST', client.POST('/v1/workspaces/{id}/projects/{project_id}/publish', init));
112
+ },
113
+
114
+ // ─── /v1 AI models + benchmarks ───────────────────────────────────────────
115
+ /** GET /v1/workspaces/{id}/projects/{project_id}/ai_models — ai-list-models */
116
+ listAiModels(init) {
117
+ return unwrap('GET', client.GET('/v1/workspaces/{id}/projects/{project_id}/ai_models', init));
118
+ },
119
+ /** DELETE /v1/workspaces/{id}/projects/{project_id}/ai_models — ai-delete-models */
120
+ deleteAiModels(init) {
121
+ return unwrap('DELETE', client.DELETE('/v1/workspaces/{id}/projects/{project_id}/ai_models', init));
122
+ },
123
+ /** GET /v1/workspaces/{id}/projects/{project_id}/ai_models/benchmarks — ai-list-benchmarks */
124
+ listBenchmarks(init) {
125
+ return unwrap('GET', client.GET('/v1/workspaces/{id}/projects/{project_id}/ai_models/benchmarks', init));
126
+ },
127
+ /**
128
+ * DELETE /v1/workspaces/{id}/projects/{project_id}/ai_models/benchmarks — ai-delete-benchmarks
129
+ */
130
+ deleteBenchmarks(init) {
131
+ return unwrap('DELETE', client.DELETE('/v1/workspaces/{id}/projects/{project_id}/ai_models/benchmarks', init));
132
+ },
133
+ /**
134
+ * PUT /v1/workspaces/{id}/projects/{project_id}/ai_models/benchmarks/{benchmark_id}
135
+ * — ai-update-benchmark
136
+ */
137
+ updateBenchmark(init) {
138
+ return unwrap('PUT', client.PUT('/v1/workspaces/{id}/projects/{project_id}/ai_models/benchmarks/{benchmark_id}', init));
139
+ },
140
+ /** PUT /v1/workspaces/{id}/projects/{project_id}/ci/competitors — ci-update-competitors */
141
+ updateCompetitors(init) {
142
+ return unwrap('PUT', client.PUT('/v1/workspaces/{id}/projects/{project_id}/ci/competitors', init));
143
+ },
144
+
145
+ // ─── /v2 AI models + benchmarks ───────────────────────────────────────────
146
+ /** POST /v2/workspaces/{id}/projects/{project_id}/ai_models — aio-project-create-model */
147
+ createAioModel(init) {
148
+ return unwrap('POST', client.POST('/v2/workspaces/{id}/projects/{project_id}/ai_models', init));
149
+ },
150
+ /**
151
+ * POST /v2/workspaces/{id}/projects/{project_id}/ai_models/benchmarks — ai-create-benchmarks-v2
152
+ */
153
+ createBenchmarks(init) {
154
+ return unwrap('POST', client.POST('/v2/workspaces/{id}/projects/{project_id}/ai_models/benchmarks', init));
155
+ },
156
+
157
+ // ─── /v2 brand URLs ───────────────────────────────────────────────────────
158
+ /**
159
+ * GET /v2/workspaces/{id}/projects/{project_id}/aio/benchmarks/{benchmark_id}/brand_urls
160
+ * — aio-list-brand-urls
161
+ */
162
+ listBrandUrls(init) {
163
+ return unwrap('GET', client.GET('/v2/workspaces/{id}/projects/{project_id}/aio/benchmarks/{benchmark_id}/brand_urls', init));
164
+ },
165
+ /**
166
+ * POST /v2/workspaces/{id}/projects/{project_id}/aio/benchmarks/{benchmark_id}/brand_urls
167
+ * — aio-create-brand-urls
168
+ */
169
+ createBrandUrls(init) {
170
+ return unwrap('POST', client.POST('/v2/workspaces/{id}/projects/{project_id}/aio/benchmarks/{benchmark_id}/brand_urls', init));
171
+ },
172
+ /**
173
+ * DELETE /v2/workspaces/{id}/projects/{project_id}/aio/benchmarks/{benchmark_id}/brand_urls
174
+ * — aio-delete-brand-urls
175
+ */
176
+ deleteBrandUrls(init) {
177
+ return unwrap('DELETE', client.DELETE('/v2/workspaces/{id}/projects/{project_id}/aio/benchmarks/{benchmark_id}/brand_urls', init));
178
+ },
179
+
180
+ // ─── /v2 AIO project state, prompts, tags ─────────────────────────────────
181
+ /**
182
+ * GET /v2/workspaces/{id}/projects/{project_id}/aio/init_status
183
+ * — aio-get-project-init-status-v2
184
+ */
185
+ getProjectInitStatus(init) {
186
+ return unwrap('GET', client.GET('/v2/workspaces/{id}/projects/{project_id}/aio/init_status', init));
187
+ },
188
+ /** POST /v2/workspaces/{id}/projects/{project_id}/aio/prompts — aio-create-prompt-v2 */
189
+ createPrompts(init) {
190
+ return unwrap('POST', client.POST('/v2/workspaces/{id}/projects/{project_id}/aio/prompts', init));
191
+ },
192
+ /**
193
+ * DELETE /v2/workspaces/{id}/projects/{project_id}/aio/prompts — aio-delete-prompt-by-ids-v2
194
+ */
195
+ deletePromptsByIds(init) {
196
+ return unwrap('DELETE', client.DELETE('/v2/workspaces/{id}/projects/{project_id}/aio/prompts', init));
197
+ },
198
+ /**
199
+ * POST /v2/workspaces/{id}/projects/{project_id}/aio/prompts/by_tags
200
+ * — aio-list-prompts-by-tag-ids
201
+ */
202
+ listPromptsByTagIds(init) {
203
+ return unwrap('POST', client.POST('/v2/workspaces/{id}/projects/{project_id}/aio/prompts/by_tags', init));
204
+ },
205
+ /** PUT /v2/workspaces/{id}/projects/{project_id}/aio/prompts/tags — aio-update-prompts-batch */
206
+ updatePromptTags(init) {
207
+ return unwrap('PUT', client.PUT('/v2/workspaces/{id}/projects/{project_id}/aio/prompts/tags', init));
208
+ },
209
+ /**
210
+ * POST /v2/workspaces/{id}/projects/{project_id}/aio/prompts/{prompt_id}/rename
211
+ * — aio-rename-prompt
212
+ */
213
+ renamePrompt(init) {
214
+ return unwrap('POST', client.POST('/v2/workspaces/{id}/projects/{project_id}/aio/prompts/{prompt_id}/rename', init));
215
+ },
216
+ /** GET /v2/workspaces/{id}/projects/{project_id}/aio/tags — aio-get-project-tags */
217
+ listProjectTags(init) {
218
+ return unwrap('GET', client.GET('/v2/workspaces/{id}/projects/{project_id}/aio/tags', init));
219
+ },
220
+ /** POST /v2/workspaces/{id}/projects/{project_id}/aio/tags — aio-create-project-tags */
221
+ createProjectTags(init) {
222
+ return unwrap('POST', client.POST('/v2/workspaces/{id}/projects/{project_id}/aio/tags', init));
223
+ },
224
+ /** PATCH /v2/workspaces/{id}/projects/{project_id}/aio/tags/{tag_id} — aio-update-tag */
225
+ updateProjectTag(init) {
226
+ return unwrap('PATCH', client.PATCH('/v2/workspaces/{id}/projects/{project_id}/aio/tags/{tag_id}', init));
227
+ },
228
+ };
229
+ }