@hitch42/applet 0.1.0-beta.10 → 0.1.0-beta.11
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 +11 -11
- package/dist/{build-BlmLiKro.js → build-BRpYQ9Lk.js} +1 -1
- package/dist/build-CypJADhV.js +2 -0
- package/dist/{ci-0Q2mUh53.js → ci-C2CL-0sj.js} +2 -2
- package/dist/client.d.ts +2 -2
- package/dist/{contract-QUvEGiRI.d.ts → contract-CsUpTBe0.d.ts} +1 -1
- package/dist/{deploy-BbL3GObV.js → deploy-CdQQQ5HG.js} +131 -80
- package/dist/{generate-XB-72Fzj.js → generate-BDHb2kjw.js} +7 -4
- package/dist/generate-Cai2X9z1.js +2 -0
- package/dist/index.d.ts +3 -2
- package/dist/index.js +2 -1
- package/dist/{init-DwsXRUk-.js → init-CpVfJQbv.js} +4 -4
- package/dist/{load-config-OKZU3UKn.js → load-config-DI-e1Ool.js} +1 -1
- package/dist/{logs-XvK6Zs5Y.js → logs-CffdKMRd.js} +2 -2
- package/dist/{manifest-I-9s8R36.d.ts → manifest-C6_F4bL8.d.ts} +3 -1
- package/dist/{manifest-4ZAc6HUk.js → manifest-CJSL9GuC.js} +6 -1
- package/dist/{project-B0qNXnFu.js → project-D-hX59RS.js} +4 -1
- package/dist/react.d.ts +2 -1
- package/dist/react.js +57 -37
- package/dist/{schedules-BkWZsbSs.js → schedules-DIIowhD3.js} +1 -1
- package/dist/server.d.ts +2 -2
- package/dist/telephony.d.ts +24 -4
- package/dist/telephony.js +135 -16
- package/dist/{variables-0tjnAeut.js → variables-Bzl2ZLQN.js} +1 -1
- package/dist/vite.d.ts +1 -1
- package/dist/vite.js +17 -6
- package/package.json +3 -1
- package/scaffold/.agents/skills/hitch-applets/SKILL.md +1 -1
- package/scaffold/.agents/skills/hitch-applets/references/markdown.md +2 -0
- package/scaffold/.agents/skills/hitch-theory/SKILL.md +1 -1
- package/scaffold/.github/workflows/hitch.yml +1 -1
- package/scaffold/applet/src/client/styles/globals.css +2 -0
- package/dist/build-CcT-wNN9.js +0 -2
- package/dist/generate-wIN3IYqL.js +0 -2
package/dist/applet.js
CHANGED
|
@@ -99,23 +99,23 @@ async function main() {
|
|
|
99
99
|
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;
|
|
100
100
|
const noModeFlags = values["client-only"] === void 0 && values["server-only"] === void 0;
|
|
101
101
|
if (positionals.length === 1 && positionals[0] === "bootstrap" && noModeFlags && noGitFlags && noVariableFlags && noLogFlags) {
|
|
102
|
-
await (await import("./init-
|
|
102
|
+
await (await import("./init-CpVfJQbv.js")).runBootstrap({ install: values["no-install"] !== true });
|
|
103
103
|
return;
|
|
104
104
|
}
|
|
105
105
|
if (positionals.length === 1 && positionals[0] === "generate" && values["no-install"] === void 0 && noModeFlags && noGitFlags && noVariableFlags && noLogFlags) {
|
|
106
|
-
await (await import("./generate-
|
|
106
|
+
await (await import("./generate-Cai2X9z1.js")).runGenerate({});
|
|
107
107
|
return;
|
|
108
108
|
}
|
|
109
109
|
if (positionals.length === 1 && positionals[0] === "build" && values["no-install"] === void 0 && noModeFlags && noGitFlags && noVariableFlags && noLogFlags) {
|
|
110
|
-
await (await import("./build-
|
|
110
|
+
await (await import("./build-CypJADhV.js")).runBuild();
|
|
111
111
|
return;
|
|
112
112
|
}
|
|
113
113
|
if (positionals.length === 1 && positionals[0] === "deploy" && values["no-install"] === void 0 && noModeFlags && noGitFlags && noVariableFlags && noLogFlags) {
|
|
114
|
-
await (await import("./deploy-
|
|
114
|
+
await (await import("./deploy-CdQQQ5HG.js")).runDeploy({});
|
|
115
115
|
return;
|
|
116
116
|
}
|
|
117
117
|
if (positionals.length === 2 && positionals[0] === "init" && noModeFlags && noVariableFlags && noLogFlags) {
|
|
118
|
-
await (await import("./init-
|
|
118
|
+
await (await import("./init-CpVfJQbv.js")).runInit(positionals[1], {
|
|
119
119
|
commit: values["no-commit"] !== true,
|
|
120
120
|
git: values["no-git"] !== true,
|
|
121
121
|
install: values["no-install"] !== true
|
|
@@ -123,7 +123,7 @@ async function main() {
|
|
|
123
123
|
return;
|
|
124
124
|
}
|
|
125
125
|
if (positionals.length === 2 && positionals[0] === "new" && noGitFlags && noVariableFlags && noLogFlags) {
|
|
126
|
-
await (await import("./init-
|
|
126
|
+
await (await import("./init-CpVfJQbv.js")).runNew({
|
|
127
127
|
code: positionals[1],
|
|
128
128
|
clientOnly: values["client-only"],
|
|
129
129
|
install: values["no-install"] !== true,
|
|
@@ -132,7 +132,7 @@ async function main() {
|
|
|
132
132
|
return;
|
|
133
133
|
}
|
|
134
134
|
if ((positionals.length === 1 || positionals.length === 2) && positionals[0] === "logs" && values["no-install"] === void 0 && noModeFlags && noGitFlags && noVariableFlags) {
|
|
135
|
-
await (await import("./logs-
|
|
135
|
+
await (await import("./logs-CffdKMRd.js")).runLogs({
|
|
136
136
|
code: positionals[1],
|
|
137
137
|
filter: values.filter,
|
|
138
138
|
run: values.run,
|
|
@@ -145,14 +145,14 @@ async function main() {
|
|
|
145
145
|
return;
|
|
146
146
|
}
|
|
147
147
|
if (positionals.length === 3 && positionals[0] === "schedules" && positionals[1] === "run" && values["no-install"] === void 0 && noModeFlags && noGitFlags && noLogFlags && values.secret === void 0) {
|
|
148
|
-
await (await import("./schedules-
|
|
148
|
+
await (await import("./schedules-DIIowhD3.js")).runSchedule({
|
|
149
149
|
code: positionals[2],
|
|
150
150
|
yes: values.yes
|
|
151
151
|
});
|
|
152
152
|
return;
|
|
153
153
|
}
|
|
154
154
|
if ((positionals.length === 3 || positionals.length === 4) && positionals[0] === "variables" && positionals[1] === "set" && values["no-install"] === void 0 && noModeFlags && noGitFlags && noLogFlags) {
|
|
155
|
-
await (await import("./variables-
|
|
155
|
+
await (await import("./variables-Bzl2ZLQN.js")).runVariablesSet({
|
|
156
156
|
key: positionals[2],
|
|
157
157
|
secret: values.secret,
|
|
158
158
|
value: positionals[3],
|
|
@@ -161,11 +161,11 @@ async function main() {
|
|
|
161
161
|
return;
|
|
162
162
|
}
|
|
163
163
|
if (positionals.length === 2 && positionals[0] === "variables" && positionals[1] === "list" && values["no-install"] === void 0 && noModeFlags && noGitFlags && noVariableFlags && noLogFlags) {
|
|
164
|
-
await (await import("./variables-
|
|
164
|
+
await (await import("./variables-Bzl2ZLQN.js")).runVariablesList({});
|
|
165
165
|
return;
|
|
166
166
|
}
|
|
167
167
|
if (positionals.length === 3 && positionals[0] === "variables" && positionals[1] === "delete" && values["no-install"] === void 0 && noModeFlags && noGitFlags && values.secret === void 0 && noLogFlags) {
|
|
168
|
-
await (await import("./variables-
|
|
168
|
+
await (await import("./variables-Bzl2ZLQN.js")).runVariablesDelete({
|
|
169
169
|
key: positionals[2],
|
|
170
170
|
yes: values.yes
|
|
171
171
|
});
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { i as prepareAppletProjects, r as prepareAppletProject } from "./project-
|
|
1
|
+
import { i as prepareAppletProjects, r as prepareAppletProject } from "./project-D-hX59RS.js";
|
|
2
2
|
import { rm } from "node:fs/promises";
|
|
3
3
|
import { resolve } from "node:path";
|
|
4
4
|
import { spawn } from "node:child_process";
|
|
@@ -56,11 +56,11 @@ async function loadGitHubActionsSources(context, options) {
|
|
|
56
56
|
const body = await response.json();
|
|
57
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
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" || !("
|
|
59
|
+
if (source === null || typeof source !== "object" || !("code" in source) || typeof source.code !== "string" || !("source_directory" in source) || typeof source.source_directory !== "string" || !("source_hash" in source) || source.source_hash !== null && typeof source.source_hash !== "string") throw new Error("Each CI applet must contain code, source_directory, and source_hash fields.");
|
|
60
60
|
return {
|
|
61
61
|
code: source.code,
|
|
62
62
|
sourceDirectory: source.source_directory,
|
|
63
|
-
|
|
63
|
+
sourceHash: source.source_hash
|
|
64
64
|
};
|
|
65
65
|
});
|
|
66
66
|
}
|
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-C6_F4bL8.js";
|
|
2
|
+
import { t as NarrowContract } from "./contract-CsUpTBe0.js";
|
|
3
3
|
import { t as WithBatchRecorder } from "./batch-Qa4B4-Yp.js";
|
|
4
4
|
import { o as WithFilesUpload } from "./upload-DKZzz5kW.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-C6_F4bL8.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,11 +1,12 @@
|
|
|
1
1
|
import { i as readWorkspaceConfig, n as fetchWithOrgAuth } from "./workspace-DruAZPmV.js";
|
|
2
|
-
import { a as loadGitHubActionsSources, n as githubActionsContext, r as hitchResponseError, t as fetchWithGitHubActions } from "./ci-
|
|
3
|
-
import { n as buildPreparedApplet, r as prepareWorkspaceBuild, t as buildApplet } from "./build-
|
|
2
|
+
import { a as loadGitHubActionsSources, n as githubActionsContext, r as hitchResponseError, t as fetchWithGitHubActions } from "./ci-C2CL-0sj.js";
|
|
3
|
+
import { n as buildPreparedApplet, r as prepareWorkspaceBuild, t as buildApplet } from "./build-BRpYQ9Lk.js";
|
|
4
4
|
import { createRequire } from "node:module";
|
|
5
|
+
import { createHash } from "node:crypto";
|
|
5
6
|
import { existsSync } from "node:fs";
|
|
6
|
-
import { readFile, readdir } from "node:fs/promises";
|
|
7
|
-
import { relative, resolve, sep } from "node:path";
|
|
8
|
-
import { execFile } from "node:child_process";
|
|
7
|
+
import { lstat, readFile, readdir, readlink } from "node:fs/promises";
|
|
8
|
+
import { dirname, relative, resolve, sep } from "node:path";
|
|
9
|
+
import { execFile, spawn } from "node:child_process";
|
|
9
10
|
import { promisify } from "node:util";
|
|
10
11
|
import { createGzip } from "node:zlib";
|
|
11
12
|
//#region \0rolldown/runtime.js
|
|
@@ -2307,11 +2308,112 @@ var require_pack = /* @__PURE__ */ __commonJSMin(((exports, module) => {
|
|
|
2307
2308
|
}
|
|
2308
2309
|
}));
|
|
2309
2310
|
//#endregion
|
|
2310
|
-
//#region src/
|
|
2311
|
+
//#region src/source-hash.ts
|
|
2311
2312
|
var import_tar_stream = /* @__PURE__ */ __toESM((/* @__PURE__ */ __commonJSMin(((exports) => {
|
|
2312
2313
|
exports.extract = require_extract();
|
|
2313
2314
|
exports.pack = require_pack();
|
|
2314
2315
|
})))(), 1);
|
|
2316
|
+
const execFileAsync$1 = promisify(execFile);
|
|
2317
|
+
function gitEnvironment() {
|
|
2318
|
+
return Object.fromEntries(Object.entries(process.env).filter(([key]) => !key.startsWith("GIT_")));
|
|
2319
|
+
}
|
|
2320
|
+
var SourceHashUnavailableError = class extends Error {
|
|
2321
|
+
constructor() {
|
|
2322
|
+
super("Git is unavailable or the applet is outside a git repository.");
|
|
2323
|
+
}
|
|
2324
|
+
};
|
|
2325
|
+
function isMissingPath(error) {
|
|
2326
|
+
return error instanceof Error && "code" in error && (error.code === "ENOENT" || error.code === "ENOTDIR");
|
|
2327
|
+
}
|
|
2328
|
+
async function hashFiles(topLevel, paths, env) {
|
|
2329
|
+
if (paths.length === 0) return [];
|
|
2330
|
+
return new Promise((resolveHashes, reject) => {
|
|
2331
|
+
const child = spawn("git", ["hash-object", "--stdin-paths"], {
|
|
2332
|
+
cwd: topLevel,
|
|
2333
|
+
env
|
|
2334
|
+
});
|
|
2335
|
+
const stdout = [];
|
|
2336
|
+
const stderr = [];
|
|
2337
|
+
child.stdout.on("data", (chunk) => stdout.push(chunk));
|
|
2338
|
+
child.stderr.on("data", (chunk) => stderr.push(chunk));
|
|
2339
|
+
child.stdin.on("error", reject);
|
|
2340
|
+
child.on("error", reject);
|
|
2341
|
+
child.on("close", (code) => {
|
|
2342
|
+
if (code !== 0) {
|
|
2343
|
+
reject(/* @__PURE__ */ new Error(`git hash-object failed (${code}): ${Buffer.concat(stderr).toString("utf8").trim()}`));
|
|
2344
|
+
return;
|
|
2345
|
+
}
|
|
2346
|
+
const hashes = Buffer.concat(stdout).toString("utf8").trimEnd().split("\n");
|
|
2347
|
+
if (hashes.length !== paths.length || hashes.some((hash) => !/^[0-9a-f]{40,64}$/.test(hash))) {
|
|
2348
|
+
reject(/* @__PURE__ */ new Error("git hash-object returned an unexpected number of hashes."));
|
|
2349
|
+
return;
|
|
2350
|
+
}
|
|
2351
|
+
resolveHashes(hashes);
|
|
2352
|
+
});
|
|
2353
|
+
child.stdin.end(paths.map((path) => `"${path.split("").map((character) => character < " " || character === "" || character === "\"" || character === "\\" ? `\\${character.charCodeAt(0).toString(8).padStart(3, "0")}` : character).join("")}"\n`).join(""));
|
|
2354
|
+
});
|
|
2355
|
+
}
|
|
2356
|
+
async function sourceHashes(appletRoots) {
|
|
2357
|
+
if (appletRoots.length === 0) return /* @__PURE__ */ new Map();
|
|
2358
|
+
const env = gitEnvironment();
|
|
2359
|
+
const workspaceRoot = dirname(dirname(appletRoots[0]));
|
|
2360
|
+
let topLevel;
|
|
2361
|
+
try {
|
|
2362
|
+
const { stdout } = await execFileAsync$1("git", ["rev-parse", "--show-toplevel"], {
|
|
2363
|
+
cwd: workspaceRoot,
|
|
2364
|
+
env
|
|
2365
|
+
});
|
|
2366
|
+
topLevel = stdout.trim();
|
|
2367
|
+
} catch (error) {
|
|
2368
|
+
if (isMissingPath(error) || error instanceof Error && error.message.includes("not a git repository")) throw new SourceHashUnavailableError();
|
|
2369
|
+
throw error;
|
|
2370
|
+
}
|
|
2371
|
+
const { stdout } = await execFileAsync$1("git", [
|
|
2372
|
+
"ls-files",
|
|
2373
|
+
"-z",
|
|
2374
|
+
"--cached",
|
|
2375
|
+
"--others",
|
|
2376
|
+
"--exclude-standard"
|
|
2377
|
+
], {
|
|
2378
|
+
cwd: topLevel,
|
|
2379
|
+
env,
|
|
2380
|
+
maxBuffer: 67108864
|
|
2381
|
+
});
|
|
2382
|
+
const paths = [...new Set(stdout.split("\0").filter(Boolean))];
|
|
2383
|
+
const present = (await Promise.all(paths.map(async (path) => {
|
|
2384
|
+
const absolutePath = resolve(topLevel, path);
|
|
2385
|
+
try {
|
|
2386
|
+
const stat = await lstat(absolutePath);
|
|
2387
|
+
if (stat.isFile()) return {
|
|
2388
|
+
path,
|
|
2389
|
+
kind: "file"
|
|
2390
|
+
};
|
|
2391
|
+
if (stat.isSymbolicLink()) return {
|
|
2392
|
+
path,
|
|
2393
|
+
kind: "link",
|
|
2394
|
+
contentId: await readlink(absolutePath)
|
|
2395
|
+
};
|
|
2396
|
+
return;
|
|
2397
|
+
} catch (error) {
|
|
2398
|
+
if (isMissingPath(error)) return void 0;
|
|
2399
|
+
throw error;
|
|
2400
|
+
}
|
|
2401
|
+
}))).filter((entry) => entry !== void 0);
|
|
2402
|
+
const regularPaths = present.filter((entry) => entry.kind === "file").map((entry) => entry.path);
|
|
2403
|
+
const hashes = await hashFiles(topLevel, regularPaths, env);
|
|
2404
|
+
const contentIds = /* @__PURE__ */ new Map();
|
|
2405
|
+
present.filter((entry) => entry.kind === "link").forEach((entry) => contentIds.set(entry.path, entry.contentId));
|
|
2406
|
+
regularPaths.forEach((path, index) => contentIds.set(path, hashes[index]));
|
|
2407
|
+
const appletsDirectory = relative(topLevel, resolve(workspaceRoot, "applets")).split(sep).join("/");
|
|
2408
|
+
return new Map(appletRoots.map((appletRoot) => {
|
|
2409
|
+
const appletDirectory = relative(topLevel, appletRoot).split(sep).join("/");
|
|
2410
|
+
const digest = createHash("sha256");
|
|
2411
|
+
[...contentIds.entries()].filter(([path]) => path !== appletsDirectory && !path.startsWith(`${appletsDirectory}/`) || path.startsWith(`${appletDirectory}/`)).sort(([left], [right]) => Buffer.compare(Buffer.from(left), Buffer.from(right))).forEach(([path, contentId]) => digest.update(`${path}\0${contentId}\n`));
|
|
2412
|
+
return [appletRoot, digest.digest("hex")];
|
|
2413
|
+
}));
|
|
2414
|
+
}
|
|
2415
|
+
//#endregion
|
|
2416
|
+
//#region src/deploy.ts
|
|
2315
2417
|
const execFileAsync = promisify(execFile);
|
|
2316
2418
|
var WorkspaceDeployError = class extends Error {
|
|
2317
2419
|
constructor(failedApplets) {
|
|
@@ -2363,9 +2465,6 @@ async function createBundle(distDir) {
|
|
|
2363
2465
|
body.set(bundle);
|
|
2364
2466
|
return body;
|
|
2365
2467
|
}
|
|
2366
|
-
function gitEnvironment() {
|
|
2367
|
-
return Object.fromEntries(Object.entries(process.env).filter(([key]) => !key.startsWith("GIT_")));
|
|
2368
|
-
}
|
|
2369
2468
|
async function readGitInfo(appletRoot) {
|
|
2370
2469
|
const env = gitEnvironment();
|
|
2371
2470
|
try {
|
|
@@ -2399,13 +2498,14 @@ function releaseForm(manifest, bundle) {
|
|
|
2399
2498
|
body.set("bundle", new File([bundle], "bundle.tar.gz", { type: "application/gzip" }));
|
|
2400
2499
|
return body;
|
|
2401
2500
|
}
|
|
2402
|
-
async function deployWithOrgAuth(appletRoot, distDir, manifest, options) {
|
|
2501
|
+
async function deployWithOrgAuth(appletRoot, distDir, manifest, options, sourceHash) {
|
|
2403
2502
|
const fetcher = options.fetch ?? globalThis.fetch;
|
|
2404
2503
|
const [bundle, git] = await Promise.all([createBundle(distDir), readGitInfo(appletRoot)]);
|
|
2405
2504
|
return fetchWithOrgAuth(manifest.org, options, (instanceUrl, accessToken) => {
|
|
2406
2505
|
const body = releaseForm(manifest, bundle);
|
|
2407
2506
|
body.set("gitDirty", String(git.gitDirty));
|
|
2408
2507
|
if (git.gitSha !== void 0) body.set("gitSha", git.gitSha);
|
|
2508
|
+
if (sourceHash !== void 0) body.set("sourceHash", sourceHash);
|
|
2409
2509
|
return fetcher(`${instanceUrl}/api/v1/applets/${manifest.code}/releases`, {
|
|
2410
2510
|
method: "POST",
|
|
2411
2511
|
headers: { Authorization: `Bearer ${accessToken}` },
|
|
@@ -2413,12 +2513,13 @@ async function deployWithOrgAuth(appletRoot, distDir, manifest, options) {
|
|
|
2413
2513
|
});
|
|
2414
2514
|
});
|
|
2415
2515
|
}
|
|
2416
|
-
async function deployWithGitHubActions(context, appletRoot, distDir, manifest, options) {
|
|
2516
|
+
async function deployWithGitHubActions(context, appletRoot, distDir, manifest, options, sourceHash) {
|
|
2417
2517
|
const fetcher = options.fetch ?? globalThis.fetch;
|
|
2418
2518
|
const [bundle, sourceDirectory] = await Promise.all([createBundle(distDir), repositoryDirectory(appletRoot)]);
|
|
2419
2519
|
return fetchWithGitHubActions(context, options, (instanceUrl, accessToken) => {
|
|
2420
2520
|
const body = releaseForm(manifest, bundle);
|
|
2421
2521
|
body.set("source_directory", sourceDirectory);
|
|
2522
|
+
if (sourceHash !== void 0) body.set("source_hash", sourceHash);
|
|
2422
2523
|
return fetcher(`${instanceUrl}/api/ci/v1/applets/${manifest.code}/releases`, {
|
|
2423
2524
|
method: "POST",
|
|
2424
2525
|
headers: { Authorization: `Bearer ${accessToken}` },
|
|
@@ -2426,12 +2527,13 @@ async function deployWithGitHubActions(context, appletRoot, distDir, manifest, o
|
|
|
2426
2527
|
});
|
|
2427
2528
|
});
|
|
2428
2529
|
}
|
|
2429
|
-
async function deployApplet(appletRoot, options, logPrefix = "") {
|
|
2530
|
+
async function deployApplet(appletRoot, options, logPrefix = "", sourceHash) {
|
|
2430
2531
|
const github = githubActionsContext(options.store?.env ?? process.env);
|
|
2532
|
+
sourceHash ??= (await computeSourceHash([appletRoot], github !== void 0)).get(appletRoot);
|
|
2431
2533
|
if (options.dist === void 0) await buildApplet(appletRoot);
|
|
2432
2534
|
const distDir = resolve(appletRoot, options.dist ?? ".hitch/dist");
|
|
2433
2535
|
const manifest = await readManifest(distDir);
|
|
2434
|
-
const response = github === void 0 ? await deployWithOrgAuth(appletRoot, distDir, manifest, options) : await deployWithGitHubActions(github, appletRoot, distDir, manifest, options);
|
|
2536
|
+
const response = github === void 0 ? await deployWithOrgAuth(appletRoot, distDir, manifest, options, sourceHash) : await deployWithGitHubActions(github, appletRoot, distDir, manifest, options, sourceHash);
|
|
2435
2537
|
if (!response.ok) throw await hitchResponseError(response, "Deploy failed");
|
|
2436
2538
|
const result = await response.json();
|
|
2437
2539
|
console.log(`${logPrefix}Deployed release ${result.data.id} (${result.promoted ? "promoted" : "not promoted"}).`);
|
|
@@ -2452,84 +2554,32 @@ async function workspaceAppletRoots(workspaceRoot) {
|
|
|
2452
2554
|
if (roots.length === 0) throw new Error(`No applets were found under ${appletsDir}.`);
|
|
2453
2555
|
return roots;
|
|
2454
2556
|
}
|
|
2455
|
-
async function
|
|
2557
|
+
async function computeSourceHash(appletRoots, required) {
|
|
2456
2558
|
try {
|
|
2457
|
-
await
|
|
2458
|
-
"diff",
|
|
2459
|
-
"--quiet",
|
|
2460
|
-
base,
|
|
2461
|
-
"HEAD",
|
|
2462
|
-
"--",
|
|
2463
|
-
...pathspecs
|
|
2464
|
-
], {
|
|
2465
|
-
cwd: topLevel,
|
|
2466
|
-
env
|
|
2467
|
-
});
|
|
2468
|
-
return false;
|
|
2559
|
+
return await sourceHashes(appletRoots);
|
|
2469
2560
|
} catch (error) {
|
|
2470
|
-
if (error instanceof
|
|
2561
|
+
if (!required && error instanceof SourceHashUnavailableError) return /* @__PURE__ */ new Map();
|
|
2471
2562
|
throw error;
|
|
2472
2563
|
}
|
|
2473
2564
|
}
|
|
2474
|
-
async function
|
|
2475
|
-
const
|
|
2476
|
-
|
|
2477
|
-
|
|
2478
|
-
|
|
2479
|
-
|
|
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, {
|
|
2565
|
+
async function ciDeployDecisions(github, appletRoots, hashes, options) {
|
|
2566
|
+
const [sources, directories] = await Promise.all([loadGitHubActionsSources(github, options), Promise.all(appletRoots.map((appletRoot) => repositoryDirectory(appletRoot)))]);
|
|
2567
|
+
const hashByDirectory = new Map(sources.map((source) => [source.sourceDirectory, source.sourceHash]));
|
|
2568
|
+
return new Map(appletRoots.map((appletRoot, index) => {
|
|
2569
|
+
const sourceHash = hashByDirectory.get(directories[index]);
|
|
2570
|
+
if (sourceHash === null || sourceHash === void 0) return [appletRoot, {
|
|
2520
2571
|
deploy: true,
|
|
2521
|
-
reason:
|
|
2572
|
+
reason: "no release with a source hash to compare"
|
|
2522
2573
|
}];
|
|
2523
|
-
if (
|
|
2574
|
+
if (sourceHash !== hashes.get(appletRoot)) return [appletRoot, {
|
|
2524
2575
|
deploy: true,
|
|
2525
|
-
reason:
|
|
2576
|
+
reason: "files changed since the current release"
|
|
2526
2577
|
}];
|
|
2527
2578
|
return [appletRoot, {
|
|
2528
2579
|
deploy: false,
|
|
2529
|
-
reason:
|
|
2580
|
+
reason: "no changes since the current release"
|
|
2530
2581
|
}];
|
|
2531
2582
|
}));
|
|
2532
|
-
return new Map(decisions);
|
|
2533
2583
|
}
|
|
2534
2584
|
async function runDeploy(options) {
|
|
2535
2585
|
const root = process.cwd();
|
|
@@ -2540,7 +2590,8 @@ async function runDeploy(options) {
|
|
|
2540
2590
|
}
|
|
2541
2591
|
if (readWorkspaceConfig(root) === void 0) throw new Error("Run applet deploy in an applet folder or in the workspace root.");
|
|
2542
2592
|
const appletRoots = await workspaceAppletRoots(root);
|
|
2543
|
-
const
|
|
2593
|
+
const hashes = await computeSourceHash(appletRoots, github !== void 0);
|
|
2594
|
+
const decisions = github === void 0 ? void 0 : await ciDeployDecisions(github, appletRoots, hashes, options);
|
|
2544
2595
|
const selectedRoots = appletRoots.filter((appletRoot) => {
|
|
2545
2596
|
const name = relative(root, appletRoot);
|
|
2546
2597
|
const decision = decisions?.get(appletRoot);
|
|
@@ -2561,7 +2612,7 @@ async function runDeploy(options) {
|
|
|
2561
2612
|
await deployApplet(appletRoot, {
|
|
2562
2613
|
...options,
|
|
2563
2614
|
dist: options.dist ?? ".hitch/dist"
|
|
2564
|
-
}, logPrefix);
|
|
2615
|
+
}, logPrefix, hashes.get(appletRoot));
|
|
2565
2616
|
};
|
|
2566
2617
|
if (interactive) {
|
|
2567
2618
|
for (const appletRoot of selectedRoots) await deploy(appletRoot);
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { f as resolveInstanceUrl, l as organizationInstanceUrl, n as fetchWithOrgAuth } from "./workspace-DruAZPmV.js";
|
|
2
|
-
import { i as loadGitHubActionsBuildInputs, n as githubActionsContext } from "./ci-
|
|
3
|
-
import { r as prepareAppletProject } from "./project-
|
|
4
|
-
import { t as loadAppletConfig } from "./load-config-
|
|
2
|
+
import { i as loadGitHubActionsBuildInputs, n as githubActionsContext } from "./ci-C2CL-0sj.js";
|
|
3
|
+
import { r as prepareAppletProject } from "./project-D-hX59RS.js";
|
|
4
|
+
import { t as loadAppletConfig } from "./load-config-DI-e1Ool.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";
|
|
@@ -479,7 +479,10 @@ export type * from "./zod.gen.ts";
|
|
|
479
479
|
`);
|
|
480
480
|
}
|
|
481
481
|
async function syncContract(outDir, manifest, options = {}) {
|
|
482
|
-
await writeContractFiles(outDir, manifest,
|
|
482
|
+
await writeContractFiles(outDir, manifest, manifest.objects.length === 0 ? {
|
|
483
|
+
paths: {},
|
|
484
|
+
components: { schemas: {} }
|
|
485
|
+
} : await loadAuthenticatedSpec(manifest, options));
|
|
483
486
|
}
|
|
484
487
|
async function runGenerate(options) {
|
|
485
488
|
await prepareAppletProject();
|
package/dist/index.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
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-C6_F4bL8.js";
|
|
2
|
+
import { n as pruneContract, t as NarrowContract } from "./contract-CsUpTBe0.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-DKZzz5kW.js";
|
|
4
4
|
import { a as createEmailPixelOutputSchema, c as emailTagsSchema, d as listEmailTrackersInputSchema, f as listEmailTrackersOutputSchema, i as createEmailPixelInputSchema, l as emailTrackerSchema, m as markEmailTrackerSentInputSchema, n as EmailTracker, o as emailContract, r as ListEmailTrackersOutput, s as emailTagKeySchema, t as TelephonyMessageReceivedEvent, u as getEmailTrackerInputSchema } from "./telephony-protocol-D-nf3Gca.js";
|
|
5
5
|
import { ContractProcedure, Meta } from "@orpc/contract";
|
|
@@ -47,6 +47,7 @@ type HitchPhoneNumber = {
|
|
|
47
47
|
e164: string;
|
|
48
48
|
label: string;
|
|
49
49
|
enabled: boolean;
|
|
50
|
+
assignedTo: string | null;
|
|
50
51
|
canRead: boolean;
|
|
51
52
|
canSend: boolean;
|
|
52
53
|
canCall: boolean;
|
package/dist/index.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { i as registerHitchContract, t as uploadFile } from "./upload-DRbVhuDm.js";
|
|
2
2
|
import { a as emailTagsSchema, c as listEmailTrackersInputSchema, d as markEmailTrackerSentInputSchema, i as emailTagKeySchema, l as listEmailTrackersOutputSchema, n as createEmailPixelOutputSchema, o as emailTrackerSchema, r as emailContract, s as getEmailTrackerInputSchema, t as createEmailPixelInputSchema } from "./email-DBTVhNB_.js";
|
|
3
3
|
import { n as meSchema, t as meContract } from "./me-BW7Paary.js";
|
|
4
|
-
import { n as appletManifestSchema, r as appletSourceDefinitionSchema, t as appletDefinitionSchema } from "./manifest-
|
|
4
|
+
import { n as appletManifestSchema, r as appletSourceDefinitionSchema, t as appletDefinitionSchema } from "./manifest-CJSL9GuC.js";
|
|
5
5
|
import { oc } from "@orpc/contract";
|
|
6
6
|
import { z } from "zod";
|
|
7
7
|
//#region src/hitch/contract.ts
|
|
@@ -86,6 +86,7 @@ const hitchPhoneNumberSchema = z.object({
|
|
|
86
86
|
e164: z.string(),
|
|
87
87
|
label: z.string(),
|
|
88
88
|
enabled: z.boolean(),
|
|
89
|
+
assignedTo: z.uuid().nullable(),
|
|
89
90
|
canRead: z.boolean(),
|
|
90
91
|
canSend: z.boolean(),
|
|
91
92
|
canCall: z.boolean(),
|
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
import { a as ORG_CODE_PATTERN, i as APPLET_CODE_PATTERN } from "./manifest-
|
|
1
|
+
import { a as ORG_CODE_PATTERN, i as APPLET_CODE_PATTERN } from "./manifest-CJSL9GuC.js";
|
|
2
2
|
import { d as resolveAuthForOrg, f as resolveInstanceUrl, i as readWorkspaceConfig } from "./workspace-DruAZPmV.js";
|
|
3
|
-
import { n as runGenerate } from "./generate-
|
|
4
|
-
import { a as writeAppletSupport, n as loadCliManifest, o as writeWorkspaceSupport, t as assertWorkspaceCli } from "./project-
|
|
5
|
-
import { n as loadAppletSourceDefinition } from "./load-config-
|
|
3
|
+
import { n as runGenerate } from "./generate-BDHb2kjw.js";
|
|
4
|
+
import { a as writeAppletSupport, n as loadCliManifest, o as writeWorkspaceSupport, t as assertWorkspaceCli } from "./project-D-hX59RS.js";
|
|
5
|
+
import { n as loadAppletSourceDefinition } from "./load-config-DI-e1Ool.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";
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { r as appletSourceDefinitionSchema } from "./manifest-
|
|
1
|
+
import { r as appletSourceDefinitionSchema } from "./manifest-CJSL9GuC.js";
|
|
2
2
|
import { t as resolveWorkspaceOrg } from "./workspace-DruAZPmV.js";
|
|
3
3
|
import { existsSync } from "node:fs";
|
|
4
4
|
import { resolve } from "node:path";
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { i as APPLET_CODE_PATTERN } from "./manifest-
|
|
1
|
+
import { i as APPLET_CODE_PATTERN } from "./manifest-CJSL9GuC.js";
|
|
2
2
|
import { i as readWorkspaceConfig, n as fetchWithOrgAuth, t as resolveWorkspaceOrg } from "./workspace-DruAZPmV.js";
|
|
3
|
-
import { t as loadAppletConfig } from "./load-config-
|
|
3
|
+
import { t as loadAppletConfig } from "./load-config-DI-e1Ool.js";
|
|
4
4
|
import { z } from "zod";
|
|
5
5
|
//#region src/logs.ts
|
|
6
6
|
const LOG_LEVELS = [
|
|
@@ -35,7 +35,9 @@ interface AppletManifest {
|
|
|
35
35
|
/** This code needs the schema as of this changeset. */
|
|
36
36
|
requiresChangeset?: string;
|
|
37
37
|
telephony?: {
|
|
38
|
-
|
|
38
|
+
read?: boolean;
|
|
39
|
+
send?: boolean;
|
|
40
|
+
events?: readonly "message.received"[];
|
|
39
41
|
};
|
|
40
42
|
schedules?: readonly {
|
|
41
43
|
code: string;
|
|
@@ -73,7 +73,11 @@ const appletManifestShape = {
|
|
|
73
73
|
name: nameSchema,
|
|
74
74
|
code: codeSchema,
|
|
75
75
|
requiresChangeset: z.uuid().optional(),
|
|
76
|
-
telephony: z.strictObject({
|
|
76
|
+
telephony: z.strictObject({
|
|
77
|
+
read: z.boolean().optional(),
|
|
78
|
+
send: z.boolean().optional(),
|
|
79
|
+
events: z.array(z.literal("message.received")).min(1).refine((events) => new Set(events).size === events.length).readonly().optional()
|
|
80
|
+
}).refine((telephony) => telephony.events === void 0 || telephony.read === true, "telephony.events needs telephony.read").optional(),
|
|
77
81
|
schedules: appletManifestSchedulesSchema.optional(),
|
|
78
82
|
variables: appletManifestVariablesSchema.optional(),
|
|
79
83
|
objects: appletManifestObjectsSchema
|
|
@@ -113,6 +117,7 @@ const appletDefinitionSchema = z.strictObject({
|
|
|
113
117
|
}).superRefine(checkDuplicateCodes);
|
|
114
118
|
const packageVersionsSchema = z.record(z.string().min(1), z.string().min(1)).readonly();
|
|
115
119
|
const RESERVED_APPLET_PACKAGES = /* @__PURE__ */ new Set([
|
|
120
|
+
"@fontsource-variable/geist-mono",
|
|
116
121
|
"@fontsource-variable/inter",
|
|
117
122
|
"@hitch42/applet",
|
|
118
123
|
"@orpc/contract",
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { i as readWorkspaceConfig, l as organizationInstanceUrl, s as DEFAULT_INSTANCE_URL } from "./workspace-DruAZPmV.js";
|
|
2
|
-
import { n as loadAppletSourceDefinition } from "./load-config-
|
|
2
|
+
import { n as loadAppletSourceDefinition } from "./load-config-DI-e1Ool.js";
|
|
3
3
|
import { z } from "zod";
|
|
4
4
|
import { existsSync } from "node:fs";
|
|
5
5
|
import { cp, mkdir, readFile, readdir, rm, symlink, writeFile } from "node:fs/promises";
|
|
@@ -74,6 +74,7 @@ const cliManifestSchema = z.object({
|
|
|
74
74
|
name: cliManifestValueSchema,
|
|
75
75
|
version: cliManifestValueSchema,
|
|
76
76
|
dependencies: z.object({
|
|
77
|
+
"@fontsource-variable/geist-mono": cliManifestValueSchema,
|
|
77
78
|
"@fontsource-variable/inter": cliManifestValueSchema,
|
|
78
79
|
"@orpc/contract": cliManifestValueSchema,
|
|
79
80
|
"@tiptap/core": cliManifestValueSchema,
|
|
@@ -158,6 +159,7 @@ function workspaceFile(cli) {
|
|
|
158
159
|
- applets/*
|
|
159
160
|
catalog:
|
|
160
161
|
"@hitch42/applet": npm:${cli.name}@${cli.version}
|
|
162
|
+
"@fontsource-variable/geist-mono": "${cli.dependencies["@fontsource-variable/geist-mono"]}"
|
|
161
163
|
"@fontsource-variable/inter": "${cli.dependencies["@fontsource-variable/inter"]}"
|
|
162
164
|
"@orpc/contract": "${cli.dependencies["@orpc/contract"]}"
|
|
163
165
|
"@orpc/server": "${cli.peerDependencies["@orpc/server"]}"
|
|
@@ -381,6 +383,7 @@ function appletPackage(definition, options) {
|
|
|
381
383
|
zod: "catalog:",
|
|
382
384
|
...options.hasServer ? { "@orpc/server": "catalog:" } : {},
|
|
383
385
|
...options.hasClient ? {
|
|
386
|
+
"@fontsource-variable/geist-mono": "catalog:",
|
|
384
387
|
"@fontsource-variable/inter": "catalog:",
|
|
385
388
|
"@tanstack/react-query": "catalog:",
|
|
386
389
|
"@tanstack/react-router": "catalog:",
|
package/dist/react.d.ts
CHANGED
|
@@ -29,9 +29,10 @@ type MarkdownEditorProps = {
|
|
|
29
29
|
minLength?: number;
|
|
30
30
|
maxLength?: number;
|
|
31
31
|
disabled?: boolean;
|
|
32
|
+
autoFocus?: boolean;
|
|
32
33
|
className?: string;
|
|
33
34
|
onUploadError?: (error: unknown, file: File) => void;
|
|
34
35
|
};
|
|
35
|
-
declare function MarkdownEditor({ value, onChange, files, id, placeholder, required, minLength, maxLength, disabled, className, onUploadError }: MarkdownEditorProps): ReactElement;
|
|
36
|
+
declare function MarkdownEditor({ value, onChange, files, id, placeholder, required, minLength, maxLength, disabled, autoFocus, className, onUploadError }: MarkdownEditorProps): ReactElement;
|
|
36
37
|
//#endregion
|
|
37
38
|
export { Markdown, MarkdownEditor, type MarkdownEditorFiles, type MarkdownEditorProps, type MarkdownFiles, type MarkdownProps };
|