diff --git a/CHANGELOG.md b/CHANGELOG.md index 84078cf370..0a0993f03d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,44 @@ +#### v3.5.2 (2023-11-29) + +##### Chores + +* up composer (49013f81) +* incrementing version number - v3.5.1 (4c543488) +* update changelog for v3.5.1 (48f7ae99) +* incrementing version number - v3.5.0 (d06fb4f0) +* incrementing version number - v3.4.3 (5c984250) +* incrementing version number - v3.4.2 (3f0dac38) +* incrementing version number - v3.4.1 (01e69574) +* incrementing version number - v3.4.0 (fd9247c5) +* incrementing version number - v3.3.9 (5805e770) +* incrementing version number - v3.3.8 (a5603565) +* incrementing version number - v3.3.7 (b26f1744) +* incrementing version number - v3.3.6 (7fb38792) +* incrementing version number - v3.3.4 (a67f84ea) +* incrementing version number - v3.3.3 (f94d239b) +* incrementing version number - v3.3.2 (ec9dac97) +* incrementing version number - v3.3.1 (151cc68f) +* incrementing version number - v3.3.0 (fc1ad70f) +* incrementing version number - v3.2.3 (b06d3e63) +* incrementing version number - v3.2.2 (758ecfcd) +* incrementing version number - v3.2.1 (20145074) +* incrementing version number - v3.2.0 (9ecac38e) +* incrementing version number - v3.1.7 (0b4e81ab) +* incrementing version number - v3.1.6 (b3a3b130) +* incrementing version number - v3.1.5 (ec19343a) +* incrementing version number - v3.1.4 (2452783c) +* incrementing version number - v3.1.3 (3b4e9d3f) +* incrementing version number - v3.1.2 (40fa3489) +* incrementing version number - v3.1.1 (40250733) +* incrementing version number - v3.1.0 (0cb386bd) +* incrementing version number - v3.0.1 (26f6ea49) +* incrementing version number - v3.0.0 (224e08cd) + +##### Bug Fixes + +* closes #12185, fix cli user password reset (6790000d) +* thumb width (a9ef58a5) + #### v3.5.1 (2023-11-14) ##### Chores diff --git a/install/package.json b/install/package.json index 5ef77abd22..14de04da6f 100644 --- a/install/package.json +++ b/install/package.json @@ -93,7 +93,7 @@ "multiparty": "4.2.3", "nconf": "0.12.1", "nodebb-plugin-2factor": "7.4.0", - "nodebb-plugin-composer-default": "10.2.27", + "nodebb-plugin-composer-default": "10.2.29", "nodebb-plugin-dbsearch": "6.2.2", "nodebb-plugin-emoji": "5.1.13", "nodebb-plugin-emoji-android": "4.0.0", diff --git a/public/src/modules/translator.common.js b/public/src/modules/translator.common.js index 49a3b59c60..c69a9cc265 100644 --- a/public/src/modules/translator.common.js +++ b/public/src/modules/translator.common.js @@ -463,7 +463,9 @@ module.exports = function (utils, load, warn) { * @returns {string} */ Translator.escape = function escape(text) { - return typeof text === 'string' ? text.replace(/\[\[/g, '[[').replace(/\]\]/g, ']]') : text; + return typeof text === 'string' ? + text.replace(/\[\[/g, '[[').replace(/\]\]/g, ']]') : + text; }; /** @@ -473,8 +475,7 @@ module.exports = function (utils, load, warn) { */ Translator.unescape = function unescape(text) { return typeof text === 'string' ? - text.replace(/[/g, '[').replace(/\\\[/g, '[') - .replace(/]/g, ']').replace(/\\\]/g, ']') : + text.replace(/]]/g, ']]').replace(/[[/g, '[[') : text; }; diff --git a/test/translator.js b/test/translator.js index 6e34012a7a..61c3d5af8e 100644 --- a/test/translator.js +++ b/test/translator.js @@ -308,10 +308,6 @@ describe('Translator static methods', () => { describe('.unescape', () => { it('should unescape escaped translation patterns within text', (done) => { - assert.strictEqual( - Translator.unescape('some nice text \\[\\[global:home\\]\\] here'), - 'some nice text [[global:home]] here' - ); assert.strictEqual( Translator.unescape('some nice text [[global:home]] here'), 'some nice text [[global:home]] here' diff --git a/types/database/hash.d.ts b/types/database/hash.d.ts new file mode 100644 index 0000000000..3bc7a93834 --- /dev/null +++ b/types/database/hash.d.ts @@ -0,0 +1,56 @@ +export interface Hash { + decrObjectField( + key: string | string[], + field: string, + ): Promise + + deleteObjectField(key: string, field: string): Promise + + deleteObjectFields(key: string, fields: string[]): Promise + + getObject(key: string, fields: string[]): Promise + + getObjectField(key: string, field: string): Promise + + getObjectFields(key: string, fields: string[]): Promise> + + getObjectKeys(key: string): Promise + + getObjectValues(key: string): Promise + + getObjects(keys: string[], fields: string[]): Promise + + getObjectsFields( + keys: string[], + fields: string[], + ): Promise[]> + + incrObjectField( + key: string | string[], + field: string, + ): Promise + + incrObjectFieldBy( + key: string | string[], + field: string, + value: number, + ): Promise + + incrObjectFieldByBulk( + data: [key: string, batch: Record][], + ): Promise + + isObjectField(key: string, field: string): Promise + + isObjectFields(key: string, fields: string[]): Promise + + setObject(key: string | string[], data: Record): Promise + + setObjectBulk(args: [key: string, data: Record][]): Promise + + setObjectField( + key: string | string[], + field: string, + value: any, + ): Promise +} diff --git a/types/database/index.d.ts b/types/database/index.d.ts new file mode 100644 index 0000000000..8ec2e7d865 --- /dev/null +++ b/types/database/index.d.ts @@ -0,0 +1,54 @@ +import { Store } from 'express-session' + +export { Hash } from './hash' +export { List } from './list' +export { Set } from './set' +export { Item } from './string' +export { + SortedSet, + SortedSetTheoryOperation, + SortedSetScanBaseParameters, +} from './zset' + +export interface Database { + checkCompatibility(callback: () => void): Promise + + checkCompatibilityVersion( + version: string, + callback: () => void, + ): Promise + + close(): Promise + + createIndices(callback: () => void): Promise + + createSessionStore(options: any): Promise + + emptydb(): Promise + + flushdb(): Promise + + info(db: any): Promise + + init(): Promise +} + +export type RedisStyleMatchString = + | string + | `*${string}` + | `${string}*` + | `*${string}*` +export type RedisStyleRangeString = `${'(' | '['}${string}` | `${string}` + +export enum ObjectType { + HASH = 'hash', + LIST = 'list', + SET = 'set', + STRING = 'string', + SORTED_SET = 'zset', +} + +export type ValueAndScore = { value: string; score: number } +export type RedisStyleAggregate = 'SUM' | 'MIN' | 'MAX' +export type NumberTowardsMinima = number | '-inf' +export type NumberTowardsMaxima = number | '+inf' diff --git a/types/database/list.d.ts b/types/database/list.d.ts new file mode 100644 index 0000000000..aa43cfa738 --- /dev/null +++ b/types/database/list.d.ts @@ -0,0 +1,15 @@ +export interface List { + listPrepend(key: string, value: string): Promise + + listAppend(key: string, value: string): Promise + + listRemoveLast(key: string): Promise + + listRemoveAll(key: string, value: string | string[]): Promise + + listTrim(key: string, start: number, stop: number): Promise + + getListRange(key: string, start: number, stop: number): Promise + + listLength(key: string): Promise +} diff --git a/types/database/set.d.ts b/types/database/set.d.ts new file mode 100644 index 0000000000..5dcfcc5ab2 --- /dev/null +++ b/types/database/set.d.ts @@ -0,0 +1,25 @@ +export interface Set { + getSetMembers(key: string): Promise + + getSetsMembers(keys: string[]): Promise + + isMemberOfSets(sets: string[], value: string): Promise + + isSetMember(key: string, value: string): Promise + + isSetMembers(key: string, values: string[]): Promise + + setAdd(key: string, value: string | string[]): Promise + + setCount(key: string): Promise + + setRemove(key: string | string[], value: string | string[]): Promise + + setRemoveRandom(key: string): Promise + + setsAdd(keys: string[], value: string | string[]): Promise + + setsCount(keys: string[]): Promise + + setsRemove(keys: string[], value: string): Promise +} diff --git a/types/database/string.d.ts b/types/database/string.d.ts new file mode 100644 index 0000000000..090a5cf252 --- /dev/null +++ b/types/database/string.d.ts @@ -0,0 +1,35 @@ +import { ObjectType, RedisStyleMatchString } from './index' + +export interface Item { + delete(key: string): Promise + + deleteAll(keys: string[]): Promise + + exists(key: string): Promise + + exists(key: string[]): Promise + + expire(key: string, seconds: number): Promise + + expireAt(key: string, timestampInSeconds: number): Promise + + get(key: string): Promise + + increment(key: string): Promise + + pexpire(key: string, ms: number): Promise + + pexpireAt(key: string, timestampInMs: number): Promise + + pttl(key: string): Promise + + rename(oldkey: string, newkey: string): Promise + + scan(params: { match: RedisStyleMatchString }): Promise + + set(key: string, value: string): Promise + + ttl(key: string): Promise + + type(key: string): Promise +} diff --git a/types/database/zset.d.ts b/types/database/zset.d.ts new file mode 100644 index 0000000000..b3b5e71bff --- /dev/null +++ b/types/database/zset.d.ts @@ -0,0 +1,245 @@ +import { + NumberTowardsMaxima, + NumberTowardsMinima, + RedisStyleAggregate, + RedisStyleMatchString, + RedisStyleRangeString, + ValueAndScore, +} from './index' + +export type SortedSetTheoryOperation = { + sets: string[] + sort?: 'ASC' | 'DESC' + start?: number + stop?: number + weights?: number[] + aggregate?: RedisStyleAggregate +} + +export type SortedSetScanBaseParameters = { + key: string + match: RedisStyleMatchString + limit?: number +} + +export interface SortedSet { + getSortedSetIntersect( + params: SortedSetTheoryOperation & { withScores: true }, + ): Promise + + getSortedSetIntersect( + params: SortedSetTheoryOperation & { withScores?: false }, + ): Promise + + getSortedSetMembers(key: string): Promise + + getSortedSetMembersWithScores(key: string): Promise + + getSortedSetRange( + key: string | string[], + start: number, + stop: number, + ): Promise + + getSortedSetRangeByLex( + key: string | string[], + min: RedisStyleRangeString | '-', + max: RedisStyleRangeString | '+', + start?: number, + count?: number, + ): Promise + + getSortedSetRangeByScore( + key: string | string[], + start: number, + count: number, + min: NumberTowardsMinima, + max: NumberTowardsMaxima, + ): Promise + + getSortedSetRangeByScoreWithScores( + key: string | string[], + start: number, + count: number, + min: NumberTowardsMinima, + max: NumberTowardsMaxima, + ): Promise + + getSortedSetRangeWithScores( + key: string | string[], + start: number, + stop: number, + ): Promise + + getSortedSetRevIntersect( + params: SortedSetTheoryOperation & { withScores: true }, + ): Promise + + getSortedSetRevIntersect( + params: SortedSetTheoryOperation & { withScores?: false }, + ): Promise + + getSortedSetRevRange( + key: string | string[], + start: number, + stop: number, + ): Promise + + getSortedSetRevRangeByLex( + key: string, + max: RedisStyleRangeString | '+', + min: RedisStyleRangeString | '-', + start?: number, + count?: number, + ): Promise + + getSortedSetRevRangeByScore( + key: string, + start: number, + count: number, + max: NumberTowardsMaxima | '+', + min: NumberTowardsMinima | '-', + ): Promise + + getSortedSetRevRangeByScoreWithScores( + key: string, + start: number, + count: number, + max: NumberTowardsMaxima, + min: NumberTowardsMinima, + ): Promise + + getSortedSetRevRangeWithScores( + key: string, + start: number, + stop: number, + ): Promise + + getSortedSetRevUnion( + params: SortedSetTheoryOperation & { withScores?: false }, + ): Promise + + getSortedSetRevUnion( + params: SortedSetTheoryOperation & { withScores: true }, + ): Promise + + getSortedSetScan( + params: SortedSetScanBaseParameters & { withScores: true }, + ): Promise + + getSortedSetScan( + params: SortedSetScanBaseParameters & { withScores?: false }, + ): Promise + + getSortedSetUnion( + params: SortedSetTheoryOperation & { withScores: true }, + ): Promise + + getSortedSetUnion( + params: SortedSetTheoryOperation & { withScores?: false }, + ): Promise + + getSortedSetsMembers(keys: string[]): Promise + + getSortedSetsMembersWithScores(keys: string[]): Promise + + isMemberOfSortedSets(keys: string[], value: string): Promise + + isSortedSetMember(key: string, value: string): Promise + + isSortedSetMembers(key: string, values: string[]): Promise + + processSortedSet( + setKey: string, + processFn: (ids: number[]) => Promise | void, + options: { withScores?: boolean; batch?: number; interval?: number, reverse?: boolean; }, + ): Promise + + sortedSetAdd(key: string, score: number, value: string): Promise + + sortedSetAdd(key: string, score: number[], value: string[]): Promise + + sortedSetAddBulk( + args: [key: string, score: number[], value: string[]][], + ): Promise + + sortedSetCard(key: string): Promise + + sortedSetCount( + key: string, + min: NumberTowardsMinima, + max: NumberTowardsMaxima, + ): Promise + + sortedSetIncrBy( + key: string, + increment: number, + value: string, + ): Promise + + sortedSetIncrByBulk( + data: [key: string, increment: number, value: string][], + ): Promise + + sortedSetIntersectCard(keys: string[]): Promise + + sortedSetLexCount( + key: string, + min: RedisStyleRangeString, + max: RedisStyleRangeString, + ): Promise + + sortedSetRank(key: string, value: string): Promise + + sortedSetRanks(key: string, values: string[]): Promise<(number | null)[]> + + sortedSetRemove( + key: string | string[], + value: string | string[], + ): Promise + + sortedSetRemoveBulk(data: [key: string, member: string][]): Promise + + sortedSetRemoveRangeByLex( + key: string, + min: RedisStyleRangeString | '-', + max: RedisStyleRangeString | '+', + ): Promise + + sortedSetRevRank(key: string, value: string): Promise + + sortedSetRevRanks(key: string, values: string[]): Promise + + sortedSetScore(key: string, value: string): Promise + + sortedSetScores(key: string, values: string[]): Promise + + sortedSetUnionCard(keys: string[]): Promise + + sortedSetsAdd( + keys: string[], + scores: number | number[], + value: string, + ): Promise + + sortedSetsCard(keys: string[]): Promise + + sortedSetsCardSum(keys: string[]): Promise + + sortedSetsRanks( + keys: T, + values: { [K in keyof T]: string }, + ): Promise + + sortedSetsRemove(keys: string[], value: string): Promise + + sortedSetsRemoveRangeByScore( + keys: string[], + min: NumberTowardsMinima, + max: NumberTowardsMaxima, + ): Promise + + sortedSetsRevRanks(keys: string[], values: string[]): Promise + + sortedSetsScore(keys: string[], value: string): Promise +}