diff --git a/.github/workflows/npm-publish.yml b/.github/workflows/npm-publish.yml index 5aa5a3e..637012e 100644 --- a/.github/workflows/npm-publish.yml +++ b/.github/workflows/npm-publish.yml @@ -34,6 +34,7 @@ jobs: with: name: build-artifact path: build/ + include-hidden-files: true retention-days: 1 publish: @@ -53,4 +54,5 @@ jobs: with: name: build-artifact path: build/ + include-hidden-files: true - run: cd build && npm publish --access public --tag alpha --provenance diff --git a/.gitignore b/.gitignore index bb6c927..994cf5b 100644 --- a/.gitignore +++ b/.gitignore @@ -1,7 +1,7 @@ node_modules/ coverage/ build/ -package-lock.json .DS_Store AGY.md AYG.md +package-lock.json diff --git a/jest.config.ts b/jest.config.ts index c9d6e5b..f036630 100644 --- a/jest.config.ts +++ b/jest.config.ts @@ -1,6 +1,6 @@ -import { execSync } from "child_process"; -import path from "path"; -import fs from "fs"; +import { execSync } from "node:child_process"; +import path from 'node:path'; +import fs from 'node:fs'; let tsJestPath = "ts-jest"; try { @@ -21,11 +21,16 @@ export default { "**/test/**/*.test.ts", "**/test/**/*.test.js" ], + "modulePathIgnorePatterns": [ + "/build/" + ], "transform": { "^.+\\.ts$": [ tsJestPath, { - "tsconfig": "/tsconfig.json" + "tsconfig": "/tsconfig.json", + "isolatedModules": true, + "diagnostics": false } ] }, diff --git a/package.json b/package.json index c20c3c3..a4aa5b8 100644 --- a/package.json +++ b/package.json @@ -1,31 +1,29 @@ { "name": "@ostro/console", - "version": "2.0.0-alpha.2", + "version": "2.0.0-alpha.3", "description": "Command module for OstroJS", - "main": "build/application.js", - "types": "build/types/application.d.ts", - "files": [ - "build" - ], + "main": "application.js", + "types": ".typed/application.d.ts", "exports": { ".": { - "types": "./build/types/application.d.ts", - "default": "./build/application.js" + "types": "./.typed/application.d.ts", + "default": "./application.js" }, "./*": { - "types": "./build/types/*.d.ts", - "default": "./build/*.js" + "types": "./.typed/*.d.ts", + "default": "./*.js" } }, "scripts": { - "build": "npx tsc -p tsconfig.build.json && node scripts/build.js", + "build": "npm run lint:check && rm -rf build && ostro-build --prepare", "prepublishOnly": "npm run build", - "test": "npx c8 npx jest", - "clean": "rm -rf build coverage" + "test": "jest", + "clean": "rm -rf build coverage", + "lint:check": "tsc --noEmit" }, "dependencies": { - "@ostro/contracts": "^2.0.0-alpha.2", - "@ostro/support": "^2.0.0-alpha.2", + "@ostro/contracts": "^2.0.0-alpha.3", + "@ostro/support": "^2.0.0-alpha.3", "commander": "^8.3.0", "lodash": "^4.17.21", "string-argv": "^0.3.2" @@ -50,13 +48,14 @@ }, "homepage": "https://github.com/ostrojs/console#readme", "devDependencies": { - "@types/node": "^22.0.0", - "typescript": "^5.8.0", + "@ostro/builder": "^2.0.0-alpha.1", "@types/jest": "^30.0.0", + "@types/node": "^22.0.0", "c8": "^10.1.3", "jest": "^30.5.2", "ts-jest": "^29.4.15", - "ts-node": "^10.9.2" + "ts-node": "^10.9.2", + "typescript": "^5.8.0" }, "overrides": { "sprintf-js": "^1.1.3", diff --git a/scripts/build.js b/scripts/build.js deleted file mode 100644 index 3937795..0000000 --- a/scripts/build.js +++ /dev/null @@ -1,94 +0,0 @@ -const fs = require('fs'); -const path = require('path'); - -function preparePackage(pkgDir = process.cwd()) { - const rootPkgPath = path.join(pkgDir, 'package.json'); - if (!fs.existsSync(rootPkgPath)) { - console.error('No package.json found in ' + pkgDir); - process.exit(1); - } - - const rootPkg = JSON.parse(fs.readFileSync(rootPkgPath, 'utf8')); - const buildDir = path.join(pkgDir, 'build'); - - if (!fs.existsSync(buildDir)) { - console.error('Build directory does not exist: ' + buildDir); - process.exit(1); - } - - const pubPkg = { ...rootPkg }; - - delete pubPkg.devDependencies; - delete pubPkg.scripts; - delete pubPkg.files; - - const stripBuild = (str) => { - if (!str || typeof str !== 'string') return str; - return str.replace(/^(\.\/)?build\//, './'); - }; - - if (pubPkg.main) pubPkg.main = stripBuild(pubPkg.main).replace(/^\.\//, ''); - if (pubPkg.types) pubPkg.types = stripBuild(pubPkg.types).replace(/^\.\//, ''); - if (pubPkg.bin) { - if (typeof pubPkg.bin === 'string') { - pubPkg.bin = stripBuild(pubPkg.bin).replace(/^\.\//, ""); - } else if (typeof pubPkg.bin === 'object') { - const newBin = {}; - for (const [k, v] of Object.entries(pubPkg.bin)) { - newBin[k] = stripBuild(v).replace(/^\.\//, ""); - } - pubPkg.bin = newBin; - } - } - - if (pubPkg.exports) { - const rewriteExports = (obj) => { - if (typeof obj === 'string') return stripBuild(obj); - if (Array.isArray(obj)) return obj.map(rewriteExports); - if (typeof obj === "object" && obj !== null) { - const res = {}; - for (const [k, v] of Object.entries(obj)) { - res[k] = rewriteExports(v); - } - return res; - } - return obj; - }; - pubPkg.exports = rewriteExports(pubPkg.exports); - } - - fs.writeFileSync(path.join(buildDir, 'package.json'), JSON.stringify(pubPkg, null, 2) + '\n'); - - function patchDualExports(dir) { - const files = fs.readdirSync(dir, { withFileTypes: true }); - for (const f of files) { - const fullPath = path.join(dir, f.name); - if (f.isDirectory()) { - patchDualExports(fullPath); - } else if (f.name.endsWith('.js') && !f.name.endsWith('.d.ts')) { - let content = fs.readFileSync(fullPath, 'utf8'); - if (content.includes('exports.default =') && !content.includes('module.exports = exports.default')) { - content += '\nif (exports.default) {\n const d = exports.default;\n module.exports = d;\n Object.assign(module.exports, exports);\n module.exports.default = d;\n}\n'; - fs.writeFileSync(fullPath, content, 'utf8'); - } - } - } - } - patchDualExports(buildDir); - - - const copyIfExists = (file) => { - const src = path.join(pkgDir, file); - if (fs.existsSync(src)) { - fs.copyFileSync(src, path.join(buildDir, file)); - } - }; - - copyIfExists('README.md'); - copyIfExists('LICENSE.md'); - copyIfExists('LICENSE'); - - console.log(`[build] Successfully prepared ${pubPkg.name}@${pubPkg.version} inside build/`); -} - -preparePackage(); diff --git a/src/application.ts b/src/application.ts index 82f4702..35f1212 100644 --- a/src/application.ts +++ b/src/application.ts @@ -1,5 +1,5 @@ import { parseArgsStringToArgv } from 'string-argv'; -import commander from 'commander'; +import { program } from 'commander'; import InputHandler from './inputHandler'; import OutputHandler from './outputHandler'; import Command from './command'; @@ -23,8 +23,8 @@ class Application { constructor($app?: any) { this.$app = $app; this.setAutoExit(0); - (commander as any).exitOverride(()=>{}); - (commander as any).showSuggestionAfterError(true); + program.exitOverride(() => { }); + program.showSuggestionAfterError(true); this.bootstrap(); } @@ -52,7 +52,7 @@ class Application { * @returns {any} */ public run($input: any[] = []) { - return (commander as any).parseAsync($input, { + return program.parseAsync($input, { from: 'user' }) @@ -111,7 +111,7 @@ class Application { * @returns {any} */ public callCommand(...args: any[]) { - return (this.call as any)(...args) + return (this.call as (...a: unknown[]) => unknown)(...args) } /** @@ -234,7 +234,7 @@ class Application { this.$commands.push(command.$signature); let options = command.$options || []; let commandArguments = command.$arguments || []; - let cmd = (commander as any).command(command.$signature); + let cmd = program.command(command.$signature); cmd.description(command.$description); @@ -266,10 +266,9 @@ class Application { let newCommand = Object.create(command); - command.input = new InputHandler(args, opts); - command.output = new OutputHandler(); + newCommand.input = new InputHandler(args, opts); + newCommand.output = new OutputHandler(); return newCommand.handle() - }) } } diff --git a/src/argument.ts b/src/argument.ts index c7bdf7d..7c2ad22 100644 --- a/src/argument.ts +++ b/src/argument.ts @@ -22,7 +22,7 @@ class Argument { * @returns The argument instance. */ public choices(values: readonly string[]): this { - this.$handler.choices(values as any); + this.$handler.choices(values as string[]); return this; } diff --git a/src/command.ts b/src/command.ts index 9ad1b12..ed06dfa 100644 --- a/src/command.ts +++ b/src/command.ts @@ -43,20 +43,53 @@ class Command extends implement(CommandContracts, Interaction, CallCommands, Has Object.defineProperty(this, '$arguments', { value: val, writable: true, configurable: true }); } + /** + * Determine if the application is using TypeScript. + * + * @returns {boolean} + */ + public isTypeScript(): boolean { + if (!this.$app) { + return false; + } + try { + if (this.$app['config']) { + const configVal = typeof this.$app['config'].get === 'function' ? + this.$app['config'].get('app.typescript') : + this.$app['config']['app.typescript']; + if (typeof configVal === 'boolean') { + return configVal; + } + } + } catch (_) {} + + if (typeof this.$app.basePath !== 'function') { + return false; + } + try { + const fs = require('node:fs'); + return fs.existsSync(this.$app.basePath('tsconfig.json')) || + fs.existsSync(this.$app.basePath('tsconfig.build.json')) || + fs.existsSync(this.$app.basePath('app.ts')); + } catch { + return false; + } + } + /** * createArgument method. * @returns {any} */ - public createArgument(...args: any[]) { - return new (Argument as any)(...args) + public createArgument(name: string, description?: string) { + return new Argument(name, description); } /** * createOption method. * @returns {any} */ - public createOption(...args: any[]) { - return new (Option as any)(...args) + public createOption(flags: string, description?: string) { + return new Option(flags, description); } /** diff --git a/src/concerns/callsCommands.ts b/src/concerns/callsCommands.ts index d2e3b11..1811416 100644 --- a/src/concerns/callsCommands.ts +++ b/src/concerns/callsCommands.ts @@ -3,7 +3,10 @@ */ class CallsCommands { public declare output: any; - public declare getConsole: any; + + public getConsole(): any { + return null; + } /** * callCommand method. @@ -20,7 +23,7 @@ class CallsCommands { * @returns {any} */ public call(...args: any[]) { - return (this.callCommand as any)(...args) + return (this.callCommand as (...a: unknown[]) => unknown)(...args) } /** diff --git a/src/concerns/hasParameters.ts b/src/concerns/hasParameters.ts index 10cfa19..e2295e9 100644 --- a/src/concerns/hasParameters.ts +++ b/src/concerns/hasParameters.ts @@ -19,7 +19,7 @@ class HasParameters { if (typeof InputArgument !== 'undefined' && $arguments instanceof InputArgument) { this.getDefinition().addArgument($arguments); } else { - this.addArgument(...Object.values($arguments as any)); + this.addArgument(...Object.values($arguments as Record)); } } @@ -27,7 +27,7 @@ class HasParameters { if (typeof InputOption !== 'undefined' && $options instanceof InputOption) { this.getDefinition().addOption($options); } else { - this.addOption(...Object.values($options as any)); + this.addOption(...Object.values($options as Record)); } } } diff --git a/src/concerns/intraction.ts b/src/concerns/intraction.ts index 3b2ec50..eb87b75 100644 --- a/src/concerns/intraction.ts +++ b/src/concerns/intraction.ts @@ -1,6 +1,7 @@ import OutputFormatterStyle from '../outputFormatterStyle'; import OutputInterface from '../outputInterface'; import CollectionInterface from '@ostro/contracts/collection/collect'; +import type { ICollection } from '@ostro/contracts/collection/collect'; import Table from '../helpers/table'; import { isset } from '@ostro/support/function'; @@ -127,8 +128,8 @@ class Interaction { public table($headers: Record, $rows: any, $tableStyle: string = 'default', $columnStyles: any[] = []) { let $table = new Table(this.output); - if ($rows instanceof CollectionInterface) { - $rows = ($rows as any).toArray(); + if ($rows instanceof CollectionInterface || (typeof ($rows as ICollection)?.toArray === 'function')) { + $rows = ($rows as ICollection).toArray(); } $table.setHeaders($headers).setRows($rows).setStyle($tableStyle); diff --git a/src/generatorCommand.ts b/src/generatorCommand.ts index ad7c889..17b997e 100644 --- a/src/generatorCommand.ts +++ b/src/generatorCommand.ts @@ -1,7 +1,7 @@ import Command from './command'; import { rtrim, trim, ltrim } from '@ostro/support/function'; import * as StringHelper from '@ostro/support/string'; -import path, { dirname } from 'path'; +import path, { dirname } from 'node:path'; declare const isDirectory: any; declare const app_path: any; @@ -184,11 +184,29 @@ class GeneratorCommand extends Command { * @returns {boolean} */ public isTypeScript(): boolean { - if (!this.$app || typeof this.$app.basePath !== 'function') { + if (!this.$app) { return false; } try { - const fs = require('fs'); + if (this.$app['config']) { + const configVal = typeof this.$app['config'].get === 'function' ? + this.$app['config'].get('app.typescript') : + this.$app['config']['app.typescript']; + if (typeof configVal === 'boolean') { + return configVal; + } + } + } catch (_) {} + + if (typeof super.isTypeScript === 'function') { + return super.isTypeScript(); + } + + if (typeof this.$app.basePath !== 'function') { + return false; + } + try { + const fs = require('node:fs'); return fs.existsSync(this.$app.basePath('tsconfig.json')) || fs.existsSync(this.$app.basePath('tsconfig.build.json')) || fs.existsSync(this.$app.basePath('app.ts')); diff --git a/src/helpers/table.ts b/src/helpers/table.ts index 7217ed8..ae62b71 100644 --- a/src/helpers/table.ts +++ b/src/helpers/table.ts @@ -1,17 +1,12 @@ -const kHeaders: unique symbol = Symbol('headers'); -const kRows: unique symbol = Symbol('row'); -const kStyle: unique symbol = Symbol('style'); -const kColumStyle: unique symbol = Symbol('columnStyle'); - /** * Class Table. */ class Table { public output: unknown; - public [kHeaders]: any[] = []; - public [kRows]: any[][] = []; - public [kStyle]: unknown; - public [kColumStyle]: unknown; + #headers: any[] = []; + #rows: any[][] = []; + #style: unknown; + #columnStyle: unknown; /** * Create a new instance. @@ -27,7 +22,7 @@ class Table { * @returns The table instance. */ public setHeaders(headers: any): this { - this[kHeaders] = headers; + this.#headers = headers; return this; } @@ -37,7 +32,7 @@ class Table { * @returns The table instance. */ public setRows(rows: any[][]): this { - this[kRows] = rows; + this.#rows = rows; return this; } @@ -47,7 +42,7 @@ class Table { * @returns The table instance. */ public setStyle(style: unknown): this { - this[kStyle] = style; + this.#style = style; return this; } @@ -58,7 +53,7 @@ class Table { * @returns The table instance. */ public setColumnStyle(columnIndex: unknown, style?: unknown): this { - this[kColumStyle] = style !== undefined ? { [columnIndex as string]: style } : columnIndex; + this.#columnStyle = style !== undefined ? { [columnIndex as string]: style } : columnIndex; return this; } @@ -67,9 +62,9 @@ class Table { */ public render(): void { const datas: Record[] = []; - for (const row of this[kRows]) { + for (const row of this.#rows) { const data: Record = {}; - this[kHeaders].forEach((header: string, i: number) => { + this.#headers.forEach((header: string, i: number) => { let message: unknown = row[i]; if (typeof message === 'string') { message = message.replace(/<.*>(.*)<\/.*>/g, '$1'); diff --git a/src/option.ts b/src/option.ts index 2fd6bf3..d436aa6 100644 --- a/src/option.ts +++ b/src/option.ts @@ -42,7 +42,7 @@ class Option { * @returns The option instance. */ public choices(values: readonly string[]): this { - this.$handler.choices(values as any); + this.$handler.choices(values as string[]); return this; } diff --git a/src/outputHandler.ts b/src/outputHandler.ts index cc04196..e2225db 100644 --- a/src/outputHandler.ts +++ b/src/outputHandler.ts @@ -1,4 +1,4 @@ -import readline from 'readline'; +import readline from 'node:readline'; import OutputFormatter from './outputFormatter'; import OutputInterface from './outputInterface'; diff --git a/test/application.test.ts b/test/application.test.ts index 96b4030..5489c78 100644 --- a/test/application.test.ts +++ b/test/application.test.ts @@ -1,3 +1,4 @@ +import { describe, test, expect } from "@jest/globals"; const _Application = require('../src/application'); const Application = _Application.default || _Application; const _Command = require('../src/command'); diff --git a/test/argumentOption.test.ts b/test/argumentOption.test.ts index ce0252f..89eca45 100644 --- a/test/argumentOption.test.ts +++ b/test/argumentOption.test.ts @@ -1,3 +1,4 @@ +import { describe, test, expect } from "@jest/globals"; const _Argument = require('../src/argument'); const Argument = _Argument.default || _Argument; const _Option = require('../src/option'); diff --git a/test/color.test.ts b/test/color.test.ts index 47f5051..0c5106e 100644 --- a/test/color.test.ts +++ b/test/color.test.ts @@ -1,3 +1,4 @@ +import { describe, test, expect } from "@jest/globals"; const _Color = require('../src/color'); const Color = _Color.default || _Color; diff --git a/test/command.test.ts b/test/command.test.ts index 053f460..121c24a 100644 --- a/test/command.test.ts +++ b/test/command.test.ts @@ -1,3 +1,4 @@ +import { describe, test, expect, jest } from "@jest/globals"; const _Command = require('../src/command'); const Command = _Command.default || _Command; diff --git a/test/outputFormatter.test.ts b/test/outputFormatter.test.ts index 700065b..2f3fe5e 100644 --- a/test/outputFormatter.test.ts +++ b/test/outputFormatter.test.ts @@ -1,3 +1,4 @@ +import { describe, test, expect } from "@jest/globals"; const _OutputFormatterStyle = require('../src/outputFormatterStyle'); const OutputFormatterStyle = _OutputFormatterStyle.default || _OutputFormatterStyle; const _OutputFormatterStyleStack = require('../src/outputFormatterStyleStack'); diff --git a/tsconfig.build.json b/tsconfig.build.json deleted file mode 100644 index 8a1d9a0..0000000 --- a/tsconfig.build.json +++ /dev/null @@ -1,33 +0,0 @@ -{ - "compilerOptions": { - "target": "ES2022", - "module": "NodeNext", - "moduleResolution": "NodeNext", - "declaration": true, - "declarationMap": true, - "sourceMap": true, - "outDir": "./build", - "rootDir": "src", - "skipLibCheck": true, - "noImplicitAny": false, - "strict": false, - "types": [ - "node" - ], - "typeRoots": [ - "./node_modules/@types", - "../node_modules/@types", - "../../node_modules/@types" - ], - "declarationDir": "./build/types" - }, - "include": [ - "src/**/*.ts" - ], - "exclude": [ - "node_modules", - "test", - "coverage", - "build" - ] -} diff --git a/tsconfig.json b/tsconfig.json index fec2da8..f9f1895 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -1,14 +1,45 @@ { - "compilerOptions": { - "target": "ES2022", - "module": "NodeNext", - "moduleResolution": "NodeNext", - "isolatedModules": true, - "rootDir": ".", - "skipLibCheck": true, - "esModuleInterop": true - }, - "include": [ - "**/*" - ] + "compilerOptions": { + "target": "ESNext", + "module": "NodeNext", + "moduleResolution": "NodeNext", + "declaration": true, + "declarationMap": true, + "sourceMap": true, + "outDir": "./build", + "rootDir": "src", + "skipLibCheck": true, + "noImplicitAny": false, + "strict": false, + "types": [ + "node" + ], + "typeRoots": [ + "./node_modules/@types" + ], + "declarationDir": "./build/.typed", + "esModuleInterop": true + }, + "include": [ + "src/**/*.ts" + ], + "exclude": [ + "node_modules", + "test", + "coverage", + "build", + "**/stubs/**", + "**/stub/**", + "**/*.stub", + "**/template/**" + ], + "assets": { + "include": [ + "src/**/stub/**/*", + "src/**/stubs/**/*", + "src/**/*.stub", + "src/**/template/**/*" + ], + "exclude": [] + } }