directory-lint 1.0.2 → 2.0.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.
package/README.md CHANGED
@@ -8,12 +8,12 @@ A powerful TypeScript library for validating and generating directory structures
8
8
  ## ✨ Features
9
9
 
10
10
  - 🔍 **Schema-based Validation** - Define your directory structure using intuitive schemas
11
- - 🏗️ **Automatic Generation** - Create directory structures from schemas with templates
11
+ - 🏗️ **Automatic Generation** - Create directory structures from schemas with content templates
12
12
  - 📝 **Pattern Matching** - Support for wildcards and regex patterns
13
- - 🎯 **15+ Framework Presets** - Built-in schemas for popular frameworks (Next.js, NestJS, Vite, etc.)
14
13
  - 🔧 **Flexible Backend** - Pluggable backend system (File System or custom)
15
14
  - 📦 **Zero Dependencies** - Lightweight with minimal footprint
16
15
  - 🎯 **TypeScript First** - Full TypeScript support with comprehensive types
16
+ - ✅ **Custom Validation** - Validate file content with custom functions
17
17
 
18
18
  ## 📦 Installation
19
19
 
@@ -26,11 +26,11 @@ npm install directory-lint
26
26
  ### Validating a Directory Structure
27
27
 
28
28
  ```typescript
29
- import { DirectoryLint, type LintSchema } from "directory-lint";
29
+ import { DirectoryLint, type ValidateSchema } from "directory-lint";
30
30
 
31
- const schema: LintSchema = {
31
+ const schema: ValidateSchema = {
32
32
  "src": {
33
- type: "dir",
33
+ type: "directory",
34
34
  required: true,
35
35
  children: {
36
36
  "index.ts": {
@@ -38,7 +38,7 @@ const schema: LintSchema = {
38
38
  required: true
39
39
  },
40
40
  "components": {
41
- type: "dir",
41
+ type: "directory",
42
42
  required: true
43
43
  }
44
44
  }
@@ -55,35 +55,28 @@ const result = await linter.validate("./my-project", schema, {
55
55
  ignore: ["node_modules", "dist", ".git"]
56
56
  });
57
57
 
58
- if (result.valid) {
59
- console.log("✅ Directory structure is valid!");
60
- } else {
61
- console.error("❌ Validation errors:", result.errors);
62
- console.warn("⚠️ Warnings:", result.warnings);
63
- }
58
+ console.log("Validation result:", result);
64
59
  ```
65
60
 
66
61
  ### Generating a Directory Structure
67
62
 
68
63
  ```typescript
69
- import { DirectoryLint, type LintSchema } from "directory-lint";
64
+ import { DirectoryLint, type GenerateSchema } from "directory-lint";
70
65
 
71
- const schema: LintSchema = {
66
+ const schema: GenerateSchema = {
72
67
  "src": {
73
- type: "dir",
74
- required: true,
68
+ type: "directory",
75
69
  children: {
76
70
  "index.ts": {
77
71
  type: "file",
78
- required: true,
79
- template: "export * from './components';\n"
72
+ content: "export * from './components';\n"
80
73
  },
81
74
  "utils": {
82
- type: "dir",
75
+ type: "directory",
83
76
  children: {
84
77
  "helper.ts": {
85
78
  type: "file",
86
- template: () => `// Generated on ${new Date().toISOString()}\n`
79
+ content: `// Generated on ${new Date().toISOString()}\n`
87
80
  }
88
81
  }
89
82
  }
@@ -99,51 +92,59 @@ const result = await linter.generate("./new-project", schema, {
99
92
  });
100
93
 
101
94
  console.log("✅ Directory structure generated!");
102
- if (result.warnings.length > 0) {
103
- console.warn("⚠️ Warnings:", result.warnings);
104
- }
95
+ console.log("Generated paths:", result.paths);
105
96
  ```
106
97
 
107
98
  ## 📚 Schema Definition
108
99
 
109
- ### Basic Schema Structure
100
+ ### Schema Types
110
101
 
111
- A schema is defined as a `LintSchema` object where keys represent file/directory names or patterns, and values define the node type and properties.
102
+ Directory Lint uses two distinct schema types:
112
103
 
113
- ```typescript
114
- type LintSchema = Record<string, LintNode>;
104
+ - **`GenerateSchema`** - For creating directory structures
105
+ - **`ValidateSchema`** - For validating existing directory structures
115
106
 
