@hitch42/applet 0.1.0-beta.10
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/LICENSE +21 -0
- package/dist/_internal/client.d.ts +7 -0
- package/dist/_internal/client.js +169 -0
- package/dist/_internal/server.d.ts +92 -0
- package/dist/_internal/server.js +181 -0
- package/dist/applet.d.ts +1 -0
- package/dist/applet.js +184 -0
- package/dist/batch-Qa4B4-Yp.d.ts +30 -0
- package/dist/build-BlmLiKro.js +90 -0
- package/dist/build-CcT-wNN9.js +2 -0
- package/dist/ci-0Q2mUh53.js +68 -0
- package/dist/client.d.ts +48 -0
- package/dist/client.js +38 -0
- package/dist/contract-QUvEGiRI.d.ts +23 -0
- package/dist/deploy-BbL3GObV.js +2579 -0
- package/dist/email-DBTVhNB_.js +62 -0
- package/dist/generate-XB-72Fzj.js +537 -0
- package/dist/generate-wIN3IYqL.js +2 -0
- package/dist/index.d.ts +185 -0
- package/dist/index.js +251 -0
- package/dist/init-DwsXRUk-.js +244 -0
- package/dist/lazy-client-x0DCI98S.js +64 -0
- package/dist/load-config-OKZU3UKn.js +27 -0
- package/dist/login-BBO74hPC.js +12 -0
- package/dist/logs-XvK6Zs5Y.js +183 -0
- package/dist/manifest-4ZAc6HUk.js +191 -0
- package/dist/manifest-I-9s8R36.d.ts +88 -0
- package/dist/me-BW7Paary.js +32 -0
- package/dist/project-B0qNXnFu.js +536 -0
- package/dist/prompt-ChS-grYO.js +29 -0
- package/dist/query-cache-CXmAyLv3.js +82 -0
- package/dist/react.d.ts +37 -0
- package/dist/react.js +515 -0
- package/dist/schedules-BkWZsbSs.js +42 -0
- package/dist/server.d.ts +46 -0
- package/dist/server.js +104 -0
- package/dist/telephony-protocol-D-nf3Gca.d.ts +76 -0
- package/dist/telephony.d.ts +77 -0
- package/dist/telephony.js +607 -0
- package/dist/upload-DKZzz5kW.d.ts +112 -0
- package/dist/upload-DRbVhuDm.js +114 -0
- package/dist/variables-0tjnAeut.js +108 -0
- package/dist/vite.d.ts +63 -0
- package/dist/vite.js +816 -0
- package/dist/workflow-CTo2kZF1.js +51 -0
- package/dist/workflow-DurM6Fwx.d.ts +28 -0
- package/dist/workflow-engine-MogejNfF.js +117 -0
- package/dist/workspace-DruAZPmV.js +390 -0
- package/package.json +112 -0
- package/scaffold/.agents/skills/hitch-applets/SKILL.md +163 -0
- package/scaffold/.agents/skills/hitch-applets/references/client.md +73 -0
- package/scaffold/.agents/skills/hitch-applets/references/email-tracking.md +49 -0
- package/scaffold/.agents/skills/hitch-applets/references/files.md +109 -0
- package/scaffold/.agents/skills/hitch-applets/references/manifest.md +198 -0
- package/scaffold/.agents/skills/hitch-applets/references/markdown.md +37 -0
- package/scaffold/.agents/skills/hitch-applets/references/performance.md +74 -0
- package/scaffold/.agents/skills/hitch-applets/references/records.md +176 -0
- package/scaffold/.agents/skills/hitch-applets/references/schedules.md +91 -0
- package/scaffold/.agents/skills/hitch-applets/references/server.md +95 -0
- package/scaffold/.agents/skills/hitch-applets/references/workflows.md +81 -0
- package/scaffold/.agents/skills/hitch-cli/SKILL.md +129 -0
- package/scaffold/.agents/skills/hitch-data/SKILL.md +52 -0
- package/scaffold/.agents/skills/hitch-data/references/attributes.md +127 -0
- package/scaffold/.agents/skills/hitch-data/references/limits.md +64 -0
- package/scaffold/.agents/skills/hitch-theory/SKILL.md +151 -0
- package/scaffold/.agents/skills/react-best-practices/SKILL.md +127 -0
- package/scaffold/.agents/skills/react-best-practices/rules/advanced-effect-event-deps.md +50 -0
- package/scaffold/.agents/skills/react-best-practices/rules/advanced-event-handler-refs.md +55 -0
- package/scaffold/.agents/skills/react-best-practices/rules/advanced-init-once.md +42 -0
- package/scaffold/.agents/skills/react-best-practices/rules/advanced-use-latest.md +39 -0
- package/scaffold/.agents/skills/react-best-practices/rules/async-cheap-condition-before-await.md +37 -0
- package/scaffold/.agents/skills/react-best-practices/rules/async-defer-await.md +82 -0
- package/scaffold/.agents/skills/react-best-practices/rules/async-dependencies.md +48 -0
- package/scaffold/.agents/skills/react-best-practices/rules/async-parallel.md +24 -0
- package/scaffold/.agents/skills/react-best-practices/rules/bundle-analyzable-paths.md +42 -0
- package/scaffold/.agents/skills/react-best-practices/rules/bundle-barrel-imports.md +39 -0
- package/scaffold/.agents/skills/react-best-practices/rules/bundle-conditional.md +35 -0
- package/scaffold/.agents/skills/react-best-practices/rules/bundle-defer-third-party.md +46 -0
- package/scaffold/.agents/skills/react-best-practices/rules/bundle-dynamic-imports.md +38 -0
- package/scaffold/.agents/skills/react-best-practices/rules/bundle-preload.md +40 -0
- package/scaffold/.agents/skills/react-best-practices/rules/client-event-listeners.md +78 -0
- package/scaffold/.agents/skills/react-best-practices/rules/client-localstorage-schema.md +74 -0
- package/scaffold/.agents/skills/react-best-practices/rules/client-passive-event-listeners.md +48 -0
- package/scaffold/.agents/skills/react-best-practices/rules/js-batch-dom-css.md +110 -0
- package/scaffold/.agents/skills/react-best-practices/rules/js-cache-function-results.md +58 -0
- package/scaffold/.agents/skills/react-best-practices/rules/js-cache-property-access.md +28 -0
- package/scaffold/.agents/skills/react-best-practices/rules/js-cache-storage.md +56 -0
- package/scaffold/.agents/skills/react-best-practices/rules/js-combine-iterations.md +32 -0
- package/scaffold/.agents/skills/react-best-practices/rules/js-early-exit.md +50 -0
- package/scaffold/.agents/skills/react-best-practices/rules/js-flatmap-filter.md +51 -0
- package/scaffold/.agents/skills/react-best-practices/rules/js-hoist-regexp.md +45 -0
- package/scaffold/.agents/skills/react-best-practices/rules/js-index-maps.md +37 -0
- package/scaffold/.agents/skills/react-best-practices/rules/js-length-check-first.md +50 -0
- package/scaffold/.agents/skills/react-best-practices/rules/js-min-max-loop.md +82 -0
- package/scaffold/.agents/skills/react-best-practices/rules/js-request-idle-callback.md +104 -0
- package/scaffold/.agents/skills/react-best-practices/rules/js-set-map-lookups.md +24 -0
- package/scaffold/.agents/skills/react-best-practices/rules/js-tosorted-immutable.md +57 -0
- package/scaffold/.agents/skills/react-best-practices/rules/rendering-activity.md +26 -0
- package/scaffold/.agents/skills/react-best-practices/rules/rendering-animate-svg-wrapper.md +38 -0
- package/scaffold/.agents/skills/react-best-practices/rules/rendering-conditional-render.md +32 -0
- package/scaffold/.agents/skills/react-best-practices/rules/rendering-content-visibility.md +38 -0
- package/scaffold/.agents/skills/react-best-practices/rules/rendering-hoist-jsx.md +36 -0
- package/scaffold/.agents/skills/react-best-practices/rules/rendering-resource-hints.md +81 -0
- package/scaffold/.agents/skills/react-best-practices/rules/rendering-script-defer-async.md +36 -0
- package/scaffold/.agents/skills/react-best-practices/rules/rendering-svg-precision.md +28 -0
- package/scaffold/.agents/skills/react-best-practices/rules/rendering-usetransition-loading.md +43 -0
- package/scaffold/.agents/skills/react-best-practices/rules/rerender-defer-reads.md +39 -0
- package/scaffold/.agents/skills/react-best-practices/rules/rerender-dependencies.md +45 -0
- package/scaffold/.agents/skills/react-best-practices/rules/rerender-derived-state-no-effect.md +40 -0
- package/scaffold/.agents/skills/react-best-practices/rules/rerender-derived-state.md +29 -0
- package/scaffold/.agents/skills/react-best-practices/rules/rerender-functional-setstate.md +77 -0
- package/scaffold/.agents/skills/react-best-practices/rules/rerender-lazy-state-init.md +56 -0
- package/scaffold/.agents/skills/react-best-practices/rules/rerender-memo-with-default-value.md +36 -0
- package/scaffold/.agents/skills/react-best-practices/rules/rerender-memo.md +44 -0
- package/scaffold/.agents/skills/react-best-practices/rules/rerender-move-effect-to-event.md +45 -0
- package/scaffold/.agents/skills/react-best-practices/rules/rerender-no-inline-components.md +75 -0
- package/scaffold/.agents/skills/react-best-practices/rules/rerender-simple-expression-in-memo.md +35 -0
- package/scaffold/.agents/skills/react-best-practices/rules/rerender-split-combined-hooks.md +64 -0
- package/scaffold/.agents/skills/react-best-practices/rules/rerender-transitions.md +40 -0
- package/scaffold/.agents/skills/react-best-practices/rules/rerender-use-deferred-value.md +59 -0
- package/scaffold/.agents/skills/react-best-practices/rules/rerender-use-ref-transient-values.md +73 -0
- package/scaffold/.agents/skills/tanstack-query/SKILL.md +136 -0
- package/scaffold/.agents/skills/tanstack-query/references/compositions/automatic-invalidation-after-mutations.md +124 -0
- package/scaffold/.agents/skills/tanstack-query/references/compositions/broadcast-realtime-and-multi-tab-synchronization.md +150 -0
- package/scaffold/.agents/skills/tanstack-query/references/compositions/compose-query-with-tanstack-router-and-start.md +248 -0
- package/scaffold/.agents/skills/tanstack-query/references/compositions/enforce-query-best-practices-with-eslint.md +167 -0
- package/scaffold/.agents/skills/tanstack-query/references/compositions/persist-offline-and-restore-caches.md +181 -0
- package/scaffold/.agents/skills/tanstack-query/references/compositions/query-data-and-forms.md +156 -0
- package/scaffold/.agents/skills/tanstack-query/references/core/build-query-abstractions.md +130 -0
- package/scaffold/.agents/skills/tanstack-query/references/core/cancel-queries-and-consume-abort-signals.md +176 -0
- package/scaffold/.agents/skills/tanstack-query/references/core/concurrent-optimistic-updates.md +135 -0
- package/scaffold/.agents/skills/tanstack-query/references/core/coordinate-query-execution.md +188 -0
- package/scaffold/.agents/skills/tanstack-query/references/core/design-query-keys-and-options.md +182 -0
- package/scaffold/.agents/skills/tanstack-query/references/core/fetch-and-observe-queries.md +193 -0
- package/scaffold/.agents/skills/tanstack-query/references/core/implement-optimistic-updates-and-cache-writes.md +168 -0
- package/scaffold/.agents/skills/tanstack-query/references/core/paginate-and-build-infinite-queries.md +188 -0
- package/scaffold/.agents/skills/tanstack-query/references/core/seed-placeholder-select-and-transform-data.md +188 -0
- package/scaffold/.agents/skills/tanstack-query/references/core/selectors-and-derived-state.md +145 -0
- package/scaffold/.agents/skills/tanstack-query/references/core/tune-defaults-freshness-retries-and-refetching.md +172 -0
- package/scaffold/.agents/skills/tanstack-query/references/core/understand-query-internals-and-observers.md +104 -0
- package/scaffold/.agents/skills/tanstack-query/references/core/write-mutations-and-invalidate-related-queries.md +183 -0
- package/scaffold/.agents/skills/tanstack-query/references/framework/debug-with-devtools.md +169 -0
- package/scaffold/.agents/skills/tanstack-query/references/framework/handle-status-and-errors.md +119 -0
- package/scaffold/.agents/skills/tanstack-query/references/framework/shape-data-and-render-efficiently.md +184 -0
- package/scaffold/.agents/skills/tanstack-query/references/framework/use-framework-adapter-reactivity.md +185 -0
- package/scaffold/.agents/skills/tanstack-query/references/framework/use-suspense-and-error-boundaries.md +208 -0
- package/scaffold/.agents/skills/tanstack-query/references/lifecycle/migrate-major-versions-and-codemods.md +169 -0
- package/scaffold/.agents/skills/tanstack-query/references/lifecycle/prefetch-and-remove-request-waterfalls.md +228 -0
- package/scaffold/.agents/skills/tanstack-query/references/lifecycle/setup-query-client-and-providers.md +161 -0
- package/scaffold/.agents/skills/tanstack-query/references/lifecycle/ssr-hydration-and-streaming.md +209 -0
- package/scaffold/.agents/skills/tanstack-query/references/lifecycle/test-query-code.md +160 -0
- package/scaffold/.agents/skills/tanstack-router/SKILL.md +134 -0
- package/scaffold/.agents/skills/tanstack-router/references/compositions/router-query.md +412 -0
- package/scaffold/.agents/skills/tanstack-router/references/react-router.md +495 -0
- package/scaffold/.agents/skills/tanstack-router/references/router-core/auth-and-guards.md +495 -0
- package/scaffold/.agents/skills/tanstack-router/references/router-core/code-splitting.md +318 -0
- package/scaffold/.agents/skills/tanstack-router/references/router-core/data-loading.md +490 -0
- package/scaffold/.agents/skills/tanstack-router/references/router-core/index.md +158 -0
- package/scaffold/.agents/skills/tanstack-router/references/router-core/navigation.md +433 -0
- package/scaffold/.agents/skills/tanstack-router/references/router-core/not-found-and-errors.md +436 -0
- package/scaffold/.agents/skills/tanstack-router/references/router-core/path-params.md +383 -0
- package/scaffold/.agents/skills/tanstack-router/references/router-core/search-params.md +343 -0
- package/scaffold/.agents/skills/tanstack-router/references/router-core/ssr.md +462 -0
- package/scaffold/.agents/skills/tanstack-router/references/router-core/type-safety.md +493 -0
- package/scaffold/.agents/skills/tanstack-router/references/router-plugin.md +250 -0
- package/scaffold/.agents/skills/tanstack-router/references/virtual-file-routes.md +215 -0
- package/scaffold/.agents/skills/web-design-guidelines/SKILL.md +184 -0
- package/scaffold/.github/workflows/hitch.yml +15 -0
- package/scaffold/AGENTS.md +38 -0
- package/scaffold/applet/components.json +25 -0
- package/scaffold/applet/src/client/components/ui/alert.tsx +73 -0
- package/scaffold/applet/src/client/components/ui/avatar.tsx +100 -0
- package/scaffold/applet/src/client/components/ui/badge.tsx +55 -0
- package/scaffold/applet/src/client/components/ui/button.tsx +90 -0
- package/scaffold/applet/src/client/components/ui/card.tsx +85 -0
- package/scaffold/applet/src/client/components/ui/checkbox.tsx +35 -0
- package/scaffold/applet/src/client/components/ui/dialog.tsx +164 -0
- package/scaffold/applet/src/client/components/ui/dropdown-menu.tsx +235 -0
- package/scaffold/applet/src/client/components/ui/input-group.tsx +144 -0
- package/scaffold/applet/src/client/components/ui/input.tsx +22 -0
- package/scaffold/applet/src/client/components/ui/label.tsx +29 -0
- package/scaffold/applet/src/client/components/ui/popover.tsx +74 -0
- package/scaffold/applet/src/client/components/ui/select.tsx +243 -0
- package/scaffold/applet/src/client/components/ui/separator.tsx +25 -0
- package/scaffold/applet/src/client/components/ui/sheet.tsx +177 -0
- package/scaffold/applet/src/client/components/ui/skeleton.tsx +13 -0
- package/scaffold/applet/src/client/components/ui/spinner.tsx +17 -0
- package/scaffold/applet/src/client/components/ui/switch.tsx +41 -0
- package/scaffold/applet/src/client/components/ui/table.tsx +114 -0
- package/scaffold/applet/src/client/components/ui/tabs.tsx +78 -0
- package/scaffold/applet/src/client/components/ui/textarea.tsx +23 -0
- package/scaffold/applet/src/client/lib/utils.ts +1 -0
- package/scaffold/applet/src/client/styles/globals.css +136 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Hitch42 Pty Ltd
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import { PersistQueryClientOptions } from "@tanstack/react-query-persist-client";
|
|
2
|
+
import { AnyRouter } from "@tanstack/react-router";
|
|
3
|
+
//#region src/internal/client.d.ts
|
|
4
|
+
declare function appletQueryPersistence(appletCode: string): Promise<Omit<PersistQueryClientOptions, "queryClient"> | undefined>;
|
|
5
|
+
declare function mountApplet(router: AnyRouter, appletCode: string): void;
|
|
6
|
+
//#endregion
|
|
7
|
+
export { appletQueryPersistence, mountApplet };
|
|
@@ -0,0 +1,169 @@
|
|
|
1
|
+
import { i as openCacheDatabase, n as clearAppletQueryCaches, o as sweepExpiredQueryCaches, r as indexedDbPersister, t as cacheTabId } from "../query-cache-CXmAyLv3.js";
|
|
2
|
+
import { QueryClientProvider } from "@tanstack/react-query";
|
|
3
|
+
import { PersistQueryClientProvider } from "@tanstack/react-query-persist-client";
|
|
4
|
+
import { RouterProvider } from "@tanstack/react-router";
|
|
5
|
+
import { createElement, useEffect } from "react";
|
|
6
|
+
import { createRoot } from "react-dom/client";
|
|
7
|
+
import { RotateCcw } from "lucide-react";
|
|
8
|
+
import { jsx, jsxs } from "react/jsx-runtime";
|
|
9
|
+
//#region src/internal/error-page.tsx
|
|
10
|
+
const STYLES = `
|
|
11
|
+
.hitch-error {
|
|
12
|
+
position: relative;
|
|
13
|
+
display: flex;
|
|
14
|
+
min-height: 100dvh;
|
|
15
|
+
align-items: center;
|
|
16
|
+
justify-content: center;
|
|
17
|
+
overflow: hidden;
|
|
18
|
+
padding: 3rem 1.5rem;
|
|
19
|
+
background:
|
|
20
|
+
radial-gradient(ellipse 80% 50% at 50% -20%, color-mix(in oklch, var(--primary) 12%, transparent), transparent),
|
|
21
|
+
var(--background);
|
|
22
|
+
color: var(--foreground);
|
|
23
|
+
font-family: "Inter Variable", Inter, ui-sans-serif, system-ui, sans-serif;
|
|
24
|
+
}
|
|
25
|
+
.hitch-error__content { width: 100%; max-width: 28rem; text-align: center; }
|
|
26
|
+
.hitch-error__title { margin: 0 0 0.75rem; font-size: 1.875rem; font-weight: 600; letter-spacing: -0.025em; }
|
|
27
|
+
.hitch-error__text { margin: 0 0 2rem; color: var(--muted-foreground); line-height: 1.625; text-wrap: balance; }
|
|
28
|
+
.hitch-error__button {
|
|
29
|
+
display: inline-flex;
|
|
30
|
+
width: 100%;
|
|
31
|
+
align-items: center;
|
|
32
|
+
justify-content: center;
|
|
33
|
+
gap: 0.5rem;
|
|
34
|
+
border: 0;
|
|
35
|
+
border-radius: calc(var(--radius, 0.625rem) + 4px);
|
|
36
|
+
padding: 0.75rem 1.5rem;
|
|
37
|
+
background: var(--primary);
|
|
38
|
+
color: var(--primary-foreground);
|
|
39
|
+
font: inherit;
|
|
40
|
+
font-weight: 500;
|
|
41
|
+
cursor: pointer;
|
|
42
|
+
transition: background 150ms;
|
|
43
|
+
}
|
|
44
|
+
.hitch-error__button:hover { background: color-mix(in oklch, var(--primary) 90%, transparent); }
|
|
45
|
+
.hitch-error__button:focus-visible { outline: 2px solid var(--ring, var(--primary)); outline-offset: 2px; }
|
|
46
|
+
.hitch-error__hint { margin: 1rem 0 0; color: var(--muted-foreground); font-size: 0.875rem; }
|
|
47
|
+
.hitch-error__details { margin-top: 1.5rem; color: var(--muted-foreground); font-size: 0.875rem; text-align: left; }
|
|
48
|
+
.hitch-error__details summary { cursor: pointer; text-align: center; }
|
|
49
|
+
.hitch-error__details pre {
|
|
50
|
+
max-height: 12rem;
|
|
51
|
+
margin: 0.75rem 0 0;
|
|
52
|
+
padding: 1rem;
|
|
53
|
+
overflow: auto;
|
|
54
|
+
border: 1px solid var(--border);
|
|
55
|
+
border-radius: var(--radius, 0.625rem);
|
|
56
|
+
font: 0.75rem/1.5 ui-monospace, monospace;
|
|
57
|
+
white-space: pre;
|
|
58
|
+
}
|
|
59
|
+
`;
|
|
60
|
+
function AppletErrorPage({ error, onReload }) {
|
|
61
|
+
useEffect(() => {
|
|
62
|
+
console.error("The applet failed to render.", error);
|
|
63
|
+
}, [error]);
|
|
64
|
+
return /* @__PURE__ */ jsxs("div", {
|
|
65
|
+
className: "hitch-error",
|
|
66
|
+
role: "alert",
|
|
67
|
+
children: [/* @__PURE__ */ jsx("style", { children: STYLES }), /* @__PURE__ */ jsxs("div", {
|
|
68
|
+
className: "hitch-error__content",
|
|
69
|
+
children: [
|
|
70
|
+
/* @__PURE__ */ jsx("h1", {
|
|
71
|
+
className: "hitch-error__title",
|
|
72
|
+
children: "We hit a snag"
|
|
73
|
+
}),
|
|
74
|
+
/* @__PURE__ */ jsx("p", {
|
|
75
|
+
className: "hitch-error__text",
|
|
76
|
+
children: "This applet ran into an unexpected error. Reload to try again."
|
|
77
|
+
}),
|
|
78
|
+
/* @__PURE__ */ jsxs("button", {
|
|
79
|
+
type: "button",
|
|
80
|
+
className: "hitch-error__button",
|
|
81
|
+
onClick: onReload,
|
|
82
|
+
children: [/* @__PURE__ */ jsx(RotateCcw, {
|
|
83
|
+
size: 16,
|
|
84
|
+
"aria-hidden": true
|
|
85
|
+
}), "Reload applet"]
|
|
86
|
+
}),
|
|
87
|
+
/* @__PURE__ */ jsx("p", {
|
|
88
|
+
className: "hitch-error__hint",
|
|
89
|
+
children: "If this keeps happening, let your admin know."
|
|
90
|
+
}),
|
|
91
|
+
import.meta.env.DEV && /* @__PURE__ */ jsxs("details", {
|
|
92
|
+
className: "hitch-error__details",
|
|
93
|
+
children: [/* @__PURE__ */ jsx("summary", { children: "Error details" }), /* @__PURE__ */ jsx("pre", { children: error instanceof Error ? error.stack ?? error.message : String(error) })]
|
|
94
|
+
})
|
|
95
|
+
]
|
|
96
|
+
})]
|
|
97
|
+
});
|
|
98
|
+
}
|
|
99
|
+
//#endregion
|
|
100
|
+
//#region src/internal/client.ts
|
|
101
|
+
const CACHE_MAX_AGE = 3e5;
|
|
102
|
+
const CACHE_SCOPE_PATTERN = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;
|
|
103
|
+
async function appletQueryPersistence(appletCode) {
|
|
104
|
+
const contextPromise = window.__hitchCacheContext;
|
|
105
|
+
if (!contextPromise) return void 0;
|
|
106
|
+
const databaseReady = openCacheDatabase().then(() => true, (error) => {
|
|
107
|
+
console.error("Could not open the applet query cache.", error);
|
|
108
|
+
return false;
|
|
109
|
+
});
|
|
110
|
+
let context;
|
|
111
|
+
try {
|
|
112
|
+
context = await contextPromise;
|
|
113
|
+
} catch (error) {
|
|
114
|
+
console.error("Could not load the applet cache context.", error);
|
|
115
|
+
return;
|
|
116
|
+
}
|
|
117
|
+
const cacheScope = typeof context === "object" && context !== null && "cacheScope" in context && typeof context.cacheScope === "string" ? context.cacheScope.trim() : void 0;
|
|
118
|
+
const cacheBuster = typeof context === "object" && context !== null && "cacheBuster" in context && typeof context.cacheBuster === "string" ? context.cacheBuster.trim() : void 0;
|
|
119
|
+
if (!cacheScope || !CACHE_SCOPE_PATTERN.test(cacheScope) || !cacheBuster || !CACHE_SCOPE_PATTERN.test(cacheBuster)) return;
|
|
120
|
+
if (!await databaseReady) return void 0;
|
|
121
|
+
try {
|
|
122
|
+
return {
|
|
123
|
+
persister: indexedDbPersister(`${appletCode}:${cacheScope}:${cacheTabId()}`),
|
|
124
|
+
maxAge: CACHE_MAX_AGE,
|
|
125
|
+
buster: cacheBuster,
|
|
126
|
+
dehydrateOptions: { shouldDehydrateMutation: () => false }
|
|
127
|
+
};
|
|
128
|
+
} catch (error) {
|
|
129
|
+
console.error("Could not access applet query cache storage.", error);
|
|
130
|
+
return;
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
function mountApplet(router, appletCode) {
|
|
134
|
+
const queryClient = router.options.context.queryClient;
|
|
135
|
+
if (!queryClient) throw new Error("getRouter must provide a QueryClient via createRouter({ context: { queryClient } }).");
|
|
136
|
+
const root = document.getElementById("root");
|
|
137
|
+
if (root === null) throw new Error("Missing #root element in index.html.");
|
|
138
|
+
router.options.defaultErrorComponent ??= ({ error }) => createElement(AppletErrorPage, {
|
|
139
|
+
error,
|
|
140
|
+
onReload: () => {
|
|
141
|
+
queryClient.clear();
|
|
142
|
+
clearAppletQueryCaches(appletCode).catch((error) => console.error("Could not clear the applet query cache.", error)).finally(() => window.location.reload());
|
|
143
|
+
}
|
|
144
|
+
});
|
|
145
|
+
const applet = createElement(RouterProvider, { router });
|
|
146
|
+
const sweepWhenIdle = () => {
|
|
147
|
+
const sweep = () => {
|
|
148
|
+
sweepExpiredQueryCaches(CACHE_MAX_AGE).catch((error) => console.error("Could not clear expired applet query caches.", error));
|
|
149
|
+
};
|
|
150
|
+
if ("requestIdleCallback" in window) requestIdleCallback(sweep);
|
|
151
|
+
else setTimeout(sweep, 1e3);
|
|
152
|
+
};
|
|
153
|
+
appletQueryPersistence(appletCode).then((persistence) => {
|
|
154
|
+
createRoot(root).render(persistence ? createElement(PersistQueryClientProvider, {
|
|
155
|
+
client: queryClient,
|
|
156
|
+
persistOptions: persistence,
|
|
157
|
+
onSuccess: sweepWhenIdle,
|
|
158
|
+
onError: () => {
|
|
159
|
+
console.error("Could not restore the applet query cache.");
|
|
160
|
+
sweepWhenIdle();
|
|
161
|
+
}
|
|
162
|
+
}, applet) : createElement(QueryClientProvider, { client: queryClient }, applet));
|
|
163
|
+
}).catch((error) => {
|
|
164
|
+
console.error("Could not initialize the applet query cache.", error);
|
|
165
|
+
createRoot(root).render(createElement(QueryClientProvider, { client: queryClient }, applet));
|
|
166
|
+
});
|
|
167
|
+
}
|
|
168
|
+
//#endregion
|
|
169
|
+
export { appletQueryPersistence, mountApplet };
|
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
import { t as AnyWorkflowDefinition } from "../workflow-DurM6Fwx.js";
|
|
2
|
+
import { d as listEmailTrackersInputSchema, i as createEmailPixelInputSchema, p as markEmailTrackerSentBodySchema, t as TelephonyMessageReceivedEvent } from "../telephony-protocol-D-nf3Gca.js";
|
|
3
|
+
import { z } from "zod";
|
|
4
|
+
//#region src/server/entry.d.ts
|
|
5
|
+
declare function createWorkerEntry(server: {
|
|
6
|
+
router: object;
|
|
7
|
+
workflows?: Record<string, AnyWorkflowDefinition>;
|
|
8
|
+
telephony?: {
|
|
9
|
+
onMessageReceived?: (event: TelephonyMessageReceivedEvent) => void | Promise<void>;
|
|
10
|
+
};
|
|
11
|
+
}, options: {
|
|
12
|
+
code: string;
|
|
13
|
+
}): {
|
|
14
|
+
fetch(request: Request, env?: unknown, ctx?: unknown): Promise<Response>;
|
|
15
|
+
};
|
|
16
|
+
//#endregion
|
|
17
|
+
//#region src/server/workflow-protocol.d.ts
|
|
18
|
+
type StepJournalEntry = {
|
|
19
|
+
kind: "step";
|
|
20
|
+
id: string;
|
|
21
|
+
name: string;
|
|
22
|
+
result: unknown;
|
|
23
|
+
};
|
|
24
|
+
type SleepJournalEntry = {
|
|
25
|
+
kind: "sleep";
|
|
26
|
+
id: string;
|
|
27
|
+
name: string;
|
|
28
|
+
until: number;
|
|
29
|
+
};
|
|
30
|
+
type AttemptJournalEntry = {
|
|
31
|
+
kind: "attempt";
|
|
32
|
+
id: string;
|
|
33
|
+
name: string;
|
|
34
|
+
error: string;
|
|
35
|
+
};
|
|
36
|
+
type FailedJournalEntry = {
|
|
37
|
+
kind: "failed";
|
|
38
|
+
id: string;
|
|
39
|
+
name: string;
|
|
40
|
+
error: string;
|
|
41
|
+
};
|
|
42
|
+
declare const journalEntrySchema: z.ZodType<StepJournalEntry | SleepJournalEntry | AttemptJournalEntry | FailedJournalEntry>;
|
|
43
|
+
type JournalEntry = z.infer<typeof journalEntrySchema>;
|
|
44
|
+
declare const workflowInvocationRequestSchema: z.ZodType<{
|
|
45
|
+
payload: unknown;
|
|
46
|
+
journal: JournalEntry[];
|
|
47
|
+
}>;
|
|
48
|
+
type WorkflowInvocationRequest = z.infer<typeof workflowInvocationRequestSchema>;
|
|
49
|
+
type StepOutcome = {
|
|
50
|
+
kind: "step";
|
|
51
|
+
id: string;
|
|
52
|
+
name: string;
|
|
53
|
+
result: unknown;
|
|
54
|
+
};
|
|
55
|
+
type SleepOutcome = {
|
|
56
|
+
kind: "sleep";
|
|
57
|
+
id: string;
|
|
58
|
+
name: string;
|
|
59
|
+
until: number;
|
|
60
|
+
};
|
|
61
|
+
type StepErrorOutcome = {
|
|
62
|
+
kind: "step_error";
|
|
63
|
+
id: string;
|
|
64
|
+
name: string;
|
|
65
|
+
message: string;
|
|
66
|
+
retries: {
|
|
67
|
+
limit: number;
|
|
68
|
+
delayMs: number;
|
|
69
|
+
backoff: "constant" | "linear" | "exponential";
|
|
70
|
+
};
|
|
71
|
+
};
|
|
72
|
+
type DoneOutcome = {
|
|
73
|
+
kind: "done";
|
|
74
|
+
result: unknown;
|
|
75
|
+
};
|
|
76
|
+
type ErrorOutcome = {
|
|
77
|
+
kind: "error";
|
|
78
|
+
message: string;
|
|
79
|
+
};
|
|
80
|
+
declare const workflowOutcomeSchema: z.ZodType<StepOutcome | SleepOutcome | StepErrorOutcome | DoneOutcome | ErrorOutcome>;
|
|
81
|
+
type WorkflowOutcome = z.infer<typeof workflowOutcomeSchema>;
|
|
82
|
+
//#endregion
|
|
83
|
+
//#region src/server/workflow-engine.d.ts
|
|
84
|
+
type Engine = {
|
|
85
|
+
invoke<T>(name: string, fn: () => Promise<T>): Promise<T>;
|
|
86
|
+
sleepUntil(name: string, until: Date): Promise<void>;
|
|
87
|
+
sleep(name: string, milliseconds: number): Promise<void>;
|
|
88
|
+
};
|
|
89
|
+
declare class WorkflowFailedError extends Error {}
|
|
90
|
+
declare function runWorkflowJournal(engine: Engine, invoke: (journal: JournalEntry[]) => Promise<WorkflowOutcome>): Promise<unknown>;
|
|
91
|
+
//#endregion
|
|
92
|
+
export { type Engine, type JournalEntry, WorkflowFailedError, type WorkflowInvocationRequest, type WorkflowOutcome, createEmailPixelInputSchema, createWorkerEntry, journalEntrySchema, listEmailTrackersInputSchema, markEmailTrackerSentBodySchema, runWorkflowJournal, workflowInvocationRequestSchema, workflowOutcomeSchema };
|
|
@@ -0,0 +1,181 @@
|
|
|
1
|
+
import { c as listEmailTrackersInputSchema, t as createEmailPixelInputSchema, u as markEmailTrackerSentBodySchema } from "../email-DBTVhNB_.js";
|
|
2
|
+
import { a as workflowOutcomeSchema, c as HITCH_SESSION_HEADER, i as workflowInvocationRequestSchema, l as HITCH_USER_HEADER, n as runWorkflowJournal, o as HITCH_APPLET_HEADER, r as journalEntrySchema, s as HITCH_APPLET_TOKEN_HEADER, t as WorkflowFailedError } from "../workflow-engine-MogejNfF.js";
|
|
3
|
+
import { o as runWithRequestContext, r as toMilliseconds, t as MAX_DURATION_MS } from "../workflow-CTo2kZF1.js";
|
|
4
|
+
import { z } from "zod";
|
|
5
|
+
import { RPCHandler } from "@orpc/server/fetch";
|
|
6
|
+
//#region src/server/telephony-protocol.ts
|
|
7
|
+
const telephonyMessageReceivedEventSchema = z.object({
|
|
8
|
+
eventId: z.string(),
|
|
9
|
+
type: z.literal("message.received"),
|
|
10
|
+
messageId: z.string(),
|
|
11
|
+
numberId: z.string(),
|
|
12
|
+
occurredAt: z.iso.datetime()
|
|
13
|
+
});
|
|
14
|
+
//#endregion
|
|
15
|
+
//#region src/server/workflow-run.ts
|
|
16
|
+
const MAX_RESULT_SIZE = 1048576;
|
|
17
|
+
function errorMessage(error) {
|
|
18
|
+
return (error instanceof Error ? error.message : String(error)).slice(0, 2048);
|
|
19
|
+
}
|
|
20
|
+
function outcomeTooLarge(outcome) {
|
|
21
|
+
return new TextEncoder().encode(JSON.stringify(outcome)).byteLength > MAX_RESULT_SIZE;
|
|
22
|
+
}
|
|
23
|
+
async function runWorkflowInvocation(definition, request) {
|
|
24
|
+
const occurrences = /* @__PURE__ */ new Map();
|
|
25
|
+
const never = new Promise(() => void 0);
|
|
26
|
+
let claimed = false;
|
|
27
|
+
let resolveRecorded = () => void 0;
|
|
28
|
+
const recordedPromise = new Promise((resolve) => {
|
|
29
|
+
resolveRecorded = resolve;
|
|
30
|
+
});
|
|
31
|
+
const nextId = (name) => {
|
|
32
|
+
const occurrence = (occurrences.get(name) ?? 0) + 1;
|
|
33
|
+
occurrences.set(name, occurrence);
|
|
34
|
+
return `${name}#${occurrence}`;
|
|
35
|
+
};
|
|
36
|
+
const record = (outcome) => {
|
|
37
|
+
resolveRecorded(outcome);
|
|
38
|
+
return never;
|
|
39
|
+
};
|
|
40
|
+
const runPromise = definition.run({
|
|
41
|
+
async do(name, optionsOrFn, possibleFn) {
|
|
42
|
+
const id = nextId(name);
|
|
43
|
+
const journaled = request.journal.find((entry) => entry.kind === "step" && entry.id === id);
|
|
44
|
+
if (journaled?.kind === "step") return journaled.result;
|
|
45
|
+
const failed = request.journal.find((entry) => entry.kind === "failed" && entry.id === id);
|
|
46
|
+
if (failed?.kind === "failed") throw new Error(failed.error);
|
|
47
|
+
if (claimed) return never;
|
|
48
|
+
claimed = true;
|
|
49
|
+
const options = typeof optionsOrFn === "function" ? void 0 : optionsOrFn;
|
|
50
|
+
const fn = typeof optionsOrFn === "function" ? optionsOrFn : possibleFn;
|
|
51
|
+
const retries = options?.retries ? {
|
|
52
|
+
limit: options.retries.limit,
|
|
53
|
+
delayMs: toMilliseconds(options.retries.delay),
|
|
54
|
+
backoff: options.retries.backoff ?? "constant"
|
|
55
|
+
} : {
|
|
56
|
+
limit: 0,
|
|
57
|
+
delayMs: 0,
|
|
58
|
+
backoff: "constant"
|
|
59
|
+
};
|
|
60
|
+
if (retries.delayMs * (retries.backoff === "exponential" ? 2 ** (retries.limit - 1) : retries.backoff === "linear" ? retries.limit : 1) > MAX_DURATION_MS) throw new Error("Retry delay grows beyond 365 days.");
|
|
61
|
+
try {
|
|
62
|
+
const outcome = {
|
|
63
|
+
kind: "step",
|
|
64
|
+
id,
|
|
65
|
+
name,
|
|
66
|
+
result: await fn()
|
|
67
|
+
};
|
|
68
|
+
return record(outcomeTooLarge(outcome) ? {
|
|
69
|
+
kind: "error",
|
|
70
|
+
message: `Step "${name}" result exceeds 1 MiB.`
|
|
71
|
+
} : outcome);
|
|
72
|
+
} catch (error) {
|
|
73
|
+
return record({
|
|
74
|
+
kind: "step_error",
|
|
75
|
+
id,
|
|
76
|
+
name,
|
|
77
|
+
message: errorMessage(error),
|
|
78
|
+
retries
|
|
79
|
+
});
|
|
80
|
+
}
|
|
81
|
+
},
|
|
82
|
+
async sleep(name, duration) {
|
|
83
|
+
const id = nextId(name);
|
|
84
|
+
if (request.journal.find((entry) => entry.kind === "sleep" && entry.id === id) !== void 0) return;
|
|
85
|
+
if (claimed) return never;
|
|
86
|
+
claimed = true;
|
|
87
|
+
return record({
|
|
88
|
+
kind: "sleep",
|
|
89
|
+
id,
|
|
90
|
+
name,
|
|
91
|
+
until: Date.now() + toMilliseconds(duration)
|
|
92
|
+
});
|
|
93
|
+
}
|
|
94
|
+
}, request.payload).then((result) => {
|
|
95
|
+
const outcome = {
|
|
96
|
+
kind: "done",
|
|
97
|
+
result
|
|
98
|
+
};
|
|
99
|
+
return outcomeTooLarge(outcome) ? {
|
|
100
|
+
kind: "error",
|
|
101
|
+
message: "Workflow result exceeds 1 MiB."
|
|
102
|
+
} : outcome;
|
|
103
|
+
}, (error) => ({
|
|
104
|
+
kind: "error",
|
|
105
|
+
message: errorMessage(error)
|
|
106
|
+
}));
|
|
107
|
+
return Promise.race([runPromise, recordedPromise]);
|
|
108
|
+
}
|
|
109
|
+
//#endregion
|
|
110
|
+
//#region src/server/entry.ts
|
|
111
|
+
const WORKFLOW_PATH_PREFIX = "/api/__hitch/workflows/";
|
|
112
|
+
const SERVER_EXPORT_ERROR = "src/server/main.ts must default-export { router, workflows } — change \"export default router\" to \"export default { router }\".";
|
|
113
|
+
function jsonError(status, error) {
|
|
114
|
+
return Response.json({ error }, { status });
|
|
115
|
+
}
|
|
116
|
+
function createWorkerEntry(server, options) {
|
|
117
|
+
const candidate = server;
|
|
118
|
+
if (typeof candidate !== "object" || candidate === null || !("router" in candidate)) throw new Error(SERVER_EXPORT_ERROR);
|
|
119
|
+
const handler = new RPCHandler(server.router);
|
|
120
|
+
return { async fetch(request, env) {
|
|
121
|
+
const userId = request.headers.get(HITCH_USER_HEADER);
|
|
122
|
+
const sessionToken = request.headers.get(HITCH_SESSION_HEADER);
|
|
123
|
+
const appletId = request.headers.get(HITCH_APPLET_HEADER);
|
|
124
|
+
const token = request.headers.get(HITCH_APPLET_TOKEN_HEADER);
|
|
125
|
+
const identity = userId !== null && sessionToken !== null ? {
|
|
126
|
+
kind: "user",
|
|
127
|
+
userId,
|
|
128
|
+
sessionToken
|
|
129
|
+
} : appletId !== null && token !== null ? {
|
|
130
|
+
kind: "applet",
|
|
131
|
+
appletId,
|
|
132
|
+
token
|
|
133
|
+
} : void 0;
|
|
134
|
+
if (identity === void 0) return jsonError(401, "missing_identity");
|
|
135
|
+
const bindings = typeof env === "object" && env !== null ? env : {};
|
|
136
|
+
if (typeof bindings.HITCH_API_URL !== "string") return jsonError(500, "missing_api_binding");
|
|
137
|
+
const service = typeof bindings.HITCH === "object" && bindings.HITCH !== null ? bindings.HITCH : void 0;
|
|
138
|
+
const apiFetch = typeof service?.fetch === "function" ? service.fetch.bind(bindings.HITCH) : globalThis.fetch.bind(globalThis);
|
|
139
|
+
return runWithRequestContext({
|
|
140
|
+
identity,
|
|
141
|
+
appletCode: options.code,
|
|
142
|
+
api: {
|
|
143
|
+
baseUrl: bindings.HITCH_API_URL,
|
|
144
|
+
fetch: apiFetch
|
|
145
|
+
}
|
|
146
|
+
}, async () => {
|
|
147
|
+
const pathname = new URL(request.url).pathname;
|
|
148
|
+
if (pathname === "/api/__hitch/telephony/message-received" && request.method === "POST") {
|
|
149
|
+
if (identity.kind !== "applet") return jsonError(403, "applet_identity_required");
|
|
150
|
+
const parsed = await request.json().then((body) => telephonyMessageReceivedEventSchema.safeParse(body)).catch(() => void 0);
|
|
151
|
+
if (!parsed?.success) return jsonError(400, "malformed_request");
|
|
152
|
+
const onMessageReceived = server.telephony?.onMessageReceived;
|
|
153
|
+
if (!onMessageReceived) return jsonError(404, "no_telephony_handler");
|
|
154
|
+
try {
|
|
155
|
+
await onMessageReceived(parsed.data);
|
|
156
|
+
return Response.json({ ok: true });
|
|
157
|
+
} catch (error) {
|
|
158
|
+
return jsonError(500, error instanceof Error ? error.message : String(error));
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
if (pathname.startsWith(WORKFLOW_PATH_PREFIX)) {
|
|
162
|
+
const parsed = await request.json().then((body) => workflowInvocationRequestSchema.safeParse(body)).catch(() => void 0);
|
|
163
|
+
if (parsed === void 0 || !parsed.success) return jsonError(400, "malformed_request");
|
|
164
|
+
const code = decodeURIComponent(pathname.slice(23));
|
|
165
|
+
const workflows = server.workflows ?? {};
|
|
166
|
+
const definition = Object.hasOwn(workflows, code) ? workflows[code] : void 0;
|
|
167
|
+
return Response.json(definition === void 0 ? {
|
|
168
|
+
kind: "error",
|
|
169
|
+
message: `Unknown workflow "${code}".`
|
|
170
|
+
} : await runWorkflowInvocation(definition, parsed.data));
|
|
171
|
+
}
|
|
172
|
+
const result = await handler.handle(request, {
|
|
173
|
+
context: {},
|
|
174
|
+
prefix: "/api"
|
|
175
|
+
});
|
|
176
|
+
return result.matched ? result.response : new Response(null, { status: 404 });
|
|
177
|
+
});
|
|
178
|
+
} };
|
|
179
|
+
}
|
|
180
|
+
//#endregion
|
|
181
|
+
export { WorkflowFailedError, createEmailPixelInputSchema, createWorkerEntry, journalEntrySchema, listEmailTrackersInputSchema, markEmailTrackerSentBodySchema, runWorkflowJournal, workflowInvocationRequestSchema, workflowOutcomeSchema };
|
package/dist/applet.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {}
|
package/dist/applet.js
ADDED
|
@@ -0,0 +1,184 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import { parseArgs } from "node:util";
|
|
3
|
+
//#region bin/applet.ts
|
|
4
|
+
const usage = `Usage:
|
|
5
|
+
applet login [--no-browser]
|
|
6
|
+
applet init <org> [--no-commit | --no-git] [--no-install]
|
|
7
|
+
applet bootstrap [--no-install]
|
|
8
|
+
applet new <code> [--client-only | --server-only] [--no-install]
|
|
9
|
+
applet generate
|
|
10
|
+
applet build
|
|
11
|
+
applet deploy
|
|
12
|
+
applet logs [code] [--since <duration>] [--limit <count>]
|
|
13
|
+
[--search <text>] [--level <level>] [--filter <json>] [--run <id>] [--live]
|
|
14
|
+
applet variables set <KEY> [value] [--secret] [-y | --yes]
|
|
15
|
+
applet variables list
|
|
16
|
+
applet variables delete <KEY> [-y | --yes]
|
|
17
|
+
applet schedules run <code> [-y | --yes]
|
|
18
|
+
|
|
19
|
+
Login options:
|
|
20
|
+
--no-browser Print the sign-in URL without opening a browser.
|
|
21
|
+
|
|
22
|
+
Init options:
|
|
23
|
+
--no-commit Do not create the initial commit
|
|
24
|
+
--no-git Do not create a git repository
|
|
25
|
+
--no-install Do not run pnpm install
|
|
26
|
+
|
|
27
|
+
New options:
|
|
28
|
+
--client-only Create only client source
|
|
29
|
+
--server-only Create only server source
|
|
30
|
+
--no-install Do not run pnpm install
|
|
31
|
+
|
|
32
|
+
Bootstrap options:
|
|
33
|
+
--no-install Do not run pnpm install
|
|
34
|
+
|
|
35
|
+
Schema changesets:
|
|
36
|
+
Set requiresChangeset in applet.manifest.ts to generate, build, and deploy
|
|
37
|
+
against a pending changeset. The release goes live when the changeset
|
|
38
|
+
applies in Hitch. After it applies, the field uses the live schema.
|
|
39
|
+
|
|
40
|
+
Run applet deploy in the workspace root to deploy every applet. In GitHub
|
|
41
|
+
Actions it skips an applet when neither its folder nor any file outside
|
|
42
|
+
applets/ changed since its current CI release.
|
|
43
|
+
|
|
44
|
+
Logs options:
|
|
45
|
+
--since <duration> Show logs from this period. Default: 1h. Maximum: 7d.
|
|
46
|
+
--limit <count> Return up to this many logs. Default: 100. Maximum: 100.
|
|
47
|
+
--search <text> Search log text.
|
|
48
|
+
--level <level> Show this level and higher levels.
|
|
49
|
+
Valid levels: debug, log, info, warn, error.
|
|
50
|
+
The log level is an alias for info.
|
|
51
|
+
--run <id> Show workflow logs for one run.
|
|
52
|
+
--filter <json> Filter log fields with a Hitch JSON filter object.
|
|
53
|
+
--live Poll for new logs every two seconds.
|
|
54
|
+
|
|
55
|
+
Variables options:
|
|
56
|
+
--secret Store the value as a secret.
|
|
57
|
+
-y, --yes Skip the live applet confirmation.
|
|
58
|
+
|
|
59
|
+
Schedules options:
|
|
60
|
+
-y, --yes Skip the schedule confirmation.
|
|
61
|
+
|
|
62
|
+
Login: applet login selects the organization from hitch.config.ts and shares
|
|
63
|
+
credentials with hitch login.
|
|
64
|
+
CI: set HITCH_API_KEY (and HITCH_API_URL for a non-default instance).
|
|
65
|
+
GitHub Actions: generate, build, and deploy use the job's OIDC token instead of
|
|
66
|
+
a key. Grant the job id-token: write.`;
|
|
67
|
+
async function main() {
|
|
68
|
+
const { positionals, values } = parseArgs({
|
|
69
|
+
allowPositionals: true,
|
|
70
|
+
options: {
|
|
71
|
+
"client-only": { type: "boolean" },
|
|
72
|
+
filter: { type: "string" },
|
|
73
|
+
run: { type: "string" },
|
|
74
|
+
level: { type: "string" },
|
|
75
|
+
limit: { type: "string" },
|
|
76
|
+
live: { type: "boolean" },
|
|
77
|
+
"no-browser": { type: "boolean" },
|
|
78
|
+
"no-commit": { type: "boolean" },
|
|
79
|
+
"no-git": { type: "boolean" },
|
|
80
|
+
"no-install": { type: "boolean" },
|
|
81
|
+
secret: { type: "boolean" },
|
|
82
|
+
search: { type: "string" },
|
|
83
|
+
"server-only": { type: "boolean" },
|
|
84
|
+
since: { type: "string" },
|
|
85
|
+
yes: {
|
|
86
|
+
type: "boolean",
|
|
87
|
+
short: "y"
|
|
88
|
+
}
|
|
89
|
+
},
|
|
90
|
+
strict: true
|
|
91
|
+
});
|
|
92
|
+
if (positionals.length === 1 && positionals[0] === "login" && Object.keys(values).every((key) => key === "no-browser")) {
|
|
93
|
+
await (await import("./login-BBO74hPC.js")).runLogin({ noBrowser: values["no-browser"] });
|
|
94
|
+
return;
|
|
95
|
+
}
|
|
96
|
+
if (values["no-browser"] !== void 0) throw new Error(usage);
|
|
97
|
+
const noGitFlags = values["no-commit"] === void 0 && values["no-git"] === void 0;
|
|
98
|
+
const noVariableFlags = values.secret === void 0 && values.yes === void 0;
|
|
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
|
+
const noModeFlags = values["client-only"] === void 0 && values["server-only"] === void 0;
|
|
101
|
+
if (positionals.length === 1 && positionals[0] === "bootstrap" && noModeFlags && noGitFlags && noVariableFlags && noLogFlags) {
|
|
102
|
+
await (await import("./init-DwsXRUk-.js")).runBootstrap({ install: values["no-install"] !== true });
|
|
103
|
+
return;
|
|
104
|
+
}
|
|
105
|
+
if (positionals.length === 1 && positionals[0] === "generate" && values["no-install"] === void 0 && noModeFlags && noGitFlags && noVariableFlags && noLogFlags) {
|
|
106
|
+
await (await import("./generate-wIN3IYqL.js")).runGenerate({});
|
|
107
|
+
return;
|
|
108
|
+
}
|
|
109
|
+
if (positionals.length === 1 && positionals[0] === "build" && values["no-install"] === void 0 && noModeFlags && noGitFlags && noVariableFlags && noLogFlags) {
|
|
110
|
+
await (await import("./build-CcT-wNN9.js")).runBuild();
|
|
111
|
+
return;
|
|
112
|
+
}
|
|
113
|
+
if (positionals.length === 1 && positionals[0] === "deploy" && values["no-install"] === void 0 && noModeFlags && noGitFlags && noVariableFlags && noLogFlags) {
|
|
114
|
+
await (await import("./deploy-BbL3GObV.js")).runDeploy({});
|
|
115
|
+
return;
|
|
116
|
+
}
|
|
117
|
+
if (positionals.length === 2 && positionals[0] === "init" && noModeFlags && noVariableFlags && noLogFlags) {
|
|
118
|
+
await (await import("./init-DwsXRUk-.js")).runInit(positionals[1], {
|
|
119
|
+
commit: values["no-commit"] !== true,
|
|
120
|
+
git: values["no-git"] !== true,
|
|
121
|
+
install: values["no-install"] !== true
|
|
122
|
+
});
|
|
123
|
+
return;
|
|
124
|
+
}
|
|
125
|
+
if (positionals.length === 2 && positionals[0] === "new" && noGitFlags && noVariableFlags && noLogFlags) {
|
|
126
|
+
await (await import("./init-DwsXRUk-.js")).runNew({
|
|
127
|
+
code: positionals[1],
|
|
128
|
+
clientOnly: values["client-only"],
|
|
129
|
+
install: values["no-install"] !== true,
|
|
130
|
+
serverOnly: values["server-only"]
|
|
131
|
+
});
|
|
132
|
+
return;
|
|
133
|
+
}
|
|
134
|
+
if ((positionals.length === 1 || positionals.length === 2) && positionals[0] === "logs" && values["no-install"] === void 0 && noModeFlags && noGitFlags && noVariableFlags) {
|
|
135
|
+
await (await import("./logs-XvK6Zs5Y.js")).runLogs({
|
|
136
|
+
code: positionals[1],
|
|
137
|
+
filter: values.filter,
|
|
138
|
+
run: values.run,
|
|
139
|
+
level: values.level,
|
|
140
|
+
limit: values.limit,
|
|
141
|
+
live: values.live,
|
|
142
|
+
search: values.search,
|
|
143
|
+
since: values.since
|
|
144
|
+
});
|
|
145
|
+
return;
|
|
146
|
+
}
|
|
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-BkWZsbSs.js")).runSchedule({
|
|
149
|
+
code: positionals[2],
|
|
150
|
+
yes: values.yes
|
|
151
|
+
});
|
|
152
|
+
return;
|
|
153
|
+
}
|
|
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-0tjnAeut.js")).runVariablesSet({
|
|
156
|
+
key: positionals[2],
|
|
157
|
+
secret: values.secret,
|
|
158
|
+
value: positionals[3],
|
|
159
|
+
yes: values.yes
|
|
160
|
+
});
|
|
161
|
+
return;
|
|
162
|
+
}
|
|
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-0tjnAeut.js")).runVariablesList({});
|
|
165
|
+
return;
|
|
166
|
+
}
|
|
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-0tjnAeut.js")).runVariablesDelete({
|
|
169
|
+
key: positionals[2],
|
|
170
|
+
yes: values.yes
|
|
171
|
+
});
|
|
172
|
+
return;
|
|
173
|
+
}
|
|
174
|
+
throw new Error(usage);
|
|
175
|
+
}
|
|
176
|
+
try {
|
|
177
|
+
await main();
|
|
178
|
+
} catch (error) {
|
|
179
|
+
console.error(error instanceof Error ? error.message : error);
|
|
180
|
+
if (!(error instanceof Error) || error.message !== usage) console.error(`\n${usage}`);
|
|
181
|
+
process.exitCode = 1;
|
|
182
|
+
}
|
|
183
|
+
//#endregion
|
|
184
|
+
export {};
|