@spark-apps/quickpeek 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 (49) hide show
  1. package/dist/api-client.d.ts +61 -0
  2. package/dist/api-client.d.ts.map +1 -0
  3. package/dist/api-client.js +180 -0
  4. package/dist/api-client.js.map +1 -0
  5. package/dist/config.d.ts +69 -0
  6. package/dist/config.d.ts.map +1 -0
  7. package/dist/config.js +43 -0
  8. package/dist/config.js.map +1 -0
  9. package/dist/crawl.d.ts +18 -0
  10. package/dist/crawl.d.ts.map +1 -0
  11. package/dist/crawl.js +175 -0
  12. package/dist/crawl.js.map +1 -0
  13. package/dist/cursor.d.ts +6 -0
  14. package/dist/cursor.d.ts.map +1 -0
  15. package/dist/cursor.js +6 -0
  16. package/dist/cursor.js.map +1 -0
  17. package/dist/ffmpeg.d.ts +50 -0
  18. package/dist/ffmpeg.d.ts.map +1 -0
  19. package/dist/ffmpeg.js +224 -0
  20. package/dist/ffmpeg.js.map +1 -0
  21. package/dist/index.d.ts +15 -0
  22. package/dist/index.d.ts.map +1 -0
  23. package/dist/index.js +26 -0
  24. package/dist/index.js.map +1 -0
  25. package/dist/prompts.d.ts +13 -0
  26. package/dist/prompts.d.ts.map +1 -0
  27. package/dist/prompts.js +91 -0
  28. package/dist/prompts.js.map +1 -0
  29. package/dist/styles.d.ts +16 -0
  30. package/dist/styles.d.ts.map +1 -0
  31. package/dist/styles.js +66 -0
  32. package/dist/styles.js.map +1 -0
  33. package/dist/tts.d.ts +64 -0
  34. package/dist/tts.d.ts.map +1 -0
  35. package/dist/tts.js +236 -0
  36. package/dist/tts.js.map +1 -0
  37. package/dist/utils.d.ts +25 -0
  38. package/dist/utils.d.ts.map +1 -0
  39. package/dist/utils.js +106 -0
  40. package/dist/utils.js.map +1 -0
  41. package/dist/voices.d.ts +2 -0
  42. package/dist/voices.d.ts.map +1 -0
  43. package/dist/voices.js +73 -0
  44. package/dist/voices.js.map +1 -0
  45. package/dist/watermark.d.ts +27 -0
  46. package/dist/watermark.d.ts.map +1 -0
  47. package/dist/watermark.js +57 -0
  48. package/dist/watermark.js.map +1 -0
  49. package/package.json +45 -0
