diff --git a/templates/ReactReduxSpa/ClientApp/boot.tsx b/templates/ReactReduxSpa/ClientApp/boot.tsx index 919c22e..7f2dd98 100644 --- a/templates/ReactReduxSpa/ClientApp/boot.tsx +++ b/templates/ReactReduxSpa/ClientApp/boot.tsx @@ -1,15 +1,24 @@ -import 'bootstrap'; -import 'bootstrap/dist/css/bootstrap.css'; import './css/site.css'; - +import 'bootstrap/dist/css/bootstrap.css'; import * as React from 'react'; import * as ReactDOM from 'react-dom'; import { browserHistory, Router } from 'react-router'; +import { Provider } from 'react-redux'; +import { syncHistoryWithStore } from 'react-router-redux'; import routes from './routes'; +import configureStore from './configureStore'; +import { ApplicationState } from './store'; + +// Get the application-wide store instance, prepopulating with state from the server where available. +const initialState = (window as any).initialReduxState as ApplicationState; +const store = configureStore(initialState); +const history = syncHistoryWithStore(browserHistory, store); // This code starts up the React app when it runs in a browser. It sets up the routing configuration // and injects the app into a DOM element. ReactDOM.render( - , + + + , document.getElementById('react-app') ); diff --git a/templates/ReactReduxSpa/ClientApp/components/Counter.tsx b/templates/ReactReduxSpa/ClientApp/components/Counter.tsx index 233bed0..6b8f05c 100644 --- a/templates/ReactReduxSpa/ClientApp/components/Counter.tsx +++ b/templates/ReactReduxSpa/ClientApp/components/Counter.tsx @@ -1,30 +1,27 @@ import * as React from 'react'; +import { Link } from 'react-router'; +import { provide } from 'redux-typed'; +import { ApplicationState } from '../store'; +import * as CounterStore from '../store/Counter'; -interface CounterState { - currentCount: number; -} - -export class Counter extends React.Component { - constructor() { - super(); - this.state = { currentCount: 0 }; - } - +class Counter extends React.Component { public render() { return

Counter

This is a simple example of a React component.

-

Current count: { this.state.currentCount }

+

Current count: { this.props.count }

- +
; } - - incrementCounter() { - this.setState({ - currentCount: this.state.currentCount + 1 - }); - } } + +// Build the CounterProps type, which allows the component to be strongly typed +const provider = provide( + (state: ApplicationState) => state.counter, // Select which part of global state maps to this component + CounterStore.actionCreators // Select which action creators should be exposed to this component +); +type CounterProps = typeof provider.allProps; +export default provider.connect(Counter); diff --git a/templates/ReactReduxSpa/ClientApp/components/FetchData.tsx b/templates/ReactReduxSpa/ClientApp/components/FetchData.tsx index a010bac..d204029 100644 --- a/templates/ReactReduxSpa/ClientApp/components/FetchData.tsx +++ b/templates/ReactReduxSpa/ClientApp/components/FetchData.tsx @@ -1,36 +1,36 @@ import * as React from 'react'; +import { Link } from 'react-router'; +import { provide } from 'redux-typed'; +import { ApplicationState } from '../store'; +import * as WeatherForecastsState from '../store/WeatherForecasts'; -interface FetchDataExampleState { - forecasts: WeatherForecast[]; - loading: boolean; +interface RouteParams { + startDateIndex: string; } -export class FetchData extends React.Component { - constructor() { - super(); - this.state = { forecasts: [], loading: true }; - - fetch('/api/SampleData/WeatherForecasts') - .then(response => response.json()) - .then((data: WeatherForecast[]) => { - this.setState({ forecasts: data, loading: false }); - }); +class FetchData extends React.Component { + componentWillMount() { + // This method runs when the component is first added to the page + let startDateIndex = parseInt(this.props.params.startDateIndex) || 0; + this.props.requestWeatherForecasts(startDateIndex); + } + + componentWillReceiveProps(nextProps: WeatherForecastProps) { + // This method runs when incoming props (e.g., route params) change + let startDateIndex = parseInt(nextProps.params.startDateIndex) || 0; + this.props.requestWeatherForecasts(startDateIndex); } public render() { - let contents = this.state.loading - ?

Loading...

- : FetchData.renderForecastsTable(this.state.forecasts); - return

Weather forecast

-

This component demonstrates fetching data from the server.

- { contents } -

For more sophisticated applications, consider an architecture such as Redux or Flux for managing state. You can generate an ASP.NET Core application with React and Redux using dotnet new aspnet/spa/reactredux instead of using this template.

+

This component demonstrates fetching data from the server and working with URL parameters.

