@ucdjs/release-scripts 0.1.0-beta.3 → 0.1.0-beta.31
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/dist/eta-BV8TCRDW.mjs +481 -0
- package/dist/index.d.mts +58 -113
- package/dist/index.mjs +1476 -756
- package/package.json +20 -10
|
@@ -0,0 +1,481 @@
|
|
|
1
|
+
import * as fs from "node:fs";
|
|
2
|
+
import * as path$2 from "node:path";
|
|
3
|
+
|
|
4
|
+
//#region node_modules/.pnpm/eta@4.5.1/node_modules/eta/dist/index.mjs
|
|
5
|
+
var EtaError = class extends Error {
|
|
6
|
+
constructor(message) {
|
|
7
|
+
super(message);
|
|
8
|
+
this.name = "Eta Error";
|
|
9
|
+
}
|
|
10
|
+
};
|
|
11
|
+
var EtaParseError = class extends EtaError {
|
|
12
|
+
constructor(message) {
|
|
13
|
+
super(message);
|
|
14
|
+
this.name = "EtaParser Error";
|
|
15
|
+
}
|
|
16
|
+
};
|
|
17
|
+
var EtaRuntimeError = class extends EtaError {
|
|
18
|
+
constructor(message) {
|
|
19
|
+
super(message);
|
|
20
|
+
this.name = "EtaRuntime Error";
|
|
21
|
+
}
|
|
22
|
+
};
|
|
23
|
+
var EtaFileResolutionError = class extends EtaError {
|
|
24
|
+
constructor(message) {
|
|
25
|
+
super(message);
|
|
26
|
+
this.name = "EtaFileResolution Error";
|
|
27
|
+
}
|
|
28
|
+
};
|
|
29
|
+
var EtaNameResolutionError = class extends EtaError {
|
|
30
|
+
constructor(message) {
|
|
31
|
+
super(message);
|
|
32
|
+
this.name = "EtaNameResolution Error";
|
|
33
|
+
}
|
|
34
|
+
};
|
|
35
|
+
/**
|
|
36
|
+
* Throws an EtaError with a nicely formatted error and message showing where in the template the error occurred.
|
|
37
|
+
*/
|
|
38
|
+
function ParseErr(message, str, indx) {
|
|
39
|
+
const whitespace = str.slice(0, indx).split(/\n/);
|
|
40
|
+
const lineNo = whitespace.length;
|
|
41
|
+
const colNo = whitespace[lineNo - 1].length + 1;
|
|
42
|
+
message += " at line " + lineNo + " col " + colNo + ":\n\n " + str.split(/\n/)[lineNo - 1] + "\n " + Array(colNo).join(" ") + "^";
|
|
43
|
+
throw new EtaParseError(message);
|
|
44
|
+
}
|
|
45
|
+
function RuntimeErr(originalError, str, lineNo, path$1) {
|
|
46
|
+
const lines = str.split("\n");
|
|
47
|
+
const start = Math.max(lineNo - 3, 0);
|
|
48
|
+
const end = Math.min(lines.length, lineNo + 3);
|
|
49
|
+
const filename = path$1;
|
|
50
|
+
const context = lines.slice(start, end).map((line, i) => {
|
|
51
|
+
const curr = i + start + 1;
|
|
52
|
+
return (curr === lineNo ? " >> " : " ") + curr + "| " + line;
|
|
53
|
+
}).join("\n");
|
|
54
|
+
const err = new EtaRuntimeError((filename ? filename + ":" + lineNo + "\n" : "line " + lineNo + "\n") + context + "\n\n" + originalError.message);
|
|
55
|
+
err.name = originalError.name;
|
|
56
|
+
err.cause = originalError;
|
|
57
|
+
throw err;
|
|
58
|
+
}
|
|
59
|
+
function readFile(path$1) {
|
|
60
|
+
let res = "";
|
|
61
|
+
try {
|
|
62
|
+
res = fs.readFileSync(path$1, "utf8");
|
|
63
|
+
} catch (err) {
|
|
64
|
+
if (err?.code === "ENOENT") throw new EtaFileResolutionError(`Could not find template: ${path$1}`);
|
|
65
|
+
else throw err;
|
|
66
|
+
}
|
|
67
|
+
return res;
|
|
68
|
+
}
|
|
69
|
+
function resolvePath(templatePath, options) {
|
|
70
|
+
let resolvedFilePath = "";
|
|
71
|
+
const views = this.config.views;
|
|
72
|
+
if (!views) throw new EtaFileResolutionError("Views directory is not defined");
|
|
73
|
+
const baseFilePath = options?.filepath;
|
|
74
|
+
const defaultExtension = this.config.defaultExtension === void 0 ? ".eta" : this.config.defaultExtension;
|
|
75
|
+
const cacheIndex = JSON.stringify({
|
|
76
|
+
filename: baseFilePath,
|
|
77
|
+
path: templatePath,
|
|
78
|
+
views: this.config.views
|
|
79
|
+
});
|
|
80
|
+
templatePath += path$2.extname(templatePath) ? "" : defaultExtension;
|
|
81
|
+
if (baseFilePath) {
|
|
82
|
+
if (this.config.cacheFilepaths && this.filepathCache[cacheIndex]) return this.filepathCache[cacheIndex];
|
|
83
|
+
if (absolutePathRegExp.exec(templatePath)?.length) {
|
|
84
|
+
const formattedPath = templatePath.replace(/^\/*|^\\*/, "");
|
|
85
|
+
resolvedFilePath = path$2.join(views, formattedPath);
|
|
86
|
+
} else resolvedFilePath = path$2.join(path$2.dirname(baseFilePath), templatePath);
|
|
87
|
+
} else resolvedFilePath = path$2.join(views, templatePath);
|
|
88
|
+
if (dirIsChild(views, resolvedFilePath)) {
|
|
89
|
+
if (baseFilePath && this.config.cacheFilepaths) this.filepathCache[cacheIndex] = resolvedFilePath;
|
|
90
|
+
return resolvedFilePath;
|
|
91
|
+
} else throw new EtaFileResolutionError(`Template '${templatePath}' is not in the views directory`);
|
|
92
|
+
}
|
|
93
|
+
function dirIsChild(parent, dir) {
|
|
94
|
+
const relative = path$2.relative(parent, dir);
|
|
95
|
+
return relative && !relative.startsWith("..") && !path$2.isAbsolute(relative);
|
|
96
|
+
}
|
|
97
|
+
const absolutePathRegExp = /^\\|^\//;
|
|
98
|
+
/* istanbul ignore next */
|
|
99
|
+
const AsyncFunction = (async () => {}).constructor;
|
|
100
|
+
/**
|
|
101
|
+
* Takes a template string and returns a template function that can be called with (data, config)
|
|
102
|
+
*
|
|
103
|
+
* @param str - The template string
|
|
104
|
+
* @param config - A custom configuration object (optional)
|
|
105
|
+
*/
|
|
106
|
+
function compile(str, options) {
|
|
107
|
+
const config = this.config;
|
|
108
|
+
const ctor = options?.async ? AsyncFunction : Function;
|
|
109
|
+
try {
|
|
110
|
+
return new ctor(config.varName, "options", this.compileToString.call(this, str, options));
|
|
111
|
+
} catch (e) {
|
|
112
|
+
if (e instanceof SyntaxError) throw new EtaParseError("Bad template syntax\n\n" + e.message + "\n" + Array(e.message.length + 1).join("=") + "\n" + this.compileToString.call(this, str, options) + "\n");
|
|
113
|
+
else throw e;
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
/**
|
|
117
|
+
* Compiles a template string to a function string. Most often users just use `compile()`, which calls `compileToString` and creates a new function using the result
|
|
118
|
+
*/
|
|
119
|
+
function compileToString(str, options) {
|
|
120
|
+
const config = this.config;
|
|
121
|
+
const isAsync = options?.async;
|
|
122
|
+
const compileBody$1 = this.compileBody;
|
|
123
|
+
const buffer = this.parse.call(this, str);
|
|
124
|
+
let res = `${config.functionHeader}
|
|
125
|
+
let include = (__eta_t, __eta_d) => this.render(__eta_t, {...${config.varName}, ...(__eta_d ?? {})}, options);
|
|
126
|
+
let includeAsync = (__eta_t, __eta_d) => this.renderAsync(__eta_t, {...${config.varName}, ...(__eta_d ?? {})}, options);
|
|
127
|
+
|
|
128
|
+
let __eta = {res: "", e: this.config.escapeFunction, f: this.config.filterFunction${config.debug ? ", line: 1, templateStr: \"" + str.replace(/\\|"/g, "\\$&").replace(/\r\n|\n|\r/g, "\\n") + "\"" : ""}};
|
|
129
|
+
|
|
130
|
+
function layout(path, data) {
|
|
131
|
+
__eta.layout = path;
|
|
132
|
+
__eta.layoutData = data;
|
|
133
|
+
}${config.debug ? "try {" : ""}${config.useWith ? "with(" + config.varName + "||{}){" : ""}
|
|
134
|
+
|
|
135
|
+
function ${config.outputFunctionName}(s){__eta.res+=s;}
|
|
136
|
+
|
|
137
|
+
${compileBody$1.call(this, buffer)}
|
|
138
|
+
if (__eta.layout) {
|
|
139
|
+
__eta.res = ${isAsync ? "await includeAsync" : "include"} (__eta.layout, {...${config.varName}, body: __eta.res, ...__eta.layoutData});
|
|
140
|
+
}
|
|
141
|
+
${config.useWith ? "}" : ""}${config.debug ? "} catch (e) { this.RuntimeErr(e, __eta.templateStr, __eta.line, options.filepath) }" : ""}
|
|
142
|
+
return __eta.res;
|
|
143
|
+
`;
|
|
144
|
+
if (config.plugins) for (let i = 0; i < config.plugins.length; i++) {
|
|
145
|
+
const plugin = config.plugins[i];
|
|
146
|
+
if (plugin.processFnString) res = plugin.processFnString(res, config);
|
|
147
|
+
}
|
|
148
|
+
return res;
|
|
149
|
+
}
|
|
150
|
+
/**
|
|
151
|
+
* Loops through the AST generated by `parse` and transform each item into JS calls
|
|
152
|
+
*
|
|
153
|
+
* **Example**
|
|
154
|
+
*
|
|
155
|
+
* ```js
|
|
156
|
+
* let templateAST = ['Hi ', { val: 'it.name', t: 'i' }]
|
|
157
|
+
* compileBody.call(Eta, templateAST)
|
|
158
|
+
* // => "__eta.res+='Hi '\n__eta.res+=__eta.e(it.name)\n"
|
|
159
|
+
* ```
|
|
160
|
+
*/
|
|
161
|
+
function compileBody(buff) {
|
|
162
|
+
const config = this.config;
|
|
163
|
+
let i = 0;
|
|
164
|
+
const buffLength = buff.length;
|
|
165
|
+
let returnStr = "";
|
|
166
|
+
for (; i < buffLength; i++) {
|
|
167
|
+
const currentBlock = buff[i];
|
|
168
|
+
if (typeof currentBlock === "string") returnStr += "__eta.res+='" + currentBlock + "';\n";
|
|
169
|
+
else {
|
|
170
|
+
const type = currentBlock.t;
|
|
171
|
+
let content = currentBlock.val || "";
|
|
172
|
+
if (config.debug) returnStr += "__eta.line=" + currentBlock.lineNo + "\n";
|
|
173
|
+
if (type === "r") {
|
|
174
|
+
if (config.autoFilter) content = "__eta.f(" + content + ")";
|
|
175
|
+
returnStr += "__eta.res+=" + content + ";\n";
|
|
176
|
+
} else if (type === "i") {
|
|
177
|
+
if (config.autoFilter) content = "__eta.f(" + content + ")";
|
|
178
|
+
if (config.autoEscape) content = "__eta.e(" + content + ")";
|
|
179
|
+
returnStr += "__eta.res+=" + content + ";\n";
|
|
180
|
+
} else if (type === "e") returnStr += content + "\n";
|
|
181
|
+
}
|
|
182
|
+
}
|
|
183
|
+
return returnStr;
|
|
184
|
+
}
|
|
185
|
+
/**
|
|
186
|
+
* Takes a string within a template and trims it, based on the preceding tag's whitespace control and `config.autoTrim`
|
|
187
|
+
*/
|
|
188
|
+
function trimWS(str, config, wsLeft, wsRight) {
|
|
189
|
+
let leftTrim;
|
|
190
|
+
let rightTrim;
|
|
191
|
+
if (Array.isArray(config.autoTrim)) {
|
|
192
|
+
leftTrim = config.autoTrim[1];
|
|
193
|
+
rightTrim = config.autoTrim[0];
|
|
194
|
+
} else leftTrim = rightTrim = config.autoTrim;
|
|
195
|
+
if (wsLeft || wsLeft === false) leftTrim = wsLeft;
|
|
196
|
+
if (wsRight || wsRight === false) rightTrim = wsRight;
|
|
197
|
+
if (!rightTrim && !leftTrim) return str;
|
|
198
|
+
if (leftTrim === "slurp" && rightTrim === "slurp") return str.trim();
|
|
199
|
+
if (leftTrim === "_" || leftTrim === "slurp") str = str.trimStart();
|
|
200
|
+
else if (leftTrim === "-" || leftTrim === "nl") str = str.replace(/^(?:\r\n|\n|\r)/, "");
|
|
201
|
+
if (rightTrim === "_" || rightTrim === "slurp") str = str.trimEnd();
|
|
202
|
+
else if (rightTrim === "-" || rightTrim === "nl") str = str.replace(/(?:\r\n|\n|\r)$/, "");
|
|
203
|
+
return str;
|
|
204
|
+
}
|
|
205
|
+
/**
|
|
206
|
+
* A map of special HTML characters to their XML-escaped equivalents
|
|
207
|
+
*/
|
|
208
|
+
const escMap = {
|
|
209
|
+
"&": "&",
|
|
210
|
+
"<": "<",
|
|
211
|
+
">": ">",
|
|
212
|
+
"\"": """,
|
|
213
|
+
"'": "'"
|
|
214
|
+
};
|
|
215
|
+
function replaceChar(s) {
|
|
216
|
+
return escMap[s];
|
|
217
|
+
}
|
|
218
|
+
/**
|
|
219
|
+
* XML-escapes an input value after converting it to a string
|
|
220
|
+
*
|
|
221
|
+
* @param str - Input value (usually a string)
|
|
222
|
+
* @returns XML-escaped string
|
|
223
|
+
*/
|
|
224
|
+
function XMLEscape(str) {
|
|
225
|
+
const newStr = String(str);
|
|
226
|
+
if (/[&<>"']/.test(newStr)) return newStr.replace(/[&<>"']/g, replaceChar);
|
|
227
|
+
else return newStr;
|
|
228
|
+
}
|
|
229
|
+
/** Eta's base (global) configuration */
|
|
230
|
+
const defaultConfig = {
|
|
231
|
+
autoEscape: true,
|
|
232
|
+
autoFilter: false,
|
|
233
|
+
autoTrim: [false, "nl"],
|
|
234
|
+
cache: false,
|
|
235
|
+
cacheFilepaths: true,
|
|
236
|
+
debug: false,
|
|
237
|
+
escapeFunction: XMLEscape,
|
|
238
|
+
filterFunction: (val) => String(val),
|
|
239
|
+
outputFunctionName: "output",
|
|
240
|
+
functionHeader: "",
|
|
241
|
+
parse: {
|
|
242
|
+
exec: "",
|
|
243
|
+
interpolate: "=",
|
|
244
|
+
raw: "~"
|
|
245
|
+
},
|
|
246
|
+
plugins: [],
|
|
247
|
+
rmWhitespace: false,
|
|
248
|
+
tags: ["<%", "%>"],
|
|
249
|
+
useWith: false,
|
|
250
|
+
varName: "it",
|
|
251
|
+
defaultExtension: ".eta"
|
|
252
|
+
};
|
|
253
|
+
const templateLitReg = /`(?:\\[\s\S]|\${(?:[^{}]|{(?:[^{}]|{[^}]*})*})*}|(?!\${)[^\\`])*`/g;
|
|
254
|
+
const singleQuoteReg = /'(?:\\[\s\w"'\\`]|[^\n\r'\\])*?'/g;
|
|
255
|
+
const doubleQuoteReg = /"(?:\\[\s\w"'\\`]|[^\n\r"\\])*?"/g;
|
|
256
|
+
/** Escape special regular expression characters inside a string */
|
|
257
|
+
function escapeRegExp(string) {
|
|
258
|
+
return string.replace(/[.*+\-?^${}()|[\]\\]/g, "\\$&");
|
|
259
|
+
}
|
|
260
|
+
function getLineNo(str, index) {
|
|
261
|
+
return str.slice(0, index).split("\n").length;
|
|
262
|
+
}
|
|
263
|
+
function parse(str) {
|
|
264
|
+
const config = this.config;
|
|
265
|
+
let buffer = [];
|
|
266
|
+
let trimLeftOfNextStr = false;
|
|
267
|
+
let lastIndex = 0;
|
|
268
|
+
const parseOptions = config.parse;
|
|
269
|
+
if (config.plugins) for (let i = 0; i < config.plugins.length; i++) {
|
|
270
|
+
const plugin = config.plugins[i];
|
|
271
|
+
if (plugin.processTemplate) str = plugin.processTemplate(str, config);
|
|
272
|
+
}
|
|
273
|
+
if (config.rmWhitespace) str = str.replace(/[\r\n]+/g, "\n").replace(/^\s+|\s+$/gm, "");
|
|
274
|
+
templateLitReg.lastIndex = 0;
|
|
275
|
+
singleQuoteReg.lastIndex = 0;
|
|
276
|
+
doubleQuoteReg.lastIndex = 0;
|
|
277
|
+
function pushString(strng, shouldTrimRightOfString) {
|
|
278
|
+
if (strng) {
|
|
279
|
+
strng = trimWS(strng, config, trimLeftOfNextStr, shouldTrimRightOfString);
|
|
280
|
+
if (strng) {
|
|
281
|
+
strng = strng.replace(/\\|'/g, "\\$&").replace(/\r\n|\n|\r/g, "\\n");
|
|
282
|
+
buffer.push(strng);
|
|
283
|
+
}
|
|
284
|
+
}
|
|
285
|
+
}
|
|
286
|
+
const prefixes = [
|
|
287
|
+
parseOptions.exec,
|
|
288
|
+
parseOptions.interpolate,
|
|
289
|
+
parseOptions.raw
|
|
290
|
+
].reduce((accumulator, prefix) => {
|
|
291
|
+
if (accumulator && prefix) return accumulator + "|" + escapeRegExp(prefix);
|
|
292
|
+
else if (prefix) return escapeRegExp(prefix);
|
|
293
|
+
else return accumulator;
|
|
294
|
+
}, "");
|
|
295
|
+
const parseOpenReg = new RegExp(escapeRegExp(config.tags[0]) + "(-|_)?\\s*(" + prefixes + ")?\\s*", "g");
|
|
296
|
+
const parseCloseReg = new RegExp("'|\"|`|\\/\\*|(\\s*(-|_)?" + escapeRegExp(config.tags[1]) + ")", "g");
|
|
297
|
+
let m;
|
|
298
|
+
while (m = parseOpenReg.exec(str)) {
|
|
299
|
+
const precedingString = str.slice(lastIndex, m.index);
|
|
300
|
+
lastIndex = m[0].length + m.index;
|
|
301
|
+
const wsLeft = m[1];
|
|
302
|
+
const prefix = m[2] || "";
|
|
303
|
+
pushString(precedingString, wsLeft);
|
|
304
|
+
parseCloseReg.lastIndex = lastIndex;
|
|
305
|
+
let closeTag;
|
|
306
|
+
let currentObj = false;
|
|
307
|
+
while (closeTag = parseCloseReg.exec(str)) if (closeTag[1]) {
|
|
308
|
+
const content = str.slice(lastIndex, closeTag.index);
|
|
309
|
+
parseOpenReg.lastIndex = lastIndex = parseCloseReg.lastIndex;
|
|
310
|
+
trimLeftOfNextStr = closeTag[2];
|
|
311
|
+
currentObj = {
|
|
312
|
+
t: prefix === parseOptions.exec ? "e" : prefix === parseOptions.raw ? "r" : prefix === parseOptions.interpolate ? "i" : "",
|
|
313
|
+
val: content
|
|
314
|
+
};
|
|
315
|
+
break;
|
|
316
|
+
} else {
|
|
317
|
+
const char = closeTag[0];
|
|
318
|
+
if (char === "/*") {
|
|
319
|
+
const commentCloseInd = str.indexOf("*/", parseCloseReg.lastIndex);
|
|
320
|
+
if (commentCloseInd === -1) ParseErr("unclosed comment", str, closeTag.index);
|
|
321
|
+
parseCloseReg.lastIndex = commentCloseInd;
|
|
322
|
+
} else if (char === "'") {
|
|
323
|
+
singleQuoteReg.lastIndex = closeTag.index;
|
|
324
|
+
if (singleQuoteReg.exec(str)) parseCloseReg.lastIndex = singleQuoteReg.lastIndex;
|
|
325
|
+
else ParseErr("unclosed string", str, closeTag.index);
|
|
326
|
+
} else if (char === "\"") {
|
|
327
|
+
doubleQuoteReg.lastIndex = closeTag.index;
|
|
328
|
+
if (doubleQuoteReg.exec(str)) parseCloseReg.lastIndex = doubleQuoteReg.lastIndex;
|
|
329
|
+
else ParseErr("unclosed string", str, closeTag.index);
|
|
330
|
+
} else if (char === "`") {
|
|
331
|
+
templateLitReg.lastIndex = closeTag.index;
|
|
332
|
+
if (templateLitReg.exec(str)) parseCloseReg.lastIndex = templateLitReg.lastIndex;
|
|
333
|
+
else ParseErr("unclosed string", str, closeTag.index);
|
|
334
|
+
}
|
|
335
|
+
}
|
|
336
|
+
if (currentObj) {
|
|
337
|
+
if (config.debug) currentObj.lineNo = getLineNo(str, m.index);
|
|
338
|
+
buffer.push(currentObj);
|
|
339
|
+
} else ParseErr("unclosed tag", str, m.index);
|
|
340
|
+
}
|
|
341
|
+
pushString(str.slice(lastIndex, str.length), false);
|
|
342
|
+
if (config.plugins) for (let i = 0; i < config.plugins.length; i++) {
|
|
343
|
+
const plugin = config.plugins[i];
|
|
344
|
+
if (plugin.processAST) buffer = plugin.processAST(buffer, config);
|
|
345
|
+
}
|
|
346
|
+
return buffer;
|
|
347
|
+
}
|
|
348
|
+
function handleCache(template, options) {
|
|
349
|
+
const templateStore = options?.async ? this.templatesAsync : this.templatesSync;
|
|
350
|
+
if (this.resolvePath && this.readFile && !template.startsWith("@")) {
|
|
351
|
+
const templatePath = options.filepath;
|
|
352
|
+
const cachedTemplate = templateStore.get(templatePath);
|
|
353
|
+
if (this.config.cache && cachedTemplate) return cachedTemplate;
|
|
354
|
+
else {
|
|
355
|
+
const templateString = this.readFile(templatePath);
|
|
356
|
+
const templateFn = this.compile(templateString, options);
|
|
357
|
+
if (this.config.cache) templateStore.define(templatePath, templateFn);
|
|
358
|
+
return templateFn;
|
|
359
|
+
}
|
|
360
|
+
} else {
|
|
361
|
+
const cachedTemplate = templateStore.get(template);
|
|
362
|
+
if (cachedTemplate) return cachedTemplate;
|
|
363
|
+
else throw new EtaNameResolutionError(`Failed to get template '${template}'`);
|
|
364
|
+
}
|
|
365
|
+
}
|
|
366
|
+
function render(template, data, meta) {
|
|
367
|
+
let templateFn;
|
|
368
|
+
const options = {
|
|
369
|
+
...meta,
|
|
370
|
+
async: false
|
|
371
|
+
};
|
|
372
|
+
if (typeof template === "string") {
|
|
373
|
+
if (this.resolvePath && this.readFile && !template.startsWith("@")) options.filepath = this.resolvePath(template, options);
|
|
374
|
+
templateFn = handleCache.call(this, template, options);
|
|
375
|
+
} else templateFn = template;
|
|
376
|
+
return templateFn.call(this, data, options);
|
|
377
|
+
}
|
|
378
|
+
function renderAsync(template, data, meta) {
|
|
379
|
+
let templateFn;
|
|
380
|
+
const options = {
|
|
381
|
+
...meta,
|
|
382
|
+
async: true
|
|
383
|
+
};
|
|
384
|
+
if (typeof template === "string") {
|
|
385
|
+
if (this.resolvePath && this.readFile && !template.startsWith("@")) options.filepath = this.resolvePath(template, options);
|
|
386
|
+
templateFn = handleCache.call(this, template, options);
|
|
387
|
+
} else templateFn = template;
|
|
388
|
+
const res = templateFn.call(this, data, options);
|
|
389
|
+
return Promise.resolve(res);
|
|
390
|
+
}
|
|
391
|
+
function renderString(template, data) {
|
|
392
|
+
const templateFn = this.compile(template, { async: false });
|
|
393
|
+
return render.call(this, templateFn, data);
|
|
394
|
+
}
|
|
395
|
+
function renderStringAsync(template, data) {
|
|
396
|
+
const templateFn = this.compile(template, { async: true });
|
|
397
|
+
return renderAsync.call(this, templateFn, data);
|
|
398
|
+
}
|
|
399
|
+
/**
|
|
400
|
+
* Handles storage and accessing of values
|
|
401
|
+
*
|
|
402
|
+
* In this case, we use it to store compiled template functions
|
|
403
|
+
* Indexed by their `name` or `filename`
|
|
404
|
+
*/
|
|
405
|
+
var Cacher = class {
|
|
406
|
+
constructor(cache) {
|
|
407
|
+
this.cache = cache;
|
|
408
|
+
}
|
|
409
|
+
define(key, val) {
|
|
410
|
+
this.cache[key] = val;
|
|
411
|
+
}
|
|
412
|
+
get(key) {
|
|
413
|
+
return this.cache[key];
|
|
414
|
+
}
|
|
415
|
+
remove(key) {
|
|
416
|
+
delete this.cache[key];
|
|
417
|
+
}
|
|
418
|
+
reset() {
|
|
419
|
+
this.cache = {};
|
|
420
|
+
}
|
|
421
|
+
load(cacheObj) {
|
|
422
|
+
this.cache = {
|
|
423
|
+
...this.cache,
|
|
424
|
+
...cacheObj
|
|
425
|
+
};
|
|
426
|
+
}
|
|
427
|
+
};
|
|
428
|
+
var Eta$1 = class {
|
|
429
|
+
constructor(customConfig) {
|
|
430
|
+
if (customConfig) this.config = {
|
|
431
|
+
...defaultConfig,
|
|
432
|
+
...customConfig
|
|
433
|
+
};
|
|
434
|
+
else this.config = { ...defaultConfig };
|
|
435
|
+
}
|
|
436
|
+
config;
|
|
437
|
+
RuntimeErr = RuntimeErr;
|
|
438
|
+
compile = compile;
|
|
439
|
+
compileToString = compileToString;
|
|
440
|
+
compileBody = compileBody;
|
|
441
|
+
parse = parse;
|
|
442
|
+
render = render;
|
|
443
|
+
renderAsync = renderAsync;
|
|
444
|
+
renderString = renderString;
|
|
445
|
+
renderStringAsync = renderStringAsync;
|
|
446
|
+
filepathCache = {};
|
|
447
|
+
templatesSync = new Cacher({});
|
|
448
|
+
templatesAsync = new Cacher({});
|
|
449
|
+
resolvePath = null;
|
|
450
|
+
readFile = null;
|
|
451
|
+
configure(customConfig) {
|
|
452
|
+
this.config = {
|
|
453
|
+
...this.config,
|
|
454
|
+
...customConfig
|
|
455
|
+
};
|
|
456
|
+
}
|
|
457
|
+
withConfig(customConfig) {
|
|
458
|
+
return {
|
|
459
|
+
...this,
|
|
460
|
+
config: {
|
|
461
|
+
...this.config,
|
|
462
|
+
...customConfig
|
|
463
|
+
}
|
|
464
|
+
};
|
|
465
|
+
}
|
|
466
|
+
loadTemplate(name, template, options) {
|
|
467
|
+
if (typeof template === "string") (options?.async ? this.templatesAsync : this.templatesSync).define(name, this.compile(template, options));
|
|
468
|
+
else {
|
|
469
|
+
let templates = this.templatesSync;
|
|
470
|
+
if (template.constructor.name === "AsyncFunction" || options?.async) templates = this.templatesAsync;
|
|
471
|
+
templates.define(name, template);
|
|
472
|
+
}
|
|
473
|
+
}
|
|
474
|
+
};
|
|
475
|
+
var Eta = class extends Eta$1 {
|
|
476
|
+
readFile = readFile;
|
|
477
|
+
resolvePath = resolvePath;
|
|
478
|
+
};
|
|
479
|
+
|
|
480
|
+
//#endregion
|
|
481
|
+
export { Eta as t };
|
package/dist/index.d.mts
CHANGED
|
@@ -1,125 +1,70 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
version: string;
|
|
6
|
-
dependencies?: Record<string, string>;
|
|
7
|
-
devDependencies?: Record<string, string>;
|
|
8
|
-
peerDependencies?: Record<string, string>;
|
|
9
|
-
[key: string]: unknown;
|
|
10
|
-
}
|
|
11
|
-
interface WorkspacePackage {
|
|
12
|
-
name: string;
|
|
13
|
-
version: string;
|
|
14
|
-
path: string;
|
|
15
|
-
packageJson: PackageJson;
|
|
16
|
-
workspaceDependencies: string[];
|
|
17
|
-
workspaceDevDependencies: string[];
|
|
18
|
-
}
|
|
1
|
+
import { Context, Effect, Schema } from "effect";
|
|
2
|
+
import { CommandExecutor } from "@effect/platform";
|
|
3
|
+
|
|
4
|
+
//#region src/options.d.ts
|
|
19
5
|
interface FindWorkspacePackagesOptions {
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
*/
|
|
23
|
-
excluded?: string[];
|
|
24
|
-
/**
|
|
25
|
-
* Only include these packages (if specified, all others are excluded)
|
|
26
|
-
*/
|
|
27
|
-
included?: string[];
|
|
28
|
-
/**
|
|
29
|
-
* Whether to exclude private packages (default: false)
|
|
30
|
-
*/
|
|
6
|
+
exclude?: string[];
|
|
7
|
+
include?: string[];
|
|
31
8
|
excludePrivate?: boolean;
|
|
32
9
|
}
|
|
33
|
-
interface
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
*/
|
|
37
|
-
package: WorkspacePackage;
|
|
38
|
-
/**
|
|
39
|
-
* Current version
|
|
40
|
-
*/
|
|
41
|
-
currentVersion: string;
|
|
42
|
-
/**
|
|
43
|
-
* New version to release
|
|
44
|
-
*/
|
|
45
|
-
newVersion: string;
|
|
46
|
-
/**
|
|
47
|
-
* Type of version bump
|
|
48
|
-
*/
|
|
49
|
-
bumpType: BumpKind;
|
|
50
|
-
/**
|
|
51
|
-
* Whether this package has direct changes (vs being updated due to dependency changes)
|
|
52
|
-
*/
|
|
53
|
-
hasDirectChanges: boolean;
|
|
54
|
-
}
|
|
55
|
-
interface ReleaseOptions {
|
|
56
|
-
/**
|
|
57
|
-
* Repository identifier (e.g., "owner/repo")
|
|
58
|
-
*/
|
|
59
|
-
repo: string;
|
|
60
|
-
/**
|
|
61
|
-
* Root directory of the workspace (defaults to process.cwd())
|
|
62
|
-
*/
|
|
10
|
+
interface ReleaseScriptsOptionsInput {
|
|
11
|
+
dryRun?: boolean;
|
|
12
|
+
repo: `${string}/${string}`;
|
|
63
13
|
workspaceRoot?: string;
|
|
64
|
-
/**
|
|
65
|
-
* Specific packages to prepare for release.
|
|
66
|
-
* - true: discover all packages
|
|
67
|
-
* - FindWorkspacePackagesOptions: discover with filters
|
|
68
|
-
* - string[]: specific package names
|
|
69
|
-
*/
|
|
70
14
|
packages?: true | FindWorkspacePackagesOptions | string[];
|
|
71
|
-
/**
|
|
72
|
-
* Branch name for the release PR (defaults to "release/next")
|
|
73
|
-
*/
|
|
74
|
-
releaseBranch?: string;
|
|
75
|
-
/**
|
|
76
|
-
* Interactive prompt configuration
|
|
77
|
-
*/
|
|
78
|
-
prompts?: {
|
|
79
|
-
/**
|
|
80
|
-
* Enable package selection prompt (defaults to true when not in CI)
|
|
81
|
-
*/
|
|
82
|
-
packages?: boolean;
|
|
83
|
-
/**
|
|
84
|
-
* Enable version override prompt (defaults to true when not in CI)
|
|
85
|
-
*/
|
|
86
|
-
versions?: boolean;
|
|
87
|
-
};
|
|
88
|
-
/**
|
|
89
|
-
* Whether to perform a dry run (no changes pushed or PR created)
|
|
90
|
-
* @default false
|
|
91
|
-
*/
|
|
92
|
-
dryRun?: boolean;
|
|
93
|
-
/**
|
|
94
|
-
* Whether to enable safety safeguards (e.g., checking for clean working directory)
|
|
95
|
-
* @default true
|
|
96
|
-
*/
|
|
97
|
-
safeguards?: boolean;
|
|
98
|
-
/**
|
|
99
|
-
* GitHub token for authentication
|
|
100
|
-
*/
|
|
101
15
|
githubToken: string;
|
|
16
|
+
branch?: {
|
|
17
|
+
release?: string;
|
|
18
|
+
default?: string;
|
|
19
|
+
};
|
|
20
|
+
globalCommitMode?: "dependencies" | "all" | "none";
|
|
102
21
|
pullRequest?: {
|
|
22
|
+
title?: string;
|
|
23
|
+
body?: string;
|
|
24
|
+
};
|
|
25
|
+
types?: Record<string, {
|
|
103
26
|
title: string;
|
|
104
|
-
|
|
27
|
+
color?: string;
|
|
28
|
+
}>;
|
|
29
|
+
changelog?: {
|
|
30
|
+
enabled?: boolean;
|
|
31
|
+
template?: string;
|
|
32
|
+
emojis?: boolean;
|
|
33
|
+
};
|
|
34
|
+
npm?: {
|
|
35
|
+
otp?: string;
|
|
36
|
+
provenance?: boolean;
|
|
105
37
|
};
|
|
106
|
-
}
|
|
107
|
-
interface ReleaseResult {
|
|
108
|
-
/**
|
|
109
|
-
* Packages that will be updated
|
|
110
|
-
*/
|
|
111
|
-
updates: VersionUpdate[];
|
|
112
|
-
/**
|
|
113
|
-
* URL of the created or updated PR
|
|
114
|
-
*/
|
|
115
|
-
prUrl?: string;
|
|
116
|
-
/**
|
|
117
|
-
* Whether a new PR was created (vs updating existing)
|
|
118
|
-
*/
|
|
119
|
-
created: boolean;
|
|
120
38
|
}
|
|
121
39
|
//#endregion
|
|
122
|
-
//#region src/
|
|
123
|
-
declare
|
|
40
|
+
//#region src/services/workspace.service.d.ts
|
|
41
|
+
declare const WorkspacePackageSchema: Schema.Struct<{
|
|
42
|
+
name: typeof Schema.String;
|
|
43
|
+
version: typeof Schema.String;
|
|
44
|
+
path: typeof Schema.String;
|
|
45
|
+
packageJson: Schema.Struct<{
|
|
46
|
+
name: typeof Schema.String;
|
|
47
|
+
private: Schema.optional<typeof Schema.Boolean>;
|
|
48
|
+
version: Schema.optional<typeof Schema.String>;
|
|
49
|
+
dependencies: Schema.optional<Schema.Record$<typeof Schema.String, typeof Schema.String>>;
|
|
50
|
+
devDependencies: Schema.optional<Schema.Record$<typeof Schema.String, typeof Schema.String>>;
|
|
51
|
+
peerDependencies: Schema.optional<Schema.Record$<typeof Schema.String, typeof Schema.String>>;
|
|
52
|
+
}>;
|
|
53
|
+
workspaceDependencies: Schema.Array$<typeof Schema.String>;
|
|
54
|
+
workspaceDevDependencies: Schema.Array$<typeof Schema.String>;
|
|
55
|
+
}>;
|
|
56
|
+
type WorkspacePackage = Schema.Schema.Type<typeof WorkspacePackageSchema>;
|
|
57
|
+
//#endregion
|
|
58
|
+
//#region src/index.d.ts
|
|
59
|
+
interface ReleaseScripts {
|
|
60
|
+
verify: () => Promise<void>;
|
|
61
|
+
prepare: () => Promise<void>;
|
|
62
|
+
publish: () => Promise<void>;
|
|
63
|
+
packages: {
|
|
64
|
+
list: () => Promise<readonly WorkspacePackage[]>;
|
|
65
|
+
get: (packageName: string) => Promise<WorkspacePackage | null>;
|
|
66
|
+
};
|
|
67
|
+
}
|
|
68
|
+
declare function createReleaseScripts(options: ReleaseScriptsOptionsInput): Promise<ReleaseScripts>;
|
|
124
69
|
//#endregion
|
|
125
|
-
export {
|
|
70
|
+
export { ReleaseScripts, createReleaseScripts };
|