@godaddy/gd-commerce-server 0.1.1 → 0.2.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/README.md CHANGED
@@ -57,3 +57,24 @@ Configure `checkoutReturnUrls` on the router using trusted deployment settings.
57
57
  Without this policy, HTTP checkout returns 503 before creating a session. Invalid request destinations return 400. This applies to both router presets that expose checkout. Trusted in-process callers of `createCheckoutSession()` own their return URLs and must construct or validate them server-side.
58
58
 
59
59
  A return from hosted checkout is not proof of payment. The order-status route uses the authorized Orders REST API, which supports completed orders, and returns its payment status (for example `PAID` or `PENDING`; `unknown` if absent). The server OAuth client must be granted `commerce.order:read`. The helper verifies the returned order ID, store, and channel and returns a limited summary without customer contact data. Hosts must authenticate callers and authorize access to each requested order before exposing this route.
60
+
61
+ ### Connection state
62
+
63
+ Hosts can implement the optional synchronous `CommerceConfiguration.readConnectionState()`
64
+ method. Its return type is exported as `CommerceConnectionState` (`unbound | connecting | ready`).
65
+ Returning `undefined` keeps the existing behavior. Throw when the state is unknown or cannot be
66
+ read. The default environment configuration does not implement this method, so missing
67
+ credentials never count as `unbound`.
68
+
69
+ `GET /config` returns `{ state: 'unbound' }` or `{ state: 'connecting' }` without reading store
70
+ credentials. `ready` includes the usual opaque `cartScope` and `currencyCode` after `read()`
71
+ succeeds. Without this method, the successful response shape is unchanged. All responses are
72
+ uncached; a malformed state or unavailable configuration returns 503. Data and checkout routes,
73
+ and the in-process checkout and order helpers, reject any state other than `ready` before
74
+ upstream calls.
75
+
76
+ The host owns the connection lifecycle. Report `ready` only after the store connection is
77
+ complete. Lost configuration is an error, never evidence of `unbound`. After a store connects,
78
+ report `unbound` again only after it is deliberately disconnected. The storefront package owns
79
+ the generic sample products and local sample cart; this server never creates sample Commerce
80
+ records or simulates checkout.
package/dist/index.d.ts CHANGED
@@ -39,7 +39,10 @@ interface CommerceConfig {
39
39
  /** Optional host-owned attribution shared by draft orders and checkout. */
40
40
  owner?: string;
41
41
  }
42
+ type CommerceConnectionState = 'unbound' | 'connecting' | 'ready';
42
43
  interface CommerceConfiguration {
44
+ /** Authoritative host state. Missing support preserves legacy live/error behavior. */
45
+ readConnectionState?(): CommerceConnectionState | undefined;
43
46
  read(): CommerceConfig;
44
47
  readCheckout(): CommerceCheckoutConfiguration;
45
48
  }
@@ -143,4 +146,4 @@ declare function createCommerceRouter(options?: CreateCommerceRouterOptions): Ro
143
146
  declare function createCommerceCatalogRouter(configuration?: CommerceConfiguration): Router;
144
147
  declare function createGoDaddyPaymentsRouter(configuration?: CommerceConfiguration, checkoutReturnUrls?: CheckoutReturnUrls): Router;
145
148
  //#endregion
146
- export { type CheckoutReturnUrls, type CheckoutSession, type CommerceCheckoutConfiguration, type CommerceCheckoutShippingConfiguration, type CommerceConfig, type CommerceConfiguration, type CommerceOrderStatus, type CommerceRouterFeatures, type CreateCheckoutSessionParams, type CreateCommerceRouterOptions, type RuntimeCommerceConfigurationOptions, createCheckoutSession, createCommerceCatalogRouter, createCommerceRouter, createGoDaddyPaymentsRouter, createRuntimeCommerceConfiguration, getOrderStatus, parseCommerceCheckoutConfiguration, readCommerceConfig };
149
+ export { type CheckoutReturnUrls, type CheckoutSession, type CommerceCheckoutConfiguration, type CommerceCheckoutShippingConfiguration, type CommerceConfig, type CommerceConfiguration, type CommerceConnectionState, type CommerceOrderStatus, type CommerceRouterFeatures, type CreateCheckoutSessionParams, type CreateCommerceRouterOptions, type RuntimeCommerceConfigurationOptions, createCheckoutSession, createCommerceCatalogRouter, createCommerceRouter, createGoDaddyPaymentsRouter, createRuntimeCommerceConfiguration, getOrderStatus, parseCommerceCheckoutConfiguration, readCommerceConfig };
package/dist/index.js CHANGED
@@ -79,7 +79,14 @@ function commerceConfigurationForResponse(res) {
79
79
  return createRuntimeCommerceConfiguration();
80
80
  }
