docvars 0.3.0 → 0.3.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -31,16 +31,16 @@ docvars <input> <output> [options]
31
31
 
32
32
  ### Options
33
33
 
34
- | Option | Default | Description |
35
- | --------------- | ---------------- | --------------------------------------------------- |
36
- | `--vars` | `variables.yaml` | Path to the variables YAML file |
37
- | `--include` | - | Glob pattern to include specific files |
38
- | `--exclude` | - | Glob pattern to exclude specific files |
39
- | `--watch` | `false` | Watch for file changes and rebuild automatically |
40
- | `--rename-from` | - | Variable name to rename from (use with --rename-to) |
41
- | `--rename-to` | - | Variable name to rename to (use with --rename-from) |
42
- | `--list-vars` | `false` | List all variables used in templates |
43
- | `--dry-run` | `false` | Preview changes without writing files |
34
+ | Option | Alias | Default | Description |
35
+ | --------------- | ----- | ---------------- | --------------------------------------------------- |
36
+ | `--vars` | `-v` | `variables.yaml` | Path to the variables YAML file |
37
+ | `--only` | `-o` | `**/*` | Glob pattern to filter files (e.g. **/*.md) |
38
+ | `--exclude` | `-e` | - | Glob pattern to exclude specific files |
39
+ | `--watch` | `-w` | `false` | Watch for file changes and rebuild automatically |
40
+ | `--rename-from` | `-r` | - | Variable name to rename from (use with --rename-to) |
41
+ | `--rename-to` | `-t` | - | Variable name to rename to (use with --rename-from) |
42
+ | `--list-vars` | `-l` | `false` | List all variables used in templates |
43
+ | `--dry-run` | `-d` | `false` | Preview changes without writing files |
44
44
 
45
45
  ## Examples
46
46
 
@@ -59,24 +59,51 @@ docvars ./templates ./output --vars production.yaml
59
59
  ### Filter files
60
60
 
61
61
  ```bash
62
- # Include only files matching pattern
63
- docvars ./templates ./output --include "api-*.md"
62
+ # Process only markdown files
63
+ docvars ./templates ./output --only "**/*.md"
64
+
65
+ # Process multiple file types
66
+ docvars ./templates ./output --only "**/*.{md,html,txt}"
67
+
68
+ # Process only files matching pattern
69
+ docvars ./templates ./output --only "api-*.md"
64
70
 
65
71
  # Exclude files matching pattern
66
72
  docvars ./templates ./output --exclude "draft-*.md"
67
73
  ```
68
74
 
75
+ By default, all text files are processed (binary files like images are automatically excluded).
76
+
69
77
  ### Watch mode
70
78
 
71
79
  ```bash
72
80
  docvars ./templates ./output --watch
73
81
  ```
74
82
 
75
- This will watch for changes in:
76
- - Template files in the input directory
77
- - The variables YAML file
83
+ Output:
84
+
85
+ ```
86
+ šŸ‘ Watch mode enabled
78
87
 
79
- When changes are detected, templates are automatically rebuilt.
88
+ ā”Œā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”¬ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”
89
+ │ Templates │ /path/to/templates │
90
+ │ Variables │ /path/to/variables.yaml │
91
+ ā””ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”“ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”˜
92
+
93
+ Waiting for changes... (Ctrl+C to stop)
94
+
95
+ šŸ‘€ Change detected: README.md (change)
96
+
97
+ ✨ Build complete
98
+
99
+ ā”Œā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”¬ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”
100
+ │ File │ Status │
101
+ ā”œā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”¼ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”¤
102
+ │ README.md │ āœ“ done │
103
+ ā””ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”“ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”˜
104
+
105
+ Processed: 1 file(s)
106
+ ```
80
107
 
81
108
  ### Rename variables
82
109
 
@@ -90,9 +117,21 @@ docvars ./templates ./output --rename-from "name" --rename-to "title"
90
117
  docvars ./templates ./output --rename-from "database.host" --rename-to "db.host"
91
118
  ```
92
119
 
93
- This updates:
94
- - All `{{oldName}}` occurrences in template files → `{{newName}}`
95
- - The key in the variables YAML file
120
+ Output:
121
+
122
+ ```
123
+ āœļø Rename complete
124
+ database.host → db.host
125
+
126
+ ā”Œā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”¬ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”
127
+ │ File │ Status │
128
+ ā”œā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”¼ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”¤
129
+ │ variables.yaml │ āœ“ updated │
130
+ │ README.md │ āœ“ updated │
131
+ ā””ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”“ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”˜
132
+
133
+ Updated: 2 file(s)
134
+ ```
96
135
 
97
136
  ### List variables
98
137
 
@@ -105,17 +144,20 @@ docvars ./templates ./output --list-vars
105
144
  Output:
106
145
 
107
146
  ```
108
- Variables used in templates:
147
+ šŸ“‹ Variables
109
148
 
110
- app.name (āœ“)
111
- → README.md
112
- → config.md
113
- api.key (āœ— undefined)
114
- → config.md
149
+ ā”Œā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”¬ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”¬ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”
150
+ │ Variable │ Status │ Used in │
151
+ ā”œā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”¼ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”¼ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”¤
152
+ │ app.name │ āœ“ defined │ README.md │
153
+ │ api.key │ āœ— undefined │ config.md │
154
+ ā””ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”“ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”“ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”˜
115
155
 
116
- Unused variables (defined but not used):
156
+ ⚠ Unused variables (defined but not used):
117
157
 
118
158
  deprecated.setting
159
+
160
+ Summary: 1 defined Ā· 1 undefined Ā· 1 unused
119
161
  ```
120
162
 
121
163
  ### Dry run
@@ -129,19 +171,18 @@ docvars ./templates ./output --dry-run
129
171
  Output:
130
172
 
131
173
  ```
132
- Dry run - no files written
133
-
134
- Files to create (1):
135
- + config.md
136
-
137
- Files to update (2):
138
- ~ README.md
139
- ~ api.md
174
+ šŸ” Dry run - no files written
140
175
 
141
- Files unchanged (1):
142
- = changelog.md
176
+ ā”Œā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”¬ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”
177
+ │ File │ Status │
178
+ ā”œā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”¼ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”¤
179
+ │ config.md │ + create │
180
+ │ README.md │ ~ update │
181
+ │ api.md │ ~ update │
182
+ │ changelog.md │ = unchanged │
183
+ ā””ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”“ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”˜
143
184
 
144
- Summary: 1 create, 2 update, 1 unchanged
185
+ Summary: 1 create Ā· 2 update Ā· 1 unchanged
145
186
  ```
146
187
 
147
188
  ## Template Syntax
@@ -13,7 +13,7 @@ export async function dryRun(options) {
13
13
  }
14
14
  const variables = loadVariables(options.vars);
15
15
  const files = await scanTemplates(inputDir, {
16
- include: options.include,
16
+ only: options.only,
17
17
  exclude: options.exclude,
18
18
  });
19
19
  const changes = [];
@@ -1,7 +1,7 @@
1
1
  export interface ListVariablesOptions {
2
2
  input: string;
3
3
  vars: string;
4
- include?: string;
4
+ only?: string;
5
5
  exclude?: string;
6
6
  }
7
7
  export interface VariableUsage {
@@ -5,7 +5,7 @@ import { loadVariables } from "../../infrastructure/repositories/variables-repos
5
5
  import { VariablesFileNotFoundError } from "../../shared/errors.js";
6
6
  const VARIABLE_PATTERN = /\{\{([\w.]+)\}\}/g;
7
7
  export async function listVariables(options) {
8
- const { input, vars, include, exclude } = options;
8
+ const { input, vars, only, exclude } = options;
9
9
  if (!existsSync(vars)) {
10
10
  throw new VariablesFileNotFoundError(vars);
11
11
  }
@@ -13,7 +13,7 @@ export async function listVariables(options) {
13
13
  const definedVars = loadVariables(vars);
14
14
  const definedVarNames = new Set(Object.keys(definedVars));
15
15
  // Scan templates and extract variable usage
16
- const templateFiles = await scanTemplates(input, { include, exclude });
16
+ const templateFiles = await scanTemplates(input, { only, exclude });
17
17
  const variableUsageMap = new Map();
18
18
  for (const file of templateFiles) {
19
19
  const content = readFileSync(file, "utf-8");
@@ -12,7 +12,7 @@ export async function processTemplates(options) {
12
12
  }
13
13
  const variables = loadVariables(options.vars);
14
14
  const files = await scanTemplates(inputDir, {
15
- include: options.include,
15
+ only: options.only,
16
16
  exclude: options.exclude,
17
17
  });
18
18
  const processedFiles = [];
@@ -3,7 +3,7 @@ export interface RenameOptions {
3
3
  vars: string;
4
4
  from: string;
5
5
  to: string;
6
- include?: string;
6
+ only?: string;
7
7
  exclude?: string;
8
8
  }
9
9
  export interface RenameResult {
@@ -6,7 +6,7 @@ function escapeRegex(str) {
6
6
  return str.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
7
7
  }
8
8
  export async function renameVariable(options) {
9
- const { input, vars, from, to, include, exclude } = options;
9
+ const { input, vars, from, to, only, exclude } = options;
10
10
  if (!existsSync(vars)) {
11
11
  throw new VariablesFileNotFoundError(vars);
12
12
  }
@@ -15,7 +15,7 @@ export async function renameVariable(options) {
15
15
  renamedInVars: false,
16
16
  };
17
17
  // Rename in template files
18
- const templateFiles = await scanTemplates(input, { include, exclude });
18
+ const templateFiles = await scanTemplates(input, { only, exclude });
19
19
  const pattern = new RegExp(`\\{\\{${escapeRegex(from)}(\\}\\}|\\|)`, "g");
20
20
  for (const file of templateFiles) {
21
21
  const content = readFileSync(file, "utf-8");
@@ -1,5 +1,5 @@
1
1
  export interface ScanOptions {
2
- include?: string;
2
+ only?: string;
3
3
  exclude?: string;
4
4
  }
5
5
  export declare function scanTemplates(inputDir: string, options?: ScanOptions): Promise<string[]>;
@@ -1,8 +1,39 @@
1
1
  import fg from "fast-glob";
2
+ // Binary and non-text files to ignore by default
3
+ const DEFAULT_IGNORE = [
4
+ "**/*.png",
5
+ "**/*.jpg",
6
+ "**/*.jpeg",
7
+ "**/*.gif",
8
+ "**/*.webp",
9
+ "**/*.ico",
10
+ "**/*.svg",
11
+ "**/*.pdf",
12
+ "**/*.zip",
13
+ "**/*.tar",
14
+ "**/*.gz",
15
+ "**/*.exe",
16
+ "**/*.dll",
17
+ "**/*.so",
18
+ "**/*.dylib",
19
+ "**/*.woff",
20
+ "**/*.woff2",
21
+ "**/*.ttf",
22
+ "**/*.eot",
23
+ "**/*.mp3",
24
+ "**/*.mp4",
25
+ "**/*.wav",
26
+ "**/*.avi",
27
+ "**/*.mov",
28
+ "**/node_modules/**",
29
+ "**/.git/**",
30
+ "**/.DS_Store",
31
+ ];
2
32
  export async function scanTemplates(inputDir, options = {}) {
3
- const pattern = options.include
4
- ? `${inputDir}/${options.include}`
5
- : `${inputDir}/**/*.md`;
6
- const ignore = options.exclude ? [`${inputDir}/${options.exclude}`] : [];
7
- return fg(pattern, { ignore });
33
+ const pattern = options.only ? `${inputDir}/${options.only}` : `${inputDir}/**/*`;
34
+ const ignore = [
35
+ ...DEFAULT_IGNORE.map((p) => `${inputDir}/${p}`),
36
+ ...(options.exclude ? [`${inputDir}/${options.exclude}`] : []),
37
+ ];
38
+ return fg(pattern, { ignore, onlyFiles: true });
8
39
  }
@@ -11,37 +11,45 @@ export declare const mainCommand: import("citty").CommandDef<{
11
11
  };
12
12
  vars: {
13
13
  type: "string";
14
+ alias: string;
14
15
  description: string;
15
16
  default: string;
16
17
  };
17
- include: {
18
+ only: {
18
19
  type: "string";
20
+ alias: string;
19
21
  description: string;
20
22
  };
21
23
  exclude: {
22
24
  type: "string";
25
+ alias: string;
23
26
  description: string;
24
27
  };
25
28
  watch: {
26
29
  type: "boolean";
30
+ alias: string;
27
31
  description: string;
28
32
  default: false;
29
33
  };
30
34
  "rename-from": {
31
35
  type: "string";
36
+ alias: string;
32
37
  description: string;
33
38
  };
34
39
  "rename-to": {
35
40
  type: "string";
41
+ alias: string;
36
42
  description: string;
37
43
  };
38
44
  "list-vars": {
39
45
  type: "boolean";
46
+ alias: string;
40
47
  description: string;
41
48
  default: false;
42
49
  };
43
50
  "dry-run": {
44
51
  type: "boolean";
52
+ alias: string;
45
53
  description: string;
46
54
  default: false;
47
55
  };
@@ -89,37 +89,45 @@ export const mainCommand = defineCommand({
89
89
  },
90
90
  vars: {
91
91
  type: "string",
92
+ alias: "v",
92
93
  description: "Path to variables YAML file",
93
94
  default: "variables.yaml",
94
95
  },
95
- include: {
96
+ only: {
96
97
  type: "string",
97
- description: "Glob pattern to include files",
98
+ alias: "o",
99
+ description: "Glob pattern to filter files (e.g. **/*.md)",
98
100
  },
99
101
  exclude: {
100
102
  type: "string",
103
+ alias: "e",
101
104
  description: "Glob pattern to exclude files",
102
105
  },
103
106
  watch: {
104
107
  type: "boolean",
108
+ alias: "w",
105
109
  description: "Watch for file changes and rebuild automatically",
106
110
  default: false,
107
111
  },
108
112
  "rename-from": {
109
113
  type: "string",
114
+ alias: "r",
110
115
  description: "Variable name to rename from (use with --rename-to)",
111
116
  },
112
117
  "rename-to": {
113
118
  type: "string",
119
+ alias: "t",
114
120
  description: "Variable name to rename to (use with --rename-from)",
115
121
  },
116
122
  "list-vars": {
117
123
  type: "boolean",
124
+ alias: "l",
118
125
  description: "List all variables used in templates",
119
126
  default: false,
120
127
  },
121
128
  "dry-run": {
122
129
  type: "boolean",
130
+ alias: "d",
123
131
  description: "Preview changes without writing files",
124
132
  default: false,
125
133
  },
@@ -132,7 +140,7 @@ export const mainCommand = defineCommand({
132
140
  input: args.input,
133
141
  output: args.output,
134
142
  vars: args.vars,
135
- include: args.include,
143
+ only: args.only,
136
144
  exclude: args.exclude,
137
145
  });
138
146
  console.log(pc.bold(pc.cyan("\nšŸ” Dry run - no files written\n")));
@@ -194,7 +202,7 @@ export const mainCommand = defineCommand({
194
202
  const result = await listVariables({
195
203
  input: args.input,
196
204
  vars: args.vars,
197
- include: args.include,
205
+ only: args.only,
198
206
  exclude: args.exclude,
199
207
  });
200
208
  console.log(pc.bold(pc.cyan("\nšŸ“‹ Variables\n")));
@@ -252,7 +260,7 @@ export const mainCommand = defineCommand({
252
260
  vars: args.vars,
253
261
  from: args["rename-from"],
254
262
  to: args["rename-to"],
255
- include: args.include,
263
+ only: args.only,
256
264
  exclude: args.exclude,
257
265
  });
258
266
  if (result.renamedInFiles.length === 0 && !result.renamedInVars) {
@@ -294,7 +302,7 @@ export const mainCommand = defineCommand({
294
302
  input: args.input,
295
303
  output: args.output,
296
304
  vars: args.vars,
297
- include: args.include,
305
+ only: args.only,
298
306
  exclude: args.exclude,
299
307
  };
300
308
  const success = await runProcess(options);
@@ -2,7 +2,7 @@ export interface CliOptions {
2
2
  input: string;
3
3
  output: string;
4
4
  vars: string;
5
- include?: string;
5
+ only?: string;
6
6
  exclude?: string;
7
7
  }
8
8
  export interface ProcessResult {
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "docvars",
3
3
  "author": "Shunta Toda",
4
- "version": "0.3.0",
4
+ "version": "0.3.2",
5
5
  "description": "Replace {{variables}} in document templates with YAML values",
6
6
  "type": "module",
7
7
  "main": "./dist/application/use-cases/process-templates.js",