├── .eslintrc.yml
├── .gitignore
├── README.md
├── docs
└── rules
│ ├── no-root-store-assets.md
│ ├── no-root-store-calls.md
│ └── require-jsdoc.md
├── lib
├── index.js
├── rules
│ ├── no-root-store-assets.js
│ ├── no-root-store-calls.js
│ └── require-jsdoc.js
└── utils.js
├── license
├── package.json
├── tests
├── lib
│ └── rules
│ │ ├── no-root-store-assets.js
│ │ ├── no-root-store-calls.js
│ │ └── require-jsdoc.js
└── utils.js
└── yarn.lock
/.eslintrc.yml:
--------------------------------------------------------------------------------
1 | extends:
2 | - airbnb-base
3 | - prettier
4 | parser: babel-eslint
5 | root: true
6 | plugins:
7 | - import
8 | - prettier
9 | rules:
10 | quotes:
11 | - error
12 | - "double"
13 | semi:
14 | - error
15 | - "never"
16 | prettier/prettier:
17 | - error
18 | - semi: false
19 | trailingComma: all
20 | # Let Prettier take care of the following rules
21 | comma-dangle: 0
22 | arrow-parens: 0
23 | object-curly-newline: 0
24 | object-curly-spacing: 0
25 | # Strict mode enabled by eslint-generator
26 | strict: 0
27 |
28 |
29 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | node_modules
2 | .npmrc
3 | .cache/
4 | yarn-error.log
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # eslint-plugin-strict-vue
2 |
3 |
4 | [](https://npmjs.org/package/eslint-plugin-strict-vue)
5 |
6 | Various ESLint rules to make you Vue(x) code a bit stricter
7 |
8 | ## 🥋 Requirements
9 | * ESLint >=4.15.0
10 | * Node.js >=8.0.0
11 |
12 | ## 🏋 Installation
13 | ```
14 | $ npm i eslint eslint-plugin-strict-vue --save-dev
15 | ```
16 |
17 | ## 🤹 Usage
18 |
19 | Configure it in `.eslintrc` or `package.json`:
20 |
21 | ```json
22 | {
23 | "name": "my-awesome-project",
24 | "eslintConfig": {
25 | "parserOptions": {
26 | "ecmaVersion": 2018,
27 | "sourceType": "module"
28 | },
29 | "plugins": [
30 | "strict-vue"
31 | ],
32 | "rules": {
33 | "strict-vue/require-jsdoc": "error",
34 | "strict-vue/no-root-store-calls": "error",
35 | "strict-vue/no-root-store-assets": "error",
36 | }
37 | }
38 | }
39 | ```
40 |
41 |
42 | ## 🎭 Rules
43 |
44 | * [require-jsdoc](./docs/rules/require-jsdoc.md) - require JSdoc comments for Vue props, and Vuex actions and state.
45 | * [no-root-store-calls](./docs/rules/no-root-store-calls.md) - disallow dispatch/commit to the global namespase.
46 | * [no-root-store-assets](./docs/rules/no-root-store-assets.md) - disallow the use of rootGetters and rootStore.
47 |
48 | ## License
49 | MIT
50 |
51 |
52 |
53 |
--------------------------------------------------------------------------------
/docs/rules/no-root-store-assets.md:
--------------------------------------------------------------------------------
1 | # Disallow rootGetters and rootState (no-root-store-assets)
2 | Using rootGetters and rootStore might be harmful in a complex applications.
3 | The rule disallows the use of rootGetters and rootStore.
4 |
5 | ## Rule Details
6 | The use of rootStore and rootGetters binds vuex module to a specific implementation of the root store. In order to reuse module elsewhere we have to re-create a specific set of root getters and a specific root state.
7 | Disallowing root store assets leads to better modules isolation and more explicit dependencies in the code.
8 |
9 | ### How to replace getters using rootState/rootGetters
10 | Case: button title depends on the user name
11 |
12 | :thumbsdown: Examples of **incorrect** code for this rule
13 | ```js
14 | actions:
15 | // root store
16 | state: {
17 | state: {
18 | userName: 'Glebka'
19 | }
20 | }
21 | ```
22 |
23 | ```js
24 | // AwesomeModule
25 | getters: {
26 | linkTitle(state, getters, rootState) {
27 | return rootState.userName ? `Hail ${rootState.userName}!` : 'Hi man!'
28 | }
29 | }
30 | ```
31 |
32 | ```js
33 | // container
34 | computed: {
35 | ...mapGetters('AwesomeModule', ['linkTitle'])
36 | }
37 | ```
38 |
39 | ```diff
40 | // template
41 | span {{linkTitle}}
42 | ```
43 |
44 | :thumbsup: Examples of **correct** code for this rule:
45 |
46 | ```js
47 | actions:
48 | // root store
49 | state: {
50 | state: {
51 | userName: 'Glebka'
52 | }
53 | }
54 | ```
55 |
56 | ```diff
57 | // AwesomeModule
58 | getters: {
59 | linkTitle(state, getters) {
60 | // Instead of using rootState return a function that explicitly depends on userName
61 | - return rootState.userName ? `Hail ${rootState.userName}!` : 'Hi man!'
62 | + return userName => userName ? `Hail ${userName}!` : 'Hi man!'
63 | }
64 | }
65 | ```
66 |
67 | ```diff
68 | // container
69 | computed: {
70 | ...mapGetters('AwesomeModule', ['linkTitle']),
71 | + ...mapState(['userName']),
72 | }
73 | ```
74 |
75 | ```diff
76 | // template
77 | - span {{linkTitle}
78 | + span {{linkTitle(userName)}}
79 | ```
80 |
81 |
82 | ### How to replace actions using rootState/rootGetters
83 | Case: weather forecast module depends on the cityID.
84 |
85 | :thumbsdown: Examples of **incorrect** code for this rule
86 |
87 | ```js
88 | // weather module
89 | actions: {
90 | fetchWeatherForecast({ rootGetters }) {
91 | const forecast = await weatherService.getForecast(rootGetters.cityID)
92 | // ...
93 | }
94 | }
95 | ```
96 |
97 | ```js
98 | // container
99 | methods: {
100 | ...mapActions('weather', ['fetchWeatherForecast']),
101 | mounted() {
102 | this.fetchWeatherForecast();
103 | }
104 | }
105 | ```
106 |
107 | :thumbsup: Examples of **correct** code for this rule:
108 |
109 | ```js
110 | // weather module
111 | actions: {
112 | // instead of using rootGetters explicitly pass cityID into the function
113 | fetchWeatherForecast(context, cityID) {
114 | const forecast = await weatherService.getForecast(cityID)
115 | // ...
116 | }
117 | }
118 | ```
119 |
120 | ```diff
121 | // container
122 | methods: {
123 | ...mapActions('weather', ['fetchWeatherForecast']),
124 | + ...mapGetters(['cityID']),
125 | mounted() {
126 | - this.fetchWeatherForecast();
127 | + this.fetchWeatherForecast(cityID);
128 | }
129 | }
130 | ```
131 |
132 | ## When Not To Use It
133 | You might not need this rule if your vuex store is small.
134 |
135 | ## Further Reading
136 |
137 | - [no-root-store-calls](./no-root-store-calls.md) - disallowing dispatch/commit to the global namespase serves the same purposes
--------------------------------------------------------------------------------
/docs/rules/no-root-store-calls.md:
--------------------------------------------------------------------------------
1 | # Disallow global commits and global dispatchs (no-root-store-calls)
2 | Using commit or dispatch with the `{ root: true }` option might be harmful in a complex applications.
3 | The rule disallow root store calls like this:
4 | ```js
5 | actions: {
6 | myAction({ commit, dispath }) {
7 | commit('mutation', args, { root: true })
8 | dispatch({ type: 'anotherAction' }, { root: true })
9 | }
10 | }
11 | ```
12 |
13 | ## Rule Details
14 | Root store calls binds vuex module to a specific implementation of the root store. In order to reuse module elsewhere we have to re-create a specific set of root actions, mutations and a specific root state.
15 | Disallowing root store calls leads to better modules isolation and more explicit dependencies in the code.
16 |
17 | :thumbsdown: Examples of **incorrect** code for this rule
18 |
19 | ```js
20 | // user module
21 | login(ctx) {
22 | // ... logining
23 | // After a successful login we need to show welcome popup which is controlled by another module
24 | ctx.dispatch('welcomePopup/show', null, { root: true})
25 | }
26 | ```
27 |
28 | ```js
29 | // container
30 | methods: {
31 | ...mapActions('user', ['login']),
32 | handleClick() {
33 | // action call
34 | this.login();
35 | }
36 | }
37 | ```
38 |
39 | :thumbsup: Examples of **correct** code for this rule:
40 |
41 | ```diff
42 | // user module
43 | login(ctx) {
44 | // ... logining
45 | - ctx.dispatch('welcomePopup/show', null, { root: true})
46 | }
47 | ```
48 |
49 | ```diff
50 | // container
51 | methods: {
52 | ...mapActions('user', ['login']),
53 | ...mapActions('welcomePopup', ['show']),
54 | handleClick() {
55 | await this.login();
56 | + // instead of dispatching to welocmePopup from login action, call it explicitly in the container:
57 | + this.show()
58 | }
59 | }
60 | ```
61 |
62 | In some complex cases, you may need to watch state or getters and apply actions based on changed values.
63 |
64 | ## When Not To Use It
65 | You might not need this rule if your vuex store is small.
66 |
67 | ## Further Reading
68 |
69 | - [no-root-store-assets](./no-root-store-assets.md) - disallowing rootState and rootGetters serves the same purposes
--------------------------------------------------------------------------------
/docs/rules/require-jsdoc.md:
--------------------------------------------------------------------------------
1 | # Require JSdoc comments (require-jsdoc)
2 | Props is a public api of the Vue component so it should be well documented. The same applies to Vuex state and actions.
3 |
4 | In terms of this rule JSdoc - it's any not empty comment block which starts with `*`. The simplest JSdoc is:
5 | ```js
6 | /** I'm a JSdoc */
7 | ```
8 | ## Rule details
9 |
10 | This rule requires JSDoc comments for specified nodes. Supported nodes:
11 |
12 | * `"VueProps"` - each prop should has JSdoc
13 | * `"VuexState"` - each action should has JSdoc
14 | * `"VuexActions"` - each state property should has JSdoc
15 |
16 | ## Options
17 |
18 | This rule has a single object option:
19 |
20 | * `"require"` requires JSDoc comments for the specified nodes
21 |
22 | Default option settings are:
23 |
24 | ```json
25 | {
26 | "require-jsdoc": ["error", {
27 | "require": {
28 | "VueProps": true,
29 | "VuexState": false,
30 | "VuexActions": false
31 | }
32 | }]
33 | }
34 | ```
35 |
36 | ### require
37 |
38 | :thumbsdown: Examples of **incorrect** code for this rule with the `{ "require": { "VueProps": true, "VuexActions": true, "VuexState": true } }` option:
39 |
40 |
41 | ```js
42 | const GREET_EMEMY = 'greet enemy action';
43 |
44 | function getInitialState() {
45 | return {
46 | message: 'GREETINGS, TRAVELER',
47 | random: Math.random
48 | }
49 | }
50 |
51 | const actions = {
52 | initState() {},
53 | [GREET_EMEMY]() {}
54 | }
55 |
56 | export default function getStore(di) {
57 | // ...
58 | return {
59 | state: getInitialState,
60 | getters: {},
61 | actions
62 | }
63 | }
64 | ```
65 |
66 | ```js
67 | export default {
68 | props: {
69 | title: {
70 | type: String,
71 | default: "Money income"
72 | },
73 | samples: {
74 | type: Array,
75 | required: true
76 | }
77 | },
78 | data() {
79 | return {}
80 | },
81 | // ...
82 | }
83 | ```
84 |
85 | :thumbsup: Examples of **correct** code for this rule:
86 |
87 | ```js
88 | const GREET_EMEMY = 'greet enemy action';
89 |
90 | function getInitialState() {
91 | return {
92 | /** Hunter's greet */
93 | message: 'GREETINGS, TRAVELER',
94 | /** another well documented property */
95 | random: Math.random
96 | }
97 | }
98 |
99 | const actions = {
100 | /** This action performs only on server side */
101 | initState() {},
102 | /** Greets enemy */
103 | [GREET_EMEMY]() {}
104 | }
105 |
106 | export default function getStore(di) {
107 | // ...
108 | return {
109 | state: getInitialState,
110 | getters: {},
111 | actions
112 | }
113 | }
114 | ```
115 |
116 | ```js
117 | export default {
118 | props: {
119 | /** Graph title */
120 | title: {
121 | type: String,
122 | default: "Money income"
123 | },
124 | /**
125 | * Graph data
126 | * @type {Array<{date: Date, money: numer}>}
127 | */
128 | samples: {
129 | type: Array,
130 | required: true
131 | }
132 | },
133 | data() {
134 | return {}
135 | },
136 | // ...
137 | }
138 | ```
139 |
140 | ## When not to use it
141 |
142 | If you do not require JSdoc for your vue props, vuex state or actions
143 |
--------------------------------------------------------------------------------
/lib/index.js:
--------------------------------------------------------------------------------
1 | /**
2 | * @fileoverview Набор eslint правил для vuex сторов N1.RU
3 | * @author glebkaf
4 | */
5 |
6 | "use strict"
7 |
8 | //------------------------------------------------------------------------------
9 | // Requirements
10 | //------------------------------------------------------------------------------
11 |
12 | const requireIndex = require("requireindex")
13 |
14 | //------------------------------------------------------------------------------
15 | // Plugin Definition
16 | //------------------------------------------------------------------------------
17 |
18 | // import all rules in lib/rules
19 | module.exports.rules = requireIndex(`${__dirname}/rules`)
20 |
--------------------------------------------------------------------------------
/lib/rules/no-root-store-assets.js:
--------------------------------------------------------------------------------
1 | "use strict"
2 |
3 | const {
4 | filter,
5 | compose,
6 | pathSatisfies,
7 | forEach,
8 | gte,
9 | map,
10 | pathEq,
11 | path,
12 | cond,
13 | T,
14 | __,
15 | always,
16 | } = require("ramda")
17 | const {
18 | isVuexGetters,
19 | getChildProperties,
20 | getIdentifierValue,
21 | } = require("../utils")
22 |
23 | const reportError = (
24 | assetName = "rootState and rootGetters",
25 | ) => context => node => {
26 | context.report({
27 | node,
28 | messageId: "avoidRootAssets",
29 | data: {
30 | assetName,
31 | },
32 | })
33 | }
34 |
35 | /**
36 | * Check getters for using root assets: rootState or rootGetter, i.e.
37 | * check that arguments length >= 3
38 | */
39 | const checkGettersForRootAssets = (node, context) => {
40 | try {
41 | const childProps = getChildProperties(node, context)
42 |
43 | const mapPropertyToFunction = cond([
44 | [pathEq(["value", "type"], "Identifier"), getIdentifierValue(context)],
45 | [T, path(["value"])],
46 | ])
47 |
48 | compose(
49 | forEach(
50 | cond([
51 | [
52 | pathSatisfies(gte(__, 4), ["params", "length"]),
53 | reportError("rootGetters")(context),
54 | ],
55 | [
56 | pathSatisfies(gte(__, 3), ["params", "length"]),
57 | reportError("rootState")(context),
58 | ],
59 | [T, always()],
60 | ]),
61 | ),
62 | map(mapPropertyToFunction),
63 | )(childProps)
64 | } catch (e) {
65 | console.error(`${e.message} \n at file: ${context.getFilename()}`)
66 | }
67 | }
68 |
69 | module.exports = {
70 | meta: {
71 | docs: {
72 | description: "Prevent from using rootState and rootGetters",
73 | },
74 | schema: [],
75 | messages: {
76 | avoidRootAssets: "Don't use {{ assetName }}",
77 | },
78 | },
79 |
80 | create(context) {
81 | return {
82 | // handle getters
83 | "ObjectExpression > Property": node => {
84 | if (isVuexGetters(node)) {
85 | checkGettersForRootAssets(node, context)
86 | }
87 | },
88 | // handle actions
89 | "Property[key.name='rootGetters']": reportError("rootGetters")(context),
90 | "Property[key.name='rootState']": reportError("rootState")(context),
91 | "MemberExpression[property.name='rootGetters']": reportError(
92 | "rootGetters",
93 | )(context),
94 | "MemberExpression[property.name='rootState']": reportError("rootState")(
95 | context,
96 | ),
97 | }
98 | },
99 | }
100 |
--------------------------------------------------------------------------------
/lib/rules/no-root-store-calls.js:
--------------------------------------------------------------------------------
1 | const R = require("ramda")
2 |
3 | /**
4 | * Checks whether commit or dispatch in the global namespace i.e.
5 | * check for { root: true } argument.
6 | */
7 | const checkRootCall = context => node => {
8 | try {
9 | const arg2 = R.path(["arguments", "1"], node)
10 | const arg3 = R.path(["arguments", "2"], node)
11 |
12 | const isRootArg = arg =>
13 | R.pathEq(["properties", "0", "key", "name"], "root", arg) &&
14 | R.pathEq(["properties", "0", "value", "value"], true, arg)
15 |
16 | const isRootCall = isRootArg(arg2) || isRootArg(arg3)
17 | const actionName =
18 | R.path(["callee", "name"], node) ||
19 | R.path(["callee", "property", "name"], node)
20 |
21 | if (isRootCall) {
22 | context.report({
23 | node,
24 | messageId: "avoidRootCalls",
25 | data: {
26 | actionName,
27 | },
28 | })
29 | }
30 | } catch (e) {
31 | console.error(`${e.message} \n at file: ${context.getFilename()}`)
32 | }
33 | }
34 |
35 | module.exports = {
36 | meta: {
37 | docs: {
38 | description:
39 | "Prevent from dispatching actions or commiting mutations in the global namespace",
40 | },
41 | schema: [],
42 | messages: {
43 | avoidRootCalls: "Don't {{ actionName }} in the global namespace.",
44 | },
45 | },
46 | create(context) {
47 | return {
48 | "CallExpression[callee.name='commit']": checkRootCall(context),
49 | "CallExpression[callee.property.name='commit']": checkRootCall(context),
50 | "CallExpression[callee.name='dispatch']": checkRootCall(context),
51 | "CallExpression[callee.property.name='dispatch']": checkRootCall(context),
52 | }
53 | },
54 | }
55 |
--------------------------------------------------------------------------------
/lib/rules/require-jsdoc.js:
--------------------------------------------------------------------------------
1 | "use strict"
2 |
3 | const R = require("ramda")
4 | const {
5 | getChildProperties,
6 | isVuexActions,
7 | isVuexState,
8 | isVueProps,
9 | } = require("../utils")
10 |
11 | const reportError = context => node => {
12 | if (!node.key) {
13 | throw new Error(`Node has no key: ${node}`)
14 | }
15 |
16 | context.report({
17 | node: node.key,
18 | message: "Missing JSDoc comment.",
19 | })
20 | }
21 |
22 | /** Checks that given node has no valid doc */
23 | const hasNoValidDoc = context => node => {
24 | const comments = context.getCommentsBefore(node) || []
25 | const hasValidDoc = comments
26 | .filter(({ type }) => type === "Block")
27 | .map(({ value = "" }) => value.trim())
28 | .some(value => value.startsWith("*") && value.length > 1)
29 | return !hasValidDoc
30 | }
31 |
32 | /** Checks that all properties inside given property has valid doc */
33 | const checkNestedPropertiesForDoc = (node, context) => {
34 | try {
35 | const childProps = getChildProperties(node, context)
36 |
37 | const filterPropsWithJsdoc = R.filter(hasNoValidDoc(context))
38 | const jsdoclessProps = filterPropsWithJsdoc(childProps)
39 |
40 | jsdoclessProps.forEach(reportError(context))
41 | } catch (e) {
42 | console.error(`${e.message} \n at file: ${context.getFilename()}`)
43 | }
44 | }
45 |
46 | module.exports = {
47 | meta: {
48 | docs: {
49 | description:
50 | "Require JSdoc comments at Vue props, and Vuex actions and state.",
51 | category: "Stylistic Issues",
52 | },
53 | schema: [
54 | {
55 | type: "object",
56 | properties: {
57 | require: {
58 | type: "object",
59 | properties: {
60 | VueProps: {
61 | type: "boolean",
62 | },
63 | VuexActions: {
64 | type: "boolean",
65 | },
66 | VuexState: {
67 | type: "boolean",
68 | },
69 | },
70 | additionalProperties: false,
71 | },
72 | },
73 | additionalProperties: false,
74 | },
75 | ],
76 | },
77 |
78 | create(context) {
79 | const defaultOptions = {
80 | VueProps: true,
81 | VuexActions: false,
82 | VuexState: false,
83 | }
84 |
85 | const { VuexActions, VuexState, VueProps } = R.merge(
86 | defaultOptions,
87 | R.path(["options", 0, "require"], context),
88 | )
89 |
90 | return {
91 | "ObjectExpression > Property": node => {
92 | if (isVuexActions(node) && VuexActions) {
93 | checkNestedPropertiesForDoc(node, context)
94 | }
95 |
96 | if (isVuexState(node) && VuexState) {
97 | checkNestedPropertiesForDoc(node, context)
98 | }
99 |
100 | if (isVueProps(node) && VueProps) {
101 | checkNestedPropertiesForDoc(node, context)
102 | }
103 | },
104 | }
105 | },
106 | }
107 |
--------------------------------------------------------------------------------
/lib/utils.js:
--------------------------------------------------------------------------------
1 | const R = require("ramda")
2 |
3 | /** Finds variable with given name */
4 | function findVariable(scope, variableName) {
5 | if (!scope) {
6 | return undefined
7 | }
8 | const { variables, upper } = scope
9 | const variable = variables.find(({ name }) => variableName === name)
10 |
11 | return variable || findVariable(upper, variableName)
12 | }
13 |
14 | /**
15 | * Finds identifier defenition.
16 | * Using to resolve actual value of link.
17 | */
18 | const getIdentifierDefenition = context => identifier => {
19 | const { name } = identifier.value
20 | const variable = findVariable(context.getScope(identifier.value), name)
21 |
22 | if (!variable) {
23 | throw new Error(`Cant find variable assigned to identifier: '${name}'`)
24 | }
25 |
26 | const defenition = R.last(variable.defs)
27 |
28 | if (!defenition) {
29 | throw new Error(`Cant find defenition of variable: '${variable.name}'`)
30 | }
31 |
32 | return defenition
33 | }
34 |
35 | /**
36 | * Finds identifier value.
37 | * Using to resolve actual value of link.
38 | */
39 | const getIdentifierValue = context => identifier => {
40 | const { type, node } = getIdentifierDefenition(context)(identifier)
41 |
42 | if (type === "Variable") {
43 | return node.init // => Variable Value
44 | }
45 |
46 | if (type === "FunctionName") {
47 | return node // => FunctionDeclaration
48 | }
49 |
50 | // can't resolve Identifier value
51 | return null
52 | }
53 |
54 | /**
55 | * Find return statement value.
56 | * Using when linting component's data, and vuex's state.
57 | */
58 | const findReturnStatement = node => {
59 | if (!node.body) {
60 | return undefined
61 | }
62 |
63 | const returnStatement = R.find(
64 | ({ type }) => type === "ReturnStatement",
65 | node.body,
66 | )
67 |
68 | return returnStatement || findReturnStatement(node.body)
69 | }
70 |
71 | // Skip spread elements for now
72 | const filterUnsupportedProps = properties =>
73 | properties
74 | .filter(({ type }) => type !== "SpreadElement") // eslint 5+
75 | .filter(({ type }) => type !== "ExperimentalSpreadProperty") // eslint 4, babel-eslint
76 |
77 | /** Return child properties of given node */
78 | const getChildProperties = (node, context) => {
79 | if (node.value.type === "ObjectExpression") {
80 | return filterUnsupportedProps(node.value.properties)
81 | }
82 |
83 | if (node.value.type === "Identifier") {
84 | const value = getIdentifierValue(context)(node)
85 |
86 | if (!value) {
87 | return []
88 | }
89 |
90 | if (value.type === "FunctionDeclaration") {
91 | const returnStatement = findReturnStatement(value)
92 | return filterUnsupportedProps(returnStatement.argument.properties)
93 | }
94 |
95 | if (value.type === "ObjectExpression") {
96 | return filterUnsupportedProps(value.properties)
97 | }
98 |
99 | return []
100 | }
101 |
102 | return []
103 | }
104 |
105 | /**
106 | * Checks that given property is inside vuex store object.
107 | * Assume that we are working with vuex object, if it contain 2 or more valid vuex keys
108 | */
109 | const isWithinVuexStore = property => {
110 | const validKeys = [
111 | "state",
112 | "actions",
113 | "mutations",
114 | "getters",
115 | "namespaced",
116 | "modules",
117 | ]
118 |
119 | const keys = property.parent.properties.map(R.path(["key", "name"]))
120 |
121 | const hasOnlyStateAndGetters = R.equals(
122 | keys.sort(),
123 | ["state", "getters"].sort(),
124 | )
125 |
126 | /**
127 | * Can't decide whether object is vuex store or it is action context
128 | * if it has only state and getters
129 | */
130 | if (hasOnlyStateAndGetters) {
131 | return false
132 | }
133 |
134 | const vaildKeysInsideProperties = R.innerJoin(
135 | (key, vaildKey) => key === vaildKey,
136 | keys,
137 | validKeys,
138 | )
139 | const hasOnlyValidKeys = R.all(key => validKeys.includes(key), keys)
140 |
141 | return R.length(vaildKeysInsideProperties) >= 2 && hasOnlyValidKeys
142 | }
143 |
144 | /**
145 | * Checks that given property is inside vue component object.
146 | * Assume that we are working with vue component, if it contain 2 or more valid vue keys
147 | */
148 | const isWithinVueComponent = property => {
149 | const validKeys = [
150 | "props",
151 | "data",
152 | "components",
153 | "computed",
154 | "methods",
155 | "watch",
156 | ]
157 | const keys = property.parent.properties.map(R.path(["key", "name"]))
158 | const vaildKeysInsideProperties = R.innerJoin(
159 | (key, vaildKey) => key === vaildKey,
160 | keys,
161 | validKeys,
162 | )
163 | return R.length(vaildKeysInsideProperties) >= 2
164 | }
165 |
166 | const isVuexActions = node =>
167 | isWithinVuexStore(node) && node.key.name === "actions"
168 |
169 | const isVuexGetters = node =>
170 | isWithinVuexStore(node) && node.key.name === "getters"
171 |
172 | const isVuexState = node => isWithinVuexStore(node) && node.key.name === "state"
173 |
174 | const isVueProps = node =>
175 | isWithinVueComponent(node) && node.key.name === "props"
176 |
177 | module.exports = {
178 | getIdentifierDefenition,
179 | getIdentifierValue,
180 | getChildProperties,
181 | isVuexGetters,
182 | isVuexActions,
183 | isVuexState,
184 | isVueProps,
185 | }
186 |
--------------------------------------------------------------------------------
/license:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) Sindre Sorhus (sindresorhus.com)
4 |
5 | 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:
6 |
7 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
8 |
9 | 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.
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "eslint-plugin-strict-vue",
3 | "version": "1.0.0",
4 | "description": "Various ESLint rules to make you Vue(x) code a bit stricter",
5 | "keywords": [
6 | "eslint",
7 | "eslintplugin",
8 | "vue",
9 | "vuex",
10 | "jsdoc"
11 | ],
12 | "author": "glebkaf",
13 | "license": "MIT",
14 | "repository": {
15 | "type": "git",
16 | "url": "https://github.com/GlebkaF/eslint-plugin-strict-vue"
17 | },
18 | "main": "lib/index.js",
19 | "scripts": {
20 | "test": "mocha tests --recursive"
21 | },
22 | "dependencies": {
23 | "ramda": "^0.25.0",
24 | "requireindex": "~1.1.0"
25 | },
26 | "devDependencies": {
27 | "babel-eslint": "^8.2.6",
28 | "eslint": "^5.3.0",
29 | "eslint-config-airbnb-base": "^13.0.0",
30 | "eslint-config-prettier": "^2.9.0",
31 | "eslint-plugin-import": "^2.13.0",
32 | "eslint-plugin-prettier": "^2.6.2",
33 | "mocha": "^3.1.2",
34 | "prettier": "^1.14.0"
35 | },
36 | "engines": {
37 | "node": ">=8"
38 | }
39 | }
40 |
--------------------------------------------------------------------------------
/tests/lib/rules/no-root-store-assets.js:
--------------------------------------------------------------------------------
1 | const R = require("ramda")
2 | const { RuleTester } = require("eslint")
3 | const rule = require("../../../lib/rules/no-root-store-assets")
4 | const { prepareCases } = require("../../utils")
5 |
6 | RuleTester.setDefaultConfig({
7 | parserOptions: {
8 | ecmaVersion: 2018,
9 | sourceType: "module",
10 | },
11 | })
12 |
13 | const ruleTester = new RuleTester()
14 |
15 | const invalidCases = [
16 | {
17 | title: "Root state and getters used by getters",
18 | code: `
19 | const getter5 = function(state, getters, { a }, { b }) {};
20 |
21 | const store = {
22 | state: {},
23 | namespaced: true,
24 | getters: {
25 | getter1(state, getters, rootState, rootGetters) {},
26 | getter2(state, getters, rS, rG) {},
27 | getter3(state, getters, { asd }, { qwe }) {},
28 | getter4: (state, getters, rootState, rootGetters) => {},
29 | getter5,
30 | },
31 | };
32 | `,
33 | errors: R.times(
34 | R.always({
35 | messageId: "avoidRootAssets",
36 | }),
37 | 5,
38 | ),
39 | },
40 | {
41 | title: "Deep linked getter",
42 | code: `
43 | const getter = function(state, getters, { a }, { b }) {};
44 |
45 | const getters = {
46 | getter,
47 | };
48 |
49 | const store = {
50 | state: {},
51 | namespaced: true,
52 | getters: {
53 | getter,
54 | },
55 | };
56 |
57 | `,
58 | errors: R.times(
59 | R.always({
60 | messageId: "avoidRootAssets",
61 | }),
62 | 1,
63 | ),
64 | },
65 | {
66 | title: "Root state and getters used by actions",
67 | code: `
68 | const action6 = function (ctx) {
69 | console.log(ctx.rootState)
70 | console.log(ctx.rootGetters)
71 | };
72 |
73 | const store = {
74 | state: {},
75 | namespaced: true,
76 | actions: {
77 | action1({ rootState, rootGetters }) {},
78 | action2({ rootState: rs, rootGetters: rg }) {},
79 | action3: function({ rootState, rootGetters }) {},
80 | action4: (ctx) => {
81 | const { rootState, rootGetters } = ctx;
82 | },
83 | action5(ctx) {
84 | console.log(ctx.rootState);
85 | console.log(ctx.rootGetters);
86 | },
87 | action6,
88 | },
89 | };
90 | `,
91 | errors: R.times(
92 | R.always({
93 | messageId: "avoidRootAssets",
94 | }),
95 | 12,
96 | ),
97 | },
98 | ]
99 |
100 | const validCases = [
101 | {
102 | title: "Getters like objects, but not getters",
103 | code: `
104 | const store = {
105 | state: {},
106 | thisIsNotGetters: {
107 | gettersLike(state, getters, rootState) {
108 |
109 | },
110 | },
111 | }
112 | `,
113 | },
114 | {
115 | title: "Valid use of context object",
116 | code: `
117 | const store = {
118 | state: {},
119 | namespaced: true,
120 | actions: {
121 | action({ commit, dispatch, state }) {},
122 | action2(ctx) {
123 | console.log(ctx.state);
124 | console.log(ctx.getters);
125 | },
126 | },
127 | };
128 | `,
129 | },
130 | ]
131 |
132 | const { valid, invalid } = prepareCases(validCases, invalidCases)
133 |
134 | ruleTester.run("no-root-store-assets", rule, {
135 | valid,
136 | invalid,
137 | })
138 |
--------------------------------------------------------------------------------
/tests/lib/rules/no-root-store-calls.js:
--------------------------------------------------------------------------------
1 | const R = require("ramda")
2 | const { RuleTester } = require("eslint")
3 | const rule = require("../../../lib/rules/no-root-store-calls")
4 | const { prepareCases } = require("../../utils")
5 |
6 | RuleTester.setDefaultConfig({
7 | parserOptions: {
8 | ecmaVersion: 2018,
9 | sourceType: "module",
10 | },
11 | })
12 |
13 | const ruleTester = new RuleTester()
14 |
15 | const invalidCases = [
16 | {
17 | title: "disapatch global action by calling ctx method",
18 | code: `
19 | export default function createSomeStore() {
20 | return {
21 | actions: {
22 | action(ctx) {
23 | ctx.commit({ type: 'a' }, { root: true })
24 | ctx.dispatch('b', null, { root: true })
25 | const { commit, dispatch } = ctx;
26 | commit('c', null, { root: true })
27 | dispatch({ type: 'd' }, { root: true })
28 | },
29 | },
30 | }
31 | }
32 | `,
33 | errors: R.times(
34 | R.always({
35 | messageId: "avoidRootCalls",
36 | }),
37 | 4,
38 | ),
39 | },
40 | {
41 | title: "commit global mutation by calling destructured method",
42 | code: `
43 | export default function createSomeStore() {
44 | return {
45 | actions: {
46 | action({ commit, dispatch }) {
47 | commit('b', null, { root: true })
48 | dispatch({ type: 'a' }, { root: true })
49 | },
50 | },
51 | }
52 | }
53 | `,
54 | errors: R.times(
55 | R.always({
56 | messageId: "avoidRootCalls",
57 | }),
58 | 2,
59 | ),
60 | },
61 | ]
62 |
63 | const validCases = [
64 | {
65 | title: "disapatch local action by calling ctx method",
66 | code: `
67 | export default function createSomeStore() {
68 | return {
69 | actions: {
70 | action(ctx) {
71 | ctx.commit('1')
72 | },
73 | },
74 | }
75 | }
76 | `,
77 | },
78 | {
79 | title: "commit local mutation by calling destructured method",
80 | code: `
81 | export default function createSomeStore() {
82 | return {
83 | actions: {
84 | action({ dispatch, commit }) {
85 | dispatch(1, null)
86 | commit({ type: 'm', prop: 1})
87 | },
88 | },
89 | }
90 | }
91 | `,
92 | },
93 | ]
94 |
95 | const { valid, invalid } = prepareCases(validCases, invalidCases)
96 |
97 | ruleTester.run("no-root-store-calls", rule, {
98 | valid,
99 | invalid,
100 | })
101 |
--------------------------------------------------------------------------------
/tests/lib/rules/require-jsdoc.js:
--------------------------------------------------------------------------------
1 | const { RuleTester } = require("eslint")
2 | const rule = require("../../../lib/rules/require-jsdoc")
3 | const { prepareCases } = require("../../utils")
4 |
5 | RuleTester.setDefaultConfig({
6 | parserOptions: {
7 | ecmaVersion: 2018,
8 | sourceType: "module",
9 | },
10 | })
11 |
12 | const ruleTester = new RuleTester()
13 |
14 | const ERROR_MESSAGE = "Missing JSDoc comment."
15 | const ACTION_PROP = "actions"
16 |
17 | const OPTIONS = [
18 | {
19 | require: {
20 | VueProps: true,
21 | VuexActions: true,
22 | VuexState: true,
23 | },
24 | },
25 | ]
26 |
27 | const getVuexCore = (prop = "getters") => `${prop}: {},`
28 |
29 | // Base test cases are cases that could be both valid and invalid
30 | // depending on the comment before childProp
31 | const createBaseCases = ({ comment }) => [
32 | {
33 | title: "store object returned by function",
34 | options: OPTIONS,
35 | code: `function createStore() {
36 | return {
37 | ${getVuexCore()}
38 | ${ACTION_PROP}: {
39 | ${comment}
40 | initState() {}
41 | }
42 | };
43 | }`,
44 | },
45 | {
46 | title: "inline store object",
47 | options: OPTIONS,
48 | code: `
49 | new Vuex.Store({
50 | ${getVuexCore()}
51 | ${ACTION_PROP}: {
52 | ${comment}
53 | initState() {}
54 | }
55 | });
56 | `,
57 | },
58 | {
59 | title: "child prop is the state",
60 | options: OPTIONS,
61 | code: `function createStore() {
62 | return {
63 | ${getVuexCore("actions")}
64 | state: {
65 | ${comment}
66 | initState() {}
67 | }
68 | };
69 | }`,
70 | },
71 | {
72 | title: "child prop is es6 function shorthand",
73 | options: OPTIONS,
74 | code: `const store = {
75 | ${getVuexCore("getters")}
76 | ${ACTION_PROP}: {
77 | ${comment}
78 | initState() {}
79 | }
80 | };`,
81 | },
82 | {
83 | title: "child prop is an arrow function",
84 | options: OPTIONS,
85 | code: `const store = {
86 | ${getVuexCore("mutations")}
87 | ${ACTION_PROP}: {
88 | ${comment}
89 | initState: () => {}
90 | }
91 | };`,
92 | },
93 | {
94 | title: "child prop is a regular function",
95 | options: OPTIONS,
96 | code: `const store = {
97 | ${getVuexCore("modules")}
98 | ${ACTION_PROP}: {
99 | ${comment}
100 | initState: function initState () {}
101 | }
102 | };`,
103 | },
104 | {
105 | title: "parent prop linked to object with different name",
106 | options: OPTIONS,
107 | code: `
108 | const awesomeName = {
109 | ${comment}
110 | initState: {}
111 | }
112 |
113 | const store = {
114 | namespaced: true,
115 | ${ACTION_PROP}: awesomeName
116 | };`,
117 | },
118 | {
119 | title: "parent prop is es6 property shorthand syntax",
120 | options: OPTIONS,
121 | code: `
122 | const justVariableForSettingUpSomeScope = '';
123 | const ${ACTION_PROP} = {
124 | ${comment}
125 | initState: {}
126 | }
127 |
128 | const store = {
129 | ${getVuexCore()}
130 | ${ACTION_PROP}
131 | };`,
132 | },
133 | {
134 | title: "child property linked to identyfier",
135 | options: OPTIONS,
136 | code: `
137 | const varibaleName = function initState () {};
138 | const ${ACTION_PROP} = {
139 | ${comment}
140 | initState: varibaleName
141 | };
142 |
143 | const store = {
144 | ${getVuexCore()}
145 | ${ACTION_PROP}
146 | };`,
147 | },
148 | {
149 | title: "spread childs",
150 | options: OPTIONS,
151 | code: `
152 | const getProps = () => {};
153 |
154 | const store = {
155 | ${getVuexCore()}
156 | ${ACTION_PROP}: {
157 | ...getProps(),
158 | ${comment}
159 | initState() {},
160 | }
161 | };`,
162 | },
163 | {
164 | title: "deep nested store object",
165 | options: OPTIONS,
166 | code: `
167 | export const mutations = {};
168 |
169 | const ${ACTION_PROP} = {
170 | ${comment}
171 | initState: function initState () {}
172 | };
173 | export default function createSsrStore() {
174 | return function nestedFunctions() {
175 | return {
176 | ${getVuexCore()}
177 | ${ACTION_PROP},
178 | mutations
179 | };
180 | }
181 | };`,
182 | },
183 | {
184 | title: "state is a function",
185 | options: OPTIONS,
186 | code: `
187 | function initialState() {
188 | return {
189 | ${comment}
190 | a: ''
191 | }
192 | }
193 |
194 | const store = {
195 | ${getVuexCore()}
196 | state: initialState,
197 | getters: {}
198 | }`,
199 | },
200 | {
201 | title: "vue props",
202 | options: OPTIONS,
203 | code: `
204 | export default {
205 | data() {},
206 | props: {
207 | ${comment}
208 | propA: {
209 |
210 | }
211 | }
212 | }
213 | `,
214 | },
215 | ]
216 |
217 | const baseValidCases = createBaseCases({ comment: "/** Simple valid jsdoc */" })
218 | const baseInvalidCases = createBaseCases({ comment: "" }).map(testCase => ({
219 | ...testCase,
220 | errors: [
221 | {
222 | message: ERROR_MESSAGE,
223 | },
224 | ],
225 | }))
226 |
227 | /**
228 | * Specify `only: true` prop. for stanalone testcase run.
229 | * Specify `skip: true` prop. to skip testcase
230 | */
231 | const validCases = [
232 | ...baseValidCases,
233 | {
234 | title: "empty parent",
235 | code: `const store = {
236 | ${getVuexCore()}
237 | ${ACTION_PROP}: {}
238 | };`,
239 | options: OPTIONS,
240 | },
241 | {
242 | title: "parent prop default import",
243 | code: `
244 | import ${ACTION_PROP} from 'store';
245 | const store = {
246 | ${getVuexCore()}
247 | ${ACTION_PROP},
248 | };`,
249 | options: OPTIONS,
250 | },
251 | {
252 | title: "parent prop named import",
253 | code: `
254 | import { ${ACTION_PROP} } from 'store';
255 | const store = {
256 | ${getVuexCore()}
257 | ${ACTION_PROP},
258 | };`,
259 | options: OPTIONS,
260 | },
261 | {
262 | title: "Object has actions key, but it's not vuex store",
263 | code: `
264 | const store = {
265 | justSomeKey: 'asd',
266 | ${ACTION_PROP}: {
267 | someKey() {},
268 | }
269 | };`,
270 | options: OPTIONS,
271 | },
272 | {
273 | title: "Actions is not an Object",
274 | code: `
275 | const store = {
276 | ${getVuexCore("namespaced")}
277 | ${ACTION_PROP}: "just string"
278 | };`,
279 | options: OPTIONS,
280 | },
281 | {
282 | title: "Should not throw error for store like objects",
283 | code: `
284 | const state = {
285 | asd: 111
286 | };
287 |
288 | const storeLikeObject = {
289 | commit: {},
290 | getters: {},
291 | state,
292 | rootGetters: {},
293 | };`,
294 | options: OPTIONS,
295 | },
296 | {
297 | title: "Should not throw error if only state and getters provided",
298 | code: `
299 | const state = {
300 | asd: 111
301 | };
302 |
303 | const storeLikeObject = {
304 | getters: {},
305 | state
306 | };`,
307 | options: OPTIONS,
308 | },
309 | {
310 | title: "Should not throw error when desctucturing state in action",
311 | code: `
312 | const state = {
313 | asd: 1
314 | };
315 |
316 | export default function a() {
317 | return {
318 | state: {},
319 | actions: {
320 | /** jsdoc */
321 | action({ state, getters }){}
322 | },
323 | };
324 | }`,
325 | options: OPTIONS,
326 | },
327 | ]
328 |
329 | const invalidCases = [
330 | ...baseInvalidCases,
331 | {
332 | title: "jsdoc is empty comment line",
333 | code: `const store = {
334 | ${getVuexCore()}
335 | ${ACTION_PROP}: {
336 | //
337 | initState() {},
338 | }
339 | };`,
340 | errors: [
341 | {
342 | message: ERROR_MESSAGE,
343 | },
344 | ],
345 | options: OPTIONS,
346 | },
347 | {
348 | title: "jsdoc is empty comment block",
349 | code: `const store = {
350 | ${getVuexCore()}
351 | ${ACTION_PROP}: {
352 | /* */
353 | initState() {},
354 | }
355 | };`,
356 | errors: [
357 | {
358 | message: ERROR_MESSAGE,
359 | },
360 | ],
361 | options: OPTIONS,
362 | },
363 |
364 | {
365 | title: "state + actions",
366 | code: `function createStore() {
367 | return {
368 | ${getVuexCore("actions")}
369 | state: {
370 | someValue: '',
371 | },
372 | ${ACTION_PROP}: {
373 | initState() {}
374 | }
375 | };
376 | }`,
377 | errors: [
378 | {
379 | message: ERROR_MESSAGE,
380 | },
381 | {
382 | message: ERROR_MESSAGE,
383 | },
384 | ],
385 | options: OPTIONS,
386 | },
387 | {
388 | title: "Only state rule enabled",
389 | code: `function createStore() {
390 | return {
391 | ${getVuexCore("actions")}
392 | state: {
393 | someValue: '',
394 | },
395 | ${ACTION_PROP}: {
396 | initState() {}
397 | }
398 | };
399 | }`,
400 | errors: [
401 | {
402 | message: ERROR_MESSAGE,
403 | },
404 | ],
405 | options: [
406 | {
407 | require: {
408 | VuexActions: false,
409 | VuexState: true,
410 | },
411 | },
412 | ],
413 | },
414 | ]
415 |
416 | const { valid, invalid } = prepareCases(validCases, invalidCases)
417 |
418 | ruleTester.run("require-jsdoc", rule, {
419 | valid,
420 | invalid,
421 | })
422 |
--------------------------------------------------------------------------------
/tests/utils.js:
--------------------------------------------------------------------------------
1 | const { isEmpty, map, omit, filter } = require("ramda")
2 |
3 | /**
4 | * Prepare testcases by filtering using skip and only props.
5 | * @param {Array} valid - valid testcases, each test may contain skip or only property
6 | * @param {Array} invalid - valid testcases, each test may contain skip or only property
7 | * @return {{valid: Array, invalid: Array}}
8 | */
9 | function prepareCases(valid = [], invalid) {
10 | const filterStandalone = filter(({ only = false }) => only)
11 | const filterSkiped = filter(({ skip = false }) => !skip)
12 | const omitProps = map(omit(["only", "skip", "title"]))
13 |
14 | const standaloneValidCases = filterStandalone(valid)
15 | const standaloneInvalidCases = filterStandalone(invalid)
16 |
17 | const prepareReturnValue = (v, i) => ({
18 | valid: omitProps(filterSkiped(v)),
19 | invalid: omitProps(filterSkiped(i)),
20 | })
21 |
22 | // there are no standalone testcases
23 | if (isEmpty(standaloneValidCases) && isEmpty(standaloneInvalidCases)) {
24 | return prepareReturnValue(valid, invalid)
25 | }
26 |
27 | return prepareReturnValue(standaloneValidCases, standaloneInvalidCases)
28 | }
29 |
30 | module.exports = {
31 | prepareCases,
32 | }
33 |
--------------------------------------------------------------------------------
/yarn.lock:
--------------------------------------------------------------------------------
1 | # THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY.
2 | # yarn lockfile v1
3 |
4 |
5 | "@babel/code-frame@7.0.0-beta.44":
6 | version "7.0.0-beta.44"
7 | resolved "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.0.0-beta.44.tgz#2a02643368de80916162be70865c97774f3adbd9"
8 | dependencies:
9 | "@babel/highlight" "7.0.0-beta.44"
10 |
11 | "@babel/generator@7.0.0-beta.44":
12 | version "7.0.0-beta.44"
13 | resolved "https://registry.npmjs.org/@babel/generator/-/generator-7.0.0-beta.44.tgz#c7e67b9b5284afcf69b309b50d7d37f3e5033d42"
14 | dependencies:
15 | "@babel/types" "7.0.0-beta.44"
16 | jsesc "^2.5.1"
17 | lodash "^4.2.0"
18 | source-map "^0.5.0"
19 | trim-right "^1.0.1"
20 |
21 | "@babel/helper-function-name@7.0.0-beta.44":
22 | version "7.0.0-beta.44"
23 | resolved "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.0.0-beta.44.tgz#e18552aaae2231100a6e485e03854bc3532d44dd"
24 | dependencies:
25 | "@babel/helper-get-function-arity" "7.0.0-beta.44"
26 | "@babel/template" "7.0.0-beta.44"
27 | "@babel/types" "7.0.0-beta.44"
28 |
29 | "@babel/helper-get-function-arity@7.0.0-beta.44":
30 | version "7.0.0-beta.44"
31 | resolved "https://registry.npmjs.org/@babel/helper-get-function-arity/-/helper-get-function-arity-7.0.0-beta.44.tgz#d03ca6dd2b9f7b0b1e6b32c56c72836140db3a15"
32 | dependencies:
33 | "@babel/types" "7.0.0-beta.44"
34 |
35 | "@babel/helper-split-export-declaration@7.0.0-beta.44":
36 | version "7.0.0-beta.44"
37 | resolved "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.0.0-beta.44.tgz#c0b351735e0fbcb3822c8ad8db4e583b05ebd9dc"
38 | dependencies:
39 | "@babel/types" "7.0.0-beta.44"
40 |
41 | "@babel/highlight@7.0.0-beta.44":
42 | version "7.0.0-beta.44"
43 | resolved "https://registry.npmjs.org/@babel/highlight/-/highlight-7.0.0-beta.44.tgz#18c94ce543916a80553edcdcf681890b200747d5"
44 | dependencies:
45 | chalk "^2.0.0"
46 | esutils "^2.0.2"
47 | js-tokens "^3.0.0"
48 |
49 | "@babel/template@7.0.0-beta.44":
50 | version "7.0.0-beta.44"
51 | resolved "https://registry.npmjs.org/@babel/template/-/template-7.0.0-beta.44.tgz#f8832f4fdcee5d59bf515e595fc5106c529b394f"
52 | dependencies:
53 | "@babel/code-frame" "7.0.0-beta.44"
54 | "@babel/types" "7.0.0-beta.44"
55 | babylon "7.0.0-beta.44"
56 | lodash "^4.2.0"
57 |
58 | "@babel/traverse@7.0.0-beta.44":
59 | version "7.0.0-beta.44"
60 | resolved "https://registry.npmjs.org/@babel/traverse/-/traverse-7.0.0-beta.44.tgz#a970a2c45477ad18017e2e465a0606feee0d2966"
61 | dependencies:
62 | "@babel/code-frame" "7.0.0-beta.44"
63 | "@babel/generator" "7.0.0-beta.44"
64 | "@babel/helper-function-name" "7.0.0-beta.44"
65 | "@babel/helper-split-export-declaration" "7.0.0-beta.44"
66 | "@babel/types" "7.0.0-beta.44"
67 | babylon "7.0.0-beta.44"
68 | debug "^3.1.0"
69 | globals "^11.1.0"
70 | invariant "^2.2.0"
71 | lodash "^4.2.0"
72 |
73 | "@babel/types@7.0.0-beta.44":
74 | version "7.0.0-beta.44"
75 | resolved "https://registry.npmjs.org/@babel/types/-/types-7.0.0-beta.44.tgz#6b1b164591f77dec0a0342aca995f2d046b3a757"
76 | dependencies:
77 | esutils "^2.0.2"
78 | lodash "^4.2.0"
79 | to-fast-properties "^2.0.0"
80 |
81 | acorn-jsx@^4.1.1:
82 | version "4.1.1"
83 | resolved "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-4.1.1.tgz#e8e41e48ea2fe0c896740610ab6a4ffd8add225e"
84 | dependencies:
85 | acorn "^5.0.3"
86 |
87 | acorn@^5.0.3, acorn@^5.6.0:
88 | version "5.7.4"
89 | resolved "https://registry.yarnpkg.com/acorn/-/acorn-5.7.4.tgz#3e8d8a9947d0599a1796d10225d7432f4a4acf5e"
90 |
91 | ajv-keywords@^3.0.0:
92 | version "3.2.0"
93 | resolved "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-3.2.0.tgz#e86b819c602cf8821ad637413698f1dec021847a"
94 |
95 | ajv@^6.0.1, ajv@^6.5.0:
96 | version "6.5.2"
97 | resolved "https://registry.npmjs.org/ajv/-/ajv-6.5.2.tgz#678495f9b82f7cca6be248dd92f59bff5e1f4360"
98 | dependencies:
99 | fast-deep-equal "^2.0.1"
100 | fast-json-stable-stringify "^2.0.0"
101 | json-schema-traverse "^0.4.1"
102 | uri-js "^4.2.1"
103 |
104 | ansi-escapes@^3.0.0:
105 | version "3.1.0"
106 | resolved "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-3.1.0.tgz#f73207bb81207d75fd6c83f125af26eea378ca30"
107 |
108 | ansi-regex@^2.0.0:
109 | version "2.1.1"
110 | resolved "http://sinopia.app.s/ansi-regex/-/ansi-regex-2.1.1.tgz#c3b33ab5ee360d86e0e628f0468ae7ef27d654df"
111 |
112 | ansi-regex@^3.0.0:
113 | version "3.0.0"
114 | resolved "http://sinopia.app.s/ansi-regex/-/ansi-regex-3.0.0.tgz#ed0317c322064f79466c02966bddb605ab37d998"
115 |
116 | ansi-styles@^2.2.1:
117 | version "2.2.1"
118 | resolved "http://sinopia.app.s/ansi-styles/-/ansi-styles-2.2.1.tgz#b432dd3358b634cf75e1e4664368240533c1ddbe"
119 |
120 | ansi-styles@^3.2.1:
121 | version "3.2.1"
122 | resolved "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz#41fbb20243e50b12be0f04b8dedbf07520ce841d"
123 | dependencies:
124 | color-convert "^1.9.0"
125 |
126 | argparse@^1.0.7:
127 | version "1.0.10"
128 | resolved "https://registry.yarnpkg.com/argparse/-/argparse-1.0.10.tgz#bcd6791ea5ae09725e17e5ad988134cd40b3d911"
129 | dependencies:
130 | sprintf-js "~1.0.2"
131 |
132 | array-union@^1.0.1:
133 | version "1.0.2"
134 | resolved "http://sinopia.app.s/array-union/-/array-union-1.0.2.tgz#9a34410e4f4e3da23dea375be5be70f24778ec39"
135 | dependencies:
136 | array-uniq "^1.0.1"
137 |
138 | array-uniq@^1.0.1:
139 | version "1.0.3"
140 | resolved "http://sinopia.app.s/array-uniq/-/array-uniq-1.0.3.tgz#af6ac877a25cc7f74e058894753858dfdb24fdb6"
141 |
142 | arrify@^1.0.0:
143 | version "1.0.1"
144 | resolved "http://sinopia.app.s/arrify/-/arrify-1.0.1.tgz#898508da2226f380df904728456849c1501a4b0d"
145 |
146 | babel-code-frame@^6.26.0:
147 | version "6.26.0"
148 | resolved "https://registry.npmjs.org/babel-code-frame/-/babel-code-frame-6.26.0.tgz#63fd43f7dc1e3bb7ce35947db8fe369a3f58c74b"
149 | dependencies:
150 | chalk "^1.1.3"
151 | esutils "^2.0.2"
152 | js-tokens "^3.0.2"
153 |
154 | babel-eslint@^8.2.6:
155 | version "8.2.6"
156 | resolved "https://registry.npmjs.org/babel-eslint/-/babel-eslint-8.2.6.tgz#6270d0c73205628067c0f7ae1693a9e797acefd9"
157 | dependencies:
158 | "@babel/code-frame" "7.0.0-beta.44"
159 | "@babel/traverse" "7.0.0-beta.44"
160 | "@babel/types" "7.0.0-beta.44"
161 | babylon "7.0.0-beta.44"
162 | eslint-scope "3.7.1"
163 | eslint-visitor-keys "^1.0.0"
164 |
165 | babylon@7.0.0-beta.44:
166 | version "7.0.0-beta.44"
167 | resolved "https://registry.npmjs.org/babylon/-/babylon-7.0.0-beta.44.tgz#89159e15e6e30c5096e22d738d8c0af8a0e8ca1d"
168 |
169 | balanced-match@^1.0.0:
170 | version "1.0.0"
171 | resolved "http://sinopia.app.s/balanced-match/-/balanced-match-1.0.0.tgz#89b4d199ab2bee49de164ea02b89ce462d71b767"
172 |
173 | brace-expansion@^1.1.7:
174 | version "1.1.11"
175 | resolved "http://sinopia.app.s/brace-expansion/-/brace-expansion-1.1.11.tgz#3c7fcbf529d87226f3d2f52b966ff5271eb441dd"
176 | dependencies:
177 | balanced-match "^1.0.0"
178 | concat-map "0.0.1"
179 |
180 | browser-stdout@1.3.0:
181 | version "1.3.0"
182 | resolved "http://sinopia.app.s/browser-stdout/-/browser-stdout-1.3.0.tgz#f351d32969d32fa5d7a5567154263d928ae3bd1f"
183 |
184 | builtin-modules@^1.0.0:
185 | version "1.1.1"
186 | resolved "https://registry.npmjs.org/builtin-modules/-/builtin-modules-1.1.1.tgz#270f076c5a72c02f5b65a47df94c5fe3a278892f"
187 |
188 | caller-path@^0.1.0:
189 | version "0.1.0"
190 | resolved "http://sinopia.app.s/caller-path/-/caller-path-0.1.0.tgz#94085ef63581ecd3daa92444a8fe94e82577751f"
191 | dependencies:
192 | callsites "^0.2.0"
193 |
194 | callsites@^0.2.0:
195 | version "0.2.0"
196 | resolved "http://sinopia.app.s/callsites/-/callsites-0.2.0.tgz#afab96262910a7f33c19a5775825c69f34e350ca"
197 |
198 | chalk@^1.1.3:
199 | version "1.1.3"
200 | resolved "http://sinopia.app.s/chalk/-/chalk-1.1.3.tgz#a8115c55e4a702fe4d150abd3872822a7e09fc98"
201 | dependencies:
202 | ansi-styles "^2.2.1"
203 | escape-string-regexp "^1.0.2"
204 | has-ansi "^2.0.0"
205 | strip-ansi "^3.0.0"
206 | supports-color "^2.0.0"
207 |
208 | chalk@^2.0.0, chalk@^2.1.0:
209 | version "2.4.1"
210 | resolved "https://registry.npmjs.org/chalk/-/chalk-2.4.1.tgz#18c49ab16a037b6eb0152cc83e3471338215b66e"
211 | dependencies:
212 | ansi-styles "^3.2.1"
213 | escape-string-regexp "^1.0.5"
214 | supports-color "^5.3.0"
215 |
216 | chardet@^0.4.0:
217 | version "0.4.2"
218 | resolved "https://registry.npmjs.org/chardet/-/chardet-0.4.2.tgz#b5473b33dc97c424e5d98dc87d55d4d8a29c8bf2"
219 |
220 | circular-json@^0.3.1:
221 | version "0.3.3"
222 | resolved "http://sinopia.app.s/circular-json/-/circular-json-0.3.3.tgz#815c99ea84f6809529d2f45791bdf82711352d66"
223 |
224 | cli-cursor@^2.1.0:
225 | version "2.1.0"
226 | resolved "https://registry.npmjs.org/cli-cursor/-/cli-cursor-2.1.0.tgz#b35dac376479facc3e94747d41d0d0f5238ffcb5"
227 | dependencies:
228 | restore-cursor "^2.0.0"
229 |
230 | cli-width@^2.0.0:
231 | version "2.2.0"
232 | resolved "http://sinopia.app.s/cli-width/-/cli-width-2.2.0.tgz#ff19ede8a9a5e579324147b0c11f0fbcbabed639"
233 |
234 | color-convert@^1.9.0:
235 | version "1.9.2"
236 | resolved "https://registry.npmjs.org/color-convert/-/color-convert-1.9.2.tgz#49881b8fba67df12a96bdf3f56c0aab9e7913147"
237 | dependencies:
238 | color-name "1.1.1"
239 |
240 | color-name@1.1.1:
241 | version "1.1.1"
242 | resolved "https://registry.npmjs.org/color-name/-/color-name-1.1.1.tgz#4b1415304cf50028ea81643643bd82ea05803689"
243 |
244 | commander@2.9.0:
245 | version "2.9.0"
246 | resolved "http://sinopia.app.s/commander/-/commander-2.9.0.tgz#9c99094176e12240cb22d6c5146098400fe0f7d4"
247 | dependencies:
248 | graceful-readlink ">= 1.0.0"
249 |
250 | concat-map@0.0.1:
251 | version "0.0.1"
252 | resolved "http://sinopia.app.s/concat-map/-/concat-map-0.0.1.tgz#d8a96bd77fd68df7793a73036a3ba0d5405d477b"
253 |
254 | contains-path@^0.1.0:
255 | version "0.1.0"
256 | resolved "https://registry.npmjs.org/contains-path/-/contains-path-0.1.0.tgz#fe8cf184ff6670b6baef01a9d4861a5cbec4120a"
257 |
258 | cross-spawn@^6.0.5:
259 | version "6.0.5"
260 | resolved "https://registry.npmjs.org/cross-spawn/-/cross-spawn-6.0.5.tgz#4a5ec7c64dfae22c3a14124dbacdee846d80cbc4"
261 | dependencies:
262 | nice-try "^1.0.4"
263 | path-key "^2.0.1"
264 | semver "^5.5.0"
265 | shebang-command "^1.2.0"
266 | which "^1.2.9"
267 |
268 | debug@2.6.8:
269 | version "2.6.8"
270 | resolved "http://sinopia.app.s/debug/-/debug-2.6.8.tgz#e731531ca2ede27d188222427da17821d68ff4fc"
271 | dependencies:
272 | ms "2.0.0"
273 |
274 | debug@^2.6.8, debug@^2.6.9:
275 | version "2.6.9"
276 | resolved "http://sinopia.app.s/debug/-/debug-2.6.9.tgz#5d128515df134ff327e90a4c93f4e077a536341f"
277 | dependencies:
278 | ms "2.0.0"
279 |
280 | debug@^3.1.0:
281 | version "3.1.0"
282 | resolved "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz#5bb5a0672628b64149566ba16819e61518c67261"
283 | dependencies:
284 | ms "2.0.0"
285 |
286 | deep-is@~0.1.3:
287 | version "0.1.3"
288 | resolved "http://sinopia.app.s/deep-is/-/deep-is-0.1.3.tgz#b369d6fb5dbc13eecf524f91b070feedc357cf34"
289 |
290 | define-properties@^1.1.2:
291 | version "1.1.2"
292 | resolved "https://registry.npmjs.org/define-properties/-/define-properties-1.1.2.tgz#83a73f2fea569898fb737193c8f873caf6d45c94"
293 | dependencies:
294 | foreach "^2.0.5"
295 | object-keys "^1.0.8"
296 |
297 | del@^2.0.2:
298 | version "2.2.2"
299 | resolved "http://sinopia.app.s/del/-/del-2.2.2.tgz#c12c981d067846c84bcaf862cff930d907ffd1a8"
300 | dependencies:
301 | globby "^5.0.0"
302 | is-path-cwd "^1.0.0"
303 | is-path-in-cwd "^1.0.0"
304 | object-assign "^4.0.1"
305 | pify "^2.0.0"
306 | pinkie-promise "^2.0.0"
307 | rimraf "^2.2.8"
308 |
309 | diff@3.2.0:
310 | version "3.2.0"
311 | resolved "http://sinopia.app.s/diff/-/diff-3.2.0.tgz#c9ce393a4b7cbd0b058a725c93df299027868ff9"
312 |
313 | doctrine@1.5.0:
314 | version "1.5.0"
315 | resolved "http://sinopia.app.s/doctrine/-/doctrine-1.5.0.tgz#379dce730f6166f76cefa4e6707a159b02c5a6fa"
316 | dependencies:
317 | esutils "^2.0.2"
318 | isarray "^1.0.0"
319 |
320 | doctrine@^2.1.0:
321 | version "2.1.0"
322 | resolved "https://registry.npmjs.org/doctrine/-/doctrine-2.1.0.tgz#5cd01fc101621b42c4cd7f5d1a66243716d3f39d"
323 | dependencies:
324 | esutils "^2.0.2"
325 |
326 | error-ex@^1.2.0:
327 | version "1.3.2"
328 | resolved "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz#b4ac40648107fdcdcfae242f428bea8a14d4f1bf"
329 | dependencies:
330 | is-arrayish "^0.2.1"
331 |
332 | es-abstract@^1.10.0, es-abstract@^1.6.1:
333 | version "1.12.0"
334 | resolved "https://registry.npmjs.org/es-abstract/-/es-abstract-1.12.0.tgz#9dbbdd27c6856f0001421ca18782d786bf8a6165"
335 | dependencies:
336 | es-to-primitive "^1.1.1"
337 | function-bind "^1.1.1"
338 | has "^1.0.1"
339 | is-callable "^1.1.3"
340 | is-regex "^1.0.4"
341 |
342 | es-to-primitive@^1.1.1:
343 | version "1.1.1"
344 | resolved "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.1.1.tgz#45355248a88979034b6792e19bb81f2b7975dd0d"
345 | dependencies:
346 | is-callable "^1.1.1"
347 | is-date-object "^1.0.1"
348 | is-symbol "^1.0.1"
349 |
350 | escape-string-regexp@1.0.5, escape-string-regexp@^1.0.2, escape-string-regexp@^1.0.5:
351 | version "1.0.5"
352 | resolved "http://sinopia.app.s/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz#1b61c0562190a8dff6ae3bb2cf0200ca130b86d4"
353 |
354 | eslint-config-airbnb-base@^13.0.0:
355 | version "13.0.0"
356 | resolved "https://registry.npmjs.org/eslint-config-airbnb-base/-/eslint-config-airbnb-base-13.0.0.tgz#2ee6279c4891128e49d6445b24aa13c2d1a21450"
357 | dependencies:
358 | eslint-restricted-globals "^0.1.1"
359 | object.assign "^4.1.0"
360 | object.entries "^1.0.4"
361 |
362 | eslint-config-prettier@^2.9.0:
363 | version "2.9.0"
364 | resolved "https://registry.npmjs.org/eslint-config-prettier/-/eslint-config-prettier-2.9.0.tgz#5ecd65174d486c22dff389fe036febf502d468a3"
365 | dependencies:
366 | get-stdin "^5.0.1"
367 |
368 | eslint-import-resolver-node@^0.3.1:
369 | version "0.3.2"
370 | resolved "https://registry.npmjs.org/eslint-import-resolver-node/-/eslint-import-resolver-node-0.3.2.tgz#58f15fb839b8d0576ca980413476aab2472db66a"
371 | dependencies:
372 | debug "^2.6.9"
373 | resolve "^1.5.0"
374 |
375 | eslint-module-utils@^2.2.0:
376 | version "2.2.0"
377 | resolved "https://registry.npmjs.org/eslint-module-utils/-/eslint-module-utils-2.2.0.tgz#b270362cd88b1a48ad308976ce7fa54e98411746"
378 | dependencies:
379 | debug "^2.6.8"
380 | pkg-dir "^1.0.0"
381 |
382 | eslint-plugin-import@^2.13.0:
383 | version "2.13.0"
384 | resolved "https://registry.npmjs.org/eslint-plugin-import/-/eslint-plugin-import-2.13.0.tgz#df24f241175e312d91662dc91ca84064caec14ed"
385 | dependencies:
386 | contains-path "^0.1.0"
387 | debug "^2.6.8"
388 | doctrine "1.5.0"
389 | eslint-import-resolver-node "^0.3.1"
390 | eslint-module-utils "^2.2.0"
391 | has "^1.0.1"
392 | lodash "^4.17.4"
393 | minimatch "^3.0.3"
394 | read-pkg-up "^2.0.0"
395 | resolve "^1.6.0"
396 |
397 | eslint-plugin-prettier@^2.6.2:
398 | version "2.6.2"
399 | resolved "https://registry.npmjs.org/eslint-plugin-prettier/-/eslint-plugin-prettier-2.6.2.tgz#71998c60aedfa2141f7bfcbf9d1c459bf98b4fad"
400 | dependencies:
401 | fast-diff "^1.1.1"
402 | jest-docblock "^21.0.0"
403 |
404 | eslint-restricted-globals@^0.1.1:
405 | version "0.1.1"
406 | resolved "https://registry.npmjs.org/eslint-restricted-globals/-/eslint-restricted-globals-0.1.1.tgz#35f0d5cbc64c2e3ed62e93b4b1a7af05ba7ed4d7"
407 |
408 | eslint-scope@3.7.1:
409 | version "3.7.1"
410 | resolved "https://registry.npmjs.org/eslint-scope/-/eslint-scope-3.7.1.tgz#3d63c3edfda02e06e01a452ad88caacc7cdcb6e8"
411 | dependencies:
412 | esrecurse "^4.1.0"
413 | estraverse "^4.1.1"
414 |
415 | eslint-scope@^4.0.0:
416 | version "4.0.0"
417 | resolved "https://registry.npmjs.org/eslint-scope/-/eslint-scope-4.0.0.tgz#50bf3071e9338bcdc43331794a0cb533f0136172"
418 | dependencies:
419 | esrecurse "^4.1.0"
420 | estraverse "^4.1.1"
421 |
422 | eslint-utils@^1.3.1:
423 | version "1.4.3"
424 | resolved "https://registry.yarnpkg.com/eslint-utils/-/eslint-utils-1.4.3.tgz#74fec7c54d0776b6f67e0251040b5806564e981f"
425 | dependencies:
426 | eslint-visitor-keys "^1.1.0"
427 |
428 | eslint-visitor-keys@^1.0.0, eslint-visitor-keys@^1.1.0:
429 | version "1.1.0"
430 | resolved "https://registry.yarnpkg.com/eslint-visitor-keys/-/eslint-visitor-keys-1.1.0.tgz#e2a82cea84ff246ad6fb57f9bde5b46621459ec2"
431 |
432 | eslint@^5.3.0:
433 | version "5.3.0"
434 | resolved "https://registry.npmjs.org/eslint/-/eslint-5.3.0.tgz#53695aca5213968aacdf970ccb231e42a2b285f8"
435 | dependencies:
436 | ajv "^6.5.0"
437 | babel-code-frame "^6.26.0"
438 | chalk "^2.1.0"
439 | cross-spawn "^6.0.5"
440 | debug "^3.1.0"
441 | doctrine "^2.1.0"
442 | eslint-scope "^4.0.0"
443 | eslint-utils "^1.3.1"
444 | eslint-visitor-keys "^1.0.0"
445 | espree "^4.0.0"
446 | esquery "^1.0.1"
447 | esutils "^2.0.2"
448 | file-entry-cache "^2.0.0"
449 | functional-red-black-tree "^1.0.1"
450 | glob "^7.1.2"
451 | globals "^11.7.0"
452 | ignore "^4.0.2"
453 | imurmurhash "^0.1.4"
454 | inquirer "^5.2.0"
455 | is-resolvable "^1.1.0"
456 | js-yaml "^3.11.0"
457 | json-stable-stringify-without-jsonify "^1.0.1"
458 | levn "^0.3.0"
459 | lodash "^4.17.5"
460 | minimatch "^3.0.4"
461 | mkdirp "^0.5.1"
462 | natural-compare "^1.4.0"
463 | optionator "^0.8.2"
464 | path-is-inside "^1.0.2"
465 | pluralize "^7.0.0"
466 | progress "^2.0.0"
467 | regexpp "^2.0.0"
468 | require-uncached "^1.0.3"
469 | semver "^5.5.0"
470 | string.prototype.matchall "^2.0.0"
471 | strip-ansi "^4.0.0"
472 | strip-json-comments "^2.0.1"
473 | table "^4.0.3"
474 | text-table "^0.2.0"
475 |
476 | espree@^4.0.0:
477 | version "4.0.0"
478 | resolved "https://registry.npmjs.org/espree/-/espree-4.0.0.tgz#253998f20a0f82db5d866385799d912a83a36634"
479 | dependencies:
480 | acorn "^5.6.0"
481 | acorn-jsx "^4.1.1"
482 |
483 | esprima@^4.0.0:
484 | version "4.0.1"
485 | resolved "https://registry.yarnpkg.com/esprima/-/esprima-4.0.1.tgz#13b04cdb3e6c5d19df91ab6987a8695619b0aa71"
486 |
487 | esquery@^1.0.1:
488 | version "1.0.1"
489 | resolved "https://registry.npmjs.org/esquery/-/esquery-1.0.1.tgz#406c51658b1f5991a5f9b62b1dc25b00e3e5c708"
490 | dependencies:
491 | estraverse "^4.0.0"
492 |
493 | esrecurse@^4.1.0:
494 | version "4.2.1"
495 | resolved "http://sinopia.app.s/esrecurse/-/esrecurse-4.2.1.tgz#007a3b9fdbc2b3bb87e4879ea19c92fdbd3942cf"
496 | dependencies:
497 | estraverse "^4.1.0"
498 |
499 | estraverse@^4.0.0, estraverse@^4.1.0, estraverse@^4.1.1:
500 | version "4.2.0"
501 | resolved "http://sinopia.app.s/estraverse/-/estraverse-4.2.0.tgz#0dee3fed31fcd469618ce7342099fc1afa0bdb13"
502 |
503 | esutils@^2.0.2:
504 | version "2.0.2"
505 | resolved "http://sinopia.app.s/esutils/-/esutils-2.0.2.tgz#0abf4f1caa5bcb1f7a9d8acc6dea4faaa04bac9b"
506 |
507 | external-editor@^2.1.0:
508 | version "2.2.0"
509 | resolved "https://registry.npmjs.org/external-editor/-/external-editor-2.2.0.tgz#045511cfd8d133f3846673d1047c154e214ad3d5"
510 | dependencies:
511 | chardet "^0.4.0"
512 | iconv-lite "^0.4.17"
513 | tmp "^0.0.33"
514 |
515 | fast-deep-equal@^2.0.1:
516 | version "2.0.1"
517 | resolved "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-2.0.1.tgz#7b05218ddf9667bf7f370bf7fdb2cb15fdd0aa49"
518 |
519 | fast-diff@^1.1.1:
520 | version "1.1.2"
521 | resolved "https://registry.npmjs.org/fast-diff/-/fast-diff-1.1.2.tgz#4b62c42b8e03de3f848460b639079920695d0154"
522 |
523 | fast-json-stable-stringify@^2.0.0:
524 | version "2.0.0"
525 | resolved "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.0.0.tgz#d5142c0caee6b1189f87d3a76111064f86c8bbf2"
526 |
527 | fast-levenshtein@~2.0.4:
528 | version "2.0.6"
529 | resolved "http://sinopia.app.s/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz#3d8a5c66883a16a30ca8643e851f19baa7797917"
530 |
531 | figures@^2.0.0:
532 | version "2.0.0"
533 | resolved "https://registry.npmjs.org/figures/-/figures-2.0.0.tgz#3ab1a2d2a62c8bfb431a0c94cb797a2fce27c962"
534 | dependencies:
535 | escape-string-regexp "^1.0.5"
536 |
537 | file-entry-cache@^2.0.0:
538 | version "2.0.0"
539 | resolved "http://sinopia.app.s/file-entry-cache/-/file-entry-cache-2.0.0.tgz#c392990c3e684783d838b8c84a45d8a048458361"
540 | dependencies:
541 | flat-cache "^1.2.1"
542 | object-assign "^4.0.1"
543 |
544 | find-up@^1.0.0:
545 | version "1.1.2"
546 | resolved "https://registry.npmjs.org/find-up/-/find-up-1.1.2.tgz#6b2e9822b1a2ce0a60ab64d610eccad53cb24d0f"
547 | dependencies:
548 | path-exists "^2.0.0"
549 | pinkie-promise "^2.0.0"
550 |
551 | find-up@^2.0.0:
552 | version "2.1.0"
553 | resolved "https://registry.npmjs.org/find-up/-/find-up-2.1.0.tgz#45d1b7e506c717ddd482775a2b77920a3c0c57a7"
554 | dependencies:
555 | locate-path "^2.0.0"
556 |
557 | flat-cache@^1.2.1:
558 | version "1.3.0"
559 | resolved "http://sinopia.app.s/flat-cache/-/flat-cache-1.3.0.tgz#d3030b32b38154f4e3b7e9c709f490f7ef97c481"
560 | dependencies:
561 | circular-json "^0.3.1"
562 | del "^2.0.2"
563 | graceful-fs "^4.1.2"
564 | write "^0.2.1"
565 |
566 | foreach@^2.0.5:
567 | version "2.0.5"
568 | resolved "https://registry.npmjs.org/foreach/-/foreach-2.0.5.tgz#0bee005018aeb260d0a3af3ae658dd0136ec1b99"
569 |
570 | fs.realpath@^1.0.0:
571 | version "1.0.0"
572 | resolved "http://sinopia.app.s/fs.realpath/-/fs.realpath-1.0.0.tgz#1504ad2523158caa40db4a2787cb01411994ea4f"
573 |
574 | function-bind@^1.1.0, function-bind@^1.1.1:
575 | version "1.1.1"
576 | resolved "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz#a56899d3ea3c9bab874bb9773b7c5ede92f4895d"
577 |
578 | functional-red-black-tree@^1.0.1:
579 | version "1.0.1"
580 | resolved "https://registry.npmjs.org/functional-red-black-tree/-/functional-red-black-tree-1.0.1.tgz#1b0ab3bd553b2a0d6399d29c0e3ea0b252078327"
581 |
582 | get-stdin@^5.0.1:
583 | version "5.0.1"
584 | resolved "https://registry.npmjs.org/get-stdin/-/get-stdin-5.0.1.tgz#122e161591e21ff4c52530305693f20e6393a398"
585 |
586 | glob@7.1.1:
587 | version "7.1.1"
588 | resolved "http://sinopia.app.s/glob/-/glob-7.1.1.tgz#805211df04faaf1c63a3600306cdf5ade50b2ec8"
589 | dependencies:
590 | fs.realpath "^1.0.0"
591 | inflight "^1.0.4"
592 | inherits "2"
593 | minimatch "^3.0.2"
594 | once "^1.3.0"
595 | path-is-absolute "^1.0.0"
596 |
597 | glob@^7.0.3, glob@^7.0.5, glob@^7.1.2:
598 | version "7.1.2"
599 | resolved "http://sinopia.app.s/glob/-/glob-7.1.2.tgz#c19c9df9a028702d678612384a6552404c636d15"
600 | dependencies:
601 | fs.realpath "^1.0.0"
602 | inflight "^1.0.4"
603 | inherits "2"
604 | minimatch "^3.0.4"
605 | once "^1.3.0"
606 | path-is-absolute "^1.0.0"
607 |
608 | globals@^11.1.0, globals@^11.7.0:
609 | version "11.7.0"
610 | resolved "https://registry.npmjs.org/globals/-/globals-11.7.0.tgz#a583faa43055b1aca771914bf68258e2fc125673"
611 |
612 | globby@^5.0.0:
613 | version "5.0.0"
614 | resolved "http://sinopia.app.s/globby/-/globby-5.0.0.tgz#ebd84667ca0dbb330b99bcfc68eac2bc54370e0d"
615 | dependencies:
616 | array-union "^1.0.1"
617 | arrify "^1.0.0"
618 | glob "^7.0.3"
619 | object-assign "^4.0.1"
620 | pify "^2.0.0"
621 | pinkie-promise "^2.0.0"
622 |
623 | graceful-fs@^4.1.2:
624 | version "4.1.11"
625 | resolved "http://sinopia.app.s/graceful-fs/-/graceful-fs-4.1.11.tgz#0e8bdfe4d1ddb8854d64e04ea7c00e2a026e5658"
626 |
627 | "graceful-readlink@>= 1.0.0":
628 | version "1.0.1"
629 | resolved "http://sinopia.app.s/graceful-readlink/-/graceful-readlink-1.0.1.tgz#4cafad76bc62f02fa039b2f94e9a3dd3a391a725"
630 |
631 | growl@1.9.2:
632 | version "1.9.2"
633 | resolved "http://sinopia.app.s/growl/-/growl-1.9.2.tgz#0ea7743715db8d8de2c5ede1775e1b45ac85c02f"
634 |
635 | has-ansi@^2.0.0:
636 | version "2.0.0"
637 | resolved "http://sinopia.app.s/has-ansi/-/has-ansi-2.0.0.tgz#34f5049ce1ecdf2b0649af3ef24e45ed35416d91"
638 | dependencies:
639 | ansi-regex "^2.0.0"
640 |
641 | has-flag@^1.0.0:
642 | version "1.0.0"
643 | resolved "http://sinopia.app.s/has-flag/-/has-flag-1.0.0.tgz#9d9e793165ce017a00f00418c43f942a7b1d11fa"
644 |
645 | has-flag@^3.0.0:
646 | version "3.0.0"
647 | resolved "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz#b5d454dc2199ae225699f3467e5a07f3b955bafd"
648 |
649 | has-symbols@^1.0.0:
650 | version "1.0.0"
651 | resolved "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.0.tgz#ba1a8f1af2a0fc39650f5c850367704122063b44"
652 |
653 | has@^1.0.1:
654 | version "1.0.3"
655 | resolved "https://registry.npmjs.org/has/-/has-1.0.3.tgz#722d7cbfc1f6aa8241f16dd814e011e1f41e8796"
656 | dependencies:
657 | function-bind "^1.1.1"
658 |
659 | he@1.1.1:
660 | version "1.1.1"
661 | resolved "http://sinopia.app.s/he/-/he-1.1.1.tgz#93410fd21b009735151f8868c2f271f3427e23fd"
662 |
663 | hosted-git-info@^2.1.4:
664 | version "2.7.1"
665 | resolved "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.7.1.tgz#97f236977bd6e125408930ff6de3eec6281ec047"
666 |
667 | iconv-lite@^0.4.17:
668 | version "0.4.23"
669 | resolved "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.23.tgz#297871f63be507adcfbfca715d0cd0eed84e9a63"
670 | dependencies:
671 | safer-buffer ">= 2.1.2 < 3"
672 |
673 | ignore@^4.0.2:
674 | version "4.0.3"
675 | resolved "https://registry.npmjs.org/ignore/-/ignore-4.0.3.tgz#e2d58c9654d75b542529fa28d80ac95b29e4f467"
676 |
677 | imurmurhash@^0.1.4:
678 | version "0.1.4"
679 | resolved "http://sinopia.app.s/imurmurhash/-/imurmurhash-0.1.4.tgz#9218b9b2b928a238b13dc4fb6b6d576f231453ea"
680 |
681 | inflight@^1.0.4:
682 | version "1.0.6"
683 | resolved "http://sinopia.app.s/inflight/-/inflight-1.0.6.tgz#49bd6331d7d02d0c09bc910a1075ba8165b56df9"
684 | dependencies:
685 | once "^1.3.0"
686 | wrappy "1"
687 |
688 | inherits@2:
689 | version "2.0.3"
690 | resolved "http://sinopia.app.s/inherits/-/inherits-2.0.3.tgz#633c2c83e3da42a502f52466022480f4208261de"
691 |
692 | inquirer@^5.2.0:
693 | version "5.2.0"
694 | resolved "https://registry.npmjs.org/inquirer/-/inquirer-5.2.0.tgz#db350c2b73daca77ff1243962e9f22f099685726"
695 | dependencies:
696 | ansi-escapes "^3.0.0"
697 | chalk "^2.0.0"
698 | cli-cursor "^2.1.0"
699 | cli-width "^2.0.0"
700 | external-editor "^2.1.0"
701 | figures "^2.0.0"
702 | lodash "^4.3.0"
703 | mute-stream "0.0.7"
704 | run-async "^2.2.0"
705 | rxjs "^5.5.2"
706 | string-width "^2.1.0"
707 | strip-ansi "^4.0.0"
708 | through "^2.3.6"
709 |
710 | invariant@^2.2.0:
711 | version "2.2.4"
712 | resolved "https://registry.npmjs.org/invariant/-/invariant-2.2.4.tgz#610f3c92c9359ce1db616e538008d23ff35158e6"
713 | dependencies:
714 | loose-envify "^1.0.0"
715 |
716 | is-arrayish@^0.2.1:
717 | version "0.2.1"
718 | resolved "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz#77c99840527aa8ecb1a8ba697b80645a7a926a9d"
719 |
720 | is-builtin-module@^1.0.0:
721 | version "1.0.0"
722 | resolved "https://registry.npmjs.org/is-builtin-module/-/is-builtin-module-1.0.0.tgz#540572d34f7ac3119f8f76c30cbc1b1e037affbe"
723 | dependencies:
724 | builtin-modules "^1.0.0"
725 |
726 | is-callable@^1.1.1, is-callable@^1.1.3:
727 | version "1.1.4"
728 | resolved "https://registry.npmjs.org/is-callable/-/is-callable-1.1.4.tgz#1e1adf219e1eeb684d691f9d6a05ff0d30a24d75"
729 |
730 | is-date-object@^1.0.1:
731 | version "1.0.1"
732 | resolved "https://registry.npmjs.org/is-date-object/-/is-date-object-1.0.1.tgz#9aa20eb6aeebbff77fbd33e74ca01b33581d3a16"
733 |
734 | is-fullwidth-code-point@^2.0.0:
735 | version "2.0.0"
736 | resolved "http://sinopia.app.s/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz#a3b30a5c4f199183167aaab93beefae3ddfb654f"
737 |
738 | is-path-cwd@^1.0.0:
739 | version "1.0.0"
740 | resolved "http://sinopia.app.s/is-path-cwd/-/is-path-cwd-1.0.0.tgz#d225ec23132e89edd38fda767472e62e65f1106d"
741 |
742 | is-path-in-cwd@^1.0.0:
743 | version "1.0.1"
744 | resolved "http://sinopia.app.s/is-path-in-cwd/-/is-path-in-cwd-1.0.1.tgz#5ac48b345ef675339bd6c7a48a912110b241cf52"
745 | dependencies:
746 | is-path-inside "^1.0.0"
747 |
748 | is-path-inside@^1.0.0:
749 | version "1.0.1"
750 | resolved "http://sinopia.app.s/is-path-inside/-/is-path-inside-1.0.1.tgz#8ef5b7de50437a3fdca6b4e865ef7aa55cb48036"
751 | dependencies:
752 | path-is-inside "^1.0.1"
753 |
754 | is-promise@^2.1.0:
755 | version "2.1.0"
756 | resolved "https://registry.npmjs.org/is-promise/-/is-promise-2.1.0.tgz#79a2a9ece7f096e80f36d2b2f3bc16c1ff4bf3fa"
757 |
758 | is-regex@^1.0.4:
759 | version "1.0.4"
760 | resolved "https://registry.npmjs.org/is-regex/-/is-regex-1.0.4.tgz#5517489b547091b0930e095654ced25ee97e9491"
761 | dependencies:
762 | has "^1.0.1"
763 |
764 | is-resolvable@^1.1.0:
765 | version "1.1.0"
766 | resolved "https://registry.npmjs.org/is-resolvable/-/is-resolvable-1.1.0.tgz#fb18f87ce1feb925169c9a407c19318a3206ed88"
767 |
768 | is-symbol@^1.0.1:
769 | version "1.0.1"
770 | resolved "https://registry.npmjs.org/is-symbol/-/is-symbol-1.0.1.tgz#3cc59f00025194b6ab2e38dbae6689256b660572"
771 |
772 | isarray@^1.0.0:
773 | version "1.0.0"
774 | resolved "http://sinopia.app.s/isarray/-/isarray-1.0.0.tgz#bb935d48582cba168c06834957a54a3e07124f11"
775 |
776 | isexe@^2.0.0:
777 | version "2.0.0"
778 | resolved "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz#e8fbf374dc556ff8947a10dcb0572d633f2cfa10"
779 |
780 | jest-docblock@^21.0.0:
781 | version "21.2.0"
782 | resolved "https://registry.npmjs.org/jest-docblock/-/jest-docblock-21.2.0.tgz#51529c3b30d5fd159da60c27ceedc195faf8d414"
783 |
784 | js-tokens@^3.0.0, js-tokens@^3.0.2:
785 | version "3.0.2"
786 | resolved "http://sinopia.app.s/js-tokens/-/js-tokens-3.0.2.tgz#9866df395102130e38f7f996bceb65443209c25b"
787 |
788 | "js-tokens@^3.0.0 || ^4.0.0":
789 | version "4.0.0"
790 | resolved "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz#19203fb59991df98e3a287050d4647cdeaf32499"
791 |
792 | js-yaml@^3.11.0:
793 | version "3.13.1"
794 | resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-3.13.1.tgz#aff151b30bfdfa8e49e05da22e7415e9dfa37847"
795 | dependencies:
796 | argparse "^1.0.7"
797 | esprima "^4.0.0"
798 |
799 | jsesc@^2.5.1:
800 | version "2.5.1"
801 | resolved "https://registry.npmjs.org/jsesc/-/jsesc-2.5.1.tgz#e421a2a8e20d6b0819df28908f782526b96dd1fe"
802 |
803 | json-schema-traverse@^0.4.1:
804 | version "0.4.1"
805 | resolved "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz#69f6a87d9513ab8bb8fe63bdb0979c448e684660"
806 |
807 | json-stable-stringify-without-jsonify@^1.0.1:
808 | version "1.0.1"
809 | resolved "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz#9db7b59496ad3f3cfef30a75142d2d930ad72651"
810 |
811 | json3@3.3.2:
812 | version "3.3.2"
813 | resolved "http://sinopia.app.s/json3/-/json3-3.3.2.tgz#3c0434743df93e2f5c42aee7b19bcb483575f4e1"
814 |
815 | levn@^0.3.0, levn@~0.3.0:
816 | version "0.3.0"
817 | resolved "http://sinopia.app.s/levn/-/levn-0.3.0.tgz#3b09924edf9f083c0490fdd4c0bc4421e04764ee"
818 | dependencies:
819 | prelude-ls "~1.1.2"
820 | type-check "~0.3.2"
821 |
822 | load-json-file@^2.0.0:
823 | version "2.0.0"
824 | resolved "https://registry.npmjs.org/load-json-file/-/load-json-file-2.0.0.tgz#7947e42149af80d696cbf797bcaabcfe1fe29ca8"
825 | dependencies:
826 | graceful-fs "^4.1.2"
827 | parse-json "^2.2.0"
828 | pify "^2.0.0"
829 | strip-bom "^3.0.0"
830 |
831 | locate-path@^2.0.0:
832 | version "2.0.0"
833 | resolved "https://registry.npmjs.org/locate-path/-/locate-path-2.0.0.tgz#2b568b265eec944c6d9c0de9c3dbbbca0354cd8e"
834 | dependencies:
835 | p-locate "^2.0.0"
836 | path-exists "^3.0.0"
837 |
838 | lodash._baseassign@^3.0.0:
839 | version "3.2.0"
840 | resolved "http://sinopia.app.s/lodash._baseassign/-/lodash._baseassign-3.2.0.tgz#8c38a099500f215ad09e59f1722fd0c52bfe0a4e"
841 | dependencies:
842 | lodash._basecopy "^3.0.0"
843 | lodash.keys "^3.0.0"
844 |
845 | lodash._basecopy@^3.0.0:
846 | version "3.0.1"
847 | resolved "http://sinopia.app.s/lodash._basecopy/-/lodash._basecopy-3.0.1.tgz#8da0e6a876cf344c0ad8a54882111dd3c5c7ca36"
848 |
849 | lodash._basecreate@^3.0.0:
850 | version "3.0.3"
851 | resolved "http://sinopia.app.s/lodash._basecreate/-/lodash._basecreate-3.0.3.tgz#1bc661614daa7fc311b7d03bf16806a0213cf821"
852 |
853 | lodash._getnative@^3.0.0:
854 | version "3.9.1"
855 | resolved "http://sinopia.app.s/lodash._getnative/-/lodash._getnative-3.9.1.tgz#570bc7dede46d61cdcde687d65d3eecbaa3aaff5"
856 |
857 | lodash._isiterateecall@^3.0.0:
858 | version "3.0.9"
859 | resolved "http://sinopia.app.s/lodash._isiterateecall/-/lodash._isiterateecall-3.0.9.tgz#5203ad7ba425fae842460e696db9cf3e6aac057c"
860 |
861 | lodash.create@3.1.1:
862 | version "3.1.1"
863 | resolved "http://sinopia.app.s/lodash.create/-/lodash.create-3.1.1.tgz#d7f2849f0dbda7e04682bb8cd72ab022461debe7"
864 | dependencies:
865 | lodash._baseassign "^3.0.0"
866 | lodash._basecreate "^3.0.0"
867 | lodash._isiterateecall "^3.0.0"
868 |
869 | lodash.isarguments@^3.0.0:
870 | version "3.1.0"
871 | resolved "http://sinopia.app.s/lodash.isarguments/-/lodash.isarguments-3.1.0.tgz#2f573d85c6a24289ff00663b491c1d338ff3458a"
872 |
873 | lodash.isarray@^3.0.0:
874 | version "3.0.4"
875 | resolved "http://sinopia.app.s/lodash.isarray/-/lodash.isarray-3.0.4.tgz#79e4eb88c36a8122af86f844aa9bcd851b5fbb55"
876 |
877 | lodash.keys@^3.0.0:
878 | version "3.1.2"
879 | resolved "http://sinopia.app.s/lodash.keys/-/lodash.keys-3.1.2.tgz#4dbc0472b156be50a0b286855d1bd0b0c656098a"
880 | dependencies:
881 | lodash._getnative "^3.0.0"
882 | lodash.isarguments "^3.0.0"
883 | lodash.isarray "^3.0.0"
884 |
885 | lodash@^4.17.4, lodash@^4.17.5, lodash@^4.2.0, lodash@^4.3.0:
886 | version "4.17.21"
887 | resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.21.tgz#679591c564c3bffaae8454cf0b3df370c3d6911c"
888 |
889 | loose-envify@^1.0.0:
890 | version "1.4.0"
891 | resolved "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz#71ee51fa7be4caec1a63839f7e682d8132d30caf"
892 | dependencies:
893 | js-tokens "^3.0.0 || ^4.0.0"
894 |
895 | mimic-fn@^1.0.0:
896 | version "1.2.0"
897 | resolved "https://registry.npmjs.org/mimic-fn/-/mimic-fn-1.2.0.tgz#820c86a39334640e99516928bd03fca88057d022"
898 |
899 | minimatch@^3.0.2, minimatch@^3.0.3, minimatch@^3.0.4:
900 | version "3.0.4"
901 | resolved "http://sinopia.app.s/minimatch/-/minimatch-3.0.4.tgz#5166e286457f03306064be5497e8dbb0c3d32083"
902 | dependencies:
903 | brace-expansion "^1.1.7"
904 |
905 | minimist@0.0.8:
906 | version "0.0.8"
907 | resolved "http://sinopia.app.s/minimist/-/minimist-0.0.8.tgz#857fcabfc3397d2625b8228262e86aa7a011b05d"
908 |
909 | mkdirp@0.5.1, mkdirp@^0.5.1:
910 | version "0.5.1"
911 | resolved "http://sinopia.app.s/mkdirp/-/mkdirp-0.5.1.tgz#30057438eac6cf7f8c4767f38648d6697d75c903"
912 | dependencies:
913 | minimist "0.0.8"
914 |
915 | mocha@^3.1.2:
916 | version "3.5.3"
917 | resolved "http://sinopia.app.s/mocha/-/mocha-3.5.3.tgz#1e0480fe36d2da5858d1eb6acc38418b26eaa20d"
918 | dependencies:
919 | browser-stdout "1.3.0"
920 | commander "2.9.0"
921 | debug "2.6.8"
922 | diff "3.2.0"
923 | escape-string-regexp "1.0.5"
924 | glob "7.1.1"
925 | growl "1.9.2"
926 | he "1.1.1"
927 | json3 "3.3.2"
928 | lodash.create "3.1.1"
929 | mkdirp "0.5.1"
930 | supports-color "3.1.2"
931 |
932 | ms@2.0.0:
933 | version "2.0.0"
934 | resolved "http://sinopia.app.s/ms/-/ms-2.0.0.tgz#5608aeadfc00be6c2901df5f9861788de0d597c8"
935 |
936 | mute-stream@0.0.7:
937 | version "0.0.7"
938 | resolved "https://registry.npmjs.org/mute-stream/-/mute-stream-0.0.7.tgz#3075ce93bc21b8fab43e1bc4da7e8115ed1e7bab"
939 |
940 | natural-compare@^1.4.0:
941 | version "1.4.0"
942 | resolved "http://sinopia.app.s/natural-compare/-/natural-compare-1.4.0.tgz#4abebfeed7541f2c27acfb29bdbbd15c8d5ba4f7"
943 |
944 | nice-try@^1.0.4:
945 | version "1.0.4"
946 | resolved "https://registry.npmjs.org/nice-try/-/nice-try-1.0.4.tgz#d93962f6c52f2c1558c0fbda6d512819f1efe1c4"
947 |
948 | normalize-package-data@^2.3.2:
949 | version "2.4.0"
950 | resolved "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-2.4.0.tgz#12f95a307d58352075a04907b84ac8be98ac012f"
951 | dependencies:
952 | hosted-git-info "^2.1.4"
953 | is-builtin-module "^1.0.0"
954 | semver "2 || 3 || 4 || 5"
955 | validate-npm-package-license "^3.0.1"
956 |
957 | object-assign@^4.0.1:
958 | version "4.1.1"
959 | resolved "http://sinopia.app.s/object-assign/-/object-assign-4.1.1.tgz#2109adc7965887cfc05cbbd442cac8bfbb360863"
960 |
961 | object-keys@^1.0.11, object-keys@^1.0.8:
962 | version "1.0.12"
963 | resolved "https://registry.npmjs.org/object-keys/-/object-keys-1.0.12.tgz#09c53855377575310cca62f55bb334abff7b3ed2"
964 |
965 | object.assign@^4.1.0:
966 | version "4.1.0"
967 | resolved "https://registry.npmjs.org/object.assign/-/object.assign-4.1.0.tgz#968bf1100d7956bb3ca086f006f846b3bc4008da"
968 | dependencies:
969 | define-properties "^1.1.2"
970 | function-bind "^1.1.1"
971 | has-symbols "^1.0.0"
972 | object-keys "^1.0.11"
973 |
974 | object.entries@^1.0.4:
975 | version "1.0.4"
976 | resolved "https://registry.npmjs.org/object.entries/-/object.entries-1.0.4.tgz#1bf9a4dd2288f5b33f3a993d257661f05d161a5f"
977 | dependencies:
978 | define-properties "^1.1.2"
979 | es-abstract "^1.6.1"
980 | function-bind "^1.1.0"
981 | has "^1.0.1"
982 |
983 | once@^1.3.0:
984 | version "1.4.0"
985 | resolved "http://sinopia.app.s/once/-/once-1.4.0.tgz#583b1aa775961d4b113ac17d9c50baef9dd76bd1"
986 | dependencies:
987 | wrappy "1"
988 |
989 | onetime@^2.0.0:
990 | version "2.0.1"
991 | resolved "https://registry.npmjs.org/onetime/-/onetime-2.0.1.tgz#067428230fd67443b2794b22bba528b6867962d4"
992 | dependencies:
993 | mimic-fn "^1.0.0"
994 |
995 | optionator@^0.8.2:
996 | version "0.8.2"
997 | resolved "http://sinopia.app.s/optionator/-/optionator-0.8.2.tgz#364c5e409d3f4d6301d6c0b4c05bba50180aeb64"
998 | dependencies:
999 | deep-is "~0.1.3"
1000 | fast-levenshtein "~2.0.4"
1001 | levn "~0.3.0"
1002 | prelude-ls "~1.1.2"
1003 | type-check "~0.3.2"
1004 | wordwrap "~1.0.0"
1005 |
1006 | os-tmpdir@~1.0.2:
1007 | version "1.0.2"
1008 | resolved "https://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz#bbe67406c79aa85c5cfec766fe5734555dfa1274"
1009 |
1010 | p-limit@^1.1.0:
1011 | version "1.3.0"
1012 | resolved "https://registry.npmjs.org/p-limit/-/p-limit-1.3.0.tgz#b86bd5f0c25690911c7590fcbfc2010d54b3ccb8"
1013 | dependencies:
1014 | p-try "^1.0.0"
1015 |
1016 | p-locate@^2.0.0:
1017 | version "2.0.0"
1018 | resolved "https://registry.npmjs.org/p-locate/-/p-locate-2.0.0.tgz#20a0103b222a70c8fd39cc2e580680f3dde5ec43"
1019 | dependencies:
1020 | p-limit "^1.1.0"
1021 |
1022 | p-try@^1.0.0:
1023 | version "1.0.0"
1024 | resolved "https://registry.npmjs.org/p-try/-/p-try-1.0.0.tgz#cbc79cdbaf8fd4228e13f621f2b1a237c1b207b3"
1025 |
1026 | parse-json@^2.2.0:
1027 | version "2.2.0"
1028 | resolved "https://registry.npmjs.org/parse-json/-/parse-json-2.2.0.tgz#f480f40434ef80741f8469099f8dea18f55a4dc9"
1029 | dependencies:
1030 | error-ex "^1.2.0"
1031 |
1032 | path-exists@^2.0.0:
1033 | version "2.1.0"
1034 | resolved "https://registry.npmjs.org/path-exists/-/path-exists-2.1.0.tgz#0feb6c64f0fc518d9a754dd5efb62c7022761f4b"
1035 | dependencies:
1036 | pinkie-promise "^2.0.0"
1037 |
1038 | path-exists@^3.0.0:
1039 | version "3.0.0"
1040 | resolved "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz#ce0ebeaa5f78cb18925ea7d810d7b59b010fd515"
1041 |
1042 | path-is-absolute@^1.0.0:
1043 | version "1.0.1"
1044 | resolved "http://sinopia.app.s/path-is-absolute/-/path-is-absolute-1.0.1.tgz#174b9268735534ffbc7ace6bf53a5a9e1b5c5f5f"
1045 |
1046 | path-is-inside@^1.0.1, path-is-inside@^1.0.2:
1047 | version "1.0.2"
1048 | resolved "http://sinopia.app.s/path-is-inside/-/path-is-inside-1.0.2.tgz#365417dede44430d1c11af61027facf074bdfc53"
1049 |
1050 | path-key@^2.0.1:
1051 | version "2.0.1"
1052 | resolved "https://registry.npmjs.org/path-key/-/path-key-2.0.1.tgz#411cadb574c5a140d3a4b1910d40d80cc9f40b40"
1053 |
1054 | path-parse@^1.0.5:
1055 | version "1.0.5"
1056 | resolved "http://sinopia.app.s/path-parse/-/path-parse-1.0.5.tgz#3c1adf871ea9cd6c9431b6ea2bd74a0ff055c4c1"
1057 |
1058 | path-type@^2.0.0:
1059 | version "2.0.0"
1060 | resolved "https://registry.npmjs.org/path-type/-/path-type-2.0.0.tgz#f012ccb8415b7096fc2daa1054c3d72389594c73"
1061 | dependencies:
1062 | pify "^2.0.0"
1063 |
1064 | pify@^2.0.0:
1065 | version "2.3.0"
1066 | resolved "http://sinopia.app.s/pify/-/pify-2.3.0.tgz#ed141a6ac043a849ea588498e7dca8b15330e90c"
1067 |
1068 | pinkie-promise@^2.0.0:
1069 | version "2.0.1"
1070 | resolved "http://sinopia.app.s/pinkie-promise/-/pinkie-promise-2.0.1.tgz#2135d6dfa7a358c069ac9b178776288228450ffa"
1071 | dependencies:
1072 | pinkie "^2.0.0"
1073 |
1074 | pinkie@^2.0.0:
1075 | version "2.0.4"
1076 | resolved "http://sinopia.app.s/pinkie/-/pinkie-2.0.4.tgz#72556b80cfa0d48a974e80e77248e80ed4f7f870"
1077 |
1078 | pkg-dir@^1.0.0:
1079 | version "1.0.0"
1080 | resolved "https://registry.npmjs.org/pkg-dir/-/pkg-dir-1.0.0.tgz#7a4b508a8d5bb2d629d447056ff4e9c9314cf3d4"
1081 | dependencies:
1082 | find-up "^1.0.0"
1083 |
1084 | pluralize@^7.0.0:
1085 | version "7.0.0"
1086 | resolved "https://registry.npmjs.org/pluralize/-/pluralize-7.0.0.tgz#298b89df8b93b0221dbf421ad2b1b1ea23fc6777"
1087 |
1088 | prelude-ls@~1.1.2:
1089 | version "1.1.2"
1090 | resolved "http://sinopia.app.s/prelude-ls/-/prelude-ls-1.1.2.tgz#21932a549f5e52ffd9a827f570e04be62a97da54"
1091 |
1092 | prettier@^1.14.0:
1093 | version "1.14.0"
1094 | resolved "https://registry.npmjs.org/prettier/-/prettier-1.14.0.tgz#847c235522035fd988100f1f43cf20a7d24f9372"
1095 |
1096 | progress@^2.0.0:
1097 | version "2.0.0"
1098 | resolved "https://registry.npmjs.org/progress/-/progress-2.0.0.tgz#8a1be366bf8fc23db2bd23f10c6fe920b4389d1f"
1099 |
1100 | punycode@^2.1.0:
1101 | version "2.1.1"
1102 | resolved "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz#b58b010ac40c22c5657616c8d2c2c02c7bf479ec"
1103 |
1104 | ramda@^0.25.0:
1105 | version "0.25.0"
1106 | resolved "https://registry.npmjs.org/ramda/-/ramda-0.25.0.tgz#8fdf68231cffa90bc2f9460390a0cb74a29b29a9"
1107 |
1108 | read-pkg-up@^2.0.0:
1109 | version "2.0.0"
1110 | resolved "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-2.0.0.tgz#6b72a8048984e0c41e79510fd5e9fa99b3b549be"
1111 | dependencies:
1112 | find-up "^2.0.0"
1113 | read-pkg "^2.0.0"
1114 |
1115 | read-pkg@^2.0.0:
1116 | version "2.0.0"
1117 | resolved "https://registry.npmjs.org/read-pkg/-/read-pkg-2.0.0.tgz#8ef1c0623c6a6db0dc6713c4bfac46332b2368f8"
1118 | dependencies:
1119 | load-json-file "^2.0.0"
1120 | normalize-package-data "^2.3.2"
1121 | path-type "^2.0.0"
1122 |
1123 | regexp.prototype.flags@^1.2.0:
1124 | version "1.2.0"
1125 | resolved "https://registry.npmjs.org/regexp.prototype.flags/-/regexp.prototype.flags-1.2.0.tgz#6b30724e306a27833eeb171b66ac8890ba37e41c"
1126 | dependencies:
1127 | define-properties "^1.1.2"
1128 |
1129 | regexpp@^2.0.0:
1130 | version "2.0.0"
1131 | resolved "https://registry.npmjs.org/regexpp/-/regexpp-2.0.0.tgz#b2a7534a85ca1b033bcf5ce9ff8e56d4e0755365"
1132 |
1133 | require-uncached@^1.0.3:
1134 | version "1.0.3"
1135 | resolved "https://registry.npmjs.org/require-uncached/-/require-uncached-1.0.3.tgz#4e0d56d6c9662fd31e43011c4b95aa49955421d3"
1136 | dependencies:
1137 | caller-path "^0.1.0"
1138 | resolve-from "^1.0.0"
1139 |
1140 | requireindex@~1.1.0:
1141 | version "1.1.0"
1142 | resolved "http://sinopia.app.s/requireindex/-/requireindex-1.1.0.tgz#e5404b81557ef75db6e49c5a72004893fe03e162"
1143 |
1144 | resolve-from@^1.0.0:
1145 | version "1.0.1"
1146 | resolved "http://sinopia.app.s/resolve-from/-/resolve-from-1.0.1.tgz#26cbfe935d1aeeeabb29bc3fe5aeb01e93d44226"
1147 |
1148 | resolve@^1.5.0, resolve@^1.6.0:
1149 | version "1.8.1"
1150 | resolved "http://sinopia.app.s/resolve/-/resolve-1.8.1.tgz#82f1ec19a423ac1fbd080b0bab06ba36e84a7a26"
1151 | dependencies:
1152 | path-parse "^1.0.5"
1153 |
1154 | restore-cursor@^2.0.0:
1155 | version "2.0.0"
1156 | resolved "https://registry.npmjs.org/restore-cursor/-/restore-cursor-2.0.0.tgz#9f7ee287f82fd326d4fd162923d62129eee0dfaf"
1157 | dependencies:
1158 | onetime "^2.0.0"
1159 | signal-exit "^3.0.2"
1160 |
1161 | rimraf@^2.2.8:
1162 | version "2.6.2"
1163 | resolved "http://sinopia.app.s/rimraf/-/rimraf-2.6.2.tgz#2ed8150d24a16ea8651e6d6ef0f47c4158ce7a36"
1164 | dependencies:
1165 | glob "^7.0.5"
1166 |
1167 | run-async@^2.2.0:
1168 | version "2.3.0"
1169 | resolved "https://registry.npmjs.org/run-async/-/run-async-2.3.0.tgz#0371ab4ae0bdd720d4166d7dfda64ff7a445a6c0"
1170 | dependencies:
1171 | is-promise "^2.1.0"
1172 |
1173 | rxjs@^5.5.2:
1174 | version "5.5.11"
1175 | resolved "https://registry.npmjs.org/rxjs/-/rxjs-5.5.11.tgz#f733027ca43e3bec6b994473be4ab98ad43ced87"
1176 | dependencies:
1177 | symbol-observable "1.0.1"
1178 |
1179 | "safer-buffer@>= 2.1.2 < 3":
1180 | version "2.1.2"
1181 | resolved "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz#44fa161b0187b9549dd84bb91802f9bd8385cd6a"
1182 |
1183 | "semver@2 || 3 || 4 || 5", semver@^5.5.0:
1184 | version "5.5.0"
1185 | resolved "https://registry.npmjs.org/semver/-/semver-5.5.0.tgz#dc4bbc7a6ca9d916dee5d43516f0092b58f7b8ab"
1186 |
1187 | shebang-command@^1.2.0:
1188 | version "1.2.0"
1189 | resolved "https://registry.npmjs.org/shebang-command/-/shebang-command-1.2.0.tgz#44aac65b695b03398968c39f363fee5deafdf1ea"
1190 | dependencies:
1191 | shebang-regex "^1.0.0"
1192 |
1193 | shebang-regex@^1.0.0:
1194 | version "1.0.0"
1195 | resolved "https://registry.npmjs.org/shebang-regex/-/shebang-regex-1.0.0.tgz#da42f49740c0b42db2ca9728571cb190c98efea3"
1196 |
1197 | signal-exit@^3.0.2:
1198 | version "3.0.2"
1199 | resolved "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.2.tgz#b5fdc08f1287ea1178628e415e25132b73646c6d"
1200 |
1201 | slice-ansi@1.0.0:
1202 | version "1.0.0"
1203 | resolved "https://registry.npmjs.org/slice-ansi/-/slice-ansi-1.0.0.tgz#044f1a49d8842ff307aad6b505ed178bd950134d"
1204 | dependencies:
1205 | is-fullwidth-code-point "^2.0.0"
1206 |
1207 | source-map@^0.5.0:
1208 | version "0.5.7"
1209 | resolved "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz#8a039d2d1021d22d1ea14c80d8ea468ba2ef3fcc"
1210 |
1211 | spdx-correct@^3.0.0:
1212 | version "3.0.0"
1213 | resolved "https://registry.npmjs.org/spdx-correct/-/spdx-correct-3.0.0.tgz#05a5b4d7153a195bc92c3c425b69f3b2a9524c82"
1214 | dependencies:
1215 | spdx-expression-parse "^3.0.0"
1216 | spdx-license-ids "^3.0.0"
1217 |
1218 | spdx-exceptions@^2.1.0:
1219 | version "2.1.0"
1220 | resolved "https://registry.npmjs.org/spdx-exceptions/-/spdx-exceptions-2.1.0.tgz#2c7ae61056c714a5b9b9b2b2af7d311ef5c78fe9"
1221 |
1222 | spdx-expression-parse@^3.0.0:
1223 | version "3.0.0"
1224 | resolved "https://registry.npmjs.org/spdx-expression-parse/-/spdx-expression-parse-3.0.0.tgz#99e119b7a5da00e05491c9fa338b7904823b41d0"
1225 | dependencies:
1226 | spdx-exceptions "^2.1.0"
1227 | spdx-license-ids "^3.0.0"
1228 |
1229 | spdx-license-ids@^3.0.0:
1230 | version "3.0.0"
1231 | resolved "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.0.tgz#7a7cd28470cc6d3a1cfe6d66886f6bc430d3ac87"
1232 |
1233 | sprintf-js@~1.0.2:
1234 | version "1.0.3"
1235 | resolved "https://registry.yarnpkg.com/sprintf-js/-/sprintf-js-1.0.3.tgz#04e6926f662895354f3dd015203633b857297e2c"
1236 |
1237 | string-width@^2.1.0, string-width@^2.1.1:
1238 | version "2.1.1"
1239 | resolved "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz#ab93f27a8dc13d28cac815c462143a6d9012ae9e"
1240 | dependencies:
1241 | is-fullwidth-code-point "^2.0.0"
1242 | strip-ansi "^4.0.0"
1243 |
1244 | string.prototype.matchall@^2.0.0:
1245 | version "2.0.0"
1246 | resolved "https://registry.npmjs.org/string.prototype.matchall/-/string.prototype.matchall-2.0.0.tgz#2af8fe3d2d6dc53ca2a59bd376b089c3c152b3c8"
1247 | dependencies:
1248 | define-properties "^1.1.2"
1249 | es-abstract "^1.10.0"
1250 | function-bind "^1.1.1"
1251 | has-symbols "^1.0.0"
1252 | regexp.prototype.flags "^1.2.0"
1253 |
1254 | strip-ansi@^3.0.0:
1255 | version "3.0.1"
1256 | resolved "http://sinopia.app.s/strip-ansi/-/strip-ansi-3.0.1.tgz#6a385fb8853d952d5ff05d0e8aaf94278dc63dcf"
1257 | dependencies:
1258 | ansi-regex "^2.0.0"
1259 |
1260 | strip-ansi@^4.0.0:
1261 | version "4.0.0"
1262 | resolved "http://sinopia.app.s/strip-ansi/-/strip-ansi-4.0.0.tgz#a8479022eb1ac368a871389b635262c505ee368f"
1263 | dependencies:
1264 | ansi-regex "^3.0.0"
1265 |
1266 | strip-bom@^3.0.0:
1267 | version "3.0.0"
1268 | resolved "http://sinopia.app.s/strip-bom/-/strip-bom-3.0.0.tgz#2334c18e9c759f7bdd56fdef7e9ae3d588e68ed3"
1269 |
1270 | strip-json-comments@^2.0.1:
1271 | version "2.0.1"
1272 | resolved "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz#3c531942e908c2697c0ec344858c286c7ca0a60a"
1273 |
1274 | supports-color@3.1.2:
1275 | version "3.1.2"
1276 | resolved "http://sinopia.app.s/supports-color/-/supports-color-3.1.2.tgz#72a262894d9d408b956ca05ff37b2ed8a6e2a2d5"
1277 | dependencies:
1278 | has-flag "^1.0.0"
1279 |
1280 | supports-color@^2.0.0:
1281 | version "2.0.0"
1282 | resolved "http://sinopia.app.s/supports-color/-/supports-color-2.0.0.tgz#535d045ce6b6363fa40117084629995e9df324c7"
1283 |
1284 | supports-color@^5.3.0:
1285 | version "5.4.0"
1286 | resolved "https://registry.npmjs.org/supports-color/-/supports-color-5.4.0.tgz#1c6b337402c2137605efe19f10fec390f6faab54"
1287 | dependencies:
1288 | has-flag "^3.0.0"
1289 |
1290 | symbol-observable@1.0.1:
1291 | version "1.0.1"
1292 | resolved "https://registry.npmjs.org/symbol-observable/-/symbol-observable-1.0.1.tgz#8340fc4702c3122df5d22288f88283f513d3fdd4"
1293 |
1294 | table@^4.0.3:
1295 | version "4.0.3"
1296 | resolved "https://registry.npmjs.org/table/-/table-4.0.3.tgz#00b5e2b602f1794b9acaf9ca908a76386a7813bc"
1297 | dependencies:
1298 | ajv "^6.0.1"
1299 | ajv-keywords "^3.0.0"
1300 | chalk "^2.1.0"
1301 | lodash "^4.17.4"
1302 | slice-ansi "1.0.0"
1303 | string-width "^2.1.1"
1304 |
1305 | text-table@^0.2.0:
1306 | version "0.2.0"
1307 | resolved "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz#7f5ee823ae805207c00af2df4a84ec3fcfa570b4"
1308 |
1309 | through@^2.3.6:
1310 | version "2.3.8"
1311 | resolved "http://sinopia.app.s/through/-/through-2.3.8.tgz#0dd4c9ffaabc357960b1b724115d7e0e86a2e1f5"
1312 |
1313 | tmp@^0.0.33:
1314 | version "0.0.33"
1315 | resolved "https://registry.npmjs.org/tmp/-/tmp-0.0.33.tgz#6d34335889768d21b2bcda0aa277ced3b1bfadf9"
1316 | dependencies:
1317 | os-tmpdir "~1.0.2"
1318 |
1319 | to-fast-properties@^2.0.0:
1320 | version "2.0.0"
1321 | resolved "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-2.0.0.tgz#dc5e698cbd079265bc73e0377681a4e4e83f616e"
1322 |
1323 | trim-right@^1.0.1:
1324 | version "1.0.1"
1325 | resolved "https://registry.npmjs.org/trim-right/-/trim-right-1.0.1.tgz#cb2e1203067e0c8de1f614094b9fe45704ea6003"
1326 |
1327 | type-check@~0.3.2:
1328 | version "0.3.2"
1329 | resolved "http://sinopia.app.s/type-check/-/type-check-0.3.2.tgz#5884cab512cf1d355e3fb784f30804b2b520db72"
1330 | dependencies:
1331 | prelude-ls "~1.1.2"
1332 |
1333 | uri-js@^4.2.1:
1334 | version "4.2.2"
1335 | resolved "https://registry.npmjs.org/uri-js/-/uri-js-4.2.2.tgz#94c540e1ff772956e2299507c010aea6c8838eb0"
1336 | dependencies:
1337 | punycode "^2.1.0"
1338 |
1339 | validate-npm-package-license@^3.0.1:
1340 | version "3.0.3"
1341 | resolved "https://registry.npmjs.org/validate-npm-package-license/-/validate-npm-package-license-3.0.3.tgz#81643bcbef1bdfecd4623793dc4648948ba98338"
1342 | dependencies:
1343 | spdx-correct "^3.0.0"
1344 | spdx-expression-parse "^3.0.0"
1345 |
1346 | which@^1.2.9:
1347 | version "1.3.1"
1348 | resolved "https://registry.npmjs.org/which/-/which-1.3.1.tgz#a45043d54f5805316da8d62f9f50918d3da70b0a"
1349 | dependencies:
1350 | isexe "^2.0.0"
1351 |
1352 | wordwrap@~1.0.0:
1353 | version "1.0.0"
1354 | resolved "http://sinopia.app.s/wordwrap/-/wordwrap-1.0.0.tgz#27584810891456a4171c8d0226441ade90cbcaeb"
1355 |
1356 | wrappy@1:
1357 | version "1.0.2"
1358 | resolved "http://sinopia.app.s/wrappy/-/wrappy-1.0.2.tgz#b5243d8f3ec1aa35f1364605bc0d1036e30ab69f"
1359 |
1360 | write@^0.2.1:
1361 | version "0.2.1"
1362 | resolved "http://sinopia.app.s/write/-/write-0.2.1.tgz#5fc03828e264cea3fe91455476f7a3c566cb0757"
1363 | dependencies:
1364 | mkdirp "^0.5.1"
1365 |
--------------------------------------------------------------------------------