shenanigans-manager
Advanced tools
Comparing version 0.8.1 to 0.8.3
{ | ||
"author": { | ||
"name": "Josh Goldberg", | ||
"email": "me@joshuakgoldberg.com" | ||
"email": "git@joshuakgoldberg.com" | ||
}, | ||
"bin": { | ||
"shenanigans-manager": "./bin/shenanigans-manager" | ||
"shenanigans-manager": "./bin/shenanigans-manager.js" | ||
}, | ||
@@ -13,24 +13,24 @@ "bugs": { | ||
"devDependencies": { | ||
"@types/glob": "^7.1.2", | ||
"@types/json-stable-stringify": "^1.0.32", | ||
"@types/minimist": "^1.2.0", | ||
"@types/mkdirp": "^1.0.1", | ||
"@types/mustache": "^4.0.1", | ||
"@types/mz": "2.7.1", | ||
"@types/node": "^14.0.13", | ||
"@types/rimraf": "^3.0.0", | ||
"npm-check-updates": "^7.0.1" | ||
"@types/glob": "^7.2.0", | ||
"@types/json-stable-stringify": "^1.0.34", | ||
"@types/minimist": "^1.2.2", | ||
"@types/mkdirp": "^1.0.2", | ||
"@types/mustache": "^4.2.1", | ||
"@types/mz": "2.7.4", | ||
"@types/node": "^18.7.3", | ||
"@types/rimraf": "^3.0.2", | ||
"npm-check-updates": "^16.0.5" | ||
}, | ||
"dependencies": { | ||
"@types/prettier": "^2.0.1", | ||
"chalk": "^4.1.0", | ||
"chokidar": "^3.4.0", | ||
"glob": "^7.1.6", | ||
"@types/prettier": "^2.7.0", | ||
"chalk": "^5.0.1", | ||
"chokidar": "^3.5.3", | ||
"glob": "^8.0.3", | ||
"json-stable-stringify": "^1.0.1", | ||
"minimist": "^1.2.5", | ||
"minimist": "^1.2.6", | ||
"mkdirp": "^1.0.4", | ||
"moment": "^2.27.0", | ||
"mustache": "^4.0.1", | ||
"moment": "^2.29.4", | ||
"mustache": "^4.2.0", | ||
"mz": "^2.7.0", | ||
"prettier": "^2.3.2", | ||
"prettier": "^2.7.1", | ||
"rimraf": "^3.0.2" | ||
@@ -49,8 +49,7 @@ }, | ||
"ncu": "ncu -u", | ||
"ncu:setup": "yarn run ncu:setup:dist && yarn run ncu:setup:package", | ||
"ncu:setup:dist": "ncu -u --packageFile setup/package-dist.json", | ||
"ncu:setup:package": "ncu -u --packageFile setup/package.json", | ||
"ncu:setup": "ncu -u --packageFile \"setup/package*.json\"", | ||
"ncu:all": "yarn run ncu && yarn run ncu:setup" | ||
}, | ||
"version": "0.8.1" | ||
"type": "module", | ||
"version": "0.8.3" | ||
} |
@@ -6,3 +6,3 @@ <!-- Top --> | ||
Documentation coming soon<sup>tm</sup>! | ||
Documentation coming soon™️! | ||
@@ -9,0 +9,0 @@ <!-- Development --> |
@@ -93,3 +93,2 @@ {{ #shenanigans.game }} | ||
background: "#ffcc33", | ||
cursor: "pointer", | ||
fontFamily: "Press Start", | ||
@@ -122,3 +121,3 @@ padding: "7px 3px", | ||
width: "auto", | ||
padding: "4px 3px 7px 3px", | ||
padding: "4px 3px 21px", | ||
boxShadow: [ | ||
@@ -145,5 +144,18 @@ "0 3px 7px black inset", | ||
}, | ||
menusInnerAreaFake: { | ||
menuTitle: { | ||
fontSize: "16px", | ||
}, | ||
menuTitleButton: { | ||
alignItems: "center", | ||
background: "none", | ||
border: "none", | ||
color: "white", | ||
display: "flex", | ||
fontFamily: "Press Start", | ||
fontSize: "16px", | ||
justifyContent: "center", | ||
}, | ||
menuTitleButtonFake: { | ||
color: "grey", | ||
}, | ||
} | ||
}, | ||
@@ -150,0 +162,0 @@ }; |
@@ -9,4 +9,4 @@ {{ #shenanigans.game }} | ||
console.error("An error happened while trying to instantiate {{ shenanigans.name }}!"); | ||
console.error(error); | ||
console.error('requirejs error:', error); | ||
}); | ||
{{ /shenanigans.game }} |
@@ -8,10 +8,7 @@ { | ||
"forceConsistentCasingInFileNames": true, | ||
"jsx": "react", | ||
"lib": ["dom", "es2015"], | ||
"jsx": "react-jsx", | ||
"jsxImportSource": "preact", | ||
"module": "amd", | ||
"moduleResolution": "node", | ||
"noFallthroughCasesInSwitch": true, | ||
"noImplicitAny": true, | ||
"noImplicitReturns": true, | ||
"noImplicitThis": true, | ||
"noUnusedLocals": true, | ||
@@ -27,3 +24,3 @@ "noUnusedParameters": true, | ||
"strictPropertyInitialization": false, | ||
"target": "es2015" | ||
"target": "ES2021" | ||
}, | ||
@@ -30,0 +27,0 @@ "exclude": ["**/*.d.ts", "**/lib"], |
{ | ||
"devDependencies": { | ||
"@babel/core": "^7.10.3", | ||
"@babel/plugin-proposal-class-properties": "^7.10.1", | ||
"@babel/plugin-proposal-decorators": "^7.10.1", | ||
"@babel/preset-react": "^7.10.1", | ||
"@babel/preset-typescript": "^7.10.1", | ||
"babel-loader": "8.1.0", | ||
"webpack": "^4.43.0", | ||
"webpack-cli": "^3.3.12" | ||
"ts-loader": "^9.3.1", | ||
"webpack": "^5.74.0", | ||
"webpack-cli": "^4.10.0" | ||
}, | ||
"scripts": { | ||
"dist": "webpack" | ||
"dist": "webpack", | ||
"test:run": "yarn mocha-headless-chrome --file test/index.html --polling 1000" | ||
} | ||
} |
{ | ||
"devDependencies": { | ||
"husky": "^4.2.5", | ||
"lint-staged": "^10.2.11" | ||
"husky": "^8.0.1", | ||
"lint-staged": "^13.0.3" | ||
}, | ||
@@ -19,3 +19,3 @@ "husky": { | ||
"compile": "tsc", | ||
"format": "prettier --ignore-path .prettierignore --list-different \"./**/*.{css,js,json,md,ts,tsx}\"", | ||
"format": "prettier --ignore-path .prettierignore --check \"./**/*.{css,js,json,md,ts,tsx}\"", | ||
"format:write": "yarn format --write", | ||
@@ -22,0 +22,0 @@ "lint": "eslint --ignore-path .eslintignore \"./src/**/*.{ts,tsx}\"" |
{ | ||
"dependencies": { | ||
"eightbittr": "^0.9.0", | ||
"userwrappr": "^0.9.0" | ||
"eightbittr": "^0.8.2", | ||
"userwrappr": "^0.8.2" | ||
}, | ||
@@ -11,33 +11,28 @@ "shenanigans": { | ||
"js": { | ||
"dev": "../node_modules/mobx/lib/mobx.umd", | ||
"prod": "../node_modules/mobx/lib/mobx.umd.min" | ||
"dev": "preact/dist/preact.umd", | ||
"prod": "preact/dist/preact.umd" | ||
}, | ||
"name": "mobx" | ||
"name": "preact" | ||
}, | ||
{ | ||
"js": { | ||
"dev": "../node_modules/mobx-react/index", | ||
"prod": "../node_modules/mobx-react/index.min" | ||
"dev": "preact/hooks/dist/hooks.umd", | ||
"prod": "preact/hooks/dist/hooks.umd" | ||
}, | ||
"name": "mobx-react" | ||
"name": "preact/hooks" | ||
}, | ||
{ | ||
"js": { | ||
"dev": "../node_modules/react/umd/react.development", | ||
"prod": "../node_modules/react/lib/react.production" | ||
"dev": "preact/jsx-runtime/dist/jsxRuntime.umd", | ||
"prod": "preact/jsx-runtime/dist/jsxRuntime.umd" | ||
}, | ||
"name": "react" | ||
"name": "preact/jsx-runtime" | ||
}, | ||
{ | ||
"js": { | ||
"dev": "../node_modules/react-dom/umd/react-dom.development", | ||
"prod": "../node_modules/react-dom/lib/react-dom.production" | ||
"dev": "userwrappr/dist/UserWrappr-Delayed", | ||
"prod": "userwrappr/dist/UserWrappr-Delayed" | ||
}, | ||
"name": "react-dom" | ||
}, | ||
{ | ||
"js": { | ||
"dev": "../node_modules/userwrappr/dist/UserWrappr-Delayed" | ||
}, | ||
"name": "UserWrappr-Delayed" | ||
"name": "UserWrappr-Delayed", | ||
"shenanigansPackage": true | ||
} | ||
@@ -44,0 +39,0 @@ ] |
{ | ||
"devDependencies": { | ||
"mobx": "^5.9.4", | ||
"mobx-react": "^5.4.3", | ||
"react": "^16.8.6", | ||
"react-dom": "^16.8.6", | ||
"preact": "^10.10.2", | ||
"requirejs": "^2.3.6" | ||
} | ||
} |
{ | ||
"browser": "./lib/index.js", | ||
"devDependencies": { | ||
"@sinonjs/fake-timers": "^6.0.1", | ||
"@types/chai": "^4.2.11", | ||
"@types/mocha": "^7.0.2", | ||
"@types/sinon": "^9.0.4", | ||
"@types/sinon-chai": "^3.2.4", | ||
"chai": "^4.2.0", | ||
"mocha": "^8.0.1", | ||
"mocha-headless-chrome": "^3.1.0", | ||
"@types/chai": "^4.3.3", | ||
"@types/mocha": "^9.1.1", | ||
"@types/sinon": "^10.0.13", | ||
"@types/sinon-chai": "^3.2.8", | ||
"chai": "^4.3.6", | ||
"mocha": "^10.0.0", | ||
"mocha-headless-chrome": "^4.0.0", | ||
"shenanigans-manager": "^0.8.1", | ||
"sinon": "^9.0.2", | ||
"sinon-chai": "^3.5.0" | ||
"sinon": "^14.0.0", | ||
"sinon-chai": "^3.7.0" | ||
}, | ||
"scripts": { | ||
"clean": "rm -rf lib *.tsbuildinfo", | ||
"clean": "rm -rf dist lib *.tsbuildinfo", | ||
"hydrate": "yarn shenanigans-manager hydrate", | ||
@@ -22,3 +21,3 @@ "link": "yarn link", | ||
"test": "yarn run test:setup && yarn run test:run", | ||
"test:run": "mocha-headless-chrome --file test/index.html", | ||
"test:run": "yarn mocha-headless-chrome --file test/index.html", | ||
"test:setup": "yarn shenanigans-manager generate-tests" | ||
@@ -25,0 +24,0 @@ }, |
@@ -6,3 +6,3 @@ ## Development | ||
``` | ||
```shell | ||
git clone https://github.com/<your-name-here>/{{ shenanigans.name }} | ||
@@ -9,0 +9,0 @@ cd {{ shenanigans.name }} |
import minimist from "minimist"; | ||
import * as path from "path"; | ||
import { CommandArgs } from "./command"; | ||
import { CommandSearcher } from "./commandSearcher"; | ||
import { ConsoleLogger } from "./loggers/consoleLogger"; | ||
import { NameTransformer } from "./nameTransformer"; | ||
import { Runner } from "./runner"; | ||
import { CommandArgs } from "./command.js"; | ||
import { CommandSearcher } from "./commandSearcher.js"; | ||
import { filesDirName } from "./directories.js"; | ||
import { ConsoleLogger } from "./loggers/consoleLogger.js"; | ||
import { NameTransformer } from "./nameTransformer.js"; | ||
import { Runner } from "./runner.js"; | ||
@@ -38,3 +39,3 @@ const argv = minimist(process.argv.slice(2)); | ||
const runner = new Runner( | ||
new CommandSearcher([path.join(__dirname, "commands")], new NameTransformer()) | ||
new CommandSearcher([path.join(filesDirName, "commands")], new NameTransformer()) | ||
); | ||
@@ -54,3 +55,3 @@ | ||
} catch (error) { | ||
console.error(error); | ||
console.error("shenanigans-manager error:", error); | ||
return; | ||
@@ -61,3 +62,3 @@ } | ||
main().catch((error) => { | ||
console.error(error); | ||
console.error("Oh no!", error); | ||
}); |
@@ -0,4 +1,5 @@ | ||
/* eslint-disable @typescript-eslint/no-unsafe-member-access */ | ||
import chalk from "chalk"; | ||
import { Runtime } from "./runtime"; | ||
import { Runtime } from "./runtime.js"; | ||
@@ -31,2 +32,3 @@ /** | ||
*/ | ||
// eslint-disable-next-line @typescript-eslint/no-invalid-void-type | ||
export type Command<TArgs extends CommandArgs = CommandArgs, TReturn = void> = ( | ||
@@ -33,0 +35,0 @@ runtime: Runtime, |
@@ -0,8 +1,8 @@ | ||
import { promises as fs } from "fs"; | ||
import mkdirp from "mkdirp"; | ||
import * as fs from "mz/fs"; | ||
import * as path from "path"; | ||
import { defaultPathArgs, ensureArgsExist, RepositoryCommandArgs } from "../command"; | ||
import { Runtime } from "../runtime"; | ||
import { Hydrate } from "./hydrate"; | ||
import { defaultPathArgs, ensureArgsExist, RepositoryCommandArgs } from "../command.js"; | ||
import { Runtime } from "../runtime.js"; | ||
import { Hydrate } from "./hydrate.js"; | ||
@@ -19,3 +19,3 @@ /** | ||
/** | ||
* Whether to include the sheananigans.dist setting in package.json. | ||
* Whether to include the shenanigans.dist setting in package.json. | ||
*/ | ||
@@ -25,3 +25,3 @@ dist?: boolean; | ||
/** | ||
* Whether to include the sheananigans.game setting in package.json. | ||
* Whether to include the shenanigans.game setting in package.json. | ||
*/ | ||
@@ -41,3 +41,3 @@ game?: boolean; | ||
/** | ||
* Whether to include the sheananigans.web setting in package.json. | ||
* Whether to include the shenanigans.web setting in package.json. | ||
*/ | ||
@@ -44,0 +44,0 @@ web?: boolean; |
import mkdirp from "mkdirp"; | ||
import * as path from "path"; | ||
import { defaultPathArgs, RepositoryCommandArgs } from "../command"; | ||
import { Runtime } from "../runtime"; | ||
import { defaultPathArgs, RepositoryCommandArgs } from "../command.js"; | ||
import { Runtime } from "../runtime.js"; | ||
@@ -7,0 +7,0 @@ const defaultDirectories = ["lib", "src", "test"]; |
@@ -1,4 +0,4 @@ | ||
import { ensureArgsExist, RepositoryCommandArgs } from "../command"; | ||
import { Runtime } from "../runtime"; | ||
import { Shell } from "../shell"; | ||
import { ensureArgsExist, RepositoryCommandArgs } from "../command.js"; | ||
import { Runtime } from "../runtime.js"; | ||
import { Shell } from "../shell.js"; | ||
@@ -5,0 +5,0 @@ /** |
import * as chokidar from "chokidar"; | ||
import { RepositoryCommandArgs, defaultPathArgs } from "../command"; | ||
import { copyTemplatesRecursive } from "../copyTemplatesRecursive"; | ||
import { Runtime } from "../runtime"; | ||
import { EnsureDirsExist } from "./ensureDirsExist"; | ||
import { defaultPathArgs, RepositoryCommandArgs } from "../command.js"; | ||
import { copyTemplatesRecursive } from "../copyTemplatesRecursive.js"; | ||
import { Runtime } from "../runtime.js"; | ||
import { EnsureDirsExist } from "./ensureDirsExist.js"; | ||
@@ -8,0 +8,0 @@ export interface GenerateTestsArgs extends RepositoryCommandArgs { |
import chalk from "chalk"; | ||
import * as fs from "mz/fs"; | ||
import { promises as fs } from "fs"; | ||
import * as path from "path"; | ||
import { NameTransformer } from "../nameTransformer"; | ||
import { Runtime } from "../runtime"; | ||
import { filesDirName } from "../directories.js"; | ||
import { NameTransformer } from "../nameTransformer.js"; | ||
import { Runtime } from "../runtime.js"; | ||
@@ -23,9 +24,6 @@ const nameTransformer = new NameTransformer(); | ||
const files: string[] = await fs.readdir(path.join(__dirname, "../../src/commands")); | ||
const commands: string[] = files | ||
.filter( | ||
(fileName: string): boolean => | ||
fileName.indexOf(".ts") !== -1 && fileName.indexOf(".d.ts") === -1 | ||
) | ||
.map((fileName: string): string => fileName.substring(0, fileName.length - ".ts".length)); | ||
const files = await fs.readdir(path.join(filesDirName, "commands")); | ||
const commands = files | ||
.filter((fileName) => fileName.endsWith(".js")) | ||
.map((fileName) => path.parse(fileName).name); | ||
@@ -32,0 +30,0 @@ for (const file of commands) { |
@@ -1,5 +0,5 @@ | ||
import { Runtime } from "../runtime"; | ||
import { HydrateFiles, HydrateFilesCommandArgs } from "./hydrateFiles"; | ||
import { HydrateReadme } from "./hydrateReadme"; | ||
import { HydratePackageJson } from "./hydratePackageJson"; | ||
import { Runtime } from "../runtime.js"; | ||
import { HydrateFiles, HydrateFilesCommandArgs } from "./hydrateFiles.js"; | ||
import { HydratePackageJson } from "./hydratePackageJson.js"; | ||
import { HydrateReadme } from "./hydrateReadme.js"; | ||
@@ -6,0 +6,0 @@ /** |
@@ -1,7 +0,11 @@ | ||
import { defaultPathArgs, RepositoryCommandArgs } from "../command"; | ||
import { Runtime } from "../runtime"; | ||
import { getShenanigansPackageContents } from "../utils"; | ||
import { EnsureDirsExist } from "./ensureDirsExist"; | ||
import { copyTemplatesRecursive } from "../copyTemplatesRecursive"; | ||
import chalk from "chalk"; | ||
import { promises as fs } from "fs"; | ||
import * as path from "path"; | ||
import { defaultPathArgs, RepositoryCommandArgs } from "../command.js"; | ||
import { copyTemplatesRecursive } from "../copyTemplatesRecursive.js"; | ||
import { Runtime } from "../runtime.js"; | ||
import { getShenanigansPackageContents } from "../utils.js"; | ||
import { EnsureDirsExist } from "./ensureDirsExist.js"; | ||
/** | ||
@@ -33,6 +37,2 @@ * Args for a hydrate-files command. | ||
if (shenanigans.dist) { | ||
await copyTemplatesRecursive(runtime, args, "dist"); | ||
} | ||
if (shenanigans.external) { | ||
@@ -45,2 +45,17 @@ await copyTemplatesRecursive(runtime, args, "external"); | ||
} | ||
if (shenanigans.dist) { | ||
// Optimization: copy everything from lib/ into dist/ | ||
// (this way the same files don't need to be in shenanigans-manager twice) | ||
const outputDirectory = path.join(args.directory, args.repository); | ||
const libDir = path.join(outputDirectory, "lib"); | ||
const distDir = path.join(outputDirectory, "dist"); | ||
// First copy over everything from lib, so we don't have to duplicate assets | ||
runtime.logger.log(chalk.grey(`Copying directory ${libDir} to ${distDir}`)); | ||
await fs.cp(libDir, distDir, { force: false, recursive: true }); | ||
// Override copied lib/ files with any new dist/ files | ||
await copyTemplatesRecursive(runtime, args, "dist"); | ||
} | ||
}; |
import chalk from "chalk"; | ||
import { promises as fs } from "fs"; | ||
import stringify from "json-stable-stringify"; | ||
import * as fs from "mz/fs"; | ||
import * as path from "path"; | ||
import { defaultPathArgs, RepositoryCommandArgs } from "../command"; | ||
import { Runtime } from "../runtime"; | ||
import { parseFileJson, setupDir } from "../utils"; | ||
import { defaultPathArgs, RepositoryCommandArgs } from "../command.js"; | ||
import { setupDirName } from "../directories.js"; | ||
import { Runtime } from "../runtime.js"; | ||
import { ShenanigansPackage } from "../typings.js"; | ||
import { parseFileJson } from "../utils.js"; | ||
@@ -15,3 +17,3 @@ const mergeOnPackageTemplate = ( | ||
for (const key in source) { | ||
target[key] = { ...(source[key] || ({} as any)), ...(target[key] || ({} as any)) }; | ||
target[key] = { ...(target[key] ?? ({} as any)), ...(source[key] ?? ({} as any)) }; | ||
} | ||
@@ -24,31 +26,33 @@ }; | ||
const packageTemplate = await parseFileJson<ShenanigansPackage>( | ||
path.join(setupDir, "package.json") | ||
path.join(setupDirName, "package.json") | ||
); | ||
const { shenanigans } = basePackageContents; | ||
if (shenanigans?.dist) { | ||
if (shenanigans.dist) { | ||
mergeOnPackageTemplate( | ||
packageTemplate, | ||
await parseFileJson<ShenanigansPackage>(path.join(setupDir, "package-dist.json")) | ||
await parseFileJson<ShenanigansPackage>(path.join(setupDirName, "package-dist.json")) | ||
); | ||
} | ||
if (shenanigans?.external) { | ||
if (shenanigans.external) { | ||
mergeOnPackageTemplate( | ||
packageTemplate, | ||
await parseFileJson<ShenanigansPackage>(path.join(setupDir, "package-external.json")) | ||
await parseFileJson<ShenanigansPackage>( | ||
path.join(setupDirName, "package-external.json") | ||
) | ||
); | ||
} | ||
if (shenanigans?.game) { | ||
if (shenanigans.game) { | ||
mergeOnPackageTemplate( | ||
packageTemplate, | ||
await parseFileJson<ShenanigansPackage>(path.join(setupDir, "package-game.json")) | ||
await parseFileJson<ShenanigansPackage>(path.join(setupDirName, "package-game.json")) | ||
); | ||
} | ||
if (shenanigans?.web) { | ||
if (shenanigans.web) { | ||
mergeOnPackageTemplate( | ||
packageTemplate, | ||
await parseFileJson<ShenanigansPackage>(path.join(setupDir, "package-web.json")) | ||
await parseFileJson<ShenanigansPackage>(path.join(setupDirName, "package-web.json")) | ||
); | ||
@@ -60,3 +64,6 @@ } | ||
await parseFileJson<ShenanigansPackage>( | ||
path.join(setupDir, `package-${shenanigans.external ? "external" : "internal"}.json`) | ||
path.join( | ||
setupDirName, | ||
`package-${shenanigans.external ? "external" : "internal"}.json` | ||
) | ||
) | ||
@@ -75,17 +82,14 @@ ); | ||
const basePackageLocation = path.join(args.directory, args.repository, "package.json"); | ||
const basePackageContents: ShenanigansPackage & Dictionary<any> = await parseFileJson< | ||
ShenanigansPackage | ||
>(basePackageLocation); | ||
const basePackageContents = await parseFileJson<ShenanigansPackage>(basePackageLocation); | ||
runtime.logger.log(chalk.grey(`Hydrating ${basePackageLocation}`)); | ||
const packageTemplate: ShenanigansPackage & Dictionary<any> = await getPackageTemplate( | ||
basePackageContents | ||
); | ||
const packageTemplate = await getPackageTemplate(basePackageContents); | ||
for (const i in packageTemplate) { | ||
if (i in basePackageContents) { | ||
if (typeof basePackageContents[i] === "object") { | ||
const baseContent = basePackageContents[i]; | ||
if (typeof baseContent === "object") { | ||
basePackageContents[i] = { | ||
...basePackageContents[i], | ||
...packageTemplate[i], | ||
...baseContent, | ||
...(packageTemplate[i] as typeof baseContent), | ||
}; | ||
@@ -92,0 +96,0 @@ } |
import chalk from "chalk"; | ||
import * as mustache from "mustache"; | ||
import * as fs from "mz/fs"; | ||
import { existsSync, promises as fs } from "fs"; | ||
import mustache from "mustache"; | ||
import * as os from "os"; | ||
import * as path from "path"; | ||
import { defaultPathArgs, RepositoryCommandArgs } from "../command"; | ||
import { Runtime } from "../runtime"; | ||
import { getShenanigansPackageContents, setupDir } from "../utils"; | ||
import { defaultPathArgs, RepositoryCommandArgs } from "../command.js"; | ||
import { setupDirName } from "../directories.js"; | ||
import { Runtime } from "../runtime.js"; | ||
import { getShenanigansPackageContents } from "../utils.js"; | ||
const templateDir = path.join(setupDir, "readme/"); | ||
const templateDir = path.join(setupDirName, "readme/"); | ||
@@ -52,3 +53,3 @@ export const replaceBetween = async ( | ||
if (!(await fs.exists(readmeLocation))) { | ||
if (!existsSync(readmeLocation)) { | ||
await fs.writeFile(readmeLocation, ""); | ||
@@ -55,0 +56,0 @@ } |
import * as path from "path"; | ||
import { defaultPathArgs, RepositoryCommandArgs } from "../command"; | ||
import { Runtime } from "../runtime"; | ||
import { globAsync } from "../utils"; | ||
import { Shell } from "../shell"; | ||
import { defaultPathArgs, RepositoryCommandArgs } from "../command.js"; | ||
import { packagesDirName } from "../directories.js"; | ||
import { Runtime } from "../runtime.js"; | ||
import { Shell } from "../shell.js"; | ||
import { globAsync } from "../utils.js"; | ||
@@ -14,5 +15,6 @@ /** | ||
const packageNames = ( | ||
await globAsync(path.join(__dirname, "../../../*")) | ||
).map((packageName) => packageName.slice(packageName.lastIndexOf("/") + 1)); | ||
const packageNames = (await globAsync(path.join(packagesDirName, "*"))).map((packageName) => | ||
packageName.slice(packageName.lastIndexOf("/") + 1) | ||
); | ||
console.log({ packageNames }); | ||
const shell = new Shell(runtime.logger); | ||
@@ -19,0 +21,0 @@ |
import chalk from "chalk"; | ||
import * as mustache from "mustache"; | ||
import * as fs from "mz/fs"; | ||
import { promises as fs } from "fs"; | ||
import mustache from "mustache"; | ||
import * as path from "path"; | ||
import { defaultPathArgs, ensureArgsExist, RepositoryCommandArgs } from "../command"; | ||
import { writeFilePretty } from "../prettier"; | ||
import { Runtime } from "../runtime"; | ||
import { defaultPathArgs, ensureArgsExist, RepositoryCommandArgs } from "../command.js"; | ||
import { writeFilePretty } from "../prettier.js"; | ||
import { Runtime } from "../runtime.js"; | ||
import { ShenanigansPackage } from "../typings.js"; | ||
import { | ||
@@ -14,3 +15,3 @@ getDependencyNamesAndExternalsOfPackage, | ||
parseFileJson, | ||
} from "../utils"; | ||
} from "../utils.js"; | ||
@@ -41,5 +42,10 @@ /** | ||
const basePackageJson = await parseFileJson<ShenanigansPackage>(basePackagePath); | ||
const nodeModules = basePackageJson.shenanigans.external | ||
? "../node_modules" | ||
: "../../../node_modules"; | ||
const { externals, dependencyNames } = await getDependencyNamesAndExternalsOfPackage( | ||
basePackagePath | ||
basePackagePath, | ||
nodeModules, | ||
!!basePackageJson.shenanigans.game | ||
); | ||
@@ -58,11 +64,19 @@ const testPaths = ( | ||
...basePackageJson, | ||
dependenciesBase: nodeModules, | ||
dependencyNames, | ||
devDependencyNames: Object.keys(basePackageJson.devDependencies || {}), | ||
devDependencyNames: Object.keys(basePackageJson.devDependencies ?? {}), | ||
externals, | ||
externalsRaw: (basePackageJson.shenanigans.loading?.externals || []).map((external) => | ||
externalsDist: (basePackageJson.shenanigans.loading?.externals ?? []) | ||
.filter((external) => !!external.js.prod) | ||
.map((external) => JSON.stringify(external, null, 4)), | ||
externalsRaw: (basePackageJson.shenanigans.loading?.externals ?? []).map((external) => | ||
JSON.stringify(external, null, 4) | ||
), | ||
nodeModules: basePackageJson.shenanigans.external | ||
? "../node_modules" | ||
: "../../../node_modules", | ||
nodeModules, | ||
resolveAliasBase: basePackageJson.shenanigans.example | ||
? "../../packages" | ||
: nodeModules.slice("../".length), | ||
shenanigansPackage: basePackageJson.shenanigans.example | ||
? "../../../packages" | ||
: nodeModules, | ||
shorthand: [...basePackageJson.shenanigans.name] | ||
@@ -69,0 +83,0 @@ .filter((c) => c.toUpperCase() === c) |
import * as cp from "mz/child_process"; | ||
import * as path from "path"; | ||
import { defaultPathArgs, RepositoryCommandArgs } from "../command"; | ||
import { Runtime } from "../runtime"; | ||
import { Shell } from "../shell"; | ||
import { parseFileJson } from "../utils"; | ||
import { defaultPathArgs, RepositoryCommandArgs } from "../command.js"; | ||
import { Runtime } from "../runtime.js"; | ||
import { Shell } from "../shell.js"; | ||
import { ShenanigansPackage } from "../typings.js"; | ||
import { parseFileJson } from "../utils.js"; | ||
const tryGetRegistryVersion = async (cwd: string) => { | ||
try { | ||
return (await cp.exec("npm show . version", { cwd })) | ||
.filter(Boolean) | ||
.join("") | ||
.trim(); | ||
} catch { | ||
return undefined; | ||
} | ||
} | ||
/** | ||
@@ -30,10 +20,7 @@ * Publishes a package if its version doesn't match the npm registry's | ||
); | ||
const registryVersion = await tryGetRegistryVersion(cwd); | ||
const registryVersion = (await cp.exec("npm show . version", { cwd })) | ||
.filter(Boolean) | ||
.join("") | ||
.trim(); | ||
runtime.logger.log( | ||
registryVersion | ||
? `Found registry version '${registryVersion}'` | ||
: "No registry version found.", | ||
); | ||
if (localVersion === registryVersion) { | ||
@@ -46,3 +33,3 @@ runtime.logger.log( | ||
await new Shell(runtime.logger,).setCwd(cwd).execute("npm publish"); | ||
await new Shell(runtime.logger).setCwd(cwd).execute("npm publish"); | ||
}; |
@@ -1,6 +0,6 @@ | ||
import * as fs from "mz/fs"; | ||
import { existsSync } from "fs"; | ||
import * as path from "path"; | ||
import { Command } from "./command"; | ||
import { NameTransformer } from "./nameTransformer"; | ||
import { Command } from "./command.js"; | ||
import { NameTransformer } from "./nameTransformer.js"; | ||
@@ -43,10 +43,10 @@ /** | ||
public async search<TCommand extends Command>(name: string): Promise<TCommand | undefined> { | ||
const camelCaseName: string = this.nameTransformer.toCamelCase(name); | ||
const camelCaseName = this.nameTransformer.toCamelCase(name); | ||
for (const directory of this.directories) { | ||
const joinedPath: string = path.join(directory, `${camelCaseName}.js`); | ||
const joinedPath = path.join(directory, `${camelCaseName}.js`); | ||
if (await fs.exists(joinedPath)) { | ||
// eslint-disable-next-line @typescript-eslint/no-var-requires | ||
return require(joinedPath)[this.nameTransformer.toPascalCase(name)]; | ||
if (existsSync(joinedPath)) { | ||
// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access | ||
return (await import(joinedPath))[this.nameTransformer.toPascalCase(name)]; | ||
} | ||
@@ -53,0 +53,0 @@ } |
import chalk from "chalk"; | ||
import { fs } from "mz"; | ||
import { existsSync, promises as fs } from "fs"; | ||
import * as path from "path"; | ||
import { RepositoryCommandArgs } from "./command"; | ||
import { Mustache } from "./commands/mustache"; | ||
import { Runtime } from "./runtime"; | ||
import { globAsync, mkdirpSafe, setupDir } from "./utils"; | ||
import { RepositoryCommandArgs } from "./command.js"; | ||
import { Mustache } from "./commands/mustache.js"; | ||
import { setupDirName } from "./directories.js"; | ||
import { Runtime } from "./runtime.js"; | ||
import { globAsync, mkdirpSafe } from "./utils.js"; | ||
const nonTextFileExtensions = new Set([".eot", ".gif", ".jpg", ".png", ".svg", ".ttf", ".woff"]); | ||
const nonTextFileExtensions = new Set([".gif", ".jpg", ".png", ".svg", ".woff2"]); | ||
@@ -21,11 +22,11 @@ /** | ||
) => { | ||
const files = await globAsync(path.join(setupDir, directory, "*")); | ||
const files = await globAsync(path.join(setupDirName, directory, "*")); | ||
await Promise.all( | ||
files.map(async (setupFile) => { | ||
if (fs.statSync(setupFile).isDirectory()) { | ||
if ((await fs.stat(setupFile)).isDirectory()) { | ||
return await copyTemplatesRecursive( | ||
runtime, | ||
args, | ||
setupFile.slice(setupDir.length), | ||
setupFile.slice(setupDirName.length), | ||
rootDirectory | ||
@@ -43,2 +44,7 @@ ); | ||
await mkdirpSafe(path.dirname(outputAbsolute)); | ||
if (existsSync(outputAbsolute)) { | ||
await fs.rm(outputAbsolute); | ||
} | ||
await fs.copyFile(setupFile, outputAbsolute); | ||
@@ -45,0 +51,0 @@ } else { |
import chalk from "chalk"; | ||
import { Logger, OnSetCwdInfo } from "../logger"; | ||
import { Logger, OnSetCwdInfo } from "../logger.js"; | ||
@@ -5,0 +5,0 @@ /** |
@@ -27,3 +27,3 @@ /** | ||
/** | ||
* Transforms a dashed-case name to PamelCase. | ||
* Transforms a dashed-case name to PascalCase. | ||
* | ||
@@ -59,3 +59,3 @@ * @param name A dashed-case name. | ||
if (output[output.length - 1] === "-") { | ||
if (output.endsWith("-")) { | ||
output = output.substring(0, output.length - 1); | ||
@@ -62,0 +62,0 @@ } |
@@ -1,8 +0,9 @@ | ||
import * as fs from "mz/fs"; | ||
import { promises as fs } from "fs"; | ||
import * as path from "path"; | ||
import prettier from "prettier"; | ||
import { setupDir } from "./utils"; | ||
import { setupDirName } from "./directories.js"; | ||
const supportInfo = prettier.getSupportInfo(); | ||
let prettierOptions: prettier.Options; | ||
let prettierOptions: prettier.Options | undefined; | ||
@@ -19,3 +20,5 @@ const prettifyIfPossible = async (fileName: string, contents: string) => { | ||
if (!prettierOptions) { | ||
const rawPrettierOptions = await fs.readFile(path.join(setupDir, "external/.prettierrc")); | ||
const rawPrettierOptions = await fs.readFile( | ||
path.join(setupDirName, "external/.prettierrc") | ||
); | ||
prettierOptions = await JSON.parse(rawPrettierOptions.toString()); | ||
@@ -22,0 +25,0 @@ } |
@@ -1,4 +0,4 @@ | ||
import { CommandSearcher } from "./commandSearcher"; | ||
import { Logger } from "./logger"; | ||
import { Runtime } from "./runtime"; | ||
import { CommandArgs } from "./command.js"; | ||
import { CommandSearcher } from "./commandSearcher.js"; | ||
import { Logger } from "./logger.js"; | ||
@@ -12,3 +12,3 @@ /** | ||
*/ | ||
args: any; | ||
args: CommandArgs; | ||
@@ -50,3 +50,3 @@ /** | ||
*/ | ||
public async run(runSettings: RunSettings): Promise<boolean> { | ||
public async run(runSettings: RunSettings) { | ||
const command = await this.commandSearcher.search(runSettings.commandName); | ||
@@ -57,10 +57,11 @@ if (!command) { | ||
const runtime: Runtime = { | ||
logger: runSettings.logger, | ||
}; | ||
await command( | ||
{ | ||
logger: runSettings.logger, | ||
}, | ||
runSettings.args | ||
); | ||
await command(runtime, runSettings.args); | ||
return true; | ||
} | ||
} |
@@ -1,2 +0,2 @@ | ||
import { Logger } from "./logger"; | ||
import { Logger } from "./logger.js"; | ||
@@ -3,0 +3,0 @@ /** |
@@ -5,3 +5,3 @@ import chalk from "chalk"; | ||
import { Logger } from "./logger"; | ||
import { Logger } from "./logger.js"; | ||
@@ -12,6 +12,6 @@ const isWindows = () => process.platform === "win32"; | ||
? { | ||
git: "git.exe", | ||
npm: "npm.cmd", | ||
yarn: "yarn.cmd", | ||
} | ||
git: "git.exe", | ||
npm: "npm.cmd", | ||
yarn: "yarn.cmd", | ||
} | ||
: {}; | ||
@@ -58,3 +58,3 @@ | ||
const cwd: string = path.resolve(path.join(...pathComponents)); | ||
const cwd = path.resolve(path.join(...pathComponents)); | ||
this.cwd = cwd; | ||
@@ -77,4 +77,3 @@ | ||
const [command, ...args] = fullCommand.split(" "); | ||
const commandAlias = | ||
commandAliases[command] !== undefined ? (commandAliases[command] as string) : command; | ||
const commandAlias = commandAliases[command] ?? command; | ||
@@ -86,3 +85,2 @@ this.logger.log(chalk.grey(`> ${commandAlias} ${args.join(" ")}`)); | ||
cwd: this.cwd, | ||
env: process.env, | ||
stdio: "inherit", | ||
@@ -89,0 +87,0 @@ }); |
@@ -1,10 +0,6 @@ | ||
interface Dictionary<TValue> { | ||
[i: string]: TValue; | ||
} | ||
interface NpmPackage { | ||
export interface NpmPackage { | ||
/** | ||
* Package dependencies to run in production. | ||
*/ | ||
dependencies?: { [i: string]: string }; | ||
dependencies?: Record<string, string>; | ||
@@ -14,3 +10,3 @@ /** | ||
*/ | ||
devDependencies?: { [i: string]: string }; | ||
devDependencies?: Record<string, string>; | ||
@@ -25,3 +21,3 @@ /** | ||
*/ | ||
scripts: Dictionary<string>; | ||
scripts: Record<string, string>; | ||
} | ||
@@ -32,3 +28,3 @@ | ||
*/ | ||
interface ShenanigansPackage extends NpmPackage { | ||
export interface ShenanigansPackage extends NpmPackage { | ||
/** | ||
@@ -39,3 +35,3 @@ * Shenanigans-specific settings for the project. | ||
[i: string]: string | Dictionary<string> | ShenanigansSchema | undefined; | ||
[i: string]: string | Record<string, string> | ShenanigansSchema | undefined; | ||
} | ||
@@ -46,3 +42,3 @@ | ||
*/ | ||
interface ShenanigansSchema { | ||
export interface ShenanigansSchema { | ||
/** | ||
@@ -54,2 +50,7 @@ * Whether to include a webpack-bundled dist/ directory. | ||
/** | ||
* Whether this is an example project located in the EightBittr monorepo. | ||
*/ | ||
example?: boolean; | ||
/** | ||
* Whether to include dependencies to instantiate a EightBittr game. | ||
@@ -83,3 +84,3 @@ */ | ||
*/ | ||
interface PackageLoading { | ||
export interface PackageLoading { | ||
/** | ||
@@ -99,3 +100,3 @@ * Additional webpack entry points. | ||
*/ | ||
interface Entry { | ||
export interface Entry { | ||
/** | ||
@@ -120,3 +121,3 @@ * Entry file point for webpack. | ||
*/ | ||
interface External { | ||
export interface External { | ||
/** | ||
@@ -136,3 +137,3 @@ * Scripts the dependency needs to bring in. | ||
*/ | ||
interface ExternalScripts { | ||
export interface ExternalScripts { | ||
/** | ||
@@ -139,0 +140,0 @@ * Development version of the script. |
import chalk from "chalk"; | ||
import { existsSync, promises as fs } from "fs"; | ||
import glob from "glob"; | ||
import mkdirp from "mkdirp"; | ||
import * as fs from "mz/fs"; | ||
import * as path from "path"; | ||
import { RepositoryCommandArgs } from "./command"; | ||
import { Logger } from "./logger"; | ||
import { RepositoryCommandArgs } from "./command.js"; | ||
import { Logger } from "./logger.js"; | ||
import { ShenanigansPackage } from "./typings.js"; | ||
export const setupDir = path.join(__dirname, "../setup"); | ||
export const mkdirpSafe = async (dir: string) => { | ||
@@ -16,3 +15,3 @@ try { | ||
} catch { | ||
// Ignore errors: t's fine for the folder to already exist | ||
// Ignore errors: it's fine for the folder to already exist | ||
} | ||
@@ -31,7 +30,10 @@ }; | ||
logger: Logger | ||
): Promise<{ [i: string]: string }> => { | ||
): Promise<Record<string, string>> => { | ||
const packagePath = path.join(...repository, "package.json"); | ||
try { | ||
return JSON.parse((await fs.readFile(packagePath)).toString()).dependencies || {}; | ||
return ( | ||
(JSON.parse((await fs.readFile(packagePath)).toString()) as ShenanigansPackage) | ||
.dependencies ?? {} | ||
); | ||
} catch (error) { | ||
@@ -82,6 +84,9 @@ logger.log(chalk.red("Could not parse", packagePath)); | ||
* @param basePackageLocation Location of a package's package.json. | ||
* @param game Whether this should include dependencies for games. | ||
* @returns Promise for the names of all the package's dependencies. | ||
*/ | ||
export const getDependencyNamesAndExternalsOfPackage = async ( | ||
basePackageLocation: string | ||
basePackageLocation: string, | ||
nodeModules: string, | ||
game: boolean | ||
): Promise<DependencyNamesAndExternals> => { | ||
@@ -101,21 +106,23 @@ const { dependencies, shenanigans } = await parseFileJson<Partial<ShenanigansPackage>>( | ||
const externalsRaw = shenanigans.loading?.externals ?? []; | ||
const externals = externalsRaw.map( | ||
(external: External): string => `"${external.name}": "${external.js.dev}"` | ||
); | ||
const externals = externalsRaw.map((external) => `"${external.name}": "${external.js.dev}"`); | ||
const allDependencyNames = Object.keys(dependencies); | ||
for (let i = 0; i < allDependencyNames.length; i += 1) { | ||
const localDependency = allDependencyNames[i]; | ||
for (const localDependency of allDependencyNames) { | ||
const modulePackageLocation = path.normalize( | ||
basePackageLocation.replace( | ||
"package.json", | ||
`node_modules/${localDependency}/package.json` | ||
`${nodeModules}/${localDependency}/package.json` | ||
) | ||
); | ||
if (await fs.exists(modulePackageLocation)) { | ||
if (existsSync(modulePackageLocation)) { | ||
allDependencyNames.push( | ||
...(await getDependencyNamesAndExternalsOfPackage(modulePackageLocation)) | ||
.dependencyNames | ||
...( | ||
await getDependencyNamesAndExternalsOfPackage( | ||
modulePackageLocation, | ||
nodeModules, | ||
game | ||
) | ||
).dependencyNames | ||
); | ||
@@ -125,3 +132,28 @@ } | ||
const dependencyNames = Array.from(new Set(allDependencyNames)) | ||
const dependencyNames = Array.from( | ||
new Set([ | ||
...allDependencyNames, | ||
...(game | ||
? [ | ||
// TODO: it would be nice to load these dynamically... | ||
"actorhittr", | ||
"areaspawnr", | ||
"autofieldr", | ||
"fpsanalyzr", | ||
"frametickr", | ||
"groupholdr", | ||
"inputwritr", | ||
"itemsholdr", | ||
"mapscreatr", | ||
"mapscreenr", | ||
"objectmakr", | ||
"pixeldrawr", | ||
"pixelrendr", | ||
"quadskeepr", | ||
"stringfilr", | ||
"timehandlr", | ||
] | ||
: []), | ||
]) | ||
) | ||
.filter((dependencyName) => dependencyName !== "requirejs") | ||
@@ -128,0 +160,0 @@ .filter( |
@@ -6,6 +6,6 @@ { | ||
"esModuleInterop": true, | ||
"module": "commonjs", | ||
"module": "ESNext", | ||
"outDir": "./lib", | ||
"rootDir": "./src", | ||
"target": "es2016" | ||
"target": "ES2021" | ||
}, | ||
@@ -12,0 +12,0 @@ "exclude": ["**/*.d.ts", "**/lib", "./setup/**/*"], |
Native code
Supply chain riskContains native code (e.g., compiled binaries or shared libraries). Including native code can obscure malicious behavior.
Found 1 instance in 1 package
Shell access
Supply chain riskThis module accesses the system shell. Accessing the system shell increases the risk of executing arbitrary code.
Found 1 instance in 1 package
Dynamic require
Supply chain riskDynamic require can indicate the package is performing dangerous or unsafe dynamic code execution.
Found 1 instance in 1 package
Environment variable access
Supply chain riskPackage accesses environment variables, which may be a sign of credential stuffing or data theft.
Found 1 instance in 1 package
0
0
Yes
63097
56
1680
+ Addedbrace-expansion@2.0.1(transitive)
+ Addedchalk@5.4.1(transitive)
+ Addedglob@8.1.0(transitive)
+ Addedminimatch@5.1.6(transitive)
- Removedansi-styles@4.3.0(transitive)
- Removedchalk@4.1.2(transitive)
- Removedcolor-convert@2.0.1(transitive)
- Removedcolor-name@1.1.4(transitive)
- Removedhas-flag@4.0.0(transitive)
- Removedsupports-color@7.2.0(transitive)
Updated@types/prettier@^2.7.0
Updatedchalk@^5.0.1
Updatedchokidar@^3.5.3
Updatedglob@^8.0.3
Updatedminimist@^1.2.6
Updatedmoment@^2.29.4
Updatedmustache@^4.2.0
Updatedprettier@^2.7.1