116
- type LintNode = FileLintNode | DirectoryLintNode;
117
- ```
107
+ ### Validate Schema Structure
108
+
109
+ ```typescript
110
+ type ValidateSchema = Record<string, ValidateNode>;
118
111
 
119
- ### Node Types
112
+ type ValidateNode = ValidateFileSchema | ValidateDirectorySchema;
120
113
 
121
- #### File Node
114
+ interface ValidateFileSchema {
115
+ type: "file";
116
+ validate?: (content: any) => boolean;
117
+ required?: boolean; // Default: true
118
+ }
122
119
 
123
- ```typescript
124
- {
125
- type: "file",
126
- required?: boolean, // Default: true
127
- example?: string, // Example name for pattern-based keys
128
- template?: string | (() => string), // File content template
129
- validate?: (content: string) => boolean | Promise<boolean> // Custom validation
120
+ interface ValidateDirectorySchema {
121
+ type: "directory";
122
+ children?: ValidateSchema;
123
+ required?: boolean; // Default: true
130
124
  }
131
125
  ```
132
126
 
133
- #### Directory Node
127
+ ### Generate Schema Structure
134
128
 
135
129
  ```typescript
136
- {
137
- type: "dir",
138
- required?: boolean, // Default: true
139
- example?: string, // Example name for pattern-based keys
140
- children?: LintSchema // Nested schema for subdirectories
130
+ type GenerateSchema = Record<string, GenerateNode>;
131
+
132
+ type GenerateNode = GenerateFileSchema | GenerateDirectorySchema;
133
+
134
+ interface GenerateFileSchema {
135
+ type: "file";
136
+ content?: any; // File content (string, Buffer, etc.)
137
+ }
138
+
139
+ interface GenerateDirectorySchema {
140
+ type: "directory";
141
+ children?: GenerateSchema;
141
142
  }
142
143
  ```
143
144
 
144
145
  ### Pattern Matching
145
146
 
146
- Directory Lint supports flexible pattern matching:
147
+ Directory Lint supports flexible pattern matching in validation schemas:
147
148
 
148
149
  #### 1. Exact Match
149
150
  ```typescript
@@ -160,8 +161,7 @@ Directory Lint supports flexible pattern matching:
160
161
  {
161
162
  "*.test.ts": {
162
163
  type: "file",
163
- required: false,
164
- example: "example.test.ts"
164
+ required: false
165
165
  }
166
166
  }
167
167
  ```
@@ -171,281 +171,371 @@ Directory Lint supports flexible pattern matching:
171
171
  {
172
172
  "/^component-.+\\.tsx$/": {
173
173
  type: "file",
174
- required: false,
175
- example: "component-button.tsx"
174
+ required: false
176
175
  }
177
176
  }
178
177
  ```
179
178
 
180
- ## 🎯 Framework Presets
179
+ **Note:** Regex patterns are **not supported** in `GenerateSchema` and will throw a `RegexNotSupported` error.
181
180
 
182
- Directory Lint includes **15+ pre-configured schemas** for popular frameworks:
181
+ ## 💡 Examples
183
182
 
184
- ### Frontend
185
- - **Vite** - React, Vue, Svelte + Tailwind + Vitest
186
- - **Next.js** - App Router & Pages Router
187
- - **React** - CRA with Redux & Router
188
- - **Vue** - Vue 3 with Pinia & Router
189
- - **Angular** - Standalone & Module-based
190
- - **Svelte/SvelteKit** - With adapters
191
- - **Nuxt** - Nuxt 3 with plugins
192
- - **Astro** - Multi-framework support
193
- - **Remix** - Full-stack framework
194
- - **Gatsby** - Static site generator
183
+ ### Basic Generation
195
184
 
196
- ### Backend
197
- - **NestJS** - Microservices, GraphQL, Prisma
198
- - **Express** - REST APIs with databases
185
+ ```typescript
186
+ import { DirectoryLint, type GenerateSchema } from "directory-lint";
199
187
 
