Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
},
"devDependencies": {
"@turbo/gen": "^2.0.9",
"@types/node": "20.14.11",
"dotenv-cli": "^7.4.2",
"eslint": "^9.7.0",
"prettier": "^3.3.3",
Expand Down
9 changes: 6 additions & 3 deletions packages/auth-better-auth/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
"description": "Better Auth adapter for HackKit",
"type": "module",
"main": "./dist/index.js",
"types": "./dist/index.d.ts",
"module": "./dist/index.mjs",
"exports": {
".": {
"types": "./dist/index.d.ts",
Expand All @@ -19,17 +19,20 @@
"dist"
],
"scripts": {
"build": "tsc -p tsconfig.json",
"build": "tsup src/index.ts src/session.ts --format cjs,esm --dts",
"dev": "tsup src/index.ts src/session.ts --format cjs,esm --dts --watch",
"typecheck": "tsc -p tsconfig.json --noEmit"
},
"dependencies": {
"@hackkit/core": "workspace:*"
"@hackkit/core": "workspace:*",
"server-only": "^0.0.1"
},
"peerDependencies": {
"better-auth": ">=1.6",
"next": ">=14"
},
"devDependencies": {
"tsup": "^8.5.1",
"typescript": "5.5.3"
},
"license": "MIT",
Expand Down
1 change: 1 addition & 0 deletions packages/blob-local/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
dist
12 changes: 7 additions & 5 deletions packages/blob-local/dist/index.d.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,14 @@
import type { BlobStorageAdapterWithView } from "@hackkit/core";
export type LocalBlobStorageOptions = {
import { BlobStorageAdapterWithView } from '@hackkit/core';

type LocalBlobStorageOptions = {
baseDir: string;
filesRoutePrefix?: string;
appBaseUrl?: string;
};
export type LocalBlobStorage = BlobStorageAdapterWithView & {
type LocalBlobStorage = BlobStorageAdapterWithView & {
resolveAbsolutePath(key: string): string;
ensureDirectoryForKey(key: string): Promise<string>;
};
export declare function createLocalBlobStorage(options: LocalBlobStorageOptions): LocalBlobStorage;
//# sourceMappingURL=index.d.ts.map
declare function createLocalBlobStorage(options: LocalBlobStorageOptions): LocalBlobStorage;

export { type LocalBlobStorage, type LocalBlobStorageOptions, createLocalBlobStorage };
1 change: 0 additions & 1 deletion packages/blob-local/dist/index.d.ts.map

This file was deleted.

102 changes: 53 additions & 49 deletions packages/blob-local/dist/index.js
Original file line number Diff line number Diff line change
@@ -1,54 +1,58 @@
import { mkdir, readFile } from "node:fs/promises";
import { dirname, join, normalize, relative, resolve } from "node:path";
import { randomUUID } from "node:crypto";
// src/index.ts
import { mkdir, readFile } from "fs/promises";
import { dirname, join, normalize, relative, resolve } from "path";
import { randomUUID } from "crypto";
function sanitizeKey(key) {
const normalized = normalize(key).replace(/^(\.\.(\/|\\|$))+/, "");
if (normalized.startsWith("..")) {
throw new Error("Invalid storage key.");
}
return normalized;
const normalized = normalize(key).replace(/^(\.\.(\/|\\|$))+/, "");
if (normalized.startsWith("..")) {
throw new Error("Invalid storage key.");
}
return normalized;
}
function buildStoredFileReference(filesRoutePrefix, key) {
return `${filesRoutePrefix}/view?key=${encodeURIComponent(key)}`;
return `${filesRoutePrefix}/view?key=${encodeURIComponent(key)}`;
}
export function createLocalBlobStorage(options) {
const baseDir = resolve(options.baseDir);
const filesRoutePrefix = options.filesRoutePrefix ?? "/api/files";
const appBaseUrl = options.appBaseUrl ?? "";
const storage = {
async getUploadTarget(input) {
const extension = input.fileName.includes(".")
? input.fileName.split(".").pop()
: undefined;
const key = sanitizeKey(`${input.location}/${randomUUID()}${extension ? `.${extension}` : ""}`);
const storedFileReference = buildStoredFileReference(filesRoutePrefix, key);
const uploadUrl = `${appBaseUrl}${filesRoutePrefix}/upload?key=${encodeURIComponent(key)}`;
return { uploadUrl, storedFileReference };
},
async readObject(input) {
const key = sanitizeKey(input.key);
const filePath = join(baseDir, key);
const relativePath = relative(baseDir, filePath);
if (relativePath.startsWith(".."))
return null;
try {
const body = await readFile(filePath);
return { body };
}
catch {
return null;
}
},
resolveAbsolutePath(key) {
const sanitized = sanitizeKey(key);
return join(baseDir, sanitized);
},
async ensureDirectoryForKey(key) {
const filePath = storage.resolveAbsolutePath(key);
await mkdir(dirname(filePath), { recursive: true });
return filePath;
},
};
return storage;
function createLocalBlobStorage(options) {
const baseDir = resolve(options.baseDir);
const filesRoutePrefix = options.filesRoutePrefix ?? "/api/files";
const appBaseUrl = options.appBaseUrl ?? "";
const storage = {
async getUploadTarget(input) {
const extension = input.fileName.includes(".") ? input.fileName.split(".").pop() : void 0;
const key = sanitizeKey(
`${input.location}/${randomUUID()}${extension ? `.${extension}` : ""}`
);
const storedFileReference = buildStoredFileReference(
filesRoutePrefix,
key
);
const uploadUrl = `${appBaseUrl}${filesRoutePrefix}/upload?key=${encodeURIComponent(key)}`;
return { uploadUrl, storedFileReference };
},
async readObject(input) {
const key = sanitizeKey(input.key);
const filePath = join(baseDir, key);
const relativePath = relative(baseDir, filePath);
if (relativePath.startsWith("..")) return null;
try {
const body = await readFile(filePath);
return { body };
} catch {
return null;
}
},
resolveAbsolutePath(key) {
const sanitized = sanitizeKey(key);
return join(baseDir, sanitized);
},
async ensureDirectoryForKey(key) {
const filePath = storage.resolveAbsolutePath(key);
await mkdir(dirname(filePath), { recursive: true });
return filePath;
}
};
return storage;
}
//# sourceMappingURL=index.js.map
export {
createLocalBlobStorage
};
1 change: 0 additions & 1 deletion packages/blob-local/dist/index.js.map

This file was deleted.

5 changes: 3 additions & 2 deletions packages/blob-local/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -15,14 +15,15 @@
"dist"
],
"scripts": {
"build": "tsc -p tsconfig.json",
"build": "tsup src/index.ts --format cjs,esm --dts",
"dev": "tsup src/index.ts --format cjs,esm --dts --watch",
"typecheck": "tsc -p tsconfig.json --noEmit"
},
"dependencies": {
"@hackkit/core": "workspace:*"
},
"devDependencies": {
"@types/node": "20.14.11",
"tsup": "^8.5.1",
"typescript": "5.5.3"
},
"license": "MIT",
Expand Down
1 change: 1 addition & 0 deletions packages/blob-s3/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
dist
12 changes: 7 additions & 5 deletions packages/blob-s3/dist/index.d.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import type { BlobStorageAdapterWithView } from "@hackkit/core";
export type S3BlobStorageOptions = {
import { BlobStorageAdapterWithView } from '@hackkit/core';

type S3BlobStorageOptions = {
bucket: string;
region: string;
endpoint?: string;
Expand All @@ -8,8 +9,9 @@ export type S3BlobStorageOptions = {
filesRoutePrefix?: string;
presignExpiresInSeconds?: number;
};
export type S3BlobStorage = BlobStorageAdapterWithView & {
type S3BlobStorage = BlobStorageAdapterWithView & {
getPresignedViewUrl(key: string): Promise<string>;
};
export declare function createS3BlobStorage(options: S3BlobStorageOptions): S3BlobStorage;
//# sourceMappingURL=index.d.ts.map
declare function createS3BlobStorage(options: S3BlobStorageOptions): S3BlobStorage;

export { type S3BlobStorage, type S3BlobStorageOptions, createS3BlobStorage };
1 change: 0 additions & 1 deletion packages/blob-s3/dist/index.d.ts.map

This file was deleted.

128 changes: 71 additions & 57 deletions packages/blob-s3/dist/index.js
Original file line number Diff line number Diff line change
@@ -1,61 +1,75 @@
import { randomUUID } from "node:crypto";
import { GetObjectCommand, PutObjectCommand, S3Client, } from "@aws-sdk/client-s3";
// src/index.ts
import { randomUUID } from "crypto";
import {
GetObjectCommand,
PutObjectCommand,
S3Client
} from "@aws-sdk/client-s3";
import { getSignedUrl } from "@aws-sdk/s3-request-presigner";
function buildStoredFileReference(filesRoutePrefix, key) {
return `${filesRoutePrefix}/view?key=${encodeURIComponent(key)}`;
return `${filesRoutePrefix}/view?key=${encodeURIComponent(key)}`;
}
export function createS3BlobStorage(options) {
const filesRoutePrefix = options.filesRoutePrefix ?? "/api/files";
const expiresIn = options.presignExpiresInSeconds ?? 3600;
const client = new S3Client({
region: options.region,
endpoint: options.endpoint,
credentials: options.accessKeyId && options.secretAccessKey
? {
accessKeyId: options.accessKeyId,
secretAccessKey: options.secretAccessKey,
}
: undefined,
});
return {
async getUploadTarget(input) {
const extension = input.fileName.includes(".")
? input.fileName.split(".").pop()
: undefined;
const key = `${input.location}/${randomUUID()}${extension ? `.${extension}` : ""}`;
const uploadUrl = await getSignedUrl(client, new PutObjectCommand({
Bucket: options.bucket,
Key: key,
}), { expiresIn });
return {
uploadUrl,
storedFileReference: buildStoredFileReference(filesRoutePrefix, key),
};
},
async readObject(input) {
try {
const response = await client.send(new GetObjectCommand({
Bucket: options.bucket,
Key: input.key,
}));
if (!response.Body)
return null;
const bytes = await response.Body.transformToByteArray();
return {
body: bytes,
contentType: response.ContentType,
};
}
catch {
return null;
}
},
async getPresignedViewUrl(key) {
return getSignedUrl(client, new GetObjectCommand({
Bucket: options.bucket,
Key: key,
}), { expiresIn });
},
};
function createS3BlobStorage(options) {
const filesRoutePrefix = options.filesRoutePrefix ?? "/api/files";
const expiresIn = options.presignExpiresInSeconds ?? 3600;
const client = new S3Client({
region: options.region,
endpoint: options.endpoint,
credentials: options.accessKeyId && options.secretAccessKey ? {
accessKeyId: options.accessKeyId,
secretAccessKey: options.secretAccessKey
} : void 0
});
return {
async getUploadTarget(input) {
const extension = input.fileName.includes(".") ? input.fileName.split(".").pop() : void 0;
const key = `${input.location}/${randomUUID()}${extension ? `.${extension}` : ""}`;
const uploadUrl = await getSignedUrl(
client,
new PutObjectCommand({
Bucket: options.bucket,
Key: key
}),
{ expiresIn }
);
return {
uploadUrl,
storedFileReference: buildStoredFileReference(
filesRoutePrefix,
key
)
};
},
async readObject(input) {
try {
const response = await client.send(
new GetObjectCommand({
Bucket: options.bucket,
Key: input.key
})
);
if (!response.Body) return null;
const bytes = await response.Body.transformToByteArray();
return {
body: bytes,
contentType: response.ContentType
};
} catch {
return null;
}
},
async getPresignedViewUrl(key) {
return getSignedUrl(
client,
new GetObjectCommand({
Bucket: options.bucket,
Key: key
}),
{ expiresIn }
);
}
};
}
//# sourceMappingURL=index.js.map
export {
createS3BlobStorage
};
1 change: 0 additions & 1 deletion packages/blob-s3/dist/index.js.map

This file was deleted.

5 changes: 3 additions & 2 deletions packages/blob-s3/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,8 @@
"dist"
],
"scripts": {
"build": "tsc -p tsconfig.json",
"build": "tsup src/index.ts --format cjs,esm --dts",
"dev": "tsup src/index.ts --format cjs,esm --dts --watch",
"typecheck": "tsc -p tsconfig.json --noEmit"
},
"dependencies": {
Expand All @@ -24,7 +25,7 @@
"@hackkit/core": "workspace:*"
},
"devDependencies": {
"@types/node": "20.14.11",
"tsup": "^8.5.1",
"typescript": "5.5.3"
},
"license": "MIT",
Expand Down
Loading