@stackframe/stack-shared 2.8.25 → 2.8.27

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 (124) hide show
  1. package/CHANGELOG.md +12 -0
  2. package/dist/config/format.d.mts +20 -5
  3. package/dist/config/format.d.ts +20 -5
  4. package/dist/config/format.js +39 -14
  5. package/dist/config/format.js.map +1 -1
  6. package/dist/config/schema.d.mts +795 -317
  7. package/dist/config/schema.d.ts +795 -317
  8. package/dist/config/schema.js +471 -84
  9. package/dist/config/schema.js.map +1 -1
  10. package/dist/crud.d.mts +1 -0
  11. package/dist/crud.d.ts +1 -0
  12. package/dist/esm/config/format.js +37 -14
  13. package/dist/esm/config/format.js.map +1 -1
  14. package/dist/esm/config/schema.js +460 -80
  15. package/dist/esm/config/schema.js.map +1 -1
  16. package/dist/esm/helpers/emails.js +136 -30
  17. package/dist/esm/helpers/emails.js.map +1 -1
  18. package/dist/esm/interface/admin-interface.js +19 -29
  19. package/dist/esm/interface/admin-interface.js.map +1 -1
  20. package/dist/esm/known-errors.js +24 -1
  21. package/dist/esm/known-errors.js.map +1 -1
  22. package/dist/esm/schema-fields.js +92 -27
  23. package/dist/esm/schema-fields.js.map +1 -1
  24. package/dist/esm/utils/currencies.js +52 -0
  25. package/dist/esm/utils/currencies.js.map +1 -0
  26. package/dist/esm/utils/dates.js +55 -1
  27. package/dist/esm/utils/dates.js.map +1 -1
  28. package/dist/esm/utils/errors.js.map +1 -1
  29. package/dist/esm/utils/objects.js +2 -0
  30. package/dist/esm/utils/objects.js.map +1 -1
  31. package/dist/esm/utils/strings.js +4 -0
  32. package/dist/esm/utils/strings.js.map +1 -1
  33. package/dist/esm/utils/types.js +45 -0
  34. package/dist/esm/utils/types.js.map +1 -1
  35. package/dist/helpers/emails.d.mts +32 -6
  36. package/dist/helpers/emails.d.ts +32 -6
  37. package/dist/helpers/emails.js +138 -30
  38. package/dist/helpers/emails.js.map +1 -1
  39. package/dist/helpers/password.d.mts +1 -0
  40. package/dist/helpers/password.d.ts +1 -0
  41. package/dist/helpers/production-mode.d.mts +1 -0
  42. package/dist/helpers/production-mode.d.ts +1 -0
  43. package/dist/index.d.mts +2 -2
  44. package/dist/index.d.ts +2 -2
  45. package/dist/interface/admin-interface.d.mts +8 -8
  46. package/dist/interface/admin-interface.d.ts +8 -8
  47. package/dist/interface/admin-interface.js +19 -29
  48. package/dist/interface/admin-interface.js.map +1 -1
  49. package/dist/interface/client-interface.d.mts +1 -0
  50. package/dist/interface/client-interface.d.ts +1 -0
  51. package/dist/interface/crud/connected-accounts.d.mts +1 -0
  52. package/dist/interface/crud/connected-accounts.d.ts +1 -0
  53. package/dist/interface/crud/contact-channels.d.mts +1 -0
  54. package/dist/interface/crud/contact-channels.d.ts +1 -0
  55. package/dist/interface/crud/current-user.d.mts +1 -0
  56. package/dist/interface/crud/current-user.d.ts +1 -0
  57. package/dist/interface/crud/email-templates.d.mts +1 -0
  58. package/dist/interface/crud/email-templates.d.ts +1 -0
  59. package/dist/interface/crud/emails.d.mts +1 -0
  60. package/dist/interface/crud/emails.d.ts +1 -0
  61. package/dist/interface/crud/internal-api-keys.d.mts +1 -0
  62. package/dist/interface/crud/internal-api-keys.d.ts +1 -0
  63. package/dist/interface/crud/notification-preferences.d.mts +1 -0
  64. package/dist/interface/crud/notification-preferences.d.ts +1 -0
  65. package/dist/interface/crud/oauth-providers.d.mts +5 -4
  66. package/dist/interface/crud/oauth-providers.d.ts +5 -4
  67. package/dist/interface/crud/project-api-keys.d.mts +3 -2
  68. package/dist/interface/crud/project-api-keys.d.ts +3 -2
  69. package/dist/interface/crud/project-permissions.d.mts +1 -0
  70. package/dist/interface/crud/project-permissions.d.ts +1 -0
  71. package/dist/interface/crud/projects.d.mts +8 -7
  72. package/dist/interface/crud/projects.d.ts +8 -7
  73. package/dist/interface/crud/sessions.d.mts +1 -0
  74. package/dist/interface/crud/sessions.d.ts +1 -0
  75. package/dist/interface/crud/svix-token.d.mts +1 -0
  76. package/dist/interface/crud/svix-token.d.ts +1 -0
  77. package/dist/interface/crud/team-invitation-details.d.mts +1 -0
  78. package/dist/interface/crud/team-invitation-details.d.ts +1 -0
  79. package/dist/interface/crud/team-invitation.d.mts +1 -0
  80. package/dist/interface/crud/team-invitation.d.ts +1 -0
  81. package/dist/interface/crud/team-member-profiles.d.mts +1 -0
  82. package/dist/interface/crud/team-member-profiles.d.ts +1 -0
  83. package/dist/interface/crud/team-memberships.d.mts +1 -0
  84. package/dist/interface/crud/team-memberships.d.ts +1 -0
  85. package/dist/interface/crud/team-permissions.d.mts +1 -0
  86. package/dist/interface/crud/team-permissions.d.ts +1 -0
  87. package/dist/interface/crud/teams.d.mts +1 -0
  88. package/dist/interface/crud/teams.d.ts +1 -0
  89. package/dist/interface/crud/users.d.mts +1 -0
  90. package/dist/interface/crud/users.d.ts +1 -0
  91. package/dist/interface/server-interface.d.mts +1 -0
  92. package/dist/interface/server-interface.d.ts +1 -0
  93. package/dist/known-errors.d.mts +6 -0
  94. package/dist/known-errors.d.ts +6 -0
  95. package/dist/known-errors.js +24 -1
  96. package/dist/known-errors.js.map +1 -1
  97. package/dist/schema-fields.d.mts +39 -8
  98. package/dist/schema-fields.d.ts +39 -8
  99. package/dist/schema-fields.js +101 -27
  100. package/dist/schema-fields.js.map +1 -1
  101. package/dist/utils/currencies.d.mts +39 -0
  102. package/dist/utils/currencies.d.ts +39 -0
  103. package/dist/utils/currencies.js +78 -0
  104. package/dist/utils/currencies.js.map +1 -0
  105. package/dist/utils/dates.d.mts +5 -1
  106. package/dist/utils/dates.d.ts +5 -1
  107. package/dist/utils/dates.js +58 -2
  108. package/dist/utils/dates.js.map +1 -1
  109. package/dist/utils/errors.d.mts +9 -0
  110. package/dist/utils/errors.d.ts +9 -0
  111. package/dist/utils/errors.js.map +1 -1
  112. package/dist/utils/objects.d.mts +23 -8
  113. package/dist/utils/objects.d.ts +23 -8
  114. package/dist/utils/objects.js +2 -0
  115. package/dist/utils/objects.js.map +1 -1
  116. package/dist/utils/strings.d.mts +3 -1
  117. package/dist/utils/strings.d.ts +3 -1
  118. package/dist/utils/strings.js +5 -0
  119. package/dist/utils/strings.js.map +1 -1
  120. package/dist/utils/types.d.mts +73 -2
  121. package/dist/utils/types.d.ts +73 -2
  122. package/dist/utils/types.js +54 -0
  123. package/dist/utils/types.js.map +1 -1
  124. package/package.json +1 -1
