@devvit/shared-types 0.12.0-next-2025-04-30-5d2b49b36.0 → 0.12.0-next-2025-08-12-20-06-14-50f19bb3e.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (89) hide show
  1. package/AdsMetadata.d.ts +6 -0
  2. package/AdsMetadata.d.ts.map +1 -0
  3. package/AdsMetadata.js +5 -0
  4. package/Assets.d.ts +0 -2
  5. package/Assets.d.ts.map +1 -1
  6. package/Assets.js +0 -2
  7. package/CircuitBreaker.d.ts.map +1 -1
  8. package/Config.d.ts +3 -3
  9. package/Config.d.ts.map +1 -1
  10. package/ConfigImpl.d.ts +8 -8
  11. package/ConfigImpl.d.ts.map +1 -1
  12. package/ConfigImpl.js +22 -31
  13. package/Header.d.ts +1 -0
  14. package/Header.d.ts.map +1 -1
  15. package/Header.js +1 -0
  16. package/PostData.d.ts +8 -0
  17. package/PostData.d.ts.map +1 -0
  18. package/ProjectTemplateInfo.d.ts +21 -0
  19. package/ProjectTemplateInfo.d.ts.map +1 -0
  20. package/ProjectTemplateInfo.js +10 -0
  21. package/client/emit-effect.d.ts +24 -0
  22. package/client/emit-effect.d.ts.map +1 -0
  23. package/client/emit-effect.js +56 -0
  24. package/client/emit-effect.test.d.ts.map +1 -0
  25. package/client/share.d.ts +3 -0
  26. package/client/share.d.ts.map +1 -0
  27. package/client/share.js +2 -0
  28. package/constants.d.ts +9 -0
  29. package/constants.d.ts.map +1 -1
  30. package/constants.js +9 -0
  31. package/fetch-domains.d.ts +14 -0
  32. package/fetch-domains.d.ts.map +1 -0
  33. package/fetch-domains.js +42 -0
  34. package/fetch-domains.test.d.ts.map +1 -0
  35. package/isDevvitDependency.js +1 -1
  36. package/json.d.ts +12 -12
  37. package/package.json +18 -13
  38. package/richtext/index.d.ts +6 -0
  39. package/richtext/index.d.ts.map +1 -0
  40. package/richtext/index.js +1 -0
  41. package/schemas/config-file.v1.d.ts +272 -0
  42. package/schemas/config-file.v1.d.ts.map +1 -0
  43. package/schemas/config-file.v1.js +254 -0
  44. package/schemas/config-file.v1.json +683 -0
  45. package/schemas/config-file.v1.test.d.ts.map +1 -0
  46. package/schemas/constants.d.ts +4 -0
  47. package/schemas/constants.d.ts.map +1 -0
  48. package/schemas/constants.js +3 -0
  49. package/{payments/products.schema.json → schemas/products.json} +1 -1
  50. package/{payments/productSchemaJSONValidator.d.ts → schemas/productsSchemaJSONValidator.d.ts} +2 -2
  51. package/schemas/productsSchemaJSONValidator.d.ts.map +1 -0
  52. package/{payments/productSchemaJSONValidator.js → schemas/productsSchemaJSONValidator.js} +1 -1
  53. package/schemas/productsSchemaJSONValidator.test.d.ts.map +1 -0
  54. package/server/get-devvit-config.d.ts +7 -0
  55. package/server/get-devvit-config.d.ts.map +1 -0
  56. package/server/get-devvit-config.js +10 -0
  57. package/shared/devvit-worker-global.d.ts +47 -0
  58. package/shared/devvit-worker-global.d.ts.map +1 -0
  59. package/shared/devvit-worker-global.js +7 -0
  60. package/{forms/types.d.ts → shared/form.d.ts} +16 -72
  61. package/shared/form.d.ts.map +1 -0
  62. package/tid.d.ts +26 -32
  63. package/tid.d.ts.map +1 -1
  64. package/tid.js +43 -62
  65. package/web-view-scripts-constants.d.ts +14 -0
  66. package/web-view-scripts-constants.d.ts.map +1 -0
  67. package/web-view-scripts-constants.js +13 -0
  68. package/forms/assertValidFormFields.d.ts +0 -11
  69. package/forms/assertValidFormFields.d.ts.map +0 -1
  70. package/forms/assertValidFormFields.js +0 -29
  71. package/forms/assertValidFormFields.test.d.ts.map +0 -1
  72. package/forms/getFormValues.d.ts +0 -6
  73. package/forms/getFormValues.d.ts.map +0 -1
  74. package/forms/getFormValues.js +0 -31
  75. package/forms/getFormValues.test.d.ts.map +0 -1
  76. package/forms/transformForm.d.ts +0 -4
  77. package/forms/transformForm.d.ts.map +0 -1
  78. package/forms/transformForm.js +0 -141
  79. package/forms/transformForm.test.d.ts.map +0 -1
  80. package/forms/types.d.ts.map +0 -1
  81. package/index.d.ts +0 -2
  82. package/index.d.ts.map +0 -1
  83. package/payments/index.d.ts +0 -4
  84. package/payments/index.d.ts.map +0 -1
  85. package/payments/index.js +0 -3
  86. package/payments/productSchemaJSONValidator.d.ts.map +0 -1
  87. package/payments/productSchemaJSONValidator.test.d.ts.map +0 -1
  88. /package/{index.js → PostData.js} +0 -0
  89. /package/{forms/types.js → shared/form.js} +0 -0
