@peable.to/contracts 0.3.0 → 0.4.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/cjs/index.js CHANGED
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.contributionPatchSchema = exports.contributionOperationKeySchema = exports.contributionMintSchema = exports.contributionPageQuerySchema = exports.contributionCollectionListSchema = exports.contributionCollectionSchema = exports.contributionListSchema = exports.contributionLinkSchema = exports.createContributionSchema = exports.contributionDetailsSchema = exports.contributionAmountSchema = void 0;
3
+ exports.contributionPatchSchema = exports.contributionOperationKeySchema = exports.contributionMintSchema = exports.contributionPageQuerySchema = exports.listQueryShape = exports.contributionCollectionListSchema = exports.contributionCollectionSchema = exports.contributionListSchema = exports.contributionLinkSchema = exports.createContributionSchema = exports.contributionDetailsSchema = exports.contributionAmountSchema = void 0;
4
4
  exports.decimalContributionAmount = decimalContributionAmount;
5
5
  exports.formatContributionAmount = formatContributionAmount;
6
6
  const zod_1 = require("zod");
@@ -41,10 +41,17 @@ exports.contributionLinkSchema = zod_1.z
41
41
  created: unixSecondsSchema,
42
42
  })
43
43
  .strict();
44
- /** The one list envelope (ADR 0014 D1). */
44
+ /**
45
+ * The one list envelope (ADR 0014 D1): `url` is the path that was listed.
46
+ */
45
47
  function listSchema(item) {
46
48
  return zod_1.z
47
- .object({ object: zod_1.z.literal('list'), data: zod_1.z.array(item), has_more: zod_1.z.boolean() })
49
+ .object({
50
+ object: zod_1.z.literal('list'),
51
+ data: zod_1.z.array(item),
52
+ has_more: zod_1.z.boolean(),
53
+ url: zod_1.z.string(),
54
+ })
48
55
  .strict();
49
56
  }
50
57
  exports.contributionListSchema = listSchema(exports.contributionLinkSchema);
@@ -69,18 +76,51 @@ exports.contributionCollectionSchema = zod_1.z
69
76
  })
70
77
  .strict();
71
78
  exports.contributionCollectionListSchema = listSchema(exports.contributionCollectionSchema);
79
+ const unixSecondsQuery = zod_1.z.coerce.number().int().nonnegative();
80
+ /**
81
+ * The list parameters every list accepts (ADR 0014 D1), newest first:
82
+ *
83
+ * - `limit` 1–100, default 10;
84
+ * - `starting_after` — the id of the last object of the previous page — or
85
+ * `ending_before` — the id of the first object of the current one, which
86
+ * pages backwards and still answers newest first. Never both;
87
+ * - `created` (one second) or `created[gt|gte|lt|lte]`, Unix seconds.
88
+ *
89
+ * Cursors are resolved by the gateway inside the caller's scope; one naming
90
+ * anything else is a 400 with `param` naming the cursor.
91
+ */
92
+ exports.listQueryShape = {
93
+ limit: zod_1.z.coerce.number().int().min(1).max(100).default(10),
94
+ starting_after: zod_1.z.string().min(1).max(255).optional(),
95
+ ending_before: zod_1.z.string().min(1).max(255).optional(),
96
+ created: zod_1.z
97
+ .union([
98
+ unixSecondsQuery.transform((x) => ({ gte: x, lte: x })),
99
+ zod_1.z
100
+ .object({
101
+ gt: unixSecondsQuery.optional(),
102
+ gte: unixSecondsQuery.optional(),
103
+ lt: unixSecondsQuery.optional(),
104
+ lte: unixSecondsQuery.optional(),
105
+ })
106
+ .strict(),
107
+ ])
108
+ .optional(),
109
+ };
72
110
  /**
73
- * Paging: `starting_after` is the public id of the last object of the previous
74
- * page (`link_…` for links, `pi_…` for collections), resolved by the gateway
75
- * inside the caller's organization, application and environment.
111
+ * Paging a contribution list: the list parameters (`link_…` cursors for links,
112
+ * `pi_…` for collections) plus the environment the Test/Live toggle selects.
76
113
  */
77
114
  exports.contributionPageQuerySchema = zod_1.z
78
115
  .object({
79
- limit: zod_1.z.coerce.number().int().min(1).max(100).default(10),
80
- starting_after: zod_1.z.string().min(1).max(200).optional(),
116
+ ...exports.listQueryShape,
81
117
  environment: zod_1.z.enum(['development', 'staging', 'production']),
82
118
  })
