sa2kit 1.0.0

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 (218) hide show
  1. package/LICENSE +22 -0
  2. package/README.md +298 -0
  3. package/dist/AliyunOSSProvider-7JLMJDXK.js +15 -0
  4. package/dist/AliyunOSSProvider-7JLMJDXK.js.map +1 -0
  5. package/dist/AliyunOSSProvider-GQMSDJGZ.mjs +6 -0
  6. package/dist/AliyunOSSProvider-GQMSDJGZ.mjs.map +1 -0
  7. package/dist/LocalStorageProvider-FVLLHBHO.mjs +6 -0
  8. package/dist/LocalStorageProvider-FVLLHBHO.mjs.map +1 -0
  9. package/dist/LocalStorageProvider-NBNHHWLY.js +15 -0
  10. package/dist/LocalStorageProvider-NBNHHWLY.js.map +1 -0
  11. package/dist/analytics/index.d.mts +1084 -0
  12. package/dist/analytics/index.d.ts +1084 -0
  13. package/dist/analytics/index.js +2595 -0
  14. package/dist/analytics/index.js.map +1 -0
  15. package/dist/analytics/index.mjs +2518 -0
  16. package/dist/analytics/index.mjs.map +1 -0
  17. package/dist/analytics/server/index.d.mts +499 -0
  18. package/dist/analytics/server/index.d.ts +499 -0
  19. package/dist/analytics/server/index.js +529 -0
  20. package/dist/analytics/server/index.js.map +1 -0
  21. package/dist/analytics/server/index.mjs +525 -0
  22. package/dist/analytics/server/index.mjs.map +1 -0
  23. package/dist/auth/client/index.d.mts +104 -0
  24. package/dist/auth/client/index.d.ts +104 -0
  25. package/dist/auth/client/index.js +21 -0
  26. package/dist/auth/client/index.js.map +1 -0
  27. package/dist/auth/client/index.mjs +4 -0
  28. package/dist/auth/client/index.mjs.map +1 -0
  29. package/dist/auth/components/index.d.mts +82 -0
  30. package/dist/auth/components/index.d.ts +82 -0
  31. package/dist/auth/components/index.js +93 -0
  32. package/dist/auth/components/index.js.map +1 -0
  33. package/dist/auth/components/index.mjs +86 -0
  34. package/dist/auth/components/index.mjs.map +1 -0
  35. package/dist/auth/hooks/index.d.mts +2 -0
  36. package/dist/auth/hooks/index.d.ts +2 -0
  37. package/dist/auth/hooks/index.js +17 -0
  38. package/dist/auth/hooks/index.js.map +1 -0
  39. package/dist/auth/hooks/index.mjs +4 -0
  40. package/dist/auth/hooks/index.mjs.map +1 -0
  41. package/dist/auth/index.d.mts +15 -0
  42. package/dist/auth/index.d.ts +15 -0
  43. package/dist/auth/index.js +110 -0
  44. package/dist/auth/index.js.map +1 -0
  45. package/dist/auth/index.mjs +9 -0
  46. package/dist/auth/index.mjs.map +1 -0
  47. package/dist/auth/middleware/index.d.mts +75 -0
  48. package/dist/auth/middleware/index.d.ts +75 -0
  49. package/dist/auth/middleware/index.js +15 -0
  50. package/dist/auth/middleware/index.js.map +1 -0
  51. package/dist/auth/middleware/index.mjs +6 -0
  52. package/dist/auth/middleware/index.mjs.map +1 -0
  53. package/dist/auth/routes/index.d.mts +163 -0
  54. package/dist/auth/routes/index.d.ts +163 -0
  55. package/dist/auth/routes/index.js +27 -0
  56. package/dist/auth/routes/index.js.map +1 -0
  57. package/dist/auth/routes/index.mjs +6 -0
  58. package/dist/auth/routes/index.mjs.map +1 -0
  59. package/dist/auth/schema/index.d.mts +789 -0
  60. package/dist/auth/schema/index.d.ts +789 -0
  61. package/dist/auth/schema/index.js +41 -0
  62. package/dist/auth/schema/index.js.map +1 -0
  63. package/dist/auth/schema/index.mjs +4 -0
  64. package/dist/auth/schema/index.mjs.map +1 -0
  65. package/dist/auth/services/index.d.mts +47 -0
  66. package/dist/auth/services/index.d.ts +47 -0
  67. package/dist/auth/services/index.js +34 -0
  68. package/dist/auth/services/index.js.map +1 -0
  69. package/dist/auth/services/index.mjs +5 -0
  70. package/dist/auth/services/index.mjs.map +1 -0
  71. package/dist/chunk-3RFBUDRA.js +507 -0
  72. package/dist/chunk-3RFBUDRA.js.map +1 -0
  73. package/dist/chunk-3XG5OHFD.mjs +37 -0
  74. package/dist/chunk-3XG5OHFD.mjs.map +1 -0
  75. package/dist/chunk-6BL3AZGD.js +285 -0
  76. package/dist/chunk-6BL3AZGD.js.map +1 -0
  77. package/dist/chunk-6FNUWAIV.js +394 -0
  78. package/dist/chunk-6FNUWAIV.js.map +1 -0
  79. package/dist/chunk-6PRFP5EG.js +171 -0
  80. package/dist/chunk-6PRFP5EG.js.map +1 -0
  81. package/dist/chunk-6VHWOPRR.mjs +90 -0
  82. package/dist/chunk-6VHWOPRR.mjs.map +1 -0
  83. package/dist/chunk-AIKEVVDR.mjs +122 -0
  84. package/dist/chunk-AIKEVVDR.mjs.map +1 -0
  85. package/dist/chunk-APY57REU.js +300 -0
  86. package/dist/chunk-APY57REU.js.map +1 -0
  87. package/dist/chunk-BJTO5JO5.mjs +10 -0
  88. package/dist/chunk-BJTO5JO5.mjs.map +1 -0
  89. package/dist/chunk-C64RY2OW.mjs +295 -0
  90. package/dist/chunk-C64RY2OW.mjs.map +1 -0
  91. package/dist/chunk-DGUM43GV.js +12 -0
  92. package/dist/chunk-DGUM43GV.js.map +1 -0
  93. package/dist/chunk-FV3FNHQY.js +92 -0
  94. package/dist/chunk-FV3FNHQY.js.map +1 -0
  95. package/dist/chunk-GSTLV3MB.mjs +316 -0
  96. package/dist/chunk-GSTLV3MB.mjs.map +1 -0
  97. package/dist/chunk-HEMA7SWK.mjs +212 -0
  98. package/dist/chunk-HEMA7SWK.mjs.map +1 -0
  99. package/dist/chunk-HWJ34NL6.js +43 -0
  100. package/dist/chunk-HWJ34NL6.js.map +1 -0
  101. package/dist/chunk-HXFFYNIF.mjs +385 -0
  102. package/dist/chunk-HXFFYNIF.mjs.map +1 -0
  103. package/dist/chunk-KGRQNEIR.mjs +183 -0
  104. package/dist/chunk-KGRQNEIR.mjs.map +1 -0
  105. package/dist/chunk-KH6RQ4J5.js +28 -0
  106. package/dist/chunk-KH6RQ4J5.js.map +1 -0
  107. package/dist/chunk-KQGP6BTS.mjs +165 -0
  108. package/dist/chunk-KQGP6BTS.mjs.map +1 -0
  109. package/dist/chunk-NMF4ANIC.js +365 -0
  110. package/dist/chunk-NMF4ANIC.js.map +1 -0
  111. package/dist/chunk-O26VCNS3.js +216 -0
  112. package/dist/chunk-O26VCNS3.js.map +1 -0
  113. package/dist/chunk-OLHGZXN3.mjs +86 -0
  114. package/dist/chunk-OLHGZXN3.mjs.map +1 -0
  115. package/dist/chunk-QU5OT4DF.js +88 -0
  116. package/dist/chunk-QU5OT4DF.js.map +1 -0
  117. package/dist/chunk-RCNNVNLT.mjs +356 -0
  118. package/dist/chunk-RCNNVNLT.mjs.map +1 -0
  119. package/dist/chunk-ROEYW4A7.js +186 -0
  120. package/dist/chunk-ROEYW4A7.js.map +1 -0
  121. package/dist/chunk-SVWQN2LR.js +131 -0
  122. package/dist/chunk-SVWQN2LR.js.map +1 -0
  123. package/dist/chunk-TKCYPDWU.js +338 -0
  124. package/dist/chunk-TKCYPDWU.js.map +1 -0
  125. package/dist/chunk-U2L6V7KD.mjs +273 -0
  126. package/dist/chunk-U2L6V7KD.mjs.map +1 -0
  127. package/dist/chunk-YVBU7QDJ.mjs +505 -0
  128. package/dist/chunk-YVBU7QDJ.mjs.map +1 -0
  129. package/dist/chunk-ZGVB35L2.mjs +25 -0
  130. package/dist/chunk-ZGVB35L2.mjs.map +1 -0
  131. package/dist/config/index.d.mts +64 -0
  132. package/dist/config/index.d.ts +64 -0
  133. package/dist/config/index.js +136 -0
  134. package/dist/config/index.js.map +1 -0
  135. package/dist/config/index.mjs +128 -0
  136. package/dist/config/index.mjs.map +1 -0
  137. package/dist/drizzle-auth-service-Bxlovhv8.d.ts +145 -0
  138. package/dist/drizzle-auth-service-DZY2F1sv.d.mts +145 -0
  139. package/dist/enums-Dume-V5Y.d.mts +16 -0
  140. package/dist/enums-Dume-V5Y.d.ts +16 -0
  141. package/dist/i18n/index.d.mts +416 -0
  142. package/dist/i18n/index.d.ts +416 -0
  143. package/dist/i18n/index.js +671 -0
  144. package/dist/i18n/index.js.map +1 -0
  145. package/dist/i18n/index.mjs +650 -0
  146. package/dist/i18n/index.mjs.map +1 -0
  147. package/dist/index-8VoHap_4.d.mts +105 -0
  148. package/dist/index-8VoHap_4.d.ts +105 -0
  149. package/dist/index.d.mts +4 -0
  150. package/dist/index.d.ts +4 -0
  151. package/dist/index.js +84 -0
  152. package/dist/index.js.map +1 -0
  153. package/dist/index.mjs +7 -0
  154. package/dist/index.mjs.map +1 -0
  155. package/dist/logger/index.d.mts +125 -0
  156. package/dist/logger/index.d.ts +125 -0
  157. package/dist/logger/index.js +29 -0
  158. package/dist/logger/index.js.map +1 -0
  159. package/dist/logger/index.mjs +4 -0
  160. package/dist/logger/index.mjs.map +1 -0
  161. package/dist/request/index.d.mts +51 -0
  162. package/dist/request/index.d.ts +51 -0
  163. package/dist/request/index.js +85 -0
  164. package/dist/request/index.js.map +1 -0
  165. package/dist/request/index.mjs +82 -0
  166. package/dist/request/index.mjs.map +1 -0
  167. package/dist/storage/index.d.mts +74 -0
  168. package/dist/storage/index.d.ts +74 -0
  169. package/dist/storage/index.js +46 -0
  170. package/dist/storage/index.js.map +1 -0
  171. package/dist/storage/index.mjs +5 -0
  172. package/dist/storage/index.mjs.map +1 -0
  173. package/dist/types-BINlP9MK.d.mts +286 -0
  174. package/dist/types-BINlP9MK.d.ts +286 -0
  175. package/dist/types-BaZccpvk.d.mts +48 -0
  176. package/dist/types-BaZccpvk.d.ts +48 -0
  177. package/dist/types-CbTsi9CZ.d.mts +31 -0
  178. package/dist/types-CbTsi9CZ.d.ts +31 -0
  179. package/dist/types-CoGG1rNV.d.mts +258 -0
  180. package/dist/types-CoGG1rNV.d.ts +258 -0
  181. package/dist/types-DAxQ1MeY.d.ts +70 -0
  182. package/dist/types-DT8LVCvE.d.mts +70 -0
  183. package/dist/types-DW9qar-w.d.mts +52 -0
  184. package/dist/types-DW9qar-w.d.ts +52 -0
  185. package/dist/universalExport/index.d.mts +235 -0
  186. package/dist/universalExport/index.d.ts +235 -0
  187. package/dist/universalExport/index.js +621 -0
  188. package/dist/universalExport/index.js.map +1 -0
  189. package/dist/universalExport/index.mjs +580 -0
  190. package/dist/universalExport/index.mjs.map +1 -0
  191. package/dist/universalExport/server/index.d.mts +429 -0
  192. package/dist/universalExport/server/index.d.ts +429 -0
  193. package/dist/universalExport/server/index.js +263 -0
  194. package/dist/universalExport/server/index.js.map +1 -0
  195. package/dist/universalExport/server/index.mjs +242 -0
  196. package/dist/universalExport/server/index.mjs.map +1 -0
  197. package/dist/universalFile/index.d.mts +310 -0
  198. package/dist/universalFile/index.d.ts +310 -0
  199. package/dist/universalFile/index.js +811 -0
  200. package/dist/universalFile/index.js.map +1 -0
  201. package/dist/universalFile/index.mjs +736 -0
  202. package/dist/universalFile/index.mjs.map +1 -0
  203. package/dist/universalFile/server/index.d.mts +2428 -0
  204. package/dist/universalFile/server/index.d.ts +2428 -0
  205. package/dist/universalFile/server/index.js +4578 -0
  206. package/dist/universalFile/server/index.js.map +1 -0
  207. package/dist/universalFile/server/index.mjs +4518 -0
  208. package/dist/universalFile/server/index.mjs.map +1 -0
  209. package/dist/useElectronStorage-Dj0rcorG.d.mts +65 -0
  210. package/dist/useElectronStorage-DwnNfIhl.d.ts +65 -0
  211. package/dist/utils/index.d.mts +188 -0
  212. package/dist/utils/index.d.ts +188 -0
  213. package/dist/utils/index.js +42 -0
  214. package/dist/utils/index.js.map +1 -0
  215. package/dist/utils/index.mjs +5 -0
  216. package/dist/utils/index.mjs.map +1 -0
  217. package/package.json +220 -0
  218. package/tailwind.animations.js +34 -0
