@hybrd/utils 1.0.10 → 1.1.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.
Files changed (42) hide show
  1. package/.cache/tsbuildinfo.json +1 -1
  2. package/.turbo/turbo-build.log +20 -2
  3. package/dist/index.cjs +261 -0
  4. package/dist/index.cjs.map +1 -0
  5. package/dist/index.d.cts +152 -0
  6. package/dist/index.d.ts +152 -10
  7. package/dist/index.js +208 -9
  8. package/dist/index.js.map +1 -0
  9. package/package.json +7 -5
  10. package/tsconfig.json +8 -4
  11. package/tsup.config.ts +14 -0
  12. package/.turbo/turbo-lint$colon$fix.log +0 -6
  13. package/.turbo/turbo-lint.log +0 -6
  14. package/.turbo/turbo-typecheck.log +0 -5
  15. package/dist/index.d.ts.map +0 -1
  16. package/dist/lib/array.d.ts +0 -25
  17. package/dist/lib/array.d.ts.map +0 -1
  18. package/dist/lib/array.js +0 -32
  19. package/dist/lib/cloudflare.d.ts +0 -22
  20. package/dist/lib/cloudflare.d.ts.map +0 -1
  21. package/dist/lib/cloudflare.js +0 -53
  22. package/dist/lib/date.d.ts +0 -17
  23. package/dist/lib/date.d.ts.map +0 -1
  24. package/dist/lib/date.js +0 -37
  25. package/dist/lib/markdown.d.ts +0 -7
  26. package/dist/lib/markdown.d.ts.map +0 -1
  27. package/dist/lib/markdown.js +0 -11
  28. package/dist/lib/object.d.ts +0 -15
  29. package/dist/lib/object.d.ts.map +0 -1
  30. package/dist/lib/object.js +0 -42
  31. package/dist/lib/storage.d.ts +0 -24
  32. package/dist/lib/storage.d.ts.map +0 -1
  33. package/dist/lib/storage.js +0 -50
  34. package/dist/lib/string.d.ts +0 -11
  35. package/dist/lib/string.d.ts.map +0 -1
  36. package/dist/lib/string.js +0 -12
  37. package/dist/lib/urls.d.ts +0 -28
  38. package/dist/lib/urls.d.ts.map +0 -1
  39. package/dist/lib/urls.js +0 -36
  40. package/dist/lib/uuid.d.ts +0 -2
  41. package/dist/lib/uuid.d.ts.map +0 -1
  42. package/dist/lib/uuid.js +0 -6
@@ -1,5 +1,23 @@
1
1
 
2
2
  
3
- > @hybrd/utils@1.0.10 build /Users/ian/Projects/01/hybrid/packages/utils
4
- > tsc
3
+ > @hybrd/utils@1.1.1 build /Users/ian/Projects/01/hybrid/packages/utils
4
+ > tsup
5
5
 
