@spacefast/common 0.0.23 → 0.0.26

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 (224) hide show
  1. package/brand-assets/LICENSE-Haskoy.txt +93 -0
  2. package/brand-assets/haskoy-latin-variable.woff2 +0 -0
  3. package/brand-assets/spacefast-favicon.svg +4 -4
  4. package/brand-assets/spacefast-sf-full-bleed.svg +3 -3
  5. package/brand-assets/spacefast-wordmark.svg +2 -4
  6. package/dist/agents/connect-targets.js +1 -1
  7. package/dist/agents/private-key-oauth.d.ts +0 -1
  8. package/dist/agents/private-key-oauth.js +46 -63
  9. package/dist/brand-assets-build.js +4 -6
  10. package/dist/brand-assets.d.ts +5 -15
  11. package/dist/brand-assets.js +15 -14
  12. package/dist/config/domains.d.ts +47 -7
  13. package/dist/config/domains.js +66 -10
  14. package/dist/config/index.d.ts +0 -1
  15. package/dist/config/index.js +0 -1
  16. package/dist/contracts/abuse.d.ts +2 -0
  17. package/dist/contracts/abuse.js +12 -0
  18. package/dist/contracts/access.d.ts +124 -12
  19. package/dist/contracts/access.js +73 -9
  20. package/dist/contracts/activity.d.ts +1 -1
  21. package/dist/contracts/activity.js +5 -12
  22. package/dist/contracts/api-keys.d.ts +21 -21
  23. package/dist/contracts/api-keys.js +2 -2
  24. package/dist/contracts/beta.js +1 -1
  25. package/dist/contracts/billing.d.ts +3 -35
  26. package/dist/contracts/billing.js +33 -52
  27. package/dist/contracts/builds.d.ts +30 -18
  28. package/dist/contracts/builds.js +28 -9
  29. package/dist/contracts/channels.js +1 -1
  30. package/dist/contracts/cli.d.ts +10 -0
  31. package/dist/contracts/cli.js +10 -0
  32. package/dist/contracts/collab-public.d.ts +63 -0
  33. package/dist/contracts/collab-public.js +46 -0
  34. package/dist/contracts/comments.d.ts +282 -53
  35. package/dist/contracts/comments.js +173 -52
  36. package/dist/contracts/common.d.ts +3 -3
  37. package/dist/contracts/common.js +5 -5
  38. package/dist/contracts/crons.d.ts +35 -0
  39. package/dist/contracts/crons.js +42 -0
  40. package/dist/contracts/device-auth.d.ts +6 -6
  41. package/dist/contracts/device-auth.js +2 -2
  42. package/dist/contracts/docs.js +2 -2
  43. package/dist/contracts/domains.d.ts +38 -27
  44. package/dist/contracts/domains.js +29 -2
  45. package/dist/contracts/enums.d.ts +34 -30
  46. package/dist/contracts/enums.js +62 -48
  47. package/dist/contracts/error-code-meta.d.ts +50 -125
  48. package/dist/contracts/error-code-meta.js +29 -41
  49. package/dist/contracts/error-codes.d.ts +1 -1
  50. package/dist/contracts/error-codes.js +14 -33
  51. package/dist/contracts/execution.d.ts +47 -66
  52. package/dist/contracts/execution.js +53 -49
  53. package/dist/contracts/feature-lifecycle-core.d.ts +0 -6
  54. package/dist/contracts/feature-lifecycle-core.js +2 -31
  55. package/dist/contracts/feature-lifecycle.d.ts +12 -52
  56. package/dist/contracts/feature-lifecycle.js +16 -59
  57. package/dist/contracts/features.d.ts +48 -60
  58. package/dist/contracts/features.js +59 -51
  59. package/dist/contracts/functions.d.ts +266 -72
  60. package/dist/contracts/functions.js +260 -37
  61. package/dist/contracts/git.d.ts +28 -34
  62. package/dist/contracts/git.js +10 -11
  63. package/dist/contracts/grants.d.ts +9 -5
  64. package/dist/contracts/grants.js +18 -9
  65. package/dist/contracts/ids.js +2 -2
  66. package/dist/contracts/internal.d.ts +8 -6
  67. package/dist/contracts/internal.js +12 -12
  68. package/dist/contracts/mcp.d.ts +11 -0
  69. package/dist/contracts/mcp.js +5 -0
  70. package/dist/contracts/me.js +1 -1
  71. package/dist/contracts/oauth-resources.d.ts +4 -3
  72. package/dist/contracts/oauth-resources.js +12 -3
  73. package/dist/contracts/operations.d.ts +90 -5
  74. package/dist/contracts/operations.js +77 -3
  75. package/dist/contracts/pages.d.ts +12 -7
  76. package/dist/contracts/pages.js +24 -1
  77. package/dist/contracts/plan-policy.d.ts +0 -2
  78. package/dist/contracts/plan-policy.js +2 -3
  79. package/dist/contracts/platform.d.ts +61 -148
  80. package/dist/contracts/platform.js +70 -126
  81. package/dist/contracts/publish-archive.d.ts +508 -0
  82. package/dist/contracts/publish-archive.js +32 -0
  83. package/dist/contracts/push-new.d.ts +4 -4
  84. package/dist/contracts/quotas.js +2 -2
  85. package/dist/contracts/repository-connections.d.ts +43 -30
  86. package/dist/contracts/repository-connections.js +11 -3
  87. package/dist/contracts/resources.d.ts +12 -24
  88. package/dist/contracts/resources.js +36 -16
  89. package/dist/contracts/runtime-api.d.ts +433 -192
  90. package/dist/contracts/runtime-api.js +421 -356
  91. package/dist/contracts/runtime-app.d.ts +127 -120
  92. package/dist/contracts/runtime-app.js +19 -10
  93. package/dist/contracts/runtime-db.d.ts +5 -5
  94. package/dist/contracts/runtime-db.js +2 -2
  95. package/dist/contracts/runtime-purge.d.ts +8 -0
  96. package/dist/contracts/runtime-purge.js +7 -0
  97. package/dist/contracts/runtime-services.d.ts +219 -0
  98. package/dist/contracts/runtime-services.js +437 -0
  99. package/dist/contracts/runtime-storage.d.ts +46 -32
  100. package/dist/contracts/runtime-storage.js +31 -8
  101. package/dist/contracts/sf-config-v1.d.ts +48 -10
  102. package/dist/contracts/space-config.d.ts +69 -18
  103. package/dist/contracts/space-config.js +226 -27
  104. package/dist/contracts/spaces.d.ts +236 -450
  105. package/dist/contracts/spaces.js +131 -151
  106. package/dist/contracts/superadmin-activity.d.ts +57 -4
  107. package/dist/contracts/superadmin-activity.js +48 -2
  108. package/dist/contracts/superadmin-search.d.ts +126 -0
  109. package/dist/contracts/superadmin-search.js +61 -0
  110. package/dist/contracts/superadmin-spaces.d.ts +361 -92
  111. package/dist/contracts/superadmin-spaces.js +97 -24
  112. package/dist/contracts/superadmin-teams.d.ts +28 -10
  113. package/dist/contracts/superadmin-teams.js +5 -8
  114. package/dist/contracts/superadmin-tenants.d.ts +0 -6
  115. package/dist/contracts/superadmin-tenants.js +1 -7
  116. package/dist/contracts/superadmin.d.ts +135 -54
  117. package/dist/contracts/superadmin.js +46 -23
  118. package/dist/contracts/tags.d.ts +12 -12
  119. package/dist/contracts/tags.js +3 -3
  120. package/dist/contracts/teams.d.ts +49 -14
  121. package/dist/contracts/teams.js +40 -22
  122. package/dist/contracts/transfers.d.ts +0 -49
  123. package/dist/contracts/transfers.js +4 -8
  124. package/dist/contracts/usage.d.ts +61 -0
  125. package/dist/contracts/usage.js +64 -0
  126. package/dist/contracts/variables.d.ts +2 -7
  127. package/dist/contracts/variables.js +9 -8
  128. package/dist/contracts/webhooks.d.ts +2 -2
  129. package/dist/contracts/zero.d.ts +102 -73
  130. package/dist/contracts/zero.js +94 -32
  131. package/dist/dashboard-paths/index.d.ts +1 -1
  132. package/dist/dashboard-paths/index.js +1 -0
  133. package/dist/docs/agent-prose.d.ts +2 -2
  134. package/dist/docs/agent-prose.js +63 -70
  135. package/dist/docs/agent-setup.js +45 -15
  136. package/dist/docs/catalog.d.ts +24 -24
  137. package/dist/docs/catalog.js +35 -24
  138. package/dist/docs/error-docs.js +194 -270
  139. package/dist/docs/skills.d.ts +12 -12
  140. package/dist/docs/skills.js +4 -4
  141. package/dist/test-helpers/fetch-stub.d.ts +16 -0
  142. package/dist/test-helpers/fetch-stub.js +25 -0
  143. package/dist/utils/build-settings.d.ts +5 -1
  144. package/dist/utils/build-settings.js +91 -13
  145. package/dist/utils/canonical-json.d.ts +10 -0
  146. package/dist/utils/canonical-json.js +22 -0
  147. package/dist/utils/cast-transport.d.ts +28 -0
  148. package/dist/utils/cast-transport.js +52 -0
  149. package/dist/utils/claim-token.d.ts +0 -8
  150. package/dist/utils/claim-token.js +3 -15
  151. package/dist/utils/concurrency.js +1 -0
  152. package/dist/utils/credential-policy.d.ts +1 -1
  153. package/dist/utils/credential-policy.js +4 -3
  154. package/dist/utils/dns-instructions.js +9 -9
  155. package/dist/utils/env-file.d.ts +17 -0
  156. package/dist/utils/env-file.js +96 -0
  157. package/dist/utils/error-code.d.ts +2 -0
  158. package/dist/utils/error-code.js +8 -0
  159. package/dist/utils/generate-space-name.d.ts +8 -10
  160. package/dist/utils/generate-space-name.js +206 -21
  161. package/dist/utils/grant-decision.fixtures.json +2938 -0
  162. package/dist/utils/grants.d.ts +2 -0
  163. package/dist/utils/grants.js +26 -1
  164. package/dist/utils/gravatar.d.ts +9 -0
  165. package/dist/utils/gravatar.js +31 -0
  166. package/dist/utils/idempotency.d.ts +6 -0
  167. package/dist/utils/idempotency.js +28 -0
  168. package/dist/utils/local-space-state.d.ts +9 -16
  169. package/dist/utils/local-space-state.js +20 -50
  170. package/dist/utils/one-shot-replay.d.ts +4 -1
  171. package/dist/utils/page-colors.d.ts +14 -12
  172. package/dist/utils/page-colors.js +15 -13
  173. package/dist/utils/page-fonts.d.ts +2 -2
  174. package/dist/utils/page-fonts.js +15 -4
  175. package/dist/utils/pages.d.ts +21 -3
  176. package/dist/utils/pages.js +42 -13
  177. package/dist/utils/publish-form-data.d.ts +12 -0
  178. package/dist/utils/publish-form-data.js +10 -0
  179. package/dist/utils/publish-policy.d.ts +27 -0
  180. package/dist/utils/publish-policy.fixtures.json +403 -0
  181. package/dist/utils/publish-policy.js +45 -20
  182. package/dist/utils/push-new.d.ts +7 -0
  183. package/dist/utils/push-new.js +7 -0
  184. package/dist/utils/query-keys.d.ts +4 -5
  185. package/dist/utils/query-keys.js +2 -3
  186. package/dist/utils/runtime-paths.d.ts +5 -0
  187. package/dist/utils/runtime-paths.js +5 -0
  188. package/dist/utils/runtime-upload-batch.d.ts +0 -5
  189. package/dist/utils/runtime-upload-batch.js +1 -27
  190. package/dist/utils/runtime-upload.d.ts +6 -11
  191. package/dist/utils/runtime-upload.js +10 -13
  192. package/dist/utils/secure-local-file.js +5 -16
  193. package/dist/utils/space-config.d.ts +1 -34
  194. package/dist/utils/space-config.js +8 -326
  195. package/dist/utils/static-runtime-policy.d.ts +9 -3
  196. package/dist/utils/static-runtime-policy.fixtures.json +38 -41
  197. package/dist/utils/static-runtime-policy.js +22 -56
  198. package/dist/utils/storage-policy.d.ts +1 -1
  199. package/dist/utils/storage-policy.js +3 -1
  200. package/dist/utils/structured-error.d.ts +14 -0
  201. package/dist/utils/structured-error.js +22 -0
  202. package/dist/utils/upload-session.d.ts +4 -1
  203. package/dist/utils/upload-session.js +33 -5
  204. package/dist/utils/version-path.js +13 -4
  205. package/dist/vocabulary.d.ts +13 -11
  206. package/dist/vocabulary.js +42 -28
  207. package/package.json +7 -17
  208. package/dist/config/postgres-budget.d.ts +0 -129
  209. package/dist/config/postgres-budget.js +0 -140
  210. package/dist/config/postgres-budget.json +0 -51
  211. package/dist/contracts/archives.d.ts +0 -331
  212. package/dist/contracts/archives.js +0 -120
  213. package/dist/contracts/deployments.d.ts +0 -574
  214. package/dist/contracts/deployments.js +0 -97
  215. package/dist/contracts/sites.d.ts +0 -416
  216. package/dist/contracts/sites.js +0 -168
  217. package/dist/contracts/superadmin-queues.d.ts +0 -414
  218. package/dist/contracts/superadmin-queues.js +0 -202
  219. package/dist/contracts/superadmin-runtime.d.ts +0 -27
  220. package/dist/contracts/superadmin-runtime.js +0 -38
  221. package/dist/index.d.ts +0 -1
  222. package/dist/index.js +0 -1
  223. package/dist/utils/api.d.ts +0 -4
  224. package/dist/utils/api.js +0 -13