81
81
  function readCommerceConfigForResponse(res) {
82
- return commerceConfigurationForResponse(res).read();
82
+ const configuration = commerceConfigurationForResponse(res);
83
+ assertCommerceConnectionReady(configuration);
84
+ return configuration.read();
85
+ }
86
+ /** Nonready and invalid connection states must never use leftover credentials. */
87
+ function assertCommerceConnectionReady(configuration) {
88
+ const state = configuration.readConnectionState?.();
89
+ if (state !== void 0 && state !== "ready") throw new Error("Commerce store connection is not ready. Complete the store connection before continuing.");
83
90
  }
84
91
 
85
92
  //#endregion
@@ -330,6 +337,7 @@ async function createCheckoutSession(params, configuration = createRuntimeCommer
330
337
  skuId,
331
338
  lineItemData
332
339
  ].filter(Boolean).length !== 1) throw new Error("createCheckoutSession: exactly one of draftOrderId, skuId, or lineItemData is required");
340
+ assertCommerceConnectionReady(configuration);
333
341
  const { storeId, channelId, clientId, clientSecret, apiBaseUrl, sourceApp, owner, currencyCode: configCurrencyCode } = configuration.read();
334
342
  const checkoutConfiguration = configuration.readCheckout();
335
343
  const enablePromotionCodes = promotionCodesEnabled(checkoutConfiguration);
@@ -420,6 +428,7 @@ async function createCheckoutSession(params, configuration = createRuntimeCommer
420
428
  //#region src/lib/commerce/get-order-status.ts
421
429
  async function getOrderStatus(orderId, configuration = createRuntimeCommerceConfiguration()) {
422
430
  if (typeof orderId !== "string" || !orderId.trim() || orderId === "." || orderId === "..") throw new Error("getOrderStatus: a valid orderId is required");
431
+ assertCommerceConnectionReady(configuration);
423
432
  const { storeId, channelId, clientId, clientSecret, apiBaseUrl, currencyCode } = configuration.read();
424
433
  const token = await getOAuthAccessToken({
425
434
  clientId,
@@ -1065,6 +1074,7 @@ async function handler$6(req, res) {
1065
1074
  return;
1066
1075
  }
1067
1076
  if (req.headers?.["x-commerce-scope"] !== void 0) {
1077
+ assertCommerceConnectionReady(configuration);
1068
1078
  if (!validateCommerceCartScope(req, res, configuration.read())) return;
1069
1079
  }
1070
1080
  const validateReturnUrls = res.locals.commerceCheckoutReturnUrlValidator;
@@ -1097,8 +1107,16 @@ async function handler$6(req, res) {
1097
1107
  async function handler$7(_req, res) {
1098
1108
  res.setHeader("Cache-Control", "no-store");
1099
1109
  try {
1100
- const config = commerceConfigurationForResponse(res).read();
1110
+ const configuration = commerceConfigurationForResponse(res);
1111
+ const state = configuration.readConnectionState?.();
1112
+ if (state === "unbound" || state === "connecting") {
1113
+ res.json({ state });
1114
+ return;
1115
+ }
1116
+ if (state !== void 0 && state !== "ready") throw new Error("Invalid Commerce connection state.");
1117
+ const config = configuration.read();
1101
1118
  res.json({
1119
+ ...state === "ready" ? { state } : {},
1102
1120
  cartScope: getCommerceCartScope(config),
1103
1121
  currencyCode: config.currencyCode
1104
1122
  });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@godaddy/gd-commerce-server",
3
- "version": "0.1.1",
3
+ "version": "0.2.0",
4
4
  "description": "Opinionated Express server integration for GoDaddy Commerce",
5
5
  "type": "module",
6
6
  "license": "MIT",