@brightspace-ui/create
Advanced tools
Comparing version 3.0.1 to 3.1.0
@@ -12,5 +12,19 @@ #!/usr/bin/env node | ||
var _index5 = require("./generators/release/index.js"); | ||
var _index6 = require("./generators/test-unit/index.js"); | ||
var _index7 = require("./generators/test-vdiff/index.js"); | ||
var _index6 = require("./generators/static-site/index.js"); | ||
var _index7 = require("./generators/test-unit/index.js"); | ||
var _index8 = require("./generators/test-vdiff/index.js"); | ||
function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; } | ||
const generatorTypes = { | ||
component: 'component', | ||
staticSite: 'staticSite', | ||
bsiApp: 'bsiApp' | ||
}; | ||
const projectTypes = { | ||
component: 'component', | ||
app: 'app' | ||
}; | ||
const applicationTypes = { | ||
bsi: 'bsi', | ||
staticSite: 'staticSite' | ||
}; | ||
function getClassName(hyphenatedName) { | ||
@@ -22,3 +36,50 @@ const hyphenRemoved = hyphenatedName.replace(/-([a-z])/g, g => { | ||
} | ||
async function getOptions() { | ||
async function getGeneratorType() { | ||
const { | ||
projectType | ||
} = await (0, _prompts.default)([{ | ||
type: 'select', | ||
name: 'projectType', | ||
message: 'What type of project is this?', | ||
choices: [{ | ||
title: 'Component', | ||
value: projectTypes.component | ||
}, { | ||
title: 'Application', | ||
value: projectTypes.app | ||
}] | ||
}], { | ||
onCancel: () => { | ||
process.exit(); | ||
} | ||
}); | ||
if (projectType === projectTypes.component) return generatorTypes.component; | ||
const { | ||
applicationType | ||
} = await (0, _prompts.default)([{ | ||
type: 'select', | ||
name: 'applicationType', | ||
message: 'What type of application is this?', | ||
choices: [{ | ||
title: 'BSI', | ||
value: applicationTypes.bsi | ||
}, { | ||
title: 'Static Site', | ||
value: applicationTypes.staticSite | ||
}] | ||
}], { | ||
onCancel: () => { | ||
process.exit(); | ||
} | ||
}); | ||
switch (applicationType) { | ||
case applicationTypes.staticSite: | ||
return generatorTypes.staticSite; | ||
case applicationTypes.bsi: | ||
return generatorTypes.bsiApp; | ||
default: | ||
break; | ||
} | ||
} | ||
async function getComponentOptions() { | ||
const questions = [{ | ||
@@ -76,4 +137,4 @@ type: 'text', | ||
} | ||
async function executeGenerator() { | ||
const options = await getOptions(); | ||
async function executeComponentGenerator() { | ||
const options = await getComponentOptions(); | ||
@@ -93,4 +154,4 @@ /** | ||
(0, _index3.run)(options); | ||
(0, _index6.run)(options); | ||
if (options.vdiff) (0, _index7.run)(options); | ||
(0, _index7.run)(options); | ||
if (options.vdiff) (0, _index8.run)(options); | ||
(0, _index2.run)(options); | ||
@@ -100,2 +161,128 @@ if (options.localization) (0, _index4.run)(options); | ||
} | ||
async function executeStaticSiteGenerator() { | ||
const { | ||
hyphenatedNameRaw, | ||
description, | ||
codeowners, | ||
hostingTarget | ||
} = await (0, _prompts.default)([{ | ||
type: 'text', | ||
name: 'hyphenatedNameRaw', | ||
message: 'What would you like to name your app? Use hyphenation instead of camelcase.' | ||
}, { | ||
type: 'text', | ||
name: 'description', | ||
message: 'What is the app description?' | ||
}, { | ||
type: 'text', | ||
name: 'codeowners', | ||
message: 'What is/are the GitHub username(s) of the codeowner(s)? (e.g., @janesmith, @johnsmith)' | ||
}, { | ||
type: 'select', | ||
name: 'hostingTarget', | ||
message: 'Where would you like to host your app?', | ||
choices: [{ | ||
title: 'd2l.dev', | ||
value: 'd2ldev' | ||
}, { | ||
title: 'S3 Bucket', | ||
value: 's3' | ||
}, { | ||
title: 'Other', | ||
value: 'other' | ||
}] | ||
}], { | ||
onCancel: () => { | ||
process.exit(); | ||
} | ||
}); | ||
const hyphenatedName = hyphenatedNameRaw.toLowerCase(); | ||
let roleToAssume, awsRegion, bucketPath, d2ldevSubdomain; | ||
if (hostingTarget === 'd2ldev') { | ||
const { | ||
subdomain | ||
} = await (0, _prompts.default)([{ | ||
type: 'text', | ||
name: 'subdomain', | ||
message: 'What is the d2l.dev subdomain you want to publish this app to?' | ||
}], { | ||
onCancel: () => { | ||
process.exit(); | ||
} | ||
}); | ||
roleToAssume = `"arn:aws:iam::022062736489:role/r+Brightspace+${hyphenatedName}+repo"`; | ||
awsRegion = 'ca-central-1'; | ||
bucketPath = `s3://d2l.dev/${subdomain}/main`; | ||
d2ldevSubdomain = subdomain; | ||
} else if (hostingTarget === 's3') { | ||
const { | ||
role, | ||
region, | ||
path | ||
} = await (0, _prompts.default)([{ | ||
type: 'text', | ||
name: 'role', | ||
message: 'What is the AWS ARN of the role you wish to authenticate as? (e.g. arn:aws:iam::123456789012:role/r+my+role)' | ||
}, { | ||
type: 'text', | ||
name: 'region', | ||
message: 'What AWS region do you want to authenticate into? (e.g. us-east-1)' | ||
}, { | ||
type: 'text', | ||
name: 'path', | ||
message: 'What is the S3 bucket path you wish to publish to? (e.g. s3://my-bucket/my-path)' | ||
}], { | ||
onCancel: () => { | ||
process.exit(); | ||
} | ||
}); | ||
roleToAssume = `"${role}"`; | ||
awsRegion = region; | ||
bucketPath = path; | ||
} | ||
const templateData = { | ||
hyphenatedName, | ||
className: getClassName(hyphenatedName), | ||
tagName: `d2l-${hyphenatedName}`, | ||
repoName: hyphenatedName, | ||
description, | ||
codeowners, | ||
hostingTarget, | ||
roleToAssume, | ||
awsRegion, | ||
bucketPath, | ||
d2ldevSubdomain | ||
}; | ||
(0, _index6.run)(templateData); | ||
console.log('\nTemplate setup complete!\n'); | ||
if (hostingTarget === 'd2ldev') { | ||
console.log('Note: Make sure you have set up the appropriate permissions in github.com/Brightspace/repo-settings so that your repo can publish to d2l.dev.'); | ||
console.log('For details on how to do this, please review the d2l.dev setup guide (https://desire2learn.atlassian.net/wiki/x/H4A70).\n'); | ||
} else if (hostingTarget === 's3') { | ||
console.log('Note: Make sure you have set up the appropriate permissions in github.com/Brightspace/repo-settings so that your repo can publish to the S3 bucket you specified.\n'); | ||
} else { | ||
console.log('Note: Since you did not specify a publishing target, the generated .github/workflows/publish.yml file doesn\'t include an actual publishing step.'); | ||
console.log('In order to publish your site, you\'ll have to add your own publishing step.\n'); | ||
} | ||
} | ||
async function executeBsiAppGenerator() { | ||
console.log('Sorry, the BSI Application template is not yet available.'); | ||
console.log('In the meantime, please create a Component project type and modify it to work as a BSI App.'); | ||
} | ||
async function executeGenerator() { | ||
const generatorType = await getGeneratorType(); | ||
switch (generatorType) { | ||
case generatorTypes.component: | ||
await executeComponentGenerator(); | ||
break; | ||
case generatorTypes.staticSite: | ||
await executeStaticSiteGenerator(); | ||
break; | ||
case generatorTypes.bsiApp: | ||
await executeBsiAppGenerator(); | ||
break; | ||
default: | ||
break; | ||
} | ||
} | ||
(async () => { | ||
@@ -102,0 +289,0 @@ try { |
@@ -6,2 +6,3 @@ "use strict"; | ||
}); | ||
exports.copyAndProcessDir = copyAndProcessDir; | ||
exports.copyFile = copyFile; | ||
@@ -12,3 +13,5 @@ exports.copyFilesInDir = copyFilesInDir; | ||
exports.mergeText = mergeText; | ||
exports.movePlugin = movePlugin; | ||
exports.replaceText = replaceText; | ||
exports.replaceTextPlugin = replaceTextPlugin; | ||
var _fs = _interopRequireDefault(require("fs")); | ||
@@ -85,2 +88,94 @@ var _path = _interopRequireDefault(require("path")); | ||
_fs.default.writeFileSync(source, result, 'utf8'); | ||
} | ||
function copyAndProcessFile(sourceRoot, destinationRoot, relativePath, fileName, plugins = []) { | ||
const context = { | ||
sourceRoot, | ||
destinationRoot, | ||
relativePath, | ||
fileName | ||
}; | ||
const source = _path.default.join(sourceRoot, relativePath, fileName); | ||
const destination = _path.default.join(destinationRoot, relativePath, fileName); | ||
const onPostCopyFns = []; | ||
const processedDestinaton = plugins.reduce((destination, plugin) => { | ||
const { | ||
newDestination = destination, | ||
onPostCopy | ||
} = plugin(source, destination, context); | ||
if (typeof onPostCopy === 'function') { | ||
onPostCopyFns.push(onPostCopy); | ||
} | ||
return newDestination; | ||
}, destination); | ||
const toPathDir = _path.default.dirname(processedDestinaton); | ||
if (!_fs.default.existsSync(toPathDir)) { | ||
_fs.default.mkdirSync(toPathDir, { | ||
recursive: true | ||
}); | ||
} | ||
_fs.default.copyFileSync(source, processedDestinaton); | ||
onPostCopyFns.forEach(onPostCopy => onPostCopy(source, processedDestinaton, context)); | ||
} | ||
function copyAndProcessDir(sourceDir, destinationDir, plugins = [], context = {}) { | ||
const { | ||
sourceRoot = sourceDir, | ||
destinationRoot = destinationDir, | ||
relativePath = '' | ||
} = context; | ||
const files = _fs.default.readdirSync(sourceDir); | ||
files.forEach(file => { | ||
const curSource = _path.default.join(sourceDir, file); | ||
if (_fs.default.lstatSync(curSource).isDirectory()) { | ||
const targetFolder = _path.default.join(destinationDir, _path.default.basename(curSource)); | ||
if (!_fs.default.existsSync(targetFolder)) { | ||
_fs.default.mkdirSync(targetFolder, { | ||
recursive: true | ||
}); | ||
} | ||
copyAndProcessDir(curSource, targetFolder, plugins, { | ||
sourceRoot, | ||
destinationRoot, | ||
relativePath: _path.default.join(relativePath, file) | ||
}); | ||
} else { | ||
copyAndProcessFile(sourceRoot, destinationRoot, relativePath, file, plugins); | ||
} | ||
}); | ||
} | ||
function movePlugin(moveMappings = {}) { | ||
const normalizedMoveMappings = Object.entries(moveMappings).reduce((acc, [key, value]) => { | ||
acc[_path.default.normalize(key)] = _path.default.normalize(value); | ||
return acc; | ||
}, {}); | ||
return (source, destination, context) => { | ||
const { | ||
destinationRoot, | ||
relativePath, | ||
fileName | ||
} = context; | ||
const newRelativeDestination = normalizedMoveMappings[_path.default.join(relativePath, fileName)]; | ||
return { | ||
newDestination: newRelativeDestination ? _path.default.join(destinationRoot, newRelativeDestination) : destination | ||
}; | ||
}; | ||
} | ||
function replaceTextPlugin(perFileReplacements = {}) { | ||
const normalizedPerFileReplacements = Object.entries(perFileReplacements).reduce((acc, [key, value]) => { | ||
acc[_path.default.normalize(key)] = value; | ||
return acc; | ||
}, {}); | ||
return () => { | ||
return { | ||
onPostCopy: (source, destination, context) => { | ||
const { | ||
relativePath, | ||
fileName | ||
} = context; | ||
const replacements = normalizedPerFileReplacements[_path.default.join(relativePath, fileName)]; | ||
if (replacements) { | ||
replaceText(destination, replacements); | ||
} | ||
} | ||
}; | ||
}; | ||
} |
{ | ||
"name": "@brightspace-ui/create", | ||
"version": "3.0.1", | ||
"version": "3.1.0", | ||
"description": "Initializer for Brightspace web components", | ||
@@ -13,3 +13,3 @@ "repository": "https://github.com/BrightspaceUI/create.git", | ||
"scripts": { | ||
"build": "rm -rf dist && babel src --out-dir dist --copy-files --include-dotfiles", | ||
"build": "rimraf dist && babel src --out-dir dist --copy-files --include-dotfiles", | ||
"lint:eslint": "eslint . --ext .js,.html", | ||
@@ -34,4 +34,5 @@ "test": "npm run lint:eslint" | ||
"eslint": "^8", | ||
"eslint-config-brightspace": "^1" | ||
"eslint-config-brightspace": "^1", | ||
"rimraf": "^5.0.7" | ||
} | ||
} |
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
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
64119
75
895
9