convex 1.42.3 → 1.43.0-alpha.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/bin/main-dev +6 -1
- package/dist/browser.bundle.js +49 -10
- package/dist/browser.bundle.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/paginated_query_client.js +20 -9
- package/dist/cjs/browser/sync/paginated_query_client.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/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/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/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/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 +14 -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/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 +2534 -2009
- package/dist/cli.bundle.cjs.map +4 -4
- 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/paginated_query_client.js +20 -9
- package/dist/esm/browser/sync/paginated_query_client.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/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/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/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 +14 -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/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 +9 -10
- package/schemas/convex.schema.json +2 -1
- package/src/browser/sync/paginated_query_client.test.ts +209 -1
- package/src/browser/sync/paginated_query_client.ts +26 -9
- 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/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 +15 -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/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
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../../../src/cli/lib/usageLimits.ts"],
|
|
4
|
+
"sourcesContent": ["import type {\n GetCurrentUsageResponse,\n UsageLimitConfigRequest,\n UsageLimitConfigResponse,\n UsageLimitMetric,\n} from \"@convex-dev/platform/deploymentApi\";\nimport { Context } from \"../../bundler/context.js\";\nimport { deploymentFetch, logAndHandleFetchError } from \"./utils/utils.js\";\n\nexport type UsageLimitDeployment = {\n deploymentUrl: string;\n adminKey: string;\n};\n\nexport const USAGE_LIMIT_METRICS = [\n \"functionCalls\",\n \"queryMutationComputeGbHours\",\n \"actionComputeConvexGbHours\",\n \"actionComputeNodeJsGbHours\",\n \"actionComputeCpuGbHours\",\n \"databaseIoGb\",\n \"searchQueryGb\",\n \"dataEgressGb\",\n] as const satisfies readonly UsageLimitMetric[];\n\n// Fails to compile if the backend's `UsageLimitMetric` gains a metric not listed\n// above, so the CLI's `--metric` choices and ordering stay complete.\ntype MissingMetric = Exclude<\n UsageLimitMetric,\n (typeof USAGE_LIMIT_METRICS)[number]\n>;\nconst _metricsExhaustive: [MissingMetric] extends [never] ? true : never = true;\nvoid _metricsExhaustive;\n\nexport const USAGE_LIMIT_WINDOWS = [\"day\", \"month\"] as const;\nexport type UsageLimitWindow = (typeof USAGE_LIMIT_WINDOWS)[number];\n\nexport const USAGE_LIMIT_TYPES = [\"warning\", \"disable\"] as const;\nexport type UsageLimitType = (typeof USAGE_LIMIT_TYPES)[number];\n\nexport const METRIC_LABELS: Record<UsageLimitMetric, string> = {\n functionCalls: \"Function calls\",\n queryMutationComputeGbHours: \"Query/Mutation compute\",\n actionComputeConvexGbHours: \"Action compute\",\n actionComputeNodeJsGbHours: \"Action compute (Node.js)\",\n actionComputeCpuGbHours: \"Action compute (CPU)\",\n databaseIoGb: \"Database I/O\",\n searchQueryGb: \"Search queries\",\n dataEgressGb: \"Data egress\",\n};\n\nexport function metricLabel(metric: string): string {\n // Look up permissively: a newer backend may report a metric this CLI's label\n // map doesn't know, in which case fall back to the raw id.\n return (METRIC_LABELS as Record<string, string>)[metric] ?? metric;\n}\n\nasync function usageLimitFetch(\n ctx: Context,\n deployment: UsageLimitDeployment,\n path: string,\n init?: { method?: string; body?: unknown },\n): Promise<unknown> {\n const fetch = deploymentFetch(ctx, deployment);\n try {\n const response = await fetch(`/api/v1${path}`, {\n method: init?.method ?? \"GET\",\n ...(init?.body !== undefined ? { body: JSON.stringify(init.body) } : {}),\n });\n const text = await response.text();\n return text.length > 0 ? JSON.parse(text) : undefined;\n } catch (e) {\n return await logAndHandleFetchError(ctx, e);\n }\n}\n\nexport async function listUsageLimits(\n ctx: Context,\n deployment: UsageLimitDeployment,\n): Promise<UsageLimitConfigResponse[]> {\n const result = (await usageLimitFetch(\n ctx,\n deployment,\n \"/list_usage_limits\",\n )) as {\n usageLimits: UsageLimitConfigResponse[];\n };\n return result.usageLimits;\n}\n\nexport async function createUsageLimit(\n ctx: Context,\n deployment: UsageLimitDeployment,\n config: UsageLimitConfigRequest,\n): Promise<UsageLimitConfigResponse> {\n const result = (await usageLimitFetch(\n ctx,\n deployment,\n \"/create_usage_limit\",\n {\n method: \"POST\",\n body: config,\n },\n )) as { usageLimit: UsageLimitConfigResponse };\n return result.usageLimit;\n}\n\nexport async function updateUsageLimit(\n ctx: Context,\n deployment: UsageLimitDeployment,\n id: string,\n config: UsageLimitConfigRequest,\n): Promise<UsageLimitConfigResponse> {\n const result = (await usageLimitFetch(\n ctx,\n deployment,\n `/update_usage_limit/${id}`,\n { method: \"POST\", body: config },\n )) as { usageLimit: UsageLimitConfigResponse };\n return result.usageLimit;\n}\n\nexport async function deleteUsageLimit(\n ctx: Context,\n deployment: UsageLimitDeployment,\n id: string,\n): Promise<void> {\n await usageLimitFetch(ctx, deployment, `/delete_usage_limit/${id}`, {\n method: \"POST\",\n });\n}\n\nexport async function getCurrentUsage(\n ctx: Context,\n deployment: UsageLimitDeployment,\n): Promise<GetCurrentUsageResponse> {\n return (await usageLimitFetch(\n ctx,\n deployment,\n \"/get_current_usage\",\n )) as GetCurrentUsageResponse;\n}\n\nfunction metricRank(metric: string): number {\n const i = (USAGE_LIMIT_METRICS as readonly string[]).indexOf(metric);\n // Unknown metrics (e.g. a newer backend adds one) sort last, stably.\n return i === -1 ? USAGE_LIMIT_METRICS.length : i;\n}\n\n// Windows coarsest-first and warning-before-disable,.\nconst windowRank = (w: string) => (w === \"month\" ? 0 : 1);\nconst typeRank = (t: string) => (t === \"warning\" ? 0 : 1);\n\nexport function compareUsageLimits(\n a: { metric: string; window: string; limitType: string },\n b: { metric: string; window: string; limitType: string },\n): number {\n return (\n metricRank(a.metric) - metricRank(b.metric) ||\n windowRank(a.window) - windowRank(b.window) ||\n typeRank(a.limitType) - typeRank(b.limitType)\n );\n}\n\nexport function compareMetricNames(a: string, b: string): number {\n return metricRank(a) - metricRank(b);\n}\n\n// A limit annotated with the current usage in its window and whether it's\n// currently triggered.\nexport type UsageLimitStatus = UsageLimitConfigResponse & {\n currentUsage: number | null;\n unit: string | null;\n triggered: boolean;\n};\n\nfunction usageInWindow(\n usage: GetCurrentUsageResponse,\n metric: string,\n window: string,\n): number | null {\n const m = usage.metrics[metric];\n if (m === undefined) {\n return null;\n }\n return window === \"day\" ? m.usage.current_day : m.usage.current_month;\n}\n\n// List usage limits annotated with current usage and triggered state, sorted in\n// dashboard order. Fetches the limits and current usage together.\nexport async function listUsageLimitsWithStatus(\n ctx: Context,\n deployment: UsageLimitDeployment,\n): Promise<{\n limits: UsageLimitStatus[];\n seedStatus: GetCurrentUsageResponse[\"seedStatus\"];\n}> {\n const [limits, usage] = await Promise.all([\n listUsageLimits(ctx, deployment),\n getCurrentUsage(ctx, deployment),\n ]);\n const withStatus = limits\n .map((limit): UsageLimitStatus => {\n const currentUsage = usageInWindow(usage, limit.metric, limit.window);\n const unit = usage.metrics[limit.metric]?.unit ?? null;\n const triggered =\n limit.enabled && currentUsage !== null && currentUsage >= limit.limit;\n return { ...limit, currentUsage, unit, triggered };\n })\n .sort(compareUsageLimits);\n return { limits: withStatus, seedStatus: usage.seedStatus };\n}\n\n// A usage limit is uniquely identified by (metric, window, limitType) \u2014 the\n// same key the backend enforces uniqueness on. The HTTP API addresses limits by\n// document id, so callers who know the natural key list and resolve it here.\nexport type UsageLimitKey = {\n metric: UsageLimitMetric;\n window: string;\n limitType: string;\n};\n\nexport async function findUsageLimitByKey(\n ctx: Context,\n deployment: UsageLimitDeployment & { deploymentNotice: string },\n key: UsageLimitKey,\n): Promise<UsageLimitConfigResponse> {\n const match = (await listUsageLimits(ctx, deployment)).find(\n (limit) =>\n limit.metric === key.metric &&\n limit.window === key.window &&\n limit.limitType === key.limitType,\n );\n if (match === undefined) {\n return ctx.crash({\n exitCode: 1,\n errorType: \"fatal\",\n printedMessage: `error: No ${key.limitType} usage limit on ${key.metric} per ${key.window}${deployment.deploymentNotice}.`,\n });\n }\n return match;\n}\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
|
+
"names": []
|
|
7
|
+
}
|
|
@@ -0,0 +1,326 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __defProp = Object.defineProperty;
|
|
3
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
5
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
6
|
+
var __export = (target, all) => {
|
|
7
|
+
for (var name in all)
|
|
8
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
9
|
+
};
|
|
10
|
+
var __copyProps = (to, from, except, desc) => {
|
|
11
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
12
|
+
for (let key of __getOwnPropNames(from))
|
|
13
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
14
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
15
|
+
}
|
|
16
|
+
return to;
|
|
17
|
+
};
|
|
18
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
19
|
+
var usageLimits_exports = {};
|
|
20
|
+
__export(usageLimits_exports, {
|
|
21
|
+
usage: () => usage,
|
|
22
|
+
usageLimits: () => usageLimits
|
|
23
|
+
});
|
|
24
|
+
module.exports = __toCommonJS(usageLimits_exports);
|
|
25
|
+
var import_extra_typings = require("@commander-js/extra-typings");
|
|
26
|
+
var import_log = require("../bundler/log.js");
|
|
27
|
+
var import_command = require("./lib/command.js");
|
|
28
|
+
var import_utils = require("./lib/utils/utils.js");
|
|
29
|
+
var import_run = require("./lib/localDeployment/run.js");
|
|
30
|
+
var import_env = require("./env.js");
|
|
31
|
+
var import_usageLimits = require("./lib/usageLimits.js");
|
|
32
|
+
async function parseLimit(ctx, value) {
|
|
33
|
+
const limit = Number(value);
|
|
34
|
+
if (!Number.isInteger(limit) || limit < 1) {
|
|
35
|
+
return ctx.crash({
|
|
36
|
+
exitCode: 1,
|
|
37
|
+
errorType: "fatal",
|
|
38
|
+
printedMessage: `error: --limit must be a positive integer, got "${value}".`
|
|
39
|
+
});
|
|
40
|
+
}
|
|
41
|
+
return limit;
|
|
42
|
+
}
|
|
43
|
+
function formatTable(header, rows, rightAlign = []) {
|
|
44
|
+
const right = new Set(rightAlign);
|
|
45
|
+
const widths = header.map(
|
|
46
|
+
(cell, i) => Math.max(cell.length, ...rows.map((row) => (row[i] ?? "").length))
|
|
47
|
+
);
|
|
48
|
+
const pad = (cell, i) => right.has(i) ? cell.padStart(widths[i]) : cell.padEnd(widths[i]);
|
|
49
|
+
const rule = (left, mid, r) => left + widths.map((w) => "\u2500".repeat(w + 2)).join(mid) + r;
|
|
50
|
+
const line = (cells) => "\u2502 " + cells.map((cell, i) => pad(cell ?? "", i)).join(" \u2502 ") + " \u2502";
|
|
51
|
+
return [
|
|
52
|
+
rule("\u250C", "\u252C", "\u2510"),
|
|
53
|
+
line(header),
|
|
54
|
+
rule("\u251C", "\u253C", "\u2524"),
|
|
55
|
+
...rows.map(line),
|
|
56
|
+
rule("\u2514", "\u2534", "\u2518")
|
|
57
|
+
].join("\n");
|
|
58
|
+
}
|
|
59
|
+
const NUMBER_FORMAT_COMPACT = new Intl.NumberFormat("en-US", {
|
|
60
|
+
notation: "compact",
|
|
61
|
+
compactDisplay: "short",
|
|
62
|
+
maximumFractionDigits: 3
|
|
63
|
+
});
|
|
64
|
+
function formatNumberCompact(value) {
|
|
65
|
+
const formatted = NUMBER_FORMAT_COMPACT.format(value);
|
|
66
|
+
return formatted === "-0" ? "0" : formatted;
|
|
67
|
+
}
|
|
68
|
+
const LIMIT_FORMAT = new Intl.NumberFormat("en-US");
|
|
69
|
+
function formatLimitAmount(value) {
|
|
70
|
+
return LIMIT_FORMAT.format(value);
|
|
71
|
+
}
|
|
72
|
+
const NUMBER_FORMAT = new Intl.NumberFormat("en-US");
|
|
73
|
+
function formatNumber(value) {
|
|
74
|
+
const formatted = NUMBER_FORMAT.format(value);
|
|
75
|
+
return formatted === "-0" ? "0" : formatted;
|
|
76
|
+
}
|
|
77
|
+
function unitFor(amount, unit) {
|
|
78
|
+
return amount === 1 && unit === "calls" ? "call" : unit;
|
|
79
|
+
}
|
|
80
|
+
function formatAmount(value, unit) {
|
|
81
|
+
return unit === null ? formatNumberCompact(value) : `${formatNumberCompact(value)} ${unitFor(value, unit)}`;
|
|
82
|
+
}
|
|
83
|
+
function usageLimitRow(limit) {
|
|
84
|
+
const currentUsage = limit.currentUsage === null ? "\u2014" : `${formatAmount(limit.currentUsage, limit.unit)} (${formatNumber(
|
|
85
|
+
Math.round(limit.currentUsage / limit.limit * 100)
|
|
86
|
+
)}%)`;
|
|
87
|
+
return [
|
|
88
|
+
(0, import_usageLimits.metricLabel)(limit.metric),
|
|
89
|
+
limit.window,
|
|
90
|
+
limit.limitType,
|
|
91
|
+
formatAmount(limit.limit, limit.unit),
|
|
92
|
+
currentUsage,
|
|
93
|
+
limit.enabled ? "yes" : "no",
|
|
94
|
+
limit.triggered ? "yes" : "no"
|
|
95
|
+
];
|
|
96
|
+
}
|
|
97
|
+
const metricOption = new import_extra_typings.Option(
|
|
98
|
+
"--metric <metric>",
|
|
99
|
+
"The metric to limit."
|
|
100
|
+
).choices(import_usageLimits.USAGE_LIMIT_METRICS);
|
|
101
|
+
const windowOption = new import_extra_typings.Option(
|
|
102
|
+
"--window <window>",
|
|
103
|
+
"The window the limit is measured over."
|
|
104
|
+
).choices(import_usageLimits.USAGE_LIMIT_WINDOWS);
|
|
105
|
+
const typeOption = new import_extra_typings.Option(
|
|
106
|
+
"--type <type>",
|
|
107
|
+
"`warning` only notifies; `disable` pauses the deployment when exceeded."
|
|
108
|
+
).choices(import_usageLimits.USAGE_LIMIT_TYPES);
|
|
109
|
+
function seedStatusMessage(seedStatus) {
|
|
110
|
+
return seedStatus === "failed" ? "We couldn't load this deployment's historical usage, so the usage shown below may understate its actual usage. Limits are still enforced going forward." : "Historical usage is still being loaded, so the usage shown below may understate this deployment's actual usage. Check back shortly for accurate totals.";
|
|
111
|
+
}
|
|
112
|
+
const listCmd = new import_extra_typings.Command("list").summary("List configured usage limits").description(
|
|
113
|
+
[
|
|
114
|
+
"List the usage limits configured on your deployment.",
|
|
115
|
+
"",
|
|
116
|
+
"\u2022 List all usage limits: `npx convex deployment usage-limits list`",
|
|
117
|
+
"\u2022 Print as JSON: `npx convex deployment usage-limits list --json`"
|
|
118
|
+
].join("\n")
|
|
119
|
+
).option("--json", "Output the usage limits as JSON.").configureHelp({ showGlobalOptions: true }).allowExcessArguments(false).action(async (cmdOptions, cmd) => {
|
|
120
|
+
const options = cmd.optsWithGlobals();
|
|
121
|
+
const { ctx, deployment } = await (0, import_env.selectEnvDeployment)(options);
|
|
122
|
+
await (0, import_utils.ensureHasConvexDependency)(ctx, "deployment usage-limits list");
|
|
123
|
+
await (0, import_run.withRunningBackend)({
|
|
124
|
+
ctx,
|
|
125
|
+
deployment,
|
|
126
|
+
action: async () => {
|
|
127
|
+
const { limits, seedStatus } = await (0, import_usageLimits.listUsageLimitsWithStatus)(
|
|
128
|
+
ctx,
|
|
129
|
+
deployment
|
|
130
|
+
);
|
|
131
|
+
if (cmdOptions.json) {
|
|
132
|
+
(0, import_log.logOutput)(JSON.stringify(limits, null, 2));
|
|
133
|
+
return;
|
|
134
|
+
}
|
|
135
|
+
if (limits.length === 0) {
|
|
136
|
+
(0, import_log.logMessage)(
|
|
137
|
+
`No usage limits configured${deployment.deploymentNotice}.`
|
|
138
|
+
);
|
|
139
|
+
return;
|
|
140
|
+
}
|
|
141
|
+
if (seedStatus !== "complete") {
|
|
142
|
+
(0, import_log.logMessage)(seedStatusMessage(seedStatus));
|
|
143
|
+
}
|
|
144
|
+
(0, import_log.logOutput)(
|
|
145
|
+
formatTable(
|
|
146
|
+
[
|
|
147
|
+
"Metric",
|
|
148
|
+
"Window",
|
|
149
|
+
"Type",
|
|
150
|
+
"Limit",
|
|
151
|
+
"Current Usage",
|
|
152
|
+
"Active",
|
|
153
|
+
"Triggered"
|
|
154
|
+
],
|
|
155
|
+
limits.map(usageLimitRow),
|
|
156
|
+
[3, 4]
|
|
157
|
+
)
|
|
158
|
+
);
|
|
159
|
+
}
|
|
160
|
+
});
|
|
161
|
+
});
|
|
162
|
+
const setCmd = new import_extra_typings.Command("set").summary("Create or update a usage limit").description(
|
|
163
|
+
[
|
|
164
|
+
"Create a usage limit, or update the existing one for the same",
|
|
165
|
+
"(metric, window, type). At most one limit exists per combination.",
|
|
166
|
+
"",
|
|
167
|
+
"\u2022 Set the amount (creates or replaces it):",
|
|
168
|
+
" `npx convex deployment usage-limits set --metric functionCalls --window day --type disable --limit 1000000`",
|
|
169
|
+
"\u2022 Deactivate without deleting: add `--inactive` (use `--active` to re-enable).",
|
|
170
|
+
"\u2022 Toggle active state without changing the amount: omit `--limit`."
|
|
171
|
+
].join("\n")
|
|
172
|
+
).addOption(metricOption.makeOptionMandatory()).addOption(windowOption.makeOptionMandatory()).addOption(typeOption.makeOptionMandatory()).option(
|
|
173
|
+
"--limit <limit>",
|
|
174
|
+
"The limit amount, in the metric's native units. Required when creating; kept as-is when omitted while updating."
|
|
175
|
+
).option("--active", "Enforce the limit (the default for a new limit).").option("--inactive", "Create or leave the limit unenforced.").configureHelp({ showGlobalOptions: true }).allowExcessArguments(false).action(async (cmdOptions, cmd) => {
|
|
176
|
+
const options = cmd.optsWithGlobals();
|
|
177
|
+
const { ctx, deployment } = await (0, import_env.selectEnvDeployment)(options);
|
|
178
|
+
await (0, import_utils.ensureHasConvexDependency)(ctx, "deployment usage-limits set");
|
|
179
|
+
if (cmdOptions.active && cmdOptions.inactive) {
|
|
180
|
+
return ctx.crash({
|
|
181
|
+
exitCode: 1,
|
|
182
|
+
errorType: "fatal",
|
|
183
|
+
printedMessage: "error: Pass at most one of --active and --inactive."
|
|
184
|
+
});
|
|
185
|
+
}
|
|
186
|
+
const newLimit = cmdOptions.limit === void 0 ? void 0 : await parseLimit(ctx, cmdOptions.limit);
|
|
187
|
+
await (0, import_run.withRunningBackend)({
|
|
188
|
+
ctx,
|
|
189
|
+
deployment,
|
|
190
|
+
action: async () => {
|
|
191
|
+
const existing = (await (0, import_usageLimits.listUsageLimits)(ctx, deployment)).find(
|
|
192
|
+
(l) => l.metric === cmdOptions.metric && l.window === cmdOptions.window && l.limitType === cmdOptions.type
|
|
193
|
+
);
|
|
194
|
+
const label = `${cmdOptions.type} usage limit on ${(0, import_usageLimits.metricLabel)(cmdOptions.metric)} per ${cmdOptions.window}`;
|
|
195
|
+
if (existing === void 0) {
|
|
196
|
+
if (newLimit === void 0) {
|
|
197
|
+
return ctx.crash({
|
|
198
|
+
exitCode: 1,
|
|
199
|
+
errorType: "fatal",
|
|
200
|
+
printedMessage: "error: --limit is required when creating a usage limit."
|
|
201
|
+
});
|
|
202
|
+
}
|
|
203
|
+
const enabled2 = !cmdOptions.inactive;
|
|
204
|
+
const created = await (0, import_usageLimits.createUsageLimit)(ctx, deployment, {
|
|
205
|
+
metric: cmdOptions.metric,
|
|
206
|
+
window: cmdOptions.window,
|
|
207
|
+
limitType: cmdOptions.type,
|
|
208
|
+
limit: newLimit,
|
|
209
|
+
enabled: enabled2
|
|
210
|
+
});
|
|
211
|
+
(0, import_log.logFinishedStep)(
|
|
212
|
+
`Created ${label}: ${formatLimitAmount(created.limit)}, ${created.enabled ? "active" : "inactive"}${deployment.deploymentNotice}.`
|
|
213
|
+
);
|
|
214
|
+
return;
|
|
215
|
+
}
|
|
216
|
+
const enabled = cmdOptions.active ? true : cmdOptions.inactive ? false : existing.enabled;
|
|
217
|
+
const limit = newLimit ?? existing.limit;
|
|
218
|
+
const changes = [];
|
|
219
|
+
if (limit !== existing.limit) {
|
|
220
|
+
changes.push(
|
|
221
|
+
`limit ${formatLimitAmount(existing.limit)} \u2192 ${formatLimitAmount(limit)}`
|
|
222
|
+
);
|
|
223
|
+
}
|
|
224
|
+
if (enabled !== existing.enabled) {
|
|
225
|
+
changes.push(
|
|
226
|
+
`${existing.enabled ? "active" : "inactive"} \u2192 ${enabled ? "active" : "inactive"}`
|
|
227
|
+
);
|
|
228
|
+
}
|
|
229
|
+
if (changes.length === 0) {
|
|
230
|
+
(0, import_log.logFinishedStep)(
|
|
231
|
+
`No changes to ${label} (${formatLimitAmount(existing.limit)}, ${existing.enabled ? "active" : "inactive"})${deployment.deploymentNotice}.`
|
|
232
|
+
);
|
|
233
|
+
return;
|
|
234
|
+
}
|
|
235
|
+
await (0, import_usageLimits.updateUsageLimit)(ctx, deployment, existing.id, {
|
|
236
|
+
metric: existing.metric,
|
|
237
|
+
window: existing.window,
|
|
238
|
+
limitType: existing.limitType,
|
|
239
|
+
limit,
|
|
240
|
+
enabled
|
|
241
|
+
});
|
|
242
|
+
(0, import_log.logFinishedStep)(
|
|
243
|
+
`Updated ${label}: ${changes.join(", ")}${deployment.deploymentNotice}.`
|
|
244
|
+
);
|
|
245
|
+
}
|
|
246
|
+
});
|
|
247
|
+
});
|
|
248
|
+
const removeCmd = new import_extra_typings.Command("remove").alias("rm").alias("delete").summary("Delete a usage limit").description(
|
|
249
|
+
[
|
|
250
|
+
"Delete a usage limit, identified by its (metric, window, type).",
|
|
251
|
+
"",
|
|
252
|
+
"\u2022 `npx convex deployment usage-limits remove --metric functionCalls --window day --type warning`"
|
|
253
|
+
].join("\n")
|
|
254
|
+
).addOption(metricOption.makeOptionMandatory()).addOption(windowOption.makeOptionMandatory()).addOption(typeOption.makeOptionMandatory()).configureHelp({ showGlobalOptions: true }).allowExcessArguments(false).action(async (cmdOptions, cmd) => {
|
|
255
|
+
const options = cmd.optsWithGlobals();
|
|
256
|
+
const { ctx, deployment } = await (0, import_env.selectEnvDeployment)(options);
|
|
257
|
+
await (0, import_utils.ensureHasConvexDependency)(ctx, "deployment usage-limits remove");
|
|
258
|
+
await (0, import_run.withRunningBackend)({
|
|
259
|
+
ctx,
|
|
260
|
+
deployment,
|
|
261
|
+
action: async () => {
|
|
262
|
+
const existing = await (0, import_usageLimits.findUsageLimitByKey)(ctx, deployment, {
|
|
263
|
+
metric: cmdOptions.metric,
|
|
264
|
+
window: cmdOptions.window,
|
|
265
|
+
limitType: cmdOptions.type
|
|
266
|
+
});
|
|
267
|
+
await (0, import_usageLimits.deleteUsageLimit)(ctx, deployment, existing.id);
|
|
268
|
+
(0, import_log.logFinishedStep)(
|
|
269
|
+
`Deleted ${existing.limitType} usage limit on ${(0, import_usageLimits.metricLabel)(existing.metric)} per ${existing.window}${deployment.deploymentNotice}.`
|
|
270
|
+
);
|
|
271
|
+
}
|
|
272
|
+
});
|
|
273
|
+
});
|
|
274
|
+
const usage = new import_extra_typings.Command("usage").summary("Show current usage for each metric").description(
|
|
275
|
+
[
|
|
276
|
+
"Show usage so far in the current day and calendar month for every metric.",
|
|
277
|
+
"",
|
|
278
|
+
"\u2022 Show current usage: `npx convex deployment usage`",
|
|
279
|
+
"\u2022 Print as JSON: `npx convex deployment usage --json`"
|
|
280
|
+
].join("\n")
|
|
281
|
+
).option("--json", "Output the usage as JSON.").configureHelp({ showGlobalOptions: true }).allowExcessArguments(false).addDeploymentSelectionOptions((0, import_command.actionDescription)("Show current usage for")).action(async (cmdOptions, cmd) => {
|
|
282
|
+
const options = cmd.optsWithGlobals();
|
|
283
|
+
const { ctx, deployment } = await (0, import_env.selectEnvDeployment)(options);
|
|
284
|
+
await (0, import_utils.ensureHasConvexDependency)(ctx, "deployment usage");
|
|
285
|
+
await (0, import_run.withRunningBackend)({
|
|
286
|
+
ctx,
|
|
287
|
+
deployment,
|
|
288
|
+
action: async () => {
|
|
289
|
+
const usage2 = await (0, import_usageLimits.getCurrentUsage)(ctx, deployment);
|
|
290
|
+
if (cmdOptions.json) {
|
|
291
|
+
(0, import_log.logOutput)(JSON.stringify(usage2, null, 2));
|
|
292
|
+
return;
|
|
293
|
+
}
|
|
294
|
+
if (usage2.seedStatus !== "complete") {
|
|
295
|
+
(0, import_log.logMessage)(seedStatusMessage(usage2.seedStatus));
|
|
296
|
+
}
|
|
297
|
+
(0, import_log.logOutput)(
|
|
298
|
+
formatTable(
|
|
299
|
+
["Metric", "Day", "Month"],
|
|
300
|
+
Object.entries(usage2.metrics).sort(([a], [b]) => (0, import_usageLimits.compareMetricNames)(a, b)).map(([metric, m]) => [
|
|
301
|
+
(0, import_usageLimits.metricLabel)(metric),
|
|
302
|
+
formatAmount(m.usage.current_day, m.unit),
|
|
303
|
+
formatAmount(m.usage.current_month, m.unit)
|
|
304
|
+
])
|
|
305
|
+
)
|
|
306
|
+
);
|
|
307
|
+
}
|
|
308
|
+
});
|
|
309
|
+
});
|
|
310
|
+
const usageLimits = new import_extra_typings.Command("usage-limits").summary("List and configure deployment usage limits").description(
|
|
311
|
+
[
|
|
312
|
+
"List and configure usage limits on your deployment.",
|
|
313
|
+
"",
|
|
314
|
+
"A usage limit either warns or pauses your deployment when a metric",
|
|
315
|
+
"(function calls, database bandwidth, \u2026) crosses a threshold within a",
|
|
316
|
+
"daily or monthly window. Each limit is identified by its",
|
|
317
|
+
"(metric, window, type).",
|
|
318
|
+
"",
|
|
319
|
+
"\u2022 List usage limits: `npx convex deployment usage-limits list`",
|
|
320
|
+
"\u2022 Create or update one: `npx convex deployment usage-limits set --metric functionCalls --window day --type disable --limit 1000000`",
|
|
321
|
+
"\u2022 Delete one: `npx convex deployment usage-limits remove --metric functionCalls --window day --type disable`"
|
|
322
|
+
].join("\n")
|
|
323
|
+
).addCommand(listCmd).addCommand(setCmd).addCommand(removeCmd).helpCommand(false).addDeploymentSelectionOptions(
|
|
324
|
+
(0, import_command.actionDescription)("List and configure usage limits on")
|
|
325
|
+
);
|
|
326
|
+
//# sourceMappingURL=usageLimits.js.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../../src/cli/usageLimits.ts"],
|
|
4
|
+
"sourcesContent": ["import { Command, Option } from \"@commander-js/extra-typings\";\nimport { Context } from \"../bundler/context.js\";\nimport { logFinishedStep, logMessage, logOutput } from \"../bundler/log.js\";\nimport { DeploymentSelectionOptions } from \"./lib/api.js\";\nimport { actionDescription } from \"./lib/command.js\";\nimport { ensureHasConvexDependency } from \"./lib/utils/utils.js\";\nimport { withRunningBackend } from \"./lib/localDeployment/run.js\";\nimport { selectEnvDeployment } from \"./env.js\";\nimport {\n compareMetricNames,\n createUsageLimit,\n deleteUsageLimit,\n findUsageLimitByKey,\n getCurrentUsage,\n listUsageLimits,\n listUsageLimitsWithStatus,\n metricLabel,\n updateUsageLimit,\n USAGE_LIMIT_METRICS,\n USAGE_LIMIT_TYPES,\n USAGE_LIMIT_WINDOWS,\n UsageLimitStatus,\n} from \"./lib/usageLimits.js\";\n\nasync function parseLimit(ctx: Context, value: string): Promise<number> {\n const limit = Number(value);\n if (!Number.isInteger(limit) || limit < 1) {\n return ctx.crash({\n exitCode: 1,\n errorType: \"fatal\",\n printedMessage: `error: --limit must be a positive integer, got \"${value}\".`,\n });\n }\n return limit;\n}\n\nfunction formatTable(\n header: string[],\n rows: string[][],\n rightAlign: number[] = [],\n): string {\n const right = new Set(rightAlign);\n const widths = header.map((cell, i) =>\n Math.max(cell.length, ...rows.map((row) => (row[i] ?? \"\").length)),\n );\n const pad = (cell: string, i: number) =>\n right.has(i) ? cell.padStart(widths[i]) : cell.padEnd(widths[i]);\n const rule = (left: string, mid: string, r: string) =>\n left + widths.map((w) => \"\\u2500\".repeat(w + 2)).join(mid) + r;\n const line = (cells: string[]) =>\n \"\\u2502 \" +\n cells.map((cell, i) => pad(cell ?? \"\", i)).join(\" \\u2502 \") +\n \" \\u2502\";\n return [\n rule(\"\\u250c\", \"\\u252c\", \"\\u2510\"),\n line(header),\n rule(\"\\u251c\", \"\\u253c\", \"\\u2524\"),\n ...rows.map(line),\n rule(\"\\u2514\", \"\\u2534\", \"\\u2518\"),\n ].join(\"\\n\");\n}\n\nconst NUMBER_FORMAT_COMPACT = new Intl.NumberFormat(\"en-US\", {\n notation: \"compact\",\n compactDisplay: \"short\",\n maximumFractionDigits: 3,\n});\nfunction formatNumberCompact(value: number): string {\n const formatted = NUMBER_FORMAT_COMPACT.format(value);\n return formatted === \"-0\" ? \"0\" : formatted;\n}\n\n// Exact, thousands-separated amount for prose (success messages), where a\n// precise value reads clearer than the compact table form.\nconst LIMIT_FORMAT = new Intl.NumberFormat(\"en-US\");\nfunction formatLimitAmount(value: number): string {\n return LIMIT_FORMAT.format(value);\n}\n\nconst NUMBER_FORMAT = new Intl.NumberFormat(\"en-US\");\nfunction formatNumber(value: number): string {\n const formatted = NUMBER_FORMAT.format(value);\n return formatted === \"-0\" ? \"0\" : formatted;\n}\n\nfunction unitFor(amount: number, unit: string): string {\n return amount === 1 && unit === \"calls\" ? \"call\" : unit;\n}\n\nfunction formatAmount(value: number, unit: string | null): string {\n return unit === null\n ? formatNumberCompact(value)\n : `${formatNumberCompact(value)} ${unitFor(value, unit)}`;\n}\n\nfunction usageLimitRow(limit: UsageLimitStatus): string[] {\n const currentUsage =\n limit.currentUsage === null\n ? \"\\u2014\"\n : `${formatAmount(limit.currentUsage, limit.unit)} (${formatNumber(\n Math.round((limit.currentUsage / limit.limit) * 100),\n )}%)`;\n return [\n metricLabel(limit.metric),\n limit.window,\n limit.limitType,\n formatAmount(limit.limit, limit.unit),\n currentUsage,\n limit.enabled ? \"yes\" : \"no\",\n limit.triggered ? \"yes\" : \"no\",\n ];\n}\n\n// The (metric, window, type) triple uniquely identifies a usage limit. `set`\n// requires all three plus a limit; `update`/`remove` reuse them to locate an\n// existing limit without needing its opaque id.\nconst metricOption = new Option(\n \"--metric <metric>\",\n \"The metric to limit.\",\n).choices(USAGE_LIMIT_METRICS);\nconst windowOption = new Option(\n \"--window <window>\",\n \"The window the limit is measured over.\",\n).choices(USAGE_LIMIT_WINDOWS);\nconst typeOption = new Option(\n \"--type <type>\",\n \"`warning` only notifies; `disable` pauses the deployment when exceeded.\",\n).choices(USAGE_LIMIT_TYPES);\n\nfunction seedStatusMessage(\n seedStatus: \"pending\" | \"partial\" | \"failed\",\n): string {\n return seedStatus === \"failed\"\n ? \"We couldn't load this deployment's historical usage, so the usage shown below may understate its actual usage. Limits are still enforced going forward.\"\n : \"Historical usage is still being loaded, so the usage shown below may understate this deployment's actual usage. Check back shortly for accurate totals.\";\n}\n\nconst listCmd = new Command(\"list\")\n .summary(\"List configured usage limits\")\n .description(\n [\n \"List the usage limits configured on your deployment.\",\n \"\",\n \"\u2022 List all usage limits: `npx convex deployment usage-limits list`\",\n \"\u2022 Print as JSON: `npx convex deployment usage-limits list --json`\",\n ].join(\"\\n\"),\n )\n .option(\"--json\", \"Output the usage limits as JSON.\")\n .configureHelp({ showGlobalOptions: true })\n .allowExcessArguments(false)\n .action(async (cmdOptions, cmd) => {\n const options = cmd.optsWithGlobals() as DeploymentSelectionOptions & {\n json?: boolean;\n };\n const { ctx, deployment } = await selectEnvDeployment(options);\n await ensureHasConvexDependency(ctx, \"deployment usage-limits list\");\n await withRunningBackend({\n ctx,\n deployment,\n action: async () => {\n const { limits, seedStatus } = await listUsageLimitsWithStatus(\n ctx,\n deployment,\n );\n if (cmdOptions.json) {\n logOutput(JSON.stringify(limits, null, 2));\n return;\n }\n if (limits.length === 0) {\n logMessage(\n `No usage limits configured${deployment.deploymentNotice}.`,\n );\n return;\n }\n // \"Triggered\" is derived from reported usage, which a non-`complete`\n // backfill may understate.\n if (seedStatus !== \"complete\") {\n logMessage(seedStatusMessage(seedStatus));\n }\n logOutput(\n formatTable(\n [\n \"Metric\",\n \"Window\",\n \"Type\",\n \"Limit\",\n \"Current Usage\",\n \"Active\",\n \"Triggered\",\n ],\n limits.map(usageLimitRow),\n [3, 4],\n ),\n );\n },\n });\n });\n\nconst setCmd = new Command(\"set\")\n .summary(\"Create or update a usage limit\")\n .description(\n [\n \"Create a usage limit, or update the existing one for the same\",\n \"(metric, window, type). At most one limit exists per combination.\",\n \"\",\n \"\u2022 Set the amount (creates or replaces it):\",\n \" `npx convex deployment usage-limits set --metric functionCalls --window day --type disable --limit 1000000`\",\n \"\u2022 Deactivate without deleting: add `--inactive` (use `--active` to re-enable).\",\n \"\u2022 Toggle active state without changing the amount: omit `--limit`.\",\n ].join(\"\\n\"),\n )\n .addOption(metricOption.makeOptionMandatory())\n .addOption(windowOption.makeOptionMandatory())\n .addOption(typeOption.makeOptionMandatory())\n .option(\n \"--limit <limit>\",\n \"The limit amount, in the metric's native units. Required when creating; kept as-is when omitted while updating.\",\n )\n .option(\"--active\", \"Enforce the limit (the default for a new limit).\")\n .option(\"--inactive\", \"Create or leave the limit unenforced.\")\n .configureHelp({ showGlobalOptions: true })\n .allowExcessArguments(false)\n .action(async (cmdOptions, cmd) => {\n const options = cmd.optsWithGlobals() as DeploymentSelectionOptions;\n const { ctx, deployment } = await selectEnvDeployment(options);\n await ensureHasConvexDependency(ctx, \"deployment usage-limits set\");\n if (cmdOptions.active && cmdOptions.inactive) {\n return ctx.crash({\n exitCode: 1,\n errorType: \"fatal\",\n printedMessage: \"error: Pass at most one of --active and --inactive.\",\n });\n }\n const newLimit =\n cmdOptions.limit === undefined\n ? undefined\n : await parseLimit(ctx, cmdOptions.limit);\n await withRunningBackend({\n ctx,\n deployment,\n action: async () => {\n const existing = (await listUsageLimits(ctx, deployment)).find(\n (l) =>\n l.metric === cmdOptions.metric &&\n l.window === cmdOptions.window &&\n l.limitType === cmdOptions.type,\n );\n const label = `${cmdOptions.type} usage limit on ${metricLabel(cmdOptions.metric)} per ${cmdOptions.window}`;\n\n // No existing limit: create one. A limit amount is required.\n if (existing === undefined) {\n if (newLimit === undefined) {\n return ctx.crash({\n exitCode: 1,\n errorType: \"fatal\",\n printedMessage:\n \"error: --limit is required when creating a usage limit.\",\n });\n }\n const enabled = !cmdOptions.inactive;\n const created = await createUsageLimit(ctx, deployment, {\n metric: cmdOptions.metric,\n window: cmdOptions.window,\n limitType: cmdOptions.type,\n limit: newLimit,\n enabled,\n });\n logFinishedStep(\n `Created ${label}: ${formatLimitAmount(created.limit)}, ${created.enabled ? \"active\" : \"inactive\"}${deployment.deploymentNotice}.`,\n );\n return;\n }\n\n // Existing limit: update it, surfacing exactly which fields changed.\n const enabled = cmdOptions.active\n ? true\n : cmdOptions.inactive\n ? false\n : existing.enabled;\n const limit = newLimit ?? existing.limit;\n const changes: string[] = [];\n if (limit !== existing.limit) {\n changes.push(\n `limit ${formatLimitAmount(existing.limit)} \\u2192 ${formatLimitAmount(limit)}`,\n );\n }\n if (enabled !== existing.enabled) {\n changes.push(\n `${existing.enabled ? \"active\" : \"inactive\"} \\u2192 ${enabled ? \"active\" : \"inactive\"}`,\n );\n }\n if (changes.length === 0) {\n logFinishedStep(\n `No changes to ${label} (${formatLimitAmount(existing.limit)}, ${existing.enabled ? \"active\" : \"inactive\"})${deployment.deploymentNotice}.`,\n );\n return;\n }\n await updateUsageLimit(ctx, deployment, existing.id, {\n metric: existing.metric,\n window: existing.window,\n limitType: existing.limitType,\n limit,\n enabled,\n });\n logFinishedStep(\n `Updated ${label}: ${changes.join(\", \")}${deployment.deploymentNotice}.`,\n );\n },\n });\n });\n\nconst removeCmd = new Command(\"remove\")\n .alias(\"rm\")\n .alias(\"delete\")\n .summary(\"Delete a usage limit\")\n .description(\n [\n \"Delete a usage limit, identified by its (metric, window, type).\",\n \"\",\n \"\u2022 `npx convex deployment usage-limits remove --metric functionCalls --window day --type warning`\",\n ].join(\"\\n\"),\n )\n .addOption(metricOption.makeOptionMandatory())\n .addOption(windowOption.makeOptionMandatory())\n .addOption(typeOption.makeOptionMandatory())\n .configureHelp({ showGlobalOptions: true })\n .allowExcessArguments(false)\n .action(async (cmdOptions, cmd) => {\n const options = cmd.optsWithGlobals() as DeploymentSelectionOptions;\n const { ctx, deployment } = await selectEnvDeployment(options);\n await ensureHasConvexDependency(ctx, \"deployment usage-limits remove\");\n await withRunningBackend({\n ctx,\n deployment,\n action: async () => {\n const existing = await findUsageLimitByKey(ctx, deployment, {\n metric: cmdOptions.metric,\n window: cmdOptions.window,\n limitType: cmdOptions.type,\n });\n await deleteUsageLimit(ctx, deployment, existing.id);\n logFinishedStep(\n `Deleted ${existing.limitType} usage limit on ${metricLabel(existing.metric)} per ${existing.window}${deployment.deploymentNotice}.`,\n );\n },\n });\n });\n\nexport const usage = new Command(\"usage\")\n .summary(\"Show current usage for each metric\")\n .description(\n [\n \"Show usage so far in the current day and calendar month for every metric.\",\n \"\",\n \"\u2022 Show current usage: `npx convex deployment usage`\",\n \"\u2022 Print as JSON: `npx convex deployment usage --json`\",\n ].join(\"\\n\"),\n )\n .option(\"--json\", \"Output the usage as JSON.\")\n .configureHelp({ showGlobalOptions: true })\n .allowExcessArguments(false)\n .addDeploymentSelectionOptions(actionDescription(\"Show current usage for\"))\n .action(async (cmdOptions, cmd) => {\n const options = cmd.optsWithGlobals() as DeploymentSelectionOptions & {\n json?: boolean;\n };\n const { ctx, deployment } = await selectEnvDeployment(options);\n await ensureHasConvexDependency(ctx, \"deployment usage\");\n await withRunningBackend({\n ctx,\n deployment,\n action: async () => {\n const usage = await getCurrentUsage(ctx, deployment);\n if (cmdOptions.json) {\n logOutput(JSON.stringify(usage, null, 2));\n return;\n }\n // A non-`complete` backfill means the numbers can understate reality.\n if (usage.seedStatus !== \"complete\") {\n logMessage(seedStatusMessage(usage.seedStatus));\n }\n logOutput(\n formatTable(\n [\"Metric\", \"Day\", \"Month\"],\n Object.entries(usage.metrics)\n .sort(([a], [b]) => compareMetricNames(a, b))\n .map(([metric, m]) => [\n metricLabel(metric),\n formatAmount(m.usage.current_day, m.unit),\n formatAmount(m.usage.current_month, m.unit),\n ]),\n ),\n );\n },\n });\n });\n\nexport const usageLimits = new Command(\"usage-limits\")\n .summary(\"List and configure deployment usage limits\")\n .description(\n [\n \"List and configure usage limits on your deployment.\",\n \"\",\n \"A usage limit either warns or pauses your deployment when a metric\",\n \"(function calls, database bandwidth, \u2026) crosses a threshold within a\",\n \"daily or monthly window. Each limit is identified by its\",\n \"(metric, window, type).\",\n \"\",\n \"\u2022 List usage limits: `npx convex deployment usage-limits list`\",\n \"\u2022 Create or update one: `npx convex deployment usage-limits set --metric functionCalls --window day --type disable --limit 1000000`\",\n \"\u2022 Delete one: `npx convex deployment usage-limits remove --metric functionCalls --window day --type disable`\",\n ].join(\"\\n\"),\n )\n .addCommand(listCmd)\n .addCommand(setCmd)\n .addCommand(removeCmd)\n .helpCommand(false)\n .addDeploymentSelectionOptions(\n actionDescription(\"List and configure usage limits on\"),\n );\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
|
+
"names": ["enabled", "usage"]
|
|
7
|
+
}
|
package/dist/cjs/index.js
CHANGED
package/dist/cjs/index.js.map
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../src/index.ts"],
|
|
4
|
-
"sourcesContent": ["export const version = \"1.
|
|
4
|
+
"sourcesContent": ["export const version = \"1.43.0-alpha.1\";"],
|
|
5
5
|
"mappings": ";;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAO,MAAM,UAAU;",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../../src/server/components/index.ts"],
|
|
4
|
-
"sourcesContent": ["import { PropertyValidators } from \"../../values/index.js\";\nimport { version } from \"../../index.js\";\nimport {\n AnyFunctionReference,\n FunctionReference,\n FunctionType,\n} from \"../api.js\";\nimport { performAsyncSyscall } from \"../impl/syscall.js\";\nimport { DefaultFunctionArgs } from \"../registration.js\";\nimport {\n AppDefinitionAnalysis,\n ComponentDefinitionAnalysis,\n ComponentDefinitionType,\n} from \"./definition.js\";\nimport {\n getFunctionAddress,\n setReferencePath,\n toReferencePath,\n} from \"./paths.js\";\nimport type {\n Validator,\n VLiteral,\n VOptional,\n VString,\n VUnion,\n} from \"../../values/validators.js\";\nimport type { Infer } from \"../../values/validator.js\";\nimport { isValidator } from \"../../values/validator.js\";\nimport type { Expand } from \"../../type_utils.js\";\nexport { getFunctionAddress } from \"./paths.js\";\n\n/**\n * A serializable reference to a Convex function.\n * Passing a this reference to another component allows that component to call this\n * function during the current function execution or at any later time.\n * Function handles are used like `api.folder.function` FunctionReferences,\n * e.g. `ctx.scheduler.runAfter(0, functionReference, args)`.\n *\n * A function reference is stable across code pushes but it's possible\n * the Convex function it refers to might no longer exist.\n *\n * This is a feature of components, which are in beta.\n * This API is unstable and may change in subsequent releases.\n */\nexport type FunctionHandle<\n Type extends FunctionType,\n Args extends DefaultFunctionArgs = any,\n ReturnType = any,\n> = string & FunctionReference<Type, \"internal\", Args, ReturnType>;\n\n/**\n * Create a serializable reference to a Convex function.\n * Passing a this reference to another component allows that component to call this\n * function during the current function execution or at any later time.\n * Function handles are used like `api.folder.function` FunctionReferences,\n * e.g. `ctx.scheduler.runAfter(0, functionReference, args)`.\n *\n * A function reference is stable across code pushes but it's possible\n * the Convex function it refers to might no longer exist.\n *\n * This is a feature of components, which are in beta.\n * This API is unstable and may change in subsequent releases.\n */\nexport async function createFunctionHandle<\n Type extends FunctionType,\n Args extends DefaultFunctionArgs,\n ReturnType,\n>(\n functionReference: FunctionReference<\n Type,\n \"public\" | \"internal\",\n Args,\n ReturnType\n >,\n): Promise<FunctionHandle<Type, Args, ReturnType>> {\n const address = getFunctionAddress(functionReference);\n return await performAsyncSyscall(\"1.0/createFunctionHandle\", {\n ...address,\n version,\n });\n}\n\ninterface ComponentExports {\n [key: string]: FunctionReference<any, any, any, any> | ComponentExports;\n}\n\n/**\n * An object of this type should be the default export of a\n * convex.config.ts file in a component definition directory.\n *\n * This is a feature of components, which are in beta.\n * This API is unstable and may change in subsequent releases.\n */\nexport type ComponentDefinition<\n Exports extends ComponentExports = any,\n Env extends EnvDefinition = {},\n> = {\n /**\n * Install a component with the given definition in this component definition.\n *\n * Takes a component definition and an optional name.\n *\n * For editor tooling this method expects a {@link ComponentDefinition}\n * but at runtime the object that is imported will be a {@link ImportedComponentDefinition}\n */\n use<Definition extends ComponentDefinition<any, any>>(\n definition: Definition,\n options?: UseOptions<Definition>,\n ): InstalledComponent<Definition>;\n\n /**\n * Internal type-only property tracking exports provided.\n *\n * @deprecated This is a type-only property, don't use it.\n */\n __exports: Exports;\n\n /**\n * References to this component's declared env vars. Pass one of these in\n * `app.use(child, { env: { ... } })` to bind a child's env var by\n * reference to this component's env var.\n */\n env: EnvRefFromDefinition<Env>;\n\n /**\n * Internal type-only property tracking env definition.\n *\n * @deprecated This is a type-only property, don't use it.\n */\n __env: Env;\n};\n\ntype ComponentDefinitionExports<T extends ComponentDefinition<any, any>> =\n T[\"__exports\"];\n\ntype ComponentDefinitionEnv<T extends ComponentDefinition<any, any>> =\n T[\"__env\"];\n\n/**\n * Options for installing a component via `app.use()` or `component.use()`.\n *\n * If the component declares required env vars, the `env` property is required.\n */\ntype UseOptions<Definition extends ComponentDefinition<any, any>> =\n keyof ComponentDefinitionEnv<Definition> extends never\n ? { name?: string; httpPrefix?: string }\n : {\n name?: string;\n httpPrefix?: string;\n env: UseOptionsEnv<ComponentDefinitionEnv<Definition>>;\n };\n\ntype UseOptionsEnv<E extends EnvDefinition> = Expand<\n {\n [K in keyof E as E[K] extends VOptional<any> ? never : K]:\n | Infer<E[K]>\n | EnvRef;\n } & {\n [K in keyof E as E[K] extends VOptional<any> ? K : never]?:\n | Infer<E[K]>\n | EnvRef\n | undefined;\n }\n>;\n\n/**\n * A string-like validator: `v.string()`, a string `v.literal(\"...\")`, or a\n * `v.union(...)` of those (recursively). Component env vars are serialized\n * as strings on the wire, so only string-typed validators are allowed.\n *\n * @public\n */\nexport type StringLikeValidator =\n | VString<string, \"required\">\n | VLiteral<string, \"required\">\n | VUnion<string, Validator<any, \"required\", any>[], \"required\">;\n\n/**\n * A definition of environment variables for the app.\n *\n * Maps environment variable names to string-like validators. Use\n * `v.string()` for a plain string, `v.literal(\"a\")` for an enum value, or\n * `v.union(v.literal(\"a\"), v.literal(\"b\"))` for an enum. Wrap in\n * `v.optional(...)` for optional vars.\n *\n * @example\n * ```typescript\n * import { defineApp } from \"convex/server\";\n * import { v } from \"convex/values\";\n *\n * const app = defineApp({\n * env: {\n * OPENAI_API_KEY: v.string(),\n * DEBUG_MODE: v.optional(v.string()),\n * },\n * });\n * ```\n *\n * @public\n */\nexport type EnvDefinition = Record<\n string,\n StringLikeValidator | VOptional<StringLikeValidator>\n>;\n\n/**\n * Compute the typed environment object from an {@link EnvDefinition}.\n *\n * Required entries get the validator's inferred string type; optional\n * entries are `T | undefined`.\n *\n * @public\n */\nexport type EnvFromDefinition<E extends EnvDefinition> = Expand<\n {\n [K in keyof E as E[K] extends VOptional<any> ? never : K]: Infer<E[K]>;\n } & {\n [K in keyof E as E[K] extends VOptional<any> ? K : never]?:\n | Infer<E[K]>\n | undefined;\n }\n>;\n\n/**\n * A reference to a parent-declared env var, produced by `app.env.<NAME>` or\n * `component.env.<NAME>`. Pass this in `use(child, { env: { ... } })` to\n * bind a child's declared env var to the parent's env var by reference\n * instead of snapshotting its current value.\n *\n * @public\n */\nexport type EnvRef<K extends string = string> = { __envVarRef: K };\n\n/**\n * Compute the typed `env` namespace object from an {@link EnvDefinition}.\n * Each declared name maps to an {@link EnvRef} for that name.\n *\n * @public\n */\nexport type EnvRefFromDefinition<E extends EnvDefinition> = {\n [K in keyof E & string]: EnvRef<K>;\n};\n\n/**\n * Extract the typed environment from an {@link AppDefinition}.\n *\n * @public\n */\nexport type EnvFromAppDefinition<A> =\n A extends AppDefinition<infer E>\n ? EnvFromDefinition<E>\n : Record<string, never>;\n\n/**\n * An object of this type should be the default export of a\n * convex.config.ts file in a component-aware convex directory.\n *\n * This is a feature of components, which are in beta.\n * This API is unstable and may change in subsequent releases.\n */\nexport type AppDefinition<Env extends EnvDefinition = EnvDefinition> = {\n /**\n * Install a component with the given definition in this component definition.\n *\n * Takes a component definition and an optional name.\n *\n * For editor tooling this method expects a {@link ComponentDefinition}\n * but at runtime the object that is imported will be a {@link ImportedComponentDefinition}\n */\n use<Definition extends ComponentDefinition<any, any>>(\n definition: Definition,\n options?: UseOptions<Definition>,\n ): InstalledComponent<Definition>;\n\n /**\n * References to this app's declared env vars. Pass one of these in\n * `app.use(child, { env: { ... } })` to bind a child's env var by\n * reference to this app's env var.\n */\n env: EnvRefFromDefinition<Env>;\n\n /**\n * Internal type-only property tracking env definition.\n *\n * @deprecated This is a type-only property, don't use it.\n */\n __env: Env;\n};\n\ninterface ExportTree {\n // Tree with serialized `Reference`s as leaves.\n [key: string]: string | ExportTree;\n}\n\ntype CommonDefinitionData = {\n _isRoot: boolean;\n _childComponents: [\n string,\n ImportedComponentDefinition,\n Record<string, any> | null,\n string | undefined,\n ][];\n _exportTree: ExportTree;\n};\n\ntype ComponentDefinitionData = CommonDefinitionData & {\n _env: PropertyValidators;\n _name: string;\n _onInitCallbacks: Record<string, (argsStr: string) => string>;\n};\ntype AppDefinitionData = CommonDefinitionData & {\n _httpPrefix?: string;\n _env?: EnvDefinition;\n};\n\n/**\n * Used to refer to an already-installed component.\n */\nclass InstalledComponent<Definition extends ComponentDefinition<any, any>> {\n /**\n * @internal\n */\n _definition: Definition;\n\n /**\n * @internal\n */\n _name: string;\n\n constructor(definition: Definition, name: string) {\n this._definition = definition;\n this._name = name;\n setReferencePath(this, `_reference/childComponent/${name}`);\n }\n\n get exports(): ComponentDefinitionExports<Definition> {\n return createExports(this._name, []);\n }\n}\n\nfunction createExports(name: string, pathParts: string[]): any {\n const handler: ProxyHandler<any> = {\n get(_, prop: string | symbol) {\n if (typeof prop === \"string\") {\n const newParts = [...pathParts, prop];\n return createExports(name, newParts);\n } else if (prop === toReferencePath) {\n let reference = `_reference/childComponent/${name}`;\n for (const part of pathParts) {\n reference += `/${part}`;\n }\n return reference;\n } else {\n return undefined;\n }\n },\n };\n return new Proxy({}, handler);\n}\n\nfunction createEnvRefs(\n ownerLabel: string,\n declared: Record<string, any> | undefined,\n): any {\n const handler: ProxyHandler<any> = {\n get(_, prop: string | symbol) {\n if (typeof prop !== \"string\") {\n return undefined;\n }\n if (!declared || !Object.prototype.hasOwnProperty.call(declared, prop)) {\n throw new Error(\n `Env var \"${prop}\" is not declared on ${ownerLabel}. Add it to the \\`env\\` option of ${ownerLabel === \"this app\" ? \"defineApp\" : \"defineComponent\"}.`,\n );\n }\n return { __envVarRef: prop };\n },\n };\n return new Proxy({}, handler);\n}\n\nfunction isEnvRef(value: unknown): value is EnvRef {\n return (\n typeof value === \"object\" &&\n value !== null &&\n typeof (value as EnvRef).__envVarRef === \"string\"\n );\n}\n\nfunction use<Definition extends ComponentDefinition<any, any>>(\n this: CommonDefinitionData,\n definition: Definition,\n options?: {\n name?: string;\n httpPrefix?: string;\n env?: Record<string, any>;\n },\n): InstalledComponent<Definition> {\n // At runtime an imported component will have this shape.\n const importedComponentDefinition =\n definition as unknown as ImportedComponentDefinition;\n if (typeof importedComponentDefinition.componentDefinitionPath !== \"string\") {\n throw new Error(\n \"Component definition does not have the required componentDefinitionPath property. This code only works in Convex runtime.\",\n );\n }\n const name =\n options?.name ??\n // added recently\n importedComponentDefinition.defaultName ??\n // can be removed once backend is out\n importedComponentDefinition.componentDefinitionPath.split(\"/\").pop()!;\n\n if (typeof name !== \"string\") {\n throw new Error(\n `Component name must be a string. Received: ${typeof name}`,\n );\n }\n if (name.length === 0) {\n // \"\" is used internally as the name for the root component, so\n // users shouldn't try to define child components with an empty name.\n throw new Error(\"Component name cannot be empty.\");\n }\n\n const httpPrefix = options?.httpPrefix;\n if (httpPrefix !== undefined) {\n if (!httpPrefix.startsWith(\"/\")) {\n throw new Error(\n `httpPrefix must start with \"/\". Received: \"${httpPrefix}\"`,\n );\n }\n }\n\n const envValues: Record<string, any> = {};\n if (options?.env) {\n for (const [key, value] of Object.entries(options.env)) {\n if (value !== undefined) {\n envValues[key] = value;\n }\n }\n }\n\n this._childComponents.push([\n name,\n importedComponentDefinition,\n envValues,\n httpPrefix,\n ]);\n return new InstalledComponent(definition, name);\n}\n\n/**\n * The runtime type of a ComponentDefinition. TypeScript will claim\n * the default export of a module like \"cool-component/convex.config.js\"\n * is a `@link ComponentDefinition}, but during component definition evaluation\n * this is its type instead.\n *\n * This is a feature of components, which are in beta.\n * This API is unstable and may change in subsequent releases.\n */\nexport type ImportedComponentDefinition = {\n componentDefinitionPath: string;\n defaultName: string;\n};\n\nfunction exportAppForAnalysis(\n this: ComponentDefinition<any, any> & AppDefinitionData,\n): AppDefinitionAnalysis {\n const definitionType = { type: \"app\" as const };\n const childComponents = serializeChildComponents(this._childComponents);\n const httpMounts = buildHttpMounts(this._childComponents);\n const envVars = this._env\n ? Object.entries(this._env).map(\n ([name, validator]) =>\n [\n name,\n {\n type: \"value\" as const,\n value: JSON.stringify(validator.json),\n ...(validator.isOptional === \"optional\"\n ? { optional: true }\n : {}),\n },\n ] as [string, { type: \"value\"; value: string; optional?: boolean }],\n )\n : undefined;\n return {\n definitionType,\n ...(this._httpPrefix !== undefined\n ? { httpPrefix: normalizeHttpPrefix(this._httpPrefix) }\n : {}),\n childComponents: childComponents as any,\n httpMounts,\n exports: serializeExportTree(this._exportTree),\n ...(envVars !== undefined ? { envVars } : {}),\n };\n}\n\nfunction serializeExportTree(tree: ExportTree): any {\n const branch: any[] = [];\n for (const [key, child] of Object.entries(tree)) {\n let node;\n if (typeof child === \"string\") {\n node = { type: \"leaf\", leaf: child };\n } else {\n node = serializeExportTree(child);\n }\n branch.push([key, node]);\n }\n return { type: \"branch\", branch };\n}\n\nfunction normalizeHttpPrefix(prefix: string): string {\n // Ensure the prefix ends with \"/\" as required by HttpMountPath in Rust.\n return prefix.endsWith(\"/\") ? prefix : prefix + \"/\";\n}\n\nfunction buildHttpMounts(\n childComponents: [\n string,\n ImportedComponentDefinition,\n Record<string, any> | null,\n string | undefined,\n ][],\n): Record<string, string> {\n const httpMounts: Record<string, string> = {};\n for (const [name, , , httpPrefix] of childComponents) {\n if (httpPrefix !== undefined) {\n const normalized = normalizeHttpPrefix(httpPrefix);\n httpMounts[normalized] = `_reference/childComponent/${name}`;\n }\n }\n return httpMounts;\n}\n\ntype SerializedEnvArg =\n | { type: \"value\"; value: string }\n | { type: \"envVar\"; name: string };\n\nfunction serializeChildComponents(\n childComponents: [\n string,\n ImportedComponentDefinition,\n Record<string, any> | null,\n string | undefined,\n ][],\n): {\n name: string;\n path: string;\n env: [string, SerializedEnvArg][] | null;\n}[] {\n return childComponents.map(([name, definition, p]) => {\n // Note: httpPrefix (4th element) is used separately in buildHttpMounts()\n let env: [string, SerializedEnvArg][] | null = null;\n if (p !== null) {\n env = [];\n for (const [name, value] of Object.entries(p)) {\n if (value === undefined) {\n continue;\n }\n if (isEnvRef(value)) {\n env.push([name, { type: \"envVar\", name: value.__envVarRef }]);\n } else if (typeof value === \"string\") {\n env.push([name, { type: \"value\", value }]);\n } else {\n throw new Error(\n `Env var \"${name}\" must be a string or an env var reference. ` +\n `Received: ${typeof value}`,\n );\n }\n }\n }\n // we know that components carry this extra information\n const path = definition.componentDefinitionPath;\n if (!path)\n throw new Error(\n \"no .componentPath for component definition \" +\n JSON.stringify(definition, null, 2),\n );\n\n return {\n name: name!,\n path: path!,\n args: [],\n env,\n };\n });\n}\n\nfunction exportComponentForAnalysis(\n this: ComponentDefinition<any, any> & ComponentDefinitionData,\n): ComponentDefinitionAnalysis {\n const envVars = Object.entries(this._env).map(\n ([name, validator]) =>\n [\n name,\n {\n type: \"value\" as const,\n value: JSON.stringify((validator as any).json),\n ...((validator as any).isOptional === \"optional\"\n ? { optional: true }\n : {}),\n },\n ] as [string, { type: \"value\"; value: string; optional?: boolean }],\n );\n const definitionType: ComponentDefinitionType = {\n type: \"childComponent\" as const,\n name: this._name,\n args: [],\n };\n const childComponents = serializeChildComponents(this._childComponents);\n const httpMounts = buildHttpMounts(this._childComponents);\n return {\n name: this._name,\n definitionType,\n childComponents: childComponents as any,\n httpMounts,\n exports: serializeExportTree(this._exportTree),\n ...(envVars.length > 0 ? { envVars } : {}),\n };\n}\n\n// This is what is actually contained in a ComponentDefinition.\ntype RuntimeComponentDefinition = Omit<\n ComponentDefinition<any, any>,\n \"__exports\" | \"__env\"\n> &\n ComponentDefinitionData & {\n export: () => ComponentDefinitionAnalysis;\n };\ntype RuntimeAppDefinition = Omit<AppDefinition<any>, \"__env\"> &\n AppDefinitionData & {\n export: () => AppDefinitionAnalysis;\n };\n\n/**\n * Define a component, a piece of a Convex deployment with namespaced resources.\n *\n * Optionally define typed environment variables that will be available via\n * the `env` export from `_generated/server` in all Convex functions within\n * this component. Values are passed by the parent via\n * `app.use(component, { env: { ... } })`.\n *\n * @param name Name must be alphanumeric plus underscores. Typically these are\n * lowercase with underscores like `\"onboarding_flow_tracker\"`.\n *\n * This is a feature of components, which are in beta.\n * This API is unstable and may change in subsequent releases.\n */\nexport function defineComponent<\n Exports extends ComponentExports = any,\n const Env extends EnvDefinition = {},\n>(\n name: string,\n options?: {\n env?: Env;\n },\n): ComponentDefinition<Exports, Env> {\n const envValidators: PropertyValidators = {};\n if (options?.env) {\n for (const [key, decl] of Object.entries(options.env)) {\n if (decl !== null && decl !== undefined && isValidator(decl)) {\n envValidators[key] = decl as any;\n } else {\n throw new Error(\n `Environment variable \"${key}\" must be defined with a validator (e.g. v.string()).`,\n );\n }\n }\n }\n\n const ret: RuntimeComponentDefinition = {\n _isRoot: false,\n _name: name,\n _env: envValidators,\n _childComponents: [],\n _exportTree: {},\n _onInitCallbacks: {},\n\n env: createEnvRefs(`component \"${name}\"`, options?.env),\n\n export: exportComponentForAnalysis,\n use,\n\n ...({} as { __exports: any; __env: any }),\n };\n return ret as any as ComponentDefinition<Exports, Env>;\n}\n\n/**\n * Attach components, reuseable pieces of a Convex deployment, to this Convex app.\n *\n * Optionally define typed environment variables that will be available via\n * the `env` export from `_generated/server` in all Convex functions.\n *\n * @example\n * ```typescript\n * import { defineApp } from \"convex/server\";\n * import { v } from \"convex/values\";\n *\n * const app = defineApp({\n * env: {\n * OPENAI_API_KEY: v.string(),\n * DEBUG_MODE: v.optional(v.string()),\n * },\n * });\n * export default app;\n * ```\n *\n * This is a feature of components, which are in beta.\n * This API is unstable and may change in subsequent releases.\n */\nexport function defineApp<Env extends EnvDefinition = EnvDefinition>(options?: {\n httpPrefix?: string;\n env?: Env;\n}): AppDefinition<Env> {\n const httpPrefix = options?.httpPrefix;\n if (httpPrefix !== undefined && !httpPrefix.startsWith(\"/\")) {\n throw new Error(\n `httpPrefix must start with \"/\". Received: \"${httpPrefix}\"`,\n );\n }\n const env = options?.env;\n if (env !== undefined) {\n for (const [name, validator] of Object.entries(env)) {\n if (!isValidator(validator)) {\n throw new Error(\n `Environment variable \"${name}\" must be defined with a validator (e.g. v.string()).`,\n );\n }\n }\n }\n const ret: RuntimeAppDefinition = {\n _isRoot: true,\n _childComponents: [],\n _exportTree: {},\n ...(httpPrefix !== undefined ? { _httpPrefix: httpPrefix } : {}),\n ...(env !== undefined ? { _env: env } : {}),\n\n env: createEnvRefs(\"this app\", env),\n\n export: exportAppForAnalysis,\n use,\n };\n return ret as unknown as AppDefinition<Env>;\n}\n\ntype AnyInterfaceType = {\n [key: string]: AnyInterfaceType;\n} & AnyFunctionReference;\nexport type AnyComponentReference = Record<string, AnyInterfaceType>;\n\nexport type AnyChildComponents = Record<string, AnyComponentReference>;\n\n/**\n * @internal\n */\nexport function currentSystemUdfInComponent(\n componentId: string,\n): AnyComponentReference {\n return {\n [toReferencePath]: `_reference/currentSystemUdfInComponent/${componentId}`,\n };\n}\n\nfunction createChildComponents(\n root: string,\n pathParts: string[],\n): AnyChildComponents {\n const handler: ProxyHandler<object> = {\n get(_, prop: string | symbol) {\n if (typeof prop === \"string\") {\n const newParts = [...pathParts, prop];\n return createChildComponents(root, newParts);\n } else if (prop === toReferencePath) {\n if (pathParts.length < 1) {\n const found = [root, ...pathParts].join(\".\");\n throw new Error(\n `API path is expected to be of the form \\`${root}.childComponent.functionName\\`. Found: \\`${found}\\``,\n );\n }\n return `_reference/childComponent/` + pathParts.join(\"/\");\n } else {\n return undefined;\n }\n },\n };\n return new Proxy({}, handler);\n}\n\nexport const componentsGeneric = () => createChildComponents(\"components\", []);\n\nexport type AnyComponents = AnyChildComponents;\n"],
|
|
5
|
-
"mappings": ";;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA,eAAwB;AAMxB,qBAAoC;AAOpC,mBAIO;AASP,uBAA4B;AAE5B,IAAAA,gBAAmC;AAkCnC,eAAsB,qBAKpB,mBAMiD;AACjD,QAAM,cAAU,iCAAmB,iBAAiB;AACpD,SAAO,UAAM,oCAAoB,4BAA4B;AAAA,IAC3D,GAAG;AAAA,IACH;AAAA,EACF,CAAC;AACH;
|
|
4
|
+
"sourcesContent": ["import { PropertyValidators } from \"../../values/index.js\";\nimport { version } from \"../../index.js\";\nimport {\n AnyFunctionReference,\n FunctionReference,\n FunctionType,\n} from \"../api.js\";\nimport { performAsyncSyscall } from \"../impl/syscall.js\";\nimport { DefaultFunctionArgs } from \"../registration.js\";\nimport {\n AppDefinitionAnalysis,\n ComponentDefinitionAnalysis,\n ComponentDefinitionType,\n} from \"./definition.js\";\nimport {\n getFunctionAddress,\n setReferencePath,\n toReferencePath,\n} from \"./paths.js\";\nimport type {\n Validator,\n VLiteral,\n VOptional,\n VString,\n VUnion,\n} from \"../../values/validators.js\";\nimport type { Infer } from \"../../values/validator.js\";\nimport { isValidator } from \"../../values/validator.js\";\nimport type { Expand } from \"../../type_utils.js\";\nexport { getFunctionAddress } from \"./paths.js\";\n\n/**\n * A serializable reference to a Convex function.\n * Passing a this reference to another component allows that component to call this\n * function during the current function execution or at any later time.\n * Function handles are used like `api.folder.function` FunctionReferences,\n * e.g. `ctx.scheduler.runAfter(0, functionReference, args)`.\n *\n * A function reference is stable across code pushes but it's possible\n * the Convex function it refers to might no longer exist.\n *\n * This is a feature of components, which are in beta.\n * This API is unstable and may change in subsequent releases.\n */\nexport type FunctionHandle<\n Type extends FunctionType,\n Args extends DefaultFunctionArgs = any,\n ReturnType = any,\n> = string & FunctionReference<Type, \"internal\", Args, ReturnType>;\n\n/**\n * Create a serializable reference to a Convex function.\n * Passing a this reference to another component allows that component to call this\n * function during the current function execution or at any later time.\n * Function handles are used like `api.folder.function` FunctionReferences,\n * e.g. `ctx.scheduler.runAfter(0, functionReference, args)`.\n *\n * A function reference is stable across code pushes but it's possible\n * the Convex function it refers to might no longer exist.\n *\n * This is a feature of components, which are in beta.\n * This API is unstable and may change in subsequent releases.\n */\nexport async function createFunctionHandle<\n Type extends FunctionType,\n Args extends DefaultFunctionArgs,\n ReturnType,\n>(\n functionReference: FunctionReference<\n Type,\n \"public\" | \"internal\",\n Args,\n ReturnType\n >,\n): Promise<FunctionHandle<Type, Args, ReturnType>> {\n const address = getFunctionAddress(functionReference);\n return await performAsyncSyscall(\"1.0/createFunctionHandle\", {\n ...address,\n version,\n });\n}\n\ninterface ComponentExports {\n [key: string]: FunctionReference<any, any, any, any> | ComponentExports;\n}\n\n/**\n * An object of this type should be the default export of a\n * convex.config.ts file in a component definition directory.\n *\n * This is a feature of components, which are in beta.\n * This API is unstable and may change in subsequent releases.\n */\nexport type ComponentDefinition<\n Exports extends ComponentExports = any,\n Env extends EnvDefinition = {},\n> = {\n /**\n * Install a component with the given definition in this component definition.\n *\n * Takes a component definition and an optional name.\n *\n * For editor tooling this method expects a {@link ComponentDefinition}\n * but at runtime the object that is imported will be a {@link ImportedComponentDefinition}\n */\n use<Definition extends ComponentDefinition<any, any>>(\n definition: Definition,\n ...args: UseArgs<Definition>\n ): InstalledComponent<Definition>;\n\n /**\n * Internal type-only property tracking exports provided.\n *\n * @deprecated This is a type-only property, don't use it.\n */\n __exports: Exports;\n\n /**\n * References to this component's declared env vars. Pass one of these in\n * `app.use(child, { env: { ... } })` to bind a child's env var by\n * reference to this component's env var.\n */\n env: EnvRefFromDefinition<Env>;\n\n /**\n * Internal type-only property tracking env definition.\n *\n * @deprecated This is a type-only property, don't use it.\n */\n __env: Env;\n};\n\ntype ComponentDefinitionExports<T extends ComponentDefinition<any, any>> =\n T[\"__exports\"];\n\ntype ComponentDefinitionEnv<T extends ComponentDefinition<any, any>> =\n T[\"__env\"];\n\n/**\n * The names in an {@link EnvDefinition} whose validators are required (not\n * wrapped in `v.optional(...)`).\n */\ntype RequiredEnvKeys<E extends EnvDefinition> = {\n [K in keyof E]: E[K] extends Validator<any, \"optional\", any> ? never : K;\n}[keyof E];\n\n/**\n * Options for installing a component via `app.use()` or `component.use()`.\n *\n * If the component declares any required env vars, the `env` property is\n * required. Otherwise it is optional, so that a component with no env vars (or\n * only optional ones) can be installed without passing `env`.\n */\ntype UseOptions<Definition extends ComponentDefinition<any, any>> =\n RequiredEnvKeys<ComponentDefinitionEnv<Definition>> extends never\n ? {\n name?: string;\n httpPrefix?: string;\n env?: UseOptionsEnv<ComponentDefinitionEnv<Definition>>;\n }\n : {\n name?: string;\n httpPrefix?: string;\n env: UseOptionsEnv<ComponentDefinitionEnv<Definition>>;\n };\n\n/**\n * The arguments to `use()` after the component definition.\n *\n * When the component declares required env vars the `options` argument is\n * mandatory (so it can't be dropped to skip the required `env`); otherwise it\n * is optional.\n */\ntype UseArgs<Definition extends ComponentDefinition<any, any>> =\n RequiredEnvKeys<ComponentDefinitionEnv<Definition>> extends never\n ? [options?: UseOptions<Definition>]\n : [options: UseOptions<Definition>];\n\ntype UseOptionsEnv<E extends EnvDefinition> = Expand<\n {\n [K in keyof E as E[K] extends Validator<any, \"optional\", any> ? never : K]:\n | Infer<E[K]>\n | EnvRef;\n } & {\n [K in keyof E as E[K] extends Validator<any, \"optional\", any>\n ? K\n : never]?: Infer<E[K]> | EnvRef | undefined;\n }\n>;\n\n/**\n * A string-like validator: `v.string()`, a string `v.literal(\"...\")`, or a\n * `v.union(...)` of those (recursively). Component env vars are serialized\n * as strings on the wire, so only string-typed validators are allowed.\n *\n * @public\n */\nexport type StringLikeValidator =\n | VString<string, \"required\">\n | VLiteral<string, \"required\">\n | VUnion<string, Validator<any, \"required\", any>[], \"required\">;\n\n/**\n * A definition of environment variables for the app.\n *\n * Maps environment variable names to string-like validators. Use\n * `v.string()` for a plain string, `v.literal(\"a\")` for an enum value, or\n * `v.union(v.literal(\"a\"), v.literal(\"b\"))` for an enum. Wrap in\n * `v.optional(...)` for optional vars.\n *\n * @example\n * ```typescript\n * import { defineApp } from \"convex/server\";\n * import { v } from \"convex/values\";\n *\n * const app = defineApp({\n * env: {\n * OPENAI_API_KEY: v.string(),\n * DEBUG_MODE: v.optional(v.string()),\n * },\n * });\n * ```\n *\n * @public\n */\nexport type EnvDefinition = Record<\n string,\n StringLikeValidator | VOptional<StringLikeValidator>\n>;\n\n/**\n * Compute the typed environment object from an {@link EnvDefinition}.\n *\n * Required entries get the validator's inferred string type; optional\n * entries are `T | undefined`.\n *\n * @public\n */\nexport type EnvFromDefinition<E extends EnvDefinition> = Expand<\n {\n [K in keyof E as E[K] extends Validator<any, \"optional\", any>\n ? never\n : K]: Infer<E[K]>;\n } & {\n [K in keyof E as E[K] extends Validator<any, \"optional\", any>\n ? K\n : never]?: Infer<E[K]> | undefined;\n }\n>;\n\n/**\n * A reference to a parent-declared env var, produced by `app.env.<NAME>` or\n * `component.env.<NAME>`. Pass this in `use(child, { env: { ... } })` to\n * bind a child's declared env var to the parent's env var by reference\n * instead of snapshotting its current value.\n *\n * @public\n */\nexport type EnvRef<K extends string = string> = { __envVarRef: K };\n\n/**\n * Compute the typed `env` namespace object from an {@link EnvDefinition}.\n * Each declared name maps to an {@link EnvRef} for that name.\n *\n * @public\n */\nexport type EnvRefFromDefinition<E extends EnvDefinition> = {\n [K in keyof E & string]: EnvRef<K>;\n};\n\n/**\n * Extract the typed environment from an {@link AppDefinition}.\n *\n * @public\n */\nexport type EnvFromAppDefinition<A> =\n A extends AppDefinition<infer E>\n ? EnvFromDefinition<E>\n : Record<string, never>;\n\n/**\n * An object of this type should be the default export of a\n * convex.config.ts file in a component-aware convex directory.\n *\n * This is a feature of components, which are in beta.\n * This API is unstable and may change in subsequent releases.\n */\nexport type AppDefinition<Env extends EnvDefinition = EnvDefinition> = {\n /**\n * Install a component with the given definition in this component definition.\n *\n * Takes a component definition and an optional name.\n *\n * For editor tooling this method expects a {@link ComponentDefinition}\n * but at runtime the object that is imported will be a {@link ImportedComponentDefinition}\n */\n use<Definition extends ComponentDefinition<any, any>>(\n definition: Definition,\n ...args: UseArgs<Definition>\n ): InstalledComponent<Definition>;\n\n /**\n * References to this app's declared env vars. Pass one of these in\n * `app.use(child, { env: { ... } })` to bind a child's env var by\n * reference to this app's env var.\n */\n env: EnvRefFromDefinition<Env>;\n\n /**\n * Internal type-only property tracking env definition.\n *\n * @deprecated This is a type-only property, don't use it.\n */\n __env: Env;\n};\n\ninterface ExportTree {\n // Tree with serialized `Reference`s as leaves.\n [key: string]: string | ExportTree;\n}\n\ntype CommonDefinitionData = {\n _isRoot: boolean;\n _childComponents: [\n string,\n ImportedComponentDefinition,\n Record<string, any> | null,\n string | undefined,\n ][];\n _exportTree: ExportTree;\n};\n\ntype ComponentDefinitionData = CommonDefinitionData & {\n _env: PropertyValidators;\n _name: string;\n _onInitCallbacks: Record<string, (argsStr: string) => string>;\n};\ntype AppDefinitionData = CommonDefinitionData & {\n _httpPrefix?: string;\n _env?: EnvDefinition;\n};\n\n/**\n * Used to refer to an already-installed component.\n */\nclass InstalledComponent<Definition extends ComponentDefinition<any, any>> {\n /**\n * @internal\n */\n _definition: Definition;\n\n /**\n * @internal\n */\n _name: string;\n\n constructor(definition: Definition, name: string) {\n this._definition = definition;\n this._name = name;\n setReferencePath(this, `_reference/childComponent/${name}`);\n }\n\n get exports(): ComponentDefinitionExports<Definition> {\n return createExports(this._name, []);\n }\n}\n\nfunction createExports(name: string, pathParts: string[]): any {\n const handler: ProxyHandler<any> = {\n get(_, prop: string | symbol) {\n if (typeof prop === \"string\") {\n const newParts = [...pathParts, prop];\n return createExports(name, newParts);\n } else if (prop === toReferencePath) {\n let reference = `_reference/childComponent/${name}`;\n for (const part of pathParts) {\n reference += `/${part}`;\n }\n return reference;\n } else {\n return undefined;\n }\n },\n };\n return new Proxy({}, handler);\n}\n\nfunction createEnvRefs(\n ownerLabel: string,\n declared: Record<string, any> | undefined,\n): any {\n const handler: ProxyHandler<any> = {\n get(_, prop: string | symbol) {\n if (typeof prop !== \"string\") {\n return undefined;\n }\n if (!declared || !Object.prototype.hasOwnProperty.call(declared, prop)) {\n throw new Error(\n `Env var \"${prop}\" is not declared on ${ownerLabel}. Add it to the \\`env\\` option of ${ownerLabel === \"this app\" ? \"defineApp\" : \"defineComponent\"}.`,\n );\n }\n return { __envVarRef: prop };\n },\n };\n return new Proxy({}, handler);\n}\n\nfunction isEnvRef(value: unknown): value is EnvRef {\n return (\n typeof value === \"object\" &&\n value !== null &&\n typeof (value as EnvRef).__envVarRef === \"string\"\n );\n}\n\nfunction use<Definition extends ComponentDefinition<any, any>>(\n this: CommonDefinitionData,\n definition: Definition,\n options?: {\n name?: string;\n httpPrefix?: string;\n env?: Record<string, any>;\n },\n): InstalledComponent<Definition> {\n // At runtime an imported component will have this shape.\n const importedComponentDefinition =\n definition as unknown as ImportedComponentDefinition;\n if (typeof importedComponentDefinition.componentDefinitionPath !== \"string\") {\n throw new Error(\n \"Component definition does not have the required componentDefinitionPath property. This code only works in Convex runtime.\",\n );\n }\n const name =\n options?.name ??\n // added recently\n importedComponentDefinition.defaultName ??\n // can be removed once backend is out\n importedComponentDefinition.componentDefinitionPath.split(\"/\").pop()!;\n\n if (typeof name !== \"string\") {\n throw new Error(\n `Component name must be a string. Received: ${typeof name}`,\n );\n }\n if (name.length === 0) {\n // \"\" is used internally as the name for the root component, so\n // users shouldn't try to define child components with an empty name.\n throw new Error(\"Component name cannot be empty.\");\n }\n\n const httpPrefix = options?.httpPrefix;\n if (httpPrefix !== undefined) {\n if (!httpPrefix.startsWith(\"/\")) {\n throw new Error(\n `httpPrefix must start with \"/\". Received: \"${httpPrefix}\"`,\n );\n }\n }\n\n const envValues: Record<string, any> = {};\n if (options?.env) {\n for (const [key, value] of Object.entries(options.env)) {\n if (value !== undefined) {\n envValues[key] = value;\n }\n }\n }\n\n this._childComponents.push([\n name,\n importedComponentDefinition,\n envValues,\n httpPrefix,\n ]);\n return new InstalledComponent(definition, name);\n}\n\n/**\n * The runtime type of a ComponentDefinition. TypeScript will claim\n * the default export of a module like \"cool-component/convex.config.js\"\n * is a `@link ComponentDefinition}, but during component definition evaluation\n * this is its type instead.\n *\n * This is a feature of components, which are in beta.\n * This API is unstable and may change in subsequent releases.\n */\nexport type ImportedComponentDefinition = {\n componentDefinitionPath: string;\n defaultName: string;\n};\n\nfunction exportAppForAnalysis(\n this: ComponentDefinition<any, any> & AppDefinitionData,\n): AppDefinitionAnalysis {\n const definitionType = { type: \"app\" as const };\n const childComponents = serializeChildComponents(this._childComponents);\n const httpMounts = buildHttpMounts(this._childComponents);\n const envVars = this._env\n ? Object.entries(this._env).map(\n ([name, validator]) =>\n [\n name,\n {\n type: \"value\" as const,\n value: JSON.stringify(validator.json),\n ...(validator.isOptional === \"optional\"\n ? { optional: true }\n : {}),\n },\n ] as [string, { type: \"value\"; value: string; optional?: boolean }],\n )\n : undefined;\n return {\n definitionType,\n ...(this._httpPrefix !== undefined\n ? { httpPrefix: normalizeHttpPrefix(this._httpPrefix) }\n : {}),\n childComponents: childComponents as any,\n httpMounts,\n exports: serializeExportTree(this._exportTree),\n ...(envVars !== undefined ? { envVars } : {}),\n };\n}\n\nfunction serializeExportTree(tree: ExportTree): any {\n const branch: any[] = [];\n for (const [key, child] of Object.entries(tree)) {\n let node;\n if (typeof child === \"string\") {\n node = { type: \"leaf\", leaf: child };\n } else {\n node = serializeExportTree(child);\n }\n branch.push([key, node]);\n }\n return { type: \"branch\", branch };\n}\n\nfunction normalizeHttpPrefix(prefix: string): string {\n // Ensure the prefix ends with \"/\" as required by HttpMountPath in Rust.\n return prefix.endsWith(\"/\") ? prefix : prefix + \"/\";\n}\n\nfunction buildHttpMounts(\n childComponents: [\n string,\n ImportedComponentDefinition,\n Record<string, any> | null,\n string | undefined,\n ][],\n): Record<string, string> {\n const httpMounts: Record<string, string> = {};\n for (const [name, , , httpPrefix] of childComponents) {\n if (httpPrefix !== undefined) {\n const normalized = normalizeHttpPrefix(httpPrefix);\n httpMounts[normalized] = `_reference/childComponent/${name}`;\n }\n }\n return httpMounts;\n}\n\ntype SerializedEnvArg =\n | { type: \"value\"; value: string }\n | { type: \"envVar\"; name: string };\n\nfunction serializeChildComponents(\n childComponents: [\n string,\n ImportedComponentDefinition,\n Record<string, any> | null,\n string | undefined,\n ][],\n): {\n name: string;\n path: string;\n env: [string, SerializedEnvArg][] | null;\n}[] {\n return childComponents.map(([name, definition, p]) => {\n // Note: httpPrefix (4th element) is used separately in buildHttpMounts()\n let env: [string, SerializedEnvArg][] | null = null;\n if (p !== null) {\n env = [];\n for (const [name, value] of Object.entries(p)) {\n if (value === undefined) {\n continue;\n }\n if (isEnvRef(value)) {\n env.push([name, { type: \"envVar\", name: value.__envVarRef }]);\n } else if (typeof value === \"string\") {\n env.push([name, { type: \"value\", value }]);\n } else {\n throw new Error(\n `Env var \"${name}\" must be a string or an env var reference. ` +\n `Received: ${typeof value}`,\n );\n }\n }\n }\n // we know that components carry this extra information\n const path = definition.componentDefinitionPath;\n if (!path)\n throw new Error(\n \"no .componentPath for component definition \" +\n JSON.stringify(definition, null, 2),\n );\n\n return {\n name: name!,\n path: path!,\n args: [],\n env,\n };\n });\n}\n\nfunction exportComponentForAnalysis(\n this: ComponentDefinition<any, any> & ComponentDefinitionData,\n): ComponentDefinitionAnalysis {\n const envVars = Object.entries(this._env).map(\n ([name, validator]) =>\n [\n name,\n {\n type: \"value\" as const,\n value: JSON.stringify((validator as any).json),\n ...((validator as any).isOptional === \"optional\"\n ? { optional: true }\n : {}),\n },\n ] as [string, { type: \"value\"; value: string; optional?: boolean }],\n );\n const definitionType: ComponentDefinitionType = {\n type: \"childComponent\" as const,\n name: this._name,\n args: [],\n };\n const childComponents = serializeChildComponents(this._childComponents);\n const httpMounts = buildHttpMounts(this._childComponents);\n return {\n name: this._name,\n definitionType,\n childComponents: childComponents as any,\n httpMounts,\n exports: serializeExportTree(this._exportTree),\n ...(envVars.length > 0 ? { envVars } : {}),\n };\n}\n\n// This is what is actually contained in a ComponentDefinition.\ntype RuntimeComponentDefinition = Omit<\n ComponentDefinition<any, any>,\n \"__exports\" | \"__env\"\n> &\n ComponentDefinitionData & {\n export: () => ComponentDefinitionAnalysis;\n };\ntype RuntimeAppDefinition = Omit<AppDefinition<any>, \"__env\"> &\n AppDefinitionData & {\n export: () => AppDefinitionAnalysis;\n };\n\n/**\n * Define a component, a piece of a Convex deployment with namespaced resources.\n *\n * Optionally define typed environment variables that will be available via\n * the `env` export from `_generated/server` in all Convex functions within\n * this component. Values are passed by the parent via\n * `app.use(component, { env: { ... } })`.\n *\n * @param name Name must be alphanumeric plus underscores. Typically these are\n * lowercase with underscores like `\"onboarding_flow_tracker\"`.\n *\n * This is a feature of components, which are in beta.\n * This API is unstable and may change in subsequent releases.\n */\nexport function defineComponent<\n Exports extends ComponentExports = any,\n const Env extends EnvDefinition = {},\n>(\n name: string,\n options?: {\n env?: Env;\n },\n): ComponentDefinition<Exports, Env> {\n const envValidators: PropertyValidators = {};\n if (options?.env) {\n for (const [key, decl] of Object.entries(options.env)) {\n if (decl !== null && decl !== undefined && isValidator(decl)) {\n envValidators[key] = decl as any;\n } else {\n throw new Error(\n `Environment variable \"${key}\" must be defined with a validator (e.g. v.string()).`,\n );\n }\n }\n }\n\n const ret: RuntimeComponentDefinition = {\n _isRoot: false,\n _name: name,\n _env: envValidators,\n _childComponents: [],\n _exportTree: {},\n _onInitCallbacks: {},\n\n env: createEnvRefs(`component \"${name}\"`, options?.env),\n\n export: exportComponentForAnalysis,\n use,\n\n ...({} as { __exports: any; __env: any }),\n };\n return ret as any as ComponentDefinition<Exports, Env>;\n}\n\n/**\n * Attach components, reuseable pieces of a Convex deployment, to this Convex app.\n *\n * Optionally define typed environment variables that will be available via\n * the `env` export from `_generated/server` in all Convex functions.\n *\n * @example\n * ```typescript\n * import { defineApp } from \"convex/server\";\n * import { v } from \"convex/values\";\n *\n * const app = defineApp({\n * env: {\n * OPENAI_API_KEY: v.string(),\n * DEBUG_MODE: v.optional(v.string()),\n * },\n * });\n * export default app;\n * ```\n *\n * This is a feature of components, which are in beta.\n * This API is unstable and may change in subsequent releases.\n */\nexport function defineApp<Env extends EnvDefinition = EnvDefinition>(options?: {\n httpPrefix?: string;\n env?: Env;\n}): AppDefinition<Env> {\n const httpPrefix = options?.httpPrefix;\n if (httpPrefix !== undefined && !httpPrefix.startsWith(\"/\")) {\n throw new Error(\n `httpPrefix must start with \"/\". Received: \"${httpPrefix}\"`,\n );\n }\n const env = options?.env;\n if (env !== undefined) {\n for (const [name, validator] of Object.entries(env)) {\n if (!isValidator(validator)) {\n throw new Error(\n `Environment variable \"${name}\" must be defined with a validator (e.g. v.string()).`,\n );\n }\n }\n }\n const ret: RuntimeAppDefinition = {\n _isRoot: true,\n _childComponents: [],\n _exportTree: {},\n ...(httpPrefix !== undefined ? { _httpPrefix: httpPrefix } : {}),\n ...(env !== undefined ? { _env: env } : {}),\n\n env: createEnvRefs(\"this app\", env),\n\n export: exportAppForAnalysis,\n use,\n };\n return ret as unknown as AppDefinition<Env>;\n}\n\ntype AnyInterfaceType = {\n [key: string]: AnyInterfaceType;\n} & AnyFunctionReference;\nexport type AnyComponentReference = Record<string, AnyInterfaceType>;\n\nexport type AnyChildComponents = Record<string, AnyComponentReference>;\n\n/**\n * @internal\n */\nexport function currentSystemUdfInComponent(\n componentId: string,\n): AnyComponentReference {\n return {\n [toReferencePath]: `_reference/currentSystemUdfInComponent/${componentId}`,\n };\n}\n\nfunction createChildComponents(\n root: string,\n pathParts: string[],\n): AnyChildComponents {\n const handler: ProxyHandler<object> = {\n get(_, prop: string | symbol) {\n if (typeof prop === \"string\") {\n const newParts = [...pathParts, prop];\n return createChildComponents(root, newParts);\n } else if (prop === toReferencePath) {\n if (pathParts.length < 1) {\n const found = [root, ...pathParts].join(\".\");\n throw new Error(\n `API path is expected to be of the form \\`${root}.childComponent.functionName\\`. Found: \\`${found}\\``,\n );\n }\n return `_reference/childComponent/` + pathParts.join(\"/\");\n } else {\n return undefined;\n }\n },\n };\n return new Proxy({}, handler);\n}\n\nexport const componentsGeneric = () => createChildComponents(\"components\", []);\n\nexport type AnyComponents = AnyChildComponents;\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
6
|
"names": ["import_paths", "name"]
|
|
7
7
|
}
|