@forgecart/sdk 1.0.0 → 1.2.1

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.
@@ -1,16 +1,19 @@
1
+ "use strict";
1
2
  /**
2
3
  * @forgecart/sdk - Auto-generated TypeScript SDK
3
4
  *
4
5
  * This file was automatically generated and should not be manually edited.
5
6
  * To regenerate, run: npm run codegen:ts
6
7
  *
7
- * Generated at: 2025-12-12T11:13:16.730Z
8
+ * Generated at: 2025-12-15T07:01:16.361Z
8
9
  * Generator version: 1.0.0
9
10
  *
10
11
  * 🤖 Generated with ForgeCart SDK Generator
11
12
  */
12
- import { GraphQLClient } from 'graphql-request';
13
- import { createClient } from 'graphql-ws';
13
+ Object.defineProperty(exports, "__esModule", { value: true });
14
+ exports.AdminNamespace = exports.AllEvents = exports.CatalogEvents = exports.PaymentEvents = exports.FulfillmentEvents = exports.CustomerEvents = exports.OrderEvents = exports.ProductEvents = void 0;
15
+ const graphql_request_1 = require("graphql-request");
16
+ const graphql_ws_1 = require("graphql-ws");
14
17
  const activeAdministratorDocument = `query activeAdministrator {
15
18
  activeAdministrator {
16
19
  id
@@ -3375,6 +3378,96 @@ const deleteCustomerNoteDocument = `mutation deleteCustomerNote($id: ID!) {
3375
3378
  message
3376
3379
  }
