@lunora/server 1.0.0-alpha.16 → 1.0.0-alpha.161

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 (91) hide show
  1. package/LICENSE.md +219 -0
  2. package/README.md +53 -1
  3. package/dist/data-model.d.mts +273 -164
  4. package/dist/data-model.d.ts +273 -164
  5. package/dist/data-model.mjs +0 -1
  6. package/dist/drizzle.mjs +1 -1
  7. package/dist/index.d.mts +3235 -1520
  8. package/dist/index.d.ts +3235 -1520
  9. package/dist/index.mjs +1 -29
  10. package/dist/otel.d.mts +554 -0
  11. package/dist/otel.d.ts +554 -0
  12. package/dist/otel.mjs +1 -0
  13. package/dist/packem_shared/ACTION_CACHE_DEFAULT_TTL_MS-DHpfdhmu.mjs +1 -0
  14. package/dist/packem_shared/DEFAULT_LIMIT-pT_tV8R0.mjs +1 -0
  15. package/dist/packem_shared/DOCUMENT_HISTORY_REDACTED_FIELDS-DAfomt5Q.mjs +1 -0
  16. package/dist/packem_shared/LunoraEnvError-A5I-PzMh.mjs +3 -0
  17. package/dist/packem_shared/PRESENCE_DEFAULT_TTL_MS-DObDBz6_.mjs +1 -0
  18. package/dist/packem_shared/allowAll-DkRAgItV.mjs +1 -0
  19. package/dist/packem_shared/apply-output-C5wZ5EAL.mjs +1 -0
  20. package/dist/packem_shared/asBucketStorage-DoGYOjq3.mjs +1 -0
  21. package/dist/packem_shared/assertShapesDeclareReadPolicies-d9t7YZ7U.mjs +1 -0
  22. package/dist/packem_shared/beginDeferredDeletes-DhwFBbvs.mjs +1 -0
  23. package/dist/packem_shared/beginDeferredSchedules-DJ6U4iq5.mjs +1 -0
  24. package/dist/packem_shared/bindOrm-D_hFUjmr.mjs +1 -0
  25. package/dist/packem_shared/buildMaskRegistry-DpWMtalG.mjs +1 -0
  26. package/dist/packem_shared/compose-middleware-DNvrHMHx.mjs +1 -0
  27. package/dist/packem_shared/composePluginMiddleware-DLFJvSOQ.mjs +1 -0
  28. package/dist/packem_shared/context-identity-B2XYGA0B.mjs +1 -0
  29. package/dist/packem_shared/createPolicyDsl-BZa6SqLJ.mjs +1 -0
  30. package/dist/packem_shared/createSecrets-D6rLB42U.mjs +1 -0
  31. package/dist/packem_shared/defineAggregateIndex-CIyA-yra.mjs +1 -0
  32. package/dist/packem_shared/defineIdentity-DwkNKwYa.mjs +1 -0
  33. package/dist/packem_shared/defineMigration-CXOS0Bvq.mjs +1 -0
  34. package/dist/packem_shared/defineMutator-DKy8UtbB.mjs +1 -0
  35. package/dist/packem_shared/defineShape-CbHQpfYD.mjs +1 -0
  36. package/dist/packem_shared/defineStorageRule-Dv4nJE0H.mjs +1 -0
  37. package/dist/packem_shared/fnv1a-D3ueNTWB.mjs +1 -0
  38. package/dist/packem_shared/functions-B2-H4PQT.mjs +1 -0
  39. package/dist/packem_shared/httpAction-DFVhrm8u.mjs +5 -0
  40. package/dist/packem_shared/initLunora-DAbEYdSo.mjs +1 -0
  41. package/dist/packem_shared/isPerDispatchMiddleware-DDQPatSm.mjs +1 -0
  42. package/dist/packem_shared/mask-DrapWB_J.mjs +1 -0
  43. package/dist/packem_shared/middleware-ChNz4wOv.mjs +1 -0
  44. package/dist/packem_shared/onConnect-BLRoOpv2.mjs +1 -0
  45. package/dist/packem_shared/onQueryChange-CatdYnH5.mjs +1 -0
  46. package/dist/packem_shared/onWhisper-CfDbFLQh.mjs +1 -0
  47. package/dist/packem_shared/plugin-DRIqze14.mjs +1 -0
  48. package/dist/packem_shared/policy-tag-V0lqFzgS.mjs +1 -0
  49. package/dist/packem_shared/protectPublic-BUYCMZZB.mjs +1 -0
  50. package/dist/packem_shared/rls-BFeCBejD.mjs +1 -0
  51. package/dist/packem_shared/run-middleware-laenw2jQ.mjs +1 -0
  52. package/dist/packem_shared/serveStorageObject-9mdw0nyU.mjs +1 -0
  53. package/dist/packem_shared/stable-key-B_BlboiY.mjs +1 -0
  54. package/dist/packem_shared/storageRules-DSmSbQqS.mjs +1 -0
  55. package/dist/packem_shared/types.d-B7FLdYUD.d.mts +148 -0
  56. package/dist/packem_shared/types.d-BCtjbIzl.d.ts +148 -0
  57. package/dist/packem_shared/wire-codec-BTOxkE1j.mjs +1 -0
  58. package/dist/rls/testing.d.mts +42 -34
  59. package/dist/rls/testing.d.ts +42 -34
  60. package/dist/rls/testing.mjs +1 -49
  61. package/dist/types.d.mts +1939 -531
  62. package/dist/types.d.ts +1939 -531
  63. package/dist/types.mjs +1 -31
  64. package/package.json +18 -5
  65. package/dist/packem_shared/LunoraEnvError-BGmd1Qs0.mjs +0 -187
  66. package/dist/packem_shared/LunoraError-WbxmrpxR.mjs +0 -9
  67. package/dist/packem_shared/PRESENCE_DEFAULT_TTL_MS-BtPCiNLW.mjs +0 -114
  68. package/dist/packem_shared/asBucketStorage-Cnxd9y2q.mjs +0 -11
  69. package/dist/packem_shared/bindOrm-CNXKgfUa.mjs +0 -130
  70. package/dist/packem_shared/buildRlsReadRegistry-DFBFLydB.mjs +0 -107
  71. package/dist/packem_shared/composePluginMiddleware-CcTj1_v2.mjs +0 -103
  72. package/dist/packem_shared/createPolicyDsl-By3QB4he.mjs +0 -32
  73. package/dist/packem_shared/createSecrets-DwaR2rNG.mjs +0 -58
  74. package/dist/packem_shared/defineAggregateIndex-znq4ygKQ.mjs +0 -295
  75. package/dist/packem_shared/defineIdentity-DiX4zM9x.mjs +0 -35
  76. package/dist/packem_shared/defineMigration-Hx01yIht.mjs +0 -10
  77. package/dist/packem_shared/defineMutator-EIXAWhs9.mjs +0 -11
  78. package/dist/packem_shared/defineShape-C5scNOrf.mjs +0 -18
  79. package/dist/packem_shared/defineStorageRule-B5nL4Z1P.mjs +0 -23
  80. package/dist/packem_shared/functions-Di9FUNkf.mjs +0 -5
  81. package/dist/packem_shared/httpAction-B_16WzMO.mjs +0 -331
  82. package/dist/packem_shared/initLunora-sQUqaejx.mjs +0 -100
  83. package/dist/packem_shared/mask-Dc8G5Gl7.mjs +0 -291
  84. package/dist/packem_shared/onConnect-CIPXKPyw.mjs +0 -13
  85. package/dist/packem_shared/policy-tag-DvpVH2tv.mjs +0 -13
  86. package/dist/packem_shared/protectPublic-BlcGpiRc.mjs +0 -15
  87. package/dist/packem_shared/rls-3sCJIH6F.mjs +0 -572
  88. package/dist/packem_shared/run-middleware-I6EiQfxL.mjs +0 -20
  89. package/dist/packem_shared/storageRules-6QxzDOcx.mjs +0 -88
  90. package/dist/packem_shared/types.d-BB3pjV0m.d.mts +0 -141
  91. package/dist/packem_shared/types.d-Cxl6ndhm.d.ts +0 -141
