mirror of
https://github.com/expressjs/express.git
synced 2026-02-26 08:45:36 +00:00
Compare commits
789 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
344b022fc7 | ||
|
|
0c49926a9b | ||
|
|
b3906cbdde | ||
|
|
fed8c2a885 | ||
|
|
bdd81f8670 | ||
|
|
6c98f80b6a | ||
|
|
f9256ef36f | ||
|
|
e5feb9fcc9 | ||
|
|
21df421ebc | ||
|
|
4c9ddc1c47 | ||
|
|
9ebe5d500d | ||
|
|
ec4a01b6b8 | ||
|
|
54271f69b5 | ||
|
|
0264908903 | ||
|
|
4d713d2b76 | ||
|
|
125bb742a3 | ||
|
|
accafc652e | ||
|
|
05f40f4321 | ||
|
|
402e7f653f | ||
|
|
4e61d0100d | ||
|
|
7748475747 | ||
|
|
91a58b5b03 | ||
|
|
13e6894393 | ||
|
|
65b62065d2 | ||
|
|
2a980ad160 | ||
|
|
0b243b1aee | ||
|
|
a3e7e05e0a | ||
|
|
c5addb9a17 | ||
|
|
e35380a39d | ||
|
|
f5b6e67aed | ||
|
|
09831580ec | ||
|
|
41c054cff1 | ||
|
|
ecf762ff38 | ||
|
|
63992bb1d7 | ||
|
|
ea49706052 | ||
|
|
dde1f7d6e8 | ||
|
|
82fc12a40b | ||
|
|
9c756b0105 | ||
|
|
160b91cbf7 | ||
|
|
d106bf5324 | ||
|
|
723b5451bb | ||
|
|
2177f67f54 | ||
|
|
f4bd86ed36 | ||
|
|
c96c690dc0 | ||
|
|
088856c3f8 | ||
|
|
2ec589c113 | ||
|
|
4cf7eed927 | ||
|
|
6d084715ba | ||
|
|
61421a8c0c | ||
|
|
f42b160bbc | ||
|
|
689073d657 | ||
|
|
2803a2b35a | ||
|
|
ee40a881f5 | ||
|
|
a7d6d29ed3 | ||
|
|
897290b685 | ||
|
|
700349ffaf | ||
|
|
4b9cd2fd0e | ||
|
|
b44191eb3d | ||
|
|
8417c60fcf | ||
|
|
bf91946bd4 | ||
|
|
26801a0afd | ||
|
|
14439731f9 | ||
|
|
d97d79ed9a | ||
|
|
26e53f0fbc | ||
|
|
6abec204c0 | ||
|
|
4b3b8cc231 | ||
|
|
e9bcdd399b | ||
|
|
815f799310 | ||
|
|
7f9e5843b9 | ||
|
|
93cf646d5c | ||
|
|
2676a1f281 | ||
|
|
6da57c7819 | ||
|
|
d546f93f2f | ||
|
|
4771ba2bc3 | ||
|
|
3ae704f67f | ||
|
|
8b6d34963d | ||
|
|
36b8148110 | ||
|
|
6d98d2e110 | ||
|
|
51a76366e3 | ||
|
|
4e3f95c0ea | ||
|
|
88bd6d8e3a | ||
|
|
51595d402b | ||
|
|
94669f9289 | ||
|
|
cd7d79f92a | ||
|
|
5e2345e966 | ||
|
|
6415f7035b | ||
|
|
b28db2c12c | ||
|
|
0b746953c4 | ||
|
|
04bc62787b | ||
|
|
da4d763ff6 | ||
|
|
7091ec17f0 | ||
|
|
416ba025a1 | ||
|
|
60fb1d2acd | ||
|
|
e9f9aaeebd | ||
|
|
4f0f6cc67d | ||
|
|
a003cfab03 | ||
|
|
a1fa90fcea | ||
|
|
11f2b1db22 | ||
|
|
084e36506a | ||
|
|
0867302ddb | ||
|
|
567c9c665d | ||
|
|
69a4cf2819 | ||
|
|
4ee853e837 | ||
|
|
414854b82e | ||
|
|
06c6b88808 | ||
|
|
1b51edac7c | ||
|
|
b625132864 | ||
|
|
e3eca80584 | ||
|
|
23b44b3ddd | ||
|
|
b9fea12245 | ||
|
|
c259c3407f | ||
|
|
fdeb1d3176 | ||
|
|
734b281900 | ||
|
|
0e3ab6ec21 | ||
|
|
59af63ac2e | ||
|
|
e720c5a21b | ||
|
|
3abea7f818 | ||
|
|
2a89eb5c74 | ||
|
|
59aae7686b | ||
|
|
c4fe7de7bc | ||
|
|
a22920707b | ||
|
|
02d1c3916e | ||
|
|
8d8bfaac7b | ||
|
|
13df1de857 | ||
|
|
2a00da2067 | ||
|
|
24e4a2570d | ||
|
|
91b6fb83b4 | ||
|
|
3531987844 | ||
|
|
f540c3b019 | ||
|
|
b8b2eff3c3 | ||
|
|
f4e48bc43e | ||
|
|
8c24fa8f7b | ||
|
|
0debedf4f3 | ||
|
|
74beeac071 | ||
|
|
9bc1742937 | ||
|
|
5ad95419ba | ||
|
|
8a76f39d98 | ||
|
|
60b7c672c1 | ||
|
|
1e42a98db6 | ||
|
|
506fbd63be | ||
|
|
b9f7a97fe1 | ||
|
|
546969d198 | ||
|
|
f05b5d0e9c | ||
|
|
3c1d605da7 | ||
|
|
6b4c4f5426 | ||
|
|
a1efd9d6cf | ||
|
|
c6ee8d6e7f | ||
|
|
442fd46799 | ||
|
|
723b67766f | ||
|
|
29e117e676 | ||
|
|
06b2b1416d | ||
|
|
8368dc178a | ||
|
|
61f4049122 | ||
|
|
bb7907b932 | ||
|
|
f56ce73186 | ||
|
|
24b3dc5516 | ||
|
|
689d175b8b | ||
|
|
340be0f79a | ||
|
|
33e8dc303a | ||
|
|
644f6464b9 | ||
|
|
ecd7572f1e | ||
|
|
97131bcda8 | ||
|
|
8d98e86d7f | ||
|
|
2c47827053 | ||
|
|
97f0a518d8 | ||
|
|
7ec5dd2b3c | ||
|
|
ab2c70b954 | ||
|
|
745a63f825 | ||
|
|
a2dfc56a49 | ||
|
|
d854c43ea1 | ||
|
|
b02a95c693 | ||
|
|
631ada0c64 | ||
|
|
75e0c7a2c9 | ||
|
|
e2482b7e36 | ||
|
|
2df96e349f | ||
|
|
a38fae126a | ||
|
|
547fdd41dc | ||
|
|
0b330ef57c | ||
|
|
158a17031a | ||
|
|
29ea1b2f74 | ||
|
|
11a209e4b7 | ||
|
|
fd8e45c344 | ||
|
|
708ac4cdf5 | ||
|
|
92c5ce59f5 | ||
|
|
8880ddad1c | ||
|
|
b91c7ffb28 | ||
|
|
ecaf67c930 | ||
|
|
99175c3ef6 | ||
|
|
1b2e097be2 | ||
|
|
04da4aaf1a | ||
|
|
2e2d78c4d9 | ||
|
|
980d881e3b | ||
|
|
1df75763e3 | ||
|
|
32c558d414 | ||
|
|
a10770286e | ||
|
|
5855339455 | ||
|
|
1cc8169938 | ||
|
|
9482b82d0b | ||
|
|
10b9b507b7 | ||
|
|
03dc367187 | ||
|
|
f739b162d9 | ||
|
|
c92420648e | ||
|
|
dd69eedd18 | ||
|
|
0def9bb659 | ||
|
|
4847d0efa1 | ||
|
|
c17fe05861 | ||
|
|
87279c08aa | ||
|
|
8bf0720391 | ||
|
|
eb4c930d5f | ||
|
|
947b6b7d57 | ||
|
|
bf4c3ee00f | ||
|
|
2a7417dd84 | ||
|
|
490f1a1738 | ||
|
|
446046f886 | ||
|
|
291993d73c | ||
|
|
e8594c3571 | ||
|
|
07aa91f7cb | ||
|
|
4ed35b4202 | ||
|
|
ea66a9b81b | ||
|
|
d0e166c3c6 | ||
|
|
cf9f662655 | ||
|
|
8da8f79c44 | ||
|
|
18f782bba9 | ||
|
|
bc5ca05509 | ||
|
|
9967ffbdc2 | ||
|
|
7df0c840e0 | ||
|
|
d8ed591117 | ||
|
|
8ee3420f0f | ||
|
|
318fd4b543 | ||
|
|
3d7fce56a3 | ||
|
|
f9063712e0 | ||
|
|
6381bc6317 | ||
|
|
a007863096 | ||
|
|
6faf26d59f | ||
|
|
e98f5848a0 | ||
|
|
a65913776d | ||
|
|
5213bd9fe7 | ||
|
|
a39e409cf3 | ||
|
|
82de4de5ab | ||
|
|
669c805615 | ||
|
|
620df0e35e | ||
|
|
f6db4ee805 | ||
|
|
12310c5294 | ||
|
|
884657d546 | ||
|
|
7511d08328 | ||
|
|
a0276c6c91 | ||
|
|
2585f209f9 | ||
|
|
9d0976229d | ||
|
|
43cc56eb9e | ||
|
|
1c7bbcc143 | ||
|
|
9cbbc8ae74 | ||
|
|
6fbc269563 | ||
|
|
2bc734aa3f | ||
|
|
89bb531b31 | ||
|
|
744564fcf8 | ||
|
|
da6cb0ed8a | ||
|
|
00ad5bee96 | ||
|
|
141914e817 | ||
|
|
bd4fdfe5f7 | ||
|
|
215f484fb4 | ||
|
|
20047bb6e4 | ||
|
|
8b9757e8b8 | ||
|
|
a84e73b958 | ||
|
|
69997cbdbe | ||
|
|
3d05e85b0c | ||
|
|
c221b8596e | ||
|
|
450c468d04 | ||
|
|
af341b0f09 | ||
|
|
1574925cad | ||
|
|
c7d528cdc0 | ||
|
|
ea537d907d | ||
|
|
eee93a2760 | ||
|
|
b35773cf19 | ||
|
|
c8a42006b8 | ||
|
|
21cf522dcd | ||
|
|
a24f27aba7 | ||
|
|
a33266a206 | ||
|
|
6fe271e8aa | ||
|
|
cbe25d66b3 | ||
|
|
3bb6d96ba9 | ||
|
|
6660649f1b | ||
|
|
a75e4707b9 | ||
|
|
db05a741f0 | ||
|
|
c2e23ece2e | ||
|
|
96850e872a | ||
|
|
b8d59d5c98 | ||
|
|
59d695c447 | ||
|
|
e242796eb3 | ||
|
|
aaa9690bcf | ||
|
|
f275e87dff | ||
|
|
9dd0e7afdb | ||
|
|
1b2f3a0698 | ||
|
|
519126d732 | ||
|
|
99a369f3d5 | ||
|
|
a1dbb11377 | ||
|
|
353348a83e | ||
|
|
dab6ee5822 | ||
|
|
fc138c108f | ||
|
|
61a23e801f | ||
|
|
313d54f033 | ||
|
|
de081eb70f | ||
|
|
06d11755c9 | ||
|
|
6f2afd3d80 | ||
|
|
d5a1cbee70 | ||
|
|
f9a0560a9c | ||
|
|
821b7f0624 | ||
|
|
f490f78563 | ||
|
|
884e080a19 | ||
|
|
eb76236e2f | ||
|
|
52e9bd67b7 | ||
|
|
135a05c524 | ||
|
|
30afebf8da | ||
|
|
8e4add7f74 | ||
|
|
0fbbc29632 | ||
|
|
2402126988 | ||
|
|
ca3c863428 | ||
|
|
28db2c2c5c | ||
|
|
685d4665fd | ||
|
|
280a8d39ec | ||
|
|
5c4f3e7cc7 | ||
|
|
de122c14f5 | ||
|
|
2a2dd5d32b | ||
|
|
508936853a | ||
|
|
5596222f6a | ||
|
|
fe67523b9c | ||
|
|
4486fa6324 | ||
|
|
ecd8a08c1c | ||
|
|
a75728432e | ||
|
|
9007dcbdba | ||
|
|
c519886be5 | ||
|
|
8aabecaf1f | ||
|
|
3ff1dbeb73 | ||
|
|
18da651c5b | ||
|
|
1b48a5cc3c | ||
|
|
561b4b601e | ||
|
|
67e64ca4c1 | ||
|
|
bd04d8a87f | ||
|
|
922e9a4615 | ||
|
|
323a38965a | ||
|
|
3f1dcb96e0 | ||
|
|
4b4fa26298 | ||
|
|
47c1d2a816 | ||
|
|
65aff94ec6 | ||
|
|
2d519077ea | ||
|
|
d967675852 | ||
|
|
22d5b7ed10 | ||
|
|
872aa4741c | ||
|
|
87bc4ef763 | ||
|
|
f0cbdeadf6 | ||
|
|
f1e8a877f4 | ||
|
|
55831bbd08 | ||
|
|
e757fa0039 | ||
|
|
95735a6fcc | ||
|
|
668d029a14 | ||
|
|
866ffd67d7 | ||
|
|
741e3f81af | ||
|
|
4efb49866d | ||
|
|
6506fb578c | ||
|
|
dfa7b80642 | ||
|
|
121fe9982b | ||
|
|
e1b45ebd05 | ||
|
|
0a48e18056 | ||
|
|
eed05a1464 | ||
|
|
10c7756764 | ||
|
|
9dadca2c64 | ||
|
|
b8e50568af | ||
|
|
94e48a16f2 | ||
|
|
efcb17dcb2 | ||
|
|
b9ecb9afe3 | ||
|
|
5266f3a5cb | ||
|
|
e502dde3c8 | ||
|
|
da6f701317 | ||
|
|
88f9733ffa | ||
|
|
8267c4b724 | ||
|
|
bc07a41693 | ||
|
|
c754c8ad7b | ||
|
|
e917028729 | ||
|
|
7b076bd8e1 | ||
|
|
bb5211fa1c | ||
|
|
7f4e37f3ea | ||
|
|
11192bd168 | ||
|
|
0bcdd88dd0 | ||
|
|
60aacac167 | ||
|
|
70a19472f1 | ||
|
|
6f7a8301a1 | ||
|
|
8b71f39516 | ||
|
|
955f2a5f78 | ||
|
|
2f782d8478 | ||
|
|
32f5293afa | ||
|
|
6d9dd2da49 | ||
|
|
40dbfa2de2 | ||
|
|
9afa1cfc85 | ||
|
|
7eacdcef19 | ||
|
|
b02d3a1744 | ||
|
|
03341204ff | ||
|
|
50eb5e4377 | ||
|
|
952484f73a | ||
|
|
4218d04183 | ||
|
|
cf5c813d2f | ||
|
|
9e5d1a30c3 | ||
|
|
8a97346eaf | ||
|
|
6eda52a3dc | ||
|
|
b9b1b19758 | ||
|
|
6f12eee8ab | ||
|
|
186a206a0a | ||
|
|
02f3933b69 | ||
|
|
0ae10bb154 | ||
|
|
95c31f7041 | ||
|
|
b93ffd4bdc | ||
|
|
8da51108e7 | ||
|
|
6bcdfef6ad | ||
|
|
44e539e1dc | ||
|
|
003459b795 | ||
|
|
6295b45920 | ||
|
|
a6b119d27a | ||
|
|
d0421ac7e1 | ||
|
|
5f0c829d7c | ||
|
|
c82fa19447 | ||
|
|
fa22245cc6 | ||
|
|
302a6152b4 | ||
|
|
dc538f6e81 | ||
|
|
62a59b6ace | ||
|
|
451ee5d9c1 | ||
|
|
f07f368fba | ||
|
|
09d5654488 | ||
|
|
3d10279826 | ||
|
|
5e9de5dcb6 | ||
|
|
5de1a08ebf | ||
|
|
4480fb997e | ||
|
|
b8fb6a7fb1 | ||
|
|
b4eb1f59d3 | ||
|
|
431f65305e | ||
|
|
f3fa758af9 | ||
|
|
ede24da964 | ||
|
|
d5b33cfad8 | ||
|
|
c39d7d9339 | ||
|
|
f95dbc28fd | ||
|
|
ac89f6f121 | ||
|
|
3d8ca8ad4a | ||
|
|
02c753583e | ||
|
|
3ed5090ca9 | ||
|
|
76bf96e9ce | ||
|
|
d3bdc3b663 | ||
|
|
0e88dceac2 | ||
|
|
e69a29d9c2 | ||
|
|
0083372bed | ||
|
|
f3c5f7ee29 | ||
|
|
40e04ec7a6 | ||
|
|
972ada9079 | ||
|
|
80e64691e1 | ||
|
|
98b0b66b6c | ||
|
|
cbaa04629a | ||
|
|
276a80895c | ||
|
|
94a6cbfbfe | ||
|
|
f8fba68ec0 | ||
|
|
c6f12a8971 | ||
|
|
323572610b | ||
|
|
f448a96685 | ||
|
|
68e824cbff | ||
|
|
086e56f1c4 | ||
|
|
b4020ec92b | ||
|
|
fe0bc4082d | ||
|
|
1780ed1091 | ||
|
|
b49af6a674 | ||
|
|
a743d5be4d | ||
|
|
187d1f57c9 | ||
|
|
950f4423f0 | ||
|
|
53bee2506d | ||
|
|
659fcc1598 | ||
|
|
a163e2cdf4 | ||
|
|
62e12fe710 | ||
|
|
8fabed82aa | ||
|
|
351396f971 | ||
|
|
b97faff6e2 | ||
|
|
b7817ab1b0 | ||
|
|
48aba21ea4 | ||
|
|
de129c289d | ||
|
|
e3f7f51f5f | ||
|
|
6f823e409c | ||
|
|
6d9b13cced | ||
|
|
f974d22c66 | ||
|
|
8d4ceb623d | ||
|
|
c0136d8b48 | ||
|
|
86f5df00ed | ||
|
|
41964580a8 | ||
|
|
ddeb71301c | ||
|
|
7154014785 | ||
|
|
628438d8d8 | ||
|
|
a24fd0ca6c | ||
|
|
95fb5cc268 | ||
|
|
44591fee23 | ||
|
|
2df1ad26a5 | ||
|
|
12c3712468 | ||
|
|
fa272edf84 | ||
|
|
d9d09b8b90 | ||
|
|
02a9d5fb28 | ||
|
|
c2f4fb5356 | ||
|
|
673d51f4f0 | ||
|
|
5cc761c865 | ||
|
|
ad7d96db47 | ||
|
|
e62bb8bf9f | ||
|
|
70589c3aef | ||
|
|
9a99c15270 | ||
|
|
550043c217 | ||
|
|
48940e6120 | ||
|
|
80f1ea9bec | ||
|
|
c3fb7e5adc | ||
|
|
94fdb674b1 | ||
|
|
f4120a6453 | ||
|
|
19c8d64855 | ||
|
|
ea3d605652 | ||
|
|
40435ec997 | ||
|
|
7137bf567d | ||
|
|
bd1672f0a4 | ||
|
|
9395db4c22 | ||
|
|
19a2eeb476 | ||
|
|
d7da22550d | ||
|
|
961dbff904 | ||
|
|
9e0fa7f1ca | ||
|
|
9e067ad2cb | ||
|
|
de5fb62b1a | ||
|
|
b208b24f83 | ||
|
|
78e55108e4 | ||
|
|
48817a798f | ||
|
|
71395f5933 | ||
|
|
e3bd14dcca | ||
|
|
c319fe260a | ||
|
|
a4bd4373b2 | ||
|
|
a50f1098d0 | ||
|
|
e2d725e016 | ||
|
|
e0066227f7 | ||
|
|
44881fabe3 | ||
|
|
1dbaae51dd | ||
|
|
56e90e3c72 | ||
|
|
713d2aed93 | ||
|
|
e0aa8bf74e | ||
|
|
85770a71fc | ||
|
|
daf66beda4 | ||
|
|
b2af101821 | ||
|
|
3eb16c233c | ||
|
|
582381bceb | ||
|
|
5e16f400f1 | ||
|
|
43dff4ceb3 | ||
|
|
04beebb2c0 | ||
|
|
1adee79e63 | ||
|
|
bd5951e603 | ||
|
|
deffce5704 | ||
|
|
48777dc377 | ||
|
|
9467a392e3 | ||
|
|
9f019c8c69 | ||
|
|
cf37240e73 | ||
|
|
60f87f8074 | ||
|
|
fde8f647d3 | ||
|
|
6da454c7fb | ||
|
|
5cf473dc5d | ||
|
|
65494692c2 | ||
|
|
bc2986fe59 | ||
|
|
58cfc9911b | ||
|
|
ad4456c491 | ||
|
|
1ba9a9ac23 | ||
|
|
ae0b630ac7 | ||
|
|
5ea2a8ff8e | ||
|
|
de41c0bfa4 | ||
|
|
a13938eed7 | ||
|
|
1b6e7004b7 | ||
|
|
2d1dade36a | ||
|
|
df4f2719db | ||
|
|
c087a45b9c | ||
|
|
347d4db3ca | ||
|
|
aabf7802a9 | ||
|
|
3763d73a1f | ||
|
|
8acaa9a3ea | ||
|
|
dbf092d3ea | ||
|
|
efd7032f71 | ||
|
|
2189ff14a9 | ||
|
|
245fa8942a | ||
|
|
1b6ad08095 | ||
|
|
a1fffda3f2 | ||
|
|
f44368f8be | ||
|
|
64dd446aa8 | ||
|
|
21f725e0ef | ||
|
|
e5dbb0cb4e | ||
|
|
d43b074f0b | ||
|
|
05fd1e4441 | ||
|
|
85c96fd64e | ||
|
|
d32ed68b29 | ||
|
|
57d3dfd9f8 | ||
|
|
eece3850bc | ||
|
|
8eb95ae579 | ||
|
|
67168fe231 | ||
|
|
c0089d971b | ||
|
|
dc8acc8676 | ||
|
|
7027b37764 | ||
|
|
b4550fbe7a | ||
|
|
a3a9166c52 | ||
|
|
06f423d4f5 | ||
|
|
4012846d25 | ||
|
|
501e24e0a9 | ||
|
|
6d9b127989 | ||
|
|
504a51c040 | ||
|
|
7f96896f67 | ||
|
|
f59de6ae3d | ||
|
|
72475543bc | ||
|
|
146a13ede7 | ||
|
|
9722202df9 | ||
|
|
51f52901eb | ||
|
|
8b6dc6ceec | ||
|
|
081b811b10 | ||
|
|
1f71fae23b | ||
|
|
acc4a619d9 | ||
|
|
1b43166fca | ||
|
|
6022567c75 | ||
|
|
12ff56e1e4 | ||
|
|
668f545fd4 | ||
|
|
7bc5f1af96 | ||
|
|
8de1230d03 | ||
|
|
034165caeb | ||
|
|
a9f15aaefc | ||
|
|
f87abb3493 | ||
|
|
cd7d241a5d | ||
|
|
9f4dbae083 | ||
|
|
f2bbd10ae7 | ||
|
|
92c859dd05 | ||
|
|
485b6f86ac | ||
|
|
906164b204 | ||
|
|
c63424a0a1 | ||
|
|
bbed8021c6 | ||
|
|
fefd729037 | ||
|
|
1a99bb0519 | ||
|
|
4420a7bd94 | ||
|
|
1678613db1 | ||
|
|
f3a47e39a4 | ||
|
|
3e3d35777d | ||
|
|
eb326d7ecb | ||
|
|
7ef92f8a17 | ||
|
|
c48014fde8 | ||
|
|
034f261fea | ||
|
|
abd1de73c1 | ||
|
|
fb3946f454 | ||
|
|
4f291e7d55 | ||
|
|
94377f681d | ||
|
|
c8d9223e93 | ||
|
|
4b39a01e6a | ||
|
|
ad4d52de29 | ||
|
|
07077c4457 | ||
|
|
bcbb9d56c5 | ||
|
|
0437c513f2 | ||
|
|
1f70b76c45 | ||
|
|
0b39fa2f7c | ||
|
|
ab1c9e924e | ||
|
|
25fdefac45 | ||
|
|
a856456a95 | ||
|
|
0d6c64fdfd | ||
|
|
c238aca438 | ||
|
|
6b506d801a | ||
|
|
dc48f27f60 | ||
|
|
8e14e06ebf | ||
|
|
572657ee4a | ||
|
|
cfae537d3b | ||
|
|
a3d635309c | ||
|
|
a2e323a012 | ||
|
|
e73913b583 | ||
|
|
ddc93aa0e2 | ||
|
|
6723b4419a | ||
|
|
d1d9631b97 | ||
|
|
1a17888073 | ||
|
|
f6dca56e72 | ||
|
|
6210e47cb6 | ||
|
|
1bcc9b1236 | ||
|
|
421ad5aaaa | ||
|
|
505f8482f2 | ||
|
|
bd47aeb88d | ||
|
|
305f982bd7 | ||
|
|
1dbfee6623 | ||
|
|
9375a9afa9 | ||
|
|
14cf9c5636 | ||
|
|
605983fd0e | ||
|
|
e06766c573 | ||
|
|
76eaa326ee | ||
|
|
c12cc88392 | ||
|
|
23c22ce3fe | ||
|
|
791cabf939 | ||
|
|
fc40702cb7 | ||
|
|
c762b16f62 | ||
|
|
5d642af8c3 | ||
|
|
7fcf1d7d5b | ||
|
|
7ee41cc23f | ||
|
|
8ddab697cc | ||
|
|
d038689658 | ||
|
|
c9531ac1f1 | ||
|
|
98224d2c4f | ||
|
|
2e1284beb6 | ||
|
|
999546dfde | ||
|
|
cc25a04d10 | ||
|
|
f90f9dde3f | ||
|
|
b69b7605b0 | ||
|
|
c6039af39d | ||
|
|
bdf604a77e | ||
|
|
76c56d1ab8 | ||
|
|
2cf830b29e | ||
|
|
e5502690d2 | ||
|
|
31dd549f35 | ||
|
|
e3dd191d54 | ||
|
|
fd48bfe8fe | ||
|
|
d7ae24228d | ||
|
|
992cd085fb | ||
|
|
20a25489de | ||
|
|
741a5aac9c | ||
|
|
3d56e7374d | ||
|
|
12bc16e72f | ||
|
|
8931b2311a | ||
|
|
bb84cf955f | ||
|
|
f3d99a4fdb | ||
|
|
dd2b897774 | ||
|
|
4bcbf67482 | ||
|
|
b5a280111f | ||
|
|
05136550c7 | ||
|
|
8a387d3ede | ||
|
|
943f28f05f | ||
|
|
7cafdb5824 | ||
|
|
193bed2649 | ||
|
|
e7a02f6a25 | ||
|
|
6847405974 | ||
|
|
f627ca8d0b | ||
|
|
e83eab85e4 | ||
|
|
1589ce2153 | ||
|
|
547ea368c2 | ||
|
|
8eee818e0b | ||
|
|
7c8456fcde | ||
|
|
53ee474c44 | ||
|
|
bd118c47df | ||
|
|
f2cf28c2f3 | ||
|
|
e44f024dab | ||
|
|
2493239192 | ||
|
|
c73b1bee51 | ||
|
|
4f8167f23f | ||
|
|
c95a1077d2 | ||
|
|
7d93503914 | ||
|
|
2b2a1b28f3 | ||
|
|
4416fb2746 | ||
|
|
60f8e77d66 | ||
|
|
23f021a3e1 | ||
|
|
67116cc5e6 | ||
|
|
42b944295a | ||
|
|
7a3b5aea11 | ||
|
|
e5ec966b2f | ||
|
|
5699d64b99 | ||
|
|
747fccfb44 | ||
|
|
9665aa2153 | ||
|
|
2f37f4b28d | ||
|
|
1a59246746 | ||
|
|
963d795d24 | ||
|
|
2f96412636 | ||
|
|
5a4310e9da | ||
|
|
2f8ac6726f | ||
|
|
ef7ad681b2 | ||
|
|
11a77a3fff | ||
|
|
ee90042d0c | ||
|
|
2c668f87c7 | ||
|
|
6343288bef | ||
|
|
694869d2aa | ||
|
|
cec5780db4 | ||
|
|
21d52daafb | ||
|
|
a7d15f382e | ||
|
|
6c751191dd | ||
|
|
1e2951a832 | ||
|
|
3a1f27fcde | ||
|
|
b309b873f1 | ||
|
|
f90e045334 | ||
|
|
f6ec710534 | ||
|
|
a9ef9e13fb | ||
|
|
f56e2a2503 | ||
|
|
8a5ecd3d89 | ||
|
|
4052c15c7f | ||
|
|
97ccc52207 | ||
|
|
0fc4f0735a | ||
|
|
ccdbe4ea37 | ||
|
|
59f2b4048a | ||
|
|
7f2532808a | ||
|
|
be35e4927c | ||
|
|
f31dcff10c | ||
|
|
509ebb1aff | ||
|
|
78e50547f1 | ||
|
|
dcc4eaabe8 | ||
|
|
8c6f9c4253 | ||
|
|
88103063fe | ||
|
|
164638b24f | ||
|
|
e66625be50 | ||
|
|
085a29685a |
11
.editorconfig
Normal file
11
.editorconfig
Normal file
@@ -0,0 +1,11 @@
|
||||
# http://editorconfig.org
|
||||
root = true
|
||||
|
||||
[*]
|
||||
charset = utf-8
|
||||
insert_final_newline = true
|
||||
trim_trailing_whitespace = true
|
||||
|
||||
[{*.js,*.json,*.yml}]
|
||||
indent_size = 2
|
||||
indent_style = space
|
||||
2
.eslintignore
Normal file
2
.eslintignore
Normal file
@@ -0,0 +1,2 @@
|
||||
coverage
|
||||
node_modules
|
||||
10
.eslintrc.yml
Normal file
10
.eslintrc.yml
Normal file
@@ -0,0 +1,10 @@
|
||||
root: true
|
||||
env:
|
||||
es2022: true
|
||||
node: true
|
||||
rules:
|
||||
eol-last: error
|
||||
eqeqeq: [error, allow-null]
|
||||
indent: [error, 2, { MemberExpression: "off", SwitchCase: 1 }]
|
||||
no-trailing-spaces: error
|
||||
no-unused-vars: [error, { vars: all, args: none, ignoreRestSiblings: true }]
|
||||
117
.github/workflows/ci.yml
vendored
Normal file
117
.github/workflows/ci.yml
vendored
Normal file
@@ -0,0 +1,117 @@
|
||||
name: ci
|
||||
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- master
|
||||
- develop
|
||||
- '4.x'
|
||||
- '5.x'
|
||||
- '5.0'
|
||||
paths-ignore:
|
||||
- '*.md'
|
||||
pull_request:
|
||||
paths-ignore:
|
||||
- '*.md'
|
||||
|
||||
# Cancel in progress workflows
|
||||
# in the scenario where we already had a run going for that PR/branch/tag but then triggered a new run
|
||||
concurrency:
|
||||
group: "${{ github.workflow }} ✨ ${{ github.event.pull_request.head.label || github.head_ref || github.ref }}"
|
||||
cancel-in-progress: true
|
||||
|
||||
jobs:
|
||||
lint:
|
||||
name: Lint
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- name: Setup Node.js {{ matrix.node-version }}
|
||||
uses: actions/setup-node@v4
|
||||
with:
|
||||
node-version: 'lts/*'
|
||||
persist-credentials: false
|
||||
|
||||
- name: Install dependencies
|
||||
run: npm install --ignore-scripts --only=dev
|
||||
|
||||
- name: Run lint
|
||||
run: npm run lint
|
||||
|
||||
test:
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
os: [ubuntu-latest, windows-latest]
|
||||
node-version: [18, 19, 20, 21, 22]
|
||||
# Node.js release schedule: https://nodejs.org/en/about/releases/
|
||||
|
||||
name: Node.js ${{ matrix.node-version }} - ${{matrix.os}}
|
||||
|
||||
runs-on: ${{ matrix.os }}
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
with:
|
||||
persist-credentials: false
|
||||
|
||||
- name: Setup Node.js ${{ matrix.node-version }}
|
||||
uses: actions/setup-node@v4
|
||||
with:
|
||||
node-version: ${{ matrix.node-version }}
|
||||
|
||||
- name: Configure npm loglevel
|
||||
run: |
|
||||
npm config set loglevel error
|
||||
shell: bash
|
||||
|
||||
- name: Install dependencies
|
||||
run: npm install
|
||||
|
||||
- name: Output Node and NPM versions
|
||||
run: |
|
||||
echo "Node.js version: $(node -v)"
|
||||
echo "NPM version: $(npm -v)"
|
||||
|
||||
- name: Run tests
|
||||
shell: bash
|
||||
run: |
|
||||
npm run test-ci
|
||||
cp coverage/lcov.info "coverage/${{ matrix.node-version }}.lcov"
|
||||
|
||||
- name: Collect code coverage
|
||||
run: |
|
||||
mv ./coverage "./${{ matrix.node-version }}"
|
||||
mkdir ./coverage
|
||||
mv "./${{ matrix.node-version }}" "./coverage/${{ matrix.node-version }}"
|
||||
|
||||
- name: Upload code coverage
|
||||
uses: actions/upload-artifact@v3
|
||||
with:
|
||||
name: coverage
|
||||
path: ./coverage
|
||||
retention-days: 1
|
||||
|
||||
coverage:
|
||||
needs: test
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
|
||||
- name: Install lcov
|
||||
shell: bash
|
||||
run: sudo apt-get -y install lcov
|
||||
|
||||
- name: Collect coverage reports
|
||||
uses: actions/download-artifact@v3
|
||||
with:
|
||||
name: coverage
|
||||
path: ./coverage
|
||||
|
||||
- name: Merge coverage reports
|
||||
shell: bash
|
||||
run: find ./coverage -name lcov.info -exec printf '-a %q\n' {} \; | xargs lcov -o ./coverage/lcov.info
|
||||
|
||||
- name: Upload coverage report
|
||||
uses: coverallsapp/github-action@master
|
||||
with:
|
||||
github-token: ${{ secrets.GITHUB_TOKEN }}
|
||||
66
.github/workflows/codeql.yml
vendored
Normal file
66
.github/workflows/codeql.yml
vendored
Normal file
@@ -0,0 +1,66 @@
|
||||
# For most projects, this workflow file will not need changing; you simply need
|
||||
# to commit it to your repository.
|
||||
#
|
||||
# You may wish to alter this file to override the set of languages analyzed,
|
||||
# or to provide custom queries or build logic.
|
||||
#
|
||||
# ******** NOTE ********
|
||||
# We have attempted to detect the languages in your repository. Please check
|
||||
# the `language` matrix defined below to confirm you have the correct set of
|
||||
# supported CodeQL languages.
|
||||
#
|
||||
name: "CodeQL"
|
||||
|
||||
on:
|
||||
push:
|
||||
branches: ["master"]
|
||||
pull_request:
|
||||
# The branches below must be a subset of the branches above
|
||||
branches: ["master"]
|
||||
schedule:
|
||||
- cron: "0 0 * * 1"
|
||||
|
||||
permissions:
|
||||
contents: read
|
||||
|
||||
jobs:
|
||||
analyze:
|
||||
name: Analyze
|
||||
runs-on: ubuntu-latest
|
||||
permissions:
|
||||
actions: read
|
||||
contents: read
|
||||
security-events: write
|
||||
|
||||
steps:
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1
|
||||
|
||||
# Initializes the CodeQL tools for scanning.
|
||||
- name: Initialize CodeQL
|
||||
uses: github/codeql-action/init@3ab4101902695724f9365a384f86c1074d94e18c # v3.24.7
|
||||
with:
|
||||
languages: javascript
|
||||
# If you wish to specify custom queries, you can do so here or in a config file.
|
||||
# By default, queries listed here will override any specified in a config file.
|
||||
# Prefix the list here with "+" to use these queries and those in the config file.
|
||||
|
||||
# Autobuild attempts to build any compiled languages (C/C++, C#, or Java).
|
||||
# If this step fails, then you should remove it and run the build manually (see below)
|
||||
# - name: Autobuild
|
||||
# uses: github/codeql-action/autobuild@3ab4101902695724f9365a384f86c1074d94e18c # v3.24.7
|
||||
|
||||
# ℹ️ Command-line programs to run using the OS shell.
|
||||
# 📚 See https://docs.github.com/en/actions/using-workflows/workflow-syntax-for-github-actions#jobsjob_idstepsrun
|
||||
|
||||
# If the Autobuild fails above, remove it and uncomment the following three lines.
|
||||
# modify them (or add more) to build your code if your project, please refer to the EXAMPLE below for guidance.
|
||||
|
||||
# - run: |
|
||||
# echo "Run, Build Application using script"
|
||||
# ./location_of_script_within_repo/buildscript.sh
|
||||
|
||||
- name: Perform CodeQL Analysis
|
||||
uses: github/codeql-action/analyze@3ab4101902695724f9365a384f86c1074d94e18c # v3.24.7
|
||||
with:
|
||||
category: "/language:javascript"
|
||||
100
.github/workflows/legacy.yml
vendored
Normal file
100
.github/workflows/legacy.yml
vendored
Normal file
@@ -0,0 +1,100 @@
|
||||
name: legacy
|
||||
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- master
|
||||
- develop
|
||||
- '4.x'
|
||||
- '5.x'
|
||||
- '5.0'
|
||||
paths-ignore:
|
||||
- '*.md'
|
||||
pull_request:
|
||||
paths-ignore:
|
||||
- '*.md'
|
||||
|
||||
# Cancel in progress workflows
|
||||
# in the scenario where we already had a run going for that PR/branch/tag but then triggered a new run
|
||||
concurrency:
|
||||
group: "${{ github.workflow }} ✨ ${{ github.event.pull_request.head.label || github.head_ref || github.ref }}"
|
||||
cancel-in-progress: true
|
||||
|
||||
jobs:
|
||||
test:
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
os: [ubuntu-latest, windows-latest]
|
||||
node-version: [16, 17]
|
||||
# Node.js release schedule: https://nodejs.org/en/about/releases/
|
||||
|
||||
name: Node.js ${{ matrix.node-version }} - ${{matrix.os}}
|
||||
|
||||
runs-on: ${{ matrix.os }}
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
with:
|
||||
persist-credentials: false
|
||||
|
||||
- name: Setup Node.js ${{ matrix.node-version }}
|
||||
uses: actions/setup-node@v4
|
||||
with:
|
||||
node-version: ${{ matrix.node-version }}
|
||||
|
||||
- name: Configure npm loglevel
|
||||
run: |
|
||||
npm config set loglevel error
|
||||
shell: bash
|
||||
|
||||
- name: Install dependencies
|
||||
run: npm install
|
||||
|
||||
- name: Output Node and NPM versions
|
||||
run: |
|
||||
echo "Node.js version: $(node -v)"
|
||||
echo "NPM version: $(npm -v)"
|
||||
|
||||
- name: Run tests
|
||||
shell: bash
|
||||
run: |
|
||||
npm run test-ci
|
||||
cp coverage/lcov.info "coverage/${{ matrix.node-version }}.lcov"
|
||||
|
||||
- name: Collect code coverage
|
||||
run: |
|
||||
mv ./coverage "./${{ matrix.node-version }}"
|
||||
mkdir ./coverage
|
||||
mv "./${{ matrix.node-version }}" "./coverage/${{ matrix.node-version }}"
|
||||
|
||||
- name: Upload code coverage
|
||||
uses: actions/upload-artifact@v3
|
||||
with:
|
||||
name: coverage
|
||||
path: ./coverage
|
||||
retention-days: 1
|
||||
|
||||
coverage:
|
||||
needs: test
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
|
||||
- name: Install lcov
|
||||
shell: bash
|
||||
run: sudo apt-get -y install lcov
|
||||
|
||||
- name: Collect coverage reports
|
||||
uses: actions/download-artifact@v3
|
||||
with:
|
||||
name: coverage
|
||||
path: ./coverage
|
||||
|
||||
- name: Merge coverage reports
|
||||
shell: bash
|
||||
run: find ./coverage -name lcov.info -exec printf '-a %q\n' {} \; | xargs lcov -o ./coverage/lcov.info
|
||||
|
||||
- name: Upload coverage report
|
||||
uses: coverallsapp/github-action@master
|
||||
with:
|
||||
github-token: ${{ secrets.GITHUB_TOKEN }}
|
||||
22
.gitignore
vendored
22
.gitignore
vendored
@@ -1,26 +1,16 @@
|
||||
# OS X
|
||||
.DS_Store*
|
||||
Icon?
|
||||
._*
|
||||
|
||||
# Windows
|
||||
Thumbs.db
|
||||
ehthumbs.db
|
||||
Desktop.ini
|
||||
|
||||
# Linux
|
||||
.directory
|
||||
*~
|
||||
|
||||
|
||||
# npm
|
||||
node_modules
|
||||
package-lock.json
|
||||
npm-shrinkwrap.json
|
||||
*.log
|
||||
*.gz
|
||||
|
||||
|
||||
# Coveralls
|
||||
.nyc_output
|
||||
coverage
|
||||
|
||||
# Benchmarking
|
||||
benchmarks/graphs
|
||||
|
||||
# ignore additional files using core.excludesFile
|
||||
# https://git-scm.com/docs/gitignore
|
||||
|
||||
12
.travis.yml
12
.travis.yml
@@ -1,12 +0,0 @@
|
||||
language: node_js
|
||||
node_js:
|
||||
- "0.10"
|
||||
- "0.12"
|
||||
- "1.0"
|
||||
- "1.8"
|
||||
- "2.0"
|
||||
- "2.3"
|
||||
sudo: false
|
||||
before_install: "npm rm --save-dev connect-redis"
|
||||
script: "npm run-script test-ci"
|
||||
after_script: "npm install coveralls@2.10.0 && cat ./coverage/lcov.info | coveralls"
|
||||
92
Charter.md
Normal file
92
Charter.md
Normal file
@@ -0,0 +1,92 @@
|
||||
# Express Charter
|
||||
|
||||
## Section 0: Guiding Principles
|
||||
|
||||
The Express project is part of the OpenJS Foundation which operates
|
||||
transparently, openly, collaboratively, and ethically.
|
||||
Project proposals, timelines, and status must not merely be open, but
|
||||
also easily visible to outsiders.
|
||||
|
||||
## Section 1: Scope
|
||||
|
||||
Express is a HTTP web server framework with a simple and expressive API
|
||||
which is highly aligned with Node.js core. We aim to be the best in
|
||||
class for writing performant, spec compliant, and powerful web servers
|
||||
in Node.js. As one of the oldest and most popular web frameworks in
|
||||
the ecosystem, we have an important place for new users and experts
|
||||
alike.
|
||||
|
||||
### 1.1: In-scope
|
||||
|
||||
Express is made of many modules spread between three GitHub Orgs:
|
||||
|
||||
- [expressjs](http://github.com/expressjs/): Top level middleware and
|
||||
libraries
|
||||
- [pillarjs](http://github.com/pillarjs/): Components which make up
|
||||
Express but can also be used for other web frameworks
|
||||
- [jshttp](http://github.com/jshttp/): Low level HTTP libraries
|
||||
|
||||
### 1.2: Out-of-Scope
|
||||
|
||||
Section Intentionally Left Blank
|
||||
|
||||
## Section 2: Relationship with OpenJS Foundation CPC.
|
||||
|
||||
Technical leadership for the projects within the OpenJS Foundation is
|
||||
delegated to the projects through their project charters by the OpenJS
|
||||
Cross Project Council (CPC). In the case of the Express project, it is
|
||||
delegated to the Express Technical Committee ("TC").
|
||||
|
||||
This Technical Committee is in charge of both the day-to-day operations
|
||||
of the project, as well as its technical management. This charter can
|
||||
be amended by the TC requiring at least two approvals and a minimum two
|
||||
week comment period for other TC members or CPC members to object. Any
|
||||
changes the CPC wishes to propose will be considered a priority but
|
||||
will follow the same process.
|
||||
|
||||
### 2.1 Other Formal Project Relationships
|
||||
|
||||
Section Intentionally Left Blank
|
||||
|
||||
## Section 3: Express Governing Body
|
||||
|
||||
The Express project is managed by the Technical Committee ("TC").
|
||||
Members can be added to the TC at any time. Any committer can nominate
|
||||
another committer to the TC and the TC uses its standard consensus
|
||||
seeking process to evaluate whether or not to add this new member.
|
||||
Members who do not participate consistently at the level of a majority
|
||||
of the other members are expected to resign.
|
||||
|
||||
## Section 4: Roles & Responsibilities
|
||||
|
||||
The Express TC manages all aspects of both the technical and community
|
||||
parts of the project. Members of the TC should attend the regular
|
||||
meetings when possible, and be available for discussion of time
|
||||
sensitive or important issues.
|
||||
|
||||
### Section 4.1 Project Operations & Management
|
||||
|
||||
Section Intentionally Left Blank
|
||||
|
||||
### Section 4.2: Decision-making, Voting, and/or Elections
|
||||
|
||||
The Express TC uses a "consensus seeking" process for issues that are
|
||||
escalated to the TC. The group tries to find a resolution that has no
|
||||
open objections among TC members. If a consensus cannot be reached
|
||||
that has no objections then a majority wins vote is called. It is also
|
||||
expected that the majority of decisions made by the TC are via a
|
||||
consensus seeking process and that voting is only used as a last-resort.
|
||||
|
||||
Resolution may involve returning the issue to committers with
|
||||
suggestions on how to move forward towards a consensus. It is not
|
||||
expected that a meeting of the TC will resolve all issues on its
|
||||
agenda during that meeting and may prefer to continue the discussion
|
||||
happening among the committers.
|
||||
|
||||
### Section 4.3: Other Project Roles
|
||||
|
||||
Section Intentionally Left Blank
|
||||
|
||||
## Section 5: Definitions
|
||||
|
||||
Section Intentionally Left Blank
|
||||
139
Code-Of-Conduct.md
Normal file
139
Code-Of-Conduct.md
Normal file
@@ -0,0 +1,139 @@
|
||||
# Contributor Covenant Code of Conduct
|
||||
|
||||
As a member of the Open JS Foundation, Express has adopted the
|
||||
[Contributor Covenant 2.0][cc-20-doc].
|
||||
|
||||
If an issue arises and you cannot resolve it directly with the parties
|
||||
involved, you can report it to the Express project TC through the following
|
||||
email: express-coc@lists.openjsf.org
|
||||
|
||||
In addition, the OpenJS Foundation maintains a Code of Conduct Panel (CoCP).
|
||||
This is a foundation-wide team established to manage escalation when a reporter
|
||||
believes that a report to a member project or the CPC has not been properly
|
||||
handled. In order to escalate to the CoCP send an email to
|
||||
coc-escalation@lists.openjsf.org.
|
||||
|
||||
## Our Pledge
|
||||
|
||||
We as members, contributors, and leaders pledge to make participation in our
|
||||
community a harassment-free experience for everyone, regardless of age, body
|
||||
size, visible or invisible disability, ethnicity, sex characteristics, gender
|
||||
identity and expression, level of experience, education, socio-economic status,
|
||||
nationality, personal appearance, race, religion, or sexual identity and
|
||||
orientation.
|
||||
|
||||
We pledge to act and interact in ways that contribute to an open, welcoming,
|
||||
diverse, inclusive, and healthy community.
|
||||
|
||||
## Our Standards
|
||||
|
||||
Examples of behavior that contributes to a positive environment for our
|
||||
community include:
|
||||
|
||||
* Demonstrating empathy and kindness toward other people
|
||||
* Being respectful of differing opinions, viewpoints, and experiences
|
||||
* Giving and gracefully accepting constructive feedback
|
||||
* Accepting responsibility and apologizing to those affected by our mistakes,
|
||||
and learning from the experience
|
||||
* Focusing on what is best not just for us as individuals, but for the overall
|
||||
community
|
||||
|
||||
Examples of unacceptable behavior include:
|
||||
|
||||
* The use of sexualized language or imagery, and sexual attention or advances
|
||||
of any kind
|
||||
* Trolling, insulting or derogatory comments, and personal or political attacks
|
||||
* Public or private harassment
|
||||
* Publishing others' private information, such as a physical or email address,
|
||||
without their explicit permission
|
||||
* Other conduct which could reasonably be considered inappropriate in a
|
||||
professional setting
|
||||
|
||||
## Enforcement Responsibilities
|
||||
|
||||
Community leaders are responsible for clarifying and enforcing our standards of
|
||||
acceptable behavior and will take appropriate and fair corrective action in
|
||||
response to any behavior that they deem inappropriate, threatening, offensive,
|
||||
or harmful.
|
||||
|
||||
Community leaders have the right and responsibility to remove, edit, or reject
|
||||
comments, commits, code, wiki edits, issues, and other contributions that are
|
||||
not aligned to this Code of Conduct, and will communicate reasons for
|
||||
moderation decisions when appropriate.
|
||||
|
||||
## Scope
|
||||
|
||||
This Code of Conduct applies within all community spaces, and also applies when
|
||||
an individual is officially representing the community in public spaces.
|
||||
Examples of representing our community include using an official e-mail
|
||||
address, posting via an official social media account, or acting as an
|
||||
appointed representative at an online or offline event.
|
||||
|
||||
## Enforcement
|
||||
|
||||
Instances of abusive, harassing, or otherwise unacceptable behavior may be
|
||||
reported to the community leaders responsible for enforcement at
|
||||
express-coc@lists.openjsf.org. All complaints will be reviewed and
|
||||
investigated promptly and fairly.
|
||||
|
||||
All community leaders are obligated to respect the privacy and security of the
|
||||
reporter of any incident.
|
||||
|
||||
## Enforcement Guidelines
|
||||
|
||||
Community leaders will follow these Community Impact Guidelines in determining
|
||||
the consequences for any action they deem in violation of this Code of Conduct:
|
||||
|
||||
### 1. Correction
|
||||
|
||||
**Community Impact**: Use of inappropriate language or other behavior deemed
|
||||
unprofessional or unwelcome in the community.
|
||||
|
||||
**Consequence**: A private, written warning from community leaders, providing
|
||||
clarity around the nature of the violation and an explanation of why the
|
||||
behavior was inappropriate. A public apology may be requested.
|
||||
|
||||
### 2. Warning
|
||||
|
||||
**Community Impact**: A violation through a single incident or series of
|
||||
actions.
|
||||
|
||||
**Consequence**: A warning with consequences for continued behavior. No
|
||||
interaction with the people involved, including unsolicited interaction with
|
||||
those enforcing the Code of Conduct, for a specified period of time. This
|
||||
includes avoiding interactions in community spaces as well as external channels
|
||||
like social media. Violating these terms may lead to a temporary or permanent
|
||||
ban.
|
||||
|
||||
### 3. Temporary Ban
|
||||
|
||||
**Community Impact**: A serious violation of community standards, including
|
||||
sustained inappropriate behavior.
|
||||
|
||||
**Consequence**: A temporary ban from any sort of interaction or public
|
||||
communication with the community for a specified period of time. No public or
|
||||
private interaction with the people involved, including unsolicited
|
||||
interaction with those enforcing the Code of Conduct, is allowed during this
|
||||
period. Violating these terms may lead to a permanent ban.
|
||||
|
||||
### 4. Permanent Ban
|
||||
|
||||
**Community Impact**: Demonstrating a pattern of violation of community
|
||||
standards, including sustained inappropriate behavior, harassment of an
|
||||
individual, or aggression toward or disparagement of classes of individuals.
|
||||
|
||||
**Consequence**: A permanent ban from any sort of public interaction within the
|
||||
project community.
|
||||
|
||||
## Attribution
|
||||
|
||||
This Code of Conduct is adapted from the [Contributor Covenant, version 2.0][cc-20-doc].
|
||||
|
||||
Community Impact Guidelines were inspired by
|
||||
[Mozilla's code of conduct enforcement ladder](https://github.com/mozilla/diversity).
|
||||
|
||||
[cc-20-doc]: https://www.contributor-covenant.org/version/2/0/code_of_conduct/
|
||||
|
||||
For answers to common questions about this code of conduct, see the FAQ at
|
||||
https://www.contributor-covenant.org/faq. Translations are available at
|
||||
https://www.contributor-covenant.org/translations.
|
||||
51
Collaborator-Guide.md
Normal file
51
Collaborator-Guide.md
Normal file
@@ -0,0 +1,51 @@
|
||||
# Express Collaborator Guide
|
||||
|
||||
## Website Issues
|
||||
|
||||
Open issues for the expressjs.com website in https://github.com/expressjs/expressjs.com.
|
||||
|
||||
## PRs and Code contributions
|
||||
|
||||
* Tests must pass.
|
||||
* Follow the [JavaScript Standard Style](http://standardjs.com/) and `npm run lint`.
|
||||
* If you fix a bug, add a test.
|
||||
|
||||
## Branches
|
||||
|
||||
Use the `master` branch for bug fixes or minor work that is intended for the
|
||||
current release stream.
|
||||
|
||||
Use the correspondingly named branch, e.g. `5.0`, for anything intended for
|
||||
a future release of Express.
|
||||
|
||||
## Steps for contributing
|
||||
|
||||
1. [Create an issue](https://github.com/expressjs/express/issues/new) for the
|
||||
bug you want to fix or the feature that you want to add.
|
||||
2. Create your own [fork](https://github.com/expressjs/express) on GitHub, then
|
||||
checkout your fork.
|
||||
3. Write your code in your local copy. It's good practice to create a branch for
|
||||
each new issue you work on, although not compulsory.
|
||||
4. To run the test suite, first install the dependencies by running `npm install`,
|
||||
then run `npm test`.
|
||||
5. Ensure your code is linted by running `npm run lint` -- fix any issue you
|
||||
see listed.
|
||||
6. If the tests pass, you can commit your changes to your fork and then create
|
||||
a pull request from there. Make sure to reference your issue from the pull
|
||||
request comments by including the issue number e.g. `#123`.
|
||||
|
||||
## Issues which are questions
|
||||
|
||||
We will typically close any vague issues or questions that are specific to some
|
||||
app you are writing. Please double check the docs and other references before
|
||||
being trigger happy with posting a question issue.
|
||||
|
||||
Things that will help get your question issue looked at:
|
||||
|
||||
* Full and runnable JS code.
|
||||
* Clear description of the problem or unexpected behavior.
|
||||
* Clear description of the expected result.
|
||||
* Steps you have taken to debug it yourself.
|
||||
|
||||
If you post a question and do not outline the above items or make it easy for
|
||||
us to understand and reproduce your issue, it will be closed.
|
||||
212
Contributing.md
212
Contributing.md
@@ -1,25 +1,209 @@
|
||||
# Express.js Community Contributing Guide 1.0
|
||||
|
||||
## Website Issues
|
||||
The goal of this document is to create a contribution process that:
|
||||
|
||||
Issues for the expressjs.com website go here https://github.com/strongloop/expressjs.com
|
||||
* Encourages new contributions.
|
||||
* Encourages contributors to remain involved.
|
||||
* Avoids unnecessary processes and bureaucracy whenever possible.
|
||||
* Creates a transparent decision making process that makes it clear how
|
||||
contributors can be involved in decision making.
|
||||
|
||||
## PRs and Code contributions
|
||||
## Vocabulary
|
||||
|
||||
* Tests must pass.
|
||||
* Follow existing coding style.
|
||||
* If you fix a bug, add a test.
|
||||
* A **Contributor** is any individual creating or commenting on an issue or pull request.
|
||||
* A **Committer** is a subset of contributors who have been given write access to the repository.
|
||||
* A **Project Captain** is the lead maintainer of a repository.
|
||||
* A **TC (Technical Committee)** is a group of committers representing the required technical
|
||||
expertise to resolve rare disputes.
|
||||
* A **Triager** is a subset of contributors who have been given triage access to the repository.
|
||||
|
||||
## Logging Issues
|
||||
|
||||
## Issues which are questions
|
||||
Log an issue for any question or problem you might have. When in doubt, log an issue, and
|
||||
any additional policies about what to include will be provided in the responses. The only
|
||||
exception is security disclosures which should be sent privately.
|
||||
|
||||
We will typically close any vague issues or questions that are specific to some app you are writing. Please double check the docs and other references before being trigger happy with posting a question issue.
|
||||
Committers may direct you to another repository, ask for additional clarifications, and
|
||||
add appropriate metadata before the issue is addressed.
|
||||
|
||||
Things that will help get your question issue looked at:
|
||||
Please be courteous and respectful. Every participant is expected to follow the
|
||||
project's Code of Conduct.
|
||||
|
||||
* Full and runnable JS code.
|
||||
* Clear description of the problem or unexpected behavior.
|
||||
* Clear description of the expected result.
|
||||
* Steps you have taken to debug it yourself.
|
||||
## Contributions
|
||||
|
||||
If you post a question and do not outline the above items or make it easy for us to understand and reproduce your issue, it will be closed.
|
||||
Any change to resources in this repository must be through pull requests. This applies to all changes
|
||||
to documentation, code, binary files, etc. Even long term committers and TC members must use
|
||||
pull requests.
|
||||
|
||||
No pull request can be merged without being reviewed.
|
||||
|
||||
For non-trivial contributions, pull requests should sit for at least 36 hours to ensure that
|
||||
contributors in other timezones have time to review. Consideration should also be given to
|
||||
weekends and other holiday periods to ensure active committers all have reasonable time to
|
||||
become involved in the discussion and review process if they wish.
|
||||
|
||||
The default for each contribution is that it is accepted once no committer has an objection.
|
||||
During a review, committers may also request that a specific contributor who is most versed in a
|
||||
particular area gives a "LGTM" before the PR can be merged. There is no additional "sign off"
|
||||
process for contributions to land. Once all issues brought by committers are addressed it can
|
||||
be landed by any committer.
|
||||
|
||||
In the case of an objection being raised in a pull request by another committer, all involved
|
||||
committers should seek to arrive at a consensus by way of addressing concerns being expressed
|
||||
by discussion, compromise on the proposed change, or withdrawal of the proposed change.
|
||||
|
||||
If a contribution is controversial and committers cannot agree about how to get it to land
|
||||
or if it should land then it should be escalated to the TC. TC members should regularly
|
||||
discuss pending contributions in order to find a resolution. It is expected that only a
|
||||
small minority of issues be brought to the TC for resolution and that discussion and
|
||||
compromise among committers be the default resolution mechanism.
|
||||
|
||||
## Becoming a Triager
|
||||
|
||||
Anyone can become a triager! Read more about the process of being a triager in
|
||||
[the triage process document](Triager-Guide.md).
|
||||
|
||||
Currently, any existing [organization member](https://github.com/orgs/expressjs/people) can nominate
|
||||
a new triager. If you are interested in becoming a triager, our best advice is to actively participate
|
||||
in the community by helping triaging issues and pull requests. As well we recommend
|
||||
to engage in other community activities like attending the TC meetings, and participating in the Slack
|
||||
discussions.
|
||||
|
||||
You can also reach out to any of the [organization members](https://github.com/orgs/expressjs/people)
|
||||
if you have questions or need guidance.
|
||||
|
||||
## Becoming a Committer
|
||||
|
||||
All contributors who land a non-trivial contribution should be on-boarded in a timely manner,
|
||||
and added as a committer, and be given write access to the repository.
|
||||
|
||||
Committers are expected to follow this policy and continue to send pull requests, go through
|
||||
proper review, and have other committers merge their pull requests.
|
||||
|
||||
## TC Process
|
||||
|
||||
The TC uses a "consensus seeking" process for issues that are escalated to the TC.
|
||||
The group tries to find a resolution that has no open objections among TC members.
|
||||
If a consensus cannot be reached that has no objections then a majority wins vote
|
||||
is called. It is also expected that the majority of decisions made by the TC are via
|
||||
a consensus seeking process and that voting is only used as a last-resort.
|
||||
|
||||
Resolution may involve returning the issue to project captains with suggestions on
|
||||
how to move forward towards a consensus. It is not expected that a meeting of the TC
|
||||
will resolve all issues on its agenda during that meeting and may prefer to continue
|
||||
the discussion happening among the project captains.
|
||||
|
||||
Members can be added to the TC at any time. Any TC member can nominate another committer
|
||||
to the TC and the TC uses its standard consensus seeking process to evaluate whether or
|
||||
not to add this new member. The TC will consist of a minimum of 3 active members and a
|
||||
maximum of 10. If the TC should drop below 5 members the active TC members should nominate
|
||||
someone new. If a TC member is stepping down, they are encouraged (but not required) to
|
||||
nominate someone to take their place.
|
||||
|
||||
TC members will be added as admin's on the Github orgs, npm orgs, and other resources as
|
||||
necessary to be effective in the role.
|
||||
|
||||
To remain "active" a TC member should have participation within the last 12 months and miss
|
||||
no more than six consecutive TC meetings. Our goal is to increase participation, not punish
|
||||
people for any lack of participation, this guideline should be only be used as such
|
||||
(replace an inactive member with a new active one, for example). Members who do not meet this
|
||||
are expected to step down. If A TC member does not step down, an issue can be opened in the
|
||||
discussions repo to move them to inactive status. TC members who step down or are removed due
|
||||
to inactivity will be moved into inactive status.
|
||||
|
||||
Inactive status members can become active members by self nomination if the TC is not already
|
||||
larger than the maximum of 10. They will also be given preference if, while at max size, an
|
||||
active member steps down.
|
||||
|
||||
## Project Captains
|
||||
|
||||
The Express TC can designate captains for individual projects/repos in the
|
||||
organizations. These captains are responsible for being the primary
|
||||
day-to-day maintainers of the repo on a technical and community front.
|
||||
Repo captains are empowered with repo ownership and package publication rights.
|
||||
When there are conflicts, especially on topics that effect the Express project
|
||||
at large, captains are responsible to raise it up to the TC and drive
|
||||
those conflicts to resolution. Captains are also responsible for making sure
|
||||
community members follow the community guidelines, maintaining the repo
|
||||
and the published package, as well as in providing user support.
|
||||
|
||||
Like TC members, Repo captains are a subset of committers.
|
||||
|
||||
To become a captain for a project the candidate is expected to participate in that
|
||||
project for at least 6 months as a committer prior to the request. They should have
|
||||
helped with code contributions as well as triaging issues. They are also required to
|
||||
have 2FA enabled on both their GitHub and npm accounts. Any TC member or existing
|
||||
captain on the repo can nominate another committer to the captain role, submit a PR to
|
||||
this doc, under `Current Project Captains` section (maintaining the sort order) with
|
||||
the project, their GitHub handle and npm username (if different). The PR will require
|
||||
at least 2 approvals from TC members and 2 weeks hold time to allow for comment and/or
|
||||
dissent. When the PR is merged, a TC member will add them to the proper GitHub/npm groups.
|
||||
|
||||
### Active Projects and Captains
|
||||
|
||||
- `expressjs/badgeboard`: @wesleytodd
|
||||
- `expressjs/basic-auth-connect`: N/A
|
||||
- `expressjs/body-parser`: @wesleytodd, @jonchurch
|
||||
- `expressjs/compression`: N/A
|
||||
- `expressjs/connect-multiparty`: N/A
|
||||
- `expressjs/cookie-parser`: @wesleytodd, @UlisesGascon
|
||||
- `expressjs/cookie-session`: N/A
|
||||
- `expressjs/cors`: @jonchurch
|
||||
- `expressjs/discussions`: @wesleytodd
|
||||
- `expressjs/errorhandler`: N/A
|
||||
- `expressjs/express-paginate`: N/A
|
||||
- `expressjs/express`: @wesleytodd
|
||||
- `expressjs/expressjs.com`: @crandmck, @jonchurch
|
||||
- `expressjs/flash`: N/A
|
||||
- `expressjs/generator`: @wesleytodd
|
||||
- `expressjs/method-override`: N/A
|
||||
- `expressjs/morgan`: @jonchurch
|
||||
- `expressjs/multer`: @LinusU
|
||||
- `expressjs/response-time`: @blakeembrey
|
||||
- `expressjs/serve-favicon`: N/A
|
||||
- `expressjs/serve-index`: N/A
|
||||
- `expressjs/serve-static`: N/A
|
||||
- `expressjs/session`: N/A
|
||||
- `expressjs/statusboard`: @wesleytodd
|
||||
- `expressjs/timeout`: N/A
|
||||
- `expressjs/vhost`: N/A
|
||||
- `jshttp/accepts`: @blakeembrey
|
||||
- `jshttp/basic-auth`: @blakeembrey
|
||||
- `jshttp/compressible`: @blakeembrey
|
||||
- `jshttp/content-disposition`: @blakeembrey
|
||||
- `jshttp/content-type`: @blakeembrey
|
||||
- `jshttp/cookie`: @wesleytodd
|
||||
- `jshttp/etag`: @blakeembrey
|
||||
- `jshttp/forwarded`: @blakeembrey
|
||||
- `jshttp/fresh`: @blakeembrey
|
||||
- `jshttp/http-assert`: @wesleytodd, @jonchurch
|
||||
- `jshttp/http-errors`: @wesleytodd, @jonchurch
|
||||
- `jshttp/media-typer`: @blakeembrey
|
||||
- `jshttp/methods`: @blakeembrey
|
||||
- `jshttp/mime-db`: @blakeembrey, @UlisesGascon
|
||||
- `jshttp/mime-types`: @blakeembrey, @UlisesGascon
|
||||
- `jshttp/negotiator`: @blakeembrey
|
||||
- `jshttp/on-finished`: @wesleytodd
|
||||
- `jshttp/on-headers`: @blakeembrey
|
||||
- `jshttp/proxy-addr`: @wesleytodd
|
||||
- `jshttp/range-parser`: @blakeembrey
|
||||
- `jshttp/statuses`: @blakeembrey
|
||||
- `jshttp/type-is`: @blakeembrey
|
||||
- `jshttp/vary`: @blakeembrey
|
||||
- `pillarjs/cookies`: @blakeembrey
|
||||
- `pillarjs/csrf`: N/A
|
||||
- `pillarjs/encodeurl`: @blakeembrey
|
||||
- `pillarjs/finalhandler`: @wesleytodd
|
||||
- `pillarjs/hbs`: N/A
|
||||
- `pillarjs/multiparty`: @blakeembrey
|
||||
- `pillarjs/parseurl`: @blakeembrey
|
||||
- `pillarjs/path-to-regexp`: @blakeembrey
|
||||
- `pillarjs/request`: @wesleytodd
|
||||
- `pillarjs/resolve-path`: @blakeembrey
|
||||
- `pillarjs/router`: @blakeembrey
|
||||
- `pillarjs/send`: @blakeembrey
|
||||
- `pillarjs/understanding-csrf`: N/A
|
||||
|
||||
### Current Initiative Captains
|
||||
|
||||
- Triage team [ref](https://github.com/expressjs/discussions/issues/227): @UlisesGascon
|
||||
|
||||
832
History.md
832
History.md
@@ -1,3 +1,813 @@
|
||||
5.0.0 / 2024-09-10
|
||||
=========================
|
||||
* remove:
|
||||
- `path-is-absolute` dependency - use `path.isAbsolute` instead
|
||||
* breaking:
|
||||
* `res.status()` accepts only integers, and input must be greater than 99 and less than 1000
|
||||
* will throw a `RangeError: Invalid status code: ${code}. Status code must be greater than 99 and less than 1000.` for inputs outside this range
|
||||
* will throw a `TypeError: Invalid status code: ${code}. Status code must be an integer.` for non integer inputs
|
||||
* deps: send@1.0.0
|
||||
* `res.redirect('back')` and `res.location('back')` is no longer a supported magic string, explicitly use `req.get('Referrer') || '/'`.
|
||||
* change:
|
||||
- `res.clearCookie` will ignore user provided `maxAge` and `expires` options
|
||||
* deps: cookie-signature@^1.2.1
|
||||
* deps: debug@4.3.6
|
||||
* deps: merge-descriptors@^2.0.0
|
||||
* deps: serve-static@^2.1.0
|
||||
* deps: qs@6.13.0
|
||||
* deps: accepts@^2.0.0
|
||||
* deps: mime-types@^3.0.0
|
||||
- `application/javascript` => `text/javascript`
|
||||
* deps: type-is@^2.0.0
|
||||
* deps: content-disposition@^1.0.0
|
||||
* deps: finalhandler@^2.0.0
|
||||
* deps: fresh@^2.0.0
|
||||
* deps: body-parser@^2.0.1
|
||||
* deps: send@^1.1.0
|
||||
|
||||
5.0.0-beta.3 / 2024-03-25
|
||||
=========================
|
||||
|
||||
This incorporates all changes after 4.19.1 up to 4.19.2.
|
||||
|
||||
5.0.0-beta.2 / 2024-03-20
|
||||
=========================
|
||||
|
||||
This incorporates all changes after 4.17.2 up to 4.19.1.
|
||||
|
||||
5.0.0-beta.1 / 2022-02-14
|
||||
=========================
|
||||
|
||||
This is the first Express 5.0 beta release, based off 4.17.2 and includes
|
||||
changes from 5.0.0-alpha.8.
|
||||
|
||||
* change:
|
||||
- Default "query parser" setting to `'simple'`
|
||||
- Requires Node.js 4+
|
||||
- Use `mime-types` for file to content type mapping
|
||||
* deps: array-flatten@3.0.0
|
||||
* deps: body-parser@2.0.0-beta.1
|
||||
- `req.body` is no longer always initialized to `{}`
|
||||
- `urlencoded` parser now defaults `extended` to `false`
|
||||
- Use `on-finished` to determine when body read
|
||||
* deps: router@2.0.0-beta.1
|
||||
- Add new `?`, `*`, and `+` parameter modifiers
|
||||
- Internalize private `router.process_params` method
|
||||
- Matching group expressions are only RegExp syntax
|
||||
- Named matching groups no longer available by position in `req.params`
|
||||
- Regular expressions can only be used in a matching group
|
||||
- Remove `debug` dependency
|
||||
- Special `*` path segment behavior removed
|
||||
- deps: array-flatten@3.0.0
|
||||
- deps: parseurl@~1.3.3
|
||||
- deps: path-to-regexp@3.2.0
|
||||
- deps: setprototypeof@1.2.0
|
||||
* deps: send@1.0.0-beta.1
|
||||
- Change `dotfiles` option default to `'ignore'`
|
||||
- Remove `hidden` option; use `dotfiles` option instead
|
||||
- Use `mime-types` for file to content type mapping
|
||||
- deps: debug@3.1.0
|
||||
* deps: serve-static@2.0.0-beta.1
|
||||
- Change `dotfiles` option default to `'ignore'`
|
||||
- Remove `hidden` option; use `dotfiles` option instead
|
||||
- Use `mime-types` for file to content type mapping
|
||||
- deps: send@1.0.0-beta.1
|
||||
|
||||
5.0.0-alpha.8 / 2020-03-25
|
||||
==========================
|
||||
|
||||
This is the eighth Express 5.0 alpha release, based off 4.17.1 and includes
|
||||
changes from 5.0.0-alpha.7.
|
||||
|
||||
5.0.0-alpha.7 / 2018-10-26
|
||||
==========================
|
||||
|
||||
This is the seventh Express 5.0 alpha release, based off 4.16.4 and includes
|
||||
changes from 5.0.0-alpha.6.
|
||||
|
||||
The major change with this alpha is the basic support for returned, rejected
|
||||
Promises in the router.
|
||||
|
||||
* remove:
|
||||
- `path-to-regexp` dependency
|
||||
* deps: debug@3.1.0
|
||||
- Add `DEBUG_HIDE_DATE` environment variable
|
||||
- Change timer to per-namespace instead of global
|
||||
- Change non-TTY date format
|
||||
- Remove `DEBUG_FD` environment variable support
|
||||
- Support 256 namespace colors
|
||||
* deps: router@2.0.0-alpha.1
|
||||
- Add basic support for returned, rejected Promises
|
||||
- Fix JSDoc for `Router` constructor
|
||||
- deps: debug@3.1.0
|
||||
- deps: parseurl@~1.3.2
|
||||
- deps: setprototypeof@1.1.0
|
||||
- deps: utils-merge@1.0.1
|
||||
|
||||
5.0.0-alpha.6 / 2017-09-24
|
||||
==========================
|
||||
|
||||
This is the sixth Express 5.0 alpha release, based off 4.15.5 and includes
|
||||
changes from 5.0.0-alpha.5.
|
||||
|
||||
* remove:
|
||||
- `res.redirect(url, status)` signature - use `res.redirect(status, url)`
|
||||
- `res.send(status, body)` signature - use `res.status(status).send(body)`
|
||||
* deps: router@~1.3.1
|
||||
- deps: debug@2.6.8
|
||||
|
||||
5.0.0-alpha.5 / 2017-03-06
|
||||
==========================
|
||||
|
||||
This is the fifth Express 5.0 alpha release, based off 4.15.2 and includes
|
||||
changes from 5.0.0-alpha.4.
|
||||
|
||||
5.0.0-alpha.4 / 2017-03-01
|
||||
==========================
|
||||
|
||||
This is the fourth Express 5.0 alpha release, based off 4.15.0 and includes
|
||||
changes from 5.0.0-alpha.3.
|
||||
|
||||
* remove:
|
||||
- Remove Express 3.x middleware error stubs
|
||||
* deps: router@~1.3.0
|
||||
- Add `next("router")` to exit from router
|
||||
- Fix case where `router.use` skipped requests routes did not
|
||||
- Skip routing when `req.url` is not set
|
||||
- Use `%o` in path debug to tell types apart
|
||||
- deps: debug@2.6.1
|
||||
- deps: setprototypeof@1.0.3
|
||||
- perf: add fast match path for `*` route
|
||||
|
||||
5.0.0-alpha.3 / 2017-01-28
|
||||
==========================
|
||||
|
||||
This is the third Express 5.0 alpha release, based off 4.14.1 and includes
|
||||
changes from 5.0.0-alpha.2.
|
||||
|
||||
* remove:
|
||||
- `res.json(status, obj)` signature - use `res.status(status).json(obj)`
|
||||
- `res.jsonp(status, obj)` signature - use `res.status(status).jsonp(obj)`
|
||||
- `res.vary()` (no arguments) -- provide a field name as an argument
|
||||
* deps: array-flatten@2.1.1
|
||||
* deps: path-is-absolute@1.0.1
|
||||
* deps: router@~1.1.5
|
||||
- deps: array-flatten@2.0.1
|
||||
- deps: methods@~1.1.2
|
||||
- deps: parseurl@~1.3.1
|
||||
- deps: setprototypeof@1.0.2
|
||||
|
||||
5.0.0-alpha.2 / 2015-07-06
|
||||
==========================
|
||||
|
||||
This is the second Express 5.0 alpha release, based off 4.13.1 and includes
|
||||
changes from 5.0.0-alpha.1.
|
||||
|
||||
* remove:
|
||||
- `app.param(fn)`
|
||||
- `req.param()` -- use `req.params`, `req.body`, or `req.query` instead
|
||||
* change:
|
||||
- `res.render` callback is always async, even for sync view engines
|
||||
- The leading `:` character in `name` for `app.param(name, fn)` is no longer removed
|
||||
- Use `router` module for routing
|
||||
- Use `path-is-absolute` module for absolute path detection
|
||||
|
||||
5.0.0-alpha.1 / 2014-11-06
|
||||
==========================
|
||||
|
||||
This is the first Express 5.0 alpha release, based off 4.10.1.
|
||||
|
||||
* remove:
|
||||
- `app.del` - use `app.delete`
|
||||
- `req.acceptsCharset` - use `req.acceptsCharsets`
|
||||
- `req.acceptsEncoding` - use `req.acceptsEncodings`
|
||||
- `req.acceptsLanguage` - use `req.acceptsLanguages`
|
||||
- `res.json(obj, status)` signature - use `res.json(status, obj)`
|
||||
- `res.jsonp(obj, status)` signature - use `res.jsonp(status, obj)`
|
||||
- `res.send(body, status)` signature - use `res.send(status, body)`
|
||||
- `res.send(status)` signature - use `res.sendStatus(status)`
|
||||
- `res.sendfile` - use `res.sendFile` instead
|
||||
- `express.query` middleware
|
||||
* change:
|
||||
- `req.host` now returns host (`hostname:port`) - use `req.hostname` for only hostname
|
||||
- `req.query` is now a getter instead of a plain property
|
||||
* add:
|
||||
- `app.router` is a reference to the base router
|
||||
|
||||
4.20.0 / 2024-09-10
|
||||
==========
|
||||
* deps: serve-static@0.16.0
|
||||
* Remove link renderization in html while redirecting
|
||||
* deps: send@0.19.0
|
||||
* Remove link renderization in html while redirecting
|
||||
* deps: body-parser@0.6.0
|
||||
* add `depth` option to customize the depth level in the parser
|
||||
* IMPORTANT: The default `depth` level for parsing URL-encoded data is now `32` (previously was `Infinity`)
|
||||
* Remove link renderization in html while using `res.redirect`
|
||||
* deps: path-to-regexp@0.1.10
|
||||
- Adds support for named matching groups in the routes using a regex
|
||||
- Adds backtracking protection to parameters without regexes defined
|
||||
* deps: encodeurl@~2.0.0
|
||||
- Removes encoding of `\`, `|`, and `^` to align better with URL spec
|
||||
* Deprecate passing `options.maxAge` and `options.expires` to `res.clearCookie`
|
||||
- Will be ignored in v5, clearCookie will set a cookie with an expires in the past to instruct clients to delete the cookie
|
||||
|
||||
4.19.2 / 2024-03-25
|
||||
==========
|
||||
|
||||
* Improved fix for open redirect allow list bypass
|
||||
|
||||
4.19.1 / 2024-03-20
|
||||
==========
|
||||
|
||||
* Allow passing non-strings to res.location with new encoding handling checks
|
||||
|
||||
4.19.0 / 2024-03-20
|
||||
==========
|
||||
|
||||
* Prevent open redirect allow list bypass due to encodeurl
|
||||
* deps: cookie@0.6.0
|
||||
|
||||
4.18.3 / 2024-02-29
|
||||
==========
|
||||
|
||||
* Fix routing requests without method
|
||||
* deps: body-parser@1.20.2
|
||||
- Fix strict json error message on Node.js 19+
|
||||
- deps: content-type@~1.0.5
|
||||
- deps: raw-body@2.5.2
|
||||
* deps: cookie@0.6.0
|
||||
- Add `partitioned` option
|
||||
|
||||
4.18.2 / 2022-10-08
|
||||
===================
|
||||
|
||||
* Fix regression routing a large stack in a single route
|
||||
* deps: body-parser@1.20.1
|
||||
- deps: qs@6.11.0
|
||||
- perf: remove unnecessary object clone
|
||||
* deps: qs@6.11.0
|
||||
|
||||
4.18.1 / 2022-04-29
|
||||
===================
|
||||
|
||||
* Fix hanging on large stack of sync routes
|
||||
|
||||
4.18.0 / 2022-04-25
|
||||
===================
|
||||
|
||||
* Add "root" option to `res.download`
|
||||
* Allow `options` without `filename` in `res.download`
|
||||
* Deprecate string and non-integer arguments to `res.status`
|
||||
* Fix behavior of `null`/`undefined` as `maxAge` in `res.cookie`
|
||||
* Fix handling very large stacks of sync middleware
|
||||
* Ignore `Object.prototype` values in settings through `app.set`/`app.get`
|
||||
* Invoke `default` with same arguments as types in `res.format`
|
||||
* Support proper 205 responses using `res.send`
|
||||
* Use `http-errors` for `res.format` error
|
||||
* deps: body-parser@1.20.0
|
||||
- Fix error message for json parse whitespace in `strict`
|
||||
- Fix internal error when inflated body exceeds limit
|
||||
- Prevent loss of async hooks context
|
||||
- Prevent hanging when request already read
|
||||
- deps: depd@2.0.0
|
||||
- deps: http-errors@2.0.0
|
||||
- deps: on-finished@2.4.1
|
||||
- deps: qs@6.10.3
|
||||
- deps: raw-body@2.5.1
|
||||
* deps: cookie@0.5.0
|
||||
- Add `priority` option
|
||||
- Fix `expires` option to reject invalid dates
|
||||
* deps: depd@2.0.0
|
||||
- Replace internal `eval` usage with `Function` constructor
|
||||
- Use instance methods on `process` to check for listeners
|
||||
* deps: finalhandler@1.2.0
|
||||
- Remove set content headers that break response
|
||||
- deps: on-finished@2.4.1
|
||||
- deps: statuses@2.0.1
|
||||
* deps: on-finished@2.4.1
|
||||
- Prevent loss of async hooks context
|
||||
* deps: qs@6.10.3
|
||||
* deps: send@0.18.0
|
||||
- Fix emitted 416 error missing headers property
|
||||
- Limit the headers removed for 304 response
|
||||
- deps: depd@2.0.0
|
||||
- deps: destroy@1.2.0
|
||||
- deps: http-errors@2.0.0
|
||||
- deps: on-finished@2.4.1
|
||||
- deps: statuses@2.0.1
|
||||
* deps: serve-static@1.15.0
|
||||
- deps: send@0.18.0
|
||||
* deps: statuses@2.0.1
|
||||
- Remove code 306
|
||||
- Rename `425 Unordered Collection` to standard `425 Too Early`
|
||||
|
||||
4.17.3 / 2022-02-16
|
||||
===================
|
||||
|
||||
* deps: accepts@~1.3.8
|
||||
- deps: mime-types@~2.1.34
|
||||
- deps: negotiator@0.6.3
|
||||
* deps: body-parser@1.19.2
|
||||
- deps: bytes@3.1.2
|
||||
- deps: qs@6.9.7
|
||||
- deps: raw-body@2.4.3
|
||||
* deps: cookie@0.4.2
|
||||
* deps: qs@6.9.7
|
||||
* Fix handling of `__proto__` keys
|
||||
* pref: remove unnecessary regexp for trust proxy
|
||||
|
||||
4.17.2 / 2021-12-16
|
||||
===================
|
||||
|
||||
* Fix handling of `undefined` in `res.jsonp`
|
||||
* Fix handling of `undefined` when `"json escape"` is enabled
|
||||
* Fix incorrect middleware execution with unanchored `RegExp`s
|
||||
* Fix `res.jsonp(obj, status)` deprecation message
|
||||
* Fix typo in `res.is` JSDoc
|
||||
* deps: body-parser@1.19.1
|
||||
- deps: bytes@3.1.1
|
||||
- deps: http-errors@1.8.1
|
||||
- deps: qs@6.9.6
|
||||
- deps: raw-body@2.4.2
|
||||
- deps: safe-buffer@5.2.1
|
||||
- deps: type-is@~1.6.18
|
||||
* deps: content-disposition@0.5.4
|
||||
- deps: safe-buffer@5.2.1
|
||||
* deps: cookie@0.4.1
|
||||
- Fix `maxAge` option to reject invalid values
|
||||
* deps: proxy-addr@~2.0.7
|
||||
- Use `req.socket` over deprecated `req.connection`
|
||||
- deps: forwarded@0.2.0
|
||||
- deps: ipaddr.js@1.9.1
|
||||
* deps: qs@6.9.6
|
||||
* deps: safe-buffer@5.2.1
|
||||
* deps: send@0.17.2
|
||||
- deps: http-errors@1.8.1
|
||||
- deps: ms@2.1.3
|
||||
- pref: ignore empty http tokens
|
||||
* deps: serve-static@1.14.2
|
||||
- deps: send@0.17.2
|
||||
* deps: setprototypeof@1.2.0
|
||||
|
||||
4.17.1 / 2019-05-25
|
||||
===================
|
||||
|
||||
* Revert "Improve error message for `null`/`undefined` to `res.status`"
|
||||
|
||||
4.17.0 / 2019-05-16
|
||||
===================
|
||||
|
||||
* Add `express.raw` to parse bodies into `Buffer`
|
||||
* Add `express.text` to parse bodies into string
|
||||
* Improve error message for non-strings to `res.sendFile`
|
||||
* Improve error message for `null`/`undefined` to `res.status`
|
||||
* Support multiple hosts in `X-Forwarded-Host`
|
||||
* deps: accepts@~1.3.7
|
||||
* deps: body-parser@1.19.0
|
||||
- Add encoding MIK
|
||||
- Add petabyte (`pb`) support
|
||||
- Fix parsing array brackets after index
|
||||
- deps: bytes@3.1.0
|
||||
- deps: http-errors@1.7.2
|
||||
- deps: iconv-lite@0.4.24
|
||||
- deps: qs@6.7.0
|
||||
- deps: raw-body@2.4.0
|
||||
- deps: type-is@~1.6.17
|
||||
* deps: content-disposition@0.5.3
|
||||
* deps: cookie@0.4.0
|
||||
- Add `SameSite=None` support
|
||||
* deps: finalhandler@~1.1.2
|
||||
- Set stricter `Content-Security-Policy` header
|
||||
- deps: parseurl@~1.3.3
|
||||
- deps: statuses@~1.5.0
|
||||
* deps: parseurl@~1.3.3
|
||||
* deps: proxy-addr@~2.0.5
|
||||
- deps: ipaddr.js@1.9.0
|
||||
* deps: qs@6.7.0
|
||||
- Fix parsing array brackets after index
|
||||
* deps: range-parser@~1.2.1
|
||||
* deps: send@0.17.1
|
||||
- Set stricter CSP header in redirect & error responses
|
||||
- deps: http-errors@~1.7.2
|
||||
- deps: mime@1.6.0
|
||||
- deps: ms@2.1.1
|
||||
- deps: range-parser@~1.2.1
|
||||
- deps: statuses@~1.5.0
|
||||
- perf: remove redundant `path.normalize` call
|
||||
* deps: serve-static@1.14.1
|
||||
- Set stricter CSP header in redirect response
|
||||
- deps: parseurl@~1.3.3
|
||||
- deps: send@0.17.1
|
||||
* deps: setprototypeof@1.1.1
|
||||
* deps: statuses@~1.5.0
|
||||
- Add `103 Early Hints`
|
||||
* deps: type-is@~1.6.18
|
||||
- deps: mime-types@~2.1.24
|
||||
- perf: prevent internal `throw` on invalid type
|
||||
|
||||
4.16.4 / 2018-10-10
|
||||
===================
|
||||
|
||||
* Fix issue where `"Request aborted"` may be logged in `res.sendfile`
|
||||
* Fix JSDoc for `Router` constructor
|
||||
* deps: body-parser@1.18.3
|
||||
- Fix deprecation warnings on Node.js 10+
|
||||
- Fix stack trace for strict json parse error
|
||||
- deps: depd@~1.1.2
|
||||
- deps: http-errors@~1.6.3
|
||||
- deps: iconv-lite@0.4.23
|
||||
- deps: qs@6.5.2
|
||||
- deps: raw-body@2.3.3
|
||||
- deps: type-is@~1.6.16
|
||||
* deps: proxy-addr@~2.0.4
|
||||
- deps: ipaddr.js@1.8.0
|
||||
* deps: qs@6.5.2
|
||||
* deps: safe-buffer@5.1.2
|
||||
|
||||
4.16.3 / 2018-03-12
|
||||
===================
|
||||
|
||||
* deps: accepts@~1.3.5
|
||||
- deps: mime-types@~2.1.18
|
||||
* deps: depd@~1.1.2
|
||||
- perf: remove argument reassignment
|
||||
* deps: encodeurl@~1.0.2
|
||||
- Fix encoding `%` as last character
|
||||
* deps: finalhandler@1.1.1
|
||||
- Fix 404 output for bad / missing pathnames
|
||||
- deps: encodeurl@~1.0.2
|
||||
- deps: statuses@~1.4.0
|
||||
* deps: proxy-addr@~2.0.3
|
||||
- deps: ipaddr.js@1.6.0
|
||||
* deps: send@0.16.2
|
||||
- Fix incorrect end tag in default error & redirects
|
||||
- deps: depd@~1.1.2
|
||||
- deps: encodeurl@~1.0.2
|
||||
- deps: statuses@~1.4.0
|
||||
* deps: serve-static@1.13.2
|
||||
- Fix incorrect end tag in redirects
|
||||
- deps: encodeurl@~1.0.2
|
||||
- deps: send@0.16.2
|
||||
* deps: statuses@~1.4.0
|
||||
* deps: type-is@~1.6.16
|
||||
- deps: mime-types@~2.1.18
|
||||
|
||||
4.16.2 / 2017-10-09
|
||||
===================
|
||||
|
||||
* Fix `TypeError` in `res.send` when given `Buffer` and `ETag` header set
|
||||
* perf: skip parsing of entire `X-Forwarded-Proto` header
|
||||
|
||||
4.16.1 / 2017-09-29
|
||||
===================
|
||||
|
||||
* deps: send@0.16.1
|
||||
* deps: serve-static@1.13.1
|
||||
- Fix regression when `root` is incorrectly set to a file
|
||||
- deps: send@0.16.1
|
||||
|
||||
4.16.0 / 2017-09-28
|
||||
===================
|
||||
|
||||
* Add `"json escape"` setting for `res.json` and `res.jsonp`
|
||||
* Add `express.json` and `express.urlencoded` to parse bodies
|
||||
* Add `options` argument to `res.download`
|
||||
* Improve error message when autoloading invalid view engine
|
||||
* Improve error messages when non-function provided as middleware
|
||||
* Skip `Buffer` encoding when not generating ETag for small response
|
||||
* Use `safe-buffer` for improved Buffer API
|
||||
* deps: accepts@~1.3.4
|
||||
- deps: mime-types@~2.1.16
|
||||
* deps: content-type@~1.0.4
|
||||
- perf: remove argument reassignment
|
||||
- perf: skip parameter parsing when no parameters
|
||||
* deps: etag@~1.8.1
|
||||
- perf: replace regular expression with substring
|
||||
* deps: finalhandler@1.1.0
|
||||
- Use `res.headersSent` when available
|
||||
* deps: parseurl@~1.3.2
|
||||
- perf: reduce overhead for full URLs
|
||||
- perf: unroll the "fast-path" `RegExp`
|
||||
* deps: proxy-addr@~2.0.2
|
||||
- Fix trimming leading / trailing OWS in `X-Forwarded-For`
|
||||
- deps: forwarded@~0.1.2
|
||||
- deps: ipaddr.js@1.5.2
|
||||
- perf: reduce overhead when no `X-Forwarded-For` header
|
||||
* deps: qs@6.5.1
|
||||
- Fix parsing & compacting very deep objects
|
||||
* deps: send@0.16.0
|
||||
- Add 70 new types for file extensions
|
||||
- Add `immutable` option
|
||||
- Fix missing `</html>` in default error & redirects
|
||||
- Set charset as "UTF-8" for .js and .json
|
||||
- Use instance methods on steam to check for listeners
|
||||
- deps: mime@1.4.1
|
||||
- perf: improve path validation speed
|
||||
* deps: serve-static@1.13.0
|
||||
- Add 70 new types for file extensions
|
||||
- Add `immutable` option
|
||||
- Set charset as "UTF-8" for .js and .json
|
||||
- deps: send@0.16.0
|
||||
* deps: setprototypeof@1.1.0
|
||||
* deps: utils-merge@1.0.1
|
||||
* deps: vary@~1.1.2
|
||||
- perf: improve header token parsing speed
|
||||
* perf: re-use options object when generating ETags
|
||||
* perf: remove dead `.charset` set in `res.jsonp`
|
||||
|
||||
4.15.5 / 2017-09-24
|
||||
===================
|
||||
|
||||
* deps: debug@2.6.9
|
||||
* deps: finalhandler@~1.0.6
|
||||
- deps: debug@2.6.9
|
||||
- deps: parseurl@~1.3.2
|
||||
* deps: fresh@0.5.2
|
||||
- Fix handling of modified headers with invalid dates
|
||||
- perf: improve ETag match loop
|
||||
- perf: improve `If-None-Match` token parsing
|
||||
* deps: send@0.15.6
|
||||
- Fix handling of modified headers with invalid dates
|
||||
- deps: debug@2.6.9
|
||||
- deps: etag@~1.8.1
|
||||
- deps: fresh@0.5.2
|
||||
- perf: improve `If-Match` token parsing
|
||||
* deps: serve-static@1.12.6
|
||||
- deps: parseurl@~1.3.2
|
||||
- deps: send@0.15.6
|
||||
- perf: improve slash collapsing
|
||||
|
||||
4.15.4 / 2017-08-06
|
||||
===================
|
||||
|
||||
* deps: debug@2.6.8
|
||||
* deps: depd@~1.1.1
|
||||
- Remove unnecessary `Buffer` loading
|
||||
* deps: finalhandler@~1.0.4
|
||||
- deps: debug@2.6.8
|
||||
* deps: proxy-addr@~1.1.5
|
||||
- Fix array argument being altered
|
||||
- deps: ipaddr.js@1.4.0
|
||||
* deps: qs@6.5.0
|
||||
* deps: send@0.15.4
|
||||
- deps: debug@2.6.8
|
||||
- deps: depd@~1.1.1
|
||||
- deps: http-errors@~1.6.2
|
||||
* deps: serve-static@1.12.4
|
||||
- deps: send@0.15.4
|
||||
|
||||
4.15.3 / 2017-05-16
|
||||
===================
|
||||
|
||||
* Fix error when `res.set` cannot add charset to `Content-Type`
|
||||
* deps: debug@2.6.7
|
||||
- Fix `DEBUG_MAX_ARRAY_LENGTH`
|
||||
- deps: ms@2.0.0
|
||||
* deps: finalhandler@~1.0.3
|
||||
- Fix missing `</html>` in HTML document
|
||||
- deps: debug@2.6.7
|
||||
* deps: proxy-addr@~1.1.4
|
||||
- deps: ipaddr.js@1.3.0
|
||||
* deps: send@0.15.3
|
||||
- deps: debug@2.6.7
|
||||
- deps: ms@2.0.0
|
||||
* deps: serve-static@1.12.3
|
||||
- deps: send@0.15.3
|
||||
* deps: type-is@~1.6.15
|
||||
- deps: mime-types@~2.1.15
|
||||
* deps: vary@~1.1.1
|
||||
- perf: hoist regular expression
|
||||
|
||||
4.15.2 / 2017-03-06
|
||||
===================
|
||||
|
||||
* deps: qs@6.4.0
|
||||
- Fix regression parsing keys starting with `[`
|
||||
|
||||
4.15.1 / 2017-03-05
|
||||
===================
|
||||
|
||||
* deps: send@0.15.1
|
||||
- Fix issue when `Date.parse` does not return `NaN` on invalid date
|
||||
- Fix strict violation in broken environments
|
||||
* deps: serve-static@1.12.1
|
||||
- Fix issue when `Date.parse` does not return `NaN` on invalid date
|
||||
- deps: send@0.15.1
|
||||
|
||||
4.15.0 / 2017-03-01
|
||||
===================
|
||||
|
||||
* Add debug message when loading view engine
|
||||
* Add `next("router")` to exit from router
|
||||
* Fix case where `router.use` skipped requests routes did not
|
||||
* Remove usage of `res._headers` private field
|
||||
- Improves compatibility with Node.js 8 nightly
|
||||
* Skip routing when `req.url` is not set
|
||||
* Use `%o` in path debug to tell types apart
|
||||
* Use `Object.create` to setup request & response prototypes
|
||||
* Use `setprototypeof` module to replace `__proto__` setting
|
||||
* Use `statuses` instead of `http` module for status messages
|
||||
* deps: debug@2.6.1
|
||||
- Allow colors in workers
|
||||
- Deprecated `DEBUG_FD` environment variable set to `3` or higher
|
||||
- Fix error when running under React Native
|
||||
- Use same color for same namespace
|
||||
- deps: ms@0.7.2
|
||||
* deps: etag@~1.8.0
|
||||
- Use SHA1 instead of MD5 for ETag hashing
|
||||
- Works with FIPS 140-2 OpenSSL configuration
|
||||
* deps: finalhandler@~1.0.0
|
||||
- Fix exception when `err` cannot be converted to a string
|
||||
- Fully URL-encode the pathname in the 404
|
||||
- Only include the pathname in the 404 message
|
||||
- Send complete HTML document
|
||||
- Set `Content-Security-Policy: default-src 'self'` header
|
||||
- deps: debug@2.6.1
|
||||
* deps: fresh@0.5.0
|
||||
- Fix false detection of `no-cache` request directive
|
||||
- Fix incorrect result when `If-None-Match` has both `*` and ETags
|
||||
- Fix weak `ETag` matching to match spec
|
||||
- perf: delay reading header values until needed
|
||||
- perf: enable strict mode
|
||||
- perf: hoist regular expressions
|
||||
- perf: remove duplicate conditional
|
||||
- perf: remove unnecessary boolean coercions
|
||||
- perf: skip checking modified time if ETag check failed
|
||||
- perf: skip parsing `If-None-Match` when no `ETag` header
|
||||
- perf: use `Date.parse` instead of `new Date`
|
||||
* deps: qs@6.3.1
|
||||
- Fix array parsing from skipping empty values
|
||||
- Fix compacting nested arrays
|
||||
* deps: send@0.15.0
|
||||
- Fix false detection of `no-cache` request directive
|
||||
- Fix incorrect result when `If-None-Match` has both `*` and ETags
|
||||
- Fix weak `ETag` matching to match spec
|
||||
- Remove usage of `res._headers` private field
|
||||
- Support `If-Match` and `If-Unmodified-Since` headers
|
||||
- Use `res.getHeaderNames()` when available
|
||||
- Use `res.headersSent` when available
|
||||
- deps: debug@2.6.1
|
||||
- deps: etag@~1.8.0
|
||||
- deps: fresh@0.5.0
|
||||
- deps: http-errors@~1.6.1
|
||||
* deps: serve-static@1.12.0
|
||||
- Fix false detection of `no-cache` request directive
|
||||
- Fix incorrect result when `If-None-Match` has both `*` and ETags
|
||||
- Fix weak `ETag` matching to match spec
|
||||
- Remove usage of `res._headers` private field
|
||||
- Send complete HTML document in redirect response
|
||||
- Set default CSP header in redirect response
|
||||
- Support `If-Match` and `If-Unmodified-Since` headers
|
||||
- Use `res.getHeaderNames()` when available
|
||||
- Use `res.headersSent` when available
|
||||
- deps: send@0.15.0
|
||||
* perf: add fast match path for `*` route
|
||||
* perf: improve `req.ips` performance
|
||||
|
||||
4.14.1 / 2017-01-28
|
||||
===================
|
||||
|
||||
* deps: content-disposition@0.5.2
|
||||
* deps: finalhandler@0.5.1
|
||||
- Fix exception when `err.headers` is not an object
|
||||
- deps: statuses@~1.3.1
|
||||
- perf: hoist regular expressions
|
||||
- perf: remove duplicate validation path
|
||||
* deps: proxy-addr@~1.1.3
|
||||
- deps: ipaddr.js@1.2.0
|
||||
* deps: send@0.14.2
|
||||
- deps: http-errors@~1.5.1
|
||||
- deps: ms@0.7.2
|
||||
- deps: statuses@~1.3.1
|
||||
* deps: serve-static@~1.11.2
|
||||
- deps: send@0.14.2
|
||||
* deps: type-is@~1.6.14
|
||||
- deps: mime-types@~2.1.13
|
||||
|
||||
4.14.0 / 2016-06-16
|
||||
===================
|
||||
|
||||
* Add `acceptRanges` option to `res.sendFile`/`res.sendfile`
|
||||
* Add `cacheControl` option to `res.sendFile`/`res.sendfile`
|
||||
* Add `options` argument to `req.range`
|
||||
- Includes the `combine` option
|
||||
* Encode URL in `res.location`/`res.redirect` if not already encoded
|
||||
* Fix some redirect handling in `res.sendFile`/`res.sendfile`
|
||||
* Fix Windows absolute path check using forward slashes
|
||||
* Improve error with invalid arguments to `req.get()`
|
||||
* Improve performance for `res.json`/`res.jsonp` in most cases
|
||||
* Improve `Range` header handling in `res.sendFile`/`res.sendfile`
|
||||
* deps: accepts@~1.3.3
|
||||
- Fix including type extensions in parameters in `Accept` parsing
|
||||
- Fix parsing `Accept` parameters with quoted equals
|
||||
- Fix parsing `Accept` parameters with quoted semicolons
|
||||
- Many performance improvements
|
||||
- deps: mime-types@~2.1.11
|
||||
- deps: negotiator@0.6.1
|
||||
* deps: content-type@~1.0.2
|
||||
- perf: enable strict mode
|
||||
* deps: cookie@0.3.1
|
||||
- Add `sameSite` option
|
||||
- Fix cookie `Max-Age` to never be a floating point number
|
||||
- Improve error message when `encode` is not a function
|
||||
- Improve error message when `expires` is not a `Date`
|
||||
- Throw better error for invalid argument to parse
|
||||
- Throw on invalid values provided to `serialize`
|
||||
- perf: enable strict mode
|
||||
- perf: hoist regular expression
|
||||
- perf: use for loop in parse
|
||||
- perf: use string concatenation for serialization
|
||||
* deps: finalhandler@0.5.0
|
||||
- Change invalid or non-numeric status code to 500
|
||||
- Overwrite status message to match set status code
|
||||
- Prefer `err.statusCode` if `err.status` is invalid
|
||||
- Set response headers from `err.headers` object
|
||||
- Use `statuses` instead of `http` module for status messages
|
||||
* deps: proxy-addr@~1.1.2
|
||||
- Fix accepting various invalid netmasks
|
||||
- Fix IPv6-mapped IPv4 validation edge cases
|
||||
- IPv4 netmasks must be contiguous
|
||||
- IPv6 addresses cannot be used as a netmask
|
||||
- deps: ipaddr.js@1.1.1
|
||||
* deps: qs@6.2.0
|
||||
- Add `decoder` option in `parse` function
|
||||
* deps: range-parser@~1.2.0
|
||||
- Add `combine` option to combine overlapping ranges
|
||||
- Fix incorrectly returning -1 when there is at least one valid range
|
||||
- perf: remove internal function
|
||||
* deps: send@0.14.1
|
||||
- Add `acceptRanges` option
|
||||
- Add `cacheControl` option
|
||||
- Attempt to combine multiple ranges into single range
|
||||
- Correctly inherit from `Stream` class
|
||||
- Fix `Content-Range` header in 416 responses when using `start`/`end` options
|
||||
- Fix `Content-Range` header missing from default 416 responses
|
||||
- Fix redirect error when `path` contains raw non-URL characters
|
||||
- Fix redirect when `path` starts with multiple forward slashes
|
||||
- Ignore non-byte `Range` headers
|
||||
- deps: http-errors@~1.5.0
|
||||
- deps: range-parser@~1.2.0
|
||||
- deps: statuses@~1.3.0
|
||||
- perf: remove argument reassignment
|
||||
* deps: serve-static@~1.11.1
|
||||
- Add `acceptRanges` option
|
||||
- Add `cacheControl` option
|
||||
- Attempt to combine multiple ranges into single range
|
||||
- Fix redirect error when `req.url` contains raw non-URL characters
|
||||
- Ignore non-byte `Range` headers
|
||||
- Use status code 301 for redirects
|
||||
- deps: send@0.14.1
|
||||
* deps: type-is@~1.6.13
|
||||
- Fix type error when given invalid type to match against
|
||||
- deps: mime-types@~2.1.11
|
||||
* deps: vary@~1.1.0
|
||||
- Only accept valid field names in the `field` argument
|
||||
* perf: use strict equality when possible
|
||||
|
||||
4.13.4 / 2016-01-21
|
||||
===================
|
||||
|
||||
* deps: content-disposition@0.5.1
|
||||
- perf: enable strict mode
|
||||
* deps: cookie@0.1.5
|
||||
- Throw on invalid values provided to `serialize`
|
||||
* deps: depd@~1.1.0
|
||||
- Support web browser loading
|
||||
- perf: enable strict mode
|
||||
* deps: escape-html@~1.0.3
|
||||
- perf: enable strict mode
|
||||
- perf: optimize string replacement
|
||||
- perf: use faster string coercion
|
||||
* deps: finalhandler@0.4.1
|
||||
- deps: escape-html@~1.0.3
|
||||
* deps: merge-descriptors@1.0.1
|
||||
- perf: enable strict mode
|
||||
* deps: methods@~1.1.2
|
||||
- perf: enable strict mode
|
||||
* deps: parseurl@~1.3.1
|
||||
- perf: enable strict mode
|
||||
* deps: proxy-addr@~1.0.10
|
||||
- deps: ipaddr.js@1.0.5
|
||||
- perf: enable strict mode
|
||||
* deps: range-parser@~1.0.3
|
||||
- perf: enable strict mode
|
||||
* deps: send@0.13.1
|
||||
- deps: depd@~1.1.0
|
||||
- deps: destroy@~1.0.4
|
||||
- deps: escape-html@~1.0.3
|
||||
- deps: range-parser@~1.0.3
|
||||
* deps: serve-static@~1.10.2
|
||||
- deps: escape-html@~1.0.3
|
||||
- deps: parseurl@~1.3.0
|
||||
- deps: send@0.13.1
|
||||
|
||||
4.13.3 / 2015-08-02
|
||||
===================
|
||||
|
||||
* Fix infinite loop condition using `mergeParams: true`
|
||||
* Fix inner numeric indices incorrectly altering parent `req.params`
|
||||
|
||||
4.13.2 / 2015-07-31
|
||||
===================
|
||||
|
||||
@@ -695,13 +1505,13 @@
|
||||
- deps: negotiator@0.4.6
|
||||
* deps: debug@1.0.2
|
||||
* deps: send@0.4.3
|
||||
- Do not throw un-catchable error on file open race condition
|
||||
- Do not throw uncatchable error on file open race condition
|
||||
- Use `escape-html` for HTML escaping
|
||||
- deps: debug@1.0.2
|
||||
- deps: finished@1.2.2
|
||||
- deps: fresh@0.2.2
|
||||
* deps: serve-static@1.2.3
|
||||
- Do not throw un-catchable error on file open race condition
|
||||
- Do not throw uncatchable error on file open race condition
|
||||
- deps: send@0.4.3
|
||||
|
||||
4.4.2 / 2014-06-09
|
||||
@@ -1542,7 +2352,7 @@
|
||||
* deps: connect@2.21.0
|
||||
- deprecate `connect(middleware)` -- use `app.use(middleware)` instead
|
||||
- deprecate `connect.createServer()` -- use `connect()` instead
|
||||
- fix `res.setHeader()` patch to work with with get -> append -> set pattern
|
||||
- fix `res.setHeader()` patch to work with get -> append -> set pattern
|
||||
- deps: compression@~1.0.8
|
||||
- deps: errorhandler@~1.1.1
|
||||
- deps: express-session@~1.5.0
|
||||
@@ -1581,7 +2391,7 @@
|
||||
- deps: serve-static@1.2.3
|
||||
* deps: debug@1.0.2
|
||||
* deps: send@0.4.3
|
||||
- Do not throw un-catchable error on file open race condition
|
||||
- Do not throw uncatchable error on file open race condition
|
||||
- Use `escape-html` for HTML escaping
|
||||
- deps: debug@1.0.2
|
||||
- deps: finished@1.2.2
|
||||
@@ -2753,8 +3563,8 @@ Shaw]
|
||||
* Added node v0.1.97 compatibility
|
||||
* Added support for deleting cookies via Request#cookie('key', null)
|
||||
* Updated haml submodule
|
||||
* Fixed not-found page, now using using charset utf-8
|
||||
* Fixed show-exceptions page, now using using charset utf-8
|
||||
* Fixed not-found page, now using charset utf-8
|
||||
* Fixed show-exceptions page, now using charset utf-8
|
||||
* Fixed view support due to fs.readFile Buffers
|
||||
* Changed; mime.type() no longer accepts ".type" due to node extname() changes
|
||||
|
||||
@@ -2766,7 +3576,7 @@ Shaw]
|
||||
* Updated haml submodule
|
||||
* Changed ETag; removed inode, modified time only
|
||||
* Fixed LF to CRLF for setting multiple cookies
|
||||
* Fixed cookie complation; values are now urlencoded
|
||||
* Fixed cookie compilation; values are now urlencoded
|
||||
* Fixed cookies parsing; accepts quoted values and url escaped cookies
|
||||
|
||||
0.11.0 / 2010-05-06
|
||||
@@ -2789,7 +3599,7 @@ Shaw]
|
||||
==================
|
||||
|
||||
* Added charset support via Request#charset (automatically assigned to 'UTF-8' when respond()'s
|
||||
encoding is set to 'utf8' or 'utf-8'.
|
||||
encoding is set to 'utf8' or 'utf-8').
|
||||
* Added "encoding" option to Request#render(). Closes #299
|
||||
* Added "dump exceptions" setting, which is enabled by default.
|
||||
* Added simple ejs template engine support
|
||||
@@ -2828,7 +3638,7 @@ Shaw]
|
||||
* Added [haml.js](http://github.com/visionmedia/haml.js) submodule; removed haml-js
|
||||
* Added callback function support to Request#halt() as 3rd/4th arg
|
||||
* Added preprocessing of route param wildcards using param(). Closes #251
|
||||
* Added view partial support (with collections etc)
|
||||
* Added view partial support (with collections etc.)
|
||||
* Fixed bug preventing falsey params (such as ?page=0). Closes #286
|
||||
* Fixed setting of multiple cookies. Closes #199
|
||||
* Changed; view naming convention is now NAME.TYPE.ENGINE (for example page.html.haml)
|
||||
@@ -2961,7 +3771,7 @@ Shaw]
|
||||
|
||||
* Added "plot" format option for Profiler (for gnuplot processing)
|
||||
* Added request number to Profiler plugin
|
||||
* Fixed binary encoding for multi-part file uploads, was previously defaulting to UTF8
|
||||
* Fixed binary encoding for multipart file uploads, was previously defaulting to UTF8
|
||||
* Fixed issue with routes not firing when not files are present. Closes #184
|
||||
* Fixed process.Promise -> events.Promise
|
||||
|
||||
@@ -3007,7 +3817,7 @@ Shaw]
|
||||
* Updated sample chat app to show messages on load
|
||||
* Updated libxmljs parseString -> parseHtmlString
|
||||
* Fixed `make init` to work with older versions of git
|
||||
* Fixed specs can now run independent specs for those who cant build deps. Closes #127
|
||||
* Fixed specs can now run independent specs for those who can't build deps. Closes #127
|
||||
* Fixed issues introduced by the node url module changes. Closes 126.
|
||||
* Fixed two assertions failing due to Collection#keys() returning strings
|
||||
* Fixed faulty Collection#toArray() spec due to keys() returning strings
|
||||
|
||||
125
Readme-Guide.md
Normal file
125
Readme-Guide.md
Normal file
@@ -0,0 +1,125 @@
|
||||
# README guidelines
|
||||
|
||||
Every module in the expressjs, pillarjs, and jshttp organizations should have
|
||||
a README file named `README.md`. The purpose of the README is to:
|
||||
|
||||
- Explain the purpose of the module and how to use it.
|
||||
- Act as a landing page (both on GitHub and npmjs.com) for the module to help
|
||||
people find it via search. Middleware module READMEs are also incorporated
|
||||
into https://expressjs.com/en/resources/middleware.html.
|
||||
- Encourage community contributions and participation.
|
||||
|
||||
Use the [README template](https://github.com/expressjs/express/wiki/README-template)
|
||||
to quickly create a new README file.
|
||||
|
||||
## Top-level items
|
||||
|
||||
**Badges** (optional): At the very top (with no subheading), include any
|
||||
applicable badges, such as npm version/downloads, build status, test coverage,
|
||||
and so on. Badges should resolve properly (not display a broken image).
|
||||
|
||||
Possible badges include:
|
||||
- npm version: `[![NPM Version][npm-image]][npm-url]`
|
||||
- npm downloads: `[![NPM Downloads][downloads-image]][downloads-url]`
|
||||
- Build status: `[![Build Status][travis-image]][travis-url]`
|
||||
- Test coverage: `[![Test Coverage][coveralls-image]][coveralls-url]`
|
||||
- Tips: `[![Gratipay][gratipay-image]][gratipay-url]`
|
||||
|
||||
**Summary**: Following badges, provide a one- or two-sentence description of
|
||||
what the module does. This should be the same as the npmjs.org blurb (which
|
||||
comes from the description property of `package.json`). Since npm doesn't
|
||||
handle markdown for the blurb, avoid using markdown in the summary sentence.
|
||||
|
||||
**TOC** (Optional): For longer READMEs, provide a table of contents that has
|
||||
a relative link to each section. A tool such as
|
||||
[doctoc](https://www.npmjs.com/package/doctoc) makes it very easy to generate
|
||||
a TOC.
|
||||
|
||||
## Overview
|
||||
|
||||
Optionally, include a section of one or two paragraphs with more high-level
|
||||
information on what the module does, what problems it solves, why one would
|
||||
use it and how. Don't just repeat what's in the summary.
|
||||
|
||||
## Installation
|
||||
|
||||
Required. This section is typically just:
|
||||
|
||||
```sh
|
||||
$ npm install module-name
|
||||
```
|
||||
|
||||
But include any other steps or requirements.
|
||||
|
||||
NOTE: Use the `sh` code block to make the shell command display properly on
|
||||
the website.
|
||||
|
||||
## Basic use
|
||||
|
||||
- Provide a general description of how to use the module with code sample.
|
||||
Include any important caveats or restrictions.
|
||||
- Explain the most common use cases.
|
||||
- Optional: a simple "hello world" type example (where applicable). This
|
||||
example is in addition to the more comprehensive [example section](#examples)
|
||||
later.
|
||||
|
||||
## API
|
||||
|
||||
Provide complete API documentation.
|
||||
|
||||
Formatting conventions: Each function is listed in a 3rd-level heading (`###`),
|
||||
like this:
|
||||
|
||||
```
|
||||
### Function_name(arg, options [, optional_arg] ... )
|
||||
```
|
||||
|
||||
**Options objects**
|
||||
|
||||
For arguments that are objects (for example, options object), describe the
|
||||
properties in a table, as follows. This matches the formatting used in the
|
||||
[Express API docs](https://expressjs.com/en/4x/api.html).
|
||||
|
||||
|Property | Description | Type | Default|
|
||||
|----------|-----------|------------|-------------|
|
||||
|Name of the property in `monospace`. | Brief description | String, Number, Boolean, etc. | If applicable.|
|
||||
|
||||
If all the properties are required (i.e. there are no defaults), then you
|
||||
can omit the default column.
|
||||
|
||||
Instead of very lengthy descriptions, link out to subsequent paragraphs for
|
||||
more detailed explanation of specific cases (e.g. "When this property is set
|
||||
to 'foobar', xyz happens; see <link to following section >.)
|
||||
|
||||
If there are options properties that are themselves options, use additional
|
||||
tables. See [`trust proxy` and `etag` properties](https://expressjs.com/en/4x/api.html#app.settings.table).
|
||||
|
||||
## Examples
|
||||
|
||||
Every README should have at least one example; ideally more. For code samples,
|
||||
be sure to use the `js` code block, for proper display in the website, e.g.:
|
||||
|
||||
```js
|
||||
var csurf = require('csurf')
|
||||
...
|
||||
```
|
||||
|
||||
## Tests
|
||||
|
||||
What tests are included.
|
||||
|
||||
How to run them.
|
||||
|
||||
The convention for running tests is `npm test`. All our projects should follow
|
||||
this convention.
|
||||
|
||||
## Contributors
|
||||
|
||||
Names of module "owners" (lead developers) and other developers who have
|
||||
contributed.
|
||||
|
||||
## License
|
||||
|
||||
Link to the license, with a short description of what it is, e.g. "MIT" or
|
||||
whatever. Ideally, avoid putting the license text directly in the README; link
|
||||
to it instead.
|
||||
208
Readme.md
208
Readme.md
@@ -1,16 +1,33 @@
|
||||
[](http://expressjs.com/)
|
||||
|
||||
Fast, unopinionated, minimalist web framework for [node](http://nodejs.org).
|
||||
**Fast, unopinionated, minimalist web framework for [Node.js](http://nodejs.org).**
|
||||
|
||||
**This project has a [Code of Conduct][].**
|
||||
|
||||
## Table of contents
|
||||
|
||||
* [Installation](#Installation)
|
||||
* [Features](#Features)
|
||||
* [Docs & Community](#docs--community)
|
||||
* [Quick Start](#Quick-Start)
|
||||
* [Running Tests](#Running-Tests)
|
||||
* [Philosophy](#Philosophy)
|
||||
* [Examples](#Examples)
|
||||
* [Contributing to Express](#Contributing)
|
||||
* [TC (Technical Committee)](#tc-technical-committee)
|
||||
* [Triagers](#triagers)
|
||||
* [License](#license)
|
||||
|
||||
|
||||
[![NPM Version][npm-version-image]][npm-url]
|
||||
[![NPM Install Size][npm-install-size-image]][npm-install-size-url]
|
||||
[![NPM Downloads][npm-downloads-image]][npm-downloads-url]
|
||||
[![OpenSSF Scorecard Badge][ossf-scorecard-badge]][ossf-scorecard-visualizer]
|
||||
|
||||
[![NPM Version][npm-image]][npm-url]
|
||||
[![NPM Downloads][downloads-image]][downloads-url]
|
||||
[![Linux Build][travis-image]][travis-url]
|
||||
[![Windows Build][appveyor-image]][appveyor-url]
|
||||
[![Test Coverage][coveralls-image]][coveralls-url]
|
||||
|
||||
```js
|
||||
var express = require('express')
|
||||
var app = express()
|
||||
const express = require('express')
|
||||
const app = express()
|
||||
|
||||
app.get('/', function (req, res) {
|
||||
res.send('Hello World')
|
||||
@@ -21,10 +38,25 @@ app.listen(3000)
|
||||
|
||||
## Installation
|
||||
|
||||
```bash
|
||||
This is a [Node.js](https://nodejs.org/en/) module available through the
|
||||
[npm registry](https://www.npmjs.com/).
|
||||
|
||||
Before installing, [download and install Node.js](https://nodejs.org/en/download/).
|
||||
Node.js 0.10 or higher is required.
|
||||
|
||||
If this is a brand new project, make sure to create a `package.json` first with
|
||||
the [`npm init` command](https://docs.npmjs.com/creating-a-package-json-file).
|
||||
|
||||
Installation is done using the
|
||||
[`npm install` command](https://docs.npmjs.com/getting-started/installing-npm-packages-locally):
|
||||
|
||||
```console
|
||||
$ npm install express
|
||||
```
|
||||
|
||||
Follow [our installing guide](http://expressjs.com/en/starter/installing.html)
|
||||
for more information.
|
||||
|
||||
## Features
|
||||
|
||||
* Robust routing
|
||||
@@ -37,15 +69,14 @@ $ npm install express
|
||||
|
||||
## Docs & Community
|
||||
|
||||
* [Website and Documentation](http://expressjs.com/) - [[website repo](https://github.com/strongloop/expressjs.com)]
|
||||
* [#express](https://webchat.freenode.net/?channels=express) on freenode IRC
|
||||
* [Github Organization](https://github.com/expressjs) for Official Middleware & Modules
|
||||
* Visit the [Wiki](https://github.com/strongloop/express/wiki)
|
||||
* [Website and Documentation](http://expressjs.com/) - [[website repo](https://github.com/expressjs/expressjs.com)]
|
||||
* [#express](https://web.libera.chat/#express) on [Libera Chat](https://libera.chat) IRC
|
||||
* [GitHub Organization](https://github.com/expressjs) for Official Middleware & Modules
|
||||
* Visit the [Wiki](https://github.com/expressjs/express/wiki)
|
||||
* [Google Group](https://groups.google.com/group/express-js) for discussion
|
||||
* [Русскоязычная документация](http://jsman.ru/express/)
|
||||
* [한국어 문서](http://expressjs.kr) - [[website repo](https://github.com/Hanul/expressjs.kr)]
|
||||
* [Gitter](https://gitter.im/expressjs/express) for support and discussion
|
||||
|
||||
**PROTIP** Be sure to read [Migrating from 3.x to 4.x](https://github.com/strongloop/express/wiki/Migrating-from-3.x-to-4.x) as well as [New features in 4.x](https://github.com/strongloop/express/wiki/New-features-in-4.x).
|
||||
**PROTIP** Be sure to read [Migrating from 3.x to 4.x](https://github.com/expressjs/express/wiki/Migrating-from-3.x-to-4.x) as well as [New features in 4.x](https://github.com/expressjs/express/wiki/New-features-in-4.x).
|
||||
|
||||
## Quick Start
|
||||
|
||||
@@ -53,32 +84,34 @@ $ npm install express
|
||||
|
||||
Install the executable. The executable's major version will match Express's:
|
||||
|
||||
```bash
|
||||
```console
|
||||
$ npm install -g express-generator@4
|
||||
```
|
||||
|
||||
Create the app:
|
||||
|
||||
```bash
|
||||
```console
|
||||
$ express /tmp/foo && cd /tmp/foo
|
||||
```
|
||||
|
||||
Install dependencies:
|
||||
|
||||
```bash
|
||||
```console
|
||||
$ npm install
|
||||
```
|
||||
|
||||
Start the server:
|
||||
|
||||
```bash
|
||||
```console
|
||||
$ npm start
|
||||
```
|
||||
|
||||
View the website at: http://localhost:3000
|
||||
|
||||
## Philosophy
|
||||
|
||||
The Express philosophy is to provide small, robust tooling for HTTP servers, making
|
||||
it a great solution for single page applications, web sites, hybrids, or public
|
||||
it a great solution for single page applications, websites, hybrids, or public
|
||||
HTTP APIs.
|
||||
|
||||
Express does not force you to use any specific ORM or template engine. With support for over
|
||||
@@ -89,50 +122,139 @@ $ npm start
|
||||
|
||||
To view the examples, clone the Express repo and install the dependencies:
|
||||
|
||||
```bash
|
||||
$ git clone git://github.com/strongloop/express.git --depth 1
|
||||
```console
|
||||
$ git clone https://github.com/expressjs/express.git --depth 1
|
||||
$ cd express
|
||||
$ npm install
|
||||
```
|
||||
|
||||
Then run whichever example you want:
|
||||
|
||||
```bash
|
||||
```console
|
||||
$ node examples/content-negotiation
|
||||
```
|
||||
|
||||
## Tests
|
||||
## Contributing
|
||||
|
||||
To run the test suite, first install the dependencies, then run `npm test`:
|
||||
[![Linux Build][github-actions-ci-image]][github-actions-ci-url]
|
||||
[![Windows Build][appveyor-image]][appveyor-url]
|
||||
[![Test Coverage][coveralls-image]][coveralls-url]
|
||||
|
||||
```bash
|
||||
The Express.js project welcomes all constructive contributions. Contributions take many forms,
|
||||
from code for bug fixes and enhancements, to additions and fixes to documentation, additional
|
||||
tests, triaging incoming pull requests and issues, and more!
|
||||
|
||||
See the [Contributing Guide](Contributing.md) for more technical details on contributing.
|
||||
|
||||
### Security Issues
|
||||
|
||||
If you discover a security vulnerability in Express, please see [Security Policies and Procedures](Security.md).
|
||||
|
||||
### Running Tests
|
||||
|
||||
To run the test suite, first install the dependencies, then run `npm test`:
|
||||
|
||||
```console
|
||||
$ npm install
|
||||
$ npm test
|
||||
```
|
||||
|
||||
## People
|
||||
|
||||
The original author of Express is [TJ Holowaychuk](https://github.com/tj) [![TJ's Gratipay][gratipay-image-visionmedia]][gratipay-url-visionmedia]
|
||||
The original author of Express is [TJ Holowaychuk](https://github.com/tj)
|
||||
|
||||
The current lead maintainer is [Douglas Christopher Wilson](https://github.com/dougwilson) [![Doug's Gratipay][gratipay-image-dougwilson]][gratipay-url-dougwilson]
|
||||
[List of all contributors](https://github.com/expressjs/express/graphs/contributors)
|
||||
|
||||
### TC (Technical Committee)
|
||||
|
||||
* [UlisesGascon](https://github.com/UlisesGascon) - **Ulises Gascón** (he/him)
|
||||
* [jonchurch](https://github.com/jonchurch) - **Jon Church**
|
||||
* [wesleytodd](https://github.com/wesleytodd) - **Wes Todd**
|
||||
* [LinusU](https://github.com/LinusU) - **Linus Unnebäck**
|
||||
* [blakeembrey](https://github.com/blakeembrey) - **Blake Embrey**
|
||||
* [sheplu](https://github.com/sheplu) - **Jean Burellier**
|
||||
* [crandmck](https://github.com/crandmck) - **Rand McKinney**
|
||||
* [ctcpip](https://github.com/ctcpip) - **Chris de Almeida**
|
||||
|
||||
<details>
|
||||
<summary>TC emeriti members</summary>
|
||||
|
||||
#### TC emeriti members
|
||||
|
||||
* [dougwilson](https://github.com/dougwilson) - **Douglas Wilson**
|
||||
* [hacksparrow](https://github.com/hacksparrow) - **Hage Yaapa**
|
||||
* [jonathanong](https://github.com/jonathanong) - **jongleberry**
|
||||
* [niftylettuce](https://github.com/niftylettuce) - **niftylettuce**
|
||||
* [troygoode](https://github.com/troygoode) - **Troy Goode**
|
||||
</details>
|
||||
|
||||
|
||||
### Triagers
|
||||
|
||||
* [aravindvnair99](https://github.com/aravindvnair99) - **Aravind Nair**
|
||||
* [carpasse](https://github.com/carpasse) - **Carlos Serrano**
|
||||
* [CBID2](https://github.com/CBID2) - **Christine Belzie**
|
||||
* [enyoghasim](https://github.com/enyoghasim) - **David Enyoghasim**
|
||||
* [UlisesGascon](https://github.com/UlisesGascon) - **Ulises Gascón** (he/him)
|
||||
* [mertcanaltin](https://github.com/mertcanaltin) - **Mert Can Altin**
|
||||
* [0ss](https://github.com/0ss) - **Salah**
|
||||
* [import-brain](https://github.com/import-brain) - **Eric Cheng** (he/him)
|
||||
* [3imed-jaberi](https://github.com/3imed-jaberi) - **Imed Jaberi**
|
||||
* [dakshkhetan](https://github.com/dakshkhetan) - **Daksh Khetan** (he/him)
|
||||
* [lucasraziel](https://github.com/lucasraziel) - **Lucas Soares Do Rego**
|
||||
* [IamLizu](https://github.com/IamLizu) - **S M Mahmudul Hasan** (he/him)
|
||||
* [Sushmeet](https://github.com/Sushmeet) - **Sushmeet Sunger**
|
||||
|
||||
<details>
|
||||
<summary>Triagers emeriti members</summary>
|
||||
|
||||
#### Emeritus Triagers
|
||||
|
||||
* [AuggieH](https://github.com/AuggieH) - **Auggie Hudak**
|
||||
* [G-Rath](https://github.com/G-Rath) - **Gareth Jones**
|
||||
* [MohammadXroid](https://github.com/MohammadXroid) - **Mohammad Ayashi**
|
||||
* [NawafSwe](https://github.com/NawafSwe) - **Nawaf Alsharqi**
|
||||
* [NotMoni](https://github.com/NotMoni) - **Moni**
|
||||
* [VigneshMurugan](https://github.com/VigneshMurugan) - **Vignesh Murugan**
|
||||
* [davidmashe](https://github.com/davidmashe) - **David Ashe**
|
||||
* [digitaIfabric](https://github.com/digitaIfabric) - **David**
|
||||
* [e-l-i-s-e](https://github.com/e-l-i-s-e) - **Elise Bonner**
|
||||
* [fed135](https://github.com/fed135) - **Frederic Charette**
|
||||
* [firmanJS](https://github.com/firmanJS) - **Firman Abdul Hakim**
|
||||
* [getspooky](https://github.com/getspooky) - **Yasser Ameur**
|
||||
* [ghinks](https://github.com/ghinks) - **Glenn**
|
||||
* [ghousemohamed](https://github.com/ghousemohamed) - **Ghouse Mohamed**
|
||||
* [gireeshpunathil](https://github.com/gireeshpunathil) - **Gireesh Punathil**
|
||||
* [jake32321](https://github.com/jake32321) - **Jake Reed**
|
||||
* [jonchurch](https://github.com/jonchurch) - **Jon Church**
|
||||
* [lekanikotun](https://github.com/lekanikotun) - **Troy Goode**
|
||||
* [marsonya](https://github.com/marsonya) - **Lekan Ikotun**
|
||||
* [mastermatt](https://github.com/mastermatt) - **Matt R. Wilson**
|
||||
* [maxakuru](https://github.com/maxakuru) - **Max Edell**
|
||||
* [mlrawlings](https://github.com/mlrawlings) - **Michael Rawlings**
|
||||
* [rodion-arr](https://github.com/rodion-arr) - **Rodion Abdurakhimov**
|
||||
* [sheplu](https://github.com/sheplu) - **Jean Burellier**
|
||||
* [tarunyadav1](https://github.com/tarunyadav1) - **Tarun yadav**
|
||||
* [tunniclm](https://github.com/tunniclm) - **Mike Tunnicliffe**
|
||||
</details>
|
||||
|
||||
[List of all contributors](https://github.com/strongloop/express/graphs/contributors)
|
||||
|
||||
## License
|
||||
|
||||
[MIT](LICENSE)
|
||||
|
||||
[npm-image]: https://img.shields.io/npm/v/express.svg
|
||||
[npm-url]: https://npmjs.org/package/express
|
||||
[downloads-image]: https://img.shields.io/npm/dm/express.svg
|
||||
[downloads-url]: https://npmjs.org/package/express
|
||||
[travis-image]: https://img.shields.io/travis/strongloop/express/master.svg?label=linux
|
||||
[travis-url]: https://travis-ci.org/strongloop/express
|
||||
[appveyor-image]: https://img.shields.io/appveyor/ci/dougwilson/express/master.svg?label=windows
|
||||
[appveyor-image]: https://badgen.net/appveyor/ci/dougwilson/express/master?label=windows
|
||||
[appveyor-url]: https://ci.appveyor.com/project/dougwilson/express
|
||||
[coveralls-image]: https://img.shields.io/coveralls/strongloop/express/master.svg
|
||||
[coveralls-url]: https://coveralls.io/r/strongloop/express?branch=master
|
||||
[gratipay-image-visionmedia]: https://img.shields.io/gratipay/visionmedia.svg
|
||||
[gratipay-url-visionmedia]: https://gratipay.com/visionmedia/
|
||||
[gratipay-image-dougwilson]: https://img.shields.io/gratipay/dougwilson.svg
|
||||
[gratipay-url-dougwilson]: https://gratipay.com/dougwilson/
|
||||
[coveralls-image]: https://badgen.net/coveralls/c/github/expressjs/express/master
|
||||
[coveralls-url]: https://coveralls.io/r/expressjs/express?branch=master
|
||||
[github-actions-ci-image]: https://badgen.net/github/checks/expressjs/express/master?label=linux
|
||||
[github-actions-ci-url]: https://github.com/expressjs/express/actions/workflows/ci.yml
|
||||
[npm-downloads-image]: https://badgen.net/npm/dm/express
|
||||
[npm-downloads-url]: https://npmcharts.com/compare/express?minimal=true
|
||||
[npm-install-size-image]: https://badgen.net/packagephobia/install/express
|
||||
[npm-install-size-url]: https://packagephobia.com/result?p=express
|
||||
[npm-url]: https://npmjs.org/package/express
|
||||
[npm-version-image]: https://badgen.net/npm/v/express
|
||||
[ossf-scorecard-badge]: https://api.scorecard.dev/projects/github.com/expressjs/express/badge
|
||||
[ossf-scorecard-visualizer]: https://ossf.github.io/scorecard-visualizer/#/projects/github.com/expressjs/express
|
||||
[Code of Conduct]: https://github.com/expressjs/express/blob/master/Code-Of-Conduct.md
|
||||
|
||||
199
Release-Process.md
Normal file
199
Release-Process.md
Normal file
@@ -0,0 +1,199 @@
|
||||
# Express Release Process
|
||||
|
||||
This document contains the technical aspects of the Express release process. The
|
||||
intended audience is those who have been authorized by the Express Technical
|
||||
Committee (TC) to create, promote and sign official release builds for Express,
|
||||
as npm packages hosted on https://npmjs.com/package/express.
|
||||
|
||||
## Who can make releases?
|
||||
|
||||
Release authorization is given by the Express TC. Once authorized, an individual
|
||||
must have the following access permissions:
|
||||
|
||||
### 1. Github release access
|
||||
|
||||
The individual making the release will need to be a member of the
|
||||
expressjs/express team with Write permission level so they are able to tag the
|
||||
release commit and push changes to the expressjs/express repository
|
||||
(see Steps 4 and 5).
|
||||
|
||||
### 2. npmjs.com release access
|
||||
|
||||
The individual making the release will need to be made an owner on the
|
||||
`express` package on npmjs.com so they are able to publish the release
|
||||
(see Step 6).
|
||||
|
||||
## How to publish a release
|
||||
|
||||
Before publishing, the following preconditions should be met:
|
||||
|
||||
- A release proposal issue or tracking pull request (see "Proposal branch"
|
||||
below) will exist documenting:
|
||||
- the proposed changes
|
||||
- the type of release: patch, minor or major
|
||||
- the version number (according to semantic versioning - http://semver.org)
|
||||
- The proposed changes should be complete.
|
||||
|
||||
There are two main release flows: patch and non-patch.
|
||||
|
||||
The patch flow is for making **patch releases**. As per semantic versioning,
|
||||
patch releases are for simple changes, eg: typo fixes, patch dependency updates,
|
||||
and simple/low-risk bug fixes. Every other type of change is made via the
|
||||
non-patch flow.
|
||||
|
||||
### Branch terminology
|
||||
|
||||
"Master branch"
|
||||
|
||||
- There is a branch in git used for the current major version of Express, named
|
||||
`master`.
|
||||
- This branch contains the completed commits for the next patch release of the
|
||||
current major version.
|
||||
- Releases for the current major version are published from this branch.
|
||||
|
||||
"Version branch"
|
||||
|
||||
- For any given major version of Express (current, previous or next) there is
|
||||
a branch in git for that release named `<major-version>.x` (eg: `4.x`).
|
||||
- This branch points to the commit of the latest tag for the given major version.
|
||||
|
||||
"Release branch"
|
||||
|
||||
- For any given major version of Express, there is a branch used for publishing
|
||||
releases.
|
||||
- For the current major version of Express, the release branch is the
|
||||
"Master branch" named `master`.
|
||||
- For all other major versions of Express, the release branch is the
|
||||
"Version branch" named `<major-version>.x`.
|
||||
|
||||
"Proposal branch"
|
||||
|
||||
- A branch in git representing a proposed new release of Express. This can be a
|
||||
minor or major release, named `<major-version>.0` for a major release,
|
||||
`<major-version>.<minor-version>` for a minor release.
|
||||
- A tracking pull request should exist to document the proposed release,
|
||||
targeted at the appropriate release branch. Prior to opening the tracking
|
||||
pull request the content of the release may have be discussed in an issue.
|
||||
- This branch contains the commits accepted so far that implement the proposal
|
||||
in the tracking pull request.
|
||||
|
||||
### Pre-release Versions
|
||||
|
||||
Alpha and Beta releases are made from a proposal branch. The version number should be
|
||||
incremented to the next minor version with a `-beta` or `-alpha` suffix.
|
||||
For example, if the next beta release is `5.0.1`, the beta release would be `5.0.1-beta.0`.
|
||||
The pre-releases are unstable and not suitable for production use.
|
||||
|
||||
### Patch flow
|
||||
|
||||
In the patch flow, simple changes are committed to the release branch which
|
||||
acts as an ever-present branch for the next patch release of the associated
|
||||
major version of Express.
|
||||
|
||||
The release branch is usually kept in a state where it is ready to release.
|
||||
Releases are made when sufficient time or change has been made to warrant it.
|
||||
This is usually proposed and decided using a github issue.
|
||||
|
||||
### Non-patch flow
|
||||
|
||||
In the non-patch flow, changes are committed to a temporary proposal branch
|
||||
created specifically for that release proposal. The branch is based on the
|
||||
most recent release of the major version of Express that the release targets.
|
||||
|
||||
Releases are made when all the changes on a proposal branch are complete and
|
||||
approved. This is done by merging the proposal branch into the release branch
|
||||
(using a fast-forward merge), tagging it with the new version number and
|
||||
publishing the release package to npmjs.com.
|
||||
|
||||
### Flow
|
||||
|
||||
Below is a detailed description of the steps to publish a release.
|
||||
|
||||
#### Step 1. Check the release is ready to publish
|
||||
|
||||
Check any relevant information to ensure the release is ready, eg: any
|
||||
milestone, label, issue or tracking pull request for the release. The release
|
||||
is ready when all proposed code, tests and documentation updates are complete
|
||||
(either merged, closed or re-targeted to another release).
|
||||
|
||||
#### Step 2. (Non-patch flow only) Merge the proposal branch into the release branch
|
||||
|
||||
In the patch flow: skip this step.
|
||||
|
||||
In the non-patch flow:
|
||||
```sh
|
||||
$ git checkout <release-branch>
|
||||
$ git merge --ff-only <proposal-branch>
|
||||
```
|
||||
|
||||
<release-branch> - see "Release branch" of "Branches" above.
|
||||
<proposal-branch> - see "Proposal branch" of "Non-patch flow" above.
|
||||
|
||||
**NOTE:** You may need to rebase the proposal branch to allow a fast-forward
|
||||
merge. Using a fast-forward merge keeps the history clean as it does
|
||||
not introduce merge commits.
|
||||
|
||||
### Step 3. Update the History.md and package.json to the new version number
|
||||
|
||||
The changes so far for the release should already be documented under the
|
||||
"unreleased" section at the top of the History.md file, as per the usual
|
||||
development practice. Change "unreleased" to the new release version / date.
|
||||
Example diff fragment:
|
||||
|
||||
```diff
|
||||
-unreleased
|
||||
-==========
|
||||
+4.13.3 / 2015-08-02
|
||||
+===================
|
||||
```
|
||||
|
||||
The version property in the package.json should already contain the version of
|
||||
the previous release. Change it to the new release version.
|
||||
|
||||
Commit these changes together under a single commit with the message set to
|
||||
the new release version (eg: `4.13.3`):
|
||||
|
||||
```sh
|
||||
$ git checkout <release-branch>
|
||||
<..edit files..>
|
||||
$ git add History.md package.json
|
||||
$ git commit -m '<version-number>'
|
||||
```
|
||||
|
||||
### Step 4. Identify and tag the release commit with the new release version
|
||||
|
||||
Create a lightweight tag (rather than an annotated tag) named after the new
|
||||
release version (eg: `4.13.3`).
|
||||
|
||||
```sh
|
||||
$ git tag <version-number>
|
||||
```
|
||||
|
||||
### Step 5. Push the release branch changes and tag to github
|
||||
|
||||
The branch and tag should be pushed directly to the main repository
|
||||
(https://github.com/expressjs/express).
|
||||
|
||||
```sh
|
||||
$ git push origin <release-branch>
|
||||
$ git push origin <version-number>
|
||||
```
|
||||
|
||||
### Step 6. Publish to npmjs.com
|
||||
|
||||
Ensure your local working copy is completely clean (no extra or changed files).
|
||||
You can use `git status` for this purpose.
|
||||
|
||||
```sh
|
||||
$ npm login <npm-username>
|
||||
$ npm publish
|
||||
```
|
||||
|
||||
**NOTE:** The version number to publish will be picked up automatically from
|
||||
package.json.
|
||||
|
||||
### Step 7. Update documentation website
|
||||
|
||||
The documentation website https://expressjs.com/ documents the current release version in various places. For a new release:
|
||||
1. Change the value of `current_version` in https://github.com/expressjs/expressjs.com/blob/gh-pages/_data/express.yml to match the latest version number.
|
||||
2. Add a new section to the change log. For example, for a 4.x release, https://github.com/expressjs/expressjs.com/blob/gh-pages/en/changelog/4x.md,
|
||||
56
Security.md
Normal file
56
Security.md
Normal file
@@ -0,0 +1,56 @@
|
||||
# Security Policies and Procedures
|
||||
|
||||
This document outlines security procedures and general policies for the Express
|
||||
project.
|
||||
|
||||
* [Reporting a Bug](#reporting-a-bug)
|
||||
* [Disclosure Policy](#disclosure-policy)
|
||||
* [Comments on this Policy](#comments-on-this-policy)
|
||||
|
||||
## Reporting a Bug
|
||||
|
||||
The Express team and community take all security bugs in Express seriously.
|
||||
Thank you for improving the security of Express. We appreciate your efforts and
|
||||
responsible disclosure and will make every effort to acknowledge your
|
||||
contributions.
|
||||
|
||||
Report security bugs by emailing the lead maintainer in the Readme.md file.
|
||||
|
||||
To ensure the timely response to your report, please ensure that the entirety
|
||||
of the report is contained within the email body and not solely behind a web
|
||||
link or an attachment.
|
||||
|
||||
The lead maintainer will acknowledge your email within 48 hours, and will send a
|
||||
more detailed response within 48 hours indicating the next steps in handling
|
||||
your report. After the initial reply to your report, the security team will
|
||||
endeavor to keep you informed of the progress towards a fix and full
|
||||
announcement, and may ask for additional information or guidance.
|
||||
|
||||
Report security bugs in third-party modules to the person or team maintaining
|
||||
the module.
|
||||
|
||||
## Pre-release Versions
|
||||
|
||||
Alpha and Beta releases are unstable and **not suitable for production use**.
|
||||
Vulnerabilities found in pre-releases should be reported according to the [Reporting a Bug](#reporting-a-bug) section.
|
||||
Due to the unstable nature of the branch it is not guaranteed that any fixes will be released in the next pre-release.
|
||||
|
||||
## Disclosure Policy
|
||||
|
||||
When the security team receives a security bug report, they will assign it to a
|
||||
primary handler. This person will coordinate the fix and release process,
|
||||
involving the following steps:
|
||||
|
||||
* Confirm the problem and determine the affected versions.
|
||||
* Audit code to find any potential similar problems.
|
||||
* Prepare fixes for all releases still under maintenance. These fixes will be
|
||||
released as fast as possible to npm.
|
||||
|
||||
## The Express Threat Model
|
||||
|
||||
We are currently working on a new version of the security model, the most updated version can be found [here](https://github.com/expressjs/security-wg/blob/main/docs/ThreatModel.md)
|
||||
|
||||
## Comments on this Policy
|
||||
|
||||
If you have suggestions on how this process could be improved please submit a
|
||||
pull request.
|
||||
70
Triager-Guide.md
Normal file
70
Triager-Guide.md
Normal file
@@ -0,0 +1,70 @@
|
||||
# Express Triager Guide
|
||||
|
||||
## Issue Triage Process
|
||||
|
||||
When a new issue or pull request is opened the issue will be labeled with `needs triage`.
|
||||
If a triage team member is available they can help make sure all the required information
|
||||
is provided. Depending on the issue or PR there are several next labels they can add for further
|
||||
classification:
|
||||
|
||||
* `needs triage`: This can be kept if the triager is unsure which next steps to take
|
||||
* `awaiting more info`: If more info has been requested from the author, apply this label.
|
||||
* `bug`: Issues that present a reasonable conviction there is a reproducible bug.
|
||||
* `enhancement`: Issues that are found to be a reasonable candidate feature additions.
|
||||
|
||||
If the issue is a question or discussion, it should be moved to GitHub Discussions.
|
||||
|
||||
### Moving Discussions and Questions to GitHub Discussions
|
||||
|
||||
For issues labeled with `question` or `discuss`, it is recommended to move them to GitHub Discussions instead:
|
||||
|
||||
* **Questions**: User questions that do not appear to be bugs or enhancements should be moved to GitHub Discussions.
|
||||
* **Discussions**: Topics for discussion should be moved to GitHub Discussions. If the discussion leads to a new feature or bug identification, it can be moved back to Issues.
|
||||
|
||||
In all cases, issues may be closed by maintainers if they don't receive a timely response when
|
||||
further information is sought, or when additional questions are asked.
|
||||
|
||||
## Approaches and Best Practices for getting into triage contributions
|
||||
|
||||
Review the organization's [StatusBoard](https://expressjs.github.io/statusboard/),
|
||||
pay special attention to these columns: stars, watchers, open issues, and contributors.
|
||||
This gives you a general idea about the criticality and health of the repository.
|
||||
Pick a few projects based on that criteria, your interests, and skills (existing or aspiring).
|
||||
|
||||
Review the project's contribution guideline if present. In a nutshell,
|
||||
commit to the community's standards and values. Review the
|
||||
documentation, for most of the projects it is just the README.md, and
|
||||
make sure you understand the key APIs, semantics, configurations, and use cases.
|
||||
|
||||
It might be helpful to write your own test apps to re-affirm your
|
||||
understanding of the key functions. This may identify some gaps in
|
||||
documentation, record those as they might be good PR's to open.
|
||||
Skim through the issue backlog; identify low hanging issues and mostly new ones.
|
||||
From those, attempt to recreate issues based on the OP description and
|
||||
ask questions if required. No question is a bad question!
|
||||
|
||||
## Removal of Triage Role
|
||||
|
||||
There are a few cases where members can be removed as triagers:
|
||||
|
||||
- Breaking the CoC or project contributor guidelines
|
||||
- Abuse or misuse of the role as deemed by the TC
|
||||
- Lack of participation for more than 6 months
|
||||
|
||||
If any of these happen we will discuss as a part of the triage portion of the regular TC meetings.
|
||||
If you have questions feel free to reach out to any of the TC members.
|
||||
|
||||
## Other Helpful Hints:
|
||||
|
||||
- Everyone is welcome to attend the [Express Technical Committee Meetings](https://github.com/expressjs/discussions#expressjs-tc-meetings), and as a triager, it might help to get a better idea of what's happening with the project.
|
||||
- When exploring the module's functionality there are a few helpful steps:
|
||||
- Turn on `DEBUG=*` (see https://www.npmjs.com/package/debug) to get detailed log information
|
||||
- It is also a good idea to do live debugging to follow the control flow, try using `node --inspect`
|
||||
- It is a good idea to make at least one pass of reading through the entire source
|
||||
- When reviewing the list of open issues there are some common types and suggested actions:
|
||||
- New/unattended issues or simple questions: A good place to start
|
||||
- Hard bugs & ongoing discussions: always feel free to chime in and help
|
||||
- Issues that imply gaps in the documentation: open PRs with changes or help the user to do so
|
||||
- For recurring issues, it is helpful to create functional examples to demonstrate (publish as gists or a repo)
|
||||
- Review and identify the maintainers. If necessary, at-mention one or more of them if you are unsure what to do
|
||||
- Make sure all your interactions are professional, welcoming, and respectful to the parties involved.
|
||||
18
appveyor.yml
18
appveyor.yml
@@ -1,18 +0,0 @@
|
||||
environment:
|
||||
matrix:
|
||||
- nodejs_version: "0.10"
|
||||
- nodejs_version: "0.12"
|
||||
- nodejs_version: "1.0"
|
||||
- nodejs_version: "1.8"
|
||||
- nodejs_version: "2.0"
|
||||
- nodejs_version: "2.3"
|
||||
install:
|
||||
- ps: Install-Product node $env:nodejs_version
|
||||
- npm rm --save-dev connect-redis
|
||||
- npm install
|
||||
build: off
|
||||
test_script:
|
||||
- node --version
|
||||
- npm --version
|
||||
- npm run test-ci
|
||||
version: "{build}"
|
||||
@@ -1,13 +1,17 @@
|
||||
|
||||
all:
|
||||
@./run 1 middleware
|
||||
@./run 5 middleware
|
||||
@./run 10 middleware
|
||||
@./run 15 middleware
|
||||
@./run 20 middleware
|
||||
@./run 30 middleware
|
||||
@./run 50 middleware
|
||||
@./run 100 middleware
|
||||
@./run 1 middleware 50
|
||||
@./run 5 middleware 50
|
||||
@./run 10 middleware 50
|
||||
@./run 15 middleware 50
|
||||
@./run 20 middleware 50
|
||||
@./run 30 middleware 50
|
||||
@./run 50 middleware 50
|
||||
@./run 100 middleware 50
|
||||
@./run 10 middleware 100
|
||||
@./run 10 middleware 250
|
||||
@./run 10 middleware 500
|
||||
@./run 10 middleware 1000
|
||||
@echo
|
||||
|
||||
.PHONY: all
|
||||
|
||||
34
benchmarks/README.md
Normal file
34
benchmarks/README.md
Normal file
@@ -0,0 +1,34 @@
|
||||
# Express Benchmarks
|
||||
|
||||
## Installation
|
||||
|
||||
You will need to install [wrk](https://github.com/wg/wrk/blob/master/INSTALL) in order to run the benchmarks.
|
||||
|
||||
## Running
|
||||
|
||||
To run the benchmarks, first install the dependencies `npm i`, then run `make`
|
||||
|
||||
The output will look something like this:
|
||||
|
||||
```
|
||||
50 connections
|
||||
1 middleware
|
||||
7.15ms
|
||||
6784.01
|
||||
|
||||
[...redacted...]
|
||||
|
||||
1000 connections
|
||||
10 middleware
|
||||
139.21ms
|
||||
6155.19
|
||||
|
||||
```
|
||||
|
||||
### Tip: Include Node.js version in output
|
||||
|
||||
You can use `make && node -v` to include the node.js version in the output.
|
||||
|
||||
### Tip: Save the results to a file
|
||||
|
||||
You can use `make > results.log` to save the results to a file `results.log`.
|
||||
@@ -1,5 +1,4 @@
|
||||
|
||||
var http = require('http');
|
||||
var express = require('..');
|
||||
var app = express();
|
||||
|
||||
@@ -14,10 +13,8 @@ while (n--) {
|
||||
});
|
||||
}
|
||||
|
||||
var body = new Buffer('Hello World');
|
||||
|
||||
app.use(function(req, res, next){
|
||||
res.send(body);
|
||||
app.use(function(req, res){
|
||||
res.send('Hello World')
|
||||
});
|
||||
|
||||
app.listen(3333);
|
||||
|
||||
@@ -4,13 +4,15 @@ echo
|
||||
MW=$1 node $2 &
|
||||
pid=$!
|
||||
|
||||
echo " $3 connections"
|
||||
|
||||
sleep 2
|
||||
|
||||
wrk 'http://localhost:3333/?foo[bar]=baz' \
|
||||
-d 3 \
|
||||
-c 50 \
|
||||
-c $3 \
|
||||
-t 8 \
|
||||
| grep 'Requests/sec' \
|
||||
| awk '{ print " " $2 }'
|
||||
| grep 'Requests/sec\|Latency' \
|
||||
| awk '{ print " " $2 }'
|
||||
|
||||
kill $pid
|
||||
|
||||
29
examples/README.md
Normal file
29
examples/README.md
Normal file
@@ -0,0 +1,29 @@
|
||||
# Express examples
|
||||
|
||||
This page contains list of examples using Express.
|
||||
|
||||
- [auth](./auth) - Authentication with login and password
|
||||
- [content-negotiation](./content-negotiation) - HTTP content negotiation
|
||||
- [cookie-sessions](./cookie-sessions) - Working with cookie-based sessions
|
||||
- [cookies](./cookies) - Working with cookies
|
||||
- [downloads](./downloads) - Transferring files to client
|
||||
- [ejs](./ejs) - Working with Embedded JavaScript templating (ejs)
|
||||
- [error-pages](./error-pages) - Creating error pages
|
||||
- [error](./error) - Working with error middleware
|
||||
- [hello-world](./hello-world) - Simple request handler
|
||||
- [markdown](./markdown) - Markdown as template engine
|
||||
- [multi-router](./multi-router) - Working with multiple Express routers
|
||||
- [mvc](./mvc) - MVC-style controllers
|
||||
- [online](./online) - Tracking online user activity with `online` and `redis` packages
|
||||
- [params](./params) - Working with route parameters
|
||||
- [resource](./resource) - Multiple HTTP operations on the same resource
|
||||
- [route-map](./route-map) - Organizing routes using a map
|
||||
- [route-middleware](./route-middleware) - Working with route middleware
|
||||
- [route-separation](./route-separation) - Organizing routes per each resource
|
||||
- [search](./search) - Search API
|
||||
- [session](./session) - User sessions
|
||||
- [static-files](./static-files) - Serving static files
|
||||
- [vhost](./vhost) - Working with virtual hosts
|
||||
- [view-constructor](./view-constructor) - Rendering views dynamically
|
||||
- [view-locals](./view-locals) - Saving data in request object between middleware calls
|
||||
- [web-service](./web-service) - Simple API service
|
||||
@@ -1,10 +1,12 @@
|
||||
'use strict'
|
||||
|
||||
/**
|
||||
* Module dependencies.
|
||||
*/
|
||||
|
||||
var express = require('../..');
|
||||
var hash = require('./pass').hash;
|
||||
var bodyParser = require('body-parser');
|
||||
var hash = require('pbkdf2-password')()
|
||||
var path = require('path');
|
||||
var session = require('express-session');
|
||||
|
||||
var app = module.exports = express();
|
||||
@@ -12,11 +14,11 @@ var app = module.exports = express();
|
||||
// config
|
||||
|
||||
app.set('view engine', 'ejs');
|
||||
app.set('views', __dirname + '/views');
|
||||
app.set('views', path.join(__dirname, 'views'));
|
||||
|
||||
// middleware
|
||||
|
||||
app.use(bodyParser.urlencoded({ extended: false }));
|
||||
app.use(express.urlencoded())
|
||||
app.use(session({
|
||||
resave: false, // don't save session if unmodified
|
||||
saveUninitialized: false, // don't create session until something stored
|
||||
@@ -45,7 +47,7 @@ var users = {
|
||||
// when you create a user, generate a salt
|
||||
// and hash the password ('foobar' is the pass here)
|
||||
|
||||
hash('foobar', function(err, salt, hash){
|
||||
hash({ password: 'foobar' }, function (err, pass, salt, hash) {
|
||||
if (err) throw err;
|
||||
// store the salt & hash in the "db"
|
||||
users.tj.salt = salt;
|
||||
@@ -59,14 +61,14 @@ function authenticate(name, pass, fn) {
|
||||
if (!module.parent) console.log('authenticating %s:%s', name, pass);
|
||||
var user = users[name];
|
||||
// query the db for the given username
|
||||
if (!user) return fn(new Error('cannot find user'));
|
||||
if (!user) return fn(null, null)
|
||||
// apply the same algorithm to the POSTed password, applying
|
||||
// the hash against the pass / salt, if there is a match we
|
||||
// found the user
|
||||
hash(pass, user.salt, function(err, hash){
|
||||
hash({ password: pass, salt: user.salt }, function (err, pass, salt, hash) {
|
||||
if (err) return fn(err);
|
||||
if (hash == user.hash) return fn(null, user);
|
||||
fn(new Error('invalid password'));
|
||||
if (hash === user.hash) return fn(null, user)
|
||||
fn(null, null)
|
||||
});
|
||||
}
|
||||
|
||||
@@ -99,8 +101,10 @@ app.get('/login', function(req, res){
|
||||
res.render('login');
|
||||
});
|
||||
|
||||
app.post('/login', function(req, res){
|
||||
app.post('/login', function (req, res, next) {
|
||||
if (!req.body) return res.sendStatus(400)
|
||||
authenticate(req.body.username, req.body.password, function(err, user){
|
||||
if (err) return next(err)
|
||||
if (user) {
|
||||
// Regenerate session when signing in
|
||||
// to prevent fixation
|
||||
@@ -112,7 +116,7 @@ app.post('/login', function(req, res){
|
||||
req.session.success = 'Authenticated as ' + user.name
|
||||
+ ' click to <a href="/logout">logout</a>. '
|
||||
+ ' You may now access <a href="/restricted">/restricted</a>.';
|
||||
res.redirect('back');
|
||||
res.redirect(req.get('Referrer') || '/');
|
||||
});
|
||||
} else {
|
||||
req.session.error = 'Authentication failed, please check your '
|
||||
|
||||
@@ -1,48 +0,0 @@
|
||||
|
||||
// check out https://github.com/tj/node-pwd
|
||||
|
||||
/**
|
||||
* Module dependencies.
|
||||
*/
|
||||
|
||||
var crypto = require('crypto');
|
||||
|
||||
/**
|
||||
* Bytesize.
|
||||
*/
|
||||
|
||||
var len = 128;
|
||||
|
||||
/**
|
||||
* Iterations. ~300ms
|
||||
*/
|
||||
|
||||
var iterations = 12000;
|
||||
|
||||
/**
|
||||
* Hashes a password with optional `salt`, otherwise
|
||||
* generate a salt for `pass` and invoke `fn(err, salt, hash)`.
|
||||
*
|
||||
* @param {String} password to hash
|
||||
* @param {String} optional salt
|
||||
* @param {Function} callback
|
||||
* @api public
|
||||
*/
|
||||
|
||||
exports.hash = function (pwd, salt, fn) {
|
||||
if (3 == arguments.length) {
|
||||
crypto.pbkdf2(pwd, salt, iterations, len, function(err, hash){
|
||||
fn(err, hash.toString('base64'));
|
||||
});
|
||||
} else {
|
||||
fn = salt;
|
||||
crypto.randomBytes(len, function(err, salt){
|
||||
if (err) return fn(err);
|
||||
salt = salt.toString('base64');
|
||||
crypto.pbkdf2(pwd, salt, iterations, len, function(err, hash){
|
||||
if (err) return fn(err);
|
||||
fn(null, salt, hash.toString('base64'));
|
||||
});
|
||||
});
|
||||
}
|
||||
};
|
||||
@@ -1,6 +1,8 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width,initial-scale=1">
|
||||
<title><%= title %></title>
|
||||
<style>
|
||||
body {
|
||||
|
||||
@@ -1,22 +1,21 @@
|
||||
|
||||
<% var title = 'Authentication Example' %>
|
||||
<% include head %>
|
||||
<%- include('head', { title: 'Authentication Example' }) -%>
|
||||
|
||||
<h1>Login</h1>
|
||||
<%- message %>
|
||||
Try accessing <a href="/restricted">/restricted</a>, then authenticate with "tj" and "foobar".
|
||||
<form method="post" action="/login">
|
||||
<p>
|
||||
<label>Username:</label>
|
||||
<input type="text" name="username">
|
||||
<label for="username">Username:</label>
|
||||
<input type="text" name="username" id="username">
|
||||
</p>
|
||||
<p>
|
||||
<label>Password:</label>
|
||||
<input type="text" name="password">
|
||||
<label for="password">Password:</label>
|
||||
<input type="text" name="password" id="password">
|
||||
</p>
|
||||
<p>
|
||||
<input type="submit" value="Login">
|
||||
</p>
|
||||
</form>
|
||||
|
||||
<% include foot %>
|
||||
<%- include('foot') -%>
|
||||
|
||||
@@ -1,31 +0,0 @@
|
||||
/**
|
||||
* Module dependencies.
|
||||
*/
|
||||
|
||||
var express = require('../..');
|
||||
var logger = require('morgan');
|
||||
var app = express();
|
||||
|
||||
app.set('views', __dirname);
|
||||
app.set('view engine', 'jade');
|
||||
|
||||
var pets = [];
|
||||
|
||||
var n = 1000;
|
||||
while (n--) {
|
||||
pets.push({ name: 'Tobi', age: 2, species: 'ferret' });
|
||||
pets.push({ name: 'Loki', age: 1, species: 'ferret' });
|
||||
pets.push({ name: 'Jane', age: 6, species: 'ferret' });
|
||||
}
|
||||
|
||||
app.use(logger('dev'));
|
||||
|
||||
app.get('/', function(req, res){
|
||||
res.render('pets', { pets: pets });
|
||||
});
|
||||
|
||||
/* istanbul ignore next */
|
||||
if (!module.parent) {
|
||||
app.listen(3000);
|
||||
console.log('Express started on port 3000');
|
||||
}
|
||||
@@ -1,12 +0,0 @@
|
||||
style.
|
||||
body {
|
||||
padding: 50px;
|
||||
font: 16px "Helvetica Neue", Helvetica;
|
||||
}
|
||||
|
||||
table
|
||||
for pet in pets
|
||||
tr
|
||||
td= pet.name
|
||||
td= pet.age
|
||||
td= pet.species
|
||||
@@ -1,7 +1,9 @@
|
||||
'use strict'
|
||||
|
||||
var users = [];
|
||||
|
||||
users.push({ name: 'Tobi' });
|
||||
users.push({ name: 'Loki' });
|
||||
users.push({ name: 'Jane' });
|
||||
|
||||
module.exports = users;
|
||||
module.exports = users;
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
'use strict'
|
||||
|
||||
var express = require('../../');
|
||||
var app = module.exports = express();
|
||||
var users = require('./db');
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
'use strict'
|
||||
|
||||
var users = require('./db');
|
||||
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
'use strict'
|
||||
|
||||
/**
|
||||
* Module dependencies.
|
||||
*/
|
||||
@@ -11,14 +13,10 @@ var app = module.exports = express();
|
||||
app.use(cookieSession({ secret: 'manny is cool' }));
|
||||
|
||||
// do something with the session
|
||||
app.use(count);
|
||||
|
||||
// custom middleware
|
||||
function count(req, res) {
|
||||
req.session.count = req.session.count || 0;
|
||||
var n = req.session.count++;
|
||||
res.send('viewed ' + n + ' times\n');
|
||||
}
|
||||
app.get('/', function (req, res) {
|
||||
req.session.count = (req.session.count || 0) + 1
|
||||
res.send('viewed ' + req.session.count + ' times\n')
|
||||
})
|
||||
|
||||
/* istanbul ignore next */
|
||||
if (!module.parent) {
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
'use strict'
|
||||
|
||||
/**
|
||||
* Module dependencies.
|
||||
*/
|
||||
@@ -6,10 +8,9 @@ var express = require('../../');
|
||||
var app = module.exports = express();
|
||||
var logger = require('morgan');
|
||||
var cookieParser = require('cookie-parser');
|
||||
var bodyParser = require('body-parser');
|
||||
|
||||
// custom log format
|
||||
if ('test' != process.env.NODE_ENV) app.use(logger(':method :url'));
|
||||
if (process.env.NODE_ENV !== 'test') app.use(logger(':method :url'))
|
||||
|
||||
// parses request cookies, populating
|
||||
// req.cookies and req.signedCookies
|
||||
@@ -18,7 +19,7 @@ if ('test' != process.env.NODE_ENV) app.use(logger(':method :url'));
|
||||
app.use(cookieParser('my secret here'));
|
||||
|
||||
// parses x-www-form-urlencoded
|
||||
app.use(bodyParser.urlencoded({ extended: false }));
|
||||
app.use(express.urlencoded())
|
||||
|
||||
app.get('/', function(req, res){
|
||||
if (req.cookies.remember) {
|
||||
@@ -32,13 +33,17 @@ app.get('/', function(req, res){
|
||||
|
||||
app.get('/forget', function(req, res){
|
||||
res.clearCookie('remember');
|
||||
res.redirect('back');
|
||||
res.redirect(req.get('Referrer') || '/');
|
||||
});
|
||||
|
||||
app.post('/', function(req, res){
|
||||
var minute = 60000;
|
||||
if (req.body.remember) res.cookie('remember', 1, { maxAge: minute });
|
||||
res.redirect('back');
|
||||
|
||||
if (req.body && req.body.remember) {
|
||||
res.cookie('remember', 1, { maxAge: minute })
|
||||
}
|
||||
|
||||
res.redirect(req.get('Referrer') || '/');
|
||||
});
|
||||
|
||||
/* istanbul ignore next */
|
||||
|
||||
3
examples/downloads/files/notes/groceries.txt
Normal file
3
examples/downloads/files/notes/groceries.txt
Normal file
@@ -0,0 +1,3 @@
|
||||
* milk
|
||||
* eggs
|
||||
* bread
|
||||
@@ -1,27 +1,32 @@
|
||||
'use strict'
|
||||
|
||||
/**
|
||||
* Module dependencies.
|
||||
*/
|
||||
|
||||
var express = require('../../');
|
||||
var path = require('path');
|
||||
|
||||
var app = module.exports = express();
|
||||
|
||||
// path to where the files are stored on disk
|
||||
var FILES_DIR = path.join(__dirname, 'files')
|
||||
|
||||
app.get('/', function(req, res){
|
||||
res.send('<ul>'
|
||||
+ '<li>Download <a href="/files/amazing.txt">amazing.txt</a>.</li>'
|
||||
+ '<li>Download <a href="/files/missing.txt">missing.txt</a>.</li>'
|
||||
+ '<li>Download <a href="/files/CCTV大赛上海分赛区.txt">CCTV大赛上海分赛区.txt</a>.</li>'
|
||||
+ '</ul>');
|
||||
res.send('<ul>' +
|
||||
'<li>Download <a href="/files/notes/groceries.txt">notes/groceries.txt</a>.</li>' +
|
||||
'<li>Download <a href="/files/amazing.txt">amazing.txt</a>.</li>' +
|
||||
'<li>Download <a href="/files/missing.txt">missing.txt</a>.</li>' +
|
||||
'<li>Download <a href="/files/CCTV大赛上海分赛区.txt">CCTV大赛上海分赛区.txt</a>.</li>' +
|
||||
'</ul>')
|
||||
});
|
||||
|
||||
// /files/* is accessed via req.params[0]
|
||||
// but here we name it :file
|
||||
app.get('/files/:file(*)', function(req, res, next){
|
||||
var file = req.params.file;
|
||||
var path = __dirname + '/files/' + file;
|
||||
|
||||
res.download(path, function(err){
|
||||
app.get('/files/*file', function (req, res, next) {
|
||||
res.download(req.params.file.join('/'), { root: FILES_DIR }, function (err) {
|
||||
if (!err) return; // file sent
|
||||
if (err && err.status !== 404) return next(err); // non-404 error
|
||||
if (err.status !== 404) return next(err); // non-404 error
|
||||
// file for download not found
|
||||
res.statusCode = 404;
|
||||
res.send('Cant find that file, sorry!');
|
||||
|
||||
@@ -1,8 +1,11 @@
|
||||
'use strict'
|
||||
|
||||
/**
|
||||
* Module dependencies.
|
||||
*/
|
||||
|
||||
var express = require('../../');
|
||||
var path = require('path');
|
||||
|
||||
var app = module.exports = express();
|
||||
|
||||
@@ -21,7 +24,11 @@ app.engine('.html', require('ejs').__express);
|
||||
|
||||
// Optional since express defaults to CWD/views
|
||||
|
||||
app.set('views', __dirname + '/views');
|
||||
app.set('views', path.join(__dirname, 'views'));
|
||||
|
||||
// Path to our public directory
|
||||
|
||||
app.use(express.static(path.join(__dirname, 'public')));
|
||||
|
||||
// Without this you would need to
|
||||
// supply the extension to res.render()
|
||||
|
||||
4
examples/ejs/public/stylesheets/style.css
Normal file
4
examples/ejs/public/stylesheets/style.css
Normal file
@@ -0,0 +1,4 @@
|
||||
body {
|
||||
padding: 50px 80px;
|
||||
font: 14px "Helvetica Neue", "Lucida Grande", Arial, sans-serif;
|
||||
}
|
||||
@@ -2,12 +2,8 @@
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title> <%= title %> </title>
|
||||
<style type="text/css">
|
||||
body {
|
||||
padding: 50px;
|
||||
font: 13px Helvetica, Arial, sans-serif;
|
||||
}
|
||||
</style>
|
||||
<meta name="viewport" content="width=device-width,initial-scale=1">
|
||||
<title><%= title %></title>
|
||||
<link rel="stylesheet" href="/stylesheets/style.css">
|
||||
</head>
|
||||
<body>
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
<% include header.html %>
|
||||
<%- include('header.html') -%>
|
||||
|
||||
<h1>Users</h1>
|
||||
<ul id="users">
|
||||
@@ -7,4 +7,4 @@
|
||||
<% }) %>
|
||||
</ul>
|
||||
|
||||
<% include footer.html %>
|
||||
<%- include('footer.html') -%>
|
||||
|
||||
@@ -1,14 +1,17 @@
|
||||
'use strict'
|
||||
|
||||
/**
|
||||
* Module dependencies.
|
||||
*/
|
||||
|
||||
var express = require('../../');
|
||||
var path = require('path');
|
||||
var app = module.exports = express();
|
||||
var logger = require('morgan');
|
||||
var silent = 'test' == process.env.NODE_ENV;
|
||||
var silent = process.env.NODE_ENV === 'test'
|
||||
|
||||
// general config
|
||||
app.set('views', __dirname + '/views');
|
||||
app.set('views', path.join(__dirname, 'views'));
|
||||
app.set('view engine', 'ejs');
|
||||
|
||||
// our custom "verbose errors" setting
|
||||
@@ -18,7 +21,7 @@ app.enable('verbose errors');
|
||||
|
||||
// disable them in production
|
||||
// use $ NODE_ENV=production node examples/error-pages
|
||||
if ('production' == app.settings.env) app.disable('verbose errors');
|
||||
if (app.settings.env === 'production') app.disable('verbose errors')
|
||||
|
||||
silent || app.use(logger('dev'));
|
||||
|
||||
@@ -60,20 +63,17 @@ app.get('/500', function(req, res, next){
|
||||
app.use(function(req, res, next){
|
||||
res.status(404);
|
||||
|
||||
// respond with html page
|
||||
if (req.accepts('html')) {
|
||||
res.render('404', { url: req.url });
|
||||
return;
|
||||
}
|
||||
|
||||
// respond with json
|
||||
if (req.accepts('json')) {
|
||||
res.send({ error: 'Not found' });
|
||||
return;
|
||||
}
|
||||
|
||||
// default to plain-text. send()
|
||||
res.type('txt').send('Not found');
|
||||
res.format({
|
||||
html: function () {
|
||||
res.render('404', { url: req.url })
|
||||
},
|
||||
json: function () {
|
||||
res.json({ error: 'Not found' })
|
||||
},
|
||||
default: function () {
|
||||
res.type('txt').send('Not found')
|
||||
}
|
||||
})
|
||||
});
|
||||
|
||||
// error-handling middleware, take the same form
|
||||
|
||||
@@ -1,3 +1,3 @@
|
||||
<% include error_header %>
|
||||
<%- include('error_header') -%>
|
||||
<h2>Cannot find <%= url %></h2>
|
||||
<% include footer %>
|
||||
<%- include('footer') -%>
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
<% include error_header %>
|
||||
<%- include('error_header') -%>
|
||||
<h2>Error: <%= error.message %></h2>
|
||||
<% if (settings['verbose errors']) { %>
|
||||
<pre><%= error.stack %></pre>
|
||||
<% } else { %>
|
||||
<p>An error occurred!</p>
|
||||
<% } %>
|
||||
<% include footer %>
|
||||
<%- include('footer') -%>
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width,initial-scale=1">
|
||||
<title>Error</title>
|
||||
</head>
|
||||
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width,initial-scale=1">
|
||||
<title>Custom Pages Example</title>
|
||||
</head>
|
||||
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
'use strict'
|
||||
|
||||
/**
|
||||
* Module dependencies.
|
||||
*/
|
||||
@@ -5,7 +7,7 @@
|
||||
var express = require('../../');
|
||||
var logger = require('morgan');
|
||||
var app = module.exports = express();
|
||||
var test = app.get('env') == 'test';
|
||||
var test = app.get('env') === 'test'
|
||||
|
||||
if (!test) app.use(logger('dev'));
|
||||
|
||||
@@ -24,13 +26,16 @@ function error(err, req, res, next) {
|
||||
res.send('Internal Server Error');
|
||||
}
|
||||
|
||||
app.get('/', function(req, res){
|
||||
app.get('/', function () {
|
||||
// Caught and passed down to the errorHandler middleware
|
||||
throw new Error('something broke!');
|
||||
});
|
||||
|
||||
app.get('/next', function(req, res, next){
|
||||
// We can also pass exceptions to next()
|
||||
// The reason for process.nextTick() is to show that
|
||||
// next() can be called inside an async operation,
|
||||
// in real life it can be a DB read or HTTP request.
|
||||
process.nextTick(function(){
|
||||
next(new Error('oh no!'));
|
||||
});
|
||||
|
||||
@@ -1,64 +0,0 @@
|
||||
|
||||
var express = require('../..');
|
||||
var logger = require('morgan');
|
||||
var app = express();
|
||||
|
||||
app.set('view engine', 'jade');
|
||||
app.set('views', __dirname + '/views');
|
||||
|
||||
function User(name) {
|
||||
this.private = 'heyyyy';
|
||||
this.secret = 'something';
|
||||
this.name = name;
|
||||
this.id = 123;
|
||||
}
|
||||
|
||||
// You'll probably want to do
|
||||
// something like this so you
|
||||
// dont expose "secret" data.
|
||||
|
||||
User.prototype.toJSON = function(){
|
||||
return {
|
||||
id: this.id,
|
||||
name: this.name
|
||||
};
|
||||
};
|
||||
|
||||
app.use(logger('dev'));
|
||||
|
||||
// earlier on expose an object
|
||||
// that we can tack properties on.
|
||||
// all res.locals props are exposed
|
||||
// to the templates, so "expose" will
|
||||
// be present.
|
||||
|
||||
app.use(function(req, res, next){
|
||||
res.locals.expose = {};
|
||||
// you could alias this as req or res.expose
|
||||
// to make it shorter and less annoying
|
||||
next();
|
||||
});
|
||||
|
||||
// pretend we loaded a user
|
||||
|
||||
app.use(function(req, res, next){
|
||||
req.user = new User('Tobi');
|
||||
next();
|
||||
});
|
||||
|
||||
app.get('/', function(req, res){
|
||||
res.redirect('/user');
|
||||
});
|
||||
|
||||
app.get('/user', function(req, res){
|
||||
// we only want to expose the user
|
||||
// to the client for this route:
|
||||
res.locals.expose.user = req.user;
|
||||
res.render('page');
|
||||
});
|
||||
|
||||
/* istanbul ignore next */
|
||||
if (!module.parent) {
|
||||
app.listen(3000);
|
||||
console.log('Express started on port 3000');
|
||||
}
|
||||
@@ -1,14 +0,0 @@
|
||||
html
|
||||
head
|
||||
title Express
|
||||
script.
|
||||
// call this whatever you like,
|
||||
// or dump them into individual
|
||||
// props like "var user ="
|
||||
var data = !{JSON.stringify(expose)}
|
||||
body
|
||||
h1 Expose client data
|
||||
p The following was exposed to the client:
|
||||
pre
|
||||
script.
|
||||
document.write(JSON.stringify(data, null, 2))
|
||||
@@ -1,6 +1,8 @@
|
||||
'use strict'
|
||||
|
||||
var express = require('../../');
|
||||
|
||||
var app = express();
|
||||
var app = module.exports = express()
|
||||
|
||||
app.get('/', function(req, res){
|
||||
res.send('Hello World');
|
||||
|
||||
@@ -1,51 +0,0 @@
|
||||
/**
|
||||
* Module dependencies.
|
||||
*/
|
||||
|
||||
var express = require('../../lib/express');
|
||||
|
||||
// Path to our public directory
|
||||
|
||||
var pub = __dirname + '/public';
|
||||
|
||||
// setup middleware
|
||||
|
||||
var app = express();
|
||||
app.use(express.static(pub));
|
||||
|
||||
// Optional since express defaults to CWD/views
|
||||
|
||||
app.set('views', __dirname + '/views');
|
||||
|
||||
// Set our default template engine to "jade"
|
||||
// which prevents the need for extensions
|
||||
// (although you can still mix and match)
|
||||
app.set('view engine', 'jade');
|
||||
|
||||
function User(name, email) {
|
||||
this.name = name;
|
||||
this.email = email;
|
||||
}
|
||||
|
||||
// Dummy users
|
||||
var users = [
|
||||
new User('tj', 'tj@vision-media.ca')
|
||||
, new User('ciaran', 'ciaranj@gmail.com')
|
||||
, new User('aaron', 'aaron.heckmann+github@gmail.com')
|
||||
];
|
||||
|
||||
app.get('/', function(req, res){
|
||||
res.render('users', { users: users });
|
||||
});
|
||||
|
||||
// change this to a better error handler in your code
|
||||
// sending stacktrace to users in production is not good
|
||||
app.use(function(err, req, res, next) {
|
||||
res.send(err.stack);
|
||||
});
|
||||
|
||||
/* istanbul ignore next */
|
||||
if (!module.parent) {
|
||||
app.listen(3000);
|
||||
console.log('Express started on port 3000');
|
||||
}
|
||||
@@ -1,4 +0,0 @@
|
||||
body {
|
||||
padding: 50px 80px;
|
||||
font: 14px "Helvetica Nueue", "Lucida Grande", Arial, sans-serif;
|
||||
}
|
||||
@@ -1,3 +0,0 @@
|
||||
head
|
||||
title Jade Example
|
||||
link(rel="stylesheet", href="/stylesheets/style.css")
|
||||
@@ -1,5 +0,0 @@
|
||||
doctype html
|
||||
html
|
||||
include header
|
||||
body
|
||||
block content
|
||||
@@ -1,8 +0,0 @@
|
||||
|
||||
extends ../layout
|
||||
|
||||
block content
|
||||
h1 Users
|
||||
#users
|
||||
for user in users
|
||||
include user
|
||||
@@ -1,3 +0,0 @@
|
||||
.user
|
||||
h2= user.name
|
||||
.email= user.email
|
||||
@@ -1,10 +1,14 @@
|
||||
'use strict'
|
||||
|
||||
/**
|
||||
* Module dependencies.
|
||||
*/
|
||||
|
||||
var escapeHtml = require('escape-html');
|
||||
var express = require('../..');
|
||||
var fs = require('fs');
|
||||
var md = require('marked').parse;
|
||||
var marked = require('marked');
|
||||
var path = require('path');
|
||||
|
||||
var app = module.exports = express();
|
||||
|
||||
@@ -13,21 +17,16 @@ var app = module.exports = express();
|
||||
app.engine('md', function(path, options, fn){
|
||||
fs.readFile(path, 'utf8', function(err, str){
|
||||
if (err) return fn(err);
|
||||
try {
|
||||
var html = md(str);
|
||||
html = html.replace(/\{([^}]+)\}/g, function(_, name){
|
||||
return options[name] || '';
|
||||
});
|
||||
fn(null, html);
|
||||
} catch(err) {
|
||||
fn(err);
|
||||
}
|
||||
var html = marked.parse(str).replace(/\{([^}]+)\}/g, function(_, name){
|
||||
return escapeHtml(options[name] || '');
|
||||
});
|
||||
fn(null, html);
|
||||
});
|
||||
});
|
||||
|
||||
app.set('views', __dirname + '/views');
|
||||
app.set('views', path.join(__dirname, 'views'));
|
||||
|
||||
// make it the default so we dont need .md
|
||||
// make it the default, so we don't need .md
|
||||
app.set('view engine', 'md');
|
||||
|
||||
app.get('/', function(req, res){
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
'use strict'
|
||||
|
||||
var express = require('../../..');
|
||||
|
||||
var apiv1 = express.Router();
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
'use strict'
|
||||
|
||||
var express = require('../../..');
|
||||
|
||||
var apiv2 = express.Router();
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
'use strict'
|
||||
|
||||
var express = require('../..');
|
||||
|
||||
var app = module.exports = express();
|
||||
@@ -6,7 +8,7 @@ app.use('/api/v1', require('./controllers/api_v1'));
|
||||
app.use('/api/v2', require('./controllers/api_v2'));
|
||||
|
||||
app.get('/', function(req, res) {
|
||||
res.send('Hello form root route.');
|
||||
res.send('Hello from root route.')
|
||||
});
|
||||
|
||||
/* istanbul ignore next */
|
||||
|
||||
@@ -1,60 +0,0 @@
|
||||
/**
|
||||
* Module dependencies.
|
||||
*/
|
||||
|
||||
var express = require('../..');
|
||||
var multiparty = require('multiparty');
|
||||
var format = require('util').format;
|
||||
|
||||
var app = module.exports = express();
|
||||
|
||||
app.get('/', function(req, res){
|
||||
res.send('<form method="post" enctype="multipart/form-data">'
|
||||
+ '<p>Title: <input type="text" name="title" /></p>'
|
||||
+ '<p>Image: <input type="file" name="image" /></p>'
|
||||
+ '<p><input type="submit" value="Upload" /></p>'
|
||||
+ '</form>');
|
||||
});
|
||||
|
||||
app.post('/', function(req, res, next){
|
||||
// create a form to begin parsing
|
||||
var form = new multiparty.Form();
|
||||
var image;
|
||||
var title;
|
||||
|
||||
form.on('error', next);
|
||||
form.on('close', function(){
|
||||
res.send(format('\nuploaded %s (%d Kb) as %s'
|
||||
, image.filename
|
||||
, image.size / 1024 | 0
|
||||
, title));
|
||||
});
|
||||
|
||||
// listen on field event for title
|
||||
form.on('field', function(name, val){
|
||||
if (name !== 'title') return;
|
||||
title = val;
|
||||
});
|
||||
|
||||
// listen on part event for image file
|
||||
form.on('part', function(part){
|
||||
if (!part.filename) return;
|
||||
if (part.name !== 'image') return part.resume();
|
||||
image = {};
|
||||
image.filename = part.filename;
|
||||
image.size = 0;
|
||||
part.on('data', function(buf){
|
||||
image.size += buf.length;
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
// parse the form
|
||||
form.parse(req);
|
||||
});
|
||||
|
||||
/* istanbul ignore next */
|
||||
if (!module.parent) {
|
||||
app.listen(4000);
|
||||
console.log('Express started on port 4000');
|
||||
}
|
||||
@@ -1,3 +1,5 @@
|
||||
'use strict'
|
||||
|
||||
exports.index = function(req, res){
|
||||
res.redirect('/users');
|
||||
};
|
||||
};
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
'use strict'
|
||||
|
||||
/**
|
||||
* Module dependencies.
|
||||
*/
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width,initial-scale=1">
|
||||
<link rel="stylesheet" href="/style.css">
|
||||
<title>Edit <%= pet.name %></title>
|
||||
</head>
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width,initial-scale=1">
|
||||
<link rel="stylesheet" href="/style.css">
|
||||
<title><%= pet.name %></title>
|
||||
</head>
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
'use strict'
|
||||
|
||||
/**
|
||||
* Module dependencies.
|
||||
*/
|
||||
|
||||
@@ -1,9 +1,13 @@
|
||||
'use strict'
|
||||
|
||||
/**
|
||||
* Module dependencies.
|
||||
*/
|
||||
|
||||
var db = require('../../db');
|
||||
|
||||
exports.engine = 'hbs';
|
||||
|
||||
exports.before = function(req, res, next){
|
||||
var id = req.params.user_id;
|
||||
if (!id) return next();
|
||||
|
||||
27
examples/mvc/controllers/user/views/edit.hbs
Normal file
27
examples/mvc/controllers/user/views/edit.hbs
Normal file
@@ -0,0 +1,27 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width,initial-scale=1">
|
||||
<link rel="stylesheet" href="/style.css">
|
||||
<title>Edit {{user.name}}</title>
|
||||
</head>
|
||||
<body>
|
||||
<h1>{{user.name}}</h1>
|
||||
<form action="/user/{{user.id}}?_method=put" method="post">
|
||||
<label for="user[name]">Name:
|
||||
<input type="text" name="user[name]" value="{{user.name}}">
|
||||
</label>
|
||||
|
||||
<input type="submit" name="submit" value="Update">
|
||||
</form>
|
||||
|
||||
<form action="/user/{{user.id}}/pet" method="post">
|
||||
<label for="pet[name]">Pet:
|
||||
<input type="text" name="pet[name]" placeholder="Pet Name">
|
||||
</label>
|
||||
|
||||
<input type="submit" name="submit" value="Add">
|
||||
</form>
|
||||
</body>
|
||||
</html>
|
||||
@@ -1,11 +0,0 @@
|
||||
link(rel='stylesheet', href='/style.css')
|
||||
h1= user.name
|
||||
form(action='/user/#{user.id}?_method=put', method='post')
|
||||
label= 'Name: '
|
||||
input(type='text', name='user[name]', value='#{user.name}')
|
||||
input(type='submit', value='Update')
|
||||
|
||||
form(action='/user/#{user.id}/pet', method='post')
|
||||
label= 'Pet: '
|
||||
input(type='text', name='pet[name]', placeholder='Name')
|
||||
input(type='submit', value='Add')
|
||||
18
examples/mvc/controllers/user/views/list.hbs
Normal file
18
examples/mvc/controllers/user/views/list.hbs
Normal file
@@ -0,0 +1,18 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width,initial-scale=1">
|
||||
<link rel="stylesheet" href="/style.css">
|
||||
<title>Users</title>
|
||||
</head>
|
||||
<body>
|
||||
<h1>Users</h1>
|
||||
<p>Click a user below to view their pets.</p>
|
||||
<ul>
|
||||
{{#each users}}
|
||||
<li><a href="/user/{{id}}">{{name}}</a></li>
|
||||
{{/each}}
|
||||
</ul>
|
||||
</body>
|
||||
</html>
|
||||
@@ -1,7 +0,0 @@
|
||||
link(rel='stylesheet', href='/style.css')
|
||||
h1 Users
|
||||
p Click a user below to view their pets.
|
||||
ul
|
||||
each user in users
|
||||
li
|
||||
a(href='/user/#{user.id}')= user.name
|
||||
31
examples/mvc/controllers/user/views/show.hbs
Normal file
31
examples/mvc/controllers/user/views/show.hbs
Normal file
@@ -0,0 +1,31 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width,initial-scale=1">
|
||||
<link rel="stylesheet" href="/style.css">
|
||||
<title>{{user.name}}</title>
|
||||
</head>
|
||||
<body>
|
||||
<h1>{{user.name}} <a href="/user/{{user.id}}/edit">edit</a></h1>
|
||||
|
||||
{{#if hasMessages}}
|
||||
<ul>
|
||||
{{#each messages}}
|
||||
<li>{{this}}</li>
|
||||
{{/each}}
|
||||
</ul>
|
||||
{{/if}}
|
||||
|
||||
{{#if user.pets.length}}
|
||||
<p>View {{user.name}}'s pets:</p>
|
||||
<ul>
|
||||
{{#each user.pets}}
|
||||
<li><a href="/pet/{{id}}">{{name}}</a></li>
|
||||
{{/each}}
|
||||
</ul>
|
||||
{{else}}
|
||||
<p>No pets!</p>
|
||||
{{/if}}
|
||||
</body>
|
||||
</html>
|
||||
@@ -1,17 +0,0 @@
|
||||
link(rel='stylesheet', href='/style.css')
|
||||
h1= user.name + ' '
|
||||
a(href='/user/#{user.id}/edit') edit
|
||||
|
||||
if (hasMessages)
|
||||
ul#messages
|
||||
each msg in messages
|
||||
li= msg
|
||||
|
||||
if (user.pets.length)
|
||||
p View #{user.name}'s pets:
|
||||
ul
|
||||
each pet in user.pets
|
||||
li
|
||||
a(href='/pet/#{pet.id}')= pet.name
|
||||
else
|
||||
p No pets!
|
||||
@@ -1,3 +1,5 @@
|
||||
'use strict'
|
||||
|
||||
// faux database
|
||||
|
||||
var pets = exports.pets = [];
|
||||
@@ -11,4 +13,4 @@ var users = exports.users = [];
|
||||
|
||||
users.push({ name: 'TJ', pets: [pets[0], pets[1], pets[2]], id: 0 });
|
||||
users.push({ name: 'Guillermo', pets: [pets[3]], id: 1 });
|
||||
users.push({ name: 'Nathan', pets: [], id: 2 });
|
||||
users.push({ name: 'Nathan', pets: [], id: 2 });
|
||||
|
||||
@@ -1,23 +1,23 @@
|
||||
'use strict'
|
||||
|
||||
/**
|
||||
* Module dependencies.
|
||||
*/
|
||||
|
||||
var express = require('../..');
|
||||
var logger = require('morgan');
|
||||
var path = require('path');
|
||||
var session = require('express-session');
|
||||
var bodyParser = require('body-parser');
|
||||
var methodOverride = require('method-override');
|
||||
|
||||
var app = module.exports = express();
|
||||
|
||||
// settings
|
||||
|
||||
// set our default template engine to "jade"
|
||||
// which prevents the need for extensions
|
||||
app.set('view engine', 'jade');
|
||||
// set our default template engine to "ejs"
|
||||
// which prevents the need for using file extensions
|
||||
app.set('view engine', 'ejs');
|
||||
|
||||
// set views for error and 404 pages
|
||||
app.set('views', __dirname + '/views');
|
||||
app.set('views', path.join(__dirname, 'views'));
|
||||
|
||||
// define a custom res.message() method
|
||||
// which stores messages in the session
|
||||
@@ -34,7 +34,7 @@ app.response.message = function(msg){
|
||||
if (!module.parent) app.use(logger('dev'));
|
||||
|
||||
// serve static files
|
||||
app.use(express.static(__dirname + '/public'));
|
||||
app.use(express.static(path.join(__dirname, 'public')));
|
||||
|
||||
// session support
|
||||
app.use(session({
|
||||
@@ -44,7 +44,7 @@ app.use(session({
|
||||
}));
|
||||
|
||||
// parse request bodies (req.body)
|
||||
app.use(bodyParser.urlencoded({ extended: true }));
|
||||
app.use(express.urlencoded({ extended: true }))
|
||||
|
||||
// allow overriding methods in query (?_method=put)
|
||||
app.use(methodOverride('_method'));
|
||||
|
||||
@@ -1,25 +1,31 @@
|
||||
'use strict'
|
||||
|
||||
/**
|
||||
* Module dependencies.
|
||||
*/
|
||||
|
||||
var express = require('../../..');
|
||||
var fs = require('fs');
|
||||
var path = require('path');
|
||||
|
||||
module.exports = function(parent, options){
|
||||
var dir = path.join(__dirname, '..', 'controllers');
|
||||
var verbose = options.verbose;
|
||||
fs.readdirSync(__dirname + '/../controllers').forEach(function(name){
|
||||
fs.readdirSync(dir).forEach(function(name){
|
||||
var file = path.join(dir, name)
|
||||
if (!fs.statSync(file).isDirectory()) return;
|
||||
verbose && console.log('\n %s:', name);
|
||||
var obj = require('./../controllers/' + name);
|
||||
var obj = require(file);
|
||||
var name = obj.name || name;
|
||||
var prefix = obj.prefix || '';
|
||||
var app = express();
|
||||
var handler;
|
||||
var method;
|
||||
var path;
|
||||
var url;
|
||||
|
||||
// allow specifying the view engine
|
||||
if (obj.engine) app.set('view engine', obj.engine);
|
||||
app.set('views', __dirname + '/../controllers/' + name + '/views');
|
||||
app.set('views', path.join(__dirname, '..', 'controllers', name, 'views'));
|
||||
|
||||
// generate routes based
|
||||
// on the exported methods
|
||||
@@ -30,27 +36,27 @@ module.exports = function(parent, options){
|
||||
switch (key) {
|
||||
case 'show':
|
||||
method = 'get';
|
||||
path = '/' + name + '/:' + name + '_id';
|
||||
url = '/' + name + '/:' + name + '_id';
|
||||
break;
|
||||
case 'list':
|
||||
method = 'get';
|
||||
path = '/' + name + 's';
|
||||
url = '/' + name + 's';
|
||||
break;
|
||||
case 'edit':
|
||||
method = 'get';
|
||||
path = '/' + name + '/:' + name + '_id/edit';
|
||||
url = '/' + name + '/:' + name + '_id/edit';
|
||||
break;
|
||||
case 'update':
|
||||
method = 'put';
|
||||
path = '/' + name + '/:' + name + '_id';
|
||||
url = '/' + name + '/:' + name + '_id';
|
||||
break;
|
||||
case 'create':
|
||||
method = 'post';
|
||||
path = '/' + name;
|
||||
url = '/' + name;
|
||||
break;
|
||||
case 'index':
|
||||
method = 'get';
|
||||
path = '/';
|
||||
url = '/';
|
||||
break;
|
||||
default:
|
||||
/* istanbul ignore next */
|
||||
@@ -59,15 +65,15 @@ module.exports = function(parent, options){
|
||||
|
||||
// setup
|
||||
handler = obj[key];
|
||||
path = prefix + path;
|
||||
url = prefix + url;
|
||||
|
||||
// before middleware support
|
||||
if (obj.before) {
|
||||
app[method](path, obj.before, handler);
|
||||
verbose && console.log(' %s %s -> before -> %s', method.toUpperCase(), path, key);
|
||||
app[method](url, obj.before, handler);
|
||||
verbose && console.log(' %s %s -> before -> %s', method.toUpperCase(), url, key);
|
||||
} else {
|
||||
app[method](path, handler);
|
||||
verbose && console.log(' %s %s -> %s', method.toUpperCase(), path, key);
|
||||
app[method](url, handler);
|
||||
verbose && console.log(' %s %s -> %s', method.toUpperCase(), url, key);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
body {
|
||||
padding: 50px;
|
||||
font: 16px "Helvetica Neue", Helvetica, Arial;
|
||||
font: 16px "Helvetica Neue", Helvetica, Arial, sans-serif;
|
||||
}
|
||||
a {
|
||||
color: #107aff;
|
||||
|
||||
13
examples/mvc/views/404.ejs
Normal file
13
examples/mvc/views/404.ejs
Normal file
@@ -0,0 +1,13 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width,initial-scale=1">
|
||||
<title>Not Found</title>
|
||||
<link rel="stylesheet" href="/style.css">
|
||||
</head>
|
||||
<body>
|
||||
<h1>404: Not Found</h1>
|
||||
<p>Sorry we can't find <%= url %></p>
|
||||
</body>
|
||||
</html>
|
||||
@@ -1,3 +0,0 @@
|
||||
link(rel='stylesheet', href='/style.css')
|
||||
h1 404: Not Found
|
||||
p Sorry we can't find #{url}
|
||||
13
examples/mvc/views/5xx.ejs
Normal file
13
examples/mvc/views/5xx.ejs
Normal file
@@ -0,0 +1,13 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width,initial-scale=1">
|
||||
<title>Internal Server Error</title>
|
||||
<link rel="stylesheet" href="/style.css">
|
||||
</head>
|
||||
<body>
|
||||
<h1>500: Internal Server Error</h1>
|
||||
<p>Looks like something blew up!</p>
|
||||
</body>
|
||||
</html>
|
||||
@@ -1,3 +0,0 @@
|
||||
link(rel='stylesheet', href='/style.css')
|
||||
h1 500: Internal Server Error
|
||||
p Looks like something blew up!
|
||||
@@ -1,4 +1,9 @@
|
||||
// first:
|
||||
'use strict'
|
||||
|
||||
// install redis first:
|
||||
// https://redis.io/
|
||||
|
||||
// then:
|
||||
// $ npm install redis online
|
||||
// $ redis-server
|
||||
|
||||
|
||||
@@ -1,28 +1,23 @@
|
||||
'use strict'
|
||||
|
||||
/**
|
||||
* Module dependencies.
|
||||
*/
|
||||
|
||||
var createError = require('http-errors')
|
||||
var express = require('../../');
|
||||
var app = module.exports = express();
|
||||
|
||||
// Faux database
|
||||
|
||||
var users = [
|
||||
{ name: 'tj' }
|
||||
{ name: 'tj' }
|
||||
, { name: 'tobi' }
|
||||
, { name: 'loki' }
|
||||
, { name: 'jane' }
|
||||
, { name: 'bandit' }
|
||||
];
|
||||
|
||||
// Create HTTP error
|
||||
|
||||
function createError(status, message) {
|
||||
var err = new Error(message);
|
||||
err.status = status;
|
||||
return err;
|
||||
}
|
||||
|
||||
// Convert :to and :from to integers
|
||||
|
||||
app.param(['to', 'from'], function(req, res, next, num, name){
|
||||
@@ -56,7 +51,7 @@ app.get('/', function(req, res){
|
||||
* GET :user.
|
||||
*/
|
||||
|
||||
app.get('/user/:user', function(req, res, next){
|
||||
app.get('/user/:user', function (req, res) {
|
||||
res.send('user ' + req.user.name);
|
||||
});
|
||||
|
||||
@@ -64,11 +59,11 @@ app.get('/user/:user', function(req, res, next){
|
||||
* GET users :from - :to.
|
||||
*/
|
||||
|
||||
app.get('/users/:from-:to', function(req, res, next){
|
||||
app.get('/users/:from-:to', function (req, res) {
|
||||
var from = req.params.from;
|
||||
var to = req.params.to;
|
||||
var names = users.map(function(user){ return user.name; });
|
||||
res.send('users ' + names.slice(from, to).join(', '));
|
||||
res.send('users ' + names.slice(from, to + 1).join(', '));
|
||||
});
|
||||
|
||||
/* istanbul ignore next */
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
'use strict'
|
||||
|
||||
/**
|
||||
* Module dependencies.
|
||||
*/
|
||||
@@ -10,7 +12,7 @@ var app = module.exports = express();
|
||||
|
||||
app.resource = function(path, obj) {
|
||||
this.get(path, obj.index);
|
||||
this.get(path + '/:a..:b.:format?', function(req, res){
|
||||
this.get(path + '/:a..:b{.:format}', function(req, res){
|
||||
var a = parseInt(req.params.a, 10);
|
||||
var b = parseInt(req.params.b, 10);
|
||||
var format = req.params.format;
|
||||
@@ -26,7 +28,7 @@ app.resource = function(path, obj) {
|
||||
// Fake records
|
||||
|
||||
var users = [
|
||||
{ name: 'tj' }
|
||||
{ name: 'tj' }
|
||||
, { name: 'ciaran' }
|
||||
, { name: 'aaron' }
|
||||
, { name: 'guillermo' }
|
||||
@@ -75,7 +77,7 @@ app.resource('/users', User);
|
||||
|
||||
app.get('/', function(req, res){
|
||||
res.send([
|
||||
'<h1>Examples:</h1> <ul>'
|
||||
'<h1>Examples:</h1> <ul>'
|
||||
, '<li>GET /users</li>'
|
||||
, '<li>GET /users/1</li>'
|
||||
, '<li>GET /users/3</li>'
|
||||
|
||||
@@ -1,10 +1,13 @@
|
||||
'use strict'
|
||||
|
||||
/**
|
||||
* Module dependencies.
|
||||
*/
|
||||
|
||||
var escapeHtml = require('escape-html')
|
||||
var express = require('../../lib/express');
|
||||
|
||||
var verbose = process.env.NODE_ENV != 'test';
|
||||
var verbose = process.env.NODE_ENV !== 'test'
|
||||
|
||||
var app = module.exports = express();
|
||||
|
||||
@@ -31,7 +34,7 @@ var users = {
|
||||
},
|
||||
|
||||
get: function(req, res){
|
||||
res.send('user ' + req.params.uid);
|
||||
res.send('user ' + escapeHtml(req.params.uid))
|
||||
},
|
||||
|
||||
delete: function(req, res){
|
||||
@@ -41,11 +44,11 @@ var users = {
|
||||
|
||||
var pets = {
|
||||
list: function(req, res){
|
||||
res.send('user ' + req.params.uid + '\'s pets');
|
||||
res.send('user ' + escapeHtml(req.params.uid) + '\'s pets')
|
||||
},
|
||||
|
||||
delete: function(req, res){
|
||||
res.send('delete ' + req.params.uid + '\'s pet ' + req.params.pid);
|
||||
res.send('delete ' + escapeHtml(req.params.uid) + '\'s pet ' + escapeHtml(req.params.pid))
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
'use strict'
|
||||
|
||||
/**
|
||||
* Module dependencies.
|
||||
*/
|
||||
@@ -15,7 +17,7 @@ var app = express();
|
||||
|
||||
// Dummy users
|
||||
var users = [
|
||||
{ id: 0, name: 'tj', email: 'tj@vision-media.ca', role: 'member' }
|
||||
{ id: 0, name: 'tj', email: 'tj@vision-media.ca', role: 'member' }
|
||||
, { id: 1, name: 'ciaran', email: 'ciaranj@gmail.com', role: 'member' }
|
||||
, { id: 2, name: 'aaron', email: 'aaron.heckmann+github@gmail.com', role: 'admin' }
|
||||
];
|
||||
@@ -34,7 +36,7 @@ function loadUser(req, res, next) {
|
||||
function andRestrictToSelf(req, res, next) {
|
||||
// If our authenticated user is the user we are viewing
|
||||
// then everything is fine :)
|
||||
if (req.authenticatedUser.id == req.user.id) {
|
||||
if (req.authenticatedUser.id === req.user.id) {
|
||||
next();
|
||||
} else {
|
||||
// You may want to implement specific exceptions
|
||||
@@ -47,7 +49,7 @@ function andRestrictToSelf(req, res, next) {
|
||||
|
||||
function andRestrictTo(role) {
|
||||
return function(req, res, next) {
|
||||
if (req.authenticatedUser.role == role) {
|
||||
if (req.authenticatedUser.role === role) {
|
||||
next();
|
||||
} else {
|
||||
next(new Error('Unauthorized'));
|
||||
|
||||
@@ -1,12 +1,14 @@
|
||||
'use strict'
|
||||
|
||||
/**
|
||||
* Module dependencies.
|
||||
*/
|
||||
|
||||
var express = require('../..');
|
||||
var path = require('path');
|
||||
var app = express();
|
||||
var logger = require('morgan');
|
||||
var cookieParser = require('cookie-parser');
|
||||
var bodyParser = require('body-parser');
|
||||
var methodOverride = require('method-override');
|
||||
var site = require('./site');
|
||||
var post = require('./post');
|
||||
@@ -16,8 +18,8 @@ module.exports = app;
|
||||
|
||||
// Config
|
||||
|
||||
app.set('view engine', 'jade');
|
||||
app.set('views', __dirname + '/views');
|
||||
app.set('view engine', 'ejs');
|
||||
app.set('views', path.join(__dirname, 'views'));
|
||||
|
||||
/* istanbul ignore next */
|
||||
if (!module.parent) {
|
||||
@@ -26,8 +28,8 @@ if (!module.parent) {
|
||||
|
||||
app.use(methodOverride('_method'));
|
||||
app.use(cookieParser());
|
||||
app.use(bodyParser.urlencoded({ extended: true }));
|
||||
app.use(express.static(__dirname + '/public'));
|
||||
app.use(express.urlencoded({ extended: true }))
|
||||
app.use(express.static(path.join(__dirname, 'public')));
|
||||
|
||||
// General
|
||||
|
||||
@@ -36,7 +38,7 @@ app.get('/', site.index);
|
||||
// User
|
||||
|
||||
app.get('/users', user.list);
|
||||
app.all('/user/:id/:op?', user.load);
|
||||
app.all('/user/:id{/:op}', user.load);
|
||||
app.get('/user/:id', user.view);
|
||||
app.get('/user/:id/view', user.view);
|
||||
app.get('/user/:id/edit', user.edit);
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
'use strict'
|
||||
|
||||
// Fake posts database
|
||||
|
||||
var posts = [
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
'use strict'
|
||||
|
||||
exports.index = function(req, res){
|
||||
res.render('index', { title: 'Route Separation Example' });
|
||||
};
|
||||
};
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
'use strict'
|
||||
|
||||
// Fake user database
|
||||
|
||||
var users = [
|
||||
@@ -41,5 +43,5 @@ exports.update = function(req, res){
|
||||
var user = req.body.user;
|
||||
req.user.name = user.name;
|
||||
req.user.email = user.email;
|
||||
res.redirect('back');
|
||||
res.redirect(req.get('Referrer') || '/');
|
||||
};
|
||||
|
||||
2
examples/route-separation/views/footer.ejs
Normal file
2
examples/route-separation/views/footer.ejs
Normal file
@@ -0,0 +1,2 @@
|
||||
</body>
|
||||
</html>
|
||||
9
examples/route-separation/views/header.ejs
Normal file
9
examples/route-separation/views/header.ejs
Normal file
@@ -0,0 +1,9 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width,initial-scale=1">
|
||||
<title><%= title %></title>
|
||||
<link rel="stylesheet" href="/style.css">
|
||||
</head>
|
||||
<body>
|
||||
10
examples/route-separation/views/index.ejs
Normal file
10
examples/route-separation/views/index.ejs
Normal file
@@ -0,0 +1,10 @@
|
||||
<%- include('header') -%>
|
||||
|
||||
<h1><%= title %></h1>
|
||||
|
||||
<ul>
|
||||
<li>Visit the <a href="/users">users</a> page.</li>
|
||||
<li>Visit the <a href="/posts">posts</a> page.</li>
|
||||
</ul>
|
||||
|
||||
<%- include('footer') -%>
|
||||
@@ -1,6 +0,0 @@
|
||||
extends layout
|
||||
|
||||
block content
|
||||
ul
|
||||
li Visit the <a href="/users">users</a> page
|
||||
li Visit the <a href="/posts">posts</a> page
|
||||
@@ -1,6 +0,0 @@
|
||||
html
|
||||
head
|
||||
title= title
|
||||
link(href="/style.css", rel="stylesheet")
|
||||
body
|
||||
block content
|
||||
12
examples/route-separation/views/posts/index.ejs
Normal file
12
examples/route-separation/views/posts/index.ejs
Normal file
@@ -0,0 +1,12 @@
|
||||
<%- include('../header') -%>
|
||||
|
||||
<h1>Posts</h1>
|
||||
|
||||
<dl id="posts">
|
||||
<% posts.forEach(function(post) { %>
|
||||
<dt><%= post.title %></dt>
|
||||
<dd><%= post.body %></dd>
|
||||
<% }) %>
|
||||
</dl>
|
||||
|
||||
<%- include('../footer') -%>
|
||||
@@ -1,8 +0,0 @@
|
||||
extends ../layout
|
||||
|
||||
block content
|
||||
h1 Posts
|
||||
dl#posts
|
||||
for post in posts
|
||||
dt= post.title
|
||||
dd= post.body
|
||||
23
examples/route-separation/views/users/edit.ejs
Normal file
23
examples/route-separation/views/users/edit.ejs
Normal file
@@ -0,0 +1,23 @@
|
||||
<%- include('../header') -%>
|
||||
|
||||
<h1>Editing <%= user.name %></h1>
|
||||
|
||||
<div id="user">
|
||||
<form action="?_method=put" method="post">
|
||||
<p>
|
||||
Name:
|
||||
<input type="text" value="<%= user.name %>" name="user[name]" />
|
||||
</p>
|
||||
|
||||
<p>
|
||||
Email:
|
||||
<input type="email" value="<%= user.email %>" name="user[email]" />
|
||||
</p>
|
||||
|
||||
<p>
|
||||
<input type="submit" value="Save" />
|
||||
</p>
|
||||
</form>
|
||||
</div>
|
||||
|
||||
<%- include('../footer') -%>
|
||||
@@ -1,12 +0,0 @@
|
||||
extends ../layout
|
||||
|
||||
block content
|
||||
h1 Editing #{user.name}
|
||||
#user
|
||||
form(action="?_method=put", method="post")
|
||||
p Name:
|
||||
input(type="text", value= user.name, name="user[name]")
|
||||
p Email:
|
||||
input(type="text", value= user.email, name="user[email]")
|
||||
p
|
||||
input(type="submit", value="Save")
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user