@devvit/client 0.11.14-next-2025-05-05-765f3688c.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/LICENSE +26 -0
- package/README.md +3 -0
- package/client-meta.min.json +175 -0
- package/client.min.js +2 -0
- package/client.min.js.map +7 -0
- package/effects/contants.d.ts +3 -0
- package/effects/contants.d.ts.map +1 -0
- package/effects/contants.js +3 -0
- package/effects/emit-effect.d.ts +17 -0
- package/effects/emit-effect.d.ts.map +1 -0
- package/effects/emit-effect.js +42 -0
- package/effects/emit-effect.test.d.ts.map +1 -0
- package/effects/helpers/assert-valid-form-fields.d.ts +11 -0
- package/effects/helpers/assert-valid-form-fields.d.ts.map +1 -0
- package/effects/helpers/assert-valid-form-fields.js +29 -0
- package/effects/helpers/assert-valid-form-fields.test.d.ts.map +1 -0
- package/effects/helpers/form-types.d.ts +149 -0
- package/effects/helpers/form-types.d.ts.map +1 -0
- package/effects/helpers/form-types.js +5 -0
- package/effects/helpers/get-form-values.d.ts +6 -0
- package/effects/helpers/get-form-values.d.ts.map +1 -0
- package/effects/helpers/get-form-values.js +30 -0
- package/effects/helpers/get-form-values.test.d.ts.map +1 -0
- package/effects/helpers/test-helpers.d.ts +10 -0
- package/effects/helpers/test-helpers.d.ts.map +1 -0
- package/effects/helpers/test-helpers.js +254 -0
- package/effects/helpers/transform-form.d.ts +4 -0
- package/effects/helpers/transform-form.d.ts.map +1 -0
- package/effects/helpers/transform-form.js +140 -0
- package/effects/helpers/transform-form.test.d.ts.map +1 -0
- package/effects/index.d.ts +4 -0
- package/effects/index.d.ts.map +1 -0
- package/effects/index.js +3 -0
- package/effects/navigate-to.d.ts +12 -0
- package/effects/navigate-to.d.ts.map +1 -0
- package/effects/navigate-to.js +17 -0
- package/effects/navigate-to.test.d.ts.map +1 -0
- package/effects/show-form.d.ts +16 -0
- package/effects/show-form.d.ts.map +1 -0
- package/effects/show-form.js +49 -0
- package/effects/show-form.test.d.ts.map +1 -0
- package/effects/show-toast.d.ts +9 -0
- package/effects/show-toast.d.ts.map +1 -0
- package/effects/show-toast.js +23 -0
- package/effects/show-toast.test.d.ts.map +1 -0
- package/effects/types.d.ts +19 -0
- package/effects/types.d.ts.map +1 -0
- package/effects/types.js +6 -0
- package/index.d.ts +2 -0
- package/index.d.ts.map +1 -0
- package/index.js +1 -0
- package/index.test.d.ts.map +1 -0
- package/package.json +49 -0
|
@@ -0,0 +1,254 @@
|
|
|
1
|
+
// Thing mocks
|
|
2
|
+
export const mockSubreddit = {
|
|
3
|
+
id: 't5_123',
|
|
4
|
+
name: 'test',
|
|
5
|
+
permalink: '/r/test',
|
|
6
|
+
createdAt: new Date(),
|
|
7
|
+
type: 'public',
|
|
8
|
+
title: 'Test Subreddit',
|
|
9
|
+
description: 'A test subreddit',
|
|
10
|
+
language: 'en',
|
|
11
|
+
nsfw: false,
|
|
12
|
+
numberOfSubscribers: 1000,
|
|
13
|
+
numberOfActiveUsers: 100,
|
|
14
|
+
settings: {
|
|
15
|
+
acceptFollowers: true,
|
|
16
|
+
allOriginalContent: false,
|
|
17
|
+
allowChatPostCreation: true,
|
|
18
|
+
allowDiscovery: true,
|
|
19
|
+
allowGalleries: true,
|
|
20
|
+
allowImages: true,
|
|
21
|
+
allowPolls: true,
|
|
22
|
+
allowPredictionContributors: true,
|
|
23
|
+
allowPredictions: true,
|
|
24
|
+
allowPredictionsTournament: true,
|
|
25
|
+
allowTalks: true,
|
|
26
|
+
allowVideoGifs: true,
|
|
27
|
+
allowVideos: true,
|
|
28
|
+
chatPostEnabled: true,
|
|
29
|
+
collectionsEnabled: true,
|
|
30
|
+
crosspostable: true,
|
|
31
|
+
emojisEnabled: true,
|
|
32
|
+
eventPostsEnabled: true,
|
|
33
|
+
linkFlairEnabled: true,
|
|
34
|
+
originalContentTagEnabled: true,
|
|
35
|
+
restrictCommenting: false,
|
|
36
|
+
restrictPosting: false,
|
|
37
|
+
shouldArchivePosts: true,
|
|
38
|
+
spoilersEnabled: true,
|
|
39
|
+
wikiEnabled: true,
|
|
40
|
+
allowedPostType: 'any',
|
|
41
|
+
allowedMediaInComments: ['giphy', 'static', 'animated', 'expression'],
|
|
42
|
+
userFlairs: {
|
|
43
|
+
enabled: true,
|
|
44
|
+
usersCanAssign: true,
|
|
45
|
+
},
|
|
46
|
+
postFlairs: {
|
|
47
|
+
enabled: true,
|
|
48
|
+
usersCanAssign: true,
|
|
49
|
+
},
|
|
50
|
+
url: 'https://www.reddit.com/r/test',
|
|
51
|
+
},
|
|
52
|
+
url: 'https://www.reddit.com/r/test',
|
|
53
|
+
};
|
|
54
|
+
export const mockPost = {
|
|
55
|
+
id: 't3_123',
|
|
56
|
+
title: 'Test Post',
|
|
57
|
+
permalink: '/r/test/comments/123/test_post',
|
|
58
|
+
authorId: 't2_456',
|
|
59
|
+
authorName: 'testuser',
|
|
60
|
+
subredditId: 't5_123',
|
|
61
|
+
subredditName: 'test',
|
|
62
|
+
body: 'Test post body',
|
|
63
|
+
bodyHtml: '<div>Test post body</div>',
|
|
64
|
+
url: 'https://www.reddit.com/r/test/comments/123/test_post',
|
|
65
|
+
createdAt: new Date(),
|
|
66
|
+
score: 100,
|
|
67
|
+
numberOfComments: 10,
|
|
68
|
+
numberOfReports: 0,
|
|
69
|
+
approved: true,
|
|
70
|
+
spam: false,
|
|
71
|
+
stickied: false,
|
|
72
|
+
removed: false,
|
|
73
|
+
removedBy: undefined,
|
|
74
|
+
removedByCategory: undefined,
|
|
75
|
+
archived: false,
|
|
76
|
+
edited: false,
|
|
77
|
+
locked: false,
|
|
78
|
+
nsfw: false,
|
|
79
|
+
quarantined: false,
|
|
80
|
+
spoiler: false,
|
|
81
|
+
hidden: false,
|
|
82
|
+
ignoringReports: false,
|
|
83
|
+
distinguishedBy: undefined,
|
|
84
|
+
flair: undefined,
|
|
85
|
+
secureMedia: undefined,
|
|
86
|
+
userReportReasons: [],
|
|
87
|
+
modReportReasons: [],
|
|
88
|
+
};
|
|
89
|
+
export const mockComment = {
|
|
90
|
+
id: 't1_123',
|
|
91
|
+
body: 'Test comment',
|
|
92
|
+
permalink: '/r/test/comments/123/test_post/comment',
|
|
93
|
+
authorId: 't2_456',
|
|
94
|
+
authorName: 'testuser',
|
|
95
|
+
subredditId: 't5_123',
|
|
96
|
+
subredditName: 'test',
|
|
97
|
+
createdAt: new Date(),
|
|
98
|
+
parentId: 't3_123',
|
|
99
|
+
postId: 't3_123',
|
|
100
|
+
approved: true,
|
|
101
|
+
locked: false,
|
|
102
|
+
removed: false,
|
|
103
|
+
stickied: false,
|
|
104
|
+
spam: false,
|
|
105
|
+
edited: false,
|
|
106
|
+
distinguishedBy: undefined,
|
|
107
|
+
numReports: 0,
|
|
108
|
+
collapsedBecauseCrowdControl: false,
|
|
109
|
+
score: 10,
|
|
110
|
+
userReportReasons: [],
|
|
111
|
+
modReportReasons: [],
|
|
112
|
+
url: 'https://www.reddit.com/r/test/comments/123/test_post/comment',
|
|
113
|
+
ignoringReports: false,
|
|
114
|
+
};
|
|
115
|
+
export const mockUser = {
|
|
116
|
+
id: 't2_123',
|
|
117
|
+
username: 'testuser',
|
|
118
|
+
createdAt: new Date(),
|
|
119
|
+
linkKarma: 1000,
|
|
120
|
+
commentKarma: 500,
|
|
121
|
+
nsfw: false,
|
|
122
|
+
isAdmin: false,
|
|
123
|
+
modPermissions: new Map(),
|
|
124
|
+
url: 'https://www.reddit.com/user/testuser',
|
|
125
|
+
permalink: '/user/testuser',
|
|
126
|
+
hasVerifiedEmail: true,
|
|
127
|
+
};
|
|
128
|
+
// Forms
|
|
129
|
+
export const basicFormDefinition = {
|
|
130
|
+
title: 'Test Form',
|
|
131
|
+
description: 'A test form',
|
|
132
|
+
acceptLabel: 'Submit',
|
|
133
|
+
cancelLabel: 'Cancel',
|
|
134
|
+
fields: [
|
|
135
|
+
{
|
|
136
|
+
type: 'string',
|
|
137
|
+
name: 'username',
|
|
138
|
+
label: 'Username',
|
|
139
|
+
},
|
|
140
|
+
],
|
|
141
|
+
};
|
|
142
|
+
export const complexFormDefinition = {
|
|
143
|
+
title: 'Complex Form',
|
|
144
|
+
description: 'A form with multiple field types',
|
|
145
|
+
acceptLabel: 'Submit',
|
|
146
|
+
cancelLabel: 'Cancel',
|
|
147
|
+
fields: [
|
|
148
|
+
{
|
|
149
|
+
type: 'string',
|
|
150
|
+
name: 'name',
|
|
151
|
+
label: 'Name',
|
|
152
|
+
},
|
|
153
|
+
{
|
|
154
|
+
type: 'number',
|
|
155
|
+
name: 'age',
|
|
156
|
+
label: 'Age',
|
|
157
|
+
},
|
|
158
|
+
{
|
|
159
|
+
type: 'select',
|
|
160
|
+
name: 'color',
|
|
161
|
+
label: 'Favorite Color',
|
|
162
|
+
options: [
|
|
163
|
+
{ label: 'Red', value: 'red' },
|
|
164
|
+
{ label: 'Blue', value: 'blue' },
|
|
165
|
+
{ label: 'Green', value: 'green' },
|
|
166
|
+
],
|
|
167
|
+
},
|
|
168
|
+
],
|
|
169
|
+
};
|
|
170
|
+
export const expectedShowFormMessage = (form) => ({
|
|
171
|
+
showForm: {
|
|
172
|
+
form: {
|
|
173
|
+
id: expect.stringMatching(/^form\.\d+$/),
|
|
174
|
+
title: form.title,
|
|
175
|
+
shortDescription: form.description,
|
|
176
|
+
acceptLabel: form.acceptLabel,
|
|
177
|
+
cancelLabel: form.cancelLabel,
|
|
178
|
+
fields: form.fields.map((field) => {
|
|
179
|
+
if (field.type === 'group') {
|
|
180
|
+
const group = field;
|
|
181
|
+
return {
|
|
182
|
+
fieldId: group.label,
|
|
183
|
+
fieldType: 6, // GROUP
|
|
184
|
+
label: group.label,
|
|
185
|
+
helpText: group.helpText,
|
|
186
|
+
defaultValue: {
|
|
187
|
+
fieldType: 6,
|
|
188
|
+
groupValue: {},
|
|
189
|
+
},
|
|
190
|
+
fieldConfig: {},
|
|
191
|
+
};
|
|
192
|
+
}
|
|
193
|
+
const baseField = {
|
|
194
|
+
fieldId: field.name,
|
|
195
|
+
label: field.label,
|
|
196
|
+
disabled: field.disabled,
|
|
197
|
+
helpText: field.helpText,
|
|
198
|
+
};
|
|
199
|
+
if (field.type === 'string') {
|
|
200
|
+
return {
|
|
201
|
+
...baseField,
|
|
202
|
+
fieldType: 0,
|
|
203
|
+
isSecret: field.isSecret,
|
|
204
|
+
required: 'required' in field ? field.required : undefined,
|
|
205
|
+
defaultValue: {
|
|
206
|
+
fieldType: 0,
|
|
207
|
+
stringValue: undefined,
|
|
208
|
+
},
|
|
209
|
+
fieldConfig: {
|
|
210
|
+
stringConfig: {
|
|
211
|
+
placeholder: undefined,
|
|
212
|
+
},
|
|
213
|
+
},
|
|
214
|
+
};
|
|
215
|
+
}
|
|
216
|
+
if (field.type === 'number') {
|
|
217
|
+
return {
|
|
218
|
+
...baseField,
|
|
219
|
+
fieldType: 2,
|
|
220
|
+
required: 'required' in field ? field.required : undefined,
|
|
221
|
+
defaultValue: {
|
|
222
|
+
fieldType: 2,
|
|
223
|
+
numberValue: undefined,
|
|
224
|
+
},
|
|
225
|
+
fieldConfig: {
|
|
226
|
+
numberConfig: {},
|
|
227
|
+
},
|
|
228
|
+
};
|
|
229
|
+
}
|
|
230
|
+
if (field.type === 'select') {
|
|
231
|
+
return {
|
|
232
|
+
...baseField,
|
|
233
|
+
fieldType: 5,
|
|
234
|
+
required: 'required' in field ? field.required : undefined,
|
|
235
|
+
defaultValue: {
|
|
236
|
+
fieldType: 5,
|
|
237
|
+
selectionValue: {
|
|
238
|
+
values: [],
|
|
239
|
+
},
|
|
240
|
+
},
|
|
241
|
+
fieldConfig: {
|
|
242
|
+
selectionConfig: {
|
|
243
|
+
choices: field.options,
|
|
244
|
+
multiSelect: undefined,
|
|
245
|
+
},
|
|
246
|
+
},
|
|
247
|
+
};
|
|
248
|
+
}
|
|
249
|
+
throw new Error(`Unsupported field type: ${field.type}`);
|
|
250
|
+
}),
|
|
251
|
+
},
|
|
252
|
+
},
|
|
253
|
+
type: 3,
|
|
254
|
+
});
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"transform-form.d.ts","sourceRoot":"","sources":["../../../src/effects/helpers/transform-form.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,IAAI,cAAc,EAAiB,MAAM,gBAAgB,CAAC;AAEjF,OAAO,KAAK,EAEV,SAAS,EAOV,MAAM,iBAAiB,CAAC;AAKzB,wBAAgB,mBAAmB,CAAC,MAAM,EAAE,SAAS,SAAS,EAAE,GAAG,cAAc,EAAE,CAqBlF"}
|
|
@@ -0,0 +1,140 @@
|
|
|
1
|
+
// This is a carbon copy of the transformFormFields function in the public-api package
|
|
2
|
+
// We copy it here so that @devvit/client does not need to depend on public-api
|
|
3
|
+
// Any changes to this function should be reflected in the public-api version
|
|
4
|
+
export function transformFormFields(fields) {
|
|
5
|
+
return fields.map((field) => {
|
|
6
|
+
switch (field.type) {
|
|
7
|
+
case 'string':
|
|
8
|
+
return transformStringField(field);
|
|
9
|
+
case 'image':
|
|
10
|
+
return transformImageField(field);
|
|
11
|
+
case 'paragraph':
|
|
12
|
+
return transformParagraphField(field);
|
|
13
|
+
case 'number':
|
|
14
|
+
return transformNumberField(field);
|
|
15
|
+
case 'select':
|
|
16
|
+
return transformSelectField(field);
|
|
17
|
+
case 'boolean':
|
|
18
|
+
return transformBooleanField(field);
|
|
19
|
+
case 'group':
|
|
20
|
+
return transformGroupField(field);
|
|
21
|
+
default:
|
|
22
|
+
throw new Error('Unknown field type.');
|
|
23
|
+
}
|
|
24
|
+
});
|
|
25
|
+
}
|
|
26
|
+
function transformStringField(field) {
|
|
27
|
+
return {
|
|
28
|
+
defaultValue: {
|
|
29
|
+
fieldType: 0,
|
|
30
|
+
stringValue: field.defaultValue,
|
|
31
|
+
},
|
|
32
|
+
disabled: field.disabled,
|
|
33
|
+
fieldConfig: {
|
|
34
|
+
stringConfig: {
|
|
35
|
+
placeholder: field.placeholder,
|
|
36
|
+
},
|
|
37
|
+
},
|
|
38
|
+
fieldId: field.name,
|
|
39
|
+
fieldType: 0,
|
|
40
|
+
helpText: field.helpText,
|
|
41
|
+
label: field.label,
|
|
42
|
+
required: field.required,
|
|
43
|
+
isSecret: field.isSecret,
|
|
44
|
+
};
|
|
45
|
+
}
|
|
46
|
+
function transformImageField(field) {
|
|
47
|
+
return {
|
|
48
|
+
disabled: field.disabled,
|
|
49
|
+
fieldId: field.name,
|
|
50
|
+
fieldType: 7,
|
|
51
|
+
helpText: field.helpText,
|
|
52
|
+
label: field.label,
|
|
53
|
+
required: field.required,
|
|
54
|
+
};
|
|
55
|
+
}
|
|
56
|
+
function transformParagraphField(field) {
|
|
57
|
+
return {
|
|
58
|
+
defaultValue: {
|
|
59
|
+
fieldType: 1,
|
|
60
|
+
stringValue: field.defaultValue,
|
|
61
|
+
},
|
|
62
|
+
disabled: field.disabled,
|
|
63
|
+
fieldConfig: {
|
|
64
|
+
paragraphConfig: {
|
|
65
|
+
lineHeight: field.lineHeight,
|
|
66
|
+
placeholder: field.placeholder,
|
|
67
|
+
},
|
|
68
|
+
},
|
|
69
|
+
fieldId: field.name,
|
|
70
|
+
fieldType: 1,
|
|
71
|
+
helpText: field.helpText,
|
|
72
|
+
label: field.label,
|
|
73
|
+
required: field.required,
|
|
74
|
+
};
|
|
75
|
+
}
|
|
76
|
+
function transformNumberField(field) {
|
|
77
|
+
return {
|
|
78
|
+
defaultValue: {
|
|
79
|
+
fieldType: 2,
|
|
80
|
+
numberValue: field.defaultValue,
|
|
81
|
+
},
|
|
82
|
+
disabled: field.disabled,
|
|
83
|
+
fieldConfig: {
|
|
84
|
+
numberConfig: {},
|
|
85
|
+
},
|
|
86
|
+
fieldId: field.name,
|
|
87
|
+
fieldType: 2,
|
|
88
|
+
helpText: field.helpText,
|
|
89
|
+
label: field.label,
|
|
90
|
+
required: field.required,
|
|
91
|
+
};
|
|
92
|
+
}
|
|
93
|
+
function transformSelectField(field) {
|
|
94
|
+
return {
|
|
95
|
+
defaultValue: {
|
|
96
|
+
fieldType: 5,
|
|
97
|
+
selectionValue: {
|
|
98
|
+
values: field.defaultValue ?? [],
|
|
99
|
+
},
|
|
100
|
+
},
|
|
101
|
+
disabled: field.disabled,
|
|
102
|
+
fieldConfig: {
|
|
103
|
+
selectionConfig: {
|
|
104
|
+
choices: field.options,
|
|
105
|
+
multiSelect: field.multiSelect,
|
|
106
|
+
},
|
|
107
|
+
},
|
|
108
|
+
fieldId: field.name,
|
|
109
|
+
fieldType: 5,
|
|
110
|
+
helpText: field.helpText,
|
|
111
|
+
label: field.label,
|
|
112
|
+
required: field.required,
|
|
113
|
+
};
|
|
114
|
+
}
|
|
115
|
+
function transformBooleanField(field) {
|
|
116
|
+
return {
|
|
117
|
+
defaultValue: {
|
|
118
|
+
fieldType: 3,
|
|
119
|
+
boolValue: field.defaultValue,
|
|
120
|
+
},
|
|
121
|
+
disabled: field.disabled,
|
|
122
|
+
fieldId: field.name,
|
|
123
|
+
fieldType: 3,
|
|
124
|
+
helpText: field.helpText,
|
|
125
|
+
label: field.label,
|
|
126
|
+
};
|
|
127
|
+
}
|
|
128
|
+
function transformGroupField(field) {
|
|
129
|
+
return {
|
|
130
|
+
fieldId: '',
|
|
131
|
+
fieldType: 6,
|
|
132
|
+
fieldConfig: {
|
|
133
|
+
groupConfig: {
|
|
134
|
+
fields: transformFormFields(field.fields),
|
|
135
|
+
},
|
|
136
|
+
},
|
|
137
|
+
label: field.label,
|
|
138
|
+
helpText: field.helpText,
|
|
139
|
+
};
|
|
140
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"transform-form.test.d.ts","sourceRoot":"","sources":["../../../src/effects/helpers/transform-form.test.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/effects/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAC9C,OAAO,EAAE,QAAQ,EAAE,MAAM,gBAAgB,CAAC;AAC1C,OAAO,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC"}
|
package/effects/index.js
ADDED
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import type { Comment, Post, Subreddit, User } from '@devvit/public-api';
|
|
2
|
+
/**
|
|
3
|
+
* Navigates to a URL, subreddit, post, comment, or user.
|
|
4
|
+
*
|
|
5
|
+
* @param thingOrUrl - The URL, subreddit, post, comment, or user to navigate to
|
|
6
|
+
*/
|
|
7
|
+
export declare function navigateTo(url: string): void;
|
|
8
|
+
export declare function navigateTo(subreddit: Subreddit): void;
|
|
9
|
+
export declare function navigateTo(post: Post): void;
|
|
10
|
+
export declare function navigateTo(comment: Comment): void;
|
|
11
|
+
export declare function navigateTo(user: User): void;
|
|
12
|
+
//# sourceMappingURL=navigate-to.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"navigate-to.d.ts","sourceRoot":"","sources":["../../src/effects/navigate-to.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,OAAO,EAAE,IAAI,EAAE,SAAS,EAAE,IAAI,EAAE,MAAM,oBAAoB,CAAC;AAIzE;;;;GAIG;AACH,wBAAgB,UAAU,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI,CAAC;AAC9C,wBAAgB,UAAU,CAAC,SAAS,EAAE,SAAS,GAAG,IAAI,CAAC;AACvD,wBAAgB,UAAU,CAAC,IAAI,EAAE,IAAI,GAAG,IAAI,CAAC;AAC7C,wBAAgB,UAAU,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI,CAAC;AACnD,wBAAgB,UAAU,CAAC,IAAI,EAAE,IAAI,GAAG,IAAI,CAAC"}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { emitEffect } from './emit-effect.js';
|
|
2
|
+
export function navigateTo(thingOrUrl) {
|
|
3
|
+
let url;
|
|
4
|
+
if (typeof thingOrUrl === 'string') {
|
|
5
|
+
// Validate URL
|
|
6
|
+
url = new URL(thingOrUrl).toString();
|
|
7
|
+
}
|
|
8
|
+
else {
|
|
9
|
+
url = new URL(thingOrUrl.permalink, 'https://www.reddit.com').toString();
|
|
10
|
+
}
|
|
11
|
+
void emitEffect({
|
|
12
|
+
navigateToUrl: {
|
|
13
|
+
url,
|
|
14
|
+
},
|
|
15
|
+
type: 5,
|
|
16
|
+
});
|
|
17
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"navigate-to.test.d.ts","sourceRoot":"","sources":["../../src/effects/navigate-to.test.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import type { Form } from '@devvit/public-api';
|
|
2
|
+
import type { FormToFormValues } from './helpers/form-types.js';
|
|
3
|
+
import { type FormEffectResponse } from './types.js';
|
|
4
|
+
/**
|
|
5
|
+
* Opens a form in a modal.
|
|
6
|
+
* Returns a promise that resolves with the form submission results.
|
|
7
|
+
* The form can be submitted or canceled by the user.
|
|
8
|
+
*
|
|
9
|
+
* @param formDefinition - The form configuration
|
|
10
|
+
* @returns A promise that resolves to either:
|
|
11
|
+
* - An object with `action: FormAction.SUBMITTED` and the submitted form values
|
|
12
|
+
* - An object with `action: FormAction.CANCELED` if the user canceled the form
|
|
13
|
+
* @throws Will throw if the form fields are invalid
|
|
14
|
+
*/
|
|
15
|
+
export declare const showForm: <const T extends Form>(formDefinition: T) => Promise<FormEffectResponse<FormToFormValues<T>>>;
|
|
16
|
+
//# sourceMappingURL=show-form.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"show-form.d.ts","sourceRoot":"","sources":["../../src/effects/show-form.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,IAAI,EAAW,MAAM,oBAAoB,CAAC;AAIxD,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,yBAAyB,CAAC;AAGhE,OAAO,EAAc,KAAK,kBAAkB,EAAE,MAAM,YAAY,CAAC;AASjE;;;;;;;;;;GAUG;AACH,eAAO,MAAM,QAAQ,+FAkCpB,CAAC"}
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
import { emitEffect } from './emit-effect.js';
|
|
2
|
+
import { assertValidFormFields } from './helpers/assert-valid-form-fields.js';
|
|
3
|
+
import { getFormValues } from './helpers/get-form-values.js';
|
|
4
|
+
import { transformFormFields } from './helpers/transform-form.js';
|
|
5
|
+
import { FormAction } from './types.js';
|
|
6
|
+
let _formKey = 1;
|
|
7
|
+
const getNextFormKey = () => {
|
|
8
|
+
_formKey++;
|
|
9
|
+
return `form.${_formKey}`;
|
|
10
|
+
};
|
|
11
|
+
/**
|
|
12
|
+
* Opens a form in a modal.
|
|
13
|
+
* Returns a promise that resolves with the form submission results.
|
|
14
|
+
* The form can be submitted or canceled by the user.
|
|
15
|
+
*
|
|
16
|
+
* @param formDefinition - The form configuration
|
|
17
|
+
* @returns A promise that resolves to either:
|
|
18
|
+
* - An object with `action: FormAction.SUBMITTED` and the submitted form values
|
|
19
|
+
* - An object with `action: FormAction.CANCELED` if the user canceled the form
|
|
20
|
+
* @throws Will throw if the form fields are invalid
|
|
21
|
+
*/
|
|
22
|
+
export const showForm = async (formDefinition) => {
|
|
23
|
+
const form = {
|
|
24
|
+
fields: [],
|
|
25
|
+
id: getNextFormKey(),
|
|
26
|
+
title: formDefinition.title,
|
|
27
|
+
acceptLabel: formDefinition.acceptLabel,
|
|
28
|
+
cancelLabel: formDefinition.cancelLabel,
|
|
29
|
+
shortDescription: formDefinition.description,
|
|
30
|
+
};
|
|
31
|
+
assertValidFormFields(formDefinition.fields);
|
|
32
|
+
form.fields = transformFormFields(formDefinition.fields);
|
|
33
|
+
const response = await emitEffect({
|
|
34
|
+
showForm: {
|
|
35
|
+
form,
|
|
36
|
+
},
|
|
37
|
+
type: 3,
|
|
38
|
+
});
|
|
39
|
+
if (!response || !response.formSubmitted) {
|
|
40
|
+
return {
|
|
41
|
+
action: FormAction.CANCELED,
|
|
42
|
+
};
|
|
43
|
+
}
|
|
44
|
+
const formResults = getFormValues(response.formSubmitted.results);
|
|
45
|
+
return {
|
|
46
|
+
action: FormAction.SUBMITTED,
|
|
47
|
+
values: formResults,
|
|
48
|
+
};
|
|
49
|
+
};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"show-form.test.d.ts","sourceRoot":"","sources":["../../src/effects/show-form.test.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import type { Toast } from '@devvit/public-api';
|
|
2
|
+
/**
|
|
3
|
+
* Shows a toast message.
|
|
4
|
+
*
|
|
5
|
+
* @param textOrToast - The text or toast object to display
|
|
6
|
+
*/
|
|
7
|
+
export declare function showToast(text: string): void;
|
|
8
|
+
export declare function showToast(toast: Toast): void;
|
|
9
|
+
//# sourceMappingURL=show-toast.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"show-toast.d.ts","sourceRoot":"","sources":["../../src/effects/show-toast.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,oBAAoB,CAAC;AAIhD;;;;GAIG;AACH,wBAAgB,SAAS,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;AAC9C,wBAAgB,SAAS,CAAC,KAAK,EAAE,KAAK,GAAG,IAAI,CAAC"}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { emitEffect } from './emit-effect.js';
|
|
2
|
+
export function showToast(textOrToast) {
|
|
3
|
+
let toast;
|
|
4
|
+
if (textOrToast instanceof Object) {
|
|
5
|
+
toast = {
|
|
6
|
+
text: textOrToast.text,
|
|
7
|
+
appearance: textOrToast.appearance === 'success'
|
|
8
|
+
? (1)
|
|
9
|
+
: (0),
|
|
10
|
+
};
|
|
11
|
+
}
|
|
12
|
+
else {
|
|
13
|
+
toast = {
|
|
14
|
+
text: textOrToast,
|
|
15
|
+
};
|
|
16
|
+
}
|
|
17
|
+
void emitEffect({
|
|
18
|
+
showToast: {
|
|
19
|
+
toast,
|
|
20
|
+
},
|
|
21
|
+
type: 4,
|
|
22
|
+
});
|
|
23
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"show-toast.test.d.ts","sourceRoot":"","sources":["../../src/effects/show-toast.test.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import type { Effect } from '@devvit/protos';
|
|
2
|
+
import type { WebViewInternalMessageScope } from '@devvit/protos/types/devvit/ui/effects/web_view/v1alpha/post_message.js';
|
|
3
|
+
export type EmitEffectPayload = {
|
|
4
|
+
id?: string;
|
|
5
|
+
scope: WebViewInternalMessageScope;
|
|
6
|
+
type: string;
|
|
7
|
+
effect: Effect;
|
|
8
|
+
};
|
|
9
|
+
export declare enum FormAction {
|
|
10
|
+
CANCELED = "CANCELED",
|
|
11
|
+
SUBMITTED = "SUBMITTED"
|
|
12
|
+
}
|
|
13
|
+
export type FormEffectResponse<T> = {
|
|
14
|
+
action: FormAction.CANCELED;
|
|
15
|
+
} | {
|
|
16
|
+
action: FormAction.SUBMITTED;
|
|
17
|
+
values: T;
|
|
18
|
+
};
|
|
19
|
+
//# sourceMappingURL=types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/effects/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,gBAAgB,CAAC;AAC7C,OAAO,KAAK,EAAE,2BAA2B,EAAE,MAAM,yEAAyE,CAAC;AAE3H,MAAM,MAAM,iBAAiB,GAAG;IAC9B,EAAE,CAAC,EAAE,MAAM,CAAC;IACZ,KAAK,EAAE,2BAA2B,CAAC;IACnC,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,MAAM,CAAC;CAChB,CAAC;AAGF,oBAAY,UAAU;IACpB,QAAQ,aAAa;IACrB,SAAS,cAAc;CACxB;AAED,MAAM,MAAM,kBAAkB,CAAC,CAAC,IAC5B;IAAE,MAAM,EAAE,UAAU,CAAC,QAAQ,CAAA;CAAE,GAC/B;IAAE,MAAM,EAAE,UAAU,CAAC,SAAS,CAAC;IAAC,MAAM,EAAE,CAAC,CAAA;CAAE,CAAC"}
|
package/effects/types.js
ADDED
package/index.d.ts
ADDED
package/index.d.ts.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,QAAQ,EAAE,SAAS,EAAE,MAAM,oBAAoB,CAAC"}
|
package/index.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { navigateTo, showForm, showToast } from './effects/index.js';
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.test.d.ts","sourceRoot":"","sources":["../src/index.test.ts"],"names":[],"mappings":""}
|
package/package.json
ADDED
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@devvit/client",
|
|
3
|
+
"version": "0.11.14-next-2025-05-05-765f3688c.0",
|
|
4
|
+
"license": "BSD-3-Clause",
|
|
5
|
+
"repository": {
|
|
6
|
+
"type": "git",
|
|
7
|
+
"url": "https://developers.reddit.com/"
|
|
8
|
+
},
|
|
9
|
+
"type": "module",
|
|
10
|
+
"main": "./index.js",
|
|
11
|
+
"scripts": {
|
|
12
|
+
"build": "tsc",
|
|
13
|
+
"build:min": "esbuild --bundle --format=esm --minify --sourcemap=linked --target=es2020",
|
|
14
|
+
"clean": "rm -rf .turbo coverage dist",
|
|
15
|
+
"clobber": "yarn clean && rm -rf node_modules",
|
|
16
|
+
"dev": "tsc -w",
|
|
17
|
+
"lint": "redlint .",
|
|
18
|
+
"lint:fix": "yarn lint --fix",
|
|
19
|
+
"prepublishOnly": "publish-package-json",
|
|
20
|
+
"test": "yarn test:unit && yarn test:types && yarn lint && yarn test:size",
|
|
21
|
+
"test:size": "yarn build:min src/index.ts --metafile=dist/client-meta.min.json --outfile=dist/client.min.js && filesize",
|
|
22
|
+
"test:types": "tsc --noEmit",
|
|
23
|
+
"test:unit": "vitest run",
|
|
24
|
+
"test:unit-with-coverage": "vitest run --coverage"
|
|
25
|
+
},
|
|
26
|
+
"types": "./index.d.ts",
|
|
27
|
+
"devDependencies": {
|
|
28
|
+
"@ampproject/filesize": "4.3.0",
|
|
29
|
+
"@devvit/protos": "0.11.14-next-2025-05-05-765f3688c.0",
|
|
30
|
+
"@devvit/public-api": "0.11.14-next-2025-05-05-765f3688c.0",
|
|
31
|
+
"@devvit/repo-tools": "0.11.14-next-2025-05-05-765f3688c.0",
|
|
32
|
+
"@devvit/tsconfig": "0.11.14-next-2025-05-05-765f3688c.0",
|
|
33
|
+
"esbuild": "0.23.0",
|
|
34
|
+
"eslint": "9.11.1",
|
|
35
|
+
"typescript": "5.3.2",
|
|
36
|
+
"vitest": "1.6.1"
|
|
37
|
+
},
|
|
38
|
+
"publishConfig": {
|
|
39
|
+
"directory": "dist"
|
|
40
|
+
},
|
|
41
|
+
"filesize": {
|
|
42
|
+
"dist/client.min.js": {
|
|
43
|
+
"gzip": "1.32 KB",
|
|
44
|
+
"none": "3.42 KB"
|
|
45
|
+
}
|
|
46
|
+
},
|
|
47
|
+
"source": "./src/index.ts",
|
|
48
|
+
"gitHead": "f74f2c6405eac9d70b8ac67cdd13b24370bddb4a"
|
|
49
|
+
}
|