@@ -1,10 +1,20 @@
1
1
  import { z } from "zod";
2
2
  import { FEATURE_RUNTIME_DEFINITIONS, FEATURE_RUNTIME_KEYS, } from "./feature-lifecycle.js";
3
- // Spec plan vocabulary (internal-docs/platform.md "Plans And Limits").
3
+ // Spec plan vocabulary (the platform spec "Plans And Limits").
4
4
  // `enterprise` and `internal` are named plans without self-serve pricing.
5
+ // Codes are wire/storage vocabulary and never change with marketing renames:
6
+ // `personal` sells as "Plus" and `work` as "Pro" (2026-08 rename) — display
7
+ // names live on PlanDefinition.name.
5
8
  export const PLAN_CODES = ["free", "personal", "work", "enterprise", "internal"];
6
9
  export const planCodeSchema = z.enum(PLAN_CODES).describe("Plan code.");
7
10
  export const DEFAULT_PLAN_CODE = "free";
11
+ export const SELF_SERVE_PLAN_CODES = ["personal", "work"];
12
+ export const PUBLIC_PLAN_CODES = [
13
+ "free",
14
+ "personal",
15
+ "work",
16
+ "enterprise",
17
+ ];
8
18
  export const FEATURE_KEYS = FEATURE_RUNTIME_KEYS;
