UNPKG

japanpost-api

Version:
241 lines 12.4 kB
"use strict"; var __classPrivateFieldSet = (this && this.__classPrivateFieldSet) || function (receiver, state, value, kind, f) { if (kind === "m") throw new TypeError("Private method is not writable"); if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a setter"); if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot write private member to an object whose class did not declare it"); return (kind === "a" ? f.call(receiver, value) : f ? f.value = value : state.set(receiver, value)), value; }; var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (receiver, state, kind, f) { if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a getter"); if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot read private member from an object whose class did not declare it"); return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver); }; var _JapanPostAPI_instances, _JapanPostAPI_baseUrl, _JapanPostAPI_tokenInit, _JapanPostAPI_token, _JapanPostAPI_tokenExpiresAt, _JapanPostAPI_autoTokenRefresh, _JapanPostAPI_retryOptions, _JapanPostAPI_circuitBreaker, _JapanPostAPI_enableValidation, _JapanPostAPI_call; Object.defineProperty(exports, "__esModule", { value: true }); exports.JapanPostAPI = void 0; const JapanPostAPIError_1 = require("./JapanPostAPIError"); const Logger_1 = require("./Logger"); const validation_1 = require("./validation"); const retry_1 = require("./retry"); const defaultBaseUrl = "https://api.da.pf.japanpost.jp"; class JapanPostAPI { constructor(tokenInit, options = { baseUrl: defaultBaseUrl }) { _JapanPostAPI_instances.add(this); _JapanPostAPI_baseUrl.set(this, void 0); _JapanPostAPI_tokenInit.set(this, void 0); _JapanPostAPI_token.set(this, void 0); _JapanPostAPI_tokenExpiresAt.set(this, void 0); // millis _JapanPostAPI_autoTokenRefresh.set(this, void 0); _JapanPostAPI_retryOptions.set(this, void 0); _JapanPostAPI_circuitBreaker.set(this, void 0); _JapanPostAPI_enableValidation.set(this, void 0); __classPrivateFieldSet(this, _JapanPostAPI_baseUrl, options.baseUrl ?? defaultBaseUrl, "f"); __classPrivateFieldSet(this, _JapanPostAPI_tokenInit, tokenInit, "f"); const tokenPassed = typeof tokenInit === "string"; if (tokenPassed) { __classPrivateFieldSet(this, _JapanPostAPI_token, tokenInit, "f"); } __classPrivateFieldSet(this, _JapanPostAPI_tokenExpiresAt, 0, "f"); __classPrivateFieldSet(this, _JapanPostAPI_autoTokenRefresh, options.autoTokenRefresh ?? !tokenPassed, "f"); __classPrivateFieldSet(this, _JapanPostAPI_retryOptions, options.retryOptions ?? {}, "f"); __classPrivateFieldSet(this, _JapanPostAPI_circuitBreaker, new retry_1.CircuitBreaker(options.circuitBreakerOptions), "f"); __classPrivateFieldSet(this, _JapanPostAPI_enableValidation, options.enableValidation ?? true, "f"); } async initToken(options) { if (typeof __classPrivateFieldGet(this, _JapanPostAPI_tokenInit, "f") === "string" && !options) { throw new Error("Pass client_id + secret_key to either the constructor or this method"); } const tokenInit = __classPrivateFieldGet(this, _JapanPostAPI_tokenInit, "f"); const response = await this.token({ grant_type: "client_credentials", client_id: options?.client_id ?? tokenInit.client_id, secret_key: options?.secret_key ?? tokenInit.secret_key, }); this.setToken(response.token); __classPrivateFieldSet(this, _JapanPostAPI_tokenExpiresAt, Date.now() + response.expires_in * 1000, "f"); } setToken(token) { __classPrivateFieldSet(this, _JapanPostAPI_token, token, "f"); } tokenExpired() { return Date.now() > __classPrivateFieldGet(this, _JapanPostAPI_tokenExpiresAt, "f"); } async token(request) { if (typeof __classPrivateFieldGet(this, _JapanPostAPI_tokenInit, "f") === "string" && !request) { throw new Error("Pass client_id + secret_key to the constructor"); } const tokenInit = __classPrivateFieldGet(this, _JapanPostAPI_tokenInit, "f"); const formParams = request ?? { grant_type: "client_credentials", client_id: tokenInit.client_id, secret_key: tokenInit.secret_key, }; return __classPrivateFieldGet(this, _JapanPostAPI_instances, "m", _JapanPostAPI_call).call(this, { method: "POST", path: "/api/v1/j/token", formParams, callTokenRefresh: false, }); } async searchcode(request) { // Execute validation if (__classPrivateFieldGet(this, _JapanPostAPI_enableValidation, "f")) { (0, validation_1.validateSearchcodeRequest)(request); } const searchCode = request.search_code.replace("-", ""); const queryParams = { ...request }; delete queryParams["search_code"]; return __classPrivateFieldGet(this, _JapanPostAPI_instances, "m", _JapanPostAPI_call).call(this, { method: "GET", path: "/api/v1/searchcode/{search_code}", pathParams: { search_code: searchCode }, queryParams, callTokenRefresh: __classPrivateFieldGet(this, _JapanPostAPI_autoTokenRefresh, "f"), }); } async *searchcodeAll(request) { // Execute validation if (__classPrivateFieldGet(this, _JapanPostAPI_enableValidation, "f")) { (0, validation_1.validateSearchcodeRequest)(request); } let page = request.page ?? 1; const limit = request.limit ?? 1000; while (true) { const response = await this.searchcode({ ...request, page, limit }); if (!response.addresses || response.addresses.length === 0) { break; } yield response; if (response.addresses.length < limit) { break; } page++; } } async addresszip(request) { // Execute validation if (__classPrivateFieldGet(this, _JapanPostAPI_enableValidation, "f")) { (0, validation_1.validateAddresszipRequest)(request); } return __classPrivateFieldGet(this, _JapanPostAPI_instances, "m", _JapanPostAPI_call).call(this, { method: "POST", path: "/api/v1/addresszip", formParams: request, callTokenRefresh: __classPrivateFieldGet(this, _JapanPostAPI_autoTokenRefresh, "f"), }); } async *addresszipAll(request) { // Execute validation if (__classPrivateFieldGet(this, _JapanPostAPI_enableValidation, "f")) { (0, validation_1.validateAddresszipRequest)(request); } let page = request.page ?? 1; const limit = request.limit ?? 1000; while (true) { const response = await this.addresszip({ ...request, page, limit }); if (!response.addresses || response.addresses.length === 0) { break; } yield response; if (response.addresses.length < limit) { break; } page++; } } /** * Update retry configuration */ updateRetryOptions(options) { __classPrivateFieldSet(this, _JapanPostAPI_retryOptions, { ...__classPrivateFieldGet(this, _JapanPostAPI_retryOptions, "f"), ...options }, "f"); } /** * Get circuit breaker state */ getCircuitBreakerState() { return { state: __classPrivateFieldGet(this, _JapanPostAPI_circuitBreaker, "f").getState(), failureCount: __classPrivateFieldGet(this, _JapanPostAPI_circuitBreaker, "f").getFailureCount(), }; } /** * Reset circuit breaker */ resetCircuitBreaker() { __classPrivateFieldGet(this, _JapanPostAPI_circuitBreaker, "f").reset(); } } exports.JapanPostAPI = JapanPostAPI; _JapanPostAPI_baseUrl = new WeakMap(), _JapanPostAPI_tokenInit = new WeakMap(), _JapanPostAPI_token = new WeakMap(), _JapanPostAPI_tokenExpiresAt = new WeakMap(), _JapanPostAPI_autoTokenRefresh = new WeakMap(), _JapanPostAPI_retryOptions = new WeakMap(), _JapanPostAPI_circuitBreaker = new WeakMap(), _JapanPostAPI_enableValidation = new WeakMap(), _JapanPostAPI_instances = new WeakSet(), _JapanPostAPI_call = async function _JapanPostAPI_call({ method, path, pathParams, queryParams, formParams, callTokenRefresh, }) { // Execute API call with circuit breaker and retry functionality return await __classPrivateFieldGet(this, _JapanPostAPI_circuitBreaker, "f").execute(async () => { return await (0, retry_1.withRetry)(async () => { if (callTokenRefresh && this.tokenExpired()) { (0, Logger_1.debugLog)(() => { if (__classPrivateFieldGet(this, _JapanPostAPI_token, "f")) { return "Token expired, refreshing..."; } else { return "No token, initializing..."; } }); await this.initToken(); } const finalPath = path.replace(/{([^}]+)}/g, (match, key) => pathParams?.[key] ?? match); const query = Object.keys(queryParams || {}).length > 0 ? `?${new URLSearchParams(queryParams).toString()}` : ""; const url = `${__classPrivateFieldGet(this, _JapanPostAPI_baseUrl, "f")}${finalPath}`.replace("//api", "/api") + query; const token = formParams ? (formParams.token ?? __classPrivateFieldGet(this, _JapanPostAPI_token, "f")) : __classPrivateFieldGet(this, _JapanPostAPI_token, "f"); const _params = {}; Object.assign(_params, formParams); if (_params && _params.token) { delete _params.token; } const headers = { "Content-Type": "application/json" }; if (token) { headers["Authorization"] = `Bearer ${token}`; } const body = method === "POST" ? JSON.stringify(_params) : undefined; (0, Logger_1.debugLog)(() => `JapanPost API request (${method} ${url}): ${body}`); const request = new Request(url, { method, headers, body }); let response = null; let responseBody = null; try { response = await fetch(request); responseBody = await response.text(); (0, Logger_1.debugLog)(() => { if (response !== null) { return `JapanPost API response - url: ${response.url}, status: ${response.status}, body: ${responseBody}`; } else { return `JapanPost API response - body: ${responseBody}`; } }); const body = JSON.parse(responseBody); if (body.error_code) { throw JapanPostAPIError_1.JapanPostAPIError.createFromResponse({ status: response.status, body: responseBody, headers: Object.fromEntries(response.headers), }); } return body; } catch (e) { (0, Logger_1.debugLog)(() => `JapanPost API error: ${e}`); if (response) { throw JapanPostAPIError_1.JapanPostAPIError.createFromResponse({ status: response.status, body: responseBody || "", headers: Object.fromEntries(response.headers), }); } else { // Treat as network error const error = e instanceof Error ? e : new Error(String(e)); throw new JapanPostAPIError_1.NetworkError(error); } } }, __classPrivateFieldGet(this, _JapanPostAPI_retryOptions, "f")); }); }; //# sourceMappingURL=JapanPostAPI.js.map