@skillsmith/core 0.4.17 → 0.5.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.
- package/CHANGELOG.md +29 -0
- package/dist/.tsbuildinfo +1 -1
- package/dist/src/api/client.cache.d.ts +34 -0
- package/dist/src/api/client.cache.d.ts.map +1 -0
- package/dist/src/api/client.cache.js +37 -0
- package/dist/src/api/client.cache.js.map +1 -0
- package/dist/src/api/client.d.ts +32 -104
- 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 +65 -52
- package/dist/src/api/client.js.map +1 -1
- package/dist/src/api/client.types.d.ts +98 -0
- package/dist/src/api/client.types.d.ts.map +1 -0
- package/dist/src/api/client.types.js +22 -0
- package/dist/src/api/client.types.js.map +1 -0
- 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/audit/remote-audit.d.ts +28 -0
- package/dist/src/audit/remote-audit.d.ts.map +1 -0
- package/dist/src/audit/remote-audit.js +90 -0
- package/dist/src/audit/remote-audit.js.map +1 -0
- package/dist/src/audit/remote-audit.test.d.ts +2 -0
- package/dist/src/audit/remote-audit.test.d.ts.map +1 -0
- package/dist/src/audit/remote-audit.test.js +81 -0
- package/dist/src/audit/remote-audit.test.js.map +1 -0
- package/dist/src/data/generic-triggers.d.ts +24 -0
- package/dist/src/data/generic-triggers.d.ts.map +1 -0
- package/dist/src/data/generic-triggers.js +19 -0
- package/dist/src/data/generic-triggers.js.map +1 -0
- package/dist/src/data/generic-triggers.json +35 -0
- 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 +5 -1
- package/dist/src/index.d.ts.map +1 -1
- package/dist/src/index.js +5 -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/api/client.cache.test.d.ts +8 -0
- package/dist/tests/api/client.cache.test.d.ts.map +1 -0
- package/dist/tests/api/client.cache.test.js +128 -0
- package/dist/tests/api/client.cache.test.js.map +1 -0
- 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
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Client-side response cache wiring
|
|
3
|
+
* @module api/client.cache
|
|
4
|
+
*
|
|
5
|
+
* SMI-4120: Extracted from client.ts to keep the client under the 500-line
|
|
6
|
+
* audit:standards gate. Contains cache construction, the per-call option
|
|
7
|
+
* type, and the `withCache` helper used by search/getSkill/recommend.
|
|
8
|
+
*/
|
|
9
|
+
import { ApiCache, type CacheConfig } from './cache.js';
|
|
10
|
+
import type { ApiResponse } from './client.js';
|
|
11
|
+
/**
|
|
12
|
+
* SMI-4120: Per-call cache directive, matching `fetch` RequestInit semantics.
|
|
13
|
+
* `no-store` skips both cache read and write for the call.
|
|
14
|
+
*/
|
|
15
|
+
export interface CallCacheOptions {
|
|
16
|
+
cache?: 'default' | 'no-store';
|
|
17
|
+
}
|
|
18
|
+
/**
|
|
19
|
+
* Cache configuration accepted by `SkillsmithApiClient`. Pass `false` to
|
|
20
|
+
* disable; pass a pre-built `ApiCache` to share one across clients; pass a
|
|
21
|
+
* `CacheConfig` object to customize TTLs.
|
|
22
|
+
*/
|
|
23
|
+
export type ClientCacheSetting = ApiCache | CacheConfig | false;
|
|
24
|
+
/**
|
|
25
|
+
* SMI-4120: Build the response cache honoring the env kill-switch. Returns
|
|
26
|
+
* `null` when disabled so callers can branch cheaply.
|
|
27
|
+
*/
|
|
28
|
+
export declare function buildResponseCache(setting: ClientCacheSetting | undefined): ApiCache | null;
|
|
29
|
+
/**
|
|
30
|
+
* SMI-4120: Run a thunk through the response cache. Stored values are the
|
|
31
|
+
* same `ApiResponse` reference — callers must not mutate.
|
|
32
|
+
*/
|
|
33
|
+
export declare function withResponseCache<T>(cache: ApiCache | null, endpointType: 'search' | 'getSkill' | 'recommend', key: string, noStore: boolean, fetcher: () => Promise<ApiResponse<T>>): Promise<ApiResponse<T>>;
|
|
34
|
+
//# sourceMappingURL=client.cache.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"client.cache.d.ts","sourceRoot":"","sources":["../../../src/api/client.cache.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,EAAE,QAAQ,EAAE,KAAK,WAAW,EAAE,MAAM,YAAY,CAAA;AACvD,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,aAAa,CAAA;AAE9C;;;GAGG;AACH,MAAM,WAAW,gBAAgB;IAC/B,KAAK,CAAC,EAAE,SAAS,GAAG,UAAU,CAAA;CAC/B;AAED;;;;GAIG;AACH,MAAM,MAAM,kBAAkB,GAAG,QAAQ,GAAG,WAAW,GAAG,KAAK,CAAA;AAE/D;;;GAGG;AACH,wBAAgB,kBAAkB,CAAC,OAAO,EAAE,kBAAkB,GAAG,SAAS,GAAG,QAAQ,GAAG,IAAI,CAK3F;AAED;;;GAGG;AACH,wBAAsB,iBAAiB,CAAC,CAAC,EACvC,KAAK,EAAE,QAAQ,GAAG,IAAI,EACtB,YAAY,EAAE,QAAQ,GAAG,UAAU,GAAG,WAAW,EACjD,GAAG,EAAE,MAAM,EACX,OAAO,EAAE,OAAO,EAChB,OAAO,EAAE,MAAM,OAAO,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC,GACrC,OAAO,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC,CAOzB"}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Client-side response cache wiring
|
|
3
|
+
* @module api/client.cache
|
|
4
|
+
*
|
|
5
|
+
* SMI-4120: Extracted from client.ts to keep the client under the 500-line
|
|
6
|
+
* audit:standards gate. Contains cache construction, the per-call option
|
|
7
|
+
* type, and the `withCache` helper used by search/getSkill/recommend.
|
|
8
|
+
*/
|
|
9
|
+
import { ApiCache } from './cache.js';
|
|
10
|
+
/**
|
|
11
|
+
* SMI-4120: Build the response cache honoring the env kill-switch. Returns
|
|
12
|
+
* `null` when disabled so callers can branch cheaply.
|
|
13
|
+
*/
|
|
14
|
+
export function buildResponseCache(setting) {
|
|
15
|
+
if (process.env.SKILLSMITH_DISABLE_CLIENT_CACHE === '1')
|
|
16
|
+
return null;
|
|
17
|
+
if (setting === false)
|
|
18
|
+
return null;
|
|
19
|
+
if (setting instanceof ApiCache)
|
|
20
|
+
return setting;
|
|
21
|
+
return new ApiCache(setting ?? {});
|
|
22
|
+
}
|
|
23
|
+
/**
|
|
24
|
+
* SMI-4120: Run a thunk through the response cache. Stored values are the
|
|
25
|
+
* same `ApiResponse` reference — callers must not mutate.
|
|
26
|
+
*/
|
|
27
|
+
export async function withResponseCache(cache, endpointType, key, noStore, fetcher) {
|
|
28
|
+
if (!cache || noStore)
|
|
29
|
+
return fetcher();
|
|
30
|
+
const hit = cache.get(key);
|
|
31
|
+
if (hit)
|
|
32
|
+
return hit;
|
|
33
|
+
const fresh = await fetcher();
|
|
34
|
+
cache.set(key, fresh, endpointType);
|
|
35
|
+
return fresh;
|
|
36
|
+
}
|
|
37
|
+
//# sourceMappingURL=client.cache.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"client.cache.js","sourceRoot":"","sources":["../../../src/api/client.cache.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,EAAE,QAAQ,EAAoB,MAAM,YAAY,CAAA;AAkBvD;;;GAGG;AACH,MAAM,UAAU,kBAAkB,CAAC,OAAuC;IACxE,IAAI,OAAO,CAAC,GAAG,CAAC,+BAA+B,KAAK,GAAG;QAAE,OAAO,IAAI,CAAA;IACpE,IAAI,OAAO,KAAK,KAAK;QAAE,OAAO,IAAI,CAAA;IAClC,IAAI,OAAO,YAAY,QAAQ;QAAE,OAAO,OAAO,CAAA;IAC/C,OAAO,IAAI,QAAQ,CAAC,OAAO,IAAI,EAAE,CAAC,CAAA;AACpC,CAAC;AAED;;;GAGG;AACH,MAAM,CAAC,KAAK,UAAU,iBAAiB,CACrC,KAAsB,EACtB,YAAiD,EACjD,GAAW,EACX,OAAgB,EAChB,OAAsC;IAEtC,IAAI,CAAC,KAAK,IAAI,OAAO;QAAE,OAAO,OAAO,EAAE,CAAA;IACvC,MAAM,GAAG,GAAG,KAAK,CAAC,GAAG,CAAiB,GAAG,CAAC,CAAA;IAC1C,IAAI,GAAG;QAAE,OAAO,GAAG,CAAA;IACnB,MAAM,KAAK,GAAG,MAAM,OAAO,EAAE,CAAA;IAC7B,KAAK,CAAC,GAAG,CAAC,GAAG,EAAE,KAAK,EAAE,YAAY,CAAC,CAAA;IACnC,OAAO,KAAK,CAAA;AACd,CAAC"}
|
package/dist/src/api/client.d.ts
CHANGED
|
@@ -2,111 +2,20 @@
|
|
|
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
|
-
import type { Skill,
|
|
8
|
+
import type { Skill, SearchOptions } from '../types/skill.js';
|
|
9
|
+
import { type ApiResponse, type ApiSearchResult, type ApiClientConfig, type RecommendationRequest, type TelemetryEvent } from './client.types.js';
|
|
10
|
+
export { ApiClientError, type ApiResponse, type ApiErrorResponse, type ApiSearchResult, type ApiClientConfig, type RecommendationRequest, type TelemetryEvent, } from './client.types.js';
|
|
11
|
+
import { ApiCache } from './cache.js';
|
|
12
|
+
import { type CallCacheOptions } from './client.cache.js';
|
|
13
|
+
export type { CallCacheOptions } from './client.cache.js';
|
|
15
14
|
export { generateAnonymousId } from './utils.js';
|
|
16
15
|
export { checkApiHealth } from './client.health.js';
|
|
17
16
|
export { ApiSearchResultSchema, SearchResponseSchema, SingleSkillResponseSchema, TelemetryResponseSchema, TrustTierSchema, } from './schemas.js';
|
|
18
17
|
/**
|
|
19
|
-
* API
|
|
20
|
-
*/
|
|
21
|
-
export interface ApiResponse<T> {
|
|
22
|
-
data: T;
|
|
23
|
-
meta?: Record<string, unknown>;
|
|
24
|
-
}
|
|
25
|
-
/**
|
|
26
|
-
* API error response
|
|
27
|
-
*/
|
|
28
|
-
export interface ApiErrorResponse {
|
|
29
|
-
error: string;
|
|
30
|
-
details?: Record<string, unknown>;
|
|
31
|
-
}
|
|
32
|
-
/**
|
|
33
|
-
* Custom error class for API client errors with retry control
|
|
34
|
-
* SMI-1257: Replace string-based retry skip with custom error class
|
|
35
|
-
*/
|
|
36
|
-
export declare class ApiClientError extends Error {
|
|
37
|
-
readonly retryable: boolean;
|
|
38
|
-
readonly statusCode?: number | undefined;
|
|
39
|
-
constructor(message: string, retryable?: boolean, statusCode?: number | undefined);
|
|
40
|
-
}
|
|
41
|
-
/**
|
|
42
|
-
* Search result from API
|
|
43
|
-
* SMI-1577: Made repo_url, created_at, updated_at optional to match schema
|
|
44
|
-
*/
|
|
45
|
-
export interface ApiSearchResult {
|
|
46
|
-
id: string;
|
|
47
|
-
name: string;
|
|
48
|
-
description: string | null;
|
|
49
|
-
author: string | null;
|
|
50
|
-
repo_url?: string | null;
|
|
51
|
-
quality_score: number | null;
|
|
52
|
-
trust_tier: TrustTier;
|
|
53
|
-
tags: string[];
|
|
54
|
-
stars?: number | null;
|
|
55
|
-
installable?: boolean | null;
|
|
56
|
-
quarantined?: boolean;
|
|
57
|
-
/** SHA-256 hash of SKILL.md content at index time */
|
|
58
|
-
content_hash?: string | null;
|
|
59
|
-
created_at?: string;
|
|
60
|
-
updated_at?: string;
|
|
61
|
-
}
|
|
62
|
-
/**
|
|
63
|
-
* Recommendation request
|
|
64
|
-
*/
|
|
65
|
-
export interface RecommendationRequest {
|
|
66
|
-
stack: string[];
|
|
67
|
-
project_type?: string;
|
|
68
|
-
limit?: number;
|
|
69
|
-
}
|
|
70
|
-
/**
|
|
71
|
-
* Telemetry event
|
|
72
|
-
*/
|
|
73
|
-
export interface TelemetryEvent {
|
|
74
|
-
event: 'skill_view' | 'skill_install' | 'skill_uninstall' | 'skill_rate' | 'search' | 'recommend' | 'compare' | 'validate';
|
|
75
|
-
skill_id?: string;
|
|
76
|
-
anonymous_id: string;
|
|
77
|
-
metadata?: Record<string, unknown>;
|
|
78
|
-
}
|
|
79
|
-
/**
|
|
80
|
-
* API client configuration
|
|
81
|
-
*/
|
|
82
|
-
export interface ApiClientConfig {
|
|
83
|
-
/** Base URL for the API (defaults to production Supabase) */
|
|
84
|
-
baseUrl?: string;
|
|
85
|
-
/** Supabase anon key for authentication */
|
|
86
|
-
anonKey?: string;
|
|
87
|
-
/** API key for authenticated requests (X-API-Key header) */
|
|
88
|
-
apiKey?: string;
|
|
89
|
-
/** Request timeout in ms (default 30000) */
|
|
90
|
-
timeout?: number;
|
|
91
|
-
/** Max retry attempts (default 3) */
|
|
92
|
-
maxRetries?: number;
|
|
93
|
-
/** Enable debug logging */
|
|
94
|
-
debug?: boolean;
|
|
95
|
-
/** Enable offline mode (disables API calls) */
|
|
96
|
-
offlineMode?: boolean;
|
|
97
|
-
}
|
|
98
|
-
/**
|
|
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
|
-
* ```
|
|
18
|
+
* Skillsmith API Client. See module docstring for SMI refs.
|
|
110
19
|
*/
|
|
111
20
|
export declare class SkillsmithApiClient {
|
|
112
21
|
private baseUrl;
|
|
@@ -116,7 +25,13 @@ export declare class SkillsmithApiClient {
|
|
|
116
25
|
private maxRetries;
|
|
117
26
|
private debug;
|
|
118
27
|
private offlineMode;
|
|
28
|
+
/** SMI-4119: Lazily-initialized batcher for telemetry events. */
|
|
29
|
+
private eventBatcher;
|
|
30
|
+
/** SMI-4120: Response cache (null when disabled). */
|
|
31
|
+
private responseCache;
|
|
119
32
|
constructor(config?: ApiClientConfig);
|
|
33
|
+
/** SMI-4120: Expose the response cache (null when disabled). */
|
|
34
|
+
getResponseCache(): ApiCache | null;
|
|
120
35
|
/**
|
|
121
36
|
* Check if client is running in offline mode
|
|
122
37
|
*/
|
|
@@ -147,25 +62,38 @@ export declare class SkillsmithApiClient {
|
|
|
147
62
|
/**
|
|
148
63
|
* Search for skills
|
|
149
64
|
* SMI-1258: Validates response against SearchResponseSchema
|
|
65
|
+
* SMI-4120: Client LRU cache; opt-out via `{ cache: 'no-store' }`.
|
|
150
66
|
*/
|
|
151
|
-
search(options: SearchOptions): Promise<ApiResponse<ApiSearchResult[]>>;
|
|
67
|
+
search(options: SearchOptions, callOptions?: CallCacheOptions): Promise<ApiResponse<ApiSearchResult[]>>;
|
|
152
68
|
/**
|
|
153
69
|
* Get skill by ID
|
|
154
70
|
* SMI-1258: Validates response against SingleSkillResponseSchema
|
|
71
|
+
* SMI-3672: Added includeContent option to fetch SKILL.md content
|
|
72
|
+
* SMI-4120: Client LRU cache; opt-out via `{ cache: 'no-store' }`.
|
|
155
73
|
*/
|
|
156
|
-
getSkill(id: string
|
|
74
|
+
getSkill(id: string, options?: {
|
|
75
|
+
includeContent?: boolean;
|
|
76
|
+
} & CallCacheOptions): Promise<ApiResponse<ApiSearchResult>>;
|
|
157
77
|
/**
|
|
158
78
|
* Get skill recommendations based on tech stack
|
|
159
79
|
* SMI-1258: Validates response against SearchResponseSchema
|
|
80
|
+
* SMI-4120: Client LRU cache; opt-out via `{ cache: 'no-store' }`.
|
|
160
81
|
*/
|
|
161
|
-
getRecommendations(request: RecommendationRequest): Promise<ApiResponse<ApiSearchResult[]>>;
|
|
82
|
+
getRecommendations(request: RecommendationRequest, callOptions?: CallCacheOptions): Promise<ApiResponse<ApiSearchResult[]>>;
|
|
162
83
|
/**
|
|
163
84
|
* Record telemetry event
|
|
164
|
-
* SMI-
|
|
85
|
+
* SMI-4119: Enqueue to in-memory batcher instead of POSTing immediately.
|
|
86
|
+
* Returns `{ ok: true }` synchronously — batcher handles failures silently,
|
|
87
|
+
* matching the prior "fail silently" contract for telemetry.
|
|
165
88
|
*/
|
|
166
89
|
recordEvent(event: TelemetryEvent): Promise<{
|
|
167
90
|
ok: boolean;
|
|
168
91
|
}>;
|
|
92
|
+
/** SMI-4119: Flush queued telemetry events (drain the batcher). */
|
|
93
|
+
flushEvents(): Promise<void>;
|
|
94
|
+
/** SMI-4119: Dispose batcher (detach exit listeners, clear timers). */
|
|
95
|
+
disposeEventBatcher(): void;
|
|
96
|
+
private getOrCreateBatcher;
|
|
169
97
|
/**
|
|
170
98
|
* Check API health status
|
|
171
99
|
*/
|
|
@@ -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,53 +2,28 @@
|
|
|
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';
|
|
9
|
+
import { ApiClientError, } from './client.types.js';
|
|
10
|
+
export { ApiClientError, } from './client.types.js';
|
|
15
11
|
// Import from extracted modules
|
|
16
|
-
import { SearchResponseSchema, SingleSkillResponseSchema
|
|
12
|
+
import { SearchResponseSchema, SingleSkillResponseSchema } from './schemas.js';
|
|
17
13
|
import { calculateBackoff, buildRequestHeaders, DEFAULT_BASE_URL, PRODUCTION_ANON_KEY, } from './utils.js';
|
|
18
14
|
import { checkApiHealth } from './client.health.js';
|
|
15
|
+
import { buildClientEventBatcher } from './client.events.js';
|
|
16
|
+
import { ApiCache } from './cache.js';
|
|
17
|
+
import { buildResponseCache, withResponseCache } from './client.cache.js';
|
|
19
18
|
// Re-export for backwards compatibility
|
|
20
19
|
export { generateAnonymousId } from './utils.js';
|
|
21
20
|
export { checkApiHealth } from './client.health.js';
|
|
22
21
|
export { ApiSearchResultSchema, SearchResponseSchema, SingleSkillResponseSchema, TelemetryResponseSchema, TrustTierSchema, } from './schemas.js';
|
|
23
|
-
/**
|
|
24
|
-
* Custom error class for API client errors with retry control
|
|
25
|
-
* SMI-1257: Replace string-based retry skip with custom error class
|
|
26
|
-
*/
|
|
27
|
-
export class ApiClientError extends Error {
|
|
28
|
-
retryable;
|
|
29
|
-
statusCode;
|
|
30
|
-
constructor(message, retryable = false, statusCode) {
|
|
31
|
-
super(message);
|
|
32
|
-
this.retryable = retryable;
|
|
33
|
-
this.statusCode = statusCode;
|
|
34
|
-
this.name = 'ApiClientError';
|
|
35
|
-
}
|
|
36
|
-
}
|
|
37
22
|
// ============================================================================
|
|
38
23
|
// API Client Class
|
|
39
24
|
// ============================================================================
|
|
40
25
|
/**
|
|
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
|
-
* ```
|
|
26
|
+
* Skillsmith API Client. See module docstring for SMI refs.
|
|
52
27
|
*/
|
|
53
28
|
export class SkillsmithApiClient {
|
|
54
29
|
baseUrl;
|
|
@@ -58,6 +33,10 @@ export class SkillsmithApiClient {
|
|
|
58
33
|
maxRetries;
|
|
59
34
|
debug;
|
|
60
35
|
offlineMode;
|
|
36
|
+
/** SMI-4119: Lazily-initialized batcher for telemetry events. */
|
|
37
|
+
eventBatcher = null;
|
|
38
|
+
/** SMI-4120: Response cache (null when disabled). */
|
|
39
|
+
responseCache = null;
|
|
61
40
|
constructor(config = {}) {
|
|
62
41
|
// SMI-1948: DEFAULT_BASE_URL now always has a value (production URL fallback)
|
|
63
42
|
// Priority: config.baseUrl > DEFAULT_BASE_URL (which checks env vars internally)
|
|
@@ -73,6 +52,11 @@ export class SkillsmithApiClient {
|
|
|
73
52
|
this.timeout = config.timeout ?? 30000;
|
|
74
53
|
this.maxRetries = config.maxRetries ?? 3;
|
|
75
54
|
this.debug = config.debug ?? false;
|
|
55
|
+
this.responseCache = buildResponseCache(config.cache);
|
|
56
|
+
}
|
|
57
|
+
/** SMI-4120: Expose the response cache (null when disabled). */
|
|
58
|
+
getResponseCache() {
|
|
59
|
+
return this.responseCache;
|
|
76
60
|
}
|
|
77
61
|
/**
|
|
78
62
|
* Check if client is running in offline mode
|
|
@@ -211,8 +195,9 @@ export class SkillsmithApiClient {
|
|
|
211
195
|
/**
|
|
212
196
|
* Search for skills
|
|
213
197
|
* SMI-1258: Validates response against SearchResponseSchema
|
|
198
|
+
* SMI-4120: Client LRU cache; opt-out via `{ cache: 'no-store' }`.
|
|
214
199
|
*/
|
|
215
|
-
async search(options) {
|
|
200
|
+
async search(options, callOptions) {
|
|
216
201
|
const params = new URLSearchParams();
|
|
217
202
|
params.set('query', options.query);
|
|
218
203
|
if (options.limit)
|
|
@@ -225,43 +210,71 @@ export class SkillsmithApiClient {
|
|
|
225
210
|
params.set('min_score', String(options.minQualityScore));
|
|
226
211
|
if (options.category)
|
|
227
212
|
params.set('category', options.category);
|
|
228
|
-
|
|
213
|
+
const endpoint = `/skills-search?${params.toString()}`;
|
|
214
|
+
return withResponseCache(this.responseCache, 'search', endpoint, callOptions?.cache === 'no-store', () => this.request(endpoint, {}, SearchResponseSchema));
|
|
229
215
|
}
|
|
230
216
|
/**
|
|
231
217
|
* Get skill by ID
|
|
232
218
|
* SMI-1258: Validates response against SingleSkillResponseSchema
|
|
219
|
+
* SMI-3672: Added includeContent option to fetch SKILL.md content
|
|
220
|
+
* SMI-4120: Client LRU cache; opt-out via `{ cache: 'no-store' }`.
|
|
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
|
+
const endpoint = `/skills-get?id=${encodedId}${contentParam}`;
|
|
226
|
+
return withResponseCache(this.responseCache, 'getSkill', endpoint, options?.cache === 'no-store', () => this.request(endpoint, {}, SingleSkillResponseSchema));
|
|
237
227
|
}
|
|
238
228
|
/**
|
|
239
229
|
* Get skill recommendations based on tech stack
|
|
240
230
|
* SMI-1258: Validates response against SearchResponseSchema
|
|
231
|
+
* SMI-4120: Client LRU cache; opt-out via `{ cache: 'no-store' }`.
|
|
241
232
|
*/
|
|
242
|
-
async getRecommendations(request) {
|
|
243
|
-
|
|
233
|
+
async getRecommendations(request, callOptions) {
|
|
234
|
+
const cacheKey = ApiCache.createKey('/skills-recommend', {
|
|
235
|
+
stack: [...request.stack].sort(),
|
|
236
|
+
project_type: request.project_type ?? null,
|
|
237
|
+
limit: request.limit ?? null,
|
|
238
|
+
});
|
|
239
|
+
return withResponseCache(this.responseCache, 'recommend', cacheKey, callOptions?.cache === 'no-store', () => this.request('/skills-recommend', {
|
|
244
240
|
method: 'POST',
|
|
245
241
|
body: JSON.stringify(request),
|
|
246
|
-
}, SearchResponseSchema);
|
|
242
|
+
}, SearchResponseSchema));
|
|
247
243
|
}
|
|
248
244
|
/**
|
|
249
245
|
* Record telemetry event
|
|
250
|
-
* SMI-
|
|
246
|
+
* SMI-4119: Enqueue to in-memory batcher instead of POSTing immediately.
|
|
247
|
+
* Returns `{ ok: true }` synchronously — batcher handles failures silently,
|
|
248
|
+
* matching the prior "fail silently" contract for telemetry.
|
|
251
249
|
*/
|
|
252
250
|
async recordEvent(event) {
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
251
|
+
if (this.offlineMode)
|
|
252
|
+
return { ok: true };
|
|
253
|
+
this.getOrCreateBatcher().enqueue(event);
|
|
254
|
+
return { ok: true };
|
|
255
|
+
}
|
|
256
|
+
/** SMI-4119: Flush queued telemetry events (drain the batcher). */
|
|
257
|
+
async flushEvents() {
|
|
258
|
+
if (this.eventBatcher)
|
|
259
|
+
await this.eventBatcher.flush();
|
|
260
|
+
}
|
|
261
|
+
/** SMI-4119: Dispose batcher (detach exit listeners, clear timers). */
|
|
262
|
+
disposeEventBatcher() {
|
|
263
|
+
if (this.eventBatcher) {
|
|
264
|
+
this.eventBatcher.dispose();
|
|
265
|
+
this.eventBatcher = null;
|
|
259
266
|
}
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
267
|
+
}
|
|
268
|
+
getOrCreateBatcher() {
|
|
269
|
+
if (!this.eventBatcher) {
|
|
270
|
+
this.eventBatcher = buildClientEventBatcher(() => ({
|
|
271
|
+
baseUrl: this.baseUrl,
|
|
272
|
+
anonKey: this.anonKey,
|
|
273
|
+
apiKey: this.apiKey,
|
|
274
|
+
timeout: this.timeout,
|
|
275
|
+
}));
|
|
264
276
|
}
|
|
277
|
+
return this.eventBatcher;
|
|
265
278
|
}
|
|
266
279
|
/**
|
|
267
280
|
* 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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"}
|