@impetik/xeer-mcp 0.2.5 → 0.2.6

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 (54) hide show
  1. package/README.md +4 -1
  2. package/dist/dev-session.d.ts +1 -1
  3. package/dist/network-policy.js +1 -1
  4. package/dist/server.d.ts +1 -1
  5. package/dist/server.js +4 -4
  6. package/dist/test-run.d.ts +1 -1
  7. package/dist/xeer-cli.d.ts +1 -1
  8. package/package.json +8 -5
  9. package/vendor/spec/actions.d.ts +1250 -0
  10. package/vendor/spec/actions.js +805 -0
  11. package/vendor/spec/admin-sql.d.ts +59 -0
  12. package/vendor/spec/admin-sql.js +147 -0
  13. package/vendor/spec/admin.d.ts +110 -0
  14. package/vendor/spec/admin.js +58 -0
  15. package/vendor/spec/canonical.d.ts +3 -0
  16. package/vendor/spec/canonical.js +36 -0
  17. package/vendor/spec/diagnostics.d.ts +49 -0
  18. package/vendor/spec/diagnostics.js +500 -0
  19. package/vendor/spec/docs.d.ts +21 -0
  20. package/vendor/spec/docs.js +57 -0
  21. package/vendor/spec/events.d.ts +8 -0
  22. package/vendor/spec/events.js +21 -0
  23. package/vendor/spec/identity-keys.d.ts +36 -0
  24. package/vendor/spec/identity-keys.js +72 -0
  25. package/vendor/spec/index.d.ts +20 -0
  26. package/vendor/spec/index.js +20 -0
  27. package/vendor/spec/local-identity.d.ts +69 -0
  28. package/vendor/spec/local-identity.js +132 -0
  29. package/vendor/spec/network-policy.d.ts +16 -0
  30. package/vendor/spec/network-policy.js +50 -0
  31. package/vendor/spec/public-assets.d.ts +153 -0
  32. package/vendor/spec/public-assets.js +166 -0
  33. package/vendor/spec/review.d.ts +82 -0
  34. package/vendor/spec/review.js +175 -0
  35. package/vendor/spec/route.d.ts +43 -0
  36. package/vendor/spec/route.js +87 -0
  37. package/vendor/spec/schema-lifecycle.d.ts +6 -0
  38. package/vendor/spec/schema-lifecycle.js +59 -0
  39. package/vendor/spec/schema-plan.d.ts +98 -0
  40. package/vendor/spec/schema-plan.js +194 -0
  41. package/vendor/spec/schema.d.ts +166 -0
  42. package/vendor/spec/schema.js +409 -0
  43. package/vendor/spec/sql-expression.d.ts +91 -0
  44. package/vendor/spec/sql-expression.js +650 -0
  45. package/vendor/spec/state-export.d.ts +143 -0
  46. package/vendor/spec/state-export.js +341 -0
  47. package/vendor/spec/storage.d.ts +61 -0
  48. package/vendor/spec/storage.js +120 -0
  49. package/vendor/spec/table-ddl.d.ts +162 -0
  50. package/vendor/spec/table-ddl.js +508 -0
  51. package/vendor/spec/types.d.ts +275 -0
  52. package/vendor/spec/types.js +11 -0
  53. package/vendor/spec/value.d.ts +22 -0
  54. package/vendor/spec/value.js +72 -0
