sweety-html-transcripts 0.2.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.
Files changed (81) hide show
  1. package/LICENSE +201 -0
  2. package/README.md +127 -0
  3. package/dist/adapters/core.d.ts +41 -0
  4. package/dist/adapters/core.js +30 -0
  5. package/dist/adapters/core.js.map +1 -0
  6. package/dist/adapters/discordjs.d.ts +26 -0
  7. package/dist/adapters/discordjs.js +102 -0
  8. package/dist/adapters/discordjs.js.map +1 -0
  9. package/dist/adapters/seyfert.d.ts +26 -0
  10. package/dist/adapters/seyfert.js +67 -0
  11. package/dist/adapters/seyfert.js.map +1 -0
  12. package/dist/downloader/images.d.ts +37 -0
  13. package/dist/downloader/images.js +119 -0
  14. package/dist/downloader/images.js.map +1 -0
  15. package/dist/generator/index.d.ts +34 -0
  16. package/dist/generator/index.js +81 -0
  17. package/dist/generator/index.js.map +1 -0
  18. package/dist/generator/renderers/attachment.d.ts +24 -0
  19. package/dist/generator/renderers/attachment.js +133 -0
  20. package/dist/generator/renderers/attachment.js.map +1 -0
  21. package/dist/generator/renderers/components.d.ts +8 -0
  22. package/dist/generator/renderers/components.js +179 -0
  23. package/dist/generator/renderers/components.js.map +1 -0
  24. package/dist/generator/renderers/content.d.ts +32 -0
  25. package/dist/generator/renderers/content.js +168 -0
  26. package/dist/generator/renderers/content.js.map +1 -0
  27. package/dist/generator/renderers/embed.d.ts +15 -0
  28. package/dist/generator/renderers/embed.js +77 -0
  29. package/dist/generator/renderers/embed.js.map +1 -0
  30. package/dist/generator/renderers/message.d.ts +15 -0
  31. package/dist/generator/renderers/message.js +95 -0
  32. package/dist/generator/renderers/message.js.map +1 -0
  33. package/dist/generator/renderers/reply.d.ts +7 -0
  34. package/dist/generator/renderers/reply.js +76 -0
  35. package/dist/generator/renderers/reply.js.map +1 -0
  36. package/dist/generator/renderers/systemMessage.d.ts +19 -0
  37. package/dist/generator/renderers/systemMessage.js +109 -0
  38. package/dist/generator/renderers/systemMessage.js.map +1 -0
  39. package/dist/generator/transcript.d.ts +12 -0
  40. package/dist/generator/transcript.js +85 -0
  41. package/dist/generator/transcript.js.map +1 -0
  42. package/dist/index.d.ts +26 -0
  43. package/dist/index.js +143 -0
  44. package/dist/index.js.map +1 -0
  45. package/dist/static/client.d.ts +2 -0
  46. package/dist/static/client.js +30 -0
  47. package/dist/static/client.js.map +1 -0
  48. package/dist/types.d.ts +69 -0
  49. package/dist/types.js +10 -0
  50. package/dist/types.js.map +1 -0
  51. package/dist/utils/api.d.ts +19 -0
  52. package/dist/utils/api.js +364 -0
  53. package/dist/utils/api.js.map +1 -0
  54. package/dist/utils/cdn.d.ts +28 -0
  55. package/dist/utils/cdn.js +61 -0
  56. package/dist/utils/cdn.js.map +1 -0
  57. package/dist/utils/channel.d.ts +34 -0
  58. package/dist/utils/channel.js +51 -0
  59. package/dist/utils/channel.js.map +1 -0
  60. package/dist/utils/embeds.d.ts +2 -0
  61. package/dist/utils/embeds.js +17 -0
  62. package/dist/utils/embeds.js.map +1 -0
  63. package/dist/utils/guild.d.ts +9 -0
  64. package/dist/utils/guild.js +19 -0
  65. package/dist/utils/guild.js.map +1 -0
  66. package/dist/utils/message.d.ts +6 -0
  67. package/dist/utils/message.js +11 -0
  68. package/dist/utils/message.js.map +1 -0
  69. package/dist/utils/profiles.d.ts +18 -0
  70. package/dist/utils/profiles.js +67 -0
  71. package/dist/utils/profiles.js.map +1 -0
  72. package/dist/utils/replacer.d.ts +28 -0
  73. package/dist/utils/replacer.js +67 -0
  74. package/dist/utils/replacer.js.map +1 -0
  75. package/dist/utils/user.d.ts +18 -0
  76. package/dist/utils/user.js +38 -0
  77. package/dist/utils/user.js.map +1 -0
  78. package/dist/utils/utils.d.ts +32 -0
  79. package/dist/utils/utils.js +61 -0
  80. package/dist/utils/utils.js.map +1 -0
  81. package/package.json +90 -0
