index.cjs.js 22 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593
  1. /*! Capacitor: https://capacitorjs.com/ - MIT License */
  2. 'use strict';
  3. Object.defineProperty(exports, '__esModule', { value: true });
  4. exports.ExceptionCode = void 0;
  5. (function (ExceptionCode) {
  6. /**
  7. * API is not implemented.
  8. *
  9. * This usually means the API can't be used because it is not implemented for
  10. * the current platform.
  11. */
  12. ExceptionCode["Unimplemented"] = "UNIMPLEMENTED";
  13. /**
  14. * API is not available.
  15. *
  16. * This means the API can't be used right now because:
  17. * - it is currently missing a prerequisite, such as network connectivity
  18. * - it requires a particular platform or browser version
  19. */
  20. ExceptionCode["Unavailable"] = "UNAVAILABLE";
  21. })(exports.ExceptionCode || (exports.ExceptionCode = {}));
  22. class CapacitorException extends Error {
  23. constructor(message, code, data) {
  24. super(message);
  25. this.message = message;
  26. this.code = code;
  27. this.data = data;
  28. }
  29. }
  30. const getPlatformId = (win) => {
  31. var _a, _b;
  32. if (win === null || win === void 0 ? void 0 : win.androidBridge) {
  33. return 'android';
  34. }
  35. else if ((_b = (_a = win === null || win === void 0 ? void 0 : win.webkit) === null || _a === void 0 ? void 0 : _a.messageHandlers) === null || _b === void 0 ? void 0 : _b.bridge) {
  36. return 'ios';
  37. }
  38. else {
  39. return 'web';
  40. }
  41. };
  42. const createCapacitor = (win) => {
  43. const capCustomPlatform = win.CapacitorCustomPlatform || null;
  44. const cap = win.Capacitor || {};
  45. const Plugins = (cap.Plugins = cap.Plugins || {});
  46. const getPlatform = () => {
  47. return capCustomPlatform !== null ? capCustomPlatform.name : getPlatformId(win);
  48. };
  49. const isNativePlatform = () => getPlatform() !== 'web';
  50. const isPluginAvailable = (pluginName) => {
  51. const plugin = registeredPlugins.get(pluginName);
  52. if (plugin === null || plugin === void 0 ? void 0 : plugin.platforms.has(getPlatform())) {
  53. // JS implementation available for the current platform.
  54. return true;
  55. }
  56. if (getPluginHeader(pluginName)) {
  57. // Native implementation available.
  58. return true;
  59. }
  60. return false;
  61. };
  62. const getPluginHeader = (pluginName) => { var _a; return (_a = cap.PluginHeaders) === null || _a === void 0 ? void 0 : _a.find((h) => h.name === pluginName); };
  63. const handleError = (err) => win.console.error(err);
  64. const registeredPlugins = new Map();
  65. const registerPlugin = (pluginName, jsImplementations = {}) => {
  66. const registeredPlugin = registeredPlugins.get(pluginName);
  67. if (registeredPlugin) {
  68. console.warn(`Capacitor plugin "${pluginName}" already registered. Cannot register plugins twice.`);
  69. return registeredPlugin.proxy;
  70. }
  71. const platform = getPlatform();
  72. const pluginHeader = getPluginHeader(pluginName);
  73. let jsImplementation;
  74. const loadPluginImplementation = async () => {
  75. if (!jsImplementation && platform in jsImplementations) {
  76. jsImplementation =
  77. typeof jsImplementations[platform] === 'function'
  78. ? (jsImplementation = await jsImplementations[platform]())
  79. : (jsImplementation = jsImplementations[platform]);
  80. }
  81. else if (capCustomPlatform !== null && !jsImplementation && 'web' in jsImplementations) {
  82. jsImplementation =
  83. typeof jsImplementations['web'] === 'function'
  84. ? (jsImplementation = await jsImplementations['web']())
  85. : (jsImplementation = jsImplementations['web']);
  86. }
  87. return jsImplementation;
  88. };
  89. const createPluginMethod = (impl, prop) => {
  90. var _a, _b;
  91. if (pluginHeader) {
  92. const methodHeader = pluginHeader === null || pluginHeader === void 0 ? void 0 : pluginHeader.methods.find((m) => prop === m.name);
  93. if (methodHeader) {
  94. if (methodHeader.rtype === 'promise') {
  95. return (options) => cap.nativePromise(pluginName, prop.toString(), options);
  96. }
  97. else {
  98. return (options, callback) => cap.nativeCallback(pluginName, prop.toString(), options, callback);
  99. }
  100. }
  101. else if (impl) {
  102. return (_a = impl[prop]) === null || _a === void 0 ? void 0 : _a.bind(impl);
  103. }
  104. }
  105. else if (impl) {
  106. return (_b = impl[prop]) === null || _b === void 0 ? void 0 : _b.bind(impl);
  107. }
  108. else {
  109. throw new CapacitorException(`"${pluginName}" plugin is not implemented on ${platform}`, exports.ExceptionCode.Unimplemented);
  110. }
  111. };
  112. const createPluginMethodWrapper = (prop) => {
  113. let remove;
  114. const wrapper = (...args) => {
  115. const p = loadPluginImplementation().then((impl) => {
  116. const fn = createPluginMethod(impl, prop);
  117. if (fn) {
  118. const p = fn(...args);
  119. remove = p === null || p === void 0 ? void 0 : p.remove;
  120. return p;
  121. }
  122. else {
  123. throw new CapacitorException(`"${pluginName}.${prop}()" is not implemented on ${platform}`, exports.ExceptionCode.Unimplemented);
  124. }
  125. });
  126. if (prop === 'addListener') {
  127. p.remove = async () => remove();
  128. }
  129. return p;
  130. };
  131. // Some flair ✨
  132. wrapper.toString = () => `${prop.toString()}() { [capacitor code] }`;
  133. Object.defineProperty(wrapper, 'name', {
  134. value: prop,
  135. writable: false,
  136. configurable: false,
  137. });
  138. return wrapper;
  139. };
  140. const addListener = createPluginMethodWrapper('addListener');
  141. const removeListener = createPluginMethodWrapper('removeListener');
  142. const addListenerNative = (eventName, callback) => {
  143. const call = addListener({ eventName }, callback);
  144. const remove = async () => {
  145. const callbackId = await call;
  146. removeListener({
  147. eventName,
  148. callbackId,
  149. }, callback);
  150. };
  151. const p = new Promise((resolve) => call.then(() => resolve({ remove })));
  152. p.remove = async () => {
  153. console.warn(`Using addListener() without 'await' is deprecated.`);
  154. await remove();
  155. };
  156. return p;
  157. };
  158. const proxy = new Proxy({}, {
  159. get(_, prop) {
  160. switch (prop) {
  161. // https://github.com/facebook/react/issues/20030
  162. case '$$typeof':
  163. return undefined;
  164. case 'toJSON':
  165. return () => ({});
  166. case 'addListener':
  167. return pluginHeader ? addListenerNative : addListener;
  168. case 'removeListener':
  169. return removeListener;
  170. default:
  171. return createPluginMethodWrapper(prop);
  172. }
  173. },
  174. });
  175. Plugins[pluginName] = proxy;
  176. registeredPlugins.set(pluginName, {
  177. name: pluginName,
  178. proxy,
  179. platforms: new Set([...Object.keys(jsImplementations), ...(pluginHeader ? [platform] : [])]),
  180. });
  181. return proxy;
  182. };
  183. // Add in convertFileSrc for web, it will already be available in native context
  184. if (!cap.convertFileSrc) {
  185. cap.convertFileSrc = (filePath) => filePath;
  186. }
  187. cap.getPlatform = getPlatform;
  188. cap.handleError = handleError;
  189. cap.isNativePlatform = isNativePlatform;
  190. cap.isPluginAvailable = isPluginAvailable;
  191. cap.registerPlugin = registerPlugin;
  192. cap.Exception = CapacitorException;
  193. cap.DEBUG = !!cap.DEBUG;
  194. cap.isLoggingEnabled = !!cap.isLoggingEnabled;
  195. return cap;
  196. };
  197. const initCapacitorGlobal = (win) => (win.Capacitor = createCapacitor(win));
  198. const Capacitor = /*#__PURE__*/ initCapacitorGlobal(typeof globalThis !== 'undefined'
  199. ? globalThis
  200. : typeof self !== 'undefined'
  201. ? self
  202. : typeof window !== 'undefined'
  203. ? window
  204. : typeof global !== 'undefined'
  205. ? global
  206. : {});
  207. const registerPlugin = Capacitor.registerPlugin;
  208. /**
  209. * Base class web plugins should extend.
  210. */
  211. class WebPlugin {
  212. constructor() {
  213. this.listeners = {};
  214. this.retainedEventArguments = {};
  215. this.windowListeners = {};
  216. }
  217. addListener(eventName, listenerFunc) {
  218. let firstListener = false;
  219. const listeners = this.listeners[eventName];
  220. if (!listeners) {
  221. this.listeners[eventName] = [];
  222. firstListener = true;
  223. }
  224. this.listeners[eventName].push(listenerFunc);
  225. // If we haven't added a window listener for this event and it requires one,
  226. // go ahead and add it
  227. const windowListener = this.windowListeners[eventName];
  228. if (windowListener && !windowListener.registered) {
  229. this.addWindowListener(windowListener);
  230. }
  231. if (firstListener) {
  232. this.sendRetainedArgumentsForEvent(eventName);
  233. }
  234. const remove = async () => this.removeListener(eventName, listenerFunc);
  235. const p = Promise.resolve({ remove });
  236. return p;
  237. }
  238. async removeAllListeners() {
  239. this.listeners = {};
  240. for (const listener in this.windowListeners) {
  241. this.removeWindowListener(this.windowListeners[listener]);
  242. }
  243. this.windowListeners = {};
  244. }
  245. notifyListeners(eventName, data, retainUntilConsumed) {
  246. const listeners = this.listeners[eventName];
  247. if (!listeners) {
  248. if (retainUntilConsumed) {
  249. let args = this.retainedEventArguments[eventName];
  250. if (!args) {
  251. args = [];
  252. }
  253. args.push(data);
  254. this.retainedEventArguments[eventName] = args;
  255. }
  256. return;
  257. }
  258. listeners.forEach((listener) => listener(data));
  259. }
  260. hasListeners(eventName) {
  261. return !!this.listeners[eventName].length;
  262. }
  263. registerWindowListener(windowEventName, pluginEventName) {
  264. this.windowListeners[pluginEventName] = {
  265. registered: false,
  266. windowEventName,
  267. pluginEventName,
  268. handler: (event) => {
  269. this.notifyListeners(pluginEventName, event);
  270. },
  271. };
  272. }
  273. unimplemented(msg = 'not implemented') {
  274. return new Capacitor.Exception(msg, exports.ExceptionCode.Unimplemented);
  275. }
  276. unavailable(msg = 'not available') {
  277. return new Capacitor.Exception(msg, exports.ExceptionCode.Unavailable);
  278. }
  279. async removeListener(eventName, listenerFunc) {
  280. const listeners = this.listeners[eventName];
  281. if (!listeners) {
  282. return;
  283. }
  284. const index = listeners.indexOf(listenerFunc);
  285. this.listeners[eventName].splice(index, 1);
  286. // If there are no more listeners for this type of event,
  287. // remove the window listener
  288. if (!this.listeners[eventName].length) {
  289. this.removeWindowListener(this.windowListeners[eventName]);
  290. }
  291. }
  292. addWindowListener(handle) {
  293. window.addEventListener(handle.windowEventName, handle.handler);
  294. handle.registered = true;
  295. }
  296. removeWindowListener(handle) {
  297. if (!handle) {
  298. return;
  299. }
  300. window.removeEventListener(handle.windowEventName, handle.handler);
  301. handle.registered = false;
  302. }
  303. sendRetainedArgumentsForEvent(eventName) {
  304. const args = this.retainedEventArguments[eventName];
  305. if (!args) {
  306. return;
  307. }
  308. delete this.retainedEventArguments[eventName];
  309. args.forEach((arg) => {
  310. this.notifyListeners(eventName, arg);
  311. });
  312. }
  313. }
  314. const WebView = /*#__PURE__*/ registerPlugin('WebView');
  315. /******** END WEB VIEW PLUGIN ********/
  316. /******** COOKIES PLUGIN ********/
  317. /**
  318. * Safely web encode a string value (inspired by js-cookie)
  319. * @param str The string value to encode
  320. */
  321. const encode = (str) => encodeURIComponent(str)
  322. .replace(/%(2[346B]|5E|60|7C)/g, decodeURIComponent)
  323. .replace(/[()]/g, escape);
  324. /**
  325. * Safely web decode a string value (inspired by js-cookie)
  326. * @param str The string value to decode
  327. */
  328. const decode = (str) => str.replace(/(%[\dA-F]{2})+/gi, decodeURIComponent);
  329. class CapacitorCookiesPluginWeb extends WebPlugin {
  330. async getCookies() {
  331. const cookies = document.cookie;
  332. const cookieMap = {};
  333. cookies.split(';').forEach((cookie) => {
  334. if (cookie.length <= 0)
  335. return;
  336. // Replace first "=" with CAP_COOKIE to prevent splitting on additional "="
  337. let [key, value] = cookie.replace(/=/, 'CAP_COOKIE').split('CAP_COOKIE');
  338. key = decode(key).trim();
  339. value = decode(value).trim();
  340. cookieMap[key] = value;
  341. });
  342. return cookieMap;
  343. }
  344. async setCookie(options) {
  345. try {
  346. // Safely Encoded Key/Value
  347. const encodedKey = encode(options.key);
  348. const encodedValue = encode(options.value);
  349. // Clean & sanitize options
  350. const expires = `; expires=${(options.expires || '').replace('expires=', '')}`; // Default is "; expires="
  351. const path = (options.path || '/').replace('path=', ''); // Default is "path=/"
  352. const domain = options.url != null && options.url.length > 0 ? `domain=${options.url}` : '';
  353. document.cookie = `${encodedKey}=${encodedValue || ''}${expires}; path=${path}; ${domain};`;
  354. }
  355. catch (error) {
  356. return Promise.reject(error);
  357. }
  358. }
  359. async deleteCookie(options) {
  360. try {
  361. document.cookie = `${options.key}=; Max-Age=0`;
  362. }
  363. catch (error) {
  364. return Promise.reject(error);
  365. }
  366. }
  367. async clearCookies() {
  368. try {
  369. const cookies = document.cookie.split(';') || [];
  370. for (const cookie of cookies) {
  371. document.cookie = cookie.replace(/^ +/, '').replace(/=.*/, `=;expires=${new Date().toUTCString()};path=/`);
  372. }
  373. }
  374. catch (error) {
  375. return Promise.reject(error);
  376. }
  377. }
  378. async clearAllCookies() {
  379. try {
  380. await this.clearCookies();
  381. }
  382. catch (error) {
  383. return Promise.reject(error);
  384. }
  385. }
  386. }
  387. const CapacitorCookies = registerPlugin('CapacitorCookies', {
  388. web: () => new CapacitorCookiesPluginWeb(),
  389. });
  390. // UTILITY FUNCTIONS
  391. /**
  392. * Read in a Blob value and return it as a base64 string
  393. * @param blob The blob value to convert to a base64 string
  394. */
  395. const readBlobAsBase64 = async (blob) => new Promise((resolve, reject) => {
  396. const reader = new FileReader();
  397. reader.onload = () => {
  398. const base64String = reader.result;
  399. // remove prefix "data:application/pdf;base64,"
  400. resolve(base64String.indexOf(',') >= 0 ? base64String.split(',')[1] : base64String);
  401. };
  402. reader.onerror = (error) => reject(error);
  403. reader.readAsDataURL(blob);
  404. });
  405. /**
  406. * Normalize an HttpHeaders map by lowercasing all of the values
  407. * @param headers The HttpHeaders object to normalize
  408. */
  409. const normalizeHttpHeaders = (headers = {}) => {
  410. const originalKeys = Object.keys(headers);
  411. const loweredKeys = Object.keys(headers).map((k) => k.toLocaleLowerCase());
  412. const normalized = loweredKeys.reduce((acc, key, index) => {
  413. acc[key] = headers[originalKeys[index]];
  414. return acc;
  415. }, {});
  416. return normalized;
  417. };
  418. /**
  419. * Builds a string of url parameters that
  420. * @param params A map of url parameters
  421. * @param shouldEncode true if you should encodeURIComponent() the values (true by default)
  422. */
  423. const buildUrlParams = (params, shouldEncode = true) => {
  424. if (!params)
  425. return null;
  426. const output = Object.entries(params).reduce((accumulator, entry) => {
  427. const [key, value] = entry;
  428. let encodedValue;
  429. let item;
  430. if (Array.isArray(value)) {
  431. item = '';
  432. value.forEach((str) => {
  433. encodedValue = shouldEncode ? encodeURIComponent(str) : str;
  434. item += `${key}=${encodedValue}&`;
  435. });
  436. // last character will always be "&" so slice it off
  437. item.slice(0, -1);
  438. }
  439. else {
  440. encodedValue = shouldEncode ? encodeURIComponent(value) : value;
  441. item = `${key}=${encodedValue}`;
  442. }
  443. return `${accumulator}&${item}`;
  444. }, '');
  445. // Remove initial "&" from the reduce
  446. return output.substr(1);
  447. };
  448. /**
  449. * Build the RequestInit object based on the options passed into the initial request
  450. * @param options The Http plugin options
  451. * @param extra Any extra RequestInit values
  452. */
  453. const buildRequestInit = (options, extra = {}) => {
  454. const output = Object.assign({ method: options.method || 'GET', headers: options.headers }, extra);
  455. // Get the content-type
  456. const headers = normalizeHttpHeaders(options.headers);
  457. const type = headers['content-type'] || '';
  458. // If body is already a string, then pass it through as-is.
  459. if (typeof options.data === 'string') {
  460. output.body = options.data;
  461. }
  462. // Build request initializers based off of content-type
  463. else if (type.includes('application/x-www-form-urlencoded')) {
  464. const params = new URLSearchParams();
  465. for (const [key, value] of Object.entries(options.data || {})) {
  466. params.set(key, value);
  467. }
  468. output.body = params.toString();
  469. }
  470. else if (type.includes('multipart/form-data') || options.data instanceof FormData) {
  471. const form = new FormData();
  472. if (options.data instanceof FormData) {
  473. options.data.forEach((value, key) => {
  474. form.append(key, value);
  475. });
  476. }
  477. else {
  478. for (const key of Object.keys(options.data)) {
  479. form.append(key, options.data[key]);
  480. }
  481. }
  482. output.body = form;
  483. const headers = new Headers(output.headers);
  484. headers.delete('content-type'); // content-type will be set by `window.fetch` to includy boundary
  485. output.headers = headers;
  486. }
  487. else if (type.includes('application/json') || typeof options.data === 'object') {
  488. output.body = JSON.stringify(options.data);
  489. }
  490. return output;
  491. };
  492. // WEB IMPLEMENTATION
  493. class CapacitorHttpPluginWeb extends WebPlugin {
  494. /**
  495. * Perform an Http request given a set of options
  496. * @param options Options to build the HTTP request
  497. */
  498. async request(options) {
  499. const requestInit = buildRequestInit(options, options.webFetchExtra);
  500. const urlParams = buildUrlParams(options.params, options.shouldEncodeUrlParams);
  501. const url = urlParams ? `${options.url}?${urlParams}` : options.url;
  502. const response = await fetch(url, requestInit);
  503. const contentType = response.headers.get('content-type') || '';
  504. // Default to 'text' responseType so no parsing happens
  505. let { responseType = 'text' } = response.ok ? options : {};
  506. // If the response content-type is json, force the response to be json
  507. if (contentType.includes('application/json')) {
  508. responseType = 'json';
  509. }
  510. let data;
  511. let blob;
  512. switch (responseType) {
  513. case 'arraybuffer':
  514. case 'blob':
  515. blob = await response.blob();
  516. data = await readBlobAsBase64(blob);
  517. break;
  518. case 'json':
  519. data = await response.json();
  520. break;
  521. case 'document':
  522. case 'text':
  523. default:
  524. data = await response.text();
  525. }
  526. // Convert fetch headers to Capacitor HttpHeaders
  527. const headers = {};
  528. response.headers.forEach((value, key) => {
  529. headers[key] = value;
  530. });
  531. return {
  532. data,
  533. headers,
  534. status: response.status,
  535. url: response.url,
  536. };
  537. }
  538. /**
  539. * Perform an Http GET request given a set of options
  540. * @param options Options to build the HTTP request
  541. */
  542. async get(options) {
  543. return this.request(Object.assign(Object.assign({}, options), { method: 'GET' }));
  544. }
  545. /**
  546. * Perform an Http POST request given a set of options
  547. * @param options Options to build the HTTP request
  548. */
  549. async post(options) {
  550. return this.request(Object.assign(Object.assign({}, options), { method: 'POST' }));
  551. }
  552. /**
  553. * Perform an Http PUT request given a set of options
  554. * @param options Options to build the HTTP request
  555. */
  556. async put(options) {
  557. return this.request(Object.assign(Object.assign({}, options), { method: 'PUT' }));
  558. }
  559. /**
  560. * Perform an Http PATCH request given a set of options
  561. * @param options Options to build the HTTP request
  562. */
  563. async patch(options) {
  564. return this.request(Object.assign(Object.assign({}, options), { method: 'PATCH' }));
  565. }
  566. /**
  567. * Perform an Http DELETE request given a set of options
  568. * @param options Options to build the HTTP request
  569. */
  570. async delete(options) {
  571. return this.request(Object.assign(Object.assign({}, options), { method: 'DELETE' }));
  572. }
  573. }
  574. const CapacitorHttp = registerPlugin('CapacitorHttp', {
  575. web: () => new CapacitorHttpPluginWeb(),
  576. });
  577. /******** END HTTP PLUGIN ********/
  578. exports.Capacitor = Capacitor;
  579. exports.CapacitorCookies = CapacitorCookies;
  580. exports.CapacitorException = CapacitorException;
  581. exports.CapacitorHttp = CapacitorHttp;
  582. exports.WebPlugin = WebPlugin;
  583. exports.WebView = WebView;
  584. exports.buildRequestInit = buildRequestInit;
  585. exports.registerPlugin = registerPlugin;
  586. //# sourceMappingURL=index.cjs.js.map