sync
This commit is contained in:
21
packages/client/package.json
Normal file
21
packages/client/package.json
Normal 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"
|
||||
}
|
||||
}
|
||||
127
packages/client/src/index.ts
Normal file
127
packages/client/src/index.ts
Normal 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", "_")
|
||||
}
|
||||
7
packages/client/tsconfig.build.json
Normal file
7
packages/client/tsconfig.build.json
Normal file
@@ -0,0 +1,7 @@
|
||||
{
|
||||
"extends": "./tsconfig.json",
|
||||
"compilerOptions": {
|
||||
"noEmit": false
|
||||
},
|
||||
"exclude": ["dist", "node_modules", "**/*.spec.ts"]
|
||||
}
|
||||
20
packages/client/tsconfig.json
Normal file
20
packages/client/tsconfig.json
Normal 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"]
|
||||
}
|
||||
Reference in New Issue
Block a user