convex 1.42.2 → 1.43.0-alpha.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +8 -1
- package/bin/main-dev +6 -1
- package/dist/browser.bundle.js +49 -10
- package/dist/browser.bundle.js.map +2 -2
- package/dist/cjs/browser/index.js.map +2 -2
- package/dist/cjs/browser/simple_client-node.js +35 -35
- package/dist/cjs/browser/simple_client-node.js.map +2 -2
- package/dist/cjs/browser/sync/client.js.map +1 -1
- package/dist/cjs/browser/sync/paginated_query_client.js +20 -9
- package/dist/cjs/browser/sync/paginated_query_client.js.map +2 -2
- package/dist/cjs/cli/codegen_templates/component_api.js +2 -2
- package/dist/cjs/cli/codegen_templates/component_api.js.map +2 -2
- package/dist/cjs/cli/codegen_templates/validator_helpers.js +2 -0
- package/dist/cjs/cli/codegen_templates/validator_helpers.js.map +2 -2
- package/dist/cjs/cli/deployment.js +2 -1
- package/dist/cjs/cli/deployment.js.map +2 -2
- package/dist/cjs/cli/deploymentCreate.js.map +2 -2
- package/dist/cjs/cli/generatedApi.js.map +1 -1
- package/dist/cjs/cli/lib/deployApi/validator.js +1 -0
- package/dist/cjs/cli/lib/deployApi/validator.js.map +2 -2
- package/dist/cjs/cli/lib/deploymentSelection.js.map +2 -2
- package/dist/cjs/cli/lib/generateDocs.js +1 -1
- package/dist/cjs/cli/lib/generateDocs.js.map +2 -2
- package/dist/cjs/cli/lib/generatedFunctionLogsApi.js.map +1 -1
- package/dist/cjs/cli/lib/localDeployment/projectMismatch.js.map +2 -2
- package/dist/cjs/cli/lib/login.js +23 -23
- package/dist/cjs/cli/lib/login.js.map +2 -2
- package/dist/cjs/cli/lib/typecheck.js +28 -25
- package/dist/cjs/cli/lib/typecheck.js.map +2 -2
- package/dist/cjs/cli/lib/usageLimits.js +164 -0
- package/dist/cjs/cli/lib/usageLimits.js.map +7 -0
- package/dist/cjs/cli/usageLimits.js +326 -0
- package/dist/cjs/cli/usageLimits.js.map +7 -0
- package/dist/cjs/index.js +1 -1
- package/dist/cjs/index.js.map +1 -1
- package/dist/cjs/react/client.js.map +2 -2
- package/dist/cjs/server/components/index.js.map +2 -2
- package/dist/cjs/server/cron.js +33 -29
- package/dist/cjs/server/cron.js.map +2 -2
- package/dist/cjs/server/database.js.map +1 -1
- package/dist/cjs/server/impl/database_impl.js +3 -0
- package/dist/cjs/server/impl/database_impl.js.map +2 -2
- package/dist/cjs/server/log.js +2 -1
- package/dist/cjs/server/log.js.map +2 -2
- package/dist/cjs/server/logVars.js +12 -1
- package/dist/cjs/server/logVars.js.map +2 -2
- package/dist/cjs/server/meta.js.map +1 -1
- package/dist/cjs/values/compare.js +5 -1
- package/dist/cjs/values/compare.js.map +2 -2
- package/dist/cjs/values/index.js +1 -0
- package/dist/cjs/values/index.js.map +2 -2
- package/dist/cjs/values/size.js +4 -0
- package/dist/cjs/values/size.js.map +2 -2
- package/dist/cjs/values/validator.js +11 -0
- package/dist/cjs/values/validator.js.map +2 -2
- package/dist/cjs/values/validators.js +20 -0
- package/dist/cjs/values/validators.js.map +2 -2
- package/dist/cjs/values/value.js +31 -0
- package/dist/cjs/values/value.js.map +2 -2
- package/dist/cjs-types/browser/index.d.ts.map +1 -1
- package/dist/cjs-types/browser/sync/paginated_query_client.d.ts +1 -38
- package/dist/cjs-types/browser/sync/paginated_query_client.d.ts.map +1 -1
- package/dist/cjs-types/cli/codegen_templates/component_api.d.ts.map +1 -1
- package/dist/cjs-types/cli/codegen_templates/validator_helpers.d.ts.map +1 -1
- package/dist/cjs-types/cli/codegen_templates/validator_helpers.test.d.ts +2 -0
- package/dist/cjs-types/cli/codegen_templates/validator_helpers.test.d.ts.map +1 -0
- package/dist/cjs-types/cli/deployment.d.ts.map +1 -1
- package/dist/cjs-types/cli/deploymentCreate.d.ts +2 -2
- package/dist/cjs-types/cli/generatedApi.d.ts +43 -43
- package/dist/cjs-types/cli/generatedApi.d.ts.map +1 -1
- package/dist/cjs-types/cli/lib/deployApi/validator.d.ts +6 -0
- package/dist/cjs-types/cli/lib/deployApi/validator.d.ts.map +1 -1
- package/dist/cjs-types/cli/lib/deploymentSelection.d.ts +2 -2
- package/dist/cjs-types/cli/lib/deploymentSelection.d.ts.map +1 -1
- package/dist/cjs-types/cli/lib/generatedFunctionLogsApi.d.ts +45 -45
- package/dist/cjs-types/cli/lib/generatedFunctionLogsApi.d.ts.map +1 -1
- package/dist/cjs-types/cli/lib/localDeployment/projectMismatch.d.ts +2 -2
- package/dist/cjs-types/cli/lib/localDeployment/projectMismatch.d.ts.map +1 -1
- package/dist/cjs-types/cli/lib/login.d.ts.map +1 -1
- package/dist/cjs-types/cli/lib/mcp/tools/insights.d.ts +24 -24
- package/dist/cjs-types/cli/lib/typecheck.d.ts +2 -0
- package/dist/cjs-types/cli/lib/typecheck.d.ts.map +1 -1
- package/dist/cjs-types/cli/lib/typecheck.test.d.ts +2 -0
- package/dist/cjs-types/cli/lib/typecheck.test.d.ts.map +1 -0
- package/dist/cjs-types/cli/lib/usageLimits.d.ts +46 -0
- package/dist/cjs-types/cli/lib/usageLimits.d.ts.map +1 -0
- package/dist/cjs-types/cli/usageLimits.d.ts +22 -0
- package/dist/cjs-types/cli/usageLimits.d.ts.map +1 -0
- package/dist/cjs-types/index.d.ts +1 -1
- package/dist/cjs-types/index.d.ts.map +1 -1
- package/dist/cjs-types/react/client.d.ts.map +1 -1
- package/dist/cjs-types/server/components/index.d.ts +26 -8
- package/dist/cjs-types/server/components/index.d.ts.map +1 -1
- package/dist/cjs-types/server/cron.d.ts +20 -11
- package/dist/cjs-types/server/cron.d.ts.map +1 -1
- package/dist/cjs-types/server/cron.test.d.ts +2 -0
- package/dist/cjs-types/server/cron.test.d.ts.map +1 -0
- package/dist/cjs-types/server/database.d.ts.map +1 -1
- package/dist/cjs-types/server/impl/database_impl.d.ts.map +1 -1
- package/dist/cjs-types/server/log.d.ts.map +1 -1
- package/dist/cjs-types/server/logVars.d.ts +14 -1
- package/dist/cjs-types/server/logVars.d.ts.map +1 -1
- package/dist/cjs-types/server/meta.d.ts +2 -2
- package/dist/cjs-types/server/meta.d.ts.map +1 -1
- package/dist/cjs-types/values/compare.d.ts.map +1 -1
- package/dist/cjs-types/values/index.d.ts +2 -2
- package/dist/cjs-types/values/index.d.ts.map +1 -1
- package/dist/cjs-types/values/size.d.ts +1 -1
- package/dist/cjs-types/values/size.d.ts.map +1 -1
- package/dist/cjs-types/values/validator.d.ts +10 -1
- package/dist/cjs-types/values/validator.d.ts.map +1 -1
- package/dist/cjs-types/values/validators.d.ts +14 -3
- package/dist/cjs-types/values/validators.d.ts.map +1 -1
- package/dist/cjs-types/values/value.d.ts +18 -1
- package/dist/cjs-types/values/value.d.ts.map +1 -1
- package/dist/cli.bundle.cjs +2327 -1866
- package/dist/cli.bundle.cjs.map +4 -4
- package/dist/esm/browser/index.js.map +2 -2
- package/dist/esm/browser/simple_client-node.js +35 -35
- package/dist/esm/browser/simple_client-node.js.map +1 -1
- package/dist/esm/browser/sync/client.js.map +1 -1
- package/dist/esm/browser/sync/paginated_query_client.js +20 -9
- package/dist/esm/browser/sync/paginated_query_client.js.map +2 -2
- package/dist/esm/cli/codegen_templates/component_api.js +8 -3
- package/dist/esm/cli/codegen_templates/component_api.js.map +2 -2
- package/dist/esm/cli/codegen_templates/validator_helpers.js +2 -0
- package/dist/esm/cli/codegen_templates/validator_helpers.js.map +2 -2
- package/dist/esm/cli/deployment.js +2 -1
- package/dist/esm/cli/deployment.js.map +2 -2
- package/dist/esm/cli/deploymentCreate.js.map +2 -2
- package/dist/esm/cli/lib/deployApi/validator.js +1 -0
- package/dist/esm/cli/lib/deployApi/validator.js.map +2 -2
- package/dist/esm/cli/lib/deploymentSelection.js.map +2 -2
- package/dist/esm/cli/lib/generateDocs.js +1 -1
- package/dist/esm/cli/lib/generateDocs.js.map +2 -2
- package/dist/esm/cli/lib/localDeployment/projectMismatch.js.map +2 -2
- package/dist/esm/cli/lib/login.js +23 -23
- package/dist/esm/cli/lib/login.js.map +2 -2
- package/dist/esm/cli/lib/typecheck.js +27 -25
- package/dist/esm/cli/lib/typecheck.js.map +2 -2
- package/dist/esm/cli/lib/usageLimits.js +129 -0
- package/dist/esm/cli/lib/usageLimits.js.map +7 -0
- package/dist/esm/cli/usageLimits.js +316 -0
- package/dist/esm/cli/usageLimits.js.map +7 -0
- package/dist/esm/index.js +1 -1
- package/dist/esm/index.js.map +1 -1
- package/dist/esm/react/client.js.map +2 -2
- package/dist/esm/server/components/index.js.map +2 -2
- package/dist/esm/server/cron.js +33 -29
- package/dist/esm/server/cron.js.map +2 -2
- package/dist/esm/server/impl/database_impl.js +4 -1
- package/dist/esm/server/impl/database_impl.js.map +2 -2
- package/dist/esm/server/log.js +3 -2
- package/dist/esm/server/log.js.map +2 -2
- package/dist/esm/server/logVars.js +11 -1
- package/dist/esm/server/logVars.js.map +2 -2
- package/dist/esm/values/compare.js +5 -1
- package/dist/esm/values/compare.js.map +2 -2
- package/dist/esm/values/index.js +1 -1
- package/dist/esm/values/index.js.map +2 -2
- package/dist/esm/values/size.js +4 -0
- package/dist/esm/values/size.js.map +2 -2
- package/dist/esm/values/validator.js +12 -0
- package/dist/esm/values/validator.js.map +2 -2
- package/dist/esm/values/validators.js +19 -0
- package/dist/esm/values/validators.js.map +2 -2
- package/dist/esm/values/value.js +29 -1
- package/dist/esm/values/value.js.map +2 -2
- package/dist/esm-types/browser/index.d.ts.map +1 -1
- package/dist/esm-types/browser/sync/paginated_query_client.d.ts +1 -38
- package/dist/esm-types/browser/sync/paginated_query_client.d.ts.map +1 -1
- package/dist/esm-types/cli/codegen_templates/component_api.d.ts.map +1 -1
- package/dist/esm-types/cli/codegen_templates/validator_helpers.d.ts.map +1 -1
- package/dist/esm-types/cli/codegen_templates/validator_helpers.test.d.ts +2 -0
- package/dist/esm-types/cli/codegen_templates/validator_helpers.test.d.ts.map +1 -0
- package/dist/esm-types/cli/deployment.d.ts.map +1 -1
- package/dist/esm-types/cli/deploymentCreate.d.ts +2 -2
- package/dist/esm-types/cli/generatedApi.d.ts +43 -43
- package/dist/esm-types/cli/generatedApi.d.ts.map +1 -1
- package/dist/esm-types/cli/lib/deployApi/validator.d.ts +6 -0
- package/dist/esm-types/cli/lib/deployApi/validator.d.ts.map +1 -1
- package/dist/esm-types/cli/lib/deploymentSelection.d.ts +2 -2
- package/dist/esm-types/cli/lib/deploymentSelection.d.ts.map +1 -1
- package/dist/esm-types/cli/lib/generatedFunctionLogsApi.d.ts +45 -45
- package/dist/esm-types/cli/lib/generatedFunctionLogsApi.d.ts.map +1 -1
- package/dist/esm-types/cli/lib/localDeployment/projectMismatch.d.ts +2 -2
- package/dist/esm-types/cli/lib/localDeployment/projectMismatch.d.ts.map +1 -1
- package/dist/esm-types/cli/lib/login.d.ts.map +1 -1
- package/dist/esm-types/cli/lib/mcp/tools/insights.d.ts +24 -24
- package/dist/esm-types/cli/lib/typecheck.d.ts +2 -0
- package/dist/esm-types/cli/lib/typecheck.d.ts.map +1 -1
- package/dist/esm-types/cli/lib/typecheck.test.d.ts +2 -0
- package/dist/esm-types/cli/lib/typecheck.test.d.ts.map +1 -0
- package/dist/esm-types/cli/lib/usageLimits.d.ts +46 -0
- package/dist/esm-types/cli/lib/usageLimits.d.ts.map +1 -0
- package/dist/esm-types/cli/usageLimits.d.ts +22 -0
- package/dist/esm-types/cli/usageLimits.d.ts.map +1 -0
- package/dist/esm-types/index.d.ts +1 -1
- package/dist/esm-types/index.d.ts.map +1 -1
- package/dist/esm-types/react/client.d.ts.map +1 -1
- package/dist/esm-types/server/components/index.d.ts +26 -8
- package/dist/esm-types/server/components/index.d.ts.map +1 -1
- package/dist/esm-types/server/cron.d.ts +20 -11
- package/dist/esm-types/server/cron.d.ts.map +1 -1
- package/dist/esm-types/server/cron.test.d.ts +2 -0
- package/dist/esm-types/server/cron.test.d.ts.map +1 -0
- package/dist/esm-types/server/database.d.ts.map +1 -1
- package/dist/esm-types/server/impl/database_impl.d.ts.map +1 -1
- package/dist/esm-types/server/log.d.ts.map +1 -1
- package/dist/esm-types/server/logVars.d.ts +14 -1
- package/dist/esm-types/server/logVars.d.ts.map +1 -1
- package/dist/esm-types/server/meta.d.ts +2 -2
- package/dist/esm-types/server/meta.d.ts.map +1 -1
- package/dist/esm-types/values/compare.d.ts.map +1 -1
- package/dist/esm-types/values/index.d.ts +2 -2
- package/dist/esm-types/values/index.d.ts.map +1 -1
- package/dist/esm-types/values/size.d.ts +1 -1
- package/dist/esm-types/values/size.d.ts.map +1 -1
- package/dist/esm-types/values/validator.d.ts +10 -1
- package/dist/esm-types/values/validator.d.ts.map +1 -1
- package/dist/esm-types/values/validators.d.ts +14 -3
- package/dist/esm-types/values/validators.d.ts.map +1 -1
- package/dist/esm-types/values/value.d.ts +18 -1
- package/dist/esm-types/values/value.d.ts.map +1 -1
- package/dist/react.bundle.js +53 -11
- package/dist/react.bundle.js.map +2 -2
- package/package.json +8 -8
- package/schemas/convex.schema.json +2 -1
- package/src/browser/index.ts +2 -0
- package/src/browser/sync/client.test.ts +8 -1
- package/src/browser/sync/client.ts +63 -0
- package/src/browser/sync/paginated_query_client.test.ts +209 -1
- package/src/browser/sync/paginated_query_client.ts +29 -11
- package/src/cli/codegen_templates/component_api.ts +8 -3
- package/src/cli/codegen_templates/validator_helpers.test.ts +31 -0
- package/src/cli/codegen_templates/validator_helpers.ts +6 -0
- package/src/cli/deployment.ts +4 -1
- package/src/cli/deploymentCreate.test.ts +2 -2
- package/src/cli/deploymentCreate.ts +2 -2
- package/src/cli/generatedApi.ts +43 -43
- package/src/cli/lib/deployApi/validator.ts +1 -0
- package/src/cli/lib/deploymentSelection.ts +2 -2
- package/src/cli/lib/generateDocs.test.ts +1 -1
- package/src/cli/lib/generateDocs.ts +3 -3
- package/src/cli/lib/generatedFunctionLogsApi.ts +45 -45
- package/src/cli/lib/localDeployment/projectMismatch.ts +2 -2
- package/src/cli/lib/login.ts +33 -30
- package/src/cli/lib/typecheck.test.ts +71 -0
- package/src/cli/lib/typecheck.ts +33 -27
- package/src/cli/lib/usageLimits.ts +242 -0
- package/src/cli/usageLimits.ts +420 -0
- package/src/index.ts +1 -1
- package/src/react/ConvexAuthState.test.tsx +24 -8
- package/src/react/auth_websocket.test.tsx +39 -29
- package/src/react/client.ts +3 -2
- package/src/react/client_provided_base_client.test.tsx +154 -36
- package/src/server/audit_logging.test.ts +2 -0
- package/src/server/components/index.test.ts +33 -1
- package/src/server/components/index.ts +41 -14
- package/src/server/cron.test.ts +58 -0
- package/src/server/cron.ts +82 -21
- package/src/server/database.ts +17 -0
- package/src/server/impl/database_impl.ts +4 -1
- package/src/server/log.ts +4 -1
- package/src/server/logVars.ts +17 -1
- package/src/server/meta.ts +2 -2
- package/src/server/schema.test.ts +6 -1
- package/src/values/compare.ts +5 -2
- package/src/values/index.ts +2 -1
- package/src/values/size.test.ts +5 -0
- package/src/values/size.ts +5 -1
- package/src/values/validator.test.ts +16 -1
- package/src/values/validator.ts +13 -0
- package/src/values/validators.ts +29 -1
- package/src/values/value.test.ts +35 -0
- package/src/values/value.ts +56 -1
package/src/cli/lib/typecheck.ts
CHANGED
|
@@ -14,6 +14,7 @@ import * as semver from "semver";
|
|
|
14
14
|
import { formatDuration, spawnAsync } from "./utils/utils.js";
|
|
15
15
|
import { readProjectConfig } from "./config.js";
|
|
16
16
|
import { WatchContext } from "./watch.js";
|
|
17
|
+
import { Filesystem } from "../../bundler/fs.js";
|
|
17
18
|
|
|
18
19
|
export type TypecheckResult = "cantTypeCheck" | "success" | "typecheckFailed";
|
|
19
20
|
|
|
@@ -139,33 +140,7 @@ async function runTsc(
|
|
|
139
140
|
tscArgs: string[],
|
|
140
141
|
handleResult: TypecheckResultHandler,
|
|
141
142
|
): Promise<void> {
|
|
142
|
-
|
|
143
|
-
let compilerPath: string | undefined;
|
|
144
|
-
switch (typescriptCompiler) {
|
|
145
|
-
case "tsgo": {
|
|
146
|
-
// @typescript/native-preview@7.0.0-dev.20260626.1 switched to using `bin/tsgo` instead of `bin/tsgo.js`.
|
|
147
|
-
const tsgoPaths = ["tsgo", "tsgo.js"].map((filename) =>
|
|
148
|
-
path.join(
|
|
149
|
-
"node_modules",
|
|
150
|
-
"@typescript",
|
|
151
|
-
"native-preview",
|
|
152
|
-
"bin",
|
|
153
|
-
filename,
|
|
154
|
-
),
|
|
155
|
-
);
|
|
156
|
-
compilerPath = tsgoPaths.find((path) => ctx.fs.exists(path));
|
|
157
|
-
break;
|
|
158
|
-
}
|
|
159
|
-
case "tsc": {
|
|
160
|
-
const tscPath = path.join("node_modules", "typescript", "bin", "tsc");
|
|
161
|
-
if (ctx.fs.exists(tscPath)) {
|
|
162
|
-
compilerPath = tscPath;
|
|
163
|
-
}
|
|
164
|
-
break;
|
|
165
|
-
}
|
|
166
|
-
default:
|
|
167
|
-
typescriptCompiler satisfies never;
|
|
168
|
-
}
|
|
143
|
+
const compilerPath = findTypeScriptCompilerPath(ctx.fs, typescriptCompiler);
|
|
169
144
|
if (!compilerPath) {
|
|
170
145
|
return handleResult("cantTypeCheck", () => {
|
|
171
146
|
logError(
|
|
@@ -197,6 +172,37 @@ async function runTsc(
|
|
|
197
172
|
}
|
|
198
173
|
}
|
|
199
174
|
|
|
175
|
+
export function findTypeScriptCompilerPath(
|
|
176
|
+
fs: Pick<Filesystem, "exists">,
|
|
177
|
+
typescriptCompiler: TypescriptCompiler,
|
|
178
|
+
): string | undefined {
|
|
179
|
+
switch (typescriptCompiler) {
|
|
180
|
+
case "tsgo": {
|
|
181
|
+
// @typescript/native-preview@7.0.0-dev.20260626.1 switched to using `bin/tsgo` instead of `bin/tsgo.js`.
|
|
182
|
+
const tsgoPaths = ["tsgo", "tsgo.js"].map((filename) =>
|
|
183
|
+
path.join(
|
|
184
|
+
"node_modules",
|
|
185
|
+
"@typescript",
|
|
186
|
+
"native-preview",
|
|
187
|
+
"bin",
|
|
188
|
+
filename,
|
|
189
|
+
),
|
|
190
|
+
);
|
|
191
|
+
return tsgoPaths.find((path) => fs.exists(path));
|
|
192
|
+
}
|
|
193
|
+
case "tsc": {
|
|
194
|
+
const tscPaths = [
|
|
195
|
+
// TypeScript 7's recommended alias when the TypeScript 6 API is also installed.
|
|
196
|
+
path.join("node_modules", "@typescript", "native", "bin", "tsc"),
|
|
197
|
+
path.join("node_modules", "typescript", "bin", "tsc"),
|
|
198
|
+
];
|
|
199
|
+
return tscPaths.find((path) => fs.exists(path));
|
|
200
|
+
}
|
|
201
|
+
default:
|
|
202
|
+
typescriptCompiler satisfies never;
|
|
203
|
+
}
|
|
204
|
+
}
|
|
205
|
+
|
|
200
206
|
async function runTscInner(
|
|
201
207
|
ctx: Context,
|
|
202
208
|
tscPath: string,
|
|
@@ -0,0 +1,242 @@
|
|
|
1
|
+
import type {
|
|
2
|
+
GetCurrentUsageResponse,
|
|
3
|
+
UsageLimitConfigRequest,
|
|
4
|
+
UsageLimitConfigResponse,
|
|
5
|
+
UsageLimitMetric,
|
|
6
|
+
} from "@convex-dev/platform/deploymentApi";
|
|
7
|
+
import { Context } from "../../bundler/context.js";
|
|
8
|
+
import { deploymentFetch, logAndHandleFetchError } from "./utils/utils.js";
|
|
9
|
+
|
|
10
|
+
export type UsageLimitDeployment = {
|
|
11
|
+
deploymentUrl: string;
|
|
12
|
+
adminKey: string;
|
|
13
|
+
};
|
|
14
|
+
|
|
15
|
+
export const USAGE_LIMIT_METRICS = [
|
|
16
|
+
"functionCalls",
|
|
17
|
+
"queryMutationComputeGbHours",
|
|
18
|
+
"actionComputeConvexGbHours",
|
|
19
|
+
"actionComputeNodeJsGbHours",
|
|
20
|
+
"actionComputeCpuGbHours",
|
|
21
|
+
"databaseIoGb",
|
|
22
|
+
"searchQueryGb",
|
|
23
|
+
"dataEgressGb",
|
|
24
|
+
] as const satisfies readonly UsageLimitMetric[];
|
|
25
|
+
|
|
26
|
+
// Fails to compile if the backend's `UsageLimitMetric` gains a metric not listed
|
|
27
|
+
// above, so the CLI's `--metric` choices and ordering stay complete.
|
|
28
|
+
type MissingMetric = Exclude<
|
|
29
|
+
UsageLimitMetric,
|
|
30
|
+
(typeof USAGE_LIMIT_METRICS)[number]
|
|
31
|
+
>;
|
|
32
|
+
const _metricsExhaustive: [MissingMetric] extends [never] ? true : never = true;
|
|
33
|
+
void _metricsExhaustive;
|
|
34
|
+
|
|
35
|
+
export const USAGE_LIMIT_WINDOWS = ["day", "month"] as const;
|
|
36
|
+
export type UsageLimitWindow = (typeof USAGE_LIMIT_WINDOWS)[number];
|
|
37
|
+
|
|
38
|
+
export const USAGE_LIMIT_TYPES = ["warning", "disable"] as const;
|
|
39
|
+
export type UsageLimitType = (typeof USAGE_LIMIT_TYPES)[number];
|
|
40
|
+
|
|
41
|
+
export const METRIC_LABELS: Record<UsageLimitMetric, string> = {
|
|
42
|
+
functionCalls: "Function calls",
|
|
43
|
+
queryMutationComputeGbHours: "Query/Mutation compute",
|
|
44
|
+
actionComputeConvexGbHours: "Action compute",
|
|
45
|
+
actionComputeNodeJsGbHours: "Action compute (Node.js)",
|
|
46
|
+
actionComputeCpuGbHours: "Action compute (CPU)",
|
|
47
|
+
databaseIoGb: "Database I/O",
|
|
48
|
+
searchQueryGb: "Search queries",
|
|
49
|
+
dataEgressGb: "Data egress",
|
|
50
|
+
};
|
|
51
|
+
|
|
52
|
+
export function metricLabel(metric: string): string {
|
|
53
|
+
// Look up permissively: a newer backend may report a metric this CLI's label
|
|
54
|
+
// map doesn't know, in which case fall back to the raw id.
|
|
55
|
+
return (METRIC_LABELS as Record<string, string>)[metric] ?? metric;
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
async function usageLimitFetch(
|
|
59
|
+
ctx: Context,
|
|
60
|
+
deployment: UsageLimitDeployment,
|
|
61
|
+
path: string,
|
|
62
|
+
init?: { method?: string; body?: unknown },
|
|
63
|
+
): Promise<unknown> {
|
|
64
|
+
const fetch = deploymentFetch(ctx, deployment);
|
|
65
|
+
try {
|
|
66
|
+
const response = await fetch(`/api/v1${path}`, {
|
|
67
|
+
method: init?.method ?? "GET",
|
|
68
|
+
...(init?.body !== undefined ? { body: JSON.stringify(init.body) } : {}),
|
|
69
|
+
});
|
|
70
|
+
const text = await response.text();
|
|
71
|
+
return text.length > 0 ? JSON.parse(text) : undefined;
|
|
72
|
+
} catch (e) {
|
|
73
|
+
return await logAndHandleFetchError(ctx, e);
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
export async function listUsageLimits(
|
|
78
|
+
ctx: Context,
|
|
79
|
+
deployment: UsageLimitDeployment,
|
|
80
|
+
): Promise<UsageLimitConfigResponse[]> {
|
|
81
|
+
const result = (await usageLimitFetch(
|
|
82
|
+
ctx,
|
|
83
|
+
deployment,
|
|
84
|
+
"/list_usage_limits",
|
|
85
|
+
)) as {
|
|
86
|
+
usageLimits: UsageLimitConfigResponse[];
|
|
87
|
+
};
|
|
88
|
+
return result.usageLimits;
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
export async function createUsageLimit(
|
|
92
|
+
ctx: Context,
|
|
93
|
+
deployment: UsageLimitDeployment,
|
|
94
|
+
config: UsageLimitConfigRequest,
|
|
95
|
+
): Promise<UsageLimitConfigResponse> {
|
|
96
|
+
const result = (await usageLimitFetch(
|
|
97
|
+
ctx,
|
|
98
|
+
deployment,
|
|
99
|
+
"/create_usage_limit",
|
|
100
|
+
{
|
|
101
|
+
method: "POST",
|
|
102
|
+
body: config,
|
|
103
|
+
},
|
|
104
|
+
)) as { usageLimit: UsageLimitConfigResponse };
|
|
105
|
+
return result.usageLimit;
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
export async function updateUsageLimit(
|
|
109
|
+
ctx: Context,
|
|
110
|
+
deployment: UsageLimitDeployment,
|
|
111
|
+
id: string,
|
|
112
|
+
config: UsageLimitConfigRequest,
|
|
113
|
+
): Promise<UsageLimitConfigResponse> {
|
|
114
|
+
const result = (await usageLimitFetch(
|
|
115
|
+
ctx,
|
|
116
|
+
deployment,
|
|
117
|
+
`/update_usage_limit/${id}`,
|
|
118
|
+
{ method: "POST", body: config },
|
|
119
|
+
)) as { usageLimit: UsageLimitConfigResponse };
|
|
120
|
+
return result.usageLimit;
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
export async function deleteUsageLimit(
|
|
124
|
+
ctx: Context,
|
|
125
|
+
deployment: UsageLimitDeployment,
|
|
126
|
+
id: string,
|
|
127
|
+
): Promise<void> {
|
|
128
|
+
await usageLimitFetch(ctx, deployment, `/delete_usage_limit/${id}`, {
|
|
129
|
+
method: "POST",
|
|
130
|
+
});
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
export async function getCurrentUsage(
|
|
134
|
+
ctx: Context,
|
|
135
|
+
deployment: UsageLimitDeployment,
|
|
136
|
+
): Promise<GetCurrentUsageResponse> {
|
|
137
|
+
return (await usageLimitFetch(
|
|
138
|
+
ctx,
|
|
139
|
+
deployment,
|
|
140
|
+
"/get_current_usage",
|
|
141
|
+
)) as GetCurrentUsageResponse;
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
function metricRank(metric: string): number {
|
|
145
|
+
const i = (USAGE_LIMIT_METRICS as readonly string[]).indexOf(metric);
|
|
146
|
+
// Unknown metrics (e.g. a newer backend adds one) sort last, stably.
|
|
147
|
+
return i === -1 ? USAGE_LIMIT_METRICS.length : i;
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
// Windows coarsest-first and warning-before-disable,.
|
|
151
|
+
const windowRank = (w: string) => (w === "month" ? 0 : 1);
|
|
152
|
+
const typeRank = (t: string) => (t === "warning" ? 0 : 1);
|
|
153
|
+
|
|
154
|
+
export function compareUsageLimits(
|
|
155
|
+
a: { metric: string; window: string; limitType: string },
|
|
156
|
+
b: { metric: string; window: string; limitType: string },
|
|
157
|
+
): number {
|
|
158
|
+
return (
|
|
159
|
+
metricRank(a.metric) - metricRank(b.metric) ||
|
|
160
|
+
windowRank(a.window) - windowRank(b.window) ||
|
|
161
|
+
typeRank(a.limitType) - typeRank(b.limitType)
|
|
162
|
+
);
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
export function compareMetricNames(a: string, b: string): number {
|
|
166
|
+
return metricRank(a) - metricRank(b);
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
// A limit annotated with the current usage in its window and whether it's
|
|
170
|
+
// currently triggered.
|
|
171
|
+
export type UsageLimitStatus = UsageLimitConfigResponse & {
|
|
172
|
+
currentUsage: number | null;
|
|
173
|
+
unit: string | null;
|
|
174
|
+
triggered: boolean;
|
|
175
|
+
};
|
|
176
|
+
|
|
177
|
+
function usageInWindow(
|
|
178
|
+
usage: GetCurrentUsageResponse,
|
|
179
|
+
metric: string,
|
|
180
|
+
window: string,
|
|
181
|
+
): number | null {
|
|
182
|
+
const m = usage.metrics[metric];
|
|
183
|
+
if (m === undefined) {
|
|
184
|
+
return null;
|
|
185
|
+
}
|
|
186
|
+
return window === "day" ? m.usage.current_day : m.usage.current_month;
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
// List usage limits annotated with current usage and triggered state, sorted in
|
|
190
|
+
// dashboard order. Fetches the limits and current usage together.
|
|
191
|
+
export async function listUsageLimitsWithStatus(
|
|
192
|
+
ctx: Context,
|
|
193
|
+
deployment: UsageLimitDeployment,
|
|
194
|
+
): Promise<{
|
|
195
|
+
limits: UsageLimitStatus[];
|
|
196
|
+
seedStatus: GetCurrentUsageResponse["seedStatus"];
|
|
197
|
+
}> {
|
|
198
|
+
const [limits, usage] = await Promise.all([
|
|
199
|
+
listUsageLimits(ctx, deployment),
|
|
200
|
+
getCurrentUsage(ctx, deployment),
|
|
201
|
+
]);
|
|
202
|
+
const withStatus = limits
|
|
203
|
+
.map((limit): UsageLimitStatus => {
|
|
204
|
+
const currentUsage = usageInWindow(usage, limit.metric, limit.window);
|
|
205
|
+
const unit = usage.metrics[limit.metric]?.unit ?? null;
|
|
206
|
+
const triggered =
|
|
207
|
+
limit.enabled && currentUsage !== null && currentUsage >= limit.limit;
|
|
208
|
+
return { ...limit, currentUsage, unit, triggered };
|
|
209
|
+
})
|
|
210
|
+
.sort(compareUsageLimits);
|
|
211
|
+
return { limits: withStatus, seedStatus: usage.seedStatus };
|
|
212
|
+
}
|
|
213
|
+
|
|
214
|
+
// A usage limit is uniquely identified by (metric, window, limitType) — the
|
|
215
|
+
// same key the backend enforces uniqueness on. The HTTP API addresses limits by
|
|
216
|
+
// document id, so callers who know the natural key list and resolve it here.
|
|
217
|
+
export type UsageLimitKey = {
|
|
218
|
+
metric: UsageLimitMetric;
|
|
219
|
+
window: string;
|
|
220
|
+
limitType: string;
|
|
221
|
+
};
|
|
222
|
+
|
|
223
|
+
export async function findUsageLimitByKey(
|
|
224
|
+
ctx: Context,
|
|
225
|
+
deployment: UsageLimitDeployment & { deploymentNotice: string },
|
|
226
|
+
key: UsageLimitKey,
|
|
227
|
+
): Promise<UsageLimitConfigResponse> {
|
|
228
|
+
const match = (await listUsageLimits(ctx, deployment)).find(
|
|
229
|
+
(limit) =>
|
|
230
|
+
limit.metric === key.metric &&
|
|
231
|
+
limit.window === key.window &&
|
|
232
|
+
limit.limitType === key.limitType,
|
|
233
|
+
);
|
|
234
|
+
if (match === undefined) {
|
|
235
|
+
return ctx.crash({
|
|
236
|
+
exitCode: 1,
|
|
237
|
+
errorType: "fatal",
|
|
238
|
+
printedMessage: `error: No ${key.limitType} usage limit on ${key.metric} per ${key.window}${deployment.deploymentNotice}.`,
|
|
239
|
+
});
|
|
240
|
+
}
|
|
241
|
+
return match;
|
|
242
|
+
}
|