@riffyh/server 1.0.0
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/index.d.mts +228 -0
- package/dist/index.mjs +74 -0
- package/dist/index.mjs.map +1 -0
- package/package.json +39 -0
package/dist/index.d.mts
ADDED
|
@@ -0,0 +1,228 @@
|
|
|
1
|
+
import { Elysia } from "elysia";
|
|
2
|
+
import * as _$_riffyh_commons0 from "@riffyh/commons";
|
|
3
|
+
|
|
4
|
+
//#region src/index.d.ts
|
|
5
|
+
declare const server: Elysia<"", {
|
|
6
|
+
decorator: {};
|
|
7
|
+
store: {};
|
|
8
|
+
derive: {};
|
|
9
|
+
resolve: {};
|
|
10
|
+
}, {
|
|
11
|
+
typebox: {};
|
|
12
|
+
error: {};
|
|
13
|
+
} & {
|
|
14
|
+
typebox: {};
|
|
15
|
+
error: {};
|
|
16
|
+
} & {
|
|
17
|
+
typebox: {};
|
|
18
|
+
error: {};
|
|
19
|
+
}, {
|
|
20
|
+
schema: {};
|
|
21
|
+
standaloneSchema: {};
|
|
22
|
+
macro: {};
|
|
23
|
+
macroFn: {};
|
|
24
|
+
parser: {};
|
|
25
|
+
response: {};
|
|
26
|
+
} & {
|
|
27
|
+
schema: {};
|
|
28
|
+
standaloneSchema: {};
|
|
29
|
+
macro: {};
|
|
30
|
+
macroFn: {};
|
|
31
|
+
parser: {};
|
|
32
|
+
} & {
|
|
33
|
+
schema: {};
|
|
34
|
+
standaloneSchema: {};
|
|
35
|
+
macro: {};
|
|
36
|
+
macroFn: {};
|
|
37
|
+
parser: {};
|
|
38
|
+
response: {};
|
|
39
|
+
}, {
|
|
40
|
+
get: {
|
|
41
|
+
body: unknown;
|
|
42
|
+
params: {};
|
|
43
|
+
query: unknown;
|
|
44
|
+
headers: unknown;
|
|
45
|
+
response: {
|
|
46
|
+
200: Response;
|
|
47
|
+
};
|
|
48
|
+
};
|
|
49
|
+
} & {
|
|
50
|
+
health: {
|
|
51
|
+
get: {
|
|
52
|
+
body: unknown;
|
|
53
|
+
params: {};
|
|
54
|
+
query: unknown;
|
|
55
|
+
headers: unknown;
|
|
56
|
+
response: {
|
|
57
|
+
200: string;
|
|
58
|
+
};
|
|
59
|
+
};
|
|
60
|
+
};
|
|
61
|
+
} & {
|
|
62
|
+
dataSources: {
|
|
63
|
+
get: {
|
|
64
|
+
body: unknown;
|
|
65
|
+
params: {};
|
|
66
|
+
query: unknown;
|
|
67
|
+
headers: unknown;
|
|
68
|
+
response: {
|
|
69
|
+
200: {
|
|
70
|
+
key: string;
|
|
71
|
+
name: string;
|
|
72
|
+
iconUrl: string;
|
|
73
|
+
}[];
|
|
74
|
+
422: {
|
|
75
|
+
type: "validation";
|
|
76
|
+
on: string;
|
|
77
|
+
summary?: string;
|
|
78
|
+
message?: string;
|
|
79
|
+
found?: unknown;
|
|
80
|
+
property?: string;
|
|
81
|
+
expected?: string;
|
|
82
|
+
};
|
|
83
|
+
};
|
|
84
|
+
};
|
|
85
|
+
};
|
|
86
|
+
} & {
|
|
87
|
+
gallery: {
|
|
88
|
+
get: {
|
|
89
|
+
body: unknown;
|
|
90
|
+
params: {};
|
|
91
|
+
query: {
|
|
92
|
+
id: string;
|
|
93
|
+
dataSource: string;
|
|
94
|
+
};
|
|
95
|
+
headers: unknown;
|
|
96
|
+
response: {
|
|
97
|
+
200: {
|
|
98
|
+
tags: {
|
|
99
|
+
key: string;
|
|
100
|
+
name: string;
|
|
101
|
+
type: _$_riffyh_commons0.TagType;
|
|
102
|
+
id: string;
|
|
103
|
+
slug: string;
|
|
104
|
+
}[];
|
|
105
|
+
key: string;
|
|
106
|
+
title: {
|
|
107
|
+
display: string;
|
|
108
|
+
original: string | null;
|
|
109
|
+
};
|
|
110
|
+
id: string;
|
|
111
|
+
cover: {
|
|
112
|
+
src: string;
|
|
113
|
+
width: number;
|
|
114
|
+
height: number;
|
|
115
|
+
};
|
|
116
|
+
pages: {
|
|
117
|
+
src: string;
|
|
118
|
+
width: number;
|
|
119
|
+
height: number;
|
|
120
|
+
order: number;
|
|
121
|
+
}[];
|
|
122
|
+
};
|
|
123
|
+
422: {
|
|
124
|
+
type: "validation";
|
|
125
|
+
on: string;
|
|
126
|
+
summary?: string;
|
|
127
|
+
message?: string;
|
|
128
|
+
found?: unknown;
|
|
129
|
+
property?: string;
|
|
130
|
+
expected?: string;
|
|
131
|
+
};
|
|
132
|
+
};
|
|
133
|
+
};
|
|
134
|
+
};
|
|
135
|
+
} & {
|
|
136
|
+
listing: {
|
|
137
|
+
get: {
|
|
138
|
+
body: unknown;
|
|
139
|
+
params: {};
|
|
140
|
+
query: {
|
|
141
|
+
query?: string | undefined;
|
|
142
|
+
page: number;
|
|
143
|
+
dataSource: never;
|
|
144
|
+
};
|
|
145
|
+
headers: unknown;
|
|
146
|
+
response: {
|
|
147
|
+
200: {
|
|
148
|
+
galleries: {
|
|
149
|
+
key: string;
|
|
150
|
+
title: {
|
|
151
|
+
display: string;
|
|
152
|
+
original: string | null;
|
|
153
|
+
};
|
|
154
|
+
id: string;
|
|
155
|
+
cover: {
|
|
156
|
+
src: string;
|
|
157
|
+
width: number;
|
|
158
|
+
height: number;
|
|
159
|
+
};
|
|
160
|
+
}[];
|
|
161
|
+
currentPage: number;
|
|
162
|
+
maximumPages: number;
|
|
163
|
+
};
|
|
164
|
+
422: {
|
|
165
|
+
type: "validation";
|
|
166
|
+
on: string;
|
|
167
|
+
summary?: string;
|
|
168
|
+
message?: string;
|
|
169
|
+
found?: unknown;
|
|
170
|
+
property?: string;
|
|
171
|
+
expected?: string;
|
|
172
|
+
};
|
|
173
|
+
};
|
|
174
|
+
};
|
|
175
|
+
};
|
|
176
|
+
} & {
|
|
177
|
+
image: {
|
|
178
|
+
get: {
|
|
179
|
+
body: unknown;
|
|
180
|
+
params: {};
|
|
181
|
+
query: {
|
|
182
|
+
url: string;
|
|
183
|
+
dataSource: never;
|
|
184
|
+
format: "webp" | "jpg";
|
|
185
|
+
};
|
|
186
|
+
headers: unknown;
|
|
187
|
+
response: {
|
|
188
|
+
200: Response;
|
|
189
|
+
422: {
|
|
190
|
+
type: "validation";
|
|
191
|
+
on: string;
|
|
192
|
+
summary?: string;
|
|
193
|
+
message?: string;
|
|
194
|
+
found?: unknown;
|
|
195
|
+
property?: string;
|
|
196
|
+
expected?: string;
|
|
197
|
+
};
|
|
198
|
+
};
|
|
199
|
+
};
|
|
200
|
+
};
|
|
201
|
+
}, {
|
|
202
|
+
derive: {};
|
|
203
|
+
resolve: {};
|
|
204
|
+
schema: {};
|
|
205
|
+
standaloneSchema: {};
|
|
206
|
+
response: {};
|
|
207
|
+
}, {
|
|
208
|
+
derive: {};
|
|
209
|
+
resolve: {};
|
|
210
|
+
schema: {};
|
|
211
|
+
standaloneSchema: {};
|
|
212
|
+
response: {};
|
|
213
|
+
} & {
|
|
214
|
+
derive: {};
|
|
215
|
+
resolve: {};
|
|
216
|
+
schema: {};
|
|
217
|
+
standaloneSchema: {};
|
|
218
|
+
} & {
|
|
219
|
+
derive: {};
|
|
220
|
+
resolve: {};
|
|
221
|
+
schema: {};
|
|
222
|
+
standaloneSchema: {};
|
|
223
|
+
response: {};
|
|
224
|
+
}>;
|
|
225
|
+
type Server = typeof server;
|
|
226
|
+
//#endregion
|
|
227
|
+
export { Server };
|
|
228
|
+
//# sourceMappingURL=index.d.mts.map
|
package/dist/index.mjs
ADDED
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import { Elysia, t } from "elysia";
|
|
3
|
+
import { swagger } from "@elysiajs/swagger";
|
|
4
|
+
import { cors } from "@elysiajs/cors";
|
|
5
|
+
import { defineCacheInstance } from "@rayriffy/filesystem";
|
|
6
|
+
import sharp from "sharp";
|
|
7
|
+
import { galleryModel, listingResultModel } from "@riffyh/commons";
|
|
8
|
+
import debug from "debug";
|
|
9
|
+
import path from "node:path";
|
|
10
|
+
//#region src/index.ts
|
|
11
|
+
const log = debug("riffyh:server");
|
|
12
|
+
const cache = defineCacheInstance();
|
|
13
|
+
log("warming up server...");
|
|
14
|
+
const configFile = process.env.RIFFYH_CONFIG_PATH || "./riffyh.config.ts";
|
|
15
|
+
const configPath = path.resolve(configFile);
|
|
16
|
+
log(`resolving config file at ${configPath}...`);
|
|
17
|
+
const config = await import(configPath).then((o) => o.default);
|
|
18
|
+
log(`loaded configuration with ${config.dataSources.length} data sources`);
|
|
19
|
+
const dataSourceKeys = t.Union(config.dataSources.map((o) => t.Literal(o.key)));
|
|
20
|
+
const server = new Elysia().use(swagger({ exclude: ["/_image"] })).use(cors()).get("/", ({ redirect }) => redirect("/swagger")).get("/health", () => "healthy").get("/dataSources", () => config.dataSources.map((o) => ({
|
|
21
|
+
key: o.key,
|
|
22
|
+
name: o.name,
|
|
23
|
+
iconUrl: o.iconUrl
|
|
24
|
+
})), { response: t.Array(t.Object({
|
|
25
|
+
key: t.String(),
|
|
26
|
+
name: t.String(),
|
|
27
|
+
iconUrl: t.String()
|
|
28
|
+
})) }).get("/gallery", async ({ query }) => {
|
|
29
|
+
const dataSource = config.dataSources.find((o) => o.key === query.dataSource);
|
|
30
|
+
if (dataSource === void 0) throw new Error(`data source ${query.dataSource} not found`);
|
|
31
|
+
return dataSource.getGallery({ id: query.id });
|
|
32
|
+
}, {
|
|
33
|
+
query: t.Object({
|
|
34
|
+
id: t.String(),
|
|
35
|
+
dataSource: t.String()
|
|
36
|
+
}),
|
|
37
|
+
response: galleryModel
|
|
38
|
+
}).get("/listing", async ({ query }) => {
|
|
39
|
+
const dataSource = config.dataSources.find((o) => o.key === query.dataSource);
|
|
40
|
+
if (dataSource === void 0) throw new Error(`data source ${query.dataSource} not found`);
|
|
41
|
+
return dataSource.getListing({
|
|
42
|
+
searchQuery: query.query || null,
|
|
43
|
+
page: query.page
|
|
44
|
+
});
|
|
45
|
+
}, {
|
|
46
|
+
query: t.Object({
|
|
47
|
+
query: t.Optional(t.String()),
|
|
48
|
+
page: t.Number(),
|
|
49
|
+
dataSource: dataSourceKeys
|
|
50
|
+
}),
|
|
51
|
+
response: listingResultModel
|
|
52
|
+
}).get("/image", async ({ query }) => {
|
|
53
|
+
const cacheKeys = [
|
|
54
|
+
query.dataSource,
|
|
55
|
+
query.url,
|
|
56
|
+
query.format
|
|
57
|
+
];
|
|
58
|
+
const cachedImage = await cache.read(cacheKeys);
|
|
59
|
+
if (cachedImage !== null) return new Response(Buffer.from(cachedImage.data), { headers: { "Content-Type": `image/${query.format}` } });
|
|
60
|
+
const dataSource = config.dataSources.find((o) => o.key === query.dataSource);
|
|
61
|
+
if (dataSource === void 0) throw new Error(`data source ${query.dataSource} not found`);
|
|
62
|
+
const resizedImage = await sharp(await dataSource.getImage({ url: query.url })).resize({ width: 1280 }).toFormat(query.format, { quality: 72 }).toBuffer();
|
|
63
|
+
await cache.write(cacheKeys, resizedImage, 864e5);
|
|
64
|
+
return new Response(resizedImage, { headers: { "Content-Type": `image/${query.format}` } });
|
|
65
|
+
}, { query: t.Object({
|
|
66
|
+
url: t.String(),
|
|
67
|
+
format: t.Union([t.Literal("webp"), t.Literal("jpg")]),
|
|
68
|
+
dataSource: dataSourceKeys
|
|
69
|
+
}) }).listen(3e3);
|
|
70
|
+
console.log(`🦊 Elysia is running at http://${server.server?.hostname}:${server.server?.port}`);
|
|
71
|
+
//#endregion
|
|
72
|
+
export {};
|
|
73
|
+
|
|
74
|
+
//# sourceMappingURL=index.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.mjs","names":[],"sources":["../src/index.ts"],"sourcesContent":["#!/usr/bin/env node\nimport { t, Elysia } from \"elysia\";\nimport { swagger } from \"@elysiajs/swagger\";\nimport { cors } from \"@elysiajs/cors\";\nimport { defineCacheInstance } from \"@rayriffy/filesystem\";\nimport sharp from \"sharp\";\n\nimport { galleryModel, listingResultModel, type Config } from \"@riffyh/commons\";\nimport debug from \"debug\";\nimport path from \"node:path\";\n\nconst log = debug(\"riffyh:server\");\nconst cache = defineCacheInstance();\n\nlog(\"warming up server...\");\n\nconst configFile = process.env.RIFFYH_CONFIG_PATH || \"./riffyh.config.ts\";\nconst configPath = path.resolve(configFile);\nlog(`resolving config file at ${configPath}...`);\nconst config: Config = await import(configPath).then((o) => o.default);\n\nlog(`loaded configuration with ${config.dataSources.length} data sources`);\n\nconst dataSourceKeys = t.Union(config.dataSources.map((o) => t.Literal(o.key)));\n\nconst server = new Elysia()\n .use(\n swagger({\n exclude: [\"/_image\"],\n }),\n )\n .use(cors())\n .get(\"/\", ({ redirect }) => redirect(\"/swagger\"))\n .get(\"/health\", () => \"healthy\")\n .get(\n \"/dataSources\",\n () =>\n config.dataSources.map((o) => ({\n key: o.key,\n name: o.name,\n iconUrl: o.iconUrl,\n })),\n {\n response: t.Array(\n t.Object({\n key: t.String(),\n name: t.String(),\n iconUrl: t.String(),\n }),\n ),\n },\n )\n .get(\n \"/gallery\",\n async ({ query }) => {\n const dataSource = config.dataSources.find((o) => o.key === query.dataSource);\n if (dataSource === undefined) throw new Error(`data source ${query.dataSource} not found`);\n\n return dataSource.getGallery({\n id: query.id,\n });\n },\n {\n query: t.Object({\n id: t.String(),\n dataSource: t.String(),\n }),\n response: galleryModel,\n },\n )\n .get(\n \"/listing\",\n async ({ query }) => {\n const dataSource = config.dataSources.find((o) => o.key === query.dataSource);\n if (dataSource === undefined) throw new Error(`data source ${query.dataSource} not found`);\n\n return dataSource.getListing({\n searchQuery: query.query || null,\n page: query.page,\n });\n },\n {\n query: t.Object({\n query: t.Optional(t.String()),\n page: t.Number(),\n dataSource: dataSourceKeys,\n }),\n response: listingResultModel,\n },\n )\n .get(\n \"/image\",\n async ({ query }) => {\n const cacheKeys = [query.dataSource, query.url, query.format];\n\n const cachedImage = await cache.read<Buffer>(cacheKeys);\n if (cachedImage !== null)\n return new Response(Buffer.from(cachedImage.data), {\n headers: {\n \"Content-Type\": `image/${query.format}`,\n },\n });\n\n const dataSource = config.dataSources.find((o) => o.key === query.dataSource);\n if (dataSource === undefined) throw new Error(`data source ${query.dataSource} not found`);\n\n const fetchedImage = await dataSource.getImage({\n url: query.url,\n });\n const resizedImage = await sharp(fetchedImage)\n .resize({\n width: 1280,\n })\n .toFormat(query.format, {\n quality: 72,\n })\n .toBuffer();\n await cache.write(\n cacheKeys,\n resizedImage,\n 86_400_000, // 1 month\n );\n\n return new Response(resizedImage, {\n headers: {\n \"Content-Type\": `image/${query.format}`,\n },\n });\n },\n {\n query: t.Object({\n url: t.String(),\n format: t.Union([t.Literal(\"webp\"), t.Literal(\"jpg\")]),\n dataSource: dataSourceKeys,\n }),\n },\n )\n .listen(3000);\n\nexport type Server = typeof server;\n\nconsole.log(`🦊 Elysia is running at http://${server.server?.hostname}:${server.server?.port}`);\n"],"mappings":"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"}
|
package/package.json
ADDED
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@riffyh/server",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"bin": "dist/index.mjs",
|
|
5
|
+
"main": "dist/index.mjs",
|
|
6
|
+
"types": "dist/index.d.mts",
|
|
7
|
+
"type": "module",
|
|
8
|
+
"repository": {
|
|
9
|
+
"type": "git",
|
|
10
|
+
"url": "git+https://github.com/rayriffy/rayriffy-h.git"
|
|
11
|
+
},
|
|
12
|
+
"files": [
|
|
13
|
+
"dist/"
|
|
14
|
+
],
|
|
15
|
+
"publishConfig": {
|
|
16
|
+
"access": "public",
|
|
17
|
+
"registry": "https://registry.npmjs.org"
|
|
18
|
+
},
|
|
19
|
+
"dependencies": {
|
|
20
|
+
"@elysiajs/cors": "1.4.1",
|
|
21
|
+
"@elysiajs/swagger": "1.3.1",
|
|
22
|
+
"@rayriffy/filesystem": "1.0.1",
|
|
23
|
+
"@sinclair/typebox": "0.34.49",
|
|
24
|
+
"debug": "4.4.3",
|
|
25
|
+
"elysia": "1.4.28",
|
|
26
|
+
"sharp": "^0.34.5",
|
|
27
|
+
"@riffyh/commons": "2.0.0"
|
|
28
|
+
},
|
|
29
|
+
"devDependencies": {
|
|
30
|
+
"@types/debug": "4.1.13",
|
|
31
|
+
"tsdown": "0.21.7"
|
|
32
|
+
},
|
|
33
|
+
"scripts": {
|
|
34
|
+
"test": "echo \"Error: no test specified\" && exit 1",
|
|
35
|
+
"dev": "bun run --watch src/index.ts",
|
|
36
|
+
"build": "tsdown",
|
|
37
|
+
"start": "bun run dist/index.mjs"
|
|
38
|
+
}
|
|
39
|
+
}
|