@applica-software-guru/didonato-storage-client 1.0.29
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +66 -0
- package/dist/index.d.mts +24 -0
- package/dist/index.d.ts +24 -0
- package/dist/index.js +98 -0
- package/dist/index.mjs +61 -0
- package/package.json +37 -0
package/README.md
ADDED
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
# @applica-software-guru/didonato-storage-client
|
|
2
|
+
|
|
3
|
+
Client TypeScript package for Didonato Storage.
|
|
4
|
+
|
|
5
|
+
Quick start
|
|
6
|
+
|
|
7
|
+
Install:
|
|
8
|
+
|
|
9
|
+
```bash
|
|
10
|
+
npm install @applica-software-guru/didonato-storage-client
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
Usage (ESM):
|
|
14
|
+
|
|
15
|
+
```ts
|
|
16
|
+
import DidonatoStorageClient from "@applica-software-guru/didonato-storage-client";
|
|
17
|
+
|
|
18
|
+
const c = new DidonatoStorageClient({ baseUrl: "https://example.com" });
|
|
19
|
+
console.log(await c.getSignedUrl("path/to/file"));
|
|
20
|
+
```
|
|
21
|
+
|
|
22
|
+
## Authentication
|
|
23
|
+
|
|
24
|
+
The client accepts an optional `token` option which can be provided in two ways:
|
|
25
|
+
|
|
26
|
+
- As a static token string: `new DidonatoStorageClient({ token: 'my-token' })`.
|
|
27
|
+
- As a function that returns a token (sync or async): `new DidonatoStorageClient({ token: () => fetchToken() })`.
|
|
28
|
+
|
|
29
|
+
Examples
|
|
30
|
+
|
|
31
|
+
1. Pass a static token:
|
|
32
|
+
|
|
33
|
+
```ts
|
|
34
|
+
import DidonatoStorageClient from "@applica-software-guru/didonato-storage-client";
|
|
35
|
+
|
|
36
|
+
const client = new DidonatoStorageClient({ baseUrl: "https://example.com", token: "MY_STATIC_TOKEN" });
|
|
37
|
+
// methods will include `Authorization: Bearer MY_STATIC_TOKEN` when calling the server
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
2. Pass a token factory (sync or async):
|
|
41
|
+
|
|
42
|
+
```ts
|
|
43
|
+
import DidonatoStorageClient from '@applica-software-guru/didonato-storage-client';
|
|
44
|
+
|
|
45
|
+
// sync factory
|
|
46
|
+
const clientSync = new DidonatoStorageClient({ baseUrl: 'https://example.com', token: () => 'token-from-fn' });
|
|
47
|
+
|
|
48
|
+
// async factory
|
|
49
|
+
const clientAsync = new DidonatoStorageClient({
|
|
50
|
+
baseUrl: 'https://example.com',
|
|
51
|
+
token: async () => {
|
|
52
|
+
// refresh or fetch token from secure storage
|
|
53
|
+
return await getFreshToken();
|
|
54
|
+
}
|
|
55
|
+
});
|
|
56
|
+
|
|
57
|
+
// The library will call your function before requests and attach
|
|
58
|
+
// `Authorization: Bearer <token>` header when present.
|
|
59
|
+
|
|
60
|
+
Notes
|
|
61
|
+
-----
|
|
62
|
+
- If you need to pass custom headers beyond Authorization, call the low-level endpoints
|
|
63
|
+
on your server or extend the client.
|
|
64
|
+
- The token option is optional; if omitted, requests are sent without an Authorization header.
|
|
65
|
+
|
|
66
|
+
```
|
package/dist/index.d.mts
ADDED
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
interface DidonatoOptions {
|
|
2
|
+
baseUrl?: string;
|
|
3
|
+
bucket?: string;
|
|
4
|
+
credentials?: Record<string, any>;
|
|
5
|
+
/**
|
|
6
|
+
* A static token string (Bearer) or a function that returns a token string (sync or Promise)
|
|
7
|
+
*/
|
|
8
|
+
token?: string | (() => string | Promise<string>);
|
|
9
|
+
}
|
|
10
|
+
declare class DidonatoStorageClient {
|
|
11
|
+
options: DidonatoOptions;
|
|
12
|
+
constructor(opts?: DidonatoOptions);
|
|
13
|
+
getToken(): Promise<string | undefined>;
|
|
14
|
+
getSignedUrl(key: string, expiresSec?: number): Promise<string>;
|
|
15
|
+
createSignedPost(key: string): Promise<{
|
|
16
|
+
url: string;
|
|
17
|
+
fields: Record<string, string>;
|
|
18
|
+
}>;
|
|
19
|
+
uploadWithSignedPost(url: string, fields: Record<string, string>, body: Buffer | Blob | string): Promise<boolean>;
|
|
20
|
+
delete(key: string): Promise<boolean>;
|
|
21
|
+
list(prefix?: string): Promise<string[]>;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
export { type DidonatoOptions, DidonatoStorageClient, DidonatoStorageClient as default };
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
interface DidonatoOptions {
|
|
2
|
+
baseUrl?: string;
|
|
3
|
+
bucket?: string;
|
|
4
|
+
credentials?: Record<string, any>;
|
|
5
|
+
/**
|
|
6
|
+
* A static token string (Bearer) or a function that returns a token string (sync or Promise)
|
|
7
|
+
*/
|
|
8
|
+
token?: string | (() => string | Promise<string>);
|
|
9
|
+
}
|
|
10
|
+
declare class DidonatoStorageClient {
|
|
11
|
+
options: DidonatoOptions;
|
|
12
|
+
constructor(opts?: DidonatoOptions);
|
|
13
|
+
getToken(): Promise<string | undefined>;
|
|
14
|
+
getSignedUrl(key: string, expiresSec?: number): Promise<string>;
|
|
15
|
+
createSignedPost(key: string): Promise<{
|
|
16
|
+
url: string;
|
|
17
|
+
fields: Record<string, string>;
|
|
18
|
+
}>;
|
|
19
|
+
uploadWithSignedPost(url: string, fields: Record<string, string>, body: Buffer | Blob | string): Promise<boolean>;
|
|
20
|
+
delete(key: string): Promise<boolean>;
|
|
21
|
+
list(prefix?: string): Promise<string[]>;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
export { type DidonatoOptions, DidonatoStorageClient, DidonatoStorageClient as default };
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __create = Object.create;
|
|
3
|
+
var __defProp = Object.defineProperty;
|
|
4
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
5
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
6
|
+
var __getProtoOf = Object.getPrototypeOf;
|
|
7
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
8
|
+
var __export = (target, all) => {
|
|
9
|
+
for (var name in all)
|
|
10
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
11
|
+
};
|
|
12
|
+
var __copyProps = (to, from, except, desc) => {
|
|
13
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
14
|
+
for (let key of __getOwnPropNames(from))
|
|
15
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
16
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
17
|
+
}
|
|
18
|
+
return to;
|
|
19
|
+
};
|
|
20
|
+
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
|
|
21
|
+
// If the importer is in node compatibility mode or this is not an ESM
|
|
22
|
+
// file that has been converted to a CommonJS file using a Babel-
|
|
23
|
+
// compatible transform (i.e. "__esModule" has not been set), then set
|
|
24
|
+
// "default" to the CommonJS "module.exports" for node compatibility.
|
|
25
|
+
isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
|
|
26
|
+
mod
|
|
27
|
+
));
|
|
28
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
29
|
+
|
|
30
|
+
// src/index.ts
|
|
31
|
+
var index_exports = {};
|
|
32
|
+
__export(index_exports, {
|
|
33
|
+
DidonatoStorageClient: () => DidonatoStorageClient,
|
|
34
|
+
default: () => DidonatoStorageClient
|
|
35
|
+
});
|
|
36
|
+
module.exports = __toCommonJS(index_exports);
|
|
37
|
+
|
|
38
|
+
// src/DidonatoStorageClient.ts
|
|
39
|
+
var import_cross_fetch = __toESM(require("cross-fetch"));
|
|
40
|
+
var DidonatoStorageClient = class {
|
|
41
|
+
constructor(opts = {}) {
|
|
42
|
+
this.options = opts;
|
|
43
|
+
}
|
|
44
|
+
async getToken() {
|
|
45
|
+
const t = this.options.token;
|
|
46
|
+
if (!t) return void 0;
|
|
47
|
+
if (typeof t === "function") {
|
|
48
|
+
try {
|
|
49
|
+
return await t();
|
|
50
|
+
} catch (err) {
|
|
51
|
+
return void 0;
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
return String(t);
|
|
55
|
+
}
|
|
56
|
+
async getSignedUrl(key, expiresSec = 3600) {
|
|
57
|
+
return `${this.options.baseUrl || "https://storage.example.com"}/signed/${encodeURIComponent(
|
|
58
|
+
key
|
|
59
|
+
)}?exp=${expiresSec}`;
|
|
60
|
+
}
|
|
61
|
+
async createSignedPost(key) {
|
|
62
|
+
const url = `${this.options.baseUrl || ""}/signed-post/${encodeURIComponent(key)}`;
|
|
63
|
+
const res = await (0, import_cross_fetch.default)(url);
|
|
64
|
+
if (!res.ok) throw new Error("failed to get signed post");
|
|
65
|
+
const json = await res.json();
|
|
66
|
+
return json;
|
|
67
|
+
}
|
|
68
|
+
async uploadWithSignedPost(url, fields, body) {
|
|
69
|
+
if (typeof FormData !== "undefined") {
|
|
70
|
+
const fd = new FormData();
|
|
71
|
+
for (const k in fields) fd.append(k, fields[k]);
|
|
72
|
+
fd.append("file", body);
|
|
73
|
+
const res = await (0, import_cross_fetch.default)(url, { method: "POST", body: fd });
|
|
74
|
+
return res.ok;
|
|
75
|
+
}
|
|
76
|
+
throw new Error("FormData not available; use form-data package in Node tests");
|
|
77
|
+
}
|
|
78
|
+
async delete(key) {
|
|
79
|
+
const url = `${this.options.baseUrl || ""}/objects/${encodeURIComponent(key)}`;
|
|
80
|
+
const token = await this.getToken();
|
|
81
|
+
const headers = token ? { Authorization: `Bearer ${token}` } : void 0;
|
|
82
|
+
const res = await (0, import_cross_fetch.default)(url, { method: "DELETE", headers });
|
|
83
|
+
return res.ok;
|
|
84
|
+
}
|
|
85
|
+
async list(prefix = "") {
|
|
86
|
+
const url = `${this.options.baseUrl || ""}/objects?prefix=${encodeURIComponent(prefix)}`;
|
|
87
|
+
const token = await this.getToken();
|
|
88
|
+
const headers = token ? { Authorization: `Bearer ${token}` } : void 0;
|
|
89
|
+
const res = await (0, import_cross_fetch.default)(url, { headers });
|
|
90
|
+
if (!res.ok) return [];
|
|
91
|
+
const json = await res.json();
|
|
92
|
+
return Array.isArray(json) ? json : [];
|
|
93
|
+
}
|
|
94
|
+
};
|
|
95
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
96
|
+
0 && (module.exports = {
|
|
97
|
+
DidonatoStorageClient
|
|
98
|
+
});
|
package/dist/index.mjs
ADDED
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
// src/DidonatoStorageClient.ts
|
|
2
|
+
import fetch from "cross-fetch";
|
|
3
|
+
var DidonatoStorageClient = class {
|
|
4
|
+
constructor(opts = {}) {
|
|
5
|
+
this.options = opts;
|
|
6
|
+
}
|
|
7
|
+
async getToken() {
|
|
8
|
+
const t = this.options.token;
|
|
9
|
+
if (!t) return void 0;
|
|
10
|
+
if (typeof t === "function") {
|
|
11
|
+
try {
|
|
12
|
+
return await t();
|
|
13
|
+
} catch (err) {
|
|
14
|
+
return void 0;
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
return String(t);
|
|
18
|
+
}
|
|
19
|
+
async getSignedUrl(key, expiresSec = 3600) {
|
|
20
|
+
return `${this.options.baseUrl || "https://storage.example.com"}/signed/${encodeURIComponent(
|
|
21
|
+
key
|
|
22
|
+
)}?exp=${expiresSec}`;
|
|
23
|
+
}
|
|
24
|
+
async createSignedPost(key) {
|
|
25
|
+
const url = `${this.options.baseUrl || ""}/signed-post/${encodeURIComponent(key)}`;
|
|
26
|
+
const res = await fetch(url);
|
|
27
|
+
if (!res.ok) throw new Error("failed to get signed post");
|
|
28
|
+
const json = await res.json();
|
|
29
|
+
return json;
|
|
30
|
+
}
|
|
31
|
+
async uploadWithSignedPost(url, fields, body) {
|
|
32
|
+
if (typeof FormData !== "undefined") {
|
|
33
|
+
const fd = new FormData();
|
|
34
|
+
for (const k in fields) fd.append(k, fields[k]);
|
|
35
|
+
fd.append("file", body);
|
|
36
|
+
const res = await fetch(url, { method: "POST", body: fd });
|
|
37
|
+
return res.ok;
|
|
38
|
+
}
|
|
39
|
+
throw new Error("FormData not available; use form-data package in Node tests");
|
|
40
|
+
}
|
|
41
|
+
async delete(key) {
|
|
42
|
+
const url = `${this.options.baseUrl || ""}/objects/${encodeURIComponent(key)}`;
|
|
43
|
+
const token = await this.getToken();
|
|
44
|
+
const headers = token ? { Authorization: `Bearer ${token}` } : void 0;
|
|
45
|
+
const res = await fetch(url, { method: "DELETE", headers });
|
|
46
|
+
return res.ok;
|
|
47
|
+
}
|
|
48
|
+
async list(prefix = "") {
|
|
49
|
+
const url = `${this.options.baseUrl || ""}/objects?prefix=${encodeURIComponent(prefix)}`;
|
|
50
|
+
const token = await this.getToken();
|
|
51
|
+
const headers = token ? { Authorization: `Bearer ${token}` } : void 0;
|
|
52
|
+
const res = await fetch(url, { headers });
|
|
53
|
+
if (!res.ok) return [];
|
|
54
|
+
const json = await res.json();
|
|
55
|
+
return Array.isArray(json) ? json : [];
|
|
56
|
+
}
|
|
57
|
+
};
|
|
58
|
+
export {
|
|
59
|
+
DidonatoStorageClient,
|
|
60
|
+
DidonatoStorageClient as default
|
|
61
|
+
};
|
package/package.json
ADDED
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@applica-software-guru/didonato-storage-client",
|
|
3
|
+
"version": "1.0.29",
|
|
4
|
+
"description": "Client per Didonato Storage (Node + Browser)",
|
|
5
|
+
"main": "dist/index.cjs",
|
|
6
|
+
"module": "dist/index.mjs",
|
|
7
|
+
"types": "dist/index.d.ts",
|
|
8
|
+
"files": [
|
|
9
|
+
"dist"
|
|
10
|
+
],
|
|
11
|
+
"scripts": {
|
|
12
|
+
"build": "tsup src/index.ts --format cjs,esm --dts --clean",
|
|
13
|
+
"test": "vitest",
|
|
14
|
+
"prepare": "npm run build"
|
|
15
|
+
},
|
|
16
|
+
"keywords": [
|
|
17
|
+
"didonato",
|
|
18
|
+
"storage",
|
|
19
|
+
"gcs",
|
|
20
|
+
"signed-post"
|
|
21
|
+
],
|
|
22
|
+
"author": "applica-software-guru",
|
|
23
|
+
"license": "MIT",
|
|
24
|
+
"publishConfig": {
|
|
25
|
+
"access": "public"
|
|
26
|
+
},
|
|
27
|
+
"dependencies": {
|
|
28
|
+
"cross-fetch": "^4.1.0",
|
|
29
|
+
"form-data": "^4.0.5"
|
|
30
|
+
},
|
|
31
|
+
"devDependencies": {
|
|
32
|
+
"tsup": "^8.5.1",
|
|
33
|
+
"typescript": "^5.9.3",
|
|
34
|
+
"vitest": "^4.0.16",
|
|
35
|
+
"@types/node": "^25.0.3"
|
|
36
|
+
}
|
|
37
|
+
}
|