Skip to content

Commit

Permalink
refactor(gatsby): restrict actions available in Node APIs (gatsbyjs#1…
Browse files Browse the repository at this point in the history
  • Loading branch information
stefanprobst authored and pieh committed Jun 6, 2019
1 parent 353e854 commit 19466a2
Show file tree
Hide file tree
Showing 12 changed files with 666 additions and 434 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -300,6 +300,7 @@ exports.onCreateNode = async ({ node, actions, ...helpers }) => {
`since`,
`lends`,
`examples`,
`tags`,
])

picked.optional = false
Expand Down
41 changes: 41 additions & 0 deletions packages/gatsby/src/redux/actions/__tests__/restricted.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
const { availableActionsByAPI } = require(`../restricted`)

const report = require(`gatsby-cli/lib/reporter`)
report.warn = jest.fn()
report.error = jest.fn()
afterEach(() => {
report.warn.mockClear()
report.error.mockClear()
})

const dispatchWithThunk = actionOrThunk =>
typeof actionOrThunk === `function` ? actionOrThunk() : actionOrThunk

describe(`Restricted actions`, () => {
it(`handles actions allowed in API`, () => {
const action = dispatchWithThunk(
availableActionsByAPI.sourceNodes.createTypes()
)
expect(action).toEqual({ type: `CREATE_TYPES` })
expect(report.warn).not.toHaveBeenCalled()
expect(report.error).not.toHaveBeenCalled()
})

it(`handles actions deprecated in API`, () => {
const action = dispatchWithThunk(
availableActionsByAPI.onPreBootstrap.createTypes()
)
expect(action).toEqual({ type: `CREATE_TYPES` })
expect(report.warn).toHaveBeenCalled()
expect(report.error).not.toHaveBeenCalled()
})

it(`handles actions forbidden in API`, () => {
const action = dispatchWithThunk(
availableActionsByAPI.onPostBootstrap.createTypes()
)
expect(action).toBeUndefined()
expect(report.warn).not.toHaveBeenCalled()
expect(report.error).toHaveBeenCalled()
})
})
2 changes: 1 addition & 1 deletion packages/gatsby/src/redux/actions/add-page-dependency.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
const _ = require(`lodash`)

const { store } = require(`../`)
const { actions } = require(`../actions.js`)
const { actions } = require(`./internal.js`)

