pug-tail 0.1.0-alpha.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.

Potentially problematic release.


This version of pug-tail might be problematic. Click here for more details.

Files changed (126) hide show
  1. package/CHANGELOG.md +37 -0
  2. package/LICENSE +21 -0
  3. package/README.md +318 -0
  4. package/dist/cli/config/loader.d.ts +9 -0
  5. package/dist/cli/config/loader.d.ts.map +1 -0
  6. package/dist/cli/config/loader.js +82 -0
  7. package/dist/cli/config/loader.js.map +1 -0
  8. package/dist/cli/config/matcher.d.ts +3 -0
  9. package/dist/cli/config/matcher.d.ts.map +1 -0
  10. package/dist/cli/config/matcher.js +29 -0
  11. package/dist/cli/config/matcher.js.map +1 -0
  12. package/dist/cli/config/types.d.ts +26 -0
  13. package/dist/cli/config/types.d.ts.map +1 -0
  14. package/dist/cli/config/types.js +2 -0
  15. package/dist/cli/config/types.js.map +1 -0
  16. package/dist/cli/dataLoader.d.ts +8 -0
  17. package/dist/cli/dataLoader.d.ts.map +1 -0
  18. package/dist/cli/dataLoader.js +70 -0
  19. package/dist/cli/dataLoader.js.map +1 -0
  20. package/dist/cli/dependencyTracker.d.ts +19 -0
  21. package/dist/cli/dependencyTracker.d.ts.map +1 -0
  22. package/dist/cli/dependencyTracker.js +149 -0
  23. package/dist/cli/dependencyTracker.js.map +1 -0
  24. package/dist/cli/fileProcessor.d.ts +32 -0
  25. package/dist/cli/fileProcessor.d.ts.map +1 -0
  26. package/dist/cli/fileProcessor.js +218 -0
  27. package/dist/cli/fileProcessor.js.map +1 -0
  28. package/dist/cli/pathResolver.d.ts +12 -0
  29. package/dist/cli/pathResolver.d.ts.map +1 -0
  30. package/dist/cli/pathResolver.js +35 -0
  31. package/dist/cli/pathResolver.js.map +1 -0
  32. package/dist/cli/watcher.d.ts +22 -0
  33. package/dist/cli/watcher.d.ts.map +1 -0
  34. package/dist/cli/watcher.js +186 -0
  35. package/dist/cli/watcher.js.map +1 -0
  36. package/dist/cli.d.ts +3 -0
  37. package/dist/cli.d.ts.map +1 -0
  38. package/dist/cli.js +624 -0
  39. package/dist/cli.js.map +1 -0
  40. package/dist/core/astTransformer.d.ts +32 -0
  41. package/dist/core/astTransformer.d.ts.map +1 -0
  42. package/dist/core/astTransformer.js +532 -0
  43. package/dist/core/astTransformer.js.map +1 -0
  44. package/dist/core/componentRegistry.d.ts +14 -0
  45. package/dist/core/componentRegistry.d.ts.map +1 -0
  46. package/dist/core/componentRegistry.js +32 -0
  47. package/dist/core/componentRegistry.js.map +1 -0
  48. package/dist/core/errorHandler.d.ts +24 -0
  49. package/dist/core/errorHandler.d.ts.map +1 -0
  50. package/dist/core/errorHandler.js +102 -0
  51. package/dist/core/errorHandler.js.map +1 -0
  52. package/dist/core/slotResolver.d.ts +9 -0
  53. package/dist/core/slotResolver.d.ts.map +1 -0
  54. package/dist/core/slotResolver.js +88 -0
  55. package/dist/core/slotResolver.js.map +1 -0
  56. package/dist/index.d.ts +10 -0
  57. package/dist/index.d.ts.map +1 -0
  58. package/dist/index.js +8 -0
  59. package/dist/index.js.map +1 -0
  60. package/dist/transform.d.ts +26 -0
  61. package/dist/transform.d.ts.map +1 -0
  62. package/dist/transform.js +247 -0
  63. package/dist/transform.js.map +1 -0
  64. package/dist/types/index.d.ts +41 -0
  65. package/dist/types/index.d.ts.map +1 -0
  66. package/dist/types/index.js +2 -0
  67. package/dist/types/index.js.map +1 -0
  68. package/dist/utils/astHelpers.d.ts +16 -0
  69. package/dist/utils/astHelpers.d.ts.map +1 -0
  70. package/dist/utils/astHelpers.js +66 -0
  71. package/dist/utils/astHelpers.js.map +1 -0
  72. package/dist/utils/attributeCategorizer.d.ts +6 -0
  73. package/dist/utils/attributeCategorizer.d.ts.map +1 -0
  74. package/dist/utils/attributeCategorizer.js +17 -0
  75. package/dist/utils/attributeCategorizer.js.map +1 -0
  76. package/dist/utils/attributes/addAttributeFallthrough.d.ts +4 -0
  77. package/dist/utils/attributes/addAttributeFallthrough.d.ts.map +1 -0
  78. package/dist/utils/attributes/addAttributeFallthrough.js +22 -0
  79. package/dist/utils/attributes/addAttributeFallthrough.js.map +1 -0
  80. package/dist/utils/attributes/createAttributesCode.d.ts +3 -0
  81. package/dist/utils/attributes/createAttributesCode.d.ts.map +1 -0
  82. package/dist/utils/attributes/createAttributesCode.js +21 -0
  83. package/dist/utils/attributes/createAttributesCode.js.map +1 -0
  84. package/dist/utils/attributes/extractAttributes.d.ts +4 -0
  85. package/dist/utils/attributes/extractAttributes.d.ts.map +1 -0
  86. package/dist/utils/attributes/extractAttributes.js +15 -0
  87. package/dist/utils/attributes/extractAttributes.js.map +1 -0
  88. package/dist/utils/attributes/findRootElements.d.ts +7 -0
  89. package/dist/utils/attributes/findRootElements.d.ts.map +1 -0
  90. package/dist/utils/attributes/findRootElements.js +36 -0
  91. package/dist/utils/attributes/findRootElements.js.map +1 -0
  92. package/dist/utils/attributes/index.d.ts +5 -0
  93. package/dist/utils/attributes/index.d.ts.map +1 -0
  94. package/dist/utils/attributes/index.js +5 -0
  95. package/dist/utils/attributes/index.js.map +1 -0
  96. package/dist/utils/babelHelpers.d.ts +3 -0
  97. package/dist/utils/babelHelpers.d.ts.map +1 -0
  98. package/dist/utils/babelHelpers.js +73 -0
  99. package/dist/utils/babelHelpers.js.map +1 -0
  100. package/dist/utils/componentDetector.d.ts +12 -0
  101. package/dist/utils/componentDetector.d.ts.map +1 -0
  102. package/dist/utils/componentDetector.js +206 -0
  103. package/dist/utils/componentDetector.js.map +1 -0
  104. package/dist/utils/dataFilesDetector.d.ts +4 -0
  105. package/dist/utils/dataFilesDetector.d.ts.map +1 -0
  106. package/dist/utils/dataFilesDetector.js +88 -0
  107. package/dist/utils/dataFilesDetector.js.map +1 -0
  108. package/dist/utils/deepClone.d.ts +5 -0
  109. package/dist/utils/deepClone.d.ts.map +1 -0
  110. package/dist/utils/deepClone.js +10 -0
  111. package/dist/utils/deepClone.js.map +1 -0
  112. package/dist/utils/index.d.ts +7 -0
  113. package/dist/utils/index.d.ts.map +1 -0
  114. package/dist/utils/index.js +7 -0
  115. package/dist/utils/index.js.map +1 -0
  116. package/dist/utils/scopeAnalyzer.d.ts +5 -0
  117. package/dist/utils/scopeAnalyzer.d.ts.map +1 -0
  118. package/dist/utils/scopeAnalyzer.js +267 -0
  119. package/dist/utils/scopeAnalyzer.js.map +1 -0
  120. package/dist/utils/usageDetector.d.ts +8 -0
  121. package/dist/utils/usageDetector.d.ts.map +1 -0
  122. package/dist/utils/usageDetector.js +148 -0
  123. package/dist/utils/usageDetector.js.map +1 -0
  124. package/docs/COMPONENTS.md +708 -0
  125. package/docs/CONFIGURATION.md +708 -0
  126. package/package.json +103 -0
