Skip to content
Merged
Show file tree
Hide file tree
Changes from 8 commits
Commits
Show all changes
42 commits
Select commit Hold shift + click to select a range
f2ce24b
feat: add upload progress callback and abort signal support
manu4543 Apr 2, 2025
10ae4cd
feat: implement abort signal support and upload progress tracking in …
manu4543 Apr 2, 2025
b4daa29
add test cases for onProgress and abort
manu4543 Apr 2, 2025
09c47d2
expose url, upload static functions. Other updates
manu4543 Apr 3, 2025
990cf29
update test cases
manu4543 Apr 3, 2025
b15ed76
refactor: update test descriptions to use 'src' instead of 'path'
manu4543 Apr 3, 2025
74b3073
refactor: update export types and remove unused ImageKitOptions inter…
manu4543 Apr 4, 2025
9341aa2
working upload test cases
manu4543 Apr 4, 2025
af7bef3
update node js version and build libs
manu4543 Apr 5, 2025
9ad887e
fix: enable terser for code minification in rollup configuration
manu4543 Apr 5, 2025
c2edc0b
fix: update codecov version to 3.8.3 and modify coverage reporting sc…
manu4543 Apr 5, 2025
cb7c135
ci: add Codecov upload step to GitHub Actions workflow
manu4543 Apr 5, 2025
b40208d
fix: remove coverage reporting step from startSampleApp script
manu4543 Apr 5, 2025
990b74d
test: add upload error handling tests for abort signal and invalid re…
manu4543 Apr 5, 2025
4d30974
improve test coverage
manu4543 Apr 5, 2025
bbe982b
chore: update package version to 5.0.0.beta.1 and add .npmignore
manu4543 Apr 6, 2025
ed16142
refactor: remove IKResponse interface and update related imports; int…
manu4543 Apr 6, 2025
c989e4a
refactor: update package name to @imagekit/javascript and modify desc…
manu4543 Apr 6, 2025
0b1463e
chore: add publishConfig with beta tag in package.json
manu4543 Apr 6, 2025
aae9934
update readme
manu4543 Apr 6, 2025
b7018e2
refactor: rename signal to abortSignal in upload options and update J…
manu4543 Apr 6, 2025
200fb8f
fix: update documentation link to point to the live ImageKit site
manu4543 Apr 6, 2025
a7655f4
refactor: re-export all interfaces for improved TypeDoc documentation
manu4543 Apr 6, 2025
7e3d812
fix links in JSDocs
manu4543 Apr 6, 2025
064596c
fix: correct version format in package.json and package-lock.json
manu4543 Apr 6, 2025
27a92f2
fix: update version to 5.0.0-beta.2 and adjust publish configuration
manu4543 Apr 6, 2025
b59f621
fix: update version to 5.0.0-beta.3 and enhance npm publish workflow
manu4543 Apr 6, 2025
8d31d57
test: add assertion for requestId in file upload response
manu4543 Apr 7, 2025
42345c3
refactor: remove unused error messages and delete test data file
manu4543 Apr 7, 2025
6b32005
test: add unit tests for buildTransformationString function
manu4543 Apr 7, 2025
814af9d
fix: update version to 5.0.0-beta.4 in package.json and package-lock.…
manu4543 Apr 7, 2025
c6b9f80
fix: update version to 5.0.0-beta.5 in package.json and package-lock.…
manu4543 Apr 7, 2025
0efc78d
fix: make encoding property optional in overlay interfaces
manu4543 Apr 7, 2025
4721a80
fix: update version to 5.0.0-beta.6 in package.json and package-lock.…
manu4543 Apr 8, 2025
dc4e067
Revert "fix: update version to 5.0.0-beta.6 in package.json and packa…
manu4543 Apr 8, 2025
32c07ce
fix: update version to 5.0.0-beta.6 in package.json and package-lock.…
manu4543 Apr 8, 2025
e6308cb
fix: replace formData.append with formData.set for upload options
manu4543 Apr 8, 2025
63ebc6d
Update src/interfaces/UploadOptions.ts
imagekitio Apr 10, 2025
d8a2d11
Update src/interfaces/UploadOptions.ts
imagekitio Apr 10, 2025
d3e5718
fix: change imports to type imports for better type checking
manu4543 Apr 10, 2025
b76ba5e
fix: update version to 5.0.0 in package.json and package-lock.json
manu4543 Apr 11, 2025
3153f03
fix: remove src from files array in package.json
manu4543 Apr 11, 2025
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
2 changes: 0 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -75,8 +75,6 @@ var imagekit = new ImageKit({
});
```

> Note: Never include your private API key in client-side code. The SDK will throw an error if you do.

### Initialization Options

| Option | Description | Example |
Expand Down
6 changes: 6 additions & 0 deletions package-lock.json

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

3 changes: 2 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
"@rollup/plugin-node-resolve": "^8.4.0",
"@rollup/plugin-typescript": "^8.2.1",
"@types/node": "^15.6.1",
"abortcontroller-polyfill": "^1.7.8",
"babel-plugin-transform-class-properties": "^6.24.1",
"chai": "^4.2.0",
"codecov": "^3.8.0",
Expand All @@ -43,7 +44,7 @@
"dev": "rollup -c -w",
"export-types": "tsc",
"build": "rm -rf dist*;rollup -c && yarn export-types",
"test": "NODE_ENV=test nyc ./node_modules/mocha/bin/mocha \"test/**/*.js\"",
"test": "NODE_ENV=test nyc ./node_modules/mocha/bin/mocha --require ./test/setup.js \"test/**/*.js\"",
"startSampleApp": "yarn build && cd samples/sample-app/ && yarn install && node index.js",
"report-coverage": "codecov"
},
Expand Down
7 changes: 3 additions & 4 deletions rollup.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,7 @@ export default [
output: {
name: "ImageKit",
file: pkg.browser,
format: "umd",
sourceMap: true,
format: "umd"
},
plugins: [
nodeResolve({ extensions: [".ts"] }),
Expand All @@ -34,8 +33,8 @@ export default [
{
input: "src/index.ts",
output: [
{ file: pkg.main, format: "cjs", exports: "default" },
{ file: pkg.module, format: "es", exports: "default" },
{ file: pkg.main, format: "cjs", exports: "named" },
{ file: pkg.module, format: "es", exports: "named" },
],
plugins: [
nodeResolve({ extensions: [".ts"] }),
Expand Down
9 changes: 9 additions & 0 deletions samples/sample-app/views/index.pug
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ html
script(type='text/javascript' src="./imagekit.min.js")
script.
try {
window.controller = new AbortController();
var imagekit = new ImageKit({
publicKey: "!{publicKey}",
urlEndpoint: "!{urlEndpoint}",
Expand Down Expand Up @@ -51,9 +52,11 @@ html
var statusEl = document.getElementById("status");
statusEl.innerHTML = "Uploading...";


// Use this if you want to track upload progress
var customXHR = new XMLHttpRequest();
customXHR.upload.addEventListener('progress', function (e) {
console.log("On progress event handler from customXHR");
if (e.loaded <= fileSize) {
var percent = Math.round(e.loaded / fileSize * 100);
console.log(`Uploaded ${percent}%`);
Expand Down Expand Up @@ -94,6 +97,11 @@ html
token: securityParametersObj.token,
signature: securityParametersObj.signature,
expire: securityParametersObj.expire,
signal: window.controller.signal,
onProgress: function(e) {
console.log("On progress event handler from SDK");
console.log(e.loaded);
},
//- extensions: [
//- {
//- name: "aws-auto-tagging",
Expand All @@ -102,6 +110,7 @@ html
//- }
//- ],
}, function(err, result) {
debugger;
if (err) {
statusEl.innerHTML = "Error uploading image. "+ err.message;
console.log(err)
Expand Down
40 changes: 20 additions & 20 deletions src/constants/errorMessages.ts
Original file line number Diff line number Diff line change
@@ -1,24 +1,24 @@
export default {
MANDATORY_INITIALIZATION_MISSING: { message: "Missing urlEndpoint during SDK initialization", help: "" },
INVALID_TRANSFORMATION_POSITION: { message: "Invalid transformationPosition parameter", help: "" },
PRIVATE_KEY_CLIENT_SIDE: { message: "privateKey should not be passed on the client side", help: "" },
MISSING_UPLOAD_DATA: { message: "Missing data for upload", help: "" },
MISSING_UPLOAD_FILE_PARAMETER: { message: "Missing file parameter for upload", help: "" },
MISSING_UPLOAD_FILENAME_PARAMETER: { message: "Missing fileName parameter for upload", help: "" },
MISSING_AUTHENTICATION_ENDPOINT: { message: "Missing authentication endpoint for upload", help: "" },
MISSING_PUBLIC_KEY: { message: "Missing public key for upload", help: "" },
AUTH_ENDPOINT_TIMEOUT: { message: "The authenticationEndpoint you provided timed out in 60 seconds", help: "" },
AUTH_ENDPOINT_NETWORK_ERROR: { message: "Request to authenticationEndpoint failed due to network error", help: "" },
AUTH_INVALID_RESPONSE: { message: "Invalid response from authenticationEndpoint. The SDK expects a JSON response with three fields i.e. signature, token and expire.", help: "" },
MANDATORY_INITIALIZATION_MISSING: { message: "Missing urlEndpoint during SDK initialization" },
INVALID_TRANSFORMATION_POSITION: { message: "Invalid transformationPosition parameter" },
PRIVATE_KEY_CLIENT_SIDE: { message: "privateKey should not be passed on the client side" },
MISSING_UPLOAD_DATA: { message: "Missing data for upload" },
MISSING_UPLOAD_FILE_PARAMETER: { message: "Missing file parameter for upload" },
MISSING_UPLOAD_FILENAME_PARAMETER: { message: "Missing fileName parameter for upload" },
MISSING_AUTHENTICATION_ENDPOINT: { message: "Missing authentication endpoint for upload" },
MISSING_PUBLIC_KEY: { message: "Missing public key for upload" },
AUTH_ENDPOINT_TIMEOUT: { message: "The authenticationEndpoint you provided timed out in 60 seconds" },
AUTH_ENDPOINT_NETWORK_ERROR: { message: "Request to authenticationEndpoint failed due to network error" },
AUTH_INVALID_RESPONSE: { message: "Invalid response from authenticationEndpoint. The SDK expects a JSON response with three fields i.e. signature, token and expire." },
UPLOAD_ENDPOINT_NETWORK_ERROR: {
message: "Request to ImageKit upload endpoint failed due to network error",
help: "",
message: "Request to ImageKit upload endpoint failed due to network error"
},
INVALID_UPLOAD_OPTIONS: { message: "Invalid uploadOptions parameter", help: "" },
MISSING_SIGNATURE: { message: "Missing signature for upload. The SDK expects token, signature and expire for authentication.", help: ""},
MISSING_TOKEN: { message: "Missing token for upload. The SDK expects token, signature and expire for authentication.", help: ""},
MISSING_EXPIRE: { message: "Missing expire for upload. The SDK expects token, signature and expire for authentication.", help: ""},
INVALID_TRANSFORMATION: { message: "Invalid transformation parameter. Please include at least pre, post, or both.", help: ""},
INVALID_PRE_TRANSFORMATION: { message: "Invalid pre transformation parameter.", help: ""},
INVALID_POST_TRANSFORMATION: { message: "Invalid post transformation parameter.", help: ""},
INVALID_UPLOAD_OPTIONS: { message: "Invalid uploadOptions parameter" },
MISSING_SIGNATURE: { message: "Missing signature for upload. The SDK expects token, signature and expire for authentication." },
MISSING_TOKEN: { message: "Missing token for upload. The SDK expects token, signature and expire for authentication." },
MISSING_EXPIRE: { message: "Missing expire for upload. The SDK expects token, signature and expire for authentication." },
INVALID_TRANSFORMATION: { message: "Invalid transformation parameter. Please include at least pre, post, or both." },
INVALID_PRE_TRANSFORMATION: { message: "Invalid pre transformation parameter." },
INVALID_POST_TRANSFORMATION: { message: "Invalid post transformation parameter." },
UPLOAD_ABORTED: { message: "Request aborted by the user" },
};
96 changes: 8 additions & 88 deletions src/index.ts
Original file line number Diff line number Diff line change
@@ -1,91 +1,11 @@
import { version } from "../package.json";
import errorMessages from "./constants/errorMessages";
import { ImageKitOptions, UploadOptions, UploadResponse, UrlOptions } from "./interfaces";
import IKResponse from "./interfaces/IKResponse";
import { upload } from "./upload/index";
import respond from "./utils/respond";
import { url } from "./url/index";
import transformationUtils from "./utils/transformation";
import { UploadOptions, UploadResponse, UrlOptions } from "./interfaces";
import { upload } from "./upload";
import { buildURL, generateTransformationString } from "./url";

function mandatoryParametersAvailable(options: ImageKitOptions) {
return options.urlEndpoint;
}
export { buildURL, generateTransformationString, upload };

const promisify = function <T = void>(thisContext: ImageKit, fn: Function) {
return function (...args: any[]): Promise<T> | void {
if (args.length === fn.length && typeof args[args.length - 1] !== "undefined") {
if (typeof args[args.length - 1] !== "function") {
throw new Error("Callback must be a function.");
}
fn.call(thisContext, ...args);
} else {
return new Promise<T>((resolve, reject) => {
const callback = function (err: Error, ...results: any[]) {
if (err) {
return reject(err);
} else {
resolve(results.length > 1 ? results : results[0]);
}
};
args.pop()
args.push(callback);
fn.call(thisContext, ...args);
});
}
};
export type {
UrlOptions,
UploadOptions,
UploadResponse
};

class ImageKit {
options: ImageKitOptions = {
publicKey: "",
urlEndpoint: "",
transformationPosition: transformationUtils.getDefault(),
};

constructor(opts: ImageKitOptions) {
this.options = { ...this.options, ...(opts || {}) };
if (!mandatoryParametersAvailable(this.options)) {
throw errorMessages.MANDATORY_INITIALIZATION_MISSING;
}

if (!transformationUtils.validParameters(this.options)) {
throw errorMessages.INVALID_TRANSFORMATION_POSITION;
}
}

/**
* A utility function to generate asset URL. It applies the specified transformations and other parameters to the URL.
*/
url(urlOptions: UrlOptions): string {
return url(urlOptions, this.options);
}

/**
* For uploading files directly from the browser to ImageKit.io.
*
* {@link https://imagekit.io/docs/api-reference/upload-file/upload-file#how-to-implement-client-side-file-upload}
*/
upload(uploadOptions: UploadOptions, options?: Partial<ImageKitOptions>): Promise<IKResponse<UploadResponse>>
upload(uploadOptions: UploadOptions, callback: (err: Error | null, response: IKResponse<UploadResponse> | null) => void, options?: Partial<ImageKitOptions>): void;
upload(uploadOptions: UploadOptions, callbackOrOptions?: ((err: Error | null, response: IKResponse<UploadResponse> | null) => void) | Partial<ImageKitOptions>, options?: Partial<ImageKitOptions>): void | Promise<IKResponse<UploadResponse>> {
let callback;
if (typeof callbackOrOptions === 'function') {
callback = callbackOrOptions;
} else {
options = callbackOrOptions || {};
}
if (!uploadOptions || typeof uploadOptions !== "object") {
return respond(true, errorMessages.INVALID_UPLOAD_OPTIONS, callback);
}
var mergedOptions = {
...this.options,
...options,
};
const { xhr: userProvidedXHR } = uploadOptions || {};
delete uploadOptions.xhr;
const xhr = userProvidedXHR || new XMLHttpRequest();
return promisify<IKResponse<UploadResponse>>(this, upload)(xhr, uploadOptions, mergedOptions, callback);
}
}

export default ImageKit;
7 changes: 0 additions & 7 deletions src/interfaces/ImageKitOptions.ts

This file was deleted.

36 changes: 28 additions & 8 deletions src/interfaces/UploadOptions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ interface AbsObject {

type PostTransformation = TransformationObject | GifToVideoOrThumbnailObject | AbsObject;

interface Transformation{
interface Transformation {
pre?: string
post?: PostTransformation[]
}
Expand All @@ -35,28 +35,38 @@ export interface UploadOptions {
* Pass the full URL, for example - https://www.example.com/rest-of-the-image-path.jpg.
*/
file: string | Blob | File;

/**
* The name with which the file has to be uploaded.
* The file name can contain:
* - Alphanumeric Characters: a-z , A-Z , 0-9 (including unicode letters, marks, and numerals in other languages)
* - Special Characters: . _ and -
* Any other character including space will be replaced by _
*/
fileName: string;

/**
* HMAC-SHA1 digest of the token+expire using your ImageKit.io private API key as a key. This should be in lowercase.
* Warning: Signature must be calculated on the server-side. This field is required for authentication when uploading a file from the client-side.
*/
signature: string;

/**
* A unique value generated by the client, which will be used by the ImageKit.io server to recognize and prevent subsequent retries for the same request. We suggest using V4 UUIDs, or another random string with enough entropy to avoid collisions.
* Note: Sending a value that has been used in the past will result in a validation error. Even if your previous request resulted in an error, you should always send a new value for this field.
*/
token: string;

/**
* The time until your signature is valid. It must be a Unix time in less than 1 hour into the future. It should be in seconds.
*/
expire: number;

/**
* The name with which the file has to be uploaded.
* The file name can contain:
* - Alphanumeric Characters: a-z , A-Z , 0-9 (including unicode letters, marks, and numerals in other languages)
* - Special Characters: . _ and -
* Any other character including space will be replaced by _
* The public API key of your ImageKit account. You can find it in the [ImageKit dashboard](https://imagekit.io/dashboard/developer/api-keys).
*/
fileName: string;
publicKey: string;

/**
* Whether to use a unique filename for this file or not.
* - Accepts true or false.
Expand Down Expand Up @@ -145,5 +155,15 @@ export interface UploadOptions {
/**
* Optional `checks` parameters can be used to run server-side checks before files are uploaded to the Media Library.
*/
checks?: string
checks?: string;

/**
* Optional callback function that will be called with the progress event when the file is being uploaded.
*/
onProgress?: (event: ProgressEvent) => void;

/**
* Optional AbortSignal object that can be used to abort the upload request
*/
signal?: AbortSignal;
}
Loading