9
19
  export const featureKeySchema = z.enum(FEATURE_KEYS).describe("Feature flag key.");
10
20
  // Feature override states (env `SPACEFAST_FLAG_*` and the feature_overrides
@@ -14,7 +24,7 @@ export const featureOverrideStateSchema = z.enum(FEATURE_OVERRIDE_STATES);
14
24
  export const planLimitValueSchema = z
15
25
  .union([z.number().int().nonnegative(), z.literal("unlimited")])
16
26
  .describe('Plan limit value; "unlimited" when the plan does not limit this axis.');
17
- // Named plan limit table (internal-docs/platform.md "Plans And Limits",
27
+ // Named plan limit table (the platform spec "Plans And Limits",
18
28
  // Free/Personal/Work columns verbatim). Keys mirror `PlanPolicyResponse.limits`
19
29
  // so plan policy is a projection of this data, never a re-derivation.
20
30
  export const planLimitsSchema = z
@@ -23,15 +33,8 @@ export const planLimitsSchema = z
23
33
  teamMembers: planLimitValueSchema,
24
34
  subTeams: planLimitValueSchema,
25
35
  externalDomainGroups: planLimitValueSchema,
26
- // Version retention (charter arbitration A3, internal plan data — never on
27
- // the PlanPolicyResponse wire shape): `versionRetentionDays` is the included
28
- // full-retention window; after it versions stay stored but gated until
29
- // `versionGatedKeepDays` from readyAt, then retention-delete with notice.
30
- // Live and channel-referenced versions are never retention-deleted.
31
- versionRetentionDays: planLimitValueSchema,
32
- versionGatedKeepDays: planLimitValueSchema,
33
36
  // Per-space daily bandwidth cap feeding the egress kill-switch sweep
