npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

entity-frame

v1.1.6

Published

entity-frame

Readme

entity-frame

欢迎使用entity-frame框架,如果是使用过asp.net core的mvc框架的码友应该会有亲切感,本框架还在测试阶段,Bug欢迎留言反馈,给你们带来的麻烦我十分抱歉。邮箱:[email protected]

2.0 后将使用ES6的标准重新编写。

无http服务版本、http/https服务移步:https://www.npmjs.com/package/internet-information-services

Bug记录

2017.12.21 影响版本 0.8.17- 没有opt.localDB和opt.mongoDB引起的错误

2017.12.23 影响版本 0.8.24- 没有mongoDB Cursor Closed引起的错误

2018.01.09 影响版本 1.1.0- IE浏览器下mime类型的错误。

新变动

  • mongodb版本

1.1.6

mongodb使用3.0以上版本

  • 返回mongodb对象

1.1.3

如果使用mongodb的话会在context.onsuccess返回mongodb对象。

mongodb.ObjectId(id)

  • 添加mime类型的对象

1.1.0

opt.mime = {mp3: "audio/mpeg"};

  • 增加全局对象 global 可在路由方法和视图中使用

0.9.0 添加自动生成{static}/index.html,加入 测试记录.html 文件

opt.global

数据库支持

本框架支持indexeddb或mongoDB

npm install indexeddb-js sqlite3

npm install mongodb

实例

引用框架

var ef = require("entity-frame");

初始化

var context = ef.init(          //初始化
    {
        project: project,       //Object (必须)      项目主体
        // gateway: gateway,    //Function          每次网络请求都会调用此回调
        // port: 8080,          //String,Number     监听端口
        // static: "wwwroot",   //String            静态文件目录
        // mime: {mp3: "audio/mpeg"},   //Object	mime类型的对象
        // html: '{/head}\n\n{/foot}',  //String    自定义全局模板
        // shared: shared,      //Array             共享模板数组
        // global: global,      //Onject            全局对象
        // lang: "zh-cn",       //String            本地化
        // charset: "UTF-8",    //String            html编码
        // localDB: "idb"       //String            本地数据库名称
        // mongoDB: "mongodb://localhost:27017/mdb" //String    mongoDB数据库连接字符串
    }
);
context.onsuccess = function (db, mongodb) { //数据库连接成功回调,如果使用mongodb的话会返回mongodb对象。

    console.log("数据库连接成功。");
};

参数详细说明

opt.gateway

...
    gateway: function (scope) {
    
        scope.Auth          //Object    身份验证信息
        scope.global        //Object    全局对象
        scope.controller    //String    控制器名称
        scope.action        //String    方法名称
        scope.filter        //String    过滤器名称
        scope.id            //String    id值
        scope.method        //String    请求方法 get、post、put、delete
        scope.redirect      //Function  重定向方法 arg1=/*url*/
        scope.request       //Object    Node.js http的request对象
        scope.response      //Object    Node.js http的response对象
        scope.request.headers["content-length"] //Int 请求数据的大小
		
        return false;       //将拒绝该次请求
    },
...

实例

function gateway(scope) {

    if (scope.Auth.Role !== "admin" && scope.controller === "admin" && scope.action !== "login") {

        scope.redirect("/admin/login");

        return false;
    }

    if (scope.Auth.Role !== "admin"
        && (scope.controller === "user" && scope.action === "list")) {

        scope.redirect("/home");

        return false;
    }
    
    ...
    //也可以在这里编写防攻击、恶意访问逻辑,return false;将拒绝该次请求
}

opt.post 设置监听端口默认值为 80

opt.static 设置静态目录默认值为 "wwwroot"

opt.html 设置自定义全局模板

默认值为:

<!DOCTYPE html>
<html lang="{lang}">
<head>
    <meta charset="{charset}">
    <title>{controller} - {action} {filter}</title>
</head>
<body>

</body>
</html>

opt.lang 设置默认模板的本地化

opt.charset 设置默认模板的编码

opt.localDB 使用本地数据库indexeddb的数据库名称,须引用 npm install indexeddb-js sqlite3,如果不使用就不用引入。

opt.mongoDB 使用mongoDB的连接字符串,须引用npm install [email protected],暂时支持2.2.33,还需打开mongoDB服务,移步http://www.runoob.com/mongodb/mongodb-window-install.html,如果不使用就不用引入。

  • 重要参数

