@stackframe/stack-shared 2.8.22 → 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 (164) hide show
  1. package/CHANGELOG.md +30 -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 +816 -294
  7. package/dist/config/schema.d.ts +816 -294
  8. package/dist/config/schema.js +471 -82
  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 -78
  15. package/dist/esm/config/schema.js.map +1 -1
  16. package/dist/esm/helpers/emails.js +185 -0
  17. package/dist/esm/helpers/emails.js.map +1 -0
  18. package/dist/esm/interface/admin-interface.js +58 -36
  19. package/dist/esm/interface/admin-interface.js.map +1 -1
  20. package/dist/esm/interface/client-interface.js +41 -0
  21. package/dist/esm/interface/client-interface.js.map +1 -1
  22. package/dist/esm/interface/crud/{oauth.js → connected-accounts.js} +2 -2
  23. package/dist/esm/interface/crud/connected-accounts.js.map +1 -0
  24. package/dist/esm/interface/crud/oauth-providers.js +87 -0
  25. package/dist/esm/interface/crud/oauth-providers.js.map +1 -0
  26. package/dist/esm/interface/crud/projects.js +7 -5
  27. package/dist/esm/interface/crud/projects.js.map +1 -1
  28. package/dist/esm/interface/server-interface.js +51 -0
  29. package/dist/esm/interface/server-interface.js.map +1 -1
  30. package/dist/esm/known-errors.js +34 -1
  31. package/dist/esm/known-errors.js.map +1 -1
  32. package/dist/esm/schema-fields.js +112 -24
  33. package/dist/esm/schema-fields.js.map +1 -1
  34. package/dist/esm/utils/currencies.js +52 -0
  35. package/dist/esm/utils/currencies.js.map +1 -0
  36. package/dist/esm/utils/dates.js +55 -1
  37. package/dist/esm/utils/dates.js.map +1 -1
  38. package/dist/esm/utils/errors.js.map +1 -1
  39. package/dist/esm/utils/esbuild.js +14 -4
  40. package/dist/esm/utils/esbuild.js.map +1 -1
  41. package/dist/esm/utils/oauth.js +1 -1
  42. package/dist/esm/utils/oauth.js.map +1 -1
  43. package/dist/esm/utils/objects.js +2 -0
  44. package/dist/esm/utils/objects.js.map +1 -1
  45. package/dist/esm/utils/strings.js +4 -0
  46. package/dist/esm/utils/strings.js.map +1 -1
  47. package/dist/esm/utils/types.js +45 -0
  48. package/dist/esm/utils/types.js.map +1 -1
  49. package/dist/helpers/emails.d.mts +50 -0
  50. package/dist/helpers/emails.d.ts +50 -0
  51. package/dist/helpers/emails.js +216 -0
  52. package/dist/helpers/emails.js.map +1 -0
  53. package/dist/helpers/password.d.mts +1 -0
  54. package/dist/helpers/password.d.ts +1 -0
  55. package/dist/helpers/production-mode.d.mts +1 -0
  56. package/dist/helpers/production-mode.d.ts +1 -0
  57. package/dist/index.d.mts +3 -3
  58. package/dist/index.d.ts +3 -3
  59. package/dist/interface/admin-interface.d.mts +24 -15
  60. package/dist/interface/admin-interface.d.ts +24 -15
  61. package/dist/interface/admin-interface.js +58 -36
  62. package/dist/interface/admin-interface.js.map +1 -1
  63. package/dist/interface/client-interface.d.mts +25 -1
  64. package/dist/interface/client-interface.d.ts +25 -1
  65. package/dist/interface/client-interface.js +41 -0
  66. package/dist/interface/client-interface.js.map +1 -1
  67. package/dist/interface/crud/{oauth.d.mts → connected-accounts.d.mts} +1 -0
  68. package/dist/interface/crud/{oauth.d.ts → connected-accounts.d.ts} +1 -0
  69. package/dist/interface/crud/{oauth.js → connected-accounts.js} +5 -5
  70. package/dist/interface/crud/connected-accounts.js.map +1 -0
  71. package/dist/interface/crud/contact-channels.d.mts +1 -0
  72. package/dist/interface/crud/contact-channels.d.ts +1 -0
  73. package/dist/interface/crud/current-user.d.mts +1 -0
  74. package/dist/interface/crud/current-user.d.ts +1 -0
  75. package/dist/interface/crud/email-templates.d.mts +1 -0
  76. package/dist/interface/crud/email-templates.d.ts +1 -0
  77. package/dist/interface/crud/emails.d.mts +1 -0
  78. package/dist/interface/crud/emails.d.ts +1 -0
  79. package/dist/interface/crud/internal-api-keys.d.mts +1 -0
  80. package/dist/interface/crud/internal-api-keys.d.ts +1 -0
  81. package/dist/interface/crud/notification-preferences.d.mts +1 -0
  82. package/dist/interface/crud/notification-preferences.d.ts +1 -0
  83. package/dist/interface/crud/oauth-providers.d.mts +173 -0
  84. package/dist/interface/crud/oauth-providers.d.ts +173 -0
  85. package/dist/interface/crud/oauth-providers.js +107 -0
  86. package/dist/interface/crud/oauth-providers.js.map +1 -0
  87. package/dist/interface/crud/project-api-keys.d.mts +1 -0
  88. package/dist/interface/crud/project-api-keys.d.ts +1 -0
  89. package/dist/interface/crud/project-permissions.d.mts +1 -0
  90. package/dist/interface/crud/project-permissions.d.ts +1 -0
  91. package/dist/interface/crud/projects.d.mts +16 -12
  92. package/dist/interface/crud/projects.d.ts +16 -12
  93. package/dist/interface/crud/projects.js +5 -3
  94. package/dist/interface/crud/projects.js.map +1 -1
  95. package/dist/interface/crud/sessions.d.mts +1 -0
  96. package/dist/interface/crud/sessions.d.ts +1 -0
  97. package/dist/interface/crud/svix-token.d.mts +1 -0
  98. package/dist/interface/crud/svix-token.d.ts +1 -0
  99. package/dist/interface/crud/team-invitation-details.d.mts +1 -0
  100. package/dist/interface/crud/team-invitation-details.d.ts +1 -0
  101. package/dist/interface/crud/team-invitation.d.mts +1 -0
  102. package/dist/interface/crud/team-invitation.d.ts +1 -0
  103. package/dist/interface/crud/team-member-profiles.d.mts +1 -0
  104. package/dist/interface/crud/team-member-profiles.d.ts +1 -0
  105. package/dist/interface/crud/team-memberships.d.mts +1 -0
  106. package/dist/interface/crud/team-memberships.d.ts +1 -0
  107. package/dist/interface/crud/team-permissions.d.mts +1 -0
  108. package/dist/interface/crud/team-permissions.d.ts +1 -0
  109. package/dist/interface/crud/teams.d.mts +1 -0
  110. package/dist/interface/crud/teams.d.ts +1 -0
  111. package/dist/interface/crud/users.d.mts +1 -0
  112. package/dist/interface/crud/users.d.ts +1 -0
  113. package/dist/interface/server-interface.d.mts +46 -1
  114. package/dist/interface/server-interface.d.ts +46 -1
  115. package/dist/interface/server-interface.js +51 -0
  116. package/dist/interface/server-interface.js.map +1 -1
  117. package/dist/known-errors.d.mts +9 -0
  118. package/dist/known-errors.d.ts +9 -0
  119. package/dist/known-errors.js +34 -1
  120. package/dist/known-errors.js.map +1 -1
  121. package/dist/schema-fields.d.mts +51 -7
  122. package/dist/schema-fields.d.ts +51 -7
  123. package/dist/schema-fields.js +128 -24
  124. package/dist/schema-fields.js.map +1 -1
  125. package/dist/utils/currencies.d.mts +39 -0
  126. package/dist/utils/currencies.d.ts +39 -0
  127. package/dist/utils/currencies.js +78 -0
  128. package/dist/utils/currencies.js.map +1 -0
  129. package/dist/utils/dates.d.mts +5 -1
  130. package/dist/utils/dates.d.ts +5 -1
  131. package/dist/utils/dates.js +58 -2
  132. package/dist/utils/dates.js.map +1 -1
  133. package/dist/utils/errors.d.mts +9 -0
  134. package/dist/utils/errors.d.ts +9 -0
  135. package/dist/utils/errors.js.map +1 -1
  136. package/dist/utils/esbuild.d.mts +3 -0
  137. package/dist/utils/esbuild.d.ts +3 -0
  138. package/dist/utils/esbuild.js +14 -4
  139. package/dist/utils/esbuild.js.map +1 -1
  140. package/dist/utils/oauth.d.mts +2 -2
  141. package/dist/utils/oauth.d.ts +2 -2
  142. package/dist/utils/oauth.js +1 -1
  143. package/dist/utils/oauth.js.map +1 -1
  144. package/dist/utils/objects.d.mts +23 -8
  145. package/dist/utils/objects.d.ts +23 -8
  146. package/dist/utils/objects.js +2 -0
  147. package/dist/utils/objects.js.map +1 -1
  148. package/dist/utils/strings.d.mts +3 -1
  149. package/dist/utils/strings.d.ts +3 -1
  150. package/dist/utils/strings.js +5 -0
  151. package/dist/utils/strings.js.map +1 -1
  152. package/dist/utils/types.d.mts +73 -2
  153. package/dist/utils/types.d.ts +73 -2
  154. package/dist/utils/types.js +54 -0
  155. package/dist/utils/types.js.map +1 -1
  156. package/package.json +1 -1
  157. package/dist/esm/helpers/email-themes.js +0 -45
  158. package/dist/esm/helpers/email-themes.js.map +0 -1
  159. package/dist/esm/interface/crud/oauth.js.map +0 -1
  160. package/dist/helpers/email-themes.d.mts +0 -13
  161. package/dist/helpers/email-themes.d.ts +0 -13
  162. package/dist/helpers/email-themes.js +0 -71
  163. package/dist/helpers/email-themes.js.map +0 -1
  164. package/dist/interface/crud/oauth.js.map +0 -1
