@capgo/capacitor-data-storage-sqlite
Version:
SQLite Storage of key/value strings pair
1,045 lines (1,030 loc) • 33.8 kB
JavaScript
'use strict';
Object.defineProperty(exports, '__esModule', { value: true });
var require$$0 = require('path');
var require$$1 = require('fs');
var require$$2 = require('sqlite3');
var src = {};
var Data$1 = {};
Object.defineProperty(Data$1, "__esModule", { value: true });
Data$1.Data = void 0;
class Data {
}
Data$1.Data = Data;
var StorageDatabaseHelper$1 = {};
var UtilsSQLite$1 = {};
Object.defineProperty(UtilsSQLite$1, "__esModule", { value: true });
UtilsSQLite$1.UtilsSQLite = void 0;
class UtilsSQLite {
constructor() {
this.pathDB = "./DataStorage";
this.Path = null;
this.NodeFs = null;
this.SQLite3 = null;
this.Path = require$$0;
this.NodeFs = require$$1;
this.SQLite3 = require$$2;
}
async connection(dbName, readOnly) {
const flags = readOnly
? this.SQLite3.OPEN_READONLY
: this.SQLite3.OPEN_CREATE | this.SQLite3.OPEN_READWRITE;
// get the path for the database
try {
const dbPath = await this.getDBPath(dbName);
const dbOpen = new this.SQLite3.Database(dbPath, flags);
return Promise.resolve(dbOpen);
}
catch (err) {
return Promise.reject(err);
}
}
async getWritableDatabase(dbName) {
const db = await this.connection(dbName, false /*,secret*/);
return db;
}
async getReadableDatabase(dbName) {
const db = await this.connection(dbName, true /*,secret*/);
return db;
}
isFileExists(dbName) {
const dbFolder = this.pathDB;
const path = this.Path.join(dbFolder, dbName);
let ret = false;
try {
if (this.NodeFs.existsSync(path)) {
ret = true;
}
return Promise.resolve(ret);
}
catch (err) {
return Promise.reject(err);
}
}
async getDBPath(dbName) {
let retPath = null;
const dbFolder = this.pathDB;
retPath = this.Path.join(dbFolder, dbName);
try {
if (!this.NodeFs.existsSync(dbFolder)) {
await this.mkdirSyncRecursive(dbFolder);
}
return Promise.resolve(retPath);
}
catch (err) {
return Promise.reject(err);
}
}
async mkdirSyncRecursive(directory) {
const path = directory.replace(/\/$/, "").split("/");
for (let i = 1; i <= path.length; i++) {
const segment = path.slice(0, i).join("/");
segment.length > 0 && !this.NodeFs.existsSync(segment)
? this.NodeFs.mkdirSync(segment)
: null;
}
return;
}
}
UtilsSQLite$1.UtilsSQLite = UtilsSQLite;
Object.defineProperty(StorageDatabaseHelper$1, "__esModule", { value: true });
StorageDatabaseHelper$1.StorageDatabaseHelper = void 0;
const Data_1$1 = Data$1;
const UtilsSQLite_1 = UtilsSQLite$1;
const COL_ID = "id";
const COL_NAME = "name";
const COL_VALUE = "value";
class StorageDatabaseHelper {
constructor() {
this.Path = null;
this.NodeFs = null;
this.isOpen = false;
this.Path = require$$0;
this.NodeFs = require$$1;
this._utils = new UtilsSQLite_1.UtilsSQLite();
}
async openStore(dbName, tableName) {
try {
this.db = await this._utils.connection(dbName, false);
if (this.db !== null) {
await this._createTable(tableName);
this.dbName = dbName;
this.tableName = tableName;
this.isOpen = true;
return Promise.resolve();
}
else {
this.dbName = "";
this.tableName = "";
this.isOpen = false;
return Promise.reject(`connection to store ${dbName}`);
}
}
catch (err) {
this.dbName = "";
this.tableName = "";
this.isOpen = false;
return Promise.reject(err);
}
}
async closeStore(dbName) {
if (dbName === this.dbName && this.isOpen && this.db != null) {
try {
await this.db.close();
this.dbName = "";
this.tableName = "";
this.isOpen = false;
return Promise.resolve();
}
catch (err) {
return Promise.reject(err);
}
}
else {
return Promise.reject(`Store ${dbName} not opened`);
}
}
async isStoreExists(dbName) {
let ret = false;
try {
ret = await this._utils.isFileExists(dbName);
return Promise.resolve(ret);
}
catch (err) {
return Promise.reject(err);
}
}
async _createTable(tableName) {
const CREATE_STORAGE_TABLE = "CREATE TABLE IF NOT EXISTS " +
tableName +
"(" +
COL_ID +
" INTEGER PRIMARY KEY AUTOINCREMENT," + // Define a primary key
COL_NAME +
" TEXT NOT NULL UNIQUE," +
COL_VALUE +
" TEXT" +
")";
try {
if (this.db != null) {
return this.db.run(CREATE_STORAGE_TABLE, async (err) => {
if (err) {
return Promise.reject(`Error: in createTable ${err.message}`);
}
else {
try {
await this._createIndex(tableName);
return Promise.resolve();
}
catch (err) {
return Promise.reject(err);
}
}
});
}
else {
return Promise.reject(`connection to store ${this.dbName}`);
}
}
catch (err) {
return Promise.reject(err);
}
}
async _createIndex(tableName) {
const idx = `index_${tableName}_on_${COL_NAME}`;
const CREATE_INDEX_NAME = "CREATE INDEX IF NOT EXISTS " +
idx +
" ON " +
tableName +
" (" +
COL_NAME +
")";
try {
if (this.db != null) {
return this.db.run(CREATE_INDEX_NAME, async (err) => {
if (err) {
return Promise.reject(`Error: in createIndex ${err.message}`);
}
else {
return Promise.resolve();
}
});
}
else {
return Promise.reject(`connection to store ${this.dbName}`);
}
}
catch (err) {
return Promise.reject(err);
}
}
async setTable(tableName) {
try {
await this._createTable(tableName);
this.tableName = tableName;
return Promise.resolve();
}
catch (err) {
this.tableName = "";
return Promise.reject(err);
}
}
// Insert a data into the database
async set(data) {
if (this.db == null) {
return Promise.reject(`this.db is null in set`);
}
try {
// Check if data.name does not exist otherwise update it
const res = await this.get(data.name);
if (res.id != null) {
// exists so update it
await this.update(data);
return Promise.resolve();
}
else {
// does not exist add it
const DATA_INSERT = `INSERT INTO "${this.tableName}"
("${COL_NAME}", "${COL_VALUE}")
VALUES (?, ?)`;
return this.db.run(DATA_INSERT, [data.name, data.value], (err) => {
if (err) {
return Promise.reject(`Data INSERT: ${err.message}`);
}
else {
return Promise.resolve();
}
});
}
}
catch (err) {
return Promise.reject(err);
}
}
// get a Data
async get(name) {
return new Promise((resolve, reject) => {
if (this.db == null) {
reject(`this.db is null in get`);
}
const DATA_SELECT_QUERY = `SELECT * FROM ${this.tableName} WHERE ${COL_NAME} = '${name}'`;
this.db.all(DATA_SELECT_QUERY, (err, rows) => {
if (err) {
const data = new Data_1$1.Data();
data.id = null;
resolve(data);
}
else {
let data = new Data_1$1.Data();
if (rows.length >= 1) {
data = rows[0];
}
else {
data.id = null;
}
resolve(data);
}
});
});
}
// update a Data
async update(data) {
return new Promise((resolve, reject) => {
if (this.db == null) {
reject(`this.db is null in update`);
}
const DATA_UPDATE = `UPDATE "${this.tableName}"
SET "${COL_VALUE}" = ? WHERE "${COL_NAME}" = ?`;
this.db.run(DATA_UPDATE, [data.value, data.name], (err) => {
if (err) {
reject(`Data UPDATE: ${err.message}`);
}
else {
resolve();
}
});
});
}
// isKey exists
async iskey(name) {
if (this.db == null) {
return Promise.reject(`this.db is null in clear`);
}
try {
const res = await this.get(name);
if (res.id != null) {
return Promise.resolve(true);
}
else {
return Promise.resolve(false);
}
}
catch (err) {
return Promise.reject(err);
}
}
// remove a key
async remove(name) {
if (this.db == null) {
return Promise.reject(`this.db is null in clear`);
}
try {
const res = await this.get(name);
if (res.id != null) {
const DATA_DELETE = `DELETE FROM "${this.tableName}"
WHERE "${COL_NAME}" = ?`;
return this.db.run(DATA_DELETE, name, (err) => {
if (err) {
return Promise.reject(`Data DELETE: ${err.message}`);
}
else {
return Promise.resolve();
}
});
}
else {
return Promise.reject(`REMOVE key does not exist`);
}
}
catch (err) {
return Promise.reject(err);
}
}
// remove all keys
async clear() {
return new Promise((resolve, reject) => {
if (this.db == null) {
reject(`this.db is null in clear`);
}
const DATA_DELETE = `DELETE FROM "${this.tableName}"`;
this.db.exec(DATA_DELETE, (err) => {
if (err) {
reject(`Data CLEAR: ${err.message}`);
}
else {
// set back the key primary index to 0
const DATA_UPDATE = `UPDATE SQLITE_SEQUENCE SET SEQ = ? `;
this.db.run(DATA_UPDATE, 0, (err) => {
if (err) {
reject(`Data UPDATE SQLITE_SEQUENCE: ${err.message}`);
}
else {
resolve();
}
});
}
});
});
}
async keys() {
return new Promise((resolve, reject) => {
if (this.db == null) {
reject(`this.db is null in clear`);
}
try {
let SELECT_KEYS = `SELECT "${COL_NAME}" FROM `;
SELECT_KEYS += `"${this.tableName}" ORDER BY ${COL_NAME};`;
this.db.all(SELECT_KEYS, (err, rows) => {
if (err) {
reject(`Keys: ${err.message}`);
}
else {
let arKeys = [];
for (let i = 0; i < rows.length; i++) {
arKeys = [...arKeys, rows[i].name];
if (i === rows.length - 1) {
resolve(arKeys);
}
}
}
});
}
catch (err) {
return Promise.reject(err);
}
});
}
async values() {
return new Promise((resolve, reject) => {
if (this.db == null) {
reject(`this.db is null in clear`);
}
try {
let SELECT_VALUES = `SELECT "${COL_VALUE}" FROM `;
SELECT_VALUES += `"${this.tableName}" ORDER BY ${COL_NAME};`;
this.db.all(SELECT_VALUES, (err, rows) => {
if (err) {
reject(`Values: ${err.message}`);
}
else {
let arValues = [];
for (let i = 0; i < rows.length; i++) {
arValues = [...arValues, rows[i].value];
if (i === rows.length - 1) {
resolve(arValues);
}
}
}
});
}
catch (err) {
reject(err);
}
});
}
async filtervalues(filter) {
return new Promise((resolve, reject) => {
if (this.db == null) {
reject(`this.db is null in clear`);
}
try {
if (!filter.startsWith("%") && !filter.endsWith("%")) {
filter = "%" + filter + "%";
}
let SELECT_VALUES = `SELECT "${COL_VALUE}" FROM `;
SELECT_VALUES += `"${this.tableName}" WHERE name `;
SELECT_VALUES += `LIKE "${filter}" ORDER BY ${COL_NAME}`;
this.db.all(SELECT_VALUES, (err, rows) => {
if (err) {
reject(`FilterValues: ${err.message}`);
}
else {
let arValues = [];
for (let i = 0; i < rows.length; i++) {
arValues = [...arValues, rows[i].value];
if (i === rows.length - 1) {
resolve(arValues);
}
}
}
});
}
catch (err) {
reject(err);
}
});
}
async keysvalues() {
return new Promise((resolve, reject) => {
if (this.db == null) {
reject(`this.db is null in clear`);
}
try {
let SELECT_KEYSVALUES = `SELECT "${COL_NAME}" , "${COL_VALUE}"`;
SELECT_KEYSVALUES += ` FROM "${this.tableName}" ORDER BY ${COL_NAME};`;
this.db.all(SELECT_KEYSVALUES, (err, rows) => {
if (err) {
reject(`KeysValues: ${err.message}`);
}
else {
resolve(rows);
}
});
}
catch (err) {
reject(err);
}
});
}
async deleteStore(dbName) {
const dbPath = this.Path.join(this._utils.pathDB, dbName);
try {
this.NodeFs.unlinkSync(dbPath);
//file removed
return Promise.resolve();
}
catch (err) {
return Promise.reject(err);
}
}
async isTable(table) {
return new Promise((resolve, reject) => {
if (this.db == null) {
reject(`isTable: this.db is null`);
}
try {
let ret = false;
const SELECT_TABLES = "SELECT name FROM sqlite_master " + "WHERE TYPE='table';";
this.db.all(SELECT_TABLES, (err, rows) => {
if (err) {
reject(`isTable: ${err.message}`);
}
else {
let arTables = [];
for (let i = 0; i < rows.length; i++) {
arTables = [...arTables, rows[i].name];
if (i === rows.length - 1) {
if (arTables.includes(table))
ret = true;
resolve(ret);
}
}
}
});
}
catch (err) {
return Promise.reject(err);
}
});
}
async tables() {
return new Promise((resolve, reject) => {
try {
const SELECT_TABLES = "SELECT name FROM sqlite_master " +
"WHERE TYPE='table' ORDER BY name;";
this.db.all(SELECT_TABLES, (err, rows) => {
if (err) {
reject(`tables: ${err.message}`);
}
else {
let arTables = [];
for (let i = 0; i < rows.length; i++) {
if (rows[i].name != "sqlite_sequence") {
arTables = [...arTables, rows[i].name];
}
if (i === rows.length - 1) {
resolve(arTables);
}
}
}
});
}
catch (err) {
return Promise.reject(err);
}
});
}
async deleteTable(table) {
if (this.db == null) {
return Promise.reject(`this.db is null in deleteTable`);
}
try {
const ret = await this.isTable(table);
if (ret) {
const DROP_STMT = `DROP TABLE IF EXISTS ${table};`;
return this.db.exec(DROP_STMT, (err) => {
if (err) {
return Promise.reject(`deleteTable: ${err.message}`);
}
else {
return Promise.resolve();
}
});
}
else {
return Promise.resolve();
}
}
catch (err) {
return Promise.reject(err);
}
}
async importJson(values) {
let changes = 0;
for (const val of values) {
try {
const data = new Data_1$1.Data();
data.name = val.key;
data.value = val.value;
await this.set(data);
changes += 1;
}
catch (err) {
return Promise.reject(err);
}
}
return Promise.resolve(changes);
}
async exportJson() {
const retJson = {};
try {
const prevTableName = this.tableName;
retJson.database = this.dbName.slice(0, -9);
retJson.encrypted = false;
retJson.tables = [];
// get the table list
const tables = await this.tables();
for (const table of tables) {
this.tableName = table;
const retTable = {};
retTable.name = table;
retTable.values = [];
const dataTable = await this.keysvalues();
for (const tdata of dataTable) {
const retData = {};
retData.key = tdata.name;
retData.value = tdata.value;
retTable.values = [...retTable.values, retData];
}
retJson.tables = [...retJson.tables, retTable];
}
this.tableName = prevTableName;
return Promise.resolve(retJson);
}
catch (err) {
return Promise.reject(err);
}
}
}
StorageDatabaseHelper$1.StorageDatabaseHelper = StorageDatabaseHelper;
var jsonUtils = {};
(function (exports) {
Object.defineProperty(exports, "__esModule", { value: true });
exports.isValue = exports.isTable = exports.isJsonStore = void 0;
/**
* IsJsonSQLite
* @param obj
*/
const isJsonStore = (obj) => {
const keyFirstLevel = ["database", "encrypted", "tables"];
if (obj == null ||
(Object.keys(obj).length === 0 && obj.constructor === Object))
return false;
for (const key of Object.keys(obj)) {
if (keyFirstLevel.indexOf(key) === -1)
return false;
if (key === "database" && typeof obj[key] != "string")
return false;
if (key === "encrypted" && typeof obj[key] != "boolean")
return false;
if (key === "tables" && typeof obj[key] != "object")
return false;
if (key === "tables") {
for (const oKey of obj[key]) {
const retTable = (0, exports.isTable)(oKey);
if (!retTable)
return false;
}
}
}
return true;
};
exports.isJsonStore = isJsonStore;
/**
* IsTable
* @param obj
*/
const isTable = (obj) => {
const keyTableLevel = ["name", "values"];
if (obj == null ||
(Object.keys(obj).length === 0 && obj.constructor === Object)) {
return false;
}
for (const key of Object.keys(obj)) {
if (keyTableLevel.indexOf(key) === -1)
return false;
if (key === "name" && typeof obj[key] != "string")
return false;
if (key === "values" && typeof obj[key] != "object")
return false;
if (key === "values") {
for (const oKey of obj[key]) {
const retValue = (0, exports.isValue)(oKey);
if (!retValue)
return false;
}
}
}
return true;
};
exports.isTable = isTable;
/**
* IsValue
* @param obj
*/
const isValue = (obj) => {
const keyTableLevel = ["key", "value"];
if (obj == null ||
(Object.keys(obj).length === 0 && obj.constructor === Object)) {
return false;
}
for (const key of Object.keys(obj)) {
if (keyTableLevel.indexOf(key) === -1)
return false;
if (key === "key" && typeof obj[key] != "string")
return false;
if (key === "value" && typeof obj[key] != "string")
return false;
}
return true;
};
exports.isValue = isValue;
} (jsonUtils));
Object.defineProperty(src, "__esModule", { value: true });
exports.CapgoCapacitorDataStorageSqlite = src.CapgoCapacitorDataStorageSqlite = void 0;
const Data_1 = Data$1;
const StorageDatabaseHelper_1 = StorageDatabaseHelper$1;
const json_utils_1 = jsonUtils;
class CapgoCapacitorDataStorageSqlite {
constructor() {
this.mDb = new StorageDatabaseHelper_1.StorageDatabaseHelper();
}
async echo(options) {
const ret = {};
ret.value = options.value ? options.value : "";
return Promise.resolve(ret);
}
async openStore(options) {
const dbName = options.database
? `${options.database}SQLite.db`
: "storageSQLite.db";
const tableName = options.table ? options.table : "storage_store";
try {
await this.mDb.openStore(dbName, tableName);
return Promise.resolve();
}
catch (err) {
return Promise.reject(err);
}
}
async closeStore(options) {
const dbName = options.database
? `${options.database}SQLite.db`
: "storageSQLite.db";
if (this.mDb.dbName === dbName && this.mDb.isOpen) {
try {
await this.mDb.closeStore(dbName);
return Promise.resolve();
}
catch (err) {
return Promise.reject(err);
}
}
else {
return Promise.resolve();
}
}
async isStoreOpen(options) {
const dbName = options.database
? `${options.database}SQLite.db`
: "storageSQLite.db";
let ret = false;
if (this.mDb.dbName === dbName && this.mDb.isOpen) {
ret = true;
}
return Promise.resolve({ result: ret });
}
async isStoreExists(options) {
const dbName = options.database
? `${options.database}SQLite.db`
: "storageSQLite.db";
let ret = false;
try {
ret = await this.mDb.isStoreExists(dbName);
return Promise.resolve({ result: ret });
}
catch (err) {
return Promise.reject(err);
}
}
async setTable(options) {
const tableName = options.table;
if (tableName == null) {
return Promise.reject("Must provide a table name");
}
try {
await this.mDb.setTable(tableName);
return Promise.resolve();
}
catch (err) {
return Promise.reject("Must open a store first");
}
}
async set(options) {
const key = options.key;
if (key == null) {
return Promise.reject("Must provide key");
}
const value = options.value;
if (value == null) {
return Promise.reject("Must provide value");
}
const data = new Data_1.Data();
data.name = key;
data.value = value;
try {
await this.mDb.set(data);
return Promise.resolve();
}
catch (err) {
return Promise.reject(err);
}
}
async get(options) {
let ret;
const key = options.key;
if (key == null) {
return Promise.reject("Must provide key");
}
try {
const data = await this.mDb.get(key);
ret = (data === null || data === void 0 ? void 0 : data.id) != null ? data.value : "";
return Promise.resolve({ value: ret });
}
catch (err) {
return Promise.reject(err);
}
}
async remove(options) {
try {
const key = options.key;
if (key == null) {
return Promise.reject("Must provide key");
}
await this.mDb.remove(key);
return Promise.resolve();
}
catch (err) {
return Promise.reject(err);
}
}
async clear() {
try {
await this.mDb.clear();
return Promise.resolve();
}
catch (err) {
return Promise.reject(err);
}
}
async iskey(options) {
let ret;
const key = options.key;
if (key == null) {
return Promise.reject("Must provide key");
}
try {
ret = await this.mDb.iskey(key);
return Promise.resolve({ result: ret });
}
catch (err) {
return Promise.reject(err);
}
}
async keys() {
try {
const ret = await this.mDb.keys();
return Promise.resolve({ keys: ret });
}
catch (err) {
return Promise.reject(err);
}
}
async values() {
try {
const ret = await this.mDb.values();
return Promise.resolve({ values: ret });
}
catch (err) {
return Promise.reject(err);
}
}
async filtervalues(options) {
const filter = options.filter;
if (filter == null || typeof filter != "string") {
return Promise.reject("Must Must provide filter as string");
}
try {
const ret = await this.mDb.filtervalues(filter);
return Promise.resolve({ values: ret });
}
catch (err) {
return Promise.reject(err);
}
}
async keysvalues() {
const ret = [];
try {
const results = await this.mDb.keysvalues();
for (const result of results) {
const res = { key: result.name, value: result.value };
ret.push(res);
}
return Promise.resolve({ keysvalues: ret });
}
catch (err) {
return Promise.reject(err);
}
}
async deleteStore(options) {
let dbName = options.database;
if (dbName == null) {
return Promise.reject("Must provide a Database Name");
}
dbName = `${options.database}SQLite.db`;
try {
await this.mDb.deleteStore(dbName);
return Promise.resolve();
}
catch (err) {
return Promise.reject(err);
}
}
async isTable(options) {
const table = options.table;
if (table == null) {
return Promise.reject("Must provide a Table Name");
}
try {
const ret = await this.mDb.isTable(table);
return Promise.resolve({ result: ret });
}
catch (err) {
return Promise.reject(err);
}
}
async tables() {
try {
const ret = await this.mDb.tables();
return Promise.resolve({ tables: ret });
}
catch (err) {
return Promise.reject(err);
}
}
async deleteTable(options) {
const table = options.table;
if (table == null) {
return Promise.reject("Must provide a Table Name");
}
try {
await this.mDb.deleteTable(table);
return Promise.resolve();
}
catch (err) {
return Promise.reject(err);
}
}
async importFromJson(options) {
const keys = Object.keys(options);
if (!keys.includes("jsonstring")) {
return Promise.reject("Must provide a json object");
}
let totalChanges = 0;
if (options === null || options === void 0 ? void 0 : options.jsonstring) {
const jsonStrObj = options.jsonstring;
const jsonObj = JSON.parse(jsonStrObj);
const isValid = (0, json_utils_1.isJsonStore)(jsonObj);
if (!isValid) {
return Promise.reject("Must provide a valid JsonSQLite Object");
}
const vJsonObj = jsonObj;
const dbName = vJsonObj.database
? `${vJsonObj.database}SQLite.db`
: "storageSQLite.db";
for (const table of vJsonObj.tables) {
const tableName = table.name ? table.name : "storage_store";
try {
// Open the database
await this.mDb.openStore(dbName, tableName);
// Import the JsonSQLite Object
if (table === null || table === void 0 ? void 0 : table.values) {
const changes = await this.mDb.importJson(table.values);
totalChanges += changes;
}
}
catch (err) {
return Promise.reject(`ImportFromJson: ${err}`);
}
finally {
await this.mDb.closeStore(dbName);
}
}
return Promise.resolve({ changes: totalChanges });
}
else {
return Promise.reject("Must provide a json object");
}
}
async isJsonValid(options) {
const keys = Object.keys(options);
if (!keys.includes("jsonstring")) {
return Promise.reject("Must provide a json object");
}
if (options === null || options === void 0 ? void 0 : options.jsonstring) {
const jsonStrObj = options.jsonstring;
const jsonObj = JSON.parse(jsonStrObj);
const isValid = (0, json_utils_1.isJsonStore)(jsonObj);
if (!isValid) {
return Promise.reject("Stringify Json Object not Valid");
}
else {
return Promise.resolve({ result: true });
}
}
else {
return Promise.reject("Must provide in options a stringify Json Object");
}
}
async exportToJson() {
try {
const ret = await this.mDb.exportJson();
return Promise.resolve({ export: ret });
}
catch (err) {
return Promise.reject(`exportToJson: ${err.message}`);
}
}
}
exports.CapgoCapacitorDataStorageSqlite = src.CapgoCapacitorDataStorageSqlite = CapgoCapacitorDataStorageSqlite;
exports.default = src;
//# sourceMappingURL=plugin.js.map