@gaganref/convex-api-keys 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +201 -0
- package/README.md +419 -0
- package/dist/client/_generated/_ignore.d.ts +1 -0
- package/dist/client/_generated/_ignore.d.ts.map +1 -0
- package/dist/client/_generated/_ignore.js +3 -0
- package/dist/client/_generated/_ignore.js.map +1 -0
- package/dist/client/crypto.d.ts +4 -0
- package/dist/client/crypto.d.ts.map +1 -0
- package/dist/client/crypto.js +48 -0
- package/dist/client/crypto.js.map +1 -0
- package/dist/client/errors.d.ts +32 -0
- package/dist/client/errors.d.ts.map +1 -0
- package/dist/client/errors.js +43 -0
- package/dist/client/errors.js.map +1 -0
- package/dist/client/index.d.ts +7 -0
- package/dist/client/index.d.ts.map +1 -0
- package/dist/client/index.js +4 -0
- package/dist/client/index.js.map +1 -0
- package/dist/client/operations.d.ts +240 -0
- package/dist/client/operations.d.ts.map +1 -0
- package/dist/client/operations.js +700 -0
- package/dist/client/operations.js.map +1 -0
- package/dist/client/options.d.ts +79 -0
- package/dist/client/options.d.ts.map +1 -0
- package/dist/client/options.js +51 -0
- package/dist/client/options.js.map +1 -0
- package/dist/client/types.d.ts +269 -0
- package/dist/client/types.d.ts.map +1 -0
- package/dist/client/types.js +24 -0
- package/dist/client/types.js.map +1 -0
- package/dist/component/_generated/api.d.ts +40 -0
- package/dist/component/_generated/api.d.ts.map +1 -0
- package/dist/component/_generated/api.js +31 -0
- package/dist/component/_generated/api.js.map +1 -0
- package/dist/component/_generated/component.d.ts +253 -0
- package/dist/component/_generated/component.d.ts.map +1 -0
- package/dist/component/_generated/component.js +11 -0
- package/dist/component/_generated/component.js.map +1 -0
- package/dist/component/_generated/dataModel.d.ts +46 -0
- package/dist/component/_generated/dataModel.d.ts.map +1 -0
- package/dist/component/_generated/dataModel.js +11 -0
- package/dist/component/_generated/dataModel.js.map +1 -0
- package/dist/component/_generated/server.d.ts +121 -0
- package/dist/component/_generated/server.d.ts.map +1 -0
- package/dist/component/_generated/server.js +78 -0
- package/dist/component/_generated/server.js.map +1 -0
- package/dist/component/cleanup.d.ts +29 -0
- package/dist/component/cleanup.d.ts.map +1 -0
- package/dist/component/cleanup.js +70 -0
- package/dist/component/cleanup.js.map +1 -0
- package/dist/component/convex.config.d.ts +3 -0
- package/dist/component/convex.config.d.ts.map +1 -0
- package/dist/component/convex.config.js +3 -0
- package/dist/component/convex.config.js.map +1 -0
- package/dist/component/crons.d.ts +3 -0
- package/dist/component/crons.d.ts.map +1 -0
- package/dist/component/crons.js +7 -0
- package/dist/component/crons.js.map +1 -0
- package/dist/component/lib.d.ts +323 -0
- package/dist/component/lib.d.ts.map +1 -0
- package/dist/component/lib.js +659 -0
- package/dist/component/lib.js.map +1 -0
- package/dist/component/schema.d.ts +82 -0
- package/dist/component/schema.d.ts.map +1 -0
- package/dist/component/schema.js +38 -0
- package/dist/component/schema.js.map +1 -0
- package/dist/component/sweep.d.ts +27 -0
- package/dist/component/sweep.d.ts.map +1 -0
- package/dist/component/sweep.js +94 -0
- package/dist/component/sweep.js.map +1 -0
- package/dist/shared.d.ts +11 -0
- package/dist/shared.d.ts.map +1 -0
- package/dist/shared.js +11 -0
- package/dist/shared.js.map +1 -0
- package/package.json +116 -0
- package/src/client/__tests__/contracts.test.ts +109 -0
- package/src/client/__tests__/errors.test.ts +133 -0
- package/src/client/__tests__/hooks.test.ts +154 -0
- package/src/client/__tests__/operations.test.ts +742 -0
- package/src/client/__tests__/setup.test.ts +31 -0
- package/src/client/_generated/_ignore.ts +1 -0
- package/src/client/crypto.ts +64 -0
- package/src/client/errors.ts +67 -0
- package/src/client/index.ts +44 -0
- package/src/client/operations.ts +881 -0
- package/src/client/options.ts +146 -0
- package/src/client/types.ts +313 -0
- package/src/component/__tests__/cleanup.test.ts +472 -0
- package/src/component/__tests__/lib.test.ts +676 -0
- package/src/component/__tests__/setup.test.ts +11 -0
- package/src/component/_generated/api.ts +56 -0
- package/src/component/_generated/component.ts +300 -0
- package/src/component/_generated/dataModel.ts +60 -0
- package/src/component/_generated/server.ts +156 -0
- package/src/component/cleanup.ts +85 -0
- package/src/component/convex.config.ts +3 -0
- package/src/component/crons.ts +20 -0
- package/src/component/lib.ts +843 -0
- package/src/component/schema.ts +49 -0
- package/src/component/sweep.ts +117 -0
- package/src/shared.ts +18 -0
- package/src/test.ts +18 -0
|
@@ -0,0 +1,146 @@
|
|
|
1
|
+
import { optionsError } from "./errors.js";
|
|
2
|
+
import type { ApiKeysTypeOptions } from "./types.js";
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Initialization options for the API keys client.
|
|
6
|
+
*
|
|
7
|
+
* Type-level concerns (namespace shape, metadata shape, permissions shape,
|
|
8
|
+
* requireName) are passed via the generic parameter of `ApiKeys<TOptions>`.
|
|
9
|
+
*/
|
|
10
|
+
export type ApiKeysOptions<
|
|
11
|
+
TOptions extends ApiKeysTypeOptions = Record<never, never>,
|
|
12
|
+
> = {
|
|
13
|
+
/**
|
|
14
|
+
* Default permissions applied when create args do not include permissions.
|
|
15
|
+
*
|
|
16
|
+
* Typed against the `permissions` field of `TOptions` when provided.
|
|
17
|
+
* This is a convenience default — not a runtime allowlist validator.
|
|
18
|
+
*/
|
|
19
|
+
permissionDefaults?: TOptions extends {
|
|
20
|
+
permissions: infer P extends Record<string, string[]>;
|
|
21
|
+
}
|
|
22
|
+
? { [K in keyof P]?: P[K] }
|
|
23
|
+
: Record<string, string[]>;
|
|
24
|
+
/**
|
|
25
|
+
* Default key behavior applied when operation-level values are omitted.
|
|
26
|
+
*/
|
|
27
|
+
keyDefaults?: {
|
|
28
|
+
/**
|
|
29
|
+
* Token prefix used when creating keys.
|
|
30
|
+
*
|
|
31
|
+
* @default "ak_"
|
|
32
|
+
*/
|
|
33
|
+
prefix?: string;
|
|
34
|
+
/**
|
|
35
|
+
* Default absolute expiration in milliseconds.
|
|
36
|
+
*
|
|
37
|
+
* Set `null` for no expiration.
|
|
38
|
+
*
|
|
39
|
+
* @default null
|
|
40
|
+
*/
|
|
41
|
+
ttlMs?: number | null;
|
|
42
|
+
/**
|
|
43
|
+
* Default idle timeout in milliseconds.
|
|
44
|
+
*
|
|
45
|
+
* Set `null` to disable idle expiration.
|
|
46
|
+
*
|
|
47
|
+
* @default null
|
|
48
|
+
*/
|
|
49
|
+
idleTimeoutMs?: number | null;
|
|
50
|
+
};
|
|
51
|
+
/**
|
|
52
|
+
* Minimum log level for console output.
|
|
53
|
+
*
|
|
54
|
+
* - `"debug"` — logs all operations including successes
|
|
55
|
+
* - `"warn"` — logs warnings and errors only (default)
|
|
56
|
+
* - `"error"` — logs infrastructure failures only
|
|
57
|
+
* - `"none"` — disables all logging
|
|
58
|
+
*
|
|
59
|
+
* @default "warn"
|
|
60
|
+
*/
|
|
61
|
+
logLevel?: "debug" | "warn" | "error" | "none";
|
|
62
|
+
};
|
|
63
|
+
|
|
64
|
+
/**
|
|
65
|
+
* Fully validated options shape used by runtime internals.
|
|
66
|
+
*/
|
|
67
|
+
export type NormalizedApiKeysOptions = {
|
|
68
|
+
permissionDefaults: Record<string, string[]> | undefined;
|
|
69
|
+
keyDefaults: {
|
|
70
|
+
prefix: string;
|
|
71
|
+
keyLengthBytes: number;
|
|
72
|
+
ttlMs: number | null;
|
|
73
|
+
idleTimeoutMs: number | null;
|
|
74
|
+
};
|
|
75
|
+
logLevel: "debug" | "warn" | "error" | "none";
|
|
76
|
+
};
|
|
77
|
+
|
|
78
|
+
const KEY_DEFAULTS = {
|
|
79
|
+
prefix: "ak_",
|
|
80
|
+
keyLengthBytes: 32,
|
|
81
|
+
ttlMs: null as number | null,
|
|
82
|
+
idleTimeoutMs: null as number | null,
|
|
83
|
+
};
|
|
84
|
+
|
|
85
|
+
const LOG_LEVELS = ["debug", "warn", "error", "none"] as const;
|
|
86
|
+
|
|
87
|
+
/**
|
|
88
|
+
* Normalize and validate API keys options.
|
|
89
|
+
*
|
|
90
|
+
* @throws {ApiKeysClientError} If any option value is invalid.
|
|
91
|
+
*/
|
|
92
|
+
export function normalizeApiKeysOptions(
|
|
93
|
+
options: ApiKeysOptions<ApiKeysTypeOptions>,
|
|
94
|
+
): NormalizedApiKeysOptions {
|
|
95
|
+
const keyDefaults = {
|
|
96
|
+
prefix: options.keyDefaults?.prefix ?? KEY_DEFAULTS.prefix,
|
|
97
|
+
keyLengthBytes: KEY_DEFAULTS.keyLengthBytes,
|
|
98
|
+
ttlMs: options.keyDefaults?.ttlMs ?? KEY_DEFAULTS.ttlMs,
|
|
99
|
+
idleTimeoutMs:
|
|
100
|
+
options.keyDefaults?.idleTimeoutMs ?? KEY_DEFAULTS.idleTimeoutMs,
|
|
101
|
+
};
|
|
102
|
+
|
|
103
|
+
if (keyDefaults.prefix.length > 32) {
|
|
104
|
+
throw optionsError(`keyDefaults.prefix exceeds max allowed length (32)`);
|
|
105
|
+
}
|
|
106
|
+
if (keyDefaults.prefix.length === 0) {
|
|
107
|
+
throw optionsError("keyDefaults.prefix must not be empty");
|
|
108
|
+
}
|
|
109
|
+
assertNullableNonNegativeInteger(keyDefaults.ttlMs, "keyDefaults.ttlMs");
|
|
110
|
+
assertNullableNonNegativeInteger(
|
|
111
|
+
keyDefaults.idleTimeoutMs,
|
|
112
|
+
"keyDefaults.idleTimeoutMs",
|
|
113
|
+
);
|
|
114
|
+
|
|
115
|
+
const logLevel = normalizeLogLevel(options.logLevel);
|
|
116
|
+
|
|
117
|
+
return {
|
|
118
|
+
permissionDefaults: options.permissionDefaults as
|
|
119
|
+
| Record<string, string[]>
|
|
120
|
+
| undefined,
|
|
121
|
+
keyDefaults,
|
|
122
|
+
logLevel,
|
|
123
|
+
};
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
function normalizeLogLevel(
|
|
127
|
+
level: "debug" | "warn" | "error" | "none" | undefined,
|
|
128
|
+
): "debug" | "warn" | "error" | "none" {
|
|
129
|
+
const resolved = level ?? "warn";
|
|
130
|
+
if (!LOG_LEVELS.includes(resolved)) {
|
|
131
|
+
throw optionsError(`logLevel must be one of: ${LOG_LEVELS.join(", ")}`);
|
|
132
|
+
}
|
|
133
|
+
return resolved;
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
export function assertNullableNonNegativeInteger(
|
|
137
|
+
value: number | null,
|
|
138
|
+
path: string,
|
|
139
|
+
) {
|
|
140
|
+
if (value === null) {
|
|
141
|
+
return;
|
|
142
|
+
}
|
|
143
|
+
if (!Number.isInteger(value) || value < 0) {
|
|
144
|
+
throw optionsError(`${path} must be null or a non-negative integer`);
|
|
145
|
+
}
|
|
146
|
+
}
|
|
@@ -0,0 +1,313 @@
|
|
|
1
|
+
import type {
|
|
2
|
+
FunctionArgs,
|
|
3
|
+
FunctionReference,
|
|
4
|
+
FunctionReturnType,
|
|
5
|
+
FunctionVisibility,
|
|
6
|
+
} from "convex/server";
|
|
7
|
+
import { v, type Infer } from "convex/values";
|
|
8
|
+
import type { ComponentApi } from "../component/_generated/component.js";
|
|
9
|
+
|
|
10
|
+
type CreateMutationResult = FunctionReturnType<ComponentApi["lib"]["create"]>;
|
|
11
|
+
type ValidateQueryResult = FunctionReturnType<ComponentApi["lib"]["validate"]>;
|
|
12
|
+
type RefreshMutationResult = FunctionReturnType<ComponentApi["lib"]["refresh"]>;
|
|
13
|
+
type GetKeyQueryResult = FunctionReturnType<ComponentApi["lib"]["getKey"]>;
|
|
14
|
+
type CleanupExpiredMutationResult = FunctionReturnType<
|
|
15
|
+
ComponentApi["cleanup"]["cleanupExpired"]
|
|
16
|
+
>;
|
|
17
|
+
|
|
18
|
+
/**
|
|
19
|
+
* Type-level options passed as the generic parameter to `ApiKeys`.
|
|
20
|
+
*
|
|
21
|
+
* All fields are TypeScript-only — they are phantom types cast over `v.any()`
|
|
22
|
+
* / `v.string()` storage. You are responsible for keeping your type param
|
|
23
|
+
* consistent with the data already stored in the database.
|
|
24
|
+
*
|
|
25
|
+
* - `namespace` — any `string` subtype (literals, template literals).
|
|
26
|
+
* Presence implies namespace is required in `create` args.
|
|
27
|
+
* - `requireName` — set to `true` to require `name` in `create` args.
|
|
28
|
+
* - `metadata` — shape of the metadata object stored with each key.
|
|
29
|
+
* - `permissions` — shape of the permissions object; values must be `string[]`
|
|
30
|
+
* subtypes (including literal arrays).
|
|
31
|
+
*/
|
|
32
|
+
export type ApiKeysTypeOptions = {
|
|
33
|
+
namespace?: string;
|
|
34
|
+
requireName?: true;
|
|
35
|
+
metadata?: Record<string, unknown>;
|
|
36
|
+
permissions?: Record<string, string[]>;
|
|
37
|
+
};
|
|
38
|
+
|
|
39
|
+
/**
|
|
40
|
+
* Freeform metadata stored with an API key.
|
|
41
|
+
*/
|
|
42
|
+
export type ApiKeyMetadata = Record<string, unknown>;
|
|
43
|
+
|
|
44
|
+
/**
|
|
45
|
+
* Metadata attached to lifecycle events (invalidate, refresh, bulk invalidate).
|
|
46
|
+
*/
|
|
47
|
+
export type ApiKeyEventMetadata = Record<string, unknown>;
|
|
48
|
+
|
|
49
|
+
// --- Internal arg shape helpers ---
|
|
50
|
+
|
|
51
|
+
type NamespaceArg<TOptions extends ApiKeysTypeOptions> = TOptions extends {
|
|
52
|
+
namespace: infer N extends string;
|
|
53
|
+
}
|
|
54
|
+
? { namespace: N }
|
|
55
|
+
: { namespace?: string };
|
|
56
|
+
|
|
57
|
+
type NamespaceFilterArg<TOptions extends ApiKeysTypeOptions> =
|
|
58
|
+
TOptions extends { namespace: infer N extends string }
|
|
59
|
+
? { namespace?: N }
|
|
60
|
+
: object;
|
|
61
|
+
|
|
62
|
+
type NameArg<TOptions extends ApiKeysTypeOptions> = TOptions extends {
|
|
63
|
+
requireName: true;
|
|
64
|
+
}
|
|
65
|
+
? { name: string }
|
|
66
|
+
: { name?: string };
|
|
67
|
+
|
|
68
|
+
type PermissionsInputArg<TOptions extends ApiKeysTypeOptions> =
|
|
69
|
+
TOptions extends { permissions: infer P extends Record<string, string[]> }
|
|
70
|
+
? { permissions?: { [K in keyof P]?: P[K] } }
|
|
71
|
+
: { permissions?: Record<string, string[]> };
|
|
72
|
+
|
|
73
|
+
// --- Internal result shape helpers ---
|
|
74
|
+
|
|
75
|
+
type NamespaceOutput<TOptions extends ApiKeysTypeOptions> = TOptions extends {
|
|
76
|
+
namespace: infer N extends string;
|
|
77
|
+
}
|
|
78
|
+
? N | undefined
|
|
79
|
+
: string | undefined;
|
|
80
|
+
|
|
81
|
+
type MetadataOutput<TOptions extends ApiKeysTypeOptions> = TOptions extends {
|
|
82
|
+
metadata: infer M extends Record<string, unknown>;
|
|
83
|
+
}
|
|
84
|
+
? M | undefined
|
|
85
|
+
: Record<string, unknown> | undefined;
|
|
86
|
+
|
|
87
|
+
type PermissionsOutput<TOptions extends ApiKeysTypeOptions> = TOptions extends {
|
|
88
|
+
permissions: infer P extends Record<string, string[]>;
|
|
89
|
+
}
|
|
90
|
+
? P | undefined
|
|
91
|
+
: Record<string, string[]> | undefined;
|
|
92
|
+
|
|
93
|
+
// --- Public types ---
|
|
94
|
+
|
|
95
|
+
export type ApiKeyId = CreateMutationResult["keyId"];
|
|
96
|
+
|
|
97
|
+
/**
|
|
98
|
+
* Plaintext API key token.
|
|
99
|
+
*
|
|
100
|
+
* Tokens are only available at creation/refresh time.
|
|
101
|
+
*/
|
|
102
|
+
export type ApiKeyToken = string;
|
|
103
|
+
|
|
104
|
+
export type CreateArgs<
|
|
105
|
+
TOptions extends ApiKeysTypeOptions = Record<never, never>,
|
|
106
|
+
> = NamespaceArg<TOptions> &
|
|
107
|
+
NameArg<TOptions> &
|
|
108
|
+
PermissionsInputArg<TOptions> & {
|
|
109
|
+
metadata?: TOptions extends {
|
|
110
|
+
metadata: infer M extends Record<string, unknown>;
|
|
111
|
+
}
|
|
112
|
+
? M
|
|
113
|
+
: ApiKeyMetadata;
|
|
114
|
+
prefix?: string;
|
|
115
|
+
ttlMs?: number | null;
|
|
116
|
+
idleTimeoutMs?: number | null;
|
|
117
|
+
};
|
|
118
|
+
|
|
119
|
+
export type CreateResult = {
|
|
120
|
+
keyId: ApiKeyId;
|
|
121
|
+
token: ApiKeyToken;
|
|
122
|
+
tokenPrefix: string;
|
|
123
|
+
tokenLast4: string;
|
|
124
|
+
createdAt: CreateMutationResult["createdAt"];
|
|
125
|
+
expiresAt?: number;
|
|
126
|
+
};
|
|
127
|
+
|
|
128
|
+
export type ValidateArgs = {
|
|
129
|
+
token: ApiKeyToken;
|
|
130
|
+
};
|
|
131
|
+
|
|
132
|
+
export type TouchArgs = {
|
|
133
|
+
keyId: ApiKeyId;
|
|
134
|
+
};
|
|
135
|
+
|
|
136
|
+
export type TouchResult = FunctionReturnType<ComponentApi["lib"]["touch"]>;
|
|
137
|
+
|
|
138
|
+
export type PaginationOptions = {
|
|
139
|
+
numItems: number;
|
|
140
|
+
cursor: string | null;
|
|
141
|
+
};
|
|
142
|
+
|
|
143
|
+
export type ListKeysArgs<
|
|
144
|
+
TOptions extends ApiKeysTypeOptions = Record<never, never>,
|
|
145
|
+
> = {
|
|
146
|
+
paginationOpts: PaginationOptions;
|
|
147
|
+
status?: "active" | "revoked";
|
|
148
|
+
order?: "asc" | "desc";
|
|
149
|
+
} & NamespaceFilterArg<TOptions>;
|
|
150
|
+
|
|
151
|
+
export type ListKeysResult = FunctionReturnType<
|
|
152
|
+
ComponentApi["lib"]["listKeys"]
|
|
153
|
+
>;
|
|
154
|
+
|
|
155
|
+
export type ListEventsArgs<
|
|
156
|
+
TOptions extends ApiKeysTypeOptions = Record<never, never>,
|
|
157
|
+
> = {
|
|
158
|
+
paginationOpts: PaginationOptions;
|
|
159
|
+
order?: "asc" | "desc";
|
|
160
|
+
} & NamespaceFilterArg<TOptions>;
|
|
161
|
+
|
|
162
|
+
export type ListEventsResult = FunctionReturnType<
|
|
163
|
+
ComponentApi["lib"]["listEvents"]
|
|
164
|
+
>;
|
|
165
|
+
|
|
166
|
+
export type ListKeyEventsArgs = {
|
|
167
|
+
keyId: ApiKeyId;
|
|
168
|
+
paginationOpts: PaginationOptions;
|
|
169
|
+
order?: "asc" | "desc";
|
|
170
|
+
};
|
|
171
|
+
|
|
172
|
+
export type ListKeyEventsResult = FunctionReturnType<
|
|
173
|
+
ComponentApi["lib"]["listKeyEvents"]
|
|
174
|
+
>;
|
|
175
|
+
|
|
176
|
+
export type GetKeyArgs = {
|
|
177
|
+
keyId: ApiKeyId;
|
|
178
|
+
};
|
|
179
|
+
|
|
180
|
+
export type GetKeyResult = GetKeyQueryResult;
|
|
181
|
+
|
|
182
|
+
export type InvalidateArgs = {
|
|
183
|
+
keyId: ApiKeyId;
|
|
184
|
+
reason?: string;
|
|
185
|
+
metadata?: ApiKeyEventMetadata;
|
|
186
|
+
};
|
|
187
|
+
|
|
188
|
+
export type InvalidateResult = FunctionReturnType<
|
|
189
|
+
ComponentApi["lib"]["invalidate"]
|
|
190
|
+
>;
|
|
191
|
+
|
|
192
|
+
export type InvalidateAllArgs<
|
|
193
|
+
TOptions extends ApiKeysTypeOptions = Record<never, never>,
|
|
194
|
+
> = {
|
|
195
|
+
before?: number;
|
|
196
|
+
after?: number;
|
|
197
|
+
reason?: string;
|
|
198
|
+
metadata?: ApiKeyEventMetadata;
|
|
199
|
+
pageSize?: number;
|
|
200
|
+
} & NamespaceFilterArg<TOptions>;
|
|
201
|
+
|
|
202
|
+
export type InvalidateAllResult = {
|
|
203
|
+
processed: number;
|
|
204
|
+
revoked: number;
|
|
205
|
+
pages: number;
|
|
206
|
+
};
|
|
207
|
+
|
|
208
|
+
export type InvalidateAllPageResult = FunctionReturnType<
|
|
209
|
+
ComponentApi["lib"]["invalidateAll"]
|
|
210
|
+
>;
|
|
211
|
+
|
|
212
|
+
export const onInvalidateHookPayloadValidator = v.union(
|
|
213
|
+
v.object({
|
|
214
|
+
trigger: v.literal("invalidate"),
|
|
215
|
+
at: v.number(),
|
|
216
|
+
keyId: v.string(),
|
|
217
|
+
reason: v.optional(v.string()),
|
|
218
|
+
}),
|
|
219
|
+
v.object({
|
|
220
|
+
trigger: v.literal("refresh"),
|
|
221
|
+
at: v.number(),
|
|
222
|
+
keyId: v.string(),
|
|
223
|
+
replacementKeyId: v.string(),
|
|
224
|
+
reason: v.optional(v.string()),
|
|
225
|
+
}),
|
|
226
|
+
v.object({
|
|
227
|
+
trigger: v.literal("invalidateAll"),
|
|
228
|
+
at: v.number(),
|
|
229
|
+
namespace: v.optional(v.string()),
|
|
230
|
+
before: v.optional(v.number()),
|
|
231
|
+
after: v.optional(v.number()),
|
|
232
|
+
reason: v.optional(v.string()),
|
|
233
|
+
processed: v.number(),
|
|
234
|
+
revoked: v.number(),
|
|
235
|
+
pages: v.number(),
|
|
236
|
+
}),
|
|
237
|
+
);
|
|
238
|
+
|
|
239
|
+
export type OnInvalidateHookPayload = Infer<
|
|
240
|
+
typeof onInvalidateHookPayloadValidator
|
|
241
|
+
>;
|
|
242
|
+
|
|
243
|
+
export type UpdateArgs = {
|
|
244
|
+
keyId: ApiKeyId;
|
|
245
|
+
name?: string;
|
|
246
|
+
metadata?: ApiKeyMetadata;
|
|
247
|
+
/** Pass `null` to remove the expiry entirely. */
|
|
248
|
+
expiresAt?: number | null;
|
|
249
|
+
/** Pass `null` to remove the idle timeout entirely. */
|
|
250
|
+
maxIdleMs?: number | null;
|
|
251
|
+
};
|
|
252
|
+
|
|
253
|
+
export type UpdateResult = FunctionReturnType<ComponentApi["lib"]["update"]>;
|
|
254
|
+
|
|
255
|
+
export type CleanupExpiredArgs = {
|
|
256
|
+
/**
|
|
257
|
+
* How long to retain revoked keys before hard-deleting them and their
|
|
258
|
+
* audit events. Must be a positive finite number.
|
|
259
|
+
*
|
|
260
|
+
* @default 30 days
|
|
261
|
+
*/
|
|
262
|
+
retentionMs?: number;
|
|
263
|
+
};
|
|
264
|
+
|
|
265
|
+
export type CleanupExpiredResult = CleanupExpiredMutationResult;
|
|
266
|
+
|
|
267
|
+
export type RefreshArgs = {
|
|
268
|
+
keyId: ApiKeyId;
|
|
269
|
+
/** Override the token prefix for the new key. Falls back to `keyDefaults.prefix`. */
|
|
270
|
+
prefix?: string;
|
|
271
|
+
reason?: string;
|
|
272
|
+
metadata?: ApiKeyEventMetadata;
|
|
273
|
+
};
|
|
274
|
+
|
|
275
|
+
type RefreshMutationSuccess = Extract<RefreshMutationResult, { ok: true }>;
|
|
276
|
+
type RefreshMutationFailure = Extract<RefreshMutationResult, { ok: false }>;
|
|
277
|
+
|
|
278
|
+
export type RefreshResult =
|
|
279
|
+
| (RefreshMutationSuccess & {
|
|
280
|
+
token: ApiKeyToken;
|
|
281
|
+
tokenPrefix: string;
|
|
282
|
+
tokenLast4: string;
|
|
283
|
+
})
|
|
284
|
+
| RefreshMutationFailure;
|
|
285
|
+
|
|
286
|
+
type ValidateSuccessBase = Extract<ValidateQueryResult, { ok: true }>;
|
|
287
|
+
type ValidateFailure = Extract<ValidateQueryResult, { ok: false }>;
|
|
288
|
+
|
|
289
|
+
export type ValidateResult<
|
|
290
|
+
TOptions extends ApiKeysTypeOptions = Record<never, never>,
|
|
291
|
+
> =
|
|
292
|
+
| (Omit<ValidateSuccessBase, "permissions" | "namespace" | "metadata"> & {
|
|
293
|
+
namespace: NamespaceOutput<TOptions>;
|
|
294
|
+
permissions: PermissionsOutput<TOptions>;
|
|
295
|
+
metadata: MetadataOutput<TOptions>;
|
|
296
|
+
})
|
|
297
|
+
| ValidateFailure;
|
|
298
|
+
|
|
299
|
+
export type RunMutationCtx = {
|
|
300
|
+
runMutation: <
|
|
301
|
+
Mutation extends FunctionReference<"mutation", FunctionVisibility>,
|
|
302
|
+
>(
|
|
303
|
+
mutation: Mutation,
|
|
304
|
+
args: FunctionArgs<Mutation>,
|
|
305
|
+
) => Promise<FunctionReturnType<Mutation>>;
|
|
306
|
+
};
|
|
307
|
+
|
|
308
|
+
export type RunQueryCtx = {
|
|
309
|
+
runQuery: <Query extends FunctionReference<"query", "internal">>(
|
|
310
|
+
query: Query,
|
|
311
|
+
args: FunctionArgs<Query>,
|
|
312
|
+
) => Promise<FunctionReturnType<Query>>;
|
|
313
|
+
};
|