Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

thinkjs

Package Overview
Dependencies
Maintainers
1
Versions
240
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

thinkjs - npm Package Compare versions

Comparing version 0.3.17 to 0.3.18

17

lib/Common/common.js

@@ -406,2 +406,19 @@ var fs = require("fs");

return deferred;
}
/**
* 快速生成一个object
* @param {[type]} key [description]
* @param {[type]} value [description]
* @return {[type]} [description]
*/
global.getObject = function(key, value){
var obj = {};
if (!isArray(key)) {
obj[key] = value;
return obj;
};
key.forEach(function(item, i){
obj[item] = value[i];
})
return obj;
}

1

lib/Conf/debug.js

@@ -7,2 +7,3 @@ /**

db_fields_cache: false, //debug模式下关闭数据表字段的缓存
db_cache_on: false,
debug_retain_files: ['/node_modules/', '/Model.class.js'], //这些文件在debug模式下不清除缓存

@@ -9,0 +10,0 @@ use_cluster: false,

52

lib/Extend/Behavior/DenyIpBehavior.class.js

@@ -6,28 +6,28 @@ /**

module.exports = Behavior(function(){
return {
options: {
deny_ip: [] //阻止的ip列表
},
run: function(){
if (this.options.deny_ip.length === 0) {
return true;
};
var clientIps = this.http.ip().split(".");
var flag = this.options.deny_ip.some(function(item){
return item.split(".").every(function(num, i){
if (num === "*" || num === clientIps[i]) {
return true;
};
})
});
//如果在阻止的ip在列表里,则返回一个不会resolve的promise
//从而让后面的代码不执行
if (flag) {
this.http.res.statusCode = 403;
this.http.res.end();
return getDefer().promise;
};
return true;
}
}
return {
options: {
deny_ip: [] //阻止的ip列表
},
run: function(){
if (this.options.deny_ip.length === 0) {
return true;
};
var clientIps = this.http.ip().split(".");
var flag = this.options.deny_ip.some(function(item){
return item.split(".").every(function(num, i){
if (num === "*" || num === clientIps[i]) {
return true;
};
})
});
//如果在阻止的ip在列表里,则返回一个不会resolve的promise
//从而让后面的代码不执行
if (flag) {
this.http.res.statusCode = 403;
this.http.res.end();
return getDefer().promise;
};
return true;
}
}
});

@@ -6,2 +6,30 @@ /**

module.exports = Model(function(){
//关联类型
const HAS_ONE = 1;
const BELONGS_TO = 2;
const HAS_MANY = 3;
const MANY_TO_MANY = 4;
//post的操作类型
const ADD = 'ADD';
const UPDATE = 'UPDATE';
const DELETE = 'DELETE';
//get时不同的type对应的回调
var mapTypeGetFn = {
1: "_getHasOneRelation",
2: "_getBelongsToRelation",
3: "_getHasManyRelation",
4: "_getManyToManyRelation"
}
//post时不同的type对应的回调
var mapTypePostFn = {
1: "_postHasOneRelation",
2: "_postBelongsToRelation",
3: "_postHasManyRelation",
4: "_postManyToManyRelation"
}
//解析page参数

@@ -29,5 +57,18 @@ var parsePage = function(options){

}
return {
/**
* 关联定义
* 数据格式:
* "Profile": {
* type: 1,
* model: "Profile",
* name: "Profile",
* key: "id",
* fKey: "user_id",
* field: "id,name",
* where: "name=xx",
* order: "",
* limit: ""
* }
* @type {Object}

@@ -37,5 +78,25 @@ */

/**
* 本次使用的关联名称,默认是全部使用
* @type {Boolean}
*/
_relationName: true,
/**
* 只读字段
* @type {String}
*/
readonlyField: "",
/**
* 保存时对数据进行校验
* @type {Boolean}
*/
validateField: true,
/**
* 字段类型
* @type {Object}
*/
fieldType: {},
/**
* 返回数据里含有count信息的查询
* @param options 查询选项
* @param pageFlag 当页面不合法时,处理方式,true为获取第一页,false为获取最后一页,undefined获取为空
* @param pageFlag 当页面不合法时的处理方式,true为获取第一页,false为获取最后一页,undefined获取为空
* @return promise

@@ -52,3 +113,3 @@ */

