From 83d1a5ff13ffcd85e01f7fad3e6b6df9dd3bf128 Mon Sep 17 00:00:00 2001 From: Julien Fontanet Date: Fri, 21 Sep 2018 11:56:33 +0200 Subject: [PATCH] feat(defined): helpers to deal with undefined (#3436) Extracted from xo-web. --- @xen-orchestra/defined/.babelrc.js | 3 ++ @xen-orchestra/defined/.npmignore | 24 +++++++++ @xen-orchestra/defined/README.md | 49 +++++++++++++++++++ @xen-orchestra/defined/package.json | 48 ++++++++++++++++++ .../defined/src/index.js | 6 ++- CHANGELOG.md | 3 +- packages/xo-web/package.json | 1 + packages/xo-web/src/common/form/index.js | 2 +- packages/xo-web/src/common/render-xo-item.js | 2 +- .../xo-web/src/common/sorted-table/index.js | 2 +- packages/xo-web/src/xo-app/backup-ng/index.js | 2 +- .../xo-web/src/xo-app/backup-ng/new/index.js | 2 +- packages/xo-web/src/xo-app/home/index.js | 2 +- .../xo-web/src/xo-app/home/template-item.js | 2 +- .../xo-web/src/xo-app/host/tab-network.js | 2 +- packages/xo-web/src/xo-app/jobs/new/index.js | 2 +- .../xo-web/src/xo-app/logs/backup-ng-logs.js | 2 +- packages/xo-web/src/xo-app/logs/index.js | 2 +- .../src/xo-app/logs/log-alert-header.js | 2 +- packages/xo-web/src/xo-app/new-vm/index.js | 2 +- packages/xo-web/src/xo-app/self/index.js | 2 +- .../xo-app/settings/cloud-configs/index.js | 2 +- packages/xo-web/src/xo-app/vm/tab-advanced.js | 2 +- packages/xo-web/src/xo-app/vm/tab-general.js | 2 +- .../xo-web/src/xo-app/xoa/licenses/index.js | 4 +- .../xo-web/src/xo-app/xoa/licenses/xosan.js | 4 +- packages/xo-web/src/xo-app/xosan/index.js | 4 +- 27 files changed, 154 insertions(+), 26 deletions(-) create mode 100644 @xen-orchestra/defined/.babelrc.js create mode 100644 @xen-orchestra/defined/.npmignore create mode 100644 @xen-orchestra/defined/README.md create mode 100644 @xen-orchestra/defined/package.json rename packages/xo-web/src/common/xo-defined.js => @xen-orchestra/defined/src/index.js (88%) diff --git a/@xen-orchestra/defined/.babelrc.js b/@xen-orchestra/defined/.babelrc.js new file mode 100644 index 000000000..4e27ec135 --- /dev/null +++ b/@xen-orchestra/defined/.babelrc.js @@ -0,0 +1,3 @@ +module.exports = require('../../@xen-orchestra/babel-config')( + require('./package.json') +) diff --git a/@xen-orchestra/defined/.npmignore b/@xen-orchestra/defined/.npmignore new file mode 100644 index 000000000..e058b6bc1 --- /dev/null +++ b/@xen-orchestra/defined/.npmignore @@ -0,0 +1,24 @@ +/benchmark/ +/benchmarks/ +*.bench.js +*.bench.js.map + +/examples/ +example.js +example.js.map +*.example.js +*.example.js.map + +/fixture/ +/fixtures/ +*.fixture.js +*.fixture.js.map +*.fixtures.js +*.fixtures.js.map + +/test/ +/tests/ +*.spec.js +*.spec.js.map + +__snapshots__/ diff --git a/@xen-orchestra/defined/README.md b/@xen-orchestra/defined/README.md new file mode 100644 index 000000000..7d35dc618 --- /dev/null +++ b/@xen-orchestra/defined/README.md @@ -0,0 +1,49 @@ +# ${pkg.name} [![Build Status](https://travis-ci.org/${pkg.shortGitHubPath}.png?branch=master)](https://travis-ci.org/${pkg.shortGitHubPath}) + +> ${pkg.description} + +## Install + +Installation of the [npm package](https://npmjs.org/package/${pkg.name}): + +``` +> npm install --save ${pkg.name} +``` + +## Usage + +**TODO** + +## Development + +``` +# Install dependencies +> yarn + +# Run the tests +> yarn test + +# Continuously compile +> yarn dev + +# Continuously run the tests +> yarn dev-test + +# Build for production (automatically called by npm install) +> yarn build +``` + +## Contributions + +Contributions are *very* welcomed, either on the documentation or on +the code. + +You may: + +- report any [issue](${pkg.bugs}) + you've encountered; +- fork and create a pull request. + +## License + +${pkg.license} © [${pkg.author.name}](${pkg.author.url}) diff --git a/@xen-orchestra/defined/package.json b/@xen-orchestra/defined/package.json new file mode 100644 index 000000000..258bfbb0b --- /dev/null +++ b/@xen-orchestra/defined/package.json @@ -0,0 +1,48 @@ +{ + "private": true, + "name": "@xen-orchestra/defined", + "version": "0.0.0", + "license": "ISC", + "description": "", + "keywords": [], + "homepage": "https://github.com/vatesfr/xen-orchestra/tree/master/@xen-orchestra/defined", + "bugs": "https://github.com/vatesfr/xen-orchestra/issues", + "repository": { + "type": "git", + "url": "https://github.com/vatesfr/xen-orchestra.git" + }, + "author": { + "name": "Julien Fontanet", + "email": "julien.fontanet@vates.fr" + }, + "preferGlobal": false, + "main": "dist/", + "bin": {}, + "files": [ + "dist/" + ], + "browserslist": [ + ">2%" + ], + "engines": { + "node": ">=6" + }, + "dependencies": {}, + "devDependencies": { + "@babel/cli": "7.0.0", + "@babel/core": "7.0.0", + "@babel/preset-env": "7.0.0", + "@babel/preset-flow": "7.0.0", + "babel-plugin-lodash": "^3.3.2", + "cross-env": "^5.1.3", + "rimraf": "^2.6.2" + }, + "scripts": { + "build": "cross-env NODE_ENV=production babel --source-maps --out-dir=dist/ src/", + "clean": "rimraf dist/", + "dev": "cross-env NODE_ENV=development babel --watch --source-maps --out-dir=dist/ src/", + "prebuild": "yarn run clean", + "predev": "yarn run prebuild", + "prepublishOnly": "yarn run build" + } +} diff --git a/packages/xo-web/src/common/xo-defined.js b/@xen-orchestra/defined/src/index.js similarity index 88% rename from packages/xo-web/src/common/xo-defined.js rename to @xen-orchestra/defined/src/index.js index 262f4e9eb..a2c34e03d 100644 --- a/packages/xo-web/src/common/xo-defined.js +++ b/@xen-orchestra/defined/src/index.js @@ -1,3 +1,5 @@ +// @flow + // Usage: // // ```js @@ -39,7 +41,7 @@ export default function defined () { // const getFriendName = _ => _.friends[0].name // const friendName = get(getFriendName, props.user) // ``` -export const get = (accessor, arg) => { +export const get = (accessor: (input: ?any) => any, arg: ?any) => { try { return accessor(arg) } catch (error) { @@ -58,5 +60,5 @@ export const get = (accessor, arg) => { // _ => new ProxyAgent(_) // ) // ``` -export const ifDef = (value, thenFn) => +export const ifDef = (value: ?any, thenFn: (value: any) => any) => value !== undefined ? thenFn(value) : value diff --git a/CHANGELOG.md b/CHANGELOG.md index 1e35948ee..0eff8bde3 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -27,8 +27,9 @@ - xo-server-backup-reports v0.14.0 - @xen-orchestra/async-map v0.0.0 -- @xen-orchestra/mixin v0.0.0 +- @xen-orchestra/defined v0.0.0 - @xen-orchestra/emit-async v0.0.0 +- @xen-orchestra/mixin v0.0.0 - xo-server v5.27.0 - xo-web v5.27.0 diff --git a/packages/xo-web/package.json b/packages/xo-web/package.json index 9f4314e01..ebf0fd53c 100644 --- a/packages/xo-web/package.json +++ b/packages/xo-web/package.json @@ -33,6 +33,7 @@ "@julien-f/freactal": "0.4.0", "@nraynaud/novnc": "0.6.1", "@xen-orchestra/cron": "^1.0.3", + "@xen-orchestra/defined": "^0.0.0", "ansi_up": "^3.0.0", "asap": "^2.0.6", "babel-core": "^6.26.0", diff --git a/packages/xo-web/src/common/form/index.js b/packages/xo-web/src/common/form/index.js index 90ffdba5a..0a3fd9ecd 100644 --- a/packages/xo-web/src/common/form/index.js +++ b/packages/xo-web/src/common/form/index.js @@ -1,5 +1,6 @@ import BaseComponent from 'base-component' import classNames from 'classnames' +import defined from '@xen-orchestra/defined' import Icon from 'icon' import map from 'lodash/map' import randomPassword from 'random-password' @@ -11,7 +12,6 @@ import { DropdownButton, MenuItem } from 'react-bootstrap-4/lib' import Button from '../button' import Component from '../base-component' -import defined from '../xo-defined' import getEventValue from '../get-event-value' import propTypes from '../prop-types-decorator' import { formatSizeRaw, parseSize } from '../utils' diff --git a/packages/xo-web/src/common/render-xo-item.js b/packages/xo-web/src/common/render-xo-item.js index d8f8edb2c..3728811ee 100644 --- a/packages/xo-web/src/common/render-xo-item.js +++ b/packages/xo-web/src/common/render-xo-item.js @@ -1,6 +1,7 @@ import _ from 'intl' import PropTypes from 'prop-types' import React from 'react' +import { get } from '@xen-orchestra/defined' import { startsWith } from 'lodash' import Icon from './icon' @@ -9,7 +10,6 @@ import propTypes from './prop-types-decorator' import { addSubscriptions, connectStore, formatSize } from './utils' import { createGetObject, createSelector } from './selectors' import { FormattedDate } from 'react-intl' -import { get } from './xo-defined' import { isSrWritable, subscribeRemotes } from './xo' // =================================================================== diff --git a/packages/xo-web/src/common/sorted-table/index.js b/packages/xo-web/src/common/sorted-table/index.js index f0385cde5..d0d50930d 100644 --- a/packages/xo-web/src/common/sorted-table/index.js +++ b/packages/xo-web/src/common/sorted-table/index.js @@ -1,6 +1,7 @@ import * as CM from 'complex-matcher' import _ from 'intl' import classNames from 'classnames' +import defined, { get } from '@xen-orchestra/defined' import DropdownMenu from 'react-bootstrap-4/lib/DropdownMenu' // https://phabricator.babeljs.io/T6662 so Dropdown.Menu won't work like https://react-bootstrap.github.io/components.html#btn-dropdowns-custom import DropdownToggle from 'react-bootstrap-4/lib/DropdownToggle' // https://phabricator.babeljs.io/T6662 so Dropdown.Toggle won't work https://react-bootstrap.github.io/components.html#btn-dropdowns-custom import React from 'react' @@ -25,7 +26,6 @@ import ActionRowButton from '../action-row-button' import Button from '../button' import ButtonGroup from '../button-group' import Component from '../base-component' -import defined, { get } from '../xo-defined' import Icon from '../icon' import Pagination from '../pagination' import propTypes from '../prop-types-decorator' diff --git a/packages/xo-web/src/xo-app/backup-ng/index.js b/packages/xo-web/src/xo-app/backup-ng/index.js index cc765d8ed..3ede1c203 100644 --- a/packages/xo-web/src/xo-app/backup-ng/index.js +++ b/packages/xo-web/src/xo-app/backup-ng/index.js @@ -9,7 +9,7 @@ import { Card, CardHeader, CardBlock } from 'card' import { confirm } from 'modal' import { constructQueryString } from 'smart-backup' import { Container, Row, Col } from 'grid' -import { get } from 'xo-defined' +import { get } from '@xen-orchestra/defined' import { isEmpty, map, groupBy, some } from 'lodash' import { NavLink, NavTabs } from 'nav' import { routes } from 'utils' diff --git a/packages/xo-web/src/xo-app/backup-ng/new/index.js b/packages/xo-web/src/xo-app/backup-ng/new/index.js index 28b2691bb..95e175799 100644 --- a/packages/xo-web/src/xo-app/backup-ng/new/index.js +++ b/packages/xo-web/src/xo-app/backup-ng/new/index.js @@ -1,6 +1,6 @@ import _ from 'intl' import ActionButton from 'action-button' -import defined, { get } from 'xo-defined' +import defined, { get } from '@xen-orchestra/defined' import Icon from 'icon' import Link from 'link' import moment from 'moment-timezone' diff --git a/packages/xo-web/src/xo-app/home/index.js b/packages/xo-web/src/xo-app/home/index.js index 75c49d84b..1dbc3028e 100644 --- a/packages/xo-web/src/xo-app/home/index.js +++ b/packages/xo-web/src/xo-app/home/index.js @@ -6,7 +6,7 @@ import Button from 'button' import CenterPanel from 'center-panel' import classNames from 'classnames' import Component from 'base-component' -import defined, { get } from 'xo-defined' +import defined, { get } from '@xen-orchestra/defined' import Icon from 'icon' import invoke from 'invoke' import Link from 'link' diff --git a/packages/xo-web/src/xo-app/home/template-item.js b/packages/xo-web/src/xo-app/home/template-item.js index 0e03e50bc..fd8555e52 100644 --- a/packages/xo-web/src/xo-app/home/template-item.js +++ b/packages/xo-web/src/xo-app/home/template-item.js @@ -1,6 +1,6 @@ import _ from 'intl' import Component from 'base-component' -import defined from 'xo-defined' +import defined from '@xen-orchestra/defined' import Ellipsis, { EllipsisContainer } from 'ellipsis' import Icon from 'icon' import Link from 'link' diff --git a/packages/xo-web/src/xo-app/host/tab-network.js b/packages/xo-web/src/xo-app/host/tab-network.js index 6c19e3d85..08f7d6ca8 100644 --- a/packages/xo-web/src/xo-app/host/tab-network.js +++ b/packages/xo-web/src/xo-app/host/tab-network.js @@ -15,7 +15,7 @@ import { connectStore, noop } from 'utils' import { Container, Row, Col } from 'grid' import { createGetObjectsOfType } from 'selectors' import { error } from 'notification' -import { get } from 'xo-defined' +import { get } from '@xen-orchestra/defined' import { Select, Number } from 'editable' import { Toggle } from 'form' import { diff --git a/packages/xo-web/src/xo-app/jobs/new/index.js b/packages/xo-web/src/xo-app/jobs/new/index.js index 906b57633..8dab63803 100644 --- a/packages/xo-web/src/xo-app/jobs/new/index.js +++ b/packages/xo-web/src/xo-app/jobs/new/index.js @@ -2,7 +2,7 @@ import _, { messages } from 'intl' import ActionButton from 'action-button' import Button from 'button' import Component from 'base-component' -import defined from 'xo-defined' +import defined from '@xen-orchestra/defined' import GenericInput from 'json-schema-input' import Icon from 'icon' import React from 'react' diff --git a/packages/xo-web/src/xo-app/logs/backup-ng-logs.js b/packages/xo-web/src/xo-app/logs/backup-ng-logs.js index 52e0fad6b..db926941d 100644 --- a/packages/xo-web/src/xo-app/logs/backup-ng-logs.js +++ b/packages/xo-web/src/xo-app/logs/backup-ng-logs.js @@ -8,7 +8,7 @@ import { alert } from 'modal' import { Card, CardHeader, CardBlock } from 'card' import { formatSize } from 'utils' import { FormattedDate } from 'react-intl' -import { get } from 'xo-defined' +import { get } from '@xen-ochestra/defined' import { isEmpty, keyBy } from 'lodash' import { subscribeBackupNgJobs, subscribeBackupNgLogs } from 'xo' diff --git a/packages/xo-web/src/xo-app/logs/index.js b/packages/xo-web/src/xo-app/logs/index.js index 76dbb569b..b9549ffaf 100644 --- a/packages/xo-web/src/xo-app/logs/index.js +++ b/packages/xo-web/src/xo-app/logs/index.js @@ -16,7 +16,7 @@ import { connectStore, formatSize, formatSpeed } from 'utils' import { createGetObject, createSelector } from 'selectors' import { filter, forEach, includes, keyBy, map, orderBy } from 'lodash' import { FormattedDate } from 'react-intl' -import { get } from 'xo-defined' +import { get } from '@xen-orchestra/defined' import { deleteJobsLogs, subscribeJobs, diff --git a/packages/xo-web/src/xo-app/logs/log-alert-header.js b/packages/xo-web/src/xo-app/logs/log-alert-header.js index 0f4a5e2bf..095dd7260 100644 --- a/packages/xo-web/src/xo-app/logs/log-alert-header.js +++ b/packages/xo-web/src/xo-app/logs/log-alert-header.js @@ -8,7 +8,7 @@ import Icon from 'icon' import React from 'react' import ReportBugButton, { CAN_REPORT_BUG } from 'report-bug-button' import Tooltip from 'tooltip' -import { get } from 'xo-defined' +import { get } from '@xen-orchestra/defined' import { injectState, provideState } from '@julien-f/freactal' import { runBackupNgJob, subscribeBackupNgLogs } from 'xo' diff --git a/packages/xo-web/src/xo-app/new-vm/index.js b/packages/xo-web/src/xo-app/new-vm/index.js index 91d89696e..aff99d346 100644 --- a/packages/xo-web/src/xo-app/new-vm/index.js +++ b/packages/xo-web/src/xo-app/new-vm/index.js @@ -3,7 +3,7 @@ import ActionButton from 'action-button' import BaseComponent from 'base-component' import Button from 'button' import classNames from 'classnames' -import defined, { get } from 'xo-defined' +import defined, { get } from '@xen-orchestra/defined' import Icon from 'icon' import isIp from 'is-ip' import Link from 'link' diff --git a/packages/xo-web/src/xo-app/self/index.js b/packages/xo-web/src/xo-app/self/index.js index a522aff34..15df198e5 100644 --- a/packages/xo-web/src/xo-app/self/index.js +++ b/packages/xo-web/src/xo-app/self/index.js @@ -2,7 +2,7 @@ import _ from 'intl' import ActionButton from 'action-button' import Collapse from 'collapse' import Component from 'base-component' -import defined from 'xo-defined' +import defined from '@xen-orchestra/defined' import differenceBy from 'lodash/differenceBy' import filter from 'lodash/filter' import forEach from 'lodash/forEach' diff --git a/packages/xo-web/src/xo-app/settings/cloud-configs/index.js b/packages/xo-web/src/xo-app/settings/cloud-configs/index.js index 0f2f049ea..af532e8b5 100644 --- a/packages/xo-web/src/xo-app/settings/cloud-configs/index.js +++ b/packages/xo-web/src/xo-app/settings/cloud-configs/index.js @@ -1,6 +1,6 @@ import _ from 'intl' import ActionButton from 'action-button' -import defined from 'xo-defined' +import defined from '@xen-orchestra/defined' import React from 'react' import SortedTable from 'sorted-table' import { addSubscriptions, generateRandomId } from 'utils' diff --git a/packages/xo-web/src/xo-app/vm/tab-advanced.js b/packages/xo-web/src/xo-app/vm/tab-advanced.js index e18553cd8..03658483d 100644 --- a/packages/xo-web/src/xo-app/vm/tab-advanced.js +++ b/packages/xo-web/src/xo-app/vm/tab-advanced.js @@ -1,7 +1,7 @@ import _ from 'intl' import ActionButton from 'action-button' import Component from 'base-component' -import defined from 'xo-defined' +import defined from '@xen-orchestra/defined' import getEventValue from 'get-event-value' import Icon from 'icon' import React from 'react' diff --git a/packages/xo-web/src/xo-app/vm/tab-general.js b/packages/xo-web/src/xo-app/vm/tab-general.js index 0e133a266..5c409a1f3 100644 --- a/packages/xo-web/src/xo-app/vm/tab-general.js +++ b/packages/xo-web/src/xo-app/vm/tab-general.js @@ -1,6 +1,6 @@ import _ from 'intl' import Copiable from 'copiable' -import defined from 'xo-defined' +import defined from '@xen-orchestra/defined' import Icon from 'icon' import isEmpty from 'lodash/isEmpty' import map from 'lodash/map' diff --git a/packages/xo-web/src/xo-app/xoa/licenses/index.js b/packages/xo-web/src/xo-app/xoa/licenses/index.js index 316bc761d..4f3d8c85d 100644 --- a/packages/xo-web/src/xo-app/xoa/licenses/index.js +++ b/packages/xo-web/src/xo-app/xoa/licenses/index.js @@ -5,12 +5,12 @@ import Link from 'link' import React from 'react' import renderXoItem from 'render-xo-item' import SortedTable from 'sorted-table' +import { addSubscriptions, connectStore, ShortDate } from 'utils' import { Container, Row, Col } from 'grid' import { createSelector, createGetObjectsOfType } from 'selectors' import { find, forEach } from 'lodash' -import { addSubscriptions, connectStore, ShortDate } from 'utils' +import { get } from '@xen-orchestra/defined' import { subscribePlugins, getLicenses } from 'xo' -import { get } from 'xo-defined' import Xosan from './xosan' diff --git a/packages/xo-web/src/xo-app/xoa/licenses/xosan.js b/packages/xo-web/src/xo-app/xoa/licenses/xosan.js index bbbb09319..917ea2b90 100644 --- a/packages/xo-web/src/xo-app/xoa/licenses/xosan.js +++ b/packages/xo-web/src/xo-app/xoa/licenses/xosan.js @@ -7,10 +7,10 @@ import renderXoItem, { PoolItem } from 'render-xo-item' import SortedTable from 'sorted-table' import { connectStore } from 'utils' import { createSelector, createGetObjectsOfType, createFilter } from 'selectors' -import { unlockXosan } from 'xo' -import { get } from 'xo-defined' import { filter, forEach, includes, map } from 'lodash' +import { get } from '@xen-orchestra/defined' import { injectIntl } from 'react-intl' +import { unlockXosan } from 'xo' @injectIntl class SelectLicense extends Component { diff --git a/packages/xo-web/src/xo-app/xosan/index.js b/packages/xo-web/src/xo-app/xosan/index.js index 66b63f3c2..359d8e632 100644 --- a/packages/xo-web/src/xo-app/xosan/index.js +++ b/packages/xo-web/src/xo-app/xosan/index.js @@ -9,9 +9,9 @@ import React from 'react' import SortedTable from 'sorted-table' import Tooltip from 'tooltip' import { Container, Col, Row } from 'grid' -import { get } from 'xo-defined' -import { every, filter, find, flatten, forEach, isEmpty, map } from 'lodash' import { createGetObjectsOfType, createSelector, isAdmin } from 'selectors' +import { every, filter, find, flatten, forEach, isEmpty, map } from 'lodash' +import { get } from '@xen-orchestra/defined' import { addSubscriptions, connectStore,