photosuite 0.1.1 → 0.1.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/integration.d.ts
CHANGED
|
@@ -13,6 +13,10 @@ export default function astroPhotosuite(options: PhotosuiteOptions): {
|
|
|
13
13
|
"astro:config:setup": ({ injectScript, updateConfig }: any) => void;
|
|
14
14
|
};
|
|
15
15
|
};
|
|
16
|
+
/**
|
|
17
|
+
* 允许使用 import { photosuite } from 'photosuite' 语法
|
|
18
|
+
*/
|
|
19
|
+
export declare const photosuite: typeof astroPhotosuite;
|
|
16
20
|
export { imageUrl } from './remark/imageUrl';
|
|
17
21
|
export { exiftoolVendored } from './rehype/exiftoolVendored';
|
|
18
22
|
export type { PhotosuiteOptions, ImageUrlOptions } from './types';
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
Object.defineProperty(exports,`__esModule`,{value:!0});var e=Object.create,t=Object.defineProperty,n=Object.getOwnPropertyDescriptor,r=Object.getOwnPropertyNames,i=Object.getPrototypeOf,a=Object.prototype.hasOwnProperty,o=(e,i,o,s)=>{if(i&&typeof i==`object`||typeof i==`function`)for(var c=r(i),l=0,u=c.length,d;l<u;l++)d=c[l],!a.call(e,d)&&d!==o&&t(e,d,{get:(e=>i[e]).bind(null,d),enumerable:!(s=n(i,d))||s.enumerable});return e},s=(n,r,a)=>(a=n==null?{}:e(i(n)),o(r||!n||!n.__esModule?t(a,`default`,{value:n,enumerable:!0}):a,n));let c=require(`exiftool-vendored`),l=require(`node:fs`);l=s(l);let u=require(`node:fs/promises`);u=s(u);let d=require(`node:path`);d=s(d);let f=require(`node:http`);f=s(f);let p=require(`node:https`);p=s(p);let m=require(`node:os`);m=s(m);let h=require(`node:url`);var g=(...e)=>{let t=e.filter(e=>typeof e==`string`&&e!==``);if(t.length===0)return``;if(t.length===1)return t[0];let n=t[0],r=t[1],i=`${n.endsWith(`/`)?n.slice(0,-1):n}/${r.startsWith(`/`)?r.slice(1):r}`;return t.length>2?g(i,...t.slice(2)):i},_=e=>!(!e||/^https?:\/\//i.test(e)||e.startsWith(`/`)||e.startsWith(`./`)||e.startsWith(`../`));function v(e={}){let{imageBase:t,imageDir:n=`imageDir`,fileDir:r=!1}=e;return(e,i)=>{let a=(i?.data?.astro?.frontmatter||i?.data?.frontmatter||{})[n]||``,o=(i?.path||i?.history?.[0]||``).split(/[\\/]/).pop()?.split(`.`).shift()||``,s=r?o:a,c=e=>{if(e){if(e.type===`image`){let n=e.url||``;(t||s)&&_(n)&&(e.url=g(t,s,n))}e.children&&e.children.length&&e.children.forEach(c)}};c(e)}}function y(e){try{let t=new h.URL(e);return t.protocol===`http:`||t.protocol===`https:`}catch{return!1}}async function b(e){let t=m.tmpdir(),n=d.extname(e)||`.bin`,r=d.join(t,`exif-${Date.now()}-${Math.random().toString(36).slice(2)}${n}`),i=l.createWriteStream(r),a=e.startsWith(`https:`)?p:f;return await new Promise((t,n)=>{a.get(e,e=>{if(e.statusCode&&e.statusCode>=300&&e.statusCode<400&&e.headers.location,e.statusCode!==200){n(Error(`HTTP `+e.statusCode));return}e.pipe(i),i.on(`finish`,t),i.on(`error`,n)}).on(`error`,n)}),{path:r,cleanup:async()=>{try{await u.unlink(r)}catch{}}}}async function x(e){let t=await c.exiftool.read(e);return{SourceFile:t.SourceFile,ExifToolVersion:t.ExifToolVersion,MIMEType:t.MIMEType,FileType:t.FileType,Make:t.Make,Model:t.Model,LensModel:t.LensModel,DateTimeOriginal:t.DateTimeOriginal,CreateDate:t.CreateDate,ModifyDate:t.ModifyDate,ImageWidth:t.ImageWidth,ImageHeight:t.ImageHeight,GPSLatitude:t.GPSLatitude,GPSLongitude:t.GPSLongitude,FNumber:t.FNumber,ExposureTime:t.ExposureTime,ISO:t.ISO,FocalLength:t.FocalLength,warnings:t.warnings||[],errors:t.errors||[]}}function S(e,t){if(t==null)return``;switch(e){case`FNumber`:return`ƒ/${Number(t).toFixed(1)}`;case`ExposureTime`:return typeof t==`number`?t>=1?`${t}s`:`1/${Math.round(1/t)}s`:t.toString();case`ISO`:return`ISO ${t}`;case`FocalLength`:let e=t.toString();return e.endsWith(`mm`)?e:`${e}mm`;case`DateTimeOriginal`:return typeof t==`object`&&t.year?`${t.year}/${t.month}/${t.day}`:t.toString();default:return t.toString()}}async function C(e,t,n){let r=e.properties?.src;if(!r)return;let i=``,a;try{if(y(r)){let e=await b(r);i=e.path,a=e.cleanup}else if(d.isAbsolute(r))i=r;else{let e=d.dirname(t.path);i=d.resolve(e,r)}if(i&&(l.existsSync(i)||y(r))&&(l.existsSync(i)||(i=decodeURIComponent(i)),l.existsSync(i))){let t=await x(i);if(!(t.FNumber&&t.ExposureTime&&t.ISO))return;let r=typeof n.exif==`object`?n.exif:{},a=r.fields||[`Model`,`LensModel`,`FocalLength`,`FNumber`,`ExposureTime`,`ISO`,`DateTimeOriginal`],o=r.separator||` · `,s=a.map(e=>{let n=t[e];return n?S(e,n):null}).filter(Boolean);if(s.length===0)return;let c=s.join(o),l={...e.properties};e.tagName=`div`,e.properties={className:[`photosuite-item`]},e.children=[{type:`element`,tagName:`img`,properties:l,children:[]},{type:`element`,tagName:`div`,properties:{className:[`photosuite-exif`]},children:[{type:`text`,value:c}]}]}}catch(e){console.warn(`[photosuite] Failed to get EXIF for ${r}:`,e)}finally{a&&await a()}}function w(e={}){return async(t,n)=>{let r=[],i=t=>{t.type===`element`&&t.tagName===`img`&&r.push(C(t,n,e)),t.children&&t.children.forEach(i)};i(t),r.length>0&&await Promise.all(r)}}function T(e){return{name:`photosuite`,hooks:{"astro:config:setup":({injectScript:t,updateConfig:n})=>{t(`page`,`
|
|
2
|
-
import { photosuite } from 'photosuite';
|
|
2
|
+
import { photosuite } from 'photosuite/client';
|
|
3
3
|
const __opts = ${JSON.stringify(e)};
|
|
4
4
|
const __run = () => photosuite(__opts);
|
|
5
5
|
__run();
|
|
6
6
|
document.addEventListener('astro:page-load', __run);
|
|
7
|
-
`);let r=[],i=[];i.push([v,e]),e.exif!==!1&&r.push([w,e]);let a={markdown:{}};r.length>0&&(a.markdown.rehypePlugins=r),i.length>0&&(a.markdown.remarkPlugins=i),Object.keys(a.markdown).length>0&&n(a)}}}}exports.default=T,exports.exiftoolVendored=w,exports.imageUrl=v;
|
|
7
|
+
`);let r=[],i=[];i.push([v,e]),e.exif!==!1&&r.push([w,e]);let a={markdown:{}};r.length>0&&(a.markdown.rehypePlugins=r),i.length>0&&(a.markdown.remarkPlugins=i),Object.keys(a.markdown).length>0&&n(a)}}}}const E=T;exports.default=T,exports.exiftoolVendored=w,exports.imageUrl=v,exports.photosuite=E;
|
|
@@ -7,109 +7,109 @@ import * as https from "node:https";
|
|
|
7
7
|
import * as os from "node:os";
|
|
8
8
|
import { URL } from "node:url";
|
|
9
9
|
var join = (...e) => {
|
|
10
|
-
let
|
|
11
|
-
if (
|
|
12
|
-
if (
|
|
13
|
-
let
|
|
14
|
-
return
|
|
10
|
+
let c = e.filter((e) => typeof e == "string" && e !== "");
|
|
11
|
+
if (c.length === 0) return "";
|
|
12
|
+
if (c.length === 1) return c[0];
|
|
13
|
+
let l = c[0], u = c[1], d = `${l.endsWith("/") ? l.slice(0, -1) : l}/${u.startsWith("/") ? u.slice(1) : u}`;
|
|
14
|
+
return c.length > 2 ? join(d, ...c.slice(2)) : d;
|
|
15
15
|
}, isShort = (e) => !(!e || /^https?:\/\//i.test(e) || e.startsWith("/") || e.startsWith("./") || e.startsWith("../"));
|
|
16
16
|
function imageUrl(e = {}) {
|
|
17
|
-
let { imageBase:
|
|
18
|
-
return (e,
|
|
19
|
-
let
|
|
17
|
+
let { imageBase: c, imageDir: l = "imageDir", fileDir: u = !1 } = e;
|
|
18
|
+
return (e, d) => {
|
|
19
|
+
let f = (d?.data?.astro?.frontmatter || d?.data?.frontmatter || {})[l] || "", p = (d?.path || d?.history?.[0] || "").split(/[\\/]/).pop()?.split(".").shift() || "", m = u ? p : f, _ = (e) => {
|
|
20
20
|
if (e) {
|
|
21
21
|
if (e.type === "image") {
|
|
22
|
-
let
|
|
23
|
-
(
|
|
22
|
+
let l = e.url || "";
|
|
23
|
+
(c || m) && isShort(l) && (e.url = join(c, m, l));
|
|
24
24
|
}
|
|
25
|
-
e.children && e.children.length && e.children.forEach(
|
|
25
|
+
e.children && e.children.length && e.children.forEach(_);
|
|
26
26
|
}
|
|
27
27
|
};
|
|
28
|
-
|
|
28
|
+
_(e);
|
|
29
29
|
};
|
|
30
30
|
}
|
|
31
31
|
function isHttpUrl(e) {
|
|
32
32
|
try {
|
|
33
|
-
let
|
|
34
|
-
return
|
|
33
|
+
let c = new URL(e);
|
|
34
|
+
return c.protocol === "http:" || c.protocol === "https:";
|
|
35
35
|
} catch {
|
|
36
36
|
return !1;
|
|
37
37
|
}
|
|
38
38
|
}
|
|
39
39
|
async function downloadToTemp(e) {
|
|
40
|
-
let
|
|
41
|
-
return await new Promise((
|
|
42
|
-
|
|
40
|
+
let m = os.tmpdir(), h = path.extname(e) || ".bin", g = path.join(m, `exif-${Date.now()}-${Math.random().toString(36).slice(2)}${h}`), _ = fs.createWriteStream(g), v = e.startsWith("https:") ? https : http;
|
|
41
|
+
return await new Promise((c, l) => {
|
|
42
|
+
v.get(e, (e) => {
|
|
43
43
|
if (e.statusCode && e.statusCode >= 300 && e.statusCode < 400 && e.headers.location, e.statusCode !== 200) {
|
|
44
|
-
|
|
44
|
+
l(/* @__PURE__ */ Error("HTTP " + e.statusCode));
|
|
45
45
|
return;
|
|
46
46
|
}
|
|
47
|
-
e.pipe(
|
|
48
|
-
}).on("error",
|
|
47
|
+
e.pipe(_), _.on("finish", c), _.on("error", l);
|
|
48
|
+
}).on("error", l);
|
|
49
49
|
}), {
|
|
50
|
-
path:
|
|
50
|
+
path: g,
|
|
51
51
|
cleanup: async () => {
|
|
52
52
|
try {
|
|
53
|
-
await fsp.unlink(
|
|
53
|
+
await fsp.unlink(g);
|
|
54
54
|
} catch {}
|
|
55
55
|
}
|
|
56
56
|
};
|
|
57
57
|
}
|
|
58
|
-
async function handleExif(
|
|
59
|
-
let
|
|
58
|
+
async function handleExif(c) {
|
|
59
|
+
let l = await exiftool.read(c);
|
|
60
60
|
return {
|
|
61
|
-
SourceFile:
|
|
62
|
-
ExifToolVersion:
|
|
63
|
-
MIMEType:
|
|
64
|
-
FileType:
|
|
65
|
-
Make:
|
|
66
|
-
Model:
|
|
67
|
-
LensModel:
|
|
68
|
-
DateTimeOriginal:
|
|
69
|
-
CreateDate:
|
|
70
|
-
ModifyDate:
|
|
71
|
-
ImageWidth:
|
|
72
|
-
ImageHeight:
|
|
73
|
-
GPSLatitude:
|
|
74
|
-
GPSLongitude:
|
|
75
|
-
FNumber:
|
|
76
|
-
ExposureTime:
|
|
77
|
-
ISO:
|
|
78
|
-
FocalLength:
|
|
79
|
-
warnings:
|
|
80
|
-
errors:
|
|
61
|
+
SourceFile: l.SourceFile,
|
|
62
|
+
ExifToolVersion: l.ExifToolVersion,
|
|
63
|
+
MIMEType: l.MIMEType,
|
|
64
|
+
FileType: l.FileType,
|
|
65
|
+
Make: l.Make,
|
|
66
|
+
Model: l.Model,
|
|
67
|
+
LensModel: l.LensModel,
|
|
68
|
+
DateTimeOriginal: l.DateTimeOriginal,
|
|
69
|
+
CreateDate: l.CreateDate,
|
|
70
|
+
ModifyDate: l.ModifyDate,
|
|
71
|
+
ImageWidth: l.ImageWidth,
|
|
72
|
+
ImageHeight: l.ImageHeight,
|
|
73
|
+
GPSLatitude: l.GPSLatitude,
|
|
74
|
+
GPSLongitude: l.GPSLongitude,
|
|
75
|
+
FNumber: l.FNumber,
|
|
76
|
+
ExposureTime: l.ExposureTime,
|
|
77
|
+
ISO: l.ISO,
|
|
78
|
+
FocalLength: l.FocalLength,
|
|
79
|
+
warnings: l.warnings || [],
|
|
80
|
+
errors: l.errors || []
|
|
81
81
|
};
|
|
82
82
|
}
|
|
83
|
-
function formatField(e,
|
|
84
|
-
if (
|
|
83
|
+
function formatField(e, c) {
|
|
84
|
+
if (c == null) return "";
|
|
85
85
|
switch (e) {
|
|
86
|
-
case "FNumber": return `ƒ/${Number(
|
|
87
|
-
case "ExposureTime": return typeof
|
|
88
|
-
case "ISO": return `ISO ${
|
|
86
|
+
case "FNumber": return `ƒ/${Number(c).toFixed(1)}`;
|
|
87
|
+
case "ExposureTime": return typeof c == "number" ? c >= 1 ? `${c}s` : `1/${Math.round(1 / c)}s` : c.toString();
|
|
88
|
+
case "ISO": return `ISO ${c}`;
|
|
89
89
|
case "FocalLength":
|
|
90
|
-
let e =
|
|
90
|
+
let e = c.toString();
|
|
91
91
|
return e.endsWith("mm") ? e : `${e}mm`;
|
|
92
|
-
case "DateTimeOriginal": return typeof
|
|
93
|
-
default: return
|
|
92
|
+
case "DateTimeOriginal": return typeof c == "object" && c.year ? `${c.year}/${c.month}/${c.day}` : c.toString();
|
|
93
|
+
default: return c.toString();
|
|
94
94
|
}
|
|
95
95
|
}
|
|
96
|
-
async function processNode(e,
|
|
97
|
-
let
|
|
98
|
-
if (!
|
|
99
|
-
let
|
|
96
|
+
async function processNode(e, l, d) {
|
|
97
|
+
let f = e.properties?.src;
|
|
98
|
+
if (!f) return;
|
|
99
|
+
let p = "", m;
|
|
100
100
|
try {
|
|
101
|
-
if (isHttpUrl(
|
|
102
|
-
let e = await downloadToTemp(
|
|
103
|
-
|
|
104
|
-
} else if (path.isAbsolute(
|
|
101
|
+
if (isHttpUrl(f)) {
|
|
102
|
+
let e = await downloadToTemp(f);
|
|
103
|
+
p = e.path, m = e.cleanup;
|
|
104
|
+
} else if (path.isAbsolute(f)) p = f;
|
|
105
105
|
else {
|
|
106
|
-
let e = path.dirname(
|
|
107
|
-
|
|
106
|
+
let e = path.dirname(l.path);
|
|
107
|
+
p = path.resolve(e, f);
|
|
108
108
|
}
|
|
109
|
-
if (
|
|
110
|
-
let
|
|
111
|
-
if (!(
|
|
112
|
-
let
|
|
109
|
+
if (p && (fs.existsSync(p) || isHttpUrl(f)) && (fs.existsSync(p) || (p = decodeURIComponent(p)), fs.existsSync(p))) {
|
|
110
|
+
let c = await handleExif(p);
|
|
111
|
+
if (!(c.FNumber && c.ExposureTime && c.ISO)) return;
|
|
112
|
+
let l = typeof d.exif == "object" ? d.exif : {}, u = l.fields || [
|
|
113
113
|
"Model",
|
|
114
114
|
"LensModel",
|
|
115
115
|
"FocalLength",
|
|
@@ -117,16 +117,16 @@ async function processNode(e, c, u) {
|
|
|
117
117
|
"ExposureTime",
|
|
118
118
|
"ISO",
|
|
119
119
|
"DateTimeOriginal"
|
|
120
|
-
],
|
|
121
|
-
let
|
|
122
|
-
return
|
|
120
|
+
], f = l.separator || " · ", m = u.map((e) => {
|
|
121
|
+
let l = c[e];
|
|
122
|
+
return l ? formatField(e, l) : null;
|
|
123
123
|
}).filter(Boolean);
|
|
124
|
-
if (
|
|
125
|
-
let
|
|
124
|
+
if (m.length === 0) return;
|
|
125
|
+
let h = m.join(f), g = { ...e.properties };
|
|
126
126
|
e.tagName = "div", e.properties = { className: ["photosuite-item"] }, e.children = [{
|
|
127
127
|
type: "element",
|
|
128
128
|
tagName: "img",
|
|
129
|
-
properties:
|
|
129
|
+
properties: g,
|
|
130
130
|
children: []
|
|
131
131
|
}, {
|
|
132
132
|
type: "element",
|
|
@@ -134,40 +134,41 @@ async function processNode(e, c, u) {
|
|
|
134
134
|
properties: { className: ["photosuite-exif"] },
|
|
135
135
|
children: [{
|
|
136
136
|
type: "text",
|
|
137
|
-
value:
|
|
137
|
+
value: h
|
|
138
138
|
}]
|
|
139
139
|
}];
|
|
140
140
|
}
|
|
141
141
|
} catch (e) {
|
|
142
|
-
console.warn(`[photosuite] Failed to get EXIF for ${
|
|
142
|
+
console.warn(`[photosuite] Failed to get EXIF for ${f}:`, e);
|
|
143
143
|
} finally {
|
|
144
|
-
|
|
144
|
+
m && await m();
|
|
145
145
|
}
|
|
146
146
|
}
|
|
147
147
|
function exiftoolVendored(e = {}) {
|
|
148
|
-
return async (
|
|
149
|
-
let
|
|
150
|
-
|
|
148
|
+
return async (c, l) => {
|
|
149
|
+
let u = [], d = (c) => {
|
|
150
|
+
c.type === "element" && c.tagName === "img" && u.push(processNode(c, l, e)), c.children && c.children.forEach(d);
|
|
151
151
|
};
|
|
152
|
-
|
|
152
|
+
d(c), u.length > 0 && await Promise.all(u);
|
|
153
153
|
};
|
|
154
154
|
}
|
|
155
155
|
function astroPhotosuite(e) {
|
|
156
156
|
return {
|
|
157
157
|
name: "photosuite",
|
|
158
|
-
hooks: { "astro:config:setup": ({ injectScript:
|
|
159
|
-
|
|
160
|
-
import { photosuite } from 'photosuite';
|
|
158
|
+
hooks: { "astro:config:setup": ({ injectScript: c, updateConfig: l }) => {
|
|
159
|
+
c("page", `
|
|
160
|
+
import { photosuite } from 'photosuite/client';
|
|
161
161
|
const __opts = ${JSON.stringify(e)};
|
|
162
162
|
const __run = () => photosuite(__opts);
|
|
163
163
|
__run();
|
|
164
164
|
document.addEventListener('astro:page-load', __run);
|
|
165
165
|
`);
|
|
166
|
-
let
|
|
167
|
-
|
|
168
|
-
let
|
|
169
|
-
|
|
166
|
+
let u = [], d = [];
|
|
167
|
+
d.push([imageUrl, e]), e.exif !== !1 && u.push([exiftoolVendored, e]);
|
|
168
|
+
let f = { markdown: {} };
|
|
169
|
+
u.length > 0 && (f.markdown.rehypePlugins = u), d.length > 0 && (f.markdown.remarkPlugins = d), Object.keys(f.markdown).length > 0 && l(f);
|
|
170
170
|
} }
|
|
171
171
|
};
|
|
172
172
|
}
|
|
173
|
-
|
|
173
|
+
const photosuite = astroPhotosuite;
|
|
174
|
+
export { astroPhotosuite as default, exiftoolVendored, imageUrl, photosuite };
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "photosuite",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.2",
|
|
4
4
|
"description": "A zero-config Astro integration for better images (Lightbox, EXIF, Path resolution).",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"astro-integration",
|
|
@@ -21,19 +21,13 @@
|
|
|
21
21
|
"bugs": "https://github.com/achuanya/photosuite/issues",
|
|
22
22
|
"type": "module",
|
|
23
23
|
"main": "./dist/photosuite.integration.js",
|
|
24
|
-
"module": "./dist/photosuite.
|
|
24
|
+
"module": "./dist/photosuite.integration.js",
|
|
25
25
|
"types": "./dist/integration.d.ts",
|
|
26
26
|
"exports": {
|
|
27
27
|
".": {
|
|
28
|
-
"
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
"require": "./dist/photosuite.integration.cjs"
|
|
32
|
-
},
|
|
33
|
-
"types": "./dist/index.d.ts",
|
|
34
|
-
"import": "./dist/photosuite.es.js",
|
|
35
|
-
"require": "./dist/photosuite.cjs.js",
|
|
36
|
-
"default": "./dist/photosuite.es.js"
|
|
28
|
+
"types": "./dist/integration.d.ts",
|
|
29
|
+
"import": "./dist/photosuite.integration.js",
|
|
30
|
+
"require": "./dist/photosuite.integration.cjs"
|
|
37
31
|
},
|
|
38
32
|
"./client": {
|
|
39
33
|
"types": "./dist/index.d.ts",
|