@stackframe/stack-shared 2.8.58 → 2.8.59

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 (47) hide show
  1. package/dist/config/migrate-catalogs-to-product-lines.d.mts +12 -0
  2. package/dist/config/migrate-catalogs-to-product-lines.d.ts +12 -0
  3. package/dist/config/migrate-catalogs-to-product-lines.js +211 -0
  4. package/dist/config/migrate-catalogs-to-product-lines.js.map +1 -0
  5. package/dist/config/schema-fuzzer.test.js +17 -6
  6. package/dist/config/schema-fuzzer.test.js.map +1 -1
  7. package/dist/config/schema.d.mts +181 -157
  8. package/dist/config/schema.d.ts +181 -157
  9. package/dist/config/schema.js +39 -8
  10. package/dist/config/schema.js.map +1 -1
  11. package/dist/esm/config/migrate-catalogs-to-product-lines.js +186 -0
  12. package/dist/esm/config/migrate-catalogs-to-product-lines.js.map +1 -0
  13. package/dist/esm/config/schema-fuzzer.test.js +17 -6
  14. package/dist/esm/config/schema-fuzzer.test.js.map +1 -1
  15. package/dist/esm/config/schema.js +40 -9
  16. package/dist/esm/config/schema.js.map +1 -1
  17. package/dist/esm/interface/client-interface.js +111 -21
  18. package/dist/esm/interface/client-interface.js.map +1 -1
  19. package/dist/esm/interface/crud/products.js +12 -1
  20. package/dist/esm/interface/crud/products.js.map +1 -1
  21. package/dist/esm/interface/server-interface.js +38 -0
  22. package/dist/esm/interface/server-interface.js.map +1 -1
  23. package/dist/esm/known-errors.js +24 -0
  24. package/dist/esm/known-errors.js.map +1 -1
  25. package/dist/esm/schema-fields.js +1 -1
  26. package/dist/esm/schema-fields.js.map +1 -1
  27. package/dist/interface/client-interface.d.mts +31 -0
  28. package/dist/interface/client-interface.d.ts +31 -0
  29. package/dist/interface/client-interface.js +111 -21
  30. package/dist/interface/client-interface.js.map +1 -1
  31. package/dist/interface/crud/products.d.mts +77 -0
  32. package/dist/interface/crud/products.d.ts +77 -0
  33. package/dist/interface/crud/products.js +12 -1
  34. package/dist/interface/crud/products.js.map +1 -1
  35. package/dist/interface/server-interface.d.mts +23 -0
  36. package/dist/interface/server-interface.d.ts +23 -0
  37. package/dist/interface/server-interface.js +38 -0
  38. package/dist/interface/server-interface.js.map +1 -1
  39. package/dist/known-errors.d.mts +6 -0
  40. package/dist/known-errors.d.ts +6 -0
  41. package/dist/known-errors.js +24 -0
  42. package/dist/known-errors.js.map +1 -1
  43. package/dist/schema-fields.d.mts +4 -4
  44. package/dist/schema-fields.d.ts +4 -4
  45. package/dist/schema-fields.js +1 -1
  46. package/dist/schema-fields.js.map +1 -1
  47. package/package.json +4 -4
