@forgecart/sdk 1.2.5 → 1.2.6

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 (58) hide show
  1. package/README.md +2 -87
  2. package/dist/admin-types.generated.d.ts +9884 -0
  3. package/dist/admin.d.ts +55 -8
  4. package/dist/admin.generated.d.ts +790 -0
  5. package/dist/admin.generated.js +1801 -0
  6. package/dist/admin.js +112 -23
  7. package/dist/client.generated.d.ts +251 -0
  8. package/dist/client.generated.js +757 -0
  9. package/dist/documents.generated.d.ts +465 -0
  10. package/dist/documents.generated.js +24283 -0
  11. package/dist/error-utils.d.ts +25 -0
  12. package/dist/error-utils.js +59 -0
  13. package/dist/hook-event-map.generated.d.ts +243 -0
  14. package/dist/hook-event-map.generated.js +9 -0
  15. package/dist/index.d.ts +23 -59
  16. package/dist/index.js +35 -83
  17. package/dist/sdk-hook-subscription.generated.d.ts +29 -0
  18. package/dist/sdk-hook-subscription.generated.js +73 -0
  19. package/dist/sdk-plugin.generated.d.ts +38 -0
  20. package/dist/sdk-plugin.generated.js +31 -0
  21. package/dist/sdk-types.generated.d.ts +56 -0
  22. package/dist/sdk-types.generated.js +28 -0
  23. package/dist/shop-types.generated.d.ts +4776 -0
  24. package/dist/shop.d.ts +18 -8
  25. package/dist/shop.generated.d.ts +213 -0
  26. package/dist/shop.generated.js +465 -0
  27. package/dist/shop.js +37 -23
  28. package/dist/upload.d.ts +14 -0
  29. package/dist/upload.js +163 -0
  30. package/package.json +10 -25
  31. package/src/admin-types.generated.ts +28377 -0
  32. package/src/admin.generated.ts +1771 -0
  33. package/src/admin.ts +55 -9
  34. package/src/client.generated.ts +845 -0
  35. package/src/documents.generated.ts +24730 -0
  36. package/src/error-utils.ts +74 -0
  37. package/src/hook-event-map.generated.ts +252 -0
  38. package/src/index.ts +23 -115
  39. package/src/sdk-hook-subscription.generated.ts +93 -0
  40. package/src/sdk-plugin.generated.ts +59 -0
  41. package/src/sdk-types.generated.ts +79 -0
  42. package/src/shop-types.generated.ts +10400 -0
  43. package/src/shop.generated.ts +452 -0
  44. package/src/shop.ts +18 -9
  45. package/src/upload.ts +211 -0
  46. package/LICENSE +0 -21
  47. package/dist/admin-namespace.d.ts +0 -2688
  48. package/dist/admin-namespace.js +0 -9691
  49. package/dist/admin-types.d.ts +0 -16195
  50. package/dist/shop-namespace.d.ts +0 -718
  51. package/dist/shop-namespace.js +0 -3124
  52. package/dist/shop-types.d.ts +0 -6310
  53. package/src/admin-namespace.ts +0 -11428
  54. package/src/admin-types.ts +0 -10809
  55. package/src/shop-namespace.ts +0 -3547
  56. package/src/shop-types.ts +0 -4684
  57. /package/dist/{admin-types.js → admin-types.generated.js} +0 -0
  58. /package/dist/{shop-types.js → shop-types.generated.js} +0 -0
