@opengeni/codemode 0.2.2 → 0.4.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/environment.d.ts +4 -1
- package/dist/index.js +344 -7
- package/dist/index.js.map +1 -1
- package/dist/interaction.d.ts +99 -1
- package/package.json +2 -2
- package/src/environment.ts +17 -5
- package/src/index.ts +47 -6
- package/src/interaction.ts +490 -0
package/dist/interaction.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { AttachedBrowserDevice, BrowserAction, BrowserActionReceipt, BrowserDiagnosticBatch, BrowserDiagnosticKind, BrowserIdentity, BrowserIdentityListResponse, BrowserIdentityMutationResponse, BrowserLocator, BrowserObservation, BrowserRevisionListResponse, BrowserSession, BrowserSessionMutationResponse, BrowserTargetListResponse, ComputerAction, ComputerActionReceipt, ComputerLocator, ComputerObservation, ComputerSession, ComputerSessionMutationResponse, ComputerTargetListResponse, InteractionPlacement, PublishBrowserRevisionResponse } from "@opengeni/contracts";
|
|
1
|
+
import type { AttachedBrowserDevice, AuthRun, AuthRunListResponse, AuthRunMutationResponse, BrowserAction, BrowserActionReceipt, BrowserClipboard, BrowserDiagnosticBatch, BrowserDiagnosticKind, BrowserIdentity, BrowserIdentityListResponse, BrowserIdentityMutationResponse, BrowserLocator, BrowserObservation, BrowserPermission, BrowserPermissionSetting, BrowserRevisionListResponse, BrowserSession, BrowserSessionMutationResponse, BrowserTargetListResponse, ComputerAction, ComputerActionReceipt, ComputerClipboard, ComputerLocator, ComputerObservation, ComputerSession, ComputerSessionMutationResponse, ComputerTargetListResponse, ExternalAuthRunRequest, ExternalAuthRunResponse, InteractionPlacement, ProtectedAuthFillRequest, ProtectedAuthFillResponse, PublishBrowserRevisionResponse, ReportAuthRunRequest, RequestHumanInteractionToolInput, RequestHumanInteractionToolOutput, SiteAuthConnection, SiteAuthConnectionListResponse, StartAuthRunRequest, UpdateBrowserIdentityRequest, VerifyAuthRunRequest } from "@opengeni/contracts";
|
|
2
2
|
import type { CodemodeCallOptions, CodemodeClient } from "./index.js";
|
|
3
3
|
import { type CodemodeClientProvider } from "./environment.js";
|
|
4
4
|
import { CodemodeArtifactCollection } from "./artifacts.js";
|
|
@@ -45,12 +45,14 @@ export declare class OpenGeniCodemode {
|
|
|
45
45
|
readonly browsers: CodemodeBrowserCollection;
|
|
46
46
|
readonly computers: CodemodeComputerCollection;
|
|
47
47
|
readonly artifacts: CodemodeArtifactCollection;
|
|
48
|
+
readonly auth: CodemodeAuth;
|
|
48
49
|
constructor(client?: CodemodeClient | CodemodeClientProvider);
|
|
49
50
|
discover(options?: {
|
|
50
51
|
includeTerminal?: boolean | undefined;
|
|
51
52
|
includeArchivedIdentities?: boolean | undefined;
|
|
52
53
|
includeDisconnectedDevices?: boolean | undefined;
|
|
53
54
|
}, callOptions?: CodemodeCallOptions): Promise<InteractionDiscovery>;
|
|
55
|
+
requestHuman(request: RequestHumanInteractionToolInput, callOptions?: CodemodeCallOptions): Promise<RequestHumanInteractionToolOutput>;
|
|
54
56
|
}
|
|
55
57
|
export declare class CodemodeBrowserCollection {
|
|
56
58
|
readonly client: CodemodeClientProvider;
|
|
@@ -71,11 +73,14 @@ export declare class CodemodeBrowserIdentityCollection {
|
|
|
71
73
|
get(identityId: string, callOptions?: CodemodeCallOptions): Promise<BrowserIdentity>;
|
|
72
74
|
create(name: string, callOptions?: CodemodeCallOptions): Promise<BrowserIdentityMutationResponse>;
|
|
73
75
|
revisions(identityId: string, callOptions?: CodemodeCallOptions): Promise<BrowserRevisionListResponse>;
|
|
76
|
+
update(identityId: string, update: Omit<UpdateBrowserIdentityRequest, "operationId">, callOptions?: CodemodeCallOptions): Promise<BrowserIdentityMutationResponse>;
|
|
74
77
|
}
|
|
75
78
|
export declare class CodemodeBrowser {
|
|
76
79
|
private readonly client;
|
|
77
80
|
readonly id: string;
|
|
78
81
|
readonly tabs: CodemodeBrowserTabCollection;
|
|
82
|
+
readonly auth: CodemodeBrowserAuth;
|
|
83
|
+
readonly clipboard: CodemodeBrowserClipboard;
|
|
79
84
|
constructor(client: CodemodeClientProvider, id: string);
|
|
80
85
|
refresh(callOptions?: CodemodeCallOptions): Promise<BrowserSession>;
|
|
81
86
|
observe(targetId?: string, callOptions?: CodemodeCallOptions): Promise<BrowserObservation>;
|
|
@@ -97,6 +102,30 @@ export declare class CodemodeBrowser {
|
|
|
97
102
|
end(callOptions?: CodemodeCallOptions): Promise<BrowserSessionMutationResponse>;
|
|
98
103
|
private lifecycle;
|
|
99
104
|
}
|
|
105
|
+
export declare class CodemodeBrowserClipboard {
|
|
106
|
+
private readonly client;
|
|
107
|
+
private readonly browserSessionId;
|
|
108
|
+
private readonly tabs;
|
|
109
|
+
constructor(client: CodemodeClientProvider, browserSessionId: string, tabs: CodemodeBrowserTabCollection);
|
|
110
|
+
read(callOptions?: CodemodeCallOptions): Promise<BrowserClipboard>;
|
|
111
|
+
write(text: string, options?: BrowserActionFences & {
|
|
112
|
+
targetId?: string | undefined;
|
|
113
|
+
}, callOptions?: CodemodeCallOptions): Promise<BrowserActionReceipt>;
|
|
114
|
+
clear(options?: BrowserActionFences & {
|
|
115
|
+
targetId?: string | undefined;
|
|
116
|
+
}, callOptions?: CodemodeCallOptions): Promise<BrowserActionReceipt>;
|
|
117
|
+
copy(options?: BrowserActionFences & {
|
|
118
|
+
targetId?: string | undefined;
|
|
119
|
+
locator?: BrowserLocator | undefined;
|
|
120
|
+
content?: "selection" | "value" | "text" | undefined;
|
|
121
|
+
}, callOptions?: CodemodeCallOptions): Promise<BrowserActionReceipt>;
|
|
122
|
+
paste(options?: BrowserActionFences & {
|
|
123
|
+
targetId?: string | undefined;
|
|
124
|
+
locator?: BrowserLocator | undefined;
|
|
125
|
+
text?: string | undefined;
|
|
126
|
+
}, callOptions?: CodemodeCallOptions): Promise<BrowserActionReceipt>;
|
|
127
|
+
private act;
|
|
128
|
+
}
|
|
100
129
|
export declare class CodemodeBrowserTabCollection {
|
|
101
130
|
private readonly client;
|
|
102
131
|
private readonly browserSessionId;
|
|
@@ -207,6 +236,12 @@ export declare class CodemodeBrowserTab {
|
|
|
207
236
|
details?: Record<string, import("zod").JSONType> | undefined;
|
|
208
237
|
} | null;
|
|
209
238
|
}>;
|
|
239
|
+
setPermission(permission: BrowserPermission, setting: BrowserPermissionSetting, fences?: BrowserActionFences, callOptions?: CodemodeCallOptions): Promise<BrowserActionReceipt>;
|
|
240
|
+
requestHuman(reason: string, options?: {
|
|
241
|
+
kind?: "manual_login" | "mfa" | "external_action" | "confirmation" | "other";
|
|
242
|
+
authRunId?: string | undefined;
|
|
243
|
+
expiresInSeconds?: number | undefined;
|
|
244
|
+
}, callOptions?: CodemodeCallOptions): Promise<RequestHumanInteractionToolOutput>;
|
|
210
245
|
getByRole(role: string, options?: {
|
|
211
246
|
name?: string;
|
|
212
247
|
exact?: boolean;
|
|
@@ -953,6 +988,43 @@ export declare class CodemodeBrowserLocator {
|
|
|
953
988
|
} | null;
|
|
954
989
|
}>;
|
|
955
990
|
}
|
|
991
|
+
export declare class CodemodeAuth {
|
|
992
|
+
private readonly client;
|
|
993
|
+
constructor(client: CodemodeClientProvider);
|
|
994
|
+
listConnections(options?: {
|
|
995
|
+
includeArchived?: boolean | undefined;
|
|
996
|
+
}, callOptions?: CodemodeCallOptions): Promise<SiteAuthConnectionListResponse>;
|
|
997
|
+
getConnection(siteAuthConnectionId: string, callOptions?: CodemodeCallOptions): Promise<SiteAuthConnection>;
|
|
998
|
+
listRuns(options?: {
|
|
999
|
+
browserSessionId?: string | undefined;
|
|
1000
|
+
siteAuthConnectionId?: string | undefined;
|
|
1001
|
+
includeSettled?: boolean | undefined;
|
|
1002
|
+
}, callOptions?: CodemodeCallOptions): Promise<AuthRunListResponse>;
|
|
1003
|
+
getRun(authRunId: string, callOptions?: CodemodeCallOptions): Promise<AuthRun>;
|
|
1004
|
+
use(browserSessionId: string, authRunId: string): CodemodeAuthRun;
|
|
1005
|
+
}
|
|
1006
|
+
export declare class CodemodeBrowserAuth {
|
|
1007
|
+
private readonly client;
|
|
1008
|
+
private readonly browserSessionId;
|
|
1009
|
+
constructor(client: CodemodeClientProvider, browserSessionId: string);
|
|
1010
|
+
listRuns(options?: {
|
|
1011
|
+
siteAuthConnectionId?: string | undefined;
|
|
1012
|
+
includeSettled?: boolean | undefined;
|
|
1013
|
+
}, callOptions?: CodemodeCallOptions): Promise<AuthRunListResponse>;
|
|
1014
|
+
start(request: Omit<StartAuthRunRequest, "operationId">, callOptions?: CodemodeCallOptions): Promise<CodemodeAuthRun>;
|
|
1015
|
+
use(authRunId: string): CodemodeAuthRun;
|
|
1016
|
+
}
|
|
1017
|
+
export declare class CodemodeAuthRun {
|
|
1018
|
+
private readonly client;
|
|
1019
|
+
readonly browserSessionId: string;
|
|
1020
|
+
readonly id: string;
|
|
1021
|
+
constructor(client: CodemodeClientProvider, browserSessionId: string, id: string);
|
|
1022
|
+
get(callOptions?: CodemodeCallOptions): Promise<AuthRun>;
|
|
1023
|
+
report(request: Omit<ReportAuthRunRequest, "operationId">, callOptions?: CodemodeCallOptions): Promise<AuthRunMutationResponse>;
|
|
1024
|
+
protectedFill(request: Omit<ProtectedAuthFillRequest, "operationId">, callOptions?: CodemodeCallOptions): Promise<ProtectedAuthFillResponse>;
|
|
1025
|
+
advanceExternal(request: Omit<ExternalAuthRunRequest, "operationId">, callOptions?: CodemodeCallOptions): Promise<ExternalAuthRunResponse>;
|
|
1026
|
+
verify(request: Omit<VerifyAuthRunRequest, "operationId">, callOptions?: CodemodeCallOptions): Promise<AuthRunMutationResponse>;
|
|
1027
|
+
}
|
|
956
1028
|
export declare class CodemodeComputerCollection {
|
|
957
1029
|
private readonly client;
|
|
958
1030
|
constructor(client: CodemodeClientProvider);
|
|
@@ -967,6 +1039,7 @@ export declare class CodemodeComputer {
|
|
|
967
1039
|
readonly id: string;
|
|
968
1040
|
readonly targets: CodemodeComputerTargetCollection;
|
|
969
1041
|
readonly apps: CodemodeComputerTargetCollection;
|
|
1042
|
+
readonly clipboard: CodemodeComputerClipboard;
|
|
970
1043
|
constructor(client: CodemodeClientProvider, id: string);
|
|
971
1044
|
refresh(callOptions?: CodemodeCallOptions): Promise<ComputerSession>;
|
|
972
1045
|
observe(targetId?: string, callOptions?: CodemodeCallOptions): Promise<ComputerObservation>;
|
|
@@ -996,6 +1069,26 @@ export declare class CodemodeComputer {
|
|
|
996
1069
|
}>;
|
|
997
1070
|
end(callOptions?: CodemodeCallOptions): Promise<ComputerSessionMutationResponse>;
|
|
998
1071
|
}
|
|
1072
|
+
export declare class CodemodeComputerClipboard {
|
|
1073
|
+
private readonly client;
|
|
1074
|
+
readonly computerSessionId: string;
|
|
1075
|
+
private readonly targets;
|
|
1076
|
+
constructor(client: CodemodeClientProvider, computerSessionId: string, targets: CodemodeComputerTargetCollection);
|
|
1077
|
+
read(callOptions?: CodemodeCallOptions): Promise<ComputerClipboard>;
|
|
1078
|
+
write(text: string, options?: {
|
|
1079
|
+
targetId?: string | undefined;
|
|
1080
|
+
}, callOptions?: CodemodeCallOptions): Promise<ComputerActionReceipt>;
|
|
1081
|
+
clear(options?: {
|
|
1082
|
+
targetId?: string | undefined;
|
|
1083
|
+
}, callOptions?: CodemodeCallOptions): Promise<ComputerActionReceipt>;
|
|
1084
|
+
copy(options?: {
|
|
1085
|
+
targetId?: string | undefined;
|
|
1086
|
+
}, callOptions?: CodemodeCallOptions): Promise<ComputerActionReceipt>;
|
|
1087
|
+
paste(options?: {
|
|
1088
|
+
targetId?: string | undefined;
|
|
1089
|
+
}, callOptions?: CodemodeCallOptions): Promise<ComputerActionReceipt>;
|
|
1090
|
+
private mutate;
|
|
1091
|
+
}
|
|
999
1092
|
export declare class CodemodeComputerTargetCollection {
|
|
1000
1093
|
private readonly client;
|
|
1001
1094
|
private readonly computerSessionId;
|
|
@@ -1004,6 +1097,7 @@ export declare class CodemodeComputerTargetCollection {
|
|
|
1004
1097
|
use(targetId: string): CodemodeComputerTarget;
|
|
1005
1098
|
focused(callOptions?: CodemodeCallOptions): Promise<CodemodeComputerTarget>;
|
|
1006
1099
|
resolveId(targetId: string | undefined, callOptions: CodemodeCallOptions): Promise<string>;
|
|
1100
|
+
resolveSeatId(targetId: string | undefined, callOptions: CodemodeCallOptions): Promise<string>;
|
|
1007
1101
|
}
|
|
1008
1102
|
export declare class CodemodeComputerTarget {
|
|
1009
1103
|
private readonly client;
|
|
@@ -1012,6 +1106,10 @@ export declare class CodemodeComputerTarget {
|
|
|
1012
1106
|
constructor(client: CodemodeClientProvider, computerSessionId: string, id: string);
|
|
1013
1107
|
observe(callOptions?: CodemodeCallOptions): Promise<ComputerObservation>;
|
|
1014
1108
|
act(action: ComputerAction, fences?: ComputerActionFences, callOptions?: CodemodeCallOptions): Promise<ComputerActionReceipt>;
|
|
1109
|
+
requestHuman(reason: string, options?: {
|
|
1110
|
+
kind?: "manual_login" | "mfa" | "external_action" | "confirmation" | "other";
|
|
1111
|
+
expiresInSeconds?: number | undefined;
|
|
1112
|
+
}, callOptions?: CodemodeCallOptions): Promise<RequestHumanInteractionToolOutput>;
|
|
1015
1113
|
getByRole(role: string, options?: {
|
|
1016
1114
|
name?: string;
|
|
1017
1115
|
exact?: boolean;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@opengeni/codemode",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.4.2",
|
|
4
4
|
"description": "Attempt-frozen programmatic tool catalog and execution authority for OpenGeni.",
|
|
5
5
|
"license": "Apache-2.0",
|
|
6
6
|
"repository": {
|
|
@@ -34,7 +34,7 @@
|
|
|
34
34
|
"prepublishOnly": "bash ../../scripts/prepublish-guard"
|
|
35
35
|
},
|
|
36
36
|
"dependencies": {
|
|
37
|
-
"@opengeni/contracts": "^0.
|
|
37
|
+
"@opengeni/contracts": "^0.50.0",
|
|
38
38
|
"ajv": "^8.20.0"
|
|
39
39
|
},
|
|
40
40
|
"engines": {
|
package/src/environment.ts
CHANGED
|
@@ -3,9 +3,13 @@ import { CodemodeClient, type CodemodeCallOptions, type CodemodeToolFunction } f
|
|
|
3
3
|
|
|
4
4
|
export const CODEMODE_ENVIRONMENT = {
|
|
5
5
|
url: "OPENGENI_CODEMODE_URL",
|
|
6
|
+
token: "OPENGENI_CODEMODE_TOKEN",
|
|
6
7
|
tokenFile: "OPENGENI_CODEMODE_TOKEN_FILE",
|
|
7
8
|
} as const;
|
|
8
9
|
|
|
10
|
+
/** Minimal environment shape; public declarations must not require `@types/node`. */
|
|
11
|
+
export type CodemodeEnvironment = Readonly<Record<string, string | undefined>>;
|
|
12
|
+
|
|
9
13
|
export type CodemodeClientProvider = () => CodemodeClient | Promise<CodemodeClient>;
|
|
10
14
|
|
|
11
15
|
/** A lazy catalog path. Every nested property remains callable at runtime. */
|
|
@@ -29,17 +33,25 @@ let cachedEnvironmentClient: { key: string; client: CodemodeClient } | null = nu
|
|
|
29
33
|
* The bearer file is reread for every HTTP request so worker renewal is live.
|
|
30
34
|
*/
|
|
31
35
|
export function environmentCodemodeClient(
|
|
32
|
-
environment:
|
|
36
|
+
environment: CodemodeEnvironment = process.env,
|
|
33
37
|
): CodemodeClient {
|
|
34
38
|
const baseUrl = requiredEnvironment(environment, CODEMODE_ENVIRONMENT.url);
|
|
35
|
-
const
|
|
36
|
-
const
|
|
39
|
+
const directTokenConfigured = environment[CODEMODE_ENVIRONMENT.token] !== undefined;
|
|
40
|
+
const tokenFile = directTokenConfigured
|
|
41
|
+
? undefined
|
|
42
|
+
: requiredEnvironment(environment, CODEMODE_ENVIRONMENT.tokenFile);
|
|
43
|
+
// Never place bearer bytes in the cache identity. The callback rereads the
|
|
44
|
+
// selected source for every request: managed token-file renewal is live, and
|
|
45
|
+
// a Connected Machine child never leaves its direct bearer in module state.
|
|
46
|
+
const key = `${baseUrl}\u0000${directTokenConfigured ? "direct" : `file:${tokenFile}`}`;
|
|
37
47
|
if (environment === process.env && cachedEnvironmentClient?.key === key) {
|
|
38
48
|
return cachedEnvironmentClient.client;
|
|
39
49
|
}
|
|
40
50
|
const client = new CodemodeClient({
|
|
41
51
|
baseUrl,
|
|
42
|
-
token:
|
|
52
|
+
token: directTokenConfigured
|
|
53
|
+
? async () => requiredEnvironment(environment, CODEMODE_ENVIRONMENT.token)
|
|
54
|
+
: async () => await readBearerFile(tokenFile!),
|
|
43
55
|
});
|
|
44
56
|
if (environment === process.env) cachedEnvironmentClient = { key, client };
|
|
45
57
|
return client;
|
|
@@ -94,7 +106,7 @@ async function readBearerFile(path: string): Promise<string> {
|
|
|
94
106
|
return token;
|
|
95
107
|
}
|
|
96
108
|
|
|
97
|
-
function requiredEnvironment(environment:
|
|
109
|
+
function requiredEnvironment(environment: CodemodeEnvironment, name: string): string {
|
|
98
110
|
const value = environment[name]?.trim();
|
|
99
111
|
if (!value) throw new Error(`${name} is required`);
|
|
100
112
|
return value;
|
package/src/index.ts
CHANGED
|
@@ -364,7 +364,12 @@ export class CodemodeClient {
|
|
|
364
364
|
method: "POST",
|
|
365
365
|
...(signal ? { signal } : {}),
|
|
366
366
|
headers: { "content-type": "application/json" },
|
|
367
|
-
body: JSON.stringify({
|
|
367
|
+
body: JSON.stringify({
|
|
368
|
+
operationId,
|
|
369
|
+
catalogDigest,
|
|
370
|
+
identity,
|
|
371
|
+
arguments: argumentsValue,
|
|
372
|
+
}),
|
|
368
373
|
});
|
|
369
374
|
return CodemodeCallSubmission.parse(await response.json()).operation;
|
|
370
375
|
}
|
|
@@ -390,7 +395,9 @@ export class CodemodeClient {
|
|
|
390
395
|
if (!response.ok) {
|
|
391
396
|
let message = `Codemode request failed with HTTP ${response.status}`;
|
|
392
397
|
try {
|
|
393
|
-
const payload = (await response.json()) as {
|
|
398
|
+
const payload = (await response.json()) as {
|
|
399
|
+
error?: { message?: unknown };
|
|
400
|
+
};
|
|
394
401
|
if (typeof payload.error?.message === "string") message = payload.error.message;
|
|
395
402
|
} catch {
|
|
396
403
|
// The status is sufficient; never echo an unbounded provider body.
|
|
@@ -453,7 +460,10 @@ export class AttemptToolEnvironment {
|
|
|
453
460
|
|
|
454
461
|
async call(
|
|
455
462
|
input: AttemptToolCallValue,
|
|
456
|
-
context: {
|
|
463
|
+
context: {
|
|
464
|
+
transportMeta?: Record<string, unknown> | null;
|
|
465
|
+
signal?: AbortSignal;
|
|
466
|
+
} = {},
|
|
457
467
|
): Promise<AttemptToolResultValue> {
|
|
458
468
|
const call = AttemptToolCall.parse(input);
|
|
459
469
|
if (call.catalogDigest !== this.catalog.digest) {
|
|
@@ -598,6 +608,15 @@ function assertCatalogSize(catalog: AttemptToolCatalogValue): void {
|
|
|
598
608
|
|
|
599
609
|
type SchemaCompiler = { compile(schema: object): ValidateFunction<unknown> };
|
|
600
610
|
|
|
611
|
+
// Validator compilation is structural and independent of attempt identity,
|
|
612
|
+
// executable closures, credentials, and authorization. Reuse only exact
|
|
613
|
+
// content-addressed validators; the attempt environment and catalog remain
|
|
614
|
+
// freshly bound and digested on every execution. The hard cap prevents an
|
|
615
|
+
// untrusted MCP schema stream from turning this process cache into a memory
|
|
616
|
+
// sink.
|
|
617
|
+
const COMPILED_CATALOG_SCHEMA_CACHE_MAX_ENTRIES = 512;
|
|
618
|
+
const compiledCatalogSchemaCache = new Map<string, ValidateFunction<unknown>>();
|
|
619
|
+
|
|
601
620
|
function createSchemaValidators(): {
|
|
602
621
|
draft7: SchemaCompiler;
|
|
603
622
|
draft2019: SchemaCompiler;
|
|
@@ -622,9 +641,31 @@ function compileCatalogSchema(
|
|
|
622
641
|
schema: AttemptToolCatalogEntryValue["inputSchema"],
|
|
623
642
|
): ValidateFunction<unknown> {
|
|
624
643
|
const dialect = typeof schema.$schema === "string" ? schema.$schema : "";
|
|
625
|
-
|
|
626
|
-
|
|
627
|
-
|
|
644
|
+
const family = dialect.includes("2020-12")
|
|
645
|
+
? "2020-12"
|
|
646
|
+
: dialect.includes("2019-09")
|
|
647
|
+
? "2019-09"
|
|
648
|
+
: "draft7";
|
|
649
|
+
const cacheKey = `${family}:${digestCanonicalJson(schema)}`;
|
|
650
|
+
const cached = compiledCatalogSchemaCache.get(cacheKey);
|
|
651
|
+
if (cached) {
|
|
652
|
+
compiledCatalogSchemaCache.delete(cacheKey);
|
|
653
|
+
compiledCatalogSchemaCache.set(cacheKey, cached);
|
|
654
|
+
return cached;
|
|
655
|
+
}
|
|
656
|
+
const compiled =
|
|
657
|
+
family === "2020-12"
|
|
658
|
+
? validators.draft2020.compile(schema)
|
|
659
|
+
: family === "2019-09"
|
|
660
|
+
? validators.draft2019.compile(schema)
|
|
661
|
+
: validators.draft7.compile(schema);
|
|
662
|
+
while (compiledCatalogSchemaCache.size >= COMPILED_CATALOG_SCHEMA_CACHE_MAX_ENTRIES) {
|
|
663
|
+
const oldest = compiledCatalogSchemaCache.keys().next().value;
|
|
664
|
+
if (oldest === undefined) break;
|
|
665
|
+
compiledCatalogSchemaCache.delete(oldest);
|
|
666
|
+
}
|
|
667
|
+
compiledCatalogSchemaCache.set(cacheKey, compiled);
|
|
668
|
+
return compiled;
|
|
628
669
|
}
|
|
629
670
|
|
|
630
671
|
function allocateCodemodePaths(definitions: readonly AttemptToolDefinition[]): string[][] {
|