- Removed ld dependency
- Improved add github action
photo-uploader.
- Removed
PHOTO_SCALAR_SALT
no longer required for the new photo-uploader.
- Improved upgraded node to v10.22.1
- Improved add
SameSite
policy to click-track cookie
- Removed Retire
mwp-csp-plugin
. All common security headers have been consolidated in Fastly.
- Removed Retire newrelic integration
- Removed Retire signalsciences integration
-
New feature
state.config.geo
, which contains geolocation info provided inrequestUtils.getRemoteGeoLocation
. Also added ability to read two new geolocation headers, if they exist in the request:x-geo-city
- plain city name string, e.g. provided byclient.geo.city
in Fastlyx-geo-latlon
- comma-separated lat/lon
These headers will be custom-set in our www Fastly config
state.config.geo
is currenty aGeoLocation
object, with a flow type defined in flow-typed/platform/js
- New feature
mwp-config
now exports apackages.mupwebPackages
path Regex pointing to the/packages/<package-name>/lib
directory in monorepo consumers (e.g. mup-web)
- New feature The Google Tag Manager util now targets specific GTM Environments based on the running environment (eg: prod, dev). Environments can also be manually chosen by passing parameters to the GTM util.
- New feature
mwp-config
now exports apaths.localPackages
path pointing to the/packages
directory in monorepo consumers (e.g. mup-web)
- Breaking change
mwp-config
now specifies babel-loader rules for Babel 7 instead of Babel 6. Downstream consumers should work with the Web Platform team to make the update
- Refactor Upgraded MWP build to Babel7 and corresponding plugins. All built packages are now the same size or slightly smaller, but there is some risk that the assets will no longer work in some older browsers, so consumer beware - you should upgrade MWP packages independently of other code changes so that it is easier to isolate problems and revert.
-
New Feature
AppContext
context provider for server-side request data. This feature supersedes accessingstate.config
through Redux in favor of a more conventional React context implementation. Check out the docs for more info.withIntl
has been refactored to use this interface instead ofreact-redux
connect
in order to avoid issues with the pure rendering constraints ofconnect
- New Feature the query
endpoint
property can now be a fully-qualified URL in order to call APIs on domains other than https://api.meetup.com
- BREAKING CHANGE -
mwp-toaster
:<ToastContainer>
now takes an object with system messages mappings instead of a message key and an array of messages.
- New Feature activity tracking support for
standardized_url
andstandardized_referer
(new fields in Activity v9).- API proxy endpoint (
mwp-api-proxy-plugin
) reads from url-encodedx-meetup-activity
header - API proxy method (
mwp-api-proxy-plugin
) takesactivityInfo
argument to inject fields into activity records mwp-store
browserfetchQueries
sendsx-meetup-activity
headermwp-store
serverfetchQueries
passesactivityInfo
tomwp-api-store
suppliesactivityInfo
argument tofetchQueries
- API proxy endpoint (
-
BREAKING CHANGE -
makeRenderer$
interface into server renderer removed - must use object-basedmakeRenderer
-
Refactor
mwp-api-proxy-plugin
now providesrequest.apiProxy
interface, which uses native Promises instead of Observables.rxjs
is no longer a peer dependency of any MWP packages.
- Removed
state.app
reducers. Consumers must convert to usingstate.api
.
- Refactor
mwp-app-route-plugin
defines aLaunchDarklyUser
type for a LaunchDarkly user object based on the official documentation - Refactor
mwp-core
uses aLaunchDarklyUser
object to callgetFlags
method ofmwp-app-route-plugin
. - New Feature
mwp-core
adds a request country and region provided by Fastly to LaunchDarkly user custom attributes.
- Adds new rasp plugin which monitors and prevents traffic from bad actors. This RASP integration uses Signal Sciences. @see https://docs.signalsciences.net/install-guides/nodejs-module/#usage-for-nodejs-hapi
- BREAKING CHANGE Upgraded to ux-capture 3.0.0.
- Renamed:
UXCaptureConfig
isUXCaptureCreate
- Renamed:
UXCaptureExpect
isUXCaptureStartView
- Refactor
mwp-tracking-plugin
now explicitly handles each type of request that results in an activity record to ensure that the expectedurl
andreferrer
values are populated
- New feature added support for
put
request
- Refactor click tracking provided by
mwp-tracking-plugin
now keeps click state in a cookie rather than Redux state.
- NEW FEATURE Create 'mwp-csp-plugin' which adds some useful security headers
- BREAKING CHANGE Upgrade to hapi v17, which requires updating of much of the platform code. Consumer apps that leverage the hapi server
- Logging change - no more stdout debug logging for tracking calls, no logging of successful api.meetup.com calls in prod.
- NEW FEATURE the API proxy path prefix can now be specified using an app's
package.json
file by specifyingconfig.apiProxyPath
with a leading slash, e.g./mu_api
, or by an env variableAPI_PROXY_PATH
.
- NEW FEATURE A selector for pulling Feature Flags from redux state
mwp-store/lib/selectors
getFeatureFlags
- This selector will pull all feature flags from
state->flags
- NEW FEATURE query functions attached to routes will now get called with a
second argument,
state
, which is the application's current Redux state. This can be used , for example, to inspect feature flags to determine what API request to make
- NEW FEATURE
mwp-app-render/lib/components/StateBroadcast
component that can be inserted anywhere in an application in order to enable awindow.getAppState()
function that returns the current Redux state tree as a single object.
- NEW FEATURE the prod REST API can now be used directly in the dev environment.
To enable, simply add
{ "api": { "host": "api.meetup.com" } }
to aconfig.development.json
file in the root of your application. Note: there is no visible difference between using the prod REST API and the dev REST API. Try not to chnage any data that doesn't belong to you.
- BREAKING CHANGE webpack build configurations have been moved to
mwp-cli and are no longer a part of
mwp-config
. Make sure to upgrade to mwp-cli >=7.1.429
.
- NEW FEATURE
api.track
action creator for async activity tracking requests from consumer apps. Pass alongviewName
and (optionally)subViewName
inquery.params
in order to tag the record with those fields.
- BREAKING CHANGE routing definitions no longer support
getIndexRoute
andgetNestedRoutes
. Instead, async loading should happen at the component level- use
getComponent
instead ofcomponent
.
- use
- NEW FEATURE support for
query.list
param to aggregate list endpoint responses
- BREAKING CHANGE dropping support for React 15. Peer dependencies will require React 16.3 or higher.
- Upgrade meetup-web-component dependencies to latest (4.8.2111), and require meetup-web-component@^4.8.0 for peer dependencies.
- New feature
state.flags
containing all LaunchDarkly feature flags
- BREAKING CHANGE
publicPath
now set as a config var that is shared by server and browser build config -APP_RUNTIME.assetPublicPath
is no longer populated by server, and consumer apps no longer need to set a 'dynamic'__webpack_public_path__
value in either the server or browser entry point script asssetPublicPath
no longer needs to be passed toserver-render/makeRenderer
- Bugfix the Redux cache middleware will now key the cache with the logged-in member's ID in order to avoid incorrectly returning cached results corresponding to other members or logged-out responses.
- New feature
SEOHead
a component for rendering SEO content in the document head. Also adds related utils undersrc/util/seo
. WP-532
- Simplified
makeServerRenderer$
no longer requires abaseUrl
param - it will be determined from the request directly
- Refactor
mwp-i18n/lib/withIntl
now expects a map of{ [localeCode]: messages }
in itsmessages
arg.mwp-cli
has been updated to provide this TRN source structure automatically.
- Moved
mwp-core/lib/localizationUtils
is now part ofmwp-i18n
, renamed toloadLocaleData
- New package
mwp-i18n
, which currently contains thewithIntl
HOC andloadLocaleData
- New package
mwp-config
- a dedicated 'config' package that can be freely imported to other MWP packages and consumers.
- Removed
api.requestAll
action creator is now a private function. Consumers must use the method-specific API request action creators, which now accept arrays of queries in addition to single query - Removed The
meta.promise
property of API actions has been removed - use themeta.request
Promise instead, which will return an array of responses. E.g. instead ofapi.post(...).meta.promise.then(response => ...)
, useapi.post(...).meta.request.then(([response]) => ...)
- Removed
api.requestAll
is no longer exported - use the method-specific action creators with the following enhancement: - New feature
api.get/post/patch/del
can now be called with an array of queries in order to make a batched API request
- Removed Oauth authentication for no-cookie requests. This means we no
longer need
MUPWEB_OAUTH_TOKEN
andMUPWEB_OAUTH_SECRET
env vars. Consumer applications should not need to change any of their code, but deployments can be cleaned up
mwp-api-state
refactored to remove redux-observable + rxjs dependencies - those are no longer peerDependencies.redux-observable
is not currently used by any other MWP package and can be removed from consumer apps
- Removed polyfill for
Intl.NumberFormat
andIntl.DateTimeFormat
- consumers should instead use thefull-icu
package and follow its instructions to ensure that Node will load all required locale data when it starts.
- Support for reading
MEETUP_VARIANT_...
cookies intostate.config.variants
- Removed Queries specifying REST API endpoints that do not support
logged-out members will no longer produce responses. Specifically,
members/self
will not be called, meaning thatstate.api.self
can not be assumed to have a value throughout the application - a selector function should be used to provide a reasonable default value in your components.
mwp-log
now contains nicely-formatted logs
- All 'internal' packages now published independently:
mwp-api-proxy-plugin
mwp-api-state
mwp-app-render
mwp-app-route-plugin
mwp-app-server
mwp-auth-plugin
mwp-core
mwp-language-plugin
mwp-router
mwp-store
mwp-sw-plugin
mwp-tracking-plugin
mwp-test-utils
-
Feature: Pass in an array of string
cssLinks
tomakeServerRenderer$
in order to add static CSS<link>
tags to the document<head>
. These tags will not be affected by<link>
s defined within<Helmet>
tags of the application, and therefore will not be subject to being clobbered by client-side rendering that will cause a FOUC (as described in this react-helmet issue).Important: The consumer application must ensure that the CSS files are bundled with the browser application script as well, even though the links themselves are not required by the browser app renderer.
- Moved
src/server
is nowsrc/app-server
-
Moved
src/components/Redirect
-->require('src/router').Redirect
-
Moved
src/components/Forbidden
-->require('src/router').Forbidden
-
Moved
src/actions/apiActionCreators
: The actiontype
constants and action creators are exported fromrequire('src/api-state')
:API_REQ
-API_RESP_SUCCESS
-API_RESP_COMPLETE
-API_RESP_ERROR
-API_RESP_FAIL
-requestAll
-get
-post
-patch
-del
-
Moved
src/actions/syncActionCreators
: The actiontype
constants and location change action creators are exported fromrequire('src/router')
. DeprecatedapiError
,apiSuccess
,apiRequest
action creators can be imported directly fromsrc/api-state/sync/syncActionCreators
, but should be marked as 'deprecated' and converted to theapi-state
action creators above.SERVER_RENDER
LOCATION_CHANGE
locationChange
-
Moved + renamed
src/middleware/platform:getEpicMiddleware
has moved torequire('src/api-state').getApiMiddleware
-
Moved + renamed Parts of
src/reducers/platform
have moved tosrc/store/reducer
.makeRootReducer
is now the default export of the module. Theapi
andapp
(deprecated) reducers are now insrc/api-state
, along withDEFAULT_API_STATE
. -
Moved some
src/components
moved tosrc/render/components
:PlatformApp
- should not be used - chooseBrowserApp
orServerApp
PageWrap
BrowserApp
ServerApp
-
Moved
state.config.localeCode
is nowstate.config.requestLanguage
to better describe where the locale code comes from - make sure you update to the latest meetup-web-mocks in order to get a validMOCK_APP_STATE
- Change (could be considered breaking, but it's specifically for a
requested update to GroupCard in mup-web):
group.duotoneUrl
is now an object withsmall
andlarge
properties -small
has a resolution of 300x400, andlarge
has a resolution of 1100x800.
- Fixed the
platform_agent
in tracking logs is now determined frompackage.json
, which should have aconfig.agent
string ofMUP_WEB
orPRO_WEB
.
- Removed Support for
?logout
query parameter, and platform-based Login/Logout components. Platform consumers should use the<Redirect>
component to redirect login and logout requests to Meetup classic until login and logout can be handled fully by the platform in a future update.
- New feature API request actions now contain a reference to a Promise that will resolve when the API request returns. WP-334
- New feature Supply
initialNow
tostate.config
to sync server and browser time reference. - New feature 301/302 Redirects now supported for internal and external routes. WP-331
- New feature Query creator functions assigned to routes will now receive
all React Router
match
properties in their argument. WP-352
- Deprecated
~/.mupweb.config
has been deprecated - node convict now manages environment configurations inutil/src/config.js
. To override any of the default values in development, create aconfig.development.json
file with the name of the configuration and new value. This file is automatically gitignored. Seeconfig.test.json
for an example configuration.
- New feature Google App Engine PubSub tracking logs. To enable, consumer
apps must ensure that the
GAE_INSTANCE
environment variable is set in the app container - GAE provides it automatically to the GAE runtime. Docs: https://cloud.google.com/appengine/docs/flexible/nodejs/runtime#environment_variables
- Refactor default locale is determined by first locale in list, as specified in consuming repo's /src/util/locales.js
- New feature support for asyncronous routes (PR #266).
Docs. Note the new
resolveAppProps
helper that allows the browser script to delay rendering until async routes are resolved - rendering docs here.
-
Deprecated
renderers/browser-render.jsx
has been deprecated - consumer applications should use vanilla React render methods to render a<BrowserApp />
, which is the new entry point for a platform-based applications, atsrc/components/BrowserApp.jsx
. The browser entry point should contain the following code:import ReactDOM from 'react-dom'; import { getInitialState, getBrowserCreateStore } from '../util/createStoreBrowser'; const routes = ...; const reducer = ...; const middleware = ... || []; const basename = ... || ''; const createStore = getBrowserCreateStore(routes, middleware, basename); const store = createStore(reducer, getInitialState(window.APP_RUNTIME)); ReactDOM.render( <BrowserApp routes={routes} store={store} basename={basename} />, document.getElementById('outlet') // this is a hard-coded id );
- Replaced
state.api.isFetching
has been replaced withstate.api.inFlight
, which is an array ofref
s corresponding to query requests that have not yet returned. Usestate.api.inFlight.includes(fooRef)
to determine whether a particular query has returned.
-
Deprecated all of the Sync action creators (e.g.
syncActionCreators.apiRequest
) have been deprecated. You should instead use the newapiActionCreators
to manually trigger API requests - see the Queries docs for more info. The Sync action creators will be removed in version 3.There are four things that consumer apps need to update:
-
syncActionCreators.apiRequest
query dispatches must be converted toapiActionCreators.requestAll
(or the method-specific equivalents described in the Queries docs). -
All reads from
state.app
should be converted tostate.api
- the child properties will be the sameref
s used instate.app
, except forstate.app.error
which is nowstate.api.fail
. -
Any reducers listening for
API_SUCCESS
(which has apayload
containing an object with aqueries
array and correspondingresponses
array) must be refactored to listen forAPI_RESP_SUCCESS
andAPI_RESP_ERROR
actions, which will each contain a{ query, response }
object corresponding to a single query and its response.The shape of each
response
object has also changed - instead of a single root-level key corresponding to the original query'sref
, the response is now a flat object with aref
property.Instead of parsing the
API_SUCCESS
payload for errors, reducers will now be able to specifically identify responses that correspond to failed/invalid responses from the REST API by listening forAPI_RESP_ERROR
-API_RESP_SUCCESS
will always correspond to a valid REST API response. -
Any reducers listening for
API_ERROR
must be refactored to listen forAPI_RESP_FAIL
. Both actions have the sameError
object payload corresponding to a general API request failure, unrelated to a specific query.
These changes must by made simultaneously, and this list assumes that the refactor described in the
v2.1
changelog has been completed first. -
- Deprecated POSTing and DELETEing through custom
POST_...
orDELETE_...
actions has been deprecated - a warning will be printed in the server logs. Use themeta.method
field in your Query objects to determine the request method, and usecomponentWillReceiveProps
to process the API result as described in the docs
-
Refactor Upgrade to React Router v4. Routes definitions change - the root level routes definition is now an array, and each route must have the following shape:
{ path: string, // must have leading '/', except for the root '' path component: React.Component, query?: function, routes?: array, // child routes, with `path` props that append to the parent exact?: boolean, // forces the component to only render when url is exact match }
Note that async routes are no longer supported - they will return in a new form in a future update
- Require Node v7 for require('url').URL
- Require window.URL polyfill for browsers without native support
- Removed
apiConfigCreators
no longer exists - use the query object directly to define theendpoint
- New env variable -
COOKIE_ENCRYPT_SECRET
must be in your env vars. It must be a 32+ character random string. - Refactored - auth cookies are now encrypted, so existing cookies must be cleared in the browser.
- Removed - Many of the shared methods in
src/util/testUtils
now are in themeetup-web-mocks
repo - Change - Use the
meetup-web-mocks
repo for testUtil methods, e.g.,
import { createFakeStore } from 'meetup-web-mocks/lib/testUtils';
- Change -
API_SUCCESS
now returns ameta
prop that contains thecsrf
token returned by the server that will be used to validate all POSTs. Your Redux reducer must include aconfig
reducer that will assignconfig.csrf
onAPI_SUCCESS
, e.g.
function config(state = {}, action) {
let csrf;
switch (action.type) {
case 'API_SUCCESS':
csrf = action.meta.csrf;
return { ...state, csrf };
//...
}
}
- Removed/Refactor - there are no more
LOGOUT_X
actions. Logout is instead a navigation action to any URL with?logout
in the URL.
- Removed -
CONFIGURE_AUTH
action will no longer contain a key namedanonymous
. The app can determine whether the current user is logged in from theapp.self
value, which should be a memeber object with astatus
indicating whether the user is logged in. - Deprecated - the
ANONYMOUS_ACCESS_URL
andANONYMOUS_AUTH_URL
env variable names have been changed toOAUTH_ACCESS_URL
andOAUTH_AUTH_URL
, respectively. The only names will still be read, but will be removed entirely in a future version.
- Refactor - all modules are now transpiled to CommonJS ES5 modules in
lib/
, so your import paths should change:
// v0.4
import <module> from 'meetup-web-platform/<moduleName>';
// v0.5
import <module> from 'meetup-web-platform/lib/<moduleName>';
If you want to use the ES6 source files directly, import them with
'meetup-web-platform/src/<moduleName>';
- Renamed -
getEpicMiddleware
is nowgetPlatformMiddleware
since all platform middleware functionality is provided as a single redux-observable epic-based middleware combining multiple epics - Removed
PostMiddleware
- the equivalent functionality is now provided as an epic inPostEpic
, which is part ofgetPlatformMiddleware
- Added
getEpicMiddleware
- Removed/Added
SyncMiddleware
,CacheMiddleware
,AuthMiddleware
are now part ofEpicMiddleware
-getEpicMiddleware(routes)
will add functionality equivalent to the previous middleware. If you are usingcreateStore
from the platform library, you can ignore this update, as the middleware loading is done for you.
-
Refactor
server-render:makeRenderer
now takesclientFilename
andassetPublicPath
as separate argumentsclientFilename
is typically provided by the webpack build stats of the client build process.assetPublicPath
is usually constructed from env vars in your server entry point. -
In order to correctly apply the
assetPublicPath
to your server and client builds, you must set__webpack_public_path__
before importing your application code, e.g.```js // your client entry point __webpack_public_path__ = window.APP_RUNTIME.assetPublicPath; const routes = require('./routes').default; const reducer = require('./features/shared/reducer').default; const render = makeRenderer(routes, reducer); // your server entry point const clientFilename = WEBPACK_CLIENT_FILENAME; const assetPublicPath = ${process.env.ASSET_SERVER_HOST}:${process.env.ASSET_SERVER_PORT}/`; __webpack_public_path__ = assetPublicPath; // eslint-disable-line no-undef const routes = require('./routes').default; const reducer = require('./features/shared/reducer').default; const renderRequest$ = makeRenderer(routes, reducer, clientFilename, assetPublicPath); ```