@pipelex/sdk 0.64.0 → 0.65.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/README.md CHANGED
@@ -197,6 +197,12 @@ const laidOut = await client.validate({ method_id: `${created.method_id}@1` }, f
197
197
  });
198
198
  if (laidOut.is_valid) console.log(laidOut.layouts?.map((layout) => layout.catalog) ?? "plain form");
199
199
 
200
+ // A host opening the page reads the same layouts with no dry run, and a builder can switch a
201
+ // page's design off, per catalog, without losing it; the list is written whole.
202
+ const { items: laidOutPages } = await client.listMethodLayouts(created.method_id, 1);
203
+ console.log(laidOutPages.length);
204
+ await client.setMethodLayoutsOff(created.method_id, ["composer"]);
205
+
200
206
  // The template catalog: the public methods every organization reads, in the platform's order, with
201
207
  // the categories that have a template and each card's thumbnails behind short-lived links. A
202
208
  // category's `labels` name it by language tag and may lack a language, in which case a client
@@ -321,7 +327,7 @@ These pages ship inside the published package, so a reader who has only installe
321
327
  | [`docs/files.md`](./docs/files.md) | An organization's files: `listFiles` and `iterateFiles`, the row, the whole record and its provenance, the query and its repeated filters, paging through filtered pages, one file and its uses, the records of an address, the rename rule, links that name the file, a zip of files and its caps, a run's files, the copy into a method's draft, and an upload recorded as a method's test file with the refusals that come with it |
322
328
  | [`docs/method-examples.md`](./docs/method-examples.md) | A method's saved examples: the create, the paged list and its iterator, the edit that raises the input revision, the latest-run write and its `recorded` or `stale` verdict, the build assistant's save and its `kept` or `created` verdict, how an integer past `Number.MAX_SAFE_INTEGER` in the inputs stays exact, and what is refused before sending |
323
329
  | [`docs/method-copy.md`](./docs/method-copy.md) | Copying a method into another organization or duplicating it: what a copy holds and the stored files it copies, the `copied` or `refused` verdict, every refusal, the copy's idempotency key, and `copied_from` |
324
- | [`docs/method-layouts.md`](./docs/method-layouts.md) | A method's stored layouts: `storeMethodLayout`, which stores a layout designed for one pipe of a published version, its closed body and its refusals, the layout and its provenance, and the `layouts` a validate by `method_id` carries when `views` names `layouts`, absent when there are none |
330
+ | [`docs/method-layouts.md`](./docs/method-layouts.md) | A method's stored layouts: `storeMethodLayout`, which stores a layout designed for one pipe of a published version, its closed body and its refusals, the layout, its provenance and its written sample, `listMethodLayouts`, which reads a version's layouts with no dry run, `setMethodLayoutsOff`, which switches a page's design off, and the `layouts` a validate by `method_id` carries when `views` names `layouts`, absent when there are none |
325
331
  | [`docs/public-methods.md`](./docs/public-methods.md) | Public methods and the template catalog: `listMethodTemplates` and its iterator, the ordering, the categories with their labels by language and `listMethodCategories`, the thumbnails' links, another organization's public method read in its narrower shape, the copy of a public method, `visibility` and `categories` on a method, and the refusals a public method's publish adds |
326
332
  | [`docs/organization-branding.md`](./docs/organization-branding.md) | An organization's logos, colours, app style and typeface, and its white-label entitlement: `getBranding`, which every member and API key reads, `updateOrganizationBranding`, a write by the `admin` or the `member` role that sets, clears or keeps each key, and how a refused logo, colour, style or typeface names its field so a settings screen shows the sentence under it |
327
333
  | [`docs/exact-integers.md`](./docs/exact-integers.md) | Which reads keep an integer past `Number.MAX_SAFE_INTEGER` exact, as a `bigint` (a run's inputs and outputs, an example's inputs), how a request body writes it back with its digits, and `parseExactJson` and `stringifyExactJson` for code showing such data as JSON text |
