Skip to content

Commit

Permalink
Merge pull request #153 from imagekit-developer/IK-1418
Browse files Browse the repository at this point in the history
Override upload parameters
  • Loading branch information
imagekitio authored May 20, 2024
2 parents 055685f + c843890 commit e044714
Show file tree
Hide file tree
Showing 7 changed files with 179 additions and 103 deletions.
184 changes: 100 additions & 84 deletions README.md

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 2 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "imagekitio-react",
"version": "4.0.0",
"version": "4.1.0",
"description": "React SDK for ImageKit.io which implements client-side upload and URL generation for use inside a react application.",
"scripts": {
"build:js": "rollup -c",
Expand Down Expand Up @@ -87,4 +87,4 @@
"react": "^16.13.1 || ^17.0.0 || ^18.0.0",
"react-dom": "^16.13.1 || ^17.0.0 || ^18.0.0"
}
}
}
41 changes: 26 additions & 15 deletions src/components/IKUpload/index.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import React, { forwardRef, useContext, useEffect, useState } from 'react';
import { IKContextBaseProps } from "../IKContext/props";
import { IKUploadProps } from "./props";
import { IKUploadProps, OverrideValues } from "./props";
import { ImageKitContext } from '../IKContext';
import useImageKitComponent from '../ImageKitComponent';

Expand Down Expand Up @@ -50,6 +50,7 @@ const IKUpload = forwardRef<HTMLInputElement, IKUploadProps & IKContextBaseProps
extensions,
customMetadata,
transformation,
overrideParameters,
...restProps
} = props;

Expand All @@ -60,6 +61,7 @@ const IKUpload = forwardRef<HTMLInputElement, IKUploadProps & IKContextBaseProps
const urlEndpoint = props.urlEndpoint || contextOptions.urlEndpoint;

