| 
									
										
										
										
											2023-08-05 12:04:58 +05:30
										 |  |  | /* | 
					
						
							| 
									
										
										
										
											2024-11-13 08:47:44 +01:00
										 |  |  |  *  Copyright 2024 Collate. | 
					
						
							| 
									
										
										
										
											2023-08-05 12:04:58 +05:30
										 |  |  |  *  Licensed under the Apache License, Version 2.0 (the "License"); | 
					
						
							|  |  |  |  *  you may not use this file except in compliance with the License. | 
					
						
							|  |  |  |  *  You may obtain a copy of the License at | 
					
						
							|  |  |  |  *  http://www.apache.org/licenses/LICENSE-2.0
 | 
					
						
							|  |  |  |  *  Unless required by applicable law or agreed to in writing, software | 
					
						
							|  |  |  |  *  distributed under the License is distributed on an "AS IS" BASIS, | 
					
						
							|  |  |  |  *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | 
					
						
							|  |  |  |  *  See the License for the specific language governing permissions and | 
					
						
							|  |  |  |  *  limitations under the License. | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | /* eslint-disable */ | 
					
						
							|  |  |  | const $RefParser = require('@apidevtools/json-schema-ref-parser'); | 
					
						
							|  |  |  | const path = require('path'); | 
					
						
							|  |  |  | const fs = require('fs'); | 
					
						
							|  |  |  | const fse = require('fs-extra'); | 
					
						
							|  |  |  | const process = require('process'); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | const cwd = process.cwd(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | const schemaDir = | 
					
						
							|  |  |  |   '../../../../../openmetadata-spec/src/main/resources/json/schema'; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | const globalParserOptions = { | 
					
						
							|  |  |  |   continueOnError: true, | 
					
						
							|  |  |  |   dereference: { | 
					
						
							|  |  |  |     circular: true, | 
					
						
							|  |  |  |   }, | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | const parser = new $RefParser(globalParserOptions); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-11-13 08:47:44 +01:00
										 |  |  | // Function to recursively remove any object by key
 | 
					
						
							| 
									
										
										
										
											2023-10-30 15:43:55 +05:30
										 |  |  | function removeObjectByKey(obj, keyToRemove) { | 
					
						
							|  |  |  |   if (typeof obj == 'object') { | 
					
						
							|  |  |  |     for (const prop in obj) { | 
					
						
							|  |  |  |       if (prop === keyToRemove) { | 
					
						
							|  |  |  |         // If the property key matches the key to remove, delete it
 | 
					
						
							|  |  |  |         delete obj[prop]; | 
					
						
							|  |  |  |       } else { | 
					
						
							|  |  |  |         // Recursively call the function on the property's value
 | 
					
						
							|  |  |  |         obj[prop] = removeObjectByKey(obj[prop], keyToRemove); | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  |   return obj; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-11-13 08:47:44 +01:00
										 |  |  | async function parseSchema(filePath, destPath, shouldDereference = false) { | 
					
						
							| 
									
										
										
										
											2023-08-05 12:04:58 +05:30
										 |  |  |   try { | 
					
						
							|  |  |  |     const fileDir = `${cwd}/${path.dirname(filePath)}`; | 
					
						
							|  |  |  |     const fileName = path.basename(filePath); | 
					
						
							|  |  |  |     process.chdir(fileDir); | 
					
						
							| 
									
										
										
										
											2023-08-20 12:01:06 +05:30
										 |  |  | 
 | 
					
						
							|  |  |  |     let parsedSchema = await parser.parse(fileName); | 
					
						
							| 
									
										
										
										
											2024-11-13 08:47:44 +01:00
										 |  |  |     if (shouldDereference || fileName.startsWith('dbt')) { | 
					
						
							| 
									
										
										
										
											2023-08-20 12:01:06 +05:30
										 |  |  |       parsedSchema = await parser.dereference(parsedSchema); | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2023-08-05 12:04:58 +05:30
										 |  |  |     const api = await parser.bundle(parsedSchema); | 
					
						
							|  |  |  |     const dirname = `${cwd}/${path.dirname(destPath)}`; | 
					
						
							| 
									
										
										
										
											2023-10-30 15:43:55 +05:30
										 |  |  |     const updatedAPIWithoutID = removeObjectByKey(api, '$id'); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-08-05 12:04:58 +05:30
										 |  |  |     if (!fs.existsSync(dirname)) { | 
					
						
							|  |  |  |       try { | 
					
						
							|  |  |  |         fs.mkdirSync(dirname, { recursive: true }); | 
					
						
							|  |  |  |       } catch (err) { | 
					
						
							|  |  |  |         console.log(err); | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2023-10-30 15:43:55 +05:30
										 |  |  |     fs.writeFileSync( | 
					
						
							|  |  |  |       `${cwd}/${destPath}`, | 
					
						
							|  |  |  |       JSON.stringify(updatedAPIWithoutID, null, 2) | 
					
						
							|  |  |  |     ); | 
					
						
							| 
									
										
										
										
											2023-08-05 12:04:58 +05:30
										 |  |  |   } catch (err) { | 
					
						
							|  |  |  |     console.log(err); | 
					
						
							|  |  |  |   } finally { | 
					
						
							|  |  |  |     process.chdir(cwd); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-11-13 08:47:44 +01:00
										 |  |  | // Function to traverse directories and parse files
 | 
					
						
							|  |  |  | async function traverseDirectory( | 
					
						
							|  |  |  |   Directory, | 
					
						
							|  |  |  |   playDir, | 
					
						
							|  |  |  |   destDir, | 
					
						
							|  |  |  |   shouldDereference = false | 
					
						
							|  |  |  | ) { | 
					
						
							| 
									
										
										
										
											2023-08-05 12:04:58 +05:30
										 |  |  |   const Files = fs.readdirSync(Directory); | 
					
						
							|  |  |  |   for (const File of Files) { | 
					
						
							|  |  |  |     const Absolute = path.join(Directory, File); | 
					
						
							|  |  |  |     if (fs.statSync(Absolute).isDirectory()) { | 
					
						
							| 
									
										
										
										
											2024-11-13 08:47:44 +01:00
										 |  |  |       await traverseDirectory(Absolute, playDir, destDir, shouldDereference); | 
					
						
							| 
									
										
										
										
											2023-08-05 12:04:58 +05:30
										 |  |  |     } else { | 
					
						
							|  |  |  |       const name = Absolute.replace(playDir, destDir); | 
					
						
							| 
									
										
										
										
											2024-11-13 08:47:44 +01:00
										 |  |  |       await parseSchema(Absolute, name, shouldDereference); | 
					
						
							| 
									
										
										
										
											2023-08-05 12:04:58 +05:30
										 |  |  |     } | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-11-13 08:47:44 +01:00
										 |  |  | // Function to copy source files
 | 
					
						
							|  |  |  | function copySourceFiles(rootDir) { | 
					
						
							| 
									
										
										
										
											2023-08-05 12:04:58 +05:30
										 |  |  |   try { | 
					
						
							|  |  |  |     fse.copySync(schemaDir, `${rootDir}/schema`); | 
					
						
							|  |  |  |   } catch (err) { | 
					
						
							|  |  |  |     console.error(err); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-11-13 08:47:44 +01:00
										 |  |  | // Main function to handle schema parsing
 | 
					
						
							|  |  |  | async function main(rootDir, srcDir, destDir, shouldDereference = false) { | 
					
						
							|  |  |  |   const playDir = `${rootDir}/${srcDir}`; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-08-05 12:04:58 +05:30
										 |  |  |   try { | 
					
						
							|  |  |  |     if (fs.existsSync(destDir)) { | 
					
						
							|  |  |  |       fs.rmSync(destDir, { recursive: true }); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     fs.mkdirSync(destDir, { recursive: true }); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-11-13 08:47:44 +01:00
										 |  |  |     copySourceFiles(rootDir); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     await traverseDirectory(playDir, playDir, destDir, shouldDereference); | 
					
						
							| 
									
										
										
										
											2023-08-05 12:04:58 +05:30
										 |  |  |   } catch (err) { | 
					
						
							|  |  |  |     console.log(err); | 
					
						
							| 
									
										
										
										
											2024-11-13 08:47:44 +01:00
										 |  |  |   } finally { | 
					
						
							|  |  |  |     // Cleanup: Remove the temporary directory
 | 
					
						
							|  |  |  |     if (fs.existsSync(rootDir)) { | 
					
						
							|  |  |  |       fs.rmSync(rootDir, { recursive: true, force: true }); | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2023-08-05 12:04:58 +05:30
										 |  |  |   } | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-08-21 17:23:45 +05:30
										 |  |  | // Function to parse Application schemas
 | 
					
						
							|  |  |  | async function parseApplicationSchemas() { | 
					
						
							|  |  |  |   const appSchemaDir = 'src/utils/ApplicationSchemas'; | 
					
						
							|  |  |  |   const destDir = 'src/jsons/applicationSchemas'; | 
					
						
							|  |  |  |    | 
					
						
							|  |  |  |   try { | 
					
						
							|  |  |  |     // Create destination directory if it doesn't exist
 | 
					
						
							|  |  |  |     if (!fs.existsSync(destDir)) { | 
					
						
							|  |  |  |       fs.mkdirSync(destDir, { recursive: true }); | 
					
						
							|  |  |  |     } else { | 
					
						
							|  |  |  |       // Clean existing destination directory
 | 
					
						
							|  |  |  |       fs.rmSync(destDir, { recursive: true }); | 
					
						
							|  |  |  |       fs.mkdirSync(destDir, { recursive: true }); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |      | 
					
						
							|  |  |  |     // Get all JSON files in ApplicationSchemas directory
 | 
					
						
							|  |  |  |     const files = fs.readdirSync(appSchemaDir).filter(file => file.endsWith('.json')); | 
					
						
							|  |  |  |      | 
					
						
							|  |  |  |     for (const file of files) { | 
					
						
							|  |  |  |       const filePath = path.join(appSchemaDir, file); | 
					
						
							|  |  |  |       const destPath = path.join(destDir, file); | 
					
						
							|  |  |  |        | 
					
						
							|  |  |  |       try { | 
					
						
							|  |  |  |         // Change to the source directory for relative path resolution
 | 
					
						
							|  |  |  |         const fileDir = path.dirname(filePath); | 
					
						
							|  |  |  |         const originalCwd = process.cwd(); | 
					
						
							|  |  |  |         process.chdir(fileDir); | 
					
						
							|  |  |  |          | 
					
						
							|  |  |  |         // Parse and dereference the schema
 | 
					
						
							|  |  |  |         let parsedSchema = await parser.parse(file); | 
					
						
							|  |  |  |         parsedSchema = await parser.dereference(parsedSchema); | 
					
						
							|  |  |  |          | 
					
						
							|  |  |  |         // Remove $id fields
 | 
					
						
							|  |  |  |         const updatedSchema = removeObjectByKey(parsedSchema, '$id'); | 
					
						
							|  |  |  |          | 
					
						
							|  |  |  |         // Change back to original directory
 | 
					
						
							|  |  |  |         process.chdir(originalCwd); | 
					
						
							|  |  |  |          | 
					
						
							|  |  |  |         // Write the processed schema to destination
 | 
					
						
							|  |  |  |         fs.writeFileSync(destPath, JSON.stringify(updatedSchema, null, 2)); | 
					
						
							|  |  |  |         console.log(`Processed ApplicationSchema: ${file}`); | 
					
						
							|  |  |  |       } catch (err) { | 
					
						
							|  |  |  |         console.error(`Error processing ${file}:`, err.message); | 
					
						
							|  |  |  |         process.chdir(cwd); | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |   } catch (err) { | 
					
						
							|  |  |  |     console.error('Error parsing Application schemas:', err); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-11-13 08:47:44 +01:00
										 |  |  | // Execute the parsing for connection and ingestion schemas
 | 
					
						
							|  |  |  | async function runParsers() { | 
					
						
							|  |  |  |   // For connection schemas
 | 
					
						
							|  |  |  |   await main( | 
					
						
							|  |  |  |     'connTemp', | 
					
						
							|  |  |  |     'schema/entity/services/connections', | 
					
						
							|  |  |  |     'src/jsons/connectionSchemas/connections', | 
					
						
							|  |  |  |     true | 
					
						
							|  |  |  |   ); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   // For ingestion schemas (with dereferencing for dbt schemas)
 | 
					
						
							|  |  |  |   await main( | 
					
						
							|  |  |  |     'ingestionTemp', | 
					
						
							|  |  |  |     'schema/metadataIngestion', | 
					
						
							|  |  |  |     'src/jsons/ingestionSchemas' | 
					
						
							|  |  |  |   ); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   await main( | 
					
						
							|  |  |  |     'workflowTemp', | 
					
						
							|  |  |  |     'schema/governance/workflows/elements/nodes', | 
					
						
							|  |  |  |     'src/jsons/governanceSchemas' | 
					
						
							|  |  |  |   ); | 
					
						
							| 
									
										
										
										
											2025-08-21 17:23:45 +05:30
										 |  |  |    | 
					
						
							|  |  |  |   // Parse Application schemas
 | 
					
						
							|  |  |  |   await parseApplicationSchemas(); | 
					
						
							| 
									
										
										
										
											2025-09-23 13:23:46 +05:30
										 |  |  | 
 | 
					
						
							|  |  |  |   // Parse configuration schemas directly
 | 
					
						
							|  |  |  |   const configDir = 'src/jsons/configuration'; | 
					
						
							|  |  |  |   if (!fs.existsSync(configDir)) { | 
					
						
							|  |  |  |     fs.mkdirSync(configDir, { recursive: true }); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   const configSchemas = [ | 
					
						
							|  |  |  |     'authenticationConfiguration.json', | 
					
						
							|  |  |  |     'authorizerConfiguration.json', | 
					
						
							|  |  |  |   ]; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   for (const configFile of configSchemas) { | 
					
						
							|  |  |  |     const srcPath = `${schemaDir}/configuration/${configFile}`; | 
					
						
							|  |  |  |     const destPath = `${configDir}/${configFile}`; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     // Only authenticationConfiguration.json needs dereferencing (has external $ref)
 | 
					
						
							|  |  |  |     const needsDereference = configFile === 'authenticationConfiguration.json'; | 
					
						
							|  |  |  |     await parseSchema(srcPath, destPath, needsDereference); | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2024-11-13 08:47:44 +01:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | runParsers(); |