@getrheo/contracts 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (81) hide show
  1. package/dist/animations.d.ts +226 -0
  2. package/dist/animations.js +1160 -0
  3. package/dist/animations.js.map +1 -0
  4. package/dist/appIntegrations.d.ts +175 -0
  5. package/dist/appIntegrations.js +60 -0
  6. package/dist/appIntegrations.js.map +1 -0
  7. package/dist/billingPeriod.d.ts +26 -0
  8. package/dist/billingPeriod.js +39 -0
  9. package/dist/billingPeriod.js.map +1 -0
  10. package/dist/canvasEditorGates.d.ts +81 -0
  11. package/dist/canvasEditorGates.js +1460 -0
  12. package/dist/canvasEditorGates.js.map +1 -0
  13. package/dist/constants/index.d.ts +30 -0
  14. package/dist/constants/index.js +67 -0
  15. package/dist/constants/index.js.map +1 -0
  16. package/dist/dashboard.d.ts +181856 -0
  17. package/dist/dashboard.js +3348 -0
  18. package/dist/dashboard.js.map +1 -0
  19. package/dist/decisions.d.ts +575 -0
  20. package/dist/decisions.js +1209 -0
  21. package/dist/decisions.js.map +1 -0
  22. package/dist/events.d.ts +231 -0
  23. package/dist/events.js +63 -0
  24. package/dist/events.js.map +1 -0
  25. package/dist/experiments-DN8pQa_D.d.ts +530 -0
  26. package/dist/externalSurfaceIntegrations.d.ts +20 -0
  27. package/dist/externalSurfaceIntegrations.js +49 -0
  28. package/dist/externalSurfaceIntegrations.js.map +1 -0
  29. package/dist/externalSurfaces.d.ts +177 -0
  30. package/dist/externalSurfaces.js +1190 -0
  31. package/dist/externalSurfaces.js.map +1 -0
  32. package/dist/fields.d.ts +8 -0
  33. package/dist/fields.js +15 -0
  34. package/dist/fields.js.map +1 -0
  35. package/dist/flowManifestSchema-CtqygXCK.d.ts +50857 -0
  36. package/dist/flowTemplateComments.d.ts +23 -0
  37. package/dist/flowTemplateComments.js +14 -0
  38. package/dist/flowTemplateComments.js.map +1 -0
  39. package/dist/flowTemplates.d.ts +22 -0
  40. package/dist/flowTemplates.js +73 -0
  41. package/dist/flowTemplates.js.map +1 -0
  42. package/dist/identity.d.ts +35 -0
  43. package/dist/identity.js +18 -0
  44. package/dist/identity.js.map +1 -0
  45. package/dist/imageContentType.d.ts +11 -0
  46. package/dist/imageContentType.js +54 -0
  47. package/dist/imageContentType.js.map +1 -0
  48. package/dist/index.d.ts +224 -0
  49. package/dist/index.js +4557 -0
  50. package/dist/index.js.map +1 -0
  51. package/dist/layerUnion-BzXoAJLY.d.ts +34 -0
  52. package/dist/layers.d.ts +89844 -0
  53. package/dist/layers.js +1507 -0
  54. package/dist/layers.js.map +1 -0
  55. package/dist/layout-D0LpaKG-.d.ts +12896 -0
  56. package/dist/localized.d.ts +17 -0
  57. package/dist/localized.js +18 -0
  58. package/dist/localized.js.map +1 -0
  59. package/dist/manifest.d.ts +22192 -0
  60. package/dist/manifest.js +2163 -0
  61. package/dist/manifest.js.map +1 -0
  62. package/dist/media.d.ts +53 -0
  63. package/dist/media.js +55 -0
  64. package/dist/media.js.map +1 -0
  65. package/dist/planEntitlements.d.ts +65 -0
  66. package/dist/planEntitlements.js +117 -0
  67. package/dist/planEntitlements.js.map +1 -0
  68. package/dist/publish-exports.json +102 -0
  69. package/dist/screens.d.ts +33586 -0
  70. package/dist/screens.js +1439 -0
  71. package/dist/screens.js.map +1 -0
  72. package/dist/sdk.d.ts +145942 -0
  73. package/dist/sdk.js +3424 -0
  74. package/dist/sdk.js.map +1 -0
  75. package/dist/sdkAttributes.d.ts +11 -0
  76. package/dist/sdkAttributes.js +17 -0
  77. package/dist/sdkAttributes.js.map +1 -0
  78. package/dist/workspaceCapabilities.d.ts +15 -0
  79. package/dist/workspaceCapabilities.js +116 -0
  80. package/dist/workspaceCapabilities.js.map +1 -0
  81. package/package.json +162 -0
