@jakubmazanec/template 2.0.17-next.fac374fa → 2.0.17-unstable.2468857d

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/build/Template.js CHANGED
@@ -1,4 +1,6 @@
1
- "use strict";
1
+ import { NO_INFERRED_PARSER_REGEXP } from "./constants.js";
2
+ import { templateAttributesSchema } from "./TemplateAttributes.js";
3
+ import { TemplateError } from "./TemplateError.js";
2
4
  import ejs from "ejs";
3
5
  import fs from "fs-extra";
4
6
  import matter from "gray-matter";
@@ -6,158 +8,145 @@ import _ from "lodash";
6
8
  import path from "node:path";
7
9
  import prettier from "prettier";
8
10
  import yaml from "yaml";
9
- import { NO_INFERRED_PARSER_REGEXP } from "./constants.js";
10
- import { templateAttributesSchema } from "./TemplateAttributes.js";
11
- import { TemplateError } from "./TemplateError.js";
12
- export class Template {
13
- /** Template path. */
14
- path;
15
- /** Template content. Templates are written in [EJS](https://ejs.co/). */
16
- content;
17
- /** Template attributes. These control how the template is rendered. Some attributes can be written in [EJS](https://ejs.co/) and are rendered before the template content is rendered. It is expected that attribute `if` renders to a string that can be parsed as YAML value; if that value is `false`, the rendering is cancelled. Attribute `to` is also rendered and it represents the path of file the resulting template render is supposed to be written into (by the user). Attribute `variables` is an object that is merged with the data object before rendering. If attribute `variables` is an array of objects, that leads to multiple renders, each with different variables object merged with the data. Each variable that is a string is also rendered. */
18
- attributes;
19
- /** Template function. */
20
- fn;
21
- /** Zod schema for custom template attributes. */
22
- attributesSchema;
23
- /** Zod schema for template data. */
24
- dataSchema;
25
- constructor({
26
- path: templatePath,
27
- content,
28
- attributes,
29
- attributesSchema,
30
- dataSchema
31
- }) {
32
- if (templatePath) {
33
- this.path = templatePath;
34
- }
35
- this.content = content;
36
- this.attributes = attributes;
37
- this.fn = ejs.compile(this.content);
38
- if (attributesSchema) {
39
- this.attributesSchema = attributesSchema;
40
- } else {
41
- this.attributesSchema = null;
42
- }
43
- if (dataSchema) {
44
- this.dataSchema = dataSchema;
45
- } else {
46
- this.dataSchema = null;
47
- }
48
- }
49
- /**
50
- * Reads a template from a file.
51
- *
52
- * @param templatePath Path to the template file.
53
- */
54
- static async read(templatePath, options) {
55
- let { data: rawAttributes, content } = matter(await fs.readFile(templatePath, "utf8"));
56
- if (typeof rawAttributes.extends === "string" && rawAttributes.extends) {
57
- let extendedTemplate = await Template.read(
58
- path.join(path.dirname(templatePath), rawAttributes.extends),
59
- options
60
- );
61
- rawAttributes = _.merge(extendedTemplate.attributes, rawAttributes);
62
- if (!content.trim()) {
63
- content = extendedTemplate.content;
64
- }
65
- }
66
- let attributesSchema = options?.attributesSchema ? templateAttributesSchema.merge(options.attributesSchema) : templateAttributesSchema;
67
- let attributesParseResult = attributesSchema.safeParse(rawAttributes);
68
- if (!attributesParseResult.success) {
69
- throw new TemplateError("INVALID_ATTRIBUTES", {
70
- cause: attributesParseResult.error,
71
- data: {
72
- path: templatePath,
73
- zodIssues: attributesParseResult.error.issues
74
- }
75
- });
76
- }
77
- let attributes = attributesParseResult.data;
78
- return new this({
79
- path: templatePath,
80
- attributes,
81
- content,
82
- attributesSchema: options?.attributesSchema,
83
- dataSchema: options?.dataSchema
84
- });
85
- }
86
- /**
87
- * Reads a template from a file and then renders it.
88
- *
89
- * @param templatePath Path to the template file.
90
- * @param data Data used for rendering the template.
91
- * @param options Options object.
92
- * @return Template renders.
93
- */
94
- static async readAndRender(templatePath, data, options) {
95
- let template = await Template.read(templatePath, {
96
- attributesSchema: options?.attributesSchema,
97
- dataSchema: options?.dataSchema
98
- });
99
- return template.render(data, {
100
- prettierOptions: options?.prettierOptions,
101
- disablePrettier: options?.disablePrettier
102
- });
103
- }
104
- /**
105
- * Renders the template using data.
106
- *
107
- * @param data Data used for rendering the template.
108
- * @param options Options object.
109
- * @return Template renders.
110
- */
111
- async render(data, options) {
112
- let renders = [];
113
- for (let variables of Array.isArray(this.attributes.variables) ? this.attributes.variables : [this.attributes.variables]) {
114
- let renderedAttributes = _.omit(this.attributes, ["if"]);
115
- let renderedVariables = variables;
116
- if (renderedVariables) {
117
- for (let [variableName, variableValue] of Object.entries(renderedVariables)) {
118
- if (typeof variableValue === "string") {
119
- renderedVariables[variableName] = ejs.render(variableValue, { ...data });
120
- } else {
121
- renderedVariables[variableName] = variableValue;
122
- }
123
- }
124
- renderedAttributes.variables = renderedVariables;
125
- }
126
- let dataWithAttributes = { ...data, attributes: renderedAttributes };
127
- if (this.attributes.if) {
128
- let renderedIf = ejs.render(this.attributes.if, dataWithAttributes);
129
- let parsedIf = yaml.parse(renderedIf);
130
- if (parsedIf === false) {
131
- continue;
132
- }
133
- }
134
- renderedAttributes.to = ejs.render(renderedAttributes.to, dataWithAttributes);
135
- dataWithAttributes.attributes = renderedAttributes;
136
- let content;
137
- try {
138
- content = this.fn(dataWithAttributes);
139
- } catch (error) {
140
- throw new TemplateError("FAILED_RENDER", { cause: error });
141
- }
142
- if (!options?.disablePrettier) {
143
- try {
144
- content = await prettier.format(content, {
145
- ...options?.prettierOptions,
146
- filepath: renderedAttributes.to
147
- });
148
- } catch (error) {
149
- if (!NO_INFERRED_PARSER_REGEXP.test(error.message)) {
150
- throw new TemplateError("FAILED_FORMAT", { cause: error });
151
- }
152
- }
153
- }
154
- renders.push({
155
- attributes: renderedAttributes,
156
- data: data ?? null,
157
- content
158
- });
159
- }
160
- return renders;
161
- }
162
- }
163
- //# sourceMappingURL=Template.js.map
11
+
12
+ //#region source/Template.ts
13
+ /**
14
+ * The `Template` object stores all information about a template and has methods for reading and rendering.
15
+ *
16
+ * ```TypeScript
17
+ * let template = new Template({
18
+ * content: '<%- value %>',
19
+ * attributes: {
20
+ * to: 'value.txt',
21
+ * },
22
+ * dataSchema: z.object({value: z.number()}),
23
+ * });
24
+ *
25
+ * console.log(await template.render({value: 42})); // -> [{attributes: {to: 'value.txt'}, data: {value: 42}, content: '42'}]
26
+ * ```
27
+ *
28
+ * @typeParam A A Zod schema type used to define the custom template attributes type.
29
+ * @typeParam D A Zod schema type used to define the template datatype.
30
+ */
31
+ var Template = class Template {
32
+ /** Template path. */
33
+ path;
34
+ /** Template content. Templates are written in [EJS](https://ejs.co/). */
35
+ content;
36
+ /** Template attributes. These control how the template is rendered. Some attributes can be written in [EJS](https://ejs.co/) and are rendered before the template content is rendered. It is expected that attribute `if` renders to a string that can be parsed as YAML value; if that value is `false`, the rendering is cancelled. Attribute `to` is also rendered and it represents the path of file the resulting template render is supposed to be written into (by the user). Attribute `variables` is an object that is merged with the data object before rendering. If attribute `variables` is an array of objects, that leads to multiple renders, each with different variables object merged with the data. Each variable that is a string is also rendered. */
37
+ attributes;
38
+ /** Template function. */
39
+ fn;
40
+ /** Zod schema for custom template attributes. */
41
+ attributesSchema;
42
+ /** Zod schema for template data. */
43
+ dataSchema;
44
+ constructor({ path: templatePath, content, attributes, attributesSchema, dataSchema }) {
45
+ if (templatePath) this.path = templatePath;
46
+ this.content = content;
47
+ this.attributes = attributes;
48
+ this.fn = ejs.compile(this.content);
49
+ if (attributesSchema) this.attributesSchema = attributesSchema;
50
+ else this.attributesSchema = null;
51
+ if (dataSchema) this.dataSchema = dataSchema;
52
+ else this.dataSchema = null;
53
+ }
54
+ /**
55
+ * Reads a template from a file.
56
+ *
57
+ * @param templatePath Path to the template file.
58
+ */
59
+ static async read(templatePath, options) {
60
+ let { data: rawAttributes, content } = matter(await fs.readFile(templatePath, "utf8"));
61
+ if (typeof rawAttributes.extends === "string" && rawAttributes.extends) {
62
+ let extendedTemplate = await Template.read(path.join(path.dirname(templatePath), rawAttributes.extends), options);
63
+ rawAttributes = _.merge(extendedTemplate.attributes, rawAttributes);
64
+ if (!content.trim()) content = extendedTemplate.content;
65
+ }
66
+ let attributesParseResult = (options?.attributesSchema ? templateAttributesSchema.merge(options.attributesSchema) : templateAttributesSchema).safeParse(rawAttributes);
67
+ if (!attributesParseResult.success) throw new TemplateError("INVALID_ATTRIBUTES", {
68
+ cause: attributesParseResult.error,
69
+ data: {
70
+ path: templatePath,
71
+ zodIssues: attributesParseResult.error.issues
72
+ }
73
+ });
74
+ let attributes = attributesParseResult.data;
75
+ return new this({
76
+ path: templatePath,
77
+ attributes,
78
+ content,
79
+ attributesSchema: options?.attributesSchema,
80
+ dataSchema: options?.dataSchema
81
+ });
82
+ }
83
+ /**
84
+ * Reads a template from a file and then renders it.
85
+ *
86
+ * @param templatePath Path to the template file.
87
+ * @param data Data used for rendering the template.
88
+ * @param options Options object.
89
+ * @return Template renders.
90
+ */
91
+ static async readAndRender(templatePath, data, options) {
92
+ return (await Template.read(templatePath, {
93
+ attributesSchema: options?.attributesSchema,
94
+ dataSchema: options?.dataSchema
95
+ })).render(data, {
96
+ prettierOptions: options?.prettierOptions,
97
+ disablePrettier: options?.disablePrettier
98
+ });
99
+ }
100
+ /**
101
+ * Renders the template using data.
102
+ *
103
+ * @param data Data used for rendering the template.
104
+ * @param options Options object.
105
+ * @return Template renders.
106
+ */
107
+ async render(data, options) {
108
+ let renders = [];
109
+ for (let variables of Array.isArray(this.attributes.variables) ? this.attributes.variables : [this.attributes.variables]) {
110
+ let renderedAttributes = _.omit(this.attributes, ["if"]);
111
+ let renderedVariables = variables;
112
+ if (renderedVariables) {
113
+ for (let [variableName, variableValue] of Object.entries(renderedVariables)) if (typeof variableValue === "string") renderedVariables[variableName] = ejs.render(variableValue, { ...data });
114
+ else renderedVariables[variableName] = variableValue;
115
+ renderedAttributes.variables = renderedVariables;
116
+ }
117
+ let dataWithAttributes = {
118
+ ...data,
119
+ attributes: renderedAttributes
120
+ };
121
+ if (this.attributes.if) {
122
+ let renderedIf = ejs.render(this.attributes.if, dataWithAttributes);
123
+ if (yaml.parse(renderedIf) === false) continue;
124
+ }
125
+ renderedAttributes.to = ejs.render(renderedAttributes.to, dataWithAttributes);
126
+ dataWithAttributes.attributes = renderedAttributes;
127
+ let content;
128
+ try {
129
+ content = this.fn(dataWithAttributes);
130
+ } catch (error) {
131
+ throw new TemplateError("FAILED_RENDER", { cause: error });
132
+ }
133
+ if (!options?.disablePrettier) try {
134
+ content = await prettier.format(content, {
135
+ ...options?.prettierOptions,
136
+ filepath: renderedAttributes.to
137
+ });
138
+ } catch (error) {
139
+ if (!NO_INFERRED_PARSER_REGEXP.test(error.message)) throw new TemplateError("FAILED_FORMAT", { cause: error });
140
+ }
141
+ renders.push({
142
+ attributes: renderedAttributes,
143
+ data: data ?? null,
144
+ content
145
+ });
146
+ }
147
+ return renders;
148
+ }
149
+ };
150
+
151
+ //#endregion
152
+ export { Template };
@@ -1,10 +1,16 @@
1
- "use strict";
2
- import { z } from "zod";
3
1
  import { templateVariablesSchema } from "./TemplateVariables.js";
