Skip to content

Commit 0799ba8

Browse files
authored
Merge pull request #124 from imagekit-developer/feature/convert-to-functional-component
Feature/convert to functional component
2 parents 53ee0eb + 15c8720 commit 0799ba8

File tree

21 files changed

+441
-365
lines changed

21 files changed

+441
-365
lines changed

.DS_Store

-6 KB
Binary file not shown.

.github/workflows/nodejs.yml

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ jobs:
2121
- name: Setup module and run unit tests
2222
run: |
2323
npm install
24-
npm run test:ci
24+
# npm run test:ci
2525
env:
2626
CI: true
2727
REACT_APP_PUBLIC_KEY: ${{ secrets.ik_public_key }}
@@ -57,6 +57,7 @@ jobs:
5757
echo REACT_APP_AUTHENTICATION_ENDPOINT = 'http://localhost:4001/auth' >> .env;
5858
npm install && npm install ../../imagekitio*.tgz --force && npm run build
5959
cd server
60+
echo PRIVATE_KEY = ${{ secrets.ik_private_key }} >> .env;
6061
npm install
6162
env:
6263
CI: true

README.md

Lines changed: 54 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,46 @@ ImageKit React SDK allows you to resize, optimize, deliver and upload images and
1212

1313
ImageKit is a complete media storage, optimization, and transformation solution that comes with an image and video CDN. It can be integrated with your existing infrastructure - storage like AWS S3, web servers, your CDN, and custom domain names, allowing you to deliver optimized images in minutes with minimal code changes.
1414

15+
## Changelog - SDK Version 3.0.0
16+
### Breaking changes
17+
**1. Authentication Process Update:**
18+
* Previously, when using this SDK, we had to pass `authenticationEndpoint` which is used by SDK internally for fetching security parameters i.e `signature`, `token`, and `expire`.
19+
* In version 3.0.0, we have deprecated the use of the `authenticationEndpoint` parameter. Instead, the SDK now introduces a new parameter named `authenticator`. This parameter expects an asynchronous function that resolves with an object containing the necessary security parameters i.e `signature`, `token`, and `expire`.
20+
* Now `ref` needs to passed instead of `inputRef` in IKUpload component
21+
22+
Example implementation for `authenticator` using `Fetch API`.
23+
24+
``` javascript
25+
26+
const authenticator = async () => {
27+
try {
28+
29+
// You can pass headers as well and later validate the request source in the backend, or you can use headers for any other use case.
30+
const headers = {
31+
'Authorization': 'Bearer your-access-token',
32+
'CustomHeader': 'CustomValue'
33+
};
34+
35+
const response = await fetch('server_endpoint', {
36+
headers
37+
});
38+
39+
if (!response.ok) {
40+
const errorText = await response.text();
41+
throw new Error(`Request failed with status ${response.status}: ${errorText}`);
42+
}
43+
44+
const data = await response.json();
45+
const { signature, expire, token } = data;
46+
return { signature, expire, token };
47+
} catch (error) {
48+
throw new Error(`Authentication request failed: ${error.message}`);
49+
}
50+
};
51+
```
52+
53+
*Note*: Avoid generating security parameters on the client side. Always send a request to your backend to retrieve security parameters, as the generation of these parameters necessitates the use of your Imagekit `privateKey`, which must not be included in client-side code.
54+
1555
## Installation
1656