package/package.json CHANGED
@@ -1,37 +1,45 @@
1
1
  {
2
2
  "name": "@devvit/shared-types",
3
- "version": "0.12.0-next-2025-04-30-5d2b49b36.0",
3
+ "version": "0.12.0-next-2025-08-12-20-06-14-50f19bb3e.0",
4
4
  "license": "BSD-3-Clause",
5
5
  "repository": {
6
6
  "type": "git",
7
7
  "url": "https://developers.reddit.com/"
8
8
  },
9
9
  "type": "module",
10
- "main": "./index.js",
10
+ "exports": {
11
+ ".": "./index.js",
12
+ "./package.json": "./package.json",
13
+ "./*": "./*"
14
+ },
15
+ "main": "./dist/index.js",
16
+ "files": [
17
+ "**"
18
+ ],
11
19
  "scripts": {
12
- "build": "tsc && yarn postbuild:copy-payments-schema",
20
+ "build": "tsc && yarn postbuild:copy-schemas",
13
21
  "clean": "rm -rf .turbo coverage dist",
14
22
  "clobber": "yarn clean && rm -rf node_modules",
15
23
  "dev": "tsc -w",
16
24
  "dev:build": "chokidar ./src --command 'yarn build && echo \"BUILD COMPLETE\"'",
17
25
  "lint": "redlint .",
18
26
  "lint:fix": "yarn lint --fix",
19
- "postbuild:copy-payments-schema": "cp -a -f ./src/payments/products.schema.json ./dist/payments",
27
+ "postbuild:copy-schemas": "cp -af src/schemas/*.json dist/schemas/",
20
28
  "prepublishOnly": "publish-package-json",
21
29
  "test": "yarn test:unit && yarn test:types",
22
30
  "test:types": "tsc --noEmit",
23
31
  "test:unit": "vitest run",
24
32
  "test:unit-with-coverage": "vitest run --coverage"
25
33
  },
26
- "types": "./index.d.ts",
34
+ "types": "./dist/index.d.ts",
27
35
  "dependencies": {
28
- "@devvit/protos": "0.12.0-next-2025-04-30-5d2b49b36.0",
36
+ "@devvit/protos": "0.12.0-next-2025-08-12-20-06-14-50f19bb3e.0",
29
37
  "jsonschema": "1.4.1",
30
38
  "uuid": "9.0.0"
31
39
  },
32
40
  "devDependencies": {
33
- "@devvit/repo-tools": "0.12.0-next-2025-04-30-5d2b49b36.0",
34
- "@devvit/tsconfig": "0.12.0-next-2025-04-30-5d2b49b36.0",
41
+ "@devvit/repo-tools": "0.12.0-next-2025-08-12-20-06-14-50f19bb3e.0",
42
+ "@devvit/tsconfig": "0.12.0-next-2025-08-12-20-06-14-50f19bb3e.0",
35
43
  "@types/redis-mock": "0.17.1",
36
44
  "@types/uuid": "9.0.0",
37
45
  "chokidar-cli": "3.0.0",
@@ -39,12 +47,9 @@
39
47
  "lit": "2.5.0",
40
48
  "redis": "4.6.6",
41
49
  "redis-mock": "0.56.3",
42
- "typescript": "5.3.2",
50
+ "typescript": "5.8.3",
43
51
  "vitest": "1.6.1"
44
52
  },
45
- "publishConfig": {
46
- "directory": "dist"
47
- },
48
53
  "source": "./src/index.ts",
49
- "gitHead": "845a931ef7e1b77a8c1163dfd7dc394c73050098"
54
+ "gitHead": "1a536f955bd384f91072b4e48447457fdf7da4af"
50
55
  }
