vidspotai-shared 1.0.100 → 1.0.101-dev.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.
- package/lib/globals/aiModels/enums.d.ts +1 -0
- package/lib/globals/aiModels/enums.d.ts.map +1 -1
- package/lib/globals/aiModels/enums.js +3 -0
- package/lib/globals/aiModels/extendCapability.d.ts +26 -0
- package/lib/globals/aiModels/extendCapability.d.ts.map +1 -0
- package/lib/globals/aiModels/extendCapability.js +42 -0
- package/lib/globals/aiModels/index.d.ts +1 -0
- package/lib/globals/aiModels/index.d.ts.map +1 -1
- package/lib/globals/aiModels/index.js +1 -0
- package/lib/globals/aiModels/providers/google.d.ts.map +1 -1
- package/lib/globals/aiModels/providers/google.js +6 -9
- package/lib/globals/aiModels/providers/hostedAvatars.js +10 -10
- package/lib/globals/creditUnit.d.ts +20 -33
- package/lib/globals/creditUnit.d.ts.map +1 -1
- package/lib/globals/creditUnit.js +20 -33
- package/lib/globals/types.d.ts +34 -2
- package/lib/globals/types.d.ts.map +1 -1
- package/lib/globals/types.js +37 -0
- package/lib/models/demoVideoProject.model.d.ts +213 -0
- package/lib/models/demoVideoProject.model.d.ts.map +1 -1
- package/lib/models/index.d.ts +2 -0
- package/lib/models/index.d.ts.map +1 -1
- package/lib/models/index.js +2 -0
- package/lib/models/mediaUpload.model.d.ts +25 -0
- package/lib/models/mediaUpload.model.d.ts.map +1 -1
- package/lib/models/productConnection.model.d.ts +57 -0
- package/lib/models/productConnection.model.d.ts.map +1 -0
- package/lib/models/productConnection.model.js +7 -0
- package/lib/models/video.model.d.ts +11 -0
- package/lib/models/video.model.d.ts.map +1 -1
- package/lib/models/videoQaJob.model.d.ts +61 -0
- package/lib/models/videoQaJob.model.d.ts.map +1 -0
- package/lib/models/videoQaJob.model.js +16 -0
- package/lib/schemas/brandKit.schema.d.ts +3 -1
- package/lib/schemas/brandKit.schema.d.ts.map +1 -1
- package/lib/schemas/brandKit.schema.js +9 -0
- package/lib/schemas/brief.schema.d.ts +5 -4
- package/lib/schemas/brief.schema.d.ts.map +1 -1
- package/lib/schemas/brief.schema.js +23 -1
- package/lib/schemas/demoQuestion.schema.d.ts +24 -4
- package/lib/schemas/demoQuestion.schema.d.ts.map +1 -1
- package/lib/schemas/demoQuestion.schema.js +8 -2
- package/lib/schemas/demoSpec.schema.d.ts +40 -6
- package/lib/schemas/demoSpec.schema.d.ts.map +1 -1
- package/lib/schemas/demoSpec.schema.js +46 -1
- package/lib/schemas/project.schema.d.ts +33 -3
- package/lib/schemas/project.schema.d.ts.map +1 -1
- package/lib/schemas/project.schema.js +22 -0
- package/lib/schemas/social.schema.d.ts +1 -1
- package/lib/schemas/videoPlan.schema.d.ts +22 -20
- package/lib/schemas/videoPlan.schema.d.ts.map +1 -1
- package/lib/schemas/videoPlan.schema.js +19 -0
- package/lib/services/agent/editClassifier.d.ts +10 -10
- package/lib/services/agent/eval/types.d.ts +3 -2
- package/lib/services/agent/eval/types.d.ts.map +1 -1
- package/lib/services/agent/executor/core.d.ts.map +1 -1
- package/lib/services/agent/executor/core.js +11 -0
- package/lib/services/agent/planner/Planner.d.ts.map +1 -1
- package/lib/services/agent/planner/Planner.js +5 -0
- package/lib/services/agent/planner/overlayRegen.d.ts.map +1 -1
- package/lib/services/agent/planner/overlayRegen.js +5 -0
- package/lib/services/agent/planner/plannerMessages.d.ts.map +1 -1
- package/lib/services/agent/planner/plannerMessages.js +10 -1
- package/lib/services/agent/planner/scriptFirstPlanner.d.ts.map +1 -1
- package/lib/services/agent/planner/scriptFirstPlanner.js +2 -0
- package/lib/services/agent/regenCore.d.ts.map +1 -1
- package/lib/services/agent/regenCore.js +11 -1
- package/lib/services/agent/runHelpers.d.ts +8 -0
- package/lib/services/agent/runHelpers.d.ts.map +1 -1
- package/lib/services/agent/runHelpers.js +5 -1
- package/lib/services/agent/tools/chapterOutline.tool.d.ts +8 -0
- package/lib/services/agent/tools/chapterOutline.tool.d.ts.map +1 -1
- package/lib/services/agent/tools/chapterOutline.tool.js +21 -8
- package/lib/services/agent/tools/composeScene.tool.d.ts +32 -2
- package/lib/services/agent/tools/composeScene.tool.d.ts.map +1 -1
- package/lib/services/agent/tools/estimateCost.tool.d.ts +11 -1
- package/lib/services/agent/tools/estimateCost.tool.d.ts.map +1 -1
- package/lib/services/agent/tools/extendVideo.tool.d.ts +9 -3
- package/lib/services/agent/tools/extendVideo.tool.d.ts.map +1 -1
- package/lib/services/agent/tools/extendVideo.tool.js +12 -27
- package/lib/services/agent/tools/generateAvatarVideo.tool.d.ts +1 -1
- package/lib/services/agent/tools/generateScript.tool.d.ts +3 -2
- package/lib/services/agent/tools/generateScript.tool.d.ts.map +1 -1
- package/lib/services/agent/tools/generateScript.tool.js +16 -7
- package/lib/services/agent/tools/generateVoiceover.tool.d.ts +1 -1
- package/lib/services/agent/tools/planVideo.tool.d.ts +11 -8
- package/lib/services/agent/tools/planVideo.tool.d.ts.map +1 -1
- package/lib/services/agent/tools/render.tool.d.ts +11 -1
- package/lib/services/agent/tools/render.tool.d.ts.map +1 -1
- package/lib/services/agent/tools/searchStock.tool.d.ts +1 -1
- package/lib/services/agent/tools/searchUserLibrary.tool.d.ts +4 -4
- package/lib/services/aiGen/providers/alibaba/alibaba.d.ts +0 -6
- package/lib/services/aiGen/providers/alibaba/alibaba.d.ts.map +1 -1
- package/lib/services/aiGen/providers/alibaba/alibaba.js +5 -103
- package/lib/services/aiGen/providers/bytedance/bytedance.service.d.ts.map +1 -1
- package/lib/services/aiGen/providers/bytedance/bytedance.service.js +1 -9
- package/lib/services/aiGen/providers/google/google.service.d.ts.map +1 -1
- package/lib/services/aiGen/providers/google/google.service.js +26 -142
- package/lib/services/aiGen/providers/google/googleErrors.d.ts.map +1 -1
- package/lib/services/aiGen/providers/google/googleErrors.js +7 -17
- package/lib/services/aiGen/providers/kling/kling.service.d.ts.map +1 -1
- package/lib/services/aiGen/providers/kling/kling.service.js +22 -3
- package/lib/services/aiGen/providers/kling/klingStatus.d.ts +7 -0
- package/lib/services/aiGen/providers/kling/klingStatus.d.ts.map +1 -1
- package/lib/services/aiGen/providers/kling/klingStatus.js +41 -4
- package/lib/services/aiGen/providers/pixverse/pixverse.service.d.ts.map +1 -1
- package/lib/services/aiGen/providers/pixverse/pixverse.service.js +25 -0
- package/lib/services/aiGen/providers/types.d.ts +20 -0
- package/lib/services/aiGen/providers/types.d.ts.map +1 -1
- package/lib/services/avatarGen/avatarProviderFactory.d.ts.map +1 -1
- package/lib/services/avatarGen/avatarProviderFactory.js +3 -0
- package/lib/services/avatarGen/index.d.ts +1 -0
- package/lib/services/avatarGen/index.d.ts.map +1 -1
- package/lib/services/avatarGen/index.js +1 -0
- package/lib/services/avatarGen/providers/synthesiaAvatarProvider.d.ts +53 -0
- package/lib/services/avatarGen/providers/synthesiaAvatarProvider.d.ts.map +1 -0
- package/lib/services/avatarGen/providers/synthesiaAvatarProvider.js +176 -0
- package/lib/services/demo/demoAuthor.d.ts +7 -0
- package/lib/services/demo/demoAuthor.d.ts.map +1 -1
- package/lib/services/demo/demoAuthor.js +2 -0
- package/lib/services/demo/demoAuthorPrompt.d.ts +6 -0
- package/lib/services/demo/demoAuthorPrompt.d.ts.map +1 -1
- package/lib/services/demo/demoAuthorPrompt.js +24 -2
- package/lib/services/demo/demoCaptions.d.ts +69 -0
- package/lib/services/demo/demoCaptions.d.ts.map +1 -0
- package/lib/services/demo/demoCaptions.js +152 -0
- package/lib/services/demo/demoMusic.d.ts +8 -1
- package/lib/services/demo/demoMusic.d.ts.map +1 -1
- package/lib/services/demo/demoMusic.js +32 -16
- package/lib/services/demo/demoScriptPrompt.d.ts +2 -1
- package/lib/services/demo/demoScriptPrompt.d.ts.map +1 -1
- package/lib/services/demo/demoScriptPrompt.js +29 -2
- package/lib/services/demo/demoStockAssets.d.ts +29 -0
- package/lib/services/demo/demoStockAssets.d.ts.map +1 -0
- package/lib/services/demo/demoStockAssets.js +107 -0
- package/lib/services/demo/index.d.ts +3 -0
- package/lib/services/demo/index.d.ts.map +1 -1
- package/lib/services/demo/index.js +3 -0
- package/lib/services/demo/productConnection.service.d.ts +78 -0
- package/lib/services/demo/productConnection.service.d.ts.map +1 -0
- package/lib/services/demo/productConnection.service.js +125 -0
- package/lib/services/editor/planToProject.d.ts.map +1 -1
- package/lib/services/editor/planToProject.helpers.d.ts +1 -0
- package/lib/services/editor/planToProject.helpers.d.ts.map +1 -1
- package/lib/services/editor/planToProject.helpers.js +3 -0
- package/lib/services/editor/planToProject.js +39 -0
- package/lib/services/editor/projectToDesign.js +13 -1
- package/lib/services/firestore.service.d.ts +14 -0
- package/lib/services/firestore.service.d.ts.map +1 -1
- package/lib/services/firestore.service.js +16 -0
- package/lib/services/translation/index.d.ts +1 -0
- package/lib/services/translation/index.d.ts.map +1 -1
- package/lib/services/translation/index.js +8 -1
- package/lib/services/translation/outputLanguage.d.ts +75 -0
- package/lib/services/translation/outputLanguage.d.ts.map +1 -0
- package/lib/services/translation/outputLanguage.js +190 -0
- package/lib/services/translation/translation.service.d.ts +13 -2
- package/lib/services/translation/translation.service.d.ts.map +1 -1
- package/lib/services/translation/translation.service.js +73 -31
- package/lib/services/tts/index.d.ts +1 -0
- package/lib/services/tts/index.d.ts.map +1 -1
- package/lib/services/tts/index.js +1 -0
- package/lib/services/tts/providers/elevenlabs.service.d.ts +7 -0
- package/lib/services/tts/providers/elevenlabs.service.d.ts.map +1 -1
- package/lib/services/tts/providers/elevenlabs.service.js +69 -13
- package/lib/services/tts/types.d.ts +29 -0
- package/lib/services/tts/types.d.ts.map +1 -1
- package/lib/services/tts/wordTimings.d.ts +27 -0
- package/lib/services/tts/wordTimings.d.ts.map +1 -0
- package/lib/services/tts/wordTimings.js +57 -0
- package/lib/utils/billableDuration.d.ts +11 -0
- package/lib/utils/billableDuration.d.ts.map +1 -0
- package/lib/utils/billableDuration.js +91 -0
- package/lib/utils/index.d.ts +3 -0
- package/lib/utils/index.d.ts.map +1 -1
- package/lib/utils/index.js +3 -0
- package/lib/utils/mp4Duration.d.ts +38 -0
- package/lib/utils/mp4Duration.d.ts.map +1 -0
- package/lib/utils/mp4Duration.js +164 -0
- package/lib/utils/socialEntitlements.d.ts +51 -0
- package/lib/utils/socialEntitlements.d.ts.map +1 -0
- package/lib/utils/socialEntitlements.js +65 -0
- package/package.json +1 -1
|
@@ -0,0 +1,164 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Dependency-free MP4 duration reader.
|
|
4
|
+
*
|
|
5
|
+
* WHY THIS EXISTS
|
|
6
|
+
* Billing prefers the DELIVERED clip length over the REQUESTED one (see
|
|
7
|
+
* `VideoStatusResult.durationSec`). Kling reports the delivered length in its
|
|
8
|
+
* status payload, so nothing has to be measured there. PixVerse does NOT — its
|
|
9
|
+
* `/video/result` response carries `create_time, id, modify_time,
|
|
10
|
+
* negative_prompt, outputHeight, outputWidth, prompt, resolution_ratio, seed,
|
|
11
|
+
* size, status, style, url` and nothing else (verified against the official
|
|
12
|
+
* docs 2026-07-24; `size` is BYTES, not seconds). So for PixVerse the only
|
|
13
|
+
* honest source of the delivered length is the file itself.
|
|
14
|
+
*
|
|
15
|
+
* We already download the finished clip into a Buffer before uploading it to
|
|
16
|
+
* Firebase, so the bytes are in hand at zero extra network cost. This module
|
|
17
|
+
* reads the length out of that Buffer by walking the MP4 box tree to `mvhd`,
|
|
18
|
+
* following the same precedent as `mp4IsComplete()` in google.service.ts:
|
|
19
|
+
* scan the bytes rather than shell out, because `packages/shared` has no
|
|
20
|
+
* ffmpeg/ffprobe dependency and must not gain one (it ships to Firebase
|
|
21
|
+
* Functions, where no such binary exists).
|
|
22
|
+
*
|
|
23
|
+
* CONTRACT: this function never throws and never guesses. Every malformed,
|
|
24
|
+
* truncated, fragmented or otherwise unreadable input returns `undefined`, and
|
|
25
|
+
* callers fall back to the requested duration — i.e. the pre-existing billing
|
|
26
|
+
* behaviour. A wrong number here would mis-bill a real user, so "I don't know"
|
|
27
|
+
* is always the correct answer when the bytes aren't unambiguous.
|
|
28
|
+
*/
|
|
29
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
30
|
+
exports.readMp4DurationSec = readMp4DurationSec;
|
|
31
|
+
/** ISO/IEC 14496-12 box header: 4-byte big-endian size + 4-byte ASCII type. */
|
|
32
|
+
const BOX_HEADER_BYTES = 8;
|
|
33
|
+
/**
|
|
34
|
+
* A `duration` of all-ones means "unknown" in ISO/IEC 14496-12 — common in
|
|
35
|
+
* fragmented MP4 (fMP4), where the real length lives in the fragments rather
|
|
36
|
+
* than in `mvhd`. Treated as unreadable rather than as a huge number.
|
|
37
|
+
*/
|
|
38
|
+
const UNKNOWN_DURATION_32 = 0xffffffff;
|
|
39
|
+
/**
|
|
40
|
+
* Built from a string, NOT from the numeric literal `0xffffffffffffffff` —
|
|
41
|
+
* that value is not exactly representable as a JS number and rounds up to
|
|
42
|
+
* 2^64, so `BigInt(0xffffffffffffffff)` would never equal the real 2^64-1
|
|
43
|
+
* marker and the check would silently never fire.
|
|
44
|
+
*/
|
|
45
|
+
const UNKNOWN_DURATION_64 = BigInt("0xffffffffffffffff");
|
|
46
|
+
/**
|
|
47
|
+
* Sanity bound. Nothing this pipeline generates is longer than a few minutes;
|
|
48
|
+
* a multi-hour result means we misparsed (e.g. read a length field as a
|
|
49
|
+
* timescale). Reject rather than bill it.
|
|
50
|
+
*/
|
|
51
|
+
const MAX_PLAUSIBLE_DURATION_SEC = 3600;
|
|
52
|
+
/**
|
|
53
|
+
* Locate a direct child box by type within `[start, end)` and return the byte
|
|
54
|
+
* range of its PAYLOAD. Returns null when absent or when the tree is malformed.
|
|
55
|
+
*/
|
|
56
|
+
function findBox(buf, type, start, end) {
|
|
57
|
+
let offset = start;
|
|
58
|
+
while (offset + BOX_HEADER_BYTES <= end) {
|
|
59
|
+
const size32 = buf.readUInt32BE(offset);
|
|
60
|
+
const boxType = buf.toString("ascii", offset + 4, offset + 8);
|
|
61
|
+
let headerSize = BOX_HEADER_BYTES;
|
|
62
|
+
let boxSize;
|
|
63
|
+
if (size32 === 1) {
|
|
64
|
+
// 64-bit "largesize" follows the type field.
|
|
65
|
+
if (offset + 16 > end)
|
|
66
|
+
return null;
|
|
67
|
+
const large = buf.readBigUInt64BE(offset + 8);
|
|
68
|
+
// Beyond Number.MAX_SAFE_INTEGER we can't index the Buffer anyway.
|
|
69
|
+
if (large > BigInt(Number.MAX_SAFE_INTEGER))
|
|
70
|
+
return null;
|
|
71
|
+
boxSize = Number(large);
|
|
72
|
+
headerSize = 16;
|
|
73
|
+
}
|
|
74
|
+
else if (size32 === 0) {
|
|
75
|
+
// Size 0 means "this box extends to the end of the enclosing range".
|
|
76
|
+
boxSize = end - offset;
|
|
77
|
+
}
|
|
78
|
+
else {
|
|
79
|
+
boxSize = size32;
|
|
80
|
+
}
|
|
81
|
+
// A box must at least contain its own header, and must not overrun.
|
|
82
|
+
if (boxSize < headerSize || offset + boxSize > end)
|
|
83
|
+
return null;
|
|
84
|
+
if (boxType === type) {
|
|
85
|
+
return {
|
|
86
|
+
payloadStart: offset + headerSize,
|
|
87
|
+
payloadEnd: offset + boxSize,
|
|
88
|
+
};
|
|
89
|
+
}
|
|
90
|
+
offset += boxSize;
|
|
91
|
+
}
|
|
92
|
+
return null;
|
|
93
|
+
}
|
|
94
|
+
/**
|
|
95
|
+
* Read the duration, in seconds, of an MP4/MOV held in memory.
|
|
96
|
+
*
|
|
97
|
+
* Returns `undefined` for anything it cannot read with confidence: non-MP4
|
|
98
|
+
* input, a truncated download (no `moov`), fragmented MP4 with an unknown
|
|
99
|
+
* `mvhd` duration, a zero/absent timescale, or an implausible result.
|
|
100
|
+
*
|
|
101
|
+
* @param buf Raw bytes of the complete file.
|
|
102
|
+
*/
|
|
103
|
+
function readMp4DurationSec(buf) {
|
|
104
|
+
try {
|
|
105
|
+
if (!Buffer.isBuffer(buf) || buf.length < BOX_HEADER_BYTES)
|
|
106
|
+
return undefined;
|
|
107
|
+
// `moov` holds the movie metadata. For non-faststart output it sits at the
|
|
108
|
+
// END of the file, which is exactly why a truncated download loses it.
|
|
109
|
+
const moov = findBox(buf, "moov", 0, buf.length);
|
|
110
|
+
if (!moov)
|
|
111
|
+
return undefined;
|
|
112
|
+
const mvhd = findBox(buf, "mvhd", moov.payloadStart, moov.payloadEnd);
|
|
113
|
+
if (!mvhd)
|
|
114
|
+
return undefined;
|
|
115
|
+
const { payloadStart, payloadEnd } = mvhd;
|
|
116
|
+
// mvhd payload: version(1) + flags(3), then version-dependent fields.
|
|
117
|
+
if (payloadStart + 4 > payloadEnd)
|
|
118
|
+
return undefined;
|
|
119
|
+
const version = buf.readUInt8(payloadStart);
|
|
120
|
+
let timescale;
|
|
121
|
+
let duration;
|
|
122
|
+
if (version === 1) {
|
|
123
|
+
// creation(8) + modification(8) + timescale(4) + duration(8) = 28 bytes
|
|
124
|
+
if (payloadStart + 4 + 28 > payloadEnd)
|
|
125
|
+
return undefined;
|
|
126
|
+
timescale = buf.readUInt32BE(payloadStart + 4 + 16);
|
|
127
|
+
const raw = buf.readBigUInt64BE(payloadStart + 4 + 20);
|
|
128
|
+
if (raw === UNKNOWN_DURATION_64)
|
|
129
|
+
return undefined;
|
|
130
|
+
if (raw > BigInt(Number.MAX_SAFE_INTEGER))
|
|
131
|
+
return undefined;
|
|
132
|
+
duration = Number(raw);
|
|
133
|
+
}
|
|
134
|
+
else if (version === 0) {
|
|
135
|
+
// creation(4) + modification(4) + timescale(4) + duration(4) = 16 bytes
|
|
136
|
+
if (payloadStart + 4 + 16 > payloadEnd)
|
|
137
|
+
return undefined;
|
|
138
|
+
timescale = buf.readUInt32BE(payloadStart + 4 + 8);
|
|
139
|
+
duration = buf.readUInt32BE(payloadStart + 4 + 12);
|
|
140
|
+
if (duration === UNKNOWN_DURATION_32)
|
|
141
|
+
return undefined;
|
|
142
|
+
}
|
|
143
|
+
else {
|
|
144
|
+
// Unknown mvhd version — the field layout is not knowable.
|
|
145
|
+
return undefined;
|
|
146
|
+
}
|
|
147
|
+
if (timescale <= 0)
|
|
148
|
+
return undefined;
|
|
149
|
+
// fMP4 commonly writes duration 0 here; the real length is in the fragments.
|
|
150
|
+
if (duration <= 0)
|
|
151
|
+
return undefined;
|
|
152
|
+
const seconds = duration / timescale;
|
|
153
|
+
if (!Number.isFinite(seconds))
|
|
154
|
+
return undefined;
|
|
155
|
+
if (seconds <= 0 || seconds > MAX_PLAUSIBLE_DURATION_SEC)
|
|
156
|
+
return undefined;
|
|
157
|
+
return seconds;
|
|
158
|
+
}
|
|
159
|
+
catch {
|
|
160
|
+
// Deliberately swallowed: an unreadable file must degrade to "unknown"
|
|
161
|
+
// (bill the requested duration), never break status polling.
|
|
162
|
+
return undefined;
|
|
163
|
+
}
|
|
164
|
+
}
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
import type { IUserSubscription } from "../models/user.model";
|
|
2
|
+
/**
|
|
3
|
+
* X8 Social Suite — per-plan entitlements (monetization gate, F1).
|
|
4
|
+
*
|
|
5
|
+
* The global `FEATURE_SOCIAL` flag is the *kill-switch* that mounts the whole
|
|
6
|
+
* `/v1/social` surface; this map is the *per-user plan gate* layered on top of
|
|
7
|
+
* it. Publishing/analytics/engage are a subscription feature (plan §7), NOT a
|
|
8
|
+
* credit feature — generation keeps burning credits, the Social Suite is gated
|
|
9
|
+
* by tier.
|
|
10
|
+
*
|
|
11
|
+
* v1 policy mirrors SOCIAL_SUITE_PLAN §7 and is intentionally table-driven so
|
|
12
|
+
* the tiering can be retuned in ONE place without touching any call site:
|
|
13
|
+
* • Free = the hook — connect ONE account, publish manually, 7-day analytics.
|
|
14
|
+
* • Paid = scheduling + calendar, AI growth layer, engage inbox, advanced
|
|
15
|
+
* analytics (best-time + audience + full history), more accounts.
|
|
16
|
+
*
|
|
17
|
+
* To make the Social Suite fully paid-only (no free hook), set FREE.enabled to
|
|
18
|
+
* false and gate the router with `requireSocialCapability` accordingly — every
|
|
19
|
+
* consumer reads this map, so that one edit changes the whole product.
|
|
20
|
+
*/
|
|
21
|
+
export interface ISocialCapabilities {
|
|
22
|
+
/** May use the Social Suite at all (connect + manual publish + basic stats). */
|
|
23
|
+
enabled: boolean;
|
|
24
|
+
/** Max connected accounts across every provider. */
|
|
25
|
+
maxAccounts: number;
|
|
26
|
+
/** Schedule posts for the future / use the content calendar (B3). */
|
|
27
|
+
scheduling: boolean;
|
|
28
|
+
/** AI growth layer: caption/hashtag/title suggest, hook score, insights (E1/E4/E5). */
|
|
29
|
+
aiGrowth: boolean;
|
|
30
|
+
/** Engagement inbox: reply / moderate / AI reply drafts (Pillar D). */
|
|
31
|
+
inbox: boolean;
|
|
32
|
+
/** Best-time-to-post (C4) + audience demographics (C7). */
|
|
33
|
+
advancedAnalytics: boolean;
|
|
34
|
+
/** How far back the overview dashboard history is visible (days). */
|
|
35
|
+
analyticsWindowDays: number;
|
|
36
|
+
}
|
|
37
|
+
/** The gated boolean capabilities a route/middleware can require. */
|
|
38
|
+
export type TSocialGatedCapability = "scheduling" | "aiGrowth" | "inbox" | "advancedAnalytics";
|
|
39
|
+
/**
|
|
40
|
+
* Resolve the Social-Suite capabilities for a user's subscription.
|
|
41
|
+
*
|
|
42
|
+
* Reuses `isPaidSubscription` so a trial / canceled / expired / inactive sub —
|
|
43
|
+
* or a missing one — falls back to the FREE hook tier, exactly like the
|
|
44
|
+
* watermark predicate. Erring toward the lower tier on a status blip (e.g.
|
|
45
|
+
* webhook lag) is the safe default: it withholds a paid feature for a moment
|
|
46
|
+
* rather than leaking it, and self-heals on the next `/v1/user` sync.
|
|
47
|
+
*/
|
|
48
|
+
export declare function getSocialCapabilities(subscription: IUserSubscription | undefined | null): ISocialCapabilities;
|
|
49
|
+
/** Whether a subscription includes a specific gated Social-Suite capability. */
|
|
50
|
+
export declare function planAllowsSocialCapability(subscription: IUserSubscription | undefined | null, capability: TSocialGatedCapability): boolean;
|
|
51
|
+
//# sourceMappingURL=socialEntitlements.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"socialEntitlements.d.ts","sourceRoot":"","sources":["../../src/utils/socialEntitlements.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,sBAAsB,CAAC;AAG9D;;;;;;;;;;;;;;;;;;GAkBG;AACH,MAAM,WAAW,mBAAmB;IAClC,gFAAgF;IAChF,OAAO,EAAE,OAAO,CAAC;IACjB,oDAAoD;IACpD,WAAW,EAAE,MAAM,CAAC;IACpB,qEAAqE;IACrE,UAAU,EAAE,OAAO,CAAC;IACpB,uFAAuF;IACvF,QAAQ,EAAE,OAAO,CAAC;IAClB,uEAAuE;IACvE,KAAK,EAAE,OAAO,CAAC;IACf,2DAA2D;IAC3D,iBAAiB,EAAE,OAAO,CAAC;IAC3B,qEAAqE;IACrE,mBAAmB,EAAE,MAAM,CAAC;CAC7B;AAED,qEAAqE;AACrE,MAAM,MAAM,sBAAsB,GAC9B,YAAY,GACZ,UAAU,GACV,OAAO,GACP,mBAAmB,CAAC;AA4CxB;;;;;;;;GAQG;AACH,wBAAgB,qBAAqB,CACnC,YAAY,EAAE,iBAAiB,GAAG,SAAS,GAAG,IAAI,GACjD,mBAAmB,CAIrB;AAED,gFAAgF;AAChF,wBAAgB,0BAA0B,CACxC,YAAY,EAAE,iBAAiB,GAAG,SAAS,GAAG,IAAI,EAClD,UAAU,EAAE,sBAAsB,GACjC,OAAO,CAET"}
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.getSocialCapabilities = getSocialCapabilities;
|
|
4
|
+
exports.planAllowsSocialCapability = planAllowsSocialCapability;
|
|
5
|
+
const types_1 = require("../globals/types");
|
|
6
|
+
const renderTier_1 = require("./renderTier");
|
|
7
|
+
const SOCIAL_CAPABILITIES = {
|
|
8
|
+
[types_1.ESUBSCRIPTION_PLANS.FREE]: {
|
|
9
|
+
enabled: true,
|
|
10
|
+
maxAccounts: 1,
|
|
11
|
+
scheduling: false,
|
|
12
|
+
aiGrowth: false,
|
|
13
|
+
inbox: false,
|
|
14
|
+
advancedAnalytics: false,
|
|
15
|
+
analyticsWindowDays: 7,
|
|
16
|
+
},
|
|
17
|
+
[types_1.ESUBSCRIPTION_PLANS.BASIC]: {
|
|
18
|
+
enabled: true,
|
|
19
|
+
maxAccounts: 5,
|
|
20
|
+
scheduling: true,
|
|
21
|
+
aiGrowth: true,
|
|
22
|
+
inbox: true,
|
|
23
|
+
advancedAnalytics: true,
|
|
24
|
+
analyticsWindowDays: 90,
|
|
25
|
+
},
|
|
26
|
+
[types_1.ESUBSCRIPTION_PLANS.PRO]: {
|
|
27
|
+
enabled: true,
|
|
28
|
+
maxAccounts: 25,
|
|
29
|
+
scheduling: true,
|
|
30
|
+
aiGrowth: true,
|
|
31
|
+
inbox: true,
|
|
32
|
+
advancedAnalytics: true,
|
|
33
|
+
analyticsWindowDays: 365,
|
|
34
|
+
},
|
|
35
|
+
[types_1.ESUBSCRIPTION_PLANS.BUSINESS]: {
|
|
36
|
+
enabled: true,
|
|
37
|
+
maxAccounts: 100,
|
|
38
|
+
scheduling: true,
|
|
39
|
+
aiGrowth: true,
|
|
40
|
+
inbox: true,
|
|
41
|
+
advancedAnalytics: true,
|
|
42
|
+
analyticsWindowDays: 365,
|
|
43
|
+
},
|
|
44
|
+
};
|
|
45
|
+
/** The tier everyone without an active paid plan falls back to (the free hook). */
|
|
46
|
+
const FREE_CAPABILITIES = SOCIAL_CAPABILITIES[types_1.ESUBSCRIPTION_PLANS.FREE];
|
|
47
|
+
/**
|
|
48
|
+
* Resolve the Social-Suite capabilities for a user's subscription.
|
|
49
|
+
*
|
|
50
|
+
* Reuses `isPaidSubscription` so a trial / canceled / expired / inactive sub —
|
|
51
|
+
* or a missing one — falls back to the FREE hook tier, exactly like the
|
|
52
|
+
* watermark predicate. Erring toward the lower tier on a status blip (e.g.
|
|
53
|
+
* webhook lag) is the safe default: it withholds a paid feature for a moment
|
|
54
|
+
* rather than leaking it, and self-heals on the next `/v1/user` sync.
|
|
55
|
+
*/
|
|
56
|
+
function getSocialCapabilities(subscription) {
|
|
57
|
+
if (!(0, renderTier_1.isPaidSubscription)(subscription))
|
|
58
|
+
return FREE_CAPABILITIES;
|
|
59
|
+
const plan = subscription?.planType;
|
|
60
|
+
return (plan && SOCIAL_CAPABILITIES[plan]) || FREE_CAPABILITIES;
|
|
61
|
+
}
|
|
62
|
+
/** Whether a subscription includes a specific gated Social-Suite capability. */
|
|
63
|
+
function planAllowsSocialCapability(subscription, capability) {
|
|
64
|
+
return getSocialCapabilities(subscription)[capability] === true;
|
|
65
|
+
}
|