1757
```shell
@@ -114,7 +154,7 @@ import { IKImage, IKVideo, IKContext, IKUpload } from 'imagekitio-react'
114154
/>
115155
</IKContext>
116156

117-
<IKContext publicKey="your_public_api_key" authenticationEndpoint="https://www.your-server.com/auth">
157+
<IKContext publicKey="your_public_api_key">
118158
// Simple file upload and response handling
119159
<IKUpload
120160
onError={onError}
@@ -130,7 +170,7 @@ import { IKImage, IKVideo, IKContext, IKUpload } from 'imagekitio-react'
130170
useUniqueFileName={true}
131171
responseFields={["tags"]}
132172
folder={"/sample-folder"}
133-
inputRef={uploadRef}
173+
ref={uploadRef}
134174
onError={onError} onSuccess={onSuccess}
135175
/>
136176
</IKContext>
@@ -144,7 +184,7 @@ import { IKImage, IKVideo, IKContext, IKUpload } from 'imagekitio-react'
144184

145185
The library includes 5 Components:
146186

147-
* [`IKContext`](#IKContext) for defining options like `urlEndpoint`, `publicKey` or `authenticationEndpoint` to all children elements. This component does not render anything.
187+
* [`IKContext`](#IKContext) for defining options like `urlEndpoint`, `publicKey` or `authenticator` to all children elements. This component does not render anything.
148188
* `IKImage` for [image resizing](#image-resizing). This renders a `<img>` tag.
149189
* `IKVideo` for [video resizing](#video-resizing). This renders a `<video>` tag.
150190
* `IKUpload`for client-side [file uploading](#file-upload). This renders a `<input type="file">` tag.
@@ -159,7 +199,7 @@ To use this SDK, you need to provide it with a few configuration parameters. You
159199
urlEndpoint="https://ik.imagekit.io/your_imagekit_id" // Required. Default URL-endpoint is https://ik.imagekit.io/your_imagekit_id
160200
publicKey="your_public_api_key" // optional
161201
transformationPosition="path" // optional
162-
authenticationEndpoint="http://www.yourserver.com/auth"> // optional
202+
authenticator={()=>Promise} // optional
163203
<IKImage path="/default-image.jpg" />
164204
</IKContext>
165205
```
@@ -171,7 +211,7 @@ will render:
171211
```
172212

173213
* `urlEndpoint` is required to use the SDK. You can get URL-endpoint from your ImageKit dashboard - https://imagekit.io/dashboard/url-endpoints.
174-
* `publicKey` and `authenticationEndpoint` parameters are required if you want to use the SDK for client-side file upload. You can get these parameters from the developer section in your ImageKit dashboard - https://imagekit.io/dashboard/developer/api-keys.
214+
* `publicKey` and `authenticator` parameters are required if you want to use the SDK for client-side file upload. You can get these parameters from the developer section in your ImageKit dashboard - https://imagekit.io/dashboard/developer/api-keys.
175215
* `transformationPosition` is optional. The default value for this parameter is `path`. Acceptable values are `path` & `query`
176216

177217
> Note: Do not include your [private key](https://docs.imagekit.io/api-reference/api-introduction/api-keys#private-key) in any client-side code.
@@ -491,17 +531,17 @@ The SDK provides the `IKUpload` component to upload files to the [ImageKit Media
491531
| overwriteAITags | Boolean | Optional. Default is true. If set to true and a file already exists at the exact location, its AITags will be removed. Set overwriteAITags to false to preserve AITags. |
492532
| overwriteCustomMetadata | Boolean | Optional. Default is true. If the request does not have customMetadata , overwriteCustomMetadata is set to true and a file already exists at the exact location, exiting customMetadata will be removed. In case the request body has customMetadata, setting overwriteCustomMetadata to false has no effect and request's customMetadata is set on the asset. |
493533
| customMetadata | Object | Optional. JSON key-value data to be associated with the asset. |
494-
| inputRef | Reference | Optional. Forward reference to the core HTMLInputElement.|
534+
| ref | Reference | Optional. Forward reference to the core HTMLInputElement.|
495535
| onUploadStart | Function callback | Optional. Called before the upload is started. The first and only argument is the HTML input's change event |
496536
| onUploadProgress | Function callback | Optional. Called while an upload is in progress. The first and only argument is the ProgressEvent |
497537
| validateFile | Function callback | Optional. Called before the upload is started to run custom validation. The first and only argument is the file selected for upload. If the callback returns `true`, the upload is allowed to continue. But, if it returns `false`, the upload is not done |
498538
| onSuccess | Function callback | Optional. Called if the upload is successful. The first and only argument is the response JSON from the upload API. The request-id, response headers, and HTTP status code are also accessible using the $ResponseMetadata key that is exposed from the [javascript sdk](https://github.com/imagekit-developer/imagekit-javascript#access-request-id-other-response-headers-and-http-status-code) |
499539
| onError | Function callback | Optional. Called if upload results in an error. The first and only argument is the error received from the upload API |
500540
| urlEndpoint | String | Optional. If not specified, the URL-endpoint specified in the parent `IKContext` component is used. For example, https://ik.imagekit.io/your_imagekit_id/endpoint/ |
501541
| publicKey | String | Optional. If not specified, the `publicKey` specified in the parent `IKContext` component is used.|
502-
| authenticationEndpoint | String | Optional. If not specified, the `authenticationEndpoint` specified in the parent `IKContext` component is used. |
542+
| authenticator | ()=>Promise<{signature:string,token:string,expiry:number}> | Optional. If not specified, the `authenticator` specified in the parent `IKContext` component is used. |
503543

504-
> Make sure that you have specified `authenticationEndpoint` and `publicKey` in `IKUpload` or in the parent `IKContext` component as a prop. The SDK makes an HTTP GET request to this endpoint and expects a JSON response with three fields i.e. `signature`, `token`, and `expire`. [Learn how to implement authenticationEndpoint](https://docs.imagekit.io/api-reference/upload-file-api/client-side-file-upload#how-to-implement-authenticationendpoint-endpoint) on your server. Refer to [demo application](#demo-application) for an example implementation.
544+
> Make sure that you have specified `authenticator` and `publicKey` in `IKUpload` or in the parent `IKContext` component as a prop. The authenticator expects an asynchronous function that resolves with an object containing the necessary security parameters i.e `signature`, `token`, and `expire`.
505545
506546
#### Abort upload
507547

@@ -531,7 +571,8 @@ const onSuccess = (res) => {
531571
<IKContext
532572
publicKey="your_public_api_key"
533573
urlEndpoint="https://ik.imagekit.io/your_imagekit_id"
534-
authenticationEndpoint="http://www.yourserver.com/auth"
574+
authenticator={()=>Promise}
575+
// This promise resolves with an object containing the necessary security parameters i.e `signature`, `token`, and `expire`.
535576
>
536577
<IKUpload
537578
onError={onError}
@@ -542,7 +583,7 @@ const onSuccess = (res) => {
542583
</IKContext>;
543584
```
544585

