eip-s3-deploy 2.1.1 → 2.2.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.
package/deploy.js CHANGED
@@ -14,7 +14,7 @@ const path = require ( 'path' );
14
14
  const _ = require ( 'lodash' );
15
15
  const fs = require ( 'fs' ).promises;
16
16
  const s3 = new aws.S3 ( { region: 'eu-west-1' } );
17
- const cf = new aws.CloudFront ( { region: 'eu-west-1' } );
17
+ const fetch = require ( 'node-fetch' );
18
18
  const recursive = require ( 'recursive-readdir' );
19
19
  const md5File = require ( 'md5-file' );
20
20
  const handlebars = require ( 'handlebars' );
@@ -36,25 +36,44 @@ const writeDeploymentLock = async ( deploymentHash ) => fs.access ( process.cwd
36
36
  return fs.writeFile ( path.join ( process.cwd (), 'deployment.lock' ), JSON.stringify ( previousHash, null, 2 ) );
37
37
  } )
38
38
  .catch ( () => {
39
- const newHash = _.stubObject ();
39
+ const newHash = {};
40
40
  newHash[ args._[ 0 ] ] = deploymentHash;
41
41
 
42
42
  return fs.writeFile ( path.join ( process.cwd (), 'deployment.lock' ), JSON.stringify ( newHash, null, 2 ) );
43
43
  } );
44
44
 
