ont-run 0.0.1
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 +228 -0
- package/bin/ont.ts +5 -0
- package/dist/bin/ont.d.ts +2 -0
- package/dist/bin/ont.js +13667 -0
- package/dist/index.js +23152 -0
- package/dist/src/browser/server.d.ts +16 -0
- package/dist/src/browser/transform.d.ts +87 -0
- package/dist/src/cli/commands/init.d.ts +12 -0
- package/dist/src/cli/commands/review.d.ts +17 -0
- package/dist/src/cli/index.d.ts +1 -0
- package/dist/src/cli/utils/config-loader.d.ts +13 -0
- package/dist/src/config/categorical.d.ts +76 -0
- package/dist/src/config/define.d.ts +46 -0
- package/dist/src/config/index.d.ts +4 -0
- package/dist/src/config/schema.d.ts +162 -0
- package/dist/src/config/types.d.ts +94 -0
- package/dist/src/index.d.ts +37 -0
- package/dist/src/lockfile/differ.d.ts +11 -0
- package/dist/src/lockfile/hasher.d.ts +31 -0
- package/dist/src/lockfile/index.d.ts +53 -0
- package/dist/src/lockfile/types.d.ts +90 -0
- package/dist/src/runtime/index.d.ts +28 -0
- package/dist/src/server/api/index.d.ts +20 -0
- package/dist/src/server/api/middleware.d.ts +34 -0
- package/dist/src/server/api/router.d.ts +18 -0
- package/dist/src/server/mcp/index.d.ts +23 -0
- package/dist/src/server/mcp/tools.d.ts +35 -0
- package/dist/src/server/resolver.d.ts +30 -0
- package/dist/src/server/start.d.ts +37 -0
- package/package.json +63 -0
- package/src/browser/server.ts +2567 -0
- package/src/browser/transform.ts +473 -0
- package/src/cli/commands/init.ts +226 -0
- package/src/cli/commands/review.ts +126 -0
- package/src/cli/index.ts +19 -0
- package/src/cli/utils/config-loader.ts +78 -0
- package/src/config/categorical.ts +101 -0
- package/src/config/define.ts +78 -0
- package/src/config/index.ts +23 -0
- package/src/config/schema.ts +196 -0
- package/src/config/types.ts +121 -0
- package/src/index.ts +53 -0
- package/src/lockfile/differ.ts +242 -0
- package/src/lockfile/hasher.ts +175 -0
- package/src/lockfile/index.ts +159 -0
- package/src/lockfile/types.ts +95 -0
- package/src/runtime/index.ts +114 -0
- package/src/server/api/index.ts +92 -0
- package/src/server/api/middleware.ts +118 -0
- package/src/server/api/router.ts +102 -0
- package/src/server/mcp/index.ts +182 -0
- package/src/server/mcp/tools.ts +199 -0
- package/src/server/resolver.ts +109 -0
- package/src/server/start.ts +151 -0
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import type { OntologyConfig } from "../config/types.js";
|
|
2
|
+
import type { OntologyDiff } from "../lockfile/types.js";
|
|
3
|
+
export interface BrowserServerOptions {
|
|
4
|
+
config: OntologyConfig;
|
|
5
|
+
/** Diff data for review mode (null = browse-only, no changes) */
|
|
6
|
+
diff?: OntologyDiff | null;
|
|
7
|
+
/** Directory to write the lockfile to on approval */
|
|
8
|
+
configDir?: string;
|
|
9
|
+
port?: number;
|
|
10
|
+
openBrowser?: boolean;
|
|
11
|
+
}
|
|
12
|
+
export interface BrowserServerResult {
|
|
13
|
+
/** Whether changes were approved (only set if there were changes) */
|
|
14
|
+
approved?: boolean;
|
|
15
|
+
}
|
|
16
|
+
export declare function startBrowserServer(options: BrowserServerOptions): Promise<BrowserServerResult>;
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
import type { OntologyConfig } from "../config/types.js";
|
|
2
|
+
import type { OntologyDiff, FunctionChange } from "../lockfile/types.js";
|
|
3
|
+
export type NodeType = "entity" | "function" | "accessGroup";
|
|
4
|
+
export type EdgeType = "operates-on" | "requires-access" | "depends-on";
|
|
5
|
+
export type ChangeStatus = "added" | "removed" | "modified" | "unchanged";
|
|
6
|
+
export interface GraphNode {
|
|
7
|
+
id: string;
|
|
8
|
+
type: NodeType;
|
|
9
|
+
label: string;
|
|
10
|
+
description: string;
|
|
11
|
+
metadata: {
|
|
12
|
+
inputs?: Record<string, unknown>;
|
|
13
|
+
outputs?: Record<string, unknown>;
|
|
14
|
+
resolver?: string;
|
|
15
|
+
functionCount?: number;
|
|
16
|
+
};
|
|
17
|
+
}
|
|
18
|
+
export interface GraphEdge {
|
|
19
|
+
id: string;
|
|
20
|
+
source: string;
|
|
21
|
+
target: string;
|
|
22
|
+
type: EdgeType;
|
|
23
|
+
label?: string;
|
|
24
|
+
}
|
|
25
|
+
export interface GraphData {
|
|
26
|
+
nodes: GraphNode[];
|
|
27
|
+
edges: GraphEdge[];
|
|
28
|
+
meta: {
|
|
29
|
+
ontologyName: string;
|
|
30
|
+
totalFunctions: number;
|
|
31
|
+
totalEntities: number;
|
|
32
|
+
totalAccessGroups: number;
|
|
33
|
+
};
|
|
34
|
+
}
|
|
35
|
+
export interface EnhancedGraphNode extends GraphNode {
|
|
36
|
+
changeStatus: ChangeStatus;
|
|
37
|
+
changeDetails?: FunctionChange;
|
|
38
|
+
}
|
|
39
|
+
export interface EnhancedGraphData {
|
|
40
|
+
nodes: EnhancedGraphNode[];
|
|
41
|
+
edges: GraphEdge[];
|
|
42
|
+
meta: GraphData["meta"] & {
|
|
43
|
+
hasChanges: boolean;
|
|
44
|
+
addedCount: number;
|
|
45
|
+
removedCount: number;
|
|
46
|
+
modifiedCount: number;
|
|
47
|
+
};
|
|
48
|
+
diff: OntologyDiff | null;
|
|
49
|
+
}
|
|
50
|
+
/**
|
|
51
|
+
* Transform OntologyConfig into graph data for visualization
|
|
52
|
+
*/
|
|
53
|
+
export declare function transformToGraphData(config: OntologyConfig): GraphData;
|
|
54
|
+
/**
|
|
55
|
+
* Search nodes by label or description
|
|
56
|
+
*/
|
|
57
|
+
export declare function searchNodes(graphData: GraphData, query: string): Array<{
|
|
58
|
+
id: string;
|
|
59
|
+
type: NodeType;
|
|
60
|
+
label: string;
|
|
61
|
+
matchType: "label" | "description";
|
|
62
|
+
}>;
|
|
63
|
+
/**
|
|
64
|
+
* Get detailed node information including connections
|
|
65
|
+
*/
|
|
66
|
+
export declare function getNodeDetails(graphData: GraphData, nodeId: string): {
|
|
67
|
+
node: GraphNode | null;
|
|
68
|
+
connections: {
|
|
69
|
+
accessGroups: string[];
|
|
70
|
+
entities: string[];
|
|
71
|
+
dependsOn: Array<{
|
|
72
|
+
functionName: string;
|
|
73
|
+
path: string;
|
|
74
|
+
}>;
|
|
75
|
+
dependedOnBy: string[];
|
|
76
|
+
functions: Array<{
|
|
77
|
+
name: string;
|
|
78
|
+
description: string;
|
|
79
|
+
inputs?: Record<string, unknown>;
|
|
80
|
+
outputs?: Record<string, unknown>;
|
|
81
|
+
}>;
|
|
82
|
+
};
|
|
83
|
+
};
|
|
84
|
+
/**
|
|
85
|
+
* Enhance graph data with diff information for review mode
|
|
86
|
+
*/
|
|
87
|
+
export declare function enhanceWithDiff(graphData: GraphData, diff: OntologyDiff | null): EnhancedGraphData;
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
export declare const reviewCommand: import("citty").CommandDef<{
|
|
2
|
+
"auto-approve": {
|
|
3
|
+
type: "boolean";
|
|
4
|
+
description: string;
|
|
5
|
+
default: false;
|
|
6
|
+
};
|
|
7
|
+
"print-only": {
|
|
8
|
+
type: "boolean";
|
|
9
|
+
description: string;
|
|
10
|
+
default: false;
|
|
11
|
+
};
|
|
12
|
+
cloud: {
|
|
13
|
+
type: "boolean";
|
|
14
|
+
description: string;
|
|
15
|
+
default: false;
|
|
16
|
+
};
|
|
17
|
+
}>;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare function run(): void;
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import type { OntologyConfig } from "../../config/types.js";
|
|
2
|
+
/**
|
|
3
|
+
* Find the ontology config file in the given directory or its parents
|
|
4
|
+
*/
|
|
5
|
+
export declare function findConfigFile(startDir?: string): string | null;
|
|
6
|
+
/**
|
|
7
|
+
* Load the ontology config from a file
|
|
8
|
+
*/
|
|
9
|
+
export declare function loadConfig(configPath?: string): Promise<{
|
|
10
|
+
config: OntologyConfig;
|
|
11
|
+
configDir: string;
|
|
12
|
+
configPath: string;
|
|
13
|
+
}>;
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
/**
|
|
3
|
+
* Symbol for storing fieldFrom metadata on Zod schemas
|
|
4
|
+
*/
|
|
5
|
+
export declare const FIELD_FROM_METADATA: unique symbol;
|
|
6
|
+
/**
|
|
7
|
+
* Metadata stored on fieldFrom Zod schemas
|
|
8
|
+
*/
|
|
9
|
+
export interface FieldFromMetadata {
|
|
10
|
+
/** Name of the function that provides options for this field */
|
|
11
|
+
functionName: string;
|
|
12
|
+
}
|
|
13
|
+
/**
|
|
14
|
+
* Type for a Zod string with fieldFrom metadata
|
|
15
|
+
*/
|
|
16
|
+
export type FieldFromString = z.ZodString & {
|
|
17
|
+
[FIELD_FROM_METADATA]: FieldFromMetadata;
|
|
18
|
+
};
|
|
19
|
+
/**
|
|
20
|
+
* Create a string field that gets its options from another function.
|
|
21
|
+
*
|
|
22
|
+
* The referenced function should return `{ value: string, label: string }[]`.
|
|
23
|
+
* - If the function has empty inputs `z.object({})`, it's treated as **bulk** (all options fetched at once)
|
|
24
|
+
* - If the function has a `query` input, it's treated as **autocomplete** (options searched)
|
|
25
|
+
*
|
|
26
|
+
* @param functionName - Name of the function that provides options
|
|
27
|
+
*
|
|
28
|
+
* @example
|
|
29
|
+
* ```ts
|
|
30
|
+
* defineOntology({
|
|
31
|
+
* functions: {
|
|
32
|
+
* // Bulk options source (empty inputs)
|
|
33
|
+
* getUserStatuses: {
|
|
34
|
+
* description: 'Get available user statuses',
|
|
35
|
+
* access: ['admin'],
|
|
36
|
+
* entities: [],
|
|
37
|
+
* inputs: z.object({}),
|
|
38
|
+
* outputs: z.array(z.object({ value: z.string(), label: z.string() })),
|
|
39
|
+
* resolver: './resolvers/options/userStatuses.ts',
|
|
40
|
+
* },
|
|
41
|
+
*
|
|
42
|
+
* // Autocomplete source (has query input)
|
|
43
|
+
* searchTeams: {
|
|
44
|
+
* description: 'Search for teams',
|
|
45
|
+
* access: ['admin'],
|
|
46
|
+
* entities: [],
|
|
47
|
+
* inputs: z.object({ query: z.string() }),
|
|
48
|
+
* outputs: z.array(z.object({ value: z.string(), label: z.string() })),
|
|
49
|
+
* resolver: './resolvers/options/searchTeams.ts',
|
|
50
|
+
* },
|
|
51
|
+
*
|
|
52
|
+
* // Function using fieldFrom
|
|
53
|
+
* createUser: {
|
|
54
|
+
* description: 'Create a user',
|
|
55
|
+
* access: ['admin'],
|
|
56
|
+
* entities: ['User'],
|
|
57
|
+
* inputs: z.object({
|
|
58
|
+
* name: z.string(),
|
|
59
|
+
* status: fieldFrom('getUserStatuses'),
|
|
60
|
+
* team: fieldFrom('searchTeams'),
|
|
61
|
+
* }),
|
|
62
|
+
* resolver: './resolvers/createUser.ts',
|
|
63
|
+
* },
|
|
64
|
+
* },
|
|
65
|
+
* })
|
|
66
|
+
* ```
|
|
67
|
+
*/
|
|
68
|
+
export declare function fieldFrom(functionName: string): FieldFromString;
|
|
69
|
+
/**
|
|
70
|
+
* Check if a Zod schema has fieldFrom metadata
|
|
71
|
+
*/
|
|
72
|
+
export declare function hasFieldFromMetadata(schema: unknown): schema is FieldFromString;
|
|
73
|
+
/**
|
|
74
|
+
* Extract fieldFrom metadata from a Zod schema
|
|
75
|
+
*/
|
|
76
|
+
export declare function getFieldFromMetadata(schema: unknown): FieldFromMetadata | null;
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import type { OntologyConfig, FunctionDefinition, AccessGroupConfig, EnvironmentConfig, EntityDefinition, AuthFunction } from "./types.js";
|
|
2
|
+
/**
|
|
3
|
+
* Define an Ontology configuration with full type inference.
|
|
4
|
+
*
|
|
5
|
+
* @example
|
|
6
|
+
* ```ts
|
|
7
|
+
* import { defineOntology, fieldFrom } from 'ont-run';
|
|
8
|
+
* import { z } from 'zod';
|
|
9
|
+
*
|
|
10
|
+
* export default defineOntology({
|
|
11
|
+
* name: 'my-api',
|
|
12
|
+
* environments: {
|
|
13
|
+
* dev: { debug: true },
|
|
14
|
+
* prod: { debug: false },
|
|
15
|
+
* },
|
|
16
|
+
* auth: async (req) => {
|
|
17
|
+
* const token = req.headers.get('Authorization');
|
|
18
|
+
* return token ? ['admin'] : ['public'];
|
|
19
|
+
* },
|
|
20
|
+
* accessGroups: {
|
|
21
|
+
* public: { description: 'Unauthenticated users' },
|
|
22
|
+
* admin: { description: 'Administrators' },
|
|
23
|
+
* },
|
|
24
|
+
* entities: {
|
|
25
|
+
* User: { description: 'A user account' },
|
|
26
|
+
* },
|
|
27
|
+
* functions: {
|
|
28
|
+
* getUser: {
|
|
29
|
+
* description: 'Get a user by ID',
|
|
30
|
+
* access: ['public', 'admin'],
|
|
31
|
+
* entities: ['User'],
|
|
32
|
+
* inputs: z.object({ id: z.string() }),
|
|
33
|
+
* resolver: './resolvers/getUser.ts',
|
|
34
|
+
* },
|
|
35
|
+
* },
|
|
36
|
+
* });
|
|
37
|
+
* ```
|
|
38
|
+
*/
|
|
39
|
+
export declare function defineOntology<TGroups extends string, TEntities extends string, TFunctions extends Record<string, FunctionDefinition<TGroups, TEntities>>>(config: {
|
|
40
|
+
name: string;
|
|
41
|
+
environments: Record<string, EnvironmentConfig>;
|
|
42
|
+
auth: AuthFunction;
|
|
43
|
+
accessGroups: Record<TGroups, AccessGroupConfig>;
|
|
44
|
+
entities?: Record<TEntities, EntityDefinition>;
|
|
45
|
+
functions: TFunctions;
|
|
46
|
+
}): OntologyConfig<TGroups, TEntities, TFunctions>;
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
export { defineOntology } from "./define.js";
|
|
2
|
+
export { fieldFrom } from "./categorical.js";
|
|
3
|
+
export type { OntologyConfig, FunctionDefinition, AccessGroupConfig, EnvironmentConfig, EntityDefinition, AuthFunction, ResolverContext, ResolverFunction, FieldOption, } from "./types.js";
|
|
4
|
+
export { OntologyConfigSchema, FunctionDefinitionSchema, AccessGroupConfigSchema, EnvironmentConfigSchema, EntityDefinitionSchema, validateAccessGroups, validateEntityReferences, validateFieldFromReferences, } from "./schema.js";
|
|
@@ -0,0 +1,162 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
/**
|
|
3
|
+
* Schema for environment configuration
|
|
4
|
+
*/
|
|
5
|
+
export declare const EnvironmentConfigSchema: z.ZodObject<{
|
|
6
|
+
debug: z.ZodOptional<z.ZodBoolean>;
|
|
7
|
+
}, "passthrough", z.ZodTypeAny, z.objectOutputType<{
|
|
8
|
+
debug: z.ZodOptional<z.ZodBoolean>;
|
|
9
|
+
}, z.ZodTypeAny, "passthrough">, z.objectInputType<{
|
|
10
|
+
debug: z.ZodOptional<z.ZodBoolean>;
|
|
11
|
+
}, z.ZodTypeAny, "passthrough">>;
|
|
12
|
+
/**
|
|
13
|
+
* Schema for access group configuration
|
|
14
|
+
*/
|
|
15
|
+
export declare const AccessGroupConfigSchema: z.ZodObject<{
|
|
16
|
+
description: z.ZodString;
|
|
17
|
+
}, "strip", z.ZodTypeAny, {
|
|
18
|
+
description: string;
|
|
19
|
+
}, {
|
|
20
|
+
description: string;
|
|
21
|
+
}>;
|
|
22
|
+
/**
|
|
23
|
+
* Schema for entity definition
|
|
24
|
+
*/
|
|
25
|
+
export declare const EntityDefinitionSchema: z.ZodObject<{
|
|
26
|
+
description: z.ZodString;
|
|
27
|
+
}, "strip", z.ZodTypeAny, {
|
|
28
|
+
description: string;
|
|
29
|
+
}, {
|
|
30
|
+
description: string;
|
|
31
|
+
}>;
|
|
32
|
+
/**
|
|
33
|
+
* Schema for function definition
|
|
34
|
+
*/
|
|
35
|
+
export declare const FunctionDefinitionSchema: z.ZodObject<{
|
|
36
|
+
description: z.ZodString;
|
|
37
|
+
access: z.ZodArray<z.ZodString, "many">;
|
|
38
|
+
entities: z.ZodArray<z.ZodString, "many">;
|
|
39
|
+
inputs: z.ZodType<z.ZodType<any, z.ZodTypeDef, any>, z.ZodTypeDef, z.ZodType<any, z.ZodTypeDef, any>>;
|
|
40
|
+
outputs: z.ZodOptional<z.ZodType<z.ZodType<any, z.ZodTypeDef, any>, z.ZodTypeDef, z.ZodType<any, z.ZodTypeDef, any>>>;
|
|
41
|
+
resolver: z.ZodString;
|
|
42
|
+
}, "strip", z.ZodTypeAny, {
|
|
43
|
+
description: string;
|
|
44
|
+
access: string[];
|
|
45
|
+
entities: string[];
|
|
46
|
+
inputs: z.ZodType<any, z.ZodTypeDef, any>;
|
|
47
|
+
resolver: string;
|
|
48
|
+
outputs?: z.ZodType<any, z.ZodTypeDef, any> | undefined;
|
|
49
|
+
}, {
|
|
50
|
+
description: string;
|
|
51
|
+
access: string[];
|
|
52
|
+
entities: string[];
|
|
53
|
+
inputs: z.ZodType<any, z.ZodTypeDef, any>;
|
|
54
|
+
resolver: string;
|
|
55
|
+
outputs?: z.ZodType<any, z.ZodTypeDef, any> | undefined;
|
|
56
|
+
}>;
|
|
57
|
+
/**
|
|
58
|
+
* Schema for auth function
|
|
59
|
+
*/
|
|
60
|
+
export declare const AuthFunctionSchema: z.ZodFunction<z.ZodTuple<[z.ZodType<Request, z.ZodTypeDef, Request>], z.ZodUnknown>, z.ZodUnion<[z.ZodArray<z.ZodString, "many">, z.ZodPromise<z.ZodArray<z.ZodString, "many">>]>>;
|
|
61
|
+
/**
|
|
62
|
+
* Schema for the full ontology configuration
|
|
63
|
+
*/
|
|
64
|
+
export declare const OntologyConfigSchema: z.ZodObject<{
|
|
65
|
+
name: z.ZodString;
|
|
66
|
+
environments: z.ZodRecord<z.ZodString, z.ZodObject<{
|
|
67
|
+
debug: z.ZodOptional<z.ZodBoolean>;
|
|
68
|
+
}, "passthrough", z.ZodTypeAny, z.objectOutputType<{
|
|
69
|
+
debug: z.ZodOptional<z.ZodBoolean>;
|
|
70
|
+
}, z.ZodTypeAny, "passthrough">, z.objectInputType<{
|
|
71
|
+
debug: z.ZodOptional<z.ZodBoolean>;
|
|
72
|
+
}, z.ZodTypeAny, "passthrough">>>;
|
|
73
|
+
auth: z.ZodFunction<z.ZodTuple<[], z.ZodUnknown>, z.ZodUnknown>;
|
|
74
|
+
accessGroups: z.ZodRecord<z.ZodString, z.ZodObject<{
|
|
75
|
+
description: z.ZodString;
|
|
76
|
+
}, "strip", z.ZodTypeAny, {
|
|
77
|
+
description: string;
|
|
78
|
+
}, {
|
|
79
|
+
description: string;
|
|
80
|
+
}>>;
|
|
81
|
+
entities: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodObject<{
|
|
82
|
+
description: z.ZodString;
|
|
83
|
+
}, "strip", z.ZodTypeAny, {
|
|
84
|
+
description: string;
|
|
85
|
+
}, {
|
|
86
|
+
description: string;
|
|
87
|
+
}>>>;
|
|
88
|
+
functions: z.ZodRecord<z.ZodString, z.ZodObject<{
|
|
89
|
+
description: z.ZodString;
|
|
90
|
+
access: z.ZodArray<z.ZodString, "many">;
|
|
91
|
+
entities: z.ZodArray<z.ZodString, "many">;
|
|
92
|
+
inputs: z.ZodType<z.ZodType<any, z.ZodTypeDef, any>, z.ZodTypeDef, z.ZodType<any, z.ZodTypeDef, any>>;
|
|
93
|
+
outputs: z.ZodOptional<z.ZodType<z.ZodType<any, z.ZodTypeDef, any>, z.ZodTypeDef, z.ZodType<any, z.ZodTypeDef, any>>>;
|
|
94
|
+
resolver: z.ZodString;
|
|
95
|
+
}, "strip", z.ZodTypeAny, {
|
|
96
|
+
description: string;
|
|
97
|
+
access: string[];
|
|
98
|
+
entities: string[];
|
|
99
|
+
inputs: z.ZodType<any, z.ZodTypeDef, any>;
|
|
100
|
+
resolver: string;
|
|
101
|
+
outputs?: z.ZodType<any, z.ZodTypeDef, any> | undefined;
|
|
102
|
+
}, {
|
|
103
|
+
description: string;
|
|
104
|
+
access: string[];
|
|
105
|
+
entities: string[];
|
|
106
|
+
inputs: z.ZodType<any, z.ZodTypeDef, any>;
|
|
107
|
+
resolver: string;
|
|
108
|
+
outputs?: z.ZodType<any, z.ZodTypeDef, any> | undefined;
|
|
109
|
+
}>>;
|
|
110
|
+
}, "strip", z.ZodTypeAny, {
|
|
111
|
+
name: string;
|
|
112
|
+
environments: Record<string, z.objectOutputType<{
|
|
113
|
+
debug: z.ZodOptional<z.ZodBoolean>;
|
|
114
|
+
}, z.ZodTypeAny, "passthrough">>;
|
|
115
|
+
auth: (...args: unknown[]) => unknown;
|
|
116
|
+
accessGroups: Record<string, {
|
|
117
|
+
description: string;
|
|
118
|
+
}>;
|
|
119
|
+
functions: Record<string, {
|
|
120
|
+
description: string;
|
|
121
|
+
access: string[];
|
|
122
|
+
entities: string[];
|
|
123
|
+
inputs: z.ZodType<any, z.ZodTypeDef, any>;
|
|
124
|
+
resolver: string;
|
|
125
|
+
outputs?: z.ZodType<any, z.ZodTypeDef, any> | undefined;
|
|
126
|
+
}>;
|
|
127
|
+
entities?: Record<string, {
|
|
128
|
+
description: string;
|
|
129
|
+
}> | undefined;
|
|
130
|
+
}, {
|
|
131
|
+
name: string;
|
|
132
|
+
environments: Record<string, z.objectInputType<{
|
|
133
|
+
debug: z.ZodOptional<z.ZodBoolean>;
|
|
134
|
+
}, z.ZodTypeAny, "passthrough">>;
|
|
135
|
+
auth: (...args: unknown[]) => unknown;
|
|
136
|
+
accessGroups: Record<string, {
|
|
137
|
+
description: string;
|
|
138
|
+
}>;
|
|
139
|
+
functions: Record<string, {
|
|
140
|
+
description: string;
|
|
141
|
+
access: string[];
|
|
142
|
+
entities: string[];
|
|
143
|
+
inputs: z.ZodType<any, z.ZodTypeDef, any>;
|
|
144
|
+
resolver: string;
|
|
145
|
+
outputs?: z.ZodType<any, z.ZodTypeDef, any> | undefined;
|
|
146
|
+
}>;
|
|
147
|
+
entities?: Record<string, {
|
|
148
|
+
description: string;
|
|
149
|
+
}> | undefined;
|
|
150
|
+
}>;
|
|
151
|
+
/**
|
|
152
|
+
* Validate that all function access groups exist in accessGroups
|
|
153
|
+
*/
|
|
154
|
+
export declare function validateAccessGroups(config: z.infer<typeof OntologyConfigSchema>): void;
|
|
155
|
+
/**
|
|
156
|
+
* Validate that all function entity references exist in entities
|
|
157
|
+
*/
|
|
158
|
+
export declare function validateEntityReferences(config: z.infer<typeof OntologyConfigSchema>): void;
|
|
159
|
+
/**
|
|
160
|
+
* Validate that all fieldFrom() references point to existing functions
|
|
161
|
+
*/
|
|
162
|
+
export declare function validateFieldFromReferences(config: z.infer<typeof OntologyConfigSchema>): void;
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
import type { z } from "zod";
|
|
2
|
+
/**
|
|
3
|
+
* Configuration for an environment (dev, test, prod)
|
|
4
|
+
*/
|
|
5
|
+
export interface EnvironmentConfig {
|
|
6
|
+
/** Enable debug mode */
|
|
7
|
+
debug?: boolean;
|
|
8
|
+
/** Any additional environment-specific settings */
|
|
9
|
+
[key: string]: unknown;
|
|
10
|
+
}
|
|
11
|
+
/**
|
|
12
|
+
* Configuration for an access group
|
|
13
|
+
*/
|
|
14
|
+
export interface AccessGroupConfig {
|
|
15
|
+
/** Description of this access group */
|
|
16
|
+
description: string;
|
|
17
|
+
}
|
|
18
|
+
/**
|
|
19
|
+
* Definition of an entity in the ontology
|
|
20
|
+
*/
|
|
21
|
+
export interface EntityDefinition {
|
|
22
|
+
/** Human-readable description of this entity */
|
|
23
|
+
description: string;
|
|
24
|
+
}
|
|
25
|
+
/**
|
|
26
|
+
* Option returned by functions used as field sources.
|
|
27
|
+
* Functions referenced by `fieldFrom()` should return an array of these.
|
|
28
|
+
*/
|
|
29
|
+
export interface FieldOption {
|
|
30
|
+
/** The stored value */
|
|
31
|
+
value: string;
|
|
32
|
+
/** Human-readable label for display */
|
|
33
|
+
label: string;
|
|
34
|
+
}
|
|
35
|
+
/**
|
|
36
|
+
* Definition of a function in the ontology
|
|
37
|
+
*/
|
|
38
|
+
export interface FunctionDefinition<TGroups extends string = string, TEntities extends string = string> {
|
|
39
|
+
/** Human-readable description of what this function does */
|
|
40
|
+
description: string;
|
|
41
|
+
/** Which access groups can call this function */
|
|
42
|
+
access: TGroups[];
|
|
43
|
+
/** Which entities this function relates to (use empty array [] if none) */
|
|
44
|
+
entities: TEntities[];
|
|
45
|
+
/** Zod schema for input validation */
|
|
46
|
+
inputs: z.ZodType<unknown>;
|
|
47
|
+
/** Zod schema for output validation/documentation */
|
|
48
|
+
outputs?: z.ZodType<unknown>;
|
|
49
|
+
/** Path to the resolver file (relative to ontology.config.ts) */
|
|
50
|
+
resolver: string;
|
|
51
|
+
}
|
|
52
|
+
/**
|
|
53
|
+
* Auth function that determines access groups for a request
|
|
54
|
+
*/
|
|
55
|
+
export type AuthFunction = (req: Request) => Promise<string[]> | string[];
|
|
56
|
+
/**
|
|
57
|
+
* The main Ontology configuration object
|
|
58
|
+
*/
|
|
59
|
+
export interface OntologyConfig<TGroups extends string = string, TEntities extends string = string, TFunctions extends Record<string, FunctionDefinition<TGroups, TEntities>> = Record<string, FunctionDefinition<TGroups, TEntities>>> {
|
|
60
|
+
/** Name of this ontology/API */
|
|
61
|
+
name: string;
|
|
62
|
+
/** Environment configurations */
|
|
63
|
+
environments: Record<string, EnvironmentConfig>;
|
|
64
|
+
/** Pluggable auth function */
|
|
65
|
+
auth: AuthFunction;
|
|
66
|
+
/** Access group definitions */
|
|
67
|
+
accessGroups: Record<TGroups, AccessGroupConfig>;
|
|
68
|
+
/** Entity definitions for categorization */
|
|
69
|
+
entities?: Record<TEntities, EntityDefinition>;
|
|
70
|
+
/** Function definitions */
|
|
71
|
+
functions: TFunctions;
|
|
72
|
+
}
|
|
73
|
+
/**
|
|
74
|
+
* Context passed to resolvers
|
|
75
|
+
*/
|
|
76
|
+
export interface ResolverContext {
|
|
77
|
+
/** Current environment name */
|
|
78
|
+
env: string;
|
|
79
|
+
/** Environment configuration */
|
|
80
|
+
envConfig: EnvironmentConfig;
|
|
81
|
+
/** Logger instance */
|
|
82
|
+
logger: {
|
|
83
|
+
info: (message: string, ...args: unknown[]) => void;
|
|
84
|
+
warn: (message: string, ...args: unknown[]) => void;
|
|
85
|
+
error: (message: string, ...args: unknown[]) => void;
|
|
86
|
+
debug: (message: string, ...args: unknown[]) => void;
|
|
87
|
+
};
|
|
88
|
+
/** Access groups for the current request */
|
|
89
|
+
accessGroups: string[];
|
|
90
|
+
}
|
|
91
|
+
/**
|
|
92
|
+
* Resolver function signature
|
|
93
|
+
*/
|
|
94
|
+
export type ResolverFunction<TArgs = unknown, TResult = unknown> = (ctx: ResolverContext, args: TArgs) => Promise<TResult> | TResult;
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Ontology - Ontology-first backends with human-approved AI access & edits
|
|
3
|
+
*
|
|
4
|
+
* @example
|
|
5
|
+
* ```ts
|
|
6
|
+
* import { defineOntology, fieldFrom } from 'ont-run';
|
|
7
|
+
* import { z } from 'zod';
|
|
8
|
+
*
|
|
9
|
+
* export default defineOntology({
|
|
10
|
+
* name: 'my-api',
|
|
11
|
+
* environments: { dev: { debug: true }, prod: { debug: false } },
|
|
12
|
+
* auth: async (req) => req.headers.get('Authorization') ? ['admin'] : ['public'],
|
|
13
|
+
* accessGroups: {
|
|
14
|
+
* public: { description: 'Unauthenticated' },
|
|
15
|
+
* admin: { description: 'Administrators' },
|
|
16
|
+
* },
|
|
17
|
+
* entities: {
|
|
18
|
+
* User: { description: 'A user account' },
|
|
19
|
+
* },
|
|
20
|
+
* functions: {
|
|
21
|
+
* hello: {
|
|
22
|
+
* description: 'Say hello',
|
|
23
|
+
* access: ['public'],
|
|
24
|
+
* entities: [],
|
|
25
|
+
* inputs: z.object({ name: z.string() }),
|
|
26
|
+
* resolver: './resolvers/hello.ts',
|
|
27
|
+
* },
|
|
28
|
+
* },
|
|
29
|
+
* });
|
|
30
|
+
* ```
|
|
31
|
+
*/
|
|
32
|
+
export { defineOntology } from "./config/define.js";
|
|
33
|
+
export { fieldFrom } from "./config/categorical.js";
|
|
34
|
+
export { startOnt } from "./server/start.js";
|
|
35
|
+
export type { StartOntOptions, StartOntResult } from "./server/start.js";
|
|
36
|
+
export type { OntologyConfig, FunctionDefinition, AccessGroupConfig, EnvironmentConfig, EntityDefinition, AuthFunction, ResolverContext, ResolverFunction, FieldOption, } from "./config/types.js";
|
|
37
|
+
export { z } from "zod";
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import type { OntologySnapshot, OntologyDiff } from "./types.js";
|
|
2
|
+
/**
|
|
3
|
+
* Compare two ontology snapshots and generate a diff.
|
|
4
|
+
* @param oldOntology - The previous ontology (from lockfile), or null if first run
|
|
5
|
+
* @param newOntology - The current ontology (from config)
|
|
6
|
+
*/
|
|
7
|
+
export declare function diffOntology(oldOntology: OntologySnapshot | null, newOntology: OntologySnapshot): OntologyDiff;
|
|
8
|
+
/**
|
|
9
|
+
* Format a diff for console output
|
|
10
|
+
*/
|
|
11
|
+
export declare function formatDiffForConsole(diff: OntologyDiff): string;
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import type { OntologyConfig } from "../config/types.js";
|
|
2
|
+
import type { OntologySnapshot } from "./types.js";
|
|
3
|
+
/**
|
|
4
|
+
* Extract the ontology snapshot from an OntologyConfig.
|
|
5
|
+
* This extracts ONLY the security-relevant parts:
|
|
6
|
+
* - Function names
|
|
7
|
+
* - Access lists
|
|
8
|
+
* - Input schemas
|
|
9
|
+
* - Output schemas
|
|
10
|
+
* - Descriptions
|
|
11
|
+
* - Entities
|
|
12
|
+
* - Field references (fieldFrom)
|
|
13
|
+
*
|
|
14
|
+
* It DOES NOT include:
|
|
15
|
+
* - Resolver paths (so resolver code can change freely)
|
|
16
|
+
* - Environment configs
|
|
17
|
+
* - Auth function
|
|
18
|
+
*/
|
|
19
|
+
export declare function extractOntology(config: OntologyConfig): OntologySnapshot;
|
|
20
|
+
/**
|
|
21
|
+
* Create a deterministic hash of an ontology snapshot.
|
|
22
|
+
* Uses SHA256 and returns a 16-character hex string.
|
|
23
|
+
*/
|
|
24
|
+
export declare function hashOntology(ontology: OntologySnapshot): string;
|
|
25
|
+
/**
|
|
26
|
+
* Extract ontology snapshot and compute hash in one step
|
|
27
|
+
*/
|
|
28
|
+
export declare function computeOntologyHash(config: OntologyConfig): {
|
|
29
|
+
ontology: OntologySnapshot;
|
|
30
|
+
hash: string;
|
|
31
|
+
};
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
import type { Lockfile, OntologySnapshot } from "./types.js";
|
|
2
|
+
export { extractOntology, hashOntology, computeOntologyHash } from "./hasher.js";
|
|
3
|
+
export { diffOntology, formatDiffForConsole } from "./differ.js";
|
|
4
|
+
export type { Lockfile, OntologySnapshot, OntologyDiff, FunctionChange, FunctionShape, } from "./types.js";
|
|
5
|
+
/**
|
|
6
|
+
* Get the lockfile path for a given config directory
|
|
7
|
+
*/
|
|
8
|
+
export declare function getLockfilePath(configDir: string): string;
|
|
9
|
+
/**
|
|
10
|
+
* Check if a lockfile exists
|
|
11
|
+
*/
|
|
12
|
+
export declare function lockfileExists(configDir: string): boolean;
|
|
13
|
+
/**
|
|
14
|
+
* Read the lockfile from disk
|
|
15
|
+
* @returns The lockfile contents, or null if it doesn't exist
|
|
16
|
+
*/
|
|
17
|
+
export declare function readLockfile(configDir: string): Promise<Lockfile | null>;
|
|
18
|
+
/**
|
|
19
|
+
* Write a lockfile to disk
|
|
20
|
+
*/
|
|
21
|
+
export declare function writeLockfile(configDir: string, ontology: OntologySnapshot, hash: string): Promise<void>;
|
|
22
|
+
/**
|
|
23
|
+
* Check if the current ontology matches the lockfile
|
|
24
|
+
* @returns { match: true } if hashes match, or { match: false, lockfile, currentHash } if not
|
|
25
|
+
*/
|
|
26
|
+
export declare function checkLockfile(configDir: string, currentHash: string): Promise<{
|
|
27
|
+
match: true;
|
|
28
|
+
lockfile: Lockfile;
|
|
29
|
+
} | {
|
|
30
|
+
match: false;
|
|
31
|
+
lockfile: Lockfile | null;
|
|
32
|
+
currentHash: string;
|
|
33
|
+
}>;
|
|
34
|
+
/**
|
|
35
|
+
* Result of lockfile validation
|
|
36
|
+
*/
|
|
37
|
+
export interface LockfileValidationResult {
|
|
38
|
+
/** Status of the lockfile check */
|
|
39
|
+
status: "valid" | "missing" | "mismatch";
|
|
40
|
+
/** The diff if there are changes (only present for 'mismatch' status) */
|
|
41
|
+
diff?: import("./types.js").OntologyDiff;
|
|
42
|
+
/** Human-readable message */
|
|
43
|
+
message: string;
|
|
44
|
+
}
|
|
45
|
+
/**
|
|
46
|
+
* Validate the lockfile against the current ontology.
|
|
47
|
+
* This is the main entry point for library use.
|
|
48
|
+
*
|
|
49
|
+
* @param configDir - Directory containing the ontology.config.ts
|
|
50
|
+
* @param currentOntology - The current ontology snapshot
|
|
51
|
+
* @param currentHash - The current ontology hash
|
|
52
|
+
*/
|
|
53
|
+
export declare function validateLockfile(configDir: string, currentOntology: OntologySnapshot, currentHash: string): Promise<LockfileValidationResult>;
|