saas-backend-kit 1.0.0 → 1.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (42) hide show
  1. package/README.md +117 -370
  2. package/copy-dts.js +59 -0
  3. package/dist/auth/index.js +6 -1
  4. package/dist/auth/index.js.map +1 -1
  5. package/dist/auth/index.mjs +6 -1
  6. package/dist/auth/index.mjs.map +1 -1
  7. package/dist/config/index.js +6 -1
  8. package/dist/config/index.js.map +1 -1
  9. package/dist/config/index.mjs +6 -1
  10. package/dist/config/index.mjs.map +1 -1
  11. package/dist/index.d.ts +1 -0
  12. package/dist/index.js +184 -1
  13. package/dist/index.js.map +1 -1
  14. package/dist/index.mjs +183 -2
  15. package/dist/index.mjs.map +1 -1
  16. package/dist/logger/index.js +6 -1
  17. package/dist/logger/index.js.map +1 -1
  18. package/dist/logger/index.mjs +6 -1
  19. package/dist/logger/index.mjs.map +1 -1
  20. package/dist/notifications/index.js +6 -1
  21. package/dist/notifications/index.js.map +1 -1
  22. package/dist/notifications/index.mjs +6 -1
  23. package/dist/notifications/index.mjs.map +1 -1
  24. package/dist/queue/index.js +6 -1
  25. package/dist/queue/index.js.map +1 -1
  26. package/dist/queue/index.mjs +6 -1
  27. package/dist/queue/index.mjs.map +1 -1
  28. package/dist/rate-limit/index.js +6 -1
  29. package/dist/rate-limit/index.js.map +1 -1
  30. package/dist/rate-limit/index.mjs +6 -1
  31. package/dist/rate-limit/index.mjs.map +1 -1
  32. package/dist/upload/index.d.ts +57 -0
  33. package/dist/upload/index.js +344 -0
  34. package/dist/upload/index.js.map +1 -0
  35. package/dist/upload/index.mjs +334 -0
  36. package/dist/upload/index.mjs.map +1 -0
  37. package/package.json +12 -2
  38. package/saas-banner.svg +239 -0
  39. package/src/config/index.ts +5 -0
  40. package/src/index.ts +2 -0
  41. package/src/upload/index.ts +268 -0
  42. package/tsup.config.ts +2 -1
package/dist/index.js CHANGED
@@ -7,6 +7,8 @@ var jwt = require('jsonwebtoken');
7
7
  var bcrypt = require('bcryptjs');
8
8
  var nodemailer = require('nodemailer');
9
9
  var express = require('express');
10
+ var clientS3 = require('@aws-sdk/client-s3');
11
+ var s3RequestPresigner = require('@aws-sdk/s3-request-presigner');
10
12
 
11
13
  function _interopDefault (e) { return e && e.__esModule ? e : { default: e }; }
12
14
 
@@ -68,7 +70,12 @@ var init_config = __esm({
68
70
  SLACK_WEBHOOK_URL: zod.z.string().optional(),
69
71
  RATE_LIMIT_WINDOW: zod.z.string().default("1m"),
70
72
  RATE_LIMIT_LIMIT: zod.z.string().default("100"),
71
- LOG_LEVEL: zod.z.enum(["fatal", "error", "warn", "info", "debug", "trace"]).default("info")
73
+ LOG_LEVEL: zod.z.enum(["fatal", "error", "warn", "info", "debug", "trace"]).default("info"),
74
+ AWS_REGION: zod.z.string().default("us-east-1"),
75
+ AWS_ACCESS_KEY_ID: zod.z.string().optional(),
76
+ AWS_SECRET_ACCESS_KEY: zod.z.string().optional(),
77
+ AWS_S3_BUCKET: zod.z.string().optional(),
78
+ AWS_ENDPOINT: zod.z.string().optional()
72
79
  });