@@ -0,0 +1,53 @@
1
+ import { z } from 'zod';
2
+
3
+ declare const splitMediaFileName: (name: string | null | undefined) => {
4
+ stem: string;
5
+ extension: string;
6
+ };
7
+ declare const mediaExtensionFromContentType: (contentType: string) => string;
8
+ /** Display/edit stem only; persisted name keeps the original or inferred extension. */
9
+ declare const mergeMediaFileNameStem: (stem: string, currentName: string | null | undefined, contentType: string) => string;
10
+
11
+ declare const MediaTypeSchema: z.ZodEnum<["image", "font", "lottie", "video"]>;
12
+ declare const MediaReferenceSchema: z.ZodObject<{
13
+ mediaAssetId: z.ZodString;
14
+ }, "strip", z.ZodTypeAny, {
15
+ mediaAssetId: string;
16
+ }, {
17
+ mediaAssetId: string;
18
+ }>;
19
+ type MediaReference = z.infer<typeof MediaReferenceSchema>;
20
+ declare const MediaAssetSchema: z.ZodObject<{
21
+ id: z.ZodString;
22
+ orgId: z.ZodString;
23
+ type: z.ZodEnum<["image", "font", "lottie", "video"]>;
24
+ url: z.ZodString;
25
+ name: z.ZodOptional<z.ZodNullable<z.ZodString>>;
26
+ contentType: z.ZodString;
27
+ sizeBytes: z.ZodNumber;
28
+ archivedAt: z.ZodOptional<z.ZodNullable<z.ZodString>>;
29
+ createdAt: z.ZodString;
30
+ }, "strip", z.ZodTypeAny, {
31
+ type: "image" | "font" | "lottie" | "video";
32
+ url: string;
33
+ id: string;
34
+ orgId: string;
35
+ contentType: string;
36
+ sizeBytes: number;
37
+ createdAt: string;
38
+ name?: string | null | undefined;
39
+ archivedAt?: string | null | undefined;
40
+ }, {
41
+ type: "image" | "font" | "lottie" | "video";
42
+ url: string;
43
+ id: string;
44
+ orgId: string;
45
+ contentType: string;
46
+ sizeBytes: number;
47
+ createdAt: string;
48
+ name?: string | null | undefined;
49
+ archivedAt?: string | null | undefined;
50
+ }>;
51
+ type MediaAsset = z.infer<typeof MediaAssetSchema>;
52
+
53
+ export { type MediaAsset, MediaAssetSchema, type MediaReference, MediaReferenceSchema, MediaTypeSchema, mediaExtensionFromContentType, mergeMediaFileNameStem, splitMediaFileName };
package/dist/media.js ADDED
@@ -0,0 +1,55 @@
1
+ import { z } from 'zod';
2
+
3
+ // src/media.ts
4
+
5
+ // src/constants/index.ts
6
+ var MEDIA_TYPES = ["image", "font", "lottie", "video"];
7
+
8
+ // src/mediaFileName.ts
9
+ var CONTENT_TYPE_EXTENSION = {
10
+ "image/png": ".png",
11
+ "image/jpeg": ".jpg",
12
+ "image/webp": ".webp",
13
+ "image/gif": ".gif",
14
+ "image/svg+xml": ".svg",
15
+ "application/json": ".json",
16
+ "text/json": ".json",
17
+ "video/mp4": ".mp4",
18
+ "video/webm": ".webm",
19
+ "video/quicktime": ".mov"
20
+ };
21
+ var splitMediaFileName = (name) => {
22
+ const raw = name?.trim() ?? "";
23
+ if (!raw) return { stem: "", extension: "" };
24
+ const dot = raw.lastIndexOf(".");
25
+ if (dot <= 0) return { stem: raw, extension: "" };
26
+ return { stem: raw.slice(0, dot), extension: raw.slice(dot) };
27
+ };
28
+ var mediaExtensionFromContentType = (contentType) => CONTENT_TYPE_EXTENSION[contentType] ?? "";
29
+ var mergeMediaFileNameStem = (stem, currentName, contentType) => {
30
+ const trimmed = stem.trim();
31
+ const { extension } = splitMediaFileName(currentName);
32
+ const ext = extension || mediaExtensionFromContentType(contentType);
33
+ return ext ? `${trimmed}${ext}` : trimmed;
34
+ };
35
+
36
+ // src/media.ts
37
+ var MediaTypeSchema = z.enum(MEDIA_TYPES);
38
+ var MediaReferenceSchema = z.object({
39
+ mediaAssetId: z.string().uuid()
40
+ });
41
+ var MediaAssetSchema = z.object({
42
+ id: z.string().uuid(),
43
+ orgId: z.string().uuid(),
44
+ type: MediaTypeSchema,
45
+ url: z.string().url(),
46
+ name: z.string().nullable().optional(),
47
+ contentType: z.string(),
48
+ sizeBytes: z.number().int().nonnegative(),
49
+ archivedAt: z.string().datetime().nullable().optional(),
50
+ createdAt: z.string().datetime()
51
+ });
52
+
53
+ export { MediaAssetSchema, MediaReferenceSchema, MediaTypeSchema, mediaExtensionFromContentType, mergeMediaFileNameStem, splitMediaFileName };
54
+ //# sourceMappingURL=media.js.map
55
+ //# sourceMappingURL=media.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/constants/index.ts","../src/mediaFileName.ts","../src/media.ts"],"names":[],"mappings":";;;;;AAmBO,IAAM,WAAA,GAAc,CAAC,OAAA,EAAS,MAAA,EAAQ,UAAU,OAAO,CAAA;;;ACnB9D,IAAM,sBAAA,GAAiD;AAAA,EACrD,WAAA,EAAa,MAAA;AAAA,EACb,YAAA,EAAc,MAAA;AAAA,EACd,YAAA,EAAc,OAAA;AAAA,EACd,WAAA,EAAa,MAAA;AAAA,EACb,eAAA,EAAiB,MAAA;AAAA,EACjB,kBAAA,EAAoB,OAAA;AAAA,EACpB,WAAA,EAAa,OAAA;AAAA,EACb,WAAA,EAAa,MAAA;AAAA,EACb,YAAA,EAAc,OAAA;AAAA,EACd,iBAAA,EAAmB;AACrB,CAAA;AAEO,IAAM,kBAAA,GAAqB,CAChC,IAAA,KACwC;AACxC,EAAA,MAAM,GAAA,GAAM,IAAA,EAAM,IAAA,EAAK,IAAK,EAAA;AAC5B,EAAA,IAAI,CAAC,GAAA,EAAK,OAAO,EAAE,IAAA,EAAM,EAAA,EAAI,WAAW,EAAA,EAAG;AAC3C,EAAA,MAAM,GAAA,GAAM,GAAA,CAAI,WAAA,CAAY,GAAG,CAAA;AAC/B,EAAA,IAAI,OAAO,CAAA,EAAG,OAAO,EAAE,IAAA,EAAM,GAAA,EAAK,WAAW,EAAA,EAAG;AAChD,EAAA,OAAO,EAAE,IAAA,EAAM,GAAA,CAAI,KAAA,CAAM,CAAA,EAAG,GAAG,CAAA,EAAG,SAAA,EAAW,GAAA,CAAI,KAAA,CAAM,GAAG,CAAA,EAAE;AAC9D;AAEO,IAAM,6BAAA,GAAgC,CAAC,WAAA,KAC5C,sBAAA,CAAuB,WAAW,CAAA,IAAK;AAGlC,IAAM,sBAAA,GAAyB,CACpC,IAAA,EACA,WAAA,EACA,WAAA,KACW;AACX,EAAA,MAAM,OAAA,GAAU,KAAK,IAAA,EAAK;AAC1B,EAAA,MAAM,EAAE,SAAA,EAAU,GAAI,kBAAA,CAAmB,WAAW,CAAA;AACpD,EAAA,MAAM,GAAA,GAAM,SAAA,IAAa,6BAAA,CAA8B,WAAW,CAAA;AAClE,EAAA,OAAO,GAAA,GAAM,CAAA,EAAG,OAAO,CAAA,EAAG,GAAG,CAAA,CAAA,GAAK,OAAA;AACpC;;;ACjCO,IAAM,eAAA,GAAkB,CAAA,CAAE,IAAA,CAAK,WAAW;AAE1C,IAAM,oBAAA,GAAuB,EAAE,MAAA,CAAO;AAAA,EAC3C,YAAA,EAAc,CAAA,CAAE,MAAA,EAAO,CAAE,IAAA;AAC3B,CAAC;AAIM,IAAM,gBAAA,GAAmB,EAAE,MAAA,CAAO;AAAA,EACvC,EAAA,EAAI,CAAA,CAAE,MAAA,EAAO,CAAE,IAAA,EAAK;AAAA,EACpB,KAAA,EAAO,CAAA,CAAE,MAAA,EAAO,CAAE,IAAA,EAAK;AAAA,EACvB,IAAA,EAAM,eAAA;AAAA,EACN,GAAA,EAAK,CAAA,CAAE,MAAA,EAAO,CAAE,GAAA,EAAI;AAAA,EACpB,MAAM,CAAA,CAAE,MAAA,EAAO,CAAE,QAAA,GAAW,QAAA,EAAS;AAAA,EACrC,WAAA,EAAa,EAAE,MAAA,EAAO;AAAA,EACtB,WAAW,CAAA,CAAE,MAAA,EAAO,CAAE,GAAA,GAAM,WAAA,EAAY;AAAA,EACxC,UAAA,EAAY,EAAE,MAAA,EAAO,CAAE,UAAS,CAAE,QAAA,GAAW,QAAA,EAAS;AAAA,EACtD,SAAA,EAAW,CAAA,CAAE,MAAA,EAAO,CAAE,QAAA;AACxB,CAAC","file":"media.js","sourcesContent":["export const ENVIRONMENTS = ['test', 'live'] as const;\nexport type Environment = (typeof ENVIRONMENTS)[number];\n\nexport const ROLES = ['owner', 'editor'] as const;\nexport type Role = (typeof ROLES)[number];\n\nexport const STEP_TYPES = [\n 'carousel',\n 'single_choice',\n 'multiple_choice',\n 'text_input',\n 'scale_input',\n 'cta',\n] as const;\nexport type StepType = (typeof STEP_TYPES)[number];\n\nexport const FIELD_CLASSIFICATIONS = ['safe', 'sensitive'] as const;\nexport type FieldClassification = (typeof FIELD_CLASSIFICATIONS)[number];\n\nexport const MEDIA_TYPES = ['image', 'font', 'lottie', 'video'] as const;\nexport type MediaType = (typeof MEDIA_TYPES)[number];\n\nexport const IMAGE_MIME_TYPES = [\n 'image/png',\n 'image/jpeg',\n 'image/webp',\n 'image/gif',\n 'image/svg+xml',\n] as const;\nexport const MAX_IMAGE_BYTES = 5 * 1024 * 1024;\n\n/** Lottie sources are JSON on the same CDN as images. */\nexport const LOTTIE_MIME_TYPES = ['application/json', 'text/json'] as const;\nexport const MAX_LOTTIE_BYTES = 10 * 1024 * 1024;\n\n/** Video files on the same CDN as images (mp4, webm, mov). */\nexport const VIDEO_MIME_TYPES = ['video/mp4', 'video/webm', 'video/quicktime'] as const;\nexport const MAX_VIDEO_BYTES = 50 * 1024 * 1024;\n\nexport const FONT_MIME_TYPES = [\n 'font/ttf',\n 'font/otf',\n 'font/woff',\n 'font/woff2',\n 'application/font-woff',\n 'application/font-woff2',\n 'application/x-font-ttf',\n 'application/x-font-otf',\n 'application/octet-stream',\n] as const;\nexport const FONT_FILE_EXTENSIONS = ['.ttf', '.otf', '.woff', '.woff2'] as const;\nexport const MAX_FONT_BYTES = 10 * 1024 * 1024;\n\nexport const EVENT_NAMES = [\n 'flow_started',\n 'step_viewed',\n 'step_completed',\n 'step_skipped',\n 'choice_selected',\n 'text_submitted',\n 'flow_completed',\n 'flow_abandoned',\n 'decision_evaluated',\n 'external_link_opened',\n 'surface_presented',\n 'surface_outcome',\n 'app_review_prompt_shown',\n 'app_review_prompt_dismissed',\n /** Emitted once per provider id when merged SDK attributes first expose that attribution source (used for integration health checks). */\n 'attribution_context_observed',\n /** Successful in-app purchase from an external surface (e.g. RevenueCat paywall); commerce fields live in `properties`. */\n 'iap_purchase',\n] as const;\nexport type EventName = (typeof EVENT_NAMES)[number];\n\nexport const PUBLISHABLE_KEY_PREFIX = 'ob_pk_';\nexport const API_VERSION = 'v1';\n\nexport const DEFAULT_LOCALE = 'en';\n\nexport const AUTOSAVE_DEBOUNCE_MS = 800;\nexport const SDK_EVENT_FLUSH_MS = 5000;\n","const CONTENT_TYPE_EXTENSION: Record<string, string> = {\n 'image/png': '.png',\n 'image/jpeg': '.jpg',\n 'image/webp': '.webp',\n 'image/gif': '.gif',\n 'image/svg+xml': '.svg',\n 'application/json': '.json',\n 'text/json': '.json',\n 'video/mp4': '.mp4',\n 'video/webm': '.webm',\n 'video/quicktime': '.mov',\n};\n\nexport const splitMediaFileName = (\n name: string | null | undefined,\n): { stem: string; extension: string } => {\n const raw = name?.trim() ?? '';\n if (!raw) return { stem: '', extension: '' };\n const dot = raw.lastIndexOf('.');\n if (dot <= 0) return { stem: raw, extension: '' };\n return { stem: raw.slice(0, dot), extension: raw.slice(dot) };\n};\n\nexport const mediaExtensionFromContentType = (contentType: string): string =>\n CONTENT_TYPE_EXTENSION[contentType] ?? '';\n\n/** Display/edit stem only; persisted name keeps the original or inferred extension. */\nexport const mergeMediaFileNameStem = (\n stem: string,\n currentName: string | null | undefined,\n contentType: string,\n): string => {\n const trimmed = stem.trim();\n const { extension } = splitMediaFileName(currentName);\n const ext = extension || mediaExtensionFromContentType(contentType);\n return ext ? `${trimmed}${ext}` : trimmed;\n};\n","import { z } from 'zod';\nimport { MEDIA_TYPES } from './constants/index';\n\nexport const MediaTypeSchema = z.enum(MEDIA_TYPES);\n\nexport const MediaReferenceSchema = z.object({\n mediaAssetId: z.string().uuid(),\n});\n\nexport type MediaReference = z.infer<typeof MediaReferenceSchema>;\n\nexport const MediaAssetSchema = z.object({\n id: z.string().uuid(),\n orgId: z.string().uuid(),\n type: MediaTypeSchema,\n url: z.string().url(),\n name: z.string().nullable().optional(),\n contentType: z.string(),\n sizeBytes: z.number().int().nonnegative(),\n archivedAt: z.string().datetime().nullable().optional(),\n createdAt: z.string().datetime(),\n});\n\nexport type MediaAsset = z.infer<typeof MediaAssetSchema>;\n\nexport {\n mergeMediaFileNameStem,\n mediaExtensionFromContentType,\n splitMediaFileName,\n} from './mediaFileName.js';\n"]}
@@ -0,0 +1,65 @@
1
+ import { E as ExperimentStatus } from './experiments-DN8pQa_D.js';
2
+ import { ResolvedCanvasEditorGates } from './canvasEditorGates.js';
3
+ import { WorkspaceCapability } from './workspaceCapabilities.js';
4
+ import 'zod';
5
+ import './flowManifestSchema-CtqygXCK.js';
6
+ import './decisions.js';
7
+ import './layout-D0LpaKG-.js';
8
+ import './localized.js';
9
+ import './media.js';
10
+
11
+ /** Experiment statuses that count toward {@link WorkspacePlanEntitlements.maxConcurrentExperiments}. */
12
+ declare const CONCURRENT_EXPERIMENT_STATUSES: readonly ["draft", "running", "pending_decision"];
13
+ type ConcurrentExperimentStatus = (typeof CONCURRENT_EXPERIMENT_STATUSES)[number];
14
+ /** Workspace subscription tier (Stripe-backed for paid tiers). */
15
+ declare const BILLING_PLAN_KEYS: readonly ["indie", "grow", "scale", "enterprise"];
16
+ type BillingPlanKey = (typeof BILLING_PLAN_KEYS)[number];
17
+ /** Numeric cap: finite max, or `null` = unlimited (Enterprise). */
18
+ type PlanNumericLimit = number | null;
19
+ type WorkspacePlanEntitlements = {
20
+ maxApps: PlanNumericLimit;
21
+ maxChannelsPerEnvironment: PlanNumericLimit;
22
+ maxSeats: PlanNumericLimit;
23
+ includedMauLive: PlanNumericLimit;
24
+ experiments: boolean;
25
+ translations: boolean;
26
+ animations: boolean;
27
+ ai: boolean;
28
+ allowInvites: boolean;
29
+ /** App integrations (RevenueCat, AppsFlyer, …) and external integration canvas steps (Grow+). */
30
+ integrations: boolean;
31
+ /** Channel rollout approval workflow (Scale+). */
32
+ rolloutApprovals: boolean;
33
+ /** Non-stopped experiments per workspace (`null` = unlimited). Indie uses `0`. */
34
+ maxConcurrentExperiments: PlanNumericLimit;
35
+ /** Mobile MMP / deep-link attribution context in the SDK (Grow+). */
36
+ attribution: boolean;
37
+ };
38
+ declare const PLAN_ENTITLEMENTS: Record<BillingPlanKey, WorkspacePlanEntitlements>;
39
+ declare const parseBillingPlanKey: (raw: string | null | undefined) => BillingPlanKey | null;
40
+ declare const getPlanEntitlements: (plan: BillingPlanKey) => WorkspacePlanEntitlements;
41
+ declare const isPlanLimitUnlimited: (limit: PlanNumericLimit) => limit is null;
42
+ declare const isWithinPlanNumericLimit: (count: number, limit: PlanNumericLimit) => boolean;
43
+ declare const countsTowardConcurrentExperimentLimit: (status: ExperimentStatus) => status is ConcurrentExperimentStatus;
44
+ declare const isWithinConcurrentExperimentLimit: (count: number, limit: PlanNumericLimit) => boolean;
45
+ /** USD per MAU above the plan included allotment (Grow / Scale; Stripe metered monthly). */
46
+ declare const LIVE_MAU_OVERAGE_USD_PER_UNIT = 0.01;
47
+ declare const formatLiveMauOverageRate: (usdPerUnit?: number) => string;
48
+ /** Footnote on the MAU included limit row in pricing tables (`*` marker). */
49
+ declare const isPricingTableMauIncludedLimit: (limit: {
50
+ emphasis: string;
51
+ detail: string;
52
+ }) => boolean;
53
+ /** Per-plan MAU footnote body (without leading `*`). `null` when no footnote applies. */
54
+ declare const pricingTableMauOverageFootnote: (planId: BillingPlanKey) => string | null;
55
+ /** Stripe meter / dashboard: MAU above included allotment for this plan. */
56
+ declare const liveMauOverageUnits: (liveMau: number, plan: BillingPlanKey) => number;
57
+ /**
58
+ * Role-derived capabilities are intersected with workspace plan entitlements
59
+ * (Org RBCL × plan matrix).
60
+ */
61
+ declare const filterCapabilitiesForPlan: (caps: ReadonlySet<WorkspaceCapability>, ent: WorkspacePlanEntitlements) => WorkspaceCapability[];
62
+ /** Merge app canvas gates with plan (Indie disables Lottie / animation-heavy layers). */
63
+ declare const mergeCanvasEditorGatesForPlan: (gates: ResolvedCanvasEditorGates, ent: WorkspacePlanEntitlements) => ResolvedCanvasEditorGates;
64
+
65
+ export { BILLING_PLAN_KEYS, type BillingPlanKey, CONCURRENT_EXPERIMENT_STATUSES, type ConcurrentExperimentStatus, LIVE_MAU_OVERAGE_USD_PER_UNIT, PLAN_ENTITLEMENTS, type PlanNumericLimit, type WorkspacePlanEntitlements, countsTowardConcurrentExperimentLimit, filterCapabilitiesForPlan, formatLiveMauOverageRate, getPlanEntitlements, isPlanLimitUnlimited, isPricingTableMauIncludedLimit, isWithinConcurrentExperimentLimit, isWithinPlanNumericLimit, liveMauOverageUnits, mergeCanvasEditorGatesForPlan, parseBillingPlanKey, pricingTableMauOverageFootnote };
@@ -0,0 +1,117 @@
1
+ // src/planEntitlements.ts
2
+ var CONCURRENT_EXPERIMENT_STATUSES = [
3
+ "draft",
4
+ "running",
5
+ "pending_decision"
6
+ ];
7
+ var BILLING_PLAN_KEYS = ["indie", "grow", "scale", "enterprise"];
8
+ var PLAN_ENTITLEMENTS = {
9
+ indie: {
10
+ maxApps: 1,
11
+ maxChannelsPerEnvironment: 1,
12
+ maxSeats: 1,
13
+ includedMauLive: 1e3,
14
+ experiments: false,
15
+ translations: false,
16
+ animations: false,
17
+ ai: false,
18
+ allowInvites: false,
19
+ integrations: false,
20
+ rolloutApprovals: false,
21
+ maxConcurrentExperiments: 0,
22
+ attribution: false
23
+ },
24
+ grow: {
25
+ maxApps: 3,
26
+ maxChannelsPerEnvironment: 3,
27
+ maxSeats: 5,
28
+ includedMauLive: 1e4,
29
+ experiments: true,
30
+ translations: true,
31
+ animations: true,
32
+ ai: true,
33
+ allowInvites: true,
34
+ integrations: true,
35
+ rolloutApprovals: false,
36
+ maxConcurrentExperiments: 2,
37
+ attribution: true
38
+ },
39
+ scale: {
40
+ maxApps: 10,
41
+ maxChannelsPerEnvironment: 10,
42
+ maxSeats: 25,
43
+ includedMauLive: 1e5,
44
+ experiments: true,
45
+ translations: true,
46
+ animations: true,
47
+ ai: true,
48
+ allowInvites: true,
49
+ integrations: true,
50
+ rolloutApprovals: true,
51
+ maxConcurrentExperiments: 5,
52
+ attribution: true
53
+ },
54
+ enterprise: {
55
+ maxApps: null,
56
+ maxChannelsPerEnvironment: null,
57
+ maxSeats: null,
58
+ includedMauLive: null,
59
+ experiments: true,
60
+ translations: true,
61
+ animations: true,
62
+ ai: true,
63
+ allowInvites: true,
64
+ integrations: true,
65
+ rolloutApprovals: true,
66
+ maxConcurrentExperiments: null,
67
+ attribution: true
68
+ }
69
+ };
70
+ var parseBillingPlanKey = (raw) => {
71
+ if (!raw?.trim()) return null;
72
+ const k = raw.trim();
73
+ return BILLING_PLAN_KEYS.includes(k) ? k : null;
74
+ };
75
+ var getPlanEntitlements = (plan) => PLAN_ENTITLEMENTS[plan];
76
+ var isPlanLimitUnlimited = (limit) => limit === null;
77
+ var isWithinPlanNumericLimit = (count, limit) => limit === null || count <= limit;
78
+ var countsTowardConcurrentExperimentLimit = (status) => CONCURRENT_EXPERIMENT_STATUSES.includes(status);
79
+ var isWithinConcurrentExperimentLimit = (count, limit) => isWithinPlanNumericLimit(count, limit);
80
+ var LIVE_MAU_OVERAGE_USD_PER_UNIT = 0.01;
81
+ var formatLiveMauOverageRate = (usdPerUnit = LIVE_MAU_OVERAGE_USD_PER_UNIT) => usdPerUnit.toLocaleString("en-US", {
82
+ style: "currency",
83
+ currency: "USD",
84
+ minimumFractionDigits: 2,
85
+ maximumFractionDigits: 2
86
+ });
87
+ var isPricingTableMauIncludedLimit = (limit) => /mau included/i.test(limit.detail);
88
+ var pricingTableMauOverageFootnote = (planId) => {
89
+ switch (planId) {
90
+ case "indie":
91
+ return "Exceeding quota pauses the SDK until the next month or plan upgrade.";
92
+ case "grow":
93
+ case "scale":
94
+ return `Additional MAU billed at ${formatLiveMauOverageRate()} per MAU per month.`;
95
+ case "enterprise":
96
+ return null;
97
+ }
98
+ };
99
+ var liveMauOverageUnits = (liveMau, plan) => {
100
+ const inc = PLAN_ENTITLEMENTS[plan].includedMauLive;
101
+ if (inc === null) return 0;
102
+ return Math.max(0, liveMau - inc);
103
+ };
104
+ var filterCapabilitiesForPlan = (caps, ent) => [...caps].filter((c) => {
105
+ if (!ent.allowInvites && c === "member:invite") return false;
106
+ if (!ent.ai && (c === "ai:brand_extract" || c === "ai:translate")) return false;
107
+ if (!ent.experiments && c === "experiment:manage") return false;
108
+ return true;
109
+ });
110
+ var mergeCanvasEditorGatesForPlan = (gates, ent) => ({
111
+ ...gates,
112
+ lottie: gates.lottie && ent.animations
113
+ });
114
+
115
+ export { BILLING_PLAN_KEYS, CONCURRENT_EXPERIMENT_STATUSES, LIVE_MAU_OVERAGE_USD_PER_UNIT, PLAN_ENTITLEMENTS, countsTowardConcurrentExperimentLimit, filterCapabilitiesForPlan, formatLiveMauOverageRate, getPlanEntitlements, isPlanLimitUnlimited, isPricingTableMauIncludedLimit, isWithinConcurrentExperimentLimit, isWithinPlanNumericLimit, liveMauOverageUnits, mergeCanvasEditorGatesForPlan, parseBillingPlanKey, pricingTableMauOverageFootnote };
116
+ //# sourceMappingURL=planEntitlements.js.map
117
+ //# sourceMappingURL=planEntitlements.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/planEntitlements.ts"],"names":[],"mappings":"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","file":"planEntitlements.js","sourcesContent":["import type { ExperimentStatus } from './dashboard/experiments';\nimport type { ResolvedCanvasEditorGates } from './canvasEditorGates';\nimport type { WorkspaceCapability } from './workspaceCapabilities';\n\n/** Experiment statuses that count toward {@link WorkspacePlanEntitlements.maxConcurrentExperiments}. */\nexport const CONCURRENT_EXPERIMENT_STATUSES = [\n 'draft',\n 'running',\n 'pending_decision',\n] as const satisfies readonly ExperimentStatus[];\nexport type ConcurrentExperimentStatus = (typeof CONCURRENT_EXPERIMENT_STATUSES)[number];\n\n/** Workspace subscription tier (Stripe-backed for paid tiers). */\nexport const BILLING_PLAN_KEYS = ['indie', 'grow', 'scale', 'enterprise'] as const;\nexport type BillingPlanKey = (typeof BILLING_PLAN_KEYS)[number];\n\n/** Numeric cap: finite max, or `null` = unlimited (Enterprise). */\nexport type PlanNumericLimit = number | null;\n\nexport type WorkspacePlanEntitlements = {\n maxApps: PlanNumericLimit;\n maxChannelsPerEnvironment: PlanNumericLimit;\n maxSeats: PlanNumericLimit;\n includedMauLive: PlanNumericLimit;\n experiments: boolean;\n translations: boolean;\n animations: boolean;\n ai: boolean;\n allowInvites: boolean;\n /** App integrations (RevenueCat, AppsFlyer, …) and external integration canvas steps (Grow+). */\n integrations: boolean;\n /** Channel rollout approval workflow (Scale+). */\n rolloutApprovals: boolean;\n /** Non-stopped experiments per workspace (`null` = unlimited). Indie uses `0`. */\n maxConcurrentExperiments: PlanNumericLimit;\n /** Mobile MMP / deep-link attribution context in the SDK (Grow+). */\n attribution: boolean;\n};\n\nexport const PLAN_ENTITLEMENTS: Record<BillingPlanKey, WorkspacePlanEntitlements> = {\n indie: {\n maxApps: 1,\n maxChannelsPerEnvironment: 1,\n maxSeats: 1,\n includedMauLive: 1_000,\n experiments: false,\n translations: false,\n animations: false,\n ai: false,\n allowInvites: false,\n integrations: false,\n rolloutApprovals: false,\n maxConcurrentExperiments: 0,\n attribution: false,\n },\n grow: {\n maxApps: 3,\n maxChannelsPerEnvironment: 3,\n maxSeats: 5,\n includedMauLive: 10_000,\n experiments: true,\n translations: true,\n animations: true,\n ai: true,\n allowInvites: true,\n integrations: true,\n rolloutApprovals: false,\n maxConcurrentExperiments: 2,\n attribution: true,\n },\n scale: {\n maxApps: 10,\n maxChannelsPerEnvironment: 10,\n maxSeats: 25,\n includedMauLive: 100_000,\n experiments: true,\n translations: true,\n animations: true,\n ai: true,\n allowInvites: true,\n integrations: true,\n rolloutApprovals: true,\n maxConcurrentExperiments: 5,\n attribution: true,\n },\n enterprise: {\n maxApps: null,\n maxChannelsPerEnvironment: null,\n maxSeats: null,\n includedMauLive: null,\n experiments: true,\n translations: true,\n animations: true,\n ai: true,\n allowInvites: true,\n integrations: true,\n rolloutApprovals: true,\n maxConcurrentExperiments: null,\n attribution: true,\n },\n};\n\nexport const parseBillingPlanKey = (raw: string | null | undefined): BillingPlanKey | null => {\n if (!raw?.trim()) return null;\n const k = raw.trim() as BillingPlanKey;\n return BILLING_PLAN_KEYS.includes(k) ? k : null;\n};\n\nexport const getPlanEntitlements = (plan: BillingPlanKey): WorkspacePlanEntitlements =>\n PLAN_ENTITLEMENTS[plan];\n\nexport const isPlanLimitUnlimited = (limit: PlanNumericLimit): limit is null => limit === null;\n\nexport const isWithinPlanNumericLimit = (count: number, limit: PlanNumericLimit): boolean =>\n limit === null || count <= limit;\n\nexport const countsTowardConcurrentExperimentLimit = (\n status: ExperimentStatus,\n): status is ConcurrentExperimentStatus =>\n (CONCURRENT_EXPERIMENT_STATUSES as readonly ExperimentStatus[]).includes(status);\n\nexport const isWithinConcurrentExperimentLimit = (\n count: number,\n limit: PlanNumericLimit,\n): boolean => isWithinPlanNumericLimit(count, limit);\n\n/** USD per MAU above the plan included allotment (Grow / Scale; Stripe metered monthly). */\nexport const LIVE_MAU_OVERAGE_USD_PER_UNIT = 0.01;\n\nexport const formatLiveMauOverageRate = (\n usdPerUnit: number = LIVE_MAU_OVERAGE_USD_PER_UNIT,\n): string =>\n usdPerUnit.toLocaleString('en-US', {\n style: 'currency',\n currency: 'USD',\n minimumFractionDigits: 2,\n maximumFractionDigits: 2,\n });\n\n/** Footnote on the MAU included limit row in pricing tables (`*` marker). */\nexport const isPricingTableMauIncludedLimit = (limit: {\n emphasis: string;\n detail: string;\n}): boolean => /mau included/i.test(limit.detail);\n\n/** Per-plan MAU footnote body (without leading `*`). `null` when no footnote applies. */\nexport const pricingTableMauOverageFootnote = (planId: BillingPlanKey): string | null => {\n switch (planId) {\n case 'indie':\n return 'Exceeding quota pauses the SDK until the next month or plan upgrade.';\n case 'grow':\n case 'scale':\n return `Additional MAU billed at ${formatLiveMauOverageRate()} per MAU per month.`;\n case 'enterprise':\n return null;\n }\n};\n\n/** Stripe meter / dashboard: MAU above included allotment for this plan. */\nexport const liveMauOverageUnits = (liveMau: number, plan: BillingPlanKey): number => {\n const inc = PLAN_ENTITLEMENTS[plan].includedMauLive;\n if (inc === null) return 0;\n return Math.max(0, liveMau - inc);\n};\n\n/**\n * Role-derived capabilities are intersected with workspace plan entitlements\n * (Org RBCL × plan matrix).\n */\nexport const filterCapabilitiesForPlan = (\n caps: ReadonlySet<WorkspaceCapability>,\n ent: WorkspacePlanEntitlements,\n): WorkspaceCapability[] =>\n [...caps].filter((c) => {\n if (!ent.allowInvites && c === 'member:invite') return false;\n if (!ent.ai && (c === 'ai:brand_extract' || c === 'ai:translate')) return false;\n if (!ent.experiments && c === 'experiment:manage') return false;\n return true;\n });\n\n/** Merge app canvas gates with plan (Indie disables Lottie / animation-heavy layers). */\nexport const mergeCanvasEditorGatesForPlan = (\n gates: ResolvedCanvasEditorGates,\n ent: WorkspacePlanEntitlements,\n): ResolvedCanvasEditorGates => ({\n ...gates,\n lottie: gates.lottie && ent.animations,\n});\n"]}
@@ -0,0 +1,102 @@
1
+ [
2
+ {
3
+ "exportKey": ".",
4
+ "distFile": "./dist/index.js"
5
+ },
6
+ {
7
+ "exportKey": "./animations",
8
+ "distFile": "./dist/animations.js"
9
+ },
10
+ {
11
+ "exportKey": "./appIntegrations",
12
+ "distFile": "./dist/appIntegrations.js"
13
+ },
14
+ {
15
+ "exportKey": "./canvasEditorGates",
16
+ "distFile": "./dist/canvasEditorGates.js"
17
+ },
18
+ {
19
+ "exportKey": "./constants",
20
+ "distFile": "./dist/constants/index.js"
21
+ },
22
+ {
23
+ "exportKey": "./dashboard",
24
+ "distFile": "./dist/dashboard.js"
25
+ },
26
+ {
27
+ "exportKey": "./decisions",
28
+ "distFile": "./dist/decisions.js"
29
+ },
30
+ {
31
+ "exportKey": "./events",
32
+ "distFile": "./dist/events.js"
33
+ },
34
+ {
35
+ "exportKey": "./externalSurfaceIntegrations",
36
+ "distFile": "./dist/externalSurfaceIntegrations.js"
37
+ },
38
+ {
39
+ "exportKey": "./externalSurfaces",
40
+ "distFile": "./dist/externalSurfaces.js"
41
+ },
42
+ {
43
+ "exportKey": "./fields",
44
+ "distFile": "./dist/fields.js"
45
+ },
46
+ {
47
+ "exportKey": "./imageContentType",
48
+ "distFile": "./dist/imageContentType.js"
49
+ },
50
+ {
51
+ "exportKey": "./identity",
52
+ "distFile": "./dist/identity.js"
53
+ },
54
+ {
55
+ "exportKey": "./layers",
56
+ "distFile": "./dist/layers.js"
57
+ },
58
+ {
59
+ "exportKey": "./localized",
60
+ "distFile": "./dist/localized.js"
61
+ },
62
+ {
63
+ "exportKey": "./manifest",
64
+ "distFile": "./dist/manifest.js"
65
+ },
66
+ {
67
+ "exportKey": "./media",
68
+ "distFile": "./dist/media.js"
69
+ },
70
+ {
71
+ "exportKey": "./screens",
72
+ "distFile": "./dist/screens.js"
73
+ },
74
+ {
75
+ "exportKey": "./sdk",
76
+ "distFile": "./dist/sdk.js"
77
+ },
78
+ {
79
+ "exportKey": "./sdkAttributes",
80
+ "distFile": "./dist/sdkAttributes.js"
81
+ },
82
+ {
83
+ "exportKey": "./flowTemplates",
84
+ "distFile": "./dist/flowTemplates.js"
85
+ },
86
+ {
87
+ "exportKey": "./flowTemplateComments",
88
+ "distFile": "./dist/flowTemplateComments.js"
89
+ },
90
+ {
91
+ "exportKey": "./workspaceCapabilities",
92
+ "distFile": "./dist/workspaceCapabilities.js"
93
+ },
94
+ {
95
+ "exportKey": "./planEntitlements",
96
+ "distFile": "./dist/planEntitlements.js"
97
+ },
98
+ {
99
+ "exportKey": "./billingPeriod",
100
+ "distFile": "./dist/billingPeriod.js"
101
+ }
102
+ ]