@brand-map/generator 0.0.0-dev.14 → 0.1.0

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 (45) hide show
  1. package/.oxfmtrc.json +29 -0
  2. package/.oxlintrc.json +144 -0
  3. package/README.md +207 -7
  4. package/bun.lock +47 -19
  5. package/package.json +15 -20
  6. package/src/actions/load-templates.ts +58 -0
  7. package/src/exports.ts +2 -0
  8. package/src/generator.ts +138 -0
  9. package/{lib.ts → src/lib.ts} +4 -4
  10. package/src/renderer-handlebars.ts +27 -0
  11. package/src/renderer-vento.ts +21 -0
  12. package/{types.ts → src/types.ts} +6 -4
  13. package/tsconfig.json +1 -1
  14. package/TODO.md +0 -2
  15. package/actions/ai.ts +0 -7
  16. package/actions/answer.ts +0 -7
  17. package/actions/blank.ts +0 -55
  18. package/actions/combine.ts +0 -14
  19. package/actions/config.ts +0 -7
  20. package/actions/context/context.ts +0 -44
  21. package/actions/context.ts +0 -10
  22. package/actions/echo.ts +0 -19
  23. package/actions/exports.ts +0 -9
  24. package/actions/jargal-context.ts +0 -21
  25. package/actions/jargal-templates.ts +0 -82
  26. package/actions/jargal-write.ts +0 -46
  27. package/actions/load-templates.ts +0 -125
  28. package/actions/modify.ts +0 -7
  29. package/actions/parallel.ts +0 -16
  30. package/actions/pipe/pipe.ts +0 -993
  31. package/actions/pipe.ts +0 -7
  32. package/actions/prompt.ts +0 -134
  33. package/actions/render-template.ts +0 -39
  34. package/actions/run/run.ts +0 -20
  35. package/actions/select-generator.ts +0 -28
  36. package/actions/use.ts +0 -9
  37. package/actions/validate-answers.ts +0 -13
  38. package/actions/write/write.ts +0 -69
  39. package/actions/write.ts +0 -51
  40. package/biome.json +0 -35
  41. package/exports.ts +0 -8
  42. package/jargal.ts +0 -181
  43. package/renderer.ts +0 -100
  44. package/runner.test.ts +0 -24
  45. package/runner.ts +0 -99
