@hitch42/applet 0.1.1-beta.6 → 0.1.1-beta.7
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/applet.js +39 -29
- package/dist/{build-DIsKQQT0.js → build-DauirTcY.js} +28 -13
- package/dist/build-DhNDp7ji.js +2 -0
- package/dist/{ci-D0nC_Ho7.js → ci-gPrwo6C0.js} +20 -4
- package/dist/client.d.ts +2 -2
- package/dist/{contract-DMrpbaLJ.d.ts → contract-DB9QQhD9.d.ts} +1 -1
- package/dist/{deploy-0dlUvCt3.js → deploy-CqrtNJ1x.js} +130 -15
- package/dist/{generate-C6eAL5eo.js → generate-BIifT6PK.js} +13 -13
- package/dist/generate-DSk8ihsC.js +2 -0
- package/dist/index.d.ts +3 -3
- package/dist/index.js +1 -1
- package/dist/{init-tEMeys9M.js → init-Wu6XmyVc.js} +5 -5
- package/dist/load-config-BknBkdRs.js +27 -0
- package/dist/login-iT9MRuaw.js +12 -0
- package/dist/{logs-m00pzr_O.js → logs-B-qZGXSK.js} +3 -3
- package/dist/{manifest-DyoJ1MIL.js → manifest-Bd04cWhu.js} +3 -0
- package/dist/{manifest-BQCAxATS.d.ts → manifest-C489nYUy.d.ts} +2 -0
- package/dist/{project-mW0vsN8A.js → project-C_rtpjp8.js} +12 -11
- package/dist/server.d.ts +2 -2
- package/dist/{variables-CP7Ce3Np.js → variables-DcwMeIau.js} +3 -3
- package/dist/vite.d.ts +1 -1
- package/dist/vite.js +4 -8
- package/dist/{auth-DaVK0k5R.js → workspace-B6lenAS5.js} +41 -4
- package/package.json +1 -1
- package/scaffold/.agents/skills/hitch-applets/SKILL.md +10 -0
- package/scaffold/.agents/skills/hitch-applets/references/manifest.md +17 -0
- package/scaffold/.agents/skills/hitch-cli/SKILL.md +5 -3
- package/scaffold/.agents/skills/hitch-data/SKILL.md +1 -1
- package/scaffold/.github/workflows/hitch.yml +0 -6
- package/dist/build-B70gkDi5.js +0 -2
- package/dist/generate-D5rSXXa-.js +0 -2
- package/dist/load-config-BnxocLAQ.js +0 -56
package/dist/applet.js
CHANGED
|
@@ -2,18 +2,22 @@
|
|
|
2
2
|
import { parseArgs } from "node:util";
|
|
3
3
|
//#region bin/applet.ts
|
|
4
4
|
const usage = `Usage:
|
|
5
|
+
applet login [--no-browser]
|
|
5
6
|
applet init <org> [--no-commit | --no-git] [--no-install]
|
|
6
7
|
applet bootstrap [--no-install]
|
|
7
8
|
applet new <code> [--client-only | --server-only] [--no-install]
|
|
8
|
-
applet generate
|
|
9
|
-
applet build
|
|
10
|
-
applet deploy
|
|
9
|
+
applet generate
|
|
10
|
+
applet build
|
|
11
|
+
applet deploy
|
|
11
12
|
applet logs [code] [--since <duration>] [--limit <count>]
|
|
12
13
|
[--search <text>] [--level <level>] [--filter <json>] [--run <id>] [--live]
|
|
13
14
|
applet variables set <KEY> [value] [--secret] [-y | --yes]
|
|
14
15
|
applet variables list
|
|
15
16
|
applet variables delete <KEY> [-y | --yes]
|
|
16
17
|
|
|
18
|
+
Login options:
|
|
19
|
+
--no-browser Print the sign-in URL without opening a browser.
|
|
20
|
+
|
|
17
21
|
Init options:
|
|
18
22
|
--no-commit Do not create the initial commit
|
|
19
23
|
--no-git Do not create a git repository
|
|
@@ -27,15 +31,14 @@ New options:
|
|
|
27
31
|
Bootstrap options:
|
|
28
32
|
--no-install Do not run pnpm install
|
|
29
33
|
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
34
|
+
Schema changesets:
|
|
35
|
+
Set requiresChangeset in applet.manifest.ts to generate, build, and deploy
|
|
36
|
+
against a pending changeset. The release goes live when the changeset
|
|
37
|
+
applies in Hitch. After it applies, the field uses the live schema.
|
|
33
38
|
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
when the changeset applies. Manifest mismatches warn.
|
|
38
|
-
Run applet deploy in the workspace root to deploy every applet.
|
|
39
|
+
Run applet deploy in the workspace root to deploy every applet. In GitHub
|
|
40
|
+
Actions it skips an applet when neither its folder nor any file outside
|
|
41
|
+
applets/ changed since its current CI release.
|
|
39
42
|
|
|
40
43
|
Logs options:
|
|
41
44
|
--since <duration> Show logs from this period. Default: 1h. Maximum: 7d.
|
|
@@ -52,6 +55,8 @@ Variables options:
|
|
|
52
55
|
--secret Store the value as a secret.
|
|
53
56
|
-y, --yes Skip the live applet confirmation.
|
|
54
57
|
|
|
58
|
+
Login: applet login selects the organization from hitch.config.ts and shares
|
|
59
|
+
credentials with hitch login.
|
|
55
60
|
CI: set HITCH_API_KEY (and HITCH_API_URL for a non-default instance).
|
|
56
61
|
GitHub Actions: generate, build, and deploy use the job's OIDC token instead of
|
|
57
62
|
a key. Grant the job id-token: write.`;
|
|
@@ -59,13 +64,13 @@ async function main() {
|
|
|
59
64
|
const { positionals, values } = parseArgs({
|
|
60
65
|
allowPositionals: true,
|
|
61
66
|
options: {
|
|
62
|
-
changeset: { type: "string" },
|
|
63
67
|
"client-only": { type: "boolean" },
|
|
64
68
|
filter: { type: "string" },
|
|
65
69
|
run: { type: "string" },
|
|
66
70
|
level: { type: "string" },
|
|
67
71
|
limit: { type: "string" },
|
|
68
72
|
live: { type: "boolean" },
|
|
73
|
+
"no-browser": { type: "boolean" },
|
|
69
74
|
"no-commit": { type: "boolean" },
|
|
70
75
|
"no-git": { type: "boolean" },
|
|
71
76
|
"no-install": { type: "boolean" },
|
|
@@ -80,36 +85,41 @@ async function main() {
|
|
|
80
85
|
},
|
|
81
86
|
strict: true
|
|
82
87
|
});
|
|
88
|
+
if (positionals.length === 1 && positionals[0] === "login" && Object.keys(values).every((key) => key === "no-browser")) {
|
|
89
|
+
await (await import("./login-iT9MRuaw.js")).runLogin({ noBrowser: values["no-browser"] });
|
|
90
|
+
return;
|
|
91
|
+
}
|
|
92
|
+
if (values["no-browser"] !== void 0) throw new Error(usage);
|
|
83
93
|
const noGitFlags = values["no-commit"] === void 0 && values["no-git"] === void 0;
|
|
84
94
|
const noVariableFlags = values.secret === void 0 && values.yes === void 0;
|
|
85
95
|
const noLogFlags = values.run === void 0 && values.filter === void 0 && values.level === void 0 && values.limit === void 0 && values.live === void 0 && values.search === void 0 && values.since === void 0;
|
|
86
96
|
const noModeFlags = values["client-only"] === void 0 && values["server-only"] === void 0;
|
|
87
|
-
if (positionals.length === 1 && positionals[0] === "bootstrap" &&
|
|
88
|
-
await (await import("./init-
|
|
97
|
+
if (positionals.length === 1 && positionals[0] === "bootstrap" && noModeFlags && noGitFlags && noVariableFlags && noLogFlags) {
|
|
98
|
+
await (await import("./init-Wu6XmyVc.js")).runBootstrap({ install: values["no-install"] !== true });
|
|
89
99
|
return;
|
|
90
100
|
}
|
|
91
101
|
if (positionals.length === 1 && positionals[0] === "generate" && values["no-install"] === void 0 && noModeFlags && noGitFlags && noVariableFlags && noLogFlags) {
|
|
92
|
-
await (await import("./generate-
|
|
102
|
+
await (await import("./generate-DSk8ihsC.js")).runGenerate({});
|
|
93
103
|
return;
|
|
94
104
|
}
|
|
95
105
|
if (positionals.length === 1 && positionals[0] === "build" && values["no-install"] === void 0 && noModeFlags && noGitFlags && noVariableFlags && noLogFlags) {
|
|
96
|
-
await (await import("./build-
|
|
106
|
+
await (await import("./build-DhNDp7ji.js")).runBuild();
|
|
97
107
|
return;
|
|
98
108
|
}
|
|
99
109
|
if (positionals.length === 1 && positionals[0] === "deploy" && values["no-install"] === void 0 && noModeFlags && noGitFlags && noVariableFlags && noLogFlags) {
|
|
100
|
-
await (await import("./deploy-
|
|
110
|
+
await (await import("./deploy-CqrtNJ1x.js")).runDeploy({});
|
|
101
111
|
return;
|
|
102
112
|
}
|
|
103
|
-
if (positionals.length === 2 && positionals[0] === "init" &&
|
|
104
|
-
await (await import("./init-
|
|
113
|
+
if (positionals.length === 2 && positionals[0] === "init" && noModeFlags && noVariableFlags && noLogFlags) {
|
|
114
|
+
await (await import("./init-Wu6XmyVc.js")).runInit(positionals[1], {
|
|
105
115
|
commit: values["no-commit"] !== true,
|
|
106
116
|
git: values["no-git"] !== true,
|
|
107
117
|
install: values["no-install"] !== true
|
|
108
118
|
});
|
|
109
119
|
return;
|
|
110
120
|
}
|
|
111
|
-
if (positionals.length === 2 && positionals[0] === "new" &&
|
|
112
|
-
await (await import("./init-
|
|
121
|
+
if (positionals.length === 2 && positionals[0] === "new" && noGitFlags && noVariableFlags && noLogFlags) {
|
|
122
|
+
await (await import("./init-Wu6XmyVc.js")).runNew({
|
|
113
123
|
code: positionals[1],
|
|
114
124
|
clientOnly: values["client-only"],
|
|
115
125
|
install: values["no-install"] !== true,
|
|
@@ -117,8 +127,8 @@ async function main() {
|
|
|
117
127
|
});
|
|
118
128
|
return;
|
|
119
129
|
}
|
|
120
|
-
if ((positionals.length === 1 || positionals.length === 2) && positionals[0] === "logs" && values
|
|
121
|
-
await (await import("./logs-
|
|
130
|
+
if ((positionals.length === 1 || positionals.length === 2) && positionals[0] === "logs" && values["no-install"] === void 0 && noModeFlags && noGitFlags && noVariableFlags) {
|
|
131
|
+
await (await import("./logs-B-qZGXSK.js")).runLogs({
|
|
122
132
|
code: positionals[1],
|
|
123
133
|
filter: values.filter,
|
|
124
134
|
run: values.run,
|
|
@@ -130,8 +140,8 @@ async function main() {
|
|
|
130
140
|
});
|
|
131
141
|
return;
|
|
132
142
|
}
|
|
133
|
-
if ((positionals.length === 3 || positionals.length === 4) && positionals[0] === "variables" &&
|
|
134
|
-
await (await import("./variables-
|
|
143
|
+
if ((positionals.length === 3 || positionals.length === 4) && positionals[0] === "variables" && positionals[1] === "set" && values["no-install"] === void 0 && noModeFlags && noGitFlags && noLogFlags) {
|
|
144
|
+
await (await import("./variables-DcwMeIau.js")).runVariablesSet({
|
|
135
145
|
key: positionals[2],
|
|
136
146
|
secret: values.secret,
|
|
137
147
|
value: positionals[3],
|
|
@@ -139,12 +149,12 @@ async function main() {
|
|
|
139
149
|
});
|
|
140
150
|
return;
|
|
141
151
|
}
|
|
142
|
-
if (positionals.length === 2 && positionals[0] === "variables" &&
|
|
143
|
-
await (await import("./variables-
|
|
152
|
+
if (positionals.length === 2 && positionals[0] === "variables" && positionals[1] === "list" && values["no-install"] === void 0 && noModeFlags && noGitFlags && noVariableFlags && noLogFlags) {
|
|
153
|
+
await (await import("./variables-DcwMeIau.js")).runVariablesList({});
|
|
144
154
|
return;
|
|
145
155
|
}
|
|
146
|
-
if (positionals.length === 3 && positionals[0] === "variables" &&
|
|
147
|
-
await (await import("./variables-
|
|
156
|
+
if (positionals.length === 3 && positionals[0] === "variables" && positionals[1] === "delete" && values["no-install"] === void 0 && noModeFlags && noGitFlags && values.secret === void 0 && noLogFlags) {
|
|
157
|
+
await (await import("./variables-DcwMeIau.js")).runVariablesDelete({
|
|
148
158
|
key: positionals[2],
|
|
149
159
|
yes: values.yes
|
|
150
160
|
});
|
|
@@ -1,7 +1,8 @@
|
|
|
1
|
-
import { r as prepareAppletProject } from "./project-
|
|
1
|
+
import { i as prepareAppletProjects, r as prepareAppletProject } from "./project-C_rtpjp8.js";
|
|
2
2
|
import { rm } from "node:fs/promises";
|
|
3
3
|
import { resolve } from "node:path";
|
|
4
4
|
import { spawn } from "node:child_process";
|
|
5
|
+
import { createInterface } from "node:readline";
|
|
5
6
|
//#region src/build.ts
|
|
6
7
|
function isMissingFile(error) {
|
|
7
8
|
return error instanceof Error && "code" in error && error.code === "ENOENT";
|
|
@@ -29,13 +30,19 @@ async function runPnpm(args, cwd) {
|
|
|
29
30
|
});
|
|
30
31
|
});
|
|
31
32
|
}
|
|
32
|
-
async function buildApplet(appletRoot,
|
|
33
|
-
|
|
33
|
+
async function buildApplet(appletRoot, outDir = ".hitch/dist") {
|
|
34
|
+
await runPnpm(["install"], await prepareAppletProject(appletRoot));
|
|
35
|
+
await buildPreparedApplet(appletRoot, outDir);
|
|
36
|
+
}
|
|
37
|
+
async function prepareWorkspaceBuild(workspaceRoot, appletRoots) {
|
|
38
|
+
await prepareAppletProjects(workspaceRoot, appletRoots);
|
|
39
|
+
await runPnpm(["install"], workspaceRoot);
|
|
40
|
+
}
|
|
41
|
+
async function buildPreparedApplet(appletRoot, outDir = ".hitch/dist", logPrefix = "") {
|
|
34
42
|
await rm(resolve(appletRoot, ".hitch"), {
|
|
35
43
|
force: true,
|
|
36
44
|
recursive: true
|
|
37
45
|
});
|
|
38
|
-
await runPnpm(["install"], workspaceRoot);
|
|
39
46
|
await new Promise((resolveBuild, rejectBuild) => {
|
|
40
47
|
let finished = false;
|
|
41
48
|
const child = spawn("pnpm", [
|
|
@@ -46,13 +53,21 @@ async function buildApplet(appletRoot, changesetId, outDir = ".hitch/dist") {
|
|
|
46
53
|
outDir
|
|
47
54
|
], {
|
|
48
55
|
cwd: appletRoot,
|
|
49
|
-
stdio: "inherit"
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
56
|
+
stdio: logPrefix === "" ? "inherit" : [
|
|
57
|
+
"ignore",
|
|
58
|
+
"pipe",
|
|
59
|
+
"pipe"
|
|
60
|
+
],
|
|
61
|
+
shell: process.platform === "win32"
|
|
55
62
|
});
|
|
63
|
+
if (child.stdout) createInterface({
|
|
64
|
+
input: child.stdout,
|
|
65
|
+
crlfDelay: Infinity
|
|
66
|
+
}).on("line", (line) => console.log(`${logPrefix}${line}`));
|
|
67
|
+
if (child.stderr) createInterface({
|
|
68
|
+
input: child.stderr,
|
|
69
|
+
crlfDelay: Infinity
|
|
70
|
+
}).on("line", (line) => console.error(`${logPrefix}${line}`));
|
|
56
71
|
child.once("error", (error) => {
|
|
57
72
|
finished = true;
|
|
58
73
|
rejectBuild(isMissingFile(error) ? /* @__PURE__ */ new Error("pnpm was not found. Install pnpm, then run applet build again.") : error);
|
|
@@ -68,8 +83,8 @@ async function buildApplet(appletRoot, changesetId, outDir = ".hitch/dist") {
|
|
|
68
83
|
});
|
|
69
84
|
});
|
|
70
85
|
}
|
|
71
|
-
async function runBuild(
|
|
72
|
-
await buildApplet(process.cwd()
|
|
86
|
+
async function runBuild() {
|
|
87
|
+
await buildApplet(process.cwd());
|
|
73
88
|
}
|
|
74
89
|
//#endregion
|
|
75
|
-
export { runBuild as n, buildApplet as t };
|
|
90
|
+
export { runBuild as i, buildPreparedApplet as n, prepareWorkspaceBuild as r, buildApplet as t };
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { l as resolveInstanceUrl } from "./workspace-B6lenAS5.js";
|
|
2
2
|
//#region src/ci.ts
|
|
3
3
|
function githubActionsContext(env = process.env) {
|
|
4
4
|
if (env.GITHUB_ACTIONS !== "true" || env.HITCH_API_KEY) return void 0;
|
|
@@ -34,9 +34,10 @@ async function fetchWithGitHubActions(context, options, request) {
|
|
|
34
34
|
const instanceUrl = await resolveInstanceUrl(void 0, options.store);
|
|
35
35
|
return request(instanceUrl, await githubActionsToken(context, instanceUrl, options.fetch ?? globalThis.fetch));
|
|
36
36
|
}
|
|
37
|
-
async function loadGitHubActionsBuildInputs(context, options) {
|
|
37
|
+
async function loadGitHubActionsBuildInputs(context, options, requiresChangeset) {
|
|
38
38
|
const fetcher = options.fetch ?? globalThis.fetch;
|
|
39
|
-
const
|
|
39
|
+
const query = requiresChangeset === void 0 ? "" : `?changeset_id=${encodeURIComponent(requiresChangeset)}`;
|
|
40
|
+
const response = await fetchWithGitHubActions(context, options, (instanceUrl, accessToken) => fetcher(`${instanceUrl}/api/ci/v1/build-inputs${query}`, {
|
|
40
41
|
method: "POST",
|
|
41
42
|
headers: { Authorization: `Bearer ${accessToken}` }
|
|
42
43
|
}));
|
|
@@ -48,5 +49,20 @@ async function loadGitHubActionsBuildInputs(context, options) {
|
|
|
48
49
|
theme: body.theme
|
|
49
50
|
};
|
|
50
51
|
}
|
|
52
|
+
async function loadGitHubActionsSources(context, options) {
|
|
53
|
+
const fetcher = options.fetch ?? globalThis.fetch;
|
|
54
|
+
const response = await fetchWithGitHubActions(context, options, (instanceUrl, accessToken) => fetcher(`${instanceUrl}/api/ci/v1/applets`, { headers: { Authorization: `Bearer ${accessToken}` } }));
|
|
55
|
+
if (!response.ok) throw await hitchResponseError(response, "Failed to load the CI applets");
|
|
56
|
+
const body = await response.json();
|
|
57
|
+
if (body === null || typeof body !== "object" || !("data" in body) || !Array.isArray(body.data)) throw new Error("The CI applets response must contain a data array.");
|
|
58
|
+
return body.data.map((source) => {
|
|
59
|
+
if (source === null || typeof source !== "object" || !("code" in source) || typeof source.code !== "string" || !("source_directory" in source) || typeof source.source_directory !== "string" || !("git_sha" in source) || source.git_sha !== null && typeof source.git_sha !== "string") throw new Error("Each CI applet must contain code, source_directory, and git_sha fields.");
|
|
60
|
+
return {
|
|
61
|
+
code: source.code,
|
|
62
|
+
sourceDirectory: source.source_directory,
|
|
63
|
+
gitSha: source.git_sha
|
|
64
|
+
};
|
|
65
|
+
});
|
|
66
|
+
}
|
|
51
67
|
//#endregion
|
|
52
|
-
export { loadGitHubActionsBuildInputs as i, githubActionsContext as n, hitchResponseError as r, fetchWithGitHubActions as t };
|
|
68
|
+
export { loadGitHubActionsSources as a, loadGitHubActionsBuildInputs as i, githubActionsContext as n, hitchResponseError as r, fetchWithGitHubActions as t };
|
package/dist/client.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { f as RegisteredContract, m as RegisteredRouter, p as RegisteredManifest } from "./manifest-
|
|
2
|
-
import { t as NarrowContract } from "./contract-
|
|
1
|
+
import { f as RegisteredContract, m as RegisteredRouter, p as RegisteredManifest } from "./manifest-C489nYUy.js";
|
|
2
|
+
import { t as NarrowContract } from "./contract-DB9QQhD9.js";
|
|
3
3
|
import { t as WithBatchRecorder } from "./batch-Qa4B4-Yp.js";
|
|
4
4
|
import { o as WithFilesUpload } from "./upload-YbRKEqR6.js";
|
|
5
5
|
import { RouterClient } from "@orpc/server";
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { n as AppletManifest } from "./manifest-
|
|
1
|
+
import { n as AppletManifest } from "./manifest-C489nYUy.js";
|
|
2
2
|
import { AnyContractRouter } from "@orpc/contract";
|
|
3
3
|
//#region src/hitch/contract.d.ts
|
|
4
4
|
type ManifestObjectFor<Manifest, Code> = Manifest extends {
|
|
@@ -1,7 +1,6 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { n as githubActionsContext, r as hitchResponseError, t as fetchWithGitHubActions } from "./ci-
|
|
3
|
-
import { r as
|
|
4
|
-
import { t as buildApplet } from "./build-DIsKQQT0.js";
|
|
1
|
+
import { i as readWorkspaceConfig, n as fetchWithOrgAuth } from "./workspace-B6lenAS5.js";
|
|
2
|
+
import { a as loadGitHubActionsSources, n as githubActionsContext, r as hitchResponseError, t as fetchWithGitHubActions } from "./ci-gPrwo6C0.js";
|
|
3
|
+
import { n as buildPreparedApplet, r as prepareWorkspaceBuild, t as buildApplet } from "./build-DauirTcY.js";
|
|
5
4
|
import { createRequire } from "node:module";
|
|
6
5
|
import { existsSync } from "node:fs";
|
|
7
6
|
import { readFile, readdir } from "node:fs/promises";
|
|
@@ -2314,6 +2313,12 @@ var import_tar_stream = /* @__PURE__ */ __toESM((/* @__PURE__ */ __commonJSMin((
|
|
|
2314
2313
|
exports.pack = require_pack();
|
|
2315
2314
|
})))(), 1);
|
|
2316
2315
|
const execFileAsync = promisify(execFile);
|
|
2316
|
+
var WorkspaceDeployError = class extends Error {
|
|
2317
|
+
constructor(failedApplets) {
|
|
2318
|
+
super(`Failed to deploy: ${failedApplets.join(", ")}. See the applet logs above.`);
|
|
2319
|
+
this.name = "WorkspaceDeployError";
|
|
2320
|
+
}
|
|
2321
|
+
};
|
|
2317
2322
|
function isErrno(error, code) {
|
|
2318
2323
|
return error instanceof Error && "code" in error && error.code === code;
|
|
2319
2324
|
}
|
|
@@ -2401,7 +2406,6 @@ async function deployWithOrgAuth(appletRoot, distDir, manifest, options) {
|
|
|
2401
2406
|
const body = releaseForm(manifest, bundle);
|
|
2402
2407
|
body.set("gitDirty", String(git.gitDirty));
|
|
2403
2408
|
if (git.gitSha !== void 0) body.set("gitSha", git.gitSha);
|
|
2404
|
-
if (options.changesetId !== void 0) body.set("changeset_id", options.changesetId);
|
|
2405
2409
|
return fetcher(`${instanceUrl}/api/v1/applets/${manifest.code}/releases`, {
|
|
2406
2410
|
method: "POST",
|
|
2407
2411
|
headers: { Authorization: `Bearer ${accessToken}` },
|
|
@@ -2422,21 +2426,21 @@ async function deployWithGitHubActions(context, appletRoot, distDir, manifest, o
|
|
|
2422
2426
|
});
|
|
2423
2427
|
});
|
|
2424
2428
|
}
|
|
2425
|
-
async function deployApplet(appletRoot, options) {
|
|
2429
|
+
async function deployApplet(appletRoot, options, logPrefix = "") {
|
|
2426
2430
|
const github = githubActionsContext(options.store?.env ?? process.env);
|
|
2427
|
-
if (
|
|
2428
|
-
if (options.dist === void 0) await buildApplet(appletRoot, options.changesetId);
|
|
2431
|
+
if (options.dist === void 0) await buildApplet(appletRoot);
|
|
2429
2432
|
const distDir = resolve(appletRoot, options.dist ?? ".hitch/dist");
|
|
2430
2433
|
const manifest = await readManifest(distDir);
|
|
2431
2434
|
const response = github === void 0 ? await deployWithOrgAuth(appletRoot, distDir, manifest, options) : await deployWithGitHubActions(github, appletRoot, distDir, manifest, options);
|
|
2432
2435
|
if (!response.ok) throw await hitchResponseError(response, "Deploy failed");
|
|
2433
2436
|
const result = await response.json();
|
|
2434
|
-
console.log(
|
|
2437
|
+
console.log(`${logPrefix}Deployed release ${result.data.id} (${result.promoted ? "promoted" : "not promoted"}).`);
|
|
2438
|
+
if (result.changeset_id !== void 0) console.log(`${logPrefix}The release goes live when changeset ${result.changeset_id} applies.`);
|
|
2435
2439
|
if (result.warnings?.length) {
|
|
2436
|
-
for (const warning of result.warnings) console.warn(
|
|
2437
|
-
console.warn(
|
|
2440
|
+
for (const warning of result.warnings) console.warn(`${logPrefix}Warning: ${warning.message}`);
|
|
2441
|
+
console.warn(`${logPrefix}Changeset ${result.changeset_id} cannot apply until the applet and the schema agree.`);
|
|
2438
2442
|
}
|
|
2439
|
-
if (result.unset_variables?.length) console.warn(
|
|
2443
|
+
if (result.unset_variables?.length) console.warn(`${logPrefix}Warning: declared variables not set: ${result.unset_variables.join(", ")}. Set them with applet variables set.`);
|
|
2440
2444
|
return result;
|
|
2441
2445
|
}
|
|
2442
2446
|
async function workspaceAppletRoots(workspaceRoot) {
|
|
@@ -2448,17 +2452,128 @@ async function workspaceAppletRoots(workspaceRoot) {
|
|
|
2448
2452
|
if (roots.length === 0) throw new Error(`No applets were found under ${appletsDir}.`);
|
|
2449
2453
|
return roots;
|
|
2450
2454
|
}
|
|
2455
|
+
async function gitChanged(topLevel, base, pathspecs, env) {
|
|
2456
|
+
try {
|
|
2457
|
+
await execFileAsync("git", [
|
|
2458
|
+
"diff",
|
|
2459
|
+
"--quiet",
|
|
2460
|
+
base,
|
|
2461
|
+
"HEAD",
|
|
2462
|
+
"--",
|
|
2463
|
+
...pathspecs
|
|
2464
|
+
], {
|
|
2465
|
+
cwd: topLevel,
|
|
2466
|
+
env
|
|
2467
|
+
});
|
|
2468
|
+
return false;
|
|
2469
|
+
} catch (error) {
|
|
2470
|
+
if (error instanceof Error && "code" in error && error.code === 1) return true;
|
|
2471
|
+
throw error;
|
|
2472
|
+
}
|
|
2473
|
+
}
|
|
2474
|
+
async function hasCommit(topLevel, sha, env) {
|
|
2475
|
+
const git = (args) => execFileAsync("git", args, {
|
|
2476
|
+
cwd: topLevel,
|
|
2477
|
+
env
|
|
2478
|
+
});
|
|
2479
|
+
return git([
|
|
2480
|
+
"cat-file",
|
|
2481
|
+
"-e",
|
|
2482
|
+
`${sha}^{commit}`
|
|
2483
|
+
]).catch(() => git([
|
|
2484
|
+
"fetch",
|
|
2485
|
+
"--depth=1",
|
|
2486
|
+
"origin",
|
|
2487
|
+
sha
|
|
2488
|
+
])).then(() => true, () => false);
|
|
2489
|
+
}
|
|
2490
|
+
async function ciDeployDecisions(github, workspaceRoot, appletRoots, options) {
|
|
2491
|
+
const env = gitEnvironment();
|
|
2492
|
+
const [sources, { stdout: topLevelOutput }, directories] = await Promise.all([
|
|
2493
|
+
loadGitHubActionsSources(github, options),
|
|
2494
|
+
execFileAsync("git", ["rev-parse", "--show-toplevel"], {
|
|
2495
|
+
cwd: workspaceRoot,
|
|
2496
|
+
env
|
|
2497
|
+
}),
|
|
2498
|
+
Promise.all(appletRoots.map((appletRoot) => repositoryDirectory(appletRoot)))
|
|
2499
|
+
]);
|
|
2500
|
+
const topLevel = topLevelOutput.trim();
|
|
2501
|
+
const appletsDirectory = relative(topLevel, resolve(workspaceRoot, "applets")).split(sep).join("/");
|
|
2502
|
+
const baseByDirectory = new Map(sources.map((source) => [source.sourceDirectory, source.gitSha]));
|
|
2503
|
+
const bases = new Set(directories.flatMap((directory) => baseByDirectory.get(directory) ?? []));
|
|
2504
|
+
const sharedChanges = /* @__PURE__ */ new Map();
|
|
2505
|
+
for (const base of bases) sharedChanges.set(base, await hasCommit(topLevel, base, env) ? await gitChanged(topLevel, base, [`:(exclude)${appletsDirectory}`], env) : void 0);
|
|
2506
|
+
const decisions = await Promise.all(appletRoots.map(async (appletRoot, index) => {
|
|
2507
|
+
const directory = directories[index];
|
|
2508
|
+
const base = baseByDirectory.get(directory) ?? null;
|
|
2509
|
+
if (base === null) return [appletRoot, {
|
|
2510
|
+
deploy: true,
|
|
2511
|
+
reason: "no CI release to compare"
|
|
2512
|
+
}];
|
|
2513
|
+
const short = base.slice(0, 7);
|
|
2514
|
+
const sharedChanged = sharedChanges.get(base);
|
|
2515
|
+
if (sharedChanged === void 0) return [appletRoot, {
|
|
2516
|
+
deploy: true,
|
|
2517
|
+
reason: `commit ${short} is not in the repository`
|
|
2518
|
+
}];
|
|
2519
|
+
if (await gitChanged(topLevel, base, [directory], env)) return [appletRoot, {
|
|
2520
|
+
deploy: true,
|
|
2521
|
+
reason: `${directory} changed since ${short}`
|
|
2522
|
+
}];
|
|
2523
|
+
if (sharedChanged) return [appletRoot, {
|
|
2524
|
+
deploy: true,
|
|
2525
|
+
reason: `files outside ${appletsDirectory} changed since ${short}`
|
|
2526
|
+
}];
|
|
2527
|
+
return [appletRoot, {
|
|
2528
|
+
deploy: false,
|
|
2529
|
+
reason: `no changes since ${short}`
|
|
2530
|
+
}];
|
|
2531
|
+
}));
|
|
2532
|
+
return new Map(decisions);
|
|
2533
|
+
}
|
|
2451
2534
|
async function runDeploy(options) {
|
|
2452
2535
|
const root = process.cwd();
|
|
2536
|
+
const github = githubActionsContext(options.store?.env ?? process.env);
|
|
2453
2537
|
if (existsSync(resolve(root, "applet.manifest.ts"))) {
|
|
2454
2538
|
await deployApplet(root, options);
|
|
2455
2539
|
return;
|
|
2456
2540
|
}
|
|
2457
2541
|
if (readWorkspaceConfig(root) === void 0) throw new Error("Run applet deploy in an applet folder or in the workspace root.");
|
|
2458
|
-
|
|
2459
|
-
|
|
2460
|
-
|
|
2542
|
+
const appletRoots = await workspaceAppletRoots(root);
|
|
2543
|
+
const decisions = github === void 0 ? void 0 : await ciDeployDecisions(github, root, appletRoots, options);
|
|
2544
|
+
const selectedRoots = appletRoots.filter((appletRoot) => {
|
|
2545
|
+
const name = relative(root, appletRoot);
|
|
2546
|
+
const decision = decisions?.get(appletRoot);
|
|
2547
|
+
if (decision === void 0) console.log(`Deploying ${name}...`);
|
|
2548
|
+
else if (decision.deploy) console.log(`Deploying ${name}: ${decision.reason}.`);
|
|
2549
|
+
else {
|
|
2550
|
+
console.log(`Skipping ${name}: ${decision.reason}.`);
|
|
2551
|
+
return false;
|
|
2552
|
+
}
|
|
2553
|
+
return true;
|
|
2554
|
+
});
|
|
2555
|
+
if (selectedRoots.length === 0) return;
|
|
2556
|
+
if (options.dist === void 0) await prepareWorkspaceBuild(root, appletRoots);
|
|
2557
|
+
const interactive = github === void 0 && (options.stdinIsTTY ?? process.stdin.isTTY === true);
|
|
2558
|
+
const deploy = async (appletRoot) => {
|
|
2559
|
+
const logPrefix = `[${relative(root, appletRoot)}] `;
|
|
2560
|
+
if (options.dist === void 0) await buildPreparedApplet(appletRoot, ".hitch/dist", interactive ? "" : logPrefix);
|
|
2561
|
+
await deployApplet(appletRoot, {
|
|
2562
|
+
...options,
|
|
2563
|
+
dist: options.dist ?? ".hitch/dist"
|
|
2564
|
+
}, logPrefix);
|
|
2565
|
+
};
|
|
2566
|
+
if (interactive) {
|
|
2567
|
+
for (const appletRoot of selectedRoots) await deploy(appletRoot);
|
|
2568
|
+
return;
|
|
2461
2569
|
}
|
|
2570
|
+
const failedApplets = (await Promise.allSettled(selectedRoots.map(deploy))).flatMap((result, index) => {
|
|
2571
|
+
if (result.status === "fulfilled") return [];
|
|
2572
|
+
const name = relative(root, selectedRoots[index]);
|
|
2573
|
+
console.error(`[${name}] ${result.reason instanceof Error ? result.reason.message : String(result.reason)}`);
|
|
2574
|
+
return [name];
|
|
2575
|
+
});
|
|
2576
|
+
if (failedApplets.length > 0) throw new WorkspaceDeployError(failedApplets);
|
|
2462
2577
|
}
|
|
2463
2578
|
//#endregion
|
|
2464
2579
|
export { runDeploy };
|
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { i as loadGitHubActionsBuildInputs, n as githubActionsContext } from "./ci-
|
|
3
|
-
import { t as loadAppletConfig } from "./load-config-
|
|
4
|
-
import { r as prepareAppletProject } from "./project-
|
|
1
|
+
import { l as resolveInstanceUrl, n as fetchWithOrgAuth, s as organizationInstanceUrl } from "./workspace-B6lenAS5.js";
|
|
2
|
+
import { i as loadGitHubActionsBuildInputs, n as githubActionsContext } from "./ci-gPrwo6C0.js";
|
|
3
|
+
import { t as loadAppletConfig } from "./load-config-BknBkdRs.js";
|
|
4
|
+
import { r as prepareAppletProject } from "./project-C_rtpjp8.js";
|
|
5
5
|
import { createRequire } from "node:module";
|
|
6
6
|
import { existsSync } from "node:fs";
|
|
7
7
|
import { access, mkdir, mkdtemp, readFile, readdir, rename, rm, writeFile } from "node:fs/promises";
|
|
@@ -352,11 +352,11 @@ async function responseJson(response) {
|
|
|
352
352
|
throw new Error("Failed to parse the organization's OpenAPI spec.", { cause: error });
|
|
353
353
|
}
|
|
354
354
|
}
|
|
355
|
-
async function loadAuthenticatedSpec(
|
|
355
|
+
async function loadAuthenticatedSpec(manifest, options) {
|
|
356
356
|
const github = githubActionsContext(options.store?.env ?? process.env);
|
|
357
|
-
if (github !== void 0) return (await loadGitHubActionsBuildInputs(github, options)).openapi;
|
|
357
|
+
if (github !== void 0) return (await loadGitHubActionsBuildInputs(github, options, manifest.requiresChangeset)).openapi;
|
|
358
358
|
const fetcher = options.fetch ?? globalThis.fetch;
|
|
359
|
-
const response = await fetchWithOrgAuth(
|
|
359
|
+
const response = await fetchWithOrgAuth(manifest.org, options, (instanceUrl, accessToken) => fetcher(`${instanceUrl}/api/v1/openapi.json${manifest.requiresChangeset === void 0 ? "" : `?changeset_id=${encodeURIComponent(manifest.requiresChangeset)}`}`, { headers: { Authorization: `Bearer ${accessToken}` } }));
|
|
360
360
|
if (!response.ok) throw new Error(`Failed to load the organization's OpenAPI spec (${response.status}).`);
|
|
361
361
|
return responseJson(response);
|
|
362
362
|
}
|
|
@@ -367,18 +367,18 @@ async function loadThemeStylesheet(orgCode, options) {
|
|
|
367
367
|
if (!response.ok) throw new Error(`Failed to load the organization's theme (${response.status}).`);
|
|
368
368
|
return response.text();
|
|
369
369
|
}
|
|
370
|
-
async function loadBuildInputs(
|
|
370
|
+
async function loadBuildInputs(manifest, options) {
|
|
371
371
|
const github = githubActionsContext(options.store?.env ?? process.env);
|
|
372
372
|
if (github !== void 0) {
|
|
373
|
-
const inputs = await loadGitHubActionsBuildInputs(github, options);
|
|
373
|
+
const inputs = await loadGitHubActionsBuildInputs(github, options, manifest.requiresChangeset);
|
|
374
374
|
return {
|
|
375
375
|
spec: inputs.openapi,
|
|
376
376
|
theme: inputs.theme
|
|
377
377
|
};
|
|
378
378
|
}
|
|
379
379
|
return {
|
|
380
|
-
spec: await loadAuthenticatedSpec(
|
|
381
|
-
theme: await loadThemeStylesheet(
|
|
380
|
+
spec: await loadAuthenticatedSpec(manifest, options),
|
|
381
|
+
theme: await loadThemeStylesheet(manifest.org, options)
|
|
382
382
|
};
|
|
383
383
|
}
|
|
384
384
|
async function generateContract(spec, outDir) {
|
|
@@ -442,14 +442,14 @@ export type * from "./zod.gen.ts";
|
|
|
442
442
|
`);
|
|
443
443
|
}
|
|
444
444
|
async function syncContract(outDir, manifest, options = {}) {
|
|
445
|
-
await writeContractFiles(outDir, manifest, await loadAuthenticatedSpec(manifest
|
|
445
|
+
await writeContractFiles(outDir, manifest, await loadAuthenticatedSpec(manifest, options));
|
|
446
446
|
}
|
|
447
447
|
async function runGenerate(options) {
|
|
448
448
|
await prepareAppletProject();
|
|
449
449
|
const root = process.cwd();
|
|
450
450
|
const outDir = resolve("./.hitch");
|
|
451
451
|
const manifest = await loadAppletConfig(process.cwd());
|
|
452
|
-
const { spec, theme: themeStylesheet } = await loadBuildInputs(manifest
|
|
452
|
+
const { spec, theme: themeStylesheet } = await loadBuildInputs(manifest, options);
|
|
453
453
|
const stagedDir = await mkdtemp(resolve("./.hitch.tmp-"));
|
|
454
454
|
const backupDir = `${stagedDir}.backup`;
|
|
455
455
|
let staged = true;
|
package/dist/index.d.ts
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
import { _ as RegisteredWorkflows, a as AppletSourceDefinition, c as appletManifestSchema, d as RegisteredCatalog, f as RegisteredContract, g as RegisteredVariables, h as RegisteredVariableKeys, i as AppletPackages, l as appletSourceDefinitionSchema, m as RegisteredRouter, n as AppletManifest, o as RegisteredAppletSourceDefinition, p as RegisteredManifest, r as AppletManifestObject, s as appletDefinitionSchema, t as AppletDefinition, u as HitchRegister, v as registerHitchContract } from "./manifest-
|
|
2
|
-
import { n as pruneContract, t as NarrowContract } from "./contract-
|
|
1
|
+
import { _ as RegisteredWorkflows, a as AppletSourceDefinition, c as appletManifestSchema, d as RegisteredCatalog, f as RegisteredContract, g as RegisteredVariables, h as RegisteredVariableKeys, i as AppletPackages, l as appletSourceDefinitionSchema, m as RegisteredRouter, n as AppletManifest, o as RegisteredAppletSourceDefinition, p as RegisteredManifest, r as AppletManifestObject, s as appletDefinitionSchema, t as AppletDefinition, u as HitchRegister, v as registerHitchContract } from "./manifest-C489nYUy.js";
|
|
2
|
+
import { n as pruneContract, t as NarrowContract } from "./contract-DB9QQhD9.js";
|
|
3
3
|
import { a as UploadedHitchFile, c as createFileOutputSchema, d as getFileOutputSchema, i as UploadProgress, l as fileSchema, n as FilesUpload, r as UploadFileOptions, s as uploadFile, t as FilesClient, u as filesContract } from "./upload-YbRKEqR6.js";
|
|
4
4
|
import { ContractProcedure, Meta } from "@orpc/contract";
|
|
5
5
|
import { z } from "zod";
|
|
6
|
-
//#region src/workspace.d.
|
|
6
|
+
//#region ../shared/auth/src/workspace.d.mts
|
|
7
7
|
interface HitchConfig {
|
|
8
8
|
sdk: string;
|
|
9
9
|
org: string;
|
package/dist/index.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { i as registerHitchContract, t as uploadFile } from "./upload-DRbVhuDm.js";
|
|
2
|
-
import { n as appletManifestSchema, r as appletSourceDefinitionSchema, t as appletDefinitionSchema } from "./manifest-
|
|
2
|
+
import { n as appletManifestSchema, r as appletSourceDefinitionSchema, t as appletDefinitionSchema } from "./manifest-Bd04cWhu.js";
|
|
3
3
|
import { oc } from "@orpc/contract";
|
|
4
4
|
import { z } from "zod";
|
|
5
5
|
//#region src/hitch/contract.ts
|
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
import { a as ORG_CODE_PATTERN, i as APPLET_CODE_PATTERN } from "./manifest-
|
|
2
|
-
import { i as
|
|
3
|
-
import { n as runGenerate } from "./generate-
|
|
4
|
-
import { n as loadAppletSourceDefinition
|
|
5
|
-
import { a as
|
|
1
|
+
import { a as ORG_CODE_PATTERN, i as APPLET_CODE_PATTERN } from "./manifest-Bd04cWhu.js";
|
|
2
|
+
import { c as resolveAuthForOrg, i as readWorkspaceConfig, l as resolveInstanceUrl } from "./workspace-B6lenAS5.js";
|
|
3
|
+
import { n as runGenerate } from "./generate-BIifT6PK.js";
|
|
4
|
+
import { n as loadAppletSourceDefinition } from "./load-config-BknBkdRs.js";
|
|
5
|
+
import { a as writeAppletSupport, n as loadCliManifest, o as writeWorkspaceSupport, t as assertWorkspaceCli } from "./project-C_rtpjp8.js";
|
|
6
6
|
import { access, cp, mkdir, readdir, writeFile } from "node:fs/promises";
|
|
7
7
|
import { relative, resolve } from "node:path";
|
|
8
8
|
import { spawn } from "node:child_process";
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import { r as appletSourceDefinitionSchema } from "./manifest-Bd04cWhu.js";
|
|
2
|
+
import { t as resolveWorkspaceOrg } from "./workspace-B6lenAS5.js";
|
|
3
|
+
import { existsSync } from "node:fs";
|
|
4
|
+
import { resolve } from "node:path";
|
|
5
|
+
import { loadConfigFromFile } from "vite";
|
|
6
|
+
//#region src/typegen/load-config.ts
|
|
7
|
+
async function loadAppletSourceDefinition(root) {
|
|
8
|
+
const path = resolve(root, "applet.manifest.ts");
|
|
9
|
+
if (!existsSync(path)) throw new Error(`No applet manifest found at ${path}.`);
|
|
10
|
+
const loaded = await loadConfigFromFile({
|
|
11
|
+
command: "build",
|
|
12
|
+
mode: "production"
|
|
13
|
+
}, path, root);
|
|
14
|
+
if (loaded === null) throw new Error(`No applet manifest found at ${path}.`);
|
|
15
|
+
const parsed = appletSourceDefinitionSchema.safeParse(loaded.config);
|
|
16
|
+
if (!parsed.success) throw new Error(`Invalid applet manifest at ${loaded.path}: ${parsed.error.message}`);
|
|
17
|
+
return parsed.data;
|
|
18
|
+
}
|
|
19
|
+
async function loadAppletConfig(root) {
|
|
20
|
+
const { dependencies: _dependencies, devDependencies: _devDependencies, ...definition } = await loadAppletSourceDefinition(root);
|
|
21
|
+
return {
|
|
22
|
+
org: resolveWorkspaceOrg(root),
|
|
23
|
+
...definition
|
|
24
|
+
};
|
|
25
|
+
}
|
|
26
|
+
//#endregion
|
|
27
|
+
export { loadAppletSourceDefinition as n, loadAppletConfig as t };
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { a as loginWithDevice, l as resolveInstanceUrl, o as AuthenticationError, r as findWorkspaceConfig } from "./workspace-B6lenAS5.js";
|
|
2
|
+
//#region src/login.ts
|
|
3
|
+
async function runLogin(options) {
|
|
4
|
+
if (process.env.HITCH_API_KEY !== void 0) throw new AuthenticationError("HITCH_API_KEY is set — unset it to manage stored logins.");
|
|
5
|
+
const { me, membership } = await loginWithDevice(await resolveInstanceUrl(), {
|
|
6
|
+
expectedOrg: findWorkspaceConfig(process.cwd())?.org,
|
|
7
|
+
noBrowser: options.noBrowser
|
|
8
|
+
});
|
|
9
|
+
console.log(`Signed in as ${me.person.email} to ${membership.name}.`);
|
|
10
|
+
}
|
|
11
|
+
//#endregion
|
|
12
|
+
export { runLogin };
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { i as APPLET_CODE_PATTERN } from "./manifest-
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
1
|
+
import { i as APPLET_CODE_PATTERN } from "./manifest-Bd04cWhu.js";
|
|
2
|
+
import { i as readWorkspaceConfig, n as fetchWithOrgAuth, t as resolveWorkspaceOrg } from "./workspace-B6lenAS5.js";
|
|
3
|
+
import { t as loadAppletConfig } from "./load-config-BknBkdRs.js";
|
|
4
4
|
import { z } from "zod";
|
|
5
5
|
//#region src/logs.ts
|
|
6
6
|
const LOG_LEVELS = [
|
|
@@ -63,6 +63,7 @@ const appletManifestShape = {
|
|
|
63
63
|
org: z.string().regex(ORG_CODE_PATTERN, "must start with a lowercase letter, end with a letter or number, and contain only lowercase letters, numbers, and non-consecutive hyphens"),
|
|
64
64
|
name: nameSchema,
|
|
65
65
|
code: codeSchema,
|
|
66
|
+
requiresChangeset: z.uuid().optional(),
|
|
66
67
|
schedules: appletManifestSchedulesSchema.optional(),
|
|
67
68
|
variables: appletManifestVariablesSchema.optional(),
|
|
68
69
|
objects: appletManifestObjectsSchema
|
|
@@ -94,6 +95,7 @@ const appletManifestSchema = z.strictObject(appletManifestShape).superRefine(che
|
|
|
94
95
|
const appletDefinitionSchema = z.strictObject({
|
|
95
96
|
name: appletManifestShape.name,
|
|
96
97
|
code: appletManifestShape.code,
|
|
98
|
+
requiresChangeset: appletManifestShape.requiresChangeset,
|
|
97
99
|
schedules: appletManifestShape.schedules,
|
|
98
100
|
variables: appletManifestShape.variables,
|
|
99
101
|
objects: appletManifestShape.objects
|
|
@@ -161,6 +163,7 @@ const checkSourcePackages = (manifest, context) => {
|
|
|
161
163
|
const appletSourceDefinitionSchema = z.strictObject({
|
|
162
164
|
name: appletManifestShape.name,
|
|
163
165
|
code: appletManifestShape.code,
|
|
166
|
+
requiresChangeset: appletManifestShape.requiresChangeset,
|
|
164
167
|
schedules: appletManifestShape.schedules,
|
|
165
168
|
variables: appletManifestShape.variables,
|
|
166
169
|
objects: appletManifestShape.objects,
|
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { i as readWorkspaceConfig } from "./workspace-B6lenAS5.js";
|
|
2
|
+
import { n as loadAppletSourceDefinition } from "./load-config-BknBkdRs.js";
|
|
2
3
|
import { z } from "zod";
|
|
3
4
|
import { existsSync } from "node:fs";
|
|
4
5
|
import { cp, mkdir, readFile, rm, symlink, writeFile } from "node:fs/promises";
|
|
@@ -340,17 +341,17 @@ export default defineConfig({
|
|
|
340
341
|
hasClient ? writeFile(resolve(root, "components.json"), await readFile(new URL("../scaffold/applet/components.json", import.meta.url), "utf8")) : void 0
|
|
341
342
|
]);
|
|
342
343
|
}
|
|
343
|
-
async function
|
|
344
|
-
const
|
|
345
|
-
const workspaceRoot = dirname(dirname(resolve(appletRoot)));
|
|
344
|
+
async function prepareAppletProjects(workspaceRoot, appletRoots) {
|
|
345
|
+
const definitions = await Promise.all(appletRoots.map((root) => loadAppletSourceDefinition(root)));
|
|
346
346
|
const workspace = readWorkspaceConfig(workspaceRoot);
|
|
347
|
-
if (workspace === void 0) throw new Error(`No Hitch workspace found
|
|
347
|
+
if (workspace === void 0) throw new Error(`No Hitch workspace found at ${workspaceRoot}.`);
|
|
348
348
|
const cli = await loadCliManifest({ allowDevelopment: true });
|
|
349
|
-
await Promise.all([cli === void 0 ? void 0 : writeWorkspaceSupport(workspaceRoot, workspace, cli), writeAppletSupport(
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
349
|
+
await Promise.all([cli === void 0 ? void 0 : writeWorkspaceSupport(workspaceRoot, workspace, cli), ...appletRoots.map((root, index) => writeAppletSupport(root, definitions[index]))]);
|
|
350
|
+
}
|
|
351
|
+
async function prepareAppletProject(appletRoot = process.cwd()) {
|
|
352
|
+
const workspaceRoot = dirname(dirname(resolve(appletRoot)));
|
|
353
|
+
await prepareAppletProjects(workspaceRoot, [appletRoot]);
|
|
354
|
+
return workspaceRoot;
|
|
354
355
|
}
|
|
355
356
|
//#endregion
|
|
356
|
-
export {
|
|
357
|
+
export { writeAppletSupport as a, prepareAppletProjects as i, loadCliManifest as n, writeWorkspaceSupport as o, prepareAppletProject as r, assertWorkspaceCli as t };
|
package/dist/server.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { a as createWorkflow, i as WorkflowStep, n as WorkflowDefinition, r as WorkflowDuration } from "./workflow-DurM6Fwx.js";
|
|
2
|
-
import { _ as RegisteredWorkflows, f as RegisteredContract, g as RegisteredVariables, p as RegisteredManifest } from "./manifest-
|
|
3
|
-
import { t as NarrowContract } from "./contract-
|
|
2
|
+
import { _ as RegisteredWorkflows, f as RegisteredContract, g as RegisteredVariables, p as RegisteredManifest } from "./manifest-C489nYUy.js";
|
|
3
|
+
import { t as NarrowContract } from "./contract-DB9QQhD9.js";
|
|
4
4
|
import { t as WithBatchRecorder } from "./batch-Qa4B4-Yp.js";
|
|
5
5
|
import { o as WithFilesUpload } from "./upload-YbRKEqR6.js";
|
|
6
6
|
import { ContractRouterClient } from "@orpc/contract";
|
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { t as loadAppletConfig } from "./load-config-
|
|
1
|
+
import { n as fetchWithOrgAuth } from "./workspace-B6lenAS5.js";
|
|
2
|
+
import { t as loadAppletConfig } from "./load-config-BknBkdRs.js";
|
|
3
3
|
import { z } from "zod";
|
|
4
|
-
import { Writable } from "node:stream";
|
|
5
4
|
import { createInterface } from "node:readline";
|
|
5
|
+
import { Writable } from "node:stream";
|
|
6
6
|
//#region src/variables.ts
|
|
7
7
|
const variableRowSchema = z.object({
|
|
8
8
|
key: z.string(),
|
package/dist/vite.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { o as RegisteredAppletSourceDefinition } from "./manifest-
|
|
1
|
+
import { o as RegisteredAppletSourceDefinition } from "./manifest-C489nYUy.js";
|
|
2
2
|
import { PluginOption } from "vite";
|
|
3
3
|
//#region ../shared/auth/src/store.d.mts
|
|
4
4
|
interface SessionCredentials {
|
package/dist/vite.js
CHANGED
|
@@ -1,7 +1,6 @@
|
|
|
1
|
-
import { i as APPLET_CODE_PATTERN, n as appletManifestSchema, r as appletSourceDefinitionSchema } from "./manifest-
|
|
2
|
-
import {
|
|
3
|
-
import { c as writeClientEntry, i as writeRegisterDeclaration, l as writeManifestGen, r as syncContract, s as writeAppletRoot, u as writeServerEntry } from "./generate-
|
|
4
|
-
import { i as resolveWorkspaceOrg } from "./load-config-BnxocLAQ.js";
|
|
1
|
+
import { i as APPLET_CODE_PATTERN, n as appletManifestSchema, r as appletSourceDefinitionSchema } from "./manifest-Bd04cWhu.js";
|
|
2
|
+
import { l as resolveInstanceUrl, s as organizationInstanceUrl, t as resolveWorkspaceOrg } from "./workspace-B6lenAS5.js";
|
|
3
|
+
import { c as writeClientEntry, i as writeRegisterDeclaration, l as writeManifestGen, r as syncContract, s as writeAppletRoot, u as writeServerEntry } from "./generate-BIifT6PK.js";
|
|
5
4
|
import { existsSync } from "node:fs";
|
|
6
5
|
import { appendFile, readFile, readdir, rm, writeFile } from "node:fs/promises";
|
|
7
6
|
import { basename, relative, resolve } from "node:path";
|
|
@@ -221,10 +220,7 @@ function applet(sourceDefinition, options = {}) {
|
|
|
221
220
|
}
|
|
222
221
|
if (environment.command === "build") themeStylesheetUrl = `${organizationInstanceUrl(await resolveInstanceUrl(void 0, options.store), manifest.org)}/theme.css`;
|
|
223
222
|
if (environment.command === "build" && manifest.objects.length > 0) {
|
|
224
|
-
contractSync ??= syncContract(resolve(root, ".hitch"), manifest,
|
|
225
|
-
...options,
|
|
226
|
-
changesetId: (options.store?.env ?? process.env).HITCH_CHANGESET_ID
|
|
227
|
-
});
|
|
223
|
+
contractSync ??= syncContract(resolve(root, ".hitch"), manifest, options);
|
|
228
224
|
await contractSync;
|
|
229
225
|
}
|
|
230
226
|
const hasHitchGen = existsSync(resolve(root, ".hitch/index.ts"));
|
|
@@ -1,5 +1,7 @@
|
|
|
1
|
+
import { createRequire } from "node:module";
|
|
2
|
+
import { existsSync } from "node:fs";
|
|
1
3
|
import { chmod, mkdir, readFile, writeFile } from "node:fs/promises";
|
|
2
|
-
import { join } from "node:path";
|
|
4
|
+
import { basename, dirname, join, resolve } from "node:path";
|
|
3
5
|
import { spawn } from "node:child_process";
|
|
4
6
|
import { homedir } from "node:os";
|
|
5
7
|
//#region ../shared/auth/src/store.mts
|
|
@@ -326,6 +328,30 @@ async function loginWithDevice(instanceUrl, options = {}) {
|
|
|
326
328
|
};
|
|
327
329
|
}
|
|
328
330
|
//#endregion
|
|
331
|
+
//#region ../shared/auth/src/workspace.mts
|
|
332
|
+
const ORG_CODE_PATTERN = /^[a-z][a-z0-9]*(?:-[a-z0-9]+)*$/;
|
|
333
|
+
const require = createRequire(import.meta.url);
|
|
334
|
+
function readWorkspaceConfig(dir) {
|
|
335
|
+
const path = resolve(dir, "hitch.config.ts");
|
|
336
|
+
if (!existsSync(path)) return void 0;
|
|
337
|
+
let module;
|
|
338
|
+
try {
|
|
339
|
+
module = require(path);
|
|
340
|
+
} catch (error) {
|
|
341
|
+
throw new Error(`Failed to load ${path}.`, { cause: error });
|
|
342
|
+
}
|
|
343
|
+
const config = module !== null && typeof module === "object" && "default" in module ? module.default : module;
|
|
344
|
+
if (config === null || typeof config !== "object" || !("sdk" in config) || typeof config.sdk !== "string" || config.sdk.length === 0 || !("org" in config) || typeof config.org !== "string" || !ORG_CODE_PATTERN.test(config.org)) throw new Error(`Invalid Hitch config in ${path}: "sdk" must be a package spec and "org" an organization code.`);
|
|
345
|
+
return {
|
|
346
|
+
sdk: config.sdk,
|
|
347
|
+
org: config.org
|
|
348
|
+
};
|
|
349
|
+
}
|
|
350
|
+
function findWorkspaceConfig(cwd) {
|
|
351
|
+
const appletsDir = dirname(cwd);
|
|
352
|
+
return readWorkspaceConfig(cwd) ?? (basename(appletsDir) === "applets" ? readWorkspaceConfig(dirname(appletsDir)) : void 0);
|
|
353
|
+
}
|
|
354
|
+
//#endregion
|
|
329
355
|
//#region src/auth.ts
|
|
330
356
|
async function fetchWithOrgAuth(orgCode, options, request) {
|
|
331
357
|
const fetcher = options.fetch ?? globalThis.fetch;
|
|
@@ -334,9 +360,10 @@ async function fetchWithOrgAuth(orgCode, options, request) {
|
|
|
334
360
|
const auth = await resolveAuthForOrg(instanceUrl, orgCode, options.store);
|
|
335
361
|
if (auth !== void 0) {
|
|
336
362
|
const response = await request(organizationUrl, bearerToken(auth));
|
|
337
|
-
|
|
363
|
+
rejectEnvironmentKey(response, auth);
|
|
364
|
+
if (response.status !== 401) return response;
|
|
338
365
|
}
|
|
339
|
-
if (!(options.stdinIsTTY ?? process.stdin.isTTY === true)) throw new
|
|
366
|
+
if (!(options.stdinIsTTY ?? process.stdin.isTTY === true)) throw new AuthenticationError("Not logged in. Run applet login, or set HITCH_API_KEY.");
|
|
340
367
|
await (options.login ?? loginWithDevice)(instanceUrl, {
|
|
341
368
|
expectedOrg: orgCode,
|
|
342
369
|
fetch: fetcher,
|
|
@@ -347,4 +374,14 @@ async function fetchWithOrgAuth(orgCode, options, request) {
|
|
|
347
374
|
return request(organizationUrl, bearerToken(credentials));
|
|
348
375
|
}
|
|
349
376
|
//#endregion
|
|
350
|
-
|
|
377
|
+
//#region src/workspace.ts
|
|
378
|
+
function resolveWorkspaceOrg(appletRoot) {
|
|
379
|
+
const appletsDir = dirname(appletRoot);
|
|
380
|
+
if (basename(appletsDir) === "applets") {
|
|
381
|
+
const config = readWorkspaceConfig(dirname(appletsDir));
|
|
382
|
+
if (config !== void 0) return config.org;
|
|
383
|
+
}
|
|
384
|
+
throw new Error(`No Hitch workspace found for ${appletRoot}. An applet must live at <workspace>/applets/<code> with hitch.config.ts in the workspace root.`);
|
|
385
|
+
}
|
|
386
|
+
//#endregion
|
|
387
|
+
export { loginWithDevice as a, resolveAuthForOrg as c, readWorkspaceConfig as i, resolveInstanceUrl as l, fetchWithOrgAuth as n, AuthenticationError as o, findWorkspaceConfig as r, organizationInstanceUrl as s, resolveWorkspaceOrg as t };
|
package/package.json
CHANGED
|
@@ -30,6 +30,8 @@ For attribute types, filters, and API limits, read `../hitch-data/SKILL.md`. To
|
|
|
30
30
|
## Work with the workspace
|
|
31
31
|
|
|
32
32
|
- Run package commands with `pnpm`.
|
|
33
|
+
- Run `pnpm exec applet login` from the workspace root or an applet directory to sign in. It uses the organization in `hitch.config.ts` and shares credentials with `hitch login`. Add `--no-browser` to print the sign-in URL without opening a browser.
|
|
34
|
+
- A server permission error is not a login request. After an applet has a CI release, the server rejects local deployments; deploy subsequent releases through CI.
|
|
33
35
|
- If `package.json` is absent, read `sdk` from `hitch.config.ts`. Run `pnpm dlx <sdk> bootstrap` from the workspace root.
|
|
34
36
|
- Run `pnpm exec applet new <code>` from the workspace root to create a full applet.
|
|
35
37
|
- Add `--client-only` or `--server-only` when the applet needs only one part.
|
|
@@ -138,3 +140,11 @@ pnpm --dir applets/<code> run build
|
|
|
138
140
|
If missing packages block a check, stop package checks. Do not retry the check through another binary.
|
|
139
141
|
|
|
140
142
|
If a command fails, report the exact blocker. Do not deploy as a verification step.
|
|
143
|
+
|
|
144
|
+
## Deploy from GitHub
|
|
145
|
+
|
|
146
|
+
- A push to the production branch runs `applet deploy` in the workspace root through GitHub Actions.
|
|
147
|
+
- An applet deploys when its own folder changed since its current CI release. Every applet deploys when a file outside `applets/` changed. An applet without a CI release always deploys.
|
|
148
|
+
- The deploy skips other applets and logs the reason. A skip is expected, not a failure.
|
|
149
|
+
- A schema change in Hitch alone does not trigger CI.
|
|
150
|
+
- Do not import from a sibling applet folder. The change check does not follow such imports.
|
|
@@ -11,6 +11,7 @@ The applet tool reads `org` from `hitch.config.ts` in the workspace root.
|
|
|
11
11
|
- `name` gives the applet a display name.
|
|
12
12
|
- `code` gives the applet its stable code and URL prefix.
|
|
13
13
|
- `objects` declares record objects and attribute access.
|
|
14
|
+
- `requiresChangeset` optionally names the schema changeset that the code needs.
|
|
14
15
|
- `variables` optionally declares runtime variables.
|
|
15
16
|
- `schedules` optionally declares scheduled server calls.
|
|
16
17
|
- `dependencies` optionally declares applet runtime packages.
|
|
@@ -42,6 +43,22 @@ The manifest and applet definition reject unknown fields.
|
|
|
42
43
|
- Expect the Vite base path to be `/<code>/`.
|
|
43
44
|
- Include the code in each client route path.
|
|
44
45
|
|
|
46
|
+
## Set `requiresChangeset`
|
|
47
|
+
|
|
48
|
+
Set `requiresChangeset` when the code needs a schema change that is not live yet.
|
|
49
|
+
|
|
50
|
+
```ts
|
|
51
|
+
requiresChangeset: "0192a1b2-c3d4-7e5f-8a9b-0c1d2e3f4a5b",
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
- Use the ID of a changeset in the same organization.
|
|
55
|
+
- Generate, build, and deploy all use this field. The CLI has no changeset flag.
|
|
56
|
+
- While the changeset is pending, types and the build use the schema that the changeset will produce.
|
|
57
|
+
- While the changeset is pending, a deploy binds the release to the changeset. The release goes live when a person applies the changeset in Hitch.
|
|
58
|
+
- After the changeset applies, the field uses the live schema. A deploy then promotes as usual. Remove the field when it is convenient.
|
|
59
|
+
- A deploy fails when the changeset was abandoned. Remove the field or name a pending changeset.
|
|
60
|
+
- A git push uses the same rules. The push never applies the changeset.
|
|
61
|
+
|
|
45
62
|
## Declare objects
|
|
46
63
|
|
|
47
64
|
Add one entry for each object that the applet needs.
|
|
@@ -12,8 +12,9 @@ The `hitch` command talks to one organization on one Hitch instance. Its data an
|
|
|
12
12
|
## Sign in
|
|
13
13
|
|
|
14
14
|
- Run `hitch login` to sign in with the device flow. The command prints a URL and a code. Open the URL and confirm the code. Add `--no-browser` when the shell cannot open a browser.
|
|
15
|
+
- `applet login` uses this same device flow and credential store. Both commands preselect the organization from `hitch.config.ts` at the workspace root or in an applet directory. Use `hitch login --org <code>` to select it explicitly.
|
|
15
16
|
- Run `hitch login --api-key` to store an API key instead. The command prompts for the key. Pass `--api-key <key>` to skip the prompt.
|
|
16
|
-
- Set `HITCH_API_KEY` to use a key for one shell session. It overrides every stored login. While it is set, `hitch login` and `hitch logout` refuse to run.
|
|
17
|
+
- Set `HITCH_API_KEY` to use a key for one shell session. It overrides every stored login. While it is set, `hitch login`, `applet login`, and `hitch logout` refuse to run.
|
|
17
18
|
- Run `hitch whoami` to print the current person, email, organization name, and organization id as JSON.
|
|
18
19
|
- Run `hitch logout` to remove every stored login and cached command set.
|
|
19
20
|
- Set `HITCH_API_URL` or pass `--instance <url>` to `hitch login` for an instance other than the default.
|
|
@@ -23,7 +24,7 @@ The `hitch` command talks to one organization on one Hitch instance. Its data an
|
|
|
23
24
|
The CLI resolves the organization in this order. The first match wins.
|
|
24
25
|
|
|
25
26
|
1. `--org <code>` on any command.
|
|
26
|
-
2. The workspace organization: the `
|
|
27
|
+
2. The workspace organization: the `org` field in `hitch.config.ts` in the current directory, or in the workspace root when the current directory is an applet under `applets/`.
|
|
27
28
|
3. `HITCH_DEFAULT_ORG`.
|
|
28
29
|
|
|
29
30
|
There is no remembered active organization. When `--org` and the workspace disagree, the command fails with `--org "x" does not match workspace organization "y"`. When several organizations are stored and none is selected, the command fails and names the three ways to choose.
|
|
@@ -110,6 +111,7 @@ hitch admin changesets update --id <changesetId> --adopt <otherChangesetId>
|
|
|
110
111
|
- Run `blockers list` before an apply. Any blocker stops the apply with HTTP 409.
|
|
111
112
|
- Run `hitch sync` after an apply, so the new objects and attributes appear as commands.
|
|
112
113
|
- Run `pnpm --dir applets/<code> run generate` after an apply, so applet types match.
|
|
114
|
+
- To build applet code before the apply, set `requiresChangeset` in `applet.manifest.ts` to the changeset ID. Generate, build, and deploy then use the changeset schema, and the release goes live when the changeset applies.
|
|
113
115
|
|
|
114
116
|
## Fix common errors
|
|
115
117
|
|
|
@@ -119,7 +121,7 @@ hitch admin changesets update --id <changesetId> --adopt <otherChangesetId>
|
|
|
119
121
|
| `HITCH_API_KEY was rejected.` | The key in the environment is invalid or revoked. Unset it or replace it. |
|
|
120
122
|
| `API key is scoped to organization "x", not "y".` | The key belongs to another organization. Select `x` or use another key. |
|
|
121
123
|
| `--org "x" does not match workspace organization` | Run the command outside the workspace, or drop `--org`. |
|
|
122
|
-
| `Multiple organizations are stored ...` | Pass `--org`,
|
|
124
|
+
| `Multiple organizations are stored ...` | Pass `--org`, use the workspace `hitch.config.ts`, or set `HITCH_DEFAULT_ORG`. |
|
|
123
125
|
| `the cached commands ... no longer load` | Run `hitch sync`. |
|
|
124
126
|
| `Refusing to delete without --yes` | Add `--yes` in a script. |
|
|
125
127
|
| `hitch <object>` is an unknown command | Run `hitch sync`. The object is new or the cache is stale. |
|
|
@@ -48,4 +48,4 @@ An organization's data lives in Hitch objects. Each object has attributes. Each
|
|
|
48
48
|
|
|
49
49
|
- Every object or attribute change goes through a changeset. Hitch evaluates the change against existing records and dependent applets.
|
|
50
50
|
- A change that would break existing data, such as a unique constraint with duplicates, is blocked until the data is fixed.
|
|
51
|
-
- An applet release can bind to a pending changeset. The changeset apply switches the schema and promotes the release together.
|
|
51
|
+
- An applet release can bind to a pending changeset. Set `requiresChangeset` in `applet.manifest.ts` to bind it. The changeset apply switches the schema and promotes the release together.
|
package/dist/build-B70gkDi5.js
DELETED
|
@@ -1,56 +0,0 @@
|
|
|
1
|
-
import { a as ORG_CODE_PATTERN, r as appletSourceDefinitionSchema } from "./manifest-DyoJ1MIL.js";
|
|
2
|
-
import { createRequire } from "node:module";
|
|
3
|
-
import { z } from "zod";
|
|
4
|
-
import { existsSync } from "node:fs";
|
|
5
|
-
import { basename, dirname, resolve } from "node:path";
|
|
6
|
-
import { loadConfigFromFile } from "vite";
|
|
7
|
-
//#region src/workspace.ts
|
|
8
|
-
const hitchConfigSchema = z.object({
|
|
9
|
-
sdk: z.string().min(1),
|
|
10
|
-
org: z.string().regex(ORG_CODE_PATTERN)
|
|
11
|
-
});
|
|
12
|
-
const require = createRequire(import.meta.url);
|
|
13
|
-
function readWorkspaceConfig(dir) {
|
|
14
|
-
const path = resolve(dir, "hitch.config.ts");
|
|
15
|
-
if (!existsSync(path)) return void 0;
|
|
16
|
-
let module;
|
|
17
|
-
try {
|
|
18
|
-
module = require(path);
|
|
19
|
-
} catch (error) {
|
|
20
|
-
throw new Error(`Failed to load ${path}.`, { cause: error });
|
|
21
|
-
}
|
|
22
|
-
const config = hitchConfigSchema.safeParse(module !== null && typeof module === "object" && "default" in module ? module.default : module);
|
|
23
|
-
if (!config.success) throw new Error(`Invalid Hitch config in ${path}: ${config.error.message}`);
|
|
24
|
-
return config.data;
|
|
25
|
-
}
|
|
26
|
-
function resolveWorkspaceOrg(appletRoot) {
|
|
27
|
-
const appletsDir = dirname(appletRoot);
|
|
28
|
-
if (basename(appletsDir) === "applets") {
|
|
29
|
-
const config = readWorkspaceConfig(dirname(appletsDir));
|
|
30
|
-
if (config !== void 0) return config.org;
|
|
31
|
-
}
|
|
32
|
-
throw new Error(`No Hitch workspace found for ${appletRoot}. An applet must live at <workspace>/applets/<code> with hitch.config.ts in the workspace root.`);
|
|
33
|
-
}
|
|
34
|
-
//#endregion
|
|
35
|
-
//#region src/typegen/load-config.ts
|
|
36
|
-
async function loadAppletSourceDefinition(root) {
|
|
37
|
-
const path = resolve(root, "applet.manifest.ts");
|
|
38
|
-
if (!existsSync(path)) throw new Error(`No applet manifest found at ${path}.`);
|
|
39
|
-
const loaded = await loadConfigFromFile({
|
|
40
|
-
command: "build",
|
|
41
|
-
mode: "production"
|
|
42
|
-
}, path, root);
|
|
43
|
-
if (loaded === null) throw new Error(`No applet manifest found at ${path}.`);
|
|
44
|
-
const parsed = appletSourceDefinitionSchema.safeParse(loaded.config);
|
|
45
|
-
if (!parsed.success) throw new Error(`Invalid applet manifest at ${loaded.path}: ${parsed.error.message}`);
|
|
46
|
-
return parsed.data;
|
|
47
|
-
}
|
|
48
|
-
async function loadAppletConfig(root) {
|
|
49
|
-
const { dependencies: _dependencies, devDependencies: _devDependencies, ...definition } = await loadAppletSourceDefinition(root);
|
|
50
|
-
return {
|
|
51
|
-
org: resolveWorkspaceOrg(root),
|
|
52
|
-
...definition
|
|
53
|
-
};
|
|
54
|
-
}
|
|
55
|
-
//#endregion
|
|
56
|
-
export { resolveWorkspaceOrg as i, loadAppletSourceDefinition as n, readWorkspaceConfig as r, loadAppletConfig as t };
|