@shipeasy/openapi 1.0.0 → 1.1.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.
Files changed (39) hide show
  1. package/dist/index.d.ts +9 -7
  2. package/dist/index.js +484 -2665
  3. package/dist/resources/alert-rules.d.ts +48 -0
  4. package/dist/resources/alert-rules.js +66 -0
  5. package/dist/resources/configs.d.ts +6 -2
  6. package/dist/resources/configs.js +67 -2375
  7. package/dist/resources/experiments.d.ts +88 -2
  8. package/dist/resources/experiments.js +138 -98
  9. package/dist/resources/gates.d.ts +51 -8
  10. package/dist/resources/gates.js +102 -70
  11. package/dist/resources/index.d.ts +156 -10
  12. package/dist/resources/index.js +483 -2664
  13. package/dist/resources/killswitches.d.ts +6 -2
  14. package/dist/resources/killswitches.js +113 -2412
  15. package/dist/resources/universes.d.ts +7 -4
  16. package/dist/resources/universes.js +30 -20
  17. package/dist/schemas/alert-rules.d.ts +43 -0
  18. package/dist/schemas/alert-rules.js +27 -0
  19. package/dist/schemas/configs.d.ts +154 -0
  20. package/dist/schemas/configs.js +134 -0
  21. package/dist/schemas/constants.d.ts +6 -0
  22. package/dist/schemas/constants.js +7 -0
  23. package/dist/schemas/experiments.d.ts +245 -0
  24. package/dist/schemas/experiments.js +216 -0
  25. package/dist/schemas/folder.d.ts +10 -0
  26. package/dist/schemas/folder.js +8 -0
  27. package/dist/schemas/gates.d.ts +304 -0
  28. package/dist/schemas/gates.js +172 -0
  29. package/dist/schemas/index.d.ts +11 -0
  30. package/dist/schemas/index.js +729 -0
  31. package/dist/schemas/killswitches.d.ts +110 -0
  32. package/dist/schemas/killswitches.js +226 -0
  33. package/dist/schemas/metric-name.d.ts +5 -0
  34. package/dist/schemas/metric-name.js +6 -0
  35. package/dist/schemas/pagination.d.ts +37 -0
  36. package/dist/schemas/pagination.js +44 -0
  37. package/dist/schemas/universes.d.ts +35 -0
  38. package/dist/schemas/universes.js +55 -0
  39. package/package.json +13 -10
