Upgrade Guide: 0.3 to 4.0
Changes to express application and mounting
WIP
The mounting process has been rewritten for modularity and clarity. This
may introduce some breaking changes if your app has been attaching the
Keystone Admin UI to a nonstandard express app (i.e. not using
Keystone.start()
, but should make things simpler going forward.
Changed
keystone.get('express session')
has been replaced bykeystone.expressSession
- Session initialisation middleware is now executed before the body parser to allow for the Admin UI to include its own bodyParser implementation
- IP Restrictions middleware is now processed first, which means that static assets will now respect restrictions (previously this only restricted routes)
keystone.routes(fn)
has been replaced bykeystone.set('routes', fn)
-
the
routes
option supports both:- the legacy
function (app) {}
way of adding routes to the root express app - an
express.Router
instance
- the legacy
Removed
keystone.static
has been removed (replacement TBA, seeadmin/server
)keystone.mount
has been removed (replaced by more granular methods, seeadmin/server
)keystone.bindEmailTestRoutes
andkeystone.set('email tests')
support (was this actually being used by anyone? let me know - @jedwatson)keystone.set('email rules')
option has been removed; you should just use variables in your templates, rather than globally applied regular expressions.- The
Types.CloudinaryImage
optionpublicID: 'slug'
option has been removed. It has been replaced by the generateFilename function. Documentation for the new option can be found infields/types/cloudinaryimage
UpdateHandler Changes
The UpdateHandler functionality has been completely rewritten to use the
new, generic List.updateItem
method. While we have tried to preserve
backwards compatibility, there may be minor differences in functionality
and the format of messages returned.
The structure of error detail passed to the callback has changed, and now matches the new API error format (see the API Spec)
If you are using the UpdateHandler please test your application comprehensively when upgrading to 0.4 and report any problems you find in the issues.
Specific changes include:
- The
callback
function now receives a single error argument options.validationMethods
is no longer supported, please apply any custom validation before callingupdateHandler.process()
options.errorMessages
is no longer supported, as fields may now return different error conditions and replacing specific error detail with a simple string has the potential to be misleading and frustrating for users. If you want to show custom messages, please handle this on a case-by-case basis in your application.
The flashErrors
option now supports the following values:
true
send all error messages toreq.flash
"validation"
only send validation error messages toreq.flash
"update"
only send update errors toreq.flash
File handling Field Types
File
field type
New The new File
field type, with the FS
, S3
and Azure
storage
adapters, replace the following field types (which are removed in 0.4) -
azureFile
localFile
localFiles
s3File
For usage instructions, see:
For the full upgrade guide for File fields, see File-Fields-Upgrade-Guide in the KeystoneJS Wiki.
CloudinaryImage
The _upload
suffix is no longer required or supported when uploading
files from an html form. Now simply provide the cloudinary field path as
the name of file upload fields. For example:
<!-- old -->
<input type="file" name="picture_upload" />
<!-- new -->
<input type="file" name="picture" />
CloudinaryImages
When the cloudinary folders
keystone option is set, in 0.3.x
CloudinaryImages
fields would incorrectly use the cloudinary prefix
option’s value as the first part of the folder path for fields that did
not specify the folder
option. This has been fixed; the folder for
uploaded images now defaults to this.list.path + '/' + this.path
Explicit support for actions with paths.action
(i.e. submitting a
fieldPath_action
value) has been removed. To remove images from the
value, submit the new value for the field without the removed image
present.
The CloudinaryImages field no longer supports deleting removed images from Cloudinary, this may be restored in a subsequent version.
Reordering images with paths.order
(i.e. submitting a
fieldPath_order
value) has also been removed. To sort images, submit
the full array of values in the correct order.
Field API Changes
-
updateItem is now asynchronous and need to pass a callback:
- Before:
field.updateItem(item, data)
- After:
field.updateItem(item, data, function(err) {...})
- Before:
Location fields
The geocodeGoogle
option has been renamed to enableImprove
.
Mongoose 4
The bundled version of Mongoose has been updated from 3.x to 4.x. Please review the Migration Guide and Release Notes for more information.
Keystone.Email
Keystone.Email
was completely rewritten as the standalone, well-tested
keystone-email
module, and requires it to be installed to work.
Changed
new Email
now accepts a second argument as the options (e.g. to set the transport)
new Email('templatepath.ext', { transport: 'mailgun' });
- The template locals are now passed in as the first, the options for
send as the second and the callback as the third argument to
.send
new Email('templatepath.ext', { transport: 'mailgun' })
.send(templateLocals, sendOptions, callback);
Removed
These options, APIs or behaviours were removed with the rewrite to an external module.
- We no longer assume
email.jade
as the default filename, you now have to pass an entire filename to or set theengine
in the.Email
call
Deprecated
All of these deprecations will continue to work throughout v4.x
,
though warnings will be added in a future minor release. We highly
encourage moving to the new APIs as soon as possible, your apps will
break in v5 otherwise!
keystone.set('email')
has been deprecated in favor of theroot
option (passed to the.Email
call)- The
templateExt
option was deprecated in favor of theengine
option keystone.set('transport')
has been deprecated in favor of settingtransport
in thenew Email()
optionskeystone.set('mailgun api key')
andkeystone.set('mailgun domain')
have been deprecated in favor of passing theapiKey
anddomain
option to the send options in.send
CSV Download
Keystone 0.3 had a feature where you could specify a custom toCSV
method on a list schema to control which values were included in the
CSV.
As the CSV Export has been completely rewritten and now supports the
same filter and fields options that the List view in the Admin UI does
(including being able to specify which fields are included in the CSV
from the Admin UI), the toCSV
method has been replaced by a new
getCSVData
method:
User.schema.methods.getCSVData = function (data, options) {
return {
password: undefined,
custom: { complex: true },
};
};
Values returned by this method will be added to the CSV regardless of
the fields specified to be included. You have access to the fields in
options.fields
. Additionally, you can set values to undefined
to
remove them from the csv if they were included.
The current User, if there is one, is provided in options.user
.
New Features
toCSV method on Fields
You can now also specify a per-field toCSV
transform. Provide a
function to return a custom value for the field if it is specified in
options.fields
:
User.add({
email: { type: Types.Email, toCSV: function (field, options) {
return this.id === options.user.id ? 'Your email address' : this.email;
}}
})
The this
scope will be the document being serialised to CSV format.
The field
argument is the field definition, and the options
argument
contains the options passed to getCSVData
(see above).
For field types that store an object, you can instead provide a list or array of keys to include in the CSV data:
User.add({
address: { type: Types.Location, toCSV: 'suburb, postcode' }
})
Automatic flattening of complex values
Objects will be flattened to multiple columns, with each key being appended to the field path using camelCase.
So, for example, the following data from a File
field with the path
attachment
:
{
id: '56dd3f1a51cb31100cf08457',
attachment: {
filename: 'photo.jpg',
size: 83452
}
}
Will be added to the CSV in two columns:
id,attachmentFilename,attachmentFilesize
56dd3f1a51cb31100cf08457,photo.jpg,83452
Removed Options
The csv expanded
keystone option has been deprecated. Relationship
fields will always be expanded into fieldName
, fieldId
columns by
default.
Changed Dependencies
Breaking Fixes
Relationship Field Updates
Relationship fields had a bug in 0.3.x and 4.0.0 betas pre-beta.6 where undefined
values passed to List.updateItem
would be persisted to the database for { many: true }
fields.
This has been fixed, so that incoming undefined
values are ignored, which is consistent with all other field types except Boolean
.
Jade
Keystone 3 included jade
as a dependency; this meant your project may
have been able to use jade as the view engine without depending on it
explicitly. Jade has now been removed from Keystone, so if you’re using
it you will need to explicitly add it to your package.json
.
Underscore
Keystone 3 included underscore
as a dependency; this was utilised by
the generator, which should have added an explicit dependency when
generating package.json
files. Unfortunately it didn’t, which means
your project may expect underscore to be available and it won’t be.
If you get the following error when starting a project with keystone 4:
Error: Cannot find module 'underscore'
Run the following command in your project’s root folder to resolve it:
npm install --save underscore