msfs-layout-generator 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.
- package/LICENSE +674 -0
- package/dist/cli.d.ts +2 -0
- package/dist/cli.js +218 -0
- package/dist/constants/constants.d.ts +1 -0
- package/dist/constants/constants.js +8 -0
- package/dist/errors/ManifestWritingError.d.ts +3 -0
- package/dist/errors/ManifestWritingError.js +10 -0
- package/dist/errors/ReadingDirError.d.ts +3 -0
- package/dist/errors/ReadingDirError.js +10 -0
- package/dist/errors/ReadingJsonError.d.ts +3 -0
- package/dist/errors/ReadingJsonError.js +10 -0
- package/dist/errors/index.d.ts +4 -0
- package/dist/errors/index.js +9 -0
- package/dist/index.d.ts +26 -0
- package/dist/index.js +30 -0
- package/dist/types/cli.d.ts +2 -0
- package/dist/types/constants/constants.d.ts +1 -0
- package/dist/types/errors/ManifestWritingError.d.ts +3 -0
- package/dist/types/errors/ReadingDirError.d.ts +3 -0
- package/dist/types/errors/ReadingJsonError.d.ts +3 -0
- package/dist/types/errors/index.d.ts +4 -0
- package/dist/types/index.d.ts +26 -0
- package/dist/types/utils/doExcludeFile.d.ts +1 -0
- package/dist/types/utils/doProcessLayoutFile.d.ts +1 -0
- package/dist/types/utils/doProcessLayoutFileCli.d.ts +17 -0
- package/dist/types/utils/doUpdateManifest.d.ts +1 -0
- package/dist/types/utils/getAllFiles.d.ts +1 -0
- package/dist/types/utils/getWindowsFileTime.d.ts +1 -0
- package/dist/types/utils/readJson.d.ts +1 -0
- package/dist/utils/doExcludeFile.d.ts +1 -0
- package/dist/utils/doExcludeFile.js +46 -0
- package/dist/utils/doProcessLayoutFile.d.ts +1 -0
- package/dist/utils/doProcessLayoutFile.js +109 -0
- package/dist/utils/doProcessLayoutFileCli.js +220 -0
- package/dist/utils/doUpdateManifest.d.ts +1 -0
- package/dist/utils/doUpdateManifest.js +23 -0
- package/dist/utils/getAllFiles.d.ts +1 -0
- package/dist/utils/getAllFiles.js +65 -0
- package/dist/utils/getWindowsFileTime.d.ts +1 -0
- package/dist/utils/getWindowsFileTime.js +11 -0
- package/dist/utils/readJson.d.ts +1 -0
- package/dist/utils/readJson.js +17 -0
- package/package.json +43 -0
package/dist/cli.js
ADDED
|
@@ -0,0 +1,218 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
"use strict";
|
|
3
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
4
|
+
if (k2 === undefined) k2 = k;
|
|
5
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
6
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
7
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
8
|
+
}
|
|
9
|
+
Object.defineProperty(o, k2, desc);
|
|
10
|
+
}) : (function(o, m, k, k2) {
|
|
11
|
+
if (k2 === undefined) k2 = k;
|
|
12
|
+
o[k2] = m[k];
|
|
13
|
+
}));
|
|
14
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
15
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
16
|
+
}) : function(o, v) {
|
|
17
|
+
o["default"] = v;
|
|
18
|
+
});
|
|
19
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
20
|
+
var ownKeys = function(o) {
|
|
21
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
22
|
+
var ar = [];
|
|
23
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
24
|
+
return ar;
|
|
25
|
+
};
|
|
26
|
+
return ownKeys(o);
|
|
27
|
+
};
|
|
28
|
+
return function (mod) {
|
|
29
|
+
if (mod && mod.__esModule) return mod;
|
|
30
|
+
var result = {};
|
|
31
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
32
|
+
__setModuleDefault(result, mod);
|
|
33
|
+
return result;
|
|
34
|
+
};
|
|
35
|
+
})();
|
|
36
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
37
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
38
|
+
};
|
|
39
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
40
|
+
const commander_1 = require("commander");
|
|
41
|
+
const chalk_1 = __importDefault(require("chalk"));
|
|
42
|
+
const path = __importStar(require("path"));
|
|
43
|
+
const doProcessLayoutFileCli_1 = require("./utils/doProcessLayoutFileCli");
|
|
44
|
+
// Define the program
|
|
45
|
+
const program = new commander_1.Command();
|
|
46
|
+
// Helper function for consistent logging
|
|
47
|
+
const logger = {
|
|
48
|
+
info: (message) => console.log(chalk_1.default.blue('ℹ'), message),
|
|
49
|
+
success: (message) => console.log(chalk_1.default.green('✓'), message),
|
|
50
|
+
error: (message) => console.log(chalk_1.default.red('✗'), message),
|
|
51
|
+
header: (message) => console.log(chalk_1.default.bold.cyan(message)),
|
|
52
|
+
dim: (message) => console.log(chalk_1.default.dim(message))
|
|
53
|
+
};
|
|
54
|
+
/**
|
|
55
|
+
* MSFS Layout Generator CLI Tool
|
|
56
|
+
*
|
|
57
|
+
* Generates or updates layout.json for MSFS community packages.
|
|
58
|
+
*
|
|
59
|
+
* @example
|
|
60
|
+
* // Generate layout.json for a package
|
|
61
|
+
* msfs-layout "F:\\fs20\\Community\\my-package"
|
|
62
|
+
*
|
|
63
|
+
* @example
|
|
64
|
+
* // Generate for multiple packages
|
|
65
|
+
* msfs-layout "package1" "package2" "package3"
|
|
66
|
+
*
|
|
67
|
+
* @example
|
|
68
|
+
* // Show help
|
|
69
|
+
* msfs-layout --help
|
|
70
|
+
*/
|
|
71
|
+
// Configure the CLI program
|
|
72
|
+
program
|
|
73
|
+
.name('msfs-layout')
|
|
74
|
+
.description(chalk_1.default.bold('Generate or update layout.json for MSFS community packages'))
|
|
75
|
+
.argument('[directories...]', 'Path to MSFS package directory(ies) containing manifest.json')
|
|
76
|
+
.option('-f, --force', 'Force overwrite existing layout.json without confirmation')
|
|
77
|
+
.option('-q, --quiet', 'Suppress non-essential output')
|
|
78
|
+
.option('-d, --debug', 'Enable debug logging for troubleshooting')
|
|
79
|
+
.option('--no-manifest-check', 'Skip manifest.json existence check')
|
|
80
|
+
.action(async (directories, options) => {
|
|
81
|
+
await handleAction(directories, options);
|
|
82
|
+
})
|
|
83
|
+
.addHelpText('after', `
|
|
84
|
+
${chalk_1.default.bold('Examples:')}
|
|
85
|
+
${chalk_1.default.dim('# Process a single package')}
|
|
86
|
+
msfs-layout "F:\\fs20\\Community\\fnx-aircraft_CFM_DAEWPUG_B2"
|
|
87
|
+
|
|
88
|
+
${chalk_1.default.dim('# Process multiple packages')}
|
|
89
|
+
msfs-layout "package1" "package2" "package3"
|
|
90
|
+
|
|
91
|
+
${chalk_1.default.dim('# Process current directory')}
|
|
92
|
+
msfs-layout .
|
|
93
|
+
|
|
94
|
+
${chalk_1.default.dim('# Force overwrite existing layout.json')}
|
|
95
|
+
msfs-layout ./my-package --force
|
|
96
|
+
|
|
97
|
+
${chalk_1.default.dim('# Quiet mode - minimal output')}
|
|
98
|
+
msfs-layout ./my-package --quiet
|
|
99
|
+
|
|
100
|
+
${chalk_1.default.bold('Notes:')}
|
|
101
|
+
• Each directory should contain a ${chalk_1.default.cyan('manifest.json')} file
|
|
102
|
+
• Creates/updates ${chalk_1.default.cyan('layout.json')} in the same directory
|
|
103
|
+
• Automatically excludes ${chalk_1.default.yellow('_CVT_')} directories
|
|
104
|
+
• Updates ${chalk_1.default.cyan('total_package_size')} in manifest.json
|
|
105
|
+
`);
|
|
106
|
+
// Handle the main action
|
|
107
|
+
async function handleAction(directories, options) {
|
|
108
|
+
const { force, quiet, debug, manifestCheck } = options;
|
|
109
|
+
// Show header if not in quiet mode
|
|
110
|
+
if (!quiet) {
|
|
111
|
+
logger.header(`msfs-layout-generator`);
|
|
112
|
+
console.log(); // Empty line
|
|
113
|
+
}
|
|
114
|
+
// Check if directories were provided
|
|
115
|
+
if (!directories || directories.length === 0) {
|
|
116
|
+
logger.error('No directories specified.');
|
|
117
|
+
logger.info('Use msfs-layout --help for usage information.');
|
|
118
|
+
process.exit(1);
|
|
119
|
+
}
|
|
120
|
+
const errors = [];
|
|
121
|
+
const successes = [];
|
|
122
|
+
let totalFilesProcessed = 0;
|
|
123
|
+
// Process each directory
|
|
124
|
+
for (const dir of directories) {
|
|
125
|
+
try {
|
|
126
|
+
const fullPath = path.resolve(dir);
|
|
127
|
+
if (!quiet) {
|
|
128
|
+
logger.info(`Processing: ${chalk_1.default.underline(fullPath)}`);
|
|
129
|
+
}
|
|
130
|
+
if (debug) {
|
|
131
|
+
logger.dim(` Debug: Resolved path: ${fullPath}`);
|
|
132
|
+
}
|
|
133
|
+
// Check if directory exists
|
|
134
|
+
if (!require('fs').existsSync(fullPath)) {
|
|
135
|
+
throw new Error(`Directory does not exist`);
|
|
136
|
+
}
|
|
137
|
+
// Run the main processing function
|
|
138
|
+
const result = await (0, doProcessLayoutFileCli_1.doProcessLayoutFileCli)(fullPath, {
|
|
139
|
+
force,
|
|
140
|
+
quiet,
|
|
141
|
+
debug,
|
|
142
|
+
checkManifest: manifestCheck
|
|
143
|
+
});
|
|
144
|
+
totalFilesProcessed += result.fileCount || 0;
|
|
145
|
+
successes.push(path.basename(fullPath));
|
|
146
|
+
if (!quiet) {
|
|
147
|
+
logger.success(`Generated layout.json for ${chalk_1.default.bold(path.basename(fullPath))}`);
|
|
148
|
+
if (result.fileCount) {
|
|
149
|
+
logger.dim(` ${result.fileCount} files included`);
|
|
150
|
+
}
|
|
151
|
+
if (result.totalSize) {
|
|
152
|
+
logger.dim(` Total package size: ${formatFileSize(result.totalSize)}`);
|
|
153
|
+
}
|
|
154
|
+
console.log(); // Empty line for separation
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
catch (error) {
|
|
158
|
+
const errorMsg = `Failed to process ${dir}: ${error.message}`;
|
|
159
|
+
errors.push(errorMsg);
|
|
160
|
+
if (!quiet) {
|
|
161
|
+
logger.error(errorMsg);
|
|
162
|
+
if (debug && error.stack) {
|
|
163
|
+
logger.dim(error.stack);
|
|
164
|
+
}
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
}
|
|
168
|
+
// Show summary
|
|
169
|
+
if (!quiet) {
|
|
170
|
+
console.log(chalk_1.default.bold.cyan('='.repeat(50)));
|
|
171
|
+
if (successes.length > 0) {
|
|
172
|
+
logger.success(`Successfully processed ${successes.length} package(s):`);
|
|
173
|
+
successes.forEach(pkg => logger.dim(` • ${pkg}`));
|
|
174
|
+
}
|
|
175
|
+
if (errors.length > 0) {
|
|
176
|
+
console.log(); // Empty line
|
|
177
|
+
logger.error(`Failed to process ${errors.length} package(s):`);
|
|
178
|
+
errors.forEach(err => logger.dim(` • ${err}`));
|
|
179
|
+
}
|
|
180
|
+
if (totalFilesProcessed > 0) {
|
|
181
|
+
console.log(); // Empty line
|
|
182
|
+
logger.info(`Total files processed: ${chalk_1.default.bold(totalFilesProcessed.toString())}`);
|
|
183
|
+
}
|
|
184
|
+
}
|
|
185
|
+
// Exit with appropriate code
|
|
186
|
+
if (errors.length > 0) {
|
|
187
|
+
process.exit(1);
|
|
188
|
+
}
|
|
189
|
+
else if (successes.length === 0) {
|
|
190
|
+
logger.error('No packages were processed.');
|
|
191
|
+
process.exit(1);
|
|
192
|
+
}
|
|
193
|
+
}
|
|
194
|
+
// Helper function to format file sizes
|
|
195
|
+
function formatFileSize(bytes) {
|
|
196
|
+
if (bytes === 0)
|
|
197
|
+
return '0 Bytes';
|
|
198
|
+
const k = 1024;
|
|
199
|
+
const sizes = ['Bytes', 'KB', 'MB', 'GB'];
|
|
200
|
+
const i = Math.floor(Math.log(bytes) / Math.log(k));
|
|
201
|
+
return parseFloat((bytes / Math.pow(k, i)).toFixed(2)) + ' ' + sizes[i];
|
|
202
|
+
}
|
|
203
|
+
// Handle unhandled errors
|
|
204
|
+
process.on('unhandledRejection', (error) => {
|
|
205
|
+
logger.error(`Unhandled error: ${error.message}`);
|
|
206
|
+
if (program.opts().debug && error.stack) {
|
|
207
|
+
console.error(chalk_1.default.dim(error.stack));
|
|
208
|
+
}
|
|
209
|
+
process.exit(1);
|
|
210
|
+
});
|
|
211
|
+
// Parse arguments
|
|
212
|
+
try {
|
|
213
|
+
program.parse(process.argv);
|
|
214
|
+
}
|
|
215
|
+
catch (error) {
|
|
216
|
+
logger.error(`Failed to parse arguments: ${error.message}`);
|
|
217
|
+
process.exit(1);
|
|
218
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare const excludedFiles: Set<string>;
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.ManifestWritingError = void 0;
|
|
4
|
+
class ManifestWritingError extends Error {
|
|
5
|
+
constructor(message) {
|
|
6
|
+
super(message);
|
|
7
|
+
this.name = "ManifestWritingError";
|
|
8
|
+
}
|
|
9
|
+
}
|
|
10
|
+
exports.ManifestWritingError = ManifestWritingError;
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.ReadingDirError = void 0;
|
|
4
|
+
class ReadingDirError extends Error {
|
|
5
|
+
constructor(message) {
|
|
6
|
+
super(message);
|
|
7
|
+
this.name = "ReadingDirError";
|
|
8
|
+
}
|
|
9
|
+
}
|
|
10
|
+
exports.ReadingDirError = ReadingDirError;
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.ReadingJsonError = void 0;
|
|
4
|
+
class ReadingJsonError extends Error {
|
|
5
|
+
constructor(message) {
|
|
6
|
+
super(message);
|
|
7
|
+
this.name = "ReadingJsonError";
|
|
8
|
+
}
|
|
9
|
+
}
|
|
10
|
+
exports.ReadingJsonError = ReadingJsonError;
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.ManifestWritingError = exports.ReadingDirError = exports.ReadingJsonError = void 0;
|
|
4
|
+
const ReadingJsonError_1 = require("./ReadingJsonError");
|
|
5
|
+
Object.defineProperty(exports, "ReadingJsonError", { enumerable: true, get: function () { return ReadingJsonError_1.ReadingJsonError; } });
|
|
6
|
+
const ReadingDirError_1 = require("./ReadingDirError");
|
|
7
|
+
Object.defineProperty(exports, "ReadingDirError", { enumerable: true, get: function () { return ReadingDirError_1.ReadingDirError; } });
|
|
8
|
+
const ManifestWritingError_1 = require("./ManifestWritingError");
|
|
9
|
+
Object.defineProperty(exports, "ManifestWritingError", { enumerable: true, get: function () { return ManifestWritingError_1.ManifestWritingError; } });
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Process an MSFS package directory to generate/update layout.json
|
|
3
|
+
*
|
|
4
|
+
* This function scans all files in the package directory, creates a layout.json
|
|
5
|
+
* with file metadata, and updates the total_package_size in manifest.json.
|
|
6
|
+
*
|
|
7
|
+
* @param packageDir - Path to the MSFS package directory (must contain manifest.json)
|
|
8
|
+
* @returns Promise that resolves when layout.json has been generated
|
|
9
|
+
*
|
|
10
|
+
* @throws {Error} If package directory doesn't exist or doesn't contain manifest.json
|
|
11
|
+
* @throws {Error} If no valid files are found in the package
|
|
12
|
+
*
|
|
13
|
+
* @example
|
|
14
|
+
* // Basic usage
|
|
15
|
+
* await doProcessLayoutFile("F:\\fs20\\Community\\my-package");
|
|
16
|
+
*
|
|
17
|
+
* @example
|
|
18
|
+
* // With error handling
|
|
19
|
+
* try {
|
|
20
|
+
* await generateLayout("./my-package");
|
|
21
|
+
* console.log("Layout generated successfully");
|
|
22
|
+
* } catch (error) {
|
|
23
|
+
* console.error("Failed:", error.message);
|
|
24
|
+
* }
|
|
25
|
+
*/
|
|
26
|
+
export declare const generateLayout: (layoutPath: string) => Promise<void>;
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.generateLayout = void 0;
|
|
4
|
+
const doProcessLayoutFile_1 = require("./utils/doProcessLayoutFile");
|
|
5
|
+
/**
|
|
6
|
+
* Process an MSFS package directory to generate/update layout.json
|
|
7
|
+
*
|
|
8
|
+
* This function scans all files in the package directory, creates a layout.json
|
|
9
|
+
* with file metadata, and updates the total_package_size in manifest.json.
|
|
10
|
+
*
|
|
11
|
+
* @param packageDir - Path to the MSFS package directory (must contain manifest.json)
|
|
12
|
+
* @returns Promise that resolves when layout.json has been generated
|
|
13
|
+
*
|
|
14
|
+
* @throws {Error} If package directory doesn't exist or doesn't contain manifest.json
|
|
15
|
+
* @throws {Error} If no valid files are found in the package
|
|
16
|
+
*
|
|
17
|
+
* @example
|
|
18
|
+
* // Basic usage
|
|
19
|
+
* await doProcessLayoutFile("F:\\fs20\\Community\\my-package");
|
|
20
|
+
*
|
|
21
|
+
* @example
|
|
22
|
+
* // With error handling
|
|
23
|
+
* try {
|
|
24
|
+
* await generateLayout("./my-package");
|
|
25
|
+
* console.log("Layout generated successfully");
|
|
26
|
+
* } catch (error) {
|
|
27
|
+
* console.error("Failed:", error.message);
|
|
28
|
+
* }
|
|
29
|
+
*/
|
|
30
|
+
exports.generateLayout = doProcessLayoutFile_1.doProcessLayoutFile;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare const excludedFiles: Set<string>;
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Process an MSFS package directory to generate/update layout.json
|
|
3
|
+
*
|
|
4
|
+
* This function scans all files in the package directory, creates a layout.json
|
|
5
|
+
* with file metadata, and updates the total_package_size in manifest.json.
|
|
6
|
+
*
|
|
7
|
+
* @param packageDir - Path to the MSFS package directory (must contain manifest.json)
|
|
8
|
+
* @returns Promise that resolves when layout.json has been generated
|
|
9
|
+
*
|
|
10
|
+
* @throws {Error} If package directory doesn't exist or doesn't contain manifest.json
|
|
11
|
+
* @throws {Error} If no valid files are found in the package
|
|
12
|
+
*
|
|
13
|
+
* @example
|
|
14
|
+
* // Basic usage
|
|
15
|
+
* await doProcessLayoutFile("F:\\fs20\\Community\\my-package");
|
|
16
|
+
*
|
|
17
|
+
* @example
|
|
18
|
+
* // With error handling
|
|
19
|
+
* try {
|
|
20
|
+
* await generateLayout("./my-package");
|
|
21
|
+
* console.log("Layout generated successfully");
|
|
22
|
+
* } catch (error) {
|
|
23
|
+
* console.error("Failed:", error.message);
|
|
24
|
+
* }
|
|
25
|
+
*/
|
|
26
|
+
export declare const generateLayout: (layoutPath: string) => Promise<void>;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare const doExcludeFile: (relativePath: string) => boolean;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare const doProcessLayoutFile: (layoutPath: string) => Promise<void>;
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
export interface ProcessOptions {
|
|
2
|
+
force?: boolean;
|
|
3
|
+
quiet?: boolean;
|
|
4
|
+
debug?: boolean;
|
|
5
|
+
checkManifest?: boolean;
|
|
6
|
+
skipManifestUpdate?: boolean;
|
|
7
|
+
}
|
|
8
|
+
export interface ProcessResult {
|
|
9
|
+
fileCount: number;
|
|
10
|
+
totalSize: number;
|
|
11
|
+
layoutPath: string;
|
|
12
|
+
manifestPath: string;
|
|
13
|
+
skippedFiles: number;
|
|
14
|
+
success: boolean;
|
|
15
|
+
message?: string;
|
|
16
|
+
}
|
|
17
|
+
export declare const doProcessLayoutFileCli: (packageDir: string, options?: ProcessOptions) => Promise<ProcessResult>;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare const doUpdateManifest: (manifestPath: string, totalPackageSize: number) => Promise<void>;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare const getAllFiles: (dirPath: string) => Promise<string[]>;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare const getWindowsFileTime: (date: Date) => number;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare function readJson<T = unknown>(path: string): Promise<T | null>;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare const doExcludeFile: (relativePath: string) => boolean;
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
+
var ownKeys = function(o) {
|
|
20
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
+
var ar = [];
|
|
22
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
+
return ar;
|
|
24
|
+
};
|
|
25
|
+
return ownKeys(o);
|
|
26
|
+
};
|
|
27
|
+
return function (mod) {
|
|
28
|
+
if (mod && mod.__esModule) return mod;
|
|
29
|
+
var result = {};
|
|
30
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
+
__setModuleDefault(result, mod);
|
|
32
|
+
return result;
|
|
33
|
+
};
|
|
34
|
+
})();
|
|
35
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
36
|
+
exports.doExcludeFile = void 0;
|
|
37
|
+
const path = __importStar(require("node:path"));
|
|
38
|
+
const constants_1 = require("../constants/constants");
|
|
39
|
+
const doExcludeFile = (relativePath) => {
|
|
40
|
+
const fileName = path.basename(relativePath).toLowerCase();
|
|
41
|
+
if (relativePath.toLowerCase().startsWith('_cvt_/')) {
|
|
42
|
+
return true;
|
|
43
|
+
}
|
|
44
|
+
return constants_1.excludedFiles.has(fileName);
|
|
45
|
+
};
|
|
46
|
+
exports.doExcludeFile = doExcludeFile;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare const doProcessLayoutFile: (layoutPath: string) => Promise<void>;
|
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
+
var ownKeys = function(o) {
|
|
20
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
+
var ar = [];
|
|
22
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
+
return ar;
|
|
24
|
+
};
|
|
25
|
+
return ownKeys(o);
|
|
26
|
+
};
|
|
27
|
+
return function (mod) {
|
|
28
|
+
if (mod && mod.__esModule) return mod;
|
|
29
|
+
var result = {};
|
|
30
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
+
__setModuleDefault(result, mod);
|
|
32
|
+
return result;
|
|
33
|
+
};
|
|
34
|
+
})();
|
|
35
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
36
|
+
exports.doProcessLayoutFile = void 0;
|
|
37
|
+
const path = __importStar(require("node:path"));
|
|
38
|
+
const getAllFiles_1 = require("./getAllFiles");
|
|
39
|
+
const doExcludeFile_1 = require("./doExcludeFile");
|
|
40
|
+
const promises_1 = require("fs/promises");
|
|
41
|
+
const getWindowsFileTime_1 = require("./getWindowsFileTime");
|
|
42
|
+
const doUpdateManifest_1 = require("./doUpdateManifest");
|
|
43
|
+
const doProcessLayoutFile = async (layoutPath) => {
|
|
44
|
+
const layoutPathFile = path.join(layoutPath, 'layout.json');
|
|
45
|
+
const directory = await (0, promises_1.readdir)(layoutPath);
|
|
46
|
+
if (!directory.includes('layout.json')) {
|
|
47
|
+
console.log(`No layout.json is found in "${layoutPath}". A new layout will be created.`);
|
|
48
|
+
await (0, promises_1.writeFile)(layoutPathFile, "", 'utf8');
|
|
49
|
+
}
|
|
50
|
+
let totalPackageSize = 0;
|
|
51
|
+
const layout = { content: [] };
|
|
52
|
+
try {
|
|
53
|
+
const allFiles = await (0, getAllFiles_1.getAllFiles)(layoutPath);
|
|
54
|
+
let hasLongPath = false;
|
|
55
|
+
for (const file of allFiles) {
|
|
56
|
+
if (file.length > 259) {
|
|
57
|
+
hasLongPath = true;
|
|
58
|
+
continue;
|
|
59
|
+
}
|
|
60
|
+
const relativePath = path.relative(layoutPath, file).split(path.sep).join('/');
|
|
61
|
+
const isExcluded = (0, doExcludeFile_1.doExcludeFile)(relativePath);
|
|
62
|
+
try {
|
|
63
|
+
const stats = await (0, promises_1.stat)(file);
|
|
64
|
+
totalPackageSize += stats.size;
|
|
65
|
+
if (isExcluded) {
|
|
66
|
+
continue;
|
|
67
|
+
}
|
|
68
|
+
const content = {
|
|
69
|
+
path: relativePath,
|
|
70
|
+
size: stats.size,
|
|
71
|
+
date: (0, getWindowsFileTime_1.getWindowsFileTime)(stats.mtime)
|
|
72
|
+
};
|
|
73
|
+
layout.content.push(content);
|
|
74
|
+
}
|
|
75
|
+
catch (error) {
|
|
76
|
+
console.log(`Error processing file ${file}: ${error.message}`);
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
if (hasLongPath) {
|
|
80
|
+
console.log(`Warning: One or more file paths in the folder containing "${layoutPath}" are 260 characters or greater in length. Some files may have been skipped.`);
|
|
81
|
+
}
|
|
82
|
+
if (layout.content.length === 0) {
|
|
83
|
+
console.log(`No files were found in the folder containing "${layoutPath}". The layout.json will not be updated.`);
|
|
84
|
+
return;
|
|
85
|
+
}
|
|
86
|
+
// Sort content by path for consistent output
|
|
87
|
+
layout.content.sort((a, b) => a.path.localeCompare(b.path));
|
|
88
|
+
// Write layout.json with LF line endings
|
|
89
|
+
const json = JSON.stringify(layout, null, 2).replace(/\r\n/g, '\n');
|
|
90
|
+
await (0, promises_1.writeFile)(layoutPathFile, json, 'utf8');
|
|
91
|
+
// Add layout.json size to total
|
|
92
|
+
const layoutStats = await (0, promises_1.stat)(layoutPath);
|
|
93
|
+
totalPackageSize += layoutStats.size;
|
|
94
|
+
// Update manifest.json if it exists
|
|
95
|
+
const manifestPath = path.join(layoutPath, 'manifest.json');
|
|
96
|
+
try {
|
|
97
|
+
await (0, promises_1.access)(manifestPath, promises_1.constants.F_OK);
|
|
98
|
+
await (0, doUpdateManifest_1.doUpdateManifest)(manifestPath, totalPackageSize);
|
|
99
|
+
}
|
|
100
|
+
catch {
|
|
101
|
+
// manifest doesn't exist, skip
|
|
102
|
+
}
|
|
103
|
+
console.log(`Successfully updated ${layoutPath} with ${layout.content.length} files`);
|
|
104
|
+
}
|
|
105
|
+
catch (error) {
|
|
106
|
+
console.log(`Error processing ${layoutPathFile}: ${error.message}`);
|
|
107
|
+
}
|
|
108
|
+
};
|
|
109
|
+
exports.doProcessLayoutFile = doProcessLayoutFile;
|