@skhema/cli 0.4.7 → 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/component.d.ts.map +1 -1
- package/dist/commands/component.js +2 -1
- package/dist/commands/contribute.d.ts.map +1 -1
- package/dist/commands/contribute.js +188 -2
- package/dist/commands/element.d.ts.map +1 -1
- package/dist/commands/element.js +2 -0
- 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 +2 -2
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":"component.d.ts","sourceRoot":"","sources":["../../src/commands/component.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAA;
|
|
1
|
+
{"version":3,"file":"component.d.ts","sourceRoot":"","sources":["../../src/commands/component.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAA;AAoEnC,wBAAgB,yBAAyB,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI,CAkKhE"}
|
|
@@ -17,11 +17,12 @@ function renderComponents(components = []) {
|
|
|
17
17
|
return;
|
|
18
18
|
}
|
|
19
19
|
logHeader(`Components (${components.length})`);
|
|
20
|
-
logTable(['id', 'name', 'type', 'pos'], components.map((c) => [
|
|
20
|
+
logTable(['id', 'name', 'type', 'pos', 'elements'], components.map((c) => [
|
|
21
21
|
c.id,
|
|
22
22
|
c.name ?? '',
|
|
23
23
|
c.componentType ?? '',
|
|
24
24
|
c.position === undefined ? '' : String(c.position),
|
|
25
|
+
c.elementCount === undefined ? '' : String(c.elementCount),
|
|
25
26
|
]));
|
|
26
27
|
}
|
|
27
28
|
function renderComponentLinks(links = []) {
|
|
@@ -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
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"element.d.ts","sourceRoot":"","sources":["../../src/commands/element.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAA;AAkBnC;;;GAGG;AACH,wBAAgB,uBAAuB,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI,
|
|
1
|
+
{"version":3,"file":"element.d.ts","sourceRoot":"","sources":["../../src/commands/element.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAA;AAkBnC;;;GAGG;AACH,wBAAgB,uBAAuB,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI,CA8S9D"}
|
package/dist/commands/element.js
CHANGED
|
@@ -99,6 +99,7 @@ export function registerElementCommands(program) {
|
|
|
99
99
|
.description('Create an element')
|
|
100
100
|
.option('--content <content>', 'Element content')
|
|
101
101
|
.option('--component-type <type>', 'Component type')
|
|
102
|
+
.option('--component-id <id>', 'Target component instance (find ids with `skhema component list`); omitted, the element lands in the first instance of the type by position (auto-created if none exists)')
|
|
102
103
|
.option('--element-type <type>', 'Element type')
|
|
103
104
|
.option('--file <path>', 'JSON payload file for the full body ("-" for stdin)')).action(async (options) => {
|
|
104
105
|
await runCommand('element create', async () => {
|
|
@@ -106,6 +107,7 @@ export function registerElementCommands(program) {
|
|
|
106
107
|
const body = buildBody(readPayloadFile(options.file), {
|
|
107
108
|
content: options.content,
|
|
108
109
|
componentType: options.componentType,
|
|
110
|
+
componentId: options.componentId,
|
|
109
111
|
elementType: options.elementType,
|
|
110
112
|
});
|
|
111
113
|
if (Object.keys(body).length === 0) {
|
|
@@ -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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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@skhema/cli",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.5.0",
|
|
4
4
|
"description": "Skhema CLI - Authentication and AI skills management for agent platforms",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/index.js",
|
|
@@ -43,7 +43,7 @@
|
|
|
43
43
|
"dependencies": {
|
|
44
44
|
"@skhema/agent-sdk": "0.1.4",
|
|
45
45
|
"@skhema/method": "0.3.0",
|
|
46
|
-
"@skhema/sdk": "0.2.
|
|
46
|
+
"@skhema/sdk": "0.2.4",
|
|
47
47
|
"chalk": "^5.3.0",
|
|
48
48
|
"commander": "^12.0.0",
|
|
49
49
|
"ora": "^8.0.0"
|