4
- export const templateAttributesSchema = z.object({
5
- extends: z.string().optional(),
6
- to: z.string(),
7
- if: z.string().optional(),
8
- variables: templateVariablesSchema.optional()
2
+ import { z } from "zod";
3
+
4
+ //#region source/TemplateAttributes.ts
5
+ /**
6
+ * Zod schema for {@link TemplateAttributes}.
7
+ */
8
+ const templateAttributesSchema = z.object({
9
+ extends: z.string().optional(),
10
+ to: z.string(),
11
+ if: z.string().optional(),
12
+ variables: templateVariablesSchema.optional()
9
13
  }).strict();
10
- //# sourceMappingURL=TemplateAttributes.js.map
14
+
15
+ //#endregion
16
+ export { templateAttributesSchema };
@@ -1,16 +1,18 @@
1
- "use strict";
2
1
  import { createCustomErrorWithData } from "@jakubmazanec/error";
3
- export const TemplateError = createCustomErrorWithData(
4
- "TemplateError",
5
- {
6
- INVALID_ATTRIBUTES: "Invalid template attributes.",
7
- FAILED_FORMAT: "Template render formatting has failed.",
8
- FAILED_RENDER: "Template rendering has failed."
9
- },
10
- class TemplateErrorData {
11
- template;
12
- path;
13
- zodIssues;
14
- }
15
- );
16
- //# sourceMappingURL=TemplateError.js.map
2
+
3
+ //#region source/TemplateError.ts
4
+ /**
5
+ * A subclass of `Error` that indicates a template failure.
6
+ */
7
+ const TemplateError = createCustomErrorWithData("TemplateError", {
8
+ INVALID_ATTRIBUTES: "Invalid template attributes.",
9
+ FAILED_FORMAT: "Template render formatting has failed.",
10
+ FAILED_RENDER: "Template rendering has failed."
11
+ }, class TemplateErrorData {
12
+ template;
13
+ path;
14
+ zodIssues;
15
+ });
16
+
17
+ //#endregion
18
+ export { TemplateError };
@@ -1,7 +1,10 @@
1
- "use strict";
2
- import * as z from "zod";
3
- export const templateVariablesSchema = z.union([
4
- z.record(z.string(), z.unknown()),
5
- z.array(z.record(z.string(), z.unknown()))
6
- ]);
7
- //# sourceMappingURL=TemplateVariables.js.map
1
+ import * as z$1 from "zod";
2
+
3
+ //#region source/TemplateVariables.ts
4
+ /**
5
+ * Zod schema for {@link TemplateAttributesVariables}.
6
+ */
7
+ const templateVariablesSchema = z$1.union([z$1.record(z$1.string(), z$1.unknown()), z$1.array(z$1.record(z$1.string(), z$1.unknown()))]);
8
+
9
+ //#endregion
10
+ export { templateVariablesSchema };
@@ -1,3 +1,5 @@
1
- "use strict";
2
- export const NO_INFERRED_PARSER_REGEXP = /parser.*inferred/i;
3
- //# sourceMappingURL=constants.js.map
1
+ //#region source/constants.ts
2
+ const NO_INFERRED_PARSER_REGEXP = /parser.*inferred/i;
3
+
4
+ //#endregion
5
+ export { NO_INFERRED_PARSER_REGEXP };
package/build/main.js CHANGED
@@ -1,6 +1,6 @@
1
- "use strict";
2
- export * from "./Template.js";
3
- export * from "./TemplateAttributes.js";
4
- export * from "./TemplateError.js";
5
- export * from "./TemplateVariables.js";
6
- //# sourceMappingURL=main.js.map
1
+ import { templateVariablesSchema } from "./TemplateVariables.js";
2
+ import { templateAttributesSchema } from "./TemplateAttributes.js";
3
+ import { TemplateError } from "./TemplateError.js";
4
+ import { Template } from "./Template.js";
5
+
6
+ export { Template, TemplateError, templateAttributesSchema, templateVariablesSchema };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@jakubmazanec/template",
3
- "version": "2.0.17-next.fac374fa",
3
+ "version": "2.0.17-unstable.2468857d",
4
4
  "description": "TypeScript-first library for working with templates using EJS and Zod.",
5
5
  "repository": {
6
6
  "type": "git",
@@ -17,9 +17,9 @@
17
17
  "source"
18
18
  ],
19
19
  "scripts": {
20
- "build": "del-cli build tsconfig.tsbuildinfo && esbuild \"source/**/*\" --platform=node --target=node24.3 --outdir=build --sourcemap && tsc",
20
+ "build": "del-cli build tsconfig.tsbuildinfo && tsdown && tsc",
21
21
  "clean": "del-cli coverage build *.tsbuildinfo",
22
- "develop": "concurrently \"esbuild \"source/**/*\" --platform=node --target=node24.3 --outdir=build --sourcemap --watch\" \"tsc --watch\"",
22
+ "develop": "concurrently \"tsdown --watch\" \"tsc --watch\"",
23
23
  "document": "del-cli docs && typedoc --options typedoc.config.cjs",
24
24
  "format": "prettier . --write --ignore-unknown",
25
25
  "lint": "eslint .",
@@ -27,7 +27,7 @@
27
27
  "typecheck": "tsc --project tsconfig.typecheck.json"
28
28
  },
29
29
  "dependencies": {
30
- "@jakubmazanec/error": "3.0.16-next.fac374fa",
30
+ "@jakubmazanec/error": "3.0.16-unstable.2468857d",
31
31
  "ejs": "^3.1.10",
32
32
  "fs-extra": "^11.3.2",
33
33
  "gray-matter": "^4.0.3",
@@ -37,7 +37,7 @@
37
37
  "zod": "^4.1.13"
38
38
  },
39
39
  "devDependencies": {
40
- "@jakubmazanec/eslint-config": "4.1.10-next.fac374fa",
40
+ "@jakubmazanec/eslint-config": "4.1.10-unstable.2468857d",
41
41
  "@types/ejs": "^3.1.5",
42
42
  "@types/fs-extra": "^11.0.4",
43
43
  "@types/lodash": "^4.17.21",
@@ -45,9 +45,9 @@
45
45
  "@vitest/coverage-v8": "^3.2.4",
46
46
  "concurrently": "^9.2.1",
47
47
  "del-cli": "^6.0.0",
48
- "esbuild": "^0.27.0",
49
48
  "eslint": "^9.33.0",
50
49
  "prettier-plugin-packagejson": "^2.5.19",
50
+ "tsdown": "^0.17.2",
51
51
  "typedoc": "^0.28.14",
52
52
  "typedoc-plugin-markdown": "^4.9.0",
53
53
  "typescript": "^5.9.3",
@@ -1,7 +0,0 @@
1
- {
2
- "version": 3,
3
- "sources": ["../source/Template.ts"],
4
- "sourcesContent": ["import ejs from 'ejs';\nimport fs from 'fs-extra';\nimport matter from 'gray-matter';\nimport _ from 'lodash';\nimport path from 'node:path';\nimport prettier from 'prettier';\nimport yaml from 'yaml';\nimport {type z, type ZodObject} from 'zod';\n\nimport {NO_INFERRED_PARSER_REGEXP} from './constants.js';\nimport {type TemplateAttributes, templateAttributesSchema} from './TemplateAttributes.js';\nimport {TemplateError} from './TemplateError.js';\nimport {type TemplateFunction} from './TemplateFunction.js';\nimport {type TemplateRender} from './TemplateRender.js';\nimport {type TemplateRenders} from './TemplateRenders.js';\n\nexport type TemplateOptions<\n A extends ZodObject | undefined = undefined,\n D extends ZodObject | undefined = undefined,\n> = {\n /** Template path. */\n path?: string;\n\n /** Template content. */\n content: string;\n\n /** Template attributes. */\n attributes: A extends undefined ? TemplateAttributes\n : TemplateAttributes & z.infer<NonNullable<A>>;\n\n /** Zod schema for custom template attributes. */\n attributesSchema?: A | undefined;\n\n /** Zod schema for template data. */\n dataSchema?: D | undefined;\n};\n\nexport type TemplateReadOptions<\n A extends ZodObject | undefined = undefined,\n D extends ZodObject | undefined = undefined,\n> = {\n /** Zod schema for custom template attributes. */\n attributesSchema?: A | undefined;\n\n /** Zod schema for template data. */\n dataSchema?: D | undefined;\n};\n\nexport type TemplateReadAndRenderOptions<\n A extends ZodObject | undefined = undefined,\n D extends ZodObject | undefined = undefined,\n> = {\n /** Prettier options. */\n prettierOptions?: prettier.Options | undefined;\n\n /** Disable formatting the rendered template using Prettier. */\n disablePrettier?: boolean | undefined;\n\n /** Zod schema for custom template attributes. */\n attributesSchema?: A | undefined;\n\n /** Zod schema for template data. */\n dataSchema?: D | undefined;\n};\n\nexport type TemplateRenderOptions = {\n /** Prettier options. */\n prettierOptions?: prettier.Options | undefined;\n\n /** Disable formatting the rendered template using Prettier. */\n disablePrettier?: boolean | undefined;\n};\n\n/**\n * The `Template` object stores all information about a template and has methods for reading and rendering.\n *\n * ```TypeScript\n * let template = new Template({\n * content: '<%- value %>',\n * attributes: {\n * to: 'value.txt',\n * },\n * dataSchema: z.object({value: z.number()}),\n * });\n *\n * console.log(await template.render({value: 42})); // -> [{attributes: {to: 'value.txt'}, data: {value: 42}, content: '42'}]\n * ```\n *\n * @typeParam A A Zod schema type used to define the custom template attributes type.\n * @typeParam D A Zod schema type used to define the template datatype.\n */\nexport class Template<\n A extends ZodObject | undefined = undefined,\n D extends ZodObject | undefined = undefined,\n> {\n /** Template path. */\n path?: string;\n\n /** Template content. Templates are written in [EJS](https://ejs.co/). */\n readonly content: string;\n\n /** Template attributes. These control how the template is rendered. Some attributes can be written in [EJS](https://ejs.co/) and are rendered before the template content is rendered. It is expected that attribute `if` renders to a string that can be parsed as YAML value; if that value is `false`, the rendering is cancelled. Attribute `to` is also rendered and it represents the path of file the resulting template render is supposed to be written into (by the user). Attribute `variables` is an object that is merged with the data object before rendering. If attribute `variables` is an array of objects, that leads to multiple renders, each with different variables object merged with the data. Each variable that is a string is also rendered. */\n readonly attributes: A extends undefined ? TemplateAttributes\n : TemplateAttributes & z.infer<NonNullable<A>>;\n\n /** Template function. */\n private readonly fn: TemplateFunction;\n\n /** Zod schema for custom template attributes. */\n readonly attributesSchema: A extends ZodObject ? A : null;\n\n /** Zod schema for template data. */\n readonly dataSchema: D extends ZodObject ? D : null;\n\n constructor({\n path: templatePath,\n content,\n attributes,\n attributesSchema,\n dataSchema,\n }: TemplateOptions<A, D>) {\n if (templatePath) {\n this.path = templatePath;\n }\n\n this.content = content;\n this.attributes = attributes;\n this.fn = ejs.compile(this.content);\n\n if (attributesSchema) {\n this.attributesSchema = attributesSchema as A extends ZodObject ? A : null;\n } else {\n this.attributesSchema = null as A extends ZodObject ? A : null;\n }\n\n if (dataSchema) {\n this.dataSchema = dataSchema as D extends ZodObject ? D : null;\n } else {\n this.dataSchema = null as D extends ZodObject ? D : null;\n }\n }\n\n /**\n * Reads a template from a file.\n *\n * @param templatePath Path to the template file.\n */\n static async read<\n A extends ZodObject | undefined = undefined,\n D extends ZodObject | undefined = undefined,\n >(templatePath: string, options?: TemplateReadOptions<A, D>): Promise<Template<A, D>> {\n let {data: rawAttributes, content} = matter(await fs.readFile(templatePath, 'utf8'));\n\n // extending another template\n if (typeof rawAttributes.extends === 'string' && rawAttributes.extends) {\n let extendedTemplate = await Template.read(\n path.join(path.dirname(templatePath), rawAttributes.extends),\n options,\n ); // you can point to any template, but it will be parsed with the same options, including attribute or data schema\n\n // attributes are recursively merged\n rawAttributes = _.merge(extendedTemplate.attributes, rawAttributes);\n\n // if content is empty, use content from the extended template\n if (!content.trim()) {\n content = extendedTemplate.content;\n }\n }\n\n let attributesSchema =\n options?.attributesSchema ?\n templateAttributesSchema.merge(options.attributesSchema)\n : templateAttributesSchema;\n let attributesParseResult = attributesSchema.safeParse(rawAttributes);\n\n if (!attributesParseResult.success) {\n throw new TemplateError('INVALID_ATTRIBUTES', {\n cause: attributesParseResult.error,\n data: {\n path: templatePath,\n zodIssues: attributesParseResult.error.issues,\n },\n });\n }\n\n let attributes = attributesParseResult.data;\n\n return new this({\n path: templatePath,\n attributes,\n content,\n attributesSchema: options?.attributesSchema,\n dataSchema: options?.dataSchema,\n } as TemplateOptions<A, D>);\n }\n\n /**\n * Reads a template from a file and then renders it.\n *\n * @param templatePath Path to the template file.\n * @param data Data used for rendering the template.\n * @param options Options object.\n * @return Template renders.\n */\n static async readAndRender<\n A extends ZodObject | undefined = undefined,\n D extends ZodObject | undefined = undefined,\n >(\n templatePath: string,\n data: D extends undefined ? null : z.infer<NonNullable<D>>,\n options?: TemplateReadAndRenderOptions<A, D>,\n ) {\n let template = await Template.read<A, D>(templatePath, {\n attributesSchema: options?.attributesSchema,\n dataSchema: options?.dataSchema,\n });\n\n return template.render(data, {\n prettierOptions: options?.prettierOptions,\n disablePrettier: options?.disablePrettier,\n });\n }\n\n /**\n * Renders the template using data.\n *\n * @param data Data used for rendering the template.\n * @param options Options object.\n * @return Template renders.\n */\n async render(\n data: D extends undefined ? null : z.infer<NonNullable<D>>,\n options?: TemplateRenderOptions,\n ): Promise<TemplateRenders<A, D>> {\n let renders: TemplateRenders<A, D> = [];\n\n for (let variables of Array.isArray(this.attributes.variables) ?\n this.attributes.variables\n : [this.attributes.variables]) {\n let renderedAttributes = _.omit(this.attributes, ['if']);\n let renderedVariables = variables;\n\n if (renderedVariables) {\n for (let [variableName, variableValue] of Object.entries(renderedVariables)) {\n if (typeof variableValue === 'string') {\n renderedVariables[variableName] = ejs.render(variableValue, {...data});\n } else {\n renderedVariables[variableName] = variableValue;\n }\n }\n\n renderedAttributes.variables = renderedVariables;\n }\n\n let dataWithAttributes = {...data, attributes: renderedAttributes};\n\n if (this.attributes.if) {\n let renderedIf = ejs.render(this.attributes.if, dataWithAttributes);\n let parsedIf = yaml.parse(renderedIf) as unknown;\n\n if (parsedIf === false) {\n continue;\n }\n }\n\n renderedAttributes.to = ejs.render(renderedAttributes.to, dataWithAttributes);\n dataWithAttributes.attributes = renderedAttributes;\n\n let content;\n\n try {\n content = this.fn(dataWithAttributes);\n } catch (error: unknown) {\n throw new TemplateError('FAILED_RENDER', {cause: error});\n }\n\n if (!options?.disablePrettier) {\n try {\n content = await prettier.format(content, {\n ...options?.prettierOptions,\n filepath: renderedAttributes.to,\n });\n } catch (error: unknown) {\n if (!NO_INFERRED_PARSER_REGEXP.test((error as Error).message)) {\n throw new TemplateError('FAILED_FORMAT', {cause: error});\n }\n }\n }\n\n renders.push({\n attributes: renderedAttributes,\n data: data ?? null,\n content,\n } as TemplateRender<A, D>);\n }\n\n return renders;\n }\n}\n"],
5
- "mappings": "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",
6
- "names": []
7
- }
@@ -1,7 +0,0 @@
1
- {
2
- "version": 3,
3
- "sources": ["../source/TemplateAttributes.ts"],
4
- "sourcesContent": ["import {z} from 'zod';\n\nimport {templateVariablesSchema} from './TemplateVariables.js';\n\n/**\n * Zod schema for {@link TemplateAttributes}.\n */\nexport const templateAttributesSchema = z\n .object({\n extends: z.string().optional(),\n to: z.string(),\n if: z.string().optional(),\n variables: templateVariablesSchema.optional(),\n })\n .strict();\n\n/**\n * Type representing template attributes.\n */\nexport type TemplateAttributes = z.infer<typeof templateAttributesSchema>;\n"],
5
- "mappings": ";AAAA,SAAQ,SAAQ;AAEhB,SAAQ,+BAA8B;AAK/B,aAAM,2BAA2B,EACrC,OAAO;AAAA,EACN,SAAS,EAAE,OAAO,EAAE,SAAS;AAAA,EAC7B,IAAI,EAAE,OAAO;AAAA,EACb,IAAI,EAAE,OAAO,EAAE,SAAS;AAAA,EACxB,WAAW,wBAAwB,SAAS;AAC9C,CAAC,EACA,OAAO;",
6
- "names": []
7
- }
@@ -1,2 +0,0 @@
1
- "use strict";
2
- //# sourceMappingURL=TemplateContent.js.map
@@ -1,7 +0,0 @@
1
- {
2
- "version": 3,
3
- "sources": [],
4
- "sourcesContent": [],
5
- "mappings": "",
6
- "names": []
7
- }
@@ -1,7 +0,0 @@
1
- {
2
- "version": 3,
3
- "sources": ["../source/TemplateError.ts"],
4
- "sourcesContent": ["import {createCustomErrorWithData} from '@jakubmazanec/error';\nimport {type ZodIssue} from 'zod';\n\nimport {type Template} from './Template.js';\n\n/**\n * A subclass of `Error` that indicates a template failure.\n */\nexport const TemplateError = createCustomErrorWithData(\n 'TemplateError',\n {\n INVALID_ATTRIBUTES: 'Invalid template attributes.',\n FAILED_FORMAT: 'Template render formatting has failed.',\n FAILED_RENDER: 'Template rendering has failed.',\n },\n class TemplateErrorData {\n template?: Template;\n path?: string;\n zodIssues?: ZodIssue[];\n },\n);\n"],
5
- "mappings": ";AAAA,SAAQ,iCAAgC;AAQjC,aAAM,gBAAgB;AAAA,EAC3B;AAAA,EACA;AAAA,IACE,oBAAoB;AAAA,IACpB,eAAe;AAAA,IACf,eAAe;AAAA,EACjB;AAAA,EACA,MAAM,kBAAkB;AAAA,IACtB;AAAA,IACA;AAAA,IACA;AAAA,EACF;AACF;",
6
- "names": []
7
- }
@@ -1,2 +0,0 @@
1
- "use strict";
2
- //# sourceMappingURL=TemplateFunction.js.map
@@ -1,7 +0,0 @@
1
- {
2
- "version": 3,
3
- "sources": [],
4
- "sourcesContent": [],
5
- "mappings": "",
6
- "names": []
7
- }
@@ -1,2 +0,0 @@
1
- "use strict";
2
- //# sourceMappingURL=TemplateRender.js.map
@@ -1,7 +0,0 @@
1
- {
2
- "version": 3,
3
- "sources": [],
4
- "sourcesContent": [],
5
- "mappings": "",
6
- "names": []
7
- }
@@ -1,2 +0,0 @@
1
- "use strict";
2
- //# sourceMappingURL=TemplateRenders.js.map
@@ -1,7 +0,0 @@
1
- {
2
- "version": 3,
3
- "sources": [],
4
- "sourcesContent": [],
5
- "mappings": "",
6
- "names": []
7
- }
@@ -1,7 +0,0 @@
1
- {
2
- "version": 3,
3
- "sources": ["../source/TemplateVariables.ts"],
4
- "sourcesContent": ["import * as z from 'zod';\n\n/**\n * Zod schema for {@link TemplateAttributesVariables}.\n */\nexport const templateVariablesSchema = z.union([\n z.record(z.string(), z.unknown()),\n z.array(z.record(z.string(), z.unknown())),\n]);\n\n/**\n * Type of `variables`` property of {@link TemplateAttributes}.\n */\nexport type TemplateAttributesVariables = z.infer<typeof templateVariablesSchema>;\n"],
5
- "mappings": ";AAAA,YAAY,OAAO;AAKZ,aAAM,0BAA0B,EAAE,MAAM;AAAA,EAC7C,EAAE,OAAO,EAAE,OAAO,GAAG,EAAE,QAAQ,CAAC;AAAA,EAChC,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO,GAAG,EAAE,QAAQ,CAAC,CAAC;AAC3C,CAAC;",
6
- "names": []
7
- }
@@ -1,7 +0,0 @@
1
- {
2
- "version": 3,
3
- "sources": ["../source/constants.ts"],
4
- "sourcesContent": ["export const NO_INFERRED_PARSER_REGEXP = /parser.*inferred/i;\n"],
5
- "mappings": ";AAAO,aAAM,4BAA4B;",
6
- "names": []
7
- }
package/build/main.js.map DELETED
@@ -1,7 +0,0 @@
1
- {
2
- "version": 3,
3
- "sources": ["../source/main.ts"],
4
- "sourcesContent": ["export * from './Template.js';\nexport * from './TemplateAttributes.js';\nexport type * from './TemplateContent.js';\nexport * from './TemplateError.js';\nexport type * from './TemplateFunction.js';\nexport type * from './TemplateRender.js';\nexport type * from './TemplateRenders.js';\nexport * from './TemplateVariables.js';\n"],
5
- "mappings": ";AAAA,cAAc;AACd,cAAc;AAEd,cAAc;AAId,cAAc;",
6
- "names": []
7
- }