diff --git a/src/cross.ts b/src/cross.ts new file mode 100644 index 0000000..9185b34 --- /dev/null +++ b/src/cross.ts @@ -0,0 +1,35 @@ +export interface NumericVersion { + readonly major: number; + readonly minor: number; + readonly patch: number; +} + +export function parseNumericVersion(value: string): NumericVersion | null { + const match = /^(\d+)\.(\d+)\.(\d+)(?:[-+].*)?$/.exec(value.trim()); + + if (!match) return null; + + const major = Number(match[1]); + const minor = Number(match[2]); + const patch = Number(match[3]); + + if (![major, minor, patch].every(Number.isSafeInteger)) return null; + + return { major, minor, patch }; +} + +export function compareVersions( + left: NumericVersion, + right: NumericVersion, +): number { + if (left.major !== right.major) return left.major - right.major; + if (left.minor !== right.minor) return left.minor - right.minor; + return left.patch - right.patch; +} + +export function isAtLeast( + actual: NumericVersion, + minimum: NumericVersion, +): boolean { + return compareVersions(actual, minimum) >= 0; +} diff --git a/src/validate.ts b/src/validate.ts new file mode 100644 index 0000000..693f6c9 --- /dev/null +++ b/src/validate.ts @@ -0,0 +1,24 @@ +import type { + ProjectGenerationResult, + ProjectGeneratorInput, + ProjectGeneratorServices, +} from './types.js'; + +export function orchestrateProjectGeneration( + input: ProjectGeneratorInput, + services: ProjectGeneratorServices, +): ProjectGenerationResult { + const validated = services.validate(input); + const destination = services.planDestination(validated); + const template = services.selectTemplate(validated, destination); + const result = services.generate({ + input: validated, + destination, + template, + }); + + services.install?.(result); + services.initializeGit?.(result); + + return result; +}