@geekapps/silo-fastify 0.0.1

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.
@@ -0,0 +1,32 @@
1
+ import type { FastifyPluginAsync } from "fastify";
2
+ export interface SiloPluginOptions {
3
+ /** Where to store uploaded files */
4
+ storagePath: string;
5
+ /** Base URL of this Fastify server (used for signed URL generation) */
6
+ baseUrl: string;
7
+ /** HMAC secret for signed URLs (min 32 chars) */
8
+ secret: string;
9
+ /** Default signed URL TTL in seconds (default: 3600) */
10
+ defaultTtl?: number;
11
+ /** Max upload size in bytes (default: 100MB) */
12
+ maxFileSize?: number;
13
+ /** Route prefix (default: /silo) */
14
+ prefix?: string;
15
+ /** Custom allowed MIME types (merges with defaults) */
16
+ allowedMimeTypes?: string[];
17
+ }
18
+ declare module "fastify" {
19
+ interface FastifyInstance {
20
+ silo: {
21
+ createSignedUrl(key: string, bucket: string, ttl?: number): string;
22
+ verifyToken(token: string): {
23
+ key: string;
24
+ bucket: string;
25
+ exp: number;
26
+ } | null;
27
+ };
28
+ }
29
+ }
30
+ export declare const siloPlugin: FastifyPluginAsync<SiloPluginOptions>;
31
+ export default siloPlugin;
32
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,kBAAkB,EAAmB,MAAM,SAAS,CAAC;AAYnE,MAAM,WAAW,iBAAiB;IAChC,oCAAoC;IACpC,WAAW,EAAE,MAAM,CAAC;IACpB,uEAAuE;IACvE,OAAO,EAAE,MAAM,CAAC;IAChB,iDAAiD;IACjD,MAAM,EAAE,MAAM,CAAC;IACf,wDAAwD;IACxD,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,gDAAgD;IAChD,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,oCAAoC;IACpC,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,uDAAuD;IACvD,gBAAgB,CAAC,EAAE,MAAM,EAAE,CAAC;CAC7B;AAED,OAAO,QAAQ,SAAS,CAAC;IACvB,UAAU,eAAe;QACvB,IAAI,EAAE;YACJ,eAAe,CAAC,GAAG,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,GAAG,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;YACnE,WAAW,CAAC,KAAK,EAAE,MAAM,GAAG;gBAAE,GAAG,EAAE,MAAM,CAAC;gBAAC,MAAM,EAAE,MAAM,CAAC;gBAAC,GAAG,EAAE,MAAM,CAAA;aAAE,GAAG,IAAI,CAAC;SACjF,CAAC;KACH;CACF;AAyID,eAAO,MAAM,UAAU,uCAAwD,CAAC;AAChF,eAAe,UAAU,CAAC"}
package/dist/index.js ADDED
@@ -0,0 +1,128 @@
1
+ import fp from "fastify-plugin";
2
+ import fastifyMultipart from "@fastify/multipart";
3
+ import { createHmac, timingSafeEqual } from "node:crypto";
4
+ import { nanoid } from "nanoid";
5
+ import { fileTypeFromBuffer } from "file-type";
6
+ import { mkdir } from "node:fs/promises";
7
+ import { createReadStream } from "node:fs";
8
+ import { join, dirname } from "node:path";
9
+ import { PassThrough } from "node:stream";
10
+ const BLOCKED_EXTS = new Set([".exe", ".msi", ".bat", ".cmd", ".sh", ".ps1", ".dll", ".scr", ".vbs"]);
11
+ const plugin = async (fastify, opts) => {
12
+ const { storagePath, baseUrl, secret, defaultTtl = 3600, maxFileSize = 100 * 1024 * 1024, prefix = "/silo", } = opts;
13
+ if (secret.length < 32)
14
+ throw new Error("[@silo/fastify] secret must be at least 32 characters");
15
+ // Register multipart if not already registered
16
+ if (!fastify.hasContentTypeParser("multipart/form-data")) {
17
+ await fastify.register(fastifyMultipart, { limits: { fileSize: maxFileSize } });
18
+ }
19
+ function sign(data) {
20
+ return createHmac("sha256", secret).update(data).digest("base64url");
21
+ }
22
+ function createSignedUrl(key, bucket, ttl = defaultTtl) {
23
+ const exp = Math.floor(Date.now() / 1000) + ttl;
24
+ const payload = JSON.stringify({ key, bucket, exp });
25
+ const encoded = Buffer.from(payload).toString("base64url");
26
+ const sig = sign(encoded);
27
+ return `${baseUrl}${prefix}/files/${bucket}/${key}?token=${encoded}.${sig}`;
28
+ }
29
+ function verifyToken(token) {
30
+ const dot = token.lastIndexOf(".");
31
+ if (dot === -1)
32
+ return null;
33
+ const encoded = token.slice(0, dot);
34
+ const sig = token.slice(dot + 1);
35
+ try {
36
+ if (!timingSafeEqual(Buffer.from(sig), Buffer.from(sign(encoded))))
37
+ return null;
38
+ }
39
+ catch {
40
+ return null;
41
+ }
42
+ try {
43
+ const payload = JSON.parse(Buffer.from(encoded, "base64url").toString());
44
+ if (Math.floor(Date.now() / 1000) > payload.exp)
45
+ return null;
46
+ return payload;
47
+ }
48
+ catch {
49
+ return null;
50
+ }
51
+ }
52
+ // Decorate fastify instance
53
+ fastify.decorate("silo", { createSignedUrl, verifyToken });
54
+ // Upload route
55
+ fastify.post(`${prefix}/upload`, async (request, reply) => {
56
+ const data = await request.file();
57
+ if (!data)
58
+ return reply.status(400).send({ error: "No file provided" });
59
+ const ext = data.filename.slice(data.filename.lastIndexOf(".")).toLowerCase();
60
+ if (BLOCKED_EXTS.has(ext)) {
61
+ return reply.status(400).send({ error: `Blocked file extension: ${ext}` });
62
+ }
63
+ const key = nanoid(24);
64
+ const bucket = request.query["bucket"] ?? "default";
65
+ const shard = key.slice(0, 2) + "/" + key.slice(2, 4);
66
+ const filePath = join(storagePath, bucket, shard, key);
67
+ await mkdir(dirname(filePath), { recursive: true });
68
+ // Sniff magic bytes
69
+ const chunks = [];
70
+ const MAX_SNIFF = 4100;
71
+ let sniffed = false;
72
+ const pass = new PassThrough();
73
+ data.file.pipe(pass);
74
+ await new Promise((resolve, reject) => {
75
+ const writeStream = require("fs").createWriteStream(filePath);
76
+ pass.pipe(writeStream);
77
+ writeStream.on("finish", resolve);
78
+ writeStream.on("error", reject);
79
+ if (!sniffed) {
80
+ const onData = (chunk) => {
81
+ if (chunks.reduce((a, b) => a + b.length, 0) < MAX_SNIFF)
82
+ chunks.push(chunk);
83
+ else {
84
+ sniffed = true;
85
+ pass.off("data", onData);
86
+ }
87
+ };
88
+ pass.on("data", onData);
89
+ }
90
+ });
91
+ const buffer = Buffer.concat(chunks);
92
+ const fileType = await fileTypeFromBuffer(buffer);
93
+ const mimeType = fileType?.mime ?? data.mimetype ?? "application/octet-stream";
94
+ const signedUrl = createSignedUrl(key, bucket);
95
+ return reply.status(201).send({ key, bucket, mimeType, signedUrl });
96
+ });
97
+ // Serve file route
98
+ fastify.get(`${prefix}/files/:bucket/:key`, async (request, reply) => {
99
+ const { bucket, key } = request.params;
100
+ const token = request.query["token"];
101
+ if (!token)
102
+ return reply.status(401).send({ error: "Token required" });
103
+ const payload = verifyToken(token);
104
+ if (!payload || payload.key !== key || payload.bucket !== bucket) {
105
+ return reply.status(403).send({ error: "Invalid or expired token" });
106
+ }
107
+ const shard = key.slice(0, 2) + "/" + key.slice(2, 4);
108
+ const filePath = join(storagePath, bucket, shard, key);
109
+ try {
110
+ void reply.header("Cache-Control", "private, max-age=3600");
111
+ void reply.header("ETag", `"${key}"`);
112
+ return reply.send(createReadStream(filePath));
113
+ }
114
+ catch {
115
+ return reply.status(404).send({ error: "File not found" });
116
+ }
117
+ });
118
+ // Sign URL for existing file
119
+ fastify.post(`${prefix}/files/:bucket/:key/sign`, async (request, reply) => {
120
+ const { bucket, key } = request.params;
121
+ const body = request.body;
122
+ const url = createSignedUrl(key, bucket, body?.ttl);
123
+ return reply.send({ url, expiresIn: body?.ttl ?? defaultTtl });
124
+ });
125
+ };
126
+ export const siloPlugin = fp(plugin, { name: "@silo/fastify", fastify: "4.x" });
127
+ export default siloPlugin;
128
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,MAAM,gBAAgB,CAAC;AAChC,OAAO,gBAAgB,MAAM,oBAAoB,CAAC;AAClD,OAAO,EAAE,UAAU,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AAC1D,OAAO,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAC;AAChC,OAAO,EAAE,kBAAkB,EAAE,MAAM,WAAW,CAAC;AAC/C,OAAO,EAAE,KAAK,EAAqB,MAAM,kBAAkB,CAAC;AAC5D,OAAO,EAAE,gBAAgB,EAAE,MAAM,SAAS,CAAC;AAC3C,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAC1C,OAAO,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AA6B1C,MAAM,YAAY,GAAG,IAAI,GAAG,CAAC,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC;AAEtG,MAAM,MAAM,GAA0C,KAAK,EAAE,OAAO,EAAE,IAAI,EAAE,EAAE;IAC5E,MAAM,EACJ,WAAW,EACX,OAAO,EACP,MAAM,EACN,UAAU,GAAG,IAAI,EACjB,WAAW,GAAG,GAAG,GAAG,IAAI,GAAG,IAAI,EAC/B,MAAM,GAAG,OAAO,GACjB,GAAG,IAAI,CAAC;IAET,IAAI,MAAM,CAAC,MAAM,GAAG,EAAE;QAAE,MAAM,IAAI,KAAK,CAAC,uDAAuD,CAAC,CAAC;IAEjG,+CAA+C;IAC/C,IAAI,CAAC,OAAO,CAAC,oBAAoB,CAAC,qBAAqB,CAAC,EAAE,CAAC;QACzD,MAAM,OAAO,CAAC,QAAQ,CAAC,gBAAgB,EAAE,EAAE,MAAM,EAAE,EAAE,QAAQ,EAAE,WAAW,EAAE,EAAE,CAAC,CAAC;IAClF,CAAC;IAED,SAAS,IAAI,CAAC,IAAY;QACxB,OAAO,UAAU,CAAC,QAAQ,EAAE,MAAM,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,MAAM,CAAC,WAAW,CAAC,CAAC;IACvE,CAAC;IAED,SAAS,eAAe,CAAC,GAAW,EAAE,MAAc,EAAE,MAAc,UAAU;QAC5E,MAAM,GAAG,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,GAAG,EAAE,GAAG,IAAI,CAAC,GAAG,GAAG,CAAC;QAChD,MAAM,OAAO,GAAG,IAAI,CAAC,SAAS,CAAC,EAAE,GAAG,EAAE,MAAM,EAAE,GAAG,EAAE,CAAC,CAAC;QACrD,MAAM,OAAO,GAAG,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,QAAQ,CAAC,WAAW,CAAC,CAAC;QAC3D,MAAM,GAAG,GAAG,IAAI,CAAC,OAAO,CAAC,CAAC;QAC1B,OAAO,GAAG,OAAO,GAAG,MAAM,UAAU,MAAM,IAAI,GAAG,UAAU,OAAO,IAAI,GAAG,EAAE,CAAC;IAC9E,CAAC;IAED,SAAS,WAAW,CAAC,KAAa;QAChC,MAAM,GAAG,GAAG,KAAK,CAAC,WAAW,CAAC,GAAG,CAAC,CAAC;QACnC,IAAI,GAAG,KAAK,CAAC,CAAC;YAAE,OAAO,IAAI,CAAC;QAC5B,MAAM,OAAO,GAAG,KAAK,CAAC,KAAK,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC;QACpC,MAAM,GAAG,GAAG,KAAK,CAAC,KAAK,CAAC,GAAG,GAAG,CAAC,CAAC,CAAC;QACjC,IAAI,CAAC;YACH,IAAI,CAAC,eAAe,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC;gBAAE,OAAO,IAAI,CAAC;QAClF,CAAC;QAAC,MAAM,CAAC;YAAC,OAAO,IAAI,CAAC;QAAC,CAAC;QACxB,IAAI,CAAC;YACH,MAAM,OAAO,GAAG,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,IAAI,CAAC,OAAO,EAAE,WAAW,CAAC,CAAC,QAAQ,EAAE,CAAiD,CAAC;YACzH,IAAI,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,GAAG,EAAE,GAAG,IAAI,CAAC,GAAG,OAAO,CAAC,GAAG;gBAAE,OAAO,IAAI,CAAC;YAC7D,OAAO,OAAO,CAAC;QACjB,CAAC;QAAC,MAAM,CAAC;YAAC,OAAO,IAAI,CAAC;QAAC,CAAC;IAC1B,CAAC;IAED,4BAA4B;IAC5B,OAAO,CAAC,QAAQ,CAAC,MAAM,EAAE,EAAE,eAAe,EAAE,WAAW,EAAE,CAAC,CAAC;IAE3D,eAAe;IACf,OAAO,CAAC,IAAI,CAAC,GAAG,MAAM,SAAS,EAAE,KAAK,EAAE,OAAO,EAAE,KAAK,EAAE,EAAE;QACxD,MAAM,IAAI,GAAG,MAAM,OAAO,CAAC,IAAI,EAAE,CAAC;QAClC,IAAI,CAAC,IAAI;YAAE,OAAO,KAAK,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,kBAAkB,EAAE,CAAC,CAAC;QAExE,MAAM,GAAG,GAAG,IAAI,CAAC,QAAQ,CAAC,KAAK,CAAC,IAAI,CAAC,QAAQ,CAAC,WAAW,CAAC,GAAG,CAAC,CAAC,CAAC,WAAW,EAAE,CAAC;QAC9E,IAAI,YAAY,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,CAAC;YAC1B,OAAO,KAAK,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,2BAA2B,GAAG,EAAE,EAAE,CAAC,CAAC;QAC7E,CAAC;QAED,MAAM,GAAG,GAAG,MAAM,CAAC,EAAE,CAAC,CAAC;QACvB,MAAM,MAAM,GAAI,OAAO,CAAC,KAAgC,CAAC,QAAQ,CAAC,IAAI,SAAS,CAAC;QAChF,MAAM,KAAK,GAAG,GAAG,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,GAAG,GAAG,GAAG,GAAG,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;QACtD,MAAM,QAAQ,GAAG,IAAI,CAAC,WAAW,EAAE,MAAM,EAAE,KAAK,EAAE,GAAG,CAAC,CAAC;QACvD,MAAM,KAAK,CAAC,OAAO,CAAC,QAAQ,CAAC,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;QAEpD,oBAAoB;QACpB,MAAM,MAAM,GAAa,EAAE,CAAC;QAC5B,MAAM,SAAS,GAAG,IAAI,CAAC;QACvB,IAAI,OAAO,GAAG,KAAK,CAAC;QAEpB,MAAM,IAAI,GAAG,IAAI,WAAW,EAAE,CAAC;QAC/B,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QAErB,MAAM,IAAI,OAAO,CAAO,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE;YAC1C,MAAM,WAAW,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC,iBAAiB,CAAC,QAAQ,CAAC,CAAC;YAC9D,IAAI,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC;YACvB,WAAW,CAAC,EAAE,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC;YAClC,WAAW,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,CAAC,CAAC;YAEhC,IAAI,CAAC,OAAO,EAAE,CAAC;gBACb,MAAM,MAAM,GAAG,CAAC,KAAa,EAAE,EAAE;oBAC/B,IAAI,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC,GAAG,SAAS;wBAAE,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;yBACxE,CAAC;wBAAC,OAAO,GAAG,IAAI,CAAC;wBAAC,IAAI,CAAC,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;oBAAC,CAAC;gBACpD,CAAC,CAAC;gBACF,IAAI,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;YAC1B,CAAC;QACH,CAAC,CAAC,CAAC;QAEH,MAAM,MAAM,GAAG,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;QACrC,MAAM,QAAQ,GAAG,MAAM,kBAAkB,CAAC,MAAM,CAAC,CAAC;QAClD,MAAM,QAAQ,GAAG,QAAQ,EAAE,IAAI,IAAI,IAAI,CAAC,QAAQ,IAAI,0BAA0B,CAAC;QAE/E,MAAM,SAAS,GAAG,eAAe,CAAC,GAAG,EAAE,MAAM,CAAC,CAAC;QAE/C,OAAO,KAAK,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,EAAE,GAAG,EAAE,MAAM,EAAE,QAAQ,EAAE,SAAS,EAAE,CAAC,CAAC;IACtE,CAAC,CAAC,CAAC;IAEH,mBAAmB;IACnB,OAAO,CAAC,GAAG,CACT,GAAG,MAAM,qBAAqB,EAC9B,KAAK,EAAE,OAAO,EAAE,KAAK,EAAE,EAAE;QACvB,MAAM,EAAE,MAAM,EAAE,GAAG,EAAE,GAAG,OAAO,CAAC,MAAM,CAAC;QACvC,MAAM,KAAK,GAAI,OAAO,CAAC,KAAgC,CAAC,OAAO,CAAC,CAAC;QACjE,IAAI,CAAC,KAAK;YAAE,OAAO,KAAK,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,gBAAgB,EAAE,CAAC,CAAC;QAEvE,MAAM,OAAO,GAAG,WAAW,CAAC,KAAK,CAAC,CAAC;QACnC,IAAI,CAAC,OAAO,IAAI,OAAO,CAAC,GAAG,KAAK,GAAG,IAAI,OAAO,CAAC,MAAM,KAAK,MAAM,EAAE,CAAC;YACjE,OAAO,KAAK,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,0BAA0B,EAAE,CAAC,CAAC;QACvE,CAAC;QAED,MAAM,KAAK,GAAG,GAAG,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,GAAG,GAAG,GAAG,GAAG,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;QACtD,MAAM,QAAQ,GAAG,IAAI,CAAC,WAAW,EAAE,MAAM,EAAE,KAAK,EAAE,GAAG,CAAC,CAAC;QAEvD,IAAI,CAAC;YACH,KAAK,KAAK,CAAC,MAAM,CAAC,eAAe,EAAE,uBAAuB,CAAC,CAAC;YAC5D,KAAK,KAAK,CAAC,MAAM,CAAC,MAAM,EAAE,IAAI,GAAG,GAAG,CAAC,CAAC;YACtC,OAAO,KAAK,CAAC,IAAI,CAAC,gBAAgB,CAAC,QAAQ,CAAC,CAAC,CAAC;QAChD,CAAC;QAAC,MAAM,CAAC;YACP,OAAO,KAAK,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,gBAAgB,EAAE,CAAC,CAAC;QAC7D,CAAC;IACH,CAAC,CACF,CAAC;IAEF,6BAA6B;IAC7B,OAAO,CAAC,IAAI,CACV,GAAG,MAAM,0BAA0B,EACnC,KAAK,EAAE,OAAO,EAAE,KAAK,EAAE,EAAE;QACvB,MAAM,EAAE,MAAM,EAAE,GAAG,EAAE,GAAG,OAAO,CAAC,MAAM,CAAC;QACvC,MAAM,IAAI,GAAG,OAAO,CAAC,IAAoC,CAAC;QAC1D,MAAM,GAAG,GAAG,eAAe,CAAC,GAAG,EAAE,MAAM,EAAE,IAAI,EAAE,GAAG,CAAC,CAAC;QACpD,OAAO,KAAK,CAAC,IAAI,CAAC,EAAE,GAAG,EAAE,SAAS,EAAE,IAAI,EAAE,GAAG,IAAI,UAAU,EAAE,CAAC,CAAC;IACjE,CAAC,CACF,CAAC;AACJ,CAAC,CAAC;AAEF,MAAM,CAAC,MAAM,UAAU,GAAG,EAAE,CAAC,MAAM,EAAE,EAAE,IAAI,EAAE,eAAe,EAAE,OAAO,EAAE,KAAK,EAAE,CAAC,CAAC;AAChF,eAAe,UAAU,CAAC"}
package/package.json ADDED
@@ -0,0 +1,36 @@
1
+ {
2
+ "name": "@geekapps/silo-fastify",
3
+ "version": "0.0.1",
4
+ "description": "Fastify plugin to embed Silo file handling in any Fastify app",
5
+ "type": "module",
6
+ "main": "./dist/index.js",
7
+ "types": "./dist/index.d.ts",
8
+ "files": [
9
+ "dist"
10
+ ],
11
+ "exports": {
12
+ ".": {
13
+ "import": "./dist/index.js",
14
+ "types": "./dist/index.d.ts"
15
+ }
16
+ },
17
+ "scripts": {
18
+ "build": "tsc -p tsconfig.json",
19
+ "dev": "tsc -p tsconfig.json --watch",
20
+ "typecheck": "tsc --noEmit"
21
+ },
22
+ "peerDependencies": {
23
+ "fastify": ">=5.0.0"
24
+ },
25
+ "dependencies": {
26
+ "@fastify/multipart": "^10.0.0",
27
+ "fastify-plugin": "^5.0.1",
28
+ "file-type": "^22.0.1",
29
+ "nanoid": "^5.1.11"
30
+ },
31
+ "devDependencies": {
32
+ "@types/node": "^24.0.0",
33
+ "fastify": "^5.8.5",
34
+ "typescript": "^5.9.3"
35
+ }
36
+ }