@rockcarver/frodo-lib 0.12.6 → 0.12.7
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/CHANGELOG.md +10 -1
- package/cjs/api/ApiTypes.js.map +1 -1
- package/cjs/index.js +9 -1
- package/cjs/index.js.map +1 -1
- package/cjs/ops/CirclesOfTrustOps.js +1 -12
- package/cjs/ops/CirclesOfTrustOps.js.map +1 -1
- package/cjs/ops/EmailTemplateOps.js +0 -12
- package/cjs/ops/EmailTemplateOps.js.map +1 -1
- package/cjs/ops/IdpOps.js +1 -12
- package/cjs/ops/IdpOps.js.map +1 -1
- package/cjs/ops/JourneyOps.js +76 -193
- package/cjs/ops/JourneyOps.js.map +1 -1
- package/cjs/ops/NodeOps.js +31 -28
- package/cjs/ops/NodeOps.js.map +1 -1
- package/cjs/ops/OpsTypes.js +28 -0
- package/cjs/ops/OpsTypes.js.map +1 -1
- package/cjs/ops/Saml2Ops.js +1 -21
- package/cjs/ops/Saml2Ops.js.map +1 -1
- package/cjs/ops/ScriptOps.js +0 -12
- package/cjs/ops/ScriptOps.js.map +1 -1
- package/cjs/ops/ThemeOps.js +0 -12
- package/cjs/ops/ThemeOps.js.map +1 -1
- package/esm/index.mjs +3 -0
- package/esm/ops/CirclesOfTrustOps.mjs +1 -11
- package/esm/ops/EmailTemplateOps.mjs +1 -11
- package/esm/ops/IdpOps.mjs +1 -11
- package/esm/ops/JourneyOps.mjs +50 -148
- package/esm/ops/NodeOps.mjs +28 -26
- package/esm/ops/OpsTypes.mjs +24 -1
- package/esm/ops/Saml2Ops.mjs +1 -19
- package/esm/ops/ScriptOps.mjs +0 -10
- package/esm/ops/ThemeOps.mjs +0 -10
- package/package.json +3 -2
- package/types/api/ApiTypes.d.ts +1 -1
- package/types/api/ApiTypes.d.ts.map +1 -1
- package/types/index.d.ts +1 -0
- package/types/index.d.ts.map +1 -1
- package/types/ops/CirclesOfTrustOps.d.ts +0 -7
- package/types/ops/CirclesOfTrustOps.d.ts.map +1 -1
- package/types/ops/EmailTemplateOps.d.ts +0 -7
- package/types/ops/EmailTemplateOps.d.ts.map +1 -1
- package/types/ops/IdpOps.d.ts +0 -7
- package/types/ops/IdpOps.d.ts.map +1 -1
- package/types/ops/JourneyOps.d.ts +4 -26
- package/types/ops/JourneyOps.d.ts.map +1 -1
- package/types/ops/NodeOps.d.ts +10 -8
- package/types/ops/NodeOps.d.ts.map +1 -1
- package/types/ops/OpsTypes.d.ts +12 -0
- package/types/ops/OpsTypes.d.ts.map +1 -1
- package/types/ops/Saml2Ops.d.ts +0 -7
- package/types/ops/Saml2Ops.d.ts.map +1 -1
- package/types/ops/ScriptOps.d.ts +0 -7
- package/types/ops/ScriptOps.d.ts.map +1 -1
- package/types/ops/ThemeOps.d.ts +0 -7
- package/types/ops/ThemeOps.d.ts.map +1 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/ops/Saml2Ops.ts"],"names":[],"mappings":"AAgCA,OAAO,EAAE,qBAAqB,EAAE,MAAM,iBAAiB,CAAC;AAExD,eAAO,MAAM,OAAO;;;;;CAKnB,CAAC;AAEF;;;;GAIG;AACH,wBAAgB,qBAAqB,CACnC,gBAAgB,EAAE,qBAAqB,GACtC,MAAM,CAWR;AAeD;;;GAGG;AACH,wBAAsB,kBAAkB,CAAC,IAAI,UAAQ,iBAsBpD;AAuCD;;;;GAIG;AACH,wBAAsB,yBAAyB,CAAC,QAAQ,KAAA,EAAE,IAAI,MAAO,iBA2CpE;AAED;;;;GAIG;AACH,wBAAsB,mBAAmB,CAAC,QAAQ,KAAA,EAAE,IAAI,MAAO,iBAoB9D;AAED;;;GAGG;AACH,wBAAsB,qBAAqB,CAAC,QAAQ,KAAA,iBA8CnD;AAED;;;GAGG;AACH,wBAAsB,0BAA0B,CAAC,IAAI,MAAO,iBAgC3D;AAED;;GAEG;AACH,wBAAsB,2BAA2B,kBAsBhD;AAgDD;;;;GAIG;AACH,wBAAsB,2BAA2B,CAAC,QAAQ,KAAA,EAAE,IAAI,KAAA,iBAqC/D;AAED;;;GAGG;AACH,wBAAsB,gCAAgC,CAAC,IAAI,KAAA,iBA8C1D;AAED;;;GAGG;AACH,wBAAsB,4BAA4B,CAAC,IAAI,KAAA,iBAoCtD;AAED;;GAEG;AACH,wBAAsB,6BAA6B,kBAoDlD","file":"Saml2Ops.d.ts","sourcesContent":["import fs from 'fs';\nimport _ from 'lodash';\nimport { decode, encode, encodeBase64Url } from '../api/utils/Base64';\nimport {\n createTable,\n printMessage,\n createProgressIndicator,\n updateProgressIndicator,\n stopProgressIndicator,\n createObjectTable,\n} from './utils/Console';\nimport {\n getProviders,\n findProviders,\n getProviderByLocationAndId,\n getProviderMetadata,\n createProvider,\n getProviderMetadataUrl,\n} from '../api/Saml2Api';\nimport { getScript } from '../api/ScriptApi';\nimport {\n convertBase64TextToArray,\n convertBase64UrlTextToArray,\n convertTextArrayToBase64,\n convertTextArrayToBase64Url,\n getRealmString,\n getTypedFilename,\n saveJsonToFile,\n saveTextToFile,\n validateImport,\n} from './utils/ExportImportUtils';\nimport { createOrUpdateScript } from './ScriptOps';\nimport { Saml2ProviderSkeleton } from '../api/ApiTypes';\n\nexport const roleMap = {\n identityProvider: 'IDP',\n serviceProvider: 'SP',\n attributeQueryProvider: 'AttrQuery',\n xacmlPolicyEnforcementPoint: 'XACML PEP',\n};\n\n/**\n * Get a one-line description of the saml2 provider object\n * @param {Saml2ProviderSkeleton} saml2ProviderObj saml2 provider object to describe\n * @returns {string} a one-line description\n */\nexport function getOneLineDescription(\n saml2ProviderObj: Saml2ProviderSkeleton\n): string {\n const roles = [];\n for (const [key, value] of Object.entries(roleMap)) {\n if (saml2ProviderObj[key]) {\n roles.push(value);\n }\n }\n const description = `[${saml2ProviderObj.entityId['brightCyan']}]${\n ' (' + saml2ProviderObj.entityLocation\n }${roles.length ? ' ' + roles.join(', ') + ')' : ')'}`;\n return description;\n}\n\n// use a function vs a template variable to avoid problems in loops\nfunction getFileDataTemplate() {\n return {\n meta: {},\n script: {},\n saml: {\n hosted: {},\n remote: {},\n metadata: {},\n },\n };\n}\n\n/**\n * List entity providers\n * @param {boolean} long Long list format with details\n */\nexport async function listSaml2Providers(long = false) {\n const providerList = (await getProviders()).result;\n providerList.sort((a, b) => a._id.localeCompare(b._id));\n if (!long) {\n for (const provider of providerList) {\n printMessage(`${provider.entityId}`, 'data');\n }\n } else {\n const table = createTable([\n 'Entity Id'['brightCyan'],\n 'Location'['brightCyan'],\n 'Role(s)'['brightCyan'],\n ]);\n for (const provider of providerList) {\n table.push([\n provider.entityId,\n provider.location,\n provider.roles.map((role) => roleMap[role]).join(', '),\n ]);\n }\n printMessage(table.toString());\n }\n}\n\n/**\n * Include dependencies in the export file\n * @param {Object} providerData Object representing a SAML entity provider\n * @param {Object} fileData File data object to add dependencies to\n */\nasync function exportDependencies(providerData, fileData) {\n const attrMapperScriptId = _.get(providerData, [\n 'identityProvider',\n 'assertionProcessing',\n 'attributeMapper',\n 'attributeMapperScript',\n ]);\n if (attrMapperScriptId && attrMapperScriptId !== '[Empty]') {\n const scriptData = await getScript(attrMapperScriptId);\n scriptData.script = convertBase64TextToArray(scriptData.script);\n // eslint-disable-next-line no-param-reassign\n fileData.script[attrMapperScriptId] = scriptData;\n }\n const idpAdapterScriptId = _.get(providerData, [\n 'identityProvider',\n 'advanced',\n 'idpAdapter',\n 'idpAdapterScript',\n ]);\n if (idpAdapterScriptId && idpAdapterScriptId !== '[Empty]') {\n const scriptData = await getScript(idpAdapterScriptId);\n scriptData.script = convertBase64TextToArray(scriptData.script);\n // eslint-disable-next-line no-param-reassign\n fileData.script[idpAdapterScriptId] = scriptData;\n }\n const metaDataResponse = await getProviderMetadata(providerData.entityId);\n // eslint-disable-next-line no-param-reassign\n fileData.saml.metadata[providerData._id] = convertBase64UrlTextToArray(\n encodeBase64Url(metaDataResponse)\n );\n}\n\n/**\n * Export a single entity provider to file\n * @param {String} entityId Provider entity id\n * @param {String} file Optional filename\n */\nexport async function exportSaml2ProviderToFile(entityId, file = null) {\n let fileName = file;\n if (!fileName) {\n fileName = getTypedFilename(entityId, 'saml');\n }\n createProgressIndicator(1, `Exporting provider ${entityId}`);\n try {\n const found = await findProviders(`entityId eq '${entityId}'`, 'location');\n switch (found.resultCount) {\n case 0:\n printMessage(`No provider with entity id '${entityId}' found`, 'error');\n break;\n case 1:\n {\n const { location } = found.result[0];\n const id = found.result[0]._id;\n try {\n const response = await getProviderByLocationAndId(location, id);\n const providerData = response;\n updateProgressIndicator(`Writing file ${fileName}`);\n const fileData = getFileDataTemplate();\n fileData.saml[location][providerData._id] = providerData;\n await exportDependencies(providerData, fileData);\n saveJsonToFile(fileData, fileName);\n stopProgressIndicator(\n `Exported ${entityId.brightCyan} to ${fileName.brightCyan}.`\n );\n } catch (err) {\n stopProgressIndicator(`${err}`);\n printMessage(err, 'error');\n }\n }\n break;\n default:\n printMessage(\n `Multiple providers with entity id '${entityId}' found`,\n 'error'\n );\n }\n } catch (error) {\n stopProgressIndicator(`${error}`);\n printMessage(error.message, 'error');\n }\n}\n\n/**\n * Export provider metadata to file\n * @param {String} entityId Provider entity id\n * @param {String} file Optional filename\n */\nexport async function exportSaml2Metadata(entityId, file = null) {\n let fileName = file;\n if (!fileName) {\n fileName = getTypedFilename(entityId, 'metadata', 'xml');\n }\n createProgressIndicator(1, `Exporting metadata for: ${entityId}`);\n getProviderMetadata(entityId)\n .then(async (response) => {\n updateProgressIndicator(`Writing file ${fileName}`);\n // printMessage(response.data, 'error');\n const metaData = response;\n saveTextToFile(metaData, fileName);\n stopProgressIndicator(\n `Exported ${entityId.brightCyan} metadata to ${fileName.brightCyan}.`\n );\n })\n .catch((err) => {\n stopProgressIndicator(`${err}`);\n printMessage(err, 'error');\n });\n}\n\n/**\n * Describe an entity provider's configuration\n * @param {String} entityId Provider entity id\n */\nexport async function describeSaml2Provider(entityId) {\n try {\n const found = await findProviders(\n `entityId eq '${entityId}'`,\n 'location,roles'\n );\n switch (found.resultCount) {\n case 0:\n printMessage(`No provider with entity id '${entityId}' found`, 'error');\n break;\n case 1:\n {\n try {\n const { location } = found.result[0];\n const id = found.result[0]._id;\n const roles = found.result[0].roles\n .map((role) => roleMap[role])\n .join(', ');\n const response = await getProviderByLocationAndId(location, id);\n const rawProviderData = response;\n delete rawProviderData._id;\n delete rawProviderData._rev;\n rawProviderData.location = location;\n rawProviderData.roles = roles;\n rawProviderData.metadataUrl = getProviderMetadataUrl(entityId);\n // const fullProviderData = getFileDataTemplate();\n // fullProviderData.saml[location][rawProviderData._id] =\n // rawProviderData;\n // await exportDependencies(rawProviderData, fullProviderData);\n // describe the provider\n const table = createObjectTable(rawProviderData);\n printMessage(table.toString());\n } catch (err) {\n printMessage(err, 'error');\n }\n }\n break;\n default:\n printMessage(\n `Multiple providers with entity id '${entityId}' found`,\n 'error'\n );\n }\n } catch (error) {\n printMessage(error.message, 'error');\n }\n}\n\n/**\n * Export all entity providers to one file\n * @param {String} file Optional filename\n */\nexport async function exportSaml2ProvidersToFile(file = null) {\n let fileName = file;\n if (!fileName) {\n fileName = getTypedFilename(`all${getRealmString()}Providers`, 'saml');\n }\n try {\n const fileData = getFileDataTemplate();\n const found = await getProviders();\n if (found.resultCount > 0) {\n createProgressIndicator(found.resultCount, 'Exporting providers');\n for (const stubData of found.result) {\n updateProgressIndicator(`Exporting provider ${stubData.entityId}`);\n // eslint-disable-next-line no-await-in-loop\n const providerData = await getProviderByLocationAndId(\n stubData.location,\n stubData._id\n );\n // eslint-disable-next-line no-await-in-loop\n await exportDependencies(providerData, fileData);\n fileData.saml[stubData.location][providerData._id] = providerData;\n }\n saveJsonToFile(fileData, fileName);\n stopProgressIndicator(\n `${found.resultCount} providers exported to ${fileName}.`\n );\n } else {\n printMessage('No entity providers found.', 'info');\n }\n } catch (error) {\n printMessage(error.message, 'error');\n printMessage(`exportProvidersToFile: ${error.response?.status}`, 'error');\n }\n}\n\n/**\n * Export all entity providers to individual files\n */\nexport async function exportSaml2ProvidersToFiles() {\n const found = await getProviders();\n if (found.resultCount > 0) {\n createProgressIndicator(found.resultCount, 'Exporting providers');\n for (const stubData of found.result) {\n updateProgressIndicator(`Exporting provider ${stubData.entityId}`);\n const fileName = getTypedFilename(stubData.entityId, 'saml');\n const fileData = getFileDataTemplate();\n // eslint-disable-next-line no-await-in-loop\n const providerData = await getProviderByLocationAndId(\n stubData.location,\n stubData._id\n );\n // eslint-disable-next-line no-await-in-loop\n await exportDependencies(providerData, fileData);\n fileData.saml[stubData.location][providerData._id] = providerData;\n saveJsonToFile(fileData, fileName);\n }\n stopProgressIndicator(`${found.resultCount} providers exported.`);\n } else {\n printMessage('No entity providers found.', 'info');\n }\n}\n\n/**\n * Include dependencies from the import file\n * @param {Object} providerData Object representing a SAML entity provider\n * @param {Object} fileData File data object to read dependencies from\n */\nasync function importDependencies(providerData, fileData) {\n const attrMapperScriptId = _.get(providerData, [\n 'identityProvider',\n 'assertionProcessing',\n 'attributeMapper',\n 'attributeMapperScript',\n ]);\n if (attrMapperScriptId && attrMapperScriptId !== '[Empty]') {\n const scriptData = _.get(fileData, ['script', attrMapperScriptId]);\n scriptData.script = convertTextArrayToBase64(scriptData.script);\n await createOrUpdateScript(attrMapperScriptId, scriptData);\n }\n const idpAdapterScriptId = _.get(providerData, [\n 'identityProvider',\n 'advanced',\n 'idpAdapter',\n 'idpAdapterScript',\n ]);\n if (idpAdapterScriptId && idpAdapterScriptId !== '[Empty]') {\n const scriptData = _.get(fileData, ['script', idpAdapterScriptId]);\n scriptData.script = convertTextArrayToBase64(scriptData.script);\n await createOrUpdateScript(attrMapperScriptId, scriptData);\n }\n}\n\n/**\n * Find provider in import file and return its location\n * @param {String} entityId64 Base64-encoded provider entity id\n * @param {Object} fileData Import file json data\n * @returns {String} 'hosted' or 'remote' if found, undefined otherwise\n */\nfunction getLocation(entityId64, fileData) {\n if (_.get(fileData, ['saml', 'hosted', entityId64])) {\n return 'hosted';\n }\n if (_.get(fileData, ['saml', 'remote', entityId64])) {\n return 'remote';\n }\n return undefined;\n}\n\n/**\n * Import a SAML entity provider by entity id from file\n * @param {String} entityId Provider entity id\n * @param {String} file Import file name\n */\nexport async function importSaml2ProviderFromFile(entityId, file) {\n const entityId64 = encode(entityId, false);\n fs.readFile(file, 'utf8', async (err, data) => {\n if (err) throw err;\n const fileData = JSON.parse(data);\n if (validateImport(fileData.meta)) {\n createProgressIndicator(1, 'Importing provider...');\n const location = getLocation(entityId64, fileData);\n if (location) {\n const providerData = _.get(fileData, ['saml', location, entityId64]);\n updateProgressIndicator(`Importing ${entityId}`);\n await importDependencies(providerData, fileData);\n let metaData = null;\n if (location === 'remote') {\n metaData = convertTextArrayToBase64Url(\n fileData.saml.metadata[entityId64]\n );\n }\n createProvider(location, providerData, metaData)\n .then(() => {\n stopProgressIndicator(\n `Successfully imported provider ${entityId}.`\n );\n })\n .catch((createProviderErr) => {\n printMessage(`\\nError importing provider ${entityId}`, 'error');\n printMessage(createProviderErr.response, 'error');\n });\n } else {\n stopProgressIndicator(\n `Provider ${entityId.brightCyan} not found in ${file.brightCyan}!`\n );\n }\n } else {\n printMessage('Import validation failed...', 'error');\n }\n });\n}\n\n/**\n * Import first SAML entity provider from file\n * @param {String} file Import file name\n */\nexport async function importFirstSaml2ProviderFromFile(file) {\n fs.readFile(file, 'utf8', async (err, data) => {\n if (err) throw err;\n const fileData = JSON.parse(data);\n if (validateImport(fileData.meta)) {\n createProgressIndicator(1, 'Importing provider...');\n // find providers in hosted and if none exist in remote\n let location = 'hosted';\n let providerIds = _.keys(fileData.saml[location]);\n if (providerIds.length === 0) {\n location = 'remote';\n providerIds = _.keys(fileData.saml[location]);\n if (providerIds.length === 0) {\n location = null;\n }\n }\n if (location) {\n const entityId64 = providerIds[0];\n const entityId = decode(entityId64);\n const providerData = _.get(fileData, ['saml', location, entityId64]);\n updateProgressIndicator(`Importing ${entityId}`);\n await importDependencies(providerData, fileData);\n let metaData = null;\n if (location === 'remote') {\n metaData = convertTextArrayToBase64Url(\n fileData.saml.metadata[entityId64]\n );\n }\n createProvider(location, providerData, metaData)\n .then(() => {\n stopProgressIndicator(\n `Successfully imported provider ${entityId}.`\n );\n })\n .catch((createProviderErr) => {\n stopProgressIndicator(`Error importing provider ${entityId}`);\n printMessage(`\\nError importing provider ${entityId}`, 'error');\n printMessage(createProviderErr.response.data, 'error');\n });\n } else {\n stopProgressIndicator(`No providers found in ${file.brightCyan}!`);\n }\n } else {\n printMessage('Import validation failed...', 'error');\n }\n });\n}\n\n/**\n * Import all SAML entity providers from file\n * @param {String} file Import file name\n */\nexport async function importSaml2ProvidersFromFile(file) {\n fs.readFile(file, 'utf8', async (err, data) => {\n if (err) throw err;\n const fileData = JSON.parse(data);\n if (validateImport(fileData.meta)) {\n // find providers in hosted and in remote and map locations\n const hostedIds = _.keys(fileData.saml.hosted);\n const remoteIds = _.keys(fileData.saml.remote);\n const providerIds = hostedIds.concat(remoteIds);\n createProgressIndicator(providerIds.length, 'Importing providers...');\n for (const entityId64 of providerIds) {\n const location = hostedIds.includes(entityId64) ? 'hosted' : 'remote';\n const entityId = decode(entityId64);\n const providerData = _.get(fileData, ['saml', location, entityId64]);\n // eslint-disable-next-line no-await-in-loop\n await importDependencies(providerData, fileData);\n let metaData = null;\n if (location === 'remote') {\n metaData = convertTextArrayToBase64Url(\n fileData.saml.metadata[entityId64]\n );\n }\n try {\n // eslint-disable-next-line no-await-in-loop\n await createProvider(location, providerData, metaData);\n updateProgressIndicator(`Imported ${entityId}`);\n } catch (createProviderErr) {\n printMessage(`\\nError importing provider ${entityId}`, 'error');\n printMessage(createProviderErr.response.data, 'error');\n }\n }\n stopProgressIndicator(`Providers imported.`);\n } else {\n printMessage('Import validation failed...', 'error');\n }\n });\n}\n\n/**\n * Import all SAML entity providers from all *.saml.json files in the current directory\n */\nexport async function importSaml2ProvidersFromFiles() {\n const names = fs.readdirSync('.');\n const jsonFiles = names.filter((name) =>\n name.toLowerCase().endsWith('.saml.json')\n );\n createProgressIndicator(jsonFiles.length, 'Importing providers...');\n let total = 0;\n let totalErrors = 0;\n for (const file of jsonFiles) {\n const data = fs.readFileSync(file, 'utf8');\n const fileData = JSON.parse(data);\n if (validateImport(fileData.meta)) {\n // find providers in hosted and in remote and map locations\n const hostedIds = _.keys(fileData.saml.hosted);\n const remoteIds = _.keys(fileData.saml.remote);\n const providerIds = hostedIds.concat(remoteIds);\n total += providerIds.length;\n let errors = 0;\n for (const entityId64 of providerIds) {\n const location = hostedIds.includes(entityId64) ? 'hosted' : 'remote';\n const entityId = decode(entityId64);\n const providerData = _.get(fileData, ['saml', location, entityId64]);\n importDependencies(providerData, fileData);\n let metaData = null;\n if (location === 'remote') {\n metaData = convertTextArrayToBase64Url(\n fileData.saml.metadata[entityId64]\n );\n }\n try {\n // eslint-disable-next-line no-await-in-loop\n await createProvider(location, providerData, metaData);\n // updateProgressIndicator(`Imported ${entityId}`);\n } catch (createProviderErr) {\n errors += 1;\n printMessage(`\\nError importing provider ${entityId}`, 'error');\n printMessage(createProviderErr.response.data, 'error');\n }\n }\n totalErrors += errors;\n updateProgressIndicator(\n `Imported ${providerIds.length - errors} provider(s) from ${file}`\n );\n } else {\n printMessage(`Validation of ${file} failed!`, 'error');\n }\n }\n stopProgressIndicator(\n `Imported ${total - totalErrors} of ${total} provider(s) from ${\n jsonFiles.length\n } file(s).`\n );\n}\n"]}
|
|
1
|
+
{"version":3,"sources":["../src/ops/Saml2Ops.ts"],"names":[],"mappings":"AAiCA,eAAO,MAAM,OAAO;;;;;CAKnB,CAAC;AAeF;;;GAGG;AACH,wBAAsB,kBAAkB,CAAC,IAAI,UAAQ,iBAsBpD;AAuCD;;;;GAIG;AACH,wBAAsB,yBAAyB,CAAC,QAAQ,KAAA,EAAE,IAAI,MAAO,iBA2CpE;AAED;;;;GAIG;AACH,wBAAsB,mBAAmB,CAAC,QAAQ,KAAA,EAAE,IAAI,MAAO,iBAoB9D;AAED;;;GAGG;AACH,wBAAsB,qBAAqB,CAAC,QAAQ,KAAA,iBA8CnD;AAED;;;GAGG;AACH,wBAAsB,0BAA0B,CAAC,IAAI,MAAO,iBAgC3D;AAED;;GAEG;AACH,wBAAsB,2BAA2B,kBAsBhD;AAgDD;;;;GAIG;AACH,wBAAsB,2BAA2B,CAAC,QAAQ,KAAA,EAAE,IAAI,KAAA,iBAqC/D;AAED;;;GAGG;AACH,wBAAsB,gCAAgC,CAAC,IAAI,KAAA,iBA8C1D;AAED;;;GAGG;AACH,wBAAsB,4BAA4B,CAAC,IAAI,KAAA,iBAoCtD;AAED;;GAEG;AACH,wBAAsB,6BAA6B,kBAoDlD","file":"Saml2Ops.d.ts","sourcesContent":["import fs from 'fs';\nimport _ from 'lodash';\nimport { decode, encode, encodeBase64Url } from '../api/utils/Base64';\nimport {\n createTable,\n printMessage,\n createProgressIndicator,\n updateProgressIndicator,\n stopProgressIndicator,\n createObjectTable,\n} from './utils/Console';\nimport {\n getProviders,\n findProviders,\n getProviderByLocationAndId,\n getProviderMetadata,\n createProvider,\n getProviderMetadataUrl,\n} from '../api/Saml2Api';\nimport { getScript } from '../api/ScriptApi';\nimport {\n convertBase64TextToArray,\n convertBase64UrlTextToArray,\n convertTextArrayToBase64,\n convertTextArrayToBase64Url,\n getRealmString,\n getTypedFilename,\n saveJsonToFile,\n saveTextToFile,\n validateImport,\n} from './utils/ExportImportUtils';\nimport { createOrUpdateScript } from './ScriptOps';\n\nexport const roleMap = {\n identityProvider: 'IDP',\n serviceProvider: 'SP',\n attributeQueryProvider: 'AttrQuery',\n xacmlPolicyEnforcementPoint: 'XACML PEP',\n};\n\n// use a function vs a template variable to avoid problems in loops\nfunction getFileDataTemplate() {\n return {\n meta: {},\n script: {},\n saml: {\n hosted: {},\n remote: {},\n metadata: {},\n },\n };\n}\n\n/**\n * List entity providers\n * @param {boolean} long Long list format with details\n */\nexport async function listSaml2Providers(long = false) {\n const providerList = (await getProviders()).result;\n providerList.sort((a, b) => a._id.localeCompare(b._id));\n if (!long) {\n for (const provider of providerList) {\n printMessage(`${provider.entityId}`, 'data');\n }\n } else {\n const table = createTable([\n 'Entity Id'['brightCyan'],\n 'Location'['brightCyan'],\n 'Role(s)'['brightCyan'],\n ]);\n for (const provider of providerList) {\n table.push([\n provider.entityId,\n provider.location,\n provider.roles.map((role) => roleMap[role]).join(', '),\n ]);\n }\n printMessage(table.toString());\n }\n}\n\n/**\n * Include dependencies in the export file\n * @param {Object} providerData Object representing a SAML entity provider\n * @param {Object} fileData File data object to add dependencies to\n */\nasync function exportDependencies(providerData, fileData) {\n const attrMapperScriptId = _.get(providerData, [\n 'identityProvider',\n 'assertionProcessing',\n 'attributeMapper',\n 'attributeMapperScript',\n ]);\n if (attrMapperScriptId && attrMapperScriptId !== '[Empty]') {\n const scriptData = await getScript(attrMapperScriptId);\n scriptData.script = convertBase64TextToArray(scriptData.script);\n // eslint-disable-next-line no-param-reassign\n fileData.script[attrMapperScriptId] = scriptData;\n }\n const idpAdapterScriptId = _.get(providerData, [\n 'identityProvider',\n 'advanced',\n 'idpAdapter',\n 'idpAdapterScript',\n ]);\n if (idpAdapterScriptId && idpAdapterScriptId !== '[Empty]') {\n const scriptData = await getScript(idpAdapterScriptId);\n scriptData.script = convertBase64TextToArray(scriptData.script);\n // eslint-disable-next-line no-param-reassign\n fileData.script[idpAdapterScriptId] = scriptData;\n }\n const metaDataResponse = await getProviderMetadata(providerData.entityId);\n // eslint-disable-next-line no-param-reassign\n fileData.saml.metadata[providerData._id] = convertBase64UrlTextToArray(\n encodeBase64Url(metaDataResponse)\n );\n}\n\n/**\n * Export a single entity provider to file\n * @param {String} entityId Provider entity id\n * @param {String} file Optional filename\n */\nexport async function exportSaml2ProviderToFile(entityId, file = null) {\n let fileName = file;\n if (!fileName) {\n fileName = getTypedFilename(entityId, 'saml');\n }\n createProgressIndicator(1, `Exporting provider ${entityId}`);\n try {\n const found = await findProviders(`entityId eq '${entityId}'`, 'location');\n switch (found.resultCount) {\n case 0:\n printMessage(`No provider with entity id '${entityId}' found`, 'error');\n break;\n case 1:\n {\n const { location } = found.result[0];\n const id = found.result[0]._id;\n try {\n const response = await getProviderByLocationAndId(location, id);\n const providerData = response;\n updateProgressIndicator(`Writing file ${fileName}`);\n const fileData = getFileDataTemplate();\n fileData.saml[location][providerData._id] = providerData;\n await exportDependencies(providerData, fileData);\n saveJsonToFile(fileData, fileName);\n stopProgressIndicator(\n `Exported ${entityId.brightCyan} to ${fileName.brightCyan}.`\n );\n } catch (err) {\n stopProgressIndicator(`${err}`);\n printMessage(err, 'error');\n }\n }\n break;\n default:\n printMessage(\n `Multiple providers with entity id '${entityId}' found`,\n 'error'\n );\n }\n } catch (error) {\n stopProgressIndicator(`${error}`);\n printMessage(error.message, 'error');\n }\n}\n\n/**\n * Export provider metadata to file\n * @param {String} entityId Provider entity id\n * @param {String} file Optional filename\n */\nexport async function exportSaml2Metadata(entityId, file = null) {\n let fileName = file;\n if (!fileName) {\n fileName = getTypedFilename(entityId, 'metadata', 'xml');\n }\n createProgressIndicator(1, `Exporting metadata for: ${entityId}`);\n getProviderMetadata(entityId)\n .then(async (response) => {\n updateProgressIndicator(`Writing file ${fileName}`);\n // printMessage(response.data, 'error');\n const metaData = response;\n saveTextToFile(metaData, fileName);\n stopProgressIndicator(\n `Exported ${entityId.brightCyan} metadata to ${fileName.brightCyan}.`\n );\n })\n .catch((err) => {\n stopProgressIndicator(`${err}`);\n printMessage(err, 'error');\n });\n}\n\n/**\n * Describe an entity provider's configuration\n * @param {String} entityId Provider entity id\n */\nexport async function describeSaml2Provider(entityId) {\n try {\n const found = await findProviders(\n `entityId eq '${entityId}'`,\n 'location,roles'\n );\n switch (found.resultCount) {\n case 0:\n printMessage(`No provider with entity id '${entityId}' found`, 'error');\n break;\n case 1:\n {\n try {\n const { location } = found.result[0];\n const id = found.result[0]._id;\n const roles = found.result[0].roles\n .map((role) => roleMap[role])\n .join(', ');\n const response = await getProviderByLocationAndId(location, id);\n const rawProviderData = response;\n delete rawProviderData._id;\n delete rawProviderData._rev;\n rawProviderData.location = location;\n rawProviderData.roles = roles;\n rawProviderData.metadataUrl = getProviderMetadataUrl(entityId);\n // const fullProviderData = getFileDataTemplate();\n // fullProviderData.saml[location][rawProviderData._id] =\n // rawProviderData;\n // await exportDependencies(rawProviderData, fullProviderData);\n // describe the provider\n const table = createObjectTable(rawProviderData);\n printMessage(table.toString());\n } catch (err) {\n printMessage(err, 'error');\n }\n }\n break;\n default:\n printMessage(\n `Multiple providers with entity id '${entityId}' found`,\n 'error'\n );\n }\n } catch (error) {\n printMessage(error.message, 'error');\n }\n}\n\n/**\n * Export all entity providers to one file\n * @param {String} file Optional filename\n */\nexport async function exportSaml2ProvidersToFile(file = null) {\n let fileName = file;\n if (!fileName) {\n fileName = getTypedFilename(`all${getRealmString()}Providers`, 'saml');\n }\n try {\n const fileData = getFileDataTemplate();\n const found = await getProviders();\n if (found.resultCount > 0) {\n createProgressIndicator(found.resultCount, 'Exporting providers');\n for (const stubData of found.result) {\n updateProgressIndicator(`Exporting provider ${stubData.entityId}`);\n // eslint-disable-next-line no-await-in-loop\n const providerData = await getProviderByLocationAndId(\n stubData.location,\n stubData._id\n );\n // eslint-disable-next-line no-await-in-loop\n await exportDependencies(providerData, fileData);\n fileData.saml[stubData.location][providerData._id] = providerData;\n }\n saveJsonToFile(fileData, fileName);\n stopProgressIndicator(\n `${found.resultCount} providers exported to ${fileName}.`\n );\n } else {\n printMessage('No entity providers found.', 'info');\n }\n } catch (error) {\n printMessage(error.message, 'error');\n printMessage(`exportProvidersToFile: ${error.response?.status}`, 'error');\n }\n}\n\n/**\n * Export all entity providers to individual files\n */\nexport async function exportSaml2ProvidersToFiles() {\n const found = await getProviders();\n if (found.resultCount > 0) {\n createProgressIndicator(found.resultCount, 'Exporting providers');\n for (const stubData of found.result) {\n updateProgressIndicator(`Exporting provider ${stubData.entityId}`);\n const fileName = getTypedFilename(stubData.entityId, 'saml');\n const fileData = getFileDataTemplate();\n // eslint-disable-next-line no-await-in-loop\n const providerData = await getProviderByLocationAndId(\n stubData.location,\n stubData._id\n );\n // eslint-disable-next-line no-await-in-loop\n await exportDependencies(providerData, fileData);\n fileData.saml[stubData.location][providerData._id] = providerData;\n saveJsonToFile(fileData, fileName);\n }\n stopProgressIndicator(`${found.resultCount} providers exported.`);\n } else {\n printMessage('No entity providers found.', 'info');\n }\n}\n\n/**\n * Include dependencies from the import file\n * @param {Object} providerData Object representing a SAML entity provider\n * @param {Object} fileData File data object to read dependencies from\n */\nasync function importDependencies(providerData, fileData) {\n const attrMapperScriptId = _.get(providerData, [\n 'identityProvider',\n 'assertionProcessing',\n 'attributeMapper',\n 'attributeMapperScript',\n ]);\n if (attrMapperScriptId && attrMapperScriptId !== '[Empty]') {\n const scriptData = _.get(fileData, ['script', attrMapperScriptId]);\n scriptData.script = convertTextArrayToBase64(scriptData.script);\n await createOrUpdateScript(attrMapperScriptId, scriptData);\n }\n const idpAdapterScriptId = _.get(providerData, [\n 'identityProvider',\n 'advanced',\n 'idpAdapter',\n 'idpAdapterScript',\n ]);\n if (idpAdapterScriptId && idpAdapterScriptId !== '[Empty]') {\n const scriptData = _.get(fileData, ['script', idpAdapterScriptId]);\n scriptData.script = convertTextArrayToBase64(scriptData.script);\n await createOrUpdateScript(attrMapperScriptId, scriptData);\n }\n}\n\n/**\n * Find provider in import file and return its location\n * @param {String} entityId64 Base64-encoded provider entity id\n * @param {Object} fileData Import file json data\n * @returns {String} 'hosted' or 'remote' if found, undefined otherwise\n */\nfunction getLocation(entityId64, fileData) {\n if (_.get(fileData, ['saml', 'hosted', entityId64])) {\n return 'hosted';\n }\n if (_.get(fileData, ['saml', 'remote', entityId64])) {\n return 'remote';\n }\n return undefined;\n}\n\n/**\n * Import a SAML entity provider by entity id from file\n * @param {String} entityId Provider entity id\n * @param {String} file Import file name\n */\nexport async function importSaml2ProviderFromFile(entityId, file) {\n const entityId64 = encode(entityId, false);\n fs.readFile(file, 'utf8', async (err, data) => {\n if (err) throw err;\n const fileData = JSON.parse(data);\n if (validateImport(fileData.meta)) {\n createProgressIndicator(1, 'Importing provider...');\n const location = getLocation(entityId64, fileData);\n if (location) {\n const providerData = _.get(fileData, ['saml', location, entityId64]);\n updateProgressIndicator(`Importing ${entityId}`);\n await importDependencies(providerData, fileData);\n let metaData = null;\n if (location === 'remote') {\n metaData = convertTextArrayToBase64Url(\n fileData.saml.metadata[entityId64]\n );\n }\n createProvider(location, providerData, metaData)\n .then(() => {\n stopProgressIndicator(\n `Successfully imported provider ${entityId}.`\n );\n })\n .catch((createProviderErr) => {\n printMessage(`\\nError importing provider ${entityId}`, 'error');\n printMessage(createProviderErr.response, 'error');\n });\n } else {\n stopProgressIndicator(\n `Provider ${entityId.brightCyan} not found in ${file.brightCyan}!`\n );\n }\n } else {\n printMessage('Import validation failed...', 'error');\n }\n });\n}\n\n/**\n * Import first SAML entity provider from file\n * @param {String} file Import file name\n */\nexport async function importFirstSaml2ProviderFromFile(file) {\n fs.readFile(file, 'utf8', async (err, data) => {\n if (err) throw err;\n const fileData = JSON.parse(data);\n if (validateImport(fileData.meta)) {\n createProgressIndicator(1, 'Importing provider...');\n // find providers in hosted and if none exist in remote\n let location = 'hosted';\n let providerIds = _.keys(fileData.saml[location]);\n if (providerIds.length === 0) {\n location = 'remote';\n providerIds = _.keys(fileData.saml[location]);\n if (providerIds.length === 0) {\n location = null;\n }\n }\n if (location) {\n const entityId64 = providerIds[0];\n const entityId = decode(entityId64);\n const providerData = _.get(fileData, ['saml', location, entityId64]);\n updateProgressIndicator(`Importing ${entityId}`);\n await importDependencies(providerData, fileData);\n let metaData = null;\n if (location === 'remote') {\n metaData = convertTextArrayToBase64Url(\n fileData.saml.metadata[entityId64]\n );\n }\n createProvider(location, providerData, metaData)\n .then(() => {\n stopProgressIndicator(\n `Successfully imported provider ${entityId}.`\n );\n })\n .catch((createProviderErr) => {\n stopProgressIndicator(`Error importing provider ${entityId}`);\n printMessage(`\\nError importing provider ${entityId}`, 'error');\n printMessage(createProviderErr.response.data, 'error');\n });\n } else {\n stopProgressIndicator(`No providers found in ${file.brightCyan}!`);\n }\n } else {\n printMessage('Import validation failed...', 'error');\n }\n });\n}\n\n/**\n * Import all SAML entity providers from file\n * @param {String} file Import file name\n */\nexport async function importSaml2ProvidersFromFile(file) {\n fs.readFile(file, 'utf8', async (err, data) => {\n if (err) throw err;\n const fileData = JSON.parse(data);\n if (validateImport(fileData.meta)) {\n // find providers in hosted and in remote and map locations\n const hostedIds = _.keys(fileData.saml.hosted);\n const remoteIds = _.keys(fileData.saml.remote);\n const providerIds = hostedIds.concat(remoteIds);\n createProgressIndicator(providerIds.length, 'Importing providers...');\n for (const entityId64 of providerIds) {\n const location = hostedIds.includes(entityId64) ? 'hosted' : 'remote';\n const entityId = decode(entityId64);\n const providerData = _.get(fileData, ['saml', location, entityId64]);\n // eslint-disable-next-line no-await-in-loop\n await importDependencies(providerData, fileData);\n let metaData = null;\n if (location === 'remote') {\n metaData = convertTextArrayToBase64Url(\n fileData.saml.metadata[entityId64]\n );\n }\n try {\n // eslint-disable-next-line no-await-in-loop\n await createProvider(location, providerData, metaData);\n updateProgressIndicator(`Imported ${entityId}`);\n } catch (createProviderErr) {\n printMessage(`\\nError importing provider ${entityId}`, 'error');\n printMessage(createProviderErr.response.data, 'error');\n }\n }\n stopProgressIndicator(`Providers imported.`);\n } else {\n printMessage('Import validation failed...', 'error');\n }\n });\n}\n\n/**\n * Import all SAML entity providers from all *.saml.json files in the current directory\n */\nexport async function importSaml2ProvidersFromFiles() {\n const names = fs.readdirSync('.');\n const jsonFiles = names.filter((name) =>\n name.toLowerCase().endsWith('.saml.json')\n );\n createProgressIndicator(jsonFiles.length, 'Importing providers...');\n let total = 0;\n let totalErrors = 0;\n for (const file of jsonFiles) {\n const data = fs.readFileSync(file, 'utf8');\n const fileData = JSON.parse(data);\n if (validateImport(fileData.meta)) {\n // find providers in hosted and in remote and map locations\n const hostedIds = _.keys(fileData.saml.hosted);\n const remoteIds = _.keys(fileData.saml.remote);\n const providerIds = hostedIds.concat(remoteIds);\n total += providerIds.length;\n let errors = 0;\n for (const entityId64 of providerIds) {\n const location = hostedIds.includes(entityId64) ? 'hosted' : 'remote';\n const entityId = decode(entityId64);\n const providerData = _.get(fileData, ['saml', location, entityId64]);\n importDependencies(providerData, fileData);\n let metaData = null;\n if (location === 'remote') {\n metaData = convertTextArrayToBase64Url(\n fileData.saml.metadata[entityId64]\n );\n }\n try {\n // eslint-disable-next-line no-await-in-loop\n await createProvider(location, providerData, metaData);\n // updateProgressIndicator(`Imported ${entityId}`);\n } catch (createProviderErr) {\n errors += 1;\n printMessage(`\\nError importing provider ${entityId}`, 'error');\n printMessage(createProviderErr.response.data, 'error');\n }\n }\n totalErrors += errors;\n updateProgressIndicator(\n `Imported ${providerIds.length - errors} provider(s) from ${file}`\n );\n } else {\n printMessage(`Validation of ${file} failed!`, 'error');\n }\n }\n stopProgressIndicator(\n `Imported ${total - totalErrors} of ${total} provider(s) from ${\n jsonFiles.length\n } file(s).`\n );\n}\n"]}
|
package/types/ops/ScriptOps.d.ts
CHANGED
|
@@ -1,10 +1,3 @@
|
|
|
1
|
-
import { ScriptSkeleton } from '../api/ApiTypes';
|
|
2
|
-
/**
|
|
3
|
-
* Get a one-line description of the script object
|
|
4
|
-
* @param {ScriptSkeleton} scriptObj script object to describe
|
|
5
|
-
* @returns {string} a one-line description
|
|
6
|
-
*/
|
|
7
|
-
export declare function getOneLineDescription(scriptObj: ScriptSkeleton): string;
|
|
8
1
|
/**
|
|
9
2
|
* List scripts
|
|
10
3
|
*/
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/ops/ScriptOps.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"sources":["../src/ops/ScriptOps.ts"],"names":[],"mappings":"AAsBA;;GAEG;AACH,wBAAsB,WAAW,CAAC,IAAI,UAAQ,iBA+B7C;AAED;;;;GAIG;AACH,wBAAsB,kBAAkB,CAAC,IAAI,KAAA,EAAE,IAAI,KAAA,iBAelD;AAED;;;GAGG;AACH,wBAAsB,mBAAmB,CAAC,IAAI,KAAA,iBAwB7C;AAED;;GAEG;AACH,wBAAsB,oBAAoB,kBAgBzC;AAED;;;;;GAKG;AACH,wBAAsB,oBAAoB,CAAC,EAAE,KAAA,EAAE,IAAI,KAAA;;;GAwBlD;AAED,wBAAsB,qBAAqB,CAAC,IAAI,KAAA,EAAE,IAAI,KAAA,EAAE,MAAM,UAAQ,iBAiDrE","file":"ScriptOps.d.ts","sourcesContent":["import fs from 'fs';\nimport { v4 as uuidv4 } from 'uuid';\nimport { applyNameCollisionPolicy } from './utils/OpsUtils';\nimport {\n createProgressIndicator,\n createTable,\n printMessage,\n stopProgressIndicator,\n updateProgressIndicator,\n} from './utils/Console';\nimport { getScriptByName, getScripts, putScript } from '../api/ScriptApi';\nimport wordwrap from './utils/Wordwrap';\nimport {\n convertBase64TextToArray,\n convertTextArrayToBase64,\n getTypedFilename,\n saveToFile,\n titleCase,\n validateImport,\n} from './utils/ExportImportUtils';\nimport storage from '../storage/SessionStorage';\n\n/**\n * List scripts\n */\nexport async function listScripts(long = false) {\n try {\n const scripts = (await getScripts()).result;\n scripts.sort((a, b) => a.name.localeCompare(b.name));\n if (long) {\n const table = createTable([\n 'Name',\n 'UUID',\n 'Language',\n 'Context',\n 'Description',\n ]);\n const langMap = { JAVASCRIPT: 'JS', GROOVY: 'Groovy' };\n scripts.forEach((script) => {\n table.push([\n wordwrap(script.name, 25, ' '),\n script._id,\n langMap[script.language],\n wordwrap(titleCase(script.context.split('_').join(' ')), 25),\n wordwrap(script.description, 30),\n ]);\n });\n printMessage(table.toString(), 'data');\n } else {\n scripts.forEach((script) => {\n printMessage(`${script.name}`, 'data');\n });\n }\n } catch (error) {\n printMessage(`Error listing scripts - ${error}`, 'error');\n }\n}\n\n/**\n * Export script to file\n * @param {String} name script name\n * @param {String} file file name\n */\nexport async function exportScriptByName(name, file) {\n let fileName = getTypedFilename(name, 'script');\n if (file) {\n fileName = file;\n }\n const scriptData = (await getScriptByName(name)).result;\n if (scriptData.length > 1) {\n printMessage(`Multiple scripts with name ${name} found...`, 'error');\n }\n scriptData.forEach((element) => {\n const scriptTextArray = convertBase64TextToArray(element.script);\n // eslint-disable-next-line no-param-reassign\n element.script = scriptTextArray;\n });\n saveToFile('script', scriptData, '_id', fileName);\n}\n\n/**\n * Export all scripts to single file\n * @param {String} file file name\n */\nexport async function exportScriptsToFile(file) {\n let fileName = getTypedFilename(\n `all${storage.session.getRealm()}Scripts`,\n 'script'\n );\n if (file) {\n fileName = file;\n }\n const scriptList = (await getScripts()).result;\n const allScriptsData = [];\n createProgressIndicator(scriptList.length, 'Exporting script');\n for (const item of scriptList) {\n updateProgressIndicator(`Reading script ${item.name}`);\n // eslint-disable-next-line no-await-in-loop\n const scriptData = (await getScriptByName(item.name)).result;\n scriptData.forEach((element) => {\n const scriptTextArray = convertBase64TextToArray(element.script);\n // eslint-disable-next-line no-param-reassign\n element.script = scriptTextArray;\n allScriptsData.push(element);\n });\n }\n stopProgressIndicator('Done');\n saveToFile('script', allScriptsData, '_id', fileName);\n}\n\n/**\n * Export all scripts to individual files\n */\nexport async function exportScriptsToFiles() {\n const scriptList = (await getScripts()).result;\n createProgressIndicator(scriptList.length, 'Exporting script');\n for (const item of scriptList) {\n updateProgressIndicator(`Reading script ${item.name}`);\n // eslint-disable-next-line no-await-in-loop\n const scriptData = (await getScriptByName(item.name)).result;\n scriptData.forEach((element) => {\n const scriptTextArray = convertBase64TextToArray(element.script);\n // eslint-disable-next-line no-param-reassign\n element.script = scriptTextArray;\n });\n const fileName = getTypedFilename(item.name, 'script');\n saveToFile('script', scriptData, '_id', fileName);\n }\n stopProgressIndicator('Done');\n}\n\n/**\n * Import script\n * @param {String} id script uuid\n * @param {Object} data script object\n * @returns {Object} a status object\n */\nexport async function createOrUpdateScript(id, data) {\n try {\n await putScript(id, data);\n return { error: false, name: data.name };\n } catch (e) {\n if (e.response.status === 409) {\n printMessage(\n `createOrUpdateScript WARNING: script with name ${data.name} already exists, using renaming policy... <name> => <name - imported (n)>`,\n 'warn'\n );\n const newName = applyNameCollisionPolicy(data.name);\n // console.log(newName);\n printMessage(`Trying to save script as ${newName}`, 'warn');\n // eslint-disable-next-line no-param-reassign\n data.name = newName;\n await createOrUpdateScript(id, data);\n return { error: false, name: data.name };\n }\n printMessage(\n `createOrUpdateScript ERROR: put script error, script ${id} - ${e.message}`,\n 'error'\n );\n return { error: true, name: data.name };\n }\n}\n\nexport async function importScriptsFromFile(name, file, reUuid = false) {\n fs.readFile(file, 'utf8', (err, data) => {\n if (err) throw err;\n const scriptData = JSON.parse(data);\n if (validateImport(scriptData.meta)) {\n createProgressIndicator(Object.keys(scriptData.script).length, '');\n for (const existingId in scriptData.script) {\n if ({}.hasOwnProperty.call(scriptData.script, existingId)) {\n let newId = existingId;\n // console.log(id);\n const encodedScript = convertTextArrayToBase64(\n scriptData.script[existingId].script\n );\n scriptData.script[existingId].script = encodedScript;\n if (reUuid) {\n newId = uuidv4();\n // printMessage(\n // `Re-uuid-ing script ${scriptData.script[existingId].name} ${existingId} => ${newId}...`\n // );\n scriptData.script[existingId]._id = newId;\n }\n if (name) {\n // printMessage(\n // `Renaming script ${scriptData.script[existingId].name} => ${options.script}...`\n // );\n scriptData.script[existingId].name = name;\n }\n updateProgressIndicator(\n `Importing ${scriptData.script[existingId].name}`\n );\n // console.log(scriptData.script[id]);\n createOrUpdateScript(newId, scriptData.script[existingId]).then(\n (result) => {\n if (result == null)\n printMessage(\n `Error importing ${scriptData.script[existingId].name}`,\n 'error'\n );\n }\n );\n if (name) break;\n }\n }\n stopProgressIndicator('Done');\n // printMessage('Done');\n } else {\n printMessage('Import validation failed...', 'error');\n }\n });\n}\n"]}
|
package/types/ops/ThemeOps.d.ts
CHANGED
|
@@ -1,10 +1,3 @@
|
|
|
1
|
-
import { ThemeSkeleton } from '../api/ApiTypes';
|
|
2
|
-
/**
|
|
3
|
-
* Get a one-line description of the theme
|
|
4
|
-
* @param {ThemeSkeleton} themeObj theme object to describe
|
|
5
|
-
* @returns {string} a one-line description
|
|
6
|
-
*/
|
|
7
|
-
export declare function getOneLineDescription(themeObj: ThemeSkeleton): string;
|
|
8
1
|
/**
|
|
9
2
|
* List all the themes
|
|
10
3
|
* @param {boolean} long Long version, more fields
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/ops/ThemeOps.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AA0BhD;;;;GAIG;AACH,wBAAgB,qBAAqB,CAAC,QAAQ,EAAE,aAAa,GAAG,MAAM,CASrE;AAED;;;GAGG;AACH,wBAAsB,UAAU,CAAC,IAAI,UAAQ,iBAyB5C;AAED;;;;GAIG;AACH,wBAAsB,iBAAiB,CAAC,IAAI,KAAA,EAAE,IAAI,KAAA,iBAejD;AAED;;;;GAIG;AACH,wBAAsB,eAAe,CAAC,EAAE,KAAA,EAAE,IAAI,KAAA,iBAe7C;AAED;;;GAGG;AACH,wBAAsB,kBAAkB,CAAC,IAAI,KAAA,iBAc5C;AAED;;GAEG;AACH,wBAAsB,mBAAmB,kBASxC;AAED;;;;GAIG;AACH,wBAAsB,iBAAiB,CAAC,IAAI,KAAA,EAAE,IAAI,KAAA,iBAoCjD;AAED;;;;GAIG;AACH,wBAAsB,eAAe,CAAC,EAAE,KAAA,EAAE,IAAI,KAAA,iBAsC7C;AAED;;;GAGG;AACH,wBAAsB,oBAAoB,CAAC,IAAI,KAAA,iBAqC9C;AAED;;GAEG;AACH,wBAAsB,qBAAqB,kBAgC1C;AAED;;;GAGG;AACH,wBAAsB,wBAAwB,CAAC,IAAI,KAAA,iBA+BlD;AAED;;;GAGG;AACH,wBAAsB,cAAc,CAAC,EAAE,KAAA,iBAQtC;AAED;;;GAGG;AACH,wBAAsB,oBAAoB,CAAC,IAAI,KAAA,iBAQ9C;AAED;;GAEG;AACH,wBAAsB,eAAe,kBAYpC","file":"ThemeOps.d.ts","sourcesContent":["import fs from 'fs';\nimport { ThemeSkeleton } from '../api/ApiTypes';\nimport {\n deleteTheme,\n deleteThemeByName,\n deleteThemes,\n getTheme,\n getThemeByName,\n getThemes,\n putTheme,\n putThemeByName,\n putThemes,\n} from '../api/ThemeApi';\nimport {\n createProgressIndicator,\n createTable,\n printMessage,\n stopProgressIndicator,\n updateProgressIndicator,\n} from './utils/Console';\nimport {\n getRealmString,\n getTypedFilename,\n saveToFile,\n validateImport,\n} from './utils/ExportImportUtils';\n\n/**\n * Get a one-line description of the theme\n * @param {ThemeSkeleton} themeObj theme object to describe\n * @returns {string} a one-line description\n */\nexport function getOneLineDescription(themeObj: ThemeSkeleton): string {\n const description = `[${themeObj._id['brightCyan']}] ${\n themeObj.name['brightYellow']\n }${\n themeObj.linkedTrees\n ? ' (' + themeObj.linkedTrees.join(', ')['brightCyan'] + ')'\n : ''\n }`;\n return description;\n}\n\n/**\n * List all the themes\n * @param {boolean} long Long version, more fields\n */\nexport async function listThemes(long = false) {\n const themeList = await getThemes();\n themeList.sort((a, b) => a.name.localeCompare(b.name));\n if (!long) {\n themeList.forEach((theme) => {\n printMessage(\n `${theme.isDefault ? theme.name.brightCyan : theme.name}`,\n 'data'\n );\n });\n } else {\n const table = createTable([\n 'Name'['brightCyan'],\n 'Id'['brightCyan'],\n 'Default'['brightCyan'],\n ]);\n themeList.forEach((theme) => {\n table.push([\n `${theme.name}`,\n `${theme._id}`,\n `${theme.isDefault ? 'Yes'['brightGreen'] : ''}`,\n ]);\n });\n printMessage(table.toString(), 'data');\n }\n}\n\n/**\n * Export theme by name to file\n * @param {String} name theme name\n * @param {String} file optional export file name\n */\nexport async function exportThemeByName(name, file) {\n let fileName = getTypedFilename(name, 'theme');\n if (file) {\n fileName = file;\n }\n createProgressIndicator(1, `Exporting ${name}`);\n const themeData = await getThemeByName(name);\n if (themeData.length === 0) {\n stopProgressIndicator(`Theme ${name} not found!`);\n printMessage(`Theme ${name} not found!`, 'error');\n } else {\n updateProgressIndicator(`Writing file ${fileName}`);\n saveToFile('theme', themeData, '_id', fileName);\n stopProgressIndicator(`Successfully exported theme ${name}.`);\n }\n}\n\n/**\n * Export theme by uuid to file\n * @param {String} id theme uuid\n * @param {String} file optional export file name\n */\nexport async function exportThemeById(id, file) {\n let fileName = getTypedFilename(id, 'theme');\n if (file) {\n fileName = file;\n }\n createProgressIndicator(1, `Exporting ${id}`);\n const themeData = await getTheme(id);\n if (themeData.length === 0) {\n stopProgressIndicator(`Theme ${id} not found!`);\n printMessage(`Theme ${id} not found!`, 'error');\n } else {\n updateProgressIndicator(`Writing file ${fileName}`);\n saveToFile('theme', themeData, '_id', fileName);\n stopProgressIndicator(`Successfully exported theme ${id}.`);\n }\n}\n\n/**\n * Export all themes to file\n * @param {String} file optional export file name\n */\nexport async function exportThemesToFile(file) {\n let fileName = getTypedFilename(`all${getRealmString()}Themes`, 'theme');\n if (file) {\n fileName = file;\n }\n const allThemesData = await getThemes();\n createProgressIndicator(allThemesData.length, 'Exporting themes');\n for (const themeData of allThemesData) {\n updateProgressIndicator(`Exporting theme ${themeData.name}`);\n }\n saveToFile('theme', allThemesData, '_id', fileName);\n stopProgressIndicator(\n `${allThemesData.length} themes exported to ${fileName}.`\n );\n}\n\n/**\n * Export all themes to separate files\n */\nexport async function exportThemesToFiles() {\n const allThemesData = await getThemes();\n createProgressIndicator(allThemesData.length, 'Exporting themes');\n for (const themeData of allThemesData) {\n updateProgressIndicator(`Writing theme ${themeData.name}`);\n const fileName = getTypedFilename(themeData.name, 'theme');\n saveToFile('theme', themeData, '_id', fileName);\n }\n stopProgressIndicator(`${allThemesData.length} themes exported.`);\n}\n\n/**\n * Import theme by name from file\n * @param {String} name theme name\n * @param {String} file import file name\n */\nexport async function importThemeByName(name, file) {\n fs.readFile(file, 'utf8', (err, data) => {\n if (err) throw err;\n const themeData = JSON.parse(data);\n if (validateImport(themeData.meta)) {\n createProgressIndicator(1, 'Importing theme...');\n let found = false;\n for (const id in themeData.theme) {\n if ({}.hasOwnProperty.call(themeData.theme, id)) {\n if (themeData.theme[id].name === name) {\n found = true;\n updateProgressIndicator(`Importing ${themeData.theme[id].name}`);\n putThemeByName(name, themeData.theme[id]).then((result) => {\n if (result == null) {\n stopProgressIndicator(\n `Error importing theme ${themeData.theme[id].name}`\n );\n printMessage(\n `Error importing theme ${themeData.theme[id].name}`,\n 'error'\n );\n } else {\n stopProgressIndicator(`Successfully imported theme ${name}.`);\n }\n });\n break;\n }\n }\n }\n if (!found) {\n stopProgressIndicator(`Theme ${name} not found!`);\n }\n } else {\n printMessage('Import validation failed...', 'error');\n }\n });\n}\n\n/**\n * Import theme by uuid from file\n * @param {String} id theme uuid\n * @param {String} file import file name\n */\nexport async function importThemeById(id, file) {\n fs.readFile(file, 'utf8', (err, data) => {\n if (err) throw err;\n const themeData = JSON.parse(data);\n if (validateImport(themeData.meta)) {\n createProgressIndicator(1, 'Importing theme...');\n let found = false;\n for (const themeId in themeData.theme) {\n if ({}.hasOwnProperty.call(themeData.theme, themeId)) {\n if (themeId === id) {\n found = true;\n updateProgressIndicator(\n `Importing ${themeData.theme[themeId]._id}`\n );\n putTheme(themeId, themeData.theme[themeId]).then((result) => {\n if (result == null) {\n stopProgressIndicator(\n `Error importing theme ${themeData.theme[themeId]._id}`\n );\n printMessage(\n `Error importing theme ${themeData.theme[themeId]._id}`,\n 'error'\n );\n } else {\n stopProgressIndicator(`Successfully imported theme ${id}.`);\n }\n });\n break;\n }\n }\n }\n if (!found) {\n stopProgressIndicator(`Theme ${id} not found!`);\n }\n } else {\n printMessage('Import validation failed...', 'error');\n }\n });\n}\n\n/**\n * Import all themes from single file\n * @param {String} file import file name\n */\nexport async function importThemesFromFile(file) {\n fs.readFile(file, 'utf8', (err, data) => {\n if (err) throw err;\n const fileData = JSON.parse(data);\n if (validateImport(fileData.meta)) {\n createProgressIndicator(\n Object.keys(fileData.theme).length,\n 'Importing themes...'\n );\n for (const id in fileData.theme) {\n if ({}.hasOwnProperty.call(fileData.theme, id)) {\n updateProgressIndicator(`Importing ${fileData.theme[id].name}`);\n }\n }\n putThemes(fileData.theme).then((result) => {\n if (result == null) {\n stopProgressIndicator(\n `Error importing ${Object.keys(fileData.theme).length} themes!`\n );\n printMessage(\n `Error importing ${\n Object.keys(fileData.theme).length\n } themes from ${file}`,\n 'error'\n );\n } else {\n stopProgressIndicator(\n `Successfully imported ${\n Object.keys(fileData.theme).length\n } themes.`\n );\n }\n });\n } else {\n printMessage('Import validation failed...', 'error');\n }\n });\n}\n\n/**\n * Import themes from separate files\n */\nexport async function importThemesFromFiles() {\n const names = fs.readdirSync('.');\n const jsonFiles = names.filter((name) =>\n name.toLowerCase().endsWith('.theme.json')\n );\n\n createProgressIndicator(jsonFiles.length, 'Importing themes...');\n let fileData = null;\n let count = 0;\n let total = 0;\n let files = 0;\n for (const file of jsonFiles) {\n const data = fs.readFileSync(file, 'utf8');\n fileData = JSON.parse(data);\n if (validateImport(fileData.meta)) {\n count = Object.keys(fileData.theme).length;\n // eslint-disable-next-line no-await-in-loop\n const result = await putThemes(fileData.theme);\n if (result == null) {\n printMessage(`Error importing ${count} themes from ${file}`, 'error');\n } else {\n files += 1;\n total += count;\n updateProgressIndicator(`Imported ${count} theme(s) from ${file}`);\n }\n } else {\n printMessage(`Validation of ${file} failed!`, 'error');\n }\n }\n stopProgressIndicator(\n `Finished importing ${total} theme(s) from ${files} file(s).`\n );\n}\n\n/**\n * Import first theme from file\n * @param {String} file import file name\n */\nexport async function importFirstThemeFromFile(file) {\n fs.readFile(file, 'utf8', (err, data) => {\n if (err) throw err;\n const themeData = JSON.parse(data);\n if (validateImport(themeData.meta)) {\n createProgressIndicator(1, 'Importing theme...');\n for (const id in themeData.theme) {\n if ({}.hasOwnProperty.call(themeData.theme, id)) {\n updateProgressIndicator(`Importing ${themeData.theme[id].name}`);\n putTheme(id, themeData.theme[id]).then((result) => {\n if (result == null) {\n stopProgressIndicator(\n `Error importing theme ${themeData.theme[id].name}`\n );\n printMessage(\n `Error importing theme ${themeData.theme[id].name}`,\n 'error'\n );\n } else {\n stopProgressIndicator(\n `Successfully imported theme ${themeData.theme[id].name}`\n );\n }\n });\n break;\n }\n }\n } else {\n printMessage('Import validation failed...', 'error');\n }\n });\n}\n\n/**\n * Delete theme by id\n * @param {String} id theme id\n */\nexport async function deleteThemeCmd(id) {\n createProgressIndicator(undefined, `Deleting ${id}...`, 'indeterminate');\n try {\n await deleteTheme(id);\n stopProgressIndicator(`Deleted ${id}.`, 'success');\n } catch (error) {\n stopProgressIndicator(`Error: ${error.message}`, 'fail');\n }\n}\n\n/**\n * Delete theme by name\n * @param {String} name theme name\n */\nexport async function deleteThemeByNameCmd(name) {\n createProgressIndicator(undefined, `Deleting ${name}...`, 'indeterminate');\n try {\n await deleteThemeByName(name);\n stopProgressIndicator(`Deleted ${name}.`, 'success');\n } catch (error) {\n stopProgressIndicator(`Error: ${error.message}`, 'fail');\n }\n}\n\n/**\n * Delete all themes\n */\nexport async function deleteThemesCmd() {\n createProgressIndicator(\n undefined,\n `Deleting all realm themes...`,\n 'indeterminate'\n );\n try {\n await deleteThemes();\n stopProgressIndicator(`Deleted all realm themes.`, 'success');\n } catch (error) {\n stopProgressIndicator(`Error: ${error.message}`, 'fail');\n }\n}\n"]}
|
|
1
|
+
{"version":3,"sources":["../src/ops/ThemeOps.ts"],"names":[],"mappings":"AA0BA;;;GAGG;AACH,wBAAsB,UAAU,CAAC,IAAI,UAAQ,iBAyB5C;AAED;;;;GAIG;AACH,wBAAsB,iBAAiB,CAAC,IAAI,KAAA,EAAE,IAAI,KAAA,iBAejD;AAED;;;;GAIG;AACH,wBAAsB,eAAe,CAAC,EAAE,KAAA,EAAE,IAAI,KAAA,iBAe7C;AAED;;;GAGG;AACH,wBAAsB,kBAAkB,CAAC,IAAI,KAAA,iBAc5C;AAED;;GAEG;AACH,wBAAsB,mBAAmB,kBASxC;AAED;;;;GAIG;AACH,wBAAsB,iBAAiB,CAAC,IAAI,KAAA,EAAE,IAAI,KAAA,iBAoCjD;AAED;;;;GAIG;AACH,wBAAsB,eAAe,CAAC,EAAE,KAAA,EAAE,IAAI,KAAA,iBAsC7C;AAED;;;GAGG;AACH,wBAAsB,oBAAoB,CAAC,IAAI,KAAA,iBAqC9C;AAED;;GAEG;AACH,wBAAsB,qBAAqB,kBAgC1C;AAED;;;GAGG;AACH,wBAAsB,wBAAwB,CAAC,IAAI,KAAA,iBA+BlD;AAED;;;GAGG;AACH,wBAAsB,cAAc,CAAC,EAAE,KAAA,iBAQtC;AAED;;;GAGG;AACH,wBAAsB,oBAAoB,CAAC,IAAI,KAAA,iBAQ9C;AAED;;GAEG;AACH,wBAAsB,eAAe,kBAYpC","file":"ThemeOps.d.ts","sourcesContent":["import fs from 'fs';\nimport {\n deleteTheme,\n deleteThemeByName,\n deleteThemes,\n getTheme,\n getThemeByName,\n getThemes,\n putTheme,\n putThemeByName,\n putThemes,\n} from '../api/ThemeApi';\nimport {\n createProgressIndicator,\n createTable,\n printMessage,\n stopProgressIndicator,\n updateProgressIndicator,\n} from './utils/Console';\nimport {\n getRealmString,\n getTypedFilename,\n saveToFile,\n validateImport,\n} from './utils/ExportImportUtils';\n\n/**\n * List all the themes\n * @param {boolean} long Long version, more fields\n */\nexport async function listThemes(long = false) {\n const themeList = await getThemes();\n themeList.sort((a, b) => a.name.localeCompare(b.name));\n if (!long) {\n themeList.forEach((theme) => {\n printMessage(\n `${theme.isDefault ? theme.name.brightCyan : theme.name}`,\n 'data'\n );\n });\n } else {\n const table = createTable([\n 'Name'['brightCyan'],\n 'Id'['brightCyan'],\n 'Default'['brightCyan'],\n ]);\n themeList.forEach((theme) => {\n table.push([\n `${theme.name}`,\n `${theme._id}`,\n `${theme.isDefault ? 'Yes'['brightGreen'] : ''}`,\n ]);\n });\n printMessage(table.toString(), 'data');\n }\n}\n\n/**\n * Export theme by name to file\n * @param {String} name theme name\n * @param {String} file optional export file name\n */\nexport async function exportThemeByName(name, file) {\n let fileName = getTypedFilename(name, 'theme');\n if (file) {\n fileName = file;\n }\n createProgressIndicator(1, `Exporting ${name}`);\n const themeData = await getThemeByName(name);\n if (themeData.length === 0) {\n stopProgressIndicator(`Theme ${name} not found!`);\n printMessage(`Theme ${name} not found!`, 'error');\n } else {\n updateProgressIndicator(`Writing file ${fileName}`);\n saveToFile('theme', themeData, '_id', fileName);\n stopProgressIndicator(`Successfully exported theme ${name}.`);\n }\n}\n\n/**\n * Export theme by uuid to file\n * @param {String} id theme uuid\n * @param {String} file optional export file name\n */\nexport async function exportThemeById(id, file) {\n let fileName = getTypedFilename(id, 'theme');\n if (file) {\n fileName = file;\n }\n createProgressIndicator(1, `Exporting ${id}`);\n const themeData = await getTheme(id);\n if (themeData.length === 0) {\n stopProgressIndicator(`Theme ${id} not found!`);\n printMessage(`Theme ${id} not found!`, 'error');\n } else {\n updateProgressIndicator(`Writing file ${fileName}`);\n saveToFile('theme', themeData, '_id', fileName);\n stopProgressIndicator(`Successfully exported theme ${id}.`);\n }\n}\n\n/**\n * Export all themes to file\n * @param {String} file optional export file name\n */\nexport async function exportThemesToFile(file) {\n let fileName = getTypedFilename(`all${getRealmString()}Themes`, 'theme');\n if (file) {\n fileName = file;\n }\n const allThemesData = await getThemes();\n createProgressIndicator(allThemesData.length, 'Exporting themes');\n for (const themeData of allThemesData) {\n updateProgressIndicator(`Exporting theme ${themeData.name}`);\n }\n saveToFile('theme', allThemesData, '_id', fileName);\n stopProgressIndicator(\n `${allThemesData.length} themes exported to ${fileName}.`\n );\n}\n\n/**\n * Export all themes to separate files\n */\nexport async function exportThemesToFiles() {\n const allThemesData = await getThemes();\n createProgressIndicator(allThemesData.length, 'Exporting themes');\n for (const themeData of allThemesData) {\n updateProgressIndicator(`Writing theme ${themeData.name}`);\n const fileName = getTypedFilename(themeData.name, 'theme');\n saveToFile('theme', themeData, '_id', fileName);\n }\n stopProgressIndicator(`${allThemesData.length} themes exported.`);\n}\n\n/**\n * Import theme by name from file\n * @param {String} name theme name\n * @param {String} file import file name\n */\nexport async function importThemeByName(name, file) {\n fs.readFile(file, 'utf8', (err, data) => {\n if (err) throw err;\n const themeData = JSON.parse(data);\n if (validateImport(themeData.meta)) {\n createProgressIndicator(1, 'Importing theme...');\n let found = false;\n for (const id in themeData.theme) {\n if ({}.hasOwnProperty.call(themeData.theme, id)) {\n if (themeData.theme[id].name === name) {\n found = true;\n updateProgressIndicator(`Importing ${themeData.theme[id].name}`);\n putThemeByName(name, themeData.theme[id]).then((result) => {\n if (result == null) {\n stopProgressIndicator(\n `Error importing theme ${themeData.theme[id].name}`\n );\n printMessage(\n `Error importing theme ${themeData.theme[id].name}`,\n 'error'\n );\n } else {\n stopProgressIndicator(`Successfully imported theme ${name}.`);\n }\n });\n break;\n }\n }\n }\n if (!found) {\n stopProgressIndicator(`Theme ${name} not found!`);\n }\n } else {\n printMessage('Import validation failed...', 'error');\n }\n });\n}\n\n/**\n * Import theme by uuid from file\n * @param {String} id theme uuid\n * @param {String} file import file name\n */\nexport async function importThemeById(id, file) {\n fs.readFile(file, 'utf8', (err, data) => {\n if (err) throw err;\n const themeData = JSON.parse(data);\n if (validateImport(themeData.meta)) {\n createProgressIndicator(1, 'Importing theme...');\n let found = false;\n for (const themeId in themeData.theme) {\n if ({}.hasOwnProperty.call(themeData.theme, themeId)) {\n if (themeId === id) {\n found = true;\n updateProgressIndicator(\n `Importing ${themeData.theme[themeId]._id}`\n );\n putTheme(themeId, themeData.theme[themeId]).then((result) => {\n if (result == null) {\n stopProgressIndicator(\n `Error importing theme ${themeData.theme[themeId]._id}`\n );\n printMessage(\n `Error importing theme ${themeData.theme[themeId]._id}`,\n 'error'\n );\n } else {\n stopProgressIndicator(`Successfully imported theme ${id}.`);\n }\n });\n break;\n }\n }\n }\n if (!found) {\n stopProgressIndicator(`Theme ${id} not found!`);\n }\n } else {\n printMessage('Import validation failed...', 'error');\n }\n });\n}\n\n/**\n * Import all themes from single file\n * @param {String} file import file name\n */\nexport async function importThemesFromFile(file) {\n fs.readFile(file, 'utf8', (err, data) => {\n if (err) throw err;\n const fileData = JSON.parse(data);\n if (validateImport(fileData.meta)) {\n createProgressIndicator(\n Object.keys(fileData.theme).length,\n 'Importing themes...'\n );\n for (const id in fileData.theme) {\n if ({}.hasOwnProperty.call(fileData.theme, id)) {\n updateProgressIndicator(`Importing ${fileData.theme[id].name}`);\n }\n }\n putThemes(fileData.theme).then((result) => {\n if (result == null) {\n stopProgressIndicator(\n `Error importing ${Object.keys(fileData.theme).length} themes!`\n );\n printMessage(\n `Error importing ${\n Object.keys(fileData.theme).length\n } themes from ${file}`,\n 'error'\n );\n } else {\n stopProgressIndicator(\n `Successfully imported ${\n Object.keys(fileData.theme).length\n } themes.`\n );\n }\n });\n } else {\n printMessage('Import validation failed...', 'error');\n }\n });\n}\n\n/**\n * Import themes from separate files\n */\nexport async function importThemesFromFiles() {\n const names = fs.readdirSync('.');\n const jsonFiles = names.filter((name) =>\n name.toLowerCase().endsWith('.theme.json')\n );\n\n createProgressIndicator(jsonFiles.length, 'Importing themes...');\n let fileData = null;\n let count = 0;\n let total = 0;\n let files = 0;\n for (const file of jsonFiles) {\n const data = fs.readFileSync(file, 'utf8');\n fileData = JSON.parse(data);\n if (validateImport(fileData.meta)) {\n count = Object.keys(fileData.theme).length;\n // eslint-disable-next-line no-await-in-loop\n const result = await putThemes(fileData.theme);\n if (result == null) {\n printMessage(`Error importing ${count} themes from ${file}`, 'error');\n } else {\n files += 1;\n total += count;\n updateProgressIndicator(`Imported ${count} theme(s) from ${file}`);\n }\n } else {\n printMessage(`Validation of ${file} failed!`, 'error');\n }\n }\n stopProgressIndicator(\n `Finished importing ${total} theme(s) from ${files} file(s).`\n );\n}\n\n/**\n * Import first theme from file\n * @param {String} file import file name\n */\nexport async function importFirstThemeFromFile(file) {\n fs.readFile(file, 'utf8', (err, data) => {\n if (err) throw err;\n const themeData = JSON.parse(data);\n if (validateImport(themeData.meta)) {\n createProgressIndicator(1, 'Importing theme...');\n for (const id in themeData.theme) {\n if ({}.hasOwnProperty.call(themeData.theme, id)) {\n updateProgressIndicator(`Importing ${themeData.theme[id].name}`);\n putTheme(id, themeData.theme[id]).then((result) => {\n if (result == null) {\n stopProgressIndicator(\n `Error importing theme ${themeData.theme[id].name}`\n );\n printMessage(\n `Error importing theme ${themeData.theme[id].name}`,\n 'error'\n );\n } else {\n stopProgressIndicator(\n `Successfully imported theme ${themeData.theme[id].name}`\n );\n }\n });\n break;\n }\n }\n } else {\n printMessage('Import validation failed...', 'error');\n }\n });\n}\n\n/**\n * Delete theme by id\n * @param {String} id theme id\n */\nexport async function deleteThemeCmd(id) {\n createProgressIndicator(undefined, `Deleting ${id}...`, 'indeterminate');\n try {\n await deleteTheme(id);\n stopProgressIndicator(`Deleted ${id}.`, 'success');\n } catch (error) {\n stopProgressIndicator(`Error: ${error.message}`, 'fail');\n }\n}\n\n/**\n * Delete theme by name\n * @param {String} name theme name\n */\nexport async function deleteThemeByNameCmd(name) {\n createProgressIndicator(undefined, `Deleting ${name}...`, 'indeterminate');\n try {\n await deleteThemeByName(name);\n stopProgressIndicator(`Deleted ${name}.`, 'success');\n } catch (error) {\n stopProgressIndicator(`Error: ${error.message}`, 'fail');\n }\n}\n\n/**\n * Delete all themes\n */\nexport async function deleteThemesCmd() {\n createProgressIndicator(\n undefined,\n `Deleting all realm themes...`,\n 'indeterminate'\n );\n try {\n await deleteThemes();\n stopProgressIndicator(`Deleted all realm themes.`, 'success');\n } catch (error) {\n stopProgressIndicator(`Error: ${error.message}`, 'fail');\n }\n}\n"]}
|