var result = {};
return this.parseOptions().then(function(options){
return this.parseOptions(options).then(function(options){
delete options.table;

@@ -69,3 +130,3 @@ parsedOptions = options;

};
result = extend({count: count, totalPage: totalPage}, pageOptions);
result = extend({count: count, total: totalPage}, pageOptions);
return self.select(parsedOptions);

@@ -76,4 +137,471 @@ }).then(function(data){

})
},
/**
* 设置本次使用的relation
* @param {[type]} name [description]
*/
setRelation: function(name){
if (isString(name)) {
name = name.split(",");
};
this._relationName = name;
return this;
},
/**
* find后置操作
* @param {[type]} data [description]
* @return {[type]} [description]
*/
_afterFind: function(data, parsedOptions){
return this.getRelation(data, parsedOptions);
},
/**
* select后置操作
* @param {[type]} data [description]
* @return {[type]} [description]
*/
_afterSelect: function(data, parsedOptions){
return this.getRelation(data, parsedOptions);
},
/**
* 获取关联的数据
* @param {[type]} data [description]
* @param Boolean isDataList 是否是数据列表
* @return {[type]}
*/
getRelation: function(data, parsedOptions){
if (isEmpty(data) || isEmpty(this.relation) || isEmpty(this._relationName)) {
return data;
};
var self = this;
var promises = [];
Object.keys(this.relation).forEach(function(key){
var promise, mapName, mapType, model, mapWhere, mapKey, mapfKey;
var value = self.relation[key];
if (!isObject(value)) {
value = {type: value};
};
mapName = value.name || key;
//如果不在开启的relation内,则直接返回
if (self._relationName !== true && self._relationName.indexOf(mapName) === -1) {
return;
};
mapType = value.type || HAS_ONE;
mapKey = value.key || self.getPk();
mapfKey = value.fKey || (self.name.toLowerCase() + "_id");
model = D(value.model || key);
model.where(value.where).cache(parsedOptions.cache).field(value.field).order(value.order).limit(value.limit);
//调用不同的类型解析
promise = self[mapTypeGetFn[mapType]](data, value, {
model: model,
mapName: mapName,
mapKey: mapKey,
mapfKey: mapfKey
}, parsedOptions);
promises.push(promise);
})
return Promise.all(promises).then(function(){
return data;
});
},
_getHasOneRelation: function(data, value, mapOptions, parsedOptions){
var self = this;
var where = self.parseRelationWhere(data, mapOptions.mapKey, mapOptions.mapfKey);
mapOptions.model.where(where);
return mapOptions.model.select().then(function(mapData){
self.parseRelationData(data, mapData, mapOptions.mapName);
});
},
_getBelongsToRelation: function(data, value, mapOptions, parsedOptions){
var self = this;
return mapOptions.model.promise.then(function(){
mapKey = mapOptions.model.getModelName().toLowerCase() + "_id";
mapfKey = mapOptions.model.getPk();
var where = self.parseRelationWhere(data, mapOptions.mapKey, mapOptions.mapfKey);
mapOptions.model.where(where);
return model.select();
}).then(function(mapData){
self.parseRelationData(data, mapData, mapOptions.mapName);
});
},
_getHasManyRelation: function(data, value, mapOptions, parsedOptions){
var self = this;
var where = self.parseRelationWhere(data, mapKey, mapfKey);
mapOptions.model.where(where);
return mapOptions.model.select().then(function(mapData){
self.parseRelationData(data, mapData, mapOptions.mapName, mapOptions.mapKey, mapOptions.mapfKey, true);
});
},
_getManyToManyRelation: function(data, value, mapOptions, parsedOptions){
var self = this;
return mapOptions.model.promise.then(function(){
var where = self.parseRelationWhere(data, mapOptions.mapKey, mapOptions.mapfKey);
var whereStr = self.db.parseWhere(where);
//关联的实体表和关系表联合查询
var sql = "SELECT b.%s, a.%s FROM %s as a, %s as b %s AND a.%s=b.%s %s";
var queryData = [
value.field || "*",
mapOptions.mapfKey,
value.rTable || self.getRelationTableName(mapOptions.model),
mapOptions.model.getTableName(),
whereStr || "WHERE ",
value.rfKey || (mapOptions.model.getModelName().toLowerCase() + "_id"),
mapOptions.model.getPk(),
value.where ? (" AND " + value.where) : ""
];
return self.parseSql(sql, queryData).then(function(sql){
return self.db.select(sql, parsedOptions.cache);
}).then(function(mapData){
self.parseRelationData(data, mapData, mapOptions.mapName, mapOptions.mapKey, mapOptions.mapfKey, true);
});
})
},
/**
* 多对多关系下,获取对应的关联表
* @return {[type]} [description]
*/
getRelationTableName: function(model){
var table = [
this.tablePrefix,
this.tableName || this.name,
"_",
model.getModelName()
].join("");
return table.toLowerCase();
},
/**
* 多堆垛关系下,回去对应关联表的模型
* @param {[type]} model [description]
* @return {[type]} [description]
*/
getRelationModel: function(model){
var name = ucfirst(this.tableName || this.name) + ucfirst(model.getModelName());
return D(name);
},
/**
* 解析relation的where条件
* @param {[type]} data [description]
* @param {[type]} mapKey [description]
* @param {[type]} mapfKey [description]
* @return {[type]} [description]
*/
parseRelationWhere: function(data, mapKey, mapfKey){
if (isArray(data)) {
var value = data.map(function(item){
return item[mapKey];
});
return getObject(mapfKey, ["IN", value]);
};
return getObject(mapfKey, data[mapKey]);
},
/**
* 解析查询后的数据
* @param {[type]} data [description]
* @param {[type]} mapData [description]
* @param {[type]} mapName [description]
* @param {[type]} mapKey [description]
* @param {[type]} mapfKey [description]
* @param {Boolean} isArrMap [description]
* @return {[type]} [description]
*/
parseRelationData: function(data, mapData, mapName, mapKey, mapfKey, isArrMap){
if (isArray(data)) {
//提前初始化,防止mapData为空导致data里的数据没有初始化的情况
data.forEach(function(item, i){
data[i][mapName] = isArrMap ? [] : {};
})
mapData.forEach(function(mapItem){
data.forEach(function(item, i){
if (mapItem[mapfKey] !== item[mapKey]) {
return;
};
if (isArrMap) {
data[i][mapName].push(mapItem);
}else{
data[i][mapName] = mapItem;
}
});
})
}else{
data[mapName] = isArrMap ? (mapData || []) : (mapData[0] || {});
}
return data;
},
/**
* 添加后置操作
* @param {[type]} data [description]
* @param {[type]} parsedOptions [description]
* @return {[type]} [description]
*/
_afterAdd: function(data, parsedOptions){
return this.postRelation(ADD, data, parsedOptions);
},
/**
* 删除后置操作
* @param {[type]} data [description]
* @param {[type]} parsedOptions [description]
* @return {[type]} [description]
*/
_afterDelete: function(data, parsedOptions){
return this.postRelation(DELETE, data, parsedOptions);
},
/**
* 更新前置操作
* @param {[type]} data [description]
* @param {[type]} parsedOptions [description]
* @return {[type]} [description]
*/
_beforeUpdate: function(data, parsedOptions){
//只读字段处理
if (!isEmpty(this.readonlyField)) {
if (isString(this.readonlyField)) {
this.readonlyField = this.readonlyField.split(",");
};
this.readonlyField.forEach(function(field){
delete data[field];
})
};
return data;
},
/**
* 更新后置操作
* @param {[type]} data [description]
* @param {[type]} parsedOptions [description]
* @return {[type]} [description]
*/
_afterUpdate: function(data, parsedOptions){
return this.postRelation(UPDATE, data, parsedOptions);
},
/**
* 提交类关联操作
* @param {[type]} postType [description]
* @param {[type]} data [description]
* @param {[type]} parsedOptions [description]
* @return {[type]} [description]
*/
postRelation: function(postType, data, parsedOptions){
if (isEmpty(data) || isEmpty(this.relation) || isEmpty(this._relationName)) {
return data;
};
var self = this;
var promises = [];
Object.keys(this.relation).forEach(function(key){
var promise, mapName, mapType, model, mapWhere, mapKey, mapfKey, mapData, pkValue;
var value = self.relation[key];
if (!isObject(value)) {
value = {type: value};
};
mapName = value.name || key;
//如果没有开启对应的relation,则直接返回
if (self._relationName !== true && self._relationName.indexOf(mapName) === -1) {
return;
};
mapData = data[mapName];
//如果没有对应的数据,则直接返回
if (isEmpty(mapData) && postType !== DELETE) {
return;
};
mapKey = value.key || self.getPk();
if (isEmpty(data[mapKey])) {
return;
};
mapType = value.type || HAS_ONE;
mapfKey = value.fKey || (self.name.toLowerCase() + "_id");
model = D(value.model || key);
model.where(value.where);
//调用不同的类型解析
promise = self[mapTypePostFn[mapType]](data, value, {
model: model,
mapName: mapName,
mapKey: mapKey,
mapfKey: mapfKey,
mapData: mapData,
type: postType
}, parsedOptions);
promises.push(promise);
})
return Promise.all(promises).then(function(){
return data;
})
},
/**
* 一对一提交
* @param {[type]} data [description]
* @param {[type]} value [description]
* @param {[type]} mapOptions [description]
* @param {[type]} parsedOptions [description]
* @return {[type]} [description]
*/
_postHasOneRelation: function(data, value, mapOptions, parsedOptions){
var promise = null;
var self = this;
var where;
switch(mapOptions.type){
case ADD:
mapOptions.mapData[mapOptions.mapfKey] = data[mapOptions.mapKey];
promise = mapOptions.model.add(mapOptions.mapData);
break;
case DELETE:
where = getObject(mapOptions.mapfKey, data[mapOptions.mapKey]);
promise = mapOptions.model.where(where).delete();
break;
case UPDATE:
where = getObject(mapOptions.mapfKey, data[mapOptions.mapKey]);
promise = mapOptions.model.where(where).update(mapOptions.mapData);
break;
default:
break;
}
return promise;
},
_postBelongsToRelation: function(data, value, mapOptions, parsedOptions){
return data;
},
/**
* 一对多提交
* @param {[type]} data [description]
* @param {[type]} value [description]
* @param {[type]} mapOptions [description]
* @param {[type]} parsedOptions [description]
* @return {[type]} [description]
*/
_postHasManyRelation: function(data, value, mapOptions, parsedOptions){
var type = mapOptions.type;
var mapData = mapOptions.mapData;
var model = mapOptions.model;
if (!isArray(mapData)) {
mapData = [mapData];
};
switch(type){
case ADD:
mapData = mapData.map(function(item){
item[mapOptions.mapfKey] = data[mapOptions.mapKey];
})
promise = model.addAll(mapData);
break;
case UPDATE:
promise = model.promise.then(function(){
var promises = [];
var pk = model.getPk();
mapData.forEach(function(item){
var pro;
if (item[pk]) {
pro = model.update(item);
}else{
item[mapOptions.mapfKey] = data[mapOptions.mapKey];
pro = model.add(item);
}
promises.push(pro);
});
return Promise.all(promises);
})
break;
case DELETE:
var where = getObject(mapOptions.mapfKey, data[mapOptions.mapKey]);
promise = model.where(where).delete();
break;
}
return promise;
},
/**
* 多对多提交
* @param Object data [description]
* @param object value [description]
* @param {[type]} mapOptions [description]
* @param {[type]} parsedOptions [description]
* @return {[type]} [description]
*/
_postManyToManyRelation: function(data, value, mapOptions, parsedOptions){
var self = this;
var model = mapOptions.model;
var promise = model.promise;
var rfKey = value.rfKey || (model.getModelName().toLowerCase() + "_id");
var relationTable = value.rTable || self.getRelationTableName(model);
var where;
var type = mapOptions.type;
var mapData = mapOptions.mapData;
var relationModel = self.getRelationModel(model);
if (type === DELETE || type === UPDATE) {
where = getObject(mapOptions.mapfKey, data[mapOptions.mapKey]);
promise = promise.then(function(){
return relationModel.where(where).delete();
})
};
if (type === ADD || type === UPDATE) {
promise = promise.then(function(){
if (!isArray(mapData)) {
mapData = isString(mapData) ? mapData.split(',') : [mapData];
};
var firstItem = mapData[0];
//关系数据
if (isNumberString(firstItem) || (isObject(firstItem) && (rfKey in firstItem))) {
//生成要更新的数据
var postData = mapData.map(function(item){
var key = [mapOptions.mapfKey, rfKey];
var val = [data[mapOptions.mapKey], item[rfKey] || item];
return getObject(key, val);
});
return relationModel.addAll(postData);
}else{ //实体数据
var unqiueField = model.getUniqueField();
if (!unqiueField) {
return getPromise(model.getTableName() + " table has no unqiue field", true);
};
return self._getRalationAddIds(mapData, model, unqiueField).then(function(ids){
var postData = ids.map(function(id){
var key = [mapOptions.mapfKey, rfKey];
var val = [data[mapOptions.mapKey], id];
return getObject(key, val);
});
return relationModel.addAll(postData);
})
}
})
};
return promise;
},
/**
* 插入数据,并获取插入的id集合
* @param {[type]} dataList [description]
* @param {[type]} model [description]
* @param {[type]} unqiueField [description]
* @return {[type]} [description]
*/
_getRalationAddIds: function(dataList, model, unqiueField){
var promises = [];
var ids = [];
dataList.forEach(function(item){
if (!isObject(item)) {
item = getObject(unqiueField, item);
};
var value = item[unqiueField];
if (!value) {
return true;
};
var where = getObject(unqiueField, value);
var promise = model.where(where).field(model.getPk()).find().then(function(data){
if (isEmpty(data)) {
return model.add(item).then(function(insertId){
ids.push(insertId);
})
}else{
ids.push(data[model.getPk()]);
}
})
promises.push(promise);
})
return Promise.all(promises).then(function(){
return ids;
})
},
/**
* 设置是否对数据进行校验
* @param {[type]} validate [description]
* @return {[type]} [description]
*/
validate: function(validate){
this.validateField = validate;
}
}
})

