@fsvreddit/fsv-devvit-web-helpers 0.1.10 → 0.2.1

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.
@@ -0,0 +1,9 @@
1
+ import { Post } from "@devvit/web/server";
2
+ export declare enum CrowdControlOption {
3
+ None = "ignore",
4
+ Off = "0",
5
+ Moderate = "1",
6
+ High = "2",
7
+ Maximum = "3"
8
+ }
9
+ export declare function setCrowdControl(post: Post, crowdControlOption: CrowdControlOption): Promise<void>;
@@ -0,0 +1,35 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.CrowdControlOption = void 0;
4
+ exports.setCrowdControl = setCrowdControl;
5
+ const server_1 = require("@devvit/web/server");
6
+ const _1 = require(".");
7
+ var CrowdControlOption;
8
+ (function (CrowdControlOption) {
9
+ CrowdControlOption["None"] = "ignore";
10
+ CrowdControlOption["Off"] = "0";
11
+ CrowdControlOption["Moderate"] = "1";
12
+ CrowdControlOption["High"] = "2";
13
+ CrowdControlOption["Maximum"] = "3";
14
+ })(CrowdControlOption || (exports.CrowdControlOption = CrowdControlOption = {}));
15
+ async function setCrowdControl(post, crowdControlOption) {
16
+ let level;
17
+ switch (crowdControlOption) {
18
+ case CrowdControlOption.Off:
19
+ level = 0;
20
+ break;
21
+ case CrowdControlOption.Moderate:
22
+ level = 1;
23
+ break;
24
+ case CrowdControlOption.High:
25
+ level = 2;
26
+ break;
27
+ case CrowdControlOption.Maximum:
28
+ level = 3;
29
+ break;
30
+ default:
31
+ return;
32
+ }
33
+ await (0, _1.getExtendedDevvit)().redditAPIPlugins.Moderation.UpdateCrowdControlLevel({ id: post.id, level }, server_1.context.metadata);
34
+ console.log(`Crowd control level set to ${crowdControlOption}`);
35
+ }
@@ -0,0 +1,50 @@
1
+ import * as protos from "@devvit/protos";
2
+ import { UserAboutResponse } from "@devvit/protos/types/devvit/plugin/redditapi/users/users_msg.js";
3
+ import { GetSubredditUsersByTypeOptions, ListingFetchOptions } from "@devvit/reddit";
4
+ import { getDevvitConfig } from "@devvit/shared-types/server/get-devvit-config.js";
5
+ export type RedditAPIPlugins = {
6
+ NewModmail: protos.NewModmail;
7
+ Widgets: protos.Widgets;
8
+ ModNote: protos.ModNote;
9
+ LinksAndComments: protos.LinksAndComments;
10
+ Moderation: protos.Moderation;
11
+ GraphQL: protos.GraphQL;
12
+ Listings: protos.Listings;
13
+ Flair: protos.Flair;
14
+ Wiki: protos.Wiki;
15
+ Users: protos.Users;
16
+ PrivateMessages: protos.PrivateMessages;
17
+ Subreddits: protos.Subreddits;
18
+ };
19
+ export type ExtendedDevvitLike = {
20
+ redditAPIPlugins: RedditAPIPlugins;
21
+ schedulerPlugin: protos.Scheduler;
22
+ kvStorePlugin: protos.KVStore;
23
+ redisPlugin: protos.RedisAPI;
24
+ mediaPlugin: protos.MediaService;
25
+ settingsPlugin: protos.Settings;
26
+ realtimePlugin: protos.Realtime;
27
+ userActionsPlugin: protos.UserActions;
28
+ use: <T>(plugin: protos.Definition) => T;
29
+ };
30
+ export declare class ExtendedDevvit implements ExtendedDevvitLike {
31
+ private config;
32
+ constructor(config: ReturnType<typeof getDevvitConfig>);
33
+ get kvStorePlugin(): protos.KVStore;
34
+ get mediaPlugin(): protos.MediaService;
35
+ get realtimePlugin(): protos.Realtime;
36
+ get redditAPIPlugins(): RedditAPIPlugins;
37
+ get redisPlugin(): protos.RedisAPI;
38
+ get schedulerPlugin(): protos.Scheduler;
39
+ get settingsPlugin(): protos.Settings;
40
+ get userActionsPlugin(): protos.UserActions;
41
+ use<T>(plugin: protos.Definition): T;
42
+ }
43
+ export declare function getExtendedDevvit(): ExtendedDevvit;
44
+ export declare function getRawUserData(username: string, metadata: protos.Metadata): Promise<UserAboutResponse>;
45
+ export declare function getRawListingData(postOrCommentIds: string[], metadata: protos.Metadata): Promise<protos.Listing>;
46
+ export declare function getRawPostData(thingIds: string[], metadata: protos.Metadata): Promise<protos.Listing>;
47
+ export declare function getRawCommentData(thingIds: string[], metadata: protos.Metadata): Promise<protos.Listing>;
48
+ export declare function getRawSubredditData(subredditName: string, metadata: protos.Metadata): Promise<protos.SubredditAboutResponse>;
49
+ export declare function setVote(id: string, dir: 1 | 0 | -1, metadata: protos.Metadata): Promise<void>;
50
+ export declare function getRawUserWhereData(userWhereRequest: GetSubredditUsersByTypeOptions, fetchOptions: ListingFetchOptions, metadata: protos.Metadata): Promise<protos.Listing>;
@@ -0,0 +1,123 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
35
+ Object.defineProperty(exports, "__esModule", { value: true });
36
+ exports.ExtendedDevvit = void 0;
37
+ exports.getExtendedDevvit = getExtendedDevvit;
38
+ exports.getRawUserData = getRawUserData;
39
+ exports.getRawListingData = getRawListingData;
40
+ exports.getRawPostData = getRawPostData;
41
+ exports.getRawCommentData = getRawCommentData;
42
+ exports.getRawSubredditData = getRawSubredditData;
43
+ exports.setVote = setVote;
44
+ exports.getRawUserWhereData = getRawUserWhereData;
45
+ const protos = __importStar(require("@devvit/protos"));
46
+ const get_devvit_config_js_1 = require("@devvit/shared-types/server/get-devvit-config.js");
47
+ class ExtendedDevvit {
48
+ constructor(config) {
49
+ this.config = config;
50
+ }
51
+ get kvStorePlugin() {
52
+ return this.config.use(protos.KVStoreDefinition);
53
+ }
54
+ get mediaPlugin() {
55
+ return this.config.use(protos.MediaServiceDefinition);
56
+ }
57
+ get realtimePlugin() {
58
+ return this.config.use(protos.RealtimeDefinition);
59
+ }
60
+ get redditAPIPlugins() {
61
+ return {
62
+ NewModmail: this.config.use(protos.NewModmailDefinition),
63
+ Widgets: this.config.use(protos.WidgetsDefinition),
64
+ ModNote: this.config.use(protos.ModNoteDefinition),
65
+ LinksAndComments: this.config.use(protos.LinksAndCommentsDefinition),
66
+ Moderation: this.config.use(protos.ModerationDefinition),
67
+ GraphQL: this.config.use(protos.GraphQLDefinition),
68
+ Listings: this.config.use(protos.ListingsDefinition),
69
+ Flair: this.config.use(protos.FlairDefinition),
70
+ Wiki: this.config.use(protos.WikiDefinition),
71
+ Users: this.config.use(protos.UsersDefinition),
72
+ PrivateMessages: this.config.use(protos.PrivateMessagesDefinition),
73
+ Subreddits: this.config.use(protos.SubredditsDefinition),
74
+ };
75
+ }
76
+ get redisPlugin() {
77
+ return this.config.use(protos.RedisAPIDefinition);
78
+ }
79
+ get schedulerPlugin() {
80
+ return this.config.use(protos.SchedulerDefinition);
81
+ }
82
+ get settingsPlugin() {
83
+ return this.config.use(protos.SettingsDefinition);
84
+ }
85
+ get userActionsPlugin() {
86
+ return this.config.use(protos.UserActionsDefinition);
87
+ }
88
+ // eslint-disable-next-line @typescript-eslint/no-unnecessary-type-parameters
89
+ use(plugin) {
90
+ return this.config.use(plugin);
91
+ }
92
+ }
93
+ exports.ExtendedDevvit = ExtendedDevvit;
94
+ const extendedDevvit = new ExtendedDevvit((0, get_devvit_config_js_1.getDevvitConfig)());
95
+ function getExtendedDevvit() {
96
+ return extendedDevvit;
97
+ }
98
+ async function getRawUserData(username, metadata) {
99
+ return getExtendedDevvit().redditAPIPlugins.Users.UserAbout({ username }, metadata);
100
+ }
101
+ async function getRawListingData(postOrCommentIds, metadata) {
102
+ return getExtendedDevvit().redditAPIPlugins.LinksAndComments.Info({ subreddits: [], thingIds: postOrCommentIds }, metadata);
103
+ }
104
+ async function getRawPostData(thingIds, metadata) {
105
+ return getRawListingData(thingIds, metadata);
106
+ }
107
+ async function getRawCommentData(thingIds, metadata) {
108
+ return getRawListingData(thingIds, metadata);
109
+ }
110
+ async function getRawSubredditData(subredditName, metadata) {
111
+ return getExtendedDevvit().redditAPIPlugins.Subreddits.SubredditAbout({ subreddit: subredditName }, metadata);
112
+ }
113
+ async function setVote(id, dir, metadata) {
114
+ await getExtendedDevvit().redditAPIPlugins.LinksAndComments.Vote({ id, dir }, metadata);
115
+ }
116
+ async function getRawUserWhereData(userWhereRequest, fetchOptions, metadata) {
117
+ return getExtendedDevvit().redditAPIPlugins.Subreddits.AboutWhere({
118
+ where: userWhereRequest.type,
119
+ subreddit: userWhereRequest.subredditName,
120
+ user: userWhereRequest.username,
121
+ ...fetchOptions,
122
+ }, metadata);
123
+ }
@@ -0,0 +1,2 @@
1
+ export * from "./crowdControl.js";
2
+ export * from "./extendedDevvit.js";
@@ -0,0 +1,18 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __exportStar = (this && this.__exportStar) || function(m, exports) {
14
+ for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
15
+ };
16
+ Object.defineProperty(exports, "__esModule", { value: true });
17
+ __exportStar(require("./crowdControl.js"), exports);
18
+ __exportStar(require("./extendedDevvit.js"), exports);
@@ -0,0 +1,18 @@
1
+ import { User } from "@devvit/web/server";
2
+ export interface UserExtended {
3
+ createdAt: Date;
4
+ commentKarma: number;
5
+ displayName?: string;
6
+ hasVerifiedEmail: boolean;
7
+ id: string;
8
+ isAdmin: boolean;
9
+ isGold: boolean;
10
+ isModerator: boolean;
11
+ linkKarma: number;
12
+ nsfw: boolean;
13
+ username: string;
14
+ userDescription?: string;
15
+ isSuspended?: boolean;
16
+ }
17
+ export declare function getUserExtended(username: string): Promise<UserExtended | undefined>;
18
+ export declare function getUserExtendedFromUser(user: User): Promise<UserExtended>;
@@ -0,0 +1,64 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.getUserExtended = getUserExtended;
4
+ exports.getUserExtendedFromUser = getUserExtendedFromUser;
5
+ const server_1 = require("@devvit/web/server");
6
+ const _1 = require(".");
7
+ async function getRawUserData(username) {
8
+ let userAboutResponse;
9
+ try {
10
+ userAboutResponse = await (0, _1.getExtendedDevvit)().redditAPIPlugins.Users.UserAbout({ username }, server_1.context.metadata);
11
+ }
12
+ catch (error) {
13
+ if (error instanceof Error && (error.message.includes("404 Not Found") || error.message.includes("403 Forbidden"))) {
14
+ return;
15
+ }
16
+ throw error; // Rethrow the error if it's not a 404 or 403
17
+ }
18
+ return userAboutResponse;
19
+ }
20
+ async function getUserExtended(username) {
21
+ const rawUserData = await getRawUserData(username);
22
+ if (!rawUserData?.data) {
23
+ return;
24
+ }
25
+ const userExtendedVal = {
26
+ createdAt: new Date((rawUserData.data.created ?? 0) * 1000),
27
+ commentKarma: rawUserData.data.commentKarma ?? 0,
28
+ displayName: rawUserData.data.subreddit?.title,
29
+ hasVerifiedEmail: rawUserData.data.hasVerifiedEmail ?? false,
30
+ id: `t2_${rawUserData.data.id ?? ""}`,
31
+ isAdmin: rawUserData.data.isEmployee ?? false,
32
+ isGold: rawUserData.data.isGold ?? false,
33
+ isModerator: rawUserData.data.isMod ?? false,
34
+ linkKarma: rawUserData.data.linkKarma ?? 0,
35
+ nsfw: rawUserData.data.subreddit?.over18 ?? false,
36
+ username: rawUserData.data.name ?? "",
37
+ userDescription: rawUserData.data.subreddit?.publicDescription,
38
+ isSuspended: rawUserData.data.isSuspended ?? false,
39
+ };
40
+ return userExtendedVal;
41
+ }
42
+ async function getUserExtendedFromUser(user) {
43
+ try {
44
+ const userExtended = await getUserExtended(user.username);
45
+ if (userExtended) {
46
+ return userExtended;
47
+ }
48
+ }
49
+ catch {
50
+ //
51
+ }
52
+ return {
53
+ createdAt: user.createdAt,
54
+ commentKarma: user.commentKarma,
55
+ hasVerifiedEmail: user.hasVerifiedEmail,
56
+ id: user.id,
57
+ isAdmin: user.isAdmin,
58
+ isGold: false,
59
+ isModerator: false,
60
+ linkKarma: user.linkKarma,
61
+ nsfw: user.nsfw,
62
+ username: user.username,
63
+ };
64
+ }
@@ -0,0 +1,2 @@
1
+ import { UserSocialLink } from "@devvit/web/server";
2
+ export declare function getUserSocialLinks(username: string): Promise<UserSocialLink[]>;
@@ -0,0 +1,24 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.getUserSocialLinks = getUserSocialLinks;
4
+ const server_1 = require("@devvit/web/server");
5
+ const _1 = require(".");
6
+ async function getUserSocialLinks(username) {
7
+ const gql = (0, _1.getExtendedDevvit)().redditAPIPlugins.GraphQL;
8
+ const response = await gql.PersistedQuery({
9
+ operationName: "GetUserSocialLinks", // Name and ID are both from <https://github.com/reddit/devvit/blob/f083/packages/public-api/src/apis/reddit/models/User.ts#L437-L438>
10
+ id: "2aca18ef5f4fc75fb91cdaace3e9aeeae2cb3843b5c26ad511e6f01b8521593a",
11
+ variables: {
12
+ name: username,
13
+ },
14
+ }, server_1.context.metadata);
15
+ // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access
16
+ if (!response.data?.user?.profile?.socialLinks) {
17
+ return [];
18
+ }
19
+ // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access, @typescript-eslint/no-unsafe-call, @typescript-eslint/no-unsafe-return
20
+ return response.data.user.profile.socialLinks.map((link) => ({
21
+ ...link,
22
+ handle: link.handle ?? undefined,
23
+ }));
24
+ }
package/dist/index.d.ts CHANGED
@@ -1,3 +1,4 @@
1
+ export * from "./extendedDevvit/index.js";
1
2
  export * from "./redditAPI/index.js";