@@ -15,7 +15,7 @@ import type { CommandIO } from "./io.js";
15
15
  * update notice and npm 12's run notices off the script's stderr, which carries the command's
16
16
  * own lines, while npm's warnings and errors still print.
17
17
  */
18
- export declare const SCRIPT_RUNNER = "npx --yes --no-update-notifier --loglevel=warn @pipelex/sdk@0.64.0";
18
+ export declare const SCRIPT_RUNNER = "npx --yes --no-update-notifier --loglevel=warn @pipelex/sdk@0.65.0";
19
19
  export declare const SCRIPT_WRITER = "@pipelex/sdk";
20
20
  export declare const SCRIPT_NEEDS = "Node 22.12 or later";
21
21
  /** Run `pipelex-sdk script` and return its exit code. */
package/dist/client.d.ts CHANGED
@@ -1,6 +1,6 @@
1
1
  import type { MTHDSProtocol, ModelCategory, ModelDeck, RunOptions, StartOptions, VersionInfo } from "mthds/protocol";
2
2
  import type { CodegenRequest, CodegenResponse, CrateRouteOptions, DictPipeOutput, FormatResponse, LintResponse, ModelCheckCategory, ModelReferenceVerdict, PipeIORequest, PipeIOResponse, PipelexRunResultStart, PipelexValidateSource, PipelexValidationResult, ResolveRequest, ResolveResponse, ValidateMethodSelector, ValidateView } from "./models.js";
3
- import type { MethodLayout, MethodLayoutInput } from "./method-layouts.js";
3
+ import type { MethodLayout, MethodLayoutInput, MethodLayoutList } from "./method-layouts.js";
4
4
  import { type GetRunResultOptions, type RunProgress, type RunRead, type RunResults, type RunResultState, type StartAndWaitForResultOptions, type WaitForResultOptions } from "./runs.js";
5
5
  import type { BillingPortalResponse, ChangePlanResponse, CheckoutResponse, DraftFileFromFileInput, DraftFileFromFileResult, FileArchive, FileArchiveRequest, FileDetail, FileLinkTarget, FileLinksResult, FilePage, FileRecord, FileRecordList, FileRenameInput, FileSummary, GetFileQuery, GetFilesByUriOptions, InvoiceView, Membership, MembershipsResponse, OrganizationBranding, OrganizationBrandingUpdate, ListFilesQuery, ListMethodExamplesQuery, ListMethodsQuery, ListMethodTemplatesQuery, ListMethodVersionsQuery, ListRunFilesQuery, MethodCategoryList, MethodCopyInput, MethodCopyResult, MethodData, MethodDeletionAccepted, MethodDetail, MethodDraftInput, MethodExample, MethodExampleAssistantSaveInput, MethodExampleAssistantSaveResult, MethodExampleCreateInput, MethodExampleLatestRunInput, MethodExampleLatestRunResult, MethodExamplePage, MethodExampleUpdateInput, MethodPage, MethodPublishInput, MethodPublishResult, MethodRenameInput, MethodSummary, MethodTemplate, MethodTemplatePage, MethodVersion, MethodVersionPage, MethodWriteInput, OnboardingSubmission, PublicMethodDetail, PipelexApiKeyCreated, PipelexApiKeyList, ListRunsQuery, RunHistoryItem, RunDetail, RunFilesPage, RunPage, PlanView, ResolvedStorageUrl, SavedMethodFile, SubscriptionResponse, UpdateRunInput, UploadGrant, UploadGrantInput, UploadInput, UploadedFile, UserProfile } from "./product-models.js";
6
6
  import type { MethodTreeForms, MethodTreeLimits } from "./method-trees.js";
@@ -174,6 +174,29 @@ export interface MethodCopyRequestOptions {
174
174
  */
175
175
  idempotencyKey?: string | null;
176
176
  }
