@od-oneapp/storage 2026.2.1701 → 2026.2.2001-canary.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.
- package/client-next.d.mts +1 -2
- package/client-next.d.mts.map +1 -1
- package/client.d.mts +39 -1
- package/client.d.mts.map +1 -1
- package/{env-DQI-n3Mw.mjs → env-BRxsA_k1.mjs} +94 -2
- package/env-BRxsA_k1.mjs.map +1 -0
- package/env.mjs +1 -1
- package/{health-check-im_huJ59.d.mts → health-check-Cxg9x7Cb.d.mts} +30 -3
- package/health-check-Cxg9x7Cb.d.mts.map +1 -0
- package/health-check-ekerANJG.mjs +832 -0
- package/health-check-ekerANJG.mjs.map +1 -0
- package/index.mjs +1 -1
- package/package.json +21 -23
- package/server-edge.d.mts +1 -2
- package/server-edge.d.mts.map +1 -1
- package/server-edge.mjs +2 -2
- package/server-next.d.mts +1 -2
- package/server-next.d.mts.map +1 -1
- package/server-next.mjs +3 -4
- package/server-next.mjs.map +1 -1
- package/server.d.mts +1 -3
- package/server.d.mts.map +1 -1
- package/server.mjs +3 -4
- package/server.mjs.map +1 -1
- package/{vercel-blob-DA8HaYuw.mjs → vercel-blob-DrfolJEu.mjs} +2 -2
- package/{vercel-blob-DA8HaYuw.mjs.map → vercel-blob-DrfolJEu.mjs.map} +1 -1
- package/client-utils-Dx6W25iz.d.mts +0 -43
- package/client-utils-Dx6W25iz.d.mts.map +0 -1
- package/env-DQI-n3Mw.mjs.map +0 -1
- package/health-check-Cow8MNnJ.mjs +0 -2208
- package/health-check-Cow8MNnJ.mjs.map +0 -1
- package/health-check-im_huJ59.d.mts.map +0 -1
- package/vercel-blob-07Sx0Akn.d.mts +0 -31
- package/vercel-blob-07Sx0Akn.d.mts.map +0 -1
package/client-next.d.mts
CHANGED
|
@@ -1,8 +1,7 @@
|
|
|
1
1
|
import { KeyGenerationOptions, KeyPattern, generateMultipleKeys, generateStorageKey, isKeyPattern, normalizeStorageKey, parseStorageKey, sanitizeStorageKey, validateStorageKey } from "./keys.mjs";
|
|
2
2
|
import { ValidationOptions, formatFileSize, parseFileSize, validateFileSize, validateMimeType } from "./validation.mjs";
|
|
3
3
|
import { BlobListResponse, ClientUploadOptions, CloudflareImagesBatchToken, CloudflareImagesListOptions, CloudflareImagesTransformOptions, CloudflareImagesVariant, DirectUploadResponse, ListOptions, PresignedUploadUrl, StorageObject, UploadOptions, UploadProgress, VercelBlobOptions } from "./types.mjs";
|
|
4
|
-
import {
|
|
5
|
-
import { generateClientTokenFromReadWriteToken, handleUpload, upload, uploadFile } from "./client.mjs";
|
|
4
|
+
import { ClientMultipartUpload, ClientPresignedUploadUrl, ClientUploadProgress, downloadFromUrl, generateClientTokenFromReadWriteToken, handleUpload, splitFileIntoChunks, upload, uploadDirectToUrl, uploadFile, uploadWithPresignedUrl } from "./client.mjs";
|
|
6
5
|
|
|
7
6
|
//#region src/client-next.d.ts
|
|
8
7
|
declare function uploadFileWithProgress(pathname: string, file: File | Blob, options?: {
|
package/client-next.d.mts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"client-next.d.mts","names":[],"sources":["../src/client-next.ts"],"mappings":"
|
|
1
|
+
{"version":3,"file":"client-next.d.mts","names":[],"sources":["../src/client-next.ts"],"mappings":";;;;;;iBAwBsB,sBAAA,CACpB,QAAA,UACA,IAAA,EAAM,IAAA,GAAO,IAAA,EACb,OAAA;EACE,MAAA;EACA,eAAA;EACA,cAAA;EACA,kBAAA;EACA,aAAA;EACA,WAAA;EACA,SAAA;EACA,gBAAA,IAAoB,KAAA;IAAS,MAAA;IAAgB,KAAA;IAAgB,UAAA;EAAA;EAC7D,eAAA;AAAA,IAED,OAAA;EAAU,GAAA;EAAa,QAAA;AAAA;AAAA,iBA0BJ,mBAAA,CACpB,KAAA,EAAO,IAAA,IACP,WAAA,GAAc,IAAA,EAAM,IAAA,EAAM,KAAA,qBAC1B,OAAA;EACE,MAAA;EACA,eAAA;EACA,cAAA;EACA,kBAAA;EACA,aAAA;EACA,WAAA;EACA,SAAA;EACA,gBAAA,IAAoB,KAAA;IAAS,MAAA;IAAgB,KAAA;IAAgB,UAAA;EAAA;EAC7D,eAAA;EACA,cAAA,IACE,SAAA,UACA,QAAA;IAAY,MAAA;IAAgB,KAAA;IAAgB,UAAA;EAAA;AAAA,IAG/C,OAAA,CAAQ,KAAA;EAAQ,GAAA;EAAa,QAAA;EAAkB,OAAA;EAAkB,KAAA;AAAA;AAAA,iBAqD9C,qBAAA,CACpB,IAAA,EAAM,IAAA,EACN,OAAA;EACE,WAAA;EACA,gBAAA;EACA,iBAAA;AAAA,IAED,OAAA;EAAU,KAAA;EAAgB,MAAA;AAAA"}
|
package/client.d.mts
CHANGED
|
@@ -1,9 +1,47 @@
|
|
|
1
1
|
import { KeyGenerationOptions, KeyPattern, generateMultipleKeys, generateStorageKey, isKeyPattern, normalizeStorageKey, parseStorageKey, sanitizeStorageKey, validateStorageKey } from "./keys.mjs";
|
|
2
2
|
import { ValidationOptions, formatFileSize, parseFileSize, validateFileSize, validateMimeType } from "./validation.mjs";
|
|
3
3
|
import { BlobListResponse, ClientUploadOptions, CloudflareImagesBatchToken, CloudflareImagesListOptions, CloudflareImagesTransformOptions, CloudflareImagesVariant, DirectUploadResponse, ListOptions, PresignedUploadUrl, StorageObject, UploadOptions, UploadProgress, VercelBlobOptions } from "./types.mjs";
|
|
4
|
-
import { a as splitFileIntoChunks, i as downloadFromUrl, n as ClientPresignedUploadUrl, o as uploadDirectToUrl, r as ClientUploadProgress, s as uploadWithPresignedUrl, t as ClientMultipartUpload } from "./client-utils-Dx6W25iz.mjs";
|
|
5
4
|
import { generateClientTokenFromReadWriteToken, handleUpload, upload } from "@vercel/blob/client";
|
|
6
5
|
|
|
6
|
+
//#region src/client-utils.d.ts
|
|
7
|
+
interface ClientPresignedUploadUrl extends PresignedUploadUrl {
|
|
8
|
+
key: string;
|
|
9
|
+
}
|
|
10
|
+
interface ClientUploadProgress {
|
|
11
|
+
loaded: number;
|
|
12
|
+
total: number;
|
|
13
|
+
percentage: number;
|
|
14
|
+
}
|
|
15
|
+
declare function uploadWithPresignedUrl(presignedData: ClientPresignedUploadUrl, file: File | Blob, options?: {
|
|
16
|
+
onProgress?: (progress: ClientUploadProgress) => void;
|
|
17
|
+
}): Promise<void>;
|
|
18
|
+
declare function uploadDirectToUrl(url: string, file: File | Blob, options?: {
|
|
19
|
+
headers?: Record<string, string>;
|
|
20
|
+
onProgress?: (progress: ClientUploadProgress) => void;
|
|
21
|
+
}): Promise<void>;
|
|
22
|
+
declare class ClientMultipartUpload {
|
|
23
|
+
private uploadId;
|
|
24
|
+
private key;
|
|
25
|
+
private parts;
|
|
26
|
+
constructor(uploadId: string, key: string);
|
|
27
|
+
uploadPart(partNumber: number, presignedUrl: string, data: Blob, _onProgress?: (progress: ClientUploadProgress) => void): Promise<void>;
|
|
28
|
+
getParts(): {
|
|
29
|
+
PartNumber: number;
|
|
30
|
+
ETag: string;
|
|
31
|
+
}[];
|
|
32
|
+
getUploadId(): string;
|
|
33
|
+
getKey(): string;
|
|
34
|
+
}
|
|
35
|
+
declare function splitFileIntoChunks(file: File | Blob, chunkSize?: number): AsyncGenerator<{
|
|
36
|
+
chunk: Blob;
|
|
37
|
+
partNumber: number;
|
|
38
|
+
start: number;
|
|
39
|
+
end: number;
|
|
40
|
+
}>;
|
|
41
|
+
declare function downloadFromUrl(url: string, options?: {
|
|
42
|
+
onProgress?: (progress: ClientUploadProgress) => void;
|
|
43
|
+
}): Promise<Blob>;
|
|
44
|
+
//#endregion
|
|
7
45
|
//#region src/client.d.ts
|
|
8
46
|
declare function uploadFile(pathname: string, file: File | Blob, options?: {
|
|
9
47
|
access?: 'public' | 'private';
|
package/client.d.mts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"client.d.mts","names":[],"sources":["../src/client.ts"],"mappings":"
|
|
1
|
+
{"version":3,"file":"client.d.mts","names":[],"sources":["../src/client-utils.ts","../src/client.ts"],"mappings":";;;;;;UAoBiB,wBAAA,SAAiC,kBAAA;EAChD,GAAA;AAAA;AAAA,UAOe,oBAAA;EACf,MAAA;EACA,KAAA;EACA,UAAA;AAAA;AAAA,iBAMoB,sBAAA,CACpB,aAAA,EAAe,wBAAA,EACf,IAAA,EAAM,IAAA,GAAO,IAAA,EACb,OAAA;EACE,UAAA,IAAc,QAAA,EAAU,oBAAA;AAAA,IAEzB,OAAA;AAAA,iBA2DmB,iBAAA,CACpB,GAAA,UACA,IAAA,EAAM,IAAA,GAAO,IAAA,EACb,OAAA;EACE,OAAA,GAAU,MAAA;EACV,UAAA,IAAc,QAAA,EAAU,oBAAA;AAAA,IAEzB,OAAA;AAAA,cAyDU,qBAAA;EAAA,QACH,QAAA;EAAA,QACA,GAAA;EAAA,QACA,KAAA;cAEI,QAAA,UAAkB,GAAA;EAKxB,UAAA,CACJ,UAAA,UACA,YAAA,UACA,IAAA,EAAM,IAAA,EACN,WAAA,IAAe,QAAA,EAAU,oBAAA,YACxB,OAAA;EAgBH,QAAA,CAAA;;;;EAIA,WAAA,CAAA;EAIA,MAAA,CAAA;AAAA;AAAA,iBAQqB,mBAAA,CACrB,IAAA,EAAM,IAAA,GAAO,IAAA,EACb,SAAA,YACC,cAAA;EAAiB,KAAA,EAAO,IAAA;EAAM,UAAA;EAAoB,KAAA;EAAe,GAAA;AAAA;AAAA,iBAsB9C,eAAA,CACpB,GAAA,UACA,OAAA;EACE,UAAA,IAAc,QAAA,EAAU,oBAAA;AAAA,IAEzB,OAAA,CAAQ,IAAA;;;iBC/LW,UAAA,CACpB,QAAA,UACA,IAAA,EAAM,IAAA,GAAO,IAAA,EACb,OAAA;EACE,MAAA;EACA,eAAA;EACA,cAAA;EACA,kBAAA;EACA,aAAA;EACA,WAAA;EACA,SAAA;EACA,gBAAA,IAAoB,KAAA;IAAS,MAAA;IAAgB,KAAA;IAAgB,UAAA;EAAA;EAC7D,eAAA;AAAA,IAED,OAAA;EAAU,GAAA;EAAa,QAAA;AAAA"}
|
|
@@ -1,7 +1,99 @@
|
|
|
1
|
-
import { logWarn } from "@od-oneapp/shared/logger";
|
|
2
1
|
import { createEnv } from "@t3-oss/env-core";
|
|
3
2
|
import { z } from "zod/v4";
|
|
4
3
|
|
|
4
|
+
//#region ../shared/src/logger/core.ts
|
|
5
|
+
/**
|
|
6
|
+
* @fileoverview Canonical logger for the OneApp platform.
|
|
7
|
+
*
|
|
8
|
+
* This module provides isomorphic logging functions that work in any environment
|
|
9
|
+
* (Browser, Node.js, Edge). Logs directly to console with runtime information.
|
|
10
|
+
*
|
|
11
|
+
* Preferred usage is to import from '@od-oneapp/shared/logger'.
|
|
12
|
+
*/
|
|
13
|
+
/**
|
|
14
|
+
* Get runtime environment information.
|
|
15
|
+
*
|
|
16
|
+
* Detects the current runtime environment (browser, Node.js, edge, Bun) and returns
|
|
17
|
+
* detailed information about the environment type, version, and capabilities.
|
|
18
|
+
*
|
|
19
|
+
* @returns Runtime information object with type, version, and environment-specific details
|
|
20
|
+
*
|
|
21
|
+
* @example
|
|
22
|
+
* ```typescript
|
|
23
|
+
* const runtime = getRuntimeInfo();
|
|
24
|
+
* // Returns: { type: 'node', version: '22.0.0', major: 22, minor: 0, isNode22Plus: true, isNextJs: true }
|
|
25
|
+
* // or: { type: 'browser', isNextJs: true }
|
|
26
|
+
* // or: { type: 'edge', variant: 'vercel' }
|
|
27
|
+
* ```
|
|
28
|
+
*/
|
|
29
|
+
const getRuntimeInfo = () => {
|
|
30
|
+
if (typeof globalThis !== "undefined" && globalThis.EdgeRuntime) return {
|
|
31
|
+
type: "edge",
|
|
32
|
+
variant: "vercel"
|
|
33
|
+
};
|
|
34
|
+
if (typeof globalThis !== "undefined" && globalThis.caches && typeof globalThis.caches !== "undefined") return {
|
|
35
|
+
type: "edge",
|
|
36
|
+
variant: "cloudflare"
|
|
37
|
+
};
|
|
38
|
+
if (typeof process !== "undefined" && process.versions?.bun) return {
|
|
39
|
+
type: "bun",
|
|
40
|
+
version: process.versions.bun
|
|
41
|
+
};
|
|
42
|
+
if (typeof globalThis !== "undefined" && "window" in globalThis && typeof globalThis.window !== "undefined" && typeof globalThis.window.document !== "undefined" && typeof globalThis.window.navigator !== "undefined") return {
|
|
43
|
+
type: "browser",
|
|
44
|
+
isNextJs: Boolean(globalThis.window.__NEXT_DATA__)
|
|
45
|
+
};
|
|
46
|
+
if (typeof process !== "undefined" && process.versions?.node) {
|
|
47
|
+
const nodeVersion = parseInt(process.versions.node.split(".")[0] ?? "0");
|
|
48
|
+
const nodeVersionMinor = parseInt(process.versions.node.split(".")[1] ?? "0");
|
|
49
|
+
if (nodeVersion < 22) console.warn(`[Observability] Node ${process.versions.node} detected. Node 22+ is required for optimal performance and latest features.`);
|
|
50
|
+
return {
|
|
51
|
+
type: "node",
|
|
52
|
+
version: process.versions.node,
|
|
53
|
+
major: nodeVersion,
|
|
54
|
+
minor: nodeVersionMinor,
|
|
55
|
+
isNode22Plus: nodeVersion >= 22,
|
|
56
|
+
isNextJs: Boolean(process.env.NEXT_RUNTIME) || Boolean(process.env.__NEXT_RUNTIME) || Boolean(process.env.NEXT_PUBLIC_VERCEL_ENV)
|
|
57
|
+
};
|
|
58
|
+
}
|
|
59
|
+
return { type: "unknown" };
|
|
60
|
+
};
|
|
61
|
+
const runtimeInfo = getRuntimeInfo();
|
|
62
|
+
/**
|
|
63
|
+
* Create a generic log function factory.
|
|
64
|
+
*
|
|
65
|
+
* Factory function that creates log functions for different levels (debug, info, warn, error).
|
|
66
|
+
* Logs directly to console with runtime information.
|
|
67
|
+
*/
|
|
68
|
+
const createLogFunction = (level) => {
|
|
69
|
+
return (message, context) => {
|
|
70
|
+
if (message instanceof Error) if (context) console[level](`[${runtimeInfo.type}]`, message, context);
|
|
71
|
+
else console[level](`[${runtimeInfo.type}]`, message);
|
|
72
|
+
else {
|
|
73
|
+
const contextStr = context ? JSON.stringify(context) : "";
|
|
74
|
+
const logMessage = contextStr ? `${message} ${contextStr}` : message;
|
|
75
|
+
console[level](`[${runtimeInfo.type}]`, logMessage);
|
|
76
|
+
}
|
|
77
|
+
};
|
|
78
|
+
};
|
|
79
|
+
/**
|
|
80
|
+
* Log a debug message (isomorphic - works in any environment).
|
|
81
|
+
*/
|
|
82
|
+
const logDebug = createLogFunction("debug");
|
|
83
|
+
/**
|
|
84
|
+
* Log an info message (isomorphic - works in any environment).
|
|
85
|
+
*/
|
|
86
|
+
const logInfo = createLogFunction("info");
|
|
87
|
+
/**
|
|
88
|
+
* Log a warning message (isomorphic - works in any environment).
|
|
89
|
+
*/
|
|
90
|
+
const logWarn = createLogFunction("warn");
|
|
91
|
+
/**
|
|
92
|
+
* Log an error message (isomorphic - works in any environment).
|
|
93
|
+
*/
|
|
94
|
+
const logError = createLogFunction("error");
|
|
95
|
+
|
|
96
|
+
//#endregion
|
|
5
97
|
//#region env.ts
|
|
6
98
|
/**
|
|
7
99
|
* @fileoverview env.ts
|
|
@@ -125,4 +217,4 @@ function getEnvWithDefaults() {
|
|
|
125
217
|
|
|
126
218
|
//#endregion
|
|
127
219
|
export { getEnvWithDefaults as n, safeEnv as r, env as t };
|
|
128
|
-
//# sourceMappingURL=env-
|
|
220
|
+
//# sourceMappingURL=env-BRxsA_k1.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"env-BRxsA_k1.mjs","names":[],"sources":["../../shared/src/logger/core.ts","../env.ts"],"sourcesContent":["/**\n * @fileoverview Canonical logger for the OneApp platform.\n *\n * This module provides isomorphic logging functions that work in any environment\n * (Browser, Node.js, Edge). Logs directly to console with runtime information.\n *\n * Preferred usage is to import from '@od-oneapp/shared/logger'.\n */\n\n/**\n * Get runtime environment information.\n *\n * Detects the current runtime environment (browser, Node.js, edge, Bun) and returns\n * detailed information about the environment type, version, and capabilities.\n *\n * @returns Runtime information object with type, version, and environment-specific details\n *\n * @example\n * ```typescript\n * const runtime = getRuntimeInfo();\n * // Returns: { type: 'node', version: '22.0.0', major: 22, minor: 0, isNode22Plus: true, isNextJs: true }\n * // or: { type: 'browser', isNextJs: true }\n * // or: { type: 'edge', variant: 'vercel' }\n * ```\n */\nexport const getRuntimeInfo = () => {\n // Edge runtime detection (Vercel Edge, Cloudflare Workers)\n if (typeof globalThis !== 'undefined' && (globalThis as any).EdgeRuntime) {\n return { type: 'edge', variant: 'vercel' };\n }\n if (\n typeof globalThis !== 'undefined' &&\n (globalThis as any).caches &&\n typeof (globalThis as any).caches !== 'undefined'\n ) {\n return { type: 'edge', variant: 'cloudflare' };\n }\n\n // Bun detection\n if (typeof process !== 'undefined' && process.versions?.bun) {\n return { type: 'bun', version: process.versions.bun };\n }\n\n // Browser detection (more robust)\n if (\n typeof globalThis !== 'undefined' &&\n 'window' in globalThis &&\n typeof (globalThis as any).window !== 'undefined' &&\n typeof (globalThis as any).window.document !== 'undefined' &&\n typeof (globalThis as any).window.navigator !== 'undefined'\n ) {\n return { type: 'browser', isNextJs: Boolean((globalThis as any).window.__NEXT_DATA__) };\n }\n\n // Node.js detection with version check\n if (typeof process !== 'undefined' && process.versions?.node) {\n const nodeVersion = parseInt(process.versions.node.split('.')[0] ?? '0');\n const nodeVersionMinor = parseInt(process.versions.node.split('.')[1] ?? '0');\n\n if (nodeVersion < 22) {\n // Note: Using console.warn here as observability system may not be initialized yet\n // eslint-disable-next-line no-console\n console.warn(\n `[Observability] Node ${process.versions.node} detected. Node 22+ is required for optimal performance and latest features.`,\n );\n }\n\n return {\n type: 'node',\n version: process.versions.node,\n major: nodeVersion,\n minor: nodeVersionMinor,\n isNode22Plus: nodeVersion >= 22,\n isNextJs:\n Boolean(process.env.NEXT_RUNTIME) ||\n Boolean(process.env.__NEXT_RUNTIME) ||\n Boolean(process.env.NEXT_PUBLIC_VERCEL_ENV),\n };\n }\n\n // Fallback\n return { type: 'unknown' };\n};\n\n// Cache the runtime info\nconst runtimeInfo = getRuntimeInfo();\n\n/**\n * Get cached runtime environment information.\n *\n * Returns the runtime information that was detected at module load time.\n * This is cached to avoid repeated detection checks.\n *\n * @returns Cached runtime information object\n */\nexport const getRuntimeEnvironment = () => runtimeInfo;\n\n/**\n * Detect if code is running in a browser environment\n * Extracted to shared utility to avoid duplication\n * @returns true if running in browser, false otherwise\n */\nexport function isBrowser(): boolean {\n return (\n typeof globalThis !== 'undefined' &&\n 'window' in globalThis &&\n typeof (globalThis as any).window !== 'undefined' &&\n typeof (globalThis as any).window.document !== 'undefined' &&\n typeof (globalThis as any).window.navigator !== 'undefined'\n );\n}\n\n/**\n * Determine if console logging should be enabled based on environment\n * Centralized logic to avoid duplication across entry points\n * @param envNodeEnv - The NEXT_PUBLIC_NODE_ENV value\n * @param consoleEnabled - The NEXT_PUBLIC_OBSERVABILITY_CONSOLE_ENABLED value (explicit control)\n * @param debugEnabled - The NEXT_PUBLIC_OBSERVABILITY_DEBUG value\n * @returns boolean indicating if console should be enabled\n */\nexport function shouldEnableConsole(\n envNodeEnv?: string,\n consoleEnabled?: boolean,\n debugEnabled?: boolean,\n): boolean {\n const isDevelopment = envNodeEnv === 'development' || process.env.NODE_ENV === 'development';\n\n // Priority: explicit control > development mode > debug mode\n if (consoleEnabled !== undefined) {\n return consoleEnabled;\n }\n if (isDevelopment) {\n return true;\n }\n return debugEnabled ?? false;\n}\n\n/**\n * Create a generic log function factory.\n *\n * Factory function that creates log functions for different levels (debug, info, warn, error).\n * Logs directly to console with runtime information.\n */\nconst createLogFunction = (level: 'debug' | 'info' | 'warn' | 'error') => {\n return (message: string | Error, context?: any): void => {\n if (message instanceof Error) {\n // For Error objects, log the error itself (console.error will show stack trace)\n // and include context as additional arguments\n if (context) {\n // eslint-disable-next-line no-console\n (console[level] as any)(`[${runtimeInfo.type}]`, message, context);\n } else {\n // eslint-disable-next-line no-console\n (console[level] as any)(`[${runtimeInfo.type}]`, message);\n }\n } else {\n // For string messages, format with context\n const contextStr = context ? JSON.stringify(context) : '';\n const logMessage = contextStr ? `${message} ${contextStr}` : message;\n // eslint-disable-next-line no-console\n (console[level] as any)(`[${runtimeInfo.type}]`, logMessage);\n }\n };\n};\n\n/**\n * Log a debug message (isomorphic - works in any environment).\n */\nexport const logDebug = createLogFunction('debug');\n\n/**\n * Log an info message (isomorphic - works in any environment).\n */\nexport const logInfo = createLogFunction('info');\n\n/**\n * Log a warning message (isomorphic - works in any environment).\n */\nexport const logWarn = createLogFunction('warn');\n\n/**\n * Log an error message (isomorphic - works in any environment).\n */\nexport const logError = createLogFunction('error');\n","/**\n * @fileoverview env.ts\n */\n\nimport { logWarn } from '@od-oneapp/shared/logger';\nimport { createEnv } from '@t3-oss/env-core';\nimport { z } from 'zod/v4';\n\n/**\n * Helper to parse and validate integer environment variables\n */\nconst parsePositiveInteger = (val: string, fieldName: string): number => {\n const parsed = Number.parseInt(val, 10);\n if (!Number.isFinite(parsed) || !Number.isInteger(parsed) || parsed < 0) {\n throw new Error(`${fieldName} must be a valid positive integer, got: ${val}`);\n }\n return parsed;\n};\n\nexport const env = createEnv({\n server: {\n // Vercel Blob\n VERCEL_BLOB_READ_WRITE_TOKEN: z.string().min(1).optional(),\n // Cloudflare Images\n CLOUDFLARE_IMAGES_ACCOUNT_ID: z.string().min(1).optional(),\n CLOUDFLARE_IMAGES_API_TOKEN: z.string().min(1).optional(),\n CLOUDFLARE_IMAGES_DELIVERY_URL: z.string().url().optional(),\n CLOUDFLARE_IMAGES_SIGNING_KEY: z.string().min(1).optional(),\n // Cloudflare R2 - Legacy single config\n R2_ACCESS_KEY_ID: z.string().min(1).optional(),\n R2_ACCOUNT_ID: z.string().min(1).optional(),\n R2_BUCKET: z.string().min(1).optional(),\n R2_SECRET_ACCESS_KEY: z.string().min(1).optional(),\n // Multi-R2 config as JSON\n R2_CREDENTIALS: z\n .string()\n .transform(val => {\n if (!val) return undefined;\n try {\n return JSON.parse(val);\n } catch {\n return undefined;\n }\n })\n .pipe(\n z\n .array(\n z.object({\n name: z.string().optional(),\n bucket: z.string(),\n accountId: z.string(),\n accessKeyId: z.string(),\n secretAccessKey: z.string(),\n }),\n )\n .optional(),\n )\n .optional(),\n // Full storage config as JSON\n STORAGE_CONFIG: z\n .string()\n .transform(val => {\n if (!val) return undefined;\n try {\n return JSON.parse(val);\n } catch {\n return undefined;\n }\n })\n .optional(),\n STORAGE_LOG_LEVEL: z.enum(['info', 'warn', 'error']).default('error'),\n STORAGE_LOG_PERFORMANCE: z\n .string()\n .default('false')\n .transform((val: string) => val === 'true'),\n STORAGE_LOG_PROVIDER: z.enum(['console', 'sentry', 'pino']).default('console'),\n STORAGE_PROVIDER: z\n .enum(['vercel-blob', 'cloudflare-r2', 'cloudflare-images', 'multi'])\n .optional(),\n // File size limits (bytes)\n STORAGE_MAX_FILE_SIZE: z\n .string()\n .default('104857600') // 100MB default\n .transform((val: string) => parsePositiveInteger(val, 'STORAGE_MAX_FILE_SIZE')),\n STORAGE_MAX_FILES_PER_UPLOAD: z\n .string()\n .default('10')\n .transform((val: string) => parsePositiveInteger(val, 'STORAGE_MAX_FILES_PER_UPLOAD')),\n // Rate limiting\n STORAGE_RATE_LIMIT_REQUESTS: z\n .string()\n .default('100')\n .transform((val: string) => parsePositiveInteger(val, 'STORAGE_RATE_LIMIT_REQUESTS')),\n STORAGE_RATE_LIMIT_WINDOW_MS: z\n .string()\n .default('60000') // 1 minute\n .transform((val: string) => parsePositiveInteger(val, 'STORAGE_RATE_LIMIT_WINDOW_MS')),\n // Security feature flags (secure-by-default for production)\n STORAGE_ENFORCE_AUTH: z\n .string()\n .default('true')\n .transform((val: string) => val === 'true'),\n STORAGE_ENABLE_RATE_LIMIT: z\n .string()\n .default('true')\n .transform((val: string) => val === 'true'),\n STORAGE_ENFORCE_CSRF: z\n .string()\n .default('true')\n .transform((val: string) => val === 'true'),\n },\n runtimeEnv: process.env,\n emptyStringAsUndefined: true,\n onValidationError: error => {\n const message = Array.isArray(error) ? error.map(e => e.message).join(', ') : String(error);\n logWarn('Storage environment validation failed:', { message });\n // Don't throw in packages - use fallbacks for resilience\n return undefined as never;\n },\n});\n\n/**\n * Provide a storage environment configuration with safe defaults.\n *\n * Returns the validated `env` from createEnv. The fallback code below exists\n * for edge cases where env validation might fail silently, but in practice\n * createEnv always returns a truthy object (even with undefined values).\n *\n * @returns The validated environment configuration\n */\nexport function safeEnv(): typeof env {\n // env from createEnv is always truthy, this is the primary return path\n return env;\n}\n\n/**\n * Get environment with fallback defaults for resilience.\n * Use this when you need guaranteed values even if env validation failed.\n *\n * @returns Environment configuration with fallback defaults applied\n */\nexport function getEnvWithDefaults() {\n return {\n VERCEL_BLOB_READ_WRITE_TOKEN: process.env.VERCEL_BLOB_READ_WRITE_TOKEN ?? '',\n CLOUDFLARE_IMAGES_ACCOUNT_ID: process.env.CLOUDFLARE_IMAGES_ACCOUNT_ID ?? '',\n CLOUDFLARE_IMAGES_API_TOKEN: process.env.CLOUDFLARE_IMAGES_API_TOKEN ?? '',\n CLOUDFLARE_IMAGES_DELIVERY_URL: process.env.CLOUDFLARE_IMAGES_DELIVERY_URL ?? '',\n CLOUDFLARE_IMAGES_SIGNING_KEY: process.env.CLOUDFLARE_IMAGES_SIGNING_KEY ?? '',\n R2_ACCESS_KEY_ID: process.env.R2_ACCESS_KEY_ID ?? '',\n R2_ACCOUNT_ID: process.env.R2_ACCOUNT_ID ?? '',\n R2_BUCKET: process.env.R2_BUCKET ?? '',\n R2_SECRET_ACCESS_KEY: process.env.R2_SECRET_ACCESS_KEY ?? '',\n R2_CREDENTIALS: process.env.R2_CREDENTIALS ?? '',\n STORAGE_CONFIG: process.env.STORAGE_CONFIG ?? '',\n STORAGE_LOG_LEVEL: process.env.STORAGE_LOG_LEVEL ?? 'error',\n STORAGE_LOG_PERFORMANCE: process.env.STORAGE_LOG_PERFORMANCE === 'true',\n STORAGE_LOG_PROVIDER: process.env.STORAGE_LOG_PROVIDER ?? 'console',\n STORAGE_PROVIDER: process.env.STORAGE_PROVIDER ?? '',\n STORAGE_MAX_FILE_SIZE: parsePositiveInteger(\n process.env.STORAGE_MAX_FILE_SIZE ?? '104857600',\n 'STORAGE_MAX_FILE_SIZE',\n ),\n STORAGE_MAX_FILES_PER_UPLOAD: parsePositiveInteger(\n process.env.STORAGE_MAX_FILES_PER_UPLOAD ?? '10',\n 'STORAGE_MAX_FILES_PER_UPLOAD',\n ),\n STORAGE_RATE_LIMIT_REQUESTS: parsePositiveInteger(\n process.env.STORAGE_RATE_LIMIT_REQUESTS ?? '100',\n 'STORAGE_RATE_LIMIT_REQUESTS',\n ),\n STORAGE_RATE_LIMIT_WINDOW_MS: parsePositiveInteger(\n process.env.STORAGE_RATE_LIMIT_WINDOW_MS ?? '60000',\n 'STORAGE_RATE_LIMIT_WINDOW_MS',\n ),\n STORAGE_ENFORCE_AUTH: process.env.STORAGE_ENFORCE_AUTH !== 'false',\n STORAGE_ENABLE_RATE_LIMIT: process.env.STORAGE_ENABLE_RATE_LIMIT !== 'false',\n STORAGE_ENFORCE_CSRF: process.env.STORAGE_ENFORCE_CSRF !== 'false',\n };\n}\n\n// Export type for better DX\nexport type Env = typeof env;\n"],"mappings":"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"}
|
package/env.mjs
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { ListOptions, MultiStorageConfig, MultipartUploadOptions, MultipartUploadResult as MultipartUploadResult$1, StorageCapabilities, StorageObject, StorageProvider, UploadOptions } from "./types.mjs";
|
|
1
|
+
import { ListOptions, MultiStorageConfig, MultipartUploadOptions, MultipartUploadResult as MultipartUploadResult$1, PresignedUploadUrl, StorageCapabilities, StorageObject, StorageProvider, UploadOptions } from "./types.mjs";
|
|
2
2
|
|
|
3
3
|
//#region providers/cloudflare-images.d.ts
|
|
4
4
|
declare const CloudflareImagesProvider: new (...args: unknown[]) => StorageProvider;
|
|
@@ -34,6 +34,33 @@ declare class MultiStorageManager {
|
|
|
34
34
|
//#region providers/cloudflare-r2.d.ts
|
|
35
35
|
declare const CloudflareR2Provider: new (...args: unknown[]) => StorageProvider;
|
|
36
36
|
//#endregion
|
|
37
|
+
//#region providers/vercel-blob.d.ts
|
|
38
|
+
declare class VercelBlobProvider implements StorageProvider {
|
|
39
|
+
private token;
|
|
40
|
+
constructor(token: string);
|
|
41
|
+
delete(key: string): Promise<void>;
|
|
42
|
+
download(key: string): Promise<Blob>;
|
|
43
|
+
exists(key: string): Promise<boolean>;
|
|
44
|
+
getMetadata(key: string): Promise<StorageObject>;
|
|
45
|
+
getUrl(key: string, _options?: {
|
|
46
|
+
expiresIn?: number;
|
|
47
|
+
}): Promise<string>;
|
|
48
|
+
list(options?: ListOptions): Promise<StorageObject[]>;
|
|
49
|
+
upload(key: string, data: ArrayBuffer | Blob | Buffer | File | ReadableStream, options?: UploadOptions): Promise<StorageObject>;
|
|
50
|
+
createMultipartUpload(key: string, _options?: UploadOptions): Promise<{
|
|
51
|
+
uploadId: string;
|
|
52
|
+
key: string;
|
|
53
|
+
}>;
|
|
54
|
+
uploadPart(): Promise<{
|
|
55
|
+
etag: string;
|
|
56
|
+
partNumber: number;
|
|
57
|
+
}>;
|
|
58
|
+
completeMultipartUpload(): Promise<StorageObject>;
|
|
59
|
+
abortMultipartUpload(): Promise<void>;
|
|
60
|
+
getPresignedUploadUrl(): Promise<PresignedUploadUrl>;
|
|
61
|
+
getCapabilities(): StorageCapabilities;
|
|
62
|
+
}
|
|
63
|
+
//#endregion
|
|
37
64
|
//#region src/multipart.d.ts
|
|
38
65
|
interface MultipartUploadState {
|
|
39
66
|
uploadId: string;
|
|
@@ -112,5 +139,5 @@ interface HealthCheckResult {
|
|
|
112
139
|
declare function checkProviderHealth(provider: StorageProvider): Promise<HealthCheckResult>;
|
|
113
140
|
declare function storageHealthCheck(provider: StorageProvider): Promise<HealthCheckResult>;
|
|
114
141
|
//#endregion
|
|
115
|
-
export { getOptimalPartSize as _, describeProviderCapabilities as a,
|
|
116
|
-
//# sourceMappingURL=health-check-
|
|
142
|
+
export { CloudflareImagesProvider as S, getOptimalPartSize as _, describeProviderCapabilities as a, CloudflareR2Provider as b, getProviderCapabilities as c, hasCapability as d, validateProviderCapabilities as f, createMultipartUploadManager as g, MultipartUploadState as h, checkProviderSuitability as i, hasAllCapabilities as l, MultipartUploadResult as m, checkProviderHealth as n, getBestProvider as o, MultipartUploadManager as p, storageHealthCheck as r, getCapabilityMatrix as s, HealthCheckResult as t, hasAnyCapability as u, hasMultipartSupport as v, MultiStorageManager as x, VercelBlobProvider as y };
|
|
143
|
+
//# sourceMappingURL=health-check-Cxg9x7Cb.d.mts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"health-check-Cxg9x7Cb.d.mts","names":[],"sources":["../providers/cloudflare-images.ts","../src/multi-storage.ts","../providers/cloudflare-r2.ts","../providers/vercel-blob.ts","../src/multipart.ts","../src/capabilities.ts","../src/health-check.ts"],"mappings":"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"}
|