@@ -30,124 +30,143 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
30
30
  // src/config/schema.ts
31
31
  var schema_exports = {};
32
32
  __export(schema_exports, {
33
- applyDefaults: () => applyDefaults,
34
- branchConfigDefaults: () => branchConfigDefaults,
33
+ applyBranchDefaults: () => applyBranchDefaults,
34
+ applyEnvironmentDefaults: () => applyEnvironmentDefaults,
35
+ applyOrganizationDefaults: () => applyOrganizationDefaults,
36
+ applyProjectDefaults: () => applyProjectDefaults,
37
+ assertNoConfigOverrideErrors: () => assertNoConfigOverrideErrors,
35
38
  branchConfigSchema: () => branchConfigSchema,
36
39
  configLevels: () => configLevels,
37
- environmentConfigDefaults: () => environmentConfigDefaults,
38
40
  environmentConfigSchema: () => environmentConfigSchema,
39
- organizationConfigDefaults: () => organizationConfigDefaults,
41
+ getConfigOverrideErrors: () => getConfigOverrideErrors,
42
+ getIncompleteConfigWarnings: () => getIncompleteConfigWarnings,
43
+ migrateConfigOverride: () => migrateConfigOverride,
40
44
  organizationConfigSchema: () => organizationConfigSchema,
41
- projectConfigDefaults: () => projectConfigDefaults,
42
- projectConfigSchema: () => projectConfigSchema
45
+ projectConfigSchema: () => projectConfigSchema,
46
+ sanitizeBranchConfig: () => sanitizeBranchConfig,
47
+ sanitizeEnvironmentConfig: () => sanitizeEnvironmentConfig,
48
+ sanitizeOrganizationConfig: () => sanitizeOrganizationConfig,
49
+ sanitizeProjectConfig: () => sanitizeProjectConfig
43
50
  });
44
51
  module.exports = __toCommonJS(schema_exports);
52
+ var yup = __toESM(require("yup"));
53
+ var import_emails = require("../helpers/emails.js");
45
54
  var schemaFields = __toESM(require("../schema-fields.js"));
46
55
  var import_schema_fields = require("../schema-fields.js");
56
+ var import_arrays = require("../utils/arrays.js");
57
+ var import_errors = require("../utils/errors.js");
47
58
  var import_oauth = require("../utils/oauth.js");
48
59
  var import_objects = require("../utils/objects.js");
49
- var import_emails = require("../helpers/emails.js");
60
+ var import_results = require("../utils/results.js");
61
+ var import_types = require("../utils/types.js");
62
+ var import_format = require("./format.js");
50
63
  var configLevels = ["project", "branch", "environment", "organization"];
51
64
  var permissionRegex = /^\$?[a-z0-9_:]+$/;
52
65
  var customPermissionRegex = /^[a-z0-9_:]+$/;
