diff --git a/package.json b/package.json index 3e9ad3f..34461bc 100644 --- a/package.json +++ b/package.json @@ -49,6 +49,7 @@ "connect-livereload": "~0.4.0", "errorhandler": "~1.0.0", "eslint": "^8.34.0", + "file-type": "16.5.4", "grunt": "~0.4.4", "grunt-angular-templates": "^0.5.4", "grunt-asset-injector": "^0.1.0", diff --git a/server/api/fonts.spec.ts b/server/api/fonts.spec.ts index 4f6bf80..0c4afa3 100644 --- a/server/api/fonts.spec.ts +++ b/server/api/fonts.spec.ts @@ -1,3 +1,4 @@ +import { fromBuffer as fileTypeFromBuffer } from "file-type"; import * as JSZip from "jszip"; import * as _ from "lodash"; import * as should from "should"; @@ -308,7 +309,8 @@ describe("GET /api/fonts/:id?download=zip", () => { should(_.keys(archive2.files).length).eql(60); }); - it("should respond with 200 for download attempt of known font istok-web with unspecified subset", async () => { + it("should respond with 200 for download attempt of known font istok-web with unspecified subset", async function () { + this.timeout(10000); const res = await request(app) .get("/api/fonts/istok-web?download=zip&formats=woff,woff2") .responseType("blob") @@ -330,13 +332,21 @@ describe("GET /api/fonts/:id?download=zip", () => { }); should(files[0].name).eql("istok-web-v20-latin-700.woff"); + should((await fileTypeFromBuffer(await files[0].async("nodebuffer")))?.mime).eql("font/woff"); should(files[1].name).eql("istok-web-v20-latin-700.woff2"); + should((await fileTypeFromBuffer(await files[1].async("nodebuffer")))?.mime).eql("font/woff2"); should(files[2].name).eql("istok-web-v20-latin-700italic.woff"); + should((await fileTypeFromBuffer(await files[2].async("nodebuffer")))?.mime).eql("font/woff"); should(files[3].name).eql("istok-web-v20-latin-700italic.woff2"); + should((await fileTypeFromBuffer(await files[3].async("nodebuffer")))?.mime).eql("font/woff2"); should(files[4].name).eql("istok-web-v20-latin-italic.woff"); + should((await fileTypeFromBuffer(await files[4].async("nodebuffer")))?.mime).eql("font/woff"); should(files[5].name).eql("istok-web-v20-latin-italic.woff2"); + should((await fileTypeFromBuffer(await files[5].async("nodebuffer")))?.mime).eql("font/woff2"); should(files[6].name).eql("istok-web-v20-latin-regular.woff"); + should((await fileTypeFromBuffer(await files[6].async("nodebuffer")))?.mime).eql("font/woff"); should(files[7].name).eql("istok-web-v20-latin-regular.woff2"); + should((await fileTypeFromBuffer(await files[7].async("nodebuffer")))?.mime).eql("font/woff2"); }); it("should respond with 200 for download attempt of known font istok-web with unspecified formats", async () => { @@ -363,25 +373,45 @@ describe("GET /api/fonts/:id?download=zip", () => { // _.each(files, (file) => console.log(file.name)); should(files[0].name).eql("istok-web-v20-latin-700.eot"); + should((await fileTypeFromBuffer(await files[0].async("nodebuffer")))?.mime).eql("application/vnd.ms-fontobject"); should(files[1].name).eql("istok-web-v20-latin-700.svg"); + should((await fileTypeFromBuffer(await files[1].async("nodebuffer")))?.mime).eql("application/xml"); should(files[2].name).eql("istok-web-v20-latin-700.ttf"); + should((await fileTypeFromBuffer(await files[2].async("nodebuffer")))?.mime).eql("font/ttf"); should(files[3].name).eql("istok-web-v20-latin-700.woff"); + should((await fileTypeFromBuffer(await files[3].async("nodebuffer")))?.mime).eql("font/woff"); should(files[4].name).eql("istok-web-v20-latin-700.woff2"); + should((await fileTypeFromBuffer(await files[4].async("nodebuffer")))?.mime).eql("font/woff2"); should(files[5].name).eql("istok-web-v20-latin-700italic.eot"); + should((await fileTypeFromBuffer(await files[5].async("nodebuffer")))?.mime).eql("application/vnd.ms-fontobject"); should(files[6].name).eql("istok-web-v20-latin-700italic.svg"); + should((await fileTypeFromBuffer(await files[6].async("nodebuffer")))?.mime).eql("application/xml"); should(files[7].name).eql("istok-web-v20-latin-700italic.ttf"); + should((await fileTypeFromBuffer(await files[7].async("nodebuffer")))?.mime).eql("font/ttf"); should(files[8].name).eql("istok-web-v20-latin-700italic.woff"); + should((await fileTypeFromBuffer(await files[8].async("nodebuffer")))?.mime).eql("font/woff"); should(files[9].name).eql("istok-web-v20-latin-700italic.woff2"); + should((await fileTypeFromBuffer(await files[9].async("nodebuffer")))?.mime).eql("font/woff2"); should(files[10].name).eql("istok-web-v20-latin-italic.eot"); + should((await fileTypeFromBuffer(await files[10].async("nodebuffer")))?.mime).eql("application/vnd.ms-fontobject"); should(files[11].name).eql("istok-web-v20-latin-italic.svg"); + should((await fileTypeFromBuffer(await files[11].async("nodebuffer")))?.mime).eql("application/xml"); should(files[12].name).eql("istok-web-v20-latin-italic.ttf"); + should((await fileTypeFromBuffer(await files[12].async("nodebuffer")))?.mime).eql("font/ttf"); should(files[13].name).eql("istok-web-v20-latin-italic.woff"); + should((await fileTypeFromBuffer(await files[13].async("nodebuffer")))?.mime).eql("font/woff"); should(files[14].name).eql("istok-web-v20-latin-italic.woff2"); + should((await fileTypeFromBuffer(await files[14].async("nodebuffer")))?.mime).eql("font/woff2"); should(files[15].name).eql("istok-web-v20-latin-regular.eot"); + should((await fileTypeFromBuffer(await files[15].async("nodebuffer")))?.mime).eql("application/vnd.ms-fontobject"); should(files[16].name).eql("istok-web-v20-latin-regular.svg"); + should((await fileTypeFromBuffer(await files[16].async("nodebuffer")))?.mime).eql("application/xml"); should(files[17].name).eql("istok-web-v20-latin-regular.ttf"); + should((await fileTypeFromBuffer(await files[17].async("nodebuffer")))?.mime).eql("font/ttf"); should(files[18].name).eql("istok-web-v20-latin-regular.woff"); + should((await fileTypeFromBuffer(await files[18].async("nodebuffer")))?.mime).eql("font/woff"); should(files[19].name).eql("istok-web-v20-latin-regular.woff2"); + should((await fileTypeFromBuffer(await files[19].async("nodebuffer")))?.mime).eql("font/woff2"); }); it("should respond with 200 for download attempt of known font istok-web and empty subsets", async () => { diff --git a/yarn.lock b/yarn.lock index 272eee6..4901395 100644 --- a/yarn.lock +++ b/yarn.lock @@ -82,6 +82,11 @@ "@nodelib/fs.scandir" "2.1.5" fastq "^1.6.0" +"@tokenizer/token@^0.3.0": + version "0.3.0" + resolved "https://registry.yarnpkg.com/@tokenizer/token/-/token-0.3.0.tgz#fe98a93fe789247e998c75e74e9c7c63217aa276" + integrity sha512-OvjF+z51L3ov0OyAU0duzsYuvO01PH7x4t6DJx+guahgTnBHkhJdG7soQeTSFLWN3efnHyibZ4Z8l2EuWwJN3A== + "@tsconfig/node10@^1.0.7": version "1.0.9" resolved "https://registry.yarnpkg.com/@tsconfig/node10/-/node10-1.0.9.tgz#df4907fc07a886922637b15e02d4cebc4c0021b2" @@ -2339,6 +2344,15 @@ file-entry-cache@^6.0.1: dependencies: flat-cache "^3.0.4" +file-type@16.5.4: + version "16.5.4" + resolved "https://registry.yarnpkg.com/file-type/-/file-type-16.5.4.tgz#474fb4f704bee427681f98dd390058a172a6c2fd" + integrity sha512-/yFHK0aGjFEgDJjEKP0pWCplsPFPhwyfwevf/pVxiN0tmE4L9LmwWxWukdJSHdoCli4VgQLehjJtwQBnqmsKcw== + dependencies: + readable-web-to-node-stream "^3.0.0" + strtok3 "^6.2.4" + token-types "^4.1.1" + file-type@^3.1.0: version "3.9.0" resolved "https://registry.yarnpkg.com/file-type/-/file-type-3.9.0.tgz#257a078384d1db8087bc449d107d52a52672b9e9" @@ -3347,6 +3361,11 @@ iconv-lite@~0.2.11: resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.2.11.tgz#1ce60a3a57864a292d1321ff4609ca4bb965adc8" integrity sha512-KhmFWgaQZY83Cbhi+ADInoUQ8Etn6BG5fikM9syeOjQltvR45h7cRKJ/9uvQEuD61I3Uju77yYce0/LhKVClQw== +ieee754@^1.2.1: + version "1.2.1" + resolved "https://registry.yarnpkg.com/ieee754/-/ieee754-1.2.1.tgz#8eb7a10a63fff25d15a57b001586d177d1b0d352" + integrity sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA== + ignore-by-default@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/ignore-by-default/-/ignore-by-default-1.0.1.tgz#48ca6d72f6c6a3af00a9ad4ae6876be3889e2b09" @@ -5019,6 +5038,11 @@ path-type@^4.0.0: resolved "https://registry.yarnpkg.com/path-type/-/path-type-4.0.0.tgz#84ed01c0a7ba380afe09d90a8c180dcd9d03043b" integrity sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw== +peek-readable@^4.1.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/peek-readable/-/peek-readable-4.1.0.tgz#4ece1111bf5c2ad8867c314c81356847e8a62e72" + integrity sha512-ZI3LnwUv5nOGbQzD9c2iDG6toheuXSZP5esSHBjopsXH4dg19soufvpUGA3uohi5anFtGb2lhAVdHzH6R/Evvg== + pend@~1.2.0: version "1.2.0" resolved "https://registry.yarnpkg.com/pend/-/pend-1.2.0.tgz#7a57eb550a6783f9115331fcf4663d5c8e007a50" @@ -5303,6 +5327,15 @@ readable-stream@^2.0.0, readable-stream@^2.0.1, readable-stream@^2.0.2, readable string_decoder "~1.1.1" util-deprecate "~1.0.1" +readable-stream@^3.6.0: + version "3.6.1" + resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-3.6.1.tgz#f9f9b5f536920253b3d26e7660e7da4ccff9bb62" + integrity sha512-+rQmrWMYGA90yenhTYsLWAsLsqVC8osOw6PKE1HDYiO0gdPeKe/xDHNzIAIn4C91YQ6oenEhfYqqc1883qHbjQ== + dependencies: + inherits "^2.0.3" + string_decoder "^1.1.1" + util-deprecate "^1.0.1" + readable-stream@~1.1.9: version "1.1.14" resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-1.1.14.tgz#7cf4c54ef648e3813084c636dd2079e166c081d9" @@ -5313,6 +5346,13 @@ readable-stream@~1.1.9: isarray "0.0.1" string_decoder "~0.10.x" +readable-web-to-node-stream@^3.0.0: + version "3.0.2" + resolved "https://registry.yarnpkg.com/readable-web-to-node-stream/-/readable-web-to-node-stream-3.0.2.tgz#5d52bb5df7b54861fd48d015e93a2cb87b3ee0bb" + integrity sha512-ePeK6cc1EcKLEhJFt/AebMCLL+GgSKhuygrZ/GLaKZYEecIgIECf4UaUuaByiGtzckwR4ain9VzUh95T1exYGw== + dependencies: + readable-stream "^3.6.0" + readdirp@^2.2.1: version "2.2.1" resolved "https://registry.yarnpkg.com/readdirp/-/readdirp-2.2.1.tgz#0e87622a3325aa33e892285caf8b4e846529a525" @@ -5511,7 +5551,7 @@ safe-buffer@5.1.2, safe-buffer@~5.1.0, safe-buffer@~5.1.1: resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.1.2.tgz#991ec69d296e0313747d59bdfd2b745c35f8828d" integrity sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g== -safe-buffer@5.2.1, safe-buffer@^5.0.1, safe-buffer@^5.1.0, safe-buffer@^5.1.1: +safe-buffer@5.2.1, safe-buffer@^5.0.1, safe-buffer@^5.1.0, safe-buffer@^5.1.1, safe-buffer@~5.2.0: version "5.2.1" resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.2.1.tgz#1eaf9fa9bdb1fdd4ec75f58f9cdb4e6b7827eec6" integrity sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ== @@ -5961,6 +6001,13 @@ string-width@^4.1.0, string-width@^4.2.0: is-fullwidth-code-point "^3.0.0" strip-ansi "^6.0.1" +string_decoder@^1.1.1: + version "1.3.0" + resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-1.3.0.tgz#42f114594a46cf1a8e30b0a84f56c78c3edac21e" + integrity sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA== + dependencies: + safe-buffer "~5.2.0" + string_decoder@~0.10.x: version "0.10.31" resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-0.10.31.tgz#62e203bc41766c6c28c9fc84301dab1c5310fa94" @@ -6077,6 +6124,14 @@ strip-outer@^1.0.0: dependencies: escape-string-regexp "^1.0.2" +strtok3@^6.2.4: + version "6.3.0" + resolved "https://registry.yarnpkg.com/strtok3/-/strtok3-6.3.0.tgz#358b80ffe6d5d5620e19a073aa78ce947a90f9a0" + integrity sha512-fZtbhtvI9I48xDSywd/somNqgUHl2L2cstmXCCif0itOf96jeW18MBSyrLuNicYQVkvpOxkZtkzujiTJ9LW5Jw== + dependencies: + "@tokenizer/token" "^0.3.0" + peek-readable "^4.1.0" + sum-up@^1.0.1: version "1.0.3" resolved "https://registry.yarnpkg.com/sum-up/-/sum-up-1.0.3.tgz#1c661f667057f63bcb7875aa1438bc162525156e" @@ -6343,6 +6398,14 @@ toidentifier@1.0.1: resolved "https://registry.yarnpkg.com/toidentifier/-/toidentifier-1.0.1.tgz#3be34321a88a820ed1bd80dfaa33e479fbb8dd35" integrity sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA== +token-types@^4.1.1: + version "4.2.1" + resolved "https://registry.yarnpkg.com/token-types/-/token-types-4.2.1.tgz#0f897f03665846982806e138977dbe72d44df753" + integrity sha512-6udB24Q737UD/SDsKAHI9FCRP7Bqc9D/MQUV02ORQg5iskjtLJlZJNdN4kKtcdtwCeWIwIHDGaUsTsCCAa8sFQ== + dependencies: + "@tokenizer/token" "^0.3.0" + ieee754 "^1.2.1" + touch@^3.1.0: version "3.1.0" resolved "https://registry.yarnpkg.com/touch/-/touch-3.1.0.tgz#fe365f5f75ec9ed4e56825e0bb76d24ab74af83b" @@ -6623,7 +6686,7 @@ use@^3.1.0: resolved "https://registry.yarnpkg.com/use/-/use-3.1.1.tgz#d50c8cac79a19fbc20f2911f56eb973f4e10070f" integrity sha512-cwESVXlO3url9YWlFW/TA9cshCEhtu7IKJ/p5soJ/gGpj7vbvFrAY/eIioQ6Dw23KjZhYgiIo8HOs1nQ2vr/oQ== -util-deprecate@~1.0.1: +util-deprecate@^1.0.1, util-deprecate@~1.0.1: version "1.0.2" resolved "https://registry.yarnpkg.com/util-deprecate/-/util-deprecate-1.0.2.tgz#450d4dc9fa70de732762fbd2d4a28981419a0ccf" integrity sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==