atmn 1.1.25 → 2.0.1

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 (117) hide show
  1. package/README.md +120 -0
  2. package/dist/bin.js +23318 -0
  3. package/dist/index.js +2946 -0
  4. package/dist/tsconfig.tsbuildinfo +1 -1
  5. package/package.json +28 -74
  6. package/src/actions/api/callApi.ts +280 -0
  7. package/src/actions/api/registerApiCommands.ts +121 -0
  8. package/src/actions/env/fetchOrgInfo.ts +32 -0
  9. package/src/actions/env/types/orgInfo.ts +18 -0
  10. package/src/actions/env.ts +94 -0
  11. package/src/actions/init/runInit.ts +401 -0
  12. package/src/actions/login/keyless.ts +135 -0
  13. package/src/actions/login.ts +144 -0
  14. package/src/actions/pull/appendPlanVersionFixture.ts +373 -0
  15. package/src/actions/pull/applyPreview.ts +553 -0
  16. package/src/actions/pull/applySettingsPreview.ts +114 -0
  17. package/src/actions/pull/changedFixtureKeys.ts +88 -0
  18. package/src/actions/pull/listSourceFiles.ts +29 -0
  19. package/src/actions/pull/locateFixture.ts +78 -0
  20. package/src/actions/pull/resolveCollectionTarget.ts +198 -0
  21. package/src/actions/pull/rewriteConfig.ts +57 -0
  22. package/src/actions/pull/scaffoldConfig.ts +118 -0
  23. package/src/actions/pull.ts +399 -0
  24. package/src/actions/push/backfillInternalIds.ts +394 -0
  25. package/src/actions/push/deprecatedFields.ts +55 -0
  26. package/src/actions/push.ts +294 -0
  27. package/src/actions/reset/runReset.ts +58 -0
  28. package/src/actions/sandbox/createSandbox.ts +83 -0
  29. package/src/actions/sandbox/deleteSandbox.ts +91 -0
  30. package/src/actions/sandbox/listSandboxes.ts +28 -0
  31. package/src/actions/sandbox/types/sandboxClient.ts +16 -0
  32. package/src/actions/sandbox/useSandbox.ts +157 -0
  33. package/src/actions/sandbox/withSandboxScopeHint.ts +27 -0
  34. package/src/actions/skills/skills.ts +246 -0
  35. package/src/auth/announceAuthorizationUrl.ts +26 -0
  36. package/src/auth/browser/openSystemBrowser.ts +7 -0
  37. package/src/auth/browser/tryOpenBrowser.ts +17 -0
  38. package/src/auth/browser/watchLauncher.ts +46 -0
  39. package/src/auth/buildAuthorizationUrl.ts +36 -0
  40. package/src/auth/callbackPages.ts +126 -0
  41. package/src/auth/createOrgApiKeys.ts +46 -0
  42. package/src/auth/keyless.ts +119 -0
  43. package/src/auth/oauthConfig.ts +63 -0
  44. package/src/auth/runOAuthFlow.ts +230 -0
  45. package/src/auth/types/browserOpener.ts +5 -0
  46. package/src/auth/types/impersonationTokens.ts +23 -0
  47. package/src/auth/types/oauthTokens.ts +13 -0
  48. package/src/auth/types/orgApiKeys.ts +6 -0
  49. package/src/bin.ts +9 -0
  50. package/src/cli.ts +648 -0
  51. package/src/config/configPackageName.ts +9 -0
  52. package/src/config/legacyConfig.ts +25 -0
  53. package/src/config/loadConfig.ts +231 -0
  54. package/src/env/assertSandboxTarget.ts +20 -0
  55. package/src/env/loadEnv.ts +184 -0
  56. package/src/env/resolveTarget.ts +134 -0
  57. package/src/env/sandboxKeyName.ts +18 -0
  58. package/src/generated/apiRoutes.ts +3937 -0
  59. package/src/generated/client.ts +52579 -0
  60. package/src/generated/emit.ts +1188 -0
  61. package/src/generated/emitRuntime.ts +522 -0
  62. package/src/generated/features.ts +146 -0
  63. package/src/generated/labels.ts +29 -0
  64. package/src/generated/licenses.ts +292 -0
  65. package/src/generated/lintRules.ts +2247 -0
  66. package/src/generated/lintRuntime.ts +865 -0
  67. package/src/generated/plans.ts +1653 -0
  68. package/src/generated/referralPrograms.ts +22 -0
  69. package/src/generated/rewards.ts +58 -0
  70. package/src/generated/settings.ts +21 -0
  71. package/src/generated/skills.ts +305 -0
  72. package/src/generated/variants.ts +949 -0
  73. package/src/generated/wire.ts +334 -0
  74. package/src/http/autumnFetch.ts +30 -0
  75. package/src/index.ts +20 -0
  76. package/src/project/chooseConfigDir.ts +41 -0
  77. package/src/project/resolveProject.ts +115 -0
  78. package/src/project/rootMarker.ts +40 -0
  79. package/src/prompt/prompt.ts +186 -0
  80. package/src/prompt/select.ts +162 -0
  81. package/src/render/renderEnv.ts +77 -0
  82. package/src/render/renderPreview.ts +945 -0
  83. package/src/render/renderSandboxes.ts +92 -0
  84. package/src/render/stripTerminalControls.ts +19 -0
  85. package/src/repo/findRepoRoot.ts +79 -0
  86. package/src/surgery/appendPropertyEdit.ts +67 -0
  87. package/src/surgery/appendToArray.ts +87 -0
  88. package/src/surgery/appendToBinding.ts +19 -0
  89. package/src/surgery/appendToCollection.ts +40 -0
  90. package/src/surgery/appendToFixtureArray.ts +71 -0
  91. package/src/surgery/arrayBinding.ts +30 -0
  92. package/src/surgery/deleteFixtureLiteral.ts +81 -0
  93. package/src/surgery/deleteReference.ts +48 -0
  94. package/src/surgery/ensureBuilderImport.ts +65 -0
  95. package/src/surgery/findFixture.ts +238 -0
  96. package/src/surgery/fixtureEdit.ts +156 -0
  97. package/src/surgery/fixtureLocation.ts +32 -0
  98. package/src/surgery/insertCollection.ts +86 -0
  99. package/src/surgery/insertFirstProperty.ts +73 -0
  100. package/src/surgery/patchFixtureProperty.ts +152 -0
  101. package/src/surgery/patchSingletonProperty.ts +221 -0
  102. package/src/surgery/replaceFixture.ts +28 -0
  103. package/src/surgery/setFixtureProperty.ts +55 -0
  104. package/src/surgery/staticFixtureRule.ts +48 -0
  105. package/src/version.ts +5 -0
  106. package/dist/cli.js +0 -146296
  107. package/dist/compose/index.js +0 -122
  108. package/dist/src/compose/builders/builderFunctions.d.ts +0 -84
  109. package/dist/src/compose/builders/rewardFunctions.d.ts +0 -5
  110. package/dist/src/compose/builders/variantFunctions.d.ts +0 -2
  111. package/dist/src/compose/index.d.ts +0 -19
  112. package/dist/src/compose/models/featureModels.d.ts +0 -262
  113. package/dist/src/compose/models/index.d.ts +0 -3
  114. package/dist/src/compose/models/planModels.d.ts +0 -562
  115. package/dist/src/compose/models/rewardModels.d.ts +0 -52
  116. package/dist/src/compose/models/variantModels.d.ts +0 -34
  117. package/readme.md +0 -186
