@axiom-lattice/gateway 2.1.100 → 2.1.102
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/.turbo/turbo-build.log +22 -18
- package/CHANGELOG.md +25 -0
- package/dist/{WechatChannelAdapter-QQYOHZTL.mjs → WechatChannelAdapter-WSDKR4OA.mjs} +23 -17
- package/dist/WechatChannelAdapter-WSDKR4OA.mjs.map +1 -0
- package/dist/chunk-R4ZO3HZ3.mjs +46 -0
- package/dist/chunk-R4ZO3HZ3.mjs.map +1 -0
- package/dist/index.js +325 -94
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +64 -67
- package/dist/index.mjs.map +1 -1
- package/dist/resources-3DGHISBZ.mjs +183 -0
- package/dist/resources-3DGHISBZ.mjs.map +1 -0
- package/package.json +6 -6
- package/src/channels/wechat/WechatChannelAdapter.ts +3 -3
- package/src/channels/wechat/__tests__/context-store.test.ts +148 -0
- package/src/channels/wechat/context-store.ts +22 -15
- package/src/controllers/__tests__/mime.test.ts +74 -0
- package/src/controllers/__tests__/resources.test.ts +99 -0
- package/src/controllers/resources.ts +252 -0
- package/src/controllers/sandbox.ts +1 -30
- package/src/controllers/workspace.ts +25 -45
- package/src/index.ts +24 -0
- package/src/routes/resource-routes.ts +24 -0
- package/src/utils/mime.ts +43 -0
- package/dist/WechatChannelAdapter-QQYOHZTL.mjs.map +0 -1
package/.turbo/turbo-build.log
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
|
|
2
|
-
> @axiom-lattice/gateway@2.1.
|
|
2
|
+
> @axiom-lattice/gateway@2.1.102 build /home/runner/work/agentic/agentic/packages/gateway
|
|
3
3
|
> tsup src/index.ts --format cjs,esm --dts --clean --sourcemap
|
|
4
4
|
|
|
5
5
|
[34mCLI[39m Building entry: src/index.ts
|
|
@@ -9,30 +9,34 @@
|
|
|
9
9
|
[34mCLI[39m Cleaning output folder
|
|
10
10
|
[34mCJS[39m Build start
|
|
11
11
|
[34mESM[39m Build start
|
|
12
|
-
[32mESM[39m [1mdist/index.mjs [22m[32m270.95 KB[39m
|
|
13
|
-
[32mESM[39m [1mdist/sender-PX32VSHB.mjs [22m[32m873.00 B[39m
|
|
14
|
-
[32mESM[39m [1mdist/WechatChannelAdapter-QQYOHZTL.mjs [22m[32m7.95 KB[39m
|
|
15
|
-
[32mESM[39m [1mdist/chunk-6CUQGDJI.mjs [22m[32m6.42 KB[39m
|
|
16
|
-
[32mESM[39m [1mdist/a2a-ERG5RMUW.mjs [22m[32m15.95 KB[39m
|
|
17
|
-
[32mESM[39m [1mdist/index.mjs.map [22m[32m575.03 KB[39m
|
|
18
|
-
[32mESM[39m [1mdist/sender-PX32VSHB.mjs.map [22m[32m2.07 KB[39m
|
|
19
|
-
[32mESM[39m [1mdist/WechatChannelAdapter-QQYOHZTL.mjs.map [22m[32m15.71 KB[39m
|
|
20
|
-
[32mESM[39m [1mdist/chunk-6CUQGDJI.mjs.map [22m[32m14.04 KB[39m
|
|
21
|
-
[32mESM[39m [1mdist/a2a-ERG5RMUW.mjs.map [22m[32m32.14 KB[39m
|
|
22
|
-
[32mESM[39m ⚡️ Build success in 415ms
|
|
23
12
|
[warn] [33m▲ [43;33m[[43;30mWARNING[43;33m][0m [1m"import.meta" is not available with the "cjs" output format and will be empty[0m [empty-import-meta]
|
|
24
13
|
|
|
25
|
-
src/index.ts:
|
|
26
|
-
[37m
|
|
14
|
+
src/index.ts:194:33:
|
|
15
|
+
[37m 194 │ const __filename = fileURLToPath([32mimport.meta[37m.url);
|
|
27
16
|
╵ [32m~~~~~~~~~~~[0m
|
|
28
17
|
|
|
29
18
|
You need to set the output format to "esm" for "import.meta" to work correctly.
|
|
30
19
|
|
|
31
20
|
|
|
32
|
-
[
|
|
33
|
-
[
|
|
34
|
-
[
|
|
21
|
+
[32mESM[39m [1mdist/index.mjs [22m[32m271.42 KB[39m
|
|
22
|
+
[32mESM[39m [1mdist/sender-PX32VSHB.mjs [22m[32m873.00 B[39m
|
|
23
|
+
[32mESM[39m [1mdist/WechatChannelAdapter-WSDKR4OA.mjs [22m[32m8.27 KB[39m
|
|
24
|
+
[32mESM[39m [1mdist/chunk-6CUQGDJI.mjs [22m[32m6.42 KB[39m
|
|
25
|
+
[32mESM[39m [1mdist/a2a-ERG5RMUW.mjs [22m[32m15.95 KB[39m
|
|
26
|
+
[32mESM[39m [1mdist/resources-3DGHISBZ.mjs [22m[32m8.12 KB[39m
|
|
27
|
+
[32mESM[39m [1mdist/chunk-R4ZO3HZ3.mjs [22m[32m1.44 KB[39m
|
|
28
|
+
[32mESM[39m [1mdist/index.mjs.map [22m[32m575.75 KB[39m
|
|
29
|
+
[32mESM[39m [1mdist/sender-PX32VSHB.mjs.map [22m[32m2.07 KB[39m
|
|
30
|
+
[32mESM[39m [1mdist/WechatChannelAdapter-WSDKR4OA.mjs.map [22m[32m16.28 KB[39m
|
|
31
|
+
[32mESM[39m [1mdist/chunk-6CUQGDJI.mjs.map [22m[32m14.04 KB[39m
|
|
32
|
+
[32mESM[39m [1mdist/a2a-ERG5RMUW.mjs.map [22m[32m32.14 KB[39m
|
|
33
|
+
[32mESM[39m [1mdist/resources-3DGHISBZ.mjs.map [22m[32m15.35 KB[39m
|
|
34
|
+
[32mESM[39m [1mdist/chunk-R4ZO3HZ3.mjs.map [22m[32m2.35 KB[39m
|
|
35
|
+
[32mESM[39m ⚡️ Build success in 520ms
|
|
36
|
+
[32mCJS[39m [1mdist/index.js [22m[32m320.15 KB[39m
|
|
37
|
+
[32mCJS[39m [1mdist/index.js.map [22m[32m658.17 KB[39m
|
|
38
|
+
[32mCJS[39m ⚡️ Build success in 535ms
|
|
35
39
|
[34mDTS[39m Build start
|
|
36
|
-
[32mDTS[39m ⚡️ Build success in
|
|
40
|
+
[32mDTS[39m ⚡️ Build success in 18706ms
|
|
37
41
|
[32mDTS[39m [1mdist/index.d.ts [22m[32m7.57 KB[39m
|
|
38
42
|
[32mDTS[39m [1mdist/index.d.mts [22m[32m7.57 KB[39m
|
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,30 @@
|
|
|
1
1
|
# @axiom-lattice/gateway
|
|
2
2
|
|
|
3
|
+
## 2.1.102
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- f2dce99: fix bugs
|
|
8
|
+
- Updated dependencies [f2dce99]
|
|
9
|
+
- @axiom-lattice/agent-eval@2.1.84
|
|
10
|
+
- @axiom-lattice/core@2.1.90
|
|
11
|
+
- @axiom-lattice/pg-stores@1.0.81
|
|
12
|
+
- @axiom-lattice/protocols@2.1.45
|
|
13
|
+
- @axiom-lattice/queue-redis@1.0.44
|
|
14
|
+
|
|
15
|
+
## 2.1.101
|
|
16
|
+
|
|
17
|
+
### Patch Changes
|
|
18
|
+
|
|
19
|
+
- 0552021: WeChat channel improvements:
|
|
20
|
+
- QR code setup: replace auto-polling with manual refresh button + 5-min countdown timer
|
|
21
|
+
- context-store: key by installationId::senderId to prevent cross-installation token collision
|
|
22
|
+
- 13cd999: fix sandbox
|
|
23
|
+
- Updated dependencies [13cd999]
|
|
24
|
+
- @axiom-lattice/core@2.1.89
|
|
25
|
+
- @axiom-lattice/agent-eval@2.1.83
|
|
26
|
+
- @axiom-lattice/pg-stores@1.0.80
|
|
27
|
+
|
|
3
28
|
## 2.1.100
|
|
4
29
|
|
|
5
30
|
### Patch Changes
|
|
@@ -11,31 +11,37 @@ import { z } from "zod";
|
|
|
11
11
|
var TOKEN_TTL_MS = 24 * 60 * 60 * 1e3;
|
|
12
12
|
var store = /* @__PURE__ */ new Map();
|
|
13
13
|
var timers = /* @__PURE__ */ new Map();
|
|
14
|
-
function
|
|
15
|
-
|
|
14
|
+
function makeKey(installationId, senderId) {
|
|
15
|
+
return `${installationId}::${senderId}`;
|
|
16
|
+
}
|
|
17
|
+
function getContextToken(installationId, senderId) {
|
|
18
|
+
const key = makeKey(installationId, senderId);
|
|
19
|
+
const entry = store.get(key);
|
|
16
20
|
if (!entry) return void 0;
|
|
17
21
|
if (Date.now() - entry.updatedAt > TOKEN_TTL_MS) {
|
|
18
|
-
deleteContextToken(senderId);
|
|
22
|
+
deleteContextToken(installationId, senderId);
|
|
19
23
|
return void 0;
|
|
20
24
|
}
|
|
21
25
|
return entry.token;
|
|
22
26
|
}
|
|
23
|
-
function setContextToken(senderId, token) {
|
|
24
|
-
const
|
|
27
|
+
function setContextToken(installationId, senderId, token) {
|
|
28
|
+
const key = makeKey(installationId, senderId);
|
|
29
|
+
const existingTimer = timers.get(key);
|
|
25
30
|
if (existingTimer) clearTimeout(existingTimer);
|
|
26
|
-
store.set(
|
|
31
|
+
store.set(key, { token, installationId, senderId, updatedAt: Date.now() });
|
|
27
32
|
const timer = setTimeout(() => {
|
|
28
|
-
store.delete(
|
|
29
|
-
timers.delete(
|
|
33
|
+
store.delete(key);
|
|
34
|
+
timers.delete(key);
|
|
30
35
|
}, TOKEN_TTL_MS);
|
|
31
|
-
timers.set(
|
|
36
|
+
timers.set(key, timer);
|
|
32
37
|
}
|
|
33
|
-
function deleteContextToken(senderId) {
|
|
34
|
-
|
|
35
|
-
|
|
38
|
+
function deleteContextToken(installationId, senderId) {
|
|
39
|
+
const key = makeKey(installationId, senderId);
|
|
40
|
+
store.delete(key);
|
|
41
|
+
const timer = timers.get(key);
|
|
36
42
|
if (timer) {
|
|
37
43
|
clearTimeout(timer);
|
|
38
|
-
timers.delete(
|
|
44
|
+
timers.delete(key);
|
|
39
45
|
}
|
|
40
46
|
}
|
|
41
47
|
|
|
@@ -81,7 +87,7 @@ var wechatChannelAdapter = {
|
|
|
81
87
|
const text = extractText(msg);
|
|
82
88
|
if (!text) return null;
|
|
83
89
|
if (msg.context_token) {
|
|
84
|
-
setContextToken(senderId, msg.context_token);
|
|
90
|
+
setContextToken(installation.id, senderId, msg.context_token);
|
|
85
91
|
}
|
|
86
92
|
return {
|
|
87
93
|
channel: "wechat",
|
|
@@ -107,13 +113,13 @@ var wechatChannelAdapter = {
|
|
|
107
113
|
},
|
|
108
114
|
async sendReply(replyTarget, message, installation) {
|
|
109
115
|
const senderId = replyTarget.rawTarget.senderId;
|
|
110
|
-
const contextToken = getContextToken(senderId);
|
|
116
|
+
const contextToken = getContextToken(installation.id, senderId);
|
|
111
117
|
if (!contextToken) {
|
|
112
118
|
logger.warn("WeChat context token expired, cannot send reply", {
|
|
113
119
|
installationId: installation.id,
|
|
114
120
|
senderId
|
|
115
121
|
});
|
|
116
|
-
deleteContextToken(senderId);
|
|
122
|
+
deleteContextToken(installation.id, senderId);
|
|
117
123
|
return;
|
|
118
124
|
}
|
|
119
125
|
const { botToken } = installation.config;
|
|
@@ -246,4 +252,4 @@ var wechatChannelAdapter = {
|
|
|
246
252
|
export {
|
|
247
253
|
wechatChannelAdapter
|
|
248
254
|
};
|
|
249
|
-
//# sourceMappingURL=WechatChannelAdapter-
|
|
255
|
+
//# sourceMappingURL=WechatChannelAdapter-WSDKR4OA.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/channels/wechat/WechatChannelAdapter.ts","../src/channels/wechat/context-store.ts"],"sourcesContent":["import { z } from \"zod\";\nimport type {\n ChannelAdapter,\n InboundMessage,\n OutboundMessage,\n ReplyTarget,\n ChannelInstallation,\n} from \"@axiom-lattice/protocols\";\nimport type { WechatChannelInstallationConfig } from \"@axiom-lattice/protocols\";\nimport { getUpdates, sendMessage } from \"./wechat-client\";\nimport { setContextToken, getContextToken, deleteContextToken } from \"./context-store\";\nimport { Logger } from \"../../logger/Logger\";\n\nconst logger = new Logger({ serviceName: \"lattice/gateway/wechat\" });\n\nconst wechatConfigSchema = z.object({\n botToken: z.string(),\n uin: z.string().optional(),\n});\n\nconst MAX_RECONNECT_DELAY_MS = 30_000;\nconst BASE_RECONNECT_DELAY_MS = 1_000;\nconst HEARTBEAT_INTERVAL_MS = 60_000;\nconst CHANNEL_VERSION = \"1.0.2\";\n\n// ─── Message type constants ───────────────────────────────────────────────\n\nconst MSG_TYPE_USER = 1;\nconst MSG_ITEM_TEXT = 1;\n\n// ─── Polling connection state ─────────────────────────────────────────────\n\ninterface PollingState {\n installationId: string;\n abortController: AbortController;\n lastActivity: number;\n heartbeatTimer: NodeJS.Timeout;\n}\n\nconst activeConnections = new Map<string, PollingState>();\n\n// ─── Message dedup ────────────────────────────────────────────────────────\n\nconst seenClientIds = new Set<string>();\n\nfunction addToDedup(clientId: string): boolean {\n if (!clientId || seenClientIds.has(clientId)) return false;\n seenClientIds.add(clientId);\n if (seenClientIds.size > 1000) {\n const first = seenClientIds.values().next().value;\n if (first !== undefined) seenClientIds.delete(first);\n }\n return true;\n}\n\n// ─── Text extraction from iLink message ───────────────────────────────────\n\nfunction extractText(msg: { item_list?: Array<{ type?: number; text_item?: { text?: string } }> }): string | null {\n if (!msg.item_list?.length) return null;\n for (const item of msg.item_list) {\n if (item.type === MSG_ITEM_TEXT && item.text_item?.text) {\n return item.text_item.text;\n }\n }\n return null;\n}\n\n// ─── Adapter ──────────────────────────────────────────────────────────────\n\nexport const wechatChannelAdapter: ChannelAdapter<WechatChannelInstallationConfig> = {\n channel: \"wechat\",\n\n configSchema: wechatConfigSchema,\n\n async receive(\n rawPayload: unknown,\n installation: ChannelInstallation<WechatChannelInstallationConfig>,\n ): Promise<InboundMessage | null> {\n const msg = rawPayload as {\n from_user_id?: string;\n client_id?: string;\n message_type?: number;\n item_list?: Array<{ type?: number; text_item?: { text?: string } }>;\n context_token?: string;\n };\n\n // Only process user messages (type 1), skip bot echoes (type 2)\n if (msg.message_type !== MSG_TYPE_USER) return null;\n\n const senderId = msg.from_user_id;\n if (!senderId) return null;\n\n const text = extractText(msg);\n if (!text) return null;\n\n // Cache context token for reply\n if (msg.context_token) {\n setContextToken(installation.id, senderId, msg.context_token);\n }\n\n return {\n channel: \"wechat\",\n channelInstallationId: installation.id,\n tenantId: installation.tenantId,\n sender: {\n id: senderId,\n displayName: senderId.split(\"@\")[0],\n },\n content: {\n text,\n },\n conversation: {\n id: senderId,\n type: \"direct\",\n },\n replyTarget: {\n adapterChannel: \"wechat\",\n channelInstallationId: installation.id,\n rawTarget: { senderId },\n },\n };\n },\n\n async sendReply(\n replyTarget: ReplyTarget,\n message: OutboundMessage,\n installation: ChannelInstallation<WechatChannelInstallationConfig>,\n ): Promise<void> {\n const senderId = replyTarget.rawTarget.senderId as string;\n const contextToken = getContextToken(installation.id, senderId);\n\n if (!contextToken) {\n logger.warn(\"WeChat context token expired, cannot send reply\", {\n installationId: installation.id,\n senderId,\n });\n deleteContextToken(installation.id, senderId);\n return;\n }\n\n const { botToken } = installation.config;\n await sendMessage(botToken, senderId, message.text, contextToken);\n },\n\n resolveThreadId(message: InboundMessage, binding: unknown): string {\n const date = new Date().toISOString().split(\"T\")[0];\n const agentId = (binding as { agentId: string }).agentId;\n return `wechat:dm:${message.sender.id}:${agentId}:${date}`;\n },\n\n async connect(\n installation: ChannelInstallation<WechatChannelInstallationConfig>,\n deps?: unknown,\n ): Promise<void> {\n const { id: installationId, tenantId, config } = installation;\n\n if (!config.botToken) {\n logger.warn(\"WeChat installation missing botToken, skipping\", { installationId });\n return;\n }\n\n if (activeConnections.has(installationId)) {\n logger.warn(\"WeChat polling already running for installation, skipping\", { installationId });\n return;\n }\n\n logger.info(\"WeChat polling starting\", { installationId, tenantId });\n\n const abortController = new AbortController();\n\n const heartbeatTimer = setInterval(() => {\n const state2 = activeConnections.get(installationId);\n if (!state2) {\n clearInterval(heartbeatTimer);\n return;\n }\n const elapsed = Date.now() - state2.lastActivity;\n if (elapsed > HEARTBEAT_INTERVAL_MS * 2) {\n logger.error(\"WeChat polling heartbeat lost — no activity\", {\n installationId,\n elapsedMs: elapsed,\n });\n state2.abortController.abort();\n }\n }, HEARTBEAT_INTERVAL_MS);\n\n const state: PollingState = {\n installationId,\n abortController,\n lastActivity: Date.now(),\n heartbeatTimer,\n };\n activeConnections.set(installationId, state);\n\n const router = (deps as { router?: { dispatch(msg: InboundMessage): Promise<unknown> } })?.router;\n\n let syncBuffer = \"\";\n let reconnectDelay = BASE_RECONNECT_DELAY_MS;\n\n const scheduleNextPoll = (): void => {\n poll().catch((err) => {\n logger.error(\"WeChat poll iteration crashed\", {\n installationId,\n error: err instanceof Error ? err.message : String(err),\n });\n const currentState = activeConnections.get(installationId);\n if (currentState && !currentState.abortController.signal.aborted) {\n setTimeout(scheduleNextPoll, reconnectDelay);\n }\n });\n };\n\n const poll = async (): Promise<void> => {\n const currentState = activeConnections.get(installationId);\n if (!currentState || currentState.abortController.signal.aborted) {\n logger.info(\"WeChat polling aborted\", { installationId });\n return;\n }\n\n try {\n const result = await getUpdates(\n config.botToken,\n syncBuffer,\n currentState.abortController.signal,\n );\n syncBuffer = result.syncBuffer;\n reconnectDelay = BASE_RECONNECT_DELAY_MS;\n currentState.lastActivity = Date.now();\n\n if (result.msgs.length > 0) {\n logger.info(\"WeChat poll received messages\", {\n installationId,\n count: result.msgs.length,\n });\n }\n\n for (const rawMsg of result.msgs) {\n // Only user messages, skip bot echoes and non-text\n if (rawMsg.message_type !== MSG_TYPE_USER) continue;\n\n const text = extractText(rawMsg);\n if (!text) continue;\n\n if (!addToDedup((rawMsg as { client_id?: string }).client_id ?? \"\")) continue;\n\n const inbound = await wechatChannelAdapter.receive(\n rawMsg,\n installation as ChannelInstallation<WechatChannelInstallationConfig>,\n );\n if (inbound && router) {\n const dispatchResult = await router.dispatch(inbound);\n if (!(dispatchResult as { success?: boolean }).success) {\n logger.warn(\"WeChat dispatch failed\", {\n installationId,\n error: (dispatchResult as { error?: { message?: string } }).error?.message,\n });\n }\n }\n }\n } catch (err) {\n if (err instanceof Error && err.name === \"AbortError\") {\n logger.info(\"WeChat poll aborted by signal\", { installationId });\n return;\n }\n\n logger.error(\"WeChat poll error\", {\n installationId,\n error: err instanceof Error ? err.message : String(err),\n });\n await new Promise((resolve) => setTimeout(resolve, reconnectDelay));\n reconnectDelay = Math.min(reconnectDelay * 2, MAX_RECONNECT_DELAY_MS);\n }\n\n scheduleNextPoll();\n };\n\n scheduleNextPoll();\n logger.info(\"WeChat polling started\", { installationId });\n },\n\n async disconnect(installationId: string): Promise<void> {\n const state = activeConnections.get(installationId);\n if (!state) {\n logger.warn(\"WeChat polling not running, nothing to disconnect\", { installationId });\n return;\n }\n\n logger.info(\"WeChat polling disconnecting\", { installationId });\n state.abortController.abort();\n clearInterval(state.heartbeatTimer);\n activeConnections.delete(installationId);\n logger.info(\"WeChat polling disconnected\", { installationId });\n },\n};\n","interface ContextTokenEntry {\n token: string;\n installationId: string;\n senderId: string;\n updatedAt: number;\n}\n\nconst TOKEN_TTL_MS = 24 * 60 * 60 * 1000; // 24 hours\nconst store = new Map<string, ContextTokenEntry>();\nconst timers = new Map<string, NodeJS.Timeout>();\n\nfunction makeKey(installationId: string, senderId: string): string {\n return `${installationId}::${senderId}`;\n}\n\nexport function getContextToken(installationId: string, senderId: string): string | undefined {\n const key = makeKey(installationId, senderId);\n const entry = store.get(key);\n if (!entry) return undefined;\n if (Date.now() - entry.updatedAt > TOKEN_TTL_MS) {\n deleteContextToken(installationId, senderId);\n return undefined;\n }\n return entry.token;\n}\n\nexport function setContextToken(installationId: string, senderId: string, token: string): void {\n const key = makeKey(installationId, senderId);\n\n const existingTimer = timers.get(key);\n if (existingTimer) clearTimeout(existingTimer);\n\n store.set(key, { token, installationId, senderId, updatedAt: Date.now() });\n\n const timer = setTimeout(() => {\n store.delete(key);\n timers.delete(key);\n }, TOKEN_TTL_MS);\n timers.set(key, timer);\n}\n\nexport function deleteContextToken(installationId: string, senderId: string): void {\n const key = makeKey(installationId, senderId);\n store.delete(key);\n const timer = timers.get(key);\n if (timer) {\n clearTimeout(timer);\n timers.delete(key);\n }\n}\n\nexport function getContextTokenStoreSize(): number {\n return store.size;\n}\n"],"mappings":"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","names":[]}
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
// src/utils/mime.ts
|
|
2
|
+
var EXT_TO_MIME = {
|
|
3
|
+
".txt": "text/plain",
|
|
4
|
+
".html": "text/html",
|
|
5
|
+
".htm": "text/html",
|
|
6
|
+
".css": "text/css",
|
|
7
|
+
".js": "application/javascript",
|
|
8
|
+
".mjs": "application/javascript",
|
|
9
|
+
".json": "application/json",
|
|
10
|
+
".pdf": "application/pdf",
|
|
11
|
+
".png": "image/png",
|
|
12
|
+
".jpg": "image/jpeg",
|
|
13
|
+
".jpeg": "image/jpeg",
|
|
14
|
+
".gif": "image/gif",
|
|
15
|
+
".webp": "image/webp",
|
|
16
|
+
".svg": "image/svg+xml",
|
|
17
|
+
".ico": "image/x-icon",
|
|
18
|
+
".zip": "application/zip",
|
|
19
|
+
".csv": "text/csv",
|
|
20
|
+
".xml": "application/xml",
|
|
21
|
+
".xlsx": "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet",
|
|
22
|
+
".xls": "application/vnd.ms-excel",
|
|
23
|
+
".pptx": "application/vnd.openxmlformats-officedocument.presentationml.presentation",
|
|
24
|
+
".ppt": "application/vnd.ms-powerpoint",
|
|
25
|
+
".docx": "application/vnd.openxmlformats-officedocument.wordprocessingml.document",
|
|
26
|
+
".doc": "application/msword",
|
|
27
|
+
".mp4": "video/mp4",
|
|
28
|
+
".webm": "video/webm",
|
|
29
|
+
".mp3": "audio/mpeg",
|
|
30
|
+
".wav": "audio/wav",
|
|
31
|
+
".ogg": "audio/ogg"
|
|
32
|
+
};
|
|
33
|
+
function getContentTypeFromFilename(filename) {
|
|
34
|
+
const ext = filename.includes(".") ? filename.slice(filename.lastIndexOf(".")).toLowerCase() : "";
|
|
35
|
+
return EXT_TO_MIME[ext] ?? "application/octet-stream";
|
|
36
|
+
}
|
|
37
|
+
function getFilenameFromPath(path) {
|
|
38
|
+
const segments = path.replace(/\/+$/, "").split("/");
|
|
39
|
+
return segments[segments.length - 1] || "download";
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
export {
|
|
43
|
+
getContentTypeFromFilename,
|
|
44
|
+
getFilenameFromPath
|
|
45
|
+
};
|
|
46
|
+
//# sourceMappingURL=chunk-R4ZO3HZ3.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/utils/mime.ts"],"sourcesContent":["const EXT_TO_MIME: Record<string, string> = {\n \".txt\": \"text/plain\",\n \".html\": \"text/html\",\n \".htm\": \"text/html\",\n \".css\": \"text/css\",\n \".js\": \"application/javascript\",\n \".mjs\": \"application/javascript\",\n \".json\": \"application/json\",\n \".pdf\": \"application/pdf\",\n \".png\": \"image/png\",\n \".jpg\": \"image/jpeg\",\n \".jpeg\": \"image/jpeg\",\n \".gif\": \"image/gif\",\n \".webp\": \"image/webp\",\n \".svg\": \"image/svg+xml\",\n \".ico\": \"image/x-icon\",\n \".zip\": \"application/zip\",\n \".csv\": \"text/csv\",\n \".xml\": \"application/xml\",\n \".xlsx\": \"application/vnd.openxmlformats-officedocument.spreadsheetml.sheet\",\n \".xls\": \"application/vnd.ms-excel\",\n \".pptx\": \"application/vnd.openxmlformats-officedocument.presentationml.presentation\",\n \".ppt\": \"application/vnd.ms-powerpoint\",\n \".docx\": \"application/vnd.openxmlformats-officedocument.wordprocessingml.document\",\n \".doc\": \"application/msword\",\n \".mp4\": \"video/mp4\",\n \".webm\": \"video/webm\",\n \".mp3\": \"audio/mpeg\",\n \".wav\": \"audio/wav\",\n \".ogg\": \"audio/ogg\",\n};\n\nexport function getContentTypeFromFilename(filename: string): string {\n const ext = filename.includes(\".\")\n ? filename.slice(filename.lastIndexOf(\".\")).toLowerCase()\n : \"\";\n return EXT_TO_MIME[ext] ?? \"application/octet-stream\";\n}\n\nexport function getFilenameFromPath(path: string): string {\n const segments = path.replace(/\\/+$/, \"\").split(\"/\");\n return segments[segments.length - 1] || \"download\";\n}\n"],"mappings":";AAAA,IAAM,cAAsC;AAAA,EAC1C,QAAQ;AAAA,EACR,SAAS;AAAA,EACT,QAAQ;AAAA,EACR,QAAQ;AAAA,EACR,OAAO;AAAA,EACP,QAAQ;AAAA,EACR,SAAS;AAAA,EACT,QAAQ;AAAA,EACR,QAAQ;AAAA,EACR,QAAQ;AAAA,EACR,SAAS;AAAA,EACT,QAAQ;AAAA,EACR,SAAS;AAAA,EACT,QAAQ;AAAA,EACR,QAAQ;AAAA,EACR,QAAQ;AAAA,EACR,QAAQ;AAAA,EACR,QAAQ;AAAA,EACR,SAAS;AAAA,EACT,QAAQ;AAAA,EACR,SAAS;AAAA,EACT,QAAQ;AAAA,EACR,SAAS;AAAA,EACT,QAAQ;AAAA,EACR,QAAQ;AAAA,EACR,SAAS;AAAA,EACT,QAAQ;AAAA,EACR,QAAQ;AAAA,EACR,QAAQ;AACV;AAEO,SAAS,2BAA2B,UAA0B;AACnE,QAAM,MAAM,SAAS,SAAS,GAAG,IAC7B,SAAS,MAAM,SAAS,YAAY,GAAG,CAAC,EAAE,YAAY,IACtD;AACJ,SAAO,YAAY,GAAG,KAAK;AAC7B;AAEO,SAAS,oBAAoB,MAAsB;AACxD,QAAM,WAAW,KAAK,QAAQ,QAAQ,EAAE,EAAE,MAAM,GAAG;AACnD,SAAO,SAAS,SAAS,SAAS,CAAC,KAAK;AAC1C;","names":[]}
|