-
-
Notifications
You must be signed in to change notification settings - Fork 4k
feat: File upload support #11108
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Draft
Jiralite
wants to merge
5
commits into
main
Choose a base branch
from
feat/builders-modal-label-file
base: main
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Draft
feat: File upload support #11108
Changes from 2 commits
Commits
Show all changes
5 commits
Select commit
Hold shift + click to select a range
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,57 @@ | ||
import type { APIFileUploadComponent } from 'discord-api-types/v10'; | ||
import { ComponentType } from 'discord-api-types/v10'; | ||
import { describe, test, expect } from 'vitest'; | ||
import { FileUploadBuilder } from '../../src/components/fileUpload/FileUpload.js'; | ||
|
||
const fileUploadComponent = () => new FileUploadBuilder(); | ||
|
||
describe('File Upload Components', () => { | ||
describe('Assertion Tests', () => { | ||
test('GIVEN valid fields THEN builder does not throw', () => { | ||
expect(() => { | ||
fileUploadComponent().setCustomId('foobar').toJSON(); | ||
}).not.toThrowError(); | ||
|
||
expect(() => { | ||
fileUploadComponent().setCustomId('foobar').setMinValues(2).setMaxValues(9).toJSON(); | ||
}).not.toThrowError(); | ||
}); | ||
}); | ||
|
||
test('GIVEN invalid fields THEN builder throws', () => { | ||
expect(() => fileUploadComponent().toJSON()).toThrowError(); | ||
|
||
expect(() => { | ||
fileUploadComponent().setCustomId('a'.repeat(500)).toJSON(); | ||
}).toThrowError(); | ||
|
||
expect(() => { | ||
fileUploadComponent().setCustomId('a').setMaxValues(55).toJSON(); | ||
}).toThrowError(); | ||
|
||
expect(() => { | ||
fileUploadComponent().setCustomId('a').setMinValues(-1).toJSON(); | ||
}).toThrowError(); | ||
}); | ||
|
||
test('GIVEN valid input THEN valid JSON outputs are given', () => { | ||
const fileUploadData = { | ||
type: ComponentType.FileUpload, | ||
custom_id: 'custom id', | ||
min_values: 5, | ||
max_values: 6, | ||
required: false, | ||
} satisfies APIFileUploadComponent; | ||
|
||
expect(new FileUploadBuilder(fileUploadData).toJSON()).toEqual(fileUploadData); | ||
|
||
expect( | ||
fileUploadComponent() | ||
.setCustomId(fileUploadData.custom_id) | ||
.setMaxValues(fileUploadData.max_values) | ||
.setMinValues(fileUploadData.min_values) | ||
.setRequired(fileUploadData.required) | ||
.toJSON(), | ||
).toEqual(fileUploadData); | ||
}); | ||
}); |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
import { ComponentType } from 'discord-api-types/v10'; | ||
import { z } from 'zod'; | ||
import { customIdPredicate } from '../../Assertions'; | ||
|
||
export const fileUploadPredicate = z.object({ | ||
type: z.literal(ComponentType.FileUpload), | ||
id: z.number().optional(), | ||
custom_id: customIdPredicate, | ||
min_values: z.number().min(0).max(10).optional(), | ||
max_values: z.number().min(1).max(10).optional(), | ||
required: z.boolean().optional(), | ||
}); |
107 changes: 107 additions & 0 deletions
107
packages/builders/src/components/fileUpload/FileUpload.ts
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,107 @@ | ||
import type { APIFileUploadComponent } from 'discord-api-types/v10'; | ||
import { ComponentType } from 'discord-api-types/v10'; | ||
import { validate } from '../../util/validation.js'; | ||
import { ComponentBuilder } from '../Component.js'; | ||
import { fileUploadPredicate } from './Assertions.js'; | ||
|
||
/** | ||
* A builder that creates API-compatible JSON data for file uploads. | ||
*/ | ||
export class FileUploadBuilder extends ComponentBuilder<APIFileUploadComponent> { | ||
/** | ||
* @internal | ||
*/ | ||
protected readonly data: Partial<APIFileUploadComponent>; | ||
|
||
/** | ||
* Creates a new file upload. | ||
* | ||
* @param data - The API data to create this file upload with | ||
* @example | ||
* Creating a file upload from an API data object: | ||
* ```ts | ||
* const fileUpload = new FileUploadBuilder({ | ||
* custom_id: "file_upload", | ||
* min_values: 2, | ||
* }); | ||
* ``` | ||
Jiralite marked this conversation as resolved.
Show resolved
Hide resolved
|
||
* @example | ||
* Creating a file upload using setters and API data: | ||
* ```ts | ||
* const fileUpload = new FileUploadBuilder({ | ||
* custom_id: "file_upload", | ||
* min_values: 2, | ||
* }).setRequired(); | ||
* ``` | ||
*/ | ||
public constructor(data: Partial<APIFileUploadComponent> = {}) { | ||
super(); | ||
this.data = { ...structuredClone(data), type: ComponentType.FileUpload }; | ||
} | ||
|
||
/** | ||
* Sets the custom id for this file upload. | ||
* | ||
* @param customId - The custom id to use | ||
*/ | ||
public setCustomId(customId: string) { | ||
this.data.custom_id = customId; | ||
return this; | ||
} | ||
|
||
/** | ||
* Sets the minimum number of file uploads required. | ||
* | ||
* @param minValues - The minimum values that must be uploaded | ||
*/ | ||
public setMinValues(minValues: number) { | ||
this.data.min_values = minValues; | ||
return this; | ||
} | ||
|
||
/** | ||
* Clears the minimum values. | ||
*/ | ||
public clearMinValues() { | ||
this.data.min_values = undefined; | ||
return this; | ||
} | ||
|
||
/** | ||
* Sets the maximum number of file uploads required. | ||
* | ||
* @param maxValues - The maximum values that must be uploaded | ||
*/ | ||
public setMaxValues(maxValues: number) { | ||
this.data.max_values = maxValues; | ||
return this; | ||
} | ||
|
||
/** | ||
* Clears the maximum values. | ||
*/ | ||
public clearMaxValues() { | ||
this.data.max_values = undefined; | ||
return this; | ||
} | ||
|
||
/** | ||
* Sets whether this file upload is required. | ||
* | ||
* @param required - Whether this file upload is required | ||
*/ | ||
public setRequired(required = true) { | ||
this.data.required = required; | ||
return this; | ||
} | ||
|
||
/** | ||
* {@inheritDoc ComponentBuilder.toJSON} | ||
*/ | ||
public toJSON(validationOverride?: boolean): APIFileUploadComponent { | ||
const clone = structuredClone(this.data); | ||
validate(fileUploadPredicate, clone, validationOverride); | ||
|
||
return clone as APIFileUploadComponent; | ||
} | ||
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.