@osdk/vite-plugin-oac 0.1.0-beta.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +146 -0
- package/build/browser/FauxFoundryTypes.js +2 -0
- package/build/browser/FauxFoundryTypes.js.map +1 -0
- package/build/browser/FoundryMiddlewareController.js +88 -0
- package/build/browser/FoundryMiddlewareController.js.map +1 -0
- package/build/browser/applySeed.js +27 -0
- package/build/browser/applySeed.js.map +1 -0
- package/build/browser/generateOntologyAssets.js +205 -0
- package/build/browser/generateOntologyAssets.js.map +1 -0
- package/build/browser/index.js +69 -0
- package/build/browser/index.js.map +1 -0
- package/build/browser/registerOntologyFullMetadata.js +194 -0
- package/build/browser/registerOntologyFullMetadata.js.map +1 -0
- package/build/browser/routeConnectToMsw.js +61 -0
- package/build/browser/routeConnectToMsw.js.map +1 -0
- package/build/browser/syncDirectories.js +204 -0
- package/build/browser/syncDirectories.js.map +1 -0
- package/build/browser/utils/readJsonFile.js +22 -0
- package/build/browser/utils/readJsonFile.js.map +1 -0
- package/build/browser/watchOntologyAsCode.js +69 -0
- package/build/browser/watchOntologyAsCode.js.map +1 -0
- package/build/cjs/index.cjs +629 -0
- package/build/cjs/index.cjs.map +1 -0
- package/build/cjs/index.d.cts +14 -0
- package/build/esm/FauxFoundryTypes.js +2 -0
- package/build/esm/FauxFoundryTypes.js.map +1 -0
- package/build/esm/FoundryMiddlewareController.js +88 -0
- package/build/esm/FoundryMiddlewareController.js.map +1 -0
- package/build/esm/applySeed.js +27 -0
- package/build/esm/applySeed.js.map +1 -0
- package/build/esm/generateOntologyAssets.js +205 -0
- package/build/esm/generateOntologyAssets.js.map +1 -0
- package/build/esm/index.js +69 -0
- package/build/esm/index.js.map +1 -0
- package/build/esm/registerOntologyFullMetadata.js +194 -0
- package/build/esm/registerOntologyFullMetadata.js.map +1 -0
- package/build/esm/routeConnectToMsw.js +61 -0
- package/build/esm/routeConnectToMsw.js.map +1 -0
- package/build/esm/syncDirectories.js +204 -0
- package/build/esm/syncDirectories.js.map +1 -0
- package/build/esm/utils/readJsonFile.js +22 -0
- package/build/esm/utils/readJsonFile.js.map +1 -0
- package/build/esm/watchOntologyAsCode.js +69 -0
- package/build/esm/watchOntologyAsCode.js.map +1 -0
- package/build/types/FauxFoundryTypes.d.ts +2 -0
- package/build/types/FauxFoundryTypes.d.ts.map +1 -0
- package/build/types/FoundryMiddlewareController.d.ts +14 -0
- package/build/types/FoundryMiddlewareController.d.ts.map +1 -0
- package/build/types/applySeed.d.ts +2 -0
- package/build/types/applySeed.d.ts.map +1 -0
- package/build/types/generateOntologyAssets.d.ts +12 -0
- package/build/types/generateOntologyAssets.d.ts.map +1 -0
- package/build/types/index.d.ts +11 -0
- package/build/types/index.d.ts.map +1 -0
- package/build/types/registerOntologyFullMetadata.d.ts +3 -0
- package/build/types/registerOntologyFullMetadata.d.ts.map +1 -0
- package/build/types/routeConnectToMsw.d.ts +6 -0
- package/build/types/routeConnectToMsw.d.ts.map +1 -0
- package/build/types/syncDirectories.d.ts +5 -0
- package/build/types/syncDirectories.d.ts.map +1 -0
- package/build/types/utils/readJsonFile.d.ts +1 -0
- package/build/types/utils/readJsonFile.d.ts.map +1 -0
- package/build/types/watchOntologyAsCode.d.ts +10 -0
- package/build/types/watchOntologyAsCode.d.ts.map +1 -0
- package/package.json +81 -0
package/README.md
ADDED
|
@@ -0,0 +1,146 @@
|
|
|
1
|
+
# OAC Vite Plugin
|
|
2
|
+
|
|
3
|
+
A Vite plugin that enables **Ontology as Code (OAC)** development by automatically generating ontology assets from TypeScript/JavaScript ontology definitions. This plugin handles the complete pipeline from ontology source code to ready-to-use OSDK (Ontology SDK) TypeScript files.
|
|
4
|
+
|
|
5
|
+
## Features
|
|
6
|
+
|
|
7
|
+
- **Automatic Asset Generation**: Converts `.ontology/ontology.mjs` files into IR, full metadata, and OSDK TypeScript files
|
|
8
|
+
- **Development Mode**: File watching with hot reload - changes to ontology files trigger automatic regeneration
|
|
9
|
+
- **Build Mode**: Seamless integration with Vite's build process for production builds
|
|
10
|
+
- **Intelligent Synchronization**: Only updates changed files to minimize build times
|
|
11
|
+
- **Foundry Middleware**: Local development server with mock Foundry API support
|
|
12
|
+
- **Comprehensive Error Handling**: Detailed logging and debug information preservation on failures
|
|
13
|
+
|
|
14
|
+
## Installation
|
|
15
|
+
|
|
16
|
+
```bash
|
|
17
|
+
pnpm add @osdk/vite-plugin-oac
|
|
18
|
+
```
|
|
19
|
+
|
|
20
|
+
## Usage
|
|
21
|
+
|
|
22
|
+
Add the plugin to your `vite.config.ts`:
|
|
23
|
+
|
|
24
|
+
```typescript
|
|
25
|
+
import oacVitePlugin from "@osdk/vite-plugin-oac";
|
|
26
|
+
import { defineConfig } from "vite";
|
|
27
|
+
|
|
28
|
+
export default defineConfig({
|
|
29
|
+
plugins: [
|
|
30
|
+
oacVitePlugin(),
|
|
31
|
+
// ... other plugins
|
|
32
|
+
],
|
|
33
|
+
});
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
## Generated Assets Pipeline
|
|
37
|
+
|
|
38
|
+
The plugin orchestrates a three-stage generation process:
|
|
39
|
+
|
|
40
|
+
```
|
|
41
|
+
.ontology/ontology.mjs → .ontology.ir.json → .ontology.json → .osdk/src/*
|
|
42
|
+
(Source) (IR Format) (Full Metadata) (OSDK Files)
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
### Stage 1: JavaScript/TypeScript → IR
|
|
46
|
+
|
|
47
|
+
- Uses `@osdk/maker` to convert ontology source code to Intermediate Representation (IR)
|
|
48
|
+
- Input: `.ontology/ontology.mjs`
|
|
49
|
+
- Output: `.ontology.ir.json`
|
|
50
|
+
|
|
51
|
+
### Stage 2: IR → Full Metadata
|
|
52
|
+
|
|
53
|
+
- Converts IR format to complete ontology metadata
|
|
54
|
+
- Input: `.ontology.ir.json`
|
|
55
|
+
- Output: `.ontology.json`
|
|
56
|
+
|
|
57
|
+
### Stage 3: Full Metadata → OSDK
|
|
58
|
+
|
|
59
|
+
- Generates TypeScript SDK files using `@osdk/cli`
|
|
60
|
+
- Input: `.ontology.json`
|
|
61
|
+
- Output: `.osdk/src/*` directory structure
|
|
62
|
+
|
|
63
|
+
## Development vs Build Mode
|
|
64
|
+
|
|
65
|
+
### Development Mode
|
|
66
|
+
|
|
67
|
+
- **File Watching**: Monitors `.ontology/` directory for changes
|
|
68
|
+
- **Hot Reload**: Automatically regenerates assets when files change
|
|
69
|
+
- **Foundry Middleware**: Provides mock Foundry API for local development
|
|
70
|
+
- **Event Emitters**: Notifies other systems when regeneration completes
|
|
71
|
+
|
|
72
|
+
### Build Mode
|
|
73
|
+
|
|
74
|
+
- **One-time Generation**: Runs during Vite's `buildStart` hook
|
|
75
|
+
- **Build Integration**: Ensures assets are ready before the main build process
|
|
76
|
+
- **Error Propagation**: Build fails if ontology generation fails
|
|
77
|
+
|
|
78
|
+
## File Structure
|
|
79
|
+
|
|
80
|
+
```
|
|
81
|
+
.@osdk/vite-plugin-oac/
|
|
82
|
+
├── index.ts # Main plugin entry point
|
|
83
|
+
├── generateOntologyAssets.ts # Core generation logic (shared by dev/build)
|
|
84
|
+
├── watchOntologyAsCode.ts # Development mode file watching
|
|
85
|
+
├── syncDirectories.ts # Intelligent file synchronization
|
|
86
|
+
├── FoundryMiddlewareController.ts # Mock Foundry API middleware
|
|
87
|
+
├── package.json # Plugin dependencies and metadata
|
|
88
|
+
└── tsconfig.json # TypeScript configuration
|
|
89
|
+
```
|
|
90
|
+
|
|
91
|
+
### Key Files
|
|
92
|
+
|
|
93
|
+
- **`index.ts`**: Main Vite plugin that coordinates between development and build modes
|
|
94
|
+
- **`generateOntologyAssets.ts`**: Contains the core three-stage generation pipeline
|
|
95
|
+
- **`watchOntologyAsCode.ts`**: Handles file watching and change detection in development
|
|
96
|
+
- **`syncDirectories.ts`**: Efficiently synchronizes generated files using SHA-256 hashing
|
|
97
|
+
- **`FoundryMiddlewareController.ts`**: Provides local Foundry API simulation for development
|
|
98
|
+
|
|
99
|
+
## Error Handling
|
|
100
|
+
|
|
101
|
+
The plugin includes comprehensive error handling:
|
|
102
|
+
|
|
103
|
+
- **Detailed Logging**: All operations are logged with timestamps
|
|
104
|
+
- **Debug Preservation**: Failed generations leave temporary files for inspection
|
|
105
|
+
- **Graceful Cleanup**: Successful operations clean up temporary files
|
|
106
|
+
- **Build Failure**: Build process stops if ontology generation fails
|
|
107
|
+
|
|
108
|
+
## Configuration
|
|
109
|
+
|
|
110
|
+
The plugin currently uses sensible defaults:
|
|
111
|
+
|
|
112
|
+
- **Ontology Directory**: `.ontology/`
|
|
113
|
+
- **IR Output**: `.ontology.ir.json`
|
|
114
|
+
- **Metadata Output**: `.ontology.json`
|
|
115
|
+
- **OSDK Output**: `.osdk/src/`
|
|
116
|
+
|
|
117
|
+
## Best Practices
|
|
118
|
+
|
|
119
|
+
1. **Ontology Structure**: Keep your ontology definitions in `.ontology/ontology.mjs`
|
|
120
|
+
2. **Version Control**: Include generated `.ontology.json` in version control for reproducible builds
|
|
121
|
+
3. **OSDK Files**: Consider `.osdk/src/` as generated code - don't edit manually
|
|
122
|
+
4. **Error Debugging**: Check temporary directories mentioned in error logs for debugging failed generations
|
|
123
|
+
|
|
124
|
+
## Troubleshooting
|
|
125
|
+
|
|
126
|
+
### Generation Failures
|
|
127
|
+
|
|
128
|
+
- Check the Vite dev server logs for detailed error messages
|
|
129
|
+
- Look for temporary directories mentioned in error logs
|
|
130
|
+
- Ensure all required dependencies are installed
|
|
131
|
+
|
|
132
|
+
### File Synchronization Issues
|
|
133
|
+
|
|
134
|
+
- The plugin uses SHA-256 hashing to detect changes
|
|
135
|
+
- Only modified files are updated to minimize build times
|
|
136
|
+
- Empty directories are automatically cleaned up
|
|
137
|
+
|
|
138
|
+
### Development Server Issues
|
|
139
|
+
|
|
140
|
+
- The Foundry middleware provides mock API responses
|
|
141
|
+
- Check browser developer tools for API-related errors
|
|
142
|
+
- Ensure ontology definitions are valid before testing
|
|
143
|
+
|
|
144
|
+
## License
|
|
145
|
+
|
|
146
|
+
Part of the larger OAC (Ontology as Code) development ecosystem.
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"FauxFoundryTypes.js","names":[],"sources":["FauxFoundryTypes.ts"],"sourcesContent":["/*\n * Copyright 2025 Palantir Technologies, Inc. All rights reserved.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport type { FauxFoundry } from \"@osdk/faux\";\n\nexport type FauxActionImpl = Parameters<\n ReturnType<FauxFoundry[\"getOntology\"]>[\"registerActionType\"]\n>[1];\n"],"mappings":"","ignoreList":[]}
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Copyright 2025 Palantir Technologies, Inc. All rights reserved.
|
|
3
|
+
*
|
|
4
|
+
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
5
|
+
* you may not use this file except in compliance with the License.
|
|
6
|
+
* You may obtain a copy of the License at
|
|
7
|
+
*
|
|
8
|
+
* http://www.apache.org/licenses/LICENSE-2.0
|
|
9
|
+
*
|
|
10
|
+
* Unless required by applicable law or agreed to in writing, software
|
|
11
|
+
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
12
|
+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
13
|
+
* See the License for the specific language governing permissions and
|
|
14
|
+
* limitations under the License.
|
|
15
|
+
*/
|
|
16
|
+
|
|
17
|
+
import { FauxFoundry } from "@osdk/faux";
|
|
18
|
+
import EventEmitter from "node:events";
|
|
19
|
+
import path from "node:path";
|
|
20
|
+
import { applySeed } from "./applySeed.js";
|
|
21
|
+
import { registerOntologyFullMetadata } from "./registerOntologyFullMetadata.js";
|
|
22
|
+
import { routeConnectToMsw } from "./routeConnectToMsw.js";
|
|
23
|
+
import { readJsonFile } from "./utils/readJsonFile.js";
|
|
24
|
+
export class FoundryMiddlewareController {
|
|
25
|
+
#fauxFoundry;
|
|
26
|
+
#serverUrl;
|
|
27
|
+
#defaultOntologyRid;
|
|
28
|
+
mswEmitter = new EventEmitter();
|
|
29
|
+
#hooks;
|
|
30
|
+
constructor(serverUrl, defaultOntologyRid, oacEmitter, hooks) {
|
|
31
|
+
this.#serverUrl = serverUrl;
|
|
32
|
+
this.#defaultOntologyRid = defaultOntologyRid;
|
|
33
|
+
this.#hooks = hooks;
|
|
34
|
+
|
|
35
|
+
// create empty initial foundry
|
|
36
|
+
this.#fauxFoundry = this.#createNewFauxFoundry();
|
|
37
|
+
oacEmitter.on("generated", () => {
|
|
38
|
+
this.#reloadOntologyDefinition().catch(e => {
|
|
39
|
+
// eslint-disable-next-line no-console
|
|
40
|
+
console.error("[oac] error reloading ontology definition", e);
|
|
41
|
+
});
|
|
42
|
+
});
|
|
43
|
+
}
|
|
44
|
+
#debugLog(message, ...optionalParams) {
|
|
45
|
+
// eslint-disable-next-line no-console
|
|
46
|
+
console.log("[oac]", message, ...optionalParams);
|
|
47
|
+
}
|
|
48
|
+
#infoLog(message, ...optionalParams) {
|
|
49
|
+
// eslint-disable-next-line no-console
|
|
50
|
+
console.log("[oac]", message, ...optionalParams);
|
|
51
|
+
}
|
|
52
|
+
#errorLog(message, ...optionalParams) {
|
|
53
|
+
// eslint-disable-next-line no-console
|
|
54
|
+
console.error("[oac]", message, ...optionalParams);
|
|
55
|
+
}
|
|
56
|
+
#createNewFauxFoundry() {
|
|
57
|
+
return new FauxFoundry(this.#serverUrl, {
|
|
58
|
+
apiName: "DefaultOntology",
|
|
59
|
+
description: "Description",
|
|
60
|
+
displayName: "Ontology",
|
|
61
|
+
rid: this.#defaultOntologyRid
|
|
62
|
+
});
|
|
63
|
+
}
|
|
64
|
+
async #reloadOntologyDefinition() {
|
|
65
|
+
// Start with a fresh faux foundry + data
|
|
66
|
+
const fauxFoundry = this.#fauxFoundry = this.#createNewFauxFoundry();
|
|
67
|
+
const ontology = fauxFoundry.getDefaultOntology();
|
|
68
|
+
const ontologyFullMetadata = readJsonFile(".ontology.json");
|
|
69
|
+
registerOntologyFullMetadata(ontology, ontologyFullMetadata);
|
|
70
|
+
try {
|
|
71
|
+
if (this.#hooks?.preSeed) {
|
|
72
|
+
this.#debugLog("[oac] calling preSeed hook");
|
|
73
|
+
}
|
|
74
|
+
await this.#hooks?.preSeed?.(ontology);
|
|
75
|
+
} catch (e) {
|
|
76
|
+
this.#errorLog("[oac] Unhandled error from preSeed hook. Ignoring and continuing.", e);
|
|
77
|
+
}
|
|
78
|
+
this.#debugLog("[osdk] applying seed data");
|
|
79
|
+
await applySeed(this.#fauxFoundry, path.resolve(import.meta.dirname, "..", "..", ".ontology", "seed.ts"));
|
|
80
|
+
this.#infoLog("[osdk] Finished reloading ontology & seed data");
|
|
81
|
+
// TODO Maybe emit something that tells the front end associated with this
|
|
82
|
+
// vite plugin to full reload?
|
|
83
|
+
}
|
|
84
|
+
middleware = async (req, res, next) => {
|
|
85
|
+
return void (await routeConnectToMsw(this.#serverUrl, this.#fauxFoundry.handlers, this.mswEmitter, req, res, next));
|
|
86
|
+
};
|
|
87
|
+
}
|
|
88
|
+
//# sourceMappingURL=FoundryMiddlewareController.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"FoundryMiddlewareController.js","names":["FauxFoundry","EventEmitter","path","applySeed","registerOntologyFullMetadata","routeConnectToMsw","readJsonFile","FoundryMiddlewareController","fauxFoundry","serverUrl","defaultOntologyRid","mswEmitter","hooks","constructor","oacEmitter","createNewFauxFoundry","on","reloadOntologyDefinition","catch","e","console","error","debugLog","#debugLog","message","optionalParams","log","infoLog","#infoLog","errorLog","#errorLog","#createNewFauxFoundry","apiName","description","displayName","rid","#reloadOntologyDefinition","ontology","getDefaultOntology","ontologyFullMetadata","preSeed","resolve","import","meta","dirname","middleware","req","res","next","handlers"],"sources":["FoundryMiddlewareController.ts"],"sourcesContent":["/*\n * Copyright 2025 Palantir Technologies, Inc. All rights reserved.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport type { msw } from \"@osdk/faux\";\nimport { FauxFoundry } from \"@osdk/faux\";\nimport type * as Ontologies from \"@osdk/foundry.ontologies\";\nimport EventEmitter from \"node:events\";\nimport path from \"node:path\";\nimport type { Connect } from \"vite\";\nimport { applySeed } from \"./applySeed.js\";\nimport { registerOntologyFullMetadata } from \"./registerOntologyFullMetadata.js\";\nimport { routeConnectToMsw } from \"./routeConnectToMsw.js\";\nimport { readJsonFile } from \"./utils/readJsonFile.js\";\nimport type { WatchOntologyAsCodeEvents } from \"./watchOntologyAsCode.js\";\n\nexport interface Hooks {\n preSeed?: (\n fauxOntology: ReturnType<FauxFoundry[\"getOntology\"]>,\n ) => Promise<void>;\n}\n\nexport class FoundryMiddlewareController {\n #fauxFoundry: FauxFoundry;\n #serverUrl: string;\n #defaultOntologyRid: string;\n readonly mswEmitter: EventEmitter<msw.LifeCycleEventsMap> = new EventEmitter<\n msw.LifeCycleEventsMap\n >();\n #hooks: Hooks | undefined;\n\n constructor(\n serverUrl: string,\n defaultOntologyRid: string,\n oacEmitter: EventEmitter<WatchOntologyAsCodeEvents>,\n hooks?: Hooks,\n ) {\n this.#serverUrl = serverUrl;\n this.#defaultOntologyRid = defaultOntologyRid;\n this.#hooks = hooks;\n\n // create empty initial foundry\n this.#fauxFoundry = this.#createNewFauxFoundry();\n\n oacEmitter.on(\"generated\", () => {\n this.#reloadOntologyDefinition().catch(e => {\n // eslint-disable-next-line no-console\n console.error(\"[oac] error reloading ontology definition\", e);\n });\n });\n }\n\n #debugLog(message?: any, ...optionalParams: any[]) {\n // eslint-disable-next-line no-console\n console.log(\"[oac]\", message, ...optionalParams);\n }\n\n #infoLog(message?: any, ...optionalParams: any[]) {\n // eslint-disable-next-line no-console\n console.log(\"[oac]\", message, ...optionalParams);\n }\n\n #errorLog(message?: any, ...optionalParams: any[]) {\n // eslint-disable-next-line no-console\n console.error(\"[oac]\", message, ...optionalParams);\n }\n\n #createNewFauxFoundry() {\n return new FauxFoundry(this.#serverUrl, {\n apiName: \"DefaultOntology\",\n description: \"Description\",\n displayName: \"Ontology\",\n rid: this.#defaultOntologyRid,\n });\n }\n\n async #reloadOntologyDefinition() {\n // Start with a fresh faux foundry + data\n const fauxFoundry = (this.#fauxFoundry = this.#createNewFauxFoundry());\n\n const ontology = fauxFoundry.getDefaultOntology();\n\n const ontologyFullMetadata = readJsonFile<Ontologies.OntologyFullMetadata>(\n \".ontology.json\",\n );\n registerOntologyFullMetadata(ontology, ontologyFullMetadata);\n\n try {\n if (this.#hooks?.preSeed) {\n this.#debugLog(\"[oac] calling preSeed hook\");\n }\n\n await this.#hooks?.preSeed?.(ontology);\n } catch (e) {\n this.#errorLog(\n \"[oac] Unhandled error from preSeed hook. Ignoring and continuing.\",\n e,\n );\n }\n\n this.#debugLog(\"[osdk] applying seed data\");\n await applySeed(\n this.#fauxFoundry,\n path.resolve(import.meta.dirname, \"..\", \"..\", \".ontology\", \"seed.ts\"),\n );\n\n this.#infoLog(\"[osdk] Finished reloading ontology & seed data\");\n // TODO Maybe emit something that tells the front end associated with this\n // vite plugin to full reload?\n }\n\n middleware: Connect.NextHandleFunction = async (req, res, next) => {\n return void await routeConnectToMsw(\n this.#serverUrl,\n this.#fauxFoundry.handlers,\n this.mswEmitter,\n req,\n res,\n next,\n );\n };\n}\n"],"mappings":"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","ignoreList":[]}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Copyright 2025 Palantir Technologies, Inc. All rights reserved.
|
|
3
|
+
*
|
|
4
|
+
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
5
|
+
* you may not use this file except in compliance with the License.
|
|
6
|
+
* You may obtain a copy of the License at
|
|
7
|
+
*
|
|
8
|
+
* http://www.apache.org/licenses/LICENSE-2.0
|
|
9
|
+
*
|
|
10
|
+
* Unless required by applicable law or agreed to in writing, software
|
|
11
|
+
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
12
|
+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
13
|
+
* See the License for the specific language governing permissions and
|
|
14
|
+
* limitations under the License.
|
|
15
|
+
*/
|
|
16
|
+
|
|
17
|
+
import { createJiti } from "jiti";
|
|
18
|
+
export async function applySeed(fauxFoundry, seedPath) {
|
|
19
|
+
const jiti = createJiti(import.meta.filename, {
|
|
20
|
+
moduleCache: false,
|
|
21
|
+
debug: false,
|
|
22
|
+
importMeta: import.meta
|
|
23
|
+
});
|
|
24
|
+
const module = await jiti.import(seedPath);
|
|
25
|
+
module.default(fauxFoundry);
|
|
26
|
+
}
|
|
27
|
+
//# sourceMappingURL=applySeed.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"applySeed.js","names":["createJiti","applySeed","fauxFoundry","seedPath","jiti","import","meta","filename","moduleCache","debug","importMeta","module","default"],"sources":["applySeed.ts"],"sourcesContent":["/*\n * Copyright 2025 Palantir Technologies, Inc. All rights reserved.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport type { FauxFoundry } from \"@osdk/faux\";\nimport { createJiti } from \"jiti\";\n\nexport async function applySeed(\n fauxFoundry: FauxFoundry,\n seedPath: string,\n): Promise<void> {\n const jiti = createJiti(import.meta.filename, {\n moduleCache: false,\n debug: false,\n importMeta: import.meta,\n });\n\n const module: { default: (fauxFoundry: FauxFoundry) => void } = await jiti\n .import(seedPath);\n module.default(fauxFoundry);\n}\n"],"mappings":"AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAGA,SAASA,UAAU,QAAQ,MAAM;AAEjC,OAAO,eAAeC,SAASA,CAC7BC,WAAwB,EACxBC,QAAgB,EACD;EACf,MAAMC,IAAI,GAAGJ,UAAU,CAACK,MAAM,CAACC,IAAI,CAACC,QAAQ,EAAE;IAC5CC,WAAW,EAAE,KAAK;IAClBC,KAAK,EAAE,KAAK;IACZC,UAAU,EAAEL,MAAM,CAACC;EACrB,CAAC,CAAC;EAEF,MAAMK,MAAuD,GAAG,MAAMP,IAAI,CACvEC,MAAM,CAACF,QAAQ,CAAC;EACnBQ,MAAM,CAACC,OAAO,CAACV,WAAW,CAAC;AAC7B","ignoreList":[]}
|
|
@@ -0,0 +1,205 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Copyright 2025 Palantir Technologies, Inc. All rights reserved.
|
|
3
|
+
*
|
|
4
|
+
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
5
|
+
* you may not use this file except in compliance with the License.
|
|
6
|
+
* You may obtain a copy of the License at
|
|
7
|
+
*
|
|
8
|
+
* http://www.apache.org/licenses/LICENSE-2.0
|
|
9
|
+
*
|
|
10
|
+
* Unless required by applicable law or agreed to in writing, software
|
|
11
|
+
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
12
|
+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
13
|
+
* See the License for the specific language governing permissions and
|
|
14
|
+
* limitations under the License.
|
|
15
|
+
*/
|
|
16
|
+
|
|
17
|
+
import { OntologyIrToFullMetadataConverter } from "@osdk/generator-converters.ontologyir";
|
|
18
|
+
import { execa } from "execa";
|
|
19
|
+
import fs from "node:fs";
|
|
20
|
+
import path from "node:path";
|
|
21
|
+
import { syncDirectories } from "./syncDirectories.js";
|
|
22
|
+
export const NOISY = false;
|
|
23
|
+
/**
|
|
24
|
+
* Generate all ontology assets: IR, full metadata, and OSDK.
|
|
25
|
+
* This function contains the core generation logic extracted from watchOntologyAsCode
|
|
26
|
+
* so it can be used both in dev mode (via file watching) and build mode.
|
|
27
|
+
*/
|
|
28
|
+
export async function generateOntologyAssets({
|
|
29
|
+
logger,
|
|
30
|
+
ontologyDir
|
|
31
|
+
}) {
|
|
32
|
+
// Ensure the ontology directory exists
|
|
33
|
+
if (!fs.existsSync(ontologyDir)) {
|
|
34
|
+
fs.mkdirSync(ontologyDir, {
|
|
35
|
+
recursive: true
|
|
36
|
+
});
|
|
37
|
+
logger.info("Created .ontology directory", {
|
|
38
|
+
timestamp: true
|
|
39
|
+
});
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
// Generate the assets in sequence
|
|
43
|
+
await ontologyJsToIr(logger);
|
|
44
|
+
await ontologyIrToFullMetadata(logger);
|
|
45
|
+
await fullMetadataToOsdk(logger);
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
/**
|
|
49
|
+
* Convert ontology.mjs to IR format using the maker tool
|
|
50
|
+
*/
|
|
51
|
+
async function ontologyJsToIr(logger) {
|
|
52
|
+
if (NOISY) {
|
|
53
|
+
logger.info("Generating Ontology IR", {
|
|
54
|
+
timestamp: true
|
|
55
|
+
});
|
|
56
|
+
}
|
|
57
|
+
const {
|
|
58
|
+
stdout,
|
|
59
|
+
stderr,
|
|
60
|
+
exitCode
|
|
61
|
+
} = await execa("pnpm", ["exec", "maker", "-i", ".ontology/ontology.mjs", "-o", ".ontology.ir.json"]);
|
|
62
|
+
if (exitCode !== 0) {
|
|
63
|
+
logger.error(`Ontology IR generation failed with exit code ${exitCode}`, {
|
|
64
|
+
timestamp: true
|
|
65
|
+
});
|
|
66
|
+
if (stderr) {
|
|
67
|
+
logger.error(`Command stderr: ${stderr}`, {
|
|
68
|
+
timestamp: true
|
|
69
|
+
});
|
|
70
|
+
}
|
|
71
|
+
throw new Error(`Failed to generate ontology IR: exit code ${exitCode}`);
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
// Log stdout for debugging if needed
|
|
75
|
+
if (stdout && NOISY) {
|
|
76
|
+
logger.info(`Ontology IR generation output: ${stdout}`, {
|
|
77
|
+
timestamp: true
|
|
78
|
+
});
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
/**
|
|
83
|
+
* Convert IR to full metadata format
|
|
84
|
+
*/
|
|
85
|
+
async function ontologyIrToFullMetadata(logger) {
|
|
86
|
+
if (NOISY) {
|
|
87
|
+
logger.info("Converting IR to Full metadata", {
|
|
88
|
+
timestamp: true
|
|
89
|
+
});
|
|
90
|
+
}
|
|
91
|
+
try {
|
|
92
|
+
const irContent = await fs.promises.readFile("./.ontology.ir.json", {
|
|
93
|
+
encoding: "utf-8"
|
|
94
|
+
});
|
|
95
|
+
const blockData = JSON.parse(irContent).blockData;
|
|
96
|
+
const fullMeta = OntologyIrToFullMetadataConverter.getFullMetadataFromIr(blockData);
|
|
97
|
+
await fs.promises.writeFile("./.ontology.json", JSON.stringify(fullMeta, null, 2));
|
|
98
|
+
if (NOISY) {
|
|
99
|
+
logger.info("Successfully converted IR to full metadata", {
|
|
100
|
+
timestamp: true
|
|
101
|
+
});
|
|
102
|
+
}
|
|
103
|
+
} catch (error) {
|
|
104
|
+
logger.error(`Failed to convert IR to full metadata: ${error instanceof Error ? error.message : String(error)}`, {
|
|
105
|
+
timestamp: true
|
|
106
|
+
});
|
|
107
|
+
throw error;
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
/**
|
|
112
|
+
* Generate OSDK from full metadata
|
|
113
|
+
*/
|
|
114
|
+
async function fullMetadataToOsdk(logger) {
|
|
115
|
+
if (NOISY) {
|
|
116
|
+
logger.info("Generating OSDK from full metadata", {
|
|
117
|
+
timestamp: true
|
|
118
|
+
});
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
// First create a clean temporary directory to generate the SDK into
|
|
122
|
+
const tempDir = path.join(process.cwd(), "node_modules", ".tmp", "osdkGeneration");
|
|
123
|
+
await fs.promises.rm(tempDir, {
|
|
124
|
+
recursive: true,
|
|
125
|
+
force: true
|
|
126
|
+
});
|
|
127
|
+
await fs.promises.mkdir(tempDir, {
|
|
128
|
+
recursive: true
|
|
129
|
+
});
|
|
130
|
+
try {
|
|
131
|
+
// Then generate the source code for the osdk
|
|
132
|
+
const tempSrcDir = path.join(tempDir, "src");
|
|
133
|
+
const {
|
|
134
|
+
stdout,
|
|
135
|
+
stderr,
|
|
136
|
+
exitCode
|
|
137
|
+
} = await execa("pnpm", ["exec", "osdk", "unstable", "typescript", "generate", "--outDir", tempSrcDir, "--ontologyPath", ".ontology.json", "--beta", "true", "--packageType", "module", "--version", "dev"]);
|
|
138
|
+
if (stdout && NOISY) {
|
|
139
|
+
logger.info(`OSDK generation output: ${stdout}`, {
|
|
140
|
+
timestamp: true
|
|
141
|
+
});
|
|
142
|
+
}
|
|
143
|
+
if (stderr) {
|
|
144
|
+
logger.error(`OSDK generation stderr: ${stderr}`, {
|
|
145
|
+
timestamp: true
|
|
146
|
+
});
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
// Then if it was successful, synchronize the generated code with the target directory
|
|
150
|
+
if (exitCode === 0) {
|
|
151
|
+
const targetDir = ".osdk/src";
|
|
152
|
+
try {
|
|
153
|
+
if (NOISY) {
|
|
154
|
+
logger.info("OSDK generation successful, synchronizing with target directory", {
|
|
155
|
+
timestamp: true
|
|
156
|
+
});
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
// Use granular synchronization instead of wholesale replacement
|
|
160
|
+
await syncDirectories(tempSrcDir, targetDir, logger);
|
|
161
|
+
if (NOISY) {
|
|
162
|
+
logger.info(`Successfully synchronized ${targetDir} with newly generated code`, {
|
|
163
|
+
timestamp: true
|
|
164
|
+
});
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
// Clean up temporary directory after successful sync
|
|
168
|
+
await fs.promises.rm(tempDir, {
|
|
169
|
+
recursive: true,
|
|
170
|
+
force: true
|
|
171
|
+
});
|
|
172
|
+
} catch (error) {
|
|
173
|
+
logger.error(`Failed to synchronize ${targetDir} directory: ${error instanceof Error ? error.message : String(error)}`, {
|
|
174
|
+
timestamp: true
|
|
175
|
+
});
|
|
176
|
+
logger.error(`Temporary files left at: ${tempDir}`, {
|
|
177
|
+
timestamp: true
|
|
178
|
+
});
|
|
179
|
+
throw error;
|
|
180
|
+
}
|
|
181
|
+
} else {
|
|
182
|
+
logger.error(`OSDK generation failed with exit code ${exitCode}`, {
|
|
183
|
+
timestamp: true
|
|
184
|
+
});
|
|
185
|
+
logger.error(`Temporary files left at: ${tempDir}`, {
|
|
186
|
+
timestamp: true
|
|
187
|
+
});
|
|
188
|
+
throw new Error(`OSDK generation failed with exit code ${exitCode}`);
|
|
189
|
+
}
|
|
190
|
+
} catch (error) {
|
|
191
|
+
// Make sure to clean up temp directory even if there's an error
|
|
192
|
+
try {
|
|
193
|
+
await fs.promises.rm(tempDir, {
|
|
194
|
+
recursive: true,
|
|
195
|
+
force: true
|
|
196
|
+
});
|
|
197
|
+
} catch (cleanupError) {
|
|
198
|
+
logger.warn(`Failed to clean up temporary directory: ${cleanupError instanceof Error ? cleanupError.message : String(cleanupError)}`, {
|
|
199
|
+
timestamp: true
|
|
200
|
+
});
|
|
201
|
+
}
|
|
202
|
+
throw error;
|
|
203
|
+
}
|
|
204
|
+
}
|
|
205
|
+
//# sourceMappingURL=generateOntologyAssets.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"generateOntologyAssets.js","names":["OntologyIrToFullMetadataConverter","execa","fs","path","syncDirectories","NOISY","generateOntologyAssets","logger","ontologyDir","existsSync","mkdirSync","recursive","info","timestamp","ontologyJsToIr","ontologyIrToFullMetadata","fullMetadataToOsdk","stdout","stderr","exitCode","error","Error","irContent","promises","readFile","encoding","blockData","JSON","parse","fullMeta","getFullMetadataFromIr","writeFile","stringify","message","String","tempDir","join","process","cwd","rm","force","mkdir","tempSrcDir","targetDir","cleanupError","warn"],"sources":["generateOntologyAssets.ts"],"sourcesContent":["/*\n * Copyright 2025 Palantir Technologies, Inc. All rights reserved.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport {\n type OntologyIrOntologyBlockDataV2,\n OntologyIrToFullMetadataConverter,\n} from \"@osdk/generator-converters.ontologyir\";\nimport { execa } from \"execa\";\nimport fs from \"node:fs\";\nimport path from \"node:path\";\nimport type { Logger } from \"vite\";\nimport { syncDirectories } from \"./syncDirectories.js\";\n\nexport const NOISY = false;\n\nexport interface GenerateOntologyAssetsOptions {\n logger: Logger;\n ontologyDir: string;\n}\n\n/**\n * Generate all ontology assets: IR, full metadata, and OSDK.\n * This function contains the core generation logic extracted from watchOntologyAsCode\n * so it can be used both in dev mode (via file watching) and build mode.\n */\nexport async function generateOntologyAssets({\n logger,\n ontologyDir,\n}: GenerateOntologyAssetsOptions): Promise<void> {\n // Ensure the ontology directory exists\n if (!fs.existsSync(ontologyDir)) {\n fs.mkdirSync(ontologyDir, { recursive: true });\n logger.info(\"Created .ontology directory\", { timestamp: true });\n }\n\n // Generate the assets in sequence\n await ontologyJsToIr(logger);\n await ontologyIrToFullMetadata(logger);\n await fullMetadataToOsdk(logger);\n}\n\n/**\n * Convert ontology.mjs to IR format using the maker tool\n */\nasync function ontologyJsToIr(logger: Logger): Promise<void> {\n if (NOISY) {\n logger.info(\"Generating Ontology IR\", { timestamp: true });\n }\n\n const { stdout, stderr, exitCode } = await execa(\"pnpm\", [\n \"exec\",\n \"maker\",\n \"-i\",\n \".ontology/ontology.mjs\",\n \"-o\",\n \".ontology.ir.json\",\n ]);\n\n if (exitCode !== 0) {\n logger.error(`Ontology IR generation failed with exit code ${exitCode}`, {\n timestamp: true,\n });\n if (stderr) {\n logger.error(`Command stderr: ${stderr}`, { timestamp: true });\n }\n throw new Error(`Failed to generate ontology IR: exit code ${exitCode}`);\n }\n\n // Log stdout for debugging if needed\n if (stdout && NOISY) {\n logger.info(`Ontology IR generation output: ${stdout}`, {\n timestamp: true,\n });\n }\n}\n\n/**\n * Convert IR to full metadata format\n */\nasync function ontologyIrToFullMetadata(logger: Logger): Promise<void> {\n if (NOISY) {\n logger.info(\"Converting IR to Full metadata\", { timestamp: true });\n }\n\n try {\n const irContent = await fs.promises.readFile(\"./.ontology.ir.json\", {\n encoding: \"utf-8\",\n });\n const blockData = JSON.parse(irContent)\n .blockData as OntologyIrOntologyBlockDataV2;\n\n const fullMeta = OntologyIrToFullMetadataConverter.getFullMetadataFromIr(\n blockData,\n );\n\n await fs.promises.writeFile(\n \"./.ontology.json\",\n JSON.stringify(fullMeta, null, 2),\n );\n\n if (NOISY) {\n logger.info(\"Successfully converted IR to full metadata\", {\n timestamp: true,\n });\n }\n } catch (error) {\n logger.error(\n `Failed to convert IR to full metadata: ${\n error instanceof Error ? error.message : String(error)\n }`,\n { timestamp: true },\n );\n throw error;\n }\n}\n\n/**\n * Generate OSDK from full metadata\n */\nasync function fullMetadataToOsdk(logger: Logger): Promise<void> {\n if (NOISY) {\n logger.info(\"Generating OSDK from full metadata\", { timestamp: true });\n }\n\n // First create a clean temporary directory to generate the SDK into\n const tempDir = path.join(\n process.cwd(),\n \"node_modules\",\n \".tmp\",\n \"osdkGeneration\",\n );\n await fs.promises.rm(tempDir, { recursive: true, force: true });\n await fs.promises.mkdir(tempDir, { recursive: true });\n\n try {\n // Then generate the source code for the osdk\n const tempSrcDir = path.join(tempDir, \"src\");\n const { stdout, stderr, exitCode } = await execa(\"pnpm\", [\n \"exec\",\n \"osdk\",\n \"unstable\",\n \"typescript\",\n \"generate\",\n \"--outDir\",\n tempSrcDir,\n \"--ontologyPath\",\n \".ontology.json\",\n \"--beta\",\n \"true\",\n \"--packageType\",\n \"module\",\n \"--version\",\n \"dev\",\n ]);\n\n if (stdout && NOISY) {\n logger.info(`OSDK generation output: ${stdout}`, { timestamp: true });\n }\n if (stderr) {\n logger.error(`OSDK generation stderr: ${stderr}`, { timestamp: true });\n }\n\n // Then if it was successful, synchronize the generated code with the target directory\n if (exitCode === 0) {\n const targetDir = \".osdk/src\";\n try {\n if (NOISY) {\n logger.info(\n \"OSDK generation successful, synchronizing with target directory\",\n {\n timestamp: true,\n },\n );\n }\n\n // Use granular synchronization instead of wholesale replacement\n await syncDirectories(tempSrcDir, targetDir, logger);\n\n if (NOISY) {\n logger.info(\n `Successfully synchronized ${targetDir} with newly generated code`,\n {\n timestamp: true,\n },\n );\n }\n\n // Clean up temporary directory after successful sync\n await fs.promises.rm(tempDir, { recursive: true, force: true });\n } catch (error) {\n logger.error(\n `Failed to synchronize ${targetDir} directory: ${\n error instanceof Error ? error.message : String(error)\n }`,\n { timestamp: true },\n );\n logger.error(`Temporary files left at: ${tempDir}`, {\n timestamp: true,\n });\n throw error;\n }\n } else {\n logger.error(`OSDK generation failed with exit code ${exitCode}`, {\n timestamp: true,\n });\n logger.error(`Temporary files left at: ${tempDir}`, { timestamp: true });\n throw new Error(`OSDK generation failed with exit code ${exitCode}`);\n }\n } catch (error) {\n // Make sure to clean up temp directory even if there's an error\n try {\n await fs.promises.rm(tempDir, { recursive: true, force: true });\n } catch (cleanupError) {\n logger.warn(\n `Failed to clean up temporary directory: ${\n cleanupError instanceof Error\n ? cleanupError.message\n : String(cleanupError)\n }`,\n { timestamp: true },\n );\n }\n throw error;\n }\n}\n"],"mappings":"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","ignoreList":[]}
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Copyright 2025 Palantir Technologies, Inc. All rights reserved.
|
|
3
|
+
*
|
|
4
|
+
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
5
|
+
* you may not use this file except in compliance with the License.
|
|
6
|
+
* You may obtain a copy of the License at
|
|
7
|
+
*
|
|
8
|
+
* http://www.apache.org/licenses/LICENSE-2.0
|
|
9
|
+
*
|
|
10
|
+
* Unless required by applicable law or agreed to in writing, software
|
|
11
|
+
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
12
|
+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
13
|
+
* See the License for the specific language governing permissions and
|
|
14
|
+
* limitations under the License.
|
|
15
|
+
*/
|
|
16
|
+
|
|
17
|
+
import path from "node:path";
|
|
18
|
+
import { FoundryMiddlewareController } from "./FoundryMiddlewareController.js";
|
|
19
|
+
import { generateOntologyAssets } from "./generateOntologyAssets.js";
|
|
20
|
+
import { watchOntologyAsCode } from "./watchOntologyAsCode.js";
|
|
21
|
+
|
|
22
|
+
/**
|
|
23
|
+
* Vite plugin for Ontology as Code (OAC) that generates ontology IR, metadata, and OSDK
|
|
24
|
+
* in both development and build modes.
|
|
25
|
+
*/
|
|
26
|
+
export function ontologyAsCode(opts) {
|
|
27
|
+
const ontologyDir = path.resolve(".ontology");
|
|
28
|
+
let config;
|
|
29
|
+
return {
|
|
30
|
+
name: "oac-vite-plugin",
|
|
31
|
+
// eslint-disable-next-line @typescript-eslint/require-await
|
|
32
|
+
async configResolved(resolvedConfig) {
|
|
33
|
+
config = resolvedConfig;
|
|
34
|
+
},
|
|
35
|
+
configureServer(server) {
|
|
36
|
+
const oacEmitter = watchOntologyAsCode({
|
|
37
|
+
watcher: server.watcher,
|
|
38
|
+
logger: server.config.logger,
|
|
39
|
+
ontologyDir
|
|
40
|
+
});
|
|
41
|
+
const middlewareUrl = `http${server.config.server.https ? "s" : ""}://localhost:${server.config.server.port}`;
|
|
42
|
+
const foundryMiddlewareController = new FoundryMiddlewareController(middlewareUrl, `ri.ontology.main.ontology.00000000-0000-0000-0000-000000000000`, oacEmitter, opts?.hooks);
|
|
43
|
+
server.middlewares.use(foundryMiddlewareController.middleware);
|
|
44
|
+
},
|
|
45
|
+
async buildStart() {
|
|
46
|
+
// Generate ontology assets during build
|
|
47
|
+
if (config.command === "build") {
|
|
48
|
+
config.logger.info("Generating ontology assets for build...", {
|
|
49
|
+
timestamp: true
|
|
50
|
+
});
|
|
51
|
+
try {
|
|
52
|
+
await generateOntologyAssets({
|
|
53
|
+
logger: config.logger,
|
|
54
|
+
ontologyDir
|
|
55
|
+
});
|
|
56
|
+
config.logger.info("Successfully generated ontology assets for build", {
|
|
57
|
+
timestamp: true
|
|
58
|
+
});
|
|
59
|
+
} catch (error) {
|
|
60
|
+
config.logger.error(`Failed to generate ontology assets: ${error instanceof Error ? error.message : String(error)}`, {
|
|
61
|
+
timestamp: true
|
|
62
|
+
});
|
|
63
|
+
throw error;
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
};
|
|
68
|
+
}
|
|
69
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","names":["path","FoundryMiddlewareController","generateOntologyAssets","watchOntologyAsCode","ontologyAsCode","opts","ontologyDir","resolve","config","name","configResolved","resolvedConfig","configureServer","server","oacEmitter","watcher","logger","middlewareUrl","https","port","foundryMiddlewareController","hooks","middlewares","use","middleware","buildStart","command","info","timestamp","error","Error","message","String"],"sources":["index.ts"],"sourcesContent":["/*\n * Copyright 2025 Palantir Technologies, Inc. All rights reserved.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport type { FauxOntology } from \"@osdk/faux\";\nimport path from \"node:path\";\nimport type { PluginOption, ResolvedConfig } from \"vite\";\nimport { FoundryMiddlewareController } from \"./FoundryMiddlewareController.js\";\nimport { generateOntologyAssets } from \"./generateOntologyAssets.js\";\nimport { watchOntologyAsCode } from \"./watchOntologyAsCode.js\";\n\n/**\n * Vite plugin for Ontology as Code (OAC) that generates ontology IR, metadata, and OSDK\n * in both development and build modes.\n */\nexport function ontologyAsCode(opts: {\n hooks?: {\n preSeed?: (fauxOntology: FauxOntology) => Promise<void>;\n };\n}): PluginOption {\n const ontologyDir = path.resolve(\".ontology\");\n\n let config: ResolvedConfig;\n\n return {\n name: \"oac-vite-plugin\",\n\n // eslint-disable-next-line @typescript-eslint/require-await\n async configResolved(resolvedConfig) {\n config = resolvedConfig;\n },\n\n configureServer(server) {\n const oacEmitter = watchOntologyAsCode({\n watcher: server.watcher,\n logger: server.config.logger,\n ontologyDir,\n });\n\n const middlewareUrl = `http${\n server.config.server.https ? \"s\" : \"\"\n }://localhost:${server.config.server.port}`;\n\n const foundryMiddlewareController = new FoundryMiddlewareController(\n middlewareUrl,\n `ri.ontology.main.ontology.00000000-0000-0000-0000-000000000000`,\n oacEmitter,\n opts?.hooks,\n );\n\n server.middlewares.use(foundryMiddlewareController.middleware);\n },\n\n async buildStart() {\n // Generate ontology assets during build\n if (config.command === \"build\") {\n config.logger.info(\"Generating ontology assets for build...\", {\n timestamp: true,\n });\n\n try {\n await generateOntologyAssets({\n logger: config.logger,\n ontologyDir,\n });\n\n config.logger.info(\n \"Successfully generated ontology assets for build\",\n { timestamp: true },\n );\n } catch (error) {\n config.logger.error(\n `Failed to generate ontology assets: ${\n error instanceof Error ? error.message : String(error)\n }`,\n { timestamp: true },\n );\n throw error;\n }\n }\n },\n };\n}\n"],"mappings":"AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAGA,OAAOA,IAAI,MAAM,WAAW;AAE5B,SAASC,2BAA2B,QAAQ,kCAAkC;AAC9E,SAASC,sBAAsB,QAAQ,6BAA6B;AACpE,SAASC,mBAAmB,QAAQ,0BAA0B;;AAE9D;AACA;AACA;AACA;AACA,OAAO,SAASC,cAAcA,CAACC,IAI9B,EAAgB;EACf,MAAMC,WAAW,GAAGN,IAAI,CAACO,OAAO,CAAC,WAAW,CAAC;EAE7C,IAAIC,MAAsB;EAE1B,OAAO;IACLC,IAAI,EAAE,iBAAiB;IAEvB;IACA,MAAMC,cAAcA,CAACC,cAAc,EAAE;MACnCH,MAAM,GAAGG,cAAc;IACzB,CAAC;IAEDC,eAAeA,CAACC,MAAM,EAAE;MACtB,MAAMC,UAAU,GAAGX,mBAAmB,CAAC;QACrCY,OAAO,EAAEF,MAAM,CAACE,OAAO;QACvBC,MAAM,EAAEH,MAAM,CAACL,MAAM,CAACQ,MAAM;QAC5BV;MACF,CAAC,CAAC;MAEF,MAAMW,aAAa,GAAG,OACpBJ,MAAM,CAACL,MAAM,CAACK,MAAM,CAACK,KAAK,GAAG,GAAG,GAAG,EAAE,gBACvBL,MAAM,CAACL,MAAM,CAACK,MAAM,CAACM,IAAI,EAAE;MAE3C,MAAMC,2BAA2B,GAAG,IAAInB,2BAA2B,CACjEgB,aAAa,EACb,gEAAgE,EAChEH,UAAU,EACVT,IAAI,EAAEgB,KACR,CAAC;MAEDR,MAAM,CAACS,WAAW,CAACC,GAAG,CAACH,2BAA2B,CAACI,UAAU,CAAC;IAChE,CAAC;IAED,MAAMC,UAAUA,CAAA,EAAG;MACjB;MACA,IAAIjB,MAAM,CAACkB,OAAO,KAAK,OAAO,EAAE;QAC9BlB,MAAM,CAACQ,MAAM,CAACW,IAAI,CAAC,yCAAyC,EAAE;UAC5DC,SAAS,EAAE;QACb,CAAC,CAAC;QAEF,IAAI;UACF,MAAM1B,sBAAsB,CAAC;YAC3Bc,MAAM,EAAER,MAAM,CAACQ,MAAM;YACrBV;UACF,CAAC,CAAC;UAEFE,MAAM,CAACQ,MAAM,CAACW,IAAI,CAChB,kDAAkD,EAClD;YAAEC,SAAS,EAAE;UAAK,CACpB,CAAC;QACH,CAAC,CAAC,OAAOC,KAAK,EAAE;UACdrB,MAAM,CAACQ,MAAM,CAACa,KAAK,CACjB,uCACEA,KAAK,YAAYC,KAAK,GAAGD,KAAK,CAACE,OAAO,GAAGC,MAAM,CAACH,KAAK,CAAC,EACtD,EACF;YAAED,SAAS,EAAE;UAAK,CACpB,CAAC;UACD,MAAMC,KAAK;QACb;MACF;IACF;EACF,CAAC;AACH","ignoreList":[]}
|