Skip to content

Commit 342f0bf

Browse files
committed
Initial commit.
0 parents  commit 342f0bf

File tree

6 files changed

+383
-0
lines changed

6 files changed

+383
-0
lines changed

.gitattributes

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
/.gitattributes export-ignore
2+
/.gitignore export-ignore
3+
/README.md export-ignore

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
vendor/

LICENSE

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
The MIT License
2+
3+
Copyright (c) Amplilabs Ltd.
4+
5+
Permission is hereby granted, free of charge, to any person obtaining a copy
6+
of this software and associated documentation files (the "Software"), to deal
7+
in the Software without restriction, including without limitation the rights
8+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9+
copies of the Software, and to permit persons to whom the Software is
10+
furnished to do so, subject to the following conditions:
11+
12+
The above copyright notice and this permission notice shall be included in
13+
all copies or substantial portions of the Software.
14+
15+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21+
THE SOFTWARE.

README.md

Lines changed: 80 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,80 @@
1+
# WEBDEVPACK SDK for JavaScript (Node.js)
2+
3+
WEBDEVPACK SDK for JavaScript provides a simple, expressive way to integrate WEBDEVPACK’s tools into your Node.js applications. Easily access web-development utilities, automate workflows, and build faster with a unified JavaScript interface.
4+
5+
The SDK uses modern ES modules and native Node.js APIs (Node 20+).
6+
7+
## Install via npm
8+
9+
```shell
10+
npm install @webdevpack/webdevpack-sdk-js
11+
```
12+
13+
## Examples
14+
15+
```js
16+
import { Client } from "@webdevpack/webdevpack-sdk";
17+
18+
const wdp = new Client({
19+
apiKey: "YOUR-API-KEY"
20+
});
21+
22+
// IMAGES
23+
24+
// Optimize images
25+
await wdp.optimizeImage(sourceFilename, targetFilename, 80);
26+
27+
// Convert images
28+
await wdp.convertImage(sourceFilename, targetFilename, "webp", 80);
29+
30+
// Get text from image (OCR)
31+
const result = await wdp.getTextFromImage(sourceFilename, "eng");
32+
33+
// Generate QR Code
34+
await wdp.generateQRCode(text, targetFilename, 500, "webp");
35+
36+
// Generate barcode
37+
await wdp.generateBarcode(text, targetFilename, 500, 300, "webp");
38+
39+
// CODE
40+
41+
// Minify JavaScript code
42+
const jsResult = await wdp.minifyJavaScript(source);
43+
44+
// Minify JavaScript file
45+
await wdp.minifyJavaScriptFile(sourceFilename, targetFilename);
46+
47+
// Minify CSS code
48+
const cssResult = await wdp.minifyCSS(source);
49+
50+
// Minify CSS file
51+
await wdp.minifyCSSFile(sourceFilename, targetFilename);
52+
53+
// WEBSITES
54+
55+
// Get domain WHOIS information
56+
const result = await wdp.domainWhois(domain);
57+
58+
// SECURITY
59+
60+
// Generate password
61+
const password = await wdp.generatePassword(length, true, true, true);
62+
63+
// Generate key pair
64+
const { privateKey, publicKey } = await wdp.generateKeyPair(bits);
65+
66+
// DOCUMENTS
67+
68+
// Convert HTML to PDF
69+
await wdp.convertHTMLToPDF(source, targetFilename);
70+
71+
// Convert HTML file to PDF
72+
await wdp.convertHTMLFileToPDF(sourceFilename, targetFilename);
73+
```
74+
75+
## Requirements
76+
- Node.js 20+
77+
- ES modules enabled ("type": "module")
78+
79+
## License
80+
This project is licensed under the MIT License. See the [license file](https://github.com/webdevpack/webdevpack-sdk-php/blob/master/LICENSE) for more information.

package.json

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
{
2+
"name": "@webdevpack/webdevpack-sdk-js",
3+
"version": "1.0.0",
4+
"description": "WEBDEVPACK SDK for JavaScript (Node.js)",
5+
"license": "MIT",
6+
"homepage": "https://webdevpack.com/",
7+
"type": "module",
8+
"main": "./src/index.js",
9+
"exports": {
10+
".": "./src/index.js"
11+
},
12+
"author": "WEBDEVPACK",
13+
"bugs": {
14+
"email": "support@webdevpack.com"
15+
}
16+
}

src/client.js

Lines changed: 262 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,262 @@
1+
/*
2+
* WEBDEVPACK SDK for JavaScript (Node.js)
3+
* https://github.com/webdevpack/webdevpack-sdk-js
4+
* Copyright (c) Amplilabs Ltd.
5+
* MIT License
6+
*/
7+
8+
import fs from "node:fs";
9+
import path from "node:path";
10+
11+
export class Client {
12+
#options = {};
13+
14+
constructor(options = {}) {
15+
this.#options = options;
16+
}
17+
18+
async #sendRequest(pathname, data = {}, method = "POST", isJSON = true) {
19+
const url = "https://api.webdevpack.com" + pathname;
20+
21+
const headers = {};
22+
if (this.#options.apiKey) {
23+
headers["WDP-API-Key"] = this.#options.apiKey;
24+
}
25+
26+
let body;
27+
28+
if (method === "POST") {
29+
if (isJSON) {
30+
headers["Content-Type"] = "application/json";
31+
body = JSON.stringify(data);
32+
} else {
33+
body = data;
34+
}
35+
}
36+
37+
const response = await fetch(url, {
38+
method,
39+
headers,
40+
body
41+
});
42+
43+
if (!response.ok) {
44+
throw new Error(`HTTP error ${response.status}`);
45+
}
46+
47+
if (method === "GET") {
48+
return { result: await response.arrayBuffer() };
49+
}
50+
51+
const text = await response.text();
52+
let parsed;
53+
54+
try {
55+
parsed = JSON.parse(text);
56+
} catch {
57+
throw new Error(`Unknown error: ${text}`);
58+
}
59+
60+
if (parsed?.status === "ok") {
61+
return parsed;
62+
}
63+
64+
if (parsed?.status === "error") {
65+
const [type, arg] = (parsed.code || "").split(":");
66+
67+
if (type === "missingArgument") {
68+
throw new Error(`Missing argument: ${arg}`);
69+
}
70+
if (type === "invalidArgument") {
71+
throw new Error(`Invalid argument: ${arg}`);
72+
}
73+
if (parsed.message) {
74+
throw new Error(`Error: ${parsed.message}`);
75+
}
76+
}
77+
78+
throw new Error(`Unknown error: ${text}`);
79+
}
80+
81+
async #uploadFile(filename) {
82+
const form = new FormData();
83+
form.append("file", new Blob([fs.readFileSync(filename)]), path.basename(filename));
84+
const response = await this.#sendRequest("/v0/upload", form, "POST", false);
85+
return response.file;
86+
}
87+
88+
async #downloadFile(fileID, targetFilename) {
89+
const response = await this.#sendRequest(`/v0/download/${fileID}`, {}, "GET", false);
90+
const buffer = Buffer.from(response.result);
91+
if (!buffer.length) {
92+
throw new Error("Download error: file empty");
93+
}
94+
this.#makeDir(path.dirname(targetFilename));
95+
fs.writeFileSync(targetFilename, buffer);
96+
}
97+
98+
#makeDir(dir) {
99+
if (!fs.existsSync(dir)) {
100+
fs.mkdirSync(dir, { recursive: true });
101+
}
102+
}
103+
104+
#checkSourceFilename(filename) {
105+
if (!fs.existsSync(filename)) {
106+
throw new Error(`The source file (${filename}) does not exist!`);
107+
}
108+
fs.accessSync(filename, fs.constants.R_OK);
109+
}
110+
111+
#checkTargetFilename(filename) {
112+
if (fs.existsSync(filename)) {
113+
fs.accessSync(filename, fs.constants.W_OK);
114+
} else {
115+
fs.accessSync(path.dirname(filename), fs.constants.W_OK);
116+
}
117+
}
118+
119+
async transformText(text, transform) {
120+
const r = await this.#sendRequest("/v0/text-transform", { text, transform });
121+
return r.result.text;
122+
}
123+
124+
async #base64(text, transform) {
125+
const r = await this.#sendRequest("/v0/base64-encode-decode", { text, transform });
126+
return r.result.text;
127+
}
128+
129+
base64Encode(text) {
130+
return this.#base64(text, "encode");
131+
}
132+
133+
base64Decode(text) {
134+
return this.#base64(text, "decode");
135+
}
136+
137+
async hashText(text, algorithm) {
138+
const r = await this.#sendRequest("/v0/text-hash", { text, algorithm });
139+
return r.result.text;
140+
}
141+
142+
async encodeURL(url) {
143+
const r = await this.#sendRequest("/v0/url-encode-decode", { text: url, transform: "encode" });
144+
return r.result.text;
145+
}
146+
147+
async decodeURL(url) {
148+
const r = await this.#sendRequest("/v0/url-encode-decode", { text: url, transform: "decode" });
149+
return r.result.text;
150+
}
151+
152+
async domainWhois(domain) {
153+
const r = await this.#sendRequest("/v0/domain-whois", { domain });
154+
return r.result.raw;
155+
}
156+
157+
async optimizeImage(source, target, quality = 100) {
158+
this.#checkSourceFilename(source);
159+
this.#checkTargetFilename(target);
160+
const fileID = await this.#uploadFile(source);
161+
const r = await this.#sendRequest("/v0/image-optimize", { file: fileID, quality });
162+
await this.#downloadFile(r.result.file, target);
163+
}
164+
165+
async convertImage(source, target, format, quality = 100) {
166+
this.#checkSourceFilename(source);
167+
this.#checkTargetFilename(target);
168+
const fileID = await this.#uploadFile(source);
169+
const r = await this.#sendRequest("/v0/image-convert", { file: fileID, format, quality });
170+
await this.#downloadFile(r.result.file, target);
171+
}
172+
173+
async getTextFromImage(source, language = "eng") {
174+
this.#checkSourceFilename(source);
175+
const fileID = await this.#uploadFile(source);
176+
const r = await this.#sendRequest("/v0/text-from-image", { file: fileID, language });
177+
return r.result.text;
178+
}
179+
180+
async generateQRCode(text, target, size, format) {
181+
this.#checkTargetFilename(target);
182+
const r = await this.#sendRequest("/v0/qrcode", { text, size, format });
183+
await this.#downloadFile(r.result.file, target);
184+
}
185+
186+
async generateBarcode(text, target, width, height, format) {
187+
this.#checkTargetFilename(target);
188+
const r = await this.#sendRequest("/v0/barcode", { text, width, height, format });
189+
await this.#downloadFile(r.result.file, target);
190+
}
191+
192+
async minifyJavaScript(code) {
193+
const r = await this.#sendRequest("/v0/js-minify-text", { text: code });
194+
return r.result.text;
195+
}
196+
197+
async minifyJavaScriptFile(source, target) {
198+
this.#checkSourceFilename(source);
199+
this.#checkTargetFilename(target);
200+
const fileID = await this.#uploadFile(source);
201+
const r = await this.#sendRequest("/v0/js-minify-file", { file: fileID });
202+
await this.#downloadFile(r.result.file, target);
203+
}
204+
205+
async minifyCSS(code) {
206+
const r = await this.#sendRequest("/v0/css-minify-text", { text: code });
207+
return r.result.text;
208+
}
209+
210+
async minifyCSSFile(source, target) {
211+
this.#checkSourceFilename(source);
212+
this.#checkTargetFilename(target);
213+
const fileID = await this.#uploadFile(source);
214+
const r = await this.#sendRequest("/v0/css-minify-file", { file: fileID });
215+
await this.#downloadFile(r.result.file, target);
216+
}
217+
218+
async #json(text, transform) {
219+
const r = await this.#sendRequest("/v0/json-encode-decode", { text, transform });
220+
return r.result.text;
221+
}
222+
223+
encodeJSON(text) {
224+
return this.#json(text, "encode");
225+
}
226+
227+
decodeJSON(text) {
228+
return this.#json(text, "decode");
229+
}
230+
231+
async generatePassword(length, includeUpperCase, includeSymbols, includeNumbers) {
232+
const r = await this.#sendRequest("/v0/password", {
233+
length,
234+
uppercase: includeUpperCase,
235+
symbols: includeSymbols,
236+
numbers: includeNumbers
237+
});
238+
return r.result.password;
239+
}
240+
241+
async generateKeyPair(bits) {
242+
const r = await this.#sendRequest("/v0/keypair", { bits });
243+
return {
244+
privateKey: r.result.privateKey,
245+
publicKey: r.result.publicKey
246+
};
247+
}
248+
249+
async convertHTMLToPDF(code, target) {
250+
this.#checkTargetFilename(target);
251+
const r = await this.#sendRequest("/v0/html-to-pdf", { text: code });
252+
await this.#downloadFile(r.result.file, target);
253+
}
254+
255+
async convertHTMLFileToPDF(source, target) {
256+
this.#checkSourceFilename(source);
257+
this.#checkTargetFilename(target);
258+
const fileID = await this.#uploadFile(source);
259+
const r = await this.#sendRequest("/v0/html-file-to-pdf", { file: fileID });
260+
await this.#downloadFile(r.result.file, target);
261+
}
262+
}

0 commit comments

Comments
 (0)