@feedlog-ai/core 0.0.1

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.
@@ -0,0 +1,18 @@
1
+ /**
2
+ * Custom error types for Feedlog SDK
3
+ */
4
+ export declare class FeedlogError extends Error {
5
+ statusCode?: number | undefined;
6
+ originalError?: unknown | undefined;
7
+ constructor(message: string, statusCode?: number | undefined, originalError?: unknown | undefined);
8
+ }
9
+ export declare class FeedlogValidationError extends FeedlogError {
10
+ constructor(message: string);
11
+ }
12
+ export declare class FeedlogNetworkError extends FeedlogError {
13
+ constructor(message: string, statusCode?: number, originalError?: unknown);
14
+ }
15
+ export declare class FeedlogTimeoutError extends FeedlogError {
16
+ constructor(message?: string);
17
+ }
18
+ //# sourceMappingURL=errors.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"errors.d.ts","sourceRoot":"","sources":["../src/errors.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,qBAAa,YAAa,SAAQ,KAAK;IAG5B,UAAU,CAAC,EAAE,MAAM;IACnB,aAAa,CAAC,EAAE,OAAO;gBAF9B,OAAO,EAAE,MAAM,EACR,UAAU,CAAC,EAAE,MAAM,YAAA,EACnB,aAAa,CAAC,EAAE,OAAO,YAAA;CAMjC;AAED,qBAAa,sBAAuB,SAAQ,YAAY;gBAC1C,OAAO,EAAE,MAAM;CAK5B;AAED,qBAAa,mBAAoB,SAAQ,YAAY;gBACvC,OAAO,EAAE,MAAM,EAAE,UAAU,CAAC,EAAE,MAAM,EAAE,aAAa,CAAC,EAAE,OAAO;CAK1E;AAED,qBAAa,mBAAoB,SAAQ,YAAY;gBACvC,OAAO,GAAE,MAA4B;CAKlD"}
package/dist/errors.js ADDED
@@ -0,0 +1,34 @@
1
+ /**
2
+ * Custom error types for Feedlog SDK
3
+ */
4
+ export class FeedlogError extends Error {
5
+ constructor(message, statusCode, originalError) {
6
+ super(message);
7
+ this.statusCode = statusCode;
8
+ this.originalError = originalError;
9
+ this.name = 'FeedlogError';
10
+ Object.setPrototypeOf(this, FeedlogError.prototype);
11
+ }
12
+ }
13
+ export class FeedlogValidationError extends FeedlogError {
14
+ constructor(message) {
15
+ super(message);
16
+ this.name = 'FeedlogValidationError';
17
+ Object.setPrototypeOf(this, FeedlogValidationError.prototype);
18
+ }
19
+ }
20
+ export class FeedlogNetworkError extends FeedlogError {
21
+ constructor(message, statusCode, originalError) {
22
+ super(message, statusCode, originalError);
23
+ this.name = 'FeedlogNetworkError';
24
+ Object.setPrototypeOf(this, FeedlogNetworkError.prototype);
25
+ }
26
+ }
27
+ export class FeedlogTimeoutError extends FeedlogError {
28
+ constructor(message = 'Request timed out') {
29
+ super(message);
30
+ this.name = 'FeedlogTimeoutError';
31
+ Object.setPrototypeOf(this, FeedlogTimeoutError.prototype);
32
+ }
33
+ }
34
+ //# sourceMappingURL=errors.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"errors.js","sourceRoot":"","sources":["../src/errors.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,MAAM,OAAO,YAAa,SAAQ,KAAK;IACrC,YACE,OAAe,EACR,UAAmB,EACnB,aAAuB;QAE9B,KAAK,CAAC,OAAO,CAAC,CAAC;QAHR,eAAU,GAAV,UAAU,CAAS;QACnB,kBAAa,GAAb,aAAa,CAAU;QAG9B,IAAI,CAAC,IAAI,GAAG,cAAc,CAAC;QAC3B,MAAM,CAAC,cAAc,CAAC,IAAI,EAAE,YAAY,CAAC,SAAS,CAAC,CAAC;IACtD,CAAC;CACF;AAED,MAAM,OAAO,sBAAuB,SAAQ,YAAY;IACtD,YAAY,OAAe;QACzB,KAAK,CAAC,OAAO,CAAC,CAAC;QACf,IAAI,CAAC,IAAI,GAAG,wBAAwB,CAAC;QACrC,MAAM,CAAC,cAAc,CAAC,IAAI,EAAE,sBAAsB,CAAC,SAAS,CAAC,CAAC;IAChE,CAAC;CACF;AAED,MAAM,OAAO,mBAAoB,SAAQ,YAAY;IACnD,YAAY,OAAe,EAAE,UAAmB,EAAE,aAAuB;QACvE,KAAK,CAAC,OAAO,EAAE,UAAU,EAAE,aAAa,CAAC,CAAC;QAC1C,IAAI,CAAC,IAAI,GAAG,qBAAqB,CAAC;QAClC,MAAM,CAAC,cAAc,CAAC,IAAI,EAAE,mBAAmB,CAAC,SAAS,CAAC,CAAC;IAC7D,CAAC;CACF;AAED,MAAM,OAAO,mBAAoB,SAAQ,YAAY;IACnD,YAAY,UAAkB,mBAAmB;QAC/C,KAAK,CAAC,OAAO,CAAC,CAAC;QACf,IAAI,CAAC,IAAI,GAAG,qBAAqB,CAAC;QAClC,MAAM,CAAC,cAAc,CAAC,IAAI,EAAE,mBAAmB,CAAC,SAAS,CAAC,CAAC;IAC7D,CAAC;CACF"}
@@ -0,0 +1,63 @@
1
+ /**
2
+ * Core SDK for Feedlog Toolkit
3
+ *
4
+ * This package provides the core functionality and utilities
5
+ * used across all Feedlog Toolkit packages.
6
+ */
7
+ export * from './types';
8
+ export * from './utils';
9
+ export * from './errors';
10
+ import { FeedlogSDKConfig, FetchIssuesParams, FetchIssuesResponse, UpvoteResponse } from './types';
11
+ /**
12
+ * Main Feedlog SDK class
13
+ * Provides methods to interact with the Feedlog API
14
+ */
15
+ export declare class FeedlogSDK {
16
+ private config;
17
+ private endpoint;
18
+ private timeout;
19
+ constructor(config?: FeedlogSDKConfig);
20
+ /**
21
+ * Fetch issues from the API
22
+ * Supports filtering by repository IDs, type, pagination, and limit
23
+ */
24
+ fetchIssues(params?: FetchIssuesParams): Promise<FetchIssuesResponse>;
25
+ /**
26
+ * Toggle upvote on an issue
27
+ * Adds upvote if not already upvoted, removes if already upvoted
28
+ */
29
+ toggleUpvote(issueId: string): Promise<UpvoteResponse>;
30
+ /**
31
+ * Build the full URL for fetching issues with query parameters
32
+ */
33
+ private buildIssuesUrl;
34
+ /**
35
+ * Get request headers
36
+ */
37
+ private getAuthHeaders;
38
+ /**
39
+ * Fetch with timeout support using AbortController
40
+ */
41
+ private fetchWithTimeout;
42
+ /**
43
+ * Validate and sanitize issues response
44
+ */
45
+ private validateIssuesResponse;
46
+ /**
47
+ * Validate and sanitize an individual issue
48
+ */
49
+ private validateIssue;
50
+ /**
51
+ * Validate upvote response
52
+ */
53
+ private validateUpvoteResponse;
54
+ /**
55
+ * Get the current endpoint
56
+ */
57
+ getEndpoint(): string;
58
+ /**
59
+ * Get the current timeout setting
60
+ */
61
+ getTimeout(): number;
62
+ }
63
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,cAAc,SAAS,CAAC;AAExB,cAAc,SAAS,CAAC;AAExB,cAAc,UAAU,CAAC;AAEzB,OAAO,EACL,gBAAgB,EAChB,iBAAiB,EACjB,mBAAmB,EACnB,cAAc,EAEf,MAAM,SAAS,CAAC;AASjB;;;GAGG;AACH,qBAAa,UAAU;IACrB,OAAO,CAAC,MAAM,CAAmB;IACjC,OAAO,CAAC,QAAQ,CAAS;IACzB,OAAO,CAAC,OAAO,CAAS;gBAEZ,MAAM,GAAE,gBAAqB;IAazC;;;OAGG;IACG,WAAW,CAAC,MAAM,GAAE,iBAAsB,GAAG,OAAO,CAAC,mBAAmB,CAAC;IAmC/E;;;OAGG;IACG,YAAY,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,cAAc,CAAC;IAmD5D;;OAEG;IACH,OAAO,CAAC,cAAc;IA6BtB;;OAEG;IACH,OAAO,CAAC,cAAc;IAMtB;;OAEG;YACW,gBAAgB;IAsB9B;;OAEG;IACH,OAAO,CAAC,sBAAsB;IA0B9B;;OAEG;IACH,OAAO,CAAC,aAAa;IA6DrB;;OAEG;IACH,OAAO,CAAC,sBAAsB;IA0B9B;;OAEG;IACH,WAAW,IAAI,MAAM;IAIrB;;OAEG;IACH,UAAU,IAAI,MAAM;CAGrB"}
package/dist/index.js ADDED
@@ -0,0 +1,261 @@
1
+ /**
2
+ * Core SDK for Feedlog Toolkit
3
+ *
4
+ * This package provides the core functionality and utilities
5
+ * used across all Feedlog Toolkit packages.
6
+ */
7
+ export * from './types';
8
+ export * from './utils';
9
+ export * from './errors';
10
+ import { sanitizeHtml } from './utils';
11
+ import { FeedlogError, FeedlogNetworkError, FeedlogTimeoutError, FeedlogValidationError, } from './errors';
12
+ /**
13
+ * Main Feedlog SDK class
14
+ * Provides methods to interact with the Feedlog API
15
+ */
16
+ export class FeedlogSDK {
17
+ constructor(config = {}) {
18
+ this.config = {
19
+ credentials: 'include',
20
+ ...config,
21
+ };
22
+ this.endpoint = this.config.endpoint || 'https://api.feedlog.app';
23
+ this.timeout = this.config.timeout || 30000;
24
+ // Ensure endpoint doesn't have trailing slash
25
+ this.endpoint = this.endpoint.replace(/\/$/, '');
26
+ }
27
+ /**
28
+ * Fetch issues from the API
29
+ * Supports filtering by repository IDs, type, pagination, and limit
30
+ */
31
+ async fetchIssues(params = {}) {
32
+ try {
33
+ const url = this.buildIssuesUrl(params);
34
+ const response = await this.fetchWithTimeout(url, {
35
+ method: 'GET',
36
+ headers: this.getAuthHeaders(),
37
+ credentials: this.config.credentials || 'include',
38
+ });
39
+ if (!response.ok) {
40
+ throw new FeedlogNetworkError(`Failed to fetch issues: ${response.statusText}`, response.status);
41
+ }
42
+ const data = await response.json();
43
+ return this.validateIssuesResponse(data);
44
+ }
45
+ catch (error) {
46
+ if (error instanceof FeedlogError) {
47
+ throw error;
48
+ }
49
+ if (error instanceof TypeError && error.message.includes('fetch')) {
50
+ throw new FeedlogNetworkError('Network error: Unable to reach API', undefined, error);
51
+ }
52
+ throw new FeedlogError(`Failed to fetch issues: ${error instanceof Error ? error.message : 'Unknown error'}`, undefined, error);
53
+ }
54
+ }
55
+ /**
56
+ * Toggle upvote on an issue
57
+ * Adds upvote if not already upvoted, removes if already upvoted
58
+ */
59
+ async toggleUpvote(issueId) {
60
+ if (!issueId || typeof issueId !== 'string') {
61
+ throw new FeedlogValidationError('Issue ID is required');
62
+ }
63
+ try {
64
+ const url = `${this.endpoint}/api/issues/${encodeURIComponent(issueId)}/upvote`;
65
+ const response = await this.fetchWithTimeout(url, {
66
+ method: 'POST',
67
+ headers: this.getAuthHeaders(),
68
+ credentials: this.config.credentials || 'include',
69
+ });
70
+ if (response.status === 404) {
71
+ throw new FeedlogNetworkError('Issue not found', 404);
72
+ }
73
+ if (response.status === 401) {
74
+ throw new FeedlogNetworkError('Unauthorized', 401);
75
+ }
76
+ if (response.status === 403) {
77
+ throw new FeedlogNetworkError('Forbidden: Domain not allowed for this repository', 403);
78
+ }
79
+ if (!response.ok) {
80
+ throw new FeedlogNetworkError(`Failed to toggle upvote: ${response.statusText}`, response.status);
81
+ }
82
+ const data = await response.json();
83
+ return this.validateUpvoteResponse(data);
84
+ }
85
+ catch (error) {
86
+ if (error instanceof FeedlogError) {
87
+ throw error;
88
+ }
89
+ if (error instanceof TypeError && error.message.includes('fetch')) {
90
+ throw new FeedlogNetworkError('Network error: Unable to reach API', undefined, error);
91
+ }
92
+ throw new FeedlogError(`Failed to toggle upvote: ${error instanceof Error ? error.message : 'Unknown error'}`, undefined, error);
93
+ }
94
+ }
95
+ /**
96
+ * Build the full URL for fetching issues with query parameters
97
+ */
98
+ buildIssuesUrl(params) {
99
+ const url = new URL(`${this.endpoint}/api/issues`);
100
+ // Handle repositoryIds - can be single string or array
101
+ if (params.repositoryIds) {
102
+ const ids = Array.isArray(params.repositoryIds)
103
+ ? params.repositoryIds
104
+ : [params.repositoryIds];
105
+ for (const id of ids) {
106
+ url.searchParams.append('repositoryIds', id);
107
+ }
108
+ }
109
+ if (params.type) {
110
+ url.searchParams.set('type', params.type);
111
+ }
112
+ if (params.cursor) {
113
+ url.searchParams.set('cursor', params.cursor);
114
+ }
115
+ if (params.limit !== undefined) {
116
+ url.searchParams.set('limit', params.limit.toString());
117
+ }
118
+ return url.toString();
119
+ }
120
+ /**
121
+ * Get request headers
122
+ */
123
+ getAuthHeaders() {
124
+ return {
125
+ 'Content-Type': 'application/json',
126
+ };
127
+ }
128
+ /**
129
+ * Fetch with timeout support using AbortController
130
+ */
131
+ async fetchWithTimeout(url, init) {
132
+ const controller = new AbortController();
133
+ const timeout = setTimeout(() => controller.abort(), this.timeout);
134
+ try {
135
+ const response = await fetch(url, {
136
+ ...init,
137
+ signal: controller.signal,
138
+ });
139
+ clearTimeout(timeout);
140
+ return response;
141
+ }
142
+ catch (error) {
143
+ clearTimeout(timeout);
144
+ if (error instanceof Error && error.name === 'AbortError') {
145
+ throw new FeedlogTimeoutError(`Request timed out after ${this.timeout}ms`);
146
+ }
147
+ throw error;
148
+ }
149
+ }
150
+ /**
151
+ * Validate and sanitize issues response
152
+ */
153
+ validateIssuesResponse(data) {
154
+ if (!data || typeof data !== 'object') {
155
+ throw new FeedlogValidationError('Invalid API response: expected object');
156
+ }
157
+ const response = data;
158
+ if (!Array.isArray(response.issues)) {
159
+ throw new FeedlogValidationError('Invalid API response: issues must be an array');
160
+ }
161
+ if (!response.pagination || typeof response.pagination !== 'object') {
162
+ throw new FeedlogValidationError('Invalid API response: pagination is required');
163
+ }
164
+ const issues = response.issues.map(issue => this.validateIssue(issue));
165
+ return {
166
+ issues,
167
+ pagination: {
168
+ cursor: response.pagination.cursor,
169
+ hasMore: Boolean(response.pagination.hasMore),
170
+ },
171
+ };
172
+ }
173
+ /**
174
+ * Validate and sanitize an individual issue
175
+ */
176
+ validateIssue(data) {
177
+ if (!data || typeof data !== 'object') {
178
+ throw new FeedlogValidationError('Invalid issue: expected object');
179
+ }
180
+ const issue = data;
181
+ // Validate required fields
182
+ if (typeof issue.id !== 'string') {
183
+ throw new FeedlogValidationError('Invalid issue: id is required and must be a string');
184
+ }
185
+ if (typeof issue.title !== 'string') {
186
+ throw new FeedlogValidationError('Invalid issue: title is required and must be a string');
187
+ }
188
+ if (!['bug', 'enhancement'].includes(String(issue.type))) {
189
+ throw new FeedlogValidationError('Invalid issue: type must be "bug" or "enhancement"');
190
+ }
191
+ if (!['open', 'closed'].includes(String(issue.status))) {
192
+ throw new FeedlogValidationError('Invalid issue: status must be "open" or "closed"');
193
+ }
194
+ if (!issue.repository || typeof issue.repository !== 'object') {
195
+ throw new FeedlogValidationError('Invalid issue: repository is required');
196
+ }
197
+ const repo = issue.repository;
198
+ if (typeof repo.id !== 'string' ||
199
+ typeof repo.name !== 'string' ||
200
+ typeof repo.owner !== 'string') {
201
+ throw new FeedlogValidationError('Invalid issue: repository must have id, name, and owner');
202
+ }
203
+ // Sanitize string fields to prevent XSS
204
+ const sanitizedTitle = sanitizeHtml(String(issue.title));
205
+ const sanitizedBody = sanitizeHtml(String(issue.body || ''));
206
+ return {
207
+ id: String(issue.id),
208
+ type: issue.type || 'bug',
209
+ status: issue.status || 'open',
210
+ pinnedAt: issue.pinnedAt ? String(issue.pinnedAt) : null,
211
+ revision: Number(issue.revision) || 1,
212
+ title: sanitizedTitle,
213
+ body: sanitizedBody,
214
+ repository: {
215
+ id: String(repo.id),
216
+ name: String(repo.name),
217
+ owner: String(repo.owner),
218
+ },
219
+ updatedAt: String(issue.updatedAt) || new Date().toISOString(),
220
+ createdAt: String(issue.createdAt) || new Date().toISOString(),
221
+ upvoteCount: Number(issue.upvoteCount) || 0,
222
+ hasUpvoted: Boolean(issue.hasUpvoted),
223
+ };
224
+ }
225
+ /**
226
+ * Validate upvote response
227
+ */
228
+ validateUpvoteResponse(data) {
229
+ if (!data || typeof data !== 'object') {
230
+ throw new FeedlogValidationError('Invalid upvote response: expected object');
231
+ }
232
+ const response = data;
233
+ if (typeof response.upvoted !== 'boolean') {
234
+ throw new FeedlogValidationError('Invalid upvote response: upvoted must be a boolean');
235
+ }
236
+ if (typeof response.upvoteCount !== 'number') {
237
+ throw new FeedlogValidationError('Invalid upvote response: upvoteCount must be a number');
238
+ }
239
+ if (typeof response.anonymousUserId !== 'string') {
240
+ throw new FeedlogValidationError('Invalid upvote response: anonymousUserId must be a string');
241
+ }
242
+ return {
243
+ upvoted: response.upvoted,
244
+ upvoteCount: response.upvoteCount,
245
+ anonymousUserId: response.anonymousUserId,
246
+ };
247
+ }
248
+ /**
249
+ * Get the current endpoint
250
+ */
251
+ getEndpoint() {
252
+ return this.endpoint;
253
+ }
254
+ /**
255
+ * Get the current timeout setting
256
+ */
257
+ getTimeout() {
258
+ return this.timeout;
259
+ }
260
+ }
261
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,85 @@
1
+ /**
2
+ * Core types for Feedlog Toolkit
3
+ */
4
+ /**
5
+ * Repository information embedded in issue responses
6
+ */
7
+ export interface Repository {
8
+ id: string;
9
+ name: string;
10
+ owner: string;
11
+ }
12
+ /**
13
+ * Issue type matching new API response schema
14
+ */
15
+ export interface FeedlogIssue {
16
+ id: string;
17
+ type: 'bug' | 'enhancement';
18
+ status: 'open' | 'closed';
19
+ pinnedAt: string | null;
20
+ title: string;
21
+ body: string;
22
+ revision: number;
23
+ repository: Repository;
24
+ updatedAt: string;
25
+ createdAt: string;
26
+ upvoteCount: number;
27
+ hasUpvoted: boolean;
28
+ }
29
+ /**
30
+ * Parameters for fetching issues
31
+ */
32
+ export interface FetchIssuesParams {
33
+ repositoryIds?: string | string[];
34
+ type?: 'bug' | 'enhancement';
35
+ cursor?: string;
36
+ limit?: number;
37
+ }
38
+ /**
39
+ * Pagination information
40
+ */
41
+ export interface PaginationInfo {
42
+ cursor: string | null;
43
+ hasMore: boolean;
44
+ }
45
+ /**
46
+ * Response from fetching issues
47
+ */
48
+ export interface FetchIssuesResponse {
49
+ issues: FeedlogIssue[];
50
+ pagination: PaginationInfo;
51
+ }
52
+ /**
53
+ * Response from upvoting an issue
54
+ */
55
+ export interface UpvoteResponse {
56
+ upvoted: boolean;
57
+ upvoteCount: number;
58
+ anonymousUserId: string;
59
+ }
60
+ /**
61
+ * SDK configuration
62
+ */
63
+ export interface FeedlogSDKConfig {
64
+ endpoint?: string;
65
+ timeout?: number;
66
+ credentials?: RequestCredentials;
67
+ }
68
+ /**
69
+ * Generic API response wrapper (for consistency)
70
+ */
71
+ export interface FeedlogResponse<T = unknown> {
72
+ success: boolean;
73
+ data?: T;
74
+ error?: string;
75
+ }
76
+ /**
77
+ * Event types for the toolkit
78
+ */
79
+ export interface FeedlogEvent {
80
+ id: string;
81
+ timestamp: number;
82
+ type: string;
83
+ data?: Record<string, unknown>;
84
+ }
85
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/types/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH;;GAEG;AACH,MAAM,WAAW,UAAU;IACzB,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;CACf;AAED;;GAEG;AACH,MAAM,WAAW,YAAY;IAC3B,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,KAAK,GAAG,aAAa,CAAC;IAC5B,MAAM,EAAE,MAAM,GAAG,QAAQ,CAAC;IAC1B,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;IACxB,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,MAAM,CAAC;IACjB,UAAU,EAAE,UAAU,CAAC;IACvB,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;IAClB,WAAW,EAAE,MAAM,CAAC;IACpB,UAAU,EAAE,OAAO,CAAC;CACrB;AAED;;GAEG;AACH,MAAM,WAAW,iBAAiB;IAChC,aAAa,CAAC,EAAE,MAAM,GAAG,MAAM,EAAE,CAAC;IAClC,IAAI,CAAC,EAAE,KAAK,GAAG,aAAa,CAAC;IAC7B,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED;;GAEG;AACH,MAAM,WAAW,cAAc;IAC7B,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;IACtB,OAAO,EAAE,OAAO,CAAC;CAClB;AAED;;GAEG;AACH,MAAM,WAAW,mBAAmB;IAClC,MAAM,EAAE,YAAY,EAAE,CAAC;IACvB,UAAU,EAAE,cAAc,CAAC;CAC5B;AAED;;GAEG;AACH,MAAM,WAAW,cAAc;IAC7B,OAAO,EAAE,OAAO,CAAC;IACjB,WAAW,EAAE,MAAM,CAAC;IACpB,eAAe,EAAE,MAAM,CAAC;CACzB;AAED;;GAEG;AACH,MAAM,WAAW,gBAAgB;IAC/B,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,WAAW,CAAC,EAAE,kBAAkB,CAAC;CAClC;AAED;;GAEG;AACH,MAAM,WAAW,eAAe,CAAC,CAAC,GAAG,OAAO;IAC1C,OAAO,EAAE,OAAO,CAAC;IACjB,IAAI,CAAC,EAAE,CAAC,CAAC;IACT,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED;;GAEG;AACH,MAAM,WAAW,YAAY;IAC3B,EAAE,EAAE,MAAM,CAAC;IACX,SAAS,EAAE,MAAM,CAAC;IAClB,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CAChC"}
@@ -0,0 +1,5 @@
1
+ /**
2
+ * Core types for Feedlog Toolkit
3
+ */
4
+ export {};
5
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/types/index.ts"],"names":[],"mappings":"AAAA;;GAEG"}
@@ -0,0 +1,36 @@
1
+ /**
2
+ * Core utilities for Feedlog Toolkit
3
+ */
4
+ export { escapeHtml, sanitizeHtml, containsDangerousContent, stripHtmlTags, truncateText, } from './sanitize';
5
+ /**
6
+ * Create a timestamp
7
+ */
8
+ export declare function createTimestamp(): number;
9
+ /**
10
+ * Generate a unique ID
11
+ */
12
+ export declare function generateId(): string;
13
+ /**
14
+ * Get cookie value by name
15
+ * Used for reading the anonymous user ID cookie set by the server
16
+ */
17
+ export declare function getCookie(name: string): string | null;
18
+ /**
19
+ * Create a rate limiter function
20
+ * Returns a function that can be called to check if an action should be rate limited
21
+ */
22
+ export declare function createRateLimiter(maxRequests: number, windowMs: number): {
23
+ /**
24
+ * Check if an action is allowed based on rate limit
25
+ */
26
+ isAllowed(): boolean;
27
+ /**
28
+ * Reset the rate limiter
29
+ */
30
+ reset(): void;
31
+ /**
32
+ * Get remaining requests in current window
33
+ */
34
+ getRemaining(): number;
35
+ };
36
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/utils/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AAGH,OAAO,EACL,UAAU,EACV,YAAY,EACZ,wBAAwB,EACxB,aAAa,EACb,YAAY,GACb,MAAM,YAAY,CAAC;AAEpB;;GAEG;AACH,wBAAgB,eAAe,IAAI,MAAM,CAExC;AAED;;GAEG;AACH,wBAAgB,UAAU,IAAI,MAAM,CAEnC;AAED;;;GAGG;AACH,wBAAgB,SAAS,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAgBrD;AAED;;;GAGG;AACH,wBAAgB,iBAAiB,CAAC,WAAW,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM;IAInE;;OAEG;iBACU,OAAO;IAiBpB;;OAEG;aACM,IAAI;IAIb;;OAEG;oBACa,MAAM;EAQzB"}
@@ -0,0 +1,76 @@
1
+ /**
2
+ * Core utilities for Feedlog Toolkit
3
+ */
4
+ // Re-export sanitization utilities
5
+ export { escapeHtml, sanitizeHtml, containsDangerousContent, stripHtmlTags, truncateText, } from './sanitize';
6
+ /**
7
+ * Create a timestamp
8
+ */
9
+ export function createTimestamp() {
10
+ return Date.now();
11
+ }
12
+ /**
13
+ * Generate a unique ID
14
+ */
15
+ export function generateId() {
16
+ return `${Date.now()}-${Math.random().toString(36).substr(2, 9)}`;
17
+ }
18
+ /**
19
+ * Get cookie value by name
20
+ * Used for reading the anonymous user ID cookie set by the server
21
+ */
22
+ export function getCookie(name) {
23
+ if (typeof document === 'undefined') {
24
+ return null;
25
+ }
26
+ const nameEQ = name + '=';
27
+ const cookies = document.cookie.split(';');
28
+ for (const cookie of cookies) {
29
+ const trimmed = cookie.trim();
30
+ if (trimmed.startsWith(nameEQ)) {
31
+ return trimmed.substring(nameEQ.length);
32
+ }
33
+ }
34
+ return null;
35
+ }
36
+ /**
37
+ * Create a rate limiter function
38
+ * Returns a function that can be called to check if an action should be rate limited
39
+ */
40
+ export function createRateLimiter(maxRequests, windowMs) {
41
+ const timestamps = [];
42
+ return {
43
+ /**
44
+ * Check if an action is allowed based on rate limit
45
+ */
46
+ isAllowed() {
47
+ const now = Date.now();
48
+ const windowStart = now - windowMs;
49
+ // Remove timestamps outside the window
50
+ while (timestamps.length > 0 && timestamps[0] < windowStart) {
51
+ timestamps.shift();
52
+ }
53
+ if (timestamps.length < maxRequests) {
54
+ timestamps.push(now);
55
+ return true;
56
+ }
57
+ return false;
58
+ },
59
+ /**
60
+ * Reset the rate limiter
61
+ */
62
+ reset() {
63
+ timestamps.length = 0;
64
+ },
65
+ /**
66
+ * Get remaining requests in current window
67
+ */
68
+ getRemaining() {
69
+ const now = Date.now();
70
+ const windowStart = now - windowMs;
71
+ const validTimestamps = timestamps.filter(ts => ts >= windowStart);
72
+ return Math.max(0, maxRequests - validTimestamps.length);
73
+ },
74
+ };
75
+ }
76
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/utils/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,mCAAmC;AACnC,OAAO,EACL,UAAU,EACV,YAAY,EACZ,wBAAwB,EACxB,aAAa,EACb,YAAY,GACb,MAAM,YAAY,CAAC;AAEpB;;GAEG;AACH,MAAM,UAAU,eAAe;IAC7B,OAAO,IAAI,CAAC,GAAG,EAAE,CAAC;AACpB,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,UAAU;IACxB,OAAO,GAAG,IAAI,CAAC,GAAG,EAAE,IAAI,IAAI,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC;AACpE,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,SAAS,CAAC,IAAY;IACpC,IAAI,OAAO,QAAQ,KAAK,WAAW,EAAE,CAAC;QACpC,OAAO,IAAI,CAAC;IACd,CAAC;IAED,MAAM,MAAM,GAAG,IAAI,GAAG,GAAG,CAAC;IAC1B,MAAM,OAAO,GAAG,QAAQ,CAAC,MAAM,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;IAE3C,KAAK,MAAM,MAAM,IAAI,OAAO,EAAE,CAAC;QAC7B,MAAM,OAAO,GAAG,MAAM,CAAC,IAAI,EAAE,CAAC;QAC9B,IAAI,OAAO,CAAC,UAAU,CAAC,MAAM,CAAC,EAAE,CAAC;YAC/B,OAAO,OAAO,CAAC,SAAS,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;QAC1C,CAAC;IACH,CAAC;IAED,OAAO,IAAI,CAAC;AACd,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,iBAAiB,CAAC,WAAmB,EAAE,QAAgB;IACrE,MAAM,UAAU,GAAa,EAAE,CAAC;IAEhC,OAAO;QACL;;WAEG;QACH,SAAS;YACP,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;YACvB,MAAM,WAAW,GAAG,GAAG,GAAG,QAAQ,CAAC;YAEnC,uCAAuC;YACvC,OAAO,UAAU,CAAC,MAAM,GAAG,CAAC,IAAI,UAAU,CAAC,CAAC,CAAC,GAAG,WAAW,EAAE,CAAC;gBAC5D,UAAU,CAAC,KAAK,EAAE,CAAC;YACrB,CAAC;YAED,IAAI,UAAU,CAAC,MAAM,GAAG,WAAW,EAAE,CAAC;gBACpC,UAAU,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;gBACrB,OAAO,IAAI,CAAC;YACd,CAAC;YAED,OAAO,KAAK,CAAC;QACf,CAAC;QAED;;WAEG;QACH,KAAK;YACH,UAAU,CAAC,MAAM,GAAG,CAAC,CAAC;QACxB,CAAC;QAED;;WAEG;QACH,YAAY;YACV,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;YACvB,MAAM,WAAW,GAAG,GAAG,GAAG,QAAQ,CAAC;YAEnC,MAAM,eAAe,GAAG,UAAU,CAAC,MAAM,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,IAAI,WAAW,CAAC,CAAC;YACnE,OAAO,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,WAAW,GAAG,eAAe,CAAC,MAAM,CAAC,CAAC;QAC3D,CAAC;KACF,CAAC;AACJ,CAAC"}
@@ -0,0 +1,27 @@
1
+ /**
2
+ * HTML and XSS sanitization utilities
3
+ */
4
+ /**
5
+ * Basic HTML entity escaping to prevent XSS
6
+ * This is a lightweight alternative to DOMPurify
7
+ */
8
+ export declare function escapeHtml(unsafe: string): string;
9
+ /**
10
+ * Sanitize HTML by removing dangerous tags and attributes
11
+ * Removes script tags, event handlers, and other potentially malicious content
12
+ */
13
+ export declare function sanitizeHtml(html: string): string;
14
+ /**
15
+ * Validate that a string is safe to display as HTML
16
+ * Returns true if string contains potentially dangerous content
17
+ */
18
+ export declare function containsDangerousContent(html: string): boolean;
19
+ /**
20
+ * Strip HTML tags completely, leaving only text content
21
+ */
22
+ export declare function stripHtmlTags(html: string): string;
23
+ /**
24
+ * Truncate text to a maximum length with ellipsis
25
+ */
26
+ export declare function truncateText(text: string, maxLength: number): string;
27
+ //# sourceMappingURL=sanitize.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sanitize.d.ts","sourceRoot":"","sources":["../../src/utils/sanitize.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH;;;GAGG;AACH,wBAAgB,UAAU,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAWjD;AAED;;;GAGG;AACH,wBAAgB,YAAY,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CA4BjD;AAED;;;GAGG;AACH,wBAAgB,wBAAwB,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAe9D;AAED;;GAEG;AACH,wBAAgB,aAAa,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAMlD;AAED;;GAEG;AACH,wBAAgB,YAAY,CAAC,IAAI,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,MAAM,CAUpE"}
@@ -0,0 +1,83 @@
1
+ /**
2
+ * HTML and XSS sanitization utilities
3
+ */
4
+ /**
5
+ * Basic HTML entity escaping to prevent XSS
6
+ * This is a lightweight alternative to DOMPurify
7
+ */
8
+ export function escapeHtml(unsafe) {
9
+ if (typeof unsafe !== 'string') {
10
+ return '';
11
+ }
12
+ return unsafe
13
+ .replace(/&/g, '&amp;')
14
+ .replace(/</g, '&lt;')
15
+ .replace(/>/g, '&gt;')
16
+ .replace(/"/g, '&quot;')
17
+ .replace(/'/g, '&#039;');
18
+ }
19
+ /**
20
+ * Sanitize HTML by removing dangerous tags and attributes
21
+ * Removes script tags, event handlers, and other potentially malicious content
22
+ */
23
+ export function sanitizeHtml(html) {
24
+ if (typeof html !== 'string') {
25
+ return '';
26
+ }
27
+ // Remove script tags and content
28
+ let sanitized = html.replace(/<script\b[^<]*(?:(?!<\/script>)<[^<]*)*<\/script>/gi, '');
29
+ // Remove on* event handlers
30
+ sanitized = sanitized.replace(/\s*on\w+\s*=\s*["'][^"']*["']/gi, '');
31
+ sanitized = sanitized.replace(/\s*on\w+\s*=\s*[^\s>]*/gi, '');
32
+ // Remove iframe tags
33
+ sanitized = sanitized.replace(/<iframe\b[^<]*(?:(?!<\/iframe>)<[^<]*)*<\/iframe>/gi, '');
34
+ // Remove style tags
35
+ sanitized = sanitized.replace(/<style\b[^<]*(?:(?!<\/style>)<[^<]*)*<\/style>/gi, '');
36
+ // Remove embed and object tags
37
+ sanitized = sanitized.replace(/<(embed|object)\b[^<]*>/gi, '');
38
+ // Remove javascript: protocol
39
+ sanitized = sanitized.replace(/javascript:/gi, '');
40
+ // Remove data: protocol for potentially dangerous mime types
41
+ sanitized = sanitized.replace(/data:(?!image\/(?:png|jpg|jpeg|gif|webp);)/gi, '');
42
+ return sanitized;
43
+ }
44
+ /**
45
+ * Validate that a string is safe to display as HTML
46
+ * Returns true if string contains potentially dangerous content
47
+ */
48
+ export function containsDangerousContent(html) {
49
+ if (typeof html !== 'string') {
50
+ return false;
51
+ }
52
+ const dangerousPatterns = [
53
+ /<script/i,
54
+ /on\w+\s*=/i,
55
+ /<iframe/i,
56
+ /<object/i,
57
+ /<embed/i,
58
+ /javascript:/i,
59
+ ];
60
+ return dangerousPatterns.some(pattern => pattern.test(html));
61
+ }
62
+ /**
63
+ * Strip HTML tags completely, leaving only text content
64
+ */
65
+ export function stripHtmlTags(html) {
66
+ if (typeof html !== 'string') {
67
+ return '';
68
+ }
69
+ return html.replace(/<[^>]*>/g, '');
70
+ }
71
+ /**
72
+ * Truncate text to a maximum length with ellipsis
73
+ */
74
+ export function truncateText(text, maxLength) {
75
+ if (typeof text !== 'string') {
76
+ return '';
77
+ }
78
+ if (text.length <= maxLength) {
79
+ return text;
80
+ }
81
+ return text.substring(0, maxLength).trim() + '...';
82
+ }
83
+ //# sourceMappingURL=sanitize.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sanitize.js","sourceRoot":"","sources":["../../src/utils/sanitize.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH;;;GAGG;AACH,MAAM,UAAU,UAAU,CAAC,MAAc;IACvC,IAAI,OAAO,MAAM,KAAK,QAAQ,EAAE,CAAC;QAC/B,OAAO,EAAE,CAAC;IACZ,CAAC;IAED,OAAO,MAAM;SACV,OAAO,CAAC,IAAI,EAAE,OAAO,CAAC;SACtB,OAAO,CAAC,IAAI,EAAE,MAAM,CAAC;SACrB,OAAO,CAAC,IAAI,EAAE,MAAM,CAAC;SACrB,OAAO,CAAC,IAAI,EAAE,QAAQ,CAAC;SACvB,OAAO,CAAC,IAAI,EAAE,QAAQ,CAAC,CAAC;AAC7B,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,YAAY,CAAC,IAAY;IACvC,IAAI,OAAO,IAAI,KAAK,QAAQ,EAAE,CAAC;QAC7B,OAAO,EAAE,CAAC;IACZ,CAAC;IAED,iCAAiC;IACjC,IAAI,SAAS,GAAG,IAAI,CAAC,OAAO,CAAC,qDAAqD,EAAE,EAAE,CAAC,CAAC;IAExF,4BAA4B;IAC5B,SAAS,GAAG,SAAS,CAAC,OAAO,CAAC,iCAAiC,EAAE,EAAE,CAAC,CAAC;IACrE,SAAS,GAAG,SAAS,CAAC,OAAO,CAAC,0BAA0B,EAAE,EAAE,CAAC,CAAC;IAE9D,qBAAqB;IACrB,SAAS,GAAG,SAAS,CAAC,OAAO,CAAC,qDAAqD,EAAE,EAAE,CAAC,CAAC;IAEzF,oBAAoB;IACpB,SAAS,GAAG,SAAS,CAAC,OAAO,CAAC,kDAAkD,EAAE,EAAE,CAAC,CAAC;IAEtF,+BAA+B;IAC/B,SAAS,GAAG,SAAS,CAAC,OAAO,CAAC,2BAA2B,EAAE,EAAE,CAAC,CAAC;IAE/D,8BAA8B;IAC9B,SAAS,GAAG,SAAS,CAAC,OAAO,CAAC,eAAe,EAAE,EAAE,CAAC,CAAC;IAEnD,6DAA6D;IAC7D,SAAS,GAAG,SAAS,CAAC,OAAO,CAAC,8CAA8C,EAAE,EAAE,CAAC,CAAC;IAElF,OAAO,SAAS,CAAC;AACnB,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,wBAAwB,CAAC,IAAY;IACnD,IAAI,OAAO,IAAI,KAAK,QAAQ,EAAE,CAAC;QAC7B,OAAO,KAAK,CAAC;IACf,CAAC;IAED,MAAM,iBAAiB,GAAG;QACxB,UAAU;QACV,YAAY;QACZ,UAAU;QACV,UAAU;QACV,SAAS;QACT,cAAc;KACf,CAAC;IAEF,OAAO,iBAAiB,CAAC,IAAI,CAAC,OAAO,CAAC,EAAE,CAAC,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC;AAC/D,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,aAAa,CAAC,IAAY;IACxC,IAAI,OAAO,IAAI,KAAK,QAAQ,EAAE,CAAC;QAC7B,OAAO,EAAE,CAAC;IACZ,CAAC;IAED,OAAO,IAAI,CAAC,OAAO,CAAC,UAAU,EAAE,EAAE,CAAC,CAAC;AACtC,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,YAAY,CAAC,IAAY,EAAE,SAAiB;IAC1D,IAAI,OAAO,IAAI,KAAK,QAAQ,EAAE,CAAC;QAC7B,OAAO,EAAE,CAAC;IACZ,CAAC;IAED,IAAI,IAAI,CAAC,MAAM,IAAI,SAAS,EAAE,CAAC;QAC7B,OAAO,IAAI,CAAC;IACd,CAAC;IAED,OAAO,IAAI,CAAC,SAAS,CAAC,CAAC,EAAE,SAAS,CAAC,CAAC,IAAI,EAAE,GAAG,KAAK,CAAC;AACrD,CAAC"}
package/package.json ADDED
@@ -0,0 +1,40 @@
1
+ {
2
+ "name": "@feedlog-ai/core",
3
+ "version": "0.0.1",
4
+ "description": "Core SDK for Feedlog Toolkit",
5
+ "main": "./dist/index.js",
6
+ "module": "./dist/index.js",
7
+ "types": "./dist/index.d.ts",
8
+ "exports": {
9
+ ".": {
10
+ "import": "./dist/index.js",
11
+ "require": "./dist/index.js",
12
+ "types": "./dist/index.d.ts"
13
+ }
14
+ },
15
+ "files": [
16
+ "dist"
17
+ ],
18
+ "scripts": {
19
+ "build": "tsc",
20
+ "dev": "tsc --watch",
21
+ "clean": "rm -rf dist",
22
+ "test": "jest",
23
+ "test:watch": "jest --watch",
24
+ "test:coverage": "jest --coverage"
25
+ },
26
+ "keywords": [
27
+ "feedlog",
28
+ "sdk",
29
+ "core"
30
+ ],
31
+ "license": "MIT",
32
+ "devDependencies": {
33
+ "@jest/test-sequencer": "^29.7.0",
34
+ "@types/jest": "^29.5.11",
35
+ "@types/node": "^20.11.24",
36
+ "jest": "^29.7.0",
37
+ "ts-jest": "^29.1.1",
38
+ "typescript": "^5.3.3"
39
+ }
40
+ }