klasik 2.3.0 → 2.4.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/dist/bin/go-schema-gen +0 -0
- package/package.json +7 -4
- package/demo-output/models/index.ts +0 -2
- package/demo-output/models/owner.ts +0 -74
- package/demo-output/models/pet.ts +0 -107
- package/demo-output/package.json +0 -14
- package/demo-output/tsconfig.json +0 -26
- package/dist/__tests__/test-helpers/cleanup-utils.d.ts +0 -64
- package/dist/__tests__/test-helpers/cleanup-utils.d.ts.map +0 -1
- package/dist/__tests__/test-helpers/cleanup-utils.js +0 -236
- package/dist/__tests__/test-helpers/cleanup-utils.js.map +0 -1
- package/docs/ARCHITECTURE.md +0 -845
- package/docs/JSDOC_ESCAPING.md +0 -280
- package/docs/json-schema-support.md +0 -353
- package/docs/validation.md +0 -350
- package/tools/go-schema-gen/go-schema-gen +0 -0
package/dist/bin/go-schema-gen
CHANGED
|
Binary file
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "klasik",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.4.0",
|
|
4
4
|
"description": "TypeScript code generator from OpenAPI/CRD/JSON Schema/Go structs - rebuilt from ground up with AST-based generation",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"types": "dist/index.d.ts",
|
|
@@ -9,10 +9,13 @@
|
|
|
9
9
|
},
|
|
10
10
|
"files": [
|
|
11
11
|
"dist/",
|
|
12
|
+
"!dist/__tests__/",
|
|
12
13
|
"templates/",
|
|
13
|
-
"tools/go-schema-gen
|
|
14
|
-
"
|
|
15
|
-
"
|
|
14
|
+
"tools/go-schema-gen/*.go",
|
|
15
|
+
"tools/go-schema-gen/*.sh",
|
|
16
|
+
"tools/go-schema-gen/*.md",
|
|
17
|
+
"tools/go-schema-gen/go.mod",
|
|
18
|
+
"tools/go-schema-gen/go.sum",
|
|
16
19
|
"README.md"
|
|
17
20
|
],
|
|
18
21
|
"scripts": {
|
|
@@ -1,74 +0,0 @@
|
|
|
1
|
-
import { ApiProperty } from "@nestjs/swagger";
|
|
2
|
-
import { Expose } from "class-transformer";
|
|
3
|
-
import { IsEmail, IsOptional, IsString, IsUUID, Matches, MinLength } from "class-validator";
|
|
4
|
-
|
|
5
|
-
/** Pet owner information */
|
|
6
|
-
export class Owner {
|
|
7
|
-
@Expose()
|
|
8
|
-
@ApiProperty({
|
|
9
|
-
type: String,
|
|
10
|
-
required: true,
|
|
11
|
-
format: `uuid`
|
|
12
|
-
})
|
|
13
|
-
@IsString()
|
|
14
|
-
@IsUUID()
|
|
15
|
-
'id': string;
|
|
16
|
-
@Expose()
|
|
17
|
-
@ApiProperty({
|
|
18
|
-
type: String,
|
|
19
|
-
required: true,
|
|
20
|
-
minLength: 1
|
|
21
|
-
})
|
|
22
|
-
@IsString()
|
|
23
|
-
@MinLength(1)
|
|
24
|
-
'name': string;
|
|
25
|
-
@Expose()
|
|
26
|
-
@ApiProperty({
|
|
27
|
-
type: String,
|
|
28
|
-
required: true,
|
|
29
|
-
format: `email`
|
|
30
|
-
})
|
|
31
|
-
@IsString()
|
|
32
|
-
@IsEmail()
|
|
33
|
-
'email': string;
|
|
34
|
-
@Expose()
|
|
35
|
-
@ApiProperty({
|
|
36
|
-
type: String,
|
|
37
|
-
required: false,
|
|
38
|
-
pattern: `^\+?[1-9]\d{1,14}$`
|
|
39
|
-
})
|
|
40
|
-
@IsOptional()
|
|
41
|
-
@IsString()
|
|
42
|
-
@Matches(/^\\+?[1-9]\\d{1,14}$/)
|
|
43
|
-
'phone'?: string;
|
|
44
|
-
public static readonly attributeTypeMap: Array<{ name: string, baseName: string, type: string, format: string, description?: string, vendorExtensions?: any, modelClass?: any }> = [
|
|
45
|
-
{
|
|
46
|
-
"name": "id",
|
|
47
|
-
"baseName": "id",
|
|
48
|
-
"type": "string",
|
|
49
|
-
"format": "uuid",
|
|
50
|
-
"vendorExtensions": {}
|
|
51
|
-
},
|
|
52
|
-
{
|
|
53
|
-
"name": "name",
|
|
54
|
-
"baseName": "name",
|
|
55
|
-
"type": "string",
|
|
56
|
-
"format": "",
|
|
57
|
-
"vendorExtensions": {}
|
|
58
|
-
},
|
|
59
|
-
{
|
|
60
|
-
"name": "email",
|
|
61
|
-
"baseName": "email",
|
|
62
|
-
"type": "string",
|
|
63
|
-
"format": "email",
|
|
64
|
-
"vendorExtensions": {}
|
|
65
|
-
},
|
|
66
|
-
{
|
|
67
|
-
"name": "phone",
|
|
68
|
-
"baseName": "phone",
|
|
69
|
-
"type": "string",
|
|
70
|
-
"format": "",
|
|
71
|
-
"vendorExtensions": {}
|
|
72
|
-
}
|
|
73
|
-
];
|
|
74
|
-
}
|
|
@@ -1,107 +0,0 @@
|
|
|
1
|
-
import { ApiProperty } from "@nestjs/swagger";
|
|
2
|
-
import { Expose, Type } from "class-transformer";
|
|
3
|
-
import { IsNumber, IsOptional, IsString, IsUUID, Max, MaxLength, Min, MinLength, ValidateNested } from "class-validator";
|
|
4
|
-
import { Owner } from "./owner.js";
|
|
5
|
-
|
|
6
|
-
/** A pet in the store */
|
|
7
|
-
export class Pet {
|
|
8
|
-
/** Pet ID */
|
|
9
|
-
@Expose()
|
|
10
|
-
@ApiProperty({
|
|
11
|
-
type: String,
|
|
12
|
-
description: `Pet ID`,
|
|
13
|
-
required: true,
|
|
14
|
-
format: `uuid`
|
|
15
|
-
})
|
|
16
|
-
@IsString()
|
|
17
|
-
@IsUUID()
|
|
18
|
-
'id': string;
|
|
19
|
-
/** Pet name */
|
|
20
|
-
@Expose()
|
|
21
|
-
@ApiProperty({
|
|
22
|
-
type: String,
|
|
23
|
-
description: `Pet name`,
|
|
24
|
-
required: true,
|
|
25
|
-
minLength: 1,
|
|
26
|
-
maxLength: 50
|
|
27
|
-
})
|
|
28
|
-
@IsString()
|
|
29
|
-
@MinLength(1)
|
|
30
|
-
@MaxLength(50)
|
|
31
|
-
'name': string;
|
|
32
|
-
/** Type of animal */
|
|
33
|
-
@Expose()
|
|
34
|
-
@ApiProperty({
|
|
35
|
-
type: String,
|
|
36
|
-
description: `Type of animal`,
|
|
37
|
-
required: true,
|
|
38
|
-
enum: ["dog", "cat", "bird", "fish"]
|
|
39
|
-
})
|
|
40
|
-
@IsString()
|
|
41
|
-
'species': string;
|
|
42
|
-
/** Pet age in years */
|
|
43
|
-
@Expose()
|
|
44
|
-
@ApiProperty({
|
|
45
|
-
type: Number,
|
|
46
|
-
description: `Pet age in years`,
|
|
47
|
-
required: false,
|
|
48
|
-
minimum: 0,
|
|
49
|
-
maximum: 30
|
|
50
|
-
})
|
|
51
|
-
@IsOptional()
|
|
52
|
-
@IsNumber()
|
|
53
|
-
@Min(0)
|
|
54
|
-
@Max(30)
|
|
55
|
-
'age'?: number;
|
|
56
|
-
@Expose()
|
|
57
|
-
@Type(() => Owner)
|
|
58
|
-
@ApiProperty({
|
|
59
|
-
type: () => Owner,
|
|
60
|
-
required: false
|
|
61
|
-
})
|
|
62
|
-
@IsOptional()
|
|
63
|
-
@ValidateNested()
|
|
64
|
-
'owner'?: Owner;
|
|
65
|
-
public static readonly attributeTypeMap: Array<{ name: string, baseName: string, type: string, format: string, description?: string, vendorExtensions?: any, modelClass?: any }> = [
|
|
66
|
-
{
|
|
67
|
-
"name": "id",
|
|
68
|
-
"baseName": "id",
|
|
69
|
-
"type": "string",
|
|
70
|
-
"format": "uuid",
|
|
71
|
-
"description": "Pet ID",
|
|
72
|
-
"vendorExtensions": {}
|
|
73
|
-
},
|
|
74
|
-
{
|
|
75
|
-
"name": "name",
|
|
76
|
-
"baseName": "name",
|
|
77
|
-
"type": "string",
|
|
78
|
-
"format": "",
|
|
79
|
-
"description": "Pet name",
|
|
80
|
-
"vendorExtensions": {}
|
|
81
|
-
},
|
|
82
|
-
{
|
|
83
|
-
"name": "species",
|
|
84
|
-
"baseName": "species",
|
|
85
|
-
"type": "string",
|
|
86
|
-
"format": "",
|
|
87
|
-
"description": "Type of animal",
|
|
88
|
-
"vendorExtensions": {}
|
|
89
|
-
},
|
|
90
|
-
{
|
|
91
|
-
"name": "age",
|
|
92
|
-
"baseName": "age",
|
|
93
|
-
"type": "number",
|
|
94
|
-
"format": "",
|
|
95
|
-
"description": "Pet age in years",
|
|
96
|
-
"vendorExtensions": {}
|
|
97
|
-
},
|
|
98
|
-
{
|
|
99
|
-
"name": "owner",
|
|
100
|
-
"baseName": "owner",
|
|
101
|
-
"type": "Owner",
|
|
102
|
-
"format": "",
|
|
103
|
-
"vendorExtensions": {},
|
|
104
|
-
"modelClass": "Owner"
|
|
105
|
-
}
|
|
106
|
-
];
|
|
107
|
-
}
|
package/demo-output/package.json
DELETED
|
@@ -1,14 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"name": "generated-models",
|
|
3
|
-
"version": "1.0.0",
|
|
4
|
-
"description": "Generated TypeScript models",
|
|
5
|
-
"main": "models/index.js",
|
|
6
|
-
"types": "models/index.d.ts",
|
|
7
|
-
"type": "module",
|
|
8
|
-
"dependencies": {
|
|
9
|
-
"class-transformer": "^0.5.1",
|
|
10
|
-
"reflect-metadata": "^0.2.2",
|
|
11
|
-
"@nestjs/swagger": "^7.0.0",
|
|
12
|
-
"class-validator": "^0.14.0"
|
|
13
|
-
}
|
|
14
|
-
}
|
|
@@ -1,26 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"compilerOptions": {
|
|
3
|
-
"target": "ES2020",
|
|
4
|
-
"module": "ESNext",
|
|
5
|
-
"lib": [
|
|
6
|
-
"ES2020"
|
|
7
|
-
],
|
|
8
|
-
"declaration": true,
|
|
9
|
-
"outDir": "./dist",
|
|
10
|
-
"strict": true,
|
|
11
|
-
"esModuleInterop": true,
|
|
12
|
-
"skipLibCheck": true,
|
|
13
|
-
"forceConsistentCasingInFileNames": true,
|
|
14
|
-
"experimentalDecorators": true,
|
|
15
|
-
"emitDecoratorMetadata": true,
|
|
16
|
-
"resolveJsonModule": true,
|
|
17
|
-
"moduleResolution": "node"
|
|
18
|
-
},
|
|
19
|
-
"include": [
|
|
20
|
-
"models/**/*"
|
|
21
|
-
],
|
|
22
|
-
"exclude": [
|
|
23
|
-
"node_modules",
|
|
24
|
-
"dist"
|
|
25
|
-
]
|
|
26
|
-
}
|
|
@@ -1,64 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Robust directory cleanup utilities for tests
|
|
3
|
-
*
|
|
4
|
-
* Handles edge cases like:
|
|
5
|
-
* - macOS Spotlight indexing (mdworker processes)
|
|
6
|
-
* - Files locked by other processes
|
|
7
|
-
* - Race conditions during cleanup
|
|
8
|
-
* - Nested directory structures
|
|
9
|
-
*/
|
|
10
|
-
export interface CleanupOptions {
|
|
11
|
-
/**
|
|
12
|
-
* Maximum number of retry attempts
|
|
13
|
-
* @default 3
|
|
14
|
-
*/
|
|
15
|
-
maxRetries?: number;
|
|
16
|
-
/**
|
|
17
|
-
* Delay in milliseconds between retries
|
|
18
|
-
* @default 100
|
|
19
|
-
*/
|
|
20
|
-
retryDelayMs?: number;
|
|
21
|
-
/**
|
|
22
|
-
* Use system rm -rf as fallback on Unix-like systems
|
|
23
|
-
* @default true
|
|
24
|
-
*/
|
|
25
|
-
useFallbackRm?: boolean;
|
|
26
|
-
/**
|
|
27
|
-
* Suppress cleanup warnings and errors
|
|
28
|
-
* @default false
|
|
29
|
-
*/
|
|
30
|
-
silent?: boolean;
|
|
31
|
-
}
|
|
32
|
-
/**
|
|
33
|
-
* Robustly remove a directory with retry logic and multiple strategies
|
|
34
|
-
*
|
|
35
|
-
* @param dirPath - Path to the directory to remove
|
|
36
|
-
* @param options - Cleanup options
|
|
37
|
-
* @returns true if successful, false otherwise
|
|
38
|
-
*/
|
|
39
|
-
export declare function robustRemoveDir(dirPath: string, options?: CleanupOptions): Promise<boolean>;
|
|
40
|
-
/**
|
|
41
|
-
* Ensure a directory exists and is clean
|
|
42
|
-
*
|
|
43
|
-
* @param dirPath - Path to the directory
|
|
44
|
-
* @param options - Cleanup options
|
|
45
|
-
*/
|
|
46
|
-
export declare function ensureCleanDirectory(dirPath: string, options?: CleanupOptions): Promise<void>;
|
|
47
|
-
/**
|
|
48
|
-
* Create a unique test directory to avoid conflicts
|
|
49
|
-
*
|
|
50
|
-
* @param baseDir - Base directory for test outputs
|
|
51
|
-
* @param testName - Name of the test
|
|
52
|
-
* @returns Path to the unique directory
|
|
53
|
-
*/
|
|
54
|
-
export declare function createUniqueTestDir(baseDir: string, testName: string): string;
|
|
55
|
-
/**
|
|
56
|
-
* Clean up test directories older than a specified age
|
|
57
|
-
* Useful for cleaning up orphaned test directories from failed runs
|
|
58
|
-
*
|
|
59
|
-
* @param baseDir - Base directory containing test outputs
|
|
60
|
-
* @param maxAgeMs - Maximum age in milliseconds (default: 1 hour)
|
|
61
|
-
* @param pattern - Pattern to match directory names (default: all)
|
|
62
|
-
*/
|
|
63
|
-
export declare function cleanupOldTestDirs(baseDir: string, maxAgeMs?: number, pattern?: RegExp): Promise<number>;
|
|
64
|
-
//# sourceMappingURL=cleanup-utils.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"cleanup-utils.d.ts","sourceRoot":"","sources":["../../../src/__tests__/test-helpers/cleanup-utils.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAMH,MAAM,WAAW,cAAc;IAC7B;;;OAGG;IACH,UAAU,CAAC,EAAE,MAAM,CAAC;IAEpB;;;OAGG;IACH,YAAY,CAAC,EAAE,MAAM,CAAC;IAEtB;;;OAGG;IACH,aAAa,CAAC,EAAE,OAAO,CAAC;IAExB;;;OAGG;IACH,MAAM,CAAC,EAAE,OAAO,CAAC;CAClB;AAiDD;;;;;;GAMG;AACH,wBAAsB,eAAe,CACnC,OAAO,EAAE,MAAM,EACf,OAAO,GAAE,cAAmB,GAC3B,OAAO,CAAC,OAAO,CAAC,CAgFlB;AAED;;;;;GAKG;AACH,wBAAsB,oBAAoB,CACxC,OAAO,EAAE,MAAM,EACf,OAAO,GAAE,cAAmB,GAC3B,OAAO,CAAC,IAAI,CAAC,CAGf;AAED;;;;;;GAMG;AACH,wBAAgB,mBAAmB,CAAC,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,MAAM,CAM7E;AAED;;;;;;;GAOG;AACH,wBAAsB,kBAAkB,CACtC,OAAO,EAAE,MAAM,EACf,QAAQ,GAAE,MAAuB,EACjC,OAAO,CAAC,EAAE,MAAM,GACf,OAAO,CAAC,MAAM,CAAC,CAoCjB"}
|
|
@@ -1,236 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
/**
|
|
3
|
-
* Robust directory cleanup utilities for tests
|
|
4
|
-
*
|
|
5
|
-
* Handles edge cases like:
|
|
6
|
-
* - macOS Spotlight indexing (mdworker processes)
|
|
7
|
-
* - Files locked by other processes
|
|
8
|
-
* - Race conditions during cleanup
|
|
9
|
-
* - Nested directory structures
|
|
10
|
-
*/
|
|
11
|
-
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
12
|
-
if (k2 === undefined) k2 = k;
|
|
13
|
-
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
14
|
-
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
15
|
-
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
16
|
-
}
|
|
17
|
-
Object.defineProperty(o, k2, desc);
|
|
18
|
-
}) : (function(o, m, k, k2) {
|
|
19
|
-
if (k2 === undefined) k2 = k;
|
|
20
|
-
o[k2] = m[k];
|
|
21
|
-
}));
|
|
22
|
-
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
23
|
-
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
24
|
-
}) : function(o, v) {
|
|
25
|
-
o["default"] = v;
|
|
26
|
-
});
|
|
27
|
-
var __importStar = (this && this.__importStar) || (function () {
|
|
28
|
-
var ownKeys = function(o) {
|
|
29
|
-
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
30
|
-
var ar = [];
|
|
31
|
-
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
32
|
-
return ar;
|
|
33
|
-
};
|
|
34
|
-
return ownKeys(o);
|
|
35
|
-
};
|
|
36
|
-
return function (mod) {
|
|
37
|
-
if (mod && mod.__esModule) return mod;
|
|
38
|
-
var result = {};
|
|
39
|
-
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
40
|
-
__setModuleDefault(result, mod);
|
|
41
|
-
return result;
|
|
42
|
-
};
|
|
43
|
-
})();
|
|
44
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
45
|
-
exports.robustRemoveDir = robustRemoveDir;
|
|
46
|
-
exports.ensureCleanDirectory = ensureCleanDirectory;
|
|
47
|
-
exports.createUniqueTestDir = createUniqueTestDir;
|
|
48
|
-
exports.cleanupOldTestDirs = cleanupOldTestDirs;
|
|
49
|
-
const fs = __importStar(require("fs"));
|
|
50
|
-
const path = __importStar(require("path"));
|
|
51
|
-
const child_process_1 = require("child_process");
|
|
52
|
-
/**
|
|
53
|
-
* Wait for a specified number of milliseconds
|
|
54
|
-
*/
|
|
55
|
-
function sleep(ms) {
|
|
56
|
-
return new Promise(resolve => setTimeout(resolve, ms));
|
|
57
|
-
}
|
|
58
|
-
/**
|
|
59
|
-
* Recursively remove all files in a directory, then remove the directory
|
|
60
|
-
* This approach is more reliable than rmSync for deeply nested structures
|
|
61
|
-
*/
|
|
62
|
-
function recursiveRemove(dirPath) {
|
|
63
|
-
if (!fs.existsSync(dirPath)) {
|
|
64
|
-
return;
|
|
65
|
-
}
|
|
66
|
-
const entries = fs.readdirSync(dirPath, { withFileTypes: true });
|
|
67
|
-
for (const entry of entries) {
|
|
68
|
-
const fullPath = path.join(dirPath, entry.name);
|
|
69
|
-
if (entry.isDirectory()) {
|
|
70
|
-
recursiveRemove(fullPath);
|
|
71
|
-
}
|
|
72
|
-
else {
|
|
73
|
-
try {
|
|
74
|
-
fs.unlinkSync(fullPath);
|
|
75
|
-
}
|
|
76
|
-
catch (error) {
|
|
77
|
-
// If we can't delete a file, try to make it writable first
|
|
78
|
-
try {
|
|
79
|
-
fs.chmodSync(fullPath, 0o666);
|
|
80
|
-
fs.unlinkSync(fullPath);
|
|
81
|
-
}
|
|
82
|
-
catch {
|
|
83
|
-
// Ignore - we'll catch this in the parent call
|
|
84
|
-
}
|
|
85
|
-
}
|
|
86
|
-
}
|
|
87
|
-
}
|
|
88
|
-
// Now remove the empty directory
|
|
89
|
-
try {
|
|
90
|
-
fs.rmdirSync(dirPath);
|
|
91
|
-
}
|
|
92
|
-
catch (error) {
|
|
93
|
-
// Directory might not be empty due to race conditions
|
|
94
|
-
// This will be caught by the retry logic
|
|
95
|
-
}
|
|
96
|
-
}
|
|
97
|
-
/**
|
|
98
|
-
* Robustly remove a directory with retry logic and multiple strategies
|
|
99
|
-
*
|
|
100
|
-
* @param dirPath - Path to the directory to remove
|
|
101
|
-
* @param options - Cleanup options
|
|
102
|
-
* @returns true if successful, false otherwise
|
|
103
|
-
*/
|
|
104
|
-
async function robustRemoveDir(dirPath, options = {}) {
|
|
105
|
-
const { maxRetries = 3, retryDelayMs = 100, useFallbackRm = true, silent = false, } = options;
|
|
106
|
-
if (!fs.existsSync(dirPath)) {
|
|
107
|
-
return true;
|
|
108
|
-
}
|
|
109
|
-
// Strategy 1: Try fs.rmSync with maxRetries option (Node 14.14+)
|
|
110
|
-
for (let attempt = 0; attempt < maxRetries; attempt++) {
|
|
111
|
-
try {
|
|
112
|
-
fs.rmSync(dirPath, {
|
|
113
|
-
recursive: true,
|
|
114
|
-
force: true,
|
|
115
|
-
maxRetries: 3,
|
|
116
|
-
retryDelay: 100,
|
|
117
|
-
});
|
|
118
|
-
return true;
|
|
119
|
-
}
|
|
120
|
-
catch (error) {
|
|
121
|
-
if (!silent && attempt === 0) {
|
|
122
|
-
console.log(`⚠️ Initial cleanup attempt failed: ${error.code || error.message}`);
|
|
123
|
-
}
|
|
124
|
-
if (attempt < maxRetries - 1) {
|
|
125
|
-
await sleep(retryDelayMs * (attempt + 1)); // Exponential backoff
|
|
126
|
-
}
|
|
127
|
-
}
|
|
128
|
-
}
|
|
129
|
-
// Strategy 2: Try manual recursive deletion
|
|
130
|
-
if (!silent) {
|
|
131
|
-
console.log('📁 Trying manual recursive deletion...');
|
|
132
|
-
}
|
|
133
|
-
try {
|
|
134
|
-
recursiveRemove(dirPath);
|
|
135
|
-
if (!fs.existsSync(dirPath)) {
|
|
136
|
-
return true;
|
|
137
|
-
}
|
|
138
|
-
}
|
|
139
|
-
catch (error) {
|
|
140
|
-
if (!silent) {
|
|
141
|
-
console.log(`⚠️ Manual recursive deletion failed: ${error.code || error.message}`);
|
|
142
|
-
}
|
|
143
|
-
}
|
|
144
|
-
// Strategy 3: Use system rm -rf on Unix-like systems
|
|
145
|
-
if (useFallbackRm && (process.platform === 'darwin' || process.platform === 'linux')) {
|
|
146
|
-
if (!silent) {
|
|
147
|
-
console.log('🔧 Using system rm -rf as fallback...');
|
|
148
|
-
}
|
|
149
|
-
try {
|
|
150
|
-
(0, child_process_1.execSync)(`rm -rf "${dirPath}"`, { stdio: 'pipe' });
|
|
151
|
-
// Verify it's gone
|
|
152
|
-
await sleep(50); // Brief wait for filesystem sync
|
|
153
|
-
if (!fs.existsSync(dirPath)) {
|
|
154
|
-
if (!silent) {
|
|
155
|
-
console.log('✅ Fallback cleanup succeeded');
|
|
156
|
-
}
|
|
157
|
-
return true;
|
|
158
|
-
}
|
|
159
|
-
}
|
|
160
|
-
catch (error) {
|
|
161
|
-
if (!silent) {
|
|
162
|
-
console.log(`⚠️ Fallback rm -rf failed: ${error.message}`);
|
|
163
|
-
}
|
|
164
|
-
}
|
|
165
|
-
}
|
|
166
|
-
// If we get here, cleanup failed
|
|
167
|
-
if (!silent) {
|
|
168
|
-
console.warn(`❌ Failed to clean up directory: ${dirPath}`);
|
|
169
|
-
console.warn(' This may cause test failures. Consider running: rm -rf test-output');
|
|
170
|
-
}
|
|
171
|
-
return false;
|
|
172
|
-
}
|
|
173
|
-
/**
|
|
174
|
-
* Ensure a directory exists and is clean
|
|
175
|
-
*
|
|
176
|
-
* @param dirPath - Path to the directory
|
|
177
|
-
* @param options - Cleanup options
|
|
178
|
-
*/
|
|
179
|
-
async function ensureCleanDirectory(dirPath, options = {}) {
|
|
180
|
-
await robustRemoveDir(dirPath, options);
|
|
181
|
-
fs.mkdirSync(dirPath, { recursive: true });
|
|
182
|
-
}
|
|
183
|
-
/**
|
|
184
|
-
* Create a unique test directory to avoid conflicts
|
|
185
|
-
*
|
|
186
|
-
* @param baseDir - Base directory for test outputs
|
|
187
|
-
* @param testName - Name of the test
|
|
188
|
-
* @returns Path to the unique directory
|
|
189
|
-
*/
|
|
190
|
-
function createUniqueTestDir(baseDir, testName) {
|
|
191
|
-
const timestamp = Date.now();
|
|
192
|
-
const random = Math.random().toString(36).substring(7);
|
|
193
|
-
const uniqueDir = path.join(baseDir, `${testName}-${timestamp}-${random}`);
|
|
194
|
-
fs.mkdirSync(uniqueDir, { recursive: true });
|
|
195
|
-
return uniqueDir;
|
|
196
|
-
}
|
|
197
|
-
/**
|
|
198
|
-
* Clean up test directories older than a specified age
|
|
199
|
-
* Useful for cleaning up orphaned test directories from failed runs
|
|
200
|
-
*
|
|
201
|
-
* @param baseDir - Base directory containing test outputs
|
|
202
|
-
* @param maxAgeMs - Maximum age in milliseconds (default: 1 hour)
|
|
203
|
-
* @param pattern - Pattern to match directory names (default: all)
|
|
204
|
-
*/
|
|
205
|
-
async function cleanupOldTestDirs(baseDir, maxAgeMs = 60 * 60 * 1000, pattern) {
|
|
206
|
-
if (!fs.existsSync(baseDir)) {
|
|
207
|
-
return 0;
|
|
208
|
-
}
|
|
209
|
-
let cleaned = 0;
|
|
210
|
-
const now = Date.now();
|
|
211
|
-
const entries = fs.readdirSync(baseDir, { withFileTypes: true });
|
|
212
|
-
for (const entry of entries) {
|
|
213
|
-
if (!entry.isDirectory()) {
|
|
214
|
-
continue;
|
|
215
|
-
}
|
|
216
|
-
if (pattern && !pattern.test(entry.name)) {
|
|
217
|
-
continue;
|
|
218
|
-
}
|
|
219
|
-
const dirPath = path.join(baseDir, entry.name);
|
|
220
|
-
try {
|
|
221
|
-
const stats = fs.statSync(dirPath);
|
|
222
|
-
const age = now - stats.mtimeMs;
|
|
223
|
-
if (age > maxAgeMs) {
|
|
224
|
-
const success = await robustRemoveDir(dirPath, { silent: true });
|
|
225
|
-
if (success) {
|
|
226
|
-
cleaned++;
|
|
227
|
-
}
|
|
228
|
-
}
|
|
229
|
-
}
|
|
230
|
-
catch {
|
|
231
|
-
// Ignore errors for individual directories
|
|
232
|
-
}
|
|
233
|
-
}
|
|
234
|
-
return cleaned;
|
|
235
|
-
}
|
|
236
|
-
//# sourceMappingURL=cleanup-utils.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"cleanup-utils.js","sourceRoot":"","sources":["../../../src/__tests__/test-helpers/cleanup-utils.ts"],"names":[],"mappings":"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"}
|