@@ -0,0 +1,2247 @@
1
+ // Generated by @autumn/atmn-generator from packages/openapi/openapi-internal.yml.
2
+ // Do not edit — run `bun generate` in packages/atmn-generator instead.
3
+
4
+ import type { LintRules } from "./lintRuntime.js";
5
+ export const LINT_RULES: LintRules = {
6
+ features: {
7
+ label: "feature",
8
+ idField: "featureId",
9
+ required: ["featureId", "name", "type"],
10
+ fields: {
11
+ type: {
12
+ enum: ["boolean", "metered", "credit_system", "ai_credit_system"],
13
+ },
14
+ defaultMarkup: {
15
+ minimum: -100,
16
+ },
17
+ internalId: {
18
+ minLength: 1,
19
+ },
20
+ },
21
+ rules: [
22
+ {
23
+ kind: "requiredWhen",
24
+ when: "type",
25
+ equals: "metered",
26
+ require: ["consumable"],
27
+ because:
28
+ "Omitting it silently creates a non-consumable feature, which never resets.",
29
+ },
30
+ {
31
+ kind: "unique",
32
+ field: "featureId",
33
+ because: "Two features claiming one id race to define the same row.",
34
+ },
35
+ {
36
+ kind: "unique",
37
+ field: "internalId",
38
+ because:
39
+ "A stable id names exactly one row; two fixtures cannot both be it.",
40
+ },
41
+ ],
42
+ },
43
+ "features.creditSchema": {
44
+ variants: {
45
+ on: "tierBehavior",
46
+ byValue: {
47
+ graduated: {
48
+ required: ["meteredFeatureId", "tierBehavior", "tiers"],
49
+ fields: {
50
+ meteredFeatureId: {
51
+ minLength: 1,
52
+ },
53
+ billingUnits: {
54
+ exclusiveMinimum: 0,
55
+ },
56
+ tierBehavior: {
57
+ enum: ["graduated"],
58
+ },
59
+ tiers: {
60
+ minItems: 1,
61
+ },
62
+ },
63
+ },
64
+ },
65
+ fallback: {
66
+ required: ["creditCost", "meteredFeatureId"],
67
+ fields: {
68
+ meteredFeatureId: {
69
+ minLength: 1,
70
+ },
71
+ billingUnits: {
72
+ exclusiveMinimum: 0,
73
+ },
74
+ creditCost: {
75
+ minimum: 0,
76
+ },
77
+ },
78
+ },
79
+ },
80
+ },
81
+ "features.creditSchema.dimensions": {
82
+ keys: {
83
+ minLength: 1,
84
+ maxLength: 64,
85
+ },
86
+ },
87
+ "features.creditSchema.dimensions.*": {
88
+ variants: {
89
+ on: "tierBehavior",
90
+ byValue: {
91
+ graduated: {
92
+ required: ["match", "tierBehavior", "tiers"],
93
+ fields: {
94
+ priority: {
95
+ minimum: -9007199254740991,
96
+ maximum: 9007199254740991,
97
+ },
98
+ tierBehavior: {
99
+ enum: ["graduated"],
100
+ },
101
+ tiers: {
102
+ minItems: 1,
103
+ },
104
+ },
105
+ },
106
+ },
107
+ fallback: {
108
+ required: ["creditCost", "match"],
109
+ fields: {
110
+ priority: {
111
+ minimum: -9007199254740991,
112
+ maximum: 9007199254740991,
113
+ },
114
+ creditCost: {
115
+ minimum: 0,
116
+ },
117
+ },
118
+ },
119
+ },
120
+ },
121
+ "features.creditSchema.dimensions.*.tiers": {
122
+ required: ["creditCost", "to"],
123
+ fields: {
124
+ to: {
125
+ exclusiveMinimum: 0,
126
+ },
127
+ creditCost: {
128
+ minimum: 0,
129
+ },
130
+ },
131
+ },
132
+ "features.creditSchema.multipliers": {
133
+ keys: {
134
+ minLength: 1,
135
+ maxLength: 64,
136
+ },
137
+ },
138
+ "features.creditSchema.multipliers.*": {
139
+ required: ["match"],
140
+ fields: {
141
+ factor: {
142
+ exclusiveMinimum: 0,
143
+ },
144
+ },
145
+ },
146
+ "features.creditSchema.tiers": {
147
+ required: ["creditCost", "to"],
148
+ fields: {
149
+ to: {
150
+ exclusiveMinimum: 0,
151
+ },
152
+ creditCost: {
153
+ minimum: 0,
154
+ },
155
+ },
156
+ },
157
+ "features.display": {
158
+ required: ["plural", "singular"],
159
+ },
160
+ "features.modelMarkups": {
161
+ keys: {
162
+ pattern: ".+\\/.+",
163
+ },
164
+ },
165
+ "features.modelMarkups.*": {
166
+ fields: {
167
+ markup: {
168
+ minimum: -100,
169
+ },
170
+ inputCost: {
171
+ minimum: 0,
172
+ },
173
+ outputCost: {
174
+ minimum: 0,
175
+ },
176
+ },
177
+ },
178
+ "features.providerMarkups.*": {
179
+ required: ["markup"],
180
+ fields: {
181
+ markup: {
182
+ minimum: -100,
183
+ },
184
+ },
185
+ },
186
+ plans: {
187
+ label: "plan",
188
+ idField: "planId",
189
+ required: ["planId", "versionSlug"],
190
+ fields: {
191
+ planId: {
192
+ minLength: 1,
193
+ pattern: "^[a-zA-Z0-9_-]+$",
194
+ },
195
+ newPlanId: {
196
+ minLength: 1,
197
+ pattern: "^[a-zA-Z0-9_-]+$",
198
+ },
199
+ internalId: {
200
+ minLength: 1,
201
+ },
202
+ name: {
203
+ minLength: 1,
204
+ },
205
+ version: {
206
+ minimum: 1,
207
+ maximum: 9007199254740991,
208
+ },
209
+ versionSlug: {
210
+ minLength: 1,
211
+ pattern: "^[a-zA-Z0-9_-]+$",
212
+ },
213
+ newVersionSlug: {
214
+ minLength: 1,
215
+ pattern: "^[a-zA-Z0-9_-]+$",
216
+ },
217
+ versioning: {
218
+ enum: ["existing", "new_version", "all_versions"],
219
+ },
220
+ baseVariantId: {
221
+ minLength: 1,
222
+ pattern: "^[a-zA-Z0-9_-]+$",
223
+ },
224
+ },
225
+ rules: [
226
+ {
227
+ kind: "unique",
228
+ field: "internalId",
229
+ because:
230
+ "A stable id names exactly one row; two fixtures cannot both be it.",
231
+ },
232
+ {
233
+ kind: "unique",
234
+ field: "planId",
235
+ alongside: "versionSlug",
236
+ because: "A plan id plus a version slug names exactly one version.",
237
+ },
238
+ {
239
+ kind: "linkedOnce",
240
+ groupBy: "planId",
241
+ namedBy: "versionSlug",
242
+ absentMeans: "v1",
243
+ collection: "variants",
244
+ identity: "variantPlanId",
245
+ pins: ["versionSlug", "version"],
246
+ because:
247
+ "When versioning a base plan with variants linked, you also need to version the variant, and relink the new version to the new variant version.",
248
+ },
249
+ {
250
+ kind: "exactlyOneActive",
251
+ groupBy: "planId",
252
+ field: "active",
253
+ label: "Plan",
254
+ because:
255
+ "Every version of a plan lives in plans; mark the one customers can buy active: true and the rest active: false.",
256
+ },
257
+ ],
258
+ },
259
+ "plans.billingControls.autoTopups": {
260
+ required: ["featureId", "quantity", "threshold"],
261
+ fields: {
262
+ quantity: {
263
+ minimum: 1,
264
+ },
265
+ },
266
+ },
267
+ "plans.billingControls.autoTopups.purchaseLimit": {
268
+ required: ["interval", "limit"],
269
+ fields: {
270
+ interval: {
271
+ enum: ["hour", "day", "week", "month"],
272
+ },
273
+ intervalCount: {
274
+ minimum: 1,
275
+ },
276
+ limit: {
277
+ minimum: 1,
278
+ },
279
+ count: {
280
+ minimum: 0,
281
+ },
282
+ },
283
+ },
284
+ "plans.billingControls.overageAllowed": {
285
+ required: ["featureId"],
286
+ },
287
+ "plans.billingControls.spendLimits": {
288
+ fields: {
289
+ limitType: {
290
+ enum: ["absolute", "usage_percentage"],
291
+ },
292
+ overageLimit: {
293
+ minimum: 0,
294
+ },
295
+ },
296
+ },
297
+ "plans.billingControls.usageAlerts": {
298
+ required: ["threshold", "thresholdType"],
299
+ fields: {
300
+ threshold: {
301
+ minimum: 0,
302
+ },
303
+ thresholdType: {
304
+ enum: [
305
+ "usage",
306
+ "usage_percentage",
307
+ "remaining",
308
+ "remaining_percentage",
309
+ ],
310
+ },
311
+ basis: {
312
+ enum: ["balance", "included", "recurring", "usage_limit"],
313
+ },
314
+ },
315
+ },
316
+ "plans.billingControls.usageAlerts.filter": {
317
+ required: ["properties"],
318
+ },
319
+ "plans.billingControls.usageAlerts.filter.properties": {
320
+ keys: {
321
+ minLength: 1,
322
+ maxLength: 64,
323
+ },
324
+ },
325
+ "plans.billingControls.usageLimits": {
326
+ required: ["featureId", "interval", "limit"],
327
+ fields: {
328
+ limit: {
329
+ minimum: 0,
330
+ },
331
+ interval: {
332
+ enum: ["day", "week", "month", "year"],
333
+ },
334
+ anchor: {
335
+ enum: ["billing_cycle", "utc"],
336
+ },
337
+ },
338
+ },
339
+ "plans.billingControls.usageLimits.filter": {
340
+ required: ["properties"],
341
+ },
342
+ "plans.billingControls.usageLimits.filter.properties": {
343
+ keys: {
344
+ minLength: 1,
345
+ maxLength: 64,
346
+ },
347
+ },
348
+ "plans.freeTrial": {
349
+ required: ["durationLength"],
350
+ fields: {
351
+ durationType: {
352
+ enum: ["day", "month", "year"],
353
+ },
354
+ onEnd: {
355
+ enum: ["bill", "revert"],
356
+ },
357
+ },
358
+ },
359
+ "plans.items": {
360
+ label: "item",
361
+ idField: "featureId",
362
+ required: ["featureId"],
363
+ fields: {
364
+ included: {
365
+ maximum: 10000000000000,
366
+ },
367
+ },
368
+ rules: [
369
+ {
370
+ kind: "exists",
371
+ field: "featureId",
372
+ in: "features",
373
+ matching: "featureId",
374
+ because: "A plan item meters a feature this config does not declare.",
375
+ },
376
+ {
377
+ kind: "targetHas",
378
+ when: "featureOverride",
379
+ field: "featureId",
380
+ in: "features",
381
+ matching: "featureId",
382
+ target: "type",
383
+ equals: "credit_system",
384
+ because:
385
+ "featureOverride is only honoured on classic credit-system features.",
386
+ },
387
+ {
388
+ kind: "targetLacks",
389
+ field: "featureId",
390
+ in: "features",
391
+ matching: "featureId",
392
+ target: "archived",
393
+ label: "Feature",
394
+ parentGuard: "archived",
395
+ parentIdField: "planId",
396
+ parentLabel: "plan",
397
+ because:
398
+ "An archived feature should not gain new customers through a live plan.",
399
+ },
400
+ ],
401
+ },
402
+ "plans.items.expiry": {
403
+ required: ["duration", "length"],
404
+ fields: {
405
+ duration: {
406
+ enum: ["day", "week", "month", "year"],
407
+ },
408
+ },
409
+ },
410
+ "plans.items.featureOverride.creditSchema": {
411
+ variants: {
412
+ on: "tierBehavior",
413
+ byValue: {
414
+ graduated: {
415
+ required: ["meteredFeatureId", "tierBehavior", "tiers"],
416
+ fields: {
417
+ meteredFeatureId: {
418
+ minLength: 1,
419
+ },
420
+ billingUnits: {
421
+ exclusiveMinimum: 0,
422
+ },
423
+ tierBehavior: {
424
+ enum: ["graduated"],
425
+ },
426
+ tiers: {
427
+ minItems: 1,
428
+ },
429
+ },
430
+ },
431
+ },
432
+ fallback: {
433
+ required: ["creditCost", "meteredFeatureId"],
434
+ fields: {
435
+ meteredFeatureId: {
436
+ minLength: 1,
437
+ },
438
+ billingUnits: {
439
+ exclusiveMinimum: 0,
440
+ },
441
+ creditCost: {
442
+ minimum: 0,
443
+ },
444
+ },
445
+ },
446
+ },
447
+ },
448
+ "plans.items.featureOverride.creditSchema.dimensions": {
449
+ keys: {
450
+ minLength: 1,
451
+ maxLength: 64,
452
+ },
453
+ },
454
+ "plans.items.featureOverride.creditSchema.dimensions.*": {
455
+ variants: {
456
+ on: "tierBehavior",
457
+ byValue: {
458
+ graduated: {
459
+ required: ["match", "tierBehavior", "tiers"],
460
+ fields: {
461
+ priority: {
462
+ minimum: -9007199254740991,
463
+ maximum: 9007199254740991,
464
+ },
465
+ tierBehavior: {
466
+ enum: ["graduated"],
467
+ },
468
+ tiers: {
469
+ minItems: 1,
470
+ },
471
+ },
472
+ },
473
+ },
474
+ fallback: {
475
+ required: ["creditCost", "match"],
476
+ fields: {
477
+ priority: {
478
+ minimum: -9007199254740991,
479
+ maximum: 9007199254740991,
480
+ },
481
+ creditCost: {
482
+ minimum: 0,
483
+ },
484
+ },
485
+ },
486
+ },
487
+ },
488
+ "plans.items.featureOverride.creditSchema.dimensions.*.tiers": {
489
+ required: ["creditCost", "to"],
490
+ fields: {
491
+ to: {
492
+ exclusiveMinimum: 0,
493
+ },
494
+ creditCost: {
495
+ minimum: 0,
496
+ },
497
+ },
498
+ },
499
+ "plans.items.featureOverride.creditSchema.multipliers": {
500
+ keys: {
501
+ minLength: 1,
502
+ maxLength: 64,
503
+ },
504
+ },
505
+ "plans.items.featureOverride.creditSchema.multipliers.*": {
506
+ required: ["match"],
507
+ fields: {
508
+ factor: {
509
+ exclusiveMinimum: 0,
510
+ },
511
+ },
512
+ },
513
+ "plans.items.featureOverride.creditSchema.tiers": {
514
+ required: ["creditCost", "to"],
515
+ fields: {
516
+ to: {
517
+ exclusiveMinimum: 0,
518
+ },
519
+ creditCost: {
520
+ minimum: 0,
521
+ },
522
+ },
523
+ },
524
+ "plans.items.featureOverride.markups": {
525
+ fields: {
526
+ defaultMarkup: {
527
+ minimum: -100,
528
+ },
529
+ },
530
+ },
531
+ "plans.items.featureOverride.markups.modelMarkups": {
532
+ keys: {
533
+ pattern: ".+\\/.+",
534
+ },
535
+ },
536
+ "plans.items.featureOverride.markups.modelMarkups.*": {
537
+ fields: {
538
+ markup: {
539
+ minimum: -100,
540
+ },
541
+ inputCost: {
542
+ minimum: 0,
543
+ },
544
+ outputCost: {
545
+ minimum: 0,
546
+ },
547
+ },
548
+ },
549
+ "plans.items.featureOverride.markups.providerMarkups.*": {
550
+ required: ["markup"],
551
+ fields: {
552
+ markup: {
553
+ minimum: -100,
554
+ },
555
+ },
556
+ },
557
+ "plans.items.price": {
558
+ label: "price",
559
+ required: ["billingMethod", "interval"],
560
+ fields: {
561
+ tierBehavior: {
562
+ enum: ["graduated", "volume"],
563
+ },
564
+ interval: {
565
+ enum: ["one_off", "week", "month", "quarter", "semi_annual", "year"],
566
+ },
567
+ billingMethod: {
568
+ enum: ["prepaid", "usage_based"],
569
+ },
570
+ allocatedBilling: {
571
+ enum: ["arrear", "prorated_legacy"],
572
+ },
573
+ },
574
+ rules: [
575
+ {
576
+ kind: "valueWhen",
577
+ when: "tierBehavior",
578
+ equals: "volume",
579
+ field: "billingMethod",
580
+ mustBe: "prepaid",
581
+ because: "Volume tiers are prepaid-only.",
582
+ },
583
+ ],
584
+ },
585
+ "plans.items.price.additionalCurrencies": {
586
+ required: ["amount", "currency"],
587
+ },
588
+ "plans.items.price.processors.stripe": {
589
+ required: ["priceId"],
590
+ },
591
+ "plans.items.price.tiers": {
592
+ required: ["to"],
593
+ },
594
+ "plans.items.price.tiers.additionalCurrencies": {
595
+ required: ["currency"],
596
+ },
597
+ "plans.items.proration": {
598
+ required: ["onDecrease", "onIncrease"],
599
+ fields: {
600
+ onIncrease: {
601
+ enum: [
602
+ "bill_immediately",
603
+ "prorate_immediately",
604
+ "prorate_next_cycle",
605
+ "bill_next_cycle",
606
+ ],
607
+ },
608
+ onDecrease: {
609
+ enum: [
610
+ "prorate",
611
+ "prorate_immediately",
612
+ "prorate_next_cycle",
613
+ "none",
614
+ "no_prorations",
615
+ ],
616
+ },
617
+ },
618
+ },
619
+ "plans.items.reset": {
620
+ required: ["interval"],
621
+ fields: {
622
+ interval: {
623
+ enum: [
624
+ "one_off",
625
+ "minute",
626
+ "hour",
627
+ "day",
628
+ "week",
629
+ "month",
630
+ "quarter",
631
+ "semi_annual",
632
+ "year",
633
+ ],
634
+ },
635
+ },
636
+ },
637
+ "plans.items.rollover": {
638
+ required: ["expiryDurationType"],
639
+ fields: {
640
+ expiryDurationType: {
641
+ enum: ["month", "forever"],
642
+ },
643
+ },
644
+ },
645
+ "plans.items.thresholdBilling": {
646
+ required: ["threshold"],
647
+ fields: {
648
+ threshold: {
649
+ exclusiveMinimum: 0,
650
+ },
651
+ },
652
+ },
653
+ "plans.licenses": {
654
+ label: "license",
655
+ idField: "licensePlanId",
656
+ required: ["licensePlanId", "versionSlug"],
657
+ fields: {
658
+ included: {
659
+ minimum: 0,
660
+ maximum: 9007199254740991,
661
+ },
662
+ },
663
+ },
664
+ "plans.licenses.customize.addItems": {
665
+ required: ["featureId"],
666
+ fields: {
667
+ included: {
668
+ maximum: 10000000000000,
669
+ },
670
+ },
671
+ },
672
+ "plans.licenses.customize.addItems.expiry": {
673
+ required: ["duration", "length"],
674
+ fields: {
675
+ duration: {
676
+ enum: ["day", "week", "month", "year"],
677
+ },
678
+ },
679
+ },
680
+ "plans.licenses.customize.addItems.featureOverride.creditSchema": {
681
+ variants: {
682
+ on: "tierBehavior",
683
+ byValue: {
684
+ graduated: {
685
+ required: ["meteredFeatureId", "tierBehavior", "tiers"],
686
+ fields: {
687
+ meteredFeatureId: {
688
+ minLength: 1,
689
+ },
690
+ billingUnits: {
691
+ exclusiveMinimum: 0,
692
+ },
693
+ tierBehavior: {
694
+ enum: ["graduated"],
695
+ },
696
+ tiers: {
697
+ minItems: 1,
698
+ },
699
+ },
700
+ },
701
+ },
702
+ fallback: {
703
+ required: ["creditCost", "meteredFeatureId"],
704
+ fields: {
705
+ meteredFeatureId: {
706
+ minLength: 1,
707
+ },
708
+ billingUnits: {
709
+ exclusiveMinimum: 0,
710
+ },
711
+ creditCost: {
712
+ minimum: 0,
713
+ },
714
+ },
715
+ },
716
+ },
717
+ },
718
+ "plans.licenses.customize.addItems.featureOverride.creditSchema.dimensions": {
719
+ keys: {
720
+ minLength: 1,
721
+ maxLength: 64,
722
+ },
723
+ },
724
+ "plans.licenses.customize.addItems.featureOverride.creditSchema.dimensions.*":
725
+ {
726
+ variants: {
727
+ on: "tierBehavior",
728
+ byValue: {
729
+ graduated: {
730
+ required: ["match", "tierBehavior", "tiers"],
731
+ fields: {
732
+ priority: {
733
+ minimum: -9007199254740991,
734
+ maximum: 9007199254740991,
735
+ },
736
+ tierBehavior: {
737
+ enum: ["graduated"],
738
+ },
739
+ tiers: {
740
+ minItems: 1,
741
+ },
742
+ },
743
+ },
744
+ },
745
+ fallback: {
746
+ required: ["creditCost", "match"],
747
+ fields: {
748
+ priority: {
749
+ minimum: -9007199254740991,
750
+ maximum: 9007199254740991,
751
+ },
752
+ creditCost: {
753
+ minimum: 0,
754
+ },
755
+ },
756
+ },
757
+ },
758
+ },
759
+ "plans.licenses.customize.addItems.featureOverride.creditSchema.dimensions.*.tiers":
760
+ {
761
+ required: ["creditCost", "to"],
762
+ fields: {
763
+ to: {
764
+ exclusiveMinimum: 0,
765
+ },
766
+ creditCost: {
767
+ minimum: 0,
768
+ },
769
+ },
770
+ },
771
+ "plans.licenses.customize.addItems.featureOverride.creditSchema.multipliers":
772
+ {
773
+ keys: {
774
+ minLength: 1,
775
+ maxLength: 64,
776
+ },
777
+ },
778
+ "plans.licenses.customize.addItems.featureOverride.creditSchema.multipliers.*":
779
+ {
780
+ required: ["match"],
781
+ fields: {
782
+ factor: {
783
+ exclusiveMinimum: 0,
784
+ },
785
+ },
786
+ },
787
+ "plans.licenses.customize.addItems.featureOverride.creditSchema.tiers": {
788
+ required: ["creditCost", "to"],
789
+ fields: {
790
+ to: {
791
+ exclusiveMinimum: 0,
792
+ },
793
+ creditCost: {
794
+ minimum: 0,
795
+ },
796
+ },
797
+ },
798
+ "plans.licenses.customize.addItems.featureOverride.markups": {
799
+ fields: {
800
+ defaultMarkup: {
801
+ minimum: -100,
802
+ },
803
+ },
804
+ },
805
+ "plans.licenses.customize.addItems.featureOverride.markups.modelMarkups": {
806
+ keys: {
807
+ pattern: ".+\\/.+",
808
+ },
809
+ },
810
+ "plans.licenses.customize.addItems.featureOverride.markups.modelMarkups.*": {
811
+ fields: {
812
+ markup: {
813
+ minimum: -100,
814
+ },
815
+ inputCost: {
816
+ minimum: 0,
817
+ },
818
+ outputCost: {
819
+ minimum: 0,
820
+ },
821
+ },
822
+ },
823
+ "plans.licenses.customize.addItems.featureOverride.markups.providerMarkups.*":
824
+ {
825
+ required: ["markup"],
826
+ fields: {
827
+ markup: {
828
+ minimum: -100,
829
+ },
830
+ },
831
+ },
832
+ "plans.licenses.customize.addItems.price": {
833
+ required: ["billingMethod", "interval"],
834
+ fields: {
835
+ tierBehavior: {
836
+ enum: ["graduated", "volume"],
837
+ },
838
+ interval: {
839
+ enum: ["one_off", "week", "month", "quarter", "semi_annual", "year"],
840
+ },
841
+ billingMethod: {
842
+ enum: ["prepaid", "usage_based"],
843
+ },
844
+ allocatedBilling: {
845
+ enum: ["arrear", "prorated_legacy"],
846
+ },
847
+ },
848
+ },
849
+ "plans.licenses.customize.addItems.price.additionalCurrencies": {
850
+ required: ["amount", "currency"],
851
+ },
852
+ "plans.licenses.customize.addItems.price.tiers": {
853
+ required: ["to"],
854
+ },
855
+ "plans.licenses.customize.addItems.price.tiers.additionalCurrencies": {
856
+ required: ["currency"],
857
+ },
858
+ "plans.licenses.customize.addItems.proration": {
859
+ required: ["onDecrease", "onIncrease"],
860
+ fields: {
861
+ onIncrease: {
862
+ enum: [
863
+ "bill_immediately",
864
+ "prorate_immediately",
865
+ "prorate_next_cycle",
866
+ "bill_next_cycle",
867
+ ],
868
+ },
869
+ onDecrease: {
870
+ enum: [
871
+ "prorate",
872
+ "prorate_immediately",
873
+ "prorate_next_cycle",
874
+ "none",
875
+ "no_prorations",
876
+ ],
877
+ },
878
+ },
879
+ },
880
+ "plans.licenses.customize.addItems.reset": {
881
+ required: ["interval"],
882
+ fields: {
883
+ interval: {
884
+ enum: [
885
+ "one_off",
886
+ "minute",
887
+ "hour",
888
+ "day",
889
+ "week",
890
+ "month",
891
+ "quarter",
892
+ "semi_annual",
893
+ "year",
894
+ ],
895
+ },
896
+ },
897
+ },
898
+ "plans.licenses.customize.addItems.rollover": {
899
+ required: ["expiryDurationType"],
900
+ fields: {
901
+ expiryDurationType: {
902
+ enum: ["month", "forever"],
903
+ },
904
+ },
905
+ },
906
+ "plans.licenses.customize.addItems.thresholdBilling": {
907
+ required: ["threshold"],
908
+ fields: {
909
+ threshold: {
910
+ exclusiveMinimum: 0,
911
+ },
912
+ },
913
+ },
914
+ "plans.licenses.customize.price": {
915
+ required: ["amount", "interval"],
916
+ fields: {
917
+ interval: {
918
+ enum: ["one_off", "week", "month", "quarter", "semi_annual", "year"],
919
+ },
920
+ },
921
+ },
922
+ "plans.licenses.customize.price.additionalCurrencies": {
923
+ required: ["amount", "currency"],
924
+ },
925
+ "plans.licenses.customize.removeItems": {
926
+ fields: {
927
+ billingMethod: {
928
+ enum: ["prepaid", "usage_based"],
929
+ },
930
+ interval: {
931
+ enum: [
932
+ "one_off",
933
+ "week",
934
+ "month",
935
+ "quarter",
936
+ "semi_annual",
937
+ "year",
938
+ "minute",
939
+ "hour",
940
+ "day",
941
+ ],
942
+ },
943
+ intervalCount: {
944
+ minimum: -9007199254740991,
945
+ maximum: 9007199254740991,
946
+ exclusiveMinimum: 0,
947
+ },
948
+ included: {
949
+ maximum: 10000000000000,
950
+ },
951
+ },
952
+ },
953
+ "plans.price": {
954
+ required: ["amount", "interval"],
955
+ fields: {
956
+ interval: {
957
+ enum: ["one_off", "week", "month", "quarter", "semi_annual", "year"],
958
+ },
959
+ },
960
+ },
961
+ "plans.price.additionalCurrencies": {
962
+ required: ["amount", "currency"],
963
+ },
964
+ "plans.price.processors.stripe": {
965
+ required: ["priceId"],
966
+ },
967
+ "plans.processors.revenuecat": {
968
+ required: ["products"],
969
+ },
970
+ "plans.processors.revenuecat.products": {
971
+ required: ["productId"],
972
+ },
973
+ "plans.processors.revenuecat.products.featureQuantities": {
974
+ required: ["featureId"],
975
+ fields: {
976
+ quantity: {
977
+ minimum: 0,
978
+ },
979
+ },
980
+ },
981
+ "plans.processors.stripe": {
982
+ required: ["productId"],
983
+ },
984
+ "plans.propagate.licenseParents": {
985
+ required: ["planId"],
986
+ fields: {
987
+ planId: {
988
+ minLength: 1,
989
+ pattern: "^[a-zA-Z0-9_-]+$",
990
+ },
991
+ version: {
992
+ minimum: 1,
993
+ maximum: 9007199254740991,
994
+ },
995
+ versionSlug: {
996
+ minLength: 1,
997
+ pattern: "^[a-zA-Z0-9_-]+$",
998
+ },
999
+ newVersionSlug: {
1000
+ minLength: 1,
1001
+ pattern: "^[a-zA-Z0-9_-]+$",
1002
+ },
1003
+ },
1004
+ },
1005
+ "plans.propagate.variants": {
1006
+ required: ["planId"],
1007
+ fields: {
1008
+ planId: {
1009
+ minLength: 1,
1010
+ pattern: "^[a-zA-Z0-9_-]+$",
1011
+ },
1012
+ version: {
1013
+ minimum: 1,
1014
+ maximum: 9007199254740991,
1015
+ },
1016
+ versionSlug: {
1017
+ minLength: 1,
1018
+ pattern: "^[a-zA-Z0-9_-]+$",
1019
+ },
1020
+ newVersionSlug: {
1021
+ minLength: 1,
1022
+ pattern: "^[a-zA-Z0-9_-]+$",
1023
+ },
1024
+ },
1025
+ },
1026
+ "plans.variants": {
1027
+ label: "variant",
1028
+ idField: "variantPlanId",
1029
+ required: ["variantPlanId", "versionSlug"],
1030
+ fields: {
1031
+ variantPlanId: {
1032
+ minLength: 1,
1033
+ pattern: "^[a-zA-Z0-9_-]+$",
1034
+ },
1035
+ internalId: {
1036
+ minLength: 1,
1037
+ },
1038
+ version: {
1039
+ minimum: 1,
1040
+ maximum: 9007199254740991,
1041
+ },
1042
+ versionSlug: {
1043
+ minLength: 1,
1044
+ pattern: "^[a-zA-Z0-9_-]+$",
1045
+ },
1046
+ name: {
1047
+ minLength: 1,
1048
+ },
1049
+ newPlanId: {
1050
+ minLength: 1,
1051
+ pattern: "^[a-zA-Z0-9_-]+$",
1052
+ },
1053
+ newVersionSlug: {
1054
+ minLength: 1,
1055
+ pattern: "^[a-zA-Z0-9_-]+$",
1056
+ },
1057
+ baseVariantId: {
1058
+ minLength: 1,
1059
+ pattern: "^[a-zA-Z0-9_-]+$",
1060
+ },
1061
+ },
1062
+ },
1063
+ "plans.variants.customize.addItems": {
1064
+ required: ["featureId"],
1065
+ fields: {
1066
+ included: {
1067
+ maximum: 10000000000000,
1068
+ },
1069
+ },
1070
+ },
1071
+ "plans.variants.customize.addItems.expiry": {
1072
+ required: ["duration", "length"],
1073
+ fields: {
1074
+ duration: {
1075
+ enum: ["day", "week", "month", "year"],
1076
+ },
1077
+ },
1078
+ },
1079
+ "plans.variants.customize.addItems.featureOverride.creditSchema": {
1080
+ variants: {
1081
+ on: "tierBehavior",
1082
+ byValue: {
1083
+ graduated: {
1084
+ required: ["meteredFeatureId", "tierBehavior", "tiers"],
1085
+ fields: {
1086
+ meteredFeatureId: {
1087
+ minLength: 1,
1088
+ },
1089
+ billingUnits: {
1090
+ exclusiveMinimum: 0,
1091
+ },
1092
+ tierBehavior: {
1093
+ enum: ["graduated"],
1094
+ },
1095
+ tiers: {
1096
+ minItems: 1,
1097
+ },
1098
+ },
1099
+ },
1100
+ },
1101
+ fallback: {
1102
+ required: ["creditCost", "meteredFeatureId"],
1103
+ fields: {
1104
+ meteredFeatureId: {
1105
+ minLength: 1,
1106
+ },
1107
+ billingUnits: {
1108
+ exclusiveMinimum: 0,
1109
+ },
1110
+ creditCost: {
1111
+ minimum: 0,
1112
+ },
1113
+ },
1114
+ },
1115
+ },
1116
+ },
1117
+ "plans.variants.customize.addItems.featureOverride.creditSchema.dimensions": {
1118
+ keys: {
1119
+ minLength: 1,
1120
+ maxLength: 64,
1121
+ },
1122
+ },
1123
+ "plans.variants.customize.addItems.featureOverride.creditSchema.dimensions.*":
1124
+ {
1125
+ variants: {
1126
+ on: "tierBehavior",
1127
+ byValue: {
1128
+ graduated: {
1129
+ required: ["match", "tierBehavior", "tiers"],
1130
+ fields: {
1131
+ priority: {
1132
+ minimum: -9007199254740991,
1133
+ maximum: 9007199254740991,
1134
+ },
1135
+ tierBehavior: {
1136
+ enum: ["graduated"],
1137
+ },
1138
+ tiers: {
1139
+ minItems: 1,
1140
+ },
1141
+ },
1142
+ },
1143
+ },
1144
+ fallback: {
1145
+ required: ["creditCost", "match"],
1146
+ fields: {
1147
+ priority: {
1148
+ minimum: -9007199254740991,
1149
+ maximum: 9007199254740991,
1150
+ },
1151
+ creditCost: {
1152
+ minimum: 0,
1153
+ },
1154
+ },
1155
+ },
1156
+ },
1157
+ },
1158
+ "plans.variants.customize.addItems.featureOverride.creditSchema.dimensions.*.tiers":
1159
+ {
1160
+ required: ["creditCost", "to"],
1161
+ fields: {
1162
+ to: {
1163
+ exclusiveMinimum: 0,
1164
+ },
1165
+ creditCost: {
1166
+ minimum: 0,
1167
+ },
1168
+ },
1169
+ },
1170
+ "plans.variants.customize.addItems.featureOverride.creditSchema.multipliers":
1171
+ {
1172
+ keys: {
1173
+ minLength: 1,
1174
+ maxLength: 64,
1175
+ },
1176
+ },
1177
+ "plans.variants.customize.addItems.featureOverride.creditSchema.multipliers.*":
1178
+ {
1179
+ required: ["match"],
1180
+ fields: {
1181
+ factor: {
1182
+ exclusiveMinimum: 0,
1183
+ },
1184
+ },
1185
+ },
1186
+ "plans.variants.customize.addItems.featureOverride.creditSchema.tiers": {
1187
+ required: ["creditCost", "to"],
1188
+ fields: {
1189
+ to: {
1190
+ exclusiveMinimum: 0,
1191
+ },
1192
+ creditCost: {
1193
+ minimum: 0,
1194
+ },
1195
+ },
1196
+ },
1197
+ "plans.variants.customize.addItems.featureOverride.markups": {
1198
+ fields: {
1199
+ defaultMarkup: {
1200
+ minimum: -100,
1201
+ },
1202
+ },
1203
+ },
1204
+ "plans.variants.customize.addItems.featureOverride.markups.modelMarkups": {
1205
+ keys: {
1206
+ pattern: ".+\\/.+",
1207
+ },
1208
+ },
1209
+ "plans.variants.customize.addItems.featureOverride.markups.modelMarkups.*": {
1210
+ fields: {
1211
+ markup: {
1212
+ minimum: -100,
1213
+ },
1214
+ inputCost: {
1215
+ minimum: 0,
1216
+ },
1217
+ outputCost: {
1218
+ minimum: 0,
1219
+ },
1220
+ },
1221
+ },
1222
+ "plans.variants.customize.addItems.featureOverride.markups.providerMarkups.*":
1223
+ {
1224
+ required: ["markup"],
1225
+ fields: {
1226
+ markup: {
1227
+ minimum: -100,
1228
+ },
1229
+ },
1230
+ },
1231
+ "plans.variants.customize.addItems.price": {
1232
+ required: ["billingMethod", "interval"],
1233
+ fields: {
1234
+ tierBehavior: {
1235
+ enum: ["graduated", "volume"],
1236
+ },
1237
+ interval: {
1238
+ enum: ["one_off", "week", "month", "quarter", "semi_annual", "year"],
1239
+ },
1240
+ billingMethod: {
1241
+ enum: ["prepaid", "usage_based"],
1242
+ },
1243
+ allocatedBilling: {
1244
+ enum: ["arrear", "prorated_legacy"],
1245
+ },
1246
+ },
1247
+ },
1248
+ "plans.variants.customize.addItems.price.additionalCurrencies": {
1249
+ required: ["amount", "currency"],
1250
+ },
1251
+ "plans.variants.customize.addItems.price.tiers": {
1252
+ required: ["to"],
1253
+ },
1254
+ "plans.variants.customize.addItems.price.tiers.additionalCurrencies": {
1255
+ required: ["currency"],
1256
+ },
1257
+ "plans.variants.customize.addItems.proration": {
1258
+ required: ["onDecrease", "onIncrease"],
1259
+ fields: {
1260
+ onIncrease: {
1261
+ enum: [
1262
+ "bill_immediately",
1263
+ "prorate_immediately",
1264
+ "prorate_next_cycle",
1265
+ "bill_next_cycle",
1266
+ ],
1267
+ },
1268
+ onDecrease: {
1269
+ enum: [
1270
+ "prorate",
1271
+ "prorate_immediately",
1272
+ "prorate_next_cycle",
1273
+ "none",
1274
+ "no_prorations",
1275
+ ],
1276
+ },
1277
+ },
1278
+ },
1279
+ "plans.variants.customize.addItems.reset": {
1280
+ required: ["interval"],
1281
+ fields: {
1282
+ interval: {
1283
+ enum: [
1284
+ "one_off",
1285
+ "minute",
1286
+ "hour",
1287
+ "day",
1288
+ "week",
1289
+ "month",
1290
+ "quarter",
1291
+ "semi_annual",
1292
+ "year",
1293
+ ],
1294
+ },
1295
+ },
1296
+ },
1297
+ "plans.variants.customize.addItems.rollover": {
1298
+ required: ["expiryDurationType"],
1299
+ fields: {
1300
+ expiryDurationType: {
1301
+ enum: ["month", "forever"],
1302
+ },
1303
+ },
1304
+ },
1305
+ "plans.variants.customize.addItems.thresholdBilling": {
1306
+ required: ["threshold"],
1307
+ fields: {
1308
+ threshold: {
1309
+ exclusiveMinimum: 0,
1310
+ },
1311
+ },
1312
+ },
1313
+ "plans.variants.customize.billingControls.autoTopups": {
1314
+ required: ["featureId", "quantity", "threshold"],
1315
+ fields: {
1316
+ quantity: {
1317
+ minimum: 1,
1318
+ },
1319
+ },
1320
+ },
1321
+ "plans.variants.customize.billingControls.autoTopups.purchaseLimit": {
1322
+ required: ["interval", "limit"],
1323
+ fields: {
1324
+ interval: {
1325
+ enum: ["hour", "day", "week", "month"],
1326
+ },
1327
+ intervalCount: {
1328
+ minimum: 1,
1329
+ },
1330
+ limit: {
1331
+ minimum: 1,
1332
+ },
1333
+ count: {
1334
+ minimum: 0,
1335
+ },
1336
+ },
1337
+ },
1338
+ "plans.variants.customize.billingControls.overageAllowed": {
1339
+ required: ["featureId"],
1340
+ },
1341
+ "plans.variants.customize.billingControls.spendLimits": {
1342
+ fields: {
1343
+ limitType: {
1344
+ enum: ["absolute", "usage_percentage"],
1345
+ },
1346
+ overageLimit: {
1347
+ minimum: 0,
1348
+ },
1349
+ },
1350
+ },
1351
+ "plans.variants.customize.billingControls.usageAlerts": {
1352
+ required: ["threshold", "thresholdType"],
1353
+ fields: {
1354
+ threshold: {
1355
+ minimum: 0,
1356
+ },
1357
+ thresholdType: {
1358
+ enum: [
1359
+ "usage",
1360
+ "usage_percentage",
1361
+ "remaining",
1362
+ "remaining_percentage",
1363
+ ],
1364
+ },
1365
+ basis: {
1366
+ enum: ["balance", "included", "recurring", "usage_limit"],
1367
+ },
1368
+ },
1369
+ },
1370
+ "plans.variants.customize.billingControls.usageAlerts.filter": {
1371
+ required: ["properties"],
1372
+ },
1373
+ "plans.variants.customize.billingControls.usageAlerts.filter.properties": {
1374
+ keys: {
1375
+ minLength: 1,
1376
+ maxLength: 64,
1377
+ },
1378
+ },
1379
+ "plans.variants.customize.billingControls.usageLimits": {
1380
+ required: ["featureId", "interval", "limit"],
1381
+ fields: {
1382
+ limit: {
1383
+ minimum: 0,
1384
+ },
1385
+ interval: {
1386
+ enum: ["day", "week", "month", "year"],
1387
+ },
1388
+ anchor: {
1389
+ enum: ["billing_cycle", "utc"],
1390
+ },
1391
+ },
1392
+ },
1393
+ "plans.variants.customize.billingControls.usageLimits.filter": {
1394
+ required: ["properties"],
1395
+ },
1396
+ "plans.variants.customize.billingControls.usageLimits.filter.properties": {
1397
+ keys: {
1398
+ minLength: 1,
1399
+ maxLength: 64,
1400
+ },
1401
+ },
1402
+ "plans.variants.customize.freeTrial": {
1403
+ required: ["durationLength"],
1404
+ fields: {
1405
+ durationType: {
1406
+ enum: ["day", "month", "year"],
1407
+ },
1408
+ onEnd: {
1409
+ enum: ["bill", "revert"],
1410
+ },
1411
+ },
1412
+ },
1413
+ "plans.variants.customize.items": {
1414
+ required: ["featureId"],
1415
+ fields: {
1416
+ included: {
1417
+ maximum: 10000000000000,
1418
+ },
1419
+ },
1420
+ },
1421
+ "plans.variants.customize.items.expiry": {
1422
+ required: ["duration", "length"],
1423
+ fields: {
1424
+ duration: {
1425
+ enum: ["day", "week", "month", "year"],
1426
+ },
1427
+ },
1428
+ },
1429
+ "plans.variants.customize.items.featureOverride.creditSchema": {
1430
+ variants: {
1431
+ on: "tierBehavior",
1432
+ byValue: {
1433
+ graduated: {
1434
+ required: ["meteredFeatureId", "tierBehavior", "tiers"],
1435
+ fields: {
1436
+ meteredFeatureId: {
1437
+ minLength: 1,
1438
+ },
1439
+ billingUnits: {
1440
+ exclusiveMinimum: 0,
1441
+ },
1442
+ tierBehavior: {
1443
+ enum: ["graduated"],
1444
+ },
1445
+ tiers: {
1446
+ minItems: 1,
1447
+ },
1448
+ },
1449
+ },
1450
+ },
1451
+ fallback: {
1452
+ required: ["creditCost", "meteredFeatureId"],
1453
+ fields: {
1454
+ meteredFeatureId: {
1455
+ minLength: 1,
1456
+ },
1457
+ billingUnits: {
1458
+ exclusiveMinimum: 0,
1459
+ },
1460
+ creditCost: {
1461
+ minimum: 0,
1462
+ },
1463
+ },
1464
+ },
1465
+ },
1466
+ },
1467
+ "plans.variants.customize.items.featureOverride.creditSchema.dimensions": {
1468
+ keys: {
1469
+ minLength: 1,
1470
+ maxLength: 64,
1471
+ },
1472
+ },
1473
+ "plans.variants.customize.items.featureOverride.creditSchema.dimensions.*": {
1474
+ variants: {
1475
+ on: "tierBehavior",
1476
+ byValue: {
1477
+ graduated: {
1478
+ required: ["match", "tierBehavior", "tiers"],
1479
+ fields: {
1480
+ priority: {
1481
+ minimum: -9007199254740991,
1482
+ maximum: 9007199254740991,
1483
+ },
1484
+ tierBehavior: {
1485
+ enum: ["graduated"],
1486
+ },
1487
+ tiers: {
1488
+ minItems: 1,
1489
+ },
1490
+ },
1491
+ },
1492
+ },
1493
+ fallback: {
1494
+ required: ["creditCost", "match"],
1495
+ fields: {
1496
+ priority: {
1497
+ minimum: -9007199254740991,
1498
+ maximum: 9007199254740991,
1499
+ },
1500
+ creditCost: {
1501
+ minimum: 0,
1502
+ },
1503
+ },
1504
+ },
1505
+ },
1506
+ },
1507
+ "plans.variants.customize.items.featureOverride.creditSchema.dimensions.*.tiers":
1508
+ {
1509
+ required: ["creditCost", "to"],
1510
+ fields: {
1511
+ to: {
1512
+ exclusiveMinimum: 0,
1513
+ },
1514
+ creditCost: {
1515
+ minimum: 0,
1516
+ },
1517
+ },
1518
+ },
1519
+ "plans.variants.customize.items.featureOverride.creditSchema.multipliers": {
1520
+ keys: {
1521
+ minLength: 1,
1522
+ maxLength: 64,
1523
+ },
1524
+ },
1525
+ "plans.variants.customize.items.featureOverride.creditSchema.multipliers.*": {
1526
+ required: ["match"],
1527
+ fields: {
1528
+ factor: {
1529
+ exclusiveMinimum: 0,
1530
+ },
1531
+ },
1532
+ },
1533
+ "plans.variants.customize.items.featureOverride.creditSchema.tiers": {
1534
+ required: ["creditCost", "to"],
1535
+ fields: {
1536
+ to: {
1537
+ exclusiveMinimum: 0,
1538
+ },
1539
+ creditCost: {
1540
+ minimum: 0,
1541
+ },
1542
+ },
1543
+ },
1544
+ "plans.variants.customize.items.featureOverride.markups": {
1545
+ fields: {
1546
+ defaultMarkup: {
1547
+ minimum: -100,
1548
+ },
1549
+ },
1550
+ },
1551
+ "plans.variants.customize.items.featureOverride.markups.modelMarkups": {
1552
+ keys: {
1553
+ pattern: ".+\\/.+",
1554
+ },
1555
+ },
1556
+ "plans.variants.customize.items.featureOverride.markups.modelMarkups.*": {
1557
+ fields: {
1558
+ markup: {
1559
+ minimum: -100,
1560
+ },
1561
+ inputCost: {
1562
+ minimum: 0,
1563
+ },
1564
+ outputCost: {
1565
+ minimum: 0,
1566
+ },
1567
+ },
1568
+ },
1569
+ "plans.variants.customize.items.featureOverride.markups.providerMarkups.*": {
1570
+ required: ["markup"],
1571
+ fields: {
1572
+ markup: {
1573
+ minimum: -100,
1574
+ },
1575
+ },
1576
+ },
1577
+ "plans.variants.customize.items.price": {
1578
+ required: ["billingMethod", "interval"],
1579
+ fields: {
1580
+ tierBehavior: {
1581
+ enum: ["graduated", "volume"],
1582
+ },
1583
+ interval: {
1584
+ enum: ["one_off", "week", "month", "quarter", "semi_annual", "year"],
1585
+ },
1586
+ billingMethod: {
1587
+ enum: ["prepaid", "usage_based"],
1588
+ },
1589
+ allocatedBilling: {
1590
+ enum: ["arrear", "prorated_legacy"],
1591
+ },
1592
+ },
1593
+ },
1594
+ "plans.variants.customize.items.price.additionalCurrencies": {
1595
+ required: ["amount", "currency"],
1596
+ },
1597
+ "plans.variants.customize.items.price.tiers": {
1598
+ required: ["to"],
1599
+ },
1600
+ "plans.variants.customize.items.price.tiers.additionalCurrencies": {
1601
+ required: ["currency"],
1602
+ },
1603
+ "plans.variants.customize.items.proration": {
1604
+ required: ["onDecrease", "onIncrease"],
1605
+ fields: {
1606
+ onIncrease: {
1607
+ enum: [
1608
+ "bill_immediately",
1609
+ "prorate_immediately",
1610
+ "prorate_next_cycle",
1611
+ "bill_next_cycle",
1612
+ ],
1613
+ },
1614
+ onDecrease: {
1615
+ enum: [
1616
+ "prorate",
1617
+ "prorate_immediately",
1618
+ "prorate_next_cycle",
1619
+ "none",
1620
+ "no_prorations",
1621
+ ],
1622
+ },
1623
+ },
1624
+ },
1625
+ "plans.variants.customize.items.reset": {
1626
+ required: ["interval"],
1627
+ fields: {
1628
+ interval: {
1629
+ enum: [
1630
+ "one_off",
1631
+ "minute",
1632
+ "hour",
1633
+ "day",
1634
+ "week",
1635
+ "month",
1636
+ "quarter",
1637
+ "semi_annual",
1638
+ "year",
1639
+ ],
1640
+ },
1641
+ },
1642
+ },
1643
+ "plans.variants.customize.items.rollover": {
1644
+ required: ["expiryDurationType"],
1645
+ fields: {
1646
+ expiryDurationType: {
1647
+ enum: ["month", "forever"],
1648
+ },
1649
+ },
1650
+ },
1651
+ "plans.variants.customize.items.thresholdBilling": {
1652
+ required: ["threshold"],
1653
+ fields: {
1654
+ threshold: {
1655
+ exclusiveMinimum: 0,
1656
+ },
1657
+ },
1658
+ },
1659
+ "plans.variants.customize.price": {
1660
+ required: ["amount", "interval"],
1661
+ fields: {
1662
+ interval: {
1663
+ enum: ["one_off", "week", "month", "quarter", "semi_annual", "year"],
1664
+ },
1665
+ },
1666
+ },
1667
+ "plans.variants.customize.price.additionalCurrencies": {
1668
+ required: ["amount", "currency"],
1669
+ },
1670
+ "plans.variants.customize.removeItems": {
1671
+ fields: {
1672
+ billingMethod: {
1673
+ enum: ["prepaid", "usage_based"],
1674
+ },
1675
+ interval: {
1676
+ enum: [
1677
+ "one_off",
1678
+ "week",
1679
+ "month",
1680
+ "quarter",
1681
+ "semi_annual",
1682
+ "year",
1683
+ "minute",
1684
+ "hour",
1685
+ "day",
1686
+ ],
1687
+ },
1688
+ intervalCount: {
1689
+ minimum: -9007199254740991,
1690
+ maximum: 9007199254740991,
1691
+ exclusiveMinimum: 0,
1692
+ },
1693
+ included: {
1694
+ maximum: 10000000000000,
1695
+ },
1696
+ },
1697
+ },
1698
+ "plans.variants.customize.removeLicenses": {
1699
+ required: ["licensePlanId"],
1700
+ },
1701
+ "plans.variants.customize.upsertLicenses": {
1702
+ required: ["licensePlanId"],
1703
+ fields: {
1704
+ included: {
1705
+ minimum: 0,
1706
+ maximum: 9007199254740991,
1707
+ },
1708
+ },
1709
+ },
1710
+ "plans.variants.customize.upsertLicenses.customize.addItems": {
1711
+ required: ["featureId"],
1712
+ fields: {
1713
+ included: {
1714
+ maximum: 10000000000000,
1715
+ },
1716
+ },
1717
+ },
1718
+ "plans.variants.customize.upsertLicenses.customize.addItems.expiry": {
1719
+ required: ["duration", "length"],
1720
+ fields: {
1721
+ duration: {
1722
+ enum: ["day", "week", "month", "year"],
1723
+ },
1724
+ },
1725
+ },
1726
+ "plans.variants.customize.upsertLicenses.customize.addItems.featureOverride.creditSchema":
1727
+ {
1728
+ variants: {
1729
+ on: "tierBehavior",
1730
+ byValue: {
1731
+ graduated: {
1732
+ required: ["meteredFeatureId", "tierBehavior", "tiers"],
1733
+ fields: {
1734
+ meteredFeatureId: {
1735
+ minLength: 1,
1736
+ },
1737
+ billingUnits: {
1738
+ exclusiveMinimum: 0,
1739
+ },
1740
+ tierBehavior: {
1741
+ enum: ["graduated"],
1742
+ },
1743
+ tiers: {
1744
+ minItems: 1,
1745
+ },
1746
+ },
1747
+ },
1748
+ },
1749
+ fallback: {
1750
+ required: ["creditCost", "meteredFeatureId"],
1751
+ fields: {
1752
+ meteredFeatureId: {
1753
+ minLength: 1,
1754
+ },
1755
+ billingUnits: {
1756
+ exclusiveMinimum: 0,
1757
+ },
1758
+ creditCost: {
1759
+ minimum: 0,
1760
+ },
1761
+ },
1762
+ },
1763
+ },
1764
+ },
1765
+ "plans.variants.customize.upsertLicenses.customize.addItems.featureOverride.creditSchema.dimensions":
1766
+ {
1767
+ keys: {
1768
+ minLength: 1,
1769
+ maxLength: 64,
1770
+ },
1771
+ },
1772
+ "plans.variants.customize.upsertLicenses.customize.addItems.featureOverride.creditSchema.dimensions.*":
1773
+ {
1774
+ variants: {
1775
+ on: "tierBehavior",
1776
+ byValue: {
1777
+ graduated: {
1778
+ required: ["match", "tierBehavior", "tiers"],
1779
+ fields: {
1780
+ priority: {
1781
+ minimum: -9007199254740991,
1782
+ maximum: 9007199254740991,
1783
+ },
1784
+ tierBehavior: {
1785
+ enum: ["graduated"],
1786
+ },
1787
+ tiers: {
1788
+ minItems: 1,
1789
+ },
1790
+ },
1791
+ },
1792
+ },
1793
+ fallback: {
1794
+ required: ["creditCost", "match"],
1795
+ fields: {
1796
+ priority: {
1797
+ minimum: -9007199254740991,
1798
+ maximum: 9007199254740991,
1799
+ },
1800
+ creditCost: {
1801
+ minimum: 0,
1802
+ },
1803
+ },
1804
+ },
1805
+ },
1806
+ },
1807
+ "plans.variants.customize.upsertLicenses.customize.addItems.featureOverride.creditSchema.dimensions.*.tiers":
1808
+ {
1809
+ required: ["creditCost"],
1810
+ fields: {
1811
+ creditCost: {
1812
+ minimum: 0,
1813
+ },
1814
+ },
1815
+ },
1816
+ "plans.variants.customize.upsertLicenses.customize.addItems.featureOverride.creditSchema.multipliers":
1817
+ {
1818
+ keys: {
1819
+ minLength: 1,
1820
+ maxLength: 64,
1821
+ },
1822
+ },
1823
+ "plans.variants.customize.upsertLicenses.customize.addItems.featureOverride.creditSchema.multipliers.*":
1824
+ {
1825
+ required: ["match"],
1826
+ fields: {
1827
+ factor: {
1828
+ exclusiveMinimum: 0,
1829
+ },
1830
+ },
1831
+ },
1832
+ "plans.variants.customize.upsertLicenses.customize.addItems.featureOverride.creditSchema.tiers":
1833
+ {
1834
+ required: ["creditCost", "to"],
1835
+ fields: {
1836
+ to: {
1837
+ exclusiveMinimum: 0,
1838
+ },
1839
+ creditCost: {
1840
+ minimum: 0,
1841
+ },
1842
+ },
1843
+ },
1844
+ "plans.variants.customize.upsertLicenses.customize.addItems.featureOverride.markups":
1845
+ {
1846
+ fields: {
1847
+ defaultMarkup: {
1848
+ minimum: -100,
1849
+ },
1850
+ },
1851
+ },
1852
+ "plans.variants.customize.upsertLicenses.customize.addItems.featureOverride.markups.modelMarkups":
1853
+ {
1854
+ keys: {
1855
+ pattern: ".+\\/.+",
1856
+ },
1857
+ },
1858
+ "plans.variants.customize.upsertLicenses.customize.addItems.featureOverride.markups.modelMarkups.*":
1859
+ {
1860
+ fields: {
1861
+ markup: {
1862
+ minimum: -100,
1863
+ },
1864
+ inputCost: {
1865
+ minimum: 0,
1866
+ },
1867
+ outputCost: {
1868
+ minimum: 0,
1869
+ },
1870
+ },
1871
+ },
1872
+ "plans.variants.customize.upsertLicenses.customize.addItems.featureOverride.markups.providerMarkups.*":
1873
+ {
1874
+ required: ["markup"],
1875
+ fields: {
1876
+ markup: {
1877
+ minimum: -100,
1878
+ },
1879
+ },
1880
+ },
1881
+ "plans.variants.customize.upsertLicenses.customize.addItems.price": {
1882
+ required: ["billingMethod", "interval"],
1883
+ fields: {
1884
+ tierBehavior: {
1885
+ enum: ["graduated", "volume"],
1886
+ },
1887
+ interval: {
1888
+ enum: ["one_off", "week", "month", "quarter", "semi_annual", "year"],
1889
+ },
1890
+ billingMethod: {
1891
+ enum: ["prepaid", "usage_based"],
1892
+ },
1893
+ allocatedBilling: {
1894
+ enum: ["arrear", "prorated_legacy"],
1895
+ },
1896
+ },
1897
+ },
1898
+ "plans.variants.customize.upsertLicenses.customize.addItems.price.additionalCurrencies":
1899
+ {
1900
+ required: ["amount", "currency"],
1901
+ },
1902
+ "plans.variants.customize.upsertLicenses.customize.addItems.price.tiers": {
1903
+ required: ["to"],
1904
+ },
1905
+ "plans.variants.customize.upsertLicenses.customize.addItems.price.tiers.additionalCurrencies":
1906
+ {
1907
+ required: ["currency"],
1908
+ },
1909
+ "plans.variants.customize.upsertLicenses.customize.addItems.proration": {
1910
+ required: ["onDecrease", "onIncrease"],
1911
+ fields: {
1912
+ onIncrease: {
1913
+ enum: [
1914
+ "bill_immediately",
1915
+ "prorate_immediately",
1916
+ "prorate_next_cycle",
1917
+ "bill_next_cycle",
1918
+ ],
1919
+ },
1920
+ onDecrease: {
1921
+ enum: [
1922
+ "prorate",
1923
+ "prorate_immediately",
1924
+ "prorate_next_cycle",
1925
+ "none",
1926
+ "no_prorations",
1927
+ ],
1928
+ },
1929
+ },
1930
+ },
1931
+ "plans.variants.customize.upsertLicenses.customize.addItems.reset": {
1932
+ required: ["interval"],
1933
+ fields: {
1934
+ interval: {
1935
+ enum: [
1936
+ "one_off",
1937
+ "minute",
1938
+ "hour",
1939
+ "day",
1940
+ "week",
1941
+ "month",
1942
+ "quarter",
1943
+ "semi_annual",
1944
+ "year",
1945
+ ],
1946
+ },
1947
+ },
1948
+ },
1949
+ "plans.variants.customize.upsertLicenses.customize.addItems.rollover": {
1950
+ required: ["expiryDurationType"],
1951
+ fields: {
1952
+ expiryDurationType: {
1953
+ enum: ["month", "forever"],
1954
+ },
1955
+ },
1956
+ },
1957
+ "plans.variants.customize.upsertLicenses.customize.addItems.thresholdBilling":
1958
+ {
1959
+ required: ["threshold"],
1960
+ fields: {
1961
+ threshold: {
1962
+ exclusiveMinimum: 0,
1963
+ },
1964
+ },
1965
+ },
1966
+ "plans.variants.customize.upsertLicenses.customize.price": {
1967
+ required: ["amount", "interval"],
1968
+ fields: {
1969
+ interval: {
1970
+ enum: ["one_off", "week", "month", "quarter", "semi_annual", "year"],
1971
+ },
1972
+ },
1973
+ },
1974
+ "plans.variants.customize.upsertLicenses.customize.price.additionalCurrencies":
1975
+ {
1976
+ required: ["amount", "currency"],
1977
+ },
1978
+ "plans.variants.customize.upsertLicenses.customize.removeItems": {
1979
+ fields: {
1980
+ billingMethod: {
1981
+ enum: ["prepaid", "usage_based"],
1982
+ },
1983
+ interval: {
1984
+ enum: [
1985
+ "one_off",
1986
+ "week",
1987
+ "month",
1988
+ "quarter",
1989
+ "semi_annual",
1990
+ "year",
1991
+ "minute",
1992
+ "hour",
1993
+ "day",
1994
+ ],
1995
+ },
1996
+ intervalCount: {
1997
+ minimum: -9007199254740991,
1998
+ maximum: 9007199254740991,
1999
+ exclusiveMinimum: 0,
2000
+ },
2001
+ included: {
2002
+ maximum: 10000000000000,
2003
+ },
2004
+ },
2005
+ },
2006
+ "plans.variants.processors.revenuecat": {
2007
+ required: ["products"],
2008
+ },
2009
+ "plans.variants.processors.revenuecat.products": {
2010
+ required: ["productId"],
2011
+ },
2012
+ "plans.variants.processors.revenuecat.products.featureQuantities": {
2013
+ required: ["featureId"],
2014
+ fields: {
2015
+ quantity: {
2016
+ minimum: 0,
2017
+ },
2018
+ },
2019
+ },
2020
+ "plans.variants.processors.stripe": {
2021
+ required: ["productId"],
2022
+ },
2023
+ referralPrograms: {
2024
+ label: "referral program",
2025
+ idField: "id",
2026
+ required: ["id", "receivedBy", "redeemOn", "rewardId"],
2027
+ fields: {
2028
+ id: {
2029
+ minLength: 1,
2030
+ },
2031
+ rewardId: {
2032
+ minLength: 1,
2033
+ },
2034
+ redeemOn: {
2035
+ enum: ["customer_creation", "checkout"],
2036
+ },
2037
+ receivedBy: {
2038
+ enum: ["referrer", "all"],
2039
+ },
2040
+ maxRedemptions: {
2041
+ minimum: -9007199254740991,
2042
+ maximum: 9007199254740991,
2043
+ exclusiveMinimum: 0,
2044
+ },
2045
+ internalId: {
2046
+ minLength: 1,
2047
+ },
2048
+ },
2049
+ rules: [
2050
+ {
2051
+ kind: "unique",
2052
+ field: "id",
2053
+ because:
2054
+ "Two referral programs claiming one id race to define the same row.",
2055
+ },
2056
+ {
2057
+ kind: "unique",
2058
+ field: "internalId",
2059
+ because:
2060
+ "A stable id names exactly one row; two fixtures cannot both be it.",
2061
+ },
2062
+ {
2063
+ kind: "exists",
2064
+ field: "rewardId",
2065
+ in: "rewards",
2066
+ matching: ["coupon.id", "featureGrant.id"],
2067
+ because:
2068
+ "A referral program grants a reward this config does not declare.",
2069
+ },
2070
+ {
2071
+ kind: "exists",
2072
+ field: "planIds",
2073
+ in: "plans",
2074
+ matching: "planId",
2075
+ because:
2076
+ "A referral program triggers on checkout of a plan this config does not declare.",
2077
+ },
2078
+ ],
2079
+ },
2080
+ removeFeatures: {
2081
+ required: ["featureId"],
2082
+ },
2083
+ removePlans: {
2084
+ required: ["planId"],
2085
+ fields: {
2086
+ version: {
2087
+ minimum: 1,
2088
+ maximum: 9007199254740991,
2089
+ },
2090
+ },
2091
+ },
2092
+ rewards: {
2093
+ label: "reward",
2094
+ rules: [
2095
+ {
2096
+ kind: "unique",
2097
+ field: ["coupon.id", "featureGrant.id"],
2098
+ because: "Two rewards claiming one id race to define the same row.",
2099
+ },
2100
+ {
2101
+ kind: "unique",
2102
+ field: ["coupon.internalId", "featureGrant.internalId"],
2103
+ because:
2104
+ "A stable id names exactly one row; two fixtures cannot both be it.",
2105
+ },
2106
+ ],
2107
+ },
2108
+ "rewards.coupon": {
2109
+ label: "coupon",
2110
+ idField: "id",
2111
+ required: [
2112
+ "duration",
2113
+ "id",
2114
+ "name",
2115
+ "planIds",
2116
+ "promoCodes",
2117
+ "type",
2118
+ "value",
2119
+ ],
2120
+ fields: {
2121
+ id: {
2122
+ minLength: 1,
2123
+ },
2124
+ name: {
2125
+ minLength: 1,
2126
+ },
2127
+ planIds: {
2128
+ minItems: 1,
2129
+ },
2130
+ internalId: {
2131
+ minLength: 1,
2132
+ },
2133
+ type: {
2134
+ enum: ["percentage_discount", "fixed_discount"],
2135
+ },
2136
+ value: {
2137
+ exclusiveMinimum: 0,
2138
+ },
2139
+ },
2140
+ rules: [
2141
+ {
2142
+ kind: "exists",
2143
+ field: "planIds",
2144
+ in: "plans",
2145
+ matching: "planId",
2146
+ because: "A coupon discounts a plan this config does not declare.",
2147
+ },
2148
+ ],
2149
+ },
2150
+ "rewards.coupon.duration": {
2151
+ required: ["length", "type"],
2152
+ fields: {
2153
+ type: {
2154
+ enum: ["one_off", "months", "forever"],
2155
+ },
2156
+ length: {
2157
+ minimum: -9007199254740991,
2158
+ maximum: 9007199254740991,
2159
+ exclusiveMinimum: 0,
2160
+ },
2161
+ },
2162
+ },
2163
+ "rewards.coupon.promoCodes": {
2164
+ required: ["code"],
2165
+ fields: {
2166
+ code: {
2167
+ minLength: 1,
2168
+ },
2169
+ globalMaxRedemption: {
2170
+ minimum: -9007199254740991,
2171
+ maximum: 9007199254740991,
2172
+ exclusiveMinimum: 0,
2173
+ },
2174
+ },
2175
+ },
2176
+ "rewards.featureGrant": {
2177
+ label: "feature grant",
2178
+ idField: "id",
2179
+ required: ["grants", "id", "name", "promoCodes"],
2180
+ fields: {
2181
+ id: {
2182
+ minLength: 1,
2183
+ },
2184
+ name: {
2185
+ minLength: 1,
2186
+ },
2187
+ grants: {
2188
+ minItems: 1,
2189
+ },
2190
+ promoCodes: {
2191
+ minItems: 1,
2192
+ },
2193
+ internalId: {
2194
+ minLength: 1,
2195
+ },
2196
+ },
2197
+ },
2198
+ "rewards.featureGrant.grants": {
2199
+ label: "grant",
2200
+ idField: "featureId",
2201
+ required: ["expiry", "featureId", "included"],
2202
+ fields: {
2203
+ featureId: {
2204
+ minLength: 1,
2205
+ },
2206
+ included: {
2207
+ minimum: 0,
2208
+ },
2209
+ },
2210
+ rules: [
2211
+ {
2212
+ kind: "exists",
2213
+ field: "featureId",
2214
+ in: "features",
2215
+ matching: "featureId",
2216
+ because:
2217
+ "A feature grant awards a feature this config does not declare.",
2218
+ },
2219
+ ],
2220
+ },
2221
+ "rewards.featureGrant.grants.expiry": {
2222
+ required: ["length", "type"],
2223
+ fields: {
2224
+ type: {
2225
+ enum: ["day", "week", "month", "year"],
2226
+ },
2227
+ length: {
2228
+ minimum: -9007199254740991,
2229
+ maximum: 9007199254740991,
2230
+ exclusiveMinimum: 0,
2231
+ },
2232
+ },
2233
+ },
2234
+ "rewards.featureGrant.promoCodes": {
2235
+ required: ["code", "maxUses"],
2236
+ fields: {
2237
+ code: {
2238
+ minLength: 1,
2239
+ },
2240
+ maxUses: {
2241
+ minimum: -9007199254740991,
2242
+ maximum: 9007199254740991,
2243
+ exclusiveMinimum: 0,
2244
+ },
2245
+ },
2246
+ },
2247
+ };