@vertesia/build-tools 1.0.0-dev.20260225.024852Z → 1.0.0-dev.20260227.104700Z

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.
Files changed (42) hide show
  1. package/lib/build-tools.js +223 -1
  2. package/lib/build-tools.js.map +1 -1
  3. package/lib/cjs/index.js +4 -1
  4. package/lib/cjs/index.js.map +1 -1
  5. package/lib/cjs/presets/index.js +6 -1
  6. package/lib/cjs/presets/index.js.map +1 -1
  7. package/lib/cjs/presets/template-collection.js +80 -0
  8. package/lib/cjs/presets/template-collection.js.map +1 -0
  9. package/lib/cjs/presets/template.js +105 -0
  10. package/lib/cjs/presets/template.js.map +1 -0
  11. package/lib/cjs/utils/template-asset-discovery.js +63 -0
  12. package/lib/cjs/utils/template-asset-discovery.js.map +1 -0
  13. package/lib/esm/index.js +1 -1
  14. package/lib/esm/index.js.map +1 -1
  15. package/lib/esm/presets/index.js +2 -0
  16. package/lib/esm/presets/index.js.map +1 -1
  17. package/lib/esm/presets/template-collection.js +74 -0
  18. package/lib/esm/presets/template-collection.js.map +1 -0
  19. package/lib/esm/presets/template.js +99 -0
  20. package/lib/esm/presets/template.js.map +1 -0
  21. package/lib/esm/utils/template-asset-discovery.js +57 -0
  22. package/lib/esm/utils/template-asset-discovery.js.map +1 -0
  23. package/lib/types/index.d.ts +1 -1
  24. package/lib/types/index.d.ts.map +1 -1
  25. package/lib/types/presets/index.d.ts +2 -0
  26. package/lib/types/presets/index.d.ts.map +1 -1
  27. package/lib/types/presets/skill.d.ts +12 -12
  28. package/lib/types/presets/template-collection.d.ts +25 -0
  29. package/lib/types/presets/template-collection.d.ts.map +1 -0
  30. package/lib/types/presets/template.d.ts +58 -0
  31. package/lib/types/presets/template.d.ts.map +1 -0
  32. package/lib/types/types.d.ts +1 -1
  33. package/lib/types/types.d.ts.map +1 -1
  34. package/lib/types/utils/template-asset-discovery.d.ts +23 -0
  35. package/lib/types/utils/template-asset-discovery.d.ts.map +1 -0
  36. package/package.json +5 -5
  37. package/src/index.ts +4 -0
  38. package/src/presets/index.ts +2 -0
  39. package/src/presets/template-collection.ts +83 -0
  40. package/src/presets/template.ts +116 -0
  41. package/src/types.ts +1 -1
  42. package/src/utils/template-asset-discovery.ts +77 -0
