34 lines
1.7 KiB
TypeScript
34 lines
1.7 KiB
TypeScript
/** TWS source releases use three numeric components, without tags or suffixes. */
|
|
export function scriptVersionError(value: unknown): string {
|
|
if (typeof value !== 'string' || !value.trim()) return 'A script release version is required.';
|
|
if (value.length > 80 || !/^(0|[1-9]\d*)\.(0|[1-9]\d*)\.(0|[1-9]\d*)$/.test(value.trim()))
|
|
return 'Use MAJOR.MINOR.PATCH for the script release version, such as 1.2.0.';
|
|
return '';
|
|
}
|
|
|
|
/** Ignore non-script components (for example native plugins) in a TWS manifest. */
|
|
export function parseScriptVersions(text: string): Record<string, string> {
|
|
let data: unknown;
|
|
try {
|
|
data = JSON.parse(text);
|
|
} catch {
|
|
throw new Error('Choose a valid versions.json file.');
|
|
}
|
|
if (!data || typeof data !== 'object' || Array.isArray(data))
|
|
throw new Error('versions.json must map script filenames to release versions.');
|
|
const entries = Object.entries(data).filter(([name]) => name.endsWith('.gsc'));
|
|
if (!entries.length) throw new Error('versions.json contains no .gsc filenames.');
|
|
for (const [name, value] of entries) {
|
|
if (name.includes('/') || name.includes('\\'))
|
|
throw new Error(`Use an exact filename in versions.json: ${name}`);
|
|
const error = scriptVersionError(value);
|
|
if (error) throw new Error(`${name}: ${error}`);
|
|
}
|
|
return Object.fromEntries(entries.map(([name, value]) => [name, (value as string).trim()]));
|
|
}
|
|
|
|
/** Uploaded filenames must never resolve inherited object properties. */
|
|
export function manifestVersion(versions: Record<string, string>, filename: string): string {
|
|
return Object.hasOwn(versions, filename) ? versions[filename] : '';
|
|
}
|