@@ -0,0 +1,708 @@
1
+ # Configuration File Guide
2
+
3
+ ## Overview
4
+
5
+ pug-tail supports configuration files for project-wide settings. Configuration files are automatically detected in the current directory or parent directories.
6
+
7
+ ## Supported Config Files
8
+
9
+ pug-tail searches for configuration files in the following order:
10
+
11
+ 1. `pugtail.config.js` - JavaScript (ES Module or CommonJS)
12
+ 2. `pugtail.config.mjs` - JavaScript ES Module
13
+ 3. `pugtail.config.json` - JSON format
14
+ 4. `.pugtailrc.js` - JavaScript (ES Module or CommonJS)
15
+ 5. `.pugtailrc.mjs` - JavaScript ES Module
16
+ 6. `.pugtailrc.json` - JSON format
17
+ 7. `.pugtailrc` - JSON format (without extension)
18
+
19
+ ### Search Behavior
20
+
21
+ pug-tail searches for configuration files starting from the **current directory** (`process.cwd()`) and moves **upward through parent directories** until:
22
+
23
+ - A configuration file is found (first match wins)
24
+ - A project root is detected (`package.json` or `.git` directory)
25
+ - The filesystem root is reached
26
+
27
+ **Example:**
28
+ ```
29
+ /home/user/project/ ← package.json (stops here)
30
+ src/
31
+ pages/ ← Current directory
32
+ index.pug
33
+ pugtail.config.js ← Found!
34
+ ```
35
+
36
+ If you run `pug-tail` from `/home/user/project/src/pages/`, it will find `/home/user/project/pugtail.config.js`.
37
+
38
+ ## Path Resolution Rules
39
+
40
+ ### With Config File (Vite-style)
41
+
42
+ When a configuration file exists, **all paths in the config file are resolved relative to the config file's location**.
43
+
44
+ ```javascript
45
+ // examples/pugtail.config.js
46
+ export default {
47
+ files: {
48
+ input: '**/*.pug', // → examples/**/*.pug
49
+ output: '../compiled', // → compiled/ (parent directory)
50
+ },
51
+ basedir: '.', // → examples/
52
+ data: './data/global.json' // → examples/data/global.json
53
+ }
54
+ ```
55
+
56
+ ### Without Config File (Webpack/ESLint-style)
57
+
58
+ When no configuration file exists, paths are resolved relative to `process.cwd()`:
59
+
60
+ - **Via npm scripts**: Relative to `package.json` location
61
+ - **Direct execution**: Relative to shell's current directory
62
+
63
+ ```bash
64
+ # Via npm run (always uses package.json location)
65
+ npm run pug-tail -- -o dist src/**/*.pug
66
+
67
+ # Direct execution (uses current directory)
68
+ cd /path/to/project
69
+ pug-tail -o dist src/**/*.pug
70
+ ```
71
+
72
+ ## Configuration Options
73
+
74
+ ### `files`
75
+
76
+ File-related settings.
77
+
78
+ #### `files.input`
79
+
80
+ - **Type**: `string | string[]`
81
+ - **Default**: (none, required via CLI or config)
82
+ - **Description**: Input files, directories, or glob patterns
83
+
84
+ ```javascript
85
+ // Single pattern
86
+ input: 'src/**/*.pug'
87
+
88
+ // Multiple patterns
89
+ input: ['src/pages/**/*.pug', 'src/templates/**/*.pug']
90
+
91
+ // Directory
92
+ input: 'src/pages'
93
+ ```
94
+
95
+ #### `files.output`
96
+
97
+ - **Type**: `string`
98
+ - **Default**: (none, required)
99
+ - **Description**: Output directory (for multiple files) or file path (for single file)
100
+
101
+ ```javascript
102
+ // Output directory
103
+ output: 'dist'
104
+
105
+ // Single file output
106
+ output: 'dist/index.html'
107
+ ```
108
+
109
+ #### `files.root`
110
+
111
+ - **Type**: `string`
112
+ - **Default**: Auto-detected from input pattern
113
+ - **Description**: Root path for maintaining directory structure in output
114
+
115
+ ```javascript
116
+ // Without root: examples/pages/index.pug → compiled/pages/index.html
117
+ // With root: examples/pages/index.pug → compiled/index.html
118
+ root: 'examples/pages'
119
+ ```
120
+
121
+ #### `files.render`
122
+
123
+ - **Type**: `string[]`
124
+ - **Default**: `['**/*.pug', '!**/_*.pug', '!**/*.component.pug', '!**/components/**/*.pug']`
125
+ - **Description**: Patterns determining which .pug files to compile. Supports negation with `!`
126
+
127
+ ```javascript
128
+ render: [
129
+ '**/*.pug', // All .pug files
130
+ '!**/_*.pug', // Exclude files starting with _ (Pug standard)
131
+ '!**/*.component.pug', // Exclude component files by naming convention
132
+ '!**/components/**/*.pug', // Exclude components directory
133
+ ]
134
+ ```
135
+
136
+ ### `extension`
137
+
138
+ - **Type**: `string`
139
+ - **Default**: `'.html'`
140
+ - **Description**: Output file extension
141
+
142
+ ```javascript
143
+ extension: '.html'
144
+ ```
145
+
146
+ ### `basedir`
147
+
148
+ - **Type**: `string`
149
+ - **Default**: `undefined`
150
+ - **Description**: Base directory for absolute includes (paths starting with `/`)
151
+
152
+ ```javascript
153
+ // In Pug: include /layouts/base.pug
154
+ // Resolves to: <basedir>/layouts/base.pug
155
+ basedir: 'src'
156
+ ```
157
+
158
+ ### `doctype`
159
+
160
+ - **Type**: `string`
161
+ - **Default**: `undefined` (uses Pug's default)
162
+ - **Description**: Doctype to use in generated HTML
163
+
164
+ ```javascript
165
+ doctype: 'html' // <!DOCTYPE html>
166
+ ```
167
+
168
+ ### `pretty`
169
+
170
+ - **Type**: `boolean`
171
+ - **Default**: `false`
172
+ - **Description**: Pretty-print HTML output with indentation
173
+
174
+ ```javascript
175
+ pretty: true
176
+ ```
177
+
178
+ ### `format`
179
+
180
+ - **Type**: `'html' | 'ast' | 'pug-code'`
181
+ - **Default**: `'html'`
182
+ - **Description**: Output format
183
+
184
+ ```javascript
185
+ format: 'html' // Standard HTML output
186
+ format: 'ast' // Output transformed AST as JSON
187
+ format: 'pug-code' // Output transformed Pug code
188
+ ```
189
+
190
+ ### `data`
191
+
192
+ - **Type**: `string | Record<string, unknown>`
193
+ - **Default**: `undefined`
194
+ - **Description**: Global data to inject into all templates
195
+
196
+ ```javascript
197
+ // JSON string
198
+ data: '{"title": "My Site"}'
199
+
200
+ // File path (relative to config file)
201
+ data: './data/global.json'
202
+
203
+ // Object
204
+ data: { title: 'My Site', author: 'John Doe' }
205
+ ```
206
+
207
+ ### `dataKey`
208
+
209
+ - **Type**: `string`
210
+ - **Default**: `undefined` (data injected directly as top-level variables)
211
+ - **Description**: Key name for injected global data. When specified, all data from the `data` option is wrapped in this key.
212
+
213
+ **Without `dataKey` (default behavior):**
214
+
215
+ ```javascript
216
+ // pugtail.config.js
217
+ export default {
218
+ data: './data/global.json'
219
+ // No dataKey specified
220
+ }
221
+ ```
222
+
223
+ ```json
224
+ // global.json
225
+ {
226
+ "siteName": "My Site",
227
+ "navigation": [...]
228
+ }
229
+ ```
230
+
231
+ ```pug
232
+ // Direct access to data
233
+ p= siteName
234
+ each item in navigation
235
+ a(href=item.url)= item.label
236
+ ```
237
+
238
+ **With `dataKey` (recommended for strict mode):**
239
+
240
+ ```javascript
241
+ // pugtail.config.js
242
+ export default {
243
+ data: './data/global.json',
244
+ dataKey: 'global', // Wrap data in 'global' key
245
+
246
+ validation: {
247
+ scopeIsolation: 'error',
248
+ allowedGlobals: ['$props', '$slots', 'global'] // Allow 'global' in components
249
+ }
250
+ }
251
+ ```
252
+
253
+ ```json
254
+ // global.json
255
+ {
256
+ "siteName": "My Site",
257
+ "navigation": [...]
258
+ }
259
+ ```
260
+
261
+ ```pug
262
+ // Access via global key
263
+ p= global.siteName
264
+ each item in global.navigation
265
+ a(href=item.url)= item.label
266
+
267
+ // In components
268
+ component Header()
269
+ header
270
+ a(href=global.siteUrl)= global.siteName // ✓ OK with allowedGlobals
271
+ each item in global.navigation
272
+ a(href=item.url)= item.label
273
+ ```
274
+
275
+ **Benefits of using `dataKey`:**
276
+
277
+ 1. **Namespace isolation**: Prevents variable name collisions
278
+ 2. **Explicit data access**: Clear distinction between global data and local variables
279
+ 3. **Component scope control**: Works well with `scopeIsolation: 'error'` mode
280
+ 4. **Easier debugging**: Know exactly where data comes from (`global.siteName` vs `siteName`)
281
+
282
+ **Recommended setup:**
283
+
284
+ ```javascript
285
+ export default {
286
+ data: './data/global.json',
287
+ dataKey: 'global', // Recommended: use a namespace
288
+
289
+ validation: {
290
+ scopeIsolation: 'error', // Strict mode
291
+ allowedGlobals: ['$props', '$slots', 'global'] // Allow global data access
292
+ }
293
+ }
294
+ ```
295
+
296
+ ### Per-Page Data Files (`$dataFiles`)
297
+
298
+ In addition to global data (via the `data` option or `--obj` CLI flag), you can load page-specific data files using the `$dataFiles` directive in your **entry Pug files** (files that are directly compiled, not included/extended files).
299
+
300
+ #### Usage
301
+
302
+ ```pug
303
+ // pages/index.pug (entry file)
304
+ - const $dataFiles = ['/data/navigation.json', '/data/footer.json']
305
+
306
+ // Data from these files is now available
307
+ header
308
+ each item in navigation
309
+ a(href=item.url)= item.label
310
+
311
+ footer
312
+ p= footer.copyright
313
+ ```
314
+
315
+ #### Path Resolution
316
+
317
+ - **Absolute paths** (starting with `/`): Resolved relative to `basedir`
318
+ ```pug
319
+ // If basedir is 'src', this resolves to 'src/data/navigation.json'
320
+ - const $dataFiles = ['/data/navigation.json']
321
+ ```
322
+
323
+ - **Relative paths**: Resolved relative to the entry file's directory
324
+ ```pug
325
+ // pages/index.pug
326
+ // Resolves to 'pages/data/navigation.json'
327
+ - const $dataFiles = ['./data/navigation.json']
328
+ // Resolves to 'data/navigation.json' (parent directory)
329
+ - const $dataFiles = ['../data/navigation.json']
330
+ ```
331
+
332
+ #### Important Constraints
333
+
334
+ 1. **Entry files only**: `$dataFiles` can only be used in entry files (files directly passed to the compiler)
335
+ ```pug
336
+ // ✓ OK - Entry file
337
+ // pages/index.pug
338
+ - const $dataFiles = ['/data/nav.json']
339
+ ```
340
+
341
+ ```pug
342
+ // ✗ NOT ALLOWED - Included component
343
+ // components/Header.pug
344
+ - const $dataFiles = ['/data/nav.json'] // Will be ignored
345
+ ```
346
+
347
+ 2. **Data separation with `dataKey`**:
348
+ - **Global data** (from `data` option): Wrapped in `dataKey` if specified
349
+ - **Page data** (from `$dataFiles`): Always injected directly, never wrapped
350
+
351
+ ```javascript
352
+ // Config with dataKey
353
+ export default {
354
+ data: './data/global.json',
355
+ dataKey: 'global'
356
+ }
357
+ ```
358
+
359
+ ```pug
360
+ // pages/index.pug
361
+ - const $dataFiles = ['/data/index.json']
362
+
363
+ // Global data: accessed via 'global' key
364
+ p= global.siteName
365
+
366
+ // Page data: accessed directly
367
+ p= hero.title
368
+ ```
369
+
370
+ 3. **Merge order**: Data is merged in the following order (later sources override earlier ones):
371
+ - Global data from config (`data` option)
372
+ - Global data from CLI (`--obj` flag)
373
+ - Page-specific data from `$dataFiles`
374
+
375
+ 4. **Automatic removal**: The `$dataFiles` declaration is automatically removed from the output, so it won't appear in the compiled HTML
376
+
377
+ #### Example Workflow
378
+
379
+ **Project structure:**
380
+ ```
381
+ project/
382
+ ├── pugtail.config.js
383
+ ├── src/
384
+ │ ├── data/
385
+ │ │ ├── global.json # Global data
386
+ │ │ ├── navigation.json # Page-specific
387
+ │ │ └── footer.json # Page-specific
388
+ │ └── pages/
389
+ │ ├── index.pug # Entry file
390
+ │ └── about.pug # Entry file
391
+ ```
392
+
393
+ **Configuration:**
394
+ ```javascript
395
+ // pugtail.config.js
396
+ export default {
397
+ basedir: 'src',
398
+ data: './data/global.json', // Global data for all pages
399
+ dataKey: 'global', // Wrap global data in 'global' key
400
+ files: {
401
+ input: 'src/pages/**/*.pug',
402
+ output: 'dist',
403
+ },
404
+ validation: {
405
+ scopeIsolation: 'error',
406
+ allowedGlobals: ['global'] // Allow components to access global.*
407
+ }
408
+ }
409
+ ```
410
+
411
+ **Entry file:**
412
+ ```pug
413
+ // src/pages/index.pug
414
+ - const $dataFiles = ['/data/navigation.json', '/data/footer.json']
415
+
416
+ // Access global data (from global.json, via 'global' key)
417
+ p= global.siteName
418
+
419
+ // Access page-specific data (from $dataFiles, directly)
420
+ header
421
+ each item in navigation
422
+ a(href=item.url)= item.label
423
+
424
+ footer
425
+ p= footer.copyright
426
+ ```
427
+
428
+ ### `watch`
429
+
430
+ - **Type**: `object`
431
+ - **Default**: `{ enabled: false, debounce: 300 }`
432
+ - **Description**: Watch mode settings
433
+
434
+ #### `watch.enabled`
435
+
436
+ - **Type**: `boolean`
437
+ - **Default**: `false`
438
+ - **Description**: Enable watch mode
439
+
440
+ ```javascript
441
+ watch: {
442
+ enabled: true
443
+ }
444
+ ```
445
+
446
+ #### `watch.debounce`
447
+
448
+ - **Type**: `number`
449
+ - **Default**: `300`
450
+ - **Description**: Debounce delay in milliseconds
451
+
452
+ ```javascript
453
+ watch: {
454
+ enabled: true,
455
+ debounce: 500 // Wait 500ms after last change
456
+ }
457
+ ```
458
+
459
+ ### `silent`
460
+
461
+ - **Type**: `boolean`
462
+ - **Default**: `false`
463
+ - **Description**: Suppress all log output (except errors)
464
+
465
+ ```javascript
466
+ silent: true
467
+ ```
468
+
469
+ ### `debug`
470
+
471
+ - **Type**: `boolean`
472
+ - **Default**: `false`
473
+ - **Description**: Enable detailed debug output for troubleshooting compilation issues
474
+
475
+ When enabled, displays detailed information about:
476
+ - Component registration (name, slots, location)
477
+ - Slot replacements (provided slots vs defined slots)
478
+ - File processing steps (lexing, parsing, transformation)
479
+ - Data loading
480
+ - AST traversal for slot detection
481
+
482
+ **Useful for:**
483
+ - Debugging slot definition/usage issues
484
+ - Understanding component transformation flow
485
+ - Troubleshooting compilation errors
486
+ - Investigating missing or undetected slots
487
+
488
+ ```javascript
489
+ debug: true
490
+ ```
491
+
492
+ **CLI Usage:**
493
+ ```bash
494
+ # Enable debug mode via CLI flag
495
+ pug-tail -d src/**/*.pug -o dist/
496
+
497
+ # Or with long form
498
+ pug-tail --debug src/**/*.pug -o dist/
499
+ ```
500
+
501
+ **Example Debug Output:**
502
+ ```
503
+ [pug-tail] Starting transformation...
504
+ [pug-tail] Lexed 398 tokens
505
+ [DEBUG] Registered component: Card
506
+ - Slots: content, footer
507
+ - Location: /path/to/Card.pug:1
508
+ [DEBUG] replaceSlots called:
509
+ - Provided slots: content
510
+ - Defined slots: content, footer
511
+ - Call location: /path/to/about.pug:42
512
+ ```
513
+
514
+ ### `validation`
515
+
516
+ Validation and code quality settings.
517
+
518
+ #### `validation.scopeIsolation`
519
+
520
+ - **Type**: `'error' | 'warn' | 'off'`
521
+ - **Default**: `'error'`
522
+ - **Description**: Controls how external variable references in components are handled
523
+
524
+ **Modes:**
525
+
526
+ - **`'error'` (default, strict mode)**
527
+ - Throws compilation errors when components reference external variables
528
+ - Enforces complete scope isolation
529
+ - Recommended for new projects
530
+ - Follows Vue.js/React best practices
531
+
532
+ - **`'warn'`**
533
+ - Logs warnings but allows compilation
534
+ - Useful for gradual migration from legacy code
535
+ - Helps identify scope issues without breaking builds
536
+
537
+ - **`'off'`**
538
+ - Disables validation entirely
539
+ - Components can access external variables (legacy Pug behavior)
540
+ - Use only when necessary for backward compatibility
541
+
542
+ **Example:**
543
+
544
+ ```javascript
545
+ // Strict mode (default, recommended)
546
+ validation: {
547
+ scopeIsolation: 'error' // Can be omitted (default)
548
+ }
549
+
550
+ // Gradual migration with warnings
551
+ validation: {
552
+ scopeIsolation: 'warn'
553
+ }
554
+
555
+ // Legacy mode (disable validation)
556
+ validation: {
557
+ scopeIsolation: 'off'
558
+ }
559
+ ```
560
+
561
+ **Error Example:**
562
+
563
+ ```pug
564
+ // This will throw an error in strict mode:
565
+ - const message = 'Hello'
566
+
567
+ component Card()
568
+ p= message // Error: Component "Card" references external variable "message"
569
+
570
+ Card()
571
+ ```
572
+
573
+ **Correct Usage:**
574
+
575
+ ```pug
576
+ // Pass via props:
577
+ - const message = 'Hello'
578
+
579
+ component Card()
580
+ - const { text } = $props
581
+ p= text
582
+
583
+ Card(text=message) // ✓ OK
584
+ ```
585
+
586
+ #### `validation.allowedGlobals`
587
+
588
+ - **Type**: `string[]`
589
+ - **Default**: `[]`
590
+ - **Description**: Additional global variables to allow in components (even in strict mode)
591
+
592
+ **Built-in allowed identifiers** (always permitted):
593
+ - JavaScript standard globals: `console`, `Math`, `Date`, `JSON`, `Object`, `Array`, `String`, `Number`, `Boolean`, `RegExp`, `Error`, `Promise`, `Set`, `Map`, etc.
594
+ - Pug built-ins: `attributes`, `block`
595
+ - pug-tail keywords: `$props`, `$attrs`
596
+
597
+ **Example:**
598
+
599
+ ```javascript
600
+ validation: {
601
+ scopeIsolation: 'error',
602
+ allowedGlobals: ['myCustomHelper', 'APP_VERSION']
603
+ }
604
+ ```
605
+
606
+ Now components can reference `myCustomHelper` and `APP_VERSION` without errors:
607
+
608
+ ```pug
609
+ component Card()
610
+ p= myCustomHelper('test') // ✓ OK
611
+ p Version: #{APP_VERSION} // ✓ OK
612
+ ```
613
+
614
+ ## Complete Example
615
+
616
+ ```javascript
617
+ // pugtail.config.js
618
+ export default {
619
+ files: {
620
+ input: ['src/pages/**/*.pug', 'src/templates/**/*.pug'],
621
+ output: 'dist',
622
+ root: 'src/pages',
623
+ render: [
624
+ '**/*.pug',
625
+ '!**/_*.pug',
626
+ '!**/*.component.pug',
627
+ '!**/components/**/*.pug',
628
+ ],
629
+ },
630
+ extension: '.html',
631
+ basedir: 'src',
632
+ doctype: 'html',
633
+ pretty: true,
634
+ format: 'html',
635
+ data: './data/global.json',
636
+ dataKey: 'global', // Wrap data in 'global' namespace
637
+ watch: {
638
+ enabled: false,
639
+ debounce: 300,
640
+ },
641
+ validation: {
642
+ scopeIsolation: 'error',
643
+ allowedGlobals: ['global'], // Allow global data access
644
+ },
645
+ silent: false,
646
+ debug: false,
647
+ }
648
+ ```
649
+
650
+ ## Using ES Modules vs CommonJS
651
+
652
+ ### ES Module (Recommended)
653
+
654
+ ```javascript
655
+ // pugtail.config.js or .mjs
656
+ export default {
657
+ files: {
658
+ input: 'src/**/*.pug',
659
+ output: 'dist',
660
+ },
661
+ pretty: true,
662
+ }
663
+ ```
664
+
665
+ ### CommonJS
666
+
667
+ ```javascript
668
+ // pugtail.config.js
669
+ module.exports = {
670
+ files: {
671
+ input: 'src/**/*.pug',
672
+ output: 'dist',
673
+ },
674
+ pretty: true,
675
+ }
676
+ ```
677
+
678
+ ### JSON
679
+
680
+ ```json
681
+ {
682
+ "files": {
683
+ "input": "src/**/*.pug",
684
+ "output": "dist"
685
+ },
686
+ "pretty": true
687
+ }
688
+ ```
689
+
690
+ ## CLI Override
691
+
692
+ CLI options always take precedence over configuration file settings:
693
+
694
+ ```bash
695
+ # Config file has pretty: false
696
+ # This command will use pretty: true
697
+ pug-tail -c config.js --pretty
698
+ ```
699
+
700
+ ## Configuration File Location
701
+
702
+ You can specify a custom configuration file path:
703
+
704
+ ```bash
705
+ pug-tail -c path/to/custom-config.js
706
+ ```
707
+
708
+ Without the `-c` option, pug-tail will automatically search for configuration files starting from the current directory and moving up to parent directories until it finds one or reaches the project root (detected by `package.json` or `.git`).