@@ -0,0 +1,6 @@
1
+ export type * from './containers.js';
2
+ export type * from './contexts.js';
3
+ export type * from './options.js';
4
+ export * from './RichTextBuilder.js';
5
+ export type * from './types.js';
6
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/richtext/index.ts"],"names":[],"mappings":"AAAA,mBAAmB,iBAAiB,CAAC;AACrC,mBAAmB,eAAe,CAAC;AAEnC,mBAAmB,cAAc,CAAC;AAClC,cAAc,sBAAsB,CAAC;AACrC,mBAAmB,YAAY,CAAC"}
@@ -0,0 +1 @@
1
+ export * from './RichTextBuilder.js';
@@ -0,0 +1,272 @@
1
+ /**
2
+ * Warning: this file is not isomorphic. Do not functionally import this file
3
+ * from client code.
4
+ */
5
+ import { Scope } from '@devvit/protos';
6
+ import type { JsonObject, JsonValue } from '../json.js';
7
+ /**
8
+ * devvit.json with defaults. See config-file.v1.json schema. Schema is assumed
9
+ * to be v1.
10
+ */
11
+ export type AppConfig = {
12
+ schema: 'v1';
13
+ name: string;
14
+ media?: {
15
+ dir: string;
16
+ };
17
+ permissions: AppPermissionConfig;
18
+ post?: AppPostConfig;
19
+ server?: AppServerConfig;
20
+ triggers?: AppTriggersConfig;
21
+ blocks?: AppBlocksConfig;
22
+ dev?: AppDevConfig;
23
+ menu?: AppMenuConfig;
24
+ scheduler?: AppSchedulerConfig;
25
+ settings?: AppSettingsConfig;
26
+ forms?: AppFormsConfig;
27
+ marketingAssets?: AppMarketingAssetsConfig;
28
+ /** The original config as parsed. Used for writebacks. */
29
+ json: AppConfigJson;
30
+ };
31
+ export type AppBlocksConfig = {
32
+ entry: string;
33
+ };
34
+ /** Describes plugin usage. */
35
+ export type AppPermissionConfig = {
36
+ http: {
37
+ enable: boolean;
38
+ domains: string[];
39
+ };
40
+ media: boolean;
41
+ menu: boolean;
42
+ payments: boolean;
43
+ realtime: boolean;
44
+ redis: boolean;
45
+ reddit: {
46
+ enable: boolean;
47
+ scope: AppScopeConfig;
48
+ asUser: Scope[];
49
+ };
50
+ settings: boolean;
51
+ triggers: boolean;
52
+ };
53
+ export type AppPostConfig = {
54
+ dir: string;
55
+ entrypoints: AppPostEntrypointsConfig;
56
+ };
57
+ export type AppPostEntrypointsConfig = {
58
+ [name: string]: AppPostEntrypointConfig;
59
+ default: AppPostEntrypointConfig;
60
+ };
61
+ export type AppPostEntrypointConfig = {
62
+ entry: string;
63
+ name: string;
64
+ height: AppPostHeightConfig;
65
+ };
66
+ export type AppPostHeightConfig = 'regular' | 'tall';
67
+ export type AppScopeConfig = 'user' | 'moderator';
68
+ export type AppServerConfig = {
69
+ dir: string;
70
+ entry: string;
71
+ };
72
+ /**
73
+ * Keys are assumed to have the format of `on${keyof TriggerEventType}` in
74
+ * blocks.template.tsx.
75
+ */
76
+ export type AppTriggersConfig = {
77
+ onAppInstall?: string;
78
+ onAppUpgrade?: string;
79
+ onAutomoderatorFilterComment?: string;
80
+ onAutomoderatorFilterPost?: string;
81
+ onCommentCreate?: string;
82
+ onCommentDelete?: string;
83
+ onCommentReport?: string;
84
+ onCommentSubmit?: string;
85
+ onCommentUpdate?: string;
86
+ onModAction?: string;
87
+ onModMail?: string;
88
+ onPostCreate?: string;
89
+ onPostDelete?: string;
90
+ onPostFlairUpdate?: string;
91
+ onPostNsfwUpdate?: string;
92
+ onPostReport?: string;
93
+ onPostSpoilerUpdate?: string;
94
+ onPostSubmit?: string;
95
+ onPostUpdate?: string;
96
+ };
97
+ export type AppMenuUserTypeConfig = 'moderator' | 'user';
98
+ export type AppMenuLocationConfig = 'comment' | 'post' | 'subreddit';
99
+ export type AppMenuPostFilterConfig = 'currentApp' | 'none';
100
+ export type AppMenuItemConfig = {
101
+ label: string;
102
+ description: string;
103
+ forUserType: AppMenuUserTypeConfig;
104
+ location: AppMenuLocationConfig[];
105
+ endpoint: string;
106
+ postFilter: AppMenuPostFilterConfig;
107
+ };
108
+ export type AppMenuConfig = {
109
+ items: AppMenuItemConfig[];
110
+ };
111
+ export type AppFormsConfig = {
112
+ [formName: string]: string;
113
+ };
114
+ export type AppMarketingAssetsConfig = {
115
+ icon?: string;
116
+ };
117
+ export type AppDevConfig = {
118
+ subreddit?: string;
119
+ };
120
+ export type AppSchedulerConfig = {
121
+ tasks: {
122
+ [name: string]: AppSchedulerTaskConfig;
123
+ };
124
+ };
125
+ export type AppSchedulerTaskConfig = {
126
+ endpoint: string;
127
+ cron?: string;
128
+ data?: JsonObject;
129
+ };
130
+ export type AppSettingsConfig = {
131
+ global?: {
132
+ [name: string]: AppSettingConfig;
133
+ };
134
+ subreddit?: {
135
+ [name: string]: AppSettingConfig;
136
+ };
137
+ };
138
+ export type AppSettingConfig = AppStringSettingConfig | AppParagraphSettingConfig | AppNumberSettingConfig | AppBooleanSettingConfig | AppSelectSettingConfig | AppMultiSelectSettingConfig;
139
+ export type AppBaseSettingConfig = {
140
+ name: string;
141
+ label: string;
142
+ helpText?: string;
143
+ validationEndpoint?: string;
144
+ };
145
+ export type AppStringSettingConfig = AppBaseSettingConfig & {
146
+ type: 'string';
147
+ placeholder?: string;
148
+ defaultValue?: string;
149
+ isSecret?: boolean;
150
+ };
151
+ export type AppParagraphSettingConfig = AppBaseSettingConfig & {
152
+ type: 'paragraph';
153
+ placeholder?: string;
154
+ defaultValue?: string;
155
+ };
156
+ export type AppNumberSettingConfig = AppBaseSettingConfig & {
157
+ type: 'number';
158
+ defaultValue?: number;
159
+ };
160
+ export type AppBooleanSettingConfig = AppBaseSettingConfig & {
161
+ type: 'boolean';
162
+ defaultValue?: boolean;
163
+ };
164
+ export type AppSelectSettingConfig = AppBaseSettingConfig & {
165
+ type: 'select';
166
+ options: Array<{
167
+ label: string;
168
+ value: string;
169
+ }>;
170
+ defaultValue?: string;
171
+ };
172
+ export type AppMultiSelectSettingConfig = AppBaseSettingConfig & {
173
+ type: 'multiSelect';
174
+ options: Array<{
175
+ label: string;
176
+ value: string;
177
+ }>;
178
+ defaultValue?: string[];
179
+ };
180
+ /**
181
+ * https://transform.tools/json-schema-to-typescript
182
+ * @internal
183
+ */
184
+ export type AppConfigJson = {
185
+ $schema?: string;
186
+ name: string;
187
+ media?: {
188
+ dir?: string;
189
+ };
190
+ permissions?: {
191
+ http?: {
192
+ enable?: boolean;
193
+ domains?: string[];
194
+ };
195
+ media?: boolean;
196
+ payments?: boolean;
197
+ realtime?: boolean;
198
+ redis?: boolean;
199
+ reddit?: {
200
+ enable?: boolean;
201
+ scope?: AppScopeConfig;
202
+ asUser?: string[];
203
+ };
204
+ };
205
+ post?: {
206
+ dir?: string;
207
+ entrypoints?: {
208
+ [name: string]: AppPostEntrypointConfigJson;
209
+ } & {
210
+ default: Partial<AppPostEntrypointConfigJson>;
211
+ };
212
+ };
213
+ server?: {
214
+ dir?: string;
215
+ entry?: string;
216
+ };
217
+ triggers?: AppTriggersConfig;
218
+ blocks?: {
219
+ entry?: string;
220
+ menu?: {
221
+ enable?: boolean;
222
+ };
223
+ settings?: {
224
+ enable?: boolean;
225
+ };
226
+ };
227
+ menu?: {
228
+ items?: {
229
+ label: string;
230
+ description?: string;
231
+ forUserType: AppMenuUserTypeConfig;
232
+ location: AppMenuLocationConfig | AppMenuLocationConfig[];
233
+ endpoint: string;
234
+ postFilter: AppMenuPostFilterConfig;
235
+ }[];
236
+ };
237
+ forms?: {
238
+ [formName: string]: string;
239
+ };
240
+ dev?: {
241
+ subreddit?: string;
242
+ };
243
+ scheduler?: AppSchedulerConfigJson;
244
+ settings?: {
245
+ global?: {
246
+ [name: string]: AppSettingConfigJson;
247
+ };
248
+ subreddit?: {
249
+ [name: string]: AppSettingConfigJson;
250
+ };
251
+ };
252
+ marketingAssets?: {
253
+ icon?: string;
254
+ };
255
+ /** User data. */
256
+ [key: string]: JsonValue;
257
+ };
258
+ export type AppPostEntrypointConfigJson = {
259
+ entry: string;
260
+ height?: AppPostHeightConfig;
261
+ };
262
+ export type AppSchedulerConfigJson = {
263
+ tasks: {
264
+ [name: string]: AppSchedulerTaskConfig | string;
265
+ };
266
+ };
267
+ export type AppSettingConfigJson = Omit<AppStringSettingConfig, 'name'> | Omit<AppParagraphSettingConfig, 'name'> | Omit<AppNumberSettingConfig, 'name'> | Omit<AppBooleanSettingConfig, 'name'> | Omit<AppSelectSettingConfig, 'name'> | Omit<AppMultiSelectSettingConfig, 'name'>;
268
+ export declare function parseAppConfig(str: string, allowUninitializedConfig: boolean): AppConfig;
269
+ export declare function parseAppConfigJson(json: JsonValue, allowUninitializedConfig: boolean): AppConfig;
270
+ /** @internal */
271
+ export declare function validate(config: Readonly<AppConfig>): void;
272
+ //# sourceMappingURL=config-file.v1.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"config-file.v1.d.ts","sourceRoot":"","sources":["../../src/schemas/config-file.v1.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,254 @@
1
+ /**
2
+ * Warning: this file is not isomorphic. Do not functionally import this file
3
+ * from client code.
4
+ */
5
+ import { Scope, scopeFromJSON } from '@devvit/protos';
6
+ import jsonschema from 'jsonschema/lib/index.js';
7
+ import schema from './config-file.v1.json' with { type: 'json' };
8
+ import { defaultPostEntry, UNINITIALIZED_APP_NAME } from './constants.js';
9
+ export function parseAppConfig(str, allowUninitializedConfig) {
10
+ if (!str)
11
+ throw Error('config is empty');
12
+ let json;
13
+ try {
14
+ json = JSON.parse(str);
15
+ }
16
+ catch (err) {
17
+ throw Error(`cannot parse config JSON`, { cause: err });
18
+ }
19
+ return parseAppConfigJson(json, allowUninitializedConfig);
20
+ }
21
+ export function parseAppConfigJson(json, allowUninitializedConfig) {
22
+ const unitializedSchema = {
23
+ ...schema,
24
+ properties: {
25
+ ...schema.properties,
26
+ name: {
27
+ ...schema.properties.name,
28
+ pattern: `${schema.properties.name.pattern}|^${UNINITIALIZED_APP_NAME}$`,
29
+ },
30
+ },
31
+ };
32
+ const ret = jsonschema.validate(json, allowUninitializedConfig ? unitializedSchema : schema);
33
+ if (!ret.valid)
34
+ throw new Error(ret.errors
35
+ .map((err) => {
36
+ if (!err.path.length && err.name === 'anyOf' && /\[subschema \d\]/.test(err.stack))
37
+ return 'config requires property "post", "server", or "blocks".';
38
+ if (err.stack.includes('name does not match pattern'))
39
+ return err.stack
40
+ .replaceAll('instance.', '')
41
+ .concat('. Try running `npm create devvit` to fix your app name.');
42
+ return err.stack.replaceAll('instance.', '').replaceAll('instance', 'config');
43
+ })
44
+ .join('; '));
45
+ const instance = ret.instance;
46
+ if (instance.$schema != null && instance.$schema !== schema.$id)
47
+ console.warn(`Unknown schema "${instance.$schema}".`);
48
+ return AppConfig(instance);
49
+ }
50
+ // jsonschema only supports rewrite hooks but it's easier to update defaults
51
+ // after validation when the entire config is known. Eg,
52
+ // `config.permissions.http` has a different default if `config.server` is set.
53
+ //
54
+ // Ajv supports some default application but it seems like some features are
55
+ // still missing (https://github.com/ajv-validator/ajv/issues/1158). Even if the
56
+ // feature is added, we need the defaults in the properties for documentation
57
+ // and the same dynamic default adjustments as above are required.
58
+ function AppConfig(json) {
59
+ const partial = {
60
+ schema: 'v1', // Always assume v1 since that's all that's supported.
61
+ name: json.name,
62
+ json,
63
+ };
64
+ if (json.media)
65
+ partial.media = {
66
+ dir: json.media.dir ?? schema.properties.media.properties.dir.default,
67
+ };
68
+ if (json.post)
69
+ partial.post = AppPostConfig(json);
70
+ if (json.server)
71
+ partial.server = {
72
+ dir: json.server.dir ?? schema.properties.server.properties.dir.default,
73
+ entry: json.server.entry ?? schema.properties.server.properties.entry.default,
74
+ };
75
+ if (json.triggers && Object.keys(json.triggers).length)
76
+ partial.triggers = json.triggers;
77
+ if (json.blocks)
78
+ partial.blocks = AppBlocksConfig(json);
79
+ if (json.menu)
80
+ partial.menu = AppMenuConfig(json);
81
+ if (json.scheduler)
82
+ partial.scheduler = AppSchedulerConfig(json);
83
+ if (json.settings)
84
+ partial.settings = AppSettingsConfig(json);
85
+ if (json.forms)
86
+ partial.forms = json.forms;
87
+ if (json.marketingAssets)
88
+ partial.marketingAssets = json.marketingAssets;
89
+ if (json.dev) {
90
+ partial.dev = {};
91
+ if (json.dev.subreddit)
92
+ partial.dev.subreddit = json.dev.subreddit;
93
+ }
94
+ const config = { ...partial, permissions: AppPermissionConfig(json, partial) };
95
+ validate(config);
96
+ // Deep copy so schema is not mutated.
97
+ return structuredClone(config);
98
+ }
99
+ function AppSchedulerConfig(json) {
100
+ const appSchedulerConfig = { tasks: {} };
101
+ if (json.scheduler?.tasks) {
102
+ for (const [name, taskSpec] of Object.entries(json.scheduler.tasks)) {
103
+ if (typeof taskSpec === 'string') {
104
+ // If the task is a string, it is an endpoint.
105
+ appSchedulerConfig.tasks[name] = {
106
+ endpoint: taskSpec,
107
+ };
108
+ }
109
+ else {
110
+ // Otherwise, it is an object with an endpoint and optionally a cron.
111
+ appSchedulerConfig.tasks[name] = {
112
+ endpoint: taskSpec.endpoint,
113
+ ...(taskSpec.cron
114
+ ? { cron: taskSpec.cron, ...(taskSpec.data ? { data: taskSpec.data } : {}) }
115
+ : {}),
116
+ };
117
+ }
118
+ }
119
+ }
120
+ return appSchedulerConfig;
121
+ }
122
+ function AppPermissionConfig(json, partial) {
123
+ return {
124
+ http: {
125
+ enable: json.permissions?.http?.enable ??
126
+ (json.permissions?.http
127
+ ? schema.properties.permissions.properties.http.properties.enable.default
128
+ : false),
129
+ domains: json.permissions?.http?.domains ??
130
+ schema.properties.permissions.properties.http.properties.domains.default,
131
+ },
132
+ media: json.permissions?.media ?? schema.properties.permissions.properties.media.default,
133
+ menu: !!partial.menu?.items?.length ||
134
+ (json.blocks?.menu?.enable ??
135
+ (json.blocks ? schema.properties.blocks.properties.menu.properties.enable.default : false)),
136
+ payments: json.permissions?.payments ?? schema.properties.permissions.properties.payments.default,
137
+ realtime: json.permissions?.realtime ?? schema.properties.permissions.properties.realtime.default,
138
+ redis: json.permissions?.redis ??
139
+ // Menu items call addCSRFTokenToContext() which uses Redis.
140
+ (partial.menu?.items?.length
141
+ ? true
142
+ : partial.post
143
+ ? true
144
+ : schema.properties.permissions.properties.redis.default),
145
+ reddit: {
146
+ enable: json.permissions?.reddit?.enable ??
147
+ (partial.post
148
+ ? true
149
+ : json.permissions?.reddit
150
+ ? schema.properties.permissions.properties.reddit.properties.enable.default
151
+ : false),
152
+ scope: json.permissions?.reddit?.scope ??
153
+ schema.properties.permissions.properties.reddit.properties.scope
154
+ .default,
155
+ asUser: json.permissions?.reddit?.asUser?.map((x) => scopeFromJSON(x)) ??
156
+ schema.properties.permissions.properties.reddit.properties.asUser.default,
157
+ },
158
+ settings: json.blocks?.settings?.enable ??
159
+ (json.blocks
160
+ ? schema.properties.blocks.properties.settings.properties.enable.default
161
+ : false),
162
+ triggers: !!partial.triggers,
163
+ };
164
+ }
165
+ function AppPostConfig(json) {
166
+ const dir = json.post?.dir ?? schema.properties.post.properties.dir.default;
167
+ const defaultHeight = schema.$defs.Entrypoint.properties.height.default;
168
+ const entrypoints = {
169
+ [defaultPostEntry]: {
170
+ name: defaultPostEntry,
171
+ entry: json.post?.entrypoints?.default.entry ??
172
+ schema.properties.post.properties.entrypoints.properties.default.properties.entry.default,
173
+ height: json.post?.entrypoints?.default.height ?? defaultHeight,
174
+ },
175
+ };
176
+ for (const [name, pt] of Object.entries(json.post?.entrypoints ?? {})) {
177
+ if (name !== defaultPostEntry)
178
+ entrypoints[name] = {
179
+ name,
180
+ entry: pt.entry,
181
+ height: pt.height ?? defaultHeight,
182
+ };
183
+ }
184
+ return {
185
+ dir,
186
+ entrypoints,
187
+ };
188
+ }
189
+ function AppBlocksConfig(json) {
190
+ return {
191
+ entry: json.blocks?.entry ?? schema.properties.blocks.properties.entry.default,
192
+ };
193
+ }
194
+ function AppMenuConfig(json) {
195
+ const items = [];
196
+ for (const item of json.menu?.items ?? []) {
197
+ items.push({
198
+ label: item.label,
199
+ description: item.description ?? '',
200
+ forUserType: item.forUserType ?? 'moderator',
201
+ postFilter: item.postFilter ?? 'none',
202
+ location: Array.isArray(item.location) ? item.location : [item.location],
203
+ endpoint: item.endpoint,
204
+ });
205
+ }
206
+ return { items };
207
+ }
208
+ function AppSettingsConfig(json) {
209
+ const appSettingsConfig = {};
210
+ if (json.settings?.global) {
211
+ appSettingsConfig.global = {};
212
+ for (const [name, setting] of Object.entries(json.settings.global)) {
213
+ appSettingsConfig.global[name] = {
214
+ ...setting,
215
+ name: name,
216
+ };
217
+ }
218
+ }
219
+ if (json.settings?.subreddit) {
220
+ appSettingsConfig.subreddit = {};
221
+ for (const [name, setting] of Object.entries(json.settings.subreddit)) {
222
+ appSettingsConfig.subreddit[name] = {
223
+ ...setting,
224
+ name: name,
225
+ };
226
+ }
227
+ }
228
+ return appSettingsConfig;
229
+ }
230
+ /** @internal */
231
+ export function validate(config) {
232
+ const errs = [];
233
+ if (config.menu?.items?.length && !config.permissions.redis)
234
+ errs.push('`config.menu.items` requires `config.permissions.redis` to be enabled');
235
+ // If there are any select settings, their default values must be in the options,
236
+ // and if it's not a multi-select, the default value must be a single string.
237
+ const settingValues = [
238
+ ...Object.values(config.settings?.global ?? {}),
239
+ ...Object.values(config.settings?.subreddit ?? {}),
240
+ ];
241
+ for (const setting of settingValues) {
242
+ if (setting.type === 'select' && setting.defaultValue) {
243
+ if (!setting.options.some((option) => option.value === setting.defaultValue))
244
+ errs.push(`Setting "${setting.name}" default value "${setting.defaultValue}" is not in
245
+ options "${setting.options.map((option) => option.value).join(', ')}"`);
246
+ }
247
+ if (setting.type === 'multiSelect' && setting.defaultValue) {
248
+ if (!setting.defaultValue.every((value) => setting.options.some((option) => option.value === value)))
249
+ errs.push(`Setting "${setting.name}" default values "${setting.defaultValue.join(', ')}" are not in options "${setting.options.map((option) => option.value).join(', ')}"`);
250
+ }
251
+ }
252
+ if (errs.length)
253
+ throw Error(`${errs.join('; ')}.`);
254
+ }