@@ -0,0 +1 @@
1
+ {"version":3,"file":"guild.js","sourceRoot":"","sources":["../../src/utils/guild.ts"],"names":[],"mappings":";;;AAEA,+BAA4B;AAE5B,MAAM,UAAU;IACd,OAAO,CAAC,KAAoC,EAAE,OAAuB;QACnE,IAAI,CAAC,KAAK,CAAC,IAAI;YAAE,OAAO;QAExB,OAAO,SAAG,CAAC,SAAS,CAAC,KAAK,CAAC,EAAE,EAAE,KAAK,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC;IACtD,CAAC;IAED,aAAa,CAAC,OAAe,EAAE,aAAqB,EAAE,OAAuB;QAC3E,OAAO,SAAG,CAAC,aAAa,CAAC,OAAO,EAAE,aAAa,EAAE,OAAO,CAAC,CAAC;IAC5D,CAAC;IAED,QAAQ,CAAC,MAAc,EAAE,IAAY,EAAE,OAAuB;QAC5D,OAAO,SAAG,CAAC,QAAQ,CAAC,MAAM,EAAE,IAAI,EAAE,OAAO,CAAC,CAAC;IAC7C,CAAC;CACF;AAEY,QAAA,UAAU,GAAG,IAAI,UAAU,EAAE,CAAC"}
@@ -0,0 +1,6 @@
1
+ import type { APIMessageData } from './channel';
2
+ declare class MessageUtils {
3
+ isForward(message: Pick<APIMessageData, 'message_reference'>): boolean;
4
+ }
5
+ export declare const messageUtils: MessageUtils;
6
+ export {};
@@ -0,0 +1,11 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.messageUtils = void 0;
4
+ const v10_1 = require("discord-api-types/v10");
5
+ class MessageUtils {
6
+ isForward(message) {
7
+ return message.message_reference?.type === v10_1.MessageReferenceType.Forward;
8
+ }
9
+ }
10
+ exports.messageUtils = new MessageUtils();
11
+ //# sourceMappingURL=message.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"message.js","sourceRoot":"","sources":["../../src/utils/message.ts"],"names":[],"mappings":";;;AAAA,+CAA6D;AAG7D,MAAM,YAAY;IAChB,SAAS,CAAC,OAAkD;QAC1D,OAAO,OAAO,CAAC,iBAAiB,EAAE,IAAI,KAAK,0BAAoB,CAAC,OAAO,CAAC;IAC1E,CAAC;CACF;AAEY,QAAA,YAAY,GAAG,IAAI,YAAY,EAAE,CAAC"}
@@ -0,0 +1,18 @@
1
+ import type { RenderMessageContext } from '../generator';
2
+ export type Profile = {
3
+ id: string;
4
+ displayName: string;
5
+ discriminator: string;
6
+ username: string;
7
+ globalName?: string | null;
8
+ author: string;
9
+ avatar?: string;
10
+ roleColor?: string;
11
+ roleIcon?: string;
12
+ roleName?: string;
13
+ bot?: boolean;
14
+ verified?: boolean;
15
+ clanTag?: string | null;
16
+ clanIcon?: string | null;
17
+ };
18
+ export declare function buildProfiles(context: RenderMessageContext): Promise<Record<string, Profile>>;
@@ -0,0 +1,67 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.buildProfiles = buildProfiles;
4
+ const v10_1 = require("discord-api-types/v10");
5
+ const channel_1 = require("./channel");
6
+ const user_1 = require("./user");
7
+ const utils_1 = require("./utils");
8
+ const guild_1 = require("./guild");
9
+ async function buildProfiles(context) {
10
+ const { adapter, messages } = context;
11
+ const profiles = {};
12
+ // loop through messages
13
+ for (const message of messages) {
14
+ // add all users
15
+ const author = message.author;
16
+ if (!profiles[author.id]) {
17
+ // add profile
18
+ const member = await adapter.resolveGuildMember(message.guild_id, author.id);
19
+ profiles[author.id] = await buildProfile(member, message.guild_id, author, context);
20
+ }
21
+ // add interaction users
22
+ if (message.interaction_metadata) {
23
+ // const user = await message.client.users.fetch(message.interactionMetadata.user.id);
24
+ const user = await adapter.resolveUser(message.interaction_metadata.user.id);
25
+ if (user && !profiles[user.id]) {
26
+ profiles[user.id] = await buildProfile(null, message.guild_id, user, context);
27
+ }
28
+ }
29
+ // threads
30
+ if (message.thread && channel_1.channelUtils.isThread(message.thread) && message.thread.last_message_id) {
31
+ const thread = (await adapter.resolveMessage(message.thread.id, message.thread.last_message_id));
32
+ profiles[thread.author.id] = await buildProfile(null, message.guild_id, thread.author, context);
33
+ }
34
+ }
35
+ // return as a JSON
36
+ return profiles;
37
+ }
38
+ async function buildProfile(member, guildId, author, context) {
39
+ if (guildId && !member)
40
+ member = await context.adapter.resolveGuildMember(guildId, author.id);
41
+ const role = await context.adapter.resolveHighestGuildMemberRole(member, guildId);
42
+ const authorName = author.bot ? author.username : user_1.userUtils.displayName(author);
43
+ const roleColor = role?.color ?? author.accent_color;
44
+ return {
45
+ id: author.id,
46
+ author: member?.nick ?? authorName,
47
+ displayName: member?.nick ?? author.global_name ?? author.username,
48
+ discriminator: author.discriminator,
49
+ username: author.username,
50
+ globalName: author.global_name,
51
+ avatar: (member && guildId ? user_1.userUtils.memberAvatarURL(member, author, guildId, { size: 64 }) : null) ??
52
+ user_1.userUtils.avatarURL(author, { size: 64 }),
53
+ roleColor: roleColor ? (0, utils_1.convertToHEX)(roleColor) : undefined,
54
+ roleIcon: role?.icon ?? undefined,
55
+ roleName: role?.name ?? undefined,
56
+ bot: author.bot,
57
+ verified: (0, utils_1.hasFlag)({ bitfield: author.flags, flag: v10_1.UserFlags.VerifiedBot }),
58
+ clanTag: author.primary_guild?.tag,
59
+ clanIcon: author.primary_guild?.identity_guild_id &&
60
+ author.primary_guild?.badge &&
61
+ guild_1.guildUtils.guildTagBadge(author.primary_guild.identity_guild_id, author.primary_guild.badge, {
62
+ size: 32,
63
+ extension: 'png',
64
+ }),
65
+ };
66
+ }
67
+ //# sourceMappingURL=profiles.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"profiles.js","sourceRoot":"","sources":["../../src/utils/profiles.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,28 @@
1
+ type Identify<T> = T extends infer U ? {
2
+ [K in keyof U]: U[K];
3
+ } : never;
4
+ type AuxIsStrictlyUndefined<T> = T extends undefined | null | never | void ? true : false;
5
+ type SnakeCase<S extends string> = S extends `${infer First}${infer Rest}` ? First extends Lowercase<First> ? `${First}${SnakeCase<Rest>}` : Rest extends `${infer Second}${string}` ? Second extends Lowercase<Second> ? `_${Lowercase<First>}${SnakeCase<Rest>}` : `${Lowercase<First>}${SnakeCase<Rest>}` : `_${Lowercase<First>}` : S;
6
+ type ObjectToSnakeUndefined<T> = T extends unknown[] ? ObjectToSnake<T[0]>[] : Identify<{
7
+ [K in keyof T as K extends number ? K : SnakeCase<Exclude<K, symbol | number>>]: T[K] extends unknown[] ? ObjectToSnake<T[K][0]>[] : T[K] extends object ? ObjectToSnake<T[K]> : T[K];
8
+ }>;
9
+ type ObjectToSnake<T> = Identify<{
10
+ [K in keyof T as K extends number ? K : SnakeCase<Exclude<K, symbol | number>>]: T[K] extends unknown[] ? Identify<ObjectToSnake<T[K][0]>[]> : T[K] extends object ? Identify<ObjectToSnake<T[K]>> : AuxIsStrictlyUndefined<T[K]> extends true ? null : ObjectToSnakeUndefined<T[K]>;
11
+ }>;
12
+ /**
13
+ * Checks if a given value is an object.
14
+ * @param o The value to check.
15
+ * @returns `true` if the value is an object, otherwise `false`.
16
+ */
17
+ export declare function isObject(o: any): o is Record<string, unknown>;
18
+ export declare const ReplaceRegex: {
19
+ camel: (s: string) => string;
20
+ snake: (s: string) => string;
21
+ };
22
+ /**
23
+ * Convert a camelCase object to snake_case.
24
+ * @param target The object to convert.
25
+ * @returns The converted object.
26
+ */
27
+ export declare function toSnakeCase<Obj extends Record<string, any>>(target: Obj): ObjectToSnake<Obj>;
28
+ export {};
@@ -0,0 +1,67 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.ReplaceRegex = void 0;
4
+ exports.isObject = isObject;
5
+ exports.toSnakeCase = toSnakeCase;
6
+ /**
7
+ * Checks if a given value is an object.
8
+ * @param o The value to check.
9
+ * @returns `true` if the value is an object, otherwise `false`.
10
+ */
11
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
12
+ function isObject(o) {
13
+ return o && typeof o === 'object' && !Array.isArray(o);
14
+ }
15
+ exports.ReplaceRegex = {
16
+ camel: (s) => {
17
+ return s.toLowerCase().replace(/(_\S)/gi, (a) => a[1].toUpperCase());
18
+ },
19
+ snake: (s) => {
20
+ // Handle sequences of uppercase letters (acronyms) and individual uppercase letters
21
+ return s
22
+ .replace(/([A-Z]+)([A-Z][a-z])/g, '$1_$2') // Handle transition from acronym to word (e.g., URLPath -> URL_Path)
23
+ .replace(/([a-z\d])([A-Z])/g, '$1_$2') // Handle transition from lowercase/digit to uppercase
24
+ .toLowerCase();
25
+ },
26
+ };
27
+ /**
28
+ * Convert a camelCase object to snake_case.
29
+ * @param target The object to convert.
30
+ * @returns The converted object.
31
+ */
32
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
33
+ function toSnakeCase(target) {
34
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
35
+ const result = {};
36
+ for (const [key, value] of Object.entries(target)) {
37
+ switch (typeof value) {
38
+ case 'string':
39
+ case 'bigint':
40
+ case 'boolean':
41
+ case 'function':
42
+ case 'number':
43
+ case 'symbol':
44
+ case 'undefined':
45
+ result[exports.ReplaceRegex.snake(key)] = value;
46
+ break;
47
+ case 'object': {
48
+ if (Array.isArray(value)) {
49
+ result[exports.ReplaceRegex.snake(key)] = value.map((prop) => typeof prop === 'object' && prop ? toSnakeCase(prop) : prop);
50
+ break;
51
+ }
52
+ if (isObject(value)) {
53
+ result[exports.ReplaceRegex.snake(key)] = toSnakeCase(value);
54
+ break;
55
+ }
56
+ if (!Number.isNaN(value)) {
57
+ result[exports.ReplaceRegex.snake(key)] = null;
58
+ break;
59
+ }
60
+ result[exports.ReplaceRegex.snake(key)] = toSnakeCase(value);
61
+ break;
62
+ }
63
+ }
64
+ }
65
+ return result;
66
+ }
67
+ //# sourceMappingURL=replacer.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"replacer.js","sourceRoot":"","sources":["../../src/utils/replacer.ts"],"names":[],"mappings":";;;AAwCA,4BAEC;AAqBD,kCAmCC;AAhED;;;;GAIG;AACH,8DAA8D;AAC9D,SAAgB,QAAQ,CAAC,CAAM;IAC7B,OAAO,CAAC,IAAI,OAAO,CAAC,KAAK,QAAQ,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC;AACzD,CAAC;AAEY,QAAA,YAAY,GAAG;IAC1B,KAAK,EAAE,CAAC,CAAS,EAAE,EAAE;QACnB,OAAO,CAAC,CAAC,WAAW,EAAE,CAAC,OAAO,CAAC,SAAS,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,WAAW,EAAE,CAAC,CAAC;IACvE,CAAC;IACD,KAAK,EAAE,CAAC,CAAS,EAAE,EAAE;QACnB,oFAAoF;QACpF,OAAO,CAAC;aACL,OAAO,CAAC,uBAAuB,EAAE,OAAO,CAAC,CAAC,qEAAqE;aAC/G,OAAO,CAAC,mBAAmB,EAAE,OAAO,CAAC,CAAC,sDAAsD;aAC5F,WAAW,EAAE,CAAC;IACnB,CAAC;CACF,CAAC;AAEF;;;;GAIG;AACH,8DAA8D;AAC9D,SAAgB,WAAW,CAAkC,MAAW;IACtE,8DAA8D;IAC9D,MAAM,MAAM,GAAwB,EAAE,CAAC;IACvC,KAAK,MAAM,CAAC,GAAG,EAAE,KAAK,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC,EAAE,CAAC;QAClD,QAAQ,OAAO,KAAK,EAAE,CAAC;YACrB,KAAK,QAAQ,CAAC;YACd,KAAK,QAAQ,CAAC;YACd,KAAK,SAAS,CAAC;YACf,KAAK,UAAU,CAAC;YAChB,KAAK,QAAQ,CAAC;YACd,KAAK,QAAQ,CAAC;YACd,KAAK,WAAW;gBACd,MAAM,CAAC,oBAAY,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,GAAG,KAAK,CAAC;gBACxC,MAAM;YACR,KAAK,QAAQ,CAAC,CAAC,CAAC;gBACd,IAAI,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC;oBACzB,MAAM,CAAC,oBAAY,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,GAAG,KAAK,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CACnD,OAAO,IAAI,KAAK,QAAQ,IAAI,IAAI,CAAC,CAAC,CAAC,WAAW,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,CAC5D,CAAC;oBACF,MAAM;gBACR,CAAC;gBACD,IAAI,QAAQ,CAAC,KAAK,CAAC,EAAE,CAAC;oBACpB,MAAM,CAAC,oBAAY,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,GAAG,WAAW,CAAC,KAAK,CAAC,CAAC;oBACrD,MAAM;gBACR,CAAC;gBACD,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,KAAK,CAAC,EAAE,CAAC;oBACzB,MAAM,CAAC,oBAAY,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,GAAG,IAAI,CAAC;oBACvC,MAAM;gBACR,CAAC;gBACD,MAAM,CAAC,oBAAY,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,GAAG,WAAW,CAAC,KAAK,CAAC,CAAC;gBACrD,MAAM;YACR,CAAC;QACH,CAAC;IACH,CAAC;IACD,OAAO,MAA4B,CAAC;AACtC,CAAC"}
@@ -0,0 +1,18 @@
1
+ import type { APIUser, Snowflake } from 'discord-api-types/v10';
2
+ import type { CDNUrlOptions } from './cdn';
3
+ import type { GuildMemberData } from './channel';
4
+ declare class UserUtils {
5
+ calculateUserDefaultAvatarIndex(userId: Snowflake, discriminator: string): number;
6
+ defaultAvatarURL(user: Pick<APIUser, 'id' | 'discriminator'>): string;
7
+ avatarURL(user: Pick<APIUser, 'id' | 'avatar' | 'discriminator'>, options?: CDNUrlOptions): string;
8
+ memberAvatarURL(member: Pick<GuildMemberData, 'avatar'>, user: Pick<APIUser, 'id' | 'avatar' | 'discriminator'>, guildId: string, options: CDNUrlOptions & {
9
+ exclude: true;
10
+ }): string | null;
11
+ memberAvatarURL(member: Pick<GuildMemberData, 'avatar'>, user: Pick<APIUser, 'id' | 'avatar' | 'discriminator'>, guildId: string, options?: CDNUrlOptions & {
12
+ exclude?: false;
13
+ }): string;
14
+ avatarDecorationURL(user: Pick<APIUser, 'id' | 'avatar_decoration_data'>): string | undefined;
15
+ displayName(user: Pick<APIUser, 'username' | 'discriminator' | 'global_name'>): string;
16
+ }
17
+ export declare const userUtils: UserUtils;
18
+ export {};
@@ -0,0 +1,38 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.userUtils = void 0;
4
+ const cdn_1 = require("./cdn");
5
+ class UserUtils {
6
+ calculateUserDefaultAvatarIndex(userId, discriminator) {
7
+ if (discriminator === '0')
8
+ return Number(BigInt(userId) >> 22n) % 6;
9
+ return Number(discriminator) % 5;
10
+ }
11
+ defaultAvatarURL(user) {
12
+ return cdn_1.cdn.defaultUserAvatar(this.calculateUserDefaultAvatarIndex(user.id, user.discriminator));
13
+ }
14
+ avatarURL(user, options) {
15
+ if (!user.avatar) {
16
+ return this.defaultAvatarURL(user);
17
+ }
18
+ return cdn_1.cdn.userAvatar(user.id, user.avatar, options);
19
+ }
20
+ memberAvatarURL(member, user, guildId, options) {
21
+ if (!member.avatar) {
22
+ return options?.exclude ? null : this.avatarURL(user, options);
23
+ }
24
+ return cdn_1.cdn.memberAvatar(guildId, user.id, member.avatar, options);
25
+ }
26
+ avatarDecorationURL(user) {
27
+ if (!user.avatar_decoration_data)
28
+ return;
29
+ return cdn_1.cdn.avatarDecoration(user.avatar_decoration_data.asset);
30
+ }
31
+ displayName(user) {
32
+ if (user.discriminator === '0')
33
+ return user.global_name ?? user.username;
34
+ return user.global_name ?? `${user.username}#${user.discriminator}`;
35
+ }
36
+ }
37
+ exports.userUtils = new UserUtils();
38
+ //# sourceMappingURL=user.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"user.js","sourceRoot":"","sources":["../../src/utils/user.ts"],"names":[],"mappings":";;;AAEA,+BAA4B;AAG5B,MAAM,SAAS;IACb,+BAA+B,CAAC,MAAiB,EAAE,aAAqB;QACtE,IAAI,aAAa,KAAK,GAAG;YAAE,OAAO,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,IAAI,GAAG,CAAC,GAAG,CAAC,CAAC;QACpE,OAAO,MAAM,CAAC,aAAa,CAAC,GAAG,CAAC,CAAC;IACnC,CAAC;IAED,gBAAgB,CAAC,IAA2C;QAC1D,OAAO,SAAG,CAAC,iBAAiB,CAAC,IAAI,CAAC,+BAA+B,CAAC,IAAI,CAAC,EAAE,EAAE,IAAI,CAAC,aAAa,CAAC,CAAC,CAAC;IAClG,CAAC;IAED,SAAS,CAAC,IAAsD,EAAE,OAAuB;QACvF,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE,CAAC;YACjB,OAAO,IAAI,CAAC,gBAAgB,CAAC,IAAI,CAAC,CAAC;QACrC,CAAC;QAED,OAAO,SAAG,CAAC,UAAU,CAAC,IAAI,CAAC,EAAE,EAAE,IAAI,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACvD,CAAC;IAcD,eAAe,CACb,MAAuC,EACvC,IAAsD,EACtD,OAAe,EACf,OAA+C;QAE/C,IAAI,CAAC,MAAM,CAAC,MAAM,EAAE,CAAC;YACnB,OAAO,OAAO,EAAE,OAAO,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC;QACjE,CAAC;QAED,OAAO,SAAG,CAAC,YAAY,CAAC,OAAO,EAAE,IAAI,CAAC,EAAE,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACpE,CAAC;IAED,mBAAmB,CAAC,IAAoD;QACtE,IAAI,CAAC,IAAI,CAAC,sBAAsB;YAAE,OAAO;QACzC,OAAO,SAAG,CAAC,gBAAgB,CAAC,IAAI,CAAC,sBAAsB,CAAC,KAAK,CAAC,CAAC;IACjE,CAAC;IAED,WAAW,CAAC,IAAiE;QAC3E,IAAI,IAAI,CAAC,aAAa,KAAK,GAAG;YAAE,OAAO,IAAI,CAAC,WAAW,IAAI,IAAI,CAAC,QAAQ,CAAC;QACzE,OAAO,IAAI,CAAC,WAAW,IAAI,GAAG,IAAI,CAAC,QAAQ,IAAI,IAAI,CAAC,aAAa,EAAE,CAAC;IACtE,CAAC;CACF;AAEY,QAAA,SAAS,GAAG,IAAI,SAAS,EAAE,CAAC"}
@@ -0,0 +1,32 @@
1
+ import type { Emoji } from 'seyfert';
2
+ import type { APIMessageComponentEmoji } from 'discord-api-types/v10';
3
+ interface FlagsOptions {
4
+ bitfield?: number;
5
+ flag: number;
6
+ }
7
+ export declare function isDefined<T>(value: T | undefined | null): value is T;
8
+ export declare function formatBytes(bytes: number, decimals?: number): {
9
+ size: number;
10
+ unit: string;
11
+ };
12
+ export declare function parseDiscordEmoji(emoji: Emoji | APIMessageComponentEmoji): string;
13
+ /**
14
+ * Converts a stream to a string
15
+ * @param stream - The stream to convert
16
+ */
17
+ export declare function streamToString(stream: NodeJS.ReadableStream): Promise<string>;
18
+ /**
19
+ *
20
+ * Check if a flag is present in a bitfield
21
+ * @param {FlagsOptions} options - The options to check.
22
+ * @returns boolean
23
+ */
24
+ export declare const hasFlag: (options: FlagsOptions) => boolean;
25
+ /**
26
+ *
27
+ * Convert a number color to HEX
28
+ * @param color - The color number
29
+ * @returns
30
+ */
31
+ export declare const convertToHEX: (color?: number) => string;
32
+ export {};
@@ -0,0 +1,61 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.convertToHEX = exports.hasFlag = void 0;
7
+ exports.isDefined = isDefined;
8
+ exports.formatBytes = formatBytes;
9
+ exports.parseDiscordEmoji = parseDiscordEmoji;
10
+ exports.streamToString = streamToString;
11
+ const twemoji_1 = __importDefault(require("twemoji"));
12
+ function isDefined(value) {
13
+ return value !== undefined && value !== null;
14
+ }
15
+ function formatBytes(bytes, decimals = 2) {
16
+ if (bytes === 0)
17
+ return { size: 0, unit: 'Bytes' };
18
+ const k = 1024;
19
+ const dm = decimals < 0 ? 0 : decimals;
20
+ const sizes = ['Bytes', 'KB', 'MB', 'GB', 'TB', 'PB', 'EB', 'ZB', 'YB'];
21
+ const i = Math.floor(Math.log(bytes) / Math.log(k));
22
+ return { size: parseFloat((bytes / Math.pow(k, i)).toFixed(dm)), unit: sizes[i] };
23
+ }
24
+ function parseDiscordEmoji(emoji) {
25
+ if (emoji.id) {
26
+ return `https://cdn.discordapp.com/emojis/${emoji.id}.${emoji.animated ? 'gif' : 'png'}`;
27
+ }
28
+ const codepoints = twemoji_1.default.convert
29
+ .toCodePoint(emoji.name.indexOf(String.fromCharCode(0x200d)) < 0 ? emoji.name.replace(/\uFE0F/g, '') : emoji.name)
30
+ .toLowerCase();
31
+ return `https://cdnjs.cloudflare.com/ajax/libs/twemoji/14.0.2/svg/${codepoints}.svg`;
32
+ }
33
+ /**
34
+ * Converts a stream to a string
35
+ * @param stream - The stream to convert
36
+ */
37
+ function streamToString(stream) {
38
+ const chunks = [];
39
+ return new Promise((resolve, reject) => {
40
+ stream.on('data', (chunk) => chunks.push(chunk));
41
+ stream.on('error', reject);
42
+ stream.on('end', () => resolve(Buffer.concat(chunks).toString('utf8')));
43
+ });
44
+ }
45
+ /**
46
+ *
47
+ * Check if a flag is present in a bitfield
48
+ * @param {FlagsOptions} options - The options to check.
49
+ * @returns boolean
50
+ */
51
+ const hasFlag = (options) => (options.bitfield ?? 0 & options.flag) === options.flag;
52
+ exports.hasFlag = hasFlag;
53
+ /**
54
+ *
55
+ * Convert a number color to HEX
56
+ * @param color - The color number
57
+ * @returns
58
+ */
59
+ const convertToHEX = (color) => (color ? `#${color.toString(16).padStart(6, '0')}` : '#FFFFFF');
60
+ exports.convertToHEX = convertToHEX;
61
+ //# sourceMappingURL=utils.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"utils.js","sourceRoot":"","sources":["../../src/utils/utils.ts"],"names":[],"mappings":"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"}
package/package.json ADDED
@@ -0,0 +1,90 @@
1
+ {
2
+ "name": "sweety-html-transcripts",
3
+ "version": "0.2.0",
4
+ "description": "A sweety formatted html transcript generator for discord bots.",
5
+ "main": "dist/index.js",
6
+ "homepage": "https://github.com/Ganyu-Studios/sweety-html-transcripts",
7
+ "types": "./dist/index.d.ts",
8
+ "scripts": {
9
+ "build": "tsc -p tsconfig.json",
10
+ "prepack": "npm run build",
11
+ "lint": "prettier --write --cache . && eslint --cache --fix .",
12
+ "typecheck": "tsc -p tsconfig.eslint.json",
13
+ "vite": "vite",
14
+ "test:seyfert": "tsx ./tests/seyfert-generate.ts",
15
+ "test:djs": "tsx ./tests/djs-generate.ts",
16
+ "update-components": "pnpm update @penwin/*@latest"
17
+ },
18
+ "repository": {
19
+ "type": "git",
20
+ "url": "git+https://github.com/Ganyu-Studios/sweety-html-transcripts.git"
21
+ },
22
+ "keywords": [
23
+ "seyfert",
24
+ "seyfert-transcripts",
25
+ "sweety-html-transcripts",
26
+ "html-transcripts",
27
+ "sweety-html-transcripts",
28
+ "discord-transcripts"
29
+ ],
30
+ "author": "Ganyu Studios",
31
+ "license": "GNU GPLv3",
32
+ "contributors": [
33
+ {
34
+ "name": "JustEvil",
35
+ "url": "https://github.com/EvilG-MC"
36
+ }
37
+ ],
38
+ "files": [
39
+ "dist/**/*.js",
40
+ "dist/**/*.d.ts",
41
+ "dist/**/*.js.map"
42
+ ],
43
+ "devDependencies": {
44
+ "@eslint/eslintrc": "^3.3.3",
45
+ "@eslint/js": "^10.0.1",
46
+ "@penwin/discord-components-core": "^4.3.8",
47
+ "@types/debug": "^4.1.12",
48
+ "@types/node": "^25.2.2",
49
+ "@types/react": "^19.2.13",
50
+ "@types/react-dom": "^19.2.3",
51
+ "@typescript-eslint/eslint-plugin": "^8.54.0",
52
+ "@typescript-eslint/parser": "^8.54.0",
53
+ "debug": "^4.4.3",
54
+ "dotenv": "^17.2.4",
55
+ "eslint": "^10.0.0",
56
+ "globals": "^17.3.0",
57
+ "husky": "^9.1.7",
58
+ "prettier": "^3.8.1",
59
+ "sharp": "^0.34.5",
60
+ "tsx": "^4.21.0",
61
+ "typescript": "^5.9.3",
62
+ "vite": "^7.3.1"
63
+ },
64
+ "dependencies": {
65
+ "@derockdev/discord-components-core": "^3.6.1",
66
+ "@derockdev/discord-components-react": "^3.6.1",
67
+ "@penwin/discord-components-react-render": "^4.3.8",
68
+ "discord-api-types": "^0.38.38",
69
+ "discord-markdown-parser": "~1.3.1",
70
+ "react": "19.2.4",
71
+ "react-dom": "19.2.4",
72
+ "simple-markdown": "^0.7.3",
73
+ "twemoji": "^14.0.2",
74
+ "undici": "^7.21.0"
75
+ },
76
+ "peerDependencies": {
77
+ "discord.js": "^14.22.1",
78
+ "seyfert": "4.1.1-dev-21714759458.0"
79
+ },
80
+ "overrides": {
81
+ "react": "$react"
82
+ },
83
+ "pnpm": {
84
+ "onlyBuiltDependencies": [
85
+ "esbuild",
86
+ "sharp"
87
+ ]
88
+ },
89
+ "packageManager": "pnpm@10.29.1+sha512.48dae233635a645768a3028d19545cacc1688639eeb1f3734e42d6d6b971afbf22aa1ac9af52a173d9c3a20c15857cfa400f19994d79a2f626fcc73fccda9bbc"
90
+ }