You're Invited:Meet the Socket Team at BlackHat and DEF CON in Las Vegas, Aug 4-6.RSVP
Socket
Book a DemoInstallSign in
Socket

@telus/digital

Package Overview
Dependencies
Maintainers
23
Versions
8
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@telus/digital - npm Package Compare versions

Comparing version

to
2.0.0

src/create_project/github/handle-saml.js

2

package.json
{
"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
}).email
}

@@ -43,0 +46,0 @@