34
- // (internal-docs/platform.md "Abuse Posture"; internal plan data — never on
37
+ // (the platform spec "Abuse Posture"; internal plan data — never on
35
38
  // the PlanPolicyResponse wire shape). WORST_CASE_QUOTAS
36
39
  // .maxEgressBytesPerSpacePerDay stays the absolute platform ceiling.
37
40
  egressBytesPerDay: planLimitValueSchema,
@@ -44,9 +47,6 @@ export const planLimitsSchema = z
44
47
  buildAccessLogRetentionHours: planLimitValueSchema,
45
48
  // One pooled limit on purpose: pricing never separates user pushes from CI builds.
46
49
  buildsDeploysMonthly: planLimitValueSchema,
47
- // Queryable analytics history window. Storage retains rollups for everyone
48
- // (env-bounded); this only clamps how far back the analytics API serves.
49
- analyticsRetentionDays: planLimitValueSchema,
50
50
  // Access-surface abuse ceilings: generous by default, enterprise unlimited.
51
51
  // Active (non-revoked, non-expired) share links per space.
52
52
  shareLinksPerSpace: planLimitValueSchema,
@@ -67,7 +67,9 @@ export const teamEntitlementsSchema = z
67
67
  planCode: planCodeSchema,
68
68
  limits: planLimitsSchema,
