@@ -16,6 +16,7 @@ import { findDuplicates } from '../utils/array.js'
1616import { toEntity } from '../utils/entity.js'
1717import { BadReq , Forbidden , InternalError , NotFound } from '../utils/error.js'
1818import { isMongoServerError } from '../utils/mongo.js'
19+ import { semverObjectToString , semverStringToObject } from '../utils/semver.js'
1920import { arrayOfObjectsHasKeysOfType , hasKeysOfType } from '../utils/typeguards.js'
2021import { getFileById , getFilesByIds } from './file.js'
2122import log from './log.js'
@@ -49,8 +50,8 @@ export function isReleaseDoc(data: unknown): data is ReleaseDoc {
4950}
5051
5152export async function validateRelease ( user : UserInterface , model : ModelDoc , release : ReleaseDoc ) {
52- if ( ! semver . valid ( release . semver ) ) {
53- throw BadReq ( `The version '${ release . semver } ' is not a valid semver value.` )
53+ if ( ! semver . valid ( release . semverString ) ) {
54+ throw BadReq ( `The version '${ release . semverString } ' is not a valid semver value.` )
5455 }
5556
5657 if ( release . images && release . images . length > 0 ) {
@@ -89,7 +90,7 @@ export async function validateRelease(user: UserInterface, model: ModelDoc, rele
8990 if ( isBailoError ( e ) && e . code === 404 ) {
9091 throw BadReq ( 'Unable to create release as the file cannot be found.' , {
9192 fileId,
92- semver : release . semver ,
93+ semver : release . semverString ,
9394 modelId : release . modelId ,
9495 } )
9596 }
@@ -125,10 +126,9 @@ export async function validateRelease(user: UserInterface, model: ModelDoc, rele
125126}
126127
127128export type CreateReleaseParams = Optional <
128- Pick <
129- ReleaseInterface ,
130- 'modelId' | 'modelCardVersion' | 'semver' | 'notes' | 'minor' | 'draft' | 'fileIds' | 'images'
131- > ,
129+ Pick < ReleaseInterface , 'modelId' | 'modelCardVersion' | 'notes' | 'minor' | 'draft' | 'fileIds' | 'images' > & {
130+ semver : string
131+ } ,
132132 'modelCardVersion'
133133>
134134export async function createRelease ( user : UserInterface , releaseParams : CreateReleaseParams ) {
@@ -150,7 +150,7 @@ export async function createRelease(user: UserInterface, releaseParams: CreateRe
150150
151151 const deletedRelease = await ReleaseModel . findOne ( {
152152 modelId : releaseParams . modelId ,
153- semver : releaseParams . semver ,
153+ semver : semverStringToObject ( releaseParams . semver ) ,
154154 deleted : true ,
155155 } )
156156 if ( deletedRelease ) {
@@ -162,6 +162,8 @@ export async function createRelease(user: UserInterface, releaseParams: CreateRe
162162 const release = new ReleaseModel ( {
163163 createdBy : user . dn ,
164164 ...releaseParams ,
165+ // override semver string to be the object representation
166+ semver : semverStringToObject ( releaseParams . semver ) ,
165167 } )
166168
167169 await validateRelease ( user , model , release )
@@ -198,7 +200,7 @@ export async function createRelease(user: UserInterface, releaseParams: CreateRe
198200 sendWebhooks (
199201 release . modelId ,
200202 WebhookEvent . CreateRelease ,
201- `Release ${ release . semver } has been created for model ${ release . modelId } ` ,
203+ `Release ${ release . semverString } has been created for model ${ release . modelId } ` ,
202204 { release } ,
203205 )
204206
@@ -223,7 +225,10 @@ export async function updateRelease(user: UserInterface, modelId: string, semver
223225 modelId : modelId ,
224226 } )
225227 }
226- const updatedRelease = await ReleaseModel . findOneAndUpdate ( { modelId, semver } , { $set : release } )
228+ const updatedRelease = await ReleaseModel . findOneAndUpdate (
229+ { modelId, semver : semverStringToObject ( semver ) } ,
230+ { $set : release } ,
231+ )
227232
228233 if ( ! updatedRelease ) {
229234 throw NotFound ( `The requested release was not found.` , { modelId, semver } )
@@ -232,7 +237,7 @@ export async function updateRelease(user: UserInterface, modelId: string, semver
232237 sendWebhooks (
233238 release . modelId ,
234239 WebhookEvent . UpdateRelease ,
235- `ReleaseModel ${ release . semver } has been updated for model ${ release . modelId } ` ,
240+ `ReleaseModel ${ release . semverString } has been updated for model ${ release . modelId } ` ,
236241 { release } ,
237242 )
238243
@@ -245,7 +250,7 @@ export async function newReleaseComment(user: UserInterface, modelId: string, se
245250 throw BadReq ( `Cannot create a new comment on a mirrored model.` )
246251 }
247252
248- const release = await ReleaseModel . findOne ( { modelId, semver } )
253+ const release = await ReleaseModel . findOne ( { modelId, semver : semverStringToObject ( semver ) } )
249254 if ( ! release ) {
250255 throw NotFound ( `The requested release was not found.` , { modelId, semver } )
251256 }
@@ -320,12 +325,13 @@ export async function getModelReleases(
320325
321326export async function getReleasesForExport ( user : UserInterface , modelId : string , semvers : string [ ] ) {
322327 const model = await getModelById ( user , modelId )
328+ const semverObjects = semvers . map ( ( semver ) => semverStringToObject ( semver ) )
323329 const releases = await ReleaseModel . find ( {
324330 modelId,
325- semver : { $in : semvers } ,
331+ semver : { $in : semverObjects } ,
326332 } )
327333
328- const missing = semvers . filter ( ( x ) => ! releases . some ( ( release ) => release . semver === x ) )
334+ const missing = semvers . filter ( ( x ) => ! releases . some ( ( release ) => release . semverString === x ) )
329335 if ( missing . length > 0 ) {
330336 throw NotFound ( 'The following releases were not found.' , { modelId, releases : missing } )
331337 }
@@ -335,43 +341,19 @@ export async function getReleasesForExport(user: UserInterface, modelId: string,
335341 if ( failedReleases . length > 0 ) {
336342 throw Forbidden ( 'You do not have the necessary permissions to export these releases.' , {
337343 modelId,
338- releases : failedReleases . map ( ( release ) => release . semver ) ,
344+ releases : failedReleases . map ( ( release ) => release . semverString ) ,
339345 user,
340346 } )
341347 }
342348
343349 return releases
344350}
345351
346- export function semverStringToObject ( semver : string ) : SemverObject {
347- const vIdentifierIndex = semver . indexOf ( 'v' )
348- const trimmedSemver = vIdentifierIndex === - 1 ? semver : semver . slice ( vIdentifierIndex + 1 )
349- const [ version , metadata ] = trimmedSemver . split ( '-' )
350- const [ major , minor , patch ] = version . split ( '.' )
351- const majorNum : number = Number ( major )
352- const minorNum : number = Number ( minor )
353- const patchNum : number = Number ( patch )
354- return { major : majorNum , minor : minorNum , patch : patchNum , ...( metadata && { metadata } ) }
355- }
356-
357- export function semverObjectToString ( semver : SemverObject ) : string {
358- if ( ! semver ) {
359- return ''
360- }
361- let metadata : string
362- if ( semver . metadata != undefined ) {
363- metadata = `-${ semver . metadata } `
364- } else {
365- metadata = ``
366- }
367- return `${ semver . major } .${ semver . minor } .${ semver . patch } ${ metadata } `
368- }
369-
370352export async function getReleaseBySemver ( user : UserInterface , model : string | ModelDoc , semver : string ) {
371353 if ( typeof model === 'string' ) {
372354 model = await getModelById ( user , model )
373355 }
374- const release = await ReleaseModel . findOne ( { modelId : model . id , semver } )
356+ const release = await ReleaseModel . findOne ( { modelId : model . id , semver : semverStringToObject ( semver ) } )
375357
376358 if ( ! release ) {
377359 throw NotFound ( `The requested release was not found.` , { modelId : model . id , semver } )
@@ -538,7 +520,7 @@ export async function deleteReleases(
538520
539521 await release . delete ( session )
540522 await removeReleaseReviews ( modelId , semver , session )
541- await removeResponsesByParentIds ( [ ...reviewsForRelease . map ( ( review ) => review . id ) , release . id ] , session )
523+ await removeResponsesByParentIds ( [ ...reviewsForRelease . map ( ( review ) => review . id ) , release . _id . toString ( ) ] , session )
542524 }
543525
544526 return { modelId, semvers }
0 commit comments