From 4b5a4e608d63bb594d59f167d507c42f32bfbfd1 Mon Sep 17 00:00:00 2001 From: Dinwy Date: Wed, 26 Jun 2024 10:02:53 +0900 Subject: [PATCH 01/15] WIP: Making Hosted Field work --- .gitignore | 13 +- deploy | 5 + .../KomojuField/KomojuSessionData.php | 121 + .../Komoju/Payments/etc/csp_whitelist.xml | 27 + .../frontend/layout/checkout_index_index.xml | 7 +- .../view/frontend/requirejs-config.js | 7 + .../web/js/extras/error-reporting/module.js | 1948 +++++++++++++++++ .../js/extras/error-reporting/module.js.map | 7 + .../view/frontend/web/js/fields-iframe.html | 14 + .../view/frontend/web/js/fields-iframe.js | 879 ++++++++ .../view/frontend/web/js/fields-iframe.js.map | 7 + .../Payments/view/frontend/web/js/fields.js | 733 +++++++ .../view/frontend/web/js/fields.js.map | 7 + .../web/js/fields/bank_transfer/module.js | 303 +++ .../web/js/fields/bank_transfer/module.js.map | 7 + .../web/js/fields/credit_card/module.js | 500 +++++ .../web/js/fields/credit_card/module.js.map | 7 + .../frontend/web/js/fields/konbini/module.js | 164 ++ .../web/js/fields/konbini/module.js.map | 7 + .../frontend/web/js/fields/offsite/module.js | 131 ++ .../web/js/fields/offsite/module.js.map | 7 + .../frontend/web/js/secure-token-return.html | 17 + .../web/js/static/credit_card_cvc.svg | 67 + .../web/js/static/credit_card_number.svg | 72 + .../view/frontend/web/js/static/shared.css | 139 ++ .../frontend/web/js/static/themes/dark.css | 9 + .../js/view/payment/method-renderer/form.js | 51 +- .../frontend/web/template/payment/form.html | 63 +- 28 files changed, 5289 insertions(+), 30 deletions(-) create mode 100755 deploy create mode 100644 src/app/code/Komoju/Payments/Controller/KomojuField/KomojuSessionData.php create mode 100644 src/app/code/Komoju/Payments/etc/csp_whitelist.xml create mode 100644 src/app/code/Komoju/Payments/view/frontend/requirejs-config.js create mode 100644 src/app/code/Komoju/Payments/view/frontend/web/js/extras/error-reporting/module.js create mode 100644 src/app/code/Komoju/Payments/view/frontend/web/js/extras/error-reporting/module.js.map create mode 100644 src/app/code/Komoju/Payments/view/frontend/web/js/fields-iframe.html create mode 100644 src/app/code/Komoju/Payments/view/frontend/web/js/fields-iframe.js create mode 100644 src/app/code/Komoju/Payments/view/frontend/web/js/fields-iframe.js.map create mode 100644 src/app/code/Komoju/Payments/view/frontend/web/js/fields.js create mode 100644 src/app/code/Komoju/Payments/view/frontend/web/js/fields.js.map create mode 100644 src/app/code/Komoju/Payments/view/frontend/web/js/fields/bank_transfer/module.js create mode 100644 src/app/code/Komoju/Payments/view/frontend/web/js/fields/bank_transfer/module.js.map create mode 100644 src/app/code/Komoju/Payments/view/frontend/web/js/fields/credit_card/module.js create mode 100644 src/app/code/Komoju/Payments/view/frontend/web/js/fields/credit_card/module.js.map create mode 100644 src/app/code/Komoju/Payments/view/frontend/web/js/fields/konbini/module.js create mode 100644 src/app/code/Komoju/Payments/view/frontend/web/js/fields/konbini/module.js.map create mode 100644 src/app/code/Komoju/Payments/view/frontend/web/js/fields/offsite/module.js create mode 100644 src/app/code/Komoju/Payments/view/frontend/web/js/fields/offsite/module.js.map create mode 100644 src/app/code/Komoju/Payments/view/frontend/web/js/secure-token-return.html create mode 100644 src/app/code/Komoju/Payments/view/frontend/web/js/static/credit_card_cvc.svg create mode 100644 src/app/code/Komoju/Payments/view/frontend/web/js/static/credit_card_number.svg create mode 100644 src/app/code/Komoju/Payments/view/frontend/web/js/static/shared.css create mode 100644 src/app/code/Komoju/Payments/view/frontend/web/js/static/themes/dark.css diff --git a/.gitignore b/.gitignore index 8f111364f..f67bf9036 100644 --- a/.gitignore +++ b/.gitignore @@ -1,7 +1,14 @@ .DS_Store # Ignore everything in the src directory -src/* +src/** -# Except for the src/app directory -!src/app/code/Komoju/ \ No newline at end of file +# Re-include directories under src/app/code/Komoju/Payments and subdirectories +!src/ +!src/app/ +!src/app/code/ +!src/app/code/Komoju/ +!src/app/code/Komoju/** + +# Ignore everything in the src directory +src/**/.DS_Store diff --git a/deploy b/deploy new file mode 100755 index 000000000..925e30a38 --- /dev/null +++ b/deploy @@ -0,0 +1,5 @@ +#!/usr/bin/env bash +bin/magento setup:upgrade +bin/magento cache:clean +bin/magento cache:flush +bin/magento setup:static-content:deploy -f \ No newline at end of file diff --git a/src/app/code/Komoju/Payments/Controller/KomojuField/KomojuSessionData.php b/src/app/code/Komoju/Payments/Controller/KomojuField/KomojuSessionData.php new file mode 100644 index 000000000..9920d2b72 --- /dev/null +++ b/src/app/code/Komoju/Payments/Controller/KomojuField/KomojuSessionData.php @@ -0,0 +1,121 @@ +jsonResultFactory = $jsonResultFactory; + $this->quoteRepository = $quoteRepository; + $this->checkoutSession = $checkoutSession; + $this->komojuApi = $komojuApi; + $this->config = $config; + $this->cart = $cart; + parent::__construct($context); + } + + public function execute() + { + $quote = $this->checkoutSession->getQuote(); + $totalAmount = $quote->getGrandTotal(); + $currencyCode = $quote->getStoreCurrencyCode(); + $customerEmail = $quote->getCustomerEmail(); + $paymentMethod = $this->getRequest()->getParam('payment_method'); + + // 세션 데이터 생성 + $komojuSession = $this->createKomojuSession( + $paymentMethod, + $totalAmount, + $currencyCode, + $customerEmail, + $quote + ); + + $result = $this->jsonResultFactory->create(); + return $result->setData([ + 'komojuSession' => $komojuSession, + 'totalAmount' => $totalAmount, + 'currency' => $currencyCode + ]); + } + + private function createKomojuSession($paymentMethod, $totalAmount, $currencyCode, $customerEmail, $quote) + { + return $this->komojuApi->createSession([ + 'amount' => $totalAmount, + 'currency' => $currencyCode, + 'default_locale' => $this->config->getKomojuLocale(), + 'payment_types' => [$paymentMethod], + 'email' => $customerEmail, + 'metadata' => [ + 'note' => 'testing' + ] + ]); + } + + private function convertAddress($address) + { + return [ + 'name' => $address->getName(), + 'street' => $address->getStreetFull(), + 'city' => $address->getCity(), + 'region' => $address->getRegion(), + 'postcode' => $address->getPostcode(), + 'country' => $address->getCountryId() + ]; + } + + public function getKomojuSessionData() { + $paymentMethod = $this->getRequest()->getParam('payment_method'); + $order = $this->getOrder(); + $billingAddress = $order->getBillingAddress(); + $externalOrderNum = $this->createExternalPayment($order); + $currencyCode = $this->storeManager->getStore()->getBaseCurrencyCode(); + $returnUrl = $this->createReturnUrl($order->getEntityId()); + + $billing_address = $this->convertToAddressParameter($order->getBillingAddress()); + $shipping_address = $this->convertToAddressParameter($order->getShippingAddress()); + + $komojuSession = $this->komojuApi->createSession([ + 'return_url' => $returnUrl, + 'default_locale' => $this->config->getKomojuLocale(), + 'payment_types' => [$paymentMethod], + 'email' => $order->getCustomerEmail(), + 'payment_data' => [ + 'name' => $order->getCustomerName(), + 'amount' => $order->getGrandTotal(), + 'currency' => $currencyCode, + 'external_order_num' => $externalOrderNum, + 'billing_address' => $billing_address, + 'shipping_address' => $shipping_address, + ], + ]); + + return $komojuSession; + } +} diff --git a/src/app/code/Komoju/Payments/etc/csp_whitelist.xml b/src/app/code/Komoju/Payments/etc/csp_whitelist.xml new file mode 100644 index 000000000..564b9e81e --- /dev/null +++ b/src/app/code/Komoju/Payments/etc/csp_whitelist.xml @@ -0,0 +1,27 @@ + + + + + + https://multipay.komoju.com + https://multipay.komoju.com/extras/error-reporting/ + https://multipay.komoju.com/static/ + + + + + https://multipay.komoju.com/static/shared.css + + + + + https://komoju.com + + + + + https://komoju.com + + + + diff --git a/src/app/code/Komoju/Payments/view/frontend/layout/checkout_index_index.xml b/src/app/code/Komoju/Payments/view/frontend/layout/checkout_index_index.xml index f2595f658..f101940fd 100644 --- a/src/app/code/Komoju/Payments/view/frontend/layout/checkout_index_index.xml +++ b/src/app/code/Komoju/Payments/view/frontend/layout/checkout_index_index.xml @@ -1,5 +1,10 @@ + + + + + @@ -40,4 +45,4 @@ - \ No newline at end of file + diff --git a/src/app/code/Komoju/Payments/view/frontend/requirejs-config.js b/src/app/code/Komoju/Payments/view/frontend/requirejs-config.js new file mode 100644 index 000000000..1584daa8e --- /dev/null +++ b/src/app/code/Komoju/Payments/view/frontend/requirejs-config.js @@ -0,0 +1,7 @@ +var config = { + map: { + '*': { + 'komojuFields': 'Komoju_Payments/js/fields' + } + } +}; diff --git a/src/app/code/Komoju/Payments/view/frontend/web/js/extras/error-reporting/module.js b/src/app/code/Komoju/Payments/view/frontend/web/js/extras/error-reporting/module.js new file mode 100644 index 000000000..c0d7463ea --- /dev/null +++ b/src/app/code/Komoju/Payments/view/frontend/web/js/extras/error-reporting/module.js @@ -0,0 +1,1948 @@ +var __getOwnPropNames = Object.getOwnPropertyNames; +var __commonJS = (cb, mod) => function __require() { + return mod || (0, cb[__getOwnPropNames(cb)[0]])((mod = { exports: {} }).exports, mod), mod.exports; +}; + +// node_modules/@honeybadger-io/js/dist/browser/honeybadger.js +var require_honeybadger = __commonJS({ + "node_modules/@honeybadger-io/js/dist/browser/honeybadger.js"(exports, module) { + (function(global2, factory) { + typeof exports === "object" && typeof module !== "undefined" ? module.exports = factory() : typeof define === "function" && define.amd ? define(factory) : (global2 = typeof globalThis !== "undefined" ? globalThis : global2 || self, global2.Honeybadger = factory()); + })(exports, function() { + "use strict"; + var commonjsGlobal = typeof globalThis !== "undefined" ? globalThis : typeof window !== "undefined" ? window : typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : {}; + function getDefaultExportFromCjs(x) { + return x && x.__esModule && Object.prototype.hasOwnProperty.call(x, "default") ? x["default"] : x; + } + function getAugmentedNamespace(n) { + var f = n.default; + if (typeof f == "function") { + var a = function() { + return f.apply(this, arguments); + }; + a.prototype = f.prototype; + } else + a = {}; + Object.defineProperty(a, "__esModule", { value: true }); + Object.keys(n).forEach(function(k) { + var d = Object.getOwnPropertyDescriptor(n, k); + Object.defineProperty(a, k, d.get ? d : { + enumerable: true, + get: function() { + return n[k]; + } + }); + }); + return a; + } + var browser$1 = {}; + var src = {}; + var client = {}; + var util$1 = {}; + var UNKNOWN_FUNCTION = ""; + function parse(stackString) { + var lines = stackString.split("\n"); + return lines.reduce(function(stack, line) { + var parseResult = parseChrome(line) || parseWinjs(line) || parseGecko(line) || parseNode(line) || parseJSC(line); + if (parseResult) { + stack.push(parseResult); + } + return stack; + }, []); + } + var chromeRe = /^\s*at (.*?) ?\(((?:file|https?|blob|chrome-extension|native|eval|webpack||\/|[a-z]:\\|\\\\).*?)(?::(\d+))?(?::(\d+))?\)?\s*$/i; + var chromeEvalRe = /\((\S*)(?::(\d+))(?::(\d+))\)/; + function parseChrome(line) { + var parts = chromeRe.exec(line); + if (!parts) { + return null; + } + var isNative2 = parts[2] && parts[2].indexOf("native") === 0; + var isEval = parts[2] && parts[2].indexOf("eval") === 0; + var submatch = chromeEvalRe.exec(parts[2]); + if (isEval && submatch != null) { + parts[2] = submatch[1]; + parts[3] = submatch[2]; + parts[4] = submatch[3]; + } + return { + file: !isNative2 ? parts[2] : null, + methodName: parts[1] || UNKNOWN_FUNCTION, + arguments: isNative2 ? [parts[2]] : [], + lineNumber: parts[3] ? +parts[3] : null, + column: parts[4] ? +parts[4] : null + }; + } + var winjsRe = /^\s*at (?:((?:\[object object\])?.+) )?\(?((?:file|ms-appx|https?|webpack|blob):.*?):(\d+)(?::(\d+))?\)?\s*$/i; + function parseWinjs(line) { + var parts = winjsRe.exec(line); + if (!parts) { + return null; + } + return { + file: parts[2], + methodName: parts[1] || UNKNOWN_FUNCTION, + arguments: [], + lineNumber: +parts[3], + column: parts[4] ? +parts[4] : null + }; + } + var geckoRe = /^\s*(.*?)(?:\((.*?)\))?(?:^|@)((?:file|https?|blob|chrome|webpack|resource|\[native).*?|[^@]*bundle)(?::(\d+))?(?::(\d+))?\s*$/i; + var geckoEvalRe = /(\S+) line (\d+)(?: > eval line \d+)* > eval/i; + function parseGecko(line) { + var parts = geckoRe.exec(line); + if (!parts) { + return null; + } + var isEval = parts[3] && parts[3].indexOf(" > eval") > -1; + var submatch = geckoEvalRe.exec(parts[3]); + if (isEval && submatch != null) { + parts[3] = submatch[1]; + parts[4] = submatch[2]; + parts[5] = null; + } + return { + file: parts[3], + methodName: parts[1] || UNKNOWN_FUNCTION, + arguments: parts[2] ? parts[2].split(",") : [], + lineNumber: parts[4] ? +parts[4] : null, + column: parts[5] ? +parts[5] : null + }; + } + var javaScriptCoreRe = /^\s*(?:([^@]*)(?:\((.*?)\))?@)?(\S.*?):(\d+)(?::(\d+))?\s*$/i; + function parseJSC(line) { + var parts = javaScriptCoreRe.exec(line); + if (!parts) { + return null; + } + return { + file: parts[3], + methodName: parts[1] || UNKNOWN_FUNCTION, + arguments: [], + lineNumber: +parts[4], + column: parts[5] ? +parts[5] : null + }; + } + var nodeRe = /^\s*at (?:((?:\[object object\])?[^\\/]+(?: \[as \S+\])?) )?\(?(.*?):(\d+)(?::(\d+))?\)?\s*$/i; + function parseNode(line) { + var parts = nodeRe.exec(line); + if (!parts) { + return null; + } + return { + file: parts[2], + methodName: parts[1] || UNKNOWN_FUNCTION, + arguments: [], + lineNumber: +parts[3], + column: parts[4] ? +parts[4] : null + }; + } + var stackTraceParser_esm = /* @__PURE__ */ Object.freeze({ + __proto__: null, + parse + }); + var require$$0 = /* @__PURE__ */ getAugmentedNamespace(stackTraceParser_esm); + var __createBinding = commonjsGlobal && commonjsGlobal.__createBinding || (Object.create ? function(o, m, k, k2) { + if (k2 === void 0) + k2 = k; + var desc = Object.getOwnPropertyDescriptor(m, k); + if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) { + desc = { enumerable: true, get: function() { + return m[k]; + } }; + } + Object.defineProperty(o, k2, desc); + } : function(o, m, k, k2) { + if (k2 === void 0) + k2 = k; + o[k2] = m[k]; + }); + var __setModuleDefault = commonjsGlobal && commonjsGlobal.__setModuleDefault || (Object.create ? function(o, v) { + Object.defineProperty(o, "default", { enumerable: true, value: v }); + } : function(o, v) { + o["default"] = v; + }); + var __importStar = commonjsGlobal && commonjsGlobal.__importStar || function(mod) { + if (mod && mod.__esModule) + return mod; + var result = {}; + if (mod != null) { + for (var k in mod) + if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) + __createBinding(result, mod, k); + } + __setModuleDefault(result, mod); + return result; + }; + var __awaiter = commonjsGlobal && commonjsGlobal.__awaiter || function(thisArg, _arguments, P, generator) { + function adopt(value) { + return value instanceof P ? value : new P(function(resolve) { + resolve(value); + }); + } + return new (P || (P = Promise))(function(resolve, reject) { + function fulfilled(value) { + try { + step(generator.next(value)); + } catch (e) { + reject(e); + } + } + function rejected(value) { + try { + step(generator["throw"](value)); + } catch (e) { + reject(e); + } + } + function step(result) { + result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); + } + step((generator = generator.apply(thisArg, _arguments || [])).next()); + }); + }; + var __generator = commonjsGlobal && commonjsGlobal.__generator || function(thisArg, body) { + var _ = { label: 0, sent: function() { + if (t[0] & 1) + throw t[1]; + return t[1]; + }, trys: [], ops: [] }, f, y, t, g; + return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { + return this; + }), g; + function verb(n) { + return function(v) { + return step([n, v]); + }; + } + function step(op) { + if (f) + throw new TypeError("Generator is already executing."); + while (_) + try { + if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) + return t; + if (y = 0, t) + op = [op[0] & 2, t.value]; + switch (op[0]) { + case 0: + case 1: + t = op; + break; + case 4: + _.label++; + return { value: op[1], done: false }; + case 5: + _.label++; + y = op[1]; + op = [0]; + continue; + case 7: + op = _.ops.pop(); + _.trys.pop(); + continue; + default: + if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { + _ = 0; + continue; + } + if (op[0] === 3 && (!t || op[1] > t[0] && op[1] < t[3])) { + _.label = op[1]; + break; + } + if (op[0] === 6 && _.label < t[1]) { + _.label = t[1]; + t = op; + break; + } + if (t && _.label < t[2]) { + _.label = t[2]; + _.ops.push(op); + break; + } + if (t[2]) + _.ops.pop(); + _.trys.pop(); + continue; + } + op = body.call(thisArg, _); + } catch (e) { + op = [6, e]; + y = 0; + } finally { + f = t = 0; + } + if (op[0] & 5) + throw op[1]; + return { value: op[0] ? op[1] : void 0, done: true }; + } + }; + Object.defineProperty(util$1, "__esModule", { value: true }); + util$1.isBrowserConfig = util$1.clone = util$1.formatCGIData = util$1.filterUrl = util$1.filter = util$1.generateStackTrace = util$1.endpoint = util$1.instrument = util$1.isErrorObject = util$1.makeNotice = util$1.logger = util$1.sanitize = util$1.shallowClone = util$1.runAfterNotifyHandlers = util$1.runBeforeNotifyHandlers = util$1.getSourceForBacktrace = util$1.getCauses = util$1.makeBacktrace = util$1.objectIsExtensible = util$1.objectIsEmpty = util$1.mergeNotice = util$1.merge = void 0; + var stackTraceParser = __importStar(require$$0); + function merge(obj1, obj2) { + var result = {}; + for (var k in obj1) { + result[k] = obj1[k]; + } + for (var k in obj2) { + result[k] = obj2[k]; + } + return result; + } + util$1.merge = merge; + function mergeNotice(notice1, notice2) { + var result = merge(notice1, notice2); + if (notice1.context && notice2.context) { + result.context = merge(notice1.context, notice2.context); + } + return result; + } + util$1.mergeNotice = mergeNotice; + function objectIsEmpty(obj) { + for (var k in obj) { + if (Object.prototype.hasOwnProperty.call(obj, k)) { + return false; + } + } + return true; + } + util$1.objectIsEmpty = objectIsEmpty; + function objectIsExtensible(obj) { + if (typeof Object.isExtensible !== "function") { + return true; + } + return Object.isExtensible(obj); + } + util$1.objectIsExtensible = objectIsExtensible; + function makeBacktrace(stack, shift) { + if (shift === void 0) { + shift = 0; + } + try { + var backtrace = stackTraceParser.parse(stack).map(function(line) { + return { + file: line.file, + method: line.methodName, + number: line.lineNumber, + column: line.column + }; + }); + backtrace.splice(0, shift); + return backtrace; + } catch (_err) { + return []; + } + } + util$1.makeBacktrace = makeBacktrace; + function getCauses(notice) { + if (notice.cause) { + var causes = []; + var cause = notice; + while (causes.length < 3 && (cause = cause.cause)) { + causes.push({ + class: cause.name, + message: cause.message, + backtrace: typeof cause.stack == "string" ? makeBacktrace(cause.stack) : null + }); + } + return causes; + } + return []; + } + util$1.getCauses = getCauses; + function getSourceForBacktrace(backtrace, getSourceFileHandler) { + return __awaiter(this, void 0, void 0, function() { + var result, index, trace, fileContent; + return __generator(this, function(_a) { + switch (_a.label) { + case 0: + result = []; + if (!getSourceFileHandler || !backtrace || !backtrace.length) { + return [2, result]; + } + index = 0; + _a.label = 1; + case 1: + if (!backtrace.length) + return [3, 3]; + trace = backtrace.splice(0)[index]; + return [4, getSourceFileHandler(trace.file)]; + case 2: + fileContent = _a.sent(); + result[index] = getSourceCodeSnippet(fileContent, trace.number); + index++; + return [3, 1]; + case 3: + return [2, result]; + } + }); + }); + } + util$1.getSourceForBacktrace = getSourceForBacktrace; + function runBeforeNotifyHandlers(notice, handlers) { + var result = true; + for (var i = 0, len = handlers.length; i < len; i++) { + var handler = handlers[i]; + if (handler(notice) === false) { + result = false; + } + } + return result; + } + util$1.runBeforeNotifyHandlers = runBeforeNotifyHandlers; + function runAfterNotifyHandlers(notice, handlers, error) { + if (notice && notice.afterNotify) { + notice.afterNotify(error, notice); + } + for (var i = 0, len = handlers.length; i < len; i++) { + handlers[i](error, notice); + } + return true; + } + util$1.runAfterNotifyHandlers = runAfterNotifyHandlers; + function shallowClone(obj) { + if (typeof obj !== "object" || obj === null) { + return {}; + } + var result = {}; + for (var k in obj) { + result[k] = obj[k]; + } + return result; + } + util$1.shallowClone = shallowClone; + function sanitize$2(obj, maxDepth) { + if (maxDepth === void 0) { + maxDepth = 8; + } + var seenObjects = []; + function seen(obj2) { + if (!obj2 || typeof obj2 !== "object") { + return false; + } + for (var i = 0; i < seenObjects.length; i++) { + var value = seenObjects[i]; + if (value === obj2) { + return true; + } + } + seenObjects.push(obj2); + return false; + } + function canSerialize(obj2) { + var typeOfObj = typeof obj2; + if (/function/.test(typeOfObj)) { + return obj2.name === "toJSON"; + } + if (/symbol/.test(typeOfObj)) { + return false; + } + if (obj2 === null) { + return false; + } + if (typeof obj2 === "object" && typeof obj2.hasOwnProperty === "undefined") { + return false; + } + return true; + } + function serialize(obj2, depth) { + if (depth === void 0) { + depth = 0; + } + if (depth >= maxDepth) { + return "[DEPTH]"; + } + if (!canSerialize(obj2)) { + return Object.prototype.toString.call(obj2); + } + if (seen(obj2)) { + return "[RECURSION]"; + } + if (Array.isArray(obj2)) { + return obj2.map(function(o) { + return safeSerialize(o, depth + 1); + }); + } + if (typeof obj2 === "object") { + var ret = {}; + for (var k in obj2) { + var v = obj2[k]; + if (Object.prototype.hasOwnProperty.call(obj2, k) && k != null && v != null) { + ret[k] = safeSerialize(v, depth + 1); + } + } + return ret; + } + return obj2; + } + function safeSerialize(obj2, depth) { + if (depth === void 0) { + depth = 0; + } + try { + return serialize(obj2, depth); + } catch (e) { + return "[ERROR] ".concat(e); + } + } + return safeSerialize(obj); + } + util$1.sanitize = sanitize$2; + function logger(client2) { + var log = function(method) { + return function() { + var _a; + var args = []; + for (var _i = 0; _i < arguments.length; _i++) { + args[_i] = arguments[_i]; + } + if (method === "debug") { + if (!client2.config.debug) { + return; + } + method = "log"; + } + args.unshift("[Honeybadger]"); + (_a = client2.config.logger)[method].apply(_a, args); + }; + }; + return { + log: log("log"), + info: log("info"), + debug: log("debug"), + warn: log("warn"), + error: log("error") + }; + } + util$1.logger = logger; + function makeNotice$1(thing) { + var notice; + if (!thing) { + notice = {}; + } else if (isErrorObject(thing)) { + var e = thing; + notice = merge(thing, { name: e.name, message: e.message, stack: e.stack, cause: e.cause }); + } else if (typeof thing === "object") { + notice = shallowClone(thing); + } else { + var m = String(thing); + notice = { message: m }; + } + return notice; + } + util$1.makeNotice = makeNotice$1; + function isErrorObject(thing) { + return thing instanceof Error || Object.prototype.toString.call(thing) === "[object Error]"; + } + util$1.isErrorObject = isErrorObject; + function instrument$5(object, name, replacement) { + if (!object || !name || !replacement || !(name in object)) { + return; + } + var original = object[name]; + while (original && original.__hb_original) { + original = original.__hb_original; + } + try { + object[name] = replacement(original); + object[name].__hb_original = original; + } catch (_e) { + } + } + util$1.instrument = instrument$5; + function endpoint(base, path) { + var endpoint2 = base.trim().replace(/\/$/, ""); + path = path.trim().replace(/(^\/|\/$)/g, ""); + return "".concat(endpoint2, "/").concat(path); + } + util$1.endpoint = endpoint; + function generateStackTrace() { + try { + throw new Error(""); + } catch (e) { + if (e.stack) { + return e.stack; + } + } + var maxStackSize = 10; + var stack = []; + var curr = arguments.callee; + while (curr && stack.length < maxStackSize) { + if (/function(?:\s+([\w$]+))+\s*\(/.test(curr.toString())) { + stack.push(RegExp.$1 || ""); + } else { + stack.push(""); + } + try { + curr = curr.caller; + } catch (e) { + break; + } + } + return stack.join("\n"); + } + util$1.generateStackTrace = generateStackTrace; + function filter(obj, filters) { + if (!is("Object", obj)) { + return; + } + if (!is("Array", filters)) { + filters = []; + } + var seen = []; + function filter2(obj2) { + var k, newObj; + if (is("Object", obj2) || is("Array", obj2)) { + if (seen.indexOf(obj2) !== -1) { + return "[CIRCULAR DATA STRUCTURE]"; + } + seen.push(obj2); + } + if (is("Object", obj2)) { + newObj = {}; + for (k in obj2) { + if (filterMatch(k, filters)) { + newObj[k] = "[FILTERED]"; + } else { + newObj[k] = filter2(obj2[k]); + } + } + return newObj; + } + if (is("Array", obj2)) { + return obj2.map(function(v) { + return filter2(v); + }); + } + if (is("Function", obj2)) { + return "[FUNC]"; + } + return obj2; + } + return filter2(obj); + } + util$1.filter = filter; + function filterMatch(key, filters) { + for (var i = 0; i < filters.length; i++) { + if (key.toLowerCase().indexOf(filters[i].toLowerCase()) !== -1) { + return true; + } + } + return false; + } + function is(type, obj) { + var klass = Object.prototype.toString.call(obj).slice(8, -1); + return obj !== void 0 && obj !== null && klass === type; + } + function filterUrl(url, filters) { + if (!filters) { + return url; + } + if (typeof url !== "string") { + return url; + } + var query = url.split(/\?/, 2)[1]; + if (!query) { + return url; + } + var result = url; + query.split(/[&]\s?/).forEach(function(pair) { + var _a = pair.split("=", 2), key = _a[0], value = _a[1]; + if (filterMatch(key, filters)) { + result = result.replace("".concat(key, "=").concat(value), "".concat(key, "=[FILTERED]")); + } + }); + return result; + } + util$1.filterUrl = filterUrl; + function formatCGIData(vars, prefix) { + if (prefix === void 0) { + prefix = ""; + } + var formattedVars = {}; + Object.keys(vars).forEach(function(key) { + var formattedKey = prefix + key.replace(/\W/g, "_").toUpperCase(); + formattedVars[formattedKey] = vars[key]; + }); + return formattedVars; + } + util$1.formatCGIData = formatCGIData; + function clone(obj) { + return JSON.parse(JSON.stringify(obj)); + } + util$1.clone = clone; + function getSourceCodeSnippet(fileData, lineNumber, sourceRadius) { + if (sourceRadius === void 0) { + sourceRadius = 2; + } + if (!fileData) { + return null; + } + var lines = fileData.split("\n"); + lines.unshift(""); + var start = lineNumber - sourceRadius; + var end = lineNumber + sourceRadius; + var result = {}; + for (var i = start; i <= end; i++) { + var line = lines[i]; + if (typeof line === "string") { + result[i] = line; + } + } + return result; + } + function isBrowserConfig(config) { + return config.async !== void 0; + } + util$1.isBrowserConfig = isBrowserConfig; + var store = {}; + Object.defineProperty(store, "__esModule", { value: true }); + store.GlobalStore = void 0; + var util_1$2 = util$1; + var GlobalStore = function() { + function GlobalStore2(contents, breadcrumbsLimit) { + this.contents = contents; + this.breadcrumbsLimit = breadcrumbsLimit; + } + GlobalStore2.create = function(contents, breadcrumbsLimit) { + return new GlobalStore2(contents, breadcrumbsLimit); + }; + GlobalStore2.prototype.available = function() { + return true; + }; + GlobalStore2.prototype.getContents = function(key) { + var value = key ? this.contents[key] : this.contents; + return JSON.parse(JSON.stringify(value)); + }; + GlobalStore2.prototype.setContext = function(context) { + this.contents.context = (0, util_1$2.merge)(this.contents.context, context || {}); + }; + GlobalStore2.prototype.addBreadcrumb = function(breadcrumb) { + if (this.contents.breadcrumbs.length == this.breadcrumbsLimit) { + this.contents.breadcrumbs.shift(); + } + this.contents.breadcrumbs.push(breadcrumb); + }; + GlobalStore2.prototype.clear = function() { + this.contents.context = {}; + this.contents.breadcrumbs = []; + }; + GlobalStore2.prototype.run = function(callback) { + return callback(); + }; + return GlobalStore2; + }(); + store.GlobalStore = GlobalStore; + var __assign = commonjsGlobal && commonjsGlobal.__assign || function() { + __assign = Object.assign || function(t) { + for (var s, i = 1, n = arguments.length; i < n; i++) { + s = arguments[i]; + for (var p in s) + if (Object.prototype.hasOwnProperty.call(s, p)) + t[p] = s[p]; + } + return t; + }; + return __assign.apply(this, arguments); + }; + Object.defineProperty(client, "__esModule", { value: true }); + client.Client = void 0; + var util_1$1 = util$1; + var store_1 = store; + var notifier = { + name: "honeybadger-js", + url: "https://github.com/honeybadger-io/honeybadger-js", + version: "4.7.4" + }; + var TAG_SEPARATOR = /,|\s+/; + var NOT_BLANK = /\S/; + var Client = function() { + function Client2(opts, transport2) { + if (opts === void 0) { + opts = {}; + } + this.__pluginsExecuted = false; + this.__store = null; + this.__beforeNotifyHandlers = []; + this.__afterNotifyHandlers = []; + this.config = __assign({ apiKey: null, endpoint: "https://api.honeybadger.io", environment: null, hostname: null, projectRoot: null, component: null, action: null, revision: null, reportData: null, breadcrumbsEnabled: true, maxBreadcrumbs: 40, maxObjectDepth: 8, logger: console, developmentEnvironments: ["dev", "development", "test"], debug: false, tags: null, enableUncaught: true, enableUnhandledRejection: true, afterUncaught: function() { + return true; + }, filters: ["creditcard", "password"], __plugins: [] }, opts); + this.__initStore(); + this.__transport = transport2; + this.logger = (0, util_1$1.logger)(this); + } + Client2.prototype.getVersion = function() { + return notifier.version; + }; + Client2.prototype.configure = function(opts) { + var _this = this; + if (opts === void 0) { + opts = {}; + } + for (var k in opts) { + this.config[k] = opts[k]; + } + if (!this.__pluginsExecuted) { + this.__pluginsExecuted = true; + this.config.__plugins.forEach(function(plugin) { + return plugin.load(_this); + }); + } + return this; + }; + Client2.prototype.__initStore = function() { + this.__store = new store_1.GlobalStore({ context: {}, breadcrumbs: [] }, this.config.maxBreadcrumbs); + }; + Client2.prototype.beforeNotify = function(handler) { + this.__beforeNotifyHandlers.push(handler); + return this; + }; + Client2.prototype.afterNotify = function(handler) { + this.__afterNotifyHandlers.push(handler); + return this; + }; + Client2.prototype.setContext = function(context) { + if (typeof context === "object" && context != null) { + this.__store.setContext(context); + } + return this; + }; + Client2.prototype.resetContext = function(context) { + this.logger.warn("Deprecation warning: `Honeybadger.resetContext()` has been deprecated; please use `Honeybadger.clear()` instead."); + this.__store.clear(); + if (typeof context === "object" && context !== null) { + this.__store.setContext(context); + } + return this; + }; + Client2.prototype.clear = function() { + this.__store.clear(); + return this; + }; + Client2.prototype.notify = function(noticeable, name, extra) { + var _this = this; + if (name === void 0) { + name = void 0; + } + if (extra === void 0) { + extra = void 0; + } + var preConditionError = null; + var notice = this.makeNotice(noticeable, name, extra); + if (!notice) { + this.logger.debug("failed to build error report"); + preConditionError = new Error("failed to build error report"); + } + if (!preConditionError && this.config.reportData === false) { + this.logger.debug("skipping error report: honeybadger.js is disabled", notice); + preConditionError = new Error("honeybadger.js is disabled"); + } + if (!preConditionError && this.__developmentMode()) { + this.logger.log("honeybadger.js is in development mode; the following error report will be sent in production.", notice); + preConditionError = new Error("honeybadger.js is in development mode"); + } + if (!preConditionError && !this.config.apiKey) { + this.logger.warn("could not send error report: no API key has been configured", notice); + preConditionError = new Error("missing API key"); + } + var sourceCodeData = notice && notice.backtrace ? notice.backtrace.map(function(trace) { + return (0, util_1$1.shallowClone)(trace); + }) : null; + var beforeNotifyResult = (0, util_1$1.runBeforeNotifyHandlers)(notice, this.__beforeNotifyHandlers); + if (!preConditionError && !beforeNotifyResult) { + this.logger.debug("skipping error report: beforeNotify handlers returned false", notice); + preConditionError = new Error("beforeNotify handlers returned false"); + } + if (preConditionError) { + (0, util_1$1.runAfterNotifyHandlers)(notice, this.__afterNotifyHandlers, preConditionError); + return false; + } + this.addBreadcrumb("Honeybadger Notice", { + category: "notice", + metadata: { + message: notice.message, + name: notice.name, + stack: notice.stack + } + }); + var breadcrumbs2 = this.__store.getContents("breadcrumbs"); + notice.__breadcrumbs = this.config.breadcrumbsEnabled ? breadcrumbs2 : []; + (0, util_1$1.getSourceForBacktrace)(sourceCodeData, this.__getSourceFileHandler).then(function(sourcePerTrace) { + sourcePerTrace.forEach(function(source, index) { + notice.backtrace[index].source = source; + }); + var payload = _this.__buildPayload(notice); + _this.__transport.send({ + headers: { + "X-API-Key": _this.config.apiKey, + "Content-Type": "application/json", + "Accept": "text/json, application/json" + }, + method: "POST", + endpoint: (0, util_1$1.endpoint)(_this.config.endpoint, "/v1/notices/js"), + maxObjectDepth: _this.config.maxObjectDepth, + logger: _this.logger, + async: (0, util_1$1.isBrowserConfig)(_this.config) ? _this.config.async : void 0 + }, payload).then(function(res) { + if (res.statusCode !== 201) { + (0, util_1$1.runAfterNotifyHandlers)(notice, _this.__afterNotifyHandlers, new Error("Bad HTTP response: ".concat(res.statusCode))); + _this.logger.warn("Error report failed: unknown response from server. code=".concat(res.statusCode)); + return; + } + var uuid = JSON.parse(res.body).id; + (0, util_1$1.runAfterNotifyHandlers)((0, util_1$1.merge)(notice, { + id: uuid + }), _this.__afterNotifyHandlers); + _this.logger.info("Error report sent \u26A1 https://app.honeybadger.io/notice/".concat(uuid)); + }).catch(function(err) { + _this.logger.error("Error report failed: an unknown error occurred.", "message=".concat(err.message)); + (0, util_1$1.runAfterNotifyHandlers)(notice, _this.__afterNotifyHandlers, err); + }); + }); + return true; + }; + Client2.prototype.notifyAsync = function(noticeable, name, extra) { + var _this = this; + if (name === void 0) { + name = void 0; + } + if (extra === void 0) { + extra = void 0; + } + return new Promise(function(resolve, reject) { + var applyAfterNotify = function(partialNotice) { + var originalAfterNotify = partialNotice.afterNotify; + partialNotice.afterNotify = function(err) { + originalAfterNotify === null || originalAfterNotify === void 0 ? void 0 : originalAfterNotify.call(_this, err); + if (err) { + return reject(err); + } + resolve(); + }; + }; + var objectToOverride; + if (noticeable.afterNotify) { + objectToOverride = noticeable; + } else if (name && name.afterNotify) { + objectToOverride = name; + } else if (extra && extra.afterNotify) { + objectToOverride = extra; + } else if (name && typeof name === "object") { + objectToOverride = name; + } else if (extra) { + objectToOverride = extra; + } else { + objectToOverride = name = {}; + } + applyAfterNotify(objectToOverride); + _this.notify(noticeable, name, extra); + }); + }; + Client2.prototype.makeNotice = function(noticeable, name, extra) { + if (name === void 0) { + name = void 0; + } + if (extra === void 0) { + extra = void 0; + } + var notice = (0, util_1$1.makeNotice)(noticeable); + if (name && !(typeof name === "object")) { + var n = String(name); + name = { name: n }; + } + if (name) { + notice = (0, util_1$1.mergeNotice)(notice, name); + } + if (typeof extra === "object" && extra !== null) { + notice = (0, util_1$1.mergeNotice)(notice, extra); + } + if ((0, util_1$1.objectIsEmpty)(notice)) { + return null; + } + var context = this.__store.getContents("context"); + var noticeTags = this.__constructTags(notice.tags); + var contextTags = this.__constructTags(context["tags"]); + var configTags = this.__constructTags(this.config.tags); + var tags = noticeTags.concat(contextTags).concat(configTags); + var uniqueTags = tags.filter(function(item, index) { + return tags.indexOf(item) === index; + }); + notice = (0, util_1$1.merge)(notice, { + name: notice.name || "Error", + context: (0, util_1$1.merge)(context, notice.context), + projectRoot: notice.projectRoot || this.config.projectRoot, + environment: notice.environment || this.config.environment, + component: notice.component || this.config.component, + action: notice.action || this.config.action, + revision: notice.revision || this.config.revision, + tags: uniqueTags + }); + var backtraceShift = 0; + if (typeof notice.stack !== "string" || !notice.stack.trim()) { + notice.stack = (0, util_1$1.generateStackTrace)(); + backtraceShift = 2; + } + notice.backtrace = (0, util_1$1.makeBacktrace)(notice.stack, backtraceShift); + return notice; + }; + Client2.prototype.addBreadcrumb = function(message, opts) { + if (!this.config.breadcrumbsEnabled) { + return; + } + opts = opts || {}; + var metadata = (0, util_1$1.shallowClone)(opts.metadata); + var category = opts.category || "custom"; + var timestamp = new Date().toISOString(); + this.__store.addBreadcrumb({ + category, + message, + metadata, + timestamp + }); + return this; + }; + Client2.prototype.__getBreadcrumbs = function() { + return this.__store.getContents("breadcrumbs").slice(); + }; + Client2.prototype.__getContext = function() { + return this.__store.getContents("context"); + }; + Client2.prototype.__developmentMode = function() { + if (this.config.reportData === true) { + return false; + } + return this.config.environment && this.config.developmentEnvironments.includes(this.config.environment); + }; + Client2.prototype.__buildPayload = function(notice) { + var headers = (0, util_1$1.filter)(notice.headers, this.config.filters) || {}; + var cgiData = (0, util_1$1.filter)(__assign(__assign({}, notice.cgiData), (0, util_1$1.formatCGIData)(headers, "HTTP_")), this.config.filters); + return { + notifier, + breadcrumbs: { + enabled: !!this.config.breadcrumbsEnabled, + trail: notice.__breadcrumbs || [] + }, + error: { + class: notice.name, + message: notice.message, + backtrace: notice.backtrace, + fingerprint: notice.fingerprint, + tags: notice.tags, + causes: (0, util_1$1.getCauses)(notice) + }, + request: { + url: (0, util_1$1.filterUrl)(notice.url, this.config.filters), + component: notice.component, + action: notice.action, + context: notice.context, + cgi_data: cgiData, + params: (0, util_1$1.filter)(notice.params, this.config.filters) || {}, + session: (0, util_1$1.filter)(notice.session, this.config.filters) || {} + }, + server: { + project_root: notice.projectRoot, + environment_name: notice.environment, + revision: notice.revision, + hostname: this.config.hostname, + time: new Date().toUTCString() + }, + details: notice.details || {} + }; + }; + Client2.prototype.__constructTags = function(tags) { + if (!tags) { + return []; + } + return tags.toString().split(TAG_SEPARATOR).filter(function(tag) { + return NOT_BLANK.test(tag); + }); + }; + return Client2; + }(); + client.Client = Client; + var types = {}; + Object.defineProperty(types, "__esModule", { value: true }); + (function(exports2) { + var __createBinding2 = commonjsGlobal && commonjsGlobal.__createBinding || (Object.create ? function(o, m, k, k2) { + if (k2 === void 0) + k2 = k; + var desc = Object.getOwnPropertyDescriptor(m, k); + if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) { + desc = { enumerable: true, get: function() { + return m[k]; + } }; + } + Object.defineProperty(o, k2, desc); + } : function(o, m, k, k2) { + if (k2 === void 0) + k2 = k; + o[k2] = m[k]; + }); + var __setModuleDefault2 = commonjsGlobal && commonjsGlobal.__setModuleDefault || (Object.create ? function(o, v) { + Object.defineProperty(o, "default", { enumerable: true, value: v }); + } : function(o, v) { + o["default"] = v; + }); + var __exportStar = commonjsGlobal && commonjsGlobal.__exportStar || function(m, exports3) { + for (var p in m) + if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports3, p)) + __createBinding2(exports3, m, p); + }; + var __importStar2 = commonjsGlobal && commonjsGlobal.__importStar || function(mod) { + if (mod && mod.__esModule) + return mod; + var result = {}; + if (mod != null) { + for (var k in mod) + if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) + __createBinding2(result, mod, k); + } + __setModuleDefault2(result, mod); + return result; + }; + Object.defineProperty(exports2, "__esModule", { value: true }); + exports2.Util = exports2.Types = exports2.Client = void 0; + var client_1 = client; + Object.defineProperty(exports2, "Client", { enumerable: true, get: function() { + return client_1.Client; + } }); + __exportStar(store, exports2); + exports2.Types = __importStar2(types); + exports2.Util = __importStar2(util$1); + })(src); + var util = {}; + Object.defineProperty(util, "__esModule", { value: true }); + util.preferCatch = util.encodeCookie = util.decodeCookie = util.localURLPathname = util.parseURL = util.nativeFetch = util.stringTextOfElement = util.stringSelectorOfElement = util.stringNameOfElement = void 0; + function stringNameOfElement(element) { + if (!element || !element.tagName) { + return ""; + } + var name = element.tagName.toLowerCase(); + if (name === "html") { + return ""; + } + if (element.id) { + name += "#".concat(element.id); + } + var stringClassNames = element.getAttribute("class"); + if (stringClassNames) { + stringClassNames.split(/\s+/).forEach(function(className) { + name += ".".concat(className); + }); + } + ["alt", "name", "title", "type"].forEach(function(attrName) { + var attr = element.getAttribute(attrName); + if (attr) { + name += "[".concat(attrName, '="').concat(attr, '"]'); + } + }); + var siblings = getSiblings(element); + if (siblings.length > 1) { + name += ":nth-child(".concat(Array.prototype.indexOf.call(siblings, element) + 1, ")"); + } + return name; + } + util.stringNameOfElement = stringNameOfElement; + function stringSelectorOfElement(element) { + var name = stringNameOfElement(element); + if (element.parentNode && element.parentNode.tagName) { + var parentName = stringSelectorOfElement(element.parentNode); + if (parentName.length > 0) { + return "".concat(parentName, " > ").concat(name); + } + } + return name; + } + util.stringSelectorOfElement = stringSelectorOfElement; + function stringTextOfElement(element) { + var text = element.textContent || element.innerText || ""; + if (!text && (element.type === "submit" || element.type === "button")) { + text = element.value; + } + return truncate(text.trim(), 300); + } + util.stringTextOfElement = stringTextOfElement; + function nativeFetch() { + if (!window.fetch) { + return false; + } + if (isNative(window.fetch)) { + return true; + } + try { + var sandbox = document.createElement("iframe"); + sandbox.style.display = "none"; + document.head.appendChild(sandbox); + var result = sandbox.contentWindow.fetch && isNative(sandbox.contentWindow.fetch); + document.head.removeChild(sandbox); + return result; + } catch (err) { + if (console && console.warn) { + console.warn("failed to detect native fetch via iframe: " + err); + } + } + return false; + } + util.nativeFetch = nativeFetch; + function isNative(func) { + return func.toString().indexOf("native") !== -1; + } + function parseURL(url) { + var match = url.match(/^(([^:/?#]+):)?(\/\/([^/?#]*))?([^?#]*)(\?([^#]*))?(#(.*))?$/) || {}; + return { + protocol: match[2], + host: match[4], + pathname: match[5] + }; + } + util.parseURL = parseURL; + function localURLPathname(url) { + var parsed = parseURL(url); + var parsedDocURL = parseURL(document.URL); + if (!parsed.host || !parsed.protocol) { + return parsed.pathname; + } + if (parsed.protocol === parsedDocURL.protocol && parsed.host === parsedDocURL.host) { + return parsed.pathname; + } + return "".concat(parsed.protocol, "://").concat(parsed.host).concat(parsed.pathname); + } + util.localURLPathname = localURLPathname; + function decodeCookie(string) { + var result = {}; + string.split(/[;,]\s?/).forEach(function(pair) { + var _a = pair.split("=", 2), key = _a[0], value = _a[1]; + result[key] = value; + }); + return result; + } + util.decodeCookie = decodeCookie; + function encodeCookie(object) { + if (typeof object !== "object") { + return void 0; + } + var cookies = []; + for (var k in object) { + cookies.push(k + "=" + object[k]); + } + return cookies.join(";"); + } + util.encodeCookie = encodeCookie; + function getSiblings(element) { + try { + var nodes = element.parentNode.childNodes; + var siblings_1 = []; + Array.prototype.forEach.call(nodes, function(node) { + if (node.tagName && node.tagName === element.tagName) { + siblings_1.push(node); + } + }); + return siblings_1; + } catch (e) { + return []; + } + } + function truncate(string, length) { + if (string.length > length) { + string = string.substr(0, length) + "..."; + } + return string; + } + util.preferCatch = function() { + var preferCatch = true; + if (!window.atob) { + preferCatch = false; + } + if (window.ErrorEvent) { + try { + if (new window.ErrorEvent("").colno === 0) { + preferCatch = false; + } + } catch (_e) { + } + } + return preferCatch; + }(); + var onerror = {}; + Object.defineProperty(onerror, "__esModule", { value: true }); + onerror.onError = onerror.ignoreNextOnError = void 0; + var core_1$5 = src; + var instrument$4 = core_1$5.Util.instrument, makeNotice = core_1$5.Util.makeNotice; + var ignoreOnError = 0; + var currentTimeout; + function ignoreNextOnError() { + ignoreOnError += 1; + clearTimeout(currentTimeout); + currentTimeout = setTimeout(function() { + ignoreOnError = 0; + }); + } + onerror.ignoreNextOnError = ignoreNextOnError; + function onError(_window) { + if (_window === void 0) { + _window = window; + } + return { + load: function(client2) { + instrument$4(_window, "onerror", function(original) { + var onerror2 = function(msg, url, line, col, err) { + client2.logger.debug("window.onerror callback invoked", arguments); + if (ignoreOnError > 0) { + client2.logger.debug("Ignoring window.onerror (error likely reported earlier)", arguments); + ignoreOnError -= 1; + return; + } + if (line === 0 && /Script error\.?/.test(msg)) { + if (client2.config.enableUncaught) { + client2.logger.warn("Ignoring cross-domain script error: enable CORS to track these types of errors", arguments); + } + return; + } + var notice = makeNotice(err); + if (!notice.name) { + notice.name = "window.onerror"; + } + if (!notice.message) { + notice.message = msg; + } + if (!notice.stack) { + notice.stack = [notice.message, "\n at ? (", url || "unknown", ":", line || 0, ":", col || 0, ")"].join(""); + } + client2.addBreadcrumb(notice.name === "window.onerror" || !notice.name ? "window.onerror" : "window.onerror: ".concat(notice.name), { + category: "error", + metadata: { + name: notice.name, + message: notice.message, + stack: notice.stack + } + }); + if (client2.config.enableUncaught) { + client2.notify(notice); + } + }; + return function(msg, url, line, col, err) { + onerror2(msg, url, line, col, err); + if (typeof original === "function") { + return original.apply(window, arguments); + } + return false; + }; + }); + } + }; + } + onerror.onError = onError; + var onunhandledrejection = {}; + Object.defineProperty(onunhandledrejection, "__esModule", { value: true }); + var core_1$4 = src; + var instrument$3 = core_1$4.Util.instrument; + function default_1$3(_window) { + if (_window === void 0) { + _window = window; + } + return { + load: function(client2) { + if (!client2.config.enableUnhandledRejection) { + return; + } + instrument$3(_window, "onunhandledrejection", function(original) { + function onunhandledrejection2(promiseRejectionEvent) { + var _a; + client2.logger.debug("window.onunhandledrejection callback invoked", arguments); + if (!client2.config.enableUnhandledRejection) { + return; + } + var reason = promiseRejectionEvent.reason; + if (reason instanceof Error) { + var fileName = "unknown"; + var lineNumber = 0; + var stackFallback = "".concat(reason.message, "\n at ? (").concat(fileName, ":").concat(lineNumber, ")"); + var stack = reason.stack || stackFallback; + var err = { + name: reason.name, + message: "UnhandledPromiseRejectionWarning: ".concat(reason), + stack + }; + client2.addBreadcrumb("window.onunhandledrejection: ".concat(err.name), { + category: "error", + metadata: err + }); + client2.notify(err); + return; + } + var message = typeof reason === "string" ? reason : (_a = JSON.stringify(reason)) !== null && _a !== void 0 ? _a : "Unspecified reason"; + client2.notify({ + name: "window.onunhandledrejection", + message: "UnhandledPromiseRejectionWarning: ".concat(message) + }); + } + return function(promiseRejectionEvent) { + onunhandledrejection2(promiseRejectionEvent); + if (typeof original === "function") { + original.apply(this, arguments); + } + }; + }); + } + }; + } + onunhandledrejection.default = default_1$3; + var breadcrumbs = {}; + Object.defineProperty(breadcrumbs, "__esModule", { value: true }); + var core_1$3 = src; + var util_1 = util; + var sanitize$1 = core_1$3.Util.sanitize, instrument$2 = core_1$3.Util.instrument; + function default_1$2(_window) { + if (_window === void 0) { + _window = window; + } + return { + load: function(client2) { + function breadcrumbsEnabled(type) { + if (client2.config.breadcrumbsEnabled === true) { + return true; + } + if (type) { + return client2.config.breadcrumbsEnabled[type] === true; + } + return client2.config.breadcrumbsEnabled !== false; + } + (function() { + if (!breadcrumbsEnabled("console")) { + return; + } + function inspectArray(obj) { + if (!Array.isArray(obj)) { + return ""; + } + return obj.map(function(value) { + try { + return String(value); + } catch (e) { + return "[unknown]"; + } + }).join(" "); + } + ["debug", "info", "warn", "error", "log"].forEach(function(level) { + instrument$2(_window.console, level, function(original) { + return function() { + var args = Array.prototype.slice.call(arguments); + var message = inspectArray(args); + var opts = { + category: "log", + metadata: { + level, + arguments: sanitize$1(args, 3) + } + }; + client2.addBreadcrumb(message, opts); + if (typeof original === "function") { + Function.prototype.apply.call(original, _window.console, arguments); + } + }; + }); + }); + })(); + (function() { + if (!breadcrumbsEnabled("dom")) { + return; + } + _window.addEventListener("click", function(event) { + var message, selector, text; + try { + message = (0, util_1.stringNameOfElement)(event.target); + selector = (0, util_1.stringSelectorOfElement)(event.target); + text = (0, util_1.stringTextOfElement)(event.target); + } catch (e) { + message = "UI Click"; + selector = "[unknown]"; + text = "[unknown]"; + } + if (message.length === 0) { + return; + } + client2.addBreadcrumb(message, { + category: "ui.click", + metadata: { + selector, + text, + event + } + }); + }, true); + })(); + (function() { + if (!breadcrumbsEnabled("network")) { + return; + } + instrument$2(XMLHttpRequest.prototype, "open", function(original) { + return function() { + var xhr = this; + var url = arguments[1]; + var method = typeof arguments[0] === "string" ? arguments[0].toUpperCase() : arguments[0]; + var message = "".concat(method, " ").concat((0, util_1.localURLPathname)(url)); + this.__hb_xhr = { + type: "xhr", + method, + url, + message + }; + if (typeof original === "function") { + original.apply(xhr, arguments); + } + }; + }); + instrument$2(XMLHttpRequest.prototype, "send", function(original) { + return function() { + var xhr = this; + function onreadystatechangeHandler() { + if (xhr.readyState === 4) { + var message = void 0; + if (xhr.__hb_xhr) { + xhr.__hb_xhr.status_code = xhr.status; + message = xhr.__hb_xhr.message; + delete xhr.__hb_xhr.message; + } + client2.addBreadcrumb(message || "XMLHttpRequest", { + category: "request", + metadata: xhr.__hb_xhr + }); + } + } + if ("onreadystatechange" in xhr && typeof xhr.onreadystatechange === "function") { + instrument$2(xhr, "onreadystatechange", function(original2) { + return function() { + onreadystatechangeHandler(); + if (typeof original2 === "function") { + original2.apply(this, arguments); + } + }; + }); + } else { + xhr.onreadystatechange = onreadystatechangeHandler; + } + if (typeof original === "function") { + original.apply(xhr, arguments); + } + }; + }); + })(); + (function() { + if (!breadcrumbsEnabled("network")) { + return; + } + if (!(0, util_1.nativeFetch)()) { + return; + } + instrument$2(_window, "fetch", function(original) { + return function() { + var input = arguments[0]; + var method = "GET"; + var url; + if (typeof input === "string") { + url = input; + } else if ("Request" in _window && input instanceof Request) { + url = input.url; + if (input.method) { + method = input.method; + } + } else { + url = String(input); + } + if (arguments[1] && arguments[1].method) { + method = arguments[1].method; + } + if (typeof method === "string") { + method = method.toUpperCase(); + } + var message = "".concat(method, " ").concat((0, util_1.localURLPathname)(url)); + var metadata = { + type: "fetch", + method, + url + }; + return original.apply(this, arguments).then(function(response) { + metadata["status_code"] = response.status; + client2.addBreadcrumb(message, { + category: "request", + metadata + }); + return response; + }).catch(function(error) { + client2.addBreadcrumb("fetch error", { + category: "error", + metadata + }); + throw error; + }); + }; + }); + })(); + (function() { + if (!breadcrumbsEnabled("navigation")) { + return; + } + var lastHref = _window.location.href; + function recordUrlChange(from, to) { + lastHref = to; + client2.addBreadcrumb("Page changed", { + category: "navigation", + metadata: { + from, + to + } + }); + } + instrument$2(_window, "onpopstate", function(original) { + return function() { + recordUrlChange(lastHref, _window.location.href); + if (original) { + return original.apply(this, arguments); + } + }; + }); + function historyWrapper(original) { + return function() { + var url = arguments.length > 2 ? arguments[2] : void 0; + if (url) { + recordUrlChange(lastHref, String(url)); + } + return original.apply(this, arguments); + }; + } + instrument$2(_window.history, "pushState", historyWrapper); + instrument$2(_window.history, "replaceState", historyWrapper); + })(); + } + }; + } + breadcrumbs.default = default_1$2; + var timers = {}; + Object.defineProperty(timers, "__esModule", { value: true }); + var core_1$2 = src; + var instrument$1 = core_1$2.Util.instrument; + function default_1$1(_window) { + if (_window === void 0) { + _window = window; + } + return { + load: function(client2) { + (function() { + function instrumentTimer(wrapOpts) { + return function(original) { + return function(func, delay) { + if (typeof func === "function") { + var args_1 = Array.prototype.slice.call(arguments, 2); + func = client2.__wrap(func, wrapOpts); + return original(function() { + func.apply(void 0, args_1); + }, delay); + } else { + return original(func, delay); + } + }; + }; + } + instrument$1(_window, "setTimeout", instrumentTimer({ component: "setTimeout" })); + instrument$1(_window, "setInterval", instrumentTimer({ component: "setInterval" })); + })(); + } + }; + } + timers.default = default_1$1; + var event_listeners = {}; + Object.defineProperty(event_listeners, "__esModule", { value: true }); + var core_1$1 = src; + var instrument = core_1$1.Util.instrument; + function default_1(_window) { + if (_window === void 0) { + _window = window; + } + return { + load: function(client2) { + var targets = ["EventTarget", "Window", "Node", "ApplicationCache", "AudioTrackList", "ChannelMergerNode", "CryptoOperation", "EventSource", "FileReader", "HTMLUnknownElement", "IDBDatabase", "IDBRequest", "IDBTransaction", "KeyOperation", "MediaController", "MessagePort", "ModalWindow", "Notification", "SVGElementInstance", "Screen", "TextTrack", "TextTrackCue", "TextTrackList", "WebSocket", "WebSocketWorker", "Worker", "XMLHttpRequest", "XMLHttpRequestEventTarget", "XMLHttpRequestUpload"]; + targets.forEach(function(prop) { + var prototype = _window[prop] && _window[prop].prototype; + if (prototype && Object.prototype.hasOwnProperty.call(prototype, "addEventListener")) { + instrument(prototype, "addEventListener", function(original) { + var wrapOpts = { component: "".concat(prop, ".prototype.addEventListener") }; + return function(type, listener, useCapture, wantsUntrusted) { + try { + if (listener && listener.handleEvent != null) { + listener.handleEvent = client2.__wrap(listener.handleEvent, wrapOpts); + } + } catch (e) { + client2.logger.error(e); + } + return original.call(this, type, client2.__wrap(listener, wrapOpts), useCapture, wantsUntrusted); + }; + }); + instrument(prototype, "removeEventListener", function(original) { + return function(type, listener, useCapture, wantsUntrusted) { + original.call(this, type, listener, useCapture, wantsUntrusted); + return original.call(this, type, client2.__wrap(listener), useCapture, wantsUntrusted); + }; + }); + } + }); + } + }; + } + event_listeners.default = default_1; + var transport = {}; + Object.defineProperty(transport, "__esModule", { value: true }); + transport.BrowserTransport = void 0; + var core_1 = src; + var sanitize = core_1.Util.sanitize; + var BrowserTransport = function() { + function BrowserTransport2() { + } + BrowserTransport2.prototype.send = function(options, payload) { + return new Promise(function(resolve, reject) { + try { + var x_1 = new XMLHttpRequest(); + x_1.open(options.method, options.endpoint, options.async); + if (Object.keys(options.headers || []).length) { + for (var i in options.headers) { + if (typeof options.headers[i] !== "undefined") { + x_1.setRequestHeader(i, String(options.headers[i])); + } + } + } + x_1.send(payload ? JSON.stringify(sanitize(payload, options.maxObjectDepth)) : void 0); + x_1.onload = function() { + return resolve({ statusCode: x_1.status, body: x_1.response }); + }; + } catch (err) { + reject(err); + } + }); + }; + return BrowserTransport2; + }(); + transport.BrowserTransport = BrowserTransport; + (function(exports2) { + var __extends = commonjsGlobal && commonjsGlobal.__extends || function() { + var extendStatics = function(d, b) { + extendStatics = Object.setPrototypeOf || { __proto__: [] } instanceof Array && function(d2, b2) { + d2.__proto__ = b2; + } || function(d2, b2) { + for (var p in b2) + if (Object.prototype.hasOwnProperty.call(b2, p)) + d2[p] = b2[p]; + }; + return extendStatics(d, b); + }; + return function(d, b) { + if (typeof b !== "function" && b !== null) + throw new TypeError("Class extends value " + String(b) + " is not a constructor or null"); + extendStatics(d, b); + function __() { + this.constructor = d; + } + d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); + }; + }(); + var __assign2 = commonjsGlobal && commonjsGlobal.__assign || function() { + __assign2 = Object.assign || function(t) { + for (var s, i = 1, n = arguments.length; i < n; i++) { + s = arguments[i]; + for (var p in s) + if (Object.prototype.hasOwnProperty.call(s, p)) + t[p] = s[p]; + } + return t; + }; + return __assign2.apply(this, arguments); + }; + var __importDefault = commonjsGlobal && commonjsGlobal.__importDefault || function(mod) { + return mod && mod.__esModule ? mod : { "default": mod }; + }; + Object.defineProperty(exports2, "__esModule", { value: true }); + exports2.Types = void 0; + var core_12 = src; + var util_12 = util; + var onerror_1 = onerror; + var onunhandledrejection_1 = __importDefault(onunhandledrejection); + var breadcrumbs_1 = __importDefault(breadcrumbs); + var timers_1 = __importDefault(timers); + var event_listeners_1 = __importDefault(event_listeners); + var transport_1 = transport; + var merge2 = core_12.Util.merge, filter2 = core_12.Util.filter, objectIsExtensible2 = core_12.Util.objectIsExtensible; + var Honeybadger2 = function(_super) { + __extends(Honeybadger3, _super); + function Honeybadger3(opts) { + if (opts === void 0) { + opts = {}; + } + var _this = _super.call(this, __assign2({ async: true, maxErrors: null, projectRoot: window.location.protocol + "//" + window.location.host }, opts), new transport_1.BrowserTransport()) || this; + _this.__errorsSent = 0; + _this.__lastWrapErr = void 0; + _this.__beforeNotifyHandlers = [ + function(notice) { + if (_this.__exceedsMaxErrors()) { + _this.logger.debug("Dropping notice: max errors exceeded", notice); + return false; + } + if (notice && !notice.url) { + notice.url = document.URL; + } + _this.__incrementErrorsCount(); + return true; + } + ]; + return _this; + } + Honeybadger3.prototype.configure = function(opts) { + if (opts === void 0) { + opts = {}; + } + return _super.prototype.configure.call(this, opts); + }; + Honeybadger3.prototype.resetMaxErrors = function() { + return this.__errorsSent = 0; + }; + Honeybadger3.prototype.factory = function(opts) { + return new Honeybadger3(opts); + }; + Honeybadger3.prototype.checkIn = function(_id) { + throw new Error("Honeybadger.checkIn() is not supported on the browser"); + }; + Honeybadger3.prototype.__buildPayload = function(notice) { + var cgiData = { + HTTP_USER_AGENT: void 0, + HTTP_REFERER: void 0, + HTTP_COOKIE: void 0 + }; + cgiData.HTTP_USER_AGENT = navigator.userAgent; + if (document.referrer.match(/\S/)) { + cgiData.HTTP_REFERER = document.referrer; + } + var cookiesObject; + if (typeof notice.cookies === "string") { + cookiesObject = (0, util_12.decodeCookie)(notice.cookies); + } else { + cookiesObject = notice.cookies; + } + if (cookiesObject) { + cgiData.HTTP_COOKIE = (0, util_12.encodeCookie)(filter2(cookiesObject, this.config.filters)); + } + var payload = _super.prototype.__buildPayload.call(this, notice); + payload.request.cgi_data = merge2(cgiData, payload.request.cgi_data); + return payload; + }; + Honeybadger3.prototype.__wrap = function(f, opts) { + if (opts === void 0) { + opts = {}; + } + var func = f; + if (!opts) { + opts = {}; + } + try { + if (typeof func !== "function") { + return func; + } + if (!objectIsExtensible2(func)) { + return func; + } + if (!func.___hb) { + var client_1 = this; + func.___hb = function() { + if (util_12.preferCatch) { + try { + return func.apply(this, arguments); + } catch (err) { + if (client_1.__lastWrapErr === err) { + throw err; + } + client_1.__lastWrapErr = err; + (0, onerror_1.ignoreNextOnError)(); + client_1.addBreadcrumb(opts.component ? "".concat(opts.component, ": ").concat(err.name) : err.name, { + category: "error", + metadata: { + message: err.message, + name: err.name, + stack: err.stack + } + }); + if (client_1.config.enableUncaught) { + client_1.notify(err); + } + throw err; + } + } else { + return func.apply(this, arguments); + } + }; + } + func.___hb.___hb = func.___hb; + return func.___hb; + } catch (_e) { + return func; + } + }; + Honeybadger3.prototype.__incrementErrorsCount = function() { + return this.__errorsSent++; + }; + Honeybadger3.prototype.__exceedsMaxErrors = function() { + return this.config.maxErrors && this.__errorsSent >= this.config.maxErrors; + }; + return Honeybadger3; + }(core_12.Client); + var core_2 = src; + Object.defineProperty(exports2, "Types", { enumerable: true, get: function() { + return core_2.Types; + } }); + exports2.default = new Honeybadger2({ + __plugins: [ + (0, onerror_1.onError)(), + (0, onunhandledrejection_1.default)(), + (0, timers_1.default)(), + (0, event_listeners_1.default)(), + (0, breadcrumbs_1.default)() + ] + }); + })(browser$1); + var browser = /* @__PURE__ */ getDefaultExportFromCjs(browser$1); + return browser; + }); + } +}); + +// src/generated/env.ts +var env_default = { + "CDN": "https://multipay.komoju.com", + "ENV": "development", + "HONEYBADGER_API_KEY": "", + "GIT_REV": "99ad2eb29ce6530dedfe3a0ec34aea970dbaa78a" +}; + +// src/extras/error-reporting/module.ts +var Honeybadger = require_honeybadger(); +var initialized = false; +var reportError = (error, context) => { + if (window.komojuErrorReporting === false) + return; + if (!initialized) + initialize(); + console.error(error, context); + Honeybadger.setContext(context); + Honeybadger.notify(error); +}; +function initialize() { + Honeybadger.configure({ + apiKey: env_default.HONEYBADGER_API_KEY, + environment: env_default.ENV, + revision: env_default.GIT_REV, + filters: ["number", "cvc", "verification_value"], + enableUncaught: false + }); + initialized = true; +} +export { + reportError +}; +//# sourceMappingURL=module.js.map diff --git a/src/app/code/Komoju/Payments/view/frontend/web/js/extras/error-reporting/module.js.map b/src/app/code/Komoju/Payments/view/frontend/web/js/extras/error-reporting/module.js.map new file mode 100644 index 000000000..3542cf190 --- /dev/null +++ b/src/app/code/Komoju/Payments/view/frontend/web/js/extras/error-reporting/module.js.map @@ -0,0 +1,7 @@ +{ + "version": 3, + "sources": ["../../../node_modules/@honeybadger-io/core/node_modules/stacktrace-parser/dist/stack-trace-parser.esm.js", "../../../node_modules/@honeybadger-io/core/build/src/util.js", "../../../node_modules/@honeybadger-io/core/build/src/store.js", "../../../node_modules/@honeybadger-io/core/build/src/client.js", "../../../node_modules/@honeybadger-io/core/build/src/types.js", "../../../node_modules/@honeybadger-io/core/build/src/index.js", "../../../node_modules/@honeybadger-io/js/build/src/browser/util.js", "../../../node_modules/@honeybadger-io/js/build/src/browser/integrations/onerror.js", "../../../node_modules/@honeybadger-io/js/build/src/browser/integrations/onunhandledrejection.js", "../../../node_modules/@honeybadger-io/js/build/src/browser/integrations/breadcrumbs.js", "../../../node_modules/@honeybadger-io/js/build/src/browser/integrations/timers.js", "../../../node_modules/@honeybadger-io/js/build/src/browser/integrations/event_listeners.js", "../../../node_modules/@honeybadger-io/js/build/src/browser/transport.js", "../../../node_modules/@honeybadger-io/js/build/src/browser.js", "../../../src/generated/env.ts", "../../../src/extras/error-reporting/module.ts"], + "sourcesContent": ["var UNKNOWN_FUNCTION = '';\n/**\n * This parses the different stack traces and puts them into one format\n * This borrows heavily from TraceKit (https://github.com/csnover/TraceKit)\n */\n\nfunction parse(stackString) {\n var lines = stackString.split('\\n');\n return lines.reduce(function (stack, line) {\n var parseResult = parseChrome(line) || parseWinjs(line) || parseGecko(line) || parseNode(line) || parseJSC(line);\n\n if (parseResult) {\n stack.push(parseResult);\n }\n\n return stack;\n }, []);\n}\nvar chromeRe = /^\\s*at (.*?) ?\\(((?:file|https?|blob|chrome-extension|native|eval|webpack||\\/|[a-z]:\\\\|\\\\\\\\).*?)(?::(\\d+))?(?::(\\d+))?\\)?\\s*$/i;\nvar chromeEvalRe = /\\((\\S*)(?::(\\d+))(?::(\\d+))\\)/;\n\nfunction parseChrome(line) {\n var parts = chromeRe.exec(line);\n\n if (!parts) {\n return null;\n }\n\n var isNative = parts[2] && parts[2].indexOf('native') === 0; // start of line\n\n var isEval = parts[2] && parts[2].indexOf('eval') === 0; // start of line\n\n var submatch = chromeEvalRe.exec(parts[2]);\n\n if (isEval && submatch != null) {\n // throw out eval line/column and use top-most line/column number\n parts[2] = submatch[1]; // url\n\n parts[3] = submatch[2]; // line\n\n parts[4] = submatch[3]; // column\n }\n\n return {\n file: !isNative ? parts[2] : null,\n methodName: parts[1] || UNKNOWN_FUNCTION,\n arguments: isNative ? [parts[2]] : [],\n lineNumber: parts[3] ? +parts[3] : null,\n column: parts[4] ? +parts[4] : null\n };\n}\n\nvar winjsRe = /^\\s*at (?:((?:\\[object object\\])?.+) )?\\(?((?:file|ms-appx|https?|webpack|blob):.*?):(\\d+)(?::(\\d+))?\\)?\\s*$/i;\n\nfunction parseWinjs(line) {\n var parts = winjsRe.exec(line);\n\n if (!parts) {\n return null;\n }\n\n return {\n file: parts[2],\n methodName: parts[1] || UNKNOWN_FUNCTION,\n arguments: [],\n lineNumber: +parts[3],\n column: parts[4] ? +parts[4] : null\n };\n}\n\nvar geckoRe = /^\\s*(.*?)(?:\\((.*?)\\))?(?:^|@)((?:file|https?|blob|chrome|webpack|resource|\\[native).*?|[^@]*bundle)(?::(\\d+))?(?::(\\d+))?\\s*$/i;\nvar geckoEvalRe = /(\\S+) line (\\d+)(?: > eval line \\d+)* > eval/i;\n\nfunction parseGecko(line) {\n var parts = geckoRe.exec(line);\n\n if (!parts) {\n return null;\n }\n\n var isEval = parts[3] && parts[3].indexOf(' > eval') > -1;\n var submatch = geckoEvalRe.exec(parts[3]);\n\n if (isEval && submatch != null) {\n // throw out eval line/column and use top-most line number\n parts[3] = submatch[1];\n parts[4] = submatch[2];\n parts[5] = null; // no column when eval\n }\n\n return {\n file: parts[3],\n methodName: parts[1] || UNKNOWN_FUNCTION,\n arguments: parts[2] ? parts[2].split(',') : [],\n lineNumber: parts[4] ? +parts[4] : null,\n column: parts[5] ? +parts[5] : null\n };\n}\n\nvar javaScriptCoreRe = /^\\s*(?:([^@]*)(?:\\((.*?)\\))?@)?(\\S.*?):(\\d+)(?::(\\d+))?\\s*$/i;\n\nfunction parseJSC(line) {\n var parts = javaScriptCoreRe.exec(line);\n\n if (!parts) {\n return null;\n }\n\n return {\n file: parts[3],\n methodName: parts[1] || UNKNOWN_FUNCTION,\n arguments: [],\n lineNumber: +parts[4],\n column: parts[5] ? +parts[5] : null\n };\n}\n\nvar nodeRe = /^\\s*at (?:((?:\\[object object\\])?[^\\\\/]+(?: \\[as \\S+\\])?) )?\\(?(.*?):(\\d+)(?::(\\d+))?\\)?\\s*$/i;\n\nfunction parseNode(line) {\n var parts = nodeRe.exec(line);\n\n if (!parts) {\n return null;\n }\n\n return {\n file: parts[2],\n methodName: parts[1] || UNKNOWN_FUNCTION,\n arguments: [],\n lineNumber: +parts[3],\n column: parts[4] ? +parts[4] : null\n };\n}\n\nexport { parse };\n", "\"use strict\";\nvar __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {\n if (k2 === undefined) k2 = k;\n var desc = Object.getOwnPropertyDescriptor(m, k);\n if (!desc || (\"get\" in desc ? !m.__esModule : desc.writable || desc.configurable)) {\n desc = { enumerable: true, get: function() { return m[k]; } };\n }\n Object.defineProperty(o, k2, desc);\n}) : (function(o, m, k, k2) {\n if (k2 === undefined) k2 = k;\n o[k2] = m[k];\n}));\nvar __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {\n Object.defineProperty(o, \"default\", { enumerable: true, value: v });\n}) : function(o, v) {\n o[\"default\"] = v;\n});\nvar __importStar = (this && this.__importStar) || function (mod) {\n if (mod && mod.__esModule) return mod;\n var result = {};\n if (mod != null) for (var k in mod) if (k !== \"default\" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);\n __setModuleDefault(result, mod);\n return result;\n};\nvar __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {\n function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }\n return new (P || (P = Promise))(function (resolve, reject) {\n function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }\n function rejected(value) { try { step(generator[\"throw\"](value)); } catch (e) { reject(e); } }\n function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }\n step((generator = generator.apply(thisArg, _arguments || [])).next());\n });\n};\nvar __generator = (this && this.__generator) || function (thisArg, body) {\n var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g;\n return g = { next: verb(0), \"throw\": verb(1), \"return\": verb(2) }, typeof Symbol === \"function\" && (g[Symbol.iterator] = function() { return this; }), g;\n function verb(n) { return function (v) { return step([n, v]); }; }\n function step(op) {\n if (f) throw new TypeError(\"Generator is already executing.\");\n while (_) try {\n if (f = 1, y && (t = op[0] & 2 ? y[\"return\"] : op[0] ? y[\"throw\"] || ((t = y[\"return\"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;\n if (y = 0, t) op = [op[0] & 2, t.value];\n switch (op[0]) {\n case 0: case 1: t = op; break;\n case 4: _.label++; return { value: op[1], done: false };\n case 5: _.label++; y = op[1]; op = [0]; continue;\n case 7: op = _.ops.pop(); _.trys.pop(); continue;\n default:\n if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }\n if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }\n if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }\n if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }\n if (t[2]) _.ops.pop();\n _.trys.pop(); continue;\n }\n op = body.call(thisArg, _);\n } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }\n if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };\n }\n};\nObject.defineProperty(exports, \"__esModule\", { value: true });\nexports.isBrowserConfig = exports.clone = exports.formatCGIData = exports.filterUrl = exports.filter = exports.generateStackTrace = exports.endpoint = exports.instrument = exports.isErrorObject = exports.makeNotice = exports.logger = exports.sanitize = exports.shallowClone = exports.runAfterNotifyHandlers = exports.runBeforeNotifyHandlers = exports.getSourceForBacktrace = exports.getCauses = exports.makeBacktrace = exports.objectIsExtensible = exports.objectIsEmpty = exports.mergeNotice = exports.merge = void 0;\nvar stackTraceParser = __importStar(require(\"stacktrace-parser\"));\nfunction merge(obj1, obj2) {\n var result = {};\n for (var k in obj1) {\n result[k] = obj1[k];\n }\n for (var k in obj2) {\n result[k] = obj2[k];\n }\n return result;\n}\nexports.merge = merge;\nfunction mergeNotice(notice1, notice2) {\n var result = merge(notice1, notice2);\n if (notice1.context && notice2.context) {\n result.context = merge(notice1.context, notice2.context);\n }\n return result;\n}\nexports.mergeNotice = mergeNotice;\nfunction objectIsEmpty(obj) {\n for (var k in obj) {\n if (Object.prototype.hasOwnProperty.call(obj, k)) {\n return false;\n }\n }\n return true;\n}\nexports.objectIsEmpty = objectIsEmpty;\nfunction objectIsExtensible(obj) {\n if (typeof Object.isExtensible !== 'function') {\n return true;\n }\n return Object.isExtensible(obj);\n}\nexports.objectIsExtensible = objectIsExtensible;\nfunction makeBacktrace(stack, shift) {\n if (shift === void 0) { shift = 0; }\n try {\n var backtrace = stackTraceParser\n .parse(stack)\n .map(function (line) {\n return {\n file: line.file,\n method: line.methodName,\n number: line.lineNumber,\n column: line.column\n };\n });\n backtrace.splice(0, shift);\n return backtrace;\n }\n catch (_err) {\n // TODO: log error\n return [];\n }\n}\nexports.makeBacktrace = makeBacktrace;\nfunction getCauses(notice) {\n if (notice.cause) {\n var causes = [];\n var cause = notice;\n while (causes.length < 3 && (cause = cause.cause)) {\n causes.push({\n class: cause.name,\n message: cause.message,\n backtrace: typeof cause.stack == 'string' ? makeBacktrace(cause.stack) : null\n });\n }\n return causes;\n }\n return [];\n}\nexports.getCauses = getCauses;\nfunction getSourceForBacktrace(backtrace, getSourceFileHandler) {\n return __awaiter(this, void 0, void 0, function () {\n var result, index, trace, fileContent;\n return __generator(this, function (_a) {\n switch (_a.label) {\n case 0:\n result = [];\n if (!getSourceFileHandler || !backtrace || !backtrace.length) {\n return [2 /*return*/, result];\n }\n index = 0;\n _a.label = 1;\n case 1:\n if (!backtrace.length) return [3 /*break*/, 3];\n trace = backtrace.splice(0)[index];\n return [4 /*yield*/, getSourceFileHandler(trace.file)];\n case 2:\n fileContent = _a.sent();\n result[index] = getSourceCodeSnippet(fileContent, trace.number);\n index++;\n return [3 /*break*/, 1];\n case 3: return [2 /*return*/, result];\n }\n });\n });\n}\nexports.getSourceForBacktrace = getSourceForBacktrace;\nfunction runBeforeNotifyHandlers(notice, handlers) {\n var result = true;\n for (var i = 0, len = handlers.length; i < len; i++) {\n var handler = handlers[i];\n if (handler(notice) === false) {\n result = false;\n }\n }\n return result;\n}\nexports.runBeforeNotifyHandlers = runBeforeNotifyHandlers;\nfunction runAfterNotifyHandlers(notice, handlers, error) {\n if (notice && notice.afterNotify) {\n notice.afterNotify(error, notice);\n }\n for (var i = 0, len = handlers.length; i < len; i++) {\n handlers[i](error, notice);\n }\n return true;\n}\nexports.runAfterNotifyHandlers = runAfterNotifyHandlers;\n// Returns a new object with properties from other object.\nfunction shallowClone(obj) {\n if (typeof (obj) !== 'object' || obj === null) {\n return {};\n }\n var result = {};\n for (var k in obj) {\n result[k] = obj[k];\n }\n return result;\n}\nexports.shallowClone = shallowClone;\nfunction sanitize(obj, maxDepth) {\n if (maxDepth === void 0) { maxDepth = 8; }\n var seenObjects = [];\n function seen(obj) {\n if (!obj || typeof (obj) !== 'object') {\n return false;\n }\n for (var i = 0; i < seenObjects.length; i++) {\n var value = seenObjects[i];\n if (value === obj) {\n return true;\n }\n }\n seenObjects.push(obj);\n return false;\n }\n function canSerialize(obj) {\n var typeOfObj = typeof obj;\n // Functions are TMI\n if (/function/.test(typeOfObj)) {\n // Let special toJSON method pass as it's used by JSON.stringify (#722)\n return obj.name === 'toJSON';\n }\n // Symbols can't convert to strings.\n if (/symbol/.test(typeOfObj)) {\n return false;\n }\n if (obj === null) {\n return false;\n }\n // No prototype, likely created with `Object.create(null)`.\n if (typeof obj === 'object' && typeof obj.hasOwnProperty === 'undefined') {\n return false;\n }\n return true;\n }\n function serialize(obj, depth) {\n if (depth === void 0) { depth = 0; }\n if (depth >= maxDepth) {\n return '[DEPTH]';\n }\n // Inspect invalid types\n if (!canSerialize(obj)) {\n return Object.prototype.toString.call(obj);\n }\n // Halt circular references\n if (seen(obj)) {\n return '[RECURSION]';\n }\n // Serialize inside arrays\n if (Array.isArray(obj)) {\n return obj.map(function (o) { return safeSerialize(o, depth + 1); });\n }\n // Serialize inside objects\n if (typeof (obj) === 'object') {\n var ret = {};\n for (var k in obj) {\n var v = obj[k];\n if (Object.prototype.hasOwnProperty.call(obj, k) && (k != null) && (v != null)) {\n ret[k] = safeSerialize(v, depth + 1);\n }\n }\n return ret;\n }\n // Return everything else untouched\n return obj;\n }\n function safeSerialize(obj, depth) {\n if (depth === void 0) { depth = 0; }\n try {\n return serialize(obj, depth);\n }\n catch (e) {\n return \"[ERROR] \".concat(e);\n }\n }\n return safeSerialize(obj);\n}\nexports.sanitize = sanitize;\nfunction logger(client) {\n var log = function (method) {\n return function () {\n var _a;\n var args = [];\n for (var _i = 0; _i < arguments.length; _i++) {\n args[_i] = arguments[_i];\n }\n if (method === 'debug') {\n if (!client.config.debug) {\n return;\n }\n // Log at default level so that you don't need to also enable verbose\n // logging in Chrome.\n method = 'log';\n }\n args.unshift('[Honeybadger]');\n (_a = client.config.logger)[method].apply(_a, args);\n };\n };\n return {\n log: log('log'),\n info: log('info'),\n debug: log('debug'),\n warn: log('warn'),\n error: log('error')\n };\n}\nexports.logger = logger;\n/**\n * Converts any object into a notice object (which at minimum has the same\n * properties as Error, but supports additional Honeybadger properties.)\n */\nfunction makeNotice(thing) {\n var notice;\n if (!thing) {\n notice = {};\n }\n else if (isErrorObject(thing)) {\n var e = thing;\n notice = merge(thing, { name: e.name, message: e.message, stack: e.stack, cause: e.cause });\n }\n else if (typeof thing === 'object') {\n notice = shallowClone(thing);\n }\n else {\n var m = String(thing);\n notice = { message: m };\n }\n return notice;\n}\nexports.makeNotice = makeNotice;\nfunction isErrorObject(thing) {\n return thing instanceof Error\n || Object.prototype.toString.call(thing) === '[object Error]'; // Important for cross-realm objects\n}\nexports.isErrorObject = isErrorObject;\n/**\n * Instrument an existing function inside an object (usually global).\n * @param {!Object} object\n * @param {!String} name\n * @param {!Function} replacement\n */\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nfunction instrument(object, name, replacement) {\n if (!object || !name || !replacement || !(name in object)) {\n return;\n }\n var original = object[name];\n while (original && original.__hb_original) {\n original = original.__hb_original;\n }\n try {\n object[name] = replacement(original);\n object[name].__hb_original = original;\n }\n catch (_e) {\n // Ignores errors like this one:\n // Error: TypeError: Cannot set property onunhandledrejection of [object Object] which has only a getter\n // User-Agent: Mozilla/5.0 (Linux; Android 10; SAMSUNG SM-G960F) AppleWebKit/537.36 (KHTML, like Gecko) SamsungBrowser/12.1 Chrome/79.0.3945.136 Mobile Safari/537.36\n }\n}\nexports.instrument = instrument;\nfunction endpoint(base, path) {\n var endpoint = base.trim().replace(/\\/$/, '');\n path = path.trim().replace(/(^\\/|\\/$)/g, '');\n return \"\".concat(endpoint, \"/\").concat(path);\n}\nexports.endpoint = endpoint;\nfunction generateStackTrace() {\n try {\n throw new Error('');\n }\n catch (e) {\n if (e.stack) {\n return e.stack;\n }\n }\n var maxStackSize = 10;\n var stack = [];\n var curr = arguments.callee;\n while (curr && stack.length < maxStackSize) {\n if (/function(?:\\s+([\\w$]+))+\\s*\\(/.test(curr.toString())) {\n stack.push(RegExp.$1 || '');\n }\n else {\n stack.push('');\n }\n try {\n curr = curr.caller;\n }\n catch (e) {\n break;\n }\n }\n return stack.join('\\n');\n}\nexports.generateStackTrace = generateStackTrace;\nfunction filter(obj, filters) {\n if (!is('Object', obj)) {\n return;\n }\n if (!is('Array', filters)) {\n filters = [];\n }\n var seen = [];\n function filter(obj) {\n var k, newObj;\n if (is('Object', obj) || is('Array', obj)) {\n if (seen.indexOf(obj) !== -1) {\n return '[CIRCULAR DATA STRUCTURE]';\n }\n seen.push(obj);\n }\n if (is('Object', obj)) {\n newObj = {};\n for (k in obj) {\n if (filterMatch(k, filters)) {\n newObj[k] = '[FILTERED]';\n }\n else {\n newObj[k] = filter(obj[k]);\n }\n }\n return newObj;\n }\n if (is('Array', obj)) {\n return obj.map(function (v) {\n return filter(v);\n });\n }\n if (is('Function', obj)) {\n return '[FUNC]';\n }\n return obj;\n }\n return filter(obj);\n}\nexports.filter = filter;\nfunction filterMatch(key, filters) {\n for (var i = 0; i < filters.length; i++) {\n if (key.toLowerCase().indexOf(filters[i].toLowerCase()) !== -1) {\n return true;\n }\n }\n return false;\n}\nfunction is(type, obj) {\n var klass = Object.prototype.toString.call(obj).slice(8, -1);\n return obj !== undefined && obj !== null && klass === type;\n}\nfunction filterUrl(url, filters) {\n if (!filters) {\n return url;\n }\n if (typeof url !== 'string') {\n return url;\n }\n var query = url.split(/\\?/, 2)[1];\n if (!query) {\n return url;\n }\n var result = url;\n query.split(/[&]\\s?/).forEach(function (pair) {\n var _a = pair.split('=', 2), key = _a[0], value = _a[1];\n if (filterMatch(key, filters)) {\n result = result.replace(\"\".concat(key, \"=\").concat(value), \"\".concat(key, \"=[FILTERED]\"));\n }\n });\n return result;\n}\nexports.filterUrl = filterUrl;\nfunction formatCGIData(vars, prefix) {\n if (prefix === void 0) { prefix = ''; }\n var formattedVars = {};\n Object.keys(vars).forEach(function (key) {\n var formattedKey = prefix + key.replace(/\\W/g, '_').toUpperCase();\n formattedVars[formattedKey] = vars[key];\n });\n return formattedVars;\n}\nexports.formatCGIData = formatCGIData;\nfunction clone(obj) {\n return JSON.parse(JSON.stringify(obj));\n}\nexports.clone = clone;\nfunction getSourceCodeSnippet(fileData, lineNumber, sourceRadius) {\n if (sourceRadius === void 0) { sourceRadius = 2; }\n if (!fileData) {\n return null;\n }\n var lines = fileData.split('\\n');\n // add one empty line because array index starts from 0, but error line number is counted from 1\n lines.unshift('');\n var start = lineNumber - sourceRadius;\n var end = lineNumber + sourceRadius;\n var result = {};\n for (var i = start; i <= end; i++) {\n var line = lines[i];\n if (typeof line === 'string') {\n result[i] = line;\n }\n }\n return result;\n}\nfunction isBrowserConfig(config) {\n return config.async !== undefined;\n}\nexports.isBrowserConfig = isBrowserConfig;\n//# sourceMappingURL=util.js.map", "\"use strict\";\nObject.defineProperty(exports, \"__esModule\", { value: true });\nexports.GlobalStore = void 0;\nvar util_1 = require(\"./util\");\nvar GlobalStore = /** @class */ (function () {\n function GlobalStore(contents, breadcrumbsLimit) {\n this.contents = contents;\n this.breadcrumbsLimit = breadcrumbsLimit;\n }\n GlobalStore.create = function (contents, breadcrumbsLimit) {\n return new GlobalStore(contents, breadcrumbsLimit);\n };\n GlobalStore.prototype.available = function () {\n return true;\n };\n GlobalStore.prototype.getContents = function (key) {\n var value = key ? this.contents[key] : this.contents;\n return JSON.parse(JSON.stringify(value));\n };\n GlobalStore.prototype.setContext = function (context) {\n this.contents.context = (0, util_1.merge)(this.contents.context, context || {});\n };\n GlobalStore.prototype.addBreadcrumb = function (breadcrumb) {\n if (this.contents.breadcrumbs.length == this.breadcrumbsLimit) {\n this.contents.breadcrumbs.shift();\n }\n this.contents.breadcrumbs.push(breadcrumb);\n };\n GlobalStore.prototype.clear = function () {\n this.contents.context = {};\n this.contents.breadcrumbs = [];\n };\n GlobalStore.prototype.run = function (callback) {\n return callback();\n };\n return GlobalStore;\n}());\nexports.GlobalStore = GlobalStore;\n//# sourceMappingURL=store.js.map", "\"use strict\";\nvar __assign = (this && this.__assign) || function () {\n __assign = Object.assign || function(t) {\n for (var s, i = 1, n = arguments.length; i < n; i++) {\n s = arguments[i];\n for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))\n t[p] = s[p];\n }\n return t;\n };\n return __assign.apply(this, arguments);\n};\nObject.defineProperty(exports, \"__esModule\", { value: true });\nexports.Client = void 0;\nvar util_1 = require(\"./util\");\nvar store_1 = require(\"./store\");\nvar notifier = {\n name: 'honeybadger-js',\n url: 'https://github.com/honeybadger-io/honeybadger-js',\n version: '__VERSION__'\n};\n// Split at commas and spaces\nvar TAG_SEPARATOR = /,|\\s+/;\n// Checks for non-blank characters\nvar NOT_BLANK = /\\S/;\nvar Client = /** @class */ (function () {\n function Client(opts, transport) {\n if (opts === void 0) { opts = {}; }\n this.__pluginsExecuted = false;\n this.__store = null;\n this.__beforeNotifyHandlers = [];\n this.__afterNotifyHandlers = [];\n this.config = __assign({ apiKey: null, endpoint: 'https://api.honeybadger.io', environment: null, hostname: null, projectRoot: null, component: null, action: null, revision: null, reportData: null, breadcrumbsEnabled: true, maxBreadcrumbs: 40, maxObjectDepth: 8, logger: console, developmentEnvironments: ['dev', 'development', 'test'], debug: false, tags: null, enableUncaught: true, enableUnhandledRejection: true, afterUncaught: function () { return true; }, filters: ['creditcard', 'password'], __plugins: [] }, opts);\n this.__initStore();\n this.__transport = transport;\n this.logger = (0, util_1.logger)(this);\n }\n Client.prototype.getVersion = function () {\n return notifier.version;\n };\n Client.prototype.configure = function (opts) {\n var _this = this;\n if (opts === void 0) { opts = {}; }\n for (var k in opts) {\n this.config[k] = opts[k];\n }\n if (!this.__pluginsExecuted) {\n this.__pluginsExecuted = true;\n this.config.__plugins.forEach(function (plugin) { return plugin.load(_this); });\n }\n return this;\n };\n Client.prototype.__initStore = function () {\n this.__store = new store_1.GlobalStore({ context: {}, breadcrumbs: [] }, this.config.maxBreadcrumbs);\n };\n Client.prototype.beforeNotify = function (handler) {\n this.__beforeNotifyHandlers.push(handler);\n return this;\n };\n Client.prototype.afterNotify = function (handler) {\n this.__afterNotifyHandlers.push(handler);\n return this;\n };\n Client.prototype.setContext = function (context) {\n if (typeof context === 'object' && context != null) {\n this.__store.setContext(context);\n }\n return this;\n };\n Client.prototype.resetContext = function (context) {\n this.logger.warn('Deprecation warning: `Honeybadger.resetContext()` has been deprecated; please use `Honeybadger.clear()` instead.');\n this.__store.clear();\n if (typeof context === 'object' && context !== null) {\n this.__store.setContext(context);\n }\n return this;\n };\n Client.prototype.clear = function () {\n this.__store.clear();\n return this;\n };\n Client.prototype.notify = function (noticeable, name, extra) {\n var _this = this;\n if (name === void 0) { name = undefined; }\n if (extra === void 0) { extra = undefined; }\n var preConditionError = null;\n var notice = this.makeNotice(noticeable, name, extra);\n if (!notice) {\n this.logger.debug('failed to build error report');\n preConditionError = new Error('failed to build error report');\n }\n if (!preConditionError && this.config.reportData === false) {\n this.logger.debug('skipping error report: honeybadger.js is disabled', notice);\n preConditionError = new Error('honeybadger.js is disabled');\n }\n if (!preConditionError && this.__developmentMode()) {\n this.logger.log('honeybadger.js is in development mode; the following error report will be sent in production.', notice);\n preConditionError = new Error('honeybadger.js is in development mode');\n }\n if (!preConditionError && !this.config.apiKey) {\n this.logger.warn('could not send error report: no API key has been configured', notice);\n preConditionError = new Error('missing API key');\n }\n // we need to have the source file data before the beforeNotifyHandlers,\n // in case they modify them\n var sourceCodeData = notice && notice.backtrace ? notice.backtrace.map(function (trace) { return (0, util_1.shallowClone)(trace); }) : null;\n var beforeNotifyResult = (0, util_1.runBeforeNotifyHandlers)(notice, this.__beforeNotifyHandlers);\n if (!preConditionError && !beforeNotifyResult) {\n this.logger.debug('skipping error report: beforeNotify handlers returned false', notice);\n preConditionError = new Error('beforeNotify handlers returned false');\n }\n if (preConditionError) {\n (0, util_1.runAfterNotifyHandlers)(notice, this.__afterNotifyHandlers, preConditionError);\n return false;\n }\n this.addBreadcrumb('Honeybadger Notice', {\n category: 'notice',\n metadata: {\n message: notice.message,\n name: notice.name,\n stack: notice.stack\n }\n });\n var breadcrumbs = this.__store.getContents('breadcrumbs');\n notice.__breadcrumbs = this.config.breadcrumbsEnabled ? breadcrumbs : [];\n (0, util_1.getSourceForBacktrace)(sourceCodeData, this.__getSourceFileHandler)\n .then(function (sourcePerTrace) {\n sourcePerTrace.forEach(function (source, index) {\n notice.backtrace[index].source = source;\n });\n var payload = _this.__buildPayload(notice);\n _this.__transport\n .send({\n headers: {\n 'X-API-Key': _this.config.apiKey,\n 'Content-Type': 'application/json',\n 'Accept': 'text/json, application/json'\n },\n method: 'POST',\n endpoint: (0, util_1.endpoint)(_this.config.endpoint, '/v1/notices/js'),\n maxObjectDepth: _this.config.maxObjectDepth,\n logger: _this.logger,\n async: (0, util_1.isBrowserConfig)(_this.config) ? _this.config.async : undefined,\n }, payload)\n .then(function (res) {\n if (res.statusCode !== 201) {\n (0, util_1.runAfterNotifyHandlers)(notice, _this.__afterNotifyHandlers, new Error(\"Bad HTTP response: \".concat(res.statusCode)));\n _this.logger.warn(\"Error report failed: unknown response from server. code=\".concat(res.statusCode));\n return;\n }\n var uuid = JSON.parse(res.body).id;\n (0, util_1.runAfterNotifyHandlers)((0, util_1.merge)(notice, {\n id: uuid\n }), _this.__afterNotifyHandlers);\n _this.logger.info(\"Error report sent \\u26A1 https://app.honeybadger.io/notice/\".concat(uuid));\n })\n .catch(function (err) {\n _this.logger.error('Error report failed: an unknown error occurred.', \"message=\".concat(err.message));\n (0, util_1.runAfterNotifyHandlers)(notice, _this.__afterNotifyHandlers, err);\n });\n });\n return true;\n };\n /**\n * An async version of {@link notify} that resolves only after the notice has been reported to Honeybadger.\n * Implemented using the {@link afterNotify} hook.\n * Rejects if for any reason the report failed to be reported.\n * Useful in serverless environments (AWS Lambda).\n */\n Client.prototype.notifyAsync = function (noticeable, name, extra) {\n var _this = this;\n if (name === void 0) { name = undefined; }\n if (extra === void 0) { extra = undefined; }\n return new Promise(function (resolve, reject) {\n var applyAfterNotify = function (partialNotice) {\n var originalAfterNotify = partialNotice.afterNotify;\n partialNotice.afterNotify = function (err) {\n originalAfterNotify === null || originalAfterNotify === void 0 ? void 0 : originalAfterNotify.call(_this, err);\n if (err) {\n return reject(err);\n }\n resolve();\n };\n };\n // We have to respect any afterNotify hooks that come from the arguments\n var objectToOverride;\n if (noticeable.afterNotify) {\n objectToOverride = noticeable;\n }\n else if (name && name.afterNotify) {\n objectToOverride = name;\n }\n else if (extra && extra.afterNotify) {\n objectToOverride = extra;\n }\n else if (name && typeof name === 'object') {\n objectToOverride = name;\n }\n else if (extra) {\n objectToOverride = extra;\n }\n else {\n objectToOverride = name = {};\n }\n applyAfterNotify(objectToOverride);\n _this.notify(noticeable, name, extra);\n });\n };\n Client.prototype.makeNotice = function (noticeable, name, extra) {\n if (name === void 0) { name = undefined; }\n if (extra === void 0) { extra = undefined; }\n var notice = (0, util_1.makeNotice)(noticeable);\n if (name && !(typeof name === 'object')) {\n var n = String(name);\n name = { name: n };\n }\n if (name) {\n notice = (0, util_1.mergeNotice)(notice, name);\n }\n if (typeof extra === 'object' && extra !== null) {\n notice = (0, util_1.mergeNotice)(notice, extra);\n }\n if ((0, util_1.objectIsEmpty)(notice)) {\n return null;\n }\n var context = this.__store.getContents('context');\n var noticeTags = this.__constructTags(notice.tags);\n var contextTags = this.__constructTags(context['tags']);\n var configTags = this.__constructTags(this.config.tags);\n // Turning into a Set will remove duplicates\n var tags = noticeTags.concat(contextTags).concat(configTags);\n var uniqueTags = tags.filter(function (item, index) { return tags.indexOf(item) === index; });\n notice = (0, util_1.merge)(notice, {\n name: notice.name || 'Error',\n context: (0, util_1.merge)(context, notice.context),\n projectRoot: notice.projectRoot || this.config.projectRoot,\n environment: notice.environment || this.config.environment,\n component: notice.component || this.config.component,\n action: notice.action || this.config.action,\n revision: notice.revision || this.config.revision,\n tags: uniqueTags,\n });\n var backtraceShift = 0;\n if (typeof notice.stack !== 'string' || !notice.stack.trim()) {\n notice.stack = (0, util_1.generateStackTrace)();\n backtraceShift = 2;\n }\n notice.backtrace = (0, util_1.makeBacktrace)(notice.stack, backtraceShift);\n return notice;\n };\n Client.prototype.addBreadcrumb = function (message, opts) {\n if (!this.config.breadcrumbsEnabled) {\n return;\n }\n opts = opts || {};\n var metadata = (0, util_1.shallowClone)(opts.metadata);\n var category = opts.category || 'custom';\n var timestamp = new Date().toISOString();\n this.__store.addBreadcrumb({\n category: category,\n message: message,\n metadata: metadata,\n timestamp: timestamp\n });\n return this;\n };\n Client.prototype.__getBreadcrumbs = function () {\n return this.__store.getContents('breadcrumbs').slice();\n };\n Client.prototype.__getContext = function () {\n return this.__store.getContents('context');\n };\n Client.prototype.__developmentMode = function () {\n if (this.config.reportData === true) {\n return false;\n }\n return (this.config.environment && this.config.developmentEnvironments.includes(this.config.environment));\n };\n Client.prototype.__buildPayload = function (notice) {\n var headers = (0, util_1.filter)(notice.headers, this.config.filters) || {};\n var cgiData = (0, util_1.filter)(__assign(__assign({}, notice.cgiData), (0, util_1.formatCGIData)(headers, 'HTTP_')), this.config.filters);\n return {\n notifier: notifier,\n breadcrumbs: {\n enabled: !!this.config.breadcrumbsEnabled,\n trail: notice.__breadcrumbs || []\n },\n error: {\n class: notice.name,\n message: notice.message,\n backtrace: notice.backtrace,\n fingerprint: notice.fingerprint,\n tags: notice.tags,\n causes: (0, util_1.getCauses)(notice),\n },\n request: {\n url: (0, util_1.filterUrl)(notice.url, this.config.filters),\n component: notice.component,\n action: notice.action,\n context: notice.context,\n cgi_data: cgiData,\n params: (0, util_1.filter)(notice.params, this.config.filters) || {},\n session: (0, util_1.filter)(notice.session, this.config.filters) || {}\n },\n server: {\n project_root: notice.projectRoot,\n environment_name: notice.environment,\n revision: notice.revision,\n hostname: this.config.hostname,\n time: new Date().toUTCString()\n },\n details: notice.details || {}\n };\n };\n Client.prototype.__constructTags = function (tags) {\n if (!tags) {\n return [];\n }\n return tags.toString().split(TAG_SEPARATOR).filter(function (tag) { return NOT_BLANK.test(tag); });\n };\n return Client;\n}());\nexports.Client = Client;\n//# sourceMappingURL=client.js.map", "\"use strict\";\nObject.defineProperty(exports, \"__esModule\", { value: true });\n//# sourceMappingURL=types.js.map", "\"use strict\";\nvar __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {\n if (k2 === undefined) k2 = k;\n var desc = Object.getOwnPropertyDescriptor(m, k);\n if (!desc || (\"get\" in desc ? !m.__esModule : desc.writable || desc.configurable)) {\n desc = { enumerable: true, get: function() { return m[k]; } };\n }\n Object.defineProperty(o, k2, desc);\n}) : (function(o, m, k, k2) {\n if (k2 === undefined) k2 = k;\n o[k2] = m[k];\n}));\nvar __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {\n Object.defineProperty(o, \"default\", { enumerable: true, value: v });\n}) : function(o, v) {\n o[\"default\"] = v;\n});\nvar __exportStar = (this && this.__exportStar) || function(m, exports) {\n for (var p in m) if (p !== \"default\" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);\n};\nvar __importStar = (this && this.__importStar) || function (mod) {\n if (mod && mod.__esModule) return mod;\n var result = {};\n if (mod != null) for (var k in mod) if (k !== \"default\" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);\n __setModuleDefault(result, mod);\n return result;\n};\nObject.defineProperty(exports, \"__esModule\", { value: true });\nexports.Util = exports.Types = exports.Client = void 0;\nvar client_1 = require(\"./client\");\nObject.defineProperty(exports, \"Client\", { enumerable: true, get: function () { return client_1.Client; } });\n__exportStar(require(\"./store\"), exports);\nexports.Types = __importStar(require(\"./types\"));\nexports.Util = __importStar(require(\"./util\"));\n//# sourceMappingURL=index.js.map", "\"use strict\";\nObject.defineProperty(exports, \"__esModule\", { value: true });\nexports.preferCatch = exports.encodeCookie = exports.decodeCookie = exports.localURLPathname = exports.parseURL = exports.nativeFetch = exports.stringTextOfElement = exports.stringSelectorOfElement = exports.stringNameOfElement = void 0;\n/**\n * Converts an HTMLElement into a human-readable string.\n * @param {!HTMLElement} element\n * @return {string}\n */\nfunction stringNameOfElement(element) {\n if (!element || !element.tagName) {\n return '';\n }\n var name = element.tagName.toLowerCase();\n // Ignore the root element in selectors and events.\n if (name === 'html') {\n return '';\n }\n if (element.id) {\n name += \"#\".concat(element.id);\n }\n var stringClassNames = element.getAttribute('class');\n if (stringClassNames) {\n stringClassNames.split(/\\s+/).forEach(function (className) {\n name += \".\".concat(className);\n });\n }\n ['alt', 'name', 'title', 'type'].forEach(function (attrName) {\n var attr = element.getAttribute(attrName);\n if (attr) {\n name += \"[\".concat(attrName, \"=\\\"\").concat(attr, \"\\\"]\");\n }\n });\n var siblings = getSiblings(element);\n if (siblings.length > 1) {\n name += \":nth-child(\".concat(Array.prototype.indexOf.call(siblings, element) + 1, \")\");\n }\n return name;\n}\nexports.stringNameOfElement = stringNameOfElement;\nfunction stringSelectorOfElement(element) {\n var name = stringNameOfElement(element);\n if (element.parentNode && element.parentNode.tagName) {\n var parentName = stringSelectorOfElement(element.parentNode);\n if (parentName.length > 0) {\n return \"\".concat(parentName, \" > \").concat(name);\n }\n }\n return name;\n}\nexports.stringSelectorOfElement = stringSelectorOfElement;\nfunction stringTextOfElement(element) {\n var text = element.textContent || element.innerText || '';\n if (!text && (element.type === 'submit' || element.type === 'button')) {\n text = element.value;\n }\n return truncate(text.trim(), 300);\n}\nexports.stringTextOfElement = stringTextOfElement;\nfunction nativeFetch() {\n if (!window.fetch) {\n return false;\n }\n if (isNative(window.fetch)) {\n return true;\n }\n // If fetch isn't native, it may be wrapped by someone else. Try to get\n // a pristine function from an iframe.\n try {\n var sandbox = document.createElement('iframe');\n sandbox.style.display = 'none';\n document.head.appendChild(sandbox);\n var result = sandbox.contentWindow.fetch && isNative(sandbox.contentWindow.fetch);\n document.head.removeChild(sandbox);\n return result;\n }\n catch (err) {\n if (console && console.warn) {\n console.warn('failed to detect native fetch via iframe: ' + err);\n }\n }\n return false;\n}\nexports.nativeFetch = nativeFetch;\nfunction isNative(func) {\n return func.toString().indexOf('native') !== -1;\n}\nfunction parseURL(url) {\n // Regexp: https://tools.ietf.org/html/rfc3986#appendix-B\n var match = url.match(/^(([^:/?#]+):)?(\\/\\/([^/?#]*))?([^?#]*)(\\?([^#]*))?(#(.*))?$/) || {};\n return {\n protocol: match[2],\n host: match[4],\n pathname: match[5]\n };\n}\nexports.parseURL = parseURL;\nfunction localURLPathname(url) {\n var parsed = parseURL(url);\n var parsedDocURL = parseURL(document.URL);\n // URL must be relative\n if (!parsed.host || !parsed.protocol) {\n return parsed.pathname;\n }\n // Same domain\n if (parsed.protocol === parsedDocURL.protocol && parsed.host === parsedDocURL.host) {\n return parsed.pathname;\n }\n // x-domain\n return \"\".concat(parsed.protocol, \"://\").concat(parsed.host).concat(parsed.pathname);\n}\nexports.localURLPathname = localURLPathname;\nfunction decodeCookie(string) {\n var result = {};\n string.split(/[;,]\\s?/).forEach(function (pair) {\n var _a = pair.split('=', 2), key = _a[0], value = _a[1];\n result[key] = value;\n });\n return result;\n}\nexports.decodeCookie = decodeCookie;\nfunction encodeCookie(object) {\n if (typeof object !== 'object') {\n return undefined;\n }\n var cookies = [];\n for (var k in object) {\n cookies.push(k + '=' + object[k]);\n }\n return cookies.join(';');\n}\nexports.encodeCookie = encodeCookie;\n// Helpers\nfunction getSiblings(element) {\n try {\n var nodes = element.parentNode.childNodes;\n var siblings_1 = [];\n Array.prototype.forEach.call(nodes, function (node) {\n if (node.tagName && node.tagName === element.tagName) {\n siblings_1.push(node);\n }\n });\n return siblings_1;\n }\n catch (e) {\n return [];\n }\n}\nfunction truncate(string, length) {\n if (string.length > length) {\n string = string.substr(0, length) + '...';\n }\n return string;\n}\n// Used to decide which error handling method to use when wrapping async\n// handlers: try/catch, or `window.onerror`. When available, `window.onerror`\n// will provide more information in modern browsers.\nexports.preferCatch = (function () {\n var preferCatch = true;\n // IE < 10\n if (!window.atob) {\n preferCatch = false;\n }\n // Modern browsers support the full ErrorEvent API\n // See https://developer.mozilla.org/en-US/docs/Web/API/ErrorEvent\n if (window.ErrorEvent) {\n try {\n if ((new window.ErrorEvent('')).colno === 0) {\n preferCatch = false;\n }\n // eslint-disable-next-line no-empty\n }\n catch (_e) { }\n }\n return preferCatch;\n})();\n//# sourceMappingURL=util.js.map", "\"use strict\";\nObject.defineProperty(exports, \"__esModule\", { value: true });\nexports.onError = exports.ignoreNextOnError = void 0;\n/* eslint-disable prefer-rest-params */\nvar core_1 = require(\"@honeybadger-io/core\");\nvar instrument = core_1.Util.instrument, makeNotice = core_1.Util.makeNotice;\nvar ignoreOnError = 0;\nvar currentTimeout;\nfunction ignoreNextOnError() {\n ignoreOnError += 1;\n clearTimeout(currentTimeout);\n currentTimeout = setTimeout(function () {\n ignoreOnError = 0;\n });\n}\nexports.ignoreNextOnError = ignoreNextOnError;\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nfunction onError(_window) {\n if (_window === void 0) { _window = window; }\n return {\n load: function (client) {\n instrument(_window, 'onerror', function (original) {\n var onerror = function (msg, url, line, col, err) {\n client.logger.debug('window.onerror callback invoked', arguments);\n if (ignoreOnError > 0) {\n client.logger.debug('Ignoring window.onerror (error likely reported earlier)', arguments);\n ignoreOnError -= 1;\n return;\n }\n // See https://developer.mozilla.org/en/docs/Web/API/GlobalEventHandlers/onerror#Notes\n if (line === 0 && /Script error\\.?/.test(msg)) {\n if (client.config.enableUncaught) {\n // Log only if the user wants to report uncaught errors\n client.logger.warn('Ignoring cross-domain script error: enable CORS to track these types of errors', arguments);\n }\n return;\n }\n var notice = makeNotice(err);\n if (!notice.name) {\n notice.name = 'window.onerror';\n }\n if (!notice.message) {\n notice.message = msg;\n }\n if (!notice.stack) {\n // Simulate v8 stack\n notice.stack = [notice.message, '\\n at ? (', url || 'unknown', ':', line || 0, ':', col || 0, ')'].join('');\n }\n client.addBreadcrumb((notice.name === 'window.onerror' || !notice.name) ? 'window.onerror' : \"window.onerror: \".concat(notice.name), {\n category: 'error',\n metadata: {\n name: notice.name,\n message: notice.message,\n stack: notice.stack\n }\n });\n if (client.config.enableUncaught) {\n client.notify(notice);\n }\n };\n return function (msg, url, line, col, err) {\n onerror(msg, url, line, col, err);\n if (typeof original === 'function') {\n return original.apply(window, arguments);\n }\n return false;\n };\n });\n }\n };\n}\nexports.onError = onError;\n//# sourceMappingURL=onerror.js.map", "\"use strict\";\nObject.defineProperty(exports, \"__esModule\", { value: true });\n/* eslint-disable prefer-rest-params */\nvar core_1 = require(\"@honeybadger-io/core\");\nvar instrument = core_1.Util.instrument;\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nfunction default_1(_window) {\n if (_window === void 0) { _window = window; }\n return {\n load: function (client) {\n if (!client.config.enableUnhandledRejection) {\n return;\n }\n instrument(_window, 'onunhandledrejection', function (original) {\n // See https://developer.mozilla.org/en-US/docs/Web/API/Window/unhandledrejection_event\n function onunhandledrejection(promiseRejectionEvent) {\n var _a;\n client.logger.debug('window.onunhandledrejection callback invoked', arguments);\n if (!client.config.enableUnhandledRejection) {\n return;\n }\n var reason = promiseRejectionEvent.reason;\n if (reason instanceof Error) {\n // simulate v8 stack\n // const fileName = reason.fileName || 'unknown'\n // const lineNumber = reason.lineNumber || 0\n var fileName = 'unknown';\n var lineNumber = 0;\n var stackFallback = \"\".concat(reason.message, \"\\n at ? (\").concat(fileName, \":\").concat(lineNumber, \")\");\n var stack = reason.stack || stackFallback;\n var err = {\n name: reason.name,\n message: \"UnhandledPromiseRejectionWarning: \".concat(reason),\n stack: stack\n };\n client.addBreadcrumb(\"window.onunhandledrejection: \".concat(err.name), {\n category: 'error',\n metadata: err\n });\n client.notify(err);\n return;\n }\n var message = typeof reason === 'string' ? reason : ((_a = JSON.stringify(reason)) !== null && _a !== void 0 ? _a : 'Unspecified reason');\n client.notify({\n name: 'window.onunhandledrejection',\n message: \"UnhandledPromiseRejectionWarning: \".concat(message)\n });\n }\n return function (promiseRejectionEvent) {\n onunhandledrejection(promiseRejectionEvent);\n if (typeof original === 'function') {\n original.apply(this, arguments);\n }\n };\n });\n }\n };\n}\nexports.default = default_1;\n//# sourceMappingURL=onunhandledrejection.js.map", "\"use strict\";\nObject.defineProperty(exports, \"__esModule\", { value: true });\n/* eslint-disable prefer-rest-params */\nvar core_1 = require(\"@honeybadger-io/core\");\nvar util_1 = require(\"../util\");\nvar sanitize = core_1.Util.sanitize, instrument = core_1.Util.instrument;\nfunction default_1(_window) {\n if (_window === void 0) { _window = window; }\n return {\n load: function (client) {\n function breadcrumbsEnabled(type) {\n if (client.config.breadcrumbsEnabled === true) {\n return true;\n }\n if (type) {\n return client.config.breadcrumbsEnabled[type] === true;\n }\n return client.config.breadcrumbsEnabled !== false;\n }\n // Breadcrumbs: instrument console\n (function () {\n if (!breadcrumbsEnabled('console')) {\n return;\n }\n function inspectArray(obj) {\n if (!Array.isArray(obj)) {\n return '';\n }\n return obj.map(function (value) {\n try {\n return String(value);\n }\n catch (e) {\n return '[unknown]';\n }\n }).join(' ');\n }\n ['debug', 'info', 'warn', 'error', 'log'].forEach(function (level) {\n instrument(_window.console, level, function (original) {\n return function () {\n var args = Array.prototype.slice.call(arguments);\n var message = inspectArray(args);\n var opts = {\n category: 'log',\n metadata: {\n level: level,\n arguments: sanitize(args, 3)\n }\n };\n client.addBreadcrumb(message, opts);\n if (typeof original === 'function') {\n Function.prototype.apply.call(original, _window.console, arguments);\n }\n };\n });\n });\n })();\n // Breadcrumbs: instrument click events\n (function () {\n if (!breadcrumbsEnabled('dom')) {\n return;\n }\n _window.addEventListener('click', function (event) {\n var message, selector, text;\n try {\n message = (0, util_1.stringNameOfElement)(event.target);\n selector = (0, util_1.stringSelectorOfElement)(event.target);\n text = (0, util_1.stringTextOfElement)(event.target);\n }\n catch (e) {\n message = 'UI Click';\n selector = '[unknown]';\n text = '[unknown]';\n }\n // There's nothing to display\n if (message.length === 0) {\n return;\n }\n client.addBreadcrumb(message, {\n category: 'ui.click',\n metadata: {\n selector: selector,\n text: text,\n event: event\n }\n });\n }, true);\n })();\n // Breadcrumbs: instrument XMLHttpRequest\n (function () {\n if (!breadcrumbsEnabled('network')) {\n return;\n }\n // -- On xhr.open: capture initial metadata\n instrument(XMLHttpRequest.prototype, 'open', function (original) {\n return function () {\n // eslint-disable-next-line @typescript-eslint/no-this-alias\n var xhr = this;\n var url = arguments[1];\n var method = typeof arguments[0] === 'string' ? arguments[0].toUpperCase() : arguments[0];\n var message = \"\".concat(method, \" \").concat((0, util_1.localURLPathname)(url));\n this.__hb_xhr = {\n type: 'xhr',\n method: method,\n url: url,\n message: message\n };\n if (typeof original === 'function') {\n original.apply(xhr, arguments);\n }\n };\n });\n // -- On xhr.send: set up xhr.onreadystatechange to report breadcrumb\n instrument(XMLHttpRequest.prototype, 'send', function (original) {\n return function () {\n // eslint-disable-next-line @typescript-eslint/no-this-alias\n var xhr = this;\n function onreadystatechangeHandler() {\n if (xhr.readyState === 4) {\n var message = void 0;\n if (xhr.__hb_xhr) {\n xhr.__hb_xhr.status_code = xhr.status;\n message = xhr.__hb_xhr.message;\n delete xhr.__hb_xhr.message;\n }\n client.addBreadcrumb(message || 'XMLHttpRequest', {\n category: 'request',\n metadata: xhr.__hb_xhr\n });\n }\n }\n if ('onreadystatechange' in xhr && typeof xhr.onreadystatechange === 'function') {\n instrument(xhr, 'onreadystatechange', function (original) {\n return function () {\n onreadystatechangeHandler();\n if (typeof original === 'function') {\n // eslint-disable-next-line prefer-rest-params\n original.apply(this, arguments);\n }\n };\n });\n }\n else {\n xhr.onreadystatechange = onreadystatechangeHandler;\n }\n if (typeof original === 'function') {\n // eslint-disable-next-line prefer-rest-params\n original.apply(xhr, arguments);\n }\n };\n });\n })();\n // Breadcrumbs: instrument fetch\n (function () {\n if (!breadcrumbsEnabled('network')) {\n return;\n }\n if (!(0, util_1.nativeFetch)()) {\n // Polyfills use XHR.\n return;\n }\n instrument(_window, 'fetch', function (original) {\n return function () {\n // eslint-disable-next-line prefer-rest-params\n var input = arguments[0];\n var method = 'GET';\n var url;\n if (typeof input === 'string') {\n url = input;\n }\n else if ('Request' in _window && input instanceof Request) {\n url = input.url;\n if (input.method) {\n method = input.method;\n }\n }\n else {\n url = String(input);\n }\n if (arguments[1] && arguments[1].method) {\n method = arguments[1].method;\n }\n if (typeof method === 'string') {\n method = method.toUpperCase();\n }\n var message = \"\".concat(method, \" \").concat((0, util_1.localURLPathname)(url));\n var metadata = {\n type: 'fetch',\n method: method,\n url: url\n };\n return original\n .apply(this, arguments)\n .then(function (response) {\n metadata['status_code'] = response.status;\n client.addBreadcrumb(message, {\n category: 'request',\n metadata: metadata\n });\n return response;\n })\n .catch(function (error) {\n client.addBreadcrumb('fetch error', {\n category: 'error',\n metadata: metadata\n });\n throw error;\n });\n };\n });\n })();\n // Breadcrumbs: instrument navigation\n (function () {\n if (!breadcrumbsEnabled('navigation')) {\n return;\n }\n // The last known href of the current page\n var lastHref = _window.location.href;\n function recordUrlChange(from, to) {\n lastHref = to;\n client.addBreadcrumb('Page changed', {\n category: 'navigation',\n metadata: {\n from: from,\n to: to\n }\n });\n }\n // https://developer.mozilla.org/en-US/docs/Web/API/WindowEventHandlers/onpopstate\n instrument(_window, 'onpopstate', function (original) {\n return function () {\n recordUrlChange(lastHref, _window.location.href);\n if (original) {\n return original.apply(this, arguments);\n }\n };\n });\n // https://developer.mozilla.org/en-US/docs/Web/API/History/pushState\n // https://developer.mozilla.org/en-US/docs/Web/API/History/replaceState\n function historyWrapper(original) {\n return function () {\n var url = arguments.length > 2 ? arguments[2] : undefined;\n if (url) {\n recordUrlChange(lastHref, String(url));\n }\n return original.apply(this, arguments);\n };\n }\n instrument(_window.history, 'pushState', historyWrapper);\n instrument(_window.history, 'replaceState', historyWrapper);\n })();\n }\n };\n}\nexports.default = default_1;\n//# sourceMappingURL=breadcrumbs.js.map", "\"use strict\";\nObject.defineProperty(exports, \"__esModule\", { value: true });\n/* eslint-disable prefer-rest-params */\nvar core_1 = require(\"@honeybadger-io/core\");\nvar instrument = core_1.Util.instrument;\nfunction default_1(_window) {\n if (_window === void 0) { _window = window; }\n return {\n load: function (client) {\n // Wrap timers\n (function () {\n function instrumentTimer(wrapOpts) {\n return function (original) {\n // See https://developer.mozilla.org/en-US/docs/Web/API/WindowTimers/setTimeout\n return function (func, delay) {\n if (typeof func === 'function') {\n var args_1 = Array.prototype.slice.call(arguments, 2);\n func = client.__wrap(func, wrapOpts);\n return original(function () {\n func.apply(void 0, args_1);\n }, delay);\n }\n else {\n return original(func, delay);\n }\n };\n };\n }\n instrument(_window, 'setTimeout', instrumentTimer({ component: 'setTimeout' }));\n instrument(_window, 'setInterval', instrumentTimer({ component: 'setInterval' }));\n })();\n }\n };\n}\nexports.default = default_1;\n//# sourceMappingURL=timers.js.map", "\"use strict\";\nObject.defineProperty(exports, \"__esModule\", { value: true });\nvar core_1 = require(\"@honeybadger-io/core\");\nvar instrument = core_1.Util.instrument;\nfunction default_1(_window) {\n if (_window === void 0) { _window = window; }\n return {\n load: function (client) {\n // Wrap event listeners\n // Event targets borrowed from bugsnag-js:\n // See https://github.com/bugsnag/bugsnag-js/blob/d55af916a4d3c7757f979d887f9533fe1a04cc93/src/bugsnag.js#L542\n var targets = ['EventTarget', 'Window', 'Node', 'ApplicationCache', 'AudioTrackList', 'ChannelMergerNode', 'CryptoOperation', 'EventSource', 'FileReader', 'HTMLUnknownElement', 'IDBDatabase', 'IDBRequest', 'IDBTransaction', 'KeyOperation', 'MediaController', 'MessagePort', 'ModalWindow', 'Notification', 'SVGElementInstance', 'Screen', 'TextTrack', 'TextTrackCue', 'TextTrackList', 'WebSocket', 'WebSocketWorker', 'Worker', 'XMLHttpRequest', 'XMLHttpRequestEventTarget', 'XMLHttpRequestUpload'];\n targets.forEach(function (prop) {\n var prototype = _window[prop] && _window[prop].prototype;\n if (prototype && Object.prototype.hasOwnProperty.call(prototype, 'addEventListener')) {\n instrument(prototype, 'addEventListener', function (original) {\n var wrapOpts = { component: \"\".concat(prop, \".prototype.addEventListener\") };\n // See https://developer.mozilla.org/en-US/docs/Web/API/EventTarget/addEventListener\n return function (type, listener, useCapture, wantsUntrusted) {\n try {\n if (listener && listener.handleEvent != null) {\n listener.handleEvent = client.__wrap(listener.handleEvent, wrapOpts);\n }\n }\n catch (e) {\n // Ignore 'Permission denied to access property \"handleEvent\"' errors.\n client.logger.error(e);\n }\n return original.call(this, type, client.__wrap(listener, wrapOpts), useCapture, wantsUntrusted);\n };\n });\n instrument(prototype, 'removeEventListener', function (original) {\n return function (type, listener, useCapture, wantsUntrusted) {\n original.call(this, type, listener, useCapture, wantsUntrusted);\n return original.call(this, type, client.__wrap(listener), useCapture, wantsUntrusted);\n };\n });\n }\n });\n }\n };\n}\nexports.default = default_1;\n//# sourceMappingURL=event_listeners.js.map", "\"use strict\";\nObject.defineProperty(exports, \"__esModule\", { value: true });\nexports.BrowserTransport = void 0;\nvar core_1 = require(\"@honeybadger-io/core\");\nvar sanitize = core_1.Util.sanitize;\nvar BrowserTransport = /** @class */ (function () {\n function BrowserTransport() {\n }\n BrowserTransport.prototype.send = function (options, payload) {\n return new Promise(function (resolve, reject) {\n try {\n var x_1 = new XMLHttpRequest();\n x_1.open(options.method, options.endpoint, options.async);\n if (Object.keys(options.headers || []).length) {\n for (var i in options.headers) {\n if (typeof options.headers[i] !== 'undefined') {\n x_1.setRequestHeader(i, String(options.headers[i]));\n }\n }\n }\n x_1.send(payload ? JSON.stringify(sanitize(payload, options.maxObjectDepth)) : undefined);\n x_1.onload = function () { return resolve({ statusCode: x_1.status, body: x_1.response }); };\n }\n catch (err) {\n reject(err);\n }\n });\n };\n return BrowserTransport;\n}());\nexports.BrowserTransport = BrowserTransport;\n//# sourceMappingURL=transport.js.map", "\"use strict\";\nvar __extends = (this && this.__extends) || (function () {\n var extendStatics = function (d, b) {\n extendStatics = Object.setPrototypeOf ||\n ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||\n function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; };\n return extendStatics(d, b);\n };\n return function (d, b) {\n if (typeof b !== \"function\" && b !== null)\n throw new TypeError(\"Class extends value \" + String(b) + \" is not a constructor or null\");\n extendStatics(d, b);\n function __() { this.constructor = d; }\n d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());\n };\n})();\nvar __assign = (this && this.__assign) || function () {\n __assign = Object.assign || function(t) {\n for (var s, i = 1, n = arguments.length; i < n; i++) {\n s = arguments[i];\n for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))\n t[p] = s[p];\n }\n return t;\n };\n return __assign.apply(this, arguments);\n};\nvar __importDefault = (this && this.__importDefault) || function (mod) {\n return (mod && mod.__esModule) ? mod : { \"default\": mod };\n};\nObject.defineProperty(exports, \"__esModule\", { value: true });\nexports.Types = void 0;\nvar core_1 = require(\"@honeybadger-io/core\");\nvar util_1 = require(\"./browser/util\");\nvar onerror_1 = require(\"./browser/integrations/onerror\");\nvar onunhandledrejection_1 = __importDefault(require(\"./browser/integrations/onunhandledrejection\"));\nvar breadcrumbs_1 = __importDefault(require(\"./browser/integrations/breadcrumbs\"));\nvar timers_1 = __importDefault(require(\"./browser/integrations/timers\"));\nvar event_listeners_1 = __importDefault(require(\"./browser/integrations/event_listeners\"));\nvar transport_1 = require(\"./browser/transport\");\nvar merge = core_1.Util.merge, filter = core_1.Util.filter, objectIsExtensible = core_1.Util.objectIsExtensible;\nvar Honeybadger = /** @class */ (function (_super) {\n __extends(Honeybadger, _super);\n function Honeybadger(opts) {\n if (opts === void 0) { opts = {}; }\n var _this = _super.call(this, __assign({ async: true, maxErrors: null, projectRoot: window.location.protocol + '//' + window.location.host }, opts), new transport_1.BrowserTransport()) || this;\n /** @internal */\n _this.__errorsSent = 0;\n /** @internal */\n _this.__lastWrapErr = undefined;\n /** @internal */\n _this.__beforeNotifyHandlers = [\n function (notice) {\n if (_this.__exceedsMaxErrors()) {\n _this.logger.debug('Dropping notice: max errors exceeded', notice);\n return false;\n }\n if (notice && !notice.url) {\n notice.url = document.URL;\n }\n _this.__incrementErrorsCount();\n return true;\n }\n ];\n return _this;\n }\n Honeybadger.prototype.configure = function (opts) {\n if (opts === void 0) { opts = {}; }\n return _super.prototype.configure.call(this, opts);\n };\n Honeybadger.prototype.resetMaxErrors = function () {\n return (this.__errorsSent = 0);\n };\n Honeybadger.prototype.factory = function (opts) {\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n return new Honeybadger(opts);\n };\n Honeybadger.prototype.checkIn = function (_id) {\n throw new Error('Honeybadger.checkIn() is not supported on the browser');\n };\n /** @internal */\n Honeybadger.prototype.__buildPayload = function (notice) {\n var cgiData = {\n HTTP_USER_AGENT: undefined,\n HTTP_REFERER: undefined,\n HTTP_COOKIE: undefined\n };\n cgiData.HTTP_USER_AGENT = navigator.userAgent;\n if (document.referrer.match(/\\S/)) {\n cgiData.HTTP_REFERER = document.referrer;\n }\n var cookiesObject;\n if (typeof notice.cookies === 'string') {\n cookiesObject = (0, util_1.decodeCookie)(notice.cookies);\n }\n else {\n cookiesObject = notice.cookies;\n }\n if (cookiesObject) {\n cgiData.HTTP_COOKIE = (0, util_1.encodeCookie)(filter(cookiesObject, this.config.filters));\n }\n var payload = _super.prototype.__buildPayload.call(this, notice);\n payload.request.cgi_data = merge(cgiData, payload.request.cgi_data);\n return payload;\n };\n /**\n * wrap always returns the same function so that callbacks can be removed via\n * removeEventListener.\n * @internal\n */\n Honeybadger.prototype.__wrap = function (f, opts) {\n if (opts === void 0) { opts = {}; }\n var func = f;\n if (!opts) {\n opts = {};\n }\n try {\n if (typeof func !== 'function') {\n return func;\n }\n if (!objectIsExtensible(func)) {\n return func;\n }\n if (!func.___hb) {\n // eslint-disable-next-line @typescript-eslint/no-this-alias\n var client_1 = this;\n func.___hb = function () {\n if (util_1.preferCatch) {\n try {\n // eslint-disable-next-line prefer-rest-params\n return func.apply(this, arguments);\n }\n catch (err) {\n if (client_1.__lastWrapErr === err) {\n throw (err);\n }\n client_1.__lastWrapErr = err;\n (0, onerror_1.ignoreNextOnError)();\n client_1.addBreadcrumb(opts.component ? \"\".concat(opts.component, \": \").concat(err.name) : err.name, {\n category: 'error',\n metadata: {\n message: err.message,\n name: err.name,\n stack: err.stack\n }\n });\n if (client_1.config.enableUncaught) {\n client_1.notify(err);\n }\n throw (err);\n }\n }\n else {\n // eslint-disable-next-line prefer-rest-params\n return func.apply(this, arguments);\n }\n };\n }\n func.___hb.___hb = func.___hb;\n return func.___hb;\n }\n catch (_e) {\n return func;\n }\n };\n /** @internal */\n Honeybadger.prototype.__incrementErrorsCount = function () {\n return this.__errorsSent++;\n };\n /** @internal */\n Honeybadger.prototype.__exceedsMaxErrors = function () {\n return this.config.maxErrors && this.__errorsSent >= this.config.maxErrors;\n };\n return Honeybadger;\n}(core_1.Client));\nvar core_2 = require(\"@honeybadger-io/core\");\nObject.defineProperty(exports, \"Types\", { enumerable: true, get: function () { return core_2.Types; } });\nexports.default = new Honeybadger({\n __plugins: [\n (0, onerror_1.onError)(),\n (0, onunhandledrejection_1.default)(),\n (0, timers_1.default)(),\n (0, event_listeners_1.default)(),\n (0, breadcrumbs_1.default)()\n ]\n});\n//# sourceMappingURL=browser.js.map", "// Generated by bin/generate.sh\n//\n// This file pulls from environment variables (and git).\n\nexport default {\n \"CDN\": \"https://multipay.komoju.com\",\n \"ENV\": \"development\",\n \"HONEYBADGER_API_KEY\": \"\",\n \"GIT_REV\": \"99ad2eb29ce6530dedfe3a0ec34aea970dbaa78a\",\n};\n", "import '../../types.d';\n\nimport env from '../../generated/env';\nconst Honeybadger = require('@honeybadger-io/js');\n\ndeclare let window: WindowWithKomojuGlobals;\nlet initialized = false;\n\n// This module wraps Honeybadger since that's what we happen to use.\n// If we switch to a different service, all we have to do is change this module.\nexport const reportError: ErrorReportFunction = (error, context) => {\n if (window.komojuErrorReporting === false) return;\n if (!initialized) initialize();\n console.error(error, context);\n Honeybadger.setContext(context);\n Honeybadger.notify(error);\n};\n\nfunction initialize() {\n Honeybadger.configure({\n apiKey: env.HONEYBADGER_API_KEY,\n environment: env.ENV,\n revision: env.GIT_REV,\n filters: ['number', 'cvc', 'verification_value'],\n // We don't want to receive reports for every error in every website...\n enableUncaught: false,\n });\n initialized = true;\n}\n"], + "mappings": "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", + "names": ["isNative", "this", "util", "sanitize", "obj", "client", "makeNotice", "instrument", "endpoint", "filter", "util_1", "require$$0", "GlobalStore", "require$$1", "Client", "transport", "breadcrumbs", "__createBinding", "__setModuleDefault", "exports", "__importStar", "require$$2", "require$$3", "core_1", "onerror", "default_1", "onunhandledrejection", "original", "BrowserTransport", "d", "b", "__assign", "require$$4", "require$$5", "require$$6", "require$$7", "merge", "objectIsExtensible", "Honeybadger"] +} diff --git a/src/app/code/Komoju/Payments/view/frontend/web/js/fields-iframe.html b/src/app/code/Komoju/Payments/view/frontend/web/js/fields-iframe.html new file mode 100644 index 000000000..ac4c3e507 --- /dev/null +++ b/src/app/code/Komoju/Payments/view/frontend/web/js/fields-iframe.html @@ -0,0 +1,14 @@ + + + + + + KOMOJU Fields + + + + + + + + diff --git a/src/app/code/Komoju/Payments/view/frontend/web/js/fields-iframe.js b/src/app/code/Komoju/Payments/view/frontend/web/js/fields-iframe.js new file mode 100644 index 000000000..aaf27a342 --- /dev/null +++ b/src/app/code/Komoju/Payments/view/frontend/web/js/fields-iframe.js @@ -0,0 +1,879 @@ +var __defProp = Object.defineProperty; +var __export = (target, all) => { + for (var name in all) + __defProp(target, name, { get: all[name], enumerable: true }); +}; + +// src/shared/spinner.html +var spinner_default = "\n\n
    \n
  • \n
  • \n
  • \n
\n"; + +// src/shared/validation.ts +function runValidation(input) { + input.dispatchEvent(new CustomEvent("validate")); + const errorMessage = input.parentElement?.querySelector("komoju-error:not(.removing)")?.textContent; + return errorMessage ?? null; +} + +// src/shared/komoju-i18n-element.ts +var defaultLanguage = "en"; +function broadcastLocaleChange(root, locale) { + root.querySelectorAll("komoju-i18n").forEach((element) => { + const i18n = element; + i18n.render(locale); + }); +} +var KomojuI18nElement = class extends HTMLElement { + static get observedAttributes() { + return ["key"]; + } + get key() { + return this.getAttribute("key"); + } + set key(value) { + this.setAttribute("key", value ?? ""); + } + connectedCallback() { + this.render(); + } + attributeChangedCallback(name, _oldValue, _newValue) { + if (name === "key") + this.render(); + } + findLocale() { + let parent = this.parentElement; + while (parent && !parent.getAttribute("locale")) { + parent = parent.parentElement; + } + return parent?.getAttribute("locale") ?? defaultLanguage; + } + render(locale) { + if (!this.key) + return; + if (!locale) + locale = this.findLocale(); + if (!Object.keys(window.komojuTranslations).includes(locale)) + locale = defaultLanguage; + const lang = locale.substring(0, 2); + const message = window.komojuTranslations[lang][this.key]; + if (!message) { + console.error(`KOMOJU bug: missing translation for key: ${this.key}`); + return; + } + const matches = message.match(/%\{[\w-]+\}/g); + if (matches) { + let result = message; + matches.forEach((match) => { + const key = match.replace(/%{|}/g, ""); + const value = this.dataset[key]; + if (value) + result = result.replace(match, value); + }); + this.textContent = result; + return; + } + this.textContent = message; + } +}; + +// src/shared/money.ts +var noDecimalCurrencies = [ + "BIF", + "CLP", + "DJF", + "GNF", + "JPY", + "KMF", + "KRW", + "MGA", + "PYG", + "RWF", + "UGX", + "VND", + "VUV", + "XAF", + "XOF", + "XPF" +]; +var nonISOCurrencies = [ + "USDC" +]; +var displayCurrencyCodeInsteadOfSymbol = [ + "CNY" +]; +function formatMoney(amountCents, currency, locale = "en") { + function nonISOFormat(currency2, amountCents2) { + if (!amountCents2) { + return ""; + } else if (nonISOCurrencies.includes(currency2) || !currency2) { + return `${amountCents2.toLocaleString()} ${currency2}`; + } else { + throw "invalid currency format"; + } + } + const amountDecimal = decentify(amountCents, currency); + if (nonISOCurrencies.includes(currency) || !currency) { + return nonISOFormat(currency, amountDecimal); + } else { + const numberFormat = new Intl.NumberFormat(`${locale}-JP`, { + style: "currency", + currency, + currencyDisplay: displayCurrencyCodeInsteadOfSymbol.includes(currency) ? "code" : "symbol" + }); + return numberFormat.format(amountDecimal); + } +} +function decentify(amountCents, currency) { + return noDecimalCurrencies.includes(currency) ? amountCents : amountCents / 100; +} + +// src/shared/komoju-api.ts +function komojuFetch(config, method, path, body) { + if (!config.komojuApi) + throw new Error("KOMOJU API URL is null"); + if (!config.publishableKey) + throw new Error("KOMOJU publishable-key not set"); + return fetch(`${config.komojuApi}${path}`, { + method, + headers: { + accept: "application/json", + "content-type": "application/json", + authorization: `Basic ${btoa(`${config.publishableKey}:`)}`, + "komoju-via": "fields" + }, + body: body ? JSON.stringify(body) : void 0 + }); +} + +// src/shared/themable.ts +var Themable = class extends HTMLElement { + get theme() { + return this.getAttribute("theme"); + } + set theme(value) { + this.setAttribute("theme", value ?? ""); + } + applyTheme() { + const root = this.shadowRoot ?? document; + if (this.theme === null) { + root.querySelectorAll("#theme,#inline-theme").forEach((el) => el.remove()); + } else if (this.theme.startsWith("http") || this.theme.startsWith("/") || this.theme.startsWith("data:")) { + this.applyExternalTheme(root, this.theme); + } else { + this.applyInlineTheme(root, this.theme); + } + } + applyInlineTheme(root, theme) { + root.querySelectorAll("#theme,#inline-theme").forEach((el) => el.remove()); + const style = document.createElement("style"); + style.id = "inline-theme"; + style.textContent = theme; + this.appendStyleTag(style); + } + applyExternalTheme(root, theme) { + root.querySelectorAll("#inline-theme").forEach((el) => el.remove()); + let link = root.querySelector("#theme"); + if (link) { + if (link.href !== this.theme) + link.href = theme; + } else { + link = document.createElement("link"); + link.id = "theme"; + link.rel = "stylesheet"; + link.href = theme; + this.appendStyleTag(link); + } + } + appendStyleTag(style) { + if (this.shadowRoot) { + this.shadowRoot.append(style); + } else { + document.head.append(style); + } + } +}; + +// src/generated/env.ts +var env_default = { + "CDN": "https://multipay.komoju.com", + "ENV": "development", + "HONEYBADGER_API_KEY": "", + "GIT_REV": "99ad2eb29ce6530dedfe3a0ec34aea970dbaa78a" +}; + +// src/generated/supported-payment-types.ts +var supported = /* @__PURE__ */ new Set(); +supported.add("bank_transfer"); +supported.add("credit_card"); +supported.add("konbini"); +supported.add("offsite"); +var supported_payment_types_default = supported; + +// src/shared/translations.ts +function registerMessages(messages) { + if (!window.komojuTranslations) { + window.komojuTranslations = { "en": {}, "ja": {} }; + } + for (const lang of Object.keys(window.komojuTranslations)) { + window.komojuTranslations[lang] = { + ...window.komojuTranslations[lang], + ...messages[lang] + }; + } +} + +// src/i18n.ts +var i18n_exports = {}; +__export(i18n_exports, { + en: () => en, + ja: () => ja +}); +var en = { + "customer-fee-will-be-charged": "A fee of %{fee} will be included.", + "dynamic-currency-notice": "Payment will be made in %{currency}: %{original} \u2192 %{converted}.", + "dynamic-currency-notice-with-fee": "Payment will be made in %{currency}: %{original} \u2192 %{converted}. (total: %{total})", + "payment-method-unavailable": "This payment method is currently unavailable.", + "verification-failed": "Verification failed.", + "close": "Close" +}; +var ja = { + "customer-fee-will-be-charged": "%{fee}\u306E\u624B\u6570\u6599\u304C\u8FFD\u52A0\u3055\u308C\u307E\u3059\u3002", + "dynamic-currency-notice": "\u652F\u6255\u3044\u306F%{currency}\u3067\u6C7A\u6E08\u3055\u308C\u307E\u3059: %{original} \u2192 %{converted}\u3002", + "dynamic-currency-notice-with-fee": "\u652F\u6255\u3044\u306F%{currency}\u3067\u6C7A\u6E08\u3055\u308C\u307E\u3059: %{original} \u2192 %{converted}\u3002(\u5408\u8A08%{total})", + "payment-method-unavailable": "\u3053\u306E\u652F\u6255\u3044\u65B9\u6CD5\u306F\u73FE\u5728\u3054\u5229\u7528\u3044\u305F\u3060\u3051\u307E\u305B\u3093\u3002", + "verification-failed": "\u8A8D\u8A3C\u306B\u5931\u6557\u3057\u307E\u3057\u305F\u3002", + "close": "\u9589\u3058\u308B" +}; + +// src/shared/message-broker.ts +var MessageBroker = class { + constructor(id) { + this._sendWindow = new Promise((resolve) => this._setSendWindow = resolve); + this._receiveWindow = new Promise((resolve) => this._setReceiveWindow = resolve); + this.messageHandler = (event) => { + if (this.origin !== "*" && event.origin !== this.origin) + return; + this.handleMessage(event); + }; + this.id = id ?? crypto.randomUUID(); + this.origin = "*"; + this.promises = /* @__PURE__ */ new Map(); + this.listeners = /* @__PURE__ */ new Map(); + } + setup(arg) { + if (this._setSendWindow) { + this._setSendWindow(arg.send); + this._setSendWindow = void 0; + } else { + this._sendWindow = Promise.resolve(arg.send); + } + if (this._setReceiveWindow) { + this._setReceiveWindow(arg.receive); + this._setReceiveWindow = void 0; + } else { + this._receiveWindow = Promise.resolve(arg.receive); + } + arg.receive.addEventListener("message", this.messageHandler); + } + send(message) { + const fullMessage = { + ...message, + brokerId: this.id, + id: crypto.randomUUID() + }; + let resolve = null; + const promise = new Promise((resolvePromise, _reject) => { + resolve = resolvePromise; + }); + if (!resolve) + throw new Error("Broker is busted"); + this.promises.set(fullMessage.id, { promise, resolve }); + return this._sendWindow.then((w) => w.postMessage(fullMessage, this.origin)).then(() => promise); + } + receive(type, listener) { + this.listeners.set(type, listener); + } + async handleMessage(event) { + const message = event.data; + if (message.brokerId !== this.id) + return; + if (message.type === "ack") { + const ack = message; + const promise = this.promises.get(ack.id); + if (!promise) + return; + promise.resolve(ack.response); + this.promises.delete(ack.id); + } else { + const listener = this.listeners.get(message.type); + const ack = { type: "ack", brokerId: this.id, id: message.id }; + if (listener) + ack.response = await listener(message) ?? void 0; + await this._sendWindow.then((w) => w.postMessage(ack, this.origin)); + } + } + destroy() { + return this._receiveWindow.then((w) => w.removeEventListener("message", this.messageHandler)); + } +}; + +// src/komoju-host-element.ts +registerMessages(i18n_exports); +var _baseKomojuAPI; +function baseKomojuAPI() { + if (_baseKomojuAPI) + return _baseKomojuAPI; + const url = new URL(window.location.href); + const params = new URLSearchParams(url.hash.slice(1)); + _baseKomojuAPI = params.get("api") ?? "https://komoju.com"; + return _baseKomojuAPI; +} +function brokerId() { + const url = new URL(window.location.href); + const params = new URLSearchParams(url.hash.slice(1)); + return params.get("broker") ?? void 0; +} +function i18nMessage(locale, key) { + if (locale === "ja") + return ja[key]; + return en[key]; +} +var KomojuHostElement = class extends Themable { + constructor() { + super(...arguments); + this._session = null; + this.module = null; + this.broker = new MessageBroker(brokerId()); + this._renderCount = 0; + this.komojuFetch = komojuFetch.bind(this, this); + } + static get observedAttributes() { + console.log("KomojuHostElement::listenToMessagesFromMainWindow"); + return [ + "komoju-api", + "session", + "session-id", + "publishable-key", + "payment-type", + "locale", + "theme", + "token", + "name" + ]; + } + get session() { + return this._session; + } + set session(value) { + console.log("KomojuHostElement set session", value); + this._session = value; + this.broker.send({ + type: "dispatch-event", + name: "komoju-session-change", + detail: { session: this._session } + }); + } + get komojuApi() { + const attribute = this.getAttribute("komoju-api"); + if (!attribute || attribute === "") + return baseKomojuAPI(); + else + return attribute; + } + set komojuApi(value) { + this.setAttribute("komoju-api", value ?? ""); + } + get sessionId() { + return this.getAttribute("session-id"); + } + set sessionId(value) { + this.setAttribute("session-id", value ?? ""); + } + get publishableKey() { + return this.getAttribute("publishable-key"); + } + set publishableKey(value) { + this.setAttribute("publishable-key", value ?? ""); + } + get paymentType() { + return this.getAttribute("payment-type"); + } + set paymentType(value) { + this.setAttribute("payment-type", value ?? ""); + } + get locale() { + return this.getAttribute("locale"); + } + set locale(value) { + this.setAttribute("locale", value ?? ""); + this.broker.send({ + type: "dispatch-event", + name: "komoju-locale-change", + detail: { locale: value } + }); + } + get token() { + return this.hasAttribute("token"); + } + set token(value) { + if (value) + this.setAttribute("token", ""); + else + this.removeAttribute("token"); + } + get name() { + return this.getAttribute("name"); + } + set name(value) { + if (value) + this.setAttribute("name", value); + else + this.removeAttribute("name"); + } + get komojuCdn() { + return env_default["CDN"]; + } + get paymentMethod() { + return this.session?.payment_methods.find((method) => method.type === this.paymentType); + } + async attributeChangedCallback(name, oldValue, newValue) { + console.log("??? KomojuHostElement attributeChangedCallback", name, oldValue); + console.log("###"); + console.log("NEW VALUE::KomojuHostElement attributeChangedCallback", name, newValue); + if (name === "session") { + if (!newValue || newValue == "") + return; + this.session = JSON.parse(newValue); + if (!this.locale) + this.locale = this.session.default_locale.substring(0, 2); + if (!this.paymentType) + this.paymentType = this.session.payment_methods[0].type; + this.render(); + } else if (name === "session-id" || name === "publishable-key") { + if (!newValue || newValue == "") + return; + if (!this.publishableKey) + return; + if (!this.sessionId) + return; + const response = await this.komojuFetch("GET", `/api/v1/sessions/${this.sessionId}`); + if (response.status === 404) { + console.error("Invalid KOMOJU session ID", this.sessionId); + return; + } + if (response.status !== 200) { + console.error("Failed to retrieve KOMOJU session", response); + return; + } + this.session = await response.json(); + if (!this.session) + throw new Error("KOMOJU returned a null session"); + if (!this.paymentType) + this.paymentType = this.session.payment_methods[0].type; + if (!this.locale) + this.locale = this.session.default_locale.substring(0, 2); + this.render(); + } else if (name === "payment-type") { + if (!newValue || newValue == "") + return; + if (!this.session) + return; + if (!this.publishableKey) + return; + this.startFade(); + await this.render(); + } else if (name === "locale") { + if (!newValue || newValue == "" || oldValue === newValue) + return; + broadcastLocaleChange(this, newValue); + } else if (name === "theme") { + this.applyTheme(); + } + } + connectedCallback() { + console.log("KomojuHostElement connectedCallback"); + this.innerHTML = spinner_default; + console.log(`${JSON.stringify(this.broker)}, broker`); + this.listenToMessagesFromMainWindow(this.broker); + this.broker.setup({ + send: window.parent, + receive: window + }); + const body = this.ownerDocument?.body; + this.resizeObserver = new ResizeObserver(() => { + const height = body.parentElement.offsetHeight; + if (height === 0) + return; + this.broker.send({ type: "resize", height: height.toString() }); + }); + if (body) + this.resizeObserver.observe(body, { box: "border-box" }); + } + disconnectedCallback() { + this.broker.destroy(); + this.resizeObserver?.disconnect(); + this.resizeObserver = void 0; + } + listenToMessagesFromMainWindow(broker) { + console.log("KomojuHostElement listenToMessagesFromMainWindow"); + broker.receive("attr", (message) => { + if (!KomojuHostElement.observedAttributes.includes(message.attr)) + return; + console.log("KomojuHostElement listenToMessagesFromMainWindow attr", message); + if (message.value === null || message.value === void 0) + this.removeAttribute(message.attr); + else + this.setAttribute(message.attr, message.value); + }); + broker.receive("submit", () => { + return this.submit(); + }); + broker.receive("end-fade", () => { + this.endFade(); + }); + } + async submit() { + if (!this.module || !this.session) { + return { type: "submit-result", errors: ["Attempted to submit before selecting KOMOJU Payment method"] }; + } + const paymentMethod = this.paymentMethod; + if (!paymentMethod) + throw new Error(`KOMOJU Payment method not found: ${this.paymentType}`); + this.querySelectorAll("komoju-error").forEach((error) => error.remove()); + const validatedFields = this.querySelectorAll(".has-validation"); + const errors = Array.prototype.map.call( + validatedFields, + (field) => field instanceof HTMLInputElement ? runValidation(field) : null + ); + if (errors.some((error) => error != null)) { + return { type: "submit-result", errors: errors.filter((error) => error != null) }; + } + this.startFade(); + const paymentDetails = this.module.paymentDetails(this, paymentMethod); + if (this.token) { + return await this.submitToken(paymentDetails); + } else { + return await this.submitPayment(paymentDetails); + } + } + async submitPayment(paymentDetails) { + const paymentMethod = this.paymentMethod; + if (!paymentMethod) { + throw new Error("Attempted to submit before selecting KOMOJU Payment method"); + } + const session = this.session; + let moduleName = paymentMethod.offsite ? "offsite" : paymentMethod.type; + if (!supported_payment_types_default.has(moduleName)) { + const result2 = { + type: "submit-result", + pay: { + status: "pending", + redirect_url: `${session.session_url}#${paymentMethod.type}` + } + }; + return result2; + } + let secureTokenId = null; + if (paymentMethod.type === "credit_card" && session.mode !== "customer") + try { + const { secureToken, error, skip } = await this.do3DS(paymentDetails); + if (secureToken) { + secureTokenId = secureToken.id; + } else if (error && !skip) { + return { + type: "submit-result", + errors: [error] + }; + } + } catch (e) { + console.error("Error during secure token flow. Continuing without.", e); + } + const payResponse = await this.komojuFetch("POST", `/api/v1/sessions/${session.id}/pay`, { + payment_details: secureTokenId ?? paymentDetails, + api_locale: this.locale + }); + const payResult = await payResponse.json(); + const result = { + type: "submit-result", + pay: payResult + }; + if (payResult.error) { + console.error(payResult); + this.handleApiError(payResult.error); + this.endFade(); + } + return result; + } + async do3DS(paymentDetails) { + const { secureToken, error } = await this.submitSecureToken(paymentDetails); + if (error && error.code === "unsupported_card_brand") { + return { + error, + skip: true + }; + } + if (error) + return { error }; + else if (!secureToken) + throw new Error("Secure token empty response"); + const status = secureToken.verification_status; + if (status === "OK" || status === "SKIPPED") { + return { secureToken }; + } + if (status === "ERRORED") { + return { + skip: true + }; + } + const dialogResult = await this.broker.send({ + type: "dialog-start", + url: secureToken.authentication_url + }); + if (dialogResult?.type !== "dialog-result") { + throw new Error("Expected dialog-result, got " + JSON.stringify(dialogResult)); + } else { + const { result } = dialogResult; + if (result.error && result.error.code === "unsupported_card_brand") { + return { + error: result.error, + skip: true + }; + } + if (result.error) { + this.handleApiError(result.error); + this.endFade(); + return result; + } + if (result.secureToken && result.secureToken.verification_status === "ERRORED") { + const error2 = i18nMessage(this.locale, "verification-failed") ?? "3DS error"; + this.handleApiError(error2); + this.endFade(); + return { + error: { + code: "verification_status_errored", + message: error2, + param: null, + details: null + } + }; + } + return result; + } + } + async submitSecureToken(paymentDetails) { + const session = this.session; + const returnURL = new URL(this.komojuCdn); + returnURL.pathname = "/secure-token-return.html"; + returnURL.searchParams.set("session_id", session.id); + const secureTokenResponse = await this.komojuFetch("POST", `/api/v1/secure_tokens`, { + amount: session.amount, + currency: session.currency, + payment_details: paymentDetails, + return_url: returnURL + }); + if (secureTokenResponse.status >= 400) { + const error = (await secureTokenResponse.json()).error; + return { error }; + } + const secureToken = await secureTokenResponse.json(); + return { secureToken }; + } + async handleApiError(error) { + if (!this.broker) + throw new Error("KOMOJU Fields bug: broker should be set by now"); + const result = await this.broker.send({ + type: "dispatch-event", + name: "komoju-error", + detail: { error } + }); + if (!result || result.type !== "dispatch-result") { + throw new Error("Expected dispatch-result, got " + JSON.stringify(result)); + } + if (result.cancel) + return; + this.querySelectorAll(".generic-error-message").forEach((container) => { + const errorText = document.createElement("komoju-error"); + if (typeof error === "string") { + errorText.textContent = error; + } else if (error.message) { + errorText.textContent = error.message; + } + container.append(errorText); + }); + } + async submitToken(paymentDetails) { + if (paymentDetails.type === "credit_card") { + const { secureToken, error, skip } = await this.do3DS(paymentDetails); + if (error && !skip) { + return { type: "submit-result", errors: [error] }; + } else if (secureToken) { + return { + type: "submit-result", + token: secureToken + }; + } + } + const tokenResponse = await this.komojuFetch("POST", `/api/v1/tokens`, { + payment_details: paymentDetails + }); + if (tokenResponse.status >= 400) { + const error = (await tokenResponse.json()).error; + this.handleApiError(error); + this.endFade(); + return { type: "submit-result", errors: [error.message] }; + } + const token = await tokenResponse.json(); + return { + type: "submit-result", + token + }; + } + async render() { + if (!this.session) + throw new Error("KOMOJU Session not loaded"); + const paymentMethod = this.session.payment_methods.find((method) => method.type === this.paymentType); + const thisRender = ++this._renderCount; + if (!paymentMethod) { + const errorElement = document.createElement("komoju-error"); + const errorMessage = document.createElement("komoju-i18n"); + errorMessage.key = "payment-method-unavailable"; + errorElement.append(errorMessage); + this.replaceChildren(errorElement); + this.applyTheme(); + return; + } + let moduleName = paymentMethod.type; + if (!supported_payment_types_default.has(moduleName)) { + moduleName = "offsite"; + } + const module = await import(`${this.komojuCdn}/fields/${moduleName}/module.js`); + if (thisRender !== this._renderCount) + return; + this.module = module; + if (!this.module) + throw new Error(`KOMOJU Payment module not found: ${this.paymentType}`); + this.module.render(this, paymentMethod); + this.querySelectorAll("input").forEach((input) => { + input.addEventListener("compositionstart", () => { + input.dataset.ime = "active"; + }); + input.addEventListener("compositionend", () => { + input.dataset.ime = "inactive"; + }); + }); + this.applyTheme(); + const priceInfo = this.querySelector(".price-info"); + if (!priceInfo) + return; + if (paymentMethod.customer_fee) { + const listItem = document.createElement("li"); + const feeMessage = document.createElement("komoju-i18n"); + listItem.classList.add("customer-fee"); + feeMessage.key = "customer-fee-will-be-charged"; + feeMessage.dataset["fee"] = formatMoney( + paymentMethod.customer_fee, + paymentMethod.currency ?? this.session.currency + ); + listItem.append(feeMessage); + priceInfo.append(listItem); + } + if (paymentMethod.exchange_rate && paymentMethod.amount && paymentMethod.currency && paymentMethod.currency !== this.session.currency) { + const listItem = document.createElement("li"); + const dccMessage = document.createElement("komoju-i18n"); + const rate = Math.round(paymentMethod.exchange_rate * 1e4) / 1e4; + dccMessage.key = "dynamic-currency-notice"; + dccMessage.dataset["currency"] = paymentMethod.currency; + dccMessage.dataset["original"] = formatMoney(this.session.amount, this.session.currency); + dccMessage.dataset["converted"] = formatMoney(paymentMethod.amount, paymentMethod.currency); + if (paymentMethod.customer_fee) { + dccMessage.key = "dynamic-currency-notice-with-fee"; + dccMessage.dataset["total"] = formatMoney( + paymentMethod.amount + paymentMethod.customer_fee, + paymentMethod.currency + ); + } + listItem.title = `1 ${this.session.currency} = ${rate} ${paymentMethod.currency}`; + listItem.classList.add("dynamic-currency"); + listItem.append(dccMessage); + priceInfo.append(listItem); + } + } + startFade() { + const fade = document.createElement("komoju-fade"); + setTimeout(() => fade.classList.add("show"), 0); + this.querySelector(".fields")?.prepend(fade); + } + endFade() { + this.querySelectorAll("komoju-fade").forEach((el) => { + const fade = el; + fade.classList.remove("show"); + setTimeout(() => fade.remove(), 500); + }); + } +}; + +// src/shared/komoju-error-element.ts +var KomojuErrorElement = class extends HTMLElement { + constructor() { + super(); + const root = this.attachShadow({ mode: "open" }); + const container = document.createElement("div"); + this.container = container; + container.style.height = "0"; + container.style.transition = "height 0.2s ease-in-out"; + const slot = document.createElement("slot"); + container.append(slot); + root.append(container); + } + connectedCallback() { + this.container.style.height = this.container.scrollHeight + "px"; + const resizeObserver = new ResizeObserver((_) => { + this.container.style.height = this.container.scrollHeight + "px"; + }); + resizeObserver.observe(this.container); + } + remove() { + this.classList.add("removing"); + this.container.style.height = "0"; + window.setTimeout(() => { + super.remove(); + }, 200); + } +}; + +// src/shared/komoju-fade-element.ts +var KomojuFadeElement = class extends HTMLElement { + connectedCallback() { + const fields = this.parentElement; + if (!fields) + return; + this.resizeObserver = new ResizeObserver((entries) => { + const { width, height } = entries[0].contentRect; + this.style.width = `${width}px`; + this.style.height = `${height}px`; + }); + this.resizeObserver?.observe(fields); + } + disconnectedCallback() { + this.resizeObserver?.disconnect(); + this.resizeObserver = void 0; + } +}; + +// src/fields-iframe.ts +window.customElements.define("komoju-host", KomojuHostElement); +window.customElements.define("komoju-error", KomojuErrorElement); +window.customElements.define("komoju-i18n", KomojuI18nElement); +window.customElements.define("komoju-fade", KomojuFadeElement); +(async () => { + const moduleName = "error-reporting"; + const module = await import(`${env_default.CDN}/extras/${moduleName}/module.js`); + const onerror = (event) => { + const error = event instanceof ErrorEvent ? event.error : event.reason; + if (!(error instanceof Error)) + return; + module.reportError(error); + }; + window.addEventListener("error", onerror); + window.addEventListener("unhandledrejection", onerror); +})(); +//# sourceMappingURL=fields-iframe.js.map diff --git a/src/app/code/Komoju/Payments/view/frontend/web/js/fields-iframe.js.map b/src/app/code/Komoju/Payments/view/frontend/web/js/fields-iframe.js.map new file mode 100644 index 000000000..2c852c0cb --- /dev/null +++ b/src/app/code/Komoju/Payments/view/frontend/web/js/fields-iframe.js.map @@ -0,0 +1,7 @@ +{ + "version": 3, + "sources": ["../src/shared/validation.ts", "../src/shared/komoju-i18n-element.ts", "../src/shared/money.ts", "../src/shared/komoju-api.ts", "../src/shared/themable.ts", "../src/generated/env.ts", "../src/generated/supported-payment-types.ts", "../src/shared/translations.ts", "../src/i18n.ts", "../src/shared/message-broker.ts", "../src/komoju-host-element.ts", "../src/shared/komoju-error-element.ts", "../src/shared/komoju-fade-element.ts", "../src/fields-iframe.ts"], + "sourcesContent": ["// Adds validation to an input element.\nexport function addValidation(\n _i18n: Translations, // Used only by typescript to compile-time catch missing translations.\n input: HTMLInputElement,\n callback: (input: HTMLInputElement) => keyof Translations['en'] | null\n) {\n // Add a class so that we know this input has validation.\n input.classList.add('has-validation');\n\n // Tiny detail: if the user has never inputted anything, we don't want to run validations at all\n // at the risk of showing an error message when the user is just clicking around.\n input.addEventListener('input', () => {\n input.dataset.validationDirty = 'true';\n });\n\n // Validation function. This will be called on 'blur' and also on a custom 'validate' event.\n const validate = (event: Event) => {\n const input = event.target as HTMLInputElement;\n\n const errorMessageKey = callback(input);\n\n if (errorMessageKey) {\n showError(_i18n, input, errorMessageKey);\n }\n };\n input.addEventListener('blur', (event) => {\n if (input.dataset.validationDirty !== 'true') return;\n else return validate(event);\n });\n input.addEventListener('validate', validate);\n\n // When the user focuses on the input, remove all error artifacts.\n input.addEventListener('focus', (event) => {\n const input = event.target as HTMLInputElement;\n clearErrors(input);\n });\n}\n\nexport function showError(\n _i18n: Translations, // Used only by typescript to compile-time catch missing translations.\n input: HTMLInputElement,\n messageKey: keyof Translations['en']\n) {\n input.classList.add('invalid');\n const key = messageKey as string;\n\n // We don't want to show the same error twice!\n const container = input.parentElement;\n const dupeSelector = `komoju-error:not(.removing) > komoju-i18n[key=\"${key}\"]`;\n if (container?.querySelector(dupeSelector)) {\n return;\n }\n\n container?.append(createErrorElement(messageKey as string));\n}\n\nexport function clearErrors(input: HTMLInputElement) {\n input.classList.remove('invalid');\n input.parentElement?.querySelectorAll('komoju-error:not(.removing)').forEach((element) => {\n element.remove();\n });\n}\n\n// Runs validations on an element.\nexport function runValidation(input: HTMLInputElement) {\n // Fire the 'validate' custom event.\n input.dispatchEvent(new CustomEvent('validate'));\n\n // If there's an error message, return it.\n const errorMessage = input.parentElement?.querySelector('komoju-error:not(.removing)')?.textContent;\n return errorMessage ?? null;\n}\n\n// Creates the error message element that appears under an invalid input.\n// Mainly just called by addValidation().\nexport function createErrorElement(messageKey: string) {\n const el = window.document.createElement('komoju-error');\n const i18nEl = window.document.createElement('komoju-i18n') as KomojuI18nElement;\n i18nEl.key = messageKey;\n el.appendChild(i18nEl);\n return el;\n}\n", "// Language gets stored in here, mostly controlled by .\ndeclare let window: WindowWithKomojuGlobals;\n\nconst defaultLanguage = 'en';\n\ntype Queryable = {\n querySelectorAll: Document['querySelectorAll'];\n};\n\nexport function broadcastLocaleChange(root: Queryable, locale: string) {\n root.querySelectorAll('komoju-i18n').forEach((element) => {\n const i18n = element as KomojuI18nElement;\n i18n.render(locale);\n });\n}\n\n// This is a element that we use internally for displaying translated text\nexport default class KomojuI18nElement extends HTMLElement {\n static get observedAttributes() {\n return ['key'];\n }\n\n // Attribute: key\n // The key of the translation to display.\n get key() {\n return this.getAttribute('key');\n }\n set key(value) {\n this.setAttribute('key', value ?? '');\n }\n\n connectedCallback() {\n this.render();\n }\n\n attributeChangedCallback(name: string, _oldValue: string, _newValue: string) {\n if (name === 'key') this.render();\n }\n\n // Search up the DOM until we find a parent element with a locale attribute.\n findLocale() {\n let parent = this.parentElement;\n while (parent && !parent.getAttribute('locale')) {\n parent = parent.parentElement;\n }\n return parent?.getAttribute('locale') ?? defaultLanguage;\n }\n\n render(locale?: string) {\n if (!this.key) return;\n\n if (!locale) locale = this.findLocale();\n if (!Object.keys(window.komojuTranslations).includes(locale)) locale = defaultLanguage;\n\n const lang = locale.substring(0, 2);\n\n const message = window.komojuTranslations[lang][this.key];\n if (!message) {\n console.error(`KOMOJU bug: missing translation for key: ${this.key}`);\n return;\n }\n\n // Perform interpolation\n const matches = message.match(/%\\{[\\w-]+\\}/g);\n if (matches) {\n let result = message;\n matches.forEach((match) => {\n const key = match.replace(/%{|}/g, '');\n const value = this.dataset[key];\n if (value) result = result.replace(match, value);\n });\n this.textContent = result;\n return;\n }\n\n this.textContent = message;\n }\n}\n", "export const noDecimalCurrencies = [\n 'BIF', // Burundian Franc\n 'CLP', // Chilean Peso\n 'DJF', // Djiboutian Franc\n 'GNF', // Guinean Franc\n 'JPY', // Japanese Yen\n 'KMF', // Comorian Franc\n 'KRW', // South Korean Won\n 'MGA', // Malagasy Ariary\n 'PYG', // Paraguayan Guaran\u00ED\n 'RWF', // Rwandan Franc\n 'UGX', // Ugandan Shilling\n 'VND', // Vietnamese \u0110\u1ED3ng\n 'VUV', // Vanuatu Vatu\n 'XAF', // Central African Cfa Franc\n 'XOF', // West African Cfa Franc\n 'XPF', // Cfp Franc\n];\n\n// Currently modern browsers depend on ISO 4217\n//\n// We do support non-fiat currencies which are not part of the\n// ISO standard and require us to build formatters for\nconst nonISOCurrencies = [\n 'USDC'\n]\n\nconst displayCurrencyCodeInsteadOfSymbol = [\n 'CNY',\n];\n\nexport function formatMoney(amountCents: number, currency: string, locale: string = 'en') {\n function nonISOFormat(currency: string, amountCents: number) {\n if (!amountCents) {\n return '';\n } else if (nonISOCurrencies.includes(currency) || !currency) {\n return `${amountCents.toLocaleString()} ${currency}`;\n } else {\n throw 'invalid currency format';\n }\n }\n\n const amountDecimal = decentify(amountCents, currency);\n\n if (nonISOCurrencies.includes(currency) || !currency) {\n return nonISOFormat(currency, amountDecimal)\n } else {\n const numberFormat = new Intl.NumberFormat(`${locale}-JP`, {\n style: 'currency',\n currency: currency,\n currencyDisplay: displayCurrencyCodeInsteadOfSymbol.includes(currency) ? \"code\" : \"symbol\"\n });\n\n return numberFormat.format(amountDecimal);\n }\n};\n\nexport function decentify(amountCents: number, currency: string) {\n return noDecimalCurrencies.includes(currency) ? amountCents : amountCents / 100.0;\n}\n", "// fetch wrapper with KOMOJU authentication already handled.\nexport function komojuFetch(\n config: {\n komojuApi: string,\n publishableKey: string | null,\n },\n method: 'GET' | 'POST',\n path: string,\n body?: object\n): Promise {\n if (!config.komojuApi) throw new Error('KOMOJU API URL is null');\n if (!config.publishableKey) throw new Error('KOMOJU publishable-key not set');\n\n return fetch(`${config.komojuApi}${path}`, {\n method,\n headers: {\n accept: 'application/json',\n 'content-type': 'application/json',\n authorization: `Basic ${btoa(`${config.publishableKey}:`)}`,\n 'komoju-via': 'fields',\n },\n body: body ? JSON.stringify(body) : undefined\n });\n}\n", "export default class Themable extends HTMLElement {\n // Attribute: theme\n // CSS file to use as a theme.\n get theme() {\n return this.getAttribute('theme');\n }\n set theme(value) {\n this.setAttribute('theme', value ?? '');\n }\n\n applyTheme() {\n const root = this.shadowRoot ?? document;\n\n if (this.theme === null) {\n root.querySelectorAll('#theme,#inline-theme').forEach(el => el.remove());\n } else if (this.theme.startsWith('http') || this.theme.startsWith('/') || this.theme.startsWith('data:')) {\n this.applyExternalTheme(root, this.theme);\n } else {\n this.applyInlineTheme(root, this.theme);\n }\n }\n\n applyInlineTheme(root: ParentNode, theme: string) {\n root.querySelectorAll('#theme,#inline-theme').forEach(el => el.remove());\n\n const style = document.createElement('style');\n style.id = 'inline-theme';\n style.textContent = theme;\n this.appendStyleTag(style);\n }\n\n applyExternalTheme(root: ParentNode, theme: string) {\n root.querySelectorAll('#inline-theme').forEach(el => el.remove());\n let link = root.querySelector('#theme') as HTMLLinkElement | null;\n if (link) {\n if (link.href !== this.theme) link.href = theme;\n } else {\n link = document.createElement('link');\n link.id = 'theme';\n link.rel = 'stylesheet';\n link.href = theme;\n this.appendStyleTag(link);\n }\n }\n\n appendStyleTag(style: HTMLLinkElement | HTMLStyleElement) {\n if (this.shadowRoot) {\n this.shadowRoot.append(style);\n }\n else {\n document.head.append(style);\n }\n }\n}\n", "// Generated by bin/generate.sh\n//\n// This file pulls from environment variables (and git).\n\nexport default {\n \"CDN\": \"https://multipay.komoju.com\",\n \"ENV\": \"development\",\n \"HONEYBADGER_API_KEY\": \"\",\n \"GIT_REV\": \"99ad2eb29ce6530dedfe3a0ec34aea970dbaa78a\",\n};\n", "// Generated by bin/generate.sh\n//\n// List of supported payment types comes from the folders in src/fields/*.\n// To add a new one, simply add a new folder.\n\nconst supported: Set = new Set();\nsupported.add('bank_transfer');\nsupported.add('credit_card');\nsupported.add('konbini');\nsupported.add('offsite');\nexport default supported;\n", "declare let window: WindowWithKomojuGlobals;\n\n// Call this to add messages to the registry.\n// Individual payment method modules can do this to add their own messages.\n// That way, we avoid needing to load all messages for every payment method upfront.\nexport function registerMessages(messages: I18n) {\n if (!window.komojuTranslations) {\n window.komojuTranslations = { 'en': {}, 'ja': {} };\n }\n\n for (const lang of Object.keys(window.komojuTranslations)) {\n window.komojuTranslations[lang] = {\n ...window.komojuTranslations[lang],\n ...messages[lang],\n };\n }\n}\n", "export const en = {\n 'customer-fee-will-be-charged': 'A fee of %{fee} will be included.',\n 'dynamic-currency-notice': 'Payment will be made in %{currency}: %{original} \u2192 %{converted}.',\n 'dynamic-currency-notice-with-fee': 'Payment will be made in %{currency}: %{original} \u2192 %{converted}. (total: %{total})',\n 'payment-method-unavailable': 'This payment method is currently unavailable.',\n 'verification-failed': 'Verification failed.',\n 'close': 'Close',\n};\n\nexport const ja: typeof en = {\n 'customer-fee-will-be-charged': '%{fee}\u306E\u624B\u6570\u6599\u304C\u8FFD\u52A0\u3055\u308C\u307E\u3059\u3002',\n 'dynamic-currency-notice': '\u652F\u6255\u3044\u306F%{currency}\u3067\u6C7A\u6E08\u3055\u308C\u307E\u3059: %{original} \u2192 %{converted}\u3002',\n 'dynamic-currency-notice-with-fee': '\u652F\u6255\u3044\u306F%{currency}\u3067\u6C7A\u6E08\u3055\u308C\u307E\u3059: %{original} \u2192 %{converted}\u3002(\u5408\u8A08%{total})',\n 'payment-method-unavailable': '\u3053\u306E\u652F\u6255\u3044\u65B9\u6CD5\u306F\u73FE\u5728\u3054\u5229\u7528\u3044\u305F\u3060\u3051\u307E\u305B\u3093\u3002',\n 'verification-failed': '\u8A8D\u8A3C\u306B\u5931\u6557\u3057\u307E\u3057\u305F\u3002',\n 'close': '\u9589\u3058\u308B',\n};\n", "export interface Message {\n type: string,\n}\nexport interface FullMessage extends Message {\n brokerId: string,\n id: string,\n}\n\ninterface MessageAck extends FullMessage {\n type: 'ack',\n response?: Message,\n}\n\ntype MessageBrokerArgs = { send: Window, receive: Window };\n\ntype TypedMessageListener = (arg: T) => Promise | Message | undefined | void;\ntype MessageListener = TypedMessageListener;\n\n// Wrapper around postMessage events that lets us use promises instead of\n// disjoint \"send\" and \"receive\" flows.\nexport class MessageBroker {\n // Keep track of which window to send to and which to receive on.\n // These are promises so that we can effectively buffer messages until the window is ready.\n _sendWindow: Promise;\n _receiveWindow: Promise;\n _setSendWindow?: (value: Window) => void;\n _setReceiveWindow?: (value: Window) => void;\n\n // Raw \"message\" event listener. We need to keep track of this so we can remove it later.\n messageHandler: (event: MessageEvent) => void;\n\n // Map of in-progress promises. When we receive an ack message with a matching id, we resolve the promise.\n promises: Map,\n resolve: (value?: Message) => void,\n }>;\n\n // Map of listeners. When we receive a message with a matching type, we call the listener.\n listeners: Map;\n\n // Unique id for this broker. Used to distinguish messages from other brokers.\n id: string;\n\n origin: string;\n\n constructor(id?: string) {\n this._sendWindow = new Promise(resolve => this._setSendWindow = resolve);\n this._receiveWindow = new Promise(resolve => this._setReceiveWindow = resolve);\n\n this.messageHandler = event => {\n if (this.origin !== '*' && event.origin !== this.origin) return;\n this.handleMessage(event);\n };\n\n this.id = id ?? crypto.randomUUID();\n this.origin = '*';\n this.promises = new Map();\n this.listeners = new Map();\n }\n\n // Call this to set up the broker\n setup(arg: MessageBrokerArgs) {\n if (this._setSendWindow) {\n this._setSendWindow(arg.send);\n this._setSendWindow = undefined;\n } else {\n this._sendWindow = Promise.resolve(arg.send);\n }\n\n if (this._setReceiveWindow) {\n this._setReceiveWindow(arg.receive);\n this._setReceiveWindow = undefined;\n } else {\n this._receiveWindow = Promise.resolve(arg.receive);\n }\n\n arg.receive.addEventListener('message', this.messageHandler);\n }\n\n // Call this to send a message. Promise will resolve when the associated ack message\n // comes back.\n send(message: MessageType): Promise {\n const fullMessage: FullMessage = {\n ...message,\n brokerId: this.id,\n id: crypto.randomUUID(),\n };\n\n let resolve: ((value?: Message) => void) | null = null;\n const promise = new Promise((resolvePromise, _reject) => {\n resolve = resolvePromise;\n });\n if (!resolve) throw new Error('Broker is busted');\n\n this.promises.set(fullMessage.id, { promise, resolve });\n return this._sendWindow.then(w => w.postMessage(fullMessage, this.origin)).then(() => promise);\n }\n\n // Call this to set the listener for a certain event. Kind of like the built-in\n // addEventListener, but can only add one per event type.\n receive(type: MessageType['type'], listener: TypedMessageListener) {\n this.listeners.set(type, listener as MessageListener);\n }\n\n // Internal message handler\n async handleMessage(event: MessageEvent) {\n const message = event.data;\n\n // Ignore messages from other brokers\n if (message.brokerId !== this.id) return;\n\n // 'ack' messages resolve an in-progress promise\n if (message.type === 'ack') {\n const ack = message as MessageAck;\n const promise = this.promises.get(ack.id);\n\n // Acks with a wrong ID typically come from another tag\n // in the same window.\n if (!promise) return;\n\n promise.resolve(ack.response);\n this.promises.delete(ack.id);\n }\n // all other messages trigger a local listener if present\n else {\n const listener = this.listeners.get(message.type);\n const ack: MessageAck = { type: 'ack', brokerId: this.id, id: message.id };\n if (listener) ack.response = (await listener(message)) ?? undefined;\n await this._sendWindow.then(w => w.postMessage(ack, this.origin));\n }\n }\n\n // Call this to clean up the window event listener\n destroy() {\n return this._receiveWindow.then(w => w.removeEventListener('message', this.messageHandler));\n }\n}\n", "import spinner from './shared/spinner.html';\nimport { runValidation } from './shared/validation';\nimport KomojuI18nElement, { broadcastLocaleChange } from './shared/komoju-i18n-element';\nimport { formatMoney } from './shared/money';\nimport { komojuFetch } from './shared/komoju-api';\nimport Themable from './shared/themable';\nimport ENV from './generated/env';\nimport supportedPaymentTypes from './generated/supported-payment-types';\n\nimport { registerMessages } from './shared/translations';\nimport * as i18n from './i18n';\nimport { MessageBroker } from './shared/message-broker';\nregisterMessages(i18n);\n\nlet _baseKomojuAPI: string | undefined;\nfunction baseKomojuAPI() {\n if (_baseKomojuAPI) return _baseKomojuAPI;\n\n const url = new URL(window.location.href);\n const params = new URLSearchParams(url.hash.slice(1));\n _baseKomojuAPI = params.get('api') ?? 'https://komoju.com';\n return _baseKomojuAPI;\n}\n\nfunction brokerId() {\n const url = new URL(window.location.href);\n const params = new URLSearchParams(url.hash.slice(1));\n return params.get('broker') ?? undefined;\n}\n\nfunction i18nMessage(locale: string | null, key: keyof typeof i18n['en']): string | undefined {\n if (locale === 'ja') return (i18n.ja as any)[key];\n return (i18n.en as any)[key];\n}\n\nexport default class KomojuHostElement extends Themable implements KomojuFieldsConfig {\n static get observedAttributes() {\n console.log('KomojuHostElement::listenToMessagesFromMainWindow');\n\n return [\n 'komoju-api',\n 'session',\n 'session-id',\n 'publishable-key',\n 'payment-type',\n 'locale',\n 'theme',\n 'token',\n 'name',\n ];\n }\n\n // 'session' is also an attribute. Set the 'session' attribute to a stringified JSON of\n // the entire KOMOJU sesion to skip having to fetch it from KOMOJU again.\n _session: KomojuSession | null = null\n get session() {\n return this._session;\n }\n set session(value) {\n console.log('KomojuHostElement set session', value);\n\n this._session = value;\n this.broker.send({\n type: 'dispatch-event',\n name: 'komoju-session-change',\n detail: { session: this._session }\n });\n }\n\n module: {\n render: KomojuRenderFunction,\n paymentDetails: KomojuPaymentDetailsFunction\n } | null = null\n\n // Attribute: komoju-api\n // Usually this'll just be https://komoju.com, but sometimes we use other URLs.\n get komojuApi() {\n const attribute = this.getAttribute('komoju-api');\n if (!attribute || attribute === '') return baseKomojuAPI();\n else return attribute;\n }\n set komojuApi(value) {\n this.setAttribute('komoju-api', value ?? '');\n }\n\n // Attribute: session-id\n // KOMOJU Session ID. Create your session on the server then pass it in here.\n get sessionId() {\n return this.getAttribute('session-id');\n }\n set sessionId(value) {\n this.setAttribute('session-id', value ?? '');\n }\n\n // Attribute: publishable-key\n // KOMOJU publishable key. Get this from your merchant dashboard.\n get publishableKey() {\n return this.getAttribute('publishable-key');\n }\n set publishableKey(value) {\n this.setAttribute('publishable-key', value ?? '');\n }\n\n // Attribute: payment-type\n // Which payment type to show. If your session only has 1 payment type, this is unnecessary.\n // Alternatively, if a element is present, this will be set automatically.\n get paymentType() {\n return this.getAttribute('payment-type');\n }\n set paymentType(value) {\n this.setAttribute('payment-type', value ?? '');\n }\n\n // Attribute: locale\n // Language of text to show. Defaults to the browser's language.\n get locale() {\n return this.getAttribute('locale');\n }\n set locale(value) {\n this.setAttribute('locale', value ?? '');\n this.broker.send({\n type: 'dispatch-event',\n name: 'komoju-locale-change',\n detail: { locale: value }\n });\n }\n\n // Attribute: token\n // Boolean attribute - if present, will generate a token instead of processing payment.\n get token() {\n return this.hasAttribute('token');\n }\n set token(value) {\n if (value) this.setAttribute('token', '');\n else this.removeAttribute('token');\n }\n\n // Attribute: name\n // Similar to an input's name attribute. This is used in token mode, and is the name of the\n // input that will contain the token.\n get name() {\n return this.getAttribute('name');\n }\n set name(value) {\n if (value) this.setAttribute('name', value);\n else this.removeAttribute('name');\n }\n\n // Where to fetch payment method modules.\n get komojuCdn() {\n return ENV['CDN'];\n }\n\n get paymentMethod() {\n return this.session?.payment_methods.find(method => method.type === this.paymentType);\n }\n\n resizeObserver?: ResizeObserver;\n\n broker: MessageBroker = new MessageBroker(brokerId());\n\n // Reactive attribute handling. When session or payment type is changed, we want to re-render.\n async attributeChangedCallback(name: string, oldValue: string | null, newValue: string | null) {\n console.log('??? KomojuHostElement attributeChangedCallback', name, oldValue);\n console.log('###')\n console.log('NEW VALUE::KomojuHostElement attributeChangedCallback', name, newValue);\n\n if (name === 'session') {\n if (!newValue || newValue == '') return;\n\n this.session = JSON.parse(newValue);\n if (!this.locale) this.locale = this.session!.default_locale.substring(0, 2);\n if (!this.paymentType) this.paymentType = this.session!.payment_methods[0].type;\n this.render();\n }\n else if (name === 'session-id' || name === 'publishable-key') {\n if (!newValue || newValue == '') return;\n\n // Session ID and publishable key are both required to fetch a session, so when either\n // one changes, we re-fetch the session.\n if (!this.publishableKey) return;\n if (!this.sessionId) return;\n\n const response = await this.komojuFetch('GET', `/api/v1/sessions/${this.sessionId}`);\n\n if (response.status === 404) {\n console.error('Invalid KOMOJU session ID', this.sessionId);\n return;\n }\n\n if (response.status !== 200) {\n console.error('Failed to retrieve KOMOJU session', response);\n return;\n }\n\n this.session = await response.json();\n if (!this.session) throw new Error('KOMOJU returned a null session');\n if (!this.paymentType) this.paymentType = this.session.payment_methods[0].type;\n if (!this.locale) this.locale = this.session.default_locale.substring(0, 2);\n\n this.render();\n }\n else if (name === 'payment-type') {\n if (!newValue || newValue == '') return;\n if (!this.session) return;\n if (!this.publishableKey) return;\n this.startFade();\n await this.render();\n }\n else if (name === 'locale') {\n if (!newValue || newValue == '' || oldValue === newValue) return;\n broadcastLocaleChange(this, newValue);\n }\n else if (name === 'theme') {\n this.applyTheme();\n }\n }\n\n connectedCallback() {\n console.log('KomojuHostElement connectedCallback')\n // We start by just showing a spinner.\n this.innerHTML = spinner;\n console.log(`${JSON.stringify(this.broker)}, broker`)\n\n // Set up message broker to communicate with the parent window.\n this.listenToMessagesFromMainWindow(this.broker);\n this.broker.setup({\n send: window.parent,\n receive: window,\n });\n\n // Set up resize observer so that the iframe can resize itself.\n const body = this.ownerDocument?.body;\n this.resizeObserver = new ResizeObserver(() => {\n const height = body.parentElement!.offsetHeight;\n if (height === 0) return;\n this.broker.send({ type: 'resize', height: height.toString() });\n });\n if (body) this.resizeObserver.observe(body, { box: 'border-box' });\n }\n\n disconnectedCallback() {\n this.broker.destroy();\n this.resizeObserver?.disconnect();\n this.resizeObserver = undefined;\n }\n\n listenToMessagesFromMainWindow(broker: MessageBroker) {\n console.log('KomojuHostElement listenToMessagesFromMainWindow');\n\n // Sync attributes from parent window.\n broker.receive('attr', (message) => {\n // Avoid XSS by restricting which attrs we're willing to receive.\n if (!KomojuHostElement.observedAttributes.includes(message.attr)) return;\n\n console.log('KomojuHostElement listenToMessagesFromMainWindow attr', message);\n\n if (message.value === null || message.value === undefined) this.removeAttribute(message.attr);\n else this.setAttribute(message.attr, message.value);\n });\n\n // Submit when parent komoju-fields element's submit function is called.\n broker.receive('submit', () => {\n return this.submit();\n });\n\n // Expose the endFade function.\n broker.receive<{ type: 'end-fade' }>('end-fade', () => {\n this.endFade();\n });\n }\n\n // Submits payment details securely to KOMOJU before redirecting.\n // The redirect target may be\n // 1. A URL for performing 3DS authentication\n // 2. An external payment provider URL (i.e. to log into a payment app or show a QR code)\n // 3. The session's return_url in the case where payment is completed instantly\n async submit(): Promise {\n if (!this.module || !this.session) {\n return { type: 'submit-result', errors: ['Attempted to submit before selecting KOMOJU Payment method'] };\n }\n const paymentMethod = this.paymentMethod;\n if (!paymentMethod) throw new Error(`KOMOJU Payment method not found: ${this.paymentType}`);\n\n // Check for invalid input\n this.querySelectorAll('komoju-error').forEach(error => error.remove());\n const validatedFields = this.querySelectorAll('.has-validation');\n const errors = Array.prototype.map.call(validatedFields, (field) =>\n field instanceof HTMLInputElement ? runValidation(field) : null\n );\n if (errors.some(error => error != null)) {\n return { type: 'submit-result', errors: errors.filter(error => error != null) };\n }\n\n // Now we can pull the payment details hash from the payment method module\n // and send it to KOMOJU.\n this.startFade();\n const paymentDetails = this.module.paymentDetails(this, paymentMethod);\n\n if (this.token) {\n return await this.submitToken(paymentDetails);\n }\n else {\n return await this.submitPayment(paymentDetails);\n }\n }\n\n // Called by submit,\n // submits payment directly to KOMOJU for processing.\n async submitPayment(paymentDetails: object): Promise {\n const paymentMethod = this.paymentMethod;\n if (!paymentMethod) {\n throw new Error('Attempted to submit before selecting KOMOJU Payment method');\n }\n const session = this.session!;\n\n // If the payment method is not supported by KOMOJU Fields, we can still redirect straight\n // to the session URL, effectively supporting *all* payment methods.\n let moduleName = paymentMethod.offsite ? 'offsite' : paymentMethod.type;\n if (!supportedPaymentTypes.has(moduleName)) {\n const result: KomojuSubmitResult = {\n type: 'submit-result',\n pay: {\n status: 'pending',\n redirect_url: `${session.session_url}#${paymentMethod.type}`,\n },\n };\n return result;\n }\n\n // Special case for 3DS\n let secureTokenId: string | null = null;\n if (paymentMethod.type === 'credit_card' && session.mode !== 'customer') try {\n const { secureToken, error, skip } = await this.do3DS(paymentDetails);\n\n if (secureToken) {\n secureTokenId = secureToken.id\n } else if (error && !skip) {\n return {\n type: 'submit-result',\n errors: [error]\n }\n }\n } catch(e) {\n console.error('Error during secure token flow. Continuing without.', e);\n }\n\n const payResponse = await this.komojuFetch('POST', `/api/v1/sessions/${session.id}/pay`, {\n payment_details: secureTokenId ?? paymentDetails,\n api_locale: this.locale\n });\n const payResult = await payResponse.json() as KomojuPayResult;\n\n const result: KomojuSubmitResult = {\n type: 'submit-result',\n pay: payResult,\n };\n\n if (payResult.error) {\n console.error(payResult);\n this.handleApiError(payResult.error);\n this.endFade();\n }\n\n return result;\n }\n\n // Special case for credit card. Called by both submitToken and submitPayment.\n // The dialog element that handles this exists in the element,\n // so we use broker to send a message to the parent window.\n async do3DS(paymentDetails: object): Promise {\n const { secureToken, error } = await this.submitSecureToken(paymentDetails);\n\n // If the card brand is unsupported, we have no choice but to skip 3DS.\n if (error && error.code === 'unsupported_card_brand') {\n return {\n error,\n skip: true,\n }\n }\n\n if (error) return { error };\n else if (!secureToken) throw new Error('Secure token empty response');\n\n const status = secureToken.verification_status;\n\n // Secure tokens with these statuses are usable as-is.\n if (status === 'OK' || status === 'SKIPPED') {\n return { secureToken };\n }\n\n // Secure token starting in an ERRORED state means misconfiguration in KOMOJU.\n // If possible, we don't want that to get in the way of payment.\n if (status === 'ERRORED') {\n return {\n skip: true,\n }\n }\n\n // This passes off control to the element.\n // Also should note that this will await until the user finishes interacting with the\n // dialog, so we might be waiting for a long time here.\n const dialogResult = await this.broker.send({\n type: 'dialog-start',\n url: secureToken.authentication_url,\n });\n\n if (dialogResult?.type !== 'dialog-result') {\n throw new Error('Expected dialog-result, got ' + JSON.stringify(dialogResult));\n } else {\n const { result } = dialogResult as KomojuDialogResult;\n\n // If the card brand is unsupported, we have no choice but to skip 3DS.\n if (result.error && result.error.code === 'unsupported_card_brand') {\n return {\n error: result.error,\n skip: true,\n };\n }\n\n if (result.error) {\n this.handleApiError(result.error);\n this.endFade();\n return result;\n }\n\n // Verification status can be \"ERRORED\" when the user intentionally clicks \"cancel\".\n // In any case, we need a full stop here and so we should *not* return the secure token,\n // as doing so will signal to the caller that we want to continue with processing.\n if (result.secureToken && result.secureToken.verification_status === 'ERRORED') {\n const error = i18nMessage(this.locale, 'verification-failed') ?? '3DS error';\n this.handleApiError(error);\n this.endFade();\n return {\n error: {\n code: 'verification_status_errored',\n message: error,\n param: null,\n details: null,\n }\n };\n }\n\n return result;\n }\n }\n\n async submitSecureToken(paymentDetails: object): Promise {\n const session = this.session!;\n const returnURL = new URL(this.komojuCdn);\n returnURL.pathname = '/secure-token-return.html';\n returnURL.searchParams.set('session_id', session.id);\n\n const secureTokenResponse = await this.komojuFetch('POST', `/api/v1/secure_tokens`, {\n amount: session.amount,\n currency: session.currency,\n payment_details: paymentDetails,\n return_url: returnURL,\n });\n if (secureTokenResponse.status >= 400) {\n const error = (await secureTokenResponse.json()).error as KomojuApiError;\n return { error };\n }\n const secureToken = await secureTokenResponse.json() as KomojuSecureToken;\n\n return { secureToken };\n }\n\n async handleApiError(error: string | KomojuApiError) {\n if (!this.broker) throw new Error('KOMOJU Fields bug: broker should be set by now');\n\n // Emit an event so implementers can handle this.\n const result = await this.broker.send({\n type: 'dispatch-event',\n name: 'komoju-error',\n detail: { error },\n });\n if (!result || result.type !== 'dispatch-result') {\n throw new Error('Expected dispatch-result, got ' + JSON.stringify(result));\n }\n\n // Show errors if implementers don't cancel the event.\n if ((result as KomojuDispatchResult).cancel) return;\n\n this.querySelectorAll('.generic-error-message').forEach(container => {\n const errorText = document.createElement('komoju-error');\n if (typeof error === 'string') {\n errorText.textContent = error;\n } else if (error.message) {\n errorText.textContent = error.message;\n }\n container.append(errorText);\n });\n }\n\n // Called by submit,\n // uses payment info to create a token that can be safely transmitted to the backend and used there.\n async submitToken(paymentDetails: any): Promise {\n // Credit cards should create a secure token instead.\n if (paymentDetails.type === 'credit_card') {\n const { secureToken, error, skip } = await this.do3DS(paymentDetails);\n // If card brand doesn't support 3DS then we can continue without.\n\n if (error && !skip) {\n return { type: 'submit-result', errors: [error] };\n } else if (secureToken) {\n return {\n type: 'submit-result',\n token: secureToken,\n };\n }\n }\n\n const tokenResponse = await this.komojuFetch('POST', `/api/v1/tokens`, {\n payment_details: paymentDetails\n });\n if (tokenResponse.status >= 400) {\n const error = (await tokenResponse.json()).error as KomojuApiError;\n this.handleApiError(error);\n this.endFade();\n return { type: 'submit-result', errors: [error.message] };\n }\n const token = await tokenResponse.json() as KomojuToken;\n return {\n type: 'submit-result',\n token\n };\n }\n\n // The below render() function often ends up being called multiple times before the previous\n // one finishes. Then they're racing to replace the DOM, which can cause weird bugs.\n // This little counter lets us ignore any renders that are not the most recent one.\n _renderCount = 0;\n\n // Renders fields for the selected payment method.\n // Usually implementers would not need to call this manually.\n async render() {\n if (!this.session) throw new Error('KOMOJU Session not loaded');\n\n const paymentMethod = this.session.payment_methods.find(method => method.type === this.paymentType);\n\n // This helps us avoid race conditions if render() gets called twice in quick succession\n // (common occurrence - session attr and payment-type attr often cause 2 renders)\n const thisRender = ++this._renderCount;\n\n if (!paymentMethod) {\n // Render \"invalid payment method\" text\n const errorElement = document.createElement('komoju-error');\n const errorMessage = document.createElement('komoju-i18n') as KomojuI18nElement;\n errorMessage.key = 'payment-method-unavailable';\n errorElement.append(errorMessage);\n this.replaceChildren(errorElement);\n this.applyTheme();\n return;\n }\n\n // Grab the module for the payment method (name of a folder in src/fields)\n let moduleName = paymentMethod.type;\n if (!supportedPaymentTypes.has(moduleName)) {\n // The offsite module works as a catch-all for payment methods that don't have their own module.\n moduleName = 'offsite';\n }\n\n const module = await import(`${this.komojuCdn}/fields/${moduleName}/module.js`);\n if (thisRender !== this._renderCount) return; // This render is no longer the most recent one\n\n this.module = module;\n if (!this.module) throw new Error(`KOMOJU Payment module not found: ${this.paymentType}`);\n\n // Render payment method fields\n this.module.render(this, paymentMethod);\n\n // Make IME status easily accessible to JS. Payment method modules can use this to avoid\n // auto-formatting while IME composition is still in progress.\n this.querySelectorAll('input').forEach((input) => {\n input.addEventListener('compositionstart', () => {\n input.dataset.ime = 'active';\n });\n input.addEventListener('compositionend', () => {\n input.dataset.ime = 'inactive';\n });\n });\n\n // Add theme styles\n this.applyTheme();\n\n // Add price info (customer fee, dynamic currency)\n const priceInfo = this.querySelector('.price-info');\n if (!priceInfo) return;\n\n // Customer fee\n if (paymentMethod.customer_fee) {\n const listItem = document.createElement('li');\n const feeMessage = document.createElement('komoju-i18n') as KomojuI18nElement;\n listItem.classList.add('customer-fee');\n feeMessage.key = 'customer-fee-will-be-charged';\n feeMessage.dataset['fee'] = formatMoney(\n paymentMethod.customer_fee,\n paymentMethod.currency ?? this.session.currency\n );\n listItem.append(feeMessage);\n priceInfo.append(listItem);\n }\n\n // Dynamic currency (DCC)\n if (\n paymentMethod.exchange_rate &&\n paymentMethod.amount &&\n paymentMethod.currency &&\n paymentMethod.currency !== this.session.currency\n ) {\n const listItem = document.createElement('li');\n const dccMessage = document.createElement('komoju-i18n') as KomojuI18nElement;\n const rate = Math.round(paymentMethod.exchange_rate * 10000) / 10000;\n dccMessage.key = 'dynamic-currency-notice';\n dccMessage.dataset['currency'] = paymentMethod.currency;\n dccMessage.dataset['original'] = formatMoney(this.session.amount, this.session.currency);\n dccMessage.dataset['converted'] = formatMoney(paymentMethod.amount, paymentMethod.currency);\n if (paymentMethod.customer_fee) {\n dccMessage.key = 'dynamic-currency-notice-with-fee';\n dccMessage.dataset['total'] = formatMoney(\n paymentMethod.amount + paymentMethod.customer_fee,\n paymentMethod.currency\n );\n }\n listItem.title = `1 ${this.session.currency} = ${rate} ${paymentMethod.currency}`;\n listItem.classList.add('dynamic-currency');\n listItem.append(dccMessage);\n priceInfo.append(listItem);\n }\n }\n\n // fetch wrapper with KOMOJU authentication already handled.\n komojuFetch = komojuFetch.bind(this, this)\n\n // Fade out fields while loading\n private startFade() {\n const fade = document.createElement('komoju-fade');\n setTimeout(() => fade.classList.add('show'), 0);\n this.querySelector('.fields')?.prepend(fade);\n }\n\n // Remove the fade effect created by startFade()\n private endFade() {\n this.querySelectorAll('komoju-fade').forEach(el => {\n const fade = el as HTMLElement;\n fade.classList.remove('show');\n // Fade animation time is 0.5s in static/shared.css right now.\n setTimeout(() => fade.remove(), 500);\n });\n }\n}\n", "// This is a error tag we use internally for displaying validation errors.\n// End users are not expected to use this.\nexport default class KomojuErrorElement extends HTMLElement {\n container: HTMLElement;\n\n constructor() {\n super();\n const root = this.attachShadow({ mode: 'open' });\n\n // This container will stretch and shrink as the error message appears and disappears.\n const container = document.createElement('div');\n this.container = container;\n container.style.height = '0';\n container.style.transition = 'height 0.2s ease-in-out';\n\n // This element's contents appears inside of the container.\n const slot = document.createElement('slot');\n container.append(slot);\n\n root.append(container);\n }\n\n // Animate the height of the error message when it appears on the page. Resize height to adjust\n // changes in width.\n connectedCallback() {\n this.container.style.height = this.container.scrollHeight + 'px';\n\n // Make sure this height adjusts if the parent element's width changes.\n const resizeObserver = new ResizeObserver((_) => {\n // Adjust the height when the observed element's size changes\n this.container.style.height = this.container.scrollHeight + 'px';\n });\n\n resizeObserver.observe(this.container);\n }\n\n // Animates the height of the error message when it is removed from the page.\n override remove() {\n this.classList.add('removing');\n this.container.style.height = '0';\n window.setTimeout(() => {\n super.remove();\n }, 200);\n }\n}\n", "// This is . It's used internally to fade out the fields temporarily during submit.\n// This prevents double submits and also signals to the user that something is happening.\n//\n// must be placed at the top of the .fields element, otherwise sizing and placement\n// won't work well.\nexport default class KomojuFadeElement extends HTMLElement {\n resizeObserver?: ResizeObserver;\n\n connectedCallback() {\n const fields = this.parentElement;\n if (!fields) return;\n\n this.resizeObserver = new ResizeObserver((entries) => {\n const { width, height } = entries[0].contentRect;\n this.style.width = `${width}px`;\n this.style.height = `${height}px`;\n });\n this.resizeObserver?.observe(fields);\n }\n\n disconnectedCallback() {\n this.resizeObserver?.disconnect();\n this.resizeObserver = undefined;\n }\n}\n", "import './types.d';\nimport KomojuHostElement from './komoju-host-element';\nimport KomojuErrorElement from './shared/komoju-error-element';\nimport KomojuI18nElement from './shared/komoju-i18n-element';\nimport KomojuFadeElement from './shared/komoju-fade-element';\nimport ENV from './generated/env';\n\n// \"Internal\" custom elements\nwindow.customElements.define('komoju-host', KomojuHostElement);\nwindow.customElements.define('komoju-error', KomojuErrorElement);\nwindow.customElements.define('komoju-i18n', KomojuI18nElement);\nwindow.customElements.define('komoju-fade', KomojuFadeElement);\n\n// Error reporting\n(async () => {\n // HACK: weird interpolation intentional because of typescript not knowing the type of the import.\n // I want the browser to actually make an async import request instead of having esbuild pull the\n // whole error-reporting module into the fields-iframe bundle.\n const moduleName = 'error-reporting';\n const module = await import(`${ENV.CDN}/extras/${moduleName}/module.js`);\n\n const onerror = (event: ErrorEvent | PromiseRejectionEvent) => {\n const error = (event instanceof ErrorEvent) ? event.error : (event.reason as Error);\n if (!(error instanceof Error)) return;\n\n module.reportError(error);\n }\n\n window.addEventListener('error', onerror);\n window.addEventListener('unhandledrejection', onerror);\n})();\n"], + "mappings": "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", + "names": ["currency", "amountCents", "result", "error"] +} diff --git a/src/app/code/Komoju/Payments/view/frontend/web/js/fields.js b/src/app/code/Komoju/Payments/view/frontend/web/js/fields.js new file mode 100644 index 000000000..cd93f573d --- /dev/null +++ b/src/app/code/Komoju/Payments/view/frontend/web/js/fields.js @@ -0,0 +1,733 @@ +var __defProp = Object.defineProperty; +var __export = (target, all) => { + for (var name in all) + __defProp(target, name, { get: all[name], enumerable: true }); +}; + +// src/generated/env.ts +var env_default = { + "CDN": "https://multipay.komoju.com", + "ENV": "development", + "HONEYBADGER_API_KEY": "", + "GIT_REV": "99ad2eb29ce6530dedfe3a0ec34aea970dbaa78a" +}; + +// src/shared/translations.ts +function registerMessages(messages) { + if (!window.komojuTranslations) { + window.komojuTranslations = { "en": {}, "ja": {} }; + } + for (const lang of Object.keys(window.komojuTranslations)) { + window.komojuTranslations[lang] = { + ...window.komojuTranslations[lang], + ...messages[lang] + }; + } +} + +// src/i18n.ts +var i18n_exports = {}; +__export(i18n_exports, { + en: () => en, + ja: () => ja +}); +var en = { + "customer-fee-will-be-charged": "A fee of %{fee} will be included.", + "dynamic-currency-notice": "Payment will be made in %{currency}: %{original} \u2192 %{converted}.", + "dynamic-currency-notice-with-fee": "Payment will be made in %{currency}: %{original} \u2192 %{converted}. (total: %{total})", + "payment-method-unavailable": "This payment method is currently unavailable.", + "verification-failed": "Verification failed.", + "close": "Close" +}; +var ja = { + "customer-fee-will-be-charged": "%{fee}\u306E\u624B\u6570\u6599\u304C\u8FFD\u52A0\u3055\u308C\u307E\u3059\u3002", + "dynamic-currency-notice": "\u652F\u6255\u3044\u306F%{currency}\u3067\u6C7A\u6E08\u3055\u308C\u307E\u3059: %{original} \u2192 %{converted}\u3002", + "dynamic-currency-notice-with-fee": "\u652F\u6255\u3044\u306F%{currency}\u3067\u6C7A\u6E08\u3055\u308C\u307E\u3059: %{original} \u2192 %{converted}\u3002(\u5408\u8A08%{total})", + "payment-method-unavailable": "\u3053\u306E\u652F\u6255\u3044\u65B9\u6CD5\u306F\u73FE\u5728\u3054\u5229\u7528\u3044\u305F\u3060\u3051\u307E\u305B\u3093\u3002", + "verification-failed": "\u8A8D\u8A3C\u306B\u5931\u6557\u3057\u307E\u3057\u305F\u3002", + "close": "\u9589\u3058\u308B" +}; + +// src/shared/message-broker.ts +var MessageBroker = class { + constructor(id) { + this._sendWindow = new Promise((resolve) => this._setSendWindow = resolve); + this._receiveWindow = new Promise((resolve) => this._setReceiveWindow = resolve); + this.messageHandler = (event) => { + if (this.origin !== "*" && event.origin !== this.origin) + return; + this.handleMessage(event); + }; + this.id = id ?? crypto.randomUUID(); + this.origin = "*"; + this.promises = /* @__PURE__ */ new Map(); + this.listeners = /* @__PURE__ */ new Map(); + } + setup(arg) { + if (this._setSendWindow) { + this._setSendWindow(arg.send); + this._setSendWindow = void 0; + } else { + this._sendWindow = Promise.resolve(arg.send); + } + if (this._setReceiveWindow) { + this._setReceiveWindow(arg.receive); + this._setReceiveWindow = void 0; + } else { + this._receiveWindow = Promise.resolve(arg.receive); + } + arg.receive.addEventListener("message", this.messageHandler); + } + send(message) { + const fullMessage = { + ...message, + brokerId: this.id, + id: crypto.randomUUID() + }; + let resolve = null; + const promise = new Promise((resolvePromise, _reject) => { + resolve = resolvePromise; + }); + if (!resolve) + throw new Error("Broker is busted"); + this.promises.set(fullMessage.id, { promise, resolve }); + return this._sendWindow.then((w) => w.postMessage(fullMessage, this.origin)).then(() => promise); + } + receive(type, listener) { + this.listeners.set(type, listener); + } + async handleMessage(event) { + const message = event.data; + if (message.brokerId !== this.id) + return; + if (message.type === "ack") { + const ack = message; + const promise = this.promises.get(ack.id); + if (!promise) + return; + promise.resolve(ack.response); + this.promises.delete(ack.id); + } else { + const listener = this.listeners.get(message.type); + const ack = { type: "ack", brokerId: this.id, id: message.id }; + if (listener) + ack.response = await listener(message) ?? void 0; + await this._sendWindow.then((w) => w.postMessage(ack, this.origin)); + } + } + destroy() { + return this._receiveWindow.then((w) => w.removeEventListener("message", this.messageHandler)); + } +}; + +// src/shared/komoju-api.ts +function komojuFetch(config, method, path, body) { + if (!config.komojuApi) + throw new Error("KOMOJU API URL is null"); + if (!config.publishableKey) + throw new Error("KOMOJU publishable-key not set"); + return fetch(`${config.komojuApi}${path}`, { + method, + headers: { + accept: "application/json", + "content-type": "application/json", + authorization: `Basic ${btoa(`${config.publishableKey}:`)}`, + "komoju-via": "fields" + }, + body: body ? JSON.stringify(body) : void 0 + }); +} + +// src/komoju-fields-element.ts +registerMessages(i18n_exports); +var KomojuFieldsElement = class extends HTMLElement { + constructor() { + super(); + this._submitting = false; + this.session = null; + this.broker = new MessageBroker(); + this.dialog = document.createElement("dialog"); + this.listenToMessagesFromIframe(this.broker); + this.dialog.style.width = "80%"; + this.dialog.style.height = "80%"; + this.dialog.style.padding = "0"; + } + static get observedAttributes() { + console.log("KomojuFieldsElement, observedAttributes"); + return [ + "komoju-api", + "session", + "session-id", + "publishable-key", + "payment-type", + "locale", + "theme", + "token", + "name" + ]; + } + get theme() { + return this.getAttribute("theme"); + } + set theme(value) { + this.setAttribute("theme", value ?? ""); + } + get komojuApi() { + return this.getAttribute("komoju-api") ?? "https://komoju.com"; + } + set komojuApi(value) { + this.setAttribute("komoju-api", value); + } + connectedCallback() { + const iframeParams = new URLSearchParams(); + iframeParams.append("broker", this.broker.id); + if (this.hasAttribute("komoju-api")) { + iframeParams.append("api", this.getAttribute("komoju-api")); + } + const iframe = document.createElement("iframe"); + iframe.setAttribute("sandbox", "allow-scripts allow-same-origin"); + iframe.setAttribute("allow", "payment *"); + iframe.title = "KOMOJU secure payment fields"; + iframe.src = `${env_default.CDN}/fields-iframe.html#${iframeParams.toString()}`; + iframe.style.border = "none"; + iframe.style.width = "100%"; + iframe.style.overflow = "hidden"; + iframe.height = "50"; + iframe.addEventListener("load", () => { + if (!iframe.contentWindow) + throw new Error("KOMOJU Fields: iframe had no contentWindow"); + this.broker.setup({ + send: iframe.contentWindow, + receive: window + }); + }); + this.replaceChildren(iframe, this.dialog); + let parent = this.parentElement; + while (parent && parent.tagName !== "FORM") { + parent = parent.parentElement; + } + if (!parent) + return; + const form = parent; + const target = form.parentElement; + if (!target) + return; + const handler = (event) => { + if (this._submitting) + return; + if (this.offsetParent === null) + return; + if (event.target !== form) + return; + event.preventDefault(); + event.stopImmediatePropagation(); + this.submit(event); + }; + target.addEventListener("submit", handler, true); + this.formSubmitHandler = { form, target, handler }; + } + disconnectedCallback() { + if (this.formSubmitHandler) { + this.formSubmitHandler.target.removeEventListener("submit", this.formSubmitHandler.handler, true); + this.formSubmitHandler = void 0; + } + this.broker.destroy(); + } + listenToMessagesFromIframe(broker) { + broker.receive("dispatch-event", (message) => { + const event = new CustomEvent(message.name, { + detail: message.detail, + bubbles: true, + composed: true, + cancelable: true + }); + if (message.name === "komoju-session-change") { + this.session = message.detail.session; + } + const result = { + type: "dispatch-result", + cancel: !this.dispatchEvent(event) + }; + return result; + }); + broker.receive("resize", (message) => { + const iframe = this.querySelector("iframe"); + iframe.height = message.height; + }); + broker.receive("dialog-start", async (message) => { + const result = { + type: "dialog-result", + result: await this.show3DSDialog(message.url) + }; + return result; + }); + } + async attributeChangedCallback(name, _oldValue, newValue) { + console.log("KomojuFieldsElement, oldValue?", name, _oldValue); + console.log("###"); + console.log("KomojuFieldsElement, attributeChangedCallback", name, newValue); + this.broker.send({ + type: "attr", + attr: name, + value: newValue + }); + } + async submit(event) { + if (this.token) + return JSON.parse(this.token); + const submitResult = await this.broker.send({ type: "submit" }); + if (submitResult?.type !== "submit-result") { + throw new Error(`Unexpected submit response from komoju-fields iframe ${JSON.stringify(submitResult)}`); + } + const result = submitResult; + if (result.errors) { + this.dispatchEvent(new CustomEvent("komoju-invalid", { + detail: { errors: result.errors }, + bubbles: true, + composed: true + })); + return; + } + if (result.pay) { + if (!result.pay.error) + await this.handlePayResult(result.pay); + return; + } + if (result.token && event && this.formSubmitHandler) { + const form = this.formSubmitHandler.form; + const inputName = this.getAttribute("name") ?? "komoju_token"; + let input = document.querySelector(`input[name="${inputName}"]`); + if (!input) { + input = document.createElement("input"); + input.type = "hidden"; + input.name = inputName; + form.append(input); + } + input.value = result.token.id; + this.submitParentForm(); + return; + } + if (result.token) { + this.token = JSON.stringify(result.token); + return result.token; + } + throw new Error("KOMOJU Fields bug: submit result was not handled"); + } + async handlePayResult(payResult) { + const session = this.session; + if (!session) + throw new Error("handlePayResult called without a session"); + const instructions = payResult.payment?.payment_details?.instructions_url; + if (instructions) { + const returnURL = new URL(session.return_url ?? session.session_url); + returnURL.searchParams.append("session_id", session.id); + this.showInstructionsDialog(instructions, returnURL.toString()); + } else if (payResult.redirect_url) { + window.location.href = payResult.redirect_url; + } else { + throw new Error(`payResult should have a redirect_url but doesnt ${JSON.stringify(payResult)}`); + } + } + async submitParentForm() { + if (!this.formSubmitHandler) + throw new Error("KOMOJU Fields: tried to submit nonexistent parent form"); + const form = this.formSubmitHandler.form; + try { + this._submitting = true; + const submitEvent = new Event("submit", { bubbles: true, cancelable: true }); + if (form.dispatchEvent(submitEvent)) { + form.submit(); + } else { + this.broker.send({ type: "end-fade" }); + } + } finally { + this._submitting = false; + } + } + showInstructionsDialog(url, finishURL) { + const dialog = this.dialog; + const iframe = createIframe(url); + iframe.style.height = "90%"; + const closeButton = document.createElement("a"); + const closeText = document.createElement("komoju-i18n"); + closeText.key = "close"; + closeButton.append(closeText); + closeButton.classList.add("komoju-fields-close-dialog"); + closeButton.href = finishURL; + closeButton.style.display = "block"; + closeButton.style.padding = "10px"; + dialog.replaceChildren( + closeButton, + iframe + ); + dialog.showModal(); + } + show3DSDialog(url) { + return new Promise((resolve, reject) => { + const dialog = this.dialog; + const origin = env_default["CDN"]; + const iframe = createIframe(url); + window.addEventListener("message", async (event) => { + if (event.origin !== origin) + return; + try { + if (!event.data?._komojuFields) + return; + const { secureTokenId } = event.data; + if (!secureTokenId) + throw new Error("No secureTokenId in message"); + const credentials = { + komojuApi: this.komojuApi, + publishableKey: this.getAttribute("publishable-key") ?? "" + }; + const secureTokenResponse = await komojuFetch(credentials, "GET", `/api/v1/secure_tokens/${secureTokenId}`); + if (secureTokenResponse.status >= 400) { + const error = await secureTokenResponse.json(); + resolve({ error }); + return; + } + const secureToken = await secureTokenResponse.json(); + dialog.close(); + resolve({ secureToken }); + } catch (e) { + reject(e); + } + }); + dialog.replaceChildren(iframe); + dialog.showModal(); + }); + } +}; +for (const attr of KomojuFieldsElement.observedAttributes) { + if (attr === "session" || attr === "theme" || attr === "komoju-api") + continue; + Object.defineProperty(KomojuFieldsElement.prototype, camelCase(attr), { + get() { + return this.getAttribute(attr); + }, + set(value) { + if (value === null) + this.removeAttribute(attr); + else + this.setAttribute(attr, value); + } + }); +} +function camelCase(str) { + return str.split("-").reduce((a, b) => a + b.charAt(0).toUpperCase() + b.slice(1)); +} +function createIframe(url) { + const iframe = document.createElement("iframe"); + iframe.setAttribute( + "sandbox", + "allow-scripts allow-forms allow-same-origin" + ); + iframe.src = url; + iframe.style.border = "none"; + iframe.style.width = "100%"; + iframe.style.height = "100%"; + return iframe; +} + +// src/picker.html +var picker_default = '\n\n
\n
\n\n\n'; + +// src/shared/radio-helpers.ts +function setupRadioParentCheckedClass(input, root) { + if (!input.parentElement) { + throw new Error("KOMOJU Fields bug: radio input has no parent"); + } + if (!input.parentElement.classList.contains("radio")) { + throw new Error("KOMOJU Fields bug: radio input parent has no .radio class"); + } + if (input.checked) { + input.parentElement.classList.add("checked"); + } + input.addEventListener("change", () => { + root.querySelectorAll(".radio.checked").forEach((el) => el.classList.remove("checked")); + input.parentElement.classList.add("checked"); + }); +} + +// src/generated/supported-payment-types.ts +var supported = /* @__PURE__ */ new Set(); +supported.add("bank_transfer"); +supported.add("credit_card"); +supported.add("konbini"); +supported.add("offsite"); +var supported_payment_types_default = supported; + +// src/shared/komoju-i18n-element.ts +var defaultLanguage = "en"; +function broadcastLocaleChange(root, locale) { + root.querySelectorAll("komoju-i18n").forEach((element) => { + const i18n = element; + i18n.render(locale); + }); +} +var KomojuI18nElement = class extends HTMLElement { + static get observedAttributes() { + return ["key"]; + } + get key() { + return this.getAttribute("key"); + } + set key(value) { + this.setAttribute("key", value ?? ""); + } + connectedCallback() { + this.render(); + } + attributeChangedCallback(name, _oldValue, _newValue) { + if (name === "key") + this.render(); + } + findLocale() { + let parent = this.parentElement; + while (parent && !parent.getAttribute("locale")) { + parent = parent.parentElement; + } + return parent?.getAttribute("locale") ?? defaultLanguage; + } + render(locale) { + if (!this.key) + return; + if (!locale) + locale = this.findLocale(); + if (!Object.keys(window.komojuTranslations).includes(locale)) + locale = defaultLanguage; + const lang = locale.substring(0, 2); + const message = window.komojuTranslations[lang][this.key]; + if (!message) { + console.error(`KOMOJU bug: missing translation for key: ${this.key}`); + return; + } + const matches = message.match(/%\{[\w-]+\}/g); + if (matches) { + let result = message; + matches.forEach((match) => { + const key = match.replace(/%{|}/g, ""); + const value = this.dataset[key]; + if (value) + result = result.replace(match, value); + }); + this.textContent = result; + return; + } + this.textContent = message; + } +}; + +// src/shared/themable.ts +var Themable = class extends HTMLElement { + get theme() { + return this.getAttribute("theme"); + } + set theme(value) { + this.setAttribute("theme", value ?? ""); + } + applyTheme() { + const root = this.shadowRoot ?? document; + if (this.theme === null) { + root.querySelectorAll("#theme,#inline-theme").forEach((el) => el.remove()); + } else if (this.theme.startsWith("http") || this.theme.startsWith("/") || this.theme.startsWith("data:")) { + this.applyExternalTheme(root, this.theme); + } else { + this.applyInlineTheme(root, this.theme); + } + } + applyInlineTheme(root, theme) { + root.querySelectorAll("#theme,#inline-theme").forEach((el) => el.remove()); + const style = document.createElement("style"); + style.id = "inline-theme"; + style.textContent = theme; + this.appendStyleTag(style); + } + applyExternalTheme(root, theme) { + root.querySelectorAll("#inline-theme").forEach((el) => el.remove()); + let link = root.querySelector("#theme"); + if (link) { + if (link.href !== this.theme) + link.href = theme; + } else { + link = document.createElement("link"); + link.id = "theme"; + link.rel = "stylesheet"; + link.href = theme; + this.appendStyleTag(link); + } + } + appendStyleTag(style) { + if (this.shadowRoot) { + this.shadowRoot.append(style); + } else { + document.head.append(style); + } + } +}; + +// src/komoju-picker-element.ts +var KomojuPickerElement = class extends Themable { + constructor() { + super(); + this.sessionChangedHandler = null; + const root = this.attachShadow({ mode: "open" }); + root.innerHTML = picker_default; + const link = document.createElement("link"); + link.rel = "stylesheet"; + link.href = `https://multipay.komoju.com/static/shared.css`; + root.append(link); + } + static get observedAttributes() { + return ["locale", "theme"]; + } + get fields() { + return this.getAttribute("fields"); + } + set fields(value) { + this.setAttribute("fields", value ?? ""); + } + get locale() { + return this.getAttribute("locale"); + } + set locale(value) { + this.setAttribute("locale", value ?? ""); + } + async connectedCallback() { + const fields = this.komojuFieldsElement(); + let handler = { + element: fields, + handler: (_evt) => { + this.render(fields); + } + }; + await this.setupPaymentTypesI18n(); + this.render(fields); + fields.addEventListener("komoju-session-change", handler.handler); + this.sessionChangedHandler = handler; + } + disconnectedCallback() { + if (this.sessionChangedHandler) { + this.sessionChangedHandler.element.removeEventListener( + "komoju-session-change", + this.sessionChangedHandler.handler + ); + } + } + async attributeChangedCallback(name, oldValue, newValue) { + if (!this.shadowRoot) + return; + if (name === "locale" && newValue && oldValue !== newValue) { + broadcastLocaleChange(this.shadowRoot, newValue); + this.updatePickerLocale(newValue); + } else if (name === "theme") { + this.applyTheme(); + } + } + komojuFieldsElement() { + if (this.fields) { + return document.querySelector(`#${this.fields}`); + } else { + return document.querySelector("komoju-fields"); + } + } + render(fields) { + if (!fields.session) + return; + if (!this.shadowRoot) + return; + const picker = this.shadowRoot.getElementById("picker"); + const template = this.shadowRoot.getElementById("radio-template"); + if (!picker) + throw new Error("KOMOJU Fields bug: wrong shadow DOM (no picker)"); + if (!template) + throw new Error("KOMOJU Fields bug: wrong shadow DOM (no template)"); + if (!this.locale) { + this.locale = fields.session.default_locale.substring(0, 2); + } + ; + this.updatePickerLocale(this.locale); + picker.replaceChildren(); + let i = 0; + for (const paymentMethod of fields.session.payment_methods) { + const moduleName = paymentMethod.offsite ? "offsite" : paymentMethod.type; + if (fields.hasAttribute("token") && !supported_payment_types_default.has(moduleName)) { + continue; + } + const radio = template.content.cloneNode(true); + const input = radio.querySelector("input"); + const icon = radio.querySelector("img"); + const text = radio.querySelector("komoju-i18n"); + if (i === 0 || fields.paymentType === paymentMethod.type) { + input.checked = true; + } + input.addEventListener("change", () => { + fields.paymentType = paymentMethod.type; + }); + setupRadioParentCheckedClass(input, this.shadowRoot); + icon.src = `${fields.komojuApi}/payment_methods/${paymentMethod.type}.svg`; + text.key = paymentMethod.type; + picker.append(radio); + i += 1; + } + if (!this.theme && fields.theme) { + this.theme = fields.theme; + this.applyTheme(); + } + } + async setupPaymentTypesI18n() { + const fields = this.komojuFieldsElement(); + const response = await komojuFetch(fields, "GET", "/api/v1/payment_methods"); + this.komojuPaymentMethods = await response.json(); + for (const method of this.komojuPaymentMethods) { + const i18n = { + en: { [method.type_slug]: method.name_en }, + ja: { [method.type_slug]: method.name_ja }, + ko: { [method.type_slug]: method.name_ko } + }; + registerMessages(i18n); + } + } + updatePickerLocale(locale) { + if (!this.shadowRoot) + return; + const picker = this.shadowRoot.getElementById("picker"); + if (picker) { + picker.setAttribute("locale", locale); + } + ; + } +}; + +// src/index.ts +window.customElements.define("komoju-fields", KomojuFieldsElement); +window.customElements.define("komoju-picker", KomojuPickerElement); +window.customElements.define("komoju-i18n", KomojuI18nElement); +window.komojuReportError = (error, context) => { + console.error(error, context); +}; +if (window.komojuErrorReporting !== false) { + (async () => { + const moduleName = "error-reporting"; + const module = await import(`https://multipay.komoju.com/extras/${moduleName}/module.js`); + window.komojuReportError = module.reportError; + })(); + const onerror = (event) => { + const komojuFieldsFiles = [ + /\/fields\.js:\d+:\d+\n/, + /\/fields\/[\w-]+\/module\.js\n:\d+:\d+/, + /\/extras\/[\w-]+\/module\.js\n:\d+:\d+/ + ]; + const error = event instanceof ErrorEvent ? event.error : event.reason; + if (!(error instanceof Error)) + return; + if (!error.stack) + return; + if (!komojuFieldsFiles.find((regex) => regex.test(error.stack))) + return; + window.komojuReportError(error); + }; + window.addEventListener("error", onerror); + window.addEventListener("unhandledrejection", onerror); +} +//# sourceMappingURL=fields.js.map diff --git a/src/app/code/Komoju/Payments/view/frontend/web/js/fields.js.map b/src/app/code/Komoju/Payments/view/frontend/web/js/fields.js.map new file mode 100644 index 000000000..959240674 --- /dev/null +++ b/src/app/code/Komoju/Payments/view/frontend/web/js/fields.js.map @@ -0,0 +1,7 @@ +{ + "version": 3, + "sources": ["../src/generated/env.ts", "../src/shared/translations.ts", "../src/i18n.ts", "../src/shared/message-broker.ts", "../src/shared/komoju-api.ts", "../src/komoju-fields-element.ts", "../src/shared/radio-helpers.ts", "../src/generated/supported-payment-types.ts", "../src/shared/komoju-i18n-element.ts", "../src/shared/themable.ts", "../src/komoju-picker-element.ts", "../src/index.ts"], + "sourcesContent": ["// Generated by bin/generate.sh\n//\n// This file pulls from environment variables (and git).\n\nexport default {\n \"CDN\": \"https://multipay.komoju.com\",\n \"ENV\": \"development\",\n \"HONEYBADGER_API_KEY\": \"\",\n \"GIT_REV\": \"99ad2eb29ce6530dedfe3a0ec34aea970dbaa78a\",\n};\n", "declare let window: WindowWithKomojuGlobals;\n\n// Call this to add messages to the registry.\n// Individual payment method modules can do this to add their own messages.\n// That way, we avoid needing to load all messages for every payment method upfront.\nexport function registerMessages(messages: I18n) {\n if (!window.komojuTranslations) {\n window.komojuTranslations = { 'en': {}, 'ja': {} };\n }\n\n for (const lang of Object.keys(window.komojuTranslations)) {\n window.komojuTranslations[lang] = {\n ...window.komojuTranslations[lang],\n ...messages[lang],\n };\n }\n}\n", "export const en = {\n 'customer-fee-will-be-charged': 'A fee of %{fee} will be included.',\n 'dynamic-currency-notice': 'Payment will be made in %{currency}: %{original} \u2192 %{converted}.',\n 'dynamic-currency-notice-with-fee': 'Payment will be made in %{currency}: %{original} \u2192 %{converted}. (total: %{total})',\n 'payment-method-unavailable': 'This payment method is currently unavailable.',\n 'verification-failed': 'Verification failed.',\n 'close': 'Close',\n};\n\nexport const ja: typeof en = {\n 'customer-fee-will-be-charged': '%{fee}\u306E\u624B\u6570\u6599\u304C\u8FFD\u52A0\u3055\u308C\u307E\u3059\u3002',\n 'dynamic-currency-notice': '\u652F\u6255\u3044\u306F%{currency}\u3067\u6C7A\u6E08\u3055\u308C\u307E\u3059: %{original} \u2192 %{converted}\u3002',\n 'dynamic-currency-notice-with-fee': '\u652F\u6255\u3044\u306F%{currency}\u3067\u6C7A\u6E08\u3055\u308C\u307E\u3059: %{original} \u2192 %{converted}\u3002(\u5408\u8A08%{total})',\n 'payment-method-unavailable': '\u3053\u306E\u652F\u6255\u3044\u65B9\u6CD5\u306F\u73FE\u5728\u3054\u5229\u7528\u3044\u305F\u3060\u3051\u307E\u305B\u3093\u3002',\n 'verification-failed': '\u8A8D\u8A3C\u306B\u5931\u6557\u3057\u307E\u3057\u305F\u3002',\n 'close': '\u9589\u3058\u308B',\n};\n", "export interface Message {\n type: string,\n}\nexport interface FullMessage extends Message {\n brokerId: string,\n id: string,\n}\n\ninterface MessageAck extends FullMessage {\n type: 'ack',\n response?: Message,\n}\n\ntype MessageBrokerArgs = { send: Window, receive: Window };\n\ntype TypedMessageListener = (arg: T) => Promise | Message | undefined | void;\ntype MessageListener = TypedMessageListener;\n\n// Wrapper around postMessage events that lets us use promises instead of\n// disjoint \"send\" and \"receive\" flows.\nexport class MessageBroker {\n // Keep track of which window to send to and which to receive on.\n // These are promises so that we can effectively buffer messages until the window is ready.\n _sendWindow: Promise;\n _receiveWindow: Promise;\n _setSendWindow?: (value: Window) => void;\n _setReceiveWindow?: (value: Window) => void;\n\n // Raw \"message\" event listener. We need to keep track of this so we can remove it later.\n messageHandler: (event: MessageEvent) => void;\n\n // Map of in-progress promises. When we receive an ack message with a matching id, we resolve the promise.\n promises: Map,\n resolve: (value?: Message) => void,\n }>;\n\n // Map of listeners. When we receive a message with a matching type, we call the listener.\n listeners: Map;\n\n // Unique id for this broker. Used to distinguish messages from other brokers.\n id: string;\n\n origin: string;\n\n constructor(id?: string) {\n this._sendWindow = new Promise(resolve => this._setSendWindow = resolve);\n this._receiveWindow = new Promise(resolve => this._setReceiveWindow = resolve);\n\n this.messageHandler = event => {\n if (this.origin !== '*' && event.origin !== this.origin) return;\n this.handleMessage(event);\n };\n\n this.id = id ?? crypto.randomUUID();\n this.origin = '*';\n this.promises = new Map();\n this.listeners = new Map();\n }\n\n // Call this to set up the broker\n setup(arg: MessageBrokerArgs) {\n if (this._setSendWindow) {\n this._setSendWindow(arg.send);\n this._setSendWindow = undefined;\n } else {\n this._sendWindow = Promise.resolve(arg.send);\n }\n\n if (this._setReceiveWindow) {\n this._setReceiveWindow(arg.receive);\n this._setReceiveWindow = undefined;\n } else {\n this._receiveWindow = Promise.resolve(arg.receive);\n }\n\n arg.receive.addEventListener('message', this.messageHandler);\n }\n\n // Call this to send a message. Promise will resolve when the associated ack message\n // comes back.\n send(message: MessageType): Promise {\n const fullMessage: FullMessage = {\n ...message,\n brokerId: this.id,\n id: crypto.randomUUID(),\n };\n\n let resolve: ((value?: Message) => void) | null = null;\n const promise = new Promise((resolvePromise, _reject) => {\n resolve = resolvePromise;\n });\n if (!resolve) throw new Error('Broker is busted');\n\n this.promises.set(fullMessage.id, { promise, resolve });\n return this._sendWindow.then(w => w.postMessage(fullMessage, this.origin)).then(() => promise);\n }\n\n // Call this to set the listener for a certain event. Kind of like the built-in\n // addEventListener, but can only add one per event type.\n receive(type: MessageType['type'], listener: TypedMessageListener) {\n this.listeners.set(type, listener as MessageListener);\n }\n\n // Internal message handler\n async handleMessage(event: MessageEvent) {\n const message = event.data;\n\n // Ignore messages from other brokers\n if (message.brokerId !== this.id) return;\n\n // 'ack' messages resolve an in-progress promise\n if (message.type === 'ack') {\n const ack = message as MessageAck;\n const promise = this.promises.get(ack.id);\n\n // Acks with a wrong ID typically come from another tag\n // in the same window.\n if (!promise) return;\n\n promise.resolve(ack.response);\n this.promises.delete(ack.id);\n }\n // all other messages trigger a local listener if present\n else {\n const listener = this.listeners.get(message.type);\n const ack: MessageAck = { type: 'ack', brokerId: this.id, id: message.id };\n if (listener) ack.response = (await listener(message)) ?? undefined;\n await this._sendWindow.then(w => w.postMessage(ack, this.origin));\n }\n }\n\n // Call this to clean up the window event listener\n destroy() {\n return this._receiveWindow.then(w => w.removeEventListener('message', this.messageHandler));\n }\n}\n", "// fetch wrapper with KOMOJU authentication already handled.\nexport function komojuFetch(\n config: {\n komojuApi: string,\n publishableKey: string | null,\n },\n method: 'GET' | 'POST',\n path: string,\n body?: object\n): Promise {\n if (!config.komojuApi) throw new Error('KOMOJU API URL is null');\n if (!config.publishableKey) throw new Error('KOMOJU publishable-key not set');\n\n return fetch(`${config.komojuApi}${path}`, {\n method,\n headers: {\n accept: 'application/json',\n 'content-type': 'application/json',\n authorization: `Basic ${btoa(`${config.publishableKey}:`)}`,\n 'komoju-via': 'fields',\n },\n body: body ? JSON.stringify(body) : undefined\n });\n}\n", "import ENV from './generated/env';\n\nimport { registerMessages } from './shared/translations';\nimport * as i18n from './i18n';\nimport { MessageBroker } from './shared/message-broker';\nimport { komojuFetch } from './shared/komoju-api';\nregisterMessages(i18n);\n\n// Language gets stored in here, mostly controlled by .\ndeclare let window: WindowWithKomojuGlobals;\n\n// This is the main entrypoint for implementers.\n// The element manages an iframe that securely hosts the KOMOJU fields UI.\n// All attributes are sent into the iframe and synced with the element.\nexport default class KomojuFieldsElement extends HTMLElement {\n static get observedAttributes() {\n console.log('KomojuFieldsElement, observedAttributes');\n\n return [\n 'komoju-api',\n 'session',\n 'session-id',\n 'publishable-key',\n 'payment-type',\n 'locale',\n 'theme',\n 'token',\n 'name',\n ];\n }\n\n // This message broker lets us communicate with the iframe using promises instead of\n // raw postMessage and addEventListener.\n broker: MessageBroker;\n\n // When a element appears inside of a
tag, we attach a submit handler to it\n // so we can seamlessly behave like an tag.\n // This formSubmitHandler lets us clean up the event listener when disconnected.\n formSubmitHandler?: {\n form: HTMLFormElement,\n target: HTMLElement, // target is different from form so we can ensure our event gets called first\n handler: (event: Event) => void\n };\n _submitting: boolean = false;\n\n session: KomojuSession | null = null;\n\n dialog: HTMLDialogElement;\n\n get theme() {\n return this.getAttribute('theme');\n }\n set theme(value) {\n this.setAttribute('theme', value ?? '');\n }\n\n get komojuApi() {\n return this.getAttribute('komoju-api') ?? 'https://komoju.com';\n }\n set komojuApi(value) {\n this.setAttribute('komoju-api', value);\n }\n\n // To keep manual submit() calls idempotent, we hold onto the token from our last\n // (and presumably only) successful submit.\n token?: string;\n\n constructor() {\n super();\n this.broker = new MessageBroker();\n this.dialog = document.createElement('dialog');\n this.listenToMessagesFromIframe(this.broker);\n\n this.dialog.style.width = '80%';\n this.dialog.style.height = '80%';\n this.dialog.style.padding = '0';\n }\n\n // When connected, we want to find the form that this element is in and attach a submit handler to it.\n connectedCallback() {\n const iframeParams = new URLSearchParams();\n iframeParams.append('broker', this.broker.id);\n if (this.hasAttribute('komoju-api')) {\n iframeParams.append('api', this.getAttribute('komoju-api')!);\n }\n\n // Set up our fields host iframe.\n const iframe = document.createElement('iframe') as HTMLIFrameElement;\n iframe.setAttribute('sandbox', 'allow-scripts allow-same-origin');\n iframe.setAttribute('allow', 'payment *');\n iframe.title = 'KOMOJU secure payment fields';\n iframe.src = `${ENV.CDN}/fields-iframe.html#${iframeParams.toString()}`;\n iframe.style.border = 'none';\n iframe.style.width = '100%';\n iframe.style.overflow = 'hidden';\n iframe.height = '50';\n iframe.addEventListener('load', () => {\n if (!iframe.contentWindow) throw new Error('KOMOJU Fields: iframe had no contentWindow');\n // Set up our message broker now that the iframe is loaded.\n this.broker.setup({\n send: iframe.contentWindow,\n receive: window,\n });\n });\n this.replaceChildren(iframe, this.dialog);\n\n // Crudely search for parent element until it is a form tag.\n let parent = this.parentElement;\n while (parent && parent.tagName !== 'FORM') {\n parent = parent.parentElement;\n }\n // It's OK if we can't find a parent form tag.\n // Implementers can call submit() manually on this element.\n if (!parent) return;\n const form = parent as HTMLFormElement;\n\n // We set the event target to the form's parent to ensure that our handler is called first.\n // This works because of capturing. Capturing events are called on parents *before* target.\n const target = form.parentElement;\n if (!target) return;\n\n const handler = (event: Event) => {\n if (this._submitting) return;\n // Make sure this komoju-fields element is visible.\n if (this.offsetParent === null) return;\n // Make sure this event is for the right form element.\n if (event.target !== form) return;\n\n event.preventDefault();\n event.stopImmediatePropagation();\n\n this.submit(event);\n };\n target.addEventListener('submit', handler, true);\n this.formSubmitHandler = { form, target, handler };\n }\n\n // When disconnected, we want to remove the submit handler from the form (if added).\n disconnectedCallback() {\n if (this.formSubmitHandler) {\n this.formSubmitHandler.target.removeEventListener('submit', this.formSubmitHandler.handler, true);\n this.formSubmitHandler = undefined;\n }\n\n this.broker.destroy();\n }\n\n // Receive messages from the iframe.\n listenToMessagesFromIframe(broker: MessageBroker) {\n // The iframe will sometimes ask us to dispatch an event.\n broker.receive('dispatch-event', (message) => {\n const event = new CustomEvent(message.name, {\n detail: message.detail,\n bubbles: true,\n composed: true,\n cancelable: true,\n });\n\n // Sync own session with iframe session.\n // This way implementers can always access the latest session from the komoju-fields element\n // in case they want to know what payment methods are supported, etc.\n if (message.name === 'komoju-session-change') {\n this.session = message.detail.session as KomojuSession;\n }\n\n const result: KomojuDispatchResult = {\n type: 'dispatch-result',\n cancel: !this.dispatchEvent(event)\n }\n\n return result;\n });\n\n // The iframe tells us how much height its content has so that we can resize it seamlessly.\n broker.receive('resize', (message) => {\n const iframe = this.querySelector('iframe') as HTMLIFrameElement;\n iframe.height = message.height;\n });\n\n broker.receive('dialog-start', async (message) => {\n const result: KomojuDialogResult = {\n type: 'dialog-result',\n result: await this.show3DSDialog(message.url),\n };\n return result;\n });\n }\n\n // Reactive attribute handling. Send all attrs to the iframe so that they are synced with the komoju-host element.\n async attributeChangedCallback(name: string, _oldValue: string | null, newValue: string | null) {\n console.log('KomojuFieldsElement, oldValue?', name, _oldValue);\n console.log('###')\n console.log('KomojuFieldsElement, attributeChangedCallback', name, newValue);\n\n this.broker.send({\n type: 'attr',\n attr: name,\n value: newValue,\n });\n }\n\n // Consumers may call this to submit the form.\n // If the 'token' attribute is set, this will return the token response from KOMOJU.\n async submit(event?: Event): Promise {\n if (this.token) return JSON.parse(this.token);\n\n // Ask the iframe to submit.\n const submitResult = await this.broker.send({ type: 'submit' });\n if (submitResult?.type !== 'submit-result') {\n throw new Error(`Unexpected submit response from komoju-fields iframe ${JSON.stringify(submitResult)}`);\n }\n const result = submitResult as KomojuSubmitResult;\n\n // On error, emit a komoju-invalid event in case consumers want to handle it.\n if (result.errors) {\n this.dispatchEvent(new CustomEvent('komoju-invalid', {\n detail: { errors: result.errors }, bubbles: true, composed: true,\n }));\n return;\n }\n\n // On payment success, redirect.\n if (result.pay) {\n if (!result.pay.error) await this.handlePayResult(result.pay);\n return;\n }\n\n // If this is part of a form submit, we want to add the token to the form and resubmit.\n if (result.token && event && this.formSubmitHandler) {\n const form = this.formSubmitHandler.form;\n\n // Now we add an input to the form with the token and submit it.\n const inputName = this.getAttribute('name') ?? 'komoju_token';\n let input = document.querySelector(`input[name=\"${inputName}\"]`) as HTMLInputElement | null;\n if (!input) {\n input = document.createElement('input');\n input.type = 'hidden';\n input.name = inputName;\n form.append(input);\n }\n input.value = result.token.id;\n\n // Re-submit the form without our submit event getting in the way.\n this.submitParentForm();\n return;\n }\n\n // Token submission.\n if (result.token) {\n this.token = JSON.stringify(result.token);\n return result.token;\n }\n\n throw new Error(\"KOMOJU Fields bug: submit result was not handled\");\n }\n\n // After submit in a standard integration, we will usually just redirect.\n // But there's a special case where we show instructions, e.g. for konbini and bank transfer.\n async handlePayResult(payResult: KomojuPayResult) {\n const session = this.session;\n if (!session) throw new Error(\"handlePayResult called without a session\");\n\n const instructions = payResult.payment?.payment_details?.instructions_url;\n\n if (instructions) {\n const returnURL = new URL(session.return_url ?? session.session_url);\n returnURL.searchParams.append('session_id', session.id);\n this.showInstructionsDialog(instructions, returnURL.toString());\n } else if (payResult.redirect_url) {\n window.location.href = payResult.redirect_url;\n } else {\n throw new Error(`payResult should have a redirect_url but doesnt ${JSON.stringify(payResult)}`);\n }\n }\n\n // Removes our form submit override and submits the parent form directly.\n async submitParentForm() {\n if (!this.formSubmitHandler) throw new Error('KOMOJU Fields: tried to submit nonexistent parent form');\n const form = this.formSubmitHandler.form;\n\n // Re-submit the form without our submit event getting in the way.\n try {\n // This _submitting flag should prevent infinite recursion.\n this._submitting = true;\n const submitEvent = new Event('submit', { bubbles: true, cancelable: true });\n if (form.dispatchEvent(submitEvent)) {\n form.submit();\n } else {\n this.broker.send({ type: 'end-fade' });\n }\n } finally {\n this._submitting = false;\n }\n }\n\n showInstructionsDialog(url: string, finishURL: string) {\n const dialog = this.dialog;\n\n const iframe = createIframe(url);\n iframe.style.height = '90%';\n\n const closeButton = document.createElement('a');\n const closeText = document.createElement('komoju-i18n') as KomojuI18nElement;\n closeText.key = 'close';\n closeButton.append(closeText);\n closeButton.classList.add('komoju-fields-close-dialog');\n closeButton.href = finishURL;\n closeButton.style.display = 'block';\n closeButton.style.padding = '10px';\n\n dialog.replaceChildren(\n closeButton,\n iframe,\n );\n dialog.showModal();\n }\n\n show3DSDialog(url: string): Promise {\n return new Promise((resolve, reject) => {\n const dialog = this.dialog;\n const origin = ENV['CDN'];\n\n const iframe = createIframe(url);\n\n window.addEventListener('message', async (event) => {\n if (event.origin !== origin) return;\n\n try {\n if (!event.data?._komojuFields) return;\n\n const { secureTokenId } = event.data;\n if (!secureTokenId) throw new Error('No secureTokenId in message');\n\n const credentials = {\n komojuApi: this.komojuApi,\n publishableKey: this.getAttribute('publishable-key') ?? '',\n };\n const secureTokenResponse = await komojuFetch(credentials, 'GET', `/api/v1/secure_tokens/${secureTokenId}`);\n if (secureTokenResponse.status >= 400) {\n const error = await secureTokenResponse.json() as KomojuApiError;\n resolve({ error });\n return;\n }\n const secureToken = await secureTokenResponse.json() as KomojuSecureToken;\n\n dialog.close();\n resolve({ secureToken });\n } catch (e) {\n reject(e);\n }\n });\n\n dialog.replaceChildren(iframe);\n dialog.showModal();\n });\n }\n}\n\n// Set up dynamic properties for each observed attribute, to support e.g.\n// const fields = document.querySelector('komoju-fields');\n// fields.sessionId = 'abc123';\nfor (const attr of KomojuFieldsElement.observedAttributes) {\n // A few special cases here.\n if (attr === 'session' || attr === 'theme' || attr === 'komoju-api') continue;\n\n Object.defineProperty(KomojuFieldsElement.prototype, camelCase(attr), {\n get() {\n return this.getAttribute(attr);\n },\n set(value) {\n if (value === null) this.removeAttribute(attr);\n else this.setAttribute(attr, value);\n },\n });\n}\n\nfunction camelCase(str: string) {\n return str\n .split('-')\n .reduce((a, b) => a + b.charAt(0).toUpperCase() + b.slice(1));\n}\n\nfunction createIframe(url: string): HTMLIFrameElement {\n const iframe = document.createElement('iframe');\n iframe.setAttribute(\n 'sandbox',\n 'allow-scripts allow-forms allow-same-origin'\n );\n iframe.src = url;\n iframe.style.border = 'none';\n iframe.style.width = '100%';\n iframe.style.height = '100%';\n return iframe;\n}", "interface QuerySelectorAll {\n querySelectorAll: HTMLElement['querySelectorAll']\n}\n\n// Add .checked to the parent .radio element when the input is checked.\n// This is just to make the CSS a little easier, since we're putting the\n// input inside of the label.\nexport function setupRadioParentCheckedClass(input: HTMLInputElement, root: QuerySelectorAll) {\n // Some sanity checks\n if (!input.parentElement) {\n throw new Error('KOMOJU Fields bug: radio input has no parent');\n }\n if (!input.parentElement.classList.contains('radio')) {\n throw new Error('KOMOJU Fields bug: radio input parent has no .radio class');\n }\n\n // Initialize the checked class\n if (input.checked) {\n input.parentElement.classList.add('checked');\n }\n\n // Set checked class then checked\n input.addEventListener('change', () => {\n root.querySelectorAll('.radio.checked').forEach((el) => el.classList.remove('checked'));\n input.parentElement!.classList.add('checked');\n });\n}\n", "// Generated by bin/generate.sh\n//\n// List of supported payment types comes from the folders in src/fields/*.\n// To add a new one, simply add a new folder.\n\nconst supported: Set = new Set();\nsupported.add('bank_transfer');\nsupported.add('credit_card');\nsupported.add('konbini');\nsupported.add('offsite');\nexport default supported;\n", "// Language gets stored in here, mostly controlled by .\ndeclare let window: WindowWithKomojuGlobals;\n\nconst defaultLanguage = 'en';\n\ntype Queryable = {\n querySelectorAll: Document['querySelectorAll'];\n};\n\nexport function broadcastLocaleChange(root: Queryable, locale: string) {\n root.querySelectorAll('komoju-i18n').forEach((element) => {\n const i18n = element as KomojuI18nElement;\n i18n.render(locale);\n });\n}\n\n// This is a element that we use internally for displaying translated text\nexport default class KomojuI18nElement extends HTMLElement {\n static get observedAttributes() {\n return ['key'];\n }\n\n // Attribute: key\n // The key of the translation to display.\n get key() {\n return this.getAttribute('key');\n }\n set key(value) {\n this.setAttribute('key', value ?? '');\n }\n\n connectedCallback() {\n this.render();\n }\n\n attributeChangedCallback(name: string, _oldValue: string, _newValue: string) {\n if (name === 'key') this.render();\n }\n\n // Search up the DOM until we find a parent element with a locale attribute.\n findLocale() {\n let parent = this.parentElement;\n while (parent && !parent.getAttribute('locale')) {\n parent = parent.parentElement;\n }\n return parent?.getAttribute('locale') ?? defaultLanguage;\n }\n\n render(locale?: string) {\n if (!this.key) return;\n\n if (!locale) locale = this.findLocale();\n if (!Object.keys(window.komojuTranslations).includes(locale)) locale = defaultLanguage;\n\n const lang = locale.substring(0, 2);\n\n const message = window.komojuTranslations[lang][this.key];\n if (!message) {\n console.error(`KOMOJU bug: missing translation for key: ${this.key}`);\n return;\n }\n\n // Perform interpolation\n const matches = message.match(/%\\{[\\w-]+\\}/g);\n if (matches) {\n let result = message;\n matches.forEach((match) => {\n const key = match.replace(/%{|}/g, '');\n const value = this.dataset[key];\n if (value) result = result.replace(match, value);\n });\n this.textContent = result;\n return;\n }\n\n this.textContent = message;\n }\n}\n", "export default class Themable extends HTMLElement {\n // Attribute: theme\n // CSS file to use as a theme.\n get theme() {\n return this.getAttribute('theme');\n }\n set theme(value) {\n this.setAttribute('theme', value ?? '');\n }\n\n applyTheme() {\n const root = this.shadowRoot ?? document;\n\n if (this.theme === null) {\n root.querySelectorAll('#theme,#inline-theme').forEach(el => el.remove());\n } else if (this.theme.startsWith('http') || this.theme.startsWith('/') || this.theme.startsWith('data:')) {\n this.applyExternalTheme(root, this.theme);\n } else {\n this.applyInlineTheme(root, this.theme);\n }\n }\n\n applyInlineTheme(root: ParentNode, theme: string) {\n root.querySelectorAll('#theme,#inline-theme').forEach(el => el.remove());\n\n const style = document.createElement('style');\n style.id = 'inline-theme';\n style.textContent = theme;\n this.appendStyleTag(style);\n }\n\n applyExternalTheme(root: ParentNode, theme: string) {\n root.querySelectorAll('#inline-theme').forEach(el => el.remove());\n let link = root.querySelector('#theme') as HTMLLinkElement | null;\n if (link) {\n if (link.href !== this.theme) link.href = theme;\n } else {\n link = document.createElement('link');\n link.id = 'theme';\n link.rel = 'stylesheet';\n link.href = theme;\n this.appendStyleTag(link);\n }\n }\n\n appendStyleTag(style: HTMLLinkElement | HTMLStyleElement) {\n if (this.shadowRoot) {\n this.shadowRoot.append(style);\n }\n else {\n document.head.append(style);\n }\n }\n}\n", "import ENV from './generated/env';\n\nimport template from './picker.html';\nimport { setupRadioParentCheckedClass } from './shared/radio-helpers';\nimport { registerMessages } from './shared/translations';\nimport { komojuFetch } from './shared/komoju-api';\nimport supportedPaymentTypes from './generated/supported-payment-types';\nimport { broadcastLocaleChange } from './shared/komoju-i18n-element';\nimport Themable from './shared/themable';\n\ntype ChangedHandler = {\n element: KomojuFieldsConfig,\n handler: (event: Event) => void,\n};\n\nexport default class KomojuPickerElement extends Themable {\n static get observedAttributes() {\n return [ 'locale', 'theme' ];\n }\n\n // Attribute: fields\n // DOM ID of element that this picker is associated with.\n // When blank, will just update all elements.\n get fields() {\n return this.getAttribute('fields');\n }\n set fields(value) {\n this.setAttribute('fields', value ?? '');\n }\n\n // Attribute: locale\n // Locale to use for payment method names.\n get locale() {\n return this.getAttribute('locale');\n }\n set locale(value) {\n this.setAttribute('locale', value ?? '');\n }\n\n komojuPaymentMethods?: Array\n\n // This picker element piggy-backs on the element's session and locale.\n sessionChangedHandler: ChangedHandler | null = null\n\n constructor() {\n super();\n const root = this.attachShadow({ mode: 'open' });\n root.innerHTML = template;\n\n // Set base CSS\n const link = document.createElement('link');\n link.rel = 'stylesheet';\n link.href = `https://multipay.komoju.com/static/shared.css`;\n root.append(link);\n }\n\n async connectedCallback() {\n const fields = this.komojuFieldsElement();\n let handler = {\n element: fields,\n handler: (_evt: Event) => { this.render(fields); },\n };\n\n await this.setupPaymentTypesI18n();\n this.render(fields);\n fields.addEventListener('komoju-session-change', handler.handler);\n this.sessionChangedHandler = handler;\n }\n\n disconnectedCallback() {\n if (this.sessionChangedHandler) {\n this.sessionChangedHandler.element.removeEventListener(\n 'komoju-session-change',\n this.sessionChangedHandler.handler\n );\n }\n }\n\n async attributeChangedCallback(name: string, oldValue: string | null, newValue: string | null) {\n if (!this.shadowRoot) return;\n\n if (name === 'locale' && newValue && oldValue !== newValue) {\n broadcastLocaleChange(this.shadowRoot, newValue);\n this.updatePickerLocale(newValue);\n }\n else if (name === 'theme') {\n this.applyTheme();\n }\n }\n\n komojuFieldsElement() {\n if (this.fields) {\n return document.querySelector(`#${this.fields}`) as KomojuFieldsConfig;\n }\n else {\n return document.querySelector('komoju-fields') as KomojuFieldsConfig;\n }\n }\n\n render(fields: KomojuFieldsConfig) {\n if (!fields.session) return;\n if (!this.shadowRoot) return;\n\n const picker = this.shadowRoot.getElementById('picker');\n const template = this.shadowRoot.getElementById('radio-template') as HTMLTemplateElement;\n if (!picker) throw new Error('KOMOJU Fields bug: wrong shadow DOM (no picker)');\n if (!template) throw new Error('KOMOJU Fields bug: wrong shadow DOM (no template)');\n\n // If locale hasn't been set on directly, use session default_locale.\n if (!this.locale) {\n this.locale = fields.session.default_locale.substring(0, 2);\n };\n\n this.updatePickerLocale(this.locale)\n\n // Clear the picker.\n picker.replaceChildren();\n\n let i = 0;\n for (const paymentMethod of fields.session.payment_methods) {\n const moduleName = paymentMethod.offsite ? 'offsite' : paymentMethod.type;\n\n // Token mode cannot handle payment methods that aren't explicitly supported, so we won't\n // show them on the picker.\n if (fields.hasAttribute('token') && !supportedPaymentTypes.has(moduleName)) {\n continue;\n }\n\n const radio = template.content.cloneNode(true) as HTMLElement;\n const input = radio.querySelector('input') as HTMLInputElement;\n const icon = radio.querySelector('img') as HTMLImageElement;\n const text = radio.querySelector('komoju-i18n') as KomojuI18nElement;\n\n if (i === 0 || fields.paymentType === paymentMethod.type) {\n input.checked = true;\n }\n input.addEventListener('change', () => {\n fields.paymentType = paymentMethod.type;\n });\n setupRadioParentCheckedClass(input, this.shadowRoot);\n\n icon.src = `${fields.komojuApi}/payment_methods/${paymentMethod.type}.svg`;\n text.key = paymentMethod.type;\n\n picker.append(radio);\n\n i += 1;\n }\n\n // Set user-defined theme\n if (!this.theme && fields.theme) {\n this.theme = fields.theme;\n this.applyTheme();\n }\n }\n\n // To keep things dynamic, we pull payment method translations from KOMOJU.\n private async setupPaymentTypesI18n() {\n const fields = this.komojuFieldsElement();\n const response = await komojuFetch(fields, 'GET', '/api/v1/payment_methods');\n this.komojuPaymentMethods = await response.json();\n\n // Convert the \"name_en\", \"name_ja\" etc into { \"en\": { \"\": \"\" } }.\n for (const method of this.komojuPaymentMethods!) {\n const i18n = {\n en: { [method.type_slug]: method.name_en },\n ja: { [method.type_slug]: method.name_ja },\n ko: { [method.type_slug]: method.name_ko },\n };\n registerMessages(i18n);\n }\n }\n\n // Update the locale of the shadow DOM parent element. This allows children to\n // determine the locale.\n private updatePickerLocale(locale: string) {\n if (!this.shadowRoot) return;\n const picker = this.shadowRoot.getElementById('picker');\n if (picker) { picker.setAttribute('locale', locale) };\n }\n}\n", "import './types.d';\nimport KomojuFieldsElement from './komoju-fields-element';\nimport KomojuPickerElement from './komoju-picker-element';\nimport KomojuI18nElement from './shared/komoju-i18n-element';\ndeclare let window: WindowWithKomojuGlobals;\n\n// Public custom elements\nwindow.customElements.define('komoju-fields', KomojuFieldsElement);\nwindow.customElements.define('komoju-picker', KomojuPickerElement);\nwindow.customElements.define('komoju-i18n', KomojuI18nElement);\n\n// Error reporting\nwindow.komojuReportError = (error, context) => {\n console.error(error, context);\n}\nif (window.komojuErrorReporting !== false) {\n // Import proper error reporting module (Honeybadger) if implementer hasn't disabled it\n (async () => {\n // HACK: unnecessary interpolation because of typescript not knowing the type of the import\n // This is a dynamic import because it means implementers who don't want it can opt out of\n // a very large chunk of JS.\n const moduleName = 'error-reporting';\n const module = await import(`https://multipay.komoju.com/extras/${moduleName}/module.js`);\n window.komojuReportError = module.reportError;\n })();\n\n // Catch errors (only ones that involve KomojuFields)\n const onerror = (event: ErrorEvent | PromiseRejectionEvent) => {\n const komojuFieldsFiles = [\n /\\/fields\\.js:\\d+:\\d+\\n/,\n /\\/fields\\/[\\w-]+\\/module\\.js\\n:\\d+:\\d+/,\n /\\/extras\\/[\\w-]+\\/module\\.js\\n:\\d+:\\d+/,\n ];\n\n const error = (event instanceof ErrorEvent) ? event.error : (event.reason as Error);\n\n if (!(error instanceof Error)) return;\n if (!error.stack) return;\n if (!komojuFieldsFiles.find((regex) => regex.test(error.stack!))) return;\n\n window.komojuReportError(error);\n };\n\n window.addEventListener('error', onerror);\n window.addEventListener('unhandledrejection', onerror);\n}\n"], + "mappings": "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", + "names": [] +} diff --git a/src/app/code/Komoju/Payments/view/frontend/web/js/fields/bank_transfer/module.js b/src/app/code/Komoju/Payments/view/frontend/web/js/fields/bank_transfer/module.js new file mode 100644 index 000000000..9f49905bc --- /dev/null +++ b/src/app/code/Komoju/Payments/view/frontend/web/js/fields/bank_transfer/module.js @@ -0,0 +1,303 @@ +var __defProp = Object.defineProperty; +var __export = (target, all) => { + for (var name in all) + __defProp(target, name, { get: all[name], enumerable: true }); +}; + +// src/fields/bank_transfer/template.html +var template_default = '
\n \n\n \n\n \n\n \n\n \n\n \n
\n\n
    \n
\n\n\n\n\n'; + +// src/shared/validation.ts +function addValidation(_i18n, input, callback) { + input.classList.add("has-validation"); + input.addEventListener("input", () => { + input.dataset.validationDirty = "true"; + }); + const validate = (event) => { + const input2 = event.target; + const errorMessageKey = callback(input2); + if (errorMessageKey) { + showError(_i18n, input2, errorMessageKey); + } + }; + input.addEventListener("blur", (event) => { + if (input.dataset.validationDirty !== "true") + return; + else + return validate(event); + }); + input.addEventListener("validate", validate); + input.addEventListener("focus", (event) => { + const input2 = event.target; + clearErrors(input2); + }); +} +function showError(_i18n, input, messageKey) { + input.classList.add("invalid"); + const key = messageKey; + const container = input.parentElement; + const dupeSelector = `komoju-error:not(.removing) > komoju-i18n[key="${key}"]`; + if (container?.querySelector(dupeSelector)) { + return; + } + container?.append(createErrorElement(messageKey)); +} +function clearErrors(input) { + input.classList.remove("invalid"); + input.parentElement?.querySelectorAll("komoju-error:not(.removing)").forEach((element) => { + element.remove(); + }); +} +function createErrorElement(messageKey) { + const el = window.document.createElement("komoju-error"); + const i18nEl = window.document.createElement("komoju-i18n"); + i18nEl.key = messageKey; + el.appendChild(i18nEl); + return el; +} + +// src/shared/translations.ts +function registerMessages(messages) { + if (!window.komojuTranslations) { + window.komojuTranslations = { "en": {}, "ja": {} }; + } + for (const lang of Object.keys(window.komojuTranslations)) { + window.komojuTranslations[lang] = { + ...window.komojuTranslations[lang], + ...messages[lang] + }; + } +} + +// src/fields/bank_transfer/i18n.ts +var i18n_exports = {}; +__export(i18n_exports, { + en: () => en, + ja: () => ja +}); +var en = { + "bt.label.lastname": "Last name", + "bt.label.firstname": "First name", + "bt.label.lastname-kana": "Last name (kana)", + "bt.label.firstname-kana": "First name (kana)", + "bt.label.email": "Email address", + "bt.label.phone": "Phone number", + "bt.error.required": "Required" +}; +var ja = { + "bt.label.lastname": "\u59D3", + "bt.label.firstname": "\u540D", + "bt.label.lastname-kana": "\u59D3 (\u30AB\u30BF\u30AB\u30CA)", + "bt.label.firstname-kana": "\u540D (\u30AB\u30BF\u30AB\u30CA)", + "bt.label.email": "\u30E1\u30FC\u30EB\u30A2\u30C9\u30EC\u30B9", + "bt.label.phone": "\u96FB\u8A71\u756A\u53F7", + "bt.error.required": "\u5FC5\u9808\u9805\u76EE\u3067\u3059" +}; + +// src/shared/char-width-utils.ts +var conversionMap = { + \u30AC: "\uFF76\uFF9E", + \u30AE: "\uFF77\uFF9E", + \u30B0: "\uFF78\uFF9E", + \u30B2: "\uFF79\uFF9E", + \u30B4: "\uFF7A\uFF9E", + \u30B6: "\uFF7B\uFF9E", + \u30B8: "\uFF7C\uFF9E", + \u30BA: "\uFF7D\uFF9E", + \u30BC: "\uFF7E\uFF9E", + \u30BE: "\uFF7F\uFF9E", + \u30C0: "\uFF80\uFF9E", + \u30C2: "\uFF81\uFF9E", + \u30C5: "\uFF82\uFF9E", + \u30C7: "\uFF83\uFF9E", + \u30C9: "\uFF84\uFF9E", + \u30D0: "\uFF8A\uFF9E", + \u30D3: "\uFF8B\uFF9E", + \u30D6: "\uFF8C\uFF9E", + \u30D9: "\uFF8D\uFF9E", + \u30DC: "\uFF8E\uFF9E", + \u30D1: "\uFF8A\uFF9F", + \u30D4: "\uFF8B\uFF9F", + \u30D7: "\uFF8C\uFF9F", + \u30DA: "\uFF8D\uFF9F", + \u30DD: "\uFF8E\uFF9F", + \u30F4: "\uFF73\uFF9E", + \u30F7: "\uFF9C\uFF9E", + \u30FA: "\uFF66\uFF9E", + \u30A2: "\uFF71", + \u30A4: "\uFF72", + \u30A6: "\uFF73", + \u30A8: "\uFF74", + \u30AA: "\uFF75", + \u30AB: "\uFF76", + \u30AD: "\uFF77", + \u30AF: "\uFF78", + \u30B1: "\uFF79", + \u30B3: "\uFF7A", + \u30B5: "\uFF7B", + \u30B7: "\uFF7C", + \u30B9: "\uFF7D", + \u30BB: "\uFF7E", + \u30BD: "\uFF7F", + \u30BF: "\uFF80", + \u30C1: "\uFF81", + \u30C4: "\uFF82", + \u30C6: "\uFF83", + \u30C8: "\uFF84", + \u30CA: "\uFF85", + \u30CB: "\uFF86", + \u30CC: "\uFF87", + \u30CD: "\uFF88", + \u30CE: "\uFF89", + \u30CF: "\uFF8A", + \u30D2: "\uFF8B", + \u30D5: "\uFF8C", + \u30D8: "\uFF8D", + \u30DB: "\uFF8E", + \u30DE: "\uFF8F", + \u30DF: "\uFF90", + \u30E0: "\uFF91", + \u30E1: "\uFF92", + \u30E2: "\uFF93", + \u30E4: "\uFF94", + \u30E6: "\uFF95", + \u30E8: "\uFF96", + \u30E9: "\uFF97", + \u30EA: "\uFF98", + \u30EB: "\uFF99", + \u30EC: "\uFF9A", + \u30ED: "\uFF9B", + \u30EF: "\uFF9C", + \u30F2: "\uFF66", + \u30F3: "\uFF9D", + \u30A1: "\uFF67", + \u30A3: "\uFF68", + \u30A5: "\uFF69", + \u30A7: "\uFF6A", + \u30A9: "\uFF6B", + \u30C3: "\uFF6F", + \u30E3: "\uFF6C", + \u30E5: "\uFF6D", + \u30E7: "\uFF6E", + "\u3002": "\uFF61", + "\u3001": "\uFF64", + \u30FC: "\uFF70", + "\u2212": "-", + "\uFF08": "(", + "\uFF09": ")", + "\u300C": "\uFF62", + "\u300D": "\uFF63", + "\u30FB": "\uFF65", + "\u3000": " ", + \uFF21: "A", + \uFF22: "B", + \uFF23: "C", + \uFF24: "D", + \uFF25: "E", + \uFF26: "F", + \uFF27: "G", + \uFF28: "H", + \uFF29: "I", + \uFF2A: "J", + \uFF2B: "K", + \uFF2C: "L", + \uFF2D: "M", + \uFF2E: "N", + \uFF2F: "O", + \uFF30: "P", + \uFF31: "Q", + \uFF32: "R", + \uFF33: "S", + \uFF34: "T", + \uFF35: "U", + \uFF36: "V", + \uFF37: "W", + \uFF38: "X", + \uFF39: "Y", + \uFF3A: "Z", + \uFF41: "a", + \uFF42: "b", + \uFF43: "c", + \uFF44: "d", + \uFF45: "e", + \uFF46: "f", + \uFF47: "g", + \uFF48: "h", + \uFF49: "i", + \uFF4A: "j", + \uFF4B: "k", + \uFF4C: "l", + \uFF4D: "m", + \uFF4E: "n", + \uFF4F: "o", + \uFF50: "p", + \uFF51: "q", + \uFF52: "r", + \uFF53: "s", + \uFF54: "t", + \uFF55: "u", + \uFF56: "v", + \uFF57: "w", + \uFF58: "x", + \uFF59: "y", + \uFF5A: "z", + "\uFF10": "0", + "\uFF11": "1", + "\uFF12": "2", + "\uFF13": "3", + "\uFF14": "4", + "\uFF15": "5", + "\uFF16": "6", + "\uFF17": "7", + "\uFF18": "8", + "\uFF19": "9" +}; +function convertCharsToHalfWidth(str) { + const convertedChars = str.split("").map((char) => { + return conversionMap[char] ?? char; + }); + return convertedChars.join(""); +} + +// src/fields/bank_transfer/module.ts +registerMessages(i18n_exports); +var render = (root, paymentMethod) => { + root.innerHTML = template_default; + root.querySelectorAll("input").forEach((element) => { + addValidation(i18n_exports, element, (input) => { + if (input.value === "") + return "bt.error.required"; + return null; + }); + }); + root.querySelectorAll(".kana").forEach((element) => { + element.addEventListener("input", (event) => { + const input = event.target; + if (input.dataset.ime === "active") + return; + input.value = convertCharsToHalfWidth(input.value); + }); + }); +}; +var paymentDetails = (root, _paymentMethod) => { + const firstname = root.querySelector("#bt-firstname"); + const lastname = root.querySelector("#bt-lastname"); + const firstnameKana = root.querySelector("#bt-firstname-kana"); + const lastnameKana = root.querySelector("#bt-lastname-kana"); + const email = root.querySelector("#bt-email"); + const phone = root.querySelector("#bt-phone"); + return { + type: "bank_transfer", + email: email.value, + family_name: lastname.value, + family_name_kana: lastnameKana.value, + given_name: firstname.value, + given_name_kana: firstnameKana.value, + phone: phone.value + }; +}; +export { + paymentDetails, + render +}; +//# sourceMappingURL=module.js.map diff --git a/src/app/code/Komoju/Payments/view/frontend/web/js/fields/bank_transfer/module.js.map b/src/app/code/Komoju/Payments/view/frontend/web/js/fields/bank_transfer/module.js.map new file mode 100644 index 000000000..68aa3b3b7 --- /dev/null +++ b/src/app/code/Komoju/Payments/view/frontend/web/js/fields/bank_transfer/module.js.map @@ -0,0 +1,7 @@ +{ + "version": 3, + "sources": ["../../../src/shared/validation.ts", "../../../src/shared/translations.ts", "../../../src/fields/bank_transfer/i18n.ts", "../../../src/shared/char-width-utils.ts", "../../../src/fields/bank_transfer/module.ts"], + "sourcesContent": ["// Adds validation to an input element.\nexport function addValidation(\n _i18n: Translations, // Used only by typescript to compile-time catch missing translations.\n input: HTMLInputElement,\n callback: (input: HTMLInputElement) => keyof Translations['en'] | null\n) {\n // Add a class so that we know this input has validation.\n input.classList.add('has-validation');\n\n // Tiny detail: if the user has never inputted anything, we don't want to run validations at all\n // at the risk of showing an error message when the user is just clicking around.\n input.addEventListener('input', () => {\n input.dataset.validationDirty = 'true';\n });\n\n // Validation function. This will be called on 'blur' and also on a custom 'validate' event.\n const validate = (event: Event) => {\n const input = event.target as HTMLInputElement;\n\n const errorMessageKey = callback(input);\n\n if (errorMessageKey) {\n showError(_i18n, input, errorMessageKey);\n }\n };\n input.addEventListener('blur', (event) => {\n if (input.dataset.validationDirty !== 'true') return;\n else return validate(event);\n });\n input.addEventListener('validate', validate);\n\n // When the user focuses on the input, remove all error artifacts.\n input.addEventListener('focus', (event) => {\n const input = event.target as HTMLInputElement;\n clearErrors(input);\n });\n}\n\nexport function showError(\n _i18n: Translations, // Used only by typescript to compile-time catch missing translations.\n input: HTMLInputElement,\n messageKey: keyof Translations['en']\n) {\n input.classList.add('invalid');\n const key = messageKey as string;\n\n // We don't want to show the same error twice!\n const container = input.parentElement;\n const dupeSelector = `komoju-error:not(.removing) > komoju-i18n[key=\"${key}\"]`;\n if (container?.querySelector(dupeSelector)) {\n return;\n }\n\n container?.append(createErrorElement(messageKey as string));\n}\n\nexport function clearErrors(input: HTMLInputElement) {\n input.classList.remove('invalid');\n input.parentElement?.querySelectorAll('komoju-error:not(.removing)').forEach((element) => {\n element.remove();\n });\n}\n\n// Runs validations on an element.\nexport function runValidation(input: HTMLInputElement) {\n // Fire the 'validate' custom event.\n input.dispatchEvent(new CustomEvent('validate'));\n\n // If there's an error message, return it.\n const errorMessage = input.parentElement?.querySelector('komoju-error:not(.removing)')?.textContent;\n return errorMessage ?? null;\n}\n\n// Creates the error message element that appears under an invalid input.\n// Mainly just called by addValidation().\nexport function createErrorElement(messageKey: string) {\n const el = window.document.createElement('komoju-error');\n const i18nEl = window.document.createElement('komoju-i18n') as KomojuI18nElement;\n i18nEl.key = messageKey;\n el.appendChild(i18nEl);\n return el;\n}\n", "declare let window: WindowWithKomojuGlobals;\n\n// Call this to add messages to the registry.\n// Individual payment method modules can do this to add their own messages.\n// That way, we avoid needing to load all messages for every payment method upfront.\nexport function registerMessages(messages: I18n) {\n if (!window.komojuTranslations) {\n window.komojuTranslations = { 'en': {}, 'ja': {} };\n }\n\n for (const lang of Object.keys(window.komojuTranslations)) {\n window.komojuTranslations[lang] = {\n ...window.komojuTranslations[lang],\n ...messages[lang],\n };\n }\n}\n", "export const en = {\n 'bt.label.lastname': 'Last name',\n 'bt.label.firstname': 'First name',\n 'bt.label.lastname-kana': 'Last name (kana)',\n 'bt.label.firstname-kana': 'First name (kana)',\n 'bt.label.email': 'Email address',\n 'bt.label.phone': 'Phone number',\n 'bt.error.required': 'Required',\n};\n\nexport const ja: typeof en = {\n 'bt.label.lastname': '\u59D3',\n 'bt.label.firstname': '\u540D',\n 'bt.label.lastname-kana': '\u59D3 (\u30AB\u30BF\u30AB\u30CA)',\n 'bt.label.firstname-kana': '\u540D (\u30AB\u30BF\u30AB\u30CA)',\n 'bt.label.email': '\u30E1\u30FC\u30EB\u30A2\u30C9\u30EC\u30B9',\n 'bt.label.phone': '\u96FB\u8A71\u756A\u53F7',\n 'bt.error.required': '\u5FC5\u9808\u9805\u76EE\u3067\u3059',\n};\n", "const conversionMap: any = {\n \u30AC: '\uFF76\uFF9E',\n \u30AE: '\uFF77\uFF9E',\n \u30B0: '\uFF78\uFF9E',\n \u30B2: '\uFF79\uFF9E',\n \u30B4: '\uFF7A\uFF9E',\n \u30B6: '\uFF7B\uFF9E',\n \u30B8: '\uFF7C\uFF9E',\n \u30BA: '\uFF7D\uFF9E',\n \u30BC: '\uFF7E\uFF9E',\n \u30BE: '\uFF7F\uFF9E',\n \u30C0: '\uFF80\uFF9E',\n \u30C2: '\uFF81\uFF9E',\n \u30C5: '\uFF82\uFF9E',\n \u30C7: '\uFF83\uFF9E',\n \u30C9: '\uFF84\uFF9E',\n \u30D0: '\uFF8A\uFF9E',\n \u30D3: '\uFF8B\uFF9E',\n \u30D6: '\uFF8C\uFF9E',\n \u30D9: '\uFF8D\uFF9E',\n \u30DC: '\uFF8E\uFF9E',\n \u30D1: '\uFF8A\uFF9F',\n \u30D4: '\uFF8B\uFF9F',\n \u30D7: '\uFF8C\uFF9F',\n \u30DA: '\uFF8D\uFF9F',\n \u30DD: '\uFF8E\uFF9F',\n \u30F4: '\uFF73\uFF9E',\n \u30F7: '\uFF9C\uFF9E',\n \u30FA: '\uFF66\uFF9E',\n \u30A2: '\uFF71',\n \u30A4: '\uFF72',\n \u30A6: '\uFF73',\n \u30A8: '\uFF74',\n \u30AA: '\uFF75',\n \u30AB: '\uFF76',\n \u30AD: '\uFF77',\n \u30AF: '\uFF78',\n \u30B1: '\uFF79',\n \u30B3: '\uFF7A',\n \u30B5: '\uFF7B',\n \u30B7: '\uFF7C',\n \u30B9: '\uFF7D',\n \u30BB: '\uFF7E',\n \u30BD: '\uFF7F',\n \u30BF: '\uFF80',\n \u30C1: '\uFF81',\n \u30C4: '\uFF82',\n \u30C6: '\uFF83',\n \u30C8: '\uFF84',\n \u30CA: '\uFF85',\n \u30CB: '\uFF86',\n \u30CC: '\uFF87',\n \u30CD: '\uFF88',\n \u30CE: '\uFF89',\n \u30CF: '\uFF8A',\n \u30D2: '\uFF8B',\n \u30D5: '\uFF8C',\n \u30D8: '\uFF8D',\n \u30DB: '\uFF8E',\n \u30DE: '\uFF8F',\n \u30DF: '\uFF90',\n \u30E0: '\uFF91',\n \u30E1: '\uFF92',\n \u30E2: '\uFF93',\n \u30E4: '\uFF94',\n \u30E6: '\uFF95',\n \u30E8: '\uFF96',\n \u30E9: '\uFF97',\n \u30EA: '\uFF98',\n \u30EB: '\uFF99',\n \u30EC: '\uFF9A',\n \u30ED: '\uFF9B',\n \u30EF: '\uFF9C',\n \u30F2: '\uFF66',\n \u30F3: '\uFF9D',\n \u30A1: '\uFF67',\n \u30A3: '\uFF68',\n \u30A5: '\uFF69',\n \u30A7: '\uFF6A',\n \u30A9: '\uFF6B',\n \u30C3: '\uFF6F',\n \u30E3: '\uFF6C',\n \u30E5: '\uFF6D',\n \u30E7: '\uFF6E',\n '\u3002': '\uFF61',\n '\u3001': '\uFF64',\n \u30FC: '\uFF70',\n '\u2212': '-',\n '\uFF08': '(',\n '\uFF09': ')',\n '\u300C': '\uFF62',\n '\u300D': '\uFF63',\n '\u30FB': '\uFF65',\n '\u3000': ' ',\n \uFF21: 'A',\n \uFF22: 'B',\n \uFF23: 'C',\n \uFF24: 'D',\n \uFF25: 'E',\n \uFF26: 'F',\n \uFF27: 'G',\n \uFF28: 'H',\n \uFF29: 'I',\n \uFF2A: 'J',\n \uFF2B: 'K',\n \uFF2C: 'L',\n \uFF2D: 'M',\n \uFF2E: 'N',\n \uFF2F: 'O',\n \uFF30: 'P',\n \uFF31: 'Q',\n \uFF32: 'R',\n \uFF33: 'S',\n \uFF34: 'T',\n \uFF35: 'U',\n \uFF36: 'V',\n \uFF37: 'W',\n \uFF38: 'X',\n \uFF39: 'Y',\n \uFF3A: 'Z',\n \uFF41: 'a',\n \uFF42: 'b',\n \uFF43: 'c',\n \uFF44: 'd',\n \uFF45: 'e',\n \uFF46: 'f',\n \uFF47: 'g',\n \uFF48: 'h',\n \uFF49: 'i',\n \uFF4A: 'j',\n \uFF4B: 'k',\n \uFF4C: 'l',\n \uFF4D: 'm',\n \uFF4E: 'n',\n \uFF4F: 'o',\n \uFF50: 'p',\n \uFF51: 'q',\n \uFF52: 'r',\n \uFF53: 's',\n \uFF54: 't',\n \uFF55: 'u',\n \uFF56: 'v',\n \uFF57: 'w',\n \uFF58: 'x',\n \uFF59: 'y',\n \uFF5A: 'z',\n '\uFF10': '0',\n '\uFF11': '1',\n '\uFF12': '2',\n '\uFF13': '3',\n '\uFF14': '4',\n '\uFF15': '5',\n '\uFF16': '6',\n '\uFF17': '7',\n '\uFF18': '8',\n '\uFF19': '9'\n};\n\nexport function convertCharsToHalfWidth(str: string) {\n const convertedChars = str.split('').map(char => {\n return conversionMap[char] ?? char;\n });\n\n return convertedChars.join('');\n}\n\nexport function convertNumbersToHalfWidth(str: string) {\n var fullwidth = '\uFF10\uFF11\uFF12\uFF13\uFF14\uFF15\uFF16\uFF17\uFF18\uFF19\uFF0F';\n var halfwidth = '0123456789/';\n\n for (var i = 0; i < 10; ++i) {\n str = str.replace(\n new RegExp(fullwidth.charAt(i), 'g'),\n halfwidth.charAt(i)\n );\n }\n\n return str;\n}\n", "import '../../types.d';\n// @ts-ignore\nimport html from './template.html'\n\nimport { addValidation } from '../../shared/validation';\nimport { registerMessages } from '../../shared/translations';\nimport * as i18n from './i18n';\nimport { convertCharsToHalfWidth } from '../../shared/char-width-utils';\nregisterMessages(i18n);\n\nexport const render: KomojuRenderFunction = (root, paymentMethod) => {\n root.innerHTML = html;\n\n // All fields are required.\n root.querySelectorAll('input').forEach(element => {\n addValidation(i18n, element, (input) => {\n if (input.value === '') return 'bt.error.required';\n return null;\n });\n });\n\n // Automatically convert full-width kana to half-width.\n root.querySelectorAll('.kana').forEach(element => {\n element.addEventListener('input', (event) => {\n const input = event.target as HTMLInputElement;\n\n // This \"ime\" data comes from komoju-host-element.ts. It lets us avoid messing up\n // customer input during IME composition.\n if (input.dataset.ime === 'active') return;\n\n input.value = convertCharsToHalfWidth(input.value);\n });\n });\n}\n\nexport const paymentDetails: KomojuPaymentDetailsFunction = (root, _paymentMethod) => {\n const firstname = root.querySelector('#bt-firstname')! as HTMLInputElement;\n const lastname = root.querySelector('#bt-lastname')! as HTMLInputElement;\n const firstnameKana = root.querySelector('#bt-firstname-kana')! as HTMLInputElement;\n const lastnameKana = root.querySelector('#bt-lastname-kana')! as HTMLInputElement;\n const email = root.querySelector('#bt-email')! as HTMLInputElement;\n const phone = root.querySelector('#bt-phone')! as HTMLInputElement;\n\n return {\n type: 'bank_transfer',\n email: email.value,\n family_name: lastname.value,\n family_name_kana: lastnameKana.value,\n given_name: firstname.value,\n given_name_kana: firstnameKana.value,\n phone: phone.value,\n }\n}\n"], + "mappings": "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AA,EACH,QAAG;AAAA,EACH,QAAG;AAAA,EACH,QAAG;AAAA,EACH,QAAG;AAAA,EACH,QAAG;AAAA,EACH,QAAG;AAAA,EACH,QAAG;AAAA,EACH,QAAG;AAAA,EACH,QAAG;AAAA,EACH,QAAG;AAAA,EACH,QAAG;AAAA,EACH,QAAG;AAAA,EACH,QAAG;AAAA,EACH,QAAG;AAAA,EACH,QAAG;AAAA,EACH,QAAG;AAAA,EACH,QAAG;AAAA,EACH,QAAG;AAAA,EACH,QAAG;AAAA,EACH,QAAG;AAAA,EACH,QAAG;AAAA,EACH,QAAG;AAAA,EACH,QAAG;AAAA,EACH,QAAG;AAAA,EACH,QAAG;AAAA,EACH,QAAG;AAAA,EACH,QAAG;AAAA,EACH,QAAG;AAAA,EACH,QAAG;AAAA,EACH,UAAK;AAAA,EACL,UAAK;AAAA,EACL,QAAG;AAAA,EACH,UAAK;AAAA,EACL,UAAK;AAAA,EACL,UAAK;AAAA,EACL,UAAK;AAAA,EACL,UAAK;AAAA,EACL,UAAK;AAAA,EACL,UAAK;AAAA,EACL,QAAG;AAAA,EACH,QAAG;AAAA,EACH,QAAG;AAAA,EACH,QAAG;AAAA,EACH,QAAG;AAAA,EACH,QAAG;AAAA,EACH,QAAG;AAAA,EACH,QAAG;AAAA,EACH,QAAG;AAAA,EACH,QAAG;AAAA,EACH,QAAG;AAAA,EACH,QAAG;AAAA,EACH,QAAG;AAAA,EACH,QAAG;AAAA,EACH,QAAG;AAAA,EACH,QAAG;AAAA,EACH,QAAG;AAAA,EACH,QAAG;AAAA,EACH,QAAG;AAAA,EACH,QAAG;AAAA,EACH,QAAG;AAAA,EACH,QAAG;AAAA,EACH,QAAG;AAAA,EACH,QAAG;AAAA,EACH,QAAG;AAAA,EACH,QAAG;AAAA,EACH,QAAG;AAAA,EACH,QAAG;AAAA,EACH,QAAG;AAAA,EACH,QAAG;AAAA,EACH,QAAG;AAAA,EACH,QAAG;AAAA,EACH,QAAG;AAAA,EACH,QAAG;AAAA,EACH,QAAG;AAAA,EACH,QAAG;AAAA,EACH,QAAG;AAAA,EACH,QAAG;AAAA,EACH,QAAG;AAAA,EACH,QAAG;AAAA,EACH,QAAG;AAAA,EACH,QAAG;AAAA,EACH,QAAG;AAAA,EACH,QAAG;AAAA,EACH,QAAG;AAAA,EACH,QAAG;AAAA,EACH,QAAG;AAAA,EACH,QAAG;AAAA,EACH,QAAG;AAAA,EACH,QAAG;AAAA,EACH,QAAG;AAAA,EACH,QAAG;AAAA,EACH,UAAK;AAAA,EACL,UAAK;AAAA,EACL,UAAK;AAAA,EACL,UAAK;AAAA,EACL,UAAK;AAAA,EACL,UAAK;AAAA,EACL,UAAK;AAAA,EACL,UAAK;AAAA,EACL,UAAK;AAAA,EACL,UAAK;AACP;AAEO,SAAS,wBAAwB,KAAa;AACnD,QAAM,iBAAiB,IAAI,MAAM,EAAE,EAAE,IAAI,UAAQ;AAC/C,WAAO,cAAc,SAAS;AAAA,EAChC,CAAC;AAED,SAAO,eAAe,KAAK,EAAE;AAC/B;;;AC5JA,iBAAiB,YAAI;AAEd,IAAM,SAA+B,CAAC,MAAM,kBAAkB;AACnE,OAAK,YAAY;AAGjB,OAAK,iBAAiB,OAAO,EAAE,QAAQ,aAAW;AAChD,kBAAc,cAAM,SAAS,CAAC,UAAU;AACtC,UAAI,MAAM,UAAU;AAAI,eAAO;AAC/B,aAAO;AAAA,IACT,CAAC;AAAA,EACH,CAAC;AAGD,OAAK,iBAAiB,OAAO,EAAE,QAAQ,aAAW;AAChD,YAAQ,iBAAiB,SAAS,CAAC,UAAU;AAC3C,YAAM,QAAQ,MAAM;AAIpB,UAAI,MAAM,QAAQ,QAAQ;AAAU;AAEpC,YAAM,QAAQ,wBAAwB,MAAM,KAAK;AAAA,IACnD,CAAC;AAAA,EACH,CAAC;AACH;AAEO,IAAM,iBAA+C,CAAC,MAAM,mBAAmB;AACpF,QAAM,YAAY,KAAK,cAAc,eAAe;AACpD,QAAM,WAAW,KAAK,cAAc,cAAc;AAClD,QAAM,gBAAgB,KAAK,cAAc,oBAAoB;AAC7D,QAAM,eAAe,KAAK,cAAc,mBAAmB;AAC3D,QAAM,QAAQ,KAAK,cAAc,WAAW;AAC5C,QAAM,QAAQ,KAAK,cAAc,WAAW;AAE5C,SAAO;AAAA,IACL,MAAM;AAAA,IACN,OAAO,MAAM;AAAA,IACb,aAAa,SAAS;AAAA,IACtB,kBAAkB,aAAa;AAAA,IAC/B,YAAY,UAAU;AAAA,IACtB,iBAAiB,cAAc;AAAA,IAC/B,OAAO,MAAM;AAAA,EACf;AACF;", + "names": ["input"] +} diff --git a/src/app/code/Komoju/Payments/view/frontend/web/js/fields/credit_card/module.js b/src/app/code/Komoju/Payments/view/frontend/web/js/fields/credit_card/module.js new file mode 100644 index 000000000..3ad5aed1c --- /dev/null +++ b/src/app/code/Komoju/Payments/view/frontend/web/js/fields/credit_card/module.js @@ -0,0 +1,500 @@ +var __defProp = Object.defineProperty; +var __export = (target, all) => { + for (var name in all) + __defProp(target, name, { get: all[name], enumerable: true }); +}; + +// src/fields/credit_card/komoju-field-icon.html +var komoju_field_icon_default = '
\n
\n\n\n'; + +// src/fields/credit_card/komoju-field-icon-element.ts +var _KomojuFieldIconElement = class extends HTMLElement { + constructor() { + super(); + this.visibleIcons = []; + const root = this.attachShadow({ mode: "open" }); + root.innerHTML = komoju_field_icon_default; + } + static get observedAttributes() { + return ["icon", "for"]; + } + get target() { + const targetId = this.getAttribute("for"); + const root = this.getRootNode(); + if (!targetId || !root || !root["querySelector"]) + return void 0; + else + return root.querySelector(`#${targetId}`); + } + set target(target) { + if (target) + this.setAttribute("for", target.id); + else + this.setAttribute("for", ""); + } + get icon() { + return this.getAttribute("icon") || ""; + } + set icon(value) { + this.setAttribute("icon", value); + } + connectedCallback() { + this.style.width = "0"; + this.style.height = "0"; + const parent = this.parentElement; + if (!parent) + return; + this.resizeObserver = new ResizeObserver(() => { + this.reposition(); + }); + this.resizeObserver.observe(parent); + this.reposition(); + setTimeout(() => this.reposition(), 100); + } + disconnectedCallback() { + this.resizeObserver?.disconnect(); + this.resizeObserver = void 0; + } + attributeChangedCallback(name, oldValue, newValue) { + if (name === "icon") { + const container = this.shadowRoot?.getElementById("komoju-field-icon"); + if (!container) + throw new Error("KOMOJU Fields bug: field icon container missing"); + if (oldValue === newValue) + return; + const icons = newValue.split(/\s+/); + this.updateVisibleIcons(icons); + } else if (name === "for") { + this.reposition(); + } + } + updateVisibleIcons(icons) { + const container = this.shadowRoot?.getElementById("komoju-field-icon"); + const target = this.target; + if (!target || !container) + return; + const iconsWidth = icons.length * (_KomojuFieldIconElement.ICON_WIDTH + _KomojuFieldIconElement.ICON_GAP); + const maxWidth = target.offsetWidth / 2; + if (iconsWidth > maxWidth) { + const hiddenIconIndex = Math.floor(maxWidth / (_KomojuFieldIconElement.ICON_WIDTH + _KomojuFieldIconElement.ICON_GAP)); + const allIcons = icons; + icons = icons.slice(0, hiddenIconIndex); + if (this.iconSwapTimeout) + clearTimeout(this.iconSwapTimeout); + this.iconSwapTimeout = setTimeout(() => { + let carry = allIcons[hiddenIconIndex - 1]; + for (let i = hiddenIconIndex - 1; i < allIcons.length - 1; i += 1) { + const temp = allIcons[i + 1]; + allIcons[i + 1] = carry; + carry = temp; + } + allIcons[hiddenIconIndex - 1] = carry; + this.updateVisibleIcons(allIcons); + }, _KomojuFieldIconElement.ICON_SWAP_INTERVAL); + } else if (this.iconSwapTimeout) { + clearTimeout(this.iconSwapTimeout); + this.iconSwapTimeout = void 0; + } + const oldIcons = this.visibleIcons; + const newIcons = icons; + if (oldIcons === newIcons) + return; + const removedIcons = oldIcons.filter((icon) => !newIcons.includes(icon)); + this.visibleIcons = icons; + for (const icon of newIcons) { + const existing = container.querySelector(`img[src="${icon}"]`); + if (existing) { + existing.style.opacity = "1"; + continue; + } + const img = document.createElement("img"); + img.src = icon; + img.width = _KomojuFieldIconElement.ICON_WIDTH; + container.append(img); + img.style.opacity = "0"; + setTimeout(() => img.style.opacity = "1", 100); + } + for (const icon of removedIcons) { + const img = container.querySelector(`img[src="${icon}"]`); + img.style.opacity = "0"; + img.style.marginRight = "0"; + } + let position = 0; + for (let i = this.visibleIcons.length - 1; i >= 0; i -= 1) { + const icon = this.visibleIcons[i]; + const img = container.querySelector(`img[src="${icon}"]`); + img.style.marginRight = `${position * (_KomojuFieldIconElement.ICON_WIDTH + _KomojuFieldIconElement.ICON_GAP)}px`; + position += 1; + } + } + reposition() { + const parent = this.parentElement; + const target = this.target; + const container = this.shadowRoot?.getElementById("komoju-field-icon"); + if (!target || !parent || !container) + return; + container.style.top = `${target.offsetTop}px`; + container.style.right = `${parent.offsetWidth - target.offsetWidth - target.offsetLeft}px`; + container.style.height = `${target.offsetHeight}px`; + const targetStyle = window.getComputedStyle(target); + container.style.paddingRight = targetStyle.paddingRight; + container.style.paddingTop = targetStyle.paddingTop; + container.style.paddingBottom = targetStyle.paddingBottom; + const icons = this.getAttribute("icon")?.split(/\s+/) || []; + this.updateVisibleIcons(icons); + } +}; +var KomojuFieldIconElement = _KomojuFieldIconElement; +KomojuFieldIconElement.ICON_WIDTH = 42; +KomojuFieldIconElement.ICON_GAP = 4; +KomojuFieldIconElement.ICON_SWAP_INTERVAL = 5e3; + +// src/fields/credit_card/template.html +var template_default = '
\n \n\n \n\n \n\n \n
\n\n
    \n
\n\n\n\n\n'; + +// src/shared/char-width-utils.ts +function convertNumbersToHalfWidth(str) { + var fullwidth = "\uFF10\uFF11\uFF12\uFF13\uFF14\uFF15\uFF16\uFF17\uFF18\uFF19\uFF0F"; + var halfwidth = "0123456789/"; + for (var i = 0; i < 10; ++i) { + str = str.replace( + new RegExp(fullwidth.charAt(i), "g"), + halfwidth.charAt(i) + ); + } + return str; +} + +// src/shared/validation.ts +function addValidation(_i18n, input, callback) { + input.classList.add("has-validation"); + input.addEventListener("input", () => { + input.dataset.validationDirty = "true"; + }); + const validate = (event) => { + const input2 = event.target; + const errorMessageKey = callback(input2); + if (errorMessageKey) { + showError(_i18n, input2, errorMessageKey); + } + }; + input.addEventListener("blur", (event) => { + if (input.dataset.validationDirty !== "true") + return; + else + return validate(event); + }); + input.addEventListener("validate", validate); + input.addEventListener("focus", (event) => { + const input2 = event.target; + clearErrors(input2); + }); +} +function showError(_i18n, input, messageKey) { + input.classList.add("invalid"); + const key = messageKey; + const container = input.parentElement; + const dupeSelector = `komoju-error:not(.removing) > komoju-i18n[key="${key}"]`; + if (container?.querySelector(dupeSelector)) { + return; + } + container?.append(createErrorElement(messageKey)); +} +function clearErrors(input) { + input.classList.remove("invalid"); + input.parentElement?.querySelectorAll("komoju-error:not(.removing)").forEach((element) => { + element.remove(); + }); +} +function createErrorElement(messageKey) { + const el = window.document.createElement("komoju-error"); + const i18nEl = window.document.createElement("komoju-i18n"); + i18nEl.key = messageKey; + el.appendChild(i18nEl); + return el; +} + +// src/fields/credit_card/card-number-utils.ts +function cardTypeToKomojuSubtype(type) { + if (type === "amex") + return "american_express"; + if (type === "diner") + return "diners_club"; + if (type === "jcb15") + return "jcb"; + if (type === "mastercard") + return "master"; + return type; +} +function insertSpaceEvery4Characters(str) { + return str.replace(/(.{4})/g, "$1 ").trim(); +} +function cardNumberMaxLength(type) { + if (type == "diner") { + return 16; + } else if (type == "amex") { + return 17; + } else { + return 23; + } +} +function formatCardNumber(value, type) { + if (type == "unknown" || type == "visa" || type == "jcb" || type == "mastercard") { + return insertSpaceEvery4Characters(value); + } else { + return value.replace(/(.{4})/, "$1 ").replace(/(.{11})/, "$1 ").trim(); + } +} +function removeNonDigits(value) { + return value.replace(/[^0-9( \/ )]+/g, ""); +} +function insertSlash(value) { + const hasSlash = value.includes("/"); + const hasFullMonth = value.length >= 2; + if (hasFullMonth && !hasSlash) { + let yearStart = value.lastIndexOf(" "); + if (yearStart === -1) + yearStart = 2; + const month = value.slice(0, 2); + const year = value.slice(yearStart, value.length); + return `${month} / ${year}`; + } + return value; +} +function removeSlash(value) { + return value.endsWith("/") ? value.replace(/[^0-9]+/g, "") : value; +} +var cardTypeRegex = { + amex: /^3[47]\d{0,13}/, + diner: /^3(?:0([0-5]|9)|[689]\d?)\d{0,11}/, + mastercard: /^(5[1-5]\d{0,2}|22[2-9]\d{0,1}|2[3-7]\d{0,2})\d{0,12}/, + jcb15: /^(?:2131|1800)\d{0,11}/, + jcb: /^(?:35)\d{0,17}/, + visa: /^4\d{0,18}/ +}; +function cardType(value) { + if (cardTypeRegex.amex.exec(value)) { + return "amex"; + } else if (cardTypeRegex.diner.exec(value)) { + return "diner"; + } else if (cardTypeRegex.mastercard.exec(value)) { + return "mastercard"; + } else if (cardTypeRegex.jcb15.exec(value)) { + return "jcb15"; + } else if (cardTypeRegex.jcb.exec(value)) { + return "jcb"; + } else if (cardTypeRegex.visa.exec(value)) { + return "visa"; + } else { + return "unknown"; + } +} +function luhnCheck(cardNumber) { + if (/[^0-9\s]+/.test(cardNumber)) { + return false; + } + let sum = 0; + let shouldDouble = false; + cardNumber = cardNumber.replace(/\D/g, ""); + const length = cardNumber.length; + for (let i = length - 1; i >= 0; --i) { + let digit = parseInt(cardNumber.charAt(i), 10); + if (shouldDouble && (digit *= 2) > 9) { + digit -= 9; + } + sum += digit; + shouldDouble = !shouldDouble; + } + return sum % 10 === 0; +} + +// src/shared/translations.ts +function registerMessages(messages) { + if (!window.komojuTranslations) { + window.komojuTranslations = { "en": {}, "ja": {} }; + } + for (const lang of Object.keys(window.komojuTranslations)) { + window.komojuTranslations[lang] = { + ...window.komojuTranslations[lang], + ...messages[lang] + }; + } +} + +// src/fields/credit_card/i18n.ts +var i18n_exports = {}; +__export(i18n_exports, { + en: () => en, + ja: () => ja +}); +var en = { + "cc.label.cardholder-name": "Cardholder name", + "cc.label.card-number": "Card number", + "cc.label.expiration": "Expiration", + "cc.label.cvc": "CVC", + "cc.error.required": "Required", + "cc.error.incomplete": "Please input the full expiration date", + "cc.error.please_use_half_width": "Please use half-width characters", + "cc.error.invalid-number": "Invalid number", + "cc.error.expired": "Card is expired", + "cc.error.invalid-month": "Month must be between 1 and 12", + "cc.error.unsupported-brand": "Unsupported card brand" +}; +var ja = { + "cc.label.cardholder-name": "\u30AB\u30FC\u30C9\u6240\u6709\u8005\u540D", + "cc.label.card-number": "\u30AB\u30FC\u30C9\u756A\u53F7", + "cc.label.expiration": "\u6709\u52B9\u671F\u9650", + "cc.label.cvc": "\u30BB\u30AD\u30E5\u30EA\u30C6\u30A3\u30B3\u30FC\u30C9", + "cc.error.required": "\u5FC5\u9808\u9805\u76EE\u3067\u3059", + "cc.error.incomplete": "\u6709\u52B9\u671F\u9650\u3092\u6B63\u3057\u304F\u5165\u529B\u3057\u3066\u304F\u3060\u3055\u3044", + "cc.error.please_use_half_width": "\u534A\u89D2\u82F1\u6570\u5B57\u30FB\u8A18\u53F7\u306E\u307F\u6709\u52B9\u3067\u3059", + "cc.error.invalid-number": "\u30AB\u30FC\u30C9\u756A\u53F7\u304C\u6B63\u3057\u304F\u3042\u308A\u307E\u305B\u3093", + "cc.error.expired": "\u30AB\u30FC\u30C9\u306E\u6709\u52B9\u671F\u9650\u304C\u5207\u308C\u3066\u3044\u307E\u3059", + "cc.error.invalid-month": "\u6708\u306F1\u304B\u308912\u306E\u9593\u3067\u5165\u529B\u3057\u3066\u304F\u3060\u3055\u3044", + "cc.error.unsupported-brand": "\u5BFE\u5FDC\u3057\u3066\u3044\u306A\u3044\u30AF\u30EC\u30B8\u30C3\u30C8\u30AB\u30FC\u30C9\u30D6\u30E9\u30F3\u30C9\u3067\u3059" +}; + +// src/fields/credit_card/module.ts +registerMessages(i18n_exports); +window.customElements.define("komoju-field-icon", KomojuFieldIconElement); +var render = (root, paymentMethod) => { + root.innerHTML = template_default; + initializeInputs( + root, + paymentMethod + ); +}; +function initializeInputs(root, paymentMethod) { + const name = document.getElementById("cc-name"); + addValidation(i18n_exports, name, (input) => { + if (input.value === "") + return "cc.error.required"; + if (/[^\x01-\x7E]/.test(input.value)) + return "cc.error.please_use_half_width"; + return null; + }); + const cardIcon = document.getElementById("cc-icon"); + const defaultCardImage = `${root.komojuCdn}/static/credit_card_number.svg`; + const supportedBrandImages = paymentMethod.brands.map((brand) => { + return `https://komoju.com/payment_methods/credit_card.svg?brands=${brand}`; + }).join(" "); + cardIcon.icon = supportedBrandImages; + const number = document.getElementById("cc-number"); + number.addEventListener("input", (event) => { + const input = event.target; + if (input.dataset.ime === "active") + return; + let value = input.value; + value = convertNumbersToHalfWidth(value).replace(/\D/g, ""); + if (value.length === 0) { + clearErrors(input); + } + const type = cardType(value); + input.maxLength = cardNumberMaxLength(type); + input.value = formatCardNumber(value, type); + input.dataset.brand = type; + const brand = cardTypeToKomojuSubtype(type); + if (type === "unknown") { + if (value.length < 3) { + cardIcon.icon = supportedBrandImages; + } else { + cardIcon.icon = defaultCardImage; + } + } else if (paymentMethod.brands.includes(brand)) { + cardIcon.icon = `https://komoju.com/payment_methods/credit_card.svg?brands=${brand}`; + clearErrors(input); + } else { + cardIcon.icon = supportedBrandImages; + showError(i18n_exports, input, "cc.error.unsupported-brand"); + } + }); + addValidation(i18n_exports, number, (input) => { + const value = input.value.replace(/\D/g, ""); + if (value === "") + return "cc.error.required"; + if (!luhnCheck(value)) + return "cc.error.invalid-number"; + const type = cardType(value); + const brand = cardTypeToKomojuSubtype(type); + if (type === "unknown") + return "cc.error.unsupported-brand"; + if (!paymentMethod.brands.includes(brand)) + return "cc.error.unsupported-brand"; + return null; + }); + const exp = document.getElementById("cc-exp"); + let lastExpValue = exp.value; + exp.addEventListener("input", (event) => { + const input = event.target; + if (input.dataset.ime === "active") + return; + let value = convertNumbersToHalfWidth(input.value); + const addedNewCharacter = value.length > lastExpValue.length; + value = removeNonDigits(value); + value = addedNewCharacter ? insertSlash(value) : removeSlash(value); + input.value = value; + lastExpValue = value; + }); + exp.addEventListener("blur", (event) => { + const input = event.target; + if (input.dataset.ime === "inactive") { + let value = convertNumbersToHalfWidth(input.value); + value = removeNonDigits(value); + value = insertSlash(value); + input.value = value; + lastExpValue = value; + } + }); + addValidation(i18n_exports, exp, (input) => { + const mmyy = input.value.replace(/[^0-9\/]/g, ""); + const [month, year] = mmyy.split("/"); + if (month == null || year == null || year.length !== 2 || month.length !== 2 || !/^\d{2}\/\d{2}$/.test(mmyy)) { + return "cc.error.incomplete"; + } + const now = new Date(); + const currentYear = parseInt( + now.getFullYear().toString().substr(2, 2) + ); + const currentMonth = now.getMonth() + 1; + const monthNum = parseInt(month); + const yearNum = parseInt(year); + if (yearNum < currentYear) { + return "cc.error.expired"; + } + if (yearNum === currentYear && monthNum < currentMonth) { + return "cc.error.expired"; + } + if (monthNum > 12 || monthNum <= 0) { + return "cc.error.invalid-month"; + } + return null; + }); + const cvcIcon = document.getElementById("cc-cvc-icon"); + cvcIcon.icon = `${root.komojuCdn}/static/credit_card_cvc.svg`; + const cvc = document.getElementById("cc-cvc"); + addValidation(i18n_exports, cvc, (input) => { + if (input.value === "") + return "cc.error.required"; + return null; + }); +} +var paymentDetails = (root, _paymentMethod) => { + const name = root.querySelector("#cc-name"); + const number = root.querySelector("#cc-number"); + const expiration = root.querySelector("#cc-exp"); + const cvc = root.querySelector("#cc-cvc"); + const [month, year] = expiration.value.split("/").map((s) => s.trim()); + return { + type: "credit_card", + name: name.value, + number: number.value.replace(/\s+/g, ""), + month, + year, + verification_value: cvc.value + }; +}; +export { + paymentDetails, + render +}; +//# sourceMappingURL=module.js.map diff --git a/src/app/code/Komoju/Payments/view/frontend/web/js/fields/credit_card/module.js.map b/src/app/code/Komoju/Payments/view/frontend/web/js/fields/credit_card/module.js.map new file mode 100644 index 000000000..e20f9dbb8 --- /dev/null +++ b/src/app/code/Komoju/Payments/view/frontend/web/js/fields/credit_card/module.js.map @@ -0,0 +1,7 @@ +{ + "version": 3, + "sources": ["../../../src/fields/credit_card/komoju-field-icon-element.ts", "../../../src/shared/char-width-utils.ts", "../../../src/shared/validation.ts", "../../../src/fields/credit_card/card-number-utils.ts", "../../../src/shared/translations.ts", "../../../src/fields/credit_card/i18n.ts", "../../../src/fields/credit_card/module.ts"], + "sourcesContent": ["// @ts-ignore\nimport html from './komoju-field-icon.html'\n\n// This element is only used for credit card.\n//\n// It lets us show the brand icons on the right side of an input element\n// without requiring sensitive DOM structure and CSS.\n//\n// Not having to worry about the DOM structure and CSS makes it easier to\n// allow custom CSS to be applied to the input elements.\nexport default class KomojuFieldIconElement extends HTMLElement {\n static ICON_WIDTH = 42;\n static ICON_GAP = 4;\n static ICON_SWAP_INTERVAL = 5000;\n\n static get observedAttributes() {\n return ['icon', 'for'];\n }\n\n // The element that this icon is for. Probably always an element.\n get target() {\n const targetId = this.getAttribute('for');\n const root = this.getRootNode() as HTMLElement;\n if (!targetId || !root || !root['querySelector']) return undefined;\n else return root.querySelector(`#${targetId}`) as HTMLElement;\n }\n set target(target: HTMLElement | undefined) {\n if (target) this.setAttribute('for', target.id);\n else this.setAttribute('for', '');\n }\n\n get icon() {\n return this.getAttribute('icon') || '';\n }\n set icon(value: string) {\n this.setAttribute('icon', value);\n }\n\n resizeObserver?: ResizeObserver;\n\n // When there's too many icons to fit in the container, we hide some of them.\n // The 'icons' attribute holds the full list of icons, and 'visibleIcons' holds\n // the list of icons that are currently visible.\n visibleIcons: string[] = [];\n\n // When we truncate icons, we want to show the hidden icons one at a time.\n iconSwapTimeout?: unknown;\n\n constructor() {\n super();\n const root = this.attachShadow({ mode: 'open' });\n root.innerHTML = html;\n }\n\n connectedCallback() {\n this.style.width = '0';\n this.style.height = '0';\n\n const parent = this.parentElement;\n if (!parent) return;\n\n this.resizeObserver = new ResizeObserver(() => {\n this.reposition();\n });\n this.resizeObserver!.observe(parent);\n this.reposition();\n setTimeout(() => this.reposition(), 100);\n }\n\n disconnectedCallback() {\n this.resizeObserver?.disconnect();\n this.resizeObserver = undefined;\n }\n \n attributeChangedCallback(name: string, oldValue: string | null, newValue: string) {\n if (name === 'icon') {\n const container = this.shadowRoot?.getElementById('komoju-field-icon');\n if (!container) throw new Error('KOMOJU Fields bug: field icon container missing');\n if (oldValue === newValue) return;\n\n const icons = newValue.split(/\\s+/);\n this.updateVisibleIcons(icons);\n }\n else if (name === 'for') {\n this.reposition();\n }\n }\n\n // Sometimes there can be too many icons and they cover the input field.\n // To account for this, we will hide some icons and then cycle through the hidden ones,\n // showing them one at a time.\n updateVisibleIcons(icons: string[]) {\n const container = this.shadowRoot?.getElementById('komoju-field-icon');\n const target = this.target;\n if (!target || !container) return;\n\n // If icons will be more than half of the target input's width, we'll chop some icons.\n const iconsWidth = icons.length * (KomojuFieldIconElement.ICON_WIDTH + KomojuFieldIconElement.ICON_GAP);\n const maxWidth = target.offsetWidth / 2;\n if (iconsWidth > maxWidth) {\n const hiddenIconIndex = Math.floor(maxWidth / (KomojuFieldIconElement.ICON_WIDTH + KomojuFieldIconElement.ICON_GAP));\n const allIcons = icons;\n icons = icons.slice(0, hiddenIconIndex);\n\n // Here we set up a setTimeout to show the hidden icons one by one.\n // This is recursive - we will call updateVisibleIcons again to rotate the icons.\n if (this.iconSwapTimeout) clearTimeout(this.iconSwapTimeout as number);\n this.iconSwapTimeout = setTimeout(() => {\n // Shift each icon to the right by one, and move the hidden icon to the front.\n let carry = allIcons[hiddenIconIndex - 1];\n for (let i = hiddenIconIndex - 1; i < allIcons.length - 1; i += 1) {\n const temp = allIcons[i + 1];\n allIcons[i + 1] = carry;\n carry = temp;\n }\n allIcons[hiddenIconIndex - 1] = carry;\n\n this.updateVisibleIcons(allIcons);\n }, KomojuFieldIconElement.ICON_SWAP_INTERVAL);\n } else if (this.iconSwapTimeout) {\n clearTimeout(this.iconSwapTimeout as number);\n this.iconSwapTimeout = undefined;\n }\n\n const oldIcons = this.visibleIcons;\n const newIcons = icons;\n if (oldIcons === newIcons) return;\n const removedIcons = oldIcons.filter((icon) => !newIcons.includes(icon));\n\n this.visibleIcons = icons;\n\n // First, add elements for new icons we've never seen before\n for (const icon of newIcons) {\n const existing = container.querySelector(`img[src=\"${icon}\"]`) as HTMLImageElement;\n if (existing) {\n existing.style.opacity = '1';\n continue;\n }\n\n const img = document.createElement('img');\n img.src = icon;\n img.width = KomojuFieldIconElement.ICON_WIDTH;\n container.append(img);\n img.style.opacity = '0';\n setTimeout(() => img.style.opacity = '1', 100);\n }\n\n // Then, remove elements for icons that are no longer present\n for (const icon of removedIcons) {\n const img = container.querySelector(`img[src=\"${icon}\"]`) as HTMLImageElement;\n img.style.opacity = '0';\n img.style.marginRight = '0';\n }\n\n // Finally, reposition the icons\n let position = 0;\n for (let i = this.visibleIcons.length - 1; i >= 0; i -= 1) {\n const icon = this.visibleIcons[i];\n const img = container.querySelector(`img[src=\"${icon}\"]`) as HTMLImageElement;\n img.style.marginRight = `${position * (KomojuFieldIconElement.ICON_WIDTH + KomojuFieldIconElement.ICON_GAP)}px`;\n position += 1;\n }\n }\n\n // This is for positioning the container element relative to the target input.\n // With this, we can show the icons on the right side of the input without\n // requiring the input to have a specific DOM structure or CSS.\n reposition() {\n const parent = this.parentElement;\n const target = this.target;\n const container = this.shadowRoot?.getElementById('komoju-field-icon');\n if (!target || !parent || !container) return;\n\n container.style.top = `${target.offsetTop}px`;\n container.style.right = `${parent.offsetWidth - target.offsetWidth - target.offsetLeft}px`;\n container.style.height = `${target.offsetHeight}px`;\n\n const targetStyle = window.getComputedStyle(target);\n\n container.style.paddingRight = targetStyle.paddingRight;\n container.style.paddingTop = targetStyle.paddingTop;\n container.style.paddingBottom = targetStyle.paddingBottom;\n\n const icons = this.getAttribute('icon')?.split(/\\s+/) || [];\n this.updateVisibleIcons(icons);\n }\n}\n", "const conversionMap: any = {\n \u30AC: '\uFF76\uFF9E',\n \u30AE: '\uFF77\uFF9E',\n \u30B0: '\uFF78\uFF9E',\n \u30B2: '\uFF79\uFF9E',\n \u30B4: '\uFF7A\uFF9E',\n \u30B6: '\uFF7B\uFF9E',\n \u30B8: '\uFF7C\uFF9E',\n \u30BA: '\uFF7D\uFF9E',\n \u30BC: '\uFF7E\uFF9E',\n \u30BE: '\uFF7F\uFF9E',\n \u30C0: '\uFF80\uFF9E',\n \u30C2: '\uFF81\uFF9E',\n \u30C5: '\uFF82\uFF9E',\n \u30C7: '\uFF83\uFF9E',\n \u30C9: '\uFF84\uFF9E',\n \u30D0: '\uFF8A\uFF9E',\n \u30D3: '\uFF8B\uFF9E',\n \u30D6: '\uFF8C\uFF9E',\n \u30D9: '\uFF8D\uFF9E',\n \u30DC: '\uFF8E\uFF9E',\n \u30D1: '\uFF8A\uFF9F',\n \u30D4: '\uFF8B\uFF9F',\n \u30D7: '\uFF8C\uFF9F',\n \u30DA: '\uFF8D\uFF9F',\n \u30DD: '\uFF8E\uFF9F',\n \u30F4: '\uFF73\uFF9E',\n \u30F7: '\uFF9C\uFF9E',\n \u30FA: '\uFF66\uFF9E',\n \u30A2: '\uFF71',\n \u30A4: '\uFF72',\n \u30A6: '\uFF73',\n \u30A8: '\uFF74',\n \u30AA: '\uFF75',\n \u30AB: '\uFF76',\n \u30AD: '\uFF77',\n \u30AF: '\uFF78',\n \u30B1: '\uFF79',\n \u30B3: '\uFF7A',\n \u30B5: '\uFF7B',\n \u30B7: '\uFF7C',\n \u30B9: '\uFF7D',\n \u30BB: '\uFF7E',\n \u30BD: '\uFF7F',\n \u30BF: '\uFF80',\n \u30C1: '\uFF81',\n \u30C4: '\uFF82',\n \u30C6: '\uFF83',\n \u30C8: '\uFF84',\n \u30CA: '\uFF85',\n \u30CB: '\uFF86',\n \u30CC: '\uFF87',\n \u30CD: '\uFF88',\n \u30CE: '\uFF89',\n \u30CF: '\uFF8A',\n \u30D2: '\uFF8B',\n \u30D5: '\uFF8C',\n \u30D8: '\uFF8D',\n \u30DB: '\uFF8E',\n \u30DE: '\uFF8F',\n \u30DF: '\uFF90',\n \u30E0: '\uFF91',\n \u30E1: '\uFF92',\n \u30E2: '\uFF93',\n \u30E4: '\uFF94',\n \u30E6: '\uFF95',\n \u30E8: '\uFF96',\n \u30E9: '\uFF97',\n \u30EA: '\uFF98',\n \u30EB: '\uFF99',\n \u30EC: '\uFF9A',\n \u30ED: '\uFF9B',\n \u30EF: '\uFF9C',\n \u30F2: '\uFF66',\n \u30F3: '\uFF9D',\n \u30A1: '\uFF67',\n \u30A3: '\uFF68',\n \u30A5: '\uFF69',\n \u30A7: '\uFF6A',\n \u30A9: '\uFF6B',\n \u30C3: '\uFF6F',\n \u30E3: '\uFF6C',\n \u30E5: '\uFF6D',\n \u30E7: '\uFF6E',\n '\u3002': '\uFF61',\n '\u3001': '\uFF64',\n \u30FC: '\uFF70',\n '\u2212': '-',\n '\uFF08': '(',\n '\uFF09': ')',\n '\u300C': '\uFF62',\n '\u300D': '\uFF63',\n '\u30FB': '\uFF65',\n '\u3000': ' ',\n \uFF21: 'A',\n \uFF22: 'B',\n \uFF23: 'C',\n \uFF24: 'D',\n \uFF25: 'E',\n \uFF26: 'F',\n \uFF27: 'G',\n \uFF28: 'H',\n \uFF29: 'I',\n \uFF2A: 'J',\n \uFF2B: 'K',\n \uFF2C: 'L',\n \uFF2D: 'M',\n \uFF2E: 'N',\n \uFF2F: 'O',\n \uFF30: 'P',\n \uFF31: 'Q',\n \uFF32: 'R',\n \uFF33: 'S',\n \uFF34: 'T',\n \uFF35: 'U',\n \uFF36: 'V',\n \uFF37: 'W',\n \uFF38: 'X',\n \uFF39: 'Y',\n \uFF3A: 'Z',\n \uFF41: 'a',\n \uFF42: 'b',\n \uFF43: 'c',\n \uFF44: 'd',\n \uFF45: 'e',\n \uFF46: 'f',\n \uFF47: 'g',\n \uFF48: 'h',\n \uFF49: 'i',\n \uFF4A: 'j',\n \uFF4B: 'k',\n \uFF4C: 'l',\n \uFF4D: 'm',\n \uFF4E: 'n',\n \uFF4F: 'o',\n \uFF50: 'p',\n \uFF51: 'q',\n \uFF52: 'r',\n \uFF53: 's',\n \uFF54: 't',\n \uFF55: 'u',\n \uFF56: 'v',\n \uFF57: 'w',\n \uFF58: 'x',\n \uFF59: 'y',\n \uFF5A: 'z',\n '\uFF10': '0',\n '\uFF11': '1',\n '\uFF12': '2',\n '\uFF13': '3',\n '\uFF14': '4',\n '\uFF15': '5',\n '\uFF16': '6',\n '\uFF17': '7',\n '\uFF18': '8',\n '\uFF19': '9'\n};\n\nexport function convertCharsToHalfWidth(str: string) {\n const convertedChars = str.split('').map(char => {\n return conversionMap[char] ?? char;\n });\n\n return convertedChars.join('');\n}\n\nexport function convertNumbersToHalfWidth(str: string) {\n var fullwidth = '\uFF10\uFF11\uFF12\uFF13\uFF14\uFF15\uFF16\uFF17\uFF18\uFF19\uFF0F';\n var halfwidth = '0123456789/';\n\n for (var i = 0; i < 10; ++i) {\n str = str.replace(\n new RegExp(fullwidth.charAt(i), 'g'),\n halfwidth.charAt(i)\n );\n }\n\n return str;\n}\n", "// Adds validation to an input element.\nexport function addValidation(\n _i18n: Translations, // Used only by typescript to compile-time catch missing translations.\n input: HTMLInputElement,\n callback: (input: HTMLInputElement) => keyof Translations['en'] | null\n) {\n // Add a class so that we know this input has validation.\n input.classList.add('has-validation');\n\n // Tiny detail: if the user has never inputted anything, we don't want to run validations at all\n // at the risk of showing an error message when the user is just clicking around.\n input.addEventListener('input', () => {\n input.dataset.validationDirty = 'true';\n });\n\n // Validation function. This will be called on 'blur' and also on a custom 'validate' event.\n const validate = (event: Event) => {\n const input = event.target as HTMLInputElement;\n\n const errorMessageKey = callback(input);\n\n if (errorMessageKey) {\n showError(_i18n, input, errorMessageKey);\n }\n };\n input.addEventListener('blur', (event) => {\n if (input.dataset.validationDirty !== 'true') return;\n else return validate(event);\n });\n input.addEventListener('validate', validate);\n\n // When the user focuses on the input, remove all error artifacts.\n input.addEventListener('focus', (event) => {\n const input = event.target as HTMLInputElement;\n clearErrors(input);\n });\n}\n\nexport function showError(\n _i18n: Translations, // Used only by typescript to compile-time catch missing translations.\n input: HTMLInputElement,\n messageKey: keyof Translations['en']\n) {\n input.classList.add('invalid');\n const key = messageKey as string;\n\n // We don't want to show the same error twice!\n const container = input.parentElement;\n const dupeSelector = `komoju-error:not(.removing) > komoju-i18n[key=\"${key}\"]`;\n if (container?.querySelector(dupeSelector)) {\n return;\n }\n\n container?.append(createErrorElement(messageKey as string));\n}\n\nexport function clearErrors(input: HTMLInputElement) {\n input.classList.remove('invalid');\n input.parentElement?.querySelectorAll('komoju-error:not(.removing)').forEach((element) => {\n element.remove();\n });\n}\n\n// Runs validations on an element.\nexport function runValidation(input: HTMLInputElement) {\n // Fire the 'validate' custom event.\n input.dispatchEvent(new CustomEvent('validate'));\n\n // If there's an error message, return it.\n const errorMessage = input.parentElement?.querySelector('komoju-error:not(.removing)')?.textContent;\n return errorMessage ?? null;\n}\n\n// Creates the error message element that appears under an invalid input.\n// Mainly just called by addValidation().\nexport function createErrorElement(messageKey: string) {\n const el = window.document.createElement('komoju-error');\n const i18nEl = window.document.createElement('komoju-i18n') as KomojuI18nElement;\n i18nEl.key = messageKey;\n el.appendChild(i18nEl);\n return el;\n}\n", "type CardType = 'visa' | 'mastercard' | 'amex' | 'jcb' | 'jcb15' | 'diner' | 'discover' | 'unionpay' | 'unknown';\n\nexport function cardTypeToKomojuSubtype(type: CardType) {\n if (type === 'amex') return 'american_express';\n if (type === 'diner') return 'diners_club';\n if (type === 'jcb15') return 'jcb';\n if (type === 'mastercard') return 'master';\n return type;\n}\n\nexport function insertSpaceEvery4Characters(str: string) {\n return str.replace(/(.{4})/g, '$1 ').trim();\n}\n\nexport function cardNumberMaxLength(type: CardType) {\n if (type == 'diner') {\n return 16;\n } else if (type == 'amex') {\n return 17;\n } else {\n return 23;\n }\n}\n\nexport function formatCardNumber(value: string, type: CardType) {\n if (\n type == 'unknown' ||\n type == 'visa' ||\n type == 'jcb' ||\n type == 'mastercard'\n ) {\n return insertSpaceEvery4Characters(value);\n } else {\n return value\n .replace(/(.{4})/, '$1 ')\n .replace(/(.{11})/, '$1 ')\n .trim();\n }\n}\n\nexport function removeNonDigits(value: string) {\n return value.replace(/[^0-9( \\/ )]+/g, '');\n}\n\n// insert \"/\" after the first 2 digits, if applicable\nexport function insertSlash(value: string) {\n const hasSlash = value.includes('/');\n const hasFullMonth = value.length >= 2;\n\n if (hasFullMonth && !hasSlash) {\n let yearStart = value.lastIndexOf(' ');\n if (yearStart === -1) yearStart = 2;\n\n const month = value.slice(0, 2);\n const year = value.slice(yearStart, value.length);\n\n return `${month} / ${year}`;\n }\n\n return value;\n}\n\n// remove \"/\" after the first 2 digits, if applicable\nexport function removeSlash(value: string) {\n return value.endsWith('/') ? value.replace(/[^0-9]+/g, '') : value;\n}\n\nexport const cardTypeRegex = {\n amex: /^3[47]\\d{0,13}/,\n diner: /^3(?:0([0-5]|9)|[689]\\d?)\\d{0,11}/,\n mastercard: /^(5[1-5]\\d{0,2}|22[2-9]\\d{0,1}|2[3-7]\\d{0,2})\\d{0,12}/,\n jcb15: /^(?:2131|1800)\\d{0,11}/,\n jcb: /^(?:35)\\d{0,17}/,\n visa: /^4\\d{0,18}/\n};\n\nexport function cardType(value: string): CardType {\n if (cardTypeRegex.amex.exec(value)) {\n return 'amex';\n } else if (cardTypeRegex.diner.exec(value)) {\n return 'diner';\n } else if (cardTypeRegex.mastercard.exec(value)) {\n return 'mastercard';\n } else if (cardTypeRegex.jcb15.exec(value)) {\n return 'jcb15';\n } else if (cardTypeRegex.jcb.exec(value)) {\n return 'jcb';\n } else if (cardTypeRegex.visa.exec(value)) {\n return 'visa';\n } else {\n return 'unknown';\n }\n}\n\nexport function luhnCheck(cardNumber: string) {\n // accept only digits and spaces\n if (/[^0-9\\s]+/.test(cardNumber)) {\n return false;\n }\n\n let sum = 0;\n let shouldDouble = false;\n cardNumber = cardNumber.replace(/\\D/g, '');\n const length = cardNumber.length;\n\n // iterating backwards, double every second digit\n for (let i = length - 1; i >= 0; --i) {\n let digit = parseInt(cardNumber.charAt(i), 10);\n\n // double. if doubled digit is > 9, subtract 9\n if (shouldDouble && (digit *= 2) > 9) {\n digit -= 9;\n }\n\n sum += digit;\n shouldDouble = !shouldDouble;\n }\n\n return sum % 10 === 0;\n}\n", "declare let window: WindowWithKomojuGlobals;\n\n// Call this to add messages to the registry.\n// Individual payment method modules can do this to add their own messages.\n// That way, we avoid needing to load all messages for every payment method upfront.\nexport function registerMessages(messages: I18n) {\n if (!window.komojuTranslations) {\n window.komojuTranslations = { 'en': {}, 'ja': {} };\n }\n\n for (const lang of Object.keys(window.komojuTranslations)) {\n window.komojuTranslations[lang] = {\n ...window.komojuTranslations[lang],\n ...messages[lang],\n };\n }\n}\n", "export const en = {\n 'cc.label.cardholder-name': 'Cardholder name',\n 'cc.label.card-number': 'Card number',\n 'cc.label.expiration': 'Expiration',\n 'cc.label.cvc': 'CVC',\n 'cc.error.required': 'Required',\n 'cc.error.incomplete': 'Please input the full expiration date',\n 'cc.error.please_use_half_width': 'Please use half-width characters',\n 'cc.error.invalid-number': 'Invalid number',\n 'cc.error.expired': 'Card is expired',\n 'cc.error.invalid-month': 'Month must be between 1 and 12',\n 'cc.error.unsupported-brand': 'Unsupported card brand',\n};\n\nexport const ja: typeof en = {\n 'cc.label.cardholder-name': '\u30AB\u30FC\u30C9\u6240\u6709\u8005\u540D',\n 'cc.label.card-number': '\u30AB\u30FC\u30C9\u756A\u53F7',\n 'cc.label.expiration': '\u6709\u52B9\u671F\u9650',\n 'cc.label.cvc': '\u30BB\u30AD\u30E5\u30EA\u30C6\u30A3\u30B3\u30FC\u30C9',\n 'cc.error.required': '\u5FC5\u9808\u9805\u76EE\u3067\u3059',\n 'cc.error.incomplete': '\u6709\u52B9\u671F\u9650\u3092\u6B63\u3057\u304F\u5165\u529B\u3057\u3066\u304F\u3060\u3055\u3044',\n 'cc.error.please_use_half_width': '\u534A\u89D2\u82F1\u6570\u5B57\u30FB\u8A18\u53F7\u306E\u307F\u6709\u52B9\u3067\u3059',\n 'cc.error.invalid-number': '\u30AB\u30FC\u30C9\u756A\u53F7\u304C\u6B63\u3057\u304F\u3042\u308A\u307E\u305B\u3093',\n 'cc.error.expired': '\u30AB\u30FC\u30C9\u306E\u6709\u52B9\u671F\u9650\u304C\u5207\u308C\u3066\u3044\u307E\u3059',\n 'cc.error.invalid-month': '\u6708\u306F1\u304B\u308912\u306E\u9593\u3067\u5165\u529B\u3057\u3066\u304F\u3060\u3055\u3044',\n 'cc.error.unsupported-brand': '\u5BFE\u5FDC\u3057\u3066\u3044\u306A\u3044\u30AF\u30EC\u30B8\u30C3\u30C8\u30AB\u30FC\u30C9\u30D6\u30E9\u30F3\u30C9\u3067\u3059',\n}\n", "import '../../types.d';\nimport KomojuFieldIconElement from './komoju-field-icon-element';\n// @ts-ignore\nimport html from './template.html'\nimport { convertNumbersToHalfWidth } from '../../shared/char-width-utils';\nimport { addValidation, showError, clearErrors } from '../../shared/validation';\nimport {\n cardType,\n formatCardNumber,\n removeNonDigits,\n insertSlash,\n removeSlash,\n cardNumberMaxLength,\n cardTypeToKomojuSubtype,\n luhnCheck,\n} from './card-number-utils';\n\nimport { registerMessages } from '../../shared/translations';\nimport * as i18n from './i18n';\nregisterMessages(i18n);\n\nwindow.customElements.define('komoju-field-icon', KomojuFieldIconElement);\n\nexport const render: KomojuRenderFunction = (root, paymentMethod) => {\n root.innerHTML = html;\n initializeInputs(\n root as KomojuFieldsConfig,\n paymentMethod as KomojuCreditCardPaymentMethod,\n );\n}\n\nfunction initializeInputs(\n root: KomojuFieldsConfig,\n paymentMethod: KomojuCreditCardPaymentMethod,\n) {\n // Card holder name validation: just make sure it's not empty\n const name = document.getElementById('cc-name')! as HTMLInputElement;\n addValidation(i18n, name, (input) => {\n if (input.value === '') return 'cc.error.required';\n if (/[^\\x01-\\x7E]/.test(input.value)) return 'cc.error.please_use_half_width';\n return null;\n });\n\n // Card number icon\n const cardIcon = document.getElementById('cc-icon')! as KomojuFieldIconElement;\n const defaultCardImage = `${root.komojuCdn}/static/credit_card_number.svg`;\n const supportedBrandImages = paymentMethod.brands.map((brand) => {\n return `https://komoju.com/payment_methods/credit_card.svg?brands=${brand}`;\n }).join(' ');\n cardIcon.icon = supportedBrandImages;\n\n // Card number format: 1234 5678 9012 3456 (sometimes more or less digits)\n const number = document.getElementById('cc-number')! as HTMLInputElement;\n number.addEventListener('input', (event) => {\n const input = event.target as HTMLInputElement;\n if (input.dataset.ime === 'active') return;\n let value = input.value;\n\n value = convertNumbersToHalfWidth(value).replace(/\\D/g, '');\n if (value.length === 0) {\n clearErrors(input);\n }\n\n const type = cardType(value);\n\n input.maxLength = cardNumberMaxLength(type);\n input.value = formatCardNumber(value, type);\n input.dataset.brand = type;\n\n // Update the card icons based on detected brand\n const brand = cardTypeToKomojuSubtype(type);\n if (type === 'unknown') {\n // Most brands are identifiable after 3 characters\n // Also show default if brand is unsupported\n if (value.length < 3) {\n cardIcon.icon = supportedBrandImages;\n } else {\n cardIcon.icon = defaultCardImage;\n }\n }\n else if (paymentMethod.brands.includes(brand)) {\n cardIcon.icon = `https://komoju.com/payment_methods/credit_card.svg?brands=${brand}`;\n clearErrors(input);\n }\n else {\n cardIcon.icon = supportedBrandImages;\n showError(i18n, input, 'cc.error.unsupported-brand');\n }\n });\n\n // Card number validation: luhn check and brand support\n addValidation(i18n, number, (input) => {\n const value = input.value.replace(/\\D/g, '');\n if (value === '') return 'cc.error.required';\n if (!luhnCheck(value)) return 'cc.error.invalid-number';\n\n const type = cardType(value);\n const brand = cardTypeToKomojuSubtype(type);\n if (type === 'unknown') return 'cc.error.unsupported-brand';\n if (!paymentMethod.brands.includes(brand)) return 'cc.error.unsupported-brand';\n\n return null;\n });\n\n // Expiration date\n const exp = document.getElementById('cc-exp')! as HTMLInputElement;\n let lastExpValue = exp.value;\n\n // Format: MM / YY. We automatically insert and remove the slash.\n exp.addEventListener('input', (event) => {\n const input = event.target as HTMLInputElement;\n\n if (input.dataset.ime === 'active') return;\n\n let value = convertNumbersToHalfWidth(input.value);\n const addedNewCharacter = value.length > lastExpValue.length;\n\n // Format value\n value = removeNonDigits(value);\n value = addedNewCharacter ? insertSlash(value) : removeSlash(value);\n\n // Update value and store as last input\n input.value = value;\n lastExpValue = value;\n });\n\n // Format: MM / YY to for IME devices.\n exp.addEventListener('blur', (event) => {\n const input = event.target as HTMLInputElement;\n\n if (input.dataset.ime === 'inactive') {\n let value = convertNumbersToHalfWidth(input.value);\n\n // Format value\n value = removeNonDigits(value);\n value = insertSlash(value);\n\n // Update value and store as last input\n input.value = value;\n lastExpValue = value;\n }\n });\n\n // Expiration validation: format and date\n addValidation(i18n, exp, (input) => {\n const mmyy = input.value.replace(/[^0-9\\/]/g, '');\n const [month, year] = mmyy.split('/');\n\n // Complain about incomplete expiration\n if (\n month == null ||\n year == null ||\n year.length !== 2 ||\n month.length !== 2 ||\n !/^\\d{2}\\/\\d{2}$/.test(mmyy)\n ) {\n return 'cc.error.incomplete';\n }\n\n const now = new Date();\n const currentYear = parseInt(\n now\n .getFullYear()\n .toString()\n .substr(2, 2)\n );\n const currentMonth = now.getMonth() + 1;\n const monthNum = parseInt(month);\n const yearNum = parseInt(year);\n\n // Complain if year is in the past\n if (yearNum < currentYear) {\n return 'cc.error.expired';\n }\n\n // Complain if month is in the past\n if (yearNum === currentYear && monthNum < currentMonth) {\n return 'cc.error.expired';\n }\n\n // Complain if month is past December\n if (monthNum > 12 || monthNum <= 0) {\n return 'cc.error.invalid-month';\n }\n\n return null;\n });\n\n // CVC\n // Here we just want to set the helper image.\n const cvcIcon = document.getElementById('cc-cvc-icon')! as KomojuFieldIconElement;\n cvcIcon.icon = `${root.komojuCdn}/static/credit_card_cvc.svg`;\n\n // CVC validation: just make sure it's not empty\n const cvc = document.getElementById('cc-cvc')! as HTMLInputElement;\n addValidation(i18n, cvc, (input) => {\n if (input.value === '') return 'cc.error.required';\n return null;\n });\n}\n\nexport const paymentDetails: KomojuPaymentDetailsFunction = (root, _paymentMethod) => {\n const name = root.querySelector('#cc-name') as HTMLInputElement;\n const number = root.querySelector('#cc-number') as HTMLInputElement;\n const expiration = root.querySelector('#cc-exp') as HTMLInputElement;\n const cvc = root.querySelector('#cc-cvc') as HTMLInputElement;\n\n const [month, year] = expiration.value.split('/').map(s => s.trim());\n\n return {\n type: 'credit_card',\n name: name.value,\n number: number.value.replace(/\\s+/g, ''),\n month, year,\n verification_value: cvc.value,\n }\n}"], + "mappings": ";;;;;;;;;;AAUA,IAAqB,0BAArB,cAAoD,YAAY;AAAA,EAsC9D,cAAc;AACZ,UAAM;AANR,wBAAyB,CAAC;AAOxB,UAAM,OAAO,KAAK,aAAa,EAAE,MAAM,OAAO,CAAC;AAC/C,SAAK,YAAY;AAAA,EACnB;AAAA,EArCA,WAAW,qBAAqB;AAC9B,WAAO,CAAC,QAAQ,KAAK;AAAA,EACvB;AAAA,EAGA,IAAI,SAAS;AACX,UAAM,WAAW,KAAK,aAAa,KAAK;AACxC,UAAM,OAAO,KAAK,YAAY;AAC9B,QAAI,CAAC,YAAY,CAAC,QAAQ,CAAC,KAAK;AAAkB,aAAO;AAAA;AACpD,aAAO,KAAK,cAAc,IAAI,UAAU;AAAA,EAC/C;AAAA,EACA,IAAI,OAAO,QAAiC;AAC1C,QAAI;AAAQ,WAAK,aAAa,OAAO,OAAO,EAAE;AAAA;AACzC,WAAK,aAAa,OAAO,EAAE;AAAA,EAClC;AAAA,EAEA,IAAI,OAAO;AACT,WAAO,KAAK,aAAa,MAAM,KAAK;AAAA,EACtC;AAAA,EACA,IAAI,KAAK,OAAe;AACtB,SAAK,aAAa,QAAQ,KAAK;AAAA,EACjC;AAAA,EAkBA,oBAAoB;AAClB,SAAK,MAAM,QAAQ;AACnB,SAAK,MAAM,SAAS;AAEpB,UAAM,SAAS,KAAK;AACpB,QAAI,CAAC;AAAQ;AAEb,SAAK,iBAAiB,IAAI,eAAe,MAAM;AAC7C,WAAK,WAAW;AAAA,IAClB,CAAC;AACD,SAAK,eAAgB,QAAQ,MAAM;AACnC,SAAK,WAAW;AAChB,eAAW,MAAM,KAAK,WAAW,GAAG,GAAG;AAAA,EACzC;AAAA,EAEA,uBAAuB;AACrB,SAAK,gBAAgB,WAAW;AAChC,SAAK,iBAAiB;AAAA,EACxB;AAAA,EAEA,yBAAyB,MAAc,UAAyB,UAAkB;AAChF,QAAI,SAAS,QAAQ;AACnB,YAAM,YAAY,KAAK,YAAY,eAAe,mBAAmB;AACrE,UAAI,CAAC;AAAW,cAAM,IAAI,MAAM,iDAAiD;AACjF,UAAI,aAAa;AAAU;AAE3B,YAAM,QAAQ,SAAS,MAAM,KAAK;AAClC,WAAK,mBAAmB,KAAK;AAAA,IAC/B,WACS,SAAS,OAAO;AACvB,WAAK,WAAW;AAAA,IAClB;AAAA,EACF;AAAA,EAKA,mBAAmB,OAAiB;AAClC,UAAM,YAAY,KAAK,YAAY,eAAe,mBAAmB;AACrE,UAAM,SAAS,KAAK;AACpB,QAAI,CAAC,UAAU,CAAC;AAAW;AAG3B,UAAM,aAAa,MAAM,UAAU,wBAAuB,aAAa,wBAAuB;AAC9F,UAAM,WAAW,OAAO,cAAc;AACtC,QAAI,aAAa,UAAU;AACzB,YAAM,kBAAkB,KAAK,MAAM,YAAY,wBAAuB,aAAa,wBAAuB,SAAS;AACnH,YAAM,WAAW;AACjB,cAAQ,MAAM,MAAM,GAAG,eAAe;AAItC,UAAI,KAAK;AAAiB,qBAAa,KAAK,eAAyB;AACrE,WAAK,kBAAkB,WAAW,MAAM;AAEtC,YAAI,QAAQ,SAAS,kBAAkB;AACvC,iBAAS,IAAI,kBAAkB,GAAG,IAAI,SAAS,SAAS,GAAG,KAAK,GAAG;AACjE,gBAAM,OAAO,SAAS,IAAI;AAC1B,mBAAS,IAAI,KAAK;AAClB,kBAAQ;AAAA,QACV;AACA,iBAAS,kBAAkB,KAAK;AAEhC,aAAK,mBAAmB,QAAQ;AAAA,MAClC,GAAG,wBAAuB,kBAAkB;AAAA,IAC9C,WAAW,KAAK,iBAAiB;AAC/B,mBAAa,KAAK,eAAyB;AAC3C,WAAK,kBAAkB;AAAA,IACzB;AAEA,UAAM,WAAW,KAAK;AACtB,UAAM,WAAW;AACjB,QAAI,aAAa;AAAU;AAC3B,UAAM,eAAe,SAAS,OAAO,CAAC,SAAS,CAAC,SAAS,SAAS,IAAI,CAAC;AAEvE,SAAK,eAAe;AAGpB,eAAW,QAAQ,UAAU;AAC3B,YAAM,WAAW,UAAU,cAAc,YAAY,QAAQ;AAC7D,UAAI,UAAU;AACZ,iBAAS,MAAM,UAAU;AACzB;AAAA,MACF;AAEA,YAAM,MAAM,SAAS,cAAc,KAAK;AACxC,UAAI,MAAM;AACV,UAAI,QAAQ,wBAAuB;AACnC,gBAAU,OAAO,GAAG;AACpB,UAAI,MAAM,UAAU;AACpB,iBAAW,MAAM,IAAI,MAAM,UAAU,KAAK,GAAG;AAAA,IAC/C;AAGA,eAAW,QAAQ,cAAc;AAC/B,YAAM,MAAM,UAAU,cAAc,YAAY,QAAQ;AACxD,UAAI,MAAM,UAAU;AACpB,UAAI,MAAM,cAAc;AAAA,IAC1B;AAGA,QAAI,WAAW;AACf,aAAS,IAAI,KAAK,aAAa,SAAS,GAAG,KAAK,GAAG,KAAK,GAAG;AACzD,YAAM,OAAO,KAAK,aAAa;AAC/B,YAAM,MAAM,UAAU,cAAc,YAAY,QAAQ;AACxD,UAAI,MAAM,cAAc,GAAG,YAAY,wBAAuB,aAAa,wBAAuB;AAClG,kBAAY;AAAA,IACd;AAAA,EACF;AAAA,EAKA,aAAa;AACX,UAAM,SAAS,KAAK;AACpB,UAAM,SAAS,KAAK;AACpB,UAAM,YAAY,KAAK,YAAY,eAAe,mBAAmB;AACrE,QAAI,CAAC,UAAU,CAAC,UAAU,CAAC;AAAW;AAEtC,cAAU,MAAM,MAAM,GAAG,OAAO;AAChC,cAAU,MAAM,QAAQ,GAAG,OAAO,cAAc,OAAO,cAAc,OAAO;AAC5E,cAAU,MAAM,SAAS,GAAG,OAAO;AAEnC,UAAM,cAAc,OAAO,iBAAiB,MAAM;AAElD,cAAU,MAAM,eAAe,YAAY;AAC3C,cAAU,MAAM,aAAa,YAAY;AACzC,cAAU,MAAM,gBAAgB,YAAY;AAE5C,UAAM,QAAQ,KAAK,aAAa,MAAM,GAAG,MAAM,KAAK,KAAK,CAAC;AAC1D,SAAK,mBAAmB,KAAK;AAAA,EAC/B;AACF;AAhLA,IAAqB,yBAArB;AAAqB,uBACZ,aAAa;AADD,uBAEZ,WAAW;AAFC,uBAGZ,qBAAqB;;;;;;ACyJvB,SAAS,0BAA0B,KAAa;AACrD,MAAI,YAAY;AAChB,MAAI,YAAY;AAEhB,WAAS,IAAI,GAAG,IAAI,IAAI,EAAE,GAAG;AAC3B,UAAM,IAAI;AAAA,MACR,IAAI,OAAO,UAAU,OAAO,CAAC,GAAG,GAAG;AAAA,MACnC,UAAU,OAAO,CAAC;AAAA,IACpB;AAAA,EACF;AAEA,SAAO;AACT;;;ACjLO,SAAS,cACd,OACA,OACA,UACA;AAEA,QAAM,UAAU,IAAI,gBAAgB;AAIpC,QAAM,iBAAiB,SAAS,MAAM;AACpC,UAAM,QAAQ,kBAAkB;AAAA,EAClC,CAAC;AAGD,QAAM,WAAW,CAAC,UAAiB;AACjC,UAAMA,SAAQ,MAAM;AAEpB,UAAM,kBAAkB,SAASA,MAAK;AAEtC,QAAI,iBAAiB;AACnB,gBAAU,OAAOA,QAAO,eAAe;AAAA,IACzC;AAAA,EACF;AACA,QAAM,iBAAiB,QAAQ,CAAC,UAAU;AACxC,QAAI,MAAM,QAAQ,oBAAoB;AAAQ;AAAA;AACzC,aAAO,SAAS,KAAK;AAAA,EAC5B,CAAC;AACD,QAAM,iBAAiB,YAAY,QAAQ;AAG3C,QAAM,iBAAiB,SAAS,CAAC,UAAU;AACzC,UAAMA,SAAQ,MAAM;AACpB,gBAAYA,MAAK;AAAA,EACnB,CAAC;AACH;AAEO,SAAS,UACd,OACA,OACA,YACA;AACA,QAAM,UAAU,IAAI,SAAS;AAC7B,QAAM,MAAM;AAGZ,QAAM,YAAY,MAAM;AACxB,QAAM,eAAe,kDAAkD;AACvE,MAAI,WAAW,cAAc,YAAY,GAAG;AAC1C;AAAA,EACF;AAEA,aAAW,OAAO,mBAAmB,UAAoB,CAAC;AAC5D;AAEO,SAAS,YAAY,OAAyB;AACnD,QAAM,UAAU,OAAO,SAAS;AAChC,QAAM,eAAe,iBAAiB,6BAA6B,EAAE,QAAQ,CAAC,YAAY;AACxF,YAAQ,OAAO;AAAA,EACjB,CAAC;AACH;AAcO,SAAS,mBAAmB,YAAoB;AACrD,QAAM,KAAK,OAAO,SAAS,cAAc,cAAc;AACvD,QAAM,SAAS,OAAO,SAAS,cAAc,aAAa;AAC1D,SAAO,MAAM;AACb,KAAG,YAAY,MAAM;AACrB,SAAO;AACT;;;AC/EO,SAAS,wBAAwB,MAAgB;AACtD,MAAI,SAAS;AAAQ,WAAO;AAC5B,MAAI,SAAS;AAAS,WAAO;AAC7B,MAAI,SAAS;AAAS,WAAO;AAC7B,MAAI,SAAS;AAAc,WAAO;AAClC,SAAO;AACT;AAEO,SAAS,4BAA4B,KAAa;AACvD,SAAO,IAAI,QAAQ,WAAW,KAAK,EAAE,KAAK;AAC5C;AAEO,SAAS,oBAAoB,MAAgB;AAClD,MAAI,QAAQ,SAAS;AACnB,WAAO;AAAA,EACT,WAAW,QAAQ,QAAQ;AACzB,WAAO;AAAA,EACT,OAAO;AACL,WAAO;AAAA,EACT;AACF;AAEO,SAAS,iBAAiB,OAAe,MAAgB;AAC9D,MACE,QAAQ,aACR,QAAQ,UACR,QAAQ,SACR,QAAQ,cACR;AACA,WAAO,4BAA4B,KAAK;AAAA,EAC1C,OAAO;AACL,WAAO,MACJ,QAAQ,UAAU,KAAK,EACvB,QAAQ,WAAW,KAAK,EACxB,KAAK;AAAA,EACV;AACF;AAEO,SAAS,gBAAgB,OAAe;AAC7C,SAAO,MAAM,QAAQ,kBAAkB,EAAE;AAC3C;AAGO,SAAS,YAAY,OAAe;AACzC,QAAM,WAAW,MAAM,SAAS,GAAG;AACnC,QAAM,eAAe,MAAM,UAAU;AAErC,MAAI,gBAAgB,CAAC,UAAU;AAC7B,QAAI,YAAY,MAAM,YAAY,GAAG;AACrC,QAAI,cAAc;AAAI,kBAAY;AAElC,UAAM,QAAQ,MAAM,MAAM,GAAG,CAAC;AAC9B,UAAM,OAAO,MAAM,MAAM,WAAW,MAAM,MAAM;AAEhD,WAAO,GAAG,WAAW;AAAA,EACvB;AAEA,SAAO;AACT;AAGO,SAAS,YAAY,OAAe;AACzC,SAAO,MAAM,SAAS,GAAG,IAAI,MAAM,QAAQ,YAAY,EAAE,IAAI;AAC/D;AAEO,IAAM,gBAAgB;AAAA,EAC3B,MAAM;AAAA,EACN,OAAO;AAAA,EACP,YAAY;AAAA,EACZ,OAAO;AAAA,EACP,KAAK;AAAA,EACL,MAAM;AACR;AAEO,SAAS,SAAS,OAAyB;AAChD,MAAI,cAAc,KAAK,KAAK,KAAK,GAAG;AAClC,WAAO;AAAA,EACT,WAAW,cAAc,MAAM,KAAK,KAAK,GAAG;AAC1C,WAAO;AAAA,EACT,WAAW,cAAc,WAAW,KAAK,KAAK,GAAG;AAC/C,WAAO;AAAA,EACT,WAAW,cAAc,MAAM,KAAK,KAAK,GAAG;AAC1C,WAAO;AAAA,EACT,WAAW,cAAc,IAAI,KAAK,KAAK,GAAG;AACxC,WAAO;AAAA,EACT,WAAW,cAAc,KAAK,KAAK,KAAK,GAAG;AACzC,WAAO;AAAA,EACT,OAAO;AACL,WAAO;AAAA,EACT;AACF;AAEO,SAAS,UAAU,YAAoB;AAE5C,MAAI,YAAY,KAAK,UAAU,GAAG;AAChC,WAAO;AAAA,EACT;AAEA,MAAI,MAAM;AACV,MAAI,eAAe;AACnB,eAAa,WAAW,QAAQ,OAAO,EAAE;AACzC,QAAM,SAAS,WAAW;AAG1B,WAAS,IAAI,SAAS,GAAG,KAAK,GAAG,EAAE,GAAG;AACpC,QAAI,QAAQ,SAAS,WAAW,OAAO,CAAC,GAAG,EAAE;AAG7C,QAAI,iBAAiB,SAAS,KAAK,GAAG;AACpC,eAAS;AAAA,IACX;AAEA,WAAO;AACP,mBAAe,CAAC;AAAA,EAClB;AAEA,SAAO,MAAM,OAAO;AACtB;;;AClHO,SAAS,iBAAiB,UAAgB;AAC/C,MAAI,CAAC,OAAO,oBAAoB;AAC9B,WAAO,qBAAqB,EAAE,MAAM,CAAC,GAAG,MAAM,CAAC,EAAE;AAAA,EACnD;AAEA,aAAW,QAAQ,OAAO,KAAK,OAAO,kBAAkB,GAAG;AACzD,WAAO,mBAAmB,QAAQ;AAAA,MAChC,GAAG,OAAO,mBAAmB;AAAA,MAC7B,GAAG,SAAS;AAAA,IACd;AAAA,EACF;AACF;;;AChBA;AAAA;AAAA;AAAA;AAAA;AAAO,IAAM,KAAK;AAAA,EAChB,4BAA4B;AAAA,EAC5B,wBAAwB;AAAA,EACxB,uBAAuB;AAAA,EACvB,gBAAgB;AAAA,EAChB,qBAAqB;AAAA,EACrB,uBAAuB;AAAA,EACvB,kCAAkC;AAAA,EAClC,2BAA2B;AAAA,EAC3B,oBAAoB;AAAA,EACpB,0BAA0B;AAAA,EAC1B,8BAA8B;AAChC;AAEO,IAAM,KAAgB;AAAA,EAC3B,4BAA4B;AAAA,EAC5B,wBAAwB;AAAA,EACxB,uBAAuB;AAAA,EACvB,gBAAgB;AAAA,EAChB,qBAAqB;AAAA,EACrB,uBAAuB;AAAA,EACvB,kCAAkC;AAAA,EAClC,2BAA2B;AAAA,EAC3B,oBAAoB;AAAA,EACpB,0BAA0B;AAAA,EAC1B,8BAA8B;AAChC;;;ACPA,iBAAiB,YAAI;AAErB,OAAO,eAAe,OAAO,qBAAqB,sBAAsB;AAEjE,IAAM,SAA+B,CAAC,MAAM,kBAAkB;AACnE,OAAK,YAAY;AACjB;AAAA,IACE;AAAA,IACA;AAAA,EACF;AACF;AAEA,SAAS,iBACP,MACA,eACA;AAEA,QAAM,OAAO,SAAS,eAAe,SAAS;AAC9C,gBAAc,cAAM,MAAM,CAAC,UAAU;AACnC,QAAI,MAAM,UAAU;AAAI,aAAO;AAC/B,QAAI,eAAe,KAAK,MAAM,KAAK;AAAG,aAAO;AAC7C,WAAO;AAAA,EACT,CAAC;AAGD,QAAM,WAAW,SAAS,eAAe,SAAS;AAClD,QAAM,mBAAmB,GAAG,KAAK;AACjC,QAAM,uBAAuB,cAAc,OAAO,IAAI,CAAC,UAAU;AAC/D,WAAO,6DAA6D;AAAA,EACtE,CAAC,EAAE,KAAK,GAAG;AACX,WAAS,OAAO;AAGhB,QAAM,SAAS,SAAS,eAAe,WAAW;AAClD,SAAO,iBAAiB,SAAS,CAAC,UAAU;AAC1C,UAAM,QAAQ,MAAM;AACpB,QAAI,MAAM,QAAQ,QAAQ;AAAU;AACpC,QAAI,QAAQ,MAAM;AAElB,YAAQ,0BAA0B,KAAK,EAAE,QAAQ,OAAO,EAAE;AAC1D,QAAI,MAAM,WAAW,GAAG;AACtB,kBAAY,KAAK;AAAA,IACnB;AAEA,UAAM,OAAO,SAAS,KAAK;AAE3B,UAAM,YAAY,oBAAoB,IAAI;AAC1C,UAAM,QAAQ,iBAAiB,OAAO,IAAI;AAC1C,UAAM,QAAQ,QAAQ;AAGtB,UAAM,QAAQ,wBAAwB,IAAI;AAC1C,QAAI,SAAS,WAAW;AAGtB,UAAI,MAAM,SAAS,GAAG;AACpB,iBAAS,OAAO;AAAA,MAClB,OAAO;AACL,iBAAS,OAAO;AAAA,MAClB;AAAA,IACF,WACS,cAAc,OAAO,SAAS,KAAK,GAAG;AAC7C,eAAS,OAAO,6DAA6D;AAC7E,kBAAY,KAAK;AAAA,IACnB,OACK;AACH,eAAS,OAAO;AAChB,gBAAU,cAAM,OAAO,4BAA4B;AAAA,IACrD;AAAA,EACF,CAAC;AAGD,gBAAc,cAAM,QAAQ,CAAC,UAAU;AACrC,UAAM,QAAQ,MAAM,MAAM,QAAQ,OAAO,EAAE;AAC3C,QAAI,UAAU;AAAI,aAAO;AACzB,QAAI,CAAC,UAAU,KAAK;AAAG,aAAO;AAE9B,UAAM,OAAO,SAAS,KAAK;AAC3B,UAAM,QAAQ,wBAAwB,IAAI;AAC1C,QAAI,SAAS;AAAW,aAAO;AAC/B,QAAI,CAAC,cAAc,OAAO,SAAS,KAAK;AAAG,aAAO;AAElD,WAAO;AAAA,EACT,CAAC;AAGD,QAAM,MAAM,SAAS,eAAe,QAAQ;AAC5C,MAAI,eAAe,IAAI;AAGvB,MAAI,iBAAiB,SAAS,CAAC,UAAU;AACvC,UAAM,QAAQ,MAAM;AAEpB,QAAI,MAAM,QAAQ,QAAQ;AAAU;AAEpC,QAAI,QAAQ,0BAA0B,MAAM,KAAK;AACjD,UAAM,oBAAoB,MAAM,SAAS,aAAa;AAGtD,YAAQ,gBAAgB,KAAK;AAC7B,YAAQ,oBAAoB,YAAY,KAAK,IAAI,YAAY,KAAK;AAGlE,UAAM,QAAQ;AACd,mBAAe;AAAA,EACjB,CAAC;AAGD,MAAI,iBAAiB,QAAQ,CAAC,UAAU;AACtC,UAAM,QAAQ,MAAM;AAEpB,QAAI,MAAM,QAAQ,QAAQ,YAAY;AACpC,UAAI,QAAQ,0BAA0B,MAAM,KAAK;AAGjD,cAAQ,gBAAgB,KAAK;AAC7B,cAAQ,YAAY,KAAK;AAGzB,YAAM,QAAQ;AACd,qBAAe;AAAA,IACjB;AAAA,EACF,CAAC;AAGD,gBAAc,cAAM,KAAK,CAAC,UAAU;AAClC,UAAM,OAAO,MAAM,MAAM,QAAQ,aAAa,EAAE;AAChD,UAAM,CAAC,OAAO,IAAI,IAAI,KAAK,MAAM,GAAG;AAGpC,QACE,SAAS,QACT,QAAQ,QACR,KAAK,WAAW,KAChB,MAAM,WAAW,KACjB,CAAC,iBAAiB,KAAK,IAAI,GAC3B;AACA,aAAO;AAAA,IACT;AAEA,UAAM,MAAM,IAAI,KAAK;AACrB,UAAM,cAAc;AAAA,MAClB,IACG,YAAY,EACZ,SAAS,EACT,OAAO,GAAG,CAAC;AAAA,IAChB;AACA,UAAM,eAAe,IAAI,SAAS,IAAI;AACtC,UAAM,WAAW,SAAS,KAAK;AAC/B,UAAM,UAAU,SAAS,IAAI;AAG7B,QAAI,UAAU,aAAa;AACzB,aAAO;AAAA,IACT;AAGA,QAAI,YAAY,eAAe,WAAW,cAAc;AACtD,aAAO;AAAA,IACT;AAGA,QAAI,WAAW,MAAM,YAAY,GAAG;AAClC,aAAO;AAAA,IACT;AAEA,WAAO;AAAA,EACT,CAAC;AAID,QAAM,UAAU,SAAS,eAAe,aAAa;AACrD,UAAQ,OAAO,GAAG,KAAK;AAGvB,QAAM,MAAM,SAAS,eAAe,QAAQ;AAC5C,gBAAc,cAAM,KAAK,CAAC,UAAU;AAClC,QAAI,MAAM,UAAU;AAAI,aAAO;AAC/B,WAAO;AAAA,EACT,CAAC;AACH;AAEO,IAAM,iBAA+C,CAAC,MAAM,mBAAmB;AACpF,QAAM,OAAO,KAAK,cAAc,UAAU;AAC1C,QAAM,SAAS,KAAK,cAAc,YAAY;AAC9C,QAAM,aAAa,KAAK,cAAc,SAAS;AAC/C,QAAM,MAAM,KAAK,cAAc,SAAS;AAExC,QAAM,CAAC,OAAO,IAAI,IAAI,WAAW,MAAM,MAAM,GAAG,EAAE,IAAI,OAAK,EAAE,KAAK,CAAC;AAEnE,SAAO;AAAA,IACL,MAAM;AAAA,IACN,MAAM,KAAK;AAAA,IACX,QAAQ,OAAO,MAAM,QAAQ,QAAQ,EAAE;AAAA,IACvC;AAAA,IAAO;AAAA,IACP,oBAAoB,IAAI;AAAA,EAC1B;AACF;", + "names": ["input"] +} diff --git a/src/app/code/Komoju/Payments/view/frontend/web/js/fields/konbini/module.js b/src/app/code/Komoju/Payments/view/frontend/web/js/fields/konbini/module.js new file mode 100644 index 000000000..eda0df48d --- /dev/null +++ b/src/app/code/Komoju/Payments/view/frontend/web/js/fields/konbini/module.js @@ -0,0 +1,164 @@ +var __defProp = Object.defineProperty; +var __export = (target, all) => { + for (var name in all) + __defProp(target, name, { get: all[name], enumerable: true }); +}; + +// src/fields/konbini/template.html +var template_default = '
\n \n\n \n\n \n
\n\n
    \n
\n\n\n\n\n'; + +// src/shared/validation.ts +function addValidation(_i18n, input, callback) { + input.classList.add("has-validation"); + input.addEventListener("input", () => { + input.dataset.validationDirty = "true"; + }); + const validate = (event) => { + const input2 = event.target; + const errorMessageKey = callback(input2); + if (errorMessageKey) { + showError(_i18n, input2, errorMessageKey); + } + }; + input.addEventListener("blur", (event) => { + if (input.dataset.validationDirty !== "true") + return; + else + return validate(event); + }); + input.addEventListener("validate", validate); + input.addEventListener("focus", (event) => { + const input2 = event.target; + clearErrors(input2); + }); +} +function showError(_i18n, input, messageKey) { + input.classList.add("invalid"); + const key = messageKey; + const container = input.parentElement; + const dupeSelector = `komoju-error:not(.removing) > komoju-i18n[key="${key}"]`; + if (container?.querySelector(dupeSelector)) { + return; + } + container?.append(createErrorElement(messageKey)); +} +function clearErrors(input) { + input.classList.remove("invalid"); + input.parentElement?.querySelectorAll("komoju-error:not(.removing)").forEach((element) => { + element.remove(); + }); +} +function createErrorElement(messageKey) { + const el = window.document.createElement("komoju-error"); + const i18nEl = window.document.createElement("komoju-i18n"); + i18nEl.key = messageKey; + el.appendChild(i18nEl); + return el; +} + +// src/shared/radio-helpers.ts +function setupRadioParentCheckedClass(input, root) { + if (!input.parentElement) { + throw new Error("KOMOJU Fields bug: radio input has no parent"); + } + if (!input.parentElement.classList.contains("radio")) { + throw new Error("KOMOJU Fields bug: radio input parent has no .radio class"); + } + if (input.checked) { + input.parentElement.classList.add("checked"); + } + input.addEventListener("change", () => { + root.querySelectorAll(".radio.checked").forEach((el) => el.classList.remove("checked")); + input.parentElement.classList.add("checked"); + }); +} + +// src/shared/translations.ts +function registerMessages(messages) { + if (!window.komojuTranslations) { + window.komojuTranslations = { "en": {}, "ja": {} }; + } + for (const lang of Object.keys(window.komojuTranslations)) { + window.komojuTranslations[lang] = { + ...window.komojuTranslations[lang], + ...messages[lang] + }; + } +} + +// src/fields/konbini/i18n.ts +var i18n_exports = {}; +__export(i18n_exports, { + en: () => en, + ja: () => ja +}); +var en = { + "kb.label.name": "Name (shown on receipt)", + "kb.label.email": "Email address", + "kb.error.required": "Required", + "kb.store.daily-yamazaki": "Daily Yamazaki", + "kb.store.family-mart": "FamilyMart", + "kb.store.lawson": "Lawson", + "kb.store.ministop": "Ministop", + "kb.store.seicomart": "Seicomart", + "kb.store.seven-eleven": "Seven Eleven" +}; +var ja = { + "kb.label.name": "\u6C0F\u540D\uFF08\u30EC\u30B7\u30FC\u30C8\u3067\u8868\u793A\u3055\u308C\u307E\u3059\uFF09", + "kb.label.email": "\u30E1\u30FC\u30EB\u30A2\u30C9\u30EC\u30B9", + "kb.error.required": "\u5FC5\u9808\u9805\u76EE\u3067\u3059", + "kb.store.daily-yamazaki": "\u30C7\u30A4\u30EA\u30FC\u30E4\u30DE\u30B6\u30AD", + "kb.store.family-mart": "\u30D5\u30A1\u30DF\u30EA\u30FC\u30DE\u30FC\u30C8", + "kb.store.lawson": "\u30ED\u30FC\u30BD\u30F3", + "kb.store.ministop": "\u30DF\u30CB\u30B9\u30C8\u30C3\u30D7", + "kb.store.seicomart": "\u30BB\u30A4\u30B3\u30FC\u30DE\u30FC\u30C8", + "kb.store.seven-eleven": "\u30BB\u30D6\u30F3\u30A4\u30EC\u30D6\u30F3" +}; + +// src/fields/konbini/module.ts +registerMessages(i18n_exports); +var render = (root, paymentMethod) => { + root.innerHTML = template_default; + initializeInputs(root, paymentMethod); +}; +var paymentDetails = (root, _paymentMethod) => { + const name = root.querySelector("#kb-name"); + const email = root.querySelector("#kb-email"); + const store = root.querySelector('input[name="kb-store"]:checked'); + return { + type: "konbini", + store: store.value, + email: email.value, + name: name.value + }; +}; +function initializeInputs(root, paymentMethod) { + const radioTemplate = root.querySelector("#konbini-radio"); + const email = root.querySelector("#kb-email"); + let checked = false; + for (const brand in paymentMethod.brands) { + const element = radioTemplate.content.cloneNode(true); + const input = element.querySelector("input"); + const image = element.querySelector("img"); + const label = element.querySelector("komoju-i18n"); + input.value = brand; + if (!checked) { + input.checked = true; + checked = true; + } + setupRadioParentCheckedClass(input, root); + image.src = `${root.komojuApi}${paymentMethod.brands[brand].icon}`; + label.key = `kb.store.${brand}`; + radioTemplate.parentElement.appendChild(element); + } + addValidation(i18n_exports, email, (input) => { + if (input.value === "") + return "kb.error.required"; + return null; + }); +} +export { + paymentDetails, + render +}; +//# sourceMappingURL=module.js.map diff --git a/src/app/code/Komoju/Payments/view/frontend/web/js/fields/konbini/module.js.map b/src/app/code/Komoju/Payments/view/frontend/web/js/fields/konbini/module.js.map new file mode 100644 index 000000000..ee8b607c2 --- /dev/null +++ b/src/app/code/Komoju/Payments/view/frontend/web/js/fields/konbini/module.js.map @@ -0,0 +1,7 @@ +{ + "version": 3, + "sources": ["../../../src/shared/validation.ts", "../../../src/shared/radio-helpers.ts", "../../../src/shared/translations.ts", "../../../src/fields/konbini/i18n.ts", "../../../src/fields/konbini/module.ts"], + "sourcesContent": ["// Adds validation to an input element.\nexport function addValidation(\n _i18n: Translations, // Used only by typescript to compile-time catch missing translations.\n input: HTMLInputElement,\n callback: (input: HTMLInputElement) => keyof Translations['en'] | null\n) {\n // Add a class so that we know this input has validation.\n input.classList.add('has-validation');\n\n // Tiny detail: if the user has never inputted anything, we don't want to run validations at all\n // at the risk of showing an error message when the user is just clicking around.\n input.addEventListener('input', () => {\n input.dataset.validationDirty = 'true';\n });\n\n // Validation function. This will be called on 'blur' and also on a custom 'validate' event.\n const validate = (event: Event) => {\n const input = event.target as HTMLInputElement;\n\n const errorMessageKey = callback(input);\n\n if (errorMessageKey) {\n showError(_i18n, input, errorMessageKey);\n }\n };\n input.addEventListener('blur', (event) => {\n if (input.dataset.validationDirty !== 'true') return;\n else return validate(event);\n });\n input.addEventListener('validate', validate);\n\n // When the user focuses on the input, remove all error artifacts.\n input.addEventListener('focus', (event) => {\n const input = event.target as HTMLInputElement;\n clearErrors(input);\n });\n}\n\nexport function showError(\n _i18n: Translations, // Used only by typescript to compile-time catch missing translations.\n input: HTMLInputElement,\n messageKey: keyof Translations['en']\n) {\n input.classList.add('invalid');\n const key = messageKey as string;\n\n // We don't want to show the same error twice!\n const container = input.parentElement;\n const dupeSelector = `komoju-error:not(.removing) > komoju-i18n[key=\"${key}\"]`;\n if (container?.querySelector(dupeSelector)) {\n return;\n }\n\n container?.append(createErrorElement(messageKey as string));\n}\n\nexport function clearErrors(input: HTMLInputElement) {\n input.classList.remove('invalid');\n input.parentElement?.querySelectorAll('komoju-error:not(.removing)').forEach((element) => {\n element.remove();\n });\n}\n\n// Runs validations on an element.\nexport function runValidation(input: HTMLInputElement) {\n // Fire the 'validate' custom event.\n input.dispatchEvent(new CustomEvent('validate'));\n\n // If there's an error message, return it.\n const errorMessage = input.parentElement?.querySelector('komoju-error:not(.removing)')?.textContent;\n return errorMessage ?? null;\n}\n\n// Creates the error message element that appears under an invalid input.\n// Mainly just called by addValidation().\nexport function createErrorElement(messageKey: string) {\n const el = window.document.createElement('komoju-error');\n const i18nEl = window.document.createElement('komoju-i18n') as KomojuI18nElement;\n i18nEl.key = messageKey;\n el.appendChild(i18nEl);\n return el;\n}\n", "interface QuerySelectorAll {\n querySelectorAll: HTMLElement['querySelectorAll']\n}\n\n// Add .checked to the parent .radio element when the input is checked.\n// This is just to make the CSS a little easier, since we're putting the\n// input inside of the label.\nexport function setupRadioParentCheckedClass(input: HTMLInputElement, root: QuerySelectorAll) {\n // Some sanity checks\n if (!input.parentElement) {\n throw new Error('KOMOJU Fields bug: radio input has no parent');\n }\n if (!input.parentElement.classList.contains('radio')) {\n throw new Error('KOMOJU Fields bug: radio input parent has no .radio class');\n }\n\n // Initialize the checked class\n if (input.checked) {\n input.parentElement.classList.add('checked');\n }\n\n // Set checked class then checked\n input.addEventListener('change', () => {\n root.querySelectorAll('.radio.checked').forEach((el) => el.classList.remove('checked'));\n input.parentElement!.classList.add('checked');\n });\n}\n", "declare let window: WindowWithKomojuGlobals;\n\n// Call this to add messages to the registry.\n// Individual payment method modules can do this to add their own messages.\n// That way, we avoid needing to load all messages for every payment method upfront.\nexport function registerMessages(messages: I18n) {\n if (!window.komojuTranslations) {\n window.komojuTranslations = { 'en': {}, 'ja': {} };\n }\n\n for (const lang of Object.keys(window.komojuTranslations)) {\n window.komojuTranslations[lang] = {\n ...window.komojuTranslations[lang],\n ...messages[lang],\n };\n }\n}\n", "export const en = {\n 'kb.label.name': 'Name (shown on receipt)',\n 'kb.label.email': 'Email address',\n 'kb.error.required': 'Required',\n 'kb.store.daily-yamazaki': 'Daily Yamazaki',\n 'kb.store.family-mart': 'FamilyMart',\n 'kb.store.lawson': 'Lawson',\n 'kb.store.ministop': 'Ministop',\n 'kb.store.seicomart': 'Seicomart',\n 'kb.store.seven-eleven': 'Seven Eleven',\n};\n\nexport const ja: typeof en = {\n 'kb.label.name': '\u6C0F\u540D\uFF08\u30EC\u30B7\u30FC\u30C8\u3067\u8868\u793A\u3055\u308C\u307E\u3059\uFF09',\n 'kb.label.email': '\u30E1\u30FC\u30EB\u30A2\u30C9\u30EC\u30B9',\n 'kb.error.required': '\u5FC5\u9808\u9805\u76EE\u3067\u3059',\n 'kb.store.daily-yamazaki': '\u30C7\u30A4\u30EA\u30FC\u30E4\u30DE\u30B6\u30AD',\n 'kb.store.family-mart': '\u30D5\u30A1\u30DF\u30EA\u30FC\u30DE\u30FC\u30C8',\n 'kb.store.lawson': '\u30ED\u30FC\u30BD\u30F3',\n 'kb.store.ministop': '\u30DF\u30CB\u30B9\u30C8\u30C3\u30D7',\n 'kb.store.seicomart': '\u30BB\u30A4\u30B3\u30FC\u30DE\u30FC\u30C8',\n 'kb.store.seven-eleven': '\u30BB\u30D6\u30F3\u30A4\u30EC\u30D6\u30F3',\n};\n", "import '../../types.d';\n// @ts-ignore\nimport html from './template.html'\nimport { addValidation } from '../../shared/validation';\nimport { setupRadioParentCheckedClass } from '../../shared/radio-helpers';\n\nimport { registerMessages } from '../../shared/translations';\nimport * as i18n from './i18n';\nregisterMessages(i18n);\n\nexport const render: KomojuRenderFunction = (root, paymentMethod) => {\n root.innerHTML = html;\n initializeInputs(root as KomojuFieldsConfig, paymentMethod as KomojuKonbiniPaymentMethod);\n}\n\nexport const paymentDetails: KomojuPaymentDetailsFunction = (root, _paymentMethod) => {\n const name = root.querySelector('#kb-name')! as HTMLInputElement;\n const email = root.querySelector('#kb-email')! as HTMLInputElement;\n const store = root.querySelector('input[name=\"kb-store\"]:checked')! as HTMLInputElement;\n\n return {\n type: 'konbini',\n store: store.value,\n email: email.value,\n name: name.value,\n }\n}\n\nfunction initializeInputs(\n root: KomojuFieldsConfig,\n paymentMethod: KomojuKonbiniPaymentMethod\n) {\n const radioTemplate = root.querySelector('#konbini-radio')! as HTMLTemplateElement;\n const email = root.querySelector('#kb-email')! as HTMLInputElement;\n \n let checked = false;\n for (const brand in paymentMethod.brands) {\n const element = radioTemplate.content.cloneNode(true) as HTMLElement;\n const input = element.querySelector('input') as HTMLInputElement;\n const image = element.querySelector('img') as HTMLImageElement;\n const label = element.querySelector('komoju-i18n') as KomojuI18nElement;\n\n input.value = brand;\n if (!checked) {\n input.checked = true;\n checked = true;\n }\n setupRadioParentCheckedClass(input, root);\n\n image.src = `${root.komojuApi}${paymentMethod.brands[brand].icon}`;\n label.key = `kb.store.${brand}`;\n\n radioTemplate.parentElement!.appendChild(element);\n }\n\n addValidation(i18n, email, (input) => {\n if (input.value === '') return 'kb.error.required';\n return null;\n });\n}\n"], + "mappings": "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", + "names": ["input"] +} diff --git a/src/app/code/Komoju/Payments/view/frontend/web/js/fields/offsite/module.js b/src/app/code/Komoju/Payments/view/frontend/web/js/fields/offsite/module.js new file mode 100644 index 000000000..559f5ea78 --- /dev/null +++ b/src/app/code/Komoju/Payments/view/frontend/web/js/fields/offsite/module.js @@ -0,0 +1,131 @@ +var __defProp = Object.defineProperty; +var __export = (target, all) => { + for (var name in all) + __defProp(target, name, { get: all[name], enumerable: true }); +}; + +// src/fields/offsite/template.html +var template_default = '
\n \n
\n\n
    \n
\n\n\n'; + +// src/shared/validation.ts +function addValidation(_i18n, input, callback) { + input.classList.add("has-validation"); + input.addEventListener("input", () => { + input.dataset.validationDirty = "true"; + }); + const validate = (event) => { + const input2 = event.target; + const errorMessageKey = callback(input2); + if (errorMessageKey) { + showError(_i18n, input2, errorMessageKey); + } + }; + input.addEventListener("blur", (event) => { + if (input.dataset.validationDirty !== "true") + return; + else + return validate(event); + }); + input.addEventListener("validate", validate); + input.addEventListener("focus", (event) => { + const input2 = event.target; + clearErrors(input2); + }); +} +function showError(_i18n, input, messageKey) { + input.classList.add("invalid"); + const key = messageKey; + const container = input.parentElement; + const dupeSelector = `komoju-error:not(.removing) > komoju-i18n[key="${key}"]`; + if (container?.querySelector(dupeSelector)) { + return; + } + container?.append(createErrorElement(messageKey)); +} +function clearErrors(input) { + input.classList.remove("invalid"); + input.parentElement?.querySelectorAll("komoju-error:not(.removing)").forEach((element) => { + element.remove(); + }); +} +function createErrorElement(messageKey) { + const el = window.document.createElement("komoju-error"); + const i18nEl = window.document.createElement("komoju-i18n"); + i18nEl.key = messageKey; + el.appendChild(i18nEl); + return el; +} + +// src/shared/translations.ts +function registerMessages(messages) { + if (!window.komojuTranslations) { + window.komojuTranslations = { "en": {}, "ja": {} }; + } + for (const lang of Object.keys(window.komojuTranslations)) { + window.komojuTranslations[lang] = { + ...window.komojuTranslations[lang], + ...messages[lang] + }; + } +} + +// src/fields/offsite/i18n.ts +var i18n_exports = {}; +__export(i18n_exports, { + en: () => en, + ja: () => ja +}); +var en = { + "os.label.name": "Customer name", + "os.label.email": "Email address", + "os.label.phone": "Phone number", + "os.error.required": "Required" +}; +var ja = { + "os.label.name": "\u304A\u540D\u524D", + "os.label.email": "\u30E1\u30FC\u30EB\u30A2\u30C9\u30EC\u30B9", + "os.label.phone": "\u96FB\u8A71\u756A\u53F7", + "os.error.required": "\u5FC5\u9808\u9805\u76EE\u3067\u3059" +}; + +// src/fields/offsite/module.ts +registerMessages(i18n_exports); +var render = (root, paymentMethod) => { + root.innerHTML = template_default; + root.querySelectorAll(".fields").forEach((element) => { + element.classList.add(paymentMethod.type); + }); + const fieldTemplate = root.querySelector("#additional-field"); + for (const field of paymentMethod.additional_fields ?? []) { + const element = fieldTemplate.content.cloneNode(true); + const input = element.querySelector("input"); + const text = element.querySelector("komoju-i18n"); + if (field === "email") + input.type = "email"; + else if (field === "phone") + input.type = "tel"; + input.id = `offsite-${field}`; + text.key = `os.label.${field}`; + fieldTemplate.parentElement.appendChild(element); + addValidation(i18n_exports, input, (input2) => { + if (input2.value === "") + return "os.error.required"; + return null; + }); + } +}; +var paymentDetails = (root, paymentMethod) => { + const result = { + type: paymentMethod.type + }; + for (const field of paymentMethod.additional_fields ?? []) { + const input = root.querySelector(`#offsite-${field}`); + result[field] = input.value; + } + return result; +}; +export { + paymentDetails, + render +}; +//# sourceMappingURL=module.js.map diff --git a/src/app/code/Komoju/Payments/view/frontend/web/js/fields/offsite/module.js.map b/src/app/code/Komoju/Payments/view/frontend/web/js/fields/offsite/module.js.map new file mode 100644 index 000000000..b64f9cc46 --- /dev/null +++ b/src/app/code/Komoju/Payments/view/frontend/web/js/fields/offsite/module.js.map @@ -0,0 +1,7 @@ +{ + "version": 3, + "sources": ["../../../src/shared/validation.ts", "../../../src/shared/translations.ts", "../../../src/fields/offsite/i18n.ts", "../../../src/fields/offsite/module.ts"], + "sourcesContent": ["// Adds validation to an input element.\nexport function addValidation(\n _i18n: Translations, // Used only by typescript to compile-time catch missing translations.\n input: HTMLInputElement,\n callback: (input: HTMLInputElement) => keyof Translations['en'] | null\n) {\n // Add a class so that we know this input has validation.\n input.classList.add('has-validation');\n\n // Tiny detail: if the user has never inputted anything, we don't want to run validations at all\n // at the risk of showing an error message when the user is just clicking around.\n input.addEventListener('input', () => {\n input.dataset.validationDirty = 'true';\n });\n\n // Validation function. This will be called on 'blur' and also on a custom 'validate' event.\n const validate = (event: Event) => {\n const input = event.target as HTMLInputElement;\n\n const errorMessageKey = callback(input);\n\n if (errorMessageKey) {\n showError(_i18n, input, errorMessageKey);\n }\n };\n input.addEventListener('blur', (event) => {\n if (input.dataset.validationDirty !== 'true') return;\n else return validate(event);\n });\n input.addEventListener('validate', validate);\n\n // When the user focuses on the input, remove all error artifacts.\n input.addEventListener('focus', (event) => {\n const input = event.target as HTMLInputElement;\n clearErrors(input);\n });\n}\n\nexport function showError(\n _i18n: Translations, // Used only by typescript to compile-time catch missing translations.\n input: HTMLInputElement,\n messageKey: keyof Translations['en']\n) {\n input.classList.add('invalid');\n const key = messageKey as string;\n\n // We don't want to show the same error twice!\n const container = input.parentElement;\n const dupeSelector = `komoju-error:not(.removing) > komoju-i18n[key=\"${key}\"]`;\n if (container?.querySelector(dupeSelector)) {\n return;\n }\n\n container?.append(createErrorElement(messageKey as string));\n}\n\nexport function clearErrors(input: HTMLInputElement) {\n input.classList.remove('invalid');\n input.parentElement?.querySelectorAll('komoju-error:not(.removing)').forEach((element) => {\n element.remove();\n });\n}\n\n// Runs validations on an element.\nexport function runValidation(input: HTMLInputElement) {\n // Fire the 'validate' custom event.\n input.dispatchEvent(new CustomEvent('validate'));\n\n // If there's an error message, return it.\n const errorMessage = input.parentElement?.querySelector('komoju-error:not(.removing)')?.textContent;\n return errorMessage ?? null;\n}\n\n// Creates the error message element that appears under an invalid input.\n// Mainly just called by addValidation().\nexport function createErrorElement(messageKey: string) {\n const el = window.document.createElement('komoju-error');\n const i18nEl = window.document.createElement('komoju-i18n') as KomojuI18nElement;\n i18nEl.key = messageKey;\n el.appendChild(i18nEl);\n return el;\n}\n", "declare let window: WindowWithKomojuGlobals;\n\n// Call this to add messages to the registry.\n// Individual payment method modules can do this to add their own messages.\n// That way, we avoid needing to load all messages for every payment method upfront.\nexport function registerMessages(messages: I18n) {\n if (!window.komojuTranslations) {\n window.komojuTranslations = { 'en': {}, 'ja': {} };\n }\n\n for (const lang of Object.keys(window.komojuTranslations)) {\n window.komojuTranslations[lang] = {\n ...window.komojuTranslations[lang],\n ...messages[lang],\n };\n }\n}\n", "export const en = {\n 'os.label.name': 'Customer name',\n 'os.label.email': 'Email address',\n 'os.label.phone': 'Phone number',\n 'os.error.required': 'Required',\n};\n\nexport const ja: typeof en = {\n 'os.label.name': '\u304A\u540D\u524D',\n 'os.label.email': '\u30E1\u30FC\u30EB\u30A2\u30C9\u30EC\u30B9',\n 'os.label.phone': '\u96FB\u8A71\u756A\u53F7',\n 'os.error.required': '\u5FC5\u9808\u9805\u76EE\u3067\u3059',\n};\n", "import '../../types.d';\n// @ts-ignore\nimport html from './template.html';\nimport { addValidation } from '../../shared/validation';\n\nimport { registerMessages } from '../../shared/translations';\nimport * as i18n from './i18n';\nregisterMessages(i18n);\n\nexport const render: KomojuRenderFunction = (root, paymentMethod) => {\n root.innerHTML = html;\n\n root.querySelectorAll('.fields').forEach((element) => {\n element.classList.add(paymentMethod.type);\n });\n\n const fieldTemplate = root.querySelector('#additional-field')! as HTMLTemplateElement;\n for (const field of paymentMethod.additional_fields ?? []) {\n const element = fieldTemplate.content.cloneNode(true) as HTMLElement;\n const input = element.querySelector('input') as HTMLInputElement;\n const text = element.querySelector('komoju-i18n') as KomojuI18nElement;\n\n if (field === 'email') input.type = 'email';\n else if (field === 'phone') input.type = 'tel';\n input.id = `offsite-${field}`;\n\n text.key = `os.label.${field}`;\n\n fieldTemplate.parentElement!.appendChild(element);\n\n addValidation(i18n, input, (input) => {\n if (input.value === '') return 'os.error.required';\n return null;\n });\n }\n}\n\nexport const paymentDetails: KomojuPaymentDetailsFunction = (root, paymentMethod) => {\n const result: any = {\n type: paymentMethod.type,\n };\n\n for (const field of paymentMethod.additional_fields ?? []) {\n const input = root.querySelector(`#offsite-${field}`)! as HTMLInputElement;\n result[field] = input.value;\n }\n\n return result;\n}\n"], + "mappings": "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", + "names": ["input", "input"] +} diff --git a/src/app/code/Komoju/Payments/view/frontend/web/js/secure-token-return.html b/src/app/code/Komoju/Payments/view/frontend/web/js/secure-token-return.html new file mode 100644 index 000000000..8f510aae6 --- /dev/null +++ b/src/app/code/Komoju/Payments/view/frontend/web/js/secure-token-return.html @@ -0,0 +1,17 @@ + + + + + + KOMOJU Fields + + + + + + diff --git a/src/app/code/Komoju/Payments/view/frontend/web/js/static/credit_card_cvc.svg b/src/app/code/Komoju/Payments/view/frontend/web/js/static/credit_card_cvc.svg new file mode 100644 index 000000000..68129726b --- /dev/null +++ b/src/app/code/Komoju/Payments/view/frontend/web/js/static/credit_card_cvc.svg @@ -0,0 +1,67 @@ + + + + + + + 123 + diff --git a/src/app/code/Komoju/Payments/view/frontend/web/js/static/credit_card_number.svg b/src/app/code/Komoju/Payments/view/frontend/web/js/static/credit_card_number.svg new file mode 100644 index 000000000..ebca587e4 --- /dev/null +++ b/src/app/code/Komoju/Payments/view/frontend/web/js/static/credit_card_number.svg @@ -0,0 +1,72 @@ + + + + + + + + 1111 2222 .. + diff --git a/src/app/code/Komoju/Payments/view/frontend/web/js/static/shared.css b/src/app/code/Komoju/Payments/view/frontend/web/js/static/shared.css new file mode 100644 index 000000000..1db981751 --- /dev/null +++ b/src/app/code/Komoju/Payments/view/frontend/web/js/static/shared.css @@ -0,0 +1,139 @@ +:root,:host { + --primary-color: #000000; + --error-color: #df1b41; + --secondary-color: #6d6e78; + --placeholder-color: #6d6e78; + --border-color: #e6e6e6; + --selected-color: #0570de; + --field-background: #ffffff; + --hover-background: #cccccc1f; + + font-family: sans-serif; + color: var(--primary-color); +} + +body { + box-sizing: border-box; + margin: 4px; +} + +komoju-i18n { + display: inline; +} + +komoju-error { + color: var(--error-color); +} + +komoju-fade { + position: absolute; + z-index: 100; + + background: white; + + opacity: 0; + transition: opacity 0.5s; +} + +komoju-fade.show { + opacity: 0.65; +} + +input { + transition: color 0.2s ease-in-out, border-color 0.2s ease-in-out; +} + +label input.invalid { + border-color: var(--error-color); + color: var(--error-color); +} + +.field { + position: relative; + display: flex; + flex-direction: column; + width: 100%; +} + +.field input { + box-shadow: 0px 1px 1px rgba(0, 0, 0, 0.03), 0px 3px 6px rgba(0, 0, 0, 0.02); + border: 1px solid var(--border-color); + border-radius: 5px; + padding: 0.75rem; + background: var(--field-background); + color: var(--primary-color); +} +.field input::placeholder { + color: var(--placeholder-color); +} + +.price-info { + color: var(--secondary-color); +} + +.fields { + gap: 12px; +} + +#picker { + gap: 12px; + margin-bottom: 12px; +} + +#picker .radio { + width: 9rem; +} + +.konbini,#picker { + justify-content: flex-start; +} + +.radio { + flex-direction: column; + align-items: flex-start; + justify-content: center; + + border-radius: 5px; + border: 1px solid var(--border-color); + box-shadow: 0px 1px 1px rgba(0, 0, 0, 0.03), 0px 3px 6px rgba(0, 0, 0, 0.02); + + background-color: var(--field-background); + color: var(--primary-color); + font-weight: 500; + font-size: 0.875rem; + + width: 11.25rem; + padding: 0.75rem; + gap: 2px; + + cursor: pointer; + + transition: background-color 0.1s ease-out, + border-color 0.1s ease-out, + color 0.1s ease-out; +} + +.radio input { + position: absolute; + opacity: 0; +} + +.radio:hover { + background: var(--hover-background); + color: var(--hover-color, var(--primary-color)) +} + +.radio:active { + background: var(--field-background); +} + +.radio.checked { + border-color: var(--selected-color); + color: var(--selected-color); +} + +iframe { + border: none; + width: 100%; + height: 100%; +} diff --git a/src/app/code/Komoju/Payments/view/frontend/web/js/static/themes/dark.css b/src/app/code/Komoju/Payments/view/frontend/web/js/static/themes/dark.css new file mode 100644 index 000000000..64421dd57 --- /dev/null +++ b/src/app/code/Komoju/Payments/view/frontend/web/js/static/themes/dark.css @@ -0,0 +1,9 @@ +:root,:host { + --primary-color: #f5f5f5; + --error-color: #f44336; + --secondary-color: #f5f5f5; + --placeholder-color: #9e9e9e; + --border-color: #e0e0e0; + --field-background: #424242; + --selected-color: #73bffb; +} diff --git a/src/app/code/Komoju/Payments/view/frontend/web/js/view/payment/method-renderer/form.js b/src/app/code/Komoju/Payments/view/frontend/web/js/view/payment/method-renderer/form.js index fea50d790..48db01f75 100644 --- a/src/app/code/Komoju/Payments/view/frontend/web/js/view/payment/method-renderer/form.js +++ b/src/app/code/Komoju/Payments/view/frontend/web/js/view/payment/method-renderer/form.js @@ -7,7 +7,8 @@ define( "Magento_Checkout/js/checkout-data", "ko", "Magento_Ui/js/model/messageList", - "mage/translate" + "mage/translate", + "mage/url" ], function ( $, @@ -17,15 +18,55 @@ define( checkoutData, ko, messageList, - $t + $t, + url ) { + ko.bindingHandlers.safeJsonAttribute = { + update: function(element, valueAccessor) { + var data = ko.unwrap(valueAccessor()); + var jsonString = JSON.stringify(data); + + console.log('##JSON: ' + jsonString); + + element.setAttribute('session', jsonString); + } + }; + "use strict"; return Component.extend({ defaults: { template: "Komoju_Payments/payment/form", active: true, redirectAfterPlaceOrder: false, - komojuMethod: ko.observable('') + komojuMethod: ko.observable(''), + komojuSession: ko.observable(''), + isDataLoaded: ko.observable(false) + }, + + initialize: function () { + this._super(); + this.loadKomojuData(); + }, + + loadKomojuData: function () { + const self = this; + self.isDataLoaded(false); + + $.get(url.build('komoju/komojufield/komojusessiondata')) + .done(function (response) { + // const komojuHost = document.querySelector('komoju-host'); + // console.log('##KOMOJU HOST: ' + komojuHost); + + // if (komojuHost) { + // console.log('##Setting SESSION: ' + JSON.stringify(this.komojuSession())); + // const sessionData = JSON.stringify(this.komojuSession()); + // komojuHost.setAttribute('session', sessionData); + // } + // console.log('##RESPONSE: ' + response); + + self.komojuSession(response.komojuSession); + self.isDataLoaded(true); + }); }, afterPlaceOrder: function() { @@ -82,6 +123,10 @@ define( return config.title; }, + getSession: function () { + return JSON.stringify(this.komojuSession()); + }, + showTitle: function () { var config = this.getConfig(); diff --git a/src/app/code/Komoju/Payments/view/frontend/web/template/payment/form.html b/src/app/code/Komoju/Payments/view/frontend/web/template/payment/form.html index a6a93e35b..a7022c75e 100644 --- a/src/app/code/Komoju/Payments/view/frontend/web/template/payment/form.html +++ b/src/app/code/Komoju/Payments/view/frontend/web/template/payment/form.html @@ -7,30 +7,47 @@

+

-
-
- - -
-
+
+
+ + +
+
+
+

OUTSIDE DATA

+ + + + + +
+
@@ -48,9 +65,9 @@

type="submit" data-bind=" click: placeOrder, - attr: {title: $t('Place Order')} + attr: {title: $t('MEOWMEOW')} "> - +
From e68210ea79b7ab310b4535834131ad94e9d42fc5 Mon Sep 17 00:00:00 2001 From: Dinwy Date: Mon, 1 Jul 2024 12:13:27 +0900 Subject: [PATCH 02/15] WIP: Making inline field work --- .../code/Komoju/Payments/Api/KomojuApi.php | 11 ++ .../KomojuField/KomojuSessionData.php | 8 +- .../Controller/KomojuField/ProcessToken.php | 117 ++++++++++++++++++ .../Payments/Model/KomojuApiService.php | 42 +++++++ .../js/view/payment/method-renderer/form.js | 111 ++++++++++++----- .../frontend/web/template/payment/form.html | 12 +- 6 files changed, 262 insertions(+), 39 deletions(-) create mode 100644 src/app/code/Komoju/Payments/Controller/KomojuField/ProcessToken.php create mode 100644 src/app/code/Komoju/Payments/Model/KomojuApiService.php diff --git a/src/app/code/Komoju/Payments/Api/KomojuApi.php b/src/app/code/Komoju/Payments/Api/KomojuApi.php index a3f21b922..10da5ddb4 100644 --- a/src/app/code/Komoju/Payments/Api/KomojuApi.php +++ b/src/app/code/Komoju/Payments/Api/KomojuApi.php @@ -8,6 +8,7 @@ use Komoju\Payments\Exception\InvalidJsonException; use Komoju\Payments\Gateway\Config\Config; use Magento\Framework\HTTP\Client\Curl; +use Psr\Log\LoggerInterface; use Exception; class KomojuApi @@ -33,11 +34,21 @@ public function createSession($payload) return $this->post('/api/v1/sessions', $payload); } + public function paySession($sessionUuid, $payload) + { + return $this->post('/api/v1/sessions/' . $sessionUuid . '/pay', $payload); + } + public function session($sessionUuid) { return $this->get('/api/v1/sessions/' . $sessionUuid); } + public function refund($paymentUuid, $payload) + { + return $this->post('/api/v1/payments/' . $paymentUuid . '/refund', $payload); + } + private function get($uri) { $url = $this->endpoint . $uri; diff --git a/src/app/code/Komoju/Payments/Controller/KomojuField/KomojuSessionData.php b/src/app/code/Komoju/Payments/Controller/KomojuField/KomojuSessionData.php index 9920d2b72..9f9c6ada7 100644 --- a/src/app/code/Komoju/Payments/Controller/KomojuField/KomojuSessionData.php +++ b/src/app/code/Komoju/Payments/Controller/KomojuField/KomojuSessionData.php @@ -11,12 +11,11 @@ use Komoju\Payments\Api\KomojuApi; use Komoju\Payments\Gateway\Config\Config; - class KomojuSessionData extends Action { - protected $jsonResultFactory; - protected $quoteRepository; - protected $checkoutSession; + protected JsonFactory $jsonResultFactory; + protected QuoteRepository $quoteRepository; + protected CheckoutSession $checkoutSession; private KomojuApi $komojuApi; private Config $config; private Cart $cart; @@ -47,7 +46,6 @@ public function execute() $customerEmail = $quote->getCustomerEmail(); $paymentMethod = $this->getRequest()->getParam('payment_method'); - // 세션 데이터 생성 $komojuSession = $this->createKomojuSession( $paymentMethod, $totalAmount, diff --git a/src/app/code/Komoju/Payments/Controller/KomojuField/ProcessToken.php b/src/app/code/Komoju/Payments/Controller/KomojuField/ProcessToken.php new file mode 100644 index 000000000..bca8f574b --- /dev/null +++ b/src/app/code/Komoju/Payments/Controller/KomojuField/ProcessToken.php @@ -0,0 +1,117 @@ +jsonResultFactory = $jsonResultFactory; + $this->checkoutSession = $checkoutSession; + $this->externalPayment = $externalPaymentFactory->create(); + // $this->orderRepository = $orderRepository; + $this->komojuApi = $komojuApi; + $this->logger = $logger; + parent::__construct($context); + } + + public function execute() + { + $result = $this->jsonResultFactory->create(); + $order = $this->getOrder(); + + $this->logger->debug('Before checking Order'); + + if ($order) { + $this->logger->debug('Order Data' . json_encode($order->getEntityId())); + $externalPayment = $this->createExternalPayment($order); + $this->logger->info('ExternalPayment: ' . $externalPayment); + } else { + $this->logger->debug('Executing KomojuSessionData controller' . 'No order found'); + } + + $this->logger->debug('After checking Order'); + + if ($this->getRequest()->isPost()) { + $postData = $this->getRequest()->getContent(); + $tokenData = json_decode($postData); + + $this->logger->debug('Executing KomojuSessionData controller' . json_encode($tokenData)); + + $currencyCode = $order->getOrderCurrencyCode(); + + // Let's create a session + $session = $this->komojuApi->createSession([ + 'amount' => $order->getGrandTotal(), + 'currency' => $currencyCode, + 'default_locale' => 'en', + 'payment_types' => ['credit_card'], + 'email' => $order->getCustomerEmail(), + 'metadata' => ['note' => 'testing'], + 'payment_data' => [ + 'name' => $order->getCustomerName(), + 'amount' => $order->getGrandTotal(), + 'currency' => $currencyCode, + 'external_order_num' => $externalPayment + ], + ]); + $data = $this->komojuApi->paySession($session->id, [ + 'customer_email' => $order->getCustomerEmail(), + 'payment_details' => $tokenData->token->id + ]); + + return $result->setData(['success' => true, 'message' => 'Token processed successfully' . json_encode($data)]); + } + + return $result->setData(['success' => false, 'message' => 'Invalid request']); + } + + private function getOrder() + { + $this->logger->info('Getting An Order'); + // $this->checkoutSession = ObjectManager::getInstance()->get(Session::class); + $order = $this->checkoutSession->getLastRealOrder(); + $this->logger->info('ProcessToken::GetOrder->order id: ' . $order->getEntityId()); + $this->logger->info('Getting An Order Done'); + return $order; + } + + private function createExternalPayment($order) + { + return $this->externalPayment->createExternalPayment($order)->getExternalPaymentId(); + } +} diff --git a/src/app/code/Komoju/Payments/Model/KomojuApiService.php b/src/app/code/Komoju/Payments/Model/KomojuApiService.php new file mode 100644 index 000000000..585c80e2b --- /dev/null +++ b/src/app/code/Komoju/Payments/Model/KomojuApiService.php @@ -0,0 +1,42 @@ +komojuApi = $komojuApi; + $this->config = $config; + $this->checkoutSession = $checkoutSession; + } + + public function createKomojuSession($paymentMethod) + { + $quote = $this->checkoutSession->getQuote(); + $totalAmount = $quote->getGrandTotal(); + $currencyCode = $quote->getStoreCurrencyCode(); + $customerEmail = $quote->getCustomerEmail(); + + return $this->komojuApi->createSession([ + 'amount' => $totalAmount, + 'currency' => $currencyCode, + 'default_locale' => $this->config->getKomojuLocale(), + 'payment_types' => [$paymentMethod], + 'email' => $customerEmail, + 'metadata' => ['note' => 'testing'] + ]); + } +} diff --git a/src/app/code/Komoju/Payments/view/frontend/web/js/view/payment/method-renderer/form.js b/src/app/code/Komoju/Payments/view/frontend/web/js/view/payment/method-renderer/form.js index 48db01f75..795d4ab77 100644 --- a/src/app/code/Komoju/Payments/view/frontend/web/js/view/payment/method-renderer/form.js +++ b/src/app/code/Komoju/Payments/view/frontend/web/js/view/payment/method-renderer/form.js @@ -21,17 +21,6 @@ define( $t, url ) { - ko.bindingHandlers.safeJsonAttribute = { - update: function(element, valueAccessor) { - var data = ko.unwrap(valueAccessor()); - var jsonString = JSON.stringify(data); - - console.log('##JSON: ' + jsonString); - - element.setAttribute('session', jsonString); - } - }; - "use strict"; return Component.extend({ defaults: { @@ -54,15 +43,7 @@ define( $.get(url.build('komoju/komojufield/komojusessiondata')) .done(function (response) { - // const komojuHost = document.querySelector('komoju-host'); - // console.log('##KOMOJU HOST: ' + komojuHost); - - // if (komojuHost) { - // console.log('##Setting SESSION: ' + JSON.stringify(this.komojuSession())); - // const sessionData = JSON.stringify(this.komojuSession()); - // komojuHost.setAttribute('session', sessionData); - // } - // console.log('##RESPONSE: ' + response); + console.log('######## RESPONSE: ' + JSON.stringify(response)); self.komojuSession(response.komojuSession); self.isDataLoaded(true); @@ -70,12 +51,32 @@ define( }, afterPlaceOrder: function() { - var redirectUrl = this.redirectUrl() + "?payment_method=" + this.komojuMethod(); + const redirectUrl = this.redirectUrl() + "?payment_method=" + this.komojuMethod(); fullScreenLoader.startLoader(); - $.mage.redirect( - redirectUrl - ); + + const komojuField = document.querySelector(`komoju-fields[payment-type='credit_card']`); + + if (komojuField && typeof komojuField.submit === 'function') { + console.log('KomojuField submit'); + + komojuField.submit().then(token => { + console.log(`Token: ${JSON.stringify(token)}`); + + if (!token) { + console.error('Failed to get token: ', JSON.stringify(redirectUrl)); + $.mage.redirect( + redirectUrl + ); + return; + } + + this.sendToken(token); + }); + } + // $.mage.redirect( + // redirectUrl + // ); }, getData: function() { @@ -85,6 +86,52 @@ define( }; }, + placeOrder: function (data, event) { + if (!this.validate()) { + return false; + } + + const boundSuper = this._super.bind(this); + + boundSuper(data, event); + + console.log('##PLACE ORDER validate success'); + }, + + sendToken: function (token) { + var serviceUrl = url.build('komoju/komojufield/processToken'); + console.log('sendToken'); + + var data = { + 'id': this.komojuSession().id, + 'token': token + } + + return $.ajax({ + url: serviceUrl, + type: 'POST', + data: JSON.stringify(data), + contentType: 'application/json', + success: function (response) { + console.log('Server responded with:', response); + console.log('Server responded with:', JSON.stringify(response)); + + if (response.success) { + var redirectUrl = url.build('checkout/onepage/success'); + + $.mage.redirect( + redirectUrl + ); + } else { + messageList.addErrorMessage({ message: response.message }); + } + }, + error: function (xhr, status, error) { + console.error('Failed to send token:', error); + } + }); + }, + selectPaymentMethod: function () { this.moveBillingForm(); selectPaymentMethodAction(this.getData()); @@ -139,18 +186,18 @@ define( var availablePaymentMethods = this.getAvailablePaymentMethods(); for (option in availablePaymentMethods) { - if (Object.prototype.hasOwnProperty.call(availablePaymentMethods, option)) { - options.push({ - value: option, - displayText: availablePaymentMethods[option], - }); - } + if (Object.prototype.hasOwnProperty.call(availablePaymentMethods, option)) { + options.push({ + value: option, + displayText: availablePaymentMethods[option], + }); + } } if (options.length === 0) { - messageList.addErrorMessage( + messageList.addErrorMessage( {message: $t("Encountered an issue communicating with KOMOJU. Please wait a moment and try again.")} - ); + ); } return options; diff --git a/src/app/code/Komoju/Payments/view/frontend/web/template/payment/form.html b/src/app/code/Komoju/Payments/view/frontend/web/template/payment/form.html index a7022c75e..b641b301c 100644 --- a/src/app/code/Komoju/Payments/view/frontend/web/template/payment/form.html +++ b/src/app/code/Komoju/Payments/view/frontend/web/template/payment/form.html @@ -45,6 +45,14 @@

OUTSIDE DATA

payment-type="credit_card" publishable-key="pk_test_lgva3j8ims1p3nhk3ut1f88t">
+ @@ -65,9 +73,9 @@

OUTSIDE DATA

type="submit" data-bind=" click: placeOrder, - attr: {title: $t('MEOWMEOW')} + attr: {title: $t('Place Order')} "> - + From 97db62e3c292d29e369c93ea6315a324effdc10b Mon Sep 17 00:00:00 2001 From: Dinwy Date: Tue, 2 Jul 2024 11:51:28 +0900 Subject: [PATCH 03/15] Make credit card hosted field work --- .../frontend/layout/checkout_index_index.xml | 4 +- .../js/view/payment/method-renderer/form.js | 91 ++++++++++++------- .../frontend/web/template/payment/form.html | 43 ++++----- 3 files changed, 79 insertions(+), 59 deletions(-) diff --git a/src/app/code/Komoju/Payments/view/frontend/layout/checkout_index_index.xml b/src/app/code/Komoju/Payments/view/frontend/layout/checkout_index_index.xml index f101940fd..072ad3951 100644 --- a/src/app/code/Komoju/Payments/view/frontend/layout/checkout_index_index.xml +++ b/src/app/code/Komoju/Payments/view/frontend/layout/checkout_index_index.xml @@ -1,8 +1,8 @@ - - + + - - diff --git a/src/app/code/Komoju/Payments/view/frontend/web/js/fields-iframe.js b/src/app/code/Komoju/Payments/view/frontend/web/js/fields-iframe.js deleted file mode 100644 index aaf27a342..000000000 --- a/src/app/code/Komoju/Payments/view/frontend/web/js/fields-iframe.js +++ /dev/null @@ -1,879 +0,0 @@ -var __defProp = Object.defineProperty; -var __export = (target, all) => { - for (var name in all) - __defProp(target, name, { get: all[name], enumerable: true }); -}; - -// src/shared/spinner.html -var spinner_default = "\n\n
    \n
  • \n
  • \n
  • \n
\n"; - -// src/shared/validation.ts -function runValidation(input) { - input.dispatchEvent(new CustomEvent("validate")); - const errorMessage = input.parentElement?.querySelector("komoju-error:not(.removing)")?.textContent; - return errorMessage ?? null; -} - -// src/shared/komoju-i18n-element.ts -var defaultLanguage = "en"; -function broadcastLocaleChange(root, locale) { - root.querySelectorAll("komoju-i18n").forEach((element) => { - const i18n = element; - i18n.render(locale); - }); -} -var KomojuI18nElement = class extends HTMLElement { - static get observedAttributes() { - return ["key"]; - } - get key() { - return this.getAttribute("key"); - } - set key(value) { - this.setAttribute("key", value ?? ""); - } - connectedCallback() { - this.render(); - } - attributeChangedCallback(name, _oldValue, _newValue) { - if (name === "key") - this.render(); - } - findLocale() { - let parent = this.parentElement; - while (parent && !parent.getAttribute("locale")) { - parent = parent.parentElement; - } - return parent?.getAttribute("locale") ?? defaultLanguage; - } - render(locale) { - if (!this.key) - return; - if (!locale) - locale = this.findLocale(); - if (!Object.keys(window.komojuTranslations).includes(locale)) - locale = defaultLanguage; - const lang = locale.substring(0, 2); - const message = window.komojuTranslations[lang][this.key]; - if (!message) { - console.error(`KOMOJU bug: missing translation for key: ${this.key}`); - return; - } - const matches = message.match(/%\{[\w-]+\}/g); - if (matches) { - let result = message; - matches.forEach((match) => { - const key = match.replace(/%{|}/g, ""); - const value = this.dataset[key]; - if (value) - result = result.replace(match, value); - }); - this.textContent = result; - return; - } - this.textContent = message; - } -}; - -// src/shared/money.ts -var noDecimalCurrencies = [ - "BIF", - "CLP", - "DJF", - "GNF", - "JPY", - "KMF", - "KRW", - "MGA", - "PYG", - "RWF", - "UGX", - "VND", - "VUV", - "XAF", - "XOF", - "XPF" -]; -var nonISOCurrencies = [ - "USDC" -]; -var displayCurrencyCodeInsteadOfSymbol = [ - "CNY" -]; -function formatMoney(amountCents, currency, locale = "en") { - function nonISOFormat(currency2, amountCents2) { - if (!amountCents2) { - return ""; - } else if (nonISOCurrencies.includes(currency2) || !currency2) { - return `${amountCents2.toLocaleString()} ${currency2}`; - } else { - throw "invalid currency format"; - } - } - const amountDecimal = decentify(amountCents, currency); - if (nonISOCurrencies.includes(currency) || !currency) { - return nonISOFormat(currency, amountDecimal); - } else { - const numberFormat = new Intl.NumberFormat(`${locale}-JP`, { - style: "currency", - currency, - currencyDisplay: displayCurrencyCodeInsteadOfSymbol.includes(currency) ? "code" : "symbol" - }); - return numberFormat.format(amountDecimal); - } -} -function decentify(amountCents, currency) { - return noDecimalCurrencies.includes(currency) ? amountCents : amountCents / 100; -} - -// src/shared/komoju-api.ts -function komojuFetch(config, method, path, body) { - if (!config.komojuApi) - throw new Error("KOMOJU API URL is null"); - if (!config.publishableKey) - throw new Error("KOMOJU publishable-key not set"); - return fetch(`${config.komojuApi}${path}`, { - method, - headers: { - accept: "application/json", - "content-type": "application/json", - authorization: `Basic ${btoa(`${config.publishableKey}:`)}`, - "komoju-via": "fields" - }, - body: body ? JSON.stringify(body) : void 0 - }); -} - -// src/shared/themable.ts -var Themable = class extends HTMLElement { - get theme() { - return this.getAttribute("theme"); - } - set theme(value) { - this.setAttribute("theme", value ?? ""); - } - applyTheme() { - const root = this.shadowRoot ?? document; - if (this.theme === null) { - root.querySelectorAll("#theme,#inline-theme").forEach((el) => el.remove()); - } else if (this.theme.startsWith("http") || this.theme.startsWith("/") || this.theme.startsWith("data:")) { - this.applyExternalTheme(root, this.theme); - } else { - this.applyInlineTheme(root, this.theme); - } - } - applyInlineTheme(root, theme) { - root.querySelectorAll("#theme,#inline-theme").forEach((el) => el.remove()); - const style = document.createElement("style"); - style.id = "inline-theme"; - style.textContent = theme; - this.appendStyleTag(style); - } - applyExternalTheme(root, theme) { - root.querySelectorAll("#inline-theme").forEach((el) => el.remove()); - let link = root.querySelector("#theme"); - if (link) { - if (link.href !== this.theme) - link.href = theme; - } else { - link = document.createElement("link"); - link.id = "theme"; - link.rel = "stylesheet"; - link.href = theme; - this.appendStyleTag(link); - } - } - appendStyleTag(style) { - if (this.shadowRoot) { - this.shadowRoot.append(style); - } else { - document.head.append(style); - } - } -}; - -// src/generated/env.ts -var env_default = { - "CDN": "https://multipay.komoju.com", - "ENV": "development", - "HONEYBADGER_API_KEY": "", - "GIT_REV": "99ad2eb29ce6530dedfe3a0ec34aea970dbaa78a" -}; - -// src/generated/supported-payment-types.ts -var supported = /* @__PURE__ */ new Set(); -supported.add("bank_transfer"); -supported.add("credit_card"); -supported.add("konbini"); -supported.add("offsite"); -var supported_payment_types_default = supported; - -// src/shared/translations.ts -function registerMessages(messages) { - if (!window.komojuTranslations) { - window.komojuTranslations = { "en": {}, "ja": {} }; - } - for (const lang of Object.keys(window.komojuTranslations)) { - window.komojuTranslations[lang] = { - ...window.komojuTranslations[lang], - ...messages[lang] - }; - } -} - -// src/i18n.ts -var i18n_exports = {}; -__export(i18n_exports, { - en: () => en, - ja: () => ja -}); -var en = { - "customer-fee-will-be-charged": "A fee of %{fee} will be included.", - "dynamic-currency-notice": "Payment will be made in %{currency}: %{original} \u2192 %{converted}.", - "dynamic-currency-notice-with-fee": "Payment will be made in %{currency}: %{original} \u2192 %{converted}. (total: %{total})", - "payment-method-unavailable": "This payment method is currently unavailable.", - "verification-failed": "Verification failed.", - "close": "Close" -}; -var ja = { - "customer-fee-will-be-charged": "%{fee}\u306E\u624B\u6570\u6599\u304C\u8FFD\u52A0\u3055\u308C\u307E\u3059\u3002", - "dynamic-currency-notice": "\u652F\u6255\u3044\u306F%{currency}\u3067\u6C7A\u6E08\u3055\u308C\u307E\u3059: %{original} \u2192 %{converted}\u3002", - "dynamic-currency-notice-with-fee": "\u652F\u6255\u3044\u306F%{currency}\u3067\u6C7A\u6E08\u3055\u308C\u307E\u3059: %{original} \u2192 %{converted}\u3002(\u5408\u8A08%{total})", - "payment-method-unavailable": "\u3053\u306E\u652F\u6255\u3044\u65B9\u6CD5\u306F\u73FE\u5728\u3054\u5229\u7528\u3044\u305F\u3060\u3051\u307E\u305B\u3093\u3002", - "verification-failed": "\u8A8D\u8A3C\u306B\u5931\u6557\u3057\u307E\u3057\u305F\u3002", - "close": "\u9589\u3058\u308B" -}; - -// src/shared/message-broker.ts -var MessageBroker = class { - constructor(id) { - this._sendWindow = new Promise((resolve) => this._setSendWindow = resolve); - this._receiveWindow = new Promise((resolve) => this._setReceiveWindow = resolve); - this.messageHandler = (event) => { - if (this.origin !== "*" && event.origin !== this.origin) - return; - this.handleMessage(event); - }; - this.id = id ?? crypto.randomUUID(); - this.origin = "*"; - this.promises = /* @__PURE__ */ new Map(); - this.listeners = /* @__PURE__ */ new Map(); - } - setup(arg) { - if (this._setSendWindow) { - this._setSendWindow(arg.send); - this._setSendWindow = void 0; - } else { - this._sendWindow = Promise.resolve(arg.send); - } - if (this._setReceiveWindow) { - this._setReceiveWindow(arg.receive); - this._setReceiveWindow = void 0; - } else { - this._receiveWindow = Promise.resolve(arg.receive); - } - arg.receive.addEventListener("message", this.messageHandler); - } - send(message) { - const fullMessage = { - ...message, - brokerId: this.id, - id: crypto.randomUUID() - }; - let resolve = null; - const promise = new Promise((resolvePromise, _reject) => { - resolve = resolvePromise; - }); - if (!resolve) - throw new Error("Broker is busted"); - this.promises.set(fullMessage.id, { promise, resolve }); - return this._sendWindow.then((w) => w.postMessage(fullMessage, this.origin)).then(() => promise); - } - receive(type, listener) { - this.listeners.set(type, listener); - } - async handleMessage(event) { - const message = event.data; - if (message.brokerId !== this.id) - return; - if (message.type === "ack") { - const ack = message; - const promise = this.promises.get(ack.id); - if (!promise) - return; - promise.resolve(ack.response); - this.promises.delete(ack.id); - } else { - const listener = this.listeners.get(message.type); - const ack = { type: "ack", brokerId: this.id, id: message.id }; - if (listener) - ack.response = await listener(message) ?? void 0; - await this._sendWindow.then((w) => w.postMessage(ack, this.origin)); - } - } - destroy() { - return this._receiveWindow.then((w) => w.removeEventListener("message", this.messageHandler)); - } -}; - -// src/komoju-host-element.ts -registerMessages(i18n_exports); -var _baseKomojuAPI; -function baseKomojuAPI() { - if (_baseKomojuAPI) - return _baseKomojuAPI; - const url = new URL(window.location.href); - const params = new URLSearchParams(url.hash.slice(1)); - _baseKomojuAPI = params.get("api") ?? "https://komoju.com"; - return _baseKomojuAPI; -} -function brokerId() { - const url = new URL(window.location.href); - const params = new URLSearchParams(url.hash.slice(1)); - return params.get("broker") ?? void 0; -} -function i18nMessage(locale, key) { - if (locale === "ja") - return ja[key]; - return en[key]; -} -var KomojuHostElement = class extends Themable { - constructor() { - super(...arguments); - this._session = null; - this.module = null; - this.broker = new MessageBroker(brokerId()); - this._renderCount = 0; - this.komojuFetch = komojuFetch.bind(this, this); - } - static get observedAttributes() { - console.log("KomojuHostElement::listenToMessagesFromMainWindow"); - return [ - "komoju-api", - "session", - "session-id", - "publishable-key", - "payment-type", - "locale", - "theme", - "token", - "name" - ]; - } - get session() { - return this._session; - } - set session(value) { - console.log("KomojuHostElement set session", value); - this._session = value; - this.broker.send({ - type: "dispatch-event", - name: "komoju-session-change", - detail: { session: this._session } - }); - } - get komojuApi() { - const attribute = this.getAttribute("komoju-api"); - if (!attribute || attribute === "") - return baseKomojuAPI(); - else - return attribute; - } - set komojuApi(value) { - this.setAttribute("komoju-api", value ?? ""); - } - get sessionId() { - return this.getAttribute("session-id"); - } - set sessionId(value) { - this.setAttribute("session-id", value ?? ""); - } - get publishableKey() { - return this.getAttribute("publishable-key"); - } - set publishableKey(value) { - this.setAttribute("publishable-key", value ?? ""); - } - get paymentType() { - return this.getAttribute("payment-type"); - } - set paymentType(value) { - this.setAttribute("payment-type", value ?? ""); - } - get locale() { - return this.getAttribute("locale"); - } - set locale(value) { - this.setAttribute("locale", value ?? ""); - this.broker.send({ - type: "dispatch-event", - name: "komoju-locale-change", - detail: { locale: value } - }); - } - get token() { - return this.hasAttribute("token"); - } - set token(value) { - if (value) - this.setAttribute("token", ""); - else - this.removeAttribute("token"); - } - get name() { - return this.getAttribute("name"); - } - set name(value) { - if (value) - this.setAttribute("name", value); - else - this.removeAttribute("name"); - } - get komojuCdn() { - return env_default["CDN"]; - } - get paymentMethod() { - return this.session?.payment_methods.find((method) => method.type === this.paymentType); - } - async attributeChangedCallback(name, oldValue, newValue) { - console.log("??? KomojuHostElement attributeChangedCallback", name, oldValue); - console.log("###"); - console.log("NEW VALUE::KomojuHostElement attributeChangedCallback", name, newValue); - if (name === "session") { - if (!newValue || newValue == "") - return; - this.session = JSON.parse(newValue); - if (!this.locale) - this.locale = this.session.default_locale.substring(0, 2); - if (!this.paymentType) - this.paymentType = this.session.payment_methods[0].type; - this.render(); - } else if (name === "session-id" || name === "publishable-key") { - if (!newValue || newValue == "") - return; - if (!this.publishableKey) - return; - if (!this.sessionId) - return; - const response = await this.komojuFetch("GET", `/api/v1/sessions/${this.sessionId}`); - if (response.status === 404) { - console.error("Invalid KOMOJU session ID", this.sessionId); - return; - } - if (response.status !== 200) { - console.error("Failed to retrieve KOMOJU session", response); - return; - } - this.session = await response.json(); - if (!this.session) - throw new Error("KOMOJU returned a null session"); - if (!this.paymentType) - this.paymentType = this.session.payment_methods[0].type; - if (!this.locale) - this.locale = this.session.default_locale.substring(0, 2); - this.render(); - } else if (name === "payment-type") { - if (!newValue || newValue == "") - return; - if (!this.session) - return; - if (!this.publishableKey) - return; - this.startFade(); - await this.render(); - } else if (name === "locale") { - if (!newValue || newValue == "" || oldValue === newValue) - return; - broadcastLocaleChange(this, newValue); - } else if (name === "theme") { - this.applyTheme(); - } - } - connectedCallback() { - console.log("KomojuHostElement connectedCallback"); - this.innerHTML = spinner_default; - console.log(`${JSON.stringify(this.broker)}, broker`); - this.listenToMessagesFromMainWindow(this.broker); - this.broker.setup({ - send: window.parent, - receive: window - }); - const body = this.ownerDocument?.body; - this.resizeObserver = new ResizeObserver(() => { - const height = body.parentElement.offsetHeight; - if (height === 0) - return; - this.broker.send({ type: "resize", height: height.toString() }); - }); - if (body) - this.resizeObserver.observe(body, { box: "border-box" }); - } - disconnectedCallback() { - this.broker.destroy(); - this.resizeObserver?.disconnect(); - this.resizeObserver = void 0; - } - listenToMessagesFromMainWindow(broker) { - console.log("KomojuHostElement listenToMessagesFromMainWindow"); - broker.receive("attr", (message) => { - if (!KomojuHostElement.observedAttributes.includes(message.attr)) - return; - console.log("KomojuHostElement listenToMessagesFromMainWindow attr", message); - if (message.value === null || message.value === void 0) - this.removeAttribute(message.attr); - else - this.setAttribute(message.attr, message.value); - }); - broker.receive("submit", () => { - return this.submit(); - }); - broker.receive("end-fade", () => { - this.endFade(); - }); - } - async submit() { - if (!this.module || !this.session) { - return { type: "submit-result", errors: ["Attempted to submit before selecting KOMOJU Payment method"] }; - } - const paymentMethod = this.paymentMethod; - if (!paymentMethod) - throw new Error(`KOMOJU Payment method not found: ${this.paymentType}`); - this.querySelectorAll("komoju-error").forEach((error) => error.remove()); - const validatedFields = this.querySelectorAll(".has-validation"); - const errors = Array.prototype.map.call( - validatedFields, - (field) => field instanceof HTMLInputElement ? runValidation(field) : null - ); - if (errors.some((error) => error != null)) { - return { type: "submit-result", errors: errors.filter((error) => error != null) }; - } - this.startFade(); - const paymentDetails = this.module.paymentDetails(this, paymentMethod); - if (this.token) { - return await this.submitToken(paymentDetails); - } else { - return await this.submitPayment(paymentDetails); - } - } - async submitPayment(paymentDetails) { - const paymentMethod = this.paymentMethod; - if (!paymentMethod) { - throw new Error("Attempted to submit before selecting KOMOJU Payment method"); - } - const session = this.session; - let moduleName = paymentMethod.offsite ? "offsite" : paymentMethod.type; - if (!supported_payment_types_default.has(moduleName)) { - const result2 = { - type: "submit-result", - pay: { - status: "pending", - redirect_url: `${session.session_url}#${paymentMethod.type}` - } - }; - return result2; - } - let secureTokenId = null; - if (paymentMethod.type === "credit_card" && session.mode !== "customer") - try { - const { secureToken, error, skip } = await this.do3DS(paymentDetails); - if (secureToken) { - secureTokenId = secureToken.id; - } else if (error && !skip) { - return { - type: "submit-result", - errors: [error] - }; - } - } catch (e) { - console.error("Error during secure token flow. Continuing without.", e); - } - const payResponse = await this.komojuFetch("POST", `/api/v1/sessions/${session.id}/pay`, { - payment_details: secureTokenId ?? paymentDetails, - api_locale: this.locale - }); - const payResult = await payResponse.json(); - const result = { - type: "submit-result", - pay: payResult - }; - if (payResult.error) { - console.error(payResult); - this.handleApiError(payResult.error); - this.endFade(); - } - return result; - } - async do3DS(paymentDetails) { - const { secureToken, error } = await this.submitSecureToken(paymentDetails); - if (error && error.code === "unsupported_card_brand") { - return { - error, - skip: true - }; - } - if (error) - return { error }; - else if (!secureToken) - throw new Error("Secure token empty response"); - const status = secureToken.verification_status; - if (status === "OK" || status === "SKIPPED") { - return { secureToken }; - } - if (status === "ERRORED") { - return { - skip: true - }; - } - const dialogResult = await this.broker.send({ - type: "dialog-start", - url: secureToken.authentication_url - }); - if (dialogResult?.type !== "dialog-result") { - throw new Error("Expected dialog-result, got " + JSON.stringify(dialogResult)); - } else { - const { result } = dialogResult; - if (result.error && result.error.code === "unsupported_card_brand") { - return { - error: result.error, - skip: true - }; - } - if (result.error) { - this.handleApiError(result.error); - this.endFade(); - return result; - } - if (result.secureToken && result.secureToken.verification_status === "ERRORED") { - const error2 = i18nMessage(this.locale, "verification-failed") ?? "3DS error"; - this.handleApiError(error2); - this.endFade(); - return { - error: { - code: "verification_status_errored", - message: error2, - param: null, - details: null - } - }; - } - return result; - } - } - async submitSecureToken(paymentDetails) { - const session = this.session; - const returnURL = new URL(this.komojuCdn); - returnURL.pathname = "/secure-token-return.html"; - returnURL.searchParams.set("session_id", session.id); - const secureTokenResponse = await this.komojuFetch("POST", `/api/v1/secure_tokens`, { - amount: session.amount, - currency: session.currency, - payment_details: paymentDetails, - return_url: returnURL - }); - if (secureTokenResponse.status >= 400) { - const error = (await secureTokenResponse.json()).error; - return { error }; - } - const secureToken = await secureTokenResponse.json(); - return { secureToken }; - } - async handleApiError(error) { - if (!this.broker) - throw new Error("KOMOJU Fields bug: broker should be set by now"); - const result = await this.broker.send({ - type: "dispatch-event", - name: "komoju-error", - detail: { error } - }); - if (!result || result.type !== "dispatch-result") { - throw new Error("Expected dispatch-result, got " + JSON.stringify(result)); - } - if (result.cancel) - return; - this.querySelectorAll(".generic-error-message").forEach((container) => { - const errorText = document.createElement("komoju-error"); - if (typeof error === "string") { - errorText.textContent = error; - } else if (error.message) { - errorText.textContent = error.message; - } - container.append(errorText); - }); - } - async submitToken(paymentDetails) { - if (paymentDetails.type === "credit_card") { - const { secureToken, error, skip } = await this.do3DS(paymentDetails); - if (error && !skip) { - return { type: "submit-result", errors: [error] }; - } else if (secureToken) { - return { - type: "submit-result", - token: secureToken - }; - } - } - const tokenResponse = await this.komojuFetch("POST", `/api/v1/tokens`, { - payment_details: paymentDetails - }); - if (tokenResponse.status >= 400) { - const error = (await tokenResponse.json()).error; - this.handleApiError(error); - this.endFade(); - return { type: "submit-result", errors: [error.message] }; - } - const token = await tokenResponse.json(); - return { - type: "submit-result", - token - }; - } - async render() { - if (!this.session) - throw new Error("KOMOJU Session not loaded"); - const paymentMethod = this.session.payment_methods.find((method) => method.type === this.paymentType); - const thisRender = ++this._renderCount; - if (!paymentMethod) { - const errorElement = document.createElement("komoju-error"); - const errorMessage = document.createElement("komoju-i18n"); - errorMessage.key = "payment-method-unavailable"; - errorElement.append(errorMessage); - this.replaceChildren(errorElement); - this.applyTheme(); - return; - } - let moduleName = paymentMethod.type; - if (!supported_payment_types_default.has(moduleName)) { - moduleName = "offsite"; - } - const module = await import(`${this.komojuCdn}/fields/${moduleName}/module.js`); - if (thisRender !== this._renderCount) - return; - this.module = module; - if (!this.module) - throw new Error(`KOMOJU Payment module not found: ${this.paymentType}`); - this.module.render(this, paymentMethod); - this.querySelectorAll("input").forEach((input) => { - input.addEventListener("compositionstart", () => { - input.dataset.ime = "active"; - }); - input.addEventListener("compositionend", () => { - input.dataset.ime = "inactive"; - }); - }); - this.applyTheme(); - const priceInfo = this.querySelector(".price-info"); - if (!priceInfo) - return; - if (paymentMethod.customer_fee) { - const listItem = document.createElement("li"); - const feeMessage = document.createElement("komoju-i18n"); - listItem.classList.add("customer-fee"); - feeMessage.key = "customer-fee-will-be-charged"; - feeMessage.dataset["fee"] = formatMoney( - paymentMethod.customer_fee, - paymentMethod.currency ?? this.session.currency - ); - listItem.append(feeMessage); - priceInfo.append(listItem); - } - if (paymentMethod.exchange_rate && paymentMethod.amount && paymentMethod.currency && paymentMethod.currency !== this.session.currency) { - const listItem = document.createElement("li"); - const dccMessage = document.createElement("komoju-i18n"); - const rate = Math.round(paymentMethod.exchange_rate * 1e4) / 1e4; - dccMessage.key = "dynamic-currency-notice"; - dccMessage.dataset["currency"] = paymentMethod.currency; - dccMessage.dataset["original"] = formatMoney(this.session.amount, this.session.currency); - dccMessage.dataset["converted"] = formatMoney(paymentMethod.amount, paymentMethod.currency); - if (paymentMethod.customer_fee) { - dccMessage.key = "dynamic-currency-notice-with-fee"; - dccMessage.dataset["total"] = formatMoney( - paymentMethod.amount + paymentMethod.customer_fee, - paymentMethod.currency - ); - } - listItem.title = `1 ${this.session.currency} = ${rate} ${paymentMethod.currency}`; - listItem.classList.add("dynamic-currency"); - listItem.append(dccMessage); - priceInfo.append(listItem); - } - } - startFade() { - const fade = document.createElement("komoju-fade"); - setTimeout(() => fade.classList.add("show"), 0); - this.querySelector(".fields")?.prepend(fade); - } - endFade() { - this.querySelectorAll("komoju-fade").forEach((el) => { - const fade = el; - fade.classList.remove("show"); - setTimeout(() => fade.remove(), 500); - }); - } -}; - -// src/shared/komoju-error-element.ts -var KomojuErrorElement = class extends HTMLElement { - constructor() { - super(); - const root = this.attachShadow({ mode: "open" }); - const container = document.createElement("div"); - this.container = container; - container.style.height = "0"; - container.style.transition = "height 0.2s ease-in-out"; - const slot = document.createElement("slot"); - container.append(slot); - root.append(container); - } - connectedCallback() { - this.container.style.height = this.container.scrollHeight + "px"; - const resizeObserver = new ResizeObserver((_) => { - this.container.style.height = this.container.scrollHeight + "px"; - }); - resizeObserver.observe(this.container); - } - remove() { - this.classList.add("removing"); - this.container.style.height = "0"; - window.setTimeout(() => { - super.remove(); - }, 200); - } -}; - -// src/shared/komoju-fade-element.ts -var KomojuFadeElement = class extends HTMLElement { - connectedCallback() { - const fields = this.parentElement; - if (!fields) - return; - this.resizeObserver = new ResizeObserver((entries) => { - const { width, height } = entries[0].contentRect; - this.style.width = `${width}px`; - this.style.height = `${height}px`; - }); - this.resizeObserver?.observe(fields); - } - disconnectedCallback() { - this.resizeObserver?.disconnect(); - this.resizeObserver = void 0; - } -}; - -// src/fields-iframe.ts -window.customElements.define("komoju-host", KomojuHostElement); -window.customElements.define("komoju-error", KomojuErrorElement); -window.customElements.define("komoju-i18n", KomojuI18nElement); -window.customElements.define("komoju-fade", KomojuFadeElement); -(async () => { - const moduleName = "error-reporting"; - const module = await import(`${env_default.CDN}/extras/${moduleName}/module.js`); - const onerror = (event) => { - const error = event instanceof ErrorEvent ? event.error : event.reason; - if (!(error instanceof Error)) - return; - module.reportError(error); - }; - window.addEventListener("error", onerror); - window.addEventListener("unhandledrejection", onerror); -})(); -//# sourceMappingURL=fields-iframe.js.map diff --git a/src/app/code/Komoju/Payments/view/frontend/web/js/fields-iframe.js.map b/src/app/code/Komoju/Payments/view/frontend/web/js/fields-iframe.js.map deleted file mode 100644 index 2c852c0cb..000000000 --- a/src/app/code/Komoju/Payments/view/frontend/web/js/fields-iframe.js.map +++ /dev/null @@ -1,7 +0,0 @@ -{ - "version": 3, - "sources": ["../src/shared/validation.ts", "../src/shared/komoju-i18n-element.ts", "../src/shared/money.ts", "../src/shared/komoju-api.ts", "../src/shared/themable.ts", "../src/generated/env.ts", "../src/generated/supported-payment-types.ts", "../src/shared/translations.ts", "../src/i18n.ts", "../src/shared/message-broker.ts", "../src/komoju-host-element.ts", "../src/shared/komoju-error-element.ts", "../src/shared/komoju-fade-element.ts", "../src/fields-iframe.ts"], - "sourcesContent": ["// Adds validation to an input element.\nexport function addValidation(\n _i18n: Translations, // Used only by typescript to compile-time catch missing translations.\n input: HTMLInputElement,\n callback: (input: HTMLInputElement) => keyof Translations['en'] | null\n) {\n // Add a class so that we know this input has validation.\n input.classList.add('has-validation');\n\n // Tiny detail: if the user has never inputted anything, we don't want to run validations at all\n // at the risk of showing an error message when the user is just clicking around.\n input.addEventListener('input', () => {\n input.dataset.validationDirty = 'true';\n });\n\n // Validation function. This will be called on 'blur' and also on a custom 'validate' event.\n const validate = (event: Event) => {\n const input = event.target as HTMLInputElement;\n\n const errorMessageKey = callback(input);\n\n if (errorMessageKey) {\n showError(_i18n, input, errorMessageKey);\n }\n };\n input.addEventListener('blur', (event) => {\n if (input.dataset.validationDirty !== 'true') return;\n else return validate(event);\n });\n input.addEventListener('validate', validate);\n\n // When the user focuses on the input, remove all error artifacts.\n input.addEventListener('focus', (event) => {\n const input = event.target as HTMLInputElement;\n clearErrors(input);\n });\n}\n\nexport function showError(\n _i18n: Translations, // Used only by typescript to compile-time catch missing translations.\n input: HTMLInputElement,\n messageKey: keyof Translations['en']\n) {\n input.classList.add('invalid');\n const key = messageKey as string;\n\n // We don't want to show the same error twice!\n const container = input.parentElement;\n const dupeSelector = `komoju-error:not(.removing) > komoju-i18n[key=\"${key}\"]`;\n if (container?.querySelector(dupeSelector)) {\n return;\n }\n\n container?.append(createErrorElement(messageKey as string));\n}\n\nexport function clearErrors(input: HTMLInputElement) {\n input.classList.remove('invalid');\n input.parentElement?.querySelectorAll('komoju-error:not(.removing)').forEach((element) => {\n element.remove();\n });\n}\n\n// Runs validations on an element.\nexport function runValidation(input: HTMLInputElement) {\n // Fire the 'validate' custom event.\n input.dispatchEvent(new CustomEvent('validate'));\n\n // If there's an error message, return it.\n const errorMessage = input.parentElement?.querySelector('komoju-error:not(.removing)')?.textContent;\n return errorMessage ?? null;\n}\n\n// Creates the error message element that appears under an invalid input.\n// Mainly just called by addValidation().\nexport function createErrorElement(messageKey: string) {\n const el = window.document.createElement('komoju-error');\n const i18nEl = window.document.createElement('komoju-i18n') as KomojuI18nElement;\n i18nEl.key = messageKey;\n el.appendChild(i18nEl);\n return el;\n}\n", "// Language gets stored in here, mostly controlled by .\ndeclare let window: WindowWithKomojuGlobals;\n\nconst defaultLanguage = 'en';\n\ntype Queryable = {\n querySelectorAll: Document['querySelectorAll'];\n};\n\nexport function broadcastLocaleChange(root: Queryable, locale: string) {\n root.querySelectorAll('komoju-i18n').forEach((element) => {\n const i18n = element as KomojuI18nElement;\n i18n.render(locale);\n });\n}\n\n// This is a element that we use internally for displaying translated text\nexport default class KomojuI18nElement extends HTMLElement {\n static get observedAttributes() {\n return ['key'];\n }\n\n // Attribute: key\n // The key of the translation to display.\n get key() {\n return this.getAttribute('key');\n }\n set key(value) {\n this.setAttribute('key', value ?? '');\n }\n\n connectedCallback() {\n this.render();\n }\n\n attributeChangedCallback(name: string, _oldValue: string, _newValue: string) {\n if (name === 'key') this.render();\n }\n\n // Search up the DOM until we find a parent element with a locale attribute.\n findLocale() {\n let parent = this.parentElement;\n while (parent && !parent.getAttribute('locale')) {\n parent = parent.parentElement;\n }\n return parent?.getAttribute('locale') ?? defaultLanguage;\n }\n\n render(locale?: string) {\n if (!this.key) return;\n\n if (!locale) locale = this.findLocale();\n if (!Object.keys(window.komojuTranslations).includes(locale)) locale = defaultLanguage;\n\n const lang = locale.substring(0, 2);\n\n const message = window.komojuTranslations[lang][this.key];\n if (!message) {\n console.error(`KOMOJU bug: missing translation for key: ${this.key}`);\n return;\n }\n\n // Perform interpolation\n const matches = message.match(/%\\{[\\w-]+\\}/g);\n if (matches) {\n let result = message;\n matches.forEach((match) => {\n const key = match.replace(/%{|}/g, '');\n const value = this.dataset[key];\n if (value) result = result.replace(match, value);\n });\n this.textContent = result;\n return;\n }\n\n this.textContent = message;\n }\n}\n", "export const noDecimalCurrencies = [\n 'BIF', // Burundian Franc\n 'CLP', // Chilean Peso\n 'DJF', // Djiboutian Franc\n 'GNF', // Guinean Franc\n 'JPY', // Japanese Yen\n 'KMF', // Comorian Franc\n 'KRW', // South Korean Won\n 'MGA', // Malagasy Ariary\n 'PYG', // Paraguayan Guaran\u00ED\n 'RWF', // Rwandan Franc\n 'UGX', // Ugandan Shilling\n 'VND', // Vietnamese \u0110\u1ED3ng\n 'VUV', // Vanuatu Vatu\n 'XAF', // Central African Cfa Franc\n 'XOF', // West African Cfa Franc\n 'XPF', // Cfp Franc\n];\n\n// Currently modern browsers depend on ISO 4217\n//\n// We do support non-fiat currencies which are not part of the\n// ISO standard and require us to build formatters for\nconst nonISOCurrencies = [\n 'USDC'\n]\n\nconst displayCurrencyCodeInsteadOfSymbol = [\n 'CNY',\n];\n\nexport function formatMoney(amountCents: number, currency: string, locale: string = 'en') {\n function nonISOFormat(currency: string, amountCents: number) {\n if (!amountCents) {\n return '';\n } else if (nonISOCurrencies.includes(currency) || !currency) {\n return `${amountCents.toLocaleString()} ${currency}`;\n } else {\n throw 'invalid currency format';\n }\n }\n\n const amountDecimal = decentify(amountCents, currency);\n\n if (nonISOCurrencies.includes(currency) || !currency) {\n return nonISOFormat(currency, amountDecimal)\n } else {\n const numberFormat = new Intl.NumberFormat(`${locale}-JP`, {\n style: 'currency',\n currency: currency,\n currencyDisplay: displayCurrencyCodeInsteadOfSymbol.includes(currency) ? \"code\" : \"symbol\"\n });\n\n return numberFormat.format(amountDecimal);\n }\n};\n\nexport function decentify(amountCents: number, currency: string) {\n return noDecimalCurrencies.includes(currency) ? amountCents : amountCents / 100.0;\n}\n", "// fetch wrapper with KOMOJU authentication already handled.\nexport function komojuFetch(\n config: {\n komojuApi: string,\n publishableKey: string | null,\n },\n method: 'GET' | 'POST',\n path: string,\n body?: object\n): Promise {\n if (!config.komojuApi) throw new Error('KOMOJU API URL is null');\n if (!config.publishableKey) throw new Error('KOMOJU publishable-key not set');\n\n return fetch(`${config.komojuApi}${path}`, {\n method,\n headers: {\n accept: 'application/json',\n 'content-type': 'application/json',\n authorization: `Basic ${btoa(`${config.publishableKey}:`)}`,\n 'komoju-via': 'fields',\n },\n body: body ? JSON.stringify(body) : undefined\n });\n}\n", "export default class Themable extends HTMLElement {\n // Attribute: theme\n // CSS file to use as a theme.\n get theme() {\n return this.getAttribute('theme');\n }\n set theme(value) {\n this.setAttribute('theme', value ?? '');\n }\n\n applyTheme() {\n const root = this.shadowRoot ?? document;\n\n if (this.theme === null) {\n root.querySelectorAll('#theme,#inline-theme').forEach(el => el.remove());\n } else if (this.theme.startsWith('http') || this.theme.startsWith('/') || this.theme.startsWith('data:')) {\n this.applyExternalTheme(root, this.theme);\n } else {\n this.applyInlineTheme(root, this.theme);\n }\n }\n\n applyInlineTheme(root: ParentNode, theme: string) {\n root.querySelectorAll('#theme,#inline-theme').forEach(el => el.remove());\n\n const style = document.createElement('style');\n style.id = 'inline-theme';\n style.textContent = theme;\n this.appendStyleTag(style);\n }\n\n applyExternalTheme(root: ParentNode, theme: string) {\n root.querySelectorAll('#inline-theme').forEach(el => el.remove());\n let link = root.querySelector('#theme') as HTMLLinkElement | null;\n if (link) {\n if (link.href !== this.theme) link.href = theme;\n } else {\n link = document.createElement('link');\n link.id = 'theme';\n link.rel = 'stylesheet';\n link.href = theme;\n this.appendStyleTag(link);\n }\n }\n\n appendStyleTag(style: HTMLLinkElement | HTMLStyleElement) {\n if (this.shadowRoot) {\n this.shadowRoot.append(style);\n }\n else {\n document.head.append(style);\n }\n }\n}\n", "// Generated by bin/generate.sh\n//\n// This file pulls from environment variables (and git).\n\nexport default {\n \"CDN\": \"https://multipay.komoju.com\",\n \"ENV\": \"development\",\n \"HONEYBADGER_API_KEY\": \"\",\n \"GIT_REV\": \"99ad2eb29ce6530dedfe3a0ec34aea970dbaa78a\",\n};\n", "// Generated by bin/generate.sh\n//\n// List of supported payment types comes from the folders in src/fields/*.\n// To add a new one, simply add a new folder.\n\nconst supported: Set = new Set();\nsupported.add('bank_transfer');\nsupported.add('credit_card');\nsupported.add('konbini');\nsupported.add('offsite');\nexport default supported;\n", "declare let window: WindowWithKomojuGlobals;\n\n// Call this to add messages to the registry.\n// Individual payment method modules can do this to add their own messages.\n// That way, we avoid needing to load all messages for every payment method upfront.\nexport function registerMessages(messages: I18n) {\n if (!window.komojuTranslations) {\n window.komojuTranslations = { 'en': {}, 'ja': {} };\n }\n\n for (const lang of Object.keys(window.komojuTranslations)) {\n window.komojuTranslations[lang] = {\n ...window.komojuTranslations[lang],\n ...messages[lang],\n };\n }\n}\n", "export const en = {\n 'customer-fee-will-be-charged': 'A fee of %{fee} will be included.',\n 'dynamic-currency-notice': 'Payment will be made in %{currency}: %{original} \u2192 %{converted}.',\n 'dynamic-currency-notice-with-fee': 'Payment will be made in %{currency}: %{original} \u2192 %{converted}. (total: %{total})',\n 'payment-method-unavailable': 'This payment method is currently unavailable.',\n 'verification-failed': 'Verification failed.',\n 'close': 'Close',\n};\n\nexport const ja: typeof en = {\n 'customer-fee-will-be-charged': '%{fee}\u306E\u624B\u6570\u6599\u304C\u8FFD\u52A0\u3055\u308C\u307E\u3059\u3002',\n 'dynamic-currency-notice': '\u652F\u6255\u3044\u306F%{currency}\u3067\u6C7A\u6E08\u3055\u308C\u307E\u3059: %{original} \u2192 %{converted}\u3002',\n 'dynamic-currency-notice-with-fee': '\u652F\u6255\u3044\u306F%{currency}\u3067\u6C7A\u6E08\u3055\u308C\u307E\u3059: %{original} \u2192 %{converted}\u3002(\u5408\u8A08%{total})',\n 'payment-method-unavailable': '\u3053\u306E\u652F\u6255\u3044\u65B9\u6CD5\u306F\u73FE\u5728\u3054\u5229\u7528\u3044\u305F\u3060\u3051\u307E\u305B\u3093\u3002',\n 'verification-failed': '\u8A8D\u8A3C\u306B\u5931\u6557\u3057\u307E\u3057\u305F\u3002',\n 'close': '\u9589\u3058\u308B',\n};\n", "export interface Message {\n type: string,\n}\nexport interface FullMessage extends Message {\n brokerId: string,\n id: string,\n}\n\ninterface MessageAck extends FullMessage {\n type: 'ack',\n response?: Message,\n}\n\ntype MessageBrokerArgs = { send: Window, receive: Window };\n\ntype TypedMessageListener = (arg: T) => Promise | Message | undefined | void;\ntype MessageListener = TypedMessageListener;\n\n// Wrapper around postMessage events that lets us use promises instead of\n// disjoint \"send\" and \"receive\" flows.\nexport class MessageBroker {\n // Keep track of which window to send to and which to receive on.\n // These are promises so that we can effectively buffer messages until the window is ready.\n _sendWindow: Promise;\n _receiveWindow: Promise;\n _setSendWindow?: (value: Window) => void;\n _setReceiveWindow?: (value: Window) => void;\n\n // Raw \"message\" event listener. We need to keep track of this so we can remove it later.\n messageHandler: (event: MessageEvent) => void;\n\n // Map of in-progress promises. When we receive an ack message with a matching id, we resolve the promise.\n promises: Map,\n resolve: (value?: Message) => void,\n }>;\n\n // Map of listeners. When we receive a message with a matching type, we call the listener.\n listeners: Map;\n\n // Unique id for this broker. Used to distinguish messages from other brokers.\n id: string;\n\n origin: string;\n\n constructor(id?: string) {\n this._sendWindow = new Promise(resolve => this._setSendWindow = resolve);\n this._receiveWindow = new Promise(resolve => this._setReceiveWindow = resolve);\n\n this.messageHandler = event => {\n if (this.origin !== '*' && event.origin !== this.origin) return;\n this.handleMessage(event);\n };\n\n this.id = id ?? crypto.randomUUID();\n this.origin = '*';\n this.promises = new Map();\n this.listeners = new Map();\n }\n\n // Call this to set up the broker\n setup(arg: MessageBrokerArgs) {\n if (this._setSendWindow) {\n this._setSendWindow(arg.send);\n this._setSendWindow = undefined;\n } else {\n this._sendWindow = Promise.resolve(arg.send);\n }\n\n if (this._setReceiveWindow) {\n this._setReceiveWindow(arg.receive);\n this._setReceiveWindow = undefined;\n } else {\n this._receiveWindow = Promise.resolve(arg.receive);\n }\n\n arg.receive.addEventListener('message', this.messageHandler);\n }\n\n // Call this to send a message. Promise will resolve when the associated ack message\n // comes back.\n send(message: MessageType): Promise {\n const fullMessage: FullMessage = {\n ...message,\n brokerId: this.id,\n id: crypto.randomUUID(),\n };\n\n let resolve: ((value?: Message) => void) | null = null;\n const promise = new Promise((resolvePromise, _reject) => {\n resolve = resolvePromise;\n });\n if (!resolve) throw new Error('Broker is busted');\n\n this.promises.set(fullMessage.id, { promise, resolve });\n return this._sendWindow.then(w => w.postMessage(fullMessage, this.origin)).then(() => promise);\n }\n\n // Call this to set the listener for a certain event. Kind of like the built-in\n // addEventListener, but can only add one per event type.\n receive(type: MessageType['type'], listener: TypedMessageListener) {\n this.listeners.set(type, listener as MessageListener);\n }\n\n // Internal message handler\n async handleMessage(event: MessageEvent) {\n const message = event.data;\n\n // Ignore messages from other brokers\n if (message.brokerId !== this.id) return;\n\n // 'ack' messages resolve an in-progress promise\n if (message.type === 'ack') {\n const ack = message as MessageAck;\n const promise = this.promises.get(ack.id);\n\n // Acks with a wrong ID typically come from another tag\n // in the same window.\n if (!promise) return;\n\n promise.resolve(ack.response);\n this.promises.delete(ack.id);\n }\n // all other messages trigger a local listener if present\n else {\n const listener = this.listeners.get(message.type);\n const ack: MessageAck = { type: 'ack', brokerId: this.id, id: message.id };\n if (listener) ack.response = (await listener(message)) ?? undefined;\n await this._sendWindow.then(w => w.postMessage(ack, this.origin));\n }\n }\n\n // Call this to clean up the window event listener\n destroy() {\n return this._receiveWindow.then(w => w.removeEventListener('message', this.messageHandler));\n }\n}\n", "import spinner from './shared/spinner.html';\nimport { runValidation } from './shared/validation';\nimport KomojuI18nElement, { broadcastLocaleChange } from './shared/komoju-i18n-element';\nimport { formatMoney } from './shared/money';\nimport { komojuFetch } from './shared/komoju-api';\nimport Themable from './shared/themable';\nimport ENV from './generated/env';\nimport supportedPaymentTypes from './generated/supported-payment-types';\n\nimport { registerMessages } from './shared/translations';\nimport * as i18n from './i18n';\nimport { MessageBroker } from './shared/message-broker';\nregisterMessages(i18n);\n\nlet _baseKomojuAPI: string | undefined;\nfunction baseKomojuAPI() {\n if (_baseKomojuAPI) return _baseKomojuAPI;\n\n const url = new URL(window.location.href);\n const params = new URLSearchParams(url.hash.slice(1));\n _baseKomojuAPI = params.get('api') ?? 'https://komoju.com';\n return _baseKomojuAPI;\n}\n\nfunction brokerId() {\n const url = new URL(window.location.href);\n const params = new URLSearchParams(url.hash.slice(1));\n return params.get('broker') ?? undefined;\n}\n\nfunction i18nMessage(locale: string | null, key: keyof typeof i18n['en']): string | undefined {\n if (locale === 'ja') return (i18n.ja as any)[key];\n return (i18n.en as any)[key];\n}\n\nexport default class KomojuHostElement extends Themable implements KomojuFieldsConfig {\n static get observedAttributes() {\n console.log('KomojuHostElement::listenToMessagesFromMainWindow');\n\n return [\n 'komoju-api',\n 'session',\n 'session-id',\n 'publishable-key',\n 'payment-type',\n 'locale',\n 'theme',\n 'token',\n 'name',\n ];\n }\n\n // 'session' is also an attribute. Set the 'session' attribute to a stringified JSON of\n // the entire KOMOJU sesion to skip having to fetch it from KOMOJU again.\n _session: KomojuSession | null = null\n get session() {\n return this._session;\n }\n set session(value) {\n console.log('KomojuHostElement set session', value);\n\n this._session = value;\n this.broker.send({\n type: 'dispatch-event',\n name: 'komoju-session-change',\n detail: { session: this._session }\n });\n }\n\n module: {\n render: KomojuRenderFunction,\n paymentDetails: KomojuPaymentDetailsFunction\n } | null = null\n\n // Attribute: komoju-api\n // Usually this'll just be https://komoju.com, but sometimes we use other URLs.\n get komojuApi() {\n const attribute = this.getAttribute('komoju-api');\n if (!attribute || attribute === '') return baseKomojuAPI();\n else return attribute;\n }\n set komojuApi(value) {\n this.setAttribute('komoju-api', value ?? '');\n }\n\n // Attribute: session-id\n // KOMOJU Session ID. Create your session on the server then pass it in here.\n get sessionId() {\n return this.getAttribute('session-id');\n }\n set sessionId(value) {\n this.setAttribute('session-id', value ?? '');\n }\n\n // Attribute: publishable-key\n // KOMOJU publishable key. Get this from your merchant dashboard.\n get publishableKey() {\n return this.getAttribute('publishable-key');\n }\n set publishableKey(value) {\n this.setAttribute('publishable-key', value ?? '');\n }\n\n // Attribute: payment-type\n // Which payment type to show. If your session only has 1 payment type, this is unnecessary.\n // Alternatively, if a element is present, this will be set automatically.\n get paymentType() {\n return this.getAttribute('payment-type');\n }\n set paymentType(value) {\n this.setAttribute('payment-type', value ?? '');\n }\n\n // Attribute: locale\n // Language of text to show. Defaults to the browser's language.\n get locale() {\n return this.getAttribute('locale');\n }\n set locale(value) {\n this.setAttribute('locale', value ?? '');\n this.broker.send({\n type: 'dispatch-event',\n name: 'komoju-locale-change',\n detail: { locale: value }\n });\n }\n\n // Attribute: token\n // Boolean attribute - if present, will generate a token instead of processing payment.\n get token() {\n return this.hasAttribute('token');\n }\n set token(value) {\n if (value) this.setAttribute('token', '');\n else this.removeAttribute('token');\n }\n\n // Attribute: name\n // Similar to an input's name attribute. This is used in token mode, and is the name of the\n // input that will contain the token.\n get name() {\n return this.getAttribute('name');\n }\n set name(value) {\n if (value) this.setAttribute('name', value);\n else this.removeAttribute('name');\n }\n\n // Where to fetch payment method modules.\n get komojuCdn() {\n return ENV['CDN'];\n }\n\n get paymentMethod() {\n return this.session?.payment_methods.find(method => method.type === this.paymentType);\n }\n\n resizeObserver?: ResizeObserver;\n\n broker: MessageBroker = new MessageBroker(brokerId());\n\n // Reactive attribute handling. When session or payment type is changed, we want to re-render.\n async attributeChangedCallback(name: string, oldValue: string | null, newValue: string | null) {\n console.log('??? KomojuHostElement attributeChangedCallback', name, oldValue);\n console.log('###')\n console.log('NEW VALUE::KomojuHostElement attributeChangedCallback', name, newValue);\n\n if (name === 'session') {\n if (!newValue || newValue == '') return;\n\n this.session = JSON.parse(newValue);\n if (!this.locale) this.locale = this.session!.default_locale.substring(0, 2);\n if (!this.paymentType) this.paymentType = this.session!.payment_methods[0].type;\n this.render();\n }\n else if (name === 'session-id' || name === 'publishable-key') {\n if (!newValue || newValue == '') return;\n\n // Session ID and publishable key are both required to fetch a session, so when either\n // one changes, we re-fetch the session.\n if (!this.publishableKey) return;\n if (!this.sessionId) return;\n\n const response = await this.komojuFetch('GET', `/api/v1/sessions/${this.sessionId}`);\n\n if (response.status === 404) {\n console.error('Invalid KOMOJU session ID', this.sessionId);\n return;\n }\n\n if (response.status !== 200) {\n console.error('Failed to retrieve KOMOJU session', response);\n return;\n }\n\n this.session = await response.json();\n if (!this.session) throw new Error('KOMOJU returned a null session');\n if (!this.paymentType) this.paymentType = this.session.payment_methods[0].type;\n if (!this.locale) this.locale = this.session.default_locale.substring(0, 2);\n\n this.render();\n }\n else if (name === 'payment-type') {\n if (!newValue || newValue == '') return;\n if (!this.session) return;\n if (!this.publishableKey) return;\n this.startFade();\n await this.render();\n }\n else if (name === 'locale') {\n if (!newValue || newValue == '' || oldValue === newValue) return;\n broadcastLocaleChange(this, newValue);\n }\n else if (name === 'theme') {\n this.applyTheme();\n }\n }\n\n connectedCallback() {\n console.log('KomojuHostElement connectedCallback')\n // We start by just showing a spinner.\n this.innerHTML = spinner;\n console.log(`${JSON.stringify(this.broker)}, broker`)\n\n // Set up message broker to communicate with the parent window.\n this.listenToMessagesFromMainWindow(this.broker);\n this.broker.setup({\n send: window.parent,\n receive: window,\n });\n\n // Set up resize observer so that the iframe can resize itself.\n const body = this.ownerDocument?.body;\n this.resizeObserver = new ResizeObserver(() => {\n const height = body.parentElement!.offsetHeight;\n if (height === 0) return;\n this.broker.send({ type: 'resize', height: height.toString() });\n });\n if (body) this.resizeObserver.observe(body, { box: 'border-box' });\n }\n\n disconnectedCallback() {\n this.broker.destroy();\n this.resizeObserver?.disconnect();\n this.resizeObserver = undefined;\n }\n\n listenToMessagesFromMainWindow(broker: MessageBroker) {\n console.log('KomojuHostElement listenToMessagesFromMainWindow');\n\n // Sync attributes from parent window.\n broker.receive('attr', (message) => {\n // Avoid XSS by restricting which attrs we're willing to receive.\n if (!KomojuHostElement.observedAttributes.includes(message.attr)) return;\n\n console.log('KomojuHostElement listenToMessagesFromMainWindow attr', message);\n\n if (message.value === null || message.value === undefined) this.removeAttribute(message.attr);\n else this.setAttribute(message.attr, message.value);\n });\n\n // Submit when parent komoju-fields element's submit function is called.\n broker.receive('submit', () => {\n return this.submit();\n });\n\n // Expose the endFade function.\n broker.receive<{ type: 'end-fade' }>('end-fade', () => {\n this.endFade();\n });\n }\n\n // Submits payment details securely to KOMOJU before redirecting.\n // The redirect target may be\n // 1. A URL for performing 3DS authentication\n // 2. An external payment provider URL (i.e. to log into a payment app or show a QR code)\n // 3. The session's return_url in the case where payment is completed instantly\n async submit(): Promise {\n if (!this.module || !this.session) {\n return { type: 'submit-result', errors: ['Attempted to submit before selecting KOMOJU Payment method'] };\n }\n const paymentMethod = this.paymentMethod;\n if (!paymentMethod) throw new Error(`KOMOJU Payment method not found: ${this.paymentType}`);\n\n // Check for invalid input\n this.querySelectorAll('komoju-error').forEach(error => error.remove());\n const validatedFields = this.querySelectorAll('.has-validation');\n const errors = Array.prototype.map.call(validatedFields, (field) =>\n field instanceof HTMLInputElement ? runValidation(field) : null\n );\n if (errors.some(error => error != null)) {\n return { type: 'submit-result', errors: errors.filter(error => error != null) };\n }\n\n // Now we can pull the payment details hash from the payment method module\n // and send it to KOMOJU.\n this.startFade();\n const paymentDetails = this.module.paymentDetails(this, paymentMethod);\n\n if (this.token) {\n return await this.submitToken(paymentDetails);\n }\n else {\n return await this.submitPayment(paymentDetails);\n }\n }\n\n // Called by submit,\n // submits payment directly to KOMOJU for processing.\n async submitPayment(paymentDetails: object): Promise {\n const paymentMethod = this.paymentMethod;\n if (!paymentMethod) {\n throw new Error('Attempted to submit before selecting KOMOJU Payment method');\n }\n const session = this.session!;\n\n // If the payment method is not supported by KOMOJU Fields, we can still redirect straight\n // to the session URL, effectively supporting *all* payment methods.\n let moduleName = paymentMethod.offsite ? 'offsite' : paymentMethod.type;\n if (!supportedPaymentTypes.has(moduleName)) {\n const result: KomojuSubmitResult = {\n type: 'submit-result',\n pay: {\n status: 'pending',\n redirect_url: `${session.session_url}#${paymentMethod.type}`,\n },\n };\n return result;\n }\n\n // Special case for 3DS\n let secureTokenId: string | null = null;\n if (paymentMethod.type === 'credit_card' && session.mode !== 'customer') try {\n const { secureToken, error, skip } = await this.do3DS(paymentDetails);\n\n if (secureToken) {\n secureTokenId = secureToken.id\n } else if (error && !skip) {\n return {\n type: 'submit-result',\n errors: [error]\n }\n }\n } catch(e) {\n console.error('Error during secure token flow. Continuing without.', e);\n }\n\n const payResponse = await this.komojuFetch('POST', `/api/v1/sessions/${session.id}/pay`, {\n payment_details: secureTokenId ?? paymentDetails,\n api_locale: this.locale\n });\n const payResult = await payResponse.json() as KomojuPayResult;\n\n const result: KomojuSubmitResult = {\n type: 'submit-result',\n pay: payResult,\n };\n\n if (payResult.error) {\n console.error(payResult);\n this.handleApiError(payResult.error);\n this.endFade();\n }\n\n return result;\n }\n\n // Special case for credit card. Called by both submitToken and submitPayment.\n // The dialog element that handles this exists in the element,\n // so we use broker to send a message to the parent window.\n async do3DS(paymentDetails: object): Promise {\n const { secureToken, error } = await this.submitSecureToken(paymentDetails);\n\n // If the card brand is unsupported, we have no choice but to skip 3DS.\n if (error && error.code === 'unsupported_card_brand') {\n return {\n error,\n skip: true,\n }\n }\n\n if (error) return { error };\n else if (!secureToken) throw new Error('Secure token empty response');\n\n const status = secureToken.verification_status;\n\n // Secure tokens with these statuses are usable as-is.\n if (status === 'OK' || status === 'SKIPPED') {\n return { secureToken };\n }\n\n // Secure token starting in an ERRORED state means misconfiguration in KOMOJU.\n // If possible, we don't want that to get in the way of payment.\n if (status === 'ERRORED') {\n return {\n skip: true,\n }\n }\n\n // This passes off control to the element.\n // Also should note that this will await until the user finishes interacting with the\n // dialog, so we might be waiting for a long time here.\n const dialogResult = await this.broker.send({\n type: 'dialog-start',\n url: secureToken.authentication_url,\n });\n\n if (dialogResult?.type !== 'dialog-result') {\n throw new Error('Expected dialog-result, got ' + JSON.stringify(dialogResult));\n } else {\n const { result } = dialogResult as KomojuDialogResult;\n\n // If the card brand is unsupported, we have no choice but to skip 3DS.\n if (result.error && result.error.code === 'unsupported_card_brand') {\n return {\n error: result.error,\n skip: true,\n };\n }\n\n if (result.error) {\n this.handleApiError(result.error);\n this.endFade();\n return result;\n }\n\n // Verification status can be \"ERRORED\" when the user intentionally clicks \"cancel\".\n // In any case, we need a full stop here and so we should *not* return the secure token,\n // as doing so will signal to the caller that we want to continue with processing.\n if (result.secureToken && result.secureToken.verification_status === 'ERRORED') {\n const error = i18nMessage(this.locale, 'verification-failed') ?? '3DS error';\n this.handleApiError(error);\n this.endFade();\n return {\n error: {\n code: 'verification_status_errored',\n message: error,\n param: null,\n details: null,\n }\n };\n }\n\n return result;\n }\n }\n\n async submitSecureToken(paymentDetails: object): Promise {\n const session = this.session!;\n const returnURL = new URL(this.komojuCdn);\n returnURL.pathname = '/secure-token-return.html';\n returnURL.searchParams.set('session_id', session.id);\n\n const secureTokenResponse = await this.komojuFetch('POST', `/api/v1/secure_tokens`, {\n amount: session.amount,\n currency: session.currency,\n payment_details: paymentDetails,\n return_url: returnURL,\n });\n if (secureTokenResponse.status >= 400) {\n const error = (await secureTokenResponse.json()).error as KomojuApiError;\n return { error };\n }\n const secureToken = await secureTokenResponse.json() as KomojuSecureToken;\n\n return { secureToken };\n }\n\n async handleApiError(error: string | KomojuApiError) {\n if (!this.broker) throw new Error('KOMOJU Fields bug: broker should be set by now');\n\n // Emit an event so implementers can handle this.\n const result = await this.broker.send({\n type: 'dispatch-event',\n name: 'komoju-error',\n detail: { error },\n });\n if (!result || result.type !== 'dispatch-result') {\n throw new Error('Expected dispatch-result, got ' + JSON.stringify(result));\n }\n\n // Show errors if implementers don't cancel the event.\n if ((result as KomojuDispatchResult).cancel) return;\n\n this.querySelectorAll('.generic-error-message').forEach(container => {\n const errorText = document.createElement('komoju-error');\n if (typeof error === 'string') {\n errorText.textContent = error;\n } else if (error.message) {\n errorText.textContent = error.message;\n }\n container.append(errorText);\n });\n }\n\n // Called by submit,\n // uses payment info to create a token that can be safely transmitted to the backend and used there.\n async submitToken(paymentDetails: any): Promise {\n // Credit cards should create a secure token instead.\n if (paymentDetails.type === 'credit_card') {\n const { secureToken, error, skip } = await this.do3DS(paymentDetails);\n // If card brand doesn't support 3DS then we can continue without.\n\n if (error && !skip) {\n return { type: 'submit-result', errors: [error] };\n } else if (secureToken) {\n return {\n type: 'submit-result',\n token: secureToken,\n };\n }\n }\n\n const tokenResponse = await this.komojuFetch('POST', `/api/v1/tokens`, {\n payment_details: paymentDetails\n });\n if (tokenResponse.status >= 400) {\n const error = (await tokenResponse.json()).error as KomojuApiError;\n this.handleApiError(error);\n this.endFade();\n return { type: 'submit-result', errors: [error.message] };\n }\n const token = await tokenResponse.json() as KomojuToken;\n return {\n type: 'submit-result',\n token\n };\n }\n\n // The below render() function often ends up being called multiple times before the previous\n // one finishes. Then they're racing to replace the DOM, which can cause weird bugs.\n // This little counter lets us ignore any renders that are not the most recent one.\n _renderCount = 0;\n\n // Renders fields for the selected payment method.\n // Usually implementers would not need to call this manually.\n async render() {\n if (!this.session) throw new Error('KOMOJU Session not loaded');\n\n const paymentMethod = this.session.payment_methods.find(method => method.type === this.paymentType);\n\n // This helps us avoid race conditions if render() gets called twice in quick succession\n // (common occurrence - session attr and payment-type attr often cause 2 renders)\n const thisRender = ++this._renderCount;\n\n if (!paymentMethod) {\n // Render \"invalid payment method\" text\n const errorElement = document.createElement('komoju-error');\n const errorMessage = document.createElement('komoju-i18n') as KomojuI18nElement;\n errorMessage.key = 'payment-method-unavailable';\n errorElement.append(errorMessage);\n this.replaceChildren(errorElement);\n this.applyTheme();\n return;\n }\n\n // Grab the module for the payment method (name of a folder in src/fields)\n let moduleName = paymentMethod.type;\n if (!supportedPaymentTypes.has(moduleName)) {\n // The offsite module works as a catch-all for payment methods that don't have their own module.\n moduleName = 'offsite';\n }\n\n const module = await import(`${this.komojuCdn}/fields/${moduleName}/module.js`);\n if (thisRender !== this._renderCount) return; // This render is no longer the most recent one\n\n this.module = module;\n if (!this.module) throw new Error(`KOMOJU Payment module not found: ${this.paymentType}`);\n\n // Render payment method fields\n this.module.render(this, paymentMethod);\n\n // Make IME status easily accessible to JS. Payment method modules can use this to avoid\n // auto-formatting while IME composition is still in progress.\n this.querySelectorAll('input').forEach((input) => {\n input.addEventListener('compositionstart', () => {\n input.dataset.ime = 'active';\n });\n input.addEventListener('compositionend', () => {\n input.dataset.ime = 'inactive';\n });\n });\n\n // Add theme styles\n this.applyTheme();\n\n // Add price info (customer fee, dynamic currency)\n const priceInfo = this.querySelector('.price-info');\n if (!priceInfo) return;\n\n // Customer fee\n if (paymentMethod.customer_fee) {\n const listItem = document.createElement('li');\n const feeMessage = document.createElement('komoju-i18n') as KomojuI18nElement;\n listItem.classList.add('customer-fee');\n feeMessage.key = 'customer-fee-will-be-charged';\n feeMessage.dataset['fee'] = formatMoney(\n paymentMethod.customer_fee,\n paymentMethod.currency ?? this.session.currency\n );\n listItem.append(feeMessage);\n priceInfo.append(listItem);\n }\n\n // Dynamic currency (DCC)\n if (\n paymentMethod.exchange_rate &&\n paymentMethod.amount &&\n paymentMethod.currency &&\n paymentMethod.currency !== this.session.currency\n ) {\n const listItem = document.createElement('li');\n const dccMessage = document.createElement('komoju-i18n') as KomojuI18nElement;\n const rate = Math.round(paymentMethod.exchange_rate * 10000) / 10000;\n dccMessage.key = 'dynamic-currency-notice';\n dccMessage.dataset['currency'] = paymentMethod.currency;\n dccMessage.dataset['original'] = formatMoney(this.session.amount, this.session.currency);\n dccMessage.dataset['converted'] = formatMoney(paymentMethod.amount, paymentMethod.currency);\n if (paymentMethod.customer_fee) {\n dccMessage.key = 'dynamic-currency-notice-with-fee';\n dccMessage.dataset['total'] = formatMoney(\n paymentMethod.amount + paymentMethod.customer_fee,\n paymentMethod.currency\n );\n }\n listItem.title = `1 ${this.session.currency} = ${rate} ${paymentMethod.currency}`;\n listItem.classList.add('dynamic-currency');\n listItem.append(dccMessage);\n priceInfo.append(listItem);\n }\n }\n\n // fetch wrapper with KOMOJU authentication already handled.\n komojuFetch = komojuFetch.bind(this, this)\n\n // Fade out fields while loading\n private startFade() {\n const fade = document.createElement('komoju-fade');\n setTimeout(() => fade.classList.add('show'), 0);\n this.querySelector('.fields')?.prepend(fade);\n }\n\n // Remove the fade effect created by startFade()\n private endFade() {\n this.querySelectorAll('komoju-fade').forEach(el => {\n const fade = el as HTMLElement;\n fade.classList.remove('show');\n // Fade animation time is 0.5s in static/shared.css right now.\n setTimeout(() => fade.remove(), 500);\n });\n }\n}\n", "// This is a error tag we use internally for displaying validation errors.\n// End users are not expected to use this.\nexport default class KomojuErrorElement extends HTMLElement {\n container: HTMLElement;\n\n constructor() {\n super();\n const root = this.attachShadow({ mode: 'open' });\n\n // This container will stretch and shrink as the error message appears and disappears.\n const container = document.createElement('div');\n this.container = container;\n container.style.height = '0';\n container.style.transition = 'height 0.2s ease-in-out';\n\n // This element's contents appears inside of the container.\n const slot = document.createElement('slot');\n container.append(slot);\n\n root.append(container);\n }\n\n // Animate the height of the error message when it appears on the page. Resize height to adjust\n // changes in width.\n connectedCallback() {\n this.container.style.height = this.container.scrollHeight + 'px';\n\n // Make sure this height adjusts if the parent element's width changes.\n const resizeObserver = new ResizeObserver((_) => {\n // Adjust the height when the observed element's size changes\n this.container.style.height = this.container.scrollHeight + 'px';\n });\n\n resizeObserver.observe(this.container);\n }\n\n // Animates the height of the error message when it is removed from the page.\n override remove() {\n this.classList.add('removing');\n this.container.style.height = '0';\n window.setTimeout(() => {\n super.remove();\n }, 200);\n }\n}\n", "// This is . It's used internally to fade out the fields temporarily during submit.\n// This prevents double submits and also signals to the user that something is happening.\n//\n// must be placed at the top of the .fields element, otherwise sizing and placement\n// won't work well.\nexport default class KomojuFadeElement extends HTMLElement {\n resizeObserver?: ResizeObserver;\n\n connectedCallback() {\n const fields = this.parentElement;\n if (!fields) return;\n\n this.resizeObserver = new ResizeObserver((entries) => {\n const { width, height } = entries[0].contentRect;\n this.style.width = `${width}px`;\n this.style.height = `${height}px`;\n });\n this.resizeObserver?.observe(fields);\n }\n\n disconnectedCallback() {\n this.resizeObserver?.disconnect();\n this.resizeObserver = undefined;\n }\n}\n", "import './types.d';\nimport KomojuHostElement from './komoju-host-element';\nimport KomojuErrorElement from './shared/komoju-error-element';\nimport KomojuI18nElement from './shared/komoju-i18n-element';\nimport KomojuFadeElement from './shared/komoju-fade-element';\nimport ENV from './generated/env';\n\n// \"Internal\" custom elements\nwindow.customElements.define('komoju-host', KomojuHostElement);\nwindow.customElements.define('komoju-error', KomojuErrorElement);\nwindow.customElements.define('komoju-i18n', KomojuI18nElement);\nwindow.customElements.define('komoju-fade', KomojuFadeElement);\n\n// Error reporting\n(async () => {\n // HACK: weird interpolation intentional because of typescript not knowing the type of the import.\n // I want the browser to actually make an async import request instead of having esbuild pull the\n // whole error-reporting module into the fields-iframe bundle.\n const moduleName = 'error-reporting';\n const module = await import(`${ENV.CDN}/extras/${moduleName}/module.js`);\n\n const onerror = (event: ErrorEvent | PromiseRejectionEvent) => {\n const error = (event instanceof ErrorEvent) ? event.error : (event.reason as Error);\n if (!(error instanceof Error)) return;\n\n module.reportError(error);\n }\n\n window.addEventListener('error', onerror);\n window.addEventListener('unhandledrejection', onerror);\n})();\n"], - "mappings": "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", - "names": ["currency", "amountCents", "result", "error"] -} diff --git a/src/app/code/Komoju/Payments/view/frontend/web/js/fields.js b/src/app/code/Komoju/Payments/view/frontend/web/js/fields.js deleted file mode 100644 index cd93f573d..000000000 --- a/src/app/code/Komoju/Payments/view/frontend/web/js/fields.js +++ /dev/null @@ -1,733 +0,0 @@ -var __defProp = Object.defineProperty; -var __export = (target, all) => { - for (var name in all) - __defProp(target, name, { get: all[name], enumerable: true }); -}; - -// src/generated/env.ts -var env_default = { - "CDN": "https://multipay.komoju.com", - "ENV": "development", - "HONEYBADGER_API_KEY": "", - "GIT_REV": "99ad2eb29ce6530dedfe3a0ec34aea970dbaa78a" -}; - -// src/shared/translations.ts -function registerMessages(messages) { - if (!window.komojuTranslations) { - window.komojuTranslations = { "en": {}, "ja": {} }; - } - for (const lang of Object.keys(window.komojuTranslations)) { - window.komojuTranslations[lang] = { - ...window.komojuTranslations[lang], - ...messages[lang] - }; - } -} - -// src/i18n.ts -var i18n_exports = {}; -__export(i18n_exports, { - en: () => en, - ja: () => ja -}); -var en = { - "customer-fee-will-be-charged": "A fee of %{fee} will be included.", - "dynamic-currency-notice": "Payment will be made in %{currency}: %{original} \u2192 %{converted}.", - "dynamic-currency-notice-with-fee": "Payment will be made in %{currency}: %{original} \u2192 %{converted}. (total: %{total})", - "payment-method-unavailable": "This payment method is currently unavailable.", - "verification-failed": "Verification failed.", - "close": "Close" -}; -var ja = { - "customer-fee-will-be-charged": "%{fee}\u306E\u624B\u6570\u6599\u304C\u8FFD\u52A0\u3055\u308C\u307E\u3059\u3002", - "dynamic-currency-notice": "\u652F\u6255\u3044\u306F%{currency}\u3067\u6C7A\u6E08\u3055\u308C\u307E\u3059: %{original} \u2192 %{converted}\u3002", - "dynamic-currency-notice-with-fee": "\u652F\u6255\u3044\u306F%{currency}\u3067\u6C7A\u6E08\u3055\u308C\u307E\u3059: %{original} \u2192 %{converted}\u3002(\u5408\u8A08%{total})", - "payment-method-unavailable": "\u3053\u306E\u652F\u6255\u3044\u65B9\u6CD5\u306F\u73FE\u5728\u3054\u5229\u7528\u3044\u305F\u3060\u3051\u307E\u305B\u3093\u3002", - "verification-failed": "\u8A8D\u8A3C\u306B\u5931\u6557\u3057\u307E\u3057\u305F\u3002", - "close": "\u9589\u3058\u308B" -}; - -// src/shared/message-broker.ts -var MessageBroker = class { - constructor(id) { - this._sendWindow = new Promise((resolve) => this._setSendWindow = resolve); - this._receiveWindow = new Promise((resolve) => this._setReceiveWindow = resolve); - this.messageHandler = (event) => { - if (this.origin !== "*" && event.origin !== this.origin) - return; - this.handleMessage(event); - }; - this.id = id ?? crypto.randomUUID(); - this.origin = "*"; - this.promises = /* @__PURE__ */ new Map(); - this.listeners = /* @__PURE__ */ new Map(); - } - setup(arg) { - if (this._setSendWindow) { - this._setSendWindow(arg.send); - this._setSendWindow = void 0; - } else { - this._sendWindow = Promise.resolve(arg.send); - } - if (this._setReceiveWindow) { - this._setReceiveWindow(arg.receive); - this._setReceiveWindow = void 0; - } else { - this._receiveWindow = Promise.resolve(arg.receive); - } - arg.receive.addEventListener("message", this.messageHandler); - } - send(message) { - const fullMessage = { - ...message, - brokerId: this.id, - id: crypto.randomUUID() - }; - let resolve = null; - const promise = new Promise((resolvePromise, _reject) => { - resolve = resolvePromise; - }); - if (!resolve) - throw new Error("Broker is busted"); - this.promises.set(fullMessage.id, { promise, resolve }); - return this._sendWindow.then((w) => w.postMessage(fullMessage, this.origin)).then(() => promise); - } - receive(type, listener) { - this.listeners.set(type, listener); - } - async handleMessage(event) { - const message = event.data; - if (message.brokerId !== this.id) - return; - if (message.type === "ack") { - const ack = message; - const promise = this.promises.get(ack.id); - if (!promise) - return; - promise.resolve(ack.response); - this.promises.delete(ack.id); - } else { - const listener = this.listeners.get(message.type); - const ack = { type: "ack", brokerId: this.id, id: message.id }; - if (listener) - ack.response = await listener(message) ?? void 0; - await this._sendWindow.then((w) => w.postMessage(ack, this.origin)); - } - } - destroy() { - return this._receiveWindow.then((w) => w.removeEventListener("message", this.messageHandler)); - } -}; - -// src/shared/komoju-api.ts -function komojuFetch(config, method, path, body) { - if (!config.komojuApi) - throw new Error("KOMOJU API URL is null"); - if (!config.publishableKey) - throw new Error("KOMOJU publishable-key not set"); - return fetch(`${config.komojuApi}${path}`, { - method, - headers: { - accept: "application/json", - "content-type": "application/json", - authorization: `Basic ${btoa(`${config.publishableKey}:`)}`, - "komoju-via": "fields" - }, - body: body ? JSON.stringify(body) : void 0 - }); -} - -// src/komoju-fields-element.ts -registerMessages(i18n_exports); -var KomojuFieldsElement = class extends HTMLElement { - constructor() { - super(); - this._submitting = false; - this.session = null; - this.broker = new MessageBroker(); - this.dialog = document.createElement("dialog"); - this.listenToMessagesFromIframe(this.broker); - this.dialog.style.width = "80%"; - this.dialog.style.height = "80%"; - this.dialog.style.padding = "0"; - } - static get observedAttributes() { - console.log("KomojuFieldsElement, observedAttributes"); - return [ - "komoju-api", - "session", - "session-id", - "publishable-key", - "payment-type", - "locale", - "theme", - "token", - "name" - ]; - } - get theme() { - return this.getAttribute("theme"); - } - set theme(value) { - this.setAttribute("theme", value ?? ""); - } - get komojuApi() { - return this.getAttribute("komoju-api") ?? "https://komoju.com"; - } - set komojuApi(value) { - this.setAttribute("komoju-api", value); - } - connectedCallback() { - const iframeParams = new URLSearchParams(); - iframeParams.append("broker", this.broker.id); - if (this.hasAttribute("komoju-api")) { - iframeParams.append("api", this.getAttribute("komoju-api")); - } - const iframe = document.createElement("iframe"); - iframe.setAttribute("sandbox", "allow-scripts allow-same-origin"); - iframe.setAttribute("allow", "payment *"); - iframe.title = "KOMOJU secure payment fields"; - iframe.src = `${env_default.CDN}/fields-iframe.html#${iframeParams.toString()}`; - iframe.style.border = "none"; - iframe.style.width = "100%"; - iframe.style.overflow = "hidden"; - iframe.height = "50"; - iframe.addEventListener("load", () => { - if (!iframe.contentWindow) - throw new Error("KOMOJU Fields: iframe had no contentWindow"); - this.broker.setup({ - send: iframe.contentWindow, - receive: window - }); - }); - this.replaceChildren(iframe, this.dialog); - let parent = this.parentElement; - while (parent && parent.tagName !== "FORM") { - parent = parent.parentElement; - } - if (!parent) - return; - const form = parent; - const target = form.parentElement; - if (!target) - return; - const handler = (event) => { - if (this._submitting) - return; - if (this.offsetParent === null) - return; - if (event.target !== form) - return; - event.preventDefault(); - event.stopImmediatePropagation(); - this.submit(event); - }; - target.addEventListener("submit", handler, true); - this.formSubmitHandler = { form, target, handler }; - } - disconnectedCallback() { - if (this.formSubmitHandler) { - this.formSubmitHandler.target.removeEventListener("submit", this.formSubmitHandler.handler, true); - this.formSubmitHandler = void 0; - } - this.broker.destroy(); - } - listenToMessagesFromIframe(broker) { - broker.receive("dispatch-event", (message) => { - const event = new CustomEvent(message.name, { - detail: message.detail, - bubbles: true, - composed: true, - cancelable: true - }); - if (message.name === "komoju-session-change") { - this.session = message.detail.session; - } - const result = { - type: "dispatch-result", - cancel: !this.dispatchEvent(event) - }; - return result; - }); - broker.receive("resize", (message) => { - const iframe = this.querySelector("iframe"); - iframe.height = message.height; - }); - broker.receive("dialog-start", async (message) => { - const result = { - type: "dialog-result", - result: await this.show3DSDialog(message.url) - }; - return result; - }); - } - async attributeChangedCallback(name, _oldValue, newValue) { - console.log("KomojuFieldsElement, oldValue?", name, _oldValue); - console.log("###"); - console.log("KomojuFieldsElement, attributeChangedCallback", name, newValue); - this.broker.send({ - type: "attr", - attr: name, - value: newValue - }); - } - async submit(event) { - if (this.token) - return JSON.parse(this.token); - const submitResult = await this.broker.send({ type: "submit" }); - if (submitResult?.type !== "submit-result") { - throw new Error(`Unexpected submit response from komoju-fields iframe ${JSON.stringify(submitResult)}`); - } - const result = submitResult; - if (result.errors) { - this.dispatchEvent(new CustomEvent("komoju-invalid", { - detail: { errors: result.errors }, - bubbles: true, - composed: true - })); - return; - } - if (result.pay) { - if (!result.pay.error) - await this.handlePayResult(result.pay); - return; - } - if (result.token && event && this.formSubmitHandler) { - const form = this.formSubmitHandler.form; - const inputName = this.getAttribute("name") ?? "komoju_token"; - let input = document.querySelector(`input[name="${inputName}"]`); - if (!input) { - input = document.createElement("input"); - input.type = "hidden"; - input.name = inputName; - form.append(input); - } - input.value = result.token.id; - this.submitParentForm(); - return; - } - if (result.token) { - this.token = JSON.stringify(result.token); - return result.token; - } - throw new Error("KOMOJU Fields bug: submit result was not handled"); - } - async handlePayResult(payResult) { - const session = this.session; - if (!session) - throw new Error("handlePayResult called without a session"); - const instructions = payResult.payment?.payment_details?.instructions_url; - if (instructions) { - const returnURL = new URL(session.return_url ?? session.session_url); - returnURL.searchParams.append("session_id", session.id); - this.showInstructionsDialog(instructions, returnURL.toString()); - } else if (payResult.redirect_url) { - window.location.href = payResult.redirect_url; - } else { - throw new Error(`payResult should have a redirect_url but doesnt ${JSON.stringify(payResult)}`); - } - } - async submitParentForm() { - if (!this.formSubmitHandler) - throw new Error("KOMOJU Fields: tried to submit nonexistent parent form"); - const form = this.formSubmitHandler.form; - try { - this._submitting = true; - const submitEvent = new Event("submit", { bubbles: true, cancelable: true }); - if (form.dispatchEvent(submitEvent)) { - form.submit(); - } else { - this.broker.send({ type: "end-fade" }); - } - } finally { - this._submitting = false; - } - } - showInstructionsDialog(url, finishURL) { - const dialog = this.dialog; - const iframe = createIframe(url); - iframe.style.height = "90%"; - const closeButton = document.createElement("a"); - const closeText = document.createElement("komoju-i18n"); - closeText.key = "close"; - closeButton.append(closeText); - closeButton.classList.add("komoju-fields-close-dialog"); - closeButton.href = finishURL; - closeButton.style.display = "block"; - closeButton.style.padding = "10px"; - dialog.replaceChildren( - closeButton, - iframe - ); - dialog.showModal(); - } - show3DSDialog(url) { - return new Promise((resolve, reject) => { - const dialog = this.dialog; - const origin = env_default["CDN"]; - const iframe = createIframe(url); - window.addEventListener("message", async (event) => { - if (event.origin !== origin) - return; - try { - if (!event.data?._komojuFields) - return; - const { secureTokenId } = event.data; - if (!secureTokenId) - throw new Error("No secureTokenId in message"); - const credentials = { - komojuApi: this.komojuApi, - publishableKey: this.getAttribute("publishable-key") ?? "" - }; - const secureTokenResponse = await komojuFetch(credentials, "GET", `/api/v1/secure_tokens/${secureTokenId}`); - if (secureTokenResponse.status >= 400) { - const error = await secureTokenResponse.json(); - resolve({ error }); - return; - } - const secureToken = await secureTokenResponse.json(); - dialog.close(); - resolve({ secureToken }); - } catch (e) { - reject(e); - } - }); - dialog.replaceChildren(iframe); - dialog.showModal(); - }); - } -}; -for (const attr of KomojuFieldsElement.observedAttributes) { - if (attr === "session" || attr === "theme" || attr === "komoju-api") - continue; - Object.defineProperty(KomojuFieldsElement.prototype, camelCase(attr), { - get() { - return this.getAttribute(attr); - }, - set(value) { - if (value === null) - this.removeAttribute(attr); - else - this.setAttribute(attr, value); - } - }); -} -function camelCase(str) { - return str.split("-").reduce((a, b) => a + b.charAt(0).toUpperCase() + b.slice(1)); -} -function createIframe(url) { - const iframe = document.createElement("iframe"); - iframe.setAttribute( - "sandbox", - "allow-scripts allow-forms allow-same-origin" - ); - iframe.src = url; - iframe.style.border = "none"; - iframe.style.width = "100%"; - iframe.style.height = "100%"; - return iframe; -} - -// src/picker.html -var picker_default = '\n\n
\n
\n\n\n'; - -// src/shared/radio-helpers.ts -function setupRadioParentCheckedClass(input, root) { - if (!input.parentElement) { - throw new Error("KOMOJU Fields bug: radio input has no parent"); - } - if (!input.parentElement.classList.contains("radio")) { - throw new Error("KOMOJU Fields bug: radio input parent has no .radio class"); - } - if (input.checked) { - input.parentElement.classList.add("checked"); - } - input.addEventListener("change", () => { - root.querySelectorAll(".radio.checked").forEach((el) => el.classList.remove("checked")); - input.parentElement.classList.add("checked"); - }); -} - -// src/generated/supported-payment-types.ts -var supported = /* @__PURE__ */ new Set(); -supported.add("bank_transfer"); -supported.add("credit_card"); -supported.add("konbini"); -supported.add("offsite"); -var supported_payment_types_default = supported; - -// src/shared/komoju-i18n-element.ts -var defaultLanguage = "en"; -function broadcastLocaleChange(root, locale) { - root.querySelectorAll("komoju-i18n").forEach((element) => { - const i18n = element; - i18n.render(locale); - }); -} -var KomojuI18nElement = class extends HTMLElement { - static get observedAttributes() { - return ["key"]; - } - get key() { - return this.getAttribute("key"); - } - set key(value) { - this.setAttribute("key", value ?? ""); - } - connectedCallback() { - this.render(); - } - attributeChangedCallback(name, _oldValue, _newValue) { - if (name === "key") - this.render(); - } - findLocale() { - let parent = this.parentElement; - while (parent && !parent.getAttribute("locale")) { - parent = parent.parentElement; - } - return parent?.getAttribute("locale") ?? defaultLanguage; - } - render(locale) { - if (!this.key) - return; - if (!locale) - locale = this.findLocale(); - if (!Object.keys(window.komojuTranslations).includes(locale)) - locale = defaultLanguage; - const lang = locale.substring(0, 2); - const message = window.komojuTranslations[lang][this.key]; - if (!message) { - console.error(`KOMOJU bug: missing translation for key: ${this.key}`); - return; - } - const matches = message.match(/%\{[\w-]+\}/g); - if (matches) { - let result = message; - matches.forEach((match) => { - const key = match.replace(/%{|}/g, ""); - const value = this.dataset[key]; - if (value) - result = result.replace(match, value); - }); - this.textContent = result; - return; - } - this.textContent = message; - } -}; - -// src/shared/themable.ts -var Themable = class extends HTMLElement { - get theme() { - return this.getAttribute("theme"); - } - set theme(value) { - this.setAttribute("theme", value ?? ""); - } - applyTheme() { - const root = this.shadowRoot ?? document; - if (this.theme === null) { - root.querySelectorAll("#theme,#inline-theme").forEach((el) => el.remove()); - } else if (this.theme.startsWith("http") || this.theme.startsWith("/") || this.theme.startsWith("data:")) { - this.applyExternalTheme(root, this.theme); - } else { - this.applyInlineTheme(root, this.theme); - } - } - applyInlineTheme(root, theme) { - root.querySelectorAll("#theme,#inline-theme").forEach((el) => el.remove()); - const style = document.createElement("style"); - style.id = "inline-theme"; - style.textContent = theme; - this.appendStyleTag(style); - } - applyExternalTheme(root, theme) { - root.querySelectorAll("#inline-theme").forEach((el) => el.remove()); - let link = root.querySelector("#theme"); - if (link) { - if (link.href !== this.theme) - link.href = theme; - } else { - link = document.createElement("link"); - link.id = "theme"; - link.rel = "stylesheet"; - link.href = theme; - this.appendStyleTag(link); - } - } - appendStyleTag(style) { - if (this.shadowRoot) { - this.shadowRoot.append(style); - } else { - document.head.append(style); - } - } -}; - -// src/komoju-picker-element.ts -var KomojuPickerElement = class extends Themable { - constructor() { - super(); - this.sessionChangedHandler = null; - const root = this.attachShadow({ mode: "open" }); - root.innerHTML = picker_default; - const link = document.createElement("link"); - link.rel = "stylesheet"; - link.href = `https://multipay.komoju.com/static/shared.css`; - root.append(link); - } - static get observedAttributes() { - return ["locale", "theme"]; - } - get fields() { - return this.getAttribute("fields"); - } - set fields(value) { - this.setAttribute("fields", value ?? ""); - } - get locale() { - return this.getAttribute("locale"); - } - set locale(value) { - this.setAttribute("locale", value ?? ""); - } - async connectedCallback() { - const fields = this.komojuFieldsElement(); - let handler = { - element: fields, - handler: (_evt) => { - this.render(fields); - } - }; - await this.setupPaymentTypesI18n(); - this.render(fields); - fields.addEventListener("komoju-session-change", handler.handler); - this.sessionChangedHandler = handler; - } - disconnectedCallback() { - if (this.sessionChangedHandler) { - this.sessionChangedHandler.element.removeEventListener( - "komoju-session-change", - this.sessionChangedHandler.handler - ); - } - } - async attributeChangedCallback(name, oldValue, newValue) { - if (!this.shadowRoot) - return; - if (name === "locale" && newValue && oldValue !== newValue) { - broadcastLocaleChange(this.shadowRoot, newValue); - this.updatePickerLocale(newValue); - } else if (name === "theme") { - this.applyTheme(); - } - } - komojuFieldsElement() { - if (this.fields) { - return document.querySelector(`#${this.fields}`); - } else { - return document.querySelector("komoju-fields"); - } - } - render(fields) { - if (!fields.session) - return; - if (!this.shadowRoot) - return; - const picker = this.shadowRoot.getElementById("picker"); - const template = this.shadowRoot.getElementById("radio-template"); - if (!picker) - throw new Error("KOMOJU Fields bug: wrong shadow DOM (no picker)"); - if (!template) - throw new Error("KOMOJU Fields bug: wrong shadow DOM (no template)"); - if (!this.locale) { - this.locale = fields.session.default_locale.substring(0, 2); - } - ; - this.updatePickerLocale(this.locale); - picker.replaceChildren(); - let i = 0; - for (const paymentMethod of fields.session.payment_methods) { - const moduleName = paymentMethod.offsite ? "offsite" : paymentMethod.type; - if (fields.hasAttribute("token") && !supported_payment_types_default.has(moduleName)) { - continue; - } - const radio = template.content.cloneNode(true); - const input = radio.querySelector("input"); - const icon = radio.querySelector("img"); - const text = radio.querySelector("komoju-i18n"); - if (i === 0 || fields.paymentType === paymentMethod.type) { - input.checked = true; - } - input.addEventListener("change", () => { - fields.paymentType = paymentMethod.type; - }); - setupRadioParentCheckedClass(input, this.shadowRoot); - icon.src = `${fields.komojuApi}/payment_methods/${paymentMethod.type}.svg`; - text.key = paymentMethod.type; - picker.append(radio); - i += 1; - } - if (!this.theme && fields.theme) { - this.theme = fields.theme; - this.applyTheme(); - } - } - async setupPaymentTypesI18n() { - const fields = this.komojuFieldsElement(); - const response = await komojuFetch(fields, "GET", "/api/v1/payment_methods"); - this.komojuPaymentMethods = await response.json(); - for (const method of this.komojuPaymentMethods) { - const i18n = { - en: { [method.type_slug]: method.name_en }, - ja: { [method.type_slug]: method.name_ja }, - ko: { [method.type_slug]: method.name_ko } - }; - registerMessages(i18n); - } - } - updatePickerLocale(locale) { - if (!this.shadowRoot) - return; - const picker = this.shadowRoot.getElementById("picker"); - if (picker) { - picker.setAttribute("locale", locale); - } - ; - } -}; - -// src/index.ts -window.customElements.define("komoju-fields", KomojuFieldsElement); -window.customElements.define("komoju-picker", KomojuPickerElement); -window.customElements.define("komoju-i18n", KomojuI18nElement); -window.komojuReportError = (error, context) => { - console.error(error, context); -}; -if (window.komojuErrorReporting !== false) { - (async () => { - const moduleName = "error-reporting"; - const module = await import(`https://multipay.komoju.com/extras/${moduleName}/module.js`); - window.komojuReportError = module.reportError; - })(); - const onerror = (event) => { - const komojuFieldsFiles = [ - /\/fields\.js:\d+:\d+\n/, - /\/fields\/[\w-]+\/module\.js\n:\d+:\d+/, - /\/extras\/[\w-]+\/module\.js\n:\d+:\d+/ - ]; - const error = event instanceof ErrorEvent ? event.error : event.reason; - if (!(error instanceof Error)) - return; - if (!error.stack) - return; - if (!komojuFieldsFiles.find((regex) => regex.test(error.stack))) - return; - window.komojuReportError(error); - }; - window.addEventListener("error", onerror); - window.addEventListener("unhandledrejection", onerror); -} -//# sourceMappingURL=fields.js.map diff --git a/src/app/code/Komoju/Payments/view/frontend/web/js/fields.js.map b/src/app/code/Komoju/Payments/view/frontend/web/js/fields.js.map deleted file mode 100644 index 959240674..000000000 --- a/src/app/code/Komoju/Payments/view/frontend/web/js/fields.js.map +++ /dev/null @@ -1,7 +0,0 @@ -{ - "version": 3, - "sources": ["../src/generated/env.ts", "../src/shared/translations.ts", "../src/i18n.ts", "../src/shared/message-broker.ts", "../src/shared/komoju-api.ts", "../src/komoju-fields-element.ts", "../src/shared/radio-helpers.ts", "../src/generated/supported-payment-types.ts", "../src/shared/komoju-i18n-element.ts", "../src/shared/themable.ts", "../src/komoju-picker-element.ts", "../src/index.ts"], - "sourcesContent": ["// Generated by bin/generate.sh\n//\n// This file pulls from environment variables (and git).\n\nexport default {\n \"CDN\": \"https://multipay.komoju.com\",\n \"ENV\": \"development\",\n \"HONEYBADGER_API_KEY\": \"\",\n \"GIT_REV\": \"99ad2eb29ce6530dedfe3a0ec34aea970dbaa78a\",\n};\n", "declare let window: WindowWithKomojuGlobals;\n\n// Call this to add messages to the registry.\n// Individual payment method modules can do this to add their own messages.\n// That way, we avoid needing to load all messages for every payment method upfront.\nexport function registerMessages(messages: I18n) {\n if (!window.komojuTranslations) {\n window.komojuTranslations = { 'en': {}, 'ja': {} };\n }\n\n for (const lang of Object.keys(window.komojuTranslations)) {\n window.komojuTranslations[lang] = {\n ...window.komojuTranslations[lang],\n ...messages[lang],\n };\n }\n}\n", "export const en = {\n 'customer-fee-will-be-charged': 'A fee of %{fee} will be included.',\n 'dynamic-currency-notice': 'Payment will be made in %{currency}: %{original} \u2192 %{converted}.',\n 'dynamic-currency-notice-with-fee': 'Payment will be made in %{currency}: %{original} \u2192 %{converted}. (total: %{total})',\n 'payment-method-unavailable': 'This payment method is currently unavailable.',\n 'verification-failed': 'Verification failed.',\n 'close': 'Close',\n};\n\nexport const ja: typeof en = {\n 'customer-fee-will-be-charged': '%{fee}\u306E\u624B\u6570\u6599\u304C\u8FFD\u52A0\u3055\u308C\u307E\u3059\u3002',\n 'dynamic-currency-notice': '\u652F\u6255\u3044\u306F%{currency}\u3067\u6C7A\u6E08\u3055\u308C\u307E\u3059: %{original} \u2192 %{converted}\u3002',\n 'dynamic-currency-notice-with-fee': '\u652F\u6255\u3044\u306F%{currency}\u3067\u6C7A\u6E08\u3055\u308C\u307E\u3059: %{original} \u2192 %{converted}\u3002(\u5408\u8A08%{total})',\n 'payment-method-unavailable': '\u3053\u306E\u652F\u6255\u3044\u65B9\u6CD5\u306F\u73FE\u5728\u3054\u5229\u7528\u3044\u305F\u3060\u3051\u307E\u305B\u3093\u3002',\n 'verification-failed': '\u8A8D\u8A3C\u306B\u5931\u6557\u3057\u307E\u3057\u305F\u3002',\n 'close': '\u9589\u3058\u308B',\n};\n", "export interface Message {\n type: string,\n}\nexport interface FullMessage extends Message {\n brokerId: string,\n id: string,\n}\n\ninterface MessageAck extends FullMessage {\n type: 'ack',\n response?: Message,\n}\n\ntype MessageBrokerArgs = { send: Window, receive: Window };\n\ntype TypedMessageListener = (arg: T) => Promise | Message | undefined | void;\ntype MessageListener = TypedMessageListener;\n\n// Wrapper around postMessage events that lets us use promises instead of\n// disjoint \"send\" and \"receive\" flows.\nexport class MessageBroker {\n // Keep track of which window to send to and which to receive on.\n // These are promises so that we can effectively buffer messages until the window is ready.\n _sendWindow: Promise;\n _receiveWindow: Promise;\n _setSendWindow?: (value: Window) => void;\n _setReceiveWindow?: (value: Window) => void;\n\n // Raw \"message\" event listener. We need to keep track of this so we can remove it later.\n messageHandler: (event: MessageEvent) => void;\n\n // Map of in-progress promises. When we receive an ack message with a matching id, we resolve the promise.\n promises: Map,\n resolve: (value?: Message) => void,\n }>;\n\n // Map of listeners. When we receive a message with a matching type, we call the listener.\n listeners: Map;\n\n // Unique id for this broker. Used to distinguish messages from other brokers.\n id: string;\n\n origin: string;\n\n constructor(id?: string) {\n this._sendWindow = new Promise(resolve => this._setSendWindow = resolve);\n this._receiveWindow = new Promise(resolve => this._setReceiveWindow = resolve);\n\n this.messageHandler = event => {\n if (this.origin !== '*' && event.origin !== this.origin) return;\n this.handleMessage(event);\n };\n\n this.id = id ?? crypto.randomUUID();\n this.origin = '*';\n this.promises = new Map();\n this.listeners = new Map();\n }\n\n // Call this to set up the broker\n setup(arg: MessageBrokerArgs) {\n if (this._setSendWindow) {\n this._setSendWindow(arg.send);\n this._setSendWindow = undefined;\n } else {\n this._sendWindow = Promise.resolve(arg.send);\n }\n\n if (this._setReceiveWindow) {\n this._setReceiveWindow(arg.receive);\n this._setReceiveWindow = undefined;\n } else {\n this._receiveWindow = Promise.resolve(arg.receive);\n }\n\n arg.receive.addEventListener('message', this.messageHandler);\n }\n\n // Call this to send a message. Promise will resolve when the associated ack message\n // comes back.\n send(message: MessageType): Promise {\n const fullMessage: FullMessage = {\n ...message,\n brokerId: this.id,\n id: crypto.randomUUID(),\n };\n\n let resolve: ((value?: Message) => void) | null = null;\n const promise = new Promise((resolvePromise, _reject) => {\n resolve = resolvePromise;\n });\n if (!resolve) throw new Error('Broker is busted');\n\n this.promises.set(fullMessage.id, { promise, resolve });\n return this._sendWindow.then(w => w.postMessage(fullMessage, this.origin)).then(() => promise);\n }\n\n // Call this to set the listener for a certain event. Kind of like the built-in\n // addEventListener, but can only add one per event type.\n receive(type: MessageType['type'], listener: TypedMessageListener) {\n this.listeners.set(type, listener as MessageListener);\n }\n\n // Internal message handler\n async handleMessage(event: MessageEvent) {\n const message = event.data;\n\n // Ignore messages from other brokers\n if (message.brokerId !== this.id) return;\n\n // 'ack' messages resolve an in-progress promise\n if (message.type === 'ack') {\n const ack = message as MessageAck;\n const promise = this.promises.get(ack.id);\n\n // Acks with a wrong ID typically come from another tag\n // in the same window.\n if (!promise) return;\n\n promise.resolve(ack.response);\n this.promises.delete(ack.id);\n }\n // all other messages trigger a local listener if present\n else {\n const listener = this.listeners.get(message.type);\n const ack: MessageAck = { type: 'ack', brokerId: this.id, id: message.id };\n if (listener) ack.response = (await listener(message)) ?? undefined;\n await this._sendWindow.then(w => w.postMessage(ack, this.origin));\n }\n }\n\n // Call this to clean up the window event listener\n destroy() {\n return this._receiveWindow.then(w => w.removeEventListener('message', this.messageHandler));\n }\n}\n", "// fetch wrapper with KOMOJU authentication already handled.\nexport function komojuFetch(\n config: {\n komojuApi: string,\n publishableKey: string | null,\n },\n method: 'GET' | 'POST',\n path: string,\n body?: object\n): Promise {\n if (!config.komojuApi) throw new Error('KOMOJU API URL is null');\n if (!config.publishableKey) throw new Error('KOMOJU publishable-key not set');\n\n return fetch(`${config.komojuApi}${path}`, {\n method,\n headers: {\n accept: 'application/json',\n 'content-type': 'application/json',\n authorization: `Basic ${btoa(`${config.publishableKey}:`)}`,\n 'komoju-via': 'fields',\n },\n body: body ? JSON.stringify(body) : undefined\n });\n}\n", "import ENV from './generated/env';\n\nimport { registerMessages } from './shared/translations';\nimport * as i18n from './i18n';\nimport { MessageBroker } from './shared/message-broker';\nimport { komojuFetch } from './shared/komoju-api';\nregisterMessages(i18n);\n\n// Language gets stored in here, mostly controlled by .\ndeclare let window: WindowWithKomojuGlobals;\n\n// This is the main entrypoint for implementers.\n// The element manages an iframe that securely hosts the KOMOJU fields UI.\n// All attributes are sent into the iframe and synced with the element.\nexport default class KomojuFieldsElement extends HTMLElement {\n static get observedAttributes() {\n console.log('KomojuFieldsElement, observedAttributes');\n\n return [\n 'komoju-api',\n 'session',\n 'session-id',\n 'publishable-key',\n 'payment-type',\n 'locale',\n 'theme',\n 'token',\n 'name',\n ];\n }\n\n // This message broker lets us communicate with the iframe using promises instead of\n // raw postMessage and addEventListener.\n broker: MessageBroker;\n\n // When a element appears inside of a tag, we attach a submit handler to it\n // so we can seamlessly behave like an tag.\n // This formSubmitHandler lets us clean up the event listener when disconnected.\n formSubmitHandler?: {\n form: HTMLFormElement,\n target: HTMLElement, // target is different from form so we can ensure our event gets called first\n handler: (event: Event) => void\n };\n _submitting: boolean = false;\n\n session: KomojuSession | null = null;\n\n dialog: HTMLDialogElement;\n\n get theme() {\n return this.getAttribute('theme');\n }\n set theme(value) {\n this.setAttribute('theme', value ?? '');\n }\n\n get komojuApi() {\n return this.getAttribute('komoju-api') ?? 'https://komoju.com';\n }\n set komojuApi(value) {\n this.setAttribute('komoju-api', value);\n }\n\n // To keep manual submit() calls idempotent, we hold onto the token from our last\n // (and presumably only) successful submit.\n token?: string;\n\n constructor() {\n super();\n this.broker = new MessageBroker();\n this.dialog = document.createElement('dialog');\n this.listenToMessagesFromIframe(this.broker);\n\n this.dialog.style.width = '80%';\n this.dialog.style.height = '80%';\n this.dialog.style.padding = '0';\n }\n\n // When connected, we want to find the form that this element is in and attach a submit handler to it.\n connectedCallback() {\n const iframeParams = new URLSearchParams();\n iframeParams.append('broker', this.broker.id);\n if (this.hasAttribute('komoju-api')) {\n iframeParams.append('api', this.getAttribute('komoju-api')!);\n }\n\n // Set up our fields host iframe.\n const iframe = document.createElement('iframe') as HTMLIFrameElement;\n iframe.setAttribute('sandbox', 'allow-scripts allow-same-origin');\n iframe.setAttribute('allow', 'payment *');\n iframe.title = 'KOMOJU secure payment fields';\n iframe.src = `${ENV.CDN}/fields-iframe.html#${iframeParams.toString()}`;\n iframe.style.border = 'none';\n iframe.style.width = '100%';\n iframe.style.overflow = 'hidden';\n iframe.height = '50';\n iframe.addEventListener('load', () => {\n if (!iframe.contentWindow) throw new Error('KOMOJU Fields: iframe had no contentWindow');\n // Set up our message broker now that the iframe is loaded.\n this.broker.setup({\n send: iframe.contentWindow,\n receive: window,\n });\n });\n this.replaceChildren(iframe, this.dialog);\n\n // Crudely search for parent element until it is a form tag.\n let parent = this.parentElement;\n while (parent && parent.tagName !== 'FORM') {\n parent = parent.parentElement;\n }\n // It's OK if we can't find a parent form tag.\n // Implementers can call submit() manually on this element.\n if (!parent) return;\n const form = parent as HTMLFormElement;\n\n // We set the event target to the form's parent to ensure that our handler is called first.\n // This works because of capturing. Capturing events are called on parents *before* target.\n const target = form.parentElement;\n if (!target) return;\n\n const handler = (event: Event) => {\n if (this._submitting) return;\n // Make sure this komoju-fields element is visible.\n if (this.offsetParent === null) return;\n // Make sure this event is for the right form element.\n if (event.target !== form) return;\n\n event.preventDefault();\n event.stopImmediatePropagation();\n\n this.submit(event);\n };\n target.addEventListener('submit', handler, true);\n this.formSubmitHandler = { form, target, handler };\n }\n\n // When disconnected, we want to remove the submit handler from the form (if added).\n disconnectedCallback() {\n if (this.formSubmitHandler) {\n this.formSubmitHandler.target.removeEventListener('submit', this.formSubmitHandler.handler, true);\n this.formSubmitHandler = undefined;\n }\n\n this.broker.destroy();\n }\n\n // Receive messages from the iframe.\n listenToMessagesFromIframe(broker: MessageBroker) {\n // The iframe will sometimes ask us to dispatch an event.\n broker.receive('dispatch-event', (message) => {\n const event = new CustomEvent(message.name, {\n detail: message.detail,\n bubbles: true,\n composed: true,\n cancelable: true,\n });\n\n // Sync own session with iframe session.\n // This way implementers can always access the latest session from the komoju-fields element\n // in case they want to know what payment methods are supported, etc.\n if (message.name === 'komoju-session-change') {\n this.session = message.detail.session as KomojuSession;\n }\n\n const result: KomojuDispatchResult = {\n type: 'dispatch-result',\n cancel: !this.dispatchEvent(event)\n }\n\n return result;\n });\n\n // The iframe tells us how much height its content has so that we can resize it seamlessly.\n broker.receive('resize', (message) => {\n const iframe = this.querySelector('iframe') as HTMLIFrameElement;\n iframe.height = message.height;\n });\n\n broker.receive('dialog-start', async (message) => {\n const result: KomojuDialogResult = {\n type: 'dialog-result',\n result: await this.show3DSDialog(message.url),\n };\n return result;\n });\n }\n\n // Reactive attribute handling. Send all attrs to the iframe so that they are synced with the komoju-host element.\n async attributeChangedCallback(name: string, _oldValue: string | null, newValue: string | null) {\n console.log('KomojuFieldsElement, oldValue?', name, _oldValue);\n console.log('###')\n console.log('KomojuFieldsElement, attributeChangedCallback', name, newValue);\n\n this.broker.send({\n type: 'attr',\n attr: name,\n value: newValue,\n });\n }\n\n // Consumers may call this to submit the form.\n // If the 'token' attribute is set, this will return the token response from KOMOJU.\n async submit(event?: Event): Promise {\n if (this.token) return JSON.parse(this.token);\n\n // Ask the iframe to submit.\n const submitResult = await this.broker.send({ type: 'submit' });\n if (submitResult?.type !== 'submit-result') {\n throw new Error(`Unexpected submit response from komoju-fields iframe ${JSON.stringify(submitResult)}`);\n }\n const result = submitResult as KomojuSubmitResult;\n\n // On error, emit a komoju-invalid event in case consumers want to handle it.\n if (result.errors) {\n this.dispatchEvent(new CustomEvent('komoju-invalid', {\n detail: { errors: result.errors }, bubbles: true, composed: true,\n }));\n return;\n }\n\n // On payment success, redirect.\n if (result.pay) {\n if (!result.pay.error) await this.handlePayResult(result.pay);\n return;\n }\n\n // If this is part of a form submit, we want to add the token to the form and resubmit.\n if (result.token && event && this.formSubmitHandler) {\n const form = this.formSubmitHandler.form;\n\n // Now we add an input to the form with the token and submit it.\n const inputName = this.getAttribute('name') ?? 'komoju_token';\n let input = document.querySelector(`input[name=\"${inputName}\"]`) as HTMLInputElement | null;\n if (!input) {\n input = document.createElement('input');\n input.type = 'hidden';\n input.name = inputName;\n form.append(input);\n }\n input.value = result.token.id;\n\n // Re-submit the form without our submit event getting in the way.\n this.submitParentForm();\n return;\n }\n\n // Token submission.\n if (result.token) {\n this.token = JSON.stringify(result.token);\n return result.token;\n }\n\n throw new Error(\"KOMOJU Fields bug: submit result was not handled\");\n }\n\n // After submit in a standard integration, we will usually just redirect.\n // But there's a special case where we show instructions, e.g. for konbini and bank transfer.\n async handlePayResult(payResult: KomojuPayResult) {\n const session = this.session;\n if (!session) throw new Error(\"handlePayResult called without a session\");\n\n const instructions = payResult.payment?.payment_details?.instructions_url;\n\n if (instructions) {\n const returnURL = new URL(session.return_url ?? session.session_url);\n returnURL.searchParams.append('session_id', session.id);\n this.showInstructionsDialog(instructions, returnURL.toString());\n } else if (payResult.redirect_url) {\n window.location.href = payResult.redirect_url;\n } else {\n throw new Error(`payResult should have a redirect_url but doesnt ${JSON.stringify(payResult)}`);\n }\n }\n\n // Removes our form submit override and submits the parent form directly.\n async submitParentForm() {\n if (!this.formSubmitHandler) throw new Error('KOMOJU Fields: tried to submit nonexistent parent form');\n const form = this.formSubmitHandler.form;\n\n // Re-submit the form without our submit event getting in the way.\n try {\n // This _submitting flag should prevent infinite recursion.\n this._submitting = true;\n const submitEvent = new Event('submit', { bubbles: true, cancelable: true });\n if (form.dispatchEvent(submitEvent)) {\n form.submit();\n } else {\n this.broker.send({ type: 'end-fade' });\n }\n } finally {\n this._submitting = false;\n }\n }\n\n showInstructionsDialog(url: string, finishURL: string) {\n const dialog = this.dialog;\n\n const iframe = createIframe(url);\n iframe.style.height = '90%';\n\n const closeButton = document.createElement('a');\n const closeText = document.createElement('komoju-i18n') as KomojuI18nElement;\n closeText.key = 'close';\n closeButton.append(closeText);\n closeButton.classList.add('komoju-fields-close-dialog');\n closeButton.href = finishURL;\n closeButton.style.display = 'block';\n closeButton.style.padding = '10px';\n\n dialog.replaceChildren(\n closeButton,\n iframe,\n );\n dialog.showModal();\n }\n\n show3DSDialog(url: string): Promise {\n return new Promise((resolve, reject) => {\n const dialog = this.dialog;\n const origin = ENV['CDN'];\n\n const iframe = createIframe(url);\n\n window.addEventListener('message', async (event) => {\n if (event.origin !== origin) return;\n\n try {\n if (!event.data?._komojuFields) return;\n\n const { secureTokenId } = event.data;\n if (!secureTokenId) throw new Error('No secureTokenId in message');\n\n const credentials = {\n komojuApi: this.komojuApi,\n publishableKey: this.getAttribute('publishable-key') ?? '',\n };\n const secureTokenResponse = await komojuFetch(credentials, 'GET', `/api/v1/secure_tokens/${secureTokenId}`);\n if (secureTokenResponse.status >= 400) {\n const error = await secureTokenResponse.json() as KomojuApiError;\n resolve({ error });\n return;\n }\n const secureToken = await secureTokenResponse.json() as KomojuSecureToken;\n\n dialog.close();\n resolve({ secureToken });\n } catch (e) {\n reject(e);\n }\n });\n\n dialog.replaceChildren(iframe);\n dialog.showModal();\n });\n }\n}\n\n// Set up dynamic properties for each observed attribute, to support e.g.\n// const fields = document.querySelector('komoju-fields');\n// fields.sessionId = 'abc123';\nfor (const attr of KomojuFieldsElement.observedAttributes) {\n // A few special cases here.\n if (attr === 'session' || attr === 'theme' || attr === 'komoju-api') continue;\n\n Object.defineProperty(KomojuFieldsElement.prototype, camelCase(attr), {\n get() {\n return this.getAttribute(attr);\n },\n set(value) {\n if (value === null) this.removeAttribute(attr);\n else this.setAttribute(attr, value);\n },\n });\n}\n\nfunction camelCase(str: string) {\n return str\n .split('-')\n .reduce((a, b) => a + b.charAt(0).toUpperCase() + b.slice(1));\n}\n\nfunction createIframe(url: string): HTMLIFrameElement {\n const iframe = document.createElement('iframe');\n iframe.setAttribute(\n 'sandbox',\n 'allow-scripts allow-forms allow-same-origin'\n );\n iframe.src = url;\n iframe.style.border = 'none';\n iframe.style.width = '100%';\n iframe.style.height = '100%';\n return iframe;\n}", "interface QuerySelectorAll {\n querySelectorAll: HTMLElement['querySelectorAll']\n}\n\n// Add .checked to the parent .radio element when the input is checked.\n// This is just to make the CSS a little easier, since we're putting the\n// input inside of the label.\nexport function setupRadioParentCheckedClass(input: HTMLInputElement, root: QuerySelectorAll) {\n // Some sanity checks\n if (!input.parentElement) {\n throw new Error('KOMOJU Fields bug: radio input has no parent');\n }\n if (!input.parentElement.classList.contains('radio')) {\n throw new Error('KOMOJU Fields bug: radio input parent has no .radio class');\n }\n\n // Initialize the checked class\n if (input.checked) {\n input.parentElement.classList.add('checked');\n }\n\n // Set checked class then checked\n input.addEventListener('change', () => {\n root.querySelectorAll('.radio.checked').forEach((el) => el.classList.remove('checked'));\n input.parentElement!.classList.add('checked');\n });\n}\n", "// Generated by bin/generate.sh\n//\n// List of supported payment types comes from the folders in src/fields/*.\n// To add a new one, simply add a new folder.\n\nconst supported: Set = new Set();\nsupported.add('bank_transfer');\nsupported.add('credit_card');\nsupported.add('konbini');\nsupported.add('offsite');\nexport default supported;\n", "// Language gets stored in here, mostly controlled by .\ndeclare let window: WindowWithKomojuGlobals;\n\nconst defaultLanguage = 'en';\n\ntype Queryable = {\n querySelectorAll: Document['querySelectorAll'];\n};\n\nexport function broadcastLocaleChange(root: Queryable, locale: string) {\n root.querySelectorAll('komoju-i18n').forEach((element) => {\n const i18n = element as KomojuI18nElement;\n i18n.render(locale);\n });\n}\n\n// This is a element that we use internally for displaying translated text\nexport default class KomojuI18nElement extends HTMLElement {\n static get observedAttributes() {\n return ['key'];\n }\n\n // Attribute: key\n // The key of the translation to display.\n get key() {\n return this.getAttribute('key');\n }\n set key(value) {\n this.setAttribute('key', value ?? '');\n }\n\n connectedCallback() {\n this.render();\n }\n\n attributeChangedCallback(name: string, _oldValue: string, _newValue: string) {\n if (name === 'key') this.render();\n }\n\n // Search up the DOM until we find a parent element with a locale attribute.\n findLocale() {\n let parent = this.parentElement;\n while (parent && !parent.getAttribute('locale')) {\n parent = parent.parentElement;\n }\n return parent?.getAttribute('locale') ?? defaultLanguage;\n }\n\n render(locale?: string) {\n if (!this.key) return;\n\n if (!locale) locale = this.findLocale();\n if (!Object.keys(window.komojuTranslations).includes(locale)) locale = defaultLanguage;\n\n const lang = locale.substring(0, 2);\n\n const message = window.komojuTranslations[lang][this.key];\n if (!message) {\n console.error(`KOMOJU bug: missing translation for key: ${this.key}`);\n return;\n }\n\n // Perform interpolation\n const matches = message.match(/%\\{[\\w-]+\\}/g);\n if (matches) {\n let result = message;\n matches.forEach((match) => {\n const key = match.replace(/%{|}/g, '');\n const value = this.dataset[key];\n if (value) result = result.replace(match, value);\n });\n this.textContent = result;\n return;\n }\n\n this.textContent = message;\n }\n}\n", "export default class Themable extends HTMLElement {\n // Attribute: theme\n // CSS file to use as a theme.\n get theme() {\n return this.getAttribute('theme');\n }\n set theme(value) {\n this.setAttribute('theme', value ?? '');\n }\n\n applyTheme() {\n const root = this.shadowRoot ?? document;\n\n if (this.theme === null) {\n root.querySelectorAll('#theme,#inline-theme').forEach(el => el.remove());\n } else if (this.theme.startsWith('http') || this.theme.startsWith('/') || this.theme.startsWith('data:')) {\n this.applyExternalTheme(root, this.theme);\n } else {\n this.applyInlineTheme(root, this.theme);\n }\n }\n\n applyInlineTheme(root: ParentNode, theme: string) {\n root.querySelectorAll('#theme,#inline-theme').forEach(el => el.remove());\n\n const style = document.createElement('style');\n style.id = 'inline-theme';\n style.textContent = theme;\n this.appendStyleTag(style);\n }\n\n applyExternalTheme(root: ParentNode, theme: string) {\n root.querySelectorAll('#inline-theme').forEach(el => el.remove());\n let link = root.querySelector('#theme') as HTMLLinkElement | null;\n if (link) {\n if (link.href !== this.theme) link.href = theme;\n } else {\n link = document.createElement('link');\n link.id = 'theme';\n link.rel = 'stylesheet';\n link.href = theme;\n this.appendStyleTag(link);\n }\n }\n\n appendStyleTag(style: HTMLLinkElement | HTMLStyleElement) {\n if (this.shadowRoot) {\n this.shadowRoot.append(style);\n }\n else {\n document.head.append(style);\n }\n }\n}\n", "import ENV from './generated/env';\n\nimport template from './picker.html';\nimport { setupRadioParentCheckedClass } from './shared/radio-helpers';\nimport { registerMessages } from './shared/translations';\nimport { komojuFetch } from './shared/komoju-api';\nimport supportedPaymentTypes from './generated/supported-payment-types';\nimport { broadcastLocaleChange } from './shared/komoju-i18n-element';\nimport Themable from './shared/themable';\n\ntype ChangedHandler = {\n element: KomojuFieldsConfig,\n handler: (event: Event) => void,\n};\n\nexport default class KomojuPickerElement extends Themable {\n static get observedAttributes() {\n return [ 'locale', 'theme' ];\n }\n\n // Attribute: fields\n // DOM ID of element that this picker is associated with.\n // When blank, will just update all elements.\n get fields() {\n return this.getAttribute('fields');\n }\n set fields(value) {\n this.setAttribute('fields', value ?? '');\n }\n\n // Attribute: locale\n // Locale to use for payment method names.\n get locale() {\n return this.getAttribute('locale');\n }\n set locale(value) {\n this.setAttribute('locale', value ?? '');\n }\n\n komojuPaymentMethods?: Array\n\n // This picker element piggy-backs on the element's session and locale.\n sessionChangedHandler: ChangedHandler | null = null\n\n constructor() {\n super();\n const root = this.attachShadow({ mode: 'open' });\n root.innerHTML = template;\n\n // Set base CSS\n const link = document.createElement('link');\n link.rel = 'stylesheet';\n link.href = `https://multipay.komoju.com/static/shared.css`;\n root.append(link);\n }\n\n async connectedCallback() {\n const fields = this.komojuFieldsElement();\n let handler = {\n element: fields,\n handler: (_evt: Event) => { this.render(fields); },\n };\n\n await this.setupPaymentTypesI18n();\n this.render(fields);\n fields.addEventListener('komoju-session-change', handler.handler);\n this.sessionChangedHandler = handler;\n }\n\n disconnectedCallback() {\n if (this.sessionChangedHandler) {\n this.sessionChangedHandler.element.removeEventListener(\n 'komoju-session-change',\n this.sessionChangedHandler.handler\n );\n }\n }\n\n async attributeChangedCallback(name: string, oldValue: string | null, newValue: string | null) {\n if (!this.shadowRoot) return;\n\n if (name === 'locale' && newValue && oldValue !== newValue) {\n broadcastLocaleChange(this.shadowRoot, newValue);\n this.updatePickerLocale(newValue);\n }\n else if (name === 'theme') {\n this.applyTheme();\n }\n }\n\n komojuFieldsElement() {\n if (this.fields) {\n return document.querySelector(`#${this.fields}`) as KomojuFieldsConfig;\n }\n else {\n return document.querySelector('komoju-fields') as KomojuFieldsConfig;\n }\n }\n\n render(fields: KomojuFieldsConfig) {\n if (!fields.session) return;\n if (!this.shadowRoot) return;\n\n const picker = this.shadowRoot.getElementById('picker');\n const template = this.shadowRoot.getElementById('radio-template') as HTMLTemplateElement;\n if (!picker) throw new Error('KOMOJU Fields bug: wrong shadow DOM (no picker)');\n if (!template) throw new Error('KOMOJU Fields bug: wrong shadow DOM (no template)');\n\n // If locale hasn't been set on directly, use session default_locale.\n if (!this.locale) {\n this.locale = fields.session.default_locale.substring(0, 2);\n };\n\n this.updatePickerLocale(this.locale)\n\n // Clear the picker.\n picker.replaceChildren();\n\n let i = 0;\n for (const paymentMethod of fields.session.payment_methods) {\n const moduleName = paymentMethod.offsite ? 'offsite' : paymentMethod.type;\n\n // Token mode cannot handle payment methods that aren't explicitly supported, so we won't\n // show them on the picker.\n if (fields.hasAttribute('token') && !supportedPaymentTypes.has(moduleName)) {\n continue;\n }\n\n const radio = template.content.cloneNode(true) as HTMLElement;\n const input = radio.querySelector('input') as HTMLInputElement;\n const icon = radio.querySelector('img') as HTMLImageElement;\n const text = radio.querySelector('komoju-i18n') as KomojuI18nElement;\n\n if (i === 0 || fields.paymentType === paymentMethod.type) {\n input.checked = true;\n }\n input.addEventListener('change', () => {\n fields.paymentType = paymentMethod.type;\n });\n setupRadioParentCheckedClass(input, this.shadowRoot);\n\n icon.src = `${fields.komojuApi}/payment_methods/${paymentMethod.type}.svg`;\n text.key = paymentMethod.type;\n\n picker.append(radio);\n\n i += 1;\n }\n\n // Set user-defined theme\n if (!this.theme && fields.theme) {\n this.theme = fields.theme;\n this.applyTheme();\n }\n }\n\n // To keep things dynamic, we pull payment method translations from KOMOJU.\n private async setupPaymentTypesI18n() {\n const fields = this.komojuFieldsElement();\n const response = await komojuFetch(fields, 'GET', '/api/v1/payment_methods');\n this.komojuPaymentMethods = await response.json();\n\n // Convert the \"name_en\", \"name_ja\" etc into { \"en\": { \"\": \"\" } }.\n for (const method of this.komojuPaymentMethods!) {\n const i18n = {\n en: { [method.type_slug]: method.name_en },\n ja: { [method.type_slug]: method.name_ja },\n ko: { [method.type_slug]: method.name_ko },\n };\n registerMessages(i18n);\n }\n }\n\n // Update the locale of the shadow DOM parent element. This allows children to\n // determine the locale.\n private updatePickerLocale(locale: string) {\n if (!this.shadowRoot) return;\n const picker = this.shadowRoot.getElementById('picker');\n if (picker) { picker.setAttribute('locale', locale) };\n }\n}\n", "import './types.d';\nimport KomojuFieldsElement from './komoju-fields-element';\nimport KomojuPickerElement from './komoju-picker-element';\nimport KomojuI18nElement from './shared/komoju-i18n-element';\ndeclare let window: WindowWithKomojuGlobals;\n\n// Public custom elements\nwindow.customElements.define('komoju-fields', KomojuFieldsElement);\nwindow.customElements.define('komoju-picker', KomojuPickerElement);\nwindow.customElements.define('komoju-i18n', KomojuI18nElement);\n\n// Error reporting\nwindow.komojuReportError = (error, context) => {\n console.error(error, context);\n}\nif (window.komojuErrorReporting !== false) {\n // Import proper error reporting module (Honeybadger) if implementer hasn't disabled it\n (async () => {\n // HACK: unnecessary interpolation because of typescript not knowing the type of the import\n // This is a dynamic import because it means implementers who don't want it can opt out of\n // a very large chunk of JS.\n const moduleName = 'error-reporting';\n const module = await import(`https://multipay.komoju.com/extras/${moduleName}/module.js`);\n window.komojuReportError = module.reportError;\n })();\n\n // Catch errors (only ones that involve KomojuFields)\n const onerror = (event: ErrorEvent | PromiseRejectionEvent) => {\n const komojuFieldsFiles = [\n /\\/fields\\.js:\\d+:\\d+\\n/,\n /\\/fields\\/[\\w-]+\\/module\\.js\\n:\\d+:\\d+/,\n /\\/extras\\/[\\w-]+\\/module\\.js\\n:\\d+:\\d+/,\n ];\n\n const error = (event instanceof ErrorEvent) ? event.error : (event.reason as Error);\n\n if (!(error instanceof Error)) return;\n if (!error.stack) return;\n if (!komojuFieldsFiles.find((regex) => regex.test(error.stack!))) return;\n\n window.komojuReportError(error);\n };\n\n window.addEventListener('error', onerror);\n window.addEventListener('unhandledrejection', onerror);\n}\n"], - "mappings": "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", - "names": [] -} diff --git a/src/app/code/Komoju/Payments/view/frontend/web/js/fields/bank_transfer/module.js b/src/app/code/Komoju/Payments/view/frontend/web/js/fields/bank_transfer/module.js deleted file mode 100644 index 9f49905bc..000000000 --- a/src/app/code/Komoju/Payments/view/frontend/web/js/fields/bank_transfer/module.js +++ /dev/null @@ -1,303 +0,0 @@ -var __defProp = Object.defineProperty; -var __export = (target, all) => { - for (var name in all) - __defProp(target, name, { get: all[name], enumerable: true }); -}; - -// src/fields/bank_transfer/template.html -var template_default = '
\n \n\n \n\n \n\n \n\n \n\n \n
\n\n
    \n
\n\n\n\n\n'; - -// src/shared/validation.ts -function addValidation(_i18n, input, callback) { - input.classList.add("has-validation"); - input.addEventListener("input", () => { - input.dataset.validationDirty = "true"; - }); - const validate = (event) => { - const input2 = event.target; - const errorMessageKey = callback(input2); - if (errorMessageKey) { - showError(_i18n, input2, errorMessageKey); - } - }; - input.addEventListener("blur", (event) => { - if (input.dataset.validationDirty !== "true") - return; - else - return validate(event); - }); - input.addEventListener("validate", validate); - input.addEventListener("focus", (event) => { - const input2 = event.target; - clearErrors(input2); - }); -} -function showError(_i18n, input, messageKey) { - input.classList.add("invalid"); - const key = messageKey; - const container = input.parentElement; - const dupeSelector = `komoju-error:not(.removing) > komoju-i18n[key="${key}"]`; - if (container?.querySelector(dupeSelector)) { - return; - } - container?.append(createErrorElement(messageKey)); -} -function clearErrors(input) { - input.classList.remove("invalid"); - input.parentElement?.querySelectorAll("komoju-error:not(.removing)").forEach((element) => { - element.remove(); - }); -} -function createErrorElement(messageKey) { - const el = window.document.createElement("komoju-error"); - const i18nEl = window.document.createElement("komoju-i18n"); - i18nEl.key = messageKey; - el.appendChild(i18nEl); - return el; -} - -// src/shared/translations.ts -function registerMessages(messages) { - if (!window.komojuTranslations) { - window.komojuTranslations = { "en": {}, "ja": {} }; - } - for (const lang of Object.keys(window.komojuTranslations)) { - window.komojuTranslations[lang] = { - ...window.komojuTranslations[lang], - ...messages[lang] - }; - } -} - -// src/fields/bank_transfer/i18n.ts -var i18n_exports = {}; -__export(i18n_exports, { - en: () => en, - ja: () => ja -}); -var en = { - "bt.label.lastname": "Last name", - "bt.label.firstname": "First name", - "bt.label.lastname-kana": "Last name (kana)", - "bt.label.firstname-kana": "First name (kana)", - "bt.label.email": "Email address", - "bt.label.phone": "Phone number", - "bt.error.required": "Required" -}; -var ja = { - "bt.label.lastname": "\u59D3", - "bt.label.firstname": "\u540D", - "bt.label.lastname-kana": "\u59D3 (\u30AB\u30BF\u30AB\u30CA)", - "bt.label.firstname-kana": "\u540D (\u30AB\u30BF\u30AB\u30CA)", - "bt.label.email": "\u30E1\u30FC\u30EB\u30A2\u30C9\u30EC\u30B9", - "bt.label.phone": "\u96FB\u8A71\u756A\u53F7", - "bt.error.required": "\u5FC5\u9808\u9805\u76EE\u3067\u3059" -}; - -// src/shared/char-width-utils.ts -var conversionMap = { - \u30AC: "\uFF76\uFF9E", - \u30AE: "\uFF77\uFF9E", - \u30B0: "\uFF78\uFF9E", - \u30B2: "\uFF79\uFF9E", - \u30B4: "\uFF7A\uFF9E", - \u30B6: "\uFF7B\uFF9E", - \u30B8: "\uFF7C\uFF9E", - \u30BA: "\uFF7D\uFF9E", - \u30BC: "\uFF7E\uFF9E", - \u30BE: "\uFF7F\uFF9E", - \u30C0: "\uFF80\uFF9E", - \u30C2: "\uFF81\uFF9E", - \u30C5: "\uFF82\uFF9E", - \u30C7: "\uFF83\uFF9E", - \u30C9: "\uFF84\uFF9E", - \u30D0: "\uFF8A\uFF9E", - \u30D3: "\uFF8B\uFF9E", - \u30D6: "\uFF8C\uFF9E", - \u30D9: "\uFF8D\uFF9E", - \u30DC: "\uFF8E\uFF9E", - \u30D1: "\uFF8A\uFF9F", - \u30D4: "\uFF8B\uFF9F", - \u30D7: "\uFF8C\uFF9F", - \u30DA: "\uFF8D\uFF9F", - \u30DD: "\uFF8E\uFF9F", - \u30F4: "\uFF73\uFF9E", - \u30F7: "\uFF9C\uFF9E", - \u30FA: "\uFF66\uFF9E", - \u30A2: "\uFF71", - \u30A4: "\uFF72", - \u30A6: "\uFF73", - \u30A8: "\uFF74", - \u30AA: "\uFF75", - \u30AB: "\uFF76", - \u30AD: "\uFF77", - \u30AF: "\uFF78", - \u30B1: "\uFF79", - \u30B3: "\uFF7A", - \u30B5: "\uFF7B", - \u30B7: "\uFF7C", - \u30B9: "\uFF7D", - \u30BB: "\uFF7E", - \u30BD: "\uFF7F", - \u30BF: "\uFF80", - \u30C1: "\uFF81", - \u30C4: "\uFF82", - \u30C6: "\uFF83", - \u30C8: "\uFF84", - \u30CA: "\uFF85", - \u30CB: "\uFF86", - \u30CC: "\uFF87", - \u30CD: "\uFF88", - \u30CE: "\uFF89", - \u30CF: "\uFF8A", - \u30D2: "\uFF8B", - \u30D5: "\uFF8C", - \u30D8: "\uFF8D", - \u30DB: "\uFF8E", - \u30DE: "\uFF8F", - \u30DF: "\uFF90", - \u30E0: "\uFF91", - \u30E1: "\uFF92", - \u30E2: "\uFF93", - \u30E4: "\uFF94", - \u30E6: "\uFF95", - \u30E8: "\uFF96", - \u30E9: "\uFF97", - \u30EA: "\uFF98", - \u30EB: "\uFF99", - \u30EC: "\uFF9A", - \u30ED: "\uFF9B", - \u30EF: "\uFF9C", - \u30F2: "\uFF66", - \u30F3: "\uFF9D", - \u30A1: "\uFF67", - \u30A3: "\uFF68", - \u30A5: "\uFF69", - \u30A7: "\uFF6A", - \u30A9: "\uFF6B", - \u30C3: "\uFF6F", - \u30E3: "\uFF6C", - \u30E5: "\uFF6D", - \u30E7: "\uFF6E", - "\u3002": "\uFF61", - "\u3001": "\uFF64", - \u30FC: "\uFF70", - "\u2212": "-", - "\uFF08": "(", - "\uFF09": ")", - "\u300C": "\uFF62", - "\u300D": "\uFF63", - "\u30FB": "\uFF65", - "\u3000": " ", - \uFF21: "A", - \uFF22: "B", - \uFF23: "C", - \uFF24: "D", - \uFF25: "E", - \uFF26: "F", - \uFF27: "G", - \uFF28: "H", - \uFF29: "I", - \uFF2A: "J", - \uFF2B: "K", - \uFF2C: "L", - \uFF2D: "M", - \uFF2E: "N", - \uFF2F: "O", - \uFF30: "P", - \uFF31: "Q", - \uFF32: "R", - \uFF33: "S", - \uFF34: "T", - \uFF35: "U", - \uFF36: "V", - \uFF37: "W", - \uFF38: "X", - \uFF39: "Y", - \uFF3A: "Z", - \uFF41: "a", - \uFF42: "b", - \uFF43: "c", - \uFF44: "d", - \uFF45: "e", - \uFF46: "f", - \uFF47: "g", - \uFF48: "h", - \uFF49: "i", - \uFF4A: "j", - \uFF4B: "k", - \uFF4C: "l", - \uFF4D: "m", - \uFF4E: "n", - \uFF4F: "o", - \uFF50: "p", - \uFF51: "q", - \uFF52: "r", - \uFF53: "s", - \uFF54: "t", - \uFF55: "u", - \uFF56: "v", - \uFF57: "w", - \uFF58: "x", - \uFF59: "y", - \uFF5A: "z", - "\uFF10": "0", - "\uFF11": "1", - "\uFF12": "2", - "\uFF13": "3", - "\uFF14": "4", - "\uFF15": "5", - "\uFF16": "6", - "\uFF17": "7", - "\uFF18": "8", - "\uFF19": "9" -}; -function convertCharsToHalfWidth(str) { - const convertedChars = str.split("").map((char) => { - return conversionMap[char] ?? char; - }); - return convertedChars.join(""); -} - -// src/fields/bank_transfer/module.ts -registerMessages(i18n_exports); -var render = (root, paymentMethod) => { - root.innerHTML = template_default; - root.querySelectorAll("input").forEach((element) => { - addValidation(i18n_exports, element, (input) => { - if (input.value === "") - return "bt.error.required"; - return null; - }); - }); - root.querySelectorAll(".kana").forEach((element) => { - element.addEventListener("input", (event) => { - const input = event.target; - if (input.dataset.ime === "active") - return; - input.value = convertCharsToHalfWidth(input.value); - }); - }); -}; -var paymentDetails = (root, _paymentMethod) => { - const firstname = root.querySelector("#bt-firstname"); - const lastname = root.querySelector("#bt-lastname"); - const firstnameKana = root.querySelector("#bt-firstname-kana"); - const lastnameKana = root.querySelector("#bt-lastname-kana"); - const email = root.querySelector("#bt-email"); - const phone = root.querySelector("#bt-phone"); - return { - type: "bank_transfer", - email: email.value, - family_name: lastname.value, - family_name_kana: lastnameKana.value, - given_name: firstname.value, - given_name_kana: firstnameKana.value, - phone: phone.value - }; -}; -export { - paymentDetails, - render -}; -//# sourceMappingURL=module.js.map diff --git a/src/app/code/Komoju/Payments/view/frontend/web/js/fields/bank_transfer/module.js.map b/src/app/code/Komoju/Payments/view/frontend/web/js/fields/bank_transfer/module.js.map deleted file mode 100644 index 68aa3b3b7..000000000 --- a/src/app/code/Komoju/Payments/view/frontend/web/js/fields/bank_transfer/module.js.map +++ /dev/null @@ -1,7 +0,0 @@ -{ - "version": 3, - "sources": ["../../../src/shared/validation.ts", "../../../src/shared/translations.ts", "../../../src/fields/bank_transfer/i18n.ts", "../../../src/shared/char-width-utils.ts", "../../../src/fields/bank_transfer/module.ts"], - "sourcesContent": ["// Adds validation to an input element.\nexport function addValidation(\n _i18n: Translations, // Used only by typescript to compile-time catch missing translations.\n input: HTMLInputElement,\n callback: (input: HTMLInputElement) => keyof Translations['en'] | null\n) {\n // Add a class so that we know this input has validation.\n input.classList.add('has-validation');\n\n // Tiny detail: if the user has never inputted anything, we don't want to run validations at all\n // at the risk of showing an error message when the user is just clicking around.\n input.addEventListener('input', () => {\n input.dataset.validationDirty = 'true';\n });\n\n // Validation function. This will be called on 'blur' and also on a custom 'validate' event.\n const validate = (event: Event) => {\n const input = event.target as HTMLInputElement;\n\n const errorMessageKey = callback(input);\n\n if (errorMessageKey) {\n showError(_i18n, input, errorMessageKey);\n }\n };\n input.addEventListener('blur', (event) => {\n if (input.dataset.validationDirty !== 'true') return;\n else return validate(event);\n });\n input.addEventListener('validate', validate);\n\n // When the user focuses on the input, remove all error artifacts.\n input.addEventListener('focus', (event) => {\n const input = event.target as HTMLInputElement;\n clearErrors(input);\n });\n}\n\nexport function showError(\n _i18n: Translations, // Used only by typescript to compile-time catch missing translations.\n input: HTMLInputElement,\n messageKey: keyof Translations['en']\n) {\n input.classList.add('invalid');\n const key = messageKey as string;\n\n // We don't want to show the same error twice!\n const container = input.parentElement;\n const dupeSelector = `komoju-error:not(.removing) > komoju-i18n[key=\"${key}\"]`;\n if (container?.querySelector(dupeSelector)) {\n return;\n }\n\n container?.append(createErrorElement(messageKey as string));\n}\n\nexport function clearErrors(input: HTMLInputElement) {\n input.classList.remove('invalid');\n input.parentElement?.querySelectorAll('komoju-error:not(.removing)').forEach((element) => {\n element.remove();\n });\n}\n\n// Runs validations on an element.\nexport function runValidation(input: HTMLInputElement) {\n // Fire the 'validate' custom event.\n input.dispatchEvent(new CustomEvent('validate'));\n\n // If there's an error message, return it.\n const errorMessage = input.parentElement?.querySelector('komoju-error:not(.removing)')?.textContent;\n return errorMessage ?? null;\n}\n\n// Creates the error message element that appears under an invalid input.\n// Mainly just called by addValidation().\nexport function createErrorElement(messageKey: string) {\n const el = window.document.createElement('komoju-error');\n const i18nEl = window.document.createElement('komoju-i18n') as KomojuI18nElement;\n i18nEl.key = messageKey;\n el.appendChild(i18nEl);\n return el;\n}\n", "declare let window: WindowWithKomojuGlobals;\n\n// Call this to add messages to the registry.\n// Individual payment method modules can do this to add their own messages.\n// That way, we avoid needing to load all messages for every payment method upfront.\nexport function registerMessages(messages: I18n) {\n if (!window.komojuTranslations) {\n window.komojuTranslations = { 'en': {}, 'ja': {} };\n }\n\n for (const lang of Object.keys(window.komojuTranslations)) {\n window.komojuTranslations[lang] = {\n ...window.komojuTranslations[lang],\n ...messages[lang],\n };\n }\n}\n", "export const en = {\n 'bt.label.lastname': 'Last name',\n 'bt.label.firstname': 'First name',\n 'bt.label.lastname-kana': 'Last name (kana)',\n 'bt.label.firstname-kana': 'First name (kana)',\n 'bt.label.email': 'Email address',\n 'bt.label.phone': 'Phone number',\n 'bt.error.required': 'Required',\n};\n\nexport const ja: typeof en = {\n 'bt.label.lastname': '\u59D3',\n 'bt.label.firstname': '\u540D',\n 'bt.label.lastname-kana': '\u59D3 (\u30AB\u30BF\u30AB\u30CA)',\n 'bt.label.firstname-kana': '\u540D (\u30AB\u30BF\u30AB\u30CA)',\n 'bt.label.email': '\u30E1\u30FC\u30EB\u30A2\u30C9\u30EC\u30B9',\n 'bt.label.phone': '\u96FB\u8A71\u756A\u53F7',\n 'bt.error.required': '\u5FC5\u9808\u9805\u76EE\u3067\u3059',\n};\n", "const conversionMap: any = {\n \u30AC: '\uFF76\uFF9E',\n \u30AE: '\uFF77\uFF9E',\n \u30B0: '\uFF78\uFF9E',\n \u30B2: '\uFF79\uFF9E',\n \u30B4: '\uFF7A\uFF9E',\n \u30B6: '\uFF7B\uFF9E',\n \u30B8: '\uFF7C\uFF9E',\n \u30BA: '\uFF7D\uFF9E',\n \u30BC: '\uFF7E\uFF9E',\n \u30BE: '\uFF7F\uFF9E',\n \u30C0: '\uFF80\uFF9E',\n \u30C2: '\uFF81\uFF9E',\n \u30C5: '\uFF82\uFF9E',\n \u30C7: '\uFF83\uFF9E',\n \u30C9: '\uFF84\uFF9E',\n \u30D0: '\uFF8A\uFF9E',\n \u30D3: '\uFF8B\uFF9E',\n \u30D6: '\uFF8C\uFF9E',\n \u30D9: '\uFF8D\uFF9E',\n \u30DC: '\uFF8E\uFF9E',\n \u30D1: '\uFF8A\uFF9F',\n \u30D4: '\uFF8B\uFF9F',\n \u30D7: '\uFF8C\uFF9F',\n \u30DA: '\uFF8D\uFF9F',\n \u30DD: '\uFF8E\uFF9F',\n \u30F4: '\uFF73\uFF9E',\n \u30F7: '\uFF9C\uFF9E',\n \u30FA: '\uFF66\uFF9E',\n \u30A2: '\uFF71',\n \u30A4: '\uFF72',\n \u30A6: '\uFF73',\n \u30A8: '\uFF74',\n \u30AA: '\uFF75',\n \u30AB: '\uFF76',\n \u30AD: '\uFF77',\n \u30AF: '\uFF78',\n \u30B1: '\uFF79',\n \u30B3: '\uFF7A',\n \u30B5: '\uFF7B',\n \u30B7: '\uFF7C',\n \u30B9: '\uFF7D',\n \u30BB: '\uFF7E',\n \u30BD: '\uFF7F',\n \u30BF: '\uFF80',\n \u30C1: '\uFF81',\n \u30C4: '\uFF82',\n \u30C6: '\uFF83',\n \u30C8: '\uFF84',\n \u30CA: '\uFF85',\n \u30CB: '\uFF86',\n \u30CC: '\uFF87',\n \u30CD: '\uFF88',\n \u30CE: '\uFF89',\n \u30CF: '\uFF8A',\n \u30D2: '\uFF8B',\n \u30D5: '\uFF8C',\n \u30D8: '\uFF8D',\n \u30DB: '\uFF8E',\n \u30DE: '\uFF8F',\n \u30DF: '\uFF90',\n \u30E0: '\uFF91',\n \u30E1: '\uFF92',\n \u30E2: '\uFF93',\n \u30E4: '\uFF94',\n \u30E6: '\uFF95',\n \u30E8: '\uFF96',\n \u30E9: '\uFF97',\n \u30EA: '\uFF98',\n \u30EB: '\uFF99',\n \u30EC: '\uFF9A',\n \u30ED: '\uFF9B',\n \u30EF: '\uFF9C',\n \u30F2: '\uFF66',\n \u30F3: '\uFF9D',\n \u30A1: '\uFF67',\n \u30A3: '\uFF68',\n \u30A5: '\uFF69',\n \u30A7: '\uFF6A',\n \u30A9: '\uFF6B',\n \u30C3: '\uFF6F',\n \u30E3: '\uFF6C',\n \u30E5: '\uFF6D',\n \u30E7: '\uFF6E',\n '\u3002': '\uFF61',\n '\u3001': '\uFF64',\n \u30FC: '\uFF70',\n '\u2212': '-',\n '\uFF08': '(',\n '\uFF09': ')',\n '\u300C': '\uFF62',\n '\u300D': '\uFF63',\n '\u30FB': '\uFF65',\n '\u3000': ' ',\n \uFF21: 'A',\n \uFF22: 'B',\n \uFF23: 'C',\n \uFF24: 'D',\n \uFF25: 'E',\n \uFF26: 'F',\n \uFF27: 'G',\n \uFF28: 'H',\n \uFF29: 'I',\n \uFF2A: 'J',\n \uFF2B: 'K',\n \uFF2C: 'L',\n \uFF2D: 'M',\n \uFF2E: 'N',\n \uFF2F: 'O',\n \uFF30: 'P',\n \uFF31: 'Q',\n \uFF32: 'R',\n \uFF33: 'S',\n \uFF34: 'T',\n \uFF35: 'U',\n \uFF36: 'V',\n \uFF37: 'W',\n \uFF38: 'X',\n \uFF39: 'Y',\n \uFF3A: 'Z',\n \uFF41: 'a',\n \uFF42: 'b',\n \uFF43: 'c',\n \uFF44: 'd',\n \uFF45: 'e',\n \uFF46: 'f',\n \uFF47: 'g',\n \uFF48: 'h',\n \uFF49: 'i',\n \uFF4A: 'j',\n \uFF4B: 'k',\n \uFF4C: 'l',\n \uFF4D: 'm',\n \uFF4E: 'n',\n \uFF4F: 'o',\n \uFF50: 'p',\n \uFF51: 'q',\n \uFF52: 'r',\n \uFF53: 's',\n \uFF54: 't',\n \uFF55: 'u',\n \uFF56: 'v',\n \uFF57: 'w',\n \uFF58: 'x',\n \uFF59: 'y',\n \uFF5A: 'z',\n '\uFF10': '0',\n '\uFF11': '1',\n '\uFF12': '2',\n '\uFF13': '3',\n '\uFF14': '4',\n '\uFF15': '5',\n '\uFF16': '6',\n '\uFF17': '7',\n '\uFF18': '8',\n '\uFF19': '9'\n};\n\nexport function convertCharsToHalfWidth(str: string) {\n const convertedChars = str.split('').map(char => {\n return conversionMap[char] ?? char;\n });\n\n return convertedChars.join('');\n}\n\nexport function convertNumbersToHalfWidth(str: string) {\n var fullwidth = '\uFF10\uFF11\uFF12\uFF13\uFF14\uFF15\uFF16\uFF17\uFF18\uFF19\uFF0F';\n var halfwidth = '0123456789/';\n\n for (var i = 0; i < 10; ++i) {\n str = str.replace(\n new RegExp(fullwidth.charAt(i), 'g'),\n halfwidth.charAt(i)\n );\n }\n\n return str;\n}\n", "import '../../types.d';\n// @ts-ignore\nimport html from './template.html'\n\nimport { addValidation } from '../../shared/validation';\nimport { registerMessages } from '../../shared/translations';\nimport * as i18n from './i18n';\nimport { convertCharsToHalfWidth } from '../../shared/char-width-utils';\nregisterMessages(i18n);\n\nexport const render: KomojuRenderFunction = (root, paymentMethod) => {\n root.innerHTML = html;\n\n // All fields are required.\n root.querySelectorAll('input').forEach(element => {\n addValidation(i18n, element, (input) => {\n if (input.value === '') return 'bt.error.required';\n return null;\n });\n });\n\n // Automatically convert full-width kana to half-width.\n root.querySelectorAll('.kana').forEach(element => {\n element.addEventListener('input', (event) => {\n const input = event.target as HTMLInputElement;\n\n // This \"ime\" data comes from komoju-host-element.ts. It lets us avoid messing up\n // customer input during IME composition.\n if (input.dataset.ime === 'active') return;\n\n input.value = convertCharsToHalfWidth(input.value);\n });\n });\n}\n\nexport const paymentDetails: KomojuPaymentDetailsFunction = (root, _paymentMethod) => {\n const firstname = root.querySelector('#bt-firstname')! as HTMLInputElement;\n const lastname = root.querySelector('#bt-lastname')! as HTMLInputElement;\n const firstnameKana = root.querySelector('#bt-firstname-kana')! as HTMLInputElement;\n const lastnameKana = root.querySelector('#bt-lastname-kana')! as HTMLInputElement;\n const email = root.querySelector('#bt-email')! as HTMLInputElement;\n const phone = root.querySelector('#bt-phone')! as HTMLInputElement;\n\n return {\n type: 'bank_transfer',\n email: email.value,\n family_name: lastname.value,\n family_name_kana: lastnameKana.value,\n given_name: firstname.value,\n given_name_kana: firstnameKana.value,\n phone: phone.value,\n }\n}\n"], - "mappings": "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AA,EACH,QAAG;AAAA,EACH,QAAG;AAAA,EACH,QAAG;AAAA,EACH,QAAG;AAAA,EACH,QAAG;AAAA,EACH,QAAG;AAAA,EACH,QAAG;AAAA,EACH,QAAG;AAAA,EACH,QAAG;AAAA,EACH,QAAG;AAAA,EACH,QAAG;AAAA,EACH,QAAG;AAAA,EACH,QAAG;AAAA,EACH,QAAG;AAAA,EACH,QAAG;AAAA,EACH,QAAG;AAAA,EACH,QAAG;AAAA,EACH,QAAG;AAAA,EACH,QAAG;AAAA,EACH,QAAG;AAAA,EACH,QAAG;AAAA,EACH,QAAG;AAAA,EACH,QAAG;AAAA,EACH,QAAG;AAAA,EACH,QAAG;AAAA,EACH,QAAG;AAAA,EACH,QAAG;AAAA,EACH,QAAG;AAAA,EACH,QAAG;AAAA,EACH,UAAK;AAAA,EACL,UAAK;AAAA,EACL,QAAG;AAAA,EACH,UAAK;AAAA,EACL,UAAK;AAAA,EACL,UAAK;AAAA,EACL,UAAK;AAAA,EACL,UAAK;AAAA,EACL,UAAK;AAAA,EACL,UAAK;AAAA,EACL,QAAG;AAAA,EACH,QAAG;AAAA,EACH,QAAG;AAAA,EACH,QAAG;AAAA,EACH,QAAG;AAAA,EACH,QAAG;AAAA,EACH,QAAG;AAAA,EACH,QAAG;AAAA,EACH,QAAG;AAAA,EACH,QAAG;AAAA,EACH,QAAG;AAAA,EACH,QAAG;AAAA,EACH,QAAG;AAAA,EACH,QAAG;AAAA,EACH,QAAG;AAAA,EACH,QAAG;AAAA,EACH,QAAG;AAAA,EACH,QAAG;AAAA,EACH,QAAG;AAAA,EACH,QAAG;AAAA,EACH,QAAG;AAAA,EACH,QAAG;AAAA,EACH,QAAG;AAAA,EACH,QAAG;AAAA,EACH,QAAG;AAAA,EACH,QAAG;AAAA,EACH,QAAG;AAAA,EACH,QAAG;AAAA,EACH,QAAG;AAAA,EACH,QAAG;AAAA,EACH,QAAG;AAAA,EACH,QAAG;AAAA,EACH,QAAG;AAAA,EACH,QAAG;AAAA,EACH,QAAG;AAAA,EACH,QAAG;AAAA,EACH,QAAG;AAAA,EACH,QAAG;AAAA,EACH,QAAG;AAAA,EACH,QAAG;AAAA,EACH,QAAG;AAAA,EACH,QAAG;AAAA,EACH,QAAG;AAAA,EACH,QAAG;AAAA,EACH,QAAG;AAAA,EACH,QAAG;AAAA,EACH,QAAG;AAAA,EACH,QAAG;AAAA,EACH,QAAG;AAAA,EACH,QAAG;AAAA,EACH,QAAG;AAAA,EACH,QAAG;AAAA,EACH,UAAK;AAAA,EACL,UAAK;AAAA,EACL,UAAK;AAAA,EACL,UAAK;AAAA,EACL,UAAK;AAAA,EACL,UAAK;AAAA,EACL,UAAK;AAAA,EACL,UAAK;AAAA,EACL,UAAK;AAAA,EACL,UAAK;AACP;AAEO,SAAS,wBAAwB,KAAa;AACnD,QAAM,iBAAiB,IAAI,MAAM,EAAE,EAAE,IAAI,UAAQ;AAC/C,WAAO,cAAc,SAAS;AAAA,EAChC,CAAC;AAED,SAAO,eAAe,KAAK,EAAE;AAC/B;;;AC5JA,iBAAiB,YAAI;AAEd,IAAM,SAA+B,CAAC,MAAM,kBAAkB;AACnE,OAAK,YAAY;AAGjB,OAAK,iBAAiB,OAAO,EAAE,QAAQ,aAAW;AAChD,kBAAc,cAAM,SAAS,CAAC,UAAU;AACtC,UAAI,MAAM,UAAU;AAAI,eAAO;AAC/B,aAAO;AAAA,IACT,CAAC;AAAA,EACH,CAAC;AAGD,OAAK,iBAAiB,OAAO,EAAE,QAAQ,aAAW;AAChD,YAAQ,iBAAiB,SAAS,CAAC,UAAU;AAC3C,YAAM,QAAQ,MAAM;AAIpB,UAAI,MAAM,QAAQ,QAAQ;AAAU;AAEpC,YAAM,QAAQ,wBAAwB,MAAM,KAAK;AAAA,IACnD,CAAC;AAAA,EACH,CAAC;AACH;AAEO,IAAM,iBAA+C,CAAC,MAAM,mBAAmB;AACpF,QAAM,YAAY,KAAK,cAAc,eAAe;AACpD,QAAM,WAAW,KAAK,cAAc,cAAc;AAClD,QAAM,gBAAgB,KAAK,cAAc,oBAAoB;AAC7D,QAAM,eAAe,KAAK,cAAc,mBAAmB;AAC3D,QAAM,QAAQ,KAAK,cAAc,WAAW;AAC5C,QAAM,QAAQ,KAAK,cAAc,WAAW;AAE5C,SAAO;AAAA,IACL,MAAM;AAAA,IACN,OAAO,MAAM;AAAA,IACb,aAAa,SAAS;AAAA,IACtB,kBAAkB,aAAa;AAAA,IAC/B,YAAY,UAAU;AAAA,IACtB,iBAAiB,cAAc;AAAA,IAC/B,OAAO,MAAM;AAAA,EACf;AACF;", - "names": ["input"] -} diff --git a/src/app/code/Komoju/Payments/view/frontend/web/js/fields/credit_card/module.js b/src/app/code/Komoju/Payments/view/frontend/web/js/fields/credit_card/module.js deleted file mode 100644 index 3ad5aed1c..000000000 --- a/src/app/code/Komoju/Payments/view/frontend/web/js/fields/credit_card/module.js +++ /dev/null @@ -1,500 +0,0 @@ -var __defProp = Object.defineProperty; -var __export = (target, all) => { - for (var name in all) - __defProp(target, name, { get: all[name], enumerable: true }); -}; - -// src/fields/credit_card/komoju-field-icon.html -var komoju_field_icon_default = '
\n
\n\n\n'; - -// src/fields/credit_card/komoju-field-icon-element.ts -var _KomojuFieldIconElement = class extends HTMLElement { - constructor() { - super(); - this.visibleIcons = []; - const root = this.attachShadow({ mode: "open" }); - root.innerHTML = komoju_field_icon_default; - } - static get observedAttributes() { - return ["icon", "for"]; - } - get target() { - const targetId = this.getAttribute("for"); - const root = this.getRootNode(); - if (!targetId || !root || !root["querySelector"]) - return void 0; - else - return root.querySelector(`#${targetId}`); - } - set target(target) { - if (target) - this.setAttribute("for", target.id); - else - this.setAttribute("for", ""); - } - get icon() { - return this.getAttribute("icon") || ""; - } - set icon(value) { - this.setAttribute("icon", value); - } - connectedCallback() { - this.style.width = "0"; - this.style.height = "0"; - const parent = this.parentElement; - if (!parent) - return; - this.resizeObserver = new ResizeObserver(() => { - this.reposition(); - }); - this.resizeObserver.observe(parent); - this.reposition(); - setTimeout(() => this.reposition(), 100); - } - disconnectedCallback() { - this.resizeObserver?.disconnect(); - this.resizeObserver = void 0; - } - attributeChangedCallback(name, oldValue, newValue) { - if (name === "icon") { - const container = this.shadowRoot?.getElementById("komoju-field-icon"); - if (!container) - throw new Error("KOMOJU Fields bug: field icon container missing"); - if (oldValue === newValue) - return; - const icons = newValue.split(/\s+/); - this.updateVisibleIcons(icons); - } else if (name === "for") { - this.reposition(); - } - } - updateVisibleIcons(icons) { - const container = this.shadowRoot?.getElementById("komoju-field-icon"); - const target = this.target; - if (!target || !container) - return; - const iconsWidth = icons.length * (_KomojuFieldIconElement.ICON_WIDTH + _KomojuFieldIconElement.ICON_GAP); - const maxWidth = target.offsetWidth / 2; - if (iconsWidth > maxWidth) { - const hiddenIconIndex = Math.floor(maxWidth / (_KomojuFieldIconElement.ICON_WIDTH + _KomojuFieldIconElement.ICON_GAP)); - const allIcons = icons; - icons = icons.slice(0, hiddenIconIndex); - if (this.iconSwapTimeout) - clearTimeout(this.iconSwapTimeout); - this.iconSwapTimeout = setTimeout(() => { - let carry = allIcons[hiddenIconIndex - 1]; - for (let i = hiddenIconIndex - 1; i < allIcons.length - 1; i += 1) { - const temp = allIcons[i + 1]; - allIcons[i + 1] = carry; - carry = temp; - } - allIcons[hiddenIconIndex - 1] = carry; - this.updateVisibleIcons(allIcons); - }, _KomojuFieldIconElement.ICON_SWAP_INTERVAL); - } else if (this.iconSwapTimeout) { - clearTimeout(this.iconSwapTimeout); - this.iconSwapTimeout = void 0; - } - const oldIcons = this.visibleIcons; - const newIcons = icons; - if (oldIcons === newIcons) - return; - const removedIcons = oldIcons.filter((icon) => !newIcons.includes(icon)); - this.visibleIcons = icons; - for (const icon of newIcons) { - const existing = container.querySelector(`img[src="${icon}"]`); - if (existing) { - existing.style.opacity = "1"; - continue; - } - const img = document.createElement("img"); - img.src = icon; - img.width = _KomojuFieldIconElement.ICON_WIDTH; - container.append(img); - img.style.opacity = "0"; - setTimeout(() => img.style.opacity = "1", 100); - } - for (const icon of removedIcons) { - const img = container.querySelector(`img[src="${icon}"]`); - img.style.opacity = "0"; - img.style.marginRight = "0"; - } - let position = 0; - for (let i = this.visibleIcons.length - 1; i >= 0; i -= 1) { - const icon = this.visibleIcons[i]; - const img = container.querySelector(`img[src="${icon}"]`); - img.style.marginRight = `${position * (_KomojuFieldIconElement.ICON_WIDTH + _KomojuFieldIconElement.ICON_GAP)}px`; - position += 1; - } - } - reposition() { - const parent = this.parentElement; - const target = this.target; - const container = this.shadowRoot?.getElementById("komoju-field-icon"); - if (!target || !parent || !container) - return; - container.style.top = `${target.offsetTop}px`; - container.style.right = `${parent.offsetWidth - target.offsetWidth - target.offsetLeft}px`; - container.style.height = `${target.offsetHeight}px`; - const targetStyle = window.getComputedStyle(target); - container.style.paddingRight = targetStyle.paddingRight; - container.style.paddingTop = targetStyle.paddingTop; - container.style.paddingBottom = targetStyle.paddingBottom; - const icons = this.getAttribute("icon")?.split(/\s+/) || []; - this.updateVisibleIcons(icons); - } -}; -var KomojuFieldIconElement = _KomojuFieldIconElement; -KomojuFieldIconElement.ICON_WIDTH = 42; -KomojuFieldIconElement.ICON_GAP = 4; -KomojuFieldIconElement.ICON_SWAP_INTERVAL = 5e3; - -// src/fields/credit_card/template.html -var template_default = '
\n \n\n \n\n \n\n \n
\n\n
    \n
\n\n\n\n\n'; - -// src/shared/char-width-utils.ts -function convertNumbersToHalfWidth(str) { - var fullwidth = "\uFF10\uFF11\uFF12\uFF13\uFF14\uFF15\uFF16\uFF17\uFF18\uFF19\uFF0F"; - var halfwidth = "0123456789/"; - for (var i = 0; i < 10; ++i) { - str = str.replace( - new RegExp(fullwidth.charAt(i), "g"), - halfwidth.charAt(i) - ); - } - return str; -} - -// src/shared/validation.ts -function addValidation(_i18n, input, callback) { - input.classList.add("has-validation"); - input.addEventListener("input", () => { - input.dataset.validationDirty = "true"; - }); - const validate = (event) => { - const input2 = event.target; - const errorMessageKey = callback(input2); - if (errorMessageKey) { - showError(_i18n, input2, errorMessageKey); - } - }; - input.addEventListener("blur", (event) => { - if (input.dataset.validationDirty !== "true") - return; - else - return validate(event); - }); - input.addEventListener("validate", validate); - input.addEventListener("focus", (event) => { - const input2 = event.target; - clearErrors(input2); - }); -} -function showError(_i18n, input, messageKey) { - input.classList.add("invalid"); - const key = messageKey; - const container = input.parentElement; - const dupeSelector = `komoju-error:not(.removing) > komoju-i18n[key="${key}"]`; - if (container?.querySelector(dupeSelector)) { - return; - } - container?.append(createErrorElement(messageKey)); -} -function clearErrors(input) { - input.classList.remove("invalid"); - input.parentElement?.querySelectorAll("komoju-error:not(.removing)").forEach((element) => { - element.remove(); - }); -} -function createErrorElement(messageKey) { - const el = window.document.createElement("komoju-error"); - const i18nEl = window.document.createElement("komoju-i18n"); - i18nEl.key = messageKey; - el.appendChild(i18nEl); - return el; -} - -// src/fields/credit_card/card-number-utils.ts -function cardTypeToKomojuSubtype(type) { - if (type === "amex") - return "american_express"; - if (type === "diner") - return "diners_club"; - if (type === "jcb15") - return "jcb"; - if (type === "mastercard") - return "master"; - return type; -} -function insertSpaceEvery4Characters(str) { - return str.replace(/(.{4})/g, "$1 ").trim(); -} -function cardNumberMaxLength(type) { - if (type == "diner") { - return 16; - } else if (type == "amex") { - return 17; - } else { - return 23; - } -} -function formatCardNumber(value, type) { - if (type == "unknown" || type == "visa" || type == "jcb" || type == "mastercard") { - return insertSpaceEvery4Characters(value); - } else { - return value.replace(/(.{4})/, "$1 ").replace(/(.{11})/, "$1 ").trim(); - } -} -function removeNonDigits(value) { - return value.replace(/[^0-9( \/ )]+/g, ""); -} -function insertSlash(value) { - const hasSlash = value.includes("/"); - const hasFullMonth = value.length >= 2; - if (hasFullMonth && !hasSlash) { - let yearStart = value.lastIndexOf(" "); - if (yearStart === -1) - yearStart = 2; - const month = value.slice(0, 2); - const year = value.slice(yearStart, value.length); - return `${month} / ${year}`; - } - return value; -} -function removeSlash(value) { - return value.endsWith("/") ? value.replace(/[^0-9]+/g, "") : value; -} -var cardTypeRegex = { - amex: /^3[47]\d{0,13}/, - diner: /^3(?:0([0-5]|9)|[689]\d?)\d{0,11}/, - mastercard: /^(5[1-5]\d{0,2}|22[2-9]\d{0,1}|2[3-7]\d{0,2})\d{0,12}/, - jcb15: /^(?:2131|1800)\d{0,11}/, - jcb: /^(?:35)\d{0,17}/, - visa: /^4\d{0,18}/ -}; -function cardType(value) { - if (cardTypeRegex.amex.exec(value)) { - return "amex"; - } else if (cardTypeRegex.diner.exec(value)) { - return "diner"; - } else if (cardTypeRegex.mastercard.exec(value)) { - return "mastercard"; - } else if (cardTypeRegex.jcb15.exec(value)) { - return "jcb15"; - } else if (cardTypeRegex.jcb.exec(value)) { - return "jcb"; - } else if (cardTypeRegex.visa.exec(value)) { - return "visa"; - } else { - return "unknown"; - } -} -function luhnCheck(cardNumber) { - if (/[^0-9\s]+/.test(cardNumber)) { - return false; - } - let sum = 0; - let shouldDouble = false; - cardNumber = cardNumber.replace(/\D/g, ""); - const length = cardNumber.length; - for (let i = length - 1; i >= 0; --i) { - let digit = parseInt(cardNumber.charAt(i), 10); - if (shouldDouble && (digit *= 2) > 9) { - digit -= 9; - } - sum += digit; - shouldDouble = !shouldDouble; - } - return sum % 10 === 0; -} - -// src/shared/translations.ts -function registerMessages(messages) { - if (!window.komojuTranslations) { - window.komojuTranslations = { "en": {}, "ja": {} }; - } - for (const lang of Object.keys(window.komojuTranslations)) { - window.komojuTranslations[lang] = { - ...window.komojuTranslations[lang], - ...messages[lang] - }; - } -} - -// src/fields/credit_card/i18n.ts -var i18n_exports = {}; -__export(i18n_exports, { - en: () => en, - ja: () => ja -}); -var en = { - "cc.label.cardholder-name": "Cardholder name", - "cc.label.card-number": "Card number", - "cc.label.expiration": "Expiration", - "cc.label.cvc": "CVC", - "cc.error.required": "Required", - "cc.error.incomplete": "Please input the full expiration date", - "cc.error.please_use_half_width": "Please use half-width characters", - "cc.error.invalid-number": "Invalid number", - "cc.error.expired": "Card is expired", - "cc.error.invalid-month": "Month must be between 1 and 12", - "cc.error.unsupported-brand": "Unsupported card brand" -}; -var ja = { - "cc.label.cardholder-name": "\u30AB\u30FC\u30C9\u6240\u6709\u8005\u540D", - "cc.label.card-number": "\u30AB\u30FC\u30C9\u756A\u53F7", - "cc.label.expiration": "\u6709\u52B9\u671F\u9650", - "cc.label.cvc": "\u30BB\u30AD\u30E5\u30EA\u30C6\u30A3\u30B3\u30FC\u30C9", - "cc.error.required": "\u5FC5\u9808\u9805\u76EE\u3067\u3059", - "cc.error.incomplete": "\u6709\u52B9\u671F\u9650\u3092\u6B63\u3057\u304F\u5165\u529B\u3057\u3066\u304F\u3060\u3055\u3044", - "cc.error.please_use_half_width": "\u534A\u89D2\u82F1\u6570\u5B57\u30FB\u8A18\u53F7\u306E\u307F\u6709\u52B9\u3067\u3059", - "cc.error.invalid-number": "\u30AB\u30FC\u30C9\u756A\u53F7\u304C\u6B63\u3057\u304F\u3042\u308A\u307E\u305B\u3093", - "cc.error.expired": "\u30AB\u30FC\u30C9\u306E\u6709\u52B9\u671F\u9650\u304C\u5207\u308C\u3066\u3044\u307E\u3059", - "cc.error.invalid-month": "\u6708\u306F1\u304B\u308912\u306E\u9593\u3067\u5165\u529B\u3057\u3066\u304F\u3060\u3055\u3044", - "cc.error.unsupported-brand": "\u5BFE\u5FDC\u3057\u3066\u3044\u306A\u3044\u30AF\u30EC\u30B8\u30C3\u30C8\u30AB\u30FC\u30C9\u30D6\u30E9\u30F3\u30C9\u3067\u3059" -}; - -// src/fields/credit_card/module.ts -registerMessages(i18n_exports); -window.customElements.define("komoju-field-icon", KomojuFieldIconElement); -var render = (root, paymentMethod) => { - root.innerHTML = template_default; - initializeInputs( - root, - paymentMethod - ); -}; -function initializeInputs(root, paymentMethod) { - const name = document.getElementById("cc-name"); - addValidation(i18n_exports, name, (input) => { - if (input.value === "") - return "cc.error.required"; - if (/[^\x01-\x7E]/.test(input.value)) - return "cc.error.please_use_half_width"; - return null; - }); - const cardIcon = document.getElementById("cc-icon"); - const defaultCardImage = `${root.komojuCdn}/static/credit_card_number.svg`; - const supportedBrandImages = paymentMethod.brands.map((brand) => { - return `https://komoju.com/payment_methods/credit_card.svg?brands=${brand}`; - }).join(" "); - cardIcon.icon = supportedBrandImages; - const number = document.getElementById("cc-number"); - number.addEventListener("input", (event) => { - const input = event.target; - if (input.dataset.ime === "active") - return; - let value = input.value; - value = convertNumbersToHalfWidth(value).replace(/\D/g, ""); - if (value.length === 0) { - clearErrors(input); - } - const type = cardType(value); - input.maxLength = cardNumberMaxLength(type); - input.value = formatCardNumber(value, type); - input.dataset.brand = type; - const brand = cardTypeToKomojuSubtype(type); - if (type === "unknown") { - if (value.length < 3) { - cardIcon.icon = supportedBrandImages; - } else { - cardIcon.icon = defaultCardImage; - } - } else if (paymentMethod.brands.includes(brand)) { - cardIcon.icon = `https://komoju.com/payment_methods/credit_card.svg?brands=${brand}`; - clearErrors(input); - } else { - cardIcon.icon = supportedBrandImages; - showError(i18n_exports, input, "cc.error.unsupported-brand"); - } - }); - addValidation(i18n_exports, number, (input) => { - const value = input.value.replace(/\D/g, ""); - if (value === "") - return "cc.error.required"; - if (!luhnCheck(value)) - return "cc.error.invalid-number"; - const type = cardType(value); - const brand = cardTypeToKomojuSubtype(type); - if (type === "unknown") - return "cc.error.unsupported-brand"; - if (!paymentMethod.brands.includes(brand)) - return "cc.error.unsupported-brand"; - return null; - }); - const exp = document.getElementById("cc-exp"); - let lastExpValue = exp.value; - exp.addEventListener("input", (event) => { - const input = event.target; - if (input.dataset.ime === "active") - return; - let value = convertNumbersToHalfWidth(input.value); - const addedNewCharacter = value.length > lastExpValue.length; - value = removeNonDigits(value); - value = addedNewCharacter ? insertSlash(value) : removeSlash(value); - input.value = value; - lastExpValue = value; - }); - exp.addEventListener("blur", (event) => { - const input = event.target; - if (input.dataset.ime === "inactive") { - let value = convertNumbersToHalfWidth(input.value); - value = removeNonDigits(value); - value = insertSlash(value); - input.value = value; - lastExpValue = value; - } - }); - addValidation(i18n_exports, exp, (input) => { - const mmyy = input.value.replace(/[^0-9\/]/g, ""); - const [month, year] = mmyy.split("/"); - if (month == null || year == null || year.length !== 2 || month.length !== 2 || !/^\d{2}\/\d{2}$/.test(mmyy)) { - return "cc.error.incomplete"; - } - const now = new Date(); - const currentYear = parseInt( - now.getFullYear().toString().substr(2, 2) - ); - const currentMonth = now.getMonth() + 1; - const monthNum = parseInt(month); - const yearNum = parseInt(year); - if (yearNum < currentYear) { - return "cc.error.expired"; - } - if (yearNum === currentYear && monthNum < currentMonth) { - return "cc.error.expired"; - } - if (monthNum > 12 || monthNum <= 0) { - return "cc.error.invalid-month"; - } - return null; - }); - const cvcIcon = document.getElementById("cc-cvc-icon"); - cvcIcon.icon = `${root.komojuCdn}/static/credit_card_cvc.svg`; - const cvc = document.getElementById("cc-cvc"); - addValidation(i18n_exports, cvc, (input) => { - if (input.value === "") - return "cc.error.required"; - return null; - }); -} -var paymentDetails = (root, _paymentMethod) => { - const name = root.querySelector("#cc-name"); - const number = root.querySelector("#cc-number"); - const expiration = root.querySelector("#cc-exp"); - const cvc = root.querySelector("#cc-cvc"); - const [month, year] = expiration.value.split("/").map((s) => s.trim()); - return { - type: "credit_card", - name: name.value, - number: number.value.replace(/\s+/g, ""), - month, - year, - verification_value: cvc.value - }; -}; -export { - paymentDetails, - render -}; -//# sourceMappingURL=module.js.map diff --git a/src/app/code/Komoju/Payments/view/frontend/web/js/fields/credit_card/module.js.map b/src/app/code/Komoju/Payments/view/frontend/web/js/fields/credit_card/module.js.map deleted file mode 100644 index e20f9dbb8..000000000 --- a/src/app/code/Komoju/Payments/view/frontend/web/js/fields/credit_card/module.js.map +++ /dev/null @@ -1,7 +0,0 @@ -{ - "version": 3, - "sources": ["../../../src/fields/credit_card/komoju-field-icon-element.ts", "../../../src/shared/char-width-utils.ts", "../../../src/shared/validation.ts", "../../../src/fields/credit_card/card-number-utils.ts", "../../../src/shared/translations.ts", "../../../src/fields/credit_card/i18n.ts", "../../../src/fields/credit_card/module.ts"], - "sourcesContent": ["// @ts-ignore\nimport html from './komoju-field-icon.html'\n\n// This element is only used for credit card.\n//\n// It lets us show the brand icons on the right side of an input element\n// without requiring sensitive DOM structure and CSS.\n//\n// Not having to worry about the DOM structure and CSS makes it easier to\n// allow custom CSS to be applied to the input elements.\nexport default class KomojuFieldIconElement extends HTMLElement {\n static ICON_WIDTH = 42;\n static ICON_GAP = 4;\n static ICON_SWAP_INTERVAL = 5000;\n\n static get observedAttributes() {\n return ['icon', 'for'];\n }\n\n // The element that this icon is for. Probably always an element.\n get target() {\n const targetId = this.getAttribute('for');\n const root = this.getRootNode() as HTMLElement;\n if (!targetId || !root || !root['querySelector']) return undefined;\n else return root.querySelector(`#${targetId}`) as HTMLElement;\n }\n set target(target: HTMLElement | undefined) {\n if (target) this.setAttribute('for', target.id);\n else this.setAttribute('for', '');\n }\n\n get icon() {\n return this.getAttribute('icon') || '';\n }\n set icon(value: string) {\n this.setAttribute('icon', value);\n }\n\n resizeObserver?: ResizeObserver;\n\n // When there's too many icons to fit in the container, we hide some of them.\n // The 'icons' attribute holds the full list of icons, and 'visibleIcons' holds\n // the list of icons that are currently visible.\n visibleIcons: string[] = [];\n\n // When we truncate icons, we want to show the hidden icons one at a time.\n iconSwapTimeout?: unknown;\n\n constructor() {\n super();\n const root = this.attachShadow({ mode: 'open' });\n root.innerHTML = html;\n }\n\n connectedCallback() {\n this.style.width = '0';\n this.style.height = '0';\n\n const parent = this.parentElement;\n if (!parent) return;\n\n this.resizeObserver = new ResizeObserver(() => {\n this.reposition();\n });\n this.resizeObserver!.observe(parent);\n this.reposition();\n setTimeout(() => this.reposition(), 100);\n }\n\n disconnectedCallback() {\n this.resizeObserver?.disconnect();\n this.resizeObserver = undefined;\n }\n \n attributeChangedCallback(name: string, oldValue: string | null, newValue: string) {\n if (name === 'icon') {\n const container = this.shadowRoot?.getElementById('komoju-field-icon');\n if (!container) throw new Error('KOMOJU Fields bug: field icon container missing');\n if (oldValue === newValue) return;\n\n const icons = newValue.split(/\\s+/);\n this.updateVisibleIcons(icons);\n }\n else if (name === 'for') {\n this.reposition();\n }\n }\n\n // Sometimes there can be too many icons and they cover the input field.\n // To account for this, we will hide some icons and then cycle through the hidden ones,\n // showing them one at a time.\n updateVisibleIcons(icons: string[]) {\n const container = this.shadowRoot?.getElementById('komoju-field-icon');\n const target = this.target;\n if (!target || !container) return;\n\n // If icons will be more than half of the target input's width, we'll chop some icons.\n const iconsWidth = icons.length * (KomojuFieldIconElement.ICON_WIDTH + KomojuFieldIconElement.ICON_GAP);\n const maxWidth = target.offsetWidth / 2;\n if (iconsWidth > maxWidth) {\n const hiddenIconIndex = Math.floor(maxWidth / (KomojuFieldIconElement.ICON_WIDTH + KomojuFieldIconElement.ICON_GAP));\n const allIcons = icons;\n icons = icons.slice(0, hiddenIconIndex);\n\n // Here we set up a setTimeout to show the hidden icons one by one.\n // This is recursive - we will call updateVisibleIcons again to rotate the icons.\n if (this.iconSwapTimeout) clearTimeout(this.iconSwapTimeout as number);\n this.iconSwapTimeout = setTimeout(() => {\n // Shift each icon to the right by one, and move the hidden icon to the front.\n let carry = allIcons[hiddenIconIndex - 1];\n for (let i = hiddenIconIndex - 1; i < allIcons.length - 1; i += 1) {\n const temp = allIcons[i + 1];\n allIcons[i + 1] = carry;\n carry = temp;\n }\n allIcons[hiddenIconIndex - 1] = carry;\n\n this.updateVisibleIcons(allIcons);\n }, KomojuFieldIconElement.ICON_SWAP_INTERVAL);\n } else if (this.iconSwapTimeout) {\n clearTimeout(this.iconSwapTimeout as number);\n this.iconSwapTimeout = undefined;\n }\n\n const oldIcons = this.visibleIcons;\n const newIcons = icons;\n if (oldIcons === newIcons) return;\n const removedIcons = oldIcons.filter((icon) => !newIcons.includes(icon));\n\n this.visibleIcons = icons;\n\n // First, add elements for new icons we've never seen before\n for (const icon of newIcons) {\n const existing = container.querySelector(`img[src=\"${icon}\"]`) as HTMLImageElement;\n if (existing) {\n existing.style.opacity = '1';\n continue;\n }\n\n const img = document.createElement('img');\n img.src = icon;\n img.width = KomojuFieldIconElement.ICON_WIDTH;\n container.append(img);\n img.style.opacity = '0';\n setTimeout(() => img.style.opacity = '1', 100);\n }\n\n // Then, remove elements for icons that are no longer present\n for (const icon of removedIcons) {\n const img = container.querySelector(`img[src=\"${icon}\"]`) as HTMLImageElement;\n img.style.opacity = '0';\n img.style.marginRight = '0';\n }\n\n // Finally, reposition the icons\n let position = 0;\n for (let i = this.visibleIcons.length - 1; i >= 0; i -= 1) {\n const icon = this.visibleIcons[i];\n const img = container.querySelector(`img[src=\"${icon}\"]`) as HTMLImageElement;\n img.style.marginRight = `${position * (KomojuFieldIconElement.ICON_WIDTH + KomojuFieldIconElement.ICON_GAP)}px`;\n position += 1;\n }\n }\n\n // This is for positioning the container element relative to the target input.\n // With this, we can show the icons on the right side of the input without\n // requiring the input to have a specific DOM structure or CSS.\n reposition() {\n const parent = this.parentElement;\n const target = this.target;\n const container = this.shadowRoot?.getElementById('komoju-field-icon');\n if (!target || !parent || !container) return;\n\n container.style.top = `${target.offsetTop}px`;\n container.style.right = `${parent.offsetWidth - target.offsetWidth - target.offsetLeft}px`;\n container.style.height = `${target.offsetHeight}px`;\n\n const targetStyle = window.getComputedStyle(target);\n\n container.style.paddingRight = targetStyle.paddingRight;\n container.style.paddingTop = targetStyle.paddingTop;\n container.style.paddingBottom = targetStyle.paddingBottom;\n\n const icons = this.getAttribute('icon')?.split(/\\s+/) || [];\n this.updateVisibleIcons(icons);\n }\n}\n", "const conversionMap: any = {\n \u30AC: '\uFF76\uFF9E',\n \u30AE: '\uFF77\uFF9E',\n \u30B0: '\uFF78\uFF9E',\n \u30B2: '\uFF79\uFF9E',\n \u30B4: '\uFF7A\uFF9E',\n \u30B6: '\uFF7B\uFF9E',\n \u30B8: '\uFF7C\uFF9E',\n \u30BA: '\uFF7D\uFF9E',\n \u30BC: '\uFF7E\uFF9E',\n \u30BE: '\uFF7F\uFF9E',\n \u30C0: '\uFF80\uFF9E',\n \u30C2: '\uFF81\uFF9E',\n \u30C5: '\uFF82\uFF9E',\n \u30C7: '\uFF83\uFF9E',\n \u30C9: '\uFF84\uFF9E',\n \u30D0: '\uFF8A\uFF9E',\n \u30D3: '\uFF8B\uFF9E',\n \u30D6: '\uFF8C\uFF9E',\n \u30D9: '\uFF8D\uFF9E',\n \u30DC: '\uFF8E\uFF9E',\n \u30D1: '\uFF8A\uFF9F',\n \u30D4: '\uFF8B\uFF9F',\n \u30D7: '\uFF8C\uFF9F',\n \u30DA: '\uFF8D\uFF9F',\n \u30DD: '\uFF8E\uFF9F',\n \u30F4: '\uFF73\uFF9E',\n \u30F7: '\uFF9C\uFF9E',\n \u30FA: '\uFF66\uFF9E',\n \u30A2: '\uFF71',\n \u30A4: '\uFF72',\n \u30A6: '\uFF73',\n \u30A8: '\uFF74',\n \u30AA: '\uFF75',\n \u30AB: '\uFF76',\n \u30AD: '\uFF77',\n \u30AF: '\uFF78',\n \u30B1: '\uFF79',\n \u30B3: '\uFF7A',\n \u30B5: '\uFF7B',\n \u30B7: '\uFF7C',\n \u30B9: '\uFF7D',\n \u30BB: '\uFF7E',\n \u30BD: '\uFF7F',\n \u30BF: '\uFF80',\n \u30C1: '\uFF81',\n \u30C4: '\uFF82',\n \u30C6: '\uFF83',\n \u30C8: '\uFF84',\n \u30CA: '\uFF85',\n \u30CB: '\uFF86',\n \u30CC: '\uFF87',\n \u30CD: '\uFF88',\n \u30CE: '\uFF89',\n \u30CF: '\uFF8A',\n \u30D2: '\uFF8B',\n \u30D5: '\uFF8C',\n \u30D8: '\uFF8D',\n \u30DB: '\uFF8E',\n \u30DE: '\uFF8F',\n \u30DF: '\uFF90',\n \u30E0: '\uFF91',\n \u30E1: '\uFF92',\n \u30E2: '\uFF93',\n \u30E4: '\uFF94',\n \u30E6: '\uFF95',\n \u30E8: '\uFF96',\n \u30E9: '\uFF97',\n \u30EA: '\uFF98',\n \u30EB: '\uFF99',\n \u30EC: '\uFF9A',\n \u30ED: '\uFF9B',\n \u30EF: '\uFF9C',\n \u30F2: '\uFF66',\n \u30F3: '\uFF9D',\n \u30A1: '\uFF67',\n \u30A3: '\uFF68',\n \u30A5: '\uFF69',\n \u30A7: '\uFF6A',\n \u30A9: '\uFF6B',\n \u30C3: '\uFF6F',\n \u30E3: '\uFF6C',\n \u30E5: '\uFF6D',\n \u30E7: '\uFF6E',\n '\u3002': '\uFF61',\n '\u3001': '\uFF64',\n \u30FC: '\uFF70',\n '\u2212': '-',\n '\uFF08': '(',\n '\uFF09': ')',\n '\u300C': '\uFF62',\n '\u300D': '\uFF63',\n '\u30FB': '\uFF65',\n '\u3000': ' ',\n \uFF21: 'A',\n \uFF22: 'B',\n \uFF23: 'C',\n \uFF24: 'D',\n \uFF25: 'E',\n \uFF26: 'F',\n \uFF27: 'G',\n \uFF28: 'H',\n \uFF29: 'I',\n \uFF2A: 'J',\n \uFF2B: 'K',\n \uFF2C: 'L',\n \uFF2D: 'M',\n \uFF2E: 'N',\n \uFF2F: 'O',\n \uFF30: 'P',\n \uFF31: 'Q',\n \uFF32: 'R',\n \uFF33: 'S',\n \uFF34: 'T',\n \uFF35: 'U',\n \uFF36: 'V',\n \uFF37: 'W',\n \uFF38: 'X',\n \uFF39: 'Y',\n \uFF3A: 'Z',\n \uFF41: 'a',\n \uFF42: 'b',\n \uFF43: 'c',\n \uFF44: 'd',\n \uFF45: 'e',\n \uFF46: 'f',\n \uFF47: 'g',\n \uFF48: 'h',\n \uFF49: 'i',\n \uFF4A: 'j',\n \uFF4B: 'k',\n \uFF4C: 'l',\n \uFF4D: 'm',\n \uFF4E: 'n',\n \uFF4F: 'o',\n \uFF50: 'p',\n \uFF51: 'q',\n \uFF52: 'r',\n \uFF53: 's',\n \uFF54: 't',\n \uFF55: 'u',\n \uFF56: 'v',\n \uFF57: 'w',\n \uFF58: 'x',\n \uFF59: 'y',\n \uFF5A: 'z',\n '\uFF10': '0',\n '\uFF11': '1',\n '\uFF12': '2',\n '\uFF13': '3',\n '\uFF14': '4',\n '\uFF15': '5',\n '\uFF16': '6',\n '\uFF17': '7',\n '\uFF18': '8',\n '\uFF19': '9'\n};\n\nexport function convertCharsToHalfWidth(str: string) {\n const convertedChars = str.split('').map(char => {\n return conversionMap[char] ?? char;\n });\n\n return convertedChars.join('');\n}\n\nexport function convertNumbersToHalfWidth(str: string) {\n var fullwidth = '\uFF10\uFF11\uFF12\uFF13\uFF14\uFF15\uFF16\uFF17\uFF18\uFF19\uFF0F';\n var halfwidth = '0123456789/';\n\n for (var i = 0; i < 10; ++i) {\n str = str.replace(\n new RegExp(fullwidth.charAt(i), 'g'),\n halfwidth.charAt(i)\n );\n }\n\n return str;\n}\n", "// Adds validation to an input element.\nexport function addValidation(\n _i18n: Translations, // Used only by typescript to compile-time catch missing translations.\n input: HTMLInputElement,\n callback: (input: HTMLInputElement) => keyof Translations['en'] | null\n) {\n // Add a class so that we know this input has validation.\n input.classList.add('has-validation');\n\n // Tiny detail: if the user has never inputted anything, we don't want to run validations at all\n // at the risk of showing an error message when the user is just clicking around.\n input.addEventListener('input', () => {\n input.dataset.validationDirty = 'true';\n });\n\n // Validation function. This will be called on 'blur' and also on a custom 'validate' event.\n const validate = (event: Event) => {\n const input = event.target as HTMLInputElement;\n\n const errorMessageKey = callback(input);\n\n if (errorMessageKey) {\n showError(_i18n, input, errorMessageKey);\n }\n };\n input.addEventListener('blur', (event) => {\n if (input.dataset.validationDirty !== 'true') return;\n else return validate(event);\n });\n input.addEventListener('validate', validate);\n\n // When the user focuses on the input, remove all error artifacts.\n input.addEventListener('focus', (event) => {\n const input = event.target as HTMLInputElement;\n clearErrors(input);\n });\n}\n\nexport function showError(\n _i18n: Translations, // Used only by typescript to compile-time catch missing translations.\n input: HTMLInputElement,\n messageKey: keyof Translations['en']\n) {\n input.classList.add('invalid');\n const key = messageKey as string;\n\n // We don't want to show the same error twice!\n const container = input.parentElement;\n const dupeSelector = `komoju-error:not(.removing) > komoju-i18n[key=\"${key}\"]`;\n if (container?.querySelector(dupeSelector)) {\n return;\n }\n\n container?.append(createErrorElement(messageKey as string));\n}\n\nexport function clearErrors(input: HTMLInputElement) {\n input.classList.remove('invalid');\n input.parentElement?.querySelectorAll('komoju-error:not(.removing)').forEach((element) => {\n element.remove();\n });\n}\n\n// Runs validations on an element.\nexport function runValidation(input: HTMLInputElement) {\n // Fire the 'validate' custom event.\n input.dispatchEvent(new CustomEvent('validate'));\n\n // If there's an error message, return it.\n const errorMessage = input.parentElement?.querySelector('komoju-error:not(.removing)')?.textContent;\n return errorMessage ?? null;\n}\n\n// Creates the error message element that appears under an invalid input.\n// Mainly just called by addValidation().\nexport function createErrorElement(messageKey: string) {\n const el = window.document.createElement('komoju-error');\n const i18nEl = window.document.createElement('komoju-i18n') as KomojuI18nElement;\n i18nEl.key = messageKey;\n el.appendChild(i18nEl);\n return el;\n}\n", "type CardType = 'visa' | 'mastercard' | 'amex' | 'jcb' | 'jcb15' | 'diner' | 'discover' | 'unionpay' | 'unknown';\n\nexport function cardTypeToKomojuSubtype(type: CardType) {\n if (type === 'amex') return 'american_express';\n if (type === 'diner') return 'diners_club';\n if (type === 'jcb15') return 'jcb';\n if (type === 'mastercard') return 'master';\n return type;\n}\n\nexport function insertSpaceEvery4Characters(str: string) {\n return str.replace(/(.{4})/g, '$1 ').trim();\n}\n\nexport function cardNumberMaxLength(type: CardType) {\n if (type == 'diner') {\n return 16;\n } else if (type == 'amex') {\n return 17;\n } else {\n return 23;\n }\n}\n\nexport function formatCardNumber(value: string, type: CardType) {\n if (\n type == 'unknown' ||\n type == 'visa' ||\n type == 'jcb' ||\n type == 'mastercard'\n ) {\n return insertSpaceEvery4Characters(value);\n } else {\n return value\n .replace(/(.{4})/, '$1 ')\n .replace(/(.{11})/, '$1 ')\n .trim();\n }\n}\n\nexport function removeNonDigits(value: string) {\n return value.replace(/[^0-9( \\/ )]+/g, '');\n}\n\n// insert \"/\" after the first 2 digits, if applicable\nexport function insertSlash(value: string) {\n const hasSlash = value.includes('/');\n const hasFullMonth = value.length >= 2;\n\n if (hasFullMonth && !hasSlash) {\n let yearStart = value.lastIndexOf(' ');\n if (yearStart === -1) yearStart = 2;\n\n const month = value.slice(0, 2);\n const year = value.slice(yearStart, value.length);\n\n return `${month} / ${year}`;\n }\n\n return value;\n}\n\n// remove \"/\" after the first 2 digits, if applicable\nexport function removeSlash(value: string) {\n return value.endsWith('/') ? value.replace(/[^0-9]+/g, '') : value;\n}\n\nexport const cardTypeRegex = {\n amex: /^3[47]\\d{0,13}/,\n diner: /^3(?:0([0-5]|9)|[689]\\d?)\\d{0,11}/,\n mastercard: /^(5[1-5]\\d{0,2}|22[2-9]\\d{0,1}|2[3-7]\\d{0,2})\\d{0,12}/,\n jcb15: /^(?:2131|1800)\\d{0,11}/,\n jcb: /^(?:35)\\d{0,17}/,\n visa: /^4\\d{0,18}/\n};\n\nexport function cardType(value: string): CardType {\n if (cardTypeRegex.amex.exec(value)) {\n return 'amex';\n } else if (cardTypeRegex.diner.exec(value)) {\n return 'diner';\n } else if (cardTypeRegex.mastercard.exec(value)) {\n return 'mastercard';\n } else if (cardTypeRegex.jcb15.exec(value)) {\n return 'jcb15';\n } else if (cardTypeRegex.jcb.exec(value)) {\n return 'jcb';\n } else if (cardTypeRegex.visa.exec(value)) {\n return 'visa';\n } else {\n return 'unknown';\n }\n}\n\nexport function luhnCheck(cardNumber: string) {\n // accept only digits and spaces\n if (/[^0-9\\s]+/.test(cardNumber)) {\n return false;\n }\n\n let sum = 0;\n let shouldDouble = false;\n cardNumber = cardNumber.replace(/\\D/g, '');\n const length = cardNumber.length;\n\n // iterating backwards, double every second digit\n for (let i = length - 1; i >= 0; --i) {\n let digit = parseInt(cardNumber.charAt(i), 10);\n\n // double. if doubled digit is > 9, subtract 9\n if (shouldDouble && (digit *= 2) > 9) {\n digit -= 9;\n }\n\n sum += digit;\n shouldDouble = !shouldDouble;\n }\n\n return sum % 10 === 0;\n}\n", "declare let window: WindowWithKomojuGlobals;\n\n// Call this to add messages to the registry.\n// Individual payment method modules can do this to add their own messages.\n// That way, we avoid needing to load all messages for every payment method upfront.\nexport function registerMessages(messages: I18n) {\n if (!window.komojuTranslations) {\n window.komojuTranslations = { 'en': {}, 'ja': {} };\n }\n\n for (const lang of Object.keys(window.komojuTranslations)) {\n window.komojuTranslations[lang] = {\n ...window.komojuTranslations[lang],\n ...messages[lang],\n };\n }\n}\n", "export const en = {\n 'cc.label.cardholder-name': 'Cardholder name',\n 'cc.label.card-number': 'Card number',\n 'cc.label.expiration': 'Expiration',\n 'cc.label.cvc': 'CVC',\n 'cc.error.required': 'Required',\n 'cc.error.incomplete': 'Please input the full expiration date',\n 'cc.error.please_use_half_width': 'Please use half-width characters',\n 'cc.error.invalid-number': 'Invalid number',\n 'cc.error.expired': 'Card is expired',\n 'cc.error.invalid-month': 'Month must be between 1 and 12',\n 'cc.error.unsupported-brand': 'Unsupported card brand',\n};\n\nexport const ja: typeof en = {\n 'cc.label.cardholder-name': '\u30AB\u30FC\u30C9\u6240\u6709\u8005\u540D',\n 'cc.label.card-number': '\u30AB\u30FC\u30C9\u756A\u53F7',\n 'cc.label.expiration': '\u6709\u52B9\u671F\u9650',\n 'cc.label.cvc': '\u30BB\u30AD\u30E5\u30EA\u30C6\u30A3\u30B3\u30FC\u30C9',\n 'cc.error.required': '\u5FC5\u9808\u9805\u76EE\u3067\u3059',\n 'cc.error.incomplete': '\u6709\u52B9\u671F\u9650\u3092\u6B63\u3057\u304F\u5165\u529B\u3057\u3066\u304F\u3060\u3055\u3044',\n 'cc.error.please_use_half_width': '\u534A\u89D2\u82F1\u6570\u5B57\u30FB\u8A18\u53F7\u306E\u307F\u6709\u52B9\u3067\u3059',\n 'cc.error.invalid-number': '\u30AB\u30FC\u30C9\u756A\u53F7\u304C\u6B63\u3057\u304F\u3042\u308A\u307E\u305B\u3093',\n 'cc.error.expired': '\u30AB\u30FC\u30C9\u306E\u6709\u52B9\u671F\u9650\u304C\u5207\u308C\u3066\u3044\u307E\u3059',\n 'cc.error.invalid-month': '\u6708\u306F1\u304B\u308912\u306E\u9593\u3067\u5165\u529B\u3057\u3066\u304F\u3060\u3055\u3044',\n 'cc.error.unsupported-brand': '\u5BFE\u5FDC\u3057\u3066\u3044\u306A\u3044\u30AF\u30EC\u30B8\u30C3\u30C8\u30AB\u30FC\u30C9\u30D6\u30E9\u30F3\u30C9\u3067\u3059',\n}\n", "import '../../types.d';\nimport KomojuFieldIconElement from './komoju-field-icon-element';\n// @ts-ignore\nimport html from './template.html'\nimport { convertNumbersToHalfWidth } from '../../shared/char-width-utils';\nimport { addValidation, showError, clearErrors } from '../../shared/validation';\nimport {\n cardType,\n formatCardNumber,\n removeNonDigits,\n insertSlash,\n removeSlash,\n cardNumberMaxLength,\n cardTypeToKomojuSubtype,\n luhnCheck,\n} from './card-number-utils';\n\nimport { registerMessages } from '../../shared/translations';\nimport * as i18n from './i18n';\nregisterMessages(i18n);\n\nwindow.customElements.define('komoju-field-icon', KomojuFieldIconElement);\n\nexport const render: KomojuRenderFunction = (root, paymentMethod) => {\n root.innerHTML = html;\n initializeInputs(\n root as KomojuFieldsConfig,\n paymentMethod as KomojuCreditCardPaymentMethod,\n );\n}\n\nfunction initializeInputs(\n root: KomojuFieldsConfig,\n paymentMethod: KomojuCreditCardPaymentMethod,\n) {\n // Card holder name validation: just make sure it's not empty\n const name = document.getElementById('cc-name')! as HTMLInputElement;\n addValidation(i18n, name, (input) => {\n if (input.value === '') return 'cc.error.required';\n if (/[^\\x01-\\x7E]/.test(input.value)) return 'cc.error.please_use_half_width';\n return null;\n });\n\n // Card number icon\n const cardIcon = document.getElementById('cc-icon')! as KomojuFieldIconElement;\n const defaultCardImage = `${root.komojuCdn}/static/credit_card_number.svg`;\n const supportedBrandImages = paymentMethod.brands.map((brand) => {\n return `https://komoju.com/payment_methods/credit_card.svg?brands=${brand}`;\n }).join(' ');\n cardIcon.icon = supportedBrandImages;\n\n // Card number format: 1234 5678 9012 3456 (sometimes more or less digits)\n const number = document.getElementById('cc-number')! as HTMLInputElement;\n number.addEventListener('input', (event) => {\n const input = event.target as HTMLInputElement;\n if (input.dataset.ime === 'active') return;\n let value = input.value;\n\n value = convertNumbersToHalfWidth(value).replace(/\\D/g, '');\n if (value.length === 0) {\n clearErrors(input);\n }\n\n const type = cardType(value);\n\n input.maxLength = cardNumberMaxLength(type);\n input.value = formatCardNumber(value, type);\n input.dataset.brand = type;\n\n // Update the card icons based on detected brand\n const brand = cardTypeToKomojuSubtype(type);\n if (type === 'unknown') {\n // Most brands are identifiable after 3 characters\n // Also show default if brand is unsupported\n if (value.length < 3) {\n cardIcon.icon = supportedBrandImages;\n } else {\n cardIcon.icon = defaultCardImage;\n }\n }\n else if (paymentMethod.brands.includes(brand)) {\n cardIcon.icon = `https://komoju.com/payment_methods/credit_card.svg?brands=${brand}`;\n clearErrors(input);\n }\n else {\n cardIcon.icon = supportedBrandImages;\n showError(i18n, input, 'cc.error.unsupported-brand');\n }\n });\n\n // Card number validation: luhn check and brand support\n addValidation(i18n, number, (input) => {\n const value = input.value.replace(/\\D/g, '');\n if (value === '') return 'cc.error.required';\n if (!luhnCheck(value)) return 'cc.error.invalid-number';\n\n const type = cardType(value);\n const brand = cardTypeToKomojuSubtype(type);\n if (type === 'unknown') return 'cc.error.unsupported-brand';\n if (!paymentMethod.brands.includes(brand)) return 'cc.error.unsupported-brand';\n\n return null;\n });\n\n // Expiration date\n const exp = document.getElementById('cc-exp')! as HTMLInputElement;\n let lastExpValue = exp.value;\n\n // Format: MM / YY. We automatically insert and remove the slash.\n exp.addEventListener('input', (event) => {\n const input = event.target as HTMLInputElement;\n\n if (input.dataset.ime === 'active') return;\n\n let value = convertNumbersToHalfWidth(input.value);\n const addedNewCharacter = value.length > lastExpValue.length;\n\n // Format value\n value = removeNonDigits(value);\n value = addedNewCharacter ? insertSlash(value) : removeSlash(value);\n\n // Update value and store as last input\n input.value = value;\n lastExpValue = value;\n });\n\n // Format: MM / YY to for IME devices.\n exp.addEventListener('blur', (event) => {\n const input = event.target as HTMLInputElement;\n\n if (input.dataset.ime === 'inactive') {\n let value = convertNumbersToHalfWidth(input.value);\n\n // Format value\n value = removeNonDigits(value);\n value = insertSlash(value);\n\n // Update value and store as last input\n input.value = value;\n lastExpValue = value;\n }\n });\n\n // Expiration validation: format and date\n addValidation(i18n, exp, (input) => {\n const mmyy = input.value.replace(/[^0-9\\/]/g, '');\n const [month, year] = mmyy.split('/');\n\n // Complain about incomplete expiration\n if (\n month == null ||\n year == null ||\n year.length !== 2 ||\n month.length !== 2 ||\n !/^\\d{2}\\/\\d{2}$/.test(mmyy)\n ) {\n return 'cc.error.incomplete';\n }\n\n const now = new Date();\n const currentYear = parseInt(\n now\n .getFullYear()\n .toString()\n .substr(2, 2)\n );\n const currentMonth = now.getMonth() + 1;\n const monthNum = parseInt(month);\n const yearNum = parseInt(year);\n\n // Complain if year is in the past\n if (yearNum < currentYear) {\n return 'cc.error.expired';\n }\n\n // Complain if month is in the past\n if (yearNum === currentYear && monthNum < currentMonth) {\n return 'cc.error.expired';\n }\n\n // Complain if month is past December\n if (monthNum > 12 || monthNum <= 0) {\n return 'cc.error.invalid-month';\n }\n\n return null;\n });\n\n // CVC\n // Here we just want to set the helper image.\n const cvcIcon = document.getElementById('cc-cvc-icon')! as KomojuFieldIconElement;\n cvcIcon.icon = `${root.komojuCdn}/static/credit_card_cvc.svg`;\n\n // CVC validation: just make sure it's not empty\n const cvc = document.getElementById('cc-cvc')! as HTMLInputElement;\n addValidation(i18n, cvc, (input) => {\n if (input.value === '') return 'cc.error.required';\n return null;\n });\n}\n\nexport const paymentDetails: KomojuPaymentDetailsFunction = (root, _paymentMethod) => {\n const name = root.querySelector('#cc-name') as HTMLInputElement;\n const number = root.querySelector('#cc-number') as HTMLInputElement;\n const expiration = root.querySelector('#cc-exp') as HTMLInputElement;\n const cvc = root.querySelector('#cc-cvc') as HTMLInputElement;\n\n const [month, year] = expiration.value.split('/').map(s => s.trim());\n\n return {\n type: 'credit_card',\n name: name.value,\n number: number.value.replace(/\\s+/g, ''),\n month, year,\n verification_value: cvc.value,\n }\n}"], - "mappings": "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", - "names": ["input"] -} diff --git a/src/app/code/Komoju/Payments/view/frontend/web/js/fields/konbini/module.js b/src/app/code/Komoju/Payments/view/frontend/web/js/fields/konbini/module.js deleted file mode 100644 index eda0df48d..000000000 --- a/src/app/code/Komoju/Payments/view/frontend/web/js/fields/konbini/module.js +++ /dev/null @@ -1,164 +0,0 @@ -var __defProp = Object.defineProperty; -var __export = (target, all) => { - for (var name in all) - __defProp(target, name, { get: all[name], enumerable: true }); -}; - -// src/fields/konbini/template.html -var template_default = '
\n \n\n \n\n \n
\n\n
    \n
\n\n\n\n\n'; - -// src/shared/validation.ts -function addValidation(_i18n, input, callback) { - input.classList.add("has-validation"); - input.addEventListener("input", () => { - input.dataset.validationDirty = "true"; - }); - const validate = (event) => { - const input2 = event.target; - const errorMessageKey = callback(input2); - if (errorMessageKey) { - showError(_i18n, input2, errorMessageKey); - } - }; - input.addEventListener("blur", (event) => { - if (input.dataset.validationDirty !== "true") - return; - else - return validate(event); - }); - input.addEventListener("validate", validate); - input.addEventListener("focus", (event) => { - const input2 = event.target; - clearErrors(input2); - }); -} -function showError(_i18n, input, messageKey) { - input.classList.add("invalid"); - const key = messageKey; - const container = input.parentElement; - const dupeSelector = `komoju-error:not(.removing) > komoju-i18n[key="${key}"]`; - if (container?.querySelector(dupeSelector)) { - return; - } - container?.append(createErrorElement(messageKey)); -} -function clearErrors(input) { - input.classList.remove("invalid"); - input.parentElement?.querySelectorAll("komoju-error:not(.removing)").forEach((element) => { - element.remove(); - }); -} -function createErrorElement(messageKey) { - const el = window.document.createElement("komoju-error"); - const i18nEl = window.document.createElement("komoju-i18n"); - i18nEl.key = messageKey; - el.appendChild(i18nEl); - return el; -} - -// src/shared/radio-helpers.ts -function setupRadioParentCheckedClass(input, root) { - if (!input.parentElement) { - throw new Error("KOMOJU Fields bug: radio input has no parent"); - } - if (!input.parentElement.classList.contains("radio")) { - throw new Error("KOMOJU Fields bug: radio input parent has no .radio class"); - } - if (input.checked) { - input.parentElement.classList.add("checked"); - } - input.addEventListener("change", () => { - root.querySelectorAll(".radio.checked").forEach((el) => el.classList.remove("checked")); - input.parentElement.classList.add("checked"); - }); -} - -// src/shared/translations.ts -function registerMessages(messages) { - if (!window.komojuTranslations) { - window.komojuTranslations = { "en": {}, "ja": {} }; - } - for (const lang of Object.keys(window.komojuTranslations)) { - window.komojuTranslations[lang] = { - ...window.komojuTranslations[lang], - ...messages[lang] - }; - } -} - -// src/fields/konbini/i18n.ts -var i18n_exports = {}; -__export(i18n_exports, { - en: () => en, - ja: () => ja -}); -var en = { - "kb.label.name": "Name (shown on receipt)", - "kb.label.email": "Email address", - "kb.error.required": "Required", - "kb.store.daily-yamazaki": "Daily Yamazaki", - "kb.store.family-mart": "FamilyMart", - "kb.store.lawson": "Lawson", - "kb.store.ministop": "Ministop", - "kb.store.seicomart": "Seicomart", - "kb.store.seven-eleven": "Seven Eleven" -}; -var ja = { - "kb.label.name": "\u6C0F\u540D\uFF08\u30EC\u30B7\u30FC\u30C8\u3067\u8868\u793A\u3055\u308C\u307E\u3059\uFF09", - "kb.label.email": "\u30E1\u30FC\u30EB\u30A2\u30C9\u30EC\u30B9", - "kb.error.required": "\u5FC5\u9808\u9805\u76EE\u3067\u3059", - "kb.store.daily-yamazaki": "\u30C7\u30A4\u30EA\u30FC\u30E4\u30DE\u30B6\u30AD", - "kb.store.family-mart": "\u30D5\u30A1\u30DF\u30EA\u30FC\u30DE\u30FC\u30C8", - "kb.store.lawson": "\u30ED\u30FC\u30BD\u30F3", - "kb.store.ministop": "\u30DF\u30CB\u30B9\u30C8\u30C3\u30D7", - "kb.store.seicomart": "\u30BB\u30A4\u30B3\u30FC\u30DE\u30FC\u30C8", - "kb.store.seven-eleven": "\u30BB\u30D6\u30F3\u30A4\u30EC\u30D6\u30F3" -}; - -// src/fields/konbini/module.ts -registerMessages(i18n_exports); -var render = (root, paymentMethod) => { - root.innerHTML = template_default; - initializeInputs(root, paymentMethod); -}; -var paymentDetails = (root, _paymentMethod) => { - const name = root.querySelector("#kb-name"); - const email = root.querySelector("#kb-email"); - const store = root.querySelector('input[name="kb-store"]:checked'); - return { - type: "konbini", - store: store.value, - email: email.value, - name: name.value - }; -}; -function initializeInputs(root, paymentMethod) { - const radioTemplate = root.querySelector("#konbini-radio"); - const email = root.querySelector("#kb-email"); - let checked = false; - for (const brand in paymentMethod.brands) { - const element = radioTemplate.content.cloneNode(true); - const input = element.querySelector("input"); - const image = element.querySelector("img"); - const label = element.querySelector("komoju-i18n"); - input.value = brand; - if (!checked) { - input.checked = true; - checked = true; - } - setupRadioParentCheckedClass(input, root); - image.src = `${root.komojuApi}${paymentMethod.brands[brand].icon}`; - label.key = `kb.store.${brand}`; - radioTemplate.parentElement.appendChild(element); - } - addValidation(i18n_exports, email, (input) => { - if (input.value === "") - return "kb.error.required"; - return null; - }); -} -export { - paymentDetails, - render -}; -//# sourceMappingURL=module.js.map diff --git a/src/app/code/Komoju/Payments/view/frontend/web/js/fields/konbini/module.js.map b/src/app/code/Komoju/Payments/view/frontend/web/js/fields/konbini/module.js.map deleted file mode 100644 index ee8b607c2..000000000 --- a/src/app/code/Komoju/Payments/view/frontend/web/js/fields/konbini/module.js.map +++ /dev/null @@ -1,7 +0,0 @@ -{ - "version": 3, - "sources": ["../../../src/shared/validation.ts", "../../../src/shared/radio-helpers.ts", "../../../src/shared/translations.ts", "../../../src/fields/konbini/i18n.ts", "../../../src/fields/konbini/module.ts"], - "sourcesContent": ["// Adds validation to an input element.\nexport function addValidation(\n _i18n: Translations, // Used only by typescript to compile-time catch missing translations.\n input: HTMLInputElement,\n callback: (input: HTMLInputElement) => keyof Translations['en'] | null\n) {\n // Add a class so that we know this input has validation.\n input.classList.add('has-validation');\n\n // Tiny detail: if the user has never inputted anything, we don't want to run validations at all\n // at the risk of showing an error message when the user is just clicking around.\n input.addEventListener('input', () => {\n input.dataset.validationDirty = 'true';\n });\n\n // Validation function. This will be called on 'blur' and also on a custom 'validate' event.\n const validate = (event: Event) => {\n const input = event.target as HTMLInputElement;\n\n const errorMessageKey = callback(input);\n\n if (errorMessageKey) {\n showError(_i18n, input, errorMessageKey);\n }\n };\n input.addEventListener('blur', (event) => {\n if (input.dataset.validationDirty !== 'true') return;\n else return validate(event);\n });\n input.addEventListener('validate', validate);\n\n // When the user focuses on the input, remove all error artifacts.\n input.addEventListener('focus', (event) => {\n const input = event.target as HTMLInputElement;\n clearErrors(input);\n });\n}\n\nexport function showError(\n _i18n: Translations, // Used only by typescript to compile-time catch missing translations.\n input: HTMLInputElement,\n messageKey: keyof Translations['en']\n) {\n input.classList.add('invalid');\n const key = messageKey as string;\n\n // We don't want to show the same error twice!\n const container = input.parentElement;\n const dupeSelector = `komoju-error:not(.removing) > komoju-i18n[key=\"${key}\"]`;\n if (container?.querySelector(dupeSelector)) {\n return;\n }\n\n container?.append(createErrorElement(messageKey as string));\n}\n\nexport function clearErrors(input: HTMLInputElement) {\n input.classList.remove('invalid');\n input.parentElement?.querySelectorAll('komoju-error:not(.removing)').forEach((element) => {\n element.remove();\n });\n}\n\n// Runs validations on an element.\nexport function runValidation(input: HTMLInputElement) {\n // Fire the 'validate' custom event.\n input.dispatchEvent(new CustomEvent('validate'));\n\n // If there's an error message, return it.\n const errorMessage = input.parentElement?.querySelector('komoju-error:not(.removing)')?.textContent;\n return errorMessage ?? null;\n}\n\n// Creates the error message element that appears under an invalid input.\n// Mainly just called by addValidation().\nexport function createErrorElement(messageKey: string) {\n const el = window.document.createElement('komoju-error');\n const i18nEl = window.document.createElement('komoju-i18n') as KomojuI18nElement;\n i18nEl.key = messageKey;\n el.appendChild(i18nEl);\n return el;\n}\n", "interface QuerySelectorAll {\n querySelectorAll: HTMLElement['querySelectorAll']\n}\n\n// Add .checked to the parent .radio element when the input is checked.\n// This is just to make the CSS a little easier, since we're putting the\n// input inside of the label.\nexport function setupRadioParentCheckedClass(input: HTMLInputElement, root: QuerySelectorAll) {\n // Some sanity checks\n if (!input.parentElement) {\n throw new Error('KOMOJU Fields bug: radio input has no parent');\n }\n if (!input.parentElement.classList.contains('radio')) {\n throw new Error('KOMOJU Fields bug: radio input parent has no .radio class');\n }\n\n // Initialize the checked class\n if (input.checked) {\n input.parentElement.classList.add('checked');\n }\n\n // Set checked class then checked\n input.addEventListener('change', () => {\n root.querySelectorAll('.radio.checked').forEach((el) => el.classList.remove('checked'));\n input.parentElement!.classList.add('checked');\n });\n}\n", "declare let window: WindowWithKomojuGlobals;\n\n// Call this to add messages to the registry.\n// Individual payment method modules can do this to add their own messages.\n// That way, we avoid needing to load all messages for every payment method upfront.\nexport function registerMessages(messages: I18n) {\n if (!window.komojuTranslations) {\n window.komojuTranslations = { 'en': {}, 'ja': {} };\n }\n\n for (const lang of Object.keys(window.komojuTranslations)) {\n window.komojuTranslations[lang] = {\n ...window.komojuTranslations[lang],\n ...messages[lang],\n };\n }\n}\n", "export const en = {\n 'kb.label.name': 'Name (shown on receipt)',\n 'kb.label.email': 'Email address',\n 'kb.error.required': 'Required',\n 'kb.store.daily-yamazaki': 'Daily Yamazaki',\n 'kb.store.family-mart': 'FamilyMart',\n 'kb.store.lawson': 'Lawson',\n 'kb.store.ministop': 'Ministop',\n 'kb.store.seicomart': 'Seicomart',\n 'kb.store.seven-eleven': 'Seven Eleven',\n};\n\nexport const ja: typeof en = {\n 'kb.label.name': '\u6C0F\u540D\uFF08\u30EC\u30B7\u30FC\u30C8\u3067\u8868\u793A\u3055\u308C\u307E\u3059\uFF09',\n 'kb.label.email': '\u30E1\u30FC\u30EB\u30A2\u30C9\u30EC\u30B9',\n 'kb.error.required': '\u5FC5\u9808\u9805\u76EE\u3067\u3059',\n 'kb.store.daily-yamazaki': '\u30C7\u30A4\u30EA\u30FC\u30E4\u30DE\u30B6\u30AD',\n 'kb.store.family-mart': '\u30D5\u30A1\u30DF\u30EA\u30FC\u30DE\u30FC\u30C8',\n 'kb.store.lawson': '\u30ED\u30FC\u30BD\u30F3',\n 'kb.store.ministop': '\u30DF\u30CB\u30B9\u30C8\u30C3\u30D7',\n 'kb.store.seicomart': '\u30BB\u30A4\u30B3\u30FC\u30DE\u30FC\u30C8',\n 'kb.store.seven-eleven': '\u30BB\u30D6\u30F3\u30A4\u30EC\u30D6\u30F3',\n};\n", "import '../../types.d';\n// @ts-ignore\nimport html from './template.html'\nimport { addValidation } from '../../shared/validation';\nimport { setupRadioParentCheckedClass } from '../../shared/radio-helpers';\n\nimport { registerMessages } from '../../shared/translations';\nimport * as i18n from './i18n';\nregisterMessages(i18n);\n\nexport const render: KomojuRenderFunction = (root, paymentMethod) => {\n root.innerHTML = html;\n initializeInputs(root as KomojuFieldsConfig, paymentMethod as KomojuKonbiniPaymentMethod);\n}\n\nexport const paymentDetails: KomojuPaymentDetailsFunction = (root, _paymentMethod) => {\n const name = root.querySelector('#kb-name')! as HTMLInputElement;\n const email = root.querySelector('#kb-email')! as HTMLInputElement;\n const store = root.querySelector('input[name=\"kb-store\"]:checked')! as HTMLInputElement;\n\n return {\n type: 'konbini',\n store: store.value,\n email: email.value,\n name: name.value,\n }\n}\n\nfunction initializeInputs(\n root: KomojuFieldsConfig,\n paymentMethod: KomojuKonbiniPaymentMethod\n) {\n const radioTemplate = root.querySelector('#konbini-radio')! as HTMLTemplateElement;\n const email = root.querySelector('#kb-email')! as HTMLInputElement;\n \n let checked = false;\n for (const brand in paymentMethod.brands) {\n const element = radioTemplate.content.cloneNode(true) as HTMLElement;\n const input = element.querySelector('input') as HTMLInputElement;\n const image = element.querySelector('img') as HTMLImageElement;\n const label = element.querySelector('komoju-i18n') as KomojuI18nElement;\n\n input.value = brand;\n if (!checked) {\n input.checked = true;\n checked = true;\n }\n setupRadioParentCheckedClass(input, root);\n\n image.src = `${root.komojuApi}${paymentMethod.brands[brand].icon}`;\n label.key = `kb.store.${brand}`;\n\n radioTemplate.parentElement!.appendChild(element);\n }\n\n addValidation(i18n, email, (input) => {\n if (input.value === '') return 'kb.error.required';\n return null;\n });\n}\n"], - "mappings": "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", - "names": ["input"] -} diff --git a/src/app/code/Komoju/Payments/view/frontend/web/js/fields/offsite/module.js b/src/app/code/Komoju/Payments/view/frontend/web/js/fields/offsite/module.js deleted file mode 100644 index 559f5ea78..000000000 --- a/src/app/code/Komoju/Payments/view/frontend/web/js/fields/offsite/module.js +++ /dev/null @@ -1,131 +0,0 @@ -var __defProp = Object.defineProperty; -var __export = (target, all) => { - for (var name in all) - __defProp(target, name, { get: all[name], enumerable: true }); -}; - -// src/fields/offsite/template.html -var template_default = '
\n \n
\n\n
    \n
\n\n\n'; - -// src/shared/validation.ts -function addValidation(_i18n, input, callback) { - input.classList.add("has-validation"); - input.addEventListener("input", () => { - input.dataset.validationDirty = "true"; - }); - const validate = (event) => { - const input2 = event.target; - const errorMessageKey = callback(input2); - if (errorMessageKey) { - showError(_i18n, input2, errorMessageKey); - } - }; - input.addEventListener("blur", (event) => { - if (input.dataset.validationDirty !== "true") - return; - else - return validate(event); - }); - input.addEventListener("validate", validate); - input.addEventListener("focus", (event) => { - const input2 = event.target; - clearErrors(input2); - }); -} -function showError(_i18n, input, messageKey) { - input.classList.add("invalid"); - const key = messageKey; - const container = input.parentElement; - const dupeSelector = `komoju-error:not(.removing) > komoju-i18n[key="${key}"]`; - if (container?.querySelector(dupeSelector)) { - return; - } - container?.append(createErrorElement(messageKey)); -} -function clearErrors(input) { - input.classList.remove("invalid"); - input.parentElement?.querySelectorAll("komoju-error:not(.removing)").forEach((element) => { - element.remove(); - }); -} -function createErrorElement(messageKey) { - const el = window.document.createElement("komoju-error"); - const i18nEl = window.document.createElement("komoju-i18n"); - i18nEl.key = messageKey; - el.appendChild(i18nEl); - return el; -} - -// src/shared/translations.ts -function registerMessages(messages) { - if (!window.komojuTranslations) { - window.komojuTranslations = { "en": {}, "ja": {} }; - } - for (const lang of Object.keys(window.komojuTranslations)) { - window.komojuTranslations[lang] = { - ...window.komojuTranslations[lang], - ...messages[lang] - }; - } -} - -// src/fields/offsite/i18n.ts -var i18n_exports = {}; -__export(i18n_exports, { - en: () => en, - ja: () => ja -}); -var en = { - "os.label.name": "Customer name", - "os.label.email": "Email address", - "os.label.phone": "Phone number", - "os.error.required": "Required" -}; -var ja = { - "os.label.name": "\u304A\u540D\u524D", - "os.label.email": "\u30E1\u30FC\u30EB\u30A2\u30C9\u30EC\u30B9", - "os.label.phone": "\u96FB\u8A71\u756A\u53F7", - "os.error.required": "\u5FC5\u9808\u9805\u76EE\u3067\u3059" -}; - -// src/fields/offsite/module.ts -registerMessages(i18n_exports); -var render = (root, paymentMethod) => { - root.innerHTML = template_default; - root.querySelectorAll(".fields").forEach((element) => { - element.classList.add(paymentMethod.type); - }); - const fieldTemplate = root.querySelector("#additional-field"); - for (const field of paymentMethod.additional_fields ?? []) { - const element = fieldTemplate.content.cloneNode(true); - const input = element.querySelector("input"); - const text = element.querySelector("komoju-i18n"); - if (field === "email") - input.type = "email"; - else if (field === "phone") - input.type = "tel"; - input.id = `offsite-${field}`; - text.key = `os.label.${field}`; - fieldTemplate.parentElement.appendChild(element); - addValidation(i18n_exports, input, (input2) => { - if (input2.value === "") - return "os.error.required"; - return null; - }); - } -}; -var paymentDetails = (root, paymentMethod) => { - const result = { - type: paymentMethod.type - }; - for (const field of paymentMethod.additional_fields ?? []) { - const input = root.querySelector(`#offsite-${field}`); - result[field] = input.value; - } - return result; -}; -export { - paymentDetails, - render -}; -//# sourceMappingURL=module.js.map diff --git a/src/app/code/Komoju/Payments/view/frontend/web/js/fields/offsite/module.js.map b/src/app/code/Komoju/Payments/view/frontend/web/js/fields/offsite/module.js.map deleted file mode 100644 index b64f9cc46..000000000 --- a/src/app/code/Komoju/Payments/view/frontend/web/js/fields/offsite/module.js.map +++ /dev/null @@ -1,7 +0,0 @@ -{ - "version": 3, - "sources": ["../../../src/shared/validation.ts", "../../../src/shared/translations.ts", "../../../src/fields/offsite/i18n.ts", "../../../src/fields/offsite/module.ts"], - "sourcesContent": ["// Adds validation to an input element.\nexport function addValidation(\n _i18n: Translations, // Used only by typescript to compile-time catch missing translations.\n input: HTMLInputElement,\n callback: (input: HTMLInputElement) => keyof Translations['en'] | null\n) {\n // Add a class so that we know this input has validation.\n input.classList.add('has-validation');\n\n // Tiny detail: if the user has never inputted anything, we don't want to run validations at all\n // at the risk of showing an error message when the user is just clicking around.\n input.addEventListener('input', () => {\n input.dataset.validationDirty = 'true';\n });\n\n // Validation function. This will be called on 'blur' and also on a custom 'validate' event.\n const validate = (event: Event) => {\n const input = event.target as HTMLInputElement;\n\n const errorMessageKey = callback(input);\n\n if (errorMessageKey) {\n showError(_i18n, input, errorMessageKey);\n }\n };\n input.addEventListener('blur', (event) => {\n if (input.dataset.validationDirty !== 'true') return;\n else return validate(event);\n });\n input.addEventListener('validate', validate);\n\n // When the user focuses on the input, remove all error artifacts.\n input.addEventListener('focus', (event) => {\n const input = event.target as HTMLInputElement;\n clearErrors(input);\n });\n}\n\nexport function showError(\n _i18n: Translations, // Used only by typescript to compile-time catch missing translations.\n input: HTMLInputElement,\n messageKey: keyof Translations['en']\n) {\n input.classList.add('invalid');\n const key = messageKey as string;\n\n // We don't want to show the same error twice!\n const container = input.parentElement;\n const dupeSelector = `komoju-error:not(.removing) > komoju-i18n[key=\"${key}\"]`;\n if (container?.querySelector(dupeSelector)) {\n return;\n }\n\n container?.append(createErrorElement(messageKey as string));\n}\n\nexport function clearErrors(input: HTMLInputElement) {\n input.classList.remove('invalid');\n input.parentElement?.querySelectorAll('komoju-error:not(.removing)').forEach((element) => {\n element.remove();\n });\n}\n\n// Runs validations on an element.\nexport function runValidation(input: HTMLInputElement) {\n // Fire the 'validate' custom event.\n input.dispatchEvent(new CustomEvent('validate'));\n\n // If there's an error message, return it.\n const errorMessage = input.parentElement?.querySelector('komoju-error:not(.removing)')?.textContent;\n return errorMessage ?? null;\n}\n\n// Creates the error message element that appears under an invalid input.\n// Mainly just called by addValidation().\nexport function createErrorElement(messageKey: string) {\n const el = window.document.createElement('komoju-error');\n const i18nEl = window.document.createElement('komoju-i18n') as KomojuI18nElement;\n i18nEl.key = messageKey;\n el.appendChild(i18nEl);\n return el;\n}\n", "declare let window: WindowWithKomojuGlobals;\n\n// Call this to add messages to the registry.\n// Individual payment method modules can do this to add their own messages.\n// That way, we avoid needing to load all messages for every payment method upfront.\nexport function registerMessages(messages: I18n) {\n if (!window.komojuTranslations) {\n window.komojuTranslations = { 'en': {}, 'ja': {} };\n }\n\n for (const lang of Object.keys(window.komojuTranslations)) {\n window.komojuTranslations[lang] = {\n ...window.komojuTranslations[lang],\n ...messages[lang],\n };\n }\n}\n", "export const en = {\n 'os.label.name': 'Customer name',\n 'os.label.email': 'Email address',\n 'os.label.phone': 'Phone number',\n 'os.error.required': 'Required',\n};\n\nexport const ja: typeof en = {\n 'os.label.name': '\u304A\u540D\u524D',\n 'os.label.email': '\u30E1\u30FC\u30EB\u30A2\u30C9\u30EC\u30B9',\n 'os.label.phone': '\u96FB\u8A71\u756A\u53F7',\n 'os.error.required': '\u5FC5\u9808\u9805\u76EE\u3067\u3059',\n};\n", "import '../../types.d';\n// @ts-ignore\nimport html from './template.html';\nimport { addValidation } from '../../shared/validation';\n\nimport { registerMessages } from '../../shared/translations';\nimport * as i18n from './i18n';\nregisterMessages(i18n);\n\nexport const render: KomojuRenderFunction = (root, paymentMethod) => {\n root.innerHTML = html;\n\n root.querySelectorAll('.fields').forEach((element) => {\n element.classList.add(paymentMethod.type);\n });\n\n const fieldTemplate = root.querySelector('#additional-field')! as HTMLTemplateElement;\n for (const field of paymentMethod.additional_fields ?? []) {\n const element = fieldTemplate.content.cloneNode(true) as HTMLElement;\n const input = element.querySelector('input') as HTMLInputElement;\n const text = element.querySelector('komoju-i18n') as KomojuI18nElement;\n\n if (field === 'email') input.type = 'email';\n else if (field === 'phone') input.type = 'tel';\n input.id = `offsite-${field}`;\n\n text.key = `os.label.${field}`;\n\n fieldTemplate.parentElement!.appendChild(element);\n\n addValidation(i18n, input, (input) => {\n if (input.value === '') return 'os.error.required';\n return null;\n });\n }\n}\n\nexport const paymentDetails: KomojuPaymentDetailsFunction = (root, paymentMethod) => {\n const result: any = {\n type: paymentMethod.type,\n };\n\n for (const field of paymentMethod.additional_fields ?? []) {\n const input = root.querySelector(`#offsite-${field}`)! as HTMLInputElement;\n result[field] = input.value;\n }\n\n return result;\n}\n"], - "mappings": "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", - "names": ["input", "input"] -} diff --git a/src/app/code/Komoju/Payments/view/frontend/web/js/secure-token-return.html b/src/app/code/Komoju/Payments/view/frontend/web/js/secure-token-return.html deleted file mode 100644 index 8f510aae6..000000000 --- a/src/app/code/Komoju/Payments/view/frontend/web/js/secure-token-return.html +++ /dev/null @@ -1,17 +0,0 @@ - - - - - - KOMOJU Fields - - - - - - diff --git a/src/app/code/Komoju/Payments/view/frontend/web/js/static/credit_card_cvc.svg b/src/app/code/Komoju/Payments/view/frontend/web/js/static/credit_card_cvc.svg deleted file mode 100644 index 68129726b..000000000 --- a/src/app/code/Komoju/Payments/view/frontend/web/js/static/credit_card_cvc.svg +++ /dev/null @@ -1,67 +0,0 @@ - - - - - - - 123 - diff --git a/src/app/code/Komoju/Payments/view/frontend/web/js/static/credit_card_number.svg b/src/app/code/Komoju/Payments/view/frontend/web/js/static/credit_card_number.svg deleted file mode 100644 index ebca587e4..000000000 --- a/src/app/code/Komoju/Payments/view/frontend/web/js/static/credit_card_number.svg +++ /dev/null @@ -1,72 +0,0 @@ - - - - - - - - 1111 2222 .. - diff --git a/src/app/code/Komoju/Payments/view/frontend/web/js/static/shared.css b/src/app/code/Komoju/Payments/view/frontend/web/js/static/shared.css deleted file mode 100644 index 1db981751..000000000 --- a/src/app/code/Komoju/Payments/view/frontend/web/js/static/shared.css +++ /dev/null @@ -1,139 +0,0 @@ -:root,:host { - --primary-color: #000000; - --error-color: #df1b41; - --secondary-color: #6d6e78; - --placeholder-color: #6d6e78; - --border-color: #e6e6e6; - --selected-color: #0570de; - --field-background: #ffffff; - --hover-background: #cccccc1f; - - font-family: sans-serif; - color: var(--primary-color); -} - -body { - box-sizing: border-box; - margin: 4px; -} - -komoju-i18n { - display: inline; -} - -komoju-error { - color: var(--error-color); -} - -komoju-fade { - position: absolute; - z-index: 100; - - background: white; - - opacity: 0; - transition: opacity 0.5s; -} - -komoju-fade.show { - opacity: 0.65; -} - -input { - transition: color 0.2s ease-in-out, border-color 0.2s ease-in-out; -} - -label input.invalid { - border-color: var(--error-color); - color: var(--error-color); -} - -.field { - position: relative; - display: flex; - flex-direction: column; - width: 100%; -} - -.field input { - box-shadow: 0px 1px 1px rgba(0, 0, 0, 0.03), 0px 3px 6px rgba(0, 0, 0, 0.02); - border: 1px solid var(--border-color); - border-radius: 5px; - padding: 0.75rem; - background: var(--field-background); - color: var(--primary-color); -} -.field input::placeholder { - color: var(--placeholder-color); -} - -.price-info { - color: var(--secondary-color); -} - -.fields { - gap: 12px; -} - -#picker { - gap: 12px; - margin-bottom: 12px; -} - -#picker .radio { - width: 9rem; -} - -.konbini,#picker { - justify-content: flex-start; -} - -.radio { - flex-direction: column; - align-items: flex-start; - justify-content: center; - - border-radius: 5px; - border: 1px solid var(--border-color); - box-shadow: 0px 1px 1px rgba(0, 0, 0, 0.03), 0px 3px 6px rgba(0, 0, 0, 0.02); - - background-color: var(--field-background); - color: var(--primary-color); - font-weight: 500; - font-size: 0.875rem; - - width: 11.25rem; - padding: 0.75rem; - gap: 2px; - - cursor: pointer; - - transition: background-color 0.1s ease-out, - border-color 0.1s ease-out, - color 0.1s ease-out; -} - -.radio input { - position: absolute; - opacity: 0; -} - -.radio:hover { - background: var(--hover-background); - color: var(--hover-color, var(--primary-color)) -} - -.radio:active { - background: var(--field-background); -} - -.radio.checked { - border-color: var(--selected-color); - color: var(--selected-color); -} - -iframe { - border: none; - width: 100%; - height: 100%; -} diff --git a/src/app/code/Komoju/Payments/view/frontend/web/js/static/themes/dark.css b/src/app/code/Komoju/Payments/view/frontend/web/js/static/themes/dark.css deleted file mode 100644 index 64421dd57..000000000 --- a/src/app/code/Komoju/Payments/view/frontend/web/js/static/themes/dark.css +++ /dev/null @@ -1,9 +0,0 @@ -:root,:host { - --primary-color: #f5f5f5; - --error-color: #f44336; - --secondary-color: #f5f5f5; - --placeholder-color: #9e9e9e; - --border-color: #e0e0e0; - --field-background: #424242; - --selected-color: #73bffb; -} diff --git a/src/app/code/Komoju/Payments/view/frontend/web/js/view/payment/method-renderer/form.js b/src/app/code/Komoju/Payments/view/frontend/web/js/view/payment/method-renderer/form.js index 4b675e824..1a8dd8af7 100644 --- a/src/app/code/Komoju/Payments/view/frontend/web/js/view/payment/method-renderer/form.js +++ b/src/app/code/Komoju/Payments/view/frontend/web/js/view/payment/method-renderer/form.js @@ -31,6 +31,7 @@ define( komojuSession: ko.observable(''), isDataLoaded: ko.observable(false), komojuToken: ko.observable(''), + komojuFieldEnabledMethods: ['credit_card', 'konbini', 'bank_transfer'] }, initialize: function () { @@ -44,10 +45,9 @@ define( $.get(url.build('komoju/komojufield/komojusessiondata')) .done(function (response) { - console.log('######## RESPONSE: ' + JSON.stringify(response)); - self.komojuSession(response.komojuSession); self.isDataLoaded(true); + self.komojuToken(null); }); }, @@ -116,14 +116,19 @@ define( const boundSuper = this._super.bind(this); - this.submitPayment().then(token => { - this.komojuToken(token); + if (this.komojuFieldEnabledMethods.includes(this.komojuMethod())) { + this.submitPayment().then(token => { + this.komojuToken(token); + boundSuper(data, event); + }).catch(error => { + console.error('Error during token submission:', error); + messageList.addErrorMessage({ message: $t("There was an error processing your payment. Please try again.") }); + fullScreenLoader.stopLoader(); + }); + } else { + this.komojuToken(null); boundSuper(data, event); - }).catch(error => { - console.error('Error during token submission:', error); - messageList.addErrorMessage({ message: $t("There was an error processing your payment. Please try again.") }); - fullScreenLoader.stopLoader(); - }); + } }, sendToken: function (token) { diff --git a/src/app/code/Komoju/Payments/view/frontend/web/template/payment/form.html b/src/app/code/Komoju/Payments/view/frontend/web/template/payment/form.html index 473c0bb58..0aabf2fa4 100644 --- a/src/app/code/Komoju/Payments/view/frontend/web/template/payment/form.html +++ b/src/app/code/Komoju/Payments/view/frontend/web/template/payment/form.html @@ -28,6 +28,7 @@

+
komoju-api="https://komoju.com" publishable-key="pk_test_lgva3j8ims1p3nhk3ut1f88t"> -
+ From 435efe73dc013aaaa31757444b3495df28cf2cb4 Mon Sep 17 00:00:00 2001 From: Dinwy Date: Tue, 2 Jul 2024 17:38:39 +0900 Subject: [PATCH 06/15] Prevent rendering komoju payment methods before data is loaded --- .../Payments/Controller/KomojuField/KomojuSessionData.php | 1 + .../frontend/web/js/view/payment/method-renderer/form.js | 5 +---- .../Payments/view/frontend/web/template/payment/form.html | 3 +++ 3 files changed, 5 insertions(+), 4 deletions(-) diff --git a/src/app/code/Komoju/Payments/Controller/KomojuField/KomojuSessionData.php b/src/app/code/Komoju/Payments/Controller/KomojuField/KomojuSessionData.php index 9f9c6ada7..c1a0a64c0 100644 --- a/src/app/code/Komoju/Payments/Controller/KomojuField/KomojuSessionData.php +++ b/src/app/code/Komoju/Payments/Controller/KomojuField/KomojuSessionData.php @@ -68,6 +68,7 @@ private function createKomojuSession($paymentMethod, $totalAmount, $currencyCode 'amount' => $totalAmount, 'currency' => $currencyCode, 'default_locale' => $this->config->getKomojuLocale(), + // 'payment_methods' => $this->komojuApi->paymentMethods(), 'payment_types' => [$paymentMethod], 'email' => $customerEmail, 'metadata' => [ diff --git a/src/app/code/Komoju/Payments/view/frontend/web/js/view/payment/method-renderer/form.js b/src/app/code/Komoju/Payments/view/frontend/web/js/view/payment/method-renderer/form.js index 1a8dd8af7..351b39ab8 100644 --- a/src/app/code/Komoju/Payments/view/frontend/web/js/view/payment/method-renderer/form.js +++ b/src/app/code/Komoju/Payments/view/frontend/web/js/view/payment/method-renderer/form.js @@ -140,7 +140,6 @@ define( return; } - console.log(`sendToken: ${JSON.stringify(token)}`); const serviceUrl = url.build('komoju/komojufield/processToken'); const data = { @@ -153,9 +152,7 @@ define( type: 'POST', data: JSON.stringify(data), contentType: 'application/json', - success: function (response) { - console.log('Server responded with:', JSON.stringify(response)); - }, + success: function (response) { }, error: function (xhr, status, error) { console.error('Failed to send token:', error); } diff --git a/src/app/code/Komoju/Payments/view/frontend/web/template/payment/form.html b/src/app/code/Komoju/Payments/view/frontend/web/template/payment/form.html index 0aabf2fa4..3ff370eca 100644 --- a/src/app/code/Komoju/Payments/view/frontend/web/template/payment/form.html +++ b/src/app/code/Komoju/Payments/view/frontend/web/template/payment/form.html @@ -7,6 +7,8 @@

+ +
+
From fbd1441bfa94e3ca67b9f2b418395f5c46b2a1b2 Mon Sep 17 00:00:00 2001 From: Dinwy Date: Wed, 3 Jul 2024 10:59:39 +0900 Subject: [PATCH 07/15] Fix lint error --- .gitignore | 1 + .../Payments/Controller/HostedPage/Webhook.php | 1 - .../Controller/KomojuField/KomojuSessionData.php | 2 +- .../web/js/view/payment/method-renderer/form.js | 12 ++++++------ 4 files changed, 8 insertions(+), 8 deletions(-) diff --git a/.gitignore b/.gitignore index f67bf9036..273e367fc 100644 --- a/.gitignore +++ b/.gitignore @@ -2,6 +2,7 @@ # Ignore everything in the src directory src/** +node_modules/ # Re-include directories under src/app/code/Komoju/Payments and subdirectories !src/ diff --git a/src/app/code/Komoju/Payments/Controller/HostedPage/Webhook.php b/src/app/code/Komoju/Payments/Controller/HostedPage/Webhook.php index fcd3c7816..c9a372cdd 100644 --- a/src/app/code/Komoju/Payments/Controller/HostedPage/Webhook.php +++ b/src/app/code/Komoju/Payments/Controller/HostedPage/Webhook.php @@ -131,7 +131,6 @@ public function execute() $this->logger->info($message); } - $result = $this->_resultFactory->create(ResultFactory::TYPE_JSON); $result->setHttpResponseCode(200); $result->setData(''); diff --git a/src/app/code/Komoju/Payments/Controller/KomojuField/KomojuSessionData.php b/src/app/code/Komoju/Payments/Controller/KomojuField/KomojuSessionData.php index c1a0a64c0..2d74b852c 100644 --- a/src/app/code/Komoju/Payments/Controller/KomojuField/KomojuSessionData.php +++ b/src/app/code/Komoju/Payments/Controller/KomojuField/KomojuSessionData.php @@ -27,7 +27,7 @@ public function __construct( CheckoutSession $checkoutSession, KomojuApi $komojuApi, Config $config, - Cart $cart, + Cart $cart ) { $this->jsonResultFactory = $jsonResultFactory; $this->quoteRepository = $quoteRepository; diff --git a/src/app/code/Komoju/Payments/view/frontend/web/js/view/payment/method-renderer/form.js b/src/app/code/Komoju/Payments/view/frontend/web/js/view/payment/method-renderer/form.js index 351b39ab8..65ceb34e6 100644 --- a/src/app/code/Komoju/Payments/view/frontend/web/js/view/payment/method-renderer/form.js +++ b/src/app/code/Komoju/Payments/view/frontend/web/js/view/payment/method-renderer/form.js @@ -40,7 +40,7 @@ define( }, loadKomojuData: function () { - const self = this; + var self = this; self.isDataLoaded(false); $.get(url.build('komoju/komojufield/komojusessiondata')) @@ -52,7 +52,7 @@ define( }, submitPayment: function () { - const komojuField = document.querySelector(`komoju-fields[payment-type='${this.komojuMethod()}']`); + var komojuField = document.querySelector(`komoju-fields[payment-type='${this.komojuMethod()}']`); if (komojuField) { return new Promise((resolve, reject) => { @@ -114,7 +114,7 @@ define( fullScreenLoader.startLoader(); - const boundSuper = this._super.bind(this); + var boundSuper = this._super.bind(this); if (this.komojuFieldEnabledMethods.includes(this.komojuMethod())) { this.submitPayment().then(token => { @@ -133,16 +133,16 @@ define( sendToken: function (token) { if (!token) { - const redirectUrl = this.redirectUrl() + "?payment_method=" + this.komojuMethod(); + var redirectUrl = this.redirectUrl() + "?payment_method=" + this.komojuMethod(); $.mage.redirect( redirectUrl ); return; } - const serviceUrl = url.build('komoju/komojufield/processToken'); + var serviceUrl = url.build('komoju/komojufield/processToken'); - const data = { + var data = { 'id': this.komojuSession().id, 'token': token } From b5cd6b3eaddc0a3b0f2145fa5e53887402654000 Mon Sep 17 00:00:00 2001 From: Dinwy Date: Wed, 3 Jul 2024 11:21:01 +0900 Subject: [PATCH 08/15] Fix eslint --- .eslintrc | 3 +- package-lock.json | 1122 +++++++++++++++++ .../KomojuField/KomojuSessionData.php | 3 +- .../js/view/payment/method-renderer/form.js | 85 +- 4 files changed, 1169 insertions(+), 44 deletions(-) create mode 100644 package-lock.json diff --git a/.eslintrc b/.eslintrc index f1fd23ff4..952cc332b 100644 --- a/.eslintrc +++ b/.eslintrc @@ -5,7 +5,8 @@ "jasmine": true, "jquery": true, "prototypejs": true, - "node": true + "node": true, + "es6": true }, "rules": { "eqeqeq": [2, "smart"], diff --git a/package-lock.json b/package-lock.json new file mode 100644 index 000000000..03144c31f --- /dev/null +++ b/package-lock.json @@ -0,0 +1,1122 @@ +{ + "name": "komoju-magento", + "lockfileVersion": 3, + "requires": true, + "packages": { + "": { + "dependencies": { + "eslint": "^7.22.0" + } + }, + "node_modules/@babel/code-frame": { + "version": "7.12.11", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.12.11.tgz", + "integrity": "sha512-Zt1yodBx1UcyiePMSkWnU4hPqhwq7hGi2nFL1LeA3EUl+q2LQx16MISgJ0+z7dnmgvP9QtIleuETGOiOH1RcIw==", + "dependencies": { + "@babel/highlight": "^7.10.4" + } + }, + "node_modules/@babel/helper-validator-identifier": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.24.7.tgz", + "integrity": "sha512-rR+PBcQ1SMQDDyF6X0wxtG8QyLCgUB0eRAGguqRLfkCA87l7yAP7ehq8SNj96OOGTO8OBV70KhuFYcIkHXOg0w==", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/highlight": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.24.7.tgz", + "integrity": "sha512-EStJpq4OuY8xYfhGVXngigBJRWxftKX9ksiGDnmlY3o7B/V7KIAc9X4oiK87uPJSc/vs5L869bem5fhZa8caZw==", + "dependencies": { + "@babel/helper-validator-identifier": "^7.24.7", + "chalk": "^2.4.2", + "js-tokens": "^4.0.0", + "picocolors": "^1.0.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/highlight/node_modules/ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "dependencies": { + "color-convert": "^1.9.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/@babel/highlight/node_modules/chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "dependencies": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/@babel/highlight/node_modules/color-convert": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", + "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "dependencies": { + "color-name": "1.1.3" + } + }, + "node_modules/@babel/highlight/node_modules/color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==" + }, + "node_modules/@babel/highlight/node_modules/escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/@babel/highlight/node_modules/has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", + "engines": { + "node": ">=4" + } + }, + "node_modules/@babel/highlight/node_modules/supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "dependencies": { + "has-flag": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/@eslint/eslintrc": { + "version": "0.4.3", + "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-0.4.3.tgz", + "integrity": "sha512-J6KFFz5QCYUJq3pf0mjEcCJVERbzv71PUIDczuh9JkwGEzced6CO5ADLHB1rbf/+oPBtoPfMYNOpGDzCANlbXw==", + "dependencies": { + "ajv": "^6.12.4", + "debug": "^4.1.1", + "espree": "^7.3.0", + "globals": "^13.9.0", + "ignore": "^4.0.6", + "import-fresh": "^3.2.1", + "js-yaml": "^3.13.1", + "minimatch": "^3.0.4", + "strip-json-comments": "^3.1.1" + }, + "engines": { + "node": "^10.12.0 || >=12.0.0" + } + }, + "node_modules/@humanwhocodes/config-array": { + "version": "0.5.0", + "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.5.0.tgz", + "integrity": "sha512-FagtKFz74XrTl7y6HCzQpwDfXP0yhxe9lHLD1UZxjvZIcbyRz8zTFF/yYNfSfzU414eDwZ1SrO0Qvtyf+wFMQg==", + "deprecated": "Use @eslint/config-array instead", + "dependencies": { + "@humanwhocodes/object-schema": "^1.2.0", + "debug": "^4.1.1", + "minimatch": "^3.0.4" + }, + "engines": { + "node": ">=10.10.0" + } + }, + "node_modules/@humanwhocodes/object-schema": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-1.2.1.tgz", + "integrity": "sha512-ZnQMnLV4e7hDlUvw8H+U8ASL02SS2Gn6+9Ac3wGGLIe7+je2AeAOxPY+izIPJDfFDb7eDjev0Us8MO1iFRN8hA==", + "deprecated": "Use @eslint/object-schema instead" + }, + "node_modules/acorn": { + "version": "7.4.1", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-7.4.1.tgz", + "integrity": "sha512-nQyp0o1/mNdbTO1PO6kHkwSrmgZ0MT/jCCpNiwbUjGoRN4dlBhqJtoQuCnEOKzgTVwg0ZWiCoQy6SxMebQVh8A==", + "bin": { + "acorn": "bin/acorn" + }, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/acorn-jsx": { + "version": "5.3.2", + "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz", + "integrity": "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==", + "peerDependencies": { + "acorn": "^6.0.0 || ^7.0.0 || ^8.0.0" + } + }, + "node_modules/ajv": { + "version": "6.12.6", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", + "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", + "dependencies": { + "fast-deep-equal": "^3.1.1", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.4.1", + "uri-js": "^4.2.2" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" + } + }, + "node_modules/ansi-colors": { + "version": "4.1.3", + "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-4.1.3.tgz", + "integrity": "sha512-/6w/C21Pm1A7aZitlI5Ni/2J6FFQN8i1Cvz3kHABAAbw93v/NlvKdVOqz7CCWz/3iv/JplRSEEZ83XION15ovw==", + "engines": { + "node": ">=6" + } + }, + "node_modules/ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "engines": { + "node": ">=8" + } + }, + "node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/argparse": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", + "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", + "dependencies": { + "sprintf-js": "~1.0.2" + } + }, + "node_modules/astral-regex": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/astral-regex/-/astral-regex-2.0.0.tgz", + "integrity": "sha512-Z7tMw1ytTXt5jqMcOP+OQteU1VuNK9Y02uuJtKQ1Sv69jXQKKg5cibLwGJow8yzZP+eAc18EmLGPal0bp36rvQ==", + "engines": { + "node": ">=8" + } + }, + "node_modules/balanced-match": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", + "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==" + }, + "node_modules/brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/callsites": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", + "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==", + "engines": { + "node": ">=6" + } + }, + "node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" + }, + "node_modules/concat-map": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", + "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==" + }, + "node_modules/cross-spawn": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", + "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", + "dependencies": { + "path-key": "^3.1.0", + "shebang-command": "^2.0.0", + "which": "^2.0.1" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/debug": { + "version": "4.3.5", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.5.tgz", + "integrity": "sha512-pt0bNEmneDIvdL1Xsd9oDQ/wrQRkXDT4AUWlNZNPKvW5x/jyO9VFXkJUP07vQ2upmw5PlaITaPKc31jK13V+jg==", + "dependencies": { + "ms": "2.1.2" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/deep-is": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz", + "integrity": "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==" + }, + "node_modules/doctrine": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz", + "integrity": "sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==", + "dependencies": { + "esutils": "^2.0.2" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==" + }, + "node_modules/enquirer": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/enquirer/-/enquirer-2.4.1.tgz", + "integrity": "sha512-rRqJg/6gd538VHvR3PSrdRBb/1Vy2YfzHqzvbhGIQpDRKIa4FgV/54b5Q1xYSxOOwKvjXweS26E0Q+nAMwp2pQ==", + "dependencies": { + "ansi-colors": "^4.1.1", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8.6" + } + }, + "node_modules/escape-string-regexp": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", + "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/eslint": { + "version": "7.32.0", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-7.32.0.tgz", + "integrity": "sha512-VHZ8gX+EDfz+97jGcgyGCyRia/dPOd6Xh9yPv8Bl1+SoaIwD+a/vlrOmGRUyOYu7MwUhc7CxqeaDZU13S4+EpA==", + "dependencies": { + "@babel/code-frame": "7.12.11", + "@eslint/eslintrc": "^0.4.3", + "@humanwhocodes/config-array": "^0.5.0", + "ajv": "^6.10.0", + "chalk": "^4.0.0", + "cross-spawn": "^7.0.2", + "debug": "^4.0.1", + "doctrine": "^3.0.0", + "enquirer": "^2.3.5", + "escape-string-regexp": "^4.0.0", + "eslint-scope": "^5.1.1", + "eslint-utils": "^2.1.0", + "eslint-visitor-keys": "^2.0.0", + "espree": "^7.3.1", + "esquery": "^1.4.0", + "esutils": "^2.0.2", + "fast-deep-equal": "^3.1.3", + "file-entry-cache": "^6.0.1", + "functional-red-black-tree": "^1.0.1", + "glob-parent": "^5.1.2", + "globals": "^13.6.0", + "ignore": "^4.0.6", + "import-fresh": "^3.0.0", + "imurmurhash": "^0.1.4", + "is-glob": "^4.0.0", + "js-yaml": "^3.13.1", + "json-stable-stringify-without-jsonify": "^1.0.1", + "levn": "^0.4.1", + "lodash.merge": "^4.6.2", + "minimatch": "^3.0.4", + "natural-compare": "^1.4.0", + "optionator": "^0.9.1", + "progress": "^2.0.0", + "regexpp": "^3.1.0", + "semver": "^7.2.1", + "strip-ansi": "^6.0.0", + "strip-json-comments": "^3.1.0", + "table": "^6.0.9", + "text-table": "^0.2.0", + "v8-compile-cache": "^2.0.3" + }, + "bin": { + "eslint": "bin/eslint.js" + }, + "engines": { + "node": "^10.12.0 || >=12.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/eslint-scope": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.1.1.tgz", + "integrity": "sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw==", + "dependencies": { + "esrecurse": "^4.3.0", + "estraverse": "^4.1.1" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/eslint-scope/node_modules/estraverse": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz", + "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==", + "engines": { + "node": ">=4.0" + } + }, + "node_modules/eslint-utils": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-2.1.0.tgz", + "integrity": "sha512-w94dQYoauyvlDc43XnGB8lU3Zt713vNChgt4EWwhXAP2XkBvndfxF0AgIqKOOasjPIPzj9JqgwkwbCYD0/V3Zg==", + "dependencies": { + "eslint-visitor-keys": "^1.1.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/mysticatea" + } + }, + "node_modules/eslint-utils/node_modules/eslint-visitor-keys": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-1.3.0.tgz", + "integrity": "sha512-6J72N8UNa462wa/KFODt/PJ3IU60SDpC3QXC1Hjc1BXXpfL2C9R5+AU7jhe0F6GREqVMh4Juu+NY7xn+6dipUQ==", + "engines": { + "node": ">=4" + } + }, + "node_modules/eslint-visitor-keys": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-2.1.0.tgz", + "integrity": "sha512-0rSmRBzXgDzIsD6mGdJgevzgezI534Cer5L/vyMX0kHzT/jiB43jRhd9YUlMGYLQy2zprNmoT8qasCGtY+QaKw==", + "engines": { + "node": ">=10" + } + }, + "node_modules/espree": { + "version": "7.3.1", + "resolved": "https://registry.npmjs.org/espree/-/espree-7.3.1.tgz", + "integrity": "sha512-v3JCNCE64umkFpmkFGqzVKsOT0tN1Zr+ueqLZfpV1Ob8e+CEgPWa+OxCoGH3tnhimMKIaBm4m/vaRpJ/krRz2g==", + "dependencies": { + "acorn": "^7.4.0", + "acorn-jsx": "^5.3.1", + "eslint-visitor-keys": "^1.3.0" + }, + "engines": { + "node": "^10.12.0 || >=12.0.0" + } + }, + "node_modules/espree/node_modules/eslint-visitor-keys": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-1.3.0.tgz", + "integrity": "sha512-6J72N8UNa462wa/KFODt/PJ3IU60SDpC3QXC1Hjc1BXXpfL2C9R5+AU7jhe0F6GREqVMh4Juu+NY7xn+6dipUQ==", + "engines": { + "node": ">=4" + } + }, + "node_modules/esprima": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", + "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==", + "bin": { + "esparse": "bin/esparse.js", + "esvalidate": "bin/esvalidate.js" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/esquery": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.5.0.tgz", + "integrity": "sha512-YQLXUplAwJgCydQ78IMJywZCceoqk1oH01OERdSAJc/7U2AylwjhSCLDEtqwg811idIS/9fIU5GjG73IgjKMVg==", + "dependencies": { + "estraverse": "^5.1.0" + }, + "engines": { + "node": ">=0.10" + } + }, + "node_modules/esrecurse": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz", + "integrity": "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==", + "dependencies": { + "estraverse": "^5.2.0" + }, + "engines": { + "node": ">=4.0" + } + }, + "node_modules/estraverse": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", + "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", + "engines": { + "node": ">=4.0" + } + }, + "node_modules/esutils": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", + "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/fast-deep-equal": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", + "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==" + }, + "node_modules/fast-json-stable-stringify": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", + "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==" + }, + "node_modules/fast-levenshtein": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", + "integrity": "sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==" + }, + "node_modules/file-entry-cache": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-6.0.1.tgz", + "integrity": "sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg==", + "dependencies": { + "flat-cache": "^3.0.4" + }, + "engines": { + "node": "^10.12.0 || >=12.0.0" + } + }, + "node_modules/flat-cache": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-3.2.0.tgz", + "integrity": "sha512-CYcENa+FtcUKLmhhqyctpclsq7QF38pKjZHsGNiSQF5r4FtoKDWabFDl3hzaEQMvT1LHEysw5twgLvpYYb4vbw==", + "dependencies": { + "flatted": "^3.2.9", + "keyv": "^4.5.3", + "rimraf": "^3.0.2" + }, + "engines": { + "node": "^10.12.0 || >=12.0.0" + } + }, + "node_modules/flatted": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.3.1.tgz", + "integrity": "sha512-X8cqMLLie7KsNUDSdzeN8FYK9rEt4Dt67OsG/DNGnYTSDBG4uFAJFBnUeiV+zCVAvwFy56IjM9sH51jVaEhNxw==" + }, + "node_modules/fs.realpath": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", + "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==" + }, + "node_modules/functional-red-black-tree": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/functional-red-black-tree/-/functional-red-black-tree-1.0.1.tgz", + "integrity": "sha512-dsKNQNdj6xA3T+QlADDA7mOSlX0qiMINjn0cgr+eGHGsbSHzTabcIogz2+p/iqP1Xs6EP/sS2SbqH+brGTbq0g==" + }, + "node_modules/glob": { + "version": "7.2.3", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", + "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", + "deprecated": "Glob versions prior to v9 are no longer supported", + "dependencies": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.1.1", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + }, + "engines": { + "node": "*" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/glob-parent": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", + "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", + "dependencies": { + "is-glob": "^4.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/globals": { + "version": "13.24.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-13.24.0.tgz", + "integrity": "sha512-AhO5QUcj8llrbG09iWhPU2B204J1xnPeL8kQmVorSsy+Sjj1sk8gIyh6cUocGmH4L0UuhAJy+hJMRA4mgA4mFQ==", + "dependencies": { + "type-fest": "^0.20.2" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "engines": { + "node": ">=8" + } + }, + "node_modules/ignore": { + "version": "4.0.6", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-4.0.6.tgz", + "integrity": "sha512-cyFDKrqc/YdcWFniJhzI42+AzS+gNwmUzOSFcRCQYwySuBBBy/KjuxWLZ/FHEH6Moq1NizMOBWyTcv8O4OZIMg==", + "engines": { + "node": ">= 4" + } + }, + "node_modules/import-fresh": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz", + "integrity": "sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==", + "dependencies": { + "parent-module": "^1.0.0", + "resolve-from": "^4.0.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/imurmurhash": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", + "integrity": "sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==", + "engines": { + "node": ">=0.8.19" + } + }, + "node_modules/inflight": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", + "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==", + "deprecated": "This module is not supported, and leaks memory. Do not use it. Check out lru-cache if you want a good and tested way to coalesce async requests by a key value, which is much more comprehensive and powerful.", + "dependencies": { + "once": "^1.3.0", + "wrappy": "1" + } + }, + "node_modules/inherits": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" + }, + "node_modules/is-extglob": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", + "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-fullwidth-code-point": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", + "engines": { + "node": ">=8" + } + }, + "node_modules/is-glob": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", + "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", + "dependencies": { + "is-extglob": "^2.1.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/isexe": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", + "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==" + }, + "node_modules/js-tokens": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", + "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==" + }, + "node_modules/js-yaml": { + "version": "3.14.1", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.1.tgz", + "integrity": "sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==", + "dependencies": { + "argparse": "^1.0.7", + "esprima": "^4.0.0" + }, + "bin": { + "js-yaml": "bin/js-yaml.js" + } + }, + "node_modules/json-buffer": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.1.tgz", + "integrity": "sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==" + }, + "node_modules/json-schema-traverse": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", + "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==" + }, + "node_modules/json-stable-stringify-without-jsonify": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz", + "integrity": "sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==" + }, + "node_modules/keyv": { + "version": "4.5.4", + "resolved": "https://registry.npmjs.org/keyv/-/keyv-4.5.4.tgz", + "integrity": "sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==", + "dependencies": { + "json-buffer": "3.0.1" + } + }, + "node_modules/levn": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz", + "integrity": "sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==", + "dependencies": { + "prelude-ls": "^1.2.1", + "type-check": "~0.4.0" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/lodash.merge": { + "version": "4.6.2", + "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz", + "integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==" + }, + "node_modules/lodash.truncate": { + "version": "4.4.2", + "resolved": "https://registry.npmjs.org/lodash.truncate/-/lodash.truncate-4.4.2.tgz", + "integrity": "sha512-jttmRe7bRse52OsWIMDLaXxWqRAmtIUccAQ3garviCqJjafXOfNMO0yMfNpdD6zbGaTU0P5Nz7e7gAT6cKmJRw==" + }, + "node_modules/minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" + }, + "node_modules/natural-compare": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", + "integrity": "sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==" + }, + "node_modules/once": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", + "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", + "dependencies": { + "wrappy": "1" + } + }, + "node_modules/optionator": { + "version": "0.9.4", + "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.4.tgz", + "integrity": "sha512-6IpQ7mKUxRcZNLIObR0hz7lxsapSSIYNZJwXPGeF0mTVqGKFIXj1DQcMoT22S3ROcLyY/rz0PWaWZ9ayWmad9g==", + "dependencies": { + "deep-is": "^0.1.3", + "fast-levenshtein": "^2.0.6", + "levn": "^0.4.1", + "prelude-ls": "^1.2.1", + "type-check": "^0.4.0", + "word-wrap": "^1.2.5" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/parent-module": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", + "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==", + "dependencies": { + "callsites": "^3.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/path-is-absolute": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", + "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/path-key": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", + "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", + "engines": { + "node": ">=8" + } + }, + "node_modules/picocolors": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.1.tgz", + "integrity": "sha512-anP1Z8qwhkbmu7MFP5iTt+wQKXgwzf7zTyGlcdzabySa9vd0Xt392U0rVmz9poOaBj0uHJKyyo9/upk0HrEQew==" + }, + "node_modules/prelude-ls": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz", + "integrity": "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==", + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/progress": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/progress/-/progress-2.0.3.tgz", + "integrity": "sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA==", + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/punycode": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz", + "integrity": "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==", + "engines": { + "node": ">=6" + } + }, + "node_modules/regexpp": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/regexpp/-/regexpp-3.2.0.tgz", + "integrity": "sha512-pq2bWo9mVD43nbts2wGv17XLiNLya+GklZ8kaDLV2Z08gDCsGpnKn9BFMepvWuHCbyVvY7J5o5+BVvoQbmlJLg==", + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/mysticatea" + } + }, + "node_modules/require-from-string": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/require-from-string/-/require-from-string-2.0.2.tgz", + "integrity": "sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/resolve-from": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", + "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==", + "engines": { + "node": ">=4" + } + }, + "node_modules/rimraf": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", + "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", + "deprecated": "Rimraf versions prior to v4 are no longer supported", + "dependencies": { + "glob": "^7.1.3" + }, + "bin": { + "rimraf": "bin.js" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/semver": { + "version": "7.6.2", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.2.tgz", + "integrity": "sha512-FNAIBWCx9qcRhoHcgcJ0gvU7SN1lYU2ZXuSfl04bSC5OpvDHFyJCjdNHomPXxjQlCBU67YW64PzY7/VIEH7F2w==", + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/shebang-command": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", + "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", + "dependencies": { + "shebang-regex": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/shebang-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", + "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", + "engines": { + "node": ">=8" + } + }, + "node_modules/slice-ansi": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-4.0.0.tgz", + "integrity": "sha512-qMCMfhY040cVHT43K9BFygqYbUPFZKHOg7K73mtTWJRb8pyP3fzf4Ixd5SzdEJQ6MRUg/WBnOLxghZtKKurENQ==", + "dependencies": { + "ansi-styles": "^4.0.0", + "astral-regex": "^2.0.0", + "is-fullwidth-code-point": "^3.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/slice-ansi?sponsor=1" + } + }, + "node_modules/sprintf-js": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", + "integrity": "sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==" + }, + "node_modules/string-width": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/strip-json-comments": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", + "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==", + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/table": { + "version": "6.8.2", + "resolved": "https://registry.npmjs.org/table/-/table-6.8.2.tgz", + "integrity": "sha512-w2sfv80nrAh2VCbqR5AK27wswXhqcck2AhfnNW76beQXskGZ1V12GwS//yYVa3d3fcvAip2OUnbDAjW2k3v9fA==", + "dependencies": { + "ajv": "^8.0.1", + "lodash.truncate": "^4.4.2", + "slice-ansi": "^4.0.0", + "string-width": "^4.2.3", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=10.0.0" + } + }, + "node_modules/table/node_modules/ajv": { + "version": "8.16.0", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.16.0.tgz", + "integrity": "sha512-F0twR8U1ZU67JIEtekUcLkXkoO5mMMmgGD8sK/xUFzJ805jxHQl92hImFAqqXMyMYjSPOyUPAwHYhB72g5sTXw==", + "dependencies": { + "fast-deep-equal": "^3.1.3", + "json-schema-traverse": "^1.0.0", + "require-from-string": "^2.0.2", + "uri-js": "^4.4.1" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" + } + }, + "node_modules/table/node_modules/json-schema-traverse": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", + "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==" + }, + "node_modules/text-table": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz", + "integrity": "sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==" + }, + "node_modules/type-check": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz", + "integrity": "sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==", + "dependencies": { + "prelude-ls": "^1.2.1" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/type-fest": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz", + "integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/uri-js": { + "version": "4.4.1", + "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", + "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==", + "dependencies": { + "punycode": "^2.1.0" + } + }, + "node_modules/v8-compile-cache": { + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/v8-compile-cache/-/v8-compile-cache-2.4.0.tgz", + "integrity": "sha512-ocyWc3bAHBB/guyqJQVI5o4BZkPhznPYUG2ea80Gond/BgNWpap8TOmLSeeQG7bnh2KMISxskdADG59j7zruhw==" + }, + "node_modules/which": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", + "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", + "dependencies": { + "isexe": "^2.0.0" + }, + "bin": { + "node-which": "bin/node-which" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/word-wrap": { + "version": "1.2.5", + "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.5.tgz", + "integrity": "sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/wrappy": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", + "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==" + } + } +} diff --git a/src/app/code/Komoju/Payments/Controller/KomojuField/KomojuSessionData.php b/src/app/code/Komoju/Payments/Controller/KomojuField/KomojuSessionData.php index 2d74b852c..010adae4e 100644 --- a/src/app/code/Komoju/Payments/Controller/KomojuField/KomojuSessionData.php +++ b/src/app/code/Komoju/Payments/Controller/KomojuField/KomojuSessionData.php @@ -89,7 +89,8 @@ private function convertAddress($address) ]; } - public function getKomojuSessionData() { + public function getKomojuSessionData() + { $paymentMethod = $this->getRequest()->getParam('payment_method'); $order = $this->getOrder(); $billingAddress = $order->getBillingAddress(); diff --git a/src/app/code/Komoju/Payments/view/frontend/web/js/view/payment/method-renderer/form.js b/src/app/code/Komoju/Payments/view/frontend/web/js/view/payment/method-renderer/form.js index 65ceb34e6..75636913e 100644 --- a/src/app/code/Komoju/Payments/view/frontend/web/js/view/payment/method-renderer/form.js +++ b/src/app/code/Komoju/Payments/view/frontend/web/js/view/payment/method-renderer/form.js @@ -41,6 +41,7 @@ define( loadKomojuData: function () { var self = this; + self.isDataLoaded(false); $.get(url.build('komoju/komojufield/komojusessiondata')) @@ -52,99 +53,99 @@ define( }, submitPayment: function () { - var komojuField = document.querySelector(`komoju-fields[payment-type='${this.komojuMethod()}']`); + var komojuField = document.querySelector('komoju-fields[payment-type=' + this.komojuMethod() + ']'); if (komojuField) { - return new Promise((resolve, reject) => { + return new Promise(function (resolve, reject) { komojuField.addEventListener('komoju-invalid', reject); - komojuField.submit().then(token => { + komojuField.submit().then(function (token) { komojuField.removeEventListener('komoju-invalid', reject); if (token) { resolve(token); } else { reject(new Error("Token not found")); } - }).catch(error => { + }).catch(function (error) { komojuField.removeEventListener('komoju-invalid', reject); reject(error); }); }); - } else { - return Promise.reject(new Error("Komoju fields component not found")); } + return Promise.reject(new Error("Komoju fields component not found")); }, afterPlaceOrder: function() { - if (this.komojuToken) { - this.sendToken(this.komojuToken()).done(function(response) { - if (response.success) { - let redirectUrl = url.build('checkout/onepage/success'); + var self = this; + var redirectUrl = url.build('checkout/onepage/success'); + var message = $t("There was an error obtaining the payment token. Please try again."); + if (self.komojuToken()) { + self.sendToken(self.komojuToken()).done(function(response) { + if (response.success) { if (response.data && response.data.redirect_url) { - redirectUrl = response.data.redirect_url + redirectUrl = response.data.redirect_url; } - $.mage.redirect( - redirectUrl - ); + $.mage.redirect(redirectUrl); } else { messageList.addErrorMessage({ message: response.message }); } - }).fail(function(error) { - console.error('Error during token submission:', error); - messageList.addErrorMessage({ message: $t("There was an error processing your payment. Please try again.") }); + }).fail(function() { + message = $t("There was an error processing your payment. Please try again."); + messageList.addErrorMessage({ message: message }); fullScreenLoader.stopLoader(); }); } else { - console.error('No token available for submission.'); - messageList.addErrorMessage({ message: $t("There was an error obtaining the payment token. Please try again.") }); + messageList.addErrorMessage({ message: message }); + fullScreenLoader.stopLoader(); } }, getData: function() { - return { - 'method': this.getCode(), - 'additional_data': null - }; + return { + 'method': this.getCode(), + 'additional_data': null + }; }, placeOrder: function (data, event) { + var boundSuper = this._super.bind(this); + var self = this; + if (!this.validate()) { return false; } fullScreenLoader.startLoader(); - var boundSuper = this._super.bind(this); - - if (this.komojuFieldEnabledMethods.includes(this.komojuMethod())) { - this.submitPayment().then(token => { - this.komojuToken(token); + if (self.komojuFieldEnabledMethods.includes(self.komojuMethod())) { + self.submitPayment().then(function (token) { + self.komojuToken(token); boundSuper(data, event); - }).catch(error => { - console.error('Error during token submission:', error); - messageList.addErrorMessage({ message: $t("There was an error processing your payment. Please try again.") }); + self.afterPlaceOrder(); + }).catch(function () { + var message = $t("There was an error processing your payment. Please try again."); + + messageList.addErrorMessage({ message: message }); fullScreenLoader.stopLoader(); }); } else { - this.komojuToken(null); + self.komojuToken(null); boundSuper(data, event); + self.afterPlaceOrder(); } }, sendToken: function (token) { - if (!token) { - var redirectUrl = this.redirectUrl() + "?payment_method=" + this.komojuMethod(); - $.mage.redirect( - redirectUrl - ); - return; - } - + var redirectUrl = this.redirectUrl() + "?payment_method=" + this.komojuMethod(); var serviceUrl = url.build('komoju/komojufield/processToken'); - var data = { 'id': this.komojuSession().id, 'token': token + }; + + if (!token) { + $.mage.redirect(redirectUrl); + return; } return $.ajax({ @@ -152,7 +153,7 @@ define( type: 'POST', data: JSON.stringify(data), contentType: 'application/json', - success: function (response) { }, + success: function () {}, error: function (xhr, status, error) { console.error('Failed to send token:', error); } From 6c34119953fd79536b714ece0a055593487d5f52 Mon Sep 17 00:00:00 2001 From: Dinwy Date: Wed, 3 Jul 2024 12:44:28 +0900 Subject: [PATCH 09/15] Remove wrong afterPlaceOrder call --- .../view/frontend/web/js/view/payment/method-renderer/form.js | 3 --- 1 file changed, 3 deletions(-) diff --git a/src/app/code/Komoju/Payments/view/frontend/web/js/view/payment/method-renderer/form.js b/src/app/code/Komoju/Payments/view/frontend/web/js/view/payment/method-renderer/form.js index 75636913e..9b6a00c81 100644 --- a/src/app/code/Komoju/Payments/view/frontend/web/js/view/payment/method-renderer/form.js +++ b/src/app/code/Komoju/Payments/view/frontend/web/js/view/payment/method-renderer/form.js @@ -121,17 +121,14 @@ define( self.submitPayment().then(function (token) { self.komojuToken(token); boundSuper(data, event); - self.afterPlaceOrder(); }).catch(function () { var message = $t("There was an error processing your payment. Please try again."); - messageList.addErrorMessage({ message: message }); fullScreenLoader.stopLoader(); }); } else { self.komojuToken(null); boundSuper(data, event); - self.afterPlaceOrder(); } }, From c65b9e0e1eafd953739b18520db3f99e1da1aaf0 Mon Sep 17 00:00:00 2001 From: Dinwy Date: Wed, 3 Jul 2024 12:46:02 +0900 Subject: [PATCH 10/15] Fix js lint error --- .../view/frontend/web/js/view/payment/method-renderer/form.js | 1 + 1 file changed, 1 insertion(+) diff --git a/src/app/code/Komoju/Payments/view/frontend/web/js/view/payment/method-renderer/form.js b/src/app/code/Komoju/Payments/view/frontend/web/js/view/payment/method-renderer/form.js index 9b6a00c81..dd6596ff0 100644 --- a/src/app/code/Komoju/Payments/view/frontend/web/js/view/payment/method-renderer/form.js +++ b/src/app/code/Komoju/Payments/view/frontend/web/js/view/payment/method-renderer/form.js @@ -123,6 +123,7 @@ define( boundSuper(data, event); }).catch(function () { var message = $t("There was an error processing your payment. Please try again."); + messageList.addErrorMessage({ message: message }); fullScreenLoader.stopLoader(); }); From 8e8214ffdab125eb6f566ce42f67bb4e46e411dd Mon Sep 17 00:00:00 2001 From: Dinwy Date: Wed, 3 Jul 2024 17:09:41 +0900 Subject: [PATCH 11/15] Add publishable key in config and fix rendering issue --- .../Controller/KomojuField/ProcessToken.php | 6 +- .../Komoju/Payments/Gateway/Config/Config.php | 10 +++ .../Payments/Model/Ui/ConfigProvider.php | 1 + .../Observer/RestoreQuoteFromSession.php | 3 + .../Komoju/Payments/etc/adminhtml/system.xml | 5 ++ src/app/code/Komoju/Payments/etc/config.xml | 1 + .../js/view/payment/method-renderer/form.js | 65 +++++++++++-------- .../frontend/web/template/payment/form.html | 12 ++-- 8 files changed, 69 insertions(+), 34 deletions(-) diff --git a/src/app/code/Komoju/Payments/Controller/KomojuField/ProcessToken.php b/src/app/code/Komoju/Payments/Controller/KomojuField/ProcessToken.php index 036cf7bef..26f452694 100644 --- a/src/app/code/Komoju/Payments/Controller/KomojuField/ProcessToken.php +++ b/src/app/code/Komoju/Payments/Controller/KomojuField/ProcessToken.php @@ -10,6 +10,7 @@ use Magento\Sales\Model\Order; use Komoju\Payments\Api\KomojuApi; +use Komoju\Payments\Gateway\Config\Config; use Komoju\Payments\Model\ExternalPaymentFactory; use Komoju\Payments\Model\ExternalPayment; @@ -20,6 +21,7 @@ class ProcessToken extends Action protected JsonFactory $jsonResultFactory; protected KomojuApi $komojuApi; protected Session $checkoutSession; + protected Config $config; protected LoggerInterface $logger; protected Order $order; protected ExternalPaymentFactory $externalPaymentFactory; @@ -32,12 +34,14 @@ public function __construct( ExternalPaymentFactory $externalPaymentFactory, ExternalPayment $externalPayment, KomojuApi $komojuApi, + Config $config, LoggerInterface $logger ) { $this->jsonResultFactory = $jsonResultFactory; $this->checkoutSession = $checkoutSession; $this->externalPayment = $externalPaymentFactory->create(); $this->komojuApi = $komojuApi; + $this->config = $config; $this->logger = $logger; parent::__construct($context); } @@ -67,7 +71,7 @@ public function execute() $session = $this->komojuApi->createSession([ 'amount' => $order->getGrandTotal(), 'currency' => $currencyCode, - 'default_locale' => 'en', + 'default_locale' => $this->config->getKomojuLocale(), 'email' => $order->getCustomerEmail(), 'metadata' => ['note' => 'testing'], 'payment_data' => [ diff --git a/src/app/code/Komoju/Payments/Gateway/Config/Config.php b/src/app/code/Komoju/Payments/Gateway/Config/Config.php index 92b336bba..25eea4e14 100644 --- a/src/app/code/Komoju/Payments/Gateway/Config/Config.php +++ b/src/app/code/Komoju/Payments/Gateway/Config/Config.php @@ -80,6 +80,16 @@ public function getSecretKey($storeId = null) return $this->getValue('secret_key', $storeId); } + /** + * Returns the value of the "Publishable Key" + * @param int|null $storeId + * @return string + */ + public function getPublishableKey($storeId = null) + { + return $this->getValue('publishable_key', $storeId); + } + /** * Returns the value of the "Webhook Secret Token" on the field on the admin * page. diff --git a/src/app/code/Komoju/Payments/Model/Ui/ConfigProvider.php b/src/app/code/Komoju/Payments/Model/Ui/ConfigProvider.php index 315b8b9ef..3a7305795 100644 --- a/src/app/code/Komoju/Payments/Model/Ui/ConfigProvider.php +++ b/src/app/code/Komoju/Payments/Model/Ui/ConfigProvider.php @@ -92,6 +92,7 @@ public function getConfig() 'available_payment_methods' => $this->createPaymentMethodOptions(), 'merchant_id' => $this->config->getMerchantId(), 'redirect_url' => $this->config->getRedirectUrl(), + 'publishable_key' => $this->config->getPublishableKey(), 'show_title' => $this->config->showTitle() ] ] diff --git a/src/app/code/Komoju/Payments/Observer/RestoreQuoteFromSession.php b/src/app/code/Komoju/Payments/Observer/RestoreQuoteFromSession.php index 2668f88b3..46630cec4 100644 --- a/src/app/code/Komoju/Payments/Observer/RestoreQuoteFromSession.php +++ b/src/app/code/Komoju/Payments/Observer/RestoreQuoteFromSession.php @@ -49,6 +49,9 @@ public function execute(Observer $observer) if ($order && $order->getStatus() == Order::STATE_PENDING_PAYMENT) { $this->checkoutSession->restoreQuote(); + } else { + $this->checkoutSession->clearQuote(); + $this->checkoutSession->clearStorage(); } } } diff --git a/src/app/code/Komoju/Payments/etc/adminhtml/system.xml b/src/app/code/Komoju/Payments/etc/adminhtml/system.xml index f4ab62c3d..f27ad9986 100644 --- a/src/app/code/Komoju/Payments/etc/adminhtml/system.xml +++ b/src/app/code/Komoju/Payments/etc/adminhtml/system.xml @@ -27,6 +27,11 @@ payment/komoju_payments/secret_key Magento\Config\Model\Config\Backend\Encrypted + + + payment/komoju_payments/publishable_key + Magento\Config\Model\Config\Backend\Encrypted + The webhook URL will be at /komoju/hostedpage/webhook of this site diff --git a/src/app/code/Komoju/Payments/etc/config.xml b/src/app/code/Komoju/Payments/etc/config.xml index 7141aab73..0a3752c99 100644 --- a/src/app/code/Komoju/Payments/etc/config.xml +++ b/src/app/code/Komoju/Payments/etc/config.xml @@ -12,6 +12,7 @@ 0 + 1 diff --git a/src/app/code/Komoju/Payments/view/frontend/web/js/view/payment/method-renderer/form.js b/src/app/code/Komoju/Payments/view/frontend/web/js/view/payment/method-renderer/form.js index dd6596ff0..00c29401c 100644 --- a/src/app/code/Komoju/Payments/view/frontend/web/js/view/payment/method-renderer/form.js +++ b/src/app/code/Komoju/Payments/view/frontend/web/js/view/payment/method-renderer/form.js @@ -79,25 +79,28 @@ define( var redirectUrl = url.build('checkout/onepage/success'); var message = $t("There was an error obtaining the payment token. Please try again."); - if (self.komojuToken()) { - self.sendToken(self.komojuToken()).done(function(response) { - if (response.success) { - if (response.data && response.data.redirect_url) { - redirectUrl = response.data.redirect_url; - } - $.mage.redirect(redirectUrl); - } else { - messageList.addErrorMessage({ message: response.message }); + if (!self.komojuFieldEnabledMethods.includes(self.komojuMethod()) || !self.komojuToken()) { + redirectUrl = this.redirectUrl() + "?payment_method=" + this.komojuMethod(); + $.mage.redirect(redirectUrl); + return; + } + + self.sendToken(self.komojuToken()).done(function(response) { + if (response.success) { + if (response.data && response.data.redirect_url) { + redirectUrl = response.data.redirect_url; } - }).fail(function() { - message = $t("There was an error processing your payment. Please try again."); - messageList.addErrorMessage({ message: message }); + $.mage.redirect(redirectUrl); + } else { + messageList.addErrorMessage({ message: response.message }); fullScreenLoader.stopLoader(); - }); - } else { + } + }).fail(function(error) { + console.error('Error during token submission:', error); + message = $t("There was an error processing your payment. Please try again."); messageList.addErrorMessage({ message: message }); fullScreenLoader.stopLoader(); - } + }); }, getData: function() { @@ -108,8 +111,9 @@ define( }, placeOrder: function (data, event) { - var boundSuper = this._super.bind(this); var self = this; + var boundSuper = this._super.bind(this); + var message = $t("There was an error processing your payment. Please try again."); if (!this.validate()) { return false; @@ -117,20 +121,21 @@ define( fullScreenLoader.startLoader(); - if (self.komojuFieldEnabledMethods.includes(self.komojuMethod())) { - self.submitPayment().then(function (token) { - self.komojuToken(token); - boundSuper(data, event); - }).catch(function () { - var message = $t("There was an error processing your payment. Please try again."); - - messageList.addErrorMessage({ message: message }); - fullScreenLoader.stopLoader(); - }); - } else { + if (!self.komojuFieldEnabledMethods.includes(self.komojuMethod())) { self.komojuToken(null); boundSuper(data, event); + return; } + + self.submitPayment().then(function (token) { + self.komojuToken(token); + boundSuper(data, event); + }).catch(function (error) { + console.error('Error during token submission:', JSON.stringify(error)); + + messageList.addErrorMessage({ message: message }); + fullScreenLoader.stopLoader(); + }); }, sendToken: function (token) { @@ -196,6 +201,12 @@ define( return config.title; }, + getPublishableKey: function () { + var config = this.getConfig(); + + return config.publishable_key; + }, + getSession: function () { return JSON.stringify(this.komojuSession()); }, diff --git a/src/app/code/Komoju/Payments/view/frontend/web/template/payment/form.html b/src/app/code/Komoju/Payments/view/frontend/web/template/payment/form.html index 3ff370eca..58675dee5 100644 --- a/src/app/code/Komoju/Payments/view/frontend/web/template/payment/form.html +++ b/src/app/code/Komoju/Payments/view/frontend/web/template/payment/form.html @@ -8,7 +8,6 @@

-
+ komoju-api="https://komoju.com">
-
From 205760e6085d763a564c83c41e5e818e541eecff Mon Sep 17 00:00:00 2001 From: Dinwy Date: Thu, 4 Jul 2024 12:11:47 +0900 Subject: [PATCH 12/15] Fix locale error --- .../frontend/web/js/view/payment/method-renderer/form.js | 6 ++++++ .../Payments/view/frontend/web/template/payment/form.html | 2 +- 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/src/app/code/Komoju/Payments/view/frontend/web/js/view/payment/method-renderer/form.js b/src/app/code/Komoju/Payments/view/frontend/web/js/view/payment/method-renderer/form.js index 00c29401c..dea9eceb0 100644 --- a/src/app/code/Komoju/Payments/view/frontend/web/js/view/payment/method-renderer/form.js +++ b/src/app/code/Komoju/Payments/view/frontend/web/js/view/payment/method-renderer/form.js @@ -201,6 +201,12 @@ define( return config.title; }, + getLocale: function() { + var config = this.getConfig(); + + return config.locale; + }, + getPublishableKey: function () { var config = this.getConfig(); diff --git a/src/app/code/Komoju/Payments/view/frontend/web/template/payment/form.html b/src/app/code/Komoju/Payments/view/frontend/web/template/payment/form.html index 58675dee5..62e402a81 100644 --- a/src/app/code/Komoju/Payments/view/frontend/web/template/payment/form.html +++ b/src/app/code/Komoju/Payments/view/frontend/web/template/payment/form.html @@ -35,7 +35,7 @@

data-bind="attr: { 'session': $parent.getSession(), 'payment-type': method.value, 'publishable-key': $parent.getPublishableKey(), - 'locale': $parent.komojuSession().default_locale, + 'locale': $parent.getLocale(), }" token = "" name="komoju_payment_token" From 486803494a0951f0c68748c05a3c40d7e8e90dbf Mon Sep 17 00:00:00 2001 From: Dinwy Date: Fri, 5 Jul 2024 10:36:25 +0900 Subject: [PATCH 13/15] Fix error with wrong token --- .../Controller/KomojuField/ProcessToken.php | 24 +++++++++---------- 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/src/app/code/Komoju/Payments/Controller/KomojuField/ProcessToken.php b/src/app/code/Komoju/Payments/Controller/KomojuField/ProcessToken.php index 26f452694..ba76d4a83 100644 --- a/src/app/code/Komoju/Payments/Controller/KomojuField/ProcessToken.php +++ b/src/app/code/Komoju/Payments/Controller/KomojuField/ProcessToken.php @@ -15,6 +15,7 @@ use Komoju\Payments\Model\ExternalPayment; use Psr\Log\LoggerInterface; +use Exception; class ProcessToken extends Action { @@ -51,11 +52,7 @@ public function execute() $result = $this->jsonResultFactory->create(); $order = $this->getOrder(); - if ($order) { - $this->logger->debug('Order Data' . json_encode($order->getEntityId())); - $externalPayment = $this->createExternalPayment($order); - $this->logger->info('ExternalPayment: ' . $externalPayment); - } else { + if (!$order) { $this->logger->debug('Executing KomojuSessionData controller' . 'No order found'); return $result->setData(['success' => false, 'message' => 'No order found']); } @@ -64,9 +61,8 @@ public function execute() $postData = $this->getRequest()->getContent(); $tokenData = json_decode($postData); - // $this->logger->debug('Executing KomojuSessionData controller' . json_encode($tokenData)); - $currencyCode = $order->getOrderCurrencyCode(); + $externalPayment = $this->createExternalPayment($order); $session = $this->komojuApi->createSession([ 'amount' => $order->getGrandTotal(), @@ -82,12 +78,16 @@ public function execute() ], ]); - $data = $this->komojuApi->paySession($session->id, [ - 'customer_email' => $order->getCustomerEmail(), - 'payment_details' => $tokenData->token->id - ]); + try { + $data = $this->komojuApi->paySession($session->id, [ + 'payment_details' => (string) $tokenData->token->id + ]); - return $result->setData(['success' => true, 'message' => 'Token processed successfully', 'data' => $data]); + return $result->setData(['success' => true, 'message' => 'Token processed successfully', 'data' => $data]); + } catch (Exception $e) { + $data = ['redirect_url' => $session->session_url]; + return $result->setData(['success' => true, 'message' => 'Cannot process token, redirect', 'data' => $data]); + } } return $result->setData(['success' => false, 'message' => 'Invalid request']); From e26ffb69b1a1d6c94103f5680ae68bf2900b221f Mon Sep 17 00:00:00 2001 From: Dinwy Date: Fri, 5 Jul 2024 10:49:22 +0900 Subject: [PATCH 14/15] Fix PHP error --- .../Controller/KomojuField/ProcessToken.php | 19 ++++++++++++++----- 1 file changed, 14 insertions(+), 5 deletions(-) diff --git a/src/app/code/Komoju/Payments/Controller/KomojuField/ProcessToken.php b/src/app/code/Komoju/Payments/Controller/KomojuField/ProcessToken.php index ba76d4a83..55a41f184 100644 --- a/src/app/code/Komoju/Payments/Controller/KomojuField/ProcessToken.php +++ b/src/app/code/Komoju/Payments/Controller/KomojuField/ProcessToken.php @@ -79,14 +79,23 @@ public function execute() ]); try { - $data = $this->komojuApi->paySession($session->id, [ - 'payment_details' => (string) $tokenData->token->id + $data = $this->komojuApi->paySession( + $session->id, + ['payment_details' => (string) $tokenData->token->id] + ); + + return $result->setData([ + 'success' => true, + 'message' => 'Token processed successfully', + 'data' => $data ]); - - return $result->setData(['success' => true, 'message' => 'Token processed successfully', 'data' => $data]); } catch (Exception $e) { $data = ['redirect_url' => $session->session_url]; - return $result->setData(['success' => true, 'message' => 'Cannot process token, redirect', 'data' => $data]); + return $result->setData([ + 'success' => true, + 'message' => 'Cannot process token, redirect', + 'data' => $data + ]); } } From 0a231fc3c18c70b1ba8f038d23bac956bf41e86e Mon Sep 17 00:00:00 2001 From: Dinwy Date: Fri, 5 Jul 2024 11:24:48 +0900 Subject: [PATCH 15/15] Set return url --- .../Komoju/Payments/Controller/KomojuField/ProcessToken.php | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/app/code/Komoju/Payments/Controller/KomojuField/ProcessToken.php b/src/app/code/Komoju/Payments/Controller/KomojuField/ProcessToken.php index 55a41f184..339db519c 100644 --- a/src/app/code/Komoju/Payments/Controller/KomojuField/ProcessToken.php +++ b/src/app/code/Komoju/Payments/Controller/KomojuField/ProcessToken.php @@ -63,10 +63,12 @@ public function execute() $currencyCode = $order->getOrderCurrencyCode(); $externalPayment = $this->createExternalPayment($order); + $returnUrl = $this->_url->getUrl('checkout/onepage/success'); $session = $this->komojuApi->createSession([ 'amount' => $order->getGrandTotal(), 'currency' => $currencyCode, + 'return_url' => $returnUrl, 'default_locale' => $this->config->getKomojuLocale(), 'email' => $order->getCustomerEmail(), 'metadata' => ['note' => 'testing'],