@stripe/extensibility-test-helpers 0.2.7

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.
@@ -0,0 +1,218 @@
1
+ /**
2
+ * `@stripe/extensibility-test-helpers`
3
+ *
4
+ * Generic test client for Stripe resources.
5
+ *
6
+ * Works with both CustomObject subclasses and API objects like Customer.
7
+ * Backend implementations can be swapped for local testing vs sandbox.
8
+ *
9
+ * @packageDocumentation
10
+ */
11
+
12
+ /**
13
+ * Backend interface for storage/API operations.
14
+ * Implement for different environments (local, sandbox, production).
15
+ * @public
16
+ */
17
+ export declare interface Backend {
18
+ /**
19
+ * Creates a new resource of the given object type.
20
+ * @param objectType - The Stripe object type string (e.g. `"customer"`).
21
+ * @param data - Fields to set on the new resource.
22
+ * @returns The created resource with a generated `id`.
23
+ */
24
+ create<T extends StripeResource>(objectType: string, data: Record<string, unknown>): Promise<T>;
25
+ /**
26
+ * Retrieves a resource by ID.
27
+ * @param objectType - The Stripe object type string.
28
+ * @param id - The resource ID.
29
+ * @returns The matching resource.
30
+ */
31
+ retrieve<T extends StripeResource>(objectType: string, id: string): Promise<T>;
32
+ /**
33
+ * Updates an existing resource by merging the provided fields.
34
+ * @param objectType - The Stripe object type string.
35
+ * @param id - The resource ID.
36
+ * @param data - Fields to merge into the existing resource.
37
+ * @returns The updated resource.
38
+ */
39
+ update<T extends StripeResource>(objectType: string, id: string, data: Record<string, unknown>): Promise<T>;
40
+ /**
41
+ * Deletes a resource by ID.
42
+ * @param objectType - The Stripe object type string.
43
+ * @param id - The resource ID.
44
+ */
45
+ delete(objectType: string, id: string): Promise<void>;
46
+ /**
47
+ * Lists resources of the given object type with optional pagination.
48
+ * @param objectType - The Stripe object type string.
49
+ * @param params - Optional pagination parameters.
50
+ * @returns A paginated list response.
51
+ */
52
+ list<T extends StripeResource>(objectType: string, params?: ListParams): Promise<ListResponse<T>>;
53
+ }
54
+
55
+ /**
56
+ * Input type for create - user-provided fields only.
57
+ *
58
+ * @public
59
+ */
60
+ export declare type CreateInput<T extends StripeResource> = Partial<Omit<T, 'id' | 'object'>>;
61
+
62
+ /**
63
+ * List pagination params.
64
+ * @public
65
+ */
66
+ export declare interface ListParams {
67
+ /** Maximum number of items to return. Defaults to `10`. */
68
+ limit?: number;
69
+ /** Return items after the item with this ID (exclusive). Use for forward pagination. */
70
+ startingAfter?: string;
71
+ /** Return items before the item with this ID (exclusive). Use for backward pagination. */
72
+ endingBefore?: string;
73
+ }
74
+
75
+ /**
76
+ * Paginated list response.
77
+ * @public
78
+ */
79
+ export declare interface ListResponse<T> {
80
+ /** The items in the current page. */
81
+ data: T[];
82
+ /** Whether additional items exist beyond this page. */
83
+ hasMore: boolean;
84
+ }
85
+
86
+ /**
87
+ * In-memory {@link Backend} implementation for use in unit tests.
88
+ *
89
+ * Each instance maintains its own isolated store. Use a shared instance
90
+ * when you need multiple clients to see the same data.
91
+ * @public
92
+ */
93
+ export declare class LocalBackend implements Backend {
94
+ private store;
95
+ private idCounter;
96
+ private getCollection;
97
+ private generateId;
98
+ /** {@inheritDoc Backend.create} */
99
+ create<T extends StripeResource>(objectType: string, data: Record<string, unknown>): Promise<T>;
100
+ /** {@inheritDoc Backend.retrieve} */
101
+ retrieve<T extends StripeResource>(objectType: string, id: string): Promise<T>;
102
+ /** {@inheritDoc Backend.update} */
103
+ update<T extends StripeResource>(objectType: string, id: string, data: Record<string, unknown>): Promise<T>;
104
+ /** {@inheritDoc Backend.delete} */
105
+ delete(objectType: string, id: string): Promise<void>;
106
+ /** {@inheritDoc Backend.list} */
107
+ list<T extends StripeResource>(objectType: string, params?: ListParams): Promise<ListResponse<T>>;
108
+ /** Resets all stored objects and the ID counter. Useful in `beforeEach` hooks. */
109
+ clear(): void;
110
+ }
111
+
112
+ /**
113
+ * A class constructor that produces instances of T.
114
+ * @public
115
+ */
116
+ export declare type ResourceClass<T extends StripeResource> = new (...args: unknown[]) => T;
117
+
118
+ /**
119
+ * Minimal interface for any Stripe resource.
120
+ * Both CustomObject and API objects satisfy this.
121
+ * @public
122
+ */
123
+ export declare interface StripeResource {
124
+ /** Unique identifier for the resource. */
125
+ id: string;
126
+ /** String identifying the object type, e.g. `"customer"` or `"custom_object.order"`. */
127
+ object: string;
128
+ }
129
+
130
+ /**
131
+ * Generic test client for any Stripe resource.
132
+ *
133
+ * @example
134
+ * ```ts
135
+ * const locations = new TestClient(Location);
136
+ * const customers = new TestClient(Customer);
137
+ *
138
+ * const loc = await locations.create({ address: '123 Main' });
139
+ * const cust = await customers.create({ email: 'test@example.com' });
140
+ * ```
141
+ * @public
142
+ */
143
+ export declare class TestClient<T extends StripeResource> {
144
+ private ResourceClass;
145
+ private static sharedBackend;
146
+ private objectType;
147
+ private backend;
148
+ constructor(ResourceClass: ResourceClass<T>, options?: TestClientOptions);
149
+ /**
150
+ * Derive object type by instantiating the class and reading its `object` field.
151
+ *
152
+ * This works for classes that set `object` in their constructor or as a field
153
+ * initializer (e.g. `object = 'test.resource'`). It does **not** work for
154
+ * custom object classes that extend `BaseObject`, because `BaseObject.object`
155
+ * is only set after the build-time code transform runs — plain construction
156
+ * leaves it undefined. For those classes, pass `objectType` explicitly in the
157
+ * constructor options.
158
+ */
159
+ private deriveObjectType;
160
+ /**
161
+ * Hydrate plain data into a class instance.
162
+ * Returns an instance with the class's prototype (so methods work).
163
+ */
164
+ private hydrate;
165
+ /**
166
+ * Creates a new resource and returns it as a hydrated class instance.
167
+ *
168
+ * Injects standard platform field defaults (`created`, `updated`, `livemode`)
169
+ * before the caller's data, so the returned instance has the same shape a real
170
+ * Stripe backend would produce. Callers can override any default via `data`.
171
+ *
172
+ * @param data - Fields to set on the new resource (excluding `id` and `object`).
173
+ */
174
+ create(data: CreateInput<T>): Promise<T>;
175
+ /**
176
+ * Retrieves a resource by ID and returns it as a hydrated class instance.
177
+ * @param id - The resource ID.
178
+ */
179
+ retrieve(id: string): Promise<T>;
180
+ /**
181
+ * Merges the provided fields into an existing resource and returns the updated instance.
182
+ * @param id - The resource ID.
183
+ * @param data - Fields to merge into the existing resource (excluding `id` and `object`).
184
+ */
185
+ update(id: string, data: UpdateInput<T>): Promise<T>;
186
+ /**
187
+ * Deletes a resource by ID.
188
+ * @param id - The resource ID.
189
+ */
190
+ delete(id: string): Promise<void>;
191
+ /**
192
+ * Lists resources with optional pagination, returning hydrated class instances.
193
+ * @param params - Optional pagination parameters.
194
+ */
195
+ list(params?: ListParams): Promise<ListResponse<T>>;
196
+ /** Clear all test data across all object types */
197
+ static clearAll(): void;
198
+ }
199
+
200
+ /**
201
+ * Options for constructing a {@link TestClient}.
202
+ * @public
203
+ */
204
+ export declare interface TestClientOptions {
205
+ /** Explicit object type (if auto-derive doesn't work) */
206
+ objectType?: string;
207
+ /** Custom backend (defaults to shared LocalBackend) */
208
+ backend?: Backend;
209
+ }
210
+
211
+ /**
212
+ * Input type for update - partial user fields.
213
+ *
214
+ * @public
215
+ */
216
+ export declare type UpdateInput<T extends StripeResource> = Partial<Omit<T, 'id' | 'object'>>;
217
+
218
+ export { }
package/dist/index.cjs ADDED
@@ -0,0 +1,248 @@
1
+ "use strict";
2
+ var __defProp = Object.defineProperty;
3
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
+ var __getOwnPropNames = Object.getOwnPropertyNames;
5
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
6
+ var __export = (target, all) => {
7
+ for (var name in all)
8
+ __defProp(target, name, { get: all[name], enumerable: true });
9
+ };
10
+ var __copyProps = (to, from, except, desc) => {
11
+ if (from && typeof from === "object" || typeof from === "function") {
12
+ for (let key of __getOwnPropNames(from))
13
+ if (!__hasOwnProp.call(to, key) && key !== except)
14
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
15
+ }
16
+ return to;
17
+ };
18
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
+
20
+ // src/index.ts
21
+ var index_exports = {};
22
+ __export(index_exports, {
23
+ LocalBackend: () => LocalBackend,
24
+ TestClient: () => TestClient
25
+ });
26
+ module.exports = __toCommonJS(index_exports);
27
+ var LocalBackend = class {
28
+ store = /* @__PURE__ */ new Map();
29
+ idCounter = 0;
30
+ getCollection(objectType) {
31
+ if (!this.store.has(objectType)) {
32
+ this.store.set(objectType, /* @__PURE__ */ new Map());
33
+ }
34
+ return this.store.get(objectType);
35
+ }
36
+ generateId() {
37
+ return `obj_test_${String(++this.idCounter)}`;
38
+ }
39
+ /** {@inheritDoc Backend.create} */
40
+ create(objectType, data) {
41
+ const id = this.generateId();
42
+ const object = {
43
+ id,
44
+ object: objectType,
45
+ ...data
46
+ };
47
+ this.getCollection(objectType).set(id, object);
48
+ return Promise.resolve(object);
49
+ }
50
+ /** {@inheritDoc Backend.retrieve} */
51
+ retrieve(objectType, id) {
52
+ const object = this.getCollection(objectType).get(id);
53
+ if (!object) {
54
+ return Promise.reject(new Error(`Object not found: ${objectType}/${id}`));
55
+ }
56
+ return Promise.resolve(object);
57
+ }
58
+ /** {@inheritDoc Backend.update} */
59
+ update(objectType, id, data) {
60
+ const object = this.getCollection(objectType).get(id);
61
+ if (!object) {
62
+ return Promise.reject(new Error(`Object not found: ${objectType}/${id}`));
63
+ }
64
+ const updated = { ...object, ...data };
65
+ this.getCollection(objectType).set(id, updated);
66
+ return Promise.resolve(updated);
67
+ }
68
+ /** {@inheritDoc Backend.delete} */
69
+ delete(objectType, id) {
70
+ const collection = this.getCollection(objectType);
71
+ if (!collection.has(id)) {
72
+ return Promise.reject(new Error(`Object not found: ${objectType}/${id}`));
73
+ }
74
+ collection.delete(id);
75
+ return Promise.resolve();
76
+ }
77
+ /** {@inheritDoc Backend.list} */
78
+ list(objectType, params) {
79
+ const collection = this.getCollection(objectType);
80
+ const all = Array.from(collection.values());
81
+ const limit = params?.limit ?? 10;
82
+ const hasStartingAfter = params?.startingAfter !== void 0;
83
+ const hasEndingBefore = params?.endingBefore !== void 0;
84
+ let startIndex = 0;
85
+ let endIndex = all.length;
86
+ if (hasStartingAfter) {
87
+ const idx = all.findIndex((o) => o.id === params.startingAfter);
88
+ if (idx >= 0) {
89
+ startIndex = idx + 1;
90
+ }
91
+ }
92
+ if (hasEndingBefore) {
93
+ const idx = all.findIndex((o) => o.id === params.endingBefore);
94
+ if (idx >= 0) {
95
+ endIndex = idx;
96
+ }
97
+ }
98
+ const windowed = all.slice(startIndex, endIndex);
99
+ const data = hasEndingBefore && !hasStartingAfter && windowed.length > limit ? windowed.slice(windowed.length - limit) : windowed.slice(0, limit);
100
+ const hasMore = limit < windowed.length;
101
+ return Promise.resolve({ data, hasMore });
102
+ }
103
+ /** Resets all stored objects and the ID counter. Useful in `beforeEach` hooks. */
104
+ clear() {
105
+ this.store.clear();
106
+ this.idCounter = 0;
107
+ }
108
+ };
109
+ var TestClient = class _TestClient {
110
+ constructor(ResourceClass, options) {
111
+ this.ResourceClass = ResourceClass;
112
+ this.backend = options?.backend ?? _TestClient.sharedBackend;
113
+ this.objectType = options?.objectType ?? this.deriveObjectType();
114
+ }
115
+ static sharedBackend = new LocalBackend();
116
+ objectType;
117
+ backend;
118
+ /**
119
+ * Derive object type by instantiating the class and reading its `object` field.
120
+ *
121
+ * This works for classes that set `object` in their constructor or as a field
122
+ * initializer (e.g. `object = 'test.resource'`). It does **not** work for
123
+ * custom object classes that extend `BaseObject`, because `BaseObject.object`
124
+ * is only set after the build-time code transform runs — plain construction
125
+ * leaves it undefined. For those classes, pass `objectType` explicitly in the
126
+ * constructor options.
127
+ */
128
+ deriveObjectType() {
129
+ let instance;
130
+ try {
131
+ instance = new this.ResourceClass();
132
+ } catch (cause) {
133
+ throw new Error(
134
+ `Could not derive object type for ${this.ResourceClass.name}. Pass it explicitly: new TestClient(${this.ResourceClass.name}, { objectType: '...' })`,
135
+ { cause: cause instanceof Error ? cause : void 0 }
136
+ );
137
+ }
138
+ if (!instance.object) {
139
+ throw new Error(
140
+ `${this.ResourceClass.name}.object is undefined after construction. Pass it explicitly: new TestClient(${this.ResourceClass.name}, { objectType: '...' })`
141
+ );
142
+ }
143
+ return instance.object;
144
+ }
145
+ // -------------------------------------------------------------------------
146
+ // Hydration - convert plain data to class instances
147
+ // -------------------------------------------------------------------------
148
+ // TODO: Handle custom constructors. Options to consider:
149
+ //
150
+ // Option 1: Pass data to constructor, assume it accepts it
151
+ // const instance = new cls(data);
152
+ //
153
+ // Option 2: Skip constructor entirely, use Object.create
154
+ // const instance = Object.create(cls.prototype) as T;
155
+ // Object.assign(instance, data);
156
+ // // Gives prototype chain (methods work) without invoking constructor
157
+ //
158
+ // Option 3: Inspect constructor.length and try both
159
+ // if (cls.length > 0) {
160
+ // return new cls(data);
161
+ // }
162
+ // return Object.assign(new cls(), data);
163
+ /**
164
+ * Hydrate plain data into a class instance.
165
+ * Returns an instance with the class's prototype (so methods work).
166
+ */
167
+ hydrate(data) {
168
+ const instance = new this.ResourceClass();
169
+ return Object.assign(instance, data);
170
+ }
171
+ // -------------------------------------------------------------------------
172
+ // CRUD+L methods - fully typed based on T
173
+ // -------------------------------------------------------------------------
174
+ /**
175
+ * Creates a new resource and returns it as a hydrated class instance.
176
+ *
177
+ * Injects standard platform field defaults (`created`, `updated`, `livemode`)
178
+ * before the caller's data, so the returned instance has the same shape a real
179
+ * Stripe backend would produce. Callers can override any default via `data`.
180
+ *
181
+ * @param data - Fields to set on the new resource (excluding `id` and `object`).
182
+ */
183
+ async create(data) {
184
+ const timestamp = Date.now();
185
+ const withDefaults = {
186
+ created: new Date(timestamp),
187
+ updated: new Date(timestamp),
188
+ livemode: false,
189
+ // eslint-disable-next-line @typescript-eslint/consistent-type-assertions -- CreateInput<T> is a generic mapped type (Partial<Omit<T,...>>) that TypeScript does not consider directly assignable to Record<string, unknown>; the cast is safe here because the Backend.create signature requires a plain record for the spread operation
190
+ ...data
191
+ };
192
+ const result = await this.backend.create(this.objectType, withDefaults);
193
+ return this.hydrate(result);
194
+ }
195
+ /**
196
+ * Retrieves a resource by ID and returns it as a hydrated class instance.
197
+ * @param id - The resource ID.
198
+ */
199
+ async retrieve(id) {
200
+ const result = await this.backend.retrieve(this.objectType, id);
201
+ return this.hydrate(result);
202
+ }
203
+ /**
204
+ * Merges the provided fields into an existing resource and returns the updated instance.
205
+ * @param id - The resource ID.
206
+ * @param data - Fields to merge into the existing resource (excluding `id` and `object`).
207
+ */
208
+ async update(id, data) {
209
+ const result = await this.backend.update(
210
+ this.objectType,
211
+ id,
212
+ // eslint-disable-next-line @typescript-eslint/consistent-type-assertions -- UpdateInput<T> is a generic mapped type (Partial<Omit<T,...>>) that TypeScript does not consider directly assignable to Record<string, unknown>; the cast is safe here because the Backend.update signature requires a plain record for the spread operation
213
+ data
214
+ );
215
+ return this.hydrate(result);
216
+ }
217
+ /**
218
+ * Deletes a resource by ID.
219
+ * @param id - The resource ID.
220
+ */
221
+ async delete(id) {
222
+ return this.backend.delete(this.objectType, id);
223
+ }
224
+ /**
225
+ * Lists resources with optional pagination, returning hydrated class instances.
226
+ * @param params - Optional pagination parameters.
227
+ */
228
+ async list(params) {
229
+ const result = await this.backend.list(this.objectType, params);
230
+ return {
231
+ ...result,
232
+ // eslint-disable-next-line @typescript-eslint/consistent-type-assertions, @typescript-eslint/no-unsafe-type-assertion -- each item is T from the backend; narrowing to Record<string, unknown> for Object.assign in hydrate is safe because T extends StripeResource which has only string-keyed properties
233
+ data: result.data.map((item) => this.hydrate(item))
234
+ };
235
+ }
236
+ // -------------------------------------------------------------------------
237
+ // Test utilities
238
+ // -------------------------------------------------------------------------
239
+ /** Clear all test data across all object types */
240
+ static clearAll() {
241
+ _TestClient.sharedBackend.clear();
242
+ }
243
+ };
244
+ // Annotate the CommonJS export names for ESM import in node:
245
+ 0 && (module.exports = {
246
+ LocalBackend,
247
+ TestClient
248
+ });
@@ -0,0 +1,207 @@
1
+ /**
2
+ * `@stripe/extensibility-test-helpers`
3
+ *
4
+ * Generic test client for Stripe resources.
5
+ *
6
+ * Works with both CustomObject subclasses and API objects like Customer.
7
+ * Backend implementations can be swapped for local testing vs sandbox.
8
+ *
9
+ * @packageDocumentation
10
+ */
11
+ /**
12
+ * Minimal interface for any Stripe resource.
13
+ * Both CustomObject and API objects satisfy this.
14
+ * @public
15
+ */
16
+ export interface StripeResource {
17
+ /** Unique identifier for the resource. */
18
+ id: string;
19
+ /** String identifying the object type, e.g. `"customer"` or `"custom_object.order"`. */
20
+ object: string;
21
+ }
22
+ /**
23
+ * Input type for create - user-provided fields only.
24
+ *
25
+ * @public
26
+ */
27
+ export type CreateInput<T extends StripeResource> = Partial<Omit<T, 'id' | 'object'>>;
28
+ /**
29
+ * Input type for update - partial user fields.
30
+ *
31
+ * @public
32
+ */
33
+ export type UpdateInput<T extends StripeResource> = Partial<Omit<T, 'id' | 'object'>>;
34
+ /**
35
+ * List pagination params.
36
+ * @public
37
+ */
38
+ export interface ListParams {
39
+ /** Maximum number of items to return. Defaults to `10`. */
40
+ limit?: number;
41
+ /** Return items after the item with this ID (exclusive). Use for forward pagination. */
42
+ startingAfter?: string;
43
+ /** Return items before the item with this ID (exclusive). Use for backward pagination. */
44
+ endingBefore?: string;
45
+ }
46
+ /**
47
+ * Paginated list response.
48
+ * @public
49
+ */
50
+ export interface ListResponse<T> {
51
+ /** The items in the current page. */
52
+ data: T[];
53
+ /** Whether additional items exist beyond this page. */
54
+ hasMore: boolean;
55
+ }
56
+ /**
57
+ * A class constructor that produces instances of T.
58
+ * @public
59
+ */
60
+ export type ResourceClass<T extends StripeResource> = new (...args: unknown[]) => T;
61
+ /**
62
+ * Backend interface for storage/API operations.
63
+ * Implement for different environments (local, sandbox, production).
64
+ * @public
65
+ */
66
+ export interface Backend {
67
+ /**
68
+ * Creates a new resource of the given object type.
69
+ * @param objectType - The Stripe object type string (e.g. `"customer"`).
70
+ * @param data - Fields to set on the new resource.
71
+ * @returns The created resource with a generated `id`.
72
+ */
73
+ create<T extends StripeResource>(objectType: string, data: Record<string, unknown>): Promise<T>;
74
+ /**
75
+ * Retrieves a resource by ID.
76
+ * @param objectType - The Stripe object type string.
77
+ * @param id - The resource ID.
78
+ * @returns The matching resource.
79
+ */
80
+ retrieve<T extends StripeResource>(objectType: string, id: string): Promise<T>;
81
+ /**
82
+ * Updates an existing resource by merging the provided fields.
83
+ * @param objectType - The Stripe object type string.
84
+ * @param id - The resource ID.
85
+ * @param data - Fields to merge into the existing resource.
86
+ * @returns The updated resource.
87
+ */
88
+ update<T extends StripeResource>(objectType: string, id: string, data: Record<string, unknown>): Promise<T>;
89
+ /**
90
+ * Deletes a resource by ID.
91
+ * @param objectType - The Stripe object type string.
92
+ * @param id - The resource ID.
93
+ */
94
+ delete(objectType: string, id: string): Promise<void>;
95
+ /**
96
+ * Lists resources of the given object type with optional pagination.
97
+ * @param objectType - The Stripe object type string.
98
+ * @param params - Optional pagination parameters.
99
+ * @returns A paginated list response.
100
+ */
101
+ list<T extends StripeResource>(objectType: string, params?: ListParams): Promise<ListResponse<T>>;
102
+ }
103
+ /**
104
+ * In-memory {@link Backend} implementation for use in unit tests.
105
+ *
106
+ * Each instance maintains its own isolated store. Use a shared instance
107
+ * when you need multiple clients to see the same data.
108
+ * @public
109
+ */
110
+ export declare class LocalBackend implements Backend {
111
+ private store;
112
+ private idCounter;
113
+ private getCollection;
114
+ private generateId;
115
+ /** {@inheritDoc Backend.create} */
116
+ create<T extends StripeResource>(objectType: string, data: Record<string, unknown>): Promise<T>;
117
+ /** {@inheritDoc Backend.retrieve} */
118
+ retrieve<T extends StripeResource>(objectType: string, id: string): Promise<T>;
119
+ /** {@inheritDoc Backend.update} */
120
+ update<T extends StripeResource>(objectType: string, id: string, data: Record<string, unknown>): Promise<T>;
121
+ /** {@inheritDoc Backend.delete} */
122
+ delete(objectType: string, id: string): Promise<void>;
123
+ /** {@inheritDoc Backend.list} */
124
+ list<T extends StripeResource>(objectType: string, params?: ListParams): Promise<ListResponse<T>>;
125
+ /** Resets all stored objects and the ID counter. Useful in `beforeEach` hooks. */
126
+ clear(): void;
127
+ }
128
+ /**
129
+ * Options for constructing a {@link TestClient}.
130
+ * @public
131
+ */
132
+ export interface TestClientOptions {
133
+ /** Explicit object type (if auto-derive doesn't work) */
134
+ objectType?: string;
135
+ /** Custom backend (defaults to shared LocalBackend) */
136
+ backend?: Backend;
137
+ }
138
+ /**
139
+ * Generic test client for any Stripe resource.
140
+ *
141
+ * @example
142
+ * ```ts
143
+ * const locations = new TestClient(Location);
144
+ * const customers = new TestClient(Customer);
145
+ *
146
+ * const loc = await locations.create({ address: '123 Main' });
147
+ * const cust = await customers.create({ email: 'test@example.com' });
148
+ * ```
149
+ * @public
150
+ */
151
+ export declare class TestClient<T extends StripeResource> {
152
+ private ResourceClass;
153
+ private static sharedBackend;
154
+ private objectType;
155
+ private backend;
156
+ constructor(ResourceClass: ResourceClass<T>, options?: TestClientOptions);
157
+ /**
158
+ * Derive object type by instantiating the class and reading its `object` field.
159
+ *
160
+ * This works for classes that set `object` in their constructor or as a field
161
+ * initializer (e.g. `object = 'test.resource'`). It does **not** work for
162
+ * custom object classes that extend `BaseObject`, because `BaseObject.object`
163
+ * is only set after the build-time code transform runs — plain construction
164
+ * leaves it undefined. For those classes, pass `objectType` explicitly in the
165
+ * constructor options.
166
+ */
167
+ private deriveObjectType;
168
+ /**
169
+ * Hydrate plain data into a class instance.
170
+ * Returns an instance with the class's prototype (so methods work).
171
+ */
172
+ private hydrate;
173
+ /**
174
+ * Creates a new resource and returns it as a hydrated class instance.
175
+ *
176
+ * Injects standard platform field defaults (`created`, `updated`, `livemode`)
177
+ * before the caller's data, so the returned instance has the same shape a real
178
+ * Stripe backend would produce. Callers can override any default via `data`.
179
+ *
180
+ * @param data - Fields to set on the new resource (excluding `id` and `object`).
181
+ */
182
+ create(data: CreateInput<T>): Promise<T>;
183
+ /**
184
+ * Retrieves a resource by ID and returns it as a hydrated class instance.
185
+ * @param id - The resource ID.
186
+ */
187
+ retrieve(id: string): Promise<T>;
188
+ /**
189
+ * Merges the provided fields into an existing resource and returns the updated instance.
190
+ * @param id - The resource ID.
191
+ * @param data - Fields to merge into the existing resource (excluding `id` and `object`).
192
+ */
193
+ update(id: string, data: UpdateInput<T>): Promise<T>;
194
+ /**
195
+ * Deletes a resource by ID.
196
+ * @param id - The resource ID.
197
+ */
198
+ delete(id: string): Promise<void>;
199
+ /**
200
+ * Lists resources with optional pagination, returning hydrated class instances.
201
+ * @param params - Optional pagination parameters.
202
+ */
203
+ list(params?: ListParams): Promise<ListResponse<T>>;
204
+ /** Clear all test data across all object types */
205
+ static clearAll(): void;
206
+ }
207
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}