@@ -650,6 +650,11 @@ var url = require("url");

select: function(options){
options = options || {};
this.model = options.model;
var sql = this.buildSelectSql(options);
var cache = options.cache;
if (isString(options) && options.indexOf('SELECT') > -1) {
var sql = options;
var cache = arguments[1];
}else{
options = options || {};
this.model = options.model;
var sql = this.buildSelectSql(options);
var cache = options.cache;
}
var self = this;

@@ -668,6 +673,3 @@ //获取数据

return S(key, undefined, cache).then(function(value){
if (value) {
return value;
};
return queryData.call(self);
return value || queryData.call(self);
})

@@ -674,0 +676,0 @@ };

@@ -191,3 +191,4 @@ var util = require('util');

"_field": Object.keys(data || {}),
"_autoinc": false
"_autoinc": false,
"_unique": []
};

@@ -203,2 +204,4 @@ var types = {};

};
}else if (val.unique) {
fields._unique.push(key);
};

@@ -216,2 +219,16 @@ }

/**
* 获取类型为唯一的字段
* @return {[type]} [description]
*/
getUniqueField: function(data){
var unqiueFileds = this.fields._unique;
var unqiue = "";
unqiueFileds.some(function(item){
if (!data || data[item]) {
return unqiue = item;
};
});
return unqiue;
},
/**
* 获取上一次操作的sql

@@ -239,13 +256,20 @@ * @return {[type]} [description]

cache: function(key, expire, type){
//如果没有key,则根据sql语句自动生成
if (isNumber(key)) {
type = expire;
expire = key;
key = "";
if (key === undefined) {
return this;
};
this._options.cache = {
key: key,
expire: expire,
type: type
};
if (isObject(key)) {
this._options.cache = key;
}else{
//如果没有key,则根据sql语句自动生成
if (isNumber(key)) {
type = expire;
expire = key;
key = "";
};
this._options.cache = {
key: key,
expire: expire,
type: type
};
}
return this;

@@ -276,6 +300,4 @@ },

where: function(where){
if (isString(where) && where) {
where = {
"_string": where
}
if (where && isString(where)) {
where = {_string: where};
};

@@ -431,3 +453,3 @@ this._options.where = extend(this._options.where || {}, where);

parseData: function(data){
data = data || {};
data = extend({}, data);
if (!isEmpty(this.fields)) {

@@ -481,6 +503,6 @@ for(var key in data){

/**
* 添加一条或者多条数据
* 添加一条数据
* @param {[type]} data [description]
* @param {[type]} options [description]
* @param {[type]} replace [description]
* @param int 返回插入的id
*/