+ { this.renderForecastsTable() } + { this.renderPagination() }
; } - private static renderForecastsTable(forecasts: WeatherForecast[]) { + private renderForecastsTable() { return @@ -41,7 +41,7 @@ export class FetchData extends React.Component { - {forecasts.map(forecast => + {this.props.forecasts.map(forecast => @@ -52,11 +52,23 @@ export class FetchData extends React.Component {
{ forecast.dateFormatted } { forecast.temperatureC }
; } + + private renderPagination() { + let prevStartDateIndex = this.props.startDateIndex - 5; + let nextStartDateIndex = this.props.startDateIndex + 5; + + return

+ Previous + Next + { this.props.isLoading ? Loading... : [] } +

; + } } -interface WeatherForecast { - dateFormatted: string; - temperatureC: number; - temperatureF: number; - summary: string; -} +// Build the WeatherForecastProps type, which allows the component to be strongly typed +const provider = provide( + (state: ApplicationState) => state.weatherForecasts, // Select which part of global state maps to this component + WeatherForecastsState.actionCreators // Select which action creators should be exposed to this component +).withExternalProps<{ params: RouteParams }>(); // Also include a 'params' property on WeatherForecastProps +type WeatherForecastProps = typeof provider.allProps; +export default provider.connect(FetchData); diff --git a/templates/ReactReduxSpa/ClientApp/components/Home.tsx b/templates/ReactReduxSpa/ClientApp/components/Home.tsx index d60da06..084a6de 100644 --- a/templates/ReactReduxSpa/ClientApp/components/Home.tsx +++ b/templates/ReactReduxSpa/ClientApp/components/Home.tsx @@ -1,13 +1,13 @@ import * as React from 'react'; -export class Home extends React.Component { +export default class Home extends React.Component { public render() { return

Hello, world!

Welcome to your new single-page application, built with:

@@ -18,11 +18,6 @@ export class Home extends React.Component {
  • Hot module replacement. In development mode, you don't even need to reload the page after making most changes. Within seconds of saving changes to files, rebuilt CSS and React components will be injected directly into your running application, preserving its live state.
  • Efficient production builds. In production mode, development-time features are disabled, and the webpack build tool produces minified static CSS and JavaScript files.
  • -

    Going further

    -

    - For larger applications, or for server-side prerendering (i.e., for isomorphic or universal applications), you should consider using a Flux/Redux-like architecture. - You can generate an ASP.NET Core application with React and Redux using dotnet new aspnet/spa/reactredux instead of using this template. -

    ; } } diff --git a/templates/ReactReduxSpa/ClientApp/configureStore.ts b/templates/ReactReduxSpa/ClientApp/configureStore.ts new file mode 100644 index 0000000..e4e7bf3 --- /dev/null +++ b/templates/ReactReduxSpa/ClientApp/configureStore.ts @@ -0,0 +1,33 @@ +import { createStore, applyMiddleware, compose, combineReducers } from 'redux'; +import * as thunkModule from 'redux-thunk'; +import { routerReducer } from 'react-router-redux'; +import * as Store from './store'; +import { typedToPlain } from 'redux-typed'; + +export default function configureStore(initialState?: Store.ApplicationState) { + // Build middleware. These are functions that can process the actions before they reach the store. + const thunk = (thunkModule as any).default; // Workaround for TypeScript not importing thunk module as expected + const devToolsExtension = (window as any).devToolsExtension; // If devTools is installed, connect to it + const createStoreWithMiddleware = compose( + applyMiddleware(thunk, typedToPlain), + devToolsExtension ? devToolsExtension() : f => f + )(createStore); + + // Combine all reducers and instantiate the app-wide store instance + const allReducers = buildRootReducer(Store.reducers); + const store = createStoreWithMiddleware(allReducers, initialState) as Redux.Store; + + // Enable Webpack hot module replacement for reducers + if (module.hot) { + module.hot.accept('./store', () => { + const nextRootReducer = require('./store'); + store.replaceReducer(buildRootReducer(nextRootReducer.reducers)); + }); + } + + return store; +} + +function buildRootReducer(allReducers) { + return combineReducers(Object.assign({}, allReducers, { routing: routerReducer })) as Redux.Reducer; +} diff --git a/templates/ReactReduxSpa/ClientApp/routes.tsx b/templates/ReactReduxSpa/ClientApp/routes.tsx index 6084614..da2f915 100644 --- a/templates/ReactReduxSpa/ClientApp/routes.tsx +++ b/templates/ReactReduxSpa/ClientApp/routes.tsx @@ -1,12 +1,14 @@ import * as React from 'react'; import { Router, Route, HistoryBase } from 'react-router'; import { Layout } from './components/Layout'; -import { Home } from './components/Home'; -import { FetchData } from './components/FetchData'; -import { Counter } from './components/Counter'; +import Home from './components/Home'; +import FetchData from './components/FetchData'; +import Counter from './components/Counter'; export default - + + { /* Optional route segment that does not affect NavMenu highlighting */ } + ; diff --git a/templates/ReactReduxSpa/ClientApp/store/Counter.ts b/templates/ReactReduxSpa/ClientApp/store/Counter.ts new file mode 100644 index 0000000..cf852ab --- /dev/null +++ b/templates/ReactReduxSpa/ClientApp/store/Counter.ts @@ -0,0 +1,40 @@ +import { typeName, isActionType, Action, Reducer } from 'redux-typed'; +import { ActionCreator } from './'; + +// ----------------- +// STATE - This defines the type of data maintained in the Redux store. + +export interface CounterState { + count: number; +} + +// ----------------- +// ACTIONS - These are serializable (hence replayable) descriptions of state transitions. +// They do not themselves have any side-effects; they just describe something that is going to happen. +// Use @typeName and isActionType for type detection that works even after serialization/deserialization. + +@typeName("INCREMENT_COUNT") +class IncrementCount extends Action { +} + +// ---------------- +// ACTION CREATORS - These are functions exposed to UI components that will trigger a state transition. +// They don't directly mutate state, but they can have external side-effects (such as loading data). + +export const actionCreators = { + increment: (): ActionCreator => (dispatch, getState) => { + dispatch(new IncrementCount()); + } +}; + +// ---------------- +// REDUCER - For a given state and action, returns the new state. To support time travel, this must not mutate the old state. +export const reducer: Reducer = (state, action) => { + if (isActionType(action, IncrementCount)) { + return { count: state.count + 1 }; + } + + // For unrecognized actions (or in cases where actions have no effect), must return the existing state + // (or default initial state if none was supplied) + return state || { count: 0 }; +}; diff --git a/templates/ReactReduxSpa/ClientApp/store/WeatherForecasts.ts b/templates/ReactReduxSpa/ClientApp/store/WeatherForecasts.ts new file mode 100644 index 0000000..b3e6b32 --- /dev/null +++ b/templates/ReactReduxSpa/ClientApp/store/WeatherForecasts.ts @@ -0,0 +1,76 @@ +import { fetch } from 'domain-task/fetch'; +import { typeName, isActionType, Action, Reducer } from 'redux-typed'; +import { ActionCreator } from './'; + +// ----------------- +// STATE - This defines the type of data maintained in the Redux store. + +export interface WeatherForecastsState { + isLoading: boolean; + startDateIndex: number; + forecasts: WeatherForecast[]; +} + +export interface WeatherForecast { + dateFormatted: string; + temperatureC: number; + temperatureF: number; + summary: string; +} + +// ----------------- +// ACTIONS - These are serializable (hence replayable) descriptions of state transitions. +// They do not themselves have any side-effects; they just describe something that is going to happen. +// Use @typeName and isActionType for type detection that works even after serialization/deserialization. + +@typeName("REQUEST_WEATHER_FORECASTS") +class RequestWeatherForecasts extends Action { + constructor(public startDateIndex: number) { + super(); + } +} + +@typeName("RECEIVE_WEATHER_FORECASTS") +class ReceiveWeatherForecasts extends Action { + constructor(public startDateIndex: number, public forecasts: WeatherForecast[]) { + super(); + } +} + +// ---------------- +// ACTION CREATORS - These are functions exposed to UI components that will trigger a state transition. +// They don't directly mutate state, but they can have external side-effects (such as loading data). + +export const actionCreators = { + requestWeatherForecasts: (startDateIndex: number): ActionCreator => (dispatch, getState) => { + // Only load data if it's something we don't already have (and are not already loading) + if (startDateIndex !== getState().weatherForecasts.startDateIndex) { + fetch(`/api/SampleData/WeatherForecasts?startDateIndex=${ startDateIndex }`) + .then(response => response.json()) + .then((data: WeatherForecast[]) => { + dispatch(new ReceiveWeatherForecasts(startDateIndex, data)); + }); + + dispatch(new RequestWeatherForecasts(startDateIndex)); + } + } +}; + +// ---------------- +// REDUCER - For a given state and action, returns the new state. To support time travel, this must not mutate the old state. +const unloadedState: WeatherForecastsState = { startDateIndex: null, forecasts: [], isLoading: false }; +export const reducer: Reducer = (state, action) => { + if (isActionType(action, RequestWeatherForecasts)) { + return { startDateIndex: action.startDateIndex, isLoading: true, forecasts: state.forecasts }; + } else if (isActionType(action, ReceiveWeatherForecasts)) { + // Only accept the incoming data if it matches the most recent request. This ensures we correctly + // handle out-of-order responses. + if (action.startDateIndex === state.startDateIndex) { + return { startDateIndex: action.startDateIndex, forecasts: action.forecasts, isLoading: false }; + } + } + + // For unrecognized actions (or in cases where actions have no effect), must return the existing state + // (or default initial state if none was supplied) + return state || unloadedState; +}; diff --git a/templates/ReactReduxSpa/ClientApp/store/index.ts b/templates/ReactReduxSpa/ClientApp/store/index.ts new file mode 100644 index 0000000..1f4798b --- /dev/null +++ b/templates/ReactReduxSpa/ClientApp/store/index.ts @@ -0,0 +1,21 @@ +import { ActionCreatorGeneric } from 'redux-typed'; +import * as WeatherForecasts from './WeatherForecasts'; +import * as Counter from './Counter'; + +// The top-level state object +export interface ApplicationState { + counter: Counter.CounterState, + weatherForecasts: WeatherForecasts.WeatherForecastsState +} + +// Whenever an action is dispatched, Redux will update each top-level application state property using +// the reducer with the matching name. It's important that the names match exactly, and that the reducer +// acts on the corresponding ApplicationState property type. +export const reducers = { + counter: Counter.reducer, + weatherForecasts: WeatherForecasts.reducer +}; + +// This type can be used as a hint on action creators so that its 'dispatch' and 'getState' params are +// correctly typed to match your store. +export type ActionCreator = ActionCreatorGeneric; diff --git a/templates/ReactReduxSpa/Controllers/SampleDataController.cs b/templates/ReactReduxSpa/Controllers/SampleDataController.cs index 1eb3835..71abf61 100644 --- a/templates/ReactReduxSpa/Controllers/SampleDataController.cs +++ b/templates/ReactReduxSpa/Controllers/SampleDataController.cs @@ -15,12 +15,12 @@ namespace WebApplicationBasic.Controllers }; [HttpGet, Route("[action]")] - public IEnumerable WeatherForecasts() + public IEnumerable WeatherForecasts(int startDateIndex) { var rng = new Random(); return Enumerable.Range(1, 5).Select(index => new WeatherForecast { - DateFormatted = DateTime.Now.AddDays(index).ToString("d"), + DateFormatted = DateTime.Now.AddDays(index + startDateIndex).ToString("d"), TemperatureC = rng.Next(-20, 55), Summary = Summaries[rng.Next(Summaries.Length)] }); diff --git a/templates/ReactReduxSpa/package.json b/templates/ReactReduxSpa/package.json index 3199313..eb19061 100644 --- a/templates/ReactReduxSpa/package.json +++ b/templates/ReactReduxSpa/package.json @@ -28,6 +28,11 @@ "domain-task": "^1.0.0", "react": "^0.14.7", "react-dom": "^0.14.7", - "react-router": "^2.0.0" + "react-redux": "^4.4.0", + "react-router": "^2.0.0", + "react-router-redux": "^4.0.0", + "redux": "^3.3.1", + "redux-thunk": "^2.0.1", + "redux-typed": "^1.0.0" } } diff --git a/templates/ReactReduxSpa/tsconfig.json b/templates/ReactReduxSpa/tsconfig.json index 39a15ea..b6603ac 100644 --- a/templates/ReactReduxSpa/tsconfig.json +++ b/templates/ReactReduxSpa/tsconfig.json @@ -3,6 +3,7 @@ "moduleResolution": "node", "target": "es6", "jsx": "preserve", + "experimentalDecorators": true, "sourceMap": true, "skipDefaultLibCheck": true }, diff --git a/templates/ReactReduxSpa/tsd.json b/templates/ReactReduxSpa/tsd.json index 523893d..6015daa 100644 --- a/templates/ReactReduxSpa/tsd.json +++ b/templates/ReactReduxSpa/tsd.json @@ -6,19 +6,40 @@ "bundle": "typings/tsd.d.ts", "installed": { "react/react.d.ts": { - "commit": "dade4414712ce84e3c63393f1aae407e9e7e6af7" + "commit": "9f0f926a12026287b5a4a229e5672c01e7549313" }, "react-router/react-router.d.ts": { - "commit": "dade4414712ce84e3c63393f1aae407e9e7e6af7" + "commit": "9f0f926a12026287b5a4a229e5672c01e7549313" }, "react/react-dom.d.ts": { "commit": "dade4414712ce84e3c63393f1aae407e9e7e6af7" }, "react-router/history.d.ts": { - "commit": "dade4414712ce84e3c63393f1aae407e9e7e6af7" + "commit": "9f0f926a12026287b5a4a229e5672c01e7549313" }, "whatwg-fetch/whatwg-fetch.d.ts": { "commit": "dade4414712ce84e3c63393f1aae407e9e7e6af7" + }, + "react-redux/react-redux.d.ts": { + "commit": "9f0f926a12026287b5a4a229e5672c01e7549313" + }, + "redux/redux.d.ts": { + "commit": "9f0f926a12026287b5a4a229e5672c01e7549313" + }, + "react-router-redux/react-router-redux.d.ts": { + "commit": "9f0f926a12026287b5a4a229e5672c01e7549313" + }, + "redux-thunk/redux-thunk.d.ts": { + "commit": "9f0f926a12026287b5a4a229e5672c01e7549313" + }, + "uglify-js/uglify-js.d.ts": { + "commit": "9f0f926a12026287b5a4a229e5672c01e7549313" + }, + "source-map/source-map.d.ts": { + "commit": "9f0f926a12026287b5a4a229e5672c01e7549313" + }, + "webpack/webpack-env.d.ts": { + "commit": "9f0f926a12026287b5a4a229e5672c01e7549313" } } } diff --git a/templates/ReactReduxSpa/typings/react-redux/react-redux.d.ts b/templates/ReactReduxSpa/typings/react-redux/react-redux.d.ts new file mode 100644 index 0000000..9c46fd1 --- /dev/null +++ b/templates/ReactReduxSpa/typings/react-redux/react-redux.d.ts @@ -0,0 +1,68 @@ +// Type definitions for react-redux 4.4.0 +// Project: https://github.com/rackt/react-redux +// Definitions by: Qubo +// Definitions: https://github.com/borisyankov/DefinitelyTyped + +/// +/// + +declare module "react-redux" { + import { ComponentClass, Component, StatelessComponent } from 'react'; + import { Store, Dispatch, ActionCreator } from 'redux'; + + export interface ComponentConstructDecorator

    { + |StatelessComponent

    )>(component: TComponentConstruct): TComponentConstruct + } + + /** + * Connects a React component to a Redux store. + * @param mapStateToProps + * @param mapDispatchToProps + * @param mergeProps + * @param options + */ + export function connect

    (mapStateToProps?: MapStateToProps, + mapDispatchToProps?: MapDispatchToPropsFunction|MapDispatchToPropsObject, + mergeProps?: MergeProps, + options?: Options): ComponentConstructDecorator

    ; + + interface MapStateToProps { + (state: any, ownProps?: any): any; + } + + interface MapDispatchToPropsFunction { + (dispatch: Dispatch, ownProps?: any): any; + } + + interface MapDispatchToPropsObject { + [name: string]: ActionCreator; + } + + interface MergeProps { + (stateProps: any, dispatchProps: any, ownProps: any): any; + } + + interface Options { + /** + * If true, implements shouldComponentUpdate and shallowly compares the result of mergeProps, + * preventing unnecessary updates, assuming that the component is a “pure” component + * and does not rely on any input or state other than its props and the selected Redux store’s state. + * Defaults to true. + * @default true + */ + pure: boolean; + } + + export interface Property { + /** + * The single Redux store in your application. + */ + store?: Store; + children?: Function; + } + + /** + * Makes the Redux store available to the connect() calls in the component hierarchy below. + */ + export class Provider extends Component { } +} diff --git a/templates/ReactReduxSpa/typings/react-router-redux/react-router-redux.d.ts b/templates/ReactReduxSpa/typings/react-router-redux/react-router-redux.d.ts new file mode 100644 index 0000000..168161a --- /dev/null +++ b/templates/ReactReduxSpa/typings/react-router-redux/react-router-redux.d.ts @@ -0,0 +1,62 @@ +// Type definitions for react-router-redux v4.0.0 +// Project: https://github.com/rackt/react-router-redux +// Definitions by: Isman Usoh , Noah Shipley , Dimitri Rosenberg +// Definitions: https://github.com/borisyankov/DefinitelyTyped + +/// +/// + +declare namespace ReactRouterRedux { + import R = Redux; + import H = HistoryModule; + + const CALL_HISTORY_METHOD: string; + const LOCATION_CHANGE: string; + + const push: PushAction; + const replace: ReplaceAction; + const go: GoAction; + const goBack: GoForwardAction; + const goForward: GoBackAction; + const routerActions: RouteActions; + + type LocationDescriptor = H.Location | H.Path; + type PushAction = (nextLocation: LocationDescriptor) => RouterAction; + type ReplaceAction = (nextLocation: LocationDescriptor) => RouterAction; + type GoAction = (n: number) => RouterAction; + type GoForwardAction = () => RouterAction; + type GoBackAction = () => RouterAction; + + type RouterAction = { + type: string + payload?: any + } + + interface RouteActions { + push: PushAction; + replace: ReplaceAction; + go: GoAction; + goForward: GoForwardAction; + goBack: GoBackAction; + } + interface ReactRouterReduxHistory extends H.History { + unsubscribe(): void; + } + + interface DefaultSelectLocationState extends Function { + (state: any): any; + } + + interface SyncHistoryWithStoreOptions { + selectLocationState?: DefaultSelectLocationState; + adjustUrlOnReplay?: boolean; + } + + function routerReducer(state?: any, options?: any): R.Reducer; + function syncHistoryWithStore(history: H.History, store: R.Store, options?: SyncHistoryWithStoreOptions): ReactRouterReduxHistory; + function routerMiddleware(history: H.History): R.Middleware; +} + +declare module "react-router-redux" { + export = ReactRouterRedux; +} diff --git a/templates/ReactReduxSpa/typings/react-router/history.d.ts b/templates/ReactReduxSpa/typings/react-router/history.d.ts index 1b5c6df..e22dbb7 100644 --- a/templates/ReactReduxSpa/typings/react-router/history.d.ts +++ b/templates/ReactReduxSpa/typings/react-router/history.d.ts @@ -1,6 +1,6 @@ -// Type definitions for history v1.13.1 +// Type definitions for history v2.0.0 // Project: https://github.com/rackt/history -// Definitions by: Sergey Buturlakin +// Definitions by: Sergey Buturlakin , Nathan Brown // Definitions: https://github.com/borisyankov/DefinitelyTyped @@ -17,21 +17,25 @@ declare namespace HistoryModule { type CreateHistoryEnhancer = (createHistory: CreateHistory) => CreateHistory interface History { - listenBefore(hook: TransitionHook): Function - listen(listener: LocationListener): Function + listenBefore(hook: TransitionHook): () => void + listen(listener: LocationListener): () => void transitionTo(location: Location): void - pushState(state: LocationState, path: Path): void - replaceState(state: LocationState, path: Path): void - push(path: Path): void - replace(path: Path): void + push(path: LocationDescriptor): void + replace(path: LocationDescriptor): void go(n: number): void goBack(): void goForward(): void createKey(): LocationKey - createPath(path: Path): Path - createHref(path: Path): Href - createLocation(path?: Path, state?: LocationState, action?: Action, key?: LocationKey): Location + createPath(path: LocationDescriptor): Path + createHref(path: LocationDescriptor): Href + createLocation(path?: LocationDescriptor, action?: Action, key?: LocationKey): Location + /** @deprecated use a location descriptor instead */ + createLocation(path?: Path, state?: LocationState, action?: Action, key?: LocationKey): Location + /** @deprecated use location.key to save state instead */ + pushState(state: LocationState, path: Path): void + /** @deprecated use location.key to save state instead */ + replaceState(state: LocationState, path: Path): void /** @deprecated use location.key to save state instead */ setState(state: LocationState): void /** @deprecated use listenBefore instead */ @@ -40,19 +44,42 @@ declare namespace HistoryModule { unregisterTransitionHook(hook: TransitionHook): void } - type HistoryOptions = Object + type HistoryOptions = { + getCurrentLocation?: () => Location + finishTransition?: (nextLocation: Location) => boolean + saveState?: (key: LocationKey, state: LocationState) => void + go?: (n: number) => void + getUserConfirmation?: (message: string, callback: (result: boolean) => void) => void + keyLength?: number + queryKey?: string | boolean + stringifyQuery?: (obj: any) => string + parseQueryString?: (str: string) => any + basename?: string + entries?: string | [any] + current?: number + } type Href = string type Location = { pathname: Pathname - search: QueryString + search: Search query: Query state: LocationState action: Action key: LocationKey + basename?: string } + type LocationDescriptorObject = { + pathname?: Pathname + search?: Search + query?: Query + state?: LocationState + } + + type LocationDescriptor = LocationDescriptorObject | Path + type LocationKey = string type LocationListener = (location: Location) => void @@ -67,11 +94,13 @@ declare namespace HistoryModule { type QueryString = string - type TransitionHook = (location: Location, callback: Function) => any + type Search = string + + type TransitionHook = (location: Location, callback: (result: any) => void) => any interface HistoryBeforeUnload { - listenBeforeUnload(hook: BeforeUnloadHook): Function + listenBeforeUnload(hook: BeforeUnloadHook): () => void } interface HistoryQueries { @@ -168,6 +197,18 @@ declare module "history/lib/actions" { } +declare module "history/lib/DOMUtils" { + export function addEventListener(node: EventTarget, event: string, listener: EventListenerOrEventListenerObject): void; + export function removeEventListener(node: EventTarget, event: string, listener: EventListenerOrEventListenerObject): void; + export function getHashPath(): string; + export function replaceHashPath(path: string): void; + export function getWindowPath(): string; + export function go(n: number): void; + export function getUserConfirmation(message: string, callback: (result: boolean) => void): void; + export function supportsHistory(): boolean; + export function supportsGoWithoutReloadUsingHash(): boolean; +} + declare module "history" { diff --git a/templates/ReactReduxSpa/typings/react-router/react-router.d.ts b/templates/ReactReduxSpa/typings/react-router/react-router.d.ts index abed5eb..e87622e 100644 --- a/templates/ReactReduxSpa/typings/react-router/react-router.d.ts +++ b/templates/ReactReduxSpa/typings/react-router/react-router.d.ts @@ -1,6 +1,6 @@ -// Type definitions for react-router v2.0.0-rc5 +// Type definitions for react-router v2.0.0 // Project: https://github.com/rackt/react-router -// Definitions by: Sergey Buturlakin , Yuichi Murata , Václav Ostrožlík +// Definitions by: Sergey Buturlakin , Yuichi Murata , Václav Ostrožlík , Nathan Brown // Definitions: https://github.com/borisyankov/DefinitelyTyped @@ -195,6 +195,10 @@ declare namespace ReactRouter { interface IndexRedirectElement extends React.ReactElement {} const IndexRedirect: IndexRedirect + interface RouterOnContext extends H.History { + setRouteLeaveHook(route: PlainRoute, hook?: RouteHook): () => void; + isActive(pathOrLoc: H.LocationDescriptor, indexOnly?: boolean): boolean; + } /* mixins */ @@ -220,6 +224,7 @@ declare namespace ReactRouter { listenBeforeLeavingRoute(route: PlainRoute, hook: RouteHook): void match(location: H.Location, callback: (error: any, nextState: RouterState, nextLocation: H.Location) => void): void isActive(pathname: H.Pathname, query?: H.Query, indexOnly?: boolean): boolean + setRouteLeaveHook(route: PlainRoute, callback: RouteHook): void } function useRoutes(createHistory: HistoryModule.CreateHistory): HistoryModule.CreateHistory @@ -447,6 +452,7 @@ declare module "react-router" { export type RouterListener = ReactRouter.RouterListener export type RouterState = ReactRouter.RouterState export type HistoryBase = ReactRouter.HistoryBase + export type RouterOnContext = ReactRouter.RouterOnContext export { Router, diff --git a/templates/ReactReduxSpa/typings/react/react.d.ts b/templates/ReactReduxSpa/typings/react/react.d.ts index 5753731..f4369e4 100644 --- a/templates/ReactReduxSpa/typings/react/react.d.ts +++ b/templates/ReactReduxSpa/typings/react/react.d.ts @@ -10,30 +10,32 @@ declare namespace __React { // ---------------------------------------------------------------------- type ReactType = string | ComponentClass | StatelessComponent; + type Key = string | number; + type Ref = string | ((instance: T) => any); interface ReactElement

    > { type: string | ComponentClass

    | StatelessComponent

    ; props: P; - key: string | number; - ref: string | ((component: Component | Element) => any); + key: Key; + ref: Ref | Element>; } interface ClassicElement

    extends ReactElement

    { type: ClassicComponentClass

    ; - ref: string | ((component: ClassicComponent) => any); + ref: Ref>; } interface DOMElement

    > extends ReactElement

    { type: string; - ref: string | ((element: Element) => any); + ref: Ref; } interface ReactHTMLElement extends DOMElement> { - ref: string | ((element: HTMLElement) => any); + ref: Ref; } interface ReactSVGElement extends DOMElement { - ref: string | ((element: SVGElement) => any); + ref: Ref; } // @@ -90,17 +92,21 @@ declare namespace __React { props?: P, ...children: ReactNode[]): ReactElement

    ; - function cloneElement

    ( - element: DOMElement

    , - props?: P, - ...children: ReactNode[]): DOMElement

    ; - function cloneElement

    ( + function cloneElement( + element: ReactHTMLElement, + props?: HTMLProps, + ...children: ReactNode[]): ReactHTMLElement; + function cloneElement( + element: ReactSVGElement, + props?: SVGProps, + ...children: ReactNode[]): ReactSVGElement; + function cloneElement

    ( element: ClassicElement

    , - props?: P, + props?: Q, ...children: ReactNode[]): ClassicElement

    ; - function cloneElement

    ( + function cloneElement

    ( element: ReactElement

    , - props?: P, + props?: Q, ...children: ReactNode[]): ReactElement

    ; function isValidElement(object: {}): boolean; @@ -321,8 +327,8 @@ declare namespace __React { interface Props { children?: ReactNode; - key?: string | number; - ref?: string | ((component: T) => any); + key?: Key; + ref?: Ref; } interface HTMLProps extends HTMLAttributes, Props { @@ -427,31 +433,7 @@ declare namespace __React { // This interface is not complete. Only properties accepting // unitless numbers are listed here (see CSSProperty.js in React) interface CSSProperties { - boxFlex?: number; - boxFlexGroup?: number; - columnCount?: number; - flex?: number | string; - flexGrow?: number; - flexShrink?: number; - fontWeight?: number | string; - lineClamp?: number; - lineHeight?: number | string; - opacity?: number; - order?: number; - orphans?: number; - widows?: number; - zIndex?: number; - zoom?: number; - fontSize?: number | string; - - // SVG-related properties - fillOpacity?: number; - strokeOpacity?: number; - strokeWidth?: number; - - // Remaining properties auto-extracted from http://docs.webplatform.org. - // License: http://docs.webplatform.org/wiki/Template:CC-by-3.0 /** * Aligns a flex container's lines within the flex container when there is extra space in the cross-axis, similar to how justify-content aligns individual items within the main-axis. */ @@ -509,12 +491,30 @@ declare namespace __React { */ backfaceVisibility?: any; + /** + * Shorthand property to set the values for one or more of: + * background-clip, background-color, background-image, + * background-origin, background-position, background-repeat, + * background-size, and background-attachment. + */ + background?: any; + + /** + * If a background-image is specified, this property determines + * whether that image's position is fixed within the viewport, + * or scrolls along with its containing block. + */ + backgroundAttachment?: "scroll" | "fixed" | "local"; + /** * This property describes how the element's background images should blend with each other and the element's background color. * The value is a list of blend modes that corresponds to each background image. Each element in the list will apply to the corresponding element of background-image. If a property doesn’t have enough comma-separated values to match the number of layers, the UA must calculate its used value by repeating the list of values until there are enough. */ backgroundBlendMode?: any; + /** + * Sets the background color of an element. + */ backgroundColor?: any; backgroundComposite?: any; @@ -530,9 +530,9 @@ declare namespace __React { backgroundOrigin?: any; /** - * Sets the horizontal position of a background image. + * Sets the position of a background image. */ - backgroundPositionX?: any; + backgroundPosition?: any; /** * Background-repeat defines if and how background images will be repeated after they have been sized and positioned @@ -554,6 +554,17 @@ declare namespace __React { */ border?: any; + /** + * Shorthand that sets the values of border-bottom-color, + * border-bottom-style, and border-bottom-width. + */ + borderBottom?: any; + + /** + * Sets the color of the bottom border of an element. + */ + borderBottomColor?: any; + /** * Defines the shape of the border of the bottom-left corner. */ @@ -564,6 +575,11 @@ declare namespace __React { */ borderBottomRightRadius?: any; + /** + * Sets the line style of the bottom border of a box. + */ + borderBottomStyle?: any; + /** * Sets the width of an element's bottom border. To set all four borders, use the border-width shorthand property which sets the values simultaneously for border-top-width, border-right-width, border-bottom-width, and border-left-width. */ @@ -724,6 +740,16 @@ declare namespace __React { */ boxOrdinalGroup?: any; + /** + * Deprecated. + */ + boxFlex?: number; + + /** + * Deprecated. + */ + boxFlexGroup?: number; + /** * The CSS break-after property allows you to force a break on multi-column layouts. More specifically, it allows you to force a break after an element. It allows you to determine if a break should occur, and what type of break it should be. The break-after CSS property describes how the page, column or region break behaves after the generated box. If there is no generated box, the property is ignored. */ @@ -760,6 +786,11 @@ declare namespace __React { */ color?: any; + /** + * Describes the number of columns of the element. + */ + columnCount?: number; + /** * Specifies how to fill columns (balanced or sequential). */ @@ -820,6 +851,11 @@ declare namespace __React { */ cueAfter?: any; + /** + * Specifies the mouse cursor displayed when the mouse pointer is over an element. + */ + cursor?: any; + /** * The direction CSS property specifies the text direction/writing direction. The rtl is used for Hebrew or Arabic text, the ltr is for other languages. */ @@ -835,6 +871,11 @@ declare namespace __React { */ fill?: any; + /** + * SVG: Specifies the opacity of the color or the content the current object is filled with. + */ + fillOpacity?: number; + /** * The ‘fill-rule’ property indicates the algorithm which is to be used to determine what parts of the canvas are included inside the shape. For a simple, non-intersecting path, it is intuitively clear what region lies "inside"; however, for a more complex path, such as a path that intersects itself or where one subpath encloses another, the interpretation of "inside" is not so obvious. * The ‘fill-rule’ property provides two options for how the inside of a shape is determined: @@ -846,6 +887,11 @@ declare namespace __React { */ filter?: any; + /** + * Shorthand for `flex-grow`, `flex-shrink`, and `flex-basis`. + */ + flex?: number | string; + /** * Obsolete, do not use. This property has been renamed to align-items. * Specifies the alignment (perpendicular to the layout axis defined by the flex-direction property) of child elements of the object. @@ -867,6 +913,11 @@ declare namespace __React { */ flexFlow?: any; + /** + * Specifies the flex grow factor of a flex item. + */ + flexGrow?: number; + /** * Do not use. This property has been renamed to align-self * Specifies the alignment (perpendicular to the layout axis defined by flex-direction) of child elements of the object. @@ -884,6 +935,11 @@ declare namespace __React { */ flexOrder?: any; + /** + * Specifies the flex shrink factor of a flex item. + */ + flexShrink?: number; + /** * Elements which have the style float are floated horizontally. These elements can move as far to the left or right of the containing element. All elements after the floating element will flow around it, but elements before the floating element are not impacted. If several floating elements are placed after each other, they will float next to each other as long as there is room. */ @@ -909,6 +965,11 @@ declare namespace __React { */ fontKerning?: any; + /** + * Specifies the size of the font. Used to compute em and ex units. + */ + fontSize?: number | string; + /** * The font-size-adjust property adjusts the font-size of the fallback fonts defined with font-family, so that the x-height is the same no matter what font is used. This preserves the readability of the text when fallback happens. */ @@ -939,6 +1000,11 @@ declare namespace __React { */ fontVariantAlternates?: any; + /** + * Specifies the weight or boldness of the font. + */ + fontWeight?: "normal" | "bold" | "lighter" | "bolder" | number; + /** * Lays out one or more grid items bound by 4 grid lines. Shorthand for setting grid-column-start, grid-column-end, grid-row-start, and grid-row-end in a single declaration. */ @@ -1044,6 +1110,13 @@ declare namespace __React { */ lineBreak?: any; + lineClamp?: number; + + /** + * Specifies the height of an inline block level element. + */ + lineHeight?: number | string; + /** * Shorthand property that sets the list-style-type, list-style-position and list-style-image properties in one declaration. */ @@ -1164,6 +1237,23 @@ declare namespace __React { */ minWidth?: any; + /** + * Specifies the transparency of an element. + */ + opacity?: number; + + /** + * Specifies the order used to lay out flex items in their flex container. + * Elements are laid out in the ascending order of the order value. + */ + order?: number; + + /** + * In paged media, this property defines the minimum number of lines in + * a block container that must be left at the bottom of the page. + */ + orphans?: number; + /** * The CSS outline property is a shorthand property for setting one or more of the individual outline properties outline-style, outline-width and outline-color in a single rule. In most cases the use of this shortcut is preferable and more convenient. * Outlines differ from borders in the following ways: • Outlines do not take up space, they are drawn above the content. @@ -1192,10 +1282,15 @@ declare namespace __React { overflowStyle?: any; /** - * The overflow-x property is a specific case of the generic overflow property. It controls how extra content exceeding the x-axis of the bounding box of an element is rendered. + * Controls how extra content exceeding the x-axis of the bounding box of an element is rendered. */ overflowX?: any; + /** + * Controls how extra content exceeding the y-axis of the bounding box of an element is rendered. + */ + overflowY?: any; + /** * The padding optional CSS property sets the required padding space on one to four sides of an element. The padding area is the space between an element and its border. Negative values are not allowed but decimal values are permitted. The element size is treated as fixed, and the content of the element shifts toward the center as padding is increased. * The padding property is a shorthand to avoid setting each side separately (padding-top, padding-right, padding-bottom, padding-left). @@ -1341,6 +1436,16 @@ declare namespace __React { */ speakAs?: any; + /** + * SVG: Specifies the opacity of the outline on the current object. + */ + strokeOpacity?: number; + + /** + * SVG: Specifies the width of the outline on the current object. + */ + strokeWidth?: number; + /** * The tab-size CSS property is used to customise the width of a tab (U+0009) character. */ @@ -1649,6 +1754,12 @@ declare namespace __React { */ whiteSpaceTreatment?: any; + /** + * In paged media, this property defines the mimimum number of lines + * that must be left at the top of the second page. + */ + widows?: number; + /** * Specifies the width of the content area of an element. The content area of the element width does not include the padding, border, and margin of the element. */ @@ -1690,6 +1801,16 @@ declare namespace __React { */ writingMode?: any; + /** + * The z-index property specifies the z-order of an element and its descendants. + * When elements overlap, z-order determines which one covers the other. + */ + zIndex?: "auto" | number; + + /** + * Sets the initial zoom factor of a document defined by @viewport. + */ + zoom?: "auto" | number; [propertyName: string]: any; } @@ -1843,6 +1964,9 @@ declare namespace __React { results?: number; security?: string; unselectable?: boolean; + + // Allows aria- and data- Attributes + [key: string]: any; } interface SVGAttributes extends HTMLAttributes { @@ -2133,11 +2257,11 @@ declare namespace JSX { interface ElementAttributesProperty { props: {}; } interface IntrinsicAttributes { - key?: string | number; + key?: React.Key; } interface IntrinsicClassAttributes { - ref?: string | ((classInstance: T) => void); + ref?: React.Ref; } interface IntrinsicElements { diff --git a/templates/ReactReduxSpa/typings/redux-thunk/redux-thunk.d.ts b/templates/ReactReduxSpa/typings/redux-thunk/redux-thunk.d.ts new file mode 100644 index 0000000..aafaa04 --- /dev/null +++ b/templates/ReactReduxSpa/typings/redux-thunk/redux-thunk.d.ts @@ -0,0 +1,18 @@ +// Type definitions for redux-thunk +// Project: https://github.com/gaearon/redux-thunk +// Definitions by: Qubo +// Definitions: https://github.com/borisyankov/DefinitelyTyped + +/// + +declare module ReduxThunk { + export interface Thunk extends Redux.Middleware {} + export interface ThunkInterface { + (dispatch: Redux.Dispatch, getState?: () => T): any; + } +} + +declare module "redux-thunk" { + var thunk: ReduxThunk.Thunk; + export = thunk; +} diff --git a/templates/ReactReduxSpa/typings/redux/redux.d.ts b/templates/ReactReduxSpa/typings/redux/redux.d.ts new file mode 100644 index 0000000..44cb297 --- /dev/null +++ b/templates/ReactReduxSpa/typings/redux/redux.d.ts @@ -0,0 +1,52 @@ +// Type definitions for Redux v1.0.0 +// Project: https://github.com/rackt/redux +// Definitions by: William Buchwalter , Vincent Prouillet +// Definitions: https://github.com/borisyankov/DefinitelyTyped + +declare module Redux { + + interface ActionCreator extends Function { + (...args: any[]): any; + } + + interface Reducer extends Function { + (state: any, action: any): any; + } + + interface Dispatch extends Function { + (action: any): any; + } + + interface StoreMethods { + dispatch: Dispatch; + getState(): any; + } + + + interface MiddlewareArg { + dispatch: Dispatch; + getState: Function; + } + + interface Middleware extends Function { + (obj: MiddlewareArg): Function; + } + + class Store { + getReducer(): Reducer; + replaceReducer(nextReducer: Reducer): void; + dispatch(action: any): any; + getState(): any; + subscribe(listener: Function): Function; + } + + function createStore(reducer: Reducer, initialState?: any, enhancer?: ()=>any): Store; + function bindActionCreators(actionCreators: T, dispatch: Dispatch): T; + function combineReducers(reducers: any): Reducer; + function applyMiddleware(...middlewares: Middleware[]): Function; + function compose(...functions: Function[]): T; +} + +declare module "redux" { + export = Redux; +} diff --git a/templates/ReactReduxSpa/typings/source-map/source-map.d.ts b/templates/ReactReduxSpa/typings/source-map/source-map.d.ts new file mode 100644 index 0000000..34aae2b --- /dev/null +++ b/templates/ReactReduxSpa/typings/source-map/source-map.d.ts @@ -0,0 +1,90 @@ +// Type definitions for source-map v0.1.38 +// Project: https://github.com/mozilla/source-map +// Definitions by: Morten Houston Ludvigsen +// Definitions: https://github.com/borisyankov/DefinitelyTyped + +declare module SourceMap { + interface StartOfSourceMap { + file?: string; + sourceRoot?: string; + } + + interface RawSourceMap extends StartOfSourceMap { + version: string; + sources: Array; + names: Array; + sourcesContent?: string[]; + mappings: string; + } + + interface Position { + line: number; + column: number; + } + + interface MappedPosition extends Position { + source: string; + name?: string; + } + + interface MappingItem { + source: string; + generatedLine: number; + generatedColumn: number; + originalLine: number; + originalColumn: number; + name: string; + } + + interface Mapping { + generated: Position; + original: Position; + source: string; + name?: string; + } + + interface CodeWithSourceMap { + code: string; + map: SourceMapGenerator; + } + + class SourceMapConsumer { + public static GENERATED_ORDER: number; + public static ORIGINAL_ORDER: number; + + constructor(rawSourceMap: RawSourceMap); + public originalPositionFor(generatedPosition: Position): MappedPosition; + public generatedPositionFor(originalPosition: MappedPosition): Position; + public sourceContentFor(source: string): string; + public eachMapping(callback: (mapping: MappingItem) => void, context?: any, order?: number): void; + } + + class SourceMapGenerator { + constructor(startOfSourceMap?: StartOfSourceMap); + public static fromSourceMap(sourceMapConsumer: SourceMapConsumer): SourceMapGenerator; + public addMapping(mapping: Mapping): void; + public setSourceContent(sourceFile: string, sourceContent: string): void; + public applySourceMap(sourceMapConsumer: SourceMapConsumer, sourceFile?: string, sourceMapPath?: string): void; + public toString(): string; + } + + class SourceNode { + constructor(); + constructor(line: number, column: number, source: string); + constructor(line: number, column: number, source: string, chunk?: string, name?: string); + public static fromStringWithSourceMap(code: string, sourceMapConsumer: SourceMapConsumer, relativePath?: string): SourceNode; + public add(chunk: any): SourceNode; + public prepend(chunk: any): SourceNode; + public setSourceContent(sourceFile: string, sourceContent: string): void; + public walk(fn: (chunk: string, mapping: MappedPosition) => void): void; + public walkSourceContents(fn: (file: string, content: string) => void): void; + public join(sep: string): SourceNode; + public replaceRight(pattern: string, replacement: string): SourceNode; + public toString(): string; + public toStringWithSourceMap(startOfSourceMap?: StartOfSourceMap): CodeWithSourceMap; + } +} + +declare module 'source-map' { + export = SourceMap; +} diff --git a/templates/ReactReduxSpa/typings/tsd.d.ts b/templates/ReactReduxSpa/typings/tsd.d.ts index f54e1c6..4a4bd18 100644 --- a/templates/ReactReduxSpa/typings/tsd.d.ts +++ b/templates/ReactReduxSpa/typings/tsd.d.ts @@ -4,3 +4,10 @@ /// /// /// +/// +/// +/// +/// +/// +/// +/// diff --git a/templates/ReactReduxSpa/typings/uglify-js/uglify-js.d.ts b/templates/ReactReduxSpa/typings/uglify-js/uglify-js.d.ts new file mode 100644 index 0000000..b9c22bc --- /dev/null +++ b/templates/ReactReduxSpa/typings/uglify-js/uglify-js.d.ts @@ -0,0 +1,430 @@ +// Type definitions for UglifyJS 2 v2.6.1 +// Project: https://github.com/mishoo/UglifyJS2 +// Definitions by: Tanguy Krotoff +// Definitions: https://github.com/borisyankov/DefinitelyTyped + +/// + +declare module 'uglify-js' { + import * as MOZ_SourceMap from 'source-map'; + + namespace UglifyJS { + interface Tokenizer { + /** + * The type of this token. + * Can be "num", "string", "regexp", "operator", "punc", "atom", "name", "keyword", "comment1" or "comment2". + * "comment1" and "comment2" are for single-line, respectively multi-line comments. + */ + type: string; + + /** + * The name of the file where this token originated from. Useful when compressing multiple files at once to generate the proper source map. + */ + file: string; + + /** + * The "value" of the token. + * That's additional information and depends on the token type: "num", "string" and "regexp" tokens you get their literal value. + * - For "operator" you get the operator. + * - For "punc" it's the punctuation sign (parens, comma, semicolon etc). + * - For "atom", "name" and "keyword" it's the name of the identifier + * - For comments it's the body of the comment (excluding the initial "//" and "/*". + */ + value: string; + + /** + * The line number of this token in the original code. + * 1-based index. + */ + line: number; + + /** + * The column number of this token in the original code. + * 0-based index. + */ + col: number; + + /** + * Short for "newline before", it's a boolean that tells us whether there was a newline before this node in the original source. It helps for automatic semicolon insertion. + * For multi-line comments in particular this will be set to true if there either was a newline before this comment, or * * if this comment contains a newline. + */ + nlb: boolean; + + /** + * This doesn't apply for comment tokens, but for all other token types it will be an array of comment tokens that were found before. + */ + comments_before: string[]; + } + + interface AST_Node { + // The first token of this node + start: AST_Node; + + // The last token of this node + end: AST_Node; + + transform(tt: TreeTransformer): AST_Toplevel; + } + + interface AST_Toplevel extends AST_Node { + // UglifyJS contains a scope analyzer which figures out variable/function definitions, references etc. + // You need to call it manually before compression or mangling. + // The figure_out_scope method is defined only on the AST_Toplevel node. + figure_out_scope(): void; + + // Get names that are optimized for GZip compression (names will be generated using the most frequent characters first) + compute_char_frequency(): void; + + mangle_names(): void; + + print(stream: OutputStream): void; + + print_to_string(options?: BeautifierOptions): string; + } + + interface MinifyOptions { + spidermonkey?: boolean; + outSourceMap?: string; + sourceRoot?: string; + inSourceMap?: string; + fromString?: boolean; + warnings?: boolean; + mangle?: Object; + output?: MinifyOutput, + compress?: Object; + } + + interface MinifyOutput { + code: string; + map: string; + } + + function minify(files: string | Array, options?: MinifyOptions): MinifyOutput; + + + interface ParseOptions { + // Default is false + strict?: boolean; + + // Input file name, default is null + filename?: string; + + // Default is null + toplevel?: AST_Toplevel; + } + + /** + * The parser creates a custom abstract syntax tree given a piece of JavaScript code. + * Perhaps you should read about the AST first. + */ + function parse(code: string, options?: ParseOptions): AST_Toplevel; + + + interface BeautifierOptions { + /** + * Start indentation on every line (only when `beautify`) + */ + indent_start?: number; + + /** + * Indentation level (only when `beautify`) + */ + indent_level?: number; + + /** + * Quote all keys in object literals? + */ + quote_keys?: boolean; + + /** + * Add a space after colon signs? + */ + space_colon?: boolean; + + /** + * Output ASCII-safe? (encodes Unicode characters as ASCII) + */ + ascii_only?: boolean; + + /** + * Escape " boolean; + + /** + * UglifyJS provides a TreeWalker object and every node has a walk method that given a walker will apply your visitor to each node in the tree. + * Your visitor can return a non-falsy value in order to prevent descending the current node. + */ + function TreeWalker(visitor: visitor): TreeWalker; + + + // TODO + interface TreeTransformer extends TreeWalker { + } + + /** + * The tree transformer is a special case of a tree walker. + * In fact it even inherits from TreeWalker and you can use the same methods, but initialization and visitor protocol are a bit different. + */ + function TreeTransformer(before: visitor, after: visitor): TreeTransformer; + } + + export = UglifyJS; +} diff --git a/templates/ReactReduxSpa/typings/webpack/webpack-env.d.ts b/templates/ReactReduxSpa/typings/webpack/webpack-env.d.ts new file mode 100644 index 0000000..0458094 --- /dev/null +++ b/templates/ReactReduxSpa/typings/webpack/webpack-env.d.ts @@ -0,0 +1,232 @@ +// Type definitions for webpack 1.12.2 (module API) +// Project: https://github.com/webpack/webpack +// Definitions by: use-strict +// Definitions: https://github.com/borisyankov/DefinitelyTyped + +/** + * Webpack module API - variables and global functions available inside modules + */ + +declare namespace __WebpackModuleApi { + interface RequireContext { + keys(): string[]; + (id: string): T; + resolve(id: string): string; + } + + interface RequireFunction { + /** + * Returns the exports from a dependency. The call is sync. No request to the server is fired. The compiler ensures that the dependency is available. + */ + (path: string): T; + /** + * Behaves similar to require.ensure, but the callback is called with the exports of each dependency in the paths array. There is no option to provide a chunk name. + */ + (paths: string[], callback: (...modules: any[]) => void): void; + /** + * Download additional dependencies on demand. The paths array lists modules that should be available. When they are, callback is called. If the callback is a function expression, dependencies in that source part are extracted and also loaded on demand. A single request is fired to the server, except if all modules are already available. + * + * This creates a chunk. The chunk can be named. If a chunk with this name already exists, the dependencies are merged into that chunk and that chunk is used. + */ + ensure: (paths: string[], callback: (require: (path: string) => T) => void, chunkName?: string) => void; + context: (path: string, deep?: boolean, filter?: RegExp) => RequireContext; + /** + * Returns the module id of a dependency. The call is sync. No request to the server is fired. The compiler ensures that the dependency is available. + * + * The module id is a number in webpack (in contrast to node.js where it is a string, the filename). + */ + resolve(path: string): number; + /** + * Like require.resolve, but doesn’t include the module into the bundle. It’s a weak dependency. + */ + resolveWeak(path: string): number; + /** + * Ensures that the dependency is available, but don’t execute it. This can be use for optimizing the position of a module in the chunks. + */ + include(path: string): void; + /** + * Multiple requires to the same module result in only one module execution and only one export. Therefore a cache in the runtime exists. Removing values from this cache cause new module execution and a new export. This is only needed in rare cases (for compatibility!). + */ + cache: { + [id: string]: any; + } + } + + interface Module { + exports: any; + require(id: string): any; + id: string; + filename: string; + loaded: boolean; + parent: any; + children: any[]; + hot: Hot; + } + type ModuleId = string|number; + + interface Hot { + /** + * Accept code updates for the specified dependencies. The callback is called when dependencies were replaced. + * @param dependencies + * @param callback + */ + accept(dependencies: string[], callback: (updatedDependencies: ModuleId[]) => void): void; + /** + * Accept code updates for the specified dependencies. The callback is called when dependencies were replaced. + * @param dependency + * @param callback + */ + accept(dependency: string, callback: () => void): void; + /** + * Accept code updates for this module without notification of parents. + * This should only be used if the module doesn’t export anything. + * The errHandler can be used to handle errors that occur while loading the updated module. + * @param errHandler + */ + accept(errHandler?: (err: Error) => void): void; + /** + * Do not accept updates for the specified dependencies. If any dependencies is updated, the code update fails with code "decline". + */ + decline(dependencies: string[]): void; + /** + * Do not accept updates for the specified dependencies. If any dependencies is updated, the code update fails with code "decline". + */ + decline(dependency: string): void; + /** + * Flag the current module as not update-able. If updated the update code would fail with code "decline". + */ + decline(): void; + /** + * Add a one time handler, which is executed when the current module code is replaced. + * Here you should destroy/remove any persistent resource you have claimed/created. + * If you want to transfer state to the new module, add it to data object. + * The data will be available at module.hot.data on the new module. + * @param callback + */ + dispose(callback: (data: T) => void): void; + /** + * Add a one time handler, which is executed when the current module code is replaced. + * Here you should destroy/remove any persistent resource you have claimed/created. + * If you want to transfer state to the new module, add it to data object. + * The data will be available at module.hot.data on the new module. + * @param callback + */ + addDisposeHandler(callback: (data: T) => void): void; + /** + * Remove a handler. + * This can useful to add a temporary dispose handler. You could i. e. replace code while in the middle of a multi-step async function. + * @param callback + */ + removeDisposeHandler(callback: (data: T) => void): void; + /** + * Throws an exceptions if status() is not idle. + * Check all currently loaded modules for updates and apply updates if found. + * If no update was found, the callback is called with null. + * If autoApply is truthy the callback will be called with all modules that were disposed. + * apply() is automatically called with autoApply as options parameter. + * If autoApply is not set the callback will be called with all modules that will be disposed on apply(). + * @param autoApply + * @param callback + */ + check(autoApply: boolean, callback: (err: Error, outdatedModules: ModuleId[]) => void): void; + /** + * Throws an exceptions if status() is not idle. + * Check all currently loaded modules for updates and apply updates if found. + * If no update was found, the callback is called with null. + * The callback will be called with all modules that will be disposed on apply(). + * @param callback + */ + check(callback: (err: Error, outdatedModules: ModuleId[]) => void): void; + /** + * If status() != "ready" it throws an error. + * Continue the update process. + * @param options + * @param callback + */ + apply(options: AcceptOptions, callback: (err: Error, outdatedModules: ModuleId[]) => void): void; + /** + * If status() != "ready" it throws an error. + * Continue the update process. + * @param callback + */ + apply(callback: (err: Error, outdatedModules: ModuleId[]) => void): void; + /** + * Return one of idle, check, watch, watch-delay, prepare, ready, dispose, apply, abort or fail. + */ + status(): string; + /** Register a callback on status change. */ + status(callback: (status: string) => void): void; + /** Register a callback on status change. */ + addStatusHandler(callback: (status: string) => void): void; + /** + * Remove a registered status change handler. + * @param callback + */ + removeStatusHandler(callback: (status: string) => void): void; + + active: boolean; + data: {}; + } + + interface AcceptOptions { + /** + * If true the update process continues even if some modules are not accepted (and would bubble to the entry point). + */ + ignoreUnaccepted?: boolean; + /** + * Indicates that apply() is automatically called by check function + */ + autoApply?: boolean; + } +} + +declare var require: __WebpackModuleApi.RequireFunction; + +/** + * The resource query of the current module. + * + * e.g. __resourceQuery === "?test" // Inside "file.js?test" + */ +declare var __resourceQuery: string; + +/** + * Equals the config options output.publicPath. + */ +declare var __webpack_public_path__: string; + +/** + * The raw require function. This expression isn’t parsed by the Parser for dependencies. + */ +declare var __webpack_require__: any; + +/** + * The internal chunk loading function + * + * @param chunkId The id for the chunk to load. + * @param callback A callback function called once the chunk is loaded. + */ +declare var __webpack_chunk_load__: (chunkId: any, callback: (require: (id: string) => any) => void) => void; + +/** + * Access to the internal object of all modules. + */ +declare var __webpack_modules__: any[]; + +/** + * Access to the hash of the compilation. + * + * Only available with the HotModuleReplacementPlugin or the ExtendedAPIPlugin + */ +declare var __webpack_hash__: any; + +/** + * Generates a require function that is not parsed by webpack. Can be used to do cool stuff with a global require function if available. + */ +declare var __non_webpack_require__: any; + +/** + * Equals the config option debug + */ +declare var DEBUG: boolean; + +declare var module: __WebpackModuleApi.Module; diff --git a/templates/ReactReduxSpa/webpack.config.prod.js b/templates/ReactReduxSpa/webpack.config.prod.js index 068da38..94bbedf 100644 --- a/templates/ReactReduxSpa/webpack.config.prod.js +++ b/templates/ReactReduxSpa/webpack.config.prod.js @@ -11,6 +11,7 @@ module.exports = { plugins: [ extractCSS, new webpack.optimize.OccurenceOrderPlugin(), - new webpack.optimize.UglifyJsPlugin({ compress: { warnings: false } }) + new webpack.optimize.UglifyJsPlugin({ compress: { warnings: false } }), + new webpack.DefinePlugin({ 'process.env.NODE_ENV': '"production"' }) ] }; diff --git a/templates/ReactReduxSpa/webpack.config.vendor.js b/templates/ReactReduxSpa/webpack.config.vendor.js index e0b57b8..c06238a 100644 --- a/templates/ReactReduxSpa/webpack.config.vendor.js +++ b/templates/ReactReduxSpa/webpack.config.vendor.js @@ -31,6 +31,7 @@ module.exports = { name: '[name]_[hash]' }) ].concat(isDevelopment ? [] : [ - new webpack.optimize.UglifyJsPlugin({ compress: { warnings: false } }) + new webpack.optimize.UglifyJsPlugin({ compress: { warnings: false } }), + new webpack.DefinePlugin({ 'process.env.NODE_ENV': '"production"' }) ]) };