pax_global_header00006660000000000000000000000064132006001610014477gustar00rootroot0000000000000052 comment=64ebb5e6e8f80801026200d46611061085b69513 ngx-translate-extract-2.3.4/000077500000000000000000000000001320060016100157445ustar00rootroot00000000000000ngx-translate-extract-2.3.4/.gitignore000066400000000000000000000003251320060016100177340ustar00rootroot00000000000000# IDE .vscode .idea # Logs and other files npm-debug.log* .DS_Store # Compiled files dist # Extracted strings strings.json strings.pot # Dependency directory node_modules # Source maps for JS builds *.js.map ngx-translate-extract-2.3.4/LICENSE000066400000000000000000000020561320060016100167540ustar00rootroot00000000000000MIT License Copyright (c) 2017 Kim Biesbjerg Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ngx-translate-extract-2.3.4/README.md000066400000000000000000000073421320060016100172310ustar00rootroot00000000000000If you like this project please show your support with a GitHub star. Much appreciated! # ngx-translate-extract Extract translatable (ngx-translate) strings and save as a JSON or Gettext pot file. Merges with existing strings if the output file already exists. ## Usage Install the package in your project: `npm install @biesbjerg/ngx-translate-extract --save-dev` Add an `extract` script to your project's `package.json`: ``` "scripts": { "extract": "ngx-translate-extract --input ./src --output ./src/assets/i18n/*.json --clean --sort --format namespaced-json" } ``` You can now run `npm run extract` to extract strings. ## Extract examples **Extract from dir and save to file** `ngx-translate-extract -i ./src -o ./src/i18n/strings.json` **Extract from multiple dirs** `ngx-translate-extract -i ./src/folder-a ./src/folder-b -o ./src/i18n/strings.json` **Extract and save to multiple files** `ngx-translate-extract -i ./src -o ./src/i18n/{da,en,fr}.json` **or** `ngx-translate-extract -i ./src -o ./src/i18n/da.json ./src/i18n/en.json ./src/i18n/fr.json` **or (update only)** `ngx-translate-extract -i ./src -o ./src/i18n/*.json` **or (update only)** ## Custom indentation By default, tabs are used for indentation when writing extracted strings to json formats: `ngx-translate-extract -i ./src -o ./src/i18n/en.json --format-indentation $'\t'` If you want to use spaces instead, you can do the following: `ngx-translate-extract -i ./src -o ./src/i18n/en.json --format-indentation ' '` ## Mark strings for extraction using a marker function If, for some reason, you want to extract strings not passed directly to TranslateService, you can wrap them in a custom marker function. ```ts import { _ } from '@biesbjerg/ngx-translate-extract'; _('Extract me'); ``` Add the `marker` argument when running the extract script: `ngx-translate-extract ... -m _` Modify the scripts arguments as required. ## Commandline arguments ``` Usage: ngx-translate-extract [options] Options: --version, -v Show version number [boolean] --help, -h Show help [boolean] --input, -i Paths you would like to extract strings from. You can use path expansion, glob patterns and multiple paths [array] [default: current working path] --patterns, -p Extract strings from the following file patterns [array] [default: ["/**/*.html","/**/*.ts"]] --output, -o Paths where you would like to save extracted strings. You can use path expansion, glob patterns and multiple paths [array] [required] --marker, -m Extract strings passed to a marker function [string] [default: false] --format, -f Output format [string] [choices: "json", "namespaced-json", "pot"] [default: "json"] --format-indentation, --fi Output format indentation [string] [default: "\t"] --replace, -r Replace the contents of output file if it exists (Merges by default) [boolean] [default: false] --sort, -s Sort strings in alphabetical order when saving [boolean] [default: false] --clean, -c Remove obsolete strings when merging [boolean] [default: false] --verbose, -vb If true, prints all processed file paths to console [boolean] [default: true] ngx-translate-extract-2.3.4/bin/000077500000000000000000000000001320060016100165145ustar00rootroot00000000000000ngx-translate-extract-2.3.4/bin/cli.js000077500000000000000000000000621320060016100176220ustar00rootroot00000000000000#! /usr/bin/env node require('../dist/cli/cli'); ngx-translate-extract-2.3.4/package-lock.json000066400000000000000000001552761320060016100212000ustar00rootroot00000000000000{ "name": "@biesbjerg/ngx-translate-extract", "version": "2.3.4", "lockfileVersion": 1, "requires": true, "dependencies": { "@types/chai": { "version": "https://registry.npmjs.org/@types/chai/-/chai-4.0.1.tgz", "integrity": "sha1-N/6neWF8/sP9KxmgJH6LvdUTO/Y=", "dev": true }, "@types/chalk": { "version": "https://registry.npmjs.org/@types/chalk/-/chalk-0.4.31.tgz", "integrity": "sha1-ox10JBprHtu5c8822XooloNKUfk=", "dev": true }, "@types/cheerio": { "version": "https://registry.npmjs.org/@types/cheerio/-/cheerio-0.22.1.tgz", "integrity": "sha1-dAxM2MTT8wdPg7mrYucR6sLHZM4=", "dev": true }, "@types/flat": { "version": "https://registry.npmjs.org/@types/flat/-/flat-0.0.28.tgz", "integrity": "sha1-XHiBSdhabPj/X18ACs3ZEs3qQnQ=", "dev": true }, "@types/glob": { "version": "https://registry.npmjs.org/@types/glob/-/glob-5.0.30.tgz", "integrity": "sha1-ECZAnFYlqGiQdGAoCNCCsoZ7ilE=", "dev": true, "requires": { "@types/minimatch": "https://registry.npmjs.org/@types/minimatch/-/minimatch-2.0.29.tgz", "@types/node": "https://registry.npmjs.org/@types/node/-/node-7.0.8.tgz" } }, "@types/minimatch": { "version": "https://registry.npmjs.org/@types/minimatch/-/minimatch-2.0.29.tgz", "integrity": "sha1-UALhT3Xi1x5WQoHfBDHIwbSio2o=", "dev": true }, "@types/mkdirp": { "version": "https://registry.npmjs.org/@types/mkdirp/-/mkdirp-0.3.29.tgz", "integrity": "sha1-fyrX7FX5FEgvybHsS7GuYCjUYGY=", "dev": true }, "@types/mocha": { "version": "https://registry.npmjs.org/@types/mocha/-/mocha-2.2.41.tgz", "integrity": "sha1-4nzwgXFT658nE7LT9saPHhw8pgg=", "dev": true }, "@types/node": { "version": "https://registry.npmjs.org/@types/node/-/node-7.0.8.tgz", "integrity": "sha1-JeTdgEtjDJFq5nEjPm1x9s4YEko=", "dev": true }, "@types/yargs": { "version": "https://registry.npmjs.org/@types/yargs/-/yargs-8.0.0.tgz", "integrity": "sha1-ZU0enRcpcyp4Q2veK4B27g0CNpM=", "dev": true }, "ansi-regex": { "version": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=" }, "ansi-styles": { "version": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.1.0.tgz", "integrity": "sha1-CcIC1ckX7CMYjKpcnLkXnNlUd1A=", "requires": { "color-convert": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.0.tgz" } }, "arrify": { "version": "https://registry.npmjs.org/arrify/-/arrify-1.0.1.tgz", "integrity": "sha1-iYUI2iIm84DfkEcoRWhJwVAaSw0=", "dev": true }, "assertion-error": { "version": "https://registry.npmjs.org/assertion-error/-/assertion-error-1.0.2.tgz", "integrity": "sha1-E8pRXYYgbaC6xm6DTdOX2HWBCUw=", "dev": true }, "babel-code-frame": { "version": "https://registry.npmjs.org/babel-code-frame/-/babel-code-frame-6.22.0.tgz", "integrity": "sha1-AnYgvuVnqIwyVhV05/0IAdMxGOQ=", "dev": true, "requires": { "chalk": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", "esutils": "https://registry.npmjs.org/esutils/-/esutils-2.0.2.tgz", "js-tokens": "https://registry.npmjs.org/js-tokens/-/js-tokens-3.0.2.tgz" }, "dependencies": { "ansi-styles": { "version": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz", "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=", "dev": true }, "chalk": { "version": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=", "dev": true, "requires": { "ansi-styles": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz", "escape-string-regexp": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", "has-ansi": "https://registry.npmjs.org/has-ansi/-/has-ansi-2.0.0.tgz", "strip-ansi": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", "supports-color": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz" } }, "supports-color": { "version": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz", "integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=", "dev": true } } }, "balanced-match": { "version": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz", "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=", "dev": true }, "boolbase": { "version": "https://registry.npmjs.org/boolbase/-/boolbase-1.0.0.tgz", "integrity": "sha1-aN/1++YMUes3cl6p4+0xDcwed24=" }, "brace-expansion": { "version": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.8.tgz", "integrity": "sha1-wHshHHyVLsH479Uad+8NHTmQopI=", "dev": true, "requires": { "balanced-match": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz", "concat-map": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz" } }, "browser-stdout": { "version": "https://registry.npmjs.org/browser-stdout/-/browser-stdout-1.3.0.tgz", "integrity": "sha1-81HTKWnTL6XXpVZxVCY9korjvR8=", "dev": true }, "builtin-modules": { "version": "https://registry.npmjs.org/builtin-modules/-/builtin-modules-1.1.1.tgz", "integrity": "sha1-Jw8HbFpywC9bZaR9+Uxf46J4iS8=" }, "camelcase": { "version": "https://registry.npmjs.org/camelcase/-/camelcase-4.1.0.tgz", "integrity": "sha1-1UVjW+HjPFQmScaRc+Xeas+uNN0=" }, "chai": { "version": "https://registry.npmjs.org/chai/-/chai-4.0.2.tgz", "integrity": "sha1-L3MnxN5vOF3XeHmZ4qsCaXoyuDs=", "dev": true, "requires": { "assertion-error": "https://registry.npmjs.org/assertion-error/-/assertion-error-1.0.2.tgz", "check-error": "https://registry.npmjs.org/check-error/-/check-error-1.0.2.tgz", "deep-eql": "https://registry.npmjs.org/deep-eql/-/deep-eql-2.0.2.tgz", "get-func-name": "https://registry.npmjs.org/get-func-name/-/get-func-name-2.0.0.tgz", "pathval": "https://registry.npmjs.org/pathval/-/pathval-1.1.0.tgz", "type-detect": "https://registry.npmjs.org/type-detect/-/type-detect-4.0.3.tgz" } }, "chalk": { "version": "https://registry.npmjs.org/chalk/-/chalk-2.0.1.tgz", "integrity": "sha1-2+xJQ20q4V9TYRTnbRRlbNvA9E0=", "requires": { "ansi-styles": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.1.0.tgz", "escape-string-regexp": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", "supports-color": "https://registry.npmjs.org/supports-color/-/supports-color-4.1.0.tgz" } }, "check-error": { "version": "https://registry.npmjs.org/check-error/-/check-error-1.0.2.tgz", "integrity": "sha1-V00xLt2Iu13YkS6Sht1sCu1KrII=", "dev": true }, "cheerio": { "version": "https://registry.npmjs.org/cheerio/-/cheerio-1.0.0-rc.2.tgz", "integrity": "sha1-S59TqBsn5NXawxwP/Qz6A8xoMNs=", "requires": { "css-select": "https://registry.npmjs.org/css-select/-/css-select-1.2.0.tgz", "dom-serializer": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-0.1.0.tgz", "entities": "https://registry.npmjs.org/entities/-/entities-1.1.1.tgz", "htmlparser2": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-3.9.2.tgz", "lodash": "https://registry.npmjs.org/lodash/-/lodash-4.17.4.tgz", "parse5": "https://registry.npmjs.org/parse5/-/parse5-3.0.2.tgz" } }, "cliui": { "version": "https://registry.npmjs.org/cliui/-/cliui-3.2.0.tgz", "integrity": "sha1-EgYBU3qRbSmUD5NNo7SNWFo5IT0=", "requires": { "string-width": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz", "strip-ansi": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", "wrap-ansi": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-2.1.0.tgz" }, "dependencies": { "string-width": { "version": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz", "integrity": "sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M=", "requires": { "code-point-at": "https://registry.npmjs.org/code-point-at/-/code-point-at-1.1.0.tgz", "is-fullwidth-code-point": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz", "strip-ansi": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz" } } } }, "code-point-at": { "version": "https://registry.npmjs.org/code-point-at/-/code-point-at-1.1.0.tgz", "integrity": "sha1-DQcLTQQ6W+ozovGkDi7bPZpMz3c=" }, "color-convert": { "version": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.0.tgz", "integrity": "sha1-Gsz5fdc5uYO/mU1W/sj5WFNkG3o=", "requires": { "color-name": "https://registry.npmjs.org/color-name/-/color-name-1.1.2.tgz" } }, "color-name": { "version": "https://registry.npmjs.org/color-name/-/color-name-1.1.2.tgz", "integrity": "sha1-XIq3K2S9IhXWF66VWeuxSEdc+Y0=" }, "colors": { "version": "https://registry.npmjs.org/colors/-/colors-1.1.2.tgz", "integrity": "sha1-FopHAXVran9RoSzgyXv6KMCE7WM=", "dev": true }, "commander": { "version": "https://registry.npmjs.org/commander/-/commander-2.9.0.tgz", "integrity": "sha1-nJkJQXbhIkDLItbFFGCYQA/g99Q=", "dev": true, "requires": { "graceful-readlink": "https://registry.npmjs.org/graceful-readlink/-/graceful-readlink-1.0.1.tgz" } }, "concat-map": { "version": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=" }, "core-util-is": { "version": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=" }, "cross-spawn": { "version": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-4.0.2.tgz", "integrity": "sha1-e5JHYhwjrf3ThWAEqCPL45dCTUE=", "requires": { "lru-cache": "https://registry.npmjs.org/lru-cache/-/lru-cache-4.1.1.tgz", "which": "https://registry.npmjs.org/which/-/which-1.2.14.tgz" } }, "css-select": { "version": "https://registry.npmjs.org/css-select/-/css-select-1.2.0.tgz", "integrity": "sha1-KzoRBTnFNV8c2NMUYj6HCxIeyFg=", "requires": { "boolbase": "https://registry.npmjs.org/boolbase/-/boolbase-1.0.0.tgz", "css-what": "https://registry.npmjs.org/css-what/-/css-what-2.1.0.tgz", "domutils": "https://registry.npmjs.org/domutils/-/domutils-1.5.1.tgz", "nth-check": "https://registry.npmjs.org/nth-check/-/nth-check-1.0.1.tgz" } }, "css-what": { "version": "https://registry.npmjs.org/css-what/-/css-what-2.1.0.tgz", "integrity": "sha1-lGfQMsOM+u+58teVASUwYvh/ob0=" }, "debug": { "version": "https://registry.npmjs.org/debug/-/debug-2.6.0.tgz", "integrity": "sha1-vFlryr52F/Edn6FTYe3tVgi4SZs=", "dev": true, "requires": { "ms": "https://registry.npmjs.org/ms/-/ms-0.7.2.tgz" } }, "decamelize": { "version": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz", "integrity": "sha1-9lNNFRSCabIDUue+4m9QH5oZEpA=" }, "deep-eql": { "version": "https://registry.npmjs.org/deep-eql/-/deep-eql-2.0.2.tgz", "integrity": "sha1-sbrAblbwp2d3aG1Qyf63XC7XZ5o=", "dev": true, "requires": { "type-detect": "https://registry.npmjs.org/type-detect/-/type-detect-3.0.0.tgz" }, "dependencies": { "type-detect": { "version": "https://registry.npmjs.org/type-detect/-/type-detect-3.0.0.tgz", "integrity": "sha1-RtDMhVOrt7E6NSsNbeov1Y8tm1U=", "dev": true } } }, "diff": { "version": "https://registry.npmjs.org/diff/-/diff-3.2.0.tgz", "integrity": "sha1-yc45Okt8vQsFinJck98pkCeGj/k=", "dev": true }, "doctrine": { "version": "https://registry.npmjs.org/doctrine/-/doctrine-0.7.2.tgz", "integrity": "sha1-fLhgNZujvpDgQLJrcpzkv6ZUxSM=", "dev": true, "requires": { "esutils": "https://registry.npmjs.org/esutils/-/esutils-1.1.6.tgz", "isarray": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz" }, "dependencies": { "esutils": { "version": "https://registry.npmjs.org/esutils/-/esutils-1.1.6.tgz", "integrity": "sha1-wBzKqa5LiXxtDD4hCuUvPHqEQ3U=", "dev": true }, "isarray": { "version": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz", "integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8=", "dev": true } } }, "dom-serializer": { "version": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-0.1.0.tgz", "integrity": "sha1-BzxpdUbOB4DOI75KKOKT5AvDDII=", "requires": { "domelementtype": "https://registry.npmjs.org/domelementtype/-/domelementtype-1.1.3.tgz", "entities": "https://registry.npmjs.org/entities/-/entities-1.1.1.tgz" }, "dependencies": { "domelementtype": { "version": "https://registry.npmjs.org/domelementtype/-/domelementtype-1.1.3.tgz", "integrity": "sha1-vSh3PiZCiBrsUVRJJCmcXNgiGFs=" } } }, "domelementtype": { "version": "https://registry.npmjs.org/domelementtype/-/domelementtype-1.3.0.tgz", "integrity": "sha1-sXrtguirWeUt2cGbF1bg/BhyBMI=" }, "domhandler": { "version": "https://registry.npmjs.org/domhandler/-/domhandler-2.4.1.tgz", "integrity": "sha1-iS5HAAqZvlW783dP/qBWHYh5wlk=", "requires": { "domelementtype": "https://registry.npmjs.org/domelementtype/-/domelementtype-1.3.0.tgz" } }, "domutils": { "version": "https://registry.npmjs.org/domutils/-/domutils-1.5.1.tgz", "integrity": "sha1-3NhIiib1Y9YQeeSMn3t+Mjc2gs8=", "requires": { "dom-serializer": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-0.1.0.tgz", "domelementtype": "https://registry.npmjs.org/domelementtype/-/domelementtype-1.3.0.tgz" } }, "encoding": { "version": "https://registry.npmjs.org/encoding/-/encoding-0.1.12.tgz", "integrity": "sha1-U4tm8+5izRq1HsMjgp0flIDHS+s=", "requires": { "iconv-lite": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.15.tgz" } }, "entities": { "version": "https://registry.npmjs.org/entities/-/entities-1.1.1.tgz", "integrity": "sha1-blwtClYhtdra7O+AuQ7ftc13cvA=" }, "error-ex": { "version": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.1.tgz", "integrity": "sha1-+FWobOYa3E6GIcPNoh56dhLDqNw=", "requires": { "is-arrayish": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz" } }, "escape-string-regexp": { "version": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=" }, "esutils": { "version": "https://registry.npmjs.org/esutils/-/esutils-2.0.2.tgz", "integrity": "sha1-Cr9PHKpbyx96nYrMbepPqqBLrJs=", "dev": true }, "execa": { "version": "https://registry.npmjs.org/execa/-/execa-0.5.1.tgz", "integrity": "sha1-3j+4XLjW6RyFvLzrFkWBeFy1ezY=", "requires": { "cross-spawn": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-4.0.2.tgz", "get-stream": "https://registry.npmjs.org/get-stream/-/get-stream-2.3.1.tgz", "is-stream": "https://registry.npmjs.org/is-stream/-/is-stream-1.1.0.tgz", "npm-run-path": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-2.0.2.tgz", "p-finally": "https://registry.npmjs.org/p-finally/-/p-finally-1.0.0.tgz", "signal-exit": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.2.tgz", "strip-eof": "https://registry.npmjs.org/strip-eof/-/strip-eof-1.0.0.tgz" } }, "find-up": { "version": "https://registry.npmjs.org/find-up/-/find-up-2.1.0.tgz", "integrity": "sha1-RdG35QbHF93UgndaK3eSCjwMV6c=", "requires": { "locate-path": "https://registry.npmjs.org/locate-path/-/locate-path-2.0.0.tgz" } }, "flat": { "version": "https://registry.npmjs.org/flat/-/flat-2.0.1.tgz", "integrity": "sha1-cOKRiKdL4MPIlAnu0fqVd5B64y8=", "requires": { "is-buffer": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.5.tgz" } }, "fs": { "version": "https://registry.npmjs.org/fs/-/fs-0.0.1-security.tgz", "integrity": "sha1-invTcYa23d84E/I4WLV+yq9eQdQ=" }, "fs.realpath": { "version": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=" }, "get-caller-file": { "version": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-1.0.2.tgz", "integrity": "sha1-9wLmMSfn4jHBYKgMFVSstw1QR+U=" }, "get-func-name": { "version": "https://registry.npmjs.org/get-func-name/-/get-func-name-2.0.0.tgz", "integrity": "sha1-6td0q+5y4gQJQzoGY2YCPdaIekE=", "dev": true }, "get-stream": { "version": "https://registry.npmjs.org/get-stream/-/get-stream-2.3.1.tgz", "integrity": "sha1-Xzj5PzRgCWZu4BUKBUFn+Rvdld4=", "requires": { "object-assign": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", "pinkie-promise": "https://registry.npmjs.org/pinkie-promise/-/pinkie-promise-2.0.1.tgz" } }, "gettext-parser": { "version": "https://registry.npmjs.org/gettext-parser/-/gettext-parser-1.2.2.tgz", "integrity": "sha1-HvDadcHnWa4wicc++k0Z5AKYdI4=", "requires": { "encoding": "https://registry.npmjs.org/encoding/-/encoding-0.1.12.tgz" } }, "glob": { "version": "https://registry.npmjs.org/glob/-/glob-7.1.2.tgz", "integrity": "sha1-wZyd+aAocC1nhhI4SmVSQExjbRU=", "requires": { "fs.realpath": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", "inflight": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", "inherits": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", "minimatch": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", "once": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", "path-is-absolute": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz" }, "dependencies": { "balanced-match": { "version": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz", "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=" }, "brace-expansion": { "version": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.8.tgz", "integrity": "sha1-wHshHHyVLsH479Uad+8NHTmQopI=", "requires": { "balanced-match": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz", "concat-map": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz" } }, "minimatch": { "version": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", "integrity": "sha1-UWbihkV/AzBgZL5Ul+jbsMPTIIM=", "requires": { "brace-expansion": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.8.tgz" } } } }, "graceful-fs": { "version": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.1.11.tgz", "integrity": "sha1-Dovf5NHduIVNZOBOp8AOKgJuVlg=" }, "graceful-readlink": { "version": "https://registry.npmjs.org/graceful-readlink/-/graceful-readlink-1.0.1.tgz", "integrity": "sha1-TK+tdrxi8C+gObL5Tpo906ORpyU=", "dev": true }, "growl": { "version": "https://registry.npmjs.org/growl/-/growl-1.9.2.tgz", "integrity": "sha1-Dqd0NxXbjY3ixe3hd14bRayFwC8=", "dev": true }, "has-ansi": { "version": "https://registry.npmjs.org/has-ansi/-/has-ansi-2.0.0.tgz", "integrity": "sha1-NPUEnOHs3ysGSa8+8k5F7TVBbZE=", "dev": true, "requires": { "ansi-regex": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz" } }, "has-flag": { "version": "https://registry.npmjs.org/has-flag/-/has-flag-1.0.0.tgz", "integrity": "sha1-nZ55MWXOAXoA8AQYxD+UKnsdEfo=", "dev": true }, "hosted-git-info": { "version": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.5.0.tgz", "integrity": "sha1-bWDjSzq7yDEwYsO3mO+NkBoHrzw=" }, "htmlparser2": { "version": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-3.9.2.tgz", "integrity": "sha1-G9+HrMoPP55T+k/M6w9LTLsAszg=", "requires": { "domelementtype": "https://registry.npmjs.org/domelementtype/-/domelementtype-1.3.0.tgz", "domhandler": "https://registry.npmjs.org/domhandler/-/domhandler-2.4.1.tgz", "domutils": "https://registry.npmjs.org/domutils/-/domutils-1.5.1.tgz", "entities": "https://registry.npmjs.org/entities/-/entities-1.1.1.tgz", "inherits": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", "readable-stream": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.3.tgz" } }, "iconv-lite": { "version": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.15.tgz", "integrity": "sha1-/iZaIYrGpXz+hUkn6dBMGYJe3es=" }, "inflight": { "version": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", "requires": { "once": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", "wrappy": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz" } }, "inherits": { "version": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=" }, "invert-kv": { "version": "https://registry.npmjs.org/invert-kv/-/invert-kv-1.0.0.tgz", "integrity": "sha1-EEqOSqym09jNFXqO+L+rLXo//bY=" }, "is-arrayish": { "version": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", "integrity": "sha1-d8mYQFJ6qOyxqLppe4BkWnqSap0=" }, "is-buffer": { "version": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.5.tgz", "integrity": "sha1-Hzsm72E7IUuIy8ojzGwB2Hlh7sw=" }, "is-builtin-module": { "version": "https://registry.npmjs.org/is-builtin-module/-/is-builtin-module-1.0.0.tgz", "integrity": "sha1-VAVy0096wxGfj3bDDLwbHgN6/74=", "requires": { "builtin-modules": "https://registry.npmjs.org/builtin-modules/-/builtin-modules-1.1.1.tgz" } }, "is-fullwidth-code-point": { "version": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz", "integrity": "sha1-754xOG8DGn8NZDr4L95QxFfvAMs=", "requires": { "number-is-nan": "https://registry.npmjs.org/number-is-nan/-/number-is-nan-1.0.1.tgz" } }, "is-stream": { "version": "https://registry.npmjs.org/is-stream/-/is-stream-1.1.0.tgz", "integrity": "sha1-EtSj3U5o4Lec6428hBc66A2RykQ=" }, "isarray": { "version": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=" }, "isexe": { "version": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=" }, "js-tokens": { "version": "https://registry.npmjs.org/js-tokens/-/js-tokens-3.0.2.tgz", "integrity": "sha1-mGbfOVECEw449/mWvOtlRDIJwls=", "dev": true }, "json3": { "version": "https://registry.npmjs.org/json3/-/json3-3.3.2.tgz", "integrity": "sha1-PAQ0dD35Pi9cQq7nsZvLSDV19OE=", "dev": true }, "lcid": { "version": "https://registry.npmjs.org/lcid/-/lcid-1.0.0.tgz", "integrity": "sha1-MIrMr6C8SDo4Z7S28rlQYlHRuDU=", "requires": { "invert-kv": "https://registry.npmjs.org/invert-kv/-/invert-kv-1.0.0.tgz" } }, "load-json-file": { "version": "https://registry.npmjs.org/load-json-file/-/load-json-file-2.0.0.tgz", "integrity": "sha1-eUfkIUmvgNaWy/eXvKq8/h/inKg=", "requires": { "graceful-fs": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.1.11.tgz", "parse-json": "https://registry.npmjs.org/parse-json/-/parse-json-2.2.0.tgz", "pify": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", "strip-bom": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz" } }, "locate-path": { "version": "https://registry.npmjs.org/locate-path/-/locate-path-2.0.0.tgz", "integrity": "sha1-K1aLJl7slExtnA3pw9u7ygNUzY4=", "requires": { "p-locate": "https://registry.npmjs.org/p-locate/-/p-locate-2.0.0.tgz", "path-exists": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz" } }, "lodash": { "version": "https://registry.npmjs.org/lodash/-/lodash-4.17.4.tgz", "integrity": "sha1-eCA6TRwyiuHYbcpkYONptX9AVa4=" }, "lodash._baseassign": { "version": "https://registry.npmjs.org/lodash._baseassign/-/lodash._baseassign-3.2.0.tgz", "integrity": "sha1-jDigmVAPIVrQnlnxci/QxSv+Ck4=", "dev": true, "requires": { "lodash._basecopy": "https://registry.npmjs.org/lodash._basecopy/-/lodash._basecopy-3.0.1.tgz", "lodash.keys": "https://registry.npmjs.org/lodash.keys/-/lodash.keys-3.1.2.tgz" } }, "lodash._basecopy": { "version": "https://registry.npmjs.org/lodash._basecopy/-/lodash._basecopy-3.0.1.tgz", "integrity": "sha1-jaDmqHbPNEwK2KVIghEd08XHyjY=", "dev": true }, "lodash._basecreate": { "version": "https://registry.npmjs.org/lodash._basecreate/-/lodash._basecreate-3.0.3.tgz", "integrity": "sha1-G8ZhYU2qf8MRt9A78WgGoCE8+CE=", "dev": true }, "lodash._getnative": { "version": "https://registry.npmjs.org/lodash._getnative/-/lodash._getnative-3.9.1.tgz", "integrity": "sha1-VwvH3t5G1hzc3mh9ZdPuy6o6r/U=", "dev": true }, "lodash._isiterateecall": { "version": "https://registry.npmjs.org/lodash._isiterateecall/-/lodash._isiterateecall-3.0.9.tgz", "integrity": "sha1-UgOte6Ql+uhCRg5pbbnPPmqsBXw=", "dev": true }, "lodash.create": { "version": "https://registry.npmjs.org/lodash.create/-/lodash.create-3.1.1.tgz", "integrity": "sha1-1/KEnw29p+BGgruM1yqwIkYd6+c=", "dev": true, "requires": { "lodash._baseassign": "https://registry.npmjs.org/lodash._baseassign/-/lodash._baseassign-3.2.0.tgz", "lodash._basecreate": "https://registry.npmjs.org/lodash._basecreate/-/lodash._basecreate-3.0.3.tgz", "lodash._isiterateecall": "https://registry.npmjs.org/lodash._isiterateecall/-/lodash._isiterateecall-3.0.9.tgz" } }, "lodash.isarguments": { "version": "https://registry.npmjs.org/lodash.isarguments/-/lodash.isarguments-3.1.0.tgz", "integrity": "sha1-L1c9hcaiQon/AGY7SRwdM4/zRYo=", "dev": true }, "lodash.isarray": { "version": "https://registry.npmjs.org/lodash.isarray/-/lodash.isarray-3.0.4.tgz", "integrity": "sha1-eeTriMNqgSKvhvhEqpvNhRtfu1U=", "dev": true }, "lodash.keys": { "version": "https://registry.npmjs.org/lodash.keys/-/lodash.keys-3.1.2.tgz", "integrity": "sha1-TbwEcrFWvlCgsoaFXRvQsMZWCYo=", "dev": true, "requires": { "lodash._getnative": "https://registry.npmjs.org/lodash._getnative/-/lodash._getnative-3.9.1.tgz", "lodash.isarguments": "https://registry.npmjs.org/lodash.isarguments/-/lodash.isarguments-3.1.0.tgz", "lodash.isarray": "https://registry.npmjs.org/lodash.isarray/-/lodash.isarray-3.0.4.tgz" } }, "lru-cache": { "version": "https://registry.npmjs.org/lru-cache/-/lru-cache-4.1.1.tgz", "integrity": "sha1-Yi4y6CSItJJ5EUpPns9F581rulU=", "requires": { "pseudomap": "https://registry.npmjs.org/pseudomap/-/pseudomap-1.0.2.tgz", "yallist": "https://registry.npmjs.org/yallist/-/yallist-2.1.2.tgz" } }, "make-error": { "version": "https://registry.npmjs.org/make-error/-/make-error-1.3.0.tgz", "integrity": "sha1-Uq06M5zPEM5itAQLcI/nByRLi5Y=", "dev": true }, "mem": { "version": "https://registry.npmjs.org/mem/-/mem-1.1.0.tgz", "integrity": "sha1-Xt1StIXKHZAP5kiVUFOZoN+kX3Y=", "requires": { "mimic-fn": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-1.1.0.tgz" } }, "mimic-fn": { "version": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-1.1.0.tgz", "integrity": "sha1-5md4PZLonb00KBi1IwudYqZyrRg=" }, "minimatch": { "version": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", "integrity": "sha1-UWbihkV/AzBgZL5Ul+jbsMPTIIM=", "dev": true, "requires": { "brace-expansion": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.8.tgz" } }, "minimist": { "version": "https://registry.npmjs.org/minimist/-/minimist-0.0.8.tgz", "integrity": "sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0=" }, "mkdirp": { "version": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.1.tgz", "integrity": "sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM=", "requires": { "minimist": "https://registry.npmjs.org/minimist/-/minimist-0.0.8.tgz" } }, "mocha": { "version": "https://registry.npmjs.org/mocha/-/mocha-3.4.2.tgz", "integrity": "sha1-0O9NMyEm2/GNDWQMmzgt1IvpdZQ=", "dev": true, "requires": { "browser-stdout": "https://registry.npmjs.org/browser-stdout/-/browser-stdout-1.3.0.tgz", "commander": "https://registry.npmjs.org/commander/-/commander-2.9.0.tgz", "debug": "https://registry.npmjs.org/debug/-/debug-2.6.0.tgz", "diff": "https://registry.npmjs.org/diff/-/diff-3.2.0.tgz", "escape-string-regexp": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", "glob": "https://registry.npmjs.org/glob/-/glob-7.1.1.tgz", "growl": "https://registry.npmjs.org/growl/-/growl-1.9.2.tgz", "json3": "https://registry.npmjs.org/json3/-/json3-3.3.2.tgz", "lodash.create": "https://registry.npmjs.org/lodash.create/-/lodash.create-3.1.1.tgz", "mkdirp": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.1.tgz", "supports-color": "https://registry.npmjs.org/supports-color/-/supports-color-3.1.2.tgz" }, "dependencies": { "glob": { "version": "https://registry.npmjs.org/glob/-/glob-7.1.1.tgz", "integrity": "sha1-gFIR3wT6rxxjo2ADBs31reULLsg=", "dev": true, "requires": { "fs.realpath": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", "inflight": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", "inherits": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", "minimatch": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", "once": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", "path-is-absolute": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz" } }, "supports-color": { "version": "https://registry.npmjs.org/supports-color/-/supports-color-3.1.2.tgz", "integrity": "sha1-cqJiiU2dQIuVbKBf83su2KbiotU=", "dev": true, "requires": { "has-flag": "https://registry.npmjs.org/has-flag/-/has-flag-1.0.0.tgz" } } } }, "ms": { "version": "https://registry.npmjs.org/ms/-/ms-0.7.2.tgz", "integrity": "sha1-riXPJRKziFodldfwN4aNhDESR2U=", "dev": true }, "normalize-package-data": { "version": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-2.4.0.tgz", "integrity": "sha1-EvlaMH1YNSB1oEkHuErIvpisAS8=", "requires": { "hosted-git-info": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.5.0.tgz", "is-builtin-module": "https://registry.npmjs.org/is-builtin-module/-/is-builtin-module-1.0.0.tgz", "semver": "https://registry.npmjs.org/semver/-/semver-5.3.0.tgz", "validate-npm-package-license": "https://registry.npmjs.org/validate-npm-package-license/-/validate-npm-package-license-3.0.1.tgz" } }, "npm-run-path": { "version": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-2.0.2.tgz", "integrity": "sha1-NakjLfo11wZ7TLLd8jV7GHFTbF8=", "requires": { "path-key": "https://registry.npmjs.org/path-key/-/path-key-2.0.1.tgz" } }, "nth-check": { "version": "https://registry.npmjs.org/nth-check/-/nth-check-1.0.1.tgz", "integrity": "sha1-mSms32KPwsQQmN6rgqxYDPFJquQ=", "requires": { "boolbase": "https://registry.npmjs.org/boolbase/-/boolbase-1.0.0.tgz" } }, "number-is-nan": { "version": "https://registry.npmjs.org/number-is-nan/-/number-is-nan-1.0.1.tgz", "integrity": "sha1-CXtgK1NCKlIsGvuHkDGDNpQaAR0=" }, "object-assign": { "version": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=" }, "once": { "version": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", "requires": { "wrappy": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz" } }, "os-locale": { "version": "https://registry.npmjs.org/os-locale/-/os-locale-2.0.0.tgz", "integrity": "sha1-FZGN7VEFIrge565aMJ1U9jn8OaQ=", "requires": { "execa": "https://registry.npmjs.org/execa/-/execa-0.5.1.tgz", "lcid": "https://registry.npmjs.org/lcid/-/lcid-1.0.0.tgz", "mem": "https://registry.npmjs.org/mem/-/mem-1.1.0.tgz" } }, "p-finally": { "version": "https://registry.npmjs.org/p-finally/-/p-finally-1.0.0.tgz", "integrity": "sha1-P7z7FbiZpEEjs0ttzBi3JDNqLK4=" }, "p-limit": { "version": "https://registry.npmjs.org/p-limit/-/p-limit-1.1.0.tgz", "integrity": "sha1-sH/y2aXYi+yAYDWJWiurZqJ5iLw=" }, "p-locate": { "version": "https://registry.npmjs.org/p-locate/-/p-locate-2.0.0.tgz", "integrity": "sha1-IKAQOyIqcMj9OcwuWAaA893l7EM=", "requires": { "p-limit": "https://registry.npmjs.org/p-limit/-/p-limit-1.1.0.tgz" } }, "parse-json": { "version": "https://registry.npmjs.org/parse-json/-/parse-json-2.2.0.tgz", "integrity": "sha1-9ID0BDTvgHQfhGkJn43qGPVaTck=", "requires": { "error-ex": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.1.tgz" } }, "parse5": { "version": "https://registry.npmjs.org/parse5/-/parse5-3.0.2.tgz", "integrity": "sha1-Be/1fw70V3+xRKefi5qWemzERRA=", "requires": { "@types/node": "https://registry.npmjs.org/@types/node/-/node-6.0.79.tgz" }, "dependencies": { "@types/node": { "version": "https://registry.npmjs.org/@types/node/-/node-6.0.79.tgz", "integrity": "sha1-Xv59Sm2MRTx+nq9V2TH0oi+sUWk=" } } }, "path": { "version": "https://registry.npmjs.org/path/-/path-0.12.7.tgz", "integrity": "sha1-1NwqUGxM4hl+tIHr/NWzbAFAsQ8=", "requires": { "process": "https://registry.npmjs.org/process/-/process-0.11.9.tgz", "util": "https://registry.npmjs.org/util/-/util-0.10.3.tgz" } }, "path-exists": { "version": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", "integrity": "sha1-zg6+ql94yxiSXqfYENe1mwEP1RU=" }, "path-is-absolute": { "version": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=" }, "path-key": { "version": "https://registry.npmjs.org/path-key/-/path-key-2.0.1.tgz", "integrity": "sha1-QRyttXTFoUDTpLGRDUDYDMn0C0A=" }, "path-parse": { "version": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.5.tgz", "integrity": "sha1-PBrfhx6pzWyUMbbqK9dKD/BVxME=", "dev": true }, "path-type": { "version": "https://registry.npmjs.org/path-type/-/path-type-2.0.0.tgz", "integrity": "sha1-8BLMuEFbcJb8LaoQVMPXI4lZTHM=", "requires": { "pify": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz" } }, "pathval": { "version": "https://registry.npmjs.org/pathval/-/pathval-1.1.0.tgz", "integrity": "sha1-uULm1L3mUwBe9rcTYd74cn0GReA=", "dev": true }, "pify": { "version": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=" }, "pinkie": { "version": "https://registry.npmjs.org/pinkie/-/pinkie-2.0.4.tgz", "integrity": "sha1-clVrgM+g1IqXToDnckjoDtT3+HA=" }, "pinkie-promise": { "version": "https://registry.npmjs.org/pinkie-promise/-/pinkie-promise-2.0.1.tgz", "integrity": "sha1-ITXW36ejWMBprJsXh3YogihFD/o=", "requires": { "pinkie": "https://registry.npmjs.org/pinkie/-/pinkie-2.0.4.tgz" } }, "process": { "version": "https://registry.npmjs.org/process/-/process-0.11.9.tgz", "integrity": "sha1-e9WtIapiU+fahoImTx4R0RwDGME=" }, "process-nextick-args": { "version": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-1.0.7.tgz", "integrity": "sha1-FQ4gt1ZZCtP5EJPyWk8q2L/zC6M=" }, "pseudomap": { "version": "https://registry.npmjs.org/pseudomap/-/pseudomap-1.0.2.tgz", "integrity": "sha1-8FKijacOYYkX7wqKw0wa5aaChrM=" }, "read-pkg": { "version": "https://registry.npmjs.org/read-pkg/-/read-pkg-2.0.0.tgz", "integrity": "sha1-jvHAYjxqbbDcZxPEv6xGMysjaPg=", "requires": { "load-json-file": "https://registry.npmjs.org/load-json-file/-/load-json-file-2.0.0.tgz", "normalize-package-data": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-2.4.0.tgz", "path-type": "https://registry.npmjs.org/path-type/-/path-type-2.0.0.tgz" } }, "read-pkg-up": { "version": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-2.0.0.tgz", "integrity": "sha1-a3KoBImE4MQeeVEP1en6mbO1Sb4=", "requires": { "find-up": "https://registry.npmjs.org/find-up/-/find-up-2.1.0.tgz", "read-pkg": "https://registry.npmjs.org/read-pkg/-/read-pkg-2.0.0.tgz" } }, "readable-stream": { "version": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.3.tgz", "integrity": "sha1-No8lEtefnUb9/HE0mueHi7weuVw=", "requires": { "core-util-is": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", "inherits": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", "isarray": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", "process-nextick-args": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-1.0.7.tgz", "safe-buffer": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.1.tgz", "string_decoder": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.0.3.tgz", "util-deprecate": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz" } }, "require-directory": { "version": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", "integrity": "sha1-jGStX9MNqxyXbiNE/+f3kqam30I=" }, "require-main-filename": { "version": "https://registry.npmjs.org/require-main-filename/-/require-main-filename-1.0.1.tgz", "integrity": "sha1-l/cXtp1IeE9fUmpsWqj/3aBVpNE=" }, "resolve": { "version": "https://registry.npmjs.org/resolve/-/resolve-1.3.3.tgz", "integrity": "sha1-ZVkHw0aahoDcLeOidaj91paR8OU=", "dev": true, "requires": { "path-parse": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.5.tgz" } }, "safe-buffer": { "version": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.1.tgz", "integrity": "sha1-iTMSr2myEj3vcfV4iQAWce6yyFM=" }, "semver": { "version": "https://registry.npmjs.org/semver/-/semver-5.3.0.tgz", "integrity": "sha1-myzl094C0XxgEq0yaqa00M9U+U8=" }, "set-blocking": { "version": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz", "integrity": "sha1-BF+XgtARrppoA93TgrJDkrPYkPc=" }, "signal-exit": { "version": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.2.tgz", "integrity": "sha1-tf3AjxKH6hF4Yo5BXiUTK3NkbG0=" }, "source-map": { "version": "https://registry.npmjs.org/source-map/-/source-map-0.5.6.tgz", "integrity": "sha1-dc449SvwczxafwwRjYEzSiu19BI=", "dev": true }, "source-map-support": { "version": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.4.15.tgz", "integrity": "sha1-AyAt9lwG0r2MfsI2KhkwVv7407E=", "dev": true, "requires": { "source-map": "https://registry.npmjs.org/source-map/-/source-map-0.5.6.tgz" } }, "spdx-correct": { "version": "https://registry.npmjs.org/spdx-correct/-/spdx-correct-1.0.2.tgz", "integrity": "sha1-SzBz2TP/UfORLwOsVRlJikFQ20A=", "requires": { "spdx-license-ids": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-1.2.2.tgz" } }, "spdx-expression-parse": { "version": "https://registry.npmjs.org/spdx-expression-parse/-/spdx-expression-parse-1.0.4.tgz", "integrity": "sha1-m98vIOH0DtRH++JzJmGR/O1RYmw=" }, "spdx-license-ids": { "version": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-1.2.2.tgz", "integrity": "sha1-yd96NCRZSt5r0RkA1ZZpbcBrrFc=" }, "string-width": { "version": "https://registry.npmjs.org/string-width/-/string-width-2.1.0.tgz", "integrity": "sha1-AwZkVh/BRslCPsfZeP4kV0N/5tA=", "requires": { "is-fullwidth-code-point": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", "strip-ansi": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz" }, "dependencies": { "ansi-regex": { "version": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz", "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=" }, "is-fullwidth-code-point": { "version": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=" }, "strip-ansi": { "version": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=", "requires": { "ansi-regex": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz" } } } }, "string_decoder": { "version": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.0.3.tgz", "integrity": "sha1-D8Z9fBQYJd6UKC3VNr7GubzoYKs=", "requires": { "safe-buffer": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.1.tgz" } }, "strip-ansi": { "version": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", "requires": { "ansi-regex": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz" } }, "strip-bom": { "version": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", "integrity": "sha1-IzTBjpx1n3vdVv3vfprj1YjmjtM=" }, "strip-eof": { "version": "https://registry.npmjs.org/strip-eof/-/strip-eof-1.0.0.tgz", "integrity": "sha1-u0P/VZim6wXYm1n80SnJgzE2Br8=" }, "strip-json-comments": { "version": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz", "integrity": "sha1-PFMZQukIwml8DsNEhYwobHygpgo=", "dev": true }, "supports-color": { "version": "https://registry.npmjs.org/supports-color/-/supports-color-4.1.0.tgz", "integrity": "sha1-kswUuz2tiSjKVlbDPhmhnyCvXHo=", "requires": { "has-flag": "https://registry.npmjs.org/has-flag/-/has-flag-2.0.0.tgz" }, "dependencies": { "has-flag": { "version": "https://registry.npmjs.org/has-flag/-/has-flag-2.0.0.tgz", "integrity": "sha1-6CB68cx7MNRGzHC3NLXovhj4jVE=" } } }, "ts-node": { "version": "https://registry.npmjs.org/ts-node/-/ts-node-3.1.0.tgz", "integrity": "sha1-p17FrrSPMFixuUXbp2XxFQuoj4w=", "dev": true, "requires": { "arrify": "https://registry.npmjs.org/arrify/-/arrify-1.0.1.tgz", "chalk": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", "diff": "https://registry.npmjs.org/diff/-/diff-3.2.0.tgz", "make-error": "https://registry.npmjs.org/make-error/-/make-error-1.3.0.tgz", "minimist": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz", "mkdirp": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.1.tgz", "source-map-support": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.4.15.tgz", "tsconfig": "https://registry.npmjs.org/tsconfig/-/tsconfig-6.0.0.tgz", "v8flags": "https://registry.npmjs.org/v8flags/-/v8flags-2.1.1.tgz", "yn": "https://registry.npmjs.org/yn/-/yn-2.0.0.tgz" }, "dependencies": { "ansi-styles": { "version": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz", "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=", "dev": true }, "chalk": { "version": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=", "dev": true, "requires": { "ansi-styles": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz", "escape-string-regexp": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", "has-ansi": "https://registry.npmjs.org/has-ansi/-/has-ansi-2.0.0.tgz", "strip-ansi": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", "supports-color": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz" } }, "minimist": { "version": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz", "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=", "dev": true }, "supports-color": { "version": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz", "integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=", "dev": true } } }, "tsconfig": { "version": "https://registry.npmjs.org/tsconfig/-/tsconfig-6.0.0.tgz", "integrity": "sha1-aw6DdgA9evGGT434+J3QBZ/80DI=", "dev": true, "requires": { "strip-bom": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", "strip-json-comments": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz" } }, "tslib": { "version": "https://registry.npmjs.org/tslib/-/tslib-1.7.1.tgz", "integrity": "sha1-vIAEFkaRkjp5/oN4u+s9ogF1OOw=", "dev": true }, "tslint": { "version": "https://registry.npmjs.org/tslint/-/tslint-5.4.3.tgz", "integrity": "sha1-dhyEArgONHt3M6BDkKdXslNYBGc=", "dev": true, "requires": { "babel-code-frame": "https://registry.npmjs.org/babel-code-frame/-/babel-code-frame-6.22.0.tgz", "colors": "https://registry.npmjs.org/colors/-/colors-1.1.2.tgz", "commander": "https://registry.npmjs.org/commander/-/commander-2.9.0.tgz", "diff": "https://registry.npmjs.org/diff/-/diff-3.2.0.tgz", "glob": "https://registry.npmjs.org/glob/-/glob-7.1.2.tgz", "minimatch": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", "resolve": "https://registry.npmjs.org/resolve/-/resolve-1.3.3.tgz", "semver": "https://registry.npmjs.org/semver/-/semver-5.3.0.tgz", "tslib": "https://registry.npmjs.org/tslib/-/tslib-1.7.1.tgz", "tsutils": "https://registry.npmjs.org/tsutils/-/tsutils-2.5.1.tgz" } }, "tslint-eslint-rules": { "version": "https://registry.npmjs.org/tslint-eslint-rules/-/tslint-eslint-rules-4.1.1.tgz", "integrity": "sha1-fDDniC8mvCdr/5HSOEl1xp2viLo=", "dev": true, "requires": { "doctrine": "https://registry.npmjs.org/doctrine/-/doctrine-0.7.2.tgz", "tslib": "https://registry.npmjs.org/tslib/-/tslib-1.7.1.tgz", "tsutils": "https://registry.npmjs.org/tsutils/-/tsutils-1.9.1.tgz" }, "dependencies": { "tsutils": { "version": "https://registry.npmjs.org/tsutils/-/tsutils-1.9.1.tgz", "integrity": "sha1-ufmrROVa+WgYMdXyjQrur1x1DLA=", "dev": true } } }, "tsutils": { "version": "https://registry.npmjs.org/tsutils/-/tsutils-2.5.1.tgz", "integrity": "sha1-wgATkMee7Bpcz6esEtWZY5aD4M8=", "dev": true, "requires": { "tslib": "https://registry.npmjs.org/tslib/-/tslib-1.7.1.tgz" } }, "type-detect": { "version": "https://registry.npmjs.org/type-detect/-/type-detect-4.0.3.tgz", "integrity": "sha1-Dj8mcLRAmbC0bChNE2p+9Jx0wuo=", "dev": true }, "typescript": { "version": "https://registry.npmjs.org/typescript/-/typescript-2.4.1.tgz", "integrity": "sha1-w8yxbdqgsjFN4DHn5v7onlujRrw=" }, "user-home": { "version": "https://registry.npmjs.org/user-home/-/user-home-1.1.1.tgz", "integrity": "sha1-K1viOjK2Onyd640PKNSFcko98ZA=", "dev": true }, "util": { "version": "https://registry.npmjs.org/util/-/util-0.10.3.tgz", "integrity": "sha1-evsa/lCAUkZInj23/g7TeTNqwPk=", "requires": { "inherits": "https://registry.npmjs.org/inherits/-/inherits-2.0.1.tgz" }, "dependencies": { "inherits": { "version": "https://registry.npmjs.org/inherits/-/inherits-2.0.1.tgz", "integrity": "sha1-sX0I0ya0Qj5Wjv9xn5GwscvfafE=" } } }, "util-deprecate": { "version": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=" }, "v8flags": { "version": "https://registry.npmjs.org/v8flags/-/v8flags-2.1.1.tgz", "integrity": "sha1-qrGh+jDUX4jdMhFIh1rALAtV5bQ=", "dev": true, "requires": { "user-home": "https://registry.npmjs.org/user-home/-/user-home-1.1.1.tgz" } }, "validate-npm-package-license": { "version": "https://registry.npmjs.org/validate-npm-package-license/-/validate-npm-package-license-3.0.1.tgz", "integrity": "sha1-KAS6vnEq0zeUWaz74kdGqywwP7w=", "requires": { "spdx-correct": "https://registry.npmjs.org/spdx-correct/-/spdx-correct-1.0.2.tgz", "spdx-expression-parse": "https://registry.npmjs.org/spdx-expression-parse/-/spdx-expression-parse-1.0.4.tgz" } }, "which": { "version": "https://registry.npmjs.org/which/-/which-1.2.14.tgz", "integrity": "sha1-mofEN48D6CfOyvGs31bHNsAcFOU=", "requires": { "isexe": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz" } }, "which-module": { "version": "https://registry.npmjs.org/which-module/-/which-module-2.0.0.tgz", "integrity": "sha1-2e8H3Od7mQK4o6j6SzHD4/fm6Ho=" }, "wrap-ansi": { "version": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-2.1.0.tgz", "integrity": "sha1-2Pw9KE3QV5T+hJc8rs3Rz4JP3YU=", "requires": { "string-width": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz", "strip-ansi": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz" }, "dependencies": { "string-width": { "version": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz", "integrity": "sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M=", "requires": { "code-point-at": "https://registry.npmjs.org/code-point-at/-/code-point-at-1.1.0.tgz", "is-fullwidth-code-point": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz", "strip-ansi": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz" } } } }, "wrappy": { "version": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=" }, "y18n": { "version": "https://registry.npmjs.org/y18n/-/y18n-3.2.1.tgz", "integrity": "sha1-bRX7qITAhnnA136I53WegR4H+kE=" }, "yallist": { "version": "https://registry.npmjs.org/yallist/-/yallist-2.1.2.tgz", "integrity": "sha1-HBH5IY8HYImkfdUS+TxmmaaoHVI=" }, "yargs": { "version": "https://registry.npmjs.org/yargs/-/yargs-8.0.2.tgz", "integrity": "sha1-YpmpBVsc78lp/355wdkY3Osiw2A=", "requires": { "camelcase": "https://registry.npmjs.org/camelcase/-/camelcase-4.1.0.tgz", "cliui": "https://registry.npmjs.org/cliui/-/cliui-3.2.0.tgz", "decamelize": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz", "get-caller-file": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-1.0.2.tgz", "os-locale": "https://registry.npmjs.org/os-locale/-/os-locale-2.0.0.tgz", "read-pkg-up": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-2.0.0.tgz", "require-directory": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", "require-main-filename": "https://registry.npmjs.org/require-main-filename/-/require-main-filename-1.0.1.tgz", "set-blocking": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz", "string-width": "https://registry.npmjs.org/string-width/-/string-width-2.1.0.tgz", "which-module": "https://registry.npmjs.org/which-module/-/which-module-2.0.0.tgz", "y18n": "https://registry.npmjs.org/y18n/-/y18n-3.2.1.tgz", "yargs-parser": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-7.0.0.tgz" } }, "yargs-parser": { "version": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-7.0.0.tgz", "integrity": "sha1-jQrELxbqVd69MyyvTEA4s+P139k=", "requires": { "camelcase": "https://registry.npmjs.org/camelcase/-/camelcase-4.1.0.tgz" } }, "yn": { "version": "https://registry.npmjs.org/yn/-/yn-2.0.0.tgz", "integrity": "sha1-5a2ryKz0CPY4X8dklWhMiOavaJo=", "dev": true } } } ngx-translate-extract-2.3.4/package.json000066400000000000000000000034161320060016100202360ustar00rootroot00000000000000{ "name": "@biesbjerg/ngx-translate-extract", "version": "2.3.4", "description": "Extract strings from projects using ngx-translate", "main": "dist/index.js", "typings": "dist/index.d.ts", "files": [ "bin/", "dist/" ], "bin": { "ngx-translate-extract": "bin/cli.js" }, "scripts": { "build": "npm run clean && tsc", "watch": "npm run clean && tsc --watch", "clean": "rm -rf ./dist", "lint": "tslint --force './src/**/*.ts'", "test": "mocha -r ts-node/register tests/**/*.spec.ts" }, "repository": { "type": "git", "url": "https://github.com/biesbjerg/ngx-translate-extract.git" }, "keywords": [ "angular", "angular2", "ionic", "ionic2", "ng2-translate", "ngx-translate", "extract", "extractor", "translate", "translation", "i18n", "gettext" ], "author": "Kim Biesbjerg ", "license": "MIT", "bugs": { "url": "https://github.com/biesbjerg/ngx-translate-extract/issues" }, "homepage": "https://github.com/biesbjerg/ngx-translate-extract", "engines": { "node": ">=4.3.2" }, "config": {}, "devDependencies": { "@types/chai": "4.0.1", "@types/glob": "5.0.30", "@types/mocha": "2.2.41", "@types/cheerio": "0.22.1", "@types/chalk": "0.4.31", "@types/flat": "0.0.28", "@types/yargs": "8.0.0", "@types/mkdirp": "0.3.29", "chai": "4.0.2", "mocha": "3.4.2", "ts-node": "3.1.0", "tslint": "5.4.3", "tslint-eslint-rules": "4.1.1" }, "dependencies": { "chalk": "2.0.1", "yargs": "8.0.2", "cheerio": "1.0.0-rc.2", "fs": "0.0.1-security", "gettext-parser": "1.2.2", "glob": "7.1.2", "path": "0.12.7", "mkdirp": "0.5.1", "flat": "2.0.1", "typescript": "2.4.1" } } ngx-translate-extract-2.3.4/src/000077500000000000000000000000001320060016100165335ustar00rootroot00000000000000ngx-translate-extract-2.3.4/src/cli/000077500000000000000000000000001320060016100173025ustar00rootroot00000000000000ngx-translate-extract-2.3.4/src/cli/cli.ts000077500000000000000000000060651320060016100204330ustar00rootroot00000000000000import { ExtractTask } from './tasks/extract.task'; import { ParserInterface } from '../parsers/parser.interface'; import { PipeParser } from '../parsers/pipe.parser'; import { DirectiveParser } from '../parsers/directive.parser'; import { ServiceParser } from '../parsers/service.parser'; import { FunctionParser } from '../parsers/function.parser'; import { CompilerInterface } from '../compilers/compiler.interface'; import { CompilerFactory } from '../compilers/compiler.factory'; import * as fs from 'fs'; import * as yargs from 'yargs'; export const cli = yargs .usage('Extract strings from files for translation.\nUsage: $0 [options]') .version(require(__dirname + '/../../package.json').version) .alias('version', 'v') .help('help') .alias('help', 'h') .option('input', { alias: 'i', describe: 'Paths you would like to extract strings from. You can use path expansion, glob patterns and multiple paths', default: process.env.PWD, type: 'array', normalize: true }) .check(options => { options.input.forEach((dir: string) => { if (!fs.existsSync(dir) || !fs.statSync(dir).isDirectory()) { throw new Error(`The path you supplied was not found: '${dir}'`); } }); return true; }) .option('patterns', { alias: 'p', describe: 'Extract strings from the following file patterns', type: 'array', default: ['/**/*.html', '/**/*.ts'] }) .option('output', { alias: 'o', describe: 'Paths where you would like to save extracted strings. You can use path expansion, glob patterns and multiple paths', type: 'array', normalize: true, required: true }) .option('marker', { alias: 'm', describe: 'Extract strings passed to a marker function', default: false, type: 'string' }) .option('format', { alias: 'f', describe: 'Output format', default: 'json', type: 'string', choices: ['json', 'namespaced-json', 'pot'] }) .option('format-indentation', { alias: 'fi', describe: 'Output format indentation', default: '\t', type: 'string' }) .option('replace', { alias: 'r', describe: 'Replace the contents of output file if it exists (Merges by default)', default: false, type: 'boolean' }) .option('sort', { alias: 's', describe: 'Sort strings in alphabetical order when saving', default: false, type: 'boolean' }) .option('clean', { alias: 'c', describe: 'Remove obsolete strings when merging', default: false, type: 'boolean' }) .option('verbose', { alias: 'vb', describe: 'Log all output to console', default: true, type: 'boolean' }) .exitProcess(true) .parse(process.argv); const extract = new ExtractTask(cli.input, cli.output, { replace: cli.replace, sort: cli.sort, clean: cli.clean, patterns: cli.patterns }); const compiler: CompilerInterface = CompilerFactory.create(cli.format, { indentation: cli.formatIndentation }); extract.setCompiler(compiler); const parsers: ParserInterface[] = [ new PipeParser(), new DirectiveParser(), new ServiceParser() ]; if (cli.marker) { parsers.push(new FunctionParser({ identifier: cli.marker })); } extract.setParsers(parsers); extract.execute(); ngx-translate-extract-2.3.4/src/cli/tasks/000077500000000000000000000000001320060016100204275ustar00rootroot00000000000000ngx-translate-extract-2.3.4/src/cli/tasks/extract.task.ts000066400000000000000000000104571320060016100234210ustar00rootroot00000000000000import { TranslationCollection } from '../../utils/translation.collection'; import { TaskInterface } from './task.interface'; import { ParserInterface } from '../../parsers/parser.interface'; import { CompilerInterface } from '../../compilers/compiler.interface'; import * as chalk from 'chalk'; import * as glob from 'glob'; import * as fs from 'fs'; import * as path from 'path'; import * as mkdirp from 'mkdirp'; export interface ExtractTaskOptionsInterface { replace?: boolean; sort?: boolean; clean?: boolean; patterns?: string[]; verbose?: boolean; } export class ExtractTask implements TaskInterface { protected _options: ExtractTaskOptionsInterface = { replace: false, sort: false, clean: false, patterns: [], verbose: true }; protected _parsers: ParserInterface[] = []; protected _compiler: CompilerInterface; public constructor(protected _input: string[], protected _output: string[], options?: ExtractTaskOptionsInterface) { this._options = Object.assign({}, this._options, options); } public execute(): void { if (!this._parsers) { throw new Error('No parsers configured'); } if (!this._compiler) { throw new Error('No compiler configured'); } const collection = this._extract(); this._out(chalk.green('Extracted %d strings\n'), collection.count()); this._save(collection); } public setParsers(parsers: ParserInterface[]): this { this._parsers = parsers; return this; } public setCompiler(compiler: CompilerInterface): this { this._compiler = compiler; return this; } /** * Extract strings from input dirs using configured parsers */ protected _extract(): TranslationCollection { this._out(chalk.bold('Extracting strings...')); let collection: TranslationCollection = new TranslationCollection(); this._input.forEach(dir => { this._readDir(dir, this._options.patterns).forEach(path => { this._options.verbose && this._out(chalk.gray('- %s'), path); const contents: string = fs.readFileSync(path, 'utf-8'); this._parsers.forEach((parser: ParserInterface) => { collection = collection.union(parser.extract(contents, path)); }); }); }); return collection; } /** * Process collection according to options (merge, clean, sort), compile and save * @param collection */ protected _save(collection: TranslationCollection): void { this._output.forEach(output => { const normalizedOutput: string = path.resolve(output); let dir: string = normalizedOutput; let filename: string = `strings.${this._compiler.extension}`; if (!fs.existsSync(normalizedOutput) || !fs.statSync(normalizedOutput).isDirectory()) { dir = path.dirname(normalizedOutput); filename = path.basename(normalizedOutput); } const outputPath: string = path.join(dir, filename); let processedCollection: TranslationCollection = collection; this._out(chalk.bold('\nSaving: %s'), outputPath); if (fs.existsSync(outputPath) && !this._options.replace) { const existingCollection: TranslationCollection = this._compiler.parse(fs.readFileSync(outputPath, 'utf-8')); if (!existingCollection.isEmpty()) { processedCollection = processedCollection.union(existingCollection); this._out(chalk.dim('- merged with %d existing strings'), existingCollection.count()); } if (this._options.clean) { const collectionCount = processedCollection.count(); processedCollection = processedCollection.intersect(collection); const removeCount = collectionCount - processedCollection.count(); if (removeCount > 0) { this._out(chalk.dim('- removed %d obsolete strings'), removeCount); } } } if (this._options.sort) { processedCollection = processedCollection.sort(); this._out(chalk.dim('- sorted strings')); } if (!fs.existsSync(dir)) { mkdirp.sync(dir); this._out(chalk.dim('- created dir: %s'), dir); } fs.writeFileSync(outputPath, this._compiler.compile(processedCollection)); this._out(chalk.green('Done!')); }); } /** * Get all files in dir matching patterns */ protected _readDir(dir: string, patterns: string[]): string[] { return patterns.reduce((results, pattern) => { return glob.sync(dir + pattern) .filter(path => fs.statSync(path).isFile()) .concat(results); }, []); } protected _out(...args: any[]): void { console.log.apply(this, arguments); } } ngx-translate-extract-2.3.4/src/cli/tasks/task.interface.ts000066400000000000000000000000651320060016100237010ustar00rootroot00000000000000export interface TaskInterface { execute(): void; } ngx-translate-extract-2.3.4/src/compilers/000077500000000000000000000000001320060016100205305ustar00rootroot00000000000000ngx-translate-extract-2.3.4/src/compilers/compiler.factory.ts000066400000000000000000000011611320060016100243570ustar00rootroot00000000000000import { CompilerInterface } from '../compilers/compiler.interface'; import { JsonCompiler } from '../compilers/json.compiler'; import { NamespacedJsonCompiler } from '../compilers/namespaced-json.compiler'; import { PoCompiler } from '../compilers/po.compiler'; export class CompilerFactory { public static create(format: string, options?: {}): CompilerInterface { switch (format) { case 'pot': return new PoCompiler(options); case 'json': return new JsonCompiler(options); case 'namespaced-json': return new NamespacedJsonCompiler(options); default: throw new Error(`Unknown format: ${format}`); } } } ngx-translate-extract-2.3.4/src/compilers/compiler.interface.ts000066400000000000000000000003571320060016100246560ustar00rootroot00000000000000import { TranslationCollection } from '../utils/translation.collection'; export interface CompilerInterface { extension: string; compile(collection: TranslationCollection): string; parse(contents: string): TranslationCollection; } ngx-translate-extract-2.3.4/src/compilers/json.compiler.ts000066400000000000000000000016561320060016100236720ustar00rootroot00000000000000import { CompilerInterface } from './compiler.interface'; import { TranslationCollection } from '../utils/translation.collection'; import * as flat from 'flat'; export class JsonCompiler implements CompilerInterface { public indentation: string = '\t'; public extension = 'json'; public constructor(options?: any) { if (options && typeof options.indentation !== 'undefined') { this.indentation = options.indentation; } } public compile(collection: TranslationCollection): string { return JSON.stringify(collection.values, null, this.indentation); } public parse(contents: string): TranslationCollection { let values: any = JSON.parse(contents); if (this._isNamespacedJsonFormat(values)) { values = flat.flatten(values); } return new TranslationCollection(values); } protected _isNamespacedJsonFormat(values: any): boolean { return Object.keys(values).some(key => typeof values[key] === 'object'); } } ngx-translate-extract-2.3.4/src/compilers/namespaced-json.compiler.ts000066400000000000000000000014551320060016100257650ustar00rootroot00000000000000import { CompilerInterface } from './compiler.interface'; import { TranslationCollection } from '../utils/translation.collection'; import * as flat from 'flat'; export class NamespacedJsonCompiler implements CompilerInterface { public indentation: string = '\t'; public extension = 'json'; public constructor(options?: any) { if (options && typeof options.indentation !== 'undefined') { this.indentation = options.indentation; } } public compile(collection: TranslationCollection): string { const values: {} = flat.unflatten(collection.values, { object: true }); return JSON.stringify(values, null, this.indentation); } public parse(contents: string): TranslationCollection { const values: {} = flat.flatten(JSON.parse(contents)); return new TranslationCollection(values); } } ngx-translate-extract-2.3.4/src/compilers/po.compiler.ts000066400000000000000000000026171320060016100233350ustar00rootroot00000000000000import { CompilerInterface } from './compiler.interface'; import { TranslationCollection, TranslationType } from '../utils/translation.collection'; import * as gettext from 'gettext-parser'; export class PoCompiler implements CompilerInterface { public extension = 'po'; /** * Translation domain */ public domain = ''; public constructor(options?: any) { } public compile(collection: TranslationCollection): string { const data = { charset: 'utf-8', headers: { 'mime-version': '1.0', 'content-type': 'text/plain; charset=utf-8', 'content-transfer-encoding': '8bit' }, translations: { [this.domain]: Object.keys(collection.values).reduce((translations, key) => { translations[key] = { msgid: key, msgstr: collection.get(key) }; return translations; }, {}) } }; return gettext.po.compile(data, 'utf-8'); } public parse(contents: string): TranslationCollection { const collection = new TranslationCollection(); const po = gettext.po.parse(contents, 'utf-8'); if (!po.translations.hasOwnProperty(this.domain)) { return collection; } const values = Object.keys(po.translations[this.domain]) .filter(key => key.length > 0) .reduce((values, key) => { values[key] = po.translations[this.domain][key].msgstr.pop(); return values; }, {}); return new TranslationCollection(values); } } ngx-translate-extract-2.3.4/src/declarations.d.ts000066400000000000000000000000411320060016100217700ustar00rootroot00000000000000declare module 'gettext-parser'; ngx-translate-extract-2.3.4/src/index.ts000066400000000000000000000013421320060016100202120ustar00rootroot00000000000000export * from './utils/translation.collection'; export * from './utils/utils'; export * from './cli/cli'; export * from './cli/tasks/task.interface'; export * from './cli/tasks/extract.task'; export * from './parsers/parser.interface'; export * from './parsers/abstract-template.parser'; export * from './parsers/abstract-ast.parser'; export * from './parsers/directive.parser'; export * from './parsers/pipe.parser'; export * from './parsers/service.parser'; export * from './parsers/function.parser'; export * from './compilers/compiler.interface'; export * from './compilers/compiler.factory'; export * from './compilers/json.compiler'; export * from './compilers/namespaced-json.compiler'; export * from './compilers/po.compiler'; ngx-translate-extract-2.3.4/src/parsers/000077500000000000000000000000001320060016100202125ustar00rootroot00000000000000ngx-translate-extract-2.3.4/src/parsers/abstract-ast.parser.ts000066400000000000000000000037411320060016100244520ustar00rootroot00000000000000import * as ts from 'typescript'; export abstract class AbstractAstParser { protected _sourceFile: ts.SourceFile; protected _createSourceFile(path: string, contents: string): ts.SourceFile { return ts.createSourceFile(path, contents, null, /*setParentNodes */ false); } /** * Get strings from function call's first argument */ protected _getCallArgStrings(callNode: ts.CallExpression): string[] { if (!callNode.arguments.length) { return; } const firstArg = callNode.arguments[0]; switch (firstArg.kind) { case ts.SyntaxKind.StringLiteral: case ts.SyntaxKind.FirstTemplateToken: return [(firstArg as ts.StringLiteral).text]; case ts.SyntaxKind.ArrayLiteralExpression: return (firstArg as ts.ArrayLiteralExpression).elements .map((element: ts.StringLiteral) => element.text); case ts.SyntaxKind.Identifier: console.log('WARNING: We cannot extract variable values passed to TranslateService (yet)'); break; default: console.log(`SKIP: Unknown argument type: '${this._syntaxKindToName(firstArg.kind)}'`, firstArg); } } /** * Find all child nodes of a kind */ protected _findNodes(node: ts.Node, kind: ts.SyntaxKind): ts.Node[] { const childrenNodes: ts.Node[] = node.getChildren(this._sourceFile); const initialValue: ts.Node[] = node.kind === kind ? [node] : []; return childrenNodes.reduce((result: ts.Node[], childNode: ts.Node) => { return result.concat(this._findNodes(childNode, kind)); }, initialValue); } protected _syntaxKindToName(kind: ts.SyntaxKind): string { return ts.SyntaxKind[kind]; } protected _printAllChildren(sourceFile: ts.SourceFile, node: ts.Node, depth = 0): void { console.log( new Array(depth + 1).join('----'), `[${node.kind}]`, this._syntaxKindToName(node.kind), `[pos: ${node.pos}-${node.end}]`, ':\t\t\t', node.getFullText(sourceFile).trim() ); depth++; node.getChildren(sourceFile).forEach(childNode => this._printAllChildren(sourceFile, childNode, depth)); } } ngx-translate-extract-2.3.4/src/parsers/abstract-template.parser.ts000066400000000000000000000010531320060016100254700ustar00rootroot00000000000000export abstract class AbstractTemplateParser { /** * Checks if file is of type javascript or typescript and * makes the assumption that it is an Angular Component */ protected _isAngularComponent(path: string): boolean { return (/\.ts|js$/i).test(path); } /** * Extracts inline template from components */ protected _extractInlineTemplate(contents: string): string { const regExp: RegExp = /template\s*:\s*(["'`])([^\1]*?)\1/; const match = regExp.exec(contents); if (match !== null) { return match[2]; } return ''; } } ngx-translate-extract-2.3.4/src/parsers/directive.parser.ts000066400000000000000000000032761320060016100240430ustar00rootroot00000000000000import { ParserInterface } from './parser.interface'; import { AbstractTemplateParser } from './abstract-template.parser'; import { TranslationCollection } from '../utils/translation.collection'; import * as cheerio from 'cheerio'; const $ = cheerio.load('', {xmlMode: true}); export class DirectiveParser extends AbstractTemplateParser implements ParserInterface { public extract(contents: string, path?: string): TranslationCollection { if (path && this._isAngularComponent(path)) { contents = this._extractInlineTemplate(contents); } return this._parseTemplate(contents); } protected _parseTemplate(template: string): TranslationCollection { let collection: TranslationCollection = new TranslationCollection(); template = this._normalizeTemplateAttributes(template); const selector = '[translate], [ng2-translate]'; $(template) .find(selector) .addBack(selector) .each((i: number, element: CheerioElement) => { const $element = $(element); const attr = $element.attr('translate') || $element.attr('ng2-translate'); if (attr) { collection = collection.add(attr); } else { $element .contents() .toArray() .filter(node => node.type === 'text') .map(node => node.nodeValue.trim()) .filter(text => text.length > 0) .forEach(text => collection = collection.add(text)); } }); return collection; } /** * Angular's `[attr]="'val'"` syntax is not valid HTML, * so it can't be parsed by standard HTML parsers. * This method replaces `[attr]="'val'""` with `attr="val"` */ protected _normalizeTemplateAttributes(template: string): string { return template.replace(/\[([^\]]+)\]="'([^']*)'"/g, '$1="$2"'); } } ngx-translate-extract-2.3.4/src/parsers/function.parser.ts000066400000000000000000000030671320060016100237100ustar00rootroot00000000000000import { ParserInterface } from './parser.interface'; import { AbstractAstParser } from './abstract-ast.parser'; import { TranslationCollection } from '../utils/translation.collection'; import * as ts from 'typescript'; export class FunctionParser extends AbstractAstParser implements ParserInterface { protected _functionIdentifier: string = '_'; public constructor(options?: any) { super(); if (options && typeof options.identifier !== 'undefined') { this._functionIdentifier = options.identifier; } } public extract(contents: string, path?: string): TranslationCollection { let collection: TranslationCollection = new TranslationCollection(); this._sourceFile = this._createSourceFile(path, contents); const callNodes = this._findCallNodes(); callNodes.forEach(callNode => { const keys: string[] = this._getCallArgStrings(callNode); if (keys && keys.length) { collection = collection.addKeys(keys); } }); return collection; } /** * Find all calls to marker function */ protected _findCallNodes(node?: ts.Node): ts.CallExpression[] { if (!node) { node = this._sourceFile; } let callNodes = this._findNodes(node, ts.SyntaxKind.CallExpression) as ts.CallExpression[]; callNodes = callNodes .filter(callNode => { // Only call expressions with arguments if (callNode.arguments.length < 1) { return false; } const identifier = (callNode.getChildAt(0) as ts.Identifier).text; if (identifier !== this._functionIdentifier) { return false; } return true; }); return callNodes; } } ngx-translate-extract-2.3.4/src/parsers/parser.interface.ts000066400000000000000000000002631320060016100240160ustar00rootroot00000000000000import { TranslationCollection } from '../utils/translation.collection'; export interface ParserInterface { extract(contents: string, path?: string): TranslationCollection; } ngx-translate-extract-2.3.4/src/parsers/pipe.parser.ts000066400000000000000000000016031320060016100230120ustar00rootroot00000000000000import { ParserInterface } from './parser.interface'; import { AbstractTemplateParser } from './abstract-template.parser'; import { TranslationCollection } from '../utils/translation.collection'; export class PipeParser extends AbstractTemplateParser implements ParserInterface { public extract(contents: string, path?: string): TranslationCollection { if (path && this._isAngularComponent(path)) { contents = this._extractInlineTemplate(contents); } return this._parseTemplate(contents); } protected _parseTemplate(template: string): TranslationCollection { let collection: TranslationCollection = new TranslationCollection(); const regExp: RegExp = /(['"`])((?:(?!\1).|\\\1)+)\1\s*\|\s*translate/g; let matches: RegExpExecArray; while (matches = regExp.exec(template)) { collection = collection.add(matches[2].split('\\\'').join('\'')); } return collection; } } ngx-translate-extract-2.3.4/src/parsers/service.parser.ts000066400000000000000000000074151320060016100235240ustar00rootroot00000000000000import { ParserInterface } from './parser.interface'; import { AbstractAstParser } from './abstract-ast.parser'; import { TranslationCollection } from '../utils/translation.collection'; import * as ts from 'typescript'; export class ServiceParser extends AbstractAstParser implements ParserInterface { protected _sourceFile: ts.SourceFile; public extract(contents: string, path?: string): TranslationCollection { let collection: TranslationCollection = new TranslationCollection(); this._sourceFile = this._createSourceFile(path, contents); const classNodes = this._findClassNodes(this._sourceFile); classNodes.forEach(classNode => { const constructorNode = this._findConstructorNode(classNode); if (!constructorNode) { return; } const propertyName: string = this._findTranslateServicePropertyName(constructorNode); if (!propertyName) { return; } const callNodes = this._findCallNodes(classNode, propertyName); callNodes.forEach(callNode => { const keys: string[] = this._getCallArgStrings(callNode); if (keys && keys.length) { collection = collection.addKeys(keys); } }); }); return collection; } /** * Detect what the TranslateService instance property * is called by inspecting constructor arguments */ protected _findTranslateServicePropertyName(constructorNode: ts.ConstructorDeclaration): string { if (!constructorNode) { return null; } const result = constructorNode.parameters.find(parameter => { // Skip if visibility modifier is not present (we want it set as an instance property) if (!parameter.modifiers) { return false; } // Parameter has no type if (!parameter.type) { return false; } // Make sure className is of the correct type const parameterType: ts.Identifier = (parameter.type as ts.TypeReferenceNode).typeName as ts.Identifier; if (!parameterType) { return false; } const className: string = parameterType.text; if (className !== 'TranslateService') { return false; } return true; }); if (result) { return (result.name as ts.Identifier).text; } } /** * Find class nodes */ protected _findClassNodes(node: ts.Node): ts.ClassDeclaration[] { return this._findNodes(node, ts.SyntaxKind.ClassDeclaration) as ts.ClassDeclaration[]; } /** * Find constructor */ protected _findConstructorNode(node: ts.ClassDeclaration): ts.ConstructorDeclaration { const constructorNodes = this._findNodes(node, ts.SyntaxKind.Constructor) as ts.ConstructorDeclaration[]; if (constructorNodes) { return constructorNodes[0]; } } /** * Find all calls to TranslateService methods */ protected _findCallNodes(node: ts.Node, propertyIdentifier: string): ts.CallExpression[] { let callNodes = this._findNodes(node, ts.SyntaxKind.CallExpression) as ts.CallExpression[]; callNodes = callNodes .filter(callNode => { // Only call expressions with arguments if (callNode.arguments.length < 1) { return false; } const propAccess = callNode.getChildAt(0).getChildAt(0) as ts.PropertyAccessExpression; if (!propAccess || propAccess.kind !== ts.SyntaxKind.PropertyAccessExpression) { return false; } if (!propAccess.getFirstToken() || propAccess.getFirstToken().kind !== ts.SyntaxKind.ThisKeyword) { return false; } if (propAccess.name.text !== propertyIdentifier) { return false; } const methodAccess = callNode.getChildAt(0) as ts.PropertyAccessExpression; if (!methodAccess || methodAccess.kind !== ts.SyntaxKind.PropertyAccessExpression) { return false; } if (!methodAccess.name || (methodAccess.name.text !== 'get' && methodAccess.name.text !== 'instant' && methodAccess.name.text !== 'stream')) { return false; } return true; }); return callNodes; } } ngx-translate-extract-2.3.4/src/utils/000077500000000000000000000000001320060016100176735ustar00rootroot00000000000000ngx-translate-extract-2.3.4/src/utils/translation.collection.ts000066400000000000000000000043531320060016100247400ustar00rootroot00000000000000export interface TranslationType { [key: string]: string } export class TranslationCollection { public values: TranslationType = {}; public constructor(values: TranslationType = {}) { this.values = values; } public add(key: string, val: string = ''): TranslationCollection { return new TranslationCollection(Object.assign({}, this.values, { [key]: val })); } public addKeys(keys: string[]): TranslationCollection { const values = keys.reduce((results, key) => { results[key] = ''; return results; }, {}); return new TranslationCollection(Object.assign({}, this.values, values)); } public remove(key: string): TranslationCollection { return this.filter(k => key !== k); } public forEach(callback: (key?: string, val?: string) => void): TranslationCollection { Object.keys(this.values).forEach(key => callback.call(this, key, this.values[key])); return this; } public filter(callback: (key?: string, val?: string) => boolean): TranslationCollection { let values: TranslationType = {}; this.forEach((key: string, val: string) => { if (callback.call(this, key, val)) { values[key] = val; } }); return new TranslationCollection(values); } public union(collection: TranslationCollection): TranslationCollection { return new TranslationCollection(Object.assign({}, this.values, collection.values)); } public intersect(collection: TranslationCollection): TranslationCollection { let values: TranslationType = {}; this.filter(key => collection.has(key)) .forEach((key: string, val: string) => { values[key] = val; }); return new TranslationCollection(values); } public has(key: string): boolean { return this.values.hasOwnProperty(key); } public get(key: string): string { return this.values[key]; } public keys(): string[] { return Object.keys(this.values); } public count(): number { return Object.keys(this.values).length; } public isEmpty(): boolean { return Object.keys(this.values).length === 0; } public sort(compareFn?: (a: string, b: string) => number): TranslationCollection { let values: TranslationType = {}; this.keys().sort(compareFn).forEach((key) => { values[key] = this.get(key); }); return new TranslationCollection(values); } } ngx-translate-extract-2.3.4/src/utils/utils.ts000066400000000000000000000001161320060016100214010ustar00rootroot00000000000000export function _(key: string | string[]): string | string[] { return key; } ngx-translate-extract-2.3.4/tests/000077500000000000000000000000001320060016100171065ustar00rootroot00000000000000ngx-translate-extract-2.3.4/tests/compilers/000077500000000000000000000000001320060016100211035ustar00rootroot00000000000000ngx-translate-extract-2.3.4/tests/compilers/namespaced-json.compiler.spec.ts000066400000000000000000000035251320060016100272710ustar00rootroot00000000000000import { expect } from 'chai'; import { TranslationCollection } from '../../src/utils/translation.collection'; import { NamespacedJsonCompiler } from '../../src/compilers/namespaced-json.compiler'; describe('NamespacedJsonCompiler', () => { let compiler: NamespacedJsonCompiler; beforeEach(() => { compiler = new NamespacedJsonCompiler(); }); it('should flatten keys on parse', () => { const contents = ` { "NAMESPACE": { "KEY": { "FIRST_KEY": "", "SECOND_KEY": "VALUE" } } } `; const collection: TranslationCollection = compiler.parse(contents); expect(collection.values).to.deep.equal({'NAMESPACE.KEY.FIRST_KEY': '', 'NAMESPACE.KEY.SECOND_KEY': 'VALUE' }); }); it('should unflatten keys on compile', () => { const collection = new TranslationCollection({ 'NAMESPACE.KEY.FIRST_KEY': '', 'NAMESPACE.KEY.SECOND_KEY': 'VALUE' }); const result: string = compiler.compile(collection); expect(result).to.equal('{\n\t"NAMESPACE": {\n\t\t"KEY": {\n\t\t\t"FIRST_KEY": "",\n\t\t\t"SECOND_KEY": "VALUE"\n\t\t}\n\t}\n}'); }); it('should preserve numeric values on compile', () => { const collection = new TranslationCollection({ "option.0": '', "option.1": '', "option.2": '' }); const result: string = compiler.compile(collection); expect(result).to.equal('{\n\t"option": {\n\t\t"0": "",\n\t\t"1": "",\n\t\t"2": ""\n\t}\n}'); }); it('should use custom indentation chars', () => { const collection = new TranslationCollection({ 'NAMESPACE.KEY.FIRST_KEY': '', 'NAMESPACE.KEY.SECOND_KEY': 'VALUE' }); const customCompiler = new NamespacedJsonCompiler({ indentation: ' ' }); const result: string = customCompiler.compile(collection); expect(result).to.equal('{\n "NAMESPACE": {\n "KEY": {\n "FIRST_KEY": "",\n "SECOND_KEY": "VALUE"\n }\n }\n}'); }); }); ngx-translate-extract-2.3.4/tests/parsers/000077500000000000000000000000001320060016100205655ustar00rootroot00000000000000ngx-translate-extract-2.3.4/tests/parsers/abstract-template.parser.spec.ts000066400000000000000000000034141320060016100267770ustar00rootroot00000000000000import { expect } from 'chai'; import { AbstractTemplateParser } from '../../src/parsers/abstract-template.parser'; class TestTemplateParser extends AbstractTemplateParser { public isAngularComponent(filePath: string): boolean { return this._isAngularComponent(filePath); } public extractInlineTemplate(contents: string): string { return this._extractInlineTemplate(contents); } } describe('AbstractTemplateParser', () => { let parser: TestTemplateParser; beforeEach(() => { parser = new TestTemplateParser(); }); it('should recognize js extension as angular component', () => { const result = parser.isAngularComponent('test.js'); expect(result).to.equal(true); }); it('should recognize ts extension as angular component', () => { const result = parser.isAngularComponent('test.ts'); expect(result).to.equal(true); }); it('should not recognize html extension as angular component', () => { const result = parser.isAngularComponent('test.html'); expect(result).to.equal(false); }); it('should extract inline template', () => { const contents = ` @Component({ selector: 'test', template: '