177
+ /** Options for `listMethodLayouts`. */
178
+ export interface MethodLayoutListOptions {
179
+ /**
180
+ * Caller-driven cancellation, such as an `AbortSignal.timeout(…)` for a page that can do without
181
+ * the layouts; the abort reason propagates untouched.
182
+ */
183
+ signal?: AbortSignal;
184
+ }
185
+ /** Options for `setMethodLayoutsOff`. */
186
+ export interface MethodLayoutsOffOptions {
187
+ /**
188
+ * The write's idempotency key, sent as the `Idempotency-Key` header of
189
+ * `PUT /v1/methods/{id}/layouts-off`, and not sent at all when absent or `null`. Generate one per
190
+ * switch the caller means to make (a `crypto.randomUUID()` is a good key), and keep it, with the
191
+ * arguments unchanged, across that write's retries.
192
+ *
193
+ * The write is the whole list, so a write sent again without a key writes that list again, and
194
+ * undoes a switch that landed in between. Under the same key the hosted API answers the retry
195
+ * with the first write's stored answer and runs nothing. The rest of the rule, a key's form and
196
+ * its `409`s included, is `MethodLayoutWriteOptions.idempotencyKey`'s.
197
+ */
198
+ idempotencyKey?: string | null;
199
+ }
177
200
  /** Options for `storeMethodLayout`. */