@@ -0,0 +1,110 @@
1
+ import { z } from 'zod';
2
+
3
+ /** A switch key is a single lowercase segment (no dots). */
4
+ declare const SWITCH_KEY_RE: RegExp;
5
+ declare const switchKeySchema: z.ZodString;
6
+ /** The fixed runtime payload delivered to clients:
7
+ *
8
+ * { value: <bool>, switches?: { <switch_key>: <bool>, … } }
9
+ *
10
+ * `switches` is optional. When present, an entry takes precedence over `value`
11
+ * for that specific switch_key on the client. */
12
+ declare const killswitchValueSchema: z.ZodObject<{
13
+ value: z.ZodBoolean;
14
+ switches: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodBoolean>>;
15
+ }, z.core.$strip>;
16
+ type KillswitchValue = z.infer<typeof killswitchValueSchema>;
17
+ declare const killswitchCreateSchema: z.ZodObject<{
18
+ name: z.ZodString;
19
+ description: z.ZodOptional<z.ZodString>;
20
+ folder: z.ZodOptional<z.ZodNullable<z.ZodString>>;
21
+ value: z.ZodOptional<z.ZodBoolean>;
22
+ switches: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodBoolean>>;
23
+ }, z.core.$strip>;
24
+ declare const killswitchUpdateSchema: z.ZodObject<{
25
+ description: z.ZodOptional<z.ZodNullable<z.ZodString>>;
26
+ folder: z.ZodOptional<z.ZodNullable<z.ZodString>>;
27
+ value: z.ZodOptional<z.ZodBoolean>;
28
+ switches: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodBoolean>>;
29
+ }, z.core.$strip>;
30
+ /** PUT one switch entry on one env. */
31
+ declare const killswitchSwitchSetSchema: z.ZodObject<{
32
+ env: z.ZodEnum<{
33
+ dev: "dev";
34
+ staging: "staging";
35
+ prod: "prod";
36
+ }>;
37
+ switchKey: z.ZodString;
38
+ value: z.ZodBoolean;
39
+ }, z.core.$strip>;
40
+ /** PATCH the flat default value for one env (dashboard quick-toggle). */
41
+ declare const killswitchValueSetSchema: z.ZodObject<{
42
+ env: z.ZodEnum<{
43
+ dev: "dev";
44
+ staging: "staging";
45
+ prod: "prod";
46
+ }>;
47
+ value: z.ZodBoolean;
48
+ }, z.core.$strip>;
49
+ /** DELETE one switch entry on one env. */
50
+ declare const killswitchSwitchUnsetSchema: z.ZodObject<{
51
+ env: z.ZodEnum<{
52
+ dev: "dev";
53
+ staging: "staging";
54
+ prod: "prod";
55
+ }>;
56
+ switchKey: z.ZodString;
57
+ }, z.core.$strip>;
58
+ declare const killswitchResponseSchema: z.ZodObject<{
59
+ id: z.ZodString;
60
+ name: z.ZodString;
61
+ description: z.ZodNullable<z.ZodString>;
62
+ updatedAt: z.ZodString;
63
+ envs: z.ZodRecord<z.ZodEnum<{
64
+ dev: "dev";
65
+ staging: "staging";
66
+ prod: "prod";
67
+ }>, z.ZodObject<{
68
+ value: z.ZodBoolean;
69
+ switches: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodBoolean>>;
70
+ version: z.ZodNumber;
71
+ publishedAt: z.ZodString;
72
+ }, z.core.$strip>>;
73
+ }, z.core.$strip>;
74
+ declare const killswitchCreateResponseSchema: z.ZodObject<{
75
+ id: z.ZodString;
76
+ name: z.ZodString;
77
+ }, z.core.$strip>;
78
+ declare const killswitchUpdateResponseSchema: z.ZodObject<{
79
+ id: z.ZodString;
80
+ }, z.core.$strip>;
81
+ declare const killswitchDeleteResponseSchema: z.ZodObject<{
82
+ ok: z.ZodLiteral<true>;
83
+ }, z.core.$strip>;
84
+ declare const killswitchSwitchSetResponseSchema: z.ZodObject<{
85
+ id: z.ZodString;
86
+ env: z.ZodEnum<{
87
+ dev: "dev";
88
+ staging: "staging";
89
+ prod: "prod";
90
+ }>;
91
+ switchKey: z.ZodString;
92
+ value: z.ZodBoolean;
93
+ }, z.core.$strip>;
94
+ declare const killswitchSwitchUnsetResponseSchema: z.ZodObject<{
95
+ id: z.ZodString;
96
+ env: z.ZodEnum<{
97
+ dev: "dev";
98
+ staging: "staging";
99
+ prod: "prod";
100
+ }>;
101
+ switchKey: z.ZodString;
102
+ removed: z.ZodBoolean;
103
+ }, z.core.$strip>;
104
+ type KillswitchCreateInput = z.infer<typeof killswitchCreateSchema>;
105
+ type KillswitchUpdateInput = z.infer<typeof killswitchUpdateSchema>;
106
+ type KillswitchSwitchSetInput = z.infer<typeof killswitchSwitchSetSchema>;
107
+ type KillswitchValueSetInput = z.infer<typeof killswitchValueSetSchema>;
108
+ type KillswitchSwitchUnsetInput = z.infer<typeof killswitchSwitchUnsetSchema>;
109
+
110
+ export { type KillswitchCreateInput, type KillswitchSwitchSetInput, type KillswitchSwitchUnsetInput, type KillswitchUpdateInput, type KillswitchValue, type KillswitchValueSetInput, SWITCH_KEY_RE, killswitchCreateResponseSchema, killswitchCreateSchema, killswitchDeleteResponseSchema, killswitchResponseSchema, killswitchSwitchSetResponseSchema, killswitchSwitchSetSchema, killswitchSwitchUnsetResponseSchema, killswitchSwitchUnsetSchema, killswitchUpdateResponseSchema, killswitchUpdateSchema, killswitchValueSchema, killswitchValueSetSchema, switchKeySchema };
@@ -0,0 +1,226 @@
1
+ // src/schemas/killswitches.ts
2
+ import { z as z3 } from "zod";
3
+
4
+ // src/schemas/configs.ts
5
+ import { z as z2 } from "zod";
6
+
7
+ // src/schemas/constants.ts
8
+ var CONFIG_ENVS = ["dev", "staging", "prod"];
9
+ var CONFIG_KINDS = ["config", "killswitch"];
10
+
11
+ // src/schemas/folder.ts
12
+ import { z } from "zod";
13
+ var folderSchema = z.string().max(256).regex(/^[a-zA-Z0-9_-]+$/, "Folder must be alphanumeric, `_` or `-` (no `/`).").nullable().optional().describe(
14
+ "Optional folder name used to group items in the dashboard. Part of the SDK lookup key: an item in folder `checkout` named `new-cart` is referenced as `checkout/new-cart` from the SDK."
15
+ );
16
+
17
+ // src/schemas/configs.ts
18
+ var SEGMENT = /^[a-z0-9](?:[a-z0-9_-]*[a-z0-9])?$/;
19
+ var RESERVED_FOLDER = "_default";
20
+ var configNameSchema = z2.string().max(128).refine(
21
+ (s) => {
22
+ const parts = s.split(".");
23
+ if (parts.length !== 2) return false;
24
+ return parts.every((p, i) => p === RESERVED_FOLDER && i === 0 ? true : SEGMENT.test(p));
25
+ },
26
+ {
27
+ message: "Must be `folder.name` \u2014 exactly two lowercase segments separated by a dot (e.g. `pricing.tiers`)."
28
+ }
29
+ ).describe(
30
+ "Stable config key in `folder.name` form (two lowercase segments separated by a dot, e.g. `pricing.tiers`). Used by SDKs as `Shipeasy.getConfig('<name>')`. Immutable after create."
31
+ );
32
+ var configKindSchema = z2.enum(CONFIG_KINDS);
33
+ var configEnvSchema = z2.enum(CONFIG_ENVS).describe("Target environment. One of the project's configured envs (`dev`, `stage`, `prod`).");
34
+ var jsonSchemaSchema = z2.record(z2.string(), z2.unknown()).refine((s) => s.type === "object", { message: "Top-level schema type must be 'object'" }).describe(
35
+ "JSON Schema (draft 2020-12) describing the shape of the config value. Top-level `type` must be `'object'`; every published value is validated against this schema."
36
+ );
37
+ var initialValuesSchema = z2.union([z2.unknown(), z2.record(configEnvSchema, z2.unknown())]).describe(
38
+ "Initial config value. Either a single JSON object applied to every env, or a `{ env: value }` map seeding per-env values. Must match `schema`. Defaults to `{}` on every env when omitted."
39
+ );
40
+ var configCreateSchema = z2.object({
41
+ name: configNameSchema,
42
+ description: z2.string().max(512).optional().describe("Optional free-form description shown in the dashboard. Max 512 chars."),
43
+ folder: folderSchema,
44
+ schema: jsonSchemaSchema,
45
+ value: initialValuesSchema.optional()
46
+ }).describe("Body for `POST /api/admin/configs`. `name` + `schema` required.");
47
+ var configUpdateSchema = z2.object({
48
+ schema: jsonSchemaSchema.optional().describe(
49
+ "Replacement schema. When supplied, the new schema is validated against every published value before it lands."
50
+ ),
51
+ value: z2.unknown().optional().describe(
52
+ "Flat value applied to **every** env. Publishes a new version per env. To target one env, use `PUT /{id}/drafts` then `POST /{id}/publish`."
53
+ ),
54
+ folder: folderSchema
55
+ }).describe(
56
+ "Body for `PATCH /api/admin/configs/{id}`. Partial \u2014 only supplied fields change. `value` republishes on every env."
57
+ );
58
+ var configSchemaUpdateSchema = z2.object({ schema: jsonSchemaSchema }).describe("Schema-only update. Does not bump value versions or rebuild KV.");
59
+ var configDraftUpsertSchema = z2.object({
60
+ env: configEnvSchema,
61
+ value: z2.unknown().describe("Draft value to stage on `env`. Validated against the config's current schema.")
62
+ }).describe(
63
+ "Body for `PUT /api/admin/configs/{id}/drafts`. Stages a value for a single env without publishing."
64
+ );
65
+ var configPublishSchema = z2.object({ env: configEnvSchema }).describe(
66
+ "Body for `POST /api/admin/configs/{id}/publish` and `DELETE /api/admin/configs/{id}/drafts`. Names the target env."
67
+ );
68
+ var configEnvPublishedSchema = z2.object({
69
+ version: z2.number().int().describe("Monotonically increasing version per env."),
70
+ publishedAt: z2.string().describe("ISO-8601 publish timestamp."),
71
+ publishedBy: z2.string().describe("Email/id of the actor who published this version.")
72
+ });
73
+ var configDraftSummarySchema = z2.object({
74
+ updatedAt: z2.string().describe("ISO-8601 last-edit timestamp on the draft."),
75
+ authorEmail: z2.string().describe("Email/id of the actor who last edited the draft."),
76
+ baseVersion: z2.number().int().describe("Published version the draft was forked from.")
77
+ });
78
+ var configResponseSchema = z2.object({
79
+ id: z2.string().describe("Stable opaque config id (`cfg_\u2026`)."),
80
+ name: configNameSchema,
81
+ description: z2.string().nullable(),
82
+ schema: jsonSchemaSchema,
83
+ updatedAt: z2.string().describe("ISO-8601 timestamp of last mutation."),
84
+ envs: z2.record(configEnvSchema, configEnvPublishedSchema).describe("Per-env latest published version metadata."),
85
+ drafts: z2.record(configEnvSchema, configDraftSummarySchema).describe("Per-env active drafts (if any)."),
86
+ values: z2.record(configEnvSchema, z2.unknown()).optional().describe("Per-env latest published values (only returned by `GET /{id}`, not list)."),
87
+ draftValues: z2.record(configEnvSchema, z2.unknown()).optional().describe("Per-env draft values (only returned by `GET /{id}`).")
88
+ });
89
+ var configCreateResponseSchema = z2.object({
90
+ id: z2.string().describe("Newly assigned config id."),
91
+ name: configNameSchema
92
+ });
93
+ var configUpdateResponseSchema = z2.object({
94
+ id: z2.string().describe("Config id that was updated.")
95
+ });
96
+ var configDeleteResponseSchema = z2.object({ ok: z2.literal(true) });
97
+ var configDraftSaveResponseSchema = z2.object({
98
+ id: z2.string(),
99
+ env: configEnvSchema,
100
+ baseVersion: z2.number().int().describe("Published version the draft is based on."),
101
+ updatedAt: z2.string()
102
+ });
103
+ var configDraftDiscardResponseSchema = z2.object({ ok: z2.literal(true) });
104
+ var configPublishResponseSchema = z2.object({
105
+ id: z2.string(),
106
+ env: configEnvSchema,
107
+ version: z2.number().int().describe("Newly published version on `env`.")
108
+ });
109
+ var configActivityEntrySchema = z2.object({
110
+ id: z2.string(),
111
+ action: z2.string().describe("Audit action (e.g. `config.create`, `config.publish`)."),
112
+ actorEmail: z2.string(),
113
+ actorType: z2.enum(["user", "cli", "system"]),
114
+ payload: z2.unknown().nullable(),
115
+ createdAt: z2.string().describe("ISO-8601 timestamp.")
116
+ });
117
+ var configActivityResponseSchema = z2.array(configActivityEntrySchema).describe("Recent audit rows for one config, newest first.");
118
+
119
+ // src/schemas/killswitches.ts
120
+ var SWITCH_KEY_RE = /^[a-z0-9](?:[a-z0-9_-]*[a-z0-9])?$/;
121
+ var switchKeySchema = z3.string().max(64).regex(SWITCH_KEY_RE, {
122
+ message: "Switch keys must be lowercase, no dots."
123
+ }).describe(
124
+ "Single-segment switch key (lowercase letters, digits, `_`/`-`; no dots). Used as the nested switch entry inside a killswitch's `switches` map."
125
+ );
126
+ var killswitchValueSchema = z3.object({
127
+ value: z3.boolean().describe(
128
+ "Default boolean delivered when no `switches` entry matches the caller's switch key."
129
+ ),
130
+ switches: z3.record(switchKeySchema, z3.boolean()).optional().describe(
131
+ "Per-switch overrides. When present, a matching key takes precedence over `value` on the client."
132
+ )
133
+ }).describe("Runtime killswitch payload returned to SDKs.");
134
+ var killswitchCreateSchema = z3.object({
135
+ name: configNameSchema.describe(
136
+ "Stable killswitch key in `folder.name` form (two lowercase segments separated by a dot \u2014 e.g. `payments.checkout`). Immutable after create."
137
+ ),
138
+ description: z3.string().max(512).optional().describe("Optional free-form description shown in the dashboard. Max 512 chars."),
139
+ folder: folderSchema,
140
+ value: z3.boolean().optional().describe(
141
+ "Default value applied to every env at creation. Defaults to `false`. Use `true` to ship the killswitch pre-tripped."
142
+ ),
143
+ switches: z3.record(switchKeySchema, z3.boolean()).optional().describe(
144
+ "Initial per-switch overrides applied to every env. Empty/omitted leaves the killswitch with only the flat `value`."
145
+ )
146
+ }).describe("Body for `POST /api/admin/killswitches`. Only `name` is required.");
147
+ var killswitchUpdateSchema = z3.object({
148
+ description: z3.string().max(512).nullish().describe("New description, or `null` to clear it. Max 512 chars."),
149
+ folder: folderSchema,
150
+ value: z3.boolean().optional().describe(
151
+ "Flat value applied to every env. Publishes a new version per env when set. Omit to leave values unchanged."
152
+ ),
153
+ switches: z3.record(switchKeySchema, z3.boolean()).optional().describe(
154
+ "Replace the switches map wholesale on every env. To edit a single entry on a single env use `PUT /{id}/switch` instead."
155
+ )
156
+ }).describe(
157
+ "Body for `PATCH /api/admin/killswitches/{id}`. Partial \u2014 only supplied fields change. `switches` replaces wholesale (no merge)."
158
+ );
159
+ var killswitchSwitchSetSchema = z3.object({
160
+ env: configEnvSchema.describe("Target environment (`dev`/`stage`/`prod`)."),
161
+ switchKey: switchKeySchema.describe("Switch key to set."),
162
+ value: z3.boolean().describe("New boolean value for this `switchKey` on this `env`.")
163
+ }).describe(
164
+ "Body for `PUT /api/admin/killswitches/{id}/switch`. Sets or updates one switch entry on one env."
165
+ );
166
+ var killswitchValueSetSchema = z3.object({
167
+ env: configEnvSchema.describe("Target environment whose flat default flips."),
168
+ value: z3.boolean().describe("New flat default for this env. Existing switches carry forward unchanged.")
169
+ }).describe(
170
+ "Body for the killswitch quick-toggle. Sets the flat `value` on one env without touching its switches."
171
+ );
172
+ var killswitchSwitchUnsetSchema = z3.object({
173
+ env: configEnvSchema.describe("Target environment."),
174
+ switchKey: switchKeySchema.describe("Switch key to remove.")
175
+ }).describe(
176
+ "Body for `DELETE /api/admin/killswitches/{id}/switch`. Removes one switch entry from one env."
177
+ );
178
+ var killswitchEnvEntrySchema = z3.object({
179
+ value: z3.boolean().describe("Flat boolean published for this env."),
180
+ switches: z3.record(switchKeySchema, z3.boolean()).optional(),
181
+ version: z3.number().int().describe("Monotonically increasing version per env."),
182
+ publishedAt: z3.string().describe("ISO-8601 publish timestamp for this version.")
183
+ });
184
+ var killswitchResponseSchema = z3.object({
185
+ id: z3.string().describe("Stable opaque killswitch id."),
186
+ name: configNameSchema,
187
+ description: z3.string().nullable().describe("Free-form description or `null`."),
188
+ updatedAt: z3.string().describe("ISO-8601 timestamp of last mutation."),
189
+ envs: z3.record(configEnvSchema, killswitchEnvEntrySchema).describe("Per-env latest value, switches, version, and publish timestamp.")
190
+ });
191
+ var killswitchCreateResponseSchema = z3.object({
192
+ id: z3.string().describe("Newly assigned killswitch id."),
193
+ name: configNameSchema
194
+ });
195
+ var killswitchUpdateResponseSchema = z3.object({
196
+ id: z3.string().describe("Killswitch id that was updated.")
197
+ });
198
+ var killswitchDeleteResponseSchema = z3.object({ ok: z3.literal(true) });
199
+ var killswitchSwitchSetResponseSchema = z3.object({
200
+ id: z3.string(),
201
+ env: configEnvSchema,
202
+ switchKey: switchKeySchema,
203
+ value: z3.boolean()
204
+ });
205
+ var killswitchSwitchUnsetResponseSchema = z3.object({
206
+ id: z3.string(),
207
+ env: configEnvSchema,
208
+ switchKey: switchKeySchema,
209
+ removed: z3.boolean().describe("`true` if the entry existed and was removed, `false` if no-op.")
210
+ });
211
+ export {
212
+ SWITCH_KEY_RE,
213
+ killswitchCreateResponseSchema,
214
+ killswitchCreateSchema,
215
+ killswitchDeleteResponseSchema,
216
+ killswitchResponseSchema,
217
+ killswitchSwitchSetResponseSchema,
218
+ killswitchSwitchSetSchema,
219
+ killswitchSwitchUnsetResponseSchema,
220
+ killswitchSwitchUnsetSchema,
221
+ killswitchUpdateResponseSchema,
222
+ killswitchUpdateSchema,
223
+ killswitchValueSchema,
224
+ killswitchValueSetSchema,
225
+ switchKeySchema
226
+ };
@@ -0,0 +1,5 @@
1
+ import { z } from 'zod';
2
+
3
+ declare const metricNameSchema: z.ZodString;
4
+
5
+ export { metricNameSchema };
@@ -0,0 +1,6 @@
1
+ // src/schemas/metric-name.ts
2
+ import { z } from "zod";
3
+ var metricNameSchema = z.string().regex(/^[a-z0-9](?:[a-z0-9_-]*[a-z0-9])?(?:\.[a-z0-9](?:[a-z0-9_-]*[a-z0-9])?)?$/).max(128);
4
+ export {
5
+ metricNameSchema
6
+ };
@@ -0,0 +1,37 @@
1
+ import { z } from 'zod';
2
+
3
+ declare const DEFAULT_PAGE_SIZE = 100;
4
+ declare const MAX_PAGE_SIZE = 500;
5
+ /**
6
+ * Query params for any paginated list endpoint. `cursor` is opaque to
7
+ * consumers; servers encode/decode via {@link encodeCursor}/{@link decodeCursor}.
8
+ */
9
+ declare const pageQuerySchema: z.ZodObject<{
10
+ limit: z.ZodDefault<z.ZodCoercedNumber<unknown>>;
11
+ cursor: z.ZodOptional<z.ZodString>;
12
+ }, z.core.$strip>;
13
+ type PageQuery = z.infer<typeof pageQuerySchema>;
14
+ /** Standard envelope every paginated list endpoint returns. */
15
+ interface Page<T> {
16
+ data: T[];
17
+ next_cursor: string | null;
18
+ }
19
+ /**
20
+ * Cursor encodes the `(ts, id)` tuple of the last row from the previous page.
21
+ * `ts` is whichever ISO-8601 timestamp column the resource sorts by — most
22
+ * resources use `updated_at`, but ones that lack it (universes, sdk_keys) use
23
+ * `created_at`. Sort order is always `ORDER BY <ts> DESC, id DESC`; keyset
24
+ * comparison is `(ts, id) < (cursor.ts, cursor.id)`. ISO-8601 text sorts
25
+ * lexicographically, so string comparison is correct.
26
+ *
27
+ * The cursor is opaque to SDK consumers — only the server (which encodes) and
28
+ * the client transport (which round-trips it) need to know the structure.
29
+ */
30
+ interface CursorParts {
31
+ ts: string;
32
+ id: string;
33
+ }
34
+ declare function encodeCursor(parts: CursorParts): string;
35
+ declare function decodeCursor(cursor: string): CursorParts;
36
+
37
+ export { type CursorParts, DEFAULT_PAGE_SIZE, MAX_PAGE_SIZE, type Page, type PageQuery, decodeCursor, encodeCursor, pageQuerySchema };
@@ -0,0 +1,44 @@
1
+ // src/schemas/pagination.ts
2
+ import { z } from "zod";
3
+ var DEFAULT_PAGE_SIZE = 100;
4
+ var MAX_PAGE_SIZE = 500;
5
+ var pageQuerySchema = z.object({
6
+ limit: z.coerce.number().int().min(1).max(MAX_PAGE_SIZE).default(DEFAULT_PAGE_SIZE),
7
+ cursor: z.string().min(1).optional()
8
+ });
9
+ var SEP = "|";
10
+ function encodeCursor(parts) {
11
+ if (parts.ts.includes(SEP)) {
12
+ throw new Error(`pagination: ts must not contain '${SEP}'`);
13
+ }
14
+ return base64UrlEncode(`${parts.ts}${SEP}${parts.id}`);
15
+ }
16
+ function decodeCursor(cursor) {
17
+ let raw;
18
+ try {
19
+ raw = base64UrlDecode(cursor);
20
+ } catch {
21
+ throw new Error("pagination: cursor is not valid base64url");
22
+ }
23
+ const sep = raw.indexOf(SEP);
24
+ if (sep < 0) throw new Error("pagination: cursor missing separator");
25
+ const ts = raw.slice(0, sep);
26
+ const id = raw.slice(sep + 1);
27
+ if (!ts || !id) throw new Error("pagination: cursor parts empty");
28
+ return { ts, id };
29
+ }
30
+ function base64UrlEncode(s) {
31
+ const b64 = btoa(s);
32
+ return b64.replace(/\+/g, "-").replace(/\//g, "_").replace(/=+$/, "");
33
+ }
34
+ function base64UrlDecode(s) {
35
+ const pad = s.length % 4 === 0 ? "" : "=".repeat(4 - s.length % 4);
36
+ return atob(s.replace(/-/g, "+").replace(/_/g, "/") + pad);
37
+ }
38
+ export {
39
+ DEFAULT_PAGE_SIZE,
40
+ MAX_PAGE_SIZE,
41
+ decodeCursor,
42
+ encodeCursor,
43
+ pageQuerySchema
44
+ };
@@ -0,0 +1,35 @@
1
+ import { z } from 'zod';
2
+
3
+ declare const universeNameSchema: z.ZodString;
4
+ declare const holdoutRangeSchema: z.ZodNullable<z.ZodTuple<[z.ZodNumber, z.ZodNumber], null>>;
5
+ declare const universeCreateSchema: z.ZodObject<{
6
+ name: z.ZodString;
7
+ folder: z.ZodOptional<z.ZodNullable<z.ZodString>>;
8
+ unit_type: z.ZodDefault<z.ZodString>;
9
+ holdout_range: z.ZodDefault<z.ZodNullable<z.ZodTuple<[z.ZodNumber, z.ZodNumber], null>>>;
10
+ }, z.core.$strip>;
11
+ declare const universeUpdateSchema: z.ZodObject<{
12
+ folder: z.ZodOptional<z.ZodNullable<z.ZodString>>;
13
+ holdout_range: z.ZodOptional<z.ZodNullable<z.ZodTuple<[z.ZodNumber, z.ZodNumber], null>>>;
14
+ }, z.core.$strip>;
15
+ declare const universeResponseSchema: z.ZodObject<{
16
+ id: z.ZodString;
17
+ name: z.ZodString;
18
+ unitType: z.ZodString;
19
+ holdoutRange: z.ZodNullable<z.ZodTuple<[z.ZodNumber, z.ZodNumber], null>>;
20
+ createdAt: z.ZodString;
21
+ }, z.core.$strip>;
22
+ declare const universeCreateResponseSchema: z.ZodObject<{
23
+ id: z.ZodString;
24
+ name: z.ZodString;
25
+ }, z.core.$strip>;
26
+ declare const universeUpdateResponseSchema: z.ZodObject<{
27
+ id: z.ZodString;
28
+ }, z.core.$strip>;
29
+ declare const universeDeleteResponseSchema: z.ZodObject<{
30
+ ok: z.ZodLiteral<true>;
31
+ }, z.core.$strip>;
32
+ type UniverseCreateInput = z.infer<typeof universeCreateSchema>;
33
+ type UniverseUpdateInput = z.infer<typeof universeUpdateSchema>;
34
+
35
+ export { type UniverseCreateInput, type UniverseUpdateInput, holdoutRangeSchema, universeCreateResponseSchema, universeCreateSchema, universeDeleteResponseSchema, universeNameSchema, universeResponseSchema, universeUpdateResponseSchema, universeUpdateSchema };
@@ -0,0 +1,55 @@
1
+ // src/schemas/universes.ts
2
+ import { z as z2 } from "zod";
3
+
4
+ // src/schemas/folder.ts
5
+ import { z } from "zod";
6
+ var folderSchema = z.string().max(256).regex(/^[a-zA-Z0-9_-]+$/, "Folder must be alphanumeric, `_` or `-` (no `/`).").nullable().optional().describe(
7
+ "Optional folder name used to group items in the dashboard. Part of the SDK lookup key: an item in folder `checkout` named `new-cart` is referenced as `checkout/new-cart` from the SDK."
8
+ );
9
+
10
+ // src/schemas/universes.ts
11
+ var universeNameSchema = z2.string().regex(/^[a-z0-9](?:[a-z0-9_-]*[a-z0-9])?(?:\.[a-z0-9](?:[a-z0-9_-]*[a-z0-9])?)?$/).max(128).describe(
12
+ "Stable universe key. Single segment or `folder.name`. Lowercase letters, digits, `_` or `-`; max 128 chars. Immutable after create."
13
+ );
14
+ var holdoutRangeSchema = z2.tuple([z2.number().int().min(0).max(9999), z2.number().int().min(0).max(9999)]).refine(([lo, hi]) => lo <= hi, "lo must be <= hi").nullable().describe(
15
+ "Inclusive `[lo, hi]` bucket range (0\u20139999) reserved as the **holdout** \u2014 callers hashed into this slice are excluded from every experiment in the universe. `null` disables the holdout. Pro plan or higher required."
16
+ );
17
+ var universeCreateSchema = z2.object({
18
+ name: universeNameSchema,
19
+ folder: folderSchema,
20
+ unit_type: z2.string().default("user_id").describe(
21
+ "Unit of randomisation. Typically `user_id`. Use `account_id` to keep whole accounts in the same group across an experiment."
22
+ ),
23
+ holdout_range: holdoutRangeSchema.default(null)
24
+ }).describe("Body for `POST /api/admin/universes`. Only `name` is required.");
25
+ var universeUpdateSchema = z2.object({
26
+ folder: folderSchema,
27
+ holdout_range: holdoutRangeSchema.optional()
28
+ }).describe(
29
+ "Body for `PATCH /api/admin/universes/{id}`. Only `holdout_range` is mutable \u2014 name and unit_type are immutable after create."
30
+ );
31
+ var universeResponseSchema = z2.object({
32
+ id: z2.string().describe("Stable opaque universe id."),
33
+ name: universeNameSchema,
34
+ unitType: z2.string().describe("Unit of randomisation. Snake-case in request (`unit_type`), camelCase in response."),
35
+ holdoutRange: z2.tuple([z2.number(), z2.number()]).nullable().describe("Reserved holdout bucket range, or `null` if none."),
36
+ createdAt: z2.string().describe("ISO-8601 timestamp of creation.")
37
+ });
38
+ var universeCreateResponseSchema = z2.object({
39
+ id: z2.string().describe("Newly assigned universe id."),
40
+ name: universeNameSchema
41
+ });
42
+ var universeUpdateResponseSchema = z2.object({
43
+ id: z2.string().describe("Universe id that was updated.")
44
+ });
45
+ var universeDeleteResponseSchema = z2.object({ ok: z2.literal(true) });
46
+ export {
47
+ holdoutRangeSchema,
48
+ universeCreateResponseSchema,
49
+ universeCreateSchema,
50
+ universeDeleteResponseSchema,
51
+ universeNameSchema,
52
+ universeResponseSchema,
53
+ universeUpdateResponseSchema,
54
+ universeUpdateSchema
55
+ };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@shipeasy/openapi",
3
- "version": "1.0.0",
3
+ "version": "1.1.0",
4
4
  "description": "Shipeasy admin OpenAPI spec + typed client. Single source of truth for endpoint paths, request/response shapes, and the resource registry consumed by @shipeasy/cli and @shipeasy/mcp.",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
@@ -22,6 +22,10 @@
22
22
  "types": "./dist/resources/*.d.ts",
23
23
  "default": "./dist/resources/*.js"
24
24
  },
