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/compressor: migrate to TS #4907

Merged
merged 3 commits into from
Feb 12, 2024
Merged
Show file tree
Hide file tree
Changes from 1 commit
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
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,11 @@ import Core from '@uppy/core'
import getFileNameAndExtension from '@uppy/utils/lib/getFileNameAndExtension'
import fs from 'node:fs'
import path from 'node:path'
import CompressorPlugin from './index.js'
import CompressorPlugin from './index.ts'

// Compressor uses browser canvas API, so need to mock compress()
CompressorPlugin.prototype.compress = (blob) => {
// @ts-expect-error mocked
CompressorPlugin.prototype.compress = async (blob: Blob) => {
return {
name: `${getFileNameAndExtension(blob.name).name}.webp`,
type: 'image/webp',
Expand All @@ -16,11 +17,28 @@ CompressorPlugin.prototype.compress = (blob) => {
}

// eslint-disable-next-line no-restricted-globals
const sampleImage = fs.readFileSync(path.join(__dirname, '../../../../e2e/cypress/fixtures/images/image.jpg'))
const sampleImage = fs.readFileSync(
path.join(__dirname, '../../../../e2e/cypress/fixtures/images/image.jpg'),
)

const file1 = { source: 'jest', name: 'image-1.jpeg', type: 'image/jpeg', data: new File([sampleImage], 'image-1.jpeg', { type: 'image/jpeg' }) }
const file2 = { source: 'jest', name: 'yolo', type: 'image/jpeg', data: new File([sampleImage], 'yolo', { type: 'image/jpeg' }) }
const file3 = { source: 'jest', name: 'my.file.is.weird.png', type: 'image/png', data: new File([sampleImage], 'my.file.is.weird.png', { type: 'image/png' }) }
const file1 = {
source: 'jest',
name: 'image-1.jpeg',
type: 'image/jpeg',
data: new File([sampleImage], 'image-1.jpeg', { type: 'image/jpeg' }),
}
const file2 = {
source: 'jest',
name: 'yolo',
type: 'image/jpeg',
data: new File([sampleImage], 'yolo', { type: 'image/jpeg' }),
}
const file3 = {
source: 'jest',
name: 'my.file.is.weird.png',
type: 'image/png',
data: new File([sampleImage], 'my.file.is.weird.png', { type: 'image/png' }),
}

describe('CompressorPlugin', () => {
it('should change update extension in file.name and file.meta.name', () => {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,14 +1,34 @@
import { BasePlugin } from '@uppy/core'
import { BasePlugin, Uppy } from '@uppy/core'
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-ignore
import { RateLimitedQueue } from '@uppy/utils/lib/RateLimitedQueue'
import getFileNameAndExtension from '@uppy/utils/lib/getFileNameAndExtension'
import prettierBytes from '@transloadit/prettier-bytes'
import CompressorJS from 'compressorjs'
import locale from './locale.js'

export default class Compressor extends BasePlugin {
import type { Body, Meta, UppyFile } from '@uppy/utils/lib/UppyFile'
import type { PluginOpts } from '@uppy/core/lib/BasePlugin.ts'

import locale from './locale.ts'

declare module '@uppy/core' {
export interface UppyEventMap<M extends Meta, B extends Body> {
'compressor:complete': (file: UppyFile<M, B>[]) => void
}
}

interface Options extends PluginOpts, CompressorJS.Options {
quality: number
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We want export ops for users and our naming pattern has been plugin name + Opts.

Suggested change
interface Options extends PluginOpts, CompressorJS.Options {
export interface CompressorOpts extends PluginOpts, CompressorJS.Options {

limit?: number
}

export default class Compressor<
M extends Meta,
B extends Body,
> extends BasePlugin<Options, M, B> {
#RateLimitedQueue

constructor (uppy, opts) {
constructor(uppy: Uppy<M, B>, opts: Options) {
super(uppy, opts)
this.id = this.opts.id || 'Compressor'
this.type = 'modifier'
Expand All @@ -30,7 +50,7 @@ export default class Compressor extends BasePlugin {
this.compress = this.compress.bind(this)
}

compress (blob) {
compress(blob: Blob): Promise<Blob | File> {
return new Promise((resolve, reject) => {
/* eslint-disable no-new */
new CompressorJS(blob, {
Expand All @@ -41,15 +61,17 @@ export default class Compressor extends BasePlugin {
})
}

async prepareUpload (fileIDs) {
async prepareUpload(fileIDs: string[]): Promise<void> {
let totalCompressedSize = 0
const compressedFiles = []
const compressedFiles: UppyFile<M, B>[] = []
const compressAndApplyResult = this.#RateLimitedQueue.wrapPromiseFunction(
async (file) => {
async (file: UppyFile<M, B>) => {
try {
const compressedBlob = await this.compress(file.data)
const compressedSavingsSize = file.data.size - compressedBlob.size
this.uppy.log(`[Image Compressor] Image ${file.id} compressed by ${prettierBytes(compressedSavingsSize)}`)
this.uppy.log(
`[Image Compressor] Image ${file.id} compressed by ${prettierBytes(compressedSavingsSize)}`,
)
totalCompressedSize += compressedSavingsSize
const { name, type, size } = compressedBlob

Expand All @@ -61,7 +83,9 @@ export default class Compressor extends BasePlugin {

this.uppy.setFileState(file.id, {
...(name && { name }),
...(compressedFileName.extension && { extension: compressedFileName.extension }),
...(compressedFileName.extension && {
extension: compressedFileName.extension,
}),
...(type && { type }),
...(size && { size }),
data: compressedBlob,
Expand All @@ -73,7 +97,10 @@ export default class Compressor extends BasePlugin {
})
compressedFiles.push(file)
} catch (err) {
this.uppy.log(`[Image Compressor] Failed to compress ${file.id}:`, 'warning')
this.uppy.log(
`[Image Compressor] Failed to compress ${file.id}:`,
'warning',
)
this.uppy.log(err, 'warning')
}
},
Expand All @@ -97,7 +124,7 @@ export default class Compressor extends BasePlugin {
file.data = file.data.slice(0, file.data.size, file.type)
}

if (!file.type.startsWith('image/')) {
if (!file.type?.startsWith('image/')) {
return Promise.resolve()
}

Expand Down Expand Up @@ -128,11 +155,11 @@ export default class Compressor extends BasePlugin {
}
}

install () {
install(): void {
this.uppy.addPreProcessor(this.prepareUpload)
}

uninstall () {
uninstall(): void {
this.uppy.removePreProcessor(this.prepareUpload)
}
}
25 changes: 25 additions & 0 deletions packages/@uppy/compressor/tsconfig.build.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
{
"extends": "../../../tsconfig.shared",
"compilerOptions": {
"noImplicitAny": false,
"outDir": "./lib",
"paths": {
"@uppy/utils/lib/*": ["../utils/src/*"],
"@uppy/core": ["../core/src/index.js"],
"@uppy/core/lib/*": ["../core/src/*"]
},
"resolveJsonModule": false,
"rootDir": "./src",
"skipLibCheck": true
},
"include": ["./src/**/*.*"],
"exclude": ["./src/**/*.test.ts"],
"references": [
{
"path": "../utils/tsconfig.build.json"
},
{
"path": "../core/tsconfig.build.json"
}
]
}
21 changes: 21 additions & 0 deletions packages/@uppy/compressor/tsconfig.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
{
"extends": "../../../tsconfig.shared",
"compilerOptions": {
"emitDeclarationOnly": false,
"noEmit": true,
"paths": {
"@uppy/utils/lib/*": ["../utils/src/*"],
"@uppy/core": ["../core/src/index.js"],
"@uppy/core/lib/*": ["../core/src/*"],
},
},
"include": ["./package.json", "./src/**/*.*"],
"references": [
{
"path": "../utils/tsconfig.build.json",
},
{
"path": "../core/tsconfig.build.json",
},
],
}
2 changes: 1 addition & 1 deletion packages/@uppy/utils/src/FileProgress.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ export interface DeterminateFileProcessing {
}
export interface IndeterminateFileProcessing {
mode: 'indeterminate'
message?: undefined
message?: string
value?: 0
}
export type FileProcessingInfo =
Expand Down
Loading