@samuelbines/nunjucks 0.0.3
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/LICENSE +26 -0
- package/README.md +55 -0
- package/dist/scripts/smoke.d.ts +1 -0
- package/dist/scripts/smoke.js +95 -0
- package/dist/src/compiler.d.ts +12 -0
- package/dist/src/compiler.js +1050 -0
- package/dist/src/environment.d.ts +103 -0
- package/dist/src/environment.js +621 -0
- package/dist/src/express-app.d.ts +2 -0
- package/dist/src/express-app.js +33 -0
- package/dist/src/filters.d.ts +44 -0
- package/dist/src/filters.js +424 -0
- package/dist/src/globals.d.ts +14 -0
- package/dist/src/globals.js +342 -0
- package/dist/src/index.d.ts +28 -0
- package/dist/src/index.js +116 -0
- package/dist/src/interpreter.d.ts +16 -0
- package/dist/src/interpreter.js +489 -0
- package/dist/src/lexer.d.ts +72 -0
- package/dist/src/lexer.js +480 -0
- package/dist/src/lib.d.ts +74 -0
- package/dist/src/lib.js +237 -0
- package/dist/src/loader.d.ts +80 -0
- package/dist/src/loader.js +175 -0
- package/dist/src/nodes.d.ts +362 -0
- package/dist/src/nodes.js +894 -0
- package/dist/src/parser.d.ts +66 -0
- package/dist/src/parser.js +1068 -0
- package/dist/src/precompile.d.ts +15 -0
- package/dist/src/precompile.js +108 -0
- package/dist/src/runtime.d.ts +33 -0
- package/dist/src/runtime.js +314 -0
- package/dist/src/transformer.d.ts +3 -0
- package/dist/src/transformer.js +161 -0
- package/dist/src/types.d.ts +27 -0
- package/dist/src/types.js +2 -0
- package/dist/tests/compiler.test.d.ts +1 -0
- package/dist/tests/compiler.test.js +201 -0
- package/dist/tests/enviornment.test.d.ts +1 -0
- package/dist/tests/enviornment.test.js +279 -0
- package/dist/tests/express.test.d.ts +1 -0
- package/dist/tests/express.test.js +86 -0
- package/dist/tests/filters.test.d.ts +13 -0
- package/dist/tests/filters.test.js +286 -0
- package/dist/tests/globals.test.d.ts +1 -0
- package/dist/tests/globals.test.js +579 -0
- package/dist/tests/interpreter.test.d.ts +1 -0
- package/dist/tests/interpreter.test.js +208 -0
- package/dist/tests/lexer.test.d.ts +1 -0
- package/dist/tests/lexer.test.js +249 -0
- package/dist/tests/lib.test.d.ts +1 -0
- package/dist/tests/lib.test.js +236 -0
- package/dist/tests/loader.test.d.ts +1 -0
- package/dist/tests/loader.test.js +301 -0
- package/dist/tests/nodes.test.d.ts +1 -0
- package/dist/tests/nodes.test.js +137 -0
- package/dist/tests/parser.test.d.ts +1 -0
- package/dist/tests/parser.test.js +294 -0
- package/dist/tests/precompile.test.d.ts +1 -0
- package/dist/tests/precompile.test.js +224 -0
- package/dist/tests/runtime.test.d.ts +1 -0
- package/dist/tests/runtime.test.js +237 -0
- package/dist/tests/transformer.test.d.ts +1 -0
- package/dist/tests/transformer.test.js +125 -0
- package/dist/tsconfig.tsbuildinfo +1 -0
- package/package.json +59 -0
package/dist/src/lib.js
ADDED
|
@@ -0,0 +1,237 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.p = exports.repeat = exports._prepareAttributeParts = exports.isObject = exports.isString = exports.isFunction = exports.hasOwnProp = exports.dump = exports.escape = exports.escapeMap = void 0;
|
|
4
|
+
exports._prettifyError = _prettifyError;
|
|
5
|
+
exports.TemplateError = TemplateError;
|
|
6
|
+
exports.getAttrGetter = getAttrGetter;
|
|
7
|
+
exports.groupBy = groupBy;
|
|
8
|
+
exports.toArray = toArray;
|
|
9
|
+
exports.without = without;
|
|
10
|
+
exports.each = each;
|
|
11
|
+
exports.asyncIter = asyncIter;
|
|
12
|
+
exports.asyncFor = asyncFor;
|
|
13
|
+
// ---- ESCAPE CHARACTERS ----
|
|
14
|
+
const escapeRegex = /[&"'<>\\]/g;
|
|
15
|
+
exports.escapeMap = {
|
|
16
|
+
'&': '&',
|
|
17
|
+
'"': '"',
|
|
18
|
+
"'": ''',
|
|
19
|
+
'<': '<',
|
|
20
|
+
'>': '>',
|
|
21
|
+
'\\': '\',
|
|
22
|
+
};
|
|
23
|
+
const typeOfItems = {
|
|
24
|
+
undefined: 'undefined',
|
|
25
|
+
object: 'object',
|
|
26
|
+
boolean: 'boolean',
|
|
27
|
+
number: 'number',
|
|
28
|
+
bigint: 'bigint',
|
|
29
|
+
string: 'string',
|
|
30
|
+
symbol: 'symbol',
|
|
31
|
+
function: 'function',
|
|
32
|
+
};
|
|
33
|
+
const escape = (val) => val?.replace(escapeRegex, (ch) => exports.escapeMap[ch]);
|
|
34
|
+
exports.escape = escape;
|
|
35
|
+
const dump = (obj, spaces) => JSON.stringify(obj, null, spaces);
|
|
36
|
+
exports.dump = dump;
|
|
37
|
+
const hasOwnProp = (obj, key) => (key ? key in obj : false);
|
|
38
|
+
exports.hasOwnProp = hasOwnProp;
|
|
39
|
+
function _prettifyError(path, withInternals, err) {
|
|
40
|
+
if (!err.update) {
|
|
41
|
+
err = TemplateError(err);
|
|
42
|
+
}
|
|
43
|
+
err.update(path);
|
|
44
|
+
if (!withInternals) {
|
|
45
|
+
const old = err;
|
|
46
|
+
err.name = old.name;
|
|
47
|
+
}
|
|
48
|
+
return err;
|
|
49
|
+
}
|
|
50
|
+
// Update template errors
|
|
51
|
+
function TemplateError(message, lineno = 0, colno = 0) {
|
|
52
|
+
const cause = message instanceof Error ? message : undefined;
|
|
53
|
+
const msg = cause ? `${cause.name}: ${cause.message}` : String(message ?? '');
|
|
54
|
+
const err = new Error(msg, cause ? { cause } : undefined);
|
|
55
|
+
err.name = 'Template render error';
|
|
56
|
+
err.lineno = lineno;
|
|
57
|
+
err.colno = colno;
|
|
58
|
+
err.firstUpdate = true;
|
|
59
|
+
console.error('Whats the error?', message, cause);
|
|
60
|
+
if (cause?.stack) {
|
|
61
|
+
Object.defineProperty(err, 'stack', {
|
|
62
|
+
configurable: true,
|
|
63
|
+
get() {
|
|
64
|
+
return cause.stack;
|
|
65
|
+
},
|
|
66
|
+
});
|
|
67
|
+
}
|
|
68
|
+
err.update = (path) => {
|
|
69
|
+
let prefix = `(${path || 'unknown path'})`;
|
|
70
|
+
if (err.firstUpdate) {
|
|
71
|
+
if (err?.lineno && err?.colno)
|
|
72
|
+
prefix += ` [Line ${err?.lineno}, Column ${err?.colno}]`;
|
|
73
|
+
else if (err?.lineno)
|
|
74
|
+
prefix += ` [Line ${err?.lineno}]`;
|
|
75
|
+
}
|
|
76
|
+
prefix += '\n '; // newline + indentation
|
|
77
|
+
err.message = prefix + (err.message || '');
|
|
78
|
+
err.firstUpdate = false;
|
|
79
|
+
return err;
|
|
80
|
+
};
|
|
81
|
+
return err;
|
|
82
|
+
}
|
|
83
|
+
const isFunction = (obj) => typeof obj === typeOfItems.function;
|
|
84
|
+
exports.isFunction = isFunction;
|
|
85
|
+
const isString = (obj) => typeof obj === typeOfItems.string;
|
|
86
|
+
exports.isString = isString;
|
|
87
|
+
const isObject = (obj) => Object.prototype.toString.call(obj) === '[object Object]';
|
|
88
|
+
exports.isObject = isObject;
|
|
89
|
+
const _prepareAttributeParts = (attr) => (typeof attr === 'string' ? attr.split('.') : [attr]);
|
|
90
|
+
exports._prepareAttributeParts = _prepareAttributeParts;
|
|
91
|
+
function getAttrGetter(attribute) {
|
|
92
|
+
const parts = (0, exports._prepareAttributeParts)(attribute);
|
|
93
|
+
return function (item) {
|
|
94
|
+
let _item = item; //TODO fix any
|
|
95
|
+
for (let i = 0; i < parts?.length; i++) {
|
|
96
|
+
const part = parts[i];
|
|
97
|
+
// If item is not an object, and we still got parts to handle, it means
|
|
98
|
+
// that something goes wrong. Just roll out to undefined in that case.
|
|
99
|
+
if (part in _item) {
|
|
100
|
+
_item = _item[part]; // TODO: FIX THIS
|
|
101
|
+
}
|
|
102
|
+
else {
|
|
103
|
+
return undefined;
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
return _item;
|
|
107
|
+
};
|
|
108
|
+
}
|
|
109
|
+
function groupBy(obj, val, throwOnUndefined) {
|
|
110
|
+
const result = {};
|
|
111
|
+
const iterator = (0, exports.isFunction)(val) ? val : getAttrGetter(val);
|
|
112
|
+
for (let i = 0; i < obj?.length; i++) {
|
|
113
|
+
const value = obj[i];
|
|
114
|
+
const key = iterator(value, i);
|
|
115
|
+
if (key === undefined && throwOnUndefined) {
|
|
116
|
+
throw new TypeError(`groupby: attribute "${val}" resolved to undefined`);
|
|
117
|
+
}
|
|
118
|
+
if (!result[key]) {
|
|
119
|
+
result[key] = [];
|
|
120
|
+
}
|
|
121
|
+
result[key]?.push(value);
|
|
122
|
+
}
|
|
123
|
+
return result;
|
|
124
|
+
}
|
|
125
|
+
function toArray(obj) {
|
|
126
|
+
return Array.prototype.slice.call(obj);
|
|
127
|
+
}
|
|
128
|
+
function without(array = [], ...contains) {
|
|
129
|
+
const result = [];
|
|
130
|
+
for (const item of array) {
|
|
131
|
+
if (!contains.includes(item))
|
|
132
|
+
result?.push(item);
|
|
133
|
+
}
|
|
134
|
+
return result;
|
|
135
|
+
}
|
|
136
|
+
const repeat = (char_, n) => {
|
|
137
|
+
let str = '';
|
|
138
|
+
for (let i = 0; i < n; i++) {
|
|
139
|
+
str += char_;
|
|
140
|
+
}
|
|
141
|
+
return str;
|
|
142
|
+
};
|
|
143
|
+
exports.repeat = repeat;
|
|
144
|
+
function each(obj, func, context) {
|
|
145
|
+
if (!obj)
|
|
146
|
+
return;
|
|
147
|
+
if (Array.prototype.forEach && obj.forEach === Array.prototype.forEach) {
|
|
148
|
+
obj.forEach(func, context);
|
|
149
|
+
}
|
|
150
|
+
else if (obj?.length === +obj?.length) {
|
|
151
|
+
for (let i = 0, l = obj?.length; i < l; i++) {
|
|
152
|
+
func.call(context, obj[i], i, obj);
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
}
|
|
156
|
+
function asyncIter(arr, iter, cb) {
|
|
157
|
+
let i = -1;
|
|
158
|
+
function next() {
|
|
159
|
+
i++;
|
|
160
|
+
if (i < arr?.length) {
|
|
161
|
+
iter(arr[i], i, next, cb);
|
|
162
|
+
}
|
|
163
|
+
else {
|
|
164
|
+
cb();
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
next();
|
|
168
|
+
}
|
|
169
|
+
function asyncFor(obj, iter, cb) {
|
|
170
|
+
const keys = Object.keys(obj || {});
|
|
171
|
+
const len = keys?.length;
|
|
172
|
+
let i = -1;
|
|
173
|
+
function next() {
|
|
174
|
+
i++;
|
|
175
|
+
const k = keys[i];
|
|
176
|
+
if (i < len) {
|
|
177
|
+
iter(k, obj[k], i, len, next);
|
|
178
|
+
}
|
|
179
|
+
else {
|
|
180
|
+
cb();
|
|
181
|
+
}
|
|
182
|
+
}
|
|
183
|
+
next();
|
|
184
|
+
}
|
|
185
|
+
// Export this to its own awesome logger function
|
|
186
|
+
const RESET = '\x1b[0m';
|
|
187
|
+
const WARN = '\x1b[33m';
|
|
188
|
+
const ERR = '\x1b[31m';
|
|
189
|
+
const HEADER = '\x1b[95m';
|
|
190
|
+
const OKBLUE = '\x1b[94m';
|
|
191
|
+
const OKCYAN = '\x1b[96m';
|
|
192
|
+
const OKGREEN = '\x1b[92m';
|
|
193
|
+
const WARNING = '\x1b[93m';
|
|
194
|
+
const FAIL = '\x1b[91m';
|
|
195
|
+
const ENDC = '\x1b[0m';
|
|
196
|
+
const BOLD = '\x1b[1m';
|
|
197
|
+
const UNDERLINE = '\x1b[4m';
|
|
198
|
+
const isObjectOrArray = (msg, space = '') => {
|
|
199
|
+
const parts = Array.isArray(msg) ? msg : [msg];
|
|
200
|
+
return parts
|
|
201
|
+
.map((i) => {
|
|
202
|
+
if (typeof i === 'string')
|
|
203
|
+
return i;
|
|
204
|
+
if (typeof i === 'number' ||
|
|
205
|
+
typeof i === 'bigint' ||
|
|
206
|
+
typeof i === 'boolean')
|
|
207
|
+
return String(i);
|
|
208
|
+
if (i instanceof Error)
|
|
209
|
+
return i.stack ?? i.message;
|
|
210
|
+
if (i && typeof i === 'object') {
|
|
211
|
+
try {
|
|
212
|
+
return JSON.stringify(i);
|
|
213
|
+
}
|
|
214
|
+
catch {
|
|
215
|
+
return '[Unserializable object]';
|
|
216
|
+
}
|
|
217
|
+
}
|
|
218
|
+
return String(i); // undefined, null, symbol, function, etc
|
|
219
|
+
})
|
|
220
|
+
.join(space);
|
|
221
|
+
};
|
|
222
|
+
exports.p = {
|
|
223
|
+
log: (...msg) => process.stdout.write(`[INFO] ${isObjectOrArray(msg)}\n`),
|
|
224
|
+
llog: (...msg) => process.stdout.write(`[INFO] ${isObjectOrArray(msg, '\n')}\n`),
|
|
225
|
+
debug: (...msg) => process.stdout.write(`${OKBLUE}[DEBUG] ${isObjectOrArray(msg)}${RESET}\n`),
|
|
226
|
+
ldebug: (...msg) => process.stdout.write(`${OKBLUE}[DEBUG] ${isObjectOrArray(msg, '\n')}${RESET}\n`),
|
|
227
|
+
warn: (...msg) => process.stdout.write(`${WARN}[WARN] ${isObjectOrArray(msg)}${RESET}\n`),
|
|
228
|
+
lwarn: (...msg) => process.stdout.write(`${WARN}[WARN] ${isObjectOrArray(msg, '\n')}${RESET}\n`),
|
|
229
|
+
err: (...msg) => process.stderr.write(`${ERR}[ERR ] ${isObjectOrArray(msg)}${RESET}\n`),
|
|
230
|
+
error: (...msg) => process.stderr.write(`${ERR}[ERR ] ${isObjectOrArray(msg)}${RESET}\n`),
|
|
231
|
+
lerr: (...msg) => process.stderr.write(`${ERR}[ERR ] ${isObjectOrArray(msg, '\n')}${RESET}\n`),
|
|
232
|
+
lerror: (...msg) => process.stderr.write(`${ERR}[ERR ] ${isObjectOrArray(msg, '\n')}${RESET}\n`),
|
|
233
|
+
exit: (...msg) => {
|
|
234
|
+
process.stderr.write(`${ERR}[ERR ] ${isObjectOrArray(msg)}${RESET}\n`);
|
|
235
|
+
process.exit(1);
|
|
236
|
+
},
|
|
237
|
+
};
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
import EventEmitter from 'events';
|
|
2
|
+
interface ILoader {
|
|
3
|
+
watch: boolean;
|
|
4
|
+
noCache: boolean;
|
|
5
|
+
resolve: (from: string, to: string) => string;
|
|
6
|
+
isRelative: (filename: string) => boolean;
|
|
7
|
+
}
|
|
8
|
+
interface IWebLoader extends ILoader {
|
|
9
|
+
baseURL: string;
|
|
10
|
+
useCache: boolean;
|
|
11
|
+
async: boolean;
|
|
12
|
+
cache: any;
|
|
13
|
+
getSource(name: string, cb?: (err: any, res: any) => void): void;
|
|
14
|
+
fetch(url: string, cb: (err: {
|
|
15
|
+
status: number;
|
|
16
|
+
content: string;
|
|
17
|
+
}, src?: string) => void): void;
|
|
18
|
+
}
|
|
19
|
+
export declare class Loader extends EventEmitter implements ILoader {
|
|
20
|
+
watch: boolean;
|
|
21
|
+
noCache: boolean;
|
|
22
|
+
cache: Record<string, any>;
|
|
23
|
+
resolve(from: string, to: string): string;
|
|
24
|
+
isRelative(filename: string): boolean;
|
|
25
|
+
get typename(): string;
|
|
26
|
+
}
|
|
27
|
+
export declare class PrecompiledLoader extends Loader {
|
|
28
|
+
precompiled: Record<string, any>;
|
|
29
|
+
constructor(compiledTemplates: any);
|
|
30
|
+
get typename(): string;
|
|
31
|
+
getSource(name: string): null | {
|
|
32
|
+
src: {
|
|
33
|
+
type: string;
|
|
34
|
+
obj: any;
|
|
35
|
+
};
|
|
36
|
+
path: string;
|
|
37
|
+
};
|
|
38
|
+
}
|
|
39
|
+
export declare class WebLoader extends Loader implements IWebLoader {
|
|
40
|
+
baseURL: string;
|
|
41
|
+
useCache: boolean;
|
|
42
|
+
async: boolean;
|
|
43
|
+
constructor(baseURL?: string, opts?: {
|
|
44
|
+
useCache?: boolean;
|
|
45
|
+
async?: boolean;
|
|
46
|
+
});
|
|
47
|
+
get typename(): string;
|
|
48
|
+
resolve(_: string, _t: string): string;
|
|
49
|
+
getSource(name: string, cb?: (err: any, res: any) => void): any;
|
|
50
|
+
fetch(url: string, cb: (err: {
|
|
51
|
+
status: number;
|
|
52
|
+
content: string;
|
|
53
|
+
}, src?: string) => void): Promise<void>;
|
|
54
|
+
}
|
|
55
|
+
interface ILoaderOpts {
|
|
56
|
+
watch: boolean;
|
|
57
|
+
noCache: boolean;
|
|
58
|
+
}
|
|
59
|
+
export declare class FileSystemLoader extends Loader {
|
|
60
|
+
searchPaths: string[];
|
|
61
|
+
pathsToNames: Record<string, any>;
|
|
62
|
+
constructor(searchPaths?: string[], opts?: ILoaderOpts);
|
|
63
|
+
get typename(): string;
|
|
64
|
+
getSource(name: string): {
|
|
65
|
+
src: string;
|
|
66
|
+
path: any;
|
|
67
|
+
noCache: boolean;
|
|
68
|
+
};
|
|
69
|
+
}
|
|
70
|
+
export declare class MemoryLoader {
|
|
71
|
+
private templates;
|
|
72
|
+
constructor(templates: Record<string, string>);
|
|
73
|
+
getSource(name: string): {
|
|
74
|
+
src: string;
|
|
75
|
+
path: string;
|
|
76
|
+
noCache: boolean;
|
|
77
|
+
};
|
|
78
|
+
get typename(): string;
|
|
79
|
+
}
|
|
80
|
+
export {};
|
|
@@ -0,0 +1,175 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.MemoryLoader = exports.FileSystemLoader = exports.WebLoader = exports.PrecompiledLoader = exports.Loader = void 0;
|
|
7
|
+
// DONE: Sat Jan 3
|
|
8
|
+
const path_1 = __importDefault(require("path"));
|
|
9
|
+
const node_fs_1 = __importDefault(require("node:fs"));
|
|
10
|
+
const events_1 = __importDefault(require("events"));
|
|
11
|
+
const lib_1 = require("./lib");
|
|
12
|
+
// --- FUNCTION ---
|
|
13
|
+
class Loader extends events_1.default {
|
|
14
|
+
watch = false;
|
|
15
|
+
noCache = false;
|
|
16
|
+
cache = {};
|
|
17
|
+
resolve(from, to) {
|
|
18
|
+
return path_1.default.resolve(path_1.default.dirname(from), to);
|
|
19
|
+
}
|
|
20
|
+
isRelative(filename) {
|
|
21
|
+
return filename.indexOf('./') === 0 || filename.indexOf('../') === 0;
|
|
22
|
+
}
|
|
23
|
+
get typename() {
|
|
24
|
+
return 'Loader';
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
exports.Loader = Loader;
|
|
28
|
+
class PrecompiledLoader extends Loader {
|
|
29
|
+
precompiled;
|
|
30
|
+
constructor(compiledTemplates) {
|
|
31
|
+
super();
|
|
32
|
+
this.precompiled = compiledTemplates || {};
|
|
33
|
+
}
|
|
34
|
+
get typename() {
|
|
35
|
+
return 'PrecompiledLoader';
|
|
36
|
+
}
|
|
37
|
+
getSource(name) {
|
|
38
|
+
if (this.precompiled[name]) {
|
|
39
|
+
return {
|
|
40
|
+
src: {
|
|
41
|
+
type: 'code',
|
|
42
|
+
obj: this.precompiled[name],
|
|
43
|
+
},
|
|
44
|
+
path: name,
|
|
45
|
+
};
|
|
46
|
+
}
|
|
47
|
+
return null;
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
exports.PrecompiledLoader = PrecompiledLoader;
|
|
51
|
+
class WebLoader extends Loader {
|
|
52
|
+
baseURL;
|
|
53
|
+
useCache;
|
|
54
|
+
async;
|
|
55
|
+
constructor(baseURL = '.', opts) {
|
|
56
|
+
super();
|
|
57
|
+
this.baseURL = baseURL;
|
|
58
|
+
opts = opts || {};
|
|
59
|
+
this.useCache = !!opts.useCache; // We default cache to false
|
|
60
|
+
this.async = !!opts.async; // We default `async` to false
|
|
61
|
+
}
|
|
62
|
+
get typename() {
|
|
63
|
+
return 'WebLoader';
|
|
64
|
+
}
|
|
65
|
+
resolve(_, _t) {
|
|
66
|
+
throw new Error('relative templates not support in the browser yet');
|
|
67
|
+
return '';
|
|
68
|
+
}
|
|
69
|
+
getSource(name, cb) {
|
|
70
|
+
const useCache = this.useCache;
|
|
71
|
+
if (useCache && this.cache && this.cache[name]) {
|
|
72
|
+
const cached = this.cache[name];
|
|
73
|
+
if (cb)
|
|
74
|
+
cb(null, cached);
|
|
75
|
+
return cached;
|
|
76
|
+
}
|
|
77
|
+
const url = this.baseURL.replace(/\/$/, '') + '/' + name.replace(/^\//, '');
|
|
78
|
+
if (!cb) {
|
|
79
|
+
throw new Error('WebLoader.getSource(name) without a callback is not supported with fetch (fetch is always async). ' +
|
|
80
|
+
'Pass a callback or precompile templates.');
|
|
81
|
+
}
|
|
82
|
+
return this.fetch(url, (err, src) => {
|
|
83
|
+
if (err) {
|
|
84
|
+
if (err.status === 404)
|
|
85
|
+
return cb(null, null);
|
|
86
|
+
return cb(err, null);
|
|
87
|
+
}
|
|
88
|
+
const result = {
|
|
89
|
+
src,
|
|
90
|
+
path: name,
|
|
91
|
+
noCache: !useCache,
|
|
92
|
+
};
|
|
93
|
+
if (useCache) {
|
|
94
|
+
this.cache = this.cache || {};
|
|
95
|
+
this.cache[name] = result;
|
|
96
|
+
}
|
|
97
|
+
this.emit('load', name, result);
|
|
98
|
+
cb(null, result);
|
|
99
|
+
});
|
|
100
|
+
}
|
|
101
|
+
fetch(url, cb) {
|
|
102
|
+
if (typeof window === 'undefined') {
|
|
103
|
+
throw new Error('WebLoader can only by used in a browser');
|
|
104
|
+
}
|
|
105
|
+
const bust = 's=' + Date.now();
|
|
106
|
+
const finalUrl = url + (url.includes('?') ? '&' : '?') + bust;
|
|
107
|
+
return fetch(finalUrl, { method: 'GET', credentials: 'same-origin' })
|
|
108
|
+
.then((res) => res.text().then((text) => {
|
|
109
|
+
if (res.ok || res.status === 0) {
|
|
110
|
+
cb(null, text);
|
|
111
|
+
}
|
|
112
|
+
else {
|
|
113
|
+
cb({ status: res.status, content: text });
|
|
114
|
+
}
|
|
115
|
+
}))
|
|
116
|
+
.catch((e) => cb({ status: 0, content: String(e?.message || e) }));
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
exports.WebLoader = WebLoader;
|
|
120
|
+
class FileSystemLoader extends Loader {
|
|
121
|
+
searchPaths;
|
|
122
|
+
pathsToNames;
|
|
123
|
+
constructor(searchPaths = ['.'], opts) {
|
|
124
|
+
super();
|
|
125
|
+
this.searchPaths = searchPaths;
|
|
126
|
+
if (typeof opts === 'boolean') {
|
|
127
|
+
throw '';
|
|
128
|
+
}
|
|
129
|
+
this.pathsToNames = {};
|
|
130
|
+
this.noCache = opts?.noCache || false;
|
|
131
|
+
this.searchPaths = (Array.isArray(searchPaths) ? searchPaths : [searchPaths]).map(path_1.default.normalize);
|
|
132
|
+
}
|
|
133
|
+
get typename() {
|
|
134
|
+
return 'FileSystemLoader';
|
|
135
|
+
}
|
|
136
|
+
getSource(name) {
|
|
137
|
+
let fullpath = null;
|
|
138
|
+
for (let i = 0; i < this.searchPaths?.length; i++) {
|
|
139
|
+
const basePath = path_1.default.resolve(this.searchPaths[i]);
|
|
140
|
+
const p = path_1.default.resolve(this.searchPaths[i], name);
|
|
141
|
+
if (p.indexOf(basePath) === 0 && node_fs_1.default.existsSync(p)) {
|
|
142
|
+
fullpath = p;
|
|
143
|
+
break;
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
if (!fullpath) {
|
|
147
|
+
return null;
|
|
148
|
+
}
|
|
149
|
+
this.pathsToNames[fullpath] = name;
|
|
150
|
+
lib_1.p.warn('Try to load file: ', this.pathsToNames, '\nFullpath: ', fullpath);
|
|
151
|
+
const source = {
|
|
152
|
+
src: node_fs_1.default.readFileSync(fullpath, 'utf-8'),
|
|
153
|
+
path: fullpath,
|
|
154
|
+
noCache: this.noCache,
|
|
155
|
+
};
|
|
156
|
+
this.emit('load', name, source);
|
|
157
|
+
return source;
|
|
158
|
+
}
|
|
159
|
+
}
|
|
160
|
+
exports.FileSystemLoader = FileSystemLoader;
|
|
161
|
+
class MemoryLoader {
|
|
162
|
+
templates;
|
|
163
|
+
constructor(templates) {
|
|
164
|
+
this.templates = templates;
|
|
165
|
+
}
|
|
166
|
+
getSource(name) {
|
|
167
|
+
if (!(name in this.templates))
|
|
168
|
+
return null;
|
|
169
|
+
return { src: this.templates[name], path: name, noCache: true };
|
|
170
|
+
}
|
|
171
|
+
get typename() {
|
|
172
|
+
return 'MemoryLoader';
|
|
173
|
+
}
|
|
174
|
+
}
|
|
175
|
+
exports.MemoryLoader = MemoryLoader;
|