66
+ function canNoLongerBeOverridden(schema, keys) {
67
+ const notOmitted = schema.concat((0, import_schema_fields.yupObject)(
68
+ Object.fromEntries(keys.map((key) => [key, schema.getNested(key).meta({ stackConfigCanNoLongerBeOverridden: true })]))
69
+ ));
70
+ return notOmitted;
71
+ }
53
72
  var projectConfigSchema = (0, import_schema_fields.yupObject)({
54
73
  sourceOfTruth: (0, import_schema_fields.yupUnion)(
55
74
  (0, import_schema_fields.yupObject)({
56
- type: (0, import_schema_fields.yupString)().oneOf(["hosted"]).optional()
57
- }).defined(),
75
+ type: (0, import_schema_fields.yupString)().oneOf(["hosted"]).defined()
76
+ }),
58
77
  (0, import_schema_fields.yupObject)({
59
- type: (0, import_schema_fields.yupString)().oneOf(["neon"]).optional(),
78
+ type: (0, import_schema_fields.yupString)().oneOf(["neon"]).defined(),
60
79
  connectionStrings: (0, import_schema_fields.yupRecord)(
61
80
  (0, import_schema_fields.yupString)().defined(),
62
81
  (0, import_schema_fields.yupString)().defined()
63
82
  ).defined()
64
- }).defined(),
83
+ }),
65
84
  (0, import_schema_fields.yupObject)({
66
- type: (0, import_schema_fields.yupString)().oneOf(["postgres"]).optional(),
85
+ type: (0, import_schema_fields.yupString)().oneOf(["postgres"]).defined(),
67
86
  connectionString: (0, import_schema_fields.yupString)().defined()
68
- }).defined()
69
- ).optional()
87
+ })
88
+ )
70
89
  });
71
90
  var branchRbacDefaultPermissions = (0, import_schema_fields.yupRecord)(
72
- (0, import_schema_fields.yupString)().optional().matches(permissionRegex),
91
+ (0, import_schema_fields.yupString)().matches(permissionRegex),
73
92
  (0, import_schema_fields.yupBoolean)().isTrue().optional()
74
- ).optional();
93
+ );
75
94
  var branchRbacSchema = (0, import_schema_fields.yupObject)({
76
95
  permissions: (0, import_schema_fields.yupRecord)(
77
- (0, import_schema_fields.yupString)().optional().matches(customPermissionRegex),
96
+ (0, import_schema_fields.yupString)().matches(customPermissionRegex),
78
97
  (0, import_schema_fields.yupObject)({
79
98
  description: (0, import_schema_fields.yupString)().optional(),
80
99
  scope: (0, import_schema_fields.yupString)().oneOf(["team", "project"]).optional(),
81
100
  containedPermissionIds: (0, import_schema_fields.yupRecord)(
82
- (0, import_schema_fields.yupString)().optional().matches(permissionRegex),
101
+ (0, import_schema_fields.yupString)().matches(permissionRegex),
83
102
  (0, import_schema_fields.yupBoolean)().isTrue().optional()
84
103
  ).optional()
85
104
  }).optional()
86
- ).optional(),
105
+ ),
87
106
  defaultPermissions: (0, import_schema_fields.yupObject)({
88
107
  teamCreator: branchRbacDefaultPermissions,
89
108
  teamMember: branchRbacDefaultPermissions,
90
109
  signUp: branchRbacDefaultPermissions
91
- }).optional()
92
- }).optional();
110
+ })
111
+ });
93
112
  var branchApiKeysSchema = (0, import_schema_fields.yupObject)({
94
113
  enabled: (0, import_schema_fields.yupObject)({
95
- team: (0, import_schema_fields.yupBoolean)().optional(),
96
- user: (0, import_schema_fields.yupBoolean)().optional()
97
- }).optional()
98
- }).optional();
114
+ team: (0, import_schema_fields.yupBoolean)(),
115
+ user: (0, import_schema_fields.yupBoolean)()
116
+ })
117
+ });
99
118
  var branchAuthSchema = (0, import_schema_fields.yupObject)({
100
- allowSignUp: (0, import_schema_fields.yupBoolean)().optional(),
119
+ allowSignUp: (0, import_schema_fields.yupBoolean)(),
101
120
  password: (0, import_schema_fields.yupObject)({
102
- allowSignIn: (0, import_schema_fields.yupBoolean)().optional()
103
- }).optional(),
121
+ allowSignIn: (0, import_schema_fields.yupBoolean)()
122
+ }),
104
123
  otp: (0, import_schema_fields.yupObject)({
105
- allowSignIn: (0, import_schema_fields.yupBoolean)().optional()
106
- }).optional(),
124
+ allowSignIn: (0, import_schema_fields.yupBoolean)()
125
+ }),
107
126
  passkey: (0, import_schema_fields.yupObject)({
108
- allowSignIn: (0, import_schema_fields.yupBoolean)().optional()
109
- }).optional(),
127
+ allowSignIn: (0, import_schema_fields.yupBoolean)()
128
+ }),
110
129
  oauth: (0, import_schema_fields.yupObject)({
111
130
  accountMergeStrategy: (0, import_schema_fields.yupString)().oneOf(["link_method", "raise_error", "allow_duplicates"]).optional(),
112
131
  providers: (0, import_schema_fields.yupRecord)(
113
- (0, import_schema_fields.yupString)().optional().matches(permissionRegex),
132
+ (0, import_schema_fields.yupString)().matches(permissionRegex),
114
133
  (0, import_schema_fields.yupObject)({
115
134
  type: (0, import_schema_fields.yupString)().oneOf(import_oauth.allProviders).optional(),
116
- allowSignIn: (0, import_schema_fields.yupBoolean)().optional(),
117
- allowConnectedAccounts: (0, import_schema_fields.yupBoolean)().optional()
118
- }).defined()
119
- ).optional()
120
- }).optional()
121
- }).optional();
135
+ allowSignIn: (0, import_schema_fields.yupBoolean)(),
136
+ allowConnectedAccounts: (0, import_schema_fields.yupBoolean)()
137
+ })
138
+ )
139
+ })
140
+ });
122
141
  var branchDomain = (0, import_schema_fields.yupObject)({
123
- allowLocalhost: (0, import_schema_fields.yupBoolean)().optional()
124
- }).optional();
125
- var branchConfigSchema = projectConfigSchema.omit(["sourceOfTruth"]).concat((0, import_schema_fields.yupObject)({
142
+ allowLocalhost: (0, import_schema_fields.yupBoolean)()
143
+ });
144
+ var branchConfigSchema = canNoLongerBeOverridden(projectConfigSchema, ["sourceOfTruth"]).concat((0, import_schema_fields.yupObject)({
126
145
  rbac: branchRbacSchema,
127
146
  teams: (0, import_schema_fields.yupObject)({
128
- createPersonalTeamOnSignUp: (0, import_schema_fields.yupBoolean)().optional(),
129
- allowClientTeamCreation: (0, import_schema_fields.yupBoolean)().optional()
130
- }).optional(),
147
+ createPersonalTeamOnSignUp: (0, import_schema_fields.yupBoolean)(),
148
+ allowClientTeamCreation: (0, import_schema_fields.yupBoolean)()
149
+ }),
131
150
  users: (0, import_schema_fields.yupObject)({
132
- allowClientUserDeletion: (0, import_schema_fields.yupBoolean)().optional()
133
- }).optional(),
151
+ allowClientUserDeletion: (0, import_schema_fields.yupBoolean)()
152
+ }),
134
153
  apiKeys: branchApiKeysSchema,