@@ -30,123 +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_email_themes = require("../helpers/email-themes.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()
157
+ selectedThemeId: schemaFields.emailThemeSchema,
158
+ themes: schemaFields.emailThemeListSchema,
159
+ templates: schemaFields.emailTemplateListSchema
140
160
  })
141
161
  }));
142
162
  var environmentConfigSchema = branchConfigSchema.concat((0, import_schema_fields.yupObject)({
143
163
  auth: branchConfigSchema.getNested("auth").concat((0, import_schema_fields.yupObject)({
144
164
  oauth: branchConfigSchema.getNested("auth").getNested("oauth").concat((0, import_schema_fields.yupObject)({
145
165
  providers: (0, import_schema_fields.yupRecord)(
146
- (0, import_schema_fields.yupString)().optional().matches(permissionRegex),
166
+ (0, import_schema_fields.yupString)().matches(permissionRegex),
147
167
  (0, import_schema_fields.yupObject)({
148
168
  type: (0, import_schema_fields.yupString)().oneOf(import_oauth.allProviders).optional(),
149
- isShared: (0, import_schema_fields.yupBoolean)().optional(),
169
+ isShared: (0, import_schema_fields.yupBoolean)(),
150
170
  clientId: schemaFields.oauthClientIdSchema.optional(),
151
171
  clientSecret: schemaFields.oauthClientSecretSchema.optional(),
152
172
  facebookConfigId: schemaFields.oauthFacebookConfigIdSchema.optional(),
@@ -154,12 +174,12 @@ var environmentConfigSchema = branchConfigSchema.concat((0, import_schema_fields
154
174
  allowSignIn: (0, import_schema_fields.yupBoolean)().optional(),
155
175
  allowConnectedAccounts: (0, import_schema_fields.yupBoolean)().optional()
156
176
  })
157
- ).optional()
158
- }).optional())
177
+ )
178
+ }))
159
179
  })),
160
180
  emails: branchConfigSchema.getNested("emails").concat((0, import_schema_fields.yupObject)({
161
181
  server: (0, import_schema_fields.yupObject)({
162
- isShared: (0, import_schema_fields.yupBoolean)().optional(),
182
+ isShared: (0, import_schema_fields.yupBoolean)(),
163
183
  host: schemaFields.emailHostSchema.optional().nonEmpty(),
164
184
  port: schemaFields.emailPortSchema.optional(),
165
185
  username: schemaFields.emailUsernameSchema.optional().nonEmpty(),
@@ -167,32 +187,103 @@ var environmentConfigSchema = branchConfigSchema.concat((0, import_schema_fields
167
187
  senderName: schemaFields.emailSenderNameSchema.optional().nonEmpty(),
168
188
  senderEmail: schemaFields.emailSenderEmailSchema.optional().nonEmpty()
169
189
  })
170
- }).optional()),
190
+ })),
171
191
  domains: branchConfigSchema.getNested("domains").concat((0, import_schema_fields.yupObject)({
172
192
  trustedDomains: (0, import_schema_fields.yupRecord)(
173
- (0, import_schema_fields.yupString)().uuid().optional(),
193
+ (0, import_schema_fields.yupString)(),
174
194
  (0, import_schema_fields.yupObject)({
175
- baseUrl: schemaFields.urlSchema.optional(),
176
- handlerPath: schemaFields.handlerPathSchema.optional()
195
+ baseUrl: schemaFields.urlSchema,
196
+ handlerPath: schemaFields.handlerPathSchema
177
197
  })
178
- ).optional()
198
+ )
179
199
  }))
