primate 0.6.3 → 0.6.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +76 -8
- package/package.json +1 -1
- package/source/EagerPromise.js +1 -1
- package/source/handlers/DOM/Parser.js +11 -2
- package/source/invariants.js +10 -5
- package/source/map_entries.js +6 -0
- package/source/sanitize.js +8 -10
package/README.md
CHANGED
|
@@ -7,9 +7,77 @@ expressive code.
|
|
|
7
7
|
## Installing
|
|
8
8
|
|
|
9
9
|
```
|
|
10
|
-
npm install primate
|
|
10
|
+
$ npm install primate
|
|
11
11
|
```
|
|
12
12
|
|
|
13
|
+
## Quick start
|
|
14
|
+
|
|
15
|
+
Lay out your app
|
|
16
|
+
|
|
17
|
+
```
|
|
18
|
+
$ mkdir -p primate-app/{routes,components,ssl} && cd primate-app
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
Create a route for `/`
|
|
22
|
+
|
|
23
|
+
```
|
|
24
|
+
// routes/site.js
|
|
25
|
+
|
|
26
|
+
import {router, html} from "primate";
|
|
27
|
+
|
|
28
|
+
router.get("/", () => html`<site-index date=${new Date()} />`);
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
Create component for your route
|
|
32
|
+
|
|
33
|
+
```
|
|
34
|
+
// components/site-index.html
|
|
35
|
+
|
|
36
|
+
Today's date is <span data-value="date"></span>.
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
Generate SSL key/certificate
|
|
40
|
+
|
|
41
|
+
```
|
|
42
|
+
openssl req -x509 -out ssl/default.crt -keyout ssl/default.key -newkey rsa:2048 -nodes -sha256 -batch
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
Add an entry file
|
|
46
|
+
|
|
47
|
+
```
|
|
48
|
+
// app.js
|
|
49
|
+
|
|
50
|
+
import {app} from "primate";
|
|
51
|
+
app.run();
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
Create and start script and enable ES modules
|
|
55
|
+
|
|
56
|
+
```
|
|
57
|
+
// package.json
|
|
58
|
+
|
|
59
|
+
{
|
|
60
|
+
"scripts": {
|
|
61
|
+
"start": "node --experimental-json-modules app.js"
|
|
62
|
+
},
|
|
63
|
+
"type": "module"
|
|
64
|
+
}
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
Install Primate
|
|
68
|
+
|
|
69
|
+
```
|
|
70
|
+
$ npm install primate
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
Run app
|
|
74
|
+
|
|
75
|
+
```
|
|
76
|
+
$ npm start
|
|
77
|
+
```
|
|
78
|
+
|
|
79
|
+
Visit `https://localhost:9999`
|
|
80
|
+
|
|
13
81
|
## Highlights
|
|
14
82
|
|
|
15
83
|
* Flexible HTTP routing, returning HTML, JSON or a custom handler
|
|
@@ -17,15 +85,15 @@ npm install primate
|
|
|
17
85
|
* Built-in support for sessions with secure cookies
|
|
18
86
|
* Input verification using data domains
|
|
19
87
|
* Many different data store modules: In-Memory (built-in),
|
|
20
|
-
[File][primate-store
|
|
21
|
-
[MongoDB][primate-store
|
|
88
|
+
[File][primate-file-store], [JSON][primate-json-store],
|
|
89
|
+
[MongoDB][primate-mongodb-store]
|
|
22
90
|
* Easy modelling of`1:1`, `1:n` and `n:m` relationships
|
|
23
91
|
* Minimally opinionated with sane, overrideable defaults
|
|
24
92
|
* No dependencies
|
|
25
93
|
|
|
26
|
-
##
|
|
94
|
+
## Resources
|
|
27
95
|
|
|
28
|
-
|
|
96
|
+
* [Getting started guide]
|
|
29
97
|
|
|
30
98
|
## License
|
|
31
99
|
|
|
@@ -34,6 +102,6 @@ BSD-3-Clause
|
|
|
34
102
|
[getting-started]: https://primatejs.com/getting-started
|
|
35
103
|
[source-code]: https://github.com/primatejs/primate
|
|
36
104
|
[issues]: https://github.com/primatejs/primate/issues
|
|
37
|
-
[primate-store
|
|
38
|
-
[primate-store
|
|
39
|
-
[primate-store
|
|
105
|
+
[primate-file-store]: https://npmjs.com/primate-file-store
|
|
106
|
+
[primate-json-store]: https://npmjs.com/primate-json-store
|
|
107
|
+
[primate-mongodb-store]: https://npmjs.com/primate-mongodb-store
|
package/package.json
CHANGED
package/source/EagerPromise.js
CHANGED
|
@@ -44,6 +44,6 @@ const last = -1;
|
|
|
44
44
|
const eager = async (strings, ...keys) =>
|
|
45
45
|
(await Promise.all(strings.slice(0, last).map(async (string, i) =>
|
|
46
46
|
strings[i] + await keys[i]
|
|
47
|
-
))).join("") + strings
|
|
47
|
+
))).join("") + strings.at(last);
|
|
48
48
|
|
|
49
49
|
export {eager};
|
|
@@ -74,12 +74,19 @@ export default class Parser {
|
|
|
74
74
|
}
|
|
75
75
|
}
|
|
76
76
|
|
|
77
|
+
try_create_text_node() {
|
|
78
|
+
if (this.buffer.length > 0) {
|
|
79
|
+
const child = new Node(this.node, "span");
|
|
80
|
+
child.text = this.buffer;
|
|
81
|
+
this.buffer = "";
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
|
|
77
85
|
// currently outside of a tag
|
|
78
86
|
process_not_reading_tag() {
|
|
79
87
|
// encountered '<'
|
|
80
88
|
if (this.current === "<") {
|
|
81
|
-
this.
|
|
82
|
-
this.buffer = "";
|
|
89
|
+
this.try_create_text_node();
|
|
83
90
|
// mark as inside tag
|
|
84
91
|
this.reading_tag = true;
|
|
85
92
|
if (this.next === "/") {
|
|
@@ -111,6 +118,8 @@ export default class Parser {
|
|
|
111
118
|
if (this.balance !== 0) {
|
|
112
119
|
throw Error(`unbalanced DOM tree: ${this.balance}`);
|
|
113
120
|
}
|
|
121
|
+
// anything left at the end could be potentially a text node
|
|
122
|
+
this.try_create_text_node();
|
|
114
123
|
return this.tree;
|
|
115
124
|
}
|
|
116
125
|
|
package/source/invariants.js
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import {constructible, nullish} from "./attributes.js";
|
|
2
|
+
import map_entries from "./map_entries.js";
|
|
2
3
|
|
|
3
4
|
const errored = error => {
|
|
4
5
|
if (typeof error === "function") {
|
|
@@ -14,6 +15,9 @@ const assert = (predicate, error) => Boolean(predicate) || errored(error);
|
|
|
14
15
|
const is = {
|
|
15
16
|
"array": value => assert(Array.isArray(value), "must be array"),
|
|
16
17
|
"string": value => assert(typeof value === "string", "must be string"),
|
|
18
|
+
"object": value => assert(typeof value === "object" && value !== null,
|
|
19
|
+
"must be object"),
|
|
20
|
+
"function": value => assert(typeof value === "function", "must be function"),
|
|
17
21
|
"defined": (value, error) => assert(value !== undefined, error),
|
|
18
22
|
"undefined": value => assert(value === undefined, "must be undefined"),
|
|
19
23
|
"constructible": (value, error) => assert(constructible(value), error),
|
|
@@ -24,9 +28,10 @@ const is = {
|
|
|
24
28
|
};
|
|
25
29
|
const {defined} = is;
|
|
26
30
|
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
}, {});
|
|
31
|
+
// too early to use map_entries here, as it relies on invariants
|
|
32
|
+
const maybe = Object.fromEntries(Object.entries(is).map(([key, value]) =>
|
|
33
|
+
[key, (...args) => nullish(args[0]) || value(...args)]));
|
|
31
34
|
|
|
32
|
-
|
|
35
|
+
const invariant = predicate => predicate();
|
|
36
|
+
|
|
37
|
+
export {assert, defined, is, maybe, invariant};
|
package/source/sanitize.js
CHANGED
|
@@ -1,10 +1,8 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
return data;
|
|
10
|
-
}, {});
|
|
1
|
+
import {is} from "./invariants.js";
|
|
2
|
+
import map_entries from "./map_entries.js";
|
|
3
|
+
|
|
4
|
+
export default (dirty = {}) => is.object(dirty)
|
|
5
|
+
&& map_entries(dirty, (key, value) => {
|
|
6
|
+
const trimmed = value.toString().trim();
|
|
7
|
+
return [key, trimmed === "" ? undefined : trimmed];
|
|
8
|
+
});
|