e22m4u 3 дней назад
Родитель
Сommit
35cdb26682

+ 4 - 0
.mocharc.cjs

@@ -0,0 +1,4 @@
+module.exports = {
+  extension: ['js'],
+  spec: 'src/**/*.spec.js',
+}

+ 0 - 4
.mocharc.json

@@ -1,4 +0,0 @@
-{
-  "extension": ["js"],
-  "spec": "src/**/*.spec.js"
-}

+ 7 - 7
dist/cjs/index.cjs

@@ -71,17 +71,17 @@ function arrayToString(input) {
 __name(arrayToString, "arrayToString");
 
 // src/format.js
-function format(pattern, ...args) {
+function format(pattern) {
   if (pattern instanceof Date) {
     pattern = pattern.toISOString();
   } else if (typeof pattern !== "string") {
     pattern = String(pattern);
   }
   const re = /(%?)(%([sdjvl]))/g;
-  const argsQueue = [...args];
-  if (argsQueue.length) {
+  const args = Array.prototype.slice.call(arguments, 1);
+  if (args.length) {
     pattern = pattern.replace(re, function(match, escaped, ptn, flag) {
-      let arg = argsQueue.shift();
+      let arg = args.shift();
       switch (flag) {
         case "s":
           arg = String(arg);
@@ -100,11 +100,11 @@ function format(pattern, ...args) {
           break;
       }
       if (!escaped) return arg;
-      argsQueue.unshift(arg);
+      args.unshift(arg);
       return match;
     });
   }
-  if (argsQueue.length) pattern += " " + argsQueue.join(" ");
+  if (args.length) pattern += " " + args.join(" ");
   pattern = pattern.replace(/%{2}/g, "%");
   return "" + pattern;
 }
@@ -116,7 +116,7 @@ var _Errorf = class _Errorf extends Error {
    * Constructor.
    *
    * @param {string|undefined} pattern
-   * @param {*} args
+   * @param {any} args
    */
   constructor(pattern = void 0, ...args) {
     const message = pattern != null ? format(pattern, ...args) : void 0;

+ 0 - 13
eslint.config.js

@@ -1,8 +1,6 @@
 import globals from 'globals';
 import eslintJs from '@eslint/js';
-import eslintJsdocPlugin from 'eslint-plugin-jsdoc';
 import eslintMochaPlugin from 'eslint-plugin-mocha';
-import eslintImportPlugin from 'eslint-plugin-import';
 import eslintPrettierConfig from 'eslint-config-prettier';
 import eslintChaiExpectPlugin from 'eslint-plugin-chai-expect';
 
@@ -15,25 +13,14 @@ export default [{
     },
   },
   plugins: {
-    'jsdoc': eslintJsdocPlugin,
     'mocha': eslintMochaPlugin,
-    'import': eslintImportPlugin,
     'chai-expect': eslintChaiExpectPlugin,
   },
   rules: {
     ...eslintJs.configs.recommended.rules,
     ...eslintPrettierConfig.rules,
-    ...eslintImportPlugin.flatConfigs.recommended.rules,
     ...eslintMochaPlugin.configs.recommended.rules,
     ...eslintChaiExpectPlugin.configs['recommended-flat'].rules,
-    ...eslintJsdocPlugin.configs['flat/recommended-error'].rules,
-    'no-duplicate-imports': 'error',
-    'jsdoc/reject-any-type': 0,
-    'jsdoc/reject-function-type': 0,
-    'jsdoc/require-param-description': 0,
-    'jsdoc/require-returns-description': 0,
-    'jsdoc/require-property-description': 0,
-    'jsdoc/tag-lines': ['error', 'any', {startLines: 1}],
   },
   files: ['src/**/*.js'],
 }];

+ 11 - 10
package.json

@@ -1,6 +1,6 @@
 {
   "name": "@e22m4u/js-format",
-  "version": "0.3.0",
+  "version": "0.2.1",
   "description": "Утилита интерполяции строк для JavaScript",
   "author": "Mikhail Evstropov <e22m4u@yandex.ru>",
   "license": "MIT",
@@ -9,15 +9,17 @@
     "format",
     "error"
   ],
-  "homepage": "https://gitrepos.ru/e22m4u/js-format",
+  "homepage": "https://github.com/e22m4u/js-format",
   "repository": {
     "type": "git",
-    "url": "git+https://gitrepos.ru/e22m4u/js-format.git"
+    "url": "git+https://github.com/e22m4u/js-format.git"
   },
   "type": "module",
+  "types": "./src/index.d.ts",
   "module": "./src/index.js",
   "main": "./dist/cjs/index.cjs",
   "exports": {
+    "types": "./src/index.d.ts",
     "import": "./src/index.js",
     "require": "./dist/cjs/index.cjs"
   },
@@ -25,12 +27,12 @@
     "node": ">=12"
   },
   "scripts": {
-    "lint": "eslint ./src",
-    "lint:fix": "eslint ./src --fix",
+    "lint": "tsc && eslint ./src",
+    "lint:fix": "tsc && eslint ./src --fix",
     "format": "prettier --write \"./src/**/*.js\"",
     "test": "npm run lint && c8 --reporter=text-summary mocha",
     "test:coverage": "npm run lint && c8 --reporter=text mocha",
-    "build:cjs": "rimraf ./dist/cjs && node build-cjs.js",
+    "build:cjs": "rimraf ./dist/cjs && node --no-warnings=ExperimentalWarning build-cjs.js",
     "prepare": "husky"
   },
   "devDependencies": {
@@ -43,13 +45,12 @@
     "eslint": "~9.39.1",
     "eslint-config-prettier": "~10.1.8",
     "eslint-plugin-chai-expect": "~3.1.0",
-    "eslint-plugin-import": "~2.32.0",
-    "eslint-plugin-jsdoc": "~61.4.1",
     "eslint-plugin-mocha": "~11.2.0",
     "globals": "~16.5.0",
     "husky": "~9.1.7",
     "mocha": "~11.7.5",
-    "prettier": "~3.7.3",
-    "rimraf": "~6.1.2"
+    "prettier": "~3.7.2",
+    "rimraf": "~6.1.2",
+    "typescript": "~5.9.3"
   }
 }

+ 6 - 0
src/array-to-string.d.ts

@@ -0,0 +1,6 @@
+/**
+ * Array to string.
+ *
+ * @param input
+ */
+export declare function arrayToString(input: any): string;

+ 2 - 2
src/array-to-string.js

@@ -10,8 +10,8 @@ const SEPARATOR = ', ';
 /**
  * Array to string.
  *
- * @param {*} input
- * @returns {string}
+ * @param {any} input
+ * @return {string}
  */
 export function arrayToString(input) {
   if (Array.isArray(input) && input.length)

+ 0 - 2
src/array-to-string.spec.js

@@ -85,7 +85,6 @@ describe('arrayToString', function () {
     });
 
     it('returns a string representation of the given named function', function () {
-      // eslint-disable-next-line jsdoc/require-jsdoc
       function foo() {}
       const res = arrayToString(foo);
       expect(res).to.be.eq('Function');
@@ -222,7 +221,6 @@ describe('arrayToString', function () {
     });
 
     it('returns an element representation of the given named function', function () {
-      // eslint-disable-next-line jsdoc/require-jsdoc
       function foo() {}
       const res = arrayToString([foo]);
       expect(res).to.be.eq('Function');

+ 12 - 0
src/errorf.d.ts

@@ -0,0 +1,12 @@
+/**
+ * Errorf.
+ */
+export declare class Errorf extends Error {
+  /**
+   * Constructor.
+   *
+   * @param pattern
+   * @param args
+   */
+  constructor(pattern: string, ...args: any[]);
+}

+ 1 - 1
src/errorf.js

@@ -8,7 +8,7 @@ export class Errorf extends Error {
    * Constructor.
    *
    * @param {string|undefined} pattern
-   * @param {*} args
+   * @param {any} args
    */
   constructor(pattern = undefined, ...args) {
     const message = pattern != null ? format(pattern, ...args) : undefined;

+ 16 - 0
src/format.d.ts

@@ -0,0 +1,16 @@
+/**
+ * Format.
+ *
+ * native:
+ * s - string
+ * d - digits
+ * j - json
+ *
+ * extras:
+ * v - value (valueToString.js)
+ * l - list (arrayToString.js)
+ *
+ * @param pattern
+ * @param args
+ */
+export declare function format(pattern: string, ...args: any[]): string;

+ 9 - 10
src/format.js

@@ -13,21 +13,20 @@ import {valueToString} from './value-to-string.js';
  * v - value (valueToString.js)
  * l - list (arrayToString.js)
  *
- * @param {*} pattern
- * @param {...*} args
- * @returns {string}
+ * @param {string} pattern
+ * @return {string}
  */
-export function format(pattern, ...args) {
+export function format(pattern) {
   if (pattern instanceof Date) {
     pattern = pattern.toISOString();
   } else if (typeof pattern !== 'string') {
     pattern = String(pattern);
   }
   const re = /(%?)(%([sdjvl]))/g;
-  const argsQueue = [...args];
-  if (argsQueue.length) {
+  const args = Array.prototype.slice.call(arguments, 1);
+  if (args.length) {
     pattern = pattern.replace(re, function (match, escaped, ptn, flag) {
-      let arg = argsQueue.shift();
+      let arg = args.shift();
       switch (flag) {
         case 's':
           arg = String(arg);
@@ -46,12 +45,12 @@ export function format(pattern, ...args) {
           break;
       }
       if (!escaped) return arg;
-      argsQueue.unshift(arg);
+      args.unshift(arg);
       return match;
     });
   }
-  // has arguments after interpolation
-  if (argsQueue.length) pattern += ' ' + argsQueue.join(' ');
+  // arguments remain after formatting
+  if (args.length) pattern += ' ' + args.join(' ');
   // update escaped %% values
   pattern = pattern.replace(/%{2}/g, '%');
   return '' + pattern;

+ 0 - 7
src/format.spec.js

@@ -91,7 +91,6 @@ describe('format', function () {
     });
 
     it('converts the given pattern of a named function to a string', function () {
-      // eslint-disable-next-line jsdoc/require-jsdoc
       function foo() {}
       const res = format(foo);
       expect(res).to.be.eq('function foo() {}');
@@ -239,7 +238,6 @@ describe('format', function () {
     });
 
     it('returns a string representation of the given named function', function () {
-      // eslint-disable-next-line jsdoc/require-jsdoc
       function foo() {}
       const res = format('%s', foo);
       expect(res).to.be.eq('function foo() {}');
@@ -372,7 +370,6 @@ describe('format', function () {
     });
 
     it('returns a string representation of the given named function', function () {
-      // eslint-disable-next-line jsdoc/require-jsdoc
       function foo() {}
       const res = format('%d', foo);
       expect(res).to.be.eq('NaN');
@@ -495,7 +492,6 @@ describe('format', function () {
     });
 
     it('returns a string representation of the given named function', function () {
-      // eslint-disable-next-line jsdoc/require-jsdoc
       function foo() {}
       const res = format('%j', foo);
       expect(res).to.be.eq('undefined');
@@ -632,7 +628,6 @@ describe('format', function () {
     });
 
     it('returns a string representation of the given named function', function () {
-      // eslint-disable-next-line jsdoc/require-jsdoc
       function foo() {}
       const res = format('%v', foo);
       expect(res).to.be.eq('Function');
@@ -760,7 +755,6 @@ describe('format', function () {
       });
 
       it('returns a string representation of the given named function', function () {
-        // eslint-disable-next-line jsdoc/require-jsdoc
         function foo() {}
         const res = format('%l', foo);
         expect(res).to.be.eq('Function');
@@ -897,7 +891,6 @@ describe('format', function () {
       });
 
       it('returns an element representation of the given named function', function () {
-        // eslint-disable-next-line jsdoc/require-jsdoc
         function foo() {}
         const res = format('%l', [foo]);
         expect(res).to.be.eq('Function');

+ 5 - 0
src/index.d.ts

@@ -0,0 +1,5 @@
+export * from './format.js';
+export * from './errorf.js';
+export * from './array-to-string.js';
+export * from './value-to-string.js';
+export * from './invalid-argument-error.js';

+ 6 - 0
src/invalid-argument-error.d.ts

@@ -0,0 +1,6 @@
+import {Errorf} from './errorf.js';
+
+/**
+ * Invalid argument error.
+ */
+export declare class InvalidArgumentError extends Errorf {}

+ 1 - 0
src/utils/index.d.ts

@@ -0,0 +1 @@
+export * from './is-class.js';

+ 7 - 0
src/utils/is-class.d.ts

@@ -0,0 +1,7 @@
+/**
+ * Returns true if the given value is ES6 class.
+ *
+ * @param {*} value
+ * @returns {boolean}
+ */
+export declare function isClass(value: unknown): boolean;

+ 6 - 0
src/value-to-string.d.ts

@@ -0,0 +1,6 @@
+/**
+ * Value to string.
+ *
+ * @param input
+ */
+export declare function valueToString(input: any): string;

+ 2 - 2
src/value-to-string.js

@@ -16,8 +16,8 @@ const BASE_CTOR_NAMES = [
 /**
  * Value to string.
  *
- * @param {*} input
- * @returns {string}
+ * @param {any} input
+ * @return {string}
  */
 export function valueToString(input) {
   if (input == null) return String(input);

+ 0 - 1
src/value-to-string.spec.js

@@ -94,7 +94,6 @@ describe('valueToString', function () {
   });
 
   it('returns a string representation of the given named function', function () {
-    // eslint-disable-next-line jsdoc/require-jsdoc
     function foo() {}
     const res = valueToString(foo);
     expect(res).to.be.eq('Function');

+ 2 - 0
jsconfig.json → tsconfig.json

@@ -1,5 +1,7 @@
 {
   "compilerOptions": {
+    "rootDir": "src",
+    "noEmit": true,
     "target": "es2022",
     "module": "NodeNext",
     "moduleResolution": "NodeNext"