nsp-server-pages 0.2.2 → 0.2.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/cjs/src/app.js +1 -1
- package/cjs/src/loaders.js +6 -6
- package/cjs/src/mount.js +2 -3
- package/cjs/src/parser/attr.js +1 -1
- package/cjs/src/parser/jsp.js +9 -2
- package/cjs/src/parser/scriptlet.js +1 -1
- package/cjs/src/parser/tag.js +1 -1
- package/cjs/src/parser/text.js +5 -1
- package/cjs/src/taglib.js +2 -3
- package/esm/src/app.js +1 -1
- package/esm/src/loaders.js +6 -6
- package/esm/src/parser/attr.js +1 -1
- package/esm/src/parser/jsp.js +9 -2
- package/esm/src/parser/scriptlet.js +1 -1
- package/esm/src/parser/tag.js +1 -1
- package/esm/src/parser/text.js +5 -1
- package/package.json +7 -6
- package/types/index.d.ts +1 -1
package/cjs/src/app.js
CHANGED
|
@@ -78,7 +78,7 @@ class App {
|
|
|
78
78
|
return loader.load(file);
|
|
79
79
|
}
|
|
80
80
|
store(context, key) {
|
|
81
|
-
if ("object" !== typeof context
|
|
81
|
+
if ("object" !== typeof context || context == null) {
|
|
82
82
|
throw new Error("Context must be an object");
|
|
83
83
|
}
|
|
84
84
|
const { storeKey } = this.options;
|
package/cjs/src/loaders.js
CHANGED
|
@@ -34,7 +34,7 @@ class JspLoader extends BaseLoader {
|
|
|
34
34
|
timeout: 1000,
|
|
35
35
|
})(async (path) => {
|
|
36
36
|
const app = this.appRef.deref();
|
|
37
|
-
app.log(`loading: ${path}`);
|
|
37
|
+
app.log(`loading JSP: ${path}`);
|
|
38
38
|
const text = await fs_1.promises.readFile(path, "utf8");
|
|
39
39
|
return app.parse(text).toFn();
|
|
40
40
|
});
|
|
@@ -64,7 +64,7 @@ class JsLoader extends BaseLoader {
|
|
|
64
64
|
timeout: 1000,
|
|
65
65
|
})(async (file) => {
|
|
66
66
|
const app = this.appRef.deref();
|
|
67
|
-
app.log(`loading: ${file}`);
|
|
67
|
+
app.log(`loading JS: ${file}`);
|
|
68
68
|
const module = await Promise.resolve(`${file}`).then(s => require(s));
|
|
69
69
|
const name = getName(file);
|
|
70
70
|
const fn = module[name];
|
|
@@ -80,8 +80,8 @@ class JsLoader extends BaseLoader {
|
|
|
80
80
|
}
|
|
81
81
|
async load(file) {
|
|
82
82
|
file = file?.replace(/\.jsp$/, ".js");
|
|
83
|
-
// valid only for .js files
|
|
84
|
-
if (!/\.
|
|
83
|
+
// valid only for .js-like files
|
|
84
|
+
if (!/\.(cjs|js|mjs|ts)$/.test(file))
|
|
85
85
|
return;
|
|
86
86
|
// skip when file does not exist
|
|
87
87
|
if (!await this.isFile(file))
|
|
@@ -110,8 +110,8 @@ class FileLoader extends BaseLoader {
|
|
|
110
110
|
});
|
|
111
111
|
}
|
|
112
112
|
async load(file) {
|
|
113
|
-
// disabled for JSP, JS and image files
|
|
114
|
-
if (/\.(jsp|
|
|
113
|
+
// disabled for JSP, JS, TS and image files
|
|
114
|
+
if (/\.(jsp|cjs|js|mjs|ts|png|gif|jpe?g|webp)$/i.test(file))
|
|
115
115
|
return;
|
|
116
116
|
// skip when file does not exist
|
|
117
117
|
if (!await this.isFile(file))
|
package/cjs/src/mount.js
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.
|
|
3
|
+
exports.mount = mount;
|
|
4
|
+
exports.load = load;
|
|
4
5
|
function mount(match, fn) {
|
|
5
6
|
const test = ("string" !== typeof match) ? match : {
|
|
6
7
|
test: ((path) => path.startsWith(match))
|
|
@@ -10,7 +11,6 @@ function mount(match, fn) {
|
|
|
10
11
|
return fn(path);
|
|
11
12
|
});
|
|
12
13
|
}
|
|
13
|
-
exports.mount = mount;
|
|
14
14
|
async function load(path) {
|
|
15
15
|
const { loaders } = this;
|
|
16
16
|
const search = path.replace(/^[^?]*\??/, "");
|
|
@@ -31,4 +31,3 @@ async function load(path) {
|
|
|
31
31
|
return fn(context);
|
|
32
32
|
};
|
|
33
33
|
}
|
|
34
|
-
exports.load = load;
|
package/cjs/src/parser/attr.js
CHANGED
|
@@ -58,10 +58,10 @@ class Attr {
|
|
|
58
58
|
const nextLF = LF + SP;
|
|
59
59
|
const keys = this.keys();
|
|
60
60
|
const items = keys.map(key => {
|
|
61
|
+
const value = this.get(key);
|
|
61
62
|
if (!isSafeKey(key)) {
|
|
62
63
|
key = JSON.stringify(key);
|
|
63
64
|
}
|
|
64
|
-
const value = this.get(key);
|
|
65
65
|
return `${key}: ${value}`;
|
|
66
66
|
});
|
|
67
67
|
// no arguments
|
package/cjs/src/parser/jsp.js
CHANGED
|
@@ -46,6 +46,7 @@ const jspToJS = (app, src, option) => {
|
|
|
46
46
|
const root = new tag_js_1.Tag(app);
|
|
47
47
|
const tree = new store_js_1.Store(root);
|
|
48
48
|
const array = src.split(tagRegExp);
|
|
49
|
+
const { vName } = app.options;
|
|
49
50
|
for (let i = 0; i < array.length; i++) {
|
|
50
51
|
const i3 = i % 3;
|
|
51
52
|
let str = array[i];
|
|
@@ -55,7 +56,7 @@ const jspToJS = (app, src, option) => {
|
|
|
55
56
|
// close-tag
|
|
56
57
|
if (tag.isClose()) {
|
|
57
58
|
const closed = tree.close();
|
|
58
|
-
if (!closed) {
|
|
59
|
+
if (!closed?.tagName) {
|
|
59
60
|
throw new Error(`invalid closing tag: </${tag.tagName}>`);
|
|
60
61
|
}
|
|
61
62
|
if (closed.tagName !== tag.tagName) {
|
|
@@ -72,7 +73,13 @@ const jspToJS = (app, src, option) => {
|
|
|
72
73
|
else if (i3 === 2 && str) {
|
|
73
74
|
// <% scriptlet %>
|
|
74
75
|
const item = new scriptlet_js_1.Scriptlet(app, str);
|
|
75
|
-
|
|
76
|
+
const toJS = (option) => {
|
|
77
|
+
const js = item.toJS(option);
|
|
78
|
+
if (/^\/\//.test(js))
|
|
79
|
+
return js; // comment
|
|
80
|
+
return `${vName} => ${js}`; // array function
|
|
81
|
+
};
|
|
82
|
+
tree.get().append({ toJS });
|
|
76
83
|
}
|
|
77
84
|
else if (i3 === 0) {
|
|
78
85
|
// text node
|
|
@@ -40,7 +40,7 @@ class Scriptlet {
|
|
|
40
40
|
}
|
|
41
41
|
app.log(`${type} found: ${src?.substring(0, 1000)}`);
|
|
42
42
|
src = /`|\$\{/.test(src) ? JSON.stringify(src) : "`" + src + "`";
|
|
43
|
-
src = `${
|
|
43
|
+
src = `${nspName}.process("${type}", ${src}, ${vName})`;
|
|
44
44
|
return src;
|
|
45
45
|
}
|
|
46
46
|
}
|
package/cjs/src/parser/tag.js
CHANGED
|
@@ -104,7 +104,7 @@ class Tag {
|
|
|
104
104
|
const nextLF = LF + SP;
|
|
105
105
|
const nextOption = { SP, LF: (body ? nextLF : LF) };
|
|
106
106
|
const type = `parse.tag.${tagName}`;
|
|
107
|
-
const def = { app, name: tagName, attr, body, LF
|
|
107
|
+
const def = { app, name: tagName, attr, body, LF, nextLF };
|
|
108
108
|
const tagJS = app.process(type, def) ?? this.getTagJS(def, nextOption);
|
|
109
109
|
return commentJS ? commentJS + tagJS : tagJS;
|
|
110
110
|
}
|
package/cjs/src/parser/text.js
CHANGED
|
@@ -52,7 +52,11 @@ const textToJS = (app, src, option) => {
|
|
|
52
52
|
value = value.replace(/\s*}$/s, "");
|
|
53
53
|
const item = new el_js_1.EL(app, value);
|
|
54
54
|
if (isAsync) {
|
|
55
|
-
|
|
55
|
+
const toJS = (option) => {
|
|
56
|
+
const js = item.toJS(option);
|
|
57
|
+
return `await ${js}`;
|
|
58
|
+
};
|
|
59
|
+
items.push({ toJS });
|
|
56
60
|
}
|
|
57
61
|
else {
|
|
58
62
|
items.push(item);
|
package/cjs/src/taglib.js
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.
|
|
3
|
+
exports.addTagLib = addTagLib;
|
|
4
|
+
exports.prepareTag = prepareTag;
|
|
4
5
|
const to_xml_1 = require("to-xml");
|
|
5
6
|
const isTagCon = (v) => ("function" === typeof v?.prototype?.render);
|
|
6
7
|
const tagConToTagFn = (Tag) => {
|
|
@@ -44,7 +45,6 @@ function addTagLib(tagLibDef) {
|
|
|
44
45
|
}
|
|
45
46
|
}
|
|
46
47
|
}
|
|
47
|
-
exports.addTagLib = addTagLib;
|
|
48
48
|
function prepareTag(name, attr, body) {
|
|
49
49
|
const { tagMap } = this;
|
|
50
50
|
const tagFn = tagMap.get(name) || defaultTagFn;
|
|
@@ -52,7 +52,6 @@ function prepareTag(name, attr, body) {
|
|
|
52
52
|
const tagDef = { name, app: this, attr: attrFn, body };
|
|
53
53
|
return tagFn(tagDef);
|
|
54
54
|
}
|
|
55
|
-
exports.prepareTag = prepareTag;
|
|
56
55
|
const defaultTagFn = (tagDef) => {
|
|
57
56
|
const { name } = tagDef;
|
|
58
57
|
// tagDef.app.log(`Unknown tag: ${name}`);
|
package/esm/src/app.js
CHANGED
|
@@ -75,7 +75,7 @@ export class App {
|
|
|
75
75
|
return loader.load(file);
|
|
76
76
|
}
|
|
77
77
|
store(context, key) {
|
|
78
|
-
if ("object" !== typeof context
|
|
78
|
+
if ("object" !== typeof context || context == null) {
|
|
79
79
|
throw new Error("Context must be an object");
|
|
80
80
|
}
|
|
81
81
|
const { storeKey } = this.options;
|
package/esm/src/loaders.js
CHANGED
|
@@ -31,7 +31,7 @@ export class JspLoader extends BaseLoader {
|
|
|
31
31
|
timeout: 1000,
|
|
32
32
|
})(async (path) => {
|
|
33
33
|
const app = this.appRef.deref();
|
|
34
|
-
app.log(`loading: ${path}`);
|
|
34
|
+
app.log(`loading JSP: ${path}`);
|
|
35
35
|
const text = await fs.readFile(path, "utf8");
|
|
36
36
|
return app.parse(text).toFn();
|
|
37
37
|
});
|
|
@@ -60,7 +60,7 @@ export class JsLoader extends BaseLoader {
|
|
|
60
60
|
timeout: 1000,
|
|
61
61
|
})(async (file) => {
|
|
62
62
|
const app = this.appRef.deref();
|
|
63
|
-
app.log(`loading: ${file}`);
|
|
63
|
+
app.log(`loading JS: ${file}`);
|
|
64
64
|
const module = await import(file);
|
|
65
65
|
const name = getName(file);
|
|
66
66
|
const fn = module[name];
|
|
@@ -76,8 +76,8 @@ export class JsLoader extends BaseLoader {
|
|
|
76
76
|
}
|
|
77
77
|
async load(file) {
|
|
78
78
|
file = file?.replace(/\.jsp$/, ".js");
|
|
79
|
-
// valid only for .js files
|
|
80
|
-
if (!/\.
|
|
79
|
+
// valid only for .js-like files
|
|
80
|
+
if (!/\.(cjs|js|mjs|ts)$/.test(file))
|
|
81
81
|
return;
|
|
82
82
|
// skip when file does not exist
|
|
83
83
|
if (!await this.isFile(file))
|
|
@@ -105,8 +105,8 @@ export class FileLoader extends BaseLoader {
|
|
|
105
105
|
});
|
|
106
106
|
}
|
|
107
107
|
async load(file) {
|
|
108
|
-
// disabled for JSP, JS and image files
|
|
109
|
-
if (/\.(jsp|
|
|
108
|
+
// disabled for JSP, JS, TS and image files
|
|
109
|
+
if (/\.(jsp|cjs|js|mjs|ts|png|gif|jpe?g|webp)$/i.test(file))
|
|
110
110
|
return;
|
|
111
111
|
// skip when file does not exist
|
|
112
112
|
if (!await this.isFile(file))
|
package/esm/src/parser/attr.js
CHANGED
|
@@ -55,10 +55,10 @@ export class Attr {
|
|
|
55
55
|
const nextLF = LF + SP;
|
|
56
56
|
const keys = this.keys();
|
|
57
57
|
const items = keys.map(key => {
|
|
58
|
+
const value = this.get(key);
|
|
58
59
|
if (!isSafeKey(key)) {
|
|
59
60
|
key = JSON.stringify(key);
|
|
60
61
|
}
|
|
61
|
-
const value = this.get(key);
|
|
62
62
|
return `${key}: ${value}`;
|
|
63
63
|
});
|
|
64
64
|
// no arguments
|
package/esm/src/parser/jsp.js
CHANGED
|
@@ -42,6 +42,7 @@ export const jspToJS = (app, src, option) => {
|
|
|
42
42
|
const root = new Tag(app);
|
|
43
43
|
const tree = new Store(root);
|
|
44
44
|
const array = src.split(tagRegExp);
|
|
45
|
+
const { vName } = app.options;
|
|
45
46
|
for (let i = 0; i < array.length; i++) {
|
|
46
47
|
const i3 = i % 3;
|
|
47
48
|
let str = array[i];
|
|
@@ -51,7 +52,7 @@ export const jspToJS = (app, src, option) => {
|
|
|
51
52
|
// close-tag
|
|
52
53
|
if (tag.isClose()) {
|
|
53
54
|
const closed = tree.close();
|
|
54
|
-
if (!closed) {
|
|
55
|
+
if (!closed?.tagName) {
|
|
55
56
|
throw new Error(`invalid closing tag: </${tag.tagName}>`);
|
|
56
57
|
}
|
|
57
58
|
if (closed.tagName !== tag.tagName) {
|
|
@@ -68,7 +69,13 @@ export const jspToJS = (app, src, option) => {
|
|
|
68
69
|
else if (i3 === 2 && str) {
|
|
69
70
|
// <% scriptlet %>
|
|
70
71
|
const item = new Scriptlet(app, str);
|
|
71
|
-
|
|
72
|
+
const toJS = (option) => {
|
|
73
|
+
const js = item.toJS(option);
|
|
74
|
+
if (/^\/\//.test(js))
|
|
75
|
+
return js; // comment
|
|
76
|
+
return `${vName} => ${js}`; // array function
|
|
77
|
+
};
|
|
78
|
+
tree.get().append({ toJS });
|
|
72
79
|
}
|
|
73
80
|
else if (i3 === 0) {
|
|
74
81
|
// text node
|
|
@@ -37,7 +37,7 @@ export class Scriptlet {
|
|
|
37
37
|
}
|
|
38
38
|
app.log(`${type} found: ${src?.substring(0, 1000)}`);
|
|
39
39
|
src = /`|\$\{/.test(src) ? JSON.stringify(src) : "`" + src + "`";
|
|
40
|
-
src = `${
|
|
40
|
+
src = `${nspName}.process("${type}", ${src}, ${vName})`;
|
|
41
41
|
return src;
|
|
42
42
|
}
|
|
43
43
|
}
|
package/esm/src/parser/tag.js
CHANGED
|
@@ -101,7 +101,7 @@ export class Tag {
|
|
|
101
101
|
const nextLF = LF + SP;
|
|
102
102
|
const nextOption = { SP, LF: (body ? nextLF : LF) };
|
|
103
103
|
const type = `parse.tag.${tagName}`;
|
|
104
|
-
const def = { app, name: tagName, attr, body, LF
|
|
104
|
+
const def = { app, name: tagName, attr, body, LF, nextLF };
|
|
105
105
|
const tagJS = app.process(type, def) ?? this.getTagJS(def, nextOption);
|
|
106
106
|
return commentJS ? commentJS + tagJS : tagJS;
|
|
107
107
|
}
|
package/esm/src/parser/text.js
CHANGED
|
@@ -48,7 +48,11 @@ const textToJS = (app, src, option) => {
|
|
|
48
48
|
value = value.replace(/\s*}$/s, "");
|
|
49
49
|
const item = new EL(app, value);
|
|
50
50
|
if (isAsync) {
|
|
51
|
-
|
|
51
|
+
const toJS = (option) => {
|
|
52
|
+
const js = item.toJS(option);
|
|
53
|
+
return `await ${js}`;
|
|
54
|
+
};
|
|
55
|
+
items.push({ toJS });
|
|
52
56
|
}
|
|
53
57
|
else {
|
|
54
58
|
items.push(item);
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "nsp-server-pages",
|
|
3
3
|
"description": "NSP JavaScript Server Pages for Node.js",
|
|
4
|
-
"version": "0.2.
|
|
4
|
+
"version": "0.2.4",
|
|
5
5
|
"author": "@kawanet",
|
|
6
6
|
"bugs": {
|
|
7
7
|
"url": "https://github.com/kawanet/nsp-server-pages/issues"
|
|
@@ -11,11 +11,11 @@
|
|
|
11
11
|
"to-xml": "^0.1.11"
|
|
12
12
|
},
|
|
13
13
|
"devDependencies": {
|
|
14
|
-
"@
|
|
15
|
-
"@types/
|
|
16
|
-
"
|
|
17
|
-
"
|
|
18
|
-
"typescript": "^5.
|
|
14
|
+
"@types/mocha": "^10.0.10",
|
|
15
|
+
"@types/node": "^25.2.0",
|
|
16
|
+
"mocha": "^11.7.5",
|
|
17
|
+
"nyc": "^17.1.0",
|
|
18
|
+
"typescript": "^5.9.3"
|
|
19
19
|
},
|
|
20
20
|
"exports": {
|
|
21
21
|
"import": {
|
|
@@ -49,6 +49,7 @@
|
|
|
49
49
|
},
|
|
50
50
|
"scripts": {
|
|
51
51
|
"build": "make all",
|
|
52
|
+
"coverage": "npx tsc -p tsconfig-cjs.json && npx nyc npx mocha cjs/test",
|
|
52
53
|
"fixpack": "fixpack",
|
|
53
54
|
"prepack": "make clean test-title all test",
|
|
54
55
|
"test": "make test"
|
package/types/index.d.ts
CHANGED
|
@@ -19,7 +19,7 @@ export declare namespace NSP {
|
|
|
19
19
|
|
|
20
20
|
type TagFn<A, T = any> = (tag: TagDef<A, T>) => (NodeFn<T> | VoidFn<T>);
|
|
21
21
|
|
|
22
|
-
type TagCon<A, T = any> = { new(tag: NSP.TagDef<A>, context: T):
|
|
22
|
+
type TagCon<A, T = any, P extends TagClass = TagClass> = { new(tag: NSP.TagDef<A>, context: T): P, prototype: P };
|
|
23
23
|
|
|
24
24
|
type LoaderFn = (path: string) => Promise<NodeFn<any> | undefined>;
|
|
25
25
|
|