@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.
- package/.cache/tsbuildinfo.json +1 -1
- package/.turbo/turbo-build.log +20 -2
- package/dist/index.cjs +261 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.cts +152 -0
- package/dist/index.d.ts +152 -10
- package/dist/index.js +208 -9
- package/dist/index.js.map +1 -0
- package/package.json +7 -5
- package/tsconfig.json +8 -4
- package/tsup.config.ts +14 -0
- package/.turbo/turbo-lint$colon$fix.log +0 -6
- package/.turbo/turbo-lint.log +0 -6
- package/.turbo/turbo-typecheck.log +0 -5
- package/dist/index.d.ts.map +0 -1
- package/dist/lib/array.d.ts +0 -25
- package/dist/lib/array.d.ts.map +0 -1
- package/dist/lib/array.js +0 -32
- package/dist/lib/cloudflare.d.ts +0 -22
- package/dist/lib/cloudflare.d.ts.map +0 -1
- package/dist/lib/cloudflare.js +0 -53
- package/dist/lib/date.d.ts +0 -17
- package/dist/lib/date.d.ts.map +0 -1
- package/dist/lib/date.js +0 -37
- package/dist/lib/markdown.d.ts +0 -7
- package/dist/lib/markdown.d.ts.map +0 -1
- package/dist/lib/markdown.js +0 -11
- package/dist/lib/object.d.ts +0 -15
- package/dist/lib/object.d.ts.map +0 -1
- package/dist/lib/object.js +0 -42
- package/dist/lib/storage.d.ts +0 -24
- package/dist/lib/storage.d.ts.map +0 -1
- package/dist/lib/storage.js +0 -50
- package/dist/lib/string.d.ts +0 -11
- package/dist/lib/string.d.ts.map +0 -1
- package/dist/lib/string.js +0 -12
- package/dist/lib/urls.d.ts +0 -28
- package/dist/lib/urls.d.ts.map +0 -1
- package/dist/lib/urls.js +0 -36
- package/dist/lib/uuid.d.ts +0 -2
- package/dist/lib/uuid.d.ts.map +0 -1
- package/dist/lib/uuid.js +0 -6
package/.turbo/turbo-build.log
CHANGED
|
@@ -1,5 +1,23 @@
|
|
|
1
1
|
|
|
2
2
|
|
|
3
|
-
> @hybrd/utils@1.
|
|
4
|
-
>
|
|
3
|
+
> @hybrd/utils@1.1.1 build /Users/ian/Projects/01/hybrid/packages/utils
|
|
4
|
+
> tsup
|
|
5
5
|
|
|
6
|
+
[34mCLI[39m Building entry: {"index":"src/index.ts"}
|
|
7
|
+
[34mCLI[39m Using tsconfig: tsconfig.json
|
|
8
|
+
[34mCLI[39m tsup v8.5.0
|
|
9
|
+
[34mCLI[39m Using tsup config: /Users/ian/Projects/01/hybrid/packages/utils/tsup.config.ts
|
|
10
|
+
[34mCLI[39m Target: es2020
|
|
11
|
+
[34mCLI[39m Cleaning output folder
|
|
12
|
+
[34mCJS[39m Build start
|
|
13
|
+
[34mESM[39m Build start
|
|
14
|
+
[32mESM[39m [1mdist/index.js [22m[32m5.11 KB[39m
|
|
15
|
+
[32mESM[39m [1mdist/index.js.map [22m[32m13.61 KB[39m
|
|
16
|
+
[32mESM[39m ⚡️ Build success in 19ms
|
|
17
|
+
[32mCJS[39m [1mdist/index.cjs [22m[32m7.59 KB[39m
|
|
18
|
+
[32mCJS[39m [1mdist/index.cjs.map [22m[32m14.07 KB[39m
|
|
19
|
+
[32mCJS[39m ⚡️ 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"]}
|
package/dist/index.d.cts
ADDED
|
@@ -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
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
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 };
|