@@ -0,0 +1,131 @@
1
+ 'use strict';
2
+
3
+ var pgCore = require('drizzle-orm/pg-core');
4
+ var drizzleOrm = require('drizzle-orm');
5
+
6
+ // src/auth/schema/enums.ts
7
+ var userRole = pgCore.pgEnum("UserRole", ["USER", "ADMIN", "SUPER_ADMIN"]);
8
+ var user = pgCore.pgTable(
9
+ "User",
10
+ {
11
+ id: pgCore.text().primaryKey().notNull(),
12
+ email: pgCore.text().notNull(),
13
+ emailVerified: pgCore.boolean().default(false).notNull(),
14
+ username: pgCore.text().notNull(),
15
+ password: pgCore.text(),
16
+ name: pgCore.text(),
17
+ nickname: pgCore.text(),
18
+ image: pgCore.text(),
19
+ avatar: pgCore.text(),
20
+ role: userRole().default("USER").notNull(),
21
+ preferences: pgCore.jsonb(),
22
+ createdAt: pgCore.timestamp({ precision: 3, mode: "string" }).default(drizzleOrm.sql`CURRENT_TIMESTAMP`).notNull(),
23
+ updatedAt: pgCore.timestamp({ precision: 3, mode: "string" }).notNull(),
24
+ twoFactorEnabled: pgCore.boolean().default(false).notNull()
25
+ },
26
+ (table) => [
27
+ pgCore.uniqueIndex("User_email_key").using("btree", table.email.asc().nullsLast().op("text_ops")),
28
+ pgCore.uniqueIndex("User_username_key").using(
29
+ "btree",
30
+ table.username.asc().nullsLast().op("text_ops")
31
+ )
32
+ ]
33
+ );
34
+ var session = pgCore.pgTable(
35
+ "Session",
36
+ {
37
+ id: pgCore.text().primaryKey().notNull(),
38
+ userId: pgCore.text().notNull(),
39
+ token: pgCore.text().notNull(),
40
+ expiresAt: pgCore.timestamp({ precision: 3, mode: "string" }).notNull(),
41
+ ipAddress: pgCore.text(),
42
+ userAgent: pgCore.text(),
43
+ createdAt: pgCore.timestamp({ precision: 3, mode: "string" }).default(drizzleOrm.sql`CURRENT_TIMESTAMP`).notNull(),
44
+ updatedAt: pgCore.timestamp({ precision: 3, mode: "string" }).default(drizzleOrm.sql`CURRENT_TIMESTAMP`).notNull()
45
+ },
46
+ (table) => [
47
+ pgCore.uniqueIndex("Session_token_key").using("btree", table.token.asc().nullsLast().op("text_ops")),
48
+ pgCore.foreignKey({
49
+ columns: [table.userId],
50
+ foreignColumns: [user.id],
51
+ name: "Session_userId_fkey"
52
+ }).onUpdate("cascade").onDelete("cascade")
53
+ ]
54
+ );
55
+ var account = pgCore.pgTable(
56
+ "Account",
57
+ {
58
+ id: pgCore.text().primaryKey().notNull(),
59
+ accountId: pgCore.text().notNull(),
60
+ providerId: pgCore.text().notNull(),
61
+ // 提供商: github, google, wechat 等
62
+ userId: pgCore.text().notNull(),
63
+ accessToken: pgCore.text(),
64
+ refreshToken: pgCore.text(),
65
+ idToken: pgCore.text(),
66
+ accessTokenExpiresAt: pgCore.timestamp({ precision: 3, mode: "string" }),
67
+ refreshTokenExpiresAt: pgCore.timestamp({ precision: 3, mode: "string" }),
68
+ scope: pgCore.text(),
69
+ password: pgCore.text(),
70
+ createdAt: pgCore.timestamp({ precision: 3, mode: "string" }).default(drizzleOrm.sql`CURRENT_TIMESTAMP`).notNull(),
71
+ updatedAt: pgCore.timestamp({ precision: 3, mode: "string" }).notNull()
72
+ },
73
+ (table) => [
74
+ pgCore.uniqueIndex("Account_providerId_accountId_key").using(
75
+ "btree",
76
+ table.providerId.asc().nullsLast().op("text_ops"),
77
+ table.accountId.asc().nullsLast().op("text_ops")
78
+ ),
79
+ pgCore.foreignKey({
80
+ columns: [table.userId],
81
+ foreignColumns: [user.id],
82
+ name: "Account_userId_fkey"
83
+ }).onUpdate("cascade").onDelete("cascade")
84
+ ]
85
+ );
86
+ var verifications = pgCore.pgTable(
87
+ "verifications",
88
+ {
89
+ id: pgCore.text().primaryKey().notNull(),
90
+ identifier: pgCore.text().notNull(),
91
+ // 邮箱或手机号
92
+ value: pgCore.text().notNull(),
93
+ // 验证码
94
+ expiresAt: pgCore.timestamp({ precision: 3, mode: "string" }).notNull(),
95
+ createdAt: pgCore.timestamp({ precision: 3, mode: "string" }).default(drizzleOrm.sql`CURRENT_TIMESTAMP`).notNull()
96
+ },
97
+ (table) => [
98
+ pgCore.uniqueIndex("verifications_identifier_value_key").using(
99
+ "btree",
100
+ table.identifier.asc().nullsLast().op("text_ops"),
101
+ table.value.asc().nullsLast().op("text_ops")
102
+ )
103
+ ]
104
+ );
105
+ var userRelations = drizzleOrm.relations(user, ({ many }) => ({
106
+ sessions: many(session),
107
+ accounts: many(account)
108
+ }));
109
+ var sessionRelations = drizzleOrm.relations(session, ({ one }) => ({
110
+ user: one(user, {
111
+ fields: [session.userId],
112
+ references: [user.id]
113
+ })
114
+ }));
115
+ var accountRelations = drizzleOrm.relations(account, ({ one }) => ({
116
+ user: one(user, {
117
+ fields: [account.userId],
118
+ references: [user.id]
119
+ })
120
+ }));
121
+
122
+ exports.account = account;
123
+ exports.accountRelations = accountRelations;
124
+ exports.session = session;
125
+ exports.sessionRelations = sessionRelations;
126
+ exports.user = user;
127
+ exports.userRelations = userRelations;
128
+ exports.userRole = userRole;
129
+ exports.verifications = verifications;
130
+ //# sourceMappingURL=chunk-SVWQN2LR.js.map
131
+ //# sourceMappingURL=chunk-SVWQN2LR.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/auth/schema/enums.ts","../src/auth/schema/user.ts","../src/auth/schema/session.ts","../src/auth/schema/account.ts","../src/auth/schema/verification.ts","../src/auth/schema/relations.ts"],"names":["pgEnum","pgTable","text","boolean","jsonb","timestamp","sql","uniqueIndex","foreignKey","relations"],"mappings":"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","file":"chunk-SVWQN2LR.js","sourcesContent":["/**\n * Auth Schema - Enums\n * 认证相关的枚举类型定义\n */\n\nimport { pgEnum } from 'drizzle-orm/pg-core';\n\n/**\n * 用户角色枚举\n */\nexport const userRole = pgEnum('UserRole', ['USER', 'ADMIN', 'SUPER_ADMIN']);\n\n/**\n * 类型定义\n */\nexport type UserRole = 'USER' | 'ADMIN' | 'SUPER_ADMIN';\n\n","/**\n * Auth Schema - User Table\n * 用户表定义\n */\n\nimport { pgTable, text, boolean, jsonb, timestamp, uniqueIndex } from 'drizzle-orm/pg-core';\nimport { sql } from 'drizzle-orm';\nimport { userRole } from './enums';\n\n/**\n * 用户表\n */\nexport const user = pgTable(\n 'User',\n {\n id: text().primaryKey().notNull(),\n email: text().notNull(),\n emailVerified: boolean().default(false).notNull(),\n username: text().notNull(),\n password: text(),\n name: text(),\n nickname: text(),\n image: text(),\n avatar: text(),\n role: userRole().default('USER').notNull(),\n preferences: jsonb(),\n createdAt: timestamp({ precision: 3, mode: 'string' })\n .default(sql`CURRENT_TIMESTAMP`)\n .notNull(),\n updatedAt: timestamp({ precision: 3, mode: 'string' }).notNull(),\n twoFactorEnabled: boolean().default(false).notNull(),\n },\n (table) => [\n uniqueIndex('User_email_key').using('btree', table.email.asc().nullsLast().op('text_ops')),\n uniqueIndex('User_username_key').using(\n 'btree',\n table.username.asc().nullsLast().op('text_ops')\n ),\n ]\n);\n\n/**\n * 类型定义\n */\nexport type User = typeof user.$inferSelect;\nexport type NewUser = typeof user.$inferInsert;\n\n","/**\n * Auth Schema - Session Table\n * 会话表定义\n */\n\nimport {\n pgTable,\n text,\n timestamp,\n uniqueIndex,\n foreignKey,\n} from 'drizzle-orm/pg-core';\nimport { sql } from 'drizzle-orm';\nimport { user } from './user';\n\n/**\n * 会话表\n */\nexport const session = pgTable(\n 'Session',\n {\n id: text().primaryKey().notNull(),\n userId: text().notNull(),\n token: text().notNull(),\n expiresAt: timestamp({ precision: 3, mode: 'string' }).notNull(),\n ipAddress: text(),\n userAgent: text(),\n createdAt: timestamp({ precision: 3, mode: 'string' })\n .default(sql`CURRENT_TIMESTAMP`)\n .notNull(),\n updatedAt: timestamp({ precision: 3, mode: 'string' })\n .default(sql`CURRENT_TIMESTAMP`)\n .notNull(),\n },\n (table) => [\n uniqueIndex('Session_token_key').using('btree', table.token.asc().nullsLast().op('text_ops')),\n foreignKey({\n columns: [table.userId],\n foreignColumns: [user.id],\n name: 'Session_userId_fkey',\n })\n .onUpdate('cascade')\n .onDelete('cascade'),\n ]\n);\n\n/**\n * 类型定义\n */\nexport type Session = typeof session.$inferSelect;\nexport type NewSession = typeof session.$inferInsert;\n\n","/**\n * Auth Schema - Account Table\n * 第三方账号关联表定义\n */\n\nimport {\n pgTable,\n text,\n timestamp,\n uniqueIndex,\n foreignKey,\n} from 'drizzle-orm/pg-core';\nimport { sql } from 'drizzle-orm';\nimport { user } from './user';\n\n/**\n * 第三方账号表(支持 OAuth 登录)\n */\nexport const account = pgTable(\n 'Account',\n {\n id: text().primaryKey().notNull(),\n accountId: text().notNull(),\n providerId: text().notNull(), // 提供商: github, google, wechat 等\n userId: text().notNull(),\n accessToken: text(),\n refreshToken: text(),\n idToken: text(),\n accessTokenExpiresAt: timestamp({ precision: 3, mode: 'string' }),\n refreshTokenExpiresAt: timestamp({ precision: 3, mode: 'string' }),\n scope: text(),\n password: text(),\n createdAt: timestamp({ precision: 3, mode: 'string' })\n .default(sql`CURRENT_TIMESTAMP`)\n .notNull(),\n updatedAt: timestamp({ precision: 3, mode: 'string' }).notNull(),\n },\n (table) => [\n uniqueIndex('Account_providerId_accountId_key').using(\n 'btree',\n table.providerId.asc().nullsLast().op('text_ops'),\n table.accountId.asc().nullsLast().op('text_ops')\n ),\n foreignKey({\n columns: [table.userId],\n foreignColumns: [user.id],\n name: 'Account_userId_fkey',\n })\n .onUpdate('cascade')\n .onDelete('cascade'),\n ]\n);\n\n/**\n * 类型定义\n */\nexport type Account = typeof account.$inferSelect;\nexport type NewAccount = typeof account.$inferInsert;\n\n","/**\n * Auth Schema - Verification Table\n * 验证码表定义\n */\n\nimport { pgTable, text, timestamp, uniqueIndex } from 'drizzle-orm/pg-core';\nimport { sql } from 'drizzle-orm';\n\n/**\n * 验证码表(邮箱验证、密码重置等)\n */\nexport const verifications = pgTable(\n 'verifications',\n {\n id: text().primaryKey().notNull(),\n identifier: text().notNull(), // 邮箱或手机号\n value: text().notNull(), // 验证码\n expiresAt: timestamp({ precision: 3, mode: 'string' }).notNull(),\n createdAt: timestamp({ precision: 3, mode: 'string' })\n .default(sql`CURRENT_TIMESTAMP`)\n .notNull(),\n },\n (table) => [\n uniqueIndex('verifications_identifier_value_key').using(\n 'btree',\n table.identifier.asc().nullsLast().op('text_ops'),\n table.value.asc().nullsLast().op('text_ops')\n ),\n ]\n);\n\n/**\n * 类型定义\n */\nexport type Verification = typeof verifications.$inferSelect;\nexport type NewVerification = typeof verifications.$inferInsert;\n\n","/**\n * Auth Schema - Relations\n * 表关系定义\n */\n\nimport { relations } from 'drizzle-orm';\nimport { user } from './user';\nimport { session } from './session';\nimport { account } from './account';\n\n/**\n * User 表关系\n */\nexport const userRelations = relations(user, ({ many }) => ({\n sessions: many(session),\n accounts: many(account),\n}));\n\n/**\n * Session 表关系\n */\nexport const sessionRelations = relations(session, ({ one }) => ({\n user: one(user, {\n fields: [session.userId],\n references: [user.id],\n }),\n}));\n\n/**\n * Account 表关系\n */\nexport const accountRelations = relations(account, ({ one }) => ({\n user: one(user, {\n fields: [account.userId],\n references: [user.id],\n }),\n}));\n\n"]}
@@ -0,0 +1,338 @@
1
+ 'use strict';
2
+
3
+ var chunkKH6RQ4J5_js = require('./chunk-KH6RQ4J5.js');
4
+ var chunk6PRFP5EG_js = require('./chunk-6PRFP5EG.js');
5
+ var fs = require('fs');
6
+ var path = require('path');
7
+ var promises = require('stream/promises');
8
+
9
+ function _interopNamespace(e) {
10
+ if (e && e.__esModule) return e;
11
+ var n = Object.create(null);
12
+ if (e) {
13
+ Object.keys(e).forEach(function (k) {
14
+ if (k !== 'default') {
15
+ var d = Object.getOwnPropertyDescriptor(e, k);
16
+ Object.defineProperty(n, k, d.get ? d : {
17
+ enumerable: true,
18
+ get: function () { return e[k]; }
19
+ });
20
+ }
21
+ });
22
+ }
23
+ n.default = e;
24
+ return Object.freeze(n);
25
+ }
26
+
27
+ var path__namespace = /*#__PURE__*/_interopNamespace(path);
28
+
29
+ var logger = chunk6PRFP5EG_js.createLogger("LocalStorageProvider");
30
+ var LocalStorageProvider = class {
31
+ constructor() {
32
+ this.type = "local";
33
+ this.config = null;
34
+ this.isInitialized = false;
35
+ }
36
+ /**
37
+ * 初始化存储提供者
38
+ */
39
+ async initialize(config) {
40
+ if (config.type !== "local") {
41
+ throw new chunkKH6RQ4J5_js.StorageProviderError("\u914D\u7F6E\u7C7B\u578B\u4E0D\u5339\u914D\uFF1A\u671F\u671B local");
42
+ }
43
+ this.config = config;
44
+ logger.info(`\u{1F4C2} [LocalStorageProvider] \u521D\u59CB\u5316\u672C\u5730\u5B58\u50A8\uFF0C\u6839\u76EE\u5F55: ${this.config.rootPath}`);
45
+ try {
46
+ await this.ensureDirectoryExists(this.config.rootPath);
47
+ await this.validateDirectoryAccess(this.config.rootPath);
48
+ this.isInitialized = true;
49
+ logger.info("\u2705 [LocalStorageProvider] \u672C\u5730\u5B58\u50A8\u521D\u59CB\u5316\u5B8C\u6210");
50
+ } catch (error) {
51
+ logger.error("\u274C [LocalStorageProvider] \u672C\u5730\u5B58\u50A8\u521D\u59CB\u5316\u5931\u8D25:", error);
52
+ throw new chunkKH6RQ4J5_js.StorageProviderError(
53
+ `\u672C\u5730\u5B58\u50A8\u521D\u59CB\u5316\u5931\u8D25: ${error instanceof Error ? error.message : "\u672A\u77E5\u9519\u8BEF"}`
54
+ );
55
+ }
56
+ }
57
+ /**
58
+ * 上传文件
59
+ */
60
+ async upload(fileInfo, filePath) {
61
+ this.ensureInitialized();
62
+ const startTime = Date.now();
63
+ logger.info(`\u{1F4E4} [LocalStorageProvider] \u5F00\u59CB\u4E0A\u4F20\u6587\u4EF6: ${filePath}`);
64
+ try {
65
+ const fullPath = this.getFullPath(filePath);
66
+ await this.ensureDirectoryExists(path__namespace.dirname(fullPath));
67
+ const buffer = Buffer.from(await fileInfo.file.arrayBuffer());
68
+ await fs.promises.writeFile(fullPath, buffer);
69
+ const stats = await fs.promises.stat(fullPath);
70
+ if (stats.size !== fileInfo.file.size) {
71
+ throw new chunkKH6RQ4J5_js.StorageProviderError(
72
+ `\u6587\u4EF6\u5927\u5C0F\u4E0D\u5339\u914D: \u671F\u671B ${fileInfo.file.size}, \u5B9E\u9645 ${stats.size}`
73
+ );
74
+ }
75
+ const accessUrl = this.generateAccessUrl(filePath);
76
+ const uploadTime = Date.now() - startTime;
77
+ logger.info(`\u2705 [LocalStorageProvider] \u6587\u4EF6\u4E0A\u4F20\u5B8C\u6210: ${filePath}, \u8017\u65F6: ${uploadTime}ms`);
78
+ return {
79
+ success: true,
80
+ path: filePath,
81
+ url: accessUrl,
82
+ size: stats.size,
83
+ data: {
84
+ fullPath,
85
+ uploadTime
86
+ }
87
+ };
88
+ } catch (error) {
89
+ logger.error(`\u274C [LocalStorageProvider] \u6587\u4EF6\u4E0A\u4F20\u5931\u8D25: ${filePath}:`, error);
90
+ return {
91
+ success: false,
92
+ error: error instanceof Error ? error.message : "\u4E0A\u4F20\u5931\u8D25"
93
+ };
94
+ }
95
+ }
96
+ /**
97
+ * 下载文件
98
+ */
99
+ async download(path2) {
100
+ this.ensureInitialized();
101
+ logger.info(`\u{1F4E5} [LocalStorageProvider] \u5F00\u59CB\u4E0B\u8F7D\u6587\u4EF6: ${path2}`);
102
+ try {
103
+ const fullPath = this.getFullPath(path2);
104
+ if (!fs.existsSync(fullPath)) {
105
+ throw new chunkKH6RQ4J5_js.StorageProviderError(`\u6587\u4EF6\u4E0D\u5B58\u5728: ${path2}`);
106
+ }
107
+ const buffer = await fs.promises.readFile(fullPath);
108
+ logger.info(`\u2705 [LocalStorageProvider] \u6587\u4EF6\u4E0B\u8F7D\u5B8C\u6210: ${path2}, \u5927\u5C0F: ${buffer.length}`);
109
+ return buffer;
110
+ } catch (error) {
111
+ logger.error(`\u274C [LocalStorageProvider] \u6587\u4EF6\u4E0B\u8F7D\u5931\u8D25: ${path2}:`, error);
112
+ throw new chunkKH6RQ4J5_js.StorageProviderError(
113
+ `\u6587\u4EF6\u4E0B\u8F7D\u5931\u8D25: ${error instanceof Error ? error.message : "\u672A\u77E5\u9519\u8BEF"}`
114
+ );
115
+ }
116
+ }
117
+ /**
118
+ * 删除文件
119
+ */
120
+ async delete(path2) {
121
+ this.ensureInitialized();
122
+ logger.info(`\u{1F5D1}\uFE0F [LocalStorageProvider] \u5F00\u59CB\u5220\u9664\u6587\u4EF6: ${path2}`);
123
+ try {
124
+ const fullPath = this.getFullPath(path2);
125
+ if (!fs.existsSync(fullPath)) {
126
+ logger.warn(`\u26A0\uFE0F [LocalStorageProvider] \u6587\u4EF6\u4E0D\u5B58\u5728: ${path2}`);
127
+ return {
128
+ success: true,
129
+ // 文件不存在也视为删除成功
130
+ data: { reason: "file_not_exists" }
131
+ };
132
+ }
133
+ await fs.promises.unlink(fullPath);
134
+ logger.info(`\u2705 [LocalStorageProvider] \u6587\u4EF6\u5220\u9664\u5B8C\u6210: ${path2}`);
135
+ return {
136
+ success: true,
137
+ data: { deletedPath: fullPath }
138
+ };
139
+ } catch (error) {
140
+ logger.error(`\u274C [LocalStorageProvider] \u6587\u4EF6\u5220\u9664\u5931\u8D25: ${path2}:`, error);
141
+ return {
142
+ success: false,
143
+ error: error instanceof Error ? error.message : "\u5220\u9664\u5931\u8D25"
144
+ };
145
+ }
146
+ }
147
+ /**
148
+ * 获取文件信息
149
+ */
150
+ async getFileInfo(path2) {
151
+ this.ensureInitialized();
152
+ try {
153
+ const fullPath = this.getFullPath(path2);
154
+ if (!fs.existsSync(fullPath)) {
155
+ return {
156
+ success: false,
157
+ error: "\u6587\u4EF6\u4E0D\u5B58\u5728"
158
+ };
159
+ }
160
+ const stats = await fs.promises.stat(fullPath);
161
+ return {
162
+ success: true,
163
+ size: stats.size,
164
+ data: {
165
+ fullPath,
166
+ size: stats.size,
167
+ mtime: stats.mtime,
168
+ ctime: stats.ctime,
169
+ isFile: stats.isFile(),
170
+ isDirectory: stats.isDirectory()
171
+ }
172
+ };
173
+ } catch (error) {
174
+ return {
175
+ success: false,
176
+ error: error instanceof Error ? error.message : "\u83B7\u53D6\u6587\u4EF6\u4FE1\u606F\u5931\u8D25"
177
+ };
178
+ }
179
+ }
180
+ /**
181
+ * 生成访问URL
182
+ */
183
+ async getAccessUrl(path2, _expiresIn) {
184
+ this.ensureInitialized();
185
+ return this.generateAccessUrl(path2);
186
+ }
187
+ /**
188
+ * 生成预签名上传URL
189
+ */
190
+ async getUploadUrl(path2, _expiresIn) {
191
+ this.ensureInitialized();
192
+ logger.warn(`\u26A0\uFE0F [LocalStorageProvider] \u672C\u5730\u5B58\u50A8\u4E0D\u652F\u6301\u9884\u7B7E\u540D\u4E0A\u4F20URL`);
193
+ return this.generateAccessUrl(path2);
194
+ }
195
+ /**
196
+ * 检查文件是否存在
197
+ */
198
+ async exists(path2) {
199
+ this.ensureInitialized();
200
+ try {
201
+ const fullPath = this.getFullPath(path2);
202
+ return fs.existsSync(fullPath);
203
+ } catch {
204
+ return false;
205
+ }
206
+ }
207
+ /**
208
+ * 列出文件
209
+ */
210
+ async list(prefix, maxKeys) {
211
+ this.ensureInitialized();
212
+ try {
213
+ const fullPrefix = this.getFullPath(prefix);
214
+ const baseDir = path__namespace.dirname(fullPrefix);
215
+ const filePattern = path__namespace.basename(fullPrefix);
216
+ if (!fs.existsSync(baseDir)) {
217
+ return [];
218
+ }
219
+ const entries = await fs.promises.readdir(baseDir, { withFileTypes: true });
220
+ let files = entries.filter((entry) => entry.isFile()).map((entry) => entry.name).filter((name) => name.startsWith(filePattern)).map((name) => path__namespace.join(path__namespace.dirname(prefix), name));
221
+ if (maxKeys && maxKeys > 0) {
222
+ files = files.slice(0, maxKeys);
223
+ }
224
+ return files;
225
+ } catch (error) {
226
+ logger.error(`\u274C [LocalStorageProvider] \u5217\u51FA\u6587\u4EF6\u5931\u8D25: ${prefix}:`, error);
227
+ return [];
228
+ }
229
+ }
230
+ // ============= 私有方法 =============
231
+ /**
232
+ * 确保已初始化
233
+ */
234
+ ensureInitialized() {
235
+ if (!this.isInitialized || !this.config) {
236
+ throw new chunkKH6RQ4J5_js.StorageProviderError("\u5B58\u50A8\u63D0\u4F9B\u8005\u672A\u521D\u59CB\u5316");
237
+ }
238
+ }
239
+ /**
240
+ * 获取完整文件路径
241
+ */
242
+ getFullPath(relativePath) {
243
+ if (!this.config) {
244
+ throw new chunkKH6RQ4J5_js.StorageProviderError("\u5B58\u50A8\u63D0\u4F9B\u8005\u672A\u521D\u59CB\u5316");
245
+ }
246
+ const normalizedPath = path__namespace.normalize(relativePath);
247
+ if (normalizedPath.includes("..")) {
248
+ throw new chunkKH6RQ4J5_js.StorageProviderError("\u975E\u6CD5\u8DEF\u5F84\uFF1A\u4E0D\u5141\u8BB8\u4F7F\u7528\u7236\u76EE\u5F55\u5F15\u7528");
249
+ }
250
+ return path__namespace.join(this.config.rootPath, normalizedPath);
251
+ }
252
+ /**
253
+ * 生成访问URL
254
+ */
255
+ generateAccessUrl(relativePath) {
256
+ if (!this.config) {
257
+ throw new chunkKH6RQ4J5_js.StorageProviderError("\u5B58\u50A8\u63D0\u4F9B\u8005\u672A\u521D\u59CB\u5316");
258
+ }
259
+ const urlPath = relativePath.replace(/\\/g, "/");
260
+ const normalizedUrlPath = urlPath.startsWith("/") ? urlPath : `/${urlPath}`;
261
+ return `${this.config.baseUrl}${normalizedUrlPath}`;
262
+ }
263
+ /**
264
+ * 确保目录存在
265
+ */
266
+ async ensureDirectoryExists(dirPath) {
267
+ try {
268
+ await fs.promises.mkdir(dirPath, { recursive: true });
269
+ } catch (error) {
270
+ if (error instanceof Error && "code" in error && error.code !== "EEXIST") {
271
+ throw error;
272
+ }
273
+ }
274
+ }
275
+ /**
276
+ * 验证目录访问权限
277
+ */
278
+ async validateDirectoryAccess(dirPath) {
279
+ try {
280
+ await fs.promises.access(dirPath, fs.promises.constants.R_OK | fs.promises.constants.W_OK);
281
+ } catch (error) {
282
+ throw new chunkKH6RQ4J5_js.StorageProviderError(
283
+ `\u76EE\u5F55\u8BBF\u95EE\u6743\u9650\u4E0D\u8DB3: ${dirPath}, ${error instanceof Error ? error.message : "\u672A\u77E5\u9519\u8BEF"}`
284
+ );
285
+ }
286
+ }
287
+ /**
288
+ * 流式上传大文件(可选实现)
289
+ */
290
+ async uploadStream(readableStream, filePath) {
291
+ this.ensureInitialized();
292
+ const startTime = Date.now();
293
+ logger.info(`\u{1F4E4} [LocalStorageProvider] \u5F00\u59CB\u6D41\u5F0F\u4E0A\u4F20\u6587\u4EF6: ${filePath}`);
294
+ try {
295
+ const fullPath = this.getFullPath(filePath);
296
+ await this.ensureDirectoryExists(path__namespace.dirname(fullPath));
297
+ const writeStream = fs.createWriteStream(fullPath);
298
+ await promises.pipeline(readableStream, writeStream);
299
+ const stats = await fs.promises.stat(fullPath);
300
+ const accessUrl = this.generateAccessUrl(filePath);
301
+ const uploadTime = Date.now() - startTime;
302
+ logger.info(
303
+ `\u2705 [LocalStorageProvider] \u6D41\u5F0F\u4E0A\u4F20\u5B8C\u6210: ${filePath}, \u5927\u5C0F: ${stats.size}, \u8017\u65F6: ${uploadTime}ms`
304
+ );
305
+ return {
306
+ success: true,
307
+ path: filePath,
308
+ url: accessUrl,
309
+ size: stats.size,
310
+ data: {
311
+ fullPath,
312
+ uploadTime
313
+ }
314
+ };
315
+ } catch (error) {
316
+ logger.error(`\u274C [LocalStorageProvider] \u6D41\u5F0F\u4E0A\u4F20\u5931\u8D25: ${filePath}:`, error);
317
+ return {
318
+ success: false,
319
+ error: error instanceof Error ? error.message : "\u6D41\u5F0F\u4E0A\u4F20\u5931\u8D25"
320
+ };
321
+ }
322
+ }
323
+ /**
324
+ * 流式下载大文件(可选实现)
325
+ */
326
+ createDownloadStream(path2) {
327
+ this.ensureInitialized();
328
+ const fullPath = this.getFullPath(path2);
329
+ if (!fs.existsSync(fullPath)) {
330
+ throw new chunkKH6RQ4J5_js.StorageProviderError(`\u6587\u4EF6\u4E0D\u5B58\u5728: ${path2}`);
331
+ }
332
+ return fs.createReadStream(fullPath);
333
+ }
334
+ };
335
+
336
+ exports.LocalStorageProvider = LocalStorageProvider;
337
+ //# sourceMappingURL=chunk-TKCYPDWU.js.map
338
+ //# sourceMappingURL=chunk-TKCYPDWU.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/universalFile/server/providers/LocalStorageProvider.ts"],"names":["createLogger","StorageProviderError","path","fs","existsSync","createWriteStream","pipeline","createReadStream"],"mappings":"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","file":"chunk-TKCYPDWU.js","sourcesContent":["/**\n * 本地存储提供者实现\n */\n\nimport { promises as fs } from 'fs';\nimport { existsSync, createReadStream, createWriteStream } from 'fs';\nimport * as path from 'path';\nimport { pipeline } from 'stream/promises';\nimport { createLogger } from '../../../logger';\n\nimport type {\n IStorageProvider,\n StorageConfig,\n LocalStorageConfig,\n StorageResult,\n UploadFileInfo,\n StorageType,\n} from '../types';\n\nimport { StorageProviderError } from '../types';\n\nconst logger = createLogger('LocalStorageProvider');\n\n/**\n * 本地文件系统存储提供者\n */\nexport class LocalStorageProvider implements IStorageProvider {\n readonly type: StorageType = 'local';\n\n private config: LocalStorageConfig | null = null;\n private isInitialized = false;\n\n /**\n * 初始化存储提供者\n */\n async initialize(config: StorageConfig): Promise<void> {\n if (config.type !== 'local') {\n throw new StorageProviderError('配置类型不匹配:期望 local');\n }\n\n this.config = config as LocalStorageConfig;\n\n logger.info(`📂 [LocalStorageProvider] 初始化本地存储,根目录: ${this.config.rootPath}`);\n\n try {\n // 确保根目录存在\n await this.ensureDirectoryExists(this.config.rootPath);\n\n // 验证目录访问权限\n await this.validateDirectoryAccess(this.config.rootPath);\n\n this.isInitialized = true;\n logger.info('✅ [LocalStorageProvider] 本地存储初始化完成');\n } catch (error) {\n logger.error('❌ [LocalStorageProvider] 本地存储初始化失败:', error);\n throw new StorageProviderError(\n `本地存储初始化失败: ${error instanceof Error ? error.message : '未知错误'}`\n );\n }\n }\n\n /**\n * 上传文件\n */\n async upload(fileInfo: UploadFileInfo, filePath: string): Promise<StorageResult> {\n this.ensureInitialized();\n\n const startTime = Date.now();\n logger.info(`📤 [LocalStorageProvider] 开始上传文件: ${filePath}`);\n\n try {\n // 生成完整文件路径\n const fullPath = this.getFullPath(filePath);\n\n // 确保父目录存在\n await this.ensureDirectoryExists(path.dirname(fullPath));\n\n // 将File对象转换为Buffer\n const buffer = Buffer.from(await fileInfo.file.arrayBuffer());\n\n // 写入文件\n await fs.writeFile(fullPath, buffer);\n\n // 验证文件写入\n const stats = await fs.stat(fullPath);\n\n if (stats.size !== fileInfo.file.size) {\n throw new StorageProviderError(\n `文件大小不匹配: 期望 ${fileInfo.file.size}, 实际 ${stats.size}`\n );\n }\n\n // 生成访问URL\n const accessUrl = this.generateAccessUrl(filePath);\n\n const uploadTime = Date.now() - startTime;\n logger.info(`✅ [LocalStorageProvider] 文件上传完成: ${filePath}, 耗时: ${uploadTime}ms`);\n\n return {\n success: true,\n path: filePath,\n url: accessUrl,\n size: stats.size,\n data: {\n fullPath,\n uploadTime,\n },\n };\n } catch (error) {\n logger.error(`❌ [LocalStorageProvider] 文件上传失败: ${filePath}:`, error);\n\n return {\n success: false,\n error: error instanceof Error ? error.message : '上传失败',\n };\n }\n }\n\n /**\n * 下载文件\n */\n async download(path: string): Promise<Buffer> {\n this.ensureInitialized();\n\n logger.info(`📥 [LocalStorageProvider] 开始下载文件: ${path}`);\n\n try {\n const fullPath = this.getFullPath(path);\n\n // 检查文件是否存在\n if (!existsSync(fullPath)) {\n throw new StorageProviderError(`文件不存在: ${path}`);\n }\n\n // 读取文件\n const buffer = await fs.readFile(fullPath);\n\n logger.info(`✅ [LocalStorageProvider] 文件下载完成: ${path}, 大小: ${buffer.length}`);\n\n return buffer;\n } catch (error) {\n logger.error(`❌ [LocalStorageProvider] 文件下载失败: ${path}:`, error);\n throw new StorageProviderError(\n `文件下载失败: ${error instanceof Error ? error.message : '未知错误'}`\n );\n }\n }\n\n /**\n * 删除文件\n */\n async delete(path: string): Promise<StorageResult> {\n this.ensureInitialized();\n\n logger.info(`🗑️ [LocalStorageProvider] 开始删除文件: ${path}`);\n\n try {\n const fullPath = this.getFullPath(path);\n\n // 检查文件是否存在\n if (!existsSync(fullPath)) {\n logger.warn(`⚠️ [LocalStorageProvider] 文件不存在: ${path}`);\n return {\n success: true, // 文件不存在也视为删除成功\n data: { reason: 'file_not_exists' },\n };\n }\n\n // 删除文件\n await fs.unlink(fullPath);\n\n logger.info(`✅ [LocalStorageProvider] 文件删除完成: ${path}`);\n\n return {\n success: true,\n data: { deletedPath: fullPath },\n };\n } catch (error) {\n logger.error(`❌ [LocalStorageProvider] 文件删除失败: ${path}:`, error);\n\n return {\n success: false,\n error: error instanceof Error ? error.message : '删除失败',\n };\n }\n }\n\n /**\n * 获取文件信息\n */\n async getFileInfo(path: string): Promise<StorageResult> {\n this.ensureInitialized();\n\n try {\n const fullPath = this.getFullPath(path);\n\n if (!existsSync(fullPath)) {\n return {\n success: false,\n error: '文件不存在',\n };\n }\n\n const stats = await fs.stat(fullPath);\n\n return {\n success: true,\n size: stats.size,\n data: {\n fullPath,\n size: stats.size,\n mtime: stats.mtime,\n ctime: stats.ctime,\n isFile: stats.isFile(),\n isDirectory: stats.isDirectory(),\n },\n };\n } catch (error) {\n return {\n success: false,\n error: error instanceof Error ? error.message : '获取文件信息失败',\n };\n }\n }\n\n /**\n * 生成访问URL\n */\n async getAccessUrl(path: string, _expiresIn?: number): Promise<string> {\n this.ensureInitialized();\n\n // 本地存储不支持过期时间,忽略expiresIn参数\n return this.generateAccessUrl(path);\n }\n\n /**\n * 生成预签名上传URL\n */\n async getUploadUrl(path: string, _expiresIn?: number): Promise<string> {\n this.ensureInitialized();\n\n // 本地存储不支持预签名上传,返回普通访问URL\n logger.warn(`⚠️ [LocalStorageProvider] 本地存储不支持预签名上传URL`);\n return this.generateAccessUrl(path);\n }\n\n /**\n * 检查文件是否存在\n */\n async exists(path: string): Promise<boolean> {\n this.ensureInitialized();\n\n try {\n const fullPath = this.getFullPath(path);\n return existsSync(fullPath);\n } catch {\n return false;\n }\n }\n\n /**\n * 列出文件\n */\n async list(prefix: string, maxKeys?: number): Promise<string[]> {\n this.ensureInitialized();\n\n try {\n const fullPrefix = this.getFullPath(prefix);\n const baseDir = path.dirname(fullPrefix);\n const filePattern = path.basename(fullPrefix);\n\n if (!existsSync(baseDir)) {\n return [];\n }\n\n const entries = await fs.readdir(baseDir, { withFileTypes: true });\n let files = entries\n .filter((entry) => entry.isFile())\n .map((entry) => entry.name)\n .filter((name) => name.startsWith(filePattern))\n .map((name) => path.join(path.dirname(prefix), name));\n\n // 限制返回数量\n if (maxKeys && maxKeys > 0) {\n files = files.slice(0, maxKeys);\n }\n\n return files;\n } catch (error) {\n logger.error(`❌ [LocalStorageProvider] 列出文件失败: ${prefix}:`, error);\n return [];\n }\n }\n\n // ============= 私有方法 =============\n\n /**\n * 确保已初始化\n */\n private ensureInitialized(): void {\n if (!this.isInitialized || !this.config) {\n throw new StorageProviderError('存储提供者未初始化');\n }\n }\n\n /**\n * 获取完整文件路径\n */\n private getFullPath(relativePath: string): string {\n if (!this.config) {\n throw new StorageProviderError('存储提供者未初始化');\n }\n\n // 防止路径遍历攻击\n const normalizedPath = path.normalize(relativePath);\n if (normalizedPath.includes('..')) {\n throw new StorageProviderError('非法路径:不允许使用父目录引用');\n }\n\n return path.join(this.config.rootPath, normalizedPath);\n }\n\n /**\n * 生成访问URL\n */\n private generateAccessUrl(relativePath: string): string {\n if (!this.config) {\n throw new StorageProviderError('存储提供者未初始化');\n }\n\n // 规范化路径分隔符为URL格式\n const urlPath = relativePath.replace(/\\\\/g, '/');\n\n // 确保URL路径以/开头\n const normalizedUrlPath = urlPath.startsWith('/') ? urlPath : `/${urlPath}`;\n\n return `${this.config.baseUrl}${normalizedUrlPath}`;\n }\n\n /**\n * 确保目录存在\n */\n private async ensureDirectoryExists(dirPath: string): Promise<void> {\n try {\n await fs.mkdir(dirPath, { recursive: true });\n } catch (error) {\n // 如果目录已存在,忽略错误\n if (error instanceof Error && 'code' in error && error.code !== 'EEXIST') {\n throw error;\n }\n }\n }\n\n /**\n * 验证目录访问权限\n */\n private async validateDirectoryAccess(dirPath: string): Promise<void> {\n try {\n // 检查读写权限\n await fs.access(dirPath, fs.constants.R_OK | fs.constants.W_OK);\n } catch (error) {\n throw new StorageProviderError(\n `目录访问权限不足: ${dirPath}, ${error instanceof Error ? error.message : '未知错误'}`\n );\n }\n }\n\n /**\n * 流式上传大文件(可选实现)\n */\n async uploadStream(\n readableStream: NodeJS.ReadableStream,\n filePath: string\n ): Promise<StorageResult> {\n this.ensureInitialized();\n\n const startTime = Date.now();\n logger.info(`📤 [LocalStorageProvider] 开始流式上传文件: ${filePath}`);\n\n try {\n const fullPath = this.getFullPath(filePath);\n\n // 确保父目录存在\n await this.ensureDirectoryExists(path.dirname(fullPath));\n\n // 创建写入流\n const writeStream = createWriteStream(fullPath);\n\n // 使用pipeline进行流式传输\n await pipeline(readableStream, writeStream);\n\n // 获取文件信息\n const stats = await fs.stat(fullPath);\n\n // 生成访问URL\n const accessUrl = this.generateAccessUrl(filePath);\n\n const uploadTime = Date.now() - startTime;\n logger.info(\n `✅ [LocalStorageProvider] 流式上传完成: ${filePath}, 大小: ${stats.size}, 耗时: ${uploadTime}ms`\n );\n\n return {\n success: true,\n path: filePath,\n url: accessUrl,\n size: stats.size,\n data: {\n fullPath,\n uploadTime,\n },\n };\n } catch (error) {\n logger.error(`❌ [LocalStorageProvider] 流式上传失败: ${filePath}:`, error);\n\n return {\n success: false,\n error: error instanceof Error ? error.message : '流式上传失败',\n };\n }\n }\n\n /**\n * 流式下载大文件(可选实现)\n */\n createDownloadStream(path: string): NodeJS.ReadableStream {\n this.ensureInitialized();\n\n const fullPath = this.getFullPath(path);\n\n if (!existsSync(fullPath)) {\n throw new StorageProviderError(`文件不存在: ${path}`);\n }\n\n return createReadStream(fullPath);\n }\n}\n\n"]}