internet-information-services
Version:
internet-information-services
1,567 lines (905 loc) • 40.2 kB
JavaScript
"use strict";
var scopePath = {};
exports.setPath = function (path) {
ReadOnly(scopePath, "wwwroot", path);
};
exports.init = function (opt) {
opt = opt || {};
opt.mime = opt.mime || {};
for (var mime in Mime)
if (Mime.hasOwnProperty(mime) && !opt.mime.hasOwnProperty(mime))
opt.mime[mime] = Mime[mime];
opt.html = opt.html || '<!DOCTYPE html>\n<html lang="{lang}">\n<head>\n<meta charset="{charset}" />\n<title>{controller} - {action} {filter}</title>\n</head>\n<body>\n\n</body>\n</html>'
.format({lang: opt.lang || "zh-cn", charset: opt.charset || "UTF-8"});
if (!fs.existsSync(scopePath.wwwroot + "/wwwroot"))
fs.mkdirSync(scopePath.wwwroot + "/wwwroot");
if (!fs.existsSync(scopePath.wwwroot + "/wwwroot/index.html"))
fs.appendFile(scopePath.wwwroot + "/wwwroot/index.html", '<!DOCTYPE html>\n<html lang="{lang}">\n<head>\n<meta charset="{charset}" />\n<title>Index</title>\n</head>\n<body>\nIndex\n</body>\n</html>'
.format({lang: opt.lang || "zh-cn", charset: opt.charset || "UTF-8"}), function () {
});
var tables = [];
if (opt.project)
buildProject.call(opt, opt.project, tables);
if (opt.shared && typeof opt.shared.forEach === "function")
buildShared(opt.shared);
opt.db = opt.db || {};
createDBServer(opt, tables);
opt.db.BreakCursor = {};
return function (request, response) {
var scope = {
Auth: {},
global: opt.global,
isEnd: false
};
if (request.headers.cookie)
request.headers.cookie.split("; ").forEach(function (cookie) {
var arr = cookie.split("=");
scope.Auth[arr[0]] = arr[1];
});
scope.Auth.set = function (user, role, time) {
setAuth(user, role, response, time);
};
scope.Auth.clear = function () {
clearAuth(response);
};
scope.request = request;
scope.response = response;
response.headers = {};
var urlObj = url.parse(request.url, true);
var routeList = urlObj.pathname.substring(1).toLowerCase().split("/");
scope.project = opt.project;
scope.controller = routeList[0];
scope.action = routeList[1];
scope.filter = routeList[2];
scope.id = routeList[3];
scope.method = request.method.toLowerCase();
scope.redirect = function (url) {
if (!scope.isEnd) {
scope.isEnd = true;
response.headers.Location = url;
response.writeHead(302, response.headers);
response.end();
}
};
if (typeof opt.gateway === "function" && opt.gateway(scope) === false) {
if (!scope.isEnd) {
scope.isEnd = true;
response.writeHead(400, response.headers);
response.end();
}
return;
}
if (opt.project.hasOwnProperty(scope.controller)) {
scope.project = opt.project;
scope.query = urlObj.query;
switch (scope.method) {
case "get":
route(scope);
break;
case "put":
case "delete":
case "post":
var chunks = [];
var size = 0;
request.on("data", function (chunk) {
chunks.push(chunk);
size += chunk.length;
});
request.on("end", function () {
scope.data = parsePost(
request.headers["content-type"] || "application/x-www-form-urlencoded",
Buffer.concat(chunks, size),
scopePath.wwwroot
);
route(scope);
});
break;
default:
response.end();
break;
}
} else {
var pathname = scopePath.wwwroot + "/wwwroot" + (urlObj.pathname.length === 1 ? "/index.html" : urlObj.pathname);
if (fs.existsSync(pathname)) {
var suffix = pathname.substr(pathname.lastIndexOf(".") + 1);
response.writeHead(200, {"Content-Type": opt.mime[suffix] ? opt.mime[suffix] : "text/plain"});
fs.createReadStream(pathname).pipe(response);
} else {
response.writeHead(404, {"Content-Type": "text/html"});
if (fs.existsSync(scopePath.wwwroot + "/views/shared/404.html"))
response.write(fs.readFileSync(scopePath.wwwroot + "/views/shared/404.html").toString().replaceAll("{pathname}", pathname.substring(scopePath.wwwroot.length)));
}
}
};
};
function createDBServer(opt, tables) {
if (typeof opt.localDB === "string") {
var indexeddbjs = require("indexeddb-js");
var sqlite3 = require("sqlite3");
var engine = new sqlite3.Database(scopePath.wwwroot + "/" + opt.localDB + ".sqlite3", sqlite3.OPEN_READWRITE | sqlite3.OPEN_CREATE);
scope = indexeddbjs.makeScope('sqlite3', engine);
return IDB(opt.db, opt.localDB, tables);
} else if (typeof opt.mongoDB === "string") {
return MDB(opt.db, opt.mongoDB, tables);
}
}
var IDB, scope, MDB, ObjectId, database;
(function () {
var key = "_";
var recent = "-";
function fClone(source, update, target) {
var obj = target || {}, timestamp = Date.now();
for (var attr in source)
if (Object.hasOwnProperty.call(source, attr))
obj[attr] = source[attr];
obj[key] = source[key] || timestamp;
obj[recent] = update ? timestamp : source[recent] || timestamp;
return obj;
}
function fSuccess(target) {
if (typeof target.onsuccess === "function") {
var f = target.onsuccess;
delete target.onsuccess;
f.apply(target, [].splice.call(arguments, 1));
}
}
function fError(target) {
console.error([].splice.call(arguments, 1));
if (typeof target.onerror === "function") {
var f = target.onerror;
delete target.onerror;
f.apply(target, [].splice.call(arguments, 1));
}
}
function addTask(store, data, result) {
var request = store.add(fClone(data.shift()));
request.onsuccess = function (e) {
if (data.length)
addTask(store, data, result);
else
fSuccess(result, e);
};
request.onerror = function (e) {
fError(result, e);
};
}
function fStore(store) {
return {
add: function (data) {
var result = {};
if (getType(data).toLowerCase() === "array") {
if (data.length)
addTask(store, data, result);
else
fSuccess(result);
} else {
var request = store.add(fClone(data));
request.onsuccess = function (e) {
fSuccess(result, e);
};
request.onerror = function (e) {
fError(result, e);
};
}
return result;
},
default: function (f) {
var result = {};
if (typeof f === "function") {
store.openCursor().onsuccess = function (event) {
var cursor = event.target.result;
if (cursor) {
if (f(cursor.value)) {
fClone(cursor.value, false, result);
ReadOnly(result, "update", function () {
var request = store.put(fClone(this, true));
request.onsuccess = function () {
fSuccess(result, result);
};
request.onerror = function (e) {
fError(result, e);
};
return this;
});
ReadOnly(result, "delete", function () {
var r = this;
var request = store.delete(r[key]);
request.onsuccess = function () {
fSuccess(r, r);
};
request.onerror = function (e) {
fError(r, e);
};
return r;
});
fSuccess(result, result);
} else
cursor.continue();
} else
fSuccess(result, null);
};
}
return result;
},
where: function (f) {
var request = store.openCursor();
var results = [];
request.onsuccess = function (event) {
var cursor = event.target.result;
if (cursor) {
var result;
if (typeof f === "function") {
if (f(cursor.value)) {
result = fClone(cursor.value);
ReadOnly(result, "update", function () {
var request = store.put(fClone(this, true));
request.onsuccess = function () {
fSuccess(result, result);
};
request.onerror = function (e) {
fError(result, e);
};
return this;
});
ReadOnly(result, "delete", function () {
var r = this;
var request = store.delete(r[key]);
request.onsuccess = function () {
fSuccess(r, r);
};
request.onerror = function (e) {
fError(r, e);
};
return r;
});
results.push(result);
}
cursor.continue();
} else {
result = fClone(cursor.value);
ReadOnly(result, "update", function () {
var request = store.put(fClone(this, true));
request.onsuccess = function () {
fSuccess(result, result);
};
request.onerror = function (e) {
fError(result, e);
};
return this;
});
ReadOnly(result, "delete", function () {
var r = this;
var request = store.delete(r[key]);
request.onsuccess = function () {
fSuccess(r, r);
};
request.onerror = function (e) {
fError(r, e);
};
return r;
});
results.push(result);
cursor.continue();
}
} else
fSuccess(results, results);
};
return results;
},
page: function (page, count) {
count = count || 20;
var request = store.openCursor();
var results = [];
var index = 0;
request.onsuccess = function (event) {
var cursor = event.target.result;
var start = page * count;
var end = start + count;
if (cursor) {
index++;
if (index > start && index <= end) {
var result = fClone(cursor.value);
ReadOnly(result, "update", function () {
var request = store.put(fClone(this, true));
request.onsuccess = function () {
fSuccess(result, result);
};
request.onerror = function (e) {
fError(result, e);
};
return this;
});
ReadOnly(result, "delete", function () {
var r = this;
var request = store.delete(r[key]);
request.onsuccess = function () {
fSuccess(r, r);
};
request.onerror = function (e) {
fError(r, e);
};
return r;
});
results.push(result);
}
cursor.continue();
} else
fSuccess(results, results, index);
};
return results;
},
count: function () {
var request = store.openCursor();
var result = {};
var index = 0;
request.onsuccess = function (event) {
var cursor = event.target.result;
if (cursor) {
index++;
cursor.continue();
} else
fSuccess(result, index);
};
return result;
}
};
}
function fComplete(value, collection) {
ReadOnly(value, "update", function () {
collection.updateOne({_id: ObjectId(this._id)}, {$set: this}, function (err, result) {
if (err)
fError(value, err);
else
fSuccess(value, result);
});
return this;
});
ReadOnly(value, "delete", function () {
var r = this;
collection.deleteOne({_id: ObjectId(this._id)}, function (err, result) {
if (err)
fError(r, err);
else
fSuccess(r, result);
});
return r;
});
return value;
}
function fCursor(cursor, f, result, arr, collection) {
if (cursor.hasNext() && !cursor.isClosed()) {
cursor.next().then(function (value) {
if (value === null) {
fSuccess(result, arr);
return;
}
var r;
if (arr) {
if (typeof f === "function") {
r = f(value);
if (r) {
arr.push(fComplete(value, collection));
if (r === BreakCursor) {
cursor.close();
fSuccess(result, arr);
return;
}
}
} else
arr.push(fComplete(value, collection));
fCursor(cursor, f, result, arr, collection);
} else {
r = f(value);
if (r) {
cursor.close();
fSuccess(result, fComplete(value, collection));
} else
fCursor(cursor, f, result, arr, collection);
}
}).catch(function (e) {
cursor.close();
fError(result, e);
});
} else
fSuccess(result, arr);
}
function fCollection(collection) {
return {
add: function (data) {
var result = {};
collection.insert(data, function (err, res) {
if (err)
fError(result, err);
else
fSuccess(result, res);
});
return result;
},
default: function (f) {
var result = {};
if (typeof f === "function") {
fCursor(collection.find(), f, result, null, collection);
}
return result;
},
where: function (f) {
var result = {};
fCursor(collection.find(), f, result, [], collection);
return result;
},
page: function (page, count) {
var result = {};
count = count || 20;
var cursor = collection.find();
cursor.skip(page * count).limit(count).toArray().then(function (arr) {
cursor.count().then(function (count) {
fSuccess(result, arr, count);
}).catch(function (e) {
fError(result, e);
});
}).catch(function (reason) {
});
return result;
},
count: function () {
var result = {};
collection.find().count().then(function (count) {
fSuccess(result, count);
}).catch(function (e) {
fError(result, e);
});
return result;
}
};
}
function fContext(db, context) {
var transaction = db.transaction(db.objectStoreNames, "readwrite");
[].forEach.call(db.objectStoreNames, function (store) {
context[store] = fStore(transaction.objectStore(store));
});
fSuccess(context, db);
}
IDB = function (context, name, tables) {
database = context;
name = name || "idb";
var db;
var request = scope.indexedDB.open(name),
add = [], del = [];
request.onsuccess = function () {
db = request.result;
if (tables && tables.constructor && tables.constructor.name === "Array") {
tables.forEach(function (table) {
if (db.objectStoreNames.indexOf(table) < 0)
add.push(table);
});
tables.forEach.call(db.objectStoreNames, function (table) {
if (tables.indexOf(table) < 0)
del.push(table);
});
} else if (db.objectStoreNames.length === 0) {
add.push("temp");
}
if (add.length + del.length > 0) {
db.close();
request = scope.indexedDB.open(name, db.version + 1);
request.onsuccess = function (event) {
db = event.target.result;
fContext(db, context);
};
request.onupgradeneeded = function (event) {
db = event.target.result;
add.forEach(function (store) {
db.createObjectStore(store, {keyPath: key})
.createIndex(key, key, {unique: true});
});
del.forEach(function (store) {
db.deleteObjectStore(store);
});
};
} else
fContext(db, context);
};
};
MDB = function (context, connStr, tables) {
database = context;
var mongodb = require("mongodb");
var client = mongodb.MongoClient;
ObjectId = mongodb.ObjectId;
client.connect(connStr, function (err, client) {
if (err)
console.error("连接失败!", err);
else {
var db = client.db();
if (tables && tables.constructor && tables.constructor.name === "Array") {
tables.forEach(function (collection) {
context[collection] = fCollection(db.collection(collection));
});
}
fSuccess(context, db, mongodb);
}
});
};
})();
function ReadOnly(target, key, value) {
if (target !== null && target !== undefined)
Object.defineProperty(target, key, {
value: value,
writable: false,
configurable: false
});
}
function parsePost(enctype, data, staticDir) {
var arr = enctype.split(";");
var obj = {};
switch (arr[0]) {
case "text/plain":
data.toString().split("\r\n").forEach(function (value) {
if (value.length) {
obj[value.substring(0, value.indexOf("="))] = value.substring(value.indexOf("=") + 1);
}
});
break;
case "application/x-www-form-urlencoded":
obj = querystring.parse(data.toString());
break;
case "multipart/form-data":
var boundary = new Buffer("--" + arr[1].substring(arr[1].indexOf("=") + 1));
var i = data.indexOf(boundary);
while (data.indexOf(boundary, i + 1) >= 0) {
parsePostData(data.slice(i + boundary.length + 2, data.indexOf(boundary, i + 1)), obj, staticDir);
i = data.indexOf(boundary, i + 1);
}
break;
}
return obj;
}
function parsePostData(buffer, obj, staticDir) {
var key = new Buffer("\r\n\r\n");
var head = buffer.slice(0, buffer.indexOf(key)).toString();
var body = buffer.slice(buffer.indexOf(key) + 4, buffer.length - 2);
key = " name=\"";
var i = head.indexOf(key) + key.length;
var name = head.substring(i, head.indexOf("\"", i));
obj[name] = {name: name};
key = " filename=\"";
if (head.indexOf(key, i) > 0) {
i = head.indexOf(key) + key.length;
obj[name].filename = head.substring(i, head.indexOf("\"", i));
}
key = "Content-Type:";
if (head.indexOf(key, i) > 0) {
i = head.indexOf(key) + key.length;
obj[name].type = head.substring(i).trim();
}
if (obj[name].filename && obj[name].type) {
obj[name].data = body;
obj[name].save = function (path, filename, sync) {
path = String(path || "temp");
if (!fs.existsSync("{0}/wwwroot/{1}".format(staticDir, path)))
fs.mkdirSync("{0}/wwwroot/{1}".format(staticDir, path));
if (!filename) {
path = "{dir}/{name}.{suffix}"
.format({
dir: path,
name: this.name,
suffix: this.filename.indexOf(".") >= 0 ? this.filename.substring(this.filename.lastIndexOf(".") + 1) : this.type.substring(this.type.indexOf("/") + 1)
})
} else if (filename.indexOf(".") < 0)
path = "{0}/{1}.{2}".format(path, filename, this.filename.indexOf(".") >= 0 ? this.filename.substring(this.filename.lastIndexOf(".") + 1) : this.type.substring(this.type.indexOf("/") + 1));
else
path = "{0}/{1}".format(path, filename);
if (sync)
fs.writeFileSync("{0}/wwwroot/{1}".format(staticDir, path), this.data);
else
fs.writeFile("{0}/wwwroot/{1}".format(staticDir, path), this.data, function () {
});
return "/" + path;
};
} else
obj[name] = body.toString();
}
function route(scope) {
scope.action = scope.action || "index";
scope.send = function (data) {
if (!scope.isEnd) {
scope.isEnd = true;
scope.response.headers["Content-Type"] = scope.response.headers["Content-Type"] || "text/html";
scope.response.writeHead(200, scope.response.headers);
scope.response.write(data);
scope.response.end();
}
};
if (typeof scope.project[scope.controller] === "function") {
scope.fn = scope.project[scope.controller];
scope.path = scopePath.wwwroot + "/views/" + scope.controller + "/index.html";
view(scope);
} else if (scope.project[scope.controller].hasOwnProperty(scope.action)) {
if (typeof scope.project[scope.controller][scope.action] === "function") {
scope.fn = scope.project[scope.controller][scope.action];
scope.path = scopePath.wwwroot + "/views/{0}/{1}.html".format(scope.controller, scope.action);
view(scope);
} else {
scope.filter = scope.filter || "index";
if (scope.project[scope.controller][scope.action] && scope.project[scope.controller][scope.action].hasOwnProperty(scope.filter)) {
scope.fn = scope.project[scope.controller][scope.action][scope.filter];
scope.path = scopePath.wwwroot + "/views/{0}/{1}/{2}.html".format(scope.controller, scope.action, scope.filter);
view(scope);
} else if (scope.project[scope.controller][scope.action] === null) {
scope.path = scopePath.wwwroot + "/views/{0}/{1}.html".format(scope.controller, scope.action);
view(scope);
} else {
notFound(scope.response, scope.controller + "/" + scope.action + "/" + scope.filter);
}
}
} else {
notFound(scope.response, scopePath.wwwroot + "/" + scope.controller + "/" + scope.action);
}
}
function view(scope) {
if (database)
for (var method in database[scope.controller])
if (database[scope.controller].hasOwnProperty(method))
scope[method] = database[scope.controller][method];
var html = "";
if (fs.existsSync(scope.path))
html = fs.readFileSync(scope.path).toString();
while (html.indexOf("{/") >= 0) {
var start = html.indexOf("{/");
var end = html.indexOf("}", start);
if (start < end) {
var value = html.substring(start, end + 1).trim();
if (value.length > 3) {
var key = value.substring(1, value.length - 1);
var partial = scopePath.wwwroot + "/views/shared{0}.html".format(key);
if (fs.existsSync(partial))
html = html.replaceAll(value, fs.readFileSync(partial).toString());
else
html = html.replaceAll(value, "<!-- 模板 {0} 不存在 -->".format(key));
}
}
}
if (typeof scope.fn === "function") {
scope.async = function (data, noHTML) {
data = data || this;
if (noHTML)
scope.send(getType(data).toLowerCase() === "string" ? data : JSON.stringify(data));
else if (data)
scope.send(script(html, data));
else
scope.send(script(html));
return false;
};
var result = scope.fn.call(scope, scope);
if (result === false) {
} else if (result === undefined) {
scope.send(script(html, scope));
} else {
scope.send(getType(result).toLowerCase() === "string" ? result : JSON.stringify(result));
}
} else
scope.send(script(html, scope));
}
function clearAuth(response) {
response.headers["Set-Cookie"] = [
"User=; expires=Thu, 01 Jan 1970 00:00:00 GMT; path=/; samesite=lax",
"Role=; expires=Thu, 01 Jan 1970 00:00:00 GMT; path=/; samesite=lax"
];
}
function setAuth(user, role, response, time) {
time = time || 365;
var date = new Date();
date.setTime(date.getTime() + time * 24 * 3600 * 1000);
date = date.toGMTString();
var cookies = [];
if (user)
cookies.push("User={0}; expires={1}; path=/; samesite=lax; httponly".format(user, date));
if (role)
cookies.push("Role={0}; expires={1}; path=/; samesite=lax; httponly".format(role, date));
response.headers["Set-Cookie"] = cookies;
}
function script(html, scope) {
var start = "<script server>", end = "<\/script>";
var temp = html;
while (temp.indexOf(start) >= 0) {
var i = temp.indexOf(start);
var code = temp.substring(temp.indexOf(start) + start.length, temp.indexOf(end, i)),
oldCode = temp.substring(temp.indexOf(start), temp.indexOf(end, i) + end.length),
newCode = "";
temp = temp.substr(temp.indexOf(end, i) + end.length);
code.split("\n").forEach(function (line) {
line = line.trim();
if (line.length) {
switch (line[0]) {
case "<":
newCode += "scope.__str__+='" + line + "'\n";
break;
case "\"":
case "'":
newCode += "scope.__str__+=" + line + "\n";
break;
default:
newCode += line + "\n";
break;
}
}
});
scope.__str__ = "";
try {
new Function("scope", "document", newCode)(scope, {
write: function (str) {
scope.__str__ += str;
}
});
} catch (e) {
scope.__str__ = "<!--server script 代码有误:" + e + "-->";
}
html = html.replace(oldCode, scope.__str__);
delete scope.__str__;
}
return html.format(scope);
}
function notFound(response, pathname) {
response.writeHead(404, {"Content-Type": "text/html"});
if (fs.existsSync(scopePath.wwwroot + "/views/shared/404.html"))
response.write(fs.readFileSync(scopePath.wwwroot + "/views/shared/404.html").toString().replaceAll("{pathname}", pathname));
response.end();
}
function buildShared(shared) {
shared.push("404");
shared.push("500");
if (!fs.existsSync(scopePath.wwwroot + "/views/shared"))
fs.mkdirSync(scopePath.wwwroot + "/views/shared");
shared.forEach(function (partial) {
var path = scopePath.wwwroot + "/views/shared/{0}.html".format(partial);
var dir = partial.substring(0, partial.lastIndexOf("/"));
if (dir.length) {
dir = dir.split("/");
var path2 = scopePath.wwwroot + "/views/shared";
for (var i = 0; i < dir.length; i++) {
path2 += "/" + dir[i];
if (!fs.existsSync(path2))
fs.mkdirSync(path2);
}
}
if (!fs.existsSync(path))
fs.appendFileSync(path, "");
});
}
function buildProject(Project, tables) {
var project = {}, controller, action, filter, dir, path;
if (!fs.existsSync(scopePath.wwwroot + "/views"))
fs.mkdirSync(scopePath.wwwroot + "/views");
for (var Controller in Project)
if (Project.hasOwnProperty(Controller)) {
controller = Controller.trim().toLowerCase();
tables.push(controller);
dir = scopePath.wwwroot + "/views/" + controller;
if (!fs.existsSync(dir))
fs.mkdirSync(dir);
if (getLen(Project[Controller])) {
project[controller] = {};
for (var Action in Project[Controller])
if (Project[Controller].hasOwnProperty(Action)) {
action = Action.trim().toLowerCase();
if (getLen(Project[Controller][Action])) {
path = "{0}/{1}".format(dir, action);
if (!fs.existsSync(path))
fs.mkdirSync(path);
project[controller][action] = {};
for (var Filter in Project[Controller][Action])
if (Project[Controller][Action].hasOwnProperty(Filter)) {
filter = Filter.trim().toLowerCase();
project[controller][action][filter] = Project[Controller][Action][Filter];
if (!fs.existsSync("{0}/{1}.html".format(path, filter)))
fs.appendFileSync("{0}/{1}.html".format(path, filter), this.html.format({
controller: controller,
action: action,
filter: filter
}));
}
} else {
project[controller][action] = Project[Controller][Action];
path = "{0}/{1}.html".format(dir, action);
if (!fs.existsSync(path))
fs.appendFileSync(path, this.html.format({controller: controller, action: action}));
}
}
} else {
if (typeof Project[Controller] === "function")
project[controller] = Project[Controller];
if (!fs.existsSync(dir + "/index.html"))
fs.appendFileSync(dir + "/index.html", this.html.format({controller: controller, action: "index"}));
}
}
this.project = project;
}
function getLen(obj) {
var len = 0;
for (var attr in obj)
if (Object.hasOwnProperty.call(obj, attr))
len++;
return len;
}
function getType(obj) {
if (obj && obj.constructor && obj.constructor.name)
return obj.constructor.name;
var type = Object.prototype.toString.call(obj);
return type.substring(type.indexOf(" ") + 1, type.length - 1);
}
function matchType(obj, type0, type1, type2) {
return [].indexOf.call(arguments, getType(obj)) > 0;
}
function recursionFormat(str, key, obj, count) {
if (count < 6)
count++;
else
return str;
if (getType(obj).toLowerCase() !== "string" && getLen(obj)) {
for (var attr in obj)
if (!(attr.length > 1 && attr[0] === "_")
&& Object.hasOwnProperty.call(obj, attr)
&& matchType(obj[attr], "String", "Object", "Boolean", "Number", "Array"))
str = recursionFormat(str, key + "." + attr, obj[attr], count);
} else if (obj !== undefined)
str = str.replaceAll("{" + key + "}", obj);
return str;
}
String.prototype.format = function () {
if (this.constructor.name !== "String")
return;
var str = this;
for (var i = 0; i < arguments.length; i++) {
var obj = arguments[i];
if (getType(obj).toLowerCase() === "object") {
for (var attr in obj)
if (Object.hasOwnProperty.call(obj, attr)
&& matchType(obj[attr], "String", "Object", "Boolean", "Number", "Array"))
str = recursionFormat(str, attr, obj[attr], 0);
} else
str = str.replaceAll("{" + i + "}", obj);
}
return str + "";
};
String.prototype.replaceAll = function (oldStr, newStr) {
var str = this;
try {
oldStr = String(oldStr);
newStr = String(newStr);
if (newStr.indexOf(oldStr) < 0)
while (str.indexOf(oldStr) >= 0)
str = str.replace(oldStr, newStr);
} catch (e) {
return this;
}
return str;
};
Date.prototype.format = function (fmt) {
var o = {
"M+": this.getMonth() + 1,
"d+": this.getDate(),
"h+": this.getHours(),
"m+": this.getMinutes(),
"s+": this.getSeconds(),
"q+": Math.floor((this.getMonth() + 3) / 3),
"S": this.getMilliseconds()
};
if (/(y+)/.test(fmt))
fmt = fmt.replace(RegExp.$1, (this.getFullYear() + "").substr(4 - RegExp.$1.length));
for (var k in o)
if (new RegExp("(" + k + ")").test(fmt))
fmt = fmt.replace(RegExp.$1, (RegExp.$1.length === 1) ? (o[k]) : (("00" + o[k]).substr(("" + o[k]).length)));
return fmt;
};
var fs = require("fs");
var url = require("url");
var querystring = require("querystring");
var Mime = {
html: "text/html",
js: "application/javascript",
css: "text/css",
json: "application/json",
jpg: "image/jpeg",
png: "image/png",
gif: "image/gif",
bmp: "image/bmp"
};