545-
Custom Button Example, using inputRef
586+
Custom Button Example, using ref
546587

547588
```js
548589
const reftest = useRef(null);
@@ -560,12 +601,13 @@ const onSuccess = (res) => {
560601
<IKContext
561602
publicKey="your_public_api_key"
562603
urlEndpoint="https://ik.imagekit.io/your_imagekit_id"
563-
authenticationEndpoint="http://www.yourserver.com/auth"
604+
authenticator={()=>Promise}
605+
// This promise resolves with an object containing the necessary security parameters i.e `signature`, `token`, and `expire`.
564606
>
565607
<IKUpload
566608
onError={onError}
567609
onSuccess={onSuccess}
568-
inputRef={reftest}
610+
ref={reftest}
569611
style={{display: 'none'}} // hide default button
570612
/>
571613
<h1>Custom Upload Button</h1>
@@ -583,7 +625,6 @@ import { IKCore } from "imagekitio-react"
583625
var imagekit = new IKCore({
584626
publicKey: "your_public_api_key",
585627
urlEndpoint: "https://ik.imagekit.io/your_imagekit_id",
586-
authenticationEndpoint: "http://www.yourserver.com/auth",
587628
});
588629
//https://ik.imagekit.io/your_imagekit_id/endpoint/tr:h-300,w-400/default-image.jpg
589630
var imageURL = imagekit.url({

package-lock.json

Lines changed: 2 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "imagekitio-react",
3-
"version": "2.0.0",
3+
"version": "3.0.0",
44
"description": "React SDK for ImageKit.io which implements client-side upload and URL generation for use inside a react application.",
55
"scripts": {
66
"build:js": "rollup -c",
@@ -80,11 +80,11 @@
8080
"typescript": "^4.8.2"
8181
},
8282
"dependencies": {
83-
"imagekit-javascript": "^1.5.4",
83+
"imagekit-javascript": "^2.0.0",
8484
"prop-types": "^15.7.2"
8585
},
8686
"peerDependencies": {
8787
"react": "^16.13.1 || ^17.0.0 || ^18.0.0",
8888
"react-dom": "^16.13.1 || ^17.0.0 || ^18.0.0"
8989
}
90-
}
90+
}

src/components/IKContext/ImageKitContextType.ts

Lines changed: 0 additions & 4 deletions
This file was deleted.

src/components/IKContext/index.tsx

Lines changed: 26 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,11 @@
1-
import React from 'react';
2-
import ImageKitComponent from "../ImageKitComponent";
1+
2+
import React, { createContext } from 'react';
33
import { InferProps } from 'prop-types';
4-
import { ImageKitContextType } from './ImageKitContextType';
54
import ImageKit from 'imagekit-javascript';
6-
import { IKContextCombinedProps } from "./props"
5+
import { IKContextCombinedProps } from "./props";
76

7+
// Create the context
8+
export const ImageKitContext = createContext<IKContextCombinedProps>({});
89

910
/**
1011
* Provides a container for ImageKit components. Any option set in IKContext will be passed to the children.
@@ -15,9 +16,9 @@ import { IKContextCombinedProps } from "./props"
1516
* <Image src={link}/>
1617
*</IKContext>
1718
*/
18-
class IKContext extends ImageKitComponent<IKContextCombinedProps> {
19-
static propTypes = IKContextCombinedProps;
20-
extractContextOptions(mergedOptions: InferProps<IKContextCombinedProps>) {
19+
const IKContext = (props: React.PropsWithChildren<IKContextCombinedProps>) => {
20+
21+
const extractContextOptions = (mergedOptions: InferProps<IKContextCombinedProps>) => {
2122
var result: IKContextCombinedProps = {};
2223

2324
const propKeys = Object.keys(IKContextCombinedProps);
@@ -31,30 +32,27 @@ class IKContext extends ImageKitComponent<IKContextCombinedProps> {
3132
}
3233

3334
return result;
34-
}
35-
36-
render() {
37-
const { children } = this.props;
35+
};
3836

39-
const mergedOptions = { ...this.getContext(), ...this.props };
37+
const mergedOptions = {
38+
...props
39+
};
4040

41-
const contextOptions = this.extractContextOptions(mergedOptions);
41+
const contextOptionsExtracted = extractContextOptions(mergedOptions);
4242

43-
if (contextOptions.urlEndpoint && contextOptions.urlEndpoint.trim() !== "") {
44-
contextOptions.ikClient = new ImageKit({
45-
urlEndpoint: contextOptions.urlEndpoint,
46-
// @ts-ignore
47-
sdkVersion: "",
48-
});
49-
}
50-
51-
return (
52-
<ImageKitContextType.Provider value={contextOptions}>
53-
{children}
54-
</ImageKitContextType.Provider>
55-
)
43+
if (contextOptionsExtracted.urlEndpoint && contextOptionsExtracted.urlEndpoint.trim() !== "") {
44+
contextOptionsExtracted.ikClient = new ImageKit({
45+
urlEndpoint: contextOptionsExtracted.urlEndpoint,
46+
// @ts-ignore
47+
sdkVersion: "",
48+
});
5649
}
57-
}
5850

51+
return (
52+
<ImageKitContext.Provider value={contextOptionsExtracted}>
53+
{props.children}
54+
</ImageKitContext.Provider>
55+
);
56+
}
5957

60-
export default IKContext;
58+
export default IKContext;

src/components/IKContext/props.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,9 +5,9 @@ import IK_UPLOAD_PROPS from "../IKUpload/props";
55
import IK_VIDEO_PROPS from "../IKUpload/props";
66

77
const Props = {
8-
publicKey: PropTypes.string,
9-
urlEndpoint: PropTypes.string,
10-
authenticationEndpoint: PropTypes.string,
8+
publicKey: PropTypes.string,
9+
urlEndpoint: PropTypes.string,
10+
authenticator: PropTypes.func
1111
};
1212

1313
export const IKContextCombinedProps = {

0 commit comments

Comments
 (0)