@kasko/fe-toolbelt
Advanced tools
Comparing version 2.0.1 to 2.1.0
# Changelog | ||
## [v2.1.0](https://github.com/kasko/fe-toolbelt/compare/v2.0.1...v2.1.0) (2023-09-08) | ||
## Feature | ||
- Adds build step to minimize dependency count for webapps; | ||
- Removes `canvas` dependency, it must be installed separately to use `graph` command; | ||
## [v2.0.1](https://github.com/kasko/fe-toolbelt/compare/v2.0.0...v2.0.1) (2023-01-02) | ||
@@ -3,0 +8,0 @@ ## Bugfix |
@@ -17,4 +17,4 @@ { | ||
"coverage", | ||
"node_modules", | ||
"node_modules" | ||
] | ||
} |
{ | ||
"license": "UNLICENSED", | ||
"name": "@kasko/fe-toolbelt", | ||
"version": "2.0.1", | ||
"version": "2.1.0", | ||
"engines": { | ||
"node": ">=8.11.x" | ||
"node": ">=16" | ||
}, | ||
"main": "src/app.js", | ||
"main": "./dist/app.js", | ||
"bin": { | ||
"kasko-fe": "src/index.js", | ||
"kk": "src/index.js" | ||
"kasko-fe": "./dist/index.js", | ||
"kk": "./dist/index.js" | ||
}, | ||
"scripts": { | ||
"start": "node src/index.js", | ||
"lint": "eslint --ignore-path .gitignore .", | ||
"test": "jest", | ||
"test:watch": "jest --watch", | ||
"test:ci": "npm run test -- --ci" | ||
"build": "node scripts/build.js", | ||
"start": "node dist/index.js", | ||
"lint": "biome check src", | ||
"test": "jest --ci", | ||
"test:watch": "jest --watch" | ||
}, | ||
"devDependencies": { | ||
"@biomejs/biome": "^1.0.0", | ||
"@kasko/webapp-flow-visualizer-lib": "^1.0.1", | ||
"@types/jest": "^29.1.2", | ||
"eslint": "^6.8.0", | ||
"eslint-config-kasko-base": "^1.1.4", | ||
"husky": "^3.0.5", | ||
"jest": "^26.0.1", | ||
"lint-staged": "^9.2.5", | ||
"nock": "^11.3.3" | ||
}, | ||
"dependencies": { | ||
"@kasko/webapp-flow-visualizer-lib": "^1.0.1", | ||
"archiver": "^3.1.1", | ||
"axios": "^0.19.0", | ||
"canvas": "^2.10.1", | ||
"canvas": "^2.11.2", | ||
"dotenv": "^8.1.0", | ||
"esbuild": "^0.19.2", | ||
"express": "^4.17.1", | ||
"flat": "^5.0.1", | ||
"form-data": "^2.5.1", | ||
"fs-extra": "^8.1.0", | ||
"getopts": "^2.2.3", | ||
"js-yaml": "^3.13.1", | ||
"marked": "^0.7.0", | ||
"marked-terminal": "^3.3.0", | ||
"ora": "^3.0.0" | ||
"identity-obj-proxy": "^3.0.0", | ||
"jest": "^26.0.1", | ||
"js-yaml": "^4.1.0", | ||
"msw": "^1.3.0", | ||
"nanospinner": "^1.1.0" | ||
}, | ||
@@ -48,15 +42,10 @@ "jest": { | ||
"testEnvironment": "node", | ||
"bail": true | ||
}, | ||
"husky": { | ||
"hooks": { | ||
"pre-commit": "lint-staged" | ||
"bail": true, | ||
"setupFiles": [ | ||
"./test.setup.js" | ||
], | ||
"moduleNameMapper": { | ||
"\\.md$": "identity-obj-proxy" | ||
} | ||
}, | ||
"lint-staged": { | ||
"*.js": [ | ||
"yarn eslint --fix", | ||
"git add" | ||
] | ||
} | ||
} |
/* This object contains aliases for flags | ||
* e.g. `kasko-fe -v` === `kasko-fe -version` */ | ||
* e.g. `kasko-fe -v` === `kasko-fe -version` */ | ||
const alias = { | ||
@@ -4,0 +4,0 @@ v: 'version', |
@@ -21,23 +21,25 @@ const axios = require('../../axios'); | ||
*/ | ||
function assumeRole( | ||
host, | ||
accountId, | ||
token, | ||
) { | ||
return axios.post(`https://api.${host}/v2/auth/assume_role`, { | ||
role_name: 'KASKO/KaskoWebappDeploymentRole', | ||
account_id: accountId, | ||
}, { | ||
headers: { | ||
Authorization: `Bearer ${token}`, | ||
'Content-Type': 'application/json', | ||
}, | ||
}).then( | ||
/** | ||
* @param {{ data: APIAuthAssumeRoleResponse }} response | ||
*/ | ||
(response) => response && response.data && response.data.token, | ||
); | ||
function assumeRole(host, accountId, token) { | ||
return axios | ||
.post( | ||
`https://api.${host}/v2/auth/assume_role`, | ||
{ | ||
role_name: 'KASKO/KaskoWebappDeploymentRole', | ||
account_id: accountId, | ||
}, | ||
{ | ||
headers: { | ||
Authorization: `Bearer ${token}`, | ||
'Content-Type': 'application/json', | ||
}, | ||
}, | ||
) | ||
.then( | ||
/** | ||
* @param {{ data: APIAuthAssumeRoleResponse }} response | ||
*/ | ||
(response) => response?.data?.token, | ||
); | ||
} | ||
module.exports = assumeRole; |
@@ -8,6 +8,3 @@ const fs = require('fs'); | ||
const key = `${timestamp}|${location}`; | ||
const hash = crypto | ||
.createHash('md5') | ||
.update(key) | ||
.digest('hex'); | ||
const hash = crypto.createHash('md5').update(key).digest('hex'); | ||
const destination = `.tmp/app-${hash}.zip`; | ||
@@ -14,0 +11,0 @@ |
@@ -22,20 +22,18 @@ const axios = require('../../axios'); | ||
*/ | ||
function deployRelease( | ||
host, | ||
pluginId, | ||
fileId, | ||
token, | ||
version = undefined, | ||
) { | ||
return axios.post(`https://api.${host}/webapp_plugins/${pluginId}/code`, { | ||
file_id: fileId, | ||
version: normalizeVersionTag(version), | ||
}, { | ||
headers: { | ||
Authorization: `Bearer ${token}`, | ||
'Content-Type': 'application/json', | ||
function deployRelease(host, pluginId, fileId, token, version = undefined) { | ||
return axios.post( | ||
`https://api.${host}/webapp_plugins/${pluginId}/code`, | ||
{ | ||
file_id: fileId, | ||
version: normalizeVersionTag(version), | ||
}, | ||
}); | ||
{ | ||
headers: { | ||
Authorization: `Bearer ${token}`, | ||
'Content-Type': 'application/json', | ||
}, | ||
}, | ||
); | ||
} | ||
module.exports = deployRelease; |
@@ -10,12 +10,24 @@ const axios = require('../../axios'); | ||
*/ | ||
function deployWebapp( | ||
host, | ||
webappId, | ||
fileId, | ||
token, | ||
) { | ||
function deployWebapp(host, webappId, fileId, token) { | ||
if (!webappId) { | ||
return axios.post(`https://api.${host}/webapps`, { | ||
return axios.post( | ||
`https://api.${host}/webapps`, | ||
{ | ||
file_id: fileId, | ||
}, | ||
{ | ||
headers: { | ||
Authorization: `Bearer ${token}`, | ||
'Content-Type': 'application/json', | ||
}, | ||
}, | ||
); | ||
} | ||
return axios.patch( | ||
`https://api.${host}/webapps/${webappId}`, | ||
{ | ||
file_id: fileId, | ||
}, { | ||
}, | ||
{ | ||
headers: { | ||
@@ -25,15 +37,6 @@ Authorization: `Bearer ${token}`, | ||
}, | ||
}); | ||
} | ||
return axios.patch(`https://api.${host}/webapps/${webappId}`, { | ||
file_id: fileId, | ||
}, { | ||
headers: { | ||
Authorization: `Bearer ${token}`, | ||
'Content-Type': 'application/json', | ||
}, | ||
}); | ||
); | ||
} | ||
module.exports = deployWebapp; |
@@ -1,3 +0,2 @@ | ||
/* eslint-disable no-continue,no-restricted-syntax,no-await-in-loop */ | ||
const ora = require('ora'); | ||
const { createSpinner } = require('nanospinner'); | ||
const yaml = require('js-yaml'); | ||
@@ -66,8 +65,12 @@ const fs = require('fs'); | ||
*/ | ||
async function deployV1({ | ||
plugin: name, | ||
host = 'eu1.kaskocloud.com', | ||
version, | ||
'fail-on-existing-version': failOnExistingVersion = false, | ||
} = { }, config) { | ||
async function deployV1( | ||
// rome-ignore lint/style/useDefaultParameterLast: <explanation> | ||
{ | ||
plugin: name, | ||
host = 'eu1.kaskocloud.com', | ||
version, | ||
'fail-on-existing-version': failOnExistingVersion = false, | ||
} = {}, | ||
config, | ||
) { | ||
const plugins = Object.keys(config.plugins).map((pluginName) => ({ | ||
@@ -88,3 +91,3 @@ ...config.plugins[pluginName], | ||
for (const plugin of filteredPlugins) { | ||
const spinner = ora(`Deploying ${plugin.name}`).start(); | ||
const spinner = createSpinner(`Deploying ${plugin.name}`).start(); | ||
let fileId; | ||
@@ -102,3 +105,3 @@ | ||
await deployRelease(host, plugin.id, fileId, token, version); | ||
spinner.succeed(`Deployed ${plugin.name}`); | ||
spinner.success({ text: `Deployed ${plugin.name}` }); | ||
@@ -109,3 +112,3 @@ if (fileId) { | ||
} catch (e) { | ||
spinner.fail(`Failed deploying ${plugin.name}`); | ||
spinner.error({ text: `Failed deploying ${plugin.name}` }); | ||
@@ -123,3 +126,3 @@ if (fileId) { | ||
if (e.response && e.response.request) { | ||
if (e.response?.request) { | ||
print(` ${e.response.status} ${e.response.request.method} ${e.response.request.path}`); | ||
@@ -140,7 +143,11 @@ } | ||
*/ | ||
async function deployV2({ | ||
plugin: name, | ||
host = 'eu1.kaskocloud.com', | ||
'fail-on-existing-version': failOnExistingVersion = false, | ||
} = { }, config) { | ||
async function deployV2( | ||
// rome-ignore lint/style/useDefaultParameterLast: <explanation> | ||
{ | ||
plugin: name, | ||
host = 'eu1.kaskocloud.com', | ||
'fail-on-existing-version': failOnExistingVersion = false, | ||
} = {}, | ||
config, | ||
) { | ||
const plugins = Object.keys(config.plugins).map((pluginName) => ({ | ||
@@ -164,3 +171,3 @@ ...config.plugins[pluginName], | ||
const buildLocation = path.join(plugin.build_location, 'products', plugin.product_id, 'webapp'); | ||
const spinner = ora(`Deploying ${plugin.name}`).start(); | ||
const spinner = createSpinner(`Deploying ${plugin.name}`).start(); | ||
let fileId; | ||
@@ -182,3 +189,8 @@ | ||
if (!product.data.has_subproducts) { | ||
const contentsLocation = path.join(plugin.build_location, 'products', plugin.product_id, 'contents.json'); | ||
const contentsLocation = path.join( | ||
plugin.build_location, | ||
'products', | ||
plugin.product_id, | ||
'contents.json', | ||
); | ||
await updateContents(host, plugin.product_id, undefined, contentsLocation, token); | ||
@@ -196,3 +208,4 @@ } | ||
const subProductsLocation = path.join(manifestsLocation, 'sub_products'); | ||
const subProducts = fs.readdirSync(subProductsLocation, 'utf-8') | ||
const subProducts = fs | ||
.readdirSync(subProductsLocation, 'utf-8') | ||
.filter((filePath) => filePath.startsWith('spr_')); | ||
@@ -230,4 +243,10 @@ | ||
const integrationsLocation = path.join(plugin.build_location, 'products', plugin.product_id, 'integrations'); | ||
const integrations = fs.readdirSync(integrationsLocation, 'utf-8') | ||
const integrationsLocation = path.join( | ||
plugin.build_location, | ||
'products', | ||
plugin.product_id, | ||
'integrations', | ||
); | ||
const integrations = fs | ||
.readdirSync(integrationsLocation, 'utf-8') | ||
.filter((filePath) => filePath.startsWith('in_')); | ||
@@ -239,9 +258,3 @@ | ||
await updateIntegration( | ||
host, | ||
plugin.product_id, | ||
integrationId, | ||
integrationPath, | ||
token, | ||
); | ||
await updateIntegration(host, plugin.product_id, integrationId, integrationPath, token); | ||
} | ||
@@ -260,3 +273,3 @@ | ||
spinner.succeed(`Deployed ${plugin.name}`); | ||
spinner.success({ text: `Deployed ${plugin.name}` }); | ||
@@ -267,3 +280,3 @@ if (fileId) { | ||
} catch (e) { | ||
spinner.fail(`Failed deploying ${plugin.name}`); | ||
spinner.error({ text: `Failed deploying ${plugin.name}` }); | ||
@@ -281,3 +294,3 @@ if (fileId) { | ||
if (e.response && e.response.request) { | ||
if (e.response?.request) { | ||
print(` ${e.response.status} ${e.response.request.method} ${e.response.request.path}`); | ||
@@ -297,3 +310,3 @@ } | ||
*/ | ||
function deploy(flags = { }) { | ||
function deploy(flags = {}) { | ||
if (!process.env.KASKO_PRIVATE_KEY) { | ||
@@ -308,3 +321,3 @@ throw new Error('KASKO_PRIVATE_KEY environment variable must be set'); | ||
/** @type {KaskoConfig} */ | ||
const config = yaml.safeLoad(fs.readFileSync('kasko.yaml', 'utf8')); | ||
const config = yaml.load(fs.readFileSync('kasko.yaml', 'utf8')); | ||
@@ -322,3 +335,4 @@ switch (config.version) { | ||
default: break; | ||
default: | ||
break; | ||
} | ||
@@ -328,1 +342,2 @@ } | ||
module.exports = deploy; | ||
module.exports.readme = require('./readme.md'); |
@@ -10,19 +10,15 @@ const axios = require('../../axios'); | ||
*/ | ||
async function getContents( | ||
host, | ||
productId, | ||
subProductId, | ||
token, | ||
) { | ||
async function getContents(host, productId, subProductId, token) { | ||
try { | ||
const subProductChunk = subProductId | ||
? `/subproducts/${subProductId}` | ||
: ''; | ||
const subProductChunk = subProductId ? `/subproducts/${subProductId}` : ''; | ||
return await axios.get(`https://api.${host}/v2/products/${productId}${subProductChunk}/contents`, { | ||
headers: { | ||
Authorization: `Bearer ${token}`, | ||
'Content-Type': 'application/json', | ||
return await axios.get( | ||
`https://api.${host}/v2/products/${productId}${subProductChunk}/contents`, | ||
{ | ||
headers: { | ||
Authorization: `Bearer ${token}`, | ||
'Content-Type': 'application/json', | ||
}, | ||
}, | ||
}); | ||
); | ||
} catch (e) { | ||
@@ -29,0 +25,0 @@ return null; |
@@ -9,7 +9,3 @@ const axios = require('../../axios'); | ||
*/ | ||
function getProductInfo( | ||
host, | ||
productId, | ||
token, | ||
) { | ||
function getProductInfo(host, productId, token) { | ||
return axios.get(`https://api.${host}/v2/products/${productId}`, { | ||
@@ -16,0 +12,0 @@ headers: { |
@@ -15,9 +15,3 @@ const fs = require('fs'); | ||
*/ | ||
async function updateContents( | ||
host, | ||
productId, | ||
subProductId, | ||
contentsLocation, | ||
token, | ||
) { | ||
async function updateContents(host, productId, subProductId, contentsLocation, token) { | ||
let data; | ||
@@ -32,5 +26,3 @@ | ||
const subProductChunk = subProductId | ||
? `/subproducts/${subProductId}` | ||
: ''; | ||
const subProductChunk = subProductId ? `/subproducts/${subProductId}` : ''; | ||
@@ -40,5 +32,22 @@ const existingContents = await getContents(host, productId, subProductId, token); | ||
if (!existingContents) { | ||
return axios.post(`https://api.${host}/v2/products/${productId}${subProductChunk}/contents`, { | ||
return axios.post( | ||
`https://api.${host}/v2/products/${productId}${subProductChunk}/contents`, | ||
{ | ||
data, | ||
}, | ||
{ | ||
headers: { | ||
Authorization: `Bearer ${token}`, | ||
'Content-Type': 'application/json', | ||
}, | ||
}, | ||
); | ||
} | ||
return axios.patch( | ||
`https://api.${host}/v2/products/${productId}${subProductChunk}/contents`, | ||
{ | ||
data, | ||
}, { | ||
}, | ||
{ | ||
headers: { | ||
@@ -48,15 +57,6 @@ Authorization: `Bearer ${token}`, | ||
}, | ||
}); | ||
} | ||
return axios.patch(`https://api.${host}/v2/products/${productId}${subProductChunk}/contents`, { | ||
data, | ||
}, { | ||
headers: { | ||
Authorization: `Bearer ${token}`, | ||
'Content-Type': 'application/json', | ||
}, | ||
}); | ||
); | ||
} | ||
module.exports = updateContents; |
@@ -13,9 +13,3 @@ const fs = require('fs'); | ||
*/ | ||
async function updateIntegration( | ||
host, | ||
productId, | ||
integrationId, | ||
integrationPath, | ||
token, | ||
) { | ||
async function updateIntegration(host, productId, integrationId, integrationPath, token) { | ||
let data; | ||
@@ -30,10 +24,14 @@ | ||
return axios.patch(`https://api.${host}/v2/products/${productId}/integrations/${integrationId}`, data, { | ||
headers: { | ||
Authorization: `Bearer ${token}`, | ||
'Content-Type': 'application/json', | ||
return axios.patch( | ||
`https://api.${host}/v2/products/${productId}/integrations/${integrationId}`, | ||
data, | ||
{ | ||
headers: { | ||
Authorization: `Bearer ${token}`, | ||
'Content-Type': 'application/json', | ||
}, | ||
}, | ||
}); | ||
); | ||
} | ||
module.exports = updateIntegration; |
@@ -10,8 +10,3 @@ const axios = require('../../axios'); | ||
*/ | ||
function updateProduct( | ||
host, | ||
productId, | ||
data, | ||
token, | ||
) { | ||
function updateProduct(host, productId, data, token) { | ||
return axios.patch(`https://api.${host}/v2/products/${productId}`, data, { | ||
@@ -18,0 +13,0 @@ headers: { |
@@ -11,17 +11,15 @@ const axios = require('../../axios'); | ||
*/ | ||
function updateSubProduct( | ||
host, | ||
productId, | ||
subProductId, | ||
data, | ||
token, | ||
) { | ||
return axios.patch(`https://api.${host}/v2/products/${productId}/subproducts/${subProductId}`, data, { | ||
headers: { | ||
Authorization: `Bearer ${token}`, | ||
'Content-Type': 'application/json', | ||
function updateSubProduct(host, productId, subProductId, data, token) { | ||
return axios.patch( | ||
`https://api.${host}/v2/products/${productId}/subproducts/${subProductId}`, | ||
data, | ||
{ | ||
headers: { | ||
Authorization: `Bearer ${token}`, | ||
'Content-Type': 'application/json', | ||
}, | ||
}, | ||
}); | ||
); | ||
} | ||
module.exports = updateSubProduct; |
const fs = require('fs'); | ||
const FormData = require('form-data'); | ||
const axios = require('../../axios'); | ||
const kaskoFetch = require('../../kasko-fetch'); | ||
/** | ||
@@ -12,13 +12,15 @@ * @param {string} host | ||
function uploadZip(host, file, token) { | ||
const data = new FormData(); | ||
data.append('file', fs.createReadStream(file)); | ||
const body = new FormData(); | ||
const blob = new Blob([fs.readFileSync(file)]); | ||
body.append('file', blob, file); | ||
return axios.post(`https://upload.${host}/uploads`, data, { | ||
return kaskoFetch('https://upload.${host}/uploads', { | ||
method: 'POST', | ||
body, | ||
headers: { | ||
Authorization: `Bearer ${token}`, | ||
...data.getHeaders(), | ||
}, | ||
}).then((response) => response.data.id); | ||
}).then((data) => data.id); | ||
} | ||
module.exports = uploadZip; |
@@ -10,8 +10,9 @@ const axios = require('../../axios'); | ||
const url = `${kaskoConfig.feApiUrl}/touchpoints/${kaskoConfig.touchpointId}/items/${item.id}`; | ||
const { data } = await axios.get(url, { | ||
params: { | ||
language: kaskoConfig.language, | ||
key: kaskoConfig.publicKey, | ||
}, | ||
}) | ||
const { data } = await axios | ||
.get(url, { | ||
params: { | ||
language: kaskoConfig.language, | ||
key: kaskoConfig.publicKey, | ||
}, | ||
}) | ||
.catch((error) => { | ||
@@ -18,0 +19,0 @@ throw error; |
@@ -15,10 +15,11 @@ const axios = require('../../axios'); | ||
const url = `${kaskoConfig.feApiUrl}/integrations/${kaskoConfig.touchpointId}`; | ||
const { data } = await axios.get(url, { | ||
params: { | ||
language: kaskoConfig.language, | ||
key: kaskoConfig.publicKey, | ||
product_version: kaskoConfig.productVersionId, | ||
integration_version: kaskoConfig.integrationVersionId, | ||
}, | ||
}) | ||
const { data } = await axios | ||
.get(url, { | ||
params: { | ||
language: kaskoConfig.language, | ||
key: kaskoConfig.publicKey, | ||
product_version: kaskoConfig.productVersionId, | ||
integration_version: kaskoConfig.integrationVersionId, | ||
}, | ||
}) | ||
.catch((error) => { | ||
@@ -25,0 +26,0 @@ throw error; |
@@ -10,10 +10,11 @@ const axios = require('../../axios'); | ||
const url = `${kaskoConfig.feApiUrl}/integrations/${kaskoConfig.touchpointId}/subproducts/${item.id}`; | ||
const { data } = await axios.get(url, { | ||
params: { | ||
language: kaskoConfig.language, | ||
key: kaskoConfig.publicKey, | ||
product_version: kaskoConfig.productVersionId, | ||
integration_version: kaskoConfig.integrationVersionId, | ||
}, | ||
}) | ||
const { data } = await axios | ||
.get(url, { | ||
params: { | ||
language: kaskoConfig.language, | ||
key: kaskoConfig.publicKey, | ||
product_version: kaskoConfig.productVersionId, | ||
integration_version: kaskoConfig.integrationVersionId, | ||
}, | ||
}) | ||
.catch((error) => { | ||
@@ -20,0 +21,0 @@ throw error; |
@@ -15,8 +15,9 @@ const axios = require('../../axios'); | ||
const url = `${kaskoConfig.feApiUrl}/touchpoints/${kaskoConfig.touchpointId}`; | ||
const { data } = await axios.get(url, { | ||
params: { | ||
language: kaskoConfig.language, | ||
key: kaskoConfig.publicKey, | ||
}, | ||
}) | ||
const { data } = await axios | ||
.get(url, { | ||
params: { | ||
language: kaskoConfig.language, | ||
key: kaskoConfig.publicKey, | ||
}, | ||
}) | ||
.catch((error) => { | ||
@@ -23,0 +24,0 @@ throw error; |
@@ -11,25 +11,24 @@ const KASKO_CONFIG_REGEX = /window\.kaskoConfig = {([^}]+)/; | ||
if (!(configText && configText.trim())) { | ||
if (!configText?.trim()) { | ||
throw new Error('Webapp config could not be loaded'); | ||
} | ||
const config = configText | ||
.split(KASKO_CONFIG_SEPARATOR_REGEX) | ||
.reduce((acc, chunk) => { | ||
const [key, ...value] = chunk.split(':'); | ||
const trimmedKey = key.trim(); | ||
const config = configText.split(KASKO_CONFIG_SEPARATOR_REGEX).reduce((acc, chunk) => { | ||
const [key, ...value] = chunk.split(':'); | ||
const trimmedKey = key.trim(); | ||
if (!trimmedKey) { | ||
return acc; | ||
} | ||
if (!trimmedKey) { | ||
return acc; | ||
} | ||
const normalizedValue = value.join(':') | ||
.trim() | ||
.replace(/^[']|[']$/g, '"') | ||
.replace(/^kqsLang$/g, '"en"'); | ||
const normalizedValue = value | ||
.join(':') | ||
.trim() | ||
.replace(/^[']|[']$/g, '"') | ||
.replace(/^kqsLang$/g, '"en"'); | ||
acc[trimmedKey] = JSON.parse(normalizedValue); | ||
acc[trimmedKey] = JSON.parse(normalizedValue); | ||
return acc; | ||
}, {}); | ||
return acc; | ||
}, {}); | ||
@@ -36,0 +35,0 @@ return config; |
@@ -12,9 +12,8 @@ const axios = require('../../axios'); | ||
async function getWebappData(url) { | ||
const { data } = await axios.get(url) | ||
.catch((error) => { | ||
throw error; | ||
}); | ||
const { data } = await axios.get(url).catch((error) => { | ||
throw error; | ||
}); | ||
if (typeof data !== 'string' || !data) { | ||
throw new Error('Webapp couldn\'t be loaded'); | ||
throw new Error("Webapp couldn't be loaded"); | ||
} | ||
@@ -24,8 +23,10 @@ | ||
if (!( | ||
kaskoConfig.touchpointId | ||
&& kaskoConfig.publicKey | ||
&& kaskoConfig.feApiUrl | ||
&& kaskoConfig.language | ||
)) { | ||
if ( | ||
!( | ||
kaskoConfig.touchpointId && | ||
kaskoConfig.publicKey && | ||
kaskoConfig.feApiUrl && | ||
kaskoConfig.language | ||
) | ||
) { | ||
throw new Error('Unsupported webapp configuration'); | ||
@@ -32,0 +33,0 @@ } |
@@ -1,6 +0,4 @@ | ||
/* eslint-disable no-restricted-syntax */ | ||
const { build } = require('@kasko/webapp-flow-visualizer-lib'); | ||
const { createCanvas } = require('canvas'); | ||
const fs = require('fs'); | ||
const ora = require('ora'); | ||
const { createSpinner } = require('nanospinner'); | ||
@@ -26,10 +24,22 @@ const getItem = require('./getItem'); | ||
*/ | ||
async function graph({ | ||
format = 'png', | ||
fontSize = undefined, | ||
silent = false, | ||
output = 'verbose', | ||
fromCli = false, | ||
file = false, | ||
} = {}, attributes) { | ||
async function graph( | ||
// rome-ignore lint/style/useDefaultParameterLast: <explanation> | ||
{ | ||
format = 'png', | ||
fontSize = undefined, | ||
silent = false, | ||
output = 'verbose', | ||
fromCli = false, | ||
file = false, | ||
} = {}, | ||
attributes, | ||
) { | ||
let nodeCanvas; | ||
try { | ||
// @ts-ignore | ||
nodeCanvas = require('canvas'); | ||
} catch (e) { | ||
throw new Error('Install "canvas" package to use `graph` command!'); | ||
} | ||
const showVerboseOutput = output !== 'verbose' || !fromCli || silent; | ||
@@ -39,3 +49,3 @@ | ||
* @param {string} text | ||
* @returns {ora.Ora} | ||
* @returns {import('nanospinner').Spinner} | ||
*/ | ||
@@ -46,4 +56,4 @@ function spin(text) { | ||
const mock = { | ||
succeed: () => {}, | ||
fail: () => {}, | ||
success: () => {}, | ||
error: () => {}, | ||
text: null, | ||
@@ -55,6 +65,6 @@ }; | ||
return ora(text).start(); | ||
return createSpinner(text).start(); | ||
} | ||
/** @type {ora.Ora} */ | ||
/** @type {import('nanospinner').Spinner} */ | ||
let spinner; | ||
@@ -66,26 +76,33 @@ | ||
spinner.succeed(); | ||
spinner.success(); | ||
spinner = spin(`Loading webapp items ${response.reduce((acc, webapp) => acc + webapp.touchpointData.items.length, 0)}`); | ||
spinner = spin( | ||
`Loading webapp items ${response.reduce( | ||
(acc, webapp) => acc + webapp.touchpointData.items.length, | ||
0, | ||
)}`, | ||
); | ||
const responseItems = await Promise.all(response.map((webapp) => ( | ||
webapp.touchpointData.items.map((item) => { | ||
if (/^ins_/.test(item.id)) { | ||
return getSubProduct(webapp.kaskoConfig, item) | ||
.then((itemData) => ({ | ||
const responseItems = await Promise.all( | ||
response | ||
.map((webapp) => | ||
webapp.touchpointData.items.map((item) => { | ||
if (/^ins_/.test(item.id)) { | ||
return getSubProduct(webapp.kaskoConfig, item).then((itemData) => ({ | ||
...webapp, | ||
itemData, | ||
})); | ||
} | ||
return getItem(webapp.kaskoConfig, item).then((itemData) => ({ | ||
...webapp, | ||
itemData, | ||
})); | ||
} | ||
}), | ||
) | ||
.flat(2), | ||
); | ||
return getItem(webapp.kaskoConfig, item) | ||
.then((itemData) => ({ | ||
...webapp, | ||
itemData, | ||
})); | ||
}) | ||
)).flat(2)); | ||
spinner.success(); | ||
spinner.succeed(); | ||
const results = []; | ||
@@ -95,3 +112,3 @@ for (const webapp of responseItems) { | ||
const canvas = createCanvas(0, 0, format === 'png' ? undefined : format); | ||
const canvas = nodeCanvas.createCanvas(0, 0, format === 'png' ? undefined : format); | ||
const data = build( | ||
@@ -110,3 +127,3 @@ canvas, | ||
spinner.succeed(); | ||
spinner.success(); | ||
@@ -122,3 +139,3 @@ if (output === 'json' && fromCli) { | ||
fs.writeFileSync(fileName, data); | ||
spinner.succeed(); | ||
spinner.success(); | ||
} | ||
@@ -131,1 +148,2 @@ } | ||
module.exports = graph; | ||
module.exports.readme = require('./readme.md'); |
@@ -1,7 +0,5 @@ | ||
const fs = require('fs'); | ||
const path = require('path'); | ||
const print = require('../../helpers/print'); | ||
const getDocs = require('../../helpers/get-docs'); | ||
const docs = global.ESBUILD ? require('../index?nocache') : require('../index'); | ||
const docs = getDocs(path.resolve(__dirname, '../../../src/commands')); | ||
const readme = require('./readme.md'); | ||
@@ -13,3 +11,2 @@ /** | ||
*/ | ||
// eslint-disable-next-line no-unused-vars | ||
function help(flags = {}, [originalCommand] = []) { | ||
@@ -22,3 +19,3 @@ let command = originalCommand; | ||
const docsContent = fs.readFileSync(docs[command], 'utf8'); | ||
const docsContent = docs[command]?.readme || readme; | ||
@@ -25,0 +22,0 @@ return print(docsContent); |
require('dotenv').config(); | ||
const ora = require('ora'); | ||
const { createSpinner } = require('nanospinner'); | ||
const get = require('./get-data'); | ||
@@ -9,2 +9,20 @@ const writeTouchpoint = require('./write-touchpoint'); | ||
/** | ||
* | ||
* @param {Promise<any>} promise | ||
* @param {string} text | ||
* @returns | ||
*/ | ||
function spinPromise(promise, text) { | ||
const spinner = createSpinner(text).start(); | ||
try { | ||
promise.then(() => spinner.success()).catch(() => spinner.error()); | ||
} catch (e) { | ||
spinner.error(); | ||
} | ||
return spinner; | ||
} | ||
async function download({ | ||
@@ -15,3 +33,3 @@ host = 'eu1.kaskocloud.com', | ||
language = process.env.WEBAPP_LANGUAGE, | ||
} = { }) { | ||
} = {}) { | ||
// Validate | ||
@@ -35,3 +53,3 @@ if (!key) { | ||
}); | ||
ora.promise(downloadTouchpointAction, 'Downloading Touchpoint'); | ||
spinPromise(downloadTouchpointAction, 'Downloading Touchpoint'); | ||
const touchpoint = await downloadTouchpointAction; | ||
@@ -41,18 +59,23 @@ | ||
const writeTouchpointAction = writeTouchpoint(touchpoint); | ||
ora.promise(writeTouchpointAction, 'Writing Touchpoint'); | ||
spinPromise(writeTouchpointAction, 'Writing Touchpoint'); | ||
await writeTouchpointAction; | ||
// Download and write all items (in parallel) | ||
await Promise.all(touchpoint.items.map(async ({ id: itemId }) => { | ||
const downloadItemAction = get(`https://feapi.${host}/touchpoints/${touchpointId}/items/${itemId}`, { | ||
language, | ||
key, | ||
}); | ||
ora.promise(downloadItemAction, `Downloading Item: ${itemId}`); | ||
const item = await downloadItemAction; | ||
await Promise.all( | ||
touchpoint.items.map(async ({ id: itemId }) => { | ||
const downloadItemAction = get( | ||
`https://feapi.${host}/touchpoints/${touchpointId}/items/${itemId}`, | ||
{ | ||
language, | ||
key, | ||
}, | ||
); | ||
spinPromise(downloadItemAction, `Downloading Item: ${itemId}`); | ||
const item = await downloadItemAction; | ||
const writeItemAction = writeItem(item); | ||
ora.promise(writeItemAction, `Writing Item: ${itemId}`); | ||
return writeItemAction; | ||
})); | ||
const writeItemAction = writeItem(item); | ||
spinPromise(writeItemAction, `Writing Item: ${itemId}`); | ||
return writeItemAction; | ||
}), | ||
); | ||
@@ -68,7 +91,10 @@ // Download and write all claims settings (in parallel) | ||
try { | ||
const downloadClaimAction = get(`https://feapi.${host}/touchpoints/${touchpointId}/items/${itemId}/claim_settings`, { | ||
language, | ||
key, | ||
}); | ||
ora.promise(downloadClaimAction, `Downloading Claims: ${itemId}`); | ||
const downloadClaimAction = get( | ||
`https://feapi.${host}/touchpoints/${touchpointId}/items/${itemId}/claim_settings`, | ||
{ | ||
language, | ||
key, | ||
}, | ||
); | ||
spinPromise(downloadClaimAction, `Downloading Claims: ${itemId}`); | ||
claim = await downloadClaimAction; | ||
@@ -85,3 +111,3 @@ } catch (e) { | ||
const writeClaimAction = writeClaims(itemId, claim); | ||
ora.promise(writeClaimAction, `Writing Claims: ${itemId}`); | ||
spinPromise(writeClaimAction, `Writing Claims: ${itemId}`); | ||
return writeClaimAction; | ||
@@ -88,0 +114,0 @@ }), |
@@ -10,5 +10,3 @@ const axios = require('../../axios'); | ||
} catch (e) { | ||
throw new Error( | ||
`${e.response.status} ${e.response.statusText}`, | ||
); | ||
throw new Error(`${e.response.status} ${e.response.statusText}`); | ||
} | ||
@@ -15,0 +13,0 @@ } |
@@ -26,1 +26,2 @@ const download = require('./download'); | ||
module.exports = run; | ||
module.exports.readme = require('./readme.md'); |
@@ -14,9 +14,16 @@ const fs = require('fs-extra'); | ||
const claim = { ...data }; | ||
claim.field_definition = { }; | ||
claim.manifest = { }; | ||
claim.content = { }; | ||
claim.field_definition = {}; | ||
claim.manifest = {}; | ||
claim.content = {}; | ||
promises.push(fs.writeFile(`${path}/claim.json`, `${JSON.stringify(claim, null, 2)}\n`)); | ||
promises.push(fs.writeFile(`${path}/manifest.json`, `${JSON.stringify(data.manifest, null, 2)}\n`)); | ||
promises.push(fs.writeFile(`${path}/field-definitions.json`, `${JSON.stringify(data.field_definition, null, 2)}\n`)); | ||
promises.push( | ||
fs.writeFile(`${path}/manifest.json`, `${JSON.stringify(data.manifest, null, 2)}\n`), | ||
); | ||
promises.push( | ||
fs.writeFile( | ||
`${path}/field-definitions.json`, | ||
`${JSON.stringify(data.field_definition, null, 2)}\n`, | ||
), | ||
); | ||
@@ -23,0 +30,0 @@ return Promise.all(promises); |
@@ -10,12 +10,26 @@ const fs = require('fs-extra'); | ||
const promises = []; | ||
promises.push(fs.writeFile(`mock-api/resources/${data.id}/contents.csv`, `${jsonToCsv(data.content.data)}\n`)); | ||
promises.push( | ||
fs.writeFile(`mock-api/resources/${data.id}/contents.csv`, `${jsonToCsv(data.content.data)}\n`), | ||
); | ||
const item = { ...data }; | ||
item.field_definition = { }; | ||
item.webapp_manifest = { }; | ||
item.content.data = { }; | ||
item.field_definition = {}; | ||
item.webapp_manifest = {}; | ||
item.content.data = {}; | ||
promises.push(fs.writeFile(`mock-api/resources/${data.id}/item.json`, `${JSON.stringify(item, null, 2)}\n`)); | ||
promises.push(fs.writeFile(`mock-api/resources/${data.id}/webapp-manifest.json`, `${JSON.stringify(data.webapp_manifest, null, 2)}\n`)); | ||
promises.push(fs.writeFile(`mock-api/resources/${data.id}/field-definitions.json`, `${JSON.stringify(data.field_definition, null, 2)}\n`)); | ||
promises.push( | ||
fs.writeFile(`mock-api/resources/${data.id}/item.json`, `${JSON.stringify(item, null, 2)}\n`), | ||
); | ||
promises.push( | ||
fs.writeFile( | ||
`mock-api/resources/${data.id}/webapp-manifest.json`, | ||
`${JSON.stringify(data.webapp_manifest, null, 2)}\n`, | ||
), | ||
); | ||
promises.push( | ||
fs.writeFile( | ||
`mock-api/resources/${data.id}/field-definitions.json`, | ||
`${JSON.stringify(data.field_definition, null, 2)}\n`, | ||
), | ||
); | ||
@@ -22,0 +36,0 @@ return Promise.all(promises); |
@@ -6,9 +6,18 @@ const fs = require('fs-extra'); | ||
const promises = []; | ||
promises.push(fs.writeFile('mock-api/resources/touchpoint-contents.csv', `${jsonToCsv(data.content.data)}\n`)); | ||
promises.push(fs.writeFile('mock-api/resources/touchpoint-webapp-manifest.json', `${JSON.stringify(data.webapp_manifest, null, 2)}\n`)); | ||
promises.push( | ||
fs.writeFile('mock-api/resources/touchpoint-contents.csv', `${jsonToCsv(data.content.data)}\n`), | ||
); | ||
promises.push( | ||
fs.writeFile( | ||
'mock-api/resources/touchpoint-webapp-manifest.json', | ||
`${JSON.stringify(data.webapp_manifest, null, 2)}\n`, | ||
), | ||
); | ||
const tp = { ...data }; | ||
tp.webapp_manifest = { }; | ||
tp.content.data = { }; | ||
promises.push(fs.writeFile('mock-api/resources/touchpoint.json', `${JSON.stringify(tp, null, 2)}\n`)); | ||
tp.webapp_manifest = {}; | ||
tp.content.data = {}; | ||
promises.push( | ||
fs.writeFile('mock-api/resources/touchpoint.json', `${JSON.stringify(tp, null, 2)}\n`), | ||
); | ||
@@ -15,0 +24,0 @@ return Promise.all(promises); |
const promiseChunks = require('../../utils/translations/promiseChunks'); | ||
const getItemManifest = require('./getItemManifest'); | ||
@@ -9,3 +10,3 @@ | ||
* @param {{batchSize: number, delayMs: number, spinner: Function}} options | ||
* @returns {Promise<{}>} | ||
* @returns {Promise<Record<string, *>[]>} | ||
*/ | ||
@@ -18,9 +19,10 @@ async function getAllItemManifests(url, params, items, options) { | ||
items, | ||
({ id }) => getItemManifest(url, params, id) | ||
// Middleware for checking if task finished or failed | ||
.then((data) => { | ||
itemsFinished += 1; | ||
spinner(`Getting item data [${itemsFinished}/${items.length}]`); | ||
return data; | ||
}), | ||
({ id }) => | ||
getItemManifest(url, params, id) | ||
// Middleware for checking if task finished or failed | ||
.then((data) => { | ||
itemsFinished += 1; | ||
spinner(`Getting item data [${itemsFinished}/${items.length}]`); | ||
return data; | ||
}), | ||
chunkOptions, | ||
@@ -27,0 +29,0 @@ ); |
@@ -1,2 +0,2 @@ | ||
const axios = require('../../axios'); | ||
const kaskoFetch = require('../../kasko-fetch'); | ||
@@ -7,9 +7,6 @@ /** | ||
* @param {string} item | ||
* @returns {Promise<{}>} | ||
* @returns {Promise<Record<string, *>>} | ||
*/ | ||
async function getItemManifest(url, params, item) { | ||
const { data } = await axios.get(`${url}/items/${item}`, { params }) | ||
.catch((error) => { | ||
throw error; | ||
}); | ||
const data = await kaskoFetch(`${url}/items/${item}`, { method: 'get' }, params); | ||
@@ -16,0 +13,0 @@ if (!data) { |
@@ -1,2 +0,2 @@ | ||
const axios = require('../../axios'); | ||
const kaskoFetch = require('../../kasko-fetch'); | ||
const extractPaths = require('../../utils/translations/extractPaths'); | ||
@@ -7,9 +7,8 @@ | ||
* @param {Object.<string, *>} params | ||
* @returns {Promise<{productName: string, touchpointTranslations: {}, items: []}>} | ||
* @returns {Promise<{productName: string, touchpointTranslations: Record<string, *>, items: [], webappManifest: Record<string, *>}>} | ||
*/ | ||
async function getTouchpointData(url, params) { | ||
const { data } = await axios.get(url, { params }) | ||
.catch((error) => { | ||
throw error; | ||
}); | ||
const data = await kaskoFetch(url, {}, params).catch((error) => { | ||
throw error; | ||
}); | ||
@@ -16,0 +15,0 @@ if (!data) { |
@@ -1,2 +0,2 @@ | ||
const ora = require('ora'); | ||
const { createSpinner } = require('nanospinner'); | ||
@@ -19,6 +19,3 @@ const getPartial = require('../../helpers/get-partial'); | ||
const leadTranslations = [ | ||
'flow.start.link', | ||
'flow.error_used_lead.title', | ||
]; | ||
const leadTranslations = ['flow.start.link', 'flow.error_used_lead.title']; | ||
@@ -32,4 +29,4 @@ const REQUEST_SPECIFIC_REQUIRED_TRANSLATIONS = { | ||
/** | ||
* @param {{}} flags | ||
* @param {string[]} attributes | ||
* @param {Record<string, any>} flags | ||
* @param {string[]=} attributes | ||
* @returns {Promise<Output>} | ||
@@ -51,3 +48,4 @@ */ | ||
if (typeof key === 'undefined') throw new Error('Translations: flag `key` must be defined.'); | ||
if (['verbose', 'json'].indexOf(output) < 0) throw new Error('Translations: flag `output` supports only "verbose" and "json".'); | ||
if (['verbose', 'json'].indexOf(output) < 0) | ||
throw new Error('Translations: flag `output` supports only "verbose" and "json".'); | ||
@@ -60,4 +58,4 @@ const showVerboseOutput = output !== 'verbose' || !fromCli || silent; | ||
return { | ||
succeed: () => {}, | ||
fail: () => {}, | ||
success: () => {}, | ||
error: () => {}, | ||
text: null, | ||
@@ -67,3 +65,3 @@ }; | ||
return ora(text).start(); | ||
return createSpinner(text).start(); | ||
} | ||
@@ -78,14 +76,11 @@ | ||
const { | ||
productName, | ||
touchpointTranslations, | ||
items, | ||
webappManifest, | ||
} = await getTouchpointData(url, requestParams) | ||
.catch((error) => { | ||
spinner.fail(); | ||
throw error; | ||
}); | ||
const { productName, touchpointTranslations, items, webappManifest } = await getTouchpointData( | ||
url, | ||
requestParams, | ||
).catch((error) => { | ||
spinner.error(); | ||
throw error; | ||
}); | ||
spinner.succeed(); | ||
spinner.success(); | ||
spinner = spin(`Getting item data [0/${items.length}]`); | ||
@@ -98,3 +93,3 @@ | ||
if (value === false) { | ||
spinner.fail(); | ||
spinner.error(); | ||
return; | ||
@@ -105,83 +100,74 @@ } | ||
}, | ||
}) | ||
.catch((error) => { | ||
spinner.fail(); | ||
throw error; | ||
}); | ||
}).catch((error) => { | ||
spinner.error(); | ||
throw error; | ||
}); | ||
spinner.succeed(); | ||
spinner.success(); | ||
spinner = spin('Preparing data'); | ||
const itemList = itemManifests.reduce( | ||
(acc, item) => { | ||
const activeRequests = (((item.webapp_manifest.schema || {}).config || {}).requests || []); | ||
const requestSpecificTranslations = activeRequests.map(({ type }) => type).reduce( | ||
(requestAcc, requestName) => { | ||
const keys = REQUEST_SPECIFIC_REQUIRED_TRANSLATIONS[requestName]; | ||
if (!keys) return requestAcc; | ||
const itemList = itemManifests.reduce((acc, item) => { | ||
const activeRequests = item.webapp_manifest.schema?.config?.requests || []; | ||
const requestSpecificTranslations = activeRequests | ||
.map(({ type }) => type) | ||
.reduce((requestAcc, requestName) => { | ||
const keys = REQUEST_SPECIFIC_REQUIRED_TRANSLATIONS[requestName]; | ||
if (!keys) return requestAcc; | ||
return requestAcc.concat(keys); | ||
}, | ||
[], | ||
); | ||
const existingItemTranslations = extractPaths(item.content.data); | ||
const fieldDefinitions = extractFieldDefinitions(item.field_definition) | ||
.concat(...activeRequests.map(extractFieldDefinitions)); | ||
const itemAndTouchpointTranslations = touchpointTranslations | ||
.concat( | ||
existingItemTranslations.filter((itemKey) => touchpointTranslations.indexOf(itemKey) < 0), | ||
); | ||
const usedTranslations = [...new Set( | ||
return requestAcc.concat(keys); | ||
}, []); | ||
const existingItemTranslations = extractPaths(item.content.data); | ||
const fieldDefinitions = extractFieldDefinitions(item.field_definition).concat( | ||
...activeRequests.map(extractFieldDefinitions), | ||
); | ||
const itemAndTouchpointTranslations = touchpointTranslations.concat( | ||
existingItemTranslations.filter((itemKey) => touchpointTranslations.indexOf(itemKey) < 0), | ||
); | ||
const usedTranslations = [ | ||
...new Set( | ||
extractContentKeys(item.webapp_manifest) | ||
.concat( | ||
extractContentKeys(webappManifest), | ||
) | ||
.concat(extractContentKeys(webappManifest)) | ||
.concat(requiredDefaults) | ||
.concat(requestSpecificTranslations) | ||
.concat(fieldDefinitions), | ||
)]; | ||
const { | ||
missingTranslations, | ||
idleTranslations, | ||
} = usedTranslations | ||
.reduce( | ||
(itemAcc, itemKey) => { | ||
const value = getPartial(itemKey.split('.'), item.content.data); | ||
), | ||
]; | ||
const { missingTranslations, idleTranslations } = usedTranslations.reduce( | ||
(itemAcc, itemKey) => { | ||
const value = getPartial(itemKey.split('.'), item.content.data); | ||
if (itemKey === value || value === '') { | ||
return { | ||
...itemAcc, | ||
idleTranslations: itemAcc.idleTranslations.concat(itemKey), | ||
}; | ||
} | ||
if (itemKey === value || value === '') { | ||
return { | ||
...itemAcc, | ||
idleTranslations: itemAcc.idleTranslations.concat(itemKey), | ||
}; | ||
} | ||
if (itemAndTouchpointTranslations.indexOf(itemKey) < 0) { | ||
return { | ||
...itemAcc, | ||
missingTranslations: itemAcc.missingTranslations.concat(itemKey), | ||
}; | ||
} | ||
if (itemAndTouchpointTranslations.indexOf(itemKey) < 0) { | ||
return { | ||
...itemAcc, | ||
missingTranslations: itemAcc.missingTranslations.concat(itemKey), | ||
}; | ||
} | ||
return itemAcc; | ||
}, | ||
{ | ||
missingTranslations: [], | ||
idleTranslations: [], | ||
}, | ||
); | ||
return itemAcc; | ||
}, | ||
{ | ||
missingTranslations: [], | ||
idleTranslations: [], | ||
}, | ||
); | ||
return { | ||
...acc, | ||
[item.id]: { | ||
contentId: item.content.id, | ||
missingTranslations, | ||
idleTranslations, | ||
usedTranslations, | ||
fieldDefinitions, | ||
existingTranslations: itemAndTouchpointTranslations, | ||
}, | ||
}; | ||
}, | ||
{}, | ||
); | ||
return { | ||
...acc, | ||
[item.id]: { | ||
contentId: item.content.id, | ||
missingTranslations, | ||
idleTranslations, | ||
usedTranslations, | ||
fieldDefinitions, | ||
existingTranslations: itemAndTouchpointTranslations, | ||
}, | ||
}; | ||
}, {}); | ||
@@ -205,3 +191,3 @@ const summaryTemplate = { | ||
spinner.succeed(); | ||
spinner.success(); | ||
@@ -261,2 +247,3 @@ print(); | ||
module.exports = translations; | ||
module.exports.readme = require('./readme.md'); | ||
@@ -263,0 +250,0 @@ /** |
const getopts = require('getopts'); | ||
const alias = require('../alias'); | ||
@@ -11,14 +12,7 @@ | ||
}); | ||
const [ | ||
firstCommand, | ||
...restOfCommands | ||
] = _; | ||
const [firstCommand, ...restOfCommands] = _; | ||
return [ | ||
firstCommand || 'default', | ||
options, | ||
restOfCommands || [], | ||
]; | ||
return [firstCommand || 'default', options, restOfCommands || []]; | ||
} | ||
module.exports = extractCommand; |
@@ -8,7 +8,3 @@ /** | ||
if (source && typeof source === 'object') { | ||
return Object.values(source) | ||
.reduce( | ||
(acc, value) => acc.concat(getDeepValues(value, true)), | ||
[], | ||
); | ||
return Object.values(source).reduce((acc, value) => acc.concat(getDeepValues(value, true)), []); | ||
} | ||
@@ -15,0 +11,0 @@ |
@@ -7,8 +7,5 @@ /** | ||
function getPartial(path, source) { | ||
return path.reduce( | ||
(previous, key) => (previous ? previous[key] : undefined), | ||
source, | ||
); | ||
return path.reduce((previous, key) => (previous ? previous[key] : undefined), source); | ||
} | ||
module.exports = getPartial; |
@@ -1,10 +0,3 @@ | ||
const marked = require('marked'); | ||
const TerminalRenderer = require('marked-terminal'); | ||
const terminalMarkdown = require('../utils/terminal-markdown'); | ||
marked.setOptions({ | ||
renderer: new TerminalRenderer({ | ||
showSectionPrefix: false, | ||
}), | ||
}); | ||
let silent = false; | ||
@@ -17,7 +10,6 @@ | ||
function print(...content) { | ||
const output = marked(content.join(' ')).trim(); | ||
const output = terminalMarkdown(content.join(' ')).trim(); | ||
/* Print content to screen */ | ||
if (!silent) { | ||
// eslint-disable-next-line no-console | ||
console.log(output); | ||
@@ -24,0 +16,0 @@ } |
@@ -9,4 +9,4 @@ /** | ||
const lengthB = nameB.length; | ||
const minLength = (lengthA > lengthB) ? lengthB : lengthA; | ||
const maxLength = (lengthA < lengthB) ? lengthB : lengthA; | ||
const minLength = lengthA > lengthB ? lengthB : lengthA; | ||
const maxLength = lengthA < lengthB ? lengthB : lengthA; | ||
let equivalency = 0; | ||
@@ -13,0 +13,0 @@ |
#! /usr/bin/env node | ||
const colors = require('picocolors'); | ||
const app = require('./app'); | ||
@@ -9,14 +11,24 @@ const extractCommand = require('./helpers/extract-command'); | ||
if (typeof command === 'function') { | ||
try { | ||
command({ | ||
...options, | ||
fromCli: true, | ||
}, restOfCommands); | ||
} catch (e) { | ||
console.error(e); | ||
process.exit(1); | ||
(async () => { | ||
if (typeof command === 'function') { | ||
try { | ||
await command( | ||
{ | ||
...options, | ||
fromCli: true, | ||
}, | ||
restOfCommands, | ||
); | ||
} catch (e) { | ||
console.log( | ||
'\n ', | ||
colors.bgRed(' Error '), | ||
colors.red(e.toString().replace(/^Error: /, '')), | ||
'\n', | ||
); | ||
process.exit(1); | ||
} | ||
} else { | ||
app.notFound({ name: commandName }); | ||
} | ||
} else { | ||
app.notFound({ name: commandName }); | ||
} | ||
})(); |
@@ -17,26 +17,28 @@ const getDeepValues = require('../../helpers/get-deep-values'); | ||
if (value.content_key && typeof value.content_key === 'object') { | ||
return Object.values(value.content_key) | ||
/** | ||
* Need to support deeply nested `content_key` structures: | ||
* | ||
* ```json | ||
* { | ||
* "content_key": { | ||
* "label": "form.last_name.label" | ||
* } | ||
* } | ||
* ``` | ||
* as well as this: | ||
* ```json | ||
* { | ||
* "content_key": { | ||
* "last_name": { | ||
* "label": "form.last_name.label" | ||
* } | ||
* } | ||
* } | ||
* ``` | ||
*/ | ||
.reduce((acc, subValue) => acc.concat(getDeepValues(subValue, true)), []) | ||
.filter((subValue) => !!subValue); | ||
return ( | ||
Object.values(value.content_key) | ||
/** | ||
* Need to support deeply nested `content_key` structures: | ||
* | ||
* ```json | ||
* { | ||
* "content_key": { | ||
* "label": "form.last_name.label" | ||
* } | ||
* } | ||
* ``` | ||
* as well as this: | ||
* ```json | ||
* { | ||
* "content_key": { | ||
* "last_name": { | ||
* "label": "form.last_name.label" | ||
* } | ||
* } | ||
* } | ||
* ``` | ||
*/ | ||
.reduce((acc, subValue) => acc.concat(getDeepValues(subValue, true)), []) | ||
.filter((subValue) => !!subValue) | ||
); | ||
} | ||
@@ -59,6 +61,3 @@ | ||
Object.keys(value).forEach((key) => { | ||
output = [ | ||
...output, | ||
...extractContentKeys(value[key]), | ||
]; | ||
output = [...output, ...extractContentKeys(value[key])]; | ||
}); | ||
@@ -65,0 +64,0 @@ |
@@ -9,12 +9,9 @@ /** | ||
return rules.split('|').reduce( | ||
(acc, ruleChunk) => { | ||
const rule = ruleChunk.replace(/:.*/, ''); | ||
return rules.split('|').reduce((acc, ruleChunk) => { | ||
const rule = ruleChunk.replace(/:.*/, ''); | ||
if (rule === '' || /^(string|integer|boolean)$/.test(rule)) return acc; | ||
if (rule === '' || /^(string|integer|boolean)$/.test(rule)) return acc; | ||
return [...acc, `form.${name}.errors.${rule}`]; | ||
}, | ||
[], | ||
); | ||
return [...acc, `form.${name}.errors.${rule}`]; | ||
}, []); | ||
} | ||
@@ -21,0 +18,0 @@ |
@@ -11,27 +11,20 @@ /** | ||
const keys = Object.keys(object); | ||
const results = keys.reduce( | ||
(res, key) => { | ||
const path = root.concat(key); | ||
const results = keys.reduce((res, key) => { | ||
const path = root.concat(key); | ||
/* Ensure that empty value is missing translation */ | ||
if (object[key] === '') return res; | ||
/* Ensure that empty value is missing translation */ | ||
if (object[key] === '') return res; | ||
if (typeof object[key] === 'object' && object[key] !== null) { | ||
extractPaths(object[key], path, res); | ||
} else | ||
if (Array.isArray(res[object[key]])) { | ||
res[object[key]].push(path); | ||
} else { | ||
res[object[key]] = [path]; | ||
} | ||
if (typeof object[key] === 'object' && object[key] !== null) { | ||
extractPaths(object[key], path, res); | ||
} else if (Array.isArray(res[object[key]])) { | ||
res[object[key]].push(path); | ||
} else { | ||
res[object[key]] = [path]; | ||
} | ||
return res; | ||
}, | ||
result, | ||
); | ||
return res; | ||
}, result); | ||
const merged = Object.keys(results).reduce( | ||
(acc, key) => [...acc, ...results[key]], | ||
[], | ||
); | ||
const merged = Object.keys(results).reduce((acc, key) => [...acc, ...results[key]], []); | ||
@@ -38,0 +31,0 @@ return merged.map((data) => data.join('.')); |
@@ -27,13 +27,18 @@ /** | ||
return chunkedData.reduce( | ||
(chain, batch) => ( | ||
(chain, batch) => | ||
chain | ||
.then((accumulatedData) => Promise.all(batch.map(mapper)) | ||
.then((newData) => (accumulatedData && typeof accumulatedData.length !== 'undefined' | ||
? [...accumulatedData, ...newData] | ||
: newData))) | ||
.then((accumulatedData) => | ||
Promise.all(batch.map(mapper)).then((newData) => | ||
accumulatedData && typeof accumulatedData.length !== 'undefined' | ||
? [...accumulatedData, ...newData] | ||
: newData, | ||
), | ||
) | ||
// Adds timeout between request chunks | ||
.then((data) => new Promise((resolve) => { | ||
setTimeout(resolve, dataArray.length > batchSize ? delayMs : 0, data); | ||
})) | ||
), | ||
.then( | ||
(data) => | ||
new Promise((resolve) => { | ||
setTimeout(resolve, dataArray.length > batchSize ? delayMs : 0, data); | ||
}), | ||
), | ||
Promise.resolve(), | ||
@@ -40,0 +45,0 @@ ); |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
Major refactor
Supply chain riskPackage has recently undergone a major refactor. It may be unstable or indicate significant internal changes. Use caution when updating to versions that include significant changes.
Found 1 instance in 1 package
Network access
Supply chain riskThis module accesses the network.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
7005149
0
72
66980
17
17
6
- Removedarchiver@^3.1.1
- Removedaxios@^0.19.0
- Removedcanvas@^2.10.1
- Removeddotenv@^8.1.0
- Removedexpress@^4.17.1
- Removedflat@^5.0.1
- Removedform-data@^2.5.1
- Removedfs-extra@^8.1.0
- Removedgetopts@^2.2.3
- Removedjs-yaml@^3.13.1
- Removedmarked@^0.7.0
- Removedmarked-terminal@^3.3.0
- Removedora@^3.0.0
- Removed@kasko/webapp-flow-visualizer-lib@1.1.1(transitive)
- Removed@mapbox/node-pre-gyp@1.0.11(transitive)
- Removedabbrev@1.1.1(transitive)
- Removedaccepts@1.3.8(transitive)
- Removedagent-base@6.0.2(transitive)
- Removedansi-escapes@3.2.0(transitive)
- Removedansi-regex@4.1.15.0.1(transitive)
- Removedansi-styles@3.2.1(transitive)
- Removedansicolors@0.3.2(transitive)
- Removedaproba@2.0.0(transitive)
- Removedarchiver@3.1.1(transitive)
- Removedarchiver-utils@2.1.0(transitive)
- Removedare-we-there-yet@2.0.0(transitive)
- Removedargparse@1.0.10(transitive)
- Removedarray-flatten@1.1.1(transitive)
- Removedasync@2.6.4(transitive)
- Removedasynckit@0.4.0(transitive)
- Removedaxios@0.19.2(transitive)
- Removedbalanced-match@1.0.2(transitive)
- Removedbase64-js@1.5.1(transitive)
- Removedbl@4.1.0(transitive)
- Removedbody-parser@1.20.3(transitive)
- Removedbrace-expansion@1.1.11(transitive)
- Removedbuffer@5.7.1(transitive)
- Removedbuffer-crc32@0.2.13(transitive)
- Removedbytes@3.1.2(transitive)
- Removedcall-bind@1.0.7(transitive)
- Removedcanvas@2.11.2(transitive)
- Removedcardinal@2.1.1(transitive)
- Removedchalk@2.4.2(transitive)
- Removedchownr@2.0.0(transitive)
- Removedcli-cursor@2.1.0(transitive)
- Removedcli-spinners@2.9.2(transitive)
- Removedcli-table@0.3.11(transitive)
- Removedclone@1.0.4(transitive)
- Removedcolor-convert@1.9.3(transitive)
- Removedcolor-name@1.1.3(transitive)
- Removedcolor-support@1.1.3(transitive)
- Removedcolors@1.0.3(transitive)
- Removedcombined-stream@1.0.8(transitive)
- Removedcompress-commons@2.1.1(transitive)
- Removedconcat-map@0.0.1(transitive)
- Removedconsole-control-strings@1.1.0(transitive)
- Removedcontent-disposition@0.5.4(transitive)
- Removedcontent-type@1.0.5(transitive)
- Removedcookie@0.7.1(transitive)
- Removedcookie-signature@1.0.6(transitive)
- Removedcore-util-is@1.0.3(transitive)
- Removedcrc@3.8.0(transitive)
- Removedcrc32-stream@3.0.1(transitive)
- Removeddebug@2.6.94.3.7(transitive)
- Removeddecompress-response@4.2.1(transitive)
- Removeddeepmerge@4.3.1(transitive)
- Removeddefaults@1.0.4(transitive)
- Removeddefine-data-property@1.1.4(transitive)
- Removeddelayed-stream@1.0.0(transitive)
- Removeddelegates@1.0.0(transitive)
- Removeddepd@2.0.0(transitive)
- Removeddestroy@1.2.0(transitive)
- Removeddetect-libc@2.0.3(transitive)
- Removeddotenv@8.6.0(transitive)
- Removedee-first@1.1.1(transitive)
- Removedemoji-regex@8.0.0(transitive)
- Removedencodeurl@1.0.22.0.0(transitive)
- Removedend-of-stream@1.4.4(transitive)
- Removedes-define-property@1.0.0(transitive)
- Removedes-errors@1.3.0(transitive)
- Removedescape-html@1.0.3(transitive)
- Removedescape-string-regexp@1.0.5(transitive)
- Removedesprima@4.0.1(transitive)
- Removedetag@1.8.1(transitive)
- Removedexpress@4.21.1(transitive)
- Removedfinalhandler@1.3.1(transitive)
- Removedflat@5.0.2(transitive)
- Removedflattie@1.1.1(transitive)
- Removedfollow-redirects@1.5.10(transitive)
- Removedform-data@2.5.2(transitive)
- Removedforwarded@0.2.0(transitive)
- Removedfresh@0.5.2(transitive)
- Removedfs-constants@1.0.0(transitive)
- Removedfs-extra@8.1.0(transitive)
- Removedfs-minipass@2.1.0(transitive)
- Removedfs.realpath@1.0.0(transitive)
- Removedfunction-bind@1.1.2(transitive)
- Removedgauge@3.0.2(transitive)
- Removedget-intrinsic@1.2.4(transitive)
- Removedgetopts@2.3.0(transitive)
- Removedglob@7.2.3(transitive)
- Removedgopd@1.0.1(transitive)
- Removedgraceful-fs@4.2.11(transitive)
- Removedgraphre@0.1.3(transitive)
- Removedhas-flag@2.0.03.0.0(transitive)
- Removedhas-property-descriptors@1.0.2(transitive)
- Removedhas-proto@1.0.3(transitive)
- Removedhas-symbols@1.0.3(transitive)
- Removedhas-unicode@2.0.1(transitive)
- Removedhasown@2.0.2(transitive)
- Removedhttp-errors@2.0.0(transitive)
- Removedhttps-proxy-agent@5.0.1(transitive)
- Removediconv-lite@0.4.24(transitive)
- Removedieee754@1.2.1(transitive)
- Removedinflight@1.0.6(transitive)
- Removedinherits@2.0.4(transitive)
- Removedipaddr.js@1.9.1(transitive)
- Removedis-fullwidth-code-point@3.0.0(transitive)
- Removedisarray@1.0.0(transitive)
- Removedjs-yaml@3.14.1(transitive)
- Removedjsonfile@4.0.0(transitive)
- Removedlazystream@1.0.1(transitive)
- Removedlodash@4.17.21(transitive)
- Removedlodash.defaults@4.2.0(transitive)
- Removedlodash.difference@4.5.0(transitive)
- Removedlodash.flatten@4.4.0(transitive)
- Removedlodash.isplainobject@4.0.6(transitive)
- Removedlodash.union@4.6.0(transitive)
- Removedlog-symbols@2.2.0(transitive)
- Removedmake-dir@3.1.0(transitive)
- Removedmarked@0.7.0(transitive)
- Removedmarked-terminal@3.3.0(transitive)
- Removedmedia-typer@0.3.0(transitive)
- Removedmerge-descriptors@1.0.3(transitive)
- Removedmethods@1.1.2(transitive)
- Removedmime@1.6.0(transitive)
- Removedmime-db@1.52.0(transitive)
- Removedmime-types@2.1.35(transitive)
- Removedmimic-fn@1.2.0(transitive)
- Removedmimic-response@2.1.0(transitive)
- Removedminimatch@3.1.2(transitive)
- Removedminipass@3.3.65.0.0(transitive)
- Removedminizlib@2.1.2(transitive)
- Removedmkdirp@1.0.4(transitive)
- Removedms@2.0.02.1.3(transitive)
- Removednan@2.22.0(transitive)
- Removednegotiator@0.6.3(transitive)
- Removednode-emoji@1.11.0(transitive)
- Removednode-fetch@2.7.0(transitive)
- Removednomnoml-es@1.5.4(transitive)
- Removednopt@5.0.0(transitive)
- Removednormalize-path@3.0.0(transitive)
- Removednpmlog@5.0.1(transitive)
- Removedobject-assign@4.1.1(transitive)
- Removedobject-inspect@1.13.3(transitive)
- Removedon-finished@2.4.1(transitive)
- Removedonce@1.4.0(transitive)
- Removedonetime@2.0.1(transitive)
- Removedora@3.4.0(transitive)
- Removedparseurl@1.3.3(transitive)
- Removedpath-is-absolute@1.0.1(transitive)
- Removedpath-to-regexp@0.1.10(transitive)
- Removedprocess-nextick-args@2.0.1(transitive)
- Removedproxy-addr@2.0.7(transitive)
- Removedqs@6.13.0(transitive)
- Removedrange-parser@1.2.1(transitive)
- Removedraw-body@2.5.2(transitive)
- Removedreadable-stream@2.3.83.6.2(transitive)
- Removedredeyed@2.1.1(transitive)
- Removedrestore-cursor@2.0.0(transitive)
- Removedrimraf@3.0.2(transitive)
- Removedsafe-buffer@5.1.25.2.1(transitive)
- Removedsafer-buffer@2.1.2(transitive)
- Removedsemver@6.3.17.6.3(transitive)
- Removedsend@0.19.0(transitive)
- Removedserve-static@1.16.2(transitive)
- Removedset-blocking@2.0.0(transitive)
- Removedset-function-length@1.2.2(transitive)
- Removedsetprototypeof@1.2.0(transitive)
- Removedside-channel@1.0.6(transitive)
- Removedsignal-exit@3.0.7(transitive)
- Removedsimple-concat@1.0.1(transitive)
- Removedsimple-get@3.1.1(transitive)
- Removedsprintf-js@1.0.3(transitive)
- Removedstatuses@2.0.1(transitive)
- Removedstring-width@4.2.3(transitive)
- Removedstring_decoder@1.1.1(transitive)
- Removedstrip-ansi@5.2.06.0.1(transitive)
- Removedsupports-color@5.5.0(transitive)
- Removedsupports-hyperlinks@1.0.1(transitive)
- Removedtar@6.2.1(transitive)
- Removedtar-stream@2.2.0(transitive)
- Removedtoidentifier@1.0.1(transitive)
- Removedtr46@0.0.3(transitive)
- Removedtype-is@1.6.18(transitive)
- Removeduniversalify@0.1.2(transitive)
- Removedunpipe@1.0.0(transitive)
- Removedutil-deprecate@1.0.2(transitive)
- Removedutils-merge@1.0.1(transitive)
- Removedvary@1.1.2(transitive)
- Removedwcwidth@1.0.1(transitive)
- Removedwebidl-conversions@3.0.1(transitive)
- Removedwhatwg-url@5.0.0(transitive)
- Removedwide-align@1.1.5(transitive)
- Removedwrappy@1.0.2(transitive)
- Removedyallist@4.0.0(transitive)
- Removedzip-stream@2.1.3(transitive)