safebyok-convex 0.0.0 → 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/README.md +32 -13
- package/dist/_virtual/_rolldown/runtime.js +13 -0
- package/dist/component/_generated/api.d.ts +7 -0
- package/dist/component/_generated/api.js +9 -0
- package/dist/component/_generated/api.js.map +1 -0
- package/dist/component/_generated/dataModel.d.ts +40 -0
- package/dist/component/_generated/dataModel.js +0 -0
- package/dist/component/_generated/server.d.ts +127 -0
- package/dist/component/_generated/server.js +74 -0
- package/dist/component/_generated/server.js.map +1 -0
- package/dist/component/convex.config.d.ts +16 -0
- package/dist/component/convex.config.js +18 -0
- package/dist/component/convex.config.js.map +1 -0
- package/dist/component/schema.d.ts +98 -0
- package/dist/component/schema.js +31 -0
- package/dist/component/schema.js.map +1 -0
- package/dist/component/validators.d.ts +196 -0
- package/dist/component/validators.js +118 -0
- package/dist/component/validators.js.map +1 -0
- package/dist/component/vaults.d.ts +225 -0
- package/dist/component/vaults.js +189 -0
- package/dist/component/vaults.js.map +1 -0
- package/dist/component-api.d.ts +20 -0
- package/dist/component-api.js +0 -0
- package/dist/convex-vault-db.d.ts +56 -0
- package/dist/convex-vault-db.js +170 -0
- package/dist/convex-vault-db.js.map +1 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.js +1 -0
- package/dist/refusals.d.ts +18 -0
- package/dist/refusals.js +16 -0
- package/dist/refusals.js.map +1 -0
- package/dist/server.d.ts +231 -0
- package/dist/server.js +147 -0
- package/dist/server.js.map +1 -0
- package/package.json +68 -16
- package/src/component/validators.ts +4 -1
- package/src/component/vaults.ts +3 -3
- package/src/convex-vault-db.ts +30 -4
- package/src/server.ts +20 -12
- package/src/test.ts +1 -1
- package/.claude/skills/LICENSE-convex-agent-skills +0 -201
- package/.claude/skills/README.md +0 -115
- package/.claude/skills/convex-create-component/SKILL.md +0 -330
- package/.claude/skills/convex-create-component/references/advanced-patterns.md +0 -152
- package/.claude/skills/convex-create-component/references/packaged-components.md +0 -61
- package/.claude/skills/convex-docs/SKILL.md +0 -31
- package/.claude/skills/convex-expert/SKILL.md +0 -42
- package/.claude/skills/convex-reviewer/SKILL.md +0 -32
- package/.claude/skills/convex-test/SKILL.md +0 -23
- package/.claude/skills/convex-verify/SKILL.md +0 -40
- package/eslint.config.mjs +0 -85
- package/tests/component/validators.test.ts +0 -160
- package/tests/component/vaults.test.ts +0 -351
- package/tests/convex-vault-db.test.ts +0 -332
- package/tests/fake-deployment.ts +0 -229
- package/tests/helpers.ts +0 -102
- package/tests/refusals.test.ts +0 -25
- package/tests/server.test.ts +0 -139
- package/tests/test.test.ts +0 -25
- package/tsconfig.json +0 -33
- package/vitest.config.ts +0 -17
package/README.md
CHANGED
|
@@ -5,8 +5,14 @@ bundle and lockboxes, ciphertext and public fields only, in tables of its own, a
|
|
|
5
5
|
**`convexVaultDB`**, the client side a vault stores through. Your Convex backend never sees a
|
|
6
6
|
whisper, a passphrase, or any key that opens one.
|
|
7
7
|
|
|
8
|
-
|
|
9
|
-
|
|
8
|
+
## Install
|
|
9
|
+
|
|
10
|
+
```sh
|
|
11
|
+
pnpm add safebyok safebyok-convex convex
|
|
12
|
+
```
|
|
13
|
+
|
|
14
|
+
`safebyok` and `convex` are peer dependencies: your app installs them itself, so the adapter and
|
|
15
|
+
your app share one copy of each, and a `VaultError` from one is a `VaultError` to the other.
|
|
10
16
|
|
|
11
17
|
## What your app adds to its `convex/` directory
|
|
12
18
|
|
|
@@ -58,7 +64,7 @@ has. Hand it to `openVault`:
|
|
|
58
64
|
```ts
|
|
59
65
|
import { ConvexClient } from 'convex/browser'
|
|
60
66
|
import { openVault } from 'safebyok'
|
|
61
|
-
import {
|
|
67
|
+
import { browserOpts } from 'safebyok/browser'
|
|
62
68
|
import { convexVaultDB } from 'safebyok-convex'
|
|
63
69
|
import { api } from '../convex/_generated/api'
|
|
64
70
|
|
|
@@ -68,7 +74,7 @@ convex.setAuth(fetchToken) // your auth provider's token, as for any Convex call
|
|
|
68
74
|
const vault = await openVault({
|
|
69
75
|
applabel: 'acme', userId, vaultlabel: 'main',
|
|
70
76
|
vaultDB: convexVaultDB(convex, api.safebyok),
|
|
71
|
-
|
|
77
|
+
...browserOpts(), // the key deriver and device store a browser wants
|
|
72
78
|
})
|
|
73
79
|
```
|
|
74
80
|
|
|
@@ -91,7 +97,8 @@ socket and its signed-in user. `safebyok-convex` itself imports nothing of React
|
|
|
91
97
|
Convex resends a mutation when it reconnects, so a write may land after any timeout you set:
|
|
92
98
|
show progress, but don't report it failed.
|
|
93
99
|
* A record holds at most 1 MiB, Convex's document limit; `openVault` keeps `maxWhisperBytes`
|
|
94
|
-
under half of it.
|
|
100
|
+
under half of it. A vault holds at most 8 MiB in all (`maxVaultBytes`; see *How big a vault
|
|
101
|
+
can be*).
|
|
95
102
|
|
|
96
103
|
## What is stored
|
|
97
104
|
|
|
@@ -113,10 +120,14 @@ Two tables, inside the component, beside nothing of your app's:
|
|
|
113
120
|
* `user_id` leads both indexes, so one user's rows are one range of each.
|
|
114
121
|
|
|
115
122
|
**How big a vault can be.** Listing a vault, watching it and erasing it each read the whole vault
|
|
116
|
-
in one Convex transaction, which may read 16 MiB; erasing reads it twice
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
123
|
+
in one Convex transaction, which may read 16 MiB; erasing reads it twice, so `convexVaultDB`
|
|
124
|
+
declares a `maxVaultBytes` of 8 MiB. A vault holds 100 lockboxes by default, raised with
|
|
125
|
+
`maxLockboxes` as far as `maxVaultBytes` allows: `openVault` refuses, with kind `bad_option`, a
|
|
126
|
+
`maxLockboxes` whose lockboxes at `maxWhisperBytes` each might not fit, and its message says how
|
|
127
|
+
many would. At the default `maxWhisperBytes` (40444) that is at most 101; at a `maxWhisperBytes`
|
|
128
|
+
of 2048, ample for API keys, it is 1365. A store past the limit is refused with kind
|
|
129
|
+
`vault_full`, until a lockbox is erased. Each record must also fit Convex's 1 MiB document limit,
|
|
130
|
+
which the core's `maxWhisperBytes` keeps well inside.
|
|
120
131
|
|
|
121
132
|
## The functions
|
|
122
133
|
|
|
@@ -152,10 +163,12 @@ register(t)
|
|
|
152
163
|
|
|
153
164
|
## Developing this package
|
|
154
165
|
|
|
155
|
-
`pnpm justify` here runs its lint, typecheck
|
|
156
|
-
in memory, with no deployment. The
|
|
157
|
-
|
|
158
|
-
|
|
166
|
+
`pnpm justify` here runs its lint, typecheck, tests -- `convex-test` under the edge runtime,
|
|
167
|
+
in memory, with no deployment -- and the build with its publint and arethetypeswrong checks. The typecheck and lint read `safebyok` from its source, through
|
|
168
|
+
the workspace's `@safebyok/source` export condition, so they need no build. The tests resolve it
|
|
169
|
+
through its built `dist/`, as a consumer's would, and make real vaults with the core's own code;
|
|
170
|
+
they build the core first by themselves (`pnpm build:deps`), so a fresh clone needs no prebuild
|
|
171
|
+
step.
|
|
159
172
|
|
|
160
173
|
The client's tests run the real `ConvexClient` and `ConvexReactClient` against
|
|
161
174
|
`tests/fake-deployment.ts`: a fake WebSocket that answers the sync protocol's query and mutation
|
|
@@ -163,6 +176,12 @@ messages from `convex-test`. It runs one call at a time, reruns every watched qu
|
|
|
163
176
|
mutation, and signs each socket in as one user from the start; its doc block says what that
|
|
164
177
|
cannot prove.
|
|
165
178
|
|
|
179
|
+
The build follows Convex's component template: ESM only, unbundled, so each of the component's
|
|
180
|
+
modules keeps its own file under `dist/component/`, beside its `convex.config.js` and
|
|
181
|
+
`_generated/`, for a host's Convex CLI to bundle at deploy. `safebyok-convex/test` alone ships as
|
|
182
|
+
source, `src/test.ts`, since its `import.meta.glob` must find the component's `.ts` modules; a
|
|
183
|
+
test runner that resolves as a bundler does (vitest) loads it.
|
|
184
|
+
|
|
166
185
|
`src/component/_generated/` holds Convex's codegen output for the component, written by the
|
|
167
186
|
templates of the installed `convex` and never edited by hand. Codegen for a component needs a
|
|
168
187
|
Convex deployment, so until one has run it holds only the files Convex writes without one
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
//#region \0rolldown/runtime.js
|
|
2
|
+
var __defProp = Object.defineProperty;
|
|
3
|
+
var __exportAll = (all, no_symbols) => {
|
|
4
|
+
let target = {};
|
|
5
|
+
for (var name in all) __defProp(target, name, {
|
|
6
|
+
get: all[name],
|
|
7
|
+
enumerable: true
|
|
8
|
+
});
|
|
9
|
+
if (!no_symbols) __defProp(target, Symbol.toStringTag, { value: "Module" });
|
|
10
|
+
return target;
|
|
11
|
+
};
|
|
12
|
+
//#endregion
|
|
13
|
+
export { __exportAll };
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import { AnyApi, AnyComponents } from "convex/server";
|
|
2
|
+
//#region src/component/_generated/api.d.ts
|
|
3
|
+
export declare const api: AnyApi;
|
|
4
|
+
export declare const internal: AnyApi;
|
|
5
|
+
export declare const components: AnyComponents;
|
|
6
|
+
//#endregion
|
|
7
|
+
//# sourceMappingURL=api.d.ts.map
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { anyApi, componentsGeneric } from "convex/server";
|
|
2
|
+
//#region src/component/_generated/api.ts
|
|
3
|
+
const api = anyApi;
|
|
4
|
+
const internal = anyApi;
|
|
5
|
+
const components = componentsGeneric();
|
|
6
|
+
//#endregion
|
|
7
|
+
export { api, components, internal };
|
|
8
|
+
|
|
9
|
+
//# sourceMappingURL=api.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"api.js","names":[],"sources":["../../../src/component/_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 { AnyApi, AnyComponents } from \"convex/server\";\nimport { anyApi, componentsGeneric } from \"convex/server\";\n\nexport const api: AnyApi = anyApi;\nexport const internal: AnyApi = anyApi;\nexport const components: AnyComponents = componentsGeneric();\n"],"mappings":";;AAaA,MAAa,MAAc;AAC3B,MAAa,WAAmB;AAChC,MAAa,aAA4B,kBAAkB"}
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import _default from "../schema.js";
|
|
2
|
+
import { DataModelFromSchemaDefinition, DocumentByName, SystemTableNames, TableNamesInDataModel } from "convex/server";
|
|
3
|
+
import { GenericId } from "convex/values";
|
|
4
|
+
//#region src/component/_generated/dataModel.d.ts
|
|
5
|
+
/**
|
|
6
|
+
* The names of all of your Convex tables.
|
|
7
|
+
*/
|
|
8
|
+
export type TableNames = TableNamesInDataModel<DataModel>;
|
|
9
|
+
/**
|
|
10
|
+
* The type of a document stored in Convex.
|
|
11
|
+
*
|
|
12
|
+
* @typeParam TableName - A string literal type of the table name (like "users").
|
|
13
|
+
*/
|
|
14
|
+
export type Doc<TableName extends TableNames> = DocumentByName<DataModel, TableName>;
|
|
15
|
+
/**
|
|
16
|
+
* An identifier for a document in Convex.
|
|
17
|
+
*
|
|
18
|
+
* Convex documents are uniquely identified by their `Id`, which is accessible
|
|
19
|
+
* on the `_id` field. To learn more, see [Document IDs](https://docs.convex.dev/using/document-ids).
|
|
20
|
+
*
|
|
21
|
+
* Documents can be loaded using `db.get(tableName, id)` in query and mutation functions.
|
|
22
|
+
*
|
|
23
|
+
* IDs are just strings at runtime, but this type can be used to distinguish them from other
|
|
24
|
+
* strings when type checking.
|
|
25
|
+
*
|
|
26
|
+
* @typeParam TableName - A string literal type of the table name (like "users").
|
|
27
|
+
*/
|
|
28
|
+
export type Id<TableName extends TableNames | SystemTableNames> = GenericId<TableName>;
|
|
29
|
+
/**
|
|
30
|
+
* A type describing your Convex data model.
|
|
31
|
+
*
|
|
32
|
+
* This type includes information about what tables you have, the type of
|
|
33
|
+
* documents stored in those tables, and the indexes defined on them.
|
|
34
|
+
*
|
|
35
|
+
* This type is used to parameterize methods like `queryGeneric` and
|
|
36
|
+
* `mutationGeneric` to make them type-safe.
|
|
37
|
+
*/
|
|
38
|
+
export type DataModel = DataModelFromSchemaDefinition<typeof _default>;
|
|
39
|
+
//#endregion
|
|
40
|
+
//# sourceMappingURL=dataModel.d.ts.map
|
|
File without changes
|
|
@@ -0,0 +1,127 @@
|
|
|
1
|
+
import { DataModel } from "./dataModel.js";
|
|
2
|
+
import { ActionBuilder, GenericActionCtx, GenericDatabaseReader, GenericDatabaseWriter, GenericMutationCtx, GenericQueryCtx, HttpActionBuilder, MutationBuilder, QueryBuilder } from "convex/server";
|
|
3
|
+
//#region src/component/_generated/server.d.ts
|
|
4
|
+
/**
|
|
5
|
+
* Typesafe environment variables.
|
|
6
|
+
*
|
|
7
|
+
* This includes platform-provided env vars and any variables declared in
|
|
8
|
+
* `convex.config.ts`.
|
|
9
|
+
*/
|
|
10
|
+
type Env = {
|
|
11
|
+
readonly CONVEX_CLOUD_URL: string;
|
|
12
|
+
readonly CONVEX_SITE_URL: string;
|
|
13
|
+
};
|
|
14
|
+
/**
|
|
15
|
+
* Define a query in this Convex app's public API.
|
|
16
|
+
*
|
|
17
|
+
* This function will be allowed to read your Convex database and will be accessible from the client.
|
|
18
|
+
*
|
|
19
|
+
* @param func - The query function. It receives a {@link QueryCtx} as its first argument.
|
|
20
|
+
* @returns The wrapped query. Include this as an `export` to name it and make it accessible.
|
|
21
|
+
*/
|
|
22
|
+
export declare const query: QueryBuilder<DataModel, "public">;
|
|
23
|
+
/**
|
|
24
|
+
* Define a query that is only accessible from other Convex functions (but not from the client).
|
|
25
|
+
*
|
|
26
|
+
* This function will be allowed to read from your Convex database. It will not be accessible from the client.
|
|
27
|
+
*
|
|
28
|
+
* @param func - The query function. It receives a {@link QueryCtx} as its first argument.
|
|
29
|
+
* @returns The wrapped query. Include this as an `export` to name it and make it accessible.
|
|
30
|
+
*/
|
|
31
|
+
export declare const internalQuery: QueryBuilder<DataModel, "internal">;
|
|
32
|
+
/**
|
|
33
|
+
* Define a mutation in this Convex app's public API.
|
|
34
|
+
*
|
|
35
|
+
* This function will be allowed to modify your Convex database and will be accessible from the client.
|
|
36
|
+
*
|
|
37
|
+
* @param func - The mutation function. It receives a {@link MutationCtx} as its first argument.
|
|
38
|
+
* @returns The wrapped mutation. Include this as an `export` to name it and make it accessible.
|
|
39
|
+
*/
|
|
40
|
+
export declare const mutation: MutationBuilder<DataModel, "public">;
|
|
41
|
+
/**
|
|
42
|
+
* Define a mutation that is only accessible from other Convex functions (but not from the client).
|
|
43
|
+
*
|
|
44
|
+
* This function will be allowed to modify your Convex database. It will not be accessible from the client.
|
|
45
|
+
*
|
|
46
|
+
* @param func - The mutation function. It receives a {@link MutationCtx} as its first argument.
|
|
47
|
+
* @returns The wrapped mutation. Include this as an `export` to name it and make it accessible.
|
|
48
|
+
*/
|
|
49
|
+
export declare const internalMutation: MutationBuilder<DataModel, "internal">;
|
|
50
|
+
/**
|
|
51
|
+
* Define an action in this Convex app's public API.
|
|
52
|
+
*
|
|
53
|
+
* An action is a function which can execute any JavaScript code, including non-deterministic
|
|
54
|
+
* code and code with side-effects, like calling third-party services.
|
|
55
|
+
* They can be run in Convex's JavaScript environment or in Node.js using the "use node" directive.
|
|
56
|
+
* They can interact with the database indirectly by calling queries and mutations using the {@link ActionCtx}.
|
|
57
|
+
*
|
|
58
|
+
* @param func - The action. It receives an {@link ActionCtx} as its first argument.
|
|
59
|
+
* @returns The wrapped action. Include this as an `export` to name it and make it accessible.
|
|
60
|
+
*/
|
|
61
|
+
export declare const action: ActionBuilder<DataModel, "public">;
|
|
62
|
+
/**
|
|
63
|
+
* Define an action that is only accessible from other Convex functions (but not from the client).
|
|
64
|
+
*
|
|
65
|
+
* @param func - The function. It receives an {@link ActionCtx} as its first argument.
|
|
66
|
+
* @returns The wrapped function. Include this as an `export` to name it and make it accessible.
|
|
67
|
+
*/
|
|
68
|
+
export declare const internalAction: ActionBuilder<DataModel, "internal">;
|
|
69
|
+
/**
|
|
70
|
+
* Define an HTTP action.
|
|
71
|
+
*
|
|
72
|
+
* The wrapped function will be used to respond to HTTP requests received
|
|
73
|
+
* by a Convex deployment if the requests matches the path and method where
|
|
74
|
+
* this action is routed. Be sure to route your httpAction in `convex/http.js`.
|
|
75
|
+
*
|
|
76
|
+
* @param func - The function. It receives an {@link ActionCtx} as its first argument
|
|
77
|
+
* and a Fetch API `Request` object as its second.
|
|
78
|
+
* @returns The wrapped function. Import this function from `convex/http.js` and route it to hook it up.
|
|
79
|
+
*/
|
|
80
|
+
export declare const httpAction: HttpActionBuilder;
|
|
81
|
+
export declare const env: Env;
|
|
82
|
+
/**
|
|
83
|
+
* A set of services for use within Convex query functions.
|
|
84
|
+
*
|
|
85
|
+
* The query context is passed as the first argument to any Convex query
|
|
86
|
+
* function run on the server.
|
|
87
|
+
*
|
|
88
|
+
* If you're using code generation, use the `QueryCtx` type in `convex/_generated/server.d.ts` instead.
|
|
89
|
+
*/
|
|
90
|
+
export type QueryCtx = GenericQueryCtx<DataModel>;
|
|
91
|
+
/**
|
|
92
|
+
* A set of services for use within Convex mutation functions.
|
|
93
|
+
*
|
|
94
|
+
* The mutation context is passed as the first argument to any Convex mutation
|
|
95
|
+
* function run on the server.
|
|
96
|
+
*
|
|
97
|
+
* If you're using code generation, use the `MutationCtx` type in `convex/_generated/server.d.ts` instead.
|
|
98
|
+
*/
|
|
99
|
+
export type MutationCtx = GenericMutationCtx<DataModel>;
|
|
100
|
+
/**
|
|
101
|
+
* A set of services for use within Convex action functions.
|
|
102
|
+
*
|
|
103
|
+
* The action context is passed as the first argument to any Convex action
|
|
104
|
+
* function run on the server.
|
|
105
|
+
*/
|
|
106
|
+
export type ActionCtx = GenericActionCtx<DataModel>;
|
|
107
|
+
/**
|
|
108
|
+
* An interface to read from the database within Convex query functions.
|
|
109
|
+
*
|
|
110
|
+
* The two entry points are {@link DatabaseReader.get}, which fetches a single
|
|
111
|
+
* document by its {@link Id}, or {@link DatabaseReader.query}, which starts
|
|
112
|
+
* building a query.
|
|
113
|
+
*/
|
|
114
|
+
export type DatabaseReader = GenericDatabaseReader<DataModel>;
|
|
115
|
+
/**
|
|
116
|
+
* An interface to read from and write to the database within Convex mutation
|
|
117
|
+
* functions.
|
|
118
|
+
*
|
|
119
|
+
* Convex guarantees that all writes within a single mutation are
|
|
120
|
+
* executed atomically, so you never have to worry about partial writes leaving
|
|
121
|
+
* your data in an inconsistent state. See [the Convex Guide](https://docs.convex.dev/understanding/convex-fundamentals/functions#atomicity-and-optimistic-concurrency-control)
|
|
122
|
+
* for the guarantees Convex provides your functions.
|
|
123
|
+
*/
|
|
124
|
+
export type DatabaseWriter = GenericDatabaseWriter<DataModel>;
|
|
125
|
+
//#endregion
|
|
126
|
+
export {};
|
|
127
|
+
//# sourceMappingURL=server.d.ts.map
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
import { actionGeneric, httpActionGeneric, internalActionGeneric, internalMutationGeneric, internalQueryGeneric, mutationGeneric, queryGeneric } from "convex/server";
|
|
2
|
+
//#region src/component/_generated/server.ts
|
|
3
|
+
/**
|
|
4
|
+
* Define a query in this Convex app's public API.
|
|
5
|
+
*
|
|
6
|
+
* This function will be allowed to read your Convex database and will be accessible from the client.
|
|
7
|
+
*
|
|
8
|
+
* @param func - The query function. It receives a {@link QueryCtx} as its first argument.
|
|
9
|
+
* @returns The wrapped query. Include this as an `export` to name it and make it accessible.
|
|
10
|
+
*/
|
|
11
|
+
const query = queryGeneric;
|
|
12
|
+
/**
|
|
13
|
+
* Define a query that is only accessible from other Convex functions (but not from the client).
|
|
14
|
+
*
|
|
15
|
+
* This function will be allowed to read from your Convex database. It will not be accessible from the client.
|
|
16
|
+
*
|
|
17
|
+
* @param func - The query function. It receives a {@link QueryCtx} as its first argument.
|
|
18
|
+
* @returns The wrapped query. Include this as an `export` to name it and make it accessible.
|
|
19
|
+
*/
|
|
20
|
+
const internalQuery = internalQueryGeneric;
|
|
21
|
+
/**
|
|
22
|
+
* Define a mutation in this Convex app's public API.
|
|
23
|
+
*
|
|
24
|
+
* This function will be allowed to modify your Convex database and will be accessible from the client.
|
|
25
|
+
*
|
|
26
|
+
* @param func - The mutation function. It receives a {@link MutationCtx} as its first argument.
|
|
27
|
+
* @returns The wrapped mutation. Include this as an `export` to name it and make it accessible.
|
|
28
|
+
*/
|
|
29
|
+
const mutation = mutationGeneric;
|
|
30
|
+
/**
|
|
31
|
+
* Define a mutation that is only accessible from other Convex functions (but not from the client).
|
|
32
|
+
*
|
|
33
|
+
* This function will be allowed to modify your Convex database. It will not be accessible from the client.
|
|
34
|
+
*
|
|
35
|
+
* @param func - The mutation function. It receives a {@link MutationCtx} as its first argument.
|
|
36
|
+
* @returns The wrapped mutation. Include this as an `export` to name it and make it accessible.
|
|
37
|
+
*/
|
|
38
|
+
const internalMutation = internalMutationGeneric;
|
|
39
|
+
/**
|
|
40
|
+
* Define an action in this Convex app's public API.
|
|
41
|
+
*
|
|
42
|
+
* An action is a function which can execute any JavaScript code, including non-deterministic
|
|
43
|
+
* code and code with side-effects, like calling third-party services.
|
|
44
|
+
* They can be run in Convex's JavaScript environment or in Node.js using the "use node" directive.
|
|
45
|
+
* They can interact with the database indirectly by calling queries and mutations using the {@link ActionCtx}.
|
|
46
|
+
*
|
|
47
|
+
* @param func - The action. It receives an {@link ActionCtx} as its first argument.
|
|
48
|
+
* @returns The wrapped action. Include this as an `export` to name it and make it accessible.
|
|
49
|
+
*/
|
|
50
|
+
const action = actionGeneric;
|
|
51
|
+
/**
|
|
52
|
+
* Define an action that is only accessible from other Convex functions (but not from the client).
|
|
53
|
+
*
|
|
54
|
+
* @param func - The function. It receives an {@link ActionCtx} as its first argument.
|
|
55
|
+
* @returns The wrapped function. Include this as an `export` to name it and make it accessible.
|
|
56
|
+
*/
|
|
57
|
+
const internalAction = internalActionGeneric;
|
|
58
|
+
/**
|
|
59
|
+
* Define an HTTP action.
|
|
60
|
+
*
|
|
61
|
+
* The wrapped function will be used to respond to HTTP requests received
|
|
62
|
+
* by a Convex deployment if the requests matches the path and method where
|
|
63
|
+
* this action is routed. Be sure to route your httpAction in `convex/http.js`.
|
|
64
|
+
*
|
|
65
|
+
* @param func - The function. It receives an {@link ActionCtx} as its first argument
|
|
66
|
+
* and a Fetch API `Request` object as its second.
|
|
67
|
+
* @returns The wrapped function. Import this function from `convex/http.js` and route it to hook it up.
|
|
68
|
+
*/
|
|
69
|
+
const httpAction = httpActionGeneric;
|
|
70
|
+
const env = globalThis.process.env;
|
|
71
|
+
//#endregion
|
|
72
|
+
export { action, env, httpAction, internalAction, internalMutation, internalQuery, mutation, query };
|
|
73
|
+
|
|
74
|
+
//# sourceMappingURL=server.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"server.js","names":[],"sources":["../../../src/component/_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 * Typesafe environment variables.\n *\n * This includes platform-provided env vars and any variables declared in\n * `convex.config.ts`.\n */\ntype Env = {\n readonly CONVEX_CLOUD_URL: string;\n readonly CONVEX_SITE_URL: string;\n};\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;\nexport const env: Env = (globalThis as unknown as { process: { env: Env } })\n .process.env;\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":";;;;;;;;;;AAmDA,MAAa,QAA2C;;;;;;;;;AAUxD,MAAa,gBACX;;;;;;;;;AAUF,MAAa,WAAiD;;;;;;;;;AAU9D,MAAa,mBACX;;;;;;;;;;;;AAaF,MAAa,SAA6C;;;;;;;AAQ1D,MAAa,iBACX;;;;;;;;;;;;AAaF,MAAa,aAAgC;AAC7C,MAAa,MAAY,WACtB,QAAQ"}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
//#region src/component/convex.config.d.ts
|
|
2
|
+
/**
|
|
3
|
+
* The safebyok component, as a host app installs it from its `convex/convex.config.ts`:
|
|
4
|
+
*
|
|
5
|
+
* @example
|
|
6
|
+
* import { defineApp } from 'convex/server'
|
|
7
|
+
* import safebyok from 'safebyok-convex/convex.config'
|
|
8
|
+
*
|
|
9
|
+
* const app = defineApp()
|
|
10
|
+
* app.use(safebyok)
|
|
11
|
+
* export default app
|
|
12
|
+
*/
|
|
13
|
+
declare const _default: import("convex/server").ComponentDefinition<any, {}>;
|
|
14
|
+
//#endregion
|
|
15
|
+
export { _default as default };
|
|
16
|
+
//# sourceMappingURL=convex.config.d.ts.map
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { defineComponent } from "convex/server";
|
|
2
|
+
//#region src/component/convex.config.ts
|
|
3
|
+
/**
|
|
4
|
+
* The safebyok component, as a host app installs it from its `convex/convex.config.ts`:
|
|
5
|
+
*
|
|
6
|
+
* @example
|
|
7
|
+
* import { defineApp } from 'convex/server'
|
|
8
|
+
* import safebyok from 'safebyok-convex/convex.config'
|
|
9
|
+
*
|
|
10
|
+
* const app = defineApp()
|
|
11
|
+
* app.use(safebyok)
|
|
12
|
+
* export default app
|
|
13
|
+
*/
|
|
14
|
+
var convex_config_default = defineComponent("safebyok");
|
|
15
|
+
//#endregion
|
|
16
|
+
export { convex_config_default as default };
|
|
17
|
+
|
|
18
|
+
//# sourceMappingURL=convex.config.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"convex.config.js","names":[],"sources":["../../src/component/convex.config.ts"],"sourcesContent":["import { defineComponent } from 'convex/server'\n\n/**\n * The safebyok component, as a host app installs it from its `convex/convex.config.ts`:\n *\n * @example\n * import { defineApp } from 'convex/server'\n * import safebyok from 'safebyok-convex/convex.config'\n *\n * const app = defineApp()\n * app.use(safebyok)\n * export default app\n */\nexport default defineComponent('safebyok')\n"],"mappings":";;;;;;;;;;;;;AAaA,IAAA,wBAAe,gBAAgB,UAAU"}
|
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
//#region src/component/schema.d.ts
|
|
2
|
+
/**
|
|
3
|
+
* The component's own tables, isolated from the host app's. Each row is a record as the core
|
|
4
|
+
* writes it, in typed columns: ciphertext and public fields only.
|
|
5
|
+
*
|
|
6
|
+
* `user_id` leads both indexes: every call is one user's, and an account's rows are one range.
|
|
7
|
+
*/
|
|
8
|
+
declare const _default: import("convex/server").SchemaDefinition<{
|
|
9
|
+
/** One VaultBundle per vault, as-is. */
|
|
10
|
+
safebyok_bundles: import("convex/server").TableDefinition<import("convex/values").VObject<{
|
|
11
|
+
format: "safebyok-vault-v1";
|
|
12
|
+
applabel: string;
|
|
13
|
+
user_id: string;
|
|
14
|
+
vaultlabel: string;
|
|
15
|
+
vault_id: string;
|
|
16
|
+
passphrase_epoch: number;
|
|
17
|
+
key_deriver_label: string;
|
|
18
|
+
passphrase_salt_b64: string;
|
|
19
|
+
vault_key_passphrase_wrapped: {
|
|
20
|
+
cipher_iv_b64: string;
|
|
21
|
+
ciphertext_b64: string;
|
|
22
|
+
};
|
|
23
|
+
created_at: string;
|
|
24
|
+
updated_at: string;
|
|
25
|
+
}, {
|
|
26
|
+
format: import("convex/values").VUnion<"safebyok-vault-v1", [import("convex/values").VLiteral<"safebyok-vault-v1", "required">], "required", never>;
|
|
27
|
+
applabel: import("convex/values").VString<string, "required">;
|
|
28
|
+
user_id: import("convex/values").VString<string, "required">;
|
|
29
|
+
vaultlabel: import("convex/values").VString<string, "required">;
|
|
30
|
+
vault_id: import("convex/values").VString<string, "required">;
|
|
31
|
+
passphrase_epoch: import("convex/values").VFloat64<number, "required">;
|
|
32
|
+
key_deriver_label: import("convex/values").VString<string, "required">;
|
|
33
|
+
passphrase_salt_b64: import("convex/values").VString<string, "required">;
|
|
34
|
+
vault_key_passphrase_wrapped: import("convex/values").VObject<{
|
|
35
|
+
cipher_iv_b64: string;
|
|
36
|
+
ciphertext_b64: string;
|
|
37
|
+
}, {
|
|
38
|
+
cipher_iv_b64: import("convex/values").VString<string, "required">;
|
|
39
|
+
ciphertext_b64: import("convex/values").VString<string, "required">;
|
|
40
|
+
}, "required", "cipher_iv_b64" | "ciphertext_b64">;
|
|
41
|
+
created_at: import("convex/values").VString<string, "required">;
|
|
42
|
+
updated_at: import("convex/values").VString<string, "required">;
|
|
43
|
+
}, "required", "format" | "applabel" | "user_id" | "vaultlabel" | "vault_id" | "passphrase_epoch" | "key_deriver_label" | "passphrase_salt_b64" | "vault_key_passphrase_wrapped" | "created_at" | "updated_at" | "vault_key_passphrase_wrapped.cipher_iv_b64" | "vault_key_passphrase_wrapped.ciphertext_b64">, {
|
|
44
|
+
by_scope: ["user_id", "applabel", "vaultlabel", "_creationTime"];
|
|
45
|
+
}, {}, {}>;
|
|
46
|
+
/**
|
|
47
|
+
* One Lockbox per boxlabel, as-is, with its vault's scope columns beside it: added on write,
|
|
48
|
+
* stripped on read. `by_box` serves one box (all four fields) and a vault's boxes (the first three).
|
|
49
|
+
*/
|
|
50
|
+
safebyok_lockboxes: import("convex/server").TableDefinition<import("convex/values").VObject<{
|
|
51
|
+
note?: string;
|
|
52
|
+
format: "safebyok-lockbox-v1";
|
|
53
|
+
created_at: string;
|
|
54
|
+
updated_at: string;
|
|
55
|
+
boxlabel: string;
|
|
56
|
+
revision_id: string;
|
|
57
|
+
lockbox_key_wrapped: {
|
|
58
|
+
cipher_iv_b64: string;
|
|
59
|
+
ciphertext_b64: string;
|
|
60
|
+
};
|
|
61
|
+
whisper_ciphered: {
|
|
62
|
+
cipher_iv_b64: string;
|
|
63
|
+
ciphertext_b64: string;
|
|
64
|
+
};
|
|
65
|
+
applabel: string;
|
|
66
|
+
user_id: string;
|
|
67
|
+
vaultlabel: string;
|
|
68
|
+
}, {
|
|
69
|
+
format: import("convex/values").VUnion<"safebyok-lockbox-v1", [import("convex/values").VLiteral<"safebyok-lockbox-v1", "required">], "required", never>;
|
|
70
|
+
boxlabel: import("convex/values").VString<string, "required">;
|
|
71
|
+
revision_id: import("convex/values").VString<string, "required">;
|
|
72
|
+
lockbox_key_wrapped: import("convex/values").VObject<{
|
|
73
|
+
cipher_iv_b64: string;
|
|
74
|
+
ciphertext_b64: string;
|
|
75
|
+
}, {
|
|
76
|
+
cipher_iv_b64: import("convex/values").VString<string, "required">;
|
|
77
|
+
ciphertext_b64: import("convex/values").VString<string, "required">;
|
|
78
|
+
}, "required", "cipher_iv_b64" | "ciphertext_b64">;
|
|
79
|
+
whisper_ciphered: import("convex/values").VObject<{
|
|
80
|
+
cipher_iv_b64: string;
|
|
81
|
+
ciphertext_b64: string;
|
|
82
|
+
}, {
|
|
83
|
+
cipher_iv_b64: import("convex/values").VString<string, "required">;
|
|
84
|
+
ciphertext_b64: import("convex/values").VString<string, "required">;
|
|
85
|
+
}, "required", "cipher_iv_b64" | "ciphertext_b64">;
|
|
86
|
+
note: import("convex/values").VString<string | undefined, "optional">;
|
|
87
|
+
created_at: import("convex/values").VString<string, "required">;
|
|
88
|
+
updated_at: import("convex/values").VString<string, "required">;
|
|
89
|
+
applabel: import("convex/values").VString<string, "required">;
|
|
90
|
+
user_id: import("convex/values").VString<string, "required">;
|
|
91
|
+
vaultlabel: import("convex/values").VString<string, "required">;
|
|
92
|
+
}, "required", "format" | "applabel" | "user_id" | "vaultlabel" | "created_at" | "updated_at" | "boxlabel" | "revision_id" | "lockbox_key_wrapped" | "whisper_ciphered" | "note" | "lockbox_key_wrapped.cipher_iv_b64" | "lockbox_key_wrapped.ciphertext_b64" | "whisper_ciphered.cipher_iv_b64" | "whisper_ciphered.ciphertext_b64">, {
|
|
93
|
+
by_box: ["user_id", "applabel", "vaultlabel", "boxlabel", "_creationTime"];
|
|
94
|
+
}, {}, {}>;
|
|
95
|
+
}, true>;
|
|
96
|
+
//#endregion
|
|
97
|
+
export { _default as default };
|
|
98
|
+
//# sourceMappingURL=schema.d.ts.map
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import { Lockbox, VaultBundle, VaultScope } from "./validators.js";
|
|
2
|
+
import { defineSchema, defineTable } from "convex/server";
|
|
3
|
+
//#region src/component/schema.ts
|
|
4
|
+
/**
|
|
5
|
+
* The component's own tables, isolated from the host app's. Each row is a record as the core
|
|
6
|
+
* writes it, in typed columns: ciphertext and public fields only.
|
|
7
|
+
*
|
|
8
|
+
* `user_id` leads both indexes: every call is one user's, and an account's rows are one range.
|
|
9
|
+
*/
|
|
10
|
+
var schema_default = defineSchema({
|
|
11
|
+
/** One VaultBundle per vault, as-is. */
|
|
12
|
+
safebyok_bundles: defineTable(VaultBundle).index("by_scope", [
|
|
13
|
+
"user_id",
|
|
14
|
+
"applabel",
|
|
15
|
+
"vaultlabel"
|
|
16
|
+
]),
|
|
17
|
+
/**
|
|
18
|
+
* One Lockbox per boxlabel, as-is, with its vault's scope columns beside it: added on write,
|
|
19
|
+
* stripped on read. `by_box` serves one box (all four fields) and a vault's boxes (the first three).
|
|
20
|
+
*/
|
|
21
|
+
safebyok_lockboxes: defineTable(Lockbox.extend(VaultScope.fields)).index("by_box", [
|
|
22
|
+
"user_id",
|
|
23
|
+
"applabel",
|
|
24
|
+
"vaultlabel",
|
|
25
|
+
"boxlabel"
|
|
26
|
+
])
|
|
27
|
+
});
|
|
28
|
+
//#endregion
|
|
29
|
+
export { schema_default as default };
|
|
30
|
+
|
|
31
|
+
//# sourceMappingURL=schema.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"schema.js","names":[],"sources":["../../src/component/schema.ts"],"sourcesContent":["import { defineSchema, defineTable } from 'convex/server'\nimport { Lockbox, VaultBundle, VaultScope } from './validators'\n\n/**\n * The component's own tables, isolated from the host app's. Each row is a record as the core\n * writes it, in typed columns: ciphertext and public fields only.\n *\n * `user_id` leads both indexes: every call is one user's, and an account's rows are one range.\n */\nexport default defineSchema({\n /** One VaultBundle per vault, as-is. */\n safebyok_bundles: defineTable(VaultBundle)\n .index('by_scope', ['user_id', 'applabel', 'vaultlabel']),\n /**\n * One Lockbox per boxlabel, as-is, with its vault's scope columns beside it: added on write,\n * stripped on read. `by_box` serves one box (all four fields) and a vault's boxes (the first three).\n */\n safebyok_lockboxes: defineTable(Lockbox.extend(VaultScope.fields))\n .index('by_box', ['user_id', 'applabel', 'vaultlabel', 'boxlabel']),\n})\n"],"mappings":";;;;;;;;;AASA,IAAA,iBAAe,aAAa;;CAE1B,kBAAkB,YAAY,WAAW,CAAC,CACvC,MAAM,YAAY;EAAC;EAAW;EAAY;CAAY,CAAC;;;;;CAK1D,oBAAoB,YAAY,QAAQ,OAAO,WAAW,MAAM,CAAC,CAAC,CAC/D,MAAM,UAAU;EAAC;EAAW;EAAY;EAAc;CAAU,CAAC;AACtE,CAAC"}
|