Skip to content
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

@uppy/core: reference updated i18n in Restricter #5118

Merged
merged 2 commits into from
Apr 29, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
26 changes: 15 additions & 11 deletions packages/@uppy/core/src/Restricter.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@
import prettierBytes from '@transloadit/prettier-bytes'
// @ts-ignore untyped
import match from 'mime-match'
import Translator from '@uppy/utils/lib/Translator'
import type { Body, Meta, UppyFile } from '@uppy/utils/lib/UppyFile'
import type { I18n } from '@uppy/utils/lib/Translator'
import type { State, NonNullableUppyOptions } from './Uppy'
Expand Down Expand Up @@ -58,12 +57,15 @@ class RestrictionError<M extends Meta, B extends Body> extends Error {
}

class Restricter<M extends Meta, B extends Body> {
i18n: Translator['translate']
getI18n: () => I18n

getOpts: () => NonNullableUppyOptions<M, B>

constructor(getOpts: () => NonNullableUppyOptions<M, B>, i18n: I18n) {
this.i18n = i18n
constructor(
getOpts: () => NonNullableUppyOptions<M, B>,
getI18n: () => I18n,
) {
this.getI18n = getI18n
this.getOpts = (): NonNullableUppyOptions<M, B> => {
const opts = getOpts()

Expand All @@ -88,7 +90,7 @@ class Restricter<M extends Meta, B extends Body> {
const nonGhostFiles = existingFiles.filter((f) => !f.isGhost)
if (nonGhostFiles.length + addingFiles.length > maxNumberOfFiles) {
throw new RestrictionError(
`${this.i18n('youCanOnlyUploadX', {
`${this.getI18n()('youCanOnlyUploadX', {
smart_count: maxNumberOfFiles,
})}`,
)
Expand All @@ -108,7 +110,7 @@ class Restricter<M extends Meta, B extends Body> {

if (totalFilesSize > maxTotalFileSize) {
throw new RestrictionError(
this.i18n('exceedsSize', {
this.getI18n()('exceedsSize', {
size: prettierBytes(maxTotalFileSize),
file: addingFile.name,
}),
Expand Down Expand Up @@ -141,7 +143,7 @@ class Restricter<M extends Meta, B extends Body> {
if (!isCorrectFileType) {
const allowedFileTypesString = allowedFileTypes.join(', ')
throw new RestrictionError(
this.i18n('youCanOnlyUploadFileTypes', {
this.getI18n()('youCanOnlyUploadFileTypes', {
types: allowedFileTypesString,
}),
{ file } as { file: UppyFile<M, B> },
Expand All @@ -152,7 +154,7 @@ class Restricter<M extends Meta, B extends Body> {
// We can't check maxFileSize if the size is unknown.
if (maxFileSize && file.size != null && file.size > maxFileSize) {
throw new RestrictionError(
this.i18n('exceedsSize', {
this.getI18n()('exceedsSize', {
size: prettierBytes(maxFileSize),
file: file.name,
}),
Expand All @@ -163,7 +165,7 @@ class Restricter<M extends Meta, B extends Body> {
// We can't check minFileSize if the size is unknown.
if (minFileSize && file.size != null && file.size < minFileSize) {
throw new RestrictionError(
this.i18n('inferiorSize', {
this.getI18n()('inferiorSize', {
size: prettierBytes(minFileSize),
}),
{ file } as { file: UppyFile<M, B> },
Expand All @@ -185,7 +187,9 @@ class Restricter<M extends Meta, B extends Body> {
const { minNumberOfFiles } = this.getOpts().restrictions
if (minNumberOfFiles && Object.keys(files).length < minNumberOfFiles) {
throw new RestrictionError(
this.i18n('youHaveToAtLeastSelectX', { smart_count: minNumberOfFiles }),
this.getI18n()('youHaveToAtLeastSelectX', {
smart_count: minNumberOfFiles,
}),
)
}
}
Expand All @@ -195,7 +199,7 @@ class Restricter<M extends Meta, B extends Body> {
error: RestrictionError<M, B>
} {
const error = new RestrictionError<M, B>(
this.i18n('missingRequiredMetaFieldOnFile', { fileName: file.name }),
this.getI18n()('missingRequiredMetaFieldOnFile', { fileName: file.name }),
)
const { requiredMetaFields } = this.getOpts().restrictions
const missingFields: string[] = []
Expand Down
32 changes: 32 additions & 0 deletions packages/@uppy/core/src/Uppy.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import fs from 'node:fs'
import path from 'node:path'
import prettierBytes from '@transloadit/prettier-bytes'
import type { Body, Meta } from '@uppy/utils/lib/UppyFile'
import type { Locale } from '@uppy/utils/lib/Translator'
import Core from './index.ts'
import UIPlugin from './UIPlugin.ts'
import BasePlugin, {
Expand Down Expand Up @@ -1540,6 +1541,18 @@ describe('src/Core', () => {
})

it('should change restrictions on the fly', () => {
const fr_FR: Locale<0 | 1> = {
strings: {
youCanOnlyUploadFileTypes:
'Vous pouvez seulement téléverser: %{types}',
},
pluralize(n) {
if (n <= 1) {
return 0
}
return 1
},
}
const core = new Core({
restrictions: {
allowedFileTypes: ['image/jpeg'],
Expand All @@ -1560,6 +1573,25 @@ describe('src/Core', () => {
}

core.setOptions({
locale: fr_FR,
})

try {
core.addFile({
source: 'vi',
name: 'foo1.png',
type: 'image/png',
// @ts-ignore
data: new File([sampleImage], { type: 'image/png' }),
})
} catch (err) {
expect(err).toMatchObject(
new Error('Vous pouvez seulement téléverser: image/jpeg'),
)
}

core.setOptions({
locale: fr_FR,
restrictions: {
allowedFileTypes: ['image/png'],
},
Expand Down
5 changes: 4 additions & 1 deletion packages/@uppy/core/src/Uppy.ts
Original file line number Diff line number Diff line change
Expand Up @@ -459,7 +459,10 @@ export class Uppy<M extends Meta, B extends Body> {
info: [],
})

this.#restricter = new Restricter<M, B>(() => this.opts, this.i18n)
this.#restricter = new Restricter<M, B>(
() => this.opts,
() => this.i18n,
)

this.#storeUnsubscribe = this.store.subscribe(
// eslint-disable-next-line
Expand Down
Loading