135
154
  domains: branchDomain,
136
155
  auth: branchAuthSchema,
137
156
  emails: (0, import_schema_fields.yupObject)({
138
- theme: schemaFields.emailThemeSchema.optional(),
139
- themeList: schemaFields.emailThemeListSchema.optional(),
140
- templateList: schemaFields.emailTemplateListSchema.optional()
157
+ selectedThemeId: schemaFields.emailThemeSchema,
158
+ themes: schemaFields.emailThemeListSchema,
159
+ templates: schemaFields.emailTemplateListSchema
141
160
  })
142
161
  }));
143
162
  var environmentConfigSchema = branchConfigSchema.concat((0, import_schema_fields.yupObject)({
144
163
  auth: branchConfigSchema.getNested("auth").concat((0, import_schema_fields.yupObject)({
145
164
  oauth: branchConfigSchema.getNested("auth").getNested("oauth").concat((0, import_schema_fields.yupObject)({
146
165
  providers: (0, import_schema_fields.yupRecord)(
147
- (0, import_schema_fields.yupString)().optional().matches(permissionRegex),
166
+ (0, import_schema_fields.yupString)().matches(permissionRegex),
148
167
  (0, import_schema_fields.yupObject)({
149
168
  type: (0, import_schema_fields.yupString)().oneOf(import_oauth.allProviders).optional(),
150
- isShared: (0, import_schema_fields.yupBoolean)().optional(),
169
+ isShared: (0, import_schema_fields.yupBoolean)(),
151
170
  clientId: schemaFields.oauthClientIdSchema.optional(),
152
171
  clientSecret: schemaFields.oauthClientSecretSchema.optional(),
153
172
  facebookConfigId: schemaFields.oauthFacebookConfigIdSchema.optional(),
@@ -155,12 +174,12 @@ var environmentConfigSchema = branchConfigSchema.concat((0, import_schema_fields
155
174
  allowSignIn: (0, import_schema_fields.yupBoolean)().optional(),
156
175
  allowConnectedAccounts: (0, import_schema_fields.yupBoolean)().optional()
157
176
  })
158
- ).optional()
159
- }).optional())
177
+ )
178
+ }))
160
179
  })),
161
180
  emails: branchConfigSchema.getNested("emails").concat((0, import_schema_fields.yupObject)({
162
181
  server: (0, import_schema_fields.yupObject)({
163
- isShared: (0, import_schema_fields.yupBoolean)().optional(),
182
+ isShared: (0, import_schema_fields.yupBoolean)(),
164
183
  host: schemaFields.emailHostSchema.optional().nonEmpty(),
165
184
  port: schemaFields.emailPortSchema.optional(),
166
185
  username: schemaFields.emailUsernameSchema.optional().nonEmpty(),
@@ -168,32 +187,103 @@ var environmentConfigSchema = branchConfigSchema.concat((0, import_schema_fields
168
187
  senderName: schemaFields.emailSenderNameSchema.optional().nonEmpty(),
169
188
  senderEmail: schemaFields.emailSenderEmailSchema.optional().nonEmpty()
170
189
  })
171
- }).optional()),
190
+ })),
172
191
  domains: branchConfigSchema.getNested("domains").concat((0, import_schema_fields.yupObject)({
173
192
  trustedDomains: (0, import_schema_fields.yupRecord)(
174
- (0, import_schema_fields.yupString)().uuid().optional(),
193
+ (0, import_schema_fields.yupString)(),
175
194
  (0, import_schema_fields.yupObject)({
176
- baseUrl: schemaFields.urlSchema.optional(),
177
- handlerPath: schemaFields.handlerPathSchema.optional()
195
+ baseUrl: schemaFields.urlSchema,
196
+ handlerPath: schemaFields.handlerPathSchema
178
197
  })
179
- ).optional()
198
+ )
180
199
  }))
