vidspotai-shared 1.0.95 → 1.0.96
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 +2 -0
- package/lib/globals/aiModels/enums.d.ts.map +1 -1
- package/lib/globals/aiModels/enums.js +5 -0
- package/lib/globals/aiModels/index.d.ts.map +1 -1
- package/lib/globals/aiModels/index.js +2 -0
- package/lib/globals/aiModels/providers/hostedAvatars.d.ts +22 -0
- package/lib/globals/aiModels/providers/hostedAvatars.d.ts.map +1 -0
- package/lib/globals/aiModels/providers/hostedAvatars.js +129 -0
- package/lib/globals/types.d.ts +58 -1
- package/lib/globals/types.d.ts.map +1 -1
- package/lib/globals/types.js +61 -1
- package/lib/models/demoVideoProject.model.d.ts +244 -0
- package/lib/models/demoVideoProject.model.d.ts.map +1 -0
- package/lib/models/demoVideoProject.model.js +2 -0
- package/lib/models/githubConnection.model.d.ts +35 -0
- package/lib/models/githubConnection.model.d.ts.map +1 -0
- package/lib/models/githubConnection.model.js +2 -0
- package/lib/models/index.d.ts +3 -0
- package/lib/models/index.d.ts.map +1 -1
- package/lib/models/index.js +3 -0
- package/lib/models/outreach.model.d.ts +175 -0
- package/lib/models/outreach.model.d.ts.map +1 -0
- package/lib/models/outreach.model.js +2 -0
- package/lib/models/video.model.d.ts +4 -0
- package/lib/models/video.model.d.ts.map +1 -1
- package/lib/schemas/brandKit.schema.d.ts +4 -0
- package/lib/schemas/brandKit.schema.d.ts.map +1 -1
- package/lib/schemas/brandKit.schema.js +10 -0
- package/lib/schemas/demoQuestion.schema.d.ts +286 -0
- package/lib/schemas/demoQuestion.schema.d.ts.map +1 -0
- package/lib/schemas/demoQuestion.schema.js +210 -0
- package/lib/schemas/demoSpec.schema.d.ts +109 -6
- package/lib/schemas/demoSpec.schema.d.ts.map +1 -1
- package/lib/schemas/demoSpec.schema.js +95 -7
- package/lib/schemas/index.d.ts +1 -0
- package/lib/schemas/index.d.ts.map +1 -1
- package/lib/schemas/index.js +1 -0
- package/lib/services/agent/providerFallback/chains.d.ts.map +1 -1
- package/lib/services/agent/providerFallback/chains.js +9 -1
- package/lib/services/agent/taskPoller.d.ts.map +1 -1
- package/lib/services/agent/taskPoller.js +17 -6
- package/lib/services/agent/tools/generateAvatarVideo.tool.d.ts +21 -9
- package/lib/services/agent/tools/generateAvatarVideo.tool.d.ts.map +1 -1
- package/lib/services/agent/tools/generateAvatarVideo.tool.js +135 -39
- package/lib/services/aiGen/aiGenFactory.service.d.ts +1 -1
- package/lib/services/aiGen/aiGenFactory.service.d.ts.map +1 -1
- package/lib/services/aiGen/aiGenFactory.service.js +10 -2
- package/lib/services/avatarGen/IAvatarVideoProvider.d.ts +136 -0
- package/lib/services/avatarGen/IAvatarVideoProvider.d.ts.map +1 -0
- package/lib/services/avatarGen/IAvatarVideoProvider.js +42 -0
- package/lib/services/avatarGen/avatarProviderFactory.d.ts +18 -0
- package/lib/services/avatarGen/avatarProviderFactory.d.ts.map +1 -0
- package/lib/services/avatarGen/avatarProviderFactory.js +54 -0
- package/lib/services/avatarGen/index.d.ts +6 -0
- package/lib/services/avatarGen/index.d.ts.map +1 -0
- package/lib/services/avatarGen/index.js +21 -0
- package/lib/services/avatarGen/providers/heygenAvatarProvider.d.ts +45 -0
- package/lib/services/avatarGen/providers/heygenAvatarProvider.d.ts.map +1 -0
- package/lib/services/avatarGen/providers/heygenAvatarProvider.js +190 -0
- package/lib/services/avatarGen/providers/klingAvatarProvider.d.ts +32 -0
- package/lib/services/avatarGen/providers/klingAvatarProvider.d.ts.map +1 -0
- package/lib/services/avatarGen/providers/klingAvatarProvider.js +69 -0
- package/lib/services/avatarGen/providers/tavusAvatarProvider.d.ts +56 -0
- package/lib/services/avatarGen/providers/tavusAvatarProvider.d.ts.map +1 -0
- package/lib/services/avatarGen/providers/tavusAvatarProvider.js +183 -0
- package/lib/services/demo/demoAuthor.d.ts +45 -0
- package/lib/services/demo/demoAuthor.d.ts.map +1 -0
- package/lib/services/demo/demoAuthor.js +75 -0
- package/lib/services/demo/demoAuthorNormalize.d.ts +49 -0
- package/lib/services/demo/demoAuthorNormalize.d.ts.map +1 -0
- package/lib/services/demo/demoAuthorNormalize.js +327 -0
- package/lib/services/demo/demoAuthorPrompt.d.ts +102 -0
- package/lib/services/demo/demoAuthorPrompt.d.ts.map +1 -0
- package/lib/services/demo/demoAuthorPrompt.js +243 -0
- package/lib/services/demo/demoCredits.d.ts +20 -0
- package/lib/services/demo/demoCredits.d.ts.map +1 -0
- package/lib/services/demo/demoCredits.js +51 -0
- package/lib/services/demo/demoMediaGuard.d.ts +43 -0
- package/lib/services/demo/demoMediaGuard.d.ts.map +1 -0
- package/lib/services/demo/demoMediaGuard.js +207 -0
- package/lib/services/demo/demoMusic.d.ts +13 -0
- package/lib/services/demo/demoMusic.d.ts.map +1 -0
- package/lib/services/demo/demoMusic.js +93 -0
- package/lib/services/demo/demoPrefill.d.ts +76 -0
- package/lib/services/demo/demoPrefill.d.ts.map +1 -0
- package/lib/services/demo/demoPrefill.js +435 -0
- package/lib/services/demo/demoRevisePrompt.d.ts +17 -0
- package/lib/services/demo/demoRevisePrompt.d.ts.map +1 -0
- package/lib/services/demo/demoRevisePrompt.js +85 -0
- package/lib/services/demo/demoReviser.d.ts +63 -0
- package/lib/services/demo/demoReviser.d.ts.map +1 -0
- package/lib/services/demo/demoReviser.js +81 -0
- package/lib/services/demo/demoScriptPrompt.d.ts +63 -0
- package/lib/services/demo/demoScriptPrompt.d.ts.map +1 -0
- package/lib/services/demo/demoScriptPrompt.js +234 -0
- package/lib/services/demo/demoScriptWriter.d.ts +65 -0
- package/lib/services/demo/demoScriptWriter.d.ts.map +1 -0
- package/lib/services/demo/demoScriptWriter.js +211 -0
- package/lib/services/demo/demoTriage.d.ts +65 -0
- package/lib/services/demo/demoTriage.d.ts.map +1 -0
- package/lib/services/demo/demoTriage.js +130 -0
- package/lib/services/demo/githubOAuth.d.ts +78 -0
- package/lib/services/demo/githubOAuth.d.ts.map +1 -0
- package/lib/services/demo/githubOAuth.js +209 -0
- package/lib/services/demo/githubOAuthState.d.ts +10 -0
- package/lib/services/demo/githubOAuthState.d.ts.map +1 -0
- package/lib/services/demo/githubOAuthState.js +63 -0
- package/lib/services/demo/index.d.ts +24 -0
- package/lib/services/demo/index.d.ts.map +1 -0
- package/lib/services/demo/index.js +39 -0
- package/lib/services/firestore.service.d.ts +11 -0
- package/lib/services/firestore.service.d.ts.map +1 -1
- package/lib/services/firestore.service.js +24 -0
- package/lib/services/index.d.ts +2 -0
- package/lib/services/index.d.ts.map +1 -1
- package/lib/services/index.js +2 -0
- package/lib/services/tts/providers/elevenlabs.service.d.ts.map +1 -1
- package/lib/services/tts/providers/elevenlabs.service.js +16 -8
- package/lib/utils/index.d.ts +1 -0
- package/lib/utils/index.d.ts.map +1 -1
- package/lib/utils/index.js +1 -0
- package/lib/utils/outreachTemplate.d.ts +46 -0
- package/lib/utils/outreachTemplate.d.ts.map +1 -0
- package/lib/utils/outreachTemplate.js +174 -0
- package/package.json +1 -1
|
@@ -0,0 +1,209 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* GitHub OAuth App client — the v2 "connect GitHub for private repos" provider
|
|
4
|
+
* (plan §5, Phase 9). VidSpotAI is the OAuth CLIENT; GitHub is the provider. A
|
|
5
|
+
* classic OAuth App 3-legged flow: authorize → exchange code → non-expiring
|
|
6
|
+
* access token. We request `repo` (private-repo read) + `read:user` (identity).
|
|
7
|
+
*
|
|
8
|
+
* DORMANT until provisioned: everything gates on `GITHUB_OAUTH_CLIENT_ID` +
|
|
9
|
+
* `GITHUB_OAUTH_CLIENT_SECRET`. Until an app is registered and those land in
|
|
10
|
+
* Doppler, `isGithubOAuthConfigured()` is false and the connect endpoint 503s —
|
|
11
|
+
* exactly like the rest of the demo feature ships behind a flag.
|
|
12
|
+
*
|
|
13
|
+
* Env:
|
|
14
|
+
* GITHUB_OAUTH_CLIENT_ID — the OAuth App client id
|
|
15
|
+
* GITHUB_OAUTH_CLIENT_SECRET — the OAuth App client secret
|
|
16
|
+
* GITHUB_OAUTH_REDIRECT_URI — must EXACTLY match the app's Authorization
|
|
17
|
+
* callback URL, e.g.
|
|
18
|
+
* https://<api-host>/v1/demo-video/github/callback
|
|
19
|
+
*/
|
|
20
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
21
|
+
exports.GITHUB_OAUTH_SCOPES = void 0;
|
|
22
|
+
exports.isGithubOAuthConfigured = isGithubOAuthConfigured;
|
|
23
|
+
exports.githubRedirectUri = githubRedirectUri;
|
|
24
|
+
exports.buildGithubAuthUrl = buildGithubAuthUrl;
|
|
25
|
+
exports.exchangeGithubCode = exchangeGithubCode;
|
|
26
|
+
exports.fetchGithubUser = fetchGithubUser;
|
|
27
|
+
exports.listGithubRepos = listGithubRepos;
|
|
28
|
+
exports.revokeGithubToken = revokeGithubToken;
|
|
29
|
+
const AUTHORIZE_URL = "https://github.com/login/oauth/authorize";
|
|
30
|
+
const TOKEN_URL = "https://github.com/login/oauth/access_token";
|
|
31
|
+
const USER_URL = "https://api.github.com/user";
|
|
32
|
+
/**
|
|
33
|
+
* Scopes we request. `repo` is the classic scope that grants private-repo
|
|
34
|
+
* access (GitHub OAuth Apps have no read-only private-repo scope — that
|
|
35
|
+
* granularity requires a GitHub App installation, a much larger integration);
|
|
36
|
+
* `read:user` is identity only. Documented as broad in the plan §10 risks.
|
|
37
|
+
*/
|
|
38
|
+
exports.GITHUB_OAUTH_SCOPES = ["read:user", "repo"];
|
|
39
|
+
const UA = "vidspotai-demo-generator";
|
|
40
|
+
/** True once both client id + secret are configured. Gate the connect flow on this. */
|
|
41
|
+
function isGithubOAuthConfigured() {
|
|
42
|
+
return Boolean(process.env.GITHUB_OAUTH_CLIENT_ID &&
|
|
43
|
+
process.env.GITHUB_OAUTH_CLIENT_SECRET);
|
|
44
|
+
}
|
|
45
|
+
function clientId() {
|
|
46
|
+
const v = process.env.GITHUB_OAUTH_CLIENT_ID;
|
|
47
|
+
if (!v)
|
|
48
|
+
throw new Error("githubOAuth: GITHUB_OAUTH_CLIENT_ID not set");
|
|
49
|
+
return v;
|
|
50
|
+
}
|
|
51
|
+
function clientSecret() {
|
|
52
|
+
const v = process.env.GITHUB_OAUTH_CLIENT_SECRET;
|
|
53
|
+
if (!v)
|
|
54
|
+
throw new Error("githubOAuth: GITHUB_OAUTH_CLIENT_SECRET not set");
|
|
55
|
+
return v;
|
|
56
|
+
}
|
|
57
|
+
/** The registered callback URL. Must byte-match the OAuth App's setting. */
|
|
58
|
+
function githubRedirectUri() {
|
|
59
|
+
const v = process.env.GITHUB_OAUTH_REDIRECT_URI;
|
|
60
|
+
if (!v)
|
|
61
|
+
throw new Error("githubOAuth: GITHUB_OAUTH_REDIRECT_URI not set");
|
|
62
|
+
return v;
|
|
63
|
+
}
|
|
64
|
+
/** Build the GitHub authorize URL the client opens to start consent. */
|
|
65
|
+
function buildGithubAuthUrl(state) {
|
|
66
|
+
const params = new URLSearchParams({
|
|
67
|
+
client_id: clientId(),
|
|
68
|
+
redirect_uri: githubRedirectUri(),
|
|
69
|
+
scope: exports.GITHUB_OAUTH_SCOPES.join(" "),
|
|
70
|
+
state,
|
|
71
|
+
// Re-prompt so a user can escalate scopes / switch accounts deliberately.
|
|
72
|
+
allow_signup: "false",
|
|
73
|
+
});
|
|
74
|
+
return `${AUTHORIZE_URL}?${params.toString()}`;
|
|
75
|
+
}
|
|
76
|
+
/**
|
|
77
|
+
* Exchange the authorization `code` for an access token. Throws on any
|
|
78
|
+
* error response (GitHub returns 200 with an `error` field on failure).
|
|
79
|
+
*/
|
|
80
|
+
async function exchangeGithubCode(code) {
|
|
81
|
+
const res = await fetch(TOKEN_URL, {
|
|
82
|
+
method: "POST",
|
|
83
|
+
headers: {
|
|
84
|
+
Accept: "application/json",
|
|
85
|
+
"Content-Type": "application/json",
|
|
86
|
+
"User-Agent": UA,
|
|
87
|
+
},
|
|
88
|
+
body: JSON.stringify({
|
|
89
|
+
client_id: clientId(),
|
|
90
|
+
client_secret: clientSecret(),
|
|
91
|
+
code,
|
|
92
|
+
redirect_uri: githubRedirectUri(),
|
|
93
|
+
}),
|
|
94
|
+
});
|
|
95
|
+
if (!res.ok) {
|
|
96
|
+
throw new Error(`githubOAuth: token exchange HTTP ${res.status}`);
|
|
97
|
+
}
|
|
98
|
+
const json = (await res.json());
|
|
99
|
+
if (json.error || typeof json.access_token !== "string" || !json.access_token) {
|
|
100
|
+
const detail = typeof json.error_description === "string"
|
|
101
|
+
? json.error_description
|
|
102
|
+
: String(json.error ?? "no access_token");
|
|
103
|
+
throw new Error(`githubOAuth: token exchange failed — ${detail}`);
|
|
104
|
+
}
|
|
105
|
+
const scopes = typeof json.scope === "string" && json.scope.length
|
|
106
|
+
? json.scope.split(",").map((s) => s.trim()).filter(Boolean)
|
|
107
|
+
: [];
|
|
108
|
+
return { accessToken: json.access_token, scopes };
|
|
109
|
+
}
|
|
110
|
+
/** Fetch the authenticated user's identity for display. Throws on failure. */
|
|
111
|
+
async function fetchGithubUser(accessToken) {
|
|
112
|
+
const res = await fetch(USER_URL, {
|
|
113
|
+
headers: {
|
|
114
|
+
Authorization: `Bearer ${accessToken}`,
|
|
115
|
+
Accept: "application/vnd.github+json",
|
|
116
|
+
"User-Agent": UA,
|
|
117
|
+
},
|
|
118
|
+
});
|
|
119
|
+
if (!res.ok) {
|
|
120
|
+
throw new Error(`githubOAuth: fetch user HTTP ${res.status}`);
|
|
121
|
+
}
|
|
122
|
+
const json = (await res.json());
|
|
123
|
+
if (typeof json.id !== "number" || typeof json.login !== "string") {
|
|
124
|
+
throw new Error("githubOAuth: unexpected /user shape");
|
|
125
|
+
}
|
|
126
|
+
return {
|
|
127
|
+
id: json.id,
|
|
128
|
+
login: json.login,
|
|
129
|
+
...(typeof json.avatar_url === "string" ? { avatarUrl: json.avatar_url } : {}),
|
|
130
|
+
};
|
|
131
|
+
}
|
|
132
|
+
/**
|
|
133
|
+
* List the connected user's repositories for the repo picker (plan §9 UX).
|
|
134
|
+
* Mirrors `fetchGithubUser`'s auth headers against `GET /user/repos`. Pulls up
|
|
135
|
+
* to `maxPages` pages of 100, sorted by most-recently pushed, spanning repos the
|
|
136
|
+
* user owns / collaborates on / can see via org membership. Best-effort per page:
|
|
137
|
+
* a mid-pagination failure returns what we have rather than throwing.
|
|
138
|
+
*/
|
|
139
|
+
async function listGithubRepos(accessToken, opts = {}) {
|
|
140
|
+
const maxPages = Math.min(Math.max(opts.maxPages ?? 3, 1), 10);
|
|
141
|
+
const out = [];
|
|
142
|
+
for (let page = 1; page <= maxPages; page++) {
|
|
143
|
+
const url = `https://api.github.com/user/repos?per_page=100&page=${page}` +
|
|
144
|
+
`&sort=pushed&affiliation=owner,collaborator,organization_member`;
|
|
145
|
+
const res = await fetch(url, {
|
|
146
|
+
headers: {
|
|
147
|
+
Authorization: `Bearer ${accessToken}`,
|
|
148
|
+
Accept: "application/vnd.github+json",
|
|
149
|
+
"User-Agent": UA,
|
|
150
|
+
},
|
|
151
|
+
});
|
|
152
|
+
if (!res.ok) {
|
|
153
|
+
if (page === 1)
|
|
154
|
+
throw new Error(`githubOAuth: list repos HTTP ${res.status}`);
|
|
155
|
+
break; // partial results are fine past the first page
|
|
156
|
+
}
|
|
157
|
+
const rows = (await res.json());
|
|
158
|
+
if (!Array.isArray(rows) || rows.length === 0)
|
|
159
|
+
break;
|
|
160
|
+
for (const r of rows) {
|
|
161
|
+
if (typeof r.full_name !== "string" || typeof r.name !== "string")
|
|
162
|
+
continue;
|
|
163
|
+
const owner = r.owner && typeof r.owner.login === "string"
|
|
164
|
+
? r.owner.login
|
|
165
|
+
: r.full_name.split("/")[0] ?? "";
|
|
166
|
+
out.push({
|
|
167
|
+
fullName: r.full_name,
|
|
168
|
+
name: r.name,
|
|
169
|
+
owner,
|
|
170
|
+
private: Boolean(r.private),
|
|
171
|
+
...(typeof r.description === "string" && r.description
|
|
172
|
+
? { description: r.description }
|
|
173
|
+
: {}),
|
|
174
|
+
defaultBranch: typeof r.default_branch === "string" ? r.default_branch : "main",
|
|
175
|
+
htmlUrl: typeof r.html_url === "string"
|
|
176
|
+
? r.html_url
|
|
177
|
+
: `https://github.com/${r.full_name}`,
|
|
178
|
+
...(typeof r.pushed_at === "string" ? { updatedAt: r.pushed_at } : {}),
|
|
179
|
+
});
|
|
180
|
+
}
|
|
181
|
+
if (rows.length < 100)
|
|
182
|
+
break; // last page
|
|
183
|
+
}
|
|
184
|
+
return out;
|
|
185
|
+
}
|
|
186
|
+
/**
|
|
187
|
+
* Best-effort provider-side revoke of a token grant (called on disconnect).
|
|
188
|
+
* Uses the OAuth App's client credentials via Basic auth. Non-fatal — returns
|
|
189
|
+
* false instead of throwing so a disconnect always completes locally.
|
|
190
|
+
*/
|
|
191
|
+
async function revokeGithubToken(accessToken) {
|
|
192
|
+
try {
|
|
193
|
+
const basic = Buffer.from(`${clientId()}:${clientSecret()}`).toString("base64");
|
|
194
|
+
const res = await fetch(`https://api.github.com/applications/${clientId()}/grant`, {
|
|
195
|
+
method: "DELETE",
|
|
196
|
+
headers: {
|
|
197
|
+
Authorization: `Basic ${basic}`,
|
|
198
|
+
Accept: "application/vnd.github+json",
|
|
199
|
+
"Content-Type": "application/json",
|
|
200
|
+
"User-Agent": UA,
|
|
201
|
+
},
|
|
202
|
+
body: JSON.stringify({ access_token: accessToken }),
|
|
203
|
+
});
|
|
204
|
+
return res.status === 204;
|
|
205
|
+
}
|
|
206
|
+
catch {
|
|
207
|
+
return false;
|
|
208
|
+
}
|
|
209
|
+
}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
export interface GithubOAuthStatePayload {
|
|
2
|
+
userId: string;
|
|
3
|
+
/** App path to return to after connect (optional). */
|
|
4
|
+
returnTo?: string;
|
|
5
|
+
}
|
|
6
|
+
/** Produce a signed state string to hand to GitHub's authorize URL. */
|
|
7
|
+
export declare function signGithubOAuthState(payload: GithubOAuthStatePayload, nonce: string): string;
|
|
8
|
+
/** Verify + decode a state string. Returns null if invalid, forged, or expired. */
|
|
9
|
+
export declare function verifyGithubOAuthState(state: string): GithubOAuthStatePayload | null;
|
|
10
|
+
//# sourceMappingURL=githubOAuthState.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"githubOAuthState.d.ts","sourceRoot":"","sources":["../../../src/services/demo/githubOAuthState.ts"],"names":[],"mappings":"AAiBA,MAAM,WAAW,uBAAuB;IACtC,MAAM,EAAE,MAAM,CAAC;IACf,sDAAsD;IACtD,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAgCD,uEAAuE;AACvE,wBAAgB,oBAAoB,CAClC,OAAO,EAAE,uBAAuB,EAChC,KAAK,EAAE,MAAM,GACZ,MAAM,CAIR;AAED,mFAAmF;AACnF,wBAAgB,sBAAsB,CACpC,KAAK,EAAE,MAAM,GACZ,uBAAuB,GAAG,IAAI,CAkBhC"}
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.signGithubOAuthState = signGithubOAuthState;
|
|
4
|
+
exports.verifyGithubOAuthState = verifyGithubOAuthState;
|
|
5
|
+
const crypto_1 = require("crypto");
|
|
6
|
+
const tokenVault_1 = require("../crypto/tokenVault");
|
|
7
|
+
/**
|
|
8
|
+
* Stateless, signed OAuth `state` for the GitHub connect flow (plan Phase 9).
|
|
9
|
+
* The callback (`/v1/demo-video/github/callback`) is UNAUTHENTICATED — GitHub
|
|
10
|
+
* redirects the browser there with no Firebase token — so we carry the
|
|
11
|
+
* initiating user's id inside a signed, time-boxed `state` rather than a server
|
|
12
|
+
* session. HMAC-SHA256 prevents forgery; the TTL bounds replay. Mirrors the
|
|
13
|
+
* Social Suite's `oauthState.ts`, kept separate so GitHub has its own payload
|
|
14
|
+
* and can use a distinct secret.
|
|
15
|
+
*
|
|
16
|
+
* Secret: `GITHUB_OAUTH_STATE_SECRET`, falling back to `SOCIAL_TOKEN_ENC_KEY`.
|
|
17
|
+
*/
|
|
18
|
+
const TTL_MS = 10 * 60 * 1000; // 10 minutes to complete consent
|
|
19
|
+
function secret() {
|
|
20
|
+
const s = process.env.GITHUB_OAUTH_STATE_SECRET ?? process.env.SOCIAL_TOKEN_ENC_KEY;
|
|
21
|
+
if (!s) {
|
|
22
|
+
throw new Error("githubOAuthState: set GITHUB_OAUTH_STATE_SECRET (or SOCIAL_TOKEN_ENC_KEY)");
|
|
23
|
+
}
|
|
24
|
+
return s;
|
|
25
|
+
}
|
|
26
|
+
function b64url(buf) {
|
|
27
|
+
return buf
|
|
28
|
+
.toString("base64")
|
|
29
|
+
.replace(/\+/g, "-")
|
|
30
|
+
.replace(/\//g, "_")
|
|
31
|
+
.replace(/=+$/, "");
|
|
32
|
+
}
|
|
33
|
+
function sign(body) {
|
|
34
|
+
return b64url((0, crypto_1.createHmac)("sha256", secret()).update(body).digest());
|
|
35
|
+
}
|
|
36
|
+
/** Produce a signed state string to hand to GitHub's authorize URL. */
|
|
37
|
+
function signGithubOAuthState(payload, nonce) {
|
|
38
|
+
const full = { ...payload, iat: Date.now(), n: nonce };
|
|
39
|
+
const body = b64url(Buffer.from(JSON.stringify(full), "utf8"));
|
|
40
|
+
return `${body}.${sign(body)}`;
|
|
41
|
+
}
|
|
42
|
+
/** Verify + decode a state string. Returns null if invalid, forged, or expired. */
|
|
43
|
+
function verifyGithubOAuthState(state) {
|
|
44
|
+
const dot = state.lastIndexOf(".");
|
|
45
|
+
if (dot <= 0)
|
|
46
|
+
return null;
|
|
47
|
+
const body = state.slice(0, dot);
|
|
48
|
+
const sig = state.slice(dot + 1);
|
|
49
|
+
if (!(0, tokenVault_1.safeEqual)(sig, sign(body)))
|
|
50
|
+
return null;
|
|
51
|
+
try {
|
|
52
|
+
const json = Buffer.from(body.replace(/-/g, "+").replace(/_/g, "/"), "base64").toString("utf8");
|
|
53
|
+
const parsed = JSON.parse(json);
|
|
54
|
+
if (!parsed.userId)
|
|
55
|
+
return null;
|
|
56
|
+
if (Date.now() - parsed.iat > TTL_MS)
|
|
57
|
+
return null;
|
|
58
|
+
return { userId: parsed.userId, returnTo: parsed.returnTo };
|
|
59
|
+
}
|
|
60
|
+
catch {
|
|
61
|
+
return null;
|
|
62
|
+
}
|
|
63
|
+
}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* SaaS Demo Video Generator — backend services.
|
|
3
|
+
* See notes/SAAS_DEMO_GENERATOR_PLAN.md.
|
|
4
|
+
*
|
|
5
|
+
* Phase 3: the DemoSpec author (single Claude `.structured<DemoSpec>()` call
|
|
6
|
+
* from inputs incl. screenshot vision) + its deterministic normalize pass.
|
|
7
|
+
* Phase 5: the narration writer (timeline-synced script over the rendered
|
|
8
|
+
* DemoSpec). The voice/mux stages live in the worker (they need TTS + ffmpeg).
|
|
9
|
+
*/
|
|
10
|
+
export * from "./demoAuthorPrompt";
|
|
11
|
+
export * from "./demoAuthorNormalize";
|
|
12
|
+
export * from "./demoAuthor";
|
|
13
|
+
export * from "./demoCredits";
|
|
14
|
+
export * from "./demoScriptPrompt";
|
|
15
|
+
export * from "./demoScriptWriter";
|
|
16
|
+
export * from "./demoMusic";
|
|
17
|
+
export * from "./demoMediaGuard";
|
|
18
|
+
export * from "./demoRevisePrompt";
|
|
19
|
+
export * from "./demoReviser";
|
|
20
|
+
export * from "./demoPrefill";
|
|
21
|
+
export * from "./demoTriage";
|
|
22
|
+
export * from "./githubOAuth";
|
|
23
|
+
export * from "./githubOAuthState";
|
|
24
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/services/demo/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AACH,cAAc,oBAAoB,CAAC;AACnC,cAAc,uBAAuB,CAAC;AACtC,cAAc,cAAc,CAAC;AAC7B,cAAc,eAAe,CAAC;AAC9B,cAAc,oBAAoB,CAAC;AACnC,cAAc,oBAAoB,CAAC;AACnC,cAAc,aAAa,CAAC;AAC5B,cAAc,kBAAkB,CAAC;AACjC,cAAc,oBAAoB,CAAC;AACnC,cAAc,eAAe,CAAC;AAC9B,cAAc,eAAe,CAAC;AAC9B,cAAc,cAAc,CAAC;AAC7B,cAAc,eAAe,CAAC;AAC9B,cAAc,oBAAoB,CAAC"}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
14
|
+
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
|
15
|
+
};
|
|
16
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
17
|
+
/**
|
|
18
|
+
* SaaS Demo Video Generator — backend services.
|
|
19
|
+
* See notes/SAAS_DEMO_GENERATOR_PLAN.md.
|
|
20
|
+
*
|
|
21
|
+
* Phase 3: the DemoSpec author (single Claude `.structured<DemoSpec>()` call
|
|
22
|
+
* from inputs incl. screenshot vision) + its deterministic normalize pass.
|
|
23
|
+
* Phase 5: the narration writer (timeline-synced script over the rendered
|
|
24
|
+
* DemoSpec). The voice/mux stages live in the worker (they need TTS + ffmpeg).
|
|
25
|
+
*/
|
|
26
|
+
__exportStar(require("./demoAuthorPrompt"), exports);
|
|
27
|
+
__exportStar(require("./demoAuthorNormalize"), exports);
|
|
28
|
+
__exportStar(require("./demoAuthor"), exports);
|
|
29
|
+
__exportStar(require("./demoCredits"), exports);
|
|
30
|
+
__exportStar(require("./demoScriptPrompt"), exports);
|
|
31
|
+
__exportStar(require("./demoScriptWriter"), exports);
|
|
32
|
+
__exportStar(require("./demoMusic"), exports);
|
|
33
|
+
__exportStar(require("./demoMediaGuard"), exports);
|
|
34
|
+
__exportStar(require("./demoRevisePrompt"), exports);
|
|
35
|
+
__exportStar(require("./demoReviser"), exports);
|
|
36
|
+
__exportStar(require("./demoPrefill"), exports);
|
|
37
|
+
__exportStar(require("./demoTriage"), exports);
|
|
38
|
+
__exportStar(require("./githubOAuth"), exports);
|
|
39
|
+
__exportStar(require("./githubOAuthState"), exports);
|
|
@@ -12,6 +12,9 @@ import { ISocialAccountModel, ISocialAnalyticsModel, ISocialInboxItemModel, ISoc
|
|
|
12
12
|
import { IShareModel } from "../models/share.model";
|
|
13
13
|
import { IUserModel } from "../models/user.model";
|
|
14
14
|
import { IVideoJobModel } from "../models/video.model";
|
|
15
|
+
import { IDemoVideoProjectModel } from "../models/demoVideoProject.model";
|
|
16
|
+
import { IGithubConnectionModel } from "../models/githubConnection.model";
|
|
17
|
+
import { IOutreachCampaignModel, IOutreachRecipientModel, IOutreachTemplateModel, IPersonalizedVideoModel, IVideoViewModel } from "../models/outreach.model";
|
|
15
18
|
/**
|
|
16
19
|
* FirestoreService
|
|
17
20
|
* ----------------
|
|
@@ -51,10 +54,18 @@ export declare class FirestoreService {
|
|
|
51
54
|
static agentRunsCol: CollectionReference<IAgentRunModel, DocumentData>;
|
|
52
55
|
static sharesCol: CollectionReference<IShareModel, DocumentData>;
|
|
53
56
|
static mediaUploadsCol: CollectionReference<IMediaUploadModel, DocumentData>;
|
|
57
|
+
static demoVideoProjectsCol: CollectionReference<IDemoVideoProjectModel, DocumentData>;
|
|
58
|
+
/** GitHub OAuth connections — one doc per user (doc id = userId). Phase 9. */
|
|
59
|
+
static githubConnectionsCol: CollectionReference<IGithubConnectionModel, DocumentData>;
|
|
54
60
|
static socialAccountsCol: CollectionReference<ISocialAccountModel, DocumentData>;
|
|
55
61
|
static socialPostsCol: CollectionReference<ISocialPostModel, DocumentData>;
|
|
56
62
|
static socialAnalyticsCol: CollectionReference<ISocialAnalyticsModel, DocumentData>;
|
|
57
63
|
static socialInboxCol: CollectionReference<ISocialInboxItemModel, DocumentData>;
|
|
64
|
+
static outreachTemplatesCol: CollectionReference<IOutreachTemplateModel, DocumentData>;
|
|
65
|
+
static personalizedVideosCol: CollectionReference<IPersonalizedVideoModel, DocumentData>;
|
|
66
|
+
static outreachCampaignsCol: CollectionReference<IOutreachCampaignModel, DocumentData>;
|
|
67
|
+
static outreachRecipientsCol: CollectionReference<IOutreachRecipientModel, DocumentData>;
|
|
68
|
+
static videoViewsCol: CollectionReference<IVideoViewModel, DocumentData>;
|
|
58
69
|
/**
|
|
59
70
|
* Sentinel for `.update()` that removes a field from a doc (wraps
|
|
60
71
|
* `FieldValue.delete()`). Use to clear a transient field — e.g. plan-B's
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"firestore.service.d.ts","sourceRoot":"","sources":["../../src/services/firestore.service.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,YAAY,EAEZ,gBAAgB,EAEhB,aAAa,EACd,MAAM,yBAAyB,CAAC;AACjC,OAAO,EACL,mBAAmB,EACnB,iBAAiB,EACjB,UAAU,EAEX,MAAM,0BAA0B,CAAC;AAClC,OAAO,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC;AAE/C,OAAO,EACL,kBAAkB,EAClB,cAAc,EACd,cAAc,EACd,iBAAiB,EAClB,MAAM,uBAAuB,CAAC;AAC/B,OAAO,EAAE,iBAAiB,EAAE,MAAM,6BAA6B,CAAC;AAChE,OAAO,EAAE,oBAAoB,EAAE,MAAM,gCAAgC,CAAC;AACtE,OAAO,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAC;AACvD,OAAO,EAAE,kBAAkB,EAAE,MAAM,8BAA8B,CAAC;AAClE,OAAO,EAAE,SAAS,EAAE,MAAM,qBAAqB,CAAC;AAEhD,OAAO,EAAE,iBAAiB,EAAE,MAAM,6BAA6B,CAAC;AAChE,OAAO,EACL,mBAAmB,EACnB,qBAAqB,EACrB,qBAAqB,EACrB,gBAAgB,EACjB,MAAM,wBAAwB,CAAC;AAChC,OAAO,EAAE,WAAW,EAAE,MAAM,uBAAuB,CAAC;AACpD,OAAO,EAAE,UAAU,EAAE,MAAM,sBAAsB,CAAC;AAClD,OAAO,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAC;
|
|
1
|
+
{"version":3,"file":"firestore.service.d.ts","sourceRoot":"","sources":["../../src/services/firestore.service.ts"],"names":[],"mappings":"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"}
|
|
@@ -164,6 +164,14 @@ FirestoreService.sharesCol = firebase_1.firestore
|
|
|
164
164
|
FirestoreService.mediaUploadsCol = firebase_1.firestore
|
|
165
165
|
.collection("mediaUploads")
|
|
166
166
|
.withConverter(collectionConverter());
|
|
167
|
+
// 🔹 SaaS Demo Video Generator — see notes/SAAS_DEMO_GENERATOR_PLAN.md
|
|
168
|
+
FirestoreService.demoVideoProjectsCol = firebase_1.firestore
|
|
169
|
+
.collection("demoVideoProjects")
|
|
170
|
+
.withConverter(collectionConverter());
|
|
171
|
+
/** GitHub OAuth connections — one doc per user (doc id = userId). Phase 9. */
|
|
172
|
+
FirestoreService.githubConnectionsCol = firebase_1.firestore
|
|
173
|
+
.collection("githubConnections")
|
|
174
|
+
.withConverter(collectionConverter());
|
|
167
175
|
// 🔹 X8 Social Suite — see notes/SOCIAL_SUITE_PLAN.md
|
|
168
176
|
FirestoreService.socialAccountsCol = firebase_1.firestore
|
|
169
177
|
.collection("socialAccounts")
|
|
@@ -177,3 +185,19 @@ FirestoreService.socialAnalyticsCol = firebase_1.firestore
|
|
|
177
185
|
FirestoreService.socialInboxCol = firebase_1.firestore
|
|
178
186
|
.collection("socialInbox")
|
|
179
187
|
.withConverter(collectionConverter());
|
|
188
|
+
// 🔹 Reach — Personalized Video Outreach (see notes/SALES_VIDEO_OUTREACH_PLAN.md)
|
|
189
|
+
FirestoreService.outreachTemplatesCol = firebase_1.firestore
|
|
190
|
+
.collection("outreachTemplates")
|
|
191
|
+
.withConverter(collectionConverter());
|
|
192
|
+
FirestoreService.personalizedVideosCol = firebase_1.firestore
|
|
193
|
+
.collection("personalizedVideos")
|
|
194
|
+
.withConverter(collectionConverter());
|
|
195
|
+
FirestoreService.outreachCampaignsCol = firebase_1.firestore
|
|
196
|
+
.collection("outreachCampaigns")
|
|
197
|
+
.withConverter(collectionConverter());
|
|
198
|
+
FirestoreService.outreachRecipientsCol = firebase_1.firestore
|
|
199
|
+
.collection("outreachRecipients")
|
|
200
|
+
.withConverter(collectionConverter());
|
|
201
|
+
FirestoreService.videoViewsCol = firebase_1.firestore
|
|
202
|
+
.collection("videoViews")
|
|
203
|
+
.withConverter(collectionConverter());
|
package/lib/services/index.d.ts
CHANGED
|
@@ -3,6 +3,7 @@ export * from "./redisOptions";
|
|
|
3
3
|
export * from "./rateLimiter";
|
|
4
4
|
export * from "./firestore.service";
|
|
5
5
|
export * from "./aiGen";
|
|
6
|
+
export * from "./avatarGen";
|
|
6
7
|
export * from "./bullmq.service";
|
|
7
8
|
export * from "./gcp";
|
|
8
9
|
export * from "./credit.service";
|
|
@@ -15,6 +16,7 @@ export * from "./musicGen";
|
|
|
15
16
|
export * from "./audioAnalysis";
|
|
16
17
|
export * from "./asr";
|
|
17
18
|
export * from "./agent";
|
|
19
|
+
export * from "./demo";
|
|
18
20
|
export * from "./promptEnhancer";
|
|
19
21
|
export * from "./assetCache.service";
|
|
20
22
|
export * from "./apiUsageCounter.service";
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/services/index.ts"],"names":[],"mappings":"AAAA,cAAc,iBAAiB,CAAC;AAChC,cAAc,gBAAgB,CAAC;AAC/B,cAAc,eAAe,CAAC;AAC9B,cAAc,qBAAqB,CAAC;AACpC,cAAc,SAAS,CAAC;AACxB,cAAc,kBAAkB,CAAC;AACjC,cAAc,OAAO,CAAC;AACtB,cAAc,kBAAkB,CAAC;AACjC,cAAc,wBAAwB,CAAC;AACvC,cAAc,mBAAmB,CAAC;AAClC,cAAc,qBAAqB,CAAC;AACpC,cAAc,OAAO,CAAC;AACtB,cAAc,eAAe,CAAC;AAC9B,cAAc,YAAY,CAAC;AAC3B,cAAc,iBAAiB,CAAC;AAChC,cAAc,OAAO,CAAC;AACtB,cAAc,SAAS,CAAC;AACxB,cAAc,kBAAkB,CAAC;AACjC,cAAc,sBAAsB,CAAC;AACrC,cAAc,2BAA2B,CAAC;AAC1C,cAAc,0BAA0B,CAAC;AACzC,cAAc,0BAA0B,CAAC;AACzC,cAAc,wBAAwB,CAAC;AACvC,cAAc,2BAA2B,CAAC;AAC1C,cAAc,SAAS,CAAC;AACxB,cAAc,UAAU,CAAC;AACzB,cAAc,eAAe,CAAC;AAC9B,cAAc,iBAAiB,CAAC;AAChC,cAAc,iBAAiB,CAAC;AAChC,cAAc,gBAAgB,CAAC;AAC/B,cAAc,gBAAgB,CAAC;AAC/B,cAAc,YAAY,CAAC;AAC3B,cAAc,kBAAkB,CAAC;AACjC,cAAc,kBAAkB,CAAC;AACjC,cAAc,YAAY,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/services/index.ts"],"names":[],"mappings":"AAAA,cAAc,iBAAiB,CAAC;AAChC,cAAc,gBAAgB,CAAC;AAC/B,cAAc,eAAe,CAAC;AAC9B,cAAc,qBAAqB,CAAC;AACpC,cAAc,SAAS,CAAC;AACxB,cAAc,aAAa,CAAC;AAC5B,cAAc,kBAAkB,CAAC;AACjC,cAAc,OAAO,CAAC;AACtB,cAAc,kBAAkB,CAAC;AACjC,cAAc,wBAAwB,CAAC;AACvC,cAAc,mBAAmB,CAAC;AAClC,cAAc,qBAAqB,CAAC;AACpC,cAAc,OAAO,CAAC;AACtB,cAAc,eAAe,CAAC;AAC9B,cAAc,YAAY,CAAC;AAC3B,cAAc,iBAAiB,CAAC;AAChC,cAAc,OAAO,CAAC;AACtB,cAAc,SAAS,CAAC;AACxB,cAAc,QAAQ,CAAC;AACvB,cAAc,kBAAkB,CAAC;AACjC,cAAc,sBAAsB,CAAC;AACrC,cAAc,2BAA2B,CAAC;AAC1C,cAAc,0BAA0B,CAAC;AACzC,cAAc,0BAA0B,CAAC;AACzC,cAAc,wBAAwB,CAAC;AACvC,cAAc,2BAA2B,CAAC;AAC1C,cAAc,SAAS,CAAC;AACxB,cAAc,UAAU,CAAC;AACzB,cAAc,eAAe,CAAC;AAC9B,cAAc,iBAAiB,CAAC;AAChC,cAAc,iBAAiB,CAAC;AAChC,cAAc,gBAAgB,CAAC;AAC/B,cAAc,gBAAgB,CAAC;AAC/B,cAAc,YAAY,CAAC;AAC3B,cAAc,kBAAkB,CAAC;AACjC,cAAc,kBAAkB,CAAC;AACjC,cAAc,YAAY,CAAC"}
|
package/lib/services/index.js
CHANGED
|
@@ -19,6 +19,7 @@ __exportStar(require("./redisOptions"), exports);
|
|
|
19
19
|
__exportStar(require("./rateLimiter"), exports);
|
|
20
20
|
__exportStar(require("./firestore.service"), exports);
|
|
21
21
|
__exportStar(require("./aiGen"), exports);
|
|
22
|
+
__exportStar(require("./avatarGen"), exports);
|
|
22
23
|
__exportStar(require("./bullmq.service"), exports);
|
|
23
24
|
__exportStar(require("./gcp"), exports);
|
|
24
25
|
__exportStar(require("./credit.service"), exports);
|
|
@@ -31,6 +32,7 @@ __exportStar(require("./musicGen"), exports);
|
|
|
31
32
|
__exportStar(require("./audioAnalysis"), exports);
|
|
32
33
|
__exportStar(require("./asr"), exports);
|
|
33
34
|
__exportStar(require("./agent"), exports);
|
|
35
|
+
__exportStar(require("./demo"), exports);
|
|
34
36
|
__exportStar(require("./promptEnhancer"), exports);
|
|
35
37
|
__exportStar(require("./assetCache.service"), exports);
|
|
36
38
|
__exportStar(require("./apiUsageCounter.service"), exports);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"elevenlabs.service.d.ts","sourceRoot":"","sources":["../../../../src/services/tts/providers/elevenlabs.service.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,sBAAsB,EAAE,eAAe,EAAE,SAAS,EAAE,SAAS,EAAE,MAAM,UAAU,CAAC;AAiBzF,qBAAa,iBAAkB,SAAQ,sBAAsB;IAC3D,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAkC;IAE1D,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAS;;IAW1B,QAAQ,CAAC,MAAM,EAAE,SAAS,GAAG,OAAO,CAAC,SAAS,CAAC;
|
|
1
|
+
{"version":3,"file":"elevenlabs.service.d.ts","sourceRoot":"","sources":["../../../../src/services/tts/providers/elevenlabs.service.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,sBAAsB,EAAE,eAAe,EAAE,SAAS,EAAE,SAAS,EAAE,MAAM,UAAU,CAAC;AAiBzF,qBAAa,iBAAkB,SAAQ,sBAAsB;IAC3D,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAkC;IAE1D,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAS;;IAW1B,QAAQ,CAAC,MAAM,EAAE,SAAS,GAAG,OAAO,CAAC,SAAS,CAAC;IA+FrD;;;;;OAKG;YACW,gBAAgB;IAsD9B,SAAS,IAAI,eAAe,EAAE;IAI9B,eAAe,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS;CAGpD"}
|
|
@@ -60,14 +60,22 @@ class ElevenLabsService extends types_1.BaseTtsProviderService {
|
|
|
60
60
|
};
|
|
61
61
|
if (params.seed !== undefined)
|
|
62
62
|
body.seed = params.seed;
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
if (
|
|
70
|
-
|
|
63
|
+
// Request-stitching / continuity hints (previous_text/next_text +
|
|
64
|
+
// previous/next_request_ids) are NOT supported by the v3 models — sending
|
|
65
|
+
// them 400s the whole request ("not yet supported with the 'eleven_v3'
|
|
66
|
+
// model"). Only thread them for models that accept them; a v3 model simply
|
|
67
|
+
// synthesizes each segment independently (fine for short demo narration).
|
|
68
|
+
const supportsContinuity = !modelId.includes("_v3");
|
|
69
|
+
if (supportsContinuity) {
|
|
70
|
+
if (params.previousText)
|
|
71
|
+
body.previous_text = params.previousText;
|
|
72
|
+
if (params.nextText)
|
|
73
|
+
body.next_text = params.nextText;
|
|
74
|
+
if (params.previousRequestIds?.length)
|
|
75
|
+
body.previous_request_ids = params.previousRequestIds.slice(0, 3);
|
|
76
|
+
if (params.nextRequestIds?.length)
|
|
77
|
+
body.next_request_ids = params.nextRequestIds.slice(0, 3);
|
|
78
|
+
}
|
|
71
79
|
if (params.applyTextNormalization)
|
|
72
80
|
body.apply_text_normalization = params.applyTextNormalization;
|
|
73
81
|
if (params.applyLanguageTextNormalization !== undefined) {
|
package/lib/utils/index.d.ts
CHANGED
package/lib/utils/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/utils/index.ts"],"names":[],"mappings":"AAAA,cAAc,UAAU,CAAC;AACzB,cAAc,WAAW,CAAC;AAC1B,cAAc,UAAU,CAAC;AACzB,cAAc,cAAc,CAAC;AAC7B,cAAc,YAAY,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/utils/index.ts"],"names":[],"mappings":"AAAA,cAAc,UAAU,CAAC;AACzB,cAAc,WAAW,CAAC;AAC1B,cAAc,UAAU,CAAC;AACzB,cAAc,cAAc,CAAC;AAC7B,cAAc,YAAY,CAAC;AAC3B,cAAc,oBAAoB,CAAC"}
|
package/lib/utils/index.js
CHANGED
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Outreach template utilities — shared between Firebase Functions (schema
|
|
3
|
+
* validation) and the node-express-server (fan-out processor).
|
|
4
|
+
*/
|
|
5
|
+
import type { VideoPlan } from "../schemas/videoPlan.schema";
|
|
6
|
+
/** Extract {{variable}} names from a script template string. */
|
|
7
|
+
export declare function extractTemplateVariables(script: string): string[];
|
|
8
|
+
/**
|
|
9
|
+
* Resolve a script template by substituting `{{varName}}` tokens with values
|
|
10
|
+
* from the `variables` map. Throws if a required variable is missing or empty.
|
|
11
|
+
*/
|
|
12
|
+
export declare function resolveTemplate(scriptTemplate: string, variables: Record<string, string>): string;
|
|
13
|
+
/**
|
|
14
|
+
* Deep-clone `value` and substitute `{{variables}}` inside every string it
|
|
15
|
+
* contains (recursively through objects and arrays). Non-string leaves are
|
|
16
|
+
* copied as-is; unknown tokens are left intact.
|
|
17
|
+
*
|
|
18
|
+
* Reach uses this to personalize an authored produced-scene `VideoPlan` per
|
|
19
|
+
* recipient — resolving `{{name}}`/`{{company}}` in scene voiceover lines,
|
|
20
|
+
* overlay text, visual prompts and titles — without re-planning. The input must
|
|
21
|
+
* be JSON-serializable (VideoPlan is); functions/Dates are not supported.
|
|
22
|
+
*/
|
|
23
|
+
export declare function resolvePlaceholdersDeep<T>(value: T, variables: Record<string, string>): T;
|
|
24
|
+
/**
|
|
25
|
+
* Translate the viewer-facing TEXT of a produced-scene {@link VideoPlan} into
|
|
26
|
+
* `toLocale` — the produced-scene half of Reach's multilingual wedge.
|
|
27
|
+
*
|
|
28
|
+
* Translates only what a viewer hears/reads: the plan `title`, each scene's
|
|
29
|
+
* `voiceoverLine`, `onScreenText`, and every `overlays[].text`. Visual `prompt`s
|
|
30
|
+
* and internal `intent`s are deliberately LEFT in the source language — those
|
|
31
|
+
* feed the video models, which expect (and were tuned on) English prompts.
|
|
32
|
+
*
|
|
33
|
+
* Behaviour:
|
|
34
|
+
* - No-ops (returns the input unchanged) when `toLocale` is absent or resolves
|
|
35
|
+
* to the same primary language as `fromLocale`.
|
|
36
|
+
* - Dedupes repeated strings (watermarks/CTAs recur across scenes) so each
|
|
37
|
+
* unique string is translated once, with bounded concurrency.
|
|
38
|
+
* - **Fails open per string:** a translation error keeps the original text
|
|
39
|
+
* rather than throwing — a translation outage must never block a render.
|
|
40
|
+
*
|
|
41
|
+
* Returns a deep clone; the input plan is never mutated.
|
|
42
|
+
*/
|
|
43
|
+
export declare function localizePlanText(plan: VideoPlan, toLocale: string | undefined, fromLocale?: string | undefined): Promise<VideoPlan>;
|
|
44
|
+
/** Generate a short URL-safe slug for a landing page (16 chars, alphanumeric). */
|
|
45
|
+
export declare function generateLandingPageSlug(): string;
|
|
46
|
+
//# sourceMappingURL=outreachTemplate.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"outreachTemplate.d.ts","sourceRoot":"","sources":["../../src/utils/outreachTemplate.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,6BAA6B,CAAC;AAK7D,gEAAgE;AAChE,wBAAgB,wBAAwB,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,EAAE,CAQjE;AAED;;;GAGG;AACH,wBAAgB,eAAe,CAC7B,cAAc,EAAE,MAAM,EACtB,SAAS,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAChC,MAAM,CAWR;AAcD;;;;;;;;;GASG;AACH,wBAAgB,uBAAuB,CAAC,CAAC,EACvC,KAAK,EAAE,CAAC,EACR,SAAS,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAChC,CAAC,CAeH;AAYD;;;;;;;;;;;;;;;;;;GAkBG;AACH,wBAAsB,gBAAgB,CACpC,IAAI,EAAE,SAAS,EACf,QAAQ,EAAE,MAAM,GAAG,SAAS,EAC5B,UAAU,GAAE,MAAM,GAAG,SAAgB,GACpC,OAAO,CAAC,SAAS,CAAC,CA+DpB;AAED,kFAAkF;AAClF,wBAAgB,uBAAuB,IAAI,MAAM,CAUhD"}
|