if (!publicKey || publicKey.trim() === "") {
console.error("Missing publicKey");
if (onError && typeof onError === "function") {
onError({
message: "Missing publicKey"
Expand All @@ -69,6 +71,7 @@ const IKUpload = forwardRef<HTMLInputElement, IKUploadProps & IKContextBaseProps
}

if (!authenticator) {
console.error("The authenticator function is not provided.");
if (onError && typeof onError === "function") {
onError({
message: "The authenticator function is not provided."
Expand All @@ -78,6 +81,7 @@ const IKUpload = forwardRef<HTMLInputElement, IKUploadProps & IKContextBaseProps
}

if (typeof authenticator !== 'function') {
console.error("The provided authenticator is not a function.");
if (onError && typeof onError === "function") {
onError({
message: "The provided authenticator is not a function."
Expand All @@ -87,6 +91,7 @@ const IKUpload = forwardRef<HTMLInputElement, IKUploadProps & IKContextBaseProps
}

if (!urlEndpoint || urlEndpoint.trim() === "") {
console.error("Missing urlEndpoint");
if (onError && typeof onError === "function") {
onError({
message: "Missing urlEndpoint"
Expand All @@ -110,6 +115,12 @@ const IKUpload = forwardRef<HTMLInputElement, IKUploadProps & IKContextBaseProps
props.onUploadStart(e);
}

let overrideValues: OverrideValues = {};

if (props.overrideParameters && typeof props.overrideParameters === 'function') {
overrideValues = props.overrideParameters(file) || {};
}

const xhr = new XMLHttpRequest();
const progressCb = (e: ProgressEvent<XMLHttpRequestEventTarget>) => {
if (props.onUploadProgress && typeof props.onUploadProgress === 'function') {
Expand All @@ -121,25 +132,25 @@ const IKUpload = forwardRef<HTMLInputElement, IKUploadProps & IKContextBaseProps

var params = {
file: file,
fileName: fileName || file.name,
useUniqueFileName,
tags,
folder,
isPrivateFile,
customCoordinates,
fileName: overrideValues.fileName || fileName || file.name,
useUniqueFileName: overrideValues.useUniqueFileName || useUniqueFileName,
tags: overrideValues.tags || tags,
folder: overrideValues.folder || folder,
isPrivateFile: overrideValues.isPrivateFile || isPrivateFile,
customCoordinates: overrideValues.customCoordinates || customCoordinates,
responseFields,
extensions,
webhookUrl,
overwriteFile,
overwriteAITags,
overwriteTags,
overwriteCustomMetadata,
customMetadata,
extensions: overrideValues.extensions || extensions,
webhookUrl: overrideValues.webhookUrl || webhookUrl,
overwriteFile: overrideValues.overwriteFile || overwriteFile,
overwriteAITags: overrideValues.overwriteAITags || overwriteAITags,
overwriteTags: overrideValues.overwriteTags || overwriteTags,
overwriteCustomMetadata: overrideValues.overwriteCustomMetadata || overwriteCustomMetadata,
customMetadata: overrideValues.customMetadata || customMetadata,
signature: '',
expire: 0,
token: '',
xhr,
transformation,
transformation: overrideValues.transformation || transformation,
};

const authPromise = authenticator();
Expand Down
19 changes: 19 additions & 0 deletions src/components/IKUpload/props.ts
Original file line number Diff line number Diff line change
Expand Up @@ -70,8 +70,26 @@ const Props = {
validateFile: PropTypes.func,
ref: PropTypes.any,
transformation: PropTypes.object,
overrideParameters: PropTypes.func,
}

export type OverrideValues = {
fileName?: IKUploadProps['fileName'];
useUniqueFileName?: IKUploadProps['useUniqueFileName'];
tags?: IKUploadProps['tags'];
folder?: IKUploadProps['folder'];
isPrivateFile?: IKUploadProps['isPrivateFile'];
customCoordinates?: IKUploadProps['customCoordinates'];
extensions?: IKUploadProps['extensions'];
webhookUrl?: IKUploadProps['webhookUrl'];
overwriteFile?: IKUploadProps['overwriteFile'];
overwriteAITags?: IKUploadProps['overwriteAITags'];
overwriteTags?: IKUploadProps['overwriteTags'];
overwriteCustomMetadata?: IKUploadProps['overwriteCustomMetadata'];
customMetadata?: IKUploadProps['customMetadata'];
transformation?: IKUploadProps['transformation'];
};

export type IKUploadProps = Omit<InferProps<typeof Props>, "customMetadata" | "transformation"> & {
useUniqueFileName?: boolean;
tags?: Array<string>;
Expand All @@ -92,6 +110,7 @@ export type IKUploadProps = Omit<InferProps<typeof Props>, "customMetadata" | "t
onUploadProgress?: (evt: ProgressEvent<XMLHttpRequestEventTarget>) => void;
validateFile?: (file: File) => boolean;
transformation?: TransformationType;
overrideParameters?: (file: File) => OverrideValues;
} & React.InputHTMLAttributes<HTMLInputElement>;

export default Props;
13 changes: 12 additions & 1 deletion tests/cypress/integration/IKUpload.cy.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,12 +12,23 @@ describe('IKUpload Element', () => {
//upload file with attachFile
cy.get('.file-upload-ik').attachFile(p)

// wait for 2 secs
// wait for 4 secs
cy.wait(4000);

//Verify uploaded file
cy.get('.uploaded-img-ik').should('have.attr', 'src');
cy.get('.uploaded-img-ik').invoke('attr', 'src').should('not.equal', '');


// wait for 4 secs
cy.wait(4000);

cy.get('.state-value').invoke('val').then((val) => {
const stateValue = JSON.parse(val);
cy.log(JSON.stringify(stateValue, null, 2));
expect(stateValue.overrideParametersValue.fileNameOnLocalSystem).to.be.eq("sample.jpeg"); // This asserts that the file object was passed to the onOverrideParameters callback
expect(stateValue.uploadedImageSource).contains("sample-folder/overridden-file-name"); // This asserts that onOverrideParameters changed fileName parameter before upload
});
});

it.skip('should upload non-image file and try to get error element', () => {
Expand Down
19 changes: 19 additions & 0 deletions tests/test-app/src/App.js
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ function App() {
"height": "300",
"width": "300"
}]);
const [overrideParametersValue, setoverrideParametersValue] = useState();

const path = "default-image.jpg";
const videoUrlEndpoint = 'https://ik.imagekit.io/demo/';
Expand Down Expand Up @@ -69,8 +70,25 @@ function App() {
setUploadProgress(e)
}

const onOverrideParameters = (file) => {
setoverrideParametersValue({
fileNameOnLocalSystem: file.name,
})
return {
fileName: 'overridden-file-name.jpg'
}
}

return (
<div className="App">
<input type="text" className="state-value" value={JSON.stringify({
error,
isUploading,
uploadProgress,
uploadedImageSource,
imageTr,
overrideParametersValue
})} style={{ display: 'none' }}></input>
<h1>Hi! This is an ImageKit React SDK Demo!</h1>

<p>Directly using <code>IkImage</code></p>
Expand Down Expand Up @@ -185,6 +203,7 @@ function App() {
className="file-upload-ik"
onUploadProgress={onUploadProgress}
onUploadStart={onUploadStart}
overrideParameters={onOverrideParameters}
/>
{isUploading !== null ? <p>{isUploading ? `...Uploading (${uploadProgress ? uploadProgress.type ? (uploadProgress.loaded / uploadProgress.total * 100).toFixed(2) + '%)' : '' : ''}` : 'uploaded'}</p> : <></>}
{isUploading ? <button onClick={() => {
Expand Down

0 comments on commit e044714

Please sign in to comment.