25
+ "./schemas/*": {
26
+ "types": "./dist/schemas/*.d.ts",
27
+ "default": "./dist/schemas/*.js"
28
+ },
25
29
  "./transport": {
26
30
  "types": "./dist/transport.d.ts",
27
31
  "default": "./dist/transport.js"
@@ -35,6 +39,12 @@
35
39
  "dist/",
36
40
  "openapi.json"
37
41
  ],
42
+ "scripts": {
43
+ "build": "tsup",
44
+ "type-check": "tsc --noEmit",
45
+ "test": "vitest run",
46
+ "emit-openapi": "tsx scripts/emit-spec.ts"
47
+ },
38
48
  "dependencies": {
39
49
  "zod": "^4.0.0"
40
50
  },
@@ -43,16 +53,9 @@
43
53
  "tsup": "^8.3.0",
44
54
  "tsx": "^4.21.0",
45
55
  "typescript": "^5.7.4",
46
- "vitest": "^2.1.0",
47
- "@shipeasy/core": "1.0.0"
56
+ "vitest": "^2.1.0"
48
57
  },
49
58
  "engines": {
50
59
  "node": ">=20"
51
- },
52
- "scripts": {
53
- "build": "tsup",
54
- "type-check": "tsc --noEmit",
55
- "test": "vitest run",
56
- "emit-openapi": "tsx scripts/emit-spec.ts"
57
60
  }
58
- }
61
+ }