69
69
  externalProxy: z.boolean().describe("Whether external proxy upstreams compile on this plan."),
70
- dedicatedRuntime: z.boolean().describe("Whether the team can use dedicated runtime sites."),
70
+ dedicatedRuntime: z
71
+ .literal(true)
72
+ .describe("Dedicated runtime availability. Every team receives its own runtime site."),
71
73
  pagesTemplates: z
72
74
  .boolean()
73
75
  .describe("Whether _pages/*.html full-page takeovers compile for this team."),
@@ -75,23 +77,17 @@ export const teamEntitlementsSchema = z
75
77
  .boolean()
76
78
  .describe("Whether theme.hideSpacefastBranding removes the badge from default pages."),
77
79
  runtimePhpWorkers: z.number().int().describe("PHP workers per serving site."),
78
- analyticsHourlyGranularity: z
79
- .boolean()
80
- .describe("Whether analytics series resolve to hourly buckets (daily otherwise)."),
81
80
  versionDiagnosticsIncluded: z
82
81
  .boolean()
83
82
  .describe("Whether version diagnostics are included with the plan."),
84
83
  })
85
84
  .describe("Resolved entitlements for a team: plan limits after add-on grants.");
86
85
  // Wire projection of TeamEntitlements for GET /v1/teams/{teamId}/entitlements.
87
- // `versionRetentionDays`/`versionGatedKeepDays` (charter A3) and
88
- // `egressBytesPerDay` (abuse posture) are internal plan data — never on a wire
86
+ // `egressBytesPerDay` (abuse posture) is internal plan data — never on a wire
89
87
  // shape, mirroring PlanPolicyResponse's deliberate exclusion.
90
88
  export const teamEntitlementsResponseSchema = teamEntitlementsSchema
91
89
  .extend({
92
90
  limits: planLimitsSchema.omit({
93
- versionRetentionDays: true,
94
- versionGatedKeepDays: true,
95
91
  egressBytesPerDay: true,
96
92
  }),
97
93
  })
