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

889 lines
20 KiB
JavaScript

var util = require('util');
var assert = require('assert');
var pathToRegexp = require('./');
/**
* Execute a regular expression and return a flat array for comparison.
*
* @param {RegExp} re
* @param {String} str
* @return {Array}
*/
var exec = function (re, str) {
var match = re.exec(str);
return match && Array.prototype.slice.call(match);
};
/**
* An array of test cases with expected inputs and outputs. The format of each
* array item is:
*
* ["path", "expected params", "route", "expected output", "options"]
*
* @type {Array}
*/
var TESTS = [
/**
* Simple paths.
*/
['/', [], '/', ['/']],
['/test', [], '/test', ['/test']],
['/test', [], '/route', null],
['/test', [], '/test/route', null],
['/test', [], '/test/', ['/test/']],
['/test/', [], '/test', ['/test']],
['/test/', [], '/test/', ['/test/']],
['/test/', [], '/test//', null],
/**
* Case-sensitive paths.
*/
['/test', [], '/test', ['/test'], { sensitive: true }],
['/test', [], '/TEST', null, { sensitive: true }],
['/TEST', [], '/test', null, { sensitive: true }],
/**
* Strict mode.
*/
['/test', [], '/test', ['/test'], { strict: true }],
['/test', [], '/test/', null, { strict: true }],
['/test/', [], '/test', null, { strict: true }],
['/test/', [], '/test/', ['/test/'], { strict: true }],
['/test/', [], '/test//', null, { strict: true }],
/**
* Non-ending mode.
*/
['/test', [], '/test', ['/test'], { end: false }],
['/test', [], '/test/', ['/test/'], { end: false }],
['/test', [], '/test/route', ['/test'], { end: false }],
['/test/', [], '/test/route', ['/test'], { end: false }],
['/test/', [], '/test//', ['/test'], { end: false }],
['/test/', [], '/test//route', ['/test'], { end: false }],
[
'/:test',
[{ name: 'test', delimiter: '/', optional: false, repeat: false }],
'/route',
['/route', 'route'],
{ end: false }
],
[
'/:test/',
[{ name: 'test', delimiter: '/', optional: false, repeat: false }],
'/route',
['/route', 'route'],
{ end: false }
],
/**
* Combine modes.
*/
['/test', [], '/test', ['/test'], { end: false, strict: true }],
['/test', [], '/test/', ['/test'], { end: false, strict: true }],
['/test', [], '/test/route', ['/test'], { end: false, strict: true }],
['/test/', [], '/test', null, { end: false, strict: true }],
['/test/', [], '/test/', ['/test/'], { end: false, strict: true }],
['/test/', [], '/test//', ['/test/'], { end: false, strict: true }],
['/test/', [], '/test/route', ['/test/'], { end: false, strict: true }],
['/test.json', [], '/test.json', ['/test.json'], { end: false, strict: true }],
['/test.json', [], '/test.json.hbs', null, { end: false, strict: true }],
[
'/:test',
[{ name: 'test', delimiter: '/', optional: false, repeat: false }],
'/route',
['/route', 'route'],
{ end: false, strict: true }
],
[
'/:test',
[{ name: 'test', delimiter: '/', optional: false, repeat: false }],
'/route/',
['/route', 'route'],
{ end: false, strict: true }
],
[
'/:test/',
[{ name: 'test', delimiter: '/', optional: false, repeat: false }],
'/route/',
['/route/', 'route'],
{ end: false, strict: true }
],
[
'/:test/',
[{ name: 'test', delimiter: '/', optional: false, repeat: false }],
'/route',
null,
{ end: false, strict: true }
],
/**
* Arrays of simple paths.
*/
[['/one', '/two'], [], '/one', ['/one']],
[['/one', '/two'], [], '/two', ['/two']],
[['/one', '/two'], [], '/three', null],
[['/one', '/two'], [], '/one/two', null],
/**
* Non-ending simple path.
*/
['/test', [], '/test/route', ['/test'], { end: false }],
/**
* Single named parameter.
*/
[
'/:test',
[{ name: 'test', delimiter: '/', optional: false, repeat: false }],
'/route',
['/route', 'route']
],
[
'/:test',
[{ name: 'test', delimiter: '/', optional: false, repeat: false }],
'/another',
['/another', 'another']
],
[
'/:test',
[{ name: 'test', delimiter: '/', optional: false, repeat: false }],
'/something/else',
null
],
[
'/:test',
[{ name: 'test', delimiter: '/', optional: false, repeat: false }],
'/route.json',
['/route.json', 'route.json']
],
[
'/:test',
[{ name: 'test', delimiter: '/', optional: false, repeat: false }],
'/route',
['/route', 'route'],
{ strict: true }],
[
'/:test',
[{ name: 'test', delimiter: '/', optional: false, repeat: false }],
'/route/',
null,
{ strict: true }
],
[
'/:test/',
[{ name: 'test', delimiter: '/', optional: false, repeat: false }],
'/route/',
['/route/', 'route'],
{ strict: true }
],
[
'/:test/',
[{ name: 'test', delimiter: '/', optional: false, repeat: false }],
'/route//',
null,
{ strict: true }
],
[
'/:test',
[{ name: 'test', delimiter: '/', optional: false, repeat: false }],
'/route.json',
['/route.json', 'route.json'],
{ end: false }
],
/**
* Optional named parameter.
*/
[
'/:test?',
[{ name: 'test', delimiter: '/', optional: true, repeat: false }],
'/route',
['/route', 'route']
],
[
'/:test?',
[{ name: 'test', delimiter: '/', optional: true, repeat: false }],
'/route/nested',
null
],
[
'/:test?',
[{ name: 'test', delimiter: '/', optional: true, repeat: false }],
'/',
['/', undefined]
],
[
'/:test?',
[{ name: 'test', delimiter: '/', optional: true, repeat: false }],
'/route',
['/route', 'route'],
{ strict: true }
],
[
'/:test?',
[{ name: 'test', delimiter: '/', optional: true, repeat: false }],
'/',
null, // Questionable behaviour.
{ strict: true }
],
[
'/:test?/',
[{ name: 'test', delimiter: '/', optional: true, repeat: false }],
'/',
['/', undefined],
{ strict: true }
],
[
'/:test?/',
[{ name: 'test', delimiter: '/', optional: true, repeat: false }],
'//',
null
],
[
'/:test?/',
[{ name: 'test', delimiter: '/', optional: true, repeat: false }],
'//',
null,
{ strict: true }
],
// Repeated once or more times parameters.
[
'/:test+',
[{ name: 'test', delimiter: '/', optional: false, repeat: true }],
'/',
null
],
[
'/:test+',
[{ name: 'test', delimiter: '/', optional: false, repeat: true }],
'/route',
['/route', 'route']
],
[
'/:test+',
[{ name: 'test', delimiter: '/', optional: false, repeat: true }],
'/some/basic/route',
['/some/basic/route', 'some/basic/route']
],
[
'/:test(\\d+)+',
[{ name: 'test', delimiter: '/', optional: false, repeat: true }],
'/abc/456/789',
null
],
[
'/:test(\\d+)+',
[{ name: 'test', delimiter: '/', optional: false, repeat: true }],
'/123/456/789',
['/123/456/789', '123/456/789']
],
[
'/route.:ext(json|xml)+',
[{ name: 'ext', delimiter: '.', optional: false, repeat: true }],
'/route.json',
['/route.json', 'json']
],
[
'/route.:ext(json|xml)+',
[{ name: 'ext', delimiter: '.', optional: false, repeat: true }],
'/route.xml.json',
['/route.xml.json', 'xml.json']
],
[
'/route.:ext(json|xml)+',
[{ name: 'ext', delimiter: '.', optional: false, repeat: true }],
'/route.html',
null
],
/**
* Repeated zero or more times parameters.
*/
[
'/:test*',
[{ name: 'test', delimiter: '/', optional: true, repeat: true }],
'/',
['/', undefined]
],
[
'/:test*',
[{ name: 'test', delimiter: '/', optional: true, repeat: true }],
'//',
null
],
[
'/:test*',
[{ name: 'test', delimiter: '/', optional: true, repeat: true }],
'/route',
['/route', 'route']
],
[
'/:test*',
[{ name: 'test', delimiter: '/', optional: true, repeat: true }],
'/some/basic/route',
['/some/basic/route', 'some/basic/route']
],
[
'/route.:ext([a-z]+)*',
[{ name: 'ext', delimiter: '.', optional: true, repeat: true }],
'/route',
['/route', undefined]
],
[
'/route.:ext([a-z]+)*',
[{ name: 'ext', delimiter: '.', optional: true, repeat: true }],
'/route.json',
['/route.json', 'json']
],
[
'/route.:ext([a-z]+)*',
[{ name: 'ext', delimiter: '.', optional: true, repeat: true }],
'/route.xml.json',
['/route.xml.json', 'xml.json']
],
[
'/route.:ext([a-z]+)*',
[{ name: 'ext', delimiter: '.', optional: true, repeat: true }],
'/route.123',
null
],
// Custom named parameters.
[
'/:test(\\d+)',
[{ name: 'test', delimiter: '/', optional: false, repeat: false }],
'/123',
['/123', '123']
],
[
'/:test(\\d+)',
[{ name: 'test', delimiter: '/', optional: false, repeat: false }],
'/abc',
null
],
[
'/:test(\\d+)',
[{ name: 'test', delimiter: '/', optional: false, repeat: false }],
'/123/abc',
null
],
[
'/:test(\\d+)',
[{ name: 'test', delimiter: '/', optional: false, repeat: false }],
'/123/abc',
['/123', '123'],
{ end: false }
],
[
'/:test(.*)',
[{ name: 'test', delimiter: '/', optional: false, repeat: false }],
'/anything/goes/here',
['/anything/goes/here', 'anything/goes/here']
],
[
'/:route([a-z]+)',
[{ name: 'route', delimiter: '/', optional: false, repeat: false }],
'/abcde',
['/abcde', 'abcde']
],
[
'/:route([a-z]+)',
[{ name: 'route', delimiter: '/', optional: false, repeat: false }],
'/12345',
null
],
[
'/:route(this|that)',
[{ name: 'route', delimiter: '/', optional: false, repeat: false }],
'/this',
['/this', 'this']
],
[
'/:route(this|that)',
[{ name: 'route', delimiter: '/', optional: false, repeat: false }],
'/that',
['/that', 'that']
],
/**
* Prefixed slashes could be omitted.
*/
[
'test',
[],
'test',
['test']
],
[
':test',
[{ name: 'test', delimiter: '/', optional: false, repeat: false }],
'route',
['route', 'route']
],
[
':test',
[{ name: 'test', delimiter: '/', optional: false, repeat: false }],
'/route',
null
],
[
':test',
[{ name: 'test', delimiter: '/', optional: false, repeat: false }],
'route/',
['route/', 'route']
],
[
':test',
[{ name: 'test', delimiter: '/', optional: false, repeat: false }],
'route/',
null,
{ strict: true }
],
[
':test',
[{ name: 'test', delimiter: '/', optional: false, repeat: false }],
'route/',
['route/', 'route'],
{ end: false }
],
/**
* Formats.
*/
[
'/test.json',
[],
'/test.json',
['/test.json']
],
[
'/test.json',
[],
'/route.json',
null
],
[
'/:test.json',
[{ name: 'test', delimiter: '/', optional: false, repeat: false }],
'/route.json',
['/route.json', 'route']
],
[
'/:test.json',
[{ name: 'test', delimiter: '/', optional: false, repeat: false }],
'/route.json.json',
['/route.json.json', 'route.json']
],
[
'/:test.json',
[{ name: 'test', delimiter: '/', optional: false, repeat: false }],
'/route.json',
['/route.json', 'route'],
{ end: false }
],
[
'/:test.json',
[{ name: 'test', delimiter: '/', optional: false, repeat: false }],
'/route.json.json',
['/route.json.json', 'route.json'],
{ end: false }
],
/**
* Format params.
*/
[
'/test.:format',
[{ name: 'format', delimiter: '.', optional: false, repeat: false }],
'/test.html',
['/test.html', 'html']
],
[
'/test.:format',
[{ name: 'format', delimiter: '.', optional: false, repeat: false }],
'/test.hbs.html',
null
],
[
'/test.:format.:format',
[
{ name: 'format', delimiter: '.', optional: false, repeat: false },
{ name: 'format', delimiter: '.', optional: false, repeat: false }
],
'/test.hbs.html',
['/test.hbs.html', 'hbs', 'html']
],
[
'/test.:format+',
[
{ name: 'format', delimiter: '.', optional: false, repeat: true }
],
'/test.hbs.html',
['/test.hbs.html', 'hbs.html']
],
[
'/test.:format',
[{ name: 'format', delimiter: '.', optional: false, repeat: false }],
'/test.hbs.html',
null,
{ end: false }
],
[
'/test.:format.',
[{ name: 'format', delimiter: '.', optional: false, repeat: false }],
'/test.hbs.html',
null,
{ end: false }
],
/**
* Format and path params.
*/
[
'/:test.:format',
[
{ name: 'test', delimiter: '/', optional: false, repeat: false },
{ name: 'format', delimiter: '.', optional: false, repeat: false }
],
'/route.html',
['/route.html', 'route', 'html']
],
[
'/:test.:format',
[
{ name: 'test', delimiter: '/', optional: false, repeat: false },
{ name: 'format', delimiter: '.', optional: false, repeat: false }
],
'/route',
null
],
[
'/:test.:format',
[
{ name: 'test', delimiter: '/', optional: false, repeat: false },
{ name: 'format', delimiter: '.', optional: false, repeat: false }
],
'/route',
null
],
[
'/:test.:format?',
[
{ name: 'test', delimiter: '/', optional: false, repeat: false },
{ name: 'format', delimiter: '.', optional: true, repeat: false }
],
'/route',
['/route', 'route', undefined]
],
[
'/:test.:format?',
[
{ name: 'test', delimiter: '/', optional: false, repeat: false },
{ name: 'format', delimiter: '.', optional: true, repeat: false }
],
'/route.json',
['/route.json', 'route', 'json']
],
[
'/:test.:format?',
[
{ name: 'test', delimiter: '/', optional: false, repeat: false },
{ name: 'format', delimiter: '.', optional: true, repeat: false }
],
'/route',
['/route', 'route', undefined],
{ end: false }
],
[
'/:test.:format?',
[
{ name: 'test', delimiter: '/', optional: false, repeat: false },
{ name: 'format', delimiter: '.', optional: true, repeat: false }
],
'/route.json',
['/route.json', 'route', 'json'],
{ end: false }
],
[
'/:test.:format?',
[
{ name: 'test', delimiter: '/', optional: false, repeat: false },
{ name: 'format', delimiter: '.', optional: true, repeat: false }
],
'/route.json.html',
['/route.json.html', 'route.json', 'html'],
{ end: false }
],
[
'/test.:format(.*)z',
[{ name: 'format', delimiter: '.', optional: false, repeat: false }],
'/test.abc',
null,
{ end: false }
],
[
'/test.:format(.*)z',
[{ name: 'format', delimiter: '.', optional: false, repeat: false }],
'/test.abcz',
['/test.abcz', 'abc'],
{ end: false }
],
/**
* Unnamed params.
*/
[
'/(\\d+)',
[{ name: '0', delimiter: '/', optional: false, repeat: false }],
'/123',
['/123', '123']
],
[
'/(\\d+)',
[{ name: '0', delimiter: '/', optional: false, repeat: false }],
'/abc',
null
],
[
'/(\\d+)',
[{ name: '0', delimiter: '/', optional: false, repeat: false }],
'/123/abc',
null
],
[
'/(\\d+)',
[{ name: '0', delimiter: '/', optional: false, repeat: false }],
'/123/abc',
['/123', '123'],
{ end: false }
],
[
'/(\\d+)',
[{ name: '0', delimiter: '/', optional: false, repeat: false }],
'/abc',
null,
{ end: false }
],
[
'/(\\d+)?',
[{ name: '0', delimiter: '/', optional: true, repeat: false }],
'/',
['/', undefined]
],
[
'/(\\d+)?',
[{ name: '0', delimiter: '/', optional: true, repeat: false }],
'/123',
['/123', '123']
],
[
'/(.*)',
[{ name: '0', delimiter: '/', optional: false, repeat: false }],
'/route',
['/route', 'route']
],
[
'/(.*)',
[{ name: '0', delimiter: '/', optional: false, repeat: false }],
'/route/nested',
['/route/nested', 'route/nested']
],
/**
* Regexps.
*/
[
/.*/,
[],
'/match/anything',
['/match/anything']
],
[
/(.*)/,
[{ name: '0', delimiter: null, optional: false, repeat: false }],
'/match/anything',
['/match/anything', '/match/anything']
],
[
/\/(\d+)/,
[{ name: '0', delimiter: null, optional: false, repeat: false }],
'/123',
['/123', '123']
],
/**
* Mixed arrays.
*/
[
['/test', /\/(\d+)/],
[{ name: '0', delimiter: null, optional: false, repeat: false }],
'/test',
['/test', undefined]
],
[
['/:test(\\d+)', /(.*)/],
[
{ name: 'test', delimiter: '/', optional: false, repeat: false },
{ name: '0', delimiter: null, optional: false, repeat: false }
],
'/123',
['/123', '123', undefined]
],
[
['/:test(\\d+)', /(.*)/],
[
{ name: 'test', delimiter: '/', optional: false, repeat: false },
{ name: '0', delimiter: null, optional: false, repeat: false }
],
'/abc',
['/abc', undefined, '/abc']
],
/**
* Correct names and indexes.
*/
[
['/:test', '/route/:test'],
[
{ name: 'test', delimiter: '/', optional: false, repeat: false },
{ name: 'test', delimiter: '/', optional: false, repeat: false }
],
'/test',
['/test', 'test', undefined]
],
[
['/:test', '/route/:test'],
[
{ name: 'test', delimiter: '/', optional: false, repeat: false },
{ name: 'test', delimiter: '/', optional: false, repeat: false }
],
'/route/test',
['/route/test', undefined, 'test']
],
[
[/^\/([^\/]+)$/, /^\/route\/([^\/]+)$/],
[
{ name: '0', delimiter: null, optional: false, repeat: false },
{ name: '0', delimiter: null, optional: false, repeat: false }
],
'/test',
['/test', 'test', undefined]
],
[
[/^\/([^\/]+)$/, /^\/route\/([^\/]+)$/],
[
{ name: '0', delimiter: null, optional: false, repeat: false },
{ name: '0', delimiter: null, optional: false, repeat: false }
],
'/route/test',
['/route/test', undefined, 'test']
],
/**
* Ignore non-matching groups in regexps.
*/
[
/(?:.*)/,
[],
'/anything/you/want',
['/anything/you/want']
],
/**
* Respect escaped characters.
*/
[
'/\\(testing\\)',
[],
'/testing',
null
],
[
'/\\(testing\\)',
[],
'/(testing)',
['/(testing)']
],
[
'/.+*?=^!:${}[]|',
[],
'/.+*?=^!:${}[]|',
['/.+*?=^!:${}[]|']
],
/**
* Real world examples.
*/
[
'/:foo/:bar',
[
{ name: 'foo', delimiter: '/', optional: false, repeat: false },
{ name: 'bar', delimiter: '/', optional: false, repeat: false }
],
'/match/route',
['/match/route', 'match', 'route']
],
[
'/:remote([\\w-.]+)/:user([\\w-]+)',
[
{ name: 'remote', delimiter: '/', optional: false, repeat: false },
{ name: 'user', delimiter: '/', optional: false, repeat: false }
],
'/endpoint/user',
['/endpoint/user', 'endpoint', 'user']
]
];
/**
* Dynamically generate the entire test suite.
*/
describe('path-to-regexp', function () {
describe('arguments', function () {
it('should work without second keys', function () {
var re = pathToRegexp('/user/:id', { end: false });
var params = [
{ name: 'id', delimiter: '/', optional: false, repeat: false }
];
assert.deepEqual(re.keys, params);
assert.deepEqual(exec(re, '/user/123/show'), ['/user/123', '123']);
});
});
describe('rules', function () {
TESTS.forEach(function (test) {
var description = '';
var options = test[4] || {};
// Generate a base description using the test values.
description += 'should ' + (test[3] ? '' : 'not ') + 'match ';
description += util.inspect(test[2]) + ' against ' + util.inspect(test[0]);
// If additional options have been defined, we should render the options
// in the test descriptions.
if (Object.keys(options).length) {
var optionsDescription = Object.keys(options).map(function (key) {
return (options[key] === false ? 'non-' : '') + key;
}).join(', ');
description += ' in ' + optionsDescription + ' mode';
}
// Execute the test and check each parameter is as expected.
it(description, function () {
var params = [];
var re = pathToRegexp(test[0], params, test[4]);
// Check the keys are as expected.
assert.equal(re.keys, params);
assert.deepEqual(params, test[1]);
// Run the regexp and check the result is expected.
assert.deepEqual(exec(re, test[2]), test[3]);
});
});
});
});