3377
3380
  }`;
3381
+ const deploymentsDocument = `query Deployments {
3382
+ deployments {
3383
+ id
3384
+ type
3385
+ status
3386
+ url
3387
+ instances
3388
+ lastDeployedAt
3389
+ errorMessage
3390
+ }
3391
+ }`;
3392
+ const deploymentDocument = `query Deployment($type: DeploymentType!) {
3393
+ deployment(type: $type) {
3394
+ id
3395
+ type
3396
+ status
3397
+ url
3398
+ instances
3399
+ lastDeployedAt
3400
+ errorMessage
3401
+ }
3402
+ }`;
3403
+ const deploymentEnvDocument = `query DeploymentEnv($type: DeploymentType!) {
3404
+ deploymentEnv(type: $type) {
3405
+ key
3406
+ value
3407
+ }
3408
+ }`;
3409
+ const channelInfoDocument = `query ChannelInfo {
3410
+ channelInfo {
3411
+ id
3412
+ code
3413
+ name
3414
+ domain
3415
+ hasApplication
3416
+ applicationName
3417
+ }
3418
+ }`;
3419
+ const validateChannelTokenDocument = `query ValidateChannelToken {
3420
+ validateChannelToken
3421
+ }`;
3422
+ const createDeploymentDocument = `mutation CreateDeployment($input: CreateDeploymentInput!) {
3423
+ createDeployment(input: $input) {
3424
+ id
3425
+ type
3426
+ status
3427
+ url
3428
+ instances
3429
+ lastDeployedAt
3430
+ errorMessage
3431
+ }
3432
+ }`;
3433
+ const deleteDeploymentDocument = `mutation DeleteDeployment($type: DeploymentType!) {
3434
+ deleteDeployment(type: $type)
3435
+ }`;
3436
+ const scaleDeploymentDocument = `mutation ScaleDeployment($input: ScaleDeploymentInput!) {
3437
+ scaleDeployment(input: $input) {
3438
+ id
3439
+ type
3440
+ status
3441
+ url
3442
+ instances
3443
+ lastDeployedAt
3444
+ errorMessage
3445
+ }
3446
+ }`;
3447
+ const setDeploymentEnvDocument = `mutation SetDeploymentEnv($input: SetEnvInput!) {
3448
+ setDeploymentEnv(input: $input)
3449
+ }`;
3450
+ const unsetDeploymentEnvDocument = `mutation UnsetDeploymentEnv($input: UnsetEnvInput!) {
3451
+ unsetDeploymentEnv(input: $input)
3452
+ }`;
3453
+ const refreshDeploymentStatusDocument = `mutation RefreshDeploymentStatus($type: DeploymentType!) {
3454
+ refreshDeploymentStatus(type: $type) {
3455
+ id
3456
+ type
3457
+ status
3458
+ url
3459
+ instances
3460
+ lastDeployedAt
3461
+ errorMessage
3462
+ }
3463
+ }`;
3464
+ const deploymentLogsDocument = `subscription DeploymentLogs($type: DeploymentType!) {
3465
+ deploymentLogs(type: $type) {
3466
+ timestamp
3467
+ message
3468
+ type
3469
+ }
3470
+ }`;
3378
3471
  const entityDuplicatorsDocument = `query entityDuplicators {
3379
3472
  entityDuplicators {
3380
3473
  code
@@ -3404,6 +3497,18 @@ const duplicateEntityDocument = `mutation duplicateEntity($input: DuplicateEntit
3404
3497
  }
3405
3498
  }
3406
3499
  }`;
3500
+ const entityEventDocument = `subscription entityEvent($categories: [EventCategory!]) {
3501
+ entityEvent(categories: $categories) {
3502
+ channelId
3503
+ eventName
3504
+ eventClass
3505
+ type
3506
+ entityId
3507
+ entity
3508
+ input
3509
+ timestamp
3510
+ }
3511
+ }`;
3407
3512
  const facetDocument = `query facet($id: ID!) {
3408
3513
  facet(id: $id) {
3409
3514
  id
@@ -6782,9 +6887,29 @@ class BaseGraphQLClient {
6782
6887
  this.endpoint = config.endpoint || 'https://api.forgecart.com/admin-api';
6783
6888
  this.wsEndpoint = config.wsEndpoint || 'wss://api.forgecart.com/admin-api';
6784
6889
  this.config = config;
6785
- // Initialize HTTP client (as fallback)
6786
- this.httpClient = new GraphQLClient(this.endpoint, {
6890
+ // Custom fetch that captures session token from response headers
6891
+ const customFetch = async (url, options) => {
6892
+ const response = await fetch(url, options);
6893
+ // Capture session token from response header
6894
+ const authToken = response.headers.get('forge-auth-token');
6895
+ if (authToken && authToken !== this.authToken) {
6896
+ this.authToken = authToken;
6897
+ // Reconnect WebSocket with new token
6898
+ if (this.wsClient) {
6899
+ this.wsConnected = false;
6900
+ this.wsClient.dispose();
6901
+ this.wsClient = null;
6902
+ this.wsInitializing = null;
6903
+ this.initializeWebSocket();
6904
+ }
6905
+ }
6906
+ return response;
6907
+ };
6908
+ // Initialize HTTP client with custom fetch
6909
+ this.httpClient = new graphql_request_1.GraphQLClient(this.endpoint, {
6787
6910
  headers: config.headers || {},
6911
+ credentials: 'include',
6912
+ fetch: customFetch,
6788
6913
  });
6789
6914
  // Initialize WebSocket connection immediately
6790
6915
  this.initializeWebSocket();
@@ -6878,6 +7003,10 @@ class BaseGraphQLClient {
6878
7003
  * Connects immediately and tracks connection state
6879
7004
  */
6880
7005
  initializeWebSocket() {
7006
+ // Skip WebSocket if httpOnly mode is enabled
7007
+ if (this.config.httpOnly) {
7008
+ return;
7009
+ }
6881
7010
  // Prevent multiple simultaneous initializations
6882
7011
  if (this.wsClient || this.wsInitializing) {
6883
7012
  return;
@@ -6897,7 +7026,20 @@ class BaseGraphQLClient {
6897
7026
  keepAlive: 10000, // Send keep-alive pings every 10 seconds
6898
7027
  connectionParams: async () => {
6899
7028
  try {
6900
- return this.authToken ? { Authorization: `Bearer ${this.authToken}` } : {};
7029
+ const params = {};
7030
+ // Add session token if available
7031
+ if (this.authToken) {
7032
+ params.Authorization = `bearer ${this.authToken}`;
7033
+ }
7034
+ // Pass all configured headers (including forge-token for channel)
7035
+ if (this.config.headers) {
7036
+ Object.entries(this.config.headers).forEach(([key, value]) => {
7037
+ if (value) {
7038
+ params[key] = value;
7039
+ }
7040
+ });
7041
+ }
7042
+ return params;
6901
7043
  }
6902
7044
  catch (error) {
6903
7045
  console.error('Error in connectionParams:', error);
@@ -6936,7 +7078,7 @@ class BaseGraphQLClient {
6936
7078
  },
6937
7079
  },
6938
7080
  };
6939
- this.wsClient = createClient(wsOptions);
7081
+ this.wsClient = (0, graphql_ws_1.createClient)(wsOptions);
6940
7082
  this.wsInitializing = null;
6941
7083
  }
6942
7084
  catch (error) {
@@ -7033,6 +7175,40 @@ class BaseGraphQLClient {
7033
7175
  }
7034
7176
  }
7035
7177
  }
7178
+ // Event categories for filtering
7179
+ exports.ProductEvents = [
7180
+ 'product.created', 'product.updated', 'product.deleted',
7181
+ 'product.variant.created', 'product.variant.updated', 'product.variant.deleted',
7182
+ 'product.option.created', 'product.option.updated', 'product.option.deleted',
7183
+ 'product.optionGroup.created', 'product.optionGroup.updated', 'product.optionGroup.deleted',
7184
+ 'product.variant.price.updated',
7185
+ ];
7186
+ exports.OrderEvents = [
7187
+ 'order.stateTransition', 'order.placementStateTransition', 'order.line.event',
7188
+ 'order.paymentStateTransition', 'order.refundStateTransition',
7189
+ 'order.coupon.applied', 'order.coupon.removed',
7190
+ ];
7191
+ exports.CustomerEvents = [
7192
+ 'customer.created', 'customer.updated', 'customer.deleted',
7193
+ 'customer.address.created', 'customer.address.updated', 'customer.address.deleted',
7194
+ 'customer.groupChange', 'customer.login', 'customer.loginfail',
7195
+ ];
7196
+ exports.FulfillmentEvents = [
7197
+ 'fulfillment.created', 'fulfillment.stateTransition',
7198
+ ];
7199
+ exports.PaymentEvents = [
7200
+ 'payment.stateTransition', 'payment.method.created', 'payment.method.updated', 'payment.method.deleted',
7201
+ ];
7202
+ exports.CatalogEvents = [
7203
+ 'collection.created', 'collection.updated', 'collection.deleted', 'collection.modification',
7204
+ 'facet.created', 'facet.updated', 'facet.deleted',
7205
+ 'facetValue.created', 'facetValue.updated', 'facetValue.deleted',
7206
+ 'asset.created', 'asset.updated', 'asset.deleted',
7207
+ ];
7208
+ exports.AllEvents = [
7209
+ ...exports.ProductEvents, ...exports.OrderEvents, ...exports.CustomerEvents,
7210
+ ...exports.FulfillmentEvents, ...exports.PaymentEvents, ...exports.CatalogEvents,
7211
+ ];
7036
7212
  /**
7037
7213
  * Administrator operations
7038
7214
  */
@@ -7072,9 +7248,16 @@ class AdministratorOperations {
7072
7248
  }
7073
7249
  /**
7074
7250
  * login mutation
7251
+ * Automatically sets the auth token on successful login
7075
7252
  */
7076
7253
  async login(variables) {
7077
- return await this.client.request(loginDocument, variables);
7254
+ const response = await this.client.request(loginDocument, variables);
7255
+ // Auto-set auth token if login was successful
7256
+ const loginResult = response?.login;
7257
+ if (loginResult && loginResult.__typename === 'CurrentUser' && loginResult.sessionToken) {
7258
+ this.client.setAuthToken(loginResult.sessionToken);
7259
+ }
7260
+ return response;
7078
7261
  }
7079
7262
  /**
7080
7263
  * logout mutation
@@ -7977,6 +8160,89 @@ class CustomerOperations {
7977
8160
  return await this.client.request(deleteCustomerNoteDocument, variables);
7978
8161
  }
7979
8162
  }
8163
+ /**
8164
+ * Deployment operations
8165
+ */
8166
+ class DeploymentOperations {
8167
+ constructor(client) {
8168
+ this.client = client;
8169
+ }
8170
+ /**
8171
+ * Deployments query
8172
+ */
8173
+ async deployments() {
8174
+ return await this.client.request(deploymentsDocument);
8175
+ }
8176
+ /**
8177
+ * Deployment query
8178
+ */
8179
+ async deployment(variables) {
8180
+ return await this.client.request(deploymentDocument, variables);
8181
+ }
8182
+ /**
8183
+ * DeploymentEnv query
8184
+ */
8185
+ async deploymentEnv(variables) {
8186
+ return await this.client.request(deploymentEnvDocument, variables);
8187
+ }
8188
+ /**
8189
+ * ChannelInfo query
8190
+ */
8191
+ async channelInfo() {
8192
+ return await this.client.request(channelInfoDocument);
8193
+ }
8194
+ /**
8195
+ * ValidateChannelToken query
8196
+ */
8197
+ async validateChannelToken() {
8198
+ return await this.client.request(validateChannelTokenDocument);
8199
+ }
8200
+ /**
8201
+ * CreateDeployment mutation
8202
+ */
8203
+ async createDeployment(variables) {
8204
+ return await this.client.request(createDeploymentDocument, variables);
8205
+ }
8206
+ /**
8207
+ * DeleteDeployment mutation
8208
+ */
8209
+ async deleteDeployment(variables) {
8210
+ return await this.client.request(deleteDeploymentDocument, variables);
8211
+ }
8212
+ /**
8213
+ * ScaleDeployment mutation
8214
+ */
8215
+ async scaleDeployment(variables) {
8216
+ return await this.client.request(scaleDeploymentDocument, variables);
8217
+ }
8218
+ /**
8219
+ * SetDeploymentEnv mutation
8220
+ */
8221
+ async setDeploymentEnv(variables) {
8222
+ return await this.client.request(setDeploymentEnvDocument, variables);
8223
+ }
8224
+ /**
8225
+ * UnsetDeploymentEnv mutation
8226
+ */
8227
+ async unsetDeploymentEnv(variables) {
8228
+ return await this.client.request(unsetDeploymentEnvDocument, variables);
8229
+ }
8230
+ /**
8231
+ * RefreshDeploymentStatus mutation
8232
+ */
8233
+ async refreshDeploymentStatus(variables) {
8234
+ return await this.client.request(refreshDeploymentStatusDocument, variables);
8235
+ }
8236
+ /**
8237
+ * DeploymentLogs subscription
8238
+ */
8239
+ async *deploymentLogs(variables) {
8240
+ const iterator = this.client.subscribe(deploymentLogsDocument, variables);
8241
+ for await (const data of iterator) {
8242
+ yield data;
8243
+ }
8244
+ }
8245
+ }
7980
8246
  /**
7981
8247
  * EntityDuplication operations
7982
8248
  */
@@ -7997,6 +8263,23 @@ class EntityDuplicationOperations {
7997
8263
  return await this.client.request(duplicateEntityDocument, variables);
7998
8264
  }
7999
8265
  }
8266
+ /**
8267
+ * EntityEvents operations
8268
+ */
8269
+ class EntityEventsOperations {
8270
+ constructor(client) {
8271
+ this.client = client;
8272
+ }
8273
+ /**
8274
+ * entityEvent subscription
8275
+ */
8276
+ async *entityEvent(variables) {
8277
+ const iterator = this.client.subscribe(entityEventDocument, variables);
8278
+ for await (const data of iterator) {
8279
+ yield data;
8280
+ }
8281
+ }
8282
+ }
8000
8283
  /**
8001
8284
  * Facet operations
8002
8285
  */
@@ -9122,8 +9405,17 @@ class ZoneOperations {
9122
9405
  * Admin namespace
9123
9406
  * Contains categorized operations for admin API
9124
9407
  */
9125
- export class AdminNamespace {
9408
+ class AdminNamespace {
9126
9409
  constructor(config) {
9410
+ // Event handler registry and state
9411
+ this.eventRegistry = {
9412
+ handlers: new Map(),
9413
+ blockingHandlers: new Map(),
9414
+ };
9415
+ this.eventSubscription = null;
9416
+ this.isListening = false;
9417
+ this.retryCount = 0;
9418
+ this.abortController = null;
9127
9419
  this.client = new BaseGraphQLClient(config);
9128
9420
  this.administrator = new AdministratorOperations(this.client);
9129
9421
  this.asset = new AssetOperations(this.client);
@@ -9135,7 +9427,9 @@ export class AdminNamespace {
9135
9427
  this.customFields = new CustomFieldsOperations(this.client);
9136
9428
  this.customerGroup = new CustomerGroupOperations(this.client);
9137
9429
  this.customer = new CustomerOperations(this.client);
9430
+ this.deployment = new DeploymentOperations(this.client);
9138
9431
  this.entityDuplication = new EntityDuplicationOperations(this.client);
9432
+ this.entityEvents = new EntityEventsOperations(this.client);
9139
9433
  this.facet = new FacetOperations(this.client);
9140
9434
  this.fulfillment = new FulfillmentOperations(this.client);
9141
9435
  this.globalSettings = new GlobalSettingsOperations(this.client);
@@ -9178,4 +9472,143 @@ export class AdminNamespace {
9178
9472
  dispose() {
9179
9473
  this.client.dispose();
9180
9474
  }
9475
+ /**
9476
+ * Register a non-blocking event handler
9477
+ * The callback will be called for each matching event without waiting
9478
+ */
9479
+ registerEventHandler(eventName, callback) {
9480
+ if (!this.eventRegistry.handlers.has(eventName)) {
9481
+ this.eventRegistry.handlers.set(eventName, new Set());
9482
+ }
9483
+ this.eventRegistry.handlers.get(eventName).add(callback);
9484
+ void this.ensureEventListening();
9485
+ return {
9486
+ unsubscribe: () => {
9487
+ this.eventRegistry.handlers.get(eventName)?.delete(callback);
9488
+ },
9489
+ };
9490
+ }
9491
+ /**
9492
+ * Register a blocking event handler
9493
+ * The callback must complete within 1000ms or it will timeout
9494
+ */
9495
+ registerBlockingEventHandler(eventName, callback) {
9496
+ if (!this.eventRegistry.blockingHandlers.has(eventName)) {
9497
+ this.eventRegistry.blockingHandlers.set(eventName, new Set());
9498
+ }
9499
+ this.eventRegistry.blockingHandlers.get(eventName).add(callback);
9500
+ void this.ensureEventListening();
9501
+ return {
9502
+ unsubscribe: () => {
9503
+ this.eventRegistry.blockingHandlers.get(eventName)?.delete(callback);
9504
+ },
9505
+ };
9506
+ }
9507
+ /**
9508
+ * Start listening to events with retry logic
9509
+ */
9510
+ async ensureEventListening() {
9511
+ if (this.isListening)
9512
+ return;
9513
+ this.isListening = true;
9514
+ this.retryCount = 0;
9515
+ this.abortController = new AbortController();
9516
+ await this.startSubscription();
9517
+ }
9518
+ async startSubscription() {
9519
+ try {
9520
+ this.eventSubscription = this.client.subscribe(entityEventDocument, {});
9521
+ // Reset retry count on successful connection
9522
+ this.retryCount = 0;
9523
+ // Process events
9524
+ for await (const result of this.eventSubscription) {
9525
+ if (!this.isListening)
9526
+ break;
9527
+ const event = result.entityEvent;
9528
+ await this.dispatchEvent(event);
9529
+ }
9530
+ }
9531
+ catch (error) {
9532
+ if (this.isListening) {
9533
+ console.error('Event subscription error:', error);
9534
+ await this.handleReconnect();
9535
+ }
9536
+ }
9537
+ }
9538
+ async handleReconnect() {
9539
+ const { maxRetries, baseDelayMs, maxDelayMs, backoffMultiplier } = AdminNamespace.RECONNECT_CONFIG;
9540
+ if (this.retryCount >= maxRetries) {
9541
+ this.isListening = false;
9542
+ throw new Error(`Max reconnection attempts (${maxRetries}) exceeded`);
9543
+ }
9544
+ // Calculate delay with exponential backoff
9545
+ const delay = Math.min(baseDelayMs * Math.pow(backoffMultiplier, this.retryCount), maxDelayMs);
9546
+ this.retryCount++;
9547
+ console.log(`Reconnecting in ${delay}ms (attempt ${this.retryCount}/${maxRetries})`);
9548
+ await new Promise(resolve => setTimeout(resolve, delay));
9549
+ await this.startSubscription();
9550
+ }
9551
+ /**
9552
+ * Dispatch event to registered handlers
9553
+ */
9554
+ async dispatchEvent(event) {
9555
+ const eventName = event.eventName;
9556
+ // Non-blocking handlers (fire-and-forget)
9557
+ const handlers = this.eventRegistry.handlers.get(eventName);
9558
+ if (handlers) {
9559
+ for (const handler of handlers) {
9560
+ try {
9561
+ handler(event);
9562
+ }
9563
+ catch (error) {
9564
+ console.error(`Error in event handler for ${eventName}:`, error);
9565
+ }
9566
+ }
9567
+ }
9568
+ // Blocking handlers (with timeout)
9569
+ const blockingHandlers = this.eventRegistry.blockingHandlers.get(eventName);
9570
+ if (blockingHandlers) {
9571
+ for (const handler of blockingHandlers) {
9572
+ try {
9573
+ await this.executeWithTimeout(handler(event), AdminNamespace.BLOCKING_TIMEOUT_MS, `Blocking handler for ${eventName} exceeded ${AdminNamespace.BLOCKING_TIMEOUT_MS}ms`);
9574
+ }
9575
+ catch (error) {
9576
+ console.error(`Error in blocking event handler for ${eventName}:`, error);
9577
+ throw error; // Re-throw for blocking handlers
9578
+ }
9579
+ }
9580
+ }
9581
+ }
9582
+ /**
9583
+ * Execute promise with timeout
9584
+ */
9585
+ async executeWithTimeout(promise, timeoutMs, errorMessage) {
9586
+ return Promise.race([
9587
+ promise,
9588
+ new Promise((_, reject) => setTimeout(() => reject(new Error(errorMessage)), timeoutMs)),
9589
+ ]);
9590
+ }
9591
+ /**
9592
+ * Stop all event listening
9593
+ */
9594
+ stopEventListening() {
9595
+ this.isListening = false;
9596
+ this.retryCount = 0;
9597
+ if (this.abortController) {
9598
+ this.abortController.abort();
9599
+ this.abortController = null;
9600
+ }
9601
+ this.eventSubscription = null;
9602
+ this.eventRegistry.handlers.clear();
9603
+ this.eventRegistry.blockingHandlers.clear();
9604
+ }
9181
9605
  }
9606
+ exports.AdminNamespace = AdminNamespace;
9607
+ // Reconnection configuration
9608
+ AdminNamespace.RECONNECT_CONFIG = {
9609
+ maxRetries: 5,
9610
+ baseDelayMs: 1000,
9611
+ maxDelayMs: 30000,
9612
+ backoffMultiplier: 2,
9613
+ };
9614
+ AdminNamespace.BLOCKING_TIMEOUT_MS = 1000;