Hello World

' }) export class TestComponent { } `; const template = parser.extractInlineTemplate(contents); expect(template).to.equal('

Hello World

'); }); it('should extract inline template spanning multiple lines', () => { const contents = ` @Component({ selector: 'test', template: '

Hello World

', styles: [' p { color: red; } '] }) export class TestComponent { } `; const template = parser.extractInlineTemplate(contents); expect(template).to.equal('\n\t\t\t\t\t

\n\t\t\t\t\t\tHello World\n\t\t\t\t\t

\n\t\t\t\t'); }); }); ngx-translate-extract-2.3.4/tests/parsers/directive.parser.spec.ts000066400000000000000000000102561320060016100253430ustar00rootroot00000000000000import { expect } from 'chai'; import { DirectiveParser } from '../../src/parsers/directive.parser'; class TestDirectiveParser extends DirectiveParser { public normalizeTemplateAttributes(template: string): string { return this._normalizeTemplateAttributes(template); } } describe('DirectiveParser', () => { const templateFilename: string = 'test.template.html'; const componentFilename: string = 'test.component.ts'; let parser: TestDirectiveParser; beforeEach(() => { parser = new TestDirectiveParser(); }); it('should extract contents when no translate attribute value is provided', () => { const contents = '
Hello World
'; const keys = parser.extract(contents, templateFilename).keys(); expect(keys).to.deep.equal(['Hello World']); }); it('should extract translate attribute if provided', () => { const contents = '
Hello World
'; const keys = parser.extract(contents, templateFilename).keys(); expect(keys).to.deep.equal(['KEY']); }); it('should extract bound translate attribute as key if provided', () => { const contents = `
Hello World
`; const keys = parser.extract(contents, templateFilename).keys(); expect(keys).to.deep.equal(['KEY']); }); it('should extract direct text nodes when no translate attribute value is provided', () => { const contents = `
Hello World Hi there
`; const keys = parser.extract(contents, templateFilename).keys(); expect(keys).to.deep.equal(['Hello', 'Hi']); }); it('should extract direct text nodes of tags with a translate attribute', () => { const contents = `
Hello World
Hi there
`; const keys = parser.extract(contents, templateFilename).keys(); expect(keys).to.deep.equal(['Hello World', 'Hi there']); }); it('should extract translate attribute if provided or direct text nodes if not', () => { const contents = `
Hello World