200
- ### Desktop
201
- - **Electron** - Desktop applications
188
+ const schema: GenerateSchema = {
189
+ "basic_file": {
190
+ type: "file",
191
+ },
192
+ "basic_folder": {
193
+ type: "directory",
194
+ children: {
195
+ "sub_dir_file": {
196
+ type: "file",
197
+ content: "Hello, World!"
198
+ }
199
+ }
200
+ }
201
+ }
202
202
 
203
- ### Monorepo
204
- - **Turborepo** - Modern monorepo tool
205
- - **Nx** - Smart monorepo
206
- - **Lerna** - Classic monorepo
203
+ const linter = new DirectoryLint();
204
+ await linter.generate("./generated", schema, { overwrite: true });
205
+ ```
207
206
 
208
- ### Using Presets
207
+ ### Basic Validation with Custom Validation
209
208
 
210
209
  ```typescript
211
- import { DirectoryLint } from "directory-lint";
212
- import { nextjs, nestjs, vite } from "directory-lint/presets";
213
-
214
- // Next.js with App Router
215
- const nextSchema = nextjs({
216
- appRouter: true,
217
- withTypeScript: true,
218
- withTailwind: true,
219
- withSrcDir: true
220
- });
221
-
222
- // NestJS with Prisma and GraphQL
223
- const nestSchema = nestjs({
224
- withPrisma: true,
225
- withGraphQL: true,
226
- withTesting: true
227
- });
210
+ import { DirectoryLint, type ValidateSchema } from "directory-lint";
228
211
 
229
- // Vite with React
230
- const viteSchema = vite({
231
- withTypeScript: true,
232
- withReact: true,
233
- withVitest: true
234
- });
212
+ const schema: ValidateSchema = {
213
+ "generated": {
214
+ type: "directory",
215
+ required: true,
216
+ children: {
217
+ "content.txt": {
218
+ type: "file",
219
+ required: true
220
+ },
221
+ "*.txt": {
222
+ type: "file",
223
+ validate: (content: string): boolean => {
224
+ return content.length > 1;
225
+ }
226
+ }
227
+ }
228
+ }
229
+ }
235
230
 
236
231
  const linter = new DirectoryLint();
237
- await linter.validate("./my-app", nextSchema);
232
+ const result = await linter.validate("./", schema, {
233
+ ignore: ["node_modules"]
234
+ });
238
235
  ```
239
236
 
240
- See the [Presets Documentation](./src/presets/README.md) for all available options.
241
-
242
- ## 🔧 Advanced Features
243
-
244
- ### File Templates
237
+ ### Project Template Generation
245
238
 
246
239
  ```typescript