180
200
  }));
181
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
+ }
182
267
  var projectConfigDefaults = {
183
268
  sourceOfTruth: {
184
- type: "hosted"
269
+ type: "hosted",
270
+ connectionStrings: void 0,
271
+ connectionString: void 0
185
272
  }
186
273
  };
187
274
  var branchConfigDefaults = {};
188
275
  var environmentConfigDefaults = {};
189
276
  var organizationConfigDefaults = {
190
277
  rbac: {
191
- permissions: (key) => ({}),
278
+ permissions: (key) => ({
279
+ containedPermissionIds: (key2) => void 0,
280
+ description: void 0,
281
+ scope: void 0
282
+ }),
192
283
  defaultPermissions: {
193
- teamCreator: {},
194
- teamMember: {},
195
- signUp: {}
284
+ teamCreator: (key) => void 0,
285
+ teamMember: (key) => void 0,
286
+ signUp: (key) => void 0
196
287
  }
197
288
  },
198
289
  apiKeys: {
@@ -211,6 +302,7 @@ var organizationConfigDefaults = {
211
302
  domains: {
212
303
  allowLocalhost: false,
213
304
  trustedDomains: (key) => ({
305
+ baseUrl: void 0,
214
306
  handlerPath: "/handler"
215
307
  })
216
308
  },
@@ -228,45 +320,342 @@ var organizationConfigDefaults = {
228
320
  oauth: {
229
321
  accountMergeStrategy: "link_method",
230
322
  providers: (key) => ({
323
+ type: void 0,
231
324
  isShared: true,
232
325
  allowSignIn: false,
233
- allowConnectedAccounts: false
326
+ allowConnectedAccounts: false,
327
+ clientId: void 0,
328
+ clientSecret: void 0,
329
+ facebookConfigId: void 0,
330
+ microsoftTenantId: void 0
234
331
  })
235
332
  }
236
333
  },
237
334
  emails: {
238
335
  server: {
239
- 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
240
343
  },
241
- theme: import_email_themes.DEFAULT_EMAIL_THEME_ID,
242
- themeList: import_email_themes.DEFAULT_EMAIL_THEMES
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)
243
354
  }
244
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
+ }
245
361
  function applyDefaults(defaults, config) {
246
- const res = typeof defaults === "function" ? {} : (0, import_objects.mapValues)(defaults, (v) => typeof v === "function" ? {} : typeof v === "object" ? applyDefaults(v, {}) : v);
247
- for (const [key, mergeValue] of Object.entries(config)) {
248
- const baseValue = typeof defaults === "function" ? defaults(key) : (0, import_objects.has)(defaults, key) ? (0, import_objects.get)(defaults, key) : void 0;
249
- if (baseValue !== void 0) {
250
- if ((0, import_objects.isObjectLike)(baseValue) && (0, import_objects.isObjectLike)(mergeValue)) {
251
- (0, import_objects.set)(res, key, applyDefaults(baseValue, mergeValue));
252
- 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;
253
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);
254
376
  }
255
- (0, import_objects.set)(res, key, mergeValue);
377
+ (0, import_objects.set)(res, key, (0, import_objects.isObjectLike)(mergeValue) ? applyDefaults(baseValue, mergeValue) : mergeValue);
256
378
  }
257
379
  return res;
258
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)()();
259
641
  // Annotate the CommonJS export names for ESM import in node:
260
642
  0 && (module.exports = {
261
- applyDefaults,
262
- branchConfigDefaults,
643
+ applyBranchDefaults,
644
+ applyEnvironmentDefaults,
645
+ applyOrganizationDefaults,
646
+ applyProjectDefaults,
647
+ assertNoConfigOverrideErrors,
263
648
  branchConfigSchema,
264
649
  configLevels,
265
- environmentConfigDefaults,
266
650
  environmentConfigSchema,
267
- organizationConfigDefaults,
651
+ getConfigOverrideErrors,
652
+ getIncompleteConfigWarnings,
653
+ migrateConfigOverride,
268
654
  organizationConfigSchema,
269
- projectConfigDefaults,
270
- projectConfigSchema
655
+ projectConfigSchema,
656
+ sanitizeBranchConfig,
657
+ sanitizeEnvironmentConfig,
658
+ sanitizeOrganizationConfig,
659
+ sanitizeProjectConfig
271
660
  });
272
661
  //# sourceMappingURL=schema.js.map