83
- .strict();
119
+ .strict()
120
+ .refine((query) => query.starting_after === undefined || query.ending_before === undefined, {
121
+ message: 'starting_after and ending_before are mutually exclusive',
122
+ path: ['ending_before'],
123
+ });
84
124
  exports.contributionMintSchema = zod_1.z
85
125
  .object({ amount: exports.contributionAmountSchema.optional() })
86
126
  .strict();
@@ -16,6 +16,7 @@ exports.contributionRoutes = [
16
16
  method: 'post',
17
17
  path,
18
18
  operationId: 'createContribution',
19
+ idempotencyKey: true,
19
20
  body: index_1.createContributionSchema,
20
21
  response: index_1.contributionLinkSchema,
21
22
  status: 201,
@@ -28,7 +29,7 @@ exports.contributionRoutes = [
28
29
  status: 200,
29
30
  },
30
31
  {
31
- method: 'patch',
32
+ method: 'post',
32
33
  path: `${path}/{id}`,
33
34
  operationId: 'setContributionActive',
34
35
  body: index_1.contributionPatchSchema,
@@ -70,8 +71,34 @@ function contributionOpenApi() {
70
71
  name: 'starting_after',
71
72
  description: 'The id of the last object on the previous page.',
72
73
  schema: { type: 'string' },
74
+ }, {
75
+ in: 'query',
76
+ name: 'ending_before',
77
+ description: 'The id of the first object on the current page; pages backwards, newest first.',
78
+ schema: { type: 'string' },
79
+ }, {
80
+ in: 'query',
81
+ name: 'created',
82
+ description: 'Unix seconds: one second, or `created[gt|gte|lt|lte]`.',
83
+ style: 'deepObject',
84
+ explode: true,
85
+ schema: {
86
+ oneOf: [
87
+ { type: 'integer', minimum: 0 },
88
+ {
89
+ type: 'object',
90
+ additionalProperties: false,
91
+ properties: {
92
+ gt: { type: 'integer', minimum: 0 },
93
+ gte: { type: 'integer', minimum: 0 },
94
+ lt: { type: 'integer', minimum: 0 },
95
+ lte: { type: 'integer', minimum: 0 },
96
+ },
97
+ },
98
+ ],
99
+ },
73
100
  });
74
- if (route.method === 'post')
101
+ if ('idempotencyKey' in route)
75
102
  parameters.push({
76
103
  in: 'header',
77
104
  name: 'Idempotency-Key',
package/dist/esm/index.js CHANGED
@@ -36,10 +36,17 @@ export const contributionLinkSchema = z
36
36
  created: unixSecondsSchema,
37
37
  })
38
38
  .strict();
39
- /** The one list envelope (ADR 0014 D1). */
39
+ /**
40
+ * The one list envelope (ADR 0014 D1): `url` is the path that was listed.
41
+ */
40
42
  function listSchema(item) {
41
43
  return z
42
- .object({ object: z.literal('list'), data: z.array(item), has_more: z.boolean() })
44
+ .object({
45
+ object: z.literal('list'),
46
+ data: z.array(item),
47
+ has_more: z.boolean(),
48
+ url: z.string(),
49
+ })
43
50
  .strict();
44
51
  }
45
52
  export const contributionListSchema = listSchema(contributionLinkSchema);
@@ -64,18 +71,51 @@ export const contributionCollectionSchema = z
64
71
  })
65
72
  .strict();
66
73
  export const contributionCollectionListSchema = listSchema(contributionCollectionSchema);
74
+ const unixSecondsQuery = z.coerce.number().int().nonnegative();
75
+ /**
76
+ * The list parameters every list accepts (ADR 0014 D1), newest first:
77
+ *
78
+ * - `limit` 1–100, default 10;
79
+ * - `starting_after` — the id of the last object of the previous page — or
80
+ * `ending_before` — the id of the first object of the current one, which
81
+ * pages backwards and still answers newest first. Never both;
82
+ * - `created` (one second) or `created[gt|gte|lt|lte]`, Unix seconds.
83
+ *
84
+ * Cursors are resolved by the gateway inside the caller's scope; one naming
85
+ * anything else is a 400 with `param` naming the cursor.
86
+ */
87
+ export const listQueryShape = {
88
+ limit: z.coerce.number().int().min(1).max(100).default(10),
89
+ starting_after: z.string().min(1).max(255).optional(),
90
+ ending_before: z.string().min(1).max(255).optional(),
91
+ created: z
92
+ .union([
93
+ unixSecondsQuery.transform((x) => ({ gte: x, lte: x })),
94
+ z
95
+ .object({
96
+ gt: unixSecondsQuery.optional(),
97
+ gte: unixSecondsQuery.optional(),
98
+ lt: unixSecondsQuery.optional(),
99
+ lte: unixSecondsQuery.optional(),
100
+ })
101
+ .strict(),
102
+ ])
103
+ .optional(),
104
+ };
67
105
  /**
68
- * Paging: `starting_after` is the public id of the last object of the previous
69
- * page (`link_…` for links, `pi_…` for collections), resolved by the gateway
70
- * inside the caller's organization, application and environment.
106
+ * Paging a contribution list: the list parameters (`link_…` cursors for links,
107
+ * `pi_…` for collections) plus the environment the Test/Live toggle selects.
71
108
  */