function createPageDependency({ path, nodeId, connection }) {
const state = store.getState()
Expand Down
25 changes: 25 additions & 0 deletions packages/gatsby/src/redux/actions/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
const { bindActionCreators } = require(`redux`)
const { store } = require(`..`)

const { actions: internalActions } = require(`./internal`)
const { actions: publicActions } = require(`./public`)
const {
actions: restrictedActions,
availableActionsByAPI,
} = require(`./restricted`)

exports.internalActions = internalActions
exports.publicActions = publicActions
exports.restrictedActions = restrictedActions
exports.restrictedActionsAvailableInAPI = availableActionsByAPI

const actions = {
...internalActions,
...publicActions,
...restrictedActions,
}

exports.actions = actions

// Deprecated, remove in v3
exports.boundActionCreators = bindActionCreators(actions, store.dispatch)
210 changes: 210 additions & 0 deletions packages/gatsby/src/redux/actions/internal.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,210 @@
// @flow
import type { Plugin } from "./types"

const actions = {}

/**
* Create a dependency between a page and data. Probably for
* internal use only.
* @param {Object} $0
* @param {string} $0.path the path to the page
* @param {string} $0.nodeId A node ID
* @param {string} $0.connection A connection type
* @private
*/
actions.createPageDependency = (
{
path,
nodeId,
connection,
}: { path: string, nodeId: string, connection: string },
plugin: string = ``
) => {
return {
type: `CREATE_COMPONENT_DEPENDENCY`,
plugin,
payload: {
path,
nodeId,
connection,
},
}
}

/**
* Delete dependencies between an array of pages and data. Probably for
* internal use only. Used when deleting pages.
* @param {Array} paths the paths to delete.
* @private
*/
actions.deleteComponentsDependencies = (paths: string[]) => {
return {
type: `DELETE_COMPONENTS_DEPENDENCIES`,
payload: {
paths,
},
}
}

/**
* When the query watcher extracts a GraphQL query, it calls
* this to store the query with its component.
* @private
*/
actions.replaceComponentQuery = ({
query,
componentPath,
}: {
query: string,
componentPath: string,
}) => {
return {
type: `REPLACE_COMPONENT_QUERY`,
payload: {
query,
componentPath,
},
}
}

/**
* When the query watcher extracts a "static" GraphQL query from <StaticQuery>
* components, it calls this to store the query with its component.
* @private
*/
actions.replaceStaticQuery = (args: any, plugin?: ?Plugin = null) => {
return {
type: `REPLACE_STATIC_QUERY`,
plugin,
payload: args,
}
}

/**
*
* Report that a query has been extracted from a component. Used by
* query-compilier.js.
*
* @param {Object} $0
* @param {componentPath} $0.componentPath The path to the component that just had
* its query read.
* @param {query} $0.query The GraphQL query that was extracted from the component.
* @private
*/
actions.queryExtracted = (
{ componentPath, query },
plugin: Plugin,
traceId?: string
) => {
return {
type: `QUERY_EXTRACTED`,
plugin,
traceId,
payload: { componentPath, query },
}
}

/**
*
* Report that the Relay Compilier found a graphql error when attempting to extract a query
*
* @param {Object} $0
* @param {componentPath} $0.componentPath The path to the component that just had
* its query read.
* @param {error} $0.error The GraphQL query that was extracted from the component.
* @private
*/
actions.queryExtractionGraphQLError = (
{ componentPath, error },
plugin: Plugin,
traceId?: string
) => {
return {
type: `QUERY_EXTRACTION_GRAPHQL_ERROR`,
plugin,
traceId,
payload: { componentPath, error },
}
}

/**
*
* Report that babel was able to extract the graphql query.
* Indicates that the file is free of JS errors.
*
* @param {Object} $0
* @param {componentPath} $0.componentPath The path to the component that just had
* its query read.
* @private
*/
actions.queryExtractedBabelSuccess = (
{ componentPath },
plugin: Plugin,
traceId?: string
) => {
return {
type: `QUERY_EXTRACTION_BABEL_SUCCESS`,
plugin,
traceId,
payload: { componentPath },
}
}

/**
*
* Report that the Relay Compilier found a babel error when attempting to extract a query
*
* @param {Object} $0
* @param {componentPath} $0.componentPath The path to the component that just had
* its query read.
* @param {error} $0.error The Babel error object
* @private
*/
actions.queryExtractionBabelError = (
{ componentPath, error },
plugin: Plugin,
traceId?: string
) => {
return {
type: `QUERY_EXTRACTION_BABEL_ERROR`,
plugin,
traceId,
payload: { componentPath, error },
}
}

/**
* Set overall program status e.g. `BOOTSTRAPING` or `BOOTSTRAP_FINISHED`.
*
* @param {string} Program status
* @private
*/
actions.setProgramStatus = (status, plugin: Plugin, traceId?: string) => {
return {
type: `SET_PROGRAM_STATUS`,
plugin,
traceId,
payload: status,
}
}

/**
* Broadcast that a page's query was run.
*
* @param {string} Path to the page component that changed.
* @private
*/
actions.pageQueryRun = (
{ path, componentPath, isPage },
plugin: Plugin,
traceId?: string
) => {
return {
type: `PAGE_QUERY_RUN`,
plugin,
traceId,
payload: { path, componentPath, isPage },
}
}

module.exports = { actions }
Loading

0 comments on commit 19466a2

Please sign in to comment.