@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.
Files changed (65) hide show
  1. package/README.md +146 -0
  2. package/build/browser/FauxFoundryTypes.js +2 -0
  3. package/build/browser/FauxFoundryTypes.js.map +1 -0
  4. package/build/browser/FoundryMiddlewareController.js +88 -0
  5. package/build/browser/FoundryMiddlewareController.js.map +1 -0
  6. package/build/browser/applySeed.js +27 -0
  7. package/build/browser/applySeed.js.map +1 -0
  8. package/build/browser/generateOntologyAssets.js +205 -0
  9. package/build/browser/generateOntologyAssets.js.map +1 -0
  10. package/build/browser/index.js +69 -0
  11. package/build/browser/index.js.map +1 -0
  12. package/build/browser/registerOntologyFullMetadata.js +194 -0
  13. package/build/browser/registerOntologyFullMetadata.js.map +1 -0
  14. package/build/browser/routeConnectToMsw.js +61 -0
  15. package/build/browser/routeConnectToMsw.js.map +1 -0
  16. package/build/browser/syncDirectories.js +204 -0
  17. package/build/browser/syncDirectories.js.map +1 -0
  18. package/build/browser/utils/readJsonFile.js +22 -0
  19. package/build/browser/utils/readJsonFile.js.map +1 -0
  20. package/build/browser/watchOntologyAsCode.js +69 -0
  21. package/build/browser/watchOntologyAsCode.js.map +1 -0
  22. package/build/cjs/index.cjs +629 -0
  23. package/build/cjs/index.cjs.map +1 -0
  24. package/build/cjs/index.d.cts +14 -0
  25. package/build/esm/FauxFoundryTypes.js +2 -0
  26. package/build/esm/FauxFoundryTypes.js.map +1 -0
  27. package/build/esm/FoundryMiddlewareController.js +88 -0
  28. package/build/esm/FoundryMiddlewareController.js.map +1 -0
  29. package/build/esm/applySeed.js +27 -0
  30. package/build/esm/applySeed.js.map +1 -0
  31. package/build/esm/generateOntologyAssets.js +205 -0
  32. package/build/esm/generateOntologyAssets.js.map +1 -0
  33. package/build/esm/index.js +69 -0
  34. package/build/esm/index.js.map +1 -0
  35. package/build/esm/registerOntologyFullMetadata.js +194 -0
  36. package/build/esm/registerOntologyFullMetadata.js.map +1 -0
  37. package/build/esm/routeConnectToMsw.js +61 -0
  38. package/build/esm/routeConnectToMsw.js.map +1 -0
  39. package/build/esm/syncDirectories.js +204 -0
  40. package/build/esm/syncDirectories.js.map +1 -0
  41. package/build/esm/utils/readJsonFile.js +22 -0
  42. package/build/esm/utils/readJsonFile.js.map +1 -0
  43. package/build/esm/watchOntologyAsCode.js +69 -0
  44. package/build/esm/watchOntologyAsCode.js.map +1 -0
  45. package/build/types/FauxFoundryTypes.d.ts +2 -0
  46. package/build/types/FauxFoundryTypes.d.ts.map +1 -0
  47. package/build/types/FoundryMiddlewareController.d.ts +14 -0
  48. package/build/types/FoundryMiddlewareController.d.ts.map +1 -0
  49. package/build/types/applySeed.d.ts +2 -0
  50. package/build/types/applySeed.d.ts.map +1 -0
  51. package/build/types/generateOntologyAssets.d.ts +12 -0
  52. package/build/types/generateOntologyAssets.d.ts.map +1 -0
  53. package/build/types/index.d.ts +11 -0
  54. package/build/types/index.d.ts.map +1 -0
  55. package/build/types/registerOntologyFullMetadata.d.ts +3 -0
  56. package/build/types/registerOntologyFullMetadata.d.ts.map +1 -0
  57. package/build/types/routeConnectToMsw.d.ts +6 -0
  58. package/build/types/routeConnectToMsw.d.ts.map +1 -0
  59. package/build/types/syncDirectories.d.ts +5 -0
  60. package/build/types/syncDirectories.d.ts.map +1 -0
  61. package/build/types/utils/readJsonFile.d.ts +1 -0
  62. package/build/types/utils/readJsonFile.d.ts.map +1 -0
  63. package/build/types/watchOntologyAsCode.d.ts +10 -0
  64. package/build/types/watchOntologyAsCode.d.ts.map +1 -0
  65. package/package.json +81 -0