@@ -1,103 +0,0 @@
1
- import { LunoraError as LunoraError$1 } from '@lunora/errors';
2
- import { r as runMiddlewareChain } from './run-middleware-I6EiQfxL.mjs';
3
-
4
- const prefixTableName = (key, bareName) => `${key}_${bareName}`;
5
- const rewriteReference = (target, key, bareNames) => bareNames.has(target) ? prefixTableName(key, target) : target;
6
- const rewriteTableReferences = (table, key, bareNames, ownBareName) => {
7
- const ownPrefixed = prefixTableName(key, ownBareName);
8
- const rewriteOn = (on) => on === "" ? ownPrefixed : rewriteReference(on, key, bareNames);
9
- const relationMap = {};
10
- for (const [accessor, relation] of Object.entries(table.relationMap)) {
11
- relationMap[accessor] = { ...relation, table: rewriteReference(relation.table, key, bareNames) };
12
- }
13
- const aggregateIndexes = table.aggregateIndexes.map((index) => {
14
- return { ...index, on: rewriteOn(index.on) };
15
- });
16
- const rankIndexes = table.rankIndexes.map((index) => {
17
- return { ...index, on: rewriteOn(index.on) };
18
- });
19
- return { ...table, aggregateIndexes, rankIndexes, relationMap };
20
- };
21
- const defineSchemaExtension = (key, options) => {
22
- if (!key) {
23
- throw new LunoraError$1("INTERNAL", "defineSchemaExtension: `key` is required and must be a non-empty string");
24
- }
25
- return {
26
- key,
27
- tables: options.tables,
28
- ...options.vectorIndexes ? { vectorIndexes: options.vectorIndexes } : {}
29
- };
30
- };
31
- const definePlugin = (key, options) => {
32
- if (!key) {
33
- throw new LunoraError$1("INTERNAL", "definePlugin: `key` is required and must be a non-empty string");
34
- }
35
- if (options.extension && options.extension.key !== key) {
36
- throw new LunoraError$1("INTERNAL", `definePlugin("${key}"): extension key "${options.extension.key}" does not match plugin key`);
37
- }
38
- return {
39
- key,
40
- ...options.extension ? { extension: options.extension } : {},
41
- ...options.middleware ? { middleware: options.middleware } : {}
42
- };
43
- };
44
- const defineComponent = (key, options) => {
45
- const plugin = definePlugin(key, {
46
- ...options.extension ? { extension: options.extension } : {},
47
- ...options.middleware ? { middleware: options.middleware } : {}
48
- });
49
- return {
50
- ...plugin,
51
- functions: options.functions ?? {}
52
- };
53
- };
54
- const mergeSchemaExtension = (base, extension) => {
55
- const { key } = extension;
56
- const bareNames = new Set(Object.keys(extension.tables));
57
- const merged = { ...base.tables };
58
- for (const [bareName, table] of Object.entries(extension.tables)) {
59
- const prefixed = prefixTableName(key, bareName);
60
- if (Object.hasOwn(merged, prefixed)) {
61
- throw new LunoraError$1(
62
- "INTERNAL",
63
- `defineSchema(...).extend("${key}"): table "${prefixed}" already exists in the base schema — another extension with the same key already contributed it`
64
- );
65
- }
66
- merged[prefixed] = rewriteTableReferences(table, key, bareNames, bareName);
67
- }
68
- const mergedVectorIndexes = { ...base.vectorIndexes };
69
- if (extension.vectorIndexes) {
70
- for (const [bareIndexName, index] of Object.entries(extension.vectorIndexes)) {
71
- const prefixed = prefixTableName(key, bareIndexName);
72
- if (Object.hasOwn(mergedVectorIndexes, prefixed)) {
73
- throw new LunoraError$1(
74
- "INTERNAL",
75
- `defineSchema(...).extend("${key}"): vector index "${prefixed}" already exists in the base schema — another extension with the same key already contributed it`
76
- );
77
- }
78
- mergedVectorIndexes[prefixed] = { ...index, table: rewriteReference(index.table, key, bareNames) };
79
- }
80
- }
81
- return {
82
- // Preserve secure-by-default RLS across `.extend(...)` — a plugin's
83
- // tables join an `.rls("required")` schema as protected-by-default too.
84
- rlsMode: base.rlsMode,
85
- tables: merged,
86
- vectorIndexes: mergedVectorIndexes
87
- };
88
- };
89
- const installPlugins = (base, plugins) => {
90
- let schema = base;
91
- for (const plugin of plugins) {
92
- if (plugin.extension) {
93
- schema = mergeSchemaExtension(schema, plugin.extension);
94
- }
95
- }
96
- return schema;
97
- };
98
- const composePluginMiddleware = (plugins) => {
99
- const middlewares = plugins.map((plugin) => plugin.middleware).filter((middleware) => middleware !== void 0);
100
- return (async ({ ctx, next }) => runMiddlewareChain(middlewares, ctx, (context) => next({ ctx: context })));
101
- };
102
-
103
- export { composePluginMiddleware, defineComponent, definePlugin, defineSchemaExtension, installPlugins, mergeSchemaExtension };
@@ -1,32 +0,0 @@
1
- import { LunoraError as LunoraError$1 } from '@lunora/errors';
2
-
3
- const definePolicy = (input) => {
4
- return { on: input.on, table: input.table, when: input.when };
5
- };
6
- const createPolicyDsl = () => (input) => {
7
- return { on: input.on, table: input.table, when: input.when };
8
- };
9
- const definePermission = (name, options = {}) => {
10
- return { name, ...options };
11
- };
12
- const definePolicies = (policies) => {
13
- const seenWhenByKey = /* @__PURE__ */ new Map();
14
- for (const policy of policies) {
15
- const key = JSON.stringify([policy.table, policy.on]);
16
- const whens = seenWhenByKey.get(key) ?? /* @__PURE__ */ new Set();
17
- if (whens.has(policy.when)) {
18
- throw new LunoraError$1(
19
- "INTERNAL",
20
- `definePolicies: duplicate policy for (table "${policy.table}", on "${policy.on}") — the same decision function is registered more than once. Multiple distinct policies per (table, on) are allowed (reads OR, writes AND); remove the duplicate.`
21
- );
22
- }
23
- whens.add(policy.when);
24
- seenWhenByKey.set(key, whens);
25
- }
26
- return policies;
27
- };
28
- const defineRole = (name, options = {}) => {
29
- return { name, ...options };
30
- };
31
-
32
- export { createPolicyDsl, definePermission, definePolicies, definePolicy, defineRole };
@@ -1,58 +0,0 @@
1
- import { LunoraError as LunoraError$1 } from '@lunora/errors';
2
-
3
- const NON_SECRET_BINDING_METHODS = [
4
- "put",
5
- // KV / R2
6
- "list",
7
- // KV / R2
8
- "delete",
9
- // KV / R2
10
- "getWithMetadata",
11
- // KV
12
- "head",
13
- // R2
14
- "createMultipartUpload",
15
- // R2
16
- "idFromName",
17
- // Durable Object namespace
18
- "newUniqueId",
19
- // Durable Object namespace
20
- "getByName",
21
- // Durable Object namespace
22
- "send",
23
- // Queue producer
24
- "sendBatch",
25
- // Queue producer
26
- "writeDataPoint",
27
- // Analytics Engine dataset
28
- "create",
29
- // Workflows binding (get(id) + create/createBatch)
30
- "createBatch"
31
- // Workflows binding
32
- ];
33
- const isSecretBinding = (value) => {
34
- if (typeof value !== "object" || value === null) {
35
- return false;
36
- }
37
- const record = value;
38
- if (typeof record.get !== "function") {
39
- return false;
40
- }
41
- return !NON_SECRET_BINDING_METHODS.some((method) => typeof record[method] === "function");
42
- };
43
- const createSecrets = (env) => {
44
- return {
45
- get: async (name) => {
46
- const binding = env[name];
47
- if (!isSecretBinding(binding)) {
48
- throw new LunoraError$1(
49
- "INTERNAL",
50
- `ctx.secrets: no Secrets Store binding named "${name}". Add a \`secrets_store_secrets[]\` entry (binding "${name}", pointing at your store + secret) to wrangler.jsonc — \`ctx.secrets\` reads a Secrets Store binding, not a plain \`.dev.vars\` value.`
51
- );
52
- }
53
- return binding.get();
54
- }
55
- };
56
- };
57
-
58
- export { createSecrets };
@@ -1,295 +0,0 @@
1
- import { LunoraError as LunoraError$1 } from '@lunora/errors';
2
- import { isOrWrapsFromValidator, v } from '@lunora/values';
3
- import { mergeSchemaExtension } from './composePluginMiddleware-CcTj1_v2.mjs';
4
-
5
- const relationBuilder = {
6
- many: (table, options) => {
7
- return { field: options.field, kind: "many", references: options.references ?? "_id", table };
8
- },
9
- one: (table, options) => {
10
- return { field: options.field, kind: "one", onDelete: options.onDelete, references: options.references ?? "_id", table };
11
- }
12
- };
13
- const makeTrigger = (timing, op, handler) => {
14
- return { handler, op, timing };
15
- };
16
- const createTriggerBuilder = () => {
17
- return {
18
- afterDelete: (handler) => makeTrigger("after", "delete", handler),
19
- afterInsert: (handler) => makeTrigger("after", "insert", handler),
20
- afterUpdate: (handler) => makeTrigger("after", "update", handler),
21
- beforeDelete: (handler) => makeTrigger("before", "delete", handler),
22
- beforeInsert: (handler) => makeTrigger("before", "insert", handler),
23
- beforeUpdate: (handler) => makeTrigger("before", "update", handler)
24
- };
25
- };
26
- const defineTable = (inputShape) => {
27
- const shape = { ...inputShape };
28
- for (const [columnName, validator] of Object.entries(shape)) {
29
- if (isOrWrapsFromValidator(validator)) {
30
- throw new LunoraError$1("INTERNAL", `defineTable: column "${columnName}" uses v.from() which is args-only — table columns need a concrete v.* type`);
31
- }
32
- }
33
- const aggregateIndexes = [];
34
- const indexes = [];
35
- const rankIndexes = [];
36
- const relations = {};
37
- const searchIndexes = [];
38
- const triggers = {};
39
- const triggerBuilder = createTriggerBuilder();
40
- const vectorIndexes = [];
41
- let shardMode = { kind: "root" };
42
- let isExternallyManaged = false;
43
- let isPublic = false;
44
- let softDelete;
45
- let externalSource;
46
- const builder = {
47
- aggregateIndex(name, options) {
48
- const op = options?.op ?? "count";
49
- if (op !== "count" && !options?.field) {
50
- throw new LunoraError$1("INTERNAL", `aggregateIndex "${name}": op "${op}" requires a "field"`);
51
- }
52
- aggregateIndexes.push({
53
- by: options?.by,
54
- field: options?.field,
55
- name,
56
- // `on` is filled in by `defineSchema` once the table is keyed; we
57
- // stash the placeholder so the AggregateIndexDefinition shape stays
58
- // straightforward for D1/DO consumers (who read `on`).
59
- on: "",
60
- op,
61
- where: options?.where
62
- });
63
- return builder;
64
- },
65
- get aggregateIndexes() {
66
- return aggregateIndexes;
67
- },
68
- get externalSource() {
69
- return externalSource;
70
- },
71
- externallyManaged() {
72
- isExternallyManaged = true;
73
- return builder;
74
- },
75
- global(options) {
76
- shardMode = { backend: options?.backend ?? "d1", kind: "global" };
77
- return builder;
78
- },
79
- get isExternallyManaged() {
80
- return isExternallyManaged;
81
- },
82
- get isPublic() {
83
- return isPublic;
84
- },
85
- index(name, fields, options) {
86
- indexes.push({ fields, name, unique: options?.unique ?? false });
87
- return builder;
88
- },
89
- get indexes() {
90
- return indexes;
91
- },
92
- public() {
93
- isPublic = true;
94
- return builder;
95
- },
96
- rankIndex(name, options) {
97
- if (!options.sortBy || options.sortBy.length === 0) {
98
- throw new LunoraError$1("INTERNAL", `rankIndex "${name}": "sortBy" is required and must list at least one key`);
99
- }
100
- const sortBy = options.sortBy.map((key) => {
101
- return {
102
- direction: key.direction ?? "asc",
103
- field: key.field
104
- };
105
- });
106
- rankIndexes.push({
107
- name,
108
- // `on` is filled in by `defineSchema` once the table is keyed —
109
- // same pattern as `aggregateIndex`.
110
- on: "",
111
- partitionBy: options.partitionBy,
112
- sortBy,
113
- where: options.where
114
- });
115
- return builder;
116
- },
117
- get rankIndexes() {
118
- return rankIndexes;
119
- },
120
- get relationMap() {
121
- return relations;
122
- },
123
- relations(build) {
124
- Object.assign(relations, build(relationBuilder));
125
- return builder;
126
- },
127
- searchIndex(name, options) {
128
- searchIndexes.push({ field: options.field, filterFields: options.filterFields, name });
129
- return builder;
130
- },
131
- get searchIndexes() {
132
- return searchIndexes;
133
- },
134
- shape,
135
- shardBy(field) {
136
- shardMode = { field, kind: "shardBy" };
137
- return builder;
138
- },
139
- get shardMode() {
140
- return shardMode;
141
- },
142
- get softDeleteMode() {
143
- return softDelete;
144
- },
145
- source(definition) {
146
- if (!definition.binding) {
147
- throw new LunoraError$1("INTERNAL", "source: `binding` is required (the wrangler Hyperdrive binding name)");
148
- }
149
- if (!definition.query) {
150
- throw new LunoraError$1("INTERNAL", "source: `query` is required (the tenant-membership SQL)");
151
- }
152
- externalSource = definition;
153
- isExternallyManaged = true;
154
- return builder;
155
- },
156
- softDelete(options) {
157
- const field = options?.field ?? "deletedAt";
158
- softDelete = { field };
159
- if (!(field in shape)) {
160
- shape[field] = v.optional(v.number().nullable());
161
- }
162
- return builder;
163
- },
164
- get triggerMap() {
165
- return triggers;
166
- },
167
- triggers(build) {
168
- Object.assign(triggers, build(triggerBuilder));
169
- return builder;
170
- },
171
- get vectorIndexes() {
172
- return vectorIndexes;
173
- },
174
- vectorize(field, options) {
175
- vectorIndexes.push({
176
- dimensions: options.dimensions,
177
- embed: options.embed,
178
- field,
179
- metadata: options.metadata,
180
- metric: options.metric,
181
- name: options.index
182
- });
183
- return builder;
184
- }
185
- };
186
- return builder;
187
- };
188
- const defineVectorIndex = (options) => {
189
- return {
190
- dimensions: options.dimensions,
191
- embed: options.embed,
192
- kind: "vectorIndex",
193
- metadata: options.metadata,
194
- metric: options.metric,
195
- select: options.source.select,
196
- table: options.source.table
197
- };
198
- };
199
- const defineAggregateIndex = (name, options) => {
200
- const op = options.op ?? "count";
201
- if (op !== "count" && !options.field) {
202
- throw new LunoraError$1("INTERNAL", `aggregateIndex "${name}": op "${op}" requires a "field"`);
203
- }
204
- return { by: options.by, field: options.field, name, on: options.on, op, where: options.where };
205
- };
206
- const defineRankIndex = (name, options) => {
207
- if (!options.sortBy || options.sortBy.length === 0) {
208
- throw new LunoraError$1("INTERNAL", `rankIndex "${name}": "sortBy" is required and must list at least one key`);
209
- }
210
- const sortBy = options.sortBy.map((key) => {
211
- return {
212
- direction: key.direction ?? "asc",
213
- field: key.field
214
- };
215
- });
216
- return { name, on: options.table, partitionBy: options.partitionBy, sortBy, where: options.where };
217
- };
218
- const withExtend = (schema) => {
219
- return {
220
- ...schema,
221
- extend(extension) {
222
- return withExtend(mergeSchemaExtension(schema, extension));
223
- },
224
- jurisdiction(_jurisdiction) {
225
- return withExtend(schema);
226
- },
227
- rls(mode) {
228
- return withExtend({ ...schema, rlsMode: mode });
229
- }
230
- };
231
- };
232
- const fillIndexTableNames = (tables) => {
233
- for (const [tableName, table] of Object.entries(tables)) {
234
- for (const index of table.aggregateIndexes) {
235
- if (index.on === "") {
236
- index.on = tableName;
237
- }
238
- }
239
- for (const index of table.rankIndexes) {
240
- if (index.on === "") {
241
- index.on = tableName;
242
- }
243
- }
244
- }
245
- };
246
- const attachStandaloneIndexes = (tables, aggregateIndexes, rankIndexes) => {
247
- for (const index of Object.values(aggregateIndexes)) {
248
- const table = tables[index.on];
249
- if (!table) {
250
- throw new LunoraError$1("INTERNAL", `defineAggregateIndex "${index.name}": unknown table "${index.on}"`);
251
- }
252
- table.aggregateIndexes.push(index);
253
- }
254
- for (const index of Object.values(rankIndexes)) {
255
- const table = tables[index.on];
256
- if (!table) {
257
- throw new LunoraError$1("INTERNAL", `defineRankIndex "${index.name}": unknown table "${index.on}"`);
258
- }
259
- table.rankIndexes.push(index);
260
- }
261
- };
262
- const validateExternalSources = (tables) => {
263
- for (const [name, table] of Object.entries(tables)) {
264
- const source = table.externalSource;
265
- if (!source) {
266
- continue;
267
- }
268
- if (table.shardMode.kind === "global") {
269
- throw new LunoraError$1(
270
- "INTERNAL",
271
- `defineSchema: table "${name}" cannot be both .source() and .global() — a sourced table materializes into a shard DO's SQLite, a global table lives in the external tier`
272
- );
273
- }
274
- if (table.shardMode.kind === "shardBy" && !source.tenantBy) {
275
- throw new LunoraError$1(
276
- "INTERNAL",
277
- `defineSchema: sourced + .shardBy() table "${name}" needs a \`tenantBy\` mapper — without it every tenant's DO would run the same unscoped query and replicate the whole multitenant table (a cross-tenant leak). Add \`tenantBy: (shardKey) => [shardKey]\` binding the shard key into the query's parameters.`
278
- );
279
- }
280
- if (source.mode === "incremental") {
281
- throw new LunoraError$1(
282
- "INTERNAL",
283
- `defineSchema: table "${name}" uses \`mode: "incremental"\`, which is not yet implemented — only "full-pull" (the default) is supported. Remove \`mode\` or set it to "full-pull".`
284
- );
285
- }
286
- }
287
- };
288
- const defineSchema = (tables, vectorIndexes = {}, aggregateIndexes = {}, rankIndexes = {}) => {
289
- fillIndexTableNames(tables);
290
- attachStandaloneIndexes(tables, aggregateIndexes, rankIndexes);
291
- validateExternalSources(tables);
292
- return withExtend({ tables, vectorIndexes });
293
- };
294
-
295
- export { defineAggregateIndex, defineRankIndex, defineSchema, defineTable, defineVectorIndex };
@@ -1,35 +0,0 @@
1
- import { LunoraError as LunoraError$1 } from '@lunora/errors';
2
- import { parseValidatorMap, ValidationError } from '@lunora/values';
3
-
4
- const NON_STRING_USER_ID_KINDS = /* @__PURE__ */ new Set([
5
- "array",
6
- "bigint",
7
- "boolean",
8
- "bytes",
9
- "date",
10
- "null",
11
- "number",
12
- "object",
13
- "optional",
14
- "record",
15
- "timestamp"
16
- ]);
17
- const defineIdentity = (claims, options = {}) => {
18
- const map = claims;
19
- const userIdValidator = map["userId"];
20
- if (userIdValidator === void 0 || NON_STRING_USER_ID_KINDS.has(userIdValidator.kind)) {
21
- throw new LunoraError$1("INTERNAL", "defineIdentity: the claim map must declare a required string `userId` validator (e.g. `v.string()` or `v.id(...)`)");
22
- }
23
- const onInvalid = options.onInvalid ?? "anonymous";
24
- const validate = (identity) => {
25
- try {
26
- parseValidatorMap(map, identity, "identity");
27
- return { ok: true };
28
- } catch (error) {
29
- return { error: error instanceof ValidationError ? error.message : String(error), ok: false };
30
- }
31
- };
32
- return { __lunoraIdentity: true, claims: map, onInvalid, validate };
33
- };
34
-
35
- export { defineIdentity };
@@ -1,10 +0,0 @@
1
- import { LunoraError as LunoraError$1 } from '@lunora/errors';
2
-
3
- const defineMigration = (definition) => {
4
- if (definition.id.trim() === "") {
5
- throw new LunoraError$1("INTERNAL", "defineMigration: `id` must be a non-empty string");
6
- }
7
- return { __lunoraMigration: true, ...definition };
8
- };
9
-
10
- export { defineMigration };
@@ -1,11 +0,0 @@
1
- import { v as validateArgs } from './functions-Di9FUNkf.mjs';
2
-
3
- const defineMutator = (definition) => {
4
- const handler = async (context, rawArgs) => {
5
- const parsed = validateArgs(definition.args ?? {}, rawArgs);
6
- return definition.server(context, parsed);
7
- };
8
- return { __lunoraMutator: true, ...definition, handler, kind: "mutation" };
9
- };
10
-
11
- export { defineMutator };
@@ -1,18 +0,0 @@
1
- import { LunoraError as LunoraError$1 } from '@lunora/errors';
2
- import { v as validateArgs } from './functions-Di9FUNkf.mjs';
3
-
4
- const defineShape = (definition) => {
5
- if (definition.table.trim() === "") {
6
- throw new LunoraError$1("INTERNAL", "defineShape: `table` must be a non-empty string");
7
- }
8
- if (definition.columns?.length === 0) {
9
- throw new LunoraError$1("INTERNAL", "defineShape: `columns` must list at least one column when provided");
10
- }
11
- const compileWhere = (context, rawArgs) => {
12
- const parsed = validateArgs(definition.args ?? {}, rawArgs);
13
- return definition.where(context, parsed);
14
- };
15
- return { __lunoraShape: true, ...definition, compileWhere };
16
- };
17
-
18
- export { defineShape };
@@ -1,23 +0,0 @@
1
- import { LunoraError as LunoraError$1 } from '@lunora/errors';
2
-
3
- const defineStorageRule = (input) => {
4
- return { bucket: input.bucket, on: input.on, prefix: input.prefix, when: input.when };
5
- };
6
- const defineStorageRules = (rules) => {
7
- const seenWhenByKey = /* @__PURE__ */ new Map();
8
- for (const rule of rules) {
9
- const key = JSON.stringify([rule.bucket, rule.on, rule.prefix]);
10
- const whens = seenWhenByKey.get(key) ?? /* @__PURE__ */ new Set();
11
- if (whens.has(rule.when)) {
12
- throw new LunoraError$1(
13
- "INTERNAL",
14
- `defineStorageRules: duplicate rule for (bucket "${rule.bucket}", on "${rule.on}"${rule.prefix === void 0 ? "" : `, prefix "${rule.prefix}"`}) — the same decision function is registered more than once. Multiple distinct rules per (bucket, on) are allowed (they OR); remove the duplicate.`
15
- );
16
- }
17
- whens.add(rule.when);
18
- seenWhenByKey.set(key, whens);
19
- }
20
- return rules;
21
- };
22
-
23
- export { defineStorageRule, defineStorageRules };
@@ -1,5 +0,0 @@
1
- import { parseValidatorMap } from '@lunora/values';
2
-
3
- const validateArgs = (validators, args) => parseValidatorMap(validators, args, "args");
4
-
5
- export { validateArgs as v };