Automated Action 545563e776 Implement comprehensive real-time chat API with NestJS
- Complete NestJS TypeScript implementation with WebSocket support
- Direct messaging (DM) and group chat functionality
- End-to-end encryption with AES encryption and key pairs
- Media file support (images, videos, audio, documents) up to 100MB
- Push notifications with Firebase Cloud Messaging integration
- Mention alerts and real-time typing indicators
- User authentication with JWT and Passport
- SQLite database with TypeORM entities and relationships
- Comprehensive API documentation with Swagger/OpenAPI
- File upload handling with secure access control
- Online/offline status tracking and presence management
- Message editing, deletion, and reply functionality
- Notification management with automatic cleanup
- Health check endpoint for monitoring
- CORS configuration for cross-origin requests
- Environment-based configuration management
- Structured for Flutter SDK integration

Features implemented:
 Real-time messaging with Socket.IO
 User registration and authentication
 Direct messages and group chats
 Media file uploads and management
 End-to-end encryption
 Push notifications
 Mention alerts
 Typing indicators
 Message read receipts
 Online status tracking
 File access control
 Comprehensive API documentation

Ready for Flutter SDK development and production deployment.
2025-06-21 17:13:05 +00:00

143 lines
4.0 KiB
JavaScript

const path = require('path')
const fs = require('fs')
const get = require('simple-get')
const pump = require('pump')
const tfs = require('tar-fs')
const zlib = require('zlib')
const util = require('./util')
const error = require('./error')
const proxy = require('./proxy')
const mkdirp = require('mkdirp-classic')
function downloadPrebuild (downloadUrl, opts, cb) {
let cachedPrebuild = util.cachedPrebuild(downloadUrl)
const localPrebuild = util.localPrebuild(downloadUrl, opts)
const tempFile = util.tempFile(cachedPrebuild)
const log = opts.log || util.noopLogger
if (opts.nolocal) return download()
log.info('looking for local prebuild @', localPrebuild)
fs.access(localPrebuild, fs.R_OK | fs.W_OK, function (err) {
if (err && err.code === 'ENOENT') {
return download()
}
log.info('found local prebuild')
cachedPrebuild = localPrebuild
unpack()
})
function download () {
ensureNpmCacheDir(function (err) {
if (err) return onerror(err)
log.info('looking for cached prebuild @', cachedPrebuild)
fs.access(cachedPrebuild, fs.R_OK | fs.W_OK, function (err) {
if (!(err && err.code === 'ENOENT')) {
log.info('found cached prebuild')
return unpack()
}
log.http('request', 'GET ' + downloadUrl)
const reqOpts = proxy({ url: downloadUrl }, opts)
if (opts.token) {
reqOpts.headers = {
'User-Agent': 'simple-get',
Accept: 'application/octet-stream',
Authorization: 'token ' + opts.token
}
}
const req = get(reqOpts, function (err, res) {
if (err) return onerror(err)
log.http(res.statusCode, downloadUrl)
if (res.statusCode !== 200) return onerror()
mkdirp(util.prebuildCache(), function () {
log.info('downloading to @', tempFile)
pump(res, fs.createWriteStream(tempFile), function (err) {
if (err) return onerror(err)
fs.rename(tempFile, cachedPrebuild, function (err) {
if (err) return cb(err)
log.info('renaming to @', cachedPrebuild)
unpack()
})
})
})
})
req.setTimeout(30 * 1000, function () {
req.abort()
})
})
function onerror (err) {
fs.unlink(tempFile, function () {
cb(err || error.noPrebuilts(opts))
})
}
})
}
function unpack () {
let binaryName
const updateName = opts.updateName || function (entry) {
if (/\.node$/i.test(entry.name)) binaryName = entry.name
}
log.info('unpacking @', cachedPrebuild)
const options = {
readable: true,
writable: true,
hardlinkAsFilesFallback: true
}
const extract = tfs.extract(opts.path, options).on('entry', updateName)
pump(fs.createReadStream(cachedPrebuild), zlib.createGunzip(), extract,
function (err) {
if (err) return cb(err)
let resolved
if (binaryName) {
try {
resolved = path.resolve(opts.path || '.', binaryName)
} catch (err) {
return cb(err)
}
log.info('unpack', 'resolved to ' + resolved)
if (opts.runtime === 'node' && opts.platform === process.platform && opts.abi === process.versions.modules && opts.arch === process.arch) {
try {
require(resolved)
} catch (err) {
return cb(err)
}
log.info('unpack', 'required ' + resolved + ' successfully')
}
}
cb(null, resolved)
})
}
function ensureNpmCacheDir (cb) {
const cacheFolder = util.npmCache()
fs.access(cacheFolder, fs.R_OK | fs.W_OK, function (err) {
if (err && err.code === 'ENOENT') {
return makeNpmCacheDir()
}
cb(err)
})
function makeNpmCacheDir () {
log.info('npm cache directory missing, creating it...')
mkdirp(cacheFolder, cb)
}
}
}
module.exports = downloadPrebuild