247
- const schema: LintSchema = {
248
- "README.md": {
249
- type: "file",
250
- template: "# My Project\n\nGenerated with Directory Lint"
240
+ import { DirectoryLint, type GenerateSchema } from "directory-lint";
241
+
242
+ const projectSchema: GenerateSchema = {
243
+ "src": {
244
+ type: "directory",
245
+ children: {
246
+ "index.ts": {
247
+ type: "file",
248
+ content: "console.log('Hello, TypeScript!');"
249
+ },
250
+ "types": {
251
+ type: "directory",
252
+ children: {
253
+ "index.d.ts": {
254
+ type: "file",
255
+ content: "export {};"
256
+ }
257
+ }
258
+ }
259
+ }
251
260
  },
252
261
  "package.json": {
253
262
  type: "file",
254
- template: () => JSON.stringify({
263
+ content: JSON.stringify({
255
264
  name: "my-project",
256
265
  version: "1.0.0",
257
- createdAt: new Date().toISOString()
266
+ main: "src/index.ts"
267
+ }, null, 2)
268
+ },
269
+ "tsconfig.json": {
270
+ type: "file",
271
+ content: JSON.stringify({
272
+ compilerOptions: {
273
+ target: "ES2020",
274
+ module: "commonjs",
275
+ strict: true
276
+ }
258
277
  }, null, 2)
259
278
  }
260
279
  };
280
+
281
+ const linter = new DirectoryLint();
282
+ await linter.generate("./my-new-project", projectSchema, {
283
+ recursive: true,
284
+ overwrite: false
285
+ });
261
286
  ```
262
287
 
263
- ### Custom Validation
288
+ ### CI/CD Validation
264
289
 
265
290
  ```typescript
266
- const schema: LintSchema = {
291
+ import { DirectoryLint, type ValidateSchema } from "directory-lint";
292
+
293
+ const ciSchema: ValidateSchema = {
294
+ "src": {
295
+ type: "directory",
296
+ required: true,
297
+ children: {
298
+ "index.ts": {
299
+ type: "file",
300
+ required: true
301
+ }
302
+ }
303
+ },
267
304
  "package.json": {
268
305
  type: "file",
269
306
  required: true,
270
- validate: async (content) => {
271
- const pkg = JSON.parse(content);
272
- return pkg.name && pkg.version;
307
+ validate: (content: any) => {
308
+ try {
309
+ const pkg = JSON.parse(content);
310
+ return pkg.name && pkg.version;
311
+ } catch {
312
+ return false;
313
+ }
273
314
  }
315
+ },
316
+ "*.config.js": {
317
+ type: "file",
318
+ required: false
274
319
  }
275
320
  };
321
+
322
+ const linter = new DirectoryLint();
323
+
324
+ try {
325
+ const result = await linter.validate(".", ciSchema, {
326
+ ignore: ["node_modules", "dist", ".git"]
327
+ });
328
+ console.log("✅ Structure validation passed!");
329
+ } catch (error) {
330
+ console.error("❌ Structure validation failed:", error.message);
331
+ process.exit(1);
332
+ }
276
333
  ```
277
334
 
278
- ### Validation Options
335
+ ## 🔌 Custom Backend
336
+
337
+ Create custom backends for different storage systems:
279
338
 
280
339
  ```typescript
281
- const result = await linter.validate("./project", schema, {
282
- ignore: ["node_modules", "dist", ".git", "*.log"]
283
- });
340
+ import { LintBackend, LintItem } from "directory-lint";
341
+
342
+ const CustomBackend: LintBackend = {
343
+ getAllItems(path: string): LintItem[] {
344
+ // Return items in the directory
345
+ return [
346
+ { name: "file.txt", type: "file" },
347
+ { name: "folder", type: "directory" }
348
+ ];
349
+ },
350
+
351
+ writeFile(path: string, content: any): void {
352
+ // Write file content
353
+ console.log(`Writing to ${path}:`, content);
354
+ },
355
+
356
+ readFile(path: string): any {
357
+ // Read file content
358
+ return "file content";
359
+ },
360
+
361
+ makeDirectory(path: string, recursive?: boolean): void {
362
+ // Create directory
363
+ console.log(`Creating directory ${path}, recursive: ${recursive}`);
364
+ },
365
+
366
+ exists(path: string): boolean {
367
+ // Check if path exists
368
+ return true;
369
+ }
370
+ };
371
+
372
+ const linter = new DirectoryLint(CustomBackend);
284
373
  ```
285
374
 
286
- ### Generation Options
375
+ ## 📖 API Reference
376
+
377
+ ### `DirectoryLint`
287
378
 
379
+ #### Constructor
288
380
  ```typescript
289
- const result = await linter.generate("./project", schema, {
290
- overwrite: true, // Overwrite existing files
291
- recursive: true // Create parent directories
292
- });
381
+ constructor(backend?: LintBackend)
293
382
  ```
294
383
 
295
- ### Validation Results
384
+ Creates a new DirectoryLint instance with an optional custom backend. Defaults to `FileSystemBackend`.
385
+
386
+ #### Methods
387
+
388
+ ##### `generate(cwd: string, schema: GenerateSchema, options?: GenerateOptions): Promise<GenerateResult>`
389
+
390
+ Generates a directory structure based on a schema.
391
+
392
+ **Parameters:**
393
+ - `cwd`: Current working directory (base path)
394
+ - `schema`: Generation schema definition
395
+ - `options`: Optional generation options
396
+
397
+ **Options:**
398
+ - `overwrite?: boolean` - Overwrite existing files (default: false)
399
+ - `recursive?: boolean` - Create parent directories if they don't exist (default: false)
296
400
 
401
+ **Returns:**
297
402
  ```typescript
298
- interface ValidationResult {
299
- valid: boolean;
300
- errors: Array<{
403
+ interface GenerateResult {
404
+ cwd: string;
405
+ paths: Record<string, {
406
+ type: "file" | "directory";
301
407
  path: string;
302
- message: string;
303
- type: "missing" | "invalid-type" | "custom";
304
- }>;
305
- warnings: Array<{
306
- path: string;
307
- message: string;
408
+ children?: Record<string, ...>;
308
409
  }>;
309
410
  }
310
411
  ```
311
412
 
312
- ## 💡 Use Cases
413
+ **Throws:**
414
+ - `RegexNotSupported` - If regex patterns are used in the schema
415
+
416
+ ##### `validate(cwd: string, schema: ValidateSchema, options?: ValidateOptions): Promise<ValidateResult>`
417
+
418
+ Validates a directory structure against a schema.
419
+
420
+ **Parameters:**
421
+ - `cwd`: Current working directory (base path)
422
+ - `schema`: Validation schema definition
423
+ - `options`: Optional validation options
313
424
 
314
- ### 1. Project Templates
315
- Ensure scaffolded projects follow the correct structure:
425
+ **Options:**
426
+ - `ignore: string[]` - Array of file/directory names to ignore during validation
316
427
 
428
+ **Returns:**
317
429
  ```typescript
318
- import { DirectoryLint } from "directory-lint";
319
- import { react } from "directory-lint/presets";
320
-
321
- async function createProject(name: string) {
322
- const linter = new DirectoryLint();
323
- const schema = react({ withTypeScript: true, withRedux: true });
324
-
325
- await linter.generate(`./${name}`, schema);
326
- console.log(`✅ Created ${name}`);
430
+ interface ValidateResult {
431
+ cwd: string;
432
+ paths: Record<string, {
433
+ type: "file" | "directory";
434
+ name: string;
435
+ path: string;
436
+ children?: Record<string, ...>;
437
+ }>;
327
438
  }
328
439
  ```
329
440
 
330
- ### 2. CI/CD Validation
331
- Verify repository structure in build pipelines:
441
+ **Throws:**
442
+ - `InvalidStructure` - If required items are missing or have incorrect types
443
+ - `InvalidContent` - If file content fails custom validation
332
444
 
333
- ```typescript
334
- // validate-structure.ts
335
- import { DirectoryLint } from "directory-lint";
336
- import { nextjs } from "directory-lint/presets";
337
-
338
- const linter = new DirectoryLint();
339
- const schema = nextjs({ appRouter: true, withTypeScript: true });
445
+ ### Backend Interface
340
446
 
341
- const result = await linter.validate(".", schema, {
342
- ignore: ["node_modules", "dist", ".next"]
343
- });
447
+ ```typescript
448
+ interface LintBackend {
449
+ getAllItems(path: string): LintItem[];
450
+ writeFile(path: string, content: any): void;
451
+ readFile(path: string): any;
452
+ makeDirectory(path: string, recursive?: boolean): void;
453
+ exists(path: string): boolean;
454
+ }
344
455
 
345
- if (!result.valid) {
346
- console.error("Structure validation failed!");
347
- console.error(result.errors);
348
- process.exit(1);
456
+ interface LintItem {
457
+ name: string;
458
+ type: "file" | "directory";
349
459
  }
350
460
  ```
351
461
 
352
- ### 3. Monorepo Validation
353
- Ensure consistent structure across packages:
462
+ ## 🚨 Error Handling
354
463
 
355
- ```typescript
356
- import { DirectoryLint, type LintSchema } from "directory-lint";
357
- import { monorepo, nextjs, nestjs } from "directory-lint/presets";
464
+ Directory Lint throws specific errors for different failure scenarios:
358
465
 
359
- const schema: LintSchema = {
360
- ...monorepo({ withTurborepo: true, packageManager: "pnpm" }),
361
- "apps": {
362
- type: "dir",
363
- required: true,
364
- children: {
365
- "web": {
366
- type: "dir",
367
- children: nextjs({ appRouter: true })
368
- },
369
- "api": {
370
- type: "dir",
371
- children: nestjs({ withPrisma: true })
372
- }
373
- }
466
+ ```typescript
467
+ import { InvalidStructure, InvalidContent, RegexNotSupported } from "directory-lint";
468
+
469
+ try {
470
+ await linter.validate("./project", schema, { ignore: [] });
471
+ } catch (error) {
472
+ if (error instanceof InvalidStructure) {
473
+ console.error("Structure error:", error.message);
474
+ } else if (error instanceof InvalidContent) {
475
+ console.error("Content validation failed:", error.message);
476
+ } else if (error instanceof RegexNotSupported) {
477
+ console.error("Regex not allowed in generate schema:", error.message);
374
478
  }
375
- };
376
-
377
- const linter = new DirectoryLint();
378
- await linter.validate(".", schema);
479
+ }
379
480
  ```
380
481
 
381
- ## 🔌 Custom Backend
482
+ ## 🔍 Pattern Matching Details
382
483
 
383
- Create custom backends for different environments:
484
+ ### Wildcard Patterns
384
485
 
385
- ```typescript
386
- import { LintBackend, LintItem } from "directory-lint";
486
+ Use `*` to match any sequence of characters:
387
487
 
388
- const S3Backend: LintBackend = {
389
- getAllItems(path: string): LintItem[] {
390
- // Your S3 implementation
391
- return [];
392
- },
488
+ ```typescript
489
+ {
490
+ "*.ts": { type: "file" }, // Matches: file.ts, index.ts, etc.
491
+ "test-*": { type: "directory" } // Matches: test-unit, test-e2e, etc.
492
+ }
493
+ ```
393
494
 
394
- writeFile(path: string, content: string): void {
395
- // Your S3 implementation
396
- },
495
+ ### Regex Patterns
397
496
 
398
- makeDirectory(path: string, recursive?: boolean): void {
399
- // Your S3 implementation
400
- },
497
+ Use `/pattern/` syntax for complex matching:
401
498
 
402
- exists(path: string): boolean {
403
- // Your S3 implementation
404
- return false;
499
+ ```typescript
500
+ {
501
+ "/^[a-z]+\\.config\\.(js|ts)$/": {
502
+ type: "file"
405
503
  }
406
- };
407
-
408
- const linter = new DirectoryLint(S3Backend);
504
+ }
505
+ // Matches: vite.config.js, jest.config.ts, etc.
409
506
  ```
410
507
 
411
- ## 📖 API Reference
508
+ ### Exact Match
412
509
 
413
- ### `DirectoryLint`
510
+ Simple string keys match exactly:
414
511
 
415
- #### Constructor
416
512
  ```typescript
417
- constructor(backend?: LintBackend)
513
+ {
514
+ "package.json": { type: "file" },
515
+ "src": { type: "directory" }
516
+ }
418
517
  ```
419
518
 
420
- #### Methods
421
-
422
- ##### `validate(path: string, schema: LintSchema, options?: ValidateOptions): Promise<ValidationResult>`
423
- Validates a directory structure against a schema.
424
-
425
- **Options:**
426
- - `ignore`: Array of patterns to ignore
427
-
428
- **Returns:** Validation result with errors and warnings
429
-
430
- ##### `generate(path: string, schema: LintSchema, options?: GenerateOptions): Promise<GenerationResult>`
431
- Generates a directory structure based on a schema.
519
+ ## 🤝 Contributing
432
520
 
433
- **Options:**
434
- - `overwrite`: Overwrite existing files (default: false)
435
- - `recursive`: Create parent directories (default: false)
521
+ Contributions are welcome! Please feel free to submit a Pull Request.
436
522
 
437
- **Returns:** Generation result with warnings
523
+ ### Development Setup
438
524
 
439
- ## 🤝 Contributing
525
+ ```bash
526
+ # Clone the repository
527
+ git clone https://github.com/yourusername/directory-lint.git
440
528
 
441
- Contributions are welcome! Please feel free to submit a Pull Request.
529
+ # Install dependencies
530
+ npm install
442
531
 
443
- ### Adding a New Preset
532
+ # Build the project
533
+ npm run build
444
534
 
445
- 1. Create a new file in `src/presets/`
446
- 2. Export a function that returns a `LintSchema`
447
- 3. Add the export to `src/presets/index.ts`
448
- 4. Update the presets README
535
+ # Run examples
536
+ npm run example:generate
537
+ npm run example:validate
538
+ ```
449
539
 
450
540
  ## 📝 License
451
541
 
@@ -454,7 +544,3 @@ MIT © Henry Vilani
454
544
  ## 🙏 Acknowledgments
455
545
 
456
546
  Built with ❤️ for the developer community.
457
-
458
- ---
459
-
460
- **Keywords:** linter,validation, filesystem, directorystructure, architecture, lint