UNPKG

@sp-api-sdk/auth

Version:

Login with Amazon (LWA) authentication for the Amazon Selling Partner API (SP-API)

151 lines (146 loc) 5.71 kB
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" }); //#region \0rolldown/runtime.js var __create = Object.create; var __defProp = Object.defineProperty; var __getOwnPropDesc = Object.getOwnPropertyDescriptor; var __getOwnPropNames = Object.getOwnPropertyNames; var __getProtoOf = Object.getPrototypeOf; var __hasOwnProp = Object.prototype.hasOwnProperty; var __copyProps = (to, from, except, desc) => { if (from && typeof from === "object" || typeof from === "function") for (var keys = __getOwnPropNames(from), i = 0, n = keys.length, key; i < n; i++) { key = keys[i]; if (!__hasOwnProp.call(to, key) && key !== except) __defProp(to, key, { get: ((k) => from[k]).bind(null, key), enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable }); } return to; }; var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target, mod)); //#endregion let node_process = require("node:process"); node_process = __toESM(node_process, 1); let axios = require("axios"); axios = __toESM(axios, 1); let read_pkg_up = require("read-pkg-up"); //#region src/error.ts /** Error thrown when an LWA token request fails. Wraps the underlying Axios error with a human-readable message that includes the HTTP status code (or "No response" for network errors). */ var SellingPartnerApiAuthError = class extends axios.AxiosError { /** The original error message from the failed HTTP request. */ innerMessage; constructor(error) { const message = error.response ? `access-token error: Response code ${error.response.status}` : "access-token error: No response"; super(message, error.code, error.config, error.request, error.response); this.innerMessage = error.message; this.name = this.constructor.name; } }; const packageJson = (0, read_pkg_up.sync)()?.packageJson ?? { _id: "", readme: "", name: "@sp-api-sdk/auth", version: "unknown" }; //#endregion //#region src/utils/axios.ts const axios$1 = axios.default.create({ baseURL: "https://api.amazon.com/auth/", timeout: 3e4, headers: { "user-agent": `${packageJson.name}/${packageJson.version}` } }); //#endregion //#region src/types/scope.ts /** Authorization scopes for grantless Selling Partner API operations. */ let AuthorizationScope = /* @__PURE__ */ function(AuthorizationScope) { /** Scope for the Notifications API. */ AuthorizationScope["NOTIFICATIONS"] = "sellingpartnerapi::notifications"; /** Scope for rotating application client credentials. */ AuthorizationScope["CLIENT_CREDENTIAL_ROTATION"] = "sellingpartnerapi::client_credential:rotation"; return AuthorizationScope; }({}); //#endregion //#region src/index.ts /** Handles Login with Amazon (LWA) OAuth token management for the Selling Partner API. Supports both refresh-token and grantless (scope-based) authentication flows. Tokens are cached and automatically refreshed when expired. Concurrent calls to {@link getAccessToken} are deduplicated into a single request. */ var SellingPartnerApiAuth = class { clientId; clientSecret; refreshToken; scopes; #accessToken; #accessTokenExpiration; #pendingTokenRequest; constructor(parameters) { const clientId = parameters.clientId ?? node_process.default.env.LWA_CLIENT_ID; if (!clientId) throw new Error("Missing required `clientId` configuration value"); const clientSecret = parameters.clientSecret ?? node_process.default.env.LWA_CLIENT_SECRET; if (!clientSecret) throw new Error("Missing required `clientSecret` configuration value"); const refreshToken = parameters.refreshToken ?? node_process.default.env.LWA_REFRESH_TOKEN; if (!refreshToken && !parameters.scopes) throw new TypeError("Either `refreshToken` or `scopes` must be specified"); this.clientId = clientId; this.clientSecret = clientSecret; this.refreshToken = refreshToken; this.scopes = parameters.scopes; } async #refreshAccessToken() { const body = { client_id: this.clientId, client_secret: this.clientSecret, ...this.refreshToken ? { grant_type: "refresh_token", refresh_token: this.refreshToken } : { grant_type: "client_credentials", scope: this.scopes.join(" ") } }; try { const expiration = /* @__PURE__ */ new Date(); const { data } = await axios$1.post("/o2/token", body); expiration.setSeconds(expiration.getSeconds() + data.expires_in); this.#accessToken = data.access_token; this.#accessTokenExpiration = expiration; return data.access_token; } catch (error) { if (error instanceof axios.AxiosError) throw new SellingPartnerApiAuthError(error); throw error; } } /** Returns a valid LWA access token, refreshing it if expired. Concurrent calls while a refresh is in progress share the same request. @returns The access token string. */ async getAccessToken() { if (this.#accessToken && (!this.#accessTokenExpiration || Date.now() < this.#accessTokenExpiration.getTime())) return this.#accessToken; if (this.#pendingTokenRequest) return this.#pendingTokenRequest; this.#pendingTokenRequest = this.#refreshAccessToken(); try { return await this.#pendingTokenRequest; } finally { this.#pendingTokenRequest = void 0; } } /** Expiration date of the currently cached access token, or `undefined` if no token has been fetched yet. */ get accessTokenExpiration() { return this.#accessTokenExpiration; } }; //#endregion exports.AuthorizationScope = AuthorizationScope; exports.SellingPartnerApiAuth = SellingPartnerApiAuth; exports.SellingPartnerApiAuthError = SellingPartnerApiAuthError; //# sourceMappingURL=index.cjs.map