Hi there

Lorem Ipsum

`; const keys = parser.extract(contents, templateFilename).keys(); expect(keys).to.deep.equal(['KEY', 'Hi there', 'OTHER_KEY']); }); it('should extract and parse inline template', () => { const contents = ` @Component({ selector: 'test', template: '

Hello World

' }) export class TestComponent { } `; const keys = parser.extract(contents, componentFilename).keys(); expect(keys).to.deep.equal(['Hello World']); }); it('should extract contents when no ng2-translate attribute value is provided', () => { const contents = '
Hello World
'; const keys = parser.extract(contents, templateFilename).keys(); expect(keys).to.deep.equal(['Hello World']); }); it('should extract ng2-translate attribute if provided', () => { const contents = '
Hello World
'; const keys = parser.extract(contents, templateFilename).keys(); expect(keys).to.deep.equal(['KEY']); }); it('should extract bound ng2-translate attribute as key if provided', () => { const contents = `
Hello World
`; const keys = parser.extract(contents, templateFilename).keys(); expect(keys).to.deep.equal(['KEY']); }); it('should not extract translate pipe in html tag', () => { const contents = `

{{ 'Audiobooks for personal development' | translate }}

`; const collection = parser.extract(contents, templateFilename); expect(collection.values).to.deep.equal({}); }); it('should normalize bound attributes', () => { const contents = `

Hello World

`; const template = parser.normalizeTemplateAttributes(contents); expect(template).to.equal('

Hello World

'); }); it('should extract contents from within custom tags', () => { const contents = `Hello World`; const keys = parser.extract(contents, templateFilename).keys(); expect(keys).to.deep.equal(['Hello World']); }); }); ngx-translate-extract-2.3.4/tests/parsers/function.parser.spec.ts000066400000000000000000000012261320060016100252070ustar00rootroot00000000000000import { expect } from 'chai'; import { FunctionParser } from '../../src/parsers/function.parser'; describe('FunctionParser', () => { const componentFilename: string = 'test.component.ts'; let parser: FunctionParser; beforeEach(() => { parser = new FunctionParser(); }); it('should extract strings using marker function', () => { const contents = ` import { _ } from '@biesbjerg/ngx-translate-extract'; _('Hello world'); _(['I', 'am', 'extracted']); otherFunction('But I am not'); `; const keys = parser.extract(contents, componentFilename).keys(); expect(keys).to.deep.equal(['Hello world', 'I', 'am', 'extracted']); }); }); ngx-translate-extract-2.3.4/tests/parsers/pipe.parser.spec.ts000066400000000000000000000072711320060016100243250ustar00rootroot00000000000000import { expect } from 'chai'; import { PipeParser } from '../../src/parsers/pipe.parser'; describe('PipeParser', () => { const templateFilename: string = 'test.template.html'; let parser: PipeParser; beforeEach(() => { parser = new PipeParser(); }); it('should only extract string using pipe', () => { const contents = ``; const keys = parser.extract(contents, templateFilename).keys(); expect(keys).to.deep.equal(['SomeKey_NotWorking']); }); it('should extract string using pipe, but between quotes only', () => { const contents = ``; const keys = parser.extract(contents, templateFilename).keys(); expect(keys).to.deep.equal(['user.settings.form.phone.placeholder']); }); it('should extract interpolated strings using translate pipe', () => { const contents = `Hello {{ 'World' | translate }}`; const keys = parser.extract(contents, templateFilename).keys(); expect(keys).to.deep.equal(['World']); }); it('should extract strings with escaped quotes', () => { const contents = `Hello {{ 'World\\'s largest potato' | translate }}`; const keys = parser.extract(contents, templateFilename).keys(); expect(keys).to.deep.equal([`World's largest potato`]); }); it('should extract strings with multiple escaped quotes', () => { const contents = `{{ 'C\\'est ok. C\\'est ok' | translate }}`; const keys = parser.extract(contents, templateFilename).keys(); expect(keys).to.deep.equal([`C'est ok. C'est ok`]); }); it('should extract interpolated strings using translate pipe in attributes', () => { const contents = ``; const keys = parser.extract(contents, templateFilename).keys(); expect(keys).to.deep.equal(['Hello World']); }); it('should extract bound strings using translate pipe in attributes', () => { const contents = ``; const keys = parser.extract(contents, templateFilename).keys(); expect(keys).to.deep.equal(['Hello World']); }); it('should not use a greedy regular expression', () => { const contents = ` {{ 'Info' | translate }} {{ 'Loading...' | translate }} `; const keys = parser.extract(contents, templateFilename).keys(); expect(keys).to.deep.equal(['Info', 'Loading...']); }); it('should extract strings on same line', () => { const contents = ``; const keys = parser.extract(contents, templateFilename).keys(); expect(keys).to.deep.equal(['Hello', 'World']); }); it('should extract strings from this template', () => { const contents = `

{{ error }}

`; const keys = parser.extract(contents, templateFilename).keys(); expect(keys).to.deep.equal(['Name', 'Create account']); }); }); ngx-translate-extract-2.3.4/tests/parsers/service.parser.spec.ts000066400000000000000000000153751320060016100250340ustar00rootroot00000000000000import { expect } from 'chai'; import { ServiceParser } from '../../src/parsers/service.parser'; class TestServiceParser extends ServiceParser { /*public getInstancePropertyName(): string { return this._getInstancePropertyName(); }*/ } describe('ServiceParser', () => { const componentFilename: string = 'test.component.ts'; let parser: TestServiceParser; beforeEach(() => { parser = new TestServiceParser(); }); /*it('should extract variable used for TranslateService', () => { const contents = ` @Component({ }) export class AppComponent { public constructor( _serviceA: ServiceA, public _serviceB: ServiceB, protected _translateService: TranslateService ) { } `; const name = parser.getInstancePropertyName(); expect(name).to.equal('_translateService'); });*/ it('should extract strings in TranslateService\'s get() method', () => { const contents = ` @Component({ }) export class AppComponent { public constructor(protected _translateService: TranslateService) { } public test() { this._translateService.get('Hello World'); } `; const keys = parser.extract(contents, componentFilename).keys(); expect(keys).to.deep.equal(['Hello World']); }); it('should extract strings in TranslateService\'s instant() method', () => { const contents = ` @Component({ }) export class AppComponent { public constructor(protected _translateService: TranslateService) { } public test() { this._translateService.instant('Hello World'); } `; const keys = parser.extract(contents, componentFilename).keys(); expect(keys).to.deep.equal(['Hello World']); }); it('should extract strings in TranslateService\'s stream() method', () => { const contents = ` @Component({ }) export class AppComponent { public constructor(protected _translateService: TranslateService) { } public test() { this._translateService.stream('Hello World'); } `; const keys = parser.extract(contents, componentFilename).keys(); expect(keys).to.deep.equal(['Hello World']); }); it('should extract array of strings in TranslateService\'s get() method', () => { const contents = ` @Component({ }) export class AppComponent { public constructor(protected _translateService: TranslateService) { } public test() { this._translateService.get(['Hello', 'World']); } `; const keys = parser.extract(contents, componentFilename).keys(); expect(keys).to.deep.equal(['Hello', 'World']); }); it('should extract array of strings in TranslateService\'s instant() method', () => { const contents = ` @Component({ }) export class AppComponent { public constructor(protected _translateService: TranslateService) { } public test() { this._translateService.instant(['Hello', 'World']); } `; const key = parser.extract(contents, componentFilename).keys(); expect(key).to.deep.equal(['Hello', 'World']); }); it('should extract array of strings in TranslateService\'s stream() method', () => { const contents = ` @Component({ }) export class AppComponent { public constructor(protected _translateService: TranslateService) { } public test() { this._translateService.stream(['Hello', 'World']); } `; const key = parser.extract(contents, componentFilename).keys(); expect(key).to.deep.equal(['Hello', 'World']); }); it('should not extract strings in get()/instant()/stream() methods of other services', () => { const contents = ` @Component({ }) export class AppComponent { public constructor( protected _translateService: TranslateService, protected _otherService: OtherService ) { } public test() { this._otherService.get('Hello World'); this._otherService.instant('Hi there'); this._otherService.stream('Hi there'); } `; const keys = parser.extract(contents, componentFilename).keys(); expect(keys).to.deep.equal([]); }); it('should extract strings with liberal spacing', () => { const contents = ` @Component({ }) export class AppComponent { public constructor( protected _translateService: TranslateService, protected _otherService: OtherService ) { } public test() { this._translateService.instant('Hello'); this._translateService.get ( 'World' ); this._translateService.instant ( ['How'] ); this._translateService.get([ 'Are' ]); this._translateService.get([ 'You' , 'Today' ]); } `; const keys = parser.extract(contents, componentFilename).keys(); expect(keys).to.deep.equal(['Hello', 'World', 'How', 'Are', 'You', 'Today']); }); it('should not extract string when not accessing property', () => { const contents = ` @Component({ }) export class AppComponent { public constructor(protected trans: TranslateService) { } public test() { trans.get("You are expected at {{time}}", {time: moment.format('H:mm')}).subscribe(); } } `; const keys = parser.extract(contents, componentFilename).keys(); expect(keys).to.deep.equal([]); }); it('should extract string with params on same line', () => { const contents = ` @Component({ }) export class AppComponent { public constructor(protected _translateService: TranslateService) { } public test() { this._translateService.get('You are expected at {{time}}', {time: moment.format('H:mm')}); } } `; const keys = parser.extract(contents, componentFilename).keys(); expect(keys).to.deep.equal(['You are expected at {{time}}']); }); it('should not crash when constructor parameter has no type', () => { const contents = ` @Component({ }) export class AppComponent { public constructor(protected _translateService) { } public test() { this._translateService.instant('Hello World'); } `; const keys = parser.extract(contents, componentFilename).keys(); expect(keys).to.deep.equal([]); }); it('should extract strings from all classes in the file', () => { const contents = ` import { Injectable } from '@angular/core'; import { TranslateService } from '@ngx-translate/core'; export class Stuff { thing: string; translate: any; constructor(thing: string) { this.translate.get('Not me'); this.thing = thing; } } @Injectable() export class MyComponent { constructor(public translate: TranslateService) { this.translate.instant("Extract me!"); } } export class OtherClass { constructor(thing: string, _translate: TranslateService) { this._translate.get("Do not extract me"); } } @Injectable() export class AuthService { constructor(public translate: TranslateService) { this.translate.instant("Hello!"); } } `; const keys = parser.extract(contents, componentFilename).keys(); expect(keys).to.deep.equal(['Extract me!', 'Hello!']); }); }); ngx-translate-extract-2.3.4/tests/utils/000077500000000000000000000000001320060016100202465ustar00rootroot00000000000000ngx-translate-extract-2.3.4/tests/utils/translation.collection.spec.ts000066400000000000000000000061731320060016100262460ustar00rootroot00000000000000import { expect } from 'chai'; import { TranslationCollection } from '../../src/utils/translation.collection'; describe('StringCollection', () => { let collection: TranslationCollection; beforeEach(() => { collection = new TranslationCollection(); }); it('should initialize with key/value pairs', () => { collection = new TranslationCollection({ key1: 'val1', key2: 'val2' }); expect(collection.values).to.deep.equal({ key1: 'val1', key2: 'val2' }); }); it('should add key with value', () => { const newCollection = collection.add('theKey', 'theVal'); expect(newCollection.get('theKey')).to.equal('theVal'); }); it('should add key with default value', () => { collection = collection.add('theKey'); expect(collection.get('theKey')).to.equal(''); }); it('should not mutate collection when adding key', () => { collection.add('theKey', 'theVal'); expect(collection.has('theKey')).to.equal(false); }); it('should add array of keys with default value', () => { collection = collection.addKeys(['key1', 'key2']); expect(collection.values).to.deep.equal({ key1: '', key2: '' }); }); it('should return true when collection has key', () => { collection = collection.add('key'); expect(collection.has('key')).to.equal(true); }); it('should return false when collection does not have key', () => { expect(collection.has('key')).to.equal(false); }); it('should remove key', () => { collection = new TranslationCollection({ removeThisKey: '' }); collection = collection.remove('removeThisKey'); expect(collection.has('removeThisKey')).to.equal(false); }); it('should not mutate collection when removing key', () => { collection = new TranslationCollection({ removeThisKey: '' }); collection.remove('removeThisKey'); expect(collection.has('removeThisKey')).to.equal(true); }); it('should return number of keys', () => { collection = collection.addKeys(['key1', 'key2', 'key3']); expect(collection.count()).to.equal(3); }); it('should merge with other collection', () => { collection = collection.add('oldKey', 'oldVal'); const newCollection = new TranslationCollection({ newKey: 'newVal' }); expect(collection.union(newCollection).values).to.deep.equal({ oldKey: 'oldVal', newKey: 'newVal' }); }); it('should intersect with passed collection', () => { collection = collection.addKeys(['red', 'green', 'blue']); const newCollection = new TranslationCollection( { red: '', blue: '' }); expect(collection.intersect(newCollection).values).to.deep.equal({ red: '', blue: '' }); }); it('should intersect with passed collection and keep original values', () => { collection = new TranslationCollection({ red: 'rød', green: 'grøn', blue: 'blå' }); const newCollection = new TranslationCollection({ red: 'no value', blue: 'also no value' }); expect(collection.intersect(newCollection).values).to.deep.equal({ red: 'rød', blue: 'blå' }); }); it('should sort translations in alphabetical order', () => { collection = new TranslationCollection({ red: 'rød', green: 'grøn', blue: 'blå' }); collection = collection.sort(); expect(collection.keys()).deep.equal(['blue', 'green', 'red']); }); }); ngx-translate-extract-2.3.4/tsconfig.json000066400000000000000000000007341320060016100204570ustar00rootroot00000000000000{ "compilerOptions": { "allowSyntheticDefaultImports": true, "noUnusedLocals": true, "noImplicitAny": true, "removeComments": true, "declaration": true, "target": "es5", "lib": [ "dom", "es2015" ], "module": "commonjs", "outDir": "./dist/", "sourceMap": true }, "include": [ "src/**/*.ts" ], "exclude": [ "node_modules" ] } ngx-translate-extract-2.3.4/tslint.json000066400000000000000000000021211320060016100201500ustar00rootroot00000000000000{ "rulesDirectory": [ "node_modules/tslint-eslint-rules/dist/rules" ], "rules": { "indent": [true, "tabs"], "semicolon": [true, "always", "ignore-interfaces"], "quotemark": [true, "single", "avoid-escape"], "only-arrow-functions": false, "no-duplicate-variable": true, "member-access": true, "member-ordering": [ true, { "order": [ "public-static-field", "public-static-method", "protected-static-field", "protected-static-method", "private-static-field", "private-static-method", "public-instance-field", "protected-instance-field", "private-instance-field", "constructor", "public-instance-method", "protected-instance-method", "private-instance-method" ] } ], "curly": true, "eofline": true, "no-trailing-whitespace": true, "trailing-comma": [ true, { "multiline": "never", "singleline": "never" } ], "whitespace": [ true, "check-branch", "check-decl", "check-operator", "check-module", "check-separator", "check-type", "check-typecast" ] } }