├── .gitignore
├── LICENSE
├── README.md
├── express-app.html
├── express-config.html
├── express-middleware.html
├── express-param.html
├── express-route.html
├── express-router.html
├── package.json
└── test
├── express-app-test
├── express-app.test.html
├── express-app.test.ts
└── mocha-loader.js
└── index.html
/.gitignore:
--------------------------------------------------------------------------------
1 | /npm-debug.log
2 | /node_modules
3 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | The MIT License (MIT)
2 | Copyright (c) 2016 Jordan Last
3 |
4 | Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
5 |
6 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
7 |
8 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
9 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # What is this?
2 | This repo contains web components built with the [Google Polymer library](https://www.polymer-project.org/1.0/) that allow you to create [Express.js](https://github.com/expressjs/express) applications. If you have not heard of web components, then please [start learning today](http://webcomponents.org/). Web components offer a way to modularize and package functionality into reusable components that can be easily shared and composed to create entire applications. Currently they are used mostly for front-end web development. Well, what about the back-end? Web components are not only useful for visual components, as the Polymer project [has shown us](https://elements.polymer-project.org/elements/iron-ajax). Now you can build APIs and other server-side applications, leveraging the same declarativeness of the front-end world. We are one step closer to true Universal JavaScript.
3 |
4 | ## Mini Application
5 | With boilerplate removed, and using Polymer 2, this is a preview of what you can expect server-side web component code to look like:
6 |
7 | ```HTML
8 |
9 |
10 |
11 |
12 |
13 |
27 | ```
28 |
29 | ## Examples
30 | Here are some example Express.js apps that have been rewritten with these web components:
31 | * https://github.com/scramjs/rest-api-express
32 | * https://github.com/scramjs/node-api
33 | * https://github.com/scramjs/node-todo
34 | * https://github.com/scramjs/node-tutorial-2-restful-app
35 | * https://github.com/scramjs/node-tutorial-for-frontend-devs
36 |
37 | Here is a [live example](http://scramjs.org/), built with web components on the front-end and the back-end.
38 |
39 | ## Installation
40 | These web components are meant to be run using [Scram.js](https://github.com/scramjs/scram-engine), which provides access to the Electron runtime, and Express.js, which is one of the most popular web frameworks running on top of Node.js. You must install these dependencies into your project separately:
41 |
42 | ```bash
43 | bower install --save express-web-components
44 | npm install --save express
45 | npm install --save scram-engine
46 | ```
47 |
48 | [See here](https://github.com/scramjs/scram-engine) for information on how to use these components with Scram.js.
49 |
50 | ## Usage
51 | In addition to the documentation below, a great place to learn how to use the components is to view this repo's [example](https://github.com/scramjs/express-web-components/tree/master/example/app/server).
52 |
53 | Also, in the documentation I'm attempting to describe the API using TypeScript types. Not all of the types I'm using are real TypeScript types, I'm just hoping it helps describe what is expected. You do not need to use TypeScript to use these components.
54 |
55 | ### Components
56 |
57 | ## ``
58 |
59 | Creates an Express application and calls the Express [app.listen](http://expressjs.com/en/4x/api.html#app.listen) function.
60 | This component is the parent of all other components that you inted
61 | to be a part of the Express application created. As long as you use different ports,
62 | you can have multiple Express applications running for each instance of ``.
63 | You can also nest `` elements to create sub-apps.
64 |
65 | ##### Properties
66 |
67 | `port: string | number`
68 |
69 | The port the Express application will run on, as specified by [app.listen](http://expressjs.com/en/4x/api.html#app.listen).
70 |
71 | `path?: string`
72 |
73 | The path that this application instance will be mounted at on the parent app, used when creating a sub-app.
74 |
75 | `hostname?: string`
76 |
77 | An optional hostname the Express application will run on, as specified by [app.listen](http://expressjs.com/en/4x/api.html#app.listen).
78 |
79 |
80 | `backlog?: number`
81 |
82 | An optional backlog the Express application will use, as specified by [app.listen](http://expressjs.com/en/4x/api.html#app.listen), and for more info see [server.listen](https://nodejs.org/api/http.html#http_server_listen_port_hostname_backlog_callback).
83 |
84 | `callback?: (e: NodeListeningEvent) => any`
85 |
86 | An optional callback function to be invoked by app.listen, as specified by [app.listen](http://expressjs.com/en/4x/api.html#app.listen)
87 |
88 | ## ``
89 |
90 | Allows specifying a callback function to be invoked with the current pertinent objects of the parent Express application. This is useful for setting configurations, such as calling `express.static(root, [options])`.
91 |
92 | ##### Properties
93 |
94 | `callback: (app: express.Application, express: Express, router: express.Router, route: express.Route) => any`
95 |
96 | A callback function that will be invoked with the the current Express application, the current Express object (from `require('express')`), the current parent router, and the current parent route.
97 |
98 | ## ``
99 |
100 | Allows hooking up Express middleware, i.e. performs the equivalent of [app.use](http://expressjs.com/en/4x/api.html#app.use), [app.get](http://expressjs.com/en/4x/api.html#app.get.method), [app.post](http://expressjs.com/en/4x/api.html#app.post.method), etc.
101 |
102 | ##### Properties
103 |
104 | `method?: string`
105 |
106 | An optional HTTP method to associate the middleware with, as defined by the Express [app.METHOD](http://expressjs.com/en/4x/api.html#app.METHOD). You must specify a path if you specify a method.
107 |
108 | `path?: string`
109 |
110 | The optional URL path that the middleware will be associated with. The path will default to `/` if no method is specified. You must specify a path if you specify a method.
111 |
112 | `callback: (req: express.Request, res: express.Response, next: express.NextFunction) => any`
113 |
114 | The callback function to be invoked on a matching request.
115 |
116 | `callbacks?: (req: express.Request, res: express.Response, next: express.NextFunction) => any[]`
117 |
118 | An optional list of callback functions to be invoked on a matching request.
119 |
120 | ## ``
121 |
122 | Creates an Express [router](http://expressjs.com/en/4x/api.html#router). All child components are hooked up to this router.
123 |
124 | ##### Properties
125 |
126 | `path?: string`
127 |
128 | The optional URL path that the router will be associated with. Defaults to `/`.
129 |
130 | ## ``
131 |
132 | Creates an Express [route](http://expressjs.com/en/4x/api.html#router.route). All child components are hooked up to this route.
133 |
134 | ##### Properties
135 |
136 | `path: string`
137 |
138 | The URL path that the route will be associated with.
139 |
140 | ## ``
141 |
142 | Equivalent to [app.param()](http://expressjs.com/en/4x/api.html#app.param) or [router.param()](http://expressjs.com/en/4x/api.html#router.param), depending on its immediate parent element.
143 |
144 | ##### Properties
145 |
146 | `name: string`
147 |
148 | The name of the parameter that the callback will be triggered for.
149 |
150 | `callback: (req: express.Request, res: express.Response, next: express.NextFunction, value: string, name: string): => any`
151 |
152 | The callback triggered on the corresponding route parameter. The parameters to the callback are the request object, the response object, the next middleware, the value of the route parameter, and the name of the route parameter.
153 |
154 | Node.js is a trademark of Joyent, Inc. and is used with its permission. We are not endorsed by or affiliated with Joyent.
155 |
--------------------------------------------------------------------------------
/express-app.html:
--------------------------------------------------------------------------------
1 |
106 |
--------------------------------------------------------------------------------
/express-config.html:
--------------------------------------------------------------------------------
1 |
16 |
--------------------------------------------------------------------------------
/express-middleware.html:
--------------------------------------------------------------------------------
1 |
130 |
--------------------------------------------------------------------------------
/express-param.html:
--------------------------------------------------------------------------------
1 |
54 |
--------------------------------------------------------------------------------
/express-route.html:
--------------------------------------------------------------------------------
1 |
43 |
--------------------------------------------------------------------------------
/express-router.html:
--------------------------------------------------------------------------------
1 |
41 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "express-web-components",
3 | "version": "0.5.4",
4 | "description": "Declaratively build Express applications with web components.",
5 | "keywords": [
6 | "web-components"
7 | ],
8 | "scripts": {
9 | "test": "electron node_modules/scram-engine/main.js test/index.html -d -p 5052"
10 | },
11 | "license": "MIT",
12 | "devDependencies": {
13 | "axios": "^0.12.0",
14 | "chai": "^3.5.0",
15 | "cors": "^2.7.1",
16 | "express": "^4.14.0",
17 | "mocha": "^2.5.3"
18 | },
19 | "dependencies": {
20 | "express": "^4.15.3"
21 | }
22 | }
23 |
--------------------------------------------------------------------------------
/test/express-app-test/express-app.test.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 |
59 |
60 |
61 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
126 |
127 |
--------------------------------------------------------------------------------
/test/express-app-test/express-app.test.ts:
--------------------------------------------------------------------------------
1 | const assert = require('chai').assert;
2 | const axios = require('axios');
3 |
4 | describe('express-app tests', function() {
5 | describe('Developer can set the port directly in the HTML to any available port.', function() {
6 | it('should receive correct responses for each request', async function(done) {
7 | const response2000 = await axios.create({
8 | baseURL: 'http://localhost:2000'
9 | }).get('/');
10 |
11 | const response3000 = await axios.create({
12 | baseURL: 'http://localhost:2000'
13 | }).get('/');
14 |
15 | const response4000 = await axios.create({
16 | baseURL: 'http://localhost:2000'
17 | }).get('/');
18 |
19 | const response5000 = await axios.create({
20 | baseURL: 'http://localhost:2000'
21 | }).get('/');
22 |
23 | const response6000 = await axios.create({
24 | baseURL: 'http://localhost:2000'
25 | }).get('/');
26 |
27 | const response7000 = await axios.create({
28 | baseURL: 'http://localhost:7000'
29 | }).get('/');
30 |
31 | const response8000 = await axios.create({
32 | baseURL: 'http://localhost:8000'
33 | }).get('/');
34 |
35 | const response9000 = await axios.create({
36 | baseURL: 'http://localhost:9000'
37 | }).get('/');
38 |
39 | const response10000 = await axios.create({
40 | baseURL: 'http://localhost:10000'
41 | }).get('/');
42 |
43 | assert.equal(response2000.status, 200);
44 | assert.equal(response3000.status, 200);
45 | assert.equal(response4000.status, 200);
46 | assert.equal(response5000.status, 200);
47 | assert.equal(response6000.status, 200);
48 | assert.equal(response7000.status, 200);
49 | assert.equal(response8000.status, 200);
50 | assert.equal(response9000.status, 200);
51 | assert.equal(response10000.status, 200);
52 |
53 | done();
54 | });
55 | });
56 |
57 | describe('The hostname is set', function() {
58 | it('should not throw an error when the hostname is passed in as a string literal to the HTML attribute', function() {});
59 | it('should not throw an error when the hostname is passed in through data binding', function() {});
60 | });
61 |
62 | describe('Bind a function to `s callback property and the function runs after the app is initialized', function() {
63 | it('should set callbackTestWorked to true', function() {
64 | assert.equal(window.callbackTestWorked, true);
65 | });
66 | });
67 |
68 | describe('initializes children', function() {
69 | it('should initialize 1 child', function() {
70 | assert.equal(window.initChildren1, true);
71 | });
72 |
73 | it('should initialize multiple children', function() {
74 | assert.equal(window.initChildren2, true);
75 | assert.equal(window.initChildren3, true);
76 | assert.equal(window.initChildren4, true);
77 | });
78 | });
79 | });
80 |
--------------------------------------------------------------------------------
/test/express-app-test/mocha-loader.js:
--------------------------------------------------------------------------------
1 | describe('running tests', function() {
2 | it('should run the tests', function(done) {
3 | System.import('express-app-test/express-app.test.ts').then(() => {
4 | done();
5 | });
6 | });
7 | });
8 |
--------------------------------------------------------------------------------
/test/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
--------------------------------------------------------------------------------