فهرست منبع

- Enhancement: Add CLI for displaying date in plain text only or JSON
- Point `main` to controllers file (which has potentially usable utilities)
- License: Add badi-cal (MIT) license

Brett Zamir 6 سال پیش
والد
کامیت
db872395b3
8فایلهای تغییر یافته به همراه777 افزوده شده و 98 حذف شده
  1. 4 0
      README.md
  2. 60 45
      api/controllers/bDateController.js
  3. 37 0
      bin/bahai-date-api.js
  4. 36 0
      bin/optionDefinitions.js
  5. 1 0
      images/cli.svg
  6. 609 51
      package-lock.json
  7. 9 2
      package.json
  8. 21 0
      vendor/assets/badi-cal/LICENSE

+ 4 - 0
README.md

@@ -93,3 +93,7 @@ Output:
     }
 }
 ```
+
+## CLI usage
+
+![cli.svg](images/cli.svg)

+ 60 - 45
api/controllers/bDateController.js

@@ -36,7 +36,7 @@ exports.test = function (req, res) {
 /**
  * @returns {BadiDateObject}
  */
-function getTodayJSON () {
+const getTodayJSON = exports.getTodayJSON = function () {
   const now = new Date();
   const here = {
     latitude: '40.712', // New York
@@ -45,42 +45,56 @@ function getTodayJSON () {
 
   const nowBadi = BadiCal.BadiDate.fromGregorianDate(now, here);
 
-  // eslint-disable-next-line no-console
-  console.log('Today: ' + nowBadi.toString());
   return {
-    message: 'Today is ' + nowBadi.toString(),
-    badi_date: {
-      year: nowBadi.getYear(),
-      month: nowBadi.getMonth(),
-      day: nowBadi.getDay(),
-      month_name: nowBadi.getMonthName()
-    },
-    greg_date: {
-      year: now.getFullYear(),
-      month: now.getMonth() + 1,
-      day: now.getDate(),
-      hour: now.getHours(),
-      minute: now.getMinutes(),
-      second: now.getSeconds()
+    now,
+    nowBadi,
+    json: {
+      message: 'Today is ' + nowBadi.toString(),
+      badi_date: {
+        year: nowBadi.getYear(),
+        month: nowBadi.getMonth(),
+        day: nowBadi.getDay(),
+        month_name: nowBadi.getMonthName()
+      },
+      greg_date: {
+        year: now.getFullYear(),
+        month: now.getMonth() + 1,
+        day: now.getDate(),
+        hour: now.getHours(),
+        minute: now.getMinutes(),
+        second: now.getSeconds()
+      }
     }
   };
-}
+};
 
 exports.today = function (req, res) {
-  res.json(getTodayJSON());
+  const {json, nowBadi} = getTodayJSON();
+  // eslint-disable-next-line no-console
+  console.log('Today: ' + nowBadi.toString());
+  res.json(json);
 };
 
 exports.todayHtml = function (req, res) {
-  res.end(JSON.stringify(getTodayJSON(), null, 2));
+  res.end(JSON.stringify(getTodayJSON().json, null, 2));
 };
 
 exports.date = function (req, res) {
-  const year = sanitizeInput(req.query.year);
-  const month = sanitizeInput(req.query.month) - 1;
-  const day = sanitizeInput(req.query.day);
-  const hour = sanitizeInput(req.query.hour);
-  const minute = sanitizeInput(req.query.minute);
-  const second = sanitizeInput(req.query.second);
+  const dateInfo = getDate(req.query);
+  // eslint-disable-next-line no-console
+  console.log(
+    'Date: ' + dateInfo.now.toString() + ' -> ' + dateInfo.nowBadi.toString()
+  );
+  res.json(dateInfo.json);
+};
+
+const getDate = exports.getDate = function (dateObj) {
+  const year = sanitizeInput(dateObj.year);
+  const month = sanitizeInput(dateObj.month) - 1;
+  const day = sanitizeInput(dateObj.day);
+  const hour = sanitizeInput(dateObj.hour);
+  const minute = sanitizeInput(dateObj.minute);
+  const second = sanitizeInput(dateObj.second);
 
   const now = new Date(year, month, day, hour, minute, second);
   const here = {
@@ -89,24 +103,25 @@ exports.date = function (req, res) {
   };
 
   const nowBadi = BadiCal.BadiDate.fromGregorianDate(now, here);
-  res.json({
-    message: 'The date is: ' + nowBadi.toString(),
-    badi_date: {
-      year: nowBadi.getYear(),
-      month: nowBadi.getMonth(),
-      day: nowBadi.getDay(),
-      month_name: nowBadi.getMonthName()
-    },
-    greg_date: {
-      year,
-      month: month + 1,
-      day,
-      hour,
-      minute,
-      second
+  return {
+    now,
+    nowBadi,
+    json: {
+      message: 'The date is: ' + nowBadi.toString(),
+      badi_date: {
+        year: nowBadi.getYear(),
+        month: nowBadi.getMonth(),
+        day: nowBadi.getDay(),
+        month_name: nowBadi.getMonthName()
+      },
+      greg_date: {
+        year,
+        month: month + 1,
+        day,
+        hour,
+        minute,
+        second
+      }
     }
-  });
-
-  // eslint-disable-next-line no-console
-  console.log('Date: ' + now.toString() + ' -> ' + nowBadi.toString());
+  };
 };

+ 37 - 0
bin/bahai-date-api.js

@@ -0,0 +1,37 @@
+#!/usr/bin/env node
+'use strict';
+
+const {join} = require('path');
+const {cliBasics} = require('command-line-basics');
+const {
+  getDate, getTodayJSON
+} = require('../api/controllers/bDateController.js');
+
+const optionDefinitions = cliBasics(
+  join(__dirname, './optionDefinitions.js')
+);
+
+if (!optionDefinitions) { // cliBasics handled
+  process.exit(); // eslint-disable-line no-process-exit
+}
+
+const {date, verbose} = optionDefinitions;
+
+let dateObj;
+if (date) {
+  const dte = new Date(date);
+  dateObj = getDate({
+    year: dte.getFullYear(),
+    month: dte.getMonth(),
+    day: dte.getDate(),
+    hour: dte.getHours(),
+    minute: dte.getMinutes(),
+    second: dte.getSeconds()
+  });
+} else {
+  dateObj = getTodayJSON();
+}
+
+const output = verbose ? dateObj : dateObj.json.message;
+// eslint-disable-next-line no-console
+console.log(output);

+ 36 - 0
bin/optionDefinitions.js

@@ -0,0 +1,36 @@
+'use strict';
+
+const pkg = require('../package.json');
+
+/* eslint-disable jsdoc/require-property */
+/**
+* @typedef {PlainObject} CoveradgeOptions
+*/
+/* eslint-enable jsdoc/require-property */
+
+const optionDefinitions = [
+  {
+    name: 'date', alias: 'd', type: String, defaultOption: true,
+    description: 'Gregorian date (parseable by `Date`) to convert to ' +
+      'Badí\' date (or empty to get today\'s date).',
+    typeLabel: '{underline date}'
+  },
+  {
+    name: 'verbose', type: Boolean,
+    description: 'Whether to provide an entire JSON object with full details.'
+  }
+];
+
+const cliSections = [
+  {
+    // Add italics: `{italic textToItalicize}`
+    content: pkg.description +
+      '\n\n{italic bahai-date [--verbose] [aDate]}'
+  },
+  {
+    optionList: optionDefinitions
+  }
+];
+
+exports.definitions = optionDefinitions;
+exports.sections = cliSections;

+ 1 - 0
images/cli.svg

@@ -0,0 +1 @@
+<svg xmlns="http://www.w3.org/2000/svg" viewBox="0, 0, 823.33, 288.45" font-family="SauceCodePro Nerd Font, Source Code Pro, Courier" font-size="14"><g fill="#D3D3D3"><rect x="0" y="0" width="823.33" height="288.45" fill="#000000"/><path d="M0,35.5146875 L159.6259765625,35.5146875 Z" stroke="#D3D3D3"/><text x="0" y="33.55" font-weight="bold">bahai-date-rest-api</text><text x="16.8" y="71.55">  RESTful Bah&#xE1;&#x27;&#xED; date API                                 </text><text x="16.8" y="109.55" font-style="italic">bahai-date [--verbose] [aDate]</text><path d="M0,149.5146875 L58.8095703125,149.5146875 Z" stroke="#D3D3D3"/><text x="0" y="147.55" font-weight="bold">Options</text><text x="16.8" y="185.55" font-weight="bold">-d</text><text x="33.61" y="185.55">, </text><text x="50.41" y="185.55" font-weight="bold">--date</text><path d="M109.2177734375,187.5146875 L142.8232421875,187.5146875 Z" stroke="#D3D3D3"/><text x="109.22" y="185.55">date</text><text x="168.03" y="185.55">   Gregorian date (parseable by &#x60;Date&#x60;) to convert to Bad&#xED;&#x27; date (or empty to    </text><text x="168.03" y="204.55">                    get today&#x27;s date).                                                            </text><text x="16.8" y="223.55" font-weight="bold">--verbose</text><text x="168.03" y="223.55">         Whether to provide an entire JSON object with full details.                   </text><text x="16.8" y="242.55" font-weight="bold">-v</text><text x="33.61" y="242.55">, </text><text x="50.41" y="242.55" font-weight="bold">--version</text><text x="16.8" y="261.55" font-weight="bold">-h</text><text x="33.61" y="261.55">, </text><text x="50.41" y="261.55" font-weight="bold">--help</text></g></svg>

تفاوت فایلی نمایش داده نمی شود زیرا این فایل بسیار بزرگ است
+ 609 - 51
package-lock.json


+ 9 - 2
package.json

@@ -1,10 +1,15 @@
 {
   "name": "bahai-date-rest-api",
   "version": "1.0.0",
-  "description": "RESTful Baha'i date API",
-  "main": "index.js",
+  "description": "RESTful Bahá'í date API",
+  "main": "api/controllers/bDateController.js",
+  "bin": {
+    "bahai-date": "./bin/bahai-date-api.js"
+  },
   "scripts": {
     "lint": "eslint --ext=js,md,html .",
+    "cmd": "./bin/bahai-date-api.js",
+    "cli-publish": "clp --config=\"bin/optionDefinitions.js\" --target images/cli.svg",
     "start": "nodemon server.js",
     "test": "echo \"Error: No test specified\" && exit 1"
   },
@@ -31,6 +36,7 @@
   "homepage": "https://github.com/dragfyre/bahai-date-api#readme",
   "devDependencies": {
     "@mysticatea/eslint-plugin": "^13.0.0",
+    "command-line-publish": "^0.6.0",
     "eslint": "^6.8.0",
     "eslint-config-ash-nazg": "^16.4.0",
     "eslint-config-standard": "^14.1.0",
@@ -53,6 +59,7 @@
   },
   "dependencies": {
     "body-parser": "^1.19.0",
+    "command-line-basics": "^0.6.2",
     "deep-extend": "^0.6.0",
     "express": "^4.17.1",
     "express-rate-limit": "^5.0.0",

+ 21 - 0
vendor/assets/badi-cal/LICENSE

@@ -0,0 +1,21 @@
+The MIT License (MIT)
+
+Copyright (c) 2015-2017 Berkeley Churchill
+
+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.

برخی فایل ها در این مقایسه diff نمایش داده نمی شوند زیرا تعداد فایل ها بسیار زیاد است