mirror of
https://github.com/frappe/books.git
synced 2024-12-22 19:09:01 +00:00
first commit
This commit is contained in:
commit
2ed02ea846
8
.eslintrc
Normal file
8
.eslintrc
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
{
|
||||||
|
"env": {
|
||||||
|
"browser": true,
|
||||||
|
"es6": true,
|
||||||
|
"node": true
|
||||||
|
},
|
||||||
|
"parser": "babel-eslint"
|
||||||
|
}
|
13
.gitignore
vendored
Normal file
13
.gitignore
vendored
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
node_modules
|
||||||
|
.DS_Store
|
||||||
|
Thumbs.db
|
||||||
|
test.db
|
||||||
|
*.log
|
||||||
|
|
||||||
|
/dist
|
||||||
|
/temp
|
||||||
|
|
||||||
|
# ignore everything in 'app' folder what had been generated from 'src' folder
|
||||||
|
/app/app.js
|
||||||
|
/app/background.js
|
||||||
|
/app/**/*.map
|
23
README.md
Normal file
23
README.md
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
# Frappe Core
|
||||||
|
|
||||||
|
Core libs for Frappe Framework JS
|
||||||
|
|
||||||
|
### Examples
|
||||||
|
|
||||||
|
const frappe = require('frappe-core);
|
||||||
|
|
||||||
|
# init database
|
||||||
|
frappe.init();
|
||||||
|
|
||||||
|
# make a new todo
|
||||||
|
let todo = frappe.get_doc({doctype: 'ToDo', subject: 'something'})
|
||||||
|
todo.insert()
|
||||||
|
|
||||||
|
# get all todos
|
||||||
|
let total_open = 0;
|
||||||
|
for (let d of frappe.get_all('ToDo')) {
|
||||||
|
todo = frappe.get_doc('ToDo', d.name);
|
||||||
|
if (todo.status == 'Open') total_open += 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
60
frappe/index.js
Normal file
60
frappe/index.js
Normal file
@ -0,0 +1,60 @@
|
|||||||
|
const path = require('path')
|
||||||
|
module.exports = {
|
||||||
|
init(db_path, user, user_key) {
|
||||||
|
this.db_path = db_path || 'test.db';
|
||||||
|
if (this._initialized) return;
|
||||||
|
this.init_config();
|
||||||
|
this.init_errors();
|
||||||
|
this.init_globals();
|
||||||
|
this.init_libs();
|
||||||
|
this.init_db();
|
||||||
|
this._initialized = true;
|
||||||
|
this.login(user, user_key);
|
||||||
|
},
|
||||||
|
init_config() {
|
||||||
|
this.config = {};
|
||||||
|
},
|
||||||
|
init_errors() {
|
||||||
|
this.ValueError = class extends Error { };
|
||||||
|
},
|
||||||
|
init_globals() {
|
||||||
|
this.meta_cache = {};
|
||||||
|
},
|
||||||
|
init_libs() {
|
||||||
|
this.utils = require('./utils');
|
||||||
|
Object.assign(this, this.utils);
|
||||||
|
let models = require('./model/models');
|
||||||
|
this.models = new models.Models();
|
||||||
|
this.model = require('./model');
|
||||||
|
this.document = require('./model/document');
|
||||||
|
this.meta = require('./model/meta');
|
||||||
|
this.session_lib = require('./session');
|
||||||
|
},
|
||||||
|
init_db() {
|
||||||
|
let database = require('./model/database');
|
||||||
|
this.db = new database.Database(this.db_path);
|
||||||
|
},
|
||||||
|
get_meta(doctype) {
|
||||||
|
if (!this.meta_cache[doctype]) {
|
||||||
|
this.meta_cache[doctype] = new this.meta.Meta(this.models.get('DocType', doctype));
|
||||||
|
}
|
||||||
|
return this.meta_cache[doctype];
|
||||||
|
},
|
||||||
|
get_doc(data, name) {
|
||||||
|
if (typeof data==='string' && typeof name==='string') {
|
||||||
|
let controller_class = this.models.get_controller(data);
|
||||||
|
var doc = new controller_class({doctype:data, name: name});
|
||||||
|
doc.load();
|
||||||
|
} else {
|
||||||
|
let controller_class = this.models.get_controller(data.doctype);
|
||||||
|
var doc = new controller_class(data);
|
||||||
|
}
|
||||||
|
return doc;
|
||||||
|
},
|
||||||
|
login(user, user_key) {
|
||||||
|
this.session = new this.session_lib.Session(user);
|
||||||
|
if (user && user_key) {
|
||||||
|
this.login(user_key);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
124
frappe/model/database.js
Normal file
124
frappe/model/database.js
Normal file
@ -0,0 +1,124 @@
|
|||||||
|
const fs = require('fs');
|
||||||
|
const path = require('path');
|
||||||
|
const SQL = require('sql.js');
|
||||||
|
const frappe = require('frappe-core');
|
||||||
|
|
||||||
|
class Database {
|
||||||
|
constructor(db_path) {
|
||||||
|
this.db_file_name = db_path;
|
||||||
|
this.connect();
|
||||||
|
}
|
||||||
|
|
||||||
|
connect() {
|
||||||
|
if (this.db_path) {
|
||||||
|
const filebuffer = fs.readFileSync(this.db_path);
|
||||||
|
this._conn = new SQL.Database(filebuffer);
|
||||||
|
} else {
|
||||||
|
this._conn = new SQL.Database();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
write() {
|
||||||
|
if (this.db_path) {
|
||||||
|
let data = this._conn.export();
|
||||||
|
fs.writeFileSync(this.db_path, new Buffer(data));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
close() {
|
||||||
|
this.write();
|
||||||
|
this._conn.close();
|
||||||
|
}
|
||||||
|
|
||||||
|
create_db() {
|
||||||
|
// Create a database.
|
||||||
|
let db = new SQL.Database();
|
||||||
|
let query = SCHEMA;
|
||||||
|
let result = db.exec(query);
|
||||||
|
if (Object.keys(result).length === 0 &&
|
||||||
|
typeof result.constructor === 'function') {
|
||||||
|
return db;
|
||||||
|
} else {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
create_table(doctype) {
|
||||||
|
let meta = frappe.get_meta(doctype);
|
||||||
|
let columns = [];
|
||||||
|
|
||||||
|
// add standard fields
|
||||||
|
let fields = frappe.model.standard_fields.slice();
|
||||||
|
if (meta.istable) {
|
||||||
|
fields = fields.concat(model.child_fields);
|
||||||
|
}
|
||||||
|
|
||||||
|
// add model fields
|
||||||
|
fields = fields.concat(meta.fields);
|
||||||
|
|
||||||
|
for (let df of fields) {
|
||||||
|
if (frappe.model.type_map[df.fieldtype]) {
|
||||||
|
columns.push(`${df.fieldname} ${frappe.model.type_map[df.fieldtype]} ${df.reqd ? "not null" : ""} ${df.default ? ("default " + frappe.utils.sqlescape(df.default)) : ""}`);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const query = `CREATE TABLE IF NOT EXISTS ${frappe.slug(doctype)} (
|
||||||
|
${columns.join(", ")})`;
|
||||||
|
|
||||||
|
return this.sql(query);
|
||||||
|
}
|
||||||
|
|
||||||
|
get(doctype, name) {
|
||||||
|
let doc = frappe.db.sql(`select * from ${frappe.slug(doctype)} where name = ${frappe.db.escape(name)}`);
|
||||||
|
return doc ? doc[0] : {};
|
||||||
|
}
|
||||||
|
|
||||||
|
insert(doctype, doc) {
|
||||||
|
this.sql(`insert into ${frappe.slug(doctype)}
|
||||||
|
(${Object.keys(doc).join(", ")})
|
||||||
|
values (${Object.values(doc).map(d => frappe.db.escape(d)).join(", ")})`);
|
||||||
|
}
|
||||||
|
|
||||||
|
update(doctype, doc) {
|
||||||
|
let assigns = [];
|
||||||
|
for (let key in doc) {
|
||||||
|
assigns.push(`${key} = ${this.escape(doc[key])}`);
|
||||||
|
}
|
||||||
|
this.sql(`update ${frappe.slug(doctype)}
|
||||||
|
set ${assigns.join(", ")}`);
|
||||||
|
}
|
||||||
|
|
||||||
|
sql(query, opts={}) {
|
||||||
|
//console.log(query);
|
||||||
|
const result = frappe.db._conn.exec(query);
|
||||||
|
if (result.length > 0) {
|
||||||
|
if (opts.as_list)
|
||||||
|
return result[0];
|
||||||
|
else
|
||||||
|
return sql_result_to_obj(result[0]);
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
get_value(doctype, name, fieldname='name') {
|
||||||
|
let value = this.sql(`select ${fieldname} from ${frappe.slug(doctype)}
|
||||||
|
where name=${this.escape(name)}`);
|
||||||
|
return value.length ? value[0][fieldname] : null;
|
||||||
|
}
|
||||||
|
|
||||||
|
escape(value) {
|
||||||
|
return frappe.utils.sqlescape(value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function sql_result_to_obj(result) {
|
||||||
|
const columns = result.columns;
|
||||||
|
return result.values.map(row => {
|
||||||
|
return columns.reduce((res, col, i) => {
|
||||||
|
res[col] = row[i];
|
||||||
|
return res;
|
||||||
|
}, {});
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
module.exports = { Database: Database };
|
109
frappe/model/document.js
Normal file
109
frappe/model/document.js
Normal file
@ -0,0 +1,109 @@
|
|||||||
|
const frappe = require('frappe-core');
|
||||||
|
|
||||||
|
class Document {
|
||||||
|
constructor(data) {
|
||||||
|
Object.assign(this, data);
|
||||||
|
}
|
||||||
|
|
||||||
|
get(key) {
|
||||||
|
return this[key];
|
||||||
|
}
|
||||||
|
|
||||||
|
set(key, value) {
|
||||||
|
this.validate_field(key, value);
|
||||||
|
this[key] = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
set_name() {
|
||||||
|
// assign a random name by default
|
||||||
|
// override this to set a name
|
||||||
|
if (!this.name) {
|
||||||
|
this.name = Math.random().toString(36).substr(3);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
get meta() {
|
||||||
|
if (!this._meta) {
|
||||||
|
this._meta = frappe.get_meta(this.doctype);
|
||||||
|
}
|
||||||
|
return this._meta;
|
||||||
|
}
|
||||||
|
|
||||||
|
append(key, document) {
|
||||||
|
if (!this[key]) {
|
||||||
|
this[key] = [];
|
||||||
|
}
|
||||||
|
this[key].push(this.init_doc(document));
|
||||||
|
}
|
||||||
|
|
||||||
|
init_doc(data) {
|
||||||
|
if (data.prototype instanceof Document) {
|
||||||
|
return data;
|
||||||
|
} else {
|
||||||
|
return new Document(d);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
validate_field (key, value) {
|
||||||
|
let df = this.meta.get_field(key);
|
||||||
|
if (df.fieldtype=='Select') {
|
||||||
|
this.meta.validate_select(df, value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
validate() { }
|
||||||
|
before_insert() { }
|
||||||
|
after_insert() { }
|
||||||
|
before_update() { }
|
||||||
|
after_update() { }
|
||||||
|
after_save() { }
|
||||||
|
|
||||||
|
get_valid_dict() {
|
||||||
|
let doc = {};
|
||||||
|
for(let df of this.meta.get_valid_fields()) {
|
||||||
|
doc[df.fieldname] = this.get(df.fieldname);
|
||||||
|
}
|
||||||
|
return doc;
|
||||||
|
}
|
||||||
|
|
||||||
|
set_standard_values() {
|
||||||
|
let now = new Date();
|
||||||
|
if (this.docstatus === null || this.docstatus === undefined) {
|
||||||
|
this.docstatus = 0;
|
||||||
|
}
|
||||||
|
if (!this.owner) {
|
||||||
|
this.owner = frappe.session.user;
|
||||||
|
this.creation = now;
|
||||||
|
}
|
||||||
|
this.modified_by = frappe.session.user;
|
||||||
|
this.modified = now;
|
||||||
|
}
|
||||||
|
|
||||||
|
load() {
|
||||||
|
Object.assign(this, frappe.db.get(this.doctype, this.name));
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
insert() {
|
||||||
|
this.set_name();
|
||||||
|
this.set_standard_values();
|
||||||
|
this.validate();
|
||||||
|
this.before_insert();
|
||||||
|
frappe.db.insert(this.doctype, this.get_valid_dict())
|
||||||
|
this.after_insert();
|
||||||
|
this.after_save();
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
update() {
|
||||||
|
this.set_standard_values();
|
||||||
|
this.validate();
|
||||||
|
this.before_insert();
|
||||||
|
frappe.db.update(this.doctype, this.get_valid_dict());
|
||||||
|
this.after_update();
|
||||||
|
this.after_save();
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
module.exports = { Document: Document };
|
63
frappe/model/index.js
Normal file
63
frappe/model/index.js
Normal file
@ -0,0 +1,63 @@
|
|||||||
|
module.exports = {
|
||||||
|
standard_fields: [
|
||||||
|
{
|
||||||
|
fieldname: 'name', fieldtype: 'Data', reqd: 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
fieldname: 'owner', fieldtype: 'Link', reqd: 1, options: 'User'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
fieldname: 'modified_by', fieldtype: 'Link', reqd: 1, options: 'User'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
fieldname: 'creation', fieldtype: 'Datetime', reqd: 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
fieldname: 'modified', fieldtype: 'Datetime', reqd: 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
fieldname: 'docstatus', fieldtype: 'Int', reqd: 1, default: 0
|
||||||
|
}
|
||||||
|
],
|
||||||
|
child_fields: [
|
||||||
|
{
|
||||||
|
fieldname: 'idx', fieldtype: 'Int', reqd: 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
fieldname: 'parent', fieldtype: 'Data', reqd: 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
fieldname: 'parenttype', fieldtype: 'Link', reqd: 1, options: 'DocType'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
fieldname: 'parentfield', fieldtype: 'Data', reqd: 1
|
||||||
|
}
|
||||||
|
],
|
||||||
|
type_map: {
|
||||||
|
'Currency': 'real'
|
||||||
|
,'Int': 'integer'
|
||||||
|
,'Float': 'real'
|
||||||
|
,'Percent': 'real'
|
||||||
|
,'Check': 'integer'
|
||||||
|
,'Small Text': 'text'
|
||||||
|
,'Long Text': 'text'
|
||||||
|
,'Code': 'text'
|
||||||
|
,'Text Editor': 'text'
|
||||||
|
,'Date': 'text'
|
||||||
|
,'Datetime': 'text'
|
||||||
|
,'Time': 'text'
|
||||||
|
,'Text': 'text'
|
||||||
|
,'Data': 'text'
|
||||||
|
,'Link': 'text'
|
||||||
|
,'Dynamic Link':'text'
|
||||||
|
,'Password': 'text'
|
||||||
|
,'Select': 'text'
|
||||||
|
,'Read Only': 'text'
|
||||||
|
,'Attach': 'text'
|
||||||
|
,'Attach Image':'text'
|
||||||
|
,'Signature': 'text'
|
||||||
|
,'Color': 'text'
|
||||||
|
,'Barcode': 'text'
|
||||||
|
,'Geolocation': 'text'
|
||||||
|
}
|
||||||
|
};
|
70
frappe/model/meta.js
Normal file
70
frappe/model/meta.js
Normal file
@ -0,0 +1,70 @@
|
|||||||
|
const Document = require('./document').Document;
|
||||||
|
const frappe = require('frappe-core');
|
||||||
|
|
||||||
|
class Meta extends Document {
|
||||||
|
constructor(data) {
|
||||||
|
super(data);
|
||||||
|
this.event_handlers = {};
|
||||||
|
}
|
||||||
|
|
||||||
|
get_field(fieldname) {
|
||||||
|
if (!this.field_map) {
|
||||||
|
this.field_map = {};
|
||||||
|
for (let df of this.fields) {
|
||||||
|
this.field_map[df.fieldname] = df;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return this.field_map[fieldname];
|
||||||
|
}
|
||||||
|
|
||||||
|
on(key, fn) {
|
||||||
|
if (!this.event_handlers[key]) {
|
||||||
|
this.event_handlers[key] = [];
|
||||||
|
}
|
||||||
|
this.event_handlers[key].push(fn);
|
||||||
|
}
|
||||||
|
|
||||||
|
get_valid_fields() {
|
||||||
|
if (!this._valid_fields) {
|
||||||
|
this._valid_fields = [];
|
||||||
|
|
||||||
|
// standard fields
|
||||||
|
for (let df of frappe.model.standard_fields) {
|
||||||
|
this._valid_fields.push(df);
|
||||||
|
}
|
||||||
|
|
||||||
|
// parent fields
|
||||||
|
if (this.istable) {
|
||||||
|
for (let df of frappe.model.child_fields) {
|
||||||
|
this._valid_fields.push(df);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// doctype fields
|
||||||
|
for (let df of this.fields) {
|
||||||
|
if (frappe.model.type_map[df.fieldtype]) {
|
||||||
|
this._valid_fields.push(df);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return this._valid_fields;
|
||||||
|
}
|
||||||
|
|
||||||
|
validate_select(df, value) {
|
||||||
|
let options = df.options;
|
||||||
|
if (typeof options === 'string') {
|
||||||
|
// values given as string
|
||||||
|
options = df.options.split('\n');
|
||||||
|
}
|
||||||
|
if (!options.includes(value)) {
|
||||||
|
throw new frappe.ValueError(`${value} must be one of ${options.join(", ")}`);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
trigger(key) {
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
module.exports = { Meta: Meta }
|
68
frappe/model/models.js
Normal file
68
frappe/model/models.js
Normal file
@ -0,0 +1,68 @@
|
|||||||
|
const walk = require('walk');
|
||||||
|
const path = require('path');
|
||||||
|
const process = require('process');
|
||||||
|
const frappe = require('frappe-core');
|
||||||
|
|
||||||
|
class Models {
|
||||||
|
constructor() {
|
||||||
|
this.data = {};
|
||||||
|
this.controllers = {};
|
||||||
|
this.setup_path_map();
|
||||||
|
}
|
||||||
|
|
||||||
|
get(doctype, name) {
|
||||||
|
if (!this.data[doctype]) {
|
||||||
|
this.data[doctype] = {};
|
||||||
|
}
|
||||||
|
if (!this.data[doctype][name]) {
|
||||||
|
this.data[doctype][name] = require(
|
||||||
|
this.path_map[frappe.slug(doctype)][frappe.slug(name)]);
|
||||||
|
}
|
||||||
|
return this.data[doctype][name];
|
||||||
|
}
|
||||||
|
|
||||||
|
get_controller(doctype) {
|
||||||
|
doctype = frappe.slug(doctype);
|
||||||
|
if (!this.controllers[doctype]) {
|
||||||
|
this.controllers[doctype] = require(this.controller_map[doctype])[doctype];
|
||||||
|
}
|
||||||
|
return this.controllers[doctype];
|
||||||
|
}
|
||||||
|
|
||||||
|
setup_path_map() {
|
||||||
|
const cwd = process.cwd();
|
||||||
|
this.path_map = {};
|
||||||
|
this.controller_map = {};
|
||||||
|
|
||||||
|
if (!frappe.config.apps) {
|
||||||
|
frappe.config.apps = [];
|
||||||
|
}
|
||||||
|
frappe.config.apps.unshift('frappe-core');
|
||||||
|
|
||||||
|
for (let app_name of frappe.config.apps) {
|
||||||
|
let start = path.resolve(require.resolve(app_name), '../models');
|
||||||
|
walk.walkSync(start, {
|
||||||
|
listeners: {
|
||||||
|
file: (basepath, file_data, next) => {
|
||||||
|
const doctype = path.basename(path.dirname(basepath));
|
||||||
|
const name = path.basename(basepath);
|
||||||
|
const file_path = path.resolve(basepath, file_data.name);
|
||||||
|
if (file_data.name.endsWith('.json')) {
|
||||||
|
if (!this.path_map[doctype]) {
|
||||||
|
this.path_map[doctype] = {};
|
||||||
|
}
|
||||||
|
|
||||||
|
this.path_map[doctype][name] = file_path;
|
||||||
|
}
|
||||||
|
if (doctype==='doctype' && file_data.name.endsWith('.js')) {
|
||||||
|
this.controller_map[name] = file_path;
|
||||||
|
}
|
||||||
|
next();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
module.exports = { Models: Models }
|
11
frappe/models/doctype/todo/todo.js
Normal file
11
frappe/models/doctype/todo/todo.js
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
const frappe = require('frappe-core');
|
||||||
|
|
||||||
|
class todo extends frappe.document.Document {
|
||||||
|
validate() {
|
||||||
|
if (!this.status) {
|
||||||
|
this.status = 'Open';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
module.exports = { todo: todo };
|
30
frappe/models/doctype/todo/todo.json
Normal file
30
frappe/models/doctype/todo/todo.json
Normal file
@ -0,0 +1,30 @@
|
|||||||
|
{
|
||||||
|
"autoname": "hash",
|
||||||
|
"name": "ToDo",
|
||||||
|
"doctype": "DocType",
|
||||||
|
"issingle": 0,
|
||||||
|
"fields": [
|
||||||
|
{
|
||||||
|
"fieldname": "subject",
|
||||||
|
"label": "Subject",
|
||||||
|
"fieldtype": "Data",
|
||||||
|
"reqd": 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"fieldname": "description",
|
||||||
|
"label": "Description",
|
||||||
|
"fieldtype": "Text"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"fieldname": "status",
|
||||||
|
"label": "Status",
|
||||||
|
"fieldtype": "Select",
|
||||||
|
"options": [
|
||||||
|
"Open",
|
||||||
|
"Closed"
|
||||||
|
],
|
||||||
|
"default": "Open",
|
||||||
|
"reqd": 1
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
17
frappe/session.js
Normal file
17
frappe/session.js
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
const frappe = require('frappe-core');
|
||||||
|
|
||||||
|
class Session {
|
||||||
|
constructor(user, user_key) {
|
||||||
|
this.user = user || 'guest';
|
||||||
|
if (this.user !== 'guest') {
|
||||||
|
this.login(user_key);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
login(user_key) {
|
||||||
|
// could be password, sessionid, otp
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
module.exports = { Session: Session };
|
18
frappe/tests/test_controller.js
Normal file
18
frappe/tests/test_controller.js
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
const assert = require('assert');
|
||||||
|
const frappe = require('frappe-core');
|
||||||
|
|
||||||
|
describe('Controller', () => {
|
||||||
|
before(function() {
|
||||||
|
frappe.init();
|
||||||
|
frappe.db.create_table('ToDo');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should call controller method', () => {
|
||||||
|
let doc = frappe.get_doc({
|
||||||
|
doctype:'ToDo',
|
||||||
|
subject: 'test'
|
||||||
|
});
|
||||||
|
doc.validate();
|
||||||
|
assert.equal(doc.status, 'Open');
|
||||||
|
});
|
||||||
|
});
|
13
frappe/tests/test_database.js
Normal file
13
frappe/tests/test_database.js
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
const assert = require('assert');
|
||||||
|
const frappe = require('frappe-core');
|
||||||
|
|
||||||
|
describe('Document', () => {
|
||||||
|
before(function() {
|
||||||
|
frappe.init();
|
||||||
|
});
|
||||||
|
|
||||||
|
// it('should create a table', () => {
|
||||||
|
// frappe.db.create_table('ToDo');
|
||||||
|
// frappe.db.write();
|
||||||
|
// });
|
||||||
|
});
|
62
frappe/tests/test_document.js
Normal file
62
frappe/tests/test_document.js
Normal file
@ -0,0 +1,62 @@
|
|||||||
|
const assert = require('assert');
|
||||||
|
const frappe = require('frappe-core');
|
||||||
|
|
||||||
|
describe('Document', () => {
|
||||||
|
before(function() {
|
||||||
|
frappe.init();
|
||||||
|
frappe.db.create_table('ToDo');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should insert a doc', () => {
|
||||||
|
let doc1 = test_doc();
|
||||||
|
doc1.subject = 'insert subject 1';
|
||||||
|
doc1.description = 'insert description 1';
|
||||||
|
doc1.insert();
|
||||||
|
|
||||||
|
// get it back from the db
|
||||||
|
let doc2 = frappe.get_doc(doc1.doctype, doc1.name);
|
||||||
|
assert.equal(doc1.subject, doc2.subject);
|
||||||
|
assert.equal(doc1.description, doc2.description);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should update a doc', () => {
|
||||||
|
let doc = test_doc().insert();
|
||||||
|
|
||||||
|
assert.notEqual(frappe.db.get_value(doc.doctype, doc.name, 'subject'), 'subject 2');
|
||||||
|
|
||||||
|
doc.subject = 'subject 2'
|
||||||
|
doc.update();
|
||||||
|
|
||||||
|
assert.equal(frappe.db.get_value(doc.doctype, doc.name, 'subject'), 'subject 2');
|
||||||
|
})
|
||||||
|
|
||||||
|
it('should get a value', () => {
|
||||||
|
assert.equal(test_doc().get('subject'), 'testing 1');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should set a value', () => {
|
||||||
|
let doc = test_doc();
|
||||||
|
doc.set('subject', 'testing 1')
|
||||||
|
assert.equal(doc.get('subject'), 'testing 1');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should not allow incorrect Select option', () => {
|
||||||
|
let doc = test_doc();
|
||||||
|
assert.throws(
|
||||||
|
() => {
|
||||||
|
doc.set('status', 'Illegal');
|
||||||
|
},
|
||||||
|
frappe.ValueError
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
const test_doc = () => {
|
||||||
|
return frappe.get_doc({
|
||||||
|
doctype: 'ToDo',
|
||||||
|
status: 'Open',
|
||||||
|
subject: 'testing 1',
|
||||||
|
description: 'test description 1'
|
||||||
|
});
|
||||||
|
}
|
21
frappe/tests/test_meta.js
Normal file
21
frappe/tests/test_meta.js
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
const assert = require('assert');
|
||||||
|
const frappe = require('frappe-core');
|
||||||
|
|
||||||
|
describe('Meta', () => {
|
||||||
|
before(function() {
|
||||||
|
frappe.init();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should get init from json file', () => {
|
||||||
|
let todo = frappe.get_meta('ToDo');
|
||||||
|
assert.equal(todo.issingle, 0);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should get fields from meta', () => {
|
||||||
|
let todo = frappe.get_meta('ToDo');
|
||||||
|
let fields = todo.fields.map((df) => df.fieldname);
|
||||||
|
assert.ok(fields.includes('subject'));
|
||||||
|
assert.ok(fields.includes('description'));
|
||||||
|
assert.ok(fields.includes('status'));
|
||||||
|
});
|
||||||
|
});
|
13
frappe/tests/test_models.js
Normal file
13
frappe/tests/test_models.js
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
const assert = require('assert');
|
||||||
|
const frappe = require('frappe-core');
|
||||||
|
|
||||||
|
describe('Models', () => {
|
||||||
|
before(function() {
|
||||||
|
frappe.init();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should get todo json', () => {
|
||||||
|
let todo = frappe.models.get('DocType', 'ToDo');
|
||||||
|
assert.equal(todo.issingle, 0);
|
||||||
|
});
|
||||||
|
});
|
23
frappe/utils.js
Normal file
23
frappe/utils.js
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
module.exports = {
|
||||||
|
slug(text) {
|
||||||
|
return text.toLowerCase().replace(/ /g, '_');
|
||||||
|
},
|
||||||
|
sqlescape(value) {
|
||||||
|
if (value===null || value===undefined) {
|
||||||
|
// null
|
||||||
|
return 'null';
|
||||||
|
|
||||||
|
} else if (value instanceof Date) {
|
||||||
|
// date
|
||||||
|
return `'${value.toISOString()}'`;
|
||||||
|
|
||||||
|
} else if (typeof value==='string') {
|
||||||
|
// text
|
||||||
|
return "'" + value.replace(/'/g, '\'').replace(/"/g, '\"') + "'";
|
||||||
|
|
||||||
|
} else {
|
||||||
|
// number
|
||||||
|
return value + '';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
4114
package-lock.json
generated
Normal file
4114
package-lock.json
generated
Normal file
File diff suppressed because it is too large
Load Diff
29
package.json
Normal file
29
package.json
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
{
|
||||||
|
"name": "frappe-core",
|
||||||
|
"version": "1.0.0",
|
||||||
|
"description": "Frappe Core",
|
||||||
|
"main": "frappe/index.js",
|
||||||
|
"scripts": {
|
||||||
|
"test": "mocha frappe/tests"
|
||||||
|
},
|
||||||
|
"dependencies": {
|
||||||
|
"sql.js": "^0.4.0",
|
||||||
|
"walk": "^2.3.9"
|
||||||
|
},
|
||||||
|
"repository": {
|
||||||
|
"type": "git",
|
||||||
|
"url": "git+https://github.com/frappe/frappe-js.git"
|
||||||
|
},
|
||||||
|
"author": "Frappe",
|
||||||
|
"license": "MIT",
|
||||||
|
"bugs": {
|
||||||
|
"url": "https://github.com/frappe/frappe-js/issues"
|
||||||
|
},
|
||||||
|
"homepage": "https://github.com/frappe/frappe-js#readme",
|
||||||
|
"devDependencies": {
|
||||||
|
"babel-eslint": "^8.0.1",
|
||||||
|
"eslint": "^4.9.0",
|
||||||
|
"mocha": "^4.0.1",
|
||||||
|
"webpack": "^3.8.1"
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user