diff --git a/.npmignore b/.npmignore new file mode 100644 index 0000000..60f1a29 --- /dev/null +++ b/.npmignore @@ -0,0 +1,12 @@ +# This file is written to be a whitelist instead of a blacklist. Start by +# ignoring everything, then add back the files we want to be included in the +# final NPM package. +* + +# And these are the files that are allowed. +!/README.md +!/LICENSE.md +!/README_EN.md +!/package.json +!/cjs/**/* +!/esm/**/* \ No newline at end of file diff --git a/package-lock.json b/package-lock.json index 886b7b8..d0916ef 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,18 +1,21 @@ { "name": "redocmx", - "version": "0.0.6", + "version": "0.0.7", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "redocmx", - "version": "0.0.6", + "version": "0.0.7", "license": "MIT", "devDependencies": { "@rollup/plugin-commonjs": "^26.0.1", "@rollup/plugin-node-resolve": "^15.2.3", + "@types/node": ">=8.1.0", "rollup": "^2.79.1", - "rollup-plugin-terser": "^7.0.2" + "rollup-plugin-terser": "^7.0.2", + "ts-node": "^10.9.2", + "typescript": "^5.5.3" }, "engines": { "node": ">= 18.0.0" @@ -55,6 +58,28 @@ "node": ">=6.9.0" } }, + "node_modules/@cspotcode/source-map-support": { + "version": "0.8.1", + "resolved": "https://registry.npmjs.org/@cspotcode/source-map-support/-/source-map-support-0.8.1.tgz", + "integrity": "sha512-IchNf6dN4tHoMFIn/7OE8LWZ19Y6q/67Bmf6vnGREv8RSbBVb9LPJxEcnwrcwX6ixSvaiGoomAUvu4YSxXrVgw==", + "dev": true, + "dependencies": { + "@jridgewell/trace-mapping": "0.3.9" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/@cspotcode/source-map-support/node_modules/@jridgewell/trace-mapping": { + "version": "0.3.9", + "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.9.tgz", + "integrity": "sha512-3Belt6tdc8bPgAtbcmdtNJlirVoTmEb5e2gC94PnkwEW9jI6CAHUeoG85tjWP5WquqfavoMtMwiG4P926ZKKuQ==", + "dev": true, + "dependencies": { + "@jridgewell/resolve-uri": "^3.0.3", + "@jridgewell/sourcemap-codec": "^1.4.10" + } + }, "node_modules/@isaacs/cliui": { "version": "8.0.2", "resolved": "https://registry.npmjs.org/@isaacs/cliui/-/cliui-8.0.2.tgz", @@ -212,6 +237,30 @@ } } }, + "node_modules/@tsconfig/node10": { + "version": "1.0.11", + "resolved": "https://registry.npmjs.org/@tsconfig/node10/-/node10-1.0.11.tgz", + "integrity": "sha512-DcRjDCujK/kCk/cUe8Xz8ZSpm8mS3mNNpta+jGCA6USEDfktlNvm1+IuZ9eTcDbNk41BHwpHHeW+N1lKCz4zOw==", + "dev": true + }, + "node_modules/@tsconfig/node12": { + "version": "1.0.11", + "resolved": "https://registry.npmjs.org/@tsconfig/node12/-/node12-1.0.11.tgz", + "integrity": "sha512-cqefuRsh12pWyGsIoBKJA9luFu3mRxCA+ORZvA4ktLSzIuCUtWVxGIuXigEwO5/ywWFMZ2QEGKWvkZG1zDMTag==", + "dev": true + }, + "node_modules/@tsconfig/node14": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/@tsconfig/node14/-/node14-1.0.3.tgz", + "integrity": "sha512-ysT8mhdixWK6Hw3i1V2AeRqZ5WfXg1G43mqoYlM2nc6388Fq5jcXyr5mRsqViLx/GJYdoL0bfXD8nmF+Zn/Iow==", + "dev": true + }, + "node_modules/@tsconfig/node16": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/@tsconfig/node16/-/node16-1.0.4.tgz", + "integrity": "sha512-vxhUy4J8lyeyinH7Azl1pdd43GJhZH/tP2weN8TntQblOY+A0XbT8DJk1/oCPuOOyg/Ja757rG0CgHcWC8OfMA==", + "dev": true + }, "node_modules/@types/estree": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.5.tgz", @@ -245,6 +294,18 @@ "node": ">=0.4.0" } }, + "node_modules/acorn-walk": { + "version": "8.3.3", + "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-8.3.3.tgz", + "integrity": "sha512-MxXdReSRhGO7VlFe1bRG/oI7/mdLV9B9JJT0N8vZOhF7gFRR5l3M8W9G8JxmKV+JC5mGqJ0QvqfSOLsCPa4nUw==", + "dev": true, + "dependencies": { + "acorn": "^8.11.0" + }, + "engines": { + "node": ">=0.4.0" + } + }, "node_modules/ansi-regex": { "version": "6.0.1", "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.0.1.tgz", @@ -269,6 +330,12 @@ "node": ">=4" } }, + "node_modules/arg": { + "version": "4.1.3", + "resolved": "https://registry.npmjs.org/arg/-/arg-4.1.3.tgz", + "integrity": "sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA==", + "dev": true + }, "node_modules/balanced-match": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", @@ -343,6 +410,12 @@ "integrity": "sha512-W9pAhw0ja1Edb5GVdIF1mjZw/ASI0AlShXM83UUGe2DVr5TdAPEA1OA8m/g8zWp9x6On7gqufY+FatDbC3MDQg==", "dev": true }, + "node_modules/create-require": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/create-require/-/create-require-1.1.1.tgz", + "integrity": "sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ==", + "dev": true + }, "node_modules/cross-spawn": { "version": "7.0.3", "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", @@ -366,6 +439,15 @@ "node": ">=0.10.0" } }, + "node_modules/diff": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz", + "integrity": "sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==", + "dev": true, + "engines": { + "node": ">=0.3.1" + } + }, "node_modules/eastasianwidth": { "version": "0.2.0", "resolved": "https://registry.npmjs.org/eastasianwidth/-/eastasianwidth-0.2.0.tgz", @@ -613,6 +695,12 @@ "@jridgewell/sourcemap-codec": "^1.4.15" } }, + "node_modules/make-error": { + "version": "1.3.6", + "resolved": "https://registry.npmjs.org/make-error/-/make-error-1.3.6.tgz", + "integrity": "sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==", + "dev": true + }, "node_modules/merge-stream": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz", @@ -974,12 +1062,74 @@ "node": ">=10" } }, + "node_modules/ts-node": { + "version": "10.9.2", + "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-10.9.2.tgz", + "integrity": "sha512-f0FFpIdcHgn8zcPSbf1dRevwt047YMnaiJM3u2w2RewrB+fob/zePZcrOyQoLMMO7aBIddLcQIEK5dYjkLnGrQ==", + "dev": true, + "dependencies": { + "@cspotcode/source-map-support": "^0.8.0", + "@tsconfig/node10": "^1.0.7", + "@tsconfig/node12": "^1.0.7", + "@tsconfig/node14": "^1.0.0", + "@tsconfig/node16": "^1.0.2", + "acorn": "^8.4.1", + "acorn-walk": "^8.1.1", + "arg": "^4.1.0", + "create-require": "^1.1.0", + "diff": "^4.0.1", + "make-error": "^1.1.1", + "v8-compile-cache-lib": "^3.0.1", + "yn": "3.1.1" + }, + "bin": { + "ts-node": "dist/bin.js", + "ts-node-cwd": "dist/bin-cwd.js", + "ts-node-esm": "dist/bin-esm.js", + "ts-node-script": "dist/bin-script.js", + "ts-node-transpile-only": "dist/bin-transpile.js", + "ts-script": "dist/bin-script-deprecated.js" + }, + "peerDependencies": { + "@swc/core": ">=1.2.50", + "@swc/wasm": ">=1.2.50", + "@types/node": "*", + "typescript": ">=2.7" + }, + "peerDependenciesMeta": { + "@swc/core": { + "optional": true + }, + "@swc/wasm": { + "optional": true + } + } + }, + "node_modules/typescript": { + "version": "5.5.3", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.5.3.tgz", + "integrity": "sha512-/hreyEujaB0w76zKo6717l3L0o/qEUtRgdvUBvlkhoWeOVMjMuHNHk0BRBzikzuGDqNmPQbg5ifMEqsHLiIUcQ==", + "dev": true, + "bin": { + "tsc": "bin/tsc", + "tsserver": "bin/tsserver" + }, + "engines": { + "node": ">=14.17" + } + }, "node_modules/undici-types": { "version": "5.26.5", "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-5.26.5.tgz", "integrity": "sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==", "dev": true }, + "node_modules/v8-compile-cache-lib": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/v8-compile-cache-lib/-/v8-compile-cache-lib-3.0.1.tgz", + "integrity": "sha512-wa7YjyUGfNZngI/vtK0UHAN+lgDCxBPCylVXGp0zu59Fz5aiGtNXaq3DhIov063MorB+VfufLh3JlF2KdTK3xg==", + "dev": true + }, "node_modules/which": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", @@ -1115,6 +1265,15 @@ "funding": { "url": "https://github.com/chalk/ansi-styles?sponsor=1" } + }, + "node_modules/yn": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/yn/-/yn-3.1.1.tgz", + "integrity": "sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q==", + "dev": true, + "engines": { + "node": ">=6" + } } }, "dependencies": { @@ -1146,6 +1305,27 @@ "picocolors": "^1.0.0" } }, + "@cspotcode/source-map-support": { + "version": "0.8.1", + "resolved": "https://registry.npmjs.org/@cspotcode/source-map-support/-/source-map-support-0.8.1.tgz", + "integrity": "sha512-IchNf6dN4tHoMFIn/7OE8LWZ19Y6q/67Bmf6vnGREv8RSbBVb9LPJxEcnwrcwX6ixSvaiGoomAUvu4YSxXrVgw==", + "dev": true, + "requires": { + "@jridgewell/trace-mapping": "0.3.9" + }, + "dependencies": { + "@jridgewell/trace-mapping": { + "version": "0.3.9", + "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.9.tgz", + "integrity": "sha512-3Belt6tdc8bPgAtbcmdtNJlirVoTmEb5e2gC94PnkwEW9jI6CAHUeoG85tjWP5WquqfavoMtMwiG4P926ZKKuQ==", + "dev": true, + "requires": { + "@jridgewell/resolve-uri": "^3.0.3", + "@jridgewell/sourcemap-codec": "^1.4.10" + } + } + } + }, "@isaacs/cliui": { "version": "8.0.2", "resolved": "https://registry.npmjs.org/@isaacs/cliui/-/cliui-8.0.2.tgz", @@ -1255,6 +1435,30 @@ "picomatch": "^2.3.1" } }, + "@tsconfig/node10": { + "version": "1.0.11", + "resolved": "https://registry.npmjs.org/@tsconfig/node10/-/node10-1.0.11.tgz", + "integrity": "sha512-DcRjDCujK/kCk/cUe8Xz8ZSpm8mS3mNNpta+jGCA6USEDfktlNvm1+IuZ9eTcDbNk41BHwpHHeW+N1lKCz4zOw==", + "dev": true + }, + "@tsconfig/node12": { + "version": "1.0.11", + "resolved": "https://registry.npmjs.org/@tsconfig/node12/-/node12-1.0.11.tgz", + "integrity": "sha512-cqefuRsh12pWyGsIoBKJA9luFu3mRxCA+ORZvA4ktLSzIuCUtWVxGIuXigEwO5/ywWFMZ2QEGKWvkZG1zDMTag==", + "dev": true + }, + "@tsconfig/node14": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/@tsconfig/node14/-/node14-1.0.3.tgz", + "integrity": "sha512-ysT8mhdixWK6Hw3i1V2AeRqZ5WfXg1G43mqoYlM2nc6388Fq5jcXyr5mRsqViLx/GJYdoL0bfXD8nmF+Zn/Iow==", + "dev": true + }, + "@tsconfig/node16": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/@tsconfig/node16/-/node16-1.0.4.tgz", + "integrity": "sha512-vxhUy4J8lyeyinH7Azl1pdd43GJhZH/tP2weN8TntQblOY+A0XbT8DJk1/oCPuOOyg/Ja757rG0CgHcWC8OfMA==", + "dev": true + }, "@types/estree": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.5.tgz", @@ -1282,6 +1486,15 @@ "integrity": "sha512-RTvkC4w+KNXrM39/lWCUaG0IbRkWdCv7W/IOW9oU6SawyxulvkQy5HQPVTKxEjczcUvapcrw3cFx/60VN/NRNw==", "dev": true }, + "acorn-walk": { + "version": "8.3.3", + "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-8.3.3.tgz", + "integrity": "sha512-MxXdReSRhGO7VlFe1bRG/oI7/mdLV9B9JJT0N8vZOhF7gFRR5l3M8W9G8JxmKV+JC5mGqJ0QvqfSOLsCPa4nUw==", + "dev": true, + "requires": { + "acorn": "^8.11.0" + } + }, "ansi-regex": { "version": "6.0.1", "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.0.1.tgz", @@ -1297,6 +1510,12 @@ "color-convert": "^1.9.0" } }, + "arg": { + "version": "4.1.3", + "resolved": "https://registry.npmjs.org/arg/-/arg-4.1.3.tgz", + "integrity": "sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA==", + "dev": true + }, "balanced-match": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", @@ -1362,6 +1581,12 @@ "integrity": "sha512-W9pAhw0ja1Edb5GVdIF1mjZw/ASI0AlShXM83UUGe2DVr5TdAPEA1OA8m/g8zWp9x6On7gqufY+FatDbC3MDQg==", "dev": true }, + "create-require": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/create-require/-/create-require-1.1.1.tgz", + "integrity": "sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ==", + "dev": true + }, "cross-spawn": { "version": "7.0.3", "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", @@ -1379,6 +1604,12 @@ "integrity": "sha512-3sUqbMEc77XqpdNO7FRyRog+eW3ph+GYCbj+rK+uYyRMuwsVy0rMiVtPn+QJlKFvWP/1PYpapqYn0Me2knFn+A==", "dev": true }, + "diff": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz", + "integrity": "sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==", + "dev": true + }, "eastasianwidth": { "version": "0.2.0", "resolved": "https://registry.npmjs.org/eastasianwidth/-/eastasianwidth-0.2.0.tgz", @@ -1559,6 +1790,12 @@ "@jridgewell/sourcemap-codec": "^1.4.15" } }, + "make-error": { + "version": "1.3.6", + "resolved": "https://registry.npmjs.org/make-error/-/make-error-1.3.6.tgz", + "integrity": "sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==", + "dev": true + }, "merge-stream": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz", @@ -1811,12 +2048,45 @@ "source-map-support": "~0.5.20" } }, + "ts-node": { + "version": "10.9.2", + "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-10.9.2.tgz", + "integrity": "sha512-f0FFpIdcHgn8zcPSbf1dRevwt047YMnaiJM3u2w2RewrB+fob/zePZcrOyQoLMMO7aBIddLcQIEK5dYjkLnGrQ==", + "dev": true, + "requires": { + "@cspotcode/source-map-support": "^0.8.0", + "@tsconfig/node10": "^1.0.7", + "@tsconfig/node12": "^1.0.7", + "@tsconfig/node14": "^1.0.0", + "@tsconfig/node16": "^1.0.2", + "acorn": "^8.4.1", + "acorn-walk": "^8.1.1", + "arg": "^4.1.0", + "create-require": "^1.1.0", + "diff": "^4.0.1", + "make-error": "^1.1.1", + "v8-compile-cache-lib": "^3.0.1", + "yn": "3.1.1" + } + }, + "typescript": { + "version": "5.5.3", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.5.3.tgz", + "integrity": "sha512-/hreyEujaB0w76zKo6717l3L0o/qEUtRgdvUBvlkhoWeOVMjMuHNHk0BRBzikzuGDqNmPQbg5ifMEqsHLiIUcQ==", + "dev": true + }, "undici-types": { "version": "5.26.5", "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-5.26.5.tgz", "integrity": "sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==", "dev": true }, + "v8-compile-cache-lib": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/v8-compile-cache-lib/-/v8-compile-cache-lib-3.0.1.tgz", + "integrity": "sha512-wa7YjyUGfNZngI/vtK0UHAN+lgDCxBPCylVXGp0zu59Fz5aiGtNXaq3DhIov063MorB+VfufLh3JlF2KdTK3xg==", + "dev": true + }, "which": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", @@ -1913,6 +2183,12 @@ } } } + }, + "yn": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/yn/-/yn-3.1.1.tgz", + "integrity": "sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q==", + "dev": true } } } diff --git a/package.json b/package.json index 65572dc..4e4d56c 100644 --- a/package.json +++ b/package.json @@ -2,12 +2,13 @@ "name": "redocmx", "version": "0.0.7", "description": "Conversión CFDI a PDF", - "main": "./src/index.js", - "types": "./src/types.d.ts", + "main": "cjs/index.js", + "types": "types/index.d.ts", "exports": { - ".": { - "import": "./dist/index.js", - "require": "./dist/index.cjs" + "types": "./types/index.d.ts", + "default": { + "import": "./esm/index.js", + "require": "./cjs/index.js" } }, "type": "module", @@ -26,7 +27,9 @@ "redocmx" ], "scripts": { - "build": "rollup -c", + "build": "npm run build-esm && npm run build-cjs", + "build-esm": "mkdir -p esm && tsc -p tsconfig.esm.json && echo '{\"type\":\"module\"}' > esm/package.json", + "build-cjs": "mkdir -p cjs && tsc -p tsconfig.cjs.json && echo '{\"type\":\"commonjs\"}' > cjs/package.json", "test": "echo \"Error: no test specified\" && exit 1" }, "author": { @@ -40,5 +43,14 @@ "homepage": "https://github.com/redocmx/client-node#readme", "bugs": { "url": "https://github.com/redocmx/client-node/issues" + }, + "devDependencies": { + "@rollup/plugin-commonjs": "^26.0.1", + "@rollup/plugin-node-resolve": "^15.2.3", + "rollup": "^2.79.1", + "rollup-plugin-terser": "^7.0.2", + "ts-node": "^10.9.2", + "typescript": "^5.5.3", + "@types/node": ">=8.1.0" } } diff --git a/src/addenda.js b/src/addenda.ts similarity index 62% rename from src/addenda.js rename to src/addenda.ts index 8fb3a90..b7767c5 100644 --- a/src/addenda.js +++ b/src/addenda.ts @@ -5,10 +5,10 @@ export default class Addenda extends File { super() } - replaceValues(content, options = null) { - if(!options) return content + replaceValues(content: string, options: { [key: string]: string } | null = null) { + if (!options) return content - for(const option of Object.entries(options)) { + for (const option of Object.entries(options)) { const [key, value] = option content = content.split(key).join(value) } @@ -16,10 +16,10 @@ export default class Addenda extends File { return content } - async getFileContent(replaceValues) { + async getFileContent(replaceValues: { [key: string]: string }) { const file = await this.getFile() const fileContent = file.content.toString() - + return this.replaceValues(fileContent, replaceValues) } diff --git a/src/assets.js b/src/assets.ts similarity index 75% rename from src/assets.js rename to src/assets.ts index 4390039..4a35aec 100644 --- a/src/assets.js +++ b/src/assets.ts @@ -1,11 +1,17 @@ import File from './file.js' +import Service from './service.js'; + +import { FetchPaginationOptions, FileComputed } from './types.js'; export default class Assets { - constructor(service) { + + service: Service; + + constructor(service: Service) { this.service = service } - async get(path) { + async get(path: string) { if (!path || path === '/') { throw new TypeError('Path must be provided to get an asset.'); } @@ -23,7 +29,7 @@ export default class Assets { return asset } - async delete(path) { + async delete(path: string) { if (!path || path === '/') { throw new TypeError('Path must be provided to get an asset.'); } @@ -37,7 +43,7 @@ export default class Assets { return asset } - async list(path, options) { + async list(path: string, options: FetchPaginationOptions) { if (path === null || path === undefined || path === '/') { throw new TypeError('Path must be provided to get an asset.'); } @@ -59,7 +65,7 @@ export default class Assets { return asset } - async put(path, source) { + async put(path: string, source: string | Buffer) { if (!path || path === '/') { throw new TypeError('Path must be provided to put an asset.'); } @@ -77,24 +83,20 @@ export default class Assets { } if (typeof source !== 'string' && !(source instanceof Uint8Array)) { - throw new TypeError('Path must be a valid string or a buffer array.'); - } - - const assetData = { - path + throw new TypeError('Source must be a valid string or a buffer array.'); } const isBufferSource = source instanceof Uint8Array + let file: FileComputed + if (isBufferSource) { - const file = { type: 'buffer', content: source } - assetData.file = file + file = { type: 'buffer', content: source } } else { - const file = new File().fromFile(source) - assetData.file = await file.getFile() + file =await ( new File().fromFile(source)).getFile() } - const asset = await this.service.putAsset({ path: assetData.path, file: assetData?.file }) + const asset = await this.service.putAsset({ path, file }) return asset } diff --git a/src/cfdi.js b/src/cfdi.ts similarity index 77% rename from src/cfdi.js rename to src/cfdi.ts index b0f4374..d8f26f2 100644 --- a/src/cfdi.js +++ b/src/cfdi.ts @@ -1,9 +1,17 @@ import Pdf from './pdf.js'; import Addenda from './addenda.js'; import File from './file.js'; +import Service from './service.js'; +import { Payload } from './types.js'; export default class Cfdi extends File { - constructor(service) { + + pdf: Pdf | null; + service: Service; + addenda: Addenda | null; + addendaReplaceValues: { [key:string]: string } | null; + + constructor(service: Service) { super(); this.pdf = null; @@ -13,7 +21,7 @@ export default class Cfdi extends File { this.service = service; } - setAddenda(addenda, replaceValues = null) { + setAddenda(addenda: Addenda, replaceValues = null) { if (addenda && !(addenda instanceof Addenda)) { throw new TypeError('Addenda must be Addenda instance.'); } @@ -26,7 +34,7 @@ export default class Cfdi extends File { this.addendaReplaceValues = replaceValues } - async toPdf(payload = {}) { + async toPdf(payload: Payload = {}) { if (this.pdf) { return this.pdf; } @@ -38,7 +46,7 @@ export default class Cfdi extends File { const file = await this.getFile(); if (this.addenda) { - const addendaContent = await this.addenda.getFileContent(this.addendaReplaceValues); + const addendaContent = await this.addenda.getFileContent(this.addendaReplaceValues ?? {}); payload.addenda = addendaContent; } diff --git a/src/file.js b/src/file.ts similarity index 84% rename from src/file.js rename to src/file.ts index 7a9aefd..452ab15 100644 --- a/src/file.js +++ b/src/file.ts @@ -1,20 +1,25 @@ -import fs from 'fs/promises'; +import * as fs from 'fs/promises'; const { F_OK, R_OK } = fs.constants; export default class File { + + filePath: string | null; + fileBuffer: Buffer | null; + fileContent: string | null; + constructor() { this.filePath = null; this.fileBuffer = null; this.fileContent = null; } - fromFile(filePath) { + fromFile(filePath: string) { this.filePath = filePath; return this } - fromString(fileContent) { + fromString(fileContent: string) { this.fileContent = fileContent; return this } @@ -31,7 +36,7 @@ export default class File { if (this.filePath) { try { await fs.access(this.filePath, F_OK | R_OK); - } catch (err) { + } catch (err: any) { if (err.code === 'ENOENT') { throw new Error(`Failed to read content from file: ${this.filePath}. The file does not exist.`); } else if (err.code === 'EACCES') { diff --git a/src/index.js b/src/index.ts similarity index 75% rename from src/index.js rename to src/index.ts index 51cd86d..e5bc6b1 100644 --- a/src/index.js +++ b/src/index.ts @@ -2,9 +2,14 @@ import Cfdi from './cfdi.js'; import Addenda from './addenda.js'; import Service from './service.js'; import Assets from './assets.js'; +import { RedocConstructorParams } from './types.js'; export default class Redoc { - constructor(config) { + + apiKey?: string; + service?: Service; + + constructor(config: string | RedocConstructorParams) { if (config && typeof config === 'string') { this.apiKey = config; @@ -25,7 +30,7 @@ export default class Redoc { } get cfdi() { - return new Cfdi(this.service); + return new Cfdi(this.service!); } get addenda() { @@ -33,6 +38,6 @@ export default class Redoc { } get assets() { - return new Assets(this.service) + return new Assets(this.service!) } } diff --git a/src/pdf.js b/src/pdf.ts similarity index 72% rename from src/pdf.js rename to src/pdf.ts index adf7be7..1dcb3aa 100644 --- a/src/pdf.js +++ b/src/pdf.ts @@ -1,5 +1,13 @@ +import { CfdisMetadata, PdfConstructorParams } from "./types.js"; + export default class Pdf { - constructor({buffer, transactionId, totalPages, totalTime, metadata}) { + buffer: Buffer; + transactionId: string; + totalPages: number; + totalTime: number; + metadata: CfdisMetadata; + + constructor({buffer, transactionId, totalPages, totalTime, metadata}: PdfConstructorParams) { this.buffer = buffer; this.transactionId = transactionId; this.totalPages = totalPages; diff --git a/src/service.js b/src/service.ts similarity index 67% rename from src/service.js rename to src/service.ts index 1216b31..364d498 100644 --- a/src/service.js +++ b/src/service.ts @@ -1,9 +1,18 @@ -import fs from 'fs' +import * as fs from 'fs' +import * as path from 'path'; -const pkg = JSON.parse(fs.readFileSync('package.json', 'utf8')) +import { RequestConfig, ServiceConstructorParams, ServiceConvertCfdiParams, ServiceDeleteAssetParams, ServiceFetchAssetsParams, ServicePutAssetParams } from './types.js'; + +const pkgPath = path.resolve(__dirname, 'package.json'); +const pkg = JSON.parse(fs.readFileSync(pkgPath, 'utf8')); + +console.log('pkg', pkg) export default class Service { - constructor(config) { + apiKey?: string + apiUrl?: string; + + constructor(config?: string | ServiceConstructorParams) { if (config && typeof config === 'string') { this.apiKey = config; @@ -15,11 +24,11 @@ export default class Service { } this.apiKey = this.apiKey || process.env.REDOC_API_KEY; - this.apiUrl = this.apiUrl || process.env.REDOC_API_URL || 'https://api.redoc.mx/cfdis/convert'; + this.apiUrl = this.apiUrl || process.env.REDOC_API_URL || 'https://api.redoc.mx'; } - async cfdisConvert({ file, payload }) { + async cfdisConvert({ file, payload }: ServiceConvertCfdiParams) { const body = new FormData(); @@ -30,7 +39,7 @@ export default class Service { body.append('addenda', payload.addenda); } - body.append('xml', new Blob([file.content], { type: 'text/xml' }), { filename: 'document' }); + body.append('xml', new Blob([file.content], { type: 'text/xml' }), 'document'); const { data: arrayBuffer, headers } = await this._request('/cfdis/convert', 'POST', { isForm: true, @@ -43,38 +52,35 @@ export default class Service { const buffer = Buffer.from(arrayBuffer); - const metadata = Buffer.from((headers.get('x-redoc-xml-metadata')), 'base64').toString('utf-8'); + const headerMetadata = headers.get('x-redoc-xml-metadata') ?? '' + const metadata = JSON.parse(Buffer.from(headerMetadata, 'base64').toString('utf-8') ?? '{}'); - const transactionId = headers.get('x-redoc-transaction-id'); - const totalPages = headers.get('x-redoc-pdf-total-pages'); - const totalTime = headers.get('x-redoc-process-total-time'); + const transactionId = headers.get('x-redoc-transaction-id') ?? ''; + const totalPages = parseInt(headers.get('x-redoc-pdf-total-pages') ?? '0'); + const totalTime = parseInt(headers.get('x-redoc-process-total-time') ?? '0'); return { buffer, metadata, transactionId, totalPages, totalTime }; } // Assets - async fetchAssets({ path, options }) { - - if(options?.nextToken) { - options.next_token = options.nextToken - delete options.nextToken - } + async fetchAssets({ path, options }: ServiceFetchAssetsParams) { const { data } = await this._request('/images', 'GET', { params: { path, - ...options + ...(options?.nextToken ? { next_token: options?.nextToken } : {}), + ...(options?.limit ? { limit: options?.limit } : {}) } }) return data } - async putAsset({ path, file }) { + async putAsset({ path, file }: ServicePutAssetParams) { const body = new FormData() body.append('path', path) - body.append('file', new Blob([file.content], { type: 'image/png' }), { filename: 'file' }); + body.append('file', new Blob([file.content], { type: 'image/png' }), 'file'); const { data } = await this._request('/images', 'PUT', { isForm: true, @@ -84,7 +90,7 @@ export default class Service { return data } - async deleteAsset({ path }) { + async deleteAsset({ path }: ServiceDeleteAssetParams) { await this._request('/images', 'DELETE', { params: { path, @@ -92,7 +98,7 @@ export default class Service { }) } - async _request(endpoint, method, config = {}) { + async _request(endpoint: string, method: string, config: RequestConfig = {}) { const { headers, body, params, isForm = false, isBufferResponse = false } = config; // Create a new URLSearchParams object for the query parameters @@ -107,13 +113,13 @@ export default class Service { const requestOptions = { method, headers: new Headers({ - 'x-redoc-api-key': this.apiKey, + 'x-redoc-api-key': this.apiKey ?? '', 'redoc-origin-name': 'sdk_node', 'redoc-origin-version': pkg.version, ...(isForm ? {} : { 'Content-Type': 'application/json' }), - ...headers + ...(headers ? headers : {}) }), - body: isForm ? body : JSON.stringify(body) + body: isForm ? body as FormData : JSON.stringify(body) }; try { diff --git a/src/types.d.ts b/src/types.d.ts index 8626856..cea1d8b 100644 --- a/src/types.d.ts +++ b/src/types.d.ts @@ -1,67 +1,146 @@ -import Cfdi from './cfdi'; -import Service from './service'; -import Pdf from './pdf'; -import Addenda from './addenda'; +// export default class Redoc { +// apiKey: string; +// service: Service; +// constructor(apiKey?: string); +// get cfdi(): Cfdi; +// get addenda(): Addenda; +// } -export default class Redoc { +// export class Cfdi extends File { +// pdf: Pdf | null; +// addenda: Addenda | null; +// constructor(); +// setAddenda(addenda: Addenda, replaceValues?: object): void; +// toPdf(payload?: CfdisConvertPayload): Promise; +// } +// export class Addenda extends File { +// constructor(); +// getFileContent(replaceValues?: object): Promise; +// } + +// export class File { +// filePath: string | null; +// fileBuffer: Buffer | null; +// fileContent: string | null; +// constructor(); +// fromFile(filePath: string): this; +// fromString(fileContent: string): this; +// getFile(): Promise<{ content: string | Buffer; type: 'string' | 'buffer' }>; +// } + +// export class Pdf { +// buffer: Buffer; +// transactionId: string; +// totalPages: number; +// totalTime: number; +// metadata: CfdisMetadata; +// constructor({ buffer, transactionId, totalPages, totalTime, metadata }: PdfConstructorParams); +// toBuffer(): Buffer; +// getTransactionId(): string; +// getTotalPages(): number; +// getTotalTimeMs(): number; +// getMetadata(): string; +// } + +// export interface CfdisConvertPayload { +// style_pdf?: string; +// style_email?: string; +// } + +// export class Service { +// apiKey: string; +// apiUrl: string; +// constructor(apiKey?: string); +// static getInstance(apiKey?: string): Service; +// cfdisConvert({ file, payload }: { file: { type: 'string' | 'buffer'; content: string | Buffer }; payload?: CfdisConvertPayload }): Promise<{ buffer: Buffer; metadata: CfdisMetadata; transactionId: string; totalPages: number; totalTime: number; }>; +// } + +///// NEW + +/* Redoc */ +export interface RedocConstructorParams { apiKey: string; - service: Service; - constructor(apiKey?: string); - get cfdi(): Cfdi; - get addenda(): Addenda; + apiUrl?: string; } -export default class Cfdi extends File { - pdf: Pdf | null; - addenda: Addenda | null; - constructor(); - setAddenda(addenda: Addenda, replaceValues?: object): void; - toPdf(payload?: CfdisConvertPayload): Promise; +/* Pdf */ +export interface PdfConstructorParams { + buffer: Buffer; + transactionId: string; + totalPages: number; + totalTime: number; + metadata: CfdisMetadata } -export default class Addenda extends File { - constructor(); - getFileContent(replaceValues?: object): Promise; + + +/* Service */ + +export interface ServiceConstructorParams { + apiKey: string; + apiUrl?: string; } -export default class File { - filePath: string | null; - fileBuffer: Buffer | null; - fileContent: string | null; - constructor(); - fromFile(filePath: string): this; - fromString(fileContent: string): this; - getFile(): Promise<{ content: string | Buffer; type: 'string' | 'buffer' }>; +export interface ServiceConvertCfdiParams { + file: FileComputed; + payload?: Payload; } -export interface CfdisMetadata { - [key: string]: any; // TBD + +interface ServiceAssetsBasic { + path: string; } -export default class Pdf { - buffer: Buffer; - transactionId: string; - totalPages: number; - totalTime: number; - metadata: CfdisMetadata; - constructor({ buffer, transactionId, totalPages, totalTime, metadata }: { buffer: Buffer; transactionId: string; totalPages: number; totalTime: number; metadata: CfdisMetadata }); - toBuffer(): Buffer; - getTransactionId(): string; - getTotalPages(): number; - getTotalTimeMs(): number; - getMetadata(): string; +export interface ServiceFetchAssetsParams extends ServiceAssetsBasic{ + options?: FetchPaginationOptions; +} + +export interface ServicePutAssetParams extends ServiceAssetsBasic{ + file: FileComputed; } -export interface CfdisConvertPayload { +export interface ServiceDeleteAssetParams extends ServiceAssetsBasic { } + + + + + + + + + + + + + +/* File */ +export interface FileComputed { + content: string | Buffer; + type: string; +} + +/* Cfdi */ + +export interface Payload { style_pdf?: string; - style_email?: string; + format?: string; + addenda?: string; } -export default class Service { - static instance: Service | null; - apiKey: string; - apiUrl: string; - constructor(apiKey?: string); - static getInstance(apiKey?: string): Service; - cfdisConvert({ file, payload }: { file: { type: 'string' | 'buffer'; content: string | Buffer }; payload?: CfdisConvertPayload }): Promise<{ buffer: Buffer; metadata: CfdisMetadata; transactionId: string; totalPages: number; totalTime: number; }>; +export interface CfdisMetadata { + [key: string]: any; // TBD +} + +/* Global */ + +export interface FetchPaginationOptions { + nextToken?: string; + limit?: number; +} +export interface RequestConfig { + headers?: { [key: string]: any }; + body?: { [key: string]: any } | FormData; + params?: { [key: string]: any }; + isForm?: boolean; + isBufferResponse?: boolean; } diff --git a/tsconfig.cjs.json b/tsconfig.cjs.json new file mode 100644 index 0000000..1453b30 --- /dev/null +++ b/tsconfig.cjs.json @@ -0,0 +1,16 @@ +{ + "compilerOptions": { + "outDir": "./cjs", + "module": "commonjs", + "target": "es2017", + "checkJs": false, + "alwaysStrict": true, + "noImplicitAny": true, + "noImplicitThis": true, + "strict": true, + "strictFunctionTypes": true, + "types": [ "node" ], + "esModuleInterop": true // This is a viral option, do not enable https://www.semver-ts.org/#module-interop + }, + "include": ["./src/**/*"], +} \ No newline at end of file diff --git a/tsconfig.esm.json b/tsconfig.esm.json new file mode 100644 index 0000000..68615d9 --- /dev/null +++ b/tsconfig.esm.json @@ -0,0 +1,8 @@ +{ + "extends": "./tsconfig.cjs.json", + "compilerOptions": { + "outDir": "./esm", + "moduleResolution": "NodeNext", + "module": "NodeNext", + }, +} \ No newline at end of file diff --git a/tsconfig.json b/tsconfig.json new file mode 100644 index 0000000..2b53f64 --- /dev/null +++ b/tsconfig.json @@ -0,0 +1,11 @@ +{ + "extends": "./tsconfig.cjs.json", + "compilerOptions": { + "noEmit": true, + "types": ["node"] + }, + "ts-node": { + "experimentalResolver": true + }, + "include": ["src/**/*.ts"] +} \ No newline at end of file