{"id":311197,"date":"2020-10-09T09:00:23","date_gmt":"2020-10-09T09:00:23","guid":{"rendered":"http:\/\/savepearlharbor.com\/?p=311197"},"modified":"-0001-11-30T00:00:00","modified_gmt":"2020-10-09T09:00:23","slug":"","status":"publish","type":"post","link":"https:\/\/savepearlharbor.com\/?p=311197","title":{"rendered":"\u041f\u043e\u043f\u0443\u043b\u044f\u0440\u043d\u044b\u0435 npm-\u043f\u0430\u043a\u0435\u0442\u044b. Volume 1"},"content":{"rendered":"\n<div class=\"post__text post__text-html post__text_v1\" id=\"post-content-body\" data-io-article-url=\"https:\/\/habr.com\/ru\/post\/522700\/\">\u0414\u043e\u0431\u0440\u043e\u0433\u043e \u0432\u0440\u0435\u043c\u0435\u043d\u0438 \u0441\u0443\u0442\u043e\u043a, \u0434\u0440\u0443\u0437\u044c\u044f!<\/p>\n<p>  \u041f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u043b\u044f\u044e \u0432\u0430\u0448\u0435\u043c\u0443 \u0432\u043d\u0438\u043c\u0430\u043d\u0438\u044e \u043f\u043e\u0434\u0431\u043e\u0440\u043a\u0443 \u0438\u0437 \u0434\u0435\u0441\u044f\u0442\u0438 \u043f\u043e\u043f\u0443\u043b\u044f\u0440\u043d\u044b\u0445 npm-\u043f\u0430\u043a\u0435\u0442\u043e\u0432 \u0441 \u043f\u0440\u0438\u043c\u0435\u0440\u0430\u043c\u0438 \u0438\u0445 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u044f \u0438 \u0430\u043b\u044c\u0442\u0435\u0440\u043d\u0430\u0442\u0438\u0432\u043d\u044b\u043c\u0438 \u0440\u0435\u0448\u0435\u043d\u0438\u044f\u043c\u0438.<\/p>\n<p>  \u041f\u0440\u0435\u0434\u043f\u043e\u043b\u0430\u0433\u0430\u0435\u0442\u0441\u044f, \u0447\u0442\u043e \u0432\u044b \u0445\u043e\u0440\u043e\u0448\u043e \u0437\u043d\u0430\u043a\u043e\u043c\u044b \u0441 JavaScript \u0438, \u0432 \u0447\u0430\u0441\u0442\u043d\u043e\u0441\u0442\u0438, \u0441 Node.js.<\/p>\n<p>  \u0412 \u0434\u0430\u043d\u043d\u043e\u043c \u0447\u0430\u0441\u0442\u0438 \u043f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u043b\u0435\u043d\u044b \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u0435 \u043f\u0430\u043a\u0435\u0442\u044b:<\/p>\n<ul>\n<li><a href=\"#chalk\">chalk<\/a><\/li>\n<li><a href=\"#progress\">progress<\/a><\/li>\n<li><a href=\"#minimist\">minimist<\/a><\/li>\n<li><a href=\"#fs-extra\">fs-extra<\/a><\/li>\n<li><a href=\"#uuid\">uuid<\/a><\/li>\n<li><a href=\"#moment\">moment<\/a><\/li>\n<li><a href=\"#axios\">axios<\/a><\/li>\n<li><a href=\"#async\">async<\/a><\/li>\n<li><a href=\"#dotenv\">dotenv<\/a><\/li>\n<li><a href=\"#validator\">validator<\/a><\/li>\n<\/ul>\n<p>  <a name=\"habracut\"><\/a><br \/>  <a name=\"chalk\"><\/a><\/p>\n<h3><a href=\"https:\/\/www.npmjs.com\/package\/chalk\" rel=\"nofollow\">chalk<\/a><\/h3>\n<p>  \u0415\u0436\u0435\u043d\u0435\u0434\u0435\u043b\u044c\u043d\u044b\u0435 \u0437\u0430\u0433\u0440\u0443\u0437\u043a\u0438: 58 \u043c\u043b\u043d.<\/p>\n<p>  \u041d\u0430\u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435: \u0444\u043e\u0440\u043c\u0430\u0442\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u0435 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0439, \u0432\u044b\u0432\u043e\u0434\u0438\u043c\u044b\u0445 \u0432 \u0442\u0435\u0440\u043c\u0438\u043d\u0430\u043b.<\/p>\n<p>  \u041f\u0440\u0438\u043c\u0435\u0440 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u044f.<\/p>\n<p>  \u0423\u0441\u0442\u0430\u043d\u0430\u0432\u043b\u0438\u0432\u0430\u0435\u043c \u043f\u0430\u043a\u0435\u0442: yarn add chalk \u0438\u043b\u0438 npm i chalk.<\/p>\n<p>  \u0421\u043e\u0437\u0434\u0430\u0435\u043c \u0444\u0430\u0439\u043b chalk.js:<\/p>\n<pre><code class=\"javascript\">const chalk = require(&quot;chalk&quot;); const log = console.log;  log( \tchalk.red(&quot;\u0421\u0442\u0440\u043e\u043a\u0430 \u043a\u0440\u0430\u0441\u043d\u043e\u0433\u043e \u0446\u0432\u0435\u0442\u0430\\n&quot;) + \tchalk.green(&quot;\u0421\u0442\u0440\u043e\u043a\u0430 \u0437\u0435\u043b\u0435\u043d\u043e\u0433\u043e \u0446\u0432\u0435\u0442\u0430\\n&quot;) + \tchalk.blue(&quot;\u0421\u0442\u0440\u043e\u043a\u0430 \u0441\u0438\u043d\u0435\u0433\u043e \u0446\u0432\u0435\u0442\u0430&quot;) );  \/\/ \u0448\u0430\u0431\u043b\u043e\u043d\u043d\u044b\u0435 \u043b\u0438\u0442\u0435\u0440\u0430\u043b\u044b const os = require(&quot;os&quot;);  log(` \tTotal memory: ${chalk.blue(os.totalmem())} bytes \tFree memory: ${chalk.green(os.freemem())} bytes \tMemory used: ${chalk.red(os.totalmem() - os.freemem())} bytes `);  \/\/ \u0442\u0435\u0433\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u044b\u0435 \u0448\u0430\u0431\u043b\u043e\u043d\u043d\u044b\u0435 \u043b\u0438\u0442\u0435\u0440\u0430\u043b\u044b const v8 = require(&quot;v8&quot;);  const { \ttotal_heap_size: total, \tused_heap_size: used, \theap_size_limit: limit, } = v8.getHeapStatistics();  log(chalk` \tHeap Size Limit: {rgb(0, 0, 255) ${limit}} \tTotal Heap Size: {hex('#008000') ${total}} \tUsed Heap Size: {red ${used}} `); <\/code><\/pre>\n<p>  \u0417\u0430\u043f\u0443\u0441\u043a\u0430\u0435\u043c \u0441\u043a\u0440\u0438\u043f\u0442: node chalk.js.<\/p>\n<p>  <img decoding=\"async\" src=\"https:\/\/habrastorage.org\/webt\/b_\/v4\/th\/b_v4thcnkv6ngeaj-1l2np4vggm.png\"><\/p>\n<p>  \u0410\u043b\u044c\u0442\u0435\u0440\u043d\u0430\u0442\u0438\u0432\u0430: <a href=\"https:\/\/gist.github.com\/iamnewton\/8754917\" rel=\"nofollow\">\u043e\u0431\u0440\u0430\u0442\u043d\u044b\u0435 \u043f\u043e\u0441\u043b\u0435\u0434\u043e\u0432\u0430\u0442\u0435\u043b\u044c\u043d\u043e\u0441\u0442\u0438 (escape sequences):<\/a><\/p>\n<pre><code class=\"javascript\">console.log( \t&quot;[31m%s[0m[32m%s[0m[34m%s[0m&quot;, \t&quot;\u0421\u0442\u0440\u043e\u043a\u0430 \u043a\u0440\u0430\u0441\u043d\u043e\u0433\u043e \u0446\u0432\u0435\u0442\u0430\\n&quot;, \t&quot;\u0421\u0442\u0440\u043e\u043a\u0430 \u0437\u0435\u043b\u0435\u043d\u043e\u0433\u043e \u0446\u0432\u0435\u0442\u0430\\n&quot;, \t&quot;\u0421\u0442\u0440\u043e\u043a\u0430 \u0441\u0438\u043d\u0435\u0433\u043e \u0446\u0432\u0435\u0442\u0430&quot; ); <\/code><\/pre>\n<p>  <a name=\"progress\"><\/a><\/p>\n<h3><a href=\"https:\/\/www.npmjs.com\/package\/progress\" rel=\"nofollow\">progress<\/a><\/h3>\n<p>  \u0415\u0436\u0435\u043d\u0435\u0434\u0435\u043b\u044c\u043d\u044b\u0435 \u0437\u0430\u0433\u0440\u0443\u0437\u043a\u0438: 13 \u043c\u043b\u043d.<\/p>\n<p>  \u041d\u0430\u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435: \u00ab\u0442\u0435\u0440\u043c\u0438\u043d\u0430\u043b\u044c\u043d\u044b\u0439\u00bb \u0438\u043d\u0434\u0438\u043a\u0430\u0442\u043e\u0440 \u043f\u0440\u043e\u0433\u0440\u0435\u0441\u0441\u0430 (ASCII-\u0441\u0438\u043c\u0432\u043e\u043b\u044b).<\/p>\n<p>  \u041f\u0440\u0438\u043c\u0435\u0440 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u044f.<\/p>\n<p>  \u0423\u0441\u0442\u0430\u043d\u0430\u0432\u043b\u0438\u0432\u0430\u0435\u043c \u043f\u0430\u043a\u0435\u0442: yarn add progress.<\/p>\n<p>  \u0421\u043e\u0437\u0434\u0430\u0435\u043c \u0444\u0430\u0439\u043b progress.js:<\/p>\n<pre><code class=\"javascript\">const ProgressBar = require(&quot;progress&quot;);  const bar = new ProgressBar(&quot;:bar&quot;, { total: 10 }); const timer = setInterval(() =&gt; { \tbar.tick(); \tif (bar.complete) { \t\tconsole.log(&quot;\\n\u041f\u043e\u0442\u0440\u0430\u0447\u0435\u043d\u043e&quot;); \t\tclearInterval(timer); \t} }, 200); <\/code><\/pre>\n<p>  \u0417\u0430\u043f\u0443\u0441\u043a\u0430\u0435\u043c \u0441\u043a\u0440\u0438\u043f\u0442: node progress.js<\/p>\n<p>  <img decoding=\"async\" src=\"https:\/\/habrastorage.org\/webt\/ek\/j6\/0y\/ekj60yywurtamvs3fcwv0w-ba7u.png\"><\/p>\n<p>  One more example:<\/p>\n<pre><code class=\"javascript\">const ProgressBar = require(&quot;progress&quot;); const https = require(&quot;https&quot;);  const req = https.request({ \thost: &quot;example.com&quot;, \tport: 443, \tpath: &quot;\/filename.ext&quot;, });  req.on(&quot;response&quot;, (res) =&gt; { \tconst len = parseInt(res.headers[&quot;content-length&quot;], 10);  \tconsole.log();  \tconst bar = new ProgressBar( \t\t&quot;  \u0437\u0430\u0433\u0440\u0443\u0437\u043a\u0430 [:bar] :rate\/bps :percent :etas&quot;, \t\t{ \t\t\tcomplete: &quot;=&quot;, \t\t\tincomplete: &quot; &quot;, \t\t\twidth: 20, \t\t\ttotal: len, \t\t} \t);  \tres.on(&quot;data&quot;, (chunk) =&gt; { \t\tbar.tick(chunk.length); \t});  \tres.on(&quot;end&quot;, () =&gt; { \t\tconsole.log(&quot;\\n\u041f\u043e\u0442\u0440\u0430\u0447\u0435\u043d\u043e&quot;); \t}); });  req.end(); <\/code><\/pre>\n<p>  <a name=\"minimist\"><\/a><\/p>\n<h3><a href=\"https:\/\/www.npmjs.com\/package\/minimist\" rel=\"nofollow\">minimist<\/a><\/h3>\n<p>  \u0415\u0436\u0435\u043d\u0435\u0434\u0435\u043b\u044c\u043d\u044b\u0435 \u0437\u0430\u0433\u0440\u0443\u0437\u043a\u0438: 35 \u043c\u043b\u043d.<\/p>\n<p>  \u041d\u0430\u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435: \u0440\u0430\u0437\u0431\u043e\u0440 \u0430\u0440\u0433\u0443\u043c\u0435\u043d\u0442\u043e\u0432, \u043f\u0435\u0440\u0435\u0434\u0430\u0432\u0430\u0435\u043c\u044b\u0445 \u0447\u0435\u0440\u0435\u0437 \u0442\u0435\u0440\u043c\u0438\u043d\u0430\u043b.<\/p>\n<p>  \u041f\u0440\u0438\u043c\u0435\u0440 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u044f.<\/p>\n<p>  \u0423\u0441\u0442\u0430\u043d\u0430\u0432\u043b\u0438\u0432\u0430\u0435\u043c \u043f\u0430\u043a\u0435\u0442: yarn add minimist.<\/p>\n<p>  \u0421\u043e\u0437\u0434\u0430\u0435\u043c \u0444\u0430\u0439\u043b minimist.js:<\/p>\n<pre><code class=\"javascript\">const args = require(&quot;minimist&quot;)(process.argv.slice(2)); console.log(args); console.log(args._); console.log(args.a); <\/code><\/pre>\n<p>  \u0417\u0430\u043f\u0443\u0441\u043a\u0430\u0435\u043c \u0441\u043a\u0440\u0438\u043f\u0442: node script.js foo bar baz -x 1 -y2 &#8212;z=3 -a<\/p>\n<p>  <img decoding=\"async\" src=\"https:\/\/habrastorage.org\/webt\/56\/nm\/bx\/56nmbxzomu7wbcus3z-nqf2dyne.png\"><\/p>\n<p>  <a name=\"fs-extra\"><\/a><\/p>\n<h3><a href=\"https:\/\/www.npmjs.com\/package\/fs-extra\" rel=\"nofollow\">fs-extra<\/a><\/h3>\n<p>  \u0415\u0436\u0435\u043d\u0435\u0434\u0435\u043b\u044c\u043d\u044b\u0435 \u0437\u0430\u0433\u0440\u0443\u0437\u043a\u0438: 32 \u043c\u043b\u043d.<\/p>\n<p>  \u041d\u0430\u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435: \u0434\u043e\u043f\u043e\u043b\u043d\u0438\u0442\u0435\u043b\u044c\u043d\u044b\u0435 \u043c\u0435\u0442\u043e\u0434\u044b \u043f\u043e \u0440\u0430\u0431\u043e\u0442\u0435 \u0441 \u0444\u0430\u0439\u043b\u043e\u0432\u043e\u0439 \u0441\u0438\u0441\u0442\u0435\u043c\u043e\u0439 (\u0440\u0430\u0441\u0448\u0438\u0440\u0435\u043d\u0438\u0435 fs).<\/p>\n<p>  \u041e\u0441\u043d\u043e\u0432\u043d\u044b\u0435 \u043c\u0435\u0442\u043e\u0434\u044b:<\/p>\n<ul>\n<li>copy \u2014 \u043a\u043e\u043f\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u0435 \u0444\u0430\u0439\u043b\u043e\u0432<\/li>\n<li>emptyDir \u2014 \u043e\u0447\u0438\u0441\u0442\u043a\u0430 \u0434\u0438\u0440\u0435\u043a\u0442\u043e\u0440\u0438\u0438. \u0415\u0441\u043b\u0438 \u0434\u0438\u0440\u0435\u043a\u0442\u043e\u0440\u0438\u0438 \u043d\u0435 \u0441\u0443\u0449\u0435\u0441\u0442\u0432\u0443\u0435\u0442, \u043e\u043d\u0430 \u0441\u043e\u0437\u0434\u0430\u0435\u0442\u0441\u044f<\/li>\n<li>ensureFile \u2014 \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0435\u043d\u0438\u0435 \u043d\u0430\u043b\u0438\u0447\u0438\u044f \u0444\u0430\u0439\u043b\u0430. \u0415\u0441\u043b\u0438 \u0432\u044b\u043f\u043e\u043b\u043d\u044f\u0435\u0442\u0441\u044f \u0437\u0430\u043f\u0440\u043e\u0441 \u043d\u0430 \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u0435 \u0444\u0430\u0439\u043b\u0430 \u0432 \u0434\u0438\u0440\u0435\u043a\u0442\u043e\u0440\u0438\u044f\u0445, \u043a\u043e\u0442\u043e\u0440\u044b\u0445 \u043d\u0435 \u0441\u0443\u0449\u0435\u0441\u0442\u0432\u0443\u0435\u0442, \u043e\u043d\u0438 \u0441\u043e\u0437\u0434\u0430\u044e\u0442\u0441\u044f<\/li>\n<li>ensureDir \u2014 \u0442\u043e\u0436\u0435 \u0441\u0430\u043c\u043e\u0435 \u043f\u0440\u0438\u043c\u0435\u043d\u0438\u0442\u0435\u043b\u044c\u043d\u043e \u043a \u0434\u0438\u0440\u0435\u043a\u0442\u043e\u0440\u0438\u0438. \u0410\u043b\u0438\u0430\u0441\u044b \u2014 mkdirs, mkdirp<\/li>\n<li>move \u2014 \u043f\u0435\u0440\u0435\u043c\u0435\u0449\u0435\u043d\u0438\u0435 \u0444\u0430\u0439\u043b\u0430 \u0438\u043b\u0438 \u0434\u0438\u0440\u0435\u043a\u0442\u043e\u0440\u0438\u0438<\/li>\n<li>outputFile \u2014 \u0430\u043d\u0430\u043b\u043e\u0433\u0438\u0447\u043d\u043e fs.writeFile, \u0437\u0430 \u0438\u0441\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u0435\u043c \u0442\u043e\u0433\u043e, \u0447\u0442\u043e \u043f\u0440\u0438 \u043e\u0442\u0441\u0443\u0442\u0441\u0442\u0432\u0438\u0438 \u0441\u043e\u0437\u0434\u0430\u0435\u0442\u0441\u044f \u0440\u043e\u0434\u0438\u0442\u0435\u043b\u044c\u0441\u043a\u0430\u044f \u0434\u0438\u0440\u0435\u043a\u0442\u043e\u0440\u0438\u044f<\/li>\n<li>outputJson \u2014 \u0430\u043d\u0430\u043b\u043e\u0433\u0438\u0447\u043d\u043e fs.writeJson, \u0437\u0430 \u0438\u0441\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u0435\u043c \u0442\u043e\u0433\u043e, \u0447\u0442\u043e \u043f\u0440\u0438 \u043e\u0442\u0441\u0443\u0442\u0441\u0442\u0432\u0438\u0438 \u0441\u043e\u0437\u0434\u0430\u0435\u0442\u0441\u044f \u0440\u043e\u0434\u0438\u0442\u0435\u043b\u044c\u0441\u043a\u0430\u044f \u0434\u0438\u0440\u0435\u043a\u0442\u043e\u0440\u0438\u044f<\/li>\n<li>readJson \u2014 \u0447\u0442\u0435\u043d\u0438\u0435 JSON-\u0444\u0430\u0439\u043b\u0430 \u0438 \u0435\u0433\u043e \u043f\u0440\u0435\u043e\u0431\u0440\u0430\u0437\u043e\u0432\u0430\u043d\u0438\u0435 \u0432 \u043e\u0431\u044a\u0435\u043a\u0442<\/li>\n<li>remove \u2014 \u0443\u0434\u0430\u043b\u0435\u043d\u0438\u0435 \u0444\u0430\u0439\u043b\u0430 \u0438\u043b\u0438 \u0434\u0438\u0440\u0435\u043a\u0442\u043e\u0440\u0438\u0438<\/li>\n<li>writeJson \u2014 \u0437\u0430\u043f\u0438\u0441\u044c \u043e\u0431\u044a\u0435\u043a\u0442\u0430 \u0432 JSON-\u0444\u0430\u0439\u043b<\/li>\n<\/ul>\n<p>  \u041f\u0440\u0438\u0432\u0435\u0434\u0435\u043d\u043d\u044b\u0435 \u043c\u0435\u0442\u043e\u0434\u044b \u044f\u0432\u043b\u044f\u044e\u0442\u0441\u044f \u0430\u0441\u0438\u043d\u0445\u0440\u043e\u043d\u043d\u044b\u043c\u0438, \u0441\u0443\u0449\u0435\u0441\u0442\u0432\u0443\u044e\u0442 \u0438\u0445 \u0441\u0438\u043d\u0445\u0440\u043e\u043d\u043d\u044b\u0435 \u0430\u043d\u0430\u043b\u043e\u0433\u0438 (\u0441 \u043f\u0440\u0438\u0441\u0442\u0430\u0432\u043a\u043e\u0439 \u00abSync\u00bb).<\/p>\n<p>  \u041c\u0435\u0442\u043e\u0434\u044b \u043c\u043e\u0433\u0443\u0442 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c\u0441\u044f \u0441 \u0444\u0443\u043d\u043a\u0446\u0438\u044f\u043c\u0438 \u043e\u0431\u0440\u0430\u0442\u043d\u043e\u0433\u043e \u0432\u044b\u0437\u043e\u0432\u0430, \u043f\u0440\u043e\u043c\u0438\u0441\u0430\u043c\u0438 \u0438 async\/await. \u042f \u0431\u0443\u0434\u0443 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u043f\u0440\u043e\u043c\u0438\u0441\u044b.<\/p>\n<pre><code class=\"javascript\">const fs = require(&quot;fs-extra&quot;);  \/\/ copy fs.copy(&quot;\/old-file&quot;, &quot;\/dir\/new-file&quot;) \t.then(() =&gt; { \t\tconsole.log(&quot;\u043f\u043e\u043b\u0443\u0447\u0438\u043b\u043e\u0441\u044c!&quot;); \t}) \t.catch((err) =&gt; { \t\tconsole.error(err); \t});  \/\/ emptyDir fs.emptyDir(&quot;\/some\/empty\/dir&quot;) \t.then(() =&gt; { \t\tconsole.log(&quot;\u043f\u043e\u043b\u0443\u0447\u0438\u043b\u043e\u0441\u044c!&quot;); \t}) \t.catch((err) =&gt; { \t\tconsole.error(err); \t});  \/\/ ensureFile const file = &quot;\/this\/path\/does\/not\/exist\/file.txt&quot;;  fs.ensureFile(file) \t.then(() =&gt; { \t\tconsole.log(&quot;\u043f\u043e\u043b\u0443\u0447\u0438\u043b\u043e\u0441\u044c!&quot;); \t}) \t.catch((err) =&gt; { \t\tconsole.error(err); \t});  \/\/ move const src = &quot;\/dir\/file.txt&quot;; const dest = &quot;\/dir\/this\/path\/does\/not\/exist\/file.txt&quot;;  fs.move(src, dest) \t.then(() =&gt; { \t\tconsole.log(&quot;\u043f\u043e\u043b\u0443\u0447\u0438\u043b\u043e\u0441\u044c!&quot;); \t}) \t.catch((err) =&gt; { \t\tconsole.error(err); \t});  \/\/ outputFile const file = &quot;\/this\/path\/does\/not\/exist\/file.txt&quot;; fs.outputFile(file, &quot;\u043f\u0440\u0438\u0432\u0435\u0442!&quot;) \t.then(() =&gt; fs.readFile(file, &quot;utf8&quot;)) \t.then((data) =&gt; { \t\tconsole.log(data); \/\/ =&gt; \u043f\u0440\u0438\u0432\u0435\u0442! \t}) \t.catch((err) =&gt; { \t\tconsole.error(err); \t});  \/\/ readJson fs.readJson(&quot;\/data.json&quot;) \t.then((obj) =&gt; { \t\tconsole.log(obj.someKey); \/\/ =&gt; some value \t}) \t.catch((err) =&gt; { \t\tconsole.error(err); \t});  \/\/ remove fs.remove(&quot;\/dir\/file&quot;) \t.then(() =&gt; { \t\tconsole.log(&quot;\u043f\u043e\u043b\u0443\u0447\u0438\u043b\u043e\u0441\u044c!&quot;); \t}) \t.catch((err) =&gt; { \t\tconsole.error(err); \t});  \/\/ writeJson fs.writeJson(&quot;\/data.json&quot;, { someKey: &quot;some value&quot; }) \t.then(() =&gt; { \t\tconsole.log(&quot;\u043f\u043e\u043b\u0443\u0447\u0438\u043b\u043e\u0441\u044c!&quot;); \t}) \t.catch((err) =&gt; { \t\tconsole.error(err); \t}); <\/code><\/pre>\n<p>  <a name=\"uuid\"><\/a><\/p>\n<h3><a href=\"https:\/\/www.npmjs.com\/package\/uuid\" rel=\"nofollow\">uuid<\/a><\/h3>\n<p>  \u0415\u0436\u0435\u043d\u0435\u0434\u0435\u043b\u044c\u043d\u044b\u0435 \u0437\u0430\u0433\u0440\u0443\u0437\u043a\u0438: 36 \u043c\u043b\u043d.<\/p>\n<p>  \u041d\u0430\u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435: \u0433\u0435\u043d\u0435\u0440\u0430\u0446\u0438\u044f \u0443\u043d\u0438\u043a\u0430\u043b\u044c\u043d\u043e\u0433\u043e \u0438\u0434\u0435\u043d\u0442\u0438\u0444\u0438\u043a\u0430\u0442\u043e\u0440\u0430.<\/p>\n<p>  \u041f\u0440\u0438\u043c\u0435\u0440 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u044f.<\/p>\n<p>  \u0421\u043e\u0437\u0434\u0430\u0434\u0438\u043c \u0441\u0435\u0440\u0432\u0435\u0440 \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e express, \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u044e\u0449\u0438\u0439 \u0438\u0434\u0435\u043d\u0442\u0438\u0444\u0438\u043a\u0430\u0442\u043e\u0440 \u043f\u043e \u0437\u0430\u043f\u0440\u043e\u0441\u0443 \u043a\u043b\u0438\u0435\u043d\u0442\u0430.<\/p>\n<p>  \u0423\u0441\u0442\u0430\u043d\u0430\u0432\u043b\u0438\u0432\u0430\u0435\u043c uuid, express \u0438 cors: yarn add uuid express cors.<\/p>\n<p>  \u0421\u043e\u0437\u0434\u0430\u0435\u043c \u0444\u0430\u0439\u043b uuid.js:<\/p>\n<pre><code class=\"javascript\">const express = require(&quot;express&quot;); const cors = require(&quot;cors&quot;);  const { v4: uuidv4 } = require(&quot;uuid&quot;);  const app = express(); app.use(cors());  app.use(&quot;\/getId&quot;, (_, res) =&gt; { \t\/\/ \u0433\u0435\u043d\u0435\u0440\u0438\u0440\u0443\u0435\u043c \u0438\u0434\u0435\u043d\u0442\u0438\u0444\u0438\u043a\u0430\u0442\u043e\u0440 \tconst id = uuidv4(); \t\/\/ \u043e\u0442\u043f\u0440\u0430\u0432\u043b\u044f\u0435\u043c \u0435\u0433\u043e \u043a\u043b\u0438\u0435\u043d\u0442\u0443 \tres.json(id); });  app.listen(process.env.PORT || 3000, () =&gt; console.log(&quot;server ready&quot;)); <\/code><\/pre>\n<p>  \u0417\u0430\u043f\u0443\u0441\u043a\u0430\u0435\u043c \u0441\u0435\u0440\u0432\u0435\u0440: node uuid.js.<\/p>\n<p>  \u0421\u043e\u0437\u0434\u0430\u0435\u043c \u0444\u0430\u0439\u043b index.html:<\/p>\n<pre><code class=\"javascript\">&lt;body&gt; \t&lt;input type=&quot;text&quot; \/&gt; \t&lt;button&gt;add&lt;\/button&gt; \t&lt;ul&gt;&lt;\/ul&gt;  \t&lt;script&gt; \t\tconst button = document.querySelector(&quot;button&quot;); \t\tconst input = document.querySelector(&quot;input&quot;); \t\tconst list = document.querySelector(&quot;ul&quot;);  \t\tbutton.addEventListener(&quot;click&quot;, async () =&gt; { \t\t\t\/\/ \u0437\u0430\u043f\u0440\u0430\u0448\u0438\u0432\u0430\u0435\u043c \u0438\u0434\u0435\u043d\u0442\u0438\u0444\u0438\u043a\u0430\u0442\u043e\u0440 \t\t\tconst res = await fetch(&quot;http:\/\/localhost:3000\/getId&quot;); \t\t\tconst id = await res.json();  \t\t\tconst value = input.value;  \t\t\tif (value.trim() !== &quot;&quot;) { \t\t\t\tlist.insertAdjacentHTML( \t\t\t\t\t&quot;beforeend&quot;, \t\t\t\t\t\/\/ \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u043c \u0438\u0434\u0435\u043d\u0442\u0438\u0444\u0438\u043a\u0430\u0442\u043e\u0440 \t\t\t\t\t`&lt;li data-id=${id}&gt;${value}&lt;\/li&gt;` \t\t\t\t); \t\t\t} \t\t});  \t\tinput.value = &quot;\u0430\u043f\u0442\u0435\u043a\u0430, \u0443\u043b\u0438\u0446\u0430, \u0444\u043e\u043d\u0430\u0440\u044c...&quot;; \t\tbutton.click(); \t&lt;\/script&gt; &lt;\/body&gt; <\/code><\/pre>\n<p>  \u041e\u0442\u043a\u0440\u044b\u0432\u0430\u0435\u043c index.html \u0432 \u0431\u0440\u0430\u0443\u0437\u0435\u0440\u0435.<\/p>\n<p>  <img decoding=\"async\" src=\"https:\/\/habrastorage.org\/webt\/it\/sh\/f_\/itshf_9si2z4nz-f0uyffohvq2y.png\"><\/p>\n<p>  \u0412 \u043a\u0430\u0447\u0435\u0441\u0442\u0432\u0435 \u0430\u043b\u044c\u0442\u0435\u0440\u043d\u0430\u0442\u0438\u0432\u044b \u0432 \u043f\u0440\u043e\u0441\u0442\u044b\u0445 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f\u0445 \u043c\u043e\u0436\u043d\u043e \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u043c\u0435\u0442\u043e\u0434 \u00abDate.now()\u00bb, \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u044e\u0449\u0438\u0439 \u043a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e \u043c\u0438\u043b\u043b\u0438\u0441\u0435\u043a\u0443\u043d\u0434, \u043f\u0440\u043e\u0448\u0435\u0434\u0448\u0438\u0445 \u0441 1 \u044f\u043d\u0432\u0430\u0440\u044f 1970 \u0433\u043e\u0434\u0430:<\/p>\n<pre><code class=\"javascript\">const id1 = Date.now(); console.log(id1); \/\/ 1601905165758 console.log(typeof id1); \/\/ number  const id2 = Date.now().toString().slice(-4); console.log(id2); \/\/ 5758 <\/code><\/pre>\n<p>  <a name=\"moment\"><\/a><\/p>\n<h3><a href=\"https:\/\/www.npmjs.com\/package\/moment\" rel=\"nofollow\">moment<\/a><\/h3>\n<p>  \u0415\u0436\u0435\u043d\u0435\u0434\u0435\u043b\u044c\u043d\u044b\u0435 \u0437\u0430\u0433\u0440\u0443\u0437\u043a\u0438: 14 \u043c\u043b\u043d.<\/p>\n<p>  \u041d\u0430\u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435: \u0444\u043e\u0440\u043c\u0430\u0442\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u0435 \u0434\u0430\u0442\u044b \u0438 \u0432\u0440\u0435\u043c\u0435\u043d\u0438.<\/p>\n<p>  \u041f\u0440\u0438\u043c\u0435\u0440 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u044f.<\/p>\n<pre><code class=\"javascript\">const moment = require(&quot;moment&quot;);  console.log( \t` \t\t${moment().format()} \t\t${moment().format(&quot;DD.MM.YYYY H:m&quot;)} \t` ); \/* \t2020-10-05T19:16:38+05:00 \t05.10.2020 19:16 *\/  moment.locale(&quot;ru&quot;);  console.log(moment().format(&quot;dddd, Do MMMM Y&quot;)); \/\/ \u043f\u043e\u043d\u0435\u0434\u0435\u043b\u044c\u043d\u0438\u043a, 5-\u0433\u043e \u043e\u043a\u0442\u044f\u0431\u0440\u044f 2020 <\/code><\/pre>\n<p>  \u0410\u043b\u044c\u0442\u0435\u0440\u043d\u0430\u0442\u0438\u0432\u0430: \u043a\u043e\u043d\u0441\u0442\u0440\u0443\u043a\u0442\u043e\u0440\u044b Date \u0438 Intl.DateTimeFormat.<\/p>\n<pre><code class=\"javascript\">const date = new Date();  const options = { \tday: &quot;numeric&quot;, \tmonth: &quot;long&quot;, \tyear: &quot;numeric&quot;, };  console.log(date.toLocaleString(&quot;ru&quot;, options)); \/\/ 5 \u043e\u043a\u0442\u044f\u0431\u0440\u044f 2020 \u0433.  options.weekday = &quot;long&quot;; options.hour = &quot;numeric&quot;; options.minute = &quot;numeric&quot;;  console.log( \tnew Intl.DateTimeFormat(&quot;ru&quot;, options).format(date) ); \/\/ \u043f\u043e\u043d\u0435\u0434\u0435\u043b\u044c\u043d\u0438\u043a, 5 \u043e\u043a\u0442\u044f\u0431\u0440\u044f 2020 \u0433., 19:42 <\/code><\/pre>\n<p>  \u0420\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u043a\u0430 moment \u0432 \u043d\u0430\u0441\u0442\u043e\u044f\u0449\u0435\u0435 \u0432\u0440\u0435\u043c\u044f \u043f\u0440\u0435\u043a\u0440\u0430\u0449\u0435\u043d\u0430.<\/p>\n<p>  <a name=\"axios\"><\/a><\/p>\n<h3><a href=\"https:\/\/www.npmjs.com\/package\/axios\" rel=\"nofollow\">axios<\/a><\/h3>\n<p>  \u0415\u0436\u0435\u043d\u0435\u0434\u0435\u043b\u044c\u043d\u044b\u0435 \u0437\u0430\u0433\u0440\u0443\u0437\u043a\u0438: 12 \u043c\u043b\u043d.<\/p>\n<p>  \u041d\u0430\u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435: \u043e\u0442\u043f\u0440\u0430\u0432\u043a\u0430 HTTP-\u0437\u0430\u043f\u0440\u043e\u0441\u043e\u0432. \u0420\u0430\u0431\u043e\u0442\u0430\u0435\u0442 \u043a\u0430\u043a \u0432 Node.js, \u0442\u0430\u043a \u0438 \u0432 \u0431\u0440\u0430\u0443\u0437\u0435\u0440\u0435.<\/p>\n<p>  \u041f\u0440\u0438\u043c\u0435\u0440 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u044f.<\/p>\n<p>  \u0423\u0441\u0442\u0430\u043d\u0430\u0432\u043b\u0438\u0432\u0430\u0435\u043c \u043f\u0430\u043a\u0435\u0442: yarn add axios.<\/p>\n<p>  \u0421\u043e\u0437\u0434\u0430\u0435\u043c \u0444\u0430\u0439\u043b axios.js:<\/p>\n<pre><code class=\"javascript\">\/\/ GET const axios = require(&quot;axios&quot;);  (async () =&gt; { \ttry { \t\tconst res = await axios.get( \t\t\t&quot;https:\/\/jsonplaceholder.typicode.com\/users&quot; \t\t); \t\tconsole.table(res.data); \t} catch (er) { \t\tconsole.error(er); \t} })(); <\/code><\/pre>\n<p>  \u0417\u0430\u043f\u0443\u0441\u043a\u0430\u0435\u043c \u0444\u0430\u0439\u043b: node axios.js.<\/p>\n<p>  <img decoding=\"async\" src=\"https:\/\/habrastorage.org\/webt\/hp\/zj\/bo\/hpzjbokgpzfjfnpnrqxmisthbri.png\"><\/p>\n<pre><code class=\"javascript\">\/\/ POST axios \t.post(&quot;\/user&quot;, { \t\tfirstName: &quot;Harry&quot;, \t\tlastName: &quot;Heman&quot;, \t}) \t.then((res) =&gt; { \t\tconsole.log(res); \t}) \t.catch((er) =&gt; { \t\tconsole.error(er); \t}); <\/code><\/pre>\n<p>  \u0420\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u044f GET-\u0437\u0430\u043f\u0440\u043e\u0441\u0430 \u043d\u0430 \u00ab\u0447\u0438\u0441\u0442\u043e\u043c\u00bb Node.js:<\/p>\n<pre><code class=\"javascript\">const https = require(&quot;https&quot;);  https \t.get(&quot;https:\/\/jsonplaceholder.typicode.com\/users&quot;, (res) =&gt; { \t\tlet data = &quot;&quot;;  \t\tres.on(&quot;data&quot;, (chunk) =&gt; { \t\t\tdata += chunk; \t\t});  \t\tres.on(&quot;end&quot;, () =&gt; { \t\t\tconsole.table(JSON.parse(data)); \t\t}); \t}) \t.on(&quot;error&quot;, (er) =&gt; { \t\tconsole.error(er.message); \t}); <\/code><\/pre>\n<p>  \u0412 \u0431\u0440\u0430\u0443\u0437\u0435\u0440\u0435 \u043c\u043e\u0436\u043d\u043e \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c Fetch API:<\/p>\n<pre><code class=\"javascript\">;(async () =&gt; { \tawait fetch(&quot;http:\/\/example.com\/user&quot;, { \t\tmethod: &quot;POST&quot;, \t\tmode: &quot;no-cors&quot;, \t\tbody: JSON.stringify({ \t\t\tfirstName: &quot;Harry&quot;, \t\t\tlastName: &quot;Heman&quot;, \t\t}), \t}); })(); <\/code><\/pre>\n<p>  \u0412 \u0441\u0435\u0442\u0438 \u043c\u043e\u0436\u043d\u043e \u0432\u0441\u0442\u0440\u0435\u0442\u0438\u0442\u044c \u0443\u043f\u043e\u043c\u0438\u043d\u0430\u043d\u0438\u0435 \u0434\u0440\u0443\u0433\u043e\u0433\u043e \u043f\u0430\u043a\u0435\u0442\u0430 \u0434\u043b\u044f \u043e\u0442\u043f\u0440\u0430\u0432\u043a\u0438 HTTP-\u0437\u0430\u043f\u0440\u043e\u0441\u043e\u0432 \u2014 request, \u043e\u0434\u043d\u0430\u043a\u043e \u0432 \u043d\u0430\u0441\u0442\u043e\u044f\u0449\u0435\u0435 \u0432\u0440\u0435\u043c\u044f \u043e\u043d \u043f\u0440\u0438\u0437\u043d\u0430\u043d \u0443\u0441\u0442\u0430\u0440\u0435\u0432\u0448\u0438\u043c.<\/p>\n<p>  <a name=\"async\"><\/a><\/p>\n<h3><a href=\"https:\/\/www.npmjs.com\/package\/async\" rel=\"nofollow\">async<\/a><\/h3>\n<p>  \u0415\u0436\u0435\u043d\u0435\u0434\u0435\u043b\u044c\u043d\u044b\u0435 \u0437\u0430\u0433\u0440\u0443\u0437\u043a\u0438: 31 \u043c\u043b\u043d.<\/p>\n<p>  \u041d\u0430\u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435: \u0443\u0442\u0438\u043b\u0438\u0442\u0430 \u0434\u043b\u044f \u0440\u0430\u0431\u043e\u0442\u044b \u0441 \u0430\u0441\u0438\u043d\u0445\u0440\u043e\u043d\u043d\u044b\u043c \u043a\u043e\u0434\u043e\u043c. \u0420\u0430\u0431\u043e\u0442\u0430\u0435\u0442 \u043a\u0430\u043a \u0432 Node.js, \u0442\u0430\u043a \u0438 \u0432 \u0431\u0440\u0430\u0443\u0437\u0435\u0440\u0435.<\/p>\n<p>  \u041f\u0440\u0438\u043c\u0435\u0440 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u044f.<\/p>\n<p>  \u0423\u0441\u0442\u0430\u043d\u0430\u0432\u043b\u0438\u0432\u0430\u0435\u043c \u043f\u0430\u043a\u0435\u0442: yarn add async.<\/p>\n<p>  \u0421\u043e\u0437\u0434\u0430\u0435\u043c 3 \u0444\u0430\u0439\u043b\u0430 (\u043d\u0430\u0437\u0432\u0430\u043d\u0438\u0435 -&gt; \u043a\u043e\u043d\u0442\u0435\u043d\u0442): file1.txt -&gt; foo, file2.txt -&gt; bar, file3.txt -&gt; baz qux.<\/p>\n<p>  \u0421\u043e\u0437\u0434\u0430\u0435\u043c \u0444\u0430\u0439\u043b async.js:<\/p>\n<pre><code class=\"javascript\">const async = require(&quot;async&quot;); const fs = require(&quot;fs&quot;);  const ext = &quot;txt&quot;; const file = (name) =&gt; `${__dirname}\/${name}.${ext}`;  \/\/ \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u044f\u0435\u043c \u0440\u0430\u0437\u043c\u0435\u0440\u044b \u0444\u0430\u0439\u043b\u043e\u0432 async.map( \t[file(&quot;file1&quot;), file(&quot;file2&quot;), file(&quot;file3&quot;)], \tfs.stat, \t(er, results) =&gt; { \t\tif (er) console.error(er);  \t\tconsole.log(results.map((item) =&gt; item.size)); \t} ); \/\/ [ 3, 3, 7 ]  \/\/ \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u044f\u0435\u043c \u0441\u043e\u0434\u0435\u0440\u0436\u0438\u043c\u043e\u0435 \u0444\u0430\u0439\u043b\u043e\u0432 async.map( \t[file(&quot;file1&quot;), file(&quot;file2&quot;), file(&quot;file3&quot;)], \tfs.readFile, \t(er, results) =&gt; { \t\tif (er) console.error(er);  \t\tconsole.log(results.map((item) =&gt; item.toString())); \t} ); \/\/ [ 'foo', 'bar', 'baz qux' ]  \/\/ \u043f\u0430\u0440\u0430\u043b\u043b\u0435\u043b\u044c\u043d\u043e\u0435 \u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u0435 \u0430\u0441\u0438\u043d\u0445\u0440\u043e\u043d\u043d\u044b\u0445 \u0444\u0443\u043d\u043a\u0446\u0438\u0439 const timer1 = () =&gt; setTimeout(() =&gt; console.log(&quot;foo&quot;), 300); const timer2 = () =&gt; setTimeout(() =&gt; console.log(&quot;bar&quot;), 100); const timer3 = () =&gt; setTimeout(() =&gt; console.log(&quot;baz&quot;), 200); const asyncFuntions = [timer1, timer2, timer3];  async.parallel(asyncFuntions, (er, res) =&gt; { \tconsole.log(res); }); \/\/ bar baz foo  \/\/ \u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u0435 \u043f\u043e\u0441\u043b\u0435\u0434\u043d\u0435\u0439 \u0430\u0441\u0438\u043d\u0445\u0440\u043e\u043d\u043d\u043e\u0439 \u0444\u0443\u043d\u043a\u0446\u0438\u0438 async.series(asyncFuntions, (_, res) =&gt; console.log(res)); \/\/ foo  \/\/ \u043a\u043e\u043c\u043f\u043e\u0437\u0438\u0446\u0438\u044f \u0438\u0437 \u0430\u0441\u0438\u043d\u0445\u0440\u043e\u043d\u043d\u044b\u0445 \u0444\u0443\u043d\u043a\u0446\u0438\u0439 const add1 = (n, cb) =&gt; setTimeout(() =&gt; cb(null, n + 1), 100); const sub2 = (n, cb) =&gt; setTimeout(() =&gt; cb(null, n - 2), 200); const mult3 = (n, cb) =&gt; setTimeout(() =&gt; cb(null, n * 3), 300);  const composed = async.compose(add1, sub2, mult3); \/\/ mult3 -&gt; sub2 -&gt; add1 composed(4, (_, res) =&gt; console.log(res)); \/\/ 11 <\/code><\/pre>\n<p>  <a name=\"dotenv\"><\/a><\/p>\n<h3><a href=\"https:\/\/www.npmjs.com\/package\/dotenv\" rel=\"nofollow\">dotenv<\/a><\/h3>\n<p>  \u0415\u0436\u0435\u043d\u0435\u0434\u0435\u043b\u044c\u043d\u044b\u0435 \u0437\u0430\u0433\u0440\u0443\u0437\u043a\u0438: 12 \u043c\u043b\u043d.<\/p>\n<p>  \u041d\u0430\u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435: \u0437\u0430\u0433\u0440\u0443\u0437\u043a\u0430 \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u044b\u0445 \u043e\u043a\u0440\u0443\u0436\u0435\u043d\u0438\u044f \u0438\u0437 \u0444\u0430\u0439\u043b\u0430 &quot;.env&quot; \u0432 process.env.<\/p>\n<p>  \u041f\u0440\u0438\u043c\u0435\u0440 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u044f.<\/p>\n<p>  \u0418\u043c\u0438\u0442\u0438\u0440\u0443\u0435\u043c \u043f\u043e\u0434\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u0435 \u043a MongoDB Cloud.<\/p>\n<p>  \u0423\u0441\u0442\u0430\u043d\u0430\u0432\u043b\u0438\u0432\u0430\u0435\u043c \u043f\u0430\u043a\u0435\u0442: yarn add dotenv.<\/p>\n<p>  \u0421\u043e\u0437\u0434\u0430\u0435\u043c \u0444\u0430\u0439\u043b &quot;.env&quot;:<\/p>\n<pre><code class=\"javascript\">\/\/ &lt;usename&gt;, &lt;password&gt; \u0438 &lt;dbname&gt; \u043f\u043e\u0434\u043b\u0435\u0436\u0430\u0442 \u0437\u0430\u043c\u0435\u043d\u0435 MONGODB=mongodb+srv:\/\/&lt;username&gt;:&lt;password&gt;@cluster0.p7jbn.mongodb.net\/&lt;dbname&gt;?retryWrites=true&amp;w=majority <\/code><\/pre>\n<p>  \u0421\u043e\u0437\u0434\u0430\u0435\u043c \u0444\u0430\u0439\u043b \u00abdotenv.js\u00bb:<\/p>\n<pre><code class=\"javascript\">\/\/ \u043f\u043e\u0434\u043a\u043b\u044e\u0447\u0430\u0435\u043c dotenv require(&quot;dotenv\/config&quot;);  \/\/ \u043f\u043e\u0434\u043a\u043b\u044e\u0447\u0430\u0435\u043c mongoose const mongoose = require(&quot;mongoose&quot;);  \/\/ process.env.MONGODB - \u0437\u0430\u0433\u0440\u0443\u0437\u043a\u0430 \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u043e\u0439 &quot;MONGODB&quot; \u0438\u0437 \u0444\u0430\u0439\u043b\u0430 &quot;.env&quot; mongoose.connect(process.env.MONGODB, { \tuseNewUrlParser: true, \tuseUnifiedTopology: true, }); <\/code><\/pre>\n<p>  \u0412 \u043a\u0430\u0447\u0435\u0441\u0442\u0432\u0435 \u0430\u043b\u044c\u0442\u0435\u0440\u043d\u0430\u0442\u0438\u0432\u044b \u043c\u043e\u0436\u043d\u043e \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c <a href=\"https:\/\/www.npmjs.com\/package\/config\" rel=\"nofollow\">config<\/a>.<\/p>\n<p>  \u0423\u0441\u0442\u0430\u043d\u0430\u0432\u043b\u0438\u0432\u0430\u0435\u043c \u043f\u0430\u043a\u0435\u0442: yarn add config.<\/p>\n<p>  \u0421\u043e\u0437\u0434\u0430\u0435\u043c \u0444\u0430\u0439\u043b config.json:<\/p>\n<pre><code class=\"javascript\">{ \t&quot;mongoDB&quot;: &quot;mongodb+srv:\/\/&lt;username&gt;:&lt;password&gt;@cluster0.p7jbn.mongodb.net\/&lt;dbname&gt;?retryWrites=true&amp;w=majority&quot; } <\/code><\/pre>\n<p>  \u0421\u043e\u0437\u0434\u0430\u0435\u043c \u0444\u0430\u0439\u043b config.js:<\/p>\n<pre><code class=\"javascript\">\/\/ \u043f\u043e\u0434\u043a\u043b\u044e\u0447\u0430\u0435\u043c config const config = require(&quot;config&quot;);  \/\/ \u043f\u043e\u0434\u043a\u043b\u044e\u0447\u0430\u0435\u043c mongoose const mongoose = require(&quot;mongoose&quot;);  \/\/ config.get(&quot;mongoDB&quot;) - \u043f\u043e\u043b\u0443\u0447\u0435\u043d\u0438\u0435 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u044f \u0441\u0432\u043e\u0439\u0441\u0442\u0432\u0430 &quot;mongoDB&quot; \u043e\u0431\u044a\u0435\u043a\u0442\u0430 &quot;config&quot; \u0438\u0437 \u0444\u0430\u0439\u043b\u0430 &quot;config.json&quot; mongoose.connect(config.get(&quot;mongoDB&quot;), { \tuseNewUrlParser: true, \tuseUnifiedTopology: true, }, () =&gt; console.log(&quot;Connected to database&quot;)); <\/code><\/pre>\n<p>  <a name=\"validator\"><\/a><\/p>\n<h3><a href=\"https:\/\/www.npmjs.com\/package\/validator\" rel=\"nofollow\">validator<\/a><\/h3>\n<p>  \u0415\u0436\u0435\u043d\u0435\u0434\u0435\u043b\u044c\u043d\u044b\u0435 \u0437\u0430\u0433\u0440\u0443\u0437\u043a\u0438: 4 \u043c\u043b\u043d.<\/p>\n<p>  \u041d\u0430\u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435: \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0430 \u0434\u043b\u044f \u0432\u0430\u043b\u0438\u0434\u0430\u0446\u0438\u0438 \u0438 \u043e\u0431\u0435\u0437\u0432\u0440\u0435\u0436\u0438\u0432\u0430\u043d\u0438\u044f \u0434\u0430\u043d\u043d\u044b\u0445, \u043f\u0435\u0440\u0435\u0434\u0430\u0432\u0430\u0435\u043c\u044b\u0445 \u0432 \u0432\u0438\u0434\u0435 \u0441\u0442\u0440\u043e\u043a.<\/p>\n<p>  \u041f\u0440\u0438\u043c\u0435\u0440 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u044f.<\/p>\n<p>  \u0420\u0435\u0430\u043b\u0438\u0437\u0443\u0435\u043c \u043e\u0442\u043f\u0440\u0430\u0432\u043a\u0443 \u0444\u043e\u0440\u043c\u044b \u0438 \u0432\u0430\u043b\u0438\u0434\u0430\u0446\u0438\u044e \u0434\u0430\u043d\u043d\u044b\u0445 \u043d\u0430 \u0441\u0435\u0440\u0432\u0435\u0440\u0435.<\/p>\n<p>  \u0423\u0441\u0442\u0430\u043d\u0430\u0432\u043b\u0438\u0432\u0430\u0435\u043c \u043f\u0430\u043a\u0435\u0442: yarn add validator.<\/p>\n<p>  \u0421\u043e\u0437\u0434\u0430\u0435\u043c \u0444\u0430\u0439\u043b index.html:<\/p>\n<pre><code class=\"javascript\">&lt;head&gt; \t&lt;title&gt;Form Validation&lt;\/title&gt; \t&lt;style&gt; \t\tlabel, \t\tspan { \t\t\tdisplay: block; \t\t\tmargin: .5rem; \t\t} \t&lt;\/style&gt; &lt;\/head&gt; &lt;body&gt; \t&lt;form&gt; \t\t&lt;label&gt;Name: &lt;input type=&quot;text&quot; value=&quot;Igor&quot; data-name=&quot;name&quot; \/&gt;&lt;\/label&gt; \t\t&lt;label&gt;Age: &lt;input type=&quot;number&quot; value=&quot;30&quot; data-name=&quot;age&quot; \/&gt;&lt;\/label&gt; \t\t&lt;label \t\t\t&gt;Email: \t\t\t&lt;input type=&quot;email&quot; value=&quot;myemail.example.com&quot; data-name=&quot;email&quot; \t\t\/&gt;&lt;\/label&gt; \t\t&lt;label \t\t\t&gt;Site: &lt;input type=&quot;url&quot; value=&quot;myblog.org&quot; data-name=&quot;url&quot; \t\t\/&gt;&lt;\/label&gt; \t\t&lt;label \t\t\t&gt;Card: &lt;input type=&quot;text&quot; value=&quot;1111222233334444&quot; data-name=&quot;card&quot; \t\t\/&gt;&lt;\/label&gt; \t\t&lt;button&gt;Send&lt;\/button&gt; \t\t&lt;p&gt;&lt;\/p&gt; \t&lt;\/form&gt;  \t&lt;script&gt; \t\tconst form = document.querySelector(&quot;form&quot;); \t\t\/\/ \u043a\u043d\u043e\u043f\u043a\u0430 \u0434\u043b\u044f \u043e\u0442\u043f\u0440\u0430\u0432\u043a\u0438 \u0444\u043e\u0440\u043c\u044b \t\tconst btn = form.querySelector(&quot;button&quot;); \t\t\/\/ \u043a\u043e\u043d\u0442\u0435\u0439\u043d\u0435\u0440 \u0434\u043b\u044f \u0432\u044b\u0432\u043e\u0434\u0430 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u044f \t\tconst log = form.querySelector(&quot;p&quot;);  \t\t\/\/ \u0432\u0441\u043f\u043e\u043c\u043e\u0433\u0430\u0442\u0435\u043b\u044c\u043d\u0430\u044f \u0444\u0443\u043d\u043a\u0446\u0438\u044f \u0434\u043b\u044f \u043f\u043e\u043b\u0443\u0447\u0435\u043d\u0438\u044f \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u044f \u0443\u043a\u0430\u0437\u0430\u043d\u043d\u043e\u0433\u043e \u0438\u043d\u043f\u0443\u0442\u0430 \t\tconst getValue = (name) =&gt; \t\t\tform.querySelector(`[data-name=${name}]`).value;  \t\tbtn.addEventListener(&quot;click&quot;, (e) =&gt; { \t\t\te.preventDefault();  \t\t\t\/\/ \u0444\u043e\u0440\u043c\u0438\u0440\u0443\u0435\u043c \u0434\u0430\u043d\u043d\u044b\u0435 \u0434\u043b\u044f \u043e\u0442\u043f\u0440\u0430\u0432\u043a\u0438 \t\t\tconst data = { \t\t\t\tname: getValue(&quot;name&quot;), \t\t\t\tage: getValue(&quot;age&quot;), \t\t\t\temail: getValue(&quot;email&quot;), \t\t\t\turl: getValue(&quot;url&quot;), \t\t\t\tcard: getValue(&quot;card&quot;), \t\t\t};  \t\t\t\/\/ \u0444\u0443\u043d\u043a\u0446\u0438\u044f \u043e\u0442\u043f\u0440\u0430\u0432\u043a\u0438 \u0434\u0430\u043d\u043d\u044b\u0445 \t\t\tconst sendData = async (url) =&gt; { \t\t\t\tconst req = await fetch(url, { \t\t\t\t\tmethod: &quot;POST&quot;, \t\t\t\t\theaders: { \t\t\t\t\t\t&quot;Content-Type&quot;: &quot;application\/json&quot;, \t\t\t\t\t}, \t\t\t\t\tbody: JSON.stringify(data), \t\t\t\t});  \t\t\t\t\/\/ \u043e\u0442\u0432\u0435\u0442 \u043e\u0442 \u0441\u0435\u0440\u0432\u0435\u0440\u0430 \u0432 \u0432\u0438\u0434\u0435 \u043c\u0430\u0441\u0441\u0438\u0432\u0430 \t\t\t\tconst res = await req.json();  \t\t\t\tconsole.log(res);  \t\t\t\t\/\/ \u0432\u044b\u0432\u043e\u0434 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u044f \u043e \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442\u0435 \t\t\t\tif (res.length !== 0) { \t\t\t\t\tlet html = &quot;&quot;; \t\t\t\t\tfor (const msg of res) { \t\t\t\t\t\thtml += `&lt;span&gt;${msg}&lt;\/span&gt;`; \t\t\t\t\t\tlog.innerHTML = html; \t\t\t\t\t} \t\t\t\t} else { \t\t\t\t\t\tlog.textContent = 'Success' \t\t\t\t\t} \t\t\t};  \t\t\tsendData(&quot;http:\/\/localhost:3000\/users&quot;); \t\t}); \t&lt;\/script&gt; <\/code><\/pre>\n<p>  \u0421\u043e\u0437\u0434\u0430\u0435\u043c \u0444\u0430\u0439\u043b validator.js:<\/p>\n<pre><code class=\"javascript\">const express = require(&quot;express&quot;); const cors = require(&quot;cors&quot;);  \/\/ \u0438\u0437\u0432\u043b\u0435\u043a\u0430\u0435\u043c \u0444\u0443\u043d\u043a\u0446\u0438\u0438, \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u044b\u0435 \u0434\u043b\u044f \u0432\u0430\u043b\u0438\u0434\u0430\u0446\u0438\u0438 \/\/ escape - \u0444\u0443\u043d\u043a\u0446\u0438\u044f \u043e\u0431\u0435\u0437\u0432\u0440\u0435\u0436\u0438\u0432\u0430\u043d\u0438\u044f \u0434\u0430\u043d\u043d\u044b\u0445 const { \tisAlpha, \tisNumeric, \tisEmail, \tisURL, \tisCreditCard, \tescape, } = require(&quot;validator&quot;);  \/\/ \u0441\u043e\u0431\u0438\u0440\u0430\u0435\u043c \u0432\u0430\u043b\u0438\u0434\u0430\u0442\u043e\u0440\u044b \u0432 \u043c\u0430\u0441\u0441\u0438\u0432 const validators = [isAlpha, isNumeric, isEmail, isURL, isCreditCard];  const app = express(); app.use(cors()); app.use(express.json());  \/\/ \u043e\u0431\u0440\u0430\u0431\u0430\u0442\u044b\u0432\u0430\u0435\u043c \u043f\u043e\u043b\u0443\u0447\u0435\u043d\u0438\u0435 \u0434\u0430\u043d\u043d\u044b\u0445 app.use(&quot;\/users&quot;, (req, res) =&gt; { \t\/\/ \u0438\u0437\u0432\u043b\u0435\u043a\u0430\u0435\u043c \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u044b\u0435 \u0434\u0430\u043d\u043d\u044b\u0435 \tconst data = ({ name, age, email, url, card } = req.body);  \tconsole.log(data);  \t\/\/ \u043c\u0430\u0441\u0441\u0438\u0432 \u0441 \u043e\u0448\u0438\u0431\u043a\u0430\u043c\u0438 \tconst errors = [];  \t\/\/ \u043f\u0440\u043e\u0432\u043e\u0434\u0438\u043c \u0432\u0430\u043b\u0438\u0434\u0430\u0446\u0438\u044e \tfor (let i = 0; i &lt; validators.length; i++) { \t\t\/\/ \u043e\u0431\u0435\u0437\u0432\u0440\u0435\u0436\u0438\u0432\u0430\u0435\u043c \u0434\u0430\u043d\u043d\u044b\u0435 \t\tescape(Object.values(data)[i]);  \t\t\/\/ \u0435\u0441\u043b\u0438 \u0434\u0430\u043d\u043d\u044b\u0435 \u043d\u0435 \u043f\u0440\u043e\u0448\u043b\u0438 \u0432\u0430\u043b\u0438\u0434\u0430\u0446\u0438\u044e \t\t\/\/ \u0434\u043e\u0431\u0430\u0432\u043b\u044f\u0435\u043c \u0441\u043e\u043e\u0442\u0432\u0435\u0442\u0441\u0442\u0432\u0443\u044e\u0449\u0435\u0435 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0435 \u0432 \u043c\u0430\u0441\u0441\u0438\u0432 \u0441 \u043e\u0448\u0438\u0431\u043a\u0430\u043c\u0438 \t\tif (!validators[i](Object.values(data)[i])) { \t\t\terrors.push(`Wrong ${Object.keys(data)[i]}`); \t\t} \t}  \tconsole.log(errors);  \t\/\/ \u043e\u0442\u043f\u0440\u0430\u0432\u043b\u044f\u0435\u043c \u043e\u0448\u0438\u0431\u043a\u0438 \u043a\u043b\u0438\u0435\u043d\u0442\u0443 \tres.json(errors); });  app.listen(process.env.PORT || 3000, () =&gt; console.log(&quot;Server ready&quot;)); <\/code><\/pre>\n<p>  \u0417\u0430\u043f\u0443\u0441\u043a\u0430\u0435\u043c \u0441\u0435\u0440\u0432\u0435\u0440: node validator.js.<\/p>\n<p>  \u041e\u0442\u043a\u0440\u044b\u0432\u0430\u0435\u043c index.html \u0438 \u043e\u0442\u043f\u0440\u0430\u0432\u043b\u044f\u0435\u043c \u0434\u0430\u043d\u043d\u044b\u0435.<\/p>\n<p>  <img decoding=\"async\" src=\"https:\/\/habrastorage.org\/webt\/df\/cl\/cx\/dfclcxrb7cwero74rnjx4y28iuo.png\"><\/p>\n<p>  <img decoding=\"async\" src=\"https:\/\/habrastorage.org\/webt\/dz\/ky\/l9\/dzkyl9d0fj2kcrbaqhwmcpsw_mc.png\"><\/p>\n<p>  \u041f\u043e\u043b\u0443\u0447\u0430\u0435\u043c \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0435 \u043e \u0442\u043e\u043c, \u0447\u0442\u043e \u0430\u0434\u0440\u0435\u0441 \u044d\u043b\u0435\u043a\u0442\u0440\u043e\u043d\u043d\u043e\u0439 \u043f\u043e\u0447\u0442\u044b \u0438 \u043d\u043e\u043c\u0435\u0440 \u043a\u0440\u0435\u0434\u0438\u0442\u043d\u043e\u0439 \u043a\u0430\u0440\u0442\u044b \u043d\u0435\u0432\u0430\u043b\u0438\u0434\u043d\u044b.<\/p>\n<p>  \u0418\u0437\u043c\u0435\u043d\u0438\u043c \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u044f email \u0438 card \u043d\u0430 myemail@example.com \u0438 2222111111111111, \u0441\u043e\u043e\u0442\u0432\u0435\u0442\u0441\u0442\u0432\u0435\u043d\u043d\u043e.<\/p>\n<p>  \u041d\u0430\u0436\u0438\u043c\u0430\u0435\u043c \u00abSend\u00bb.<\/p>\n<p>  <img decoding=\"async\" src=\"https:\/\/habrastorage.org\/webt\/we\/mx\/z0\/wemxz0z9nb9hliv1cm-qkeygpcm.png\"><\/p>\n<p>  <img decoding=\"async\" src=\"https:\/\/habrastorage.org\/webt\/oo\/kj\/b-\/ookjb-iozgwgsnmfxv33ssazgcu.png\"><\/p>\n<p>  \u041f\u043e\u043b\u0443\u0447\u0430\u0435\u043c \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0435 \u043e\u0431 \u0443\u0441\u043f\u0435\u0448\u043d\u043e\u0439 \u0432\u0430\u043b\u0438\u0434\u0430\u0446\u0438\u0438 \u0434\u0430\u043d\u043d\u044b\u0445.<\/p>\n<p>  \u041d\u0430 \u0441\u0435\u0433\u043e\u0434\u043d\u044f \u044d\u0442\u043e \u0432\u0441\u0435. \u041d\u0430\u0434\u0435\u044e\u0441\u044c, \u0432\u044b \u043d\u0430\u0448\u043b\u0438 \u0434\u043b\u044f \u0441\u0435\u0431\u044f \u0447\u0442\u043e-\u0442\u043e \u043f\u043e\u043b\u0435\u0437\u043d\u043e\u0435. \u0411\u043b\u0430\u0433\u043e\u0434\u0430\u0440\u044e \u0437\u0430 \u0432\u043d\u0438\u043c\u0430\u043d\u0438\u0435.<\/p><\/div>\n<p> \u0441\u0441\u044b\u043b\u043a\u0430 \u043d\u0430 \u043e\u0440\u0438\u0433\u0438\u043d\u0430\u043b \u0441\u0442\u0430\u0442\u044c\u0438 <a href=\"https:\/\/habr.com\/ru\/post\/522700\/\"> https:\/\/habr.com\/ru\/post\/522700\/<\/a><\/p>\n","protected":false},"excerpt":{"rendered":"\n<div class=\"post__text post__text-html post__text_v1\" id=\"post-content-body\" data-io-article-url=\"https:\/\/habr.com\/ru\/post\/522700\/\">\u0414\u043e\u0431\u0440\u043e\u0433\u043e \u0432\u0440\u0435\u043c\u0435\u043d\u0438 \u0441\u0443\u0442\u043e\u043a, \u0434\u0440\u0443\u0437\u044c\u044f!<\/p>\n<p>  \u041f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u043b\u044f\u044e \u0432\u0430\u0448\u0435\u043c\u0443 \u0432\u043d\u0438\u043c\u0430\u043d\u0438\u044e \u043f\u043e\u0434\u0431\u043e\u0440\u043a\u0443 \u0438\u0437 \u0434\u0435\u0441\u044f\u0442\u0438 \u043f\u043e\u043f\u0443\u043b\u044f\u0440\u043d\u044b\u0445 npm-\u043f\u0430\u043a\u0435\u0442\u043e\u0432 \u0441 \u043f\u0440\u0438\u043c\u0435\u0440\u0430\u043c\u0438 \u0438\u0445 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u044f \u0438 \u0430\u043b\u044c\u0442\u0435\u0440\u043d\u0430\u0442\u0438\u0432\u043d\u044b\u043c\u0438 \u0440\u0435\u0448\u0435\u043d\u0438\u044f\u043c\u0438.<\/p>\n<p>  \u041f\u0440\u0435\u0434\u043f\u043e\u043b\u0430\u0433\u0430\u0435\u0442\u0441\u044f, \u0447\u0442\u043e \u0432\u044b \u0445\u043e\u0440\u043e\u0448\u043e \u0437\u043d\u0430\u043a\u043e\u043c\u044b \u0441 JavaScript \u0438, \u0432 \u0447\u0430\u0441\u0442\u043d\u043e\u0441\u0442\u0438, \u0441 Node.js.<\/p>\n<p>  \u0412 \u0434\u0430\u043d\u043d\u043e\u043c \u0447\u0430\u0441\u0442\u0438 \u043f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u043b\u0435\u043d\u044b \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u0435 \u043f\u0430\u043a\u0435\u0442\u044b:<\/p>\n<ul>\n<li><a href=\"#chalk\">chalk<\/a><\/li>\n<li><a href=\"#progress\">progress<\/a><\/li>\n<li><a href=\"#minimist\">minimist<\/a><\/li>\n<li><a href=\"#fs-extra\">fs-extra<\/a><\/li>\n<li><a href=\"#uuid\">uuid<\/a><\/li>\n<li><a href=\"#moment\">moment<\/a><\/li>\n<li><a href=\"#axios\">axios<\/a><\/li>\n<li><a href=\"#async\">async<\/a><\/li>\n<li><a href=\"#dotenv\">dotenv<\/a><\/li>\n<li><a href=\"#validator\">validator<\/a><\/li>\n<\/ul>\n<p>  <\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[],"tags":[],"class_list":["post-311197","post","type-post","status-publish","format-standard","hentry"],"_links":{"self":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts\/311197","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=311197"}],"version-history":[{"count":0,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts\/311197\/revisions"}],"wp:attachment":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=311197"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=311197"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=311197"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}