apostrophe 3.30.0 → 3.32.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/.eslintrc +3 -0
- package/CHANGELOG.md +26 -0
- package/modules/@apostrophecms/area/index.js +6 -0
- package/modules/@apostrophecms/area/ui/apos/components/AposAreaEditor.vue +18 -2
- package/modules/@apostrophecms/asset/index.js +65 -7
- package/modules/@apostrophecms/asset/lib/webpack/utils.js +242 -28
- package/modules/@apostrophecms/doc-type/ui/apos/components/AposDocEditor.vue +26 -16
- package/modules/@apostrophecms/i18n/i18n/en.json +19 -3
- package/modules/@apostrophecms/i18n/i18n/es.json +3 -0
- package/modules/@apostrophecms/i18n/i18n/fr.json +3 -0
- package/modules/@apostrophecms/i18n/i18n/pt-BR.json +4 -1
- package/modules/@apostrophecms/i18n/i18n/sk.json +3 -0
- package/modules/@apostrophecms/i18n/ui/apos/components/AposI18nLocalize.vue +41 -20
- package/modules/@apostrophecms/image-widget/index.js +4 -1
- package/modules/@apostrophecms/image-widget/public/placeholder.jpg +0 -0
- package/modules/@apostrophecms/image-widget/ui/src/index.scss +3 -0
- package/modules/@apostrophecms/image-widget/views/widget.html +35 -27
- package/modules/@apostrophecms/login/index.js +123 -26
- package/modules/@apostrophecms/login/ui/apos/components/AposForgotPasswordForm.vue +124 -0
- package/modules/@apostrophecms/login/ui/apos/components/AposLoginForm.vue +339 -0
- package/modules/@apostrophecms/login/ui/apos/components/AposResetPasswordForm.vue +163 -0
- package/modules/@apostrophecms/login/ui/apos/components/TheAposLogin.vue +135 -293
- package/modules/@apostrophecms/login/ui/apos/components/TheAposLoginHeader.vue +65 -14
- package/modules/@apostrophecms/login/ui/apos/mixins/AposLoginFormMixin.js +45 -0
- package/modules/@apostrophecms/login/views/passwordResetEmail.html +9 -0
- package/modules/@apostrophecms/modal/ui/apos/components/AposModal.vue +17 -6
- package/modules/@apostrophecms/modal/ui/apos/components/AposModalBody.vue +4 -1
- package/modules/@apostrophecms/modal/ui/apos/components/AposModalTabs.vue +7 -1
- package/modules/@apostrophecms/piece-type/index.js +1 -1
- package/modules/@apostrophecms/rich-text-widget/index.js +4 -1
- package/modules/@apostrophecms/rich-text-widget/ui/apos/components/AposRichTextWidgetEditor.vue +75 -12
- package/modules/@apostrophecms/rich-text-widget/ui/apos/tiptap-extensions/Default.js +11 -5
- package/modules/@apostrophecms/rich-text-widget/ui/apos/tiptap-extensions/Heading.js +6 -2
- package/modules/@apostrophecms/rich-text-widget/ui/apos/tiptap-extensions/Link.js +7 -4
- package/modules/@apostrophecms/schema/lib/addFieldTypes.js +1 -1
- package/modules/@apostrophecms/schema/ui/apos/components/AposInputWrapper.vue +4 -1
- package/modules/@apostrophecms/schema/ui/apos/components/AposSchema.vue +4 -0
- package/modules/@apostrophecms/template/index.js +11 -12
- package/modules/@apostrophecms/template/lib/bundlesLoader.js +20 -5
- package/modules/@apostrophecms/ui/ui/apos/mixins/AposAdvisoryLockMixin.js +2 -1
- package/modules/@apostrophecms/video-widget/index.js +4 -1
- package/modules/@apostrophecms/video-widget/views/widget.html +24 -16
- package/modules/@apostrophecms/widget-type/index.js +44 -8
- package/modules/@apostrophecms/widget-type/ui/apos/components/AposWidget.vue +5 -2
- package/modules/@apostrophecms/widget-type/ui/apos/mixins/AposWidgetMixin.js +11 -0
- package/package.json +6 -5
- package/test/assets.js +338 -25
- package/test/extra_node_modules/@company/bundle/index.js +8 -0
- package/test/extra_node_modules/@company/bundle/ui/src/company.js +3 -0
- package/test/extra_node_modules/@company/bundle/ui/src/company.scss +3 -0
- package/test/login.js +427 -12
- package/test/modules/@company/bundle/index.js +10 -0
- package/test/modules/@company/bundle/ui/src/company.js +3 -0
- package/test/modules/@company/bundle/ui/src/company.scss +3 -0
- package/test/modules/bundle-edge/index.js +10 -0
- package/test/modules/bundle-edge/ui/src/edge.js +3 -0
- package/test/modules/bundle-edge/ui/src/edge.scss +3 -0
- package/test/modules/bundle-page/index.js +2 -1
- package/test/modules/bundle-page/ui/src/extra.js +3 -1
- package/test/modules/bundle-page/ui/src/extra.scss +3 -0
- package/test/modules/bundle-page/ui/src/main.js +3 -0
- package/test/modules/bundle-page/ui/src/main.scss +3 -0
- package/test/modules/bundle-page-type/index.js +12 -0
- package/test/modules/bundle-page-type/ui/src/another.js +3 -0
- package/test/modules/bundle-page-type/ui/src/index.js +3 -0
- package/test/modules/bundle-page-type/ui/src/index.scss +3 -0
- package/test/modules/bundle-page-type/ui/src/main.js +3 -0
- package/test/modules/bundle-page-type/ui/src/main.scss +3 -0
- package/test/modules/bundle-widget/ui/src/extra2.js +3 -1
- package/test/modules/placeholder-page/index.js +21 -0
- package/test/modules/placeholder-page/views/page.html +3 -0
- package/test/modules/placeholder-widget/index.js +36 -0
- package/test/modules/placeholder-widget/views/widget.html +5 -0
- package/test/widgets.js +453 -114
- package/test-lib/test.js +9 -1
|
@@ -1,20 +1,28 @@
|
|
|
1
|
-
{% if data.options.
|
|
2
|
-
{% set className = data.options.className %}
|
|
3
|
-
{% elif data.manager.options.className %}
|
|
4
|
-
{% set className = data.manager.options.className %}
|
|
5
|
-
{% endif %}
|
|
6
|
-
|
|
7
|
-
{# oembed repopulates me #}
|
|
8
|
-
{% if data.widget.video %}
|
|
1
|
+
{% if data.widget.aposPlaceholder and data.manager.options.placeholderUrl %}
|
|
9
2
|
<div
|
|
10
|
-
{% if className %} class="{{ className }}"{% endif %}
|
|
11
3
|
data-apos-video-widget
|
|
12
|
-
data-apos-video-url={{ data.
|
|
4
|
+
data-apos-video-url="{{ data.manager.options.placeholderUrl }}"
|
|
13
5
|
>
|
|
14
|
-
{% if data.widget.video.thumbnail %}
|
|
15
|
-
<img src="{{ data.widget.video.thumbnail }}" alt="{{ data.widget.video.thumbnail }}"/>
|
|
16
|
-
{% endif %}
|
|
17
6
|
</div>
|
|
18
|
-
{%
|
|
19
|
-
|
|
20
|
-
{%
|
|
7
|
+
{% else %}
|
|
8
|
+
{% if data.options.className %}
|
|
9
|
+
{% set className = data.options.className %}
|
|
10
|
+
{% elif data.manager.options.className %}
|
|
11
|
+
{% set className = data.manager.options.className %}
|
|
12
|
+
{% endif %}
|
|
13
|
+
|
|
14
|
+
{# oembed repopulates me #}
|
|
15
|
+
{% if data.widget.video %}
|
|
16
|
+
<div
|
|
17
|
+
{% if className %} class="{{ className }}"{% endif %}
|
|
18
|
+
data-apos-video-widget
|
|
19
|
+
data-apos-video-url={{ data.widget.video.url }}
|
|
20
|
+
>
|
|
21
|
+
{% if data.widget.video.thumbnail %}
|
|
22
|
+
<img src="{{ data.widget.video.thumbnail }}" alt="{{ data.widget.video.thumbnail }}"/>
|
|
23
|
+
{% endif %}
|
|
24
|
+
</div>
|
|
25
|
+
{% elif data.user %}
|
|
26
|
+
<p {% if data.manager.options.className %} class="{{ data.manager.options.className }} {{ data.manager.options.className }}--error"{% endif %}>No video selected</p>
|
|
27
|
+
{% endif %}
|
|
28
|
+
{% endif %}
|
|
@@ -97,7 +97,10 @@ const _ = require('lodash');
|
|
|
97
97
|
module.exports = {
|
|
98
98
|
cascades: [ 'fields' ],
|
|
99
99
|
options: {
|
|
100
|
-
neverLoadSelf: true
|
|
100
|
+
neverLoadSelf: true,
|
|
101
|
+
initialModal: true,
|
|
102
|
+
placeholder: false,
|
|
103
|
+
placeholderClass: 'apos-placeholder'
|
|
101
104
|
},
|
|
102
105
|
init(self) {
|
|
103
106
|
|
|
@@ -161,8 +164,24 @@ module.exports = {
|
|
|
161
164
|
...self.getWidgetsBundles(`${widget.type}-widget`)
|
|
162
165
|
};
|
|
163
166
|
|
|
167
|
+
let effectiveWidget = widget;
|
|
168
|
+
|
|
169
|
+
if (widget.aposPlaceholder === true) {
|
|
170
|
+
// Do not render widget on preview mode:
|
|
171
|
+
if (req.query.aposEdit !== '1') {
|
|
172
|
+
return '';
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
effectiveWidget = { ...widget };
|
|
176
|
+
self.schema.forEach(field => {
|
|
177
|
+
if (field.placeholder !== undefined) {
|
|
178
|
+
effectiveWidget[field.name] = field.placeholder;
|
|
179
|
+
}
|
|
180
|
+
});
|
|
181
|
+
}
|
|
182
|
+
|
|
164
183
|
return self.render(req, self.template, {
|
|
165
|
-
widget:
|
|
184
|
+
widget: effectiveWidget,
|
|
166
185
|
options: options,
|
|
167
186
|
manager: self,
|
|
168
187
|
contextOptions: _with
|
|
@@ -176,11 +195,25 @@ module.exports = {
|
|
|
176
195
|
return {};
|
|
177
196
|
}
|
|
178
197
|
|
|
179
|
-
|
|
180
|
-
|
|
198
|
+
const { rebundleModules } = self.apos.asset;
|
|
199
|
+
|
|
200
|
+
const rebundleConfigs = rebundleModules.filter(entry => {
|
|
201
|
+
const names = widget.__meta?.chain?.map(c => c.name) ?? [ widgetType ];
|
|
202
|
+
return names.includes(entry.name);
|
|
203
|
+
});
|
|
204
|
+
|
|
205
|
+
return Object.entries(widget.__meta.webpack || {})
|
|
206
|
+
.reduce((acc, [ moduleName, config ]) => {
|
|
207
|
+
if (!config || !config.bundles) {
|
|
208
|
+
return acc;
|
|
209
|
+
}
|
|
181
210
|
return {
|
|
182
211
|
...acc,
|
|
183
|
-
...
|
|
212
|
+
...self.apos.asset.transformRebundledFor(
|
|
213
|
+
moduleName,
|
|
214
|
+
config.bundles,
|
|
215
|
+
rebundleConfigs
|
|
216
|
+
)
|
|
184
217
|
};
|
|
185
218
|
}, {});
|
|
186
219
|
},
|
|
@@ -276,11 +309,14 @@ module.exports = {
|
|
|
276
309
|
// Make sure we get default values for contextual fields so
|
|
277
310
|
// `by` doesn't go missing for `@apostrophecms/image-widget`
|
|
278
311
|
const output = self.apos.schema.newInstance(self.schema);
|
|
279
|
-
const schema = self.allowedSchema(req);
|
|
280
312
|
output._id = self.apos.launder.id(input._id) || self.apos.util.generateId();
|
|
281
|
-
await self.apos.schema.convert(req, schema, input, output);
|
|
282
313
|
output.metaType = 'widget';
|
|
283
314
|
output.type = self.name;
|
|
315
|
+
output.aposPlaceholder = self.apos.launder.boolean(input.aposPlaceholder);
|
|
316
|
+
if (!output.aposPlaceholder) {
|
|
317
|
+
const schema = self.allowedSchema(req);
|
|
318
|
+
await self.apos.schema.convert(req, schema, input, output);
|
|
319
|
+
}
|
|
284
320
|
return output;
|
|
285
321
|
},
|
|
286
322
|
|
|
@@ -352,7 +388,7 @@ module.exports = {
|
|
|
352
388
|
action: self.action,
|
|
353
389
|
schema: schema,
|
|
354
390
|
contextual: self.options.contextual,
|
|
355
|
-
|
|
391
|
+
placeholderClass: self.options.placeholderClass,
|
|
356
392
|
className: self.options.className,
|
|
357
393
|
components: self.options.components
|
|
358
394
|
});
|
|
@@ -62,6 +62,17 @@ export default {
|
|
|
62
62
|
this.rendered = '<p>Unable to render this widget.</p>';
|
|
63
63
|
console.error('Unable to render widget. Possibly the schema has been changed and the existing widget does not pass validation.', e);
|
|
64
64
|
}
|
|
65
|
+
},
|
|
66
|
+
getClasses() {
|
|
67
|
+
const { placeholderClass } = this.moduleOptions;
|
|
68
|
+
|
|
69
|
+
if (!placeholderClass) {
|
|
70
|
+
return {};
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
return {
|
|
74
|
+
[placeholderClass]: this.value.aposPlaceholder === true
|
|
75
|
+
};
|
|
65
76
|
}
|
|
66
77
|
}
|
|
67
78
|
};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "apostrophe",
|
|
3
|
-
"version": "3.
|
|
3
|
+
"version": "3.32.0",
|
|
4
4
|
"description": "The Apostrophe Content Management System.",
|
|
5
5
|
"main": "index.js",
|
|
6
6
|
"scripts": {
|
|
@@ -35,6 +35,7 @@
|
|
|
35
35
|
"@opentelemetry/semantic-conventions": "^1.0.1",
|
|
36
36
|
"@tiptap/extension-highlight": "^2.0.0-beta.33",
|
|
37
37
|
"@tiptap/extension-link": "^2.0.0-beta.38",
|
|
38
|
+
"@tiptap/extension-placeholder": "^2.0.0-beta.196",
|
|
38
39
|
"@tiptap/extension-text-align": "^2.0.0-beta.29",
|
|
39
40
|
"@tiptap/extension-text-style": "^2.0.0-beta.23",
|
|
40
41
|
"@tiptap/extension-underline": "^2.0.0-beta.23",
|
|
@@ -124,16 +125,16 @@
|
|
|
124
125
|
"eslint-config-apostrophe": "^3.4.0",
|
|
125
126
|
"eslint-plugin-n": "^15.2.1",
|
|
126
127
|
"eslint-plugin-node": "^11.1.0",
|
|
128
|
+
"eslint-plugin-promise": "^5.1.0",
|
|
127
129
|
"eslint-plugin-vue": "^7.9.0",
|
|
128
130
|
"mocha": "^9.1.2",
|
|
129
131
|
"nyc": "^15.1.0",
|
|
130
132
|
"replace-in-file": "^6.1.0",
|
|
131
|
-
"vue-eslint-parser": "^7.1.1",
|
|
132
|
-
"webpack-bundle-analyzer": "^3.9.0",
|
|
133
|
-
"eslint-plugin-promise": "^5.1.0",
|
|
134
133
|
"stylelint": "^14.6.1",
|
|
135
134
|
"stylelint-declaration-strict-value": "^1.8.0",
|
|
136
|
-
"stylelint-order": "^5.0.0"
|
|
135
|
+
"stylelint-order": "^5.0.0",
|
|
136
|
+
"vue-eslint-parser": "^7.1.1",
|
|
137
|
+
"webpack-bundle-analyzer": "^3.9.0"
|
|
137
138
|
},
|
|
138
139
|
"browserslist": [
|
|
139
140
|
"ie >= 10"
|
package/test/assets.js
CHANGED
|
@@ -6,6 +6,8 @@ const Promise = require('bluebird');
|
|
|
6
6
|
|
|
7
7
|
const {
|
|
8
8
|
checkModulesWebpackConfig,
|
|
9
|
+
formatRebundleConfig,
|
|
10
|
+
verifyRebundleConfig,
|
|
9
11
|
getWebpackExtensions,
|
|
10
12
|
fillExtraBundles
|
|
11
13
|
} = require('../modules/@apostrophecms/asset/lib/webpack/utils');
|
|
@@ -99,7 +101,12 @@ describe('Assets', function() {
|
|
|
99
101
|
after(async function() {
|
|
100
102
|
await deleteBuiltFolders(publicFolderPath, true);
|
|
101
103
|
await removeCache();
|
|
102
|
-
|
|
104
|
+
await t.destroy(apos);
|
|
105
|
+
});
|
|
106
|
+
|
|
107
|
+
afterEach(function() {
|
|
108
|
+
// Prevent hang forever if particular tests fail while testing prod.
|
|
109
|
+
process.env.NODE_ENV = 'development';
|
|
103
110
|
});
|
|
104
111
|
|
|
105
112
|
this.timeout(5 * 60 * 1000);
|
|
@@ -136,13 +143,16 @@ describe('Assets', function() {
|
|
|
136
143
|
|
|
137
144
|
it('should get webpack extensions from modules and fill extra bundles', async function () {
|
|
138
145
|
const expectedEntryPointsNames = {
|
|
139
|
-
js: [ 'extra', 'extra2' ],
|
|
140
|
-
css: [ 'extra' ]
|
|
146
|
+
js: [ 'company', 'main', 'another', 'extra', 'extra2' ],
|
|
147
|
+
css: [ 'company', 'main', 'extra' ]
|
|
141
148
|
};
|
|
142
149
|
|
|
143
150
|
apos = await t.create({
|
|
144
151
|
root: module,
|
|
145
|
-
modules
|
|
152
|
+
modules: {
|
|
153
|
+
'@company/bundle': {},
|
|
154
|
+
...modules
|
|
155
|
+
}
|
|
146
156
|
});
|
|
147
157
|
|
|
148
158
|
const {
|
|
@@ -158,23 +168,28 @@ describe('Assets', function() {
|
|
|
158
168
|
assert(extensions.ext1.resolve.alias.ext1Overriden);
|
|
159
169
|
assert(extensions.ext2.resolve.alias.ext2);
|
|
160
170
|
|
|
161
|
-
assert
|
|
171
|
+
assert.equal(
|
|
172
|
+
Object.keys(verifiedBundles).length,
|
|
173
|
+
Math.max(expectedEntryPointsNames.js.length, expectedEntryPointsNames.css.length)
|
|
174
|
+
);
|
|
162
175
|
|
|
163
|
-
assert(verifiedBundles.
|
|
164
|
-
assert(verifiedBundles.
|
|
176
|
+
assert(verifiedBundles.main.js.length, 2);
|
|
177
|
+
assert(verifiedBundles.main.scss.length, 1);
|
|
165
178
|
|
|
166
|
-
|
|
167
|
-
assert(verifiedBundles.
|
|
179
|
+
// The local and the npm module source
|
|
180
|
+
assert.equal(verifiedBundles.company.js.length, 2);
|
|
181
|
+
assert.equal(verifiedBundles.company.scss.length, 2);
|
|
168
182
|
|
|
169
|
-
|
|
183
|
+
assert.equal(verifiedBundles.extra.js.length, 1);
|
|
184
|
+
assert.equal(verifiedBundles.extra.scss.length, 1);
|
|
170
185
|
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
});
|
|
186
|
+
assert.equal(verifiedBundles.extra2.js.length, 1);
|
|
187
|
+
assert.equal(verifiedBundles.extra2.scss.length, 0);
|
|
174
188
|
|
|
175
|
-
filled
|
|
176
|
-
|
|
177
|
-
|
|
189
|
+
const filled = fillExtraBundles(verifiedBundles);
|
|
190
|
+
|
|
191
|
+
assert.deepEqual(filled.js, expectedEntryPointsNames.js);
|
|
192
|
+
assert.deepEqual(filled.css, expectedEntryPointsNames.css);
|
|
178
193
|
});
|
|
179
194
|
|
|
180
195
|
it('should build the right bundles in dev and prod modes', async function () {
|
|
@@ -214,18 +229,22 @@ describe('Assets', function() {
|
|
|
214
229
|
const bundlePage = await apos.http.get('/bundle', { jar });
|
|
215
230
|
|
|
216
231
|
assert(bundlePage.includes(getStylesheetMarkup('public-bundle')));
|
|
232
|
+
assert(bundlePage.includes(getStylesheetMarkup('main-bundle')));
|
|
217
233
|
assert(!bundlePage.includes(getStylesheetMarkup('extra-bundle')));
|
|
218
234
|
|
|
219
235
|
assert(bundlePage.includes(getScriptMarkup('public-module-bundle')));
|
|
236
|
+
assert(bundlePage.includes(getScriptMarkup('main-module-bundle')));
|
|
220
237
|
assert(!bundlePage.includes(getScriptMarkup('extra-module-bundle')));
|
|
221
238
|
assert(bundlePage.includes(getScriptMarkup('extra2-module-bundle')));
|
|
222
239
|
|
|
223
240
|
const childPage = await apos.http.get('/bundle/child', { jar });
|
|
224
241
|
|
|
225
242
|
assert(childPage.includes(getStylesheetMarkup('public-bundle')));
|
|
243
|
+
assert(bundlePage.includes(getStylesheetMarkup('main-bundle')));
|
|
226
244
|
assert(childPage.includes(getStylesheetMarkup('extra-bundle')));
|
|
227
245
|
|
|
228
246
|
assert(childPage.includes(getScriptMarkup('public-module-bundle')));
|
|
247
|
+
assert(bundlePage.includes(getScriptMarkup('main-module-bundle')));
|
|
229
248
|
assert(childPage.includes(getScriptMarkup('extra-module-bundle')));
|
|
230
249
|
assert(!childPage.includes(getScriptMarkup('extra2-module-bundle')));
|
|
231
250
|
});
|
|
@@ -472,7 +491,7 @@ describe('Assets', function() {
|
|
|
472
491
|
// Modify asset and rebuild
|
|
473
492
|
const assetPath = path.join(process.cwd(), 'test/modules/bundle-page/ui/src/extra.js');
|
|
474
493
|
const assetPathPublic = path.join(process.cwd(), 'test/public/apos-frontend/default/extra-module-bundle.js');
|
|
475
|
-
const assetContent =
|
|
494
|
+
const assetContent = fs.readFileSync(assetPath, 'utf-8');
|
|
476
495
|
fs.writeFileSync(
|
|
477
496
|
assetPath,
|
|
478
497
|
'export default () => { \'bundle-page-watcher-test-src\'; };\n',
|
|
@@ -526,8 +545,8 @@ describe('Assets', function() {
|
|
|
526
545
|
const assetPathPublicCss = path.join(rootPath, 'test/public/apos-frontend/default/public-bundle.css');
|
|
527
546
|
const assetPathAposJs = path.join(rootPath, 'test/public/apos-frontend/default/apos-module-bundle.js');
|
|
528
547
|
const assetPathAposCss = path.join(rootPath, 'test/public/apos-frontend/default/apos-bundle.css');
|
|
529
|
-
const assetContentJs =
|
|
530
|
-
const assetContentScss =
|
|
548
|
+
const assetContentJs = fs.readFileSync(assetPathJs, 'utf-8');
|
|
549
|
+
const assetContentScss = fs.readFileSync(assetPathScss, 'utf-8');
|
|
531
550
|
// Resurrect the default assets content if test has failed
|
|
532
551
|
fs.writeFileSync(assetPathJs, assetContentJs, 'utf8');
|
|
533
552
|
fs.writeFileSync(assetPathScss, assetContentScss, 'utf8');
|
|
@@ -647,8 +666,8 @@ describe('Assets', function() {
|
|
|
647
666
|
const assetPathPublicCss = path.join(rootPath, 'test/public/apos-frontend/default/public-bundle.css');
|
|
648
667
|
const assetPathAposJs = path.join(rootPath, 'test/public/apos-frontend/default/apos-module-bundle.js');
|
|
649
668
|
const assetPathAposCss = path.join(rootPath, 'test/public/apos-frontend/default/apos-bundle.css');
|
|
650
|
-
const assetContentJs =
|
|
651
|
-
const assetContentScss =
|
|
669
|
+
const assetContentJs = fs.readFileSync(assetPathJs, 'utf-8');
|
|
670
|
+
const assetContentScss = fs.readFileSync(assetPathCss, 'utf-8');
|
|
652
671
|
// Resurrect the default assets content if test has failed
|
|
653
672
|
fs.writeFileSync(assetPathJs, assetContentJs, 'utf8');
|
|
654
673
|
fs.writeFileSync(assetPathCss, assetContentScss, 'utf8');
|
|
@@ -982,8 +1001,8 @@ describe('Assets', function() {
|
|
|
982
1001
|
const assetPathPublicCss = path.join(rootPath, 'test/public/apos-frontend/default/public-bundle.css');
|
|
983
1002
|
const assetPathAposJs = path.join(rootPath, 'test/public/apos-frontend/default/apos-module-bundle.js');
|
|
984
1003
|
const assetPathAposCss = path.join(rootPath, 'test/public/apos-frontend/default/apos-bundle.css');
|
|
985
|
-
const assetContentJs =
|
|
986
|
-
const assetContentScss =
|
|
1004
|
+
const assetContentJs = fs.readFileSync(assetPathJs, 'utf-8');
|
|
1005
|
+
const assetContentScss = fs.readFileSync(assetPathScss, 'utf-8');
|
|
987
1006
|
// Resurrect the default assets content if test has failed
|
|
988
1007
|
fs.writeFileSync(assetPathJs, assetContentJs, 'utf8');
|
|
989
1008
|
fs.writeFileSync(assetPathScss, assetContentScss, 'utf8');
|
|
@@ -1124,7 +1143,7 @@ describe('Assets', function() {
|
|
|
1124
1143
|
|
|
1125
1144
|
const assetPath = path.join(process.cwd(), 'test/modules/bundle-page/ui/src/extra.js');
|
|
1126
1145
|
const assetPathPublic = path.join(process.cwd(), 'test/public/apos-frontend/default/extra-module-bundle.js');
|
|
1127
|
-
const assetContent =
|
|
1146
|
+
const assetContent = fs.readFileSync(assetPath, 'utf-8');
|
|
1128
1147
|
|
|
1129
1148
|
// Modify below the debounce rate
|
|
1130
1149
|
for (const i of [ 1, 2, 3 ]) {
|
|
@@ -1330,6 +1349,289 @@ describe('Assets', function() {
|
|
|
1330
1349
|
|
|
1331
1350
|
assertWebpackExtensionOptions(extensions, extensionOptions);
|
|
1332
1351
|
});
|
|
1352
|
+
|
|
1353
|
+
it('should verify that asset re-bundle configs are valid', async function () {
|
|
1354
|
+
assert.doesNotThrow(() => verifyRebundleConfig());
|
|
1355
|
+
assert.doesNotThrow(() => verifyRebundleConfig([]));
|
|
1356
|
+
assert.doesNotThrow(() => formatRebundleConfig());
|
|
1357
|
+
assert.doesNotThrow(() => formatRebundleConfig({}));
|
|
1358
|
+
|
|
1359
|
+
assert.doesNotThrow(() => formatRebundleConfig({
|
|
1360
|
+
'bundle-page': 'main',
|
|
1361
|
+
'bundle-page-type': 'new',
|
|
1362
|
+
'bundle-widget:extra': 'widget',
|
|
1363
|
+
'@company/bundle:company': 'newcompany',
|
|
1364
|
+
'bundle-edge:edge': 'main'
|
|
1365
|
+
}));
|
|
1366
|
+
|
|
1367
|
+
// too much catch-all
|
|
1368
|
+
assert.throws(() => formatRebundleConfig({
|
|
1369
|
+
'bundle-page': 'main',
|
|
1370
|
+
'bundle-page:extra': 'new'
|
|
1371
|
+
}));
|
|
1372
|
+
assert.throws(() => formatRebundleConfig({
|
|
1373
|
+
'bundle-page:extra': 'new',
|
|
1374
|
+
'bundle-page': 'main'
|
|
1375
|
+
}));
|
|
1376
|
+
assert.throws(() => formatRebundleConfig({
|
|
1377
|
+
'bundle-page': 'main',
|
|
1378
|
+
'bundle-page:extra': 'main'
|
|
1379
|
+
}));
|
|
1380
|
+
assert.throws(() => formatRebundleConfig({
|
|
1381
|
+
'bundle-page': 'new',
|
|
1382
|
+
'bundle-page:extra': 'another'
|
|
1383
|
+
}));
|
|
1384
|
+
assert.throws(() => formatRebundleConfig({
|
|
1385
|
+
'bundle-page:extra': 'another',
|
|
1386
|
+
'bundle-page': 'new'
|
|
1387
|
+
}));
|
|
1388
|
+
});
|
|
1389
|
+
|
|
1390
|
+
it('should build and remap the right bundles in dev and prod modes', async function () {
|
|
1391
|
+
await t.destroy(apos);
|
|
1392
|
+
const getPath = (p) => `${publicFolderPath}/apos-frontend/` + p;
|
|
1393
|
+
const checkFileExists = async (p) => fs.pathExists(getPath(p));
|
|
1394
|
+
async function checkBundlesExists (folderPath, fileNames) {
|
|
1395
|
+
for (const fileName of fileNames) {
|
|
1396
|
+
const extraBundleExists = await checkFileExists(folderPath + fileName);
|
|
1397
|
+
assert(extraBundleExists);
|
|
1398
|
+
}
|
|
1399
|
+
}
|
|
1400
|
+
function checkBundlesContents (folderPath, bundles, not = false) {
|
|
1401
|
+
for (const [ fileName, regexes ] of Object.entries(bundles)) {
|
|
1402
|
+
const contents = fs.readFileSync(getPath(folderPath + fileName), 'utf-8');
|
|
1403
|
+
for (const regex of regexes) {
|
|
1404
|
+
const method = not ? 'doesNotMatch' : 'match';
|
|
1405
|
+
assert[method](contents, new RegExp(regex), `${fileName} - ${regex}`);
|
|
1406
|
+
}
|
|
1407
|
+
}
|
|
1408
|
+
}
|
|
1409
|
+
|
|
1410
|
+
apos = await t.create({
|
|
1411
|
+
root: module,
|
|
1412
|
+
modules: {
|
|
1413
|
+
'@company/bundle': {},
|
|
1414
|
+
'bundle-edge': {},
|
|
1415
|
+
...modules,
|
|
1416
|
+
'@apostrophecms/asset': {
|
|
1417
|
+
options: {
|
|
1418
|
+
rebundleModules: {
|
|
1419
|
+
// Everything from the `bundle-page` module should
|
|
1420
|
+
// go in the regular "main" bundle
|
|
1421
|
+
'bundle-page': 'main',
|
|
1422
|
+
// all from `bundle-page-type` should go
|
|
1423
|
+
// in a new bundle 'bundle-page'
|
|
1424
|
+
'bundle-page-type': 'new',
|
|
1425
|
+
// 'extra2' bundle from `bundle-widget` should go
|
|
1426
|
+
// in a new bundle 'widget-bundle'
|
|
1427
|
+
'bundle-widget:extra2': 'widget',
|
|
1428
|
+
// 'company' bundle from `@company/bundle:company` should go
|
|
1429
|
+
// in a new bundle 'newcompany'. The local module contribution
|
|
1430
|
+
// to the 'company' build should stay.
|
|
1431
|
+
'@company/bundle:company': 'newcompany',
|
|
1432
|
+
// Edge case - send "edge" bundle only to the main bundle
|
|
1433
|
+
'bundle-edge:edge': 'main'
|
|
1434
|
+
}
|
|
1435
|
+
}
|
|
1436
|
+
}
|
|
1437
|
+
}
|
|
1438
|
+
});
|
|
1439
|
+
|
|
1440
|
+
const existingBundleNames = [
|
|
1441
|
+
'public-module-bundle.js',
|
|
1442
|
+
'public-bundle.css',
|
|
1443
|
+
'new-module-bundle.js',
|
|
1444
|
+
'new-bundle.css',
|
|
1445
|
+
'company-module-bundle.js',
|
|
1446
|
+
'company-bundle.css',
|
|
1447
|
+
'newcompany-module-bundle.js',
|
|
1448
|
+
'newcompany-bundle.css',
|
|
1449
|
+
'widget-module-bundle.js'
|
|
1450
|
+
];
|
|
1451
|
+
const bundleContents = {
|
|
1452
|
+
'public-module-bundle.js': [
|
|
1453
|
+
/BUNDLE_MAIN_PAGE['"]+/g,
|
|
1454
|
+
/BUNDLE_EXTRA_PAGE['"]+/g,
|
|
1455
|
+
/BUNDLE_EDGE['"]+/g
|
|
1456
|
+
],
|
|
1457
|
+
'public-bundle.css': [
|
|
1458
|
+
/\.main-page[\s]*\{/g,
|
|
1459
|
+
/\.extra-page[\s]*\{/g,
|
|
1460
|
+
/\.edge[\s]*\{/g
|
|
1461
|
+
],
|
|
1462
|
+
'new-module-bundle.js': [
|
|
1463
|
+
/BUNDLE_INDEX_PAGE_TYPE['"]+/g,
|
|
1464
|
+
/BUNDLE_ANOTHER_PAGE_TYPE['"]+/g,
|
|
1465
|
+
/BUNDLE_MAIN_PAGE_TYPE['"]+/g
|
|
1466
|
+
],
|
|
1467
|
+
'new-bundle.css': [
|
|
1468
|
+
/\.index-page-type[\s]*\{/g,
|
|
1469
|
+
/\.main-page-type[\s]*\{/g
|
|
1470
|
+
],
|
|
1471
|
+
'company-module-bundle.js': [
|
|
1472
|
+
/BUNDLE_OVERRIDE_COMPANY['"]+/g
|
|
1473
|
+
],
|
|
1474
|
+
'company-bundle.css': [
|
|
1475
|
+
/\.override-company[\s]*\{/g
|
|
1476
|
+
],
|
|
1477
|
+
'newcompany-module-bundle.js': [
|
|
1478
|
+
/BUNDLE_COMPANY['"]+/g
|
|
1479
|
+
],
|
|
1480
|
+
'newcompany-bundle.css': [
|
|
1481
|
+
/\.company[\s]*\{/g
|
|
1482
|
+
],
|
|
1483
|
+
'widget-module-bundle.js': [
|
|
1484
|
+
/BUNDLE_WIDGET_EXTRA2['"]+/g
|
|
1485
|
+
]
|
|
1486
|
+
};
|
|
1487
|
+
const bundleNoDuplicateContents = {
|
|
1488
|
+
'public-module-bundle.js': [
|
|
1489
|
+
/BUNDLE_COMPANY['"]+/g,
|
|
1490
|
+
/BUNDLE_WIDGET_EXTRA2['"]+/g,
|
|
1491
|
+
/BUNDLE_OVERRIDE_COMPANY['"]+/g,
|
|
1492
|
+
/BUNDLE_MAIN_PAGE_TYPE['"]+/g,
|
|
1493
|
+
/BUNDLE_ANOTHER_PAGE_TYPE['"]+/g,
|
|
1494
|
+
/BUNDLE_INDEX_PAGE_TYPE['"]+/g
|
|
1495
|
+
],
|
|
1496
|
+
'public-bundle.css': [
|
|
1497
|
+
/\.main-page-type[\s]*\{/g,
|
|
1498
|
+
/\.override-company[\s]*\{/g,
|
|
1499
|
+
/\.company[\s]*\{/g
|
|
1500
|
+
]
|
|
1501
|
+
};
|
|
1502
|
+
const nonExistingBundleNames = [
|
|
1503
|
+
'main-module-bundle.js',
|
|
1504
|
+
'extra-module-bundle.js',
|
|
1505
|
+
'extra2-module-bundle.js',
|
|
1506
|
+
'edge-module-bundle.js',
|
|
1507
|
+
'main-bundle.css',
|
|
1508
|
+
'extra-bundle.css',
|
|
1509
|
+
'edge-bundle.css'
|
|
1510
|
+
];
|
|
1511
|
+
|
|
1512
|
+
process.env.NODE_ENV = 'production';
|
|
1513
|
+
await deleteBuiltFolders(publicFolderPath, true);
|
|
1514
|
+
await apos.asset.tasks.build.task();
|
|
1515
|
+
{
|
|
1516
|
+
const [ releaseId ] = await fs.readdir(getPath('releases'));
|
|
1517
|
+
const releasePath = `releases/${releaseId}/default/`;
|
|
1518
|
+
await checkBundlesExists(releasePath, existingBundleNames);
|
|
1519
|
+
checkBundlesContents(releasePath, bundleContents);
|
|
1520
|
+
checkBundlesContents(releasePath, bundleNoDuplicateContents, true);
|
|
1521
|
+
for (const file of nonExistingBundleNames) {
|
|
1522
|
+
assert.throws(() => fs.readFileSync(releasePath + file), {
|
|
1523
|
+
code: 'ENOENT'
|
|
1524
|
+
}, file);
|
|
1525
|
+
}
|
|
1526
|
+
}
|
|
1527
|
+
|
|
1528
|
+
process.env.NODE_ENV = 'development';
|
|
1529
|
+
await deleteBuiltFolders(publicFolderPath, true);
|
|
1530
|
+
await apos.asset.tasks.build.task();
|
|
1531
|
+
{
|
|
1532
|
+
const releasePath = getPath('default/');
|
|
1533
|
+
await checkBundlesExists('default/', existingBundleNames);
|
|
1534
|
+
checkBundlesContents('default/', bundleContents);
|
|
1535
|
+
checkBundlesContents('default/', bundleNoDuplicateContents, true);
|
|
1536
|
+
for (const file of nonExistingBundleNames) {
|
|
1537
|
+
assert.throws(() => fs.readFileSync(releasePath + file), {
|
|
1538
|
+
code: 'ENOENT'
|
|
1539
|
+
}, file);
|
|
1540
|
+
}
|
|
1541
|
+
}
|
|
1542
|
+
});
|
|
1543
|
+
|
|
1544
|
+
it('should load the right remapped bundles inside the right page', async function () {
|
|
1545
|
+
await t.destroy(apos);
|
|
1546
|
+
apos = await t.create({
|
|
1547
|
+
root: module,
|
|
1548
|
+
modules: {
|
|
1549
|
+
'@company/bundle': {},
|
|
1550
|
+
'bundle-edge': {},
|
|
1551
|
+
...modules,
|
|
1552
|
+
'@apostrophecms/asset': {
|
|
1553
|
+
options: {
|
|
1554
|
+
rebundleModules: {
|
|
1555
|
+
'bundle-page': 'main',
|
|
1556
|
+
'bundle-page-type': 'new',
|
|
1557
|
+
'bundle-widget:extra2': 'widget',
|
|
1558
|
+
'@company/bundle:company': 'newcompany'
|
|
1559
|
+
}
|
|
1560
|
+
}
|
|
1561
|
+
}
|
|
1562
|
+
}
|
|
1563
|
+
});
|
|
1564
|
+
|
|
1565
|
+
const { _id: homeId } = await apos.page
|
|
1566
|
+
.find(apos.task.getAnonReq(), { level: 0 })
|
|
1567
|
+
.toObject();
|
|
1568
|
+
const jar = apos.http.jar();
|
|
1569
|
+
|
|
1570
|
+
await apos.doc.db.insertMany(pagesToInsert(homeId));
|
|
1571
|
+
|
|
1572
|
+
const bundlePage = await apos.http.get('/bundle', { jar });
|
|
1573
|
+
|
|
1574
|
+
assert(bundlePage.includes(getStylesheetMarkup('public-bundle')));
|
|
1575
|
+
assert(bundlePage.includes(getStylesheetMarkup('new-bundle')));
|
|
1576
|
+
assert(!bundlePage.includes(getStylesheetMarkup('main-bundle')));
|
|
1577
|
+
assert(!bundlePage.includes(getStylesheetMarkup('extra-bundle')));
|
|
1578
|
+
assert(!bundlePage.includes(getStylesheetMarkup('extra2-bundle')));
|
|
1579
|
+
assert(!bundlePage.includes(getStylesheetMarkup('newcompany-bundle')));
|
|
1580
|
+
assert(!bundlePage.includes(getStylesheetMarkup('company-bundle')));
|
|
1581
|
+
|
|
1582
|
+
assert(bundlePage.includes(getScriptMarkup('public-module-bundle')));
|
|
1583
|
+
assert(bundlePage.includes(getScriptMarkup('new-module-bundle')));
|
|
1584
|
+
assert(bundlePage.includes(getScriptMarkup('widget-module-bundle')));
|
|
1585
|
+
assert(!bundlePage.includes(getScriptMarkup('main-module-bundle')));
|
|
1586
|
+
assert(!bundlePage.includes(getScriptMarkup('extra-module-bundle')));
|
|
1587
|
+
assert(!bundlePage.includes(getScriptMarkup('extra2-module-bundle')));
|
|
1588
|
+
assert(!bundlePage.includes(getStylesheetMarkup('newcompany-bundle')));
|
|
1589
|
+
assert(!bundlePage.includes(getStylesheetMarkup('company-bundle')));
|
|
1590
|
+
|
|
1591
|
+
const childPage = await apos.http.get('/bundle/child', { jar });
|
|
1592
|
+
|
|
1593
|
+
assert(childPage.includes(getStylesheetMarkup('public-bundle')));
|
|
1594
|
+
assert(childPage.includes(getStylesheetMarkup('new-bundle')));
|
|
1595
|
+
assert(!childPage.includes(getStylesheetMarkup('main-bundle')));
|
|
1596
|
+
assert(!childPage.includes(getStylesheetMarkup('extra-bundle')));
|
|
1597
|
+
assert(!childPage.includes(getStylesheetMarkup('extra2-bundle')));
|
|
1598
|
+
|
|
1599
|
+
assert(childPage.includes(getScriptMarkup('public-module-bundle')));
|
|
1600
|
+
assert(childPage.includes(getScriptMarkup('new-module-bundle')));
|
|
1601
|
+
assert(!childPage.includes(getScriptMarkup('widget-module-bundle')));
|
|
1602
|
+
assert(!childPage.includes(getScriptMarkup('main-module-bundle')));
|
|
1603
|
+
assert(!childPage.includes(getScriptMarkup('extra-module-bundle')));
|
|
1604
|
+
assert(!childPage.includes(getScriptMarkup('extra2-module-bundle')));
|
|
1605
|
+
});
|
|
1606
|
+
|
|
1607
|
+
it('should load all the remapped bundles on all pages when the user is logged in', async function () {
|
|
1608
|
+
await t.createAdmin(apos);
|
|
1609
|
+
const jar = await t.getUserJar(apos);
|
|
1610
|
+
|
|
1611
|
+
const homePage = await apos.http.get('/', { jar });
|
|
1612
|
+
assert(homePage.match(/logged in/));
|
|
1613
|
+
|
|
1614
|
+
const bundlePage = await apos.http.get('/bundle', { jar });
|
|
1615
|
+
|
|
1616
|
+
assert(bundlePage.includes(getStylesheetMarkup('apos-bundle')));
|
|
1617
|
+
assert(bundlePage.includes(getStylesheetMarkup('new-bundle')));
|
|
1618
|
+
assert(bundlePage.includes(getStylesheetMarkup('company-bundle')));
|
|
1619
|
+
assert(bundlePage.includes(getStylesheetMarkup('newcompany-bundle')));
|
|
1620
|
+
assert(!bundlePage.includes(getStylesheetMarkup('public-bundle')));
|
|
1621
|
+
assert(!bundlePage.includes(getStylesheetMarkup('main-bundle')));
|
|
1622
|
+
assert(!bundlePage.includes(getStylesheetMarkup('extra-bundle')));
|
|
1623
|
+
assert(!bundlePage.includes(getStylesheetMarkup('extra2-bundle')));
|
|
1624
|
+
|
|
1625
|
+
assert(bundlePage.includes(getScriptMarkup('apos-module-bundle')));
|
|
1626
|
+
assert(bundlePage.includes(getScriptMarkup('new-module-bundle')));
|
|
1627
|
+
assert(bundlePage.includes(getScriptMarkup('widget-module-bundle')));
|
|
1628
|
+
assert(bundlePage.includes(getStylesheetMarkup('newcompany-bundle')));
|
|
1629
|
+
assert(bundlePage.includes(getStylesheetMarkup('company-bundle')));
|
|
1630
|
+
assert(!bundlePage.includes(getScriptMarkup('public-module-bundle')));
|
|
1631
|
+
assert(!bundlePage.includes(getScriptMarkup('main-module-bundle')));
|
|
1632
|
+
assert(!bundlePage.includes(getScriptMarkup('extra-module-bundle')));
|
|
1633
|
+
assert(!bundlePage.includes(getScriptMarkup('extra2-module-bundle')));
|
|
1634
|
+
});
|
|
1333
1635
|
});
|
|
1334
1636
|
|
|
1335
1637
|
function loadUtils () {
|
|
@@ -1346,7 +1648,16 @@ function loadUtils () {
|
|
|
1346
1648
|
const getStylesheetMarkup = (file) =>
|
|
1347
1649
|
`<link href="/apos-frontend/default/${file}.css" rel="stylesheet" />`;
|
|
1348
1650
|
|
|
1349
|
-
const expectedBundlesNames = [
|
|
1651
|
+
const expectedBundlesNames = [
|
|
1652
|
+
'main-module-bundle.js',
|
|
1653
|
+
'another-module-bundle.js',
|
|
1654
|
+
'company-module-bundle.js',
|
|
1655
|
+
'extra-module-bundle.js',
|
|
1656
|
+
'extra2-module-bundle.js',
|
|
1657
|
+
'main-bundle.css',
|
|
1658
|
+
'company-bundle.css',
|
|
1659
|
+
'extra-bundle.css'
|
|
1660
|
+
];
|
|
1350
1661
|
|
|
1351
1662
|
const deleteBuiltFolders = async (publicPath, deleteAposBuild = false) => {
|
|
1352
1663
|
await fs.remove(publicPath + '/apos-frontend');
|
|
@@ -1359,9 +1670,11 @@ function loadUtils () {
|
|
|
1359
1670
|
|
|
1360
1671
|
const allBundlesAreIncluded = (page) => {
|
|
1361
1672
|
assert(page.includes(getStylesheetMarkup('apos-bundle')));
|
|
1673
|
+
assert(page.includes(getStylesheetMarkup('main-bundle')));
|
|
1362
1674
|
assert(page.includes(getStylesheetMarkup('extra-bundle')));
|
|
1363
1675
|
|
|
1364
1676
|
assert(page.includes(getScriptMarkup('apos-module-bundle')));
|
|
1677
|
+
assert(page.includes(getScriptMarkup('main-module-bundle')));
|
|
1365
1678
|
assert(page.includes(getScriptMarkup('extra-module-bundle')));
|
|
1366
1679
|
assert(page.includes(getScriptMarkup('extra2-module-bundle')));
|
|
1367
1680
|
};
|