package/.oxfmtrc.json ADDED
@@ -0,0 +1,29 @@
1
+ {
2
+ "$schema": "./node_modules/oxfmt/configuration_schema.json",
3
+ "ignorePatterns": [],
4
+ "printWidth": 160,
5
+ "tabWidth": 2,
6
+ "semi": true,
7
+ "arrowParens": "always",
8
+ "experimentalSortPackageJson": true,
9
+ "useTabs": false,
10
+ "trailingComma": "all",
11
+ "singleQuote": false,
12
+ "singleAttributePerLine": true,
13
+ "quoteProps": "consistent",
14
+ "insertFinalNewline": true,
15
+ "embeddedLanguageFormatting": "auto",
16
+ "bracketSpacing": true,
17
+
18
+ "experimentalSortImports": {
19
+ "groups": [
20
+ ["side-effect"],
21
+ ["builtin"],
22
+ ["external", "external-type"],
23
+ ["internal", "internal-type"],
24
+ ["parent", "parent-type"],
25
+ ["sibling", "sibling-type"],
26
+ ["index", "index-type"]
27
+ ]
28
+ }
29
+ }
package/.oxlintrc.json ADDED
@@ -0,0 +1,144 @@
1
+ {
2
+ "$schema": "./node_modules/oxlint/configuration_schema.json",
3
+ "plugins": ["unicorn", "typescript", "oxc", "import"],
4
+ "categories": {},
5
+ "rules": {
6
+ "constructor-super": "warn",
7
+ "for-direction": "warn",
8
+ "no-async-promise-executor": "warn",
9
+ "no-caller": "warn",
10
+ "no-class-assign": "warn",
11
+ "no-compare-neg-zero": "warn",
12
+ "no-cond-assign": "warn",
13
+ "no-const-assign": "warn",
14
+ "no-constant-binary-expression": "warn",
15
+ "no-constant-condition": "warn",
16
+ "no-control-regex": "warn",
17
+ "no-debugger": "warn",
18
+ "no-delete-var": "warn",
19
+ "no-dupe-class-members": "warn",
20
+ "no-dupe-else-if": "warn",
21
+ "no-dupe-keys": "warn",
22
+ "no-duplicate-case": "warn",
23
+ "no-empty-character-class": "warn",
24
+ "no-empty-pattern": "warn",
25
+ "no-empty-static-block": "warn",
26
+ "no-eval": "warn",
27
+ "no-ex-assign": "warn",
28
+ "no-extra-boolean-cast": "warn",
29
+ "no-func-assign": "warn",
30
+ "no-global-assign": "warn",
31
+ "no-import-assign": "warn",
32
+ "no-invalid-regexp": "warn",
33
+ "no-irregular-whitespace": "warn",
34
+ "no-loss-of-precision": "warn",
35
+ "no-new-native-nonconstructor": "warn",
36
+ "no-nonoctal-decimal-escape": "warn",
37
+ "no-obj-calls": "warn",
38
+ "no-self-assign": "warn",
39
+ "no-setter-return": "warn",
40
+ "no-shadow-restricted-names": "warn",
41
+ "no-sparse-arrays": "warn",
42
+ "no-this-before-super": "warn",
43
+ "no-unassigned-vars": "warn",
44
+ "no-unsafe-finally": "warn",
45
+ "no-unsafe-negation": "warn",
46
+ "no-unsafe-optional-chaining": "warn",
47
+ "no-unused-expressions": "warn",
48
+ "no-unused-labels": "warn",
49
+ "no-unused-private-class-members": "error",
50
+ "no-unused-vars": "error",
51
+ "no-useless-backreference": "warn",
52
+ "no-useless-catch": "warn",
53
+ "no-useless-escape": "warn",
54
+ "no-useless-rename": "warn",
55
+ "no-with": "warn",
56
+ "require-yield": "warn",
57
+ "use-isnan": "warn",
58
+ "valid-typeof": "warn",
59
+ "oxc/bad-array-method-on-arguments": "warn",
60
+ "oxc/bad-char-at-comparison": "warn",
61
+ "oxc/bad-comparison-sequence": "warn",
62
+ "oxc/bad-min-max-func": "warn",
63
+ "oxc/bad-object-literal-comparison": "warn",
64
+ "oxc/bad-replace-all-arg": "warn",
65
+ "oxc/const-comparisons": "warn",
66
+ "oxc/double-comparisons": "warn",
67
+ "oxc/erasing-op": "warn",
68
+ "oxc/missing-throw": "warn",
69
+ "oxc/number-arg-out-of-range": "warn",
70
+ "oxc/only-used-in-recursion": "warn",
71
+ "oxc/uninvoked-array-callback": "warn",
72
+ "typescript/await-thenable": "warn",
73
+ "typescript/no-array-delete": "warn",
74
+ "typescript/no-base-to-string": "warn",
75
+ "typescript/no-duplicate-enum-values": "warn",
76
+ "typescript/no-duplicate-type-constituents": "warn",
77
+ "typescript/no-extra-non-null-assertion": "warn",
78
+ "typescript/no-floating-promises": "warn",
79
+ "typescript/no-for-in-array": "warn",
80
+ "typescript/no-implied-eval": "warn",
81
+ "typescript/no-meaningless-void-operator": "warn",
82
+ "typescript/no-misused-new": "warn",
83
+ "typescript/no-misused-spread": "warn",
84
+ "typescript/no-non-null-asserted-optional-chain": "warn",
85
+ "typescript/no-redundant-type-constituents": "warn",
86
+ "typescript/no-this-alias": "warn",
87
+ "typescript/no-unnecessary-parameter-property-assignment": "warn",
88
+ "typescript/no-unsafe-declaration-merging": "warn",
89
+ "typescript/no-unsafe-unary-minus": "warn",
90
+ "typescript/no-useless-empty-export": "warn",
91
+ "typescript/no-wrapper-object-types": "warn",
92
+ "typescript/prefer-as-const": "warn",
93
+ "typescript/require-array-sort-compare": "warn",
94
+ "typescript/restrict-template-expressions": "warn",
95
+ "typescript/triple-slash-reference": "warn",
96
+ "typescript/unbound-method": "warn",
97
+ "unicorn/no-await-in-promise-methods": "warn",
98
+ "unicorn/no-empty-file": "warn",
99
+ "unicorn/no-invalid-fetch-options": "warn",
100
+ "unicorn/no-invalid-remove-event-listener": "warn",
101
+ "unicorn/no-new-array": "warn",
102
+ "unicorn/no-single-promise-in-promise-methods": "warn",
103
+ "unicorn/no-thenable": "warn",
104
+ "unicorn/no-unnecessary-await": "warn",
105
+ "unicorn/no-useless-fallback-in-spread": "warn",
106
+ "unicorn/no-useless-length-check": "warn",
107
+ "unicorn/no-useless-spread": "warn",
108
+ "unicorn/prefer-set-size": "warn",
109
+ "unicorn/prefer-string-starts-ends-with": "warn"
110
+ },
111
+ "settings": {
112
+ "jsx-a11y": {
113
+ "polymorphicPropName": null,
114
+ "components": {},
115
+ "attributes": {}
116
+ },
117
+ "next": {
118
+ "rootDir": []
119
+ },
120
+ "react": {
121
+ "formComponents": [],
122
+ "linkComponents": [],
123
+ "version": null
124
+ },
125
+ "jsdoc": {
126
+ "ignorePrivate": false,
127
+ "ignoreInternal": false,
128
+ "ignoreReplacesDocs": true,
129
+ "overrideReplacesDocs": true,
130
+ "augmentsExtendsReplacesDocs": false,
131
+ "implementsReplacesDocs": false,
132
+ "exemptDestructuredRootsFromChecks": false,
133
+ "tagNamePreference": {}
134
+ },
135
+ "vitest": {
136
+ "typecheck": false
137
+ }
138
+ },
139
+ "env": {
140
+ "builtin": true
141
+ },
142
+ "globals": {},
143
+ "ignorePatterns": []
144
+ }
package/README.md CHANGED
@@ -1,15 +1,215 @@
1
- # @codeandmoney/jargal
1
+ # @brand-map/generator
2
2
 
