@rhinostone/swig-core 2.0.0-alpha.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.
@@ -0,0 +1,59 @@
1
+ var fs = require('fs'),
2
+ path = require('path');
3
+
4
+ /**
5
+ * Loads templates from the file system.
6
+ * @alias swig.loaders.fs
7
+ * @example
8
+ * swig.setDefaults({ loader: swig.loaders.fs() });
9
+ * @example
10
+ * // Load Templates from a specific directory (does not require using relative paths in your templates)
11
+ * swig.setDefaults({ loader: swig.loaders.fs(__dirname + '/templates' )});
12
+ * @param {string} [basepath=''] Path to the templates as string. Assigning this value allows you to use semi-absolute paths to templates instead of relative paths.
13
+ * @param {string} [encoding='utf8'] Template encoding
14
+ */
15
+ module.exports = function (basepath, encoding) {
16
+ var ret = {};
17
+
18
+ encoding = encoding || 'utf8';
19
+ basepath = (basepath) ? path.normalize(basepath) : null;
20
+
21
+ /**
22
+ * Resolves <var>to</var> to an absolute path or unique identifier. This is used for building correct, normalized, and absolute paths to a given template.
23
+ * @alias resolve
24
+ * @param {string} to Non-absolute identifier or pathname to a file.
25
+ * @param {string} [from] If given, should attempt to find the <var>to</var> path in relation to this given, known path.
26
+ * @return {string}
27
+ */
28
+ ret.resolve = function (to, from) {
29
+ if (basepath) {
30
+ from = basepath;
31
+ } else {
32
+ from = (from) ? path.dirname(from) : process.cwd();
33
+ }
34
+ return path.resolve(from, to);
35
+ };
36
+
37
+ /**
38
+ * Loads a single template. Given a unique <var>identifier</var> found by the <var>resolve</var> method this should return the given template.
39
+ * @alias load
40
+ * @param {string} identifier Unique identifier of a template (possibly an absolute path).
41
+ * @param {function} [cb] Asynchronous callback function. If not provided, this method should run synchronously.
42
+ * @return {string} Template source string.
43
+ */
44
+ ret.load = function (identifier, cb) {
45
+ if (!fs || (cb && !fs.readFile) || !fs.readFileSync) {
46
+ throw new Error('Unable to find file ' + identifier + ' because there is no filesystem to read from.');
47
+ }
48
+
49
+ identifier = ret.resolve(identifier);
50
+
51
+ if (cb) {
52
+ fs.readFile(identifier, encoding, cb);
53
+ return;
54
+ }
55
+ return fs.readFileSync(identifier, encoding);
56
+ };
57
+
58
+ return ret;
59
+ };
@@ -0,0 +1,53 @@
1
+ /**
2
+ * @namespace TemplateLoader
3
+ * @description Swig is able to accept custom template loaders written by you, so that your templates can come from your favorite storage medium without needing to be part of the core library.
4
+ * A template loader consists of two methods: <var>resolve</var> and <var>load</var>. Each method is used internally by Swig to find and load the source of the template before attempting to parse and compile it.
5
+ * @example
6
+ * // A theoretical memcached loader
7
+ * var path = require('path'),
8
+ * Memcached = require('memcached');
9
+ * function memcachedLoader(locations, options) {
10
+ * var memcached = new Memcached(locations, options);
11
+ * return {
12
+ * resolve: function (to, from) {
13
+ * return path.resolve(from, to);
14
+ * },
15
+ * load: function (identifier, cb) {
16
+ * memcached.get(identifier, function (err, data) {
17
+ * // if (!data) { load from filesystem; }
18
+ * cb(err, data);
19
+ * });
20
+ * }
21
+ * };
22
+ * };
23
+ * // Tell swig about the loader:
24
+ * swig.setDefaults({ loader: memcachedLoader(['localhost:11211']) });
25
+ */
26
+
27
+ /**
28
+ * @function
29
+ * @name resolve
30
+ * @memberof TemplateLoader
31
+ * @description
32
+ * Resolves <var>to</var> to an absolute path or unique identifier. This is used for building correct, normalized, and absolute paths to a given template.
33
+ * @param {string} to Non-absolute identifier or pathname to a file.
34
+ * @param {string} [from] If given, should attempt to find the <var>to</var> path in relation to this given, known path.
35
+ * @return {string}
36
+ */
37
+
38
+ /**
39
+ * @function
40
+ * @name load
41
+ * @memberof TemplateLoader
42
+ * @description
43
+ * Loads a single template. Given a unique <var>identifier</var> found by the <var>resolve</var> method this should return the given template.
44
+ * @param {string} identifier Unique identifier of a template (possibly an absolute path).
45
+ * @param {function} [cb] Asynchronous callback function. If not provided, this method should run synchronously.
46
+ * @return {string} Template source string.
47
+ */
48
+
49
+ /**
50
+ * @private
51
+ */
52
+ exports.fs = require('./filesystem');
53
+ exports.memory = require('./memory');
@@ -0,0 +1,63 @@
1
+ var path = require('path'),
2
+ utils = require('../utils');
3
+
4
+ /**
5
+ * Loads templates from a provided object mapping.
6
+ * @alias swig.loaders.memory
7
+ * @example
8
+ * var templates = {
9
+ * "layout": "{% block content %}{% endblock %}",
10
+ * "home.html": "{% extends 'layout.html' %}{% block content %}...{% endblock %}"
11
+ * };
12
+ * swig.setDefaults({ loader: swig.loaders.memory(templates) });
13
+ *
14
+ * @param {object} mapping Hash object with template paths as keys and template sources as values.
15
+ * @param {string} [basepath] Path to the templates as string. Assigning this value allows you to use semi-absolute paths to templates instead of relative paths.
16
+ */
17
+ module.exports = function (mapping, basepath) {
18
+ var ret = {};
19
+
20
+ basepath = (basepath) ? path.normalize(basepath) : null;
21
+
22
+ /**
23
+ * Resolves <var>to</var> to an absolute path or unique identifier. This is used for building correct, normalized, and absolute paths to a given template.
24
+ * @alias resolve
25
+ * @param {string} to Non-absolute identifier or pathname to a file.
26
+ * @param {string} [from] If given, should attempt to find the <var>to</var> path in relation to this given, known path.
27
+ * @return {string}
28
+ */
29
+ ret.resolve = function (to, from) {
30
+ if (basepath) {
31
+ from = basepath;
32
+ } else {
33
+ from = (from) ? path.dirname(from) : '/';
34
+ }
35
+ return path.resolve(from, to);
36
+ };
37
+
38
+ /**
39
+ * Loads a single template. Given a unique <var>identifier</var> found by the <var>resolve</var> method this should return the given template.
40
+ * @alias load
41
+ * @param {string} identifier Unique identifier of a template (possibly an absolute path).
42
+ * @param {function} [cb] Asynchronous callback function. If not provided, this method should run synchronously.
43
+ * @return {string} Template source string.
44
+ */
45
+ ret.load = function (pathname, cb) {
46
+ var src, paths;
47
+
48
+ paths = [pathname, pathname.replace(/^(\/|\\)/, '')];
49
+
50
+ src = mapping[paths[0]] || mapping[paths[1]];
51
+ if (!src) {
52
+ utils.throwError('Unable to find template "' + pathname + '".');
53
+ }
54
+
55
+ if (cb) {
56
+ cb(null, src);
57
+ return;
58
+ }
59
+ return src;
60
+ };
61
+
62
+ return ret;
63
+ };
@@ -0,0 +1,25 @@
1
+ /**
2
+ * Template-source property access blocklist for CVE-2023-25345.
3
+ *
4
+ * Any identifier that matches this list is rejected at parse time by
5
+ * parser.js, tags/set.js, tags/for.js, tags/macro.js, and tags/import.js.
6
+ * The list covers read access (`{{ __proto__ }}` / `{{ foo.__proto__ }}`
7
+ * / `{{ foo["__proto__"] }}`), write access (`{% set __proto__ = ... %}`
8
+ * / `{% set foo["__proto__"] = ... %}`), loop variables
9
+ * (`{% for __proto__ in items %}`), macro names (`{% macro __proto__() %}`),
10
+ * and import aliases (`{% import "f" as __proto__ %}`).
11
+ *
12
+ * Kept as a shared constant so any future tag that assigns to `_ctx.*`
13
+ * or otherwise exposes an identifier as a property key picks up the
14
+ * full blocklist without drift across copies.
15
+ *
16
+ * See .claude/security.md for the full attack-vector table and the
17
+ * tags/parser checkpoints that consume this list.
18
+ */
19
+
20
+ /**
21
+ * Property names that must never reach `_ctx.<name>` or be accessed
22
+ * via dot / string-bracket notation from template source.
23
+ * @type {string[]}
24
+ */
25
+ exports.dangerousProps = ['__proto__', 'constructor', 'prototype'];