diff --git a/frappe/backends/http.js b/frappe/backends/http.js deleted file mode 100644 index 57af0f0e..00000000 --- a/frappe/backends/http.js +++ /dev/null @@ -1,235 +0,0 @@ -const frappe = require('frappe'); -const Observable = require('frappe/utils/observable'); -const triggerEvent = (name) => frappe.events.trigger(`http:${name}`); - -module.exports = class HTTPClient extends Observable { - constructor({ server, protocol = 'http' }) { - super(); - - this.server = server; - this.protocol = protocol; - frappe.config.serverURL = this.getURL(); - - // if the backend is http, then always client! - frappe.isServer = false; - - this.initTypeMap(); - } - - connect() {} - - async insert(doctype, doc) { - doc.doctype = doctype; - let filesToUpload = this.getFilesToUpload(doc); - let url = this.getURL('/api/resource', doctype); - - const responseDoc = await this.fetch(url, { - method: 'POST', - body: JSON.stringify(doc), - }); - - await this.uploadFilesAndUpdateDoc(filesToUpload, doctype, responseDoc); - - return responseDoc; - } - - async get(doctype, name) { - name = encodeURIComponent(name); - let url = this.getURL('/api/resource', doctype, name); - return await this.fetch(url, { - method: 'GET', - headers: this.getHeaders(), - }); - } - - async getAll({ doctype, fields, filters, start, limit, sortBy, order }) { - let url = this.getURL('/api/resource', doctype); - - url = - url + - '?' + - frappe.getQueryString({ - fields: JSON.stringify(fields), - filters: JSON.stringify(filters), - start: start, - limit: limit, - sortBy: sortBy, - order: order, - }); - - return await this.fetch(url, { - method: 'GET', - }); - } - - async update(doctype, doc) { - doc.doctype = doctype; - let filesToUpload = this.getFilesToUpload(doc); - let url = this.getURL('/api/resource', doctype, doc.name); - - const responseDoc = await this.fetch(url, { - method: 'PUT', - body: JSON.stringify(doc), - }); - - await this.uploadFilesAndUpdateDoc(filesToUpload, doctype, responseDoc); - - return responseDoc; - } - - async delete(doctype, name) { - let url = this.getURL('/api/resource', doctype, name); - - return await this.fetch(url, { - method: 'DELETE', - }); - } - - async deleteMany(doctype, names) { - let url = this.getURL('/api/resource', doctype); - - return await this.fetch(url, { - method: 'DELETE', - body: JSON.stringify(names), - }); - } - - async exists(doctype, name) { - return (await this.getValue(doctype, name, 'name')) ? true : false; - } - - async getValue(doctype, name, fieldname) { - let url = this.getURL('/api/resource', doctype, name, fieldname); - - return ( - await this.fetch(url, { - method: 'GET', - }) - ).value; - } - - async fetch(url, args) { - triggerEvent('ajaxStart'); - - args.headers = this.getHeaders(); - let response = await frappe.fetch(url, args); - - triggerEvent('ajaxStop'); - - if (response.status === 200) { - let data = await response.json(); - return data; - } - - if (response.status === 401) { - triggerEvent('unauthorized'); - } - - throw Error(await response.text()); - } - - getFilesToUpload(doc) { - const meta = frappe.getMeta(doc.doctype); - const fileFields = meta.getFieldsWith({ fieldtype: 'File' }); - const filesToUpload = []; - - if (fileFields.length > 0) { - fileFields.forEach((df) => { - const files = doc[df.fieldname] || []; - if (files.length) { - filesToUpload.push({ - fieldname: df.fieldname, - files: files, - }); - } - delete doc[df.fieldname]; - }); - } - - return filesToUpload; - } - - async uploadFilesAndUpdateDoc(filesToUpload, doctype, doc) { - if (filesToUpload.length > 0) { - // upload files - for (const fileToUpload of filesToUpload) { - const files = await this.uploadFiles( - fileToUpload.files, - doctype, - doc.name, - fileToUpload.fieldname - ); - doc[fileToUpload.fieldname] = files[0].name; - } - } - } - - async uploadFiles(fileList, doctype, name, fieldname) { - let url = this.getURL('/api/upload', doctype, name, fieldname); - - let formData = new FormData(); - for (const file of fileList) { - formData.append('files', file, file.name); - } - - let response = await frappe.fetch(url, { - method: 'POST', - body: formData, - }); - - const data = await response.json(); - if (response.status !== 200) { - throw Error(data.error); - } - return data; - } - - getURL(...parts) { - return this.protocol + '://' + this.server + (parts || []).join('/'); - } - - getHeaders() { - const headers = { - Accept: 'application/json', - 'Content-Type': 'application/json', - }; - if (frappe.session && frappe.session.token) { - headers.token = frappe.session.token; - } - return headers; - } - - initTypeMap() { - this.typeMap = { - AutoComplete: true, - Currency: true, - Int: true, - Float: true, - Percent: true, - Check: true, - 'Small Text': true, - 'Long Text': true, - Code: true, - 'Text Editor': true, - Date: true, - Datetime: true, - Time: true, - Text: true, - Data: true, - Link: true, - DynamicLink: true, - Password: true, - Select: true, - 'Read Only': true, - File: true, - Attach: true, - 'Attach Image': true, - Signature: true, - Color: true, - Barcode: true, - Geolocation: true, - }; - } - - close() {} -}; diff --git a/frappe/backends/mysql.js b/frappe/backends/mysql.js deleted file mode 100644 index f544f3cf..00000000 --- a/frappe/backends/mysql.js +++ /dev/null @@ -1,238 +0,0 @@ -const frappe = require('frappe'); -const mysql = require('mysql'); -const Database = require('./database'); -const debug = false; - -module.exports = class mysqlDatabase extends Database { - constructor({ db_name, username, password, host }) { - super(); - this.db_name = db_name; - this.username = username; - this.password = password; - this.host = host; - this.init_typeMap(); - } - - connect(db_name) { - if (db_name) { - this.db_name = db_name; - } - return new Promise((resolve) => { - this.conn = new mysql.createConnection({ - host: this.host, - user: this.username, - password: this.password, - database: this.db_name, - }); - () => { - if (debug) { - this.conn.on('trace', (trace) => console.log(trace)); - } - }; - resolve(); - }); - } - - async tableExists(table) { - const name = await this.sql(`SELECT table_name - FROM information_schema.tables - WHERE table_schema = '${this.db_name}' - AND table_name = '${table}'`); - return name && name.length ? true : false; - } - - async runCreateTableQuery(doctype, columns, values) { - const query = `CREATE TABLE IF NOT EXISTS ${doctype} ( - ${columns.join(', ')})`; - - return await this.run(query, values); - } - - updateColumnDefinition(df, columns, indexes) { - columns.push( - `${df.fieldname} ${this.typeMap[df.fieldtype]} ${ - df.required && !df.default ? 'not null' : '' - } ${df.default ? `default '${df.default}'` : ''}` - ); - } - - async getTableColumns(doctype) { - return (await this.sql(`SHOW COLUMNS FROM ${doctype}`)).map((d) => d.Field); - } - - async runAddColumnQuery(doctype, fields) { - await this.run( - `ALTER TABLE ${doctype} ADD COLUMN ${this.get_column_definition(doctype)}` - ); - } - - getOne(doctype, name, fields = '*') { - fields = this.prepareFields(fields); - - return new Promise((resolve, reject) => { - this.conn.get( - `select ${fields} from ${doctype} - where name = ?`, - name, - (err, row) => { - resolve(row || {}); - } - ); - }); - } - - async insertOne(doctype, doc) { - let fields = this.get_keys(doctype); - let placeholders = fields.map((d) => '?').join(', '); - - if (!doc.name) { - doc.name = frappe.getRandomString(); - } - - return await this.run( - `insert into ${doctype} - (${fields.map((field) => field.fieldname).join(', ')}) - values (${placeholders})`, - this.getFormattedValues(fields, doc) - ); - } - - async updateOne(doctype, doc) { - let fields = this.getKeys(doctype); - let assigns = fields.map((field) => `${field.fieldname} = ?`); - let values = this.getFormattedValues(fields, doc); - - // additional name for where clause - values.push(doc.name); - - return await this.run( - `update ${doctype} - set ${assigns.join(', ')} where name=?`, - values - ); - } - - async runDeleteOtherChildren(field, added) { - await this.run( - `delete from ${field.childtype} - where - parent = ? and - name not in (${added - .slice(1) - .map((d) => '?') - .join(', ')})`, - added - ); - } - - async deleteOne(doctype, name) { - return await this.run(`delete from ${doctype} where name=?`, name); - } - - async deleteChildren(parenttype, parent) { - await this.run(`delete from ${parent} where parent=?`, parent); - } - - getAll({ - doctype, - fields, - filters, - start, - limit, - order_by = 'modified', - order = 'desc', - } = {}) { - if (!fields) { - fields = frappe.getMeta(doctype).getKeywordFields(); - } - return new Promise((resolve, reject) => { - let conditions = this.getFilterConditions(filters); - - this.conn.all( - `select ${fields.join(', ')} - from ${doctype} - ${conditions.conditions ? 'where' : ''} ${conditions.conditions} - ${order_by ? 'order by ' + order_by : ''} ${ - order_by ? order || 'asc' : '' - } - ${limit ? 'limit ' + limit : ''} ${ - start ? 'offset ' + start : '' - }`, - conditions.values, - (err, rows) => { - if (err) { - reject(err); - } else { - resolve(rows); - } - } - ); - }); - } - - run(query, params) { - // TODO promisify - return new Promise((resolve, reject) => { - this.conn.query(query, params, (err) => { - if (err) { - if (debug) { - console.error(err); - } - reject(err); - } else { - resolve(); - } - }); - }); - } - - sql(query, params) { - return new Promise((resolve) => { - this.conn.query(query, params, (err, rows) => { - resolve(rows); - }); - }); - } - - async commit() { - try { - await this.run('commit'); - } catch (e) { - if (e.errno !== 1) { - throw e; - } - } - } - - init_typeMap() { - this.typeMap = { - AutoComplete: 'VARCHAR(140)', - Currency: 'real', - Int: 'INT', - Float: 'decimal(18,6)', - Percent: 'real', - Check: 'INT(1)', - 'Small Text': 'text', - 'Long Text': 'text', - Code: 'text', - 'Text Editor': 'text', - Date: 'DATE', - Datetime: 'DATETIME', - Time: 'TIME', - Text: 'text', - Data: 'VARCHAR(140)', - Link: ' varchar(140)', - DynamicLink: 'text', - Password: 'varchar(140)', - Select: 'VARCHAR(140)', - 'Read Only': 'varchar(140)', - File: 'text', - Attach: 'text', - 'Attach Image': 'text', - Signature: 'text', - Color: 'text', - Barcode: 'text', - Geolocation: 'text', - }; - } -}; diff --git a/src/background.js b/src/background.ts similarity index 100% rename from src/background.js rename to src/background.ts diff --git a/vue.config.js b/vue.config.js index 12013dcc..54f03ca6 100644 --- a/vue.config.js +++ b/vue.config.js @@ -5,8 +5,8 @@ module.exports = { pluginOptions: { electronBuilder: { nodeIntegration: true, - disableMainProcessTypescript: true, - mainProcessTypeChecking: false, + disableMainProcessTypescript: false, + mainProcessTypeChecking: true, chainWebpackRendererProcess: (config) => { config.target('electron-renderer'); config.resolve.alias.set('frappe', path.resolve(__dirname, './frappe'));