@shipeasy/openapi 1.1.0 → 1.2.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/dist/index.js CHANGED
@@ -671,7 +671,7 @@ var experimentUpdateSchema = z6.object({
671
671
  );
672
672
  var experimentStatusUpdateSchema = z6.object({
673
673
  status: z6.enum(["draft", "running", "stopped", "archived"]).describe(
674
- "Target status. Allowed transitions: `draft \u2192 running`, `running \u2192 stopped`, `stopped \u2192 archived`, `draft \u2192 archived`. Restarting an archived experiment is not allowed."
674
+ "Target status. Allowed transitions: `draft \u2192 running`, `running \u2192 stopped`, `stopped \u2192 archived`, `draft \u2192 archived`, and `archived \u2192 draft` (restore \u2014 only if the experiment never started). Restarting an archived experiment directly is not allowed; restore it to draft first, then start."
675
675
  )
676
676
  }).describe("Body for `POST /api/admin/experiments/{id}/status`.");
677
677
  var experimentMetricsUpdateSchema = z6.object({
@@ -776,24 +776,29 @@ function experimentsClient(t) {
776
776
  if (opts.cursor) query.cursor = opts.cursor;
777
777
  return t.request("GET", BASE2, void 0, query);
778
778
  }
779
- async function listAll() {
779
+ async function listAllWith(status) {
780
780
  const out = [];
781
781
  let cursor;
782
782
  do {
783
- const page = await list({ limit: 500, cursor });
783
+ const query = { limit: "500" };
784
+ if (cursor) query.cursor = cursor;
785
+ if (status) query.status = status;
786
+ const page = await t.request("GET", BASE2, void 0, query);
784
787
  out.push(...page.data);
785
788
  cursor = page.next_cursor ?? void 0;
786
789
  } while (cursor);
787
790
  return out;
788
791
  }
792
+ async function listAll() {
793
+ return listAllWith();
794
+ }
789
795
  async function resolve(idOrName) {
790
796
  try {
791
797
  return await t.request("GET", `${BASE2}/${idOrName}`);
792
798
  } catch (err) {
793
799
  if (!(err instanceof ApiError) || err.status !== 404) throw err;
794
800
  }
795
- const all = await listAll();
796
- const found = all.find((e) => e.name === idOrName);
801
+ const found = (await listAllWith()).find((e) => e.name === idOrName) ?? (await listAllWith("archived")).find((e) => e.name === idOrName);
797
802
  if (!found) throw new ApiError(`Experiment '${idOrName}' not found`, 404);
798
803
  return found;
799
804
  }
@@ -816,6 +821,7 @@ function experimentsClient(t) {
816
821
  start: (id) => setStatus(id, "running"),
817
822
  stop: (id) => setStatus(id, "stopped"),
818
823
  archive: (id) => setStatus(id, "archived"),
824
+ restore: (id) => setStatus(id, "draft"),
819
825
  setMetrics: (id, input) => t.request("POST", `${BASE2}/${id}/metrics`, experimentMetricsUpdateSchema.parse(input)),
820
826
  results: (id) => t.request("GET", `${BASE2}/${id}/results`),
821
827
  timeseries: (id, metric) => t.request(
@@ -862,7 +868,7 @@ var experimentsResource = {
862
868
  "",
863
869
  "**Identity.** Stable `name` (a-z, 0-9, `_`/`-`, max 64 chars). Immutable after create.",
864
870
  "",
865
- "**Lifecycle.** `draft \u2192 running \u2192 stopped \u2192 archived`. Transition via `POST /{id}/status`. Restarting an archived experiment is not allowed.",
871
+ "**Lifecycle.** `draft \u2192 running \u2192 stopped \u2192 archived`. Transition via `POST /{id}/status`. An archived experiment that never started can be restored with `archived \u2192 draft`; restarting an archived experiment directly is not allowed.",
866
872
  "",
867
873
  "**Allocation.** `allocation_pct` (basis points, 0\u201310000) is the share of the targeted audience enrolled; `groups[].weight` (must sum to 10000) splits the enrolled audience. `targeting_gate` narrows the eligible audience before allocation.",
868
874
  "",
@@ -881,6 +887,7 @@ var experimentsResource = {
881
887
  { name: "start", description: "Transition draft experiment to running" },
882
888
  { name: "stop", description: "Stop a running experiment" },
883
889
  { name: "archive", description: "Archive a stopped experiment" },
890
+ { name: "restore", description: "Restore an archived (never-started) experiment to draft" },
884
891
  { name: "reanalyze", description: "Re-run analysis pass for the experiment" }
885
892
  ],
886
893
  endpoints: [
@@ -1061,8 +1068,9 @@ var experimentsResource = {
1061
1068
  "- `running \u2192 stopped` \u2014 halts allocation. Existing exposures stay in the dataset.",
1062
1069
  "- `stopped \u2192 archived` \u2014 soft-delete.",
1063
1070
  "- `draft \u2192 archived` \u2014 discard an unstarted experiment.",
1071
+ "- `archived \u2192 draft` \u2014 restore a soft-deleted experiment so it can be re-completed and started. Allowed only if it never started; one that already ran must be cloned instead.",
1064
1072
  "",
1065
- "Restarting an `archived` experiment is not allowed; clone instead. Returns `409` on illegal transitions and `429` if the plan's `experiments_running` limit is exceeded on `\u2192 running`."
1073
+ "Restarting an `archived` experiment directly is not allowed \u2014 restore it to `draft` first. Returns `409` on illegal transitions and `429` if the plan's `experiments_running` limit is exceeded on `\u2192 running`."
1066
1074
  ].join("\n"),
1067
1075
  pathParams: { id: "Stable opaque experiment id." },
1068
1076
  request: experimentStatusUpdateSchema,
@@ -1083,6 +1091,11 @@ var experimentsResource = {
1083
1091
  summary: "Archive \u2014 stopped \u2192 archived",
1084
1092
  description: "Soft-deletes the experiment. List endpoints exclude archived rows by default.",
1085
1093
  value: { status: "archived" }
1094
+ },
1095
+ restore: {
1096
+ summary: "Restore \u2014 archived \u2192 draft",
1097
+ description: "Un-deletes a soft-deleted experiment so it can be re-completed and started. Allowed only if it never ran.",
1098
+ value: { status: "draft" }
1086
1099
  }
1087
1100
  },
1088
1101
  response: { id: "exp_01j7wb12c3d4e5f6g7h8j9k0l1", status: "running" }
@@ -59,6 +59,8 @@ interface ExperimentsClient {
59
59
  start(id: string): Promise<Experiment>;
60
60
  stop(id: string): Promise<Experiment>;
61
61
  archive(id: string): Promise<Experiment>;
62
+ /** Restore a soft-deleted (archived) experiment back to `draft`. */
63
+ restore(id: string): Promise<Experiment>;
62
64
  setMetrics(id: string, input: ExperimentMetricsInput): Promise<unknown>;
63
65
  results(id: string): Promise<ExperimentResult[]>;
64
66
  timeseries(id: string, metric?: string): Promise<ExperimentTimeseriesPoint[]>;
@@ -167,6 +169,9 @@ declare const experimentsResource: {
167
169
  }, {
168
170
  readonly name: "archive";
169
171
  readonly description: "Archive a stopped experiment";
172
+ }, {
173
+ readonly name: "restore";
174
+ readonly description: "Restore an archived (never-started) experiment to draft";
170
175
  }, {
171
176
  readonly name: "reanalyze";
172
177
  readonly description: "Re-run analysis pass for the experiment";
@@ -637,6 +642,13 @@ declare const experimentsResource: {
637
642
  readonly status: "archived";
638
643
  };
639
644
  };
645
+ readonly restore: {
646
+ readonly summary: "Restore — archived → draft";
647
+ readonly description: "Un-deletes a soft-deleted experiment so it can be re-completed and started. Allowed only if it never ran.";
648
+ readonly value: {
649
+ readonly status: "draft";
650
+ };
651
+ };
640
652
  };
641
653
  readonly response: {
642
654
  readonly id: "exp_01j7wb12c3d4e5f6g7h8j9k0l1";
@@ -106,7 +106,7 @@ var experimentUpdateSchema = z3.object({
106
106
  );
107
107
  var experimentStatusUpdateSchema = z3.object({
108
108
  status: z3.enum(["draft", "running", "stopped", "archived"]).describe(
109
- "Target status. Allowed transitions: `draft \u2192 running`, `running \u2192 stopped`, `stopped \u2192 archived`, `draft \u2192 archived`. Restarting an archived experiment is not allowed."
109
+ "Target status. Allowed transitions: `draft \u2192 running`, `running \u2192 stopped`, `stopped \u2192 archived`, `draft \u2192 archived`, and `archived \u2192 draft` (restore \u2014 only if the experiment never started). Restarting an archived experiment directly is not allowed; restore it to draft first, then start."
110
110
  )
111
111
  }).describe("Body for `POST /api/admin/experiments/{id}/status`.");
112
112
  var experimentMetricsUpdateSchema = z3.object({
@@ -221,24 +221,29 @@ function experimentsClient(t) {
221
221
  if (opts.cursor) query.cursor = opts.cursor;
222
222
  return t.request("GET", BASE, void 0, query);
223
223
  }
224
- async function listAll() {
224
+ async function listAllWith(status) {
225
225
  const out = [];
226
226
  let cursor;
227
227
  do {
228
- const page = await list({ limit: 500, cursor });
228
+ const query = { limit: "500" };
229
+ if (cursor) query.cursor = cursor;
230
+ if (status) query.status = status;
231
+ const page = await t.request("GET", BASE, void 0, query);
229
232
  out.push(...page.data);
230
233
  cursor = page.next_cursor ?? void 0;
231
234
  } while (cursor);
232
235
  return out;
233
236
  }
237
+ async function listAll() {
238
+ return listAllWith();
239
+ }
234
240
  async function resolve(idOrName) {
235
241
  try {
236
242
  return await t.request("GET", `${BASE}/${idOrName}`);
237
243
  } catch (err) {
238
244
  if (!(err instanceof ApiError) || err.status !== 404) throw err;
239
245
  }
240
- const all = await listAll();
241
- const found = all.find((e) => e.name === idOrName);
246
+ const found = (await listAllWith()).find((e) => e.name === idOrName) ?? (await listAllWith("archived")).find((e) => e.name === idOrName);
242
247
  if (!found) throw new ApiError(`Experiment '${idOrName}' not found`, 404);
243
248
  return found;
244
249
  }
@@ -261,6 +266,7 @@ function experimentsClient(t) {
261
266
  start: (id) => setStatus(id, "running"),
262
267
  stop: (id) => setStatus(id, "stopped"),
263
268
  archive: (id) => setStatus(id, "archived"),
269
+ restore: (id) => setStatus(id, "draft"),
264
270
  setMetrics: (id, input) => t.request("POST", `${BASE}/${id}/metrics`, experimentMetricsUpdateSchema.parse(input)),
265
271
  results: (id) => t.request("GET", `${BASE}/${id}/results`),
266
272
  timeseries: (id, metric) => t.request(
@@ -307,7 +313,7 @@ var experimentsResource = {
307
313
  "",
308
314
  "**Identity.** Stable `name` (a-z, 0-9, `_`/`-`, max 64 chars). Immutable after create.",
309
315
  "",
310
- "**Lifecycle.** `draft \u2192 running \u2192 stopped \u2192 archived`. Transition via `POST /{id}/status`. Restarting an archived experiment is not allowed.",
316
+ "**Lifecycle.** `draft \u2192 running \u2192 stopped \u2192 archived`. Transition via `POST /{id}/status`. An archived experiment that never started can be restored with `archived \u2192 draft`; restarting an archived experiment directly is not allowed.",
311
317
  "",
312
318
  "**Allocation.** `allocation_pct` (basis points, 0\u201310000) is the share of the targeted audience enrolled; `groups[].weight` (must sum to 10000) splits the enrolled audience. `targeting_gate` narrows the eligible audience before allocation.",
313
319
  "",
@@ -326,6 +332,7 @@ var experimentsResource = {
326
332
  { name: "start", description: "Transition draft experiment to running" },
327
333
  { name: "stop", description: "Stop a running experiment" },
328
334
  { name: "archive", description: "Archive a stopped experiment" },
335
+ { name: "restore", description: "Restore an archived (never-started) experiment to draft" },
329
336
  { name: "reanalyze", description: "Re-run analysis pass for the experiment" }
330
337
  ],
331
338
  endpoints: [
@@ -506,8 +513,9 @@ var experimentsResource = {
506
513
  "- `running \u2192 stopped` \u2014 halts allocation. Existing exposures stay in the dataset.",
507
514
  "- `stopped \u2192 archived` \u2014 soft-delete.",
508
515
  "- `draft \u2192 archived` \u2014 discard an unstarted experiment.",
516
+ "- `archived \u2192 draft` \u2014 restore a soft-deleted experiment so it can be re-completed and started. Allowed only if it never started; one that already ran must be cloned instead.",
509
517
  "",
510
- "Restarting an `archived` experiment is not allowed; clone instead. Returns `409` on illegal transitions and `429` if the plan's `experiments_running` limit is exceeded on `\u2192 running`."
518
+ "Restarting an `archived` experiment directly is not allowed \u2014 restore it to `draft` first. Returns `409` on illegal transitions and `429` if the plan's `experiments_running` limit is exceeded on `\u2192 running`."
511
519
  ].join("\n"),
512
520
  pathParams: { id: "Stable opaque experiment id." },
513
521
  request: experimentStatusUpdateSchema,
@@ -528,6 +536,11 @@ var experimentsResource = {
528
536
  summary: "Archive \u2014 stopped \u2192 archived",
529
537
  description: "Soft-deletes the experiment. List endpoints exclude archived rows by default.",
530
538
  value: { status: "archived" }
539
+ },
540
+ restore: {
541
+ summary: "Restore \u2014 archived \u2192 draft",
542
+ description: "Un-deletes a soft-deleted experiment so it can be re-completed and started. Allowed only if it never ran.",
543
+ value: { status: "draft" }
531
544
  }
532
545
  },
533
546
  response: { id: "exp_01j7wb12c3d4e5f6g7h8j9k0l1", status: "running" }
@@ -792,6 +792,9 @@ declare const RESOURCE_REGISTRY: readonly [{
792
792
  }, {
793
793
  readonly name: "archive";
794
794
  readonly description: "Archive a stopped experiment";
795
+ }, {
796
+ readonly name: "restore";
797
+ readonly description: "Restore an archived (never-started) experiment to draft";
795
798
  }, {
796
799
  readonly name: "reanalyze";
797
800
  readonly description: "Re-run analysis pass for the experiment";
@@ -1262,6 +1265,13 @@ declare const RESOURCE_REGISTRY: readonly [{
1262
1265
  readonly status: "archived";
1263
1266
  };
1264
1267
  };
1268
+ readonly restore: {
1269
+ readonly summary: "Restore — archived → draft";
1270
+ readonly description: "Un-deletes a soft-deleted experiment so it can be re-completed and started. Allowed only if it never ran.";
1271
+ readonly value: {
1272
+ readonly status: "draft";
1273
+ };
1274
+ };
1265
1275
  };
1266
1276
  readonly response: {
1267
1277
  readonly id: "exp_01j7wb12c3d4e5f6g7h8j9k0l1";
@@ -602,7 +602,7 @@ var experimentUpdateSchema = z5.object({
602
602
  );
603
603
  var experimentStatusUpdateSchema = z5.object({
604
604
  status: z5.enum(["draft", "running", "stopped", "archived"]).describe(
605
- "Target status. Allowed transitions: `draft \u2192 running`, `running \u2192 stopped`, `stopped \u2192 archived`, `draft \u2192 archived`. Restarting an archived experiment is not allowed."
605
+ "Target status. Allowed transitions: `draft \u2192 running`, `running \u2192 stopped`, `stopped \u2192 archived`, `draft \u2192 archived`, and `archived \u2192 draft` (restore \u2014 only if the experiment never started). Restarting an archived experiment directly is not allowed; restore it to draft first, then start."
606
606
  )
607
607
  }).describe("Body for `POST /api/admin/experiments/{id}/status`.");
608
608
  var experimentMetricsUpdateSchema = z5.object({
@@ -707,24 +707,29 @@ function experimentsClient(t) {
707
707
  if (opts.cursor) query.cursor = opts.cursor;
708
708
  return t.request("GET", BASE2, void 0, query);
709
709
  }
710
- async function listAll() {
710
+ async function listAllWith(status) {
711
711
  const out = [];
712
712
  let cursor;
713
713
  do {
714
- const page = await list({ limit: 500, cursor });
714
+ const query = { limit: "500" };
715
+ if (cursor) query.cursor = cursor;
716
+ if (status) query.status = status;
717
+ const page = await t.request("GET", BASE2, void 0, query);
715
718
  out.push(...page.data);
716
719
  cursor = page.next_cursor ?? void 0;
717
720
  } while (cursor);
718
721
  return out;
719
722
  }
723
+ async function listAll() {
724
+ return listAllWith();
725
+ }
720
726
  async function resolve(idOrName) {
721
727
  try {
722
728
  return await t.request("GET", `${BASE2}/${idOrName}`);
723
729
  } catch (err) {
724
730
  if (!(err instanceof ApiError) || err.status !== 404) throw err;
725
731
  }
726
- const all = await listAll();
727
- const found = all.find((e) => e.name === idOrName);
732
+ const found = (await listAllWith()).find((e) => e.name === idOrName) ?? (await listAllWith("archived")).find((e) => e.name === idOrName);
728
733
  if (!found) throw new ApiError(`Experiment '${idOrName}' not found`, 404);
729
734
  return found;
730
735
  }
@@ -747,6 +752,7 @@ function experimentsClient(t) {
747
752
  start: (id) => setStatus(id, "running"),
748
753
  stop: (id) => setStatus(id, "stopped"),
749
754
  archive: (id) => setStatus(id, "archived"),
755
+ restore: (id) => setStatus(id, "draft"),
750
756
  setMetrics: (id, input) => t.request("POST", `${BASE2}/${id}/metrics`, experimentMetricsUpdateSchema.parse(input)),
751
757
  results: (id) => t.request("GET", `${BASE2}/${id}/results`),
752
758
  timeseries: (id, metric) => t.request(
@@ -793,7 +799,7 @@ var experimentsResource = {
793
799
  "",
794
800
  "**Identity.** Stable `name` (a-z, 0-9, `_`/`-`, max 64 chars). Immutable after create.",
795
801
  "",
796
- "**Lifecycle.** `draft \u2192 running \u2192 stopped \u2192 archived`. Transition via `POST /{id}/status`. Restarting an archived experiment is not allowed.",
802
+ "**Lifecycle.** `draft \u2192 running \u2192 stopped \u2192 archived`. Transition via `POST /{id}/status`. An archived experiment that never started can be restored with `archived \u2192 draft`; restarting an archived experiment directly is not allowed.",
797
803
  "",
798
804
  "**Allocation.** `allocation_pct` (basis points, 0\u201310000) is the share of the targeted audience enrolled; `groups[].weight` (must sum to 10000) splits the enrolled audience. `targeting_gate` narrows the eligible audience before allocation.",
799
805
  "",
@@ -812,6 +818,7 @@ var experimentsResource = {
812
818
  { name: "start", description: "Transition draft experiment to running" },
813
819
  { name: "stop", description: "Stop a running experiment" },
814
820
  { name: "archive", description: "Archive a stopped experiment" },
821
+ { name: "restore", description: "Restore an archived (never-started) experiment to draft" },
815
822
  { name: "reanalyze", description: "Re-run analysis pass for the experiment" }
816
823
  ],
817
824
  endpoints: [
@@ -992,8 +999,9 @@ var experimentsResource = {
992
999
  "- `running \u2192 stopped` \u2014 halts allocation. Existing exposures stay in the dataset.",
993
1000
  "- `stopped \u2192 archived` \u2014 soft-delete.",
994
1001
  "- `draft \u2192 archived` \u2014 discard an unstarted experiment.",
1002
+ "- `archived \u2192 draft` \u2014 restore a soft-deleted experiment so it can be re-completed and started. Allowed only if it never started; one that already ran must be cloned instead.",
995
1003
  "",
996
- "Restarting an `archived` experiment is not allowed; clone instead. Returns `409` on illegal transitions and `429` if the plan's `experiments_running` limit is exceeded on `\u2192 running`."
1004
+ "Restarting an `archived` experiment directly is not allowed \u2014 restore it to `draft` first. Returns `409` on illegal transitions and `429` if the plan's `experiments_running` limit is exceeded on `\u2192 running`."
997
1005
  ].join("\n"),
998
1006
  pathParams: { id: "Stable opaque experiment id." },
999
1007
  request: experimentStatusUpdateSchema,
@@ -1014,6 +1022,11 @@ var experimentsResource = {
1014
1022
  summary: "Archive \u2014 stopped \u2192 archived",
1015
1023
  description: "Soft-deletes the experiment. List endpoints exclude archived rows by default.",
1016
1024
  value: { status: "archived" }
1025
+ },
1026
+ restore: {
1027
+ summary: "Restore \u2014 archived \u2192 draft",
1028
+ description: "Un-deletes a soft-deleted experiment so it can be re-completed and started. Allowed only if it never ran.",
1029
+ value: { status: "draft" }
1017
1030
  }
1018
1031
  },
1019
1032
  response: { id: "exp_01j7wb12c3d4e5f6g7h8j9k0l1", status: "running" }
@@ -103,7 +103,7 @@ var experimentUpdateSchema = z3.object({
103
103
  );
104
104
  var experimentStatusUpdateSchema = z3.object({
105
105
  status: z3.enum(["draft", "running", "stopped", "archived"]).describe(
106
- "Target status. Allowed transitions: `draft \u2192 running`, `running \u2192 stopped`, `stopped \u2192 archived`, `draft \u2192 archived`. Restarting an archived experiment is not allowed."
106
+ "Target status. Allowed transitions: `draft \u2192 running`, `running \u2192 stopped`, `stopped \u2192 archived`, `draft \u2192 archived`, and `archived \u2192 draft` (restore \u2014 only if the experiment never started). Restarting an archived experiment directly is not allowed; restore it to draft first, then start."
107
107
  )
108
108
  }).describe("Body for `POST /api/admin/experiments/{id}/status`.");
109
109
  var experimentMetricsUpdateSchema = z3.object({
@@ -530,7 +530,7 @@ var experimentUpdateSchema = z8.object({
530
530
  );
531
531
  var experimentStatusUpdateSchema = z8.object({
532
532
  status: z8.enum(["draft", "running", "stopped", "archived"]).describe(
533
- "Target status. Allowed transitions: `draft \u2192 running`, `running \u2192 stopped`, `stopped \u2192 archived`, `draft \u2192 archived`. Restarting an archived experiment is not allowed."
533
+ "Target status. Allowed transitions: `draft \u2192 running`, `running \u2192 stopped`, `stopped \u2192 archived`, `draft \u2192 archived`, and `archived \u2192 draft` (restore \u2014 only if the experiment never started). Restarting an archived experiment directly is not allowed; restore it to draft first, then start."
534
534
  )
535
535
  }).describe("Body for `POST /api/admin/experiments/{id}/status`.");
536
536
  var experimentMetricsUpdateSchema = z8.object({