3
- To install dependencies:
3
+ A powerful file generation library that creates files from templates using template engines like Vento or Handlebars.
4
+
5
+ ## Installation
4
6
 
5
7
  ```bash
6
- bun install
8
+ npm install -D @brand-map/generator
9
+ # or
10
+ bun add -D @brand-map/generator
7
11
  ```
8
12
 
9
- To run:
13
+ ## Quick Start
10
14
 
11
- ```bash
12
- bun run
15
+ ```typescript
16
+ import { Genrator } from "@brand-map/generator";
17
+ import { loadTemplates } from "@brand-map/generator";
18
+
19
+ const generator = new Genrator({
20
+ out: "./components/ui",
21
+ cwd: process.cwd(),
22
+ })
23
+ .addContext(await loadTemplates("./templates"))
24
+ .addContext({ data: [{ name: "Button" }, { name: "Input" }, { name: "Text" }] });
25
+
26
+ await generator.render();
27
+ await generator.write();
28
+ ```
29
+
30
+ ## API Reference
31
+
32
+ ### `Genrator`
33
+
34
+ The main class for generating files from templates.
35
+
36
+ #### Constructor
37
+
38
+ ```typescript
39
+ new Genrator(config?: {
40
+ engine?: "vento" | "handlebars"; // Default: "vento"
41
+ out?: string; // Default: process.cwd()
42
+ cwd?: string; // Default: process.cwd()
43
+ })
44
+ ```
45
+
46
+ **Parameters:**
47
+
48
+ - `engine` - The template engine to use. Options: `"vento"` (default) or `"handlebars"`
49
+ - `out` - The directory where generated files will be written
50
+ - `cwd` - The current working directory for resolving relative paths
51
+
52
+ #### Methods
53
+
54
+ ##### `addContext(setter)`
55
+
56
+ Adds context data to the generator. Can be called multiple times to merge context.
57
+
58
+ **Parameters:**
59
+
60
+ - `setter` - Either an object to merge into context, or a function that receives the current context and returns a partial context object
61
+
62
+ **Returns:** The generator instance (for chaining)
63
+
64
+ **Example:**
65
+
66
+ ```typescript
67
+ // Using an object
68
+ generator.addContext({ data: [{ name: "Button" }] });
69
+
70
+ // Using a function
71
+ generator.addContext(() => ({ data: [{ name: "Button" }] }));
72
+ generator.addContext((ctx) => ({ data: { isDark: ctx.theme === "dark" } }));
73
+
74
+ // loadTemplates is a special actions that returns callback
75
+ generator.addContext(await loadTemplates("./templates"));
76
+ ```
77
+
78
+ ##### `render(renderFn?)`
79
+
80
+ Renders templates with the provided context data.
81
+
82
+ **Parameters:**
83
+
84
+ - `renderFn` (optional) - A custom function that receives the context and returns an array of `{ path: string; content: string }` objects. If not provided, the generator will automatically render all templates.
85
+
86
+ **Behavior:**
87
+
88
+ - If `renderFn` is provided, it will be used to generate the rendered files
89
+ - If `context.data` is an array, each template will be rendered once for each item in the array
90
+ - If `context.data` is an object, each template will be rendered once with that object
91
+ - If `context.data` is not set, templates will be rendered with an empty data object
92
+
93
+ **Returns:** `Promise<void>`
94
+
95
+ ##### `write(callback?)`
96
+
97
+ Writes the rendered files to disk.
98
+
99
+ **Parameters:**
100
+
101
+ - `callback` (optional) - A function that receives `{ path, content, writeFn }` for each rendered file. If provided, you can customize the write behavior. If not provided, files are written automatically.
102
+
103
+ **Returns:** `Promise<void>`
104
+
105
+ ### `loadTemplates(templatesPath)`
106
+
107
+ Loads template files from a directory.
108
+
109
+ **Parameters:**
110
+
111
+ - `templatesPath` - The path to the directory containing template files
112
+
113
+ **Returns:** `Promise<(ctx: Record<string, any>) => { templates: Record<string, TemplateData> }>`
114
+
115
+ **Behavior:**
116
+
117
+ - Recursively walks the directory tree
118
+ - Skips files and directories that start with `_` (underscore)
119
+ - Automatically strips `.hbs` and `.vto` extensions from relative paths
120
+ - Returns a setter function that can be passed to `addContext()`
121
+
122
+ **Template File Naming:**
123
+
124
+ - Template file paths can contain template expressions (e.g., `{{name |> kebabCase}}.vto`)
125
+ - Files starting with `_` are ignored (useful for partials or examples)
126
+ - Supported extensions: `.vto` (Vento), `.hbs` (Handlebars)
127
+
128
+ ## Usage Examples
129
+
130
+ ### Basic Usage
131
+
132
+ ```typescript
133
+ import { Genrator, loadTemplates } from "@brand-map/generator";
134
+
135
+ const generator = new Genrator({
136
+ out: "./output",
137
+ })
138
+ .addContext(await loadTemplates("./templates"))
139
+ .addContext({
140
+ data: [{ name: "Button" }, { name: "Input" }],
141
+ });
142
+
143
+ await generator.render();
144
+ await generator.write();
145
+ ```
146
+
147
+ ### Using Handlebars Engine
148
+
149
+ ```typescript
150
+ const generator = new Genrator({
151
+ engine: "handlebars",
152
+ out: "./output",
153
+ })
154
+ .addContext(await loadTemplates("./templates"))
155
+ .addContext({ data: { name: "Component" } });
156
+
157
+ await generator.render();
158
+ await generator.write();
13
159
  ```
14
160
 
15
- This project was created using `bun init` in bun v1.3.0. [Bun](https://bun.com) is a fast all-in-one JavaScript runtime.
161
+ ### Custom Render Function
162
+
163
+ ```typescript
164
+ await generator.render((ctx) => {
165
+ return ctx.templates.map((template) => ({
166
+ path: `custom/${template.relative}`,
167
+ content: template.content,
168
+ }));
169
+ });
170
+ ```
171
+
172
+ ### Custom Write Function
173
+
174
+ ```typescript
175
+ await generator.write(async ({ path, content, writeFn }) => {
176
+ // Custom logic before writing
177
+ console.log(`Writing to ${path}`);
178
+
179
+ // Use the provided writeFn or implement custom logic
180
+ await writeFn({ path, content });
181
+ });
182
+ ```
183
+
184
+ ## Template Examples
185
+
186
+ ### Vento Template
187
+
188
+ ```vento
189
+ {{ "<h1>Hello, world!</h1>" |> safe }}
190
+
191
+ {{ name |> constantCase }}
192
+ ```
193
+
194
+ ### Dynamic File Paths
195
+
196
+ Template files can have dynamic paths that are rendered based on context data:
197
+
198
+ - `{{name |> kebabCase}}.vto` - Creates files like `button.ts`, `input.ts`
199
+ - `{{name |> constantCase}}/index.ts.vto` - Creates directories and files
200
+
201
+ ## Context Structure
202
+
203
+ The generator maintains a context object with the following structure:
204
+
205
+ ```typescript
206
+ {
207
+ templates: Record<string, TemplateData>; // Loaded templates
208
+ data: unknown; // Your data (object or array)
209
+ rendered: Array<{
210
+ // Rendered files
211
+ path: string;
212
+ content: string;
213
+ }>;
214
+ }
215
+ ```
package/bun.lock CHANGED
@@ -1,20 +1,22 @@
1
1
  {
2
2
  "lockfileVersion": 1,
3
- "configVersion": 0,
3
+ "configVersion": 1,
4
4
  "workspaces": {
5
5
  "": {
6
- "name": "@codeandmoney/jargal",
6
+ "name": "@brand-map/generator",
7
7
  "dependencies": {
8
8
  "change-case": "^5.4.4",
9
- "enquirer": "^2.4.1",
10
9
  "es-toolkit": "^1.40.0",
11
10
  "handlebars": "^4.7.8",
12
11
  "title-case": "^4.3.2",
13
12
  "valibot": "^1.1.0",
13
+ "ventojs": "^2.3.0",
14
14
  },
15
15
  "devDependencies": {
16
16
  "@types/bun": "^1.3.0",
17
- "@types/node": "^24.7.2",
17
+ "@types/node": "^25.0.9",
18
+ "oxfmt": "^0.24.0",
19
+ "oxlint": "^1.39.0",
18
20
  },
19
21
  "peerDependencies": {
20
22
  "typescript": "^5",
@@ -22,25 +24,47 @@
22
24
  },
23
25
  },
24
26
  "packages": {
25
- "@types/bun": ["@types/bun@1.3.0", "", { "dependencies": { "bun-types": "1.3.0" } }, "sha512-+lAGCYjXjip2qY375xX/scJeVRmZ5cY0wyHYyCYxNcdEXrQ4AOe3gACgd4iQ8ksOslJtW4VNxBJ8llUwc3a6AA=="],
27
+ "@oxfmt/darwin-arm64": ["@oxfmt/darwin-arm64@0.24.0", "", { "os": "darwin", "cpu": "arm64" }, "sha512-aYXuGf/yq8nsyEcHindGhiz9I+GEqLkVq8CfPbd+6VE259CpPEH+CaGHEO1j6vIOmNr8KHRq+IAjeRO2uJpb8A=="],
26
28
 
27
- "@types/node": ["@types/node@24.7.2", "", { "dependencies": { "undici-types": "~7.14.0" } }, "sha512-/NbVmcGTP+lj5oa4yiYxxeBjRivKQ5Ns1eSZeB99ExsEQ6rX5XYU1Zy/gGxY/ilqtD4Etx9mKyrPxZRetiahhA=="],
29
+ "@oxfmt/darwin-x64": ["@oxfmt/darwin-x64@0.24.0", "", { "os": "darwin", "cpu": "x64" }, "sha512-vs3b8Bs53hbiNvcNeBilzE/+IhDTWKjSBB3v/ztr664nZk65j0xr+5IHMBNz3CFppmX7o/aBta2PxY+t+4KoPg=="],
28
30
 
29
- "@types/react": ["@types/react@19.2.2", "", { "dependencies": { "csstype": "^3.0.2" } }, "sha512-6mDvHUFSjyT2B2yeNx2nUgMxh9LtOWvkhIU3uePn2I2oyNymUAX1NIsdgviM4CH+JSrp2D2hsMvJOkxY+0wNRA=="],
31
+ "@oxfmt/linux-arm64-gnu": ["@oxfmt/linux-arm64-gnu@0.24.0", "", { "os": "linux", "cpu": "arm64" }, "sha512-ItPDOPoQ0wLj/s8osc5ch57uUcA1Wk8r0YdO8vLRpXA3UNg7KPOm1vdbkIZRRiSUphZcuX5ioOEetEK8H7RlTw=="],
30
32
 
31
- "ansi-colors": ["ansi-colors@4.1.3", "", {}, "sha512-/6w/C21Pm1A7aZitlI5Ni/2J6FFQN8i1Cvz3kHABAAbw93v/NlvKdVOqz7CCWz/3iv/JplRSEEZ83XION15ovw=="],
33
+ "@oxfmt/linux-arm64-musl": ["@oxfmt/linux-arm64-musl@0.24.0", "", { "os": "linux", "cpu": "arm64" }, "sha512-JkQO3WnQjQTJONx8nxdgVBfl6BBFfpp9bKhChYhWeakwJdr7QPOAWJ/v3FGZfr0TbqINwnNR74aVZayDDRyXEA=="],
32
34
 
33
- "ansi-regex": ["ansi-regex@5.0.1", "", {}, "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ=="],
35
+ "@oxfmt/linux-x64-gnu": ["@oxfmt/linux-x64-gnu@0.24.0", "", { "os": "linux", "cpu": "x64" }, "sha512-N/SXlFO+2kak5gMt0oxApi0WXQDhwA0PShR0UbkY0PwtHjfSiDqJSOumyNqgQVoroKr1GNnoRmUqjZIz6DKIcw=="],
34
36
 
35
- "bun-types": ["bun-types@1.3.0", "", { "dependencies": { "@types/node": "*" }, "peerDependencies": { "@types/react": "^19" } }, "sha512-u8X0thhx+yJ0KmkxuEo9HAtdfgCBaM/aI9K90VQcQioAmkVp3SG3FkwWGibUFz3WdXAdcsqOcbU40lK7tbHdkQ=="],
37
+ "@oxfmt/linux-x64-musl": ["@oxfmt/linux-x64-musl@0.24.0", "", { "os": "linux", "cpu": "x64" }, "sha512-WM0pek5YDCQf50XQ7GLCE9sMBCMPW/NPAEPH/Hx6Qyir37lEsP4rUmSECo/QFNTU6KBc9NnsviAyJruWPpCMXw=="],
36
38
 
37
- "change-case": ["change-case@5.4.4", "", {}, "sha512-HRQyTk2/YPEkt9TnUPbOpr64Uw3KOicFWPVBb+xiHvd6eBx/qPr9xqfBFDT8P2vWsvvz4jbEkfDe71W3VyNu2w=="],
39
+ "@oxfmt/win32-arm64": ["@oxfmt/win32-arm64@0.24.0", "", { "os": "win32", "cpu": "arm64" }, "sha512-vFCseli1KWtwdHrVlT/jWfZ8jP8oYpnPPEjI23mPLW8K/6GEJmmvy0PZP5NpWUFNTzX0lqie58XnrATJYAe9Xw=="],
40
+
41
+ "@oxfmt/win32-x64": ["@oxfmt/win32-x64@0.24.0", "", { "os": "win32", "cpu": "x64" }, "sha512-0tmlNzcyewAnauNeBCq0xmAkmiKzl+H09p0IdHy+QKrTQdtixtf+AOjDAADbRfihkS+heF15Pjc4IyJMdAAJjw=="],
42
+
43
+ "@oxlint/darwin-arm64": ["@oxlint/darwin-arm64@1.39.0", "", { "os": "darwin", "cpu": "arm64" }, "sha512-lT3hNhIa02xCujI6YGgjmYGg3Ht/X9ag5ipUVETaMpx5Rd4BbTNWUPif1WN1YZHxt3KLCIqaAe7zVhatv83HOQ=="],
44
+
45
+ "@oxlint/darwin-x64": ["@oxlint/darwin-x64@1.39.0", "", { "os": "darwin", "cpu": "x64" }, "sha512-UT+rfTWd+Yr7iJeSLd/7nF8X4gTYssKh+n77hxl6Oilp3NnG1CKRHxZDy3o3lIBnwgzJkdyUAiYWO1bTMXQ1lA=="],
46
+
47
+ "@oxlint/linux-arm64-gnu": ["@oxlint/linux-arm64-gnu@1.39.0", "", { "os": "linux", "cpu": "arm64" }, "sha512-qocBkvS2V6rH0t9AT3DfQunMnj3xkM7srs5/Ycj2j5ZqMoaWd/FxHNVJDFP++35roKSvsRJoS0mtA8/77jqm6Q=="],
48
+
49
+ "@oxlint/linux-arm64-musl": ["@oxlint/linux-arm64-musl@1.39.0", "", { "os": "linux", "cpu": "arm64" }, "sha512-arZzAc1PPcz9epvGBBCMHICeyQloKtHX3eoOe62B3Dskn7gf6Q14wnDHr1r9Vp4vtcBATNq6HlKV14smdlC/qA=="],
50
+
51
+ "@oxlint/linux-x64-gnu": ["@oxlint/linux-x64-gnu@1.39.0", "", { "os": "linux", "cpu": "x64" }, "sha512-ZVt5qsECpuNprdWxAPpDBwoixr1VTcZ4qAEQA2l/wmFyVPDYFD3oBY/SWACNnWBddMrswjTg9O8ALxYWoEpmXw=="],
52
+
53
+ "@oxlint/linux-x64-musl": ["@oxlint/linux-x64-musl@1.39.0", "", { "os": "linux", "cpu": "x64" }, "sha512-pB0hlGyKPbxr9NMIV783lD6cWL3MpaqnZRM9MWni4yBdHPTKyFNYdg5hGD0Bwg+UP4S2rOevq/+OO9x9Bi7E6g=="],
54
+
55
+ "@oxlint/win32-arm64": ["@oxlint/win32-arm64@1.39.0", "", { "os": "win32", "cpu": "arm64" }, "sha512-Gg2SFaJohI9+tIQVKXlPw3FsPQFi/eCSWiCgwPtPn5uzQxHRTeQEZKuluz1fuzR5U70TXubb2liZi4Dgl8LJQA=="],
38
56
 
39
- "csstype": ["csstype@3.1.3", "", {}, "sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw=="],
57
+ "@oxlint/win32-x64": ["@oxlint/win32-x64@1.39.0", "", { "os": "win32", "cpu": "x64" }, "sha512-sbi25lfj74hH+6qQtb7s1wEvd1j8OQbTaH8v3xTcDjrwm579Cyh0HBv1YSZ2+gsnVwfVDiCTL1D0JsNqYXszVA=="],
40
58
 
41
- "enquirer": ["enquirer@2.4.1", "", { "dependencies": { "ansi-colors": "^4.1.1", "strip-ansi": "^6.0.1" } }, "sha512-rRqJg/6gd538VHvR3PSrdRBb/1Vy2YfzHqzvbhGIQpDRKIa4FgV/54b5Q1xYSxOOwKvjXweS26E0Q+nAMwp2pQ=="],
59
+ "@types/bun": ["@types/bun@1.3.6", "", { "dependencies": { "bun-types": "1.3.6" } }, "sha512-uWCv6FO/8LcpREhenN1d1b6fcspAB+cefwD7uti8C8VffIv0Um08TKMn98FynpTiU38+y2dUO55T11NgDt8VAA=="],
42
60
 
43
- "es-toolkit": ["es-toolkit@1.40.0", "", {}, "sha512-8o6w0KFmU0CiIl0/Q/BCEOabF2IJaELM1T2PWj6e8KqzHv1gdx+7JtFnDwOx1kJH/isJ5NwlDG1nCr1HrRF94Q=="],
61
+ "@types/node": ["@types/node@25.0.9", "", { "dependencies": { "undici-types": "~7.16.0" } }, "sha512-/rpCXHlCWeqClNBwUhDcusJxXYDjZTyE8v5oTO7WbL8eij2nKhUeU89/6xgjU7N4/Vh3He0BtyhJdQbDyhiXAw=="],
62
+
63
+ "bun-types": ["bun-types@1.3.6", "", { "dependencies": { "@types/node": "*" } }, "sha512-OlFwHcnNV99r//9v5IIOgQ9Uk37gZqrNMCcqEaExdkVq3Avwqok1bJFmvGMCkCE0FqzdY8VMOZpfpR3lwI+CsQ=="],
64
+
65
+ "change-case": ["change-case@5.4.4", "", {}, "sha512-HRQyTk2/YPEkt9TnUPbOpr64Uw3KOicFWPVBb+xiHvd6eBx/qPr9xqfBFDT8P2vWsvvz4jbEkfDe71W3VyNu2w=="],
66
+
67
+ "es-toolkit": ["es-toolkit@1.44.0", "", {}, "sha512-6penXeZalaV88MM3cGkFZZfOoLGWshWWfdy0tWw/RlVVyhvMaWSBTOvXNeiW3e5FwdS5ePW0LGEu17zT139ktg=="],
44
68
 
45
69
  "handlebars": ["handlebars@4.7.8", "", { "dependencies": { "minimist": "^1.2.5", "neo-async": "^2.6.2", "source-map": "^0.6.1", "wordwrap": "^1.0.0" }, "optionalDependencies": { "uglify-js": "^3.1.4" }, "bin": { "handlebars": "bin/handlebars" } }, "sha512-vafaFqs8MZkRrSX7sFVUdo3ap/eNiLnb4IakshzvP56X5Nr1iGKAIqdX6tMlm6HcNRIkr6AxO5jFEoJzzpT8aQ=="],
46
70
 
@@ -48,9 +72,13 @@
48
72
 
49
73
  "neo-async": ["neo-async@2.6.2", "", {}, "sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw=="],
50
74
 
75
+ "oxfmt": ["oxfmt@0.24.0", "", { "dependencies": { "tinypool": "2.0.0" }, "optionalDependencies": { "@oxfmt/darwin-arm64": "0.24.0", "@oxfmt/darwin-x64": "0.24.0", "@oxfmt/linux-arm64-gnu": "0.24.0", "@oxfmt/linux-arm64-musl": "0.24.0", "@oxfmt/linux-x64-gnu": "0.24.0", "@oxfmt/linux-x64-musl": "0.24.0", "@oxfmt/win32-arm64": "0.24.0", "@oxfmt/win32-x64": "0.24.0" }, "bin": { "oxfmt": "bin/oxfmt" } }, "sha512-UjeM3Peez8Tl7IJ9s5UwAoZSiDRMww7BEc21gDYxLq3S3/KqJnM3mjNxsoSHgmBvSeX6RBhoVc2MfC/+96RdSw=="],
76
+
77
+ "oxlint": ["oxlint@1.39.0", "", { "optionalDependencies": { "@oxlint/darwin-arm64": "1.39.0", "@oxlint/darwin-x64": "1.39.0", "@oxlint/linux-arm64-gnu": "1.39.0", "@oxlint/linux-arm64-musl": "1.39.0", "@oxlint/linux-x64-gnu": "1.39.0", "@oxlint/linux-x64-musl": "1.39.0", "@oxlint/win32-arm64": "1.39.0", "@oxlint/win32-x64": "1.39.0" }, "peerDependencies": { "oxlint-tsgolint": ">=0.10.0" }, "optionalPeers": ["oxlint-tsgolint"], "bin": { "oxlint": "bin/oxlint" } }, "sha512-wSiLr0wjG+KTU6c1LpVoQk7JZ7l8HCKlAkVDVTJKWmCGazsNxexxnOXl7dsar92mQcRnzko5g077ggP3RINSjA=="],
78
+
51
79
  "source-map": ["source-map@0.6.1", "", {}, "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g=="],
52
80
 
53
- "strip-ansi": ["strip-ansi@6.0.1", "", { "dependencies": { "ansi-regex": "^5.0.1" } }, "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A=="],
81
+ "tinypool": ["tinypool@2.0.0", "", {}, "sha512-/RX9RzeH2xU5ADE7n2Ykvmi9ED3FBGPAjw9u3zucrNNaEBIO0HPSYgL0NT7+3p147ojeSdaVu08F6hjpv31HJg=="],
54
82
 
55
83
  "title-case": ["title-case@4.3.2", "", {}, "sha512-I/nkcBo73mO42Idfv08jhInV61IMb61OdIFxk+B4Gu1oBjWBPOLmhZdsli+oJCVaD+86pYQA93cJfFt224ZFAA=="],
56
84
 
@@ -58,12 +86,12 @@
58
86
 
59
87
  "uglify-js": ["uglify-js@3.19.3", "", { "bin": { "uglifyjs": "bin/uglifyjs" } }, "sha512-v3Xu+yuwBXisp6QYTcH4UbH+xYJXqnq2m/LtQVWKWzYc1iehYnLixoQDN9FH6/j9/oybfd6W9Ghwkl8+UMKTKQ=="],
60
88
 
61
- "undici-types": ["undici-types@7.14.0", "", {}, "sha512-QQiYxHuyZ9gQUIrmPo3IA+hUl4KYk8uSA7cHrcKd/l3p1OTpZcM0Tbp9x7FAtXdAYhlasd60ncPpgu6ihG6TOA=="],
89
+ "undici-types": ["undici-types@7.16.0", "", {}, "sha512-Zz+aZWSj8LE6zoxD+xrjh4VfkIG8Ya6LvYkZqtUQGJPZjYl53ypCaUwWqo7eI0x66KBGeRo+mlBEkMSeSZ38Nw=="],
62
90
 
63
- "valibot": ["valibot@1.1.0", "", { "peerDependencies": { "typescript": ">=5" }, "optionalPeers": ["typescript"] }, "sha512-Nk8lX30Qhu+9txPYTwM0cFlWLdPFsFr6LblzqIySfbZph9+BFsAHsNvHOymEviUepeIW6KFHzpX8TKhbptBXXw=="],
91
+ "valibot": ["valibot@1.2.0", "", { "peerDependencies": { "typescript": ">=5" }, "optionalPeers": ["typescript"] }, "sha512-mm1rxUsmOxzrwnX5arGS+U4T25RdvpPjPN4yR0u9pUBov9+zGVtO84tif1eY4r6zWxVxu3KzIyknJy3rxfRZZg=="],
64
92
 
65
- "wordwrap": ["wordwrap@1.0.0", "", {}, "sha512-gvVzJFlPycKc5dZN4yPkP8w7Dc37BtP1yczEneOb4uq34pXZcvrtRTmWV8W+Ume+XCxKgbjM+nevkyFPMybd4Q=="],
93
+ "ventojs": ["ventojs@2.3.0", "", {}, "sha512-Vi/ZdC7QwdaaPTDL6fMWBxj+LnLTynDbef8Mb3YId3AR1Tnds2dS8YRUU/o51/Fv/5rdTNFJL4YHtBpfBbTQKg=="],
66
94
 
67
- "bun-types/@types/node": ["@types/node@24.7.0", "", { "dependencies": { "undici-types": "~7.14.0" } }, "sha512-IbKooQVqUBrlzWTi79E8Fw78l8k1RNtlDDNWsFZs7XonuQSJ8oNYfEeclhprUldXISRMLzBpILuKgPlIxm+/Yw=="],
95
+ "wordwrap": ["wordwrap@1.0.0", "", {}, "sha512-gvVzJFlPycKc5dZN4yPkP8w7Dc37BtP1yczEneOb4uq34pXZcvrtRTmWV8W+Ume+XCxKgbjM+nevkyFPMybd4Q=="],
68
96
  }
69
97
  }
package/package.json CHANGED
@@ -1,39 +1,34 @@
1
1
  {
2
2
  "name": "@brand-map/generator",
3
- "version": "0.0.0-dev.14",
3
+ "version": "0.1.0",
4
4
  "description": "Renderer",
5
5
  "license": "MIT",
6
- "author": "Code & Money Team",
7
- "contributors": [
8
- {
9
- "name": "Alexey Sokolov",
10
- "email": "alexey@codeandmoney.com",
11
- "url": "https://codeandmoney.com"
12
- }
13
- ],
6
+ "author": "Brand-Map Team",
14
7
  "exports": {
15
- "./old": "./exports.ts",
16
- ".": "./jargal.ts",
17
- "./types": "./types.ts",
18
- "./actions": "./actions/exports.ts",
19
- "./renderer": "./renderer.ts"
8
+ ".": "./src/exports.ts"
9
+ },
10
+ "publishConfig": {
11
+ "access": "public"
12
+ },
13
+ "scripts": {
14
+ "format": "oxfmt",
15
+ "lint:fix": "oxlint --fix"
20
16
  },
21
17
  "dependencies": {
22
18
  "change-case": "^5.4.4",
23
- "enquirer": "^2.4.1",
24
19
  "es-toolkit": "^1.40.0",
25
20
  "handlebars": "^4.7.8",
26
21
  "title-case": "^4.3.2",
27
- "valibot": "^1.1.0"
22
+ "valibot": "^1.1.0",
23
+ "ventojs": "^2.3.0"
28
24
  },
29
25
  "devDependencies": {
30
26
  "@types/bun": "^1.3.0",
31
- "@types/node": "^24.7.2"
27
+ "@types/node": "^25.0.9",
28
+ "oxfmt": "^0.24.0",
29
+ "oxlint": "^1.39.0"
32
30
  },
33
31
  "peerDependencies": {
34
32
  "typescript": "^5"
35
- },
36
- "publishConfig": {
37
- "access": "public"
38
33
  }
39
34
  }
@@ -0,0 +1,58 @@
1
+ import { readdir, readFile } from "node:fs/promises";
2
+ import path, { resolve } from "node:path";
3
+
4
+ export type TemplateData = {
5
+ path: string;
6
+ relative: string;
7
+ content: string;
8
+ };
9
+
10
+ export async function loadTemplates(teamplatesPath: string): Promise<(ctx: Record<string, any>) => { templates: Record<string, TemplateData> }> {
11
+ if (!teamplatesPath || typeof teamplatesPath !== "string") {
12
+ throw new Error(`Invalid templates path provided. Try string`);
13
+ }
14
+
15
+ const record = {} as Record<string, TemplateData>;
16
+
17
+ const resolvedPath = resolve(teamplatesPath);
18
+
19
+ for await (const templatePath of walkDir(resolvedPath)) {
20
+ if (path.basename(templatePath).startsWith("_")) {
21
+ continue;
22
+ }
23
+
24
+ const relative = path.relative(resolvedPath, templatePath).replace(".hbs", "").replace(".vto", "");
25
+
26
+ const contentRaw = await readFile(path.resolve(resolvedPath, templatePath));
27
+
28
+ const data: TemplateData = {
29
+ content: new TextDecoder().decode(contentRaw),
30
+ path: templatePath,
31
+ relative,
32
+ };
33
+
34
+ if (data.relative.startsWith("_")) {
35
+ continue;
36
+ }
37
+
38
+ Object.assign(record, { [relative]: data });
39
+ }
40
+
41
+ return function setter(_ctx: Record<string, any>) {
42
+ return { templates: record };
43
+ };
44
+ }
45
+
46
+ async function* walkDir(dir: string): AsyncGenerator<string, void, void> {
47
+ const entries = await readdir(dir, { withFileTypes: true });
48
+
49
+ for (const entry of entries) {
50
+ const templatePath = path.join(dir, entry.name);
51
+
52
+ if (entry.isDirectory()) {
53
+ yield* walkDir(templatePath);
54
+ } else if (entry.isFile()) {
55
+ yield templatePath;
56
+ }
57
+ }
58
+ }
package/src/exports.ts ADDED
@@ -0,0 +1,2 @@
1
+ export { Genrator } from "./generator";
2
+ export { loadTemplates } from "./actions/load-templates";