@@ -104,8 +100,6 @@ const UNLIMITED_LIMITS = {
104
100
  teamMembers: "unlimited",
105
101
  subTeams: "unlimited",
106
102
  externalDomainGroups: "unlimited",
107
- versionRetentionDays: "unlimited",
108
- versionGatedKeepDays: "unlimited",
109
103
  egressBytesPerDay: "unlimited",
110
104
  maxFileBytes: "unlimited",
111
105
  maxVersionFiles: "unlimited",
@@ -113,7 +107,6 @@ const UNLIMITED_LIMITS = {
113
107
  auditLogRetentionHours: "unlimited",
114
108
  buildAccessLogRetentionHours: "unlimited",
115
109
  buildsDeploysMonthly: "unlimited",
116
- analyticsRetentionDays: "unlimited",
117
110
  shareLinksPerSpace: "unlimited",
118
111
  invitesPerSpace: "unlimited",
119
112
  inviteEmailsPerSpaceDaily: "unlimited",
@@ -135,13 +128,16 @@ export const PLAN_DEFINITIONS = {
135
128
  code: "free",
136
129
  name: "Free",
137
130
  monthlyPriceUsd: 0,
131
+ yearlyPriceUsd: 0,
132
+ // Free is single-player: the owner is the only editor. Reviewers and
133
+ // agent principals are not seats.
134
+ includedSeats: 1,
135
+ extraSeatPriceUsd: null,
138
136
  limits: {
139
- storageBytes: 5 * GB,
140
- teamMembers: 3,
137
+ storageBytes: 10 * GB,
138
+ teamMembers: 1,
141
139
  subTeams: 0,
142
140
  externalDomainGroups: 3,
143
- versionRetentionDays: 30, // included full-retention window (charter A3)
144
- versionGatedKeepDays: 183, // kept gated ~6 months from readyAt, then deleted
145
141
  egressBytesPerDay: 100 * GB, // = worst-case ceiling; tunable per plan
146
142
  maxFileBytes: 50 * MB,
147
143
  maxVersionFiles: 20_000,
@@ -149,24 +145,26 @@ export const PLAN_DEFINITIONS = {
149
145
  auditLogRetentionHours: 48,
150
146
  buildAccessLogRetentionHours: 48,
151
147
  buildsDeploysMonthly: 100,
152
- analyticsRetentionDays: 30,
153
148
  ...ACCESS_QUOTA_DEFAULTS,
154
149
  },
155
150
  externalProxy: false,
156
- dedicatedRuntime: false,
157
151
  pagesTemplates: false,
158
152
  hideSpacefastBranding: false,
159
153
  runtimePhpWorkers: 2,
160
- analyticsHourlyGranularity: false,
161
154
  },
162
155
  personal: {
163
156
  code: "personal",
164
- name: "Personal",
165
- monthlyPriceUsd: 5,
157
+ name: "Plus",
158
+ monthlyPriceUsd: 4.99,
159
+ yearlyPriceUsd: 49.99,
160
+ includedSeats: 3,
161
+ // Each paid seat also raises usage limits (builds, domains, emails,
162
+ // versions) via additive grants — the seat price is not access alone.
163
+ extraSeatPriceUsd: { monthly: 4.99, yearly: 49.99 },
166
164
  limits: {
167
165
  ...UNLIMITED_LIMITS,
168
- storageBytes: 20 * GB,
169
- teamMembers: 5,
166
+ storageBytes: 50 * GB,
167
+ teamMembers: 3,
170
168
  subTeams: 0,
171
169
  externalDomainGroups: 10,
172
170
  maxFileBytes: 1 * GB,
@@ -174,61 +172,61 @@ export const PLAN_DEFINITIONS = {
174
172
  auditLogRetentionHours: MONTH_HOURS,
175
173
  buildAccessLogRetentionHours: MONTH_HOURS,
176
174
  buildsDeploysMonthly: 1000,
177
- analyticsRetentionDays: 365,
178
175
  ...ACCESS_QUOTA_DEFAULTS,
179
176
  },
180
177
  externalProxy: true,
181
- dedicatedRuntime: false,
182
178
  pagesTemplates: true,
183
179
  hideSpacefastBranding: true,
184
180
  runtimePhpWorkers: 4,
185
- analyticsHourlyGranularity: true,
186
181
  },
187
182
  work: {
188
183
  code: "work",
189
- name: "Work",
190
- monthlyPriceUsd: 15,
184
+ name: "Pro",
185
+ monthlyPriceUsd: 49.99,
186
+ yearlyPriceUsd: 499,
187
+ includedSeats: 10,
188
+ extraSeatPriceUsd: { monthly: 4.99, yearly: 49.99 },
191
189
  limits: {
192
190
  ...UNLIMITED_LIMITS,
193
- storageBytes: 50 * GB,
194
- // 15 seats included; the $1/seat add-on rides EntitlementGrant
195
- // ({ limit: "teamMembers", add: n }) grants are no-ops on
196
- // "unlimited" limits, so this must stay numeric.
197
- teamMembers: 15,
191
+ storageBytes: 200 * GB,
192
+ // The catalog keeps the included quantity numeric for display and seat
193
+ // billing. An active paid Stripe source lifts admission separately so
194
+ // editors beyond this number can be added and reconciled automatically.
195
+ teamMembers: 10,
198
196
  subTeams: 0,
199
197
  ...ACCESS_QUOTA_DEFAULTS,
200
198
  },
201
199
  externalProxy: true,
202
- dedicatedRuntime: false,
203
200
  pagesTemplates: true,
204
201
  hideSpacefastBranding: true,
205
202
  runtimePhpWorkers: 4,
206
- analyticsHourlyGranularity: true,
207
203
  },
208
204
  // Footnote-only publicly ("custom — talk to us"); manual grant, never self-serve.
209
205
  enterprise: {
210
206
  code: "enterprise",
211
207
  name: "Enterprise",
212
208
  monthlyPriceUsd: null,
209
+ yearlyPriceUsd: null,
210
+ includedSeats: "unlimited",
211
+ extraSeatPriceUsd: null,
213
212
  limits: { ...UNLIMITED_LIMITS },
214
213
  externalProxy: true,
215
- dedicatedRuntime: true,
216
214
  pagesTemplates: true,
217
215
  hideSpacefastBranding: true,
218
216
  runtimePhpWorkers: 4,
219
- analyticsHourlyGranularity: true,
220
217
  },
221
218
  internal: {
222
219
  code: "internal",
223
220
  name: "Internal",
224
221
  monthlyPriceUsd: null,
222
+ yearlyPriceUsd: null,
223
+ includedSeats: "unlimited",
224
+ extraSeatPriceUsd: null,
225
225
  limits: { ...UNLIMITED_LIMITS },
226
226
  externalProxy: true,
227
- dedicatedRuntime: true,
228
227
  pagesTemplates: true,
229
228
  hideSpacefastBranding: true,
230
229
  runtimePhpWorkers: 4,
231
- analyticsHourlyGranularity: true,
232
230
  },
233
231
  };
234
232
  export const FEATURE_DEFINITIONS = FEATURE_RUNTIME_DEFINITIONS;
@@ -262,3 +260,13 @@ export function featureDefaultForPlan(key, planCode) {
262
260
  export function planLimitNumber(value) {
263
261
  return value === "unlimited" ? null : value;
264
262
  }
263
+ /** Extra editor quantity billed on a paid Stripe subscription. */
264
+ export function extraSeatQuantity(editorMemberships, includedSeats) {
265
+ if (!Number.isInteger(editorMemberships) || editorMemberships < 0) {
266
+ throw new RangeError("Editor membership count must be a non-negative integer.");
267
+ }
268
+ return includedSeats === "unlimited" ? 0 : Math.max(0, editorMemberships - includedSeats);
269
+ }
270
+ export function planPriceUsd(plan, interval) {
271
+ return interval === "monthly" ? plan.monthlyPriceUsd : plan.yearlyPriceUsd;
272
+ }