@@ -0,0 +1,98 @@
1
+ import type { ApplicationSchemaIdentityV0, NormalizedApplicationManifestV0, ScalarType } from './types.js';
2
+ export declare const SCHEMA_PROTOCOL: "xeer.schema.v0";
3
+ export type NormalizedDatabaseSchemaV0 = NormalizedApplicationManifestV0['database'];
4
+ /**
5
+ * Field keys with no dedicated step. Each one changes what the column's DDL says, so a change to any
6
+ * of them has to reach the plan — otherwise a schema whose hash moved would produce no steps and be
7
+ * classified as an unchanged schema that somehow needs a version bump.
8
+ */
9
+ export declare const FIELD_ATTRIBUTES: readonly ["collate", "default", "enum", "generated", "onDelete", "onUpdate", "table", "unique"];
10
+ export type FieldAttribute = (typeof FIELD_ATTRIBUTES)[number];
11
+ export type SchemaPlanStepV0 = {
12
+ kind: 'table.add';
13
+ table: string;
14
+ } | {
15
+ kind: 'table.remove';
16
+ table: string;
17
+ } | {
18
+ kind: 'table.constraint';
19
+ table: string;
20
+ constraint: 'unique' | 'checks';
21
+ from: unknown;
22
+ to: unknown;
23
+ } | {
24
+ kind: 'field.add';
25
+ table: string;
26
+ field: string;
27
+ optional: boolean;
28
+ } | {
29
+ kind: 'field.remove';
30
+ table: string;
31
+ field: string;
32
+ } | {
33
+ kind: 'field.type';
34
+ table: string;
35
+ field: string;
36
+ from: ScalarType;
37
+ to: ScalarType;
38
+ } | {
39
+ kind: 'field.optional';
40
+ table: string;
41
+ field: string;
42
+ from: boolean;
43
+ to: boolean;
44
+ } | {
45
+ kind: 'field.maxLength';
46
+ table: string;
47
+ field: string;
48
+ from: number | null;
49
+ to: number | null;
50
+ } | {
51
+ kind: 'field.attribute';
52
+ table: string;
53
+ field: string;
54
+ attribute: FieldAttribute;
55
+ from: unknown;
56
+ to: unknown;
57
+ } | {
58
+ kind: 'index.add';
59
+ table: string;
60
+ index: string;
61
+ fields: string[];
62
+ } | {
63
+ kind: 'index.remove';
64
+ table: string;
65
+ index: string;
66
+ fields: string[];
67
+ } | {
68
+ kind: 'index.change';
69
+ table: string;
70
+ index: string;
71
+ from: string[];
72
+ to: string[];
73
+ } | {
74
+ kind: 'index.attribute';
75
+ table: string;
76
+ index: string;
77
+ attribute: 'unique' | 'where';
78
+ from: unknown;
79
+ to: unknown;
80
+ } | {
81
+ kind: 'unknown.change';
82
+ path: string;
83
+ };
84
+ export interface SchemaPlanV0 {
85
+ protocol: typeof SCHEMA_PROTOCOL;
86
+ application: string;
87
+ from: ApplicationSchemaIdentityV0;
88
+ to: ApplicationSchemaIdentityV0;
89
+ classification: 'unchanged' | 'compatible' | 'incompatible';
90
+ steps: SchemaPlanStepV0[];
91
+ requiresReset: boolean;
92
+ }
93
+ export type SchemaPlanningErrorCode = 'schema_version_regressed' | 'schema_version_unchanged' | 'schema_version_skipped';
94
+ export declare class SchemaPlanningError extends Error {
95
+ readonly code: SchemaPlanningErrorCode;
96
+ constructor(code: SchemaPlanningErrorCode, message: string);
97
+ }
98
+ export declare function planSchemaChangeWithIdentities(application: string, fromSchema: NormalizedDatabaseSchemaV0, from: ApplicationSchemaIdentityV0, toSchema: NormalizedDatabaseSchemaV0, to: ApplicationSchemaIdentityV0): SchemaPlanV0;
@@ -0,0 +1,194 @@
1
+ import { indexTermLabel, normalizedIndex } from './table-ddl.js';
2
+ export const SCHEMA_PROTOCOL = 'xeer.schema.v0';
3
+ /**
4
+ * Field keys with no dedicated step. Each one changes what the column's DDL says, so a change to any
5
+ * of them has to reach the plan — otherwise a schema whose hash moved would produce no steps and be
6
+ * classified as an unchanged schema that somehow needs a version bump.
7
+ */
8
+ export const FIELD_ATTRIBUTES = Object.freeze([
9
+ 'collate', 'default', 'enum', 'generated', 'onDelete', 'onUpdate', 'table', 'unique',
10
+ ]);
11
+ export class SchemaPlanningError extends Error {
12
+ code;
13
+ constructor(code, message) {
14
+ super(message);
15
+ this.code = code;
16
+ this.name = 'SchemaPlanningError';
17
+ }
18
+ }
19
+ function sameArray(left, right) {
20
+ return left.length === right.length && left.every((value, index) => value === right[index]);
21
+ }
22
+ function maxLengthStep(table, field, from, to) {
23
+ if (from === to)
24
+ return null;
25
+ return { kind: 'field.maxLength', table, field, from: from ?? null, to: to ?? null };
26
+ }
27
+ function tableSteps(tableName, from, to) {
28
+ const steps = [];
29
+ const fromFields = new Set(Object.keys(from.fields));
30
+ const toFields = new Set(Object.keys(to.fields));
31
+ for (const field of [...fromFields].filter((name) => !toFields.has(name)).sort()) {
32
+ steps.push({ kind: 'field.remove', table: tableName, field });
33
+ }
34
+ for (const field of [...toFields].filter((name) => !fromFields.has(name)).sort()) {
35
+ steps.push({ kind: 'field.add', table: tableName, field, optional: to.fields[field].optional ?? false });
36
+ }
37
+ for (const field of [...fromFields].filter((name) => toFields.has(name)).sort()) {
38
+ const before = from.fields[field];
39
+ const after = to.fields[field];
40
+ if (before.type !== after.type) {
41
+ steps.push({ kind: 'field.type', table: tableName, field, from: before.type, to: after.type });
42
+ }
43
+ const beforeOptional = before.optional ?? false;
44
+ const afterOptional = after.optional ?? false;
45
+ if (beforeOptional !== afterOptional) {
46
+ steps.push({ kind: 'field.optional', table: tableName, field, from: beforeOptional, to: afterOptional });
47
+ }
48
+ const length = maxLengthStep(tableName, field, before.maxLength, after.maxLength);
49
+ if (length)
50
+ steps.push(length);
51
+ for (const attribute of FIELD_ATTRIBUTES) {
52
+ if (sameUnknownValue(before[attribute], after[attribute]))
53
+ continue;
54
+ steps.push({ kind: 'field.attribute', table: tableName, field, attribute,
55
+ from: before[attribute] ?? null, to: after[attribute] ?? null });
56
+ }
57
+ }
58
+ for (const constraint of ['unique', 'checks']) {
59
+ if (sameUnknownValue(from[constraint], to[constraint]))
60
+ continue;
61
+ steps.push({ kind: 'table.constraint', table: tableName, constraint,
62
+ from: from[constraint] ?? null, to: to[constraint] ?? null });
63
+ }
64
+ // Indexes are compared through their normalized form, so `["slug"]` and `{ columns: ["slug"] }`
65
+ // are one index written two ways rather than a change from one to the other.
66
+ const terms = (index) => normalizedIndex(index).columns.map(indexTermLabel);
67
+ const fromIndexes = from.indexes ?? {};
68
+ const toIndexes = to.indexes ?? {};
69
+ const fromNames = new Set(Object.keys(fromIndexes));
70
+ const toNames = new Set(Object.keys(toIndexes));
71
+ for (const index of [...fromNames].filter((name) => !toNames.has(name)).sort()) {
72
+ steps.push({ kind: 'index.remove', table: tableName, index, fields: terms(fromIndexes[index]) });
73
+ }
74
+ for (const index of [...toNames].filter((name) => !fromNames.has(name)).sort()) {
75
+ steps.push({ kind: 'index.add', table: tableName, index, fields: terms(toIndexes[index]) });
76
+ }
77
+ for (const index of [...fromNames].filter((name) => toNames.has(name)).sort()) {
78
+ const before = normalizedIndex(fromIndexes[index]);
79
+ const after = normalizedIndex(toIndexes[index]);
80
+ if (!sameArray(terms(fromIndexes[index]), terms(toIndexes[index]))) {
81
+ steps.push({ kind: 'index.change', table: tableName, index,
82
+ from: terms(fromIndexes[index]), to: terms(toIndexes[index]) });
83
+ }
84
+ for (const attribute of ['unique', 'where']) {
85
+ if (before[attribute] === after[attribute])
86
+ continue;
87
+ steps.push({ kind: 'index.attribute', table: tableName, index, attribute,
88
+ from: before[attribute], to: after[attribute] });
89
+ }
90
+ }
91
+ return steps;
92
+ }
93
+ /**
94
+ * Whether a step leaves the rows already stored valid. Nothing in the extended vocabulary does,
95
+ * with one exception: a DEFAULT decides what a later insert that omits the column receives and says
96
+ * nothing about the rows already there, so changing one cannot invalidate them.
97
+ */
98
+ function isCompatible(step) {
99
+ if (step.kind === 'table.add' || step.kind === 'index.add')
100
+ return true;
101
+ if (step.kind === 'field.add')
102
+ return step.optional;
103
+ if (step.kind === 'field.optional')
104
+ return step.from === false && step.to === true;
105
+ if (step.kind === 'field.maxLength') {
106
+ return step.from !== null && (step.to === null || step.to > step.from);
107
+ }
108
+ if (step.kind === 'field.attribute')
109
+ return step.attribute === 'default';
110
+ return false;
111
+ }
112
+ function sameUnknownValue(left, right) {
113
+ if (Object.is(left, right))
114
+ return true;
115
+ if (typeof left !== typeof right || left === null || right === null)
116
+ return false;
117
+ if (Array.isArray(left) || Array.isArray(right)) {
118
+ return Array.isArray(left) && Array.isArray(right) && left.length === right.length
119
+ && left.every((value, index) => sameUnknownValue(value, right[index]));
120
+ }
121
+ if (typeof left !== 'object')
122
+ return false;
123
+ const before = left;
124
+ const after = right;
125
+ const beforeKeys = Object.keys(before).sort();
126
+ const afterKeys = Object.keys(after).sort();
127
+ return sameArray(beforeKeys, afterKeys)
128
+ && beforeKeys.every((key) => sameUnknownValue(before[key], after[key]));
129
+ }
130
+ function unknownKeySteps(path, from, to, allowed) {
131
+ const before = typeof from === 'object' && from !== null && !Array.isArray(from)
132
+ ? from : {};
133
+ const after = typeof to === 'object' && to !== null && !Array.isArray(to)
134
+ ? to : {};
135
+ const known = new Set(allowed);
136
+ return [...new Set([...Object.keys(before), ...Object.keys(after)])]
137
+ .filter((key) => !known.has(key))
138
+ .sort()
139
+ .filter((key) => {
140
+ const beforeHas = Object.hasOwn(before, key);
141
+ const afterHas = Object.hasOwn(after, key);
142
+ return beforeHas !== afterHas || !sameUnknownValue(before[key], after[key]);
143
+ })
144
+ .map((key) => ({ kind: 'unknown.change', path: `${path}.${key}` }));
145
+ }
146
+ function unknownSchemaSteps(fromSchema, toSchema) {
147
+ const steps = unknownKeySteps('database', fromSchema, toSchema, ['version', 'tables']);
148
+ const tableNames = [...new Set([...Object.keys(fromSchema.tables), ...Object.keys(toSchema.tables)])].sort();
149
+ for (const tableName of tableNames) {
150
+ const beforeTable = fromSchema.tables[tableName];
151
+ const afterTable = toSchema.tables[tableName];
152
+ steps.push(...unknownKeySteps(`database.tables.${tableName}`, beforeTable, afterTable, ['fields', 'indexes', 'unique', 'checks']));
153
+ const beforeFields = beforeTable?.fields ?? {};
154
+ const afterFields = afterTable?.fields ?? {};
155
+ const fieldNames = [...new Set([...Object.keys(beforeFields), ...Object.keys(afterFields)])].sort();
156
+ for (const fieldName of fieldNames) {
157
+ steps.push(...unknownKeySteps(`database.tables.${tableName}.fields.${fieldName}`, beforeFields[fieldName], afterFields[fieldName], ['type', 'optional', 'maxLength', ...FIELD_ATTRIBUTES]));
158
+ }
159
+ }
160
+ return steps;
161
+ }
162
+ export function planSchemaChangeWithIdentities(application, fromSchema, from, toSchema, to) {
163
+ const unknownSteps = unknownSchemaSteps(fromSchema, toSchema);
164
+ if (to.applicationSchemaVersion < from.applicationSchemaVersion) {
165
+ throw new SchemaPlanningError('schema_version_regressed', `Application schema version cannot regress from ${from.applicationSchemaVersion} to ${to.applicationSchemaVersion}.`);
166
+ }
167
+ if (to.applicationSchemaVersion === from.applicationSchemaVersion
168
+ && (to.schemaHash !== from.schemaHash || unknownSteps.length > 0)) {
169
+ throw new SchemaPlanningError('schema_version_unchanged', `Application schema changed without increasing database.version from ${from.applicationSchemaVersion}.`);
170
+ }
171
+ if (to.applicationSchemaVersion > from.applicationSchemaVersion + 1) {
172
+ throw new SchemaPlanningError('schema_version_skipped', `Application schema version must advance one step from ${from.applicationSchemaVersion}; received ${to.applicationSchemaVersion}.`);
173
+ }
174
+ if (to.schemaHash === from.schemaHash && unknownSteps.length === 0
175
+ && to.applicationSchemaVersion === from.applicationSchemaVersion) {
176
+ return { protocol: SCHEMA_PROTOCOL, application, from, to,
177
+ classification: 'unchanged', steps: [], requiresReset: false };
178
+ }
179
+ const steps = [...unknownSteps];
180
+ const fromTables = new Set(Object.keys(fromSchema.tables));
181
+ const toTables = new Set(Object.keys(toSchema.tables));
182
+ for (const table of [...fromTables].filter((name) => !toTables.has(name)).sort()) {
183
+ steps.push({ kind: 'table.remove', table });
184
+ }
185
+ for (const table of [...toTables].filter((name) => !fromTables.has(name)).sort()) {
186
+ steps.push({ kind: 'table.add', table });
187
+ }
188
+ for (const table of [...fromTables].filter((name) => toTables.has(name)).sort()) {
189
+ steps.push(...tableSteps(table, fromSchema.tables[table], toSchema.tables[table]));
190
+ }
191
+ const classification = steps.every(isCompatible) ? 'compatible' : 'incompatible';
192
+ return { protocol: SCHEMA_PROTOCOL, application, from, to, classification, steps,
193
+ requiresReset: classification === 'incompatible' };
194
+ }
@@ -0,0 +1,166 @@
1
+ import { z } from 'zod';
2
+ import { type ApplicationManifestV0, type NormalizedApplicationManifestV0 } from './types.js';
3
+ /** The normalized database fragment embedded in artifacts and review metadata. */
4
+ export declare const normalizedDatabaseSchema: z.ZodObject<{
5
+ version: z.ZodNumber;
6
+ tables: z.ZodRecord<z.ZodString, z.ZodObject<{
7
+ fields: z.ZodRecord<z.ZodString, z.ZodObject<{
8
+ type: z.ZodEnum<{
9
+ string: "string";
10
+ number: "number";
11
+ boolean: "boolean";
12
+ datetime: "datetime";
13
+ bytes: "bytes";
14
+ json: "json";
15
+ ref: "ref";
16
+ }>;
17
+ optional: z.ZodOptional<z.ZodBoolean>;
18
+ maxLength: z.ZodOptional<z.ZodNumber>;
19
+ unique: z.ZodOptional<z.ZodBoolean>;
20
+ enum: z.ZodOptional<z.ZodArray<z.ZodString>>;
21
+ default: z.ZodOptional<z.ZodUnion<readonly [z.ZodString, z.ZodNumber, z.ZodBoolean]>>;
22
+ collate: z.ZodOptional<z.ZodEnum<{
23
+ binary: "binary";
24
+ nocase: "nocase";
25
+ rtrim: "rtrim";
26
+ }>>;
27
+ table: z.ZodOptional<z.ZodString>;
28
+ onDelete: z.ZodOptional<z.ZodEnum<{
29
+ noAction: "noAction";
30
+ restrict: "restrict";
31
+ cascade: "cascade";
32
+ setNull: "setNull";
33
+ setDefault: "setDefault";
34
+ }>>;
35
+ onUpdate: z.ZodOptional<z.ZodEnum<{
36
+ noAction: "noAction";
37
+ restrict: "restrict";
38
+ cascade: "cascade";
39
+ setNull: "setNull";
40
+ setDefault: "setDefault";
41
+ }>>;
42
+ generated: z.ZodOptional<z.ZodObject<{
43
+ expression: z.ZodString;
44
+ stored: z.ZodOptional<z.ZodBoolean>;
45
+ }, z.core.$strict>>;
46
+ }, z.core.$strict>>;
47
+ indexes: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnion<readonly [z.ZodArray<z.ZodString>, z.ZodObject<{
48
+ columns: z.ZodArray<z.ZodUnion<readonly [z.ZodString, z.ZodObject<{
49
+ column: z.ZodString;
50
+ collate: z.ZodOptional<z.ZodEnum<{
51
+ binary: "binary";
52
+ nocase: "nocase";
53
+ rtrim: "rtrim";
54
+ }>>;
55
+ desc: z.ZodOptional<z.ZodBoolean>;
56
+ }, z.core.$strict>, z.ZodObject<{
57
+ expression: z.ZodString;
58
+ desc: z.ZodOptional<z.ZodBoolean>;
59
+ }, z.core.$strict>]>>;
60
+ unique: z.ZodOptional<z.ZodBoolean>;
61
+ where: z.ZodOptional<z.ZodString>;
62
+ }, z.core.$strict>]>>>;
63
+ unique: z.ZodOptional<z.ZodArray<z.ZodArray<z.ZodString>>>;
64
+ checks: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodString>>;
65
+ }, z.core.$strict>>;
66
+ }, z.core.$strict>;
67
+ export declare const applicationManifestSchema: z.ZodObject<{
68
+ $schema: z.ZodOptional<z.ZodString>;
69
+ format: z.ZodLiteral<"xeer.application-source.v0">;
70
+ name: z.ZodString;
71
+ entrypoints: z.ZodObject<{
72
+ client: z.ZodString;
73
+ server: z.ZodString;
74
+ }, z.core.$strict>;
75
+ app: z.ZodOptional<z.ZodObject<{
76
+ spa: z.ZodOptional<z.ZodBoolean>;
77
+ title: z.ZodOptional<z.ZodString>;
78
+ language: z.ZodOptional<z.ZodString>;
79
+ description: z.ZodOptional<z.ZodString>;
80
+ favicon: z.ZodOptional<z.ZodString>;
81
+ }, z.core.$strict>>;
82
+ database: z.ZodOptional<z.ZodObject<{
83
+ version: z.ZodOptional<z.ZodNumber>;
84
+ tables: z.ZodRecord<z.ZodString, z.ZodObject<{
85
+ fields: z.ZodRecord<z.ZodString, z.ZodObject<{
86
+ type: z.ZodEnum<{
87
+ string: "string";
88
+ number: "number";
89
+ boolean: "boolean";
90
+ datetime: "datetime";
91
+ bytes: "bytes";
92
+ json: "json";
93
+ ref: "ref";
94
+ }>;
95
+ optional: z.ZodOptional<z.ZodBoolean>;
96
+ maxLength: z.ZodOptional<z.ZodNumber>;
97
+ unique: z.ZodOptional<z.ZodBoolean>;
98
+ enum: z.ZodOptional<z.ZodArray<z.ZodString>>;
99
+ default: z.ZodOptional<z.ZodUnion<readonly [z.ZodString, z.ZodNumber, z.ZodBoolean]>>;
100
+ collate: z.ZodOptional<z.ZodEnum<{
101
+ binary: "binary";
102
+ nocase: "nocase";
103
+ rtrim: "rtrim";
104
+ }>>;
105
+ table: z.ZodOptional<z.ZodString>;
106
+ onDelete: z.ZodOptional<z.ZodEnum<{
107
+ noAction: "noAction";
108
+ restrict: "restrict";
109
+ cascade: "cascade";
110
+ setNull: "setNull";
111
+ setDefault: "setDefault";
112
+ }>>;
113
+ onUpdate: z.ZodOptional<z.ZodEnum<{
114
+ noAction: "noAction";
115
+ restrict: "restrict";
116
+ cascade: "cascade";
117
+ setNull: "setNull";
118
+ setDefault: "setDefault";
119
+ }>>;
120
+ generated: z.ZodOptional<z.ZodObject<{
121
+ expression: z.ZodString;
122
+ stored: z.ZodOptional<z.ZodBoolean>;
123
+ }, z.core.$strict>>;
124
+ }, z.core.$strict>>;
125
+ indexes: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnion<readonly [z.ZodArray<z.ZodString>, z.ZodObject<{
126
+ columns: z.ZodArray<z.ZodUnion<readonly [z.ZodString, z.ZodObject<{
127
+ column: z.ZodString;
128
+ collate: z.ZodOptional<z.ZodEnum<{
129
+ binary: "binary";
130
+ nocase: "nocase";
131
+ rtrim: "rtrim";
132
+ }>>;
133
+ desc: z.ZodOptional<z.ZodBoolean>;
134
+ }, z.core.$strict>, z.ZodObject<{
135
+ expression: z.ZodString;
136
+ desc: z.ZodOptional<z.ZodBoolean>;
137
+ }, z.core.$strict>]>>;
138
+ unique: z.ZodOptional<z.ZodBoolean>;
139
+ where: z.ZodOptional<z.ZodString>;
140
+ }, z.core.$strict>]>>>;
141
+ unique: z.ZodOptional<z.ZodArray<z.ZodArray<z.ZodString>>>;
142
+ checks: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodString>>;
143
+ }, z.core.$strict>>;
144
+ }, z.core.$strict>>;
145
+ storage: z.ZodOptional<z.ZodObject<{
146
+ maxObjectBytes: z.ZodOptional<z.ZodNumber>;
147
+ readBytes: z.ZodOptional<z.ZodNumber>;
148
+ writeBytes: z.ZodOptional<z.ZodNumber>;
149
+ }, z.core.$strict>>;
150
+ capabilities: z.ZodOptional<z.ZodArray<z.ZodEnum<{
151
+ database: "database";
152
+ storage: "storage";
153
+ }>>>;
154
+ budgets: z.ZodOptional<z.ZodObject<{
155
+ queryRows: z.ZodOptional<z.ZodNumber>;
156
+ mutationWrites: z.ZodOptional<z.ZodNumber>;
157
+ requestBytes: z.ZodOptional<z.ZodNumber>;
158
+ responseBytes: z.ZodOptional<z.ZodNumber>;
159
+ liveConnections: z.ZodOptional<z.ZodNumber>;
160
+ }, z.core.$strict>>;
161
+ }, z.core.$strict>;
162
+ /** Stable editor-facing schema location emitted into every scaffolded `xeer.app.json`. */
163
+ export declare const APPLICATION_MANIFEST_SCHEMA_URL: "https://docs.xeer.run/application-v0.schema.json";
164
+ export declare const applicationManifestJsonSchema: Readonly<Record<string, unknown>>;
165
+ export declare function parseApplicationManifest(value: unknown): ApplicationManifestV0;
166
+ export declare function normalizeApplicationManifest(manifest: ApplicationManifestV0): NormalizedApplicationManifestV0;