wcc-contentful 0.0.3 → 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/.circleci/config.yml +51 -0
- data/.gitignore +8 -0
- data/.rspec +1 -0
- data/.rubocop.yml +240 -0
- data/.rubocop_todo.yml +13 -0
- data/CHANGELOG.md +7 -1
- data/Gemfile +4 -2
- data/Guardfile +36 -0
- data/README.md +1 -1
- data/Rakefile +5 -3
- data/bin/rspec +3 -0
- data/lib/generators/wcc/USAGE +24 -0
- data/lib/generators/wcc/menu_generator.rb +67 -0
- data/lib/generators/wcc/templates/.keep +0 -0
- data/lib/generators/wcc/templates/Procfile +3 -0
- data/lib/generators/wcc/templates/contentful_shell_wrapper +342 -0
- data/lib/generators/wcc/templates/menu/generated_add_menus.ts +85 -0
- data/lib/generators/wcc/templates/menu/menu.rb +25 -0
- data/lib/generators/wcc/templates/menu/menu_button.rb +25 -0
- data/lib/generators/wcc/templates/release +9 -0
- data/lib/generators/wcc/templates/wcc_contentful.rb +18 -0
- data/lib/wcc/contentful.rb +93 -26
- data/lib/wcc/contentful/client_ext.rb +15 -0
- data/lib/wcc/contentful/configuration.rb +93 -0
- data/lib/wcc/contentful/content_type_indexer.rb +153 -0
- data/lib/wcc/contentful/exceptions.rb +34 -0
- data/lib/wcc/contentful/graphql.rb +15 -0
- data/lib/wcc/contentful/graphql/builder.rb +172 -0
- data/lib/wcc/contentful/graphql/types.rb +54 -0
- data/lib/wcc/contentful/helpers.rb +28 -0
- data/lib/wcc/contentful/indexed_representation.rb +111 -0
- data/lib/wcc/contentful/model.rb +24 -0
- data/lib/wcc/contentful/model/menu.rb +7 -0
- data/lib/wcc/contentful/model/menu_button.rb +15 -0
- data/lib/wcc/contentful/model_builder.rb +151 -0
- data/lib/wcc/contentful/model_validators.rb +64 -0
- data/lib/wcc/contentful/model_validators/dsl.rb +165 -0
- data/lib/wcc/contentful/simple_client.rb +127 -0
- data/lib/wcc/contentful/simple_client/response.rb +160 -0
- data/lib/wcc/contentful/store.rb +8 -0
- data/lib/wcc/contentful/store/cdn_adapter.rb +79 -0
- data/lib/wcc/contentful/store/memory_store.rb +75 -0
- data/lib/wcc/contentful/store/postgres_store.rb +132 -0
- data/lib/wcc/contentful/version.rb +3 -1
- data/wcc-contentful.gemspec +49 -24
- metadata +261 -16
- data/lib/wcc/contentful/redirect.rb +0 -33
@@ -0,0 +1,67 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Wcc
|
4
|
+
class MenuGenerator < Rails::Generators::Base
|
5
|
+
source_root File.expand_path('templates', __dir__)
|
6
|
+
|
7
|
+
def create_menus_migration
|
8
|
+
now = Time.now.strftime('%Y%m%d%H%M')
|
9
|
+
copy_file 'menu/generated_add_menus.ts',
|
10
|
+
"db/migrate/#{now}01_generated_add_menus.ts"
|
11
|
+
end
|
12
|
+
|
13
|
+
def ensure_migration_tools_installed
|
14
|
+
in_root do
|
15
|
+
run 'npm init -y' unless File.exist?('package.json')
|
16
|
+
package = JSON.parse(File.read('package.json'))
|
17
|
+
deps = package['dependencies']
|
18
|
+
|
19
|
+
unless deps.try(:[], 'contentful-migration-cli').present?
|
20
|
+
run 'npm install --save watermarkchurch/migration-cli'
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
def ensure_wrapper_script_in_bin_dir
|
26
|
+
unless inside('bin') { File.exist?('contentful') }
|
27
|
+
copy_file 'contentful_shell_wrapper', 'bin/contentful'
|
28
|
+
end
|
29
|
+
|
30
|
+
if inside('bin') { File.exist?('release') }
|
31
|
+
release = inside('bin') { File.read('release') }
|
32
|
+
unless release.include?('contentful migrate')
|
33
|
+
insert_into_file('bin/release', after: 'bundle exec rake db:migrate') do
|
34
|
+
<<~HEREDOC
|
35
|
+
DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
|
36
|
+
$DIR/contentful migrate -y
|
37
|
+
HEREDOC
|
38
|
+
end
|
39
|
+
end
|
40
|
+
else
|
41
|
+
copy_file 'release', 'bin/release'
|
42
|
+
end
|
43
|
+
|
44
|
+
if in_root { File.exist?('Procfile') }
|
45
|
+
procfile = in_root { File.read('Procfile') }
|
46
|
+
unless procfile.include?('release:')
|
47
|
+
insert_into_file('Procfile') do
|
48
|
+
'release: bin/release'
|
49
|
+
end
|
50
|
+
end
|
51
|
+
else
|
52
|
+
copy_file 'Procfile'
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
def ensure_initializer_exists
|
57
|
+
return if inside('config/initializers') { File.exist?('wcc_contentful.rb') }
|
58
|
+
|
59
|
+
copy_file 'wcc_contentful.rb', 'config/initializers/wcc_contentful.rb'
|
60
|
+
end
|
61
|
+
|
62
|
+
def drop_model_overrides_in_lib_dir
|
63
|
+
copy_file 'menu/menu.rb', 'lib/wcc/contentful/model/menu.rb'
|
64
|
+
copy_file 'menu/menu_button.rb', 'lib/wcc/contentful/model/menu_button.rb'
|
65
|
+
end
|
66
|
+
end
|
67
|
+
end
|
File without changes
|
@@ -0,0 +1,342 @@
|
|
1
|
+
#!/bin/bash
|
2
|
+
|
3
|
+
COLOR_NC='\033[0m' # No Color
|
4
|
+
COLOR_GRAY='\033[1;30m'
|
5
|
+
COLOR_RED='\033[0;31m'
|
6
|
+
COLOR_LCYAN='\033[1;36m'
|
7
|
+
COLOR_YELLOW='\033[1;33m'
|
8
|
+
COLOR_LGREEN='\033[1;32m'
|
9
|
+
|
10
|
+
logv() {
|
11
|
+
([[ ! -z "$VERBOSE" ]] && >&2 echo -e "${COLOR_GRAY}$@${COLOR_NC}") || true
|
12
|
+
}
|
13
|
+
|
14
|
+
logerr() {
|
15
|
+
>&2 echo -e "${COLOR_RED}$@${COLOR_NC}"
|
16
|
+
}
|
17
|
+
|
18
|
+
## *** Argument Parsing & validation ***
|
19
|
+
|
20
|
+
usage() {
|
21
|
+
echo "$0 <command> [opts]
|
22
|
+
Commands:
|
23
|
+
migrate [dir|file]
|
24
|
+
runs pending migration files in the given directory
|
25
|
+
* [dir|file] optional - Default: db/migrate
|
26
|
+
|
27
|
+
setup [file]
|
28
|
+
initializes a space with bare-minimum schema and seeds
|
29
|
+
* [file] optional - default: db/contentful-schema.json
|
30
|
+
|
31
|
+
backup [file]
|
32
|
+
downloads a backup of the current space to the given file
|
33
|
+
* [file] optional - default: timestamped file in current directory
|
34
|
+
|
35
|
+
clean [no-init]
|
36
|
+
Deletes all data in a given space and optionally sets it up again
|
37
|
+
using 'bin/contentful setup'.
|
38
|
+
* [no-init] optional - Skips the 'setup' step at the end.
|
39
|
+
|
40
|
+
restore [file]
|
41
|
+
restores a given backup file into the current space
|
42
|
+
* [file] optional - default: the most recent backup file in the current directory
|
43
|
+
|
44
|
+
restore_from -s [to space ID] <from space ID>
|
45
|
+
restores all data from the given space into the current space
|
46
|
+
* <space ID> required - the ID of the space to receive data from
|
47
|
+
* -s [to space ID] optional - the current working space. Default: \$CONTENTFUL_SPACE_ID
|
48
|
+
|
49
|
+
generate [name]
|
50
|
+
Creates a sample migration in the db/migrate directory
|
51
|
+
* [name] optional - default: 'contentful_migration'
|
52
|
+
|
53
|
+
Flags:" && \
|
54
|
+
grep " .)\ #" $0
|
55
|
+
echo "
|
56
|
+
Examples:" && \
|
57
|
+
grep -i "#\ example:" $0 | awk '{$1=""; $2=""; print " "$0}'
|
58
|
+
}
|
59
|
+
|
60
|
+
parse_args() {
|
61
|
+
OPTIND=1
|
62
|
+
local s=$(echo "$1" | tr '[:upper:]' '[:lower:]')
|
63
|
+
case "$s" in
|
64
|
+
migrate|setup|backup|export|restore|restore_from|import|generate|clean|help|h|\?)
|
65
|
+
export subcommand=$s
|
66
|
+
OPTIND=2
|
67
|
+
;;
|
68
|
+
esac
|
69
|
+
|
70
|
+
# Parse flags
|
71
|
+
while getopts ":hyvs:a:" arg; do
|
72
|
+
case $arg in
|
73
|
+
y) # Yes - skip prompts
|
74
|
+
export YES="-y"
|
75
|
+
;;
|
76
|
+
s) # Contentful Space ID - overrides env var CONTENTFUL_SPACE_ID
|
77
|
+
export CONTENTFUL_SPACE_ID=$OPTARG
|
78
|
+
;;
|
79
|
+
a) # Contentful Mgmt Token - overrides env var CONTENTFUL_MANAGEMENT_TOKEN
|
80
|
+
export CONTENTFUL_MANAGEMENT_TOKEN=$OPTARG
|
81
|
+
;;
|
82
|
+
v) # Verbose mode - extra output
|
83
|
+
export VERBOSE=true
|
84
|
+
;;
|
85
|
+
h) # Display help.
|
86
|
+
usage
|
87
|
+
exit 0
|
88
|
+
;;
|
89
|
+
*)
|
90
|
+
logerr "Unknown option: '$OPTARG'"
|
91
|
+
usage
|
92
|
+
exit -1
|
93
|
+
;;
|
94
|
+
esac
|
95
|
+
done
|
96
|
+
|
97
|
+
export OPTIND
|
98
|
+
}
|
99
|
+
|
100
|
+
parse_args $@ && shift $(($OPTIND - 1))
|
101
|
+
# If they put args before the command like 'bin/contentful -s 1xab migrate -y', try parsing again
|
102
|
+
[[ -z "$subcommand" ]] && parse_args $@ && shift $(($OPTIND - 1))
|
103
|
+
|
104
|
+
require_environment() {
|
105
|
+
[[ -z "$CONTENTFUL_SPACE_ID" ]] && logerr "Please set CONTENTFUL_SPACE_ID environment variable or use '-s' flag." && exit -1;
|
106
|
+
[[ -z "$CONTENTFUL_MANAGEMENT_TOKEN" ]] && logerr "Please set CONTENTFUL_MANAGEMENT_TOKEN environment variable or use '-a' flag." && exit -1;
|
107
|
+
if [[ ! -f node_modules/.bin/contentful-migration ]]; then
|
108
|
+
command -v npm >/dev/null 2>&1 || (logerr "I require 'npm' but it's not installed. Please install nodejs."; exit -1)
|
109
|
+
logv "npm install"
|
110
|
+
npm install
|
111
|
+
[[ -f node_modules/.bin/contentful-migration ]] || (logerr "Failed installing node modules - please ensure contentful CLI is installed"; exit -1)
|
112
|
+
fi
|
113
|
+
}
|
114
|
+
|
115
|
+
## *** Utility functions ***
|
116
|
+
|
117
|
+
confirm() {
|
118
|
+
[[ -z "$2" ]] && [[ ! -z "$YES" ]] && logv "$1 (y/n): confirmed by -y flag" && return 0;
|
119
|
+
|
120
|
+
while true; do
|
121
|
+
if [[ -z "$2" ]]; then
|
122
|
+
read -p $'\033[1;36m'"$1"' (y/n): '$'\033[0m' yn
|
123
|
+
else
|
124
|
+
# double confirm - extra dangerous.
|
125
|
+
read -p $'\033[0;31m'"$1"' (y/n): '$'\033[0m' yn
|
126
|
+
fi
|
127
|
+
case $yn in
|
128
|
+
[Yy]* ) return 0;;
|
129
|
+
[Nn]* ) return 1;;
|
130
|
+
* ) echo "Please answer yes or no.";;
|
131
|
+
esac
|
132
|
+
done
|
133
|
+
}
|
134
|
+
|
135
|
+
get_space_name() {
|
136
|
+
logv "curl -s https://api.contentful.com/spaces/$1?access_token=****"
|
137
|
+
curl -s https://api.contentful.com/spaces/$1?access_token=$CONTENTFUL_MANAGEMENT_TOKEN | jq -r .name | tr '[:upper:]' '[:lower:]'
|
138
|
+
}
|
139
|
+
|
140
|
+
set -e
|
141
|
+
|
142
|
+
# *** Commands ***
|
143
|
+
|
144
|
+
# Example: bin/contentful migrate -y -s 1xab -a $MY_TOKEN db/migrate/20180101120000_add_content_type_dog.ts
|
145
|
+
# equivalent to: bin/rake db:migrate
|
146
|
+
migrate() {
|
147
|
+
ARG="$1"
|
148
|
+
[[ -z "$ARG" ]] && ARG="db/migrate"
|
149
|
+
[[ -d "$ARG" ]] && ARG="batch $ARG"
|
150
|
+
|
151
|
+
require_environment
|
152
|
+
|
153
|
+
logv "contentful-migration -s $CONTENTFUL_SPACE_ID -a ***** $YES -p $ARG"
|
154
|
+
node_modules/.bin/ts-node node_modules/.bin/contentful-migration \
|
155
|
+
-s $CONTENTFUL_SPACE_ID -a $CONTENTFUL_MANAGEMENT_TOKEN \
|
156
|
+
$YES -p $ARG
|
157
|
+
|
158
|
+
mkdir -p db
|
159
|
+
logv "contentful-export -s --export-dir db --content-file contentful-schema.json --space-id $CONTENTFUL_SPACE_ID --management-token ***** --query-entries 'content_type=migrationHistory' --query-assets 'sys.id=false'"
|
160
|
+
node_modules/.bin/contentful-export --export-dir db --content-file contentful-schema.json \
|
161
|
+
--space-id $CONTENTFUL_SPACE_ID --management-token $CONTENTFUL_MANAGEMENT_TOKEN \
|
162
|
+
--query-entries 'content_type=migrationHistory' \
|
163
|
+
--query-assets 'sys.id=false'
|
164
|
+
|
165
|
+
if [[ $(git diff-index --name-only HEAD | grep 'db/contentful-schema.json') == "" ]]; then
|
166
|
+
echo -e "${COLOR_LGREEN}✓ Schema in contentful space is equivalent to stored schema${COLOR_NC}"
|
167
|
+
else
|
168
|
+
echo -e "${COLOR_YELLOW}⚠️ Schema changed after running migrations${COLOR_NC}"
|
169
|
+
fi
|
170
|
+
}
|
171
|
+
|
172
|
+
# Example: bin/contentful backup -s 1xab -a $MY_TOKEN 2018_01_01.1xab.dump.json
|
173
|
+
# equivalent to: bin/rake db:dump[2018_01_01.dump]
|
174
|
+
backup() {
|
175
|
+
FILE="$1"
|
176
|
+
[[ ! -z "$FILE" ]] && FILE="--content-file $FILE" && shift
|
177
|
+
|
178
|
+
require_environment
|
179
|
+
|
180
|
+
logv "contentful-export $FILE --space-id $CONTENTFUL_SPACE_ID --management-token ***** $@"
|
181
|
+
node_modules/.bin/contentful-export $FILE \
|
182
|
+
--space-id $CONTENTFUL_SPACE_ID --management-token $CONTENTFUL_MANAGEMENT_TOKEN \
|
183
|
+
$@
|
184
|
+
}
|
185
|
+
|
186
|
+
# Example: bin/contentful restore -y -s 1xab -a $MY_TOKEN 2018_01_01.1xab.dump.json
|
187
|
+
# equivalent to: bin/rake db:restore[2018_01_01.dump]
|
188
|
+
restore() {
|
189
|
+
FILE="$1"
|
190
|
+
if [[ -z "$FILE" ]]; then
|
191
|
+
FILE=$(ls contentful-export-$CONTENTFUL_SPACE_ID-* | sort -r | head -n 1)
|
192
|
+
[[ -z "$FILE" ]] && logerr "No file given on command line" && exit -1
|
193
|
+
fi
|
194
|
+
|
195
|
+
confirm "Import $FILE into $CONTENTFUL_SPACE_ID?" || exit -1
|
196
|
+
|
197
|
+
require_environment
|
198
|
+
|
199
|
+
logv "contentful-import --space-id $CONTENTFUL_SPACE_ID --management-token ***** --content-file $FILE"
|
200
|
+
node_modules/.bin/contentful-import \
|
201
|
+
--space-id $CONTENTFUL_SPACE_ID --management-token $CONTENTFUL_MANAGEMENT_TOKEN \
|
202
|
+
--content-file $FILE
|
203
|
+
}
|
204
|
+
|
205
|
+
# Example: bin/contentful setup -y -s 1xab -a $MY_TOKEN db/my-schema.json
|
206
|
+
# equivalent to: bin/rake db:setup
|
207
|
+
setup() {
|
208
|
+
FILE="$1"
|
209
|
+
[[ -z "$FILE" ]] && FILE=db/contentful-schema.json
|
210
|
+
|
211
|
+
confirm "Initialize space $CONTENTFUL_SPACE_ID from seed file $FILE?" || exit -1
|
212
|
+
|
213
|
+
require_environment
|
214
|
+
|
215
|
+
logv "contentful-import --space-id $CONTENTFUL_SPACE_ID --management-token ***** --content-file $FILE"
|
216
|
+
node_modules/.bin/contentful-import \
|
217
|
+
--space-id $CONTENTFUL_SPACE_ID --management-token $CONTENTFUL_MANAGEMENT_TOKEN \
|
218
|
+
--content-file $FILE
|
219
|
+
|
220
|
+
migrate
|
221
|
+
}
|
222
|
+
|
223
|
+
# Example: bin/contentful clean -s 1xab -a $MY_TOKEN
|
224
|
+
clean() {
|
225
|
+
command -v jq >/dev/null 2>&1 || (logerr "I require 'jq' but it's not installed. Please run 'brew install jq'"; exit -1)
|
226
|
+
|
227
|
+
require_environment
|
228
|
+
|
229
|
+
name=$(get_space_name $CONTENTFUL_SPACE_ID)
|
230
|
+
|
231
|
+
confirm "This will delete all data and content types from $name. Are you sure?" || exit -1
|
232
|
+
[[ "$name" != *staging ]] && [[ "$name" != *test ]] && confirm "$name is not a staging or test environment! Are you really sure?" dangerous!
|
233
|
+
|
234
|
+
local bkup_file="contentful-export-$CONTENTFUL_SPACE_ID-`date +"%Y-%m-%dT%H-%M-%S"`.json"
|
235
|
+
backup $bkup_file
|
236
|
+
content_types=$(cat $bkup_file | jq -r '.contentTypes[].sys.id')
|
237
|
+
entries=$(cat $bkup_file | jq -r '.entries[].sys.id')
|
238
|
+
assets=$(cat $bkup_file | jq -r '.assets[].sys.id')
|
239
|
+
|
240
|
+
delete() {
|
241
|
+
logv "curl -XDELETE https://api.contentful.com/spaces/$CONTENTFUL_SPACE_ID/$1/$2/published\?access_token\=*****"
|
242
|
+
curl -s --fail -XDELETE https://api.contentful.com/spaces/$CONTENTFUL_SPACE_ID/$1/$2/published\?access_token\=$CONTENTFUL_MANAGEMENT_TOKEN > /dev/null
|
243
|
+
logv "curl -XDELETE https://api.contentful.com/spaces/$CONTENTFUL_SPACE_ID/$1/$2\?access_token\=*****"
|
244
|
+
curl -s --fail -XDELETE https://api.contentful.com/spaces/$CONTENTFUL_SPACE_ID/$1/$2\?access_token\=$CONTENTFUL_MANAGEMENT_TOKEN > /dev/null
|
245
|
+
}
|
246
|
+
|
247
|
+
[[ ! -z "$assets" ]] && while read -r id; do delete 'assets' $id; done <<< "${assets}"
|
248
|
+
[[ ! -z "$entries" ]] && while read -r id; do delete 'entries' $id; done <<< "${entries}"
|
249
|
+
[[ ! -z "$content_types" ]] && while read -r id; do delete 'content_types' $id; done <<< "${content_types}"
|
250
|
+
|
251
|
+
echo -e "${COLOR_LGREEN}All content deleted - prior content saved at${COLOR_NC} $bkup_file"
|
252
|
+
[[ "$1" == "no-init" ]] || (setup || logerr "Error setting up space $name!")
|
253
|
+
}
|
254
|
+
|
255
|
+
# Example: bin/contentful restore_from -s $staging_space_id -a $MY_TOKEN $production_space_id
|
256
|
+
restore_from() {
|
257
|
+
command -v jq >/dev/null 2>&1 || (logerr "I require 'jq' but it's not installed. Please run 'brew install jq'"; exit -1)
|
258
|
+
|
259
|
+
require_environment
|
260
|
+
|
261
|
+
from_space_id=$1
|
262
|
+
[[ -z "$from_space_id" ]] && logerr "Please provide the space ID from which to restore data" && exit -1
|
263
|
+
to_space_id=$CONTENTFUL_SPACE_ID
|
264
|
+
|
265
|
+
from_name=$(get_space_name $from_space_id)
|
266
|
+
to_name=$(get_space_name $CONTENTFUL_SPACE_ID)
|
267
|
+
|
268
|
+
echo -e "${COLOR_LCYAN}This will backup all data from $from_name, delete all data in $to_name, and then write the $from_name data over it.${COLOR_NC}"
|
269
|
+
confirm "Continue?" || exit -1
|
270
|
+
export YES='-y' # don't keep bugging the user
|
271
|
+
|
272
|
+
export CONTENTFUL_SPACE_ID=$from_space_id
|
273
|
+
local bkup_file="contentful-export-$from_space_id-`date +"%Y-%m-%dT%H-%M-%S"`.json"
|
274
|
+
logv "bin/contentful backup -s $CONTENTFUL_SPACE_ID $bkup_file"
|
275
|
+
backup $bkup_file --skip-roles --skip-webhooks
|
276
|
+
|
277
|
+
export CONTENTFUL_SPACE_ID=$to_space_id
|
278
|
+
logv "bin/contentful clean -s $CONTENTFUL_SPACE_ID"
|
279
|
+
clean no-init
|
280
|
+
|
281
|
+
logv "bin/contentful restore -s $CONTENTFUL_SPACE_ID $bkup_file"
|
282
|
+
restore $bkup_file
|
283
|
+
}
|
284
|
+
|
285
|
+
# Example: bin/contentful generate add content type dog
|
286
|
+
# equivalent to: bin/rails generate migration add_content_type_dog
|
287
|
+
generate() {
|
288
|
+
migration="
|
289
|
+
import Migration from 'contentful-migration-cli'
|
290
|
+
|
291
|
+
export = function (migration: Migration) {
|
292
|
+
const dog = migration.createContentType('dog', {
|
293
|
+
name: 'Dog'
|
294
|
+
})
|
295
|
+
|
296
|
+
const name = dog.createField('name')
|
297
|
+
name.name('Name')
|
298
|
+
.type('Symbol')
|
299
|
+
.required(true)
|
300
|
+
}
|
301
|
+
"
|
302
|
+
|
303
|
+
timestamp=$(date +%Y%m%d%H%M%S)
|
304
|
+
filename="$@"
|
305
|
+
[[ -z "$filename" ]] && filename="contentful_migration"
|
306
|
+
filename=${filename// /\_}
|
307
|
+
filename="db/migrate/${timestamp}_${filename}.ts"
|
308
|
+
echo "$migration" > $filename
|
309
|
+
echo "generated file $filename"
|
310
|
+
}
|
311
|
+
|
312
|
+
case $subcommand in
|
313
|
+
migrate)
|
314
|
+
migrate $@
|
315
|
+
;;
|
316
|
+
backup|export)
|
317
|
+
backup $@
|
318
|
+
;;
|
319
|
+
restore|import)
|
320
|
+
restore $@
|
321
|
+
;;
|
322
|
+
setup)
|
323
|
+
setup $@
|
324
|
+
;;
|
325
|
+
generate)
|
326
|
+
generate $@
|
327
|
+
;;
|
328
|
+
clean)
|
329
|
+
clean $@
|
330
|
+
;;
|
331
|
+
restore_from)
|
332
|
+
restore_from $@
|
333
|
+
;;
|
334
|
+
help|h|\?)
|
335
|
+
usage
|
336
|
+
;;
|
337
|
+
*)
|
338
|
+
logerr "Unknown command: '$1'"
|
339
|
+
usage
|
340
|
+
exit -1
|
341
|
+
;;
|
342
|
+
esac
|
@@ -0,0 +1,85 @@
|
|
1
|
+
|
2
|
+
import Migration from 'contentful-migration-cli'
|
3
|
+
|
4
|
+
export = function (migration: Migration) {
|
5
|
+
const menu = migration.createContentType('menu')
|
6
|
+
.name('Menu')
|
7
|
+
.description('A Menu contains a number of Menu Buttons or other Menus, which ' +
|
8
|
+
'will be rendered as drop-downs.')
|
9
|
+
.displayField('name')
|
10
|
+
|
11
|
+
menu.createField('name')
|
12
|
+
.name('Menu Name')
|
13
|
+
.type('Symbol')
|
14
|
+
.required(true)
|
15
|
+
|
16
|
+
menu.createField('topButton')
|
17
|
+
.name('Top Button')
|
18
|
+
.type('Link')
|
19
|
+
.linkType('Entry')
|
20
|
+
.validations([
|
21
|
+
{
|
22
|
+
linkContentType: [ 'menuButton' ],
|
23
|
+
message: 'The Top Button must be a button linking to a URL or page. ' +
|
24
|
+
'If the menu is a dropdown, this button is visible when it is collapsed.'
|
25
|
+
}
|
26
|
+
])
|
27
|
+
|
28
|
+
menu.createField('items')
|
29
|
+
.name('Items')
|
30
|
+
.type('Array')
|
31
|
+
.items({
|
32
|
+
type: 'Link',
|
33
|
+
linkType: 'Entry',
|
34
|
+
validations: [
|
35
|
+
{
|
36
|
+
linkContentType: [ 'menu', 'menuButton' ],
|
37
|
+
message: 'The items must be either buttons or drop-down menus'
|
38
|
+
}
|
39
|
+
]
|
40
|
+
})
|
41
|
+
|
42
|
+
const menuButton = migration.createContentType('menuButton')
|
43
|
+
.name('Menu Button')
|
44
|
+
.description('A Menu Button is a clickable button that goes on a Menu. ' +
|
45
|
+
'It has a link to a Page or a URL.')
|
46
|
+
.displayField('text')
|
47
|
+
|
48
|
+
menuButton.createField('text')
|
49
|
+
.name('Text')
|
50
|
+
.type('Symbol')
|
51
|
+
.required(true)
|
52
|
+
.validations([
|
53
|
+
{
|
54
|
+
size: { min: 1, max: 60 },
|
55
|
+
message: 'A Menu Button should have a very short text field - ideally a ' +
|
56
|
+
'single word. Please limit the text to 60 characters.'
|
57
|
+
}
|
58
|
+
])
|
59
|
+
|
60
|
+
menuButton.createField('icon')
|
61
|
+
.name('Icon')
|
62
|
+
.type('Link')
|
63
|
+
.linkType('Asset')
|
64
|
+
|
65
|
+
menuButton.createField('externalLink')
|
66
|
+
.name('External Link')
|
67
|
+
.type('Symbol')
|
68
|
+
.validations([
|
69
|
+
{
|
70
|
+
regexp: { pattern: "^(ftp|http|https):\\/\\/(\\w+:{0,1}\\w*@)?(\\S+)(:[0-9]+)?(\\/|\\/([\\w#!:.?+=&%@!\\-\\/]))?$" },
|
71
|
+
message: "The external link must be a URL like 'https://www.watermark.org/'"
|
72
|
+
}
|
73
|
+
])
|
74
|
+
|
75
|
+
menuButton.createField('link')
|
76
|
+
.name('Page Link')
|
77
|
+
.type('Link')
|
78
|
+
.linkType('Entry')
|
79
|
+
.validations([
|
80
|
+
{
|
81
|
+
linkContentType: [ 'page' ],
|
82
|
+
message: 'The Page Link must be a link to a Page which has a slug.'
|
83
|
+
}
|
84
|
+
])
|
85
|
+
}
|