@@ -0,0 +1,194 @@
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
+ export function registerOntologyFullMetadata(ontology, ontologyFullMetadata) {
18
+ // Register object types
19
+ Object.values(ontologyFullMetadata.objectTypes).forEach(objectType => {
20
+ ontology.registerObjectType(objectType);
21
+ });
22
+ // Register action types with implementations
23
+ Object.values(ontologyFullMetadata.actionTypes).forEach(actionType => {
24
+ const implementation = createActionImplementation(actionType);
25
+ const actionTypeWithCamelCaseApiName = {
26
+ ...actionType,
27
+ apiName: camelcase(actionType.apiName)
28
+ };
29
+ ontology.registerActionType(actionTypeWithCamelCaseApiName, implementation);
30
+ });
31
+ Object.values(ontologyFullMetadata.sharedPropertyTypes).forEach(actionType => {
32
+ ontology.registerSharedPropertyType(actionType);
33
+ });
34
+ Object.values(ontologyFullMetadata.queryTypes).forEach(query => {
35
+ ontology.registerQueryType(query);
36
+ });
37
+ Object.values(ontologyFullMetadata.interfaceTypes).forEach(iface => {
38
+ ontology.registerInterfaceType(iface);
39
+ });
40
+ }
41
+
42
+ /**
43
+ * Creates a fake implementation for an action type based on its operations
44
+ */
45
+ function createActionImplementation(actionType) {
46
+ return (batch, payload) => {
47
+ // Extract parameters from payload
48
+ const params = payload.parameters;
49
+
50
+ // Handle different operation types
51
+ for (const operation of actionType.operations) {
52
+ switch (operation.type) {
53
+ case "createObject":
54
+ {
55
+ // Handle create object operation
56
+ const objectTypeApiName = operation.objectTypeApiName;
57
+ const primaryKey = params.primaryKey_;
58
+
59
+ // Create object data from parameters, excluding the primary key
60
+ const objectData = {};
61
+ for (const [key, value] of Object.entries(params)) {
62
+ if (key !== "primaryKey_") {
63
+ const param = actionType.parameters[key];
64
+ objectData[key] = toDataValue(value, param);
65
+ }
66
+ }
67
+ batch.addObject(objectTypeApiName, primaryKey, objectData);
68
+ break;
69
+ }
70
+ case "modifyObject":
71
+ {
72
+ // Handle modify object operation
73
+ let objectTypeApiName;
74
+ let primaryKey;
75
+ if (typeof operation.objectTypeApiName === "string") {
76
+ objectTypeApiName = operation.objectTypeApiName;
77
+ primaryKey = params.primaryKey_;
78
+ } else {
79
+ // If objectTypeApiName is a parameter reference
80
+ const objectToModify = params[operation.objectTypeApiName];
81
+ if (objectToModify) {
82
+ objectTypeApiName = objectToModify.objectTypeApiName || objectToModify;
83
+ primaryKey = objectToModify.primaryKeyValue || params.primaryKey_;
84
+ } else {
85
+ // Default to the parameter name if not found
86
+ objectTypeApiName = operation.objectTypeApiName;
87
+ primaryKey = params.primaryKey_;
88
+ }
89
+ }
90
+
91
+ // Create object data from parameters, excluding the primary key and objectToModifyParameter
92
+ const objectData = {};
93
+ for (const [key, value] of Object.entries(params)) {
94
+ if (key !== "primaryKey_" && key !== "objectToModifyParameter") {
95
+ const param = actionType.parameters[key];
96
+ objectData[key] = toDataValue(value, param);
97
+ }
98
+ }
99
+ batch.modifyObject(objectTypeApiName, primaryKey, objectData);
100
+ break;
101
+ }
102
+ case "deleteObject":
103
+ {
104
+ // Handle delete object operation
105
+ let objectTypeApiName;
106
+ let primaryKey;
107
+ if (typeof operation.objectTypeApiName === "string") {
108
+ objectTypeApiName = operation.objectTypeApiName;
109
+ primaryKey = params.primaryKey_;
110
+ } else {
111
+ // If objectTypeApiName is a parameter reference
112
+ const objectToDelete = params[operation.objectTypeApiName];
113
+ if (objectToDelete) {
114
+ objectTypeApiName = objectToDelete.objectTypeApiName || objectToDelete;
115
+ primaryKey = objectToDelete.primaryKeyValue || params.primaryKey_;
116
+ } else {
117
+ // Default to the parameter name if not found
118
+ objectTypeApiName = operation.objectTypeApiName;
119
+ primaryKey = params.primaryKey_;
120
+ }
121
+ }
122
+ batch.deleteObject(objectTypeApiName, primaryKey);
123
+ break;
124
+ }
125
+ case "createLink":
126
+ {
127
+ // Handle create link operation
128
+ const aSideObjectTypeApiName = operation.aSideObjectTypeApiName;
129
+ const bSideObjectTypeApiName = operation.bSideObjectTypeApiName;
130
+ const linkTypeApiNameAtoB = operation.linkTypeApiNameAtoB;
131
+
132
+ // For simplicity, assume we have the primary keys in the parameters
133
+ // In a real implementation, we would need to extract them from the parameters
134
+ const aSidePrimaryKey = params.aSidePrimaryKey || params.primaryKey_;
135
+ const bSidePrimaryKey = params.bSidePrimaryKey || params.linkedObjectPrimaryKey;
136
+ if (aSidePrimaryKey && bSidePrimaryKey) {
137
+ batch.addLink(aSideObjectTypeApiName, aSidePrimaryKey, linkTypeApiNameAtoB, bSideObjectTypeApiName, bSidePrimaryKey);
138
+ }
139
+ break;
140
+ }
141
+ case "deleteLink":
142
+ {
143
+ // Handle delete link operation
144
+ const aSideObjectTypeApiName = operation.aSideObjectTypeApiName;
145
+ const bSideObjectTypeApiName = operation.bSideObjectTypeApiName;
146
+ const linkTypeApiNameAtoB = operation.linkTypeApiNameAtoB;
147
+
148
+ // For simplicity, assume we have the primary keys in the parameters
149
+ // In a real implementation, we would need to extract them from the parameters
150
+ const aSidePrimaryKey = params.aSidePrimaryKey || params.primaryKey_;
151
+ const bSidePrimaryKey = params.bSidePrimaryKey || params.linkedObjectPrimaryKey;
152
+ if (aSidePrimaryKey && bSidePrimaryKey) {
153
+ batch.removeLink(aSideObjectTypeApiName, aSidePrimaryKey, linkTypeApiNameAtoB, bSideObjectTypeApiName, bSidePrimaryKey);
154
+ }
155
+ break;
156
+ }
157
+ // Handle other operation types as needed
158
+ case "createInterfaceObject":
159
+ case "modifyInterfaceObject":
160
+ case "deleteInterfaceObject":
161
+ // These operations are not implemented for now
162
+ throw new Error(`Operation type ${operation.type} not implemented yet`);
163
+ break;
164
+ default:
165
+ throw new Error(`Unknown operation type: ${operation.type}`);
166
+ }
167
+ }
168
+ };
169
+ }
170
+ function camelcase(apiName) {
171
+ return apiName.toLowerCase().replace(/[-_]+(.)?/g, (_, chr) => chr ? chr.toUpperCase() : "");
172
+ }
173
+ function toDataValue(value, param) {
174
+ if (param.dataType.type === "geoshape" && typeof value === "string") {
175
+ return latLonStringToGeoJSON(value);
176
+ }
177
+ return value;
178
+ }
179
+ function latLonStringToGeoJSON(latLonStr) {
180
+ // Split the string by comma and parse as floats
181
+ const [lat, lon] = latLonStr.split(",").map(Number);
182
+
183
+ // Basic validation
184
+ if (isNaN(lat) || isNaN(lon) || lat < -90 || lat > 90 || lon < -180 || lon > 180) {
185
+ throw new Error("Invalid latitude or longitude");
186
+ }
187
+
188
+ // Return GeoJSON Point
189
+ return {
190
+ type: "Point",
191
+ coordinates: [lon, lat] // GeoJSON uses [longitude, latitude]
192
+ };
193
+ }
194
+ //# sourceMappingURL=registerOntologyFullMetadata.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"registerOntologyFullMetadata.js","names":["registerOntologyFullMetadata","ontology","ontologyFullMetadata","Object","values","objectTypes","forEach","objectType","registerObjectType","actionTypes","actionType","implementation","createActionImplementation","actionTypeWithCamelCaseApiName","apiName","camelcase","registerActionType","sharedPropertyTypes","registerSharedPropertyType","queryTypes","query","registerQueryType","interfaceTypes","iface","registerInterfaceType","batch","payload","params","parameters","operation","operations","type","objectTypeApiName","primaryKey","primaryKey_","objectData","key","value","entries","param","toDataValue","addObject","objectToModify","primaryKeyValue","modifyObject","objectToDelete","deleteObject","aSideObjectTypeApiName","bSideObjectTypeApiName","linkTypeApiNameAtoB","aSidePrimaryKey","bSidePrimaryKey","linkedObjectPrimaryKey","addLink","removeLink","Error","toLowerCase","replace","_","chr","toUpperCase","dataType","latLonStringToGeoJSON","latLonStr","lat","lon","split","map","Number","isNaN","coordinates"],"sources":["registerOntologyFullMetadata.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 type * as Ontologies from \"@osdk/foundry.ontologies\";\nimport type { FauxActionImpl } from \"./FauxFoundryTypes.js\";\n\nexport function registerOntologyFullMetadata(\n ontology: ReturnType<FauxFoundry[\"getOntology\"]>,\n ontologyFullMetadata: Ontologies.OntologyFullMetadata,\n): void {\n // Register object types\n Object.values(ontologyFullMetadata.objectTypes).forEach((objectType) => {\n ontology.registerObjectType(objectType);\n });\n // Register action types with implementations\n Object.values(ontologyFullMetadata.actionTypes).forEach((actionType) => {\n const implementation = createActionImplementation(actionType);\n const actionTypeWithCamelCaseApiName = {\n ...actionType,\n apiName: camelcase(actionType.apiName),\n };\n ontology.registerActionType(actionTypeWithCamelCaseApiName, implementation);\n });\n Object.values(ontologyFullMetadata.sharedPropertyTypes).forEach(\n (actionType) => {\n ontology.registerSharedPropertyType(actionType);\n },\n );\n Object.values(ontologyFullMetadata.queryTypes).forEach((query) => {\n ontology.registerQueryType(query);\n });\n Object.values(ontologyFullMetadata.interfaceTypes).forEach((iface) => {\n ontology.registerInterfaceType(iface);\n });\n}\n\n/**\n * Creates a fake implementation for an action type based on its operations\n */\nfunction createActionImplementation(\n actionType: Ontologies.ActionTypeV2,\n): FauxActionImpl {\n return (\n batch: {\n addObject: (\n objectType: string,\n primaryKey: string | number | boolean,\n object: Record<string, unknown>,\n ) => void;\n modifyObject: (\n objectType: string,\n primaryKey: string | number | boolean,\n update: Record<string, unknown>,\n ) => void;\n deleteObject: (\n objectType: string,\n primaryKey: string | number | boolean,\n ) => void;\n addLink: (\n leftObjectType: string,\n leftPrimaryKey: string | number | boolean,\n leftLinkName: string,\n rightObjectType: string,\n rightPrimaryKey: string | number | boolean,\n ) => void;\n removeLink: (\n leftObjectType: string,\n leftPrimaryKey: string | number | boolean,\n leftLinkName: string,\n rightObjectType: string,\n rightPrimaryKey: string | number | boolean,\n ) => void;\n },\n payload: {\n parameters: Record<string, any>;\n },\n _ctx: unknown,\n ) => {\n // Extract parameters from payload\n const params = payload.parameters;\n\n // Handle different operation types\n for (const operation of actionType.operations) {\n switch (operation.type) {\n case \"createObject\": {\n // Handle create object operation\n const objectTypeApiName = operation.objectTypeApiName;\n const primaryKey = params.primaryKey_;\n\n // Create object data from parameters, excluding the primary key\n const objectData: Record<string, unknown> = {};\n for (const [key, value] of Object.entries(params)) {\n if (key !== \"primaryKey_\") {\n const param = actionType.parameters[key];\n objectData[key] = toDataValue(value, param);\n }\n }\n\n batch.addObject(objectTypeApiName, primaryKey, objectData);\n break;\n }\n case \"modifyObject\": {\n // Handle modify object operation\n let objectTypeApiName: string;\n let primaryKey: string | number | boolean;\n\n if (typeof operation.objectTypeApiName === \"string\") {\n objectTypeApiName = operation.objectTypeApiName;\n primaryKey = params.primaryKey_;\n } else {\n // If objectTypeApiName is a parameter reference\n const objectToModify = params[operation.objectTypeApiName];\n if (objectToModify) {\n objectTypeApiName = objectToModify.objectTypeApiName\n || objectToModify;\n primaryKey = objectToModify.primaryKeyValue || params.primaryKey_;\n } else {\n // Default to the parameter name if not found\n objectTypeApiName = operation.objectTypeApiName;\n primaryKey = params.primaryKey_;\n }\n }\n\n // Create object data from parameters, excluding the primary key and objectToModifyParameter\n const objectData: Record<string, unknown> = {};\n for (const [key, value] of Object.entries(params)) {\n if (key !== \"primaryKey_\" && key !== \"objectToModifyParameter\") {\n const param = actionType.parameters[key];\n objectData[key] = toDataValue(value, param);\n }\n }\n\n batch.modifyObject(objectTypeApiName, primaryKey, objectData);\n break;\n }\n case \"deleteObject\": {\n // Handle delete object operation\n let objectTypeApiName: string;\n let primaryKey: string | number | boolean;\n\n if (typeof operation.objectTypeApiName === \"string\") {\n objectTypeApiName = operation.objectTypeApiName;\n primaryKey = params.primaryKey_;\n } else {\n // If objectTypeApiName is a parameter reference\n const objectToDelete = params[operation.objectTypeApiName];\n if (objectToDelete) {\n objectTypeApiName = objectToDelete.objectTypeApiName\n || objectToDelete;\n primaryKey = objectToDelete.primaryKeyValue || params.primaryKey_;\n } else {\n // Default to the parameter name if not found\n objectTypeApiName = operation.objectTypeApiName;\n primaryKey = params.primaryKey_;\n }\n }\n\n batch.deleteObject(objectTypeApiName, primaryKey);\n break;\n }\n case \"createLink\": {\n // Handle create link operation\n const aSideObjectTypeApiName = operation.aSideObjectTypeApiName;\n const bSideObjectTypeApiName = operation.bSideObjectTypeApiName;\n const linkTypeApiNameAtoB = operation.linkTypeApiNameAtoB;\n\n // For simplicity, assume we have the primary keys in the parameters\n // In a real implementation, we would need to extract them from the parameters\n const aSidePrimaryKey = params.aSidePrimaryKey || params.primaryKey_;\n const bSidePrimaryKey = params.bSidePrimaryKey\n || params.linkedObjectPrimaryKey;\n\n if (aSidePrimaryKey && bSidePrimaryKey) {\n batch.addLink(\n aSideObjectTypeApiName,\n aSidePrimaryKey,\n linkTypeApiNameAtoB,\n bSideObjectTypeApiName,\n bSidePrimaryKey,\n );\n }\n break;\n }\n case \"deleteLink\": {\n // Handle delete link operation\n const aSideObjectTypeApiName = operation.aSideObjectTypeApiName;\n const bSideObjectTypeApiName = operation.bSideObjectTypeApiName;\n const linkTypeApiNameAtoB = operation.linkTypeApiNameAtoB;\n\n // For simplicity, assume we have the primary keys in the parameters\n // In a real implementation, we would need to extract them from the parameters\n const aSidePrimaryKey = params.aSidePrimaryKey || params.primaryKey_;\n const bSidePrimaryKey = params.bSidePrimaryKey\n || params.linkedObjectPrimaryKey;\n\n if (aSidePrimaryKey && bSidePrimaryKey) {\n batch.removeLink(\n aSideObjectTypeApiName,\n aSidePrimaryKey,\n linkTypeApiNameAtoB,\n bSideObjectTypeApiName,\n bSidePrimaryKey,\n );\n }\n break;\n }\n // Handle other operation types as needed\n case \"createInterfaceObject\":\n case \"modifyInterfaceObject\":\n case \"deleteInterfaceObject\":\n // These operations are not implemented for now\n throw new Error(\n `Operation type ${operation.type} not implemented yet`,\n );\n break;\n default:\n throw new Error(`Unknown operation type: ${(operation as any).type}`);\n }\n }\n };\n}\n\nfunction camelcase(apiName: string): string {\n return apiName\n .toLowerCase()\n .replace(/[-_]+(.)?/g, (_, chr) => (chr ? chr.toUpperCase() : \"\"));\n}\n\nfunction toDataValue(value: any, param: Ontologies.ActionParameterV2): unknown {\n if (param.dataType.type === \"geoshape\" && typeof value === \"string\") {\n return latLonStringToGeoJSON(value);\n }\n return value;\n}\n\nfunction latLonStringToGeoJSON(latLonStr: string) {\n // Split the string by comma and parse as floats\n const [lat, lon] = latLonStr.split(\",\").map(Number);\n\n // Basic validation\n if (\n isNaN(lat)\n || isNaN(lon)\n || lat < -90\n || lat > 90\n || lon < -180\n || lon > 180\n ) {\n throw new Error(\"Invalid latitude or longitude\");\n }\n\n // Return GeoJSON Point\n return {\n type: \"Point\",\n coordinates: [lon, lat], // GeoJSON uses [longitude, latitude]\n };\n}\n"],"mappings":"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","ignoreList":[]}
@@ -0,0 +1,61 @@
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 { msw } from "@osdk/faux";
18
+ import { Readable } from "stream";
19
+ export async function routeConnectToMsw(baseUrl, handlers, emitter, req, res, next) {
20
+ const method = req.method ?? "GET";
21
+ const canRequestHaveBody = method !== "HEAD" && method !== "GET";
22
+ const mockRequest = new Request(new URL(req.url, baseUrl), {
23
+ method,
24
+ headers: new Headers(req.headers),
25
+ credentials: "omit",
26
+ // @ts-expect-error Internal Undici property.
27
+ duplex: canRequestHaveBody ? "half" : undefined,
28
+ body: canRequestHaveBody ? Readable.toWeb(req) : undefined
29
+ });
30
+ await msw.handleRequest(mockRequest, crypto.randomUUID(), handlers, {
31
+ onUnhandledRequest: "bypass"
32
+ }, emitter, {
33
+ resolutionContext: {
34
+ baseUrl
35
+ },
36
+ // eslint-disable-next-line @typescript-eslint/require-await
37
+ async onMockedResponse(mockedResponse) {
38
+ const {
39
+ status,
40
+ statusText,
41
+ headers
42
+ } = mockedResponse;
43
+ res.statusCode = status;
44
+ res.statusMessage = statusText;
45
+ headers.forEach((value, name) => {
46
+ res.appendHeader(name, value);
47
+ });
48
+ if (mockedResponse.body) {
49
+ // @ts-expect-error Types don't match exactly
50
+ const stream = Readable.fromWeb(mockedResponse.body);
51
+ stream.pipe(res);
52
+ } else {
53
+ res.end();
54
+ }
55
+ },
56
+ onPassthroughResponse() {
57
+ next();
58
+ }
59
+ });
60
+ }
61
+ //# sourceMappingURL=routeConnectToMsw.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"routeConnectToMsw.js","names":["msw","Readable","routeConnectToMsw","baseUrl","handlers","emitter","req","res","next","method","canRequestHaveBody","mockRequest","Request","URL","url","headers","Headers","credentials","duplex","undefined","body","toWeb","handleRequest","crypto","randomUUID","onUnhandledRequest","resolutionContext","onMockedResponse","mockedResponse","status","statusText","statusCode","statusMessage","forEach","value","name","appendHeader","stream","fromWeb","pipe","end","onPassthroughResponse"],"sources":["routeConnectToMsw.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 { msw } from \"@osdk/faux\";\nimport type { IncomingMessage, ServerResponse } from \"http\";\nimport type { EventEmitter } from \"node:events\";\nimport { Readable } from \"stream\";\nimport type { Connect } from \"vite\";\n\nexport async function routeConnectToMsw(\n baseUrl: string,\n handlers: FauxFoundry[\"handlers\"],\n emitter: EventEmitter<msw.LifeCycleEventsMap>,\n req: Connect.IncomingMessage,\n res: ServerResponse<IncomingMessage>,\n next: Connect.NextFunction,\n): Promise<void> {\n const method = req.method ?? \"GET\";\n const canRequestHaveBody = method !== \"HEAD\" && method !== \"GET\";\n\n const mockRequest = new Request(new URL(req.url!, baseUrl), {\n method,\n headers: new Headers(req.headers as HeadersInit),\n credentials: \"omit\",\n // @ts-expect-error Internal Undici property.\n duplex: canRequestHaveBody ? \"half\" : undefined,\n body: canRequestHaveBody\n ? (Readable.toWeb(req) as ReadableStream)\n : undefined,\n });\n\n await msw.handleRequest(\n mockRequest,\n crypto.randomUUID(),\n handlers,\n {\n onUnhandledRequest: \"bypass\",\n },\n emitter as unknown as Parameters<typeof msw[\"handleRequest\"]>[4],\n {\n resolutionContext: {\n baseUrl,\n },\n // eslint-disable-next-line @typescript-eslint/require-await\n async onMockedResponse(mockedResponse) {\n const { status, statusText, headers } = mockedResponse;\n\n res.statusCode = status;\n res.statusMessage = statusText;\n\n headers.forEach((value, name) => {\n res.appendHeader(name, value);\n });\n\n if (mockedResponse.body) {\n // @ts-expect-error Types don't match exactly\n const stream = Readable.fromWeb(mockedResponse.body);\n stream.pipe(res);\n } else {\n res.end();\n }\n },\n onPassthroughResponse() {\n next();\n },\n },\n );\n}\n"],"mappings":"AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAGA,SAASA,GAAG,QAAQ,YAAY;AAGhC,SAASC,QAAQ,QAAQ,QAAQ;AAGjC,OAAO,eAAeC,iBAAiBA,CACrCC,OAAe,EACfC,QAAiC,EACjCC,OAA6C,EAC7CC,GAA4B,EAC5BC,GAAoC,EACpCC,IAA0B,EACX;EACf,MAAMC,MAAM,GAAGH,GAAG,CAACG,MAAM,IAAI,KAAK;EAClC,MAAMC,kBAAkB,GAAGD,MAAM,KAAK,MAAM,IAAIA,MAAM,KAAK,KAAK;EAEhE,MAAME,WAAW,GAAG,IAAIC,OAAO,CAAC,IAAIC,GAAG,CAACP,GAAG,CAACQ,GAAG,EAAGX,OAAO,CAAC,EAAE;IAC1DM,MAAM;IACNM,OAAO,EAAE,IAAIC,OAAO,CAACV,GAAG,CAACS,OAAsB,CAAC;IAChDE,WAAW,EAAE,MAAM;IACnB;IACAC,MAAM,EAAER,kBAAkB,GAAG,MAAM,GAAGS,SAAS;IAC/CC,IAAI,EAAEV,kBAAkB,GACnBT,QAAQ,CAACoB,KAAK,CAACf,GAAG,CAAC,GACpBa;EACN,CAAC,CAAC;EAEF,MAAMnB,GAAG,CAACsB,aAAa,CACrBX,WAAW,EACXY,MAAM,CAACC,UAAU,CAAC,CAAC,EACnBpB,QAAQ,EACR;IACEqB,kBAAkB,EAAE;EACtB,CAAC,EACDpB,OAAO,EACP;IACEqB,iBAAiB,EAAE;MACjBvB;IACF,CAAC;IACD;IACA,MAAMwB,gBAAgBA,CAACC,cAAc,EAAE;MACrC,MAAM;QAAEC,MAAM;QAAEC,UAAU;QAAEf;MAAQ,CAAC,GAAGa,cAAc;MAEtDrB,GAAG,CAACwB,UAAU,GAAGF,MAAM;MACvBtB,GAAG,CAACyB,aAAa,GAAGF,UAAU;MAE9Bf,OAAO,CAACkB,OAAO,CAAC,CAACC,KAAK,EAAEC,IAAI,KAAK;QAC/B5B,GAAG,CAAC6B,YAAY,CAACD,IAAI,EAAED,KAAK,CAAC;MAC/B,CAAC,CAAC;MAEF,IAAIN,cAAc,CAACR,IAAI,EAAE;QACvB;QACA,MAAMiB,MAAM,GAAGpC,QAAQ,CAACqC,OAAO,CAACV,cAAc,CAACR,IAAI,CAAC;QACpDiB,MAAM,CAACE,IAAI,CAAChC,GAAG,CAAC;MAClB,CAAC,MAAM;QACLA,GAAG,CAACiC,GAAG,CAAC,CAAC;MACX;IACF,CAAC;IACDC,qBAAqBA,CAAA,EAAG;MACtBjC,IAAI,CAAC,CAAC;IACR;EACF,CACF,CAAC;AACH","ignoreList":[]}
@@ -0,0 +1,204 @@
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 crypto from "node:crypto";
18
+ import fs from "node:fs";
19
+ import path from "node:path";
20
+ import { NOISY } from "./generateOntologyAssets.js";
21
+
22
+ /**
23
+ * Synchronize directories by copying only changed files and removing obsolete ones
24
+ */
25
+ export async function syncDirectories(sourceDir, targetDir, logger) {
26
+ if (NOISY) {
27
+ logger.info(`Synchronizing ${sourceDir} to ${targetDir}`, {
28
+ timestamp: true
29
+ });
30
+ }
31
+
32
+ // Ensure target directory exists
33
+ await fs.promises.mkdir(targetDir, {
34
+ recursive: true
35
+ });
36
+
37
+ // Get all files in both directories
38
+ const [sourceFiles, targetFiles] = await Promise.all([getAllFiles(sourceDir), getAllFiles(targetDir)]);
39
+ let updatedCount = 0;
40
+ let addedCount = 0;
41
+ let removedCount = 0;
42
+ let unchangedCount = 0;
43
+ const errors = [];
44
+
45
+ // Process files from source directory
46
+ for (const relativeFile of sourceFiles) {
47
+ const sourceFile = path.join(sourceDir, relativeFile);
48
+ const targetFile = path.join(targetDir, relativeFile);
49
+ try {
50
+ const targetExists = targetFiles.includes(relativeFile);
51
+ const isDifferent = await areFilesDifferent(sourceFile, targetFile);
52
+ if (!targetExists) {
53
+ // New file - need to create directory structure
54
+ await fs.promises.mkdir(path.dirname(targetFile), {
55
+ recursive: true
56
+ });
57
+ await fs.promises.copyFile(sourceFile, targetFile);
58
+ addedCount++;
59
+ logger.info(`Added: ${relativeFile}`, {
60
+ timestamp: true
61
+ });
62
+ } else if (isDifferent) {
63
+ // Changed file - update it
64
+ await fs.promises.copyFile(sourceFile, targetFile);
65
+ updatedCount++;
66
+ logger.info(`Updated: ${targetFile}`, {
67
+ timestamp: true
68
+ });
69
+ } else {
70
+ // File is unchanged
71
+ unchangedCount++;
72
+ }
73
+ } catch (error) {
74
+ const errorMsg = `Failed to sync ${relativeFile}: ${error instanceof Error ? error.message : String(error)}`;
75
+ errors.push(errorMsg);
76
+ logger.error(errorMsg, {
77
+ timestamp: true
78
+ });
79
+ }
80
+ }
81
+
82
+ // Remove files that exist in target but not in source
83
+ for (const relativeFile of targetFiles) {
84
+ if (!sourceFiles.includes(relativeFile)) {
85
+ const targetFile = path.join(targetDir, relativeFile);
86
+ try {
87
+ await fs.promises.unlink(targetFile);
88
+ removedCount++;
89
+ logger.info(`Removed: ${relativeFile}`, {
90
+ timestamp: true
91
+ });
92
+ } catch (error) {
93
+ const errorMsg = `Failed to remove ${relativeFile}: ${error instanceof Error ? error.message : String(error)}`;
94
+ errors.push(errorMsg);
95
+ logger.error(errorMsg, {
96
+ timestamp: true
97
+ });
98
+ }
99
+ }
100
+ }
101
+
102
+ // Clean up empty directories in target
103
+ try {
104
+ await removeEmptyDirectories(targetDir);
105
+ } catch (error) {
106
+ logger.warn(`Failed to clean up empty directories: ${error instanceof Error ? error.message : String(error)}`, {
107
+ timestamp: true
108
+ });
109
+ }
110
+ if (NOISY) {
111
+ // Log summary
112
+ logger.info(`Sync complete: ${addedCount} added, ${updatedCount} updated, ${removedCount} removed, ${unchangedCount} unchanged`, {
113
+ timestamp: true
114
+ });
115
+ }
116
+ if (errors.length > 0) {
117
+ logger.warn(`Encountered ${errors.length} errors during sync`, {
118
+ timestamp: true
119
+ });
120
+ }
121
+ }
122
+
123
+ /**
124
+ * Remove empty directories recursively
125
+ */
126
+ async function removeEmptyDirectories(dir) {
127
+ try {
128
+ const entries = await fs.promises.readdir(dir, {
129
+ withFileTypes: true
130
+ });
131
+
132
+ // First, recursively clean subdirectories
133
+ for (const entry of entries) {
134
+ if (entry.isDirectory()) {
135
+ const subdir = path.join(dir, entry.name);
136
+ await removeEmptyDirectories(subdir);
137
+ }
138
+ }
139
+
140
+ // Then check if this directory is now empty
141
+ const remainingEntries = await fs.promises.readdir(dir);
142
+ if (remainingEntries.length === 0) {
143
+ // Don't remove the root target directory itself
144
+
145
+ if (path.resolve(dir) !== path.resolve(".osdk/src")) {
146
+ await fs.promises.rmdir(dir);
147
+ }
148
+ }
149
+ } catch (error) {
150
+ // Ignore errors when cleaning up directories
151
+ }
152
+ }
153
+
154
+ /**
155
+ * Calculate SHA-256 hash of a file's contents
156
+ */
157
+ async function getFileHash(filePath) {
158
+ try {
159
+ const content = await fs.promises.readFile(filePath);
160
+ return crypto.createHash("sha256").update(content).digest("hex");
161
+ } catch (error) {
162
+ // Return empty hash for non-existent files
163
+ return "";
164
+ }
165
+ }
166
+
167
+ /**
168
+ * Check if two files are different by comparing their hashes
169
+ */
170
+ async function areFilesDifferent(sourceFile, targetFile) {
171
+ try {
172
+ const [sourceHash, targetHash] = await Promise.all([getFileHash(sourceFile), getFileHash(targetFile)]);
173
+ return sourceHash !== targetHash || sourceHash === ""; // Different if hashes differ or source doesn't exist
174
+ } catch (error) {
175
+ // If we can't compare, assume they're different to be safe
176
+ return true;
177
+ }
178
+ }
179
+
180
+ /**
181
+ * Recursively get all files in a directory
182
+ */
183
+ async function getAllFiles(dir, baseDir = dir) {
184
+ const files = [];
185
+ try {
186
+ const entries = await fs.promises.readdir(dir, {
187
+ withFileTypes: true
188
+ });
189
+ for (const entry of entries) {
190
+ const fullPath = path.join(dir, entry.name);
191
+ const relativePath = path.relative(baseDir, fullPath);
192
+ if (entry.isDirectory()) {
193
+ const subFiles = await getAllFiles(fullPath, baseDir);
194
+ files.push(...subFiles);
195
+ } else if (entry.isFile()) {
196
+ files.push(relativePath);
197
+ }
198
+ }
199
+ } catch (error) {
200
+ // Directory doesn't exist or can't be read
201
+ }
202
+ return files;
203
+ }
204
+ //# sourceMappingURL=syncDirectories.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"syncDirectories.js","names":["crypto","fs","path","NOISY","syncDirectories","sourceDir","targetDir","logger","info","timestamp","promises","mkdir","recursive","sourceFiles","targetFiles","Promise","all","getAllFiles","updatedCount","addedCount","removedCount","unchangedCount","errors","relativeFile","sourceFile","join","targetFile","targetExists","includes","isDifferent","areFilesDifferent","dirname","copyFile","error","errorMsg","Error","message","String","push","unlink","removeEmptyDirectories","warn","length","dir","entries","readdir","withFileTypes","entry","isDirectory","subdir","name","remainingEntries","resolve","rmdir","getFileHash","filePath","content","readFile","createHash","update","digest","sourceHash","targetHash","baseDir","files","fullPath","relativePath","relative","subFiles","isFile"],"sources":["syncDirectories.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 crypto from \"node:crypto\";\nimport fs from \"node:fs\";\nimport path from \"node:path\";\nimport type { Logger } from \"vite\";\nimport { NOISY } from \"./generateOntologyAssets.js\";\n\n/**\n * Synchronize directories by copying only changed files and removing obsolete ones\n */\nexport async function syncDirectories(\n sourceDir: string,\n targetDir: string,\n logger: Logger,\n): Promise<void> {\n if (NOISY) {\n logger.info(`Synchronizing ${sourceDir} to ${targetDir}`, {\n timestamp: true,\n });\n }\n\n // Ensure target directory exists\n await fs.promises.mkdir(targetDir, { recursive: true });\n\n // Get all files in both directories\n const [sourceFiles, targetFiles] = await Promise.all([\n getAllFiles(sourceDir),\n getAllFiles(targetDir),\n ]);\n\n let updatedCount = 0;\n let addedCount = 0;\n let removedCount = 0;\n let unchangedCount = 0;\n const errors: string[] = [];\n\n // Process files from source directory\n for (const relativeFile of sourceFiles) {\n const sourceFile = path.join(sourceDir, relativeFile);\n const targetFile = path.join(targetDir, relativeFile);\n\n try {\n const targetExists = targetFiles.includes(relativeFile);\n const isDifferent = await areFilesDifferent(sourceFile, targetFile);\n\n if (!targetExists) {\n // New file - need to create directory structure\n await fs.promises.mkdir(path.dirname(targetFile), { recursive: true });\n await fs.promises.copyFile(sourceFile, targetFile);\n addedCount++;\n logger.info(`Added: ${relativeFile}`, { timestamp: true });\n } else if (isDifferent) {\n // Changed file - update it\n await fs.promises.copyFile(sourceFile, targetFile);\n updatedCount++;\n logger.info(`Updated: ${targetFile}`, { timestamp: true });\n } else {\n // File is unchanged\n unchangedCount++;\n }\n } catch (error) {\n const errorMsg = `Failed to sync ${relativeFile}: ${\n error instanceof Error ? error.message : String(error)\n }`;\n errors.push(errorMsg);\n logger.error(errorMsg, { timestamp: true });\n }\n }\n\n // Remove files that exist in target but not in source\n for (const relativeFile of targetFiles) {\n if (!sourceFiles.includes(relativeFile)) {\n const targetFile = path.join(targetDir, relativeFile);\n try {\n await fs.promises.unlink(targetFile);\n removedCount++;\n logger.info(`Removed: ${relativeFile}`, { timestamp: true });\n } catch (error) {\n const errorMsg = `Failed to remove ${relativeFile}: ${\n error instanceof Error ? error.message : String(error)\n }`;\n errors.push(errorMsg);\n logger.error(errorMsg, { timestamp: true });\n }\n }\n }\n\n // Clean up empty directories in target\n try {\n await removeEmptyDirectories(targetDir);\n } catch (error) {\n logger.warn(\n `Failed to clean up empty directories: ${\n error instanceof Error ? error.message : String(error)\n }`,\n { timestamp: true },\n );\n }\n\n if (NOISY) {\n // Log summary\n logger.info(\n `Sync complete: ${addedCount} added, ${updatedCount} updated, ${removedCount} removed, ${unchangedCount} unchanged`,\n { timestamp: true },\n );\n }\n\n if (errors.length > 0) {\n logger.warn(`Encountered ${errors.length} errors during sync`, {\n timestamp: true,\n });\n }\n}\n\n/**\n * Remove empty directories recursively\n */\nasync function removeEmptyDirectories(dir: string): Promise<void> {\n try {\n const entries = await fs.promises.readdir(dir, { withFileTypes: true });\n\n // First, recursively clean subdirectories\n for (const entry of entries) {\n if (entry.isDirectory()) {\n const subdir = path.join(dir, entry.name);\n await removeEmptyDirectories(subdir);\n }\n }\n\n // Then check if this directory is now empty\n const remainingEntries = await fs.promises.readdir(dir);\n if (remainingEntries.length === 0) {\n // Don't remove the root target directory itself\n const targetDir = \".osdk/src\";\n if (path.resolve(dir) !== path.resolve(targetDir)) {\n await fs.promises.rmdir(dir);\n }\n }\n } catch (error) {\n // Ignore errors when cleaning up directories\n }\n}\n\n/**\n * Calculate SHA-256 hash of a file's contents\n */\nasync function getFileHash(filePath: string): Promise<string> {\n try {\n const content = await fs.promises.readFile(filePath);\n return crypto.createHash(\"sha256\").update(content).digest(\"hex\");\n } catch (error) {\n // Return empty hash for non-existent files\n return \"\";\n }\n}\n\n/**\n * Check if two files are different by comparing their hashes\n */\nasync function areFilesDifferent(\n sourceFile: string,\n targetFile: string,\n): Promise<boolean> {\n try {\n const [sourceHash, targetHash] = await Promise.all([\n getFileHash(sourceFile),\n getFileHash(targetFile),\n ]);\n return sourceHash !== targetHash || sourceHash === \"\"; // Different if hashes differ or source doesn't exist\n } catch (error) {\n // If we can't compare, assume they're different to be safe\n return true;\n }\n}\n\n/**\n * Recursively get all files in a directory\n */\nasync function getAllFiles(\n dir: string,\n baseDir: string = dir,\n): Promise<string[]> {\n const files: string[] = [];\n\n try {\n const entries = await fs.promises.readdir(dir, { withFileTypes: true });\n\n for (const entry of entries) {\n const fullPath = path.join(dir, entry.name);\n const relativePath = path.relative(baseDir, fullPath);\n\n if (entry.isDirectory()) {\n const subFiles = await getAllFiles(fullPath, baseDir);\n files.push(...subFiles);\n } else if (entry.isFile()) {\n files.push(relativePath);\n }\n }\n } catch (error) {\n // Directory doesn't exist or can't be read\n }\n\n return files;\n}\n"],"mappings":"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","ignoreList":[]}
@@ -0,0 +1,22 @@
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 * as fs from "node:fs";
18
+ export function readJsonFile(arg0) {
19
+ const content = fs.readFileSync(arg0, "utf-8");
20
+ return JSON.parse(content);
21
+ }
22
+ //# sourceMappingURL=readJsonFile.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"readJsonFile.js","names":["fs","readJsonFile","arg0","content","readFileSync","JSON","parse"],"sources":["readJsonFile.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 * as fs from \"node:fs\";\n\nexport function readJsonFile<T>(arg0: string): T {\n const content = fs.readFileSync(arg0, \"utf-8\");\n return JSON.parse(content);\n}\n"],"mappings":"AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA,OAAO,KAAKA,EAAE,MAAM,SAAS;AAE7B,OAAO,SAASC,YAAYA,CAAIC,IAAY,EAAK;EAC/C,MAAMC,OAAO,GAAGH,EAAE,CAACI,YAAY,CAACF,IAAI,EAAE,OAAO,CAAC;EAC9C,OAAOG,IAAI,CAACC,KAAK,CAACH,OAAO,CAAC;AAC5B","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 EventEmitter from "node:events";
18
+ import fs from "node:fs";
19
+ import { generateOntologyAssets } from "./generateOntologyAssets.js";
20
+ export function watchOntologyAsCode({
21
+ watcher,
22
+ logger,
23
+ ontologyDir
24
+ }) {
25
+ const emitter = new EventEmitter();
26
+ logger.info(`Starting OAC file watcher for ${ontologyDir}`, {
27
+ timestamp: true
28
+ });
29
+ if (!fs.existsSync(ontologyDir)) {
30
+ fs.mkdirSync(ontologyDir, {
31
+ recursive: true
32
+ });
33
+ logger.info("Created .ontology directory", {
34
+ timestamp: true
35
+ });
36
+ }
37
+ watcher.add(ontologyDir);
38
+
39
+ // Add event listeners
40
+ watcher.on("add", handleOacFileChanged).on("change", handleOacFileChanged).on("unlink", handleOacFileChanged);
41
+
42
+ // invoke the handler at startup
43
+ handleOacFileChanged(undefined);
44
+ return emitter;
45
+ function handleOacFileChanged(filePath) {
46
+ if (filePath && !filePath.startsWith(`${ontologyDir}/`)) {
47
+ return;
48
+ }
49
+ if (filePath) {
50
+ logger.info(`File ${filePath} changed.`, {
51
+ timestamp: true
52
+ });
53
+ }
54
+ (async () => {
55
+ await generateOntologyAssets({
56
+ logger,
57
+ ontologyDir
58
+ });
59
+ emitter.emit("generated");
60
+ })().catch(error => {
61
+ // eslint-disable-next-line no-console
62
+ console.error(error);
63
+ logger.error(`Error executing command: ${error.message}`, {
64
+ timestamp: true
65
+ });
66
+ });
67
+ }
68
+ }
69
+ //# sourceMappingURL=watchOntologyAsCode.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"watchOntologyAsCode.js","names":["EventEmitter","fs","generateOntologyAssets","watchOntologyAsCode","watcher","logger","ontologyDir","emitter","info","timestamp","existsSync","mkdirSync","recursive","add","on","handleOacFileChanged","undefined","filePath","startsWith","emit","catch","error","console","message"],"sources":["watchOntologyAsCode.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 EventEmitter from \"node:events\";\nimport fs from \"node:fs\";\nimport type { FSWatcher, Logger } from \"vite\";\nimport { generateOntologyAssets } from \"./generateOntologyAssets.js\";\n\nexport interface WatchOntologyAsCodeEvents {\n generated: [];\n}\n\nexport function watchOntologyAsCode(\n { watcher, logger, ontologyDir }: {\n watcher: FSWatcher;\n logger: Logger;\n ontologyDir: string;\n },\n): EventEmitter<WatchOntologyAsCodeEvents> {\n const emitter = new EventEmitter<WatchOntologyAsCodeEvents>();\n logger.info(`Starting OAC file watcher for ${ontologyDir}`, {\n timestamp: true,\n });\n\n if (!fs.existsSync(ontologyDir)) {\n fs.mkdirSync(ontologyDir, { recursive: true });\n\n logger.info(\"Created .ontology directory\", { timestamp: true });\n }\n\n watcher.add(ontologyDir);\n\n // Add event listeners\n watcher\n .on(\"add\", handleOacFileChanged)\n .on(\"change\", handleOacFileChanged)\n .on(\"unlink\", handleOacFileChanged);\n\n // invoke the handler at startup\n handleOacFileChanged(undefined);\n\n return emitter;\n\n function handleOacFileChanged(filePath: string | undefined): void {\n if (filePath && !filePath.startsWith(`${ontologyDir}/`)) {\n return;\n }\n\n if (filePath) {\n logger.info(`File ${filePath} changed.`, { timestamp: true });\n }\n\n (async () => {\n await generateOntologyAssets({\n logger,\n ontologyDir,\n });\n emitter.emit(\"generated\");\n })().catch((error) => {\n // eslint-disable-next-line no-console\n console.error(error);\n logger.error(`Error executing command: ${error.message}`, {\n timestamp: true,\n });\n });\n }\n}\n"],"mappings":"AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA,OAAOA,YAAY,MAAM,aAAa;AACtC,OAAOC,EAAE,MAAM,SAAS;AAExB,SAASC,sBAAsB,QAAQ,6BAA6B;AAMpE,OAAO,SAASC,mBAAmBA,CACjC;EAAEC,OAAO;EAAEC,MAAM;EAAEC;AAInB,CAAC,EACwC;EACzC,MAAMC,OAAO,GAAG,IAAIP,YAAY,CAA4B,CAAC;EAC7DK,MAAM,CAACG,IAAI,CAAC,iCAAiCF,WAAW,EAAE,EAAE;IAC1DG,SAAS,EAAE;EACb,CAAC,CAAC;EAEF,IAAI,CAACR,EAAE,CAACS,UAAU,CAACJ,WAAW,CAAC,EAAE;IAC/BL,EAAE,CAACU,SAAS,CAACL,WAAW,EAAE;MAAEM,SAAS,EAAE;IAAK,CAAC,CAAC;IAE9CP,MAAM,CAACG,IAAI,CAAC,6BAA6B,EAAE;MAAEC,SAAS,EAAE;IAAK,CAAC,CAAC;EACjE;EAEAL,OAAO,CAACS,GAAG,CAACP,WAAW,CAAC;;EAExB;EACAF,OAAO,CACJU,EAAE,CAAC,KAAK,EAAEC,oBAAoB,CAAC,CAC/BD,EAAE,CAAC,QAAQ,EAAEC,oBAAoB,CAAC,CAClCD,EAAE,CAAC,QAAQ,EAAEC,oBAAoB,CAAC;;EAErC;EACAA,oBAAoB,CAACC,SAAS,CAAC;EAE/B,OAAOT,OAAO;EAEd,SAASQ,oBAAoBA,CAACE,QAA4B,EAAQ;IAChE,IAAIA,QAAQ,IAAI,CAACA,QAAQ,CAACC,UAAU,CAAC,GAAGZ,WAAW,GAAG,CAAC,EAAE;MACvD;IACF;IAEA,IAAIW,QAAQ,EAAE;MACZZ,MAAM,CAACG,IAAI,CAAC,QAAQS,QAAQ,WAAW,EAAE;QAAER,SAAS,EAAE;MAAK,CAAC,CAAC;IAC/D;IAEA,CAAC,YAAY;MACX,MAAMP,sBAAsB,CAAC;QAC3BG,MAAM;QACNC;MACF,CAAC,CAAC;MACFC,OAAO,CAACY,IAAI,CAAC,WAAW,CAAC;IAC3B,CAAC,EAAE,CAAC,CAACC,KAAK,CAAEC,KAAK,IAAK;MACpB;MACAC,OAAO,CAACD,KAAK,CAACA,KAAK,CAAC;MACpBhB,MAAM,CAACgB,KAAK,CAAC,4BAA4BA,KAAK,CAACE,OAAO,EAAE,EAAE;QACxDd,SAAS,EAAE;MACb,CAAC,CAAC;IACJ,CAAC,CAAC;EACJ;AACF","ignoreList":[]}