@simplyhomes/sos-sdk
Version:
TypeScript SDK for Simply Homes SoS API v4
120 lines (119 loc) ⢠4.51 kB
JavaScript
import { readFileSync, writeFileSync, readdirSync, statSync } from 'fs';
import { join } from 'path';
/**
* Recursively get all .ts files in a directory
*/
function getAllTsFiles(dir) {
const files = [];
const entries = readdirSync(dir);
for (const entry of entries) {
const fullPath = join(dir, entry);
const stat = statSync(fullPath);
if (stat.isDirectory()) {
files.push(...getAllTsFiles(fullPath));
}
else if (entry.endsWith('.ts')) {
files.push(fullPath);
}
}
return files;
}
/**
* Transform Date types to string in a TypeScript file
*/
function transformFile(filePath) {
let content = readFileSync(filePath, 'utf-8');
const originalContent = content;
let typeReplacements = 0;
let fromJsonReplacements = 0;
let toJsonReplacements = 0;
// 1. Transform interface property types: Date -> string
// Matches: ": Date;" or "?: Date;" (with property name before)
content = content.replace(/:\s*Date;/g, (match) => {
typeReplacements++;
return ': string;';
});
content = content.replace(/\?:\s*Date;/g, (match) => {
typeReplacements++;
return '?: string;';
});
// 2. Transform Array<Date> to Array<string> (if any)
content = content.replace(/Array<Date>/g, () => {
typeReplacements++;
return 'Array<string>';
});
// 3. Transform FromJSON: new Date(json['field']) -> json['field']
// Matches patterns like: (new Date(json['expectedClosingDate']))
// The parentheses might be there for type coercion
content = content.replace(/\(new Date\(json\[([^\]]+)\]\)\)/g, (match, fieldName) => {
fromJsonReplacements++;
return `json[${fieldName}]`;
});
// Also handle without outer parentheses: new Date(json['field'])
content = content.replace(/new Date\(json\[([^\]]+)\]\)/g, (match, fieldName) => {
fromJsonReplacements++;
return `json[${fieldName}]`;
});
// 4. Transform ToJSON: value['field'].toISOString() -> value['field']
// This handles the serialization back to JSON
content = content.replace(/value\[([^\]]+)\]\.toISOString\(\)/g, (match, fieldName) => {
toJsonReplacements++;
return `value[${fieldName}]`;
});
// Write back if modified
const modified = content !== originalContent;
if (modified) {
writeFileSync(filePath, content, 'utf-8');
}
return {
modified,
typeReplacements,
fromJsonReplacements,
toJsonReplacements
};
}
/**
* Main transformation function
*/
async function main() {
console.log('š Starting Date -> string type transformation...\n');
const modelsDir = join(process.cwd(), 'src', 'generated', 'src', 'models');
console.log(`š Scanning directory: ${modelsDir}\n`);
const files = getAllTsFiles(modelsDir);
console.log(`š Found ${files.length} TypeScript files\n`);
const stats = {
filesProcessed: 0,
filesModified: 0,
typeReplacements: 0,
fromJsonReplacements: 0,
toJsonReplacements: 0
};
for (const file of files) {
stats.filesProcessed++;
const result = transformFile(file);
if (result.modified) {
stats.filesModified++;
stats.typeReplacements += result.typeReplacements;
stats.fromJsonReplacements += result.fromJsonReplacements;
stats.toJsonReplacements += result.toJsonReplacements;
const fileName = file.split(/[/\\]/).pop();
console.log(` ā ${fileName} (${result.typeReplacements} types, ${result.fromJsonReplacements} fromJSON, ${result.toJsonReplacements} toJSON)`);
}
}
console.log('\n⨠Transformation complete!\n');
console.log('š Summary:');
console.log(` ⢠Files processed: ${stats.filesProcessed}`);
console.log(` ⢠Files modified: ${stats.filesModified}`);
console.log(` ⢠Type replacements: ${stats.typeReplacements}`);
console.log(` ⢠FromJSON replacements: ${stats.fromJsonReplacements}`);
console.log(` ⢠ToJSON replacements: ${stats.toJsonReplacements}\n`);
if (stats.filesModified === 0) {
console.log('ā ļø No files were modified. The transformation may have already been applied.\n');
}
process.exit(0);
}
main().catch((error) => {
console.error('\nā Transformation failed:\n');
console.error(error);
process.exit(1);
});