opt.shared 共享模板目录

引用结构:{/{path}/{file}}

模板文件将自动生成在views下shared文件夹中

opt.shared = ["head", "foot", "user/head", "user/foot", "templet/partial/page"];

自动生成的文件结构

views ─ shared ┬ head.html
               ├ foot.html
               ├ user ─────┬ head.html
               │           └ foot.html
               └ templet ─── partial ── page.html

实例

<html>
{/user/head}
<div>内容1</div>
{/templet/partial/page}
<div>内容2</div>
{/foor}
</html>

opt.project 项目的主要重要结构和逻辑处理中心

路由结构:://{domain}/{controller}/{action}/{filter}/{id}

var project = {
    controller1: {
        action1: {
            filter1: ...,
            filter2: ...,
            ...
        },
        action2: ...,
        ...
    },
    controller2: ...,
    ...
};

视图文件将自动生成在views文件夹中

views ┬ controller1 ┬ action1 ┬ filter1
      │             │         ├ filter2
      │             │         └ ...
      │             ├ action2
      │             │
      │             └ ...
      ├ controller2
      │
      └ ...

实例1

var project = { //大小写不敏感
    LOG: {
        Add: function (scrop) { // todo },
        list: function (scrop) { // todo }
    },
    admin: function (scrop) { // todo },
    user: {
        index: null,
        login: function (scrop) { // todo },
        logon: function (scrop) { // todo },
        logout: function (scrop) { // todo },
        vip: {
            index: null,
            logout: null
        },
        svip: {
            index: null,
            logout: function (scrop) { // todo }
        }
    }
};

自动生成的文件结构

views ┬ log ──┬─── add.html
      │       └── list.html
      ├ admin ── index.html
      └ user ─┬─ index.html
              ├─ login.html
              ├─ logon.html
              ├ logout.html
              ├ vip ────────┬─ index.html
              │             └ logout.html
              └ svip ───────┬─ index.html
                            └ logout.html

请求(实例1)

参数方式1:filter, id;

://domain/log/list/user/201712

路由到方法 project.log.list(scope)

方法中使用:

scope.where(l => l.filter === scope.filter && l.data >= scope.id).onsuccess = function (list) {
    list.forEach(log) { //todo };
};

页面内使用

<html>
<body>
<h2>{filter}</h2>
日期:{id}
...
</body>
</html>

参数方式2:querystring;

://domain/log/list?filter=user&date=201712

路由到方法 project.log.list(scope)

方法中使用:

scope.where(l => l.filter === scope.query.filter && l.data >= scope.query.date).onsuccess = function (list) {
    list.forEach(log) { //todo };
};

页面内使用

<html>
<body>
<h2>{query.filter}</h2>
日期:{query.date}
...
</body>
</html>

参数方式3:data; //post,put,delete

://domain/log/list

路由到方法 project.log.list(scope)

方法中使用:

scope.where(l => l.filter === scope.data.filter && l.data >= scope.data.date).onsuccess = function (list) {
    list.forEach(log) { //todo };
};

//文件上传处理
scope.data.file1.save("file", "f1.jpg");//异步处理
//scope.data.file1.save("file", "f1.jpg", true);//同步处理

//参数缺省,如:<input type="file" name="i1" /> //type: image/jpeg
//scope.data.file1.save("file"); 等价 scope.data.file1.save("file", "i1.jpeg");

页面内使用

<html>
<body>
<h2>{data.filter}</h2>
日期:{data.date}
...
</body>
</html>

参数方式4:混合使用

://domain/log/list/user?date=201712

路由到方法 project.log.list(scope)

方法中使用:

scope.where(l => l.filter === scope.filter && l.data >= scope.query.date).onsuccess = function (list) {
    list.forEach(log) { //todo };
};

//文件上传处理
scope.data.file1.save("file", "f1.jpg");//异步处理
//scope.data.file1.save("file", "f1.jpg", true);//同步处理

//参数缺省,如:<input type="file" name="i1" /> //type: image/jpeg
//scope.data.file1.save("file"); 等价 scope.data.file1.save("file", "i1.jpeg");

页面内使用

<html>
<body>
<h2>{filter}</h2>
日期:{data.date}
...
</body>
</html>

服务器端脚本

<script server>

    // todo
    
</script>

循环5个div

1、//不推荐

<script server>

    for (var i = 0; i < 5; i++)
    
        <div>{id}</div>
    
</script>

2、//推荐

<script server>

    for (var i = 0; i < 5; i++)
    
        '<div>{0}</div>'.format(i);
    
</script>

3、

<script server>

    for (var i = 0; i < 5; i++)
    
        document.write('<div>{0}</div>'.format(i));
    
</script>

可以使用路由到的方法传递过来的数据,默认为scope的数据

<script server>

    "" + scope.method;
    
    "name: {query.name}, age: {query.age}.".format(scope);
    
    if (!scope.Auth.user)
    
        scope.redirect("/user/login");
        
    else
    
        '<h4>登录成功,正在跳转</h4><meta http-equiv="Refresh" content="1; url=/home" />';
    
</script>

数据库使用

如果配置了数据库context.onsuccess会返回一个数据库context实例,数据库自动按照控制器生成对应的数据表,context里面就有相应的表实体。

如 实例1:

context.user
context.admin
context.log
context.log.add({title: "Login", date: Date.now()}).onsuccess = function (ev) {};
context.log.add([{title: "Logon", date: Date.now()}, {title: "Login", date: Date.now()}]).onsuccess = function (ev) {};

//在controller对应的action中
scope.add({title: "Login", date: Date.now()}).onsuccess = function (ev) {};
scope.add([{title: "Logon", date: Date.now()}, {title: "Login", date: Date.now()}]).onsuccess = function (ev) {};

查一个

context.user.default(u => u.uid === Uid && u.pwd === Pwd).onsuccess = function (result) {
    if (result === null)
        ;// todo
    else
        ;// todo 
}
//在controller对应的action中
scope.default(u => u.uid === scope.data.uid && u.pwd === scope.data.pwd).onsuccess = function (result) {
    if (result === null)
        ;// todo
    else
        ;// todo 
}

查多个

context.log.where(l => l.title === "Login").onsuccess = function (arr) {
    arr.forEach(function (l) { // todo });
}
//在controller对应的action中
scope.where(l => l.title === "Login").onsuccess = function (arr) {
    arr.forEach(function (l) { // todo });
}

分页

context.log.page(1, 10).onsuccess = function (arr, count) {
    arr.forEach(function (l) { // todo });
}
//在controller对应的action中
scope.page(1, 10).onsuccess = function (arr, count) {
    arr.forEach(function (l) { // todo });
}

总条数

context.log.count().onsuccess = function (count) {
    // todo
}
//在controller对应的action中
scope.count().onsuccess = function (count) {
    // todo
}
context.log.default(l => l.date === "201712").onsuccess = function (result) {
    if (result === null)
        ;// todo
    else {
        result.remark = "remark";
        result.update();
    }
}
context.log.where(l => l.title === "Login").onsuccess = function (arr) {
    arr.forEach(function (l) {
        l.remark = "login";
        l.update();
    });
}
//在controller对应的action中
scope.default(l => l.date === "201712").onsuccess = function (result) {
    if (result === null)
        ;// todo
    else {
        result.remark = "remark";
        result.update();
    }
}
scope.where(l => l.title === "Login").onsuccess = function (arr) {
    arr.forEach(function (l) {
        l.remark = "login";
        l.update();
    });
}
context.log.default(l => l.date === "201712").onsuccess = function (result) {
    if (result === null)
        ;// todo
    else
        result.delete();
}
context.log.where(l => l.title === "Login").onsuccess = function (arr) {
    arr.forEach(function (l) {
        l.delete();
    });
}
//在controller对应的action中
scope.default(l => l.date === "201712").onsuccess = function (result) {
    if (result === null)
        ;// todo
    else
        result.delete();
}
scope.where(l => l.title === "Login").onsuccess = function (arr) {
    arr.forEach(function (l) {
        l.delete();
    });
}

身份验证

action中

scope.Auth.User     //String
scope.Auth.Role     //String
scope.Auth.set      //Function arg: user, role, expiredays;
scope.Auth.clear    //Function

重定向

action中

scope.redirect  //Function arg: url;

等待异步处理完成

action中

setTimeout(function () {
    scope.date = Date.now();
    scope.async();
}, 1000);
context.user.default(u => u.uid === scope.query.uid).onsuccess = function (resault) {
    if (resault === null) {
        scope.msg = {rc: 1, rm: "用户不存在"};
        scope.async();
    } else
        scope.async({rc: 0, rm: "用户已存在"});
};
return false;//异步标志,任务被挂起,直到scope.async被执行。