replace-all-mustaches 0.0.1 → 0.0.2
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/README.md +5 -1
- package/dist/index.cjs +135 -0
- package/dist/index.d.cts +39 -0
- package/dist/index.d.ts +39 -0
- package/dist/index.js +94 -0
- package/package.json +1 -1
- package/src/index.ts +1 -1
- package/src/nodes/{renderUntilStable.ts → replaceAllMustaches.ts} +2 -2
- package/tsconfig.json +0 -46
- package/tsup.config.ts +0 -10
package/README.md
CHANGED
package/dist/index.cjs
ADDED
|
@@ -0,0 +1,135 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __create = Object.create;
|
|
3
|
+
var __defProp = Object.defineProperty;
|
|
4
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
5
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
6
|
+
var __getProtoOf = Object.getPrototypeOf;
|
|
7
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
8
|
+
var __export = (target, all) => {
|
|
9
|
+
for (var name in all)
|
|
10
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
11
|
+
};
|
|
12
|
+
var __copyProps = (to, from, except, desc) => {
|
|
13
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
14
|
+
for (let key of __getOwnPropNames(from))
|
|
15
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
16
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
17
|
+
}
|
|
18
|
+
return to;
|
|
19
|
+
};
|
|
20
|
+
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
|
|
21
|
+
// If the importer is in node compatibility mode or this is not an ESM
|
|
22
|
+
// file that has been converted to a CommonJS file using a Babel-
|
|
23
|
+
// compatible transform (i.e. "__esModule" has not been set), then set
|
|
24
|
+
// "default" to the CommonJS "module.exports" for node compatibility.
|
|
25
|
+
isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
|
|
26
|
+
mod
|
|
27
|
+
));
|
|
28
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
29
|
+
|
|
30
|
+
// src/index.ts
|
|
31
|
+
var index_exports = {};
|
|
32
|
+
__export(index_exports, {
|
|
33
|
+
Variable: () => Variable,
|
|
34
|
+
VariableView: () => VariableView,
|
|
35
|
+
hasDuplicates: () => hasDuplicates,
|
|
36
|
+
hasMustacheTags: () => hasMustacheTags,
|
|
37
|
+
renderUntilStable: () => renderUntilStable
|
|
38
|
+
});
|
|
39
|
+
module.exports = __toCommonJS(index_exports);
|
|
40
|
+
|
|
41
|
+
// src/nodes/helperFunctions.ts
|
|
42
|
+
function hasMustacheTags(template) {
|
|
43
|
+
return template.includes("{{") || template.includes("}}");
|
|
44
|
+
}
|
|
45
|
+
function hasDuplicates(arr) {
|
|
46
|
+
return new Set(arr).size !== arr.length;
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
// src/nodes/replaceAllMustaches.ts
|
|
50
|
+
var import_mustache = __toESM(require("mustache"), 1);
|
|
51
|
+
|
|
52
|
+
// src/nodes/Variable.ts
|
|
53
|
+
var Variable = class {
|
|
54
|
+
key;
|
|
55
|
+
value;
|
|
56
|
+
constructor(key, value) {
|
|
57
|
+
this.key = key;
|
|
58
|
+
this.value = value;
|
|
59
|
+
}
|
|
60
|
+
};
|
|
61
|
+
|
|
62
|
+
// src/nodes/VariableView.ts
|
|
63
|
+
var VariableView = class _VariableView {
|
|
64
|
+
static _collection = [];
|
|
65
|
+
static get all() {
|
|
66
|
+
return Object.fromEntries(
|
|
67
|
+
_VariableView._collection.flatMap((view) => Object.entries(view))
|
|
68
|
+
);
|
|
69
|
+
}
|
|
70
|
+
static get allNames() {
|
|
71
|
+
return _VariableView._collection.map((variable) => Object.keys(variable)).flat();
|
|
72
|
+
}
|
|
73
|
+
// [key:string] gives permission for arbitrary string keys
|
|
74
|
+
constructor(...variableValuePairs) {
|
|
75
|
+
variableValuePairs.forEach((pair) => {
|
|
76
|
+
this[pair.key] = pair.value;
|
|
77
|
+
if (_VariableView.allNames.includes(pair.key)) {
|
|
78
|
+
console.warn(`Master variable list already contains the variable ${pair.key} being added by ${this.constructor.name}.`);
|
|
79
|
+
console.trace();
|
|
80
|
+
}
|
|
81
|
+
});
|
|
82
|
+
_VariableView._collection.push(this);
|
|
83
|
+
if (hasDuplicates(variableValuePairs.map((pair) => pair.key))) {
|
|
84
|
+
console.warn(`Duplicated values in ${this.constructor.name}. (And yes, I should and will add where those occur.)`);
|
|
85
|
+
}
|
|
86
|
+
;
|
|
87
|
+
}
|
|
88
|
+
add(...variableValuePair) {
|
|
89
|
+
variableValuePair.forEach((pair) => {
|
|
90
|
+
this[pair.key] = pair.value;
|
|
91
|
+
});
|
|
92
|
+
}
|
|
93
|
+
replace(variableKey, value) {
|
|
94
|
+
this[variableKey] = value;
|
|
95
|
+
}
|
|
96
|
+
};
|
|
97
|
+
|
|
98
|
+
// src/nodes/replaceAllMustaches.ts
|
|
99
|
+
function renderUntilStable(template, view, { maxPasses = 20, detectCycles = true } = {}) {
|
|
100
|
+
let current = template;
|
|
101
|
+
const seen = /* @__PURE__ */ new Set();
|
|
102
|
+
let pass = 0;
|
|
103
|
+
for (pass; pass < maxPasses; pass += 1) {
|
|
104
|
+
if (hasMustacheTags(current)) {
|
|
105
|
+
if (detectCycles) {
|
|
106
|
+
if (seen.has(current)) {
|
|
107
|
+
throw new Error(`Render cycle detected at pass ${pass}: "${current}"`);
|
|
108
|
+
}
|
|
109
|
+
;
|
|
110
|
+
seen.add(current);
|
|
111
|
+
}
|
|
112
|
+
;
|
|
113
|
+
const next = import_mustache.default.render(current, VariableView.all);
|
|
114
|
+
if (next === current) {
|
|
115
|
+
return next;
|
|
116
|
+
}
|
|
117
|
+
;
|
|
118
|
+
current = next;
|
|
119
|
+
} else {
|
|
120
|
+
console.log("passes:", pass);
|
|
121
|
+
return current;
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
;
|
|
125
|
+
console.log("passes:", pass);
|
|
126
|
+
return current;
|
|
127
|
+
}
|
|
128
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
129
|
+
0 && (module.exports = {
|
|
130
|
+
Variable,
|
|
131
|
+
VariableView,
|
|
132
|
+
hasDuplicates,
|
|
133
|
+
hasMustacheTags,
|
|
134
|
+
renderUntilStable
|
|
135
|
+
});
|
package/dist/index.d.cts
ADDED
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Confirm whether there are valid mustache tags remaining in the template string.
|
|
3
|
+
* @param template
|
|
4
|
+
* @returns
|
|
5
|
+
*/
|
|
6
|
+
declare function hasMustacheTags(template: string): boolean;
|
|
7
|
+
declare function hasDuplicates(arr: any[]): boolean;
|
|
8
|
+
|
|
9
|
+
type MustacheValue = string | string[] | Function;
|
|
10
|
+
/**
|
|
11
|
+
* A key-value pair for a variable name and its value.
|
|
12
|
+
*/
|
|
13
|
+
declare class Variable {
|
|
14
|
+
key: string;
|
|
15
|
+
value: MustacheValue;
|
|
16
|
+
constructor(key: string, value: MustacheValue);
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
/**
|
|
20
|
+
* A generic class to create a view (the context for a Mustache.render() call). This class's _collection property holds all the names in any subsequently created variable registry via the allKeys getter.
|
|
21
|
+
* @todo Prevent duplicates
|
|
22
|
+
*/
|
|
23
|
+
declare class VariableView {
|
|
24
|
+
private static _collection;
|
|
25
|
+
static get all(): Record<string, MustacheValue>;
|
|
26
|
+
static get allNames(): string[];
|
|
27
|
+
[key: string]: MustacheValue;
|
|
28
|
+
constructor(...variableValuePairs: Variable[]);
|
|
29
|
+
add(...variableValuePair: Variable[]): void;
|
|
30
|
+
replace(variableKey: string, value: string | Function): void;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
type replaceAllMustaches = {
|
|
34
|
+
maxPasses?: number;
|
|
35
|
+
detectCycles?: boolean;
|
|
36
|
+
};
|
|
37
|
+
declare function renderUntilStable(template: string, view: VariableView, { maxPasses, detectCycles }?: replaceAllMustaches): string;
|
|
38
|
+
|
|
39
|
+
export { type MustacheValue, Variable, VariableView, hasDuplicates, hasMustacheTags, renderUntilStable };
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Confirm whether there are valid mustache tags remaining in the template string.
|
|
3
|
+
* @param template
|
|
4
|
+
* @returns
|
|
5
|
+
*/
|
|
6
|
+
declare function hasMustacheTags(template: string): boolean;
|
|
7
|
+
declare function hasDuplicates(arr: any[]): boolean;
|
|
8
|
+
|
|
9
|
+
type MustacheValue = string | string[] | Function;
|
|
10
|
+
/**
|
|
11
|
+
* A key-value pair for a variable name and its value.
|
|
12
|
+
*/
|
|
13
|
+
declare class Variable {
|
|
14
|
+
key: string;
|
|
15
|
+
value: MustacheValue;
|
|
16
|
+
constructor(key: string, value: MustacheValue);
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
/**
|
|
20
|
+
* A generic class to create a view (the context for a Mustache.render() call). This class's _collection property holds all the names in any subsequently created variable registry via the allKeys getter.
|
|
21
|
+
* @todo Prevent duplicates
|
|
22
|
+
*/
|
|
23
|
+
declare class VariableView {
|
|
24
|
+
private static _collection;
|
|
25
|
+
static get all(): Record<string, MustacheValue>;
|
|
26
|
+
static get allNames(): string[];
|
|
27
|
+
[key: string]: MustacheValue;
|
|
28
|
+
constructor(...variableValuePairs: Variable[]);
|
|
29
|
+
add(...variableValuePair: Variable[]): void;
|
|
30
|
+
replace(variableKey: string, value: string | Function): void;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
type replaceAllMustaches = {
|
|
34
|
+
maxPasses?: number;
|
|
35
|
+
detectCycles?: boolean;
|
|
36
|
+
};
|
|
37
|
+
declare function renderUntilStable(template: string, view: VariableView, { maxPasses, detectCycles }?: replaceAllMustaches): string;
|
|
38
|
+
|
|
39
|
+
export { type MustacheValue, Variable, VariableView, hasDuplicates, hasMustacheTags, renderUntilStable };
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
// src/nodes/helperFunctions.ts
|
|
2
|
+
function hasMustacheTags(template) {
|
|
3
|
+
return template.includes("{{") || template.includes("}}");
|
|
4
|
+
}
|
|
5
|
+
function hasDuplicates(arr) {
|
|
6
|
+
return new Set(arr).size !== arr.length;
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
// src/nodes/replaceAllMustaches.ts
|
|
10
|
+
import Mustache from "mustache";
|
|
11
|
+
|
|
12
|
+
// src/nodes/Variable.ts
|
|
13
|
+
var Variable = class {
|
|
14
|
+
key;
|
|
15
|
+
value;
|
|
16
|
+
constructor(key, value) {
|
|
17
|
+
this.key = key;
|
|
18
|
+
this.value = value;
|
|
19
|
+
}
|
|
20
|
+
};
|
|
21
|
+
|
|
22
|
+
// src/nodes/VariableView.ts
|
|
23
|
+
var VariableView = class _VariableView {
|
|
24
|
+
static _collection = [];
|
|
25
|
+
static get all() {
|
|
26
|
+
return Object.fromEntries(
|
|
27
|
+
_VariableView._collection.flatMap((view) => Object.entries(view))
|
|
28
|
+
);
|
|
29
|
+
}
|
|
30
|
+
static get allNames() {
|
|
31
|
+
return _VariableView._collection.map((variable) => Object.keys(variable)).flat();
|
|
32
|
+
}
|
|
33
|
+
// [key:string] gives permission for arbitrary string keys
|
|
34
|
+
constructor(...variableValuePairs) {
|
|
35
|
+
variableValuePairs.forEach((pair) => {
|
|
36
|
+
this[pair.key] = pair.value;
|
|
37
|
+
if (_VariableView.allNames.includes(pair.key)) {
|
|
38
|
+
console.warn(`Master variable list already contains the variable ${pair.key} being added by ${this.constructor.name}.`);
|
|
39
|
+
console.trace();
|
|
40
|
+
}
|
|
41
|
+
});
|
|
42
|
+
_VariableView._collection.push(this);
|
|
43
|
+
if (hasDuplicates(variableValuePairs.map((pair) => pair.key))) {
|
|
44
|
+
console.warn(`Duplicated values in ${this.constructor.name}. (And yes, I should and will add where those occur.)`);
|
|
45
|
+
}
|
|
46
|
+
;
|
|
47
|
+
}
|
|
48
|
+
add(...variableValuePair) {
|
|
49
|
+
variableValuePair.forEach((pair) => {
|
|
50
|
+
this[pair.key] = pair.value;
|
|
51
|
+
});
|
|
52
|
+
}
|
|
53
|
+
replace(variableKey, value) {
|
|
54
|
+
this[variableKey] = value;
|
|
55
|
+
}
|
|
56
|
+
};
|
|
57
|
+
|
|
58
|
+
// src/nodes/replaceAllMustaches.ts
|
|
59
|
+
function renderUntilStable(template, view, { maxPasses = 20, detectCycles = true } = {}) {
|
|
60
|
+
let current = template;
|
|
61
|
+
const seen = /* @__PURE__ */ new Set();
|
|
62
|
+
let pass = 0;
|
|
63
|
+
for (pass; pass < maxPasses; pass += 1) {
|
|
64
|
+
if (hasMustacheTags(current)) {
|
|
65
|
+
if (detectCycles) {
|
|
66
|
+
if (seen.has(current)) {
|
|
67
|
+
throw new Error(`Render cycle detected at pass ${pass}: "${current}"`);
|
|
68
|
+
}
|
|
69
|
+
;
|
|
70
|
+
seen.add(current);
|
|
71
|
+
}
|
|
72
|
+
;
|
|
73
|
+
const next = Mustache.render(current, VariableView.all);
|
|
74
|
+
if (next === current) {
|
|
75
|
+
return next;
|
|
76
|
+
}
|
|
77
|
+
;
|
|
78
|
+
current = next;
|
|
79
|
+
} else {
|
|
80
|
+
console.log("passes:", pass);
|
|
81
|
+
return current;
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
;
|
|
85
|
+
console.log("passes:", pass);
|
|
86
|
+
return current;
|
|
87
|
+
}
|
|
88
|
+
export {
|
|
89
|
+
Variable,
|
|
90
|
+
VariableView,
|
|
91
|
+
hasDuplicates,
|
|
92
|
+
hasMustacheTags,
|
|
93
|
+
renderUntilStable
|
|
94
|
+
};
|
package/package.json
CHANGED
package/src/index.ts
CHANGED
|
@@ -2,7 +2,7 @@ import Mustache from "mustache";
|
|
|
2
2
|
import { VariableView } from "./VariableView";
|
|
3
3
|
import { hasMustacheTags } from "./helperFunctions";
|
|
4
4
|
|
|
5
|
-
type
|
|
5
|
+
type replaceAllMustaches = {
|
|
6
6
|
maxPasses?: number;
|
|
7
7
|
detectCycles?: boolean;
|
|
8
8
|
};
|
|
@@ -10,7 +10,7 @@ type RenderLoopOptions = {
|
|
|
10
10
|
export function renderUntilStable(
|
|
11
11
|
template: string,
|
|
12
12
|
view: VariableView,
|
|
13
|
-
{ maxPasses = 20, detectCycles = true }:
|
|
13
|
+
{ maxPasses = 20, detectCycles = true }: replaceAllMustaches = {},
|
|
14
14
|
): string {
|
|
15
15
|
let current = template;
|
|
16
16
|
const seen = new Set<string>();
|
package/tsconfig.json
DELETED
|
@@ -1,46 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
// Visit https://aka.ms/tsconfig to read more about this file
|
|
3
|
-
"compilerOptions": {
|
|
4
|
-
// File Layout
|
|
5
|
-
// "rootDir": "./src",
|
|
6
|
-
// "outDir": "./dist",
|
|
7
|
-
|
|
8
|
-
// Environment Settings
|
|
9
|
-
// See also https://aka.ms/tsconfig/module
|
|
10
|
-
"module": "es2022",
|
|
11
|
-
"target": "es2022",
|
|
12
|
-
"types": [],
|
|
13
|
-
// For nodejs:
|
|
14
|
-
// "lib": ["esnext"],
|
|
15
|
-
// "types": ["node"],
|
|
16
|
-
// and npm install -D @types/node
|
|
17
|
-
|
|
18
|
-
// Other Outputs
|
|
19
|
-
"sourceMap": true,
|
|
20
|
-
"declaration": true,
|
|
21
|
-
"declarationMap": true,
|
|
22
|
-
|
|
23
|
-
// Stricter Typechecking Options
|
|
24
|
-
"noUncheckedIndexedAccess": true,
|
|
25
|
-
"exactOptionalPropertyTypes": true,
|
|
26
|
-
|
|
27
|
-
// Style Options
|
|
28
|
-
// "noImplicitReturns": true,
|
|
29
|
-
// "noImplicitOverride": true,
|
|
30
|
-
// "noUnusedLocals": true,
|
|
31
|
-
// "noUnusedParameters": true,
|
|
32
|
-
// "noFallthroughCasesInSwitch": true,
|
|
33
|
-
// "noPropertyAccessFromIndexSignature": true,
|
|
34
|
-
|
|
35
|
-
// Recommended Options
|
|
36
|
-
"strict": true,
|
|
37
|
-
"jsx": "react-jsx",
|
|
38
|
-
"verbatimModuleSyntax": true,
|
|
39
|
-
"isolatedModules": true,
|
|
40
|
-
"noUncheckedSideEffectImports": true,
|
|
41
|
-
"moduleDetection": "force",
|
|
42
|
-
"skipLibCheck": true,
|
|
43
|
-
},
|
|
44
|
-
"include": ["src"],
|
|
45
|
-
"exclude": ["node_modules"]
|
|
46
|
-
}
|