@contentcredits/sdk 2.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.
- package/dist/api/client.d.ts +13 -0
- package/dist/api/comments.d.ts +27 -0
- package/dist/api/credits.d.ts +16 -0
- package/dist/auth/popup.d.ts +18 -0
- package/dist/auth/storage.d.ts +6 -0
- package/dist/auth/token.d.ts +17 -0
- package/dist/comments/index.d.ts +9 -0
- package/dist/comments/panel.d.ts +8 -0
- package/dist/comments/widget.d.ts +7 -0
- package/dist/content-credits.cjs.js +2574 -0
- package/dist/content-credits.cjs.js.map +1 -0
- package/dist/content-credits.d.ts +175 -0
- package/dist/content-credits.esm.js +2572 -0
- package/dist/content-credits.esm.js.map +1 -0
- package/dist/content-credits.umd.min.js +2 -0
- package/dist/content-credits.umd.min.js.map +1 -0
- package/dist/core/config.d.ts +2 -0
- package/dist/core/events.d.ts +8 -0
- package/dist/core/state.d.ts +10 -0
- package/dist/extension/bridge.d.ts +19 -0
- package/dist/extension/detector.d.ts +13 -0
- package/dist/index.d.ts +58 -0
- package/dist/paywall/gate.d.ts +20 -0
- package/dist/paywall/index.d.ts +9 -0
- package/dist/paywall/renderer.d.ts +16 -0
- package/dist/types/index.d.ts +174 -0
- package/dist/ui/sanitize.d.ts +24 -0
- package/dist/ui/shadow.d.ts +12 -0
- package/dist/ui/styles.d.ts +2 -0
- package/package.json +52 -0
|
@@ -0,0 +1,174 @@
|
|
|
1
|
+
export interface User {
|
|
2
|
+
_id: string;
|
|
3
|
+
firstName: string;
|
|
4
|
+
lastName: string;
|
|
5
|
+
email: string;
|
|
6
|
+
credits: number;
|
|
7
|
+
roles: UserRole[];
|
|
8
|
+
isVerified: boolean;
|
|
9
|
+
isActive: boolean;
|
|
10
|
+
linkedPublisherId?: string;
|
|
11
|
+
purchaseHistory: PurchaseItem[];
|
|
12
|
+
}
|
|
13
|
+
export type UserRole = 'consumer' | 'publisher' | 'admin';
|
|
14
|
+
export interface PurchaseItem {
|
|
15
|
+
articleId: string;
|
|
16
|
+
postUrl: string;
|
|
17
|
+
postName: string;
|
|
18
|
+
creditsSpent: number;
|
|
19
|
+
purchasedAt: string;
|
|
20
|
+
}
|
|
21
|
+
export interface Article {
|
|
22
|
+
_id: string;
|
|
23
|
+
publisherId: string;
|
|
24
|
+
url: string;
|
|
25
|
+
title: string;
|
|
26
|
+
creditsToPurchase: number;
|
|
27
|
+
publisherEarningRate: number;
|
|
28
|
+
totalPurchases: number;
|
|
29
|
+
isActive: boolean;
|
|
30
|
+
}
|
|
31
|
+
export interface Comment {
|
|
32
|
+
_id: string;
|
|
33
|
+
threadId: string;
|
|
34
|
+
parentCommentId: string | null;
|
|
35
|
+
authorId: string;
|
|
36
|
+
content: string;
|
|
37
|
+
isActive: boolean;
|
|
38
|
+
mentions: string[];
|
|
39
|
+
likeCount: number;
|
|
40
|
+
hasLiked: boolean;
|
|
41
|
+
createdAt: string;
|
|
42
|
+
updatedAt: string;
|
|
43
|
+
author?: CommentAuthor;
|
|
44
|
+
replies?: Comment[];
|
|
45
|
+
}
|
|
46
|
+
export interface CommentAuthor {
|
|
47
|
+
_id: string;
|
|
48
|
+
firstName: string;
|
|
49
|
+
lastName: string;
|
|
50
|
+
profilePicture?: string;
|
|
51
|
+
}
|
|
52
|
+
export interface CommentThread {
|
|
53
|
+
_id: string;
|
|
54
|
+
pageUrl: string;
|
|
55
|
+
hostname: string;
|
|
56
|
+
isOpen: boolean;
|
|
57
|
+
}
|
|
58
|
+
export type CommentSortBy = 'TOP' | 'NEWEST' | 'TIPPED_MOST';
|
|
59
|
+
export interface ApiResponse<T = Record<string, unknown>> {
|
|
60
|
+
success: boolean;
|
|
61
|
+
message?: string;
|
|
62
|
+
data?: T;
|
|
63
|
+
}
|
|
64
|
+
export interface CheckAccessResponse {
|
|
65
|
+
success: boolean;
|
|
66
|
+
message?: string;
|
|
67
|
+
}
|
|
68
|
+
export interface PurchaseResponse {
|
|
69
|
+
success: boolean;
|
|
70
|
+
message?: string;
|
|
71
|
+
}
|
|
72
|
+
export interface CommentsResponse {
|
|
73
|
+
thread: CommentThread;
|
|
74
|
+
comments: Comment[];
|
|
75
|
+
}
|
|
76
|
+
export type EnsureThreadResponse = CommentThread;
|
|
77
|
+
export interface SDKConfig {
|
|
78
|
+
/** Publisher API key from the Content Credits admin panel */
|
|
79
|
+
apiKey: string;
|
|
80
|
+
/** Full URL of the article page. Defaults to window.location.href */
|
|
81
|
+
articleUrl?: string;
|
|
82
|
+
/** CSS selector for the element containing the premium content to gate */
|
|
83
|
+
contentSelector?: string;
|
|
84
|
+
/** Number of visible paragraphs before the paywall kicks in. Default: 2 */
|
|
85
|
+
teaserParagraphs?: number;
|
|
86
|
+
/** Whether to enable the comment widget. Default: true */
|
|
87
|
+
enableComments?: boolean;
|
|
88
|
+
/** Override the Chrome extension ID */
|
|
89
|
+
extensionId?: string;
|
|
90
|
+
/** Visual theme options */
|
|
91
|
+
theme?: SDKTheme;
|
|
92
|
+
/** Custom HTML template string for the paywall overlay */
|
|
93
|
+
paywallTemplate?: string;
|
|
94
|
+
/** Called when the user is granted access to the article */
|
|
95
|
+
onAccessGranted?: () => void;
|
|
96
|
+
/** Enable verbose debug logging */
|
|
97
|
+
debug?: boolean;
|
|
98
|
+
}
|
|
99
|
+
export interface SDKTheme {
|
|
100
|
+
/** Primary brand colour used for buttons and accents. Default: '#44C678' */
|
|
101
|
+
primaryColor?: string;
|
|
102
|
+
/** Font family for all SDK UI elements */
|
|
103
|
+
fontFamily?: string;
|
|
104
|
+
}
|
|
105
|
+
export interface ResolvedConfig extends Required<Omit<SDKConfig, 'paywallTemplate' | 'onAccessGranted' | 'theme'>> {
|
|
106
|
+
articleUrl: string;
|
|
107
|
+
hostName: string;
|
|
108
|
+
pageTitle: string;
|
|
109
|
+
apiBaseUrl: string;
|
|
110
|
+
accountsUrl: string;
|
|
111
|
+
paywallTemplate?: string;
|
|
112
|
+
onAccessGranted?: () => void;
|
|
113
|
+
theme: Required<SDKTheme>;
|
|
114
|
+
}
|
|
115
|
+
export interface SDKState {
|
|
116
|
+
isLoading: boolean;
|
|
117
|
+
isExtensionAvailable: boolean;
|
|
118
|
+
isLoggedIn: boolean;
|
|
119
|
+
hasAccess: boolean;
|
|
120
|
+
isLoaded: boolean;
|
|
121
|
+
user: User | null;
|
|
122
|
+
creditBalance: number | null;
|
|
123
|
+
requiredCredits: number | null;
|
|
124
|
+
}
|
|
125
|
+
export interface SDKEventMap {
|
|
126
|
+
ready: {
|
|
127
|
+
state: SDKState;
|
|
128
|
+
};
|
|
129
|
+
'auth:login': {
|
|
130
|
+
user: User;
|
|
131
|
+
};
|
|
132
|
+
'auth:logout': Record<string, never>;
|
|
133
|
+
'paywall:shown': Record<string, never>;
|
|
134
|
+
'paywall:hidden': Record<string, never>;
|
|
135
|
+
'article:purchased': {
|
|
136
|
+
creditsSpent: number;
|
|
137
|
+
remainingBalance: number;
|
|
138
|
+
};
|
|
139
|
+
'credits:insufficient': {
|
|
140
|
+
required: number;
|
|
141
|
+
available: number;
|
|
142
|
+
};
|
|
143
|
+
'comment:posted': {
|
|
144
|
+
comment: Comment;
|
|
145
|
+
};
|
|
146
|
+
'comment:liked': {
|
|
147
|
+
commentId: string;
|
|
148
|
+
hasLiked: boolean;
|
|
149
|
+
};
|
|
150
|
+
'comment:deleted': {
|
|
151
|
+
commentId: string;
|
|
152
|
+
};
|
|
153
|
+
error: {
|
|
154
|
+
message: string;
|
|
155
|
+
error?: unknown;
|
|
156
|
+
};
|
|
157
|
+
}
|
|
158
|
+
export type SDKEventName = keyof SDKEventMap;
|
|
159
|
+
export type SDKEventHandler<K extends SDKEventName> = (payload: SDKEventMap[K]) => void;
|
|
160
|
+
export interface ExtensionMessage {
|
|
161
|
+
type: string;
|
|
162
|
+
data?: Record<string, unknown>;
|
|
163
|
+
}
|
|
164
|
+
export interface AuthorizationResponseData {
|
|
165
|
+
isAuthenticated: boolean;
|
|
166
|
+
doesHaveAccess: boolean;
|
|
167
|
+
creditBalance?: number;
|
|
168
|
+
requiredCredits?: number;
|
|
169
|
+
}
|
|
170
|
+
export interface PurchaseResponseData {
|
|
171
|
+
doesHaveAccess: boolean;
|
|
172
|
+
creditBalance?: number;
|
|
173
|
+
creditsSpent?: number;
|
|
174
|
+
}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Safe DOM text node — never use innerHTML with user-generated content.
|
|
3
|
+
* Returns a text node that can be appended to any element.
|
|
4
|
+
*/
|
|
5
|
+
export declare function safeText(str: string): Text;
|
|
6
|
+
/**
|
|
7
|
+
* Set an element's text content safely (no HTML injection).
|
|
8
|
+
*/
|
|
9
|
+
export declare function setTextContent(el: Element, str: string): void;
|
|
10
|
+
/**
|
|
11
|
+
* Create an element with safe text content.
|
|
12
|
+
*/
|
|
13
|
+
export declare function el<K extends keyof HTMLElementTagNameMap>(tag: K, text?: string, attrs?: Record<string, string>): HTMLElementTagNameMap[K];
|
|
14
|
+
/**
|
|
15
|
+
* Render comment content as safe DOM nodes.
|
|
16
|
+
* Supports newlines → <br> but no raw HTML from user input.
|
|
17
|
+
* Returns a DocumentFragment.
|
|
18
|
+
*/
|
|
19
|
+
export declare function renderCommentContent(raw: string): DocumentFragment;
|
|
20
|
+
/**
|
|
21
|
+
* Validate that a URL is safe (http/https only).
|
|
22
|
+
* Returns null if unsafe.
|
|
23
|
+
*/
|
|
24
|
+
export declare function sanitizeUrl(url: string): string | null;
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Creates an isolated Shadow DOM host attached to document.body.
|
|
3
|
+
* All SDK UI lives inside this shadow root so partner CSS cannot
|
|
4
|
+
* bleed in and SDK CSS cannot bleed out.
|
|
5
|
+
*/
|
|
6
|
+
export declare function createShadowHost(id: string): {
|
|
7
|
+
host: HTMLElement;
|
|
8
|
+
root: ShadowRoot;
|
|
9
|
+
};
|
|
10
|
+
export declare function removeShadowHost(id: string): void;
|
|
11
|
+
/** Inject a <style> tag into a shadow root */
|
|
12
|
+
export declare function injectStyles(root: ShadowRoot, css: string): void;
|
package/package.json
ADDED
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@contentcredits/sdk",
|
|
3
|
+
"version": "2.0.0",
|
|
4
|
+
"description": "Content Credits JS SDK — drop-in paywall and comments for any website",
|
|
5
|
+
"author": "Content Credits",
|
|
6
|
+
"license": "MIT",
|
|
7
|
+
"main": "dist/content-credits.cjs.js",
|
|
8
|
+
"module": "dist/content-credits.esm.js",
|
|
9
|
+
"browser": "dist/content-credits.umd.min.js",
|
|
10
|
+
"types": "dist/content-credits.d.ts",
|
|
11
|
+
"files": [
|
|
12
|
+
"dist"
|
|
13
|
+
],
|
|
14
|
+
"exports": {
|
|
15
|
+
".": {
|
|
16
|
+
"import": "./dist/content-credits.esm.js",
|
|
17
|
+
"require": "./dist/content-credits.cjs.js",
|
|
18
|
+
"types": "./dist/content-credits.d.ts"
|
|
19
|
+
}
|
|
20
|
+
},
|
|
21
|
+
"scripts": {
|
|
22
|
+
"build": "rollup -c rollup.config.mjs",
|
|
23
|
+
"build:watch": "rollup -c rollup.config.mjs --watch",
|
|
24
|
+
"build:dev": "USE_LOCALHOST=true rollup -c rollup.config.mjs",
|
|
25
|
+
"demo": "npm run build && npx serve . -l 4444 --no-clipboard",
|
|
26
|
+
"demo:dev": "npm run build:dev && npx serve . -l 4444 --no-clipboard",
|
|
27
|
+
"test": "vitest run",
|
|
28
|
+
"test:watch": "vitest",
|
|
29
|
+
"test:coverage": "vitest run --coverage",
|
|
30
|
+
"lint": "eslint src --ext .ts",
|
|
31
|
+
"lint:fix": "eslint src --ext .ts --fix",
|
|
32
|
+
"typecheck": "tsc --noEmit",
|
|
33
|
+
"clean": "rm -rf dist"
|
|
34
|
+
},
|
|
35
|
+
"devDependencies": {
|
|
36
|
+
"@rollup/plugin-node-resolve": "^15.2.3",
|
|
37
|
+
"@rollup/plugin-replace": "^5.0.5",
|
|
38
|
+
"@rollup/plugin-typescript": "^11.1.6",
|
|
39
|
+
"@types/node": "^20.11.5",
|
|
40
|
+
"@typescript-eslint/eslint-plugin": "^6.19.1",
|
|
41
|
+
"@typescript-eslint/parser": "^6.19.1",
|
|
42
|
+
"@vitest/coverage-v8": "^1.2.2",
|
|
43
|
+
"eslint": "^8.56.0",
|
|
44
|
+
"jsdom": "^24.0.0",
|
|
45
|
+
"rollup": "^4.9.6",
|
|
46
|
+
"rollup-plugin-dts": "^6.1.0",
|
|
47
|
+
"rollup-plugin-terser": "^7.0.2",
|
|
48
|
+
"tslib": "^2.6.2",
|
|
49
|
+
"typescript": "^5.3.3",
|
|
50
|
+
"vitest": "^1.2.2"
|
|
51
|
+
}
|
|
52
|
+
}
|