@@ -139,21 +139,25 @@ var StackClientInterface = class {
139
139
  if (!("publishableClientKey" in this.options)) {
140
140
  throw new Error("Admin session token is currently not supported for fetching new access token. Did you try to log in on a StackApp initiated with the admin session?");
141
141
  }
142
+ const tokenEndpoint = this.getApiUrl() + "/auth/oauth/token";
142
143
  const as = {
143
144
  issuer: this.options.getBaseUrl(),
144
145
  algorithm: "oauth2",
145
- token_endpoint: this.getApiUrl() + "/auth/oauth/token"
146
+ token_endpoint: tokenEndpoint
146
147
  };
147
148
  const client = {
148
149
  client_id: this.projectId,
149
- client_secret: this.options.publishableClientKey,
150
- token_endpoint_auth_method: "client_secret_post"
150
+ client_secret: this.options.publishableClientKey
151
151
  };
152
+ const clientAuthentication = oauth.ClientSecretPost(this.options.publishableClientKey);
153
+ const allowInsecure = (process.env.NODE_ENV?.includes("dev") || process.env.NODE_ENV === "test") && tokenEndpoint.startsWith("http://");
152
154
  const response = await this._networkRetryException(async () => {
153
155
  const rawResponse = await oauth.refreshTokenGrantRequest(
154
156
  as,
155
157
  client,
156
- refreshToken.token
158
+ clientAuthentication,
159
+ refreshToken.token,
160
+ allowInsecure ? { [oauth.allowInsecureRequests]: true } : void 0
157
161
  );
158
162
  const response2 = await this._processResponse(rawResponse);
159
163
  if (response2.status === "error") {
@@ -170,9 +174,18 @@ var StackClientInterface = class {
170
174
  return response2.data;
171
175
  });
172
176
  if (!response) return null;
173
- const result = await oauth.processRefreshTokenResponse(as, client, response);
174
- if (oauth.isOAuth2Error(result)) {
175
- throw new import_errors.StackAssertionError("OAuth error", { result });
177
+ let result;
178
+ try {
179
+ result = await oauth.processRefreshTokenResponse(as, client, response);
180
+ } catch (e) {
181
+ if (e instanceof oauth.ResponseBodyError) {
182
+ throw new import_errors.StackAssertionError("ResponseBodyError when processing refresh token response", {
183
+ cause: e.cause,
184
+ code: e.code,
185
+ error: e.error
186
+ });
187
+ }
188
+ throw new import_errors.StackAssertionError("Unexpected error when processing refresh token response", { cause: e });
176
189
  }
177
190
  if (!result.access_token) {
178
191
  throw new import_errors.StackAssertionError("Access token not found in token endpoint response, this is weird!");
@@ -800,35 +813,56 @@ var StackClientInterface = class {
800
813
  if (!("publishableClientKey" in this.options)) {
801
814
  throw new Error("Admin session token is currently not supported for OAuth");
802
815
  }
816
+ const tokenEndpoint = this.getApiUrl() + "/auth/oauth/token";
803
817
  const as = {
804
818
  issuer: this.options.getBaseUrl(),
805
819
  algorithm: "oauth2",
806
- token_endpoint: this.getApiUrl() + "/auth/oauth/token"
820
+ token_endpoint: tokenEndpoint
807
821
  };
808
822
  const client = {
809
823
  client_id: this.projectId,
810
- client_secret: this.options.publishableClientKey,
811
- token_endpoint_auth_method: "client_secret_post"
824
+ client_secret: this.options.publishableClientKey
812
825
  };
813
- const params = await this._networkRetryException(
814
- async () => oauth.validateAuthResponse(as, client, options.oauthParams, options.state)
815
- );
816
- if (oauth.isOAuth2Error(params)) {
817
- throw new import_errors.StackAssertionError("Error validating outer OAuth response", { params });
826
+ const clientAuthentication = oauth.ClientSecretPost(this.options.publishableClientKey);
827
+ const allowInsecure = (process.env.NODE_ENV?.includes("dev") || process.env.NODE_ENV === "test") && tokenEndpoint.startsWith("http://");
828
+ let params;
829
+ try {
830
+ params = oauth.validateAuthResponse(as, client, options.oauthParams, options.state);
831
+ } catch (e) {
832
+ if (e instanceof oauth.AuthorizationResponseError) {
833
+ throw new import_errors.StackAssertionError("Authorization response error when validating outer OAuth response", {
834
+ //cause is a URLSearchParams object for this error, so we need to serialize it better
835
+ cause: Object.fromEntries(e.cause),
836
+ code: e.code,
837
+ error: e.error
838
+ });
839
+ }
840
+ throw new import_errors.StackAssertionError("Unexpected error when validating outer OAuth response", { cause: e });
818
841
  }
819
842
  const response = await oauth.authorizationCodeGrantRequest(
820
843
  as,
821
844
  client,
845
+ clientAuthentication,
822
846
  params,
823
847
  options.redirectUri,
824
- options.codeVerifier
848
+ options.codeVerifier,
849
+ allowInsecure ? { [oauth.allowInsecureRequests]: true } : void 0
825
850
  );
826
- const result = await oauth.processAuthorizationCodeOAuth2Response(as, client, response);
827
- if (oauth.isOAuth2Error(result)) {
828
- if ("code" in result && result.code === "MULTI_FACTOR_AUTHENTICATION_REQUIRED") {
829
- throw new import_known_errors.KnownErrors.MultiFactorAuthenticationRequired(result.details.attempt_code);
851
+ let result;
852
+ try {
853
+ result = await oauth.processAuthorizationCodeResponse(as, client, response);
854
+ } catch (e) {
855
+ if (e instanceof oauth.ResponseBodyError) {
856
+ if (e.cause.code === "MULTI_FACTOR_AUTHENTICATION_REQUIRED") {
857
+ throw new import_known_errors.KnownErrors.MultiFactorAuthenticationRequired(e.cause.details.attempt_code);
858
+ }
859
+ throw new import_errors.StackAssertionError("Outer OAuth error during authorization code response", {
860
+ cause: e.cause,
861
+ code: e.code,
862
+ error: e.error
863
+ });
830
864
  }
831
- throw new import_errors.StackAssertionError("Outer OAuth error during authorization code response", { result });
865
+ throw new import_errors.StackAssertionError("Unexpected error when processing authorization code response", { cause: e });
832
866
  }
833
867
  return {
834
868
  newUser: result.is_new_user,
@@ -1386,6 +1420,24 @@ var StackClientInterface = class {
1386
1420
  session
1387
1421
  );
1388
1422
  }
1423
+ async switchSubscription(options, session) {
1424
+ await this.sendClientRequest(
1425
+ import_urls.urlString`/payments/products/${options.customer_type}/${options.customer_id}/switch`,
1426
+ {
1427
+ method: "POST",
1428
+ headers: {
1429
+ "content-type": "application/json"
1430
+ },
1431
+ body: JSON.stringify({
1432
+ from_product_id: options.from_product_id,
1433
+ to_product_id: options.to_product_id,
1434
+ price_id: options.price_id,
1435
+ quantity: options.quantity
1436
+ })
1437
+ },
1438
+ session
1439
+ );
1440
+ }
1389
1441
  async createCheckoutUrl(customer_type, customer_id, productIdOrInline, session, returnUrl) {
1390
1442
  const productBody = typeof productIdOrInline === "string" ? { product_id: productIdOrInline } : { inline_product: productIdOrInline };
1391
1443
  const response = await this.sendClientRequest(
@@ -1402,6 +1454,44 @@ var StackClientInterface = class {
1402
1454
  const { url } = await response.json();
1403
1455
  return url;
1404
1456
  }
1457
+ async getCustomerBilling(customerType, customerId, session) {
1458
+ const response = await this.sendClientRequest(
1459
+ import_urls.urlString`/payments/billing/${customerType}/${customerId}`,
1460
+ {},
1461
+ session
1462
+ );
1463
+ return await response.json();
1464
+ }
1465
+ async createCustomerPaymentMethodSetupIntent(customerType, customerId, session) {
1466
+ const response = await this.sendClientRequest(
1467
+ import_urls.urlString`/payments/payment-method/${customerType}/${customerId}/setup-intent`,
1468
+ {
1469
+ method: "POST",
1470
+ headers: {
1471
+ "content-type": "application/json"
1472
+ },
1473
+ body: JSON.stringify({})
1474
+ },
1475
+ session
1476
+ );
1477
+ return await response.json();
1478
+ }
1479
+ async setDefaultCustomerPaymentMethodFromSetupIntent(customerType, customerId, setupIntentId, session) {
1480
+ const response = await this.sendClientRequest(
1481
+ import_urls.urlString`/payments/payment-method/${customerType}/${customerId}/set-default`,
1482
+ {
1483
+ method: "POST",
1484
+ headers: {
1485
+ "content-type": "application/json"
1486
+ },
1487
+ body: JSON.stringify({
1488
+ setup_intent_id: setupIntentId
1489
+ })
1490
+ },
1491
+ session
1492
+ );
1493
+ return await response.json();
1494
+ }
1405
1495
  async transferProject(internalProjectSession, projectIdToTransfer, newTeamId) {
1406
1496
  if (this.options.projectId !== "internal") {
1407
1497
  throw new import_errors.StackAssertionError("StackClientInterface.transferProject() is only available for internal projects (please specify the project ID in the constructor)");