azion
Version:
Azion Packages for Edge Computing.
846 lines (845 loc) • 24.6 kB
JavaScript
function S(r) {
return r.replace(/^\//, "");
}
const v = async (r, e = 1e3, o) => {
let s = 0;
const t = 12e4, a = Date.now();
for (; Date.now() - a < t; )
try {
return await r();
} catch (n) {
if (o && console.error("Error in retryWithBackoff:", n), s === 0 && console.warn("Attempting to synchronize. The content may not be synchronized on the edge yet."), Date.now() - a >= t)
throw new Error("Max retry time reached");
console.log(`Retry attempt ${s + 1} failed. Retrying in ${e * Math.pow(2, s)} ms...`), await new Promise((c) => setTimeout(c, e * Math.pow(2, s))), s++;
}
throw new Error("Max retry time reached");
};
async function U(r, e, o) {
const s = r.headers.get("Content-Type"), t = s?.includes("application/json");
if (!t && e) {
const n = `Expected JSON response, but got: ${await r.text()}`;
throw o && console.log(`Error in fetch: ${n}`), new Error(n);
}
return t ? r.json() : (s?.includes("application/octet-stream"), r.text());
}
async function p(r, e, o, s = !0) {
const t = await fetch(r, e);
if (!t.ok)
try {
const n = await U(t, !0, o);
if (o && console.log("Error response body:", n), n.errors && Array.isArray(n.errors) && n.errors.length > 0 || n.detail || n.message)
return n;
const c = `HTTP error! Status: ${t.status} - ${t.statusText}`;
throw o && console.log(`Error in fetch: ${c}`), new Error(c);
} catch {
const n = `HTTP error! Status: ${t.status} - ${t.statusText}`;
throw o && console.log(`Error in fetch: ${n}`), new Error(n);
}
return await U(t, s, o);
}
const g = (r = "production") => ({
production: "https://api.azion.com/v4/workspace/storage",
development: "/v4/workspace/storage",
staging: "https://stage-api.azion.com/v4/workspace/storage"
})[r], $ = (r, e = {}) => {
const o = {
Accept: "application/json",
...e
};
return r ? {
...o,
Authorization: `Token ${r}`
} : o;
}, T = (r, e, o) => ({
method: r,
headers: e,
credentials: "include"
}), b = (r, e, o) => {
let s = { message: "Error unknown", operation: o };
if (e.errors && Array.isArray(e.errors) && e.errors.length > 0) {
const t = e.errors[0];
if (t.detail)
return s = {
message: t.detail,
operation: o
}, s;
if (t.title)
return s = {
message: t.title,
operation: o
}, s;
}
return r.forEach((t) => {
e[t] && (s = {
message: Array.isArray(e[t]) ? e[t].join(", ") : e[t],
operation: o
});
}), s;
}, W = async (r, e, o, s = "production") => {
try {
const { page_size: t = 10, page: a = 1, search: n, ordering: c, fields: i } = e || {}, u = new URLSearchParams({ page_size: String(t), page: String(a) });
n && u.append("search", n), c && u.append("ordering", c), i && u.append("fields", i);
const h = $(r, { Accept: "application/json; version=3" }), z = T("GET", h), P = g(s), y = await p(`${P}/buckets?${u.toString()}`, z, o);
return y.results ? (o && console.log("Response:", y), y) : (y.error = b(["detail"], y, "get all buckets"), {
error: y.error ?? JSON.stringify(y)
});
} catch (t) {
return o && console.error("Error getting all buckets:", t), {
error: { message: t.toString(), operation: "get all buckets" }
};
}
}, J = async (r, e, o, s, t = "production") => {
try {
const a = new URLSearchParams(), n = $(r, { Accept: "application/json; version=3" }), c = T("GET", n), u = `${g(t)}/buckets/${e}${a.toString() ? `?${a.toString()}` : ""}`;
s && console.log(`GET bucket URL: ${u}`);
const h = await p(u, c, s);
return h.data ? (s && console.log("Response:", h), h) : {
error: b(["detail"], h, "get bucket by name")
};
} catch (a) {
return s && console.error("Error getting bucket by name:", a), {
error: { message: a.toString(), operation: "get bucket by name" }
};
}
}, D = async (r, e, o, s, t = "production") => {
try {
const a = g(t), n = await p(
`${a}/buckets`,
{
method: "POST",
headers: { Accept: "application/json", "Content-Type": "application/json", Authorization: `Token ${r}` },
body: JSON.stringify({ name: e, workloads_access: o })
},
s
);
return n?.state ? (s && console.log("Response:", n), n) : (n.error = b(["name", "workloads_access", "detail"], n, "create bucket"), {
error: n.error ?? JSON.stringify(n)
});
} catch (a) {
return s && console.error("Error creating bucket:", a), {
error: { message: a.toString(), operation: "create bucket" }
};
}
}, L = async (r, e, o, s, t = "production") => {
try {
const a = g(t), n = await p(
`${a}/buckets/${e}`,
{
method: "PATCH",
headers: { Accept: "application/json", "Content-Type": "application/json", Authorization: `Token ${r}` },
body: JSON.stringify({ workloads_access: o })
},
s
);
return n?.state ? (s && console.log("Response:", n), n) : (n.error = b(["name", "workloads_access", "detail"], n, "update bucket"), {
error: n.error ?? JSON.stringify(n)
});
} catch (a) {
return s && console.error("Error updating bucket:", a), {
error: { message: a.toString(), operation: "update bucket" }
};
}
}, F = async (r, e, o, s = "production") => {
try {
const t = g(s), a = await p(
`${t}/buckets/${e}`,
{
method: "DELETE",
headers: { Accept: "application/json", Authorization: `Token ${r}` }
},
o
);
return a?.state ? (o && console.log("Response Delete Bucket:", a), a) : (a.error = b(["detail"], a, "delete bucket"), {
error: a.error ?? JSON.stringify(a)
});
} catch (t) {
return o && console.error("Error deleting bucket:", t), {
error: { message: t.toString(), operation: "delete bucket" }
};
}
}, G = async (r, e, o, s, t = "production") => {
try {
const { max_object_count: a = 1e4 } = o || {}, n = new URLSearchParams({ max_object_count: String(a) }), c = g(t), i = await p(
`${c}/buckets/${e}/objects?${n.toString()}`,
{
method: "GET",
headers: { Accept: "application/json", Authorization: `Token ${r}` }
},
s
);
return i.results ? (s && console.log("Response:", i), i) : (i.error = b(["detail"], i, "get all objects"), {
error: i.error ?? JSON.stringify(i)
});
} catch (a) {
return s && console.error("Error getting all objects:", a), {
error: { message: a.toString(), operation: "get all objects" }
};
}
}, H = async (r, e, o, s, t = "application/octet-stream", a, n = "production") => {
try {
const c = g(n), i = typeof s == "string" ? new TextEncoder().encode(s) : s, u = await p(
`${c}/buckets/${e}/objects/${o}`,
{
method: "POST",
headers: {
Accept: "application/json",
"Content-Type": t,
Authorization: `Token ${r}`
},
body: i
},
a
);
return u?.state ? (a && console.log("Response:", u), u) : (u.error = b(["detail"], u, "create object"), {
error: u.error ?? JSON.stringify(u)
});
} catch (c) {
return a && console.error("Error posting object:", c), {
error: { message: c.toString(), operation: "create object" }
};
}
}, I = async (r, e, o, s, t = "production") => {
try {
const a = g(t), n = $(r), c = T("GET", n), i = await p(`${a}/buckets/${e}/objects/${o}`, c, s, !1);
return i.error || i.errors ? { error: b(["detail"], i, "get object by key") } : (s && console.log("Response:", i), { data: i });
} catch (a) {
return s && console.error("Error getting object by name:", a), {
error: { message: a.toString(), operation: "get object by key" }
};
}
}, q = async (r, e, o, s, t = "application/octet-stream", a, n = "production") => {
try {
const c = g(n), i = typeof s == "string" ? new TextEncoder().encode(s) : s, u = await p(
`${c}/buckets/${e}/objects/${o}`,
{
method: "PUT",
headers: {
Accept: "application/json",
"Content-Type": t,
Authorization: `Token ${r}`
},
body: i
},
a
);
return u.error || u.errors ? (u.error = b(["detail"], u, "put object"), {
error: u.error ?? JSON.stringify(u)
}) : (a && console.log("Response:", u), u);
} catch (c) {
return a && console.error("Error putting object:", c), {
error: { message: c.toString(), operation: "put object" }
};
}
}, Z = async (r, e, o, s, t = "production") => {
try {
const a = g(t), n = await p(
`${a}/buckets/${e}/objects/${o}`,
{
method: "DELETE",
headers: { Accept: "application/json", Authorization: `Token ${r}` }
},
s
);
return n?.state ? (s && console.log("Response:", n), n) : (n.error = b(["detail"], n, "delete object"), {
error: n.error ?? JSON.stringify(n)
});
} catch (a) {
return s && console.error("Error deleting object:", a), {
error: { message: a.toString(), operation: "delete object" }
};
}
}, V = () => globalThis.Azion?.Storage || null;
class f {
constructor(e, o) {
this.token = e, this.debug = o;
}
token;
debug;
storage = null;
/**
* Initializes the storage instance if not already initialized.
*
* @param {string} bucketName The name of the bucket to initialize.
*/
initializeStorage(e) {
this.storage || (this.storage = new globalThis.Azion.Storage(e), this.name = e);
}
name = "";
// @ts-expect-error - workloads_access is not defined in the AzionBucket interface
workloads_access = "unknown";
/**
* Retrieves a bucket by name.
*
* @param {Object} params - Parameters for retrieving a bucket.
* @param {string} params.name - The name of the bucket.
* @returns {Promise<AzionBucket | null>} The bucket object or null if not found.
*/
async getBucket({ name: e }) {
return this.initializeStorage(e), this.storage ? (this.name = e, {
name: e,
// @ts-expect-error - workloads_access is not defined in the AzionBucket interface
workloads_access: "unknown",
state: "executed-runtime",
getObjects: this.getObjects.bind(this),
getObjectByKey: this.getObjectByKey.bind(this),
createObject: this.createObject.bind(this),
updateObject: this.updateObject.bind(this),
deleteObject: this.deleteObject.bind(this)
}) : null;
}
/**
* Retrieves all objects in the bucket.
*
* Uses retry with exponential backoff to handle eventual consistency delays.
*
* @param {Object} params - Parameters for object collection.
* @param {AzionObjectCollectionParams} [params.params] - Parameters for object collection.
* @returns {Promise<AzionStorageResponse<AzionBucketObjects>>} The list of objects or error message.
*/
async getObjects({
params: e
}) {
this.initializeStorage(this.name);
try {
const o = await v(() => this.storage.list()), s = e?.max_object_count ?? o.entries.length, t = await Promise.all(
o.entries.slice(0, s).map(async (a) => ({
key: S(a.key),
size: a.content_length,
state: "executed-runtime"
}))
);
return {
data: {
objects: t,
count: t.length
}
};
} catch (o) {
return this.debug && console.error("Error getting objects:", o), {
error: {
message: o?.message ?? "Error getting objects",
operation: "getObjects"
}
};
}
}
/**
* Retrieves an object by key.
*
* Uses retry with exponential backoff to handle eventual consistency delays.
*
* @param {Object} params - Parameters for retrieving an object.
* @param {string} params.key - The key of the object to retrieve.
* @returns {Promise<AzionStorageResponse<AzionBucketObject>>} The object or null if an error occurs.
*/
async getObjectByKey({ key: e }) {
this.initializeStorage(this.name);
try {
const o = await v(() => this.storage.get(e)), s = await o.arrayBuffer();
return {
data: {
state: "executed-runtime",
key: S(e),
size: o.contentLength,
content: s,
content_type: o.metadata?.get("content-type")
}
};
} catch (o) {
return this.debug && console.error("Error getting object by key:", o), {
error: {
message: o?.message ?? "Error getting object by key",
operation: "getObjectByKey"
}
};
}
}
/**
* Creates a new object in the bucket.
*
* Uses retry with exponential backoff to handle eventual consistency delays.
*
* @param {Object} params - Parameters for creating an object.
* @param {string} params.key - The key of the object to create.
* @param {ContentObjectStorage} params.content - The content of the object.
* @param {{ content_type?: string }} [params.options] - Optional metadata for the object.
* @returns {Promise<AzionStorageResponse<AzionBucketObject>>} The created object or error message.
*/
async createObject({
key: e,
content: o,
options: s
}) {
this.initializeStorage(this.name);
try {
const t = typeof o == "string" ? new TextEncoder().encode(o) : o;
await v(
() => this.storage.put(e, t, {
"content-type": s?.content_type
}),
1e3,
this.debug
);
const a = o instanceof ArrayBuffer ? o.byteLength : o.toString().length;
return {
data: {
state: "executed-runtime",
key: S(e),
size: a,
content_type: s?.content_type
}
};
} catch (t) {
return this.debug && console.error("Error creating object:", t), {
error: {
message: t?.message ?? "Error creating object",
operation: "createObject"
}
};
}
}
/**
* Updates an existing object in the bucket.
*
* Uses retry with exponential backoff to handle eventual consistency delays.
*
* @param {Object} params - Parameters for updating an object.
* @param {string} params.key - The key of the object to update.
* @param {ContentObjectStorage} params.content - The new content of the object.
* @param {{ content_type?: string }} [params.options] - Optional metadata for the object.
* @returns {Promise<AzionStorageResponse<AzionBucketObject>>} The updated object or error message.
*/
async updateObject({
key: e,
content: o,
options: s
}) {
return this.createObject({ key: e, content: o, options: s });
}
/**
* Deletes an object from the bucket.
*
* Uses retry with exponential backoff to handle eventual consistency delays.
*
* @param {Object} params - Parameters for deleting an object.
* @param {string} params.key - The key of the object to delete.
* @returns {Promise<AzionStorageResponse<AzionDeletedBucketObject>>} Confirmation of deletion or error if an error occurs.
*/
async deleteObject({ key: e }) {
this.initializeStorage(this.name);
try {
return await v(() => this.storage.delete(e)), { data: { key: S(e), state: "executed-runtime" } };
} catch (o) {
return this.debug && console.error("Error deleting object:", o), {
error: {
message: o?.message ?? "Error deleting object",
operation: "deleteObject"
}
};
}
}
}
const R = () => typeof window < "u" && typeof window.document < "u", Q = !R() && process?.env.AZION_DEBUG === "true", d = (r) => R() ? r ?? "" : r ?? process?.env.AZION_TOKEN ?? "", j = (r) => r ?? !!Q, m = (r) => R() ? r ?? "production" : r ?? process?.env.AZION_ENV ?? "production", l = (r) => ({
...r,
debug: j(r?.debug),
env: m(r?.env)
}), O = (r, e) => ((...o) => {
const s = o[o.length - 1];
return l(s).external || !V() ? e(...o) : r(...o);
}), A = async (r, e, o, s) => {
const t = l(s), a = await D(
d(r),
e,
o,
t.debug,
t.env
);
return a.data ? {
data: {
...a.data,
workloads_access: a.data.workloads_access,
last_editor: a.data.last_editor,
last_modified: a.data.last_modified,
product_version: a.data.product_version,
getObjects: ({
params: n
}) => w(r, e, n, t),
getObjectByKey: ({ key: n }) => k(r, e, n, t),
createObject: ({
key: n,
content: c,
params: i
}) => _(r, e, n, c, i, t),
updateObject: ({
key: n,
content: c,
params: i
}) => B(r, e, n, c, i, t),
deleteObject: ({ key: n }) => E(r, e, n, t)
}
} : {
error: a.error
};
}, C = async (r, e, o) => {
const s = l(o), t = await F(d(r), e, s.debug, s.env);
return t.data ? { data: { name: t.data.name, state: t.state } } : {
error: t.error
};
}, M = async (r, e, o) => {
const s = l(o), t = await W(d(r), e, s.debug, s.env);
if (t?.results) {
const a = t.results?.map((n) => ({
...n,
workloads_access: n.workloads_access,
last_editor: n.last_editor,
last_modified: n.last_modified,
product_version: n.product_version,
getObjects: ({
params: c
}) => w(r, n.name, c, s),
getObjectByKey: ({ key: c }) => k(r, n.name, c, s),
createObject: ({
key: c,
content: i,
params: u
}) => _(r, n.name, c, i, u, s),
updateObject: ({
key: c,
content: i,
params: u
}) => B(r, n.name, c, i, u, s),
deleteObject: ({ key: c }) => E(r, n.name, c, s)
}));
return {
data: {
buckets: a,
count: t.count ?? a.length
}
};
}
return {
error: t.error
};
}, x = async (r, e, o) => {
const s = l(o), t = await J(
d(r),
e,
void 0,
// fields parameter
s.debug,
s.env
);
if (t.data) {
const a = t.data;
return {
data: {
name: a.name,
workloads_access: a.workloads_access,
last_editor: a.last_editor,
last_modified: a.last_modified,
product_version: a.product_version,
getObjects: ({
params: n
}) => w(r, e, n, s),
getObjectByKey: ({ key: n }) => k(r, e, n, s),
createObject: ({
key: n,
content: c,
params: i
}) => _(r, e, n, c, i, s),
updateObject: ({
key: n,
content: c,
params: i
}) => B(r, e, n, c, i, s),
deleteObject: ({ key: n }) => E(r, e, n, s)
}
};
}
return {
error: {
message: t.error?.message ?? "Bucket not found",
operation: "get bucket"
}
};
}, N = async (r, e, o, s) => {
const t = l(s), a = await L(
d(r),
e,
o,
t.debug,
t.env
);
return a?.data ? {
data: {
...a.data,
workloads_access: a.data.workloads_access,
last_editor: a.data.last_editor,
last_modified: a.data.last_modified,
product_version: a.data.product_version,
getObjects: ({
params: n
}) => w(r, e, n, t),
getObjectByKey: ({ key: n }) => k(r, e, n, t),
createObject: ({
key: n,
content: c,
params: i
}) => _(r, e, n, c, i, t),
updateObject: ({
key: n,
content: c,
params: i
}) => B(r, e, n, c, i, t),
deleteObject: ({ key: n }) => E(r, e, n, t)
}
} : {
error: a.error
};
}, K = async (r, e, o, s) => {
const t = l(s), a = await x(r, e, t);
if (a.data)
return t.debug && console.log(`Bucket '${e}' already exists`), a;
t.debug && console.log(`Bucket '${e}' not found, creating...`);
const n = await A(r, e, o, t);
return n.data ? (t.debug && console.log(`Bucket '${e}' created successfully`), n) : {
error: {
message: n.error?.message ?? `Failed to setup storage bucket '${e}'`,
operation: "setup storage"
}
};
}, w = O(
async (r, e, o, s) => {
const t = new f(r, s?.debug);
t.name = e;
const a = await t.getObjects({ params: o });
return a.data ? {
data: a.data
} : {
error: {
message: "Failed to retrieve objects",
operation: "get objects"
}
};
},
async (r, e, o, s) => {
const t = await G(d(r), e, o, s?.debug, s?.env);
return t.results ? {
data: {
objects: t.results,
count: t.results.length
}
} : {
error: t?.error
};
}
), k = O(
async (r, e, o, s) => {
const t = new f(r, s?.debug);
t.name = e;
const a = await t.getObjectByKey({ key: o });
return a.data ? {
data: a.data
} : {
error: {
message: "Failed to retrieve object",
operation: "get object by key"
}
};
},
async (r, e, o, s) => {
const t = await I(
d(r),
e,
o,
j(s?.debug),
m(s?.env)
);
return t.data ? {
data: {
key: o,
content: t.data
}
} : {
error: t.error
};
}
), _ = O(
async (r, e, o, s, t, a) => {
const n = new f(r, a?.debug);
n.name = e;
const c = await n.createObject({ key: o, content: s, options: t });
return c?.data ? {
data: c.data
} : {
error: {
message: "Failed to create object",
operation: "create object"
}
};
},
async (r, e, o, s, t, a) => {
const n = await H(
d(r),
e,
o,
s,
t?.content_type ?? "application/octet-stream",
j(a?.debug),
m(a?.env)
);
return n.data ? {
data: {
key: n.data.object_key,
content_type: t?.content_type,
state: n.state
}
} : {
error: n.error
};
}
), B = O(
async (r, e, o, s, t, a) => {
const n = new f(r, a?.debug);
n.name = e;
const c = await n.updateObject({ key: o, content: s, options: t });
return c?.data ? {
data: c.data
} : {
error: c.error
};
},
async (r, e, o, s, t, a) => {
const n = await q(
d(r),
e,
o,
s,
t?.content_type ?? "application/octet-stream",
j(a?.debug),
m(a?.env)
);
return n.data ? {
data: {
key: n.data.object_key,
content: s,
content_type: t?.content_type,
state: n.state
}
} : {
error: n.error
};
}
), E = O(
async (r, e, o, s) => {
const t = new f(r, s?.debug);
t.name = e;
const a = await t.deleteObject({ key: o });
return a.data ? {
data: a.data
} : {
error: a.error
};
},
async (r, e, o, s) => {
const t = await Z(
d(r),
e,
o,
j(s?.debug),
m(s?.env)
);
return t.data ? {
data: {
key: o,
state: t.state
}
} : {
error: t.error
};
}
), X = ({
name: r,
workloads_access: e,
options: o
}) => A(d(), r, e, l(o)), Y = ({
name: r,
options: e
}) => C(d(), r, l(e)), ee = ({
params: r,
options: e
}) => M(d(), r, l(e)), te = ({
name: r,
options: e
}) => x(d(), r, l(e)), re = ({
name: r,
workloads_access: e,
options: o
}) => N(d(), r, e, l(o)), oe = ({
name: r,
workloads_access: e,
options: o
}) => K(d(), r, e, l(o)), se = ({
bucket: r,
params: e,
options: o
}) => w(d(), r, e, l(o)), ne = ({
bucket: r,
key: e,
content: o,
params: s,
options: t
}) => _(d(), r, e, o, s, l(t)), ae = ({
bucket: r,
key: e,
options: o
}) => k(d(), r, e, l(o)), ce = ({
bucket: r,
key: e,
content: o,
params: s,
options: t
}) => B(d(), r, e, o, s, l(t)), ie = ({
bucket: r,
key: e,
options: o
}) => E(d(), r, e, l(o)), ue = (r) => {
const e = d(r?.token), o = l(r?.options);
return {
getBuckets: (t) => M(e, t?.params, o),
createBucket: ({
name: t,
workloads_access: a
}) => A(e, t, a, o),
updateBucket: ({
name: t,
workloads_access: a
}) => N(e, t, a, o),
deleteBucket: ({ name: t }) => C(e, t, o),
getBucket: ({ name: t }) => x(e, t, o),
setupStorage: ({
name: t,
workloads_access: a
}) => K(e, t, a, o)
};
};
export {
X as createBucket,
A as createBucketMethod,
ue as createClient,
ne as createObject,
ue as default,
Y as deleteBucket,
C as deleteBucketMethod,
ie as deleteObject,
te as getBucket,
ee as getBuckets,
M as getBucketsMethod,
ae as getObjectByKey,
se as getObjects,
oe as setupStorage,
K as setupStorageMethod,
re as updateBucket,
N as updateBucketMethod,
ce as updateObject
};