@@ -0,0 +1,74 @@
1
+ export interface ExtractedError {
2
+ code: string;
3
+ variables: Record<string, string>;
4
+ classification: string;
5
+ message?: string;
6
+ }
7
+
8
+ interface GraphQLErrorLike {
9
+ response?: {
10
+ errors?: Array<{
11
+ message?: string;
12
+ extensions?: Record<string, unknown>;
13
+ }>;
14
+ };
15
+ }
16
+
17
+ /**
18
+ * Get the first GraphQL error from an error object.
19
+ * Uses duck-typing so it works across bundler boundaries where instanceof fails.
20
+ */
21
+ function getFirstGraphQLError(error: unknown): { message?: string; extensions?: Record<string, unknown> } | null {
22
+ const err = error as GraphQLErrorLike;
23
+ const errors = err?.response?.errors;
24
+ if (!Array.isArray(errors) || errors.length === 0) {
25
+ return null;
26
+ }
27
+ return errors[0] ?? null;
28
+ }
29
+
30
+ /**
31
+ * Extract the structured error code from a ClientError.
32
+ * Returns null if the error has no GraphQL error code.
33
+ */
34
+ export function extractErrorCode(error: unknown): string | null {
35
+ const firstError = getFirstGraphQLError(error);
36
+ if (!firstError?.extensions?.['code']) {
37
+ return null;
38
+ }
39
+ return firstError.extensions['code'] as string;
40
+ }
41
+
42
+ /**
43
+ * Extract full structured error info from a ClientError.
44
+ * Returns null if the error has no GraphQL extensions.
45
+ */
46
+ export function extractError(error: unknown): ExtractedError | null {
47
+ const firstError = getFirstGraphQLError(error);
48
+ if (!firstError?.extensions) {
49
+ return null;
50
+ }
51
+
52
+ return {
53
+ code: (firstError.extensions['code'] as string) ?? firstError.message,
54
+ variables: (firstError.extensions['variables'] as Record<string, string>) ?? {},
55
+ classification: (firstError.extensions['classification'] as string) ?? 'UNKNOWN',
56
+ message: (firstError.extensions['message'] as string) ?? undefined,
57
+ };
58
+ }
59
+
60
+ /**
61
+ * Extract the localized error message from a ClientError.
62
+ * Returns null if the error has no localized message.
63
+ */
64
+ export function extractErrorMessage(error: unknown): string | null {
65
+ const firstError = getFirstGraphQLError(error);
66
+ return (firstError?.extensions?.['message'] as string) ?? null;
67
+ }
68
+
69
+ /**
70
+ * Check if an error has a specific error code.
71
+ */
72
+ export function isErrorCode(error: unknown, code: string): boolean {
73
+ return extractErrorCode(error) === code;
74
+ }
@@ -0,0 +1,252 @@
1
+ /* eslint-disable */
2
+ /**
3
+ * AUTO-GENERATED FILE — DO NOT EDIT
4
+ *
5
+ * This file was generated by @forgecart/client-sdk-generators.
6
+ * Any manual changes will be overwritten on the next generation run.
7
+ */
8
+
9
+
10
+ import type { AddIdentityToSegmentInput, Administrator, Asset, AudienceMembership, AudienceSegment, Channel, ChannelPlugin, Collection, Country, CreateAdministratorInput, CreateAssetInput, CreateAudienceSegmentInput, CreateChannelInput, CreateCollectionInput, CreateCountryInput, CreateCustomerGroupInput, CreateCustomerInput, CreateFacetInput, CreateFacetValueInput, CreateFulfillmentInput, CreateProductInput, CreateProductVariantInput, CreatePromotionInput, CreateRoleInput, CreateSellerInput, CreateStockLocationInput, CreateTaxCategoryInput, CreateTaxRateInput, CreateZoneInput, Customer, CustomerGroup, Facet, FacetValue, Fulfillment, HistoryEntry, Order, Product, ProductVariant, Promotion, RegisterCustomerInput, RemoveIdentityFromSegmentInput, Role, Seller, StockLocation, TaxCategory, TaxRate, UpdateAdministratorInput, UpdateAssetInput, UpdateAudienceSegmentInput, UpdateChannelInput, UpdateChannelPluginConfigInput, UpdateCollectionInput, UpdateCountryInput, UpdateCustomerGroupInput, UpdateCustomerInput, UpdateFacetInput, UpdateFacetValueInput, UpdateProductInput, UpdateProductVariantInput, UpdatePromotionInput, UpdateRoleInput, UpdateSellerInput, UpdateStockLocationInput, UpdateTaxCategoryInput, UpdateTaxRateInput, UpdateZoneInput, Zone } from './admin-types.generated';
11
+ import type { TransactionContext } from './client.generated';
12
+
13
+ export interface AdminHookEventMap {
14
+ 'asset.create.before': CreateAssetInput;
15
+ 'asset.create.after': Asset;
16
+ 'asset.create.async': Asset;
17
+ 'asset.update.before': UpdateAssetInput;
18
+ 'asset.update.after': Asset;
19
+ 'asset.update.async': Asset;
20
+ 'asset.executeSingleAssetDelete.before': void;
21
+ 'asset.executeSingleAssetDelete.after': Asset;
22
+ 'asset.executeSingleAssetDelete.async': Asset;
23
+ 'asset.createFromUrl.before': string;
24
+ 'asset.createFromUrl.after': Asset;
25
+ 'asset.createFromUrl.async': Asset;
26
+ 'administrator.create.before': CreateAdministratorInput;
27
+ 'administrator.create.after': Administrator;
28
+ 'administrator.create.async': Administrator;
29
+ 'administrator.update.before': UpdateAdministratorInput;
30
+ 'administrator.update.after': Administrator;
31
+ 'administrator.update.async': Administrator;
32
+ 'administrator.softDelete.before': string;
33
+ 'administrator.softDelete.after': Administrator;
34
+ 'administrator.softDelete.async': Administrator;
35
+ 'administrator.inviteExistingUser.before': void;
36
+ 'administrator.inviteExistingUser.after': Administrator;
37
+ 'administrator.inviteExistingUser.async': Administrator;
38
+ 'administrator.inviteNewUser.before': void;
39
+ 'administrator.inviteNewUser.after': Administrator;
40
+ 'administrator.inviteNewUser.async': Administrator;
41
+ 'authentication.attemptLogin.before': unknown;
42
+ 'authentication.attemptLogin.after': unknown;
43
+ 'authentication.attemptLogin.async': unknown;
44
+ 'role.create.before': CreateRoleInput;
45
+ 'role.create.after': Role;
46
+ 'role.create.async': Role;
47
+ 'role.update.before': UpdateRoleInput;
48
+ 'role.update.after': Role;
49
+ 'role.update.async': Role;
50
+ 'role.executeRoleDelete.before': void;
51
+ 'role.executeRoleDelete.after': Role;
52
+ 'role.executeRoleDelete.async': Role;
53
+ 'collection.create.before': CreateCollectionInput;
54
+ 'collection.create.after': Collection;
55
+ 'collection.create.async': Collection;
56
+ 'collection.update.before': UpdateCollectionInput;
57
+ 'collection.update.after': Collection;
58
+ 'collection.update.async': Collection;
59
+ 'collection.executeCollectionDelete.before': void;
60
+ 'collection.executeCollectionDelete.after': Collection;
61
+ 'collection.executeCollectionDelete.async': Collection;
62
+ 'facet.create.before': CreateFacetInput;
63
+ 'facet.create.after': Facet;
64
+ 'facet.create.async': Facet;
65
+ 'facet.update.before': UpdateFacetInput;
66
+ 'facet.update.after': Facet;
67
+ 'facet.update.async': Facet;
68
+ 'facet.executeFacetDelete.before': void;
69
+ 'facet.executeFacetDelete.after': Facet;
70
+ 'facet.executeFacetDelete.async': Facet;
71
+ 'facetValue.create.before': CreateFacetValueInput;
72
+ 'facetValue.create.after': FacetValue;
73
+ 'facetValue.create.async': FacetValue;
74
+ 'facetValue.update.before': UpdateFacetValueInput;
75
+ 'facetValue.update.after': FacetValue;
76
+ 'facetValue.update.async': FacetValue;
77
+ 'facetValue.executeFacetValueDelete.before': void;
78
+ 'facetValue.executeFacetValueDelete.after': FacetValue;
79
+ 'facetValue.executeFacetValueDelete.async': FacetValue;
80
+ 'channel.create.before': CreateChannelInput;
81
+ 'channel.create.after': Channel;
82
+ 'channel.create.async': Channel;
83
+ 'channel.update.before': UpdateChannelInput;
84
+ 'channel.update.after': Channel;
85
+ 'channel.update.async': Channel;
86
+ 'channel.delete.before': string;
87
+ 'channel.delete.after': Channel;
88
+ 'channel.delete.async': Channel;
89
+ 'customer.create.before': CreateCustomerInput;
90
+ 'customer.create.after': Customer;
91
+ 'customer.create.async': Customer;
92
+ 'customer.update.before': UpdateCustomerInput;
93
+ 'customer.update.after': Customer;
94
+ 'customer.update.async': Customer;
95
+ 'customer.performSoftDelete.before': string;
96
+ 'customer.performSoftDelete.after': Customer;
97
+ 'customer.performSoftDelete.async': Customer;
98
+ 'customer.registerCustomerAccount.before': RegisterCustomerInput;
99
+ 'customer.registerCustomerAccount.after': Customer;
100
+ 'customer.registerCustomerAccount.async': Customer;
101
+ 'customer.createCustomerForRegistration.before': void;
102
+ 'customer.createCustomerForRegistration.after': Customer;
103
+ 'customer.createCustomerForRegistration.async': Customer;
104
+ 'customerGroup.create.before': CreateCustomerGroupInput;
105
+ 'customerGroup.create.after': CustomerGroup;
106
+ 'customerGroup.create.async': CustomerGroup;
107
+ 'customerGroup.update.before': UpdateCustomerGroupInput;
108
+ 'customerGroup.update.after': CustomerGroup;
109
+ 'customerGroup.update.async': CustomerGroup;
110
+ 'customerGroup.executeCustomerGroupDelete.before': void;
111
+ 'customerGroup.executeCustomerGroupDelete.after': CustomerGroup;
112
+ 'customerGroup.executeCustomerGroupDelete.async': CustomerGroup;
113
+ 'country.create.before': CreateCountryInput;
114
+ 'country.create.after': Country;
115
+ 'country.create.async': Country;
116
+ 'country.update.before': UpdateCountryInput;
117
+ 'country.update.after': Country;
118
+ 'country.update.async': Country;
119
+ 'country.executeCountryDelete.before': void;
120
+ 'country.executeCountryDelete.after': Country;
121
+ 'country.executeCountryDelete.async': Country;
122
+ 'zone.create.before': CreateZoneInput;
123
+ 'zone.create.after': Zone;
124
+ 'zone.create.async': Zone;
125
+ 'zone.update.before': UpdateZoneInput;
126
+ 'zone.update.after': Zone;
127
+ 'zone.update.async': Zone;
128
+ 'zone.delete.before': string;
129
+ 'zone.delete.after': Zone;
130
+ 'zone.delete.async': Zone;
131
+ 'product.create.before': CreateProductInput;
132
+ 'product.create.after': Product;
133
+ 'product.create.async': Product;
134
+ 'product.update.before': UpdateProductInput;
135
+ 'product.update.after': Product;
136
+ 'product.update.async': Product;
137
+ 'product.executeProductDelete.before': void;
138
+ 'product.executeProductDelete.after': Product;
139
+ 'product.executeProductDelete.async': Product;
140
+ 'productVariant.createSingleVariant.before': CreateProductVariantInput;
141
+ 'productVariant.createSingleVariant.after': ProductVariant;
142
+ 'productVariant.createSingleVariant.async': ProductVariant;
143
+ 'productVariant.updateSingleVariant.before': UpdateProductVariantInput;
144
+ 'productVariant.updateSingleVariant.after': ProductVariant;
145
+ 'productVariant.updateSingleVariant.async': ProductVariant;
146
+ 'productVariant.deleteSingleVariant.before': string;
147
+ 'productVariant.deleteSingleVariant.after': ProductVariant;
148
+ 'productVariant.deleteSingleVariant.async': ProductVariant;
149
+ 'promotion.create.before': CreatePromotionInput;
150
+ 'promotion.create.after': Promotion;
151
+ 'promotion.create.async': Promotion;
152
+ 'promotion.update.before': UpdatePromotionInput;
153
+ 'promotion.update.after': Promotion;
154
+ 'promotion.update.async': Promotion;
155
+ 'promotion.executePromotionDelete.before': void;
156
+ 'promotion.executePromotionDelete.after': Promotion;
157
+ 'promotion.executePromotionDelete.async': Promotion;
158
+ 'seller.create.before': CreateSellerInput;
159
+ 'seller.create.after': Seller;
160
+ 'seller.create.async': Seller;
161
+ 'seller.update.before': UpdateSellerInput;
162
+ 'seller.update.after': Seller;
163
+ 'seller.update.async': Seller;
164
+ 'seller.softDelete.before': string;
165
+ 'seller.softDelete.after': Seller;
166
+ 'seller.softDelete.async': Seller;
167
+ 'stockLocation.create.before': CreateStockLocationInput;
168
+ 'stockLocation.create.after': StockLocation;
169
+ 'stockLocation.create.async': StockLocation;
170
+ 'stockLocation.update.before': UpdateStockLocationInput;
171
+ 'stockLocation.update.after': StockLocation;
172
+ 'stockLocation.update.async': StockLocation;
173
+ 'stockLocation.executeStockLocationDelete.before': void;
174
+ 'stockLocation.executeStockLocationDelete.after': StockLocation;
175
+ 'stockLocation.executeStockLocationDelete.async': StockLocation;
176
+ 'taxCategory.create.before': CreateTaxCategoryInput;
177
+ 'taxCategory.create.after': TaxCategory;
178
+ 'taxCategory.create.async': TaxCategory;
179
+ 'taxCategory.update.before': UpdateTaxCategoryInput;
180
+ 'taxCategory.update.after': TaxCategory;
181
+ 'taxCategory.update.async': TaxCategory;
182
+ 'taxCategory.executeTaxCategoryDelete.before': void;
183
+ 'taxCategory.executeTaxCategoryDelete.after': TaxCategory;
184
+ 'taxCategory.executeTaxCategoryDelete.async': TaxCategory;
185
+ 'taxRate.create.before': CreateTaxRateInput;
186
+ 'taxRate.create.after': TaxRate;
187
+ 'taxRate.create.async': TaxRate;
188
+ 'taxRate.update.before': UpdateTaxRateInput;
189
+ 'taxRate.update.after': TaxRate;
190
+ 'taxRate.update.async': TaxRate;
191
+ 'taxRate.delete.before': string;
192
+ 'taxRate.delete.after': TaxRate;
193
+ 'taxRate.delete.async': TaxRate;
194
+ 'fulfillment.createFulfillment.before': CreateFulfillmentInput;
195
+ 'fulfillment.createFulfillment.after': Fulfillment;
196
+ 'fulfillment.createFulfillment.async': Fulfillment;
197
+ 'fulfillment.executeFulfillmentTransition.before': unknown;
198
+ 'fulfillment.executeFulfillmentTransition.after': unknown;
199
+ 'fulfillment.executeFulfillmentTransition.async': unknown;
200
+ 'order.createDraft.before': void;
201
+ 'order.createDraft.after': Order;
202
+ 'order.createDraft.async': Order;
203
+ 'order.create.before': void;
204
+ 'order.create.after': Order;
205
+ 'order.create.async': Order;
206
+ 'payment.executePaymentTransition.before': unknown;
207
+ 'payment.executePaymentTransition.after': unknown;
208
+ 'payment.executePaymentTransition.async': unknown;
209
+ 'channelPlugin.enable.before': string;
210
+ 'channelPlugin.enable.after': ChannelPlugin;
211
+ 'channelPlugin.enable.async': ChannelPlugin;
212
+ 'channelPlugin.disable.before': string;
213
+ 'channelPlugin.disable.after': ChannelPlugin;
214
+ 'channelPlugin.disable.async': ChannelPlugin;
215
+ 'channelPlugin.updateConfiguration.before': UpdateChannelPluginConfigInput;
216
+ 'channelPlugin.updateConfiguration.after': ChannelPlugin;
217
+ 'channelPlugin.updateConfiguration.async': ChannelPlugin;
218
+ 'history.createForOrder.before': unknown;
219
+ 'history.createForOrder.after': HistoryEntry;
220
+ 'history.createForOrder.async': HistoryEntry;
221
+ 'history.createForCustomer.before': unknown;
222
+ 'history.createForCustomer.after': HistoryEntry;
223
+ 'history.createForCustomer.async': HistoryEntry;
224
+ 'history.updateEntry.before': unknown;
225
+ 'history.updateEntry.after': HistoryEntry;
226
+ 'history.updateEntry.async': HistoryEntry;
227
+ 'history.deleteEntry.before': string;
228
+ 'history.deleteEntry.after': HistoryEntry;
229
+ 'history.deleteEntry.async': HistoryEntry;
230
+ 'audienceSegment.create.before': CreateAudienceSegmentInput;
231
+ 'audienceSegment.create.after': AudienceSegment;
232
+ 'audienceSegment.create.async': AudienceSegment;
233
+ 'audienceSegment.update.before': UpdateAudienceSegmentInput;
234
+ 'audienceSegment.update.after': AudienceSegment;
235
+ 'audienceSegment.update.async': AudienceSegment;
236
+ 'audienceSegment.delete.before': string;
237
+ 'audienceSegment.delete.after': AudienceSegment;
238
+ 'audienceSegment.delete.async': AudienceSegment;
239
+ 'audienceMembership.addIdentityToSegment.before': AddIdentityToSegmentInput;
240
+ 'audienceMembership.addIdentityToSegment.after': AudienceMembership;
241
+ 'audienceMembership.addIdentityToSegment.async': AudienceMembership;
242
+ 'audienceMembership.removeIdentityFromSegment.before': RemoveIdentityFromSegmentInput;
243
+ 'audienceMembership.removeIdentityFromSegment.after': AudienceMembership;
244
+ 'audienceMembership.removeIdentityFromSegment.async': AudienceMembership;
245
+ }
246
+
247
+ export type AdminHookPoint = keyof AdminHookEventMap;
248
+
249
+ export type AdminHookHandler<K extends AdminHookPoint> =
250
+ AdminHookEventMap[K] extends void
251
+ ? (ctx: TransactionContext) => Promise<void>
252
+ : (ctx: TransactionContext, payload: AdminHookEventMap[K]) => Promise<void>;
package/src/index.ts CHANGED
@@ -1,115 +1,23 @@
1
- /**
2
- * @forgecart/sdk - Auto-generated TypeScript SDK
3
- *
4
- * This file was automatically generated and should not be manually edited.
5
- * To regenerate, run: npm run codegen:ts
6
- *
7
- * 🤖 Generated with ForgeCart SDK Generator
8
- */
9
-
10
- import { AdminNamespace, AdminSDKConfig } from './admin.js'
11
- import { ShopNamespace, ShopSDKConfig } from './shop.js'
12
-
13
- /**
14
- * Unified SDK Configuration
15
- */
16
- export interface ForgeCartSDKConfig {
17
- /** Base API endpoint (e.g., 'https://api.forgecart.com') */
18
- endpoint?: string
19
- /** Channel token for Vendure multi-tenancy (required) */
20
- token: string
21
- /** Use HTTP only, skip WebSocket initialization (default: false) */
22
- httpOnly?: boolean
23
- /** Enable debug logging with request timing (default: false) */
24
- debug?: boolean
25
- /** Custom HTTP headers */
26
- headers?: Record<string, string>
27
- /** Custom WebSocket implementation (optional, auto-detected if not provided) */
28
- webSocketImpl?: unknown
29
- }
30
-
31
- // Re-export individual namespace configs and classes
32
- export type { AdminSDKConfig, ShopSDKConfig }
33
- export { AdminNamespace, ShopNamespace }
34
-
35
- /**
36
- * ForgeCartSDK
37
- * Unified SDK with categorized operations across multiple namespaces
38
- *
39
- * @example
40
- * ```typescript
41
- * const sdk = new ForgeCartSDK({
42
- * endpoint: 'https://api.forgecart.com',
43
- * token: 'your-channel-token',
44
- * });
45
- *
46
- * // Admin namespace → Category → Operations
47
- * await sdk.admin.products.products({ take: 10 });
48
- * await sdk.admin.customer.customer({ id: '1' });
49
- *
50
- * // Shop namespace → Category → Operations
51
- * await sdk.shop.products.products({ take: 10 });
52
- * await sdk.shop.order.addItemToOrder({ productVariantId: '1', quantity: 1 });
53
- * ```
54
- */
55
- export class ForgeCartSDK {
56
- readonly admin: AdminNamespace
57
- readonly shop: ShopNamespace
58
-
59
- constructor(config: ForgeCartSDKConfig) {
60
- // Validate channel token is provided
61
- if (!config.token || config.token.trim() === '') {
62
- throw new Error('ForgeCartSDK: Channel token is required. Please provide a valid "token" in the configuration.')
63
- }
64
-
65
- const baseEndpoint = config.endpoint || 'https://api.forgecart.com'
66
- const baseWsEndpoint = baseEndpoint.replace('http', 'ws')
67
-
68
- // Build headers with token
69
- const headers: Record<string, string> = {
70
- ...config.headers,
71
- 'forge-token': config.token,
72
- }
73
-
74
- const adminConfig: AdminSDKConfig = {
75
- endpoint: `${baseEndpoint}/admin-api`,
76
- wsEndpoint: `${baseWsEndpoint}/admin-api`,
77
- headers,
78
- webSocketImpl: config.webSocketImpl,
79
- httpOnly: config.httpOnly,
80
- debug: config.debug,
81
- }
82
- this.admin = new AdminNamespace(adminConfig)
83
-
84
- const shopConfig: ShopSDKConfig = {
85
- endpoint: `${baseEndpoint}/shop-api`,
86
- wsEndpoint: `${baseWsEndpoint}/shop-api`,
87
- headers,
88
- webSocketImpl: config.webSocketImpl,
89
- httpOnly: config.httpOnly,
90
- debug: config.debug,
91
- }
92
- this.shop = new ShopNamespace(shopConfig)
93
- }
94
-
95
- setAdminAuthToken(token: string): void {
96
- this.admin.setAuthToken(token)
97
- }
98
-
99
- clearAdminAuthToken(): void {
100
- this.admin.clearAuthToken()
101
- }
102
-
103
- setShopAuthToken(token: string): void {
104
- this.shop.setAuthToken(token)
105
- }
106
-
107
- clearShopAuthToken(): void {
108
- this.shop.clearAuthToken()
109
- }
110
-
111
- dispose(): void {
112
- this.admin.dispose()
113
- this.shop.dispose()
114
- }
115
- }
1
+ export { ForgeCartAdminClient } from './client.generated';
2
+ export { ForgeCartShopClient } from './client.generated';
3
+ export { ForgeCartClient, ClientError, QueryObservable } from './client.generated';
4
+ export type { GraphQLErrorResponse } from './client.generated';
5
+ export type { ForgeCartAdminClientConfig } from './client.generated';
6
+ export type { ForgeCartShopClientConfig } from './client.generated';
7
+ export type { ForgeCartClientConfig } from './client.generated';
8
+ export { TransactionContext } from './client.generated';
9
+ export { ForgeCartGraphQLModule } from './client.generated';
10
+ export { AdminNamespace } from './admin.generated';
11
+ export { ShopNamespace } from './shop.generated';
12
+ export type { ID, Type, ApiExtension, IRequestContext, HookHandler } from './sdk-types.generated';
13
+ export type { IFulfillmentHandler, FulfillmentHandlerCapabilities, OrderLineInput } from './sdk-types.generated';
14
+ export { SdkError, SdkErrorCode } from './sdk-types.generated';
15
+ export type { ConfigurationItem, ManageableConfig, IHookRegistry } from './sdk-plugin.generated';
16
+ export { ForgeCartPlugin } from './sdk-plugin.generated';
17
+ export type { HookDispatchEvent, HookSubscription } from './sdk-hook-subscription.generated';
18
+ export { hookDispatchDocument, hookRespondDocument, HookSubscriptionManager } from './sdk-hook-subscription.generated';
19
+ export type { AdminHookEventMap, AdminHookPoint, AdminHookHandler } from './hook-event-map.generated';
20
+ export type { AcfFieldType } from './admin-types.generated';
21
+ export { extractErrorCode, extractError, extractErrorMessage, isErrorCode } from './error-utils';
22
+ export type { ExtractedError } from './error-utils';
23
+ export { Observable, firstValueFrom, lastValueFrom } from 'rxjs';
@@ -0,0 +1,93 @@
1
+ /* eslint-disable */
2
+ /**
3
+ * AUTO-GENERATED FILE — DO NOT EDIT
4
+ *
5
+ * This file was generated by @forgecart/client-sdk-generators.
6
+ * Any manual changes will be overwritten on the next generation run.
7
+ */
8
+
9
+ import { Observable, firstValueFrom } from 'rxjs';
10
+ import type { IRequestContext } from './sdk-types.generated';
11
+
12
+ export interface HookDispatchEvent {
13
+ id: string;
14
+ hookPoint: string;
15
+ transactionToken: string;
16
+ subscriberId: string;
17
+ args: unknown[];
18
+ }
19
+
20
+ export const hookDispatchDocument = `
21
+ subscription OnHookDispatch($hookPoints: [String!]!) {
22
+ hookDispatched(hookPoints: $hookPoints) {
23
+ id
24
+ hookPoint
25
+ transactionToken
26
+ subscriberId
27
+ args
28
+ }
29
+ }
30
+ `;
31
+
32
+ export const hookRespondDocument = `
33
+ mutation RespondToHook($input: RespondToHookDispatchInput!) {
34
+ respondToHookDispatch(input: $input)
35
+ }
36
+ `;
37
+
38
+ export interface HookSubscription {
39
+ unsubscribe(): void;
40
+ readonly closed: Promise<void>;
41
+ }
42
+
43
+ export class HookSubscriptionManager<TContext = unknown> {
44
+ constructor(
45
+ private readonly subscribeFn: (hookPoints: string[]) => Observable<{ hookDispatched: HookDispatchEvent }>,
46
+ private readonly respondFn: (id: string, subscriberId: string, error?: string) => Observable<unknown>,
47
+ private readonly createContext: (transactionToken: string) => TContext,
48
+ ) {}
49
+
50
+ on(
51
+ hookPoints: string[],
52
+ handler: (ctx: TContext, payload?: unknown) => Promise<void>,
53
+ ): HookSubscription {
54
+ let resolveClose: (() => void) | undefined;
55
+ const closed = new Promise<void>((resolve) => { resolveClose = resolve; });
56
+
57
+ const subscription = this.subscribeFn(hookPoints).subscribe({
58
+ next: async (value) => {
59
+ const event = value.hookDispatched;
60
+ const suffix = event.hookPoint.split('.').pop();
61
+ const ctx = this.createContext(event.transactionToken);
62
+ const payload = Array.isArray(event.args) && event.args.length > 0
63
+ ? event.args[0]
64
+ : undefined;
65
+ try {
66
+ await handler(ctx, payload);
67
+ if (suffix === 'before' || suffix === 'after') {
68
+ await firstValueFrom(this.respondFn(event.id, event.subscriberId));
69
+ }
70
+ } catch (error: unknown) {
71
+ if (suffix === 'before' || suffix === 'after') {
72
+ await firstValueFrom(this.respondFn(
73
+ event.id,
74
+ event.subscriberId,
75
+ error instanceof Error ? error.message : String(error),
76
+ ));
77
+ }
78
+ }
79
+ },
80
+ error: () => {
81
+ resolveClose?.();
82
+ },
83
+ complete: () => {
84
+ resolveClose?.();
85
+ },
86
+ });
87
+
88
+ return {
89
+ unsubscribe: () => { subscription.unsubscribe(); },
90
+ closed,
91
+ };
92
+ }
93
+ }
@@ -0,0 +1,59 @@
1
+ /* eslint-disable */
2
+ /**
3
+ * AUTO-GENERATED FILE — DO NOT EDIT
4
+ *
5
+ * This file was generated by @forgecart/client-sdk-generators.
6
+ * Any manual changes will be overwritten on the next generation run.
7
+ */
8
+
9
+ import type { Type, ApiExtension, HookHandler } from './sdk-types.generated';
10
+
11
+ export interface ConfigurationItem {
12
+ readonly code: string;
13
+ readonly label: string;
14
+ readonly description?: string;
15
+ readonly type: 'string' | 'number' | 'boolean' | 'json';
16
+ readonly defaultValue?: unknown;
17
+ }
18
+
19
+ export interface ManageableConfig {
20
+ readonly description: string;
21
+ readonly imageUrl?: string;
22
+ readonly tags: string[];
23
+ readonly configurationItems: ConfigurationItem[];
24
+ }
25
+
26
+ export interface IHookRegistry {
27
+ on(
28
+ hookPoint: string,
29
+ handler: HookHandler,
30
+ priority?: number,
31
+ ): void;
32
+ }
33
+
34
+ export abstract class ForgeCartPlugin {
35
+ abstract readonly code: string;
36
+ abstract readonly name: string;
37
+ abstract readonly version: string;
38
+
39
+ readonly entities: Type[] = [];
40
+ readonly services: Type[] = [];
41
+ readonly resolvers: Type[] = [];
42
+ readonly controllers: Type[] = [];
43
+ readonly adminApiExtensions?: ApiExtension;
44
+ readonly shopApiExtensions?: ApiExtension;
45
+
46
+ register(_hooks: IHookRegistry): void {
47
+ // no-op default
48
+ }
49
+ onBootstrap(): Promise<void> {
50
+ // no-op default
51
+ return Promise.resolve();
52
+ }
53
+ onShutdown(): Promise<void> {
54
+ // no-op default
55
+ return Promise.resolve();
56
+ }
57
+
58
+ readonly manageable?: ManageableConfig;
59
+ }