everyapp 0.2.2 → 0.3.0-rc.1
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/README.md +6 -77
- package/bin/everyapp.js +235 -0
- package/dist/access-F3GKBKAW.js +1 -0
- package/dist/activity-4MFMH5JP.js +12 -0
- package/dist/apps-63K2DGVT.js +9 -0
- package/dist/chunk-2UFJRKEE.js +4 -0
- package/dist/chunk-3AAHHUJC.js +11 -0
- package/dist/chunk-3Z53CH4F.js +6 -0
- package/dist/chunk-5ZTFC6DK.js +1 -0
- package/dist/chunk-6O3GJS5H.js +15 -0
- package/dist/chunk-74EST4VW.js +2 -0
- package/dist/chunk-7LG3F4FF.js +10 -0
- package/dist/chunk-AUDGOIHE.js +1 -0
- package/dist/chunk-BHMRY53V.js +2 -0
- package/dist/chunk-DQWOXSL3.js +32 -0
- package/dist/chunk-E3EPK27P.js +10 -0
- package/dist/chunk-E7EUXUVD.js +1 -0
- package/dist/chunk-ECLJ5IAL.js +126 -0
- package/dist/chunk-EQX4GKJ2.js +4 -0
- package/dist/chunk-EUNGJMJ6.js +20 -0
- package/dist/chunk-F6IH47GT.js +4 -0
- package/dist/chunk-G64S77GC.js +33 -0
- package/dist/chunk-GD2JZMD3.js +1 -0
- package/dist/chunk-GRFPP4UW.js +7 -0
- package/dist/chunk-IA534DGW.js +10 -0
- package/dist/chunk-IG26HYRR.js +45 -0
- package/dist/chunk-IZEOAOKL.js +6 -0
- package/dist/chunk-JYKRUS5C.js +1 -0
- package/dist/chunk-KMAOZRV4.js +18 -0
- package/dist/chunk-MC56CUQI.js +7 -0
- package/dist/chunk-MDORVBPD.js +1 -0
- package/dist/chunk-N4E5YE4X.js +5 -0
- package/dist/chunk-NJFWEYX7.js +1 -0
- package/dist/chunk-OEOVNJAN.js +1 -0
- package/dist/chunk-OVKVV6MK.js +2 -0
- package/dist/chunk-PL6EORDJ.js +15 -0
- package/dist/chunk-PMPIMHKG.js +6 -0
- package/dist/chunk-QZWSSWMP.js +22 -0
- package/dist/chunk-R4CGF622.js +2 -0
- package/dist/chunk-RFVMR32Y.js +1 -0
- package/dist/chunk-RQFHVU3Y.js +25 -0
- package/dist/chunk-SAT3PGZU.js +57 -0
- package/dist/chunk-SPPR6WCI.js +1 -0
- package/dist/chunk-TPWSGRNT.js +30 -0
- package/dist/chunk-VVQRET35.js +2 -0
- package/dist/chunk-VXJQGJ7Y.js +2 -0
- package/dist/chunk-WEM3WLOC.js +1 -0
- package/dist/chunk-Y3VIFPN5.js +1 -0
- package/dist/chunk-YJBYZWSP.js +22 -0
- package/dist/chunk-ZYL2ZHCF.js +98 -0
- package/dist/configure-2KMHM22T.js +8 -0
- package/dist/create-ELEJMZBS.js +22 -0
- package/dist/db-MZIAKGBN.js +9 -0
- package/dist/delete-H47KPJSB.js +3 -0
- package/dist/deploy-HGFJLLUO.js +1 -0
- package/dist/dev-62VA7UEM.js +86 -0
- package/dist/email-NNFD3VVB.js +10 -0
- package/dist/events-JDY76EG6.js +15 -0
- package/dist/groups-NQFXDZZP.js +8 -0
- package/dist/index.js +92 -1
- package/dist/install-JTZWRZIL.js +1 -0
- package/dist/login-P6LYQQWP.js +1 -0
- package/dist/mcp-NCFWEBMD.js +1 -0
- package/dist/provider-WVBI2VED.js +13 -0
- package/dist/release-6FYSPXXA.js +1 -0
- package/dist/restore-XBU7DOJV.js +3 -0
- package/dist/secret-ML5EXS3O.js +1 -0
- package/dist/setup-IEXCISLP.js +1 -0
- package/dist/status-OPLPKJ4U.js +4 -0
- package/dist/teardown-3JMMLK6O.js +22 -0
- package/dist/update-37ZDATLR.js +1 -0
- package/dist/workspace-DAFZVYQ2.js +21 -0
- package/package.json +30 -27
- package/skills/build-every-app/SKILL.md +199 -0
- package/skills/build-every-app/patterns.md +134 -0
- package/skills/everyapp/SKILL.md +292 -0
- package/skills/everyapp/mcp.md +336 -0
- package/skills/everyapp/security-review.md +61 -0
- package/skills/everyapp/setup/README.md +263 -0
- package/skills/everyapp/setup/access.md +178 -0
- package/skills/everyapp/setup/context.md +117 -0
- package/skills/everyapp/setup/dataforseo.md +287 -0
- package/skills/everyapp/setup/email.md +366 -0
- package/skills/everyapp/setup/gateway.md +243 -0
- package/skills/everyapp/setup/google.md +360 -0
- package/skills/everyapp/setup/microsoft-365.md +281 -0
- package/skills/everyapp/setup/openai.md +318 -0
- package/skills/everyapp/setup/openrouter.md +309 -0
- package/skills/everyapp/setup/providers.md +353 -0
- package/skills/everyapp/setup/remote-mcp.md +199 -0
- package/skills/everyapp/setup/slack.md +344 -0
- package/skills/everyapp/setup/workers-ai.md +138 -0
- package/bin/__everyapp_bash_complete.js +0 -12
- package/dist/bash-complete.js +0 -3
- package/dist/chunk-7BOQJFI5.js +0 -8
- package/dist/chunk-7YVJFS4A.js +0 -1
- package/dist/chunk-BIXKPCDH.js +0 -2
- package/dist/chunk-DLGPLHBH.js +0 -47
- package/dist/chunk-FD6K2YA7.js +0 -9
- package/dist/chunk-GAJEQYJH.js +0 -39
- package/dist/chunk-O2KDOP5R.js +0 -13
- package/dist/chunk-OI2MBGBG.js +0 -4
- package/dist/chunk-POSDLD3G.js +0 -8
- package/dist/chunk-RB5D2R45.js +0 -1
- package/dist/chunk-U4LIQ5VR.js +0 -1
- package/dist/chunk-VEYSNPDH.js +0 -3
- package/dist/chunk-VP6SKW44.js +0 -7
- package/dist/chunk-WO3NE7ZU.js +0 -7
- package/dist/chunk-XTO2VTPY.js +0 -6
- package/dist/chunk-YJ2DKIZS.js +0 -1
- package/dist/create-DYQ3NBWJ.js +0 -22
- package/dist/deploy-PYTCMDGV.js +0 -7
- package/dist/deploy-RMAHOA4Z.js +0 -55
- package/dist/dev-SAE237FS.js +0 -0
- package/dist/generateConfig-46Z3ERF3.js +0 -1
- package/dist/login-B6EF3SMX.js +0 -1
- package/dist/logout-XMKZBLNV.js +0 -1
- package/dist/remoteD1Shell-A67JMO3H.js +0 -6
- package/dist/setupLocal-TZJUW5ES.js +0 -6
- package/gateway/every-app-gateway-build.tar.gz +0 -0
package/README.md
CHANGED
|
@@ -1,82 +1,11 @@
|
|
|
1
1
|
# everyapp
|
|
2
2
|
|
|
3
|
-
CLI for [Every App](https://everyapp.
|
|
3
|
+
The CLI for [Every App](https://everyapp.com): deploy and run private web apps on your own Cloudflare account.
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
Nothing is published while we work from the repository (`.github/RELEASE.md`), so the CLI runs from a checkout of it: `pnpm install` once at the root, then `pnpm everyapp <command>` anywhere in the repository (never `npx everyapp`, which is npm's old 0.2 CLI). It builds itself the first time and again whenever its source, or the SDK, perimeter or toolbus it bundles, changed (`bin/everyapp.js`). Requires Node.js 22.18 or newer.
|
|
6
6
|
|
|
7
|
-
|
|
8
|
-
# Run the latest CLI directly with npx
|
|
9
|
-
npx -y everyapp@latest <command>
|
|
10
|
-
```
|
|
7
|
+
Every command but `dev` takes `--json` (NDJSON events on stdout; exit 0 done, 1 error, 2 action required) and `--help` lists its flags.
|
|
11
8
|
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
Deploy the Every App Gateway to your Cloudflare account:
|
|
17
|
-
|
|
18
|
-
```bash
|
|
19
|
-
npx -y everyapp@latest gateway deploy
|
|
20
|
-
```
|
|
21
|
-
|
|
22
|
-
### Create a new app
|
|
23
|
-
|
|
24
|
-
Create a new app from the starter template:
|
|
25
|
-
|
|
26
|
-
```bash
|
|
27
|
-
npx -y everyapp@latest app create [name]
|
|
28
|
-
```
|
|
29
|
-
|
|
30
|
-
This will:
|
|
31
|
-
|
|
32
|
-
1. Prompt for an app ID (or use the provided name)
|
|
33
|
-
2. Deploy to Cloudflare (D1 database, KV namespace, Worker)
|
|
34
|
-
3. Configure wrangler.jsonc, package.json, and .env files
|
|
35
|
-
4. Install dependencies and run local migrations
|
|
36
|
-
|
|
37
|
-
### Deploy an app
|
|
38
|
-
|
|
39
|
-
Deploy your app to Cloudflare:
|
|
40
|
-
|
|
41
|
-
```bash
|
|
42
|
-
npx -y everyapp@latest app deploy
|
|
43
|
-
```
|
|
44
|
-
|
|
45
|
-
Run this from your app directory to build and deploy updates.
|
|
46
|
-
|
|
47
|
-
### Set up local environment
|
|
48
|
-
|
|
49
|
-
Set up local development for an existing Every App app (for example, after cloning a repo):
|
|
50
|
-
|
|
51
|
-
```bash
|
|
52
|
-
npx -y everyapp@latest app setup-local
|
|
53
|
-
```
|
|
54
|
-
|
|
55
|
-
This will:
|
|
56
|
-
|
|
57
|
-
1. Verify Cloudflare and gateway setup
|
|
58
|
-
2. Install dependencies
|
|
59
|
-
3. Create or refresh `.env.local`
|
|
60
|
-
4. Generate Cloudflare types and run local migrations
|
|
61
|
-
|
|
62
|
-
### Remote D1 shell
|
|
63
|
-
|
|
64
|
-
Run commands with access to your production D1 database:
|
|
65
|
-
|
|
66
|
-
```bash
|
|
67
|
-
npx -y everyapp@latest app remote-d1-shell -- <command>
|
|
68
|
-
```
|
|
69
|
-
|
|
70
|
-
Examples:
|
|
71
|
-
|
|
72
|
-
```bash
|
|
73
|
-
# Run migrations
|
|
74
|
-
npx -y everyapp@latest app remote-d1-shell -- npx drizzle-kit migrate
|
|
75
|
-
|
|
76
|
-
# Open Drizzle Studio
|
|
77
|
-
npx -y everyapp@latest app remote-d1-shell -- npx drizzle-kit studio
|
|
78
|
-
```
|
|
79
|
-
|
|
80
|
-
## Documentation
|
|
81
|
-
|
|
82
|
-
For full documentation, visit [everyapp.dev/docs](https://everyapp.dev/docs).
|
|
9
|
+
- Every command, explained: https://everyapp.com/docs/commands
|
|
10
|
+
- What coding agents read: [`skills/everyapp/SKILL.md`](skills/everyapp/SKILL.md), copied into each new app by `everyapp create`
|
|
11
|
+
- How it is tested: [`../../docs/TESTING.md`](../../docs/TESTING.md)
|
package/bin/everyapp.js
CHANGED
|
@@ -1,6 +1,241 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
// Committed launcher so package managers can link the bin at install time,
|
|
3
3
|
// before dist/ exists (fresh CI checkouts install with --ignore-scripts).
|
|
4
|
+
//
|
|
5
|
+
// everyapp runs from a checkout of the Every App repository: nothing is
|
|
6
|
+
// published while we work from the repository (.github/RELEASE.md). So when
|
|
7
|
+
// the CLI's source, or the SDK, perimeter or toolbus it bundles, changed
|
|
8
|
+
// since dist/ was built, it is rebuilt first: a few seconds, and only after
|
|
9
|
+
// a change, so `everyapp` always runs the code in front of you.
|
|
10
|
+
//
|
|
11
|
+
// Dependency-free, and nothing newer than Node 18 runs before the Node
|
|
12
|
+
// check below: an old Node must reach the friendly message, not a
|
|
13
|
+
// SyntaxError. (src/bin/launcher.test.ts holds the imports to that.)
|
|
14
|
+
import { spawnSync } from "node:child_process";
|
|
15
|
+
import fs from "node:fs";
|
|
16
|
+
import path from "node:path";
|
|
17
|
+
import { fileURLToPath } from "node:url";
|
|
18
|
+
|
|
19
|
+
// The Node this needs, said as src/lib/runtime.ts says it (the launcher
|
|
20
|
+
// can't import src): cf loads cloudflare.config.ts with Node's built-in
|
|
21
|
+
// TypeScript stripping, which Node gained in 22.18.0.
|
|
22
|
+
const MIN_NODE_VERSION = "22.18.0";
|
|
23
|
+
|
|
24
|
+
/** Whether `version` is older than `minimum` (both "major.minor.patch", a leading v allowed). */
|
|
25
|
+
function olderThan(version, minimum) {
|
|
26
|
+
const parse = (value) =>
|
|
27
|
+
value
|
|
28
|
+
.replace(/^v/, "")
|
|
29
|
+
.split(/[.-]/)
|
|
30
|
+
.slice(0, 3)
|
|
31
|
+
.map((part) => Number.parseInt(part, 10) || 0);
|
|
32
|
+
const [left, right] = [parse(version), parse(minimum)];
|
|
33
|
+
for (let i = 0; i < 3; i += 1) {
|
|
34
|
+
if ((left[i] ?? 0) !== (right[i] ?? 0)) return (left[i] ?? 0) < (right[i] ?? 0);
|
|
35
|
+
}
|
|
36
|
+
return false;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
// Colors as the CLI decides them (src/lib/output/terminal.ts): never with
|
|
40
|
+
// NO_COLOR, only at a terminal that isn't dumb; FORCE_COLOR decides alone.
|
|
41
|
+
const colors =
|
|
42
|
+
process.env.FORCE_COLOR !== undefined
|
|
43
|
+
? process.env.FORCE_COLOR !== "0"
|
|
44
|
+
: Boolean(process.stderr.isTTY) && !process.env.NO_COLOR && process.env.TERM !== "dumb";
|
|
45
|
+
const dim = (text) => (colors ? `\x1b[2m${text}\x1b[22m` : text);
|
|
46
|
+
const red = (text) => (colors ? `\x1b[31m${text}\x1b[39m` : text);
|
|
47
|
+
|
|
48
|
+
if (olderThan(process.versions.node, MIN_NODE_VERSION)) {
|
|
49
|
+
const message = `everyapp needs Node.js ${MIN_NODE_VERSION} or newer; this is ${process.versions.node}\nThe Cloudflare CLI loads cloudflare.config.ts with Node's built-in TypeScript support.`;
|
|
50
|
+
const fix = "install Node 22 or 24, then run the command again";
|
|
51
|
+
if (process.argv.includes("--json")) {
|
|
52
|
+
// One event on stdout, as the CLI's --json would write it.
|
|
53
|
+
process.stdout.write(
|
|
54
|
+
`${JSON.stringify({
|
|
55
|
+
v: 1,
|
|
56
|
+
ts: new Date().toISOString(),
|
|
57
|
+
type: "error",
|
|
58
|
+
code: "UNSUPPORTED_RUNTIME",
|
|
59
|
+
message,
|
|
60
|
+
retryable: false,
|
|
61
|
+
data: { fix },
|
|
62
|
+
})}\n`,
|
|
63
|
+
);
|
|
64
|
+
} else {
|
|
65
|
+
const [headline, ...detail] = message.split("\n");
|
|
66
|
+
process.stderr.write(
|
|
67
|
+
[`${red("✗")} ${headline}`, ...detail.map((line) => dim(` ${line}`)), ` Fix: ${fix}`, ""].join("\n"),
|
|
68
|
+
);
|
|
69
|
+
}
|
|
70
|
+
process.exit(1);
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
const cliDir = path.dirname(path.dirname(fileURLToPath(import.meta.url)));
|
|
74
|
+
const packagesDir = path.dirname(cliDir);
|
|
75
|
+
const sdkDir = path.join(packagesDir, "sdk");
|
|
76
|
+
|
|
77
|
+
/** When `file` was last written, in ms; 0 when it doesn't exist. */
|
|
78
|
+
function writtenAt(file) {
|
|
79
|
+
return fs.statSync(file, { throwIfNoEntry: false })?.mtimeMs ?? 0;
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
/** The newest write to any of `entries` (files, or directories walked whole), tests aside. */
|
|
83
|
+
function newestWrite(entries) {
|
|
84
|
+
let newest = 0;
|
|
85
|
+
for (const entry of entries) {
|
|
86
|
+
const stat = fs.statSync(entry, { throwIfNoEntry: false });
|
|
87
|
+
if (!stat) continue;
|
|
88
|
+
if (!stat.isDirectory()) {
|
|
89
|
+
newest = Math.max(newest, stat.mtimeMs);
|
|
90
|
+
continue;
|
|
91
|
+
}
|
|
92
|
+
for (const file of fs.readdirSync(entry, { recursive: true, withFileTypes: true })) {
|
|
93
|
+
if (!file.isFile() || file.name.endsWith(".test.ts")) continue;
|
|
94
|
+
newest = Math.max(newest, writtenAt(path.join(file.parentPath, file.name)));
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
return newest;
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
/** Which of the SDK and the CLI changed since their dist/ was built. */
|
|
101
|
+
function staleness() {
|
|
102
|
+
const sdkBuilt = writtenAt(path.join(sdkDir, "dist", "server", "index.js"));
|
|
103
|
+
const sdk =
|
|
104
|
+
newestWrite([
|
|
105
|
+
path.join(sdkDir, "src"),
|
|
106
|
+
path.join(sdkDir, "package.json"),
|
|
107
|
+
path.join(sdkDir, "tsconfig.json"),
|
|
108
|
+
path.join(sdkDir, "tsconfig.build.json"),
|
|
109
|
+
]) > sdkBuilt;
|
|
110
|
+
const cli =
|
|
111
|
+
sdk ||
|
|
112
|
+
newestWrite([
|
|
113
|
+
path.join(cliDir, "src"),
|
|
114
|
+
path.join(cliDir, "package.json"),
|
|
115
|
+
path.join(cliDir, "tsconfig.json"),
|
|
116
|
+
path.join(packagesDir, "perimeter", "src"),
|
|
117
|
+
path.join(packagesDir, "perimeter", "package.json"),
|
|
118
|
+
path.join(packagesDir, "toolbus", "src"),
|
|
119
|
+
path.join(packagesDir, "toolbus", "package.json"),
|
|
120
|
+
path.join(sdkDir, "dist"),
|
|
121
|
+
]) > writtenAt(path.join(cliDir, "dist", "index.js"));
|
|
122
|
+
return { sdk, cli };
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
/**
|
|
126
|
+
* Run one build command; whether it succeeded. A failure prints the build's
|
|
127
|
+
* output and what failed, and is reported rather than exited on: the caller
|
|
128
|
+
* holds the rebuild lock, and process.exit would skip the finally that
|
|
129
|
+
* releases it.
|
|
130
|
+
*/
|
|
131
|
+
function rebuild(command, args, cwd) {
|
|
132
|
+
const result = spawnSync(command, args, { cwd, encoding: "utf8" });
|
|
133
|
+
if (result.status === 0) return true;
|
|
134
|
+
process.stderr.write(result.stdout ?? "");
|
|
135
|
+
process.stderr.write(result.stderr ?? "");
|
|
136
|
+
console.error(
|
|
137
|
+
`everyapp: couldn't rebuild from this checkout: \`${[command, ...args].join(" ")}\` in ${cwd} ${result.error ? `failed (${result.error.message})` : `exited ${result.status}`}.`,
|
|
138
|
+
);
|
|
139
|
+
return false;
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
// One rebuild at a time per checkout. Two everyapps started together (an
|
|
143
|
+
// agent running commands in parallel, two terminals) would both rebuild,
|
|
144
|
+
// and one would trip over the files the other just cleaned. The lock is a
|
|
145
|
+
// directory under the checkout's build cache: mkdir without `recursive` is
|
|
146
|
+
// atomic, so EEXIST means another process holds it. The holder writes its
|
|
147
|
+
// pid; a lock older than 5 minutes, or whose holder is gone, is taken over.
|
|
148
|
+
const LOCK_DIR = path.join(path.dirname(packagesDir), "node_modules", ".cache", "everyapp", "rebuild.lock");
|
|
149
|
+
const LOCK_STALE_MS = 5 * 60_000;
|
|
150
|
+
const LOCK_POLL_MS = 200;
|
|
151
|
+
|
|
152
|
+
/** Whether the lock at `lockDir` was left behind: too old, or its holder is gone. */
|
|
153
|
+
function abandoned(lockDir) {
|
|
154
|
+
const stat = fs.statSync(lockDir, { throwIfNoEntry: false });
|
|
155
|
+
if (!stat) return false;
|
|
156
|
+
if (Date.now() - stat.mtimeMs > LOCK_STALE_MS) return true;
|
|
157
|
+
let pid;
|
|
158
|
+
try {
|
|
159
|
+
pid = Number.parseInt(fs.readFileSync(path.join(lockDir, "pid"), "utf8"), 10);
|
|
160
|
+
} catch {
|
|
161
|
+
// Just made, its pid not written yet: the age rule covers a holder that died here.
|
|
162
|
+
return false;
|
|
163
|
+
}
|
|
164
|
+
if (!Number.isInteger(pid) || pid <= 0) return false;
|
|
165
|
+
try {
|
|
166
|
+
process.kill(pid, 0);
|
|
167
|
+
return false;
|
|
168
|
+
} catch (error) {
|
|
169
|
+
return error?.code === "ESRCH";
|
|
170
|
+
}
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
function sleep(ms) {
|
|
174
|
+
Atomics.wait(new Int32Array(new SharedArrayBuffer(4)), 0, 0, ms);
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
/**
|
|
178
|
+
* Run `build` holding the rebuild lock, unless `stillNeeded` says the wait
|
|
179
|
+
* made it moot; what `build` returned, or true when nothing was needed.
|
|
180
|
+
* The lock is released on the way out whatever happened inside.
|
|
181
|
+
*/
|
|
182
|
+
function withRebuildLock(stillNeeded, build) {
|
|
183
|
+
fs.mkdirSync(path.dirname(LOCK_DIR), { recursive: true });
|
|
184
|
+
let waiting = false;
|
|
185
|
+
for (;;) {
|
|
186
|
+
try {
|
|
187
|
+
fs.mkdirSync(LOCK_DIR);
|
|
188
|
+
break;
|
|
189
|
+
} catch (error) {
|
|
190
|
+
if (error?.code !== "EEXIST") throw error;
|
|
191
|
+
}
|
|
192
|
+
if (abandoned(LOCK_DIR)) {
|
|
193
|
+
fs.rmSync(LOCK_DIR, { recursive: true, force: true });
|
|
194
|
+
continue;
|
|
195
|
+
}
|
|
196
|
+
if (!waiting) {
|
|
197
|
+
waiting = true;
|
|
198
|
+
console.error(dim("Waiting for another everyapp to finish rebuilding the CLI..."));
|
|
199
|
+
}
|
|
200
|
+
sleep(LOCK_POLL_MS);
|
|
201
|
+
}
|
|
202
|
+
try {
|
|
203
|
+
fs.writeFileSync(path.join(LOCK_DIR, "pid"), String(process.pid));
|
|
204
|
+
const stale = stillNeeded();
|
|
205
|
+
return stale ? build(stale) : true;
|
|
206
|
+
} finally {
|
|
207
|
+
fs.rmSync(LOCK_DIR, { recursive: true, force: true });
|
|
208
|
+
}
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
// Only in a checkout: a packed CLI has dist/ and no source.
|
|
212
|
+
if (fs.existsSync(path.join(cliDir, "src")) && fs.existsSync(path.join(sdkDir, "src")) && staleness().cli) {
|
|
213
|
+
const built = withRebuildLock(
|
|
214
|
+
// Checked again under the lock: the everyapp we waited for may have rebuilt.
|
|
215
|
+
() => {
|
|
216
|
+
const stale = staleness();
|
|
217
|
+
return stale.cli ? stale : null;
|
|
218
|
+
},
|
|
219
|
+
(stale) => {
|
|
220
|
+
// The CLI bundles the SDK from its dist/, and apps load it from there too.
|
|
221
|
+
if (stale.sdk && !rebuild("pnpm", ["run", "build"], sdkDir)) return false;
|
|
222
|
+
// tsup alone, no type check: `pnpm -C packages/cli build` type-checks.
|
|
223
|
+
if (!rebuild("pnpm", ["exec", "tsup", "--silent"], cliDir)) return false;
|
|
224
|
+
// The checkout's short commit. Not --dirty: that answers for every tracked
|
|
225
|
+
// file in the repository (after `create` inside the checkout, the lockfile),
|
|
226
|
+
// not for the sources this rebuild came from, and reads as a fault.
|
|
227
|
+
const commit = spawnSync("git", ["describe", "--always", "--exclude=*"], {
|
|
228
|
+
cwd: cliDir,
|
|
229
|
+
encoding: "utf8",
|
|
230
|
+
}).stdout.trim();
|
|
231
|
+
console.error(dim(`Rebuilt the everyapp CLI from this checkout (${commit})`));
|
|
232
|
+
return true;
|
|
233
|
+
},
|
|
234
|
+
);
|
|
235
|
+
// Exited here, with the lock released: process.exit skips a finally.
|
|
236
|
+
if (!built) process.exit(1);
|
|
237
|
+
}
|
|
238
|
+
|
|
4
239
|
import("../dist/index.js").catch((error) => {
|
|
5
240
|
if (error?.code === "ERR_MODULE_NOT_FOUND") {
|
|
6
241
|
console.error(
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{a,b,c,d,e,f,g,h,i}from"./chunk-QZWSSWMP.js";import"./chunk-E3EPK27P.js";import"./chunk-IG26HYRR.js";import"./chunk-IA534DGW.js";import"./chunk-MDORVBPD.js";import"./chunk-6O3GJS5H.js";import"./chunk-GRFPP4UW.js";import"./chunk-Y3VIFPN5.js";import"./chunk-PL6EORDJ.js";import"./chunk-EUNGJMJ6.js";import"./chunk-ZYL2ZHCF.js";import"./chunk-SPPR6WCI.js";import"./chunk-7LG3F4FF.js";import"./chunk-GD2JZMD3.js";import"./chunk-F6IH47GT.js";import"./chunk-JYKRUS5C.js";import"./chunk-SAT3PGZU.js";export{c as APPS_APPLICATION_NAME,b as GATEWAY_APPLICATION_NAME,a as POLICY_NAME,e as off,d as on,f as show,i as showAccess,h as turnAccessOff,g as turnAccessOn};
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import{a as $,c as w,d as T,e as f,f as g}from"./chunk-OEOVNJAN.js";import{I,J as E,L as O,M as P,N as R,O as L,P as N,g as S}from"./chunk-ECLJ5IAL.js";import"./chunk-ZYL2ZHCF.js";import"./chunk-SPPR6WCI.js";import"./chunk-7LG3F4FF.js";import"./chunk-F6IH47GT.js";import"./chunk-JYKRUS5C.js";import{c as A,f as k,hc as v,oc as y}from"./chunk-SAT3PGZU.js";import a from"chalk";var b="workspace.update";async function J(e){await y(e,p=>z({flags:e,out:p}))}async function Q(e){await y(e,p=>D({flags:e,out:p}))}async function Y(e){await y(e,p=>M({flags:e,out:p}))}async function Z(e,p){await y(e,o=>U({flags:e,out:o},p))}async function ee(e){await y(e,p=>j({flags:e,out:p}))}async function ae(e,p){await y(e,o=>B({flags:e,out:o},p))}var m=e=>e.toLocaleString("en-US"),x=e=>e===0?a.dim("\u2013"):`$${(e/1e6).toFixed(4)}`;async function z(e){let{out:p,flags:o}=e,{ws:r}=await $(e),s=o.month??I(new Date(r.now)),i=await E(r,s),n=v(["APP","CALLS","FAILED","TOOL CALLS","TOKENS IN/OUT","COST","CAP"],i.byApp.map(t=>[t.appSlug??t.appRowId,m(t.calls),t.failures>0?a.yellow(m(t.failures)):a.dim("0"),m(t.toolCalls),`${m(t.inputTokens)}/${m(t.outputTokens)}`,x(t.costMicros),t.callable?t.monthlyCallCap===null?a.dim("none"):m(t.monthlyCallCap):a.dim("removed")])),u=v(["MEMBER","CALLS","FAILED","TOOL CALLS","TOKENS IN/OUT","COST"],i.byMember.map(t=>[t.userId===""?a.dim("the apps themselves"):t.email??a.dim(`${t.userId} (no longer a member)`),m(t.calls),t.failures>0?a.yellow(m(t.failures)):a.dim("0"),m(t.toolCalls),`${m(t.inputTokens)}/${m(t.outputTokens)}`,x(t.costMicros)])),l=v(["PROVIDER","KIND","CALLS","FAILED","TOKENS IN/OUT","COST"],i.byTarget.map(t=>[t.target,t.kind,m(t.calls),t.failures>0?a.yellow(m(t.failures)):a.dim("0"),`${m(t.inputTokens)}/${m(t.outputTokens)}`,x(t.costMicros)])),c=i.byApp.reduce((t,h)=>t+h.calls,0),d=i.byApp.reduce((t,h)=>t+h.toolCalls,0),C=`${r.organization.name}, ${s}: ${k(c,"provider call")} and ${k(d,"tool call")} across ${k(i.byApp.length,"app")}`;p.emit({type:"done",message:C,display:[C,"",a.bold("By app"),...i.byApp.length>0?n:[a.dim("no apps")],"",a.bold("By member"),...i.byMember.length>0?u:[a.dim("no calls")],"",a.bold("By provider"),...i.byTarget.length>0?l:[a.dim("no calls")],"",a.dim(`Cap an app: ${A} workspace app cap <app> <n|off>`)].join(`
|
|
2
|
+
`),data:{organization:r.organization,...i}})}async function D(e){let{out:p,flags:o}=e,{ws:r}=await $(e),s=o.app===void 0?void 0:await S(r,o.app,{callable:!0}),i=o.user===void 0?void 0:await w(r,o.user),n=await O(r,{limit:o.limit,before:o.before,appRowId:s?.id,userId:i?.id,decision:o.decision,risk:o.risk,since:o.since}),u=v(["WHEN (UTC)","WHO","APP","TOOL","RISK","DECISION","OUTCOME","MS","CLIENT"],n.calls.map(d=>[f(d.createdAt),d.user.email??a.dim(d.user.id),d.app.slug?`${d.app.slug}${d.app.removed?a.dim(" (removed)"):""}`:a.dim("gateway"),d.tool.via?`${d.tool.name} ${a.dim(`via ${d.tool.via}`)}`:d.tool.name,d.tool.risk??a.dim("\u2013"),d.decision==="allowed"?a.green("allowed"):a.red(`blocked${d.reason?a.dim(` (${d.reason})`):""}`),d.outcome,d.durationMs===null?a.dim("\u2013"):String(d.durationMs),d.credential.clientName??d.credential.clientInfo??a.dim(d.credential.kind)])),l=n.nextBefore?`${n.nextBefore.createdAt}:${n.nextBefore.id}`:null,c=`${k(n.calls.length,"tool call")} in ${r.organization.name}${n.nextBefore?" (more before this page)":""}`;p.emit({type:"done",message:c,display:[n.calls.length>0?u.join(`
|
|
3
|
+
`):a.dim("No tool calls match."),...l?[a.dim(`Next page: ${A} workspace activity --before ${l}`)]:[]].join(`
|
|
4
|
+
`),data:{organization:r.organization,calls:n.calls.map(d=>({...d,createdAt:g(d.createdAt)})),nextBefore:l,...l?{next:[{command:`${A} workspace activity --before ${l}`,note:"the next page"}]}:{}}})}var W=e=>({id:e.id,user:e.user,name:e.name,prefix:e.prefix,app:e.app.slug,scopes:e.scopes,active:e.active,createdAt:g(e.createdAt),expiresAt:g(e.expiresAt),lastUsedAt:g(e.lastUsedAt),revokedAt:g(e.revokedAt)});async function M(e){let{out:p,flags:o}=e,{ws:r}=await $(e),s=o.user===void 0?void 0:await w(r,o.user),i=await P(r,s?.id),n=o.all?i:i.filter(c=>c.active),u=v(["ID","MEMBER","NAME","PREFIX","APP","SCOPES","STATE","LAST USED","EXPIRES"],n.map(c=>[c.id,c.user.email,c.name,`${c.prefix}\u2026`,c.app.slug??a.dim("all apps"),c.scopes.join(","),c.revokedAt!==null?a.dim("revoked"):c.active?a.green("active"):a.yellow("expired"),f(c.lastUsedAt),f(c.expiresAt)])),l=`${k(n.length,o.all?"personal access token":"active personal access token")}${s?` of ${T(s)}`:""} in ${r.organization.name}${!o.all&&i.length>n.length?` (${i.length-n.length} revoked or expired: --all)`:""}`;p.emit({type:"done",message:l,display:[n.length>0?u.join(`
|
|
5
|
+
`):a.dim(l),a.dim(`Revoke one: ${A} workspace token revoke <id>. Tokens are made in Admin \u2192 Tokens; a value is never shown again.`)].join(`
|
|
6
|
+
`),data:{organization:r.organization,tokens:n.map(W)}})}async function U(e,p){let{out:o}=e,{ws:r}=await $(e);o.emit({type:"step",step:b,status:"start",message:`Revoking the token ${p}...`});let{token:s,already:i}=await R(r,p);o.emit({type:"step",step:b,status:"ok",message:`Revoked ${s.name}`,data:{tokenId:s.id,already:i}});let n=i?[`${s.user.email}'s token ${s.name} (${s.prefix}\u2026) was revoked already, on ${f(s.revokedAt)} UTC.`]:[`Revoked ${s.user.email}'s token ${s.name} (${s.prefix}\u2026).`,"It stops working on its next request."];o.emit({type:"done",message:n.join(`
|
|
7
|
+
`),display:[n[0],...n.slice(1).map(u=>a.dim(u))].join(`
|
|
8
|
+
`),data:{organization:r.organization,token:W(s),already:i}})}var F=e=>({id:e.id,user:e.user,clientName:e.clientName,clientDomain:e.clientDomain,redirectHost:e.redirectHost,apps:e.apps,access:e.access,createdAt:g(e.createdAt),lastUsedAt:g(e.lastUsedAt),revokedAt:g(e.revokedAt),revokedReason:e.revokedReason});async function j(e){let{out:p,flags:o}=e,{ws:r}=await $(e),s=o.user===void 0?void 0:await w(r,o.user),i=await L(r,s?.id),n=v(["ID","MEMBER","AI APP","APPS","ACCESS","LAST USED","SINCE"],i.map(l=>[l.id,l.user.email,`${l.clientName}${l.clientDomain?a.dim(` (${l.clientDomain})`):""}`,l.apps==="all"?"all":l.apps.join(", ")||a.dim("none"),l.access==="write"?"read & write":"read",f(l.lastUsedAt),f(l.createdAt)])),u=`${k(i.length,"AI connection")}${s?` of ${T(s)}`:""} in ${r.organization.name}`;p.emit({type:"done",message:u,display:[i.length>0?n.join(`
|
|
9
|
+
`):a.dim(u),a.dim(`Revoke one: ${A} workspace connection revoke <id>`)].join(`
|
|
10
|
+
`),data:{organization:r.organization,connections:i.map(F)}})}async function B(e,p){let{out:o}=e,{ws:r}=await $(e);o.emit({type:"step",step:b,status:"start",message:`Revoking the connection ${p}...`});let{connection:s,already:i}=await N(r,p);o.emit({type:"step",step:b,status:"ok",message:`Revoked ${s.clientName}`,data:{connectionId:s.id,already:i}});let n=i?[`${s.user.email}'s connection from ${s.clientName} was revoked already${s.revokedReason?` (${s.revokedReason})`:""}.`]:[`Revoked ${s.user.email}'s connection from ${s.clientName}.`,"The client is out on its next request; its grant in the Gateway's authorization server lapses on its own."];o.emit({type:"done",message:n.join(`
|
|
11
|
+
`),display:[n[0],...n.slice(1).map(u=>a.dim(u))].join(`
|
|
12
|
+
`),data:{organization:r.organization,connection:F(s),already:i}})}export{Q as activity,ae as connectionRevoke,ee as connections,D as listActivity,j as listConnections,M as listTokens,z as reportUsage,B as revokeConnection,U as revokeToken,Z as tokenRevoke,Y as tokens,J as usage};
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import{a as f,g as T,h as k,j as F}from"./chunk-OEOVNJAN.js";import{B as j,D as z,E as O,F as I,G as x,g as N}from"./chunk-ECLJ5IAL.js";import{a as C,d as W,e as P}from"./chunk-MDORVBPD.js";import"./chunk-Y3VIFPN5.js";import"./chunk-ZYL2ZHCF.js";import{a as b}from"./chunk-SPPR6WCI.js";import"./chunk-7LG3F4FF.js";import"./chunk-F6IH47GT.js";import"./chunk-JYKRUS5C.js";import{c as S,f as g,hc as $,oc as h,xb as A}from"./chunk-SAT3PGZU.js";import d from"chalk";var w="workspace.update";async function Y(e){await h(e,n=>U({flags:e,out:n}))}async function Z(e,n){await h(e,a=>E({flags:e,out:a},n))}async function ee(e,n){await h(e,a=>M({flags:e,out:a},n))}async function te(e,n,a){await h(e,i=>L({flags:e,out:i},n,a))}function G(e){if(!e)return null;try{let n=JSON.parse(e);return n&&typeof n=="object"&&!Array.isArray(n)?n:null}catch{return null}}function R(e,n){let a=G(e.manifest);if(!a||e.tier==="dispatch"||e.status==="pending")return null;try{return P(a)?W({manifest:a,appId:e.appSlug,gatewayNames:n,secretNames:b(e.secretNames)}).setup:null}catch{return null}}var v=(e,n)=>({id:e.id,appId:e.appSlug,name:e.name,description:e.description,status:e.status,scope:e.scope,tier:e.tier,hostname:e.hostname,everyone:e.everyone,accessCount:e.accessCount,...n===void 0?{}:{setup:n}});async function U(e){let{out:n}=e,{gateway:a,ws:i}=await f(e),l=await j(i),o=null;try{o=await C(a.cf)}catch(t){n.emit({type:"warning",code:"SETTINGS_UNKNOWN",message:`Couldn't list the Gateway's settings, so what each app needs set is unknown
|
|
2
|
+
${A(t)}`})}let s=l.map(t=>({app:t,setup:R(t,o)})),p=$(["APP","NAME","STATUS","WHO CAN OPEN","SETUP"],s.map(({app:t,setup:c})=>[t.appSlug,t.name,t.status==="active"?d.green(t.status):d.yellow(t.status),t.scope==="shared"?"everyone, every organization":t.everyone?`everyone ${d.dim(`(${t.accessCount})`)}`:g(t.accessCount,"member"),c===null?d.dim("\u2013"):c.ready?d.green("ready"):d.yellow(`needs ${c.unmet.map(u=>u.names.join(" or ")).join(", ")}`)])),m=s.filter(({setup:t})=>t&&!t.ready);n.emit({type:"done",message:`${g(l.length,"app")} in ${i.organization.name}${m.length>0?`, ${m.length} needing setup`:""}`,display:l.length>0?p.join(`
|
|
3
|
+
`):d.dim(`No apps in ${i.organization.name} yet.`),data:{organization:i.organization,apps:s.map(({app:t,setup:c})=>v(t,c)),...m.length>0?{next:m.flatMap(({app:t,setup:c})=>c?.command?[{command:c.command.command,note:t.appSlug}]:[])}:{}}})}async function E(e,n){let{out:a,flags:i}=e,{ws:l}=await f(e);a.emit({type:"step",step:w,status:"start",message:`Updating ${n}...`});let{app:o,granted:s}=await z(l,n,{name:i.name,description:i.description,everyone:i.everyone===void 0?void 0:i.everyone==="on"});a.emit({type:"step",step:w,status:"ok",message:`Updated ${o.appSlug}`,data:{appRowId:o.id,granted:s}});let p=[`${o.appSlug} is "${o.name}"${o.description?`: ${o.description}`:""}.`,o.scope==="shared"?"A shared app: every member of every organization can open it.":o.everyone?`Available to everyone in ${l.organization.name}${s>0?` (${g(s,"member")} granted now)`:""}; new members get it on joining.`:`Private: ${g(o.accessCount,"member")} can open it (workspace app access ${o.appSlug}).`];a.emit({type:"done",message:p.join(`
|
|
4
|
+
`),display:[p[0],d.dim(p[1])].join(`
|
|
5
|
+
`),data:{organization:l.organization,app:v(o),granted:s}})}async function M(e,n){let{out:a,flags:i}=e,{change:l}=F(i),{ws:o}=await f(e),s=await N(o,n),p=[],m=[],t;l?(a.emit({type:"step",step:w,status:"start",message:`Changing who can open ${s.appSlug}...`}),{granted:p,revoked:m,users:t}=await I(o,s,l),a.emit({type:"step",step:w,status:"ok",message:`${s.appSlug}: ${g(p.length,"grant")} added, ${m.length} revoked`,data:{appRowId:s.id,granted:p.length,revoked:m.length}})):t=await O(o,s);let c=t.filter(r=>r.direct||r.viaGroups.length>0),u=$(["EMAIL","ROLE","STATUS","DIRECT","VIA GROUPS"],t.map(r=>[r.email,r.primaryRole??r.role,T(r),r.direct?d.green("yes"):d.dim("no"),r.viaGroups.length>0?r.viaGroups.join(", "):d.dim("\u2013")])),y=l?`${s.appSlug}: granted ${p.length>0?p.map(r=>r.email).join(", "):"nobody"}, revoked ${m.length>0?m.map(r=>r.email).join(", "):"nobody"}; ${g(c.length,"member")} can open it now.`:`${g(c.length,"member")} of ${t.length} can open ${s.appSlug}${s.everyone?" (available to everyone)":""}.`;a.emit({type:"done",message:y,display:[y,u.join(`
|
|
6
|
+
`)].join(`
|
|
7
|
+
`),data:{organization:o.organization,app:v({...s,accessCount:c.length}),users:t.map(r=>({...k(r),direct:r.direct,viaGroups:r.viaGroups})),...l?{granted:p.map(k),revoked:m.map(k)}:{}}})}async function L(e,n,a){let{out:i}=e,{ws:l}=await f(e);i.emit({type:"step",step:w,status:"start",message:`Setting ${n}'s cap...`});let o=await x(l,n,a),{app:s,was:p,capAlertsId:m}=o,t=y=>y===null?"no cap":`${y.toLocaleString("en-US")} calls a month`;i.emit({type:"step",step:w,status:"ok",message:`${s.appSlug}: ${t(a)}`,data:{appRowId:s.id,cap:a,was:p}});let c=[a===p?`${s.appSlug} had ${t(a)} already. Nothing changed.`:`${s.appSlug}: ${t(a)} for ${l.organization.name} (was ${t(p)}).`,a===null?"Its provider calls are no longer capped.":"Past it, a provider tool answers a tool error naming the cap, and an app's brokered call gets 429 app_monthly_cap_exceeded until the next UTC month."],u=m===null?null:{subscriptionId:m,message:`Owners and admins are emailed at 80% and at the cap (the built-in Cap alerts subscription; ${S} events list shows it).`};u&&c.push(u.message),i.emit({type:"done",message:c.join(`
|
|
8
|
+
`),display:[c[0],...c.slice(1).map(y=>d.dim(y))].join(`
|
|
9
|
+
`),data:{organization:l.organization,app:v(s),cap:a,was:p,capAlerts:u}})}export{ee as appAccess,M as appAccessCommand,te as appCap,Z as appSet,Y as apps,U as listApps,L as setCap,E as updateApp};
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import{c as e}from"./chunk-SAT3PGZU.js";import{buildCommand as n,buildRouteMap as c}from"@stricli/core";var r={kind:"parsed",parse:String,brief:"The Gateway's URL, checked against the Gateway in your Cloudflare account (default: EVERYAPP_GATEWAY_URL)",optional:!0},i={kind:"parsed",parse:String,brief:"The Cloudflare account of the Gateway, when your login sees several (default: CLOUDFLARE_ACCOUNT_ID)",optional:!0},g={kind:"parsed",parse:String,brief:"The organization to act on, by slug, id or name (default: the install organization; a name two organizations share is refused, ORG_AMBIGUOUS: give the slug)",placeholder:"slug",optional:!0},l={kind:"boolean",brief:"Print NDJSON events on stdout and never prompt (exit 0 done, 1 error, 2 action required, 251/252 bad command or arguments)",optional:!0},f={kind:"boolean",brief:"Print the result as an NDJSON event",optional:!0},d={kind:"boolean",brief:"Show every step and progress line, the output of what everyapp runs, and an unexpected error's stack trace",optional:!0},w={kind:"boolean",brief:"Skip everyapp's own confirmations (never cf's questions, or the one before replacing a Worker changed outside everyapp)",optional:!0},u={kind:"boolean",brief:"Publish new hostnames even where a DNS record answers them (one at a hostname is replaced)",optional:!0},y={"allow-delete-durable-object-data":{kind:"boolean",brief:"Deploy even though Durable Object classes were removed, deleting their data",optional:!0},"allow-delete-workflows":{kind:"boolean",brief:"Deploy even though Workflows were removed, deleting them and their instances",optional:!0},"force-dns":{...u,brief:"Publish the app's new hostname even where a DNS record answers it (one at the hostname is replaced)"},"enable-email-routing":{kind:"boolean",brief:"Turn on Email Routing for the domains the app's inbound addresses (everyapp email set --inbound) name that don't route mail yet (locks their MX and SPF records to Cloudflare)",optional:!0}};var p=(o=>(o.Senders="senders",o.Inbound="inbound",o))(p||{}),t={manifest:{kind:"parsed",parse:String,brief:"Path to everyapp.config.ts, if it isn't in this directory",placeholder:"path",optional:!0},gateway:r,"account-id":i,json:l,verbose:d},m=n({loader:async()=>{let{set:a}=await import("./email-NNFD3VVB.js");return a},parameters:{positional:{kind:"tuple",parameters:[]},flags:{sender:{kind:"parsed",parse:String,variadic:!0,optional:!0,placeholder:"pattern",brief:"Address the app may send as: '*@<domain>' or one address (repeat, up to 20)"},inbound:{kind:"parsed",parse:String,variadic:!0,optional:!0,placeholder:"address",brief:"Address whose mail goes to the app: '*@<apex>' or one address (repeat, up to 50)"},"enable-email-routing":{kind:"boolean",optional:!0,brief:"Turn on Email Routing for inbound domains without asking"},...t}},docs:{brief:"Set senders or inbound addresses, without a deploy",fullDescription:["Each flag replaces its whole list; a list you don't name is kept. The Gateway","picks up a change within 30 seconds, without a deploy. Addresses set before","the app's first upload are routed by its next deploy.","","Requirements:"," --sender everyapp.config.ts lists capabilities.email; each domain is set up for Email Sending"," --inbound everyapp.config.ts declares email: { inbound: true }; the domain is on Cloudflare DNS","","Examples:",` ${e} email set --sender '*@mail.example.com'`,` ${e} email set --inbound reports@mail.example.com`,` ${e} email set --inbound '*@example.com' --enable-email-routing`].join(`
|
|
2
|
+
`)}}),b=n({loader:async()=>{let{unset:a}=await import("./email-NNFD3VVB.js");return a},parameters:{positional:{kind:"array",minimum:1,parameter:{brief:"List to clear: senders or inbound",placeholder:"senders|inbound",parse:a=>{let s=Object.values(p).find(o=>o===a);if(!s)throw new Error("Use senders, inbound, or both.");return s}}},flags:t},docs:{brief:"Clear senders or inbound addresses, without a deploy",fullDescription:["Clearing inbound addresses removes their Email Routing rules; a catch-all goes","back to dropping mail. Nothing is built or deployed.","","Examples:",` ${e} email unset inbound`,` ${e} email unset senders inbound`].join(`
|
|
3
|
+
`)}}),h=n({loader:async()=>{let{show:a}=await import("./email-NNFD3VVB.js");return a},parameters:{positional:{kind:"tuple",parameters:[]},flags:t},docs:{brief:"Show the app's senders and inbound addresses",fullDescription:["Lists the app's senders and inbound addresses on the Gateway, and whether each","inbound address is routed.","","Examples:",` ${e} email show`,` ${e} email show --manifest ../analytics/everyapp.config.ts`].join(`
|
|
4
|
+
`)}}),S=c({routes:{show:h,set:m,unset:b},docs:{brief:"Manage the addresses an app sends as and receives at"}});export{r as a,i as b,g as c,l as d,f as e,d as f,w as g,u as h,y as i,S as j};
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import{d as o,f as s}from"./chunk-EUNGJMJ6.js";var r={sql:`CREATE TABLE IF NOT EXISTS _everyapp_restore_points (
|
|
2
|
+
target TEXT PRIMARY KEY,
|
|
3
|
+
database_id TEXT NOT NULL,
|
|
4
|
+
bookmark TEXT NOT NULL,
|
|
5
|
+
migrations TEXT NOT NULL,
|
|
6
|
+
created_at INTEGER NOT NULL,
|
|
7
|
+
created_by TEXT NOT NULL
|
|
8
|
+
)`},d=o,c=s;async function g(a,t){await a.run([r,{sql:`INSERT INTO _everyapp_restore_points (target, database_id, bookmark, migrations, created_at, created_by)
|
|
9
|
+
VALUES (?1, ?2, ?3, ?4, ?5, ?6)
|
|
10
|
+
ON CONFLICT (target) DO UPDATE SET database_id = excluded.database_id, bookmark = excluded.bookmark,
|
|
11
|
+
migrations = excluded.migrations, created_at = excluded.created_at, created_by = excluded.created_by`,params:[t.target,t.databaseId,t.bookmark,JSON.stringify(t.migrations),t.createdAt,t.createdBy]}])}async function E(a,t){let[,i=[]]=await a.run([r,{sql:"SELECT target, database_id, bookmark, migrations, created_at, created_by FROM _everyapp_restore_points WHERE target = ?",params:[t]}]),e=i[0];return e?{target:String(e.target),databaseId:String(e.database_id),bookmark:String(e.bookmark),migrations:JSON.parse(String(e.migrations)).map(String),createdAt:Number(e.created_at),createdBy:String(e.created_by)}:null}async function T(a,t){await a.run([r,{sql:"DELETE FROM _everyapp_restore_points WHERE target = ?",params:[t]}])}export{d as a,c as b,g as c,E as d,T as e};
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import{a as H,b as X,d as P,e as G,f as q,g as J,h as D,i as z,j as N,k as $,l as A}from"./chunk-AUDGOIHE.js";import{a as F,f as x}from"./chunk-OVKVV6MK.js";import{b as B,c as U,f as K,g as j}from"./chunk-PL6EORDJ.js";import{ma as W}from"./chunk-ZYL2ZHCF.js";import{b as L,d as Z}from"./chunk-F6IH47GT.js";import{c as _,tb as p,zb as T}from"./chunk-SAT3PGZU.js";function M(e){return`everyapp:${e}`}function O(e){if(!e)return null;if(e.startsWith("catch_all:"))return{kind:"catch_all",zoneId:e.slice(10)};let[n,t]=e.split("/");return n&&t?{kind:"rule",zoneId:n,ruleId:t}:null}function w(e){return e.slice(e.lastIndexOf("@")+1)}function b(e){return e.startsWith("*@")}async function ye({cf:e,gatewayDb:n,accountId:t,workerName:l,addresses:a,interactive:i,enableRouting:r=!1,confirm:s=L}){let d=(await B(n,l)).filter(o=>o.kind==="email-route"),m=d.filter(o=>!a.includes(o.binding));if(a.length===0)return d.length>0?{workerName:l,accountId:t,routes:[],enable:[],dropped:m}:null;let E=await U(n,"email-route");for(let o of a){let u=E.find(f=>f.name===o&&f.workerName!==l);if(u){let f=await W(n,u.workerName);throw new p("EMAIL_ADDRESS_TAKEN",`${o} already goes to another app${f?` (${f})`:""}`,{fix:`pick another address, or run ${_} email unset inbound in ${f?`${f}'s`:"that app's"} directory first`,data:{address:o,workerName:u.workerName,appId:f}})}}let R=new Map;for(let o of new Set(a.map(w)))R.set(o,await se(e,o,t));for(let o of a.filter(b)){let u=R.get(w(o));if(u.name!==w(o))throw new p("EMAIL_CATCH_ALL_NOT_APEX",`${o}: catch-alls only work on a zone's apex
|
|
2
|
+
${w(o)} is a subdomain of ${u.name}.`,{fix:`list each address instead, e.g. --inbound support@${w(o)}`,data:{address:o,zone:u.name}})}let y=te(e),g=[];for(let[o,u]of R)await ne(e,u,o,await y.settings(u.id))||g.push({zone:u,domain:o});g.sort((o,u)=>+(o.domain!==o.zone.name)-+(u.domain!==u.zone.name));let S=new Set(d.flatMap(o=>{let u=O(o.resourceId);return u?.kind==="rule"?[u.ruleId]:[]})),k=o=>oe(o,l)||o.id!==null&&S.has(o.id),v=[];for(let o of a){let u=R.get(w(o));if(b(o)){let c=await y.catchAll(u.id),C=c.enabled&&c.actions.some(re=>re.type!=="drop");if(!k(c)&&C)throw new p("EMAIL_CATCH_ALL_TAKEN",`${u.name}'s catch-all already ${Y(c)}
|
|
3
|
+
${o} would take it over.`,{fix:"set the catch-all back to Drop (Email Routing \u2192 Routing rules), or list addresses one by one",data:{address:o,zone:u.name,actions:c.actions}});v.push({address:o,zone:u,existing:k(c)?c:null});continue}let f=(await y.rules(u.id)).filter(c=>A(c)===o),h=f.find(c=>!k(c));if(h)throw new p("EMAIL_ADDRESS_TAKEN",`${o} already ${Y(h)}
|
|
4
|
+
The Email Routing rule ${h.name?`"${h.name}"`:h.id} on ${u.name} delivers it.`,{fix:"remove that rule, or pick another address",data:{address:o,zone:u.name,ruleId:h.id,actions:h.actions}});let I=f.find(c=>c.id!==null&&S.has(c.id))??f[0]??null;v.push({address:o,zone:u,existing:I})}if(g.length>0&&!r){let o=g.map(({domain:c})=>c),u=o.join(", "),h=`Turning it on locks ${o.length===1?"the domain's":"their"} MX and SPF records to Cloudflare.`,I=g.map(({zone:c,domain:C})=>`npx cf email-routing enable -z ${c.name} --name ${C}`);if(!i)throw new p("EMAIL_ROUTING_DISABLED",`Email Routing is off for ${u}
|
|
5
|
+
${h} Nothing was changed.`,{data:{domains:o,commands:I}});await Z(s,`Turn on Email Routing for ${u}?`,{context:[`Email Routing is off for ${u}. ${h.replace("the domain's","its")}`]})}return{workerName:l,accountId:t,routes:v,enable:g,dropped:m}}async function be({cf:e,gatewayDb:n,plan:t,onProgress:l}){let{workerName:a}=t,i=!1,r=s=>{i=!0,l?.(s)};for(let{zone:s,domain:d}of t.enable)await X(e,s.id,d),r(`Turned on Email Routing for ${d}.`);for(let{address:s,zone:d,existing:m}of t.routes){let E=g=>ue(n,a,s,g);if(b(s)){let g=Q(a,{type:"all"});await E(`catch_all:${d.id}`),(!m||!V(m,g))&&(await N(e,d.id,g),r(`${d.name}'s catch-all sends mail to ${a}.`));continue}let R=Q(a,{type:"literal",field:"to",value:s});if(m?.id){await E(`${d.id}/${m.id}`),V(m,R)||(await J(e,d.id,m.id,R),r(`Updated the Email Routing rule for ${s}.`));continue}await E(null);let y=await q(e,d.id,R);await E(`${d.id}/${y}`),r(`Created the Email Routing rule for ${s}.`)}for(let s of t.dropped)await ie(e,n,a,t.accountId,s),r(`Removed the route for ${s.name}, which the app's inbound addresses no longer list.`);return{routed:t.routes.map(s=>s.address),removed:t.dropped.map(s=>s.name),changed:i}}function $e(e){let{appId:n,workerName:t,routed:l,removed:a}=e,i=a.length?` Removed the routes for ${a.join(", ")}.`:"";if(l.length===0)return`${n} receives no mail.${i}`;let r=e.sendersSettable?ae(l,e.senders):[],s=r.length===1,d=r.length?` To reply from ${r.join(", ")}, onboard ${s?"it":"them"} to Email Sending and list ${s?"it":"them"} with \`${_} email set --sender\` (docs/runbooks/email-sending-setup.md).`:"";return`Mail to ${l.join(", ")} goes to ${t}.${i}${d}`}function ae(e,n){return[...new Set(e.map(w))].filter(t=>!n.some(l=>l.endsWith(`@${t}`)))}async function Ae({cf:e,gatewayDb:n,accountId:t,workerName:l,routes:a}){let i=[];for(let r of a)await ie(e,n,l,t,r)&&i.push(b(r.name)?`the catch-all of ${w(r.name)} (it drops mail again)`:`the Email Routing rule for ${r.name}`);return i}async function ke(e,n){let t=te(e),l=[];for(let a of n){let i=R=>l.push({workerName:a.workerName,address:a.name,problem:R}),r=O(a.resourceId);if(!r){i("a deploy stopped before recording its rule");continue}let s=r.kind==="catch_all"?await t.catchAll(r.zoneId):await G(e,r.zoneId,r.ruleId);if(!s){i("its Email Routing rule is gone");continue}if(!s.enabled||$(s)!==a.workerName){i(r.kind==="catch_all"?`the catch-all ${s.enabled?`sends mail ${ee(s)}`:"is off"}`:`its rule ${s.enabled?`sends mail ${ee(s)}`:"is off"}`);continue}let d=await t.settings(r.zoneId),m=w(a.name),E={id:r.zoneId,name:d.name?.toLowerCase()??m};await ne(e,E,m,d)||i(`Email Routing is off for ${m}`)}return l}async function se(e,n,t){try{return await x(e,n,t)}catch(l){throw l instanceof p&&l.code==="ZONE_NOT_FOUND"?new p("EMAIL_ZONE_NOT_FOUND",`${n} isn't on Cloudflare DNS in this account
|
|
6
|
+
Email Routing needs the domain's zone in the Gateway's Cloudflare account.`,{fix:"add the domain (or its parent) to the account, or pick an address on another domain",data:{domain:n}}):l}}async function ne(e,n,t,l){return t===n.name?l.enabled:(await F(e,n.id,t)).some(i=>i.type==="MX"&&/\.mx\.cloudflare\.net\.?$/i.test(i.content??""))}function te(e){let n=new Map,t=new Map,l=new Map,a=(i,r,s)=>{let d=i.get(r);return d||(d=s(),i.set(r,d)),d};return{settings:i=>a(n,i,()=>H(e,i)),rules:i=>a(t,i,()=>P(e,i)),catchAll:i=>a(l,i,()=>z(e,i))}}function Q(e,n){return{name:M(e),enabled:!0,matchers:[n],actions:[{type:"worker",value:[e]}]}}var le={name:"",enabled:!1,matchers:[{type:"all"}],actions:[{type:"drop"}]};function oe(e,n){return e.name===M(n)||$(e)===n}function V(e,n){let t=n.matchers[0];return e.name===n.name&&e.enabled===n.enabled&&e.actions.length===1&&$(e)===n.actions[0].value[0]&&e.matchers.length===1&&e.matchers[0].type===t.type&&("value"in t?A(e)===t.value:!0)}function Y(e){let n=e.actions[0];return!n||n.type==="drop"?"drops mail":n.type==="forward"?`forwards to ${n.value?.[0]??"an address"}`:n.type==="worker"?"goes to another Worker":`sends mail to "${n.type}"`}function ee(e){let n=e.actions[0];if(!n)return"nowhere";let t=n.value?.[0];return n.type==="worker"?`to the Worker ${t??"(unnamed)"}`:n.type==="forward"?`to ${t??"an address"}`:`to "${n.type}"`}async function ue(e,n,t,l){try{await K(e,n,{kind:"email-route",binding:t,name:t,resourceId:l})}catch(a){throw a instanceof p&&a.code==="RESOURCE_OWNED"?new p("EMAIL_ADDRESS_TAKEN",`${t} was recorded for another app while this run was routing it`,{fix:"take another address, or remove it from that app first",data:{address:t}}):a}}async function ie(e,n,t,l,a){let i=O(a.resourceId),r=!1;try{if(i?.kind==="rule")r=await D(e,i.zoneId,i.ruleId);else if(i?.kind==="catch_all"){let s=await z(e,i.zoneId);oe(s,t)&&(await N(e,i.zoneId,le),r=!0)}else r=await de(e,t,l,a.name)}catch(s){if(!T(s,"not_found"))throw s}return await j(n,t,{kind:"email-route",binding:a.binding}),r}async function de(e,n,t,l){if(b(l))return!1;let a;try{a=(await x(e,w(l),t)).id}catch(r){if(r instanceof p)return!1;throw r}let i=!1;for(let r of await P(e,a))r.id&&r.name===M(n)&&A(r)===l&&(i=await D(e,a,r.id)||i);return i}function ve(e){return{sends:e.capabilities?.email?.access==="write",receives:e.email?.inbound===!0}}export{ye as a,be as b,$e as c,ae as d,Ae as e,ke as f,ve as g};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{m as r}from"./chunk-JYKRUS5C.js";import{Vb as t}from"./chunk-SAT3PGZU.js";var u=100;function c(e,n){return t(e,{plane:"account",args:["r2","buckets","list","--name-contains",n,"--per-page",String(u)]},r).then(o=>o.map(s=>s.name))}async function f(e,n){return(await c(e,n)).includes(n)}async function p(e,n){await e.run({plane:"account",mode:"json",args:["r2","buckets","create","--name",n]})}async function m(e,n){await e.run({plane:"account",mode:"json",args:["r2","buckets","delete",n,"--force"]})}export{c as a,f as b,p as c,m as d};
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import{c as M,e as H}from"./chunk-EUNGJMJ6.js";import{Vb as d,Wb as _,Yb as j,_b as B,c as L,f as N,k as m,tb as A,xb as O,yb as z,zb as g}from"./chunk-SAT3PGZU.js";import{z as o}from"zod";var C={perPage:100,maxPages:20};async function p(t){try{return await t}catch(e){throw b(e)}}var x=o.looseObject({name:o.string().nullish(),auth_domain:o.string(),session_duration:o.string().nullish(),allow_authenticate_via_warp:o.boolean().nullish(),deny_unmatched_requests:o.boolean().nullish(),deny_unmatched_requests_exempted_zone_names:o.array(o.string()).nullish(),warp_auth_non_browser_401:o.boolean().nullish(),mfa_config:o.unknown().nullish()});async function te(t){try{return await d(t,{plane:"account",args:["zero-trust","organization","get"]},x)}catch(e){if(g(e,"not_found")||e instanceof z&&/not[_ ]found/i.test(e.message))return null;throw b(e)}}async function xe(t){try{return await te(t)}catch(e){if(g(e,"access_not_enabled"))return null;throw e}}function Ee(t,e){return p(d(t,{plane:"account",files:{"body.json":e},args:n=>["zero-trust","organization","create","--body",`@${n["body.json"]}`]},x))}function Ie(t,e,n){let s={name:e.name??e.auth_domain,auth_domain:e.auth_domain,allow_authenticate_via_warp:e.allow_authenticate_via_warp??!1,deny_unmatched_requests:e.deny_unmatched_requests??!1,deny_unmatched_requests_exempted_zone_names:e.deny_unmatched_requests_exempted_zone_names??[],warp_auth_non_browser_401:e.warp_auth_non_browser_401??!1,...e.mfa_config?{mfa_config:e.mfa_config}:{},session_duration:n};return p(d(t,{plane:"account",files:{"body.json":s},args:r=>["zero-trust","organization","update","--body",`@${r["body.json"]}`]},x))}var E=o.looseObject({id:o.string(),type:o.string(),name:o.string().nullish(),config:o.looseObject({restrict_to_account_members:o.boolean().nullish()}).nullish()});function De(t){return p(_(t,["zero-trust","identity-providers","list"],o.array(E),C))}function $e(t){return p(d(t,{plane:"account",files:{"body.json":{name:"One-time PIN",type:"onetimepin",config:{}}},args:e=>["zero-trust","identity-providers","create","--body",`@${e["body.json"]}`]},E))}function ve(t){return p(d(t,{plane:"account",files:{"body.json":{name:"Cloudflare",type:"cloudflare",config:{restrict_to_account_members:!0}}},args:e=>["zero-trust","identity-providers","create","--body",`@${e["body.json"]}`]},E))}var I=o.looseObject({id:o.string(),name:o.string(),decision:o.string(),include:o.array(o.record(o.string(),o.unknown())).nullish(),exclude:o.array(o.record(o.string(),o.unknown())).nullish(),require:o.array(o.record(o.string(),o.unknown())).nullish(),reusable:o.boolean().nullish()});function Te(t){return p(_(t,["zero-trust","access","policies","list"],o.array(I),C))}function ke(t,e){return p(d(t,{plane:"account",files:{"body.json":{...e,exclude:[],require:[]}},args:n=>["zero-trust","access","policies","create","--body",`@${n["body.json"]}`]},I))}async function Le(t,e){try{return await t.run({plane:"account",mode:"json",args:["zero-trust","access","policies","delete",e,"--force"]}),!0}catch(n){if(g(n,"not_found"))return!1;throw b(n)}}var ne=new Set(["id","uid","created_at","updated_at","app_count","reusable"]);function Ne(t,e,n){let s={};for(let[r,i]of Object.entries(e))ne.has(r)||(s[r]=i);return s.include=n,s.exclude=e.exclude??[],s.require=e.require??[],p(d(t,{plane:"account",files:{"body.json":s},args:r=>["zero-trust","access","policies","update",e.id,"--body",`@${r["body.json"]}`]},I))}var se=o.looseObject({path_pattern:o.string(),behavior:o.string()}),oe=o.looseObject({type:o.string().nullish(),uri:o.string().nullish(),overrides:o.array(se).nullish()}),ie=o.looseObject({id:o.string(),name:o.string().nullish(),precedence:o.number().nullish(),reusable:o.boolean().nullish()}),D=o.looseObject({id:o.string(),aud:o.string(),name:o.string().nullish(),type:o.string(),created_at:o.string().nullish(),destinations:o.array(oe).nullish(),policies:o.array(ie).nullish(),session_duration:o.string().nullish(),http_only_cookie_attribute:o.boolean().nullish(),enable_binding_cookie:o.boolean().nullish(),allowed_idps:o.array(o.string()).nullish(),auto_redirect_to_identity:o.boolean().nullish(),app_launcher_visible:o.boolean().nullish(),oauth_configuration:o.looseObject({enabled:o.boolean().nullish()}).nullish()});function $(t){return p(_(t,["zero-trust","access","applications","list"],o.array(D),C))}function ze(t,e){return p(d(t,{plane:"account",files:{"body.json":e},args:n=>["zero-trust","access","applications","create","--body",`@${n["body.json"]}`]},D))}var re=new Set(["id","uid","aud","created_at","updated_at","domain","self_hosted_domains","policies","scim_config"]);function U(t,e){let n={};for(let[s,r]of Object.entries(t))re.has(s)||(n[s]=r);return n.policies=[...t.policies??[]].sort((s,r)=>(s.precedence??0)-(r.precedence??0)).map(s=>s.id),{...n,...e}}function q(t,e,n){return p(d(t,{plane:"account",files:{"body.json":n},args:s=>["zero-trust","access","applications","update",e,"--body",`@${s["body.json"]}`]},D))}async function je(t,e){try{return await t.run({plane:"account",mode:"json",args:["zero-trust","access","applications","delete",e,"--force"]}),!0}catch(n){if(g(n,"not_found"))return!1;throw b(n)}}var ae="https://dash.cloudflare.com/profile/api-tokens";function b(t){return g(t,"auth")?new A("ACCESS_PERMISSION_MISSING",`This Cloudflare login can't manage Access
|
|
2
|
+
${t.message.split(`
|
|
3
|
+
`)[0]}`,{fix:"use a login or token with Access: Apps and Policies (edit) and Access: Organizations, Identity Providers, and Groups (edit)",data:{url:ae}}):t}var W=["/mcp","/mcp/*"],J="/health",ce=[...W,"/oauth/token","/oauth/register","/.well-known/*",J],le=512;function ue(t){if(!t.startsWith("/"))return null;let e=t.split("/").map((s,r)=>{if(r===0)return s;let i=s.replace(/\*{2,}/g,"*");return/^:[A-Za-z_][A-Za-z0-9_]*$/.test(i)?"*":i});if(e.some(s=>(s.match(/\*/g)??[]).length>1))return null;let n=e.join("/");return n.length>le?null:n}var K=t=>t.map(e=>({path_pattern:e,behavior:"public"})),pe=t=>t.publicPaths.length>0||t.mcp;function de(t,{managedOAuth:e}){let n=t.mcp&&!e?[...W]:[],s=[];for(let r of t.publicPaths){let i=ue(r);if(i===null){s.push({appId:t.appId,path:r,reason:"not_expressible"});continue}if(!n.includes(i)){if(n.length>=25){s.push({appId:t.appId,path:r,reason:"too_many"});continue}n.push(i)}}return{destination:{type:"public",uri:t.hostname.toLowerCase(),overrides:K(n)},dropped:s}}function Me(t,e){return{type:"public",uri:t.toLowerCase(),overrides:K(e?[J]:ce)}}var v=t=>`*.${t.toLowerCase()}`;function V(t,e){let n=t.toLowerCase(),s=`.${e.toLowerCase()}`;return n.endsWith(s)&&!n.slice(0,-s.length).includes(".")&&n.length>s.length}function X(t,e,{managedOAuth:n=!1}={}){let s=[{type:"public",uri:v(t),overrides:[]}],r=[],i=[];for(let a of[...e].sort((l,u)=>l.hostname.localeCompare(u.hostname))){if(!pe(a))continue;if(!V(a.hostname,t)){i.push(a.appId);continue}let l=de(a,{managedOAuth:n});r.push(...l.dropped),l.destination.overrides.length!==0&&s.push(l.destination)}return{destinations:s,dropped:r,outsideBase:i}}function fe(t,e){let n=P(t);return!n||n.includes("/")?!1:n===e.gatewayHost.toLowerCase()||n===v(e.appBaseDomain)||V(n,e.appBaseDomain)}function Z(t,e){let n=[],s=[];for(let r of t)(fe(r.uri,e)?n:s).push(r);return{owned:n,foreign:s}}var P=t=>(t??"").toLowerCase().replace(/\/+$/,"");function F(t){return t.map(e=>({type:e.type??"public",uri:P(e.uri),overrides:[...e.overrides??[]].map(n=>`${n.behavior}:${n.path_pattern}`).sort()})).sort((e,n)=>e.uri.localeCompare(n.uri))}function Q(t,e){return JSON.stringify(F(t))===JSON.stringify(F(e))}function Y(t,e){return t.type==="self_hosted"&&(t.destinations??[]).some(n=>(n.type??"public")==="public"&&P(n.uri)===P(e))}function T(t,{gatewayHost:e,appBaseDomain:n}){return{gateway:t.find(s=>Y(s,e))??null,apps:t.find(s=>Y(s,v(n)))??null}}var ee=t=>t?.oauth_configuration?.enabled===!0,He=t=>({email:{email:t.toLowerCase()}}),Ue=t=>({email_domain:{domain:t.toLowerCase()}});function G(t){return JSON.stringify(t,(e,n)=>typeof n=="string"?n.toLowerCase():n)}function qe(t,e){let n=new Set(t.map(G)),s=[];for(let r of e){let i=G(r);n.has(i)||(n.add(i),s.push(r))}return{include:[...t,...s],added:s}}function Fe(t){return t.flatMap(e=>{let n=e.email?.email;return typeof n=="string"?[n]:[]})}function Ye(t){return t.flatMap(e=>{let n=e.email_domain?.domain;return typeof n=="string"?[n]:[]})}var y="cloudflare",w="onetimepin",Ge=["oidc","saml"];function We(t){return{cloudflare:!t.some(e=>e.type===y),pin:!t.some(e=>e.type===w)}}function Je(t){return t.filter(e=>e.type===y&&e.config?.restrict_to_account_members!==!0)}function Ke(t){let e=[...t.some(n=>n.type===y)?["a Cloudflare account"]:[],...t.filter(n=>n.type!==y&&n.type!==w).map(n=>n.name??n.type),...t.some(n=>n.type===w)?["a one-time PIN"]:[]];return e.length<=1?e[0]??"no sign-in method":`${e.slice(0,-1).join(", ")} or ${e.at(-1)}`}function Ve(t){return t.filter(e=>e.type===w||e.type===y&&e.config?.restrict_to_account_members===!0)}function ge(t,e){let n=[...t??[]];for(let s of e)n.includes(s)||n.push(s);return n}function me(t,e){let n=ge(t?.allowed_idps,e);return{allowedIdps:n,autoRedirect:n.length===1}}function Xe(t,e){let n=me(t,e),s=t.allowed_idps??[];return s.length===n.allowedIdps.length&&n.allowedIdps.every(r=>s.includes(r))&&(t.auto_redirect_to_identity??!1)===n.autoRedirect}function Ze(t){let e=t.trim();if(!/^(\d+(?:\.\d+)?(?:ns|us|µs|ms|s|m|h))+$/.test(e))return null;let n={ns:1e-9,us:1e-6,\u00B5s:1e-6,ms:.001,s:1,m:60,h:3600},s=0;for(let[,r,i]of e.matchAll(/(\d+(?:\.\d+)?)(ns|us|µs|ms|s|m|h)/g))s+=Number(r)*n[i];return s}var ye=["binding","active","disabled"],he=6e4;async function Ae(t){let[e=[]]=await t.run([{sql:`SELECT app_slug, hostname, manifest FROM apps
|
|
4
|
+
WHERE status IN (${ye.map(n=>`'${n}'`).join(", ")}) AND hostname IS NOT NULL
|
|
5
|
+
ORDER BY hostname`}]);return e.map(n=>({appId:String(n.app_slug),hostname:String(n.hostname),publicPaths:j(n.manifest).map(s=>s.path),mcp:B(n.manifest)!==null}))}function _e({publicRoutes:t,mcp:e}){return t&&e?"public routes and /mcp":e?"/mcp":"public routes"}var k=t=>({gatewayHost:t.gatewayHost.toLowerCase(),appBaseDomain:t.appBaseDomain.toLowerCase()});async function be({cf:t,db:e,install:n,out:s}){let r=k(n),i=await M({db:e,id:H,purpose:"access.sync",out:s,step:"gateway.lease",waitMs:he});try{let a=T(await $(t),r);return a.apps?(await i.check(),await Pe({cf:t,db:e,install:n,application:a.apps,gateway:a.gateway})):null}finally{await i.release()}}async function Pe({cf:t,db:e,install:n,application:s,gateway:r}){let i=k(n),a=X(i.appBaseDomain,await Ae(e),{managedOAuth:ee(r)}),l=s.destinations??[],{foreign:u}=Z(l,i),h=r?.id===s.id?l.filter(R=>(R.uri??"").toLowerCase().replace(/\/+$/,"")===i.gatewayHost):[],c=[...u,...h,...a.destinations],f={dropped:a.dropped,outsideBase:a.outsideBase,foreign:u.length>0?[{application:s.name??s.id,uris:u.map(R=>R.uri??"(private)")}]:[]};return Q(l,c)?{application:s,changed:!1,...f}:{application:await q(t,s.id,U(s,{destinations:c})),changed:!0,...f}}function we(t,e){let n=e.dropped.filter(i=>i.reason==="not_expressible"),s=e.dropped.filter(i=>i.reason==="too_many"),r=i=>i===1?"A public route stays":`${i} public routes stay`;n.length>0&&t.emit({type:"warning",code:"ACCESS_ROUTE_NOT_EXPRESSIBLE",step:"access.routes",message:`${r(n.length)} behind Access: ${m(n.map(i=>`${i.appId} ${i.path}`))}
|
|
6
|
+
Access path patterns take one * per segment, so these have no equivalent. People signed in to Access still reach them.`,data:{routes:n}}),s.length>0&&t.emit({type:"warning",code:"ACCESS_TOO_MANY_PUBLIC_ROUTES",step:"access.routes",message:`${r(s.length)} behind Access: ${m(s.map(i=>`${i.appId} ${i.path}`))}
|
|
7
|
+
Access lets through at most 25 paths per host (two of them for /mcp where the manifest sets mcp). Merge routes under one prefix, or keep these behind the login.`,data:{routes:s}}),e.outsideBase.length>0&&t.emit({type:"warning",code:"ACCESS_APP_OUTSIDE_BASE",step:"access.routes",message:`${m(e.outsideBase)} ${e.outsideBase.length===1?"isn't":"aren't"} under the apps' domain, so Access isn't set up for ${e.outsideBase.length===1?"it":"them"}.`,data:{apps:e.outsideBase}});for(let{application:i,uris:a}of e.foreign)t.emit({type:"warning",code:"ACCESS_FOREIGN_DESTINATION",step:"access.routes",message:`The Access application "${i}" also covers ${m(a)}
|
|
8
|
+
${N(a.length,"That destination").replace(/^1 That destination/,"That destination").replace(/^(\d+) That destinations?/,"Those $1 destinations")} ${a.length===1?"isn't":"aren't"} Every App's and ${a.length===1?"stays":"stay"} as ${a.length===1?"it is":"they are"}. access off won't delete this application.`,data:{application:i,uris:a}})}async function ct(t,{appId:e,surface:n,removing:s=!1}){let{cf:r,install:i,out:a}=t,l=`${L} access on`,u=_e(n),h;try{h=await $(r)}catch(c){let f=c instanceof A&&c.code==="ACCESS_PERMISSION_MISSING";if(f&&!n.publicRoutes&&!n.mcp)return;let S=s?`If the Gateway is behind Access, ${e}'s host stays listed there until it is updated.`:`If the Gateway is behind Access, ${e}'s ${u} need a login there until it is updated.`;a.emit({type:"warning",code:"ACCESS_NOT_CHECKED",step:"app.access",message:f?`This Cloudflare login can't read Cloudflare Access, so ${e} wasn't checked against it
|
|
9
|
+
${S}`:`Couldn't check Cloudflare Access for ${e}
|
|
10
|
+
${O(c).split(`
|
|
11
|
+
`)[0]}
|
|
12
|
+
${S}`,data:{appId:e,rerun:l,rerunNote:f?"with a login that can manage Access, if the Gateway is behind it":"if the Gateway is behind Access"}});return}if(T(h,k(i)).apps)try{let c=await be(t);if(!c)return;we(a,c);let f=s?c.changed?`Cloudflare Access no longer lets ${e}'s ${u} through.`:`Cloudflare Access had nothing of ${e}'s to take back.`:c.changed?`Cloudflare Access lets ${e}'s ${u} through.`:`Cloudflare Access already matched ${e}'s ${u}.`;a.emit({type:"step",step:"app.access",status:c.changed?"ok":"skip",message:f,data:{appId:e,applicationId:c.application.id,changed:c.changed,removed:s}})}catch(c){a.emit({type:"warning",code:"ACCESS_SYNC_FAILED",step:"app.access",message:`Couldn't update Cloudflare Access for ${e}'s ${u}
|
|
13
|
+
${O(c).split(`
|
|
14
|
+
`)[0]}
|
|
15
|
+
${s?`${e}'s host stays listed there until it is updated.`:"Until it is updated, they need an Access login."}`,data:{appId:e,rerun:l}})}}export{te as a,xe as b,Ee as c,Ie as d,De as e,$e as f,ve as g,Te as h,ke as i,Le as j,Ne as k,$ as l,ze as m,U as n,q as o,je as p,W as q,Me as r,X as s,Z as t,Q as u,T as v,ee as w,He as x,Ue as y,qe as z,Fe as A,Ye as B,y as C,w as D,Ge as E,We as F,Je as G,Ke as H,Ve as I,me as J,Xe as K,Ze as L,Ae as M,k as N,we as O,ct as P};
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
import{i as d}from"./chunk-DQWOXSL3.js";import{e as g,f as c}from"./chunk-GD2JZMD3.js";import{a as m,e as y}from"./chunk-JYKRUS5C.js";import{Ob as a,Vb as l,hb as p}from"./chunk-SAT3PGZU.js";import e from"node:path";var u=".cloudflare/state",A=6e5;async function L(i,t){let r=t.resources?.d1??[];if(r.length===0)return{status:"skipped",reason:"no_d1"};let o=g(r,t.migrations),n=c(t);return await a(e.resolve(i,n))?{status:"found",binding:o,dir:n}:{status:"skipped",reason:"no_migrations_dir"}}async function b({cwd:i,manifest:t,cf:r,onApply:o}){let n=await L(i,t);return n.status==="skipped"?n:(o?.(),{status:"applied",...await R({cwd:i,manifest:t,cf:r,...n})})}async function R({cwd:i,manifest:t,cf:r,binding:o,dir:n}){let s=d(p(t.id),o);return{applied:(await l(r,{plane:"project",cwd:i,local:!0,timeoutMs:A,env:f(i),args:["d1","migrations","apply",s,"--local","--persist-to",u,"--dir",n]},m)).map(M=>M.name),database:s}}async function k({cwd:i,manifest:t,cf:r}){let o=g(t.resources?.d1??[],t.migrations);return(await l(r,{plane:"project",cwd:i,local:!0,env:f(i),args:["d1","migrations","list",d(p(t.id),o),"--local","--persist-to",u,"--dir",c(t)]},y)).map(s=>s.Name)}function f(i){let t=e.join(i,".everyapp","registry");return{CLOUDFLARE_REGISTRY_PATH:t,MINIFLARE_REGISTRY_PATH:t}}async function I(i){let t=await a(e.join(i,".wrangler","state")),r=await a(e.join(i,u));return!t||r?null:`Local data now lives in .cloudflare/state
|
|
2
|
+
Rows in the old .wrangler/state database weren't copied over.`}export{L as a,b,R as c,k as d,f as e,I as f};
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import{e as A,h as d}from"./chunk-F6IH47GT.js";import{b as L}from"./chunk-JYKRUS5C.js";import{Bb as C,Vb as p,bc as E,c,d as g,tb as u,ub as s,xb as h}from"./chunk-SAT3PGZU.js";import f from"chalk";var O=null;async function _(o){let t=await p(o,{plane:"account",args:["auth","whoami"]},L);return O=t.authenticated&&!process.env.CLOUDFLARE_API_TOKEN?t.email??null:null,t}function x(){return O}var m=5*60*1e3;function F(o,t){return i=>o.emit({type:"action_required",action:"cloudflare_login",step:t,message:"Log in to Cloudflare: open this link and enter the code",data:{url:i.url,code:i.code,expiresAt:new Date(Date.now()+m).toISOString(),waiting:!0,waitingFor:"Cloudflare login"}})}async function S(o){let t=await _(o.cf);return t.authenticated?t:w(o)}async function w({cf:o,interactive:t,onDeviceLogin:i}){if(process.env.CLOUDFLARE_API_TOKEN)throw new u("CLOUDFLARE_TOKEN_REJECTED",`Cloudflare didn't accept CLOUDFLARE_API_TOKEN
|
|
2
|
+
It may be mistyped, expired or revoked.
|
|
3
|
+
A token needs Account \u203A Workers Scripts \u203A Edit, Account \u203A D1 \u203A Edit, Account \u203A Workers KV Storage \u203A Edit, Zone \u203A Zone \u203A Read and Zone \u203A DNS \u203A Read: https://dash.cloudflare.com/profile/api-tokens`,{fix:`set a valid token, or unset CLOUDFLARE_API_TOKEN and run ${c} login`});if(t)d(`${f.cyan("\u2192")} Log in to Cloudflare to continue
|
|
4
|
+
${f.dim(" Starting Cloudflare's login. Open its link and enter the code.")}`),await o.run({plane:"account",mode:"interactive",args:["auth","login"]});else if(i)await D(o,i);else throw new s("cloudflare_login",`Log in to Cloudflare with ${c} login
|
|
5
|
+
Unattended? Set CLOUDFLARE_API_TOKEN and CLOUDFLARE_ACCOUNT_ID instead.`);let n=await _(o);if(!n.authenticated)throw new u("CLOUDFLARE_LOGIN_FAILED","Cloudflare login didn't complete",{rerun:`${c} login`});return t&&d(`Logged in to Cloudflare${n.email?` as ${n.email}`:""} ${f.green("\u2713")}`),n}async function D(o,t){let i="",n=!1;try{await o.run({plane:"account",mode:"text",timeoutMs:m,args:["auth","login","--no-browser"],onOutput:l=>{i+=l;let a=/please visit:\s*(https?:\/\/\S+)/i.exec(i)?.[1],e=/enter the code:\s*(\S+)/i.exec(i)?.[1];n||!a||!e||(n=!0,t({url:a,code:e}))}})}catch(l){throw new u("CLOUDFLARE_LOGIN_FAILED",l instanceof C?`Cloudflare login timed out after ${E(m)}
|
|
6
|
+
Or set CLOUDFLARE_API_TOKEN and CLOUDFLARE_ACCOUNT_ID.`:`Cloudflare login didn't complete
|
|
7
|
+
${h(l)}`,{retryable:!0,rerun:`${c} login`})}}async function P({whoami:o,flag:t,interactive:i}){let n=(o.accounts??[]).map(e=>({id:e.id,name:e.name??null})),l=e=>n.find(r=>r.id===e)??{id:e,name:null},a=t||process.env.CLOUDFLARE_ACCOUNT_ID||void 0;if(a){if(n.length>0&&!n.some(e=>e.id===a)){let e=Math.max(...n.map(r=>(r.name??r.id).length));throw new u("ACCOUNT_NOT_ACCESSIBLE",[`${o.email??"This login"} can't use Cloudflare account ${a}`,"Accounts this login can use:",...n.map(r=>` ${(r.name??r.id).padEnd(e)} ${r.id}`)].join(`
|
|
8
|
+
`),{rerun:`${c} login`,fix:"pass one of these with --account-id, or log in as someone else"})}return l(a)}if(n.length===1)return n[0];if(n.length===0)throw new u("ACCOUNT_REQUIRED",`This Cloudflare login can't list any accounts
|
|
9
|
+
The account id is in your dashboard URL: dash.cloudflare.com/<account-id>/\u2026`,{fix:"pass --account-id, or set CLOUDFLARE_ACCOUNT_ID"});if(!i)throw new s("choose_account",`Choose the Cloudflare account to install in
|
|
10
|
+
${o.email??"This login"} can use ${n.length} accounts. Run one of:`,void 0,{rerun:null,data:{choices:n.map(e=>({accountId:e.id,accountName:e.name,label:e.name,rerun:g(["--account-id",e.id])}))}});return A("Which account should the Gateway go in?",n.map(e=>({label:e.name??e.id,value:e})),{context:[`${o.email??"This login"} can use ${n.length} Cloudflare accounts`]})}export{_ as a,x as b,F as c,S as d,w as e,P as f};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{Vb as a,yb as c,zb as u}from"./chunk-SAT3PGZU.js";import{z as i}from"zod";var f=i.looseObject({enabled:i.boolean(),name:i.string().nullish(),status:i.string().nullish()}),p=i.looseObject({type:i.string(),field:i.string().nullish(),value:i.string().nullish()}),d=i.looseObject({type:i.string(),value:i.array(i.string()).nullish()}),l=i.looseObject({id:i.string().nullish(),tag:i.string().nullish(),name:i.string().nullish(),enabled:i.boolean().nullish(),matchers:i.array(p).nullish(),actions:i.array(d).nullish()}).transform(n=>({id:n.id??n.tag??null,name:n.name??null,enabled:n.enabled??!0,matchers:n.matchers??[],actions:n.actions??[]})),y=i.array(l),g=50,h=10;function C(n,t){return a(n,{plane:"account",args:["email-routing","settings","get","-z",t]},f)}async function x(n,t,e){await n.run({plane:"account",mode:"json",args:["email-routing","enable","-z",t,"--name",e]})}async function j(n,t){await n.run({plane:"account",mode:"json",args:["email-routing","disable","-z",t,"--force"]})}async function z(n,t){let e=new Map;for(let r=1;r<=h;r+=1){let o=await a(n,{plane:"account",args:["email-routing","rules","list-account","-z",t,"--per-page",String(g),"--page",String(r)]},y),m=e.size;for(let[R,s]of o.entries())e.set(s.id??`${r}:${R}`,s);if(o.length<g||e.size===m)break}return[...e.values()]}async function P(n,t,e){try{return await a(n,{plane:"account",args:["email-routing","rules","get",e,"-z",t]},l)}catch(r){if(u(r,"not_found"))return null;throw r}}async function v(n,t,e){let r=await a(n,{plane:"account",files:{"rule.json":e},args:o=>["email-routing","rules","create","-z",t,"--body",`@${o["rule.json"]}`]},l);if(!r.id)throw new c({message:"cf email-routing rules create answered without the new rule's id.",apiCodes:[],kind:"unknown"},{exitCode:0,stderr:""});return r.id}async function A(n,t,e,r){await n.run({plane:"account",mode:"json",files:{"rule.json":r},args:o=>["email-routing","rules","update",e,"-z",t,"--body",`@${o["rule.json"]}`]})}async function O(n,t,e){try{return await n.run({plane:"account",mode:"json",args:["email-routing","rules","delete",e,"-z",t,"--force"]}),!0}catch(r){if(u(r,"not_found"))return!1;throw r}}function S(n,t){return a(n,{plane:"account",args:["email-routing","rules","catch-all","get","-z",t]},l)}async function k(n,t,e){await n.run({plane:"account",mode:"json",files:{"catch-all.json":e},args:r=>["email-routing","rules","catch-all","update","-z",t,"--body",`@${r["catch-all.json"]}`]})}function $(n){return n.actions.find(e=>e.type==="worker")?.value?.[0]??null}function B(n){let t=n.matchers.find(e=>e.type==="literal"&&(e.field??"to")==="to");return t?.value?t.value.toLowerCase():null}export{C as a,x as b,j as c,z as d,P as e,v as f,A as g,O as h,S as i,k as j,$ as k,B as l};
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
import o from"node:fs/promises";import t from"node:path";var i=["No cloudflare.config.ts in this app","Every App apps build their Worker in a cloudflare.config.ts at the app root:","",' import { defineConfig } from "cf/config";',' import { everyAppWorker } from "@every-app/sdk/cloudflare";',' import * as entrypoint from "./src/entry.worker.ts" with { type: "cf-worker" };',' import manifest from "./everyapp.config.ts";',""," export default defineConfig((ctx) => ({"," worker: everyAppWorker({ manifest, entrypoint, ctx }),"," }));","","starter/ has the full setup (package.json, vite.config.ts)."].join(`
|
|
2
|
+
`);async function s(e){try{let r=await o.readFile(t.join(e,"cloudflare.config.ts"),"utf8");return{usesEveryAppWorker:r.includes("everyAppWorker"),hasCrons:/\bcrons\s*:/.test(r)}}catch{return null}}export{i as a,s as b};
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import{createHash as d,createHmac as N}from"node:crypto";var l="https://gateway.dev.localhost";var I=`-----BEGIN PRIVATE KEY-----
|
|
2
|
+
MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQCHjTNZ/5Aresl0
|
|
3
|
+
xM2jL5cX2LJ1XmtpZJ4S3gNfJ5j3xzwhkdGPLZRdpph6PB55tGy/0DP5tm4vdx8n
|
|
4
|
+
QTuk4Z3hUI6JIbUGMmCWZMLXCFXgx3qqEsNU4/qLO1QlLEPCeVHzlS07I0ngbl1h
|
|
5
|
+
jpGsBaU8wxc9Jh0ZaoA/iflBcDD7u5MWYkx1bLVbwottOP/81IafcMKb4RkkgLyr
|
|
6
|
+
3IOExJwzR6MmcFUKiW+nhPyTx23aRga7ZZ3t0Iyse/+XFSioPnxq+l0w7Ntpm3Cx
|
|
7
|
+
DsEBohqYh5DUArGacKPWenbe5a9hCahpmhy+6ktIAsrt9YZTJUNn5Fbge03kqrNn
|
|
8
|
+
Kl+LJnyRAgMBAAECggEABCi9GAB3URw3APgWarDHwS2vGRqU72KM1p2dCx8FCqpA
|
|
9
|
+
cjO+Ezd171Mwp8R/N2MFuLN32sxCEH8GU88kuDwLevm8q+C+xBJI5ChykYRCFU/t
|
|
10
|
+
l7kUaP8HRZ0kCXF0oUuVbATKYt+D8WjVgOwt1FJGhgki5geMukZKKdjvDtbVS+4D
|
|
11
|
+
qGRBV4/XT4Y5JDNrjnITwSV2xfMD6Yd92/NN375+V9vWFI4kaESPbE/YQ7yF1o66
|
|
12
|
+
DfhjRMSMmTgWEeoVDwFMlnXppo1nkdEXY8MXlgho0mDGre4PurAvQmZRYlU6VJ63
|
|
13
|
+
x7/NTaNPnQEJ7+FkUXvtOz8sCBjLzgtilGnBNwGqeQKBgQC7zA7kojSPYvlm7nbC
|
|
14
|
+
L2kO8iAL3p/B1vtS6XLTFiV0Wv2kT6Cy51ulVteUijwGMrDuCMdBqXfIocQvYhls
|
|
15
|
+
JzPR/DaFcE2qClCei9L4wxvdBLcqoQH7LsllGA9oHSoZNnzT0muNech0xuL75X6B
|
|
16
|
+
LLMpVtOyb/prd8N6hhBlcGElCQKBgQC4x8A9aDnFlcyztcutW2YQMfEyDEK+PcuC
|
|
17
|
+
n6cnSJ8MjmFEyulKZuklqKkhwMiNBm8xNhI6UdUtrFPfKmGqYifjEUX4D6xGLL8b
|
|
18
|
+
LNOZojkMAI3jtuD+IGzlpkSCy2TWXVb53TTi82LUD7Sbb5siYhL5uW0IRzbJt1aR
|
|
19
|
+
n2JNphvFSQKBgA1NPNjQ7GwjlIrH5T2H4ice20o78JDoS1DqHCn7bZe6QjD7OuSx
|
|
20
|
+
Inqplgd9axb9TC7wDD0IZeWeH6lDh41zkWYUOUBmXfnnVSKFwOHB4B1dkiPA18UU
|
|
21
|
+
4Ur5002Kk0rJ4zmVs+yHbb1nwPgan0VDB0WsUr5W1CP8jaoGCO9GcHsRAoGAX6Xm
|
|
22
|
+
eOLupLx6DbxZBg99sXxoocN++QL7yU3jNI5+5fz9lKKESCMlJH09r18fcQCXph2b
|
|
23
|
+
Kd0aQF4nvCkwDQZqJzvVwCY8wsZ+1g5KKgizBudyiyErLeCS/f0nEZ0/QUdnskcz
|
|
24
|
+
DRd3XNYUYzFOWGnz8JhvPA3A6oGgqhiaxh7p2SECgYA+7s6WRfQLSad3dXuDNajQ
|
|
25
|
+
sBwG4E6M/yUbgdbNjnv+AuVYS8Uyvf6x/xaWH3zssluIXhod0Two22bjtkPGJ2nx
|
|
26
|
+
1ZXmbxSdWVGwLZn3GYRoRu6X6VGTbFAaK1mb7KDfwjoaauV7G3A2mw6M5xxg4zx/
|
|
27
|
+
hsbx0DA4sMMIUEniw9W/YA==
|
|
28
|
+
-----END PRIVATE KEY-----
|
|
29
|
+
`;var o=Object.freeze({workerName:"every-hosted--sentinel",organizationId:"everyapp-hosted-deploy-sentinel",gatewayUrl:"https://every-hosted--sentinel.invalid",publicKey:`-----BEGIN PUBLIC KEY-----
|
|
30
|
+
EVERYAPPHOSTEDDEPLOYSENTINEL
|
|
31
|
+
-----END PUBLIC KEY-----
|
|
32
|
+
`});function i(t){return`${o.workerName}--${t}`}function a(t){let r=(e,E)=>Object.fromEntries((e??[]).map(s=>[s,E(i(s))])),{resources:n}=t;return{workerName:o.workerName,organizationId:o.organizationId,gatewayUrl:o.gatewayUrl,identityPublicKeys:[o.publicKey],resources:{d1:r(n?.d1,e=>({name:e,id:e})),kv:r(n?.kv,e=>({id:e})),hyperdrive:r(n?.hyperdrive?.map(e=>e.name),e=>({id:e})),r2:r(n?.r2,e=>({name:e}))}}}var u=Object.freeze({enabled:!0,headSamplingRate:1,redactQueryString:!0,logs:Object.freeze({enabled:!0,invocationLogs:!0,persist:!0,headSamplingRate:1}),traces:Object.freeze({enabled:!0,persist:!0,headSamplingRate:.1}),issues:Object.freeze({enabled:!0})});var c=63;function f(t,r){let n=`${t}--${r}`;if(n.length>c)throw new Error(`Helper Worker ${n} is longer than Cloudflare's ${c} characters; shorten its name in everyapp.config.ts.`);return n}function p(t,r){return`${t}--${r.toLowerCase().replaceAll("_","-")}`}function _(t,r){return d("sha256").update(`${t}:${r}`).digest("hex").slice(0,32)}export{l as a,I as b,o as c,i as d,a as e,u as f,f as g,p as h,_ as i};
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
var s=`CREATE TABLE IF NOT EXISTS _everyapp_access (
|
|
2
|
+
id TEXT PRIMARY KEY CHECK (id = 'access'),
|
|
3
|
+
team_domain TEXT NOT NULL,
|
|
4
|
+
gateway_aud TEXT NOT NULL,
|
|
5
|
+
apps_aud TEXT NOT NULL,
|
|
6
|
+
written_at INTEGER NOT NULL
|
|
7
|
+
)`;async function r(t){let[a=[]]=await t.run([{sql:"SELECT name FROM sqlite_master WHERE type = 'table' AND name = '_everyapp_access'"}]);if(a.length===0)return null;let[n=[]]=await t.run([{sql:"SELECT team_domain, gateway_aud, apps_aud, written_at FROM _everyapp_access WHERE id = 'access'"}]),e=n[0];return e?{teamDomain:String(e.team_domain),gatewayAud:String(e.gateway_aud),appsAud:String(e.apps_aud),writtenAt:Number(e.written_at)}:null}async function o(t,a,n=[]){await t.run([{sql:s},{sql:`INSERT INTO _everyapp_access (id, team_domain, gateway_aud, apps_aud, written_at)
|
|
8
|
+
VALUES ('access', ?1, ?2, ?3, ?4)
|
|
9
|
+
ON CONFLICT(id) DO UPDATE SET team_domain = excluded.team_domain,
|
|
10
|
+
gateway_aud = excluded.gateway_aud, apps_aud = excluded.apps_aud, written_at = excluded.written_at`,params:[a.teamDomain,a.gatewayAud,a.appsAud,a.writtenAt]},...n])}async function d(t,a=[]){await t.run([{sql:s},{sql:"DELETE FROM _everyapp_access WHERE id = 'access'"},...a])}function u(t,a){return t.teamDomain===a.teamDomain&&t.gatewayAud===a.gatewayAud&&t.appsAud===a.appsAud}var i=["CLOUDFLARE_ACCESS_TEAM_DOMAIN","CLOUDFLARE_ACCESS_APPS_AUD","CLOUDFLARE_ACCESS_AUD"];function c(t){return i.every(a=>t.includes(a))}function p(t,a){return{on:c(t),teamDomain:a?.teamDomain??null}}export{r as a,o as b,d as c,u as d,i as e,p as f};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{Pb as e}from"./chunk-SAT3PGZU.js";import t from"node:path";var n=".cloudflare/types/index.d.ts";async function p(r,o){await r.run({args:["workers","types"],plane:"project",cwd:o,mode:"text"})}async function a(r){return e(t.join(r,n))}export{p as a,a as b};
|