appstage 0.2.22 → 0.2.24
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.cjs +18 -10
- package/dist/index.d.ts +9 -0
- package/dist/index.mjs +18 -10
- package/package.json +1 -1
- package/src/controllers/files.ts +40 -36
- package/src/controllers/redirect.ts +10 -0
package/dist/index.cjs
CHANGED
|
@@ -79,7 +79,6 @@ function matches(x, matcher) {
|
|
|
79
79
|
}
|
|
80
80
|
const defaultExtensions = ["html", "htm"];
|
|
81
81
|
const defaultPath = (req) => req.path;
|
|
82
|
-
const defaultLanguages = getLanguageList;
|
|
83
82
|
/**
|
|
84
83
|
* Serves files from the specified directory path or paths in a locale-aware
|
|
85
84
|
* fashion after applying optional transforms.
|
|
@@ -91,6 +90,7 @@ const files = (params) => {
|
|
|
91
90
|
let fallthrough = p.fallthrough ?? true;
|
|
92
91
|
return async (req, res, next) => {
|
|
93
92
|
let urlPath = typeof p.path === "string" ? p.path : (p.path ?? defaultPath)(req);
|
|
93
|
+
let defaultLanguage = typeof p.defaultLanguage === "function" ? p.defaultLanguage(req) : p.defaultLanguage ?? "en";
|
|
94
94
|
if (!matches(urlPath, p.matches)) {
|
|
95
95
|
if (fallthrough) next();
|
|
96
96
|
else {
|
|
@@ -113,24 +113,24 @@ const files = (params) => {
|
|
|
113
113
|
}
|
|
114
114
|
return;
|
|
115
115
|
}
|
|
116
|
-
let langs = (p.languages ?? defaultLanguages)(req);
|
|
117
116
|
let filePath = null;
|
|
118
117
|
let urlExt = (0, node_path.extname)(urlPath);
|
|
118
|
+
let langs = (p.languages ?? getLanguageList)(req);
|
|
119
|
+
let defaultLanguageIndex = langs.indexOf(defaultLanguage);
|
|
120
|
+
let suffixes = langs.map((s) => `.${s}`);
|
|
121
|
+
if (defaultLanguageIndex === -1) suffixes.push("");
|
|
122
|
+
else suffixes.splice(defaultLanguageIndex + 1, 0, "");
|
|
119
123
|
for (let k = 0; k < bases.length && filePath === null; k++) {
|
|
120
124
|
let base = bases[k];
|
|
121
125
|
if (!urlPath.endsWith("/")) {
|
|
122
|
-
for (let i = 0; i <
|
|
126
|
+
for (let i = 0; i < suffixes.length && filePath === null; i++) filePath = await resolve(base, `${urlPath}${suffixes[i]}`);
|
|
123
127
|
if (filePath === null && urlExt) {
|
|
124
128
|
let urlPathBase = urlPath.slice(0, -urlExt.length);
|
|
125
|
-
for (let i = 0; i <
|
|
129
|
+
for (let i = 0; i < suffixes.length && filePath === null; i++) filePath = await resolve(base, `${urlPathBase}${suffixes[i]}${urlExt}`);
|
|
126
130
|
}
|
|
127
|
-
|
|
128
|
-
for (let i = 0; i < langs.length && filePath === null; i++) for (let j = 0; j < exts.length && filePath === null; j++) filePath = await resolve(base, `${urlPath}.${langs[i]}.${exts[j]}`);
|
|
129
|
-
for (let i = 0; i < exts.length && filePath === null; i++) filePath = await resolve(base, `${urlPath}.${exts[i]}`);
|
|
131
|
+
for (let i = 0; i < suffixes.length && filePath === null; i++) for (let j = 0; j < exts.length && filePath === null; j++) filePath = await resolve(base, `${urlPath}${suffixes[i]}.${exts[j]}`);
|
|
130
132
|
}
|
|
131
|
-
for (let i = 0; i <
|
|
132
|
-
for (let i = 0; i < langs.length && filePath === null; i++) for (let j = 0; j < exts.length && filePath === null; j++) filePath = await resolve(base, urlPath, `index.${langs[i]}.${exts[j]}`);
|
|
133
|
-
for (let i = 0; i < exts.length && filePath === null; i++) filePath = await resolve(base, urlPath, `index.${exts[i]}`);
|
|
133
|
+
for (let i = 0; i < suffixes.length && filePath === null; i++) for (let j = 0; j < exts.length && filePath === null; j++) filePath = await resolve(base, urlPath, `index${suffixes[i]}.${exts[j]}`);
|
|
134
134
|
}
|
|
135
135
|
if (filePath === null) {
|
|
136
136
|
if (fallthrough) next();
|
|
@@ -167,6 +167,14 @@ const redirect = (params) => {
|
|
|
167
167
|
return (req, res) => {
|
|
168
168
|
let search = req.originalUrl.split("?")[1] ?? "";
|
|
169
169
|
if (search) search = `${url.includes("?") ? "&" : "?"}${search}`;
|
|
170
|
+
emitLog(req.app, "Redirecting", {
|
|
171
|
+
data: {
|
|
172
|
+
from: req.originalUrl,
|
|
173
|
+
to: `${url}${search}`
|
|
174
|
+
},
|
|
175
|
+
req,
|
|
176
|
+
res
|
|
177
|
+
});
|
|
170
178
|
res.redirect(status, `${url}${search}`);
|
|
171
179
|
};
|
|
172
180
|
};
|
package/dist/index.d.ts
CHANGED
|
@@ -21,8 +21,17 @@ type FilesParams = {
|
|
|
21
21
|
base: string | string[];
|
|
22
22
|
path?: string | ((req: Request) => string); /** Specifies which paths should be accepted. */
|
|
23
23
|
matches?: StringMatcher;
|
|
24
|
+
/**
|
|
25
|
+
* @default ["html", "htm"]
|
|
26
|
+
*/
|
|
24
27
|
extensions?: string[];
|
|
25
28
|
languages?: (req: Request) => string[];
|
|
29
|
+
/**
|
|
30
|
+
* Assumed file language if unspecified in the file name.
|
|
31
|
+
*
|
|
32
|
+
* @default "en"
|
|
33
|
+
*/
|
|
34
|
+
defaultLanguage?: string | ((req: Request) => string);
|
|
26
35
|
transform?: TransformContent[];
|
|
27
36
|
fallthrough?: boolean;
|
|
28
37
|
};
|
package/dist/index.mjs
CHANGED
|
@@ -53,7 +53,6 @@ function matches(x, matcher) {
|
|
|
53
53
|
}
|
|
54
54
|
const defaultExtensions = ["html", "htm"];
|
|
55
55
|
const defaultPath = (req) => req.path;
|
|
56
|
-
const defaultLanguages = getLanguageList;
|
|
57
56
|
/**
|
|
58
57
|
* Serves files from the specified directory path or paths in a locale-aware
|
|
59
58
|
* fashion after applying optional transforms.
|
|
@@ -65,6 +64,7 @@ const files = (params) => {
|
|
|
65
64
|
let fallthrough = p.fallthrough ?? true;
|
|
66
65
|
return async (req, res, next) => {
|
|
67
66
|
let urlPath = typeof p.path === "string" ? p.path : (p.path ?? defaultPath)(req);
|
|
67
|
+
let defaultLanguage = typeof p.defaultLanguage === "function" ? p.defaultLanguage(req) : p.defaultLanguage ?? "en";
|
|
68
68
|
if (!matches(urlPath, p.matches)) {
|
|
69
69
|
if (fallthrough) next();
|
|
70
70
|
else {
|
|
@@ -87,24 +87,24 @@ const files = (params) => {
|
|
|
87
87
|
}
|
|
88
88
|
return;
|
|
89
89
|
}
|
|
90
|
-
let langs = (p.languages ?? defaultLanguages)(req);
|
|
91
90
|
let filePath = null;
|
|
92
91
|
let urlExt = extname(urlPath);
|
|
92
|
+
let langs = (p.languages ?? getLanguageList)(req);
|
|
93
|
+
let defaultLanguageIndex = langs.indexOf(defaultLanguage);
|
|
94
|
+
let suffixes = langs.map((s) => `.${s}`);
|
|
95
|
+
if (defaultLanguageIndex === -1) suffixes.push("");
|
|
96
|
+
else suffixes.splice(defaultLanguageIndex + 1, 0, "");
|
|
93
97
|
for (let k = 0; k < bases.length && filePath === null; k++) {
|
|
94
98
|
let base = bases[k];
|
|
95
99
|
if (!urlPath.endsWith("/")) {
|
|
96
|
-
for (let i = 0; i <
|
|
100
|
+
for (let i = 0; i < suffixes.length && filePath === null; i++) filePath = await resolve$1(base, `${urlPath}${suffixes[i]}`);
|
|
97
101
|
if (filePath === null && urlExt) {
|
|
98
102
|
let urlPathBase = urlPath.slice(0, -urlExt.length);
|
|
99
|
-
for (let i = 0; i <
|
|
103
|
+
for (let i = 0; i < suffixes.length && filePath === null; i++) filePath = await resolve$1(base, `${urlPathBase}${suffixes[i]}${urlExt}`);
|
|
100
104
|
}
|
|
101
|
-
|
|
102
|
-
for (let i = 0; i < langs.length && filePath === null; i++) for (let j = 0; j < exts.length && filePath === null; j++) filePath = await resolve$1(base, `${urlPath}.${langs[i]}.${exts[j]}`);
|
|
103
|
-
for (let i = 0; i < exts.length && filePath === null; i++) filePath = await resolve$1(base, `${urlPath}.${exts[i]}`);
|
|
105
|
+
for (let i = 0; i < suffixes.length && filePath === null; i++) for (let j = 0; j < exts.length && filePath === null; j++) filePath = await resolve$1(base, `${urlPath}${suffixes[i]}.${exts[j]}`);
|
|
104
106
|
}
|
|
105
|
-
for (let i = 0; i <
|
|
106
|
-
for (let i = 0; i < langs.length && filePath === null; i++) for (let j = 0; j < exts.length && filePath === null; j++) filePath = await resolve$1(base, urlPath, `index.${langs[i]}.${exts[j]}`);
|
|
107
|
-
for (let i = 0; i < exts.length && filePath === null; i++) filePath = await resolve$1(base, urlPath, `index.${exts[i]}`);
|
|
107
|
+
for (let i = 0; i < suffixes.length && filePath === null; i++) for (let j = 0; j < exts.length && filePath === null; j++) filePath = await resolve$1(base, urlPath, `index${suffixes[i]}.${exts[j]}`);
|
|
108
108
|
}
|
|
109
109
|
if (filePath === null) {
|
|
110
110
|
if (fallthrough) next();
|
|
@@ -141,6 +141,14 @@ const redirect = (params) => {
|
|
|
141
141
|
return (req, res) => {
|
|
142
142
|
let search = req.originalUrl.split("?")[1] ?? "";
|
|
143
143
|
if (search) search = `${url.includes("?") ? "&" : "?"}${search}`;
|
|
144
|
+
emitLog(req.app, "Redirecting", {
|
|
145
|
+
data: {
|
|
146
|
+
from: req.originalUrl,
|
|
147
|
+
to: `${url}${search}`
|
|
148
|
+
},
|
|
149
|
+
req,
|
|
150
|
+
res
|
|
151
|
+
});
|
|
144
152
|
res.redirect(status, `${url}${search}`);
|
|
145
153
|
};
|
|
146
154
|
};
|
package/package.json
CHANGED
package/src/controllers/files.ts
CHANGED
|
@@ -66,15 +66,23 @@ export type FilesParams = {
|
|
|
66
66
|
path?: string | ((req: Request) => string);
|
|
67
67
|
/** Specifies which paths should be accepted. */
|
|
68
68
|
matches?: StringMatcher;
|
|
69
|
+
/**
|
|
70
|
+
* @default ["html", "htm"]
|
|
71
|
+
*/
|
|
69
72
|
extensions?: string[];
|
|
70
73
|
languages?: (req: Request) => string[];
|
|
74
|
+
/**
|
|
75
|
+
* Assumed file language if unspecified in the file name.
|
|
76
|
+
*
|
|
77
|
+
* @default "en"
|
|
78
|
+
*/
|
|
79
|
+
defaultLanguage?: string | ((req: Request) => string);
|
|
71
80
|
transform?: TransformContent[];
|
|
72
81
|
fallthrough?: boolean;
|
|
73
82
|
};
|
|
74
83
|
|
|
75
84
|
const defaultExtensions = ["html", "htm"];
|
|
76
85
|
const defaultPath = (req: Request) => req.path;
|
|
77
|
-
const defaultLanguages = getLanguageList;
|
|
78
86
|
|
|
79
87
|
/**
|
|
80
88
|
* Serves files from the specified directory path or paths in a locale-aware
|
|
@@ -91,6 +99,11 @@ export const files: Controller<string | FilesParams> = (params) => {
|
|
|
91
99
|
let urlPath =
|
|
92
100
|
typeof p.path === "string" ? p.path : (p.path ?? defaultPath)(req);
|
|
93
101
|
|
|
102
|
+
let defaultLanguage =
|
|
103
|
+
typeof p.defaultLanguage === "function"
|
|
104
|
+
? p.defaultLanguage(req)
|
|
105
|
+
: (p.defaultLanguage ?? "en");
|
|
106
|
+
|
|
94
107
|
if (!matches(urlPath, p.matches)) {
|
|
95
108
|
if (fallthrough) next();
|
|
96
109
|
else {
|
|
@@ -125,67 +138,58 @@ export const files: Controller<string | FilesParams> = (params) => {
|
|
|
125
138
|
return;
|
|
126
139
|
}
|
|
127
140
|
|
|
128
|
-
let langs = (p.languages ?? defaultLanguages)(req);
|
|
129
141
|
let filePath: string | null = null;
|
|
130
142
|
let urlExt = extname(urlPath);
|
|
131
143
|
|
|
132
|
-
|
|
144
|
+
let langs = (p.languages ?? getLanguageList)(req);
|
|
145
|
+
let defaultLanguageIndex = langs.indexOf(defaultLanguage);
|
|
146
|
+
|
|
147
|
+
let suffixes = langs.map((s) => `.${s}`);
|
|
148
|
+
|
|
149
|
+
// Check the suffixless path right after the default language suffix.
|
|
150
|
+
if (defaultLanguageIndex === -1) suffixes.push("");
|
|
151
|
+
else suffixes.splice(defaultLanguageIndex + 1, 0, "");
|
|
152
|
+
|
|
153
|
+
// Example:
|
|
154
|
+
// path = /x, langs = [en, ru], default lang: en, exts = [html, htm]
|
|
133
155
|
for (let k = 0; k < bases.length && filePath === null; k++) {
|
|
134
156
|
let base = bases[k];
|
|
135
157
|
|
|
136
158
|
if (!urlPath.endsWith("/")) {
|
|
137
|
-
// /x.en /x.ru
|
|
138
|
-
for (let i = 0; i <
|
|
139
|
-
filePath = await resolve(base, `${urlPath}
|
|
159
|
+
// /x.en /x /x.ru
|
|
160
|
+
for (let i = 0; i < suffixes.length && filePath === null; i++)
|
|
161
|
+
filePath = await resolve(base, `${urlPath}${suffixes[i]}`);
|
|
140
162
|
|
|
141
163
|
if (filePath === null && urlExt) {
|
|
142
164
|
let urlPathBase = urlPath.slice(0, -urlExt.length);
|
|
143
165
|
|
|
144
|
-
// /x.en.ext /x.ru.ext
|
|
145
|
-
for (let i = 0; i <
|
|
166
|
+
// /x.en.ext /x.ext /x.ru.ext
|
|
167
|
+
for (let i = 0; i < suffixes.length && filePath === null; i++)
|
|
146
168
|
filePath = await resolve(
|
|
147
169
|
base,
|
|
148
|
-
`${urlPathBase}
|
|
170
|
+
`${urlPathBase}${suffixes[i]}${urlExt}`,
|
|
149
171
|
);
|
|
150
172
|
}
|
|
151
173
|
|
|
152
|
-
// /x
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
// /x.en.html /x.en.htm /x.ru.html /x.ru.htm
|
|
156
|
-
for (let i = 0; i < langs.length && filePath === null; i++) {
|
|
174
|
+
// /x.en.html /x.en.htm /x.html /x.htm /x.ru.html /x.ru.htm
|
|
175
|
+
for (let i = 0; i < suffixes.length && filePath === null; i++) {
|
|
157
176
|
for (let j = 0; j < exts.length && filePath === null; j++)
|
|
158
|
-
filePath = await resolve(
|
|
177
|
+
filePath = await resolve(
|
|
178
|
+
base,
|
|
179
|
+
`${urlPath}${suffixes[i]}.${exts[j]}`,
|
|
180
|
+
);
|
|
159
181
|
}
|
|
160
|
-
|
|
161
|
-
// /x.html /x.htm
|
|
162
|
-
for (let i = 0; i < exts.length && filePath === null; i++)
|
|
163
|
-
filePath = await resolve(base, `${urlPath}.${exts[i]}`);
|
|
164
|
-
}
|
|
165
|
-
|
|
166
|
-
// /x.en/index.html /x.en/index.htm /x.ru/index.html /x.ru/index.htm
|
|
167
|
-
for (let i = 0; i < langs.length && filePath === null; i++) {
|
|
168
|
-
for (let j = 0; j < exts.length && filePath === null; j++)
|
|
169
|
-
filePath = await resolve(
|
|
170
|
-
base,
|
|
171
|
-
`${urlPath}.${langs[i]}`,
|
|
172
|
-
`index.${exts[j]}`,
|
|
173
|
-
);
|
|
174
182
|
}
|
|
175
183
|
|
|
176
|
-
// /x/index.en.html /x/index.en.htm /x/index.ru.html /x/index.ru.htm
|
|
177
|
-
for (let i = 0; i <
|
|
184
|
+
// /x/index.en.html /x/index.en.htm /x/index.html /x/index.htm /x/index.ru.html /x/index.ru.htm
|
|
185
|
+
for (let i = 0; i < suffixes.length && filePath === null; i++) {
|
|
178
186
|
for (let j = 0; j < exts.length && filePath === null; j++)
|
|
179
187
|
filePath = await resolve(
|
|
180
188
|
base,
|
|
181
189
|
urlPath,
|
|
182
|
-
`index
|
|
190
|
+
`index${suffixes[i]}.${exts[j]}`,
|
|
183
191
|
);
|
|
184
192
|
}
|
|
185
|
-
|
|
186
|
-
// /x/index.html /x/index.htm
|
|
187
|
-
for (let i = 0; i < exts.length && filePath === null; i++)
|
|
188
|
-
filePath = await resolve(base, urlPath, `index.${exts[i]}`);
|
|
189
193
|
}
|
|
190
194
|
|
|
191
195
|
if (filePath === null) {
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import type { Controller } from "../types/Controller.ts";
|
|
2
|
+
import { emitLog } from "../utils/emitLog.ts";
|
|
2
3
|
|
|
3
4
|
export type RedirectParams = {
|
|
4
5
|
url: string;
|
|
@@ -14,6 +15,15 @@ export const redirect: Controller<string | RedirectParams> = (params) => {
|
|
|
14
15
|
|
|
15
16
|
if (search) search = `${url.includes("?") ? "&" : "?"}${search}`;
|
|
16
17
|
|
|
18
|
+
emitLog(req.app, "Redirecting", {
|
|
19
|
+
data: {
|
|
20
|
+
from: req.originalUrl,
|
|
21
|
+
to: `${url}${search}`,
|
|
22
|
+
},
|
|
23
|
+
req,
|
|
24
|
+
res,
|
|
25
|
+
});
|
|
26
|
+
|
|
17
27
|
res.redirect(status, `${url}${search}`);
|
|
18
28
|
};
|
|
19
29
|
};
|