@@ -499,13 +521,18 @@ add: function(data, options, replace){

var self = this;
var pk = self.getPk();
//解析后的选项
var parsedOptions = {};
//解析后的数据
var parsedData = {};
return this.parseOptions(options).then(function(options){
parsedOptions = options;
return self._beforeAdd(data, parsedOptions);
}).then(function(data){
parsedData = data;
data = self.parseData(data);
return self._beforeAdd(data, options);
}).then(function(data){
return self.db.insert(data, parsedOptions, replace);
}).then(function(data){
var id = self.db.getLastInsertId();
return getPromise(self._afterAdd(id, parsedOptions));
}).then(function(){
parsedData[self.getPk()] = self.db.getLastInsertId();
return self._afterAdd(parsedData, parsedOptions);
}).then(function(){
return parsedData[self.getPk()];
});

@@ -543,6 +570,8 @@ },

var self = this;
var parsedOptions = {};
return this.parseOptions(options).then(function(options){
parsedOptions = options;
return self.db.delete(options);
}).then(function(data){
return self._afterDelete(data, options);
}).then(function(affectedRows){
return self._afterDelete(parsedOptions.where || {}, parsedOptions);
});

@@ -584,16 +613,15 @@ },

var pk = self.getPk();
var pkValue = "";
var options = {};
return this.parseOptions(options).then(function(opts){
data = self.parseData(data);
options = opts;
var parsedOptions = {};
var parsedData = {};
var affectedRows = 0;
return this.parseOptions(options).then(function(options){
parsedOptions = options;
return self._beforeUpdate(data, options);
}).then(function(data){
if (isEmpty(self._options.where) && isEmpty(options.where)) {
parsedData = data;
data = self.parseData(data);
if (isEmpty(parsedOptions.where) || isEmpty(parsedOptions.where[pk])) {
// 如果存在主键数据 则自动作为更新条件
if (!isEmpty(data[pk])) {
var where = {};
where[pk] = data[pk];
options.where = where;
pkValue = data[pk];
parsedOptions.where = getObject(pk, data[pk]);
delete data[pk];

@@ -603,11 +631,11 @@ }else{

}
};
return self.db.update(data, options);
}else{
parsedData[pk] = parsedOptions.where[pk];
}
return self.db.update(data, parsedOptions);
}).then(function(data){
if (pkValue) {
data[pk] = pkValue;
};
return self._afterUpdate(data, options);
}).then(function(data){
return data.affectedRows;
affectedRows = data.affectedRows;
return self._afterUpdate(parsedData, parsedOptions);
}).then(function(){
return affectedRows;
})

@@ -702,4 +730,3 @@ },

}).then(function(data){
var result = data[0] ? data[0] : {};
return self._afterFind(result, parsedOptions);
return self._afterFind(data[0] || {}, parsedOptions);
})

@@ -706,0 +733,0 @@ },

@@ -80,3 +80,4 @@ /**

"default": item.Default,
"primary": item.Key == 'pri',
"primary": item.Key === 'PRI',
"unique": item.Key === 'UNI',
"autoinc": item.Extra.toLowerCase() == 'auto_increment'

@@ -83,0 +84,0 @@ };

{
"name": "thinkjs",
"description": "thinkphp web framework for nodejs",
"version": "0.3.17",
"version": "0.3.18",
"author": {

@@ -6,0 +6,0 @@ "name": "welefen",

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc