| 1 | export const RELEASE_ASSET_PREFIX |
| 2 |
| 3 | export const DEFAULT_RELEASE_ASSET_MAX_BYTES = 2 * 1024 ** 3; |
| 4 |
| 5 | /** A bare `type/subtype`: an asset's type is served back as its `Content-Type`. */ |
| 6 | export const MEDIA_TYPE = /^[\w.+-]+\/[\w.+-]+$/; |
| 7 |
| 8 | /** Where an asset's bytes live. A release's or a repository's assets can be removed by prefix. */ |
| 9 | export function releaseAssetKey( |
| 10 | repositoryId: string, |
| 11 | releaseId?: string, |
| 12 | assetId?: string, |
| 13 | ) { |
| 14 | return [RELEASE_ASSET_PREFIX, repositoryId, releaseId, assetId] |
| 15 | .filter(Boolean) |
| 16 | .join('/') |
| 17 | .concat(assetId ? '' : '/'); |
| 18 | } |
| 19 |
| 20 | /** A file name, never a path: it becomes the last segment of a download URL and the name a browser saves. */ |
| 21 | export function isValidAssetName(name: string) { |
| 22 | return ( |
| 23 | name.length > 0 && |
| 24 | name.length <= 255 && |
| 25 | name !== '.' && |
| 26 | name !== '..' && |
| 27 | // no separators, no control characters |
| 28 | !/[/\\\u0000-\u001f\u007f]/.test(name) |
| 29 | ); |
| 30 | } |