japanpost-api
Version:
Japan Post Servive API client
241 lines • 12.4 kB
JavaScript
;
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