| 1 | import { ApiProperty, ApiPropertyOptional } from '@nestjs/swagger'; |
| 2 | import { Transform, Type |
| 3 | import { |
| 4 | IsBoolean, |
| 5 | IsInt, |
| 6 | IsISO8601, |
| 7 | IsOptional, |
| 8 | IsString, |
| 9 | Matches, |
| 10 | Max, |
| 11 | MaxLength, |
| 12 | Min, |
| 13 | MinLength, |
| 14 | ValidateIf, |
| 15 | ValidateNested, |
| 16 | } from 'class-validator'; |
| 17 | |
| 18 | import { MEDIA_TYPE } |
| 19 | |
| 20 | export class ReleaseAssetDTO |
| 21 | @ApiProperty() |
| 22 | @IsString() |
| 23 | id: string; |
| 24 | |
| 25 | @ApiProperty({ example |
| 26 | @IsString() |
| 27 | name: string; |
| 28 | |
| 29 | @ApiProperty({ example |
| 30 | @IsString() |
| 31 | contentType: string; |
| 32 | |
| 33 | @ApiProperty({ description |
| 34 | @IsInt() |
| 35 | size: number; |
| 36 | |
| 37 | @ApiProperty() |
| 38 | @IsInt() |
| 39 | downloadCount: number; |
| 40 | |
| 41 | @ApiProperty() |
| 42 | @IsISO8601() |
| 43 | createdAt: string; |
| 44 | } |
| 45 | |
| 46 | export class UploadReleaseAssetQueryDTO |
| 47 | @ApiProperty({ |
| 48 | description: 'File name the asset is saved and downloaded under.', |
| 49 | example: 'ghost-linux-x64.tar.gz', |
| 50 | }) |
| 51 | @IsString() |
| 52 | @MaxLength(255) |
| 53 | name: string; |
| 54 | |
| 55 | @ApiPropertyOptional({ |
| 56 | description: |
| 57 | 'Media type the file is served with. The request body itself is always `application/octet-stream`.', |
| 58 | example: 'application/gzip', |
| 59 | }) |
| 60 | @IsString() |
| 61 | @IsOptional() |
| 62 | @Matches(MEDIA_TYPE) |
| 63 | type?: string |
| 64 | } |
| 65 | |
| 66 | export class ReleaseDTO |
| 67 | @ApiProperty() |
| 68 | @IsString() |
| 69 | id: string; |
| 70 | |
| 71 | @ApiProperty({ |
| 72 | description: 'Tag name, without the `refs/tags/` prefix.', |
| 73 | example: 'v1.0.0', |
| 74 | }) |
| 75 | @IsString() |
| 76 | tagName: string; |
| 77 | |
| 78 | @ApiProperty({ |
| 79 | type: String, |
| 80 | nullable: true, |
| 81 | description: '`null` reads as the tag name.', |
| 82 | }) |
| 83 | @IsString() |
| 84 | @IsOptional() |
| 85 | name: string |
| 86 | |
| 87 | @ApiProperty({ type |
| 88 | @IsString() |
| 89 | @IsOptional() |
| 90 | body: string |
| 91 | |
| 92 | @ApiProperty({ |
| 93 | description: 'Only people who can write to the repository see drafts.', |
| 94 | }) |
| 95 | @IsBoolean() |
| 96 | isDraft: boolean; |
| 97 | |
| 98 | @ApiProperty() |
| 99 | @IsBoolean() |
| 100 | isPrerelease: boolean; |
| 101 | |
| 102 | @ApiProperty({ |
| 103 | description: |
| 104 | 'The most recently published release that is neither a draft nor a prerelease.', |
| 105 | }) |
| 106 | @IsBoolean() |
| 107 | isLatest: boolean; |
| 108 | |
| 109 | @ApiProperty({ |
| 110 | type: String, |
| 111 | nullable: true, |
| 112 | description: 'Null once the author account is deleted.', |
| 113 | }) |
| 114 | @IsString() |
| 115 | @IsOptional() |
| 116 | authorUsername: string |
| 117 | |
| 118 | @ApiProperty({ |
| 119 | type: String, |
| 120 | nullable: true, |
| 121 | description: |
| 122 | 'The commit the tag points at. `null` when the tag has since been deleted.', |
| 123 | }) |
| 124 | @IsString() |
| 125 | @IsOptional() |
| 126 | commitSha: string |
| 127 | |
| 128 | @ApiProperty({ type |
| 129 | @ValidateNested({ each |
| 130 | @Type(() => |
| 131 | assets: ReleaseAssetDTO |
| 132 | |
| 133 | @ApiProperty({ type |
| 134 | @IsISO8601() |
| 135 | @IsOptional() |
| 136 | publishedAt: string |
| 137 | |
| 138 | @ApiProperty() |
| 139 | @IsISO8601() |
| 140 | createdAt: string; |
| 141 | |
| 142 | @ApiProperty() |
| 143 | @IsISO8601() |
| 144 | updatedAt: string; |
| 145 | |
| 146 | @ApiProperty({ |
| 147 | description: 'True when the requesting user can write to the repository.', |
| 148 | }) |
| 149 | @IsBoolean() |
| 150 | viewerCanEdit: boolean; |
| 151 | } |
| 152 | |
| 153 | export class GetReleasesQueryDTO |
| 154 | @ApiPropertyOptional({ |
| 155 | description: |
| 156 | 'Opaque cursor returned as `nextCursor` by the previous page. Omit for the first page.', |
| 157 | }) |
| 158 | @IsString() |
| 159 | @IsOptional() |
| 160 | cursor?: string |
| 161 | |
| 162 | @ApiPropertyOptional({ |
| 163 | description: 'Page size.', |
| 164 | minimum: 1, |
| 165 | maximum: 100, |
| 166 | default: 10, |
| 167 | }) |
| 168 | @Type(() => |
| 169 | @IsInt() |
| 170 | @Min(1) |
| 171 | @Max(100) |
| 172 | @IsOptional() |
| 173 | limit?: number |
| 174 | } |
| 175 | |
| 176 | export class GetReleasesResponseDTO |
| 177 | @ApiProperty({ type |
| 178 | @ValidateNested({ each |
| 179 | @Type(() => |
| 180 | releases: ReleaseDTO |
| 181 | |
| 182 | @ApiProperty({ type |
| 183 | @IsString() |
| 184 | @IsOptional() |
| 185 | nextCursor: string |
| 186 | } |
| 187 | |
| 188 | export class CreateReleaseRequestDTO |
| 189 | @ApiProperty({ |
| 190 | description: |
| 191 | 'An existing tag, or a new one to create at `target`. Without the `refs/tags/` prefix.', |
| 192 | example: 'v1.0.0', |
| 193 | }) |
| 194 | @IsString() |
| 195 | @Transform(({ |
| 196 | @MinLength(1) |
| 197 | @MaxLength(250) |
| 198 | tagName: string; |
| 199 | |
| 200 | @ApiPropertyOptional({ |
| 201 | description: |
| 202 | 'Branch or commit sha a new tag points at. Defaults to the default branch; ignored when the tag already exists.', |
| 203 | example: 'main', |
| 204 | }) |
| 205 | @IsString() |
| 206 | @IsOptional() |
| 207 | @MaxLength(250) |
| 208 | target?: string |
| 209 | |
| 210 | @ApiPropertyOptional({ example |
| 211 | @IsString() |
| 212 | @IsOptional() |
| 213 | @Transform(({ |
| 214 | @MaxLength(200) |
| 215 | name?: string |
| 216 | |
| 217 | @ApiPropertyOptional({ description |
| 218 | @IsString() |
| 219 | @IsOptional() |
| 220 | @MaxLength(100000) |
| 221 | body?: string |
| 222 | |
| 223 | @ApiPropertyOptional({ default |
| 224 | @IsBoolean() |
| 225 | @IsOptional() |
| 226 | isDraft?: boolean |
| 227 | |
| 228 | @ApiPropertyOptional({ default |
| 229 | @IsBoolean() |
| 230 | @IsOptional() |
| 231 | isPrerelease?: boolean |
| 232 | } |
| 233 | |
| 234 | export class UpdateReleaseRequestDTO |
| 235 | @ApiPropertyOptional({ |
| 236 | type: String, |
| 237 | nullable: true, |
| 238 | description: '`null` falls back to the tag name.', |
| 239 | }) |
| 240 | @IsString() |
| 241 | @IsOptional() |
| 242 | @ValidateIf((_ |
| 243 | @Transform(({ |
| 244 | @MaxLength(200) |
| 245 | name?: string |
| 246 | |
| 247 | @ApiPropertyOptional({ |
| 248 | type: String, |
| 249 | nullable: true, |
| 250 | description: 'Markdown. `null` clears the notes.', |
| 251 | }) |
| 252 | @IsString() |
| 253 | @IsOptional() |
| 254 | @ValidateIf((_ |
| 255 | @MaxLength(100000) |
| 256 | body?: string |
| 257 | |
| 258 | @ApiPropertyOptional({ |
| 259 | description: 'Publishing a draft stamps `publishedAt` the first time.', |
| 260 | }) |
| 261 | @IsBoolean() |
| 262 | @IsOptional() |
| 263 | isDraft?: boolean |
| 264 | |
| 265 | @ApiPropertyOptional() |
| 266 | @IsBoolean() |
| 267 | @IsOptional() |
| 268 | isPrerelease?: boolean |
| 269 | } |