2
3
  export * from "./tasks/index.js";
3
4
  export * from "./triggers/index.js";
package/dist/index.js CHANGED
@@ -14,6 +14,7 @@ var __exportStar = (this && this.__exportStar) || function(m, exports) {
14
14
  for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
15
15
  };
16
16
  Object.defineProperty(exports, "__esModule", { value: true });
17
+ __exportStar(require("./extendedDevvit/index.js"), exports);
17
18
  __exportStar(require("./redditAPI/index.js"), exports);
18
19
  __exportStar(require("./tasks/index.js"), exports);
19
20
  __exportStar(require("./triggers/index.js"), exports);
@@ -1,2 +1,2 @@
1
1
  import { UpdateWikiPageOptions, WikiPage } from "@devvit/web/server";
2
- export declare function updateWikiPageMulti(options: UpdateWikiPageOptions): Promise<WikiPage>;
2
+ export declare function updateWikiPageMulti(options: UpdateWikiPageOptions, verboseLogs?: boolean): Promise<WikiPage>;
@@ -3,8 +3,11 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.updateWikiPageMulti = updateWikiPageMulti;
4
4
  const server_1 = require("@devvit/web/server");
5
5
  const marked_1 = require("marked");
6
- async function updateWikiPageMulti(options) {
6
+ async function updateWikiPageMulti(options, verboseLogs = false) {
7
7
  const isV2WikiEnabled = await server_1.reddit.isWikiV2Enabled(server_1.context.subredditName);
8
+ if (verboseLogs) {
9
+ console.log(`Wiki Update: v2 enabled: ${isV2WikiEnabled}`);
10
+ }
8
11
  const promises = [
9
12
  server_1.reddit.updateWikiPage({
10
13
  ...options,
@@ -18,6 +21,9 @@ async function updateWikiPageMulti(options) {
18
21
  content: contentHtml,
19
22
  wikiVersion: "v2",
20
23
  }));
24
+ if (verboseLogs) {
25
+ console.log(`Wiki Update: v2 content HTML generated`);
26
+ }
21
27
  }
22
28
  return Promise.all(promises).then(results => results[0]);
23
29
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@fsvreddit/fsv-devvit-web-helpers",
3
- "version": "0.1.10",
3
+ "version": "0.2.1",
4
4
  "description": "Helper functions and utilities for Devvit Web apps on Reddit",
5
5
  "main": "dist/index.js",
6
6
  "scripts": {
@@ -38,6 +38,9 @@
38
38
  "devvit"
39
39
  ],
40
40
  "peerDependencies": {
41
- "@devvit/web": "^0.14.1"
41
+ "@devvit/protos": "^0.14.6",
42
+ "@devvit/reddit": "^0.14.6",
43
+ "@devvit/shared-types": "^0.14.6",
44
+ "@devvit/web": "^0.14.6"
42
45
  }
43
46
  }