express-hbs 2.5.0 → 3.0.0
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/.github/workflows/publish.yml +73 -0
- package/.github/workflows/test.yml +32 -8
- package/.nvmrc +1 -0
- package/.nycrc.json +16 -0
- package/.oxfmtrc.json +19 -0
- package/.oxlintrc.json +32 -0
- package/AGENTS.md +40 -0
- package/LICENSE +1 -1
- package/README.md +50 -22
- package/example/app-layoutsDir.js +32 -39
- package/example/app.js +27 -34
- package/lib/hbs.js +82 -90
- package/lib/resolver.js +10 -9
- package/package.json +29 -22
- package/renovate.json +9 -2
- package/test/apps/async/index.js +54 -42
- package/test/apps/i18n/index.js +9 -7
- package/test/asyncSpecs.js +12 -12
- package/test/cacheSpecs.js +18 -21
- package/test/customExtension.js +15 -16
- package/test/handlebarsSpecs.js +16 -19
- package/test/helperSpecs.js +22 -20
- package/test/helpers.js +3 -3
- package/test/i18nSpecs.js +10 -8
- package/test/issues.js +136 -122
- package/test/layoutSpecs.js +23 -25
- package/test/localTemplateOptions.js +40 -42
- package/test/multiple.js +30 -34
- package/test/nonExpress.js +9 -10
- package/test/optionsSpecs.js +5 -7
- package/test/resolverSpecs.js +54 -0
- package/.eslintrc +0 -42
package/lib/hbs.js
CHANGED
|
@@ -10,12 +10,12 @@ var _ = require('lodash');
|
|
|
10
10
|
/**
|
|
11
11
|
* Regex pattern for layout directive. {{!< layout }}
|
|
12
12
|
*/
|
|
13
|
-
var layoutPattern = /{{!<\s+([A-Za-z0-9
|
|
13
|
+
var layoutPattern = /{{!<\s+([A-Za-z0-9._\-/]+)\s*}}/;
|
|
14
14
|
|
|
15
15
|
/**
|
|
16
16
|
* Constructor
|
|
17
17
|
*/
|
|
18
|
-
var ExpressHbs = function() {
|
|
18
|
+
var ExpressHbs = function () {
|
|
19
19
|
this.handlebars = handlebars.create();
|
|
20
20
|
this.SafeString = this.handlebars.SafeString;
|
|
21
21
|
this.Utils = this.handlebars.Utils;
|
|
@@ -33,7 +33,7 @@ var ExpressHbs = function() {
|
|
|
33
33
|
* <link rel="stylesheet" href='{{{URL "css/style.css"}}}' />
|
|
34
34
|
* {{/contentFor}}
|
|
35
35
|
*/
|
|
36
|
-
ExpressHbs.prototype.content = function(name, options, context) {
|
|
36
|
+
ExpressHbs.prototype.content = function (name, options, context) {
|
|
37
37
|
var block = options.data.root.blockCache[name] || (options.data.root.blockCache[name] = []);
|
|
38
38
|
block.push(options.fn(context));
|
|
39
39
|
};
|
|
@@ -46,9 +46,8 @@ ExpressHbs.prototype.content = function(name, options, context) {
|
|
|
46
46
|
* @param {String} filename Path to template file.
|
|
47
47
|
* @param {String} layout Layout path.
|
|
48
48
|
*/
|
|
49
|
-
ExpressHbs.prototype.layoutPath = function(filename, layout) {
|
|
50
|
-
var dirs,
|
|
51
|
-
layoutPath;
|
|
49
|
+
ExpressHbs.prototype.layoutPath = function (filename, layout) {
|
|
50
|
+
var dirs, layoutPath;
|
|
52
51
|
if (layout[0] === '.') {
|
|
53
52
|
dirs = path.dirname(filename);
|
|
54
53
|
} else if (this.layoutsDir) {
|
|
@@ -71,7 +70,7 @@ ExpressHbs.prototype.layoutPath = function(filename, layout) {
|
|
|
71
70
|
* @param {String} filename Path to template
|
|
72
71
|
* @returns {String|undefined} Returns the path to layout.
|
|
73
72
|
*/
|
|
74
|
-
ExpressHbs.prototype.declaredLayoutFile = function(str, filename) {
|
|
73
|
+
ExpressHbs.prototype.declaredLayoutFile = function (str, filename) {
|
|
75
74
|
var matches = str.match(layoutPattern);
|
|
76
75
|
if (matches) {
|
|
77
76
|
var layout = matches[1];
|
|
@@ -96,12 +95,14 @@ ExpressHbs.prototype.declaredLayoutFile = function(str, filename) {
|
|
|
96
95
|
* @param {Boolean} useCache Cache the compiled layout?
|
|
97
96
|
* @param {Function} cb Callback called with layouts stack
|
|
98
97
|
*/
|
|
99
|
-
ExpressHbs.prototype.cacheLayout = function(layoutFile, useCache, cb) {
|
|
98
|
+
ExpressHbs.prototype.cacheLayout = function (layoutFile, useCache, cb) {
|
|
100
99
|
var self = this;
|
|
101
100
|
|
|
102
101
|
if (this.restrictLayoutsTo) {
|
|
103
102
|
if (!layoutFile.startsWith(this.restrictLayoutsTo)) {
|
|
104
|
-
var err = new Error(
|
|
103
|
+
var err = new Error(
|
|
104
|
+
'Cannot read ' + layoutFile + ' it does not reside in ' + this.restrictLayoutsTo,
|
|
105
|
+
);
|
|
105
106
|
return cb(err, null);
|
|
106
107
|
}
|
|
107
108
|
}
|
|
@@ -113,14 +114,14 @@ ExpressHbs.prototype.cacheLayout = function(layoutFile, useCache, cb) {
|
|
|
113
114
|
var layoutTemplates = this.cache[layoutFile];
|
|
114
115
|
if (layoutTemplates) return cb(null, layoutTemplates);
|
|
115
116
|
|
|
116
|
-
fs.readFile(layoutFile, 'utf8', function(err, str) {
|
|
117
|
+
fs.readFile(layoutFile, 'utf8', function (err, str) {
|
|
117
118
|
if (err) return cb(err);
|
|
118
119
|
|
|
119
120
|
// File path of eventual declared parent layout
|
|
120
121
|
var parentLayoutFile = self.declaredLayoutFile(str, layoutFile);
|
|
121
122
|
|
|
122
123
|
// This function returns the current layout stack to the caller
|
|
123
|
-
var _returnLayouts = function(layouts) {
|
|
124
|
+
var _returnLayouts = function (layouts) {
|
|
124
125
|
var currentLayout;
|
|
125
126
|
layouts = layouts.slice(0);
|
|
126
127
|
currentLayout = self.compile(str, layoutFile);
|
|
@@ -133,7 +134,7 @@ ExpressHbs.prototype.cacheLayout = function(layoutFile, useCache, cb) {
|
|
|
133
134
|
|
|
134
135
|
if (parentLayoutFile) {
|
|
135
136
|
// Recursively compile/cache parent layouts
|
|
136
|
-
self.cacheLayout(parentLayoutFile, useCache, function(err, parentLayouts) {
|
|
137
|
+
self.cacheLayout(parentLayoutFile, useCache, function (err, parentLayouts) {
|
|
137
138
|
if (err) return cb(err);
|
|
138
139
|
_returnLayouts(parentLayouts);
|
|
139
140
|
});
|
|
@@ -147,7 +148,7 @@ ExpressHbs.prototype.cacheLayout = function(layoutFile, useCache, cb) {
|
|
|
147
148
|
/**
|
|
148
149
|
* Cache partial templates found under directories configure in partialsDir.
|
|
149
150
|
*/
|
|
150
|
-
ExpressHbs.prototype.cachePartials = function(cb) {
|
|
151
|
+
ExpressHbs.prototype.cachePartials = function (cb) {
|
|
151
152
|
var self = this;
|
|
152
153
|
|
|
153
154
|
if (!(this.partialsDir instanceof Array)) {
|
|
@@ -158,36 +159,36 @@ ExpressHbs.prototype.cachePartials = function(cb) {
|
|
|
158
159
|
var count = 0;
|
|
159
160
|
|
|
160
161
|
function readNext() {
|
|
161
|
-
readdirp(self.partialsDir[count], {fileFilter: '*' + self._options.extname})
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
162
|
+
readdirp(self.partialsDir[count], { fileFilter: '*' + self._options.extname })
|
|
163
|
+
.on('warn', function (err) {
|
|
164
|
+
console.warn('Non-fatal error in express-hbs cachePartials.', err);
|
|
165
|
+
})
|
|
166
|
+
.on('error', function (err) {
|
|
167
|
+
console.error('Fatal error in express-hbs cachePartials', err);
|
|
168
|
+
return cb(err);
|
|
169
|
+
})
|
|
170
|
+
.on('data', function (entry) {
|
|
171
|
+
if (!entry) return;
|
|
172
|
+
var source = fs.readFileSync(entry.fullPath, 'utf8');
|
|
173
|
+
var dirname = path.dirname(entry.path);
|
|
174
|
+
dirname = dirname === '.' ? '' : dirname + '/';
|
|
175
|
+
|
|
176
|
+
var name = dirname + path.basename(entry.basename, self._options.extname);
|
|
177
|
+
// fix the path in windows
|
|
178
|
+
name = name.split('\\').join('/');
|
|
179
|
+
self.registerPartial(name, source, entry.fullPath);
|
|
180
|
+
})
|
|
181
|
+
.on('end', function () {
|
|
182
|
+
count += 1;
|
|
183
|
+
|
|
184
|
+
// If all directories aren't read, read the next directory
|
|
185
|
+
if (count < self.partialsDir.length) {
|
|
186
|
+
readNext();
|
|
187
|
+
} else {
|
|
188
|
+
self.isPartialCachingComplete = true;
|
|
189
|
+
if (cb) cb(null, true);
|
|
190
|
+
}
|
|
191
|
+
});
|
|
191
192
|
}
|
|
192
193
|
|
|
193
194
|
readNext();
|
|
@@ -210,7 +211,7 @@ ExpressHbs.prototype.cachePartials = function(cb) {
|
|
|
210
211
|
* }
|
|
211
212
|
* }
|
|
212
213
|
*/
|
|
213
|
-
ExpressHbs.prototype.express3 = function(options) {
|
|
214
|
+
ExpressHbs.prototype.express3 = function (options) {
|
|
214
215
|
var self = this;
|
|
215
216
|
|
|
216
217
|
// Set defaults
|
|
@@ -227,31 +228,31 @@ ExpressHbs.prototype.express3 = function(options) {
|
|
|
227
228
|
|
|
228
229
|
if (options.i18n) {
|
|
229
230
|
var i18n = options.i18n;
|
|
230
|
-
this.handlebars.registerHelper('__', function() {
|
|
231
|
+
this.handlebars.registerHelper('__', function () {
|
|
231
232
|
var args = Array.prototype.slice.call(arguments);
|
|
232
233
|
var options = args.pop();
|
|
233
234
|
return i18n.__.apply(options.data.root, args);
|
|
234
235
|
});
|
|
235
|
-
this.handlebars.registerHelper('__n', function() {
|
|
236
|
+
this.handlebars.registerHelper('__n', function () {
|
|
236
237
|
var args = Array.prototype.slice.call(arguments);
|
|
237
238
|
var options = args.pop();
|
|
238
239
|
return i18n.__n.apply(options.data.root, args);
|
|
239
240
|
});
|
|
240
241
|
}
|
|
241
242
|
|
|
242
|
-
this.handlebars.registerHelper(this._options.blockHelperName, function(name, options) {
|
|
243
|
+
this.handlebars.registerHelper(this._options.blockHelperName, function (name, options) {
|
|
243
244
|
var val = options.data.root.blockCache[name];
|
|
244
245
|
if (val === undefined && typeof options.fn === 'function') {
|
|
245
246
|
val = options.fn(this);
|
|
246
247
|
}
|
|
247
248
|
if (Array.isArray(val)) {
|
|
248
|
-
val = val.join('\n');
|
|
249
|
+
val = val.join('\n');
|
|
249
250
|
}
|
|
250
251
|
return val;
|
|
251
252
|
});
|
|
252
253
|
|
|
253
254
|
// Pass 'this' as context of helper function to don't lose context call of helpers.
|
|
254
|
-
this.handlebars.registerHelper(this._options.contentHelperName, function(name, options) {
|
|
255
|
+
this.handlebars.registerHelper(this._options.contentHelperName, function (name, options) {
|
|
255
256
|
return self.content(name, options, this);
|
|
256
257
|
});
|
|
257
258
|
|
|
@@ -300,12 +301,12 @@ ExpressHbs.prototype.express4 = ExpressHbs.prototype.express3;
|
|
|
300
301
|
*
|
|
301
302
|
* @param {Boolean} useCache Whether to cache.
|
|
302
303
|
*/
|
|
303
|
-
ExpressHbs.prototype.loadDefaultLayout = function(useCache, cb) {
|
|
304
|
+
ExpressHbs.prototype.loadDefaultLayout = function (useCache, cb) {
|
|
304
305
|
var self = this;
|
|
305
306
|
if (!this._options.defaultLayout) return cb();
|
|
306
307
|
if (useCache && this.defaultLayoutTemplates) return cb(null, this.defaultLayoutTemplates);
|
|
307
308
|
|
|
308
|
-
this.cacheLayout(this._options.defaultLayout, useCache, function(err, templates) {
|
|
309
|
+
this.cacheLayout(this._options.defaultLayout, useCache, function (err, templates) {
|
|
309
310
|
if (err) return cb(err);
|
|
310
311
|
self.defaultLayoutTemplates = templates.slice(0);
|
|
311
312
|
return cb(null, templates);
|
|
@@ -315,7 +316,7 @@ ExpressHbs.prototype.loadDefaultLayout = function(useCache, cb) {
|
|
|
315
316
|
/**
|
|
316
317
|
* Expose useful methods.
|
|
317
318
|
*/
|
|
318
|
-
ExpressHbs.prototype.registerHelper = function(name, fn) {
|
|
319
|
+
ExpressHbs.prototype.registerHelper = function (name, fn) {
|
|
319
320
|
this.handlebars.registerHelper(name, fn);
|
|
320
321
|
};
|
|
321
322
|
|
|
@@ -325,7 +326,7 @@ ExpressHbs.prototype.registerHelper = function(name, fn) {
|
|
|
325
326
|
* @param {String} name The name of the partial as used in a template.
|
|
326
327
|
* @param {String} source String source of the partial.
|
|
327
328
|
*/
|
|
328
|
-
ExpressHbs.prototype.registerPartial = function(name, source, filename) {
|
|
329
|
+
ExpressHbs.prototype.registerPartial = function (name, source, filename) {
|
|
329
330
|
this.handlebars.registerPartial(name, this.compile(source, filename));
|
|
330
331
|
};
|
|
331
332
|
|
|
@@ -335,7 +336,7 @@ ExpressHbs.prototype.registerPartial = function(name, source, filename) {
|
|
|
335
336
|
* @param {String} source The source to compile.
|
|
336
337
|
* @param {String} filename The path used to embed into __filename for errors.
|
|
337
338
|
*/
|
|
338
|
-
ExpressHbs.prototype.compile = function(source, filename) {
|
|
339
|
+
ExpressHbs.prototype.compile = function (source, filename) {
|
|
339
340
|
// Handlebars has a bug with comment only partial causes errors. This must
|
|
340
341
|
// be a string so the block below can add a space.
|
|
341
342
|
if (typeof source !== 'string') {
|
|
@@ -368,53 +369,46 @@ ExpressHbs.prototype.compile = function(source, filename) {
|
|
|
368
369
|
* @param {String} name The name of the partial as used in a template.
|
|
369
370
|
* @param {String} fn The `function(options, cb)`
|
|
370
371
|
*/
|
|
371
|
-
ExpressHbs.prototype.registerAsyncHelper = function(name, fn) {
|
|
372
|
-
this.handlebars.registerHelper(name, function(context, options) {
|
|
373
|
-
var resolverCache =
|
|
372
|
+
ExpressHbs.prototype.registerAsyncHelper = function (name, fn) {
|
|
373
|
+
this.handlebars.registerHelper(name, function (context, options) {
|
|
374
|
+
var resolverCache =
|
|
375
|
+
this.resolverCache ||
|
|
374
376
|
_.get(context, 'data.root.resolverCache') ||
|
|
375
377
|
_.get(options, 'data.root.resolverCache');
|
|
376
378
|
if (!resolverCache) {
|
|
377
379
|
throw new Error('Could not find resolver cache in async helper ' + name + '.');
|
|
378
380
|
}
|
|
379
381
|
if (options && fn.length > 2) {
|
|
380
|
-
var resolveFunc = function(arr, cb) {
|
|
382
|
+
var resolveFunc = function (arr, cb) {
|
|
381
383
|
return fn.call(this, arr[0], arr[1], cb);
|
|
382
384
|
};
|
|
383
385
|
|
|
384
|
-
return resolver.resolve(
|
|
385
|
-
resolverCache,
|
|
386
|
-
resolveFunc.bind(this),
|
|
387
|
-
[context, options]
|
|
388
|
-
);
|
|
386
|
+
return resolver.resolve(resolverCache, resolveFunc.bind(this), [context, options]);
|
|
389
387
|
}
|
|
390
|
-
return resolver.resolve(
|
|
391
|
-
resolverCache,
|
|
392
|
-
fn.bind(this),
|
|
393
|
-
context
|
|
394
|
-
);
|
|
388
|
+
return resolver.resolve(resolverCache, fn.bind(this), context);
|
|
395
389
|
});
|
|
396
390
|
};
|
|
397
391
|
|
|
398
|
-
ExpressHbs.prototype.getTemplateOptions = function() {
|
|
392
|
+
ExpressHbs.prototype.getTemplateOptions = function () {
|
|
399
393
|
return this._options.templateOptions;
|
|
400
394
|
};
|
|
401
395
|
|
|
402
|
-
ExpressHbs.prototype.updateTemplateOptions = function(templateOptions) {
|
|
396
|
+
ExpressHbs.prototype.updateTemplateOptions = function (templateOptions) {
|
|
403
397
|
this._options.templateOptions = templateOptions;
|
|
404
398
|
};
|
|
405
399
|
|
|
406
|
-
ExpressHbs.prototype.getLocalTemplateOptions = function(locals) {
|
|
400
|
+
ExpressHbs.prototype.getLocalTemplateOptions = function (locals) {
|
|
407
401
|
return locals._templateOptions || {};
|
|
408
402
|
};
|
|
409
403
|
|
|
410
|
-
ExpressHbs.prototype.updateLocalTemplateOptions = function(locals, localTemplateOptions) {
|
|
411
|
-
return locals._templateOptions = localTemplateOptions;
|
|
404
|
+
ExpressHbs.prototype.updateLocalTemplateOptions = function (locals, localTemplateOptions) {
|
|
405
|
+
return (locals._templateOptions = localTemplateOptions);
|
|
412
406
|
};
|
|
413
407
|
|
|
414
408
|
/**
|
|
415
409
|
* Creates a new instance of ExpressHbs.
|
|
416
410
|
*/
|
|
417
|
-
ExpressHbs.prototype.create = function() {
|
|
411
|
+
ExpressHbs.prototype.create = function () {
|
|
418
412
|
return new ExpressHbs();
|
|
419
413
|
};
|
|
420
414
|
|
|
@@ -508,7 +502,6 @@ ExpressHbs.prototype.___express = function ___express(filename, source, options,
|
|
|
508
502
|
cb(null, res);
|
|
509
503
|
}
|
|
510
504
|
|
|
511
|
-
|
|
512
505
|
/**
|
|
513
506
|
* Renders `template` with an optional set of nested `layoutTemplates` using
|
|
514
507
|
* data in `locals`.
|
|
@@ -520,7 +513,7 @@ ExpressHbs.prototype.___express = function ___express(filename, source, options,
|
|
|
520
513
|
// being passed the rendered string of the previous ones as `body`
|
|
521
514
|
var i = layoutTemplates.length - 1;
|
|
522
515
|
|
|
523
|
-
var _stackRenderer = function(err, htmlStr) {
|
|
516
|
+
var _stackRenderer = function (err, htmlStr) {
|
|
524
517
|
if (err) return cb(err);
|
|
525
518
|
|
|
526
519
|
if (i >= 0) {
|
|
@@ -535,7 +528,6 @@ ExpressHbs.prototype.___express = function ___express(filename, source, options,
|
|
|
535
528
|
renderTemplate(template, locals, _stackRenderer);
|
|
536
529
|
}
|
|
537
530
|
|
|
538
|
-
|
|
539
531
|
/**
|
|
540
532
|
* Lazy loads js-beautify, which should not be used in production env.
|
|
541
533
|
*/
|
|
@@ -561,14 +553,14 @@ ExpressHbs.prototype.___express = function ___express(filename, source, options,
|
|
|
561
553
|
}
|
|
562
554
|
}
|
|
563
555
|
|
|
564
|
-
fs.readFile(filename, 'utf8', function(err, source) {
|
|
556
|
+
fs.readFile(filename, 'utf8', function (err, source) {
|
|
565
557
|
if (err) return cb(err);
|
|
566
558
|
|
|
567
559
|
var template = self.compile(source, filename);
|
|
568
560
|
if (options.cache) {
|
|
569
561
|
self.cache[filename] = {
|
|
570
562
|
source: source,
|
|
571
|
-
template: template
|
|
563
|
+
template: template,
|
|
572
564
|
};
|
|
573
565
|
}
|
|
574
566
|
return cb(null, source, template);
|
|
@@ -579,16 +571,16 @@ ExpressHbs.prototype.___express = function ___express(filename, source, options,
|
|
|
579
571
|
* Compiles a file into a template and a layoutTemplate, then renders it above.
|
|
580
572
|
*/
|
|
581
573
|
function compileFile(locals, cb) {
|
|
582
|
-
getSourceTemplate(function(err, source, template) {
|
|
574
|
+
getSourceTemplate(function (err, source, template) {
|
|
583
575
|
if (err) return cb(err);
|
|
584
576
|
|
|
585
577
|
// Try to get the layout
|
|
586
|
-
parseLayout(source, filename, function(err, layoutTemplates) {
|
|
578
|
+
parseLayout(source, filename, function (err, layoutTemplates) {
|
|
587
579
|
if (err) return cb(err);
|
|
588
580
|
|
|
589
581
|
function renderIt(layoutTemplates) {
|
|
590
582
|
if (self._options.beautify) {
|
|
591
|
-
return render(template, locals, layoutTemplates, function(err, html) {
|
|
583
|
+
return render(template, locals, layoutTemplates, function (err, html) {
|
|
592
584
|
if (err) return cb(err);
|
|
593
585
|
loadBeautify();
|
|
594
586
|
return cb(null, self.beautify(html, self.beautifyrc));
|
|
@@ -608,7 +600,7 @@ ExpressHbs.prototype.___express = function ___express(filename, source, options,
|
|
|
608
600
|
} else if (typeof options.layout !== 'undefined' && options.layout) {
|
|
609
601
|
// 2. Layout specified by options from render
|
|
610
602
|
var layoutFile = self.layoutPath(filename, options.layout);
|
|
611
|
-
self.cacheLayout(layoutFile, options.cache, function(err, layoutTemplates) {
|
|
603
|
+
self.cacheLayout(layoutFile, options.cache, function (err, layoutTemplates) {
|
|
612
604
|
if (err) return cb(err);
|
|
613
605
|
renderIt(layoutTemplates);
|
|
614
606
|
});
|
|
@@ -625,11 +617,11 @@ ExpressHbs.prototype.___express = function ___express(filename, source, options,
|
|
|
625
617
|
|
|
626
618
|
function replaceValue(values, text) {
|
|
627
619
|
if (typeof text === 'string') {
|
|
628
|
-
Object.keys(values).forEach(function(id) {
|
|
629
|
-
text = text.replace(id, function() {
|
|
620
|
+
Object.keys(values).forEach(function (id) {
|
|
621
|
+
text = text.replace(id, function () {
|
|
630
622
|
return values[id];
|
|
631
623
|
});
|
|
632
|
-
text = text.replace(self.Utils.escapeExpression(id), function() {
|
|
624
|
+
text = text.replace(self.Utils.escapeExpression(id), function () {
|
|
633
625
|
return self.Utils.escapeExpression(values[id]);
|
|
634
626
|
});
|
|
635
627
|
});
|
|
@@ -640,9 +632,9 @@ ExpressHbs.prototype.___express = function ___express(filename, source, options,
|
|
|
640
632
|
// Handles waiting for async helpers
|
|
641
633
|
function handleAsync(err, res) {
|
|
642
634
|
if (err) return cb(err);
|
|
643
|
-
resolver.done(options.resolverCache, function(err, values) {
|
|
635
|
+
resolver.done(options.resolverCache, function (err, values) {
|
|
644
636
|
if (err) return cb(err);
|
|
645
|
-
Object.keys(values).forEach(function(key) {
|
|
637
|
+
Object.keys(values).forEach(function (key) {
|
|
646
638
|
values[key] = replaceValue(values, values[key]);
|
|
647
639
|
});
|
|
648
640
|
res = replaceValue(values, res);
|
|
@@ -654,13 +646,13 @@ ExpressHbs.prototype.___express = function ___express(filename, source, options,
|
|
|
654
646
|
}
|
|
655
647
|
|
|
656
648
|
// kick it off by loading default template (if any)
|
|
657
|
-
this.loadDefaultLayout(options.cache, function(err) {
|
|
649
|
+
this.loadDefaultLayout(options.cache, function (err) {
|
|
658
650
|
if (err) return cb(err);
|
|
659
651
|
|
|
660
652
|
// Force reloading of all partials if caching is not used. Inefficient but there
|
|
661
653
|
// is no loading partial event.
|
|
662
654
|
if (self.partialsDir && (!options.cache || !self.isPartialCachingComplete)) {
|
|
663
|
-
return self.cachePartials(function(err) {
|
|
655
|
+
return self.cachePartials(function (err) {
|
|
664
656
|
if (err) return cb(err);
|
|
665
657
|
return compileFile(options, handleAsync);
|
|
666
658
|
});
|
package/lib/resolver.js
CHANGED
|
@@ -14,9 +14,9 @@ var ID_SUFFIX = '__';
|
|
|
14
14
|
|
|
15
15
|
function resolve(cache, fn, context) {
|
|
16
16
|
var id = ID_PREFIX + ID_ESCAPED_STRING + generateId(ID_LENGTH) + ID_SUFFIX;
|
|
17
|
-
cache[id] = new Promise(function(passed, failed) {
|
|
17
|
+
cache[id] = new Promise(function (passed, failed) {
|
|
18
18
|
try {
|
|
19
|
-
fn(context, function(res) {
|
|
19
|
+
fn(context, function (res) {
|
|
20
20
|
passed(res);
|
|
21
21
|
});
|
|
22
22
|
} catch (error) {
|
|
@@ -29,23 +29,24 @@ function resolve(cache, fn, context) {
|
|
|
29
29
|
// cache is an object where the keys are cache keys and values are promises. See above.
|
|
30
30
|
function done(cache, callback) {
|
|
31
31
|
return Promise.all(Object.values(cache))
|
|
32
|
-
.then(function(values) {
|
|
32
|
+
.then(function (values) {
|
|
33
33
|
var resolvedCache = {};
|
|
34
34
|
var keys = Object.keys(cache);
|
|
35
|
-
values.forEach(function(value, index) {
|
|
35
|
+
values.forEach(function (value, index) {
|
|
36
36
|
resolvedCache[keys[index]] = value;
|
|
37
37
|
});
|
|
38
38
|
callback(null, resolvedCache);
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
39
|
+
})
|
|
40
|
+
.catch(function (error) {
|
|
41
|
+
callback(error);
|
|
42
|
+
});
|
|
42
43
|
}
|
|
43
44
|
|
|
44
45
|
function hasResolvers(text) {
|
|
45
46
|
// NOTE: We specifically search the text for the ID_PREFIX **NOT** including the escapable character
|
|
46
47
|
// This is because that character can be escaped in the text, and lead us to not finding unresolved
|
|
47
48
|
// async helper outputs.
|
|
48
|
-
if (text.search(ID_PREFIX)
|
|
49
|
+
if (text.search(ID_PREFIX) >= 0) {
|
|
49
50
|
return true;
|
|
50
51
|
}
|
|
51
52
|
return false;
|
|
@@ -54,5 +55,5 @@ function hasResolvers(text) {
|
|
|
54
55
|
module.exports = {
|
|
55
56
|
done: done,
|
|
56
57
|
hasResolvers: hasResolvers,
|
|
57
|
-
resolve: resolve
|
|
58
|
+
resolve: resolve,
|
|
58
59
|
};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "express-hbs",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "3.0.0",
|
|
4
4
|
"description": "Express handlebars template engine complete with multiple layouts, partials and blocks.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"express4",
|
|
@@ -10,17 +10,12 @@
|
|
|
10
10
|
"partials"
|
|
11
11
|
],
|
|
12
12
|
"main": "index.js",
|
|
13
|
+
"engines": {
|
|
14
|
+
"node": ">=20"
|
|
15
|
+
},
|
|
13
16
|
"directories": {
|
|
14
17
|
"example": "example"
|
|
15
18
|
},
|
|
16
|
-
"scripts": {
|
|
17
|
-
"lint": "eslint --ext .js --cache lib/**",
|
|
18
|
-
"test": "mocha",
|
|
19
|
-
"posttest": "yarn lint",
|
|
20
|
-
"coverage": "nyc yarn test",
|
|
21
|
-
"preship": "yarn test",
|
|
22
|
-
"ship": "STATUS=$(git status --porcelain); echo $STATUS; if [ -z \"$STATUS\" ]; then yarn publish && git push --follow-tags; fi"
|
|
23
|
-
},
|
|
24
19
|
"repository": {
|
|
25
20
|
"type": "git",
|
|
26
21
|
"url": "https://github.com/TryGhost/express-hbs"
|
|
@@ -29,21 +24,33 @@
|
|
|
29
24
|
"author": "Mario Gutierrez <mario@barc.com>",
|
|
30
25
|
"license": "MIT",
|
|
31
26
|
"devDependencies": {
|
|
32
|
-
"cookie-parser": "1.4.
|
|
33
|
-
"
|
|
34
|
-
"
|
|
35
|
-
"
|
|
36
|
-
"
|
|
37
|
-
"
|
|
38
|
-
"
|
|
39
|
-
"
|
|
27
|
+
"cookie-parser": "1.4.7",
|
|
28
|
+
"express": "5.2.1",
|
|
29
|
+
"i18n": "0.15.3",
|
|
30
|
+
"mocha": "11.7.6",
|
|
31
|
+
"nyc": "18.0.0",
|
|
32
|
+
"oxfmt": "0.57.0",
|
|
33
|
+
"oxlint": "1.72.0",
|
|
34
|
+
"rewire": "9.0.1",
|
|
35
|
+
"supertest": "7.2.2"
|
|
40
36
|
},
|
|
41
37
|
"dependencies": {
|
|
42
|
-
"
|
|
43
|
-
"
|
|
44
|
-
"
|
|
38
|
+
"@tryghost/pro-ship": "1.1.5",
|
|
39
|
+
"handlebars": "4.7.9",
|
|
40
|
+
"lodash": "4.18.1",
|
|
41
|
+
"readdirp": "3.6.0"
|
|
45
42
|
},
|
|
46
43
|
"optionalDependencies": {
|
|
47
|
-
"js-beautify": "^
|
|
44
|
+
"js-beautify": "^2.0.0"
|
|
45
|
+
},
|
|
46
|
+
"scripts": {
|
|
47
|
+
"lint": "oxlint --quiet && oxfmt --check .",
|
|
48
|
+
"lint:fix": "oxlint --fix && oxfmt .",
|
|
49
|
+
"format": "oxfmt .",
|
|
50
|
+
"test": "mocha",
|
|
51
|
+
"posttest": "pnpm lint",
|
|
52
|
+
"coverage": "nyc --check-coverage mocha",
|
|
53
|
+
"preship": "pnpm test",
|
|
54
|
+
"ship": "pro-ship"
|
|
48
55
|
}
|
|
49
|
-
}
|
|
56
|
+
}
|
package/renovate.json
CHANGED
|
@@ -1,6 +1,13 @@
|
|
|
1
1
|
{
|
|
2
|
+
"$schema": "https://docs.renovatebot.com/renovate-schema.json",
|
|
2
3
|
"extends": [
|
|
3
|
-
"
|
|
4
|
-
|
|
4
|
+
"local>TryGhost/renovate-config"
|
|
5
|
+
],
|
|
6
|
+
"packageRules": [
|
|
7
|
+
{
|
|
8
|
+
"description": "Keep pnpm on 10.x while this repo supports Node 20; pnpm 11 requires Node 22.13 or newer.",
|
|
9
|
+
"matchPackageNames": ["pnpm"],
|
|
10
|
+
"allowedVersions": "<11"
|
|
11
|
+
}
|
|
5
12
|
]
|
|
6
13
|
}
|