@devvit/client 0.12.7-next-2025-12-15-22-14-35-6c217d0d4.0 → 0.12.7-next-2025-12-16-01-25-33-548943dfa.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.
@@ -5,6 +5,11 @@
5
5
  "imports": [],
6
6
  "format": "esm"
7
7
  },
8
+ "src/effects/helpers/form-types.ts": {
9
+ "bytes": 2373,
10
+ "imports": [],
11
+ "format": "esm"
12
+ },
8
13
  "../protos/dist/json/devvit/ui/effects/v1alpha/effect.js": {
9
14
  "bytes": 2186,
10
15
  "imports": [],
@@ -95,22 +100,182 @@
95
100
  "format": "esm"
96
101
  },
97
102
  "src/effects/helpers/assert-valid-form-fields.ts": {
98
- "bytes": 1271,
103
+ "bytes": 1270,
99
104
  "imports": [],
100
105
  "format": "esm"
101
106
  },
102
- "src/effects/helpers/get-form-values.ts": {
103
- "bytes": 1337,
107
+ "../protos/dist/json/devvit/ui/form_builder/v1alpha/type.js": {
108
+ "bytes": 1198,
104
109
  "imports": [],
105
110
  "format": "esm"
106
111
  },
107
- "src/effects/helpers/transform-form.ts": {
108
- "bytes": 4194,
112
+ "../shared/dist/types/menu-item.js": {
113
+ "bytes": 11,
114
+ "imports": [],
115
+ "format": "esm"
116
+ },
117
+ "../shared/dist/types/settings.js": {
118
+ "bytes": 11,
119
+ "imports": [],
120
+ "format": "esm"
121
+ },
122
+ "../protos/dist/json/devvit/events/v1alpha/events.js": {
123
+ "bytes": 1117,
124
+ "imports": [],
125
+ "format": "esm"
126
+ },
127
+ "../protos/dist/json/devvit/reddit/v2alpha/postv2.js": {
128
+ "bytes": 1135,
129
+ "imports": [],
130
+ "format": "esm"
131
+ },
132
+ "../protos/dist/json/devvit/reddit/v2alpha/subredditv2.js": {
133
+ "bytes": 1611,
134
+ "imports": [],
135
+ "format": "esm"
136
+ },
137
+ "../shared/dist/types/triggers.js": {
138
+ "bytes": 708,
139
+ "imports": [
140
+ {
141
+ "path": "../protos/dist/json/devvit/events/v1alpha/events.js",
142
+ "kind": "import-statement",
143
+ "original": "@devvit/protos/json/devvit/events/v1alpha/events.js"
144
+ },
145
+ {
146
+ "path": "../protos/dist/json/devvit/events/v1alpha/events.js",
147
+ "kind": "import-statement",
148
+ "original": "@devvit/protos/json/devvit/events/v1alpha/events.js"
149
+ },
150
+ {
151
+ "path": "../protos/dist/json/devvit/reddit/v2alpha/postv2.js",
152
+ "kind": "import-statement",
153
+ "original": "@devvit/protos/json/devvit/reddit/v2alpha/postv2.js"
154
+ },
155
+ {
156
+ "path": "../protos/dist/json/devvit/reddit/v2alpha/subredditv2.js",
157
+ "kind": "import-statement",
158
+ "original": "@devvit/protos/json/devvit/reddit/v2alpha/subredditv2.js"
159
+ }
160
+ ],
161
+ "format": "esm"
162
+ },
163
+ "../shared/dist/types/ui-response.js": {
164
+ "bytes": 11,
165
+ "imports": [],
166
+ "format": "esm"
167
+ },
168
+ "../shared-types/dist/json.js": {
169
+ "bytes": 11,
170
+ "imports": [],
171
+ "format": "esm"
172
+ },
173
+ "../shared-types/dist/shared/baseContext.js": {
174
+ "bytes": 11,
109
175
  "imports": [],
110
176
  "format": "esm"
111
177
  },
178
+ "../shared-types/dist/shared/form.js": {
179
+ "bytes": 177,
180
+ "imports": [],
181
+ "format": "esm"
182
+ },
183
+ "../shared-types/dist/assert.js": {
184
+ "bytes": 89,
185
+ "imports": [],
186
+ "format": "esm"
187
+ },
188
+ "../shared-types/dist/tid.js": {
189
+ "bytes": 2471,
190
+ "imports": [
191
+ {
192
+ "path": "../shared-types/dist/assert.js",
193
+ "kind": "import-statement",
194
+ "original": "./assert.js"
195
+ }
196
+ ],
197
+ "format": "esm"
198
+ },
199
+ "../shared/dist/index.js": {
200
+ "bytes": 356,
201
+ "imports": [
202
+ {
203
+ "path": "../shared/dist/types/menu-item.js",
204
+ "kind": "import-statement",
205
+ "original": "./types/menu-item.js"
206
+ },
207
+ {
208
+ "path": "../shared/dist/types/settings.js",
209
+ "kind": "import-statement",
210
+ "original": "./types/settings.js"
211
+ },
212
+ {
213
+ "path": "../shared/dist/types/triggers.js",
214
+ "kind": "import-statement",
215
+ "original": "./types/triggers.js"
216
+ },
217
+ {
218
+ "path": "../shared/dist/types/ui-response.js",
219
+ "kind": "import-statement",
220
+ "original": "./types/ui-response.js"
221
+ },
222
+ {
223
+ "path": "../shared-types/dist/json.js",
224
+ "kind": "import-statement",
225
+ "original": "@devvit/shared-types/json.js"
226
+ },
227
+ {
228
+ "path": "../shared-types/dist/shared/baseContext.js",
229
+ "kind": "import-statement",
230
+ "original": "@devvit/shared-types/shared/baseContext.js"
231
+ },
232
+ {
233
+ "path": "../shared-types/dist/shared/form.js",
234
+ "kind": "import-statement",
235
+ "original": "@devvit/shared-types/shared/form.js"
236
+ },
237
+ {
238
+ "path": "../shared-types/dist/tid.js",
239
+ "kind": "import-statement",
240
+ "original": "@devvit/shared-types/tid.js"
241
+ }
242
+ ],
243
+ "format": "esm"
244
+ },
245
+ "src/effects/helpers/get-form-values.ts": {
246
+ "bytes": 1449,
247
+ "imports": [
248
+ {
249
+ "path": "../protos/dist/json/devvit/ui/form_builder/v1alpha/type.js",
250
+ "kind": "import-statement",
251
+ "original": "@devvit/protos/json/devvit/ui/form_builder/v1alpha/type.js"
252
+ },
253
+ {
254
+ "path": "../shared/dist/index.js",
255
+ "kind": "import-statement",
256
+ "original": "@devvit/shared"
257
+ }
258
+ ],
259
+ "format": "esm"
260
+ },
261
+ "src/effects/helpers/transform-form.ts": {
262
+ "bytes": 4205,
263
+ "imports": [
264
+ {
265
+ "path": "../protos/dist/json/devvit/ui/form_builder/v1alpha/type.js",
266
+ "kind": "import-statement",
267
+ "original": "@devvit/protos/json/devvit/ui/form_builder/v1alpha/type.js"
268
+ },
269
+ {
270
+ "path": "../shared/dist/index.js",
271
+ "kind": "import-statement",
272
+ "original": "@devvit/shared"
273
+ }
274
+ ],
275
+ "format": "esm"
276
+ },
112
277
  "src/effects/show-form.ts": {
113
- "bytes": 2095,
278
+ "bytes": 2130,
114
279
  "imports": [
115
280
  {
116
281
  "path": "../shared-types/dist/client/emit-effect.js",
@@ -183,13 +348,18 @@
183
348
  "format": "esm"
184
349
  },
185
350
  "src/index.ts": {
186
- "bytes": 409,
351
+ "bytes": 458,
187
352
  "imports": [
188
353
  {
189
354
  "path": "src/clientContext.ts",
190
355
  "kind": "import-statement",
191
356
  "original": "./clientContext.js"
192
357
  },
358
+ {
359
+ "path": "src/effects/helpers/form-types.ts",
360
+ "kind": "import-statement",
361
+ "original": "./effects/helpers/form-types.js"
362
+ },
193
363
  {
194
364
  "path": "src/effects/navigate-to.ts",
195
365
  "kind": "import-statement",
@@ -234,7 +404,7 @@
234
404
  "imports": [],
235
405
  "exports": [],
236
406
  "inputs": {},
237
- "bytes": 39857
407
+ "bytes": 51263
238
408
  },
239
409
  "dist/client.min.js": {
240
410
  "imports": [],
@@ -276,22 +446,46 @@
276
446
  "bytesInOutput": 405
277
447
  },
278
448
  "src/effects/run-as-user.ts": {
279
- "bytesInOutput": 513
449
+ "bytesInOutput": 514
280
450
  },
281
451
  "../shared-types/dist/constants.js": {
282
452
  "bytesInOutput": 25
283
453
  },
284
454
  "src/effects/share.ts": {
285
- "bytesInOutput": 358
455
+ "bytesInOutput": 359
286
456
  },
287
457
  "src/effects/helpers/assert-valid-form-fields.ts": {
288
458
  "bytesInOutput": 357
289
459
  },
460
+ "../protos/dist/json/devvit/ui/form_builder/v1alpha/type.js": {
461
+ "bytesInOutput": 258
462
+ },
463
+ "../shared/dist/index.js": {
464
+ "bytesInOutput": 0
465
+ },
466
+ "../protos/dist/json/devvit/events/v1alpha/events.js": {
467
+ "bytesInOutput": 450
468
+ },
469
+ "../shared/dist/types/triggers.js": {
470
+ "bytesInOutput": 0
471
+ },
472
+ "../protos/dist/json/devvit/reddit/v2alpha/postv2.js": {
473
+ "bytesInOutput": 366
474
+ },
475
+ "../protos/dist/json/devvit/reddit/v2alpha/subredditv2.js": {
476
+ "bytesInOutput": 511
477
+ },
478
+ "../shared-types/dist/shared/form.js": {
479
+ "bytesInOutput": 74
480
+ },
481
+ "../shared-types/dist/tid.js": {
482
+ "bytesInOutput": 125
483
+ },
290
484
  "src/effects/helpers/get-form-values.ts": {
291
- "bytesInOutput": 331
485
+ "bytesInOutput": 379
292
486
  },
293
487
  "src/effects/helpers/transform-form.ts": {
294
- "bytesInOutput": 1664
488
+ "bytesInOutput": 1760
295
489
  },
296
490
  "src/effects/show-form.ts": {
297
491
  "bytesInOutput": 345
@@ -309,7 +503,7 @@
309
503
  "bytesInOutput": 993
310
504
  }
311
505
  },
312
- "bytes": 7106
506
+ "bytes": 9038
313
507
  }
314
508
  }
315
509
  }
package/client.min.js CHANGED
@@ -1,2 +1,2 @@
1
- var D=globalThis.devvit?.context;var n;(function(e){e[e.EFFECT_REALTIME_SUB=0]="EFFECT_REALTIME_SUB",e[e.EFFECT_RERENDER_UI=1]="EFFECT_RERENDER_UI",e[e.EFFECT_RELOAD_PART=2]="EFFECT_RELOAD_PART",e[e.EFFECT_SHOW_FORM=3]="EFFECT_SHOW_FORM",e[e.EFFECT_SHOW_TOAST=4]="EFFECT_SHOW_TOAST",e[e.EFFECT_NAVIGATE_TO_URL=5]="EFFECT_NAVIGATE_TO_URL",e[e.EFFECT_SET_INTERVALS=7]="EFFECT_SET_INTERVALS",e[e.EFFECT_CREATE_ORDER=8]="EFFECT_CREATE_ORDER",e[e.EFFECT_WEB_VIEW=9]="EFFECT_WEB_VIEW",e[e.EFFECT_CAN_RUN_AS_USER=11]="EFFECT_CAN_RUN_AS_USER",e[e.EFFECT_TELEMETRY=12]="EFFECT_TELEMETRY",e[e.EFFECT_UPDATE_REQUEST_CONTEXT=13]="EFFECT_UPDATE_REQUEST_CONTEXT",e[e.UNRECOGNIZED=-1]="UNRECOGNIZED"})(n||(n={}));var p;(function(e){e[e.CLIENT=0]="CLIENT",e[e.UNRECOGNIZED=-1]="UNRECOGNIZED"})(p||(p={}));var S="devvit-internal",v={[n.EFFECT_SHOW_FORM]:!0,[n.EFFECT_CAN_RUN_AS_USER]:!0,[n.EFFECT_CREATE_ORDER]:!0},i=e=>new Promise(t=>{let r={...e,realtimeEffect:e.realtime,scope:p.CLIENT,type:S};if((e.showToast||e.navigateToUrl||e.showForm||e.type===n.EFFECT_CAN_RUN_AS_USER)&&(r.effect=e),v[e.type]){let o=crypto.randomUUID();r.id=o;let l=d=>{d.data?.type==="devvit-message"&&d.data?.data?.id===o&&(t(d.data.data),removeEventListener("message",l))};addEventListener("message",l),parent.postMessage(r,"*")}else parent.postMessage(r,"*"),t(void 0)});function B(e){let t=typeof e=="string"?e:e.url,r;try{r=new URL(t).toString()}catch{throw new TypeError(`Invalid URL: ${t}`)}i({navigateToUrl:{url:r},type:5})}var a;(function(e){e[e.CONSENT_STATUS_UNKNOWN=0]="CONSENT_STATUS_UNKNOWN",e[e.REVOKED=1]="REVOKED",e[e.GRANTED=2]="GRANTED",e[e.UNRECOGNIZED=-1]="UNRECOGNIZED"})(a||(a={}));var F;(function(e){e[e.SCOPE_UNKNOWN=0]="SCOPE_UNKNOWN",e[e.SUBMIT_POST=1]="SUBMIT_POST",e[e.SUBMIT_COMMENT=2]="SUBMIT_COMMENT",e[e.SUBSCRIBE_TO_SUBREDDIT=3]="SUBSCRIBE_TO_SUBREDDIT",e[e.UNRECOGNIZED=-1]="UNRECOGNIZED"})(F||(F={}));var k=async()=>{let e=devvit.appPermissionState;if(!e)return!0;if(e.requestedScopes.length===0)return!1;switch(e.consentStatus){case a.REVOKED:return!1;case a.GRANTED:if(e.requestedScopes.every(r=>e.grantedScopes.includes(r)))return!0;break;case a.CONSENT_STATUS_UNKNOWN:case a.UNRECOGNIZED:break;default:{e.consentStatus;break}}return(await i({canRunAsUser:{postId:devvit.context.postId,appSlug:devvit.context.appName,subredditId:devvit.context.subredditId},type:11}))?.consentStatus?.consentStatus===a.GRANTED};var u="$devvit_icon.png";async function J(e){if(e.data&&e.data.length>1024)throw Error(`data must be <= ${1024} characters but was ${e.data.length} characters`);let t=`${new URL(u,location.origin)}`,r;try{r=await fetch(t,{method:"HEAD"})}catch{}await i({type:9,share:{appIconUri:r?.ok?t:void 0,userData:e.data,text:e.text,title:e.title}})}function ee(){return devvit.share?.userData}function E(e,t=new Set){for(let r of e){if(r.type==="group"){E(r.fields,t);continue}let o=r.name;if(t.has(o))throw new Error(`Duplicate field name: ${o}`);t.add(o)}N(e)}function N(e){for(let t of e)if(t.type==="string"&&t.isSecret&&t.scope!=="app")throw`Invalid setting: only app settings can be secrets. Add "scope: SettingScope.App" to field "${t.name}"`}function I(e){switch(e.fieldType){case 0:return e.stringValue;case 7:return e.stringValue;case 1:return e.stringValue;case 2:return e.numberValue;case 3:return e.boolValue;case 5:return e.selectionValue?.values??[];default:return}}function T(e){return Object.keys(e).reduce((t,r)=>{let o=I(e[r]);return o!==void 0&&(t[r]=o),t},{})}function m(e){return e.map(t=>{switch(t.type){case"string":return C(t);case"image":return x(t);case"paragraph":return y(t);case"number":return h(t);case"select":return O(t);case"boolean":return U(t);case"group":return g(t);default:throw new Error("Unknown field type.")}})}function C(e){return{defaultValue:{fieldType:0,stringValue:e.defaultValue},disabled:e.disabled,fieldConfig:{stringConfig:{placeholder:e.placeholder}},fieldId:e.name,fieldType:0,helpText:e.helpText,label:e.label,required:e.required,isSecret:e.isSecret}}function x(e){return{disabled:e.disabled,fieldId:e.name,fieldType:7,helpText:e.helpText,label:e.label,required:e.required}}function y(e){return{defaultValue:{fieldType:1,stringValue:e.defaultValue},disabled:e.disabled,fieldConfig:{paragraphConfig:{lineHeight:e.lineHeight,placeholder:e.placeholder}},fieldId:e.name,fieldType:1,helpText:e.helpText,label:e.label,required:e.required}}function h(e){return{defaultValue:{fieldType:2,numberValue:e.defaultValue},disabled:e.disabled,fieldConfig:{numberConfig:{}},fieldId:e.name,fieldType:2,helpText:e.helpText,label:e.label,required:e.required}}function O(e){return{defaultValue:{fieldType:5,selectionValue:{values:e.defaultValue??[]}},disabled:e.disabled,fieldConfig:{selectionConfig:{choices:e.options,multiSelect:e.multiSelect}},fieldId:e.name,fieldType:5,helpText:e.helpText,label:e.label,required:e.required}}function U(e){return{defaultValue:{fieldType:3,boolValue:e.defaultValue},disabled:e.disabled,fieldId:e.name,fieldType:3,helpText:e.helpText,label:e.label}}function g(e){return{fieldId:"",fieldType:6,fieldConfig:{groupConfig:{fields:m(e.fields)}},label:e.label,helpText:e.helpText}}var f=1,A=()=>(f++,`form.${f}`),pe=async e=>{let t={fields:[],id:A(),title:e.title,acceptLabel:e.acceptLabel,cancelLabel:e.cancelLabel,shortDescription:e.description};E(e.fields),t.fields=m(e.fields);let r=await i({showForm:{form:t},type:3});return!r||!r.formSubmitted?{action:"CANCELED"}:{action:"SUBMITTED",values:T(r.formSubmitted.results)}};function me(e){let t;e instanceof Object?t={text:e.text,appearance:e.appearance==="success"?1:0}:t={text:e},i({showToast:{toast:t},type:4})}var s;(function(e){e[e.UNSPECIFIED=0]="UNSPECIFIED",e[e.INLINE_MODE=1]="INLINE_MODE",e[e.IMMERSIVE_MODE=2]="IMMERSIVE_MODE",e[e.UNRECOGNIZED=-1]="UNRECOGNIZED"})(s||(s={}));var _="token";var Re=()=>b(devvit.webViewMode);function Se(e,t){if(devvit.webViewMode===s.IMMERSIVE_MODE)throw Error("web view is already expanded");return R(s.IMMERSIVE_MODE,e,t)}function ve(e){if(devvit.webViewMode===s.INLINE_MODE)throw Error("web view is already inlined");return R(s.INLINE_MODE,e,void 0)}function Ne(e){}function Ie(e){}async function R(e,t,r){if(!t.isTrusted||t.type!=="click")throw console.error("Expanded mode effect ignored due to untrusted event"),new Error("Untrusted event");if(r!=null&&!devvit.entrypoints[r])throw Error(`no entrypoint named "${r}"; all entrypoints must appear in \`devvit.json\` \`post.entrypoints\``);let o;if(r){let d=new URL(devvit.entrypoints[r]);d.searchParams.set(_,devvit.token),o=`${d}`}await i({type:9,immersiveMode:{entryUrl:o,immersiveMode:e}})}function b(e){switch(e){case s.IMMERSIVE_MODE:return"expanded";case s.INLINE_MODE:case s.UNRECOGNIZED:case s.UNSPECIFIED:case void 0:return"inline";default:throw Error(`${e} not a WebViewImmersiveMode`)}}export{Ne as addWebViewModeListener,k as canRunAsUser,D as context,ve as exitExpandedMode,ee as getShareData,Re as getWebViewMode,B as navigateTo,Ie as removeWebViewModeListener,Se as requestExpandedMode,pe as showForm,J as showShareSheet,me as showToast};
1
+ var j=globalThis.devvit?.context;var i;(function(e){e[e.EFFECT_REALTIME_SUB=0]="EFFECT_REALTIME_SUB",e[e.EFFECT_RERENDER_UI=1]="EFFECT_RERENDER_UI",e[e.EFFECT_RELOAD_PART=2]="EFFECT_RELOAD_PART",e[e.EFFECT_SHOW_FORM=3]="EFFECT_SHOW_FORM",e[e.EFFECT_SHOW_TOAST=4]="EFFECT_SHOW_TOAST",e[e.EFFECT_NAVIGATE_TO_URL=5]="EFFECT_NAVIGATE_TO_URL",e[e.EFFECT_SET_INTERVALS=7]="EFFECT_SET_INTERVALS",e[e.EFFECT_CREATE_ORDER=8]="EFFECT_CREATE_ORDER",e[e.EFFECT_WEB_VIEW=9]="EFFECT_WEB_VIEW",e[e.EFFECT_CAN_RUN_AS_USER=11]="EFFECT_CAN_RUN_AS_USER",e[e.EFFECT_TELEMETRY=12]="EFFECT_TELEMETRY",e[e.EFFECT_UPDATE_REQUEST_CONTEXT=13]="EFFECT_UPDATE_REQUEST_CONTEXT",e[e.UNRECOGNIZED=-1]="UNRECOGNIZED"})(i||(i={}));var c;(function(e){e[e.CLIENT=0]="CLIENT",e[e.UNRECOGNIZED=-1]="UNRECOGNIZED"})(c||(c={}));var h="devvit-internal",D={[i.EFFECT_SHOW_FORM]:!0,[i.EFFECT_CAN_RUN_AS_USER]:!0,[i.EFFECT_CREATE_ORDER]:!0},a=e=>new Promise(t=>{let r={...e,realtimeEffect:e.realtime,scope:c.CLIENT,type:h};if((e.showToast||e.navigateToUrl||e.showForm||e.type===i.EFFECT_CAN_RUN_AS_USER)&&(r.effect=e),D[e.type]){let n=crypto.randomUUID();r.id=n;let f=p=>{p.data?.type==="devvit-message"&&p.data?.data?.id===n&&(t(p.data.data),removeEventListener("message",f))};addEventListener("message",f),parent.postMessage(r,"*")}else parent.postMessage(r,"*"),t(void 0)});function J(e){let t=typeof e=="string"?e:e.url,r;try{r=new URL(t).toString()}catch{throw new TypeError(`Invalid URL: ${t}`)}a({navigateToUrl:{url:r},type:5})}var E;(function(e){e[e.CONSENT_STATUS_UNKNOWN=0]="CONSENT_STATUS_UNKNOWN",e[e.REVOKED=1]="REVOKED",e[e.GRANTED=2]="GRANTED",e[e.UNRECOGNIZED=-1]="UNRECOGNIZED"})(E||(E={}));var O;(function(e){e[e.SCOPE_UNKNOWN=0]="SCOPE_UNKNOWN",e[e.SUBMIT_POST=1]="SUBMIT_POST",e[e.SUBMIT_COMMENT=2]="SUBMIT_COMMENT",e[e.SUBSCRIBE_TO_SUBREDDIT=3]="SUBSCRIBE_TO_SUBREDDIT",e[e.UNRECOGNIZED=-1]="UNRECOGNIZED"})(O||(O={}));var te=async()=>{let e=devvit.appPermissionState;if(!e)return!0;if(e.requestedScopes.length===0)return!1;switch(e.consentStatus){case E.REVOKED:return!1;case E.GRANTED:if(e.requestedScopes.every(r=>e.grantedScopes.includes(r)))return!0;break;case E.CONSENT_STATUS_UNKNOWN:case E.UNRECOGNIZED:break;default:{e.consentStatus;break}}return(await a({canRunAsUser:{postId:devvit.context.postId,appSlug:devvit.context.appName,subredditId:devvit.context.subredditId},type:11}))?.consentStatus?.consentStatus===E.GRANTED};var R="$devvit_icon.png";async function ie(e){if(e.data&&e.data.length>1024)throw Error(`data must be <= ${1024} characters but was ${e.data.length} characters`);let t=`${new URL(R,location.origin)}`,r;try{r=await fetch(t,{method:"HEAD"})}catch{}await a({type:9,share:{appIconUri:r?.ok?t:void 0,userData:e.data,text:e.text,title:e.title}})}function pe(){return devvit.share?.userData}function l(e,t=new Set){for(let r of e){if(r.type==="group"){l(r.fields,t);continue}let n=r.name;if(t.has(n))throw new Error(`Duplicate field name: ${n}`);t.add(n)}M(e)}function M(e){for(let t of e)if(t.type==="string"&&t.isSecret&&t.scope!=="app")throw`Invalid setting: only app settings can be secrets. Add "scope: SettingScope.App" to field "${t.name}"`}var o;(function(e){e[e.STRING=0]="STRING",e[e.PARAGRAPH=1]="PARAGRAPH",e[e.NUMBER=2]="NUMBER",e[e.BOOLEAN=3]="BOOLEAN",e[e.LIST=4]="LIST",e[e.SELECTION=5]="SELECTION",e[e.GROUP=6]="GROUP",e[e.IMAGE=7]="IMAGE",e[e.UNRECOGNIZED=-1]="UNRECOGNIZED"})(o||(o={}));var m;(function(e){e[e.UNKNOWN_EVENT_SOURCE=0]="UNKNOWN_EVENT_SOURCE",e[e.USER=1]="USER",e[e.ADMIN=2]="ADMIN",e[e.MODERATOR=3]="MODERATOR",e[e.UNRECOGNIZED=-1]="UNRECOGNIZED"})(m||(m={}));var u;(function(e){e[e.UNSPECIFIED_DELETION_REASON=0]="UNSPECIFIED_DELETION_REASON",e[e.SPAM=1]="SPAM",e[e.LEGAL=2]="LEGAL",e[e.OTHER=3]="OTHER",e[e.UNKNOWN=4]="UNKNOWN",e[e.EXPLICIT_CONTENT=5]="EXPLICIT_CONTENT",e[e.UNRECOGNIZED=-1]="UNRECOGNIZED"})(u||(u={}));var d;(function(e){e[e.OFF=0]="OFF",e[e.LENIENT=1]="LENIENT",e[e.MEDIUM=2]="MEDIUM",e[e.STRICT=3]="STRICT",e[e.UNRECOGNIZED=-1]="UNRECOGNIZED"})(d||(d={}));var N;(function(e){e[e.NULL_VALUE=0]="NULL_VALUE",e[e.ADMIN=1]="ADMIN",e[e.GOLD=2]="GOLD",e[e.GOLD_AUTO=3]="GOLD_AUTO",e[e.YES=4]="YES",e[e.SPECIAL=5]="SPECIAL",e[e.UNRECOGNIZED=-1]="UNRECOGNIZED"})(N||(N={}));var T;(function(e){e[e.ARCHIVED=0]="ARCHIVED",e[e.EMPLOYEES_ONLY=1]="EMPLOYEES_ONLY",e[e.GOLD_ONLY=2]="GOLD_ONLY",e[e.GOLD_RESTRICTED=3]="GOLD_RESTRICTED",e[e.PRIVATE=4]="PRIVATE",e[e.PUBLIC=5]="PUBLIC",e[e.RESTRICTED=6]="RESTRICTED",e[e.USER=7]="USER",e[e.UNRECOGNIZED=-1]="UNRECOGNIZED"})(T||(T={}));var _;(function(e){e[e.UNKNOWN_SUBREDDIT_RATING=0]="UNKNOWN_SUBREDDIT_RATING",e[e.E=1]="E",e[e.M1=2]="M1",e[e.M2=3]="M2",e[e.D=4]="D",e[e.V=5]="V",e[e.X=6]="X",e[e.UNRECOGNIZED=-1]="UNRECOGNIZED"})(_||(_={}));var F;(function(e){e.Installation="installation",e.App="app"})(F||(F={}));var C;(function(e){e.COMMENT="t1_",e.ACCOUNT="t2_",e.LINK="t3_",e.MESSAGE="t4_",e.SUBREDDIT="t5_",e.AWARD="t6_"})(C||(C={}));function L(e){switch(e.fieldType){case o.STRING:return e.stringValue;case o.IMAGE:return e.stringValue;case o.PARAGRAPH:return e.stringValue;case o.NUMBER:return e.numberValue;case o.BOOLEAN:return e.boolValue;case o.SELECTION:return e.selectionValue?.values??[];default:return}}function U(e){return Object.keys(e).reduce((t,r)=>{let n=L(e[r]);return n!==void 0&&(t[r]=n),t},{})}function I(e){return e.map(t=>{switch(t.type){case"string":return P(t);case"image":return V(t);case"paragraph":return G(t);case"number":return w(t);case"select":return g(t);case"boolean":return b(t);case"group":return W(t);default:throw new Error("Unknown field type.")}})}function P(e){return{defaultValue:{fieldType:o.STRING,stringValue:e.defaultValue},disabled:e.disabled,fieldConfig:{stringConfig:{placeholder:e.placeholder}},fieldId:e.name,fieldType:o.STRING,helpText:e.helpText,label:e.label,required:e.required,isSecret:e.isSecret}}function V(e){return{disabled:e.disabled,fieldId:e.name,fieldType:o.IMAGE,helpText:e.helpText,label:e.label,required:e.required}}function G(e){return{defaultValue:{fieldType:o.PARAGRAPH,stringValue:e.defaultValue},disabled:e.disabled,fieldConfig:{paragraphConfig:{lineHeight:e.lineHeight,placeholder:e.placeholder}},fieldId:e.name,fieldType:o.PARAGRAPH,helpText:e.helpText,label:e.label,required:e.required}}function w(e){return{defaultValue:{fieldType:o.NUMBER,numberValue:e.defaultValue},disabled:e.disabled,fieldConfig:{numberConfig:{}},fieldId:e.name,fieldType:o.NUMBER,helpText:e.helpText,label:e.label,required:e.required}}function g(e){return{defaultValue:{fieldType:o.SELECTION,selectionValue:{values:e.defaultValue??[]}},disabled:e.disabled,fieldConfig:{selectionConfig:{choices:e.options,multiSelect:e.multiSelect}},fieldId:e.name,fieldType:o.SELECTION,helpText:e.helpText,label:e.label,required:e.required}}function b(e){return{defaultValue:{fieldType:o.BOOLEAN,boolValue:e.defaultValue},disabled:e.disabled,fieldId:e.name,fieldType:o.BOOLEAN,helpText:e.helpText,label:e.label}}function W(e){return{fieldId:"",fieldType:o.GROUP,fieldConfig:{groupConfig:{fields:I(e.fields)}},label:e.label,helpText:e.helpText}}var A=1,B=()=>(A++,`form.${A}`),$e=async e=>{let t={fields:[],id:B(),title:e.title,acceptLabel:e.acceptLabel,cancelLabel:e.cancelLabel,shortDescription:e.description};l(e.fields),t.fields=I(e.fields);let r=await a({showForm:{form:t},type:3});return!r||!r.formSubmitted?{action:"CANCELED"}:{action:"SUBMITTED",values:U(r.formSubmitted.results)}};function ke(e){let t;e instanceof Object?t={text:e.text,appearance:e.appearance==="success"?1:0}:t={text:e},a({showToast:{toast:t},type:4})}var s;(function(e){e[e.UNSPECIFIED=0]="UNSPECIFIED",e[e.INLINE_MODE=1]="INLINE_MODE",e[e.IMMERSIVE_MODE=2]="IMMERSIVE_MODE",e[e.UNRECOGNIZED=-1]="UNRECOGNIZED"})(s||(s={}));var v="token";var tt=()=>y(devvit.webViewMode);function rt(e,t){if(devvit.webViewMode===s.IMMERSIVE_MODE)throw Error("web view is already expanded");return S(s.IMMERSIVE_MODE,e,t)}function ot(e){if(devvit.webViewMode===s.INLINE_MODE)throw Error("web view is already inlined");return S(s.INLINE_MODE,e,void 0)}function nt(e){}function at(e){}async function S(e,t,r){if(!t.isTrusted||t.type!=="click")throw console.error("Expanded mode effect ignored due to untrusted event"),new Error("Untrusted event");if(r!=null&&!devvit.entrypoints[r])throw Error(`no entrypoint named "${r}"; all entrypoints must appear in \`devvit.json\` \`post.entrypoints\``);let n;if(r){let p=new URL(devvit.entrypoints[r]);p.searchParams.set(v,devvit.token),n=`${p}`}await a({type:9,immersiveMode:{entryUrl:n,immersiveMode:e}})}function y(e){switch(e){case s.IMMERSIVE_MODE:return"expanded";case s.INLINE_MODE:case s.UNRECOGNIZED:case s.UNSPECIFIED:case void 0:return"inline";default:throw Error(`${e} not a WebViewImmersiveMode`)}}export{nt as addWebViewModeListener,te as canRunAsUser,j as context,ot as exitExpandedMode,pe as getShareData,tt as getWebViewMode,J as navigateTo,at as removeWebViewModeListener,rt as requestExpandedMode,$e as showForm,ie as showShareSheet,ke as showToast};
2
2
  //# sourceMappingURL=client.min.js.map
package/client.min.js.map CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
- "sources": ["../src/clientContext.ts", "../../protos/dist/json/devvit/ui/effects/v1alpha/effect.js", "../../protos/dist/json/devvit/ui/effects/web_view/v1alpha/post_message.js", "../../shared-types/dist/client/emit-effect.js", "../src/effects/navigate-to.ts", "../../protos/dist/json/reddit/devvit/app_permission/v1/app_permission.js", "../src/effects/run-as-user.ts", "../../shared-types/dist/constants.js", "../src/effects/share.ts", "../src/effects/helpers/assert-valid-form-fields.ts", "../src/effects/helpers/get-form-values.ts", "../src/effects/helpers/transform-form.ts", "../src/effects/show-form.ts", "../src/effects/show-toast.ts", "../../protos/dist/json/devvit/ui/effects/web_view/v1alpha/immersive_mode.js", "../../shared-types/dist/webbit.js", "../src/effects/web-view-mode.ts"],
4
- "sourcesContent": ["import type { Context } from '@devvit/shared-types/client/client-context.js';\n\n// Use nullish coalescing for local development.\nexport const context: Context = globalThis.devvit?.context!;\n", "/**\n * #effect.ts\n *\n * Code generated by ts-proto. DO NOT EDIT.\n * @packageDocumentation\n */\n/* eslint-disable */\nexport var EffectType;\n(function (EffectType) {\n /** EFFECT_REALTIME_SUB - Notify client to synchronize its realtime subscriptions */\n EffectType[EffectType[\"EFFECT_REALTIME_SUB\"] = 0] = \"EFFECT_REALTIME_SUB\";\n /** EFFECT_RERENDER_UI - Trigger a re-render for apps that have visible UI */\n EffectType[EffectType[\"EFFECT_RERENDER_UI\"] = 1] = \"EFFECT_RERENDER_UI\";\n /**\n * EFFECT_RELOAD_PART - Notify the client that parts of a subreddit, post, or comment should be reloaded\n *\n * @deprecated\n */\n EffectType[EffectType[\"EFFECT_RELOAD_PART\"] = 2] = \"EFFECT_RELOAD_PART\";\n /** EFFECT_SHOW_FORM - Display a user input form */\n EffectType[EffectType[\"EFFECT_SHOW_FORM\"] = 3] = \"EFFECT_SHOW_FORM\";\n /** EFFECT_SHOW_TOAST - Display a transient toast message */\n EffectType[EffectType[\"EFFECT_SHOW_TOAST\"] = 4] = \"EFFECT_SHOW_TOAST\";\n /** EFFECT_NAVIGATE_TO_URL - Notify the client to navigate to a URL */\n EffectType[EffectType[\"EFFECT_NAVIGATE_TO_URL\"] = 5] = \"EFFECT_NAVIGATE_TO_URL\";\n /** EFFECT_SET_INTERVALS - This updates the list of active timers. */\n EffectType[EffectType[\"EFFECT_SET_INTERVALS\"] = 7] = \"EFFECT_SET_INTERVALS\";\n /** EFFECT_CREATE_ORDER - This starts a purchase flow */\n EffectType[EffectType[\"EFFECT_CREATE_ORDER\"] = 8] = \"EFFECT_CREATE_ORDER\";\n /** EFFECT_WEB_VIEW - Control and communicate with WebViews */\n EffectType[EffectType[\"EFFECT_WEB_VIEW\"] = 9] = \"EFFECT_WEB_VIEW\";\n /** EFFECT_CAN_RUN_AS_USER - Check if the app can execute some actions as the user */\n EffectType[EffectType[\"EFFECT_CAN_RUN_AS_USER\"] = 11] = \"EFFECT_CAN_RUN_AS_USER\";\n /** EFFECT_TELEMETRY - Statistical data event for analytics. */\n EffectType[EffectType[\"EFFECT_TELEMETRY\"] = 12] = \"EFFECT_TELEMETRY\";\n /** EFFECT_UPDATE_REQUEST_CONTEXT - Request an updated signed request context */\n EffectType[EffectType[\"EFFECT_UPDATE_REQUEST_CONTEXT\"] = 13] = \"EFFECT_UPDATE_REQUEST_CONTEXT\";\n EffectType[EffectType[\"UNRECOGNIZED\"] = -1] = \"UNRECOGNIZED\";\n})(EffectType || (EffectType = {}));\n", "/**\n * #post_message.ts\n *\n * Code generated by ts-proto. DO NOT EDIT.\n * @packageDocumentation\n */\n/* eslint-disable */\n/**\n * Blocks only.\n *\n * @deprecated\n */\nexport var WebViewInternalMessageScope;\n(function (WebViewInternalMessageScope) {\n /** CLIENT - Message is intended for the client only */\n WebViewInternalMessageScope[WebViewInternalMessageScope[\"CLIENT\"] = 0] = \"CLIENT\";\n WebViewInternalMessageScope[WebViewInternalMessageScope[\"UNRECOGNIZED\"] = -1] = \"UNRECOGNIZED\";\n})(WebViewInternalMessageScope || (WebViewInternalMessageScope = {}));\n", "import { EffectType } from '@devvit/protos/json/devvit/ui/effects/v1alpha/effect.js';\nimport { WebViewInternalMessageScope, } from '@devvit/protos/json/devvit/ui/effects/web_view/v1alpha/post_message.js';\n/** `WebViewInternalMessage.type`. */\nexport const webViewInternalMessageType = 'devvit-internal';\nconst EFFECTS_WITH_RESPONSE = {\n [EffectType.EFFECT_SHOW_FORM]: true,\n [EffectType.EFFECT_CAN_RUN_AS_USER]: true,\n [EffectType.EFFECT_CREATE_ORDER]: true,\n};\n/**\n * Emits an effect to the parent window and handles the response if required.\n *\n * @param effect - The effect to be emitted to the parent window\n * @returns A promise that resolves with the response message for effects that require\n * a response, or resolves immediately with undefined for effects that don't\n *\n * @description\n * This function handles two types of effects:\n * 1. Effects that require a response: Creates a unique ID, sets up a message listener,\n * and resolves the promise when a matching response is received\n * 2. Effects that don't require a response: Posts the message and resolves immediately\n */\nexport const emitEffect = (effect) => {\n return new Promise((resolve) => {\n const message = {\n ...effect,\n realtimeEffect: effect.realtime, // to-do: remove deprecated field.\n scope: WebViewInternalMessageScope.CLIENT,\n type: webViewInternalMessageType,\n };\n // For temporary backward compatibility, we set both `message.effect_type` above, and `effect` below\n // Once mobile clients are updated to consume the strongly typed properties above, we can remove this block\n // *Do not* add new effects here, use the strongly typed properties above\n if (effect.showToast ||\n effect.navigateToUrl ||\n effect.showForm ||\n effect.type === EffectType.EFFECT_CAN_RUN_AS_USER) {\n message.effect = effect;\n }\n // Only set message id and add a listener for effects which require a response\n if (EFFECTS_WITH_RESPONSE[effect.type]) {\n const id = crypto.randomUUID();\n message.id = id;\n const handleEffect = (event) => {\n if (event.data?.type === 'devvit-message' && event.data?.data?.id === id) {\n resolve(event.data.data);\n removeEventListener('message', handleEffect);\n }\n };\n addEventListener('message', handleEffect);\n // Post message to the parent window, handled by client web view component\n parent.postMessage(message, '*');\n }\n else {\n parent.postMessage(message, '*');\n // Resolve immediately for effects that don't expect a response.\n resolve(undefined);\n }\n });\n};\n", "import type { EffectType } from '@devvit/protos/json/devvit/ui/effects/v1alpha/effect.js';\nimport { emitEffect } from '@devvit/shared-types/client/emit-effect.js';\n\n/**\n * Navigates to a URL, subreddit, post, comment, or user.\n *\n * @param thingOrUrl - The URL, subreddit, post, comment, or user to navigate to\n */\nexport function navigateTo(thingOrUrl: string | { readonly url: string }): void {\n const inputUrl = typeof thingOrUrl === 'string' ? thingOrUrl : thingOrUrl.url;\n let normalizedUrl: string;\n try {\n normalizedUrl = new URL(inputUrl).toString();\n } catch {\n throw new TypeError(`Invalid URL: ${inputUrl}`);\n }\n void emitEffect({\n navigateToUrl: {\n url: normalizedUrl,\n },\n type: 5 satisfies EffectType.EFFECT_NAVIGATE_TO_URL,\n });\n}\n", "/**\n * #app_permission.ts\n *\n * Code generated by ts-proto. DO NOT EDIT.\n * @packageDocumentation\n */\n/* eslint-disable */\n/** This enum is used to represent the consent status of an app permission. */\nexport var ConsentStatus;\n(function (ConsentStatus) {\n /** CONSENT_STATUS_UNKNOWN - The consent status is unknown, which means it has not been set or is not applicable. */\n ConsentStatus[ConsentStatus[\"CONSENT_STATUS_UNKNOWN\"] = 0] = \"CONSENT_STATUS_UNKNOWN\";\n /** REVOKED - The user has explicitly denied consent for the app permissions. */\n ConsentStatus[ConsentStatus[\"REVOKED\"] = 1] = \"REVOKED\";\n /** GRANTED - The user has granted consent for the app permissions. */\n ConsentStatus[ConsentStatus[\"GRANTED\"] = 2] = \"GRANTED\";\n ConsentStatus[ConsentStatus[\"UNRECOGNIZED\"] = -1] = \"UNRECOGNIZED\";\n})(ConsentStatus || (ConsentStatus = {}));\n/** This enum is used to represent the scopes of permissions that can be granted to an app. */\nexport var Scope;\n(function (Scope) {\n /** SCOPE_UNKNOWN - The scope is unknown, which means it has not been set or is not applicable. */\n Scope[Scope[\"SCOPE_UNKNOWN\"] = 0] = \"SCOPE_UNKNOWN\";\n /** SUBMIT_POST - Allows the app to submit posts on behalf of the user. */\n Scope[Scope[\"SUBMIT_POST\"] = 1] = \"SUBMIT_POST\";\n /** SUBMIT_COMMENT - Allows the app to submit comments on behalf of the user. */\n Scope[Scope[\"SUBMIT_COMMENT\"] = 2] = \"SUBMIT_COMMENT\";\n /** SUBSCRIBE_TO_SUBREDDIT - Allows the app to subscribe the user to a subreddit. */\n Scope[Scope[\"SUBSCRIBE_TO_SUBREDDIT\"] = 3] = \"SUBSCRIBE_TO_SUBREDDIT\";\n Scope[Scope[\"UNRECOGNIZED\"] = -1] = \"UNRECOGNIZED\";\n})(Scope || (Scope = {}));\n", "import type { EffectType } from '@devvit/protos/json/devvit/ui/effects/v1alpha/effect.js';\nimport { ConsentStatus } from '@devvit/protos/json/reddit/devvit/app_permission/v1/app_permission.js';\nimport { emitEffect } from '@devvit/shared-types/client/emit-effect.js';\n\n/**\n * This method is used to check if the app has been granted all the requested scopes.\n *\n * @experimental\n * @returns true if the app has been granted all the requested scopes, false otherwise.\n */\nexport const canRunAsUser = async (): Promise<boolean> => {\n const appPermissionState = devvit.appPermissionState;\n\n if (!appPermissionState) {\n // Note: The app permission state will be missing when the app runs on clients that haven't implemented this feature yet.\n // \"true\" is the correct value for the time being, until we have all clients supporting this feature.\n return true;\n }\n\n if (appPermissionState.requestedScopes.length === 0) {\n // the app does not have permission to do anything as the user\n return false;\n }\n\n switch (appPermissionState.consentStatus) {\n case ConsentStatus.REVOKED:\n return false;\n case ConsentStatus.GRANTED:\n // If the app has been granted all the requested scopes, return true\n if (\n appPermissionState.requestedScopes.every((scope) =>\n appPermissionState.grantedScopes.includes(scope)\n )\n ) {\n return true;\n }\n // Otherwise, the sets of scopes do not overlap we emit the effect to request the scopes; continue\n break;\n case ConsentStatus.CONSENT_STATUS_UNKNOWN:\n case ConsentStatus.UNRECOGNIZED:\n // We don't know the status, so we'll have to ask.\n break;\n default: {\n appPermissionState.consentStatus satisfies never;\n break;\n }\n }\n\n const response = await emitEffect({\n canRunAsUser: {\n postId: devvit.context.postId,\n appSlug: devvit.context.appName,\n subredditId: devvit.context.subredditId,\n },\n type: 11 satisfies EffectType.EFFECT_CAN_RUN_AS_USER,\n });\n\n return response?.consentStatus?.consentStatus === ConsentStatus.GRANTED;\n};\n", "// to-do: move to service + CLI package.\n// Do not use in @devvit/public-api. Protos not in externalized @devvit/protos\n// barrel.\nexport const ACTOR_SRC_DIR = 'src';\nexport const ACTOR_SRC_PRIMARY_NAME = 'main';\n/** payments stuff. */\nexport const PRODUCTS_JSON_FILE = 'products.json';\n/**\n * The hashing algorithm used - pass this to `createHash`\n */\nexport const ASSET_HASHING_ALGO = 'sha256';\n/**\n * The max number of subscribers allowed in a test subreddit (ie where a user can install an uploaded, private app\n * Determines if a PRIVATE (unpublished) version of an app can be installed or playtested\n *\n * TODO: turn this off before we go live - see DX-1336\n * */\nexport const MAX_ALLOWED_SUBSCRIBER_COUNT = 200;\n/**\n * How many assets to upload at once. Sending too many at once can cause the\n * server to become overwhelmed and start erroring clients out.\n * @type {number}\n */\nexport const ASSET_UPLOAD_BATCH_SIZE = 10;\nexport const REDDIT_OAUTH_COPY_PASTE_CLIENT_ID = 'TWTsqXa53CexlrYGBWaesQ';\n/** All server endpoints must start with this prefix. */\nexport const apiPathPrefix = '/api/';\n/** All unexposed APIs must start with this prefix. */\nexport const internalPathPrefix = '/internal/';\n/** When an app's icon is present in the media assets list, it'll be with this special name. */\nexport const ICON_FILE_PATH = '$devvit_icon.png'; // Uses special characters intentionally to avoid conflicts with real asset paths\nexport const REDDIT_DISCORD_INVITE_URL = 'https://discord.gg/Cd43ExtEFS';\nexport const REDDIT_SUBREDDIT_URL = 'https://www.reddit.com/r/devvit';\n", "import type { EffectType } from '@devvit/protos/json/devvit/ui/effects/v1alpha/effect.js';\nimport { emitEffect } from '@devvit/shared-types/client/emit-effect.js';\nimport { maxShareParamUserDataChars } from '@devvit/shared-types/client/share.js';\nimport { ICON_FILE_PATH } from '@devvit/shared-types/constants.js';\n\nexport type ShareSheetOpts = {\n /** Data to share. Must be 1024 characters or less. */\n data?: string | undefined;\n /** Title of share sheet. */\n title?: string | undefined;\n /** Body text of share sheet. */\n text?: string | undefined;\n};\n\n// to-do: unit test.\n// to-do: move to web view scripts.\n/** Show the native share sheet or copy to clipboard depending on device. */\nexport async function showShareSheet(opts: Readonly<ShareSheetOpts>): Promise<void> {\n if (opts.data && opts.data.length > maxShareParamUserDataChars)\n throw Error(\n `data must be <= ${maxShareParamUserDataChars} characters but was ${opts.data.length} characters`\n );\n\n const iconURL = `${new URL(ICON_FILE_PATH, location.origin)}`;\n let iconRsp;\n try {\n iconRsp = await fetch(iconURL, { method: 'HEAD' });\n } catch {\n //\n }\n\n await emitEffect({\n type: 9 satisfies EffectType.EFFECT_WEB_VIEW,\n share: {\n appIconUri: iconRsp?.ok ? iconURL : undefined,\n userData: opts.data,\n text: opts.text,\n title: opts.title,\n },\n });\n}\n\nexport function getShareData(): string | undefined {\n return devvit.share?.userData;\n}\n", "import type { FormField, SettingScope } from './form-types.js';\n\n/**\n * Make sure that the form fields have unique names.\n *\n * This is a carbon copy of the assertValidFormFields function in the public-api package\n * We copy it here so that @devvit/client does not need to depend on public-api\n * Any changes to this function should be reflected in the public-api version\n */\nexport function assertValidFormFields(\n fields: readonly FormField[],\n seenNames: Set<string> = new Set()\n): void {\n for (const field of fields) {\n if (field.type === 'group') {\n assertValidFormFields(field.fields, seenNames);\n continue;\n }\n\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n const fieldName = (field as any).name as string;\n\n if (seenNames.has(fieldName)) {\n throw new Error(`Duplicate field name: ${fieldName}`);\n }\n\n seenNames.add(fieldName);\n }\n assertAppSecretsOnly(fields);\n}\n\nexport function assertAppSecretsOnly(fields: readonly FormField[]): void {\n for (const field of fields) {\n if (field.type === 'string' && field.isSecret && field.scope !== ('app' as SettingScope.App)) {\n throw `Invalid setting: only app settings can be secrets. Add \"scope: SettingScope.App\" to field \"${field.name}\"`;\n }\n }\n}\n", "import type { FormFieldType, FormFieldValue } from '@devvit/protos';\n\nimport type { FormValues } from './form-types.js';\n\nfunction flattenFormFieldValue(\n value: FormFieldValue\n): undefined | string | string[] | number | boolean {\n switch (value.fieldType) {\n case 0 satisfies FormFieldType.STRING:\n return value.stringValue;\n case 7 satisfies FormFieldType.IMAGE:\n // the string value is the URL\n return value.stringValue;\n case 1 satisfies FormFieldType.PARAGRAPH:\n return value.stringValue;\n case 2 satisfies FormFieldType.NUMBER:\n return value.numberValue;\n case 3 satisfies FormFieldType.BOOLEAN:\n return value.boolValue;\n case 5 satisfies FormFieldType.SELECTION:\n return value.selectionValue?.values ?? [];\n default:\n return undefined;\n }\n}\n\n// This is a carbon copy of the transformFormFields function in the public-api package\n// We copy it here so that @devvit/client does not need to depend on public-api\n// Any changes to this function should be reflected in the public-api version\nexport function getFormValues(results: { [key: string]: FormFieldValue }): FormValues {\n return Object.keys(results).reduce((acc, key) => {\n const val = flattenFormFieldValue(results[key]);\n if (val !== undefined) acc[key] = val;\n return acc;\n }, {} as FormValues);\n}\n", "import type { FormField as FormFieldProto, FormFieldType } from '@devvit/protos';\n\nimport type {\n BooleanField,\n FormField,\n FormFieldGroup,\n ImageField,\n NumberField,\n ParagraphField,\n SelectField,\n StringField,\n} from './form-types.js';\n\n// This is a carbon copy of the transformFormFields function in the public-api package\n// We copy it here so that @devvit/client does not need to depend on public-api\n// Any changes to this function should be reflected in the public-api version\nexport function transformFormFields(fields: readonly FormField[]): FormFieldProto[] {\n return fields.map((field) => {\n switch (field.type) {\n case 'string':\n return transformStringField(field);\n case 'image':\n return transformImageField(field);\n case 'paragraph':\n return transformParagraphField(field);\n case 'number':\n return transformNumberField(field);\n case 'select':\n return transformSelectField(field);\n case 'boolean':\n return transformBooleanField(field);\n case 'group':\n return transformGroupField(field);\n default:\n throw new Error('Unknown field type.');\n }\n });\n}\n\nfunction transformStringField(field: StringField): FormFieldProto {\n return {\n defaultValue: {\n fieldType: 0 satisfies FormFieldType.STRING,\n stringValue: field.defaultValue,\n },\n disabled: field.disabled,\n fieldConfig: {\n stringConfig: {\n placeholder: field.placeholder,\n },\n },\n fieldId: field.name,\n fieldType: 0 satisfies FormFieldType.STRING,\n helpText: field.helpText,\n label: field.label,\n required: field.required,\n isSecret: field.isSecret,\n };\n}\n\nfunction transformImageField(field: ImageField): FormFieldProto {\n return {\n disabled: field.disabled,\n fieldId: field.name,\n fieldType: 7 satisfies FormFieldType.IMAGE,\n helpText: field.helpText,\n label: field.label,\n required: field.required,\n };\n}\n\nfunction transformParagraphField(field: ParagraphField): FormFieldProto {\n return {\n defaultValue: {\n fieldType: 1 satisfies FormFieldType.PARAGRAPH,\n stringValue: field.defaultValue,\n },\n disabled: field.disabled,\n fieldConfig: {\n paragraphConfig: {\n lineHeight: field.lineHeight,\n placeholder: field.placeholder,\n },\n },\n fieldId: field.name,\n fieldType: 1 satisfies FormFieldType.PARAGRAPH,\n helpText: field.helpText,\n label: field.label,\n required: field.required,\n };\n}\n\nfunction transformNumberField(field: NumberField): FormFieldProto {\n return {\n defaultValue: {\n fieldType: 2 satisfies FormFieldType.NUMBER,\n numberValue: field.defaultValue,\n },\n disabled: field.disabled,\n fieldConfig: {\n numberConfig: {},\n },\n fieldId: field.name,\n fieldType: 2 satisfies FormFieldType.NUMBER,\n helpText: field.helpText,\n label: field.label,\n required: field.required,\n };\n}\n\nfunction transformSelectField(field: SelectField): FormFieldProto {\n return {\n defaultValue: {\n fieldType: 5 satisfies FormFieldType.SELECTION,\n selectionValue: {\n values: field.defaultValue ?? [],\n },\n },\n disabled: field.disabled,\n fieldConfig: {\n selectionConfig: {\n choices: field.options,\n multiSelect: field.multiSelect,\n },\n },\n fieldId: field.name,\n fieldType: 5 satisfies FormFieldType.SELECTION,\n helpText: field.helpText,\n label: field.label,\n required: field.required,\n };\n}\n\nfunction transformBooleanField(field: BooleanField): FormFieldProto {\n return {\n defaultValue: {\n fieldType: 3 satisfies FormFieldType.BOOLEAN,\n boolValue: field.defaultValue,\n },\n disabled: field.disabled,\n fieldId: field.name,\n fieldType: 3 satisfies FormFieldType.BOOLEAN,\n helpText: field.helpText,\n label: field.label,\n };\n}\n\nfunction transformGroupField(field: FormFieldGroup): FormFieldProto {\n return {\n fieldId: '',\n fieldType: 6 satisfies FormFieldType.GROUP,\n fieldConfig: {\n groupConfig: {\n fields: transformFormFields(field.fields),\n },\n },\n label: field.label,\n helpText: field.helpText,\n };\n}\n", "import type { Form as FormProto } from '@devvit/protos';\nimport type { EffectType } from '@devvit/protos/json/devvit/ui/effects/v1alpha/effect.js';\nimport { emitEffect } from '@devvit/shared-types/client/emit-effect.js';\nimport type { FormKey } from '@devvit/shared-types/useForm.js';\n\nimport { assertValidFormFields } from './helpers/assert-valid-form-fields.js';\nimport type { Form, FormToFormValues } from './helpers/form-types.js';\nimport type { FormEffectResponse } from './helpers/form-types.js';\nimport { getFormValues } from './helpers/get-form-values.js';\nimport { transformFormFields } from './helpers/transform-form.js';\n\nlet _formKey = 1;\n\nconst getNextFormKey = (): FormKey => {\n _formKey++;\n return `form.${_formKey}`;\n};\n\n/**\n * Opens a form in a modal.\n * Returns a promise that resolves with the form submission results.\n * The form can be submitted or canceled by the user.\n *\n * @param formDefinition - The form configuration\n * @returns A promise that resolves to either:\n * - An object with `action: FormAction.SUBMITTED` and the submitted form values\n * - An object with `action: FormAction.CANCELED` if the user canceled the form\n * @throws Will throw if the form fields are invalid\n */\nexport const showForm = async <const T extends Form>(\n formDefinition: T\n): Promise<FormEffectResponse<FormToFormValues<T>>> => {\n const form: FormProto = {\n fields: [],\n id: getNextFormKey(),\n title: formDefinition.title,\n acceptLabel: formDefinition.acceptLabel,\n cancelLabel: formDefinition.cancelLabel,\n shortDescription: formDefinition.description,\n };\n\n assertValidFormFields(formDefinition.fields);\n form.fields = transformFormFields(formDefinition.fields);\n\n const response = await emitEffect({\n showForm: {\n form,\n },\n type: 3 satisfies EffectType.EFFECT_SHOW_FORM,\n });\n\n if (!response || !response.formSubmitted) {\n return {\n action: 'CANCELED',\n };\n }\n\n const formResults = getFormValues(response.formSubmitted.results);\n\n return {\n action: 'SUBMITTED',\n values: formResults as FormToFormValues<T>,\n };\n};\n", "import type { EffectType } from '@devvit/protos/json/devvit/ui/effects/v1alpha/effect.js';\nimport type {\n Toast as ToastProto,\n ToastAppearance,\n} from '@devvit/protos/json/devvit/ui/toast/toast.js';\nimport type { Toast } from '@devvit/shared';\nimport { emitEffect } from '@devvit/shared-types/client/emit-effect.js';\n\n/**\n * Shows a toast message.\n *\n * @param textOrToast - The text or toast object to display\n */\nexport function showToast(text: string): void;\nexport function showToast(toast: Toast): void;\nexport function showToast(textOrToast: string | Toast): void {\n let toast: ToastProto;\n\n if (textOrToast instanceof Object) {\n toast = {\n text: textOrToast.text,\n appearance:\n textOrToast.appearance === 'success'\n ? (1 satisfies ToastAppearance.SUCCESS)\n : (0 satisfies ToastAppearance.NEUTRAL),\n };\n } else {\n toast = {\n text: textOrToast,\n };\n }\n\n void emitEffect({\n showToast: {\n toast,\n },\n type: 4 satisfies EffectType.EFFECT_SHOW_TOAST,\n });\n}\n", "/**\n * #immersive_mode.ts\n *\n * Code generated by ts-proto. DO NOT EDIT.\n * @packageDocumentation\n */\n/* eslint-disable */\n/** How a Devvit app is presented. */\nexport var WebViewImmersiveMode;\n(function (WebViewImmersiveMode) {\n WebViewImmersiveMode[WebViewImmersiveMode[\"UNSPECIFIED\"] = 0] = \"UNSPECIFIED\";\n /**\n * INLINE_MODE - Conventional post presentation. May appear adjacent other posts in a feed\n * or with comments.\n */\n WebViewImmersiveMode[WebViewImmersiveMode[\"INLINE_MODE\"] = 1] = \"INLINE_MODE\";\n /**\n * IMMERSIVE_MODE - Large modal expanded presentation. Appears popped out from the rest of the\n * Reddit experience which is disabled.\n */\n WebViewImmersiveMode[WebViewImmersiveMode[\"IMMERSIVE_MODE\"] = 2] = \"IMMERSIVE_MODE\";\n WebViewImmersiveMode[WebViewImmersiveMode[\"UNRECOGNIZED\"] = -1] = \"UNRECOGNIZED\";\n})(WebViewImmersiveMode || (WebViewImmersiveMode = {}));\n", "export const noWebbitToken = `0.0.0`;\n/**\n * `RequestContext` token query parameter name on `DevvitPost.entrypointUrl`.\n */\nexport const tokenParam = 'token';\n", "import type { EffectType } from '@devvit/protos/json/devvit/ui/effects/v1alpha/effect.js';\nimport { WebViewImmersiveMode } from '@devvit/protos/json/devvit/ui/effects/web_view/v1alpha/immersive_mode.js';\nimport { emitEffect } from '@devvit/shared-types/client/emit-effect.js';\nimport { tokenParam } from '@devvit/shared-types/webbit.js';\n\n/**\n * The presentation mode of the web view.\n * 'inline' The web view is displayed inline within a feed or post detail page\n * 'expanded' The web view is displayed in a larger modal presentation\n * @experimental\n */\nexport type WebViewMode = 'inline' | 'expanded';\n\n/**\n * A listener that is called when the web view mode changes.\n * @param mode The new mode, either 'inline' or 'expanded'.\n * @experimental\n */\nexport type WebViewModeListener = (mode: WebViewMode) => void;\n\n/**\n * Represents the current web view mode state for the application.\n *\n * @experimental\n */\nexport const getWebViewMode = (): WebViewMode => webViewMode(devvit.webViewMode);\n\n/**\n * Requests expanded mode for the web view.\n * This will display the web view in a larger modal presentation.\n *\n * @param event The gesture that triggered the request, must be a trusted event.\n * @param entry The destination URI name. Eg, `'splash'` or `'default'`. Entry\n * names are the `devvit.json` `post.entrypoints` keys. Passing the\n * same entrypoint as currently loaded causes a reload.\n * @returns A promise that resolves request has been received.\n * @throws When already expanded.\n *\n * @experimental\n * @example\n * ```ts\n * button.addEventListener('click', async (event) => {\n * await requestExpandedMode(event);\n * });\n * ```\n */\nexport function requestExpandedMode(event: MouseEvent, entry: string): Promise<void> {\n if (devvit.webViewMode === WebViewImmersiveMode.IMMERSIVE_MODE)\n throw Error('web view is already expanded');\n return emitModeEffect(WebViewImmersiveMode.IMMERSIVE_MODE, event, entry);\n}\n\n/**\n * Exits expanded mode for the web view.\n * This will display the web view in an inline presentation.\n *\n * @param event The event that triggered the request, must be a trusted event.\n * @returns A promise that resolves request has been received.\n * @throws When already inlined.\n *\n * @experimental\n * @example\n * ```ts\n * button.addEventListener('click', async (event) => {\n * await exitExpandedMode(event);\n * });\n * ```\n */\nexport function exitExpandedMode(event: MouseEvent): Promise<void> {\n if (devvit.webViewMode === WebViewImmersiveMode.INLINE_MODE)\n throw Error('web view is already inlined');\n return emitModeEffect(WebViewImmersiveMode.INLINE_MODE, event, undefined);\n}\n\n/**\n * @deprecated This API is deprecated and will be removed in a future release.\n * use window.addEventListener(\"focus\", () => { }) to receive notifications\n * when the web view mode changes back to inline.\n * Adds a listener that is called when the web view mode changes. Initial mode\n * is not reported. Web views in the process of destruction may not receive a\n * mode change event.\n *\n * @param callback The callback to be called when the mode changes.\n * @experimental\n */\nexport function addWebViewModeListener(_: WebViewModeListener): void {}\n\n/**\n * @deprecated This API is deprecated and will be removed in a future release.\n * Removes a listener that was previously added with `addWebViewModeListener`.\n *\n * @param callback The callback to be removed.\n * @experimental\n */\nexport function removeWebViewModeListener(_: WebViewModeListener): void {}\n\nasync function emitModeEffect(\n mode: WebViewImmersiveMode,\n event: Event,\n entry: string | undefined\n): Promise<void> {\n if (!event.isTrusted || event.type !== 'click') {\n console.error('Expanded mode effect ignored due to untrusted event');\n throw new Error('Untrusted event');\n }\n\n if (entry != null && !devvit.entrypoints[entry])\n throw Error(\n `no entrypoint named \"${entry}\"; all entrypoints must appear in \\`devvit.json\\` \\`post.entrypoints\\``\n );\n\n let entryUrl;\n if (entry) {\n // Only `DevvitPost.entrypointUrl` has a token.\n const url = new URL(devvit.entrypoints[entry]);\n url.searchParams.set(tokenParam, devvit.token);\n entryUrl = `${url}`;\n }\n\n const type = 9 satisfies EffectType.EFFECT_WEB_VIEW;\n await emitEffect({\n type,\n immersiveMode: { entryUrl, immersiveMode: mode },\n });\n}\n\nfunction webViewMode(mode: WebViewImmersiveMode | undefined): WebViewMode {\n switch (mode) {\n case WebViewImmersiveMode.IMMERSIVE_MODE:\n return 'expanded';\n case WebViewImmersiveMode.INLINE_MODE:\n case WebViewImmersiveMode.UNRECOGNIZED:\n case WebViewImmersiveMode.UNSPECIFIED:\n case undefined:\n return 'inline';\n default:\n mode satisfies never;\n throw Error(`${mode} not a WebViewImmersiveMode`);\n }\n}\n"],
5
- "mappings": "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",
6
- "names": ["context", "EffectType", "WebViewInternalMessageScope", "webViewInternalMessageType", "EFFECTS_WITH_RESPONSE", "EffectType", "emitEffect", "effect", "resolve", "message", "WebViewInternalMessageScope", "id", "handleEffect", "event", "navigateTo", "thingOrUrl", "inputUrl", "normalizedUrl", "emitEffect", "ConsentStatus", "Scope", "canRunAsUser", "appPermissionState", "ConsentStatus", "scope", "emitEffect", "ICON_FILE_PATH", "showShareSheet", "opts", "iconURL", "ICON_FILE_PATH", "iconRsp", "emitEffect", "getShareData", "assertValidFormFields", "fields", "seenNames", "field", "fieldName", "assertAppSecretsOnly", "flattenFormFieldValue", "value", "getFormValues", "results", "acc", "key", "val", "transformFormFields", "fields", "field", "transformStringField", "transformImageField", "transformParagraphField", "transformNumberField", "transformSelectField", "transformBooleanField", "transformGroupField", "_formKey", "getNextFormKey", "showForm", "formDefinition", "form", "assertValidFormFields", "transformFormFields", "response", "emitEffect", "getFormValues", "showToast", "textOrToast", "toast", "emitEffect", "WebViewImmersiveMode", "tokenParam", "getWebViewMode", "webViewMode", "requestExpandedMode", "event", "entry", "WebViewImmersiveMode", "emitModeEffect", "exitExpandedMode", "addWebViewModeListener", "_", "removeWebViewModeListener", "mode", "entryUrl", "url", "tokenParam", "emitEffect"]
3
+ "sources": ["../src/clientContext.ts", "../../protos/dist/json/devvit/ui/effects/v1alpha/effect.js", "../../protos/dist/json/devvit/ui/effects/web_view/v1alpha/post_message.js", "../../shared-types/dist/client/emit-effect.js", "../src/effects/navigate-to.ts", "../../protos/dist/json/reddit/devvit/app_permission/v1/app_permission.js", "../src/effects/run-as-user.ts", "../../shared-types/dist/constants.js", "../src/effects/share.ts", "../src/effects/helpers/assert-valid-form-fields.ts", "../../protos/dist/json/devvit/ui/form_builder/v1alpha/type.js", "../../protos/dist/json/devvit/events/v1alpha/events.js", "../../protos/dist/json/devvit/reddit/v2alpha/postv2.js", "../../protos/dist/json/devvit/reddit/v2alpha/subredditv2.js", "../../shared-types/dist/shared/form.js", "../../shared-types/dist/tid.js", "../src/effects/helpers/get-form-values.ts", "../src/effects/helpers/transform-form.ts", "../src/effects/show-form.ts", "../src/effects/show-toast.ts", "../../protos/dist/json/devvit/ui/effects/web_view/v1alpha/immersive_mode.js", "../../shared-types/dist/webbit.js", "../src/effects/web-view-mode.ts"],
4
+ "sourcesContent": ["import type { Context } from '@devvit/shared-types/client/client-context.js';\n\n// Use nullish coalescing for local development.\nexport const context: Context = globalThis.devvit?.context!;\n", "/**\n * #effect.ts\n *\n * Code generated by ts-proto. DO NOT EDIT.\n * @packageDocumentation\n */\n/* eslint-disable */\nexport var EffectType;\n(function (EffectType) {\n /** EFFECT_REALTIME_SUB - Notify client to synchronize its realtime subscriptions */\n EffectType[EffectType[\"EFFECT_REALTIME_SUB\"] = 0] = \"EFFECT_REALTIME_SUB\";\n /** EFFECT_RERENDER_UI - Trigger a re-render for apps that have visible UI */\n EffectType[EffectType[\"EFFECT_RERENDER_UI\"] = 1] = \"EFFECT_RERENDER_UI\";\n /**\n * EFFECT_RELOAD_PART - Notify the client that parts of a subreddit, post, or comment should be reloaded\n *\n * @deprecated\n */\n EffectType[EffectType[\"EFFECT_RELOAD_PART\"] = 2] = \"EFFECT_RELOAD_PART\";\n /** EFFECT_SHOW_FORM - Display a user input form */\n EffectType[EffectType[\"EFFECT_SHOW_FORM\"] = 3] = \"EFFECT_SHOW_FORM\";\n /** EFFECT_SHOW_TOAST - Display a transient toast message */\n EffectType[EffectType[\"EFFECT_SHOW_TOAST\"] = 4] = \"EFFECT_SHOW_TOAST\";\n /** EFFECT_NAVIGATE_TO_URL - Notify the client to navigate to a URL */\n EffectType[EffectType[\"EFFECT_NAVIGATE_TO_URL\"] = 5] = \"EFFECT_NAVIGATE_TO_URL\";\n /** EFFECT_SET_INTERVALS - This updates the list of active timers. */\n EffectType[EffectType[\"EFFECT_SET_INTERVALS\"] = 7] = \"EFFECT_SET_INTERVALS\";\n /** EFFECT_CREATE_ORDER - This starts a purchase flow */\n EffectType[EffectType[\"EFFECT_CREATE_ORDER\"] = 8] = \"EFFECT_CREATE_ORDER\";\n /** EFFECT_WEB_VIEW - Control and communicate with WebViews */\n EffectType[EffectType[\"EFFECT_WEB_VIEW\"] = 9] = \"EFFECT_WEB_VIEW\";\n /** EFFECT_CAN_RUN_AS_USER - Check if the app can execute some actions as the user */\n EffectType[EffectType[\"EFFECT_CAN_RUN_AS_USER\"] = 11] = \"EFFECT_CAN_RUN_AS_USER\";\n /** EFFECT_TELEMETRY - Statistical data event for analytics. */\n EffectType[EffectType[\"EFFECT_TELEMETRY\"] = 12] = \"EFFECT_TELEMETRY\";\n /** EFFECT_UPDATE_REQUEST_CONTEXT - Request an updated signed request context */\n EffectType[EffectType[\"EFFECT_UPDATE_REQUEST_CONTEXT\"] = 13] = \"EFFECT_UPDATE_REQUEST_CONTEXT\";\n EffectType[EffectType[\"UNRECOGNIZED\"] = -1] = \"UNRECOGNIZED\";\n})(EffectType || (EffectType = {}));\n", "/**\n * #post_message.ts\n *\n * Code generated by ts-proto. DO NOT EDIT.\n * @packageDocumentation\n */\n/* eslint-disable */\n/**\n * Blocks only.\n *\n * @deprecated\n */\nexport var WebViewInternalMessageScope;\n(function (WebViewInternalMessageScope) {\n /** CLIENT - Message is intended for the client only */\n WebViewInternalMessageScope[WebViewInternalMessageScope[\"CLIENT\"] = 0] = \"CLIENT\";\n WebViewInternalMessageScope[WebViewInternalMessageScope[\"UNRECOGNIZED\"] = -1] = \"UNRECOGNIZED\";\n})(WebViewInternalMessageScope || (WebViewInternalMessageScope = {}));\n", "import { EffectType } from '@devvit/protos/json/devvit/ui/effects/v1alpha/effect.js';\nimport { WebViewInternalMessageScope, } from '@devvit/protos/json/devvit/ui/effects/web_view/v1alpha/post_message.js';\n/** `WebViewInternalMessage.type`. */\nexport const webViewInternalMessageType = 'devvit-internal';\nconst EFFECTS_WITH_RESPONSE = {\n [EffectType.EFFECT_SHOW_FORM]: true,\n [EffectType.EFFECT_CAN_RUN_AS_USER]: true,\n [EffectType.EFFECT_CREATE_ORDER]: true,\n};\n/**\n * Emits an effect to the parent window and handles the response if required.\n *\n * @param effect - The effect to be emitted to the parent window\n * @returns A promise that resolves with the response message for effects that require\n * a response, or resolves immediately with undefined for effects that don't\n *\n * @description\n * This function handles two types of effects:\n * 1. Effects that require a response: Creates a unique ID, sets up a message listener,\n * and resolves the promise when a matching response is received\n * 2. Effects that don't require a response: Posts the message and resolves immediately\n */\nexport const emitEffect = (effect) => {\n return new Promise((resolve) => {\n const message = {\n ...effect,\n realtimeEffect: effect.realtime, // to-do: remove deprecated field.\n scope: WebViewInternalMessageScope.CLIENT,\n type: webViewInternalMessageType,\n };\n // For temporary backward compatibility, we set both `message.effect_type` above, and `effect` below\n // Once mobile clients are updated to consume the strongly typed properties above, we can remove this block\n // *Do not* add new effects here, use the strongly typed properties above\n if (effect.showToast ||\n effect.navigateToUrl ||\n effect.showForm ||\n effect.type === EffectType.EFFECT_CAN_RUN_AS_USER) {\n message.effect = effect;\n }\n // Only set message id and add a listener for effects which require a response\n if (EFFECTS_WITH_RESPONSE[effect.type]) {\n const id = crypto.randomUUID();\n message.id = id;\n const handleEffect = (event) => {\n if (event.data?.type === 'devvit-message' && event.data?.data?.id === id) {\n resolve(event.data.data);\n removeEventListener('message', handleEffect);\n }\n };\n addEventListener('message', handleEffect);\n // Post message to the parent window, handled by client web view component\n parent.postMessage(message, '*');\n }\n else {\n parent.postMessage(message, '*');\n // Resolve immediately for effects that don't expect a response.\n resolve(undefined);\n }\n });\n};\n", "import type { EffectType } from '@devvit/protos/json/devvit/ui/effects/v1alpha/effect.js';\nimport { emitEffect } from '@devvit/shared-types/client/emit-effect.js';\n\n/**\n * Navigates to a URL, subreddit, post, comment, or user.\n *\n * @param thingOrUrl - The URL, subreddit, post, comment, or user to navigate to\n */\nexport function navigateTo(thingOrUrl: string | { readonly url: string }): void {\n const inputUrl = typeof thingOrUrl === 'string' ? thingOrUrl : thingOrUrl.url;\n let normalizedUrl: string;\n try {\n normalizedUrl = new URL(inputUrl).toString();\n } catch {\n throw new TypeError(`Invalid URL: ${inputUrl}`);\n }\n void emitEffect({\n navigateToUrl: {\n url: normalizedUrl,\n },\n type: 5 satisfies EffectType.EFFECT_NAVIGATE_TO_URL,\n });\n}\n", "/**\n * #app_permission.ts\n *\n * Code generated by ts-proto. DO NOT EDIT.\n * @packageDocumentation\n */\n/* eslint-disable */\n/** This enum is used to represent the consent status of an app permission. */\nexport var ConsentStatus;\n(function (ConsentStatus) {\n /** CONSENT_STATUS_UNKNOWN - The consent status is unknown, which means it has not been set or is not applicable. */\n ConsentStatus[ConsentStatus[\"CONSENT_STATUS_UNKNOWN\"] = 0] = \"CONSENT_STATUS_UNKNOWN\";\n /** REVOKED - The user has explicitly denied consent for the app permissions. */\n ConsentStatus[ConsentStatus[\"REVOKED\"] = 1] = \"REVOKED\";\n /** GRANTED - The user has granted consent for the app permissions. */\n ConsentStatus[ConsentStatus[\"GRANTED\"] = 2] = \"GRANTED\";\n ConsentStatus[ConsentStatus[\"UNRECOGNIZED\"] = -1] = \"UNRECOGNIZED\";\n})(ConsentStatus || (ConsentStatus = {}));\n/** This enum is used to represent the scopes of permissions that can be granted to an app. */\nexport var Scope;\n(function (Scope) {\n /** SCOPE_UNKNOWN - The scope is unknown, which means it has not been set or is not applicable. */\n Scope[Scope[\"SCOPE_UNKNOWN\"] = 0] = \"SCOPE_UNKNOWN\";\n /** SUBMIT_POST - Allows the app to submit posts on behalf of the user. */\n Scope[Scope[\"SUBMIT_POST\"] = 1] = \"SUBMIT_POST\";\n /** SUBMIT_COMMENT - Allows the app to submit comments on behalf of the user. */\n Scope[Scope[\"SUBMIT_COMMENT\"] = 2] = \"SUBMIT_COMMENT\";\n /** SUBSCRIBE_TO_SUBREDDIT - Allows the app to subscribe the user to a subreddit. */\n Scope[Scope[\"SUBSCRIBE_TO_SUBREDDIT\"] = 3] = \"SUBSCRIBE_TO_SUBREDDIT\";\n Scope[Scope[\"UNRECOGNIZED\"] = -1] = \"UNRECOGNIZED\";\n})(Scope || (Scope = {}));\n", "import type { EffectType } from '@devvit/protos/json/devvit/ui/effects/v1alpha/effect.js';\nimport { ConsentStatus } from '@devvit/protos/json/reddit/devvit/app_permission/v1/app_permission.js';\nimport { emitEffect } from '@devvit/shared-types/client/emit-effect.js';\n\n/**\n * This method is used to check if the app has been granted all the requested scopes.\n *\n * @experimental\n * @returns true if the app has been granted all the requested scopes, false otherwise.\n */\nexport const canRunAsUser = async (): Promise<boolean> => {\n const appPermissionState = devvit.appPermissionState;\n\n if (!appPermissionState) {\n // Note: The app permission state will be missing when the app runs on clients that haven't implemented this feature yet.\n // \"true\" is the correct value for the time being, until we have all clients supporting this feature.\n return true;\n }\n\n if (appPermissionState.requestedScopes.length === 0) {\n // the app does not have permission to do anything as the user\n return false;\n }\n\n switch (appPermissionState.consentStatus) {\n case ConsentStatus.REVOKED:\n return false;\n case ConsentStatus.GRANTED:\n // If the app has been granted all the requested scopes, return true\n if (\n appPermissionState.requestedScopes.every((scope) =>\n appPermissionState.grantedScopes.includes(scope)\n )\n ) {\n return true;\n }\n // Otherwise, the sets of scopes do not overlap we emit the effect to request the scopes; continue\n break;\n case ConsentStatus.CONSENT_STATUS_UNKNOWN:\n case ConsentStatus.UNRECOGNIZED:\n // We don't know the status, so we'll have to ask.\n break;\n default: {\n appPermissionState.consentStatus satisfies never;\n break;\n }\n }\n\n const response = await emitEffect({\n canRunAsUser: {\n postId: devvit.context.postId,\n appSlug: devvit.context.appName,\n subredditId: devvit.context.subredditId,\n },\n type: 11 satisfies EffectType.EFFECT_CAN_RUN_AS_USER,\n });\n\n return response?.consentStatus?.consentStatus === ConsentStatus.GRANTED;\n};\n", "// to-do: move to service + CLI package.\n// Do not use in @devvit/public-api. Protos not in externalized @devvit/protos\n// barrel.\nexport const ACTOR_SRC_DIR = 'src';\nexport const ACTOR_SRC_PRIMARY_NAME = 'main';\n/** payments stuff. */\nexport const PRODUCTS_JSON_FILE = 'products.json';\n/**\n * The hashing algorithm used - pass this to `createHash`\n */\nexport const ASSET_HASHING_ALGO = 'sha256';\n/**\n * The max number of subscribers allowed in a test subreddit (ie where a user can install an uploaded, private app\n * Determines if a PRIVATE (unpublished) version of an app can be installed or playtested\n *\n * TODO: turn this off before we go live - see DX-1336\n * */\nexport const MAX_ALLOWED_SUBSCRIBER_COUNT = 200;\n/**\n * How many assets to upload at once. Sending too many at once can cause the\n * server to become overwhelmed and start erroring clients out.\n * @type {number}\n */\nexport const ASSET_UPLOAD_BATCH_SIZE = 10;\nexport const REDDIT_OAUTH_COPY_PASTE_CLIENT_ID = 'TWTsqXa53CexlrYGBWaesQ';\n/** All server endpoints must start with this prefix. */\nexport const apiPathPrefix = '/api/';\n/** All unexposed APIs must start with this prefix. */\nexport const internalPathPrefix = '/internal/';\n/** When an app's icon is present in the media assets list, it'll be with this special name. */\nexport const ICON_FILE_PATH = '$devvit_icon.png'; // Uses special characters intentionally to avoid conflicts with real asset paths\nexport const REDDIT_DISCORD_INVITE_URL = 'https://discord.gg/Cd43ExtEFS';\nexport const REDDIT_SUBREDDIT_URL = 'https://www.reddit.com/r/devvit';\n", "import type { EffectType } from '@devvit/protos/json/devvit/ui/effects/v1alpha/effect.js';\nimport { emitEffect } from '@devvit/shared-types/client/emit-effect.js';\nimport { maxShareParamUserDataChars } from '@devvit/shared-types/client/share.js';\nimport { ICON_FILE_PATH } from '@devvit/shared-types/constants.js';\n\nexport type ShareSheetOpts = {\n /** Data to share. Must be 1024 characters or less. */\n data?: string | undefined;\n /** Title of share sheet. */\n title?: string | undefined;\n /** Body text of share sheet. */\n text?: string | undefined;\n};\n\n// to-do: unit test.\n// to-do: move to web view scripts.\n/** Show the native share sheet or copy to clipboard depending on device. */\nexport async function showShareSheet(opts: Readonly<ShareSheetOpts>): Promise<void> {\n if (opts.data && opts.data.length > maxShareParamUserDataChars)\n throw Error(\n `data must be <= ${maxShareParamUserDataChars} characters but was ${opts.data.length} characters`\n );\n\n const iconURL = `${new URL(ICON_FILE_PATH, location.origin)}`;\n let iconRsp;\n try {\n iconRsp = await fetch(iconURL, { method: 'HEAD' });\n } catch {\n //\n }\n\n await emitEffect({\n type: 9 satisfies EffectType.EFFECT_WEB_VIEW,\n share: {\n appIconUri: iconRsp?.ok ? iconURL : undefined,\n userData: opts.data,\n text: opts.text,\n title: opts.title,\n },\n });\n}\n\nexport function getShareData(): string | undefined {\n return devvit.share?.userData;\n}\n", "import type { FormField, SettingScope } from '@devvit/shared';\n\n/**\n * Make sure that the form fields have unique names.\n *\n * This is a carbon copy of the assertValidFormFields function in the public-api package\n * We copy it here so that @devvit/client does not need to depend on public-api\n * Any changes to this function should be reflected in the public-api version\n */\nexport function assertValidFormFields(\n fields: readonly FormField[],\n seenNames: Set<string> = new Set()\n): void {\n for (const field of fields) {\n if (field.type === 'group') {\n assertValidFormFields(field.fields, seenNames);\n continue;\n }\n\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n const fieldName = (field as any).name as string;\n\n if (seenNames.has(fieldName)) {\n throw new Error(`Duplicate field name: ${fieldName}`);\n }\n\n seenNames.add(fieldName);\n }\n assertAppSecretsOnly(fields);\n}\n\nexport function assertAppSecretsOnly(fields: readonly FormField[]): void {\n for (const field of fields) {\n if (field.type === 'string' && field.isSecret && field.scope !== ('app' as SettingScope.App)) {\n throw `Invalid setting: only app settings can be secrets. Add \"scope: SettingScope.App\" to field \"${field.name}\"`;\n }\n }\n}\n", "/**\n * #type.ts\n *\n * Code generated by ts-proto. DO NOT EDIT.\n * @packageDocumentation\n */\n/* eslint-disable */\nexport var FormFieldType;\n(function (FormFieldType) {\n /** STRING - Single-line string */\n FormFieldType[FormFieldType[\"STRING\"] = 0] = \"STRING\";\n /** PARAGRAPH - Multi-line string */\n FormFieldType[FormFieldType[\"PARAGRAPH\"] = 1] = \"PARAGRAPH\";\n /** NUMBER - Number input */\n FormFieldType[FormFieldType[\"NUMBER\"] = 2] = \"NUMBER\";\n /** BOOLEAN - Checkbox, switch */\n FormFieldType[FormFieldType[\"BOOLEAN\"] = 3] = \"BOOLEAN\";\n /** LIST - Collect multiple entries of a single type */\n FormFieldType[FormFieldType[\"LIST\"] = 4] = \"LIST\";\n /** SELECTION - Provide a list of options for the user to choose from */\n FormFieldType[FormFieldType[\"SELECTION\"] = 5] = \"SELECTION\";\n /** GROUP - Create a labeled subsection of the form with nested fields */\n FormFieldType[FormFieldType[\"GROUP\"] = 6] = \"GROUP\";\n /** IMAGE - Image upload - value is a URL for the uploaded image */\n FormFieldType[FormFieldType[\"IMAGE\"] = 7] = \"IMAGE\";\n FormFieldType[FormFieldType[\"UNRECOGNIZED\"] = -1] = \"UNRECOGNIZED\";\n})(FormFieldType || (FormFieldType = {}));\n", "/**\n * #events.ts\n *\n * Code generated by ts-proto. DO NOT EDIT.\n * @packageDocumentation\n */\n/* eslint-disable */\nexport var EventSource;\n(function (EventSource) {\n EventSource[EventSource[\"UNKNOWN_EVENT_SOURCE\"] = 0] = \"UNKNOWN_EVENT_SOURCE\";\n EventSource[EventSource[\"USER\"] = 1] = \"USER\";\n EventSource[EventSource[\"ADMIN\"] = 2] = \"ADMIN\";\n EventSource[EventSource[\"MODERATOR\"] = 3] = \"MODERATOR\";\n EventSource[EventSource[\"UNRECOGNIZED\"] = -1] = \"UNRECOGNIZED\";\n})(EventSource || (EventSource = {}));\nexport var DeletionReason;\n(function (DeletionReason) {\n DeletionReason[DeletionReason[\"UNSPECIFIED_DELETION_REASON\"] = 0] = \"UNSPECIFIED_DELETION_REASON\";\n DeletionReason[DeletionReason[\"SPAM\"] = 1] = \"SPAM\";\n DeletionReason[DeletionReason[\"LEGAL\"] = 2] = \"LEGAL\";\n DeletionReason[DeletionReason[\"OTHER\"] = 3] = \"OTHER\";\n DeletionReason[DeletionReason[\"UNKNOWN\"] = 4] = \"UNKNOWN\";\n DeletionReason[DeletionReason[\"EXPLICIT_CONTENT\"] = 5] = \"EXPLICIT_CONTENT\";\n DeletionReason[DeletionReason[\"UNRECOGNIZED\"] = -1] = \"UNRECOGNIZED\";\n})(DeletionReason || (DeletionReason = {}));\n", "/**\n * #postv2.ts\n *\n * Code generated by ts-proto. DO NOT EDIT.\n * @packageDocumentation\n */\n/* eslint-disable */\nexport var CrowdControlLevel;\n(function (CrowdControlLevel) {\n CrowdControlLevel[CrowdControlLevel[\"OFF\"] = 0] = \"OFF\";\n CrowdControlLevel[CrowdControlLevel[\"LENIENT\"] = 1] = \"LENIENT\";\n CrowdControlLevel[CrowdControlLevel[\"MEDIUM\"] = 2] = \"MEDIUM\";\n CrowdControlLevel[CrowdControlLevel[\"STRICT\"] = 3] = \"STRICT\";\n CrowdControlLevel[CrowdControlLevel[\"UNRECOGNIZED\"] = -1] = \"UNRECOGNIZED\";\n})(CrowdControlLevel || (CrowdControlLevel = {}));\nexport var DistinguishType;\n(function (DistinguishType) {\n DistinguishType[DistinguishType[\"NULL_VALUE\"] = 0] = \"NULL_VALUE\";\n DistinguishType[DistinguishType[\"ADMIN\"] = 1] = \"ADMIN\";\n DistinguishType[DistinguishType[\"GOLD\"] = 2] = \"GOLD\";\n DistinguishType[DistinguishType[\"GOLD_AUTO\"] = 3] = \"GOLD_AUTO\";\n DistinguishType[DistinguishType[\"YES\"] = 4] = \"YES\";\n DistinguishType[DistinguishType[\"SPECIAL\"] = 5] = \"SPECIAL\";\n DistinguishType[DistinguishType[\"UNRECOGNIZED\"] = -1] = \"UNRECOGNIZED\";\n})(DistinguishType || (DistinguishType = {}));\n", "/**\n * #subredditv2.ts\n *\n * Code generated by ts-proto. DO NOT EDIT.\n * @packageDocumentation\n */\n/* eslint-disable */\nexport var SubredditType;\n(function (SubredditType) {\n SubredditType[SubredditType[\"ARCHIVED\"] = 0] = \"ARCHIVED\";\n SubredditType[SubredditType[\"EMPLOYEES_ONLY\"] = 1] = \"EMPLOYEES_ONLY\";\n SubredditType[SubredditType[\"GOLD_ONLY\"] = 2] = \"GOLD_ONLY\";\n SubredditType[SubredditType[\"GOLD_RESTRICTED\"] = 3] = \"GOLD_RESTRICTED\";\n SubredditType[SubredditType[\"PRIVATE\"] = 4] = \"PRIVATE\";\n SubredditType[SubredditType[\"PUBLIC\"] = 5] = \"PUBLIC\";\n SubredditType[SubredditType[\"RESTRICTED\"] = 6] = \"RESTRICTED\";\n SubredditType[SubredditType[\"USER\"] = 7] = \"USER\";\n SubredditType[SubredditType[\"UNRECOGNIZED\"] = -1] = \"UNRECOGNIZED\";\n})(SubredditType || (SubredditType = {}));\n/** used with data-api */\nexport var SubredditRating;\n(function (SubredditRating) {\n SubredditRating[SubredditRating[\"UNKNOWN_SUBREDDIT_RATING\"] = 0] = \"UNKNOWN_SUBREDDIT_RATING\";\n /** E - everyone */\n SubredditRating[SubredditRating[\"E\"] = 1] = \"E\";\n /** M1 - mature 1 */\n SubredditRating[SubredditRating[\"M1\"] = 2] = \"M1\";\n /** M2 - mature 2 */\n SubredditRating[SubredditRating[\"M2\"] = 3] = \"M2\";\n /** D - high-risk drug use */\n SubredditRating[SubredditRating[\"D\"] = 4] = \"D\";\n /** V - violence & gore */\n SubredditRating[SubredditRating[\"V\"] = 5] = \"V\";\n /** X - sexually explicit */\n SubredditRating[SubredditRating[\"X\"] = 6] = \"X\";\n SubredditRating[SubredditRating[\"UNRECOGNIZED\"] = -1] = \"UNRECOGNIZED\";\n})(SubredditRating || (SubredditRating = {}));\n", "export var SettingScope;\n(function (SettingScope) {\n SettingScope[\"Installation\"] = \"installation\";\n SettingScope[\"App\"] = \"app\";\n})(SettingScope || (SettingScope = {}));\n", "import { assert } from './assert.js';\n/**\n * - **C**omment (T1).\n * - **A**ccount (T2).\n * - **L**ink (T3).\n * - **M**essage (T4).\n * - **S**ubreddit (T5).\n * - **T**rophies (T6).\n */\nexport var T_PREFIX;\n(function (T_PREFIX) {\n T_PREFIX[\"COMMENT\"] = \"t1_\";\n T_PREFIX[\"ACCOUNT\"] = \"t2_\";\n T_PREFIX[\"LINK\"] = \"t3_\";\n T_PREFIX[\"MESSAGE\"] = \"t4_\";\n T_PREFIX[\"SUBREDDIT\"] = \"t5_\";\n T_PREFIX[\"AWARD\"] = \"t6_\";\n})(T_PREFIX || (T_PREFIX = {}));\n// type guards\nexport function isT1(id) {\n return id.startsWith(T_PREFIX.COMMENT);\n}\nexport function isT2(id) {\n return id.startsWith(T_PREFIX.ACCOUNT);\n}\nexport function isT3(id) {\n return id.startsWith(T_PREFIX.LINK);\n}\nexport function isT4(id) {\n return id.startsWith(T_PREFIX.MESSAGE);\n}\nexport function isT5(id) {\n return id.startsWith(T_PREFIX.SUBREDDIT);\n}\nexport function isT6(id) {\n return id.startsWith(T_PREFIX.AWARD);\n}\n// assertion functions\nexport function assertT1(id) {\n assert(isT1(id), `Expected comment id to start with ${T_PREFIX.COMMENT}, got ${id}`);\n}\nexport function assertT2(id) {\n assert(isT2(id), `Expected account id to start with ${T_PREFIX.ACCOUNT}, got ${id}`);\n}\nexport function assertT3(id) {\n assert(isT3(id), `Expected link id to start with ${T_PREFIX.LINK}, got ${id}`);\n}\nexport function assertT4(id) {\n assert(isT4(id), `Expected message id to start with ${T_PREFIX.MESSAGE}, got ${id}`);\n}\nexport function assertT5(id) {\n assert(isT5(id), `Expected subreddit id to start with ${T_PREFIX.SUBREDDIT}, got ${id}`);\n}\nexport function assertT6(id) {\n assert(isT6(id), `Expected award id to start with ${T_PREFIX.AWARD}, got ${id}`);\n}\n// factory functions\nexport function T1(id) {\n assertT1(id);\n return id;\n}\nexport function T2(id) {\n assertT2(id);\n return id;\n}\nexport function T3(id) {\n assertT3(id);\n return id;\n}\nexport function T4(id) {\n assertT4(id);\n return id;\n}\nexport function T5(id) {\n assertT5(id);\n return id;\n}\nexport function T6(id) {\n assertT6(id);\n return id;\n}\nexport function asTid(id) {\n if (isT1(id)) {\n return T1(id);\n }\n if (isT2(id)) {\n return T2(id);\n }\n if (isT3(id)) {\n return T3(id);\n }\n if (isT4(id)) {\n return T4(id);\n }\n if (isT5(id)) {\n return T5(id);\n }\n if (isT6(id)) {\n return T6(id);\n }\n throw new Error(`Expected thing id to start with ${Object.values(T_PREFIX).join(', ')} got ${id}}`);\n}\n", "import { FormFieldType } from '@devvit/protos/json/devvit/ui/form_builder/v1alpha/type.js';\nimport type { FormFieldValue } from '@devvit/protos/json/devvit/ui/form_builder/v1alpha/value.js';\nimport { type FormValues, type JsonObject } from '@devvit/shared';\n\nfunction flattenFormFieldValue(\n value: FormFieldValue\n): undefined | string | string[] | number | boolean {\n switch (value.fieldType) {\n case FormFieldType.STRING:\n return value.stringValue;\n case FormFieldType.IMAGE:\n // the string value is the URL\n return value.stringValue;\n case FormFieldType.PARAGRAPH:\n return value.stringValue;\n case FormFieldType.NUMBER:\n return value.numberValue;\n case FormFieldType.BOOLEAN:\n return value.boolValue;\n case FormFieldType.SELECTION:\n return value.selectionValue?.values ?? [];\n default:\n return undefined;\n }\n}\n\n// This is a carbon copy of the transformFormFields function in the public-api package\n// We copy it here so that @devvit/client does not need to depend on public-api\n// Any changes to this function should be reflected in the public-api version\nexport function getFormValues<T extends JsonObject>(results: {\n [key: string]: FormFieldValue;\n}): FormValues<T> {\n return Object.keys(results).reduce((acc, key) => {\n const val = flattenFormFieldValue(results[key]);\n if (val !== undefined) (acc as JsonObject)[key] = val;\n return acc;\n }, {} as FormValues<T>);\n}\n", "import type { FormField as FormFieldProto } from '@devvit/protos/json/devvit/ui/form_builder/v1alpha/field.js';\nimport { FormFieldType } from '@devvit/protos/json/devvit/ui/form_builder/v1alpha/type.js';\nimport {\n type BooleanField,\n type FormField,\n type FormFieldGroup,\n type ImageField,\n type NumberField,\n type ParagraphField,\n type SelectField,\n type StringField,\n} from '@devvit/shared';\n\n// This is a carbon copy of the transformFormFields function in the public-api package\n// We copy it here so that @devvit/client does not need to depend on public-api\n// Any changes to this function should be reflected in the public-api version\nexport function transformFormFields(fields: readonly FormField[]): FormFieldProto[] {\n return fields.map((field) => {\n switch (field.type) {\n case 'string':\n return transformStringField(field);\n case 'image':\n return transformImageField(field);\n case 'paragraph':\n return transformParagraphField(field);\n case 'number':\n return transformNumberField(field);\n case 'select':\n return transformSelectField(field);\n case 'boolean':\n return transformBooleanField(field);\n case 'group':\n return transformGroupField(field);\n default:\n throw new Error('Unknown field type.');\n }\n });\n}\n\nfunction transformStringField(field: StringField): FormFieldProto {\n return {\n defaultValue: {\n fieldType: FormFieldType.STRING,\n stringValue: field.defaultValue,\n },\n disabled: field.disabled,\n fieldConfig: {\n stringConfig: {\n placeholder: field.placeholder,\n },\n },\n fieldId: field.name,\n fieldType: FormFieldType.STRING,\n helpText: field.helpText,\n label: field.label,\n required: field.required,\n isSecret: field.isSecret,\n };\n}\n\nfunction transformImageField(field: ImageField): FormFieldProto {\n return {\n disabled: field.disabled,\n fieldId: field.name,\n fieldType: FormFieldType.IMAGE,\n helpText: field.helpText,\n label: field.label,\n required: field.required,\n };\n}\n\nfunction transformParagraphField(field: ParagraphField): FormFieldProto {\n return {\n defaultValue: {\n fieldType: FormFieldType.PARAGRAPH,\n stringValue: field.defaultValue,\n },\n disabled: field.disabled,\n fieldConfig: {\n paragraphConfig: {\n lineHeight: field.lineHeight,\n placeholder: field.placeholder,\n },\n },\n fieldId: field.name,\n fieldType: FormFieldType.PARAGRAPH,\n helpText: field.helpText,\n label: field.label,\n required: field.required,\n };\n}\n\nfunction transformNumberField(field: NumberField): FormFieldProto {\n return {\n defaultValue: {\n fieldType: FormFieldType.NUMBER,\n numberValue: field.defaultValue,\n },\n disabled: field.disabled,\n fieldConfig: {\n numberConfig: {},\n },\n fieldId: field.name,\n fieldType: FormFieldType.NUMBER,\n helpText: field.helpText,\n label: field.label,\n required: field.required,\n };\n}\n\nfunction transformSelectField(field: SelectField): FormFieldProto {\n return {\n defaultValue: {\n fieldType: FormFieldType.SELECTION,\n selectionValue: {\n values: field.defaultValue ?? [],\n },\n },\n disabled: field.disabled,\n fieldConfig: {\n selectionConfig: {\n choices: field.options,\n multiSelect: field.multiSelect,\n },\n },\n fieldId: field.name,\n fieldType: FormFieldType.SELECTION,\n helpText: field.helpText,\n label: field.label,\n required: field.required,\n };\n}\n\nfunction transformBooleanField(field: BooleanField): FormFieldProto {\n return {\n defaultValue: {\n fieldType: FormFieldType.BOOLEAN,\n boolValue: field.defaultValue,\n },\n disabled: field.disabled,\n fieldId: field.name,\n fieldType: FormFieldType.BOOLEAN,\n helpText: field.helpText,\n label: field.label,\n };\n}\n\nfunction transformGroupField(field: FormFieldGroup): FormFieldProto {\n return {\n fieldId: '',\n fieldType: FormFieldType.GROUP,\n fieldConfig: {\n groupConfig: {\n fields: transformFormFields(field.fields),\n },\n },\n label: field.label,\n helpText: field.helpText,\n };\n}\n", "import type { EffectType } from '@devvit/protos/json/devvit/ui/effects/v1alpha/effect.js';\nimport type { Form as FormProto } from '@devvit/protos/json/devvit/ui/form_builder/v1alpha/form.js';\nimport type { Form } from '@devvit/shared';\nimport { emitEffect } from '@devvit/shared-types/client/emit-effect.js';\nimport type { FormKey } from '@devvit/shared-types/useForm.js';\n\nimport { assertValidFormFields } from './helpers/assert-valid-form-fields.js';\nimport type { FormEffectResponse, FormToFormValues } from './helpers/form-types.js';\nimport { getFormValues } from './helpers/get-form-values.js';\nimport { transformFormFields } from './helpers/transform-form.js';\n\nlet _formKey = 1;\n\nconst getNextFormKey = (): FormKey => {\n _formKey++;\n return `form.${_formKey}`;\n};\n\n/**\n * Opens a form in a modal.\n * Returns a promise that resolves with the form submission results.\n * The form can be submitted or canceled by the user.\n *\n * @param formDefinition - The form configuration\n * @returns A promise that resolves to either:\n * - An object with `action: FormAction.SUBMITTED` and the submitted form values\n * - An object with `action: FormAction.CANCELED` if the user canceled the form\n * @throws Will throw if the form fields are invalid\n */\nexport const showForm = async <const T extends Form>(\n formDefinition: T\n): Promise<FormEffectResponse<FormToFormValues<T>>> => {\n const form: FormProto = {\n fields: [],\n id: getNextFormKey(),\n title: formDefinition.title,\n acceptLabel: formDefinition.acceptLabel,\n cancelLabel: formDefinition.cancelLabel,\n shortDescription: formDefinition.description,\n };\n\n assertValidFormFields(formDefinition.fields);\n form.fields = transformFormFields(formDefinition.fields);\n\n const response = await emitEffect({\n showForm: {\n form,\n },\n type: 3 satisfies EffectType.EFFECT_SHOW_FORM,\n });\n\n if (!response || !response.formSubmitted) {\n return {\n action: 'CANCELED',\n };\n }\n\n const formResults = getFormValues(response.formSubmitted.results);\n\n return {\n action: 'SUBMITTED',\n values: formResults as FormToFormValues<T>,\n };\n};\n", "import type { EffectType } from '@devvit/protos/json/devvit/ui/effects/v1alpha/effect.js';\nimport type {\n Toast as ToastProto,\n ToastAppearance,\n} from '@devvit/protos/json/devvit/ui/toast/toast.js';\nimport type { Toast } from '@devvit/shared';\nimport { emitEffect } from '@devvit/shared-types/client/emit-effect.js';\n\n/**\n * Shows a toast message.\n *\n * @param textOrToast - The text or toast object to display\n */\nexport function showToast(text: string): void;\nexport function showToast(toast: Toast): void;\nexport function showToast(textOrToast: string | Toast): void {\n let toast: ToastProto;\n\n if (textOrToast instanceof Object) {\n toast = {\n text: textOrToast.text,\n appearance:\n textOrToast.appearance === 'success'\n ? (1 satisfies ToastAppearance.SUCCESS)\n : (0 satisfies ToastAppearance.NEUTRAL),\n };\n } else {\n toast = {\n text: textOrToast,\n };\n }\n\n void emitEffect({\n showToast: {\n toast,\n },\n type: 4 satisfies EffectType.EFFECT_SHOW_TOAST,\n });\n}\n", "/**\n * #immersive_mode.ts\n *\n * Code generated by ts-proto. DO NOT EDIT.\n * @packageDocumentation\n */\n/* eslint-disable */\n/** How a Devvit app is presented. */\nexport var WebViewImmersiveMode;\n(function (WebViewImmersiveMode) {\n WebViewImmersiveMode[WebViewImmersiveMode[\"UNSPECIFIED\"] = 0] = \"UNSPECIFIED\";\n /**\n * INLINE_MODE - Conventional post presentation. May appear adjacent other posts in a feed\n * or with comments.\n */\n WebViewImmersiveMode[WebViewImmersiveMode[\"INLINE_MODE\"] = 1] = \"INLINE_MODE\";\n /**\n * IMMERSIVE_MODE - Large modal expanded presentation. Appears popped out from the rest of the\n * Reddit experience which is disabled.\n */\n WebViewImmersiveMode[WebViewImmersiveMode[\"IMMERSIVE_MODE\"] = 2] = \"IMMERSIVE_MODE\";\n WebViewImmersiveMode[WebViewImmersiveMode[\"UNRECOGNIZED\"] = -1] = \"UNRECOGNIZED\";\n})(WebViewImmersiveMode || (WebViewImmersiveMode = {}));\n", "export const noWebbitToken = `0.0.0`;\n/**\n * `RequestContext` token query parameter name on `DevvitPost.entrypointUrl`.\n */\nexport const tokenParam = 'token';\n", "import type { EffectType } from '@devvit/protos/json/devvit/ui/effects/v1alpha/effect.js';\nimport { WebViewImmersiveMode } from '@devvit/protos/json/devvit/ui/effects/web_view/v1alpha/immersive_mode.js';\nimport { emitEffect } from '@devvit/shared-types/client/emit-effect.js';\nimport { tokenParam } from '@devvit/shared-types/webbit.js';\n\n/**\n * The presentation mode of the web view.\n * 'inline' The web view is displayed inline within a feed or post detail page\n * 'expanded' The web view is displayed in a larger modal presentation\n * @experimental\n */\nexport type WebViewMode = 'inline' | 'expanded';\n\n/**\n * A listener that is called when the web view mode changes.\n * @param mode The new mode, either 'inline' or 'expanded'.\n * @experimental\n */\nexport type WebViewModeListener = (mode: WebViewMode) => void;\n\n/**\n * Represents the current web view mode state for the application.\n *\n * @experimental\n */\nexport const getWebViewMode = (): WebViewMode => webViewMode(devvit.webViewMode);\n\n/**\n * Requests expanded mode for the web view.\n * This will display the web view in a larger modal presentation.\n *\n * @param event The gesture that triggered the request, must be a trusted event.\n * @param entry The destination URI name. Eg, `'splash'` or `'default'`. Entry\n * names are the `devvit.json` `post.entrypoints` keys. Passing the\n * same entrypoint as currently loaded causes a reload.\n * @returns A promise that resolves request has been received.\n * @throws When already expanded.\n *\n * @experimental\n * @example\n * ```ts\n * button.addEventListener('click', async (event) => {\n * await requestExpandedMode(event);\n * });\n * ```\n */\nexport function requestExpandedMode(event: MouseEvent, entry: string): Promise<void> {\n if (devvit.webViewMode === WebViewImmersiveMode.IMMERSIVE_MODE)\n throw Error('web view is already expanded');\n return emitModeEffect(WebViewImmersiveMode.IMMERSIVE_MODE, event, entry);\n}\n\n/**\n * Exits expanded mode for the web view.\n * This will display the web view in an inline presentation.\n *\n * @param event The event that triggered the request, must be a trusted event.\n * @returns A promise that resolves request has been received.\n * @throws When already inlined.\n *\n * @experimental\n * @example\n * ```ts\n * button.addEventListener('click', async (event) => {\n * await exitExpandedMode(event);\n * });\n * ```\n */\nexport function exitExpandedMode(event: MouseEvent): Promise<void> {\n if (devvit.webViewMode === WebViewImmersiveMode.INLINE_MODE)\n throw Error('web view is already inlined');\n return emitModeEffect(WebViewImmersiveMode.INLINE_MODE, event, undefined);\n}\n\n/**\n * @deprecated This API is deprecated and will be removed in a future release.\n * use window.addEventListener(\"focus\", () => { }) to receive notifications\n * when the web view mode changes back to inline.\n * Adds a listener that is called when the web view mode changes. Initial mode\n * is not reported. Web views in the process of destruction may not receive a\n * mode change event.\n *\n * @param callback The callback to be called when the mode changes.\n * @experimental\n */\nexport function addWebViewModeListener(_: WebViewModeListener): void {}\n\n/**\n * @deprecated This API is deprecated and will be removed in a future release.\n * Removes a listener that was previously added with `addWebViewModeListener`.\n *\n * @param callback The callback to be removed.\n * @experimental\n */\nexport function removeWebViewModeListener(_: WebViewModeListener): void {}\n\nasync function emitModeEffect(\n mode: WebViewImmersiveMode,\n event: Event,\n entry: string | undefined\n): Promise<void> {\n if (!event.isTrusted || event.type !== 'click') {\n console.error('Expanded mode effect ignored due to untrusted event');\n throw new Error('Untrusted event');\n }\n\n if (entry != null && !devvit.entrypoints[entry])\n throw Error(\n `no entrypoint named \"${entry}\"; all entrypoints must appear in \\`devvit.json\\` \\`post.entrypoints\\``\n );\n\n let entryUrl;\n if (entry) {\n // Only `DevvitPost.entrypointUrl` has a token.\n const url = new URL(devvit.entrypoints[entry]);\n url.searchParams.set(tokenParam, devvit.token);\n entryUrl = `${url}`;\n }\n\n const type = 9 satisfies EffectType.EFFECT_WEB_VIEW;\n await emitEffect({\n type,\n immersiveMode: { entryUrl, immersiveMode: mode },\n });\n}\n\nfunction webViewMode(mode: WebViewImmersiveMode | undefined): WebViewMode {\n switch (mode) {\n case WebViewImmersiveMode.IMMERSIVE_MODE:\n return 'expanded';\n case WebViewImmersiveMode.INLINE_MODE:\n case WebViewImmersiveMode.UNRECOGNIZED:\n case WebViewImmersiveMode.UNSPECIFIED:\n case undefined:\n return 'inline';\n default:\n mode satisfies never;\n throw Error(`${mode} not a WebViewImmersiveMode`);\n }\n}\n"],
5
+ "mappings": "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",
6
+ "names": ["context", "EffectType", "WebViewInternalMessageScope", "webViewInternalMessageType", "EFFECTS_WITH_RESPONSE", "EffectType", "emitEffect", "effect", "resolve", "message", "WebViewInternalMessageScope", "id", "handleEffect", "event", "navigateTo", "thingOrUrl", "inputUrl", "normalizedUrl", "emitEffect", "ConsentStatus", "Scope", "canRunAsUser", "appPermissionState", "ConsentStatus", "scope", "emitEffect", "ICON_FILE_PATH", "showShareSheet", "opts", "iconURL", "ICON_FILE_PATH", "iconRsp", "emitEffect", "getShareData", "assertValidFormFields", "fields", "seenNames", "field", "fieldName", "assertAppSecretsOnly", "FormFieldType", "EventSource", "DeletionReason", "CrowdControlLevel", "DistinguishType", "SubredditType", "SubredditRating", "SettingScope", "T_PREFIX", "flattenFormFieldValue", "value", "FormFieldType", "getFormValues", "results", "acc", "key", "val", "transformFormFields", "fields", "field", "transformStringField", "transformImageField", "transformParagraphField", "transformNumberField", "transformSelectField", "transformBooleanField", "transformGroupField", "FormFieldType", "_formKey", "getNextFormKey", "showForm", "formDefinition", "form", "assertValidFormFields", "transformFormFields", "response", "emitEffect", "getFormValues", "showToast", "textOrToast", "toast", "emitEffect", "WebViewImmersiveMode", "tokenParam", "getWebViewMode", "webViewMode", "requestExpandedMode", "event", "entry", "WebViewImmersiveMode", "emitModeEffect", "exitExpandedMode", "addWebViewModeListener", "_", "removeWebViewModeListener", "mode", "entryUrl", "url", "tokenParam", "emitEffect"]
7
7
  }
@@ -1,4 +1,4 @@
1
- import type { FormField } from './form-types.js';
1
+ import type { FormField } from '@devvit/shared';
2
2
  /**
3
3
  * Make sure that the form fields have unique names.
4
4
  *
@@ -1 +1 @@
1
- {"version":3,"file":"assert-valid-form-fields.d.ts","sourceRoot":"","sources":["../../../src/effects/helpers/assert-valid-form-fields.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAgB,MAAM,iBAAiB,CAAC;AAE/D;;;;;;GAMG;AACH,wBAAgB,qBAAqB,CACnC,MAAM,EAAE,SAAS,SAAS,EAAE,EAC5B,SAAS,GAAE,GAAG,CAAC,MAAM,CAAa,GACjC,IAAI,CAiBN;AAED,wBAAgB,oBAAoB,CAAC,MAAM,EAAE,SAAS,SAAS,EAAE,GAAG,IAAI,CAMvE"}
1
+ {"version":3,"file":"assert-valid-form-fields.d.ts","sourceRoot":"","sources":["../../../src/effects/helpers/assert-valid-form-fields.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAgB,MAAM,gBAAgB,CAAC;AAE9D;;;;;;GAMG;AACH,wBAAgB,qBAAqB,CACnC,MAAM,EAAE,SAAS,SAAS,EAAE,EAC5B,SAAS,GAAE,GAAG,CAAC,MAAM,CAAa,GACjC,IAAI,CAiBN;AAED,wBAAgB,oBAAoB,CAAC,MAAM,EAAE,SAAS,SAAS,EAAE,GAAG,IAAI,CAMvE"}
@@ -1,8 +1,4 @@
1
- import type { FieldConfig_Boolean, FieldConfig_Number, FieldConfig_Paragraph, FieldConfig_Selection, FieldConfig_Selection_Item, FieldConfig_String } from '@devvit/protos';
2
- import type { JsonObject } from '@devvit/shared-types/json.js';
3
- type Prettify<T> = {
4
- [K in keyof T]: T[K];
5
- };
1
+ import type { BooleanField, Form, FormField, FormFieldGroup, ImageField, NumberField, ParagraphField, SelectField, StringField } from '@devvit/shared';
6
2
  export type FormAction = 'CANCELED' | 'SUBMITTED';
7
3
  export type FormEffectResponse<T> = {
8
4
  action: 'CANCELED';
@@ -10,91 +6,6 @@ export type FormEffectResponse<T> = {
10
6
  action: 'SUBMITTED';
11
7
  values: T;
12
8
  };
13
- export type FormValues = JsonObject;
14
- export type BaseField<ValueType> = {
15
- /**
16
- * The name of the field. This will be used as the key in the `values` object
17
- * when the form is submitted.
18
- */
19
- name: string;
20
- /** The label of the field. This will be displayed to the user */
21
- label: string;
22
- /** An optional help text that will be displayed below the field */
23
- helpText?: string | undefined;
24
- /**
25
- * If true the field will be required and the user will not be able to submit
26
- * the form without filling it in.
27
- */
28
- required?: boolean | undefined;
29
- /** If true the field will be disabled */
30
- disabled?: boolean | undefined;
31
- /** The default value of the field */
32
- defaultValue?: ValueType | undefined;
33
- /**
34
- * This indicates whether the field (setting) is an app level or install level
35
- * setting. App setting values can be used by any installation.
36
- */
37
- scope?: SettingScopeType | undefined;
38
- };
39
- export type SettingScopeType = 'installation' | 'app';
40
- export declare enum SettingScope {
41
- Installation = "installation",
42
- App = "app"
43
- }
44
- /** A text field */
45
- export type StringField = Prettify<BaseField<string> & Omit<FieldConfig_String, 'minLength' | 'maxLength'> & {
46
- type: 'string';
47
- isSecret?: boolean;
48
- }>;
49
- /**
50
- * Allows a user to upload an image as part of submitting the form. The string value that's
51
- * given back is the URL of the image.
52
- * @experimental
53
- */
54
- export type ImageField = Omit<BaseField<string>, 'defaultValue'> & {
55
- type: 'image';
56
- };
57
- /** A paragraph or textarea field */
58
- export type ParagraphField = Prettify<BaseField<string> & Omit<FieldConfig_Paragraph, 'maxCharacters'> & {
59
- type: 'paragraph';
60
- }>;
61
- /** A number field */
62
- export type NumberField = Prettify<BaseField<number> & Omit<FieldConfig_Number, 'min' | 'max' | 'step'> & {
63
- type: 'number';
64
- }>;
65
- /** A boolean field displayed as a toggle */
66
- export type BooleanField = Prettify<Omit<BaseField<boolean>, 'required'> & FieldConfig_Boolean & {
67
- type: 'boolean';
68
- }>;
69
- /** A dropdown field that allows users to pick from a list of options */
70
- export type SelectField = Prettify<BaseField<string[]> & Omit<FieldConfig_Selection, 'choices' | 'renderAsList' | 'minSelections' | 'maxSelections'> & {
71
- type: 'select';
72
- options: FieldConfig_Selection_Item[];
73
- }>;
74
- /** A grouping of fields */
75
- export type FormFieldGroup = {
76
- type: 'group';
77
- /** The label of the group that will be displayed to the user */
78
- label: string;
79
- /** The fields that will be displayed in the group */
80
- fields: readonly FormField[];
81
- /** An optional help text that will be displayed below the group */
82
- helpText?: string | undefined;
83
- required?: never;
84
- };
85
- export type FormField = StringField | ImageField | ParagraphField | NumberField | BooleanField | SelectField | FormFieldGroup;
86
- export type Form = {
87
- /** The fields that will be displayed in the form */
88
- fields: readonly FormField[];
89
- /** An optional title for the form */
90
- title?: string;
91
- /** An optional description for the form */
92
- description?: string;
93
- /** An optional label for the submit button */
94
- acceptLabel?: string;
95
- /** An optional label for the cancel button */
96
- cancelLabel?: string;
97
- };
98
9
  /**
99
10
  * A function that returns a form. You can use this to dynamically generate a form.
100
11
  * @example
@@ -1 +1 @@
1
- {"version":3,"file":"form-types.d.ts","sourceRoot":"","sources":["../../../src/effects/helpers/form-types.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"form-types.d.ts","sourceRoot":"","sources":["../../../src/effects/helpers/form-types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,YAAY,EACZ,IAAI,EACJ,SAAS,EACT,cAAc,EACd,UAAU,EACV,WAAW,EACX,cAAc,EACd,WAAW,EACX,WAAW,EACZ,MAAM,gBAAgB,CAAC;AAExB,MAAM,MAAM,UAAU,GAAG,UAAU,GAAG,WAAW,CAAC;AAElD,MAAM,MAAM,kBAAkB,CAAC,CAAC,IAAI;IAAE,MAAM,EAAE,UAAU,CAAA;CAAE,GAAG;IAAE,MAAM,EAAE,WAAW,CAAC;IAAC,MAAM,EAAE,CAAC,CAAA;CAAE,CAAC;AAEhG;;;;;;;;;;;;;;;;KAgBK;AAEL,MAAM,MAAM,YAAY,CAAC,CAAC,SAAS;IAAE,CAAC,GAAG,EAAE,MAAM,GAAG,GAAG,CAAA;CAAE,GAAG;IAAE,CAAC,GAAG,EAAE,MAAM,GAAG,GAAG,CAAA;CAAE,IAAI,CACpF,IAAI,EAAE,CAAC,KACJ,IAAI,CAAC;AAEV,MAAM,MAAM,gBAAgB,CAAC,CAAC,SAAS,IAAI,GAAG,YAAY,GAAG,IAAI,GAAG,YAAY,IAC9E,sBAAsB,CAAC,CAAC,CAAC,SAAS,YAAY,GAAG,UAAU,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC;AAEjF;;;GAGG;AACH,KAAK,sBAAsB,CAAC,CAAC,SAAS,SAAS,SAAS,EAAE,IAAI,CAAC,SAAS,SAAS;IAC/E,MAAM,KAAK,SAAS,SAAS;IAC7B,GAAG,MAAM,IAAI,SAAS,SAAS,EAAE;CAClC,GACG,oBAAoB,CAAC,KAAK,CAAC,GAAG,sBAAsB,CAAC,IAAI,CAAC,GAE1D;IAAE,CAAC,GAAG,EAAE,MAAM,GAAG,GAAG,CAAA;CAAE,CAAC;AAE3B,gEAAgE;AAChE,KAAK,oBAAoB,CAAC,CAAC,SAAS,SAAS,IAAI,CAAC,SAAS,YAAY,GACnE;KAAG,CAAC,IAAI,CAAC,CAAC,MAAM,CAAC,GAAG,OAAO;CAAE,GAC7B,CAAC,SAAS,UAAU,GAAG,cAAc,GAAG,WAAW,GACjD,4BAA4B,CAAC,CAAC,EAAE,MAAM,CAAC,GACvC,CAAC,SAAS,WAAW,GACnB,4BAA4B,CAAC,CAAC,EAAE,MAAM,CAAC,GACvC,CAAC,SAAS,WAAW,GACnB;KAAG,CAAC,IAAI,CAAC,CAAC,MAAM,CAAC,GAAG,MAAM,EAAE;CAAE,GAC9B,CAAC,SAAS,cAAc,GACtB,sBAAsB,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,GACnC,KAAK,CAAC;AAElB;;;GAGG;AACH,KAAK,4BAA4B,CAC/B,CAAC,SAAS,UAAU,GAAG,cAAc,GAAG,WAAW,GAAG,WAAW,EACjE,CAAC,IACC,CAAC,SAAS;IAAE,QAAQ,EAAE,IAAI,CAAA;CAAE,GAAG;IAAE,YAAY,EAAE,OAAO,GAAG,MAAM,GAAG,MAAM,CAAA;CAAE,GAC1E;KAAG,CAAC,IAAI,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC;CAAE,GACvB;KAAG,CAAC,IAAI,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC;CAAE,CAAC"}
@@ -1,5 +1 @@
1
- export var SettingScope;
2
- (function (SettingScope) {
3
- SettingScope["Installation"] = "installation";
4
- SettingScope["App"] = "app";
5
- })(SettingScope || (SettingScope = {}));
1
+ export {};
@@ -1,6 +1,6 @@
1
- import type { FormFieldValue } from '@devvit/protos';
2
- import type { FormValues } from './form-types.js';
3
- export declare function getFormValues(results: {
1
+ import type { FormFieldValue } from '@devvit/protos/json/devvit/ui/form_builder/v1alpha/value.js';
2
+ import { type FormValues, type JsonObject } from '@devvit/shared';
3
+ export declare function getFormValues<T extends JsonObject>(results: {
4
4
  [key: string]: FormFieldValue;
5
- }): FormValues;
5
+ }): FormValues<T>;
6
6
  //# sourceMappingURL=get-form-values.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"get-form-values.d.ts","sourceRoot":"","sources":["../../../src/effects/helpers/get-form-values.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAiB,cAAc,EAAE,MAAM,gBAAgB,CAAC;AAEpE,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AA2BlD,wBAAgB,aAAa,CAAC,OAAO,EAAE;IAAE,CAAC,GAAG,EAAE,MAAM,GAAG,cAAc,CAAA;CAAE,GAAG,UAAU,CAMpF"}
1
+ {"version":3,"file":"get-form-values.d.ts","sourceRoot":"","sources":["../../../src/effects/helpers/get-form-values.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,6DAA6D,CAAC;AAClG,OAAO,EAAE,KAAK,UAAU,EAAE,KAAK,UAAU,EAAE,MAAM,gBAAgB,CAAC;AA2BlE,wBAAgB,aAAa,CAAC,CAAC,SAAS,UAAU,EAAE,OAAO,EAAE;IAC3D,CAAC,GAAG,EAAE,MAAM,GAAG,cAAc,CAAC;CAC/B,GAAG,UAAU,CAAC,CAAC,CAAC,CAMhB"}
@@ -1,17 +1,19 @@
1
+ import { FormFieldType } from '@devvit/protos/json/devvit/ui/form_builder/v1alpha/type.js';
2
+ import {} from '@devvit/shared';
1
3
  function flattenFormFieldValue(value) {
2
4
  switch (value.fieldType) {
3
- case 0:
5
+ case FormFieldType.STRING:
4
6
  return value.stringValue;
5
- case 7:
7
+ case FormFieldType.IMAGE:
6
8
  // the string value is the URL
7
9
  return value.stringValue;
8
- case 1:
10
+ case FormFieldType.PARAGRAPH:
9
11
  return value.stringValue;
10
- case 2:
12
+ case FormFieldType.NUMBER:
11
13
  return value.numberValue;
12
- case 3:
14
+ case FormFieldType.BOOLEAN:
13
15
  return value.boolValue;
14
- case 5:
16
+ case FormFieldType.SELECTION:
15
17
  return value.selectionValue?.values ?? [];
16
18
  default:
17
19
  return undefined;
@@ -1,6 +1,6 @@
1
- import type { Effect } from '@devvit/protos/json/devvit/ui/effects/v1alpha/effect.js';
1
+ import { type Effect } from '@devvit/protos/json/devvit/ui/effects/v1alpha/effect.js';
2
+ import type { Form } from '@devvit/shared';
2
3
  import type { DevvitGlobal } from '@devvit/shared-types/client/devvit-global.js';
3
- import type { Form } from './form-types.js';
4
4
  export declare const mockDevvit: Readonly<DevvitGlobal>;
5
5
  export declare const mockSubreddit: {
6
6
  readonly id: "t5_123";
@@ -1 +1 @@
1
- {"version":3,"file":"test-helpers.d.ts","sourceRoot":"","sources":["../../../src/effects/helpers/test-helpers.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAc,MAAM,yDAAyD,CAAC;AAClG,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,8CAA8C,CAAC;AAGjF,OAAO,KAAK,EAAE,IAAI,EAA4C,MAAM,iBAAiB,CAAC;AAItF,eAAO,MAAM,UAAU,EAAE,QAAQ,CAAC,YAAY,CAqB7C,CAAC;AAIF,eAAO,MAAM,aAAa;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAmDhB,CAAC;AAEX,eAAO,MAAM,QAAQ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAkCX,CAAC;AAEX,eAAO,MAAM,WAAW;;;;;;;;;;;;;;;;;;;;;;;;;CAyBd,CAAC;AAEX,eAAO,MAAM,QAAQ;;;;;;;;;;;;CAYX,CAAC;AAIX,eAAO,MAAM,mBAAmB,EAAE,QAAQ,CAAC,IAAI,CAY9C,CAAC;AAEF,eAAO,MAAM,qBAAqB,EAAE,QAAQ,CAAC,IAAI,CA2BhD,CAAC;AAEF,eAAO,MAAM,uBAAuB,GAAI,MAAM,QAAQ,CAAC,IAAI,CAAC,KAAG,MAyF7D,CAAC"}
1
+ {"version":3,"file":"test-helpers.d.ts","sourceRoot":"","sources":["../../../src/effects/helpers/test-helpers.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,MAAM,EAAc,MAAM,yDAAyD,CAAC;AAClG,OAAO,KAAK,EAAE,IAAI,EAA4C,MAAM,gBAAgB,CAAC;AACrF,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,8CAA8C,CAAC;AAKjF,eAAO,MAAM,UAAU,EAAE,QAAQ,CAAC,YAAY,CAqB7C,CAAC;AAIF,eAAO,MAAM,aAAa;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAmDhB,CAAC;AAEX,eAAO,MAAM,QAAQ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAkCX,CAAC;AAEX,eAAO,MAAM,WAAW;;;;;;;;;;;;;;;;;;;;;;;;;CAyBd,CAAC;AAEX,eAAO,MAAM,QAAQ;;;;;;;;;;;;CAYX,CAAC;AAIX,eAAO,MAAM,mBAAmB,EAAE,QAAQ,CAAC,IAAI,CAY9C,CAAC;AAEF,eAAO,MAAM,qBAAqB,EAAE,QAAQ,CAAC,IAAI,CA2BhD,CAAC;AAEF,eAAO,MAAM,uBAAuB,GAAI,MAAM,QAAQ,CAAC,IAAI,CAAC,KAAG,MAyF7D,CAAC"}
@@ -1,3 +1,4 @@
1
+ import { EffectType } from '@devvit/protos/json/devvit/ui/effects/v1alpha/effect.js';
1
2
  import { noWebbitToken } from '@devvit/shared-types/webbit.js';
2
3
  // Devvit mocks
3
4
  export const mockDevvit = {
@@ -274,5 +275,5 @@ export const expectedShowFormMessage = (form) => ({
274
275
  }),
275
276
  },
276
277
  },
277
- type: 3,
278
+ type: EffectType.EFFECT_SHOW_FORM,
278
279
  });
@@ -1,4 +1,4 @@
1
- import type { FormField as FormFieldProto } from '@devvit/protos';
2
- import type { FormField } from './form-types.js';
1
+ import type { FormField as FormFieldProto } from '@devvit/protos/json/devvit/ui/form_builder/v1alpha/field.js';
2
+ import { type FormField } from '@devvit/shared';
3
3
  export declare function transformFormFields(fields: readonly FormField[]): FormFieldProto[];
4
4
  //# sourceMappingURL=transform-form.d.ts.map
@@ -1 +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"}
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,EAAE,MAAM,6DAA6D,CAAC;AAE/G,OAAO,EAEL,KAAK,SAAS,EAOf,MAAM,gBAAgB,CAAC;AAKxB,wBAAgB,mBAAmB,CAAC,MAAM,EAAE,SAAS,SAAS,EAAE,GAAG,cAAc,EAAE,CAqBlF"}
@@ -1,3 +1,5 @@
1
+ import { FormFieldType } from '@devvit/protos/json/devvit/ui/form_builder/v1alpha/type.js';
2
+ import {} from '@devvit/shared';
1
3
  // This is a carbon copy of the transformFormFields function in the public-api package
2
4
  // We copy it here so that @devvit/client does not need to depend on public-api
3
5
  // Any changes to this function should be reflected in the public-api version
@@ -26,7 +28,7 @@ export function transformFormFields(fields) {
26
28
  function transformStringField(field) {
27
29
  return {
28
30
  defaultValue: {
29
- fieldType: 0,
31
+ fieldType: FormFieldType.STRING,
30
32
  stringValue: field.defaultValue,
31
33
  },
32
34
  disabled: field.disabled,
@@ -36,7 +38,7 @@ function transformStringField(field) {
36
38
  },
37
39
  },
38
40
  fieldId: field.name,
39
- fieldType: 0,
41
+ fieldType: FormFieldType.STRING,
40
42
  helpText: field.helpText,
41
43
  label: field.label,
42
44
  required: field.required,
@@ -47,7 +49,7 @@ function transformImageField(field) {
47
49
  return {
48
50
  disabled: field.disabled,
49
51
  fieldId: field.name,
50
- fieldType: 7,
52
+ fieldType: FormFieldType.IMAGE,
51
53
  helpText: field.helpText,
52
54
  label: field.label,
53
55
  required: field.required,
@@ -56,7 +58,7 @@ function transformImageField(field) {
56
58
  function transformParagraphField(field) {
57
59
  return {
58
60
  defaultValue: {
59
- fieldType: 1,
61
+ fieldType: FormFieldType.PARAGRAPH,
60
62
  stringValue: field.defaultValue,
61
63
  },
62
64
  disabled: field.disabled,
@@ -67,7 +69,7 @@ function transformParagraphField(field) {
67
69
  },
68
70
  },
69
71
  fieldId: field.name,
70
- fieldType: 1,
72
+ fieldType: FormFieldType.PARAGRAPH,
71
73
  helpText: field.helpText,
72
74
  label: field.label,
73
75
  required: field.required,
@@ -76,7 +78,7 @@ function transformParagraphField(field) {
76
78
  function transformNumberField(field) {
77
79
  return {
78
80
  defaultValue: {
79
- fieldType: 2,
81
+ fieldType: FormFieldType.NUMBER,
80
82
  numberValue: field.defaultValue,
81
83
  },
82
84
  disabled: field.disabled,
@@ -84,7 +86,7 @@ function transformNumberField(field) {
84
86
  numberConfig: {},
85
87
  },
86
88
  fieldId: field.name,
87
- fieldType: 2,
89
+ fieldType: FormFieldType.NUMBER,
88
90
  helpText: field.helpText,
89
91
  label: field.label,
90
92
  required: field.required,
@@ -93,7 +95,7 @@ function transformNumberField(field) {
93
95
  function transformSelectField(field) {
94
96
  return {
95
97
  defaultValue: {
96
- fieldType: 5,
98
+ fieldType: FormFieldType.SELECTION,
97
99
  selectionValue: {
98
100
  values: field.defaultValue ?? [],
99
101
  },
@@ -106,7 +108,7 @@ function transformSelectField(field) {
106
108
  },
107
109
  },
108
110
  fieldId: field.name,
109
- fieldType: 5,
111
+ fieldType: FormFieldType.SELECTION,
110
112
  helpText: field.helpText,
111
113
  label: field.label,
112
114
  required: field.required,
@@ -115,12 +117,12 @@ function transformSelectField(field) {
115
117
  function transformBooleanField(field) {
116
118
  return {
117
119
  defaultValue: {
118
- fieldType: 3,
120
+ fieldType: FormFieldType.BOOLEAN,
119
121
  boolValue: field.defaultValue,
120
122
  },
121
123
  disabled: field.disabled,
122
124
  fieldId: field.name,
123
- fieldType: 3,
125
+ fieldType: FormFieldType.BOOLEAN,
124
126
  helpText: field.helpText,
125
127
  label: field.label,
126
128
  };
@@ -128,7 +130,7 @@ function transformBooleanField(field) {
128
130
  function transformGroupField(field) {
129
131
  return {
130
132
  fieldId: '',
131
- fieldType: 6,
133
+ fieldType: FormFieldType.GROUP,
132
134
  fieldConfig: {
133
135
  groupConfig: {
134
136
  fields: transformFormFields(field.fields),
@@ -1,5 +1,5 @@
1
- import type { Form, FormToFormValues } from './helpers/form-types.js';
2
- import type { FormEffectResponse } from './helpers/form-types.js';
1
+ import type { Form } from '@devvit/shared';
2
+ import type { FormEffectResponse, FormToFormValues } from './helpers/form-types.js';
3
3
  /**
4
4
  * Opens a form in a modal.
5
5
  * Returns a promise that resolves with the form submission results.
@@ -1 +1 @@
1
- {"version":3,"file":"show-form.d.ts","sourceRoot":"","sources":["../../src/effects/show-form.ts"],"names":[],"mappings":"AAMA,OAAO,KAAK,EAAE,IAAI,EAAE,gBAAgB,EAAE,MAAM,yBAAyB,CAAC;AACtE,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,yBAAyB,CAAC;AAWlE;;;;;;;;;;GAUG;AACH,eAAO,MAAM,QAAQ,GAAU,KAAK,CAAC,CAAC,SAAS,IAAI,EACjD,gBAAgB,CAAC,KAChB,OAAO,CAAC,kBAAkB,CAAC,gBAAgB,CAAC,CAAC,CAAC,CAAC,CAgCjD,CAAC"}
1
+ {"version":3,"file":"show-form.d.ts","sourceRoot":"","sources":["../../src/effects/show-form.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,gBAAgB,CAAC;AAK3C,OAAO,KAAK,EAAE,kBAAkB,EAAE,gBAAgB,EAAE,MAAM,yBAAyB,CAAC;AAWpF;;;;;;;;;;GAUG;AACH,eAAO,MAAM,QAAQ,GAAU,KAAK,CAAC,CAAC,SAAS,IAAI,EACjD,gBAAgB,CAAC,KAChB,OAAO,CAAC,kBAAkB,CAAC,gBAAgB,CAAC,CAAC,CAAC,CAAC,CAgCjD,CAAC"}
package/index.d.ts CHANGED
@@ -1,4 +1,5 @@
1
1
  export * from './clientContext.js';
2
+ export * from './effects/helpers/form-types.js';
2
3
  export * from './effects/navigate-to.js';
3
4
  export * from './effects/run-as-user.js';
4
5
  export * from './effects/share.js';
package/index.d.ts.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,oBAAoB,CAAC;AACnC,cAAc,0BAA0B,CAAC;AACzC,cAAc,0BAA0B,CAAC;AACzC,cAAc,oBAAoB,CAAC;AACnC,cAAc,wBAAwB,CAAC;AACvC,cAAc,yBAAyB,CAAC;AACxC,cAAc,4BAA4B,CAAC;AAC3C,YAAY,EAAE,OAAO,EAAE,MAAM,+CAA+C,CAAC;AAC7E,cAAc,kCAAkC,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,oBAAoB,CAAC;AACnC,cAAc,iCAAiC,CAAC;AAChD,cAAc,0BAA0B,CAAC;AACzC,cAAc,0BAA0B,CAAC;AACzC,cAAc,oBAAoB,CAAC;AACnC,cAAc,wBAAwB,CAAC;AACvC,cAAc,yBAAyB,CAAC;AACxC,cAAc,4BAA4B,CAAC;AAC3C,YAAY,EAAE,OAAO,EAAE,MAAM,+CAA+C,CAAC;AAC7E,cAAc,kCAAkC,CAAC"}
package/index.js CHANGED
@@ -1,4 +1,5 @@
1
1
  export * from './clientContext.js';
2
+ export * from './effects/helpers/form-types.js';
2
3
  export * from './effects/navigate-to.js';
3
4
  export * from './effects/run-as-user.js';
4
5
  export * from './effects/share.js';
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@devvit/client",
3
- "version": "0.12.7-next-2025-12-15-22-14-35-6c217d0d4.0",
3
+ "version": "0.12.7-next-2025-12-16-01-25-33-548943dfa.0",
4
4
  "license": "BSD-3-Clause",
5
5
  "repository": {
6
6
  "type": "git",
@@ -33,14 +33,14 @@
33
33
  "test:unit-with-coverage": "vitest run --coverage"
34
34
  },
35
35
  "dependencies": {
36
- "@devvit/protos": "0.12.7-next-2025-12-15-22-14-35-6c217d0d4.0",
37
- "@devvit/shared": "0.12.7-next-2025-12-15-22-14-35-6c217d0d4.0",
38
- "@devvit/shared-types": "0.12.7-next-2025-12-15-22-14-35-6c217d0d4.0"
36
+ "@devvit/protos": "0.12.7-next-2025-12-16-01-25-33-548943dfa.0",
37
+ "@devvit/shared": "0.12.7-next-2025-12-16-01-25-33-548943dfa.0",
38
+ "@devvit/shared-types": "0.12.7-next-2025-12-16-01-25-33-548943dfa.0"
39
39
  },
40
40
  "devDependencies": {
41
41
  "@ampproject/filesize": "4.3.0",
42
- "@devvit/repo-tools": "0.12.7-next-2025-12-15-22-14-35-6c217d0d4.0",
43
- "@devvit/tsconfig": "0.12.7-next-2025-12-15-22-14-35-6c217d0d4.0",
42
+ "@devvit/repo-tools": "0.12.7-next-2025-12-16-01-25-33-548943dfa.0",
43
+ "@devvit/tsconfig": "0.12.7-next-2025-12-16-01-25-33-548943dfa.0",
44
44
  "esbuild": "0.25.9",
45
45
  "eslint": "9.11.1",
46
46
  "typescript": "5.8.3",
@@ -48,9 +48,9 @@
48
48
  },
49
49
  "filesize": {
50
50
  "dist/client.min.js": {
51
- "gzip": "3 KB",
52
- "none": "8 KB"
51
+ "gzip": "4 KB",
52
+ "none": "9 KB"
53
53
  }
54
54
  },
55
- "gitHead": "fcc618ff752a1a1bc60b1398a0a8eac5fd0a7628"
55
+ "gitHead": "bf6d4a1e497f8df6626f4b9495b15787bd6fb643"
56
56
  }