@@ -0,0 +1,61 @@
1
+ /**
2
+ * Unified API client for groq-backend and stripe-backend
3
+ * SaaS-ready: No CLI-specific code, pure functions with dependency injection
4
+ */
5
+ import type { UserTier } from './config.js';
6
+ export interface RateLimitInfo {
7
+ used: number;
8
+ limit: number;
9
+ tier: UserTier;
10
+ resetAt?: string;
11
+ }
12
+ export interface AIResponse {
13
+ success: true;
14
+ content: string;
15
+ limits: RateLimitInfo;
16
+ }
17
+ export interface AIError {
18
+ success: false;
19
+ error: string;
20
+ isRateLimit?: boolean;
21
+ isAuthError?: boolean;
22
+ }
23
+ export type AIResult = AIResponse | AIError;
24
+ export interface SubscriptionStatus {
25
+ status: 'active' | 'trialing' | 'lifetime' | 'past_due' | 'canceled' | null;
26
+ currentPeriodEnd?: string;
27
+ }
28
+ /**
29
+ * Get API credentials from environment
30
+ */
31
+ export declare function getCredentials(): {
32
+ appId: string;
33
+ appSecret: string;
34
+ } | null;
35
+ /**
36
+ * Check if API credentials are configured
37
+ */
38
+ export declare function hasCredentials(): boolean;
39
+ /**
40
+ * Call AI via groq-backend proxy
41
+ * Returns structured response with rate limit info
42
+ */
43
+ export declare function callAI(systemPrompt: string, userPrompt: string, userEmail: string): Promise<AIResult>;
44
+ /**
45
+ * Check subscription status via stripe-backend
46
+ */
47
+ export declare function checkSubscription(userEmail: string, appId?: string): Promise<SubscriptionStatus>;
48
+ /**
49
+ * Determine user tier based on subscription status
50
+ */
51
+ export declare function getTier(userEmail: string): Promise<UserTier>;
52
+ /**
53
+ * Check if watermark should be applied
54
+ * Watermark applies to free tier videos longer than 20 seconds
55
+ */
56
+ export declare function shouldWatermark(tier: UserTier, videoDurationSeconds: number): boolean;
57
+ /**
58
+ * Get upgrade URL for pricing page
59
+ */
60
+ export declare function getUpgradeUrl(userEmail?: string): string;
61
+ //# sourceMappingURL=api-client.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"api-client.d.ts","sourceRoot":"","sources":["../src/api-client.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;AAE5C,MAAM,WAAW,aAAa;IAC5B,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,QAAQ,CAAC;IACf,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED,MAAM,WAAW,UAAU;IACzB,OAAO,EAAE,IAAI,CAAC;IACd,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,EAAE,aAAa,CAAC;CACvB;AAED,MAAM,WAAW,OAAO;IACtB,OAAO,EAAE,KAAK,CAAC;IACf,KAAK,EAAE,MAAM,CAAC;IACd,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,WAAW,CAAC,EAAE,OAAO,CAAC;CACvB;AAED,MAAM,MAAM,QAAQ,GAAG,UAAU,GAAG,OAAO,CAAC;AAE5C,MAAM,WAAW,kBAAkB;IACjC,MAAM,EAAE,QAAQ,GAAG,UAAU,GAAG,UAAU,GAAG,UAAU,GAAG,UAAU,GAAG,IAAI,CAAC;IAC5E,gBAAgB,CAAC,EAAE,MAAM,CAAC;CAC3B;AAYD;;GAEG;AACH,wBAAgB,cAAc,IAAI;IAAE,KAAK,EAAE,MAAM,CAAC;IAAC,SAAS,EAAE,MAAM,CAAA;CAAE,GAAG,IAAI,CAS5E;AAED;;GAEG;AACH,wBAAgB,cAAc,IAAI,OAAO,CAExC;AAYD;;;GAGG;AACH,wBAAsB,MAAM,CAAC,YAAY,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,QAAQ,CAAC,CAuE3G;AAED;;GAEG;AACH,wBAAsB,iBAAiB,CAAC,SAAS,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,kBAAkB,CAAC,CAgCtG;AAED;;GAEG;AACH,wBAAsB,OAAO,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,QAAQ,CAAC,CAsBlE;AAED;;;GAGG;AACH,wBAAgB,eAAe,CAAC,IAAI,EAAE,QAAQ,EAAE,oBAAoB,EAAE,MAAM,GAAG,OAAO,CAErF;AAED;;GAEG;AACH,wBAAgB,aAAa,CAAC,SAAS,CAAC,EAAE,MAAM,GAAG,MAAM,CAWxD"}
@@ -0,0 +1,180 @@
1
+ /**
2
+ * Unified API client for groq-backend and stripe-backend
3
+ * SaaS-ready: No CLI-specific code, pure functions with dependency injection
4
+ */
5
+ // Environment variable names
6
+ const ENV_APP_ID = 'QP_APP_ID';
7
+ const ENV_APP_SECRET = 'QP_APP_SECRET';
8
+ const ENV_GROQ_BACKEND = 'QP_GROQ_BACKEND';
9
+ const ENV_STRIPE_BACKEND = 'QP_STRIPE_BACKEND';
10
+ // Default backend URLs
11
+ const DEFAULT_GROQ_BACKEND = 'https://groq-backend.vercel.app';
12
+ const DEFAULT_STRIPE_BACKEND = 'https://sparkstripe.com';
13
+ /**
14
+ * Get API credentials from environment
15
+ */
16
+ export function getCredentials() {
17
+ const appId = process.env[ENV_APP_ID];
18
+ const appSecret = process.env[ENV_APP_SECRET];
19
+ if (!appId || !appSecret) {
20
+ return null;
21
+ }
22
+ return { appId, appSecret };
23
+ }
24
+ /**
25
+ * Check if API credentials are configured
26
+ */
27
+ export function hasCredentials() {
28
+ return getCredentials() !== null;
29
+ }
30
+ /**
31
+ * Get backend URLs from environment or defaults
32
+ */
33
+ function getBackendUrls() {
34
+ return {
35
+ groq: process.env[ENV_GROQ_BACKEND] || DEFAULT_GROQ_BACKEND,
36
+ stripe: process.env[ENV_STRIPE_BACKEND] || DEFAULT_STRIPE_BACKEND,
37
+ };
38
+ }
39
+ /**
40
+ * Call AI via groq-backend proxy
41
+ * Returns structured response with rate limit info
42
+ */
43
+ export async function callAI(systemPrompt, userPrompt, userEmail) {
44
+ const credentials = getCredentials();
45
+ if (!credentials) {
46
+ return {
47
+ success: false,
48
+ error: `Missing API credentials. Set ${ENV_APP_ID} and ${ENV_APP_SECRET} environment variables.`,
49
+ isAuthError: true,
50
+ };
51
+ }
52
+ if (!userEmail) {
53
+ return {
54
+ success: false,
55
+ error: 'User email is required for API access.',
56
+ isAuthError: true,
57
+ };
58
+ }
59
+ const { groq } = getBackendUrls();
60
+ try {
61
+ const response = await fetch(`${groq}/api/chat`, {
62
+ method: 'POST',
63
+ headers: { 'Content-Type': 'application/json' },
64
+ body: JSON.stringify({
65
+ appId: credentials.appId,
66
+ appSecret: credentials.appSecret,
67
+ userEmail,
68
+ model: 'llama-3.3-70b-versatile',
69
+ messages: [
70
+ { role: 'system', content: systemPrompt },
71
+ { role: 'user', content: userPrompt },
72
+ ],
73
+ }),
74
+ });
75
+ const data = await response.json();
76
+ if (!data.success) {
77
+ const error = data.error || 'Unknown API error';
78
+ const isRateLimit = error.toLowerCase().includes('rate limit');
79
+ const isAuthError = error.toLowerCase().includes('invalid') ||
80
+ error.toLowerCase().includes('unknown app') ||
81
+ error.toLowerCase().includes('secret');
82
+ return {
83
+ success: false,
84
+ error,
85
+ isRateLimit,
86
+ isAuthError,
87
+ };
88
+ }
89
+ return {
90
+ success: true,
91
+ content: data.response,
92
+ limits: {
93
+ used: data.limits?.used ?? 0,
94
+ limit: data.limits?.limit ?? 50,
95
+ tier: data.limits?.tier ?? 'free',
96
+ resetAt: data.limits?.resetAt,
97
+ },
98
+ };
99
+ }
100
+ catch (err) {
101
+ const message = err instanceof Error ? err.message : String(err);
102
+ return {
103
+ success: false,
104
+ error: `Network error: ${message}`,
105
+ };
106
+ }
107
+ }
108
+ /**
109
+ * Check subscription status via stripe-backend
110
+ */
111
+ export async function checkSubscription(userEmail, appId) {
112
+ const credentials = getCredentials();
113
+ const effectiveAppId = appId || credentials?.appId;
114
+ if (!effectiveAppId) {
115
+ return { status: null };
116
+ }
117
+ const { stripe } = getBackendUrls();
118
+ try {
119
+ const params = new URLSearchParams({
120
+ email: userEmail,
121
+ app_id: effectiveAppId,
122
+ });
123
+ const response = await fetch(`${stripe}/api/subscription/status-public?${params}`);
124
+ if (!response.ok) {
125
+ return { status: null };
126
+ }
127
+ const data = await response.json();
128
+ const subscription = data.subscription;
129
+ return {
130
+ status: subscription?.status ?? null,
131
+ currentPeriodEnd: subscription?.current_period_end,
132
+ };
133
+ }
134
+ catch {
135
+ return { status: null };
136
+ }
137
+ }
138
+ /**
139
+ * Determine user tier based on subscription status
140
+ */
141
+ export async function getTier(userEmail) {
142
+ const subscription = await checkSubscription(userEmail);
143
+ if (!subscription.status) {
144
+ return 'free';
145
+ }
146
+ // Pro statuses: active subscription, lifetime purchase, or valid trial
147
+ const proStatuses = ['active', 'trialing', 'lifetime'];
148
+ if (proStatuses.includes(subscription.status)) {
149
+ // For trialing, check if still valid
150
+ if (subscription.status === 'trialing' && subscription.currentPeriodEnd) {
151
+ const endDate = new Date(subscription.currentPeriodEnd);
152
+ if (endDate <= new Date()) {
153
+ return 'free';
154
+ }
155
+ }
156
+ return 'pro';
157
+ }
158
+ return 'free';
159
+ }
160
+ /**
161
+ * Check if watermark should be applied
162
+ * Watermark applies to free tier videos longer than 20 seconds
163
+ */
164
+ export function shouldWatermark(tier, videoDurationSeconds) {
165
+ return tier === 'free' && videoDurationSeconds > 20;
166
+ }
167
+ /**
168
+ * Get upgrade URL for pricing page
169
+ */
170
+ export function getUpgradeUrl(userEmail) {
171
+ const credentials = getCredentials();
172
+ const { stripe } = getBackendUrls();
173
+ const appId = credentials?.appId || 'quickpeek';
174
+ let url = `${stripe}/pricing/${appId}`;
175
+ if (userEmail) {
176
+ url += `?email=${encodeURIComponent(userEmail)}`;
177
+ }
178
+ return url;
179
+ }
180
+ //# sourceMappingURL=api-client.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"api-client.js","sourceRoot":"","sources":["../src/api-client.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,69 @@
1
+ /**
2
+ * Configuration types and defaults for QuickPeek
3
+ */
4
+ export declare const VERSION = "1.2.0";
5
+ export declare const CONFIG_FILE = "quickpeek.config.json";
6
+ export type UserTier = 'free' | 'pro';
7
+ export interface UserConfig {
8
+ email?: string;
9
+ tier?: UserTier;
10
+ }
11
+ export interface Config {
12
+ lang?: string;
13
+ user?: UserConfig;
14
+ plan?: {
15
+ maxSteps: number;
16
+ };
17
+ video: {
18
+ width: number;
19
+ height: number;
20
+ format: string;
21
+ preset: 'ultrafast' | 'superfast' | 'veryfast' | 'faster' | 'fast' | 'medium' | 'slow' | 'slower' | 'veryslow';
22
+ quality: number;
23
+ fps: number;
24
+ cursor: boolean;
25
+ highlight: boolean;
26
+ fadeIn: number;
27
+ fadeOut: number;
28
+ transition: 'none' | 'fade';
29
+ contrast: number;
30
+ };
31
+ audio?: {
32
+ voice?: string;
33
+ format: string;
34
+ bitrate: string;
35
+ };
36
+ music?: {
37
+ path: string;
38
+ volume: number;
39
+ fadeIn: number;
40
+ fadeOut: number;
41
+ };
42
+ intro?: {
43
+ enabled: boolean;
44
+ text?: string;
45
+ };
46
+ timing: {
47
+ minStepDuration: number;
48
+ };
49
+ output: {
50
+ dir: string;
51
+ };
52
+ }
53
+ export interface CaptionWordStyle {
54
+ color: string;
55
+ size: number;
56
+ bold: boolean;
57
+ }
58
+ export interface CaptionStyle {
59
+ font: string;
60
+ outline: string;
61
+ outlineWidth: number;
62
+ shadow: number;
63
+ marginBottom: number;
64
+ regular: CaptionWordStyle;
65
+ highlight: CaptionWordStyle;
66
+ }
67
+ export declare const DEFAULT_CONFIG: Config;
68
+ export declare const DEFAULT_CAPTIONS: CaptionStyle;
69
+ //# sourceMappingURL=config.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,eAAO,MAAM,OAAO,UAAU,CAAC;AAC/B,eAAO,MAAM,WAAW,0BAA0B,CAAC;AAEnD,MAAM,MAAM,QAAQ,GAAG,MAAM,GAAG,KAAK,CAAC;AAEtC,MAAM,WAAW,UAAU;IACzB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,IAAI,CAAC,EAAE,QAAQ,CAAC;CACjB;AAED,MAAM,WAAW,MAAM;IACrB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,IAAI,CAAC,EAAE,UAAU,CAAC;IAClB,IAAI,CAAC,EAAE;QACL,QAAQ,EAAE,MAAM,CAAC;KAClB,CAAC;IACF,KAAK,EAAE;QACL,KAAK,EAAE,MAAM,CAAC;QACd,MAAM,EAAE,MAAM,CAAC;QACf,MAAM,EAAE,MAAM,CAAC;QACf,MAAM,EAAE,WAAW,GAAG,WAAW,GAAG,UAAU,GAAG,QAAQ,GAAG,MAAM,GAAG,QAAQ,GAAG,MAAM,GAAG,QAAQ,GAAG,UAAU,CAAC;QAC/G,OAAO,EAAE,MAAM,CAAC;QAChB,GAAG,EAAE,MAAM,CAAC;QACZ,MAAM,EAAE,OAAO,CAAC;QAChB,SAAS,EAAE,OAAO,CAAC;QACnB,MAAM,EAAE,MAAM,CAAC;QACf,OAAO,EAAE,MAAM,CAAC;QAChB,UAAU,EAAE,MAAM,GAAG,MAAM,CAAC;QAC5B,QAAQ,EAAE,MAAM,CAAC;KAClB,CAAC;IACF,KAAK,CAAC,EAAE;QACN,KAAK,CAAC,EAAE,MAAM,CAAC;QACf,MAAM,EAAE,MAAM,CAAC;QACf,OAAO,EAAE,MAAM,CAAC;KACjB,CAAC;IACF,KAAK,CAAC,EAAE;QACN,IAAI,EAAE,MAAM,CAAC;QACb,MAAM,EAAE,MAAM,CAAC;QACf,MAAM,EAAE,MAAM,CAAC;QACf,OAAO,EAAE,MAAM,CAAC;KACjB,CAAC;IACF,KAAK,CAAC,EAAE;QACN,OAAO,EAAE,OAAO,CAAC;QACjB,IAAI,CAAC,EAAE,MAAM,CAAC;KACf,CAAC;IACF,MAAM,EAAE;QACN,eAAe,EAAE,MAAM,CAAC;KACzB,CAAC;IACF,MAAM,EAAE;QACN,GAAG,EAAE,MAAM,CAAC;KACb,CAAC;CACH;AAED,MAAM,WAAW,gBAAgB;IAC/B,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,OAAO,CAAC;CACf;AAED,MAAM,WAAW,YAAY;IAC3B,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;IAChB,YAAY,EAAE,MAAM,CAAC;IACrB,MAAM,EAAE,MAAM,CAAC;IACf,YAAY,EAAE,MAAM,CAAC;IACrB,OAAO,EAAE,gBAAgB,CAAC;IAC1B,SAAS,EAAE,gBAAgB,CAAC;CAC7B;AAED,eAAO,MAAM,cAAc,EAAE,MAmB5B,CAAC;AAEF,eAAO,MAAM,gBAAgB,EAAE,YAgB9B,CAAC"}
package/dist/config.js ADDED
@@ -0,0 +1,43 @@
1
+ /**
2
+ * Configuration types and defaults for QuickPeek
3
+ */
4
+ export const VERSION = '1.2.0';
5
+ export const CONFIG_FILE = 'quickpeek.config.json';
6
+ export const DEFAULT_CONFIG = {
7
+ plan: { maxSteps: 8 },
8
+ video: {
9
+ width: 1080,
10
+ height: 1920,
11
+ format: 'mp4',
12
+ preset: 'fast',
13
+ quality: 0.5,
14
+ fps: 30,
15
+ cursor: true,
16
+ highlight: false,
17
+ fadeIn: 0.3,
18
+ fadeOut: 0.3,
19
+ transition: 'none',
20
+ contrast: 0.25,
21
+ },
22
+ audio: { format: 'mp3', bitrate: '192k' },
23
+ timing: { minStepDuration: 1500 },
24
+ output: { dir: './demo' },
25
+ };
26
+ export const DEFAULT_CAPTIONS = {
27
+ font: 'Arial',
28
+ outline: '#000000',
29
+ outlineWidth: 3,
30
+ shadow: 2,
31
+ marginBottom: 80,
32
+ regular: {
33
+ color: '#FFFFFF',
34
+ size: 56,
35
+ bold: true,
36
+ },
37
+ highlight: {
38
+ color: '#FFFF00',
39
+ size: 64,
40
+ bold: true,
41
+ },
42
+ };
43
+ //# sourceMappingURL=config.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"config.js","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,MAAM,CAAC,MAAM,OAAO,GAAG,OAAO,CAAC;AAC/B,MAAM,CAAC,MAAM,WAAW,GAAG,uBAAuB,CAAC;AAoEnD,MAAM,CAAC,MAAM,cAAc,GAAW;IACpC,IAAI,EAAE,EAAE,QAAQ,EAAE,CAAC,EAAE;IACrB,KAAK,EAAE;QACL,KAAK,EAAE,IAAI;QACX,MAAM,EAAE,IAAI;QACZ,MAAM,EAAE,KAAK;QACb,MAAM,EAAE,MAAM;QACd,OAAO,EAAE,GAAG;QACZ,GAAG,EAAE,EAAE;QACP,MAAM,EAAE,IAAI;QACZ,SAAS,EAAE,KAAK;QAChB,MAAM,EAAE,GAAG;QACX,OAAO,EAAE,GAAG;QACZ,UAAU,EAAE,MAAM;QAClB,QAAQ,EAAE,IAAI;KACf;IACD,KAAK,EAAE,EAAE,MAAM,EAAE,KAAK,EAAE,OAAO,EAAE,MAAM,EAAE;IACzC,MAAM,EAAE,EAAE,eAAe,EAAE,IAAI,EAAE;IACjC,MAAM,EAAE,EAAE,GAAG,EAAE,QAAQ,EAAE;CAC1B,CAAC;AAEF,MAAM,CAAC,MAAM,gBAAgB,GAAiB;IAC5C,IAAI,EAAE,OAAO;IACb,OAAO,EAAE,SAAS;IAClB,YAAY,EAAE,CAAC;IACf,MAAM,EAAE,CAAC;IACT,YAAY,EAAE,EAAE;IAChB,OAAO,EAAE;QACP,KAAK,EAAE,SAAS;QAChB,IAAI,EAAE,EAAE;QACR,IAAI,EAAE,IAAI;KACX;IACD,SAAS,EAAE;QACT,KAAK,EAAE,SAAS;QAChB,IAAI,EAAE,EAAE;QACR,IAAI,EAAE,IAAI;KACX;CACF,CAAC"}
@@ -0,0 +1,18 @@
1
+ /**
2
+ * Page crawling and interactive element extraction
3
+ */
4
+ export interface ElementInfo {
5
+ type: string;
6
+ text: string;
7
+ selector: string;
8
+ }
9
+ /**
10
+ * Crawl a page and extract interactive elements with smart selectors
11
+ */
12
+ export declare function crawlPage(url: string, task: (text: string) => {
13
+ succeed: (text?: string) => void;
14
+ }): Promise<{
15
+ title: string;
16
+ elements: ElementInfo[];
17
+ }>;
18
+ //# sourceMappingURL=crawl.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"crawl.d.ts","sourceRoot":"","sources":["../src/crawl.ts"],"names":[],"mappings":"AAAA;;GAEG;AAIH,MAAM,WAAW,WAAW;IAC1B,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,MAAM,CAAC;CAClB;AAaD;;GAEG;AACH,wBAAsB,SAAS,CAC7B,GAAG,EAAE,MAAM,EACX,IAAI,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK;IAAE,OAAO,EAAE,CAAC,IAAI,CAAC,EAAE,MAAM,KAAK,IAAI,CAAA;CAAE,GAC3D,OAAO,CAAC;IAAE,KAAK,EAAE,MAAM,CAAC;IAAC,QAAQ,EAAE,WAAW,EAAE,CAAA;CAAE,CAAC,CAqKrD"}
package/dist/crawl.js ADDED
@@ -0,0 +1,175 @@
1
+ /**
2
+ * Page crawling and interactive element extraction
3
+ */
4
+ import { chromium } from 'playwright';
5
+ /**
6
+ * Crawl a page and extract interactive elements with smart selectors
7
+ */
8
+ export async function crawlPage(url, task) {
9
+ const browserTask = task('Launching browser');
10
+ const browser = await chromium.launch({ headless: true });
11
+ const page = await browser.newPage();
12
+ browserTask.succeed('Browser launched');
13
+ const crawlTask = task('Crawling page');
14
+ await page.goto(url, { waitUntil: 'networkidle', timeout: 30000 });
15
+ const title = await page.title();
16
+ // Extract raw element data from page (no functions to avoid tsx __name issue)
17
+ const rawElements = (await page.evaluate(`
18
+ (() => {
19
+ const items = [];
20
+
21
+ // Helper to get parent context
22
+ const getCtx = (el) => {
23
+ let p = el.parentElement;
24
+ while (p && p !== document.body) {
25
+ if (p.id) return '#' + p.id;
26
+ const cls = Array.from(p.classList).find(c =>
27
+ /toolbar|header|footer|sidebar|panel|modal|dialog|nav|menu|controls|actions/i.test(c)
28
+ );
29
+ if (cls) return '.' + cls;
30
+ if (['header', 'footer', 'nav', 'main', 'aside', 'form'].includes(p.tagName.toLowerCase())) {
31
+ return p.tagName.toLowerCase();
32
+ }
33
+ p = p.parentElement;
34
+ }
35
+ return '';
36
+ };
37
+
38
+ // Buttons (use textContent to catch hidden elements too)
39
+ document.querySelectorAll('button, [role="button"]').forEach(el => {
40
+ const text = (el.textContent || el.innerText || '').trim().replace(/\\s+/g, ' ').slice(0, 40);
41
+ const testId = el.getAttribute('data-testid');
42
+ const ariaLabel = el.getAttribute('aria-label');
43
+ if (!text && !testId && !ariaLabel) return;
44
+ items.push({ type: 'button', text: text || ariaLabel || testId, testId, ctx: getCtx(el) });
45
+ });
46
+
47
+ // Inputs (including file inputs with labels)
48
+ document.querySelectorAll('input, textarea, select').forEach(el => {
49
+ if (el.type === 'hidden') return;
50
+ const testId = el.getAttribute('data-testid');
51
+ // For file inputs, get label text
52
+ const labelText = el.type === 'file' && el.labels?.[0]
53
+ ? el.labels[0].textContent?.trim()
54
+ : null;
55
+ const text = labelText || el.placeholder || el.name || el.id || '';
56
+ // Include file inputs even without text (they're important)
57
+ if (!text && !testId && el.type !== 'file') return;
58
+ items.push({
59
+ type: el.type || 'input',
60
+ text: text || (el.type === 'file' ? 'file upload' : testId),
61
+ testId,
62
+ id: el.id,
63
+ name: el.name,
64
+ placeholder: el.placeholder,
65
+ isFile: el.type === 'file'
66
+ });
67
+ });
68
+
69
+ // Links (use textContent to catch hidden elements too)
70
+ document.querySelectorAll('a[href]').forEach(el => {
71
+ const text = (el.textContent || el.innerText || '').trim().replace(/\\s+/g, ' ').slice(0, 40);
72
+ if (text && text.length >= 2) items.push({ type: 'link', text });
73
+ });
74
+
75
+ return items.slice(0, 40);
76
+ })()
77
+ `));
78
+ // Filter out navigation, account, and footer links that shouldn't be in demos
79
+ const SKIP_PATTERNS = [
80
+ // Navigation
81
+ /^home$/i,
82
+ /^about$/i,
83
+ /^about us$/i,
84
+ /^contact$/i,
85
+ /^contact us$/i,
86
+ /^help$/i,
87
+ /^support$/i,
88
+ /^faq$/i,
89
+ /^docs$/i,
90
+ /^documentation$/i,
91
+ // Account
92
+ /^log ?in$/i,
93
+ /^sign ?in$/i,
94
+ /^sign ?up$/i,
95
+ /^register$/i,
96
+ /^my ?account$/i,
97
+ /^profile$/i,
98
+ /^settings$/i,
99
+ /^log ?out$/i,
100
+ /^sign ?out$/i,
101
+ // Business
102
+ /^pricing$/i,
103
+ /^plans$/i,
104
+ /^subscribe$/i,
105
+ /^upgrade$/i,
106
+ /^buy$/i,
107
+ /^purchase$/i,
108
+ // Footer
109
+ /^privacy$/i,
110
+ /^terms$/i,
111
+ /^legal$/i,
112
+ /^blog$/i,
113
+ /^careers$/i,
114
+ /^jobs$/i,
115
+ /^twitter$/i,
116
+ /^facebook$/i,
117
+ /^linkedin$/i,
118
+ /^instagram$/i,
119
+ /^github$/i,
120
+ /^cookie/i,
121
+ /^gdpr$/i,
122
+ ];
123
+ const filteredElements = rawElements.filter((el) => {
124
+ if (!el.text)
125
+ return true; // Keep elements without text (like file inputs)
126
+ const text = el.text.toLowerCase().trim();
127
+ // Skip if matches any skip pattern
128
+ return !SKIP_PATTERNS.some((pattern) => pattern.test(text));
129
+ });
130
+ // Build smart selectors in Node.js (avoids tsx transpilation issues)
131
+ const btnTexts = {};
132
+ for (const el of filteredElements) {
133
+ if (el.type === 'button' && el.text) {
134
+ btnTexts[el.text] = (btnTexts[el.text] || 0) + 1;
135
+ }
136
+ }
137
+ const elements = filteredElements.map((el) => {
138
+ let selector;
139
+ if (el.testId) {
140
+ selector = `[data-testid="${el.testId}"]`;
141
+ }
142
+ else if (el.isFile || el.type === 'file') {
143
+ // File inputs always use type selector
144
+ selector = 'input[type="file"]';
145
+ }
146
+ else if (el.type === 'button') {
147
+ if (btnTexts[el.text] === 1) {
148
+ selector = `text="${el.text}"`;
149
+ }
150
+ else {
151
+ selector = el.ctx ? `${el.ctx} >> text="${el.text}"` : `button:has-text("${el.text}")`;
152
+ }
153
+ }
154
+ else if (el.type === 'link') {
155
+ selector = `text="${el.text}"`;
156
+ }
157
+ else if (el.id) {
158
+ selector = `#${el.id}`;
159
+ }
160
+ else if (el.name) {
161
+ selector = `[name="${el.name}"]`;
162
+ }
163
+ else if (el.placeholder) {
164
+ selector = `[placeholder="${el.placeholder}"]`;
165
+ }
166
+ else {
167
+ selector = `text="${el.text}"`;
168
+ }
169
+ return { type: el.type, text: el.text, selector };
170
+ });
171
+ await browser.close();
172
+ crawlTask.succeed(`Found ${elements.length} interactive elements`);
173
+ return { title, elements };
174
+ }
175
+ //# sourceMappingURL=crawl.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"crawl.js","sourceRoot":"","sources":["../src/crawl.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,6 @@
1
+ /**
2
+ * Cursor PNG as base64 data URI for browser injection
3
+ * Source: src/imgs/cursor.png
4
+ */
5
+ export declare const CURSOR_PNG = "data:image/png;base64,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";
6
+ //# sourceMappingURL=cursor.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cursor.d.ts","sourceRoot":"","sources":["../src/cursor.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,eAAO,MAAM,UAAU,+gFACu/E,CAAC"}
package/dist/cursor.js ADDED
@@ -0,0 +1,6 @@
1
+ /**
2
+ * Cursor PNG as base64 data URI for browser injection
3
+ * Source: src/imgs/cursor.png
4
+ */
5
+ export const CURSOR_PNG = 'data:image/png;base64,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';
6
+ //# sourceMappingURL=cursor.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cursor.js","sourceRoot":"","sources":["../src/cursor.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,MAAM,CAAC,MAAM,UAAU,GACrB,4gFAA4gF,CAAC"}
@@ -0,0 +1,50 @@
1
+ import type { UserTier } from './config.js';
2
+ /**
3
+ * Run ffprobe to get media duration in milliseconds
4
+ */
5
+ export declare function getMediaDuration(filePath: string): Promise<number>;
6
+ /**
7
+ * Concatenate audio files using ffmpeg concat demuxer
8
+ */
9
+ export declare function concatMedia(listPath: string, output: string): Promise<void>;
10
+ export interface ComposeOptions {
11
+ videoPath: string;
12
+ assPath: string;
13
+ outputPath: string;
14
+ voiceoverPath?: string | undefined;
15
+ musicPath?: string | undefined;
16
+ musicVolume?: number | undefined;
17
+ musicFadeIn?: number | undefined;
18
+ musicFadeOut?: number | undefined;
19
+ width: number;
20
+ height: number;
21
+ fps: number;
22
+ preset: string;
23
+ quality: number;
24
+ fadeIn: number;
25
+ fadeOut: number;
26
+ videoDuration: number;
27
+ audioBitrate?: string | undefined;
28
+ contrast?: number | undefined;
29
+ trimStart?: number | undefined;
30
+ userTier?: UserTier | undefined;
31
+ }
32
+ /**
33
+ * Compose final video with subtitles, voiceover, and music
34
+ */
35
+ export declare function composeVideo(opts: ComposeOptions): Promise<void>;
36
+ /**
37
+ * Generate silence audio file of specified duration
38
+ */
39
+ export declare function generateSilence(outputPath: string, durationMs: number): Promise<void>;
40
+ export interface SpeedUpOptions {
41
+ inputPath: string;
42
+ outputPath: string;
43
+ factor: number;
44
+ preset: string;
45
+ }
46
+ /**
47
+ * Speed up video by a factor
48
+ */
49
+ export declare function speedUpVideo(opts: SpeedUpOptions): Promise<void>;
50
+ //# sourceMappingURL=ffmpeg.d.ts.map