@amityco/ts-sdk 7.29.0 → 7.29.1-cc0fba8.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.
- package/dist/@types/core/errors.d.ts +2 -0
- package/dist/@types/core/errors.d.ts.map +1 -1
- package/dist/@types/domains/content.d.ts +11 -0
- package/dist/@types/domains/content.d.ts.map +1 -1
- package/dist/@types/domains/user.d.ts +31 -0
- package/dist/@types/domains/user.d.ts.map +1 -1
- package/dist/commentRepository/api/flagComment.d.ts +72 -5
- package/dist/commentRepository/api/flagComment.d.ts.map +1 -1
- package/dist/commentRepository/internalApi/flagCommentWithOptions.d.ts +13 -0
- package/dist/commentRepository/internalApi/flagCommentWithOptions.d.ts.map +1 -0
- package/dist/commentRepository/internalApi/flagCommentWithReasonString.d.ts +17 -0
- package/dist/commentRepository/internalApi/flagCommentWithReasonString.d.ts.map +1 -0
- package/dist/commentRepository/internalApi/index.d.ts +2 -0
- package/dist/commentRepository/internalApi/index.d.ts.map +1 -1
- package/dist/commentRepository/internalApi/tests/integration/flagCommentWithOptions.integration.test.d.ts +2 -0
- package/dist/commentRepository/internalApi/tests/integration/flagCommentWithOptions.integration.test.d.ts.map +1 -0
- package/dist/commentRepository/internalApi/tests/integration/flagCommentWithReasonString.integration.test.d.ts +2 -0
- package/dist/commentRepository/internalApi/tests/integration/flagCommentWithReasonString.integration.test.d.ts.map +1 -0
- package/dist/core/transports/tests/integration/serverErrorCodes.integration.test.d.ts +2 -0
- package/dist/core/transports/tests/integration/serverErrorCodes.integration.test.d.ts.map +1 -0
- package/dist/index.cjs.js +445 -51
- package/dist/index.esm.js +446 -52
- package/dist/index.umd.js +2 -2
- package/dist/messageRepository/api/flagMessage.d.ts +73 -6
- package/dist/messageRepository/api/flagMessage.d.ts.map +1 -1
- package/dist/messageRepository/api/tests/integration/flagMessage.overloads.integration.test.d.ts +2 -0
- package/dist/messageRepository/api/tests/integration/flagMessage.overloads.integration.test.d.ts.map +1 -0
- package/dist/messageRepository/internalApi/flagMessageWithOptions.d.ts +13 -0
- package/dist/messageRepository/internalApi/flagMessageWithOptions.d.ts.map +1 -0
- package/dist/messageRepository/internalApi/flagMessageWithReasonString.d.ts +18 -0
- package/dist/messageRepository/internalApi/flagMessageWithReasonString.d.ts.map +1 -0
- package/dist/messageRepository/internalApi/tests/integration/flagMessageWithOptions.integration.test.d.ts +2 -0
- package/dist/messageRepository/internalApi/tests/integration/flagMessageWithOptions.integration.test.d.ts.map +1 -0
- package/dist/messageRepository/internalApi/tests/integration/flagMessageWithReasonString.integration.test.d.ts +2 -0
- package/dist/messageRepository/internalApi/tests/integration/flagMessageWithReasonString.integration.test.d.ts.map +1 -0
- package/dist/postRepository/api/flagPost.d.ts +73 -6
- package/dist/postRepository/api/flagPost.d.ts.map +1 -1
- package/dist/postRepository/api/tests/integration/flagPost.overloads.integration.test.d.ts +2 -0
- package/dist/postRepository/api/tests/integration/flagPost.overloads.integration.test.d.ts.map +1 -0
- package/dist/postRepository/internalApi/flagPostWithOptions.d.ts +13 -0
- package/dist/postRepository/internalApi/flagPostWithOptions.d.ts.map +1 -0
- package/dist/postRepository/internalApi/flagPostWithReasonString.d.ts +17 -0
- package/dist/postRepository/internalApi/flagPostWithReasonString.d.ts.map +1 -0
- package/dist/postRepository/internalApi/index.d.ts +2 -0
- package/dist/postRepository/internalApi/index.d.ts.map +1 -1
- package/dist/postRepository/internalApi/tests/integration/flagPostWithOptions.integration.test.d.ts +2 -0
- package/dist/postRepository/internalApi/tests/integration/flagPostWithOptions.integration.test.d.ts.map +1 -0
- package/dist/postRepository/internalApi/tests/integration/flagPostWithReasonString.integration.test.d.ts +2 -0
- package/dist/postRepository/internalApi/tests/integration/flagPostWithReasonString.integration.test.d.ts.map +1 -0
- package/dist/userRepository/api/flagUser.d.ts +50 -9
- package/dist/userRepository/api/flagUser.d.ts.map +1 -1
- package/dist/userRepository/api/flagUserBehavior.d.ts +29 -0
- package/dist/userRepository/api/flagUserBehavior.d.ts.map +1 -0
- package/dist/userRepository/api/flagUserProfile.d.ts +29 -0
- package/dist/userRepository/api/flagUserProfile.d.ts.map +1 -0
- package/dist/userRepository/api/index.d.ts +2 -0
- package/dist/userRepository/api/index.d.ts.map +1 -1
- package/dist/userRepository/api/tests/integration/flagUser.overloads.integration.test.d.ts +2 -0
- package/dist/userRepository/api/tests/integration/flagUser.overloads.integration.test.d.ts.map +1 -0
- package/dist/userRepository/api/tests/integration/flagUserBehavior.integration.test.d.ts +2 -0
- package/dist/userRepository/api/tests/integration/flagUserBehavior.integration.test.d.ts.map +1 -0
- package/dist/userRepository/api/tests/integration/flagUserProfile.integration.test.d.ts +2 -0
- package/dist/userRepository/api/tests/integration/flagUserProfile.integration.test.d.ts.map +1 -0
- package/dist/userRepository/utils/submitUserReport.d.ts +10 -0
- package/dist/userRepository/utils/submitUserReport.d.ts.map +1 -0
- package/dist/userRepository/utils/userReport.d.ts +35 -0
- package/dist/userRepository/utils/userReport.d.ts.map +1 -0
- package/dist/utils/contentFlag.d.ts +28 -0
- package/dist/utils/contentFlag.d.ts.map +1 -0
- package/package.json +1 -1
package/dist/index.cjs.js
CHANGED
|
@@ -58,6 +58,18 @@ exports.UserReportTypeEnum = void 0;
|
|
|
58
58
|
UserReportTypeEnum["AVATAR"] = "avatarFileId";
|
|
59
59
|
UserReportTypeEnum["BEHAVIOR"] = "behavior";
|
|
60
60
|
})(exports.UserReportTypeEnum || (exports.UserReportTypeEnum = {}));
|
|
61
|
+
/**
|
|
62
|
+
* The profile field a user is reported for in `UserRepository.flagUserProfile`.
|
|
63
|
+
* Each member is the backend `reportType` wire value. There is deliberately no
|
|
64
|
+
* behavior member: behavior reports need a reason and go through
|
|
65
|
+
* `UserRepository.flagUserBehavior`.
|
|
66
|
+
*/
|
|
67
|
+
exports.UserProfileFieldEnum = void 0;
|
|
68
|
+
(function (UserProfileFieldEnum) {
|
|
69
|
+
UserProfileFieldEnum["DISPLAY_NAME"] = "displayName";
|
|
70
|
+
UserProfileFieldEnum["DESCRIPTION"] = "description";
|
|
71
|
+
UserProfileFieldEnum["AVATAR"] = "avatarFileId";
|
|
72
|
+
})(exports.UserProfileFieldEnum || (exports.UserProfileFieldEnum = {}));
|
|
61
73
|
|
|
62
74
|
const FileType = Object.freeze({
|
|
63
75
|
FILE: 'file',
|
|
@@ -834,6 +846,18 @@ class AmityModuleNotEntitledError extends ASCApiError {
|
|
|
834
846
|
this.type = 'AmityModuleNotEntitledError';
|
|
835
847
|
}
|
|
836
848
|
}
|
|
849
|
+
/**
|
|
850
|
+
* Input sanitization related error
|
|
851
|
+
* @category Errors
|
|
852
|
+
*/
|
|
853
|
+
class ASCInvalidParameterError extends ASCError {
|
|
854
|
+
/**
|
|
855
|
+
* @param message A custom error message
|
|
856
|
+
*/
|
|
857
|
+
constructor(message) {
|
|
858
|
+
super(message, 800110 /* Amity.ClientError.INVALID_PARAMETERS */, "error" /* Amity.ErrorLevel.ERROR */);
|
|
859
|
+
}
|
|
860
|
+
}
|
|
837
861
|
|
|
838
862
|
let activeClient = null;
|
|
839
863
|
/**
|
|
@@ -13451,7 +13475,7 @@ const getWatchSessionStorage = () => {
|
|
|
13451
13475
|
return storageInstance;
|
|
13452
13476
|
};
|
|
13453
13477
|
|
|
13454
|
-
const privateKey = "
|
|
13478
|
+
const privateKey = "MIIEpQIBAAKCAQEAwAEc/oZgYIvKSUG/C3mONYLR4ZPgAjMEX4bJ+xqqakUDRtqlNO+eZs2blQ1Ko0DBkqPExyQezvjibH5W2UZBV5RaBTlTcNVKTToMBEGesAfaEcM3qUyQHxdbFYZv6P4sb14dcwxTQ8usmaV8ooiR1Fcaso5ZWYcZ8Hb46FbQ7OoVumsBtPWwfZ4f003o5VCl6AIM6lcLv9UDLlFVYhE+PeXpRHtfWlGqxMvqC9oinlwhL6nWv6VjQXW4nhcib72dPBzfHT7k/PMKto2SxALYdb68ENiAGuJLWi3AUHSyYCJK2w7wIlWfJUAI0v26ub10IpExr6D5QuW2577jjP93iwIDAQABAoIBAFWfqXhwIIatkFY+9Z1+ZcbDQimgsmMIsUiQaX6Lk7e0cxOj6czDlxYtVtaPiNtow2pLkjNkjkCqiP7tEHnwdK9DvylZOTa2R15NJpK3WLcTqVIGhsn/FL5owfvFah6zSsmXZParZm5zY9NZE03ALZhOB9/cz0e3kf/EbpfeL2mW7MApyiUt5i09ycchroOpcWp73ipIxvgigtZyUGFmsQicWhUs28F0D7w4Qfk76yG3nqXeb+BAMhCaIaa/k/aAxhiZG/ygEQWQrcC8gfe+jyicMAQPDEVS9YuUMGsLjIjKuVLZzp2xirQnhc2i2zVNEIvG6soprPOBEMQugzrtX5ECgYEA3b7KAbBIbDl1e4ZSCWhHdHkiWVZHaopsR/LhqDDNhXjWjq3AesgV6k0j9EdziMn/HmmOso0bz99GTV3JZf4A9ztTLumJlkHbdVtlgOqSjrFLj12rH9KXTheyIhWSpUmm8+WB1xasFbqpvJaGo7F3pd2Fqj1XR4mp5BO7c/t7LJ0CgYEA3aouEzXQ9THRKYocdfY69EI1Il1t/d/RSqqd9BxEjxBgxkM13ZiYIn/R4WW/nCUrlmhxG44Aa2Gob4Ahfsui2xKTg/g/3Zk/rAxAEGkfOLGoenaJMD41fH4wUq3FRYwkvnaMb9Hd6f/TlBHslIRa2NN58bSBGJCyBP2b59+2+EcCgYEAixDVRXvV37GlYUOa/XVdosk5Zoe6oDGRuQm0xbNdoUBoZvDHDvme7ONWEiQha/8qtVsD+CyQ7awcPfb8kK9c0bBt+bTS6d4BkTcxkEkMgtrkBVR8Nqfu5jXsLH4VCv4G61zbMhZw8+ut+az5YX2yCN7Frj9sFlxapMRPQmzMEe0CgYEAumsAzM8ZqNv4mAK65Mnr0rhLj1cbxcKRdUYACOgtEFQpzxN/HZnTeFAe5nx3pI3uFlRHq3DFEYnT6dHMWaJQmAULYpVIwMi9L6gtyJ9fzoI6uqMtxRDMUqKdaSsTGOY/kJ6KhQ/unXi1K3XXjR+yd1+C0q+HUm1+CYxvrZYLfskCgYEArsEy+IQOiqniJ0NE2vVUF+UK/IRZaic9YKcpov5Ot7Vvzm/MnnW4N1ljVskocETBWMmPUvNSExVjPebi+rxd8fa5kY8BJScPTzMFbunZn/wjtGdcM10qdlVQ9doG61A/9P3ezFKCfS4AvF/H/59LcSx2Bh28fp3/efiVIOpVd4Y=";
|
|
13455
13479
|
/*
|
|
13456
13480
|
* The crypto algorithm used for importing key and signing string
|
|
13457
13481
|
*/
|
|
@@ -15250,18 +15274,18 @@ const buildFlagUserBody = (options) => {
|
|
|
15250
15274
|
/**
|
|
15251
15275
|
* ```js
|
|
15252
15276
|
* import { UserRepository } from '@amityco/ts-sdk'
|
|
15277
|
+
*
|
|
15278
|
+
* // Typeless report (supported).
|
|
15253
15279
|
* const flagged = await UserRepository.flagUser('userId')
|
|
15254
|
-
* const flaggedBehavior = await UserRepository.flagUser('userId', {
|
|
15255
|
-
* reportType: 'behavior',
|
|
15256
|
-
* reason: 'Harassment or bullying',
|
|
15257
|
-
* comment: 'optional free-text',
|
|
15258
|
-
* })
|
|
15259
15280
|
* ```
|
|
15260
15281
|
*
|
|
15282
|
+
* Flags a user. Two call shapes are accepted (see the overloads): id-only, which
|
|
15283
|
+
* sends no body and stays supported, and the deprecated structured options object,
|
|
15284
|
+
* whose request mapping is unchanged. New code reporting a profile field or behavior
|
|
15285
|
+
* should use `flagUserProfile` or `flagUserBehavior`.
|
|
15286
|
+
*
|
|
15261
15287
|
* @param userId The ID of the user to be flagged
|
|
15262
|
-
* @param options
|
|
15263
|
-
* body: `reportType`, `reason`, `comment`. Only non-null fields are included.
|
|
15264
|
-
* All validation is server-side; a bodyless call produces a typeless report.
|
|
15288
|
+
* @param options Deprecated report metadata; omit for a typeless report
|
|
15265
15289
|
* @returns the flagged {@link Amity.User}
|
|
15266
15290
|
*
|
|
15267
15291
|
* @category User API
|
|
@@ -15282,6 +15306,156 @@ const flagUser = async (userId, options) => {
|
|
|
15282
15306
|
};
|
|
15283
15307
|
/* end_public_function */
|
|
15284
15308
|
|
|
15309
|
+
/**
|
|
15310
|
+
* Sends a validated split user report (`flagUserProfile` / `flagUserBehavior`) to the
|
|
15311
|
+
* same endpoint as `flagUser`, then persists the returned user and fires `user.flagged`
|
|
15312
|
+
* exactly as `flagUser` does, so all three calls share return, cache and event behaviour.
|
|
15313
|
+
*
|
|
15314
|
+
* Not exported from the public API.
|
|
15315
|
+
*/
|
|
15316
|
+
const submitUserReport = async (apiName, userId, body) => {
|
|
15317
|
+
var _a;
|
|
15318
|
+
const client = getActiveClient();
|
|
15319
|
+
client.log(`user/${apiName}`, { userId, body });
|
|
15320
|
+
const { data } = await client.http.post(`/api/v4/me/flags/${encodeURIComponent(userId)}`, body);
|
|
15321
|
+
const payload = prepareUserPayload(data);
|
|
15322
|
+
if (client.cache) {
|
|
15323
|
+
ingestInCache(payload);
|
|
15324
|
+
}
|
|
15325
|
+
fireEvent('user.flagged', data);
|
|
15326
|
+
return (_a = payload.users.find(user => user.userId === userId)) !== null && _a !== void 0 ? _a : payload.users[0];
|
|
15327
|
+
};
|
|
15328
|
+
|
|
15329
|
+
/** Maximum `comment` length, in string length units, after trimming. */
|
|
15330
|
+
const USER_REPORT_COMMENT_MAX_LENGTH = 300;
|
|
15331
|
+
const PROFILE_FIELDS = Object.values(exports.UserProfileFieldEnum);
|
|
15332
|
+
const BEHAVIOR_REASONS = Object.values(exports.ContentFlagReasonEnum);
|
|
15333
|
+
const assertOptionsObject = (apiName, options, shape) => {
|
|
15334
|
+
if (typeof options !== 'object' || options === null || Array.isArray(options)) {
|
|
15335
|
+
throw new ASCInvalidParameterError(`${apiName}: expected an options object \`${shape}\``);
|
|
15336
|
+
}
|
|
15337
|
+
return options;
|
|
15338
|
+
};
|
|
15339
|
+
/**
|
|
15340
|
+
* Normalizes an optional reporter `comment`: it must be a string when supplied (`null`
|
|
15341
|
+
* is not a valid supplied comment); it is trimmed; a blank result is omitted (the
|
|
15342
|
+
* backend rejects `""`); a result longer than 300 characters is rejected before any
|
|
15343
|
+
* request. Otherwise the trimmed text is returned unchanged.
|
|
15344
|
+
*
|
|
15345
|
+
* @throws {ASCInvalidParameterError} `INVALID_PARAMETERS` for a non-string or over-length comment
|
|
15346
|
+
*/
|
|
15347
|
+
const normalizeUserReportComment = (apiName, comment) => {
|
|
15348
|
+
if (comment === undefined)
|
|
15349
|
+
return undefined;
|
|
15350
|
+
if (typeof comment !== 'string') {
|
|
15351
|
+
throw new ASCInvalidParameterError(`${apiName}: \`comment\` must be a string when supplied`);
|
|
15352
|
+
}
|
|
15353
|
+
const trimmed = comment.trim();
|
|
15354
|
+
if (trimmed.length === 0)
|
|
15355
|
+
return undefined;
|
|
15356
|
+
if (trimmed.length > USER_REPORT_COMMENT_MAX_LENGTH) {
|
|
15357
|
+
throw new ASCInvalidParameterError(`${apiName}: \`comment\` must be at most ${USER_REPORT_COMMENT_MAX_LENGTH} characters after trimming`);
|
|
15358
|
+
}
|
|
15359
|
+
return trimmed;
|
|
15360
|
+
};
|
|
15361
|
+
const withComment = (body, comment) => comment === undefined ? body : Object.assign(Object.assign({}, body), { comment });
|
|
15362
|
+
/**
|
|
15363
|
+
* Validates `flagUserProfile` options and builds its request body. Untyped callers can
|
|
15364
|
+
* pass anything at runtime, so nothing is trusted from the declared type. Any `reason`
|
|
15365
|
+
* key is ignored and never sent.
|
|
15366
|
+
*
|
|
15367
|
+
* @throws {ASCInvalidParameterError} `INVALID_PARAMETERS` when the options are malformed
|
|
15368
|
+
*/
|
|
15369
|
+
const toUserProfileReportBody = (options) => {
|
|
15370
|
+
const apiName = 'flagUserProfile';
|
|
15371
|
+
const { field, comment } = assertOptionsObject(apiName, options, '{ field, comment? }');
|
|
15372
|
+
if (typeof field !== 'string' || !PROFILE_FIELDS.includes(field)) {
|
|
15373
|
+
throw new ASCInvalidParameterError(`${apiName}: \`field\` must be a \`UserProfileFieldEnum\` value`);
|
|
15374
|
+
}
|
|
15375
|
+
return withComment({ reportType: field }, normalizeUserReportComment(apiName, comment));
|
|
15376
|
+
};
|
|
15377
|
+
/**
|
|
15378
|
+
* Validates `flagUserBehavior` options and builds its request body. `reason` must be one
|
|
15379
|
+
* of the nine `ContentFlagReasonEnum` values and is sent as that canonical label;
|
|
15380
|
+
* `reportType` is always `behavior`.
|
|
15381
|
+
*
|
|
15382
|
+
* @throws {ASCInvalidParameterError} `INVALID_PARAMETERS` when the options are malformed
|
|
15383
|
+
*/
|
|
15384
|
+
const toUserBehaviorReportBody = (options) => {
|
|
15385
|
+
const apiName = 'flagUserBehavior';
|
|
15386
|
+
const { reason, comment } = assertOptionsObject(apiName, options, '{ reason, comment? }');
|
|
15387
|
+
if (typeof reason !== 'string' || !BEHAVIOR_REASONS.includes(reason)) {
|
|
15388
|
+
throw new ASCInvalidParameterError(`${apiName}: \`reason\` must be a \`ContentFlagReasonEnum\` value`);
|
|
15389
|
+
}
|
|
15390
|
+
return withComment({ reportType: 'behavior', reason }, normalizeUserReportComment(apiName, comment));
|
|
15391
|
+
};
|
|
15392
|
+
|
|
15393
|
+
/* begin_public_function
|
|
15394
|
+
id: user.flag_profile
|
|
15395
|
+
*/
|
|
15396
|
+
/**
|
|
15397
|
+
* ```js
|
|
15398
|
+
* import { UserRepository, UserProfileFieldEnum } from '@amityco/ts-sdk'
|
|
15399
|
+
* const flagged = await UserRepository.flagUserProfile('userId', {
|
|
15400
|
+
* field: UserProfileFieldEnum.AVATAR,
|
|
15401
|
+
* comment: 'Nudity in profile photo',
|
|
15402
|
+
* })
|
|
15403
|
+
* ```
|
|
15404
|
+
*
|
|
15405
|
+
* Reports one of a user's profile fields (display name, description or avatar). The
|
|
15406
|
+
* call has no reason: profile reports never carry one, so the backend's reason rules
|
|
15407
|
+
* cannot be violated from here. A `reason` key passed at runtime is ignored and never sent.
|
|
15408
|
+
*
|
|
15409
|
+
* `comment` is trimmed; a blank comment is omitted from the request; a comment longer
|
|
15410
|
+
* than 300 characters after trimming is rejected before any request. Otherwise the
|
|
15411
|
+
* trimmed text is sent unchanged.
|
|
15412
|
+
*
|
|
15413
|
+
* Sends `POST /api/v4/me/flags/:userId` with `{ reportType: <field>, comment? }`.
|
|
15414
|
+
*
|
|
15415
|
+
* @param userId The ID of the user to be reported
|
|
15416
|
+
* @param options `field` is a `UserProfileFieldEnum` value; `comment` is optional free text
|
|
15417
|
+
* @returns the flagged {@link Amity.User}
|
|
15418
|
+
* @throws {ASCInvalidParameterError} `INVALID_PARAMETERS` when `options` is missing or malformed, or `comment` is over 300 characters, before any request is made
|
|
15419
|
+
*
|
|
15420
|
+
* @category User API
|
|
15421
|
+
* @async
|
|
15422
|
+
* */
|
|
15423
|
+
const flagUserProfile = async (userId, options) => submitUserReport('flagUserProfile', userId, toUserProfileReportBody(options));
|
|
15424
|
+
/* end_public_function */
|
|
15425
|
+
|
|
15426
|
+
/* begin_public_function
|
|
15427
|
+
id: user.flag_behavior
|
|
15428
|
+
*/
|
|
15429
|
+
/**
|
|
15430
|
+
* ```js
|
|
15431
|
+
* import { UserRepository, ContentFlagReasonEnum } from '@amityco/ts-sdk'
|
|
15432
|
+
* const flagged = await UserRepository.flagUserBehavior('userId', {
|
|
15433
|
+
* reason: ContentFlagReasonEnum.Others,
|
|
15434
|
+
* comment: 'Impersonating our brand',
|
|
15435
|
+
* })
|
|
15436
|
+
* ```
|
|
15437
|
+
*
|
|
15438
|
+
* Reports a user's behavior. `reason` is required and is one of the nine
|
|
15439
|
+
* `ContentFlagReasonEnum` values, sent as its canonical label. Reporter text, including
|
|
15440
|
+
* the explanation for `Others`, always travels in `comment`; the reason never carries text.
|
|
15441
|
+
*
|
|
15442
|
+
* `comment` is trimmed; a blank comment is omitted from the request; a comment longer
|
|
15443
|
+
* than 300 characters after trimming is rejected before any request. Otherwise the
|
|
15444
|
+
* trimmed text is sent unchanged.
|
|
15445
|
+
*
|
|
15446
|
+
* Sends `POST /api/v4/me/flags/:userId` with `{ reportType: 'behavior', reason, comment? }`.
|
|
15447
|
+
*
|
|
15448
|
+
* @param userId The ID of the user to be reported
|
|
15449
|
+
* @param options `reason` is a `ContentFlagReasonEnum` value; `comment` is optional free text
|
|
15450
|
+
* @returns the flagged {@link Amity.User}
|
|
15451
|
+
* @throws {ASCInvalidParameterError} `INVALID_PARAMETERS` when `options` is missing or malformed, `reason` is missing or unknown, or `comment` is over 300 characters, before any request is made
|
|
15452
|
+
*
|
|
15453
|
+
* @category User API
|
|
15454
|
+
* @async
|
|
15455
|
+
* */
|
|
15456
|
+
const flagUserBehavior = async (userId, options) => submitUserReport('flagUserBehavior', userId, toUserBehaviorReportBody(options));
|
|
15457
|
+
/* end_public_function */
|
|
15458
|
+
|
|
15285
15459
|
/* begin_public_function
|
|
15286
15460
|
id: user.unflag
|
|
15287
15461
|
*/
|
|
@@ -16456,6 +16630,8 @@ var index$r = /*#__PURE__*/Object.freeze({
|
|
|
16456
16630
|
getUserByIds: getUserByIds,
|
|
16457
16631
|
updateUser: updateUser,
|
|
16458
16632
|
flagUser: flagUser,
|
|
16633
|
+
flagUserProfile: flagUserProfile,
|
|
16634
|
+
flagUserBehavior: flagUserBehavior,
|
|
16459
16635
|
unflagUser: unflagUser,
|
|
16460
16636
|
isUserFlaggedByMe: isUserFlaggedByMe,
|
|
16461
16637
|
getAllBlockedUsers: getAllBlockedUsers,
|
|
@@ -20160,23 +20336,85 @@ getDeliveredUsers.locally = (query) => {
|
|
|
20160
20336
|
return { data: users, cachedAt, prevPage, nextPage };
|
|
20161
20337
|
};
|
|
20162
20338
|
|
|
20163
|
-
|
|
20164
|
-
id: message.flag
|
|
20165
|
-
*/
|
|
20339
|
+
const CONTENT_FLAG_REASONS = Object.values(exports.ContentFlagReasonEnum);
|
|
20166
20340
|
/**
|
|
20167
|
-
*
|
|
20168
|
-
*
|
|
20169
|
-
*
|
|
20170
|
-
|
|
20341
|
+
* True when a public `flagX(id, input)` argument is the legacy shape (a reason string
|
|
20342
|
+
* or nothing). Anything else is routed to the `Amity.ContentFlagOptions` path, whose
|
|
20343
|
+
* validation rejects malformed values before any request is made.
|
|
20344
|
+
*/
|
|
20345
|
+
const isLegacyContentFlagReason = (input) => input === undefined || typeof input === 'string';
|
|
20346
|
+
/**
|
|
20347
|
+
* Validates an `Amity.ContentFlagOptions` argument. Untyped (plain JS) callers can pass
|
|
20348
|
+
* anything at runtime, so the checks do not trust the declared type: the value must be a
|
|
20349
|
+
* plain object, `reason` must be one of the nine `ContentFlagReasonEnum` values and
|
|
20350
|
+
* `detail`, when supplied, must be a string (`null` is not a valid supplied detail).
|
|
20171
20351
|
*
|
|
20172
|
-
* @param
|
|
20173
|
-
* @
|
|
20174
|
-
|
|
20352
|
+
* @param apiName used in the error message, e.g. `flagPost`
|
|
20353
|
+
* @throws {ASCInvalidParameterError} `INVALID_PARAMETERS` when the options are malformed
|
|
20354
|
+
*/
|
|
20355
|
+
const validateContentFlagOptions = (apiName, options) => {
|
|
20356
|
+
if (typeof options !== 'object' || options === null || Array.isArray(options)) {
|
|
20357
|
+
throw new ASCInvalidParameterError(`${apiName}: expected an options object \`{ reason, detail? }\``);
|
|
20358
|
+
}
|
|
20359
|
+
const { reason, detail } = options;
|
|
20360
|
+
if (typeof reason !== 'string' || !CONTENT_FLAG_REASONS.includes(reason)) {
|
|
20361
|
+
throw new ASCInvalidParameterError(`${apiName}: \`reason\` must be a \`ContentFlagReasonEnum\` value`);
|
|
20362
|
+
}
|
|
20363
|
+
if (detail !== undefined && typeof detail !== 'string') {
|
|
20364
|
+
throw new ASCInvalidParameterError(`${apiName}: \`detail\` must be a string when supplied`);
|
|
20365
|
+
}
|
|
20366
|
+
return { reason: reason, detail };
|
|
20367
|
+
};
|
|
20368
|
+
/**
|
|
20369
|
+
* Builds the request body for validated options. `detail` is forwarded unchanged (empty
|
|
20370
|
+
* and whitespace-only strings included) and omitted from the body when `undefined`; the
|
|
20371
|
+
* backend enforces the 300-character limit.
|
|
20372
|
+
*/
|
|
20373
|
+
const toContentFlagBody = ({ reason, detail }) => detail === undefined ? { reason } : { reason, detail };
|
|
20374
|
+
|
|
20375
|
+
/**
|
|
20376
|
+
* New `flagMessage(messageId, { reason, detail? })` implementation. Any category,
|
|
20377
|
+
* including `Others`, may carry a `detail`. `detail` is forwarded unchanged (empty and
|
|
20378
|
+
* whitespace-only strings included) and omitted from the request body when `undefined`;
|
|
20379
|
+
* the backend enforces the 300-character limit.
|
|
20175
20380
|
*
|
|
20176
|
-
*
|
|
20177
|
-
*
|
|
20178
|
-
*
|
|
20179
|
-
|
|
20381
|
+
* Not exported from the public API. It is reached through the
|
|
20382
|
+
* `MessageRepository.flagMessage(messageId, options)` overload; see `api/flagMessage.ts`.
|
|
20383
|
+
*
|
|
20384
|
+
* @throws {ASCInvalidParameterError} `INVALID_PARAMETERS` when `options` is malformed, before any request is made
|
|
20385
|
+
*/
|
|
20386
|
+
const flagMessageWithOptions = async (messageId, options) => {
|
|
20387
|
+
// Validate first: an input error must surface as INVALID_PARAMETERS regardless of
|
|
20388
|
+
// whether a client is active, and validation needs nothing from the client.
|
|
20389
|
+
const body = toContentFlagBody(validateContentFlagOptions('flagMessage', options));
|
|
20390
|
+
const client = getActiveClient();
|
|
20391
|
+
client.log('message/flag', messageId);
|
|
20392
|
+
const { data: payload } = await client.http.post(`/api/v5/messages/${encodeURIComponent(messageId)}/flags`, body);
|
|
20393
|
+
if (client.cache) {
|
|
20394
|
+
const messagePayload = await prepareMessagePayload(payload);
|
|
20395
|
+
ingestInCache(messagePayload);
|
|
20396
|
+
}
|
|
20397
|
+
fireEvent('message.flagged', payload);
|
|
20398
|
+
return !!payload;
|
|
20399
|
+
};
|
|
20400
|
+
|
|
20401
|
+
/**
|
|
20402
|
+
* Legacy `flagMessage(messageId, reason?)` implementation, kept verbatim so existing
|
|
20403
|
+
* callers keep the exact request body they had before the options contract existed:
|
|
20404
|
+
*
|
|
20405
|
+
* - predefined `ContentFlagReasonEnum` value → `{ reason: <value>, detail: '' }`
|
|
20406
|
+
* - any other non-empty string (including the literal `'Others'`) → `{ reason: 'Others', detail: <string> }`
|
|
20407
|
+
* - `undefined` or `''` → `{ reason: 'Others', detail: '' }`
|
|
20408
|
+
* (for `undefined` the message body carries `detail: undefined`, which JSON serialization omits)
|
|
20409
|
+
*
|
|
20410
|
+
* Not exported from the public API. It is reached through the deprecated
|
|
20411
|
+
* `MessageRepository.flagMessage(messageId, reason)` overload; see `api/flagMessage.ts`.
|
|
20412
|
+
*
|
|
20413
|
+
* Not itself deprecated: it implements the deprecated legacy-string overload of the public
|
|
20414
|
+
* `flagMessage`, which carries the deprecation tag. New code should use `flagMessageWithOptions`
|
|
20415
|
+
* (the `{ reason, detail? }` contract). This path stays available throughout the current major version.
|
|
20416
|
+
*/
|
|
20417
|
+
const flagMessageWithReasonString = async (messageId, reason) => {
|
|
20180
20418
|
const client = getActiveClient();
|
|
20181
20419
|
client.log('message/flag', messageId);
|
|
20182
20420
|
const isPredefinedReason = reason &&
|
|
@@ -20193,6 +20431,42 @@ const flagMessage = async (messageId, reason) => {
|
|
|
20193
20431
|
fireEvent('message.flagged', payload);
|
|
20194
20432
|
return !!payload;
|
|
20195
20433
|
};
|
|
20434
|
+
|
|
20435
|
+
/* begin_public_function
|
|
20436
|
+
id: message.flag
|
|
20437
|
+
*/
|
|
20438
|
+
/**
|
|
20439
|
+
* ```js
|
|
20440
|
+
* import { MessageRepository, ContentFlagReasonEnum } from '@amityco/ts-sdk'
|
|
20441
|
+
*
|
|
20442
|
+
* // No reason.
|
|
20443
|
+
* await MessageRepository.flagMessage(messageId)
|
|
20444
|
+
*
|
|
20445
|
+
* // Category plus optional reporter context (any category, including Others).
|
|
20446
|
+
* await MessageRepository.flagMessage(messageId, {
|
|
20447
|
+
* reason: ContentFlagReasonEnum.SpamOrScams,
|
|
20448
|
+
* detail: 'Repeated promotional links',
|
|
20449
|
+
* })
|
|
20450
|
+
* ```
|
|
20451
|
+
*
|
|
20452
|
+
* Reports a message to moderation. Three call shapes are accepted (see the overloads):
|
|
20453
|
+
* id-only, an options object, and the deprecated legacy reason string. The public
|
|
20454
|
+
* name only dispatches on the input shape; the two implementations are kept separate
|
|
20455
|
+
* so the legacy path is untouched by the new contract:
|
|
20456
|
+
*
|
|
20457
|
+
* - `undefined` or a string → `flagMessageWithReasonString` (unchanged legacy mapping)
|
|
20458
|
+
* - anything else → `flagMessageWithOptions` (validated `{ reason, detail? }`)
|
|
20459
|
+
*
|
|
20460
|
+
* @param messageId The ID of the message to flag
|
|
20461
|
+
* @param input an options object `{ reason, detail? }`, a legacy reason string, or nothing
|
|
20462
|
+
* @returns `true` when the report was created
|
|
20463
|
+
*
|
|
20464
|
+
* @category Message API
|
|
20465
|
+
* @async
|
|
20466
|
+
* */
|
|
20467
|
+
const flagMessage = (messageId, input) => isLegacyContentFlagReason(input)
|
|
20468
|
+
? flagMessageWithReasonString(messageId, input)
|
|
20469
|
+
: flagMessageWithOptions(messageId, input);
|
|
20196
20470
|
/* end_public_function */
|
|
20197
20471
|
|
|
20198
20472
|
/* begin_public_function
|
|
@@ -27338,23 +27612,22 @@ const declineComment = async (commentId, reason) => {
|
|
|
27338
27612
|
};
|
|
27339
27613
|
/* end_public_function */
|
|
27340
27614
|
|
|
27341
|
-
/* begin_public_function
|
|
27342
|
-
id: comment.flag
|
|
27343
|
-
*/
|
|
27344
27615
|
/**
|
|
27345
|
-
*
|
|
27346
|
-
*
|
|
27347
|
-
* const flagged = await CommentRepository.flagComment(commentId, reason)
|
|
27348
|
-
* ```
|
|
27616
|
+
* Legacy `flagComment(commentId, reason?)` implementation, kept verbatim so existing
|
|
27617
|
+
* callers keep the exact request body they had before the options contract existed:
|
|
27349
27618
|
*
|
|
27350
|
-
*
|
|
27351
|
-
*
|
|
27352
|
-
*
|
|
27619
|
+
* - predefined `ContentFlagReasonEnum` value → `{ reason: <value>, detail: '' }`
|
|
27620
|
+
* - any other non-empty string (including the literal `'Others'`) → `{ reason: 'Others', detail: <string> }`
|
|
27621
|
+
* - `undefined` or `''` → `{ reason: 'Others', detail: '' }`
|
|
27353
27622
|
*
|
|
27354
|
-
*
|
|
27355
|
-
*
|
|
27356
|
-
*
|
|
27357
|
-
|
|
27623
|
+
* Not exported from the public API. It is reached through the deprecated
|
|
27624
|
+
* `CommentRepository.flagComment(commentId, reason)` overload; see `api/flagComment.ts`.
|
|
27625
|
+
*
|
|
27626
|
+
* Not itself deprecated: it implements the deprecated legacy-string overload of the public
|
|
27627
|
+
* `flagComment`, which carries the deprecation tag. New code should use `flagCommentWithOptions`
|
|
27628
|
+
* (the `{ reason, detail? }` contract). This path stays available throughout the current major version.
|
|
27629
|
+
*/
|
|
27630
|
+
const flagCommentWithReasonString = async (commentId, reason) => {
|
|
27358
27631
|
const client = getActiveClient();
|
|
27359
27632
|
client.log('comment/flagComment', commentId);
|
|
27360
27633
|
const isPredefinedReason = reason &&
|
|
@@ -27370,6 +27643,67 @@ const flagComment = async (commentId, reason) => {
|
|
|
27370
27643
|
fireEvent('comment.flagged', payload);
|
|
27371
27644
|
return !!payload;
|
|
27372
27645
|
};
|
|
27646
|
+
|
|
27647
|
+
/**
|
|
27648
|
+
* New `flagComment(commentId, { reason, detail? })` implementation. Any category,
|
|
27649
|
+
* including `Others`, may carry a `detail`. `detail` is forwarded unchanged (empty and
|
|
27650
|
+
* whitespace-only strings included) and omitted from the request body when `undefined`;
|
|
27651
|
+
* the backend enforces the 300-character limit.
|
|
27652
|
+
*
|
|
27653
|
+
* Not exported from the public API. It is reached through the
|
|
27654
|
+
* `CommentRepository.flagComment(commentId, options)` overload; see `api/flagComment.ts`.
|
|
27655
|
+
*
|
|
27656
|
+
* @throws {ASCInvalidParameterError} `INVALID_PARAMETERS` when `options` is malformed, before any request is made
|
|
27657
|
+
*/
|
|
27658
|
+
const flagCommentWithOptions = async (commentId, options) => {
|
|
27659
|
+
// Validate first: an input error must surface as INVALID_PARAMETERS regardless of
|
|
27660
|
+
// whether a client is active, and validation needs nothing from the client.
|
|
27661
|
+
const body = toContentFlagBody(validateContentFlagOptions('flagComment', options));
|
|
27662
|
+
const client = getActiveClient();
|
|
27663
|
+
client.log('comment/flagComment', commentId);
|
|
27664
|
+
const { data: payload } = await client.http.post(`/api/v3/comments/${encodeURIComponent(commentId)}/flag`, body);
|
|
27665
|
+
if (client.cache) {
|
|
27666
|
+
ingestInCache(payload);
|
|
27667
|
+
}
|
|
27668
|
+
fireEvent('comment.flagged', payload);
|
|
27669
|
+
return !!payload;
|
|
27670
|
+
};
|
|
27671
|
+
|
|
27672
|
+
/* begin_public_function
|
|
27673
|
+
id: comment.flag
|
|
27674
|
+
*/
|
|
27675
|
+
/**
|
|
27676
|
+
* ```js
|
|
27677
|
+
* import { CommentRepository, ContentFlagReasonEnum } from '@amityco/ts-sdk'
|
|
27678
|
+
*
|
|
27679
|
+
* // No reason: sent as Others with an empty detail.
|
|
27680
|
+
* await CommentRepository.flagComment(commentId)
|
|
27681
|
+
*
|
|
27682
|
+
* // Category plus optional reporter context (any category, including Others).
|
|
27683
|
+
* await CommentRepository.flagComment(commentId, {
|
|
27684
|
+
* reason: ContentFlagReasonEnum.SpamOrScams,
|
|
27685
|
+
* detail: 'Repeated promotional links',
|
|
27686
|
+
* })
|
|
27687
|
+
* ```
|
|
27688
|
+
*
|
|
27689
|
+
* Reports a comment to moderation. Three call shapes are accepted (see the overloads):
|
|
27690
|
+
* id-only, an options object, and the deprecated legacy reason string. The public
|
|
27691
|
+
* name only dispatches on the input shape; the two implementations are kept separate
|
|
27692
|
+
* so the legacy path is untouched by the new contract:
|
|
27693
|
+
*
|
|
27694
|
+
* - `undefined` or a string → `flagCommentWithReasonString` (unchanged legacy mapping)
|
|
27695
|
+
* - anything else → `flagCommentWithOptions` (validated `{ reason, detail? }`)
|
|
27696
|
+
*
|
|
27697
|
+
* @param commentId The ID of the comment to flag
|
|
27698
|
+
* @param input an options object `{ reason, detail? }`, a legacy reason string, or nothing
|
|
27699
|
+
* @returns `true` when the report was created
|
|
27700
|
+
*
|
|
27701
|
+
* @category Comment API
|
|
27702
|
+
* @async
|
|
27703
|
+
* */
|
|
27704
|
+
const flagComment = (commentId, input) => isLegacyContentFlagReason(input)
|
|
27705
|
+
? flagCommentWithReasonString(commentId, input)
|
|
27706
|
+
: flagCommentWithOptions(commentId, input);
|
|
27373
27707
|
/* end_public_function */
|
|
27374
27708
|
|
|
27375
27709
|
/* begin_public_function
|
|
@@ -29723,23 +30057,47 @@ const declinePost = async (postId) => {
|
|
|
29723
30057
|
};
|
|
29724
30058
|
/* end_public_function */
|
|
29725
30059
|
|
|
29726
|
-
/* begin_public_function
|
|
29727
|
-
id: post.flag
|
|
29728
|
-
*/
|
|
29729
30060
|
/**
|
|
29730
|
-
*
|
|
29731
|
-
*
|
|
29732
|
-
*
|
|
29733
|
-
*
|
|
30061
|
+
* New `flagPost(postId, { reason, detail? })` implementation. Any category, including
|
|
30062
|
+
* `Others`, may carry a `detail`. `detail` is forwarded unchanged (empty and
|
|
30063
|
+
* whitespace-only strings included) and omitted from the request body when `undefined`;
|
|
30064
|
+
* the backend enforces the 300-character limit.
|
|
29734
30065
|
*
|
|
29735
|
-
*
|
|
29736
|
-
*
|
|
29737
|
-
* @returns a boolean
|
|
30066
|
+
* Not exported from the public API. It is reached through the
|
|
30067
|
+
* `PostRepository.flagPost(postId, options)` overload; see `api/flagPost.ts`.
|
|
29738
30068
|
*
|
|
29739
|
-
* @
|
|
29740
|
-
|
|
29741
|
-
|
|
29742
|
-
|
|
30069
|
+
* @throws {ASCInvalidParameterError} `INVALID_PARAMETERS` when `options` is malformed, before any request is made
|
|
30070
|
+
*/
|
|
30071
|
+
const flagPostWithOptions = async (postId, options) => {
|
|
30072
|
+
// Validate first: an input error must surface as INVALID_PARAMETERS regardless of
|
|
30073
|
+
// whether a client is active, and validation needs nothing from the client.
|
|
30074
|
+
const body = toContentFlagBody(validateContentFlagOptions('flagPost', options));
|
|
30075
|
+
const client = getActiveClient();
|
|
30076
|
+
client.log('post/flagPost', postId);
|
|
30077
|
+
const { data: payload } = await client.http.post(`/api/v3/posts/${encodeURIComponent(postId)}/flag`, body);
|
|
30078
|
+
if (client.cache) {
|
|
30079
|
+
ingestInCache(prepareMembershipPayload(payload, 'communityUsers'));
|
|
30080
|
+
}
|
|
30081
|
+
fireEvent('post.flagged', payload);
|
|
30082
|
+
return !!payload;
|
|
30083
|
+
};
|
|
30084
|
+
|
|
30085
|
+
/**
|
|
30086
|
+
* Legacy `flagPost(postId, reason?)` implementation, kept verbatim so existing
|
|
30087
|
+
* callers keep the exact request body they had before the options contract existed:
|
|
30088
|
+
*
|
|
30089
|
+
* - predefined `ContentFlagReasonEnum` value → `{ reason: <value>, detail: '' }`
|
|
30090
|
+
* - any other non-empty string (including the literal `'Others'`) → `{ reason: 'Others', detail: <string> }`
|
|
30091
|
+
* - `undefined` or `''` → `{ reason: 'Others', detail: '' }`
|
|
30092
|
+
*
|
|
30093
|
+
* Not exported from the public API. It is reached through the deprecated
|
|
30094
|
+
* `PostRepository.flagPost(postId, reason)` overload; see `api/flagPost.ts`.
|
|
30095
|
+
*
|
|
30096
|
+
* Not itself deprecated: it implements the deprecated legacy-string overload of the public
|
|
30097
|
+
* `flagPost`, which carries the deprecation tag. New code should use `flagPostWithOptions`
|
|
30098
|
+
* (the `{ reason, detail? }` contract). This path stays available throughout the current major version.
|
|
30099
|
+
*/
|
|
30100
|
+
const flagPostWithReasonString = async (postId, reason) => {
|
|
29743
30101
|
const client = getActiveClient();
|
|
29744
30102
|
client.log('post/flagPost', postId);
|
|
29745
30103
|
const isPredefinedReason = reason &&
|
|
@@ -29755,6 +30113,42 @@ const flagPost = async (postId, reason) => {
|
|
|
29755
30113
|
fireEvent('post.flagged', payload);
|
|
29756
30114
|
return !!payload;
|
|
29757
30115
|
};
|
|
30116
|
+
|
|
30117
|
+
/* begin_public_function
|
|
30118
|
+
id: post.flag
|
|
30119
|
+
*/
|
|
30120
|
+
/**
|
|
30121
|
+
* ```js
|
|
30122
|
+
* import { PostRepository, ContentFlagReasonEnum } from '@amityco/ts-sdk'
|
|
30123
|
+
*
|
|
30124
|
+
* // No reason.
|
|
30125
|
+
* await PostRepository.flagPost(postId)
|
|
30126
|
+
*
|
|
30127
|
+
* // Category plus optional reporter context (any category, including Others).
|
|
30128
|
+
* await PostRepository.flagPost(postId, {
|
|
30129
|
+
* reason: ContentFlagReasonEnum.SpamOrScams,
|
|
30130
|
+
* detail: 'Repeated promotional links',
|
|
30131
|
+
* })
|
|
30132
|
+
* ```
|
|
30133
|
+
*
|
|
30134
|
+
* Reports a post to moderation. Three call shapes are accepted (see the overloads):
|
|
30135
|
+
* id-only, an options object, and the deprecated legacy reason string. The public
|
|
30136
|
+
* name only dispatches on the input shape; the two implementations are kept separate
|
|
30137
|
+
* so the legacy path is untouched by the new contract:
|
|
30138
|
+
*
|
|
30139
|
+
* - `undefined` or a string → `flagPostWithReasonString` (unchanged legacy mapping)
|
|
30140
|
+
* - anything else → `flagPostWithOptions` (validated `{ reason, detail? }`)
|
|
30141
|
+
*
|
|
30142
|
+
* @param postId The ID of the post to flag
|
|
30143
|
+
* @param input an options object `{ reason, detail? }`, a legacy reason string, or nothing
|
|
30144
|
+
* @returns `true` when the report was created
|
|
30145
|
+
*
|
|
30146
|
+
* @category Post API
|
|
30147
|
+
* @async
|
|
30148
|
+
* */
|
|
30149
|
+
const flagPost = (postId, input) => isLegacyContentFlagReason(input)
|
|
30150
|
+
? flagPostWithReasonString(postId, input)
|
|
30151
|
+
: flagPostWithOptions(postId, input);
|
|
29758
30152
|
/* end_public_function */
|
|
29759
30153
|
|
|
29760
30154
|
/* begin_public_function
|