cvx-kit 0.1.7 → 0.1.10
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +15 -0
- package/README.md +63 -47
- package/dist/agent-tools.d.mts +5 -5
- package/dist/agent-tools.mjs.map +1 -1
- package/dist/auth.d.mts +39 -289
- package/dist/auth.mjs.map +1 -1
- package/dist/components/approvals/_generated/api.d.mts +3 -4
- package/dist/components/approvals/_generated/api.mjs.map +1 -1
- package/dist/components/approvals/_generated/component.d.mts +1 -2
- package/dist/components/approvals/_generated/dataModel.d.mts +4 -5
- package/dist/components/approvals/_generated/server.d.mts +12 -13
- package/dist/components/approvals/_generated/server.mjs.map +1 -1
- package/dist/components/approvals/audit.d.mts +8 -8
- package/dist/components/approvals/audit.mjs +1 -1
- package/dist/components/approvals/audit.mjs.map +1 -1
- package/dist/components/approvals/client.d.mts +10 -10
- package/dist/components/approvals/client.mjs.map +1 -1
- package/dist/components/approvals/constants.d.mts +30 -30
- package/dist/components/approvals/constants.mjs.map +1 -1
- package/dist/components/approvals/convex.config.mjs.map +1 -1
- package/dist/components/approvals/decisions.d.mts +6 -6
- package/dist/components/approvals/decisions.mjs.map +1 -1
- package/dist/components/approvals/functions.d.mts +3 -3
- package/dist/components/approvals/functions.mjs.map +1 -1
- package/dist/components/approvals/health.d.mts +2 -2
- package/dist/components/approvals/health.mjs.map +1 -1
- package/dist/components/approvals/requests.d.mts +8 -8
- package/dist/components/approvals/requests.mjs.map +1 -1
- package/dist/components/approvals/validators.d.mts +29 -29
- package/dist/components/approvals/validators.mjs +1 -1
- package/dist/components/approvals/validators.mjs.map +1 -1
- package/dist/components/approvals/workflow.d.mts +3 -3
- package/dist/components/approvals/workflow.mjs.map +1 -1
- package/dist/components/approvals/workflow_steps.d.mts +15 -15
- package/dist/components/approvals/workflow_steps.mjs.map +1 -1
- package/dist/components/foundation/_generated/api.d.mts +3 -4
- package/dist/components/foundation/_generated/api.mjs.map +1 -1
- package/dist/components/foundation/_generated/component.d.mts +1 -2
- package/dist/components/foundation/_generated/dataModel.d.mts +4 -5
- package/dist/components/foundation/_generated/server.d.mts +12 -13
- package/dist/components/foundation/_generated/server.mjs.map +1 -1
- package/dist/components/foundation/client.d.mts +21 -13
- package/dist/components/foundation/client.mjs.map +1 -1
- package/dist/components/foundation/convex.config.mjs.map +1 -1
- package/dist/components/foundation/functions.d.mts +2 -2
- package/dist/components/foundation/functions.mjs.map +1 -1
- package/dist/components/foundation/modules/command/command.d.mts +14 -14
- package/dist/components/foundation/modules/command/command.mjs.map +1 -1
- package/dist/components/foundation/modules/command/lifecycle.d.mts +12 -13
- package/dist/components/foundation/modules/command/lifecycle.mjs.map +1 -1
- package/dist/components/foundation/modules/observability/observability.d.mts +4 -4
- package/dist/components/foundation/modules/observability/observability.mjs.map +1 -1
- package/dist/components/foundation/modules/query/query.d.mts +5 -5
- package/dist/components/foundation/modules/query/query.mjs.map +1 -1
- package/dist/components/foundation/operation.d.mts +5 -6
- package/dist/components/foundation/operation.mjs.map +1 -1
- package/dist/components/foundation/result.d.mts +6 -6
- package/dist/components/foundation/result.mjs.map +1 -1
- package/dist/components/foundation/telemetry.d.mts +2 -2
- package/dist/components/foundation/telemetry.mjs.map +1 -1
- package/dist/crud.d.mts +6 -5
- package/dist/crud.mjs.map +1 -1
- package/dist/errors.d.mts +4 -4
- package/dist/errors.mjs.map +1 -1
- package/dist/index.d.mts +2 -2
- package/dist/middleware.d.mts +2 -3
- package/dist/middleware.mjs.map +1 -1
- package/dist/modules/contracts/contract.d.mts +12 -13
- package/dist/modules/contracts/contract.mjs.map +1 -1
- package/dist/modules/contracts/convex.d.mts +3 -5
- package/dist/modules/contracts/convex.mjs.map +1 -1
- package/dist/modules/contracts/errors.d.mts +8 -9
- package/dist/modules/contracts/errors.mjs +1 -1
- package/dist/modules/contracts/errors.mjs.map +1 -1
- package/dist/modules/contracts/exposure.d.mts +13 -14
- package/dist/modules/contracts/exposure.mjs +1 -1
- package/dist/modules/contracts/exposure.mjs.map +1 -1
- package/dist/modules/contracts/idempotency.d.mts +15 -16
- package/dist/modules/contracts/idempotency.mjs +1 -1
- package/dist/modules/contracts/idempotency.mjs.map +1 -1
- package/dist/modules/contracts/standard.d.mts +2 -3
- package/dist/modules/contracts/standard.mjs.map +1 -1
- package/dist/modules/contracts/workflow.d.mts +26 -27
- package/dist/modules/contracts/workflow.mjs.map +1 -1
- package/dist/modules/effect/api-runtime.d.mts +20 -11
- package/dist/modules/effect/api-runtime.mjs +1 -1
- package/dist/modules/effect/api-runtime.mjs.map +1 -1
- package/dist/modules/effect/api-zod.d.mts +5 -6
- package/dist/modules/effect/api-zod.mjs.map +1 -1
- package/dist/modules/effect/api.d.mts +6 -7
- package/dist/modules/effect/api.mjs.map +1 -1
- package/dist/modules/effect/command.d.mts +10 -7
- package/dist/modules/effect/command.mjs +1 -1
- package/dist/modules/effect/command.mjs.map +1 -1
- package/dist/modules/effect/crud.d.mts +7 -8
- package/dist/modules/effect/crud.mjs.map +1 -1
- package/dist/modules/effect/errors.d.mts +1 -2
- package/dist/modules/effect/errors.mjs.map +1 -1
- package/dist/modules/effect/foundation.d.mts +3 -4
- package/dist/modules/effect/foundation.mjs.map +1 -1
- package/dist/modules/effect/idempotency.d.mts +2 -3
- package/dist/modules/effect/idempotency.mjs.map +1 -1
- package/dist/modules/effect/normalize.d.mts +2 -3
- package/dist/modules/effect/normalize.mjs.map +1 -1
- package/dist/modules/effect/operation.d.mts +17 -18
- package/dist/modules/effect/operation.mjs.map +1 -1
- package/dist/modules/effect/query.d.mts +8 -5
- package/dist/modules/effect/query.mjs +1 -1
- package/dist/modules/effect/query.mjs.map +1 -1
- package/dist/modules/effect/schema.d.mts +8 -9
- package/dist/modules/effect/schema.mjs.map +1 -1
- package/dist/modules/effect/workflow.d.mts +5 -6
- package/dist/modules/effect/workflow.mjs.map +1 -1
- package/dist/oxlint/architecture.d.mts +6 -7
- package/dist/oxlint/architecture.mjs +1 -1
- package/dist/oxlint/architecture.mjs.map +1 -1
- package/dist/oxlint/ast.d.mts +22 -23
- package/dist/oxlint/ast.mjs +1 -1
- package/dist/oxlint/ast.mjs.map +1 -1
- package/dist/oxlint/ownership.d.mts +2 -3
- package/dist/oxlint/ownership.mjs +1 -1
- package/dist/oxlint/ownership.mjs.map +1 -1
- package/dist/oxlint.d.mts +4 -4
- package/dist/oxlint.mjs +1 -1
- package/dist/oxlint.mjs.map +1 -1
- package/dist/state-machine.d.mts +1 -2
- package/dist/state-machine.mjs.map +1 -1
- package/dist/tenancy.d.mts +6 -6
- package/dist/tenancy.mjs.map +1 -1
- package/dist/triggers.d.mts +6 -6
- package/dist/triggers.mjs.map +1 -1
- package/dist/webhooks.d.mts +5 -6
- package/dist/webhooks.mjs.map +1 -1
- package/dist/zod-table.d.mts +10 -10
- package/dist/zod-table.mjs.map +1 -1
- package/docs/architecture.md +3 -3
- package/docs/auth.md +10 -4
- package/docs/command-context.md +150 -0
- package/docs/commands-legacy.md +511 -0
- package/docs/commands.md +113 -451
- package/docs/conventions.md +15 -5
- package/docs/crud.md +4 -0
- package/docs/domain-operations.md +1 -1
- package/docs/effect.md +14 -3
- package/docs/llms.md +69 -45
- package/docs/migration.md +1 -1
- package/docs/oxlint.md +1 -1
- package/docs/upgrading.md +18 -1
- package/docs/zod-table.md +1 -1
- package/package.json +21 -15
- package/scripts/test-packed-auth.mjs +68 -0
- package/scripts/test-packed-effect.mjs +4 -1
- package/scripts/test-packed-ids.mjs +2 -2
- package/dist/node_modules/@standard-schema/spec/dist/index.d.mts +0 -79
package/dist/auth.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"auth.mjs","names":[],"sources":["../src/auth.ts"],"sourcesContent":["import { z } from 'zod'\nimport { zCustomAction, zCustomMutation, zCustomQuery } from 'convex-helpers/server/zod4'\nimport type {\n\tActionBuilder,\n\tDocumentByInfo,\n\tPaginationOptions,\n\tPaginationResult,\n\tGenericActionCtx,\n\tGenericDataModel,\n\tGenericMutationCtx,\n\tGenericQueryCtx,\n\tGenericTableInfo,\n\tIndexNames,\n\tIndexRange,\n\tIndexRangeBuilder,\n\tMutationBuilder,\n\tNamedIndex,\n\tQuery,\n\tQueryBuilder,\n\tQueryInitializer,\n\tUserIdentity,\n} from 'convex/server'\nimport type { Triggers } from 'convex-helpers/server/triggers'\nimport type { TableNamesInDataModel } from 'convex/server'\nimport { defaultErrors, type ErrorFactory } from './errors'\nimport {\n\tcomposeRules,\n\tcreateTenantRules,\n\twrapDatabaseReader,\n\twrapDatabaseWriter,\n\ttype RLSConfig,\n\ttype Rules,\n} from './tenancy'\n\n/** The default vocabulary; every app can supply its own via the Role generic. */\nexport type DefaultRole = 'reader' | 'writer' | 'admin'\n\nexport type Actor<Role extends string> = Readonly<{\n\tuserId: string\n\torganizationId: string\n\trole: Role\n}>\n\nexport type AuthBundle<Role extends string> = Readonly<{\n\tidentity: UserIdentity\n\tuser: Readonly<{ id: string }>\n\torg: Readonly<{ organizationId: string; role: Role }>\n\trole: Role\n\tactor: Actor<Role>\n\t/** The resolved tenant — security.tenancy.resolve, or the organization id. */\n\ttenant: string\n}>\n\n/**\n * Row-level security configuration. Tenant isolation and role-level rules\n * compose (AND) onto the same wrapped database: queries get a wrapped\n * reader, mutations get triggers first, then a wrapped writer.\n */\nexport type SecurityConfig<DataModel extends GenericDataModel, Role extends string> = {\n\t/**\n\t * Tenant isolation. `tables` is THE registry: every listed table gets\n\t * read/insert/modify gated on row.tenant === ctx.tenant. Pair with\n\t * tenantTable (schema) and tenantOwnership (triggers) on the same list.\n\t */\n\ttenancy?: {\n\t\ttables: readonly TableNamesInDataModel<DataModel>[]\n\t\t/** Maps the auth bundle to the tenant; defaults to org.organizationId. */\n\t\tresolve?: (bundle: Omit<AuthBundle<Role>, 'tenant'>) => string\n\t}\n\t/**\n\t * Role-level (or any policy) rules derived from the authenticated bundle,\n\t * composed AND-wise with tenant isolation. E.g. gate `modify` on a table\n\t * to admin roles.\n\t */\n\trules?: (bundle: AuthBundle<Role>) => Rules<unknown, DataModel>\n\t/**\n\t * Policy for tables with no rule. Defaults to 'deny' when tenancy is\n\t * configured (unlisted tables are unreachable — fail closed), 'allow'\n\t * otherwise.\n\t */\n\tdefaultPolicy?: RLSConfig['defaultPolicy']\n}\n\ntype AnyAuthContext<DataModel extends GenericDataModel> =\n\t| GenericQueryCtx<DataModel>\n\t| GenericMutationCtx<DataModel>\n\t| GenericActionCtx<DataModel>\n\nexport type AuthFunctionsConfig<DataModel extends GenericDataModel, Role extends string> = {\n\t/** The consumer's generated function builders (from ./_generated/server). */\n\tquery: QueryBuilder<DataModel, 'public'>\n\tmutation: MutationBuilder<DataModel, 'public'>\n\taction: ActionBuilder<DataModel, 'public'>\n\tinternalQuery: QueryBuilder<DataModel, 'internal'>\n\tinternalMutation: MutationBuilder<DataModel, 'internal'>\n\tinternalAction: ActionBuilder<DataModel, 'internal'>\n\t/** Resolves the synchronized principal, e.g. (ctx) => authKit.getAuthUser(ctx). */\n\tgetAuthUser: (ctx: AnyAuthContext<DataModel>) => Promise<{ id: string } | null>\n\t/**\n\t * Maps an identity role slug onto the app's role vocabulary. Returning\n\t * null rejects the caller with FORBIDDEN — unknown roles never pass.\n\t */\n\tmapRole: (roleSlug?: string) => Role | null\n\t/** Roles allowed through the admin* constructors. */\n\tadminRoles: readonly NoInfer<Role>[]\n\t/**\n\t * Live membership check for actions (queries/mutations trust the JWT).\n\t * Authentication fails closed with FORBIDDEN when verification errors.\n\t * Omit to let actions trust the JWT like queries do.\n\t */\n\tverifyMembership?: (input: {\n\t\tuserId: string\n\t\torganizationId: string\n\t}) => Promise<{ organizationId: string; roleSlug: string } | null>\n\t/**\n\t * Resolves organization authority from the app's own data for identity\n\t * providers whose tokens carry no org claims. When configured, its result\n\t * overrides claim-based resolution; null or an error rejects with FORBIDDEN\n\t * (fail closed). In actions the ctx has no db — resolve via ctx.runQuery.\n\t */\n\tresolveOrganization?: (input: {\n\t\tctx: AnyAuthContext<DataModel>\n\t\tidentity: UserIdentity\n\t\tuser: { id: string }\n\t}) => Promise<{ organizationId: string; roleSlug: string } | null>\n\t/** Host error policy; defaults to throwing KitError. */\n\terrors?: ErrorFactory\n\t/**\n\t * Application trigger registry. When set, every authMutation,\n\t * roleMutation, and systemMutation write runs through triggers.wrapDB —\n\t * evaluations registered on tables fire structurally.\n\t */\n\ttriggers?: Triggers<DataModel>\n\t/** Lower-level alternative to `triggers`: a custom ctx wrapper. */\n\twrapDB?: (ctx: GenericMutationCtx<DataModel>) => GenericMutationCtx<DataModel>\n\t/** Upper bound for include() reads. */\n\tmaxIncludedQueryRows?: number\n\t/**\n\t * Row-level security: tenant isolation (from a table registry) and\n\t * role-level rules, applied structurally inside every auth*, role*, and\n\t * admin* constructor. system* constructors stay unwrapped (trusted).\n\t */\n\tsecurity?: SecurityConfig<DataModel, Role>\n}\n\n/** WorkOS-style default: `member` writes; reader/writer/admin pass through. */\nexport function defaultRoleMap(roleSlug?: string): DefaultRole | null {\n\tconst normalized = roleSlug?.trim().toLowerCase()\n\tif (normalized === 'member') return 'writer'\n\treturn normalized === 'reader' || normalized === 'writer' || normalized === 'admin'\n\t\t? normalized\n\t\t: null\n}\n\nexport type IncludedQuery<Table extends GenericTableInfo> = {\n\twhen<Value>(\n\t\tvalue: Value | null | undefined,\n\t\tselect: (query: QueryInitializer<Table>, value: Value) => Query<Table>,\n\t): IncludedQuery<Table>\n\tmatching<IndexName extends IndexNames<Table>>(\n\t\tindexName: IndexName,\n\t\tindexRange?: (\n\t\t\tquery: IndexRangeBuilder<DocumentByInfo<Table>, NamedIndex<Table, IndexName>>,\n\t\t) => IndexRange,\n\t\tshouldMatch?: boolean,\n\t): IncludedQuery<Table>\n\totherwise(select: (query: QueryInitializer<Table>) => Query<Table>): Query<Table>\n\tresolve(): Query<Table>\n\texecute(limit: number): Promise<DocumentByInfo<Table>[]>\n\texecute<Result>(\n\t\tlimit: number,\n\t\ttransform: (data: Awaited<ReturnType<Query<Table>['take']>>) => Result | Promise<Result>,\n\t): Promise<Result>\n\t/**\n\t * Cursor pagination over the selected indexed query. numItems is bounded\n\t * by the same maxRows policy as execute(). Under row-level security a\n\t * page may be shorter than numItems (rejected rows are filtered after\n\t * pagination); cursors remain correct. Pair with paginated(dto) from\n\t * cvx-kit/zod-table for the boundary schemas.\n\t */\n\tpaginate(opts: PaginationOptions): Promise<PaginationResult<DocumentByInfo<Table>>>\n\tpaginate<Item>(\n\t\topts: PaginationOptions,\n\t\ttransform: (page: DocumentByInfo<Table>[]) => Item[] | Promise<Item[]>,\n\t): Promise<PaginationResult<Item>>\n}\n\nexport type Include = <Table extends GenericTableInfo>(\n\tquery: QueryInitializer<Table>,\n) => IncludedQuery<Table>\n\n/** Builds an include() that selects the first matching indexed query and bounds the read. */\nexport function createInclude(options?: { errors?: ErrorFactory; maxRows?: number }): Include {\n\tconst errors = options?.errors ?? defaultErrors\n\tconst maxRows = options?.maxRows ?? 100\n\n\tfunction attach<Table extends GenericTableInfo>(\n\t\tquery: QueryInitializer<Table>,\n\t\tselected?: Query<Table>,\n\t): IncludedQuery<Table> {\n\t\tfunction execute(limit: number): Promise<DocumentByInfo<Table>[]>\n\t\tfunction execute<Result>(\n\t\t\tlimit: number,\n\t\t\ttransform: (data: DocumentByInfo<Table>[]) => Result | Promise<Result>,\n\t\t): Promise<Result>\n\t\tasync function execute<Result>(\n\t\t\tlimit: number,\n\t\t\ttransform?: (data: DocumentByInfo<Table>[]) => Result | Promise<Result>,\n\t\t) {\n\t\t\tif (!Number.isSafeInteger(limit) || limit < 1 || limit > maxRows) {\n\t\t\t\treturn errors.throw({\n\t\t\t\t\tcode: 'INVALID_REQUEST_BOUNDARY',\n\t\t\t\t\tmessage: `A bounded query limit must be from 1 to ${maxRows}`,\n\t\t\t\t})\n\t\t\t}\n\t\t\tconst data = await (selected ?? query.fullTableScan()).take(limit)\n\t\t\treturn transform ? transform(data) : data\n\t\t}\n\t\tfunction paginate(opts: PaginationOptions): Promise<PaginationResult<DocumentByInfo<Table>>>\n\t\tfunction paginate<Item>(\n\t\t\topts: PaginationOptions,\n\t\t\ttransform: (page: DocumentByInfo<Table>[]) => Item[] | Promise<Item[]>,\n\t\t): Promise<PaginationResult<Item>>\n\t\tasync function paginate<Item>(\n\t\t\topts: PaginationOptions,\n\t\t\ttransform?: (page: DocumentByInfo<Table>[]) => Item[] | Promise<Item[]>,\n\t\t) {\n\t\t\tif (!Number.isSafeInteger(opts.numItems) || opts.numItems < 1 || opts.numItems > maxRows) {\n\t\t\t\treturn errors.throw({\n\t\t\t\t\tcode: 'INVALID_REQUEST_BOUNDARY',\n\t\t\t\t\tmessage: `A page size must be from 1 to ${maxRows}`,\n\t\t\t\t})\n\t\t\t}\n\t\t\tconst result = await (selected ?? query.fullTableScan()).paginate(opts)\n\t\t\treturn transform ? { ...result, page: await transform(result.page) } : result\n\t\t}\n\t\treturn {\n\t\t\twhen: (value, select) =>\n\t\t\t\tselected || value === undefined || value === null\n\t\t\t\t\t? attach(query, selected)\n\t\t\t\t\t: attach(query, select(query, value)),\n\t\t\tmatching: (indexName, indexRange, shouldMatch = true) =>\n\t\t\t\tselected || !shouldMatch\n\t\t\t\t\t? attach(query, selected)\n\t\t\t\t\t: attach(query, query.withIndex(indexName, indexRange)),\n\t\t\totherwise: (select) => selected ?? select(query),\n\t\t\tresolve: () => selected ?? query.fullTableScan(),\n\t\t\texecute,\n\t\t\tpaginate,\n\t\t}\n\t}\n\n\treturn (query) => attach(query)\n}\n\n/**\n * Builds the auth-aware function constructors from the host's injected\n * policy: identity resolution, the app's own role vocabulary, live\n * membership verification for actions, trigger wrapping for mutations,\n * and errors. Role-based access is first-class — every constructor family\n * has a role-gated variant (roleQuery/roleMutation/roleAction), and the\n * admin* constructors are just that gate applied to config.adminRoles.\n */\nexport function createAuthFunctions<\n\tDataModel extends GenericDataModel,\n\tconst Role extends string = DefaultRole,\n>(config: AuthFunctionsConfig<DataModel, Role>) {\n\tconst errors = config.errors ?? defaultErrors\n\tconst triggers = config.triggers\n\tconst wrapDB = triggers\n\t\t? (ctx: GenericMutationCtx<DataModel>) => triggers.wrapDB(ctx)\n\t\t: (config.wrapDB ?? ((ctx) => ctx))\n\tconst include = createInclude({\n\t\terrors,\n\t\tmaxRows: config.maxIncludedQueryRows,\n\t})\n\n\tasync function authenticatedUser(ctx: AnyAuthContext<DataModel>): Promise<AuthBundle<Role>> {\n\t\tconst identity = await ctx.auth.getUserIdentity()\n\t\tconst user = identity ? await config.getAuthUser(ctx) : null\n\t\tif (!identity || !user) return errors.throw({ code: 'UNAUTHENTICATED' })\n\t\tlet organizationId: string\n\t\tlet organizationRole: string | undefined\n\t\tif (config.resolveOrganization) {\n\t\t\t// The hook is the organization authority — claims are skipped\n\t\t\t// entirely. Authentication fails closed when it errors or abstains.\n\t\t\tlet resolved: { organizationId: string; roleSlug: string } | null = null\n\t\t\ttry {\n\t\t\t\tresolved = await config.resolveOrganization({ ctx, identity, user })\n\t\t\t} catch {\n\t\t\t\t// Authentication fails closed when the hook cannot resolve.\n\t\t\t}\n\t\t\tif (!resolved) return errors.throw({ code: 'FORBIDDEN' })\n\t\t\torganizationId = resolved.organizationId\n\t\t\torganizationRole = resolved.roleSlug\n\t\t} else {\n\t\t\tconst claims = organizationClaims.parse(identity)\n\t\t\tconst claimedOrganizationId = claims.organization?.organizationId ?? claims.org_id\n\t\t\tif (!claimedOrganizationId) return errors.throw({ code: 'UNAUTHENTICATED' })\n\t\t\torganizationId = claimedOrganizationId\n\t\t\torganizationRole = claims.organization?.role ?? claims.role\n\t\t}\n\t\tconst role = config.mapRole(organizationRole)\n\t\tif (!role) return errors.throw({ code: 'FORBIDDEN' })\n\t\tconst base = {\n\t\t\tidentity,\n\t\t\tuser: Object.freeze({ id: user.id }),\n\t\t\torg: Object.freeze({ organizationId, role }),\n\t\t\trole,\n\t\t\tactor: Object.freeze({ userId: user.id, organizationId, role }),\n\t\t}\n\t\treturn Object.freeze({\n\t\t\t...base,\n\t\t\ttenant: config.security?.tenancy?.resolve?.(base) ?? organizationId,\n\t\t})\n\t}\n\n\tconst securityConfig: RLSConfig | undefined = config.security\n\t\t? {\n\t\t\t\tdefaultPolicy:\n\t\t\t\t\tconfig.security.defaultPolicy ?? (config.security.tenancy ? 'deny' : 'allow'),\n\t\t\t}\n\t\t: undefined\n\n\tfunction securityRules(bundle: AuthBundle<Role>): Rules<unknown, DataModel> | undefined {\n\t\tconst security = config.security\n\t\tif (!security) return undefined\n\t\tconst sets: Rules<unknown, DataModel>[] = []\n\t\tif (security.tenancy) {\n\t\t\tsets.push(createTenantRules<DataModel>(bundle.tenant, security.tenancy.tables))\n\t\t}\n\t\tif (security.rules) sets.push(security.rules(bundle))\n\t\treturn sets.length === 1 ? sets[0] : composeRules(...sets)\n\t}\n\n\tfunction secureReader(\n\t\tctx: GenericQueryCtx<DataModel>,\n\t\tbundle: AuthBundle<Role>,\n\t): GenericQueryCtx<DataModel> {\n\t\tconst rules = securityRules(bundle)\n\t\tif (!rules) return ctx\n\t\treturn {\n\t\t\t...ctx,\n\t\t\tdb: wrapDatabaseReader({}, ctx.db, rules, securityConfig),\n\t\t}\n\t}\n\n\tfunction secureWriter(\n\t\tctx: GenericMutationCtx<DataModel>,\n\t\tbundle: AuthBundle<Role>,\n\t): GenericMutationCtx<DataModel> {\n\t\tconst rules = securityRules(bundle)\n\t\tif (!rules) return ctx\n\t\t// Triggers wrap first (ctx already trigger-wrapped by the caller),\n\t\t// then row-level security wraps the triggered db — order matters.\n\t\treturn {\n\t\t\t...ctx,\n\t\t\tdb: wrapDatabaseWriter({}, ctx.db, rules, securityConfig),\n\t\t}\n\t}\n\n\tasync function verifiedMembership(userId: string, organizationId: string) {\n\t\tif (!config.verifyMembership) return null\n\t\ttry {\n\t\t\tconst membership = await config.verifyMembership({\n\t\t\t\tuserId,\n\t\t\t\torganizationId,\n\t\t\t})\n\t\t\tif (membership && membership.organizationId === organizationId) {\n\t\t\t\treturn membership\n\t\t\t}\n\t\t} catch {\n\t\t\t// Authentication fails closed when membership cannot be verified.\n\t\t}\n\t\treturn errors.throw({ code: 'FORBIDDEN' })\n\t}\n\n\tfunction requireRole(role: Role, allowed: readonly Role[]) {\n\t\tif (!allowed.includes(role)) return errors.throw({ code: 'FORBIDDEN' })\n\t}\n\n\tasync function queryInput(ctx: GenericQueryCtx<DataModel>) {\n\t\tconst bundle = await authenticatedUser(ctx)\n\t\treturn {\n\t\t\tctx: { ...secureReader(ctx, bundle), include, ...bundle },\n\t\t\targs: {},\n\t\t}\n\t}\n\n\tasync function mutationInput(ctx: GenericMutationCtx<DataModel>) {\n\t\tconst bundle = await authenticatedUser(ctx)\n\t\treturn {\n\t\t\tctx: { ...secureWriter(wrapDB(ctx), bundle), include, ...bundle },\n\t\t\targs: {},\n\t\t}\n\t}\n\n\tasync function actionInput(ctx: GenericActionCtx<DataModel>) {\n\t\tconst authenticated = await authenticatedUser(ctx)\n\t\tconst membership = await verifiedMembership(\n\t\t\tauthenticated.user.id,\n\t\t\tauthenticated.org.organizationId,\n\t\t)\n\t\tif (!membership) return { ctx: { ...ctx, ...authenticated }, args: {} }\n\t\tconst role = config.mapRole(membership.roleSlug)\n\t\tif (!role) return errors.throw({ code: 'FORBIDDEN' })\n\t\tconst verified = {\n\t\t\tidentity: authenticated.identity,\n\t\t\tuser: authenticated.user,\n\t\t\torg: Object.freeze({\n\t\t\t\torganizationId: membership.organizationId,\n\t\t\t\trole,\n\t\t\t}),\n\t\t\trole,\n\t\t\tactor: Object.freeze({\n\t\t\t\tuserId: authenticated.user.id,\n\t\t\t\torganizationId: membership.organizationId,\n\t\t\t\trole,\n\t\t\t}),\n\t\t}\n\t\treturn {\n\t\t\tctx: {\n\t\t\t\t...ctx,\n\t\t\t\t...verified,\n\t\t\t\t// Tenant re-derives from the live-verified organization.\n\t\t\t\ttenant: config.security?.tenancy?.resolve?.(verified) ?? membership.organizationId,\n\t\t\t},\n\t\t\targs: {},\n\t\t}\n\t}\n\n\t/** Query constructor allowing only the given roles. */\n\tfunction roleQuery(...allowed: readonly Role[]) {\n\t\treturn zCustomQuery(config.query, {\n\t\t\targs: {},\n\t\t\tinput: async (ctx) => {\n\t\t\t\tconst authenticated = await queryInput(ctx)\n\t\t\t\trequireRole(authenticated.ctx.actor.role, allowed)\n\t\t\t\treturn authenticated\n\t\t\t},\n\t\t})\n\t}\n\n\t/** Mutation constructor allowing only the given roles. */\n\tfunction roleMutation(...allowed: readonly Role[]) {\n\t\treturn zCustomMutation(config.mutation, {\n\t\t\targs: {},\n\t\t\tinput: async (ctx) => {\n\t\t\t\tconst authenticated = await mutationInput(ctx)\n\t\t\t\trequireRole(authenticated.ctx.actor.role, allowed)\n\t\t\t\treturn authenticated\n\t\t\t},\n\t\t})\n\t}\n\n\t/** Action constructor allowing only the given roles (post live verification). */\n\tfunction roleAction(...allowed: readonly Role[]) {\n\t\treturn zCustomAction(config.action, {\n\t\t\targs: {},\n\t\t\tinput: async (ctx) => {\n\t\t\t\tconst authenticated = await actionInput(ctx)\n\t\t\t\trequireRole(authenticated.ctx.actor.role, allowed)\n\t\t\t\treturn authenticated\n\t\t\t},\n\t\t})\n\t}\n\n\treturn {\n\t\tinclude,\n\t\tauthenticatedUser,\n\t\troleQuery,\n\t\troleMutation,\n\t\troleAction,\n\t\tauthQuery: zCustomQuery(config.query, { args: {}, input: queryInput }),\n\t\tauthMutation: zCustomMutation(config.mutation, {\n\t\t\targs: {},\n\t\t\tinput: mutationInput,\n\t\t}),\n\t\tauthAction: zCustomAction(config.action, {\n\t\t\targs: {},\n\t\t\tinput: actionInput,\n\t\t}),\n\t\tadminQuery: roleQuery(...config.adminRoles),\n\t\tadminMutation: roleMutation(...config.adminRoles),\n\t\tadminAction: roleAction(...config.adminRoles),\n\t\tsystemQuery: zCustomQuery(config.internalQuery, {\n\t\t\targs: {},\n\t\t\tinput: async (ctx) => ({ ctx: { ...ctx, include }, args: {} }),\n\t\t}),\n\t\tsystemMutation: zCustomMutation(config.internalMutation, {\n\t\t\targs: {},\n\t\t\tinput: async (ctx) => ({ ctx: { ...wrapDB(ctx), include }, args: {} }),\n\t\t}),\n\t\tsystemAction: zCustomAction(config.internalAction, {\n\t\t\targs: {},\n\t\t\tinput: async (ctx) => ({ ctx, args: {} }),\n\t\t}),\n\t}\n}\n\nconst organizationClaims = z.object({\n\torganization: z\n\t\t.object({\n\t\t\torganizationId: z.string().optional().catch(undefined),\n\t\t\trole: z.string().optional().catch(undefined),\n\t\t})\n\t\t.optional()\n\t\t.catch(undefined),\n\torg_id: z.string().optional().catch(undefined),\n\trole: z.string().optional().catch(undefined),\n})\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"auth.mjs","names":["defaultRoleMap","normalized","roleSlug","createInclude","errors","options","defaultErrors","maxRows","attach","execute","limit","data","selected","query","transform","paginate","opts","result","value","select","shouldMatch","indexName","indexRange","createAuthFunctions","config","triggers","wrapDB","ctx","include","authenticatedUser","identity","user","organizationId","organizationRole","resolved","claims","organizationClaims","claimedOrganizationId","role","base","securityConfig","securityRules","security","sets","createTenantRules","bundle","composeRules","secureReader","rules","wrapDatabaseReader","secureWriter","wrapDatabaseWriter","verifiedMembership","membership","requireRole","allowed","queryInput","mutationInput","actionInput","authenticated","verified","roleQuery","zCustomQuery","roleMutation","zCustomMutation","roleAction","zCustomAction","z"],"sources":["../src/auth.ts"],"sourcesContent":["import { z } from 'zod'\nimport { zCustomAction, zCustomMutation, zCustomQuery } from 'convex-helpers/server/zod4'\nimport type { CustomBuilder } from 'convex-helpers/server/zod4'\nimport type {\n\tActionBuilder,\n\tDocumentByInfo,\n\tPaginationOptions,\n\tPaginationResult,\n\tGenericActionCtx,\n\tGenericDataModel,\n\tGenericMutationCtx,\n\tGenericQueryCtx,\n\tGenericTableInfo,\n\tIndexNames,\n\tIndexRange,\n\tIndexRangeBuilder,\n\tMutationBuilder,\n\tNamedIndex,\n\tQuery,\n\tQueryBuilder,\n\tQueryInitializer,\n\tUserIdentity,\n} from 'convex/server'\nimport type { Triggers } from 'convex-helpers/server/triggers'\nimport type { TableNamesInDataModel } from 'convex/server'\nimport { defaultErrors, type ErrorFactory } from './errors'\nimport {\n\tcomposeRules,\n\tcreateTenantRules,\n\twrapDatabaseReader,\n\twrapDatabaseWriter,\n\ttype RLSConfig,\n\ttype Rules,\n} from './tenancy'\n\n/** The default vocabulary; every app can supply its own via the Role generic. */\nexport type DefaultRole = 'reader' | 'writer' | 'admin'\n\nexport type Actor<Role extends string> = Readonly<{\n\tuserId: string\n\torganizationId: string\n\trole: Role\n}>\n\nexport type AuthBundle<Role extends string> = Readonly<{\n\tidentity: UserIdentity\n\tuser: Readonly<{ id: string }>\n\torg: Readonly<{ organizationId: string; role: Role }>\n\trole: Role\n\tactor: Actor<Role>\n\t/** The resolved tenant — security.tenancy.resolve, or the organization id. */\n\ttenant: string\n}>\n\n/**\n * Row-level security configuration. Tenant isolation and role-level rules\n * compose (AND) onto the same wrapped database: queries get a wrapped\n * reader, mutations get triggers first, then a wrapped writer.\n */\nexport type SecurityConfig<DataModel extends GenericDataModel, Role extends string> = {\n\t/**\n\t * Tenant isolation. `tables` is THE registry: every listed table gets\n\t * read/insert/modify gated on row.tenant === ctx.tenant. Pair with\n\t * tenantTable (schema) and tenantOwnership (triggers) on the same list.\n\t */\n\ttenancy?: {\n\t\ttables: readonly TableNamesInDataModel<DataModel>[]\n\t\t/** Maps the auth bundle to the tenant; defaults to org.organizationId. */\n\t\tresolve?: (bundle: Omit<AuthBundle<Role>, 'tenant'>) => string\n\t}\n\t/**\n\t * Role-level (or any policy) rules derived from the authenticated bundle,\n\t * composed AND-wise with tenant isolation. E.g. gate `modify` on a table\n\t * to admin roles.\n\t */\n\trules?: (bundle: AuthBundle<Role>) => Rules<unknown, DataModel>\n\t/**\n\t * Policy for tables with no rule. Defaults to 'deny' when tenancy is\n\t * configured (unlisted tables are unreachable — fail closed), 'allow'\n\t * otherwise.\n\t */\n\tdefaultPolicy?: RLSConfig['defaultPolicy']\n}\n\ntype AnyAuthContext<DataModel extends GenericDataModel> =\n\t| GenericQueryCtx<DataModel>\n\t| GenericMutationCtx<DataModel>\n\t| GenericActionCtx<DataModel>\n\nexport type AuthFunctionsConfig<DataModel extends GenericDataModel, Role extends string> = {\n\t/** The consumer's generated function builders (from ./_generated/server). */\n\tquery: QueryBuilder<DataModel, 'public'>\n\tmutation: MutationBuilder<DataModel, 'public'>\n\taction: ActionBuilder<DataModel, 'public'>\n\tinternalQuery: QueryBuilder<DataModel, 'internal'>\n\tinternalMutation: MutationBuilder<DataModel, 'internal'>\n\tinternalAction: ActionBuilder<DataModel, 'internal'>\n\t/** Resolves the synchronized principal, e.g. (ctx) => authKit.getAuthUser(ctx). */\n\tgetAuthUser: (ctx: AnyAuthContext<DataModel>) => Promise<{ id: string } | null>\n\t/**\n\t * Maps an identity role slug onto the app's role vocabulary. Returning\n\t * null rejects the caller with FORBIDDEN — unknown roles never pass.\n\t */\n\tmapRole: (roleSlug?: string) => Role | null\n\t/** Roles allowed through the admin* constructors. */\n\tadminRoles: readonly NoInfer<Role>[]\n\t/**\n\t * Live membership check for actions (queries/mutations trust the JWT).\n\t * Authentication fails closed with FORBIDDEN when verification errors.\n\t * Omit to let actions trust the JWT like queries do.\n\t */\n\tverifyMembership?: (input: {\n\t\tuserId: string\n\t\torganizationId: string\n\t}) => Promise<{ organizationId: string; roleSlug: string } | null>\n\t/**\n\t * Resolves organization authority from the app's own data for identity\n\t * providers whose tokens carry no org claims. When configured, its result\n\t * overrides claim-based resolution; null or an error rejects with FORBIDDEN\n\t * (fail closed). In actions the ctx has no db — resolve via ctx.runQuery.\n\t */\n\tresolveOrganization?: (input: {\n\t\tctx: AnyAuthContext<DataModel>\n\t\tidentity: UserIdentity\n\t\tuser: { id: string }\n\t}) => Promise<{ organizationId: string; roleSlug: string } | null>\n\t/** Host error policy; defaults to throwing KitError. */\n\terrors?: ErrorFactory\n\t/**\n\t * Application trigger registry. When set, every authMutation,\n\t * roleMutation, and systemMutation write runs through triggers.wrapDB —\n\t * evaluations registered on tables fire structurally.\n\t */\n\ttriggers?: Triggers<DataModel>\n\t/** Lower-level alternative to `triggers`: a custom ctx wrapper. */\n\twrapDB?: (ctx: GenericMutationCtx<DataModel>) => GenericMutationCtx<DataModel>\n\t/** Upper bound for include() reads. */\n\tmaxIncludedQueryRows?: number\n\t/**\n\t * Row-level security: tenant isolation (from a table registry) and\n\t * role-level rules, applied structurally inside every auth*, role*, and\n\t * admin* constructor. system* constructors stay unwrapped (trusted).\n\t */\n\tsecurity?: SecurityConfig<DataModel, Role>\n}\n\n/** WorkOS-style default: `member` writes; reader/writer/admin pass through. */\nexport function defaultRoleMap(roleSlug?: string): DefaultRole | null {\n\tconst normalized = roleSlug?.trim().toLowerCase()\n\tif (normalized === 'member') return 'writer'\n\treturn normalized === 'reader' || normalized === 'writer' || normalized === 'admin'\n\t\t? normalized\n\t\t: null\n}\n\nexport type IncludedQuery<Table extends GenericTableInfo> = {\n\twhen<Value>(\n\t\tvalue: Value | null | undefined,\n\t\tselect: (query: QueryInitializer<Table>, value: Value) => Query<Table>,\n\t): IncludedQuery<Table>\n\tmatching<IndexName extends IndexNames<Table>>(\n\t\tindexName: IndexName,\n\t\tindexRange?: (\n\t\t\tquery: IndexRangeBuilder<DocumentByInfo<Table>, NamedIndex<Table, IndexName>>,\n\t\t) => IndexRange,\n\t\tshouldMatch?: boolean,\n\t): IncludedQuery<Table>\n\totherwise(select: (query: QueryInitializer<Table>) => Query<Table>): Query<Table>\n\tresolve(): Query<Table>\n\texecute(limit: number): Promise<DocumentByInfo<Table>[]>\n\texecute<Result>(\n\t\tlimit: number,\n\t\ttransform: (data: Awaited<ReturnType<Query<Table>['take']>>) => Result | Promise<Result>,\n\t): Promise<Result>\n\t/**\n\t * Cursor pagination over the selected indexed query. numItems is bounded\n\t * by the same maxRows policy as execute(). Under row-level security a\n\t * page may be shorter than numItems (rejected rows are filtered after\n\t * pagination); cursors remain correct. Pair with paginated(dto) from\n\t * cvx-kit/zod-table for the boundary schemas.\n\t */\n\tpaginate(opts: PaginationOptions): Promise<PaginationResult<DocumentByInfo<Table>>>\n\tpaginate<Item>(\n\t\topts: PaginationOptions,\n\t\ttransform: (page: DocumentByInfo<Table>[]) => Item[] | Promise<Item[]>,\n\t): Promise<PaginationResult<Item>>\n}\n\nexport type Include = <Table extends GenericTableInfo>(\n\tquery: QueryInitializer<Table>,\n) => IncludedQuery<Table>\n\n/**\n * Keep native contexts symbolic in published declarations. Inferred spreads\n * copy build-time Convex methods and override the consumer's native context.\n */\nexport type AuthFunctions<DataModel extends GenericDataModel, Role extends string = DefaultRole> = {\n\tinclude: Include\n\tauthenticatedUser: (ctx: AnyAuthContext<DataModel>) => Promise<AuthBundle<Role>>\n\tauthQuery: CustomBuilder<\n\t\t'query',\n\t\t{},\n\t\tGenericQueryCtx<DataModel> & AuthBundle<Role> & { include: Include },\n\t\t{},\n\t\tGenericQueryCtx<DataModel>,\n\t\t'public',\n\t\tobject\n\t>\n\tauthMutation: CustomBuilder<\n\t\t'mutation',\n\t\t{},\n\t\tGenericMutationCtx<DataModel> & AuthBundle<Role> & { include: Include },\n\t\t{},\n\t\tGenericMutationCtx<DataModel>,\n\t\t'public',\n\t\tobject\n\t>\n\tauthAction: CustomBuilder<\n\t\t'action',\n\t\t{},\n\t\tGenericActionCtx<DataModel> & AuthBundle<Role>,\n\t\t{},\n\t\tGenericActionCtx<DataModel>,\n\t\t'public',\n\t\tobject\n\t>\n\troleQuery: (...allowed: readonly Role[]) => AuthFunctions<DataModel, Role>['authQuery']\n\troleMutation: (...allowed: readonly Role[]) => AuthFunctions<DataModel, Role>['authMutation']\n\troleAction: (...allowed: readonly Role[]) => AuthFunctions<DataModel, Role>['authAction']\n\tadminQuery: AuthFunctions<DataModel, Role>['authQuery']\n\tadminMutation: AuthFunctions<DataModel, Role>['authMutation']\n\tadminAction: AuthFunctions<DataModel, Role>['authAction']\n\tsystemQuery: CustomBuilder<\n\t\t'query',\n\t\t{},\n\t\tGenericQueryCtx<DataModel> & { include: Include },\n\t\t{},\n\t\tGenericQueryCtx<DataModel>,\n\t\t'internal',\n\t\tobject\n\t>\n\tsystemMutation: CustomBuilder<\n\t\t'mutation',\n\t\t{},\n\t\tGenericMutationCtx<DataModel> & { include: Include },\n\t\t{},\n\t\tGenericMutationCtx<DataModel>,\n\t\t'internal',\n\t\tobject\n\t>\n\tsystemAction: CustomBuilder<\n\t\t'action',\n\t\t{},\n\t\tGenericActionCtx<DataModel>,\n\t\t{},\n\t\tGenericActionCtx<DataModel>,\n\t\t'internal',\n\t\tobject\n\t>\n}\n\n/** Builds an include() that selects the first matching indexed query and bounds the read. */\nexport function createInclude(options?: { errors?: ErrorFactory; maxRows?: number }): Include {\n\tconst errors = options?.errors ?? defaultErrors\n\tconst maxRows = options?.maxRows ?? 100\n\n\tfunction attach<Table extends GenericTableInfo>(\n\t\tquery: QueryInitializer<Table>,\n\t\tselected?: Query<Table>,\n\t): IncludedQuery<Table> {\n\t\tfunction execute(limit: number): Promise<DocumentByInfo<Table>[]>\n\t\tfunction execute<Result>(\n\t\t\tlimit: number,\n\t\t\ttransform: (data: DocumentByInfo<Table>[]) => Result | Promise<Result>,\n\t\t): Promise<Result>\n\t\tasync function execute<Result>(\n\t\t\tlimit: number,\n\t\t\ttransform?: (data: DocumentByInfo<Table>[]) => Result | Promise<Result>,\n\t\t) {\n\t\t\tif (!Number.isSafeInteger(limit) || limit < 1 || limit > maxRows) {\n\t\t\t\treturn errors.throw({\n\t\t\t\t\tcode: 'INVALID_REQUEST_BOUNDARY',\n\t\t\t\t\tmessage: `A bounded query limit must be from 1 to ${maxRows}`,\n\t\t\t\t})\n\t\t\t}\n\t\t\tconst data = await (selected ?? query.fullTableScan()).take(limit)\n\t\t\treturn transform ? transform(data) : data\n\t\t}\n\t\tfunction paginate(opts: PaginationOptions): Promise<PaginationResult<DocumentByInfo<Table>>>\n\t\tfunction paginate<Item>(\n\t\t\topts: PaginationOptions,\n\t\t\ttransform: (page: DocumentByInfo<Table>[]) => Item[] | Promise<Item[]>,\n\t\t): Promise<PaginationResult<Item>>\n\t\tasync function paginate<Item>(\n\t\t\topts: PaginationOptions,\n\t\t\ttransform?: (page: DocumentByInfo<Table>[]) => Item[] | Promise<Item[]>,\n\t\t) {\n\t\t\tif (!Number.isSafeInteger(opts.numItems) || opts.numItems < 1 || opts.numItems > maxRows) {\n\t\t\t\treturn errors.throw({\n\t\t\t\t\tcode: 'INVALID_REQUEST_BOUNDARY',\n\t\t\t\t\tmessage: `A page size must be from 1 to ${maxRows}`,\n\t\t\t\t})\n\t\t\t}\n\t\t\tconst result = await (selected ?? query.fullTableScan()).paginate(opts)\n\t\t\treturn transform ? { ...result, page: await transform(result.page) } : result\n\t\t}\n\t\treturn {\n\t\t\twhen: (value, select) =>\n\t\t\t\tselected || value === undefined || value === null\n\t\t\t\t\t? attach(query, selected)\n\t\t\t\t\t: attach(query, select(query, value)),\n\t\t\tmatching: (indexName, indexRange, shouldMatch = true) =>\n\t\t\t\tselected || !shouldMatch\n\t\t\t\t\t? attach(query, selected)\n\t\t\t\t\t: attach(query, query.withIndex(indexName, indexRange)),\n\t\t\totherwise: (select) => selected ?? select(query),\n\t\t\tresolve: () => selected ?? query.fullTableScan(),\n\t\t\texecute,\n\t\t\tpaginate,\n\t\t}\n\t}\n\n\treturn (query) => attach(query)\n}\n\n/**\n * Builds the auth-aware function constructors from the host's injected\n * policy: identity resolution, the app's own role vocabulary, live\n * membership verification for actions, trigger wrapping for mutations,\n * and errors. Role-based access is first-class — every constructor family\n * has a role-gated variant (roleQuery/roleMutation/roleAction), and the\n * admin* constructors are just that gate applied to config.adminRoles.\n */\nexport function createAuthFunctions<\n\tDataModel extends GenericDataModel,\n\tconst Role extends string = DefaultRole,\n>(config: AuthFunctionsConfig<DataModel, Role>): AuthFunctions<DataModel, Role> {\n\tconst errors = config.errors ?? defaultErrors\n\tconst triggers = config.triggers\n\tconst wrapDB = triggers\n\t\t? (ctx: GenericMutationCtx<DataModel>) => triggers.wrapDB(ctx)\n\t\t: (config.wrapDB ?? ((ctx) => ctx))\n\tconst include = createInclude({\n\t\terrors,\n\t\tmaxRows: config.maxIncludedQueryRows,\n\t})\n\n\tasync function authenticatedUser(ctx: AnyAuthContext<DataModel>): Promise<AuthBundle<Role>> {\n\t\tconst identity = await ctx.auth.getUserIdentity()\n\t\tconst user = identity ? await config.getAuthUser(ctx) : null\n\t\tif (!identity || !user) return errors.throw({ code: 'UNAUTHENTICATED' })\n\t\tlet organizationId: string\n\t\tlet organizationRole: string | undefined\n\t\tif (config.resolveOrganization) {\n\t\t\t// The hook is the organization authority — claims are skipped\n\t\t\t// entirely. Authentication fails closed when it errors or abstains.\n\t\t\tlet resolved: { organizationId: string; roleSlug: string } | null = null\n\t\t\ttry {\n\t\t\t\tresolved = await config.resolveOrganization({ ctx, identity, user })\n\t\t\t} catch {\n\t\t\t\t// Authentication fails closed when the hook cannot resolve.\n\t\t\t}\n\t\t\tif (!resolved) return errors.throw({ code: 'FORBIDDEN' })\n\t\t\torganizationId = resolved.organizationId\n\t\t\torganizationRole = resolved.roleSlug\n\t\t} else {\n\t\t\tconst claims = organizationClaims.parse(identity)\n\t\t\tconst claimedOrganizationId = claims.organization?.organizationId ?? claims.org_id\n\t\t\tif (!claimedOrganizationId) return errors.throw({ code: 'UNAUTHENTICATED' })\n\t\t\torganizationId = claimedOrganizationId\n\t\t\torganizationRole = claims.organization?.role ?? claims.role\n\t\t}\n\t\tconst role = config.mapRole(organizationRole)\n\t\tif (!role) return errors.throw({ code: 'FORBIDDEN' })\n\t\tconst base = {\n\t\t\tidentity,\n\t\t\tuser: Object.freeze({ id: user.id }),\n\t\t\torg: Object.freeze({ organizationId, role }),\n\t\t\trole,\n\t\t\tactor: Object.freeze({ userId: user.id, organizationId, role }),\n\t\t}\n\t\treturn Object.freeze({\n\t\t\t...base,\n\t\t\ttenant: config.security?.tenancy?.resolve?.(base) ?? organizationId,\n\t\t})\n\t}\n\n\tconst securityConfig: RLSConfig | undefined = config.security\n\t\t? {\n\t\t\t\tdefaultPolicy:\n\t\t\t\t\tconfig.security.defaultPolicy ?? (config.security.tenancy ? 'deny' : 'allow'),\n\t\t\t}\n\t\t: undefined\n\n\tfunction securityRules(bundle: AuthBundle<Role>): Rules<unknown, DataModel> | undefined {\n\t\tconst security = config.security\n\t\tif (!security) return undefined\n\t\tconst sets: Rules<unknown, DataModel>[] = []\n\t\tif (security.tenancy) {\n\t\t\tsets.push(createTenantRules<DataModel>(bundle.tenant, security.tenancy.tables))\n\t\t}\n\t\tif (security.rules) sets.push(security.rules(bundle))\n\t\treturn sets.length === 1 ? sets[0] : composeRules(...sets)\n\t}\n\n\tfunction secureReader(\n\t\tctx: GenericQueryCtx<DataModel>,\n\t\tbundle: AuthBundle<Role>,\n\t): GenericQueryCtx<DataModel> {\n\t\tconst rules = securityRules(bundle)\n\t\tif (!rules) return ctx\n\t\treturn {\n\t\t\t...ctx,\n\t\t\tdb: wrapDatabaseReader({}, ctx.db, rules, securityConfig),\n\t\t}\n\t}\n\n\tfunction secureWriter(\n\t\tctx: GenericMutationCtx<DataModel>,\n\t\tbundle: AuthBundle<Role>,\n\t): GenericMutationCtx<DataModel> {\n\t\tconst rules = securityRules(bundle)\n\t\tif (!rules) return ctx\n\t\t// Triggers wrap first (ctx already trigger-wrapped by the caller),\n\t\t// then row-level security wraps the triggered db — order matters.\n\t\treturn {\n\t\t\t...ctx,\n\t\t\tdb: wrapDatabaseWriter({}, ctx.db, rules, securityConfig),\n\t\t}\n\t}\n\n\tasync function verifiedMembership(userId: string, organizationId: string) {\n\t\tif (!config.verifyMembership) return null\n\t\ttry {\n\t\t\tconst membership = await config.verifyMembership({\n\t\t\t\tuserId,\n\t\t\t\torganizationId,\n\t\t\t})\n\t\t\tif (membership && membership.organizationId === organizationId) {\n\t\t\t\treturn membership\n\t\t\t}\n\t\t} catch {\n\t\t\t// Authentication fails closed when membership cannot be verified.\n\t\t}\n\t\treturn errors.throw({ code: 'FORBIDDEN' })\n\t}\n\n\tfunction requireRole(role: Role, allowed: readonly Role[]) {\n\t\tif (!allowed.includes(role)) return errors.throw({ code: 'FORBIDDEN' })\n\t}\n\n\tasync function queryInput(ctx: GenericQueryCtx<DataModel>) {\n\t\tconst bundle = await authenticatedUser(ctx)\n\t\treturn {\n\t\t\tctx: { ...secureReader(ctx, bundle), include, ...bundle },\n\t\t\targs: {},\n\t\t}\n\t}\n\n\tasync function mutationInput(ctx: GenericMutationCtx<DataModel>) {\n\t\tconst bundle = await authenticatedUser(ctx)\n\t\treturn {\n\t\t\tctx: { ...secureWriter(wrapDB(ctx), bundle), include, ...bundle },\n\t\t\targs: {},\n\t\t}\n\t}\n\n\tasync function actionInput(ctx: GenericActionCtx<DataModel>) {\n\t\tconst authenticated = await authenticatedUser(ctx)\n\t\tconst membership = await verifiedMembership(\n\t\t\tauthenticated.user.id,\n\t\t\tauthenticated.org.organizationId,\n\t\t)\n\t\tif (!membership) return { ctx: { ...ctx, ...authenticated }, args: {} }\n\t\tconst role = config.mapRole(membership.roleSlug)\n\t\tif (!role) return errors.throw({ code: 'FORBIDDEN' })\n\t\tconst verified = {\n\t\t\tidentity: authenticated.identity,\n\t\t\tuser: authenticated.user,\n\t\t\torg: Object.freeze({\n\t\t\t\torganizationId: membership.organizationId,\n\t\t\t\trole,\n\t\t\t}),\n\t\t\trole,\n\t\t\tactor: Object.freeze({\n\t\t\t\tuserId: authenticated.user.id,\n\t\t\t\torganizationId: membership.organizationId,\n\t\t\t\trole,\n\t\t\t}),\n\t\t}\n\t\treturn {\n\t\t\tctx: {\n\t\t\t\t...ctx,\n\t\t\t\t...verified,\n\t\t\t\t// Tenant re-derives from the live-verified organization.\n\t\t\t\ttenant: config.security?.tenancy?.resolve?.(verified) ?? membership.organizationId,\n\t\t\t},\n\t\t\targs: {},\n\t\t}\n\t}\n\n\t/** Query constructor allowing only the given roles. */\n\tfunction roleQuery(...allowed: readonly Role[]) {\n\t\treturn zCustomQuery(config.query, {\n\t\t\targs: {},\n\t\t\tinput: async (ctx) => {\n\t\t\t\tconst authenticated = await queryInput(ctx)\n\t\t\t\trequireRole(authenticated.ctx.actor.role, allowed)\n\t\t\t\treturn authenticated\n\t\t\t},\n\t\t})\n\t}\n\n\t/** Mutation constructor allowing only the given roles. */\n\tfunction roleMutation(...allowed: readonly Role[]) {\n\t\treturn zCustomMutation(config.mutation, {\n\t\t\targs: {},\n\t\t\tinput: async (ctx) => {\n\t\t\t\tconst authenticated = await mutationInput(ctx)\n\t\t\t\trequireRole(authenticated.ctx.actor.role, allowed)\n\t\t\t\treturn authenticated\n\t\t\t},\n\t\t})\n\t}\n\n\t/** Action constructor allowing only the given roles (post live verification). */\n\tfunction roleAction(...allowed: readonly Role[]) {\n\t\treturn zCustomAction(config.action, {\n\t\t\targs: {},\n\t\t\tinput: async (ctx) => {\n\t\t\t\tconst authenticated = await actionInput(ctx)\n\t\t\t\trequireRole(authenticated.ctx.actor.role, allowed)\n\t\t\t\treturn authenticated\n\t\t\t},\n\t\t})\n\t}\n\n\treturn {\n\t\tinclude,\n\t\tauthenticatedUser,\n\t\troleQuery,\n\t\troleMutation,\n\t\troleAction,\n\t\tauthQuery: zCustomQuery(config.query, { args: {}, input: queryInput }),\n\t\tauthMutation: zCustomMutation(config.mutation, {\n\t\t\targs: {},\n\t\t\tinput: mutationInput,\n\t\t}),\n\t\tauthAction: zCustomAction(config.action, {\n\t\t\targs: {},\n\t\t\tinput: actionInput,\n\t\t}),\n\t\tadminQuery: roleQuery(...config.adminRoles),\n\t\tadminMutation: roleMutation(...config.adminRoles),\n\t\tadminAction: roleAction(...config.adminRoles),\n\t\tsystemQuery: zCustomQuery(config.internalQuery, {\n\t\t\targs: {},\n\t\t\tinput: async (ctx) => ({ ctx: { ...ctx, include }, args: {} }),\n\t\t}),\n\t\tsystemMutation: zCustomMutation(config.internalMutation, {\n\t\t\targs: {},\n\t\t\tinput: async (ctx) => ({ ctx: { ...wrapDB(ctx), include }, args: {} }),\n\t\t}),\n\t\tsystemAction: zCustomAction(config.internalAction, {\n\t\t\targs: {},\n\t\t\tinput: async (ctx) => ({ ctx, args: {} }),\n\t\t}),\n\t}\n}\n\nconst organizationClaims = z.object({\n\torganization: z\n\t\t.object({\n\t\t\torganizationId: z.string().optional().catch(undefined),\n\t\t\trole: z.string().optional().catch(undefined),\n\t\t})\n\t\t.optional()\n\t\t.catch(undefined),\n\torg_id: z.string().optional().catch(undefined),\n\trole: z.string().optional().catch(undefined),\n})\n"],"mappings":"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"}
|
|
@@ -30,7 +30,7 @@ declare const fullApi: ApiFromModules<{
|
|
|
30
30
|
* const myFunctionReference = api.myModule.myFunction;
|
|
31
31
|
* ```
|
|
32
32
|
*/
|
|
33
|
-
declare const api: FilterApi<typeof fullApi, FunctionReference<any, "public">>;
|
|
33
|
+
export declare const api: FilterApi<typeof fullApi, FunctionReference<any, "public">>;
|
|
34
34
|
/**
|
|
35
35
|
* A utility for referencing Convex functions in your app's internal API.
|
|
36
36
|
*
|
|
@@ -39,11 +39,10 @@ declare const api: FilterApi<typeof fullApi, FunctionReference<any, "public">>;
|
|
|
39
39
|
* const myFunctionReference = internal.myModule.myFunction;
|
|
40
40
|
* ```
|
|
41
41
|
*/
|
|
42
|
-
declare const internal: FilterApi<typeof fullApi, FunctionReference<any, "internal">>;
|
|
43
|
-
declare const components: {
|
|
42
|
+
export declare const internal: FilterApi<typeof fullApi, FunctionReference<any, "internal">>;
|
|
43
|
+
export declare const components: {
|
|
44
44
|
workflow: import("@convex-dev/workflow/_generated/component.js").ComponentApi<"workflow">;
|
|
45
45
|
auditLog: import("convex-audit-log/_generated/component.js").ComponentApi<"auditLog">;
|
|
46
46
|
};
|
|
47
47
|
//#endregion
|
|
48
|
-
export { api, components, internal };
|
|
49
48
|
//# sourceMappingURL=api.d.mts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"api.mjs","names":[],"sources":["../../../../src/components/approvals/_generated/api.ts"],"sourcesContent":["/* eslint-disable */\n/**\n * Generated `api` utility.\n *\n * THIS CODE IS AUTOMATICALLY GENERATED.\n *\n * To regenerate, run `npx convex dev`.\n * @module\n */\n\nimport type * as audit from \"../audit.js\";\nimport type * as client from \"../client.js\";\nimport type * as constants from \"../constants.js\";\nimport type * as decisions from \"../decisions.js\";\nimport type * as functions from \"../functions.js\";\nimport type * as health from \"../health.js\";\nimport type * as requests from \"../requests.js\";\nimport type * as validators from \"../validators.js\";\nimport type * as workflow from \"../workflow.js\";\nimport type * as workflow_steps from \"../workflow_steps.js\";\n\nimport type {\n ApiFromModules,\n FilterApi,\n FunctionReference,\n} from \"convex/server\";\nimport { anyApi, componentsGeneric } from \"convex/server\";\n\nconst fullApi: ApiFromModules<{\n audit: typeof audit;\n client: typeof client;\n constants: typeof constants;\n decisions: typeof decisions;\n functions: typeof functions;\n health: typeof health;\n requests: typeof requests;\n validators: typeof validators;\n workflow: typeof workflow;\n workflow_steps: typeof workflow_steps;\n}> = anyApi as any;\n\n/**\n * A utility for referencing Convex functions in your app's public API.\n *\n * Usage:\n * ```js\n * const myFunctionReference = api.myModule.myFunction;\n * ```\n */\nexport const api: FilterApi<\n typeof fullApi,\n FunctionReference<any, \"public\">\n> = anyApi as any;\n\n/**\n * A utility for referencing Convex functions in your app's internal API.\n *\n * Usage:\n * ```js\n * const myFunctionReference = internal.myModule.myFunction;\n * ```\n */\nexport const internal: FilterApi<\n typeof fullApi,\n FunctionReference<any, \"internal\">\n> = anyApi as any;\n\nexport const components = componentsGeneric() as unknown as {\n workflow: import(\"@convex-dev/workflow/_generated/component.js\").ComponentApi<\"workflow\">;\n auditLog: import(\"convex-audit-log/_generated/component.js\").ComponentApi<\"auditLog\">;\n};\n"],"mappings":"8DAiDA,
|
|
1
|
+
{"version":3,"file":"api.mjs","names":["api","anyApi","internal","components","componentsGeneric"],"sources":["../../../../src/components/approvals/_generated/api.ts"],"sourcesContent":["/* eslint-disable */\n/**\n * Generated `api` utility.\n *\n * THIS CODE IS AUTOMATICALLY GENERATED.\n *\n * To regenerate, run `npx convex dev`.\n * @module\n */\n\nimport type * as audit from \"../audit.js\";\nimport type * as client from \"../client.js\";\nimport type * as constants from \"../constants.js\";\nimport type * as decisions from \"../decisions.js\";\nimport type * as functions from \"../functions.js\";\nimport type * as health from \"../health.js\";\nimport type * as requests from \"../requests.js\";\nimport type * as validators from \"../validators.js\";\nimport type * as workflow from \"../workflow.js\";\nimport type * as workflow_steps from \"../workflow_steps.js\";\n\nimport type {\n ApiFromModules,\n FilterApi,\n FunctionReference,\n} from \"convex/server\";\nimport { anyApi, componentsGeneric } from \"convex/server\";\n\nconst fullApi: ApiFromModules<{\n audit: typeof audit;\n client: typeof client;\n constants: typeof constants;\n decisions: typeof decisions;\n functions: typeof functions;\n health: typeof health;\n requests: typeof requests;\n validators: typeof validators;\n workflow: typeof workflow;\n workflow_steps: typeof workflow_steps;\n}> = anyApi as any;\n\n/**\n * A utility for referencing Convex functions in your app's public API.\n *\n * Usage:\n * ```js\n * const myFunctionReference = api.myModule.myFunction;\n * ```\n */\nexport const api: FilterApi<\n typeof fullApi,\n FunctionReference<any, \"public\">\n> = anyApi as any;\n\n/**\n * A utility for referencing Convex functions in your app's internal API.\n *\n * Usage:\n * ```js\n * const myFunctionReference = internal.myModule.myFunction;\n * ```\n */\nexport const internal: FilterApi<\n typeof fullApi,\n FunctionReference<any, \"internal\">\n> = anyApi as any;\n\nexport const components = componentsGeneric() as unknown as {\n workflow: import(\"@convex-dev/workflow/_generated/component.js\").ComponentApi<\"workflow\">;\n auditLog: import(\"convex-audit-log/_generated/component.js\").ComponentApi<\"auditLog\">;\n};\n"],"mappings":"8DAiDA,MAAaA,EAGTC,EAUSC,EAGTD,EAESE,EAAaC,EAAkB"}
|
|
@@ -11,7 +11,7 @@ import { FunctionReference } from "convex/server";
|
|
|
11
11
|
* }
|
|
12
12
|
* ```
|
|
13
13
|
*/
|
|
14
|
-
type ComponentApi<Name extends string | undefined = string | undefined> = {
|
|
14
|
+
export type ComponentApi<Name extends string | undefined = string | undefined> = {
|
|
15
15
|
audit: {
|
|
16
16
|
cleanup: FunctionReference<"mutation", "internal", {
|
|
17
17
|
batchSize: number;
|
|
@@ -300,5 +300,4 @@ type ComponentApi<Name extends string | undefined = string | undefined> = {
|
|
|
300
300
|
};
|
|
301
301
|
};
|
|
302
302
|
//#endregion
|
|
303
|
-
export { ComponentApi };
|
|
304
303
|
//# sourceMappingURL=component.d.mts.map
|
|
@@ -5,13 +5,13 @@ import { GenericId } from "convex/values";
|
|
|
5
5
|
/**
|
|
6
6
|
* The names of all of your Convex tables.
|
|
7
7
|
*/
|
|
8
|
-
type TableNames = TableNamesInDataModel<DataModel>;
|
|
8
|
+
export type TableNames = TableNamesInDataModel<DataModel>;
|
|
9
9
|
/**
|
|
10
10
|
* The type of a document stored in Convex.
|
|
11
11
|
*
|
|
12
12
|
* @typeParam TableName - A string literal type of the table name (like "users").
|
|
13
13
|
*/
|
|
14
|
-
type Doc<TableName extends TableNames> = DocumentByName<DataModel, TableName>;
|
|
14
|
+
export type Doc<TableName extends TableNames> = DocumentByName<DataModel, TableName>;
|
|
15
15
|
/**
|
|
16
16
|
* An identifier for a document in Convex.
|
|
17
17
|
*
|
|
@@ -25,7 +25,7 @@ type Doc<TableName extends TableNames> = DocumentByName<DataModel, TableName>;
|
|
|
25
25
|
*
|
|
26
26
|
* @typeParam TableName - A string literal type of the table name (like "users").
|
|
27
27
|
*/
|
|
28
|
-
type Id<TableName extends TableNames | SystemTableNames> = GenericId<TableName>;
|
|
28
|
+
export type Id<TableName extends TableNames | SystemTableNames> = GenericId<TableName>;
|
|
29
29
|
/**
|
|
30
30
|
* A type describing your Convex data model.
|
|
31
31
|
*
|
|
@@ -35,7 +35,6 @@ type Id<TableName extends TableNames | SystemTableNames> = GenericId<TableName>;
|
|
|
35
35
|
* This type is used to parameterize methods like `queryGeneric` and
|
|
36
36
|
* `mutationGeneric` to make them type-safe.
|
|
37
37
|
*/
|
|
38
|
-
type DataModel = DataModelFromSchemaDefinition<typeof _default>;
|
|
38
|
+
export type DataModel = DataModelFromSchemaDefinition<typeof _default>;
|
|
39
39
|
//#endregion
|
|
40
|
-
export { DataModel, Doc, Id, TableNames };
|
|
41
40
|
//# sourceMappingURL=dataModel.d.mts.map
|
|
@@ -9,7 +9,7 @@ import { ActionBuilder, GenericActionCtx, GenericDatabaseReader, GenericDatabase
|
|
|
9
9
|
* @param func - The query function. It receives a {@link QueryCtx} as its first argument.
|
|
10
10
|
* @returns The wrapped query. Include this as an `export` to name it and make it accessible.
|
|
11
11
|
*/
|
|
12
|
-
declare const query: QueryBuilder<DataModel, "public">;
|
|
12
|
+
export declare const query: QueryBuilder<DataModel, "public">;
|
|
13
13
|
/**
|
|
14
14
|
* Define a query that is only accessible from other Convex functions (but not from the client).
|
|
15
15
|
*
|
|
@@ -18,7 +18,7 @@ declare const query: QueryBuilder<DataModel, "public">;
|
|
|
18
18
|
* @param func - The query function. It receives a {@link QueryCtx} as its first argument.
|
|
19
19
|
* @returns The wrapped query. Include this as an `export` to name it and make it accessible.
|
|
20
20
|
*/
|
|
21
|
-
declare const internalQuery: QueryBuilder<DataModel, "internal">;
|
|
21
|
+
export declare const internalQuery: QueryBuilder<DataModel, "internal">;
|
|
22
22
|
/**
|
|
23
23
|
* Define a mutation in this Convex app's public API.
|
|
24
24
|
*
|
|
@@ -27,7 +27,7 @@ declare const internalQuery: QueryBuilder<DataModel, "internal">;
|
|
|
27
27
|
* @param func - The mutation function. It receives a {@link MutationCtx} as its first argument.
|
|
28
28
|
* @returns The wrapped mutation. Include this as an `export` to name it and make it accessible.
|
|
29
29
|
*/
|
|
30
|
-
declare const mutation: MutationBuilder<DataModel, "public">;
|
|
30
|
+
export declare const mutation: MutationBuilder<DataModel, "public">;
|
|
31
31
|
/**
|
|
32
32
|
* Define a mutation that is only accessible from other Convex functions (but not from the client).
|
|
33
33
|
*
|
|
@@ -36,7 +36,7 @@ declare const mutation: MutationBuilder<DataModel, "public">;
|
|
|
36
36
|
* @param func - The mutation function. It receives a {@link MutationCtx} as its first argument.
|
|
37
37
|
* @returns The wrapped mutation. Include this as an `export` to name it and make it accessible.
|
|
38
38
|
*/
|
|
39
|
-
declare const internalMutation: MutationBuilder<DataModel, "internal">;
|
|
39
|
+
export declare const internalMutation: MutationBuilder<DataModel, "internal">;
|
|
40
40
|
/**
|
|
41
41
|
* Define an action in this Convex app's public API.
|
|
42
42
|
*
|
|
@@ -48,14 +48,14 @@ declare const internalMutation: MutationBuilder<DataModel, "internal">;
|
|
|
48
48
|
* @param func - The action. It receives an {@link ActionCtx} as its first argument.
|
|
49
49
|
* @returns The wrapped action. Include this as an `export` to name it and make it accessible.
|
|
50
50
|
*/
|
|
51
|
-
declare const action: ActionBuilder<DataModel, "public">;
|
|
51
|
+
export declare const action: ActionBuilder<DataModel, "public">;
|
|
52
52
|
/**
|
|
53
53
|
* Define an action that is only accessible from other Convex functions (but not from the client).
|
|
54
54
|
*
|
|
55
55
|
* @param func - The function. It receives an {@link ActionCtx} as its first argument.
|
|
56
56
|
* @returns The wrapped function. Include this as an `export` to name it and make it accessible.
|
|
57
57
|
*/
|
|
58
|
-
declare const internalAction: ActionBuilder<DataModel, "internal">;
|
|
58
|
+
export declare const internalAction: ActionBuilder<DataModel, "internal">;
|
|
59
59
|
/**
|
|
60
60
|
* Define an HTTP action.
|
|
61
61
|
*
|
|
@@ -67,7 +67,7 @@ declare const internalAction: ActionBuilder<DataModel, "internal">;
|
|
|
67
67
|
* and a Fetch API `Request` object as its second.
|
|
68
68
|
* @returns The wrapped function. Import this function from `convex/http.js` and route it to hook it up.
|
|
69
69
|
*/
|
|
70
|
-
declare const httpAction: HttpActionBuilder;
|
|
70
|
+
export declare const httpAction: HttpActionBuilder;
|
|
71
71
|
/**
|
|
72
72
|
* A set of services for use within Convex query functions.
|
|
73
73
|
*
|
|
@@ -76,7 +76,7 @@ declare const httpAction: HttpActionBuilder;
|
|
|
76
76
|
*
|
|
77
77
|
* If you're using code generation, use the `QueryCtx` type in `convex/_generated/server.d.ts` instead.
|
|
78
78
|
*/
|
|
79
|
-
type QueryCtx = GenericQueryCtx<DataModel>;
|
|
79
|
+
export type QueryCtx = GenericQueryCtx<DataModel>;
|
|
80
80
|
/**
|
|
81
81
|
* A set of services for use within Convex mutation functions.
|
|
82
82
|
*
|
|
@@ -85,14 +85,14 @@ type QueryCtx = GenericQueryCtx<DataModel>;
|
|
|
85
85
|
*
|
|
86
86
|
* If you're using code generation, use the `MutationCtx` type in `convex/_generated/server.d.ts` instead.
|
|
87
87
|
*/
|
|
88
|
-
type MutationCtx = GenericMutationCtx<DataModel>;
|
|
88
|
+
export type MutationCtx = GenericMutationCtx<DataModel>;
|
|
89
89
|
/**
|
|
90
90
|
* A set of services for use within Convex action functions.
|
|
91
91
|
*
|
|
92
92
|
* The action context is passed as the first argument to any Convex action
|
|
93
93
|
* function run on the server.
|
|
94
94
|
*/
|
|
95
|
-
type ActionCtx = GenericActionCtx<DataModel>;
|
|
95
|
+
export type ActionCtx = GenericActionCtx<DataModel>;
|
|
96
96
|
/**
|
|
97
97
|
* An interface to read from the database within Convex query functions.
|
|
98
98
|
*
|
|
@@ -100,7 +100,7 @@ type ActionCtx = GenericActionCtx<DataModel>;
|
|
|
100
100
|
* document by its {@link Id}, or {@link DatabaseReader.query}, which starts
|
|
101
101
|
* building a query.
|
|
102
102
|
*/
|
|
103
|
-
type DatabaseReader = GenericDatabaseReader<DataModel>;
|
|
103
|
+
export type DatabaseReader = GenericDatabaseReader<DataModel>;
|
|
104
104
|
/**
|
|
105
105
|
* An interface to read from and write to the database within Convex mutation
|
|
106
106
|
* functions.
|
|
@@ -110,7 +110,6 @@ type DatabaseReader = GenericDatabaseReader<DataModel>;
|
|
|
110
110
|
* your data in an inconsistent state. See [the Convex Guide](https://docs.convex.dev/understanding/convex-fundamentals/functions#atomicity-and-optimistic-concurrency-control)
|
|
111
111
|
* for the guarantees Convex provides your functions.
|
|
112
112
|
*/
|
|
113
|
-
type DatabaseWriter = GenericDatabaseWriter<DataModel>;
|
|
113
|
+
export type DatabaseWriter = GenericDatabaseWriter<DataModel>;
|
|
114
114
|
//#endregion
|
|
115
|
-
export { ActionCtx, DatabaseReader, DatabaseWriter, MutationCtx, QueryCtx, action, httpAction, internalAction, internalMutation, internalQuery, mutation, query };
|
|
116
115
|
//# sourceMappingURL=server.d.mts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"server.mjs","names":[],"sources":["../../../../src/components/approvals/_generated/server.ts"],"sourcesContent":["/* eslint-disable */\n/**\n * Generated utilities for implementing server-side Convex query and mutation functions.\n *\n * THIS CODE IS AUTOMATICALLY GENERATED.\n *\n * To regenerate, run `npx convex dev`.\n * @module\n */\n\nimport type {\n ActionBuilder,\n HttpActionBuilder,\n MutationBuilder,\n QueryBuilder,\n GenericActionCtx,\n GenericMutationCtx,\n GenericQueryCtx,\n GenericDatabaseReader,\n GenericDatabaseWriter,\n} from \"convex/server\";\nimport {\n actionGeneric,\n httpActionGeneric,\n queryGeneric,\n mutationGeneric,\n internalActionGeneric,\n internalMutationGeneric,\n internalQueryGeneric,\n} from \"convex/server\";\nimport type { DataModel } from \"./dataModel.js\";\n\n/**\n * Define a query in this Convex app's public API.\n *\n * This function will be allowed to read your Convex database and will be accessible from the client.\n *\n * @param func - The query function. It receives a {@link QueryCtx} as its first argument.\n * @returns The wrapped query. Include this as an `export` to name it and make it accessible.\n */\nexport const query: QueryBuilder<DataModel, \"public\"> = queryGeneric;\n\n/**\n * Define a query that is only accessible from other Convex functions (but not from the client).\n *\n * This function will be allowed to read from your Convex database. It will not be accessible from the client.\n *\n * @param func - The query function. It receives a {@link QueryCtx} as its first argument.\n * @returns The wrapped query. Include this as an `export` to name it and make it accessible.\n */\nexport const internalQuery: QueryBuilder<DataModel, \"internal\"> =\n internalQueryGeneric;\n\n/**\n * Define a mutation in this Convex app's public API.\n *\n * This function will be allowed to modify your Convex database and will be accessible from the client.\n *\n * @param func - The mutation function. It receives a {@link MutationCtx} as its first argument.\n * @returns The wrapped mutation. Include this as an `export` to name it and make it accessible.\n */\nexport const mutation: MutationBuilder<DataModel, \"public\"> = mutationGeneric;\n\n/**\n * Define a mutation that is only accessible from other Convex functions (but not from the client).\n *\n * This function will be allowed to modify your Convex database. It will not be accessible from the client.\n *\n * @param func - The mutation function. It receives a {@link MutationCtx} as its first argument.\n * @returns The wrapped mutation. Include this as an `export` to name it and make it accessible.\n */\nexport const internalMutation: MutationBuilder<DataModel, \"internal\"> =\n internalMutationGeneric;\n\n/**\n * Define an action in this Convex app's public API.\n *\n * An action is a function which can execute any JavaScript code, including non-deterministic\n * code and code with side-effects, like calling third-party services.\n * They can be run in Convex's JavaScript environment or in Node.js using the \"use node\" directive.\n * They can interact with the database indirectly by calling queries and mutations using the {@link ActionCtx}.\n *\n * @param func - The action. It receives an {@link ActionCtx} as its first argument.\n * @returns The wrapped action. Include this as an `export` to name it and make it accessible.\n */\nexport const action: ActionBuilder<DataModel, \"public\"> = actionGeneric;\n\n/**\n * Define an action that is only accessible from other Convex functions (but not from the client).\n *\n * @param func - The function. It receives an {@link ActionCtx} as its first argument.\n * @returns The wrapped function. Include this as an `export` to name it and make it accessible.\n */\nexport const internalAction: ActionBuilder<DataModel, \"internal\"> =\n internalActionGeneric;\n\n/**\n * Define an HTTP action.\n *\n * The wrapped function will be used to respond to HTTP requests received\n * by a Convex deployment if the requests matches the path and method where\n * this action is routed. Be sure to route your httpAction in `convex/http.js`.\n *\n * @param func - The function. It receives an {@link ActionCtx} as its first argument\n * and a Fetch API `Request` object as its second.\n * @returns The wrapped function. Import this function from `convex/http.js` and route it to hook it up.\n */\nexport const httpAction: HttpActionBuilder = httpActionGeneric;\n\n/**\n * A set of services for use within Convex query functions.\n *\n * The query context is passed as the first argument to any Convex query\n * function run on the server.\n *\n * If you're using code generation, use the `QueryCtx` type in `convex/_generated/server.d.ts` instead.\n */\nexport type QueryCtx = GenericQueryCtx<DataModel>;\n\n/**\n * A set of services for use within Convex mutation functions.\n *\n * The mutation context is passed as the first argument to any Convex mutation\n * function run on the server.\n *\n * If you're using code generation, use the `MutationCtx` type in `convex/_generated/server.d.ts` instead.\n */\nexport type MutationCtx = GenericMutationCtx<DataModel>;\n\n/**\n * A set of services for use within Convex action functions.\n *\n * The action context is passed as the first argument to any Convex action\n * function run on the server.\n */\nexport type ActionCtx = GenericActionCtx<DataModel>;\n\n/**\n * An interface to read from the database within Convex query functions.\n *\n * The two entry points are {@link DatabaseReader.get}, which fetches a single\n * document by its {@link Id}, or {@link DatabaseReader.query}, which starts\n * building a query.\n */\nexport type DatabaseReader = GenericDatabaseReader<DataModel>;\n\n/**\n * An interface to read from and write to the database within Convex mutation\n * functions.\n *\n * Convex guarantees that all writes within a single mutation are\n * executed atomically, so you never have to worry about partial writes leaving\n * your data in an inconsistent state. See [the Convex Guide](https://docs.convex.dev/understanding/convex-fundamentals/functions#atomicity-and-optimistic-concurrency-control)\n * for the guarantees Convex provides your functions.\n */\nexport type DatabaseWriter = GenericDatabaseWriter<DataModel>;\n"],"mappings":"8LAwCA,
|
|
1
|
+
{"version":3,"file":"server.mjs","names":["query","queryGeneric","internalQuery","internalQueryGeneric","mutation","mutationGeneric","internalMutation","internalMutationGeneric","action","actionGeneric","internalAction","internalActionGeneric","httpAction","httpActionGeneric"],"sources":["../../../../src/components/approvals/_generated/server.ts"],"sourcesContent":["/* eslint-disable */\n/**\n * Generated utilities for implementing server-side Convex query and mutation functions.\n *\n * THIS CODE IS AUTOMATICALLY GENERATED.\n *\n * To regenerate, run `npx convex dev`.\n * @module\n */\n\nimport type {\n ActionBuilder,\n HttpActionBuilder,\n MutationBuilder,\n QueryBuilder,\n GenericActionCtx,\n GenericMutationCtx,\n GenericQueryCtx,\n GenericDatabaseReader,\n GenericDatabaseWriter,\n} from \"convex/server\";\nimport {\n actionGeneric,\n httpActionGeneric,\n queryGeneric,\n mutationGeneric,\n internalActionGeneric,\n internalMutationGeneric,\n internalQueryGeneric,\n} from \"convex/server\";\nimport type { DataModel } from \"./dataModel.js\";\n\n/**\n * Define a query in this Convex app's public API.\n *\n * This function will be allowed to read your Convex database and will be accessible from the client.\n *\n * @param func - The query function. It receives a {@link QueryCtx} as its first argument.\n * @returns The wrapped query. Include this as an `export` to name it and make it accessible.\n */\nexport const query: QueryBuilder<DataModel, \"public\"> = queryGeneric;\n\n/**\n * Define a query that is only accessible from other Convex functions (but not from the client).\n *\n * This function will be allowed to read from your Convex database. It will not be accessible from the client.\n *\n * @param func - The query function. It receives a {@link QueryCtx} as its first argument.\n * @returns The wrapped query. Include this as an `export` to name it and make it accessible.\n */\nexport const internalQuery: QueryBuilder<DataModel, \"internal\"> =\n internalQueryGeneric;\n\n/**\n * Define a mutation in this Convex app's public API.\n *\n * This function will be allowed to modify your Convex database and will be accessible from the client.\n *\n * @param func - The mutation function. It receives a {@link MutationCtx} as its first argument.\n * @returns The wrapped mutation. Include this as an `export` to name it and make it accessible.\n */\nexport const mutation: MutationBuilder<DataModel, \"public\"> = mutationGeneric;\n\n/**\n * Define a mutation that is only accessible from other Convex functions (but not from the client).\n *\n * This function will be allowed to modify your Convex database. It will not be accessible from the client.\n *\n * @param func - The mutation function. It receives a {@link MutationCtx} as its first argument.\n * @returns The wrapped mutation. Include this as an `export` to name it and make it accessible.\n */\nexport const internalMutation: MutationBuilder<DataModel, \"internal\"> =\n internalMutationGeneric;\n\n/**\n * Define an action in this Convex app's public API.\n *\n * An action is a function which can execute any JavaScript code, including non-deterministic\n * code and code with side-effects, like calling third-party services.\n * They can be run in Convex's JavaScript environment or in Node.js using the \"use node\" directive.\n * They can interact with the database indirectly by calling queries and mutations using the {@link ActionCtx}.\n *\n * @param func - The action. It receives an {@link ActionCtx} as its first argument.\n * @returns The wrapped action. Include this as an `export` to name it and make it accessible.\n */\nexport const action: ActionBuilder<DataModel, \"public\"> = actionGeneric;\n\n/**\n * Define an action that is only accessible from other Convex functions (but not from the client).\n *\n * @param func - The function. It receives an {@link ActionCtx} as its first argument.\n * @returns The wrapped function. Include this as an `export` to name it and make it accessible.\n */\nexport const internalAction: ActionBuilder<DataModel, \"internal\"> =\n internalActionGeneric;\n\n/**\n * Define an HTTP action.\n *\n * The wrapped function will be used to respond to HTTP requests received\n * by a Convex deployment if the requests matches the path and method where\n * this action is routed. Be sure to route your httpAction in `convex/http.js`.\n *\n * @param func - The function. It receives an {@link ActionCtx} as its first argument\n * and a Fetch API `Request` object as its second.\n * @returns The wrapped function. Import this function from `convex/http.js` and route it to hook it up.\n */\nexport const httpAction: HttpActionBuilder = httpActionGeneric;\n\n/**\n * A set of services for use within Convex query functions.\n *\n * The query context is passed as the first argument to any Convex query\n * function run on the server.\n *\n * If you're using code generation, use the `QueryCtx` type in `convex/_generated/server.d.ts` instead.\n */\nexport type QueryCtx = GenericQueryCtx<DataModel>;\n\n/**\n * A set of services for use within Convex mutation functions.\n *\n * The mutation context is passed as the first argument to any Convex mutation\n * function run on the server.\n *\n * If you're using code generation, use the `MutationCtx` type in `convex/_generated/server.d.ts` instead.\n */\nexport type MutationCtx = GenericMutationCtx<DataModel>;\n\n/**\n * A set of services for use within Convex action functions.\n *\n * The action context is passed as the first argument to any Convex action\n * function run on the server.\n */\nexport type ActionCtx = GenericActionCtx<DataModel>;\n\n/**\n * An interface to read from the database within Convex query functions.\n *\n * The two entry points are {@link DatabaseReader.get}, which fetches a single\n * document by its {@link Id}, or {@link DatabaseReader.query}, which starts\n * building a query.\n */\nexport type DatabaseReader = GenericDatabaseReader<DataModel>;\n\n/**\n * An interface to read from and write to the database within Convex mutation\n * functions.\n *\n * Convex guarantees that all writes within a single mutation are\n * executed atomically, so you never have to worry about partial writes leaving\n * your data in an inconsistent state. See [the Convex Guide](https://docs.convex.dev/understanding/convex-fundamentals/functions#atomicity-and-optimistic-concurrency-control)\n * for the guarantees Convex provides your functions.\n */\nexport type DatabaseWriter = GenericDatabaseWriter<DataModel>;\n"],"mappings":"8LAwCA,MAAaA,EAA2CC,EAU3CC,EACXC,EAUWC,EAAiDC,EAUjDC,EACXC,EAaWC,EAA6CC,EAQ7CC,EACXC,EAaWC,EAAgCC"}
|
|
@@ -3,7 +3,7 @@ import { AuditEventInput, AuditLog } from "convex-audit-log";
|
|
|
3
3
|
declare namespace audit_d_exports {
|
|
4
4
|
export { ApprovalAuditProjection, ApprovalAuditTransition, approvalAudit, approvalAuditEvent, cleanup, history, logApprovalTransition };
|
|
5
5
|
}
|
|
6
|
-
type ApprovalAuditTransition = Readonly<{
|
|
6
|
+
export type ApprovalAuditTransition = Readonly<{
|
|
7
7
|
action: string;
|
|
8
8
|
actorRef?: string;
|
|
9
9
|
runId: string;
|
|
@@ -12,14 +12,14 @@ type ApprovalAuditTransition = Readonly<{
|
|
|
12
12
|
transition: string;
|
|
13
13
|
severity?: AuditEventInput['severity'];
|
|
14
14
|
}>;
|
|
15
|
-
type ApprovalAuditProjection = Readonly<{
|
|
15
|
+
export type ApprovalAuditProjection = Readonly<{
|
|
16
16
|
action: string;
|
|
17
17
|
actorRef?: string;
|
|
18
18
|
correlationKey: string;
|
|
19
19
|
transition: string;
|
|
20
20
|
}>;
|
|
21
|
-
declare const approvalAudit: AuditLog;
|
|
22
|
-
declare const history: import("convex/server").RegisteredQuery<"public", {
|
|
21
|
+
export declare const approvalAudit: AuditLog;
|
|
22
|
+
export declare const history: import("convex/server").RegisteredQuery<"public", {
|
|
23
23
|
limit?: number | undefined;
|
|
24
24
|
resourceRef: string;
|
|
25
25
|
resourceType: string;
|
|
@@ -29,12 +29,12 @@ declare const history: import("convex/server").RegisteredQuery<"public", {
|
|
|
29
29
|
correlationKey: string;
|
|
30
30
|
transition: string;
|
|
31
31
|
}>[]>>;
|
|
32
|
-
declare const cleanup: import("convex/server").RegisteredMutation<"public", {
|
|
32
|
+
export declare const cleanup: import("convex/server").RegisteredMutation<"public", {
|
|
33
33
|
batchSize: number;
|
|
34
34
|
olderThanDays: number;
|
|
35
35
|
}, Promise<number>>;
|
|
36
|
-
declare function approvalAuditEvent(input: ApprovalAuditTransition): AuditEventInput;
|
|
37
|
-
declare function logApprovalTransition(ctx: MutationCtx, input: ApprovalAuditTransition): Promise<void>;
|
|
36
|
+
export declare function approvalAuditEvent(input: ApprovalAuditTransition): AuditEventInput;
|
|
37
|
+
export declare function logApprovalTransition(ctx: MutationCtx, input: ApprovalAuditTransition): Promise<void>;
|
|
38
38
|
//#endregion
|
|
39
|
-
export {
|
|
39
|
+
export { audit_d_exports };
|
|
40
40
|
//# sourceMappingURL=audit.d.mts.map
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import{components as e}from"./_generated/api.mjs";import{mutation as t,query as n}from"./_generated/server.mjs";import{APPROVAL_AUDIT_RETENTION_CATEGORY as r,MAX_APPROVAL_AUDIT_RETENTION_DAYS as i}from"./constants.mjs";import{z as a}from"zod";import{v as o}from"convex/values";import{AuditLog as s}from"convex-audit-log";const c=new s(e.auditLog,{samplingEnabled:!1}),l=n({args:{resourceType:o.string(),resourceRef:o.string(),limit:o.optional(o.number())},returns:o.array(o.object({action:o.string(),actorRef:o.optional(o.string()),correlationKey:o.string(),transition:o.string()})),handler:async(e,t)=>{let n=Math.max(1,Math.min(Math.trunc(t.limit??100),100)),r=await c.queryByResource(e,{resourceType:t.resourceType,resourceId:t.resourceRef,limit:n}),i
|
|
1
|
+
import{components as e}from"./_generated/api.mjs";import{mutation as t,query as n}from"./_generated/server.mjs";import{APPROVAL_AUDIT_RETENTION_CATEGORY as r,MAX_APPROVAL_AUDIT_RETENTION_DAYS as i}from"./constants.mjs";import{z as a}from"zod";import{v as o}from"convex/values";import{AuditLog as s}from"convex-audit-log";const c=new s(e.auditLog,{samplingEnabled:!1}),l=n({args:{resourceType:o.string(),resourceRef:o.string(),limit:o.optional(o.number())},returns:o.array(o.object({action:o.string(),actorRef:o.optional(o.string()),correlationKey:o.string(),transition:o.string()})),handler:async(e,t)=>{let n=Math.max(1,Math.min(Math.trunc(t.limit??100),100)),r=await c.queryByResource(e,{resourceType:t.resourceType,resourceId:t.resourceRef,limit:n}),i=/* @__PURE__ */ new Map;for(let e of r){let t=h(e);t&&i.set(t.correlationKey,t)}return[...i.values()]}}),u=t({args:{olderThanDays:o.number(),batchSize:o.number()},returns:o.number(),handler:(e,t)=>{let n=p(t.olderThanDays,1,i,`olderThanDays`),a=p(t.batchSize,1,100,`batchSize`);return c.cleanup(e,{olderThanDays:n,batchSize:a,retentionCategory:r})}});function d(e){return{action:e.action,actorId:e.actorRef,resourceType:e.resourceType,resourceId:e.resourceRef,severity:e.severity??`info`,tags:[`approvals`],retentionCategory:r,metadata:{correlationKey:`${e.runId}:${e.transition}`,runId:e.runId,transition:e.transition}}}async function f(e,t){await c.log(e,d(t))}function p(e,t,n,r){if(!Number.isInteger(e)||e<t||e>n)throw Error(`${r} must be an integer between ${t} and ${n}`);return e}const m=a.object({action:a.string(),actorId:a.string().optional().catch(void 0),metadata:a.object({correlationKey:a.string(),transition:a.string()})});function h(e){let t=m.safeParse(e);if(!t.success)return null;let{action:n,actorId:r,metadata:i}=t.data;return{action:n,actorRef:r,...i}}export{c as approvalAudit,d as approvalAuditEvent,u as cleanup,l as history,f as logApprovalTransition};
|
|
2
2
|
//# sourceMappingURL=audit.mjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"audit.mjs","names":[],"sources":["../../../src/components/approvals/audit.ts"],"sourcesContent":["import { z } from 'zod'\nimport { AuditLog, type AuditEventInput } from 'convex-audit-log'\nimport { v } from 'convex/values'\n\nimport { components } from './_generated/api'\nimport { mutation, query, type MutationCtx } from './_generated/server'\nimport {\n\tAPPROVAL_AUDIT_RETENTION_CATEGORY,\n\tMAX_APPROVAL_AUDIT_CLEANUP_BATCH_SIZE,\n\tMAX_APPROVAL_AUDIT_RETENTION_DAYS,\n\tMIN_APPROVAL_AUDIT_RETENTION_DAYS,\n} from './constants'\n\nexport type ApprovalAuditTransition = Readonly<{\n\taction: string\n\tactorRef?: string\n\trunId: string\n\tresourceType: string\n\tresourceRef: string\n\ttransition: string\n\tseverity?: AuditEventInput['severity']\n}>\n\nexport type ApprovalAuditProjection = Readonly<{\n\taction: string\n\tactorRef?: string\n\tcorrelationKey: string\n\ttransition: string\n}>\n\nexport const approvalAudit = new AuditLog(components.auditLog, {\n\tsamplingEnabled: false,\n})\n\nexport const history = query({\n\targs: {\n\t\tresourceType: v.string(),\n\t\tresourceRef: v.string(),\n\t\tlimit: v.optional(v.number()),\n\t},\n\treturns: v.array(\n\t\tv.object({\n\t\t\taction: v.string(),\n\t\t\tactorRef: v.optional(v.string()),\n\t\t\tcorrelationKey: v.string(),\n\t\t\ttransition: v.string(),\n\t\t}),\n\t),\n\thandler: async (ctx, input) => {\n\t\tconst limit = Math.max(1, Math.min(Math.trunc(input.limit ?? 100), 100))\n\t\tconst events = await approvalAudit.queryByResource(ctx, {\n\t\t\tresourceType: input.resourceType,\n\t\t\tresourceId: input.resourceRef,\n\t\t\tlimit,\n\t\t})\n\t\tconst unique = new Map<string, ApprovalAuditProjection>()\n\t\tfor (const event of events) {\n\t\t\tconst projection = auditProjection(event)\n\t\t\tif (projection) unique.set(projection.correlationKey, projection)\n\t\t}\n\t\treturn [...unique.values()]\n\t},\n})\n\nexport const cleanup = mutation({\n\targs: {\n\t\tolderThanDays: v.number(),\n\t\tbatchSize: v.number(),\n\t},\n\treturns: v.number(),\n\thandler: (ctx, input) => {\n\t\tconst olderThanDays = boundedInteger(\n\t\t\tinput.olderThanDays,\n\t\t\tMIN_APPROVAL_AUDIT_RETENTION_DAYS,\n\t\t\tMAX_APPROVAL_AUDIT_RETENTION_DAYS,\n\t\t\t'olderThanDays',\n\t\t)\n\t\tconst batchSize = boundedInteger(\n\t\t\tinput.batchSize,\n\t\t\t1,\n\t\t\tMAX_APPROVAL_AUDIT_CLEANUP_BATCH_SIZE,\n\t\t\t'batchSize',\n\t\t)\n\t\treturn approvalAudit.cleanup(ctx, {\n\t\t\tolderThanDays,\n\t\t\tbatchSize,\n\t\t\tretentionCategory: APPROVAL_AUDIT_RETENTION_CATEGORY,\n\t\t})\n\t},\n})\n\nexport function approvalAuditEvent(input: ApprovalAuditTransition): AuditEventInput {\n\treturn {\n\t\taction: input.action,\n\t\tactorId: input.actorRef,\n\t\tresourceType: input.resourceType,\n\t\tresourceId: input.resourceRef,\n\t\tseverity: input.severity ?? 'info',\n\t\ttags: ['approvals'],\n\t\tretentionCategory: APPROVAL_AUDIT_RETENTION_CATEGORY,\n\t\tmetadata: {\n\t\t\tcorrelationKey: `${input.runId}:${input.transition}`,\n\t\t\trunId: input.runId,\n\t\t\ttransition: input.transition,\n\t\t},\n\t}\n}\n\nexport async function logApprovalTransition(\n\tctx: MutationCtx,\n\tinput: ApprovalAuditTransition,\n): Promise<void> {\n\tawait approvalAudit.log(ctx, approvalAuditEvent(input))\n}\n\nfunction boundedInteger(value: number, minimum: number, maximum: number, name: string): number {\n\tif (!Number.isInteger(value) || value < minimum || value > maximum)\n\t\tthrow new Error(`${name} must be an integer between ${minimum} and ${maximum}`)\n\treturn value\n}\n\nconst auditEventProjection = z.object({\n\taction: z.string(),\n\tactorId: z.string().optional().catch(undefined),\n\tmetadata: z.object({ correlationKey: z.string(), transition: z.string() }),\n})\n\nfunction auditProjection(\n\tevent: Awaited<ReturnType<typeof approvalAudit.queryByResource>>[number],\n): ApprovalAuditProjection | null {\n\tconst parsed = auditEventProjection.safeParse(event)\n\tif (!parsed.success) return null\n\tconst { action, actorId, metadata } = parsed.data\n\treturn { action, actorRef: actorId, ...metadata }\n}\n"],"mappings":"iUA8BA,
|
|
1
|
+
{"version":3,"file":"audit.mjs","names":["approvalAudit","AuditLog","components","history","query","v","limit","input","events","ctx","unique","event","projection","auditProjection","cleanup","mutation","olderThanDays","boundedInteger","MAX_APPROVAL_AUDIT_RETENTION_DAYS","batchSize","APPROVAL_AUDIT_RETENTION_CATEGORY","approvalAuditEvent","logApprovalTransition","value","minimum","maximum","name","auditEventProjection","z","parsed","actorId","metadata"],"sources":["../../../src/components/approvals/audit.ts"],"sourcesContent":["import { z } from 'zod'\nimport { AuditLog, type AuditEventInput } from 'convex-audit-log'\nimport { v } from 'convex/values'\n\nimport { components } from './_generated/api'\nimport { mutation, query, type MutationCtx } from './_generated/server'\nimport {\n\tAPPROVAL_AUDIT_RETENTION_CATEGORY,\n\tMAX_APPROVAL_AUDIT_CLEANUP_BATCH_SIZE,\n\tMAX_APPROVAL_AUDIT_RETENTION_DAYS,\n\tMIN_APPROVAL_AUDIT_RETENTION_DAYS,\n} from './constants'\n\nexport type ApprovalAuditTransition = Readonly<{\n\taction: string\n\tactorRef?: string\n\trunId: string\n\tresourceType: string\n\tresourceRef: string\n\ttransition: string\n\tseverity?: AuditEventInput['severity']\n}>\n\nexport type ApprovalAuditProjection = Readonly<{\n\taction: string\n\tactorRef?: string\n\tcorrelationKey: string\n\ttransition: string\n}>\n\nexport const approvalAudit = new AuditLog(components.auditLog, {\n\tsamplingEnabled: false,\n})\n\nexport const history = query({\n\targs: {\n\t\tresourceType: v.string(),\n\t\tresourceRef: v.string(),\n\t\tlimit: v.optional(v.number()),\n\t},\n\treturns: v.array(\n\t\tv.object({\n\t\t\taction: v.string(),\n\t\t\tactorRef: v.optional(v.string()),\n\t\t\tcorrelationKey: v.string(),\n\t\t\ttransition: v.string(),\n\t\t}),\n\t),\n\thandler: async (ctx, input) => {\n\t\tconst limit = Math.max(1, Math.min(Math.trunc(input.limit ?? 100), 100))\n\t\tconst events = await approvalAudit.queryByResource(ctx, {\n\t\t\tresourceType: input.resourceType,\n\t\t\tresourceId: input.resourceRef,\n\t\t\tlimit,\n\t\t})\n\t\tconst unique = new Map<string, ApprovalAuditProjection>()\n\t\tfor (const event of events) {\n\t\t\tconst projection = auditProjection(event)\n\t\t\tif (projection) unique.set(projection.correlationKey, projection)\n\t\t}\n\t\treturn [...unique.values()]\n\t},\n})\n\nexport const cleanup = mutation({\n\targs: {\n\t\tolderThanDays: v.number(),\n\t\tbatchSize: v.number(),\n\t},\n\treturns: v.number(),\n\thandler: (ctx, input) => {\n\t\tconst olderThanDays = boundedInteger(\n\t\t\tinput.olderThanDays,\n\t\t\tMIN_APPROVAL_AUDIT_RETENTION_DAYS,\n\t\t\tMAX_APPROVAL_AUDIT_RETENTION_DAYS,\n\t\t\t'olderThanDays',\n\t\t)\n\t\tconst batchSize = boundedInteger(\n\t\t\tinput.batchSize,\n\t\t\t1,\n\t\t\tMAX_APPROVAL_AUDIT_CLEANUP_BATCH_SIZE,\n\t\t\t'batchSize',\n\t\t)\n\t\treturn approvalAudit.cleanup(ctx, {\n\t\t\tolderThanDays,\n\t\t\tbatchSize,\n\t\t\tretentionCategory: APPROVAL_AUDIT_RETENTION_CATEGORY,\n\t\t})\n\t},\n})\n\nexport function approvalAuditEvent(input: ApprovalAuditTransition): AuditEventInput {\n\treturn {\n\t\taction: input.action,\n\t\tactorId: input.actorRef,\n\t\tresourceType: input.resourceType,\n\t\tresourceId: input.resourceRef,\n\t\tseverity: input.severity ?? 'info',\n\t\ttags: ['approvals'],\n\t\tretentionCategory: APPROVAL_AUDIT_RETENTION_CATEGORY,\n\t\tmetadata: {\n\t\t\tcorrelationKey: `${input.runId}:${input.transition}`,\n\t\t\trunId: input.runId,\n\t\t\ttransition: input.transition,\n\t\t},\n\t}\n}\n\nexport async function logApprovalTransition(\n\tctx: MutationCtx,\n\tinput: ApprovalAuditTransition,\n): Promise<void> {\n\tawait approvalAudit.log(ctx, approvalAuditEvent(input))\n}\n\nfunction boundedInteger(value: number, minimum: number, maximum: number, name: string): number {\n\tif (!Number.isInteger(value) || value < minimum || value > maximum)\n\t\tthrow new Error(`${name} must be an integer between ${minimum} and ${maximum}`)\n\treturn value\n}\n\nconst auditEventProjection = z.object({\n\taction: z.string(),\n\tactorId: z.string().optional().catch(undefined),\n\tmetadata: z.object({ correlationKey: z.string(), transition: z.string() }),\n})\n\nfunction auditProjection(\n\tevent: Awaited<ReturnType<typeof approvalAudit.queryByResource>>[number],\n): ApprovalAuditProjection | null {\n\tconst parsed = auditEventProjection.safeParse(event)\n\tif (!parsed.success) return null\n\tconst { action, actorId, metadata } = parsed.data\n\treturn { action, actorRef: actorId, ...metadata }\n}\n"],"mappings":"iUA8BA,MAAaA,EAAgB,IAAIC,EAASC,EAAW,SAAU,CAC9D,gBAAiB,EAClB,CAAC,EAEYC,EAAUC,EAAM,CAC5B,KAAM,CACL,aAAcC,EAAE,OAAO,EACvB,YAAaA,EAAE,OAAO,EACtB,MAAOA,EAAE,SAASA,EAAE,OAAO,CAAC,CAC7B,EACA,QAASA,EAAE,MACVA,EAAE,OAAO,CACR,OAAQA,EAAE,OAAO,EACjB,SAAUA,EAAE,SAASA,EAAE,OAAO,CAAC,EAC/B,eAAgBA,EAAE,OAAO,EACzB,WAAYA,EAAE,OAAO,CACtB,CAAC,CACF,EACA,QAAS,MAAO,EAAK,IAAU,CAC9B,IAAMC,EAAQ,KAAK,IAAI,EAAG,KAAK,IAAI,KAAK,MAAMC,EAAM,OAAS,GAAG,EAAG,GAAG,CAAC,EACjEC,EAAS,MAAMR,EAAc,gBAAgBS,EAAK,CACvD,aAAcF,EAAM,aACpB,WAAYA,EAAM,YAClB,OACD,CAAC,EACKG,kBAAS,IAAI,IACnB,IAAK,IAAMC,KAASH,EAAQ,CAC3B,IAAMI,EAAaC,EAAgBF,CAAK,EACpCC,GAAYF,EAAO,IAAIE,EAAW,eAAgBA,CAAU,CACjE,CACA,MAAO,CAAC,GAAGF,EAAO,OAAO,CAAC,CAC3B,CACD,CAAC,EAEYI,EAAUC,EAAS,CAC/B,KAAM,CACL,cAAeV,EAAE,OAAO,EACxB,UAAWA,EAAE,OAAO,CACrB,EACA,QAASA,EAAE,OAAO,EAClB,SAAU,EAAK,IAAU,CACxB,IAAMW,EAAgBC,EACrBV,EAAM,cAAA,EAENW,EACA,eACD,EACMC,EAAYF,EACjBV,EAAM,UACN,EAAA,IAEA,WACD,EACA,OAAOP,EAAc,QAAQS,EAAK,CACjC,gBACA,YACA,kBAAmBW,CACpB,CAAC,CACF,CACD,CAAC,EAED,SAAgBC,EAAmB,EAAiD,CACnF,MAAO,CACN,OAAQd,EAAM,OACd,QAASA,EAAM,SACf,aAAcA,EAAM,aACpB,WAAYA,EAAM,YAClB,SAAUA,EAAM,UAAY,OAC5B,KAAM,CAAC,WAAW,EAClB,kBAAmBa,EACnB,SAAU,CACT,eAAgB,GAAGb,EAAM,MAAM,GAAGA,EAAM,aACxC,MAAOA,EAAM,MACb,WAAYA,EAAM,UACnB,CACD,CACD,CAEA,eAAsBe,EACrB,EACA,EACgB,CAChB,MAAMtB,EAAc,IAAIS,EAAKY,EAAmBd,CAAK,CAAC,CACvD,CAEA,SAASU,EAAe,EAAe,EAAiB,EAAiB,EAAsB,CAC9F,GAAI,CAAC,OAAO,UAAUM,CAAK,GAAKA,EAAQC,GAAWD,EAAQE,EAC1D,MAAU,MAAM,GAAGC,EAAK,8BAA8BF,EAAQ,OAAOC,GAAS,EAC/E,OAAOF,CACR,CAEA,MAAMI,EAAuBC,EAAE,OAAO,CACrC,OAAQA,EAAE,OAAO,EACjB,QAASA,EAAE,OAAO,CAAC,CAAC,SAAS,CAAC,CAAC,MAAM,IAAA,EAAS,EAC9C,SAAUA,EAAE,OAAO,CAAE,eAAgBA,EAAE,OAAO,EAAG,WAAYA,EAAE,OAAO,CAAE,CAAC,CAC1E,CAAC,EAED,SAASf,EACR,EACiC,CACjC,IAAMgB,EAASF,EAAqB,UAAUhB,CAAK,EACnD,GAAI,CAACkB,EAAO,QAAS,OAAO,KAC5B,GAAM,CAAE,SAAQ,UAAS,YAAaA,EAAO,KAC7C,MAAO,CAAE,SAAQ,SAAUC,EAAS,GAAGC,CAAS,CACjD"}
|
|
@@ -6,39 +6,39 @@ import { FunctionArgs, FunctionReference, FunctionReturnType, GenericDataModel,
|
|
|
6
6
|
declare namespace client_d_exports {
|
|
7
7
|
export { ApprovalAuditCleanupInput, ApprovalAuditHistoryInput, ApprovalCallbackInput, ApprovalDecisionInput, ApprovalEvidenceItem, ApprovalStartInput, ApprovalStatus, Approvals, ApprovalsOptions, ConfiguredApprovalWorkflow, approvalCallbackArgs, approvalCallbackInput };
|
|
8
8
|
}
|
|
9
|
-
type ApprovalsOptions = Readonly<{
|
|
9
|
+
export type ApprovalsOptions = Readonly<{
|
|
10
10
|
createHandle?: CreateApprovalHandle;
|
|
11
11
|
}>;
|
|
12
|
-
type ApprovalStartInput = Readonly<{
|
|
12
|
+
export type ApprovalStartInput = Readonly<{
|
|
13
13
|
scopeRef: string;
|
|
14
14
|
resourceType: string;
|
|
15
15
|
resourceRef: string;
|
|
16
16
|
requester: ApprovalActor;
|
|
17
17
|
metadata?: ApprovalMetadata;
|
|
18
18
|
}>;
|
|
19
|
-
type ApprovalDecisionInput = Readonly<{
|
|
19
|
+
export type ApprovalDecisionInput = Readonly<{
|
|
20
20
|
runId: string;
|
|
21
21
|
decision: ApprovalDecision;
|
|
22
22
|
reason?: string;
|
|
23
23
|
}>;
|
|
24
|
-
type ApprovalEvidenceItem = Readonly<{
|
|
24
|
+
export type ApprovalEvidenceItem = Readonly<{
|
|
25
25
|
stepKey: string;
|
|
26
26
|
actorRef: string;
|
|
27
27
|
decision: ApprovalDecision;
|
|
28
28
|
reason?: string;
|
|
29
29
|
decidedAt: number;
|
|
30
30
|
}>;
|
|
31
|
-
type ApprovalAuditHistoryInput = Readonly<{
|
|
31
|
+
export type ApprovalAuditHistoryInput = Readonly<{
|
|
32
32
|
resourceType: string;
|
|
33
33
|
resourceRef: string;
|
|
34
34
|
limit?: number;
|
|
35
35
|
}>;
|
|
36
|
-
type ApprovalAuditCleanupInput = Readonly<{
|
|
36
|
+
export type ApprovalAuditCleanupInput = Readonly<{
|
|
37
37
|
olderThanDays: number;
|
|
38
38
|
batchSize: number;
|
|
39
39
|
}>;
|
|
40
|
-
type ApprovalStatus = FunctionReturnType<ComponentApi['requests']['status']>;
|
|
41
|
-
declare class Approvals<Component extends ComponentApi = ComponentApi> {
|
|
40
|
+
export type ApprovalStatus = FunctionReturnType<ComponentApi['requests']['status']>;
|
|
41
|
+
export declare class Approvals<Component extends ComponentApi = ComponentApi> {
|
|
42
42
|
private readonly component;
|
|
43
43
|
private readonly createHandle;
|
|
44
44
|
constructor(component: Component, options?: ApprovalsOptions);
|
|
@@ -74,7 +74,7 @@ declare class Approvals<Component extends ComponentApi = ComponentApi> {
|
|
|
74
74
|
steps: readonly ApprovalWorkflowStep[];
|
|
75
75
|
}>): ConfiguredApprovalWorkflow<Component>;
|
|
76
76
|
}
|
|
77
|
-
declare class ConfiguredApprovalWorkflow<Component extends ComponentApi = ComponentApi> {
|
|
77
|
+
export declare class ConfiguredApprovalWorkflow<Component extends ComponentApi = ComponentApi> {
|
|
78
78
|
readonly name: string;
|
|
79
79
|
readonly compatibilityKey: string;
|
|
80
80
|
readonly steps: readonly ApprovalWorkflowStep[];
|
|
@@ -93,5 +93,5 @@ declare class ConfiguredApprovalWorkflow<Component extends ComponentApi = Compon
|
|
|
93
93
|
restart<DataModel extends GenericDataModel>(ctx: GenericMutationCtx<DataModel>, runId: string): Promise<FunctionReturnType<Component['requests']['restart']>>;
|
|
94
94
|
}
|
|
95
95
|
//#endregion
|
|
96
|
-
export {
|
|
96
|
+
export { type ApprovalCallbackInput, approvalCallbackArgs, approvalCallbackInput, client_d_exports };
|
|
97
97
|
//# sourceMappingURL=client.d.mts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"client.mjs","names":[],"sources":["../../../src/components/approvals/client.ts"],"sourcesContent":["import type { ApprovalCallbackInput } from './validators'\nimport type {\n\tFunctionArgs,\n\tFunctionReference,\n\tFunctionReturnType,\n\tGenericDataModel,\n\tGenericMutationCtx,\n\tGenericQueryCtx,\n} from 'convex/server'\n\nimport type { ComponentApi } from './_generated/component'\nimport type { ApprovalDecision } from './constants'\nimport type { ApprovalActor, ApprovalMetadata, ApprovalWorkflowDescriptor } from './validators'\nimport {\n\tcompileApprovalDescriptor,\n\ttype ApprovalActionStep,\n\ttype ApprovalBranchStep,\n\ttype ApprovalDecisionStep,\n\ttype ApprovalDefinition,\n\ttype ApprovalMutationStep,\n\ttype ApprovalNotifyStep,\n\ttype ApprovalWorkflowStep,\n\ttype CreateApprovalHandle,\n} from './workflow_steps'\n\nexport { approvalCallbackArgs, approvalCallbackInput } from './validators'\nexport type { ApprovalCallbackInput } from './validators'\n\nexport type ApprovalsOptions = Readonly<{\n\tcreateHandle?: CreateApprovalHandle\n}>\n\nexport type ApprovalStartInput = Readonly<{\n\tscopeRef: string\n\tresourceType: string\n\tresourceRef: string\n\trequester: ApprovalActor\n\tmetadata?: ApprovalMetadata\n}>\n\nexport type ApprovalDecisionInput = Readonly<{\n\trunId: string\n\tdecision: ApprovalDecision\n\treason?: string\n}>\n\nexport type ApprovalEvidenceItem = Readonly<{\n\tstepKey: string\n\tactorRef: string\n\tdecision: ApprovalDecision\n\treason?: string\n\tdecidedAt: number\n}>\n\nexport type ApprovalAuditHistoryInput = Readonly<{\n\tresourceType: string\n\tresourceRef: string\n\tlimit?: number\n}>\n\nexport type ApprovalAuditCleanupInput = Readonly<{\n\tolderThanDays: number\n\tbatchSize: number\n}>\n\nexport type ApprovalStatus = FunctionReturnType<ComponentApi['requests']['status']>\n\nexport class Approvals<Component extends ComponentApi = ComponentApi> {\n\tprivate readonly component: Component\n\tprivate readonly createHandle: CreateApprovalHandle | undefined\n\n\tconstructor(component: Component, options: ApprovalsOptions = {}) {\n\t\tthis.component = component\n\t\tthis.createHandle = options.createHandle\n\t}\n\n\tcleanupAudit<DataModel extends GenericDataModel>(\n\t\tctx: GenericMutationCtx<DataModel>,\n\t\tinput: ApprovalAuditCleanupInput,\n\t): Promise<FunctionReturnType<Component['audit']['cleanup']>> {\n\t\treturn ctx.runMutation(this.component.audit.cleanup, input)\n\t}\n\n\tmutation(\n\t\tkey: string,\n\t\toptions: Readonly<{\n\t\t\thandler: FunctionReference<'mutation', 'internal', ApprovalCallbackInput, unknown>\n\t\t\tretry?: boolean\n\t\t}>,\n\t): ApprovalMutationStep {\n\t\treturn Object.freeze({\n\t\t\tkind: 'mutation',\n\t\t\tkey,\n\t\t\thandler: options.handler,\n\t\t\tretry: options.retry ?? false,\n\t\t})\n\t}\n\n\taction(\n\t\tkey: string,\n\t\toptions: Readonly<{\n\t\t\thandler: FunctionReference<'action', 'internal', ApprovalCallbackInput, unknown>\n\t\t\tretry?: boolean\n\t\t}>,\n\t): ApprovalActionStep {\n\t\treturn Object.freeze({\n\t\t\tkind: 'action',\n\t\t\tkey,\n\t\t\thandler: options.handler,\n\t\t\tretry: options.retry ?? false,\n\t\t})\n\t}\n\n\tnotify(\n\t\tkey: string,\n\t\toptions: Readonly<{\n\t\t\thandler: FunctionReference<'action', 'internal', ApprovalCallbackInput, unknown>\n\t\t\tretry?: boolean\n\t\t}>,\n\t): ApprovalNotifyStep {\n\t\treturn Object.freeze({\n\t\t\tkind: 'notify',\n\t\t\tkey,\n\t\t\thandler: options.handler,\n\t\t\tretry: options.retry ?? false,\n\t\t})\n\t}\n\n\tdecision(\n\t\tkey: string,\n\t\toptions: Readonly<{\n\t\t\tdecisions: readonly ApprovalDecision[]\n\t\t\tquorum: Readonly<{ kind: 'count'; approvals: number }>\n\t\t\tmakerChecker?: boolean\n\t\t\texpiresAfterMs?: number\n\t\t}>,\n\t): ApprovalDecisionStep {\n\t\treturn Object.freeze({\n\t\t\tkind: 'decision',\n\t\t\tkey,\n\t\t\tdecisions: Object.freeze([...options.decisions]),\n\t\t\tquorum: Object.freeze({ ...options.quorum }),\n\t\t\tmakerChecker: options.makerChecker ?? false,\n\t\t\texpiresAfterMs: options.expiresAfterMs,\n\t\t})\n\t}\n\n\tbranch(\n\t\tkey: string,\n\t\toptions: Readonly<{\n\t\t\tapprovedStepKey: string\n\t\t\trejectedStepKey: string\n\t\t}>,\n\t): ApprovalBranchStep {\n\t\treturn Object.freeze({ kind: 'branch', key, ...options })\n\t}\n\n\tdefine(\n\t\tinput: Readonly<{\n\t\t\tname: string\n\t\t\tcompatibilityKey?: string\n\t\t\tsteps: readonly ApprovalWorkflowStep[]\n\t\t}>,\n\t): ConfiguredApprovalWorkflow<Component> {\n\t\tconst definition = freezeDefinition({\n\t\t\tname: input.name,\n\t\t\tcompatibilityKey: input.compatibilityKey ?? input.name,\n\t\t\tsteps: input.steps,\n\t\t})\n\t\treturn new ConfiguredApprovalWorkflow(this.component, definition, this.createHandle)\n\t}\n}\n\nexport class ConfiguredApprovalWorkflow<Component extends ComponentApi = ComponentApi> {\n\treadonly name: string\n\treadonly compatibilityKey: string\n\treadonly steps: readonly ApprovalWorkflowStep[]\n\n\tprivate readonly component: Component\n\tprivate readonly definition: ApprovalDefinition\n\tprivate readonly createHandle: CreateApprovalHandle | undefined\n\n\tconstructor(\n\t\tcomponent: Component,\n\t\tdefinition: ApprovalDefinition,\n\t\tcreateHandle?: CreateApprovalHandle,\n\t) {\n\t\tthis.component = component\n\t\tthis.definition = definition\n\t\tthis.name = definition.name\n\t\tthis.compatibilityKey = definition.compatibilityKey\n\t\tthis.steps = definition.steps\n\t\tthis.createHandle = createHandle\n\t\tObject.freeze(this)\n\t}\n\n\tdescriptor(): Promise<Readonly<ApprovalWorkflowDescriptor>> {\n\t\treturn compileApprovalDescriptor(this.definition, this.createHandle)\n\t}\n\n\tasync start<DataModel extends GenericDataModel>(\n\t\tctx: GenericMutationCtx<DataModel>,\n\t\tinput: ApprovalStartInput,\n\t): Promise<FunctionReturnType<Component['requests']['start']>> {\n\t\treturn ctx.runMutation(this.component.requests.start, {\n\t\t\t...input,\n\t\t\tworkflow: await this.descriptor(),\n\t\t})\n\t}\n\n\tdecide<DataModel extends GenericDataModel>(\n\t\tctx: GenericMutationCtx<DataModel>,\n\t\tinput: ApprovalDecisionInput,\n\t\tactor: ApprovalActor,\n\t): Promise<FunctionReturnType<Component['decisions']['decide']>> {\n\t\treturn ctx.runMutation(this.component.decisions.decide, {\n\t\t\t...input,\n\t\t\tactor,\n\t\t\tcompatibilityKey: this.compatibilityKey,\n\t\t})\n\t}\n\n\tevidence<DataModel extends GenericDataModel>(\n\t\tctx: GenericQueryCtx<DataModel>,\n\t\trunId: string,\n\t): Promise<FunctionReturnType<Component['decisions']['list']>> {\n\t\treturn ctx.runQuery(this.component.decisions.list, { runId })\n\t}\n\n\tauditHistory<DataModel extends GenericDataModel>(\n\t\tctx: GenericQueryCtx<DataModel>,\n\t\tinput: ApprovalAuditHistoryInput,\n\t): Promise<FunctionReturnType<Component['audit']['history']>> {\n\t\treturn ctx.runQuery(this.component.audit.history, input)\n\t}\n\n\tcancel<DataModel extends GenericDataModel>(\n\t\tctx: GenericMutationCtx<DataModel>,\n\t\trunId: string,\n\t\tactor: ApprovalActor,\n\t): Promise<FunctionReturnType<Component['requests']['cancel']>> {\n\t\treturn ctx.runMutation(this.component.requests.cancel, {\n\t\t\trunId,\n\t\t\tactor,\n\t\t\tcompatibilityKey: this.compatibilityKey,\n\t\t})\n\t}\n\n\tstatus<DataModel extends GenericDataModel>(\n\t\tctx: GenericQueryCtx<DataModel>,\n\t\trunId: string,\n\t): Promise<ApprovalStatus | null> {\n\t\treturn ctx.runQuery(this.component.requests.status, {\n\t\t\trunId,\n\t\t\tcompatibilityKey: this.compatibilityKey,\n\t\t})\n\t}\n\n\tlist<DataModel extends GenericDataModel>(\n\t\tctx: GenericQueryCtx<DataModel>,\n\t\tinput: FunctionArgs<Component['requests']['list']>,\n\t): Promise<FunctionReturnType<Component['requests']['list']>> {\n\t\treturn ctx.runQuery(this.component.requests.list, input)\n\t}\n\n\trestart<DataModel extends GenericDataModel>(\n\t\tctx: GenericMutationCtx<DataModel>,\n\t\trunId: string,\n\t): Promise<FunctionReturnType<Component['requests']['restart']>> {\n\t\treturn ctx.runMutation(this.component.requests.restart, {\n\t\t\trunId,\n\t\t\tcompatibilityKey: this.compatibilityKey,\n\t\t})\n\t}\n}\n\nfunction freezeDefinition(definition: ApprovalDefinition): ApprovalDefinition {\n\treturn Object.freeze({\n\t\t...definition,\n\t\tsteps: Object.freeze(\n\t\t\tdefinition.steps.map((step) => {\n\t\t\t\tif (step.kind === 'decision')\n\t\t\t\t\treturn Object.freeze({\n\t\t\t\t\t\t...step,\n\t\t\t\t\t\tdecisions: Object.freeze([...step.decisions]),\n\t\t\t\t\t\tquorum: Object.freeze({ ...step.quorum }),\n\t\t\t\t\t})\n\t\t\t\treturn Object.freeze({ ...step })\n\t\t\t}),\n\t\t),\n\t})\n}\n\n// The component definition is deliberately NOT re-exported here: Convex's\n// CLI only discovers a component whose resolved file is convex.config.js,\n// so hosts must mount via the dedicated subpath:\n// import approvals from 'cvx-kit/components/approvals/convex.config'\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"client.mjs","names":["Approvals","component","options","ctx","input","definition","freezeDefinition","ConfiguredApprovalWorkflow","createHandle","compileApprovalDescriptor","step","approvalCallbackArgs","approvalCallbackInput"],"sources":["../../../src/components/approvals/client.ts"],"sourcesContent":["import type { ApprovalCallbackInput } from './validators'\nimport type {\n\tFunctionArgs,\n\tFunctionReference,\n\tFunctionReturnType,\n\tGenericDataModel,\n\tGenericMutationCtx,\n\tGenericQueryCtx,\n} from 'convex/server'\n\nimport type { ComponentApi } from './_generated/component'\nimport type { ApprovalDecision } from './constants'\nimport type { ApprovalActor, ApprovalMetadata, ApprovalWorkflowDescriptor } from './validators'\nimport {\n\tcompileApprovalDescriptor,\n\ttype ApprovalActionStep,\n\ttype ApprovalBranchStep,\n\ttype ApprovalDecisionStep,\n\ttype ApprovalDefinition,\n\ttype ApprovalMutationStep,\n\ttype ApprovalNotifyStep,\n\ttype ApprovalWorkflowStep,\n\ttype CreateApprovalHandle,\n} from './workflow_steps'\n\nexport { approvalCallbackArgs, approvalCallbackInput } from './validators'\nexport type { ApprovalCallbackInput } from './validators'\n\nexport type ApprovalsOptions = Readonly<{\n\tcreateHandle?: CreateApprovalHandle\n}>\n\nexport type ApprovalStartInput = Readonly<{\n\tscopeRef: string\n\tresourceType: string\n\tresourceRef: string\n\trequester: ApprovalActor\n\tmetadata?: ApprovalMetadata\n}>\n\nexport type ApprovalDecisionInput = Readonly<{\n\trunId: string\n\tdecision: ApprovalDecision\n\treason?: string\n}>\n\nexport type ApprovalEvidenceItem = Readonly<{\n\tstepKey: string\n\tactorRef: string\n\tdecision: ApprovalDecision\n\treason?: string\n\tdecidedAt: number\n}>\n\nexport type ApprovalAuditHistoryInput = Readonly<{\n\tresourceType: string\n\tresourceRef: string\n\tlimit?: number\n}>\n\nexport type ApprovalAuditCleanupInput = Readonly<{\n\tolderThanDays: number\n\tbatchSize: number\n}>\n\nexport type ApprovalStatus = FunctionReturnType<ComponentApi['requests']['status']>\n\nexport class Approvals<Component extends ComponentApi = ComponentApi> {\n\tprivate readonly component: Component\n\tprivate readonly createHandle: CreateApprovalHandle | undefined\n\n\tconstructor(component: Component, options: ApprovalsOptions = {}) {\n\t\tthis.component = component\n\t\tthis.createHandle = options.createHandle\n\t}\n\n\tcleanupAudit<DataModel extends GenericDataModel>(\n\t\tctx: GenericMutationCtx<DataModel>,\n\t\tinput: ApprovalAuditCleanupInput,\n\t): Promise<FunctionReturnType<Component['audit']['cleanup']>> {\n\t\treturn ctx.runMutation(this.component.audit.cleanup, input)\n\t}\n\n\tmutation(\n\t\tkey: string,\n\t\toptions: Readonly<{\n\t\t\thandler: FunctionReference<'mutation', 'internal', ApprovalCallbackInput, unknown>\n\t\t\tretry?: boolean\n\t\t}>,\n\t): ApprovalMutationStep {\n\t\treturn Object.freeze({\n\t\t\tkind: 'mutation',\n\t\t\tkey,\n\t\t\thandler: options.handler,\n\t\t\tretry: options.retry ?? false,\n\t\t})\n\t}\n\n\taction(\n\t\tkey: string,\n\t\toptions: Readonly<{\n\t\t\thandler: FunctionReference<'action', 'internal', ApprovalCallbackInput, unknown>\n\t\t\tretry?: boolean\n\t\t}>,\n\t): ApprovalActionStep {\n\t\treturn Object.freeze({\n\t\t\tkind: 'action',\n\t\t\tkey,\n\t\t\thandler: options.handler,\n\t\t\tretry: options.retry ?? false,\n\t\t})\n\t}\n\n\tnotify(\n\t\tkey: string,\n\t\toptions: Readonly<{\n\t\t\thandler: FunctionReference<'action', 'internal', ApprovalCallbackInput, unknown>\n\t\t\tretry?: boolean\n\t\t}>,\n\t): ApprovalNotifyStep {\n\t\treturn Object.freeze({\n\t\t\tkind: 'notify',\n\t\t\tkey,\n\t\t\thandler: options.handler,\n\t\t\tretry: options.retry ?? false,\n\t\t})\n\t}\n\n\tdecision(\n\t\tkey: string,\n\t\toptions: Readonly<{\n\t\t\tdecisions: readonly ApprovalDecision[]\n\t\t\tquorum: Readonly<{ kind: 'count'; approvals: number }>\n\t\t\tmakerChecker?: boolean\n\t\t\texpiresAfterMs?: number\n\t\t}>,\n\t): ApprovalDecisionStep {\n\t\treturn Object.freeze({\n\t\t\tkind: 'decision',\n\t\t\tkey,\n\t\t\tdecisions: Object.freeze([...options.decisions]),\n\t\t\tquorum: Object.freeze({ ...options.quorum }),\n\t\t\tmakerChecker: options.makerChecker ?? false,\n\t\t\texpiresAfterMs: options.expiresAfterMs,\n\t\t})\n\t}\n\n\tbranch(\n\t\tkey: string,\n\t\toptions: Readonly<{\n\t\t\tapprovedStepKey: string\n\t\t\trejectedStepKey: string\n\t\t}>,\n\t): ApprovalBranchStep {\n\t\treturn Object.freeze({ kind: 'branch', key, ...options })\n\t}\n\n\tdefine(\n\t\tinput: Readonly<{\n\t\t\tname: string\n\t\t\tcompatibilityKey?: string\n\t\t\tsteps: readonly ApprovalWorkflowStep[]\n\t\t}>,\n\t): ConfiguredApprovalWorkflow<Component> {\n\t\tconst definition = freezeDefinition({\n\t\t\tname: input.name,\n\t\t\tcompatibilityKey: input.compatibilityKey ?? input.name,\n\t\t\tsteps: input.steps,\n\t\t})\n\t\treturn new ConfiguredApprovalWorkflow(this.component, definition, this.createHandle)\n\t}\n}\n\nexport class ConfiguredApprovalWorkflow<Component extends ComponentApi = ComponentApi> {\n\treadonly name: string\n\treadonly compatibilityKey: string\n\treadonly steps: readonly ApprovalWorkflowStep[]\n\n\tprivate readonly component: Component\n\tprivate readonly definition: ApprovalDefinition\n\tprivate readonly createHandle: CreateApprovalHandle | undefined\n\n\tconstructor(\n\t\tcomponent: Component,\n\t\tdefinition: ApprovalDefinition,\n\t\tcreateHandle?: CreateApprovalHandle,\n\t) {\n\t\tthis.component = component\n\t\tthis.definition = definition\n\t\tthis.name = definition.name\n\t\tthis.compatibilityKey = definition.compatibilityKey\n\t\tthis.steps = definition.steps\n\t\tthis.createHandle = createHandle\n\t\tObject.freeze(this)\n\t}\n\n\tdescriptor(): Promise<Readonly<ApprovalWorkflowDescriptor>> {\n\t\treturn compileApprovalDescriptor(this.definition, this.createHandle)\n\t}\n\n\tasync start<DataModel extends GenericDataModel>(\n\t\tctx: GenericMutationCtx<DataModel>,\n\t\tinput: ApprovalStartInput,\n\t): Promise<FunctionReturnType<Component['requests']['start']>> {\n\t\treturn ctx.runMutation(this.component.requests.start, {\n\t\t\t...input,\n\t\t\tworkflow: await this.descriptor(),\n\t\t})\n\t}\n\n\tdecide<DataModel extends GenericDataModel>(\n\t\tctx: GenericMutationCtx<DataModel>,\n\t\tinput: ApprovalDecisionInput,\n\t\tactor: ApprovalActor,\n\t): Promise<FunctionReturnType<Component['decisions']['decide']>> {\n\t\treturn ctx.runMutation(this.component.decisions.decide, {\n\t\t\t...input,\n\t\t\tactor,\n\t\t\tcompatibilityKey: this.compatibilityKey,\n\t\t})\n\t}\n\n\tevidence<DataModel extends GenericDataModel>(\n\t\tctx: GenericQueryCtx<DataModel>,\n\t\trunId: string,\n\t): Promise<FunctionReturnType<Component['decisions']['list']>> {\n\t\treturn ctx.runQuery(this.component.decisions.list, { runId })\n\t}\n\n\tauditHistory<DataModel extends GenericDataModel>(\n\t\tctx: GenericQueryCtx<DataModel>,\n\t\tinput: ApprovalAuditHistoryInput,\n\t): Promise<FunctionReturnType<Component['audit']['history']>> {\n\t\treturn ctx.runQuery(this.component.audit.history, input)\n\t}\n\n\tcancel<DataModel extends GenericDataModel>(\n\t\tctx: GenericMutationCtx<DataModel>,\n\t\trunId: string,\n\t\tactor: ApprovalActor,\n\t): Promise<FunctionReturnType<Component['requests']['cancel']>> {\n\t\treturn ctx.runMutation(this.component.requests.cancel, {\n\t\t\trunId,\n\t\t\tactor,\n\t\t\tcompatibilityKey: this.compatibilityKey,\n\t\t})\n\t}\n\n\tstatus<DataModel extends GenericDataModel>(\n\t\tctx: GenericQueryCtx<DataModel>,\n\t\trunId: string,\n\t): Promise<ApprovalStatus | null> {\n\t\treturn ctx.runQuery(this.component.requests.status, {\n\t\t\trunId,\n\t\t\tcompatibilityKey: this.compatibilityKey,\n\t\t})\n\t}\n\n\tlist<DataModel extends GenericDataModel>(\n\t\tctx: GenericQueryCtx<DataModel>,\n\t\tinput: FunctionArgs<Component['requests']['list']>,\n\t): Promise<FunctionReturnType<Component['requests']['list']>> {\n\t\treturn ctx.runQuery(this.component.requests.list, input)\n\t}\n\n\trestart<DataModel extends GenericDataModel>(\n\t\tctx: GenericMutationCtx<DataModel>,\n\t\trunId: string,\n\t): Promise<FunctionReturnType<Component['requests']['restart']>> {\n\t\treturn ctx.runMutation(this.component.requests.restart, {\n\t\t\trunId,\n\t\t\tcompatibilityKey: this.compatibilityKey,\n\t\t})\n\t}\n}\n\nfunction freezeDefinition(definition: ApprovalDefinition): ApprovalDefinition {\n\treturn Object.freeze({\n\t\t...definition,\n\t\tsteps: Object.freeze(\n\t\t\tdefinition.steps.map((step) => {\n\t\t\t\tif (step.kind === 'decision')\n\t\t\t\t\treturn Object.freeze({\n\t\t\t\t\t\t...step,\n\t\t\t\t\t\tdecisions: Object.freeze([...step.decisions]),\n\t\t\t\t\t\tquorum: Object.freeze({ ...step.quorum }),\n\t\t\t\t\t})\n\t\t\t\treturn Object.freeze({ ...step })\n\t\t\t}),\n\t\t),\n\t})\n}\n\n// The component definition is deliberately NOT re-exported here: Convex's\n// CLI only discovers a component whose resolved file is convex.config.js,\n// so hosts must mount via the dedicated subpath:\n// import approvals from 'cvx-kit/components/approvals/convex.config'\n"],"mappings":"oJAmEA,IAAaA,EAAb,KAAsE,CACrE,UACA,aAEA,YAAY,EAAsB,EAA4B,CAAC,EAAG,CACjE,KAAK,UAAYC,EACjB,KAAK,aAAeC,EAAQ,YAC7B,CAEA,aACC,EACA,EAC6D,CAC7D,OAAOC,EAAI,YAAY,KAAK,UAAU,MAAM,QAASC,CAAK,CAC3D,CAEA,SACC,EACA,EAIuB,CACvB,OAAO,OAAO,OAAO,CACpB,KAAM,WACN,MACA,QAASF,EAAQ,QACjB,MAAOA,EAAQ,OAAS,EACzB,CAAC,CACF,CAEA,OACC,EACA,EAIqB,CACrB,OAAO,OAAO,OAAO,CACpB,KAAM,SACN,MACA,QAASA,EAAQ,QACjB,MAAOA,EAAQ,OAAS,EACzB,CAAC,CACF,CAEA,OACC,EACA,EAIqB,CACrB,OAAO,OAAO,OAAO,CACpB,KAAM,SACN,MACA,QAASA,EAAQ,QACjB,MAAOA,EAAQ,OAAS,EACzB,CAAC,CACF,CAEA,SACC,EACA,EAMuB,CACvB,OAAO,OAAO,OAAO,CACpB,KAAM,WACN,MACA,UAAW,OAAO,OAAO,CAAC,GAAGA,EAAQ,SAAS,CAAC,EAC/C,OAAQ,OAAO,OAAO,CAAE,GAAGA,EAAQ,MAAO,CAAC,EAC3C,aAAcA,EAAQ,cAAgB,GACtC,eAAgBA,EAAQ,cACzB,CAAC,CACF,CAEA,OACC,EACA,EAIqB,CACrB,OAAO,OAAO,OAAO,CAAE,KAAM,SAAU,MAAK,GAAGA,CAAQ,CAAC,CACzD,CAEA,OACC,EAKwC,CACxC,IAAMG,EAAaC,EAAiB,CACnC,KAAMF,EAAM,KACZ,iBAAkBA,EAAM,kBAAoBA,EAAM,KAClD,MAAOA,EAAM,KACd,CAAC,EACD,OAAO,IAAIG,EAA2B,KAAK,UAAWF,EAAY,KAAK,YAAY,CACpF,CACD,EAEaE,EAAb,KAAuF,CACtF,KACA,iBACA,MAEA,UACA,WACA,aAEA,YACC,EACA,EACA,EACC,CACD,KAAK,UAAYN,EACjB,KAAK,WAAaI,EAClB,KAAK,KAAOA,EAAW,KACvB,KAAK,iBAAmBA,EAAW,iBACnC,KAAK,MAAQA,EAAW,MACxB,KAAK,aAAeG,EACpB,OAAO,OAAO,IAAI,CACnB,CAEA,YAA4D,CAC3D,OAAOC,EAA0B,KAAK,WAAY,KAAK,YAAY,CACpE,CAEA,MAAM,MACL,EACA,EAC8D,CAC9D,OAAON,EAAI,YAAY,KAAK,UAAU,SAAS,MAAO,CACrD,GAAGC,EACH,SAAU,MAAM,KAAK,WAAW,CACjC,CAAC,CACF,CAEA,OACC,EACA,EACA,EACgE,CAChE,OAAOD,EAAI,YAAY,KAAK,UAAU,UAAU,OAAQ,CACvD,GAAGC,EACH,QACA,iBAAkB,KAAK,gBACxB,CAAC,CACF,CAEA,SACC,EACA,EAC8D,CAC9D,OAAOD,EAAI,SAAS,KAAK,UAAU,UAAU,KAAM,CAAE,OAAM,CAAC,CAC7D,CAEA,aACC,EACA,EAC6D,CAC7D,OAAOA,EAAI,SAAS,KAAK,UAAU,MAAM,QAASC,CAAK,CACxD,CAEA,OACC,EACA,EACA,EAC+D,CAC/D,OAAOD,EAAI,YAAY,KAAK,UAAU,SAAS,OAAQ,CACtD,QACA,QACA,iBAAkB,KAAK,gBACxB,CAAC,CACF,CAEA,OACC,EACA,EACiC,CACjC,OAAOA,EAAI,SAAS,KAAK,UAAU,SAAS,OAAQ,CACnD,QACA,iBAAkB,KAAK,gBACxB,CAAC,CACF,CAEA,KACC,EACA,EAC6D,CAC7D,OAAOA,EAAI,SAAS,KAAK,UAAU,SAAS,KAAMC,CAAK,CACxD,CAEA,QACC,EACA,EACgE,CAChE,OAAOD,EAAI,YAAY,KAAK,UAAU,SAAS,QAAS,CACvD,QACA,iBAAkB,KAAK,gBACxB,CAAC,CACF,CACD,EAEA,SAASG,EAAiB,EAAoD,CAC7E,OAAO,OAAO,OAAO,CACpB,GAAGD,EACH,MAAO,OAAO,OACbA,EAAW,MAAM,IAAK,GACjBK,EAAK,OAAS,WACV,OAAO,OAAO,CACpB,GAAGA,EACH,UAAW,OAAO,OAAO,CAAC,GAAGA,EAAK,SAAS,CAAC,EAC5C,OAAQ,OAAO,OAAO,CAAE,GAAGA,EAAK,MAAO,CAAC,CACzC,CAAC,EACK,OAAO,OAAO,CAAE,GAAGA,CAAK,CAAC,CAChC,CACF,CACD,CAAC,CACF"}
|