181
200
  }));
182
201
  var organizationConfigSchema = environmentConfigSchema.concat((0, import_schema_fields.yupObject)({}));
202
+ function migrateConfigOverride(type, oldUnmigratedConfigOverride) {
203
+ const isBranchOrHigher = ["branch", "environment", "organization"].includes(type);
204
+ const isEnvironmentOrHigher = ["environment", "organization"].includes(type);
205
+ let res = oldUnmigratedConfigOverride;
206
+ if (isBranchOrHigher) {
207
+ res = renameProperty(res, "emails.theme", "emails.selectedThemeId");
208
+ }
209
+ if (isEnvironmentOrHigher) {
210
+ res = mapProperty(res, "domains.trustedDomains", (value) => {
211
+ if (Array.isArray(value)) {
212
+ return (0, import_objects.typedFromEntries)(value.map((v, i) => [`${i}`, v]));
213
+ }
214
+ return value;
215
+ });
216
+ }
217
+ if (isBranchOrHigher) {
218
+ res = removeProperty(res, "emails.themeList");
219
+ res = removeProperty(res, "emails.templateList");
220
+ }
221
+ if (type === "environment") {
222
+ res = removeProperty(res, "sourceOfTruth");
223
+ }
224
+ return res;
225
+ }
226
+ function removeProperty(obj, path) {
227
+ return mapProperty(obj, path, () => void 0);
228
+ }
229
+ function mapProperty(obj, path, mapper) {
230
+ const keyParts = path.split(".");
231
+ for (let i = 0; i < keyParts.length; i++) {
232
+ const pathPrefix = keyParts.slice(0, i).join(".");
233
+ const pathSuffix = keyParts.slice(i).join(".");
234
+ if ((0, import_objects.has)(obj, pathPrefix) && (0, import_objects.isObjectLike)((0, import_objects.get)(obj, pathPrefix))) {
235
+ const newValue = mapProperty((0, import_objects.get)(obj, pathPrefix), pathSuffix, mapper);
236
+ (0, import_objects.set)(obj, pathPrefix, newValue);
237
+ }
238
+ }
239
+ if ((0, import_objects.has)(obj, path)) {
240
+ const newValue = mapper((0, import_objects.get)(obj, path));
241
+ if (newValue !== void 0) {
242
+ (0, import_objects.set)(obj, path, newValue);
243
+ } else {
244
+ (0, import_objects.deleteKey)(obj, path);
245
+ }
246
+ }
247
+ return obj;
248
+ }
249
+ function renameProperty(obj, oldPath, newPath) {
250
+ const oldKeyParts = oldPath.split(".");
251
+ const newKeyParts = newPath.split(".");
252
+ if (!(0, import_arrays.isShallowEqual)(oldKeyParts.slice(0, -1), newKeyParts.slice(0, -1))) throw new import_errors.StackAssertionError(`oldPath and newPath must have the same prefix. Provided: ${oldPath} and ${newPath}`);
253
+ for (let i = 0; i < oldKeyParts.length; i++) {
254
+ const pathPrefix = oldKeyParts.slice(0, i).join(".");
255
+ const oldPathSuffix = oldKeyParts.slice(i).join(".");
256
+ const newPathSuffix = newKeyParts.slice(i).join(".");
257
+ if ((0, import_objects.has)(obj, pathPrefix) && (0, import_objects.isObjectLike)((0, import_objects.get)(obj, pathPrefix))) {
258
+ (0, import_objects.set)(obj, pathPrefix, renameProperty((0, import_objects.get)(obj, pathPrefix), oldPathSuffix, newPathSuffix));
259
+ }
260
+ }
261
+ if ((0, import_objects.has)(obj, oldPath)) {
262
+ (0, import_objects.set)(obj, newPath, (0, import_objects.get)(obj, oldPath));
263
+ (0, import_objects.deleteKey)(obj, oldPath);
264
+ }
265
+ return obj;
266
+ }
183
267
  var projectConfigDefaults = {
184
268
  sourceOfTruth: {
185
- type: "hosted"
269
+ type: "hosted",
270
+ connectionStrings: void 0,
271
+ connectionString: void 0
186
272
  }
187
273
  };
188
274
  var branchConfigDefaults = {};
189
275
  var environmentConfigDefaults = {};
