@squarecloud/blob
Advanced tools
Comparing version 0.1.0 to 1.0.0
# @squarecloud/blob | ||
## 1.0.0 | ||
### Major Changes | ||
- a88b29b: Rename `objects.put` and related to `objects.create` | ||
- a88b29b: Update to new Blob API routes | ||
### Minor Changes | ||
- a73de9f: New `mimeType` prop for `objects.put` method, required if file is a Buffer | ||
- 3810094: `objects.put` now returns useful info about the uploaded object | ||
### Patch Changes | ||
- 1407c2f: Export some typings and mimeType enum | ||
- 3f5c7b8: Fix `objects.list` method | ||
## 0.1.0 | ||
@@ -4,0 +21,0 @@ |
import './managers/api.js'; | ||
export { S as SquareCloudBlob } from './index-D3kETQQ8.js'; | ||
export { S as SquareCloudBlob } from './index-CTI71HKx.js'; | ||
export { CreateObjectResponse, CreateObjectType } from './types/create.js'; | ||
export { ListObjectsResponse } from './types/list.js'; | ||
export { MimeTypes } from './utils/mimetype.js'; | ||
import './types/api.js'; | ||
import './types/put.js'; | ||
import 'zod'; | ||
import './schemas/put.js'; | ||
import './validation/schemas/create.js'; | ||
import './validation/schemas/list.js'; |
280
lib/index.js
@@ -27,2 +27,3 @@ var __defProp = Object.defineProperty; | ||
__export(src_exports, { | ||
MimeTypes: () => MimeTypes, | ||
SquareCloudBlob: () => SquareCloudBlob | ||
@@ -38,3 +39,2 @@ }); | ||
this.message = this.getMessage(code); | ||
Error.captureStackTrace(this, _SquareCloudBlobError); | ||
} | ||
@@ -84,21 +84,162 @@ getMessage(rawCode) { | ||
// src/managers/objects.ts | ||
// src/utils/mimetype.ts | ||
var mimeTypesWithExtension = { | ||
"video/mp4": ["mp4"], | ||
"video/mpeg": ["mpeg"], | ||
"video/webm": ["webm"], | ||
"video/x-flv": ["flv"], | ||
"video/x-m4v": ["m4v"], | ||
"image/jpeg": ["jpg", "jpeg"], | ||
"image/png": ["png"], | ||
"image/apng": ["apng"], | ||
"image/tiff": ["tiff"], | ||
"image/gif": ["gif"], | ||
"image/webp": ["webp"], | ||
"image/bmp": ["bmp"], | ||
"image/svg+xml": ["svg"], | ||
"image/x-icon": ["ico"], | ||
"image/ico": ["ico"], | ||
"image/cur": ["cur"], | ||
"image/heic": ["heic"], | ||
"image/heif": ["heif"], | ||
"audio/wav": ["wav"], | ||
"audio/ogg": ["ogg"], | ||
"audio/opus": ["opus"], | ||
"audio/mp4": ["mp4"], | ||
"audio/mpeg": ["mp3"], | ||
"audio/aac": ["aac"], | ||
"text/plain": ["txt"], | ||
"text/html": ["html"], | ||
"text/css": ["css"], | ||
"text/csv": ["csv"], | ||
"text/x-sql": ["sql"], | ||
"application/xml": ["xml"], | ||
"application/sql": ["sql"], | ||
"application/x-sql": ["sql"], | ||
"application/x-sqlite3": ["sqlite3"], | ||
"application/x-pkcs12": ["pfx"], | ||
"application/pdf": ["pdf"], | ||
"application/json": ["json"], | ||
"application/javascript": ["js"] | ||
}; | ||
var MimeTypes = /* @__PURE__ */ ((MimeTypes2) => { | ||
MimeTypes2["VIDEO_MP4"] = "video/mp4"; | ||
MimeTypes2["VIDEO_MPEG"] = "video/mpeg"; | ||
MimeTypes2["VIDEO_WEBM"] = "video/webm"; | ||
MimeTypes2["VIDEO_X_FLV"] = "video/x-flv"; | ||
MimeTypes2["VIDEO_X_M4V"] = "video/x-m4v"; | ||
MimeTypes2["IMAGE_JPEG"] = "image/jpeg"; | ||
MimeTypes2["IMAGE_PNG"] = "image/png"; | ||
MimeTypes2["IMAGE_APNG"] = "image/apng"; | ||
MimeTypes2["IMAGE_TIFF"] = "image/tiff"; | ||
MimeTypes2["IMAGE_GIF"] = "image/gif"; | ||
MimeTypes2["IMAGE_WEBP"] = "image/webp"; | ||
MimeTypes2["IMAGE_BMP"] = "image/bmp"; | ||
MimeTypes2["IMAGE_SVG"] = "image/svg+xml"; | ||
MimeTypes2["IMAGE_X_ICON"] = "image/x-icon"; | ||
MimeTypes2["IMAGE_ICO"] = "image/ico"; | ||
MimeTypes2["IMAGE_CUR"] = "image/cur"; | ||
MimeTypes2["IMAGE_HEIC"] = "image/heic"; | ||
MimeTypes2["IMAGE_HEIF"] = "image/heif"; | ||
MimeTypes2["AUDIO_WAV"] = "audio/wav"; | ||
MimeTypes2["AUDIO_OGG"] = "audio/ogg"; | ||
MimeTypes2["AUDIO_OPUS"] = "audio/opus"; | ||
MimeTypes2["AUDIO_MP4"] = "audio/mp4"; | ||
MimeTypes2["AUDIO_MPEG"] = "audio/mpeg"; | ||
MimeTypes2["AUDIO_AAC"] = "audio/aac"; | ||
MimeTypes2["TEXT_PLAIN"] = "text/plain"; | ||
MimeTypes2["TEXT_HTML"] = "text/html"; | ||
MimeTypes2["TEXT_CSS"] = "text/css"; | ||
MimeTypes2["TEXT_CSV"] = "text/csv"; | ||
MimeTypes2["TEXT_X_SQL"] = "text/x-sql"; | ||
MimeTypes2["APPLICATION_XML"] = "application/xml"; | ||
MimeTypes2["APPLICATION_SQL"] = "application/sql"; | ||
MimeTypes2["APPLICATION_X_SQL"] = "application/x-sql"; | ||
MimeTypes2["APPLICATION_X_SQLITE3"] = "application/x-sqlite3"; | ||
MimeTypes2["APPLICATION_X_PKCS12"] = "application/x-pkcs12"; | ||
MimeTypes2["APPLICATION_PDF"] = "application/pdf"; | ||
MimeTypes2["APPLICATION_JSON"] = "application/json"; | ||
MimeTypes2["APPLICATION_JAVASCRIPT"] = "application/javascript"; | ||
return MimeTypes2; | ||
})(MimeTypes || {}); | ||
var mimeTypes = Object.keys(mimeTypesWithExtension); | ||
function getMimeTypeFromExtension(extension) { | ||
const entries = Object.entries(mimeTypesWithExtension); | ||
const mimeType = entries.find( | ||
([, extensions]) => extensions.includes(extension) | ||
)?.[0]; | ||
return mimeType || "text/plain"; | ||
} | ||
// src/utils/pathlike.ts | ||
var import_promises = require("fs/promises"); | ||
async function parsePathLike(pathLike) { | ||
if (typeof pathLike === "string") { | ||
const fileBuffer = await (0, import_promises.readFile)(pathLike).catch(() => void 0); | ||
if (!fileBuffer) { | ||
throw new SquareCloudBlobError("INVALID_FILE", "File not found"); | ||
} | ||
return fileBuffer; | ||
} | ||
return pathLike; | ||
} | ||
// src/schemas/list.ts | ||
// src/validation/schemas/create.ts | ||
var import_zod2 = require("zod"); | ||
// src/validation/schemas/common.ts | ||
var import_zod = require("zod"); | ||
var listObjectSchema = import_zod.z.object({ | ||
name: import_zod.z.string(), | ||
size: import_zod.z.number(), | ||
created_at: import_zod.z.coerce.date(), | ||
expire_at: import_zod.z.coerce.date().optional() | ||
var stringSchema = import_zod.z.string(); | ||
var nameLikeSchema = import_zod.z.string().min(3).max(32).regex(/^[a-zA-Z0-9_]{3,32}$/, { | ||
message: "Name must contain only letters, numbers and _" | ||
}); | ||
var listObjectsResponseSchema = import_zod.z.array(listObjectSchema); | ||
// src/assertions/handlers.ts | ||
// src/validation/schemas/create.ts | ||
var createObjectSchema = import_zod2.z.object({ | ||
/** A string representing the name for the file. */ | ||
name: nameLikeSchema, | ||
/** Use absolute path, Buffer or Blob */ | ||
file: import_zod2.z.string().or(import_zod2.z.instanceof(Buffer)), | ||
/** A string representing the MIME type of the file. */ | ||
mimeType: import_zod2.z.enum(mimeTypes).optional(), | ||
/** A string representing the prefix for the file. */ | ||
prefix: nameLikeSchema.optional(), | ||
/** A number indicating the expiration period of the file, ranging from 1 to 365 days. */ | ||
expire: import_zod2.z.number().min(1).max(365).optional(), | ||
/** Set to true if a security hash is required. */ | ||
securityHash: import_zod2.z.boolean().optional(), | ||
/** Set to true if the file should be set for automatic download. */ | ||
autoDownload: import_zod2.z.boolean().optional() | ||
}).refine(({ file, mimeType }) => !(file instanceof Buffer && !mimeType), { | ||
message: "mimeType is required if file is a Buffer", | ||
path: ["mimeType"] | ||
}); | ||
var createObjectPayloadSchema = createObjectSchema.transform( | ||
({ file, securityHash, autoDownload, ...rest }) => ({ | ||
file, | ||
params: { | ||
...rest, | ||
security_hash: securityHash, | ||
auto_download: autoDownload | ||
} | ||
}) | ||
); | ||
var createObjectResponseSchema = import_zod2.z.object({ | ||
/** The id of the uploaded file. */ | ||
id: import_zod2.z.string(), | ||
/** The name of the uploaded file. */ | ||
name: import_zod2.z.string(), | ||
/** The prefix of the uploaded file. */ | ||
prefix: import_zod2.z.string().optional(), | ||
/** The size of the uploaded file. */ | ||
size: import_zod2.z.number(), | ||
/** The URL of the uploaded file. (File distributed in Square Cloud CDN) */ | ||
url: import_zod2.z.string() | ||
}); | ||
// src/validation/assertions/handlers.ts | ||
function handleAPIObjectAssertion({ | ||
schema, | ||
value, | ||
code, | ||
route | ||
code | ||
}) { | ||
@@ -115,3 +256,3 @@ const name = code.toLowerCase().replaceAll("_", " "); | ||
`INVALID_API_${code}`, | ||
`Invalid ${name} object received from API ${route}`, | ||
`Invalid ${name} object received from API`, | ||
{ cause } | ||
@@ -122,8 +263,7 @@ ); | ||
// src/assertions/list.ts | ||
function assertListObjectsResponse(value) { | ||
// src/validation/assertions/create.ts | ||
function assertCreateObjectResponse(value) { | ||
return handleAPIObjectAssertion({ | ||
schema: listObjectsResponseSchema, | ||
code: "LIST_OBJECTS", | ||
route: "/list", | ||
schema: createObjectResponseSchema, | ||
code: "CREATE_OBJECT", | ||
value | ||
@@ -133,48 +273,19 @@ }); | ||
// src/schemas/put.ts | ||
// src/validation/schemas/list.ts | ||
var import_zod3 = require("zod"); | ||
// src/schemas/common.ts | ||
var import_zod2 = require("zod"); | ||
var stringSchema = import_zod2.z.string(); | ||
var nameLikeSchema = import_zod2.z.string().min(3).max(32).regex(/^[a-zA-Z0-9_]{3,32}$/, { | ||
message: "Name must contain only letters, numbers and _" | ||
var listObjectSchema = import_zod3.z.object({ | ||
name: import_zod3.z.string(), | ||
size: import_zod3.z.number(), | ||
created_at: import_zod3.z.coerce.date(), | ||
expire_at: import_zod3.z.coerce.date().optional() | ||
}); | ||
// src/schemas/put.ts | ||
var putObjectSchema = import_zod3.z.object({ | ||
/** A string representing the name for the file. */ | ||
name: nameLikeSchema, | ||
/** Use absolute path or Buffer, can be a single file or compressed (zip) */ | ||
file: import_zod3.z.string().or(import_zod3.z.instanceof(Buffer)), | ||
/** A string representing the prefix for the file. */ | ||
prefix: nameLikeSchema.optional(), | ||
/** A number indicating the expiration period of the file, ranging from 1 to 365 days. */ | ||
expire: import_zod3.z.number().min(1).max(365).optional(), | ||
/** Set to true if a security hash is required. */ | ||
securityHash: import_zod3.z.boolean().optional(), | ||
/** Set to true if the file should be set for automatic download. */ | ||
autoDownload: import_zod3.z.boolean().optional() | ||
var listObjectsResponseSchema = import_zod3.z.object({ | ||
objects: import_zod3.z.array(listObjectSchema) | ||
}); | ||
var putObjectPayloadSchema = putObjectSchema.transform( | ||
({ file, securityHash, autoDownload, ...rest }) => ({ | ||
file, | ||
params: { | ||
...rest, | ||
security_hash: securityHash, | ||
auto_download: autoDownload | ||
} | ||
}) | ||
); | ||
var putObjectResponseSchema = import_zod3.z.object({ | ||
/** The URL of the uploaded file. (File distributed in Square Cloud CDN) */ | ||
url: import_zod3.z.string() | ||
}); | ||
// src/assertions/put.ts | ||
function assertPutObjectResponse(value) { | ||
// src/validation/assertions/list.ts | ||
function assertListObjectsResponse(value) { | ||
return handleAPIObjectAssertion({ | ||
schema: putObjectResponseSchema, | ||
code: "PUT_OBJECT", | ||
route: "/put", | ||
schema: listObjectsResponseSchema, | ||
code: "LIST_OBJECTS", | ||
value | ||
@@ -185,3 +296,3 @@ }); | ||
// src/managers/objects.ts | ||
var BlobObjectsManager = class { | ||
var ObjectsManager = class { | ||
constructor(client) { | ||
@@ -199,4 +310,4 @@ this.client = client; | ||
async list() { | ||
const { response } = await this.client.api.request("list"); | ||
return assertListObjectsResponse(response); | ||
const { response } = await this.client.api.request("objects"); | ||
return assertListObjectsResponse(response)?.objects; | ||
} | ||
@@ -210,15 +321,20 @@ /** | ||
* ```js | ||
* await blob.objects.put({ file: "path/to/file.jpeg", name: "my_image" }); | ||
* await blob.objects.create({ file: "path/to/file.jpeg", name: "my_image" }); | ||
* ``` | ||
*/ | ||
async put(object) { | ||
const payload = putObjectPayloadSchema.parse(object); | ||
const file = await this.parseFile(payload.file); | ||
async create(object) { | ||
const payload = createObjectPayloadSchema.parse(object); | ||
const file = await parsePathLike(payload.file); | ||
const mimeType = typeof object.file === "string" ? getMimeTypeFromExtension(object.file.split(".")[1]) : object.mimeType; | ||
const formData = new FormData(); | ||
formData.append("file", new Blob([file])); | ||
formData.append("file", new Blob([file], { type: mimeType })); | ||
const { response } = await this.client.api.request( | ||
"put", | ||
{ method: "PUT", body: formData, params: payload.params } | ||
"objects", | ||
{ | ||
method: "POST", | ||
body: formData, | ||
params: payload.params | ||
} | ||
); | ||
return assertPutObjectResponse(response); | ||
return assertCreateObjectResponse(response); | ||
} | ||
@@ -232,3 +348,3 @@ /** | ||
* ```js | ||
* await blob.objects.delete("ID/prefix/name1_xxx-xxx.zip", "ID/prefix/name_xxx-xxx-xxx.png"); | ||
* await blob.objects.delete("ID/prefix/name1_xxx-xxx.mp4", "ID/prefix/name_xxx-xxx-xxx.png"); | ||
* ``` | ||
@@ -238,18 +354,13 @@ */ | ||
const ids = objects.flat(); | ||
const response = await this.client.api.request("delete", { | ||
const { status } = await this.client.api.request("objects", { | ||
method: "DELETE", | ||
body: { objects: ids } | ||
}); | ||
return response.status === "success"; | ||
return status === "success"; | ||
} | ||
async parseFile(file) { | ||
let result; | ||
if (typeof file === "string") { | ||
result = await (0, import_promises.readFile)(file).catch(() => void 0); | ||
} | ||
if (!result) { | ||
throw new SquareCloudBlobError("INVALID_FILE", "File not found"); | ||
} | ||
return result; | ||
} | ||
/** | ||
* Parses the object URL to extract id, prefix, and name. | ||
* | ||
* @param url - The object URL to parse. | ||
*/ | ||
parseObjectUrl(url) { | ||
@@ -274,3 +385,3 @@ const pattern = /^https:\/\/public-blob\.squarecloud\.dev\/([^\/]+)\/([^\/]+\/)?([^_]+)_[\w-]+\.\w+$/; | ||
__publicField(this, "api"); | ||
__publicField(this, "objects", new BlobObjectsManager(this)); | ||
__publicField(this, "objects", new ObjectsManager(this)); | ||
this.api = new APIManager(apiKey); | ||
@@ -285,4 +396,5 @@ } | ||
0 && (module.exports = { | ||
MimeTypes, | ||
SquareCloudBlob | ||
}); | ||
//# sourceMappingURL=index.js.map |
@@ -31,15 +31,2 @@ var __defProp = Object.defineProperty; | ||
// src/managers/objects.ts | ||
var import_promises = require("fs/promises"); | ||
// src/schemas/list.ts | ||
var import_zod = require("zod"); | ||
var listObjectSchema = import_zod.z.object({ | ||
name: import_zod.z.string(), | ||
size: import_zod.z.number(), | ||
created_at: import_zod.z.coerce.date(), | ||
expire_at: import_zod.z.coerce.date().optional() | ||
}); | ||
var listObjectsResponseSchema = import_zod.z.array(listObjectSchema); | ||
// src/structures/error.ts | ||
@@ -51,3 +38,2 @@ var SquareCloudBlobError = class _SquareCloudBlobError extends Error { | ||
this.message = this.getMessage(code); | ||
Error.captureStackTrace(this, _SquareCloudBlobError); | ||
} | ||
@@ -61,61 +47,95 @@ getMessage(rawCode) { | ||
// src/assertions/handlers.ts | ||
function handleAPIObjectAssertion({ | ||
schema, | ||
value, | ||
code, | ||
route | ||
}) { | ||
const name = code.toLowerCase().replaceAll("_", " "); | ||
try { | ||
return schema.parse(value); | ||
} catch (err) { | ||
const cause = err.errors?.map((err2) => ({ | ||
...err2, | ||
path: err2.path.join(" > ") | ||
})); | ||
throw new SquareCloudBlobError( | ||
`INVALID_API_${code}`, | ||
`Invalid ${name} object received from API ${route}`, | ||
{ cause } | ||
); | ||
} | ||
// src/utils/mimetype.ts | ||
var mimeTypesWithExtension = { | ||
"video/mp4": ["mp4"], | ||
"video/mpeg": ["mpeg"], | ||
"video/webm": ["webm"], | ||
"video/x-flv": ["flv"], | ||
"video/x-m4v": ["m4v"], | ||
"image/jpeg": ["jpg", "jpeg"], | ||
"image/png": ["png"], | ||
"image/apng": ["apng"], | ||
"image/tiff": ["tiff"], | ||
"image/gif": ["gif"], | ||
"image/webp": ["webp"], | ||
"image/bmp": ["bmp"], | ||
"image/svg+xml": ["svg"], | ||
"image/x-icon": ["ico"], | ||
"image/ico": ["ico"], | ||
"image/cur": ["cur"], | ||
"image/heic": ["heic"], | ||
"image/heif": ["heif"], | ||
"audio/wav": ["wav"], | ||
"audio/ogg": ["ogg"], | ||
"audio/opus": ["opus"], | ||
"audio/mp4": ["mp4"], | ||
"audio/mpeg": ["mp3"], | ||
"audio/aac": ["aac"], | ||
"text/plain": ["txt"], | ||
"text/html": ["html"], | ||
"text/css": ["css"], | ||
"text/csv": ["csv"], | ||
"text/x-sql": ["sql"], | ||
"application/xml": ["xml"], | ||
"application/sql": ["sql"], | ||
"application/x-sql": ["sql"], | ||
"application/x-sqlite3": ["sqlite3"], | ||
"application/x-pkcs12": ["pfx"], | ||
"application/pdf": ["pdf"], | ||
"application/json": ["json"], | ||
"application/javascript": ["js"] | ||
}; | ||
var mimeTypes = Object.keys(mimeTypesWithExtension); | ||
function getMimeTypeFromExtension(extension) { | ||
const entries = Object.entries(mimeTypesWithExtension); | ||
const mimeType = entries.find( | ||
([, extensions]) => extensions.includes(extension) | ||
)?.[0]; | ||
return mimeType || "text/plain"; | ||
} | ||
// src/assertions/list.ts | ||
function assertListObjectsResponse(value) { | ||
return handleAPIObjectAssertion({ | ||
schema: listObjectsResponseSchema, | ||
code: "LIST_OBJECTS", | ||
route: "/list", | ||
value | ||
}); | ||
// src/utils/pathlike.ts | ||
var import_promises = require("fs/promises"); | ||
async function parsePathLike(pathLike) { | ||
if (typeof pathLike === "string") { | ||
const fileBuffer = await (0, import_promises.readFile)(pathLike).catch(() => void 0); | ||
if (!fileBuffer) { | ||
throw new SquareCloudBlobError("INVALID_FILE", "File not found"); | ||
} | ||
return fileBuffer; | ||
} | ||
return pathLike; | ||
} | ||
// src/schemas/put.ts | ||
var import_zod3 = require("zod"); | ||
// src/validation/schemas/create.ts | ||
var import_zod2 = require("zod"); | ||
// src/schemas/common.ts | ||
var import_zod2 = require("zod"); | ||
var stringSchema = import_zod2.z.string(); | ||
var nameLikeSchema = import_zod2.z.string().min(3).max(32).regex(/^[a-zA-Z0-9_]{3,32}$/, { | ||
// src/validation/schemas/common.ts | ||
var import_zod = require("zod"); | ||
var stringSchema = import_zod.z.string(); | ||
var nameLikeSchema = import_zod.z.string().min(3).max(32).regex(/^[a-zA-Z0-9_]{3,32}$/, { | ||
message: "Name must contain only letters, numbers and _" | ||
}); | ||
// src/schemas/put.ts | ||
var putObjectSchema = import_zod3.z.object({ | ||
// src/validation/schemas/create.ts | ||
var createObjectSchema = import_zod2.z.object({ | ||
/** A string representing the name for the file. */ | ||
name: nameLikeSchema, | ||
/** Use absolute path or Buffer, can be a single file or compressed (zip) */ | ||
file: import_zod3.z.string().or(import_zod3.z.instanceof(Buffer)), | ||
/** Use absolute path, Buffer or Blob */ | ||
file: import_zod2.z.string().or(import_zod2.z.instanceof(Buffer)), | ||
/** A string representing the MIME type of the file. */ | ||
mimeType: import_zod2.z.enum(mimeTypes).optional(), | ||
/** A string representing the prefix for the file. */ | ||
prefix: nameLikeSchema.optional(), | ||
/** A number indicating the expiration period of the file, ranging from 1 to 365 days. */ | ||
expire: import_zod3.z.number().min(1).max(365).optional(), | ||
expire: import_zod2.z.number().min(1).max(365).optional(), | ||
/** Set to true if a security hash is required. */ | ||
securityHash: import_zod3.z.boolean().optional(), | ||
securityHash: import_zod2.z.boolean().optional(), | ||
/** Set to true if the file should be set for automatic download. */ | ||
autoDownload: import_zod3.z.boolean().optional() | ||
autoDownload: import_zod2.z.boolean().optional() | ||
}).refine(({ file, mimeType }) => !(file instanceof Buffer && !mimeType), { | ||
message: "mimeType is required if file is a Buffer", | ||
path: ["mimeType"] | ||
}); | ||
var putObjectPayloadSchema = putObjectSchema.transform( | ||
var createObjectPayloadSchema = createObjectSchema.transform( | ||
({ file, securityHash, autoDownload, ...rest }) => ({ | ||
@@ -130,13 +150,42 @@ file, | ||
); | ||
var putObjectResponseSchema = import_zod3.z.object({ | ||
var createObjectResponseSchema = import_zod2.z.object({ | ||
/** The id of the uploaded file. */ | ||
id: import_zod2.z.string(), | ||
/** The name of the uploaded file. */ | ||
name: import_zod2.z.string(), | ||
/** The prefix of the uploaded file. */ | ||
prefix: import_zod2.z.string().optional(), | ||
/** The size of the uploaded file. */ | ||
size: import_zod2.z.number(), | ||
/** The URL of the uploaded file. (File distributed in Square Cloud CDN) */ | ||
url: import_zod3.z.string() | ||
url: import_zod2.z.string() | ||
}); | ||
// src/assertions/put.ts | ||
function assertPutObjectResponse(value) { | ||
// src/validation/assertions/handlers.ts | ||
function handleAPIObjectAssertion({ | ||
schema, | ||
value, | ||
code | ||
}) { | ||
const name = code.toLowerCase().replaceAll("_", " "); | ||
try { | ||
return schema.parse(value); | ||
} catch (err) { | ||
const cause = err.errors?.map((err2) => ({ | ||
...err2, | ||
path: err2.path.join(" > ") | ||
})); | ||
throw new SquareCloudBlobError( | ||
`INVALID_API_${code}`, | ||
`Invalid ${name} object received from API`, | ||
{ cause } | ||
); | ||
} | ||
} | ||
// src/validation/assertions/create.ts | ||
function assertCreateObjectResponse(value) { | ||
return handleAPIObjectAssertion({ | ||
schema: putObjectResponseSchema, | ||
code: "PUT_OBJECT", | ||
route: "/put", | ||
schema: createObjectResponseSchema, | ||
code: "CREATE_OBJECT", | ||
value | ||
@@ -146,4 +195,25 @@ }); | ||
// src/validation/schemas/list.ts | ||
var import_zod3 = require("zod"); | ||
var listObjectSchema = import_zod3.z.object({ | ||
name: import_zod3.z.string(), | ||
size: import_zod3.z.number(), | ||
created_at: import_zod3.z.coerce.date(), | ||
expire_at: import_zod3.z.coerce.date().optional() | ||
}); | ||
var listObjectsResponseSchema = import_zod3.z.object({ | ||
objects: import_zod3.z.array(listObjectSchema) | ||
}); | ||
// src/validation/assertions/list.ts | ||
function assertListObjectsResponse(value) { | ||
return handleAPIObjectAssertion({ | ||
schema: listObjectsResponseSchema, | ||
code: "LIST_OBJECTS", | ||
value | ||
}); | ||
} | ||
// src/managers/objects.ts | ||
var BlobObjectsManager = class { | ||
var ObjectsManager = class { | ||
constructor(client) { | ||
@@ -161,4 +231,4 @@ this.client = client; | ||
async list() { | ||
const { response } = await this.client.api.request("list"); | ||
return assertListObjectsResponse(response); | ||
const { response } = await this.client.api.request("objects"); | ||
return assertListObjectsResponse(response)?.objects; | ||
} | ||
@@ -172,15 +242,20 @@ /** | ||
* ```js | ||
* await blob.objects.put({ file: "path/to/file.jpeg", name: "my_image" }); | ||
* await blob.objects.create({ file: "path/to/file.jpeg", name: "my_image" }); | ||
* ``` | ||
*/ | ||
async put(object) { | ||
const payload = putObjectPayloadSchema.parse(object); | ||
const file = await this.parseFile(payload.file); | ||
async create(object) { | ||
const payload = createObjectPayloadSchema.parse(object); | ||
const file = await parsePathLike(payload.file); | ||
const mimeType = typeof object.file === "string" ? getMimeTypeFromExtension(object.file.split(".")[1]) : object.mimeType; | ||
const formData = new FormData(); | ||
formData.append("file", new Blob([file])); | ||
formData.append("file", new Blob([file], { type: mimeType })); | ||
const { response } = await this.client.api.request( | ||
"put", | ||
{ method: "PUT", body: formData, params: payload.params } | ||
"objects", | ||
{ | ||
method: "POST", | ||
body: formData, | ||
params: payload.params | ||
} | ||
); | ||
return assertPutObjectResponse(response); | ||
return assertCreateObjectResponse(response); | ||
} | ||
@@ -194,3 +269,3 @@ /** | ||
* ```js | ||
* await blob.objects.delete("ID/prefix/name1_xxx-xxx.zip", "ID/prefix/name_xxx-xxx-xxx.png"); | ||
* await blob.objects.delete("ID/prefix/name1_xxx-xxx.mp4", "ID/prefix/name_xxx-xxx-xxx.png"); | ||
* ``` | ||
@@ -200,18 +275,13 @@ */ | ||
const ids = objects.flat(); | ||
const response = await this.client.api.request("delete", { | ||
const { status } = await this.client.api.request("objects", { | ||
method: "DELETE", | ||
body: { objects: ids } | ||
}); | ||
return response.status === "success"; | ||
return status === "success"; | ||
} | ||
async parseFile(file) { | ||
let result; | ||
if (typeof file === "string") { | ||
result = await (0, import_promises.readFile)(file).catch(() => void 0); | ||
} | ||
if (!result) { | ||
throw new SquareCloudBlobError("INVALID_FILE", "File not found"); | ||
} | ||
return result; | ||
} | ||
/** | ||
* Parses the object URL to extract id, prefix, and name. | ||
* | ||
* @param url - The object URL to parse. | ||
*/ | ||
parseObjectUrl(url) { | ||
@@ -236,3 +306,3 @@ const pattern = /^https:\/\/public-blob\.squarecloud\.dev\/([^\/]+)\/([^\/]+\/)?([^_]+)_[\w-]+\.\w+$/; | ||
__publicField(this, "api"); | ||
__publicField(this, "objects", new BlobObjectsManager(this)); | ||
__publicField(this, "objects", new ObjectsManager(this)); | ||
this.api = new APIManager(apiKey); | ||
@@ -239,0 +309,0 @@ } |
@@ -1,6 +0,9 @@ | ||
export { B as BlobObjectsManager } from '../index-D3kETQQ8.js'; | ||
import '../types/put.js'; | ||
export { O as ObjectsManager } from '../index-CTI71HKx.js'; | ||
import '../types/create.js'; | ||
import './api.js'; | ||
import '../types/api.js'; | ||
import '../types/list.js'; | ||
import 'zod'; | ||
import '../schemas/put.js'; | ||
import '../validation/schemas/list.js'; | ||
import '../utils/mimetype.js'; | ||
import '../validation/schemas/create.js'; |
@@ -22,17 +22,6 @@ var __defProp = Object.defineProperty; | ||
__export(objects_exports, { | ||
BlobObjectsManager: () => BlobObjectsManager | ||
ObjectsManager: () => ObjectsManager | ||
}); | ||
module.exports = __toCommonJS(objects_exports); | ||
var import_promises = require("fs/promises"); | ||
// src/schemas/list.ts | ||
var import_zod = require("zod"); | ||
var listObjectSchema = import_zod.z.object({ | ||
name: import_zod.z.string(), | ||
size: import_zod.z.number(), | ||
created_at: import_zod.z.coerce.date(), | ||
expire_at: import_zod.z.coerce.date().optional() | ||
}); | ||
var listObjectsResponseSchema = import_zod.z.array(listObjectSchema); | ||
// src/structures/error.ts | ||
@@ -44,3 +33,2 @@ var SquareCloudBlobError = class _SquareCloudBlobError extends Error { | ||
this.message = this.getMessage(code); | ||
Error.captureStackTrace(this, _SquareCloudBlobError); | ||
} | ||
@@ -54,61 +42,95 @@ getMessage(rawCode) { | ||
// src/assertions/handlers.ts | ||
function handleAPIObjectAssertion({ | ||
schema, | ||
value, | ||
code, | ||
route | ||
}) { | ||
const name = code.toLowerCase().replaceAll("_", " "); | ||
try { | ||
return schema.parse(value); | ||
} catch (err) { | ||
const cause = err.errors?.map((err2) => ({ | ||
...err2, | ||
path: err2.path.join(" > ") | ||
})); | ||
throw new SquareCloudBlobError( | ||
`INVALID_API_${code}`, | ||
`Invalid ${name} object received from API ${route}`, | ||
{ cause } | ||
); | ||
} | ||
// src/utils/mimetype.ts | ||
var mimeTypesWithExtension = { | ||
"video/mp4": ["mp4"], | ||
"video/mpeg": ["mpeg"], | ||
"video/webm": ["webm"], | ||
"video/x-flv": ["flv"], | ||
"video/x-m4v": ["m4v"], | ||
"image/jpeg": ["jpg", "jpeg"], | ||
"image/png": ["png"], | ||
"image/apng": ["apng"], | ||
"image/tiff": ["tiff"], | ||
"image/gif": ["gif"], | ||
"image/webp": ["webp"], | ||
"image/bmp": ["bmp"], | ||
"image/svg+xml": ["svg"], | ||
"image/x-icon": ["ico"], | ||
"image/ico": ["ico"], | ||
"image/cur": ["cur"], | ||
"image/heic": ["heic"], | ||
"image/heif": ["heif"], | ||
"audio/wav": ["wav"], | ||
"audio/ogg": ["ogg"], | ||
"audio/opus": ["opus"], | ||
"audio/mp4": ["mp4"], | ||
"audio/mpeg": ["mp3"], | ||
"audio/aac": ["aac"], | ||
"text/plain": ["txt"], | ||
"text/html": ["html"], | ||
"text/css": ["css"], | ||
"text/csv": ["csv"], | ||
"text/x-sql": ["sql"], | ||
"application/xml": ["xml"], | ||
"application/sql": ["sql"], | ||
"application/x-sql": ["sql"], | ||
"application/x-sqlite3": ["sqlite3"], | ||
"application/x-pkcs12": ["pfx"], | ||
"application/pdf": ["pdf"], | ||
"application/json": ["json"], | ||
"application/javascript": ["js"] | ||
}; | ||
var mimeTypes = Object.keys(mimeTypesWithExtension); | ||
function getMimeTypeFromExtension(extension) { | ||
const entries = Object.entries(mimeTypesWithExtension); | ||
const mimeType = entries.find( | ||
([, extensions]) => extensions.includes(extension) | ||
)?.[0]; | ||
return mimeType || "text/plain"; | ||
} | ||
// src/assertions/list.ts | ||
function assertListObjectsResponse(value) { | ||
return handleAPIObjectAssertion({ | ||
schema: listObjectsResponseSchema, | ||
code: "LIST_OBJECTS", | ||
route: "/list", | ||
value | ||
}); | ||
// src/utils/pathlike.ts | ||
var import_promises = require("fs/promises"); | ||
async function parsePathLike(pathLike) { | ||
if (typeof pathLike === "string") { | ||
const fileBuffer = await (0, import_promises.readFile)(pathLike).catch(() => void 0); | ||
if (!fileBuffer) { | ||
throw new SquareCloudBlobError("INVALID_FILE", "File not found"); | ||
} | ||
return fileBuffer; | ||
} | ||
return pathLike; | ||
} | ||
// src/schemas/put.ts | ||
var import_zod3 = require("zod"); | ||
// src/validation/schemas/create.ts | ||
var import_zod2 = require("zod"); | ||
// src/schemas/common.ts | ||
var import_zod2 = require("zod"); | ||
var stringSchema = import_zod2.z.string(); | ||
var nameLikeSchema = import_zod2.z.string().min(3).max(32).regex(/^[a-zA-Z0-9_]{3,32}$/, { | ||
// src/validation/schemas/common.ts | ||
var import_zod = require("zod"); | ||
var stringSchema = import_zod.z.string(); | ||
var nameLikeSchema = import_zod.z.string().min(3).max(32).regex(/^[a-zA-Z0-9_]{3,32}$/, { | ||
message: "Name must contain only letters, numbers and _" | ||
}); | ||
// src/schemas/put.ts | ||
var putObjectSchema = import_zod3.z.object({ | ||
// src/validation/schemas/create.ts | ||
var createObjectSchema = import_zod2.z.object({ | ||
/** A string representing the name for the file. */ | ||
name: nameLikeSchema, | ||
/** Use absolute path or Buffer, can be a single file or compressed (zip) */ | ||
file: import_zod3.z.string().or(import_zod3.z.instanceof(Buffer)), | ||
/** Use absolute path, Buffer or Blob */ | ||
file: import_zod2.z.string().or(import_zod2.z.instanceof(Buffer)), | ||
/** A string representing the MIME type of the file. */ | ||
mimeType: import_zod2.z.enum(mimeTypes).optional(), | ||
/** A string representing the prefix for the file. */ | ||
prefix: nameLikeSchema.optional(), | ||
/** A number indicating the expiration period of the file, ranging from 1 to 365 days. */ | ||
expire: import_zod3.z.number().min(1).max(365).optional(), | ||
expire: import_zod2.z.number().min(1).max(365).optional(), | ||
/** Set to true if a security hash is required. */ | ||
securityHash: import_zod3.z.boolean().optional(), | ||
securityHash: import_zod2.z.boolean().optional(), | ||
/** Set to true if the file should be set for automatic download. */ | ||
autoDownload: import_zod3.z.boolean().optional() | ||
autoDownload: import_zod2.z.boolean().optional() | ||
}).refine(({ file, mimeType }) => !(file instanceof Buffer && !mimeType), { | ||
message: "mimeType is required if file is a Buffer", | ||
path: ["mimeType"] | ||
}); | ||
var putObjectPayloadSchema = putObjectSchema.transform( | ||
var createObjectPayloadSchema = createObjectSchema.transform( | ||
({ file, securityHash, autoDownload, ...rest }) => ({ | ||
@@ -123,13 +145,42 @@ file, | ||
); | ||
var putObjectResponseSchema = import_zod3.z.object({ | ||
var createObjectResponseSchema = import_zod2.z.object({ | ||
/** The id of the uploaded file. */ | ||
id: import_zod2.z.string(), | ||
/** The name of the uploaded file. */ | ||
name: import_zod2.z.string(), | ||
/** The prefix of the uploaded file. */ | ||
prefix: import_zod2.z.string().optional(), | ||
/** The size of the uploaded file. */ | ||
size: import_zod2.z.number(), | ||
/** The URL of the uploaded file. (File distributed in Square Cloud CDN) */ | ||
url: import_zod3.z.string() | ||
url: import_zod2.z.string() | ||
}); | ||
// src/assertions/put.ts | ||
function assertPutObjectResponse(value) { | ||
// src/validation/assertions/handlers.ts | ||
function handleAPIObjectAssertion({ | ||
schema, | ||
value, | ||
code | ||
}) { | ||
const name = code.toLowerCase().replaceAll("_", " "); | ||
try { | ||
return schema.parse(value); | ||
} catch (err) { | ||
const cause = err.errors?.map((err2) => ({ | ||
...err2, | ||
path: err2.path.join(" > ") | ||
})); | ||
throw new SquareCloudBlobError( | ||
`INVALID_API_${code}`, | ||
`Invalid ${name} object received from API`, | ||
{ cause } | ||
); | ||
} | ||
} | ||
// src/validation/assertions/create.ts | ||
function assertCreateObjectResponse(value) { | ||
return handleAPIObjectAssertion({ | ||
schema: putObjectResponseSchema, | ||
code: "PUT_OBJECT", | ||
route: "/put", | ||
schema: createObjectResponseSchema, | ||
code: "CREATE_OBJECT", | ||
value | ||
@@ -139,4 +190,25 @@ }); | ||
// src/validation/schemas/list.ts | ||
var import_zod3 = require("zod"); | ||
var listObjectSchema = import_zod3.z.object({ | ||
name: import_zod3.z.string(), | ||
size: import_zod3.z.number(), | ||
created_at: import_zod3.z.coerce.date(), | ||
expire_at: import_zod3.z.coerce.date().optional() | ||
}); | ||
var listObjectsResponseSchema = import_zod3.z.object({ | ||
objects: import_zod3.z.array(listObjectSchema) | ||
}); | ||
// src/validation/assertions/list.ts | ||
function assertListObjectsResponse(value) { | ||
return handleAPIObjectAssertion({ | ||
schema: listObjectsResponseSchema, | ||
code: "LIST_OBJECTS", | ||
value | ||
}); | ||
} | ||
// src/managers/objects.ts | ||
var BlobObjectsManager = class { | ||
var ObjectsManager = class { | ||
constructor(client) { | ||
@@ -154,4 +226,4 @@ this.client = client; | ||
async list() { | ||
const { response } = await this.client.api.request("list"); | ||
return assertListObjectsResponse(response); | ||
const { response } = await this.client.api.request("objects"); | ||
return assertListObjectsResponse(response)?.objects; | ||
} | ||
@@ -165,15 +237,20 @@ /** | ||
* ```js | ||
* await blob.objects.put({ file: "path/to/file.jpeg", name: "my_image" }); | ||
* await blob.objects.create({ file: "path/to/file.jpeg", name: "my_image" }); | ||
* ``` | ||
*/ | ||
async put(object) { | ||
const payload = putObjectPayloadSchema.parse(object); | ||
const file = await this.parseFile(payload.file); | ||
async create(object) { | ||
const payload = createObjectPayloadSchema.parse(object); | ||
const file = await parsePathLike(payload.file); | ||
const mimeType = typeof object.file === "string" ? getMimeTypeFromExtension(object.file.split(".")[1]) : object.mimeType; | ||
const formData = new FormData(); | ||
formData.append("file", new Blob([file])); | ||
formData.append("file", new Blob([file], { type: mimeType })); | ||
const { response } = await this.client.api.request( | ||
"put", | ||
{ method: "PUT", body: formData, params: payload.params } | ||
"objects", | ||
{ | ||
method: "POST", | ||
body: formData, | ||
params: payload.params | ||
} | ||
); | ||
return assertPutObjectResponse(response); | ||
return assertCreateObjectResponse(response); | ||
} | ||
@@ -187,3 +264,3 @@ /** | ||
* ```js | ||
* await blob.objects.delete("ID/prefix/name1_xxx-xxx.zip", "ID/prefix/name_xxx-xxx-xxx.png"); | ||
* await blob.objects.delete("ID/prefix/name1_xxx-xxx.mp4", "ID/prefix/name_xxx-xxx-xxx.png"); | ||
* ``` | ||
@@ -193,18 +270,13 @@ */ | ||
const ids = objects.flat(); | ||
const response = await this.client.api.request("delete", { | ||
const { status } = await this.client.api.request("objects", { | ||
method: "DELETE", | ||
body: { objects: ids } | ||
}); | ||
return response.status === "success"; | ||
return status === "success"; | ||
} | ||
async parseFile(file) { | ||
let result; | ||
if (typeof file === "string") { | ||
result = await (0, import_promises.readFile)(file).catch(() => void 0); | ||
} | ||
if (!result) { | ||
throw new SquareCloudBlobError("INVALID_FILE", "File not found"); | ||
} | ||
return result; | ||
} | ||
/** | ||
* Parses the object URL to extract id, prefix, and name. | ||
* | ||
* @param url - The object URL to parse. | ||
*/ | ||
parseObjectUrl(url) { | ||
@@ -226,4 +298,4 @@ const pattern = /^https:\/\/public-blob\.squarecloud\.dev\/([^\/]+)\/([^\/]+\/)?([^_]+)_[\w-]+\.\w+$/; | ||
0 && (module.exports = { | ||
BlobObjectsManager | ||
ObjectsManager | ||
}); | ||
//# sourceMappingURL=objects.js.map |
@@ -31,3 +31,2 @@ var __defProp = Object.defineProperty; | ||
this.message = this.getMessage(code); | ||
Error.captureStackTrace(this, _SquareCloudBlobError); | ||
} | ||
@@ -34,0 +33,0 @@ getMessage(rawCode) { |
@@ -13,5 +13,4 @@ import { ZodSchema } from 'zod'; | ||
code: string; | ||
route: string; | ||
}; | ||
export type { APIObjectAssertionProps, BaseAssertionProps, LiteralAssertionProps }; |
import { z } from 'zod'; | ||
import { listObjectsResponseSchema } from '../schemas/list.js'; | ||
import { listObjectsResponseSchema } from '../validation/schemas/list.js'; | ||
@@ -4,0 +4,0 @@ type ListObjectsResponse = z.infer<typeof listObjectsResponseSchema>; |
{ | ||
"name": "@squarecloud/blob", | ||
"private": false, | ||
"version": "0.1.0", | ||
"version": "1.0.0", | ||
"description": "Official Square Cloud Blob SDK for NodeJS", | ||
@@ -6,0 +6,0 @@ "main": "lib/index.js", |
@@ -31,9 +31,11 @@ <div align="center"> | ||
Visit our [official API documentation](https://docs.squarecloud.app/blob-reference/) for more information about how this service. | ||
Visit our [official API documentation](https://docs.squarecloud.app/blob-reference/) for more information about this service. | ||
## Getting Started | ||
- _Login and get your API Key at [https://squarecloud.app/account](https://squarecloud.app/account)._ | ||
```ts | ||
import { SquareCloudBlob } from "@squarecloud/blob" | ||
// const { SquareCloudBlob } = require("@squarecloud/blob"); | ||
// CommonJS => const { SquareCloudBlob } = require("@squarecloud/blob"); | ||
@@ -46,11 +48,37 @@ const blob = new SquareCloudBlob("Your API Key") | ||
- _Check supported file types [here](https://docs.squarecloud.app/services/blob#supported-file-types)._ | ||
```ts | ||
const object = await blob.objects.put({ file: "path/to/file.png", name: "my_image" }) | ||
console.log(object.url) | ||
const blobObject = await blob.objects.create({ | ||
file: "path/to/file.png", // Absolute path to your file | ||
name: "my_image", // File name without extension | ||
}) | ||
console.log(blobObject.url) | ||
``` | ||
#### Advanced usage with Buffer | ||
```ts | ||
import { MimeTypes } from "@squarecloud/blob" | ||
// CommonJS => const { MimeTypes } = require("@squarecloud/blob") | ||
const blobObject = await blob.objects.create({ | ||
file: Buffer.from("content"), | ||
name: "my_image", | ||
mimeType: MimeTypes.IMAGE_JPEG, // Also accepts an string "image/jpeg" | ||
}) | ||
console.log(blobObject.url) | ||
``` | ||
### Deleting objects | ||
```ts | ||
const objectsToDelete = ["ID/prefix/name1_xxx-xxx.zip", "ID/prefix/name_xxx-xxx-xxx.png"] | ||
// List of objects to delete (Limit of 100 per request) | ||
const objectsToDelete = [ | ||
"ID/prefix/name1_xxx-xxx.mp4", | ||
"ID/prefix/name_xxx-xxx-xxx.png" | ||
] | ||
await blob.objects.delete(objectsToDelete) | ||
@@ -57,0 +85,0 @@ ``` |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
Major refactor
Supply chain riskPackage has recently undergone a major refactor. It may be unstable or indicate significant internal changes. Use caution when updating to versions that include significant changes.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
No v1
QualityPackage is not semver >=1. This means it is not stable and does not support ^ ranges.
Found 1 instance in 1 package
362362
118
3888
0
91
8
5