package/lib/cjs/index.js CHANGED
@@ -19,7 +19,7 @@
19
19
  * ```
20
20
  */
21
21
  Object.defineProperty(exports, "__esModule", { value: true });
22
- exports.parseFrontmatter = exports.TemplateType = exports.PromptRole = exports.PromptDefinitionSchema = exports.SkillPropertiesSchema = exports.SkillDefinitionSchema = exports.promptTransformer = exports.skillCollectionTransformer = exports.rawTransformer = exports.skillTransformer = exports.vertesiaImportPlugin = void 0;
22
+ exports.parseFrontmatter = exports.TemplateType = exports.PromptRole = exports.PromptDefinitionSchema = exports.RenderingTemplateDefinitionSchema = exports.SkillPropertiesSchema = exports.SkillDefinitionSchema = exports.promptTransformer = exports.templateCollectionTransformer = exports.templateTransformer = exports.skillCollectionTransformer = exports.rawTransformer = exports.skillTransformer = exports.vertesiaImportPlugin = void 0;
23
23
  // Core plugin
24
24
  var plugin_js_1 = require("./plugin.js");
25
25
  Object.defineProperty(exports, "vertesiaImportPlugin", { enumerable: true, get: function () { return plugin_js_1.vertesiaImportPlugin; } });
@@ -28,9 +28,12 @@ var index_js_1 = require("./presets/index.js");
28
28
  Object.defineProperty(exports, "skillTransformer", { enumerable: true, get: function () { return index_js_1.skillTransformer; } });
29
29
  Object.defineProperty(exports, "rawTransformer", { enumerable: true, get: function () { return index_js_1.rawTransformer; } });
30
30
  Object.defineProperty(exports, "skillCollectionTransformer", { enumerable: true, get: function () { return index_js_1.skillCollectionTransformer; } });
31
+ Object.defineProperty(exports, "templateTransformer", { enumerable: true, get: function () { return index_js_1.templateTransformer; } });
32
+ Object.defineProperty(exports, "templateCollectionTransformer", { enumerable: true, get: function () { return index_js_1.templateCollectionTransformer; } });
31
33
  Object.defineProperty(exports, "promptTransformer", { enumerable: true, get: function () { return index_js_1.promptTransformer; } });
32
34
  Object.defineProperty(exports, "SkillDefinitionSchema", { enumerable: true, get: function () { return index_js_1.SkillDefinitionSchema; } });
33
35
  Object.defineProperty(exports, "SkillPropertiesSchema", { enumerable: true, get: function () { return index_js_1.SkillPropertiesSchema; } });
36
+ Object.defineProperty(exports, "RenderingTemplateDefinitionSchema", { enumerable: true, get: function () { return index_js_1.RenderingTemplateDefinitionSchema; } });
34
37
  Object.defineProperty(exports, "PromptDefinitionSchema", { enumerable: true, get: function () { return index_js_1.PromptDefinitionSchema; } });
35
38
  Object.defineProperty(exports, "PromptRole", { enumerable: true, get: function () { return index_js_1.PromptRole; } });
36
39
  Object.defineProperty(exports, "TemplateType", { enumerable: true, get: function () { return index_js_1.TemplateType; } });
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":";AAAA;;;;;;;;;;;;;;;;;;GAkBG;;;AAEH,cAAc;AACd,yCAAmD;AAA1C,iHAAA,oBAAoB,OAAA;AAa7B,UAAU;AACV,+CAc4B;AAbxB,4GAAA,gBAAgB,OAAA;AAChB,0GAAA,cAAc,OAAA;AACd,sHAAA,0BAA0B,OAAA;AAC1B,6GAAA,iBAAiB,OAAA;AACjB,iHAAA,qBAAqB,OAAA;AACrB,iHAAA,qBAAqB,OAAA;AACrB,kHAAA,sBAAsB,OAAA;AAKtB,sGAAA,UAAU,OAAA;AACV,wGAAA,YAAY,OAAA;AAGhB,YAAY;AACZ,2DAAoF;AAA3E,kHAAA,gBAAgB,OAAA"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":";AAAA;;;;;;;;;;;;;;;;;;GAkBG;;;AAEH,cAAc;AACd,yCAAmD;AAA1C,iHAAA,oBAAoB,OAAA;AAa7B,UAAU;AACV,+CAkB4B;AAjBxB,4GAAA,gBAAgB,OAAA;AAChB,0GAAA,cAAc,OAAA;AACd,sHAAA,0BAA0B,OAAA;AAC1B,+GAAA,mBAAmB,OAAA;AACnB,yHAAA,6BAA6B,OAAA;AAC7B,6GAAA,iBAAiB,OAAA;AACjB,iHAAA,qBAAqB,OAAA;AACrB,iHAAA,qBAAqB,OAAA;AACrB,6HAAA,iCAAiC,OAAA;AACjC,kHAAA,sBAAsB,OAAA;AAMtB,sGAAA,UAAU,OAAA;AACV,wGAAA,YAAY,OAAA;AAGhB,YAAY;AACZ,2DAAoF;AAA3E,kHAAA,gBAAgB,OAAA"}
@@ -3,13 +3,18 @@
3
3
  * Preset transformers for common use cases
4
4
  */
5
5
  Object.defineProperty(exports, "__esModule", { value: true });
6
- exports.TemplateType = exports.PromptRole = exports.PromptDefinitionSchema = exports.promptTransformer = exports.rawTransformer = exports.skillCollectionTransformer = exports.SkillPropertiesSchema = exports.SkillDefinitionSchema = exports.skillTransformer = void 0;
6
+ exports.TemplateType = exports.PromptRole = exports.PromptDefinitionSchema = exports.promptTransformer = exports.rawTransformer = exports.templateCollectionTransformer = exports.RenderingTemplateDefinitionSchema = exports.templateTransformer = exports.skillCollectionTransformer = exports.SkillPropertiesSchema = exports.SkillDefinitionSchema = exports.skillTransformer = void 0;
7
7
  var skill_js_1 = require("./skill.js");
8
8
  Object.defineProperty(exports, "skillTransformer", { enumerable: true, get: function () { return skill_js_1.skillTransformer; } });
9
9
  Object.defineProperty(exports, "SkillDefinitionSchema", { enumerable: true, get: function () { return skill_js_1.SkillDefinitionSchema; } });
10
10
  Object.defineProperty(exports, "SkillPropertiesSchema", { enumerable: true, get: function () { return skill_js_1.SkillPropertiesSchema; } });
11
11
  var skill_collection_js_1 = require("./skill-collection.js");
12
12
  Object.defineProperty(exports, "skillCollectionTransformer", { enumerable: true, get: function () { return skill_collection_js_1.skillCollectionTransformer; } });
13
+ var template_js_1 = require("./template.js");
14
+ Object.defineProperty(exports, "templateTransformer", { enumerable: true, get: function () { return template_js_1.templateTransformer; } });
15
+ Object.defineProperty(exports, "RenderingTemplateDefinitionSchema", { enumerable: true, get: function () { return template_js_1.RenderingTemplateDefinitionSchema; } });
16
+ var template_collection_js_1 = require("./template-collection.js");
17
+ Object.defineProperty(exports, "templateCollectionTransformer", { enumerable: true, get: function () { return template_collection_js_1.templateCollectionTransformer; } });
13
18
  var raw_js_1 = require("./raw.js");
14
19
  Object.defineProperty(exports, "rawTransformer", { enumerable: true, get: function () { return raw_js_1.rawTransformer; } });
15
20
  var prompt_js_1 = require("./prompt.js");
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/presets/index.ts"],"names":[],"mappings":";AAAA;;GAEG;;;AAEH,uCAAyI;AAAhI,4GAAA,gBAAgB,OAAA;AAAE,iHAAA,qBAAqB,OAAA;AAAE,iHAAA,qBAAqB,OAAA;AACvE,6DAAmE;AAA1D,iIAAA,0BAA0B,OAAA;AACnC,mCAA0C;AAAjC,wGAAA,cAAc,OAAA;AACvB,yCAAiJ;AAAxI,8GAAA,iBAAiB,OAAA;AAAE,mHAAA,sBAAsB,OAAA;AAAiD,uGAAA,UAAU,OAAA;AAAE,yGAAA,YAAY,OAAA"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/presets/index.ts"],"names":[],"mappings":";AAAA;;GAEG;;;AAEH,uCAAyI;AAAhI,4GAAA,gBAAgB,OAAA;AAAE,iHAAA,qBAAqB,OAAA;AAAE,iHAAA,qBAAqB,OAAA;AACvE,6DAAmE;AAA1D,iIAAA,0BAA0B,OAAA;AACnC,6CAAyH;AAAhH,kHAAA,mBAAmB,OAAA;AAAE,gIAAA,iCAAiC,OAAA;AAC/D,mEAAyE;AAAhE,uIAAA,6BAA6B,OAAA;AACtC,mCAA0C;AAAjC,wGAAA,cAAc,OAAA;AACvB,yCAAiJ;AAAxI,8GAAA,iBAAiB,OAAA;AAAE,mHAAA,sBAAsB,OAAA;AAAiD,uGAAA,UAAU,OAAA;AAAE,yGAAA,YAAY,OAAA"}
@@ -0,0 +1,80 @@
1
+ "use strict";
2
+ /**
3
+ * Template collection transformer for directory-based template imports
4
+ * Scans a directory for subdirectories containing TEMPLATE.md files
5
+ */
6
+ var __importDefault = (this && this.__importDefault) || function (mod) {
7
+ return (mod && mod.__esModule) ? mod : { "default": mod };
8
+ };
9
+ Object.defineProperty(exports, "__esModule", { value: true });
10
+ exports.templateCollectionTransformer = void 0;
11
+ const node_fs_1 = require("node:fs");
12
+ const node_path_1 = __importDefault(require("node:path"));
13
+ /**
14
+ * Template collection transformer preset
15
+ * Transforms directory imports with ?templates suffix into an array of template imports
16
+ *
17
+ * Matches:
18
+ * - ./all?templates (recommended - generates all.js in the directory)
19
+ * - Any path ending with a filename and ?templates
20
+ *
21
+ * NOTE: A filename before ?templates is REQUIRED to avoid naming conflicts.
22
+ * The filename becomes the output module name.
23
+ *
24
+ * @example
25
+ * ```typescript
26
+ * import templates from './all?templates';
27
+ * // Scans current directory for subdirectories with TEMPLATE.md
28
+ * // Generates all.js containing array of all templates
29
+ * ```
30
+ */
31
+ exports.templateCollectionTransformer = {
32
+ pattern: /\/[^/?]+\?templates$/,
33
+ virtual: true,
34
+ transform: (_content, filePath) => {
35
+ // Remove ?templates suffix and the filename to get directory path
36
+ const pathWithoutQuery = filePath.replace(/\?templates$/, '');
37
+ const dirPath = node_path_1.default.dirname(pathWithoutQuery);
38
+ if (!(0, node_fs_1.existsSync)(dirPath)) {
39
+ throw new Error(`Directory not found: ${dirPath}`);
40
+ }
41
+ if (!(0, node_fs_1.statSync)(dirPath).isDirectory()) {
42
+ throw new Error(`Not a directory: ${dirPath}`);
43
+ }
44
+ // Scan for subdirectories containing TEMPLATE.md
45
+ const entries = (0, node_fs_1.readdirSync)(dirPath);
46
+ const imports = [];
47
+ const names = [];
48
+ for (const entry of entries) {
49
+ const entryPath = node_path_1.default.join(dirPath, entry);
50
+ try {
51
+ if ((0, node_fs_1.statSync)(entryPath).isDirectory()) {
52
+ const templateFile = node_path_1.default.join(entryPath, 'TEMPLATE.md');
53
+ if ((0, node_fs_1.existsSync)(templateFile)) {
54
+ const identifier = `Template_${entry.replace(/[^a-zA-Z0-9_]/g, '_')}`;
55
+ imports.push(`import ${identifier} from './${entry}/TEMPLATE.md';`);
56
+ names.push(identifier);
57
+ }
58
+ }
59
+ }
60
+ catch (_err) {
61
+ // Skip entries that can't be read
62
+ continue;
63
+ }
64
+ }
65
+ if (names.length === 0) {
66
+ console.warn(`No TEMPLATE.md files found in subdirectories of ${dirPath}`);
67
+ }
68
+ // Generate code that imports all templates and exports as array
69
+ const code = [
70
+ ...imports,
71
+ '',
72
+ `export default [${names.join(', ')}];`
73
+ ].join('\n');
74
+ return {
75
+ data: null,
76
+ code
77
+ };
78
+ }
79
+ };
80
+ //# sourceMappingURL=template-collection.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"template-collection.js","sourceRoot":"","sources":["../../../src/presets/template-collection.ts"],"names":[],"mappings":";AAAA;;;GAGG;;;;;;AAEH,qCAA4D;AAC5D,0DAA6B;AAG7B;;;;;;;;;;;;;;;;;GAiBG;AACU,QAAA,6BAA6B,GAAsB;IAC5D,OAAO,EAAE,sBAAsB;IAC/B,OAAO,EAAE,IAAI;IACb,SAAS,EAAE,CAAC,QAAgB,EAAE,QAAgB,EAAE,EAAE;QAC9C,kEAAkE;QAClE,MAAM,gBAAgB,GAAG,QAAQ,CAAC,OAAO,CAAC,cAAc,EAAE,EAAE,CAAC,CAAC;QAC9D,MAAM,OAAO,GAAG,mBAAI,CAAC,OAAO,CAAC,gBAAgB,CAAC,CAAC;QAE/C,IAAI,CAAC,IAAA,oBAAU,EAAC,OAAO,CAAC,EAAE,CAAC;YACvB,MAAM,IAAI,KAAK,CAAC,wBAAwB,OAAO,EAAE,CAAC,CAAC;QACvD,CAAC;QAED,IAAI,CAAC,IAAA,kBAAQ,EAAC,OAAO,CAAC,CAAC,WAAW,EAAE,EAAE,CAAC;YACnC,MAAM,IAAI,KAAK,CAAC,oBAAoB,OAAO,EAAE,CAAC,CAAC;QACnD,CAAC;QAED,iDAAiD;QACjD,MAAM,OAAO,GAAG,IAAA,qBAAW,EAAC,OAAO,CAAC,CAAC;QACrC,MAAM,OAAO,GAAa,EAAE,CAAC;QAC7B,MAAM,KAAK,GAAa,EAAE,CAAC;QAE3B,KAAK,MAAM,KAAK,IAAI,OAAO,EAAE,CAAC;YAC1B,MAAM,SAAS,GAAG,mBAAI,CAAC,IAAI,CAAC,OAAO,EAAE,KAAK,CAAC,CAAC;YAE5C,IAAI,CAAC;gBACD,IAAI,IAAA,kBAAQ,EAAC,SAAS,CAAC,CAAC,WAAW,EAAE,EAAE,CAAC;oBACpC,MAAM,YAAY,GAAG,mBAAI,CAAC,IAAI,CAAC,SAAS,EAAE,aAAa,CAAC,CAAC;oBACzD,IAAI,IAAA,oBAAU,EAAC,YAAY,CAAC,EAAE,CAAC;wBAC3B,MAAM,UAAU,GAAG,YAAY,KAAK,CAAC,OAAO,CAAC,gBAAgB,EAAE,GAAG,CAAC,EAAE,CAAC;wBACtE,OAAO,CAAC,IAAI,CAAC,UAAU,UAAU,YAAY,KAAK,gBAAgB,CAAC,CAAC;wBACpE,KAAK,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;oBAC3B,CAAC;gBACL,CAAC;YACL,CAAC;YAAC,OAAO,IAAI,EAAE,CAAC;gBACZ,kCAAkC;gBAClC,SAAS;YACb,CAAC;QACL,CAAC;QAED,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YACrB,OAAO,CAAC,IAAI,CAAC,mDAAmD,OAAO,EAAE,CAAC,CAAC;QAC/E,CAAC;QAED,gEAAgE;QAChE,MAAM,IAAI,GAAG;YACT,GAAG,OAAO;YACV,EAAE;YACF,mBAAmB,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI;SAC1C,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QAEb,OAAO;YACH,IAAI,EAAE,IAAI;YACV,IAAI;SACP,CAAC;IACN,CAAC;CACJ,CAAC"}
@@ -0,0 +1,105 @@
1
+ "use strict";
2
+ /**
3
+ * Template transformer preset for markdown files with frontmatter
4
+ */
5
+ var __importDefault = (this && this.__importDefault) || function (mod) {
6
+ return (mod && mod.__esModule) ? mod : { "default": mod };
7
+ };
8
+ Object.defineProperty(exports, "__esModule", { value: true });
9
+ exports.templateTransformer = exports.RenderingTemplateDefinitionSchema = void 0;
10
+ const node_path_1 = __importDefault(require("node:path"));
11
+ const zod_1 = require("zod");
12
+ const frontmatter_js_1 = require("../parsers/frontmatter.js");
13
+ const template_asset_discovery_js_1 = require("../utils/template-asset-discovery.js");
14
+ /**
15
+ * Zod schema for template frontmatter validation.
16
+ * Only includes fields authored by the user.
17
+ * The name and id are inferred from the directory structure.
18
+ */
19
+ const TemplateFrontmatterSchema = zod_1.z.object({
20
+ title: zod_1.z.string().optional(),
21
+ description: zod_1.z.string().min(1, 'Template description is required'),
22
+ tags: zod_1.z.array(zod_1.z.string()).optional(),
23
+ type: zod_1.z.enum(['presentation', 'document']),
24
+ }).strict();
25
+ /**
26
+ * MUST be kept in sync with @vertesia/tools-sdk RenderingTemplateDefinition
27
+ * Zod schema for template definition
28
+ */
29
+ exports.RenderingTemplateDefinitionSchema = zod_1.z.object({
30
+ id: zod_1.z.string().min(1, 'Template id is required'),
31
+ name: zod_1.z.string().min(1, 'Template name is required'),
32
+ title: zod_1.z.string().optional(),
33
+ description: zod_1.z.string().min(1, 'Template description is required'),
34
+ instructions: zod_1.z.string(),
35
+ tags: zod_1.z.array(zod_1.z.string()).optional(),
36
+ type: zod_1.z.enum(['presentation', 'document']),
37
+ assets: zod_1.z.array(zod_1.z.string()),
38
+ }).passthrough();
39
+ /**
40
+ * Derive the template path segments from the file path.
41
+ *
42
+ * Example: .../templates/examples/report/TEMPLATE.md
43
+ * → category: "examples", name: "report", relative: "examples/report"
44
+ */
45
+ function deriveTemplatePathInfo(filePath) {
46
+ const templateDir = node_path_1.default.dirname(filePath);
47
+ const templateName = node_path_1.default.basename(templateDir);
48
+ const collectionDir = node_path_1.default.dirname(templateDir);
49
+ const category = node_path_1.default.basename(collectionDir);
50
+ return { category, templateName, relative: `${category}/${templateName}` };
51
+ }
52
+ /**
53
+ * Template transformer preset
54
+ * Transforms markdown files with ?template suffix OR TEMPLATE.md files into template definition objects
55
+ *
56
+ * Matches:
57
+ * - Files with ?template suffix: ./my-template.md?template
58
+ * - TEMPLATE.md files: ./my-template/TEMPLATE.md
59
+ *
60
+ * @example
61
+ * ```typescript
62
+ * import template1 from './my-template.md?template';
63
+ * import template2 from './my-template/TEMPLATE.md';
64
+ * // Both are RenderingTemplateDefinition objects
65
+ * ```
66
+ */
67
+ exports.templateTransformer = {
68
+ pattern: /(\.md\?template$|\/TEMPLATE\.md$)/,
69
+ schema: exports.RenderingTemplateDefinitionSchema,
70
+ transform: (content, filePath) => {
71
+ const { frontmatter, content: markdown } = (0, frontmatter_js_1.parseFrontmatter)(content);
72
+ // Validate frontmatter
73
+ const frontmatterValidation = TemplateFrontmatterSchema.safeParse(frontmatter);
74
+ if (!frontmatterValidation.success) {
75
+ const errors = frontmatterValidation.error.errors
76
+ .map((err) => {
77
+ const pathStr = err.path.length > 0 ? err.path.join('.') : 'frontmatter';
78
+ return ` - ${pathStr}: ${err.message}`;
79
+ })
80
+ .join('\n');
81
+ throw new Error(`Invalid frontmatter in ${filePath}:\n${errors}`);
82
+ }
83
+ // Derive template path from directory structure
84
+ const { category, templateName, relative: templatePath } = deriveTemplatePathInfo(filePath);
85
+ // Discover asset files in the template directory
86
+ const assets = (0, template_asset_discovery_js_1.discoverTemplateAssets)(filePath, templatePath);
87
+ // Build template definition
88
+ // Assets use absolute paths for direct server-side resolution
89
+ const templateData = {
90
+ id: `${category}:${templateName}`,
91
+ name: templateName,
92
+ title: frontmatter.title,
93
+ description: frontmatter.description,
94
+ instructions: markdown,
95
+ tags: frontmatter.tags,
96
+ type: frontmatter.type,
97
+ assets: assets.fileNames.map(f => `/templates/${templatePath}/${f}`),
98
+ };
99
+ return {
100
+ data: templateData,
101
+ assets: assets.assetFiles,
102
+ };
103
+ }
104
+ };
105
+ //# sourceMappingURL=template.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"template.js","sourceRoot":"","sources":["../../../src/presets/template.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,63 @@
1
+ "use strict";
2
+ /**
3
+ * Utilities for discovering asset files in template directories
4
+ */
5
+ var __importDefault = (this && this.__importDefault) || function (mod) {
6
+ return (mod && mod.__esModule) ? mod : { "default": mod };
7
+ };
8
+ Object.defineProperty(exports, "__esModule", { value: true });
9
+ exports.discoverTemplateAssets = discoverTemplateAssets;
10
+ const node_fs_1 = require("node:fs");
11
+ const node_path_1 = __importDefault(require("node:path"));
12
+ /**
13
+ * Files to exclude from template asset discovery
14
+ * (source files and the template definition itself)
15
+ */
16
+ const EXCLUDED_PATTERNS = [
17
+ /^TEMPLATE\.md$/,
18
+ /\.ts$/,
19
+ /\.js$/,
20
+ ];
21
+ function isExcluded(fileName) {
22
+ return EXCLUDED_PATTERNS.some(p => p.test(fileName));
23
+ }
24
+ /**
25
+ * Discover asset files in a template directory.
26
+ * All files except TEMPLATE.md, *.ts, and *.js are considered assets.
27
+ *
28
+ * @param templateFilePath - Absolute path to the TEMPLATE.md file
29
+ * @param templatePath - The template path segment (e.g., "examples/report")
30
+ * @returns Discovered assets and metadata
31
+ */
32
+ function discoverTemplateAssets(templateFilePath, templatePath) {
33
+ const templateDir = node_path_1.default.dirname(templateFilePath);
34
+ const fileNames = [];
35
+ const assetFiles = [];
36
+ let files;
37
+ try {
38
+ files = (0, node_fs_1.readdirSync)(templateDir).filter(file => {
39
+ try {
40
+ return (0, node_fs_1.statSync)(node_path_1.default.join(templateDir, file)).isFile();
41
+ }
42
+ catch {
43
+ return false;
44
+ }
45
+ });
46
+ }
47
+ catch {
48
+ files = [];
49
+ }
50
+ for (const file of files) {
51
+ if (isExcluded(file)) {
52
+ continue;
53
+ }
54
+ fileNames.push(file);
55
+ assetFiles.push({
56
+ sourcePath: node_path_1.default.join(templateDir, file),
57
+ destPath: node_path_1.default.join('templates', templatePath, file),
58
+ type: 'template',
59
+ });
60
+ }
61
+ return { fileNames, assetFiles };
62
+ }
63
+ //# sourceMappingURL=template-asset-discovery.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"template-asset-discovery.js","sourceRoot":"","sources":["../../../src/utils/template-asset-discovery.ts"],"names":[],"mappings":";AAAA;;GAEG;;;;;AAuCH,wDAmCC;AAxED,qCAAgD;AAChD,0DAA6B;AAc7B;;;GAGG;AACH,MAAM,iBAAiB,GAAG;IACtB,gBAAgB;IAChB,OAAO;IACP,OAAO;CACV,CAAC;AAEF,SAAS,UAAU,CAAC,QAAgB;IAChC,OAAO,iBAAiB,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAC;AACzD,CAAC;AAED;;;;;;;GAOG;AACH,SAAgB,sBAAsB,CAClC,gBAAwB,EACxB,YAAoB;IAEpB,MAAM,WAAW,GAAG,mBAAI,CAAC,OAAO,CAAC,gBAAgB,CAAC,CAAC;IACnD,MAAM,SAAS,GAAa,EAAE,CAAC;IAC/B,MAAM,UAAU,GAAgB,EAAE,CAAC;IAEnC,IAAI,KAAe,CAAC;IACpB,IAAI,CAAC;QACD,KAAK,GAAG,IAAA,qBAAW,EAAC,WAAW,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,EAAE;YAC3C,IAAI,CAAC;gBACD,OAAO,IAAA,kBAAQ,EAAC,mBAAI,CAAC,IAAI,CAAC,WAAW,EAAE,IAAI,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC;YAC3D,CAAC;YAAC,MAAM,CAAC;gBACL,OAAO,KAAK,CAAC;YACjB,CAAC;QACL,CAAC,CAAC,CAAC;IACP,CAAC;IAAC,MAAM,CAAC;QACL,KAAK,GAAG,EAAE,CAAC;IACf,CAAC;IAED,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;QACvB,IAAI,UAAU,CAAC,IAAI,CAAC,EAAE,CAAC;YACnB,SAAS;QACb,CAAC;QAED,SAAS,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QACrB,UAAU,CAAC,IAAI,CAAC;YACZ,UAAU,EAAE,mBAAI,CAAC,IAAI,CAAC,WAAW,EAAE,IAAI,CAAC;YACxC,QAAQ,EAAE,mBAAI,CAAC,IAAI,CAAC,WAAW,EAAE,YAAY,EAAE,IAAI,CAAC;YACpD,IAAI,EAAE,UAAU;SACnB,CAAC,CAAC;IACP,CAAC;IAED,OAAO,EAAE,SAAS,EAAE,UAAU,EAAE,CAAC;AACrC,CAAC"}
package/lib/esm/index.js CHANGED
@@ -20,7 +20,7 @@
20
20
  // Core plugin
21
21
  export { vertesiaImportPlugin } from './plugin.js';
22
22
  // Presets
23
- export { skillTransformer, rawTransformer, skillCollectionTransformer, promptTransformer, SkillDefinitionSchema, SkillPropertiesSchema, PromptDefinitionSchema, PromptRole, TemplateType } from './presets/index.js';
23
+ export { skillTransformer, rawTransformer, skillCollectionTransformer, templateTransformer, templateCollectionTransformer, promptTransformer, SkillDefinitionSchema, SkillPropertiesSchema, RenderingTemplateDefinitionSchema, PromptDefinitionSchema, PromptRole, TemplateType } from './presets/index.js';
24
24
  // Utilities
25
25
  export { parseFrontmatter } from './parsers/frontmatter.js';
26
26
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;GAkBG;AAEH,cAAc;AACd,OAAO,EAAE,oBAAoB,EAAE,MAAM,aAAa,CAAC;AAanD,UAAU;AACV,OAAO,EACH,gBAAgB,EAChB,cAAc,EACd,0BAA0B,EAC1B,iBAAiB,EACjB,qBAAqB,EACrB,qBAAqB,EACrB,sBAAsB,EAKtB,UAAU,EACV,YAAY,EACf,MAAM,oBAAoB,CAAC;AAE5B,YAAY;AACZ,OAAO,EAAE,gBAAgB,EAA0B,MAAM,0BAA0B,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;GAkBG;AAEH,cAAc;AACd,OAAO,EAAE,oBAAoB,EAAE,MAAM,aAAa,CAAC;AAanD,UAAU;AACV,OAAO,EACH,gBAAgB,EAChB,cAAc,EACd,0BAA0B,EAC1B,mBAAmB,EACnB,6BAA6B,EAC7B,iBAAiB,EACjB,qBAAqB,EACrB,qBAAqB,EACrB,iCAAiC,EACjC,sBAAsB,EAMtB,UAAU,EACV,YAAY,EACf,MAAM,oBAAoB,CAAC;AAE5B,YAAY;AACZ,OAAO,EAAE,gBAAgB,EAA0B,MAAM,0BAA0B,CAAC"}
@@ -3,6 +3,8 @@
3
3
  */
4
4
  export { skillTransformer, SkillDefinitionSchema, SkillPropertiesSchema } from './skill.js';
5
5
  export { skillCollectionTransformer } from './skill-collection.js';
6
+ export { templateTransformer, RenderingTemplateDefinitionSchema } from './template.js';
7
+ export { templateCollectionTransformer } from './template-collection.js';
6
8
  export { rawTransformer } from './raw.js';
7
9
  export { promptTransformer, PromptDefinitionSchema, PromptRole, TemplateType } from './prompt.js';
8
10
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/presets/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,gBAAgB,EAAE,qBAAqB,EAAE,qBAAqB,EAA+C,MAAM,YAAY,CAAC;AACzI,OAAO,EAAE,0BAA0B,EAAE,MAAM,uBAAuB,CAAC;AACnE,OAAO,EAAE,cAAc,EAAE,MAAM,UAAU,CAAC;AAC1C,OAAO,EAAE,iBAAiB,EAAE,sBAAsB,EAAiD,UAAU,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/presets/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,gBAAgB,EAAE,qBAAqB,EAAE,qBAAqB,EAA+C,MAAM,YAAY,CAAC;AACzI,OAAO,EAAE,0BAA0B,EAAE,MAAM,uBAAuB,CAAC;AACnE,OAAO,EAAE,mBAAmB,EAAE,iCAAiC,EAAoC,MAAM,eAAe,CAAC;AACzH,OAAO,EAAE,6BAA6B,EAAE,MAAM,0BAA0B,CAAC;AACzE,OAAO,EAAE,cAAc,EAAE,MAAM,UAAU,CAAC;AAC1C,OAAO,EAAE,iBAAiB,EAAE,sBAAsB,EAAiD,UAAU,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC"}
@@ -0,0 +1,74 @@
1
+ /**
2
+ * Template collection transformer for directory-based template imports
3
+ * Scans a directory for subdirectories containing TEMPLATE.md files
4
+ */
5
+ import { readdirSync, statSync, existsSync } from 'node:fs';
6
+ import path from 'node:path';
7
+ /**
8
+ * Template collection transformer preset
9
+ * Transforms directory imports with ?templates suffix into an array of template imports
10
+ *
11
+ * Matches:
12
+ * - ./all?templates (recommended - generates all.js in the directory)
13
+ * - Any path ending with a filename and ?templates
14
+ *
15
+ * NOTE: A filename before ?templates is REQUIRED to avoid naming conflicts.
16
+ * The filename becomes the output module name.
17
+ *
18
+ * @example
19
+ * ```typescript
20
+ * import templates from './all?templates';
21
+ * // Scans current directory for subdirectories with TEMPLATE.md
22
+ * // Generates all.js containing array of all templates
23
+ * ```
24
+ */
25
+ export const templateCollectionTransformer = {
26
+ pattern: /\/[^/?]+\?templates$/,
27
+ virtual: true,
28
+ transform: (_content, filePath) => {
29
+ // Remove ?templates suffix and the filename to get directory path
30
+ const pathWithoutQuery = filePath.replace(/\?templates$/, '');
31
+ const dirPath = path.dirname(pathWithoutQuery);
32
+ if (!existsSync(dirPath)) {
33
+ throw new Error(`Directory not found: ${dirPath}`);
34
+ }
35
+ if (!statSync(dirPath).isDirectory()) {
36
+ throw new Error(`Not a directory: ${dirPath}`);
37
+ }
38
+ // Scan for subdirectories containing TEMPLATE.md
39
+ const entries = readdirSync(dirPath);
40
+ const imports = [];
41
+ const names = [];
42
+ for (const entry of entries) {
43
+ const entryPath = path.join(dirPath, entry);
44
+ try {
45
+ if (statSync(entryPath).isDirectory()) {
46
+ const templateFile = path.join(entryPath, 'TEMPLATE.md');
47
+ if (existsSync(templateFile)) {
48
+ const identifier = `Template_${entry.replace(/[^a-zA-Z0-9_]/g, '_')}`;
49
+ imports.push(`import ${identifier} from './${entry}/TEMPLATE.md';`);
50
+ names.push(identifier);
51
+ }
52
+ }
53
+ }
54
+ catch (_err) {
55
+ // Skip entries that can't be read
56
+ continue;
57
+ }
58
+ }
59
+ if (names.length === 0) {
60
+ console.warn(`No TEMPLATE.md files found in subdirectories of ${dirPath}`);
61
+ }
62
+ // Generate code that imports all templates and exports as array
63
+ const code = [
64
+ ...imports,
65
+ '',
66
+ `export default [${names.join(', ')}];`
67
+ ].join('\n');
68
+ return {
69
+ data: null,
70
+ code
71
+ };
72
+ }
73
+ };
74
+ //# sourceMappingURL=template-collection.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"template-collection.js","sourceRoot":"","sources":["../../../src/presets/template-collection.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,WAAW,EAAE,QAAQ,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;AAC5D,OAAO,IAAI,MAAM,WAAW,CAAC;AAG7B;;;;;;;;;;;;;;;;;GAiBG;AACH,MAAM,CAAC,MAAM,6BAA6B,GAAsB;IAC5D,OAAO,EAAE,sBAAsB;IAC/B,OAAO,EAAE,IAAI;IACb,SAAS,EAAE,CAAC,QAAgB,EAAE,QAAgB,EAAE,EAAE;QAC9C,kEAAkE;QAClE,MAAM,gBAAgB,GAAG,QAAQ,CAAC,OAAO,CAAC,cAAc,EAAE,EAAE,CAAC,CAAC;QAC9D,MAAM,OAAO,GAAG,IAAI,CAAC,OAAO,CAAC,gBAAgB,CAAC,CAAC;QAE/C,IAAI,CAAC,UAAU,CAAC,OAAO,CAAC,EAAE,CAAC;YACvB,MAAM,IAAI,KAAK,CAAC,wBAAwB,OAAO,EAAE,CAAC,CAAC;QACvD,CAAC;QAED,IAAI,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC,WAAW,EAAE,EAAE,CAAC;YACnC,MAAM,IAAI,KAAK,CAAC,oBAAoB,OAAO,EAAE,CAAC,CAAC;QACnD,CAAC;QAED,iDAAiD;QACjD,MAAM,OAAO,GAAG,WAAW,CAAC,OAAO,CAAC,CAAC;QACrC,MAAM,OAAO,GAAa,EAAE,CAAC;QAC7B,MAAM,KAAK,GAAa,EAAE,CAAC;QAE3B,KAAK,MAAM,KAAK,IAAI,OAAO,EAAE,CAAC;YAC1B,MAAM,SAAS,GAAG,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,KAAK,CAAC,CAAC;YAE5C,IAAI,CAAC;gBACD,IAAI,QAAQ,CAAC,SAAS,CAAC,CAAC,WAAW,EAAE,EAAE,CAAC;oBACpC,MAAM,YAAY,GAAG,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE,aAAa,CAAC,CAAC;oBACzD,IAAI,UAAU,CAAC,YAAY,CAAC,EAAE,CAAC;wBAC3B,MAAM,UAAU,GAAG,YAAY,KAAK,CAAC,OAAO,CAAC,gBAAgB,EAAE,GAAG,CAAC,EAAE,CAAC;wBACtE,OAAO,CAAC,IAAI,CAAC,UAAU,UAAU,YAAY,KAAK,gBAAgB,CAAC,CAAC;wBACpE,KAAK,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;oBAC3B,CAAC;gBACL,CAAC;YACL,CAAC;YAAC,OAAO,IAAI,EAAE,CAAC;gBACZ,kCAAkC;gBAClC,SAAS;YACb,CAAC;QACL,CAAC;QAED,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YACrB,OAAO,CAAC,IAAI,CAAC,mDAAmD,OAAO,EAAE,CAAC,CAAC;QAC/E,CAAC;QAED,gEAAgE;QAChE,MAAM,IAAI,GAAG;YACT,GAAG,OAAO;YACV,EAAE;YACF,mBAAmB,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI;SAC1C,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QAEb,OAAO;YACH,IAAI,EAAE,IAAI;YACV,IAAI;SACP,CAAC;IACN,CAAC;CACJ,CAAC"}
@@ -0,0 +1,99 @@
1
+ /**
2
+ * Template transformer preset for markdown files with frontmatter
3
+ */
4
+ import path from 'node:path';
5
+ import { z } from 'zod';
6
+ import { parseFrontmatter } from '../parsers/frontmatter.js';
7
+ import { discoverTemplateAssets } from '../utils/template-asset-discovery.js';
8
+ /**
9
+ * Zod schema for template frontmatter validation.
10
+ * Only includes fields authored by the user.
11
+ * The name and id are inferred from the directory structure.
12
+ */
13
+ const TemplateFrontmatterSchema = z.object({
14
+ title: z.string().optional(),
15
+ description: z.string().min(1, 'Template description is required'),
16
+ tags: z.array(z.string()).optional(),
17
+ type: z.enum(['presentation', 'document']),
18
+ }).strict();
19
+ /**
20
+ * MUST be kept in sync with @vertesia/tools-sdk RenderingTemplateDefinition
21
+ * Zod schema for template definition
22
+ */
23
+ export const RenderingTemplateDefinitionSchema = z.object({
24
+ id: z.string().min(1, 'Template id is required'),
25
+ name: z.string().min(1, 'Template name is required'),
26
+ title: z.string().optional(),
27
+ description: z.string().min(1, 'Template description is required'),
28
+ instructions: z.string(),
29
+ tags: z.array(z.string()).optional(),
30
+ type: z.enum(['presentation', 'document']),
31
+ assets: z.array(z.string()),
32
+ }).passthrough();
33
+ /**
34
+ * Derive the template path segments from the file path.
35
+ *
36
+ * Example: .../templates/examples/report/TEMPLATE.md
37
+ * → category: "examples", name: "report", relative: "examples/report"
38
+ */
39
+ function deriveTemplatePathInfo(filePath) {
40
+ const templateDir = path.dirname(filePath);
41
+ const templateName = path.basename(templateDir);
42
+ const collectionDir = path.dirname(templateDir);
43
+ const category = path.basename(collectionDir);
44
+ return { category, templateName, relative: `${category}/${templateName}` };
45
+ }
46
+ /**
47
+ * Template transformer preset
48
+ * Transforms markdown files with ?template suffix OR TEMPLATE.md files into template definition objects
49
+ *
50
+ * Matches:
51
+ * - Files with ?template suffix: ./my-template.md?template
52
+ * - TEMPLATE.md files: ./my-template/TEMPLATE.md
53
+ *
54
+ * @example
55
+ * ```typescript
56
+ * import template1 from './my-template.md?template';
57
+ * import template2 from './my-template/TEMPLATE.md';
58
+ * // Both are RenderingTemplateDefinition objects
59
+ * ```
60
+ */
61
+ export const templateTransformer = {
62
+ pattern: /(\.md\?template$|\/TEMPLATE\.md$)/,
63
+ schema: RenderingTemplateDefinitionSchema,
64
+ transform: (content, filePath) => {
65
+ const { frontmatter, content: markdown } = parseFrontmatter(content);
66
+ // Validate frontmatter
67
+ const frontmatterValidation = TemplateFrontmatterSchema.safeParse(frontmatter);
68
+ if (!frontmatterValidation.success) {
69
+ const errors = frontmatterValidation.error.errors
70
+ .map((err) => {
71
+ const pathStr = err.path.length > 0 ? err.path.join('.') : 'frontmatter';
72
+ return ` - ${pathStr}: ${err.message}`;
73
+ })
74
+ .join('\n');
75
+ throw new Error(`Invalid frontmatter in ${filePath}:\n${errors}`);
76
+ }
77
+ // Derive template path from directory structure
78
+ const { category, templateName, relative: templatePath } = deriveTemplatePathInfo(filePath);
79
+ // Discover asset files in the template directory
80
+ const assets = discoverTemplateAssets(filePath, templatePath);
81
+ // Build template definition
82
+ // Assets use absolute paths for direct server-side resolution
83
+ const templateData = {
84
+ id: `${category}:${templateName}`,
85
+ name: templateName,
86
+ title: frontmatter.title,
87
+ description: frontmatter.description,
88
+ instructions: markdown,
89
+ tags: frontmatter.tags,
90
+ type: frontmatter.type,
91
+ assets: assets.fileNames.map(f => `/templates/${templatePath}/${f}`),
92
+ };
93
+ return {
94
+ data: templateData,
95
+ assets: assets.assetFiles,
96
+ };
97
+ }
98
+ };
99
+ //# sourceMappingURL=template.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"template.js","sourceRoot":"","sources":["../../../src/presets/template.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,57 @@
1
+ /**
2
+ * Utilities for discovering asset files in template directories
3
+ */
4
+ import { readdirSync, statSync } from 'node:fs';
5
+ import path from 'node:path';
6
+ /**
7
+ * Files to exclude from template asset discovery
8
+ * (source files and the template definition itself)
9
+ */
10
+ const EXCLUDED_PATTERNS = [
11
+ /^TEMPLATE\.md$/,
12
+ /\.ts$/,
13
+ /\.js$/,
14
+ ];
15
+ function isExcluded(fileName) {
16
+ return EXCLUDED_PATTERNS.some(p => p.test(fileName));
17
+ }
18
+ /**
19
+ * Discover asset files in a template directory.
20
+ * All files except TEMPLATE.md, *.ts, and *.js are considered assets.
21
+ *
22
+ * @param templateFilePath - Absolute path to the TEMPLATE.md file
23
+ * @param templatePath - The template path segment (e.g., "examples/report")
24
+ * @returns Discovered assets and metadata
25
+ */
26
+ export function discoverTemplateAssets(templateFilePath, templatePath) {
27
+ const templateDir = path.dirname(templateFilePath);
28
+ const fileNames = [];
29
+ const assetFiles = [];
30
+ let files;
31
+ try {
32
+ files = readdirSync(templateDir).filter(file => {
33
+ try {
34
+ return statSync(path.join(templateDir, file)).isFile();
35
+ }
36
+ catch {
37
+ return false;
38
+ }
39
+ });
40
+ }
41
+ catch {
42
+ files = [];
43
+ }
44
+ for (const file of files) {
45
+ if (isExcluded(file)) {
46
+ continue;
47
+ }
48
+ fileNames.push(file);
49
+ assetFiles.push({
50
+ sourcePath: path.join(templateDir, file),
51
+ destPath: path.join('templates', templatePath, file),
52
+ type: 'template',
53
+ });
54
+ }
55
+ return { fileNames, assetFiles };
56
+ }
57
+ //# sourceMappingURL=template-asset-discovery.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"template-asset-discovery.js","sourceRoot":"","sources":["../../../src/utils/template-asset-discovery.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,WAAW,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAC;AAChD,OAAO,IAAI,MAAM,WAAW,CAAC;AAc7B;;;GAGG;AACH,MAAM,iBAAiB,GAAG;IACtB,gBAAgB;IAChB,OAAO;IACP,OAAO;CACV,CAAC;AAEF,SAAS,UAAU,CAAC,QAAgB;IAChC,OAAO,iBAAiB,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAC;AACzD,CAAC;AAED;;;;;;;GAOG;AACH,MAAM,UAAU,sBAAsB,CAClC,gBAAwB,EACxB,YAAoB;IAEpB,MAAM,WAAW,GAAG,IAAI,CAAC,OAAO,CAAC,gBAAgB,CAAC,CAAC;IACnD,MAAM,SAAS,GAAa,EAAE,CAAC;IAC/B,MAAM,UAAU,GAAgB,EAAE,CAAC;IAEnC,IAAI,KAAe,CAAC;IACpB,IAAI,CAAC;QACD,KAAK,GAAG,WAAW,CAAC,WAAW,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,EAAE;YAC3C,IAAI,CAAC;gBACD,OAAO,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,WAAW,EAAE,IAAI,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC;YAC3D,CAAC;YAAC,MAAM,CAAC;gBACL,OAAO,KAAK,CAAC;YACjB,CAAC;QACL,CAAC,CAAC,CAAC;IACP,CAAC;IAAC,MAAM,CAAC;QACL,KAAK,GAAG,EAAE,CAAC;IACf,CAAC;IAED,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;QACvB,IAAI,UAAU,CAAC,IAAI,CAAC,EAAE,CAAC;YACnB,SAAS;QACb,CAAC;QAED,SAAS,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QACrB,UAAU,CAAC,IAAI,CAAC;YACZ,UAAU,EAAE,IAAI,CAAC,IAAI,CAAC,WAAW,EAAE,IAAI,CAAC;YACxC,QAAQ,EAAE,IAAI,CAAC,IAAI,CAAC,WAAW,EAAE,YAAY,EAAE,IAAI,CAAC;YACpD,IAAI,EAAE,UAAU;SACnB,CAAC,CAAC;IACP,CAAC;IAED,OAAO,EAAE,SAAS,EAAE,UAAU,EAAE,CAAC;AACrC,CAAC"}
@@ -19,6 +19,6 @@
19
19
  */
20
20
  export { vertesiaImportPlugin } from './plugin.js';
21
21
  export type { PluginConfig, TransformerRule, TransformerPreset, TransformFunction, TransformResult, AssetFile, WidgetConfig } from './types.js';
22
- export { skillTransformer, rawTransformer, skillCollectionTransformer, promptTransformer, SkillDefinitionSchema, SkillPropertiesSchema, PromptDefinitionSchema, type SkillDefinition, type SkillContentType, type PromptDefinition, type PromptContentType, PromptRole, TemplateType } from './presets/index.js';
22
+ export { skillTransformer, rawTransformer, skillCollectionTransformer, templateTransformer, templateCollectionTransformer, promptTransformer, SkillDefinitionSchema, SkillPropertiesSchema, RenderingTemplateDefinitionSchema, PromptDefinitionSchema, type SkillDefinition, type SkillContentType, type RenderingTemplateDefinition, type PromptDefinition, type PromptContentType, PromptRole, TemplateType } from './presets/index.js';
23
23
  export { parseFrontmatter, type FrontmatterResult } from './parsers/frontmatter.js';
24
24
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;GAkBG;AAGH,OAAO,EAAE,oBAAoB,EAAE,MAAM,aAAa,CAAC;AAGnD,YAAY,EACR,YAAY,EACZ,eAAe,EACf,iBAAiB,EACjB,iBAAiB,EACjB,eAAe,EACf,SAAS,EACT,YAAY,EACf,MAAM,YAAY,CAAC;AAGpB,OAAO,EACH,gBAAgB,EAChB,cAAc,EACd,0BAA0B,EAC1B,iBAAiB,EACjB,qBAAqB,EACrB,qBAAqB,EACrB,sBAAsB,EACtB,KAAK,eAAe,EACpB,KAAK,gBAAgB,EACrB,KAAK,gBAAgB,EACrB,KAAK,iBAAiB,EACtB,UAAU,EACV,YAAY,EACf,MAAM,oBAAoB,CAAC;AAG5B,OAAO,EAAE,gBAAgB,EAAE,KAAK,iBAAiB,EAAE,MAAM,0BAA0B,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;GAkBG;AAGH,OAAO,EAAE,oBAAoB,EAAE,MAAM,aAAa,CAAC;AAGnD,YAAY,EACR,YAAY,EACZ,eAAe,EACf,iBAAiB,EACjB,iBAAiB,EACjB,eAAe,EACf,SAAS,EACT,YAAY,EACf,MAAM,YAAY,CAAC;AAGpB,OAAO,EACH,gBAAgB,EAChB,cAAc,EACd,0BAA0B,EAC1B,mBAAmB,EACnB,6BAA6B,EAC7B,iBAAiB,EACjB,qBAAqB,EACrB,qBAAqB,EACrB,iCAAiC,EACjC,sBAAsB,EACtB,KAAK,eAAe,EACpB,KAAK,gBAAgB,EACrB,KAAK,2BAA2B,EAChC,KAAK,gBAAgB,EACrB,KAAK,iBAAiB,EACtB,UAAU,EACV,YAAY,EACf,MAAM,oBAAoB,CAAC;AAG5B,OAAO,EAAE,gBAAgB,EAAE,KAAK,iBAAiB,EAAE,MAAM,0BAA0B,CAAC"}
@@ -3,6 +3,8 @@
3
3
  */
4
4
  export { skillTransformer, SkillDefinitionSchema, SkillPropertiesSchema, type SkillDefinition, type SkillContentType } from './skill.js';
5
5
  export { skillCollectionTransformer } from './skill-collection.js';
6
+ export { templateTransformer, RenderingTemplateDefinitionSchema, type RenderingTemplateDefinition } from './template.js';
7
+ export { templateCollectionTransformer } from './template-collection.js';
6
8
  export { rawTransformer } from './raw.js';
7
9
  export { promptTransformer, PromptDefinitionSchema, type PromptDefinition, type PromptContentType, PromptRole, TemplateType } from './prompt.js';
8
10
  //# sourceMappingURL=index.d.ts.map