190
276
  var organizationConfigDefaults = {
191
277
  rbac: {
192
- permissions: (key) => ({}),
278
+ permissions: (key) => ({
279
+ containedPermissionIds: (key2) => void 0,
280
+ description: void 0,
281
+ scope: void 0
282
+ }),
193
283
  defaultPermissions: {
194
- teamCreator: {},
195
- teamMember: {},
196
- signUp: {}
284
+ teamCreator: (key) => void 0,
285
+ teamMember: (key) => void 0,
286
+ signUp: (key) => void 0
197
287
  }
198
288
  },
199
289
  apiKeys: {
@@ -212,6 +302,7 @@ var organizationConfigDefaults = {
212
302
  domains: {
213
303
  allowLocalhost: false,
214
304
  trustedDomains: (key) => ({
305
+ baseUrl: void 0,
215
306
  handlerPath: "/handler"
216
307
  })
217
308
  },
@@ -229,46 +320,342 @@ var organizationConfigDefaults = {
229
320
  oauth: {
230
321
  accountMergeStrategy: "link_method",
231
322
  providers: (key) => ({
323
+ type: void 0,
232
324
  isShared: true,
233
325
  allowSignIn: false,
234
- allowConnectedAccounts: false
326
+ allowConnectedAccounts: false,
327
+ clientId: void 0,
328
+ clientSecret: void 0,
329
+ facebookConfigId: void 0,
330
+ microsoftTenantId: void 0
235
331
  })
236
332
  }
237
333
  },
238
334
  emails: {
239
335
  server: {
240
- isShared: true
336
+ isShared: true,
337
+ host: void 0,
338
+ port: void 0,
339
+ username: void 0,
340
+ password: void 0,
341
+ senderName: void 0,
342
+ senderEmail: void 0
241
343
  },
242
- theme: import_emails.DEFAULT_EMAIL_THEME_ID,
243
- themeList: import_emails.DEFAULT_EMAIL_THEMES,
244
- templateList: import_emails.DEFAULT_EMAIL_TEMPLATES
344
+ selectedThemeId: import_emails.DEFAULT_EMAIL_THEME_ID,
345
+ themes: (0, import_objects.typedAssign)((key) => ({
346
+ displayName: "Unnamed Theme",
347
+ tsxSource: "Error: Theme config is missing TypeScript source code."
348
+ }), import_emails.DEFAULT_EMAIL_THEMES),
349
+ templates: (0, import_objects.typedAssign)((key) => ({
350
+ displayName: "Unnamed Template",
351
+ tsxSource: "Error: Template config is missing TypeScript source code.",
352
+ themeId: void 0
353
+ }), import_emails.DEFAULT_EMAIL_TEMPLATES)
245
354
  }
246
355
  };
356
+ (0, import_types.typeAssertIs)()();
357
+ (0, import_types.typeAssertIs)()();
358
+ function deepReplaceFunctionsWithObjects(obj) {
359
+ return (0, import_objects.mapValues)({ ...obj }, (v) => (0, import_objects.isObjectLike)(v) ? deepReplaceFunctionsWithObjects(v) : v);
360
+ }
247
361
  function applyDefaults(defaults, config) {
248
- const res = typeof defaults === "function" ? {} : (0, import_objects.mapValues)(defaults, (v) => typeof v === "function" ? {} : typeof v === "object" ? applyDefaults(v, {}) : v);
249
- for (const [key, mergeValue] of Object.entries(config)) {
250
- const baseValue = typeof defaults === "function" ? defaults(key) : (0, import_objects.has)(defaults, key) ? (0, import_objects.get)(defaults, key) : void 0;
251
- if (baseValue !== void 0) {
252
- if ((0, import_objects.isObjectLike)(baseValue) && (0, import_objects.isObjectLike)(mergeValue)) {
253
- (0, import_objects.set)(res, key, applyDefaults(baseValue, mergeValue));
254
- continue;
362
+ const res = deepReplaceFunctionsWithObjects(defaults);
363
+ outer: for (const [key, mergeValue] of Object.entries(config)) {
364
+ if (mergeValue === void 0) continue;
365
+ const keyParts = key.split(".");
366
+ let baseValue = defaults;
367
+ let currentRes = res;
368
+ for (const [index, part] of keyParts.entries()) {
369
+ baseValue = (0, import_objects.has)(baseValue, part) ? (0, import_objects.get)(baseValue, part) : typeof baseValue === "function" ? baseValue(part) : void 0;
370
+ if (baseValue === void 0 || !(0, import_objects.isObjectLike)(baseValue)) {
371
+ (0, import_objects.set)(res, key, mergeValue);
372
+ continue outer;
255
373
  }
374
+ if (!(0, import_objects.has)(currentRes, part)) (0, import_objects.set)(currentRes, part, deepReplaceFunctionsWithObjects(baseValue));
375
+ currentRes = (0, import_objects.get)(currentRes, part);
256
376
  }
257
- (0, import_objects.set)(res, key, mergeValue);
377
+ (0, import_objects.set)(res, key, (0, import_objects.isObjectLike)(mergeValue) ? applyDefaults(baseValue, mergeValue) : mergeValue);
258
378
  }
259
379
  return res;
260
380
  }
381
+ function applyProjectDefaults(config) {
382
+ return applyDefaults(projectConfigDefaults, config);
383
+ }
384
+ function applyBranchDefaults(config) {
385
+ return applyDefaults(
386
+ branchConfigDefaults,
387
+ applyDefaults(
388
+ projectConfigDefaults,
389
+ config
390
+ )
391
+ );
392
+ }
393
+ function applyEnvironmentDefaults(config) {
394
+ return applyDefaults(
395
+ environmentConfigDefaults,
396
+ applyDefaults(
397
+ branchConfigDefaults,
398
+ applyDefaults(
399
+ projectConfigDefaults,
400
+ config
401
+ )
402
+ )
403
+ );
404
+ }
405
+ function applyOrganizationDefaults(config) {
406
+ return applyDefaults(
407
+ organizationConfigDefaults,
408
+ applyDefaults(
409
+ environmentConfigDefaults,
410
+ applyDefaults(
411
+ branchConfigDefaults,
412
+ applyDefaults(
413
+ projectConfigDefaults,
414
+ config
415
+ )
416
+ )
417
+ )
418
+ );
419
+ }
420
+ async function sanitizeProjectConfig(config) {
421
+ (0, import_format.assertNormalized)(config);
422
+ const oldSourceOfTruth = config.sourceOfTruth;
423
+ const sourceOfTruth = oldSourceOfTruth.type === "neon" && typeof oldSourceOfTruth.connectionStrings === "object" ? {
424
+ type: "neon",
425
+ connectionStrings: { ...(0, import_objects.filterUndefined)(oldSourceOfTruth.connectionStrings) }
426
+ } : oldSourceOfTruth.type === "postgres" && typeof oldSourceOfTruth.connectionString === "string" ? {
427
+ type: "postgres",
428
+ connectionString: oldSourceOfTruth.connectionString
429
+ } : {
430
+ type: "hosted"
431
+ };
432
+ return {
433
+ ...config,
434
+ sourceOfTruth
435
+ };
436
+ }
437
+ async function sanitizeBranchConfig(config) {
438
+ (0, import_format.assertNormalized)(config);
439
+ const prepared = await sanitizeProjectConfig(config);
440
+ return {
441
+ ...prepared
442
+ };
443
+ }
444
+ async function sanitizeEnvironmentConfig(config) {
445
+ (0, import_format.assertNormalized)(config);
446
+ const prepared = await sanitizeBranchConfig(config);
447
+ return {
448
+ ...prepared
449
+ };
450
+ }
451
+ async function sanitizeOrganizationConfig(config) {
452
+ (0, import_format.assertNormalized)(config);
453
+ const prepared = await sanitizeEnvironmentConfig(config);
454
+ const themes = {
455
+ ...import_emails.DEFAULT_EMAIL_THEMES,
456
+ ...prepared.emails.themes
457
+ };
458
+ const templates = {
459
+ ...import_emails.DEFAULT_EMAIL_TEMPLATES,
460
+ ...prepared.emails.templates
461
+ };
462
+ return {
463
+ ...prepared,
464
+ emails: {
465
+ ...prepared.emails,
466
+ selectedThemeId: (0, import_objects.has)(themes, prepared.emails.selectedThemeId) ? prepared.emails.selectedThemeId : import_emails.DEFAULT_EMAIL_THEME_ID,
467
+ themes,
468
+ templates
469
+ }
470
+ };
471
+ }
472
+ async function getConfigOverrideErrors(schema, configOverride, options = {}) {
473
+ if (typeof configOverride !== "object" || configOverride === null) {
474
+ return import_results.Result.error("Config override must be a non-null object.");
475
+ }
476
+ if (Object.getPrototypeOf(configOverride) !== Object.getPrototypeOf({})) {
477
+ return import_results.Result.error("Config override must be plain old JavaScript object.");
478
+ }
479
+ const reason = (0, import_format.getInvalidConfigReason)(configOverride, { configName: "override" });
480
+ if (reason) return import_results.Result.error("Invalid config format: " + reason);
481
+ const getSubSchema = (schema2, key) => {
482
+ const keyParts = key.split(".");
483
+ if (!schema2.hasNested(keyParts[0])) {
484
+ return void 0;
485
+ }
486
+ const nestedSchema = schema2.getNested(keyParts[0]);
487
+ if (nestedSchema.meta()?.stackConfigCanNoLongerBeOverridden && !options.allowPropertiesThatCanNoLongerBeOverridden) {
488
+ return void 0;
489
+ }
490
+ if (keyParts.length === 1) {
491
+ return nestedSchema;
492
+ } else {
493
+ return getSubSchema(nestedSchema, keyParts.slice(1).join("."));
494
+ }
495
+ };
496
+ const getRestrictedSchemaBase = (path, schema2) => {
497
+ const schemaInfo = schema2.meta()?.stackSchemaInfo;
498
+ switch (schemaInfo?.type) {
499
+ case "string": {
500
+ const stringSchema = schema2;
501
+ const description = stringSchema.describe();
502
+ let res = (0, import_schema_fields.yupString)();
503
+ if (description.tests.some((t) => t.name === "uuid")) {
504
+ res = res.uuid();
505
+ }
506
+ return res;
507
+ }
508
+ case "number": {
509
+ return (0, import_schema_fields.yupNumber)();
510
+ }
511
+ case "boolean": {
512
+ return (0, import_schema_fields.yupBoolean)();
513
+ }
514
+ case "date": {
515
+ return (0, import_schema_fields.yupDate)();
516
+ }
517
+ case "mixed": {
518
+ return (0, import_schema_fields.yupMixed)();
519
+ }
520
+ case "array": {
521
+ throw new import_errors.StackAssertionError(`Arrays are not supported in config JSON files (besides tuples). Use a record instead.`, { schemaInfo, schema: schema2 });
522
+ }
523
+ case "tuple": {
524
+ return (0, import_schema_fields.yupTuple)(schemaInfo.items.map((s, index) => getRestrictedSchema(path + `[${index}]`, s)));
525
+ }
526
+ case "union": {
527
+ const schemas = schemaInfo.items;
528
+ const nonObjectSchemas = [...schemas.entries()].filter(([index, s]) => s.meta()?.stackSchemaInfo?.type !== "object");
529
+ const objectSchemas = schemas.filter((s) => s.meta()?.stackSchemaInfo?.type === "object");
530
+ const allObjectSchemaKeys = [...new Set(objectSchemas.flatMap((s) => Object.keys(s.fields)))];
531
+ const mergedObjectSchema = (0, import_schema_fields.yupObject)(
532
+ Object.fromEntries(
533
+ allObjectSchemaKeys.map((key) => [key, (0, import_schema_fields.yupUnion)(
534
+ ...objectSchemas.flatMap((s, index) => s.hasNested(key) ? [s.getNested(key)] : [])
535
+ )])
536
+ )
537
+ );
538
+ return (0, import_schema_fields.yupUnion)(
539
+ ...nonObjectSchemas.map(([index, s]) => getRestrictedSchema(path + `|variant-${index}|`, s)),
540
+ ...objectSchemas.length > 0 ? [getRestrictedSchema(path + (nonObjectSchemas.length > 0 ? `|variant|` : ""), mergedObjectSchema)] : []
541
+ );
542
+ }
543
+ case "record": {
544
+ return (0, import_schema_fields.yupRecord)(getRestrictedSchema(path + ".key", schemaInfo.keySchema), getRestrictedSchema(path + ".value", schemaInfo.valueSchema));
545
+ }
546
+ case "object": {
547
+ const objectSchema = schema2;
548
+ return (0, import_schema_fields.yupObject)(
549
+ Object.fromEntries(
550
+ Object.entries(objectSchema.fields).map(([key, value]) => [key, getRestrictedSchema(path + "." + key, value)])
551
+ )
552
+ );
553
+ }
554
+ case "never": {
555
+ return (0, import_schema_fields.yupNever)();
556
+ }
557
+ default: {
558
+ throw new import_errors.StackAssertionError(`Unknown schema info at path ${path}: ${JSON.stringify(schemaInfo)}`, { schemaInfo, schema: schema2 });
559
+ }
560
+ }
561
+ };
562
+ const getRestrictedSchema = (path, schema2) => {
563
+ let restricted = getRestrictedSchemaBase(path, schema2);
564
+ restricted = restricted.nullable();
565
+ const description = schema2.describe();
566
+ if (description.oneOf.length > 0) {
567
+ restricted = restricted.oneOf(description.oneOf);
568
+ }
569
+ if (description.notOneOf.length > 0) {
570
+ restricted = restricted.notOneOf(description.notOneOf);
571
+ }
572
+ return restricted;
573
+ };
574
+ for (const [key, value] of Object.entries(configOverride)) {
575
+ if (value === void 0) continue;
576
+ const subSchema = getSubSchema(schema, key);
577
+ if (!subSchema) {
578
+ return import_results.Result.error(`The key ${JSON.stringify(key)} is not valid for the schema.`);
579
+ }
580
+ let restrictedSchema = getRestrictedSchema(key, subSchema);
581
+ try {
582
+ await restrictedSchema.validate(value, {
583
+ strict: true,
584
+ ...{
585
+ // Although `path` is not part of the yup types, it is actually recognized and does the correct thing
586
+ path: key
587
+ },
588
+ context: {
589
+ noUnknownPathPrefixes: [""]
590
+ }
591
+ });
592
+ } catch (error) {
593
+ if (error instanceof yup.ValidationError) {
594
+ return import_results.Result.error(error.message);
595
+ }
596
+ throw error;
597
+ }
598
+ }
599
+ return import_results.Result.ok(null);
600
+ }
601
+ async function assertNoConfigOverrideErrors(schema, config, options = {}) {
602
+ const res = await getConfigOverrideErrors(schema, config, options);
603
+ if (res.status === "error") throw new import_errors.StackAssertionError(`Config override is invalid \u2014 at a place where it should have already been validated! ${res.error}`, { options, config, schema });
604
+ }
605
+ (0, import_types.typeAssertIs)()();
606
+ (0, import_types.typeAssertExtends)()();
607
+ (0, import_types.typeAssertExtends)()();
608
+ async function getIncompleteConfigWarnings(schema, incompleteConfig) {
609
+ await assertNoConfigOverrideErrors(schema, incompleteConfig, { allowPropertiesThatCanNoLongerBeOverridden: true });
610
+ let normalized;
611
+ try {
612
+ normalized = (0, import_format.normalize)(incompleteConfig, { onDotIntoNull: "empty-object" });
613
+ } catch (error) {
614
+ if (error instanceof import_format.NormalizationError) {
615
+ return import_results.Result.error(`Config is not normalizable. ` + error.message);
616
+ }
617
+ throw error;
618
+ }
619
+ try {
620
+ await schema.validate(normalized, {
621
+ strict: true,
622
+ context: {
623
+ noUnknownPathPrefixes: [""]
624
+ }
625
+ });
626
+ return import_results.Result.ok(null);
627
+ } catch (error) {
628
+ if (error instanceof yup.ValidationError) {
629
+ return import_results.Result.error(error.message);
630
+ }
631
+ throw error;
632
+ }
633
+ }
634
+ (0, import_types.typeAssertExtends)()();
635
+ (0, import_types.typeAssertExtends)()();
636
+ (0, import_types.typeAssertExtends)()();
637
+ (0, import_types.typeAssertExtends)()();
638
+ (0, import_types.typeAssert)()();
639
+ (0, import_types.typeAssert)()();
640
+ (0, import_types.typeAssertExtends)()();
261
641
  // Annotate the CommonJS export names for ESM import in node:
262
642
  0 && (module.exports = {
263
- applyDefaults,
264
- branchConfigDefaults,
643
+ applyBranchDefaults,
644
+ applyEnvironmentDefaults,
645
+ applyOrganizationDefaults,
646
+ applyProjectDefaults,
647
+ assertNoConfigOverrideErrors,
265
648
  branchConfigSchema,
266
649
  configLevels,
267
- environmentConfigDefaults,
268
650
  environmentConfigSchema,
269
- organizationConfigDefaults,
651
+ getConfigOverrideErrors,
652
+ getIncompleteConfigWarnings,
653
+ migrateConfigOverride,
270
654
  organizationConfigSchema,
271
- projectConfigDefaults,
272
- projectConfigSchema
655
+ projectConfigSchema,
656
+ sanitizeBranchConfig,
657
+ sanitizeEnvironmentConfig,
658
+ sanitizeOrganizationConfig,
659
+ sanitizeProjectConfig
273
660
  });
274
661
  //# sourceMappingURL=schema.js.map