73
80
  ConfigManager = class {
74
81
  config = null;
@@ -1154,6 +1161,180 @@ express.Response.prototype.paginated = function(data, page, limit, total) {
1154
1161
  };
1155
1162
  var response = ResponseHelper;
1156
1163
 
1164
+ // src/upload/index.ts
1165
+ init_config();
1166
+ init_logger();
1167
+ var S3Service = class {
1168
+ client = null;
1169
+ bucket;
1170
+ initialized = false;
1171
+ constructor() {
1172
+ this.bucket = "";
1173
+ }
1174
+ initialize(config2) {
1175
+ this.client = new clientS3.S3Client({
1176
+ region: config2.region || "us-east-1",
1177
+ credentials: config2.accessKeyId && config2.secretAccessKey ? {
1178
+ accessKeyId: config2.accessKeyId,
1179
+ secretAccessKey: config2.secretAccessKey
1180
+ } : void 0,
1181
+ endpoint: config2.endpoint,
1182
+ forcePathStyle: config2.forcePathStyle || false
1183
+ });
1184
+ this.bucket = config2.bucket;
1185
+ this.initialized = true;
1186
+ exports.logger.info("S3 service initialized", { bucket: this.bucket });
1187
+ }
1188
+ isInitialized() {
1189
+ return this.initialized;
1190
+ }
1191
+ ensureInitialized() {
1192
+ if (!this.initialized) {
1193
+ const region = exports.config.get("AWS_REGION") || "us-east-1";
1194
+ const bucket = exports.config.get("AWS_S3_BUCKET") || "";
1195
+ this.initialize({
1196
+ region,
1197
+ accessKeyId: exports.config.get("AWS_ACCESS_KEY_ID"),
1198
+ secretAccessKey: exports.config.get("AWS_SECRET_ACCESS_KEY"),
1199
+ bucket,
1200
+ endpoint: exports.config.get("AWS_ENDPOINT")
1201
+ });
1202
+ }
1203
+ }
1204
+ async upload(file, options = {}) {
1205
+ this.ensureInitialized();
1206
+ const key = options.key || this.generateKey();
1207
+ const contentType = options.contentType || this.guessContentType(key);
1208
+ const command = new clientS3.PutObjectCommand({
1209
+ Bucket: this.bucket,
1210
+ Key: key,
1211
+ Body: file,
1212
+ ContentType: contentType,
1213
+ Metadata: options.metadata
1214
+ });
1215
+ await this.client.send(command);
1216
+ const url = await this.getSignedUrl(key, { expiresIn: options.expiresIn || 3600 });
1217
+ exports.logger.info("File uploaded to S3", { key, bucket: this.bucket, contentType });
1218
+ return {
1219
+ key,
1220
+ url,
1221
+ bucket: this.bucket,
1222
+ contentType
1223
+ };
1224
+ }
1225
+ async uploadImage(file, filename, options = {}) {
1226
+ const key = options.key || `images/${Date.now()}-${filename}`;
1227
+ return this.upload(file, {
1228
+ ...options,
1229
+ key,
1230
+ contentType: options.contentType || this.getImageContentType(filename)
1231
+ });
1232
+ }
1233
+ async uploadVideo(file, filename, options = {}) {
1234
+ const key = options.key || `videos/${Date.now()}-${filename}`;
1235
+ return this.upload(file, {
1236
+ ...options,
1237
+ key,
1238
+ contentType: options.contentType || this.getVideoContentType(filename)
1239
+ });
1240
+ }
1241
+ async delete(key) {
1242
+ this.ensureInitialized();
1243
+ const command = new clientS3.DeleteObjectCommand({
1244
+ Bucket: this.bucket,
1245
+ Key: key
1246
+ });
1247
+ await this.client.send(command);
1248
+ exports.logger.info("File deleted from S3", { key, bucket: this.bucket });
1249
+ }
1250
+ async getSignedUrl(key, options = {}) {
1251
+ this.ensureInitialized();
1252
+ const command = new clientS3.GetObjectCommand({
1253
+ Bucket: this.bucket,
1254
+ Key: key
1255
+ });
1256
+ return s3RequestPresigner.getSignedUrl(this.client, command, {
1257
+ expiresIn: options.expiresIn || 3600
1258
+ });
1259
+ }
1260
+ async getPublicUrl(key) {
1261
+ return `https://${this.bucket}.s3.${exports.config.get("AWS_REGION") || "us-east-1"}.amazonaws.com/${key}`;
1262
+ }
1263
+ async listFiles(prefix, maxKeys = 1e3) {
1264
+ this.ensureInitialized();
1265
+ const command = new clientS3.ListObjectsV2Command({
1266
+ Bucket: this.bucket,
1267
+ Prefix: prefix,
1268
+ MaxKeys: maxKeys
1269
+ });
1270
+ const response2 = await this.client.send(command);
1271
+ return (response2.Contents || []).map((item) => ({
1272
+ key: item.Key || "",
1273
+ lastModified: item.LastModified,
1274
+ size: item.Size
1275
+ }));
1276
+ }
1277
+ generateKey() {
1278
+ const timestamp = Date.now();
1279
+ const random = Math.random().toString(36).substring(2, 15);
1280
+ return `uploads/${timestamp}-${random}`;
1281
+ }
1282
+ guessContentType(key) {
1283
+ const ext = key.split(".").pop()?.toLowerCase();
1284
+ const contentTypes = {
1285
+ jpg: "image/jpeg",
1286
+ jpeg: "image/jpeg",
1287
+ png: "image/png",
1288
+ gif: "image/gif",
1289
+ webp: "image/webp",
1290
+ svg: "image/svg+xml",
1291
+ mp4: "video/mp4",
1292
+ webm: "video/webm",
1293
+ mov: "video/quicktime",
1294
+ avi: "video/x-msvideo",
1295
+ pdf: "application/pdf",
1296
+ json: "application/json",
1297
+ txt: "text/plain"
1298
+ };
1299
+ return contentTypes[ext || ""] || "application/octet-stream";
1300
+ }
1301
+ getImageContentType(filename) {
1302
+ const ext = filename.split(".").pop()?.toLowerCase();
1303
+ const imageTypes = {
1304
+ jpg: "image/jpeg",
1305
+ jpeg: "image/jpeg",
1306
+ png: "image/png",
1307
+ gif: "image/gif",
1308
+ webp: "image/webp",
1309
+ svg: "image/svg+xml"
1310
+ };
1311
+ return imageTypes[ext || ""] || "image/jpeg";
1312
+ }
1313
+ getVideoContentType(filename) {
1314
+ const ext = filename.split(".").pop()?.toLowerCase();
1315
+ const videoTypes = {
1316
+ mp4: "video/mp4",
1317
+ webm: "video/webm",
1318
+ mov: "video/quicktime",
1319
+ avi: "video/x-msvideo",
1320
+ mkv: "video/x-matroska",
1321
+ ogv: "video/ogg"
1322
+ };
1323
+ return videoTypes[ext || ""] || "video/mp4";
1324
+ }
1325
+ };
1326
+ var s3Service = new S3Service();
1327
+ var upload = {
1328
+ initialize: (config2) => s3Service.initialize(config2),
1329
+ file: (file, options) => s3Service.upload(file, options),
1330
+ image: (file, filename, options) => s3Service.uploadImage(file, filename, options),
1331
+ video: (file, filename, options) => s3Service.uploadVideo(file, filename, options),
1332
+ delete: (key) => s3Service.delete(key),
1333
+ getSignedUrl: (key, options) => s3Service.getSignedUrl(key, options),
1334
+ getPublicUrl: (key) => s3Service.getPublicUrl(key),
1335
+ listFiles: (prefix, maxKeys) => s3Service.listFiles(prefix, maxKeys)
1336
+ };
1337
+
1157
1338
  // src/plugin.ts
1158
1339
  init_logger();
1159
1340
  init_config();
@@ -1299,5 +1480,7 @@ exports.notification = notification;
1299
1480
  exports.notify = notify;
1300
1481
  exports.rateLimit = rateLimit;
1301
1482
  exports.response = response;
1483
+ exports.s3Service = s3Service;
1484
+ exports.upload = upload;
1302
1485
  //# sourceMappingURL=index.js.map
1303
1486
  //# sourceMappingURL=index.js.map