@telus/digital
Advanced tools
Comparing version
{ | ||
"name": "@telus/digital", | ||
"version": "1.1.0", | ||
"version": "2.0.0", | ||
"description": "Telus digital provides you, as a developer, of what you need to succeed", | ||
@@ -5,0 +5,0 @@ "keywords": [ |
@@ -8,5 +8,10 @@ const { isEmpty } = require('lodash') | ||
const simpleGit = require('simple-git') | ||
const filters = require('../utils/filters') | ||
const GitHub = require('../create_project/github') | ||
const ini = require('../ini') | ||
const { commonQs, processAnswers } = require('../create_project/questions/') | ||
const { | ||
commonQs, | ||
processAnswers, | ||
generateQuestionsfromTemplate | ||
} = require('../create_project/questions/') | ||
@@ -18,3 +23,2 @@ const { log, error } = console | ||
createDirectory, | ||
generateQuestions, | ||
fetchTemplate, | ||
@@ -25,4 +29,8 @@ prepareDepsInstallation, | ||
const ProjectTypes = require('../create_project/types') | ||
const projectObjs = require('../create_project/types') | ||
const projectTypes = projectObjs.reduce((prev, current) => { | ||
return { ...prev, ...{ [current.type]: current.value } } | ||
}, {}) | ||
module.exports = { | ||
@@ -40,3 +48,3 @@ command: 'create <name>', | ||
type: 'string', | ||
describe: `Type of the project can be ${Object.values(ProjectTypes).join(', ')}` | ||
describe: `Type of the project can be ${Object.values(projectTypes).join(', ')}` | ||
}) | ||
@@ -58,9 +66,11 @@ }, | ||
const { type, name } = argv | ||
assert(type, 'Must include type of project') | ||
assert(name, 'Must include name of project') | ||
assert( | ||
Object.keys(ProjectTypes).includes(argv.type.toLowerCase()), | ||
`Type of project should be one of ${Object.keys(ProjectTypes).join(', ')}` | ||
) | ||
if (type) { | ||
assert( | ||
Object.keys(projectTypes).includes(type.toLowerCase()), | ||
`Type of project should be one of ${Object.keys(projectTypes).join(', ')}` | ||
) | ||
} | ||
try { | ||
@@ -76,18 +86,53 @@ // Creates a directory, validates name and returns the project absolute path. | ||
// Ask project (npm and colophon) related questions | ||
spinner.stopAndPersist({ text: `Fetching template ${type} `, symbol: '📖' }) | ||
const { templatePath, templateLibs } = await fetchTemplate(projectRoot, ProjectTypes[type]) | ||
spinner.info('Template fetched and configured.') | ||
const { authedClient } = await GitHub.client(config.github.token) | ||
const user = await GitHub.getUserInfo(authedClient) | ||
const teamsResponse = await GitHub.getTeamsList(authedClient) | ||
const teams = teamsResponse.data | ||
const answers = await generateQuestions(commonQs(name, teams), templateLibs.questions) | ||
answers.user = user | ||
answers.team = teams.find((t) => t.name === answers.team) | ||
const projectAnswers = processAnswers(answers) | ||
const userResponse = await GitHub.getUserInfo(authedClient) | ||
const user = userResponse.data | ||
/** | ||
* Creating answers object to reuse in templates | ||
*/ | ||
const answers = { project: {}, template: {}, user, team: {} } | ||
const project = await commonQs({ teams, name, type }) | ||
answers.project = processAnswers(project) | ||
const projectTemplate = type ? projectTypes[type] : answers.project.type | ||
const { templatePath, templateLibs } = await fetchTemplate(projectRoot, projectTemplate) | ||
// Ask project (npm and colophon) related questions | ||
spinner.stopAndPersist({ | ||
text: `Fetching template for ${ | ||
projectObjs.find((p) => Object.values(p).includes(projectTemplate)).name | ||
} `, | ||
symbol: '📖' | ||
}) | ||
spinner.info('Template fetched and configured.') | ||
answers.template = await generateQuestionsfromTemplate(templateLibs.questions) | ||
answers.team = teams.find((t) => t.name === answers.project.team) | ||
/** | ||
* if user response data comes back with good info then | ||
* we need to process it and add it to the answers object, | ||
* for usage later as answers.user | ||
*/ | ||
if (answers.user) { | ||
answers.user.email = filters.getValidEmail([ | ||
...answers.user.emails, | ||
{ email: answers.user.email || '', default: true } | ||
]) | ||
} | ||
/** | ||
* as of this point the answers object has specific project | ||
* answer information under the `project` key | ||
* template custom information under the `template` key | ||
* github user information under the `user` key | ||
* All this keys and info are accessible in any template | ||
* simply by accessing the keys of the answers object | ||
*/ | ||
/** | ||
* Make Git an entire set of functions that creates a repo `simple git` | ||
@@ -97,3 +142,3 @@ * and then pushes stuff to github | ||
await copyFiles(templatePath, projectRoot, projectAnswers) | ||
await copyFiles(templatePath, projectRoot, answers) | ||
@@ -103,5 +148,5 @@ // create github repo | ||
authedClient, | ||
projectAnswers.private, | ||
projectAnswers.name, | ||
projectAnswers.description | ||
answers.project.private, | ||
answers.project.name, | ||
answers.project.description | ||
) | ||
@@ -129,3 +174,3 @@ | ||
.commit('chore: initial scaffold commit') | ||
.addRemote('origin', `git@github.com:telus/${projectAnswers.key}.git`) | ||
.addRemote('origin', `git@github.com:telus/${answers.project.name}.git`) | ||
.push(['-u', 'origin', 'master'], () => { | ||
@@ -132,0 +177,0 @@ spinner.succeed('Start hacking! 🥳 🙌 🎉 ') |
const { setGithubConfig } = require('./config') | ||
const handleSaml = require('./handleSaml') | ||
const handleSaml = require('./handle-saml') | ||
/** | ||
* Get teams list from github | ||
* @param {Object} authedClient - Authenticated instance of octokit client | ||
* @returns {Promise<Teams[]>} | ||
*/ | ||
const getTeamsList = async (authedClient) => { | ||
@@ -28,2 +33,24 @@ let page = 1 | ||
/** | ||
* Get authenticated user information | ||
* We get this in order to set up basic information for | ||
* colophon, and other appropiate project information | ||
* | ||
* @param {Object} authedClient - Authenticated instance of octokit client | ||
* @returns {Promise<AuthUser>} | ||
*/ | ||
const getUserInfo = async (authedClient) => { | ||
try { | ||
const { data } = await authedClient.users.getAuthenticated() | ||
const userEmailsResponse = await authedClient.users.listEmails() | ||
data.emails = userEmailsResponse.data | ||
return { data } | ||
} catch (err) { | ||
/** | ||
* Deal with the error on your caller 😎 | ||
*/ | ||
throw err | ||
} | ||
} | ||
module.exports = { | ||
@@ -33,29 +60,4 @@ setGithubConfig, | ||
newRepository: require('./repository'), | ||
/** | ||
* Get authenticated user information | ||
* We get this in order to set up basic information for | ||
* colophon, and other appropiate project information | ||
* | ||
* @param {Object} authedClient - Authenticated instance of octokit client | ||
* @returns {Promise<AuthUser>} | ||
*/ | ||
getUserInfo: async (authedClient) => { | ||
try { | ||
const { data } = await authedClient.users.getAuthenticated() | ||
const userEmailsResponse = await authedClient.users.listEmails() | ||
data.emails = userEmailsResponse.data | ||
return data | ||
} catch (err) { | ||
/** | ||
* Deal with the error on your caller 😎 | ||
*/ | ||
throw err | ||
} | ||
}, | ||
/** | ||
* Get teams list from github | ||
* @param {Object} authedClient - Authenticated instance of octokit client | ||
* @returns {Promise<Teams[]>} | ||
*/ | ||
getUserInfo, | ||
getTeamsList | ||
} |
/* eslint no-console: 0 */ | ||
const handleSaml = require('./handleSaml') | ||
const handleSaml = require('./handle-saml') | ||
@@ -5,0 +5,0 @@ /** |
@@ -6,3 +6,2 @@ const { ensureDir, writeFile, exists, mkdirp, readFile, remove } = require('fs-extra') | ||
const chalk = require('chalk') | ||
const inquirer = require('inquirer') | ||
const glob = require('fast-glob') | ||
@@ -113,29 +112,2 @@ const njk = require('nunjucks') | ||
* | ||
* We use inquirer.js to generate questions. | ||
* A question in it's basic form consists of: | ||
* @typedef {Object} Question | ||
* @property {string} type - Defaults to input. Possible values: input, number, confirm, list, rawlist, expand, checkbox, password, editor | ||
* @property {string} name - Name to use when storing the answer in the answers hash | ||
* @property {string|function} message - The question to print. | ||
* @property {string|number|boolean|Array|function} default - The year | ||
* @property {function} filter - The year | ||
* @property {Array|function} choices - The year | ||
* @property {function} validate | ||
* | ||
* You can see more information about questions here https://github.com/SBoudrias/Inquirer.js/#objects | ||
*/ | ||
/** | ||
* | ||
* @param {Question[]} commonQs | ||
* @param {Question[]} templateQs | ||
*/ | ||
const generateQuestions = async (commonQs, templateQs = []) => { | ||
assert(commonQs.length > 0, 'At least 1 question is required') | ||
const questions = [...commonQs, ...templateQs] | ||
return inquirer.prompt(questions) | ||
} | ||
/** | ||
* | ||
* @param {string} src - Source folder of template project files | ||
@@ -246,5 +218,4 @@ * @param {string} destination - Destination folder for project files | ||
createDirectory, | ||
generateQuestions, | ||
fetchTemplate, | ||
copyFiles | ||
} |
const _ = require('lodash') | ||
const inquirer = require('inquirer') | ||
const spdx = require('spdx-license-list/full') | ||
const pkg = require('../../../package.json') | ||
const licenses = require('./licenses') | ||
const validators = require('../../utils/validators') | ||
const filters = require('../../utils/filters') | ||
const ProjectTypes = require('../types.js') | ||
/** | ||
* License related questions to a project | ||
*/ | ||
const unlicensed = [ | ||
{ | ||
name: 'UNLICENSED', | ||
value: { | ||
key: 'UNLICENSED', | ||
name: 'UNLICENSED', | ||
licenseText: '(c) Copyright <year> <copyright holders> All rights reserved' | ||
} | ||
} | ||
] | ||
const approved = ['Apache-2.0', 'ISC', 'MIT'] | ||
const opensource = Object.entries(spdx) | ||
// only use approved licenses | ||
.filter(([key]) => approved.includes(key)) | ||
// structure objects for use with `inquirer` | ||
.map(([key, value]) => ({ name: value.name, value: Object.assign({ key }, value) })) | ||
const licenses = unlicensed.concat(opensource) | ||
/** | ||
* End license related questions behaviour | ||
*/ | ||
/** | ||
* Collection of Common questions for any given telus project | ||
*/ | ||
module.exports = (projectName = '', teams = [{ name: 'Telus' }]) => [ | ||
{ | ||
type: 'confirm', | ||
name: 'oss', | ||
message: 'Project is open-source?', | ||
default: false | ||
}, | ||
{ | ||
type: 'input', | ||
name: 'title', | ||
message: | ||
'Project title (1 alphabet char, followed by 0 to 20 alphanumeric, hyphen, or space chars):', | ||
validate: validators.isTitle, | ||
default: () => _.capitalize(projectName), | ||
filter: filters.toStrTrimmed | ||
}, | ||
{ | ||
type: 'input', | ||
name: 'name', | ||
message: 'Project package name or repository name', | ||
default: (answers) => | ||
projectName | ||
? projectName.replace(/@.+\//, '') | ||
: answers.title.toLowerCase().replace(/[\W_]+/g, '-'), | ||
filter: validators.toStrTrimmed, | ||
validate: validators.isValidName | ||
}, | ||
{ | ||
type: 'list', | ||
name: 'license', | ||
message: 'Project license:', | ||
default: (answers) => pkg.license || (answers.oss ? 'MIT' : 'UNLICENSED'), | ||
choices: licenses | ||
}, | ||
{ | ||
type: 'input', | ||
name: 'description', | ||
message: 'Project description:', | ||
default: 'TELUS Core scaffolded project', | ||
validate: validators.isNotEmpty, | ||
filter: filters.toStrTrimmed | ||
}, | ||
{ | ||
type: 'input', | ||
name: 'topics', | ||
message: 'Project keywords (comma separated):', | ||
default: pkg.keywords ? pkg.keywords.filter((input) => input !== 'telus').join(', ') : null, | ||
validate: validators.isNotEmpty, | ||
filter: filters.toListCommas | ||
}, | ||
{ | ||
type: 'list', | ||
name: 'team', | ||
message: 'Select The Project Owner Team:', | ||
choices: teams | ||
module.exports = ({ teams, name, type }) => { | ||
const tmpQs = [] | ||
if (!type) { | ||
const typeQuestion = { | ||
type: 'list', | ||
name: 'type', | ||
message: 'Select a project type:', | ||
choices: ProjectTypes | ||
} | ||
tmpQs.push(typeQuestion) | ||
} | ||
] | ||
const questions = tmpQs.concat([ | ||
{ | ||
type: 'confirm', | ||
name: 'oss', | ||
message: 'Project is open-source?', | ||
default: false | ||
}, | ||
{ | ||
type: 'input', | ||
name: 'title', | ||
message: | ||
'Project title (1 alphabet char, followed by 0 to 20 alphanumeric, hyphen, or space chars):', | ||
validate: validators.isTitle, | ||
default: () => _.capitalize(name), | ||
filter: filters.toStrTrimmed | ||
}, | ||
{ | ||
type: 'input', | ||
name: 'name', | ||
message: 'Project package name or repository name', | ||
default: (answers) => | ||
name ? name.replace(/@.+\//, '') : filters.toStrProjectKey(answers.title), | ||
filter: validators.toStrTrimmed, | ||
validate: validators.isValidName | ||
}, | ||
{ | ||
type: 'list', | ||
name: 'license', | ||
message: 'Project license:', | ||
default: (answers) => pkg.license || (answers.oss ? 'MIT' : 'UNLICENSED'), | ||
choices: licenses | ||
}, | ||
{ | ||
type: 'input', | ||
name: 'description', | ||
message: 'Project description:', | ||
default: 'TELUS Core scaffolded project', | ||
validate: validators.isNotEmpty, | ||
filter: filters.toStrTrimmed | ||
}, | ||
{ | ||
type: 'input', | ||
name: 'topics', | ||
message: 'Project keywords (comma separated):', | ||
default: pkg.keywords ? pkg.keywords.filter((input) => input !== 'telus').join(', ') : null, | ||
validate: validators.isNotEmpty, | ||
filter: filters.toListCommas | ||
}, | ||
{ | ||
type: 'list', | ||
name: 'team', | ||
message: 'Select The Project Owner Team:', | ||
choices: teams | ||
} | ||
]) | ||
return inquirer.prompt(questions) | ||
} |
@@ -0,4 +1,35 @@ | ||
const inquirer = require('inquirer') | ||
/** | ||
* | ||
* We use inquirer.js to generate questions. | ||
* A question in it's basic form consists of: | ||
* @typedef {Object} Question | ||
* @property {string} type - Defaults to input. Possible values: input, number, confirm, list, rawlist, expand, checkbox, password, editor | ||
* @property {string} name - Name to use when storing the answer in the answers hash | ||
* @property {string|function} message - The question to print. | ||
* @property {string|number|boolean|Array|function} default - The year | ||
* @property {function} filter - The year | ||
* @property {Array|function} choices - The year | ||
* @property {function} validate | ||
* | ||
* You can see more information about questions here https://github.com/SBoudrias/Inquirer.js/#objects | ||
*/ | ||
/** | ||
* | ||
* @param {Question[]} templateQs | ||
*/ | ||
const generateQuestionsfromTemplate = async (templateQs = []) => { | ||
if (templateQs.length === 0) { | ||
return Promise.resolve() | ||
} | ||
const questions = [...templateQs] | ||
return inquirer.prompt(questions) | ||
} | ||
module.exports = { | ||
commonQs: require('./common'), | ||
processAnswers: require('./process-answers') | ||
processAnswers: require('./process-answers'), | ||
generateQuestionsfromTemplate | ||
} |
@@ -7,3 +7,2 @@ const filters = require('../../utils/filters') | ||
newAnswers.access = !newAnswers.oss ? 'restricted' : 'public' | ||
newAnswers.key = filters.toStrProjectKey(newAnswers.title) | ||
newAnswers.keywords = filters.toStrListCommas(newAnswers.topics) | ||
@@ -13,11 +12,3 @@ newAnswers.licenseText = filters.toStrLicense(newAnswers.license.licenseText) | ||
// User info | ||
if (input.user) { | ||
newAnswers.user.email = filters.getValidEmail([ | ||
...newAnswers.user.emails, | ||
{ email: newAnswers.user.email || '', default: true } | ||
]) | ||
} | ||
return newAnswers | ||
} |
{ | ||
"version": "0.0.0-development", | ||
"name": "@telus/{{name}}", | ||
"description": "{{description}}", | ||
"homepage": "https://github.com/telus/{{name}}", | ||
"name": "@telus/{{ project.name }}", | ||
"description": "{{ project.description }}", | ||
"homepage": "https://github.com/telus/{{ project.name }}", | ||
"repository": { | ||
"type": "git", | ||
"url": "https://github.com/telus/{{name}}.git" | ||
"url": "https://github.com/telus/{{ project.name }}.git" | ||
}, | ||
"license": "{{license}}", | ||
"license": "{{ project.license }}", | ||
"main": "index.js", | ||
@@ -20,7 +20,6 @@ "engines": { | ||
"bugs": { | ||
"url": "https://github.com/telus/{{name}}/issues" | ||
"url": "https://github.com/telus/{{ project.name }}/issues" | ||
}, | ||
"scripts": { | ||
"lint:audit": "telus-core lint:audit", | ||
"lint:deps": "telus-core lint:deps", | ||
"lint:ec": "telus-core lint:ec", | ||
@@ -27,0 +26,0 @@ "lint:js": "telus-core lint:js", |
@@ -1,6 +0,12 @@ | ||
module.exports = { | ||
api: 'target', | ||
gqlapi: '@telus/ng-gql-api-template', | ||
ui: 'target', | ||
library: '@telus/ng-library-template' | ||
} | ||
module.exports = [ | ||
{ | ||
type: 'gqlapi', | ||
value: '@telus/ng-gql-api-template', | ||
name: 'GQL API' | ||
}, | ||
{ | ||
type: 'library', | ||
value: '@telus/ng-library-template', | ||
name: 'Library' | ||
} | ||
] |
@@ -30,13 +30,16 @@ /** | ||
*/ | ||
const getValidEmail = (arr = []) => { | ||
const getValidEmail = (emails = []) => { | ||
const regex = RegExp('^[A-Za-z0-9._%+-]+@(telus.com|telusdigital.com)$', 'gi') | ||
const emails = arr.map((e) => e.email) | ||
const result = emails.filter((e) => { | ||
return regex.test(e) || e.default | ||
const telusEmail = emails.find((e) => { | ||
return regex.test(e.email) | ||
}) | ||
// there's always going to be at least a default value in the array | ||
// hence this horrible thing result[0] 😨 | ||
return result[0] | ||
if (telusEmail) { | ||
return telusEmail.email | ||
} | ||
return emails.find((e) => { | ||
return e.primary && e.verified | ||
} | ||
@@ -43,0 +46,0 @@ |
Unidentified License
License(Experimental) Something that seems like a license was found, but its contents could not be matched with a known license.
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
Unidentified License
License(Experimental) Something that seems like a license was found, but its contents could not be matched with a known license.
Found 1 instance in 1 package
40992
13.18%1130
5.41%0
-100%