astro-cloudinary
Version:
<a href="https://github.com/cloudinary-community/astro-cloudinary/actions/workflows/test_and_release.yml"><img alt="GitHub Workflow Status" src="https://img.shields.io/github/actions/workflow/status/cloudinary-community/astro-cloudinary/test_and_release.y
212 lines (208 loc) • 6.98 kB
JavaScript
import {
ASTRO_CLOUDINARY_VERSION
} from "../chunk-TFLUFGNO.js";
// src/loaders/assets-loader.ts
import { AstroError } from "astro/errors";
// src/types/resources.ts
import { z } from "astro/zod";
var cloudinaryResourceAccessModeSchema = z.union([
z.enum(["public", "authenticated"]),
z.intersection(z.string(), z.object({}))
]);
var cloudinaryResourceContextSchema = z.object({
custom: z.object({
alt: z.string().optional(),
caption: z.string().optional()
}).and(
z.record(z.string().optional())
)
});
var cloudinaryResourceDeliveryTypeSchema = z.union([
z.enum(["animoto", "asset", "authenticated", "dailymotion", "facebook", "fetch", "gravatar", "hulu", "instagram", "list", "multi", "private", "text", "twitter", "twitter_name", "upload", "vimeo", "worldstarhiphop", "youtube"]),
z.intersection(z.string(), z.object({}))
]);
var cloudinaryResourceResourceTypeSchema = z.union([
z.enum(["image", "video", "raw", "auto"]),
z.intersection(z.string(), z.object({}))
]);
var cloudinaryResourceSchema = z.object({
access_mode: cloudinaryResourceAccessModeSchema.optional(),
access_control: z.array(z.string()).optional(),
asset_id: z.string(),
backup: z.boolean().optional(),
bytes: z.number(),
context: cloudinaryResourceContextSchema.optional(),
colors: z.array(z.tuple([z.string(), z.number()])).optional(),
coordinates: z.object({}).passthrough().optional(),
created_at: z.string(),
derived: z.array(z.string()).optional(),
display_name: z.string().optional(),
exif: z.object({}).passthrough().optional(),
faces: z.array(z.array(z.number())).optional(),
folder: z.string(),
format: z.string(),
height: z.number(),
image_metadata: z.object({}).passthrough().optional(),
info: z.object({}).passthrough().optional(),
media_metadata: z.object({}).passthrough().optional(),
metadata: z.object({}).passthrough().optional(),
moderation: z.union([z.object({}).passthrough(), z.array(z.string())]).optional(),
pages: z.number().optional(),
phash: z.string().optional(),
placeholder: z.boolean().optional(),
predominant: z.object({}).passthrough().optional(),
public_id: z.string(),
quality_analysis: z.number().optional(),
resource_type: cloudinaryResourceResourceTypeSchema,
secure_url: z.string(),
signature: z.string().optional(),
tags: z.array(z.string()).optional(),
type: cloudinaryResourceDeliveryTypeSchema,
url: z.string(),
version: z.number(),
width: z.number()
}).passthrough();
// src/lib/resources.ts
async function cldRequest(path) {
return fetch(`https://api.cloudinary.com/v1_1/${import.meta.env.PUBLIC_CLOUDINARY_CLOUD_NAME}${path}`, {
headers: {
"Authorization": "Basic " + btoa(`${import.meta.env.PUBLIC_CLOUDINARY_API_KEY}:${import.meta.env.CLOUDINARY_API_SECRET}`),
"User-Agent": `CloudinaryAstro/${ASTRO_CLOUDINARY_VERSION}`
}
});
}
async function getEnvironmentConfig() {
const params = new URLSearchParams();
params.append("settings", "true");
const response = await cldRequest(`/config?${params}`);
if (!response.ok) {
throw new Error("Failed to get product environment.");
}
const data = await response.json();
return data;
}
async function listResources(options) {
const params = new URLSearchParams();
if (options.nextCursor) {
params.append("next_cursor", options.nextCursor);
}
if (options.limit) {
params.append("max_results", `${options.limit}`);
}
params.append("type", options.deliveryType);
const contentOptions = ["context", "metadata", "moderation", "tags"];
for (let contentOption of contentOptions) {
const value = options[contentOption];
if (typeof value === "boolean") {
params.append(contentOption, `${value}`);
}
}
if (Array.isArray(options.fields)) {
const fields = options.fields.join(",");
params.append("fields", fields);
}
let response;
if (options.folder) {
if (options.folderMode === "dynamic") {
params.append("asset_folder", options.folder);
response = await cldRequest(`/resources/by_asset_folder?${params}`);
} else if (options.folderMode === "fixed") {
params.append("prefix", options.folder);
response = await cldRequest(`/resources/${options.resourceType}?${params}`);
} else {
throw new Error(`Unhandled folder mode: ${options.folderMode}`);
}
} else {
response = await cldRequest(`/resources/${options.resourceType}?${params}`);
}
if (!response.ok) {
throw new Error(`Failed to list resources - ${response.statusText}`);
}
const data = await response.json();
return data;
}
// src/loaders/assets-loader.ts
var CLOUDINARY_DEFAULT_LIMIT = 10;
var REQUIRED_CREDENTIALS = [
"PUBLIC_CLOUDINARY_CLOUD_NAME",
"PUBLIC_CLOUDINARY_API_KEY",
"CLOUDINARY_API_SECRET"
];
function cldAssetsLoader(options) {
return {
name: "cloudinary-assets-loader",
load: async ({ store, logger, generateDigest }) => {
REQUIRED_CREDENTIALS.forEach((CREDENTIAL) => {
if (typeof import.meta.env[CREDENTIAL] === "undefined") {
throw new AstroError(`Missing ${CREDENTIAL}. Please set it as an environment variable inside of your .env.`);
}
});
const { settings: { folder_mode: folderMode } } = await getEnvironmentConfig();
logger.info(`Loading Cloudinary Assets`);
const {
context,
deliveryType = "upload",
fields,
folder,
limit = CLOUDINARY_DEFAULT_LIMIT,
metadata,
moderation,
resourceType = "image",
tags
} = options || {};
let resources = [];
let totalAssetsLoaded = 0;
let nextCursor = void 0;
const requestOptions = {
context,
deliveryType,
fields,
folder,
folderMode,
limit,
metadata,
moderation,
resourceType,
tags
};
while (totalAssetsLoaded < limit) {
let data = void 0;
try {
data = await listResources({
...requestOptions,
nextCursor
});
if (!data) {
throw new Error("Unkown error.");
}
} catch (error) {
logger.error(`${error}`);
return;
}
const newResources = data.resources.slice(0, limit - totalAssetsLoaded);
resources = [...resources, ...newResources];
totalAssetsLoaded += newResources.length;
nextCursor = data.next_cursor;
if (!nextCursor) {
break;
}
}
for (const resource of resources) {
store.set({
id: resource.public_id,
data: resource,
digest: generateDigest(resource)
// @TODO could this be used to render an <img or <video? Can this render CldImage?
// rendered: {
// html: ...
// },
});
}
},
schema: cloudinaryResourceSchema
};
}
export {
cldAssetsLoader
};
//# sourceMappingURL=index.js.map