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.
Files changed (62) hide show
  1. package/README.md +32 -13
  2. package/dist/_virtual/_rolldown/runtime.js +13 -0
  3. package/dist/component/_generated/api.d.ts +7 -0
  4. package/dist/component/_generated/api.js +9 -0
  5. package/dist/component/_generated/api.js.map +1 -0
  6. package/dist/component/_generated/dataModel.d.ts +40 -0
  7. package/dist/component/_generated/dataModel.js +0 -0
  8. package/dist/component/_generated/server.d.ts +127 -0
  9. package/dist/component/_generated/server.js +74 -0
  10. package/dist/component/_generated/server.js.map +1 -0
  11. package/dist/component/convex.config.d.ts +16 -0
  12. package/dist/component/convex.config.js +18 -0
  13. package/dist/component/convex.config.js.map +1 -0
  14. package/dist/component/schema.d.ts +98 -0
  15. package/dist/component/schema.js +31 -0
  16. package/dist/component/schema.js.map +1 -0
  17. package/dist/component/validators.d.ts +196 -0
  18. package/dist/component/validators.js +118 -0
  19. package/dist/component/validators.js.map +1 -0
  20. package/dist/component/vaults.d.ts +225 -0
  21. package/dist/component/vaults.js +189 -0
  22. package/dist/component/vaults.js.map +1 -0
  23. package/dist/component-api.d.ts +20 -0
  24. package/dist/component-api.js +0 -0
  25. package/dist/convex-vault-db.d.ts +56 -0
  26. package/dist/convex-vault-db.js +170 -0
  27. package/dist/convex-vault-db.js.map +1 -0
  28. package/dist/index.d.ts +3 -0
  29. package/dist/index.js +1 -0
  30. package/dist/refusals.d.ts +18 -0
  31. package/dist/refusals.js +16 -0
  32. package/dist/refusals.js.map +1 -0
  33. package/dist/server.d.ts +231 -0
  34. package/dist/server.js +147 -0
  35. package/dist/server.js.map +1 -0
  36. package/package.json +68 -16
  37. package/src/component/validators.ts +4 -1
  38. package/src/component/vaults.ts +3 -3
  39. package/src/convex-vault-db.ts +30 -4
  40. package/src/server.ts +20 -12
  41. package/src/test.ts +1 -1
  42. package/.claude/skills/LICENSE-convex-agent-skills +0 -201
  43. package/.claude/skills/README.md +0 -115
  44. package/.claude/skills/convex-create-component/SKILL.md +0 -330
  45. package/.claude/skills/convex-create-component/references/advanced-patterns.md +0 -152
  46. package/.claude/skills/convex-create-component/references/packaged-components.md +0 -61
  47. package/.claude/skills/convex-docs/SKILL.md +0 -31
  48. package/.claude/skills/convex-expert/SKILL.md +0 -42
  49. package/.claude/skills/convex-reviewer/SKILL.md +0 -32
  50. package/.claude/skills/convex-test/SKILL.md +0 -23
  51. package/.claude/skills/convex-verify/SKILL.md +0 -40
  52. package/eslint.config.mjs +0 -85
  53. package/tests/component/validators.test.ts +0 -160
  54. package/tests/component/vaults.test.ts +0 -351
  55. package/tests/convex-vault-db.test.ts +0 -332
  56. package/tests/fake-deployment.ts +0 -229
  57. package/tests/helpers.ts +0 -102
  58. package/tests/refusals.test.ts +0 -25
  59. package/tests/server.test.ts +0 -139
  60. package/tests/test.test.ts +0 -25
  61. package/tsconfig.json +0 -33
  62. 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
- A workspace package, source-exported (`exports` points at `src/`) while the interface settles;
9
- not yet built or published. `convex` is a peer dependency.
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 { idbDeviceDB } from 'safebyok/idb'
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
- deviceDB: idbDeviceDB(),
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. A lockbox at the
117
- largest whisper a vault stores by default is about 54 KB, so about 150 of those; a lockbox
118
- holding an API key is about 1 KB, so thousands. Each record must also fit Convex's 1 MiB document
119
- limit, which the core's `maxWhisperBytes` keeps well inside.
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 and tests: `convex-test` under the edge runtime,
156
- in memory, with no deployment. The tests and typecheck resolve `safebyok` through its built
157
- `dist/`, as a consumer's would, and make real vaults with the core's own code; each script builds
158
- the core first by itself (`pnpm build:deps`), so a fresh clone needs no prebuild step.
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"}