45
45
  const deploy = async () => {
46
- const config = require ( path.join ( process.cwd (), 'deployConf.js' ) )[ args._[ 0 ] ];
47
- const promiseChain = _.stubObject ();
46
+ const files = await fs.readdir ( process.cwd () );
47
+ let deployConfName;
48
+
49
+ if ( files.find ( f => f === 'deployConf.cjs' ) )
50
+ deployConfName = 'deployConf.cjs';
51
+ else
52
+ deployConfName = 'deployConf.js';
53
+
54
+ const parentConfig = require ( path.join ( process.cwd (), deployConfName ) );
55
+ const config = require ( path.join ( process.cwd (), deployConfName ) )[ args._[ 0 ] ];
56
+ const promiseChain = {};
48
57
 
49
58
  if ( !config ) {
50
59
  process.stdout.write ( '\x1b[38;5;196mThe environment specified cannot be found in the deployConfig.js file.\x1b[0m\n' );
51
60
  process.exit ( 0 );
52
61
  }
62
+ if ( !parentConfig.version || parentConfig.version !== 2 ) {
63
+ process.stdout.write ( '\x1b[38;5;196mThere is a deployConf.js file however it\'s not using the latest version please update your config to version 2.\x1b[0m\n' );
64
+ process.stdout.write ( '\x1b[38;5;214mHere is an example deployConf.js to assist:\x1b[0m - https://cf.eip.telegraph.co.uk/testFolder/example.html\n' );
65
+ process.exit ( 0 );
66
+ }
67
+ if ( ![ 'bucket', 'folder', 'cache' ].every ( key => Object.keys ( config ).includes ( key ) ) ){
68
+ process.stdout.write ( '\x1b[38;5;214mThere is a deployConf.js file however it\'s not structured correctly, please make sure you\'ve got the correct attributes.\x1b[0m\n' );
69
+ process.stdout.write ( '\x1b[38;5;190mHere is an example deployConf.js to assist:\x1b[0m - https://cf.eip.telegraph.co.uk/testFolder/example.html\n' );
70
+ process.exit ( 0 );
71
+ }
53
72
 
54
73
  process.stdout.write ( '-------------------\n' );
55
74
  process.stdout.write ( '\x1b[38;5;214mINITIATING DEPLOYMENT TO:\x1b[0m \x1b[38;5;190m' + args._[ 0 ] + '\n' );
56
75
  process.stdout.write ( '\x1b[38;5;214m📁 Copying contents of:\x1b[0m \x1b[38;5;190m' + ( config.targetFolder ? process.cwd () + '/' + config.targetFolder : process.cwd () ) + ( args._[ 1 ] ? '/' + args._[ 1 ] : '' ) + '\x1b[0m\n' );
57
- process.stdout.write ( '\x1b[38;5;214m🗑 to S3 Bucket/Folder:\x1b[0m \x1b[38;5;190m' + config.Bucket + '/' + ( config.Folder || '' ) + ( args._[ 1 ] ? args._[ 1 ] + '/' : '' ) + '\x1b[0m\n' );
76
+ process.stdout.write ( '\x1b[38;5;214m🗑 to S3 Bucket/Folder:\x1b[0m \x1b[38;5;190m' + config.bucket + '/' + ( config.folder || '' ) + ( args._[ 1 ] ? args._[ 1 ] + '/' : '' ) + '\x1b[0m\n' );
58
77
  process.stdout.write ( '\x1b[38;5;214m☁️ CloudFront CDN Invalidation:\x1b[0m ' + ( config.cdnId ? '\x1b[38;5;190mYES (' + config.cdnId + ')' : '\x1b[38;5;9mNO' ) + '\x1b[0m\n' );
59
78
  if ( args._[ 1 ] ) process.stdout.write ( '\x1b[38;5;214m📂 Custom Deploy Folder Selected:\x1b[0m \x1b[38;5;190m' + args._[ 1 ] + '\x1b[0m\n' );
60
79
  if ( args.f ) {
@@ -66,11 +85,11 @@ const deploy = async () => {
66
85
  let scanDirectory = path.resolve ( config.targetFolder && config.targetFolder !== '' ? `${ process.cwd () }/${ config.targetFolder }` : process.cwd () );
67
86
  if ( args._[ 1 ] ) scanDirectory = path.join ( scanDirectory, args._[ 1 ] );
68
87
 
69
- const scannedFiles = await recursive ( scanDirectory, _.concat ( config.Omit || [], [ 'deployment.lock' ] ) );
88
+ const scannedFiles = await recursive ( scanDirectory, _.concat ( config.omit || [], [ 'deployment.lock' ] ) );
70
89
  const deploymentLock = await loadDeploymentLock ();
71
90
 
72
91
  promiseChain.changedFiles = promiseChain.newFiles = 0;
73
- promiseChain.deploymentHash = _.stubObject ();
92
+ promiseChain.deploymentHash = {};
74
93
 
75
94
  const filesToUpload = _.compact ( _.map ( scannedFiles, filename => {
76
95
  promiseChain.deploymentHash[ _.replace ( filename, process.cwd (), '' ) ] = md5File.sync ( filename );
@@ -118,7 +137,7 @@ const deploy = async () => {
118
137
  //do nothing
119
138
  }
120
139
 
121
- let key = ( config.Folder ? `${ config.Folder }` : '' ) + ( config.targetFolder && config.targetFolder !== '' ? _.replace ( _.replace ( filename, process.cwd (), '' ), `${ config.targetFolder }/`, '' ) : _.replace ( filename, process.cwd (), '' ) );
140
+ let key = ( config.folder ? `${ config.folder }` : '' ) + ( config.targetFolder && config.targetFolder !== '' ? _.replace ( _.replace ( filename, process.cwd (), '' ), `${ config.targetFolder }/`, '' ) : _.replace ( filename, process.cwd (), '' ) );
122
141
  key = key.replace ( /\\/g, '/' );
123
142
  if ( key.indexOf ( '/' ) === 0 ){
124
143
  key = key.substr ( 1 );
@@ -128,11 +147,11 @@ const deploy = async () => {
128
147
  }
129
148
 
130
149
  return s3.putObject ( {
131
- Bucket: config.Bucket,
150
+ Bucket: config.bucket,
132
151
  Key: key,
133
152
  ACL: 'public-read',
134
153
  Body: body,
135
- CacheControl: config.CacheControl || 'max-age=3600, s-maxage=31536000',
154
+ CacheControl: Object.keys ( config.cache ).map ( cacheKey => typeof config.cache[ cacheKey ] === 'boolean' ? config.cache[ cacheKey ] ? cacheKey : null : config.cache[ cacheKey ] ? `${cacheKey}=${config.cache[ cacheKey ]}` : null ).filter ( n => n ).join ( ', ' ),
136
155
  ContentType: mime.getType ( filename )
137
156
  } ).promise ().then ( () => progressBar.increment () );
138
157
 
@@ -141,18 +160,19 @@ const deploy = async () => {
141
160
  progressBar.stop ();
142
161
 
143
162
  if ( config.cdnId ) {
144
- await cf.createInvalidation ( {
145
- DistributionId: config.cdnId,
146
- InvalidationBatch: {
147
- CallerReference: new Date ().valueOf () + '/' + Math.floor ( Math.random () * 65535 ),
148
- Paths: {
149
- Quantity: 1,
150
- Items: [ config.Folder ? '/' + config.Folder + '/*' : '/*' ]
151
- }
152
- }
153
- } ).promise ();
163
+ await fetch ( 'https://tools.eip.telegraph.co.uk/v1/invalidate', {
164
+ method: 'POST',
165
+ headers: {
166
+ 'Content-Type': 'application/json'
167
+ },
168
+ body: JSON.stringify ( {
169
+ cdn: config.cdnId,
170
+ key: [ config.folder ? '/' + config.folder + '/*' : '/*' ],
171
+ environment: config?.environment || undefined
172
+ } )
173
+ } );
154
174
  process.stdout.write ( '-------------------\n' );
155
- process.stdout.write ( '📤 \x1b[38;5;190mCloudFront Cache Cleared\x1b[0m | Invalidation: ' + ( config.Folder ? '/' + config.Folder + '/*' : '/*' ) + '\n' );
175
+ process.stdout.write ( '📤 \x1b[38;5;190mCloudFront Cache Cleared\x1b[0m | Invalidation: ' + ( config.folder ? '/' + config.folder + '/*' : '/*' ) + '\n' );
156
176
  }
157
177
 
158
178
  // This should be done after everything is complete.
package/deployConf.js CHANGED
@@ -1,30 +1,52 @@
1
1
  module.exports = {
2
-
2
+ version: 2,
3
3
  prod: {
4
- Bucket: 's3.eip.telegraph.co.uk',
5
- cdnId: 'E3CNSI2YZ2LXA6',
6
- Folder: 'testFolder',
7
- targetFolder: 'test',
8
- CacheControl: 'max-age=1, s-maxage=86400',
9
- Omit: [
4
+ bucket: 's3.eip.telegraph.co.uk', // The location you want to deploy to.
5
+ cdnId: 'cf', // The prefix or identifier for the CDN. e.g. "cf", "cf-particle-html", etc
6
+ folder: 'testFolder', // The remote folder you which to upload to.
7
+ targetFolder: 'test', // The local folder to use as a root for uploading. Remove this to use root folder.
8
+ cache: {
9
+ 'max-age': 3600, // Specifies the maximum age of the resource in seconds on a user's device.
10
+ 's-maxage': 86400 * 7, // Specifies the maximum age of the resource in shared caches (e.g., CDNs e.g., CloudFront, Google Cloud CDN).
11
+ 'public': true, // Indicates that the response can be cached by both public and private caches.
12
+ 'private': false, // Indicates that the response is intended for a single user and should not be cached by CDNs, this should be false unless we're generating private information.
13
+ 'no-cache': false, // This will still cache the resource, but it will be requested from the server each time its requested again. This should be false.
14
+ 'no-store': false, // This is the same as above, except it will not cache the resource at all. (e.g. large files), this should be false.
15
+ 'must-revalidate': false, // Requires the cache to revalidate the resource with the server before serving it to subsequent requests. Useful for frequently changing resources such as live data files.
16
+ 'proxy-revalidate': false, // Similar to must-revalidate, but specifically applies to CDN caches.
17
+ 'immutable': false // Indicates that the resource is considered immutable and should not change. Caches can store immutable resources indefinitely. Use wisely.
18
+ },
19
+ omit: [ // File & folder to ignore from deployment.
10
20
  'deployConf.js'
11
21
  ],
12
22
  data: {
13
- key1: 'production1',
14
- key2: 'production2'
23
+ key1: 'production1', // Replaces {{key1}} in any text-based files with what you put here
24
+ key2: 'production2' // Replaces {{key2}} in any text-based files with what you put here
15
25
  }
16
26
  },
17
27
  test: {
18
- Bucket: 's3-test.eip.telegraph.co.uk',
19
- cdnId: 'E2HC9DMO560JVW',
20
- Folder: 'testFolder',
21
- targetFolder: 'test',
22
- Omit: [
28
+ bucket: 's3-test.eip.telegraph.co.uk', // The location you want to deploy to.
29
+ cdnId: 'cf', // The prefix or identifier for the CDN. e.g. "cf", "cf-particle-html", etc
30
+ environment: 'test', // The variant of environment.
31
+ folder: 'testFolder', // The remote folder you which to upload to.
32
+ targetFolder: 'test', // The local folder to use as a root for uploading. Remove this to use root folder.
33
+ cache: {
34
+ 'max-age': 3600, // Specifies the maximum age of the resource in seconds on a user's device.
35
+ 's-maxage': 86400 * 7, // Specifies the maximum age of the resource in shared caches (e.g., CDNs e.g., CloudFront, Google Cloud CDN).
36
+ 'public': true, // Indicates that the response can be cached by both public and private caches.
37
+ 'private': false, // Indicates that the response is intended for a single user and should not be cached by CDNs, this should be false unless we're generating private information.
38
+ 'no-cache': false, // This will still cache the resource, but it will be requested from the server each time its requested again. This should be false.
39
+ 'no-store': false, // This is the same as above, except it will not cache the resource at all. (e.g. large files), this should be false.
40
+ 'must-revalidate': false, // Requires the cache to revalidate the resource with the server before serving it to subsequent requests. Useful for frequently changing resources such as live data files.
41
+ 'proxy-revalidate': false, // Similar to must-revalidate, but specifically applies to CDN caches.
42
+ 'immutable': false // Indicates that the resource is considered immutable and should not change. Caches can store immutable resources indefinitely. Use wisely.
43
+ },
44
+ omit: [ // File & folder to ignore from deployment.
23
45
  'deployConf.js'
24
46
  ],
25
47
  data: {
26
- key1: 'test1',
27
- key2: 'test2'
48
+ key1: 'production1', // Replaces {{key1}} in any text-based files with what you put here
49
+ key2: 'production2' // Replaces {{key2}} in any text-based files with what you put here
28
50
  }
29
51
  }
30
- };
52
+ };
package/deployment.lock CHANGED
@@ -12,5 +12,14 @@
12
12
  "/test/folder1/file2.txt": "d41d8cd98f00b204e9800998ecf8427e",
13
13
  "/test/folder2/file1.txt": "d41d8cd98f00b204e9800998ecf8427e",
14
14
  "/test/folder2/file2.txt": "d41d8cd98f00b204e9800998ecf8427e"
15
+ },
16
+ "prod": {
17
+ "/test/file1.txt": "f5b5ed0c72f4e9984c3e7a8b18c08c2b",
18
+ "/test/file2.txt": "d41d8cd98f00b204e9800998ecf8427e",
19
+ "/test/folder1/file1.txt": "d41d8cd98f00b204e9800998ecf8427e",
20
+ "/test/folder1/file2.txt": "d41d8cd98f00b204e9800998ecf8427e",
21
+ "/test/folder2/file1.txt": "d41d8cd98f00b204e9800998ecf8427e",
22
+ "/test/folder2/file2.txt": "d41d8cd98f00b204e9800998ecf8427e",
23
+ "/test/example.html": "d3ee67eb6e0f33d59c944fb4786359f3"
15
24
  }
16
25
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "eip-s3-deploy",
3
- "version": "2.1.1",
3
+ "version": "2.2.0",
4
4
  "description": "Deploy static websites to S3 - all files will be public",
5
5
  "main": "deploy.js",
6
6
  "bin": {
@@ -31,6 +31,7 @@
31
31
  "md5-file": "^5.0.0",
32
32
  "mime": "^2.4.6",
33
33
  "minimist": "^1.2.5",
34
+ "node-fetch": "2.6.7",
34
35
  "recursive-readdir": "^2.2.2"
35
36
  }
36
37
  }
@@ -0,0 +1,117 @@
1
+ <!DOCTYPE html>
2
+ <html lang="en">
3
+
4
+ <head>
5
+ <meta charset="UTF-8">
6
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
7
+ <title>Code Block Example</title>
8
+ <style>
9
+ body {
10
+ display: flex;
11
+ justify-content: center;
12
+ align-items: center;
13
+ height: 100vh;
14
+ margin: 0;
15
+ padding: 0;
16
+ background-color: #2d2d2d;
17
+ }
18
+
19
+ .code-block {
20
+ background-color: #3f3f3f;
21
+ padding: 10px;
22
+ font-family: Consolas, monospace;
23
+ font-size: 14px;
24
+ line-height: 1.4;
25
+ overflow-x: auto;
26
+ border-radius: 4px;
27
+ }
28
+
29
+ /* PrismJS 1.29.0
30
+ https://prismjs.com/download.html#themes=prism-tomorrow&languages=markup+css+clike+javascript */
31
+ code[class*=language-],pre[class*=language-]{color:#ccc;background:0 0;font-family:Consolas,Monaco,'Andale Mono','Ubuntu Mono',monospace;font-size:1em;text-align:left;white-space:pre;word-spacing:normal;word-break:normal;word-wrap:normal;line-height:1.5;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-hyphens:none;-moz-hyphens:none;-ms-hyphens:none;hyphens:none}pre[class*=language-]{padding:1em;margin:.5em 0;overflow:auto}:not(pre)>code[class*=language-],pre[class*=language-]{background:#2d2d2d}:not(pre)>code[class*=language-]{padding:.1em;border-radius:.3em;white-space:normal}.token.block-comment,.token.cdata,.token.comment,.token.doctype,.token.prolog{color:#999}.token.punctuation{color:#ccc}.token.attr-name,.token.deleted,.token.namespace,.token.tag{color:#e2777a}.token.function-name{color:#6196cc}.token.boolean,.token.function,.token.number{color:#f08d49}.token.class-name,.token.constant,.token.property,.token.symbol{color:#f8c555}.token.atrule,.token.builtin,.token.important,.token.keyword,.token.selector{color:#cc99cd}.token.attr-value,.token.char,.token.regex,.token.string,.token.variable{color:#7ec699}.token.entity,.token.operator,.token.url{color:#67cdcc}.token.bold,.token.important{font-weight:700}.token.italic{font-style:italic}.token.entity{cursor:help}.token.inserted{color:green}
32
+
33
+ </style>
34
+ </head>
35
+
36
+ <body>
37
+ <div class="code-block language-js">
38
+ <pre>
39
+ <code>
40
+ module.exports = {
41
+ version: 2,
42
+ prod: {
43
+ bucket: 's3.eip.telegraph.co.uk', // The location you want to deploy to.
44
+ cdnId: 'cf', // The prefix or identifier for the CDN. e.g. "cf", "cf-particle-html", etc
45
+ folder: 'testFolder', // The remote folder you which to upload to.
46
+ targetFolder: 'test', // The local folder to use as a root for uploading. Remove this to use root folder.
47
+ cache: {
48
+ 'max-age': 3600, // Specifies the maximum age of the resource in seconds on a user's device.
49
+ 's-maxage': 86400 * 7, // Specifies the maximum age of the resource in shared caches (e.g., CDNs e.g., CloudFront, Google Cloud CDN).
50
+ 'public': true, // Indicates that the response can be cached by both public and private caches.
51
+ 'private': false, // Indicates that the response is intended for a single user and should not be cached by CDNs, this should be false unless we're generating private information.
52
+ 'no-cache': false, // This will still cache the resource, but it will be requested from the server each time its requested again. This should be false.
53
+ 'no-store': false, // This is the same as above, except it will not cache the resource at all. (e.g. large files), this should be false.
54
+ 'must-revalidate': false, // Requires the cache to revalidate the resource with the server before serving it to subsequent requests. Useful for frequently changing resources such as live data files.
55
+ 'proxy-revalidate': false, // Similar to must-revalidate, but specifically applies to CDN caches.
56
+ 'immutable': false // Indicates that the resource is considered immutable and should not change. Caches can store immutable resources indefinitely. Use wisely.
57
+ },
58
+ omit: [ // File & folder to ignore from deployment.
59
+ 'deployConf.js'
60
+ ],
61
+ data: {
62
+ key1: 'production1', // Replaces {{key1}} in any text-based files with what you put here
63
+ key2: 'production2' // Replaces {{key2}} in any text-based files with what you put here
64
+ }
65
+ },
66
+ test: {
67
+ bucket: 's3-test.eip.telegraph.co.uk', // The location you want to deploy to.
68
+ cdnId: 'cf', // The prefix or identifier for the CDN. e.g. "cf", "cf-particle-html", etc
69
+ environment: 'test', // The variant of environment.
70
+ folder: 'testFolder', // The remote folder you which to upload to.
71
+ targetFolder: 'test', // The local folder to use as a root for uploading. Remove this to use root folder.
72
+ cache: {
73
+ 'max-age': 3600, // Specifies the maximum age of the resource in seconds on a user's device.
74
+ 's-maxage': 86400 * 7, // Specifies the maximum age of the resource in shared caches (e.g., CDNs e.g., CloudFront, Google Cloud CDN).
75
+ 'public': true, // Indicates that the response can be cached by both public and private caches.
76
+ 'private': false, // Indicates that the response is intended for a single user and should not be cached by CDNs, this should be false unless we're generating private information.
77
+ 'no-cache': false, // This will still cache the resource, but it will be requested from the server each time its requested again. This should be false.
78
+ 'no-store': false, // This is the same as above, except it will not cache the resource at all. (e.g. large files), this should be false.
79
+ 'must-revalidate': false, // Requires the cache to revalidate the resource with the server before serving it to subsequent requests. Useful for frequently changing resources such as live data files.
80
+ 'proxy-revalidate': false, // Similar to must-revalidate, but specifically applies to CDN caches.
81
+ 'immutable': false // Indicates that the resource is considered immutable and should not change. Caches can store immutable resources indefinitely. Use wisely.
82
+ },
83
+ omit: [ // File & folder to ignore from deployment.
84
+ 'deployConf.js'
85
+ ],
86
+ data: {
87
+ key1: 'production1', // Replaces {{key1}} in any text-based files with what you put here
88
+ key2: 'production2' // Replaces {{key2}} in any text-based files with what you put here
89
+ }
90
+ }
91
+ };
92
+ </code>
93
+ </pre>
94
+ </div>
95
+
96
+ <script>
97
+ /* PrismJS 1.29.0
98
+ https://prismjs.com/download.html#themes=prism-tomorrow&languages=markup+css+clike+javascript */
99
+ var _self="undefined"!=typeof window?window:"undefined"!=typeof WorkerGlobalScope&&self instanceof WorkerGlobalScope?self:{},Prism=function(e){var n=/(?:^|\s)lang(?:uage)?-([\w-]+)(?=\s|$)/i,t=0,r={},a={manual:e.Prism&&e.Prism.manual,disableWorkerMessageHandler:e.Prism&&e.Prism.disableWorkerMessageHandler,util:{encode:function e(n){return n instanceof i?new i(n.type,e(n.content),n.alias):Array.isArray(n)?n.map(e):n.replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/\u00a0/g," ")},type:function(e){return Object.prototype.toString.call(e).slice(8,-1)},objId:function(e){return e.__id||Object.defineProperty(e,"__id",{value:++t}),e.__id},clone:function e(n,t){var r,i;switch(t=t||{},a.util.type(n)){case"Object":if(i=a.util.objId(n),t[i])return t[i];for(var l in r={},t[i]=r,n)n.hasOwnProperty(l)&&(r[l]=e(n[l],t));return r;case"Array":return i=a.util.objId(n),t[i]?t[i]:(r=[],t[i]=r,n.forEach((function(n,a){r[a]=e(n,t)})),r);default:return n}},getLanguage:function(e){for(;e;){var t=n.exec(e.className);if(t)return t[1].toLowerCase();e=e.parentElement}return"none"},setLanguage:function(e,t){e.className=e.className.replace(RegExp(n,"gi"),""),e.classList.add("language-"+t)},currentScript:function(){if("undefined"==typeof document)return null;if("currentScript"in document)return document.currentScript;try{throw new Error}catch(r){var e=(/at [^(\r\n]*\((.*):[^:]+:[^:]+\)$/i.exec(r.stack)||[])[1];if(e){var n=document.getElementsByTagName("script");for(var t in n)if(n[t].src==e)return n[t]}return null}},isActive:function(e,n,t){for(var r="no-"+n;e;){var a=e.classList;if(a.contains(n))return!0;if(a.contains(r))return!1;e=e.parentElement}return!!t}},languages:{plain:r,plaintext:r,text:r,txt:r,extend:function(e,n){var t=a.util.clone(a.languages[e]);for(var r in n)t[r]=n[r];return t},insertBefore:function(e,n,t,r){var i=(r=r||a.languages)[e],l={};for(var o in i)if(i.hasOwnProperty(o)){if(o==n)for(var s in t)t.hasOwnProperty(s)&&(l[s]=t[s]);t.hasOwnProperty(o)||(l[o]=i[o])}var u=r[e];return r[e]=l,a.languages.DFS(a.languages,(function(n,t){t===u&&n!=e&&(this[n]=l)})),l},DFS:function e(n,t,r,i){i=i||{};var l=a.util.objId;for(var o in n)if(n.hasOwnProperty(o)){t.call(n,o,n[o],r||o);var s=n[o],u=a.util.type(s);"Object"!==u||i[l(s)]?"Array"!==u||i[l(s)]||(i[l(s)]=!0,e(s,t,o,i)):(i[l(s)]=!0,e(s,t,null,i))}}},plugins:{},highlightAll:function(e,n){a.highlightAllUnder(document,e,n)},highlightAllUnder:function(e,n,t){var r={callback:t,container:e,selector:'code[class*="language-"], [class*="language-"] code, code[class*="lang-"], [class*="lang-"] code'};a.hooks.run("before-highlightall",r),r.elements=Array.prototype.slice.apply(r.container.querySelectorAll(r.selector)),a.hooks.run("before-all-elements-highlight",r);for(var i,l=0;i=r.elements[l++];)a.highlightElement(i,!0===n,r.callback)},highlightElement:function(n,t,r){var i=a.util.getLanguage(n),l=a.languages[i];a.util.setLanguage(n,i);var o=n.parentElement;o&&"pre"===o.nodeName.toLowerCase()&&a.util.setLanguage(o,i);var s={element:n,language:i,grammar:l,code:n.textContent};function u(e){s.highlightedCode=e,a.hooks.run("before-insert",s),s.element.innerHTML=s.highlightedCode,a.hooks.run("after-highlight",s),a.hooks.run("complete",s),r&&r.call(s.element)}if(a.hooks.run("before-sanity-check",s),(o=s.element.parentElement)&&"pre"===o.nodeName.toLowerCase()&&!o.hasAttribute("tabindex")&&o.setAttribute("tabindex","0"),!s.code)return a.hooks.run("complete",s),void(r&&r.call(s.element));if(a.hooks.run("before-highlight",s),s.grammar)if(t&&e.Worker){var c=new Worker(a.filename);c.onmessage=function(e){u(e.data)},c.postMessage(JSON.stringify({language:s.language,code:s.code,immediateClose:!0}))}else u(a.highlight(s.code,s.grammar,s.language));else u(a.util.encode(s.code))},highlight:function(e,n,t){var r={code:e,grammar:n,language:t};if(a.hooks.run("before-tokenize",r),!r.grammar)throw new Error('The language "'+r.language+'" has no grammar.');return r.tokens=a.tokenize(r.code,r.grammar),a.hooks.run("after-tokenize",r),i.stringify(a.util.encode(r.tokens),r.language)},tokenize:function(e,n){var t=n.rest;if(t){for(var r in t)n[r]=t[r];delete n.rest}var a=new s;return u(a,a.head,e),o(e,a,n,a.head,0),function(e){for(var n=[],t=e.head.next;t!==e.tail;)n.push(t.value),t=t.next;return n}(a)},hooks:{all:{},add:function(e,n){var t=a.hooks.all;t[e]=t[e]||[],t[e].push(n)},run:function(e,n){var t=a.hooks.all[e];if(t&&t.length)for(var r,i=0;r=t[i++];)r(n)}},Token:i};function i(e,n,t,r){this.type=e,this.content=n,this.alias=t,this.length=0|(r||"").length}function l(e,n,t,r){e.lastIndex=n;var a=e.exec(t);if(a&&r&&a[1]){var i=a[1].length;a.index+=i,a[0]=a[0].slice(i)}return a}function o(e,n,t,r,s,g){for(var f in t)if(t.hasOwnProperty(f)&&t[f]){var h=t[f];h=Array.isArray(h)?h:[h];for(var d=0;d<h.length;++d){if(g&&g.cause==f+","+d)return;var v=h[d],p=v.inside,m=!!v.lookbehind,y=!!v.greedy,k=v.alias;if(y&&!v.pattern.global){var x=v.pattern.toString().match(/[imsuy]*$/)[0];v.pattern=RegExp(v.pattern.source,x+"g")}for(var b=v.pattern||v,w=r.next,A=s;w!==n.tail&&!(g&&A>=g.reach);A+=w.value.length,w=w.next){var E=w.value;if(n.length>e.length)return;if(!(E instanceof i)){var P,L=1;if(y){if(!(P=l(b,A,e,m))||P.index>=e.length)break;var S=P.index,O=P.index+P[0].length,j=A;for(j+=w.value.length;S>=j;)j+=(w=w.next).value.length;if(A=j-=w.value.length,w.value instanceof i)continue;for(var C=w;C!==n.tail&&(j<O||"string"==typeof C.value);C=C.next)L++,j+=C.value.length;L--,E=e.slice(A,j),P.index-=A}else if(!(P=l(b,0,E,m)))continue;S=P.index;var N=P[0],_=E.slice(0,S),M=E.slice(S+N.length),W=A+E.length;g&&W>g.reach&&(g.reach=W);var z=w.prev;if(_&&(z=u(n,z,_),A+=_.length),c(n,z,L),w=u(n,z,new i(f,p?a.tokenize(N,p):N,k,N)),M&&u(n,w,M),L>1){var I={cause:f+","+d,reach:W};o(e,n,t,w.prev,A,I),g&&I.reach>g.reach&&(g.reach=I.reach)}}}}}}function s(){var e={value:null,prev:null,next:null},n={value:null,prev:e,next:null};e.next=n,this.head=e,this.tail=n,this.length=0}function u(e,n,t){var r=n.next,a={value:t,prev:n,next:r};return n.next=a,r.prev=a,e.length++,a}function c(e,n,t){for(var r=n.next,a=0;a<t&&r!==e.tail;a++)r=r.next;n.next=r,r.prev=n,e.length-=a}if(e.Prism=a,i.stringify=function e(n,t){if("string"==typeof n)return n;if(Array.isArray(n)){var r="";return n.forEach((function(n){r+=e(n,t)})),r}var i={type:n.type,content:e(n.content,t),tag:"span",classes:["token",n.type],attributes:{},language:t},l=n.alias;l&&(Array.isArray(l)?Array.prototype.push.apply(i.classes,l):i.classes.push(l)),a.hooks.run("wrap",i);var o="";for(var s in i.attributes)o+=" "+s+'="'+(i.attributes[s]||"").replace(/"/g,"&quot;")+'"';return"<"+i.tag+' class="'+i.classes.join(" ")+'"'+o+">"+i.content+"</"+i.tag+">"},!e.document)return e.addEventListener?(a.disableWorkerMessageHandler||e.addEventListener("message",(function(n){var t=JSON.parse(n.data),r=t.language,i=t.code,l=t.immediateClose;e.postMessage(a.highlight(i,a.languages[r],r)),l&&e.close()}),!1),a):a;var g=a.util.currentScript();function f(){a.manual||a.highlightAll()}if(g&&(a.filename=g.src,g.hasAttribute("data-manual")&&(a.manual=!0)),!a.manual){var h=document.readyState;"loading"===h||"interactive"===h&&g&&g.defer?document.addEventListener("DOMContentLoaded",f):window.requestAnimationFrame?window.requestAnimationFrame(f):window.setTimeout(f,16)}return a}(_self);"undefined"!=typeof module&&module.exports&&(module.exports=Prism),"undefined"!=typeof global&&(global.Prism=Prism);
100
+ Prism.languages.markup={comment:{pattern:/<!--(?:(?!<!--)[\s\S])*?-->/,greedy:!0},prolog:{pattern:/<\?[\s\S]+?\?>/,greedy:!0},doctype:{pattern:/<!DOCTYPE(?:[^>"'[\]]|"[^"]*"|'[^']*')+(?:\[(?:[^<"'\]]|"[^"]*"|'[^']*'|<(?!!--)|<!--(?:[^-]|-(?!->))*-->)*\]\s*)?>/i,greedy:!0,inside:{"internal-subset":{pattern:/(^[^\[]*\[)[\s\S]+(?=\]>$)/,lookbehind:!0,greedy:!0,inside:null},string:{pattern:/"[^"]*"|'[^']*'/,greedy:!0},punctuation:/^<!|>$|[[\]]/,"doctype-tag":/^DOCTYPE/i,name:/[^\s<>'"]+/}},cdata:{pattern:/<!\[CDATA\[[\s\S]*?\]\]>/i,greedy:!0},tag:{pattern:/<\/?(?!\d)[^\s>\/=$<%]+(?:\s(?:\s*[^\s>\/=]+(?:\s*=\s*(?:"[^"]*"|'[^']*'|[^\s'">=]+(?=[\s>]))|(?=[\s/>])))+)?\s*\/?>/,greedy:!0,inside:{tag:{pattern:/^<\/?[^\s>\/]+/,inside:{punctuation:/^<\/?/,namespace:/^[^\s>\/:]+:/}},"special-attr":[],"attr-value":{pattern:/=\s*(?:"[^"]*"|'[^']*'|[^\s'">=]+)/,inside:{punctuation:[{pattern:/^=/,alias:"attr-equals"},{pattern:/^(\s*)["']|["']$/,lookbehind:!0}]}},punctuation:/\/?>/,"attr-name":{pattern:/[^\s>\/]+/,inside:{namespace:/^[^\s>\/:]+:/}}}},entity:[{pattern:/&[\da-z]{1,8};/i,alias:"named-entity"},/&#x?[\da-f]{1,8};/i]},Prism.languages.markup.tag.inside["attr-value"].inside.entity=Prism.languages.markup.entity,Prism.languages.markup.doctype.inside["internal-subset"].inside=Prism.languages.markup,Prism.hooks.add("wrap",(function(a){"entity"===a.type&&(a.attributes.title=a.content.replace(/&amp;/,"&"))})),Object.defineProperty(Prism.languages.markup.tag,"addInlined",{value:function(a,e){var s={};s["language-"+e]={pattern:/(^<!\[CDATA\[)[\s\S]+?(?=\]\]>$)/i,lookbehind:!0,inside:Prism.languages[e]},s.cdata=/^<!\[CDATA\[|\]\]>$/i;var t={"included-cdata":{pattern:/<!\[CDATA\[[\s\S]*?\]\]>/i,inside:s}};t["language-"+e]={pattern:/[\s\S]+/,inside:Prism.languages[e]};var n={};n[a]={pattern:RegExp("(<__[^>]*>)(?:<!\\[CDATA\\[(?:[^\\]]|\\](?!\\]>))*\\]\\]>|(?!<!\\[CDATA\\[)[^])*?(?=</__>)".replace(/__/g,(function(){return a})),"i"),lookbehind:!0,greedy:!0,inside:t},Prism.languages.insertBefore("markup","cdata",n)}}),Object.defineProperty(Prism.languages.markup.tag,"addAttribute",{value:function(a,e){Prism.languages.markup.tag.inside["special-attr"].push({pattern:RegExp("(^|[\"'\\s])(?:"+a+")\\s*=\\s*(?:\"[^\"]*\"|'[^']*'|[^\\s'\">=]+(?=[\\s>]))","i"),lookbehind:!0,inside:{"attr-name":/^[^\s=]+/,"attr-value":{pattern:/=[\s\S]+/,inside:{value:{pattern:/(^=\s*(["']|(?!["'])))\S[\s\S]*(?=\2$)/,lookbehind:!0,alias:[e,"language-"+e],inside:Prism.languages[e]},punctuation:[{pattern:/^=/,alias:"attr-equals"},/"|'/]}}}})}}),Prism.languages.html=Prism.languages.markup,Prism.languages.mathml=Prism.languages.markup,Prism.languages.svg=Prism.languages.markup,Prism.languages.xml=Prism.languages.extend("markup",{}),Prism.languages.ssml=Prism.languages.xml,Prism.languages.atom=Prism.languages.xml,Prism.languages.rss=Prism.languages.xml;
101
+ !function(s){var e=/(?:"(?:\\(?:\r\n|[\s\S])|[^"\\\r\n])*"|'(?:\\(?:\r\n|[\s\S])|[^'\\\r\n])*')/;s.languages.css={comment:/\/\*[\s\S]*?\*\//,atrule:{pattern:RegExp("@[\\w-](?:[^;{\\s\"']|\\s+(?!\\s)|"+e.source+")*?(?:;|(?=\\s*\\{))"),inside:{rule:/^@[\w-]+/,"selector-function-argument":{pattern:/(\bselector\s*\(\s*(?![\s)]))(?:[^()\s]|\s+(?![\s)])|\((?:[^()]|\([^()]*\))*\))+(?=\s*\))/,lookbehind:!0,alias:"selector"},keyword:{pattern:/(^|[^\w-])(?:and|not|only|or)(?![\w-])/,lookbehind:!0}}},url:{pattern:RegExp("\\burl\\((?:"+e.source+"|(?:[^\\\\\r\n()\"']|\\\\[^])*)\\)","i"),greedy:!0,inside:{function:/^url/i,punctuation:/^\(|\)$/,string:{pattern:RegExp("^"+e.source+"$"),alias:"url"}}},selector:{pattern:RegExp("(^|[{}\\s])[^{}\\s](?:[^{};\"'\\s]|\\s+(?![\\s{])|"+e.source+")*(?=\\s*\\{)"),lookbehind:!0},string:{pattern:e,greedy:!0},property:{pattern:/(^|[^-\w\xA0-\uFFFF])(?!\s)[-_a-z\xA0-\uFFFF](?:(?!\s)[-\w\xA0-\uFFFF])*(?=\s*:)/i,lookbehind:!0},important:/!important\b/i,function:{pattern:/(^|[^-a-z0-9])[-a-z0-9]+(?=\()/i,lookbehind:!0},punctuation:/[(){};:,]/},s.languages.css.atrule.inside.rest=s.languages.css;var t=s.languages.markup;t&&(t.tag.addInlined("style","css"),t.tag.addAttribute("style","css"))}(Prism);
102
+ Prism.languages.clike={comment:[{pattern:/(^|[^\\])\/\*[\s\S]*?(?:\*\/|$)/,lookbehind:!0,greedy:!0},{pattern:/(^|[^\\:])\/\/.*/,lookbehind:!0,greedy:!0}],string:{pattern:/(["'])(?:\\(?:\r\n|[\s\S])|(?!\1)[^\\\r\n])*\1/,greedy:!0},"class-name":{pattern:/(\b(?:class|extends|implements|instanceof|interface|new|trait)\s+|\bcatch\s+\()[\w.\\]+/i,lookbehind:!0,inside:{punctuation:/[.\\]/}},keyword:/\b(?:break|catch|continue|do|else|finally|for|function|if|in|instanceof|new|null|return|throw|try|while)\b/,boolean:/\b(?:false|true)\b/,function:/\b\w+(?=\()/,number:/\b0x[\da-f]+\b|(?:\b\d+(?:\.\d*)?|\B\.\d+)(?:e[+-]?\d+)?/i,operator:/[<>]=?|[!=]=?=?|--?|\+\+?|&&?|\|\|?|[?*/~^%]/,punctuation:/[{}[\];(),.:]/};
103
+ Prism.languages.javascript=Prism.languages.extend("clike",{"class-name":[Prism.languages.clike["class-name"],{pattern:/(^|[^$\w\xA0-\uFFFF])(?!\s)[_$A-Z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*(?=\.(?:constructor|prototype))/,lookbehind:!0}],keyword:[{pattern:/((?:^|\})\s*)catch\b/,lookbehind:!0},{pattern:/(^|[^.]|\.\.\.\s*)\b(?:as|assert(?=\s*\{)|async(?=\s*(?:function\b|\(|[$\w\xA0-\uFFFF]|$))|await|break|case|class|const|continue|debugger|default|delete|do|else|enum|export|extends|finally(?=\s*(?:\{|$))|for|from(?=\s*(?:['"]|$))|function|(?:get|set)(?=\s*(?:[#\[$\w\xA0-\uFFFF]|$))|if|implements|import|in|instanceof|interface|let|new|null|of|package|private|protected|public|return|static|super|switch|this|throw|try|typeof|undefined|var|void|while|with|yield)\b/,lookbehind:!0}],function:/#?(?!\s)[_$a-zA-Z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*(?=\s*(?:\.\s*(?:apply|bind|call)\s*)?\()/,number:{pattern:RegExp("(^|[^\\w$])(?:NaN|Infinity|0[bB][01]+(?:_[01]+)*n?|0[oO][0-7]+(?:_[0-7]+)*n?|0[xX][\\dA-Fa-f]+(?:_[\\dA-Fa-f]+)*n?|\\d+(?:_\\d+)*n|(?:\\d+(?:_\\d+)*(?:\\.(?:\\d+(?:_\\d+)*)?)?|\\.\\d+(?:_\\d+)*)(?:[Ee][+-]?\\d+(?:_\\d+)*)?)(?![\\w$])"),lookbehind:!0},operator:/--|\+\+|\*\*=?|=>|&&=?|\|\|=?|[!=]==|<<=?|>>>?=?|[-+*/%&|^!=<>]=?|\.{3}|\?\?=?|\?\.?|[~:]/}),Prism.languages.javascript["class-name"][0].pattern=/(\b(?:class|extends|implements|instanceof|interface|new)\s+)[\w.\\]+/,Prism.languages.insertBefore("javascript","keyword",{regex:{pattern:RegExp("((?:^|[^$\\w\\xA0-\\uFFFF.\"'\\])\\s]|\\b(?:return|yield))\\s*)/(?:(?:\\[(?:[^\\]\\\\\r\n]|\\\\.)*\\]|\\\\.|[^/\\\\\\[\r\n])+/[dgimyus]{0,7}|(?:\\[(?:[^[\\]\\\\\r\n]|\\\\.|\\[(?:[^[\\]\\\\\r\n]|\\\\.|\\[(?:[^[\\]\\\\\r\n]|\\\\.)*\\])*\\])*\\]|\\\\.|[^/\\\\\\[\r\n])+/[dgimyus]{0,7}v[dgimyus]{0,7})(?=(?:\\s|/\\*(?:[^*]|\\*(?!/))*\\*/)*(?:$|[\r\n,.;:})\\]]|//))"),lookbehind:!0,greedy:!0,inside:{"regex-source":{pattern:/^(\/)[\s\S]+(?=\/[a-z]*$)/,lookbehind:!0,alias:"language-regex",inside:Prism.languages.regex},"regex-delimiter":/^\/|\/$/,"regex-flags":/^[a-z]+$/}},"function-variable":{pattern:/#?(?!\s)[_$a-zA-Z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*(?=\s*[=:]\s*(?:async\s*)?(?:\bfunction\b|(?:\((?:[^()]|\([^()]*\))*\)|(?!\s)[_$a-zA-Z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*)\s*=>))/,alias:"function"},parameter:[{pattern:/(function(?:\s+(?!\s)[_$a-zA-Z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*)?\s*\(\s*)(?!\s)(?:[^()\s]|\s+(?![\s)])|\([^()]*\))+(?=\s*\))/,lookbehind:!0,inside:Prism.languages.javascript},{pattern:/(^|[^$\w\xA0-\uFFFF])(?!\s)[_$a-z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*(?=\s*=>)/i,lookbehind:!0,inside:Prism.languages.javascript},{pattern:/(\(\s*)(?!\s)(?:[^()\s]|\s+(?![\s)])|\([^()]*\))+(?=\s*\)\s*=>)/,lookbehind:!0,inside:Prism.languages.javascript},{pattern:/((?:\b|\s|^)(?!(?:as|async|await|break|case|catch|class|const|continue|debugger|default|delete|do|else|enum|export|extends|finally|for|from|function|get|if|implements|import|in|instanceof|interface|let|new|null|of|package|private|protected|public|return|set|static|super|switch|this|throw|try|typeof|undefined|var|void|while|with|yield)(?![$\w\xA0-\uFFFF]))(?:(?!\s)[_$a-zA-Z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*\s*)\(\s*|\]\s*\(\s*)(?!\s)(?:[^()\s]|\s+(?![\s)])|\([^()]*\))+(?=\s*\)\s*\{)/,lookbehind:!0,inside:Prism.languages.javascript}],constant:/\b[A-Z](?:[A-Z_]|\dx?)*\b/}),Prism.languages.insertBefore("javascript","string",{hashbang:{pattern:/^#!.*/,greedy:!0,alias:"comment"},"template-string":{pattern:/`(?:\\[\s\S]|\$\{(?:[^{}]|\{(?:[^{}]|\{[^}]*\})*\})+\}|(?!\$\{)[^\\`])*`/,greedy:!0,inside:{"template-punctuation":{pattern:/^`|`$/,alias:"string"},interpolation:{pattern:/((?:^|[^\\])(?:\\{2})*)\$\{(?:[^{}]|\{(?:[^{}]|\{[^}]*\})*\})+\}/,lookbehind:!0,inside:{"interpolation-punctuation":{pattern:/^\$\{|\}$/,alias:"punctuation"},rest:Prism.languages.javascript}},string:/[\s\S]+/}},"string-property":{pattern:/((?:^|[,{])[ \t]*)(["'])(?:\\(?:\r\n|[\s\S])|(?!\2)[^\\\r\n])*\2(?=\s*:)/m,lookbehind:!0,greedy:!0,alias:"property"}}),Prism.languages.insertBefore("javascript","operator",{"literal-property":{pattern:/((?:^|[,{])[ \t]*)(?!\s)[_$a-zA-Z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*(?=\s*:)/m,lookbehind:!0,alias:"property"}}),Prism.languages.markup&&(Prism.languages.markup.tag.addInlined("script","javascript"),Prism.languages.markup.tag.addAttribute("on(?:abort|blur|change|click|composition(?:end|start|update)|dblclick|error|focus(?:in|out)?|key(?:down|up)|load|mouse(?:down|enter|leave|move|out|over|up)|reset|resize|scroll|select|slotchange|submit|unload|wheel)","javascript")),Prism.languages.js=Prism.languages.javascript;
104
+
105
+ </script>
106
+ <script>
107
+ // Function to highlight code using Prism.js library
108
+ function highlightCode() {
109
+ Prism.highlightAllUnder(document.querySelector(".code-block"));
110
+ }
111
+
112
+ // Call the highlightCode function when the page loads
113
+ window.addEventListener("DOMContentLoaded", highlightCode);
114
+ </script>
115
+ </body>
116
+
117
+ </html>
@@ -1,26 +0,0 @@
1
- module.exports = {
2
- prod: {
3
- Bucket: 's3.eip.telegraph.co.uk',
4
- Folder: 'testFolder',
5
- targetFolder: 'test',
6
- Omit: [
7
- 'deployConf.js'
8
- ],
9
- data: {
10
- key1: "production1",
11
- key2: "production2"
12
- }
13
- },
14
- staging: {
15
- Bucket: 's3-staging.eip.telegraph.co.uk',
16
- cdnId: 'E2YWDG5C5WR01M',
17
- Folder: 'testFolder',
18
- Omit: [
19
- 'deployConf.js'
20
- ],
21
- data: {
22
- key1: "staging1",
23
- key2: "staging2"
24
- }
25
- }
26
- };
@@ -1,10 +0,0 @@
1
- {
2
- "staging": {
3
- "/Users/ollie/workspace/olivers-tools/eip-s3-deploy/test/file1.txt": "f5b5ed0c72f4e9984c3e7a8b18c08c2b",
4
- "/Users/ollie/workspace/olivers-tools/eip-s3-deploy/test/file2.txt": "d41d8cd98f00b204e9800998ecf8427e",
5
- "/Users/ollie/workspace/olivers-tools/eip-s3-deploy/test/folder1/file1.txt": "d41d8cd98f00b204e9800998ecf8427e",
6
- "/Users/ollie/workspace/olivers-tools/eip-s3-deploy/test/folder1/file2.txt": "d41d8cd98f00b204e9800998ecf8427e",
7
- "/Users/ollie/workspace/olivers-tools/eip-s3-deploy/test/folder2/file1.txt": "d41d8cd98f00b204e9800998ecf8427e",
8
- "/Users/ollie/workspace/olivers-tools/eip-s3-deploy/test/folder2/file2.txt": "d41d8cd98f00b204e9800998ecf8427e"
9
- }
10
- }