6
+ CLI Building entry: {"index":"src/index.ts"}
7
+ CLI Using tsconfig: tsconfig.json
8
+ CLI tsup v8.5.0
9
+ CLI Using tsup config: /Users/ian/Projects/01/hybrid/packages/utils/tsup.config.ts
10
+ CLI Target: es2020
11
+ CLI Cleaning output folder
12
+ CJS Build start
13
+ ESM Build start
14
+ ESM dist/index.js 5.11 KB
15
+ ESM dist/index.js.map 13.61 KB
16
+ ESM ⚡️ Build success in 19ms
17
+ CJS dist/index.cjs 7.59 KB
18
+ CJS dist/index.cjs.map 14.07 KB
19
+ CJS ⚡️ Build success in 19ms
20
+ DTS Build start
21
+ DTS ⚡️ Build success in 924ms
22
+ DTS dist/index.d.cts 5.76 KB
23
+ DTS dist/index.d.ts 5.76 KB
package/dist/index.cjs ADDED
@@ -0,0 +1,261 @@
1
+ "use strict";
2
+ var __create = Object.create;
3
+ var __defProp = Object.defineProperty;
4
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
5
+ var __getOwnPropNames = Object.getOwnPropertyNames;
6
+ var __getProtoOf = Object.getPrototypeOf;
7
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
8
+ var __export = (target, all) => {
9
+ for (var name in all)
10
+ __defProp(target, name, { get: all[name], enumerable: true });
11
+ };
12
+ var __copyProps = (to, from, except, desc) => {
13
+ if (from && typeof from === "object" || typeof from === "function") {
14
+ for (let key of __getOwnPropNames(from))
15
+ if (!__hasOwnProp.call(to, key) && key !== except)
16
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
17
+ }
18
+ return to;
19
+ };
20
+ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
21
+ // If the importer is in node compatibility mode or this is not an ESM
22
+ // file that has been converted to a CommonJS file using a Babel-
23
+ // compatible transform (i.e. "__esModule" has not been set), then set
24
+ // "default" to the CommonJS "module.exports" for node compatibility.
25
+ isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
26
+ mod
27
+ ));
28
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
29
+
30
+ // src/index.ts
31
+ var src_exports = {};
32
+ __export(src_exports, {
33
+ ExternalDatabaseAdapter: () => ExternalDatabaseAdapter,
34
+ R2StorageAdapter: () => R2StorageAdapter,
35
+ chunk: () => chunk,
36
+ createStorageAdapter: () => createStorageAdapter,
37
+ formatDate: () => formatDate,
38
+ formatRelativeDate: () => formatRelativeDate,
39
+ getCloudflareEnvironment: () => getCloudflareEnvironment,
40
+ getCloudflareServiceUrl: () => getCloudflareServiceUrl,
41
+ getCloudflareStoragePath: () => getCloudflareStoragePath,
42
+ getUrl: () => getUrl,
43
+ pruneEmpty: () => pruneEmpty,
44
+ randomUUID: () => randomUUID,
45
+ shuffle: () => shuffle,
46
+ stringifyValues: () => stringifyValues,
47
+ stripMarkdown: () => stripMarkdown,
48
+ truncate: () => truncate,
49
+ uniq: () => uniq
50
+ });
51
+ module.exports = __toCommonJS(src_exports);
52
+
53
+ // src/lib/array.ts
54
+ function chunk(arr, size) {
55
+ return Array.from(
56
+ { length: Math.ceil(arr.length / size) },
57
+ (_, i) => arr.slice(i * size, i * size + size)
58
+ );
59
+ }
60
+ function uniq(array) {
61
+ return array.filter((item, index, self) => self.indexOf(item) === index);
62
+ }
63
+ function shuffle(array) {
64
+ if (!array) return [];
65
+ return array.sort(() => Math.random() - 0.5);
66
+ }
67
+
68
+ // src/lib/cloudflare.ts
69
+ function getCloudflareEnvironment() {
70
+ if (process.env.CF_PAGES_BRANCH) {
71
+ return {
72
+ isCloudflare: true,
73
+ platform: "pages",
74
+ storagePath: "/tmp"
75
+ };
76
+ }
77
+ if (process.env.CF_WORKER_NAME) {
78
+ return {
79
+ isCloudflare: true,
80
+ platform: "workers",
81
+ storagePath: "/tmp"
82
+ };
83
+ }
84
+ return {
85
+ isCloudflare: false,
86
+ platform: "local",
87
+ storagePath: process.env.PROJECT_ROOT || process.cwd()
88
+ };
89
+ }
90
+ function getCloudflareStoragePath(subPath) {
91
+ const env = getCloudflareEnvironment();
92
+ if (env.isCloudflare) {
93
+ return subPath ? `/tmp/${subPath}` : "/tmp";
94
+ }
95
+ const basePath = env.storagePath;
96
+ const dataPath = subPath ? `${basePath}/.data/${subPath}` : `${basePath}/.data`;
97
+ return dataPath;
98
+ }
99
+ function getCloudflareServiceUrl(fallbackPort = 3e3) {
100
+ if (process.env.CF_PAGES_URL) {
101
+ return process.env.CF_PAGES_URL;
102
+ }
103
+ if (process.env.CF_WORKER_URL) {
104
+ return process.env.CF_WORKER_URL;
105
+ }
106
+ return `http://localhost:${fallbackPort}`;
107
+ }
108
+
109
+ // src/lib/storage.ts
110
+ var import_promises = __toESM(require("fs/promises"), 1);
111
+ var R2StorageAdapter = class {
112
+ constructor(bucket) {
113
+ this.bucket = bucket;
114
+ }
115
+ async uploadFile(localPath, remotePath) {
116
+ const fileData = await import_promises.default.readFile(localPath);
117
+ await this.bucket.put(remotePath, fileData);
118
+ }
119
+ async downloadFile(remotePath, localPath) {
120
+ const object = await this.bucket.get(remotePath);
121
+ if (object) {
122
+ await import_promises.default.writeFile(localPath, await object.arrayBuffer());
123
+ }
124
+ }
125
+ async exists(remotePath) {
126
+ const object = await this.bucket.head(remotePath);
127
+ return object !== null;
128
+ }
129
+ async delete(remotePath) {
130
+ await this.bucket.delete(remotePath);
131
+ }
132
+ };
133
+ var ExternalDatabaseAdapter = class {
134
+ constructor(connectionString) {
135
+ this.connectionString = connectionString;
136
+ }
137
+ async uploadFile(localPath, remotePath) {
138
+ throw new Error("External database storage not yet implemented");
139
+ }
140
+ async downloadFile(remotePath, localPath) {
141
+ throw new Error("External database storage not yet implemented");
142
+ }
143
+ async exists(remotePath) {
144
+ return false;
145
+ }
146
+ async delete(remotePath) {
147
+ }
148
+ };
149
+ function createStorageAdapter() {
150
+ if (typeof globalThis !== "undefined" && "XMTP_STORAGE" in globalThis) {
151
+ return new R2StorageAdapter(globalThis.XMTP_STORAGE);
152
+ }
153
+ if (typeof process !== "undefined" && process.env?.DATABASE_URL) {
154
+ return new ExternalDatabaseAdapter(process.env.DATABASE_URL);
155
+ }
156
+ return null;
157
+ }
158
+
159
+ // src/lib/date.ts
160
+ var import_date_fns = require("date-fns");
161
+ function formatDate(stringOrDate) {
162
+ if (!stringOrDate) return "";
163
+ const date = new Date(stringOrDate);
164
+ return date.toLocaleDateString(void 0, {
165
+ year: "numeric",
166
+ month: "short",
167
+ day: "numeric"
168
+ });
169
+ }
170
+ function formatRelativeDate(date) {
171
+ if ((0, import_date_fns.isToday)(date)) {
172
+ return `Today, ${(0, import_date_fns.format)(date, "h:mm a")}`;
173
+ }
174
+ if ((0, import_date_fns.isYesterday)(date)) {
175
+ return `Yesterday, ${(0, import_date_fns.format)(date, "h:mm a")}`;
176
+ }
177
+ if ((/* @__PURE__ */ new Date()).getFullYear() === date.getFullYear()) {
178
+ return (0, import_date_fns.format)(date, "MMM d, h:mm a");
179
+ }
180
+ return (0, import_date_fns.format)(date, "MMM d, yyyy");
181
+ }
182
+
183
+ // src/lib/object.ts
184
+ function stringifyValues(obj) {
185
+ const result = {};
186
+ if (!obj) {
187
+ return {};
188
+ }
189
+ for (const key in obj) {
190
+ const value = obj[key];
191
+ result[key] = value === null ? "null" : typeof value === "object" ? JSON.stringify(value) : String(value);
192
+ }
193
+ return result;
194
+ }
195
+ function pruneEmpty(obj) {
196
+ if (!obj) {
197
+ return {};
198
+ }
199
+ return Object.entries(obj).reduce(
200
+ (acc, [key, value]) => {
201
+ if (value === void 0 || value === null || value === "") {
202
+ return acc;
203
+ }
204
+ acc[key] = value;
205
+ return acc;
206
+ },
207
+ {}
208
+ );
209
+ }
210
+
211
+ // src/lib/markdown.ts
212
+ var import_remark = require("remark");
213
+ var import_strip_markdown = __toESM(require("strip-markdown"), 1);
214
+ async function stripMarkdown(markdown) {
215
+ const file = await (0, import_remark.remark)().use(import_strip_markdown.default).process(markdown);
216
+ return String(file);
217
+ }
218
+
219
+ // src/lib/string.ts
220
+ function truncate(str, length) {
221
+ return str.length > length ? `${str.slice(0, length)}...` : str;
222
+ }
223
+
224
+ // src/lib/urls.ts
225
+ function getUrl(path = "") {
226
+ const trimmedPath = path.replace(/^\/+/, "");
227
+ if (process.env.AGENT_URL) {
228
+ return `https://${process.env.AGENT_URL}/${trimmedPath}`;
229
+ }
230
+ if (process.env.RAILWAY_PUBLIC_DOMAIN) {
231
+ return `https://${process.env.RAILWAY_PUBLIC_DOMAIN}/${trimmedPath}`;
232
+ }
233
+ return `https://localhost:8454/${trimmedPath}`;
234
+ }
235
+
236
+ // src/lib/uuid.ts
237
+ var import_uuid = require("uuid");
238
+ function randomUUID() {
239
+ return (0, import_uuid.v4)();
240
+ }
241
+ // Annotate the CommonJS export names for ESM import in node:
242
+ 0 && (module.exports = {
243
+ ExternalDatabaseAdapter,
244
+ R2StorageAdapter,
245
+ chunk,
246
+ createStorageAdapter,
247
+ formatDate,
248
+ formatRelativeDate,
249
+ getCloudflareEnvironment,
250
+ getCloudflareServiceUrl,
251
+ getCloudflareStoragePath,
252
+ getUrl,
253
+ pruneEmpty,
254
+ randomUUID,
255
+ shuffle,
256
+ stringifyValues,
257
+ stripMarkdown,
258
+ truncate,
259
+ uniq
260
+ });
261
+ //# sourceMappingURL=index.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/index.ts","../src/lib/array.ts","../src/lib/cloudflare.ts","../src/lib/storage.ts","../src/lib/date.ts","../src/lib/object.ts","../src/lib/markdown.ts","../src/lib/string.ts","../src/lib/urls.ts","../src/lib/uuid.ts"],"sourcesContent":["export * from \"./lib/array\"\nexport * from \"./lib/cloudflare\"\nexport * from \"./lib/storage\"\nexport * from \"./lib/date\"\nexport * from \"./lib/object\"\nexport * from \"./lib/markdown\"\nexport * from \"./lib/string\"\nexport * from \"./lib/urls\"\nexport * from \"./lib/uuid\"\n","/**\n * Splits an array into chunks of specified size.\n *\n * @template T - The type of the array elements.\n * @param {T[]} arr - The array to split into chunks.\n * @param {number} size - The maximum number of elements per chunk.\n * @returns {T[][]} An array of chunks, where each chunk is an array of T.\n */\nexport function chunk<T>(arr: T[], size: number): T[][] {\n\treturn Array.from({ length: Math.ceil(arr.length / size) }, (_, i) =>\n\t\tarr.slice(i * size, i * size + size)\n\t)\n}\n\n/**\n * Returns a new array with only unique elements from the input array.\n *\n * @template T - The type of the array elements.\n * @param {T[]} array - The array from which to remove duplicate elements.\n * @returns {T[]} A new array containing only unique elements.\n */\nexport function uniq<T>(array: T[]): T[] {\n\treturn array.filter((item, index, self) => self.indexOf(item) === index)\n}\n\n/**\n * Randomly shuffles the elements of an array.\n *\n * @param {any[] | undefined} array - The array to shuffle. If undefined, returns an empty array.\n * @returns {any[]} A shuffled copy of the input array.\n */\nexport function shuffle(array: any[] | undefined) {\n\tif (!array) return []\n\treturn array.sort(() => Math.random() - 0.5)\n}\n","/**\n * Cloudflare environment detection and storage utilities\n */\n\ndeclare const process: {\n env: Record<string, string | undefined>\n cwd(): string\n}\n\nexport interface CloudflareEnvironment {\n isCloudflare: boolean\n platform: 'pages' | 'workers' | 'local'\n storagePath: string\n}\n\n/**\n * Detects if running in Cloudflare environment and returns appropriate storage configuration\n */\nexport function getCloudflareEnvironment(): CloudflareEnvironment {\n if (process.env.CF_PAGES_BRANCH) {\n return {\n isCloudflare: true,\n platform: 'pages',\n storagePath: '/tmp'\n }\n }\n\n if (process.env.CF_WORKER_NAME) {\n return {\n isCloudflare: true,\n platform: 'workers',\n storagePath: '/tmp'\n }\n }\n\n return {\n isCloudflare: false,\n platform: 'local',\n storagePath: process.env.PROJECT_ROOT || process.cwd()\n }\n}\n\n/**\n * Gets the appropriate storage path for the current environment\n * @param subPath - Optional subdirectory within the storage path\n */\nexport function getCloudflareStoragePath(subPath?: string): string {\n const env = getCloudflareEnvironment()\n \n if (env.isCloudflare) {\n return subPath ? `/tmp/${subPath}` : '/tmp'\n }\n\n const basePath = env.storagePath\n const dataPath = subPath ? `${basePath}/.data/${subPath}` : `${basePath}/.data`\n \n return dataPath\n}\n\n/**\n * Gets service URL based on Cloudflare environment variables\n */\nexport function getCloudflareServiceUrl(fallbackPort = 3000): string {\n if (process.env.CF_PAGES_URL) {\n return process.env.CF_PAGES_URL\n }\n\n if (process.env.CF_WORKER_URL) {\n return process.env.CF_WORKER_URL\n }\n\n // Local development fallback\n return `http://localhost:${fallbackPort}`\n}\n","import fs from \"node:fs/promises\"\n\nexport interface StorageAdapter {\n uploadFile(localPath: string, remotePath: string): Promise<void>\n downloadFile(remotePath: string, localPath: string): Promise<void>\n exists(remotePath: string): Promise<boolean>\n delete(remotePath: string): Promise<void>\n}\n\nexport class R2StorageAdapter implements StorageAdapter {\n constructor(private bucket: any) {}\n \n async uploadFile(localPath: string, remotePath: string): Promise<void> {\n const fileData = await fs.readFile(localPath)\n await this.bucket.put(remotePath, fileData)\n }\n \n async downloadFile(remotePath: string, localPath: string): Promise<void> {\n const object = await this.bucket.get(remotePath)\n if (object) {\n await fs.writeFile(localPath, await object.arrayBuffer())\n }\n }\n \n async exists(remotePath: string): Promise<boolean> {\n const object = await this.bucket.head(remotePath)\n return object !== null\n }\n \n async delete(remotePath: string): Promise<void> {\n await this.bucket.delete(remotePath)\n }\n}\n\nexport class ExternalDatabaseAdapter implements StorageAdapter {\n constructor(private connectionString: string) {}\n \n async uploadFile(localPath: string, remotePath: string): Promise<void> {\n throw new Error('External database storage not yet implemented')\n }\n \n async downloadFile(remotePath: string, localPath: string): Promise<void> {\n throw new Error('External database storage not yet implemented')\n }\n \n async exists(remotePath: string): Promise<boolean> {\n return false\n }\n \n async delete(remotePath: string): Promise<void> {\n }\n}\n\nexport function createStorageAdapter(): StorageAdapter | null {\n if (typeof globalThis !== 'undefined' && 'XMTP_STORAGE' in globalThis) {\n return new R2StorageAdapter((globalThis as any).XMTP_STORAGE)\n }\n \n if (typeof process !== 'undefined' && process.env?.DATABASE_URL) {\n return new ExternalDatabaseAdapter(process.env.DATABASE_URL)\n }\n \n return null\n}\n","import { format, isToday, isYesterday } from \"date-fns\";\n\n/**\n * Formats a date string or Date object into a localized date string\n * @param stringOrDate - Date string or Date object to format\n * @returns Formatted date string (e.g., \"Jan 1, 2024\") or empty string if no input\n */\nexport function formatDate(stringOrDate?: string | Date): string {\n\tif (!stringOrDate) return \"\";\n\n\tconst date = new Date(stringOrDate);\n\n\treturn date.toLocaleDateString(undefined, {\n\t\tyear: \"numeric\",\n\t\tmonth: \"short\",\n\t\tday: \"numeric\",\n\t});\n}\n\n/**\n * Formats a date relative to the current time\n * @param date - Date object to format\n * @returns Formatted string with relative time:\n * - \"Today, [time]\" for today's dates\n * - \"Yesterday, [time]\" for yesterday's dates\n * - \"MMM d, h:mm a\" for dates in current year\n * - \"MMM d, yyyy\" for dates in other years\n */\nexport function formatRelativeDate(date: Date) {\n\tif (isToday(date)) {\n\t\treturn `Today, ${format(date, \"h:mm a\")}`;\n\t}\n\tif (isYesterday(date)) {\n\t\treturn `Yesterday, ${format(date, \"h:mm a\")}`;\n\t}\n\tif (new Date().getFullYear() === date.getFullYear()) {\n\t\treturn format(date, \"MMM d, h:mm a\");\n\t}\n\treturn format(date, \"MMM d, yyyy\");\n}\n","/**\n * Stringifies all values in an object, including objects and null values.\n * If obj is undefined, returns an empty object.\n * @param obj - The object to stringify\n * @returns A new object with the same keys as obj, but with all values stringified\n */\nexport function stringifyValues(\n\tobj: Record<string, unknown> | undefined\n): Record<string, string> {\n\tconst result: Record<string, string> = {}\n\n\tif (!obj) {\n\t\treturn {}\n\t}\n\n\tfor (const key in obj) {\n\t\tconst value = obj[key]\n\t\tresult[key] =\n\t\t\tvalue === null\n\t\t\t\t? \"null\"\n\t\t\t\t: typeof value === \"object\"\n\t\t\t\t\t? JSON.stringify(value)\n\t\t\t\t\t: String(value)\n\t}\n\n\treturn result\n}\n\n/**\n * Removes empty values (undefined, null, empty strings) from an object\n *\n * @param obj - The object to prune\n * @returns A new object with empty values removed\n */\nexport function pruneEmpty<T extends Record<string, unknown>>(\n\tobj: T | undefined\n): Partial<T> {\n\tif (!obj) {\n\t\treturn {}\n\t}\n\n\treturn Object.entries(obj).reduce(\n\t\t(acc, [key, value]) => {\n\t\t\t// Skip undefined, null, and empty strings\n\t\t\tif (value === undefined || value === null || value === \"\") {\n\t\t\t\treturn acc\n\t\t\t}\n\t\t\t// Avoid spread syntax on accumulator\n\t\t\tacc[key as keyof T] = value as any\n\t\t\treturn acc\n\t\t},\n\t\t{} as Partial<T>\n\t)\n}\n","import { remark } from \"remark\"\nimport strip from \"strip-markdown\"\n\n/**\n * Strips markdown from a string\n * @param markdown - The markdown string to strip\n * @returns The stripped markdown string\n */\nexport async function stripMarkdown(markdown: string) {\n\tconst file = await remark().use(strip).process(markdown)\n\treturn String(file)\n}\n","/**\n * Truncates a given string to a specified length, adding an ellipsis if the\n * string is longer than the specified length.\n *\n * @param {string} str - The string to truncate.\n * @param {number} length - The maximum length of the resulting string.\n *\n * @returns {string} The truncated string.\n */\nexport function truncate(str: string, length: number) {\n\treturn str.length > length ? `${str.slice(0, length)}...` : str\n}\n","/**\n * Get the agent application URL for webhooks and callbacks\n *\n * This function constructs the URL for the main agent application, used primarily\n * for QStash webhooks and external callbacks. It supports multiple deployment\n * environments with fallback logic.\n *\n * @param path - Optional path to append to the base URL (leading slashes are normalized)\n * @returns The complete URL for the agent application\n *\n * @example\n * ```typescript\n * // Get base URL\n * getUrl() // \"http://localhost:8454/\"\n *\n * // Get URL with path\n * getUrl(\"/qstash/webhook\") // \"http://localhost:8454/qstash/webhook\"\n * getUrl(\"api/health\") // \"http://localhost:8454/api/health\"\n * ```\n *\n * @remarks\n * URL resolution priority:\n * 1. `AGENT_URL` environment variable (custom deployment)\n * 2. `RAILWAY_PUBLIC_DOMAIN` environment variable (Railway deployment)\n * 3. `http://localhost:8454/` (default)\n */\nexport function getUrl(path = \"\") {\n\tconst trimmedPath = path.replace(/^\\/+/, \"\")\n\n\tif (process.env.AGENT_URL) {\n\t\treturn `https://${process.env.AGENT_URL}/${trimmedPath}`\n\t}\n\n\tif (process.env.RAILWAY_PUBLIC_DOMAIN) {\n\t\treturn `https://${process.env.RAILWAY_PUBLIC_DOMAIN}/${trimmedPath}`\n\t}\n\n\treturn `https://localhost:8454/${trimmedPath}`\n}\n","import { v4 as uuidv4 } from \"uuid\";\n\n// The node:crypto version is not supported in the browser.\n// Use the uuid package instead.\nexport function randomUUID(): string {\n\treturn uuidv4();\n}\n"],"mappings":"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","names":["fs","strip","uuidv4"]}
@@ -0,0 +1,152 @@
1
+ /**
2
+ * Splits an array into chunks of specified size.
3
+ *
4
+ * @template T - The type of the array elements.
5
+ * @param {T[]} arr - The array to split into chunks.
6
+ * @param {number} size - The maximum number of elements per chunk.
7
+ * @returns {T[][]} An array of chunks, where each chunk is an array of T.
8
+ */
9
+ declare function chunk<T>(arr: T[], size: number): T[][];
10
+ /**
11
+ * Returns a new array with only unique elements from the input array.
12
+ *
13
+ * @template T - The type of the array elements.
14
+ * @param {T[]} array - The array from which to remove duplicate elements.
15
+ * @returns {T[]} A new array containing only unique elements.
16
+ */
17
+ declare function uniq<T>(array: T[]): T[];
18
+ /**
19
+ * Randomly shuffles the elements of an array.
20
+ *
21
+ * @param {any[] | undefined} array - The array to shuffle. If undefined, returns an empty array.
22
+ * @returns {any[]} A shuffled copy of the input array.
23
+ */
24
+ declare function shuffle(array: any[] | undefined): any[];
25
+
26
+ /**
27
+ * Cloudflare environment detection and storage utilities
28
+ */
29
+ interface CloudflareEnvironment {
30
+ isCloudflare: boolean;
31
+ platform: 'pages' | 'workers' | 'local';
32
+ storagePath: string;
33
+ }
34
+ /**
35
+ * Detects if running in Cloudflare environment and returns appropriate storage configuration
36
+ */
37
+ declare function getCloudflareEnvironment(): CloudflareEnvironment;
38
+ /**
39
+ * Gets the appropriate storage path for the current environment
40
+ * @param subPath - Optional subdirectory within the storage path
41
+ */
42
+ declare function getCloudflareStoragePath(subPath?: string): string;
43
+ /**
44
+ * Gets service URL based on Cloudflare environment variables
45
+ */
46
+ declare function getCloudflareServiceUrl(fallbackPort?: number): string;
47
+
48
+ interface StorageAdapter {
49
+ uploadFile(localPath: string, remotePath: string): Promise<void>;
50
+ downloadFile(remotePath: string, localPath: string): Promise<void>;
51
+ exists(remotePath: string): Promise<boolean>;
52
+ delete(remotePath: string): Promise<void>;
53
+ }
54
+ declare class R2StorageAdapter implements StorageAdapter {
55
+ private bucket;
56
+ constructor(bucket: any);
57
+ uploadFile(localPath: string, remotePath: string): Promise<void>;
58
+ downloadFile(remotePath: string, localPath: string): Promise<void>;
59
+ exists(remotePath: string): Promise<boolean>;
60
+ delete(remotePath: string): Promise<void>;
61
+ }
62
+ declare class ExternalDatabaseAdapter implements StorageAdapter {
63
+ private connectionString;
64
+ constructor(connectionString: string);
65
+ uploadFile(localPath: string, remotePath: string): Promise<void>;
66
+ downloadFile(remotePath: string, localPath: string): Promise<void>;
67
+ exists(remotePath: string): Promise<boolean>;
68
+ delete(remotePath: string): Promise<void>;
69
+ }
70
+ declare function createStorageAdapter(): StorageAdapter | null;
71
+
72
+ /**
73
+ * Formats a date string or Date object into a localized date string
74
+ * @param stringOrDate - Date string or Date object to format
75
+ * @returns Formatted date string (e.g., "Jan 1, 2024") or empty string if no input
76
+ */
77
+ declare function formatDate(stringOrDate?: string | Date): string;
78
+ /**
79
+ * Formats a date relative to the current time
80
+ * @param date - Date object to format
81
+ * @returns Formatted string with relative time:
82
+ * - "Today, [time]" for today's dates
83
+ * - "Yesterday, [time]" for yesterday's dates
84
+ * - "MMM d, h:mm a" for dates in current year
85
+ * - "MMM d, yyyy" for dates in other years
86
+ */
87
+ declare function formatRelativeDate(date: Date): string;
88
+
89
+ /**
90
+ * Stringifies all values in an object, including objects and null values.
91
+ * If obj is undefined, returns an empty object.
92
+ * @param obj - The object to stringify
93
+ * @returns A new object with the same keys as obj, but with all values stringified
94
+ */
95
+ declare function stringifyValues(obj: Record<string, unknown> | undefined): Record<string, string>;
96
+ /**
97
+ * Removes empty values (undefined, null, empty strings) from an object
98
+ *
99
+ * @param obj - The object to prune
100
+ * @returns A new object with empty values removed
101
+ */
102
+ declare function pruneEmpty<T extends Record<string, unknown>>(obj: T | undefined): Partial<T>;
103
+
104
+ /**
105
+ * Strips markdown from a string
106
+ * @param markdown - The markdown string to strip
107
+ * @returns The stripped markdown string
108
+ */
109
+ declare function stripMarkdown(markdown: string): Promise<string>;
110
+
111
+ /**
112
+ * Truncates a given string to a specified length, adding an ellipsis if the
113
+ * string is longer than the specified length.
114
+ *
115
+ * @param {string} str - The string to truncate.
116
+ * @param {number} length - The maximum length of the resulting string.
117
+ *
118
+ * @returns {string} The truncated string.
119
+ */
120
+ declare function truncate(str: string, length: number): string;
121
+
122
+ /**
123
+ * Get the agent application URL for webhooks and callbacks
124
+ *
125
+ * This function constructs the URL for the main agent application, used primarily
126
+ * for QStash webhooks and external callbacks. It supports multiple deployment
127
+ * environments with fallback logic.
128
+ *
129
+ * @param path - Optional path to append to the base URL (leading slashes are normalized)
130
+ * @returns The complete URL for the agent application
131
+ *
132
+ * @example
133
+ * ```typescript
134
+ * // Get base URL
135
+ * getUrl() // "http://localhost:8454/"
136
+ *
137
+ * // Get URL with path
138
+ * getUrl("/qstash/webhook") // "http://localhost:8454/qstash/webhook"
139
+ * getUrl("api/health") // "http://localhost:8454/api/health"
140
+ * ```
141
+ *
142
+ * @remarks
143
+ * URL resolution priority:
144
+ * 1. `AGENT_URL` environment variable (custom deployment)
145
+ * 2. `RAILWAY_PUBLIC_DOMAIN` environment variable (Railway deployment)
146
+ * 3. `http://localhost:8454/` (default)
147
+ */
148
+ declare function getUrl(path?: string): string;
149
+
150
+ declare function randomUUID(): string;
151
+
152
+ export { type CloudflareEnvironment, ExternalDatabaseAdapter, R2StorageAdapter, type StorageAdapter, chunk, createStorageAdapter, formatDate, formatRelativeDate, getCloudflareEnvironment, getCloudflareServiceUrl, getCloudflareStoragePath, getUrl, pruneEmpty, randomUUID, shuffle, stringifyValues, stripMarkdown, truncate, uniq };
package/dist/index.d.ts CHANGED
@@ -1,10 +1,152 @@
1
- export * from "./lib/array";
2
- export * from "./lib/cloudflare";
3
- export * from "./lib/storage";
4
- export * from "./lib/date";
5
- export * from "./lib/object";
6
- export * from "./lib/markdown";
7
- export * from "./lib/string";
8
- export * from "./lib/urls";
9
- export * from "./lib/uuid";
10
- //# sourceMappingURL=index.d.ts.map
1
+ /**
2
+ * Splits an array into chunks of specified size.
3
+ *
4
+ * @template T - The type of the array elements.
5
+ * @param {T[]} arr - The array to split into chunks.
6
+ * @param {number} size - The maximum number of elements per chunk.
7
+ * @returns {T[][]} An array of chunks, where each chunk is an array of T.
8
+ */
9
+ declare function chunk<T>(arr: T[], size: number): T[][];
10
+ /**
11
+ * Returns a new array with only unique elements from the input array.
12
+ *
13
+ * @template T - The type of the array elements.
14
+ * @param {T[]} array - The array from which to remove duplicate elements.
15
+ * @returns {T[]} A new array containing only unique elements.
16
+ */
17
+ declare function uniq<T>(array: T[]): T[];
18
+ /**
19
+ * Randomly shuffles the elements of an array.
20
+ *
21
+ * @param {any[] | undefined} array - The array to shuffle. If undefined, returns an empty array.
22
+ * @returns {any[]} A shuffled copy of the input array.
23
+ */
24
+ declare function shuffle(array: any[] | undefined): any[];
25
+
26
+ /**
27
+ * Cloudflare environment detection and storage utilities
28
+ */
29
+ interface CloudflareEnvironment {
30
+ isCloudflare: boolean;
31
+ platform: 'pages' | 'workers' | 'local';
32
+ storagePath: string;
33
+ }
34
+ /**
35
+ * Detects if running in Cloudflare environment and returns appropriate storage configuration
36
+ */
37
+ declare function getCloudflareEnvironment(): CloudflareEnvironment;
38
+ /**
39
+ * Gets the appropriate storage path for the current environment
40
+ * @param subPath - Optional subdirectory within the storage path
41
+ */
42
+ declare function getCloudflareStoragePath(subPath?: string): string;
43
+ /**
44
+ * Gets service URL based on Cloudflare environment variables
45
+ */
46
+ declare function getCloudflareServiceUrl(fallbackPort?: number): string;
47
+
48
+ interface StorageAdapter {
49
+ uploadFile(localPath: string, remotePath: string): Promise<void>;
50
+ downloadFile(remotePath: string, localPath: string): Promise<void>;
51
+ exists(remotePath: string): Promise<boolean>;
52
+ delete(remotePath: string): Promise<void>;
53
+ }
54
+ declare class R2StorageAdapter implements StorageAdapter {
55
+ private bucket;
56
+ constructor(bucket: any);
57
+ uploadFile(localPath: string, remotePath: string): Promise<void>;
58
+ downloadFile(remotePath: string, localPath: string): Promise<void>;
59
+ exists(remotePath: string): Promise<boolean>;
60
+ delete(remotePath: string): Promise<void>;
61
+ }
62
+ declare class ExternalDatabaseAdapter implements StorageAdapter {
63
+ private connectionString;
64
+ constructor(connectionString: string);
65
+ uploadFile(localPath: string, remotePath: string): Promise<void>;
66
+ downloadFile(remotePath: string, localPath: string): Promise<void>;
67
+ exists(remotePath: string): Promise<boolean>;
68
+ delete(remotePath: string): Promise<void>;
69
+ }
70
+ declare function createStorageAdapter(): StorageAdapter | null;
71
+
72
+ /**
73
+ * Formats a date string or Date object into a localized date string
74
+ * @param stringOrDate - Date string or Date object to format
75
+ * @returns Formatted date string (e.g., "Jan 1, 2024") or empty string if no input
76
+ */
77
+ declare function formatDate(stringOrDate?: string | Date): string;
78
+ /**
79
+ * Formats a date relative to the current time
80
+ * @param date - Date object to format
81
+ * @returns Formatted string with relative time:
82
+ * - "Today, [time]" for today's dates
83
+ * - "Yesterday, [time]" for yesterday's dates
84
+ * - "MMM d, h:mm a" for dates in current year
85
+ * - "MMM d, yyyy" for dates in other years
86
+ */
87
+ declare function formatRelativeDate(date: Date): string;
88
+
89
+ /**
90
+ * Stringifies all values in an object, including objects and null values.
91
+ * If obj is undefined, returns an empty object.
92
+ * @param obj - The object to stringify
93
+ * @returns A new object with the same keys as obj, but with all values stringified
94
+ */
95
+ declare function stringifyValues(obj: Record<string, unknown> | undefined): Record<string, string>;
96
+ /**
97
+ * Removes empty values (undefined, null, empty strings) from an object
98
+ *
99
+ * @param obj - The object to prune
100
+ * @returns A new object with empty values removed
101
+ */
102
+ declare function pruneEmpty<T extends Record<string, unknown>>(obj: T | undefined): Partial<T>;
103
+
104
+ /**
105
+ * Strips markdown from a string
106
+ * @param markdown - The markdown string to strip
107
+ * @returns The stripped markdown string
108
+ */
109
+ declare function stripMarkdown(markdown: string): Promise<string>;
110
+
111
+ /**
112
+ * Truncates a given string to a specified length, adding an ellipsis if the
113
+ * string is longer than the specified length.
114
+ *
115
+ * @param {string} str - The string to truncate.
116
+ * @param {number} length - The maximum length of the resulting string.
117
+ *
118
+ * @returns {string} The truncated string.
119
+ */
120
+ declare function truncate(str: string, length: number): string;
121
+
122
+ /**
123
+ * Get the agent application URL for webhooks and callbacks
124
+ *
125
+ * This function constructs the URL for the main agent application, used primarily
126
+ * for QStash webhooks and external callbacks. It supports multiple deployment
127
+ * environments with fallback logic.
128
+ *
129
+ * @param path - Optional path to append to the base URL (leading slashes are normalized)
130
+ * @returns The complete URL for the agent application
131
+ *
132
+ * @example
133
+ * ```typescript
134
+ * // Get base URL
135
+ * getUrl() // "http://localhost:8454/"
136
+ *
137
+ * // Get URL with path
138
+ * getUrl("/qstash/webhook") // "http://localhost:8454/qstash/webhook"
139
+ * getUrl("api/health") // "http://localhost:8454/api/health"
140
+ * ```
141
+ *
142
+ * @remarks
143
+ * URL resolution priority:
144
+ * 1. `AGENT_URL` environment variable (custom deployment)
145
+ * 2. `RAILWAY_PUBLIC_DOMAIN` environment variable (Railway deployment)
146
+ * 3. `http://localhost:8454/` (default)
147
+ */
148
+ declare function getUrl(path?: string): string;
149
+
150
+ declare function randomUUID(): string;
151
+
152
+ export { type CloudflareEnvironment, ExternalDatabaseAdapter, R2StorageAdapter, type StorageAdapter, chunk, createStorageAdapter, formatDate, formatRelativeDate, getCloudflareEnvironment, getCloudflareServiceUrl, getCloudflareStoragePath, getUrl, pruneEmpty, randomUUID, shuffle, stringifyValues, stripMarkdown, truncate, uniq };