@skhema/cli 0.4.8 → 0.5.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/README.md +23 -0
- package/dist/commands/contribute.d.ts.map +1 -1
- package/dist/commands/contribute.js +188 -2
- package/dist/lib/contribute/api.d.ts +14 -0
- package/dist/lib/contribute/api.d.ts.map +1 -0
- package/dist/lib/contribute/api.js +36 -0
- package/dist/lib/contribute/embed-generator.d.ts +1 -0
- package/dist/lib/contribute/embed-generator.d.ts.map +1 -1
- package/dist/lib/contribute/embed-generator.js +6 -1
- package/dist/lib/contribute/types.d.ts +74 -0
- package/dist/lib/contribute/types.d.ts.map +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -160,6 +160,29 @@ skhema workspace use --clear
|
|
|
160
160
|
|
|
161
161
|
Later workspace-scoped commands read this default when `--workspace` is omitted.
|
|
162
162
|
|
|
163
|
+
## Contributor commands
|
|
164
|
+
|
|
165
|
+
Approved contributors get a `contribute` command group for generating embeds and
|
|
166
|
+
shareable links, and for inspecting their account, analytics, and payouts. Every
|
|
167
|
+
command is gated on approved-contributor status and honours `--json`.
|
|
168
|
+
|
|
169
|
+
```sh
|
|
170
|
+
skhema contribute generate embed --element-type key_challenge \
|
|
171
|
+
--content "..." --contributor-id contrib_… # HTML <skhema-element> snippet
|
|
172
|
+
skhema contribute generate link --element-type key_challenge \
|
|
173
|
+
--content "..." --contributor-id contrib_… # save + share links
|
|
174
|
+
|
|
175
|
+
skhema contribute status # approval status, ID, display name
|
|
176
|
+
skhema contribute profile # public profile (edit at contribute.skhema.com/account)
|
|
177
|
+
skhema contribute analytics --time-range 30d # embeds, loads, clicks, CTR + top content
|
|
178
|
+
skhema contribute analytics --content-hash <hash> # per-content detail with top pages
|
|
179
|
+
skhema contribute payouts # payout history (20% commission, 60-day hold)
|
|
180
|
+
```
|
|
181
|
+
|
|
182
|
+
Generated embed snippets pin the CDN to a specific `@skhema/embed` version
|
|
183
|
+
(`https://unpkg.com/@skhema/embed@<version>/dist/embed.min.js`), so a published
|
|
184
|
+
snippet renders identically forever rather than tracking `latest`.
|
|
185
|
+
|
|
163
186
|
## Configuration & storage
|
|
164
187
|
|
|
165
188
|
| What | Where |
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"contribute.d.ts","sourceRoot":"","sources":["../../src/commands/contribute.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAA;
|
|
1
|
+
{"version":3,"file":"contribute.d.ts","sourceRoot":"","sources":["../../src/commands/contribute.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAA;AA0HnC,wBAAgB,0BAA0B,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI,CAskBjE"}
|
|
@@ -2,10 +2,11 @@ import fs from 'node:fs';
|
|
|
2
2
|
import ora from 'ora';
|
|
3
3
|
import { isApprovedContributor } from '../lib/auth/entitlements.js';
|
|
4
4
|
import { getStoredCredentials } from '../lib/auth/token-store.js';
|
|
5
|
+
import { postContributeFunction } from '../lib/contribute/api.js';
|
|
5
6
|
import { resolveComponentAuthor, resolveElementAuthor, } from '../lib/contribute/author-resolver.js';
|
|
6
7
|
import { generateComponentEmbed, generateEmbed, } from '../lib/contribute/embed-generator.js';
|
|
7
8
|
import { generateSaveComponentLink, generateSaveElementLink, publishAndGenerateComponentShareLink, publishAndGenerateElementShareLink, } from '../lib/contribute/link-generator.js';
|
|
8
|
-
import { getGlobalOptions, log, outputError, outputSuccess, } from '../lib/output.js';
|
|
9
|
+
import { getGlobalOptions, log, logHeader, logTable, outputError, outputSuccess, } from '../lib/output.js';
|
|
9
10
|
function parseElementArgs(elementArgs) {
|
|
10
11
|
return elementArgs.map((arg) => {
|
|
11
12
|
const colonIndex = arg.indexOf(':');
|
|
@@ -45,10 +46,30 @@ async function requireContributor() {
|
|
|
45
46
|
process.exit(1);
|
|
46
47
|
}
|
|
47
48
|
}
|
|
49
|
+
const ANALYTICS_TIME_RANGES = ['24h', '7d', '30d', '90d'];
|
|
50
|
+
function truncate(text, max = 42) {
|
|
51
|
+
const clean = text.replace(/\s+/g, ' ').trim();
|
|
52
|
+
return clean.length > max ? `${clean.slice(0, max - 1)}…` : clean;
|
|
53
|
+
}
|
|
54
|
+
function formatDate(iso) {
|
|
55
|
+
const date = new Date(iso);
|
|
56
|
+
return Number.isNaN(date.getTime()) ? iso : date.toISOString().slice(0, 10);
|
|
57
|
+
}
|
|
58
|
+
// payoutAmount is stored in minor units (cents) — the backend computes it as
|
|
59
|
+
// Math.round(subtotalCents * 20 / 100). Render as a major-unit decimal.
|
|
60
|
+
function formatAmount(amountCents, currency) {
|
|
61
|
+
if (amountCents === null)
|
|
62
|
+
return '—';
|
|
63
|
+
const amount = (amountCents / 100).toFixed(2);
|
|
64
|
+
return currency ? `${amount} ${currency.toUpperCase()}` : amount;
|
|
65
|
+
}
|
|
66
|
+
function isDetailAnalytics(data) {
|
|
67
|
+
return 'pages' in data;
|
|
68
|
+
}
|
|
48
69
|
export function registerContributeCommands(program) {
|
|
49
70
|
const contribute = program
|
|
50
71
|
.command('contribute')
|
|
51
|
-
.description('Contributor tools — requires approved contributor status')
|
|
72
|
+
.description('Contributor tools — embeds, links, status, profile, analytics, and payouts (requires approved contributor status)')
|
|
52
73
|
.hook('preAction', requireContributor);
|
|
53
74
|
const generate = contribute
|
|
54
75
|
.command('generate')
|
|
@@ -315,4 +336,169 @@ export function registerContributeCommands(program) {
|
|
|
315
336
|
process.exit(1);
|
|
316
337
|
}
|
|
317
338
|
});
|
|
339
|
+
contribute
|
|
340
|
+
.command('status')
|
|
341
|
+
.description('Show your contributor approval status, ID, and display name')
|
|
342
|
+
.action(async () => {
|
|
343
|
+
const opts = getGlobalOptions();
|
|
344
|
+
const spinner = opts.json || opts.quiet
|
|
345
|
+
? null
|
|
346
|
+
: ora('Fetching contributor status...').start();
|
|
347
|
+
try {
|
|
348
|
+
const status = await postContributeFunction('contributor-manage', { action: 'check-status' });
|
|
349
|
+
const profile = await postContributeFunction('contributor-manage', { action: 'get-profile' });
|
|
350
|
+
spinner?.stop();
|
|
351
|
+
if (getGlobalOptions().json) {
|
|
352
|
+
outputSuccess({ status, profile }, 'contribute status');
|
|
353
|
+
}
|
|
354
|
+
else {
|
|
355
|
+
const approval = status.approved
|
|
356
|
+
? 'Approved contributor'
|
|
357
|
+
: status.isContributor
|
|
358
|
+
? 'Pending approval'
|
|
359
|
+
: 'Not a contributor';
|
|
360
|
+
log(`Status: ${approval}`);
|
|
361
|
+
log(`Contributor ID: ${status.contributorId ?? profile.contributorId ?? '—'}`);
|
|
362
|
+
log(`Display name: ${profile.resolvedDisplayName}`);
|
|
363
|
+
}
|
|
364
|
+
}
|
|
365
|
+
catch (error) {
|
|
366
|
+
spinner?.stop();
|
|
367
|
+
outputError(error instanceof Error ? error.message : 'Failed to fetch status', 'contribute status');
|
|
368
|
+
process.exit(1);
|
|
369
|
+
}
|
|
370
|
+
});
|
|
371
|
+
contribute
|
|
372
|
+
.command('profile')
|
|
373
|
+
.description('Show your public contributor profile (read-only)')
|
|
374
|
+
.action(async () => {
|
|
375
|
+
const opts = getGlobalOptions();
|
|
376
|
+
const spinner = opts.json || opts.quiet ? null : ora('Fetching profile...').start();
|
|
377
|
+
try {
|
|
378
|
+
const profile = await postContributeFunction('contributor-manage', { action: 'get-profile' });
|
|
379
|
+
spinner?.stop();
|
|
380
|
+
if (getGlobalOptions().json) {
|
|
381
|
+
outputSuccess(profile, 'contribute profile');
|
|
382
|
+
}
|
|
383
|
+
else {
|
|
384
|
+
log(`Contributor ID: ${profile.contributorId}`);
|
|
385
|
+
log(`Display name: ${profile.resolvedDisplayName}`);
|
|
386
|
+
log(`Name preference: ${profile.displayNamePreference}`);
|
|
387
|
+
log(`Custom name: ${profile.displayName ?? '—'}`);
|
|
388
|
+
log(`Bio: ${profile.bio ?? '—'}`);
|
|
389
|
+
log(`Website: ${profile.publicWebsiteUrl ?? '—'}`);
|
|
390
|
+
log('');
|
|
391
|
+
log('Edit your profile at https://contribute.skhema.com/account');
|
|
392
|
+
}
|
|
393
|
+
}
|
|
394
|
+
catch (error) {
|
|
395
|
+
spinner?.stop();
|
|
396
|
+
outputError(error instanceof Error ? error.message : 'Failed to fetch profile', 'contribute profile');
|
|
397
|
+
process.exit(1);
|
|
398
|
+
}
|
|
399
|
+
});
|
|
400
|
+
contribute
|
|
401
|
+
.command('analytics')
|
|
402
|
+
.description('Show embed analytics for your contributed content')
|
|
403
|
+
.option('--time-range <range>', `Time range: ${ANALYTICS_TIME_RANGES.join(', ')}`, '30d')
|
|
404
|
+
.option('--content-hash <hash>', 'Show per-content detail for a single content hash')
|
|
405
|
+
.action(async (options) => {
|
|
406
|
+
const timeRange = options.timeRange;
|
|
407
|
+
if (!ANALYTICS_TIME_RANGES.includes(timeRange)) {
|
|
408
|
+
outputError(`Invalid --time-range "${timeRange}". Valid values: ${ANALYTICS_TIME_RANGES.join(', ')}`, 'contribute analytics');
|
|
409
|
+
process.exit(1);
|
|
410
|
+
}
|
|
411
|
+
const opts = getGlobalOptions();
|
|
412
|
+
const spinner = opts.json || opts.quiet ? null : ora('Fetching analytics...').start();
|
|
413
|
+
try {
|
|
414
|
+
const data = await postContributeFunction('embed-manage', {
|
|
415
|
+
action: 'get-analytics',
|
|
416
|
+
time_range: timeRange,
|
|
417
|
+
...(options.contentHash ? { content_hash: options.contentHash } : {}),
|
|
418
|
+
});
|
|
419
|
+
spinner?.stop();
|
|
420
|
+
if (getGlobalOptions().json) {
|
|
421
|
+
outputSuccess(data, 'contribute analytics');
|
|
422
|
+
return;
|
|
423
|
+
}
|
|
424
|
+
const { summary } = data;
|
|
425
|
+
const totals = [
|
|
426
|
+
['Embeds', String(summary.total_embeds)],
|
|
427
|
+
['Loads', String(summary.total_loads)],
|
|
428
|
+
['Clicks', String(summary.total_clicks)],
|
|
429
|
+
['CTR', summary.click_through_rate],
|
|
430
|
+
];
|
|
431
|
+
if (isDetailAnalytics(data)) {
|
|
432
|
+
logHeader(`Analytics — ${data.summary.content_hash} (last ${timeRange})`);
|
|
433
|
+
log(truncate(data.summary.content, 72));
|
|
434
|
+
log('');
|
|
435
|
+
logTable(['Metric', 'Value'], totals);
|
|
436
|
+
if (data.pages.length > 0) {
|
|
437
|
+
log('');
|
|
438
|
+
logHeader('Top pages');
|
|
439
|
+
logTable(['Page', 'Loads', 'Clicks'], data.pages
|
|
440
|
+
.slice(0, 10)
|
|
441
|
+
.map((p) => [
|
|
442
|
+
truncate(p.pageTitle || p.pageUrl),
|
|
443
|
+
String(p.loads),
|
|
444
|
+
String(p.clicks),
|
|
445
|
+
]));
|
|
446
|
+
}
|
|
447
|
+
}
|
|
448
|
+
else {
|
|
449
|
+
logHeader(`Analytics — all content (last ${timeRange})`);
|
|
450
|
+
logTable(['Metric', 'Value'], totals);
|
|
451
|
+
const topContent = data.performance?.top_performing_content ?? [];
|
|
452
|
+
if (topContent.length > 0) {
|
|
453
|
+
log('');
|
|
454
|
+
logHeader('Top content');
|
|
455
|
+
logTable(['Content', 'Loads', 'Clicks', 'CTR'], topContent
|
|
456
|
+
.slice(0, 10)
|
|
457
|
+
.map((c) => [
|
|
458
|
+
truncate(c.content),
|
|
459
|
+
String(c.loads),
|
|
460
|
+
String(c.clicks),
|
|
461
|
+
c.ctr,
|
|
462
|
+
]));
|
|
463
|
+
}
|
|
464
|
+
}
|
|
465
|
+
}
|
|
466
|
+
catch (error) {
|
|
467
|
+
spinner?.stop();
|
|
468
|
+
outputError(error instanceof Error ? error.message : 'Failed to fetch analytics', 'contribute analytics');
|
|
469
|
+
process.exit(1);
|
|
470
|
+
}
|
|
471
|
+
});
|
|
472
|
+
contribute
|
|
473
|
+
.command('payouts')
|
|
474
|
+
.description('List your contributor payouts')
|
|
475
|
+
.action(async () => {
|
|
476
|
+
const opts = getGlobalOptions();
|
|
477
|
+
const spinner = opts.json || opts.quiet ? null : ora('Fetching payouts...').start();
|
|
478
|
+
try {
|
|
479
|
+
const data = await postContributeFunction('contributor-payout', { action: 'list-payouts' });
|
|
480
|
+
spinner?.stop();
|
|
481
|
+
if (getGlobalOptions().json) {
|
|
482
|
+
outputSuccess(data, 'contribute payouts');
|
|
483
|
+
return;
|
|
484
|
+
}
|
|
485
|
+
const payouts = data.payouts ?? [];
|
|
486
|
+
if (payouts.length === 0) {
|
|
487
|
+
log('No payouts yet.');
|
|
488
|
+
return;
|
|
489
|
+
}
|
|
490
|
+
logTable(['Created', 'Amount', 'Status'], payouts.map((p) => [
|
|
491
|
+
formatDate(p.createdAt),
|
|
492
|
+
formatAmount(p.payoutAmount, p.payoutCurrency),
|
|
493
|
+
p.payoutStatus,
|
|
494
|
+
]));
|
|
495
|
+
log('');
|
|
496
|
+
log('20% commission, 60-day holding window');
|
|
497
|
+
}
|
|
498
|
+
catch (error) {
|
|
499
|
+
spinner?.stop();
|
|
500
|
+
outputError(error instanceof Error ? error.message : 'Failed to fetch payouts', 'contribute payouts');
|
|
501
|
+
process.exit(1);
|
|
502
|
+
}
|
|
503
|
+
});
|
|
318
504
|
}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
/** Supabase edge functions the contributor commands talk to. */
|
|
2
|
+
export type ContributeEdgeFunction = 'contributor-manage' | 'embed-manage' | 'contributor-payout';
|
|
3
|
+
/**
|
|
4
|
+
* POST a JSON action to a Supabase edge function with the stored OAuth session.
|
|
5
|
+
* Shared by every authenticated `contribute` subcommand so the auth headers,
|
|
6
|
+
* base URL, and error mapping live in exactly one place.
|
|
7
|
+
*
|
|
8
|
+
* Resolves the access token itself: the `contribute` group's requireContributor
|
|
9
|
+
* preAction already guarantees an approved session, so callers never plumb a
|
|
10
|
+
* token through. Throws a clear Error on missing auth or a non-2xx response,
|
|
11
|
+
* which the command wraps with outputError + a non-zero exit.
|
|
12
|
+
*/
|
|
13
|
+
export declare function postContributeFunction<T>(fn: ContributeEdgeFunction, body: Record<string, unknown>): Promise<T>;
|
|
14
|
+
//# sourceMappingURL=api.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"api.d.ts","sourceRoot":"","sources":["../../../src/lib/contribute/api.ts"],"names":[],"mappings":"AAGA,gEAAgE;AAChE,MAAM,MAAM,sBAAsB,GAC9B,oBAAoB,GACpB,cAAc,GACd,oBAAoB,CAAA;AAExB;;;;;;;;;GASG;AACH,wBAAsB,sBAAsB,CAAC,CAAC,EAC5C,EAAE,EAAE,sBAAsB,EAC1B,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAC5B,OAAO,CAAC,CAAC,CAAC,CA+BZ"}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import { getStoredCredentials } from '../auth/token-store.js';
|
|
2
|
+
import { SUPABASE_PUBLISHABLE_KEY, SUPABASE_URL } from '../config.js';
|
|
3
|
+
/**
|
|
4
|
+
* POST a JSON action to a Supabase edge function with the stored OAuth session.
|
|
5
|
+
* Shared by every authenticated `contribute` subcommand so the auth headers,
|
|
6
|
+
* base URL, and error mapping live in exactly one place.
|
|
7
|
+
*
|
|
8
|
+
* Resolves the access token itself: the `contribute` group's requireContributor
|
|
9
|
+
* preAction already guarantees an approved session, so callers never plumb a
|
|
10
|
+
* token through. Throws a clear Error on missing auth or a non-2xx response,
|
|
11
|
+
* which the command wraps with outputError + a non-zero exit.
|
|
12
|
+
*/
|
|
13
|
+
export async function postContributeFunction(fn, body) {
|
|
14
|
+
const credentials = await getStoredCredentials();
|
|
15
|
+
if (!credentials?.access_token) {
|
|
16
|
+
throw new Error('Authentication required. Run "skhema auth login" first.');
|
|
17
|
+
}
|
|
18
|
+
const response = await fetch(`${SUPABASE_URL}/functions/v1/${fn}`, {
|
|
19
|
+
method: 'POST',
|
|
20
|
+
headers: {
|
|
21
|
+
'Content-Type': 'application/json',
|
|
22
|
+
Authorization: `Bearer ${credentials.access_token}`,
|
|
23
|
+
apikey: SUPABASE_PUBLISHABLE_KEY,
|
|
24
|
+
},
|
|
25
|
+
body: JSON.stringify(body),
|
|
26
|
+
});
|
|
27
|
+
if (!response.ok) {
|
|
28
|
+
// Supabase edge functions and the gateway return `{ message }`, while some
|
|
29
|
+
// handlers return `{ error }` — accept either before the generic fallback.
|
|
30
|
+
const detail = (await response.json().catch(() => ({})));
|
|
31
|
+
throw new Error(detail.error ||
|
|
32
|
+
detail.message ||
|
|
33
|
+
`Request to ${fn} failed: ${response.status}`);
|
|
34
|
+
}
|
|
35
|
+
return (await response.json());
|
|
36
|
+
}
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import type { GenerateComponentEmbedOptions, GenerateComponentEmbedResult, GenerateEmbedOptions, GenerateEmbedResult } from './types.js';
|
|
2
|
+
export declare const EMBED_CDN_VERSION = "0.1.13";
|
|
2
3
|
export declare function generateEmbed(options: GenerateEmbedOptions): GenerateEmbedResult;
|
|
3
4
|
export declare function generateComponentEmbed(options: GenerateComponentEmbedOptions): GenerateComponentEmbedResult;
|
|
4
5
|
//# sourceMappingURL=embed-generator.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"embed-generator.d.ts","sourceRoot":"","sources":["../../../src/lib/contribute/embed-generator.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EACV,6BAA6B,EAC7B,4BAA4B,EAC5B,oBAAoB,EACpB,mBAAmB,EACpB,MAAM,YAAY,CAAA;
|
|
1
|
+
{"version":3,"file":"embed-generator.d.ts","sourceRoot":"","sources":["../../../src/lib/contribute/embed-generator.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EACV,6BAA6B,EAC7B,4BAA4B,EAC5B,oBAAoB,EACpB,mBAAmB,EACpB,MAAM,YAAY,CAAA;AAMnB,eAAO,MAAM,iBAAiB,WAAW,CAAA;AAGzC,wBAAgB,aAAa,CAC3B,OAAO,EAAE,oBAAoB,GAC5B,mBAAmB,CA8DrB;AAED,wBAAgB,sBAAsB,CACpC,OAAO,EAAE,6BAA6B,GACrC,4BAA4B,CA0G9B"}
|
|
@@ -1,5 +1,10 @@
|
|
|
1
1
|
import { COMPONENT_TYPES, ELEMENT_TYPES, SKHEMA_MAPPING, } from '@skhema/method/vocabulary';
|
|
2
|
-
|
|
2
|
+
// Pin the CDN snippet to a published @skhema/embed version. Unversioned unpkg
|
|
3
|
+
// URLs resolve to "latest", so an unversioned snippet silently changes behaviour
|
|
4
|
+
// on every embed publish — a generated snippet must render the same way forever.
|
|
5
|
+
// Bump this in lockstep with @skhema/embed releases.
|
|
6
|
+
export const EMBED_CDN_VERSION = '0.1.13';
|
|
7
|
+
const CDN_URL = `https://unpkg.com/@skhema/embed@${EMBED_CDN_VERSION}/dist/embed.min.js`;
|
|
3
8
|
export function generateEmbed(options) {
|
|
4
9
|
const { elementType, contributorId, authorName, authorSlug, content, theme, trackAnalytics, sourceUrl, } = options;
|
|
5
10
|
if (!contributorId?.trim()) {
|
|
@@ -88,4 +88,78 @@ export interface PublishComponentShareLinkResult {
|
|
|
88
88
|
shareUrl: string;
|
|
89
89
|
componentId: string;
|
|
90
90
|
}
|
|
91
|
+
/** contributor-manage `check-status` */
|
|
92
|
+
export interface ContributorStatusResponse {
|
|
93
|
+
isContributor: boolean;
|
|
94
|
+
approved: boolean;
|
|
95
|
+
contributorId: string | null;
|
|
96
|
+
}
|
|
97
|
+
/** contributor-manage `get-profile` */
|
|
98
|
+
export interface ContributorProfileResponse {
|
|
99
|
+
contributorId: string;
|
|
100
|
+
displayName: string | null;
|
|
101
|
+
displayNamePreference: 'personal' | 'organization';
|
|
102
|
+
bio: string | null;
|
|
103
|
+
avatarUrl: string | null;
|
|
104
|
+
publicWebsiteUrl: string | null;
|
|
105
|
+
resolvedDisplayName: string;
|
|
106
|
+
userName: string | null;
|
|
107
|
+
organizationName: string | null;
|
|
108
|
+
}
|
|
109
|
+
/** embed-manage `get-analytics` (no content hash — the roll-up view) */
|
|
110
|
+
export interface ContributorAnalyticsResponse {
|
|
111
|
+
summary: {
|
|
112
|
+
total_embeds: number;
|
|
113
|
+
total_loads: number;
|
|
114
|
+
total_clicks: number;
|
|
115
|
+
click_through_rate: string;
|
|
116
|
+
};
|
|
117
|
+
performance: {
|
|
118
|
+
top_performing_content: Array<{
|
|
119
|
+
content: string;
|
|
120
|
+
clicks: number;
|
|
121
|
+
loads: number;
|
|
122
|
+
ctr: string;
|
|
123
|
+
content_hash: string;
|
|
124
|
+
element_type: string;
|
|
125
|
+
}>;
|
|
126
|
+
traffic_sources: Array<{
|
|
127
|
+
domain: string;
|
|
128
|
+
loads: number;
|
|
129
|
+
clicks: number;
|
|
130
|
+
percentage: number;
|
|
131
|
+
}>;
|
|
132
|
+
};
|
|
133
|
+
}
|
|
134
|
+
/** embed-manage `get-analytics` (with content hash — the per-content detail) */
|
|
135
|
+
export interface DetailAnalyticsResponse {
|
|
136
|
+
summary: {
|
|
137
|
+
total_embeds: number;
|
|
138
|
+
total_loads: number;
|
|
139
|
+
total_clicks: number;
|
|
140
|
+
click_through_rate: string;
|
|
141
|
+
content_hash: string;
|
|
142
|
+
element_type: string;
|
|
143
|
+
content: string;
|
|
144
|
+
};
|
|
145
|
+
pages: Array<{
|
|
146
|
+
pageUrl: string;
|
|
147
|
+
pageTitle: string;
|
|
148
|
+
loads: number;
|
|
149
|
+
clicks: number;
|
|
150
|
+
}>;
|
|
151
|
+
}
|
|
152
|
+
/** contributor-payout `list-payouts` */
|
|
153
|
+
export interface PayoutRecord {
|
|
154
|
+
id: string;
|
|
155
|
+
createdAt: string;
|
|
156
|
+
approvalStatus: string;
|
|
157
|
+
payoutStatus: string;
|
|
158
|
+
payoutCurrency: string | null;
|
|
159
|
+
payoutAmount: number | null;
|
|
160
|
+
notes: string | null;
|
|
161
|
+
}
|
|
162
|
+
export interface PayoutListResponse {
|
|
163
|
+
payouts: PayoutRecord[];
|
|
164
|
+
}
|
|
91
165
|
//# sourceMappingURL=types.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../src/lib/contribute/types.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../src/lib/contribute/types.ts"],"names":[],"mappings":"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"}
|