This commit is contained in:
2026-05-12 07:54:32 +03:00
parent 0faa8b9d2d
commit d49449c30c
187 changed files with 4826 additions and 5884 deletions

View File

@@ -0,0 +1,21 @@
{
"name": "@image-platform/client",
"version": "0.1.0",
"private": true,
"exports": {
".": {
"types": "./src/index.ts",
"require": "./dist/index.js",
"import": "./dist/index.js",
"default": "./dist/index.js"
}
},
"types": "./src/index.ts",
"scripts": {
"build": "tsc -p tsconfig.build.json",
"typecheck": "tsc --noEmit -p tsconfig.json"
},
"devDependencies": {
"typescript": "^6.0.3"
}
}

View File

@@ -0,0 +1,127 @@
export type ImagePlatformFormat = "auto" | "avif" | "jpg" | "png" | "webp"
export type ImagePlatformResize = "fill" | "fit"
export type ImagePlatformRemoteUrlInput = {
baseUrl: string
fit?: ImagePlatformResize
format?: ImagePlatformFormat
height?: number | null
preset: string
project: string
quality?: number | null
sourceBaseUrl?: string
src: string
width?: number | null
}
export type ImagePlatformNextLoaderOptions = {
baseUrl: string
defaultQuality?: number
fit?: ImagePlatformResize
format?: ImagePlatformFormat
preset: string
project: string
sourceBaseUrl?: string
}
export type ImagePlatformNextLoaderParams = {
quality?: number
src: string
width: number
}
export type ImagePlatformOperations = {
fit?: ImagePlatformResize
format?: ImagePlatformFormat
height?: number
quality?: number
width?: number
}
export type ImagePlatformUnpicOptions = {
baseUrl: string
defaultQuality?: number
fit?: ImagePlatformResize
format?: ImagePlatformFormat
preset: string
project: string
sourceBaseUrl?: string
}
export function buildImagePlatformRemoteUrl(input: ImagePlatformRemoteUrlInput) {
const sourceUrl = resolveImagePlatformSourceUrl(input.src, input.sourceBaseUrl)
const url = new URL(`/p/${encodePathSegment(input.project)}/remote/${encodePathSegment(input.preset)}`, input.baseUrl)
url.searchParams.set("src", sourceUrl)
if (input.width) {
url.searchParams.set("w", input.width.toString())
}
if (input.height) {
url.searchParams.set("h", input.height.toString())
}
if (input.quality) {
url.searchParams.set("q", input.quality.toString())
}
if (input.fit) {
url.searchParams.set("fit", input.fit)
}
url.searchParams.set("f", input.format ?? "auto")
return url.toString()
}
export function createImagePlatformNextLoader(options: ImagePlatformNextLoaderOptions) {
return function imagePlatformNextLoader(params: ImagePlatformNextLoaderParams) {
return buildImagePlatformRemoteUrl({
baseUrl: options.baseUrl,
fit: options.fit,
format: options.format,
preset: options.preset,
project: options.project,
quality: params.quality ?? options.defaultQuality,
sourceBaseUrl: options.sourceBaseUrl,
src: params.src,
width: params.width,
})
}
}
export function imagePlatformUnpicTransformer(
src: string,
operations: ImagePlatformOperations,
options: ImagePlatformUnpicOptions,
) {
return buildImagePlatformRemoteUrl({
baseUrl: options.baseUrl,
fit: operations.fit ?? options.fit,
format: operations.format ?? options.format,
height: operations.height,
preset: options.preset,
project: options.project,
quality: operations.quality ?? options.defaultQuality,
sourceBaseUrl: options.sourceBaseUrl,
src,
width: operations.width,
})
}
export function resolveImagePlatformSourceUrl(src: string, sourceBaseUrl?: string) {
try {
return new URL(src).toString()
} catch {
if (!sourceBaseUrl) {
throw new Error("sourceBaseUrl is required for relative image src")
}
return new URL(src, sourceBaseUrl).toString()
}
}
function encodePathSegment(value: string) {
return encodeURIComponent(value).replaceAll("%2D", "-").replaceAll("%5F", "_")
}

View File

@@ -0,0 +1,7 @@
{
"extends": "./tsconfig.json",
"compilerOptions": {
"noEmit": false
},
"exclude": ["dist", "node_modules", "**/*.spec.ts"]
}

View File

@@ -0,0 +1,20 @@
{
"compilerOptions": {
"allowSyntheticDefaultImports": true,
"declaration": true,
"esModuleInterop": true,
"forceConsistentCasingInFileNames": true,
"lib": ["ES2023", "DOM"],
"module": "Node16",
"moduleResolution": "Node16",
"noUncheckedIndexedAccess": true,
"outDir": "./dist",
"rootDir": "./src",
"skipLibCheck": true,
"sourceMap": true,
"strict": true,
"target": "ES2023"
},
"include": ["src/**/*.ts"],
"exclude": ["dist", "node_modules"]
}