72
109
  export const contributionPageQuerySchema = z
73
110
  .object({
74
- limit: z.coerce.number().int().min(1).max(100).default(10),
75
- starting_after: z.string().min(1).max(200).optional(),
111
+ ...listQueryShape,
76
112
  environment: z.enum(['development', 'staging', 'production']),
77
113
  })
78
- .strict();
114
+ .strict()
115
+ .refine((query) => query.starting_after === undefined || query.ending_before === undefined, {
116
+ message: 'starting_after and ending_before are mutually exclusive',
117
+ path: ['ending_before'],
118
+ });
79
119
  export const contributionMintSchema = z
80
120
  .object({ amount: contributionAmountSchema.optional() })
81
121
  .strict();
@@ -12,6 +12,7 @@ export const contributionRoutes = [
12
12
  method: 'post',
13
13
  path,
14
14
  operationId: 'createContribution',
15
+ idempotencyKey: true,
15
16
  body: createContributionSchema,
16
17
  response: contributionLinkSchema,
17
18
  status: 201,
@@ -24,7 +25,7 @@ export const contributionRoutes = [
24
25
  status: 200,
25
26
  },
26
27
  {
27
- method: 'patch',
28
+ method: 'post',
28
29
  path: `${path}/{id}`,
29
30
  operationId: 'setContributionActive',
30
31
  body: contributionPatchSchema,
@@ -66,8 +67,34 @@ export function contributionOpenApi() {
66
67
  name: 'starting_after',
67
68
  description: 'The id of the last object on the previous page.',
68
69
  schema: { type: 'string' },
70
+ }, {
71
+ in: 'query',
72
+ name: 'ending_before',
73
+ description: 'The id of the first object on the current page; pages backwards, newest first.',
74
+ schema: { type: 'string' },
75
+ }, {
76
+ in: 'query',
77
+ name: 'created',
78
+ description: 'Unix seconds: one second, or `created[gt|gte|lt|lte]`.',
79
+ style: 'deepObject',
80
+ explode: true,
81
+ schema: {
82
+ oneOf: [
83
+ { type: 'integer', minimum: 0 },
84
+ {
85
+ type: 'object',
86
+ additionalProperties: false,
87
+ properties: {
88
+ gt: { type: 'integer', minimum: 0 },
89
+ gte: { type: 'integer', minimum: 0 },
90
+ lt: { type: 'integer', minimum: 0 },
91
+ lte: { type: 'integer', minimum: 0 },
92
+ },
93
+ },
94
+ ],
95
+ },
69
96
  });
70
- if (route.method === 'post')
97
+ if ('idempotencyKey' in route)
71
98
  parameters.push({
72
99
  in: 'header',
73
100
  name: 'Idempotency-Key',
@@ -69,6 +69,7 @@ export declare const contributionListSchema: z.ZodObject<{
69
69
  created: z.ZodNumber;
70
70
  }, z.core.$strict>>;
71
71
  has_more: z.ZodBoolean;
72
+ url: z.ZodString;
72
73
  }, z.core.$strict>;
73
74
  export type ContributionList = z.infer<typeof contributionListSchema>;
74
75
  export declare const contributionCollectionSchema: z.ZodObject<{
@@ -107,20 +108,56 @@ export declare const contributionCollectionListSchema: z.ZodObject<{
107
108
  }, z.core.$strict>>;
108
109
  }, z.core.$strict>>;
109
110
  has_more: z.ZodBoolean;
111
+ url: z.ZodString;
110
112
  }, z.core.$strict>;
111
113
  /**
112
- * Paging: `starting_after` is the public id of the last object of the previous
113
- * page (`link_…` for links, `pi_…` for collections), resolved by the gateway
114
- * inside the caller's organization, application and environment.
114
+ * The list parameters every list accepts (ADR 0014 D1), newest first:
115
+ *
116
+ * - `limit` 1–100, default 10;
117
+ * - `starting_after` — the id of the last object of the previous page — or
118
+ * `ending_before` — the id of the first object of the current one, which
119
+ * pages backwards and still answers newest first. Never both;
120
+ * - `created` (one second) or `created[gt|gte|lt|lte]`, Unix seconds.
121
+ *
122
+ * Cursors are resolved by the gateway inside the caller's scope; one naming
123
+ * anything else is a 400 with `param` naming the cursor.
115
124
  */
116
- export declare const contributionPageQuerySchema: z.ZodObject<{
125
+ export declare const listQueryShape: {
117
126
  limit: z.ZodDefault<z.ZodCoercedNumber<unknown>>;
118
127
  starting_after: z.ZodOptional<z.ZodString>;
128
+ ending_before: z.ZodOptional<z.ZodString>;
129
+ created: z.ZodOptional<z.ZodUnion<readonly [z.ZodPipe<z.ZodCoercedNumber<unknown>, z.ZodTransform<{
130
+ gte: number;
131
+ lte: number;
132
+ }, number>>, z.ZodObject<{
133
+ gt: z.ZodOptional<z.ZodCoercedNumber<unknown>>;
134
+ gte: z.ZodOptional<z.ZodCoercedNumber<unknown>>;
135
+ lt: z.ZodOptional<z.ZodCoercedNumber<unknown>>;
136
+ lte: z.ZodOptional<z.ZodCoercedNumber<unknown>>;
137
+ }, z.core.$strict>]>>;
138
+ };
139
+ /**
140
+ * Paging a contribution list: the list parameters (`link_…` cursors for links,
141
+ * `pi_…` for collections) plus the environment the Test/Live toggle selects.
142
+ */
143
+ export declare const contributionPageQuerySchema: z.ZodObject<{
119
144
  environment: z.ZodEnum<{
120
145
  development: "development";
121
146
  staging: "staging";
122
147
  production: "production";
123
148
  }>;
149
+ limit: z.ZodDefault<z.ZodCoercedNumber<unknown>>;
150
+ starting_after: z.ZodOptional<z.ZodString>;
151
+ ending_before: z.ZodOptional<z.ZodString>;
152
+ created: z.ZodOptional<z.ZodUnion<readonly [z.ZodPipe<z.ZodCoercedNumber<unknown>, z.ZodTransform<{
153
+ gte: number;
154
+ lte: number;
155
+ }, number>>, z.ZodObject<{
156
+ gt: z.ZodOptional<z.ZodCoercedNumber<unknown>>;
157
+ gte: z.ZodOptional<z.ZodCoercedNumber<unknown>>;
158
+ lt: z.ZodOptional<z.ZodCoercedNumber<unknown>>;
159
+ lte: z.ZodOptional<z.ZodCoercedNumber<unknown>>;
160
+ }, z.core.$strict>]>>;
124
161
  }, z.core.$strict>;
125
162
  export declare const contributionMintSchema: z.ZodObject<{
126
163
  amount: z.ZodOptional<z.ZodString>;
@@ -3,6 +3,7 @@ export declare const contributionRoutes: readonly [{
3
3
  readonly method: "post";
4
4
  readonly path: "/v1/organizations/{organizationId}/applications/{applicationId}/contributions";
5
5
  readonly operationId: "createContribution";
6
+ readonly idempotencyKey: true;
6
7
  readonly body: z.ZodObject<{
7
8
  purpose: z.ZodString;
8
9
  amount_mode: z.ZodEnum<{
@@ -65,10 +66,11 @@ export declare const contributionRoutes: readonly [{
65
66
  created: z.ZodNumber;
66
67
  }, z.core.$strict>>;
67
68
  has_more: z.ZodBoolean;
69
+ url: z.ZodString;
68
70
  }, z.core.$strict>;
69
71
  readonly status: 200;
70
72
  }, {
71
- readonly method: "patch";
73
+ readonly method: "post";
72
74
  readonly path: "/v1/organizations/{organizationId}/applications/{applicationId}/contributions/{id}";
73
75
  readonly operationId: "setContributionActive";
74
76
  readonly body: z.ZodObject<{
@@ -120,6 +122,7 @@ export declare const contributionRoutes: readonly [{
120
122
  }, z.core.$strict>>;
121
123
  }, z.core.$strict>>;
122
124
  has_more: z.ZodBoolean;
125
+ url: z.ZodString;
123
126
  }, z.core.$strict>;
124
127
  readonly status: 200;
125
128
  }];
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@peable.to/contracts",
3
- "version": "0.3.0",
3
+ "version": "0.4.0",
4
4
  "description": "Validated Peable contribution-link contracts",
5
5
  "main": "dist/cjs/index.js",
6
6
  "module": "dist/esm/index.js",