178
201
  export interface MethodLayoutWriteOptions {
179
202
  /**
@@ -317,7 +340,7 @@ export declare class PipelexApiClient implements HostedProtocolSurface {
317
340
  * whose errors then say whether it may have (see `RunCreation`).
318
341
  * `idempotencyKey`, already checked by `idempotencyKeyOf`, is sent as the
319
342
  * `Idempotency-Key` header; only `start`, `copyMethod`, `storeMethodLayout`,
320
- * `rotateWebhookSecret` and `replayRunWebhookDelivery` pass one.
343
+ * `setMethodLayoutsOff`, `rotateWebhookSecret` and `replayRunWebhookDelivery` pass one.
321
344
  */
322
345
  private requestRaw;
323
346
  /**
@@ -347,7 +370,7 @@ export declare class PipelexApiClient implements HostedProtocolSurface {
347
370
  private requestProductObject;
348
371
  /**
349
372
  * A methods-catalog route answering one stored method (`createMethod`, `writeDraft`,
350
- * `renameMethod`), read as `readObjectAnswer` reads it.
373
+ * `renameMethod`, `setMethodLayoutsOff`), read as `readObjectAnswer` reads it.
351
374
  */
352
375
  private requestMethodData;
353
376
  /**
@@ -1414,8 +1437,8 @@ export declare class PipelexApiClient implements HostedProtocolSurface {
1414
1437
  *
1415
1438
  * A layout is a data file a producer designed over the version's input-form descriptor, in the
1416
1439
  * vocabulary of a catalog of components. The platform stores it beside the method, keyed by the
1417
- * content it was designed for, and hands it back on every validate of the method by `method_id`
1418
- * that names `layouts` among its `views` and resolves the same tree
1440
+ * content it was designed for, and hands it back through `listMethodLayouts` and on every validate
1441
+ * of the method by `method_id` that names `layouts` among its `views` and resolves the same tree
1419
1442
  * (`PipelexValidationReport.layouts`). It never produces, parses or judges one.
1420
1443
  *
1421
1444
  * `layout.tree_digest` must be the digest of the tree `version` holds, its
@@ -1428,12 +1451,13 @@ export declare class PipelexApiClient implements HostedProtocolSurface {
1428
1451
  * (`MethodLayoutWriteOptions`). A content keeps at most 16
1429
1452
  * layouts, every pipe, catalog and prompt hash together; past the bound a write removes first what
1430
1453
  * newer prompts of the same pipe and catalog superseded (see `docs/method-layouts.md`).
1454
+ * `layout.sample_json` keeps a written sample with the layout, never a run's output.
1431
1455
  *
1432
1456
  * The write changes the method, so it takes an `admin` or a `member` of the method's
1433
1457
  * organization. Takes a bare catalog id, as `getMethod` does, and the version number. Sends the
1434
1458
  * members of `MethodLayoutInput` and nothing else, the route's body being closed at both levels,
1435
- * and leaves out each optional provenance member that is `null` or omitted, for the platform's
1436
- * default. Throws `RequestArgumentError` before any request for a `version` that is not a positive
1459
+ * and leaves out `sample_json` and each optional provenance member that is `null` or omitted, for
1460
+ * the platform's default. Throws `RequestArgumentError` before any request for a `version` that is not a positive
1437
1461
  * integer and for a `layout` or a `provenance` that is not an object; every other member is sent
1438
1462
  * as given. Throws `ApiResponseError` when the platform refuses the write, which stores nothing:
1439
1463
  * `422` `request.invalid` for a member breaking its shape or bound, naming it in `params.field`
@@ -1452,6 +1476,57 @@ export declare class PipelexApiClient implements HostedProtocolSurface {
1452
1476
  * an `ApiResponseError` too.
1453
1477
  */
1454
1478
  storeMethodLayout(methodId: string, version: number, layout: MethodLayoutInput, options?: MethodLayoutWriteOptions): Promise<MethodLayout>;
1479
+ /**
1480
+ * The layouts stored for the content of a published version of a method —
1481
+ * `GET /v1/methods/{id}/versions/{n}/layouts` — newest first, at most 16, `items` empty when none
1482
+ * is stored. It touches only the platform's database and calls no runner, so it costs a host far
1483
+ * less than the `layouts` view of `validate`, which dry-runs every pipe of the method.
1484
+ *
1485
+ * It answers what is stored whatever `layouts_off` says: the switch is the host's to honour.
1486
+ * Another organization's public method reads too, with the layouts its builders stored, and a
1487
+ * `runner` reads what it is shown. Takes a bare catalog id, as `getMethod` does, and the version
1488
+ * number. `options.signal` cancels the read. Throws `RequestArgumentError` for a `version` that is
1489
+ * not a positive integer, before any request.
1490
+ *
1491
+ * Throws `ApiResponseError`: `404` `pipelex.catalog.not_found` for an unknown method or another
1492
+ * organization's internal one, its `params.resource` `method`, and for a version the method never
1493
+ * published, its `params.resource` `version`; `409` `pipelex.catalog.being_deleted` while the
1494
+ * erasure of the caller's own method is pending, under way or stopped; `500` `runtime.unexpected`
1495
+ * for a version stored before methods were trees, which names no tree. An answer whose `items` is
1496
+ * not an array is an answer the SDK cannot read, thrown as an `ApiResponseError` too; an entry
1497
+ * that does not read as a layout is left out (`readMethodLayouts`), so one layout it cannot read
1498
+ * never costs the caller the others.
1499
+ */
1500
+ listMethodLayouts(methodId: string, version: number, options?: MethodLayoutListOptions): Promise<MethodLayoutList>;
1501
+ /**
1502
+ * Set which catalogs of a method have their layouts switched off —
1503
+ * `PUT /v1/methods/{id}/layouts-off` — and return the method, its `layouts_off` the list as held.
1504
+ *
1505
+ * `catalogs` is the whole list and replaces the one held, each catalog id once, at most 8, empty
1506
+ * when every design is on: to change one, read `layouts_off` and write the new list. The switch
1507
+ * acts at once, with no publish, and holds across every publish. A layout switched off is kept,
1508
+ * and `listMethodLayouts` still answers it; a host draws the plain page instead. Like a rename, it
1509
+ * never moves the draft token, so the `updated_at` a caller holds stays valid.
1510
+ *
1511
+ * The last write to land is the one held. `options.idempotencyKey` is sent as the
1512
+ * `Idempotency-Key` header, so a write whose answer was lost is sent again under the same key and
1513
+ * answered as the first was (`MethodLayoutsOffOptions`).
1514
+ *
1515
+ * The write changes the method, so it takes an `admin` or a `member` of the method's
1516
+ * organization. Takes a bare catalog id, as `getMethod` does. Throws `RequestArgumentError` before
1517
+ * any request for `catalogs` that is not an array; its entries are sent as given. Throws
1518
+ * `ApiResponseError`: `404` `pipelex.catalog.not_found` for an unknown method or another
1519
+ * organization's, a public one included; `403` `auth.forbidden` naming the `member` requirement
1520
+ * for a `runner` or a caller with no recognised role; `409` `pipelex.catalog.being_deleted` while
1521
+ * the method's erasure is pending, under way or stopped; `413` `request.too_large` for a list that
1522
+ * would leave the method too large to publish, which a list that does not grow never is; and
1523
+ * `422` `request.invalid` for more than 8 catalogs, a catalog named twice or one that is not a
1524
+ * slug. Under an idempotency key, `409` `request.idempotency_conflict` for the key sent with a
1525
+ * different list and `409` `request.idempotency_key_in_use` while its earlier request is still
1526
+ * being handled; a key that is not 1 to 255 visible ASCII characters is a `RequestArgumentError`
1527
+ * before any request.
1528
+ */
1529
+ setMethodLayoutsOff(methodId: string, catalogs: readonly string[], options?: MethodLayoutsOffOptions): Promise<MethodData>;
1455
1530
  /**
1456
1531
  * Copy a method into an organization the caller may change methods in —
1457
1532
  * `POST /v1/methods/{id}/copy`: the method's own organization for a duplicate, another team, or
package/dist/client.js CHANGED
@@ -332,6 +332,14 @@ const LAYOUT_VERSION_ARGUMENT = {
332
332
  name: "version",
333
333
  what: "a version number, the published version the layout was designed for, a positive integer",
334
334
  };
335
+ const LAYOUT_LIST_VERSION_ARGUMENT = {
336
+ name: "version",
337
+ what: "a version number, the published version whose layouts to read, a positive integer",
338
+ };
339
+ const LAYOUTS_OFF_CATALOGS_ARGUMENT = {
340
+ name: "catalogs",
341
+ what: "the ids of the catalogs to switch off as an array, the whole list, empty for none",
342
+ };
335
343
  const LAYOUT_ARGUMENT = {
336
344
  name: "layout",
337
345
  what: "the layout to store as an object, a MethodLayoutInput",
@@ -601,7 +609,7 @@ export class PipelexApiClient {
601
609
  * whose errors then say whether it may have (see `RunCreation`).
602
610
  * `idempotencyKey`, already checked by `idempotencyKeyOf`, is sent as the
603
611
  * `Idempotency-Key` header; only `start`, `copyMethod`, `storeMethodLayout`,
604
- * `rotateWebhookSecret` and `replayRunWebhookDelivery` pass one.
612
+ * `setMethodLayoutsOff`, `rotateWebhookSecret` and `replayRunWebhookDelivery` pass one.
605
613
  */
606
614
  async requestRaw(method, url, options = {}) {
607
615
  const hasBody = options.body !== undefined;
@@ -718,7 +726,7 @@ export class PipelexApiClient {
718
726
  }
719
727
  /**
720
728
  * A methods-catalog route answering one stored method (`createMethod`, `writeDraft`,
721
- * `renameMethod`), read as `readObjectAnswer` reads it.
729
+ * `renameMethod`, `setMethodLayoutsOff`), read as `readObjectAnswer` reads it.
722
730
  */
723
731
  async requestMethodData(method, endpoint, body, options = {}) {
724
732
  const res = await this.requestProductAnswer(method, endpoint, body, options);
@@ -2663,8 +2671,8 @@ export class PipelexApiClient {
2663
2671
  *
2664
2672
  * A layout is a data file a producer designed over the version's input-form descriptor, in the
2665
2673
  * vocabulary of a catalog of components. The platform stores it beside the method, keyed by the
2666
- * content it was designed for, and hands it back on every validate of the method by `method_id`
2667
- * that names `layouts` among its `views` and resolves the same tree
2674
+ * content it was designed for, and hands it back through `listMethodLayouts` and on every validate
2675
+ * of the method by `method_id` that names `layouts` among its `views` and resolves the same tree
2668
2676
  * (`PipelexValidationReport.layouts`). It never produces, parses or judges one.
2669
2677
  *
2670
2678
  * `layout.tree_digest` must be the digest of the tree `version` holds, its
@@ -2677,12 +2685,13 @@ export class PipelexApiClient {
2677
2685
  * (`MethodLayoutWriteOptions`). A content keeps at most 16
2678
2686
  * layouts, every pipe, catalog and prompt hash together; past the bound a write removes first what
2679
2687
  * newer prompts of the same pipe and catalog superseded (see `docs/method-layouts.md`).
2688
+ * `layout.sample_json` keeps a written sample with the layout, never a run's output.
2680
2689
  *
2681
2690
  * The write changes the method, so it takes an `admin` or a `member` of the method's
2682
2691
  * organization. Takes a bare catalog id, as `getMethod` does, and the version number. Sends the
2683
2692
  * members of `MethodLayoutInput` and nothing else, the route's body being closed at both levels,
2684
- * and leaves out each optional provenance member that is `null` or omitted, for the platform's
2685
- * default. Throws `RequestArgumentError` before any request for a `version` that is not a positive
2693
+ * and leaves out `sample_json` and each optional provenance member that is `null` or omitted, for
2694
+ * the platform's default. Throws `RequestArgumentError` before any request for a `version` that is not a positive
2686
2695
  * integer and for a `layout` or a `provenance` that is not an object; every other member is sent
2687
2696
  * as given. Throws `ApiResponseError` when the platform refuses the write, which stores nothing:
2688
2697
  * `422` `request.invalid` for a member breaking its shape or bound, naming it in `params.field`
@@ -2716,6 +2725,79 @@ export class PipelexApiClient {
2716
2725
  }
2717
2726
  return stored;
2718
2727
  }
2728
+ /**
2729
+ * The layouts stored for the content of a published version of a method —
2730
+ * `GET /v1/methods/{id}/versions/{n}/layouts` — newest first, at most 16, `items` empty when none
2731
+ * is stored. It touches only the platform's database and calls no runner, so it costs a host far
2732
+ * less than the `layouts` view of `validate`, which dry-runs every pipe of the method.
2733
+ *
2734
+ * It answers what is stored whatever `layouts_off` says: the switch is the host's to honour.
2735
+ * Another organization's public method reads too, with the layouts its builders stored, and a
2736
+ * `runner` reads what it is shown. Takes a bare catalog id, as `getMethod` does, and the version
2737
+ * number. `options.signal` cancels the read. Throws `RequestArgumentError` for a `version` that is
2738
+ * not a positive integer, before any request.
2739
+ *
2740
+ * Throws `ApiResponseError`: `404` `pipelex.catalog.not_found` for an unknown method or another
2741
+ * organization's internal one, its `params.resource` `method`, and for a version the method never
2742
+ * published, its `params.resource` `version`; `409` `pipelex.catalog.being_deleted` while the
2743
+ * erasure of the caller's own method is pending, under way or stopped; `500` `runtime.unexpected`
2744
+ * for a version stored before methods were trees, which names no tree. An answer whose `items` is
2745
+ * not an array is an answer the SDK cannot read, thrown as an `ApiResponseError` too; an entry
2746
+ * that does not read as a layout is left out (`readMethodLayouts`), so one layout it cannot read
2747
+ * never costs the caller the others.
2748
+ */
2749
+ async listMethodLayouts(methodId, version, options = {}) {
2750
+ const call = "listMethodLayouts";
2751
+ if (!Number.isSafeInteger(version) || version < 1) {
2752
+ throw argumentRefusal(call, LAYOUT_LIST_VERSION_ARGUMENT, describeNumberArgument(version), "not_a_positive_integer");
2753
+ }
2754
+ const endpoint = `${methodPath(methodId, call)}/versions/${version}/layouts`;
2755
+ const res = await this.requestProductAnswer("GET", endpoint, undefined, {
2756
+ signal: options.signal,
2757
+ });
2758
+ const answer = this.readObjectAnswer("GET", endpoint, res);
2759
+ if (!Array.isArray(answer.items)) {
2760
+ throw this.unreadableAnswer("GET", `/${API_PREFIX}/${endpoint}`, res, "a list of layouts whose `items` is not an array");
2761
+ }
2762
+ return { ...answer, items: readMethodLayouts(answer.items) };
2763
+ }
2764
+ /**
2765
+ * Set which catalogs of a method have their layouts switched off —
2766
+ * `PUT /v1/methods/{id}/layouts-off` — and return the method, its `layouts_off` the list as held.
2767
+ *
2768
+ * `catalogs` is the whole list and replaces the one held, each catalog id once, at most 8, empty
2769
+ * when every design is on: to change one, read `layouts_off` and write the new list. The switch
2770
+ * acts at once, with no publish, and holds across every publish. A layout switched off is kept,
2771
+ * and `listMethodLayouts` still answers it; a host draws the plain page instead. Like a rename, it
2772
+ * never moves the draft token, so the `updated_at` a caller holds stays valid.
2773
+ *
2774
+ * The last write to land is the one held. `options.idempotencyKey` is sent as the
2775
+ * `Idempotency-Key` header, so a write whose answer was lost is sent again under the same key and
2776
+ * answered as the first was (`MethodLayoutsOffOptions`).
2777
+ *
2778
+ * The write changes the method, so it takes an `admin` or a `member` of the method's
2779
+ * organization. Takes a bare catalog id, as `getMethod` does. Throws `RequestArgumentError` before
2780
+ * any request for `catalogs` that is not an array; its entries are sent as given. Throws
2781
+ * `ApiResponseError`: `404` `pipelex.catalog.not_found` for an unknown method or another
2782
+ * organization's, a public one included; `403` `auth.forbidden` naming the `member` requirement
2783
+ * for a `runner` or a caller with no recognised role; `409` `pipelex.catalog.being_deleted` while
2784
+ * the method's erasure is pending, under way or stopped; `413` `request.too_large` for a list that
2785
+ * would leave the method too large to publish, which a list that does not grow never is; and
2786
+ * `422` `request.invalid` for more than 8 catalogs, a catalog named twice or one that is not a
2787
+ * slug. Under an idempotency key, `409` `request.idempotency_conflict` for the key sent with a
2788
+ * different list and `409` `request.idempotency_key_in_use` while its earlier request is still
2789
+ * being handled; a key that is not 1 to 255 visible ASCII characters is a `RequestArgumentError`
2790
+ * before any request.
2791
+ */
2792
+ async setMethodLayoutsOff(methodId, catalogs, options = {}) {
2793
+ const call = "setMethodLayoutsOff";
2794
+ const endpoint = `${methodPath(methodId, call)}/layouts-off`;
2795
+ if (!Array.isArray(catalogs)) {
2796
+ throw argumentRefusal(call, LAYOUTS_OFF_CATALOGS_ARGUMENT, describeNumberArgument(catalogs), "not_a_list");
2797
+ }
2798
+ const idempotencyKey = idempotencyKeyOf(options, "set the layouts off");
2799
+ return this.requestMethodData("PUT", endpoint, { catalogs }, { idempotencyKey });
2800
+ }
2719
2801
  /**
2720
2802
  * Copy a method into an organization the caller may change methods in —
2721
2803
  * `POST /v1/methods/{id}/copy`: the method's own organization for a duplicate, another team, or
@@ -4483,14 +4565,14 @@ const MAX_IDEMPOTENCY_KEY_LENGTH = 255;
4483
4565
  */
4484
4566
  const VISIBLE_ASCII = /^[\x21-\x7E]+$/;
4485
4567
  /**
4486
- * The idempotency key a start, a method copy, a layout write, a secret rotation or a delivery
4487
- * replay sends, or
4568
+ * The idempotency key a start, a method copy, a layout write, a write of the layouts switched off,
4569
+ * a secret rotation or a delivery replay sends, or
4488
4570
  * `undefined` when the options carry none (absent or `null`). A key that is not a string of 1 to
4489
4571
  * 255 visible ASCII characters is refused with a `RequestArgumentError` rather than dropped, an
4490
4572
  * empty one included, since a request sent without the key its caller gave would lose the
4491
4573
  * protection the caller asked for without a word. `request` says what the request does, as the
4492
4574
  * refusal's last sentence names it ("start the run", "copy the method", "store the layout",
4493
- * "rotate the secret", "replay the delivery"). The message never quotes the key, which a caller may derive from
4575
+ * "set the layouts off", "rotate the secret", "replay the delivery"). The message never quotes the key, which a caller may derive from
4494
4576
  * something private. The Python SDK holds a key to the same rule, in the same words.
4495
4577
  */
4496
4578
  function idempotencyKeyOf(options, request = "start the run") {
@@ -4871,10 +4953,20 @@ function withReadLayouts(answer) {
4871
4953
  read.layouts = layouts;
4872
4954
  return read;
4873
4955
  }
4956
+ /** `source`'s members that `members` lists, each `optional` one left out when `null` or omitted. */
4957
+ function sentMembers(members, source) {
4958
+ const sent = {};
4959
+ for (const [member, presence] of Object.entries(members)) {
4960
+ const value = source[member];
4961
+ if (presence === "required" || value != null)
4962
+ sent[member] = value;
4963
+ }
4964
+ return sent;
4965
+ }
4874
4966
  /**
4875
4967
  * The body `storeMethodLayout` sends for `layout`: the members of `MethodLayoutInput` and nothing
4876
- * else, since the route's body is closed at both levels, each provenance member that is `null` or
4877
- * omitted left out for the platform's default. The members are `LAYOUT_INPUT_MEMBERS` and
4968
+ * else, since the route's body is closed at both levels, `sample_json` and each provenance member
4969
+ * that is `null` or omitted left out for the platform's default. The members are `LAYOUT_INPUT_MEMBERS` and
4878
4970
  * `PROVENANCE_INPUT_MEMBERS`, which the build holds to the interfaces. A layout or a provenance that is not an object is
4879
4971
  * refused with `RequestArgumentError` before anything is sent; every other member is sent as given,
4880
4972
  * for the platform to hold to its shapes, its `422` naming the member it refuses.
@@ -4887,16 +4979,8 @@ function methodLayoutBody(layout, call) {
4887
4979
  if (!isPlainObject(provenance)) {
4888
4980
  throw argumentRefusal(call, LAYOUT_PROVENANCE_ARGUMENT, describeNumberArgument(provenance), "not_an_object");
4889
4981
  }
4890
- const sentProvenance = {};
4891
- for (const [member, presence] of Object.entries(PROVENANCE_INPUT_MEMBERS)) {
4892
- const value = provenance[member];
4893
- if (presence === "required" || value != null)
4894
- sentProvenance[member] = value;
4895
- }
4896
- const body = {};
4897
- for (const member of Object.keys(LAYOUT_INPUT_MEMBERS))
4898
- body[member] = layout[member];
4899
- body.provenance = sentProvenance;
4982
+ const body = sentMembers(LAYOUT_INPUT_MEMBERS, layout);
4983
+ body.provenance = sentMembers(PROVENANCE_INPUT_MEMBERS, provenance);
4900
4984
  return body;
4901
4985
  }
4902
4986
  /**