@skillsmith/core 0.4.17 → 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/CHANGELOG.md +20 -0
- package/dist/.tsbuildinfo +1 -1
- package/dist/src/api/client.d.ts +19 -21
- package/dist/src/api/client.d.ts.map +1 -1
- package/dist/src/api/client.events.d.ts +39 -0
- package/dist/src/api/client.events.d.ts.map +1 -0
- package/dist/src/api/client.events.js +77 -0
- package/dist/src/api/client.events.js.map +1 -0
- package/dist/src/api/client.js +39 -33
- package/dist/src/api/client.js.map +1 -1
- package/dist/src/api/event-batcher.d.ts +81 -0
- package/dist/src/api/event-batcher.d.ts.map +1 -0
- package/dist/src/api/event-batcher.js +191 -0
- package/dist/src/api/event-batcher.js.map +1 -0
- package/dist/src/api/index.d.ts +1 -0
- package/dist/src/api/index.d.ts.map +1 -1
- package/dist/src/api/index.js +2 -0
- package/dist/src/api/index.js.map +1 -1
- package/dist/src/api/schemas.d.ts +58 -0
- package/dist/src/api/schemas.d.ts.map +1 -1
- package/dist/src/api/schemas.js +45 -0
- package/dist/src/api/schemas.js.map +1 -1
- package/dist/src/db/migration-runner.d.ts +44 -0
- package/dist/src/db/migration-runner.d.ts.map +1 -0
- package/dist/src/db/migration-runner.js +175 -0
- package/dist/src/db/migration-runner.js.map +1 -0
- package/dist/src/db/migration.d.ts.map +1 -1
- package/dist/src/db/migration.js +2 -1
- package/dist/src/db/migration.js.map +1 -1
- package/dist/src/db/migrations/v12-risk-score-history.d.ts +10 -0
- package/dist/src/db/migrations/v12-risk-score-history.d.ts.map +1 -0
- package/dist/src/db/migrations/v12-risk-score-history.js +25 -0
- package/dist/src/db/migrations/v12-risk-score-history.js.map +1 -0
- package/dist/src/db/migrations/v13-team-tables.d.ts +11 -0
- package/dist/src/db/migrations/v13-team-tables.d.ts.map +1 -0
- package/dist/src/db/migrations/v13-team-tables.js +14 -0
- package/dist/src/db/migrations/v13-team-tables.js.map +1 -0
- package/dist/src/db/schema-sql.d.ts +16 -0
- package/dist/src/db/schema-sql.d.ts.map +1 -0
- package/dist/src/db/schema-sql.js +161 -0
- package/dist/src/db/schema-sql.js.map +1 -0
- package/dist/src/db/schema.d.ts +7 -32
- package/dist/src/db/schema.d.ts.map +1 -1
- package/dist/src/db/schema.js +13 -303
- package/dist/src/db/schema.js.map +1 -1
- package/dist/src/exports/repositories.d.ts +1 -0
- package/dist/src/exports/repositories.d.ts.map +1 -1
- package/dist/src/exports/repositories.js +4 -0
- package/dist/src/exports/repositories.js.map +1 -1
- package/dist/src/exports/services.d.ts +2 -1
- package/dist/src/exports/services.d.ts.map +1 -1
- package/dist/src/exports/services.js +1 -0
- package/dist/src/exports/services.js.map +1 -1
- package/dist/src/index.d.ts +1 -1
- package/dist/src/index.d.ts.map +1 -1
- package/dist/src/index.js +1 -1
- package/dist/src/index.js.map +1 -1
- package/dist/src/repositories/RiskScoreHistoryRepository.d.ts +37 -0
- package/dist/src/repositories/RiskScoreHistoryRepository.d.ts.map +1 -0
- package/dist/src/repositories/RiskScoreHistoryRepository.js +66 -0
- package/dist/src/repositories/RiskScoreHistoryRepository.js.map +1 -0
- package/dist/src/scoring/index.d.ts +1 -0
- package/dist/src/scoring/index.d.ts.map +1 -1
- package/dist/src/scoring/index.js +1 -0
- package/dist/src/scoring/index.js.map +1 -1
- package/dist/src/scoring/quality-score.d.ts +49 -0
- package/dist/src/scoring/quality-score.d.ts.map +1 -0
- package/dist/src/scoring/quality-score.js +73 -0
- package/dist/src/scoring/quality-score.js.map +1 -0
- package/dist/src/scripts/__tests__/scan-imported-skills.test.js +5 -0
- package/dist/src/scripts/__tests__/scan-imported-skills.test.js.map +1 -1
- package/dist/src/security/index.d.ts +2 -0
- package/dist/src/security/index.d.ts.map +1 -1
- package/dist/src/security/index.js +2 -0
- package/dist/src/security/index.js.map +1 -1
- package/dist/src/security/risk-trend.d.ts +21 -0
- package/dist/src/security/risk-trend.d.ts.map +1 -0
- package/dist/src/security/risk-trend.js +81 -0
- package/dist/src/security/risk-trend.js.map +1 -0
- package/dist/src/security/scanner/SecurityScanner.d.ts +2 -0
- package/dist/src/security/scanner/SecurityScanner.d.ts.map +1 -1
- package/dist/src/security/scanner/SecurityScanner.helpers.d.ts.map +1 -1
- package/dist/src/security/scanner/SecurityScanner.helpers.js +14 -8
- package/dist/src/security/scanner/SecurityScanner.helpers.js.map +1 -1
- package/dist/src/security/scanner/SecurityScanner.js +55 -1
- package/dist/src/security/scanner/SecurityScanner.js.map +1 -1
- package/dist/src/security/scanner/index.d.ts +1 -1
- package/dist/src/security/scanner/index.d.ts.map +1 -1
- package/dist/src/security/scanner/index.js +1 -1
- package/dist/src/security/scanner/index.js.map +1 -1
- package/dist/src/security/scanner/patterns.d.ts +6 -0
- package/dist/src/security/scanner/patterns.d.ts.map +1 -1
- package/dist/src/security/scanner/patterns.js +25 -0
- package/dist/src/security/scanner/patterns.js.map +1 -1
- package/dist/src/security/scanner/types.d.ts +2 -1
- package/dist/src/security/scanner/types.d.ts.map +1 -1
- package/dist/src/security/scanner/weights.d.ts.map +1 -1
- package/dist/src/security/scanner/weights.js +1 -0
- package/dist/src/security/scanner/weights.js.map +1 -1
- package/dist/src/services/skill-config-schema.d.ts +36 -0
- package/dist/src/services/skill-config-schema.d.ts.map +1 -0
- package/dist/src/services/skill-config-schema.js +76 -0
- package/dist/src/services/skill-config-schema.js.map +1 -0
- package/dist/src/services/skill-installation.feedback.d.ts +24 -0
- package/dist/src/services/skill-installation.feedback.d.ts.map +1 -0
- package/dist/src/services/skill-installation.feedback.js +37 -0
- package/dist/src/services/skill-installation.feedback.js.map +1 -0
- package/dist/src/services/skill-installation.helpers.d.ts +33 -7
- package/dist/src/services/skill-installation.helpers.d.ts.map +1 -1
- package/dist/src/services/skill-installation.helpers.js +74 -32
- package/dist/src/services/skill-installation.helpers.js.map +1 -1
- package/dist/src/services/skill-installation.service.d.ts +8 -16
- package/dist/src/services/skill-installation.service.d.ts.map +1 -1
- package/dist/src/services/skill-installation.service.js +86 -37
- package/dist/src/services/skill-installation.service.js.map +1 -1
- package/dist/src/services/skill-installation.types.d.ts +22 -0
- package/dist/src/services/skill-installation.types.d.ts.map +1 -1
- package/dist/src/services/skill-installation.types.js.map +1 -1
- package/dist/src/types.d.ts +2 -0
- package/dist/src/types.d.ts.map +1 -1
- package/dist/tests/SecurityScanner.ai-defence.test.d.ts +6 -0
- package/dist/tests/SecurityScanner.ai-defence.test.d.ts.map +1 -0
- package/dist/tests/SecurityScanner.ai-defence.test.js +221 -0
- package/dist/tests/SecurityScanner.ai-defence.test.js.map +1 -0
- package/dist/tests/SecurityScanner.performance.test.d.ts +6 -0
- package/dist/tests/SecurityScanner.performance.test.d.ts.map +1 -0
- package/dist/tests/SecurityScanner.performance.test.js +132 -0
- package/dist/tests/SecurityScanner.performance.test.js.map +1 -0
- package/dist/tests/SecurityScanner.scoring.test.d.ts +6 -0
- package/dist/tests/SecurityScanner.scoring.test.d.ts.map +1 -0
- package/dist/tests/SecurityScanner.scoring.test.js +197 -0
- package/dist/tests/SecurityScanner.scoring.test.js.map +1 -0
- package/dist/tests/SecurityScanner.test.d.ts +2 -2
- package/dist/tests/SecurityScanner.test.js +2 -520
- package/dist/tests/SecurityScanner.test.js.map +1 -1
- package/dist/tests/SkillMatcher.test.js +5 -5
- package/dist/tests/SkillMatcher.test.js.map +1 -1
- package/dist/tests/db/schema-migrations.test.js +8 -6
- package/dist/tests/db/schema-migrations.test.js.map +1 -1
- package/dist/tests/integration/events-batch-contract.test.d.ts +12 -0
- package/dist/tests/integration/events-batch-contract.test.d.ts.map +1 -0
- package/dist/tests/integration/events-batch-contract.test.js +69 -0
- package/dist/tests/integration/events-batch-contract.test.js.map +1 -0
- package/dist/tests/scoring/quality-score.test.d.ts +7 -0
- package/dist/tests/scoring/quality-score.test.d.ts.map +1 -0
- package/dist/tests/scoring/quality-score.test.js +78 -0
- package/dist/tests/scoring/quality-score.test.js.map +1 -0
- package/dist/tests/security/ContinuousSecurity.false-positives.test.d.ts +6 -0
- package/dist/tests/security/ContinuousSecurity.false-positives.test.d.ts.map +1 -0
- package/dist/tests/security/ContinuousSecurity.false-positives.test.js +89 -0
- package/dist/tests/security/ContinuousSecurity.false-positives.test.js.map +1 -0
- package/dist/tests/security/ContinuousSecurity.performance.test.d.ts +6 -0
- package/dist/tests/security/ContinuousSecurity.performance.test.d.ts.map +1 -0
- package/dist/tests/security/ContinuousSecurity.performance.test.js +177 -0
- package/dist/tests/security/ContinuousSecurity.performance.test.js.map +1 -0
- package/dist/tests/security/ContinuousSecurity.reporting.test.d.ts +6 -0
- package/dist/tests/security/ContinuousSecurity.reporting.test.d.ts.map +1 -0
- package/dist/tests/security/ContinuousSecurity.reporting.test.js +106 -0
- package/dist/tests/security/ContinuousSecurity.reporting.test.js.map +1 -0
- package/dist/tests/security/ContinuousSecurity.test.d.ts +9 -2
- package/dist/tests/security/ContinuousSecurity.test.d.ts.map +1 -1
- package/dist/tests/security/ContinuousSecurity.test.js +9 -336
- package/dist/tests/security/ContinuousSecurity.test.js.map +1 -1
- package/dist/tests/security/pii-detection.test.d.ts +7 -0
- package/dist/tests/security/pii-detection.test.d.ts.map +1 -0
- package/dist/tests/security/pii-detection.test.js +91 -0
- package/dist/tests/security/pii-detection.test.js.map +1 -0
- package/dist/tests/security/risk-trend.test.d.ts +6 -0
- package/dist/tests/security/risk-trend.test.d.ts.map +1 -0
- package/dist/tests/security/risk-trend.test.js +68 -0
- package/dist/tests/security/risk-trend.test.js.map +1 -0
- package/dist/tests/security/scanner-regression-guard.test.d.ts +12 -0
- package/dist/tests/security/scanner-regression-guard.test.d.ts.map +1 -0
- package/dist/tests/security/scanner-regression-guard.test.js +111 -0
- package/dist/tests/security/scanner-regression-guard.test.js.map +1 -0
- package/dist/tests/services/aidefence-feedback.test.d.ts +6 -0
- package/dist/tests/services/aidefence-feedback.test.d.ts.map +1 -0
- package/dist/tests/services/aidefence-feedback.test.js +115 -0
- package/dist/tests/services/aidefence-feedback.test.js.map +1 -0
- package/dist/tests/services/dep-quarantine-check.test.d.ts +5 -0
- package/dist/tests/services/dep-quarantine-check.test.d.ts.map +1 -0
- package/dist/tests/services/dep-quarantine-check.test.js +92 -0
- package/dist/tests/services/dep-quarantine-check.test.js.map +1 -0
- package/dist/tests/services/skill-config-schema.test.d.ts +5 -0
- package/dist/tests/services/skill-config-schema.test.d.ts.map +1 -0
- package/dist/tests/services/skill-config-schema.test.js +98 -0
- package/dist/tests/services/skill-config-schema.test.js.map +1 -0
- package/dist/tests/unit/api-client-events.test.d.ts +10 -0
- package/dist/tests/unit/api-client-events.test.d.ts.map +1 -0
- package/dist/tests/unit/api-client-events.test.js +73 -0
- package/dist/tests/unit/api-client-events.test.js.map +1 -0
- package/dist/tests/unit/event-batcher.test.d.ts +13 -0
- package/dist/tests/unit/event-batcher.test.d.ts.map +1 -0
- package/dist/tests/unit/event-batcher.test.js +155 -0
- package/dist/tests/unit/event-batcher.test.js.map +1 -0
- package/dist/tests/unit/services/skill-installation-extended.test.d.ts +8 -0
- package/dist/tests/unit/services/skill-installation-extended.test.d.ts.map +1 -0
- package/dist/tests/unit/services/skill-installation-extended.test.js +423 -0
- package/dist/tests/unit/services/skill-installation-extended.test.js.map +1 -0
- package/dist/tests/unit/services/skill-installation.service.test.js +0 -390
- package/dist/tests/unit/services/skill-installation.service.test.js.map +1 -1
- package/package.json +7 -7
package/dist/src/api/client.d.ts
CHANGED
|
@@ -2,14 +2,8 @@
|
|
|
2
2
|
* Skillsmith API Client
|
|
3
3
|
* @module api/client
|
|
4
4
|
*
|
|
5
|
-
* SMI-1244: API client for
|
|
6
|
-
* SMI-
|
|
7
|
-
*
|
|
8
|
-
* Provides methods to interact with the Skillsmith API:
|
|
9
|
-
* - search: Search skills with filters
|
|
10
|
-
* - getSkill: Get skill by ID
|
|
11
|
-
* - getRecommendations: Get skill recommendations based on tech stack
|
|
12
|
-
* - recordEvent: Record telemetry event
|
|
5
|
+
* SMI-1244: API client for Supabase endpoints. SMI-1258: Zod response validation.
|
|
6
|
+
* SMI-4119: `recordEvent` batches via EventBatcher (see client.events.ts).
|
|
13
7
|
*/
|
|
14
8
|
import type { Skill, TrustTier, SearchOptions } from '../types/skill.js';
|
|
15
9
|
export { generateAnonymousId } from './utils.js';
|
|
@@ -56,6 +50,8 @@ export interface ApiSearchResult {
|
|
|
56
50
|
quarantined?: boolean;
|
|
57
51
|
/** SHA-256 hash of SKILL.md content at index time */
|
|
58
52
|
content_hash?: string | null;
|
|
53
|
+
/** SMI-3672: Raw SKILL.md content (only when include_content=true) */
|
|
54
|
+
content?: string | null;
|
|
59
55
|
created_at?: string;
|
|
60
56
|
updated_at?: string;
|
|
61
57
|
}
|
|
@@ -96,17 +92,7 @@ export interface ApiClientConfig {
|
|
|
96
92
|
offlineMode?: boolean;
|
|
97
93
|
}
|
|
98
94
|
/**
|
|
99
|
-
* Skillsmith API Client
|
|
100
|
-
*
|
|
101
|
-
* @example
|
|
102
|
-
* ```typescript
|
|
103
|
-
* const client = new SkillsmithApiClient({
|
|
104
|
-
* anonKey: process.env.SUPABASE_ANON_KEY,
|
|
105
|
-
* });
|
|
106
|
-
*
|
|
107
|
-
* const results = await client.search({ query: 'testing' });
|
|
108
|
-
* console.log(results.data);
|
|
109
|
-
* ```
|
|
95
|
+
* Skillsmith API Client. See module docstring for SMI refs.
|
|
110
96
|
*/
|
|
111
97
|
export declare class SkillsmithApiClient {
|
|
112
98
|
private baseUrl;
|
|
@@ -116,6 +102,8 @@ export declare class SkillsmithApiClient {
|
|
|
116
102
|
private maxRetries;
|
|
117
103
|
private debug;
|
|
118
104
|
private offlineMode;
|
|
105
|
+
/** SMI-4119: Lazily-initialized batcher for telemetry events. */
|
|
106
|
+
private eventBatcher;
|
|
119
107
|
constructor(config?: ApiClientConfig);
|
|
120
108
|
/**
|
|
121
109
|
* Check if client is running in offline mode
|
|
@@ -152,8 +140,11 @@ export declare class SkillsmithApiClient {
|
|
|
152
140
|
/**
|
|
153
141
|
* Get skill by ID
|
|
154
142
|
* SMI-1258: Validates response against SingleSkillResponseSchema
|
|
143
|
+
* SMI-3672: Added includeContent option to fetch SKILL.md content
|
|
155
144
|
*/
|
|
156
|
-
getSkill(id: string
|
|
145
|
+
getSkill(id: string, options?: {
|
|
146
|
+
includeContent?: boolean;
|
|
147
|
+
}): Promise<ApiResponse<ApiSearchResult>>;
|
|
157
148
|
/**
|
|
158
149
|
* Get skill recommendations based on tech stack
|
|
159
150
|
* SMI-1258: Validates response against SearchResponseSchema
|
|
@@ -161,11 +152,18 @@ export declare class SkillsmithApiClient {
|
|
|
161
152
|
getRecommendations(request: RecommendationRequest): Promise<ApiResponse<ApiSearchResult[]>>;
|
|
162
153
|
/**
|
|
163
154
|
* Record telemetry event
|
|
164
|
-
* SMI-
|
|
155
|
+
* SMI-4119: Enqueue to in-memory batcher instead of POSTing immediately.
|
|
156
|
+
* Returns `{ ok: true }` synchronously — batcher handles failures silently,
|
|
157
|
+
* matching the prior "fail silently" contract for telemetry.
|
|
165
158
|
*/
|
|
166
159
|
recordEvent(event: TelemetryEvent): Promise<{
|
|
167
160
|
ok: boolean;
|
|
168
161
|
}>;
|
|
162
|
+
/** SMI-4119: Flush queued telemetry events (drain the batcher). */
|
|
163
|
+
flushEvents(): Promise<void>;
|
|
164
|
+
/** SMI-4119: Dispose batcher (detach exit listeners, clear timers). */
|
|
165
|
+
disposeEventBatcher(): void;
|
|
166
|
+
private getOrCreateBatcher;
|
|
169
167
|
/**
|
|
170
168
|
* Check API health status
|
|
171
169
|
*/
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../../../src/api/client.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../../../src/api/client.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Event batching glue for SkillsmithApiClient
|
|
3
|
+
* @module api/client.events
|
|
4
|
+
*
|
|
5
|
+
* SMI-4119: Keeps batcher wiring out of client.ts to stay under the 500-line cap.
|
|
6
|
+
*
|
|
7
|
+
* This module exposes a small helper that builds a flush function bound to a
|
|
8
|
+
* client's base URL / auth headers and posts batches to `POST /events`.
|
|
9
|
+
*/
|
|
10
|
+
import type { TelemetryEvent } from './client.js';
|
|
11
|
+
import { type EventBatcher } from './event-batcher.js';
|
|
12
|
+
/**
|
|
13
|
+
* Inputs required to POST a batch to `/events`.
|
|
14
|
+
* Kept narrow so we don't expose private client fields.
|
|
15
|
+
*/
|
|
16
|
+
export interface BatchPostContext {
|
|
17
|
+
baseUrl: string;
|
|
18
|
+
anonKey: string | undefined;
|
|
19
|
+
apiKey: string | undefined;
|
|
20
|
+
/** Request timeout in ms. */
|
|
21
|
+
timeout: number;
|
|
22
|
+
}
|
|
23
|
+
/**
|
|
24
|
+
* Build a flush function that POSTs a batch to `${baseUrl}/events`.
|
|
25
|
+
*
|
|
26
|
+
* Emits `X-Skillsmith-Batched: true` so the edge function can stamp
|
|
27
|
+
* `audit_logs.metadata.batched` and post-deploy SQL can distinguish
|
|
28
|
+
* batched vs stale single-client traffic.
|
|
29
|
+
*
|
|
30
|
+
* Throws on non-2xx responses so the batcher can retry.
|
|
31
|
+
*/
|
|
32
|
+
export declare function createBatchFlushFn(ctx: () => BatchPostContext): (events: TelemetryEvent[]) => Promise<void>;
|
|
33
|
+
/**
|
|
34
|
+
* Build an EventBatcher that POSTs to `${baseUrl}/events` using the live
|
|
35
|
+
* auth context returned by `ctx()`. Lazily re-reads context on each flush so
|
|
36
|
+
* config changes (e.g. API key rotation) are honored.
|
|
37
|
+
*/
|
|
38
|
+
export declare function buildClientEventBatcher(ctx: () => BatchPostContext): EventBatcher;
|
|
39
|
+
//# sourceMappingURL=client.events.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"client.events.d.ts","sourceRoot":"","sources":["../../../src/api/client.events.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,aAAa,CAAA;AAEjD,OAAO,EAAsB,KAAK,YAAY,EAAE,MAAM,oBAAoB,CAAA;AAE1E;;;GAGG;AACH,MAAM,WAAW,gBAAgB;IAC/B,OAAO,EAAE,MAAM,CAAA;IACf,OAAO,EAAE,MAAM,GAAG,SAAS,CAAA;IAC3B,MAAM,EAAE,MAAM,GAAG,SAAS,CAAA;IAC1B,6BAA6B;IAC7B,OAAO,EAAE,MAAM,CAAA;CAChB;AAED;;;;;;;;GAQG;AACH,wBAAgB,kBAAkB,CAChC,GAAG,EAAE,MAAM,gBAAgB,GAC1B,CAAC,MAAM,EAAE,cAAc,EAAE,KAAK,OAAO,CAAC,IAAI,CAAC,CAmC7C;AAED;;;;GAIG;AACH,wBAAgB,uBAAuB,CAAC,GAAG,EAAE,MAAM,gBAAgB,GAAG,YAAY,CAEjF"}
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Event batching glue for SkillsmithApiClient
|
|
3
|
+
* @module api/client.events
|
|
4
|
+
*
|
|
5
|
+
* SMI-4119: Keeps batcher wiring out of client.ts to stay under the 500-line cap.
|
|
6
|
+
*
|
|
7
|
+
* This module exposes a small helper that builds a flush function bound to a
|
|
8
|
+
* client's base URL / auth headers and posts batches to `POST /events`.
|
|
9
|
+
*/
|
|
10
|
+
import { buildRequestHeaders } from './utils.js';
|
|
11
|
+
import { createEventBatcher } from './event-batcher.js';
|
|
12
|
+
/**
|
|
13
|
+
* Build a flush function that POSTs a batch to `${baseUrl}/events`.
|
|
14
|
+
*
|
|
15
|
+
* Emits `X-Skillsmith-Batched: true` so the edge function can stamp
|
|
16
|
+
* `audit_logs.metadata.batched` and post-deploy SQL can distinguish
|
|
17
|
+
* batched vs stale single-client traffic.
|
|
18
|
+
*
|
|
19
|
+
* Throws on non-2xx responses so the batcher can retry.
|
|
20
|
+
*/
|
|
21
|
+
export function createBatchFlushFn(ctx) {
|
|
22
|
+
return async (events) => {
|
|
23
|
+
if (events.length === 0)
|
|
24
|
+
return;
|
|
25
|
+
const { baseUrl, anonKey, apiKey, timeout } = ctx();
|
|
26
|
+
// SMI-4119: Correlation ID per batch POST so operators can join all
|
|
27
|
+
// `audit_logs` rows inserted from one client flush. Format matches the
|
|
28
|
+
// edge function's validation regex `[a-zA-Z0-9_-]{1,64}`.
|
|
29
|
+
const batchId = generateBatchId();
|
|
30
|
+
const controller = new AbortController();
|
|
31
|
+
const timer = setTimeout(() => controller.abort(), timeout);
|
|
32
|
+
try {
|
|
33
|
+
const res = await fetch(`${baseUrl}/events`, {
|
|
34
|
+
method: 'POST',
|
|
35
|
+
headers: {
|
|
36
|
+
...buildRequestHeaders(anonKey),
|
|
37
|
+
...(apiKey ? { 'X-API-Key': apiKey } : {}),
|
|
38
|
+
'X-Skillsmith-Batched': 'true',
|
|
39
|
+
'X-Skillsmith-Batch-Id': batchId,
|
|
40
|
+
},
|
|
41
|
+
body: JSON.stringify({ events }),
|
|
42
|
+
signal: controller.signal,
|
|
43
|
+
});
|
|
44
|
+
if (!res.ok) {
|
|
45
|
+
// Drain the body to free the socket; ignore parse errors.
|
|
46
|
+
await res.text().catch(() => '');
|
|
47
|
+
throw new Error(`events batch POST failed: ${res.status}`);
|
|
48
|
+
}
|
|
49
|
+
// Drain body to allow keep-alive reuse; ignore errors.
|
|
50
|
+
await res.text().catch(() => '');
|
|
51
|
+
}
|
|
52
|
+
finally {
|
|
53
|
+
clearTimeout(timer);
|
|
54
|
+
}
|
|
55
|
+
};
|
|
56
|
+
}
|
|
57
|
+
/**
|
|
58
|
+
* Build an EventBatcher that POSTs to `${baseUrl}/events` using the live
|
|
59
|
+
* auth context returned by `ctx()`. Lazily re-reads context on each flush so
|
|
60
|
+
* config changes (e.g. API key rotation) are honored.
|
|
61
|
+
*/
|
|
62
|
+
export function buildClientEventBatcher(ctx) {
|
|
63
|
+
return createEventBatcher(createBatchFlushFn(ctx));
|
|
64
|
+
}
|
|
65
|
+
/**
|
|
66
|
+
* Generate a short, URL-safe correlation ID for a batch POST.
|
|
67
|
+
* Uses `crypto.randomUUID` when available; falls back to Math.random so the
|
|
68
|
+
* code runs in environments without the Web Crypto API.
|
|
69
|
+
*/
|
|
70
|
+
function generateBatchId() {
|
|
71
|
+
const g = globalThis;
|
|
72
|
+
if (g.crypto && typeof g.crypto.randomUUID === 'function') {
|
|
73
|
+
return g.crypto.randomUUID();
|
|
74
|
+
}
|
|
75
|
+
return `b-${Date.now().toString(36)}-${Math.random().toString(36).slice(2, 10)}`;
|
|
76
|
+
}
|
|
77
|
+
//# sourceMappingURL=client.events.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"client.events.js","sourceRoot":"","sources":["../../../src/api/client.events.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAGH,OAAO,EAAE,mBAAmB,EAAE,MAAM,YAAY,CAAA;AAChD,OAAO,EAAE,kBAAkB,EAAqB,MAAM,oBAAoB,CAAA;AAc1E;;;;;;;;GAQG;AACH,MAAM,UAAU,kBAAkB,CAChC,GAA2B;IAE3B,OAAO,KAAK,EAAE,MAAwB,EAAiB,EAAE;QACvD,IAAI,MAAM,CAAC,MAAM,KAAK,CAAC;YAAE,OAAM;QAC/B,MAAM,EAAE,OAAO,EAAE,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,GAAG,GAAG,EAAE,CAAA;QAEnD,oEAAoE;QACpE,uEAAuE;QACvE,0DAA0D;QAC1D,MAAM,OAAO,GAAG,eAAe,EAAE,CAAA;QAEjC,MAAM,UAAU,GAAG,IAAI,eAAe,EAAE,CAAA;QACxC,MAAM,KAAK,GAAG,UAAU,CAAC,GAAG,EAAE,CAAC,UAAU,CAAC,KAAK,EAAE,EAAE,OAAO,CAAC,CAAA;QAC3D,IAAI,CAAC;YACH,MAAM,GAAG,GAAG,MAAM,KAAK,CAAC,GAAG,OAAO,SAAS,EAAE;gBAC3C,MAAM,EAAE,MAAM;gBACd,OAAO,EAAE;oBACP,GAAG,mBAAmB,CAAC,OAAO,CAAC;oBAC/B,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,WAAW,EAAE,MAAM,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;oBAC1C,sBAAsB,EAAE,MAAM;oBAC9B,uBAAuB,EAAE,OAAO;iBACjC;gBACD,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,EAAE,MAAM,EAAE,CAAC;gBAChC,MAAM,EAAE,UAAU,CAAC,MAAM;aAC1B,CAAC,CAAA;YACF,IAAI,CAAC,GAAG,CAAC,EAAE,EAAE,CAAC;gBACZ,0DAA0D;gBAC1D,MAAM,GAAG,CAAC,IAAI,EAAE,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,EAAE,CAAC,CAAA;gBAChC,MAAM,IAAI,KAAK,CAAC,6BAA6B,GAAG,CAAC,MAAM,EAAE,CAAC,CAAA;YAC5D,CAAC;YACD,uDAAuD;YACvD,MAAM,GAAG,CAAC,IAAI,EAAE,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,EAAE,CAAC,CAAA;QAClC,CAAC;gBAAS,CAAC;YACT,YAAY,CAAC,KAAK,CAAC,CAAA;QACrB,CAAC;IACH,CAAC,CAAA;AACH,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,uBAAuB,CAAC,GAA2B;IACjE,OAAO,kBAAkB,CAAC,kBAAkB,CAAC,GAAG,CAAC,CAAC,CAAA;AACpD,CAAC;AAED;;;;GAIG;AACH,SAAS,eAAe;IACtB,MAAM,CAAC,GAAG,UAAwD,CAAA;IAClE,IAAI,CAAC,CAAC,MAAM,IAAI,OAAO,CAAC,CAAC,MAAM,CAAC,UAAU,KAAK,UAAU,EAAE,CAAC;QAC1D,OAAO,CAAC,CAAC,MAAM,CAAC,UAAU,EAAE,CAAA;IAC9B,CAAC;IACD,OAAO,KAAK,IAAI,CAAC,GAAG,EAAE,CAAC,QAAQ,CAAC,EAAE,CAAC,IAAI,IAAI,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,EAAE,CAAA;AAClF,CAAC"}
|
package/dist/src/api/client.js
CHANGED
|
@@ -2,20 +2,15 @@
|
|
|
2
2
|
* Skillsmith API Client
|
|
3
3
|
* @module api/client
|
|
4
4
|
*
|
|
5
|
-
* SMI-1244: API client for
|
|
6
|
-
* SMI-
|
|
7
|
-
*
|
|
8
|
-
* Provides methods to interact with the Skillsmith API:
|
|
9
|
-
* - search: Search skills with filters
|
|
10
|
-
* - getSkill: Get skill by ID
|
|
11
|
-
* - getRecommendations: Get skill recommendations based on tech stack
|
|
12
|
-
* - recordEvent: Record telemetry event
|
|
5
|
+
* SMI-1244: API client for Supabase endpoints. SMI-1258: Zod response validation.
|
|
6
|
+
* SMI-4119: `recordEvent` batches via EventBatcher (see client.events.ts).
|
|
13
7
|
*/
|
|
14
8
|
import { SkillsmithError, ErrorCodes } from '../errors.js';
|
|
15
9
|
// Import from extracted modules
|
|
16
|
-
import { SearchResponseSchema, SingleSkillResponseSchema
|
|
10
|
+
import { SearchResponseSchema, SingleSkillResponseSchema } from './schemas.js';
|
|
17
11
|
import { calculateBackoff, buildRequestHeaders, DEFAULT_BASE_URL, PRODUCTION_ANON_KEY, } from './utils.js';
|
|
18
12
|
import { checkApiHealth } from './client.health.js';
|
|
13
|
+
import { buildClientEventBatcher } from './client.events.js';
|
|
19
14
|
// Re-export for backwards compatibility
|
|
20
15
|
export { generateAnonymousId } from './utils.js';
|
|
21
16
|
export { checkApiHealth } from './client.health.js';
|
|
@@ -38,17 +33,7 @@ export class ApiClientError extends Error {
|
|
|
38
33
|
// API Client Class
|
|
39
34
|
// ============================================================================
|
|
40
35
|
/**
|
|
41
|
-
* Skillsmith API Client
|
|
42
|
-
*
|
|
43
|
-
* @example
|
|
44
|
-
* ```typescript
|
|
45
|
-
* const client = new SkillsmithApiClient({
|
|
46
|
-
* anonKey: process.env.SUPABASE_ANON_KEY,
|
|
47
|
-
* });
|
|
48
|
-
*
|
|
49
|
-
* const results = await client.search({ query: 'testing' });
|
|
50
|
-
* console.log(results.data);
|
|
51
|
-
* ```
|
|
36
|
+
* Skillsmith API Client. See module docstring for SMI refs.
|
|
52
37
|
*/
|
|
53
38
|
export class SkillsmithApiClient {
|
|
54
39
|
baseUrl;
|
|
@@ -58,6 +43,8 @@ export class SkillsmithApiClient {
|
|
|
58
43
|
maxRetries;
|
|
59
44
|
debug;
|
|
60
45
|
offlineMode;
|
|
46
|
+
/** SMI-4119: Lazily-initialized batcher for telemetry events. */
|
|
47
|
+
eventBatcher = null;
|
|
61
48
|
constructor(config = {}) {
|
|
62
49
|
// SMI-1948: DEFAULT_BASE_URL now always has a value (production URL fallback)
|
|
63
50
|
// Priority: config.baseUrl > DEFAULT_BASE_URL (which checks env vars internally)
|
|
@@ -230,10 +217,12 @@ export class SkillsmithApiClient {
|
|
|
230
217
|
/**
|
|
231
218
|
* Get skill by ID
|
|
232
219
|
* SMI-1258: Validates response against SingleSkillResponseSchema
|
|
220
|
+
* SMI-3672: Added includeContent option to fetch SKILL.md content
|
|
233
221
|
*/
|
|
234
|
-
async getSkill(id) {
|
|
222
|
+
async getSkill(id, options) {
|
|
235
223
|
const encodedId = encodeURIComponent(id);
|
|
236
|
-
|
|
224
|
+
const contentParam = options?.includeContent ? '&include_content=true' : '';
|
|
225
|
+
return this.request(`/skills-get?id=${encodedId}${contentParam}`, {}, SingleSkillResponseSchema);
|
|
237
226
|
}
|
|
238
227
|
/**
|
|
239
228
|
* Get skill recommendations based on tech stack
|
|
@@ -247,21 +236,38 @@ export class SkillsmithApiClient {
|
|
|
247
236
|
}
|
|
248
237
|
/**
|
|
249
238
|
* Record telemetry event
|
|
250
|
-
* SMI-
|
|
239
|
+
* SMI-4119: Enqueue to in-memory batcher instead of POSTing immediately.
|
|
240
|
+
* Returns `{ ok: true }` synchronously — batcher handles failures silently,
|
|
241
|
+
* matching the prior "fail silently" contract for telemetry.
|
|
251
242
|
*/
|
|
252
243
|
async recordEvent(event) {
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
244
|
+
if (this.offlineMode)
|
|
245
|
+
return { ok: true };
|
|
246
|
+
this.getOrCreateBatcher().enqueue(event);
|
|
247
|
+
return { ok: true };
|
|
248
|
+
}
|
|
249
|
+
/** SMI-4119: Flush queued telemetry events (drain the batcher). */
|
|
250
|
+
async flushEvents() {
|
|
251
|
+
if (this.eventBatcher)
|
|
252
|
+
await this.eventBatcher.flush();
|
|
253
|
+
}
|
|
254
|
+
/** SMI-4119: Dispose batcher (detach exit listeners, clear timers). */
|
|
255
|
+
disposeEventBatcher() {
|
|
256
|
+
if (this.eventBatcher) {
|
|
257
|
+
this.eventBatcher.dispose();
|
|
258
|
+
this.eventBatcher = null;
|
|
259
259
|
}
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
260
|
+
}
|
|
261
|
+
getOrCreateBatcher() {
|
|
262
|
+
if (!this.eventBatcher) {
|
|
263
|
+
this.eventBatcher = buildClientEventBatcher(() => ({
|
|
264
|
+
baseUrl: this.baseUrl,
|
|
265
|
+
anonKey: this.anonKey,
|
|
266
|
+
apiKey: this.apiKey,
|
|
267
|
+
timeout: this.timeout,
|
|
268
|
+
}));
|
|
264
269
|
}
|
|
270
|
+
return this.eventBatcher;
|
|
265
271
|
}
|
|
266
272
|
/**
|
|
267
273
|
* Check API health status
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"client.js","sourceRoot":"","sources":["../../../src/api/client.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"client.js","sourceRoot":"","sources":["../../../src/api/client.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* EventBatcher — client-side telemetry batcher
|
|
3
|
+
* @module api/event-batcher
|
|
4
|
+
*
|
|
5
|
+
* SMI-4119: Batch telemetry events to reduce Supabase edge function invocations.
|
|
6
|
+
*
|
|
7
|
+
* Flushes on:
|
|
8
|
+
* - size : queue reaches `maxBatchSize` (default 20)
|
|
9
|
+
* - time : `maxWaitMs` elapsed since first enqueue in the current batch (default 10s)
|
|
10
|
+
* - exit : `beforeExit` / `SIGINT` / `SIGTERM` (drain with `drainTimeoutMs`, default 2s)
|
|
11
|
+
*
|
|
12
|
+
* POSTs to `/events` with `{events: [...]}` and `X-Skillsmith-Batched: true` header.
|
|
13
|
+
* On failure: retry once after `retryDelayMs` (default 2s); on second failure, drop silently
|
|
14
|
+
* (matches the existing "fail silently" contract on telemetry).
|
|
15
|
+
*/
|
|
16
|
+
import type { TelemetryEvent } from './client.js';
|
|
17
|
+
/**
|
|
18
|
+
* Flush function signature. Returns a resolved promise on success, rejects on failure.
|
|
19
|
+
* Must throw / reject on non-2xx responses so the batcher can retry.
|
|
20
|
+
*/
|
|
21
|
+
export type BatchFlushFn = (events: TelemetryEvent[]) => Promise<void>;
|
|
22
|
+
/**
|
|
23
|
+
* Construction options for EventBatcher (all optional; defaults documented inline).
|
|
24
|
+
*/
|
|
25
|
+
export interface EventBatcherOptions {
|
|
26
|
+
/** Max events per batch before forced flush. Default: 20 (aligns with edge function max). */
|
|
27
|
+
maxBatchSize?: number;
|
|
28
|
+
/** Max ms to wait after first enqueue before flushing. Default: 10_000. */
|
|
29
|
+
maxWaitMs?: number;
|
|
30
|
+
/** Delay before retry on first flush failure. Default: 2_000. */
|
|
31
|
+
retryDelayMs?: number;
|
|
32
|
+
/** Max time to wait during process-exit drain. Default: 2_000. */
|
|
33
|
+
drainTimeoutMs?: number;
|
|
34
|
+
/** Attach process-exit listeners. Default: true. Disable in tests to avoid handler leaks. */
|
|
35
|
+
registerExitHandlers?: boolean;
|
|
36
|
+
}
|
|
37
|
+
/**
|
|
38
|
+
* In-memory batcher. Single-process, fire-and-forget.
|
|
39
|
+
*/
|
|
40
|
+
export declare class EventBatcher {
|
|
41
|
+
private queue;
|
|
42
|
+
private timer;
|
|
43
|
+
private activeFlush;
|
|
44
|
+
private readonly maxBatchSize;
|
|
45
|
+
private readonly maxWaitMs;
|
|
46
|
+
private readonly retryDelayMs;
|
|
47
|
+
private readonly drainTimeoutMs;
|
|
48
|
+
private readonly flushFn;
|
|
49
|
+
private exitHandlersAttached;
|
|
50
|
+
private disposed;
|
|
51
|
+
constructor(flushFn: BatchFlushFn, options?: EventBatcherOptions);
|
|
52
|
+
/**
|
|
53
|
+
* Enqueue an event. Flushes immediately if the batch reaches `maxBatchSize`.
|
|
54
|
+
* Fire-and-forget — errors are swallowed.
|
|
55
|
+
*/
|
|
56
|
+
enqueue(event: TelemetryEvent): void;
|
|
57
|
+
/**
|
|
58
|
+
* Force a flush of any queued events. Resolves when the in-flight POST completes.
|
|
59
|
+
* Used by shutdown paths and tests.
|
|
60
|
+
*/
|
|
61
|
+
flush(): Promise<void>;
|
|
62
|
+
/**
|
|
63
|
+
* Current queue depth (observability / tests).
|
|
64
|
+
*/
|
|
65
|
+
size(): number;
|
|
66
|
+
/**
|
|
67
|
+
* Detach exit handlers and clear timers. Call when disposing short-lived clients.
|
|
68
|
+
*/
|
|
69
|
+
dispose(): void;
|
|
70
|
+
private clearTimer;
|
|
71
|
+
private flushNow;
|
|
72
|
+
private doFlushWithRetry;
|
|
73
|
+
private attachExitHandlers;
|
|
74
|
+
private detachExitHandlers;
|
|
75
|
+
private drainHandler;
|
|
76
|
+
}
|
|
77
|
+
/**
|
|
78
|
+
* Factory for an EventBatcher bound to a POST function.
|
|
79
|
+
*/
|
|
80
|
+
export declare function createEventBatcher(flushFn: BatchFlushFn, options?: EventBatcherOptions): EventBatcher;
|
|
81
|
+
//# sourceMappingURL=event-batcher.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"event-batcher.d.ts","sourceRoot":"","sources":["../../../src/api/event-batcher.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAEH,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,aAAa,CAAA;AAEjD;;;GAGG;AACH,MAAM,MAAM,YAAY,GAAG,CAAC,MAAM,EAAE,cAAc,EAAE,KAAK,OAAO,CAAC,IAAI,CAAC,CAAA;AAEtE;;GAEG;AACH,MAAM,WAAW,mBAAmB;IAClC,6FAA6F;IAC7F,YAAY,CAAC,EAAE,MAAM,CAAA;IACrB,2EAA2E;IAC3E,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,iEAAiE;IACjE,YAAY,CAAC,EAAE,MAAM,CAAA;IACrB,kEAAkE;IAClE,cAAc,CAAC,EAAE,MAAM,CAAA;IACvB,6FAA6F;IAC7F,oBAAoB,CAAC,EAAE,OAAO,CAAA;CAC/B;AAOD;;GAEG;AACH,qBAAa,YAAY;IACvB,OAAO,CAAC,KAAK,CAAuB;IACpC,OAAO,CAAC,KAAK,CAA6C;IAC1D,OAAO,CAAC,WAAW,CAA6B;IAChD,OAAO,CAAC,QAAQ,CAAC,YAAY,CAAQ;IACrC,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAQ;IAClC,OAAO,CAAC,QAAQ,CAAC,YAAY,CAAQ;IACrC,OAAO,CAAC,QAAQ,CAAC,cAAc,CAAQ;IACvC,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAc;IACtC,OAAO,CAAC,oBAAoB,CAAQ;IACpC,OAAO,CAAC,QAAQ,CAAQ;gBAEZ,OAAO,EAAE,YAAY,EAAE,OAAO,GAAE,mBAAwB;IAYpE;;;OAGG;IACH,OAAO,CAAC,KAAK,EAAE,cAAc,GAAG,IAAI;IAuBpC;;;OAGG;IACG,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;IAK5B;;OAEG;IACH,IAAI,IAAI,MAAM;IAId;;OAEG;IACH,OAAO,IAAI,IAAI;IAMf,OAAO,CAAC,UAAU;YAOJ,QAAQ;YA+BR,gBAAgB;IAoB9B,OAAO,CAAC,kBAAkB;IAS1B,OAAO,CAAC,kBAAkB;IAS1B,OAAO,CAAC,YAAY,CAWnB;CACF;AAED;;GAEG;AACH,wBAAgB,kBAAkB,CAChC,OAAO,EAAE,YAAY,EACrB,OAAO,CAAC,EAAE,mBAAmB,GAC5B,YAAY,CAEd"}
|