@osdk/integration-testing 0.0.0 → 0.1.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 +16 -0
- package/bin/postinstall.mjs +15 -0
- package/build/browser/cli-service/CliServiceLauncher.js +220 -0
- package/build/browser/cli-service/CliServiceLauncher.js.map +1 -0
- package/build/browser/cli-service/FoundryCliService.js +168 -0
- package/build/browser/cli-service/FoundryCliService.js.map +1 -0
- package/build/browser/cli-service/OntologyServer.js +32 -0
- package/build/browser/cli-service/OntologyServer.js.map +1 -0
- package/build/browser/cli-service/ServiceDiscoverer.js +100 -0
- package/build/browser/cli-service/ServiceDiscoverer.js.map +1 -0
- package/build/browser/cli-service/StatusServer.js +91 -0
- package/build/browser/cli-service/StatusServer.js.map +1 -0
- package/build/browser/createIntegrationClient.js +67 -0
- package/build/browser/createIntegrationClient.js.map +1 -0
- package/build/browser/createIntegrationServer.js +115 -0
- package/build/browser/createIntegrationServer.js.map +1 -0
- package/build/browser/createSeedClient.js +77 -0
- package/build/browser/createSeedClient.js.map +1 -0
- package/build/browser/generated/cli/OntologySeedingService/setSeed.js +28 -0
- package/build/browser/generated/cli/OntologySeedingService/setSeed.js.map +1 -0
- package/build/browser/generated/cli/OntologySeedingService.js +19 -0
- package/build/browser/generated/cli/OntologySeedingService.js.map +1 -0
- package/build/browser/generated/cli/StatusService/getStatus.js +25 -0
- package/build/browser/generated/cli/StatusService/getStatus.js.map +1 -0
- package/build/browser/generated/cli/StatusService/publishStatus.js +26 -0
- package/build/browser/generated/cli/StatusService/publishStatus.js.map +1 -0
- package/build/browser/generated/cli/StatusService.js +20 -0
- package/build/browser/generated/cli/StatusService.js.map +1 -0
- package/build/browser/generated/cli/__components.js +2 -0
- package/build/browser/generated/cli/__components.js.map +1 -0
- package/build/browser/generated/cli/index.js +20 -0
- package/build/browser/generated/cli/index.js.map +1 -0
- package/build/browser/index.js +27 -0
- package/build/browser/index.js.map +1 -0
- package/build/browser/scripts/download.js +92 -0
- package/build/browser/scripts/download.js.map +1 -0
- package/build/browser/scripts/foundry-host.js +59 -0
- package/build/browser/scripts/foundry-host.js.map +1 -0
- package/build/browser/scripts/foundry-token.js +50 -0
- package/build/browser/scripts/foundry-token.js.map +1 -0
- package/build/browser/scripts/gitRemote.js +39 -0
- package/build/browser/scripts/gitRemote.js.map +1 -0
- package/build/browser/scripts/postinstall.js +38 -0
- package/build/browser/scripts/postinstall.js.map +1 -0
- package/build/browser/test/NoSpawnStatusServer.js +33 -0
- package/build/browser/test/NoSpawnStatusServer.js.map +1 -0
- package/build/browser/test/StubService.js +61 -0
- package/build/browser/test/StubService.js.map +1 -0
- package/build/browser/test/emptyOntologyMetadata.js +32 -0
- package/build/browser/test/emptyOntologyMetadata.js.map +1 -0
- package/build/browser/test/stubStatusServer.js +74 -0
- package/build/browser/test/stubStatusServer.js.map +1 -0
- package/build/browser/test/writeDiscoveryFile.js +39 -0
- package/build/browser/test/writeDiscoveryFile.js.map +1 -0
- package/build/browser/types.js +2 -0
- package/build/browser/types.js.map +1 -0
- package/build/browser/utils/empty-ontology-block.js +61 -0
- package/build/browser/utils/empty-ontology-block.js.map +1 -0
- package/build/browser/utils/foundry-cli.js +46 -0
- package/build/browser/utils/foundry-cli.js.map +1 -0
- package/build/browser/utils/process.js +26 -0
- package/build/browser/utils/process.js.map +1 -0
- package/build/browser/utils/service.js +33 -0
- package/build/browser/utils/service.js.map +1 -0
- package/build/cjs/index.cjs +841 -0
- package/build/cjs/index.cjs.map +1 -0
- package/build/cjs/index.d.cts +118 -0
- package/build/esm/cli-service/CliServiceLauncher.js +220 -0
- package/build/esm/cli-service/CliServiceLauncher.js.map +1 -0
- package/build/esm/cli-service/FoundryCliService.js +168 -0
- package/build/esm/cli-service/FoundryCliService.js.map +1 -0
- package/build/esm/cli-service/OntologyServer.js +32 -0
- package/build/esm/cli-service/OntologyServer.js.map +1 -0
- package/build/esm/cli-service/ServiceDiscoverer.js +100 -0
- package/build/esm/cli-service/ServiceDiscoverer.js.map +1 -0
- package/build/esm/cli-service/StatusServer.js +91 -0
- package/build/esm/cli-service/StatusServer.js.map +1 -0
- package/build/esm/createIntegrationClient.js +67 -0
- package/build/esm/createIntegrationClient.js.map +1 -0
- package/build/esm/createIntegrationServer.js +115 -0
- package/build/esm/createIntegrationServer.js.map +1 -0
- package/build/esm/createSeedClient.js +77 -0
- package/build/esm/createSeedClient.js.map +1 -0
- package/build/esm/generated/cli/OntologySeedingService/setSeed.js +28 -0
- package/build/esm/generated/cli/OntologySeedingService/setSeed.js.map +1 -0
- package/build/esm/generated/cli/OntologySeedingService.js +19 -0
- package/build/esm/generated/cli/OntologySeedingService.js.map +1 -0
- package/build/esm/generated/cli/StatusService/getStatus.js +25 -0
- package/build/esm/generated/cli/StatusService/getStatus.js.map +1 -0
- package/build/esm/generated/cli/StatusService/publishStatus.js +26 -0
- package/build/esm/generated/cli/StatusService/publishStatus.js.map +1 -0
- package/build/esm/generated/cli/StatusService.js +20 -0
- package/build/esm/generated/cli/StatusService.js.map +1 -0
- package/build/esm/generated/cli/__components.js +2 -0
- package/build/esm/generated/cli/__components.js.map +1 -0
- package/build/esm/generated/cli/index.js +20 -0
- package/build/esm/generated/cli/index.js.map +1 -0
- package/build/esm/index.js +27 -0
- package/build/esm/index.js.map +1 -0
- package/build/esm/scripts/download.js +92 -0
- package/build/esm/scripts/download.js.map +1 -0
- package/build/esm/scripts/foundry-host.js +59 -0
- package/build/esm/scripts/foundry-host.js.map +1 -0
- package/build/esm/scripts/foundry-token.js +50 -0
- package/build/esm/scripts/foundry-token.js.map +1 -0
- package/build/esm/scripts/gitRemote.js +39 -0
- package/build/esm/scripts/gitRemote.js.map +1 -0
- package/build/esm/scripts/postinstall.js +38 -0
- package/build/esm/scripts/postinstall.js.map +1 -0
- package/build/esm/test/NoSpawnStatusServer.js +33 -0
- package/build/esm/test/NoSpawnStatusServer.js.map +1 -0
- package/build/esm/test/StubService.js +61 -0
- package/build/esm/test/StubService.js.map +1 -0
- package/build/esm/test/emptyOntologyMetadata.js +32 -0
- package/build/esm/test/emptyOntologyMetadata.js.map +1 -0
- package/build/esm/test/stubStatusServer.js +74 -0
- package/build/esm/test/stubStatusServer.js.map +1 -0
- package/build/esm/test/writeDiscoveryFile.js +39 -0
- package/build/esm/test/writeDiscoveryFile.js.map +1 -0
- package/build/esm/types.js +2 -0
- package/build/esm/types.js.map +1 -0
- package/build/esm/utils/empty-ontology-block.js +61 -0
- package/build/esm/utils/empty-ontology-block.js.map +1 -0
- package/build/esm/utils/foundry-cli.js +46 -0
- package/build/esm/utils/foundry-cli.js.map +1 -0
- package/build/esm/utils/process.js +26 -0
- package/build/esm/utils/process.js.map +1 -0
- package/build/esm/utils/service.js +33 -0
- package/build/esm/utils/service.js.map +1 -0
- package/build/types/cli-service/CliServiceLauncher.d.ts +36 -0
- package/build/types/cli-service/CliServiceLauncher.d.ts.map +1 -0
- package/build/types/cli-service/FoundryCliService.d.ts +60 -0
- package/build/types/cli-service/FoundryCliService.d.ts.map +1 -0
- package/build/types/cli-service/OntologyServer.d.ts +10 -0
- package/build/types/cli-service/OntologyServer.d.ts.map +1 -0
- package/build/types/cli-service/ServiceDiscoverer.d.ts +22 -0
- package/build/types/cli-service/ServiceDiscoverer.d.ts.map +1 -0
- package/build/types/cli-service/StatusServer.d.ts +17 -0
- package/build/types/cli-service/StatusServer.d.ts.map +1 -0
- package/build/types/createIntegrationClient.d.ts +2 -0
- package/build/types/createIntegrationClient.d.ts.map +1 -0
- package/build/types/createIntegrationServer.d.ts +2 -0
- package/build/types/createIntegrationServer.d.ts.map +1 -0
- package/build/types/createSeedClient.d.ts +9 -0
- package/build/types/createSeedClient.d.ts.map +1 -0
- package/build/types/generated/cli/OntologySeedingService/setSeed.d.ts +9 -0
- package/build/types/generated/cli/OntologySeedingService/setSeed.d.ts.map +1 -0
- package/build/types/generated/cli/OntologySeedingService.d.ts +1 -0
- package/build/types/generated/cli/OntologySeedingService.d.ts.map +1 -0
- package/build/types/generated/cli/StatusService/getStatus.d.ts +6 -0
- package/build/types/generated/cli/StatusService/getStatus.d.ts.map +1 -0
- package/build/types/generated/cli/StatusService/publishStatus.d.ts +7 -0
- package/build/types/generated/cli/StatusService/publishStatus.d.ts.map +1 -0
- package/build/types/generated/cli/StatusService.d.ts +2 -0
- package/build/types/generated/cli/StatusService.d.ts.map +1 -0
- package/build/types/generated/cli/__components.d.ts +189 -0
- package/build/types/generated/cli/__components.d.ts.map +1 -0
- package/build/types/generated/cli/index.d.ts +3 -0
- package/build/types/generated/cli/index.d.ts.map +1 -0
- package/build/types/index.d.ts +10 -0
- package/build/types/index.d.ts.map +1 -0
- package/build/types/scripts/download.d.ts +6 -0
- package/build/types/scripts/download.d.ts.map +1 -0
- package/build/types/scripts/foundry-host.d.ts +7 -0
- package/build/types/scripts/foundry-host.d.ts.map +1 -0
- package/build/types/scripts/foundry-token.d.ts +5 -0
- package/build/types/scripts/foundry-token.d.ts.map +1 -0
- package/build/types/scripts/gitRemote.d.ts +9 -0
- package/build/types/scripts/gitRemote.d.ts.map +1 -0
- package/build/types/scripts/postinstall.d.ts +1 -0
- package/build/types/scripts/postinstall.d.ts.map +1 -0
- package/build/types/test/NoSpawnStatusServer.d.ts +11 -0
- package/build/types/test/NoSpawnStatusServer.d.ts.map +1 -0
- package/build/types/test/StubService.d.ts +23 -0
- package/build/types/test/StubService.d.ts.map +1 -0
- package/build/types/test/emptyOntologyMetadata.d.ts +3 -0
- package/build/types/test/emptyOntologyMetadata.d.ts.map +1 -0
- package/build/types/test/stubStatusServer.d.ts +14 -0
- package/build/types/test/stubStatusServer.d.ts.map +1 -0
- package/build/types/test/writeDiscoveryFile.d.ts +8 -0
- package/build/types/test/writeDiscoveryFile.d.ts.map +1 -0
- package/build/types/types.d.ts +104 -0
- package/build/types/types.d.ts.map +1 -0
- package/build/types/utils/empty-ontology-block.d.ts +4 -0
- package/build/types/utils/empty-ontology-block.d.ts.map +1 -0
- package/build/types/utils/foundry-cli.d.ts +13 -0
- package/build/types/utils/foundry-cli.d.ts.map +1 -0
- package/build/types/utils/process.d.ts +1 -0
- package/build/types/utils/process.d.ts.map +1 -0
- package/build/types/utils/service.d.ts +4 -0
- package/build/types/utils/service.d.ts.map +1 -0
- package/package.json +93 -1
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Copyright 2026 Palantir Technologies, Inc. All rights reserved.
|
|
3
|
+
*
|
|
4
|
+
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
5
|
+
* you may not use this file except in compliance with the License.
|
|
6
|
+
* You may obtain a copy of the License at
|
|
7
|
+
*
|
|
8
|
+
* http://www.apache.org/licenses/LICENSE-2.0
|
|
9
|
+
*
|
|
10
|
+
* Unless required by applicable law or agreed to in writing, software
|
|
11
|
+
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
12
|
+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
13
|
+
* See the License for the specific language governing permissions and
|
|
14
|
+
* limitations under the License.
|
|
15
|
+
*/
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
* The published name of this package.
|
|
19
|
+
*
|
|
20
|
+
* Placeholder entry point for `@osdk/integration-testing`. Integration-testing
|
|
21
|
+
* helpers will be exported from here as they are implemented.
|
|
22
|
+
*/
|
|
23
|
+
|
|
24
|
+
export { createIntegrationClient } from "./createIntegrationClient.js";
|
|
25
|
+
export { createIntegrationServer } from "./createIntegrationServer.js";
|
|
26
|
+
export { checkFoundryCliVersion } from "./utils/foundry-cli.js";
|
|
27
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","names":["createIntegrationClient","createIntegrationServer","checkFoundryCliVersion"],"sources":["index.ts"],"sourcesContent":["/*\n * Copyright 2026 Palantir Technologies, Inc. All rights reserved.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n/**\n * The published name of this package.\n *\n * Placeholder entry point for `@osdk/integration-testing`. Integration-testing\n * helpers will be exported from here as they are implemented.\n */\n\nexport type {\n SeedClient,\n IntegrationClient,\n IntegrationClientConfig,\n IntegrationServer,\n IntegrationServerConfig,\n} from \"./types.js\";\n\nexport { createIntegrationClient } from \"./createIntegrationClient.js\";\nexport { createIntegrationServer } from \"./createIntegrationServer.js\";\n\nexport { checkFoundryCliVersion } from \"./utils/foundry-cli.js\";\n"],"mappings":"AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAUA,SAASA,uBAAuB,QAAQ,8BAA8B;AACtE,SAASC,uBAAuB,QAAQ,8BAA8B;AAEtE,SAASC,sBAAsB,QAAQ,wBAAwB","ignoreList":[]}
|
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Copyright 2026 Palantir Technologies, Inc. All rights reserved.
|
|
3
|
+
*
|
|
4
|
+
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
5
|
+
* you may not use this file except in compliance with the License.
|
|
6
|
+
* You may obtain a copy of the License at
|
|
7
|
+
*
|
|
8
|
+
* http://www.apache.org/licenses/LICENSE-2.0
|
|
9
|
+
*
|
|
10
|
+
* Unless required by applicable law or agreed to in writing, software
|
|
11
|
+
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
12
|
+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
13
|
+
* See the License for the specific language governing permissions and
|
|
14
|
+
* limitations under the License.
|
|
15
|
+
*/
|
|
16
|
+
|
|
17
|
+
import { spawn } from "node:child_process";
|
|
18
|
+
import { rm, writeFile } from "node:fs/promises";
|
|
19
|
+
import { tmpdir } from "node:os";
|
|
20
|
+
import { join } from "node:path";
|
|
21
|
+
import consola from "consola";
|
|
22
|
+
import invariant from "tiny-invariant";
|
|
23
|
+
import { resolveFoundryHost } from "./foundry-host.js";
|
|
24
|
+
import { getFoundryToken } from "./foundry-token.js";
|
|
25
|
+
const INSTALL_SCRIPT_PATH = "/code/api/extension/install-script";
|
|
26
|
+
const INSTALL_BAT_PATH = "/code/api/extension/install-bat";
|
|
27
|
+
const fetchInstallScript = async (foundryUrl, token, isWindows) => {
|
|
28
|
+
const url = new URL(isWindows ? INSTALL_BAT_PATH : INSTALL_SCRIPT_PATH, foundryUrl);
|
|
29
|
+
consola.start(`Fetching the Foundry CLI installer from ${url.href}`);
|
|
30
|
+
const response = await fetch(url, {
|
|
31
|
+
headers: {
|
|
32
|
+
authorization: `Bearer ${token}`
|
|
33
|
+
}
|
|
34
|
+
});
|
|
35
|
+
!response.ok ? process.env.NODE_ENV !== "production" ? invariant(false, () => `Failed to fetch the Foundry CLI installer from ${url.href}: ` + `${response.status} ${response.statusText}`) : invariant(false) : void 0;
|
|
36
|
+
return await response.text();
|
|
37
|
+
};
|
|
38
|
+
const run = async (command, args, env, stdin) => {
|
|
39
|
+
await new Promise((fulfil, reject) => {
|
|
40
|
+
const child = spawn(command, args, {
|
|
41
|
+
env,
|
|
42
|
+
stdio: [stdin === undefined ? "ignore" : "pipe", "inherit", "inherit"]
|
|
43
|
+
});
|
|
44
|
+
child.on("error", reject);
|
|
45
|
+
child.on("close", (code, signal) => {
|
|
46
|
+
if (code === 0) {
|
|
47
|
+
fulfil();
|
|
48
|
+
return;
|
|
49
|
+
}
|
|
50
|
+
const reason = signal == null ? `code ${String(code)}` : `signal ${signal}`;
|
|
51
|
+
reject(new Error(`The Foundry CLI installer exited with ${reason}`));
|
|
52
|
+
});
|
|
53
|
+
if (stdin !== undefined) {
|
|
54
|
+
child.stdin?.end(stdin);
|
|
55
|
+
}
|
|
56
|
+
});
|
|
57
|
+
};
|
|
58
|
+
const runInstallScript = async (script, env) => await run("bash", ["-s", "--"], env, script);
|
|
59
|
+
const runInstallBat = async (script, env) => {
|
|
60
|
+
const batPath = join(tmpdir(), `install-foundry-${process.pid}.bat`);
|
|
61
|
+
await writeFile(batPath, script);
|
|
62
|
+
try {
|
|
63
|
+
await run("cmd.exe", ["/d", "/s", "/c", batPath], env);
|
|
64
|
+
} finally {
|
|
65
|
+
await rm(batPath, {
|
|
66
|
+
force: true
|
|
67
|
+
});
|
|
68
|
+
}
|
|
69
|
+
};
|
|
70
|
+
|
|
71
|
+
/**
|
|
72
|
+
* Installs the Foundry CLI by running the installer the stack serves, with the
|
|
73
|
+
* resolved stack url and token injected as `FOUNDRY_URL` and `TOKEN`.
|
|
74
|
+
*/
|
|
75
|
+
export const installFoundryCli = async (options = {}) => {
|
|
76
|
+
const env = options.env ?? process.env;
|
|
77
|
+
const isWindows = process.platform === "win32";
|
|
78
|
+
const [host, token] = await Promise.all([resolveFoundryHost(options), getFoundryToken(options)]);
|
|
79
|
+
const foundryUrl = `https://${host}`;
|
|
80
|
+
const script = await fetchInstallScript(foundryUrl, token, isWindows);
|
|
81
|
+
const installerEnv = {
|
|
82
|
+
...env,
|
|
83
|
+
FOUNDRY_URL: foundryUrl,
|
|
84
|
+
TOKEN: token
|
|
85
|
+
};
|
|
86
|
+
if (isWindows) {
|
|
87
|
+
await runInstallBat(script, installerEnv);
|
|
88
|
+
} else {
|
|
89
|
+
await runInstallScript(script, installerEnv);
|
|
90
|
+
}
|
|
91
|
+
};
|
|
92
|
+
//# sourceMappingURL=download.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"download.js","names":["spawn","rm","writeFile","tmpdir","join","consola","invariant","resolveFoundryHost","getFoundryToken","INSTALL_SCRIPT_PATH","INSTALL_BAT_PATH","fetchInstallScript","foundryUrl","token","isWindows","url","URL","start","href","response","fetch","headers","authorization","ok","process","env","NODE_ENV","status","statusText","text","run","command","args","stdin","Promise","fulfil","reject","child","stdio","undefined","on","code","signal","reason","String","Error","end","runInstallScript","script","runInstallBat","batPath","pid","force","installFoundryCli","options","platform","host","all","installerEnv","FOUNDRY_URL","TOKEN"],"sources":["download.ts"],"sourcesContent":["/*\n * Copyright 2026 Palantir Technologies, Inc. All rights reserved.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { spawn } from \"node:child_process\";\nimport { rm, writeFile } from \"node:fs/promises\";\nimport { tmpdir } from \"node:os\";\nimport { join } from \"node:path\";\n\nimport consola from \"consola\";\nimport invariant from \"tiny-invariant\";\n\nimport { resolveFoundryHost } from \"./foundry-host.js\";\nimport {\n getFoundryToken,\n type ResolveBearerTokenOptions,\n} from \"./foundry-token.js\";\n\nconst INSTALL_SCRIPT_PATH = \"/code/api/extension/install-script\";\nconst INSTALL_BAT_PATH = \"/code/api/extension/install-bat\";\n\nconst fetchInstallScript = async (\n foundryUrl: string,\n token: string,\n isWindows: boolean,\n): Promise<string> => {\n const url = new URL(\n isWindows ? INSTALL_BAT_PATH : INSTALL_SCRIPT_PATH,\n foundryUrl,\n );\n consola.start(`Fetching the Foundry CLI installer from ${url.href}`);\n const response = await fetch(url, {\n headers: { authorization: `Bearer ${token}` },\n });\n invariant(\n response.ok,\n () =>\n `Failed to fetch the Foundry CLI installer from ${url.href}: ` +\n `${response.status} ${response.statusText}`,\n );\n return await response.text();\n};\n\nconst run = async (\n command: string,\n args: string[],\n env: NodeJS.ProcessEnv,\n stdin?: string,\n): Promise<void> => {\n await new Promise<void>((fulfil, reject) => {\n const child = spawn(command, args, {\n env,\n stdio: [stdin === undefined ? \"ignore\" : \"pipe\", \"inherit\", \"inherit\"],\n });\n child.on(\"error\", reject);\n child.on(\"close\", (code, signal) => {\n if (code === 0) {\n fulfil();\n return;\n }\n const reason =\n signal == null ? `code ${String(code)}` : `signal ${signal}`;\n reject(new Error(`The Foundry CLI installer exited with ${reason}`));\n });\n if (stdin !== undefined) {\n child.stdin?.end(stdin);\n }\n });\n};\n\nconst runInstallScript = async (\n script: string,\n env: NodeJS.ProcessEnv,\n): Promise<void> => await run(\"bash\", [\"-s\", \"--\"], env, script);\n\nconst runInstallBat = async (\n script: string,\n env: NodeJS.ProcessEnv,\n): Promise<void> => {\n const batPath = join(tmpdir(), `install-foundry-${process.pid}.bat`);\n await writeFile(batPath, script);\n try {\n await run(\"cmd.exe\", [\"/d\", \"/s\", \"/c\", batPath], env);\n } finally {\n await rm(batPath, { force: true });\n }\n};\n\n/**\n * Installs the Foundry CLI by running the installer the stack serves, with the\n * resolved stack url and token injected as `FOUNDRY_URL` and `TOKEN`.\n */\nexport const installFoundryCli = async (\n options: ResolveBearerTokenOptions = {},\n): Promise<void> => {\n const env = options.env ?? process.env;\n const isWindows = process.platform === \"win32\";\n\n const [host, token] = await Promise.all([\n resolveFoundryHost(options),\n getFoundryToken(options),\n ]);\n const foundryUrl = `https://${host}`;\n\n const script = await fetchInstallScript(foundryUrl, token, isWindows);\n const installerEnv = { ...env, FOUNDRY_URL: foundryUrl, TOKEN: token };\n if (isWindows) {\n await runInstallBat(script, installerEnv);\n } else {\n await runInstallScript(script, installerEnv);\n }\n};\n"],"mappings":"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","ignoreList":[]}
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Copyright 2026 Palantir Technologies, Inc. All rights reserved.
|
|
3
|
+
*
|
|
4
|
+
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
5
|
+
* you may not use this file except in compliance with the License.
|
|
6
|
+
* You may obtain a copy of the License at
|
|
7
|
+
*
|
|
8
|
+
* http://www.apache.org/licenses/LICENSE-2.0
|
|
9
|
+
*
|
|
10
|
+
* Unless required by applicable law or agreed to in writing, software
|
|
11
|
+
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
12
|
+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
13
|
+
* See the License for the specific language governing permissions and
|
|
14
|
+
* limitations under the License.
|
|
15
|
+
*/
|
|
16
|
+
|
|
17
|
+
import invariant from "tiny-invariant";
|
|
18
|
+
import { readGitRemoteUrl } from "./gitRemote.js";
|
|
19
|
+
const parseGitRemoteHost = gitRemote => {
|
|
20
|
+
try {
|
|
21
|
+
// Strips any userinfo (`https://user:token@host/...`), and the port with it:
|
|
22
|
+
// a git remote's port belongs to the git transport (`ssh://...:22/repo`),
|
|
23
|
+
// not to the Foundry endpoint this host is used to build.
|
|
24
|
+
return new URL(gitRemote).hostname || undefined;
|
|
25
|
+
} catch {
|
|
26
|
+
// scp-like remotes (`user@host:path`)
|
|
27
|
+
const host = gitRemote.slice(gitRemote.lastIndexOf("@") + 1).split(":")[0].split("/")[0];
|
|
28
|
+
return host === "" ? undefined : host;
|
|
29
|
+
}
|
|
30
|
+
};
|
|
31
|
+
|
|
32
|
+
/**
|
|
33
|
+
* Reads the host out of an explicitly configured value.
|
|
34
|
+
*/
|
|
35
|
+
const parseConfiguredHost = value => {
|
|
36
|
+
const trimmed = value.trim();
|
|
37
|
+
let fromUrl;
|
|
38
|
+
try {
|
|
39
|
+
fromUrl = new URL(trimmed).host || undefined;
|
|
40
|
+
} catch {
|
|
41
|
+
fromUrl = undefined;
|
|
42
|
+
}
|
|
43
|
+
return fromUrl ?? (trimmed.split("/")[0] || undefined);
|
|
44
|
+
};
|
|
45
|
+
export const resolveFoundryHost = async (options = {}) => {
|
|
46
|
+
const env = options.env ?? process.env;
|
|
47
|
+
const envValue = env.FOUNDRY_EXTERNAL_HOST ?? env.FOUNDRY_HOSTNAME;
|
|
48
|
+
if (envValue) {
|
|
49
|
+
const configured = parseConfiguredHost(envValue);
|
|
50
|
+
if (configured) {
|
|
51
|
+
return configured;
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
const gitRemote = await readGitRemoteUrl(options);
|
|
55
|
+
const gitRemoteHost = gitRemote === undefined ? undefined : parseGitRemoteHost(gitRemote);
|
|
56
|
+
!(gitRemoteHost !== undefined) ? process.env.NODE_ENV !== "production" ? invariant(false, "Cannot resolve the Foundry host. Please set FOUNDRY_EXTERNAL_HOST or " + "FOUNDRY_HOSTNAME, or configure a git remote pointing at Foundry.") : invariant(false) : void 0;
|
|
57
|
+
return gitRemoteHost;
|
|
58
|
+
};
|
|
59
|
+
//# sourceMappingURL=foundry-host.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"foundry-host.js","names":["invariant","readGitRemoteUrl","parseGitRemoteHost","gitRemote","URL","hostname","undefined","host","slice","lastIndexOf","split","parseConfiguredHost","value","trimmed","trim","fromUrl","resolveFoundryHost","options","env","process","envValue","FOUNDRY_EXTERNAL_HOST","FOUNDRY_HOSTNAME","configured","gitRemoteHost","NODE_ENV"],"sources":["foundry-host.ts"],"sourcesContent":["/*\n * Copyright 2026 Palantir Technologies, Inc. All rights reserved.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport invariant from \"tiny-invariant\";\n\nimport type { ResolveBearerTokenOptions } from \"./foundry-token.js\";\nimport { readGitRemoteUrl } from \"./gitRemote.js\";\n\nexport type ArtifactPlatform =\n | \"linux-amd64\"\n | \"linux-arm64\"\n | \"macos-amd64\"\n | \"macos-arm64\"\n | \"windows-amd64\";\n\nexport interface FoundryCliInstallPathsOptions {\n env?: NodeJS.ProcessEnv;\n platform?: NodeJS.Platform;\n}\nconst parseGitRemoteHost = (gitRemote: string): string | undefined => {\n try {\n // Strips any userinfo (`https://user:token@host/...`), and the port with it:\n // a git remote's port belongs to the git transport (`ssh://...:22/repo`),\n // not to the Foundry endpoint this host is used to build.\n return new URL(gitRemote).hostname || undefined;\n } catch {\n // scp-like remotes (`user@host:path`)\n const host = gitRemote\n .slice(gitRemote.lastIndexOf(\"@\") + 1)\n .split(\":\")[0]\n .split(\"/\")[0];\n return host === \"\" ? undefined : host;\n }\n};\n\n/**\n * Reads the host out of an explicitly configured value.\n */\nconst parseConfiguredHost = (value: string): string | undefined => {\n const trimmed = value.trim();\n let fromUrl: string | undefined;\n try {\n fromUrl = new URL(trimmed).host || undefined;\n } catch {\n fromUrl = undefined;\n }\n return fromUrl ?? (trimmed.split(\"/\")[0] || undefined);\n};\n\nexport const resolveFoundryHost = async (\n options: ResolveBearerTokenOptions = {},\n): Promise<string> => {\n const env = options.env ?? process.env;\n const envValue = env.FOUNDRY_EXTERNAL_HOST ?? env.FOUNDRY_HOSTNAME;\n if (envValue) {\n const configured = parseConfiguredHost(envValue);\n if (configured) {\n return configured;\n }\n }\n const gitRemote = await readGitRemoteUrl(options);\n const gitRemoteHost =\n gitRemote === undefined ? undefined : parseGitRemoteHost(gitRemote);\n invariant(\n gitRemoteHost !== undefined,\n \"Cannot resolve the Foundry host. Please set FOUNDRY_EXTERNAL_HOST or \" +\n \"FOUNDRY_HOSTNAME, or configure a git remote pointing at Foundry.\",\n );\n return gitRemoteHost;\n};\n"],"mappings":"AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA,OAAOA,SAAS,MAAM,gBAAgB;AAGtC,SAASC,gBAAgB,QAAQ,gBAAgB;AAajD,MAAMC,kBAAkB,GAAIC,SAAiB,IAAyB;EACpE,IAAI;IACF;IACA;IACA;IACA,OAAO,IAAIC,GAAG,CAACD,SAAS,CAAC,CAACE,QAAQ,IAAIC,SAAS;EACjD,CAAC,CAAC,MAAM;IACN;IACA,MAAMC,IAAI,GAAGJ,SAAS,CACnBK,KAAK,CAACL,SAAS,CAACM,WAAW,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CACrCC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CACbA,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;IAChB,OAAOH,IAAI,KAAK,EAAE,GAAGD,SAAS,GAAGC,IAAI;EACvC;AACF,CAAC;;AAED;AACA;AACA;AACA,MAAMI,mBAAmB,GAAIC,KAAa,IAAyB;EACjE,MAAMC,OAAO,GAAGD,KAAK,CAACE,IAAI,CAAC,CAAC;EAC5B,IAAIC,OAA2B;EAC/B,IAAI;IACFA,OAAO,GAAG,IAAIX,GAAG,CAACS,OAAO,CAAC,CAACN,IAAI,IAAID,SAAS;EAC9C,CAAC,CAAC,MAAM;IACNS,OAAO,GAAGT,SAAS;EACrB;EACA,OAAOS,OAAO,KAAKF,OAAO,CAACH,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,IAAIJ,SAAS,CAAC;AACxD,CAAC;AAED,OAAO,MAAMU,kBAAkB,GAAG,MAAAA,CAChCC,OAAkC,GAAG,CAAC,CAAC,KACnB;EACpB,MAAMC,GAAG,GAAGD,OAAO,CAACC,GAAG,IAAIC,OAAO,CAACD,GAAG;EACtC,MAAME,QAAQ,GAAGF,GAAG,CAACG,qBAAqB,IAAIH,GAAG,CAACI,gBAAgB;EAClE,IAAIF,QAAQ,EAAE;IACZ,MAAMG,UAAU,GAAGZ,mBAAmB,CAACS,QAAQ,CAAC;IAChD,IAAIG,UAAU,EAAE;MACd,OAAOA,UAAU;IACnB;EACF;EACA,MAAMpB,SAAS,GAAG,MAAMF,gBAAgB,CAACgB,OAAO,CAAC;EACjD,MAAMO,aAAa,GACjBrB,SAAS,KAAKG,SAAS,GAAGA,SAAS,GAAGJ,kBAAkB,CAACC,SAAS,CAAC;EACrE,EACEqB,aAAa,KAAKlB,SAAS,IAAAa,OAAA,CAAAD,GAAA,CAAAO,QAAA,oBAD7BzB,SAAS,QAEP,uEAAuE,GACrE,kEAAkE,IAHtEA,SAAS;EAKT,OAAOwB,aAAa;AACtB,CAAC","ignoreList":[]}
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Copyright 2026 Palantir Technologies, Inc. All rights reserved.
|
|
3
|
+
*
|
|
4
|
+
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
5
|
+
* you may not use this file except in compliance with the License.
|
|
6
|
+
* You may obtain a copy of the License at
|
|
7
|
+
*
|
|
8
|
+
* http://www.apache.org/licenses/LICENSE-2.0
|
|
9
|
+
*
|
|
10
|
+
* Unless required by applicable law or agreed to in writing, software
|
|
11
|
+
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
12
|
+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
13
|
+
* See the License for the specific language governing permissions and
|
|
14
|
+
* limitations under the License.
|
|
15
|
+
*/
|
|
16
|
+
|
|
17
|
+
import { readFile } from "node:fs/promises";
|
|
18
|
+
import invariant from "tiny-invariant";
|
|
19
|
+
import { readGitRemoteUrl } from "./gitRemote.js";
|
|
20
|
+
const parseGitRemoteToken = gitRemote => {
|
|
21
|
+
let url;
|
|
22
|
+
try {
|
|
23
|
+
url = new URL(gitRemote);
|
|
24
|
+
} catch {
|
|
25
|
+
return undefined;
|
|
26
|
+
}
|
|
27
|
+
const encodedToken = url.password || url.username;
|
|
28
|
+
return encodedToken.length ? decodeURIComponent(encodedToken) : undefined;
|
|
29
|
+
};
|
|
30
|
+
const resolveFoundryToken = async (options = {}) => {
|
|
31
|
+
const env = options.env ?? process.env;
|
|
32
|
+
if (env.FOUNDRY_CONTAINER_RUNTIME_TYPE === "CODE_WORKSPACE") {
|
|
33
|
+
const tokenPath = env.FOUNDRY_SCOPED_TOKEN;
|
|
34
|
+
!tokenPath ? process.env.NODE_ENV !== "production" ? invariant(false, "FOUNDRY_SCOPED_TOKEN: unbound variable") : invariant(false) : void 0;
|
|
35
|
+
const contents = await readFile(tokenPath, "utf-8");
|
|
36
|
+
return contents.trim();
|
|
37
|
+
}
|
|
38
|
+
if (env.FOUNDRY_HOSTNAME && env.FOUNDRY_TOKEN && env.FOUNDRY_USERNAME) {
|
|
39
|
+
return env.FOUNDRY_TOKEN;
|
|
40
|
+
}
|
|
41
|
+
const gitRemote = await readGitRemoteUrl(options);
|
|
42
|
+
!(gitRemote !== undefined) ? process.env.NODE_ENV !== "production" ? invariant(false, "Warning: Git remote url not set.\n" + "Please ensure the following environment variables are set " + "[FOUNDRY_HOSTNAME, FOUNDRY_USERNAME, FOUNDRY_TOKEN]") : invariant(false) : void 0;
|
|
43
|
+
return parseGitRemoteToken(gitRemote);
|
|
44
|
+
};
|
|
45
|
+
export const getFoundryToken = async (options = {}) => {
|
|
46
|
+
const token = await resolveFoundryToken(options);
|
|
47
|
+
!(token !== undefined) ? process.env.NODE_ENV !== "production" ? invariant(false, "Could not resolve token") : invariant(false) : void 0;
|
|
48
|
+
return token;
|
|
49
|
+
};
|
|
50
|
+
//# sourceMappingURL=foundry-token.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"foundry-token.js","names":["readFile","invariant","readGitRemoteUrl","parseGitRemoteToken","gitRemote","url","URL","undefined","encodedToken","password","username","length","decodeURIComponent","resolveFoundryToken","options","env","process","FOUNDRY_CONTAINER_RUNTIME_TYPE","tokenPath","FOUNDRY_SCOPED_TOKEN","NODE_ENV","contents","trim","FOUNDRY_HOSTNAME","FOUNDRY_TOKEN","FOUNDRY_USERNAME","getFoundryToken","token"],"sources":["foundry-token.ts"],"sourcesContent":["/*\n * Copyright 2026 Palantir Technologies, Inc. All rights reserved.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { readFile } from \"node:fs/promises\";\n\nimport invariant from \"tiny-invariant\";\n\nimport { readGitRemoteUrl } from \"./gitRemote.js\";\n\nexport interface ResolveBearerTokenOptions {\n env?: NodeJS.ProcessEnv;\n cwd?: string;\n}\n\nconst parseGitRemoteToken = (gitRemote: string): string | undefined => {\n let url: URL;\n try {\n url = new URL(gitRemote);\n } catch {\n return undefined;\n }\n const encodedToken = url.password || url.username;\n return encodedToken.length ? decodeURIComponent(encodedToken) : undefined;\n};\n\nconst resolveFoundryToken = async (\n options: ResolveBearerTokenOptions = {},\n): Promise<string | undefined> => {\n const env = options.env ?? process.env;\n if (env.FOUNDRY_CONTAINER_RUNTIME_TYPE === \"CODE_WORKSPACE\") {\n const tokenPath = env.FOUNDRY_SCOPED_TOKEN;\n invariant(tokenPath, \"FOUNDRY_SCOPED_TOKEN: unbound variable\");\n const contents = await readFile(tokenPath, \"utf-8\");\n return contents.trim();\n }\n if (env.FOUNDRY_HOSTNAME && env.FOUNDRY_TOKEN && env.FOUNDRY_USERNAME) {\n return env.FOUNDRY_TOKEN;\n }\n const gitRemote = await readGitRemoteUrl(options);\n invariant(\n gitRemote !== undefined,\n \"Warning: Git remote url not set.\\n\" +\n \"Please ensure the following environment variables are set \" +\n \"[FOUNDRY_HOSTNAME, FOUNDRY_USERNAME, FOUNDRY_TOKEN]\",\n );\n return parseGitRemoteToken(gitRemote);\n};\n\nexport const getFoundryToken = async (\n options: ResolveBearerTokenOptions = {},\n): Promise<string> => {\n const token = await resolveFoundryToken(options);\n invariant(token !== undefined, \"Could not resolve token\");\n return token;\n};\n"],"mappings":"AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA,SAASA,QAAQ,QAAQ,kBAAkB;AAE3C,OAAOC,SAAS,MAAM,gBAAgB;AAEtC,SAASC,gBAAgB,QAAQ,gBAAgB;AAOjD,MAAMC,mBAAmB,GAAIC,SAAiB,IAAyB;EACrE,IAAIC,GAAQ;EACZ,IAAI;IACFA,GAAG,GAAG,IAAIC,GAAG,CAACF,SAAS,CAAC;EAC1B,CAAC,CAAC,MAAM;IACN,OAAOG,SAAS;EAClB;EACA,MAAMC,YAAY,GAAGH,GAAG,CAACI,QAAQ,IAAIJ,GAAG,CAACK,QAAQ;EACjD,OAAOF,YAAY,CAACG,MAAM,GAAGC,kBAAkB,CAACJ,YAAY,CAAC,GAAGD,SAAS;AAC3E,CAAC;AAED,MAAMM,mBAAmB,GAAG,MAAAA,CAC1BC,OAAkC,GAAG,CAAC,CAAC,KACP;EAChC,MAAMC,GAAG,GAAGD,OAAO,CAACC,GAAG,IAAIC,OAAO,CAACD,GAAG;EACtC,IAAIA,GAAG,CAACE,8BAA8B,KAAK,gBAAgB,EAAE;IAC3D,MAAMC,SAAS,GAAGH,GAAG,CAACI,oBAAoB;IAC1C,CAAUD,SAAS,GAAAF,OAAA,CAAAD,GAAA,CAAAK,QAAA,oBAAnBnB,SAAS,QAAY,wCAAwC,IAA7DA,SAAS;IACT,MAAMoB,QAAQ,GAAG,MAAMrB,QAAQ,CAACkB,SAAS,EAAE,OAAO,CAAC;IACnD,OAAOG,QAAQ,CAACC,IAAI,CAAC,CAAC;EACxB;EACA,IAAIP,GAAG,CAACQ,gBAAgB,IAAIR,GAAG,CAACS,aAAa,IAAIT,GAAG,CAACU,gBAAgB,EAAE;IACrE,OAAOV,GAAG,CAACS,aAAa;EAC1B;EACA,MAAMpB,SAAS,GAAG,MAAMF,gBAAgB,CAACY,OAAO,CAAC;EACjD,EACEV,SAAS,KAAKG,SAAS,IAAAS,OAAA,CAAAD,GAAA,CAAAK,QAAA,oBADzBnB,SAAS,QAEP,oCAAoC,GAClC,4DAA4D,GAC5D,qDAAqD,IAJzDA,SAAS;EAMT,OAAOE,mBAAmB,CAACC,SAAS,CAAC;AACvC,CAAC;AAED,OAAO,MAAMsB,eAAe,GAAG,MAAAA,CAC7BZ,OAAkC,GAAG,CAAC,CAAC,KACnB;EACpB,MAAMa,KAAK,GAAG,MAAMd,mBAAmB,CAACC,OAAO,CAAC;EAChD,EAAUa,KAAK,KAAKpB,SAAS,IAAAS,OAAA,CAAAD,GAAA,CAAAK,QAAA,oBAA7BnB,SAAS,QAAsB,yBAAyB,IAAxDA,SAAS;EACT,OAAO0B,KAAK;AACd,CAAC","ignoreList":[]}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Copyright 2026 Palantir Technologies, Inc. All rights reserved.
|
|
3
|
+
*
|
|
4
|
+
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
5
|
+
* you may not use this file except in compliance with the License.
|
|
6
|
+
* You may obtain a copy of the License at
|
|
7
|
+
*
|
|
8
|
+
* http://www.apache.org/licenses/LICENSE-2.0
|
|
9
|
+
*
|
|
10
|
+
* Unless required by applicable law or agreed to in writing, software
|
|
11
|
+
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
12
|
+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
13
|
+
* See the License for the specific language governing permissions and
|
|
14
|
+
* limitations under the License.
|
|
15
|
+
*/
|
|
16
|
+
|
|
17
|
+
import { execFile } from "node:child_process";
|
|
18
|
+
import { promisify } from "node:util";
|
|
19
|
+
const execFileAsync = promisify(execFile);
|
|
20
|
+
/**
|
|
21
|
+
* Reads `remote.origin.url` from the git config of `cwd`, returning `undefined`
|
|
22
|
+
* when git fails or no remote is configured.
|
|
23
|
+
*/
|
|
24
|
+
export const readGitRemoteUrl = async (options = {}) => {
|
|
25
|
+
const env = options.env ?? process.env;
|
|
26
|
+
const cwd = options.cwd ?? env.INIT_CWD ?? process.cwd();
|
|
27
|
+
try {
|
|
28
|
+
const {
|
|
29
|
+
stdout
|
|
30
|
+
} = await execFileAsync("git", ["config", "remote.origin.url"], {
|
|
31
|
+
cwd
|
|
32
|
+
});
|
|
33
|
+
const gitRemote = stdout.trim();
|
|
34
|
+
return gitRemote.length === 0 ? undefined : gitRemote;
|
|
35
|
+
} catch {
|
|
36
|
+
return undefined;
|
|
37
|
+
}
|
|
38
|
+
};
|
|
39
|
+
//# sourceMappingURL=gitRemote.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"gitRemote.js","names":["execFile","promisify","execFileAsync","readGitRemoteUrl","options","env","process","cwd","INIT_CWD","stdout","gitRemote","trim","length","undefined"],"sources":["gitRemote.ts"],"sourcesContent":["/*\n * Copyright 2026 Palantir Technologies, Inc. All rights reserved.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { execFile } from \"node:child_process\";\nimport { promisify } from \"node:util\";\n\nconst execFileAsync = promisify(execFile);\n\nexport interface GitRemoteOptions {\n env?: NodeJS.ProcessEnv;\n cwd?: string;\n}\n\n/**\n * Reads `remote.origin.url` from the git config of `cwd`, returning `undefined`\n * when git fails or no remote is configured.\n */\nexport const readGitRemoteUrl = async (\n options: GitRemoteOptions = {},\n): Promise<string | undefined> => {\n const env = options.env ?? process.env;\n const cwd = options.cwd ?? env.INIT_CWD ?? process.cwd();\n try {\n const { stdout } = await execFileAsync(\n \"git\",\n [\"config\", \"remote.origin.url\"],\n { cwd },\n );\n const gitRemote = stdout.trim();\n return gitRemote.length === 0 ? undefined : gitRemote;\n } catch {\n return undefined;\n }\n};\n"],"mappings":"AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA,SAASA,QAAQ,QAAQ,oBAAoB;AAC7C,SAASC,SAAS,QAAQ,WAAW;AAErC,MAAMC,aAAa,GAAGD,SAAS,CAACD,QAAQ,CAAC;AAOzC;AACA;AACA;AACA;AACA,OAAO,MAAMG,gBAAgB,GAAG,MAAAA,CAC9BC,OAAyB,GAAG,CAAC,CAAC,KACE;EAChC,MAAMC,GAAG,GAAGD,OAAO,CAACC,GAAG,IAAIC,OAAO,CAACD,GAAG;EACtC,MAAME,GAAG,GAAGH,OAAO,CAACG,GAAG,IAAIF,GAAG,CAACG,QAAQ,IAAIF,OAAO,CAACC,GAAG,CAAC,CAAC;EACxD,IAAI;IACF,MAAM;MAAEE;IAAO,CAAC,GAAG,MAAMP,aAAa,CACpC,KAAK,EACL,CAAC,QAAQ,EAAE,mBAAmB,CAAC,EAC/B;MAAEK;IAAI,CACR,CAAC;IACD,MAAMG,SAAS,GAAGD,MAAM,CAACE,IAAI,CAAC,CAAC;IAC/B,OAAOD,SAAS,CAACE,MAAM,KAAK,CAAC,GAAGC,SAAS,GAAGH,SAAS;EACvD,CAAC,CAAC,MAAM;IACN,OAAOG,SAAS;EAClB;AACF,CAAC","ignoreList":[]}
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Copyright 2026 Palantir Technologies, Inc. All rights reserved.
|
|
3
|
+
*
|
|
4
|
+
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
5
|
+
* you may not use this file except in compliance with the License.
|
|
6
|
+
* You may obtain a copy of the License at
|
|
7
|
+
*
|
|
8
|
+
* http://www.apache.org/licenses/LICENSE-2.0
|
|
9
|
+
*
|
|
10
|
+
* Unless required by applicable law or agreed to in writing, software
|
|
11
|
+
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
12
|
+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
13
|
+
* See the License for the specific language governing permissions and
|
|
14
|
+
* limitations under the License.
|
|
15
|
+
*/
|
|
16
|
+
|
|
17
|
+
import consola from "consola";
|
|
18
|
+
import invariant from "tiny-invariant";
|
|
19
|
+
import { checkFoundryCliVersion, MIN_FOUNDRY_CLI_VERSION } from "../utils/foundry-cli.js";
|
|
20
|
+
import { installFoundryCli } from "./download.js";
|
|
21
|
+
export const postinstall = async () => {
|
|
22
|
+
const result = await checkFoundryCliVersion();
|
|
23
|
+
switch (result.type) {
|
|
24
|
+
case "installed":
|
|
25
|
+
consola.info(`✅ Foundry CLI (v${result.version}) is installed already, skipping installation.`);
|
|
26
|
+
return;
|
|
27
|
+
case "version-error":
|
|
28
|
+
consola.warn(`Foundry CLI is installed, but we could not probe its version.`);
|
|
29
|
+
return;
|
|
30
|
+
case "version-incompatible":
|
|
31
|
+
process.env.NODE_ENV !== "production" ? invariant(false, `Foundry CLI (v${result.version}) is installed already, but the minimum required version is ${MIN_FOUNDRY_CLI_VERSION}. Please run "foundry update self" to update foundry cli.`) : invariant(false);
|
|
32
|
+
return;
|
|
33
|
+
case "not-found":
|
|
34
|
+
consola.info(`Foundry CLI not found locally, attempting to install...`);
|
|
35
|
+
await installFoundryCli();
|
|
36
|
+
}
|
|
37
|
+
};
|
|
38
|
+
//# sourceMappingURL=postinstall.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"postinstall.js","names":["consola","invariant","checkFoundryCliVersion","MIN_FOUNDRY_CLI_VERSION","installFoundryCli","postinstall","result","type","info","version","warn","process","env","NODE_ENV"],"sources":["postinstall.ts"],"sourcesContent":["/*\n * Copyright 2026 Palantir Technologies, Inc. All rights reserved.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport consola from \"consola\";\nimport invariant from \"tiny-invariant\";\n\nimport {\n checkFoundryCliVersion,\n MIN_FOUNDRY_CLI_VERSION,\n} from \"../utils/foundry-cli.js\";\nimport { installFoundryCli } from \"./download.js\";\n\nexport const postinstall = async (): Promise<void> => {\n const result = await checkFoundryCliVersion();\n switch (result.type) {\n case \"installed\":\n consola.info(\n `✅ Foundry CLI (v${result.version}) is installed already, skipping installation.`,\n );\n return;\n case \"version-error\":\n consola.warn(\n `Foundry CLI is installed, but we could not probe its version.`,\n );\n return;\n case \"version-incompatible\":\n invariant(\n false,\n `Foundry CLI (v${result.version}) is installed already, but the minimum required version is ${MIN_FOUNDRY_CLI_VERSION}. Please run \"foundry update self\" to update foundry cli.`,\n );\n return;\n case \"not-found\":\n consola.info(`Foundry CLI not found locally, attempting to install...`);\n await installFoundryCli();\n return;\n }\n};\n"],"mappings":"AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA,OAAOA,OAAO,MAAM,SAAS;AAC7B,OAAOC,SAAS,MAAM,gBAAgB;AAEtC,SACEC,sBAAsB,EACtBC,uBAAuB,QAClB,yBAAyB;AAChC,SAASC,iBAAiB,QAAQ,eAAe;AAEjD,OAAO,MAAMC,WAAW,GAAG,MAAAA,CAAA,KAA2B;EACpD,MAAMC,MAAM,GAAG,MAAMJ,sBAAsB,CAAC,CAAC;EAC7C,QAAQI,MAAM,CAACC,IAAI;IACjB,KAAK,WAAW;MACdP,OAAO,CAACQ,IAAI,CACV,mBAAmBF,MAAM,CAACG,OAAO,gDACnC,CAAC;MACD;IACF,KAAK,eAAe;MAClBT,OAAO,CAACU,IAAI,CACV,+DACF,CAAC;MACD;IACF,KAAK,sBAAsB;MACzBC,OAAA,CAAAC,GAAA,CAAAC,QAAA,oBAAAZ,SAAS,QAEP,iBAAiBK,MAAM,CAACG,OAAO,+DAA+DN,uBAAuB,2DAA2D,IAFlLF,SAAS;MAIT;IACF,KAAK,WAAW;MACdD,OAAO,CAACQ,IAAI,CAAC,yDAAyD,CAAC;MACvE,MAAMJ,iBAAiB,CAAC,CAAC;EAE7B;AACF,CAAC","ignoreList":[]}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Copyright 2026 Palantir Technologies, Inc. All rights reserved.
|
|
3
|
+
*
|
|
4
|
+
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
5
|
+
* you may not use this file except in compliance with the License.
|
|
6
|
+
* You may obtain a copy of the License at
|
|
7
|
+
*
|
|
8
|
+
* http://www.apache.org/licenses/LICENSE-2.0
|
|
9
|
+
*
|
|
10
|
+
* Unless required by applicable law or agreed to in writing, software
|
|
11
|
+
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
12
|
+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
13
|
+
* See the License for the specific language governing permissions and
|
|
14
|
+
* limitations under the License.
|
|
15
|
+
*/
|
|
16
|
+
|
|
17
|
+
import { StatusServer } from "../cli-service/StatusServer.js";
|
|
18
|
+
|
|
19
|
+
/**
|
|
20
|
+
* A {@link StatusServer} that never spawns the Foundry CLI, for tests that put
|
|
21
|
+
* a stub server behind it: health and status reads still go over HTTP to
|
|
22
|
+
* whatever the discoverer found, but starting is a no-op rather than a spawn —
|
|
23
|
+
* or, since a discoverable stub is already answering, a refusal to start.
|
|
24
|
+
*/
|
|
25
|
+
export class NoSpawnStatusServer extends StatusServer {
|
|
26
|
+
start() {
|
|
27
|
+
return Promise.resolve();
|
|
28
|
+
}
|
|
29
|
+
stop() {
|
|
30
|
+
return Promise.resolve();
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
//# sourceMappingURL=NoSpawnStatusServer.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"NoSpawnStatusServer.js","names":["StatusServer","NoSpawnStatusServer","start","Promise","resolve","stop"],"sources":["NoSpawnStatusServer.ts"],"sourcesContent":["/*\n * Copyright 2026 Palantir Technologies, Inc. All rights reserved.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { StatusServer } from \"../cli-service/StatusServer.js\";\n\n/**\n * A {@link StatusServer} that never spawns the Foundry CLI, for tests that put\n * a stub server behind it: health and status reads still go over HTTP to\n * whatever the discoverer found, but starting is a no-op rather than a spawn —\n * or, since a discoverable stub is already answering, a refusal to start.\n */\nexport class NoSpawnStatusServer extends StatusServer {\n override start(): Promise<void> {\n return Promise.resolve();\n }\n\n override stop(): Promise<void> {\n return Promise.resolve();\n }\n}\n"],"mappings":"AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA,SAASA,YAAY,QAAQ,gCAAgC;;AAE7D;AACA;AACA;AACA;AACA;AACA;AACA,OAAO,MAAMC,mBAAmB,SAASD,YAAY,CAAC;EAC3CE,KAAKA,CAAA,EAAkB;IAC9B,OAAOC,OAAO,CAACC,OAAO,CAAC,CAAC;EAC1B;EAESC,IAAIA,CAAA,EAAkB;IAC7B,OAAOF,OAAO,CAACC,OAAO,CAAC,CAAC;EAC1B;AACF","ignoreList":[]}
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Copyright 2026 Palantir Technologies, Inc. All rights reserved.
|
|
3
|
+
*
|
|
4
|
+
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
5
|
+
* you may not use this file except in compliance with the License.
|
|
6
|
+
* You may obtain a copy of the License at
|
|
7
|
+
*
|
|
8
|
+
* http://www.apache.org/licenses/LICENSE-2.0
|
|
9
|
+
*
|
|
10
|
+
* Unless required by applicable law or agreed to in writing, software
|
|
11
|
+
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
12
|
+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
13
|
+
* See the License for the specific language governing permissions and
|
|
14
|
+
* limitations under the License.
|
|
15
|
+
*/
|
|
16
|
+
|
|
17
|
+
import { FoundryCliService } from "../cli-service/FoundryCliService.js";
|
|
18
|
+
/**
|
|
19
|
+
* A {@link FoundryCliService} that reports its own health and never spawns
|
|
20
|
+
* anything, so orchestration can be tested without the Foundry CLI.
|
|
21
|
+
*/
|
|
22
|
+
export class StubService extends FoundryCliService {
|
|
23
|
+
#startLog;
|
|
24
|
+
#stateWhenStarted;
|
|
25
|
+
#message;
|
|
26
|
+
#started = false;
|
|
27
|
+
constructor(name, config) {
|
|
28
|
+
super(name, config);
|
|
29
|
+
this.#startLog = config.startLog;
|
|
30
|
+
this.#stateWhenStarted = config.stateWhenStarted ?? "READY";
|
|
31
|
+
this.#message = config.message;
|
|
32
|
+
}
|
|
33
|
+
getArgs() {
|
|
34
|
+
return [];
|
|
35
|
+
}
|
|
36
|
+
isStarted() {
|
|
37
|
+
return this.#started;
|
|
38
|
+
}
|
|
39
|
+
start() {
|
|
40
|
+
this.#started = true;
|
|
41
|
+
this.#startLog?.push(this.name);
|
|
42
|
+
return Promise.resolve();
|
|
43
|
+
}
|
|
44
|
+
checkHealth() {
|
|
45
|
+
const state = this.#started ? this.#stateWhenStarted : "UNDISCOVERED";
|
|
46
|
+
return Promise.resolve({
|
|
47
|
+
service: this.name,
|
|
48
|
+
state,
|
|
49
|
+
ready: state === "READY",
|
|
50
|
+
terminal: state === "FAILED" || state === "STOPPED",
|
|
51
|
+
...(this.#message !== undefined ? {
|
|
52
|
+
message: this.#message
|
|
53
|
+
} : {})
|
|
54
|
+
});
|
|
55
|
+
}
|
|
56
|
+
stop() {
|
|
57
|
+
this.#started = false;
|
|
58
|
+
return Promise.resolve();
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
//# sourceMappingURL=StubService.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"StubService.js","names":["FoundryCliService","StubService","startLog","stateWhenStarted","message","started","constructor","name","config","getArgs","isStarted","start","push","Promise","resolve","checkHealth","state","service","ready","terminal","undefined","stop"],"sources":["StubService.ts"],"sourcesContent":["/*\n * Copyright 2026 Palantir Technologies, Inc. All rights reserved.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport {\n FoundryCliService,\n type FoundryServiceConfig,\n type ServiceHealth,\n type ServiceState,\n} from \"../cli-service/FoundryCliService.js\";\nimport type { ServiceName } from \"../generated/cli/index.js\";\n\nexport interface StubServiceConfig extends FoundryServiceConfig {\n /** Recorded in order as services start, for asserting dependency order. */\n startLog?: ServiceName[];\n /** State reported once started. Defaults to `READY`. */\n stateWhenStarted?: ServiceState;\n /** Explanation reported alongside the state, as a real service publishes. */\n message?: string;\n}\n\n/**\n * A {@link FoundryCliService} that reports its own health and never spawns\n * anything, so orchestration can be tested without the Foundry CLI.\n */\nexport class StubService extends FoundryCliService {\n #startLog: ServiceName[] | undefined;\n #stateWhenStarted: ServiceState;\n #message: string | undefined;\n #started = false;\n\n constructor(name: ServiceName, config: StubServiceConfig) {\n super(name, config);\n this.#startLog = config.startLog;\n this.#stateWhenStarted = config.stateWhenStarted ?? \"READY\";\n this.#message = config.message;\n }\n\n protected override getArgs(): readonly string[] {\n return [];\n }\n\n isStarted(): boolean {\n return this.#started;\n }\n\n override start(): Promise<void> {\n this.#started = true;\n this.#startLog?.push(this.name);\n return Promise.resolve();\n }\n\n override checkHealth(): Promise<ServiceHealth> {\n const state: ServiceState = this.#started\n ? this.#stateWhenStarted\n : \"UNDISCOVERED\";\n return Promise.resolve({\n service: this.name,\n state,\n ready: state === \"READY\",\n terminal: state === \"FAILED\" || state === \"STOPPED\",\n ...(this.#message !== undefined ? { message: this.#message } : {}),\n });\n }\n\n override stop(): Promise<void> {\n this.#started = false;\n return Promise.resolve();\n }\n}\n"],"mappings":"AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA,SACEA,iBAAiB,QAIZ,qCAAqC;AAY5C;AACA;AACA;AACA;AACA,OAAO,MAAMC,WAAW,SAASD,iBAAiB,CAAC;EACjD,CAACE,QAAQ;EACT,CAACC,gBAAgB;EACjB,CAACC,OAAO;EACR,CAACC,OAAO,GAAG,KAAK;EAEhBC,WAAWA,CAACC,IAAiB,EAAEC,MAAyB,EAAE;IACxD,KAAK,CAACD,IAAI,EAAEC,MAAM,CAAC;IACnB,IAAI,CAAC,CAACN,QAAQ,GAAGM,MAAM,CAACN,QAAQ;IAChC,IAAI,CAAC,CAACC,gBAAgB,GAAGK,MAAM,CAACL,gBAAgB,IAAI,OAAO;IAC3D,IAAI,CAAC,CAACC,OAAO,GAAGI,MAAM,CAACJ,OAAO;EAChC;EAEmBK,OAAOA,CAAA,EAAsB;IAC9C,OAAO,EAAE;EACX;EAEAC,SAASA,CAAA,EAAY;IACnB,OAAO,IAAI,CAAC,CAACL,OAAO;EACtB;EAESM,KAAKA,CAAA,EAAkB;IAC9B,IAAI,CAAC,CAACN,OAAO,GAAG,IAAI;IACpB,IAAI,CAAC,CAACH,QAAQ,EAAEU,IAAI,CAAC,IAAI,CAACL,IAAI,CAAC;IAC/B,OAAOM,OAAO,CAACC,OAAO,CAAC,CAAC;EAC1B;EAESC,WAAWA,CAAA,EAA2B;IAC7C,MAAMC,KAAmB,GAAG,IAAI,CAAC,CAACX,OAAO,GACrC,IAAI,CAAC,CAACF,gBAAgB,GACtB,cAAc;IAClB,OAAOU,OAAO,CAACC,OAAO,CAAC;MACrBG,OAAO,EAAE,IAAI,CAACV,IAAI;MAClBS,KAAK;MACLE,KAAK,EAAEF,KAAK,KAAK,OAAO;MACxBG,QAAQ,EAAEH,KAAK,KAAK,QAAQ,IAAIA,KAAK,KAAK,SAAS;MACnD,IAAI,IAAI,CAAC,CAACZ,OAAO,KAAKgB,SAAS,GAAG;QAAEhB,OAAO,EAAE,IAAI,CAAC,CAACA;MAAQ,CAAC,GAAG,CAAC,CAAC;IACnE,CAAC,CAAC;EACJ;EAESiB,IAAIA,CAAA,EAAkB;IAC7B,IAAI,CAAC,CAAChB,OAAO,GAAG,KAAK;IACrB,OAAOQ,OAAO,CAACC,OAAO,CAAC,CAAC;EAC1B;AACF","ignoreList":[]}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Copyright 2026 Palantir Technologies, Inc. All rights reserved.
|
|
3
|
+
*
|
|
4
|
+
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
5
|
+
* you may not use this file except in compliance with the License.
|
|
6
|
+
* You may obtain a copy of the License at
|
|
7
|
+
*
|
|
8
|
+
* http://www.apache.org/licenses/LICENSE-2.0
|
|
9
|
+
*
|
|
10
|
+
* Unless required by applicable law or agreed to in writing, software
|
|
11
|
+
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
12
|
+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
13
|
+
* See the License for the specific language governing permissions and
|
|
14
|
+
* limitations under the License.
|
|
15
|
+
*/
|
|
16
|
+
|
|
17
|
+
/** The smallest metadata the ontology server accepts. */
|
|
18
|
+
export const EMPTY_ONTOLOGY_METADATA = {
|
|
19
|
+
ontology: {
|
|
20
|
+
apiName: "ontology",
|
|
21
|
+
rid: "ri.ontology.main.ontology.0",
|
|
22
|
+
displayName: "ontology",
|
|
23
|
+
description: "local ontology"
|
|
24
|
+
},
|
|
25
|
+
objectTypes: {},
|
|
26
|
+
actionTypes: {},
|
|
27
|
+
queryTypes: {},
|
|
28
|
+
interfaceTypes: {},
|
|
29
|
+
sharedPropertyTypes: {},
|
|
30
|
+
valueTypes: {}
|
|
31
|
+
};
|
|
32
|
+
//# sourceMappingURL=emptyOntologyMetadata.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"emptyOntologyMetadata.js","names":["EMPTY_ONTOLOGY_METADATA","ontology","apiName","rid","displayName","description","objectTypes","actionTypes","queryTypes","interfaceTypes","sharedPropertyTypes","valueTypes"],"sources":["emptyOntologyMetadata.ts"],"sourcesContent":["/*\n * Copyright 2026 Palantir Technologies, Inc. All rights reserved.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport type { OntologyFullMetadata } from \"@osdk/foundry.ontologies\";\n\n/** The smallest metadata the ontology server accepts. */\nexport const EMPTY_ONTOLOGY_METADATA: OntologyFullMetadata = {\n ontology: {\n apiName: \"ontology\",\n rid: \"ri.ontology.main.ontology.0\",\n displayName: \"ontology\",\n description: \"local ontology\",\n },\n objectTypes: {},\n actionTypes: {},\n queryTypes: {},\n interfaceTypes: {},\n sharedPropertyTypes: {},\n valueTypes: {},\n};\n"],"mappings":"AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAIA;AACA,OAAO,MAAMA,uBAA6C,GAAG;EAC3DC,QAAQ,EAAE;IACRC,OAAO,EAAE,UAAU;IACnBC,GAAG,EAAE,6BAA6B;IAClCC,WAAW,EAAE,UAAU;IACvBC,WAAW,EAAE;EACf,CAAC;EACDC,WAAW,EAAE,CAAC,CAAC;EACfC,WAAW,EAAE,CAAC,CAAC;EACfC,UAAU,EAAE,CAAC,CAAC;EACdC,cAAc,EAAE,CAAC,CAAC;EAClBC,mBAAmB,EAAE,CAAC,CAAC;EACvBC,UAAU,EAAE,CAAC;AACf,CAAC","ignoreList":[]}
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Copyright 2026 Palantir Technologies, Inc. All rights reserved.
|
|
3
|
+
*
|
|
4
|
+
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
5
|
+
* you may not use this file except in compliance with the License.
|
|
6
|
+
* You may obtain a copy of the License at
|
|
7
|
+
*
|
|
8
|
+
* http://www.apache.org/licenses/LICENSE-2.0
|
|
9
|
+
*
|
|
10
|
+
* Unless required by applicable law or agreed to in writing, software
|
|
11
|
+
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
12
|
+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
13
|
+
* See the License for the specific language governing permissions and
|
|
14
|
+
* limitations under the License.
|
|
15
|
+
*/
|
|
16
|
+
|
|
17
|
+
import { createServer } from "node:http";
|
|
18
|
+
/**
|
|
19
|
+
* Stand-in for the real status server, mirroring the two behaviors the client
|
|
20
|
+
* code has to get right: `/api/health` is what reports the server's own health
|
|
21
|
+
* (it publishes no lifecycle for itself), and `GET /status` answers `204` — not
|
|
22
|
+
* an empty array — when nothing has reported yet.
|
|
23
|
+
*/
|
|
24
|
+
export const startStubStatusServer = async (initialStatuses = []) => {
|
|
25
|
+
const statuses = new Map(initialStatuses.map(status => [status.service, status]));
|
|
26
|
+
let healthy = true;
|
|
27
|
+
const server = createServer((req, res) => {
|
|
28
|
+
if (req.url === "/api/health") {
|
|
29
|
+
if (!healthy) {
|
|
30
|
+
res.writeHead(503).end();
|
|
31
|
+
return;
|
|
32
|
+
}
|
|
33
|
+
res.writeHead(200, {
|
|
34
|
+
"Content-Type": "application/json"
|
|
35
|
+
});
|
|
36
|
+
res.end(JSON.stringify({
|
|
37
|
+
status: "healthy"
|
|
38
|
+
}));
|
|
39
|
+
return;
|
|
40
|
+
}
|
|
41
|
+
if (req.url === "/status" && req.method === "GET") {
|
|
42
|
+
if (statuses.size === 0) {
|
|
43
|
+
res.writeHead(204).end();
|
|
44
|
+
return;
|
|
45
|
+
}
|
|
46
|
+
res.writeHead(200, {
|
|
47
|
+
"Content-Type": "application/json"
|
|
48
|
+
});
|
|
49
|
+
res.end(JSON.stringify([...statuses.values()]));
|
|
50
|
+
return;
|
|
51
|
+
}
|
|
52
|
+
res.writeHead(404).end();
|
|
53
|
+
});
|
|
54
|
+
await new Promise(resolve => server.listen(0, "127.0.0.1", resolve));
|
|
55
|
+
const {
|
|
56
|
+
port
|
|
57
|
+
} = server.address();
|
|
58
|
+
return {
|
|
59
|
+
url: `http://127.0.0.1:${port}`,
|
|
60
|
+
setHealthy: next => {
|
|
61
|
+
healthy = next;
|
|
62
|
+
},
|
|
63
|
+
close: () => new Promise((resolve, reject) => {
|
|
64
|
+
server.close(err => {
|
|
65
|
+
if (err != null) {
|
|
66
|
+
reject(err);
|
|
67
|
+
return;
|
|
68
|
+
}
|
|
69
|
+
resolve();
|
|
70
|
+
});
|
|
71
|
+
})
|
|
72
|
+
};
|
|
73
|
+
};
|
|
74
|
+
//# sourceMappingURL=stubStatusServer.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"stubStatusServer.js","names":["createServer","startStubStatusServer","initialStatuses","statuses","Map","map","status","service","healthy","server","req","res","url","writeHead","end","JSON","stringify","method","size","values","Promise","resolve","listen","port","address","setHealthy","next","close","reject","err"],"sources":["stubStatusServer.ts"],"sourcesContent":["/*\n * Copyright 2026 Palantir Technologies, Inc. All rights reserved.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { createServer, type Server } from \"node:http\";\nimport type { AddressInfo } from \"node:net\";\n\nimport type { ServiceName, ServiceStatus } from \"../generated/cli/index.js\";\n\nexport interface StubStatusServer {\n url: string;\n /** Toggle what `/api/health` answers. */\n setHealthy: (healthy: boolean) => void;\n close: () => Promise<void>;\n}\n\n/**\n * Stand-in for the real status server, mirroring the two behaviors the client\n * code has to get right: `/api/health` is what reports the server's own health\n * (it publishes no lifecycle for itself), and `GET /status` answers `204` — not\n * an empty array — when nothing has reported yet.\n */\nexport const startStubStatusServer = async (\n initialStatuses: ServiceStatus[] = [],\n): Promise<StubStatusServer> => {\n const statuses = new Map<ServiceName, ServiceStatus>(\n initialStatuses.map((status) => [status.service, status]),\n );\n let healthy = true;\n\n const server: Server = createServer((req, res) => {\n if (req.url === \"/api/health\") {\n if (!healthy) {\n res.writeHead(503).end();\n return;\n }\n res.writeHead(200, { \"Content-Type\": \"application/json\" });\n res.end(JSON.stringify({ status: \"healthy\" }));\n return;\n }\n if (req.url === \"/status\" && req.method === \"GET\") {\n if (statuses.size === 0) {\n res.writeHead(204).end();\n return;\n }\n res.writeHead(200, { \"Content-Type\": \"application/json\" });\n res.end(JSON.stringify([...statuses.values()]));\n return;\n }\n res.writeHead(404).end();\n });\n\n await new Promise<void>((resolve) => server.listen(0, \"127.0.0.1\", resolve));\n const { port } = server.address() as AddressInfo;\n\n return {\n url: `http://127.0.0.1:${port}`,\n setHealthy: (next) => {\n healthy = next;\n },\n close: () =>\n new Promise<void>((resolve, reject) => {\n server.close((err) => {\n if (err != null) {\n reject(err);\n return;\n }\n resolve();\n });\n }),\n };\n};\n"],"mappings":"AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA,SAASA,YAAY,QAAqB,WAAW;AAYrD;AACA;AACA;AACA;AACA;AACA;AACA,OAAO,MAAMC,qBAAqB,GAAG,MAAAA,CACnCC,eAAgC,GAAG,EAAE,KACP;EAC9B,MAAMC,QAAQ,GAAG,IAAIC,GAAG,CACtBF,eAAe,CAACG,GAAG,CAAEC,MAAM,IAAK,CAACA,MAAM,CAACC,OAAO,EAAED,MAAM,CAAC,CAC1D,CAAC;EACD,IAAIE,OAAO,GAAG,IAAI;EAElB,MAAMC,MAAc,GAAGT,YAAY,CAAC,CAACU,GAAG,EAAEC,GAAG,KAAK;IAChD,IAAID,GAAG,CAACE,GAAG,KAAK,aAAa,EAAE;MAC7B,IAAI,CAACJ,OAAO,EAAE;QACZG,GAAG,CAACE,SAAS,CAAC,GAAG,CAAC,CAACC,GAAG,CAAC,CAAC;QACxB;MACF;MACAH,GAAG,CAACE,SAAS,CAAC,GAAG,EAAE;QAAE,cAAc,EAAE;MAAmB,CAAC,CAAC;MAC1DF,GAAG,CAACG,GAAG,CAACC,IAAI,CAACC,SAAS,CAAC;QAAEV,MAAM,EAAE;MAAU,CAAC,CAAC,CAAC;MAC9C;IACF;IACA,IAAII,GAAG,CAACE,GAAG,KAAK,SAAS,IAAIF,GAAG,CAACO,MAAM,KAAK,KAAK,EAAE;MACjD,IAAId,QAAQ,CAACe,IAAI,KAAK,CAAC,EAAE;QACvBP,GAAG,CAACE,SAAS,CAAC,GAAG,CAAC,CAACC,GAAG,CAAC,CAAC;QACxB;MACF;MACAH,GAAG,CAACE,SAAS,CAAC,GAAG,EAAE;QAAE,cAAc,EAAE;MAAmB,CAAC,CAAC;MAC1DF,GAAG,CAACG,GAAG,CAACC,IAAI,CAACC,SAAS,CAAC,CAAC,GAAGb,QAAQ,CAACgB,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC;MAC/C;IACF;IACAR,GAAG,CAACE,SAAS,CAAC,GAAG,CAAC,CAACC,GAAG,CAAC,CAAC;EAC1B,CAAC,CAAC;EAEF,MAAM,IAAIM,OAAO,CAAQC,OAAO,IAAKZ,MAAM,CAACa,MAAM,CAAC,CAAC,EAAE,WAAW,EAAED,OAAO,CAAC,CAAC;EAC5E,MAAM;IAAEE;EAAK,CAAC,GAAGd,MAAM,CAACe,OAAO,CAAC,CAAgB;EAEhD,OAAO;IACLZ,GAAG,EAAE,oBAAoBW,IAAI,EAAE;IAC/BE,UAAU,EAAGC,IAAI,IAAK;MACpBlB,OAAO,GAAGkB,IAAI;IAChB,CAAC;IACDC,KAAK,EAAEA,CAAA,KACL,IAAIP,OAAO,CAAO,CAACC,OAAO,EAAEO,MAAM,KAAK;MACrCnB,MAAM,CAACkB,KAAK,CAAEE,GAAG,IAAK;QACpB,IAAIA,GAAG,IAAI,IAAI,EAAE;UACfD,MAAM,CAACC,GAAG,CAAC;UACX;QACF;QACAR,OAAO,CAAC,CAAC;MACX,CAAC,CAAC;IACJ,CAAC;EACL,CAAC;AACH,CAAC","ignoreList":[]}
|