├── .eslintignore ├── .eslintrc.cjs ├── .gitattributes ├── .github ├── FUNDING.yml └── workflows │ ├── build.yml │ ├── deploy.yml │ └── pr.yml ├── .gitignore ├── .moon ├── tasks.yml ├── toolchain.yml └── workspace.yml ├── .prettierignore ├── .yarn ├── patches │ └── ink-testing-library-npm-3.0.0-c20aad0bd9.patch └── releases │ └── yarn-4.1.0.cjs ├── .yarnrc.yml ├── CHANGELOG.md ├── LICENSE ├── README.md ├── lerna.json ├── package.json ├── packages ├── args │ ├── CHANGELOG.md │ ├── LICENSE │ ├── README.md │ ├── package.json │ ├── src │ │ ├── ArgsError.ts │ │ ├── Checker.ts │ │ ├── ParseError.ts │ │ ├── Scope.ts │ │ ├── ValidationError.ts │ │ ├── constants.ts │ │ ├── debug.ts │ │ ├── format.ts │ │ ├── helpers │ │ │ ├── castValue.ts │ │ │ ├── createScope.ts │ │ │ ├── expandShortOption.ts │ │ │ ├── formatValue.ts │ │ │ ├── getDefaultValue.ts │ │ │ ├── isCommand.ts │ │ │ ├── isLongOption.ts │ │ │ ├── isOptionLike.ts │ │ │ ├── isShortOption.ts │ │ │ ├── isShortOptionGroup.ts │ │ │ ├── mapParserOptions.ts │ │ │ └── processShortOptionGroup.ts │ │ ├── index.ts │ │ ├── parse.ts │ │ ├── parseInContext.ts │ │ └── types.ts │ ├── tests │ │ ├── __fixtures__ │ │ │ └── options.ts │ │ ├── format.test.ts │ │ ├── parse.test.ts │ │ └── parseInContext.test.ts │ ├── tsconfig.json │ └── tsconfig.mjs.json ├── cli │ ├── .eslintrc.cjs │ ├── CHANGELOG.md │ ├── LICENSE │ ├── README.md │ ├── __mocks__ │ │ └── term-size.js │ ├── examples │ │ ├── .eslintrc.cjs │ │ ├── bin.mjs │ │ ├── commands │ │ │ ├── BuildCommand.mjs │ │ │ ├── ConfirmCommand.mjs │ │ │ ├── ErrorCommand.mjs │ │ │ ├── ErrorCompCommand.mjs │ │ │ ├── ExitCommand.mjs │ │ │ ├── ExitCompCommand.mjs │ │ │ ├── InputCommand.mjs │ │ │ ├── LoggerCommand.mjs │ │ │ ├── MultiSelectCommand.mjs │ │ │ ├── OptionsCommand.mjs │ │ │ ├── ParamsCommand.mjs │ │ │ ├── ScaffoldCommand.mjs │ │ │ ├── SelectCommand.mjs │ │ │ └── scaffold │ │ │ │ ├── ScaffoldControllerCommand.mjs │ │ │ │ ├── ScaffoldModelCommand.mjs │ │ │ │ └── ScaffoldViewCommand.mjs │ │ ├── random.mjs │ │ └── sleep.mjs │ ├── moon.yml │ ├── package.json │ ├── res │ │ └── en │ │ │ ├── cli.yml │ │ │ └── prompt.yml │ ├── src │ │ ├── CLIError.ts │ │ ├── Command.ts │ │ ├── CommandManager.ts │ │ ├── LogBuffer.ts │ │ ├── Program.ts │ │ ├── ProgramContext.ts │ │ ├── components │ │ │ ├── Confirm.tsx │ │ │ ├── Failure.tsx │ │ │ ├── Header.tsx │ │ │ ├── Help.tsx │ │ │ ├── HiddenInput.tsx │ │ │ ├── IndexHelp.tsx │ │ │ ├── Input.tsx │ │ │ ├── MultiSelect.tsx │ │ │ ├── PasswordInput.tsx │ │ │ ├── Select.tsx │ │ │ ├── Style.tsx │ │ │ ├── index.ts │ │ │ └── internal │ │ │ │ ├── Cursor.tsx │ │ │ │ ├── DividerRow.tsx │ │ │ │ ├── HelpCommands.tsx │ │ │ │ ├── HelpOptions.tsx │ │ │ │ ├── HelpParams.tsx │ │ │ │ ├── HelpUsage.tsx │ │ │ │ ├── Label.tsx │ │ │ │ ├── LogWriter.ts │ │ │ │ ├── OptionRow.tsx │ │ │ │ ├── Prompt.tsx │ │ │ │ ├── ScrollableList.tsx │ │ │ │ ├── Selected.tsx │ │ │ │ └── Wrapper.tsx │ │ ├── constants.ts │ │ ├── decorators │ │ │ ├── Config.ts │ │ │ ├── Flag.ts │ │ │ ├── Number.ts │ │ │ ├── Numbers.ts │ │ │ ├── Params.ts │ │ │ ├── String.ts │ │ │ ├── Strings.ts │ │ │ └── index.ts │ │ ├── helpers │ │ │ ├── applyMarkdown.ts │ │ │ ├── applyStyle.ts │ │ │ ├── formatCommandCall.ts │ │ │ ├── formatDescription.ts │ │ │ ├── formatType.ts │ │ │ ├── formatValue.ts │ │ │ ├── getLongestWidth.ts │ │ │ ├── groupByCategory.ts │ │ │ ├── index.ts │ │ │ ├── isArgvSize.ts │ │ │ ├── isNodeBinary.ts │ │ │ ├── loadTheme.ts │ │ │ ├── mapCommandMetadata.ts │ │ │ └── patchDebugModule.ts │ │ ├── hooks │ │ │ ├── index.ts │ │ │ ├── useDimensions.ts │ │ │ ├── useIsMounted.ts │ │ │ ├── useListNavigation.ts │ │ │ ├── useProgram.ts │ │ │ └── useRenderLoop.ts │ │ ├── index.ts │ │ ├── initializers │ │ │ ├── flag.ts │ │ │ ├── index.ts │ │ │ ├── number.ts │ │ │ ├── numbers.ts │ │ │ ├── params.ts │ │ │ ├── string.ts │ │ │ └── strings.ts │ │ ├── metadata │ │ │ ├── args.ts │ │ │ ├── blueprints.ts │ │ │ ├── createOptionDecorator.ts │ │ │ ├── createOptionInitializer.ts │ │ │ ├── getConstructor.ts │ │ │ ├── getInheritedCategories.ts │ │ │ ├── getInheritedOptions.ts │ │ │ ├── globalOptions.ts │ │ │ ├── registerOption.ts │ │ │ ├── registerParams.ts │ │ │ ├── validateConfig.ts │ │ │ ├── validateOptions.ts │ │ │ └── validateParams.ts │ │ ├── middleware │ │ │ ├── checkNodeRequirement.ts │ │ │ ├── checkPackageOutdated.ts │ │ │ ├── index.ts │ │ │ └── removeProcessBin.ts │ │ ├── react.ts │ │ ├── test.ts │ │ ├── translate.ts │ │ └── types.ts │ ├── tests │ │ ├── Command.test.ts │ │ ├── Failure.test.tsx │ │ ├── Header.test.tsx │ │ ├── Help.test.tsx │ │ ├── IndexHelp.test.tsx │ │ ├── LogBuffer.test.ts │ │ ├── Program.test.tsx │ │ ├── Style.test.tsx │ │ ├── __fixtures__ │ │ │ ├── AllDecoratorCommand.ts │ │ │ ├── AllInitializerCommand.ts │ │ │ ├── AllPropsCommand.ts │ │ │ ├── BuildDecoratorCommand.ts │ │ │ ├── BuildInitializerCommand.ts │ │ │ ├── BuildPropsCommand.ts │ │ │ ├── ClientDecoratorCommand.ts │ │ │ ├── InstallDecoratorCommand.ts │ │ │ ├── InstallInitializerCommand.ts │ │ │ ├── InstallPropsCommand.ts │ │ │ ├── args.ts │ │ │ └── commands.ts │ │ ├── __snapshots__ │ │ │ ├── Failure.test.tsx.snap │ │ │ ├── Header.test.tsx.snap │ │ │ ├── Help.test.tsx.snap │ │ │ ├── IndexHelp.test.tsx.snap │ │ │ ├── Program.test.tsx.snap │ │ │ └── Style.test.tsx.snap │ │ ├── components │ │ │ ├── Confirm.test.tsx │ │ │ ├── HiddenInput.test.tsx │ │ │ ├── Input.test.tsx │ │ │ ├── MultiSelect.test.tsx │ │ │ ├── PasswordInput.test.tsx │ │ │ ├── Select.test.tsx │ │ │ ├── __snapshots__ │ │ │ │ ├── Confirm.test.tsx.snap │ │ │ │ ├── HiddenInput.test.tsx.snap │ │ │ │ ├── Input.test.tsx.snap │ │ │ │ ├── MultiSelect.test.tsx.snap │ │ │ │ ├── PasswordInput.test.tsx.snap │ │ │ │ └── Select.test.tsx.snap │ │ │ └── internal │ │ │ │ ├── Cursor.test.tsx │ │ │ │ ├── Label.test.tsx │ │ │ │ ├── Prompt.test.tsx │ │ │ │ ├── ScrollableList.test.tsx │ │ │ │ └── __snapshots__ │ │ │ │ ├── Cursor.test.tsx.snap │ │ │ │ ├── Label.test.tsx.snap │ │ │ │ ├── Prompt.test.tsx.snap │ │ │ │ └── ScrollableList.test.tsx.snap │ │ ├── helpers.ts │ │ ├── helpers │ │ │ ├── isArgvSize.test.ts │ │ │ ├── isNodeBinary.test.ts │ │ │ ├── loadTheme.test.ts │ │ │ └── patchDebugModule.test.ts │ │ ├── hooks │ │ │ ├── __snapshots__ │ │ │ │ └── useProgram.test.tsx.snap │ │ │ └── useProgram.test.tsx │ │ └── middleware │ │ │ └── checkPackageOutdated.test.ts │ ├── tsconfig.json │ └── tsconfig.mjs.json ├── common │ ├── CHANGELOG.md │ ├── LICENSE │ ├── README.md │ ├── package.json │ ├── src │ │ ├── CommonError.ts │ │ ├── Contract.ts │ │ ├── ExitError.ts │ │ ├── ModulePath.ts │ │ ├── PackageGraph.ts │ │ ├── Path.ts │ │ ├── PathResolver.ts │ │ ├── Project.ts │ │ ├── VirtualPath.ts │ │ ├── constants.ts │ │ ├── helpers │ │ │ ├── createBlueprint.ts │ │ │ ├── deepFreeze.ts │ │ │ ├── deepMerge.ts │ │ │ ├── formatMs.ts │ │ │ ├── index.ts │ │ │ ├── instanceOf.ts │ │ │ ├── isEmpty.ts │ │ │ ├── isFilePath.ts │ │ │ ├── isModuleName.ts │ │ │ ├── isObject.ts │ │ │ ├── isPlainObject.ts │ │ │ └── toArray.ts │ │ ├── index.ts │ │ ├── optimal.ts │ │ ├── serializers │ │ │ ├── json.ts │ │ │ └── yaml.ts │ │ ├── test.ts │ │ └── types.ts │ ├── tests │ │ ├── Contract.test.ts │ │ ├── ExitError.test.ts │ │ ├── ModulePath.test.ts │ │ ├── PackageGraph.test.ts │ │ ├── Path.test.ts │ │ ├── PathResolver.test.ts │ │ ├── Project.test.ts │ │ ├── VirtualPath.test.ts │ │ ├── __snapshots__ │ │ │ └── Contract.test.ts.snap │ │ ├── helpers │ │ │ ├── __fixtures__ │ │ │ │ ├── default-export.ts │ │ │ │ ├── default-named-exports.ts │ │ │ │ ├── imports.ts │ │ │ │ └── named-exports.ts │ │ │ ├── __snapshots__ │ │ │ │ └── deepFreeze.test.ts.snap │ │ │ ├── createBlueprint.test.ts │ │ │ ├── deepFreeze.test.ts │ │ │ ├── deepMerge.test.ts │ │ │ ├── formatMs.test.ts │ │ │ ├── instanceOf.test.ts │ │ │ ├── isEmpty.test.ts │ │ │ ├── isFilePath.test.ts │ │ │ ├── isModuleName.test.ts │ │ │ ├── isObject.test.ts │ │ │ ├── isPlainObject.test.ts │ │ │ └── toArray.test.ts │ │ └── serializers │ │ │ ├── __fixtures__ │ │ │ ├── test.json │ │ │ └── test.yaml │ │ │ ├── json.test.ts │ │ │ └── yaml.test.ts │ ├── tsconfig.json │ └── tsconfig.mjs.json ├── config │ ├── CHANGELOG.md │ ├── LICENSE │ ├── README.md │ ├── package.json │ ├── src │ │ ├── Cache.ts │ │ ├── ConfigError.ts │ │ ├── ConfigFinder.ts │ │ ├── Configuration.ts │ │ ├── Finder.ts │ │ ├── IgnoreFinder.ts │ │ ├── Processor.ts │ │ ├── constants.ts │ │ ├── helpers │ │ │ ├── createFileName.ts │ │ │ ├── getEnv.ts │ │ │ ├── mergeArray.ts │ │ │ ├── mergeExtends.ts │ │ │ ├── mergeObject.ts │ │ │ ├── mergePlugins.ts │ │ │ └── overwrite.ts │ │ ├── index.ts │ │ ├── loaders │ │ │ ├── cjs.ts │ │ │ ├── js.ts │ │ │ ├── json.ts │ │ │ ├── mjs.ts │ │ │ ├── ts.ts │ │ │ └── yaml.ts │ │ ├── schemas.ts │ │ └── types.ts │ ├── tests │ │ ├── Cache.test.ts │ │ ├── ConfigFinder.test.ts │ │ ├── Configuration.test.ts │ │ ├── IgnoreFinder.test.ts │ │ ├── Processor.test.ts │ │ ├── __snapshots__ │ │ │ ├── ConfigFinder.test.ts.snap │ │ │ ├── IgnoreFinder.test.ts.snap │ │ │ └── Processor.test.ts.snap │ │ ├── helpers.ts │ │ └── helpers │ │ │ ├── getEnv.test.ts │ │ │ ├── mergeArray.test.ts │ │ │ ├── mergeExtends.test.ts │ │ │ ├── mergeObject.test.ts │ │ │ ├── mergePlugins.test.ts │ │ │ └── overwrite.test.ts │ ├── tsconfig.json │ └── tsconfig.mjs.json ├── debug │ ├── CHANGELOG.md │ ├── LICENSE │ ├── README.md │ ├── package.json │ ├── src │ │ ├── CrashReporter.ts │ │ ├── createDebugger.ts │ │ ├── debug.ts │ │ ├── index.ts │ │ ├── test.ts │ │ └── types.ts │ ├── tests │ │ ├── CrashReporter.test.ts │ │ ├── __snapshots__ │ │ │ └── CrashReporter.test.ts.snap │ │ └── createDebugger.test.ts │ ├── tsconfig.json │ └── tsconfig.mjs.json ├── decorators │ ├── .eslintrc.cjs │ ├── CHANGELOG.md │ ├── LICENSE │ ├── README.md │ ├── moon.yml │ ├── package.json │ ├── src │ │ ├── Bind.ts │ │ ├── Debounce.ts │ │ ├── Deprecate.ts │ │ ├── Memoize.ts │ │ ├── Throttle.ts │ │ ├── helpers │ │ │ ├── isClass.ts │ │ │ ├── isMethod.ts │ │ │ ├── isParam.ts │ │ │ └── isProperty.ts │ │ └── index.ts │ ├── tests │ │ ├── Bind.test.ts │ │ ├── Debounce.test.ts │ │ ├── Deprecate.test.ts │ │ ├── Memoize.test.ts │ │ └── Throttle.test.ts │ ├── tsconfig.esm.json │ ├── tsconfig.json │ └── tsconfig.mjs.json ├── event │ ├── CHANGELOG.md │ ├── LICENSE │ ├── README.md │ ├── package.json │ ├── src │ │ ├── BailEvent.ts │ │ ├── BaseEvent.ts │ │ ├── ConcurrentEvent.ts │ │ ├── Event.ts │ │ ├── EventError.ts │ │ ├── WaterfallEvent.ts │ │ ├── constants.ts │ │ ├── debug.ts │ │ ├── index.ts │ │ └── types.ts │ ├── tests │ │ ├── BailEvent.test.ts │ │ ├── BaseEvent.test.ts │ │ ├── ConcurrentEvent.test.ts │ │ ├── Event.test.ts │ │ ├── WaterfallEvent.test.ts │ │ └── __snapshots__ │ │ │ └── BaseEvent.test.ts.snap │ ├── tsconfig.esm.json │ ├── tsconfig.json │ └── tsconfig.mjs.json ├── internal │ ├── CHANGELOG.md │ ├── LICENSE │ ├── README.md │ ├── package.json │ ├── src │ │ ├── browser.ts │ │ ├── color.ts │ │ ├── createInternalDebugger.ts │ │ ├── createScopedError.ts │ │ ├── env.ts │ │ ├── importAbsoluteModule.ts │ │ ├── index.ts │ │ └── interopDefault.ts │ ├── tests │ │ └── createInternalDebugger.test.ts │ ├── tsconfig.esm.json │ ├── tsconfig.json │ └── tsconfig.mjs.json ├── log │ ├── CHANGELOG.md │ ├── LICENSE │ ├── README.md │ ├── package.json │ ├── res │ │ └── en │ │ │ └── log.yaml │ ├── src │ │ ├── Logger.ts │ │ ├── Transport.ts │ │ ├── constants.ts │ │ ├── createLogger.ts │ │ ├── debug.ts │ │ ├── formats.ts │ │ ├── index.ts │ │ ├── test.ts │ │ ├── translate.ts │ │ ├── transports │ │ │ ├── ConsoleTransport.ts │ │ │ ├── FileTransport.ts │ │ │ ├── RotatingFileTransport.ts │ │ │ └── StreamTransport.ts │ │ └── types.ts │ ├── tests │ │ ├── Logger.test.ts │ │ ├── createLogger.test.ts │ │ ├── formats.test.ts │ │ └── transports │ │ │ ├── FileTransport.test.ts │ │ │ ├── RotatingFileTransport.test.ts │ │ │ └── helpers.ts │ ├── tsconfig.json │ └── tsconfig.mjs.json ├── module │ ├── CHANGELOG.md │ ├── LICENSE │ ├── README.md │ ├── moon.yml │ ├── package.json │ ├── src │ │ ├── hooks │ │ │ ├── index.ts │ │ │ └── typescript.ts │ │ ├── index.ts │ │ ├── interopModule.ts │ │ ├── requireModule.ts │ │ ├── requireTSModule.ts │ │ ├── types.ts │ │ └── typescript.ts │ ├── tests │ │ ├── __fixtures__ │ │ │ ├── .eslintrc.cjs │ │ │ ├── default-export.ts │ │ │ ├── default-named-exports.ts │ │ │ ├── format-cjs.cjs │ │ │ ├── format-js.js │ │ │ ├── format-mjs.mjs │ │ │ ├── format-ts.ts │ │ │ ├── format-tsx.tsx │ │ │ ├── imports.ts │ │ │ └── named-exports.ts │ │ ├── commonjs.assert.cjs │ │ ├── commonjs.assert.mjs │ │ ├── helpers.ts │ │ ├── hook-tester.cjs │ │ ├── hook.assert.mjs │ │ ├── requireModule.test.ts │ │ └── requireTSModule.test.ts │ ├── tsconfig.cjs.json │ ├── tsconfig.json │ └── tsconfig.mjs.json ├── pipeline │ ├── .eslintrc.cjs │ ├── CHANGELOG.md │ ├── LICENSE │ ├── README.md │ ├── package.json │ ├── src │ │ ├── AggregatedPipeline.ts │ │ ├── ConcurrentPipeline.ts │ │ ├── Context.ts │ │ ├── Monitor.ts │ │ ├── ParallelPipeline.ts │ │ ├── Pipeline.ts │ │ ├── PipelineError.ts │ │ ├── PooledPipeline.ts │ │ ├── Routine.ts │ │ ├── SerialPipeline.ts │ │ ├── Task.ts │ │ ├── WaterfallPipeline.ts │ │ ├── WorkUnit.ts │ │ ├── constants.ts │ │ ├── createWorkUnit.ts │ │ ├── debug.ts │ │ ├── index.ts │ │ └── types.ts │ ├── tests │ │ ├── .eslintrc.cjs │ │ ├── AggregatedPipeline.test.ts │ │ ├── ConcurrentPipeline.test.ts │ │ ├── Context.test.ts │ │ ├── Monitor.test.ts │ │ ├── ParallelPipeline.test.ts │ │ ├── PooledPipeline.test.ts │ │ ├── Routine.test.ts │ │ ├── SerialPipeline.test.ts │ │ ├── WaterfallPipeline.test.ts │ │ ├── WorkUnit.test.ts │ │ ├── __snapshots__ │ │ │ ├── Routine.test.ts.snap │ │ │ └── WorkUnit.test.ts.snap │ │ ├── createWorkUnit.test.ts │ │ └── helpers.ts │ ├── tsconfig.json │ └── tsconfig.mjs.json ├── plugin │ ├── CHANGELOG.md │ ├── LICENSE │ ├── README.md │ ├── package.json │ ├── src │ │ ├── Loader.ts │ │ ├── Plugin.ts │ │ ├── PluginError.ts │ │ ├── Registry.ts │ │ ├── constants.ts │ │ ├── debug.ts │ │ ├── index.ts │ │ └── types.ts │ ├── tests │ │ ├── Loader.test.ts │ │ ├── Plugin.test.ts │ │ ├── Registry.test.ts │ │ └── __fixtures__ │ │ │ └── Renderer.ts │ ├── tsconfig.json │ └── tsconfig.mjs.json ├── terminal │ ├── CHANGELOG.md │ ├── LICENSE │ ├── README.md │ ├── moon.yml │ ├── package.json │ ├── src │ │ ├── cursor.ts │ │ ├── index.ts │ │ ├── screen.ts │ │ └── text.ts │ ├── tsconfig.json │ └── tsconfig.mjs.json ├── test-utils │ ├── CHANGELOG.md │ ├── LICENSE │ ├── README.md │ ├── moon.yml │ ├── package.json │ ├── src │ │ ├── fixtures.ts │ │ ├── index.ts │ │ └── types.ts │ ├── tsconfig.json │ └── tsconfig.mjs.json └── translate │ ├── CHANGELOG.md │ ├── LICENSE │ ├── README.md │ ├── package.json │ ├── src │ ├── FileBackend.ts │ ├── LocaleDetector.ts │ ├── TranslateError.ts │ ├── createTranslator.ts │ ├── debug.ts │ ├── index.ts │ └── types.ts │ ├── tests │ ├── FileBackend.test.ts │ ├── LocaleDetector.test.ts │ ├── __snapshots__ │ │ └── createTranslator.test.ts.snap │ └── createTranslator.test.ts │ ├── tsconfig.json │ └── tsconfig.mjs.json ├── prettier.config.cjs ├── tests ├── __fixtures__ │ ├── .eslintrc.cjs │ ├── config-extends-custom-setting-name │ │ ├── .config │ │ │ └── boost.json │ │ ├── node_modules │ │ │ └── foo │ │ │ │ └── boost.preset.js │ │ ├── package.json │ │ └── some │ │ │ └── relative │ │ │ └── path │ │ │ └── config.js │ ├── config-extends-from-override │ │ ├── .config │ │ │ └── boost.json │ │ ├── package.json │ │ └── some │ │ │ └── relative │ │ │ └── path │ │ │ └── config.js │ ├── config-extends-fs-paths │ │ ├── .config │ │ │ └── boost.js │ │ ├── package.json │ │ └── some │ │ │ ├── absolute │ │ │ └── path │ │ │ │ └── config.yml │ │ │ └── relative │ │ │ └── path │ │ │ └── config.js │ ├── config-extends-module-presets │ │ ├── .config │ │ │ └── boost.json │ │ ├── node_modules │ │ │ ├── @scope │ │ │ │ └── bar │ │ │ │ │ └── boost.preset.js │ │ │ └── foo │ │ │ │ └── boost.preset.js │ │ └── package.json │ ├── config-file-tree-all-types │ │ ├── .config │ │ │ └── boost.json │ │ ├── package.json │ │ └── src │ │ │ ├── .boost.json │ │ │ └── app │ │ │ ├── .boost.cjs │ │ │ └── profiles │ │ │ ├── .boost.js │ │ │ └── settings │ │ │ └── .boost.yaml │ ├── config-file-tree-cjs │ │ ├── .config │ │ │ └── boost.json │ │ ├── package.json │ │ └── src │ │ │ ├── app │ │ │ ├── .boost.cjs │ │ │ ├── index.js │ │ │ └── profiles │ │ │ │ ├── Detail.ts │ │ │ │ └── settings │ │ │ │ └── .boost.cjs │ │ │ └── setup.ts │ ├── config-file-tree-js-root-file │ │ ├── boost.config.json │ │ ├── package.json │ │ └── src │ │ │ ├── app │ │ │ ├── .boost.js │ │ │ ├── index.js │ │ │ └── profiles │ │ │ │ ├── Detail.vue │ │ │ │ └── settings │ │ │ │ └── .boost.js │ │ │ └── setup.ts │ ├── config-file-tree-js │ │ ├── .config │ │ │ └── boost.json │ │ ├── package.json │ │ └── src │ │ │ ├── app │ │ │ ├── .boost.js │ │ │ ├── index.js │ │ │ └── profiles │ │ │ │ ├── Detail.vue │ │ │ │ └── settings │ │ │ │ └── .boost.js │ │ │ └── setup.ts │ ├── config-file-tree-json │ │ ├── .config │ │ │ └── boost.json │ │ ├── package.json │ │ └── src │ │ │ ├── app │ │ │ ├── .boost.json │ │ │ ├── index.js │ │ │ └── profiles │ │ │ │ ├── Detail.tsx │ │ │ │ └── settings │ │ │ │ └── .boost.json │ │ │ └── setup.ts │ ├── config-file-tree-json5 │ │ ├── .config │ │ │ └── boost.json │ │ ├── package.json │ │ └── src │ │ │ ├── app │ │ │ ├── .boost.json5 │ │ │ ├── index.js │ │ │ └── profiles │ │ │ │ ├── Detail.tsx │ │ │ │ └── settings │ │ │ │ └── .boost.json5 │ │ │ └── setup.ts │ ├── config-file-tree-mjs │ │ ├── .config │ │ │ └── boost.json │ │ ├── package.json │ │ └── src │ │ │ ├── app │ │ │ ├── .boost.mjs │ │ │ ├── index.js │ │ │ └── profiles │ │ │ │ ├── Detail.ts │ │ │ │ └── settings │ │ │ │ └── .boost.mjs │ │ │ └── setup.ts │ ├── config-file-tree-ts │ │ ├── .config │ │ │ └── boost.json │ │ ├── package.json │ │ └── src │ │ │ ├── app │ │ │ ├── .boost.ts │ │ │ ├── index.js │ │ │ └── profiles │ │ │ │ ├── Detail.vue │ │ │ │ └── settings │ │ │ │ └── .boost.ts │ │ │ └── setup.ts │ ├── config-file-tree-yaml │ │ ├── .config │ │ │ └── boost.json │ │ ├── package.json │ │ └── src │ │ │ ├── app │ │ │ ├── .boost.yaml │ │ │ ├── index.js │ │ │ └── profiles │ │ │ │ ├── Detail.tsx │ │ │ │ └── settings │ │ │ │ └── .boost.yaml │ │ │ └── setup.ts │ ├── config-file-tree-yml │ │ ├── .config │ │ │ └── boost.json │ │ ├── package.json │ │ └── src │ │ │ ├── app │ │ │ ├── .boost.yml │ │ │ ├── index.js │ │ │ └── profiles │ │ │ │ ├── Detail.tsx │ │ │ │ └── settings │ │ │ │ └── .boost.yml │ │ │ └── setup.ts │ ├── config-ignore-file-tree │ │ ├── .boostignore │ │ ├── .config │ │ │ └── boost.json │ │ ├── package.json │ │ └── src │ │ │ └── app │ │ │ ├── components │ │ │ └── build │ │ │ │ ├── .boostignore │ │ │ │ └── Button.tsx │ │ │ └── feature │ │ │ ├── .boostignore │ │ │ └── signup │ │ │ ├── .boostignore │ │ │ └── flow │ │ │ └── StepOne.tsx │ ├── config-invalid-branch-nested-extends │ │ ├── .config │ │ │ └── boost.json │ │ ├── package.json │ │ └── src │ │ │ └── .boost.json │ ├── config-invalid-branch-nested-overrides │ │ ├── .config │ │ │ └── boost.json │ │ ├── package.json │ │ └── src │ │ │ └── .boost.json │ ├── config-invalid-extends-path │ │ ├── .config │ │ │ └── boost.json │ │ └── package.json │ ├── config-missing-extends-path │ │ ├── .config │ │ │ └── boost.json │ │ └── package.json │ ├── config-overrides-custom-settings-name │ │ ├── .config │ │ │ └── boost.json │ │ ├── package.json │ │ └── src │ │ │ ├── bar │ │ │ └── doesnt-match.ts │ │ │ └── foo │ │ │ ├── does-match.ts │ │ │ └── doesnt-match.js │ ├── config-overrides-from-branch-with-excludes │ │ ├── .config │ │ │ └── boost.json │ │ ├── package.json │ │ └── src │ │ │ ├── baa.ts │ │ │ ├── bar.ts │ │ │ └── baz.ts │ ├── config-overrides-from-branch │ │ ├── .config │ │ │ └── boost.json │ │ ├── package.json │ │ └── src │ │ │ ├── bar │ │ │ └── doesnt-match.ts │ │ │ └── foo │ │ │ ├── does-match.ts │ │ │ └── doesnt-match.js │ ├── config-package-file-tree-monorepo │ │ ├── .config │ │ │ └── boost.json │ │ ├── index.ts │ │ ├── package.json │ │ └── packages │ │ │ ├── core │ │ │ ├── package.json │ │ │ └── src │ │ │ │ ├── deep │ │ │ │ └── nested │ │ │ │ │ └── core.ts │ │ │ │ └── index.ts │ │ │ ├── log │ │ │ ├── package.json │ │ │ └── src │ │ │ │ └── index.js │ │ │ └── plugin │ │ │ ├── index.js │ │ │ ├── nested │ │ │ └── example │ │ │ │ ├── package.json │ │ │ │ └── src │ │ │ │ └── index.ts │ │ │ └── package.json │ ├── config-root-config-cjs │ │ ├── .config │ │ │ └── boost.cjs │ │ └── package.json │ ├── config-root-config-js-file │ │ ├── boost.config.js │ │ └── package.json │ ├── config-root-config-js │ │ ├── .config │ │ │ └── boost.js │ │ └── package.json │ ├── config-root-config-json │ │ ├── .config │ │ │ └── boost.json │ │ └── package.json │ ├── config-root-config-json5 │ │ ├── .config │ │ │ └── boost.json5 │ │ └── package.json │ ├── config-root-config-mjs │ │ ├── .config │ │ │ └── boost.mjs │ │ └── package.json │ ├── config-root-config-toml │ │ ├── .config │ │ │ └── boost.toml │ │ └── package.json │ ├── config-root-config-ts │ │ ├── .config │ │ │ └── boost.ts │ │ └── package.json │ ├── config-root-config-yaml │ │ ├── .config │ │ │ └── boost.yaml │ │ └── package.json │ ├── config-root-config-yml │ │ ├── .config │ │ │ └── boost.yml │ │ └── package.json │ ├── config-root-without-package-json │ │ ├── .config │ │ │ └── boost.json │ │ └── nested │ │ │ └── index.js │ ├── config-scenario-branch-invalid-file-name │ │ ├── .config │ │ │ └── boost.json │ │ ├── package.json │ │ └── src │ │ │ ├── app │ │ │ └── .boost.toml │ │ │ └── boost.json │ ├── config-scenario-branch-multiple-types │ │ ├── .config │ │ │ └── boost.json │ │ ├── package.json │ │ └── src │ │ │ └── app │ │ │ ├── .boost.json │ │ │ └── .boost.yaml │ ├── config-scenario-branch-root-file │ │ ├── boost.config.json │ │ ├── package.json │ │ └── src │ │ │ └── app │ │ │ └── .boost.json │ ├── config-scenario-branch-with-envs │ │ ├── .config │ │ │ └── boost.json │ │ ├── package.json │ │ └── src │ │ │ └── app │ │ │ ├── .boost.json │ │ │ ├── .boost.production.json │ │ │ ├── .boost.staging.json │ │ │ └── .boost.test.json │ ├── config-scenario-configs-above-root │ │ ├── .boost.json │ │ ├── .config │ │ │ └── boost.json │ │ └── nested │ │ │ ├── .config │ │ │ └── boost.json │ │ │ ├── deep │ │ │ └── .boost.json │ │ │ └── package.json │ ├── config-scenario-not-root │ │ └── .empty │ ├── file-types │ │ ├── js.js │ │ ├── json.json │ │ ├── json5.json5 │ │ ├── jsx.jsx │ │ ├── ts.ts │ │ ├── tsx.tsx │ │ ├── yaml.yaml │ │ └── yml.yml │ ├── i18n-resources-more │ │ ├── en-US │ │ │ └── common.yaml │ │ └── en │ │ │ └── common.yaml │ ├── i18n-resources │ │ ├── en │ │ │ ├── common.yaml │ │ │ ├── type-cjs.cjs │ │ │ ├── type-js.js │ │ │ ├── type-json.json │ │ │ ├── type-json5.json5 │ │ │ ├── type-mjs.mjs │ │ │ ├── type-yaml-short.yml │ │ │ └── type-yaml.yaml │ │ └── package.json │ ├── module-basic │ │ ├── bar.js │ │ ├── foo.js │ │ ├── index.js │ │ └── package.json │ ├── module-no-package │ │ └── index.js │ ├── plugin-export-nonfunc │ │ └── index.js │ ├── plugin-renderer-class │ │ └── index.mjs │ ├── plugin-renderer-object │ │ └── index.js │ ├── workspace-lerna │ │ ├── lerna.json │ │ ├── package.json │ │ └── packages │ │ │ └── foo │ │ │ └── package.json │ ├── workspace-mismatch │ │ ├── package.json │ │ └── packages │ │ │ └── foo │ │ │ └── package.json │ ├── workspace-multiple │ │ ├── modules │ │ │ └── bar │ │ │ │ └── package.json │ │ ├── package.json │ │ └── packages │ │ │ ├── baz │ │ │ └── package.json │ │ │ └── foo │ │ │ └── package.json │ ├── workspace-no-config │ │ ├── package.json │ │ └── packages │ │ │ └── foo │ │ │ └── package.json │ ├── workspace-no-packages │ │ └── package.json │ ├── workspace-pnpm │ │ ├── package.json │ │ ├── packages │ │ │ ├── foo │ │ │ │ └── package.json │ │ │ └── qux │ │ │ │ └── package.json │ │ └── pnpm-workspace.yaml │ ├── workspace-yarn-nohoist │ │ ├── configs │ │ │ └── testBoost.js │ │ ├── package.json │ │ └── packages │ │ │ └── foo │ │ │ └── package.json │ └── workspace-yarn │ │ ├── configs │ │ └── testBoost.js │ │ ├── package.json │ │ └── packages │ │ └── foo │ │ └── package.json └── setup.ts ├── themes ├── dracula │ ├── CHANGELOG.md │ ├── LICENSE │ ├── README.md │ ├── index.js │ └── package.json ├── moon-dark │ ├── CHANGELOG.md │ ├── LICENSE │ ├── README.md │ ├── index.js │ └── package.json ├── moon-light │ ├── CHANGELOG.md │ ├── LICENSE │ ├── README.md │ ├── index.js │ └── package.json ├── one-dark │ ├── CHANGELOG.md │ ├── LICENSE │ ├── README.md │ ├── index.js │ └── package.json ├── one-light │ ├── CHANGELOG.md │ ├── LICENSE │ ├── README.md │ ├── index.js │ └── package.json ├── solarized │ ├── CHANGELOG.md │ ├── LICENSE │ ├── README.md │ ├── index.js │ └── package.json ├── test-private │ ├── CHANGELOG.md │ ├── index.js │ └── package.json └── test-public │ ├── CHANGELOG.md │ ├── index.js │ └── package.json ├── tsconfig.docs.json ├── tsconfig.eslint.json ├── tsconfig.json ├── tsconfig.options.json ├── types ├── global.d.ts ├── supports-hyperlinks.d.ts └── vitest.d.ts ├── vitest.config.ts ├── website ├── .eslintrc.cjs ├── .gitignore ├── CHANGELOG.md ├── babel.config.js ├── docs │ ├── args.mdx │ ├── cli.mdx │ ├── cli │ │ ├── components.md │ │ └── prompts.md │ ├── common.mdx │ ├── config.mdx │ ├── crash.mdx │ ├── debug.mdx │ ├── decorators.mdx │ ├── event.mdx │ ├── index.mdx │ ├── internal │ │ └── errors.md │ ├── log.mdx │ ├── migrate │ │ ├── 3.0.md │ │ ├── 4.0.md │ │ └── 5.0.md │ ├── module.mdx │ ├── pipeline.mdx │ ├── plugin.mdx │ ├── terminal.mdx │ └── translate.mdx ├── docusaurus.config.js ├── moon.yml ├── package.json ├── sidebars.js ├── src │ ├── css │ │ └── custom.css │ ├── pages │ │ ├── index.tsx │ │ └── styles.module.css │ └── theme │ │ ├── Badge.tsx │ │ ├── BadgeGroup.tsx │ │ ├── EnvBadges.tsx │ │ └── styles.module.css ├── static │ ├── .nojekyll │ ├── CNAME │ └── img │ │ ├── cli │ │ ├── command.png │ │ ├── options.png │ │ ├── params.png │ │ ├── program.png │ │ ├── prompts │ │ │ ├── confirm.gif │ │ │ ├── hidden-input.gif │ │ │ ├── input.gif │ │ │ ├── multiselect.gif │ │ │ ├── password-input.gif │ │ │ ├── select-labels.gif │ │ │ └── select.gif │ │ ├── subcommands.png │ │ ├── unknown-option.png │ │ └── variadic-params.png │ │ ├── favicon.svg │ │ ├── logo-bg.svg │ │ └── logo.svg ├── tsconfig.json └── types │ ├── docusaurus.d.ts │ └── global.d.ts └── yarn.lock /.eslintignore: -------------------------------------------------------------------------------- 1 | node_modules/ 2 | build/ 3 | cjs/ 4 | coverage/ 5 | dist/ 6 | dts/ 7 | esm/ 8 | lib/ 9 | mjs/ 10 | umd/ 11 | *.d.ts 12 | *.d.cts 13 | *.d.mts 14 | *.min.js 15 | *.map 16 | *.snap 17 | -------------------------------------------------------------------------------- /.eslintrc.cjs: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | root: true, 3 | extends: ['moon', 'moon/node'], 4 | parserOptions: { 5 | project: 'tsconfig.eslint.json', 6 | tsconfigRootDir: __dirname, 7 | }, 8 | rules: { 9 | 'node/no-unpublished-import': 'off', 10 | // Doesnt work with `package.json` exports 11 | 'import/no-unresolved': 'off', 12 | // Not ESM yet 13 | 'unicorn/prefer-module': 'off', 14 | }, 15 | }; 16 | -------------------------------------------------------------------------------- /.gitattributes: -------------------------------------------------------------------------------- 1 | * text=auto eol=lf 2 | -------------------------------------------------------------------------------- /.github/FUNDING.yml: -------------------------------------------------------------------------------- 1 | ko_fi: milesjohnson 2 | -------------------------------------------------------------------------------- /.github/workflows/pr.yml: -------------------------------------------------------------------------------- 1 | name: PR 2 | on: pull_request 3 | jobs: 4 | conventional: 5 | name: Conventional Title 6 | runs-on: ubuntu-latest 7 | steps: 8 | - uses: actions/checkout@v4 9 | - uses: actions/setup-node@v4 10 | - uses: beemojs/conventional-pr-action@v2 11 | with: 12 | require-multiple-commits: false 13 | env: 14 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} 15 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Logs 2 | logs/ 3 | *.log 4 | 5 | # Cache 6 | .eslintcache 7 | .idea 8 | .npm 9 | .vscode 10 | .yarnclean 11 | 12 | # Directories 13 | _book/ 14 | coverage/ 15 | cjs/ 16 | dts/ 17 | esm/ 18 | lib/ 19 | mjs/ 20 | node_modules/ 21 | 22 | # Custom 23 | *.min.js 24 | *.map 25 | 26 | # Configs 27 | .flowconfig 28 | webpack.config.js 29 | *.tsbuildinfo 30 | 31 | # Yarn 32 | .yarn/* 33 | !.yarn/patches 34 | !.yarn/releases 35 | !.yarn/plugins 36 | !.yarn/sdks 37 | !.yarn/versions 38 | .pnp.* 39 | 40 | # moon 41 | .moon/cache 42 | .moon/docker 43 | -------------------------------------------------------------------------------- /.moon/toolchain.yml: -------------------------------------------------------------------------------- 1 | $schema: 'https://moonrepo.dev/schemas/toolchain.json' 2 | 3 | node: 4 | version: '20.11.0' 5 | packageManager: 'yarn' 6 | yarn: 7 | version: '4.1.0' 8 | addEnginesConstraint: true 9 | dedupeOnLockfileChange: true 10 | syncProjectWorkspaceDependencies: false 11 | 12 | typescript: 13 | routeOutDirToCache: true 14 | -------------------------------------------------------------------------------- /.moon/workspace.yml: -------------------------------------------------------------------------------- 1 | $schema: 'https://moonrepo.dev/schemas/workspace.json' 2 | 3 | projects: 4 | - 'packages/*' 5 | - 'website' 6 | -------------------------------------------------------------------------------- /.prettierignore: -------------------------------------------------------------------------------- 1 | .docusaurus/ 2 | .github/ 3 | .yarn/ 4 | node_modules/ 5 | build/ 6 | cjs/ 7 | coverage/ 8 | dist/ 9 | dts/ 10 | esm/ 11 | lib/ 12 | mjs/ 13 | umd/ 14 | CHANGELOG.md 15 | *.d.ts 16 | *.d.cts 17 | *.d.mts 18 | .yarn 19 | -------------------------------------------------------------------------------- /.yarnrc.yml: -------------------------------------------------------------------------------- 1 | compressionLevel: mixed 2 | 3 | enableGlobalCache: true 4 | 5 | enableTelemetry: false 6 | 7 | nodeLinker: node-modules 8 | 9 | yarnPath: .yarn/releases/yarn-4.1.0.cjs 10 | -------------------------------------------------------------------------------- /lerna.json: -------------------------------------------------------------------------------- 1 | { 2 | "version": "independent", 3 | "npmClient": "yarn", 4 | "command": { 5 | "publish": { 6 | "ignoreChanges": [ 7 | "*.md", 8 | "*.test.ts" 9 | ], 10 | "message": "Release [ci skip]" 11 | } 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /packages/args/src/ParseError.ts: -------------------------------------------------------------------------------- 1 | export class ParseError extends Error { 2 | arg: string; 3 | 4 | index: number; 5 | 6 | constructor(message: string, arg: string, index: number) { 7 | super(message); 8 | 9 | this.name = 'ParseError'; 10 | this.arg = arg; 11 | this.index = index; 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /packages/args/src/ValidationError.ts: -------------------------------------------------------------------------------- 1 | import type { LongOptionName } from './types'; 2 | 3 | export class ValidationError extends Error { 4 | option: string; 5 | 6 | constructor(message: string, option: LongOptionName = '') { 7 | super(message); 8 | 9 | this.name = 'ValidationError'; 10 | this.option = option; 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /packages/args/src/debug.ts: -------------------------------------------------------------------------------- 1 | import { createInternalDebugger } from '@boost/internal'; 2 | 3 | export const debug = createInternalDebugger('args'); 4 | -------------------------------------------------------------------------------- /packages/args/src/helpers/expandShortOption.ts: -------------------------------------------------------------------------------- 1 | import { ArgsError } from '../ArgsError'; 2 | import type { AliasMap, LongOptionName, ShortOptionName } from '../types'; 3 | 4 | /** 5 | * Expand a short option name to a long option name. 6 | */ 7 | export function expandShortOption( 8 | short: ShortOptionName, 9 | map: AliasMap, 10 | loose: boolean, 11 | ): LongOptionName { 12 | if (!map[short]) { 13 | if (loose) { 14 | return short; 15 | } 16 | 17 | throw new ArgsError('SHORT_UNKNOWN', [short]); 18 | } 19 | 20 | return map[short]; 21 | } 22 | -------------------------------------------------------------------------------- /packages/args/src/helpers/formatValue.ts: -------------------------------------------------------------------------------- 1 | import { ArgsError } from '../ArgsError'; 2 | import type { Option, ValueType } from '../types'; 3 | 4 | export function formatValue(value: ValueType, format?: Option['format']): ValueType { 5 | let nextValue = value; 6 | const prevType = typeof nextValue; 7 | 8 | if (typeof format === 'function' && prevType !== 'boolean') { 9 | nextValue = format(nextValue); 10 | 11 | const nextType = typeof nextValue; 12 | 13 | if (nextType !== prevType) { 14 | throw new ArgsError('VALUE_INVALID_FORMAT', [prevType, nextType]); 15 | } 16 | } 17 | 18 | return nextValue; 19 | } 20 | -------------------------------------------------------------------------------- /packages/args/src/helpers/getDefaultValue.ts: -------------------------------------------------------------------------------- 1 | import { DEFAULT_BOOLEAN_VALUE, DEFAULT_NUMBER_VALUE, DEFAULT_STRING_VALUE } from '../constants'; 2 | import type { OptionConfig, ValueType } from '../types'; 3 | 4 | export function getDefaultValue(config: OptionConfig): ValueType { 5 | let value = config.default as ValueType; 6 | 7 | if (value === undefined) { 8 | if (config.multiple) { 9 | value = []; 10 | } else if (config.type === 'boolean') { 11 | value = DEFAULT_BOOLEAN_VALUE; 12 | } else if (config.type === 'number') { 13 | value = DEFAULT_NUMBER_VALUE; 14 | } else { 15 | value = DEFAULT_STRING_VALUE; 16 | } 17 | } 18 | 19 | return value; 20 | } 21 | -------------------------------------------------------------------------------- /packages/args/src/helpers/isCommand.ts: -------------------------------------------------------------------------------- 1 | import type { CommandChecker } from '../types'; 2 | 3 | /** 4 | * Check that an argument is a command by looping through a list of available 5 | * commands, or running a command checking function. If an exact match, 6 | * or looks like a sub-command ("cmd:sub") return true. 7 | */ 8 | export function isCommand(arg: string, commandCheck: CommandChecker | string[]): boolean { 9 | if (Array.isArray(commandCheck) && commandCheck.length > 0) { 10 | return commandCheck.includes(arg); 11 | } 12 | 13 | if (typeof commandCheck === 'function') { 14 | return commandCheck(arg); 15 | } 16 | 17 | return false; 18 | } 19 | -------------------------------------------------------------------------------- /packages/args/src/helpers/isLongOption.ts: -------------------------------------------------------------------------------- 1 | import { LONG_OPTION_FORMAT } from '../constants'; 2 | 3 | export function isLongOption(arg: string): boolean { 4 | return LONG_OPTION_FORMAT.test(arg); 5 | } 6 | -------------------------------------------------------------------------------- /packages/args/src/helpers/isOptionLike.ts: -------------------------------------------------------------------------------- 1 | import { OPTION_LIKE } from '../constants'; 2 | 3 | /** 4 | * Check that an argument looks like a long option, short option, 5 | * or short option group. Do not return true for negative numbers. 6 | */ 7 | export function isOptionLike(arg: string): boolean { 8 | return OPTION_LIKE.test(arg); 9 | } 10 | -------------------------------------------------------------------------------- /packages/args/src/helpers/isShortOption.ts: -------------------------------------------------------------------------------- 1 | import { SHORT_OPTION_FORMAT } from '../constants'; 2 | 3 | export function isShortOption(arg: string): boolean { 4 | return SHORT_OPTION_FORMAT.test(arg); 5 | } 6 | -------------------------------------------------------------------------------- /packages/args/src/helpers/isShortOptionGroup.ts: -------------------------------------------------------------------------------- 1 | import { SHORT_OPTION_GROUP_FORMAT } from '../constants'; 2 | 3 | export function isShortOptionGroup(arg: string): boolean { 4 | return SHORT_OPTION_GROUP_FORMAT.test(arg); 5 | } 6 | -------------------------------------------------------------------------------- /packages/args/src/index.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * @copyright 2020, Miles Johnson 3 | * @license https://opensource.org/licenses/MIT 4 | */ 5 | 6 | export * from './ArgsError'; 7 | export * from './constants'; 8 | export * from './format'; 9 | export * from './parse'; 10 | export * from './ParseError'; 11 | export * from './parseInContext'; 12 | export * from './types'; 13 | export * from './ValidationError'; 14 | -------------------------------------------------------------------------------- /packages/args/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../../tsconfig.options.json", 3 | "compilerOptions": { 4 | "outDir": "../../.moon/cache/types/packages/args", 5 | "rootDir": "." 6 | }, 7 | "include": [ 8 | "src/**/*", 9 | "tests/**/*", 10 | "types/**/*", 11 | "../../types/**/*" 12 | ], 13 | "references": [ 14 | { 15 | "path": "./tsconfig.mjs.json" 16 | }, 17 | { 18 | "path": "../internal" 19 | } 20 | ] 21 | } 22 | -------------------------------------------------------------------------------- /packages/args/tsconfig.mjs.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../../tsconfig.options.json", 3 | "compilerOptions": { 4 | "outDir": "mjs", 5 | "rootDir": "src", 6 | "emitDeclarationOnly": true 7 | }, 8 | "include": [ 9 | "src/**/*", 10 | "../../types/**/*" 11 | ] 12 | } 13 | -------------------------------------------------------------------------------- /packages/cli/.eslintrc.cjs: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | extends: ['moon/react'], 3 | rules: { 4 | 'react/jsx-no-literals': 'off', 5 | 'react/no-array-index-key': 'off', 6 | }, 7 | }; 8 | -------------------------------------------------------------------------------- /packages/cli/__mocks__/term-size.js: -------------------------------------------------------------------------------- 1 | function size() { 2 | return { columns: 80, rows: 80 }; 3 | } 4 | 5 | size.size = size; 6 | 7 | module.exports = size; 8 | -------------------------------------------------------------------------------- /packages/cli/examples/.eslintrc.cjs: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | rules: { 3 | 'max-classes-per-file': 'off', 4 | 'no-magic-numbers': 'off', 5 | 'sort-keys': 'off', 6 | 'import/no-extraneous-dependencies': 'off', 7 | 'import/no-default-export': 'off', 8 | 'import/no-useless-path-segments': 'off', 9 | '@typescript-eslint/require-await': 'off', 10 | 'unicorn/import-index': 'off', 11 | }, 12 | }; 13 | -------------------------------------------------------------------------------- /packages/cli/examples/commands/BuildCommand.mjs: -------------------------------------------------------------------------------- 1 | import { Command } from '../../mjs/index.mjs'; 2 | 3 | export default class BuildCommand extends Command { 4 | static path = 'build'; 5 | 6 | static aliases = ['make']; 7 | 8 | static description = 'Build a project'; 9 | 10 | static deprecated = true; 11 | 12 | async run() { 13 | // 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /packages/cli/examples/commands/ConfirmCommand.mjs: -------------------------------------------------------------------------------- 1 | import { createElement } from 'react'; 2 | import { Command } from '../../mjs/index.mjs'; 3 | import { Confirm } from '../../mjs/react.mjs'; 4 | 5 | export default class ConfirmCommand extends Command { 6 | static description = 'Test `Confirm` component'; 7 | 8 | static path = 'confirm'; 9 | 10 | static category = 'prompt'; 11 | 12 | static options = {}; 13 | 14 | async run() { 15 | return createElement(Confirm, { 16 | label: 'Do you want to continue?', 17 | onSubmit: (value) => { 18 | this.log('SUBMIT', value); 19 | }, 20 | }); 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /packages/cli/examples/commands/ErrorCommand.mjs: -------------------------------------------------------------------------------- 1 | import { Command } from '../../mjs/index.mjs'; 2 | import sleep from '../sleep.mjs'; 3 | 4 | export default class ErrorCommand extends Command { 5 | static description = 'Test thrown errors render a failure state'; 6 | 7 | static path = 'error'; 8 | 9 | static category = 'test'; 10 | 11 | async run() { 12 | console.log('Will throw an error in 3 seconds...'); 13 | 14 | await sleep(3000); 15 | 16 | throw new Error('Custom thrown error!'); 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /packages/cli/examples/commands/ExitCommand.mjs: -------------------------------------------------------------------------------- 1 | import { Command } from '../../mjs/index.mjs'; 2 | import sleep from '../sleep.mjs'; 3 | 4 | export default class ExitCommand extends Command { 5 | static description = 'Test exiting the program'; 6 | 7 | static path = 'exit'; 8 | 9 | static category = 'test'; 10 | 11 | static options = { 12 | error: { 13 | description: 'Throw an error', 14 | type: 'boolean', 15 | }, 16 | }; 17 | 18 | async run() { 19 | console.log('Will exit in 3 seconds...'); 20 | 21 | await sleep(3000); 22 | 23 | if (this.error) { 24 | this.exit('Failed!'); 25 | } else { 26 | this.exit(); 27 | } 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /packages/cli/examples/commands/MultiSelectCommand.mjs: -------------------------------------------------------------------------------- 1 | import { MultiSelect } from '../../mjs/react.mjs'; 2 | import SelectCommand from './SelectCommand.mjs'; 3 | 4 | export default class MultiSelectCommand extends SelectCommand { 5 | static description = 'Test `MultiSelect` component'; 6 | 7 | static path = 'multiselect'; 8 | 9 | getComponent() { 10 | return MultiSelect; 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /packages/cli/examples/commands/ParamsCommand.mjs: -------------------------------------------------------------------------------- 1 | import { Command } from '../../mjs/index.mjs'; 2 | 3 | export default class ParamsCommand extends Command { 4 | static description = 'List of all possible param types'; 5 | 6 | static path = 'pms'; 7 | 8 | static category = 'feature'; 9 | 10 | static params = [ 11 | { 12 | description: 'String', 13 | label: 'name', 14 | required: true, 15 | type: 'string', 16 | }, 17 | { 18 | default: 18, 19 | description: 'Number', 20 | label: 'age', 21 | type: 'number', 22 | }, 23 | { 24 | description: 'Boolean', 25 | label: 'active', 26 | type: 'boolean', 27 | }, 28 | ]; 29 | 30 | run() { 31 | // 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /packages/cli/examples/commands/ScaffoldCommand.mjs: -------------------------------------------------------------------------------- 1 | import { Command } from '../../mjs/index.mjs'; 2 | import ScaffoldControllerCommand from './scaffold/ScaffoldControllerCommand.mjs'; 3 | import ScaffoldModelCommand from './scaffold/ScaffoldModelCommand.mjs'; 4 | import ScaffoldViewCommand from './scaffold/ScaffoldViewCommand.mjs'; 5 | 6 | export default class ScaffoldCommand extends Command { 7 | static description = 'Scaffold files based on a template'; 8 | 9 | static path = 'scaffold'; 10 | 11 | constructor() { 12 | super(); 13 | 14 | this.register(new ScaffoldControllerCommand()) 15 | .register(new ScaffoldModelCommand()) 16 | .register(new ScaffoldViewCommand()); 17 | } 18 | 19 | async run() { 20 | return this.render(await this.createHelp()); 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /packages/cli/examples/commands/scaffold/ScaffoldControllerCommand.mjs: -------------------------------------------------------------------------------- 1 | import { Command } from '../../../mjs/index.mjs'; 2 | 3 | export default class ScaffoldControllerCommand extends Command { 4 | static description = 'Scaffold a controller'; 5 | 6 | static path = 'scaffold:controller'; 7 | 8 | async run() { 9 | this.log('Scaffolded'); 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /packages/cli/examples/commands/scaffold/ScaffoldModelCommand.mjs: -------------------------------------------------------------------------------- 1 | import { Command } from '../../../mjs/index.mjs'; 2 | 3 | export default class ScaffoldModelCommand extends Command { 4 | static description = 'Scaffold a model'; 5 | 6 | static path = 'scaffold:model'; 7 | 8 | async run() { 9 | this.log('Scaffolded'); 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /packages/cli/examples/commands/scaffold/ScaffoldViewCommand.mjs: -------------------------------------------------------------------------------- 1 | import { Command } from '../../../mjs/index.mjs'; 2 | 3 | export default class ScaffoldViewCommand extends Command { 4 | static description = 'Scaffold a view'; 5 | 6 | static path = 'scaffold:view'; 7 | 8 | async run() { 9 | this.log('Scaffolded'); 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /packages/cli/examples/random.mjs: -------------------------------------------------------------------------------- 1 | export default function random(max, min) { 2 | return Math.floor(Math.random() * max) + min; 3 | } 4 | -------------------------------------------------------------------------------- /packages/cli/examples/sleep.mjs: -------------------------------------------------------------------------------- 1 | export default async function sleep(delay) { 2 | return new Promise((resolve) => { 3 | setTimeout(resolve, delay); 4 | }); 5 | } 6 | -------------------------------------------------------------------------------- /packages/cli/moon.yml: -------------------------------------------------------------------------------- 1 | type: 'application' 2 | 3 | tasks: 4 | dev: 5 | command: 'node ./examples/bin.mjs' 6 | deps: ['build'] 7 | local: true 8 | -------------------------------------------------------------------------------- /packages/cli/res/en/cli.yml: -------------------------------------------------------------------------------- 1 | categoryGlobal: Global 2 | errorInvalidLocale: Locale must be in the format of "en" or "en-US". 3 | labelAbout: About 4 | labelCommands: Commands 5 | labelError: Error 6 | labelOption: Option "{{name}}" 7 | labelOptions: Options 8 | labelParam: Param "{{name}}" 9 | labelParams: Params 10 | labelStackTrace: Stack Trace 11 | labelUsage: Usage 12 | labelWarnings: Warnings 13 | optionHelpDescription: Display help and usage menu 14 | optionLocaleDescription: Display output in the chosen locale 15 | optionVersionDescription: Display version number 16 | tagChoices: choices 17 | tagCount: counter 18 | tagDefault: default 19 | tagDeprecated: deprecated 20 | tagMultiple: multiple 21 | tagRequired: required 22 | -------------------------------------------------------------------------------- /packages/cli/res/en/prompt.yml: -------------------------------------------------------------------------------- 1 | confirmInvalidValue: Please select "{{yes}}" or "{{no}}" 2 | scrollOverflowBefore: '{{count}} more' 3 | scrollOverflowAfter: '{{count}} more' 4 | -------------------------------------------------------------------------------- /packages/cli/src/LogBuffer.ts: -------------------------------------------------------------------------------- 1 | type BufferListener = (message: string) => void; 2 | 3 | export class LogBuffer { 4 | protected listener?: BufferListener; 5 | 6 | protected stream: NodeJS.WriteStream; 7 | 8 | constructor(stream: NodeJS.WriteStream) { 9 | this.stream = stream; 10 | } 11 | 12 | on(listener: BufferListener) { 13 | this.listener = listener; 14 | 15 | return () => { 16 | delete this.listener; 17 | }; 18 | } 19 | 20 | write = (message: string) => { 21 | if (this.listener) { 22 | this.listener(message); 23 | } else { 24 | this.stream.write(message); 25 | } 26 | }; 27 | } 28 | -------------------------------------------------------------------------------- /packages/cli/src/ProgramContext.ts: -------------------------------------------------------------------------------- 1 | import { createContext } from 'react'; 2 | import type { ProgramContextType } from './types'; 3 | 4 | // @ts-expect-error Ignore default value 5 | export const ProgramContext = createContext(); 6 | -------------------------------------------------------------------------------- /packages/cli/src/components/HiddenInput.tsx: -------------------------------------------------------------------------------- 1 | import { Input, type InputProps } from './Input'; 2 | 3 | export type HiddenInputProps = Omit; 4 | 5 | /** 6 | * A React component that renders an input field that hides its content from the terminal. 7 | */ 8 | export function HiddenInput(props: HiddenInputProps) { 9 | return ; 10 | } 11 | -------------------------------------------------------------------------------- /packages/cli/src/components/PasswordInput.tsx: -------------------------------------------------------------------------------- 1 | import { Input, type InputProps } from './Input'; 2 | 3 | export type PasswordInputProps = Omit; 4 | 5 | /** 6 | * A React component that renders an input field with characters masked with "*". 7 | */ 8 | export function PasswordInput(props: PasswordInputProps) { 9 | return ; 10 | } 11 | -------------------------------------------------------------------------------- /packages/cli/src/components/index.ts: -------------------------------------------------------------------------------- 1 | export * from './Confirm'; 2 | export * from './Failure'; 3 | export * from './Header'; 4 | export * from './Help'; 5 | export * from './HiddenInput'; 6 | export * from './IndexHelp'; 7 | export * from './Input'; 8 | export * from './MultiSelect'; 9 | export * from './PasswordInput'; 10 | export * from './Select'; 11 | export * from './Style'; 12 | -------------------------------------------------------------------------------- /packages/cli/src/components/internal/Cursor.tsx: -------------------------------------------------------------------------------- 1 | import { Text } from 'ink'; 2 | import { Style } from '../Style'; 3 | 4 | export interface CursorProps { 5 | focused?: boolean; 6 | hideCursor?: boolean; 7 | position: number; 8 | value: string; 9 | } 10 | 11 | export function Cursor({ focused, hideCursor, position, value }: CursorProps) { 12 | if (!focused) { 13 | return {value}; 14 | } 15 | 16 | return ( 17 | 18 | {value.slice(0, position)} 19 | {hideCursor ? ( 20 | value[position] 21 | ) : ( 22 | 25 | )} 26 | {value.slice(position + 1)} 27 | 28 | ); 29 | } 30 | -------------------------------------------------------------------------------- /packages/cli/src/components/internal/DividerRow.tsx: -------------------------------------------------------------------------------- 1 | import type { ReactNode } from 'react'; 2 | import { Box } from 'ink'; 3 | import { Style } from '../Style'; 4 | 5 | export interface DividerRowProps { 6 | label: NonNullable; 7 | } 8 | 9 | export function DividerRow({ label }: DividerRowProps) { 10 | return ( 11 | 12 | 13 | 14 | ); 15 | } 16 | -------------------------------------------------------------------------------- /packages/cli/src/components/internal/HelpUsage.tsx: -------------------------------------------------------------------------------- 1 | import { Box, Text } from 'ink'; 2 | import { toArray } from '@boost/common'; 3 | import { DELIMITER, SPACING_COL } from '../../constants'; 4 | import { msg } from '../../translate'; 5 | import { Header } from '../Header'; 6 | 7 | export interface HelpUsageProps { 8 | delimiter?: string; 9 | usage?: string[] | string; 10 | } 11 | 12 | export function HelpUsage({ delimiter = DELIMITER, usage = '' }: HelpUsageProps) { 13 | return ( 14 | <> 15 |
16 | 17 | {toArray(usage).map((example) => ( 18 | 19 | {example.startsWith(delimiter) ? example : delimiter + example} 20 | 21 | ))} 22 | 23 | ); 24 | } 25 | -------------------------------------------------------------------------------- /packages/cli/src/components/internal/Label.tsx: -------------------------------------------------------------------------------- 1 | import type { ReactNode } from 'react'; 2 | import { Text } from 'ink'; 3 | 4 | export interface LabelProps { 5 | children: NonNullable; 6 | } 7 | 8 | export function Label({ children }: LabelProps) { 9 | if (typeof children === 'string') { 10 | return {children}; 11 | } 12 | 13 | // eslint-disable-next-line react/jsx-no-useless-fragment 14 | return <>{children}; 15 | } 16 | -------------------------------------------------------------------------------- /packages/cli/src/components/internal/LogWriter.ts: -------------------------------------------------------------------------------- 1 | import { useEffect } from 'react'; 2 | import { useStderr, useStdout } from 'ink'; 3 | import { LogBuffer } from '../../LogBuffer'; 4 | 5 | export interface LogWriterProps { 6 | errBuffer: LogBuffer; 7 | outBuffer: LogBuffer; 8 | } 9 | 10 | export function LogWriter({ errBuffer, outBuffer }: LogWriterProps) { 11 | const { write: writeErr } = useStderr(); 12 | const { write: writeOut } = useStdout(); 13 | 14 | useEffect(() => errBuffer.on(writeErr), [errBuffer, writeErr]); 15 | 16 | useEffect(() => outBuffer.on(writeOut), [outBuffer, writeOut]); 17 | 18 | return null; 19 | } 20 | -------------------------------------------------------------------------------- /packages/cli/src/components/internal/Selected.tsx: -------------------------------------------------------------------------------- 1 | import { applyStyle } from '../../helpers'; 2 | import { Style } from '../Style'; 3 | 4 | export interface SelectedProps { 5 | value: T | T[]; 6 | } 7 | 8 | export function Selected({ value }: SelectedProps) { 9 | const selected = Array.isArray(value) 10 | ? [...value].sort().join(applyStyle(', ', 'muted')) 11 | : String(value); 12 | 13 | return ; 14 | } 15 | -------------------------------------------------------------------------------- /packages/cli/src/decorators/Flag.ts: -------------------------------------------------------------------------------- 1 | import type { Flag as FlagConfig } from '@boost/args'; 2 | import { createOptionDecorator } from '../metadata/createOptionDecorator'; 3 | import type { PartialConfig } from '../types'; 4 | 5 | /** 6 | * A property decorator for declaring a command line flag (boolean value). 7 | */ 8 | export function Flag(description: string, config?: PartialConfig): PropertyDecorator { 9 | return createOptionDecorator({ 10 | ...config, 11 | description, 12 | type: 'boolean', 13 | }); 14 | } 15 | -------------------------------------------------------------------------------- /packages/cli/src/decorators/Number.ts: -------------------------------------------------------------------------------- 1 | import type { SingleOption } from '@boost/args'; 2 | import { createOptionDecorator } from '../metadata/createOptionDecorator'; 3 | import type { PartialConfig } from '../types'; 4 | 5 | /** 6 | * A property decorator for declaring a command line option with a numeric value. 7 | */ 8 | export function Number( 9 | description: string, 10 | config?: PartialConfig>, 11 | ): PropertyDecorator { 12 | return createOptionDecorator>({ 13 | ...config, 14 | description, 15 | type: 'number', 16 | }); 17 | } 18 | -------------------------------------------------------------------------------- /packages/cli/src/decorators/Numbers.ts: -------------------------------------------------------------------------------- 1 | import type { MultipleOption } from '@boost/args'; 2 | import { createOptionDecorator } from '../metadata/createOptionDecorator'; 3 | import type { PartialConfig } from '../types'; 4 | 5 | /** 6 | * A property decorator for declaring a command line option with multiple numeric values. 7 | */ 8 | export function Numbers( 9 | description: string, 10 | config?: PartialConfig>, 11 | ): PropertyDecorator { 12 | return createOptionDecorator>({ 13 | ...config, 14 | default: [], 15 | description, 16 | multiple: true, 17 | type: 'number', 18 | }); 19 | } 20 | -------------------------------------------------------------------------------- /packages/cli/src/decorators/Params.ts: -------------------------------------------------------------------------------- 1 | import type { MapParamConfig, ParamConfig, PrimitiveType } from '@boost/args'; 2 | import { registerParams } from '../metadata/registerParams'; 3 | 4 | /** 5 | * A method decorator for declaring command line parameters (positional arguments). 6 | */ 7 | export function Params( 8 | ...config: MapParamConfig 9 | ): MethodDecorator { 10 | return (target, method) => { 11 | registerParams(target, method, config as ParamConfig[]); 12 | }; 13 | } 14 | -------------------------------------------------------------------------------- /packages/cli/src/decorators/String.ts: -------------------------------------------------------------------------------- 1 | import type { SingleOption } from '@boost/args'; 2 | import { createOptionDecorator } from '../metadata/createOptionDecorator'; 3 | import type { PartialConfig } from '../types'; 4 | 5 | /** 6 | * A property decorator for declaring a command line option with a string value. 7 | */ 8 | export function String( 9 | description: string, 10 | config?: PartialConfig>, 11 | ): PropertyDecorator { 12 | return createOptionDecorator>({ 13 | ...config, 14 | description, 15 | type: 'string', 16 | }); 17 | } 18 | -------------------------------------------------------------------------------- /packages/cli/src/decorators/Strings.ts: -------------------------------------------------------------------------------- 1 | import type { MultipleOption } from '@boost/args'; 2 | import { createOptionDecorator } from '../metadata/createOptionDecorator'; 3 | import type { PartialConfig } from '../types'; 4 | 5 | /** 6 | * A property decorator for declaring a command line option with multiple string values. 7 | */ 8 | export function Strings( 9 | description: string, 10 | config?: PartialConfig>, 11 | ): PropertyDecorator { 12 | return createOptionDecorator>({ 13 | ...config, 14 | default: [], 15 | description, 16 | multiple: true, 17 | type: 'string', 18 | }); 19 | } 20 | -------------------------------------------------------------------------------- /packages/cli/src/decorators/index.ts: -------------------------------------------------------------------------------- 1 | export { Flag } from './Flag'; 2 | export { Number } from './Number'; 3 | export { Numbers } from './Numbers'; 4 | export { Params } from './Params'; 5 | export { String } from './String'; 6 | export { Strings } from './Strings'; 7 | -------------------------------------------------------------------------------- /packages/cli/src/helpers/applyMarkdown.ts: -------------------------------------------------------------------------------- 1 | import { style } from '@boost/terminal'; 2 | 3 | export function applyMarkdown(text: string): string { 4 | return text.replace(/(?:\*|~|_){1,2}([^*~_]+)(?:\*|~|_){1,2}/giu, (match, body) => { 5 | if (match.startsWith('~')) { 6 | return style.strikethrough(body); 7 | } 8 | 9 | if (match.startsWith('**') || match.startsWith('__')) { 10 | return style.bold(body); 11 | } 12 | 13 | if (match.startsWith('*') || match.startsWith('_')) { 14 | return style.italic(body); 15 | } 16 | 17 | // istanbul ignore next 18 | return match; 19 | }); 20 | } 21 | -------------------------------------------------------------------------------- /packages/cli/src/helpers/applyStyle.ts: -------------------------------------------------------------------------------- 1 | import { style } from '@boost/terminal'; 2 | import type { StyleType } from '../types'; 3 | import { loadTheme } from './loadTheme'; 4 | 5 | export function applyStyle(text: string, type: StyleType): string { 6 | const color = loadTheme()[type]; 7 | const apply = color.startsWith('#') ? style.hex(color) : style[color as 'black']; 8 | 9 | return apply(text); 10 | } 11 | -------------------------------------------------------------------------------- /packages/cli/src/helpers/formatCommandCall.ts: -------------------------------------------------------------------------------- 1 | import type { CommandConfig } from '../types'; 2 | import { formatType } from './formatType'; 3 | 4 | export function formatCommandCall(name: string, metadata: CommandConfig): string { 5 | let output = name; 6 | 7 | if (metadata.params) { 8 | metadata.params.forEach((param) => { 9 | output += ' '; 10 | output += formatType(param, true); 11 | }); 12 | } 13 | 14 | return output; 15 | } 16 | -------------------------------------------------------------------------------- /packages/cli/src/helpers/formatType.ts: -------------------------------------------------------------------------------- 1 | import { applyStyle } from './applyStyle'; 2 | 3 | export function formatType( 4 | config: { 5 | label?: string; 6 | multiple?: boolean; 7 | required?: boolean; 8 | type: string; 9 | }, 10 | inline: boolean = false, 11 | ): string { 12 | let type = config.type + (config.multiple ? '[]' : ''); 13 | 14 | if (inline) { 15 | if (config.label) { 16 | type = config.label; 17 | } 18 | 19 | type = config.required ? type : `[${type}]`; 20 | } 21 | 22 | return applyStyle(type, 'muted'); 23 | } 24 | -------------------------------------------------------------------------------- /packages/cli/src/helpers/formatValue.ts: -------------------------------------------------------------------------------- 1 | import type { PrimitiveType } from '@boost/args'; 2 | 3 | export function formatValue(value: PrimitiveType): string { 4 | switch (typeof value) { 5 | case 'string': 6 | return `"${value}"`; 7 | default: 8 | return String(value); 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /packages/cli/src/helpers/getLongestWidth.ts: -------------------------------------------------------------------------------- 1 | import { stripAnsi } from '@boost/terminal'; 2 | 3 | export function getLongestWidth(values: string[]): number { 4 | return values.reduce((sum, value) => { 5 | const text = stripAnsi(value); 6 | 7 | return text.length > sum ? text.length : sum; 8 | }, 0); 9 | } 10 | -------------------------------------------------------------------------------- /packages/cli/src/helpers/index.ts: -------------------------------------------------------------------------------- 1 | export * from './applyMarkdown'; 2 | export * from './applyStyle'; 3 | export * from './formatCommandCall'; 4 | export * from './formatDescription'; 5 | export * from './formatType'; 6 | export * from './formatValue'; 7 | export * from './getLongestWidth'; 8 | export * from './groupByCategory'; 9 | export * from './isArgvSize'; 10 | export * from './loadTheme'; 11 | export * from './mapCommandMetadata'; 12 | -------------------------------------------------------------------------------- /packages/cli/src/helpers/isArgvSize.ts: -------------------------------------------------------------------------------- 1 | import type { Argv } from '../types'; 2 | import { isNodeBinary } from './isNodeBinary'; 3 | 4 | export function isArgvSize(argv: Argv, size: number): boolean { 5 | let list = [...argv]; 6 | 7 | // Node process binaries are included 8 | if (list.length > 0 && isNodeBinary(list[0])) { 9 | list = list.slice(2); 10 | } 11 | 12 | // Rest args are included 13 | list.some((arg, index) => { 14 | if (arg === '--') { 15 | list = list.slice(0, index); 16 | 17 | return true; 18 | } 19 | 20 | return false; 21 | }); 22 | 23 | return list.length === size; 24 | } 25 | -------------------------------------------------------------------------------- /packages/cli/src/helpers/isNodeBinary.ts: -------------------------------------------------------------------------------- 1 | export function isNodeBinary(bin: string): boolean { 2 | return Boolean(bin.match(/(\/|\\)node(js)?(\.exe)?$/u)); 3 | } 4 | -------------------------------------------------------------------------------- /packages/cli/src/helpers/mapCommandMetadata.ts: -------------------------------------------------------------------------------- 1 | import type { Commandable, CommandMetadataMap } from '../types'; 2 | 3 | export function mapCommandMetadata(commands: Record) { 4 | const map: CommandMetadataMap = {}; 5 | 6 | Object.entries(commands).forEach(([path, config]) => { 7 | map[path] = config.getMetadata(); 8 | }); 9 | 10 | return map; 11 | } 12 | -------------------------------------------------------------------------------- /packages/cli/src/helpers/patchDebugModule.ts: -------------------------------------------------------------------------------- 1 | /* eslint-disable no-console */ 2 | 3 | import { createRequire } from 'node:module'; 4 | 5 | const requireDebug = createRequire(import.meta.url); 6 | 7 | /** 8 | * Wrap the `debug` stream since it writes to `process.stderr` directly. 9 | * https://www.npmjs.com/package/debug#output-streams 10 | */ 11 | export function patchDebugModule(): () => void { 12 | if (!process.env.DEBUG) { 13 | return () => {}; 14 | } 15 | 16 | const debug = requireDebug('debug') as typeof import('debug'); 17 | const originalLog = debug.log; 18 | 19 | debug.log = console.error.bind(console); 20 | 21 | return () => { 22 | debug.log = originalLog; 23 | }; 24 | } 25 | -------------------------------------------------------------------------------- /packages/cli/src/hooks/index.ts: -------------------------------------------------------------------------------- 1 | export * from './useDimensions'; 2 | export * from './useIsMounted'; 3 | export * from './useListNavigation'; 4 | export * from './useProgram'; 5 | export * from './useRenderLoop'; 6 | -------------------------------------------------------------------------------- /packages/cli/src/hooks/useDimensions.ts: -------------------------------------------------------------------------------- 1 | import { useEffect, useState } from 'react'; 2 | import { useStdout } from 'ink'; 3 | import { screen } from '@boost/terminal'; 4 | 5 | export function useDimensions(): { height: number; width: number } { 6 | const [dims, setDims] = useState(() => screen.size()); 7 | const { stdout } = useStdout(); 8 | 9 | useEffect(() => { 10 | // istanbul ignore next 11 | const handler = () => { 12 | setDims(screen.size()); 13 | }; 14 | 15 | stdout?.on('resize', handler); 16 | 17 | return () => { 18 | stdout?.off('resize', handler); 19 | }; 20 | }, [stdout]); 21 | 22 | return { 23 | height: dims.rows, 24 | width: dims.columns, 25 | }; 26 | } 27 | -------------------------------------------------------------------------------- /packages/cli/src/hooks/useIsMounted.ts: -------------------------------------------------------------------------------- 1 | import { useEffect, useRef } from 'react'; 2 | 3 | export function useIsMounted() { 4 | const mounted = useRef(false); 5 | 6 | useEffect(() => { 7 | mounted.current = true; 8 | 9 | return () => { 10 | mounted.current = false; 11 | }; 12 | }, []); 13 | 14 | return mounted; 15 | } 16 | -------------------------------------------------------------------------------- /packages/cli/src/hooks/useRenderLoop.ts: -------------------------------------------------------------------------------- 1 | /* eslint-disable no-magic-numbers */ 2 | 3 | import { useCallback, useEffect, useReducer, useRef } from 'react'; 4 | 5 | export function useRenderLoop(fps: number = 30): () => void { 6 | const [, forceUpdate] = useReducer((count: number) => count + 1, 0); 7 | const timer = useRef(); 8 | 9 | const clear = useCallback(() => { 10 | if (timer.current) { 11 | clearInterval(timer.current); 12 | } 13 | }, []); 14 | 15 | useEffect(() => { 16 | timer.current = setInterval(forceUpdate, fps / 1000); 17 | 18 | return clear; 19 | }, [clear, fps]); 20 | 21 | return clear; 22 | } 23 | -------------------------------------------------------------------------------- /packages/cli/src/index.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * @copyright 2020, Miles Johnson 3 | * @license https://opensource.org/licenses/MIT 4 | */ 5 | 6 | export * from './CLIError'; 7 | export * from './Command'; 8 | export * from './constants'; 9 | export { Config } from './decorators/Config'; 10 | export * from './helpers'; 11 | export * as Arg from './metadata/args'; 12 | export * from './middleware'; 13 | export * from './Program'; 14 | export * from './types'; 15 | -------------------------------------------------------------------------------- /packages/cli/src/initializers/flag.ts: -------------------------------------------------------------------------------- 1 | import type { Flag as FlagConfig } from '@boost/args'; 2 | import { createOptionInitializer } from '../metadata/createOptionInitializer'; 3 | import type { PartialConfig } from '../types'; 4 | 5 | /** 6 | * A property initializer for declaring a command line flag (boolean value). 7 | */ 8 | export function flag(description: string, config?: PartialConfig): boolean { 9 | return createOptionInitializer({ 10 | default: false, 11 | ...config, 12 | description, 13 | type: 'boolean', 14 | }); 15 | } 16 | -------------------------------------------------------------------------------- /packages/cli/src/initializers/index.ts: -------------------------------------------------------------------------------- 1 | export { flag } from './flag'; 2 | export { number } from './number'; 3 | export { numbers } from './numbers'; 4 | export { params } from './params'; 5 | export { string } from './string'; 6 | export { strings } from './strings'; 7 | -------------------------------------------------------------------------------- /packages/cli/src/initializers/number.ts: -------------------------------------------------------------------------------- 1 | import type { SingleOption } from '@boost/args'; 2 | import { createOptionInitializer } from '../metadata/createOptionInitializer'; 3 | import type { PartialConfig } from '../types'; 4 | 5 | /** 6 | * A property initializer for declaring a command line option with a numeric value. 7 | */ 8 | export function number( 9 | description: string, 10 | config?: PartialConfig>, 11 | ): T { 12 | return createOptionInitializer, T>({ 13 | default: 0, 14 | ...config, 15 | description, 16 | type: 'number', 17 | }); 18 | } 19 | -------------------------------------------------------------------------------- /packages/cli/src/initializers/numbers.ts: -------------------------------------------------------------------------------- 1 | import type { MultipleOption } from '@boost/args'; 2 | import { createOptionInitializer } from '../metadata/createOptionInitializer'; 3 | import type { PartialConfig } from '../types'; 4 | 5 | /** 6 | * A property initializer for declaring a command line option with multiple numeric values. 7 | */ 8 | export function numbers( 9 | description: string, 10 | config?: PartialConfig>, 11 | ): T { 12 | return createOptionInitializer, T>({ 13 | default: [], 14 | ...config, 15 | description, 16 | multiple: true, 17 | type: 'number', 18 | }); 19 | } 20 | -------------------------------------------------------------------------------- /packages/cli/src/initializers/params.ts: -------------------------------------------------------------------------------- 1 | import type { MapParamConfig, PrimitiveType } from '@boost/args'; 2 | 3 | /** 4 | * A property initializer for declaring command line parameters (positional arguments). 5 | */ 6 | export function params( 7 | ...config: MapParamConfig 8 | ): MapParamConfig { 9 | // This exists for type checking and convenience 10 | return config; 11 | } 12 | -------------------------------------------------------------------------------- /packages/cli/src/initializers/string.ts: -------------------------------------------------------------------------------- 1 | import type { SingleOption } from '@boost/args'; 2 | import { createOptionInitializer } from '../metadata/createOptionInitializer'; 3 | import type { PartialConfig } from '../types'; 4 | 5 | /** 6 | * A property initializer for declaring a command line option with a string value. 7 | */ 8 | export function string( 9 | description: string, 10 | config?: PartialConfig>, 11 | ): T { 12 | return createOptionInitializer, T>({ 13 | default: '', 14 | ...config, 15 | description, 16 | type: 'string', 17 | }); 18 | } 19 | -------------------------------------------------------------------------------- /packages/cli/src/initializers/strings.ts: -------------------------------------------------------------------------------- 1 | import type { MultipleOption } from '@boost/args'; 2 | import { createOptionInitializer } from '../metadata/createOptionInitializer'; 3 | import type { PartialConfig } from '../types'; 4 | 5 | /** 6 | * A property initializer for declaring a command line option with multiple string values. 7 | */ 8 | export function strings( 9 | description: string, 10 | config?: PartialConfig>, 11 | ): T { 12 | return createOptionInitializer, T>({ 13 | default: [], 14 | ...config, 15 | description, 16 | multiple: true, 17 | type: 'string', 18 | }); 19 | } 20 | -------------------------------------------------------------------------------- /packages/cli/src/metadata/args.ts: -------------------------------------------------------------------------------- 1 | export * from '../decorators'; 2 | export * from '../initializers'; 3 | -------------------------------------------------------------------------------- /packages/cli/src/metadata/createOptionDecorator.ts: -------------------------------------------------------------------------------- 1 | import type { Option } from '@boost/args'; 2 | import { registerOption } from './registerOption'; 3 | 4 | // eslint-disable-next-line @typescript-eslint/no-explicit-any 5 | export function createOptionDecorator>(config: O): PropertyDecorator { 6 | return (target, name) => { 7 | registerOption(target, name, config); 8 | }; 9 | } 10 | -------------------------------------------------------------------------------- /packages/cli/src/metadata/getConstructor.ts: -------------------------------------------------------------------------------- 1 | import type { CommandStaticConfig } from '../types'; 2 | 3 | export function getConstructor(target: Object): CommandStaticConfig { 4 | return target.constructor as unknown as CommandStaticConfig; 5 | } 6 | -------------------------------------------------------------------------------- /packages/cli/src/metadata/getInheritedCategories.ts: -------------------------------------------------------------------------------- 1 | /* eslint-disable @typescript-eslint/no-unsafe-argument */ 2 | /* eslint-disable @typescript-eslint/no-unsafe-assignment */ 3 | 4 | import type { Categories } from '../types'; 5 | import { getConstructor } from './getConstructor'; 6 | 7 | export function getInheritedCategories(base: Object): Categories { 8 | const categories: Categories = {}; 9 | let target = Object.getPrototypeOf(base); 10 | 11 | while (target) { 12 | const ctor = getConstructor(target); 13 | 14 | if (ctor.categories) { 15 | Object.assign(categories, ctor.categories); 16 | } else { 17 | break; 18 | } 19 | 20 | target = Object.getPrototypeOf(target); 21 | } 22 | 23 | return categories; 24 | } 25 | -------------------------------------------------------------------------------- /packages/cli/src/metadata/getInheritedOptions.ts: -------------------------------------------------------------------------------- 1 | /* eslint-disable @typescript-eslint/no-unsafe-argument */ 2 | /* eslint-disable @typescript-eslint/no-unsafe-assignment */ 3 | 4 | import type { OptionConfigMap } from '@boost/args'; 5 | import { getConstructor } from './getConstructor'; 6 | 7 | export function getInheritedOptions(base: Object): OptionConfigMap { 8 | const options: OptionConfigMap = {}; 9 | let target = Object.getPrototypeOf(base); 10 | 11 | while (target) { 12 | const ctor = getConstructor(target); 13 | 14 | if (ctor.options) { 15 | Object.assign(options, ctor.options); 16 | } else { 17 | break; 18 | } 19 | 20 | target = Object.getPrototypeOf(target); 21 | } 22 | 23 | return options; 24 | } 25 | -------------------------------------------------------------------------------- /packages/cli/src/metadata/registerParams.ts: -------------------------------------------------------------------------------- 1 | import type { ParamConfig } from '@boost/args'; 2 | import { CLIError } from '../CLIError'; 3 | import { getConstructor } from './getConstructor'; 4 | 5 | export function registerParams(target: Object, method: string | symbol, config: ParamConfig[]) { 6 | if (method !== 'run') { 7 | throw new CLIError('PARAMS_RUN_ONLY'); 8 | } 9 | 10 | getConstructor(target).params = config; 11 | } 12 | -------------------------------------------------------------------------------- /packages/cli/src/metadata/validateConfig.ts: -------------------------------------------------------------------------------- 1 | import { optimal } from '@boost/common/optimal'; 2 | import type { CommandStaticConfig } from '../types'; 3 | import { commandConstructorBlueprint } from './blueprints'; 4 | 5 | export function validateConfig( 6 | name: string, 7 | config: Omit, 8 | ) { 9 | optimal(commandConstructorBlueprint, { 10 | name, 11 | unknown: true, 12 | }).validate(config); 13 | } 14 | -------------------------------------------------------------------------------- /packages/cli/src/metadata/validateParams.ts: -------------------------------------------------------------------------------- 1 | import { type ParamConfigList } from '@boost/args'; 2 | import { optimal } from '@boost/common/optimal'; 3 | import { msg } from '../translate'; 4 | import { paramBlueprint } from './blueprints'; 5 | 6 | export function validateParams(params: ParamConfigList) { 7 | params.forEach((config, index) => 8 | optimal(paramBlueprint, { 9 | name: msg('cli:labelParam', { name: config.label ?? index }), 10 | unknown: false, 11 | }).validate(config), 12 | ); 13 | } 14 | -------------------------------------------------------------------------------- /packages/cli/src/middleware/index.ts: -------------------------------------------------------------------------------- 1 | export * from './checkNodeRequirement'; 2 | export * from './checkPackageOutdated'; 3 | -------------------------------------------------------------------------------- /packages/cli/src/middleware/removeProcessBin.ts: -------------------------------------------------------------------------------- 1 | import { isNodeBinary } from '../helpers/isNodeBinary'; 2 | import type { Middleware } from '../types'; 3 | 4 | export function removeProcessBin(): Middleware { 5 | return (argv, parse) => parse(argv.length > 0 && isNodeBinary(argv[0]) ? argv.slice(2) : argv); 6 | } 7 | -------------------------------------------------------------------------------- /packages/cli/src/react.ts: -------------------------------------------------------------------------------- 1 | export * from './components'; 2 | export * from './hooks'; 3 | export * from './ProgramContext'; 4 | -------------------------------------------------------------------------------- /packages/cli/src/translate.ts: -------------------------------------------------------------------------------- 1 | import path from 'node:path'; 2 | import { fileURLToPath } from 'node:url'; 3 | import { createTranslator } from '@boost/translate'; 4 | 5 | export const msg = await createTranslator( 6 | ['cli', 'prompt'], 7 | path.join(path.dirname(fileURLToPath(import.meta.url)), '../res'), 8 | ); 9 | -------------------------------------------------------------------------------- /packages/cli/tests/LogBuffer.test.ts: -------------------------------------------------------------------------------- 1 | import { describe, expect, it, vi } from 'vitest'; 2 | import { LogBuffer } from '../src/LogBuffer'; 3 | 4 | describe('LogBuffer', () => { 5 | it('removes listener when calling return function', () => { 6 | const spy = vi.fn(); 7 | const buffer = new LogBuffer(process.stdout); 8 | 9 | const undo = buffer.on(spy); 10 | 11 | // @ts-expect-error Allow access 12 | expect(buffer.listener).toBe(spy); 13 | 14 | undo(); 15 | 16 | // @ts-expect-error Allow access 17 | expect(buffer.listener).toBeUndefined(); 18 | }); 19 | }); 20 | -------------------------------------------------------------------------------- /packages/cli/tests/__fixtures__/BuildDecoratorCommand.ts: -------------------------------------------------------------------------------- 1 | import { Arg, Command, Config, type GlobalOptions } from '../../src'; 2 | 3 | export interface BuildOptions extends GlobalOptions { 4 | dst: string; 5 | src: string; 6 | } 7 | 8 | @Config('build', 'Build a project', { 9 | aliases: ['compile'], 10 | category: 'setup', 11 | usage: 'build -S ./src -D ./lib', 12 | }) 13 | export class BuildDecoratorCommand extends Command { 14 | // --dst, -D 15 | @Arg.String('Destination path', { short: 'D' }) 16 | dst: string = ''; 17 | 18 | // --src, -S 19 | @Arg.String('Source path', { short: 'S' }) 20 | src: string = './src'; 21 | 22 | async run() { 23 | await Promise.resolve(); 24 | 25 | return 'Build!'; 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /packages/cli/tests/__snapshots__/Header.test.tsx.snap: -------------------------------------------------------------------------------- 1 | // Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html 2 | 3 | exports[`
> renders \`default\` 1`] = ` 4 | " 5 |  TITLE  6 | " 7 | `; 8 | 9 | exports[`
> renders \`failure\` 1`] = ` 10 | " 11 |  TITLE  12 | " 13 | `; 14 | 15 | exports[`
> renders \`muted\` 1`] = ` 16 | " 17 |  TITLE  18 | " 19 | `; 20 | 21 | exports[`
> renders \`success\` 1`] = ` 22 | " 23 |  TITLE  24 | " 25 | `; 26 | 27 | exports[`
> renders \`warning\` 1`] = ` 28 | " 29 |  TITLE  30 | " 31 | `; 32 | -------------------------------------------------------------------------------- /packages/cli/tests/components/__snapshots__/HiddenInput.test.tsx.snap: -------------------------------------------------------------------------------- 1 | // Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html 2 | 3 | exports[`HiddenInput > renders default value as stars 1`] = `"? Age?"`; 4 | 5 | exports[`HiddenInput > renders entered text as stars 1`] = `"? Age?"`; 6 | 7 | exports[`HiddenInput > renders label by default 1`] = `"? Age?"`; 8 | 9 | exports[`HiddenInput > renders placeholder if no default value 1`] = `"? Age? "`; 10 | -------------------------------------------------------------------------------- /packages/cli/tests/components/__snapshots__/PasswordInput.test.tsx.snap: -------------------------------------------------------------------------------- 1 | // Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html 2 | 3 | exports[`PasswordInput > renders default value as stars 1`] = `"? Password? ****"`; 4 | 5 | exports[`PasswordInput > renders entered text as stars 1`] = `"? Password? *"`; 6 | 7 | exports[`PasswordInput > renders label by default 1`] = `"? Password?  "`; 8 | 9 | exports[`PasswordInput > renders placeholder if no default value 1`] = `"? Password? "`; 10 | -------------------------------------------------------------------------------- /packages/cli/tests/components/internal/Label.test.tsx: -------------------------------------------------------------------------------- 1 | import { Text } from 'ink'; 2 | import { render } from 'ink-testing-library'; 3 | import { describe, expect, it } from 'vitest'; 4 | import { Label } from '../../../src/components/internal/Label'; 5 | 6 | describe('Label', () => { 7 | it('renders a string wrapped in text', () => { 8 | const { lastFrame } = render(); 9 | 10 | expect(lastFrame()).toMatchSnapshot(); 11 | }); 12 | 13 | it('renders an element', () => { 14 | const { lastFrame } = render( 15 | , 18 | ); 19 | 20 | expect(lastFrame()).toMatchSnapshot(); 21 | }); 22 | }); 23 | -------------------------------------------------------------------------------- /packages/cli/tests/components/internal/__snapshots__/Cursor.test.tsx.snap: -------------------------------------------------------------------------------- 1 | // Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html 2 | 3 | exports[`Cursor > renders cursor after value 1`] = `"Some string of text "`; 4 | 5 | exports[`Cursor > renders cursor at the end 1`] = `"Some string of text"`; 6 | 7 | exports[`Cursor > renders cursor at the start 1`] = `"Some string of text"`; 8 | 9 | exports[`Cursor > renders cursor in the middle 1`] = `"Some string of text"`; 10 | 11 | exports[`Cursor > renders no cursor if \`hideCursor\` is passed 1`] = `"Some string of text"`; 12 | 13 | exports[`Cursor > renders value with no cursor if not focused 1`] = `"Some string of text"`; 14 | -------------------------------------------------------------------------------- /packages/cli/tests/components/internal/__snapshots__/Label.test.tsx.snap: -------------------------------------------------------------------------------- 1 | // Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html 2 | 3 | exports[`Label > renders a string wrapped in text 1`] = `"Content"`; 4 | 5 | exports[`Label > renders an element 1`] = `"Content"`; 6 | -------------------------------------------------------------------------------- /packages/cli/tests/helpers/patchDebugModule.test.ts: -------------------------------------------------------------------------------- 1 | import debug from 'debug'; 2 | import { describe, expect, it, vi } from 'vitest'; 3 | import { patchDebugModule } from '../../src/helpers/patchDebugModule'; 4 | 5 | describe('patchDebugModule()', () => { 6 | it('wraps `debug`', () => { 7 | // We need to set env var before hand 8 | process.env.DEBUG = '*'; 9 | 10 | const inst = debug('boostcli:test'); 11 | const spy = vi.spyOn(console, 'error').mockImplementation(() => {}); 12 | const unpatch = patchDebugModule(); 13 | 14 | debug.enable('boostcli:*'); 15 | inst('Debugging'); 16 | 17 | expect(spy).toHaveBeenCalledWith(expect.stringContaining('boostcli:test Debugging')); 18 | 19 | unpatch(); 20 | spy.mockRestore(); 21 | }); 22 | }); 23 | -------------------------------------------------------------------------------- /packages/cli/tests/hooks/__snapshots__/useProgram.test.tsx.snap: -------------------------------------------------------------------------------- 1 | // Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html 2 | 3 | exports[`Input > custom \`exit\` doesnt cause an infinite loop 1`] = `""`; 4 | -------------------------------------------------------------------------------- /packages/cli/tests/hooks/useProgram.test.tsx: -------------------------------------------------------------------------------- 1 | import { useEffect } from 'react'; 2 | import { Box } from 'ink'; 3 | import { render } from 'ink-testing-library'; 4 | import { describe, expect, it } from 'vitest'; 5 | import { useProgram } from '../../src/hooks/useProgram'; 6 | 7 | describe('Input', () => { 8 | function TestProgram() { 9 | const program = useProgram(); 10 | 11 | useEffect(() => {}, [program.exit]); 12 | 13 | return ; 14 | } 15 | 16 | it('custom `exit` doesnt cause an infinite loop', () => { 17 | const { lastFrame } = render(); 18 | 19 | expect(lastFrame()).toMatchSnapshot(); 20 | }); 21 | }); 22 | -------------------------------------------------------------------------------- /packages/cli/tsconfig.mjs.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../../tsconfig.options.json", 3 | "compilerOptions": { 4 | "outDir": "mjs", 5 | "rootDir": "src", 6 | "emitDeclarationOnly": true 7 | }, 8 | "include": [ 9 | "src/**/*", 10 | "../../types/**/*" 11 | ] 12 | } 13 | -------------------------------------------------------------------------------- /packages/common/README.md: -------------------------------------------------------------------------------- 1 | # Common utilities - Boost 2 | 3 | ![build status](https://img.shields.io/github/actions/workflow/status/milesj/boost/build.yml) 4 | ![npm version](https://img.shields.io/npm/v/@boost/common) 5 | 6 | A collection of common utilities and helpers for general purpose or Boost packages. 7 | 8 | ```ts 9 | import { isObject, toArray } from '@boost/common'; 10 | ``` 11 | 12 | ## Installation 13 | 14 | ``` 15 | yarn add @boost/common 16 | ``` 17 | 18 | ## Documentation 19 | 20 | - [https://boostlib.dev/docs/common](https://boostlib.dev/docs/common) 21 | - [https://boostlib.dev/api/common](https://boostlib.dev/api/common) 22 | -------------------------------------------------------------------------------- /packages/common/src/CommonError.ts: -------------------------------------------------------------------------------- 1 | import { createScopedError } from '@boost/internal'; 2 | 3 | const errors = { 4 | PARSE_INVALID_EXT: 'Unable to parse file "{0}". Unsupported file extension.', 5 | PATH_REQUIRE_ABSOLUTE: 'An absolute file path is required.', 6 | PATH_RESOLVE_LOOKUPS: 'Failed to resolve a path using the following lookups (in order):\n{0}\n', 7 | PROJECT_NO_PACKAGE: 'No `package.json` found within project root.', 8 | }; 9 | 10 | export type CommonErrorCode = keyof typeof errors; 11 | 12 | export const CommonError = createScopedError('CMN', 'CommonError', errors); 13 | -------------------------------------------------------------------------------- /packages/common/src/ExitError.ts: -------------------------------------------------------------------------------- 1 | export class ExitError extends Error { 2 | code: number; 3 | 4 | constructor(message: string, code: number) { 5 | super(message); 6 | 7 | this.code = code; 8 | this.name = 'ExitError'; 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /packages/common/src/constants.ts: -------------------------------------------------------------------------------- 1 | // https://github.com/npm/validate-npm-package-name 2 | export const MODULE_NAME_PART = /[a-z0-9]{1}[-a-z0-9_.]*/u; 3 | 4 | export const MODULE_NAME_PATTERN = new RegExp( 5 | `^(?:@(${MODULE_NAME_PART.source})/)?(${MODULE_NAME_PART.source})$`, 6 | 'u', 7 | ); 8 | -------------------------------------------------------------------------------- /packages/common/src/helpers/formatMs.ts: -------------------------------------------------------------------------------- 1 | import prettyMs, { type Options } from 'pretty-ms'; 2 | 3 | /** 4 | * Can be used to format a UNIX timestamp in milliseconds into a shorthand human readable format. 5 | * Wraps the [pretty-ms](https://www.npmjs.com/package/pretty-ms) package to handle infinite 6 | * numbers, zeros, and more. 7 | * 8 | * ```ts 9 | * import { formatMs } from '@boost/common'; 10 | * 11 | * formatMs(1337000000); // 15d 11h 23m 20s 12 | * ``` 13 | */ 14 | export function formatMs(ms: number, options?: Options): string { 15 | if (!Number.isFinite(ms) || ms === 0) { 16 | return '0s'; 17 | } 18 | 19 | return prettyMs(ms, { keepDecimalsOnWholeSeconds: true, ...options }); 20 | } 21 | -------------------------------------------------------------------------------- /packages/common/src/helpers/index.ts: -------------------------------------------------------------------------------- 1 | export * from './createBlueprint'; 2 | export * from './deepFreeze'; 3 | export * from './deepMerge'; 4 | export * from './formatMs'; 5 | export * from './instanceOf'; 6 | export * from './isEmpty'; 7 | export * from './isFilePath'; 8 | export * from './isModuleName'; 9 | export * from './isObject'; 10 | export * from './isPlainObject'; 11 | export * from './toArray'; 12 | -------------------------------------------------------------------------------- /packages/common/src/helpers/isEmpty.ts: -------------------------------------------------------------------------------- 1 | import { isObject } from './isObject'; 2 | 3 | /** 4 | * Returns `true` if an object has no properties, an array has no items, 5 | * or the value is falsy, otherwise, it returns `false`. 6 | * 7 | * ```ts 8 | * import { isEmpty } from '@boost/common'; 9 | * 10 | * isEmpty({}); // true 11 | * isEmpty({ name: 'Boost' }); // false 12 | * 13 | * isEmpty([]); // true 14 | * isEmpty(['Boost']); // false 15 | * ``` 16 | */ 17 | export function isEmpty(value: unknown): boolean { 18 | return ( 19 | !value || 20 | (Array.isArray(value) && value.length === 0) || 21 | (isObject(value) && Object.keys(value).length === 0) || 22 | false 23 | ); 24 | } 25 | -------------------------------------------------------------------------------- /packages/common/src/helpers/isObject.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Returns `true` if the value is an object. 3 | * 4 | * ```ts 5 | * import { isObject } from '@boost/common'; 6 | * 7 | * isObject({}); // true 8 | * isObject(new Foo()); // true 9 | * isObject([]); // false 10 | * ``` 11 | * 12 | * Generics can be used to type the return value of the object (when necessary). 13 | * 14 | * ```ts 15 | * interface Person { 16 | * name: string; 17 | * } 18 | * 19 | * if (isObject(person)) { 20 | * console.log(person.name); 21 | * } 22 | * ``` 23 | */ 24 | export function isObject(value: unknown): value is T { 25 | return typeof value === 'object' && value !== null && !Array.isArray(value); 26 | } 27 | -------------------------------------------------------------------------------- /packages/common/src/helpers/toArray.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Converts a non-array to an array. If the provided value is falsy, 3 | * an empty array is returned. If the provided value is truthy and a 4 | * non-array, an array of 1 item is returned. 5 | * 6 | * ```ts 7 | * import { toArray } from '@boost/common'; 8 | * 9 | * toArray(123); // [123] 10 | * toArray('abc'); // ['abc'] 11 | * toArray(['a', 'b', 'c']); // ['a', 'b', 'c'] 12 | * ``` 13 | */ 14 | export function toArray(value?: T | T[]): T[] { 15 | if (value === undefined) { 16 | return []; 17 | } 18 | 19 | return Array.isArray(value) ? value : [value]; 20 | } 21 | -------------------------------------------------------------------------------- /packages/common/src/index.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * @copyright 2020, Miles Johnson 3 | * @license https://opensource.org/licenses/MIT 4 | */ 5 | 6 | export * from './CommonError'; 7 | export * from './constants'; 8 | export * from './Contract'; 9 | export * from './ExitError'; 10 | export * from './helpers'; 11 | export * from './ModulePath'; 12 | export * from './PackageGraph'; 13 | export * from './Path'; 14 | export * from './PathResolver'; 15 | export * from './Project'; 16 | export * as json from './serializers/json'; 17 | export * as yaml from './serializers/yaml'; 18 | export * from './types'; 19 | export * from './VirtualPath'; 20 | export * from '@boost/decorators'; 21 | export type { Blueprint, DeepPartial, Schemas } from 'optimal'; 22 | -------------------------------------------------------------------------------- /packages/common/src/optimal.ts: -------------------------------------------------------------------------------- 1 | import { instance, shape, string, union } from 'optimal'; 2 | import { Path } from './Path'; 3 | import type { PortablePath } from './types'; 4 | 5 | export * from 'optimal'; 6 | 7 | /** 8 | * A schema for validating a value is a `PortablePath`. 9 | * Checks for a string, `Path`, or `Pathable`. 10 | */ 11 | export const portablePathSchema = union('').of([ 12 | string(), 13 | instance().of(Path), 14 | instance().of(Path, { loose: true }), 15 | shape({ 16 | path: string(), 17 | }), 18 | ]); 19 | -------------------------------------------------------------------------------- /packages/common/tests/ExitError.test.ts: -------------------------------------------------------------------------------- 1 | import { describe, expect, it } from 'vitest'; 2 | import { ExitError } from '../src/ExitError'; 3 | 4 | describe('ExitError', () => { 5 | it('sets the message and exit code', () => { 6 | const error = new ExitError('Oops', 3); 7 | 8 | expect(error.message).toBe('Oops'); 9 | expect(error.code).toBe(3); 10 | }); 11 | }); 12 | -------------------------------------------------------------------------------- /packages/common/tests/helpers/__fixtures__/default-export.ts: -------------------------------------------------------------------------------- 1 | // eslint-disable-next-line import/no-default-export 2 | export default 'default'; 3 | -------------------------------------------------------------------------------- /packages/common/tests/helpers/__fixtures__/default-named-exports.ts: -------------------------------------------------------------------------------- 1 | export const a = 1; 2 | export const b = 2; 3 | export const c = 3; 4 | 5 | // eslint-disable-next-line import/no-default-export 6 | export default 'default'; 7 | -------------------------------------------------------------------------------- /packages/common/tests/helpers/__fixtures__/imports.ts: -------------------------------------------------------------------------------- 1 | import defaultExport from './default-export'; 2 | import * as defaultNamedExports from './default-named-exports'; 3 | import * as namedExports from './named-exports'; 4 | 5 | // eslint-disable-next-line import/no-default-export 6 | export default { 7 | defaultExport, 8 | defaultNamedExports, 9 | namedExports, 10 | }; 11 | -------------------------------------------------------------------------------- /packages/common/tests/helpers/__fixtures__/named-exports.ts: -------------------------------------------------------------------------------- 1 | export const a = 1; 2 | export const b = 2; 3 | export const c = 3; 4 | -------------------------------------------------------------------------------- /packages/common/tests/helpers/__snapshots__/deepFreeze.test.ts.snap: -------------------------------------------------------------------------------- 1 | // Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html 2 | 3 | exports[`deepFreeze() > returns a frozen object 1`] = `[TypeError: Cannot assign to read only property 'bar' of object '#']`; 4 | -------------------------------------------------------------------------------- /packages/common/tests/helpers/createBlueprint.test.ts: -------------------------------------------------------------------------------- 1 | import { describe, expect, it } from 'vitest'; 2 | import { createBlueprint } from '../../src/helpers/createBlueprint'; 3 | 4 | describe('createBlueprint()', () => { 5 | it('returns a blueprint', () => { 6 | const blueprint = createBlueprint((schemas) => ({ 7 | foo: schemas.string(), 8 | })); 9 | 10 | expect(blueprint).toHaveProperty('foo'); 11 | expect(blueprint.foo.schema()).toBe('string'); 12 | }); 13 | }); 14 | -------------------------------------------------------------------------------- /packages/common/tests/helpers/formatMs.test.ts: -------------------------------------------------------------------------------- 1 | import { describe, expect, it } from 'vitest'; 2 | import { formatMs } from '../../src/helpers/formatMs'; 3 | 4 | describe('formatMs()', () => { 5 | it('handles zero', () => { 6 | expect(formatMs(0)).toBe('0s'); 7 | }); 8 | 9 | it('formats large milliseconds', () => { 10 | expect(formatMs(482_639_237)).toBe('5d 14h 3m 59.2s'); 11 | }); 12 | }); 13 | -------------------------------------------------------------------------------- /packages/common/tests/helpers/toArray.test.ts: -------------------------------------------------------------------------------- 1 | import { describe, expect, it } from 'vitest'; 2 | import { toArray } from '../../src/helpers/toArray'; 3 | 4 | describe('toArray()', () => { 5 | it('returns an empty array for undefined', () => { 6 | expect(toArray()).toEqual([]); 7 | expect(toArray(undefined)).toEqual([]); 8 | }); 9 | 10 | it('returns an array as is', () => { 11 | expect(toArray([1, 2, 3])).toEqual([1, 2, 3]); 12 | }); 13 | 14 | it('returns non-arrays as an array of 1 item', () => { 15 | expect(toArray(123)).toEqual([123]); 16 | expect(toArray(true)).toEqual([true]); 17 | expect(toArray(null)).toEqual([null]); 18 | expect(toArray('abc')).toEqual(['abc']); 19 | expect(toArray({})).toEqual([{}]); 20 | }); 21 | }); 22 | -------------------------------------------------------------------------------- /packages/common/tests/serializers/__fixtures__/test.json: -------------------------------------------------------------------------------- 1 | { 2 | "foo": 123, 3 | "bar": true, 4 | "baz": "abc", 5 | "qux": {} 6 | } 7 | -------------------------------------------------------------------------------- /packages/common/tests/serializers/__fixtures__/test.yaml: -------------------------------------------------------------------------------- 1 | foo: 123 2 | bar: true 3 | baz: abc 4 | qux: {} 5 | -------------------------------------------------------------------------------- /packages/common/tests/serializers/json.test.ts: -------------------------------------------------------------------------------- 1 | import path from 'node:path'; 2 | import { describe, expect, it } from 'vitest'; 3 | import * as json from '../../src/serializers/json'; 4 | 5 | describe('json', () => { 6 | const data = { 7 | foo: 123, 8 | bar: true, 9 | baz: 'abc', 10 | qux: {}, 11 | }; 12 | 13 | it('serializes and parses json', () => { 14 | expect(json.parse(json.stringify(data))).toEqual(data); 15 | }); 16 | 17 | it('loads and parses from a file', () => { 18 | expect(json.load(path.join(__dirname, '__fixtures__/test.json'))).toEqual(data); 19 | }); 20 | }); 21 | -------------------------------------------------------------------------------- /packages/common/tests/serializers/yaml.test.ts: -------------------------------------------------------------------------------- 1 | import path from 'node:path'; 2 | import { describe, expect, it } from 'vitest'; 3 | import * as yaml from '../../src/serializers/yaml'; 4 | 5 | describe('yaml', () => { 6 | const data = { 7 | foo: 123, 8 | bar: true, 9 | baz: 'abc', 10 | qux: {}, 11 | }; 12 | 13 | it('serializes and parses yaml', () => { 14 | expect(yaml.parse(yaml.stringify(data))).toEqual(data); 15 | }); 16 | 17 | it('loads and parses from a file', () => { 18 | expect(yaml.load(path.join(__dirname, '__fixtures__/test.yaml'))).toEqual(data); 19 | }); 20 | }); 21 | -------------------------------------------------------------------------------- /packages/common/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../../tsconfig.options.json", 3 | "compilerOptions": { 4 | "outDir": "../../.moon/cache/types/packages/common", 5 | "rootDir": "." 6 | }, 7 | "include": [ 8 | "src/**/*", 9 | "tests/**/*", 10 | "types/**/*", 11 | "../../types/**/*" 12 | ], 13 | "references": [ 14 | { 15 | "path": "./tsconfig.mjs.json" 16 | }, 17 | { 18 | "path": "../decorators" 19 | }, 20 | { 21 | "path": "../internal" 22 | }, 23 | { 24 | "path": "../test-utils" 25 | } 26 | ] 27 | } 28 | -------------------------------------------------------------------------------- /packages/common/tsconfig.mjs.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../../tsconfig.options.json", 3 | "compilerOptions": { 4 | "outDir": "mjs", 5 | "rootDir": "src", 6 | "emitDeclarationOnly": true 7 | }, 8 | "include": [ 9 | "src/**/*", 10 | "../../types/**/*" 11 | ] 12 | } 13 | -------------------------------------------------------------------------------- /packages/config/src/constants.ts: -------------------------------------------------------------------------------- 1 | import type { ExtType } from './types'; 2 | 3 | export const CONFIG_FOLDER = '.config'; 4 | 5 | export const ROOT_CONFIG_DIR_REGEX = /\.config([/\\])([\d.a-z]+)\.([\da-z]{2,5})$/i; 6 | 7 | export const ROOT_CONFIG_FILE_REGEX = /([\da-z]+)\.config\.([\da-z]{2,5})$/i; 8 | 9 | export const PACKAGE_FILE = 'package.json'; 10 | 11 | export const DEFAULT_EXTS: ExtType[] = ['js', 'json', 'cjs', 'mjs', 'ts', 'json5', 'yaml', 'yml']; 12 | -------------------------------------------------------------------------------- /packages/config/src/helpers/createFileName.ts: -------------------------------------------------------------------------------- 1 | import { CONFIG_FOLDER } from '../constants'; 2 | import type { FileType } from '../types'; 3 | 4 | export function createFileName(type: FileType, name: string, ext: string, suffix?: string): string { 5 | // boost.js 6 | let fileName = name; 7 | 8 | // .boost.js 9 | if (type === 'branch') { 10 | fileName = `.${name}`; 11 | } 12 | 13 | // .config/boost.js 14 | if (type === 'root-folder') { 15 | fileName = `${CONFIG_FOLDER}/${name}`; 16 | } 17 | 18 | // boost.config.js 19 | if (type === 'root-file') { 20 | fileName = name + CONFIG_FOLDER; 21 | } 22 | 23 | if (suffix) { 24 | fileName += `.${suffix}`; 25 | } 26 | 27 | fileName += `.${ext}`; 28 | 29 | return fileName; 30 | } 31 | -------------------------------------------------------------------------------- /packages/config/src/helpers/getEnv.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Detect the current environment name from `_ENV` and `NODE_ENV`. 3 | */ 4 | export function getEnv(name: string): string { 5 | const constName = name.replace(/[A-Z]/gu, (char) => `_${char}`).toUpperCase(); 6 | 7 | return (process.env[`${constName}_ENV`] ?? process.env.NODE_ENV ?? 'development').toLowerCase(); 8 | } 9 | -------------------------------------------------------------------------------- /packages/config/src/helpers/mergeArray.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Merges previous and next arrays into a new array while removing duplicates (using `Set`). 3 | */ 4 | export function mergeArray(prev: T, next: T): T { 5 | return [...new Set([...prev, ...next])].filter((value) => value !== undefined) as T; 6 | } 7 | -------------------------------------------------------------------------------- /packages/config/src/helpers/mergeExtends.ts: -------------------------------------------------------------------------------- 1 | import { toArray } from '@boost/common'; 2 | import { type ExtendsSetting } from '../types'; 3 | import { mergeArray } from './mergeArray'; 4 | 5 | /** 6 | * Merges previous and next file paths (either a string or array of strings) into a 7 | * new list of file paths. This is useful if utilizing config extending. 8 | */ 9 | export function mergeExtends(prev: ExtendsSetting, next: ExtendsSetting): string[] { 10 | return mergeArray(toArray(prev), toArray(next)); 11 | } 12 | -------------------------------------------------------------------------------- /packages/config/src/helpers/mergeObject.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Shallow merges previous and next objects into a new object using object spread. 3 | */ 4 | export function mergeObject(prev: T, next: T): T { 5 | return { ...prev, ...next }; 6 | } 7 | -------------------------------------------------------------------------------- /packages/config/src/helpers/overwrite.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Overwrite the previous value with the next value. 3 | */ 4 | export function overwrite(prev: T, next: T): T { 5 | return next; 6 | } 7 | -------------------------------------------------------------------------------- /packages/config/src/index.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * @copyright 2020, Miles Johnson 3 | * @license https://opensource.org/licenses/MIT 4 | */ 5 | 6 | export * from './ConfigError'; 7 | export * from './Configuration'; 8 | export * from './helpers/getEnv'; 9 | export * from './helpers/mergeArray'; 10 | export * from './helpers/mergeExtends'; 11 | export * from './helpers/mergeObject'; 12 | export * from './helpers/mergePlugins'; 13 | export * from './helpers/overwrite'; 14 | export * from './schemas'; 15 | export * from './types'; 16 | -------------------------------------------------------------------------------- /packages/config/src/loaders/cjs.ts: -------------------------------------------------------------------------------- 1 | import { Path } from '@boost/common'; 2 | import { loadJs } from './js'; 3 | 4 | export async function loadCjs(path: Path): Promise { 5 | return loadJs(path); 6 | } 7 | -------------------------------------------------------------------------------- /packages/config/src/loaders/js.ts: -------------------------------------------------------------------------------- 1 | import { Path } from '@boost/common'; 2 | import { importAbsoluteModule } from '@boost/internal'; 3 | 4 | export async function loadJs(path: Path): Promise { 5 | return importAbsoluteModule(path.path()); 6 | } 7 | -------------------------------------------------------------------------------- /packages/config/src/loaders/json.ts: -------------------------------------------------------------------------------- 1 | import fs from 'node:fs'; 2 | import { json, Path } from '@boost/common'; 3 | 4 | export async function loadJson(path: Path): Promise { 5 | return json.parse(await fs.promises.readFile(path.path(), 'utf8')); 6 | } 7 | -------------------------------------------------------------------------------- /packages/config/src/loaders/mjs.ts: -------------------------------------------------------------------------------- 1 | import { Path } from '@boost/common'; 2 | import { loadJs } from './js'; 3 | 4 | export async function loadMjs(path: Path): Promise { 5 | return loadJs(path); 6 | } 7 | -------------------------------------------------------------------------------- /packages/config/src/loaders/ts.ts: -------------------------------------------------------------------------------- 1 | import { Path } from '@boost/common'; 2 | import { requireTSModule } from '@boost/module'; 3 | 4 | // eslint-disable-next-line @typescript-eslint/require-await 5 | export async function loadTs(path: Path): Promise { 6 | return requireTSModule(path).default as T; 7 | } 8 | -------------------------------------------------------------------------------- /packages/config/src/loaders/yaml.ts: -------------------------------------------------------------------------------- 1 | import fs from 'node:fs'; 2 | import { Path, yaml } from '@boost/common'; 3 | 4 | export async function loadYaml(path: Path): Promise { 5 | return yaml.parse(await fs.promises.readFile(path.path(), 'utf8')); 6 | } 7 | -------------------------------------------------------------------------------- /packages/config/tests/__snapshots__/ConfigFinder.test.ts.snap: -------------------------------------------------------------------------------- 1 | // Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html 2 | 3 | exports[`ConfigFinder > errors if name is not in camel case 1`] = ` 4 | [OptimalError: The following validations have failed for \`ConfigFinder\`: 5 | - Invalid field "name". String must be in camel case. (pattern "^[a-z][a-zA-Z0-9]+$")] 6 | `; 7 | -------------------------------------------------------------------------------- /packages/config/tests/__snapshots__/IgnoreFinder.test.ts.snap: -------------------------------------------------------------------------------- 1 | // Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html 2 | 3 | exports[`IgnoreFinder > errors if name is not in camel case 1`] = ` 4 | [OptimalError: The following validations have failed for \`IgnoreFinder\`: 5 | - Invalid field "name". String must be in camel case. (pattern "^[a-z][a-zA-Z0-9]+$")] 6 | `; 7 | -------------------------------------------------------------------------------- /packages/config/tests/helpers.ts: -------------------------------------------------------------------------------- 1 | import { mockNormalizedFilePath } from '@boost/common/test'; 2 | 3 | export function mockSystemPath(part: string, wrap: boolean = true) { 4 | return process.platform === 'win32' && wrap && !part.match(/^[A-Z]:/u) 5 | ? mockNormalizedFilePath('D:', part) 6 | : mockNormalizedFilePath(part); 7 | } 8 | -------------------------------------------------------------------------------- /packages/config/tests/helpers/overwrite.test.ts: -------------------------------------------------------------------------------- 1 | import { describe, expect, it } from 'vitest'; 2 | import { overwrite } from '../../src/helpers/overwrite'; 3 | 4 | describe('overwrite()', () => { 5 | it('returns the next value', () => { 6 | expect(overwrite('foo', 123)).toBe(123); 7 | }); 8 | }); 9 | -------------------------------------------------------------------------------- /packages/config/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../../tsconfig.options.json", 3 | "compilerOptions": { 4 | "outDir": "../../.moon/cache/types/packages/config", 5 | "rootDir": "." 6 | }, 7 | "include": [ 8 | "src/**/*", 9 | "tests/**/*", 10 | "types/**/*", 11 | "../../types/**/*" 12 | ], 13 | "references": [ 14 | { 15 | "path": "./tsconfig.mjs.json" 16 | }, 17 | { 18 | "path": "../common" 19 | }, 20 | { 21 | "path": "../debug" 22 | }, 23 | { 24 | "path": "../event" 25 | }, 26 | { 27 | "path": "../internal" 28 | }, 29 | { 30 | "path": "../module" 31 | }, 32 | { 33 | "path": "../test-utils" 34 | } 35 | ] 36 | } 37 | -------------------------------------------------------------------------------- /packages/config/tsconfig.mjs.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../../tsconfig.options.json", 3 | "compilerOptions": { 4 | "outDir": "mjs", 5 | "rootDir": "src", 6 | "emitDeclarationOnly": true 7 | }, 8 | "include": [ 9 | "src/**/*", 10 | "../../types/**/*" 11 | ] 12 | } 13 | -------------------------------------------------------------------------------- /packages/debug/src/debug.ts: -------------------------------------------------------------------------------- 1 | import { createInternalDebugger } from '@boost/internal'; 2 | 3 | export const debug = createInternalDebugger('debug'); 4 | -------------------------------------------------------------------------------- /packages/debug/src/index.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * @copyright 2020, Miles Johnson 3 | * @license https://opensource.org/licenses/MIT 4 | */ 5 | 6 | export * from './CrashReporter'; 7 | export * from './createDebugger'; 8 | export * from './types'; 9 | -------------------------------------------------------------------------------- /packages/debug/src/test.ts: -------------------------------------------------------------------------------- 1 | import type { Debugger } from '.'; 2 | 3 | /** 4 | * Returns a Vitest spy that matches the return value shape of `createDebugger`. 5 | * 6 | * ```ts 7 | * import { mockDebugger } from '@boost/debug/test'; 8 | * 9 | * it('calls the debugger', async () => { 10 | * const debug = await mockDebugger(); 11 | * 12 | * debug('Something is broken!'); 13 | * 14 | * expect(debug).toHaveBeenCalled(); 15 | * }); 16 | * ``` 17 | */ 18 | export async function mockDebugger(): Promise { 19 | const { vi } = await import('vitest'); 20 | const debug = vi.fn() as any; 21 | 22 | debug.disable = vi.fn(); 23 | debug.enable = vi.fn(); 24 | debug.invariant = vi.fn(); 25 | debug.verbose = vi.fn(); 26 | 27 | return debug; 28 | } 29 | -------------------------------------------------------------------------------- /packages/debug/src/types.ts: -------------------------------------------------------------------------------- 1 | import debug from 'debug'; 2 | 3 | export interface Debugger extends debug.IDebugger { 4 | /** Log a message to the console and interpolate with the parameters. */ 5 | (message: string, ...params: unknown[]): void; 6 | /** Disable all debugger messages from logging to the console. */ 7 | disable: () => void; 8 | /** Enable all debugger messages to log the console. */ 9 | enable: () => void; 10 | /** Log a pass or fail message based on a conditional. */ 11 | invariant: (condition: boolean, message: string, pass: string, fail: string) => void; 12 | /** Log verbose messages that only appear when the `BOOSTJS_DEBUG_VERBOSE` is set. */ 13 | verbose: (message: string, ...params: unknown[]) => void; 14 | } 15 | -------------------------------------------------------------------------------- /packages/debug/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../../tsconfig.options.json", 3 | "compilerOptions": { 4 | "outDir": "../../.moon/cache/types/packages/debug", 5 | "rootDir": "." 6 | }, 7 | "include": [ 8 | "src/**/*", 9 | "tests/**/*", 10 | "types/**/*", 11 | "../../types/**/*" 12 | ], 13 | "references": [ 14 | { 15 | "path": "./tsconfig.mjs.json" 16 | }, 17 | { 18 | "path": "../common" 19 | }, 20 | { 21 | "path": "../internal" 22 | } 23 | ] 24 | } 25 | -------------------------------------------------------------------------------- /packages/debug/tsconfig.mjs.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../../tsconfig.options.json", 3 | "compilerOptions": { 4 | "outDir": "mjs", 5 | "rootDir": "src", 6 | "emitDeclarationOnly": true 7 | }, 8 | "include": [ 9 | "src/**/*", 10 | "../../types/**/*" 11 | ] 12 | } 13 | -------------------------------------------------------------------------------- /packages/decorators/.eslintrc.cjs: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | rules: { 3 | 'no-param-reassign': 'off', 4 | // Any is required for lots of decorator stuff to work 5 | '@typescript-eslint/no-unsafe-assignment': 'off', 6 | }, 7 | }; 8 | -------------------------------------------------------------------------------- /packages/decorators/moon.yml: -------------------------------------------------------------------------------- 1 | workspace: 2 | inheritedTasks: 3 | # Vitest doesn't support TS decorators! 4 | exclude: ['test', 'test-cov'] 5 | -------------------------------------------------------------------------------- /packages/decorators/src/helpers/isClass.ts: -------------------------------------------------------------------------------- 1 | export function isClass( 2 | target: Function | Object, 3 | property?: string | symbol, 4 | descriptor?: unknown, 5 | ): boolean { 6 | return typeof target === 'function' && !property && !descriptor; 7 | } 8 | -------------------------------------------------------------------------------- /packages/decorators/src/helpers/isMethod.ts: -------------------------------------------------------------------------------- 1 | export function isMethod( 2 | target: Function | Object, 3 | property?: string | symbol, 4 | descriptor?: unknown, 5 | ): boolean { 6 | return Boolean( 7 | property && 8 | descriptor && 9 | typeof descriptor === 'object' && 10 | !('initializer' in descriptor) && 11 | ('value' in descriptor || 'get' in descriptor), 12 | ); 13 | } 14 | -------------------------------------------------------------------------------- /packages/decorators/src/helpers/isParam.ts: -------------------------------------------------------------------------------- 1 | export function isParam( 2 | target: Function | Object, 3 | property?: string | symbol, 4 | index?: unknown, 5 | ): boolean { 6 | return Boolean(property && typeof index === 'number'); 7 | } 8 | -------------------------------------------------------------------------------- /packages/decorators/src/helpers/isProperty.ts: -------------------------------------------------------------------------------- 1 | export function isProperty( 2 | target: Function | Object, 3 | property?: string | symbol, 4 | descriptor?: unknown, 5 | ): boolean { 6 | return Boolean( 7 | property && 8 | ((descriptor && typeof descriptor === 'object' && 'initializer' in descriptor) || 9 | descriptor === undefined), 10 | ); 11 | } 12 | -------------------------------------------------------------------------------- /packages/decorators/src/index.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * @copyright 2020, Miles Johnson 3 | * @license https://opensource.org/licenses/MIT 4 | */ 5 | 6 | export * from './Bind'; 7 | export * from './Debounce'; 8 | export * from './Deprecate'; 9 | export * from './Memoize'; 10 | export * from './Throttle'; 11 | -------------------------------------------------------------------------------- /packages/decorators/tsconfig.esm.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../../tsconfig.options.json", 3 | "compilerOptions": { 4 | "outDir": "esm", 5 | "rootDir": "src", 6 | "emitDeclarationOnly": true 7 | }, 8 | "include": [ 9 | "src/**/*", 10 | "../../types/**/*" 11 | ] 12 | } 13 | -------------------------------------------------------------------------------- /packages/decorators/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../../tsconfig.options.json", 3 | "compilerOptions": { 4 | "outDir": "../../.moon/cache/types/packages/decorators", 5 | "rootDir": ".", 6 | "noUnusedLocals": false 7 | }, 8 | "include": [ 9 | "src/**/*", 10 | "tests/**/*", 11 | "types/**/*", 12 | "../../types/**/*" 13 | ], 14 | "references": [ 15 | { 16 | "path": "./tsconfig.esm.json" 17 | }, 18 | { 19 | "path": "./tsconfig.mjs.json" 20 | } 21 | ] 22 | } 23 | -------------------------------------------------------------------------------- /packages/decorators/tsconfig.mjs.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../../tsconfig.options.json", 3 | "compilerOptions": { 4 | "outDir": "mjs", 5 | "rootDir": "src", 6 | "emitDeclarationOnly": true 7 | }, 8 | "include": [ 9 | "src/**/*", 10 | "../../types/**/*" 11 | ] 12 | } 13 | -------------------------------------------------------------------------------- /packages/event/src/BailEvent.ts: -------------------------------------------------------------------------------- 1 | import { BaseEvent } from './BaseEvent'; 2 | import { debug } from './debug'; 3 | 4 | export class BailEvent extends BaseEvent< 5 | boolean | void, 6 | Args, 7 | Scope 8 | > { 9 | /** 10 | * Synchronously execute listeners with the defined arguments. 11 | * If a listener returns `false`, the loop with be aborted early, 12 | * and the emitter will return `true` (for bailed). 13 | */ 14 | emit(args: Args, scope?: Scope): boolean { 15 | if (__DEV__) { 16 | debug('Emitting "%s%s" as bail', this.name, scope ? `:${scope}` : ''); 17 | } 18 | 19 | return [...this.getListeners(scope)].some((listener) => listener(...args) === false); 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /packages/event/src/ConcurrentEvent.ts: -------------------------------------------------------------------------------- 1 | import { BaseEvent } from './BaseEvent'; 2 | import { debug } from './debug'; 3 | 4 | export class ConcurrentEvent< 5 | Args extends unknown[], 6 | Scope extends string = string, 7 | > extends BaseEvent, Args, Scope> { 8 | /** 9 | * Asynchronously execute listeners for with the defined arguments. 10 | * Will return a promise with an array of each listener result. 11 | */ 12 | async emit(args: Args, scope?: Scope): Promise { 13 | if (__DEV__) { 14 | debug('Emitting "%s%s" as concurrent', this.name, scope ? `:${scope}` : ''); 15 | } 16 | 17 | return Promise.all([...this.getListeners(scope)].map((listener) => listener(...args))); 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /packages/event/src/Event.ts: -------------------------------------------------------------------------------- 1 | import { BaseEvent } from './BaseEvent'; 2 | 3 | export class Event extends BaseEvent< 4 | void, 5 | Args, 6 | Scope 7 | > { 8 | /** 9 | * Synchronously execute listeners with the defined arguments. 10 | */ 11 | emit(args: Args, scope?: Scope) { 12 | [...this.getListeners(scope)].forEach((listener) => { 13 | listener(...args); 14 | }); 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /packages/event/src/EventError.ts: -------------------------------------------------------------------------------- 1 | import { createScopedError } from '@boost/internal'; 2 | 3 | const errors = { 4 | LISTENER_INVALID: 'Invalid event listener for "{0}", must be a function.', 5 | NAME_INVALID: 6 | 'Invalid event {0} "{1}". May only contain dashes, periods, and lowercase characters.', 7 | }; 8 | 9 | export type EventErrorCode = keyof typeof errors; 10 | 11 | export const EventError = createScopedError('EVT', 'EventError', errors); 12 | -------------------------------------------------------------------------------- /packages/event/src/WaterfallEvent.ts: -------------------------------------------------------------------------------- 1 | import { BaseEvent } from './BaseEvent'; 2 | import { debug } from './debug'; 3 | 4 | export class WaterfallEvent extends BaseEvent< 5 | Arg, 6 | [Arg], 7 | Scope 8 | > { 9 | /** 10 | * Synchronously execute listeners with the defined argument value. 11 | * The return value of each listener will be passed as an argument to the next listener. 12 | */ 13 | emit(arg: Arg, scope?: Scope): Arg { 14 | if (__DEV__) { 15 | debug('Emitting "%s%s" as waterfall', this.name, scope ? `:${scope}` : ''); 16 | } 17 | 18 | return [...this.getListeners(scope)].reduce((nextValue, listener) => listener(nextValue), arg); 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /packages/event/src/constants.ts: -------------------------------------------------------------------------------- 1 | export const WILDCARD_SCOPE = '*'; 2 | 3 | export const EVENT_NAME_PATTERN = /^[a-z]{1}[-.a-z0-9]*[a-z]{1}$/u; 4 | -------------------------------------------------------------------------------- /packages/event/src/debug.ts: -------------------------------------------------------------------------------- 1 | import { createInternalDebugger } from '@boost/internal'; 2 | 3 | export const debug = createInternalDebugger('event'); 4 | -------------------------------------------------------------------------------- /packages/event/src/index.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * @copyright 2020, Miles Johnson 3 | * @license https://opensource.org/licenses/MIT 4 | */ 5 | 6 | export * from './BailEvent'; 7 | export * from './BaseEvent'; 8 | export * from './ConcurrentEvent'; 9 | export * from './constants'; 10 | export * from './Event'; 11 | export * from './EventError'; 12 | export * from './types'; 13 | export * from './WaterfallEvent'; 14 | -------------------------------------------------------------------------------- /packages/event/src/types.ts: -------------------------------------------------------------------------------- 1 | export type Listener = A extends [ 2 | infer A1, 3 | infer A2, 4 | infer A3, 5 | infer A4, 6 | infer A5, 7 | ] 8 | ? (a1: A1, a2: A2, a3: A3, a4: A4, a5: A5) => R 9 | : A extends [infer A1, infer A2, infer A3, infer A4] 10 | ? (a1: A1, a2: A2, a3: A3, a4: A4) => R 11 | : A extends [infer A1, infer A2, infer A3] 12 | ? (a1: A1, a2: A2, a3: A3) => R 13 | : A extends [infer A1, infer A2] 14 | ? (a1: A1, a2: A2) => R 15 | : A extends [infer A1] 16 | ? (a1: A1) => R 17 | : A extends unknown[] 18 | ? (...args: A) => R 19 | : never; 20 | 21 | export type Unlistener = () => void; 22 | 23 | export type WildstarScope = '*'; 24 | -------------------------------------------------------------------------------- /packages/event/tsconfig.esm.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../../tsconfig.options.json", 3 | "compilerOptions": { 4 | "outDir": "esm", 5 | "rootDir": "src", 6 | "emitDeclarationOnly": true 7 | }, 8 | "include": [ 9 | "src/**/*", 10 | "../../types/**/*" 11 | ] 12 | } 13 | -------------------------------------------------------------------------------- /packages/event/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../../tsconfig.options.json", 3 | "compilerOptions": { 4 | "outDir": "../../.moon/cache/types/packages/event", 5 | "rootDir": "." 6 | }, 7 | "include": [ 8 | "src/**/*", 9 | "tests/**/*", 10 | "types/**/*", 11 | "../../types/**/*" 12 | ], 13 | "references": [ 14 | { 15 | "path": "./tsconfig.esm.json" 16 | }, 17 | { 18 | "path": "./tsconfig.mjs.json" 19 | }, 20 | { 21 | "path": "../internal" 22 | } 23 | ] 24 | } 25 | -------------------------------------------------------------------------------- /packages/event/tsconfig.mjs.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../../tsconfig.options.json", 3 | "compilerOptions": { 4 | "outDir": "mjs", 5 | "rootDir": "src", 6 | "emitDeclarationOnly": true 7 | }, 8 | "include": [ 9 | "src/**/*", 10 | "../../types/**/*" 11 | ] 12 | } 13 | -------------------------------------------------------------------------------- /packages/internal/README.md: -------------------------------------------------------------------------------- 1 | # Boost Internals 2 | 3 | ![build status](https://img.shields.io/github/actions/workflow/status/milesj/boost/build.yml) 4 | ![npm version](https://img.shields.io/npm/v/@boost/internal) 5 | 6 | Internal utilities for Boost packages. This should rarely be used directly. 7 | -------------------------------------------------------------------------------- /packages/internal/src/browser.ts: -------------------------------------------------------------------------------- 1 | export * from './color'; 2 | export * from './createInternalDebugger'; 3 | export * from './createScopedError'; 4 | export * from './env'; 5 | export * from './interopDefault'; 6 | -------------------------------------------------------------------------------- /packages/internal/src/color.ts: -------------------------------------------------------------------------------- 1 | /* eslint-disable no-magic-numbers, sort-keys */ 2 | 3 | export type ColorFormatter = (message: string | { toString: () => string }) => string; 4 | 5 | // https://github.com/chalk/ansi-styles/blob/master/index.js#L75 6 | function createColor(open: number): ColorFormatter { 7 | return (message) => `\u001B[${open}m${String(message)}\u001B[39m`; 8 | } 9 | 10 | export const color = { 11 | // States 12 | fail: createColor(31), 13 | mute: createColor(90), 14 | pass: createColor(32), 15 | // Types 16 | filePath: createColor(36), 17 | moduleName: createColor(33), 18 | projectName: createColor(34), 19 | symbol: createColor(35), 20 | }; 21 | -------------------------------------------------------------------------------- /packages/internal/src/createInternalDebugger.ts: -------------------------------------------------------------------------------- 1 | import debug, { type Debugger } from 'debug'; 2 | 3 | export function sentenceCase(value: unknown): string { 4 | return String(value) 5 | .replace(/[A-Z]/gu, (match) => ` ${match.toLocaleLowerCase()}`) 6 | .trim(); 7 | } 8 | 9 | debug.formatters.S = sentenceCase; 10 | 11 | export function createInternalDebugger(namespace: string): Debugger { 12 | return debug(`boost:${namespace}`); 13 | } 14 | -------------------------------------------------------------------------------- /packages/internal/src/env.ts: -------------------------------------------------------------------------------- 1 | let envVars: Record = {}; 2 | 3 | if (global.process !== undefined) { 4 | envVars = process.env; 5 | } else if ('window' in global && global.window !== undefined) { 6 | // @ts-expect-error Allow type mismatch 7 | // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment 8 | envVars = window; 9 | } 10 | 11 | export function env(key: string, value?: T | null): T | undefined { 12 | const name = `BOOSTJS_${key}`; 13 | 14 | if (value === null) { 15 | delete envVars[name]; 16 | 17 | return undefined; 18 | } 19 | 20 | if (typeof value === 'string') { 21 | envVars[name] = value; 22 | 23 | return value; 24 | } 25 | 26 | return envVars[name] as T; 27 | } 28 | -------------------------------------------------------------------------------- /packages/internal/src/importAbsoluteModule.ts: -------------------------------------------------------------------------------- 1 | import { pathToFileURL } from 'node:url'; 2 | import { interopDefault } from './interopDefault'; 3 | 4 | // import() expects URLs, not file paths. 5 | // https://github.com/nodejs/node/issues/31710 6 | export async function importAbsoluteModule(path: string): Promise { 7 | const file = pathToFileURL(path).toString(); 8 | const mod = (await import(file)) as unknown; 9 | 10 | return interopDefault(mod); 11 | } 12 | -------------------------------------------------------------------------------- /packages/internal/src/index.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * @copyright 2020, Miles Johnson 3 | * @license https://opensource.org/licenses/MIT 4 | */ 5 | 6 | export * from './browser'; 7 | export * from './importAbsoluteModule'; 8 | -------------------------------------------------------------------------------- /packages/internal/src/interopDefault.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * For compatibility with ES modules, this function is used to extract the 3 | * default export from an incompatible module. 4 | */ 5 | export function interopDefault(result: unknown): R { 6 | if (result && typeof result === 'object' && 'default' in result) { 7 | return result.default as R; 8 | } 9 | 10 | return result as R; 11 | } 12 | -------------------------------------------------------------------------------- /packages/internal/tests/createInternalDebugger.test.ts: -------------------------------------------------------------------------------- 1 | import { describe, expect, it } from 'vitest'; 2 | import { createInternalDebugger, sentenceCase } from '../src/createInternalDebugger'; 3 | 4 | describe('createInternalDebugger()', () => { 5 | it('returns a `debug` instance', () => { 6 | const debug = createInternalDebugger('foo'); 7 | 8 | expect(typeof debug).toBe('function'); 9 | expect(debug.namespace).toBe('boost:foo'); 10 | }); 11 | 12 | it('formats to sentence case', () => { 13 | expect(sentenceCase('BaseExampleEvent')).toBe('base example event'); 14 | }); 15 | }); 16 | -------------------------------------------------------------------------------- /packages/internal/tsconfig.esm.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../../tsconfig.options.json", 3 | "compilerOptions": { 4 | "outDir": "esm", 5 | "rootDir": "src", 6 | "emitDeclarationOnly": true 7 | }, 8 | "include": [ 9 | "src/**/*", 10 | "../../types/**/*" 11 | ] 12 | } 13 | -------------------------------------------------------------------------------- /packages/internal/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../../tsconfig.options.json", 3 | "compilerOptions": { 4 | "outDir": "../../.moon/cache/types/packages/internal", 5 | "rootDir": "." 6 | }, 7 | "include": [ 8 | "src/**/*", 9 | "tests/**/*", 10 | "types/**/*", 11 | "../../types/**/*" 12 | ], 13 | "references": [ 14 | { 15 | "path": "./tsconfig.esm.json" 16 | }, 17 | { 18 | "path": "./tsconfig.mjs.json" 19 | } 20 | ] 21 | } 22 | -------------------------------------------------------------------------------- /packages/internal/tsconfig.mjs.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../../tsconfig.options.json", 3 | "compilerOptions": { 4 | "outDir": "mjs", 5 | "rootDir": "src", 6 | "emitDeclarationOnly": true 7 | }, 8 | "include": [ 9 | "src/**/*", 10 | "../../types/**/*" 11 | ] 12 | } 13 | -------------------------------------------------------------------------------- /packages/log/res/en/log.yaml: -------------------------------------------------------------------------------- 1 | levelDebug: debug 2 | levelError: error 3 | levelInfo: info 4 | levelLog: log 5 | levelTrace: trace 6 | levelWarn: warn 7 | -------------------------------------------------------------------------------- /packages/log/src/constants.ts: -------------------------------------------------------------------------------- 1 | import chalk from 'chalk'; 2 | import { msg } from './translate'; 3 | import type { LogLevel, LogLevelLabels } from './types'; 4 | 5 | // In order of priority! 6 | export const LOG_LEVELS: LogLevel[] = ['log', 'trace', 'debug', 'info', 'warn', 'error']; 7 | 8 | export const DEFAULT_LABELS: LogLevelLabels = { 9 | debug: chalk.gray(msg('log:levelDebug')), 10 | error: chalk.red(msg('log:levelError')), 11 | info: chalk.cyan(msg('log:levelInfo')), 12 | log: chalk.yellow(msg('log:levelLog')), 13 | trace: chalk.magenta(msg('log:levelTrace')), 14 | warn: chalk.yellow(msg('log:levelWarn')), 15 | }; 16 | 17 | export const MAX_LOG_SIZE = 10_485_760; 18 | -------------------------------------------------------------------------------- /packages/log/src/debug.ts: -------------------------------------------------------------------------------- 1 | import { createInternalDebugger } from '@boost/internal'; 2 | 3 | export const debug = createInternalDebugger('log'); 4 | -------------------------------------------------------------------------------- /packages/log/src/index.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * @copyright 2020, Miles Johnson 3 | * @license https://opensource.org/licenses/MIT 4 | */ 5 | 6 | export * from './constants'; 7 | export * from './createLogger'; 8 | export * as formats from './formats'; 9 | export * from './Logger'; 10 | export * from './Transport'; 11 | export * from './transports/ConsoleTransport'; 12 | export * from './transports/FileTransport'; 13 | export * from './transports/RotatingFileTransport'; 14 | export * from './transports/StreamTransport'; 15 | export * from './types'; 16 | -------------------------------------------------------------------------------- /packages/log/src/translate.ts: -------------------------------------------------------------------------------- 1 | import path from 'node:path'; 2 | import { fileURLToPath } from 'node:url'; 3 | import { createTranslator } from '@boost/translate'; 4 | 5 | export const msg = await createTranslator( 6 | 'log', 7 | path.join(path.dirname(fileURLToPath(import.meta.url)), '../res'), 8 | ); 9 | -------------------------------------------------------------------------------- /packages/log/src/transports/ConsoleTransport.ts: -------------------------------------------------------------------------------- 1 | import { LOG_LEVELS } from '../constants'; 2 | import * as formats from '../formats'; 3 | import { Transport } from '../Transport'; 4 | import type { LogItem, TransportOptions } from '../types'; 5 | 6 | export class ConsoleTransport extends Transport { 7 | constructor(options?: Partial) { 8 | super({ 9 | format: formats.console, 10 | levels: LOG_LEVELS, 11 | ...options, 12 | }); 13 | } 14 | 15 | write(message: string, item: LogItem) { 16 | // eslint-disable-next-line no-console 17 | console[item.level](message.trim()); 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /packages/log/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../../tsconfig.options.json", 3 | "compilerOptions": { 4 | "outDir": "../../.moon/cache/types/packages/log", 5 | "rootDir": "." 6 | }, 7 | "include": [ 8 | "src/**/*", 9 | "tests/**/*", 10 | "types/**/*", 11 | "../../types/**/*" 12 | ], 13 | "references": [ 14 | { 15 | "path": "./tsconfig.mjs.json" 16 | }, 17 | { 18 | "path": "../common" 19 | }, 20 | { 21 | "path": "../internal" 22 | }, 23 | { 24 | "path": "../translate" 25 | } 26 | ] 27 | } 28 | -------------------------------------------------------------------------------- /packages/log/tsconfig.mjs.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../../tsconfig.options.json", 3 | "compilerOptions": { 4 | "outDir": "mjs", 5 | "rootDir": "src", 6 | "emitDeclarationOnly": true 7 | }, 8 | "include": [ 9 | "src/**/*", 10 | "../../types/**/*" 11 | ] 12 | } 13 | -------------------------------------------------------------------------------- /packages/module/moon.yml: -------------------------------------------------------------------------------- 1 | tasks: 2 | test-tsm: 3 | command: 'node ./tests/commonjs.assert.cjs && node ./tests/commonjs.assert.mjs' 4 | deps: 5 | - 'build' 6 | options: 7 | shell: true 8 | 9 | test-hook: 10 | command: 'node ./tests/hook-tester.cjs' 11 | deps: 12 | - 'build' 13 | options: 14 | shell: true 15 | 16 | workspace: 17 | inheritedTasks: 18 | exclude: ['test', 'test-cov'] 19 | -------------------------------------------------------------------------------- /packages/module/src/hooks/index.ts: -------------------------------------------------------------------------------- 1 | // https://nodejs.org/api/module.html#customization-hooks 2 | 3 | import { register } from 'node:module'; 4 | 5 | register('./hook-typescript.mjs', import.meta.url); 6 | -------------------------------------------------------------------------------- /packages/module/src/index.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * @copyright 2021, Miles Johnson 3 | * @license https://opensource.org/licenses/MIT 4 | */ 5 | 6 | export * from './interopModule'; 7 | export * from './requireModule'; 8 | export * from './requireTSModule'; 9 | export * from './types'; 10 | -------------------------------------------------------------------------------- /packages/module/tests/__fixtures__/.eslintrc.cjs: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | rules: { 3 | 'import/no-default-export': 'off', 4 | 'react/jsx-filename-extension': 'off', 5 | }, 6 | }; 7 | -------------------------------------------------------------------------------- /packages/module/tests/__fixtures__/default-export.ts: -------------------------------------------------------------------------------- 1 | type Str = string; 2 | 3 | const result: Str = 'default'; 4 | 5 | export default result; 6 | -------------------------------------------------------------------------------- /packages/module/tests/__fixtures__/default-named-exports.ts: -------------------------------------------------------------------------------- 1 | export type Num = number; 2 | 3 | export const a: Num = 1; 4 | export const b: Num = 2; 5 | export const c: Num = 3; 6 | 7 | export default 'default'; 8 | -------------------------------------------------------------------------------- /packages/module/tests/__fixtures__/format-cjs.cjs: -------------------------------------------------------------------------------- 1 | exports.a = 1; 2 | exports.b = 2; 3 | exports.c = 3; 4 | -------------------------------------------------------------------------------- /packages/module/tests/__fixtures__/format-js.js: -------------------------------------------------------------------------------- 1 | module.exports = 'default'; 2 | -------------------------------------------------------------------------------- /packages/module/tests/__fixtures__/format-mjs.mjs: -------------------------------------------------------------------------------- 1 | export default 'default'; 2 | -------------------------------------------------------------------------------- /packages/module/tests/__fixtures__/format-ts.ts: -------------------------------------------------------------------------------- 1 | type Str = string; 2 | 3 | const result: Str = 'default'; 4 | 5 | export default result; 6 | -------------------------------------------------------------------------------- /packages/module/tests/__fixtures__/format-tsx.tsx: -------------------------------------------------------------------------------- 1 | export type Num = number; 2 | 3 | export const a: Num = 1; 4 | export const b: Num = 2; 5 | export const c: Num = 3; 6 | -------------------------------------------------------------------------------- /packages/module/tests/__fixtures__/imports.ts: -------------------------------------------------------------------------------- 1 | // No extensions on purpose! 2 | import defaultExport from './default-export'; 3 | import * as defaultNamedExports from './default-named-exports'; 4 | import * as namedExports from './named-exports'; 5 | 6 | export default { 7 | defaultExport, 8 | defaultNamedExports, 9 | namedExports, 10 | }; 11 | -------------------------------------------------------------------------------- /packages/module/tests/__fixtures__/named-exports.ts: -------------------------------------------------------------------------------- 1 | export type Num = number; 2 | 3 | export const a: Num = 1; 4 | export const b: Num = 2; 5 | export const c: Num = 3; 6 | -------------------------------------------------------------------------------- /packages/module/tests/commonjs.assert.mjs: -------------------------------------------------------------------------------- 1 | // This just tests that the CommonJS tools can be imported 2 | async function test() { 3 | // eslint-disable-next-line import/no-useless-path-segments 4 | await import('../cjs/index.cjs'); 5 | } 6 | 7 | test().catch(console.error); 8 | -------------------------------------------------------------------------------- /packages/module/tests/helpers.ts: -------------------------------------------------------------------------------- 1 | import path from 'node:path'; 2 | import { fileURLToPath } from 'node:url'; 3 | 4 | export function getFixture(file: string): string { 5 | return path.join(path.dirname(fileURLToPath(import.meta.url)), '__fixtures__', file); 6 | } 7 | -------------------------------------------------------------------------------- /packages/module/tests/requireTSModule.test.ts: -------------------------------------------------------------------------------- 1 | import { describe, expect, it } from 'vitest'; 2 | import { requireTSModule } from '../src/requireTSModule'; 3 | 4 | describe('requireTSModule()', () => { 5 | it('errors if not a .ts file or .tsx file', () => { 6 | expect(() => { 7 | requireTSModule('some-fake-module'); 8 | }).toThrow( 9 | 'Unable to import non-TypeScript file "some-fake-module", use `requireModule` instead.', 10 | ); 11 | }); 12 | }); 13 | -------------------------------------------------------------------------------- /packages/module/tsconfig.cjs.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../../tsconfig.options.json", 3 | "compilerOptions": { 4 | "outDir": "cjs", 5 | "rootDir": "src", 6 | "emitDeclarationOnly": true 7 | }, 8 | "include": [ 9 | "src/**/*", 10 | "../../types/**/*" 11 | ] 12 | } 13 | -------------------------------------------------------------------------------- /packages/module/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../../tsconfig.options.json", 3 | "compilerOptions": { 4 | "outDir": "../../.moon/cache/types/packages/module", 5 | "rootDir": "." 6 | }, 7 | "include": [ 8 | "src/**/*", 9 | "tests/**/*", 10 | "types/**/*", 11 | "../../types/**/*" 12 | ], 13 | "references": [ 14 | { 15 | "path": "./tsconfig.cjs.json" 16 | }, 17 | { 18 | "path": "./tsconfig.mjs.json" 19 | } 20 | ] 21 | } 22 | -------------------------------------------------------------------------------- /packages/module/tsconfig.mjs.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../../tsconfig.options.json", 3 | "compilerOptions": { 4 | "outDir": "mjs", 5 | "rootDir": "src", 6 | "emitDeclarationOnly": true 7 | }, 8 | "include": [ 9 | "src/**/*", 10 | "../../types/**/*" 11 | ] 12 | } 13 | -------------------------------------------------------------------------------- /packages/pipeline/.eslintrc.cjs: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | rules: { 3 | 'no-dupe-class-members': 'off', 4 | 'lines-between-class-members': 'off', 5 | '@typescript-eslint/no-unsafe-assignment': 'off', 6 | }, 7 | }; 8 | -------------------------------------------------------------------------------- /packages/pipeline/src/PipelineError.ts: -------------------------------------------------------------------------------- 1 | import { createScopedError } from '@boost/internal'; 2 | 3 | const errors = { 4 | ACTION_REQUIRED: 'Work units require an executable function.', 5 | ROUTINE_INVALID_KEY: 'Routine key must be a valid unique string.', 6 | WORK_REQUIRED_TITLE: 'Work units require a title.', 7 | WORK_TIME_OUT: 'Work unit has timed out.', 8 | WORK_UNKNOWN: 'Unknown work unit type. Must be a `Routine`, `Task`, `WorkUnit`, or function.', 9 | }; 10 | 11 | export type PipelineErrorCode = keyof typeof errors; 12 | 13 | export const PipelineError = createScopedError('PLN', 'PipelineError', errors); 14 | -------------------------------------------------------------------------------- /packages/pipeline/src/Task.ts: -------------------------------------------------------------------------------- 1 | import type { Blueprint, Schemas } from '@boost/common/optimal'; 2 | import { WorkUnit } from './WorkUnit'; 3 | 4 | export class Task extends WorkUnit<{}, Input, Output> { 5 | // A task is simply a work unit that executes a standard function. 6 | // It doesn't need configurable options, so implement an empty blueprint. 7 | blueprint(schemas: Schemas): Blueprint { 8 | return {}; 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /packages/pipeline/src/constants.ts: -------------------------------------------------------------------------------- 1 | import type { Status } from './types'; 2 | 3 | export const STATUS_PENDING: Status = 'pending'; 4 | export const STATUS_RUNNING: Status = 'running'; 5 | export const STATUS_SKIPPED: Status = 'skipped'; 6 | export const STATUS_PASSED: Status = 'passed'; 7 | export const STATUS_FAILED: Status = 'failed'; 8 | -------------------------------------------------------------------------------- /packages/pipeline/src/debug.ts: -------------------------------------------------------------------------------- 1 | import { createInternalDebugger } from '@boost/internal'; 2 | 3 | export const debug = createInternalDebugger('pipeline'); 4 | -------------------------------------------------------------------------------- /packages/pipeline/src/index.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * @copyright 2020, Miles Johnson 3 | * @license https://opensource.org/licenses/MIT 4 | */ 5 | 6 | export * from './AggregatedPipeline'; 7 | export * from './ConcurrentPipeline'; 8 | export * from './constants'; 9 | export * from './Context'; 10 | export * from './Monitor'; 11 | export * from './ParallelPipeline'; 12 | export * from './PipelineError'; 13 | export * from './PooledPipeline'; 14 | export * from './Routine'; 15 | export * from './SerialPipeline'; 16 | export * from './Task'; 17 | export * from './types'; 18 | export * from './WaterfallPipeline'; 19 | export * from './WorkUnit'; 20 | -------------------------------------------------------------------------------- /packages/pipeline/tests/.eslintrc.cjs: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | rules: { 3 | '@typescript-eslint/require-await': 'off', 4 | }, 5 | }; 6 | -------------------------------------------------------------------------------- /packages/pipeline/tests/__snapshots__/Routine.test.ts.snap: -------------------------------------------------------------------------------- 1 | // Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html 2 | 3 | exports[`Routine > errors if key is not a string 1`] = `[PipelineError: Routine key must be a valid unique string. [PLN:ROUTINE_INVALID_KEY]]`; 4 | 5 | exports[`Routine > errors if no key is provided 1`] = `[PipelineError: Routine key must be a valid unique string. [PLN:ROUTINE_INVALID_KEY]]`; 6 | -------------------------------------------------------------------------------- /packages/pipeline/tests/__snapshots__/WorkUnit.test.ts.snap: -------------------------------------------------------------------------------- 1 | // Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html 2 | 3 | exports[`Work > constructor() > errors if action is not a function 1`] = `[PipelineError: Work units require an executable function. [PLN:ACTION_REQUIRED]]`; 4 | 5 | exports[`Work > constructor() > errors if no title 1`] = `[PipelineError: Work units require a title. [PLN:WORK_REQUIRED_TITLE]]`; 6 | 7 | exports[`Work > constructor() > errors if title is not a string 1`] = `[PipelineError: Work units require a title. [PLN:WORK_REQUIRED_TITLE]]`; 8 | -------------------------------------------------------------------------------- /packages/pipeline/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../../tsconfig.options.json", 3 | "compilerOptions": { 4 | "outDir": "../../.moon/cache/types/packages/pipeline", 5 | "rootDir": ".", 6 | "verbatimModuleSyntax": false 7 | }, 8 | "include": [ 9 | "src/**/*", 10 | "tests/**/*", 11 | "types/**/*", 12 | "../../types/**/*" 13 | ], 14 | "references": [ 15 | { 16 | "path": "./tsconfig.mjs.json" 17 | }, 18 | { 19 | "path": "../common" 20 | }, 21 | { 22 | "path": "../debug" 23 | }, 24 | { 25 | "path": "../event" 26 | }, 27 | { 28 | "path": "../internal" 29 | }, 30 | { 31 | "path": "../translate" 32 | } 33 | ] 34 | } 35 | -------------------------------------------------------------------------------- /packages/pipeline/tsconfig.mjs.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../../tsconfig.options.json", 3 | "compilerOptions": { 4 | "outDir": "mjs", 5 | "rootDir": "src", 6 | "emitDeclarationOnly": true 7 | }, 8 | "include": [ 9 | "src/**/*", 10 | "../../types/**/*" 11 | ] 12 | } 13 | -------------------------------------------------------------------------------- /packages/plugin/src/Plugin.ts: -------------------------------------------------------------------------------- 1 | import { Contract } from '@boost/common'; 2 | import type { Pluggable } from './types'; 3 | 4 | export abstract class Plugin 5 | extends Contract 6 | implements Pluggable 7 | { 8 | abstract name: string; 9 | 10 | startup(tool: T) {} 11 | 12 | shutdown(tool: T) {} 13 | } 14 | -------------------------------------------------------------------------------- /packages/plugin/src/constants.ts: -------------------------------------------------------------------------------- 1 | export const DEFAULT_PRIORITY = 100; 2 | -------------------------------------------------------------------------------- /packages/plugin/src/debug.ts: -------------------------------------------------------------------------------- 1 | import { createInternalDebugger } from '@boost/internal'; 2 | 3 | export const debug = createInternalDebugger('plugin'); 4 | -------------------------------------------------------------------------------- /packages/plugin/src/index.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * @copyright 2020, Miles Johnson 3 | * @license https://opensource.org/licenses/MIT 4 | */ 5 | 6 | export * from './constants'; 7 | export * from './Plugin'; 8 | export * from './PluginError'; 9 | export * from './Registry'; 10 | export * from './types'; 11 | -------------------------------------------------------------------------------- /packages/plugin/tests/Plugin.test.ts: -------------------------------------------------------------------------------- 1 | import { describe, expect, it } from 'vitest'; 2 | import { Renderer } from './__fixtures__/Renderer'; 3 | 4 | describe('Plugin', () => { 5 | it('accepts options in the constructor', () => { 6 | const plugin = new Renderer({ value: 'foo' }); 7 | 8 | expect(plugin.options).toEqual({ value: 'foo' }); 9 | }); 10 | }); 11 | -------------------------------------------------------------------------------- /packages/plugin/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../../tsconfig.options.json", 3 | "compilerOptions": { 4 | "outDir": "../../.moon/cache/types/packages/plugin", 5 | "rootDir": "." 6 | }, 7 | "include": [ 8 | "src/**/*", 9 | "tests/**/*", 10 | "types/**/*", 11 | "../../types/**/*" 12 | ], 13 | "references": [ 14 | { 15 | "path": "./tsconfig.mjs.json" 16 | }, 17 | { 18 | "path": "../common" 19 | }, 20 | { 21 | "path": "../debug" 22 | }, 23 | { 24 | "path": "../event" 25 | }, 26 | { 27 | "path": "../internal" 28 | }, 29 | { 30 | "path": "../module" 31 | }, 32 | { 33 | "path": "../test-utils" 34 | } 35 | ] 36 | } 37 | -------------------------------------------------------------------------------- /packages/plugin/tsconfig.mjs.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../../tsconfig.options.json", 3 | "compilerOptions": { 4 | "outDir": "mjs", 5 | "rootDir": "src", 6 | "emitDeclarationOnly": true 7 | }, 8 | "include": [ 9 | "src/**/*", 10 | "../../types/**/*" 11 | ] 12 | } 13 | -------------------------------------------------------------------------------- /packages/terminal/README.md: -------------------------------------------------------------------------------- 1 | # Terminal utilities - Boost 2 | 3 | ![build status](https://img.shields.io/github/actions/workflow/status/milesj/boost/build.yml) 4 | ![npm version](https://img.shields.io/npm/v/@boost/terminal) 5 | 6 | A collection of utilities for managing and interacting with a terminal. 7 | 8 | ## Installation 9 | 10 | ``` 11 | yarn add @boost/terminal 12 | ``` 13 | 14 | ## Documentation 15 | 16 | - [https://boostlib.dev/docs/terminal](https://boostlib.dev/docs/terminal) 17 | - [https://boostlib.dev/api/terminal](https://boostlib.dev/api/terminal) 18 | -------------------------------------------------------------------------------- /packages/terminal/moon.yml: -------------------------------------------------------------------------------- 1 | workspace: 2 | inheritedTasks: 3 | exclude: ['test', 'test-cov'] 4 | -------------------------------------------------------------------------------- /packages/terminal/src/index.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * @copyright 2020, Miles Johnson 3 | * @license https://opensource.org/licenses/MIT 4 | */ 5 | 6 | import style from 'chalk'; 7 | import figures from 'figures'; 8 | 9 | export * as cursor from './cursor'; 10 | export * as screen from './screen'; 11 | export * from './text'; 12 | 13 | export { figures, style }; 14 | -------------------------------------------------------------------------------- /packages/terminal/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../../tsconfig.options.json", 3 | "compilerOptions": { 4 | "outDir": "../../.moon/cache/types/packages/terminal", 5 | "rootDir": "." 6 | }, 7 | "include": [ 8 | "src/**/*", 9 | "tests/**/*", 10 | "types/**/*", 11 | "../../types/**/*" 12 | ], 13 | "references": [ 14 | { 15 | "path": "./tsconfig.mjs.json" 16 | } 17 | ] 18 | } 19 | -------------------------------------------------------------------------------- /packages/terminal/tsconfig.mjs.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../../tsconfig.options.json", 3 | "compilerOptions": { 4 | "outDir": "mjs", 5 | "rootDir": "src", 6 | "emitDeclarationOnly": true 7 | }, 8 | "include": [ 9 | "src/**/*", 10 | "../../types/**/*" 11 | ] 12 | } 13 | -------------------------------------------------------------------------------- /packages/test-utils/README.md: -------------------------------------------------------------------------------- 1 | # Testing utilities - Boost 2 | 3 | ![build status](https://img.shields.io/github/actions/workflow/status/milesj/boost/build.yml) 4 | ![npm version](https://img.shields.io/npm/v/@boost/test-utils) 5 | 6 | Vite testing utilities for [Boost](https://github.com/milesj/boost/) powered applications. 7 | 8 | ## Requirements 9 | 10 | - Boost 11 | - Vite 12 | 13 | ## Installation 14 | 15 | ``` 16 | yarn add @boost/test-utils 17 | ``` 18 | -------------------------------------------------------------------------------- /packages/test-utils/moon.yml: -------------------------------------------------------------------------------- 1 | workspace: 2 | inheritedTasks: 3 | exclude: ['test', 'test-cov'] 4 | -------------------------------------------------------------------------------- /packages/test-utils/src/index.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * @copyright 2020, Miles Johnson 3 | * @license https://opensource.org/licenses/MIT 4 | */ 5 | 6 | export * from './fixtures'; 7 | export * from './types'; 8 | -------------------------------------------------------------------------------- /packages/test-utils/src/types.ts: -------------------------------------------------------------------------------- 1 | export type DirectoryContent = string | null; 2 | 3 | export type DirectoryJSON = Record; 4 | 5 | export type DirectoryStructure = DirectoryJSON | ((root: string) => DirectoryJSON); 6 | -------------------------------------------------------------------------------- /packages/test-utils/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../../tsconfig.options.json", 3 | "compilerOptions": { 4 | "outDir": "../../.moon/cache/types/packages/test-utils", 5 | "rootDir": "." 6 | }, 7 | "include": [ 8 | "src/**/*", 9 | "tests/**/*", 10 | "types/**/*", 11 | "../../types/**/*" 12 | ], 13 | "references": [ 14 | { 15 | "path": "./tsconfig.mjs.json" 16 | } 17 | ] 18 | } 19 | -------------------------------------------------------------------------------- /packages/test-utils/tsconfig.mjs.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../../tsconfig.options.json", 3 | "compilerOptions": { 4 | "outDir": "mjs", 5 | "rootDir": "src", 6 | "emitDeclarationOnly": true 7 | }, 8 | "include": [ 9 | "src/**/*", 10 | "../../types/**/*" 11 | ] 12 | } 13 | -------------------------------------------------------------------------------- /packages/translate/src/TranslateError.ts: -------------------------------------------------------------------------------- 1 | import { createScopedError } from '@boost/internal'; 2 | 3 | const errors = { 4 | LOCALE_REQUIRED: 'A locale must be defined if auto-detection is disabled.', 5 | NAMESPACE_REQUIRED: 'A namespace is required for translations.', 6 | RESOURCE_PATH_INVALID: 'Resource path "{0}" must be a directory.', 7 | RESOURCES_REQUIRED: 'At least 1 resource directory path is required.', 8 | }; 9 | 10 | export type TranslateErrorCode = keyof typeof errors; 11 | 12 | export const TranslateError = createScopedError( 13 | 'TLT', 14 | 'TranslateError', 15 | errors, 16 | ); 17 | -------------------------------------------------------------------------------- /packages/translate/src/debug.ts: -------------------------------------------------------------------------------- 1 | import { createInternalDebugger } from '@boost/internal'; 2 | 3 | export const debug = createInternalDebugger('translate'); 4 | -------------------------------------------------------------------------------- /packages/translate/src/index.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * @copyright 2020, Miles Johnson 3 | * @license https://opensource.org/licenses/MIT 4 | */ 5 | 6 | export * from './createTranslator'; 7 | export * from './TranslateError'; 8 | export * from './types'; 9 | -------------------------------------------------------------------------------- /packages/translate/tests/__snapshots__/createTranslator.test.ts.snap: -------------------------------------------------------------------------------- 1 | // Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html 2 | 3 | exports[`createTranslator() > errors if \`autoDetect\` and \`locale\` are empty 1`] = `[TranslateError: A locale must be defined if auto-detection is disabled. [TLT:LOCALE_REQUIRED]]`; 4 | 5 | exports[`createTranslator() > errors if no namespace is provided 1`] = `[TranslateError: A namespace is required for translations. [TLT:NAMESPACE_REQUIRED]]`; 6 | 7 | exports[`createTranslator() > errors if no resource paths are provided 1`] = `[TranslateError: At least 1 resource directory path is required. [TLT:RESOURCES_REQUIRED]]`; 8 | -------------------------------------------------------------------------------- /packages/translate/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../../tsconfig.options.json", 3 | "compilerOptions": { 4 | "outDir": "../../.moon/cache/types/packages/translate", 5 | "rootDir": "." 6 | }, 7 | "include": [ 8 | "src/**/*", 9 | "tests/**/*", 10 | "types/**/*", 11 | "../../types/**/*" 12 | ], 13 | "references": [ 14 | { 15 | "path": "./tsconfig.mjs.json" 16 | }, 17 | { 18 | "path": "../common" 19 | }, 20 | { 21 | "path": "../internal" 22 | } 23 | ] 24 | } 25 | -------------------------------------------------------------------------------- /packages/translate/tsconfig.mjs.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../../tsconfig.options.json", 3 | "compilerOptions": { 4 | "outDir": "mjs", 5 | "rootDir": "src", 6 | "emitDeclarationOnly": true 7 | }, 8 | "include": [ 9 | "src/**/*", 10 | "../../types/**/*" 11 | ] 12 | } 13 | -------------------------------------------------------------------------------- /prettier.config.cjs: -------------------------------------------------------------------------------- 1 | module.exports = 'prettier-config-moon'; 2 | -------------------------------------------------------------------------------- /tests/__fixtures__/.eslintrc.cjs: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | rules: { 3 | 'import/no-unresolved': 0, 4 | 'import/no-dynamic-require': 0, 5 | }, 6 | }; 7 | -------------------------------------------------------------------------------- /tests/__fixtures__/config-extends-custom-setting-name/.config/boost.json: -------------------------------------------------------------------------------- 1 | { 2 | "root": true, 3 | "presets": [ 4 | "foo", 5 | "../some/relative/path/config.js" 6 | ] 7 | } 8 | -------------------------------------------------------------------------------- /tests/__fixtures__/config-extends-custom-setting-name/node_modules/foo/boost.preset.js: -------------------------------------------------------------------------------- 1 | module.exports = {"type":"module"}; -------------------------------------------------------------------------------- /tests/__fixtures__/config-extends-custom-setting-name/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "boost-config-extends-custom-setting-name", 3 | "version": "0.0.0" 4 | } 5 | -------------------------------------------------------------------------------- /tests/__fixtures__/config-extends-custom-setting-name/some/relative/path/config.js: -------------------------------------------------------------------------------- 1 | module.exports = { type: 'fs' }; 2 | -------------------------------------------------------------------------------- /tests/__fixtures__/config-extends-from-override/.config/boost.json: -------------------------------------------------------------------------------- 1 | { 2 | "root": true, 3 | "overrides": [ 4 | { 5 | "include": [ 6 | "*" 7 | ], 8 | "settings": { 9 | "extends": "../some/relative/path/config.js", 10 | "overridden": true 11 | } 12 | } 13 | ] 14 | } 15 | -------------------------------------------------------------------------------- /tests/__fixtures__/config-extends-from-override/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "boost-config-extends-from-override", 3 | "version": "0.0.0" 4 | } 5 | -------------------------------------------------------------------------------- /tests/__fixtures__/config-extends-from-override/some/relative/path/config.js: -------------------------------------------------------------------------------- 1 | module.exports = { extended: true }; 2 | -------------------------------------------------------------------------------- /tests/__fixtures__/config-extends-fs-paths/.config/boost.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | root: true, 3 | extends: [ 4 | '../some/relative/path/config.js', 5 | `${process.cwd()}/../../tests/__fixtures__/config-extends-fs-paths/some/absolute/path/config.yml`, 6 | ], 7 | }; 8 | -------------------------------------------------------------------------------- /tests/__fixtures__/config-extends-fs-paths/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "boost-config-extends-fs-paths", 3 | "version": "0.0.0" 4 | } 5 | -------------------------------------------------------------------------------- /tests/__fixtures__/config-extends-fs-paths/some/absolute/path/config.yml: -------------------------------------------------------------------------------- 1 | absolute: true 2 | -------------------------------------------------------------------------------- /tests/__fixtures__/config-extends-fs-paths/some/relative/path/config.js: -------------------------------------------------------------------------------- 1 | module.exports = { relative: true }; 2 | -------------------------------------------------------------------------------- /tests/__fixtures__/config-extends-module-presets/.config/boost.json: -------------------------------------------------------------------------------- 1 | { 2 | "root": true, 3 | "extends": [ 4 | "foo", 5 | "@scope/bar" 6 | ] 7 | } 8 | -------------------------------------------------------------------------------- /tests/__fixtures__/config-extends-module-presets/node_modules/@scope/bar/boost.preset.js: -------------------------------------------------------------------------------- 1 | module.exports = {"name":"@scope/bar"}; -------------------------------------------------------------------------------- /tests/__fixtures__/config-extends-module-presets/node_modules/foo/boost.preset.js: -------------------------------------------------------------------------------- 1 | module.exports = {"name":"foo"}; -------------------------------------------------------------------------------- /tests/__fixtures__/config-extends-module-presets/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "boost-config-extends-module-presets", 3 | "version": "0.0.0" 4 | } 5 | -------------------------------------------------------------------------------- /tests/__fixtures__/config-file-tree-all-types/.config/boost.json: -------------------------------------------------------------------------------- 1 | { 2 | "debug": true 3 | } 4 | -------------------------------------------------------------------------------- /tests/__fixtures__/config-file-tree-all-types/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "boost-config-file-tree-all-types", 3 | "version": "0.0.0" 4 | } 5 | -------------------------------------------------------------------------------- /tests/__fixtures__/config-file-tree-all-types/src/.boost.json: -------------------------------------------------------------------------------- 1 | { 2 | "type": "json" 3 | } 4 | -------------------------------------------------------------------------------- /tests/__fixtures__/config-file-tree-all-types/src/app/.boost.cjs: -------------------------------------------------------------------------------- 1 | module.exports = { type: 'cjs' }; 2 | -------------------------------------------------------------------------------- /tests/__fixtures__/config-file-tree-all-types/src/app/profiles/.boost.js: -------------------------------------------------------------------------------- 1 | module.exports = { type: 'js' }; 2 | -------------------------------------------------------------------------------- /tests/__fixtures__/config-file-tree-all-types/src/app/profiles/settings/.boost.yaml: -------------------------------------------------------------------------------- 1 | type: yaml 2 | -------------------------------------------------------------------------------- /tests/__fixtures__/config-file-tree-cjs/.config/boost.json: -------------------------------------------------------------------------------- 1 | { 2 | "debug": true 3 | } 4 | -------------------------------------------------------------------------------- /tests/__fixtures__/config-file-tree-cjs/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "boost-config-file-tree-cjs", 3 | "type": "commonjs" 4 | } 5 | -------------------------------------------------------------------------------- /tests/__fixtures__/config-file-tree-cjs/src/app/.boost.cjs: -------------------------------------------------------------------------------- 1 | module.exports = { debug: false }; 2 | -------------------------------------------------------------------------------- /tests/__fixtures__/config-file-tree-cjs/src/app/index.js: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/milesj/boost/868b258fac254aa4c2673755a9fd5acf89091980/tests/__fixtures__/config-file-tree-cjs/src/app/index.js -------------------------------------------------------------------------------- /tests/__fixtures__/config-file-tree-cjs/src/app/profiles/Detail.ts: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/milesj/boost/868b258fac254aa4c2673755a9fd5acf89091980/tests/__fixtures__/config-file-tree-cjs/src/app/profiles/Detail.ts -------------------------------------------------------------------------------- /tests/__fixtures__/config-file-tree-cjs/src/app/profiles/settings/.boost.cjs: -------------------------------------------------------------------------------- 1 | module.exports = { verbose: true }; 2 | -------------------------------------------------------------------------------- /tests/__fixtures__/config-file-tree-cjs/src/setup.ts: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/milesj/boost/868b258fac254aa4c2673755a9fd5acf89091980/tests/__fixtures__/config-file-tree-cjs/src/setup.ts -------------------------------------------------------------------------------- /tests/__fixtures__/config-file-tree-js-root-file/boost.config.json: -------------------------------------------------------------------------------- 1 | { 2 | "debug": true 3 | } 4 | -------------------------------------------------------------------------------- /tests/__fixtures__/config-file-tree-js-root-file/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "boost-config-file-tree-js-root-file", 3 | "version": "0.0.0" 4 | } 5 | -------------------------------------------------------------------------------- /tests/__fixtures__/config-file-tree-js-root-file/src/app/.boost.js: -------------------------------------------------------------------------------- 1 | module.exports = { debug: false }; 2 | -------------------------------------------------------------------------------- /tests/__fixtures__/config-file-tree-js-root-file/src/app/index.js: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/milesj/boost/868b258fac254aa4c2673755a9fd5acf89091980/tests/__fixtures__/config-file-tree-js-root-file/src/app/index.js -------------------------------------------------------------------------------- /tests/__fixtures__/config-file-tree-js-root-file/src/app/profiles/Detail.vue: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/milesj/boost/868b258fac254aa4c2673755a9fd5acf89091980/tests/__fixtures__/config-file-tree-js-root-file/src/app/profiles/Detail.vue -------------------------------------------------------------------------------- /tests/__fixtures__/config-file-tree-js-root-file/src/app/profiles/settings/.boost.js: -------------------------------------------------------------------------------- 1 | module.exports = { verbose: true }; 2 | -------------------------------------------------------------------------------- /tests/__fixtures__/config-file-tree-js-root-file/src/setup.ts: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/milesj/boost/868b258fac254aa4c2673755a9fd5acf89091980/tests/__fixtures__/config-file-tree-js-root-file/src/setup.ts -------------------------------------------------------------------------------- /tests/__fixtures__/config-file-tree-js/.config/boost.json: -------------------------------------------------------------------------------- 1 | { 2 | "debug": true 3 | } 4 | -------------------------------------------------------------------------------- /tests/__fixtures__/config-file-tree-js/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "boost-config-file-tree-js", 3 | "version": "0.0.0" 4 | } 5 | -------------------------------------------------------------------------------- /tests/__fixtures__/config-file-tree-js/src/app/.boost.js: -------------------------------------------------------------------------------- 1 | module.exports = { debug: false }; 2 | -------------------------------------------------------------------------------- /tests/__fixtures__/config-file-tree-js/src/app/index.js: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/milesj/boost/868b258fac254aa4c2673755a9fd5acf89091980/tests/__fixtures__/config-file-tree-js/src/app/index.js -------------------------------------------------------------------------------- /tests/__fixtures__/config-file-tree-js/src/app/profiles/Detail.vue: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/milesj/boost/868b258fac254aa4c2673755a9fd5acf89091980/tests/__fixtures__/config-file-tree-js/src/app/profiles/Detail.vue -------------------------------------------------------------------------------- /tests/__fixtures__/config-file-tree-js/src/app/profiles/settings/.boost.js: -------------------------------------------------------------------------------- 1 | module.exports = { verbose: true }; 2 | -------------------------------------------------------------------------------- /tests/__fixtures__/config-file-tree-js/src/setup.ts: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/milesj/boost/868b258fac254aa4c2673755a9fd5acf89091980/tests/__fixtures__/config-file-tree-js/src/setup.ts -------------------------------------------------------------------------------- /tests/__fixtures__/config-file-tree-json/.config/boost.json: -------------------------------------------------------------------------------- 1 | { 2 | "debug": true 3 | } 4 | -------------------------------------------------------------------------------- /tests/__fixtures__/config-file-tree-json/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "boost-config-file-tree-json", 3 | "version": "0.0.0" 4 | } 5 | -------------------------------------------------------------------------------- /tests/__fixtures__/config-file-tree-json/src/app/.boost.json: -------------------------------------------------------------------------------- 1 | { 2 | "debug": false 3 | } 4 | -------------------------------------------------------------------------------- /tests/__fixtures__/config-file-tree-json/src/app/index.js: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/milesj/boost/868b258fac254aa4c2673755a9fd5acf89091980/tests/__fixtures__/config-file-tree-json/src/app/index.js -------------------------------------------------------------------------------- /tests/__fixtures__/config-file-tree-json/src/app/profiles/Detail.tsx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/milesj/boost/868b258fac254aa4c2673755a9fd5acf89091980/tests/__fixtures__/config-file-tree-json/src/app/profiles/Detail.tsx -------------------------------------------------------------------------------- /tests/__fixtures__/config-file-tree-json/src/app/profiles/settings/.boost.json: -------------------------------------------------------------------------------- 1 | { 2 | "verbose": true 3 | } 4 | -------------------------------------------------------------------------------- /tests/__fixtures__/config-file-tree-json/src/setup.ts: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/milesj/boost/868b258fac254aa4c2673755a9fd5acf89091980/tests/__fixtures__/config-file-tree-json/src/setup.ts -------------------------------------------------------------------------------- /tests/__fixtures__/config-file-tree-json5/.config/boost.json: -------------------------------------------------------------------------------- 1 | { 2 | "debug": true 3 | } 4 | -------------------------------------------------------------------------------- /tests/__fixtures__/config-file-tree-json5/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "boost-config-file-tree-json5", 3 | "version": "0.0.0" 4 | } 5 | -------------------------------------------------------------------------------- /tests/__fixtures__/config-file-tree-json5/src/app/.boost.json5: -------------------------------------------------------------------------------- 1 | { debug: false } 2 | -------------------------------------------------------------------------------- /tests/__fixtures__/config-file-tree-json5/src/app/index.js: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/milesj/boost/868b258fac254aa4c2673755a9fd5acf89091980/tests/__fixtures__/config-file-tree-json5/src/app/index.js -------------------------------------------------------------------------------- /tests/__fixtures__/config-file-tree-json5/src/app/profiles/Detail.tsx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/milesj/boost/868b258fac254aa4c2673755a9fd5acf89091980/tests/__fixtures__/config-file-tree-json5/src/app/profiles/Detail.tsx -------------------------------------------------------------------------------- /tests/__fixtures__/config-file-tree-json5/src/app/profiles/settings/.boost.json5: -------------------------------------------------------------------------------- 1 | { verbose: true } 2 | -------------------------------------------------------------------------------- /tests/__fixtures__/config-file-tree-json5/src/setup.ts: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/milesj/boost/868b258fac254aa4c2673755a9fd5acf89091980/tests/__fixtures__/config-file-tree-json5/src/setup.ts -------------------------------------------------------------------------------- /tests/__fixtures__/config-file-tree-mjs/.config/boost.json: -------------------------------------------------------------------------------- 1 | { 2 | "debug": true 3 | } 4 | -------------------------------------------------------------------------------- /tests/__fixtures__/config-file-tree-mjs/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "boost-config-file-tree-mjs", 3 | "type": "module" 4 | } 5 | -------------------------------------------------------------------------------- /tests/__fixtures__/config-file-tree-mjs/src/app/.boost.mjs: -------------------------------------------------------------------------------- 1 | exports default {"debug":false}; -------------------------------------------------------------------------------- /tests/__fixtures__/config-file-tree-mjs/src/app/index.js: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/milesj/boost/868b258fac254aa4c2673755a9fd5acf89091980/tests/__fixtures__/config-file-tree-mjs/src/app/index.js -------------------------------------------------------------------------------- /tests/__fixtures__/config-file-tree-mjs/src/app/profiles/Detail.ts: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/milesj/boost/868b258fac254aa4c2673755a9fd5acf89091980/tests/__fixtures__/config-file-tree-mjs/src/app/profiles/Detail.ts -------------------------------------------------------------------------------- /tests/__fixtures__/config-file-tree-mjs/src/app/profiles/settings/.boost.mjs: -------------------------------------------------------------------------------- 1 | exports default {"verbose":true}; -------------------------------------------------------------------------------- /tests/__fixtures__/config-file-tree-mjs/src/setup.ts: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/milesj/boost/868b258fac254aa4c2673755a9fd5acf89091980/tests/__fixtures__/config-file-tree-mjs/src/setup.ts -------------------------------------------------------------------------------- /tests/__fixtures__/config-file-tree-ts/.config/boost.json: -------------------------------------------------------------------------------- 1 | { 2 | "debug": true 3 | } 4 | -------------------------------------------------------------------------------- /tests/__fixtures__/config-file-tree-ts/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "boost-config-file-tree-ts", 3 | "version": "0.0.0" 4 | } 5 | -------------------------------------------------------------------------------- /tests/__fixtures__/config-file-tree-ts/src/app/.boost.ts: -------------------------------------------------------------------------------- 1 | const config: { debug: boolean } = { debug: false }; 2 | export default config; 3 | -------------------------------------------------------------------------------- /tests/__fixtures__/config-file-tree-ts/src/app/index.js: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/milesj/boost/868b258fac254aa4c2673755a9fd5acf89091980/tests/__fixtures__/config-file-tree-ts/src/app/index.js -------------------------------------------------------------------------------- /tests/__fixtures__/config-file-tree-ts/src/app/profiles/Detail.vue: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/milesj/boost/868b258fac254aa4c2673755a9fd5acf89091980/tests/__fixtures__/config-file-tree-ts/src/app/profiles/Detail.vue -------------------------------------------------------------------------------- /tests/__fixtures__/config-file-tree-ts/src/app/profiles/settings/.boost.ts: -------------------------------------------------------------------------------- 1 | const config: { verbose: boolean } = { verbose: true }; 2 | export default config; 3 | -------------------------------------------------------------------------------- /tests/__fixtures__/config-file-tree-ts/src/setup.ts: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/milesj/boost/868b258fac254aa4c2673755a9fd5acf89091980/tests/__fixtures__/config-file-tree-ts/src/setup.ts -------------------------------------------------------------------------------- /tests/__fixtures__/config-file-tree-yaml/.config/boost.json: -------------------------------------------------------------------------------- 1 | { 2 | "debug": true 3 | } 4 | -------------------------------------------------------------------------------- /tests/__fixtures__/config-file-tree-yaml/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "boost-config-file-tree-yaml", 3 | "version": "0.0.0" 4 | } 5 | -------------------------------------------------------------------------------- /tests/__fixtures__/config-file-tree-yaml/src/app/.boost.yaml: -------------------------------------------------------------------------------- 1 | debug: false 2 | -------------------------------------------------------------------------------- /tests/__fixtures__/config-file-tree-yaml/src/app/index.js: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/milesj/boost/868b258fac254aa4c2673755a9fd5acf89091980/tests/__fixtures__/config-file-tree-yaml/src/app/index.js -------------------------------------------------------------------------------- /tests/__fixtures__/config-file-tree-yaml/src/app/profiles/Detail.tsx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/milesj/boost/868b258fac254aa4c2673755a9fd5acf89091980/tests/__fixtures__/config-file-tree-yaml/src/app/profiles/Detail.tsx -------------------------------------------------------------------------------- /tests/__fixtures__/config-file-tree-yaml/src/app/profiles/settings/.boost.yaml: -------------------------------------------------------------------------------- 1 | verbose: true 2 | -------------------------------------------------------------------------------- /tests/__fixtures__/config-file-tree-yaml/src/setup.ts: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/milesj/boost/868b258fac254aa4c2673755a9fd5acf89091980/tests/__fixtures__/config-file-tree-yaml/src/setup.ts -------------------------------------------------------------------------------- /tests/__fixtures__/config-file-tree-yml/.config/boost.json: -------------------------------------------------------------------------------- 1 | { 2 | "debug": true 3 | } 4 | -------------------------------------------------------------------------------- /tests/__fixtures__/config-file-tree-yml/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "boost-config-file-tree-yml", 3 | "version": "0.0.0" 4 | } 5 | -------------------------------------------------------------------------------- /tests/__fixtures__/config-file-tree-yml/src/app/.boost.yml: -------------------------------------------------------------------------------- 1 | debug: false 2 | -------------------------------------------------------------------------------- /tests/__fixtures__/config-file-tree-yml/src/app/index.js: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/milesj/boost/868b258fac254aa4c2673755a9fd5acf89091980/tests/__fixtures__/config-file-tree-yml/src/app/index.js -------------------------------------------------------------------------------- /tests/__fixtures__/config-file-tree-yml/src/app/profiles/Detail.tsx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/milesj/boost/868b258fac254aa4c2673755a9fd5acf89091980/tests/__fixtures__/config-file-tree-yml/src/app/profiles/Detail.tsx -------------------------------------------------------------------------------- /tests/__fixtures__/config-file-tree-yml/src/app/profiles/settings/.boost.yml: -------------------------------------------------------------------------------- 1 | verbose: true 2 | -------------------------------------------------------------------------------- /tests/__fixtures__/config-file-tree-yml/src/setup.ts: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/milesj/boost/868b258fac254aa4c2673755a9fd5acf89091980/tests/__fixtures__/config-file-tree-yml/src/setup.ts -------------------------------------------------------------------------------- /tests/__fixtures__/config-ignore-file-tree/.boostignore: -------------------------------------------------------------------------------- 1 | *.log 2 | *.lock -------------------------------------------------------------------------------- /tests/__fixtures__/config-ignore-file-tree/.config/boost.json: -------------------------------------------------------------------------------- 1 | { 2 | "debug": true 3 | } 4 | -------------------------------------------------------------------------------- /tests/__fixtures__/config-ignore-file-tree/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "boost-config-ignore-file-tree", 3 | "version": "0.0.0" 4 | } 5 | -------------------------------------------------------------------------------- /tests/__fixtures__/config-ignore-file-tree/src/app/components/build/.boostignore: -------------------------------------------------------------------------------- 1 | esm/ -------------------------------------------------------------------------------- /tests/__fixtures__/config-ignore-file-tree/src/app/components/build/Button.tsx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/milesj/boost/868b258fac254aa4c2673755a9fd5acf89091980/tests/__fixtures__/config-ignore-file-tree/src/app/components/build/Button.tsx -------------------------------------------------------------------------------- /tests/__fixtures__/config-ignore-file-tree/src/app/feature/.boostignore: -------------------------------------------------------------------------------- 1 | # Compiled 2 | lib/ -------------------------------------------------------------------------------- /tests/__fixtures__/config-ignore-file-tree/src/app/feature/signup/.boostignore: -------------------------------------------------------------------------------- 1 | # Empty -------------------------------------------------------------------------------- /tests/__fixtures__/config-ignore-file-tree/src/app/feature/signup/flow/StepOne.tsx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/milesj/boost/868b258fac254aa4c2673755a9fd5acf89091980/tests/__fixtures__/config-ignore-file-tree/src/app/feature/signup/flow/StepOne.tsx -------------------------------------------------------------------------------- /tests/__fixtures__/config-invalid-branch-nested-extends/.config/boost.json: -------------------------------------------------------------------------------- 1 | { 2 | "level": 1, 3 | "extends": [] 4 | } 5 | -------------------------------------------------------------------------------- /tests/__fixtures__/config-invalid-branch-nested-extends/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "boost-config-invalid-branch-nested-extends", 3 | "version": "0.0.0" 4 | } 5 | -------------------------------------------------------------------------------- /tests/__fixtures__/config-invalid-branch-nested-extends/src/.boost.json: -------------------------------------------------------------------------------- 1 | { 2 | "level": 2, 3 | "extends": [] 4 | } 5 | -------------------------------------------------------------------------------- /tests/__fixtures__/config-invalid-branch-nested-overrides/.config/boost.json: -------------------------------------------------------------------------------- 1 | { 2 | "level": 1, 3 | "overrides": [] 4 | } 5 | -------------------------------------------------------------------------------- /tests/__fixtures__/config-invalid-branch-nested-overrides/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "boost-config-invalid-branch-nested-overrides", 3 | "version": "0.0.0" 4 | } 5 | -------------------------------------------------------------------------------- /tests/__fixtures__/config-invalid-branch-nested-overrides/src/.boost.json: -------------------------------------------------------------------------------- 1 | { 2 | "level": 2, 3 | "overrides": [] 4 | } 5 | -------------------------------------------------------------------------------- /tests/__fixtures__/config-invalid-extends-path/.config/boost.json: -------------------------------------------------------------------------------- 1 | { 2 | "root": true, 3 | "extends": "123!#?" 4 | } 5 | -------------------------------------------------------------------------------- /tests/__fixtures__/config-invalid-extends-path/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "boost-config-invalid-extends-path", 3 | "version": "0.0.0" 4 | } 5 | -------------------------------------------------------------------------------- /tests/__fixtures__/config-missing-extends-path/.config/boost.json: -------------------------------------------------------------------------------- 1 | { 2 | "root": true, 3 | "extends": "../some/missing/path/config.js" 4 | } 5 | -------------------------------------------------------------------------------- /tests/__fixtures__/config-missing-extends-path/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "boost-config-missing-extends-path", 3 | "version": "0.0.0" 4 | } 5 | -------------------------------------------------------------------------------- /tests/__fixtures__/config-overrides-custom-settings-name/.config/boost.json: -------------------------------------------------------------------------------- 1 | { 2 | "level": 1, 3 | "rules": [ 4 | { 5 | "include": "*.ts", 6 | "settings": { 7 | "level": 2 8 | } 9 | } 10 | ] 11 | } 12 | -------------------------------------------------------------------------------- /tests/__fixtures__/config-overrides-custom-settings-name/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "boost-config-overrides-custom-settings-name", 3 | "version": "0.0.0" 4 | } 5 | -------------------------------------------------------------------------------- /tests/__fixtures__/config-overrides-custom-settings-name/src/bar/doesnt-match.ts: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/milesj/boost/868b258fac254aa4c2673755a9fd5acf89091980/tests/__fixtures__/config-overrides-custom-settings-name/src/bar/doesnt-match.ts -------------------------------------------------------------------------------- /tests/__fixtures__/config-overrides-custom-settings-name/src/foo/does-match.ts: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/milesj/boost/868b258fac254aa4c2673755a9fd5acf89091980/tests/__fixtures__/config-overrides-custom-settings-name/src/foo/does-match.ts -------------------------------------------------------------------------------- /tests/__fixtures__/config-overrides-custom-settings-name/src/foo/doesnt-match.js: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/milesj/boost/868b258fac254aa4c2673755a9fd5acf89091980/tests/__fixtures__/config-overrides-custom-settings-name/src/foo/doesnt-match.js -------------------------------------------------------------------------------- /tests/__fixtures__/config-overrides-from-branch-with-excludes/.config/boost.json: -------------------------------------------------------------------------------- 1 | { 2 | "level": 1, 3 | "overrides": [ 4 | { 5 | "exclude": "baz.ts", 6 | "include": [ 7 | "ba*" 8 | ], 9 | "settings": { 10 | "level": 2 11 | } 12 | } 13 | ] 14 | } 15 | -------------------------------------------------------------------------------- /tests/__fixtures__/config-overrides-from-branch-with-excludes/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "boost-config-overrides-from-branch-with-excludes", 3 | "version": "0.0.0" 4 | } 5 | -------------------------------------------------------------------------------- /tests/__fixtures__/config-overrides-from-branch-with-excludes/src/baa.ts: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/milesj/boost/868b258fac254aa4c2673755a9fd5acf89091980/tests/__fixtures__/config-overrides-from-branch-with-excludes/src/baa.ts -------------------------------------------------------------------------------- /tests/__fixtures__/config-overrides-from-branch-with-excludes/src/bar.ts: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/milesj/boost/868b258fac254aa4c2673755a9fd5acf89091980/tests/__fixtures__/config-overrides-from-branch-with-excludes/src/bar.ts -------------------------------------------------------------------------------- /tests/__fixtures__/config-overrides-from-branch-with-excludes/src/baz.ts: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/milesj/boost/868b258fac254aa4c2673755a9fd5acf89091980/tests/__fixtures__/config-overrides-from-branch-with-excludes/src/baz.ts -------------------------------------------------------------------------------- /tests/__fixtures__/config-overrides-from-branch/.config/boost.json: -------------------------------------------------------------------------------- 1 | { 2 | "level": 1, 3 | "overrides": [ 4 | { 5 | "include": "*.ts", 6 | "settings": { 7 | "level": 2 8 | } 9 | } 10 | ] 11 | } 12 | -------------------------------------------------------------------------------- /tests/__fixtures__/config-overrides-from-branch/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "boost-config-overrides-from-branch", 3 | "version": "0.0.0" 4 | } 5 | -------------------------------------------------------------------------------- /tests/__fixtures__/config-overrides-from-branch/src/bar/doesnt-match.ts: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/milesj/boost/868b258fac254aa4c2673755a9fd5acf89091980/tests/__fixtures__/config-overrides-from-branch/src/bar/doesnt-match.ts -------------------------------------------------------------------------------- /tests/__fixtures__/config-overrides-from-branch/src/foo/does-match.ts: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/milesj/boost/868b258fac254aa4c2673755a9fd5acf89091980/tests/__fixtures__/config-overrides-from-branch/src/foo/does-match.ts -------------------------------------------------------------------------------- /tests/__fixtures__/config-overrides-from-branch/src/foo/doesnt-match.js: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/milesj/boost/868b258fac254aa4c2673755a9fd5acf89091980/tests/__fixtures__/config-overrides-from-branch/src/foo/doesnt-match.js -------------------------------------------------------------------------------- /tests/__fixtures__/config-package-file-tree-monorepo/.config/boost.json: -------------------------------------------------------------------------------- 1 | { 2 | "debug": true 3 | } 4 | -------------------------------------------------------------------------------- /tests/__fixtures__/config-package-file-tree-monorepo/index.ts: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/milesj/boost/868b258fac254aa4c2673755a9fd5acf89091980/tests/__fixtures__/config-package-file-tree-monorepo/index.ts -------------------------------------------------------------------------------- /tests/__fixtures__/config-package-file-tree-monorepo/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "boost-config-package-file-tree-monorepo", 3 | "version": "0.0.0" 4 | } 5 | -------------------------------------------------------------------------------- /tests/__fixtures__/config-package-file-tree-monorepo/packages/core/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "core" 3 | } 4 | -------------------------------------------------------------------------------- /tests/__fixtures__/config-package-file-tree-monorepo/packages/core/src/deep/nested/core.ts: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/milesj/boost/868b258fac254aa4c2673755a9fd5acf89091980/tests/__fixtures__/config-package-file-tree-monorepo/packages/core/src/deep/nested/core.ts -------------------------------------------------------------------------------- /tests/__fixtures__/config-package-file-tree-monorepo/packages/core/src/index.ts: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/milesj/boost/868b258fac254aa4c2673755a9fd5acf89091980/tests/__fixtures__/config-package-file-tree-monorepo/packages/core/src/index.ts -------------------------------------------------------------------------------- /tests/__fixtures__/config-package-file-tree-monorepo/packages/log/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "log" 3 | } 4 | -------------------------------------------------------------------------------- /tests/__fixtures__/config-package-file-tree-monorepo/packages/log/src/index.js: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/milesj/boost/868b258fac254aa4c2673755a9fd5acf89091980/tests/__fixtures__/config-package-file-tree-monorepo/packages/log/src/index.js -------------------------------------------------------------------------------- /tests/__fixtures__/config-package-file-tree-monorepo/packages/plugin/index.js: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/milesj/boost/868b258fac254aa4c2673755a9fd5acf89091980/tests/__fixtures__/config-package-file-tree-monorepo/packages/plugin/index.js -------------------------------------------------------------------------------- /tests/__fixtures__/config-package-file-tree-monorepo/packages/plugin/nested/example/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "plugin-example" 3 | } 4 | -------------------------------------------------------------------------------- /tests/__fixtures__/config-package-file-tree-monorepo/packages/plugin/nested/example/src/index.ts: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/milesj/boost/868b258fac254aa4c2673755a9fd5acf89091980/tests/__fixtures__/config-package-file-tree-monorepo/packages/plugin/nested/example/src/index.ts -------------------------------------------------------------------------------- /tests/__fixtures__/config-package-file-tree-monorepo/packages/plugin/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "plugin" 3 | } 4 | -------------------------------------------------------------------------------- /tests/__fixtures__/config-root-config-cjs/.config/boost.cjs: -------------------------------------------------------------------------------- 1 | module.exports = { debug: true }; 2 | -------------------------------------------------------------------------------- /tests/__fixtures__/config-root-config-cjs/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "boost-config-root-config-cjs", 3 | "type": "commonjs" 4 | } 5 | -------------------------------------------------------------------------------- /tests/__fixtures__/config-root-config-js-file/boost.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { debug: true }; 2 | -------------------------------------------------------------------------------- /tests/__fixtures__/config-root-config-js-file/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "boost-config-root-config-js-file", 3 | "version": "0.0.0" 4 | } 5 | -------------------------------------------------------------------------------- /tests/__fixtures__/config-root-config-js/.config/boost.js: -------------------------------------------------------------------------------- 1 | module.exports = { debug: true }; 2 | -------------------------------------------------------------------------------- /tests/__fixtures__/config-root-config-js/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "boost-config-root-config-js", 3 | "version": "0.0.0" 4 | } 5 | -------------------------------------------------------------------------------- /tests/__fixtures__/config-root-config-json/.config/boost.json: -------------------------------------------------------------------------------- 1 | { 2 | "debug": true 3 | } 4 | -------------------------------------------------------------------------------- /tests/__fixtures__/config-root-config-json/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "boost-config-root-config-json", 3 | "version": "0.0.0" 4 | } 5 | -------------------------------------------------------------------------------- /tests/__fixtures__/config-root-config-json5/.config/boost.json5: -------------------------------------------------------------------------------- 1 | { debug: true } 2 | -------------------------------------------------------------------------------- /tests/__fixtures__/config-root-config-json5/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "boost-config-root-config-json5", 3 | "version": "0.0.0" 4 | } 5 | -------------------------------------------------------------------------------- /tests/__fixtures__/config-root-config-mjs/.config/boost.mjs: -------------------------------------------------------------------------------- 1 | exports default {"debug":true}; -------------------------------------------------------------------------------- /tests/__fixtures__/config-root-config-mjs/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "boost-config-root-config-mjs", 3 | "type": "module" 4 | } 5 | -------------------------------------------------------------------------------- /tests/__fixtures__/config-root-config-toml/.config/boost.toml: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/milesj/boost/868b258fac254aa4c2673755a9fd5acf89091980/tests/__fixtures__/config-root-config-toml/.config/boost.toml -------------------------------------------------------------------------------- /tests/__fixtures__/config-root-config-toml/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "boost-config-root-config-toml", 3 | "version": "0.0.0" 4 | } 5 | -------------------------------------------------------------------------------- /tests/__fixtures__/config-root-config-ts/.config/boost.ts: -------------------------------------------------------------------------------- 1 | const config: { debug: boolean } = { debug: true }; 2 | export default config; 3 | -------------------------------------------------------------------------------- /tests/__fixtures__/config-root-config-ts/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "boost-config-root-config-ts", 3 | "type": "typescript" 4 | } 5 | -------------------------------------------------------------------------------- /tests/__fixtures__/config-root-config-yaml/.config/boost.yaml: -------------------------------------------------------------------------------- 1 | debug: true 2 | -------------------------------------------------------------------------------- /tests/__fixtures__/config-root-config-yaml/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "boost-config-root-config-yaml", 3 | "version": "0.0.0" 4 | } 5 | -------------------------------------------------------------------------------- /tests/__fixtures__/config-root-config-yml/.config/boost.yml: -------------------------------------------------------------------------------- 1 | debug: true 2 | -------------------------------------------------------------------------------- /tests/__fixtures__/config-root-config-yml/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "boost-config-root-config-yml", 3 | "version": "0.0.0" 4 | } 5 | -------------------------------------------------------------------------------- /tests/__fixtures__/config-root-without-package-json/.config/boost.json: -------------------------------------------------------------------------------- 1 | { 2 | "debug": true 3 | } 4 | -------------------------------------------------------------------------------- /tests/__fixtures__/config-root-without-package-json/nested/index.js: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/milesj/boost/868b258fac254aa4c2673755a9fd5acf89091980/tests/__fixtures__/config-root-without-package-json/nested/index.js -------------------------------------------------------------------------------- /tests/__fixtures__/config-scenario-branch-invalid-file-name/.config/boost.json: -------------------------------------------------------------------------------- 1 | { 2 | "debug": true 3 | } 4 | -------------------------------------------------------------------------------- /tests/__fixtures__/config-scenario-branch-invalid-file-name/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "boost-config-scenario-branch-invalid-file-name", 3 | "version": "0.0.0" 4 | } 5 | -------------------------------------------------------------------------------- /tests/__fixtures__/config-scenario-branch-invalid-file-name/src/app/.boost.toml: -------------------------------------------------------------------------------- 1 | invalidExt: true 2 | -------------------------------------------------------------------------------- /tests/__fixtures__/config-scenario-branch-invalid-file-name/src/boost.json: -------------------------------------------------------------------------------- 1 | missingDot: true 2 | -------------------------------------------------------------------------------- /tests/__fixtures__/config-scenario-branch-multiple-types/.config/boost.json: -------------------------------------------------------------------------------- 1 | { 2 | "debug": true 3 | } 4 | -------------------------------------------------------------------------------- /tests/__fixtures__/config-scenario-branch-multiple-types/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "boost-config-scenario-branch-multiple-types", 3 | "version": "0.0.0" 4 | } 5 | -------------------------------------------------------------------------------- /tests/__fixtures__/config-scenario-branch-multiple-types/src/app/.boost.json: -------------------------------------------------------------------------------- 1 | { 2 | "type": "json" 3 | } 4 | -------------------------------------------------------------------------------- /tests/__fixtures__/config-scenario-branch-multiple-types/src/app/.boost.yaml: -------------------------------------------------------------------------------- 1 | type: yaml 2 | -------------------------------------------------------------------------------- /tests/__fixtures__/config-scenario-branch-root-file/boost.config.json: -------------------------------------------------------------------------------- 1 | { 2 | "debug": true 3 | } 4 | -------------------------------------------------------------------------------- /tests/__fixtures__/config-scenario-branch-root-file/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "boost-config-scenario-branch-root-file", 3 | "version": "0.0.0" 4 | } 5 | -------------------------------------------------------------------------------- /tests/__fixtures__/config-scenario-branch-root-file/src/app/.boost.json: -------------------------------------------------------------------------------- 1 | { 2 | "type": "json" 3 | } 4 | -------------------------------------------------------------------------------- /tests/__fixtures__/config-scenario-branch-with-envs/.config/boost.json: -------------------------------------------------------------------------------- 1 | { 2 | "debug": true 3 | } 4 | -------------------------------------------------------------------------------- /tests/__fixtures__/config-scenario-branch-with-envs/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "boost-config-scenario-branch-with-envs", 3 | "version": "0.0.0" 4 | } 5 | -------------------------------------------------------------------------------- /tests/__fixtures__/config-scenario-branch-with-envs/src/app/.boost.json: -------------------------------------------------------------------------------- 1 | { 2 | "env": "all" 3 | } 4 | -------------------------------------------------------------------------------- /tests/__fixtures__/config-scenario-branch-with-envs/src/app/.boost.production.json: -------------------------------------------------------------------------------- 1 | { 2 | "env": "production" 3 | } 4 | -------------------------------------------------------------------------------- /tests/__fixtures__/config-scenario-branch-with-envs/src/app/.boost.staging.json: -------------------------------------------------------------------------------- 1 | { 2 | "env": "staging" 3 | } 4 | -------------------------------------------------------------------------------- /tests/__fixtures__/config-scenario-branch-with-envs/src/app/.boost.test.json: -------------------------------------------------------------------------------- 1 | { 2 | "env": "test" 3 | } 4 | -------------------------------------------------------------------------------- /tests/__fixtures__/config-scenario-configs-above-root/.boost.json: -------------------------------------------------------------------------------- 1 | { 2 | "belowRoot": true 3 | } 4 | -------------------------------------------------------------------------------- /tests/__fixtures__/config-scenario-configs-above-root/.config/boost.json: -------------------------------------------------------------------------------- 1 | { 2 | "belowRoot": true 3 | } 4 | -------------------------------------------------------------------------------- /tests/__fixtures__/config-scenario-configs-above-root/nested/.config/boost.json: -------------------------------------------------------------------------------- 1 | { 2 | "root": true 3 | } 4 | -------------------------------------------------------------------------------- /tests/__fixtures__/config-scenario-configs-above-root/nested/deep/.boost.json: -------------------------------------------------------------------------------- 1 | { 2 | "aboveRoot": true 3 | } 4 | -------------------------------------------------------------------------------- /tests/__fixtures__/config-scenario-configs-above-root/nested/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "boost-config-scenario-configs-above-root", 3 | "type": "commonjs" 4 | } 5 | -------------------------------------------------------------------------------- /tests/__fixtures__/config-scenario-not-root/.empty: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/milesj/boost/868b258fac254aa4c2673755a9fd5acf89091980/tests/__fixtures__/config-scenario-not-root/.empty -------------------------------------------------------------------------------- /tests/__fixtures__/file-types/js.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | type: 'js', 3 | }; 4 | -------------------------------------------------------------------------------- /tests/__fixtures__/file-types/json.json: -------------------------------------------------------------------------------- 1 | { 2 | "type": "json" 3 | } 4 | -------------------------------------------------------------------------------- /tests/__fixtures__/file-types/json5.json5: -------------------------------------------------------------------------------- 1 | { 2 | type: 'json5', 3 | } 4 | -------------------------------------------------------------------------------- /tests/__fixtures__/file-types/jsx.jsx: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | jsx: true, 3 | type: 'js', 4 | }; 5 | -------------------------------------------------------------------------------- /tests/__fixtures__/file-types/ts.ts: -------------------------------------------------------------------------------- 1 | const config: Record = { 2 | type: 'ts', 3 | }; 4 | 5 | export default config; 6 | -------------------------------------------------------------------------------- /tests/__fixtures__/file-types/tsx.tsx: -------------------------------------------------------------------------------- 1 | export default { 2 | type: 'tsx', 3 | }; 4 | -------------------------------------------------------------------------------- /tests/__fixtures__/file-types/yaml.yaml: -------------------------------------------------------------------------------- 1 | type: yaml 2 | -------------------------------------------------------------------------------- /tests/__fixtures__/file-types/yml.yml: -------------------------------------------------------------------------------- 1 | short: true 2 | type: yaml 3 | -------------------------------------------------------------------------------- /tests/__fixtures__/i18n-resources-more/en-US/common.yaml: -------------------------------------------------------------------------------- 1 | region: us 2 | -------------------------------------------------------------------------------- /tests/__fixtures__/i18n-resources-more/en/common.yaml: -------------------------------------------------------------------------------- 1 | lang: 'en' 2 | -------------------------------------------------------------------------------- /tests/__fixtures__/i18n-resources/en/common.yaml: -------------------------------------------------------------------------------- 1 | key: 'value' 2 | -------------------------------------------------------------------------------- /tests/__fixtures__/i18n-resources/en/type-cjs.cjs: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | type: 'cjs', 3 | }; 4 | -------------------------------------------------------------------------------- /tests/__fixtures__/i18n-resources/en/type-js.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | type: 'js', 3 | }; 4 | -------------------------------------------------------------------------------- /tests/__fixtures__/i18n-resources/en/type-json.json: -------------------------------------------------------------------------------- 1 | { 2 | "type": "json" 3 | } 4 | -------------------------------------------------------------------------------- /tests/__fixtures__/i18n-resources/en/type-json5.json5: -------------------------------------------------------------------------------- 1 | { 2 | type: 'json5', 3 | } 4 | -------------------------------------------------------------------------------- /tests/__fixtures__/i18n-resources/en/type-mjs.mjs: -------------------------------------------------------------------------------- 1 | export default { 2 | type: 'mjs', 3 | }; 4 | -------------------------------------------------------------------------------- /tests/__fixtures__/i18n-resources/en/type-yaml-short.yml: -------------------------------------------------------------------------------- 1 | type: 'yaml' 2 | short: true 3 | -------------------------------------------------------------------------------- /tests/__fixtures__/i18n-resources/en/type-yaml.yaml: -------------------------------------------------------------------------------- 1 | type: 'yaml' 2 | -------------------------------------------------------------------------------- /tests/__fixtures__/i18n-resources/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "test", 3 | "type": "commonjs" 4 | } 5 | -------------------------------------------------------------------------------- /tests/__fixtures__/module-basic/bar.js: -------------------------------------------------------------------------------- 1 | module.exports = 'bar'; 2 | -------------------------------------------------------------------------------- /tests/__fixtures__/module-basic/foo.js: -------------------------------------------------------------------------------- 1 | module.exports = 'foo'; 2 | -------------------------------------------------------------------------------- /tests/__fixtures__/module-basic/index.js: -------------------------------------------------------------------------------- 1 | exports = 'main'; 2 | -------------------------------------------------------------------------------- /tests/__fixtures__/module-basic/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "module-basic", 3 | "version": "0.0.0", 4 | "main": "./index.js" 5 | } 6 | -------------------------------------------------------------------------------- /tests/__fixtures__/module-no-package/index.js: -------------------------------------------------------------------------------- 1 | module.exports = {}; 2 | -------------------------------------------------------------------------------- /tests/__fixtures__/plugin-export-nonfunc/index.js: -------------------------------------------------------------------------------- 1 | module.exports = {}; 2 | -------------------------------------------------------------------------------- /tests/__fixtures__/plugin-renderer-class/index.mjs: -------------------------------------------------------------------------------- 1 | import { Plugin } from '@boost/plugin'; 2 | 3 | class Renderer extends Plugin { 4 | blueprint({ string }) { 5 | return { 6 | value: string(), 7 | }; 8 | } 9 | 10 | render() { 11 | return 'test'; 12 | } 13 | } 14 | 15 | // Async 16 | export default async function rendererPlugin(options) { 17 | await Promise.resolve(); 18 | 19 | return new Renderer(options); 20 | }; 21 | -------------------------------------------------------------------------------- /tests/__fixtures__/plugin-renderer-object/index.js: -------------------------------------------------------------------------------- 1 | // Sync 2 | module.exports = function rendererPlugin(options) { 3 | return { 4 | options, 5 | render() { 6 | return 'test'; 7 | }, 8 | }; 9 | }; 10 | -------------------------------------------------------------------------------- /tests/__fixtures__/workspace-lerna/lerna.json: -------------------------------------------------------------------------------- 1 | { 2 | "packages": [ 3 | "packages/*" 4 | ] 5 | } 6 | -------------------------------------------------------------------------------- /tests/__fixtures__/workspace-lerna/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "test-boost-workspace-lerna", 3 | "version": "0.0.0", 4 | "testBoost": { 5 | "lerna": true 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /tests/__fixtures__/workspace-lerna/packages/foo/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "test-boost-workspace-foo-lerna", 3 | "version": "0.0.0" 4 | } 5 | -------------------------------------------------------------------------------- /tests/__fixtures__/workspace-mismatch/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "test-boost-workspace-mismatch", 3 | "version": "0.0.0", 4 | "workspaces": [ 5 | "workspaces/*" 6 | ], 7 | "testBoost": { 8 | "yarn": true 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /tests/__fixtures__/workspace-mismatch/packages/foo/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "test-boost-workspace-foo-mismatch", 3 | "version": "0.0.0" 4 | } 5 | -------------------------------------------------------------------------------- /tests/__fixtures__/workspace-multiple/modules/bar/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "test-boost-workspace-multiple-bar", 3 | "version": "0.0.0" 4 | } 5 | -------------------------------------------------------------------------------- /tests/__fixtures__/workspace-multiple/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "test-boost-workspace-multiple", 3 | "version": "0.0.0", 4 | "workspaces": [ 5 | "packages/*", 6 | "modules/*" 7 | ] 8 | } 9 | -------------------------------------------------------------------------------- /tests/__fixtures__/workspace-multiple/packages/baz/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "test-boost-workspace-multiple-baz", 3 | "version": "0.0.0" 4 | } 5 | -------------------------------------------------------------------------------- /tests/__fixtures__/workspace-multiple/packages/foo/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "test-boost-workspace-multiple-foo", 3 | "version": "0.0.0" 4 | } 5 | -------------------------------------------------------------------------------- /tests/__fixtures__/workspace-no-config/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "test-boost-workspace-no-config", 3 | "version": "0.0.0", 4 | "workspaces": [ 5 | "packages/*" 6 | ] 7 | } 8 | -------------------------------------------------------------------------------- /tests/__fixtures__/workspace-no-config/packages/foo/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "test-boost-workspace-foo-no-config", 3 | "version": "0.0.0" 4 | } 5 | -------------------------------------------------------------------------------- /tests/__fixtures__/workspace-no-packages/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "test-boost-workspace-no-packages", 3 | "version": "0.0.0" 4 | } 5 | -------------------------------------------------------------------------------- /tests/__fixtures__/workspace-pnpm/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "test-boost-workspace-pnpm", 3 | "version": "0.0.0", 4 | "testBoost": { 5 | "pnpm": true 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /tests/__fixtures__/workspace-pnpm/packages/foo/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "test-boost-workspace-foo-pnpm", 3 | "version": "0.0.0" 4 | } 5 | -------------------------------------------------------------------------------- /tests/__fixtures__/workspace-pnpm/packages/qux/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "test-boost-workspace-qux-pnpm", 3 | "version": "0.0.0" 4 | } 5 | -------------------------------------------------------------------------------- /tests/__fixtures__/workspace-pnpm/pnpm-workspace.yaml: -------------------------------------------------------------------------------- 1 | packages: 2 | - 'packages/**' 3 | - '!**/qux' 4 | -------------------------------------------------------------------------------- /tests/__fixtures__/workspace-yarn-nohoist/configs/testBoost.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | yarn: true, 3 | nohoist: true, 4 | }; 5 | -------------------------------------------------------------------------------- /tests/__fixtures__/workspace-yarn-nohoist/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "test-boost-workspace-yarn-nohoist", 3 | "version": "0.0.0", 4 | "workspaces": { 5 | "packages": [ 6 | "packages/*" 7 | ], 8 | "nohoist": [ 9 | "**/react-native/**" 10 | ] 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /tests/__fixtures__/workspace-yarn-nohoist/packages/foo/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "test-boost-workspace-foo-yarn-nohoist", 3 | "version": "0.0.0" 4 | } 5 | -------------------------------------------------------------------------------- /tests/__fixtures__/workspace-yarn/configs/testBoost.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | yarn: true, 3 | }; 4 | -------------------------------------------------------------------------------- /tests/__fixtures__/workspace-yarn/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "test-boost-workspace-yarn", 3 | "version": "0.0.0", 4 | "workspaces": [ 5 | "packages/*" 6 | ] 7 | } 8 | -------------------------------------------------------------------------------- /tests/__fixtures__/workspace-yarn/packages/foo/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "test-boost-workspace-foo-yarn", 3 | "version": "0.0.0" 4 | } 5 | -------------------------------------------------------------------------------- /themes/dracula/README.md: -------------------------------------------------------------------------------- 1 | # Dracula Theme - Boost 2 | 3 | [Dracula](https://draculatheme.com/) command line theme for Boost powered CLIs. Ideal for dark 4 | terminals. 5 | 6 | ```bash 7 | yarn install @boost/theme-dracula --dev 8 | ``` 9 | -------------------------------------------------------------------------------- /themes/dracula/index.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @copyright 2020, Miles Johnson 3 | * @license https://opensource.org/licenses/MIT 4 | */ 5 | 6 | module.exports = { 7 | default: '#f8f8f2', 8 | failure: '#ff5555', 9 | info: '#9ee4f7', 10 | inverted: '#282a36', 11 | muted: '#999999', 12 | notice: '#e97fbf', 13 | success: '#50fa7b', 14 | warning: '#f1fa8c', 15 | }; 16 | -------------------------------------------------------------------------------- /themes/dracula/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@boost/theme-dracula", 3 | "version": "2.1.1", 4 | "release": "1594765247526", 5 | "description": "Dracula command line theme for Boost powered CLIs.", 6 | "keywords": [ 7 | "boost", 8 | "theme", 9 | "dracula" 10 | ], 11 | "main": "./index.js", 12 | "repository": "https://github.com/milesj/boost/tree/master/themes/dracula", 13 | "license": "MIT", 14 | "publishConfig": { 15 | "access": "public" 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /themes/moon-dark/README.md: -------------------------------------------------------------------------------- 1 | # DSOTM Theme - Boost 2 | 3 | [Dark Side of the Moon](https://github.com/thierryc/dark-side-of-the-moon-syntax) command line theme 4 | for Boost powered CLIs. Ideal for dark terminals. 5 | 6 | ```bash 7 | yarn install @boost/theme-moon-dark --dev 8 | ``` 9 | -------------------------------------------------------------------------------- /themes/moon-dark/index.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @copyright 2020, Miles Johnson 3 | * @license https://opensource.org/licenses/MIT 4 | */ 5 | 6 | module.exports = { 7 | default: '#e2e2e2', 8 | failure: '#e88147', 9 | info: '#47c1d6', 10 | inverted: '#201d1e', 11 | muted: '#7C7C7C', 12 | notice: '#b368db', 13 | success: '#7bb571', 14 | warning: '#fbb71b', 15 | }; 16 | -------------------------------------------------------------------------------- /themes/moon-dark/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@boost/theme-moon-dark", 3 | "version": "2.1.1", 4 | "release": "1594765247526", 5 | "description": "Dark Side of the Moon command line theme for Boost powered CLIs.", 6 | "keywords": [ 7 | "boost", 8 | "theme", 9 | "moon", 10 | "dark", 11 | "side" 12 | ], 13 | "main": "./index.js", 14 | "repository": "https://github.com/milesj/boost/tree/master/themes/moon-dark", 15 | "license": "MIT", 16 | "publishConfig": { 17 | "access": "public" 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /themes/moon-light/README.md: -------------------------------------------------------------------------------- 1 | # FSOTM Theme - Boost 2 | 3 | [Far Side of the Moon](https://github.com/thierryc/far-side-of-the-moon-syntax) command line theme 4 | for Boost powered CLIs. Ideal for light terminals. 5 | 6 | ```bash 7 | yarn install @boost/theme-moon-light --dev 8 | ``` 9 | -------------------------------------------------------------------------------- /themes/moon-light/index.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @copyright 2020, Miles Johnson 3 | * @license https://opensource.org/licenses/MIT 4 | */ 5 | 6 | module.exports = { 7 | default: '#5b6775', 8 | failure: '#dd6f38', 9 | info: '#00b4cb;', 10 | inverted: '#ffffff', 11 | muted: '#a1a1a1', 12 | notice: '#a40699', 13 | success: '#5c9f50', 14 | warning: '#e8a72b', 15 | }; 16 | -------------------------------------------------------------------------------- /themes/moon-light/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@boost/theme-moon-light", 3 | "version": "2.1.1", 4 | "release": "1594765247526", 5 | "description": "Far Side of the Moon command line theme for Boost powered CLIs.", 6 | "keywords": [ 7 | "boost", 8 | "theme", 9 | "moon", 10 | "light", 11 | "far", 12 | "side" 13 | ], 14 | "main": "./index.js", 15 | "repository": "https://github.com/milesj/boost/tree/master/themes/moon-light", 16 | "license": "MIT", 17 | "publishConfig": { 18 | "access": "public" 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /themes/one-dark/README.md: -------------------------------------------------------------------------------- 1 | # One Dark Theme - Boost 2 | 3 | [One Dark](https://github.com/atom/atom/tree/master/packages/one-dark-ui) command line theme for 4 | Boost powered CLIs. Ideal for dark terminals. 5 | 6 | ```bash 7 | yarn install @boost/theme-one-dark --dev 8 | ``` 9 | -------------------------------------------------------------------------------- /themes/one-dark/index.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @copyright 2020, Miles Johnson 3 | * @license https://opensource.org/licenses/MIT 4 | */ 5 | 6 | module.exports = { 7 | default: '#dde1f6', 8 | failure: '#E06C75', 9 | info: '#6da8e5', 10 | inverted: '#313440', 11 | muted: '#ABB2BF', 12 | notice: '#bc7bd9', 13 | success: '#98C379', 14 | warning: '#D19A66', 15 | }; 16 | -------------------------------------------------------------------------------- /themes/one-dark/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@boost/theme-one-dark", 3 | "version": "2.1.1", 4 | "release": "1594765247526", 5 | "description": "One Dark command line theme for Boost powered CLIs.", 6 | "keywords": [ 7 | "boost", 8 | "theme", 9 | "one", 10 | "dark" 11 | ], 12 | "main": "./index.js", 13 | "repository": "https://github.com/milesj/boost/tree/master/themes/one-dark", 14 | "license": "MIT", 15 | "publishConfig": { 16 | "access": "public" 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /themes/one-light/README.md: -------------------------------------------------------------------------------- 1 | # One Light Theme - Boost 2 | 3 | [One Light](https://github.com/atom/atom/tree/master/packages/one-light-ui) command line theme for 4 | Boost powered CLIs. Ideal for light terminals. 5 | 6 | ```bash 7 | yarn install @boost/theme-one-light --dev 8 | ``` 9 | -------------------------------------------------------------------------------- /themes/one-light/index.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @copyright 2020, Miles Johnson 3 | * @license https://opensource.org/licenses/MIT 4 | */ 5 | 6 | module.exports = { 7 | default: '#373a42', 8 | failure: '#E45649', 9 | info: '#4c79ea', 10 | inverted: '#fafafa', 11 | muted: '#ABB2BF', 12 | notice: '#a045a7', 13 | success: '#50A14F', 14 | warning: '#986801', 15 | }; 16 | -------------------------------------------------------------------------------- /themes/one-light/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@boost/theme-one-light", 3 | "version": "2.1.1", 4 | "release": "1594765247526", 5 | "description": "One Light command line theme for Boost powered CLIs.", 6 | "keywords": [ 7 | "boost", 8 | "theme", 9 | "one", 10 | "light" 11 | ], 12 | "main": "./index.js", 13 | "repository": "https://github.com/milesj/boost/tree/master/themes/one-light", 14 | "license": "MIT", 15 | "publishConfig": { 16 | "access": "public" 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /themes/solarized/README.md: -------------------------------------------------------------------------------- 1 | # Solarized Theme - Boost 2 | 3 | [Solarized](http://ethanschoonover.com/solarized) command line theme for Boost powered CLIs. Ideal 4 | for dark terminals. 5 | 6 | ```bash 7 | yarn install @boost/theme-solarized --dev 8 | ``` 9 | -------------------------------------------------------------------------------- /themes/solarized/index.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @copyright 2020, Miles Johnson 3 | * @license https://opensource.org/licenses/MIT 4 | */ 5 | 6 | module.exports = { 7 | default: '#eee8d5', 8 | failure: '#dc322f', 9 | info: '#2aa198', 10 | inverted: '#002b36', 11 | muted: '#93a1a1', 12 | notice: '#d33682', 13 | success: '#859900', 14 | warning: '#b58900', 15 | }; 16 | -------------------------------------------------------------------------------- /themes/solarized/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@boost/theme-solarized", 3 | "version": "2.1.1", 4 | "release": "1594765247526", 5 | "description": "Solarized command line theme for Boost powered CLIs.", 6 | "keywords": [ 7 | "boost", 8 | "theme", 9 | "solarized" 10 | ], 11 | "main": "./index.js", 12 | "repository": "https://github.com/milesj/boost/tree/master/themes/solarized", 13 | "license": "MIT", 14 | "publishConfig": { 15 | "access": "public" 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /themes/test-private/index.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | default: 'private', 3 | failure: 'private', 4 | info: 'private', 5 | inverted: 'private', 6 | muted: 'private', 7 | notice: 'private', 8 | success: 'private', 9 | warning: 'private', 10 | }; 11 | -------------------------------------------------------------------------------- /themes/test-private/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@boost/theme-test-private", 3 | "version": "0.2.1", 4 | "main": "./index.js", 5 | "private": true 6 | } 7 | -------------------------------------------------------------------------------- /themes/test-public/index.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | default: 'public', 3 | failure: 'public', 4 | info: 'public', 5 | inverted: 'public', 6 | muted: 'public', 7 | notice: 'public', 8 | success: 'public', 9 | warning: 'public', 10 | }; 11 | -------------------------------------------------------------------------------- /themes/test-public/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "boost-theme-test-public", 3 | "version": "0.2.1", 4 | "main": "./index.js", 5 | "private": true 6 | } 7 | -------------------------------------------------------------------------------- /tsconfig.docs.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "./tsconfig.options.json", 3 | "compilerOptions": { 4 | "declarationDir": "dts", 5 | "outDir": "dts" 6 | }, 7 | "include": [ 8 | "packages/*/src/**/*", 9 | "packages/*/types/**/*", 10 | "types/**/*" 11 | ] 12 | } 13 | -------------------------------------------------------------------------------- /tsconfig.eslint.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "./tsconfig.options.json", 3 | "include": [ 4 | "packages/*/src/**/*", 5 | "packages/*/tests/**/*", 6 | "packages/*/types/**/*", 7 | "packages/cli/examples/**/*", 8 | "themes/*/src/**/*", 9 | "themes/*/tests/**/*", 10 | "themes/*/types/**/*", 11 | "website/src/**/*", 12 | "website/types/**/*", 13 | "tests/setup.ts", 14 | "types/**/*", 15 | "*.config.js", 16 | "*.config.ts" 17 | ] 18 | } 19 | -------------------------------------------------------------------------------- /tsconfig.options.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "tsconfig-moon/tsconfig.projects.json", 3 | "compilerOptions": { 4 | "experimentalDecorators": true, 5 | "module": "es2022", 6 | "moduleResolution": "bundler", 7 | "jsx": "react-jsx", 8 | "verbatimModuleSyntax": true, 9 | "resolvePackageJsonExports": true, 10 | "resolvePackageJsonImports": true, 11 | "customConditions": ["node", "default"], 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /types/global.d.ts: -------------------------------------------------------------------------------- 1 | /* eslint-disable @typescript-eslint/method-signature-style */ 2 | 3 | declare const __DEV__: boolean; 4 | declare const __PROD__: boolean; 5 | declare const __TEST__: boolean; 6 | 7 | declare function delay(time?: number): Promise; 8 | -------------------------------------------------------------------------------- /types/supports-hyperlinks.d.ts: -------------------------------------------------------------------------------- 1 | declare module 'supports-hyperlinks' { 2 | export default function supportsHyperlinks(): { stdout: boolean; stderr: boolean }; 3 | } 4 | -------------------------------------------------------------------------------- /types/vitest.d.ts: -------------------------------------------------------------------------------- 1 | import type { Assertion, AsymmetricMatchersContaining } from 'vitest' 2 | 3 | interface CustomMatchers { 4 | toBeFilePath(path: string): R 5 | } 6 | 7 | declare module 'vitest' { 8 | interface Assertion extends CustomMatchers {} 9 | interface AsymmetricMatchersContaining extends CustomMatchers {} 10 | } 11 | -------------------------------------------------------------------------------- /website/.eslintrc.cjs: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | rules: { 3 | 'import/no-unresolved': 'off', 4 | 'import/no-default-export': 'off', 5 | 'react/jsx-no-literals': 'off', 6 | }, 7 | }; 8 | -------------------------------------------------------------------------------- /website/.gitignore: -------------------------------------------------------------------------------- 1 | # Dependencies 2 | /node_modules 3 | 4 | # Production 5 | /build 6 | 7 | # Generated files 8 | .docusaurus 9 | .cache-loader 10 | 11 | # Misc 12 | .DS_Store 13 | .env.local 14 | .env.development.local 15 | .env.test.local 16 | .env.production.local 17 | 18 | npm-debug.log* 19 | yarn-debug.log* 20 | yarn-error.log* 21 | 22 | # Required for website 23 | !babel.config.js 24 | !tsconfig.json 25 | -------------------------------------------------------------------------------- /website/babel.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | presets: [require.resolve('@docusaurus/core/lib/babel/preset')], 3 | }; 4 | -------------------------------------------------------------------------------- /website/moon.yml: -------------------------------------------------------------------------------- 1 | type: 'application' 2 | 3 | workspace: 4 | inheritedTasks: 5 | include: ['format', 'lint', 'typecheck'] 6 | 7 | tasks: 8 | build: 9 | command: 'yarn run build' 10 | options: 11 | # Requires node 18 but our CI has 16 12 | allowFailure: true 13 | 14 | dev: 15 | command: 'yarn run start' 16 | local: true 17 | -------------------------------------------------------------------------------- /website/src/theme/Badge.tsx: -------------------------------------------------------------------------------- 1 | import { type ReactNode } from 'react'; 2 | 3 | export interface BadgeProps { 4 | children: ReactNode; 5 | type: string; 6 | } 7 | 8 | export default function Badge({ children, type }: BadgeProps) { 9 | return {children}; 10 | } 11 | -------------------------------------------------------------------------------- /website/src/theme/BadgeGroup.tsx: -------------------------------------------------------------------------------- 1 | import type { ReactNode } from 'react'; 2 | import styles from './styles.module.css'; 3 | 4 | export interface BadgeGroupProps { 5 | children: ReactNode; 6 | } 7 | 8 | export default function BadgeGroup({ children }: BadgeGroupProps) { 9 | return {children}; 10 | } 11 | -------------------------------------------------------------------------------- /website/src/theme/styles.module.css: -------------------------------------------------------------------------------- 1 | .badgeGroup { 2 | display: flex; 3 | margin-bottom: 1rem; 4 | } 5 | 6 | .badgeGroup > span { 7 | margin-right: 0.5rem; 8 | } 9 | 10 | .apiLink { 11 | float: right; 12 | } 13 | -------------------------------------------------------------------------------- /website/static/.nojekyll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/milesj/boost/868b258fac254aa4c2673755a9fd5acf89091980/website/static/.nojekyll -------------------------------------------------------------------------------- /website/static/CNAME: -------------------------------------------------------------------------------- 1 | boostlib.dev 2 | -------------------------------------------------------------------------------- /website/static/img/cli/command.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/milesj/boost/868b258fac254aa4c2673755a9fd5acf89091980/website/static/img/cli/command.png -------------------------------------------------------------------------------- /website/static/img/cli/options.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/milesj/boost/868b258fac254aa4c2673755a9fd5acf89091980/website/static/img/cli/options.png -------------------------------------------------------------------------------- /website/static/img/cli/params.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/milesj/boost/868b258fac254aa4c2673755a9fd5acf89091980/website/static/img/cli/params.png -------------------------------------------------------------------------------- /website/static/img/cli/program.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/milesj/boost/868b258fac254aa4c2673755a9fd5acf89091980/website/static/img/cli/program.png -------------------------------------------------------------------------------- /website/static/img/cli/prompts/confirm.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/milesj/boost/868b258fac254aa4c2673755a9fd5acf89091980/website/static/img/cli/prompts/confirm.gif -------------------------------------------------------------------------------- /website/static/img/cli/prompts/hidden-input.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/milesj/boost/868b258fac254aa4c2673755a9fd5acf89091980/website/static/img/cli/prompts/hidden-input.gif -------------------------------------------------------------------------------- /website/static/img/cli/prompts/input.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/milesj/boost/868b258fac254aa4c2673755a9fd5acf89091980/website/static/img/cli/prompts/input.gif -------------------------------------------------------------------------------- /website/static/img/cli/prompts/multiselect.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/milesj/boost/868b258fac254aa4c2673755a9fd5acf89091980/website/static/img/cli/prompts/multiselect.gif -------------------------------------------------------------------------------- /website/static/img/cli/prompts/password-input.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/milesj/boost/868b258fac254aa4c2673755a9fd5acf89091980/website/static/img/cli/prompts/password-input.gif -------------------------------------------------------------------------------- /website/static/img/cli/prompts/select-labels.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/milesj/boost/868b258fac254aa4c2673755a9fd5acf89091980/website/static/img/cli/prompts/select-labels.gif -------------------------------------------------------------------------------- /website/static/img/cli/prompts/select.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/milesj/boost/868b258fac254aa4c2673755a9fd5acf89091980/website/static/img/cli/prompts/select.gif -------------------------------------------------------------------------------- /website/static/img/cli/subcommands.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/milesj/boost/868b258fac254aa4c2673755a9fd5acf89091980/website/static/img/cli/subcommands.png -------------------------------------------------------------------------------- /website/static/img/cli/unknown-option.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/milesj/boost/868b258fac254aa4c2673755a9fd5acf89091980/website/static/img/cli/unknown-option.png -------------------------------------------------------------------------------- /website/static/img/cli/variadic-params.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/milesj/boost/868b258fac254aa4c2673755a9fd5acf89091980/website/static/img/cli/variadic-params.png -------------------------------------------------------------------------------- /website/static/img/logo-bg.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /website/static/img/logo.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /website/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../tsconfig.options.json", 3 | "compilerOptions": { 4 | "declarationDir": "dts", 5 | "outDir": "../.moon/cache/types/website", 6 | "rootDir": ".", 7 | "emitDeclarationOnly": true, 8 | "jsx": "react-jsx" 9 | }, 10 | "exclude": [ 11 | "dts" 12 | ], 13 | "include": [ 14 | "src/**/*", 15 | "types/**/*", 16 | "../types/**/*" 17 | ], 18 | "references": [] 19 | } 20 | -------------------------------------------------------------------------------- /website/types/docusaurus.d.ts: -------------------------------------------------------------------------------- 1 | /// 2 | -------------------------------------------------------------------------------- /website/types/global.d.ts: -------------------------------------------------------------------------------- 1 | declare module '*.module.css'; 2 | declare module '@docusaurus/*'; 3 | --------------------------------------------------------------------------------