apostrophe 3.31.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 +21 -1
- 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 +17 -3
- package/modules/@apostrophecms/i18n/i18n/es.json +1 -0
- package/modules/@apostrophecms/i18n/i18n/fr.json +1 -0
- package/modules/@apostrophecms/i18n/i18n/pt-BR.json +2 -1
- package/modules/@apostrophecms/i18n/i18n/sk.json +1 -0
- package/modules/@apostrophecms/i18n/ui/apos/components/AposI18nLocalize.vue +41 -20
- 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/ui/apos/components/AposRichTextWidgetEditor.vue +4 -3
- 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/widget-type/index.js +17 -3
- package/package.json +1 -1
- 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-lib/test.js +9 -1
package/.eslintrc
CHANGED
package/CHANGELOG.md
CHANGED
|
@@ -1,10 +1,30 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## 3.32.0 (2022-11-09)
|
|
4
|
+
|
|
5
|
+
### Adds
|
|
6
|
+
|
|
7
|
+
* Adds Reset Password feature to the login page. Note that the feature must be enabled and email delivery must be properly configured. See the [documentation](https://v3.docs.apostrophecms.org/reference/modules/login.html) for more details.
|
|
8
|
+
* Allow project-level developer to override bundling decisions by configuring the `@apostrophecms/asset` module. Check the [module documentation](https://v3.docs.apostrophecms.org/reference/modules/asset.html#options) for more information.
|
|
9
|
+
|
|
10
|
+
### Fixes
|
|
11
|
+
|
|
12
|
+
* Query builders for regular select fields have always accepted null to mean "do not filter on this property." Now this also works for dynamic select fields.
|
|
13
|
+
* The i18n UI state management now doesn't allow actions while it's busy.
|
|
14
|
+
* Fixed various localization bugs in the text of the "Update" dropdown menu.
|
|
15
|
+
* The `singleton: true` option for piece types now automatically implies `showCreate: false`.
|
|
16
|
+
* Remove browser console warnings by handling Tiptap Editor's breaking changes and duplicated plugins.
|
|
17
|
+
* The editor modal now allocates more space to area fields when possible, resolving common concerns about editing large widgets inside the modal.
|
|
18
|
+
|
|
3
19
|
## 3.31.0 (2022-10-27)
|
|
4
20
|
|
|
5
21
|
### Adds
|
|
6
22
|
|
|
7
|
-
* Adds `placeholder: true` and `initialModal: false` features to improve the user experience of adding widgets to the page. Checkout the [Widget Placeholders documentation](https://v3.docs.apostrophecms.org/guide/areas-and-widgets.html#adding-placeholder-content-to-widgets) for more detail.
|
|
23
|
+
* Adds `placeholder: true` and `initialModal: false` features to improve the user experience of adding widgets to the page. Checkout the [Widget Placeholders documentation](https://v3.docs.apostrophecms.org/guide/areas-and-widgets.html#adding-placeholder-content-to-widgets) for more detail.
|
|
24
|
+
|
|
25
|
+
### Fixes
|
|
26
|
+
|
|
27
|
+
* When another user is editing the document, the other user's name is now displayed correctly.
|
|
8
28
|
|
|
9
29
|
## 3.30.0 (2022-10-12)
|
|
10
30
|
|
|
@@ -17,7 +17,8 @@ const {
|
|
|
17
17
|
fillExtraBundles,
|
|
18
18
|
getBundlesNames,
|
|
19
19
|
writeBundlesImportFiles,
|
|
20
|
-
findNodeModulesSymlinks
|
|
20
|
+
findNodeModulesSymlinks,
|
|
21
|
+
transformRebundledFor
|
|
21
22
|
} = require('./lib/webpack/utils');
|
|
22
23
|
|
|
23
24
|
module.exports = {
|
|
@@ -38,7 +39,10 @@ module.exports = {
|
|
|
38
39
|
watch: true,
|
|
39
40
|
// Miliseconds to wait between asset sources changes before
|
|
40
41
|
// performing a build.
|
|
41
|
-
watchDebounceMs: 1000
|
|
42
|
+
watchDebounceMs: 1000,
|
|
43
|
+
// Object containing instructions for remapping existing bundles.
|
|
44
|
+
// See the modulre reference documentation for more information.
|
|
45
|
+
rebundleModules: undefined
|
|
42
46
|
},
|
|
43
47
|
|
|
44
48
|
async init(self) {
|
|
@@ -51,16 +55,21 @@ module.exports = {
|
|
|
51
55
|
self.initUploadfs();
|
|
52
56
|
|
|
53
57
|
const {
|
|
54
|
-
extensions = {},
|
|
58
|
+
extensions = {},
|
|
59
|
+
extensionOptions = {},
|
|
60
|
+
verifiedBundles = {},
|
|
61
|
+
rebundleModules = {}
|
|
55
62
|
} = await getWebpackExtensions({
|
|
56
63
|
getMetadata: self.apos.synth.getMetadata,
|
|
57
|
-
modulesToInstantiate: self.apos.modulesToBeInstantiated()
|
|
64
|
+
modulesToInstantiate: self.apos.modulesToBeInstantiated(),
|
|
65
|
+
rebundleModulesConfig: self.options.rebundleModules
|
|
58
66
|
});
|
|
59
67
|
|
|
60
68
|
self.extraBundles = fillExtraBundles(verifiedBundles);
|
|
61
69
|
self.webpackExtensions = extensions;
|
|
62
70
|
self.webpackExtensionOptions = extensionOptions;
|
|
63
71
|
self.verifiedBundles = verifiedBundles;
|
|
72
|
+
self.rebundleModules = rebundleModules;
|
|
64
73
|
self.buildWatcherEnable = process.env.APOS_ASSET_WATCH !== '0' && self.options.watch !== false;
|
|
65
74
|
self.buildWatcherDebounceMs = parseInt(self.options.watchDebounceMs || 1000, 10);
|
|
66
75
|
self.buildWatcher = null;
|
|
@@ -312,15 +321,27 @@ module.exports = {
|
|
|
312
321
|
}
|
|
313
322
|
|
|
314
323
|
if (options.index) {
|
|
324
|
+
// Gather modules with non-main, catch-all bundles
|
|
325
|
+
const ignoreModules = self.rebundleModules
|
|
326
|
+
.filter(entry => !entry.main && !entry.source)
|
|
327
|
+
.reduce((acc, entry) => ({
|
|
328
|
+
...acc,
|
|
329
|
+
[entry.name]: true
|
|
330
|
+
}), {});
|
|
331
|
+
|
|
315
332
|
indexJsImports = getImports(source, 'index.js', {
|
|
316
333
|
invokeApps: true,
|
|
317
334
|
enumerateImports: true,
|
|
318
335
|
importSuffix: 'App',
|
|
319
|
-
requireDefaultExport: true
|
|
336
|
+
requireDefaultExport: true,
|
|
337
|
+
mainModuleBundles: getMainModuleBundleFiles('js'),
|
|
338
|
+
ignoreModules
|
|
320
339
|
});
|
|
321
340
|
indexSassImports = getImports(source, 'index.scss', {
|
|
322
341
|
importSuffix: 'Stylesheet',
|
|
323
|
-
enumerateImports: true
|
|
342
|
+
enumerateImports: true,
|
|
343
|
+
mainModuleBundles: getMainModuleBundleFiles('scss'),
|
|
344
|
+
ignoreModules
|
|
324
345
|
});
|
|
325
346
|
}
|
|
326
347
|
|
|
@@ -351,7 +372,7 @@ module.exports = {
|
|
|
351
372
|
name,
|
|
352
373
|
buildDir,
|
|
353
374
|
mainBundleName: outputFilename.replace('.js', ''),
|
|
354
|
-
verifiedBundles:
|
|
375
|
+
verifiedBundles: getVerifiedBundlesInEffect(),
|
|
355
376
|
getImportFileOutput,
|
|
356
377
|
writeImportFile
|
|
357
378
|
});
|
|
@@ -437,6 +458,32 @@ module.exports = {
|
|
|
437
458
|
}));
|
|
438
459
|
}
|
|
439
460
|
|
|
461
|
+
function getMainModuleBundleFiles(ext) {
|
|
462
|
+
return Object.values(self.verifiedBundles)
|
|
463
|
+
.reduce((acc, entry) => {
|
|
464
|
+
if (!entry.main) {
|
|
465
|
+
return acc;
|
|
466
|
+
};
|
|
467
|
+
return [
|
|
468
|
+
...acc,
|
|
469
|
+
...(entry[ext] || [])
|
|
470
|
+
];
|
|
471
|
+
}, []);
|
|
472
|
+
}
|
|
473
|
+
|
|
474
|
+
function getVerifiedBundlesInEffect() {
|
|
475
|
+
return Object.entries(self.verifiedBundles)
|
|
476
|
+
.reduce((acc, [ key, entry ]) => {
|
|
477
|
+
if (entry.main) {
|
|
478
|
+
return acc;
|
|
479
|
+
};
|
|
480
|
+
return {
|
|
481
|
+
...acc,
|
|
482
|
+
[key]: entry
|
|
483
|
+
};
|
|
484
|
+
}, {});
|
|
485
|
+
}
|
|
486
|
+
|
|
440
487
|
function writeImportFile ({
|
|
441
488
|
importFile,
|
|
442
489
|
prologue,
|
|
@@ -625,6 +672,9 @@ module.exports = {
|
|
|
625
672
|
for (const name of modulesToInstantiate) {
|
|
626
673
|
const metadata = self.apos.synth.getMetadata(name);
|
|
627
674
|
for (const entry of metadata.__meta.chain) {
|
|
675
|
+
if (options.ignoreModules?.[entry.name]) {
|
|
676
|
+
seen[entry.dirname] = true;
|
|
677
|
+
}
|
|
628
678
|
if (seen[entry.dirname]) {
|
|
629
679
|
continue;
|
|
630
680
|
}
|
|
@@ -652,6 +702,10 @@ module.exports = {
|
|
|
652
702
|
components.reverse();
|
|
653
703
|
}
|
|
654
704
|
|
|
705
|
+
if (options.mainModuleBundles) {
|
|
706
|
+
components.push(...options.mainModuleBundles);
|
|
707
|
+
}
|
|
708
|
+
|
|
655
709
|
return getImportFileOutput(components, options);
|
|
656
710
|
}
|
|
657
711
|
|
|
@@ -883,6 +937,10 @@ module.exports = {
|
|
|
883
937
|
},
|
|
884
938
|
methods(self) {
|
|
885
939
|
return {
|
|
940
|
+
// Register the library function as method to be used by core modules.
|
|
941
|
+
// Open the implementation for more dev comments.
|
|
942
|
+
transformRebundledFor,
|
|
943
|
+
|
|
886
944
|
async initUploadfs() {
|
|
887
945
|
if (self.options.uploadfs) {
|
|
888
946
|
self.uploadfs = await self.apos.modules['@apostrophecms/uploadfs'].getInstance(self.options.uploadfs);
|
|
@@ -47,16 +47,25 @@ module.exports = {
|
|
|
47
47
|
}
|
|
48
48
|
},
|
|
49
49
|
|
|
50
|
+
// Export for testing
|
|
51
|
+
formatRebundleConfig,
|
|
52
|
+
verifyRebundleConfig,
|
|
53
|
+
|
|
54
|
+
transformRebundledFor,
|
|
55
|
+
|
|
50
56
|
async getWebpackExtensions ({
|
|
51
|
-
getMetadata, modulesToInstantiate
|
|
57
|
+
getMetadata, modulesToInstantiate, rebundleModulesConfig = {}
|
|
52
58
|
}) {
|
|
53
59
|
const modulesMeta = modulesToInstantiate
|
|
54
60
|
.map((name) => getMetadata(name));
|
|
55
61
|
|
|
62
|
+
const rebundleModules = formatRebundleConfig(rebundleModulesConfig);
|
|
63
|
+
|
|
56
64
|
const {
|
|
57
65
|
extensions, extensionOptions, foundBundles
|
|
58
66
|
} = getModulesWebpackConfigs(
|
|
59
|
-
modulesMeta
|
|
67
|
+
modulesMeta,
|
|
68
|
+
rebundleModules
|
|
60
69
|
);
|
|
61
70
|
|
|
62
71
|
const verifiedBundles = await verifyBundlesEntryPoints(foundBundles);
|
|
@@ -64,26 +73,36 @@ module.exports = {
|
|
|
64
73
|
return {
|
|
65
74
|
extensions,
|
|
66
75
|
extensionOptions,
|
|
67
|
-
verifiedBundles
|
|
76
|
+
verifiedBundles,
|
|
77
|
+
rebundleModules
|
|
68
78
|
};
|
|
69
79
|
},
|
|
70
80
|
|
|
71
81
|
fillExtraBundles (verifiedBundles = {}) {
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
82
|
+
|
|
83
|
+
const res = Object.entries(verifiedBundles).reduce(
|
|
84
|
+
(acc, [ bundleName, entry ]) => {
|
|
85
|
+
const {
|
|
86
|
+
js, scss, main
|
|
87
|
+
} = entry;
|
|
88
|
+
if (main) {
|
|
89
|
+
return acc;
|
|
90
|
+
}
|
|
91
|
+
return {
|
|
92
|
+
js: [
|
|
93
|
+
...acc.js,
|
|
94
|
+
...(js.length && !acc.js.includes(bundleName)) ? [ bundleName ] : []
|
|
95
|
+
],
|
|
96
|
+
css: [
|
|
97
|
+
...acc.css,
|
|
98
|
+
...(scss.length && !acc.css.includes(bundleName)) ? [ bundleName ] : []
|
|
99
|
+
]
|
|
100
|
+
};
|
|
101
|
+
}, {
|
|
102
|
+
js: [],
|
|
103
|
+
css: []
|
|
104
|
+
});
|
|
105
|
+
return res;
|
|
87
106
|
},
|
|
88
107
|
|
|
89
108
|
getBundlesNames (bundles, es5 = false) {
|
|
@@ -177,13 +196,17 @@ async function findSymlinks(where, sub = '') {
|
|
|
177
196
|
return result;
|
|
178
197
|
}
|
|
179
198
|
|
|
180
|
-
function getModulesWebpackConfigs (modulesMeta) {
|
|
199
|
+
function getModulesWebpackConfigs (modulesMeta, rebundleModules) {
|
|
181
200
|
const {
|
|
182
201
|
extensions, extensionOptions, bundles
|
|
183
202
|
} = modulesMeta.reduce((modulesAcc, meta) => {
|
|
184
203
|
const { webpack, __meta } = meta;
|
|
185
204
|
|
|
186
|
-
const configs = formatConfigs(
|
|
205
|
+
const configs = formatConfigs(
|
|
206
|
+
__meta.chain,
|
|
207
|
+
webpack,
|
|
208
|
+
rebundleModules
|
|
209
|
+
);
|
|
187
210
|
|
|
188
211
|
if (!configs.length) {
|
|
189
212
|
return modulesAcc;
|
|
@@ -235,15 +258,57 @@ function getModulesWebpackConfigs (modulesMeta) {
|
|
|
235
258
|
};
|
|
236
259
|
|
|
237
260
|
async function verifyBundlesEntryPoints (bundles) {
|
|
238
|
-
const checkPathsPromises = bundles.map(async ({
|
|
261
|
+
const checkPathsPromises = bundles.map(async ({
|
|
262
|
+
bundleName, modulePath, bundleRemapping
|
|
263
|
+
}) => {
|
|
239
264
|
const jsPath = `${modulePath}/ui/src/${bundleName}.js`;
|
|
240
265
|
const scssPath = `${modulePath}/ui/src/${bundleName}.scss`;
|
|
266
|
+
const jsIndexPath = `${modulePath}/ui/src/index.js`;
|
|
267
|
+
const scssIndexPath = `${modulePath}/ui/src/index.scss`;
|
|
268
|
+
let main = false;
|
|
269
|
+
let withIndex;
|
|
241
270
|
|
|
242
271
|
const jsFileExists = await fs.pathExists(jsPath);
|
|
243
272
|
const scssFileExists = await fs.pathExists(scssPath);
|
|
244
273
|
|
|
274
|
+
for (const remapping of bundleRemapping) {
|
|
275
|
+
main = remapping.main;
|
|
276
|
+
// - catch all to "main" or new bundle name,
|
|
277
|
+
// already verified it's unique for the given module
|
|
278
|
+
if (!remapping.source) {
|
|
279
|
+
// Bundle name for "main" "doesn't matter - it will be ignored and never built,
|
|
280
|
+
// we want to achieve a free from colision name. What matters is main = true.
|
|
281
|
+
// Target is 'main' by convention: `main.bundleName`
|
|
282
|
+
bundleName = `${remapping.target}.${bundleName}`;
|
|
283
|
+
if (!remapping.main) {
|
|
284
|
+
// move "ui/src/index.*" to the bundle,
|
|
285
|
+
// verify existence later, better performance
|
|
286
|
+
withIndex = {
|
|
287
|
+
jsPath: jsIndexPath,
|
|
288
|
+
scssPath: scssIndexPath
|
|
289
|
+
};
|
|
290
|
+
bundleName = remapping.target;
|
|
291
|
+
}
|
|
292
|
+
|
|
293
|
+
break;
|
|
294
|
+
}
|
|
295
|
+
// - not a catch-all statement from this point on
|
|
296
|
+
// - "main" for a concrete bunbdle
|
|
297
|
+
if (remapping.main && remapping.source === bundleName) {
|
|
298
|
+
bundleName = `${remapping.target}.${bundleName}`;
|
|
299
|
+
break;
|
|
300
|
+
}
|
|
301
|
+
// - not "main", concrete bundle remapping
|
|
302
|
+
if (remapping.source === bundleName) {
|
|
303
|
+
bundleName = remapping.target;
|
|
304
|
+
break;
|
|
305
|
+
}
|
|
306
|
+
}
|
|
307
|
+
|
|
245
308
|
return {
|
|
246
309
|
bundleName,
|
|
310
|
+
main,
|
|
311
|
+
withIndex,
|
|
247
312
|
...jsFileExists && { jsPath },
|
|
248
313
|
...scssFileExists && { scssPath }
|
|
249
314
|
};
|
|
@@ -251,8 +316,39 @@ async function verifyBundlesEntryPoints (bundles) {
|
|
|
251
316
|
|
|
252
317
|
const bundlesPaths = await Promise.all(checkPathsPromises);
|
|
253
318
|
|
|
254
|
-
|
|
255
|
-
|
|
319
|
+
// Verify and squash withIndex data
|
|
320
|
+
const seen = {};
|
|
321
|
+
const bundlesPathsWithIndex = [];
|
|
322
|
+
for (const entry of bundlesPaths) {
|
|
323
|
+
if (!entry.withIndex) {
|
|
324
|
+
bundlesPathsWithIndex.push(entry);
|
|
325
|
+
continue;
|
|
326
|
+
}
|
|
327
|
+
if (seen[entry.bundleName]) {
|
|
328
|
+
delete entry.withIndex;
|
|
329
|
+
bundlesPathsWithIndex.push(entry);
|
|
330
|
+
continue;
|
|
331
|
+
}
|
|
332
|
+
seen[entry.bundleName] = true;
|
|
333
|
+
const { jsPath, scssPath } = entry.withIndex;
|
|
334
|
+
const jsFileExists = await fs.pathExists(jsPath);
|
|
335
|
+
const scssFileExists = await fs.pathExists(scssPath);
|
|
336
|
+
if (!jsFileExists && !scssFileExists) {
|
|
337
|
+
delete entry.withIndex;
|
|
338
|
+
bundlesPathsWithIndex.push(entry);
|
|
339
|
+
continue;
|
|
340
|
+
}
|
|
341
|
+
bundlesPathsWithIndex.push({
|
|
342
|
+
...entry,
|
|
343
|
+
withIndex: {
|
|
344
|
+
...jsFileExists && { jsPath },
|
|
345
|
+
...scssFileExists && { scssPath }
|
|
346
|
+
}
|
|
347
|
+
});
|
|
348
|
+
}
|
|
349
|
+
|
|
350
|
+
const packedFilesByBundle = bundlesPathsWithIndex.reduce((acc, {
|
|
351
|
+
bundleName, jsPath, scssPath, main, withIndex
|
|
256
352
|
}) => {
|
|
257
353
|
if (!jsPath && !scssPath) {
|
|
258
354
|
return acc;
|
|
@@ -261,11 +357,18 @@ async function verifyBundlesEntryPoints (bundles) {
|
|
|
261
357
|
return {
|
|
262
358
|
...acc,
|
|
263
359
|
[bundleName]: {
|
|
360
|
+
main,
|
|
361
|
+
// Boolean indicating if the "main" index.js is included
|
|
362
|
+
// caused by a remapping. It's not yet used anywhere but
|
|
363
|
+
// it's an useful information that we keep.
|
|
364
|
+
withIndex: !!withIndex || acc[bundleName]?.withIndex,
|
|
264
365
|
js: [
|
|
366
|
+
...withIndex?.jsPath ? [ withIndex?.jsPath ] : [],
|
|
265
367
|
...acc[bundleName] ? acc[bundleName].js : [],
|
|
266
368
|
...jsPath ? [ jsPath ] : []
|
|
267
369
|
],
|
|
268
370
|
scss: [
|
|
371
|
+
...withIndex?.scssPath ? [ withIndex?.scssPath ] : [],
|
|
269
372
|
...acc[bundleName] ? acc[bundleName].scss : [],
|
|
270
373
|
...scssPath ? [ scssPath ] : []
|
|
271
374
|
]
|
|
@@ -276,7 +379,105 @@ async function verifyBundlesEntryPoints (bundles) {
|
|
|
276
379
|
return packedFilesByBundle;
|
|
277
380
|
};
|
|
278
381
|
|
|
279
|
-
|
|
382
|
+
// Normalize config:
|
|
383
|
+
// - from { moduleName: 'main' }
|
|
384
|
+
// to [{ main: true, name: 'moduleName', target: 'main' }]
|
|
385
|
+
// - from { moduleName: bundleName }
|
|
386
|
+
// to [{ main: false, name: 'moduleName', target: bundleName }]
|
|
387
|
+
// - from { 'moduleName:sourceBundle': 'main' }
|
|
388
|
+
// to [{ main: true, name: 'moduleName', source: 'sourceBundle', target: 'main' }]
|
|
389
|
+
// - from { 'moduleName:sourceBundle': targetBundle }
|
|
390
|
+
// to [{ main: false, name: 'moduleName', source: 'sourceBundle', target: targetBundle }]
|
|
391
|
+
function formatRebundleConfig(mappingConfig = {}) {
|
|
392
|
+
const result = Object.keys(mappingConfig).reduce((transformed, key) => {
|
|
393
|
+
const main = mappingConfig[key] === 'main';
|
|
394
|
+
const [ moduleName, sourceBundle ] = key.split(':');
|
|
395
|
+
return [
|
|
396
|
+
...transformed,
|
|
397
|
+
{
|
|
398
|
+
name: moduleName,
|
|
399
|
+
source: sourceBundle,
|
|
400
|
+
target: mappingConfig[key],
|
|
401
|
+
main
|
|
402
|
+
}
|
|
403
|
+
];
|
|
404
|
+
}, []);
|
|
405
|
+
// Better panic than sorry!
|
|
406
|
+
verifyRebundleConfig(result);
|
|
407
|
+
return result;
|
|
408
|
+
}
|
|
409
|
+
|
|
410
|
+
// This function is used to detect re-bundled and moved to the main build bundles.
|
|
411
|
+
// It returns filtered configuration containing the proper bundle names.
|
|
412
|
+
// See usage in `template/lib/bundlesLoader.js` and `widget-type/index.js`.
|
|
413
|
+
// Expected arguments:
|
|
414
|
+
// - moduleName: the module owning the bundleConfig
|
|
415
|
+
// - bundleConfig: the bundle configuration ({ bundles: {...} })
|
|
416
|
+
// - rebundleConfigs: the normalized output of `formatRebundleConfig(asset.options.rebundleModules)`
|
|
417
|
+
function transformRebundledFor(moduleName, bundleConfigs, rebundleConfigs) {
|
|
418
|
+
const rebundle = rebundleConfigs
|
|
419
|
+
.filter(entry => entry.name === moduleName);
|
|
420
|
+
let result = { ...bundleConfigs };
|
|
421
|
+
|
|
422
|
+
for (const entry of rebundle) {
|
|
423
|
+
// 1. CatchAll to "main", already bundled in the main build - skip.
|
|
424
|
+
if (!entry.source && entry.main) {
|
|
425
|
+
result = {};
|
|
426
|
+
break;
|
|
427
|
+
}
|
|
428
|
+
// 2. CatchAll to a new bundle name, preserve merged options.
|
|
429
|
+
if (!entry.source && !entry.main) {
|
|
430
|
+
const options = Object.values(bundleConfigs)
|
|
431
|
+
.reduce((all, opts) => ({
|
|
432
|
+
...all,
|
|
433
|
+
...opts
|
|
434
|
+
}), {});
|
|
435
|
+
result = { [entry.target]: options };
|
|
436
|
+
break;
|
|
437
|
+
}
|
|
438
|
+
// 3. Rename a single bundle.
|
|
439
|
+
if (entry.source) {
|
|
440
|
+
// 3.1. ... but it's sent to the main build
|
|
441
|
+
if (entry.main) {
|
|
442
|
+
delete result[entry.source];
|
|
443
|
+
continue;
|
|
444
|
+
}
|
|
445
|
+
// 3.2. rename it, preserve the options
|
|
446
|
+
if (bundleConfigs[entry.source]) {
|
|
447
|
+
result[entry.target] = { ...bundleConfigs[entry.source] };
|
|
448
|
+
delete result[entry.source];
|
|
449
|
+
}
|
|
450
|
+
}
|
|
451
|
+
}
|
|
452
|
+
|
|
453
|
+
return result;
|
|
454
|
+
}
|
|
455
|
+
|
|
456
|
+
// Expects formatted by formatRebundleConfig() `asset.options.rebundleModules`
|
|
457
|
+
function verifyRebundleConfig(config = []) {
|
|
458
|
+
const targeted = [];
|
|
459
|
+
const catchAllModules = {};
|
|
460
|
+
for (const entry of config) {
|
|
461
|
+
if (!entry.source) {
|
|
462
|
+
catchAllModules[entry.name] = `${entry.name}: ${entry.target}`;
|
|
463
|
+
} else {
|
|
464
|
+
targeted.push(entry);
|
|
465
|
+
}
|
|
466
|
+
}
|
|
467
|
+
for (const entry of targeted) {
|
|
468
|
+
if (catchAllModules[entry.name]) {
|
|
469
|
+
const conflicting = `${entry.name}${entry.source ? `:${entry.source}` : ''}: ${entry.target}`;
|
|
470
|
+
throw new Error(
|
|
471
|
+
'Invalid apos.asset.options.rebundleModules: ' +
|
|
472
|
+
`"${catchAllModules[entry.name]}" conflicts with ` +
|
|
473
|
+
`"${conflicting}"`
|
|
474
|
+
);
|
|
475
|
+
}
|
|
476
|
+
}
|
|
477
|
+
}
|
|
478
|
+
|
|
479
|
+
// Gather and transform all available webpack configs
|
|
480
|
+
function formatConfigs (chain, webpackConfigs, rebundleModules) {
|
|
280
481
|
return Object.entries(webpackConfigs)
|
|
281
482
|
.map(([ name, config ], i) => {
|
|
282
483
|
|
|
@@ -285,16 +486,26 @@ function formatConfigs (chain, webpackConfigs) {
|
|
|
285
486
|
}
|
|
286
487
|
|
|
287
488
|
const {
|
|
288
|
-
bundles = {},
|
|
489
|
+
bundles = {},
|
|
490
|
+
extensions = {},
|
|
491
|
+
extensionOptions = {}
|
|
289
492
|
} = config;
|
|
493
|
+
const bundleNames = Object.keys(bundles);
|
|
494
|
+
|
|
495
|
+
// Remapping only for the explicitly defined by the module bundle
|
|
496
|
+
// configurations
|
|
497
|
+
const bundleRemapping = rebundleModules
|
|
498
|
+
.filter(entry => entry.name === chain[i].name);
|
|
290
499
|
|
|
291
500
|
return {
|
|
501
|
+
name: chain[i].name,
|
|
292
502
|
extensions,
|
|
293
503
|
extensionOptions,
|
|
294
504
|
bundles: {
|
|
295
505
|
[name]: {
|
|
296
|
-
bundleNames
|
|
297
|
-
modulePath: chain[i].dirname
|
|
506
|
+
bundleNames,
|
|
507
|
+
modulePath: chain[i].dirname,
|
|
508
|
+
bundleRemapping
|
|
298
509
|
}
|
|
299
510
|
}
|
|
300
511
|
};
|
|
@@ -303,11 +514,14 @@ function formatConfigs (chain, webpackConfigs) {
|
|
|
303
514
|
|
|
304
515
|
function flattenBundles (bundles) {
|
|
305
516
|
return Object.values(bundles)
|
|
306
|
-
.reduce((acc, {
|
|
517
|
+
.reduce((acc, {
|
|
518
|
+
bundleNames, modulePath, bundleRemapping
|
|
519
|
+
}) => {
|
|
307
520
|
return [
|
|
308
521
|
...acc,
|
|
309
522
|
...bundleNames.map((bundleName) => ({
|
|
310
523
|
bundleName,
|
|
524
|
+
bundleRemapping,
|
|
311
525
|
modulePath
|
|
312
526
|
}))
|
|
313
527
|
];
|
|
@@ -650,16 +650,17 @@ export default {
|
|
|
650
650
|
// Powers the dropdown Save menu
|
|
651
651
|
// all actions expected to be methods of this component
|
|
652
652
|
// Needs to be manually computed because this.saveLabel doesn't stay reactive when part of an object
|
|
653
|
-
const typeLabel = this.moduleOptions
|
|
654
|
-
? this.moduleOptions.label
|
|
655
|
-
: 'document';
|
|
653
|
+
const typeLabel = this.$t(this.moduleOptions
|
|
654
|
+
? this.moduleOptions.label
|
|
655
|
+
: 'document');
|
|
656
656
|
const isNew = !this.docId;
|
|
657
657
|
// this.original takes a moment to populate, don't crash
|
|
658
658
|
const canPreview = this.original && (this.original._id ? this.original._url : this.original._previewable);
|
|
659
659
|
const canNew = this.moduleOptions.showCreate;
|
|
660
|
+
const isSingleton = this.moduleOptions.singleton;
|
|
660
661
|
const description = {
|
|
661
662
|
saveLabel: this.$t(this.saveLabel),
|
|
662
|
-
typeLabel
|
|
663
|
+
typeLabel
|
|
663
664
|
};
|
|
664
665
|
const menu = [
|
|
665
666
|
{
|
|
@@ -667,7 +668,8 @@ export default {
|
|
|
667
668
|
action: 'onSave',
|
|
668
669
|
description: {
|
|
669
670
|
...description,
|
|
670
|
-
key:
|
|
671
|
+
key: isSingleton ? 'apostrophe:updateSingleton'
|
|
672
|
+
: (isNew ? 'apostrophe:insertAndReturn' : 'apostrophe:updateAndReturn')
|
|
671
673
|
},
|
|
672
674
|
def: true
|
|
673
675
|
}
|
|
@@ -689,7 +691,8 @@ export default {
|
|
|
689
691
|
menu.push({
|
|
690
692
|
label: {
|
|
691
693
|
key: 'apostrophe:takeActionAndCreateNew',
|
|
692
|
-
saveLabel: this.$t(this.saveLabel)
|
|
694
|
+
saveLabel: this.$t(this.saveLabel),
|
|
695
|
+
typeLabel
|
|
693
696
|
},
|
|
694
697
|
action: 'onSaveAndNew',
|
|
695
698
|
description: {
|
|
@@ -707,18 +710,25 @@ export default {
|
|
|
707
710
|
}
|
|
708
711
|
if (this.manuallyPublished && canPreview) {
|
|
709
712
|
menu.push({
|
|
710
|
-
label:
|
|
713
|
+
label: {
|
|
714
|
+
key: 'apostrophe:saveDraftAndPreview',
|
|
715
|
+
typeLabel
|
|
716
|
+
},
|
|
711
717
|
action: 'onSaveDraftAndView',
|
|
712
|
-
description:
|
|
713
|
-
|
|
718
|
+
description: {
|
|
719
|
+
key: 'apostrophe:saveDraftAndPreviewDescription',
|
|
720
|
+
typeLabel
|
|
721
|
+
}
|
|
714
722
|
});
|
|
715
723
|
};
|
|
716
724
|
if (this.manuallyPublished && canNew) {
|
|
717
725
|
menu.push({
|
|
718
726
|
label: 'apostrophe:saveDraftAndCreateNew',
|
|
719
727
|
action: 'onSaveDraftAndNew',
|
|
720
|
-
description:
|
|
721
|
-
|
|
728
|
+
description: {
|
|
729
|
+
key: 'apostrophe:saveDraftAndCreateNewDescription',
|
|
730
|
+
typeLabel
|
|
731
|
+
}
|
|
722
732
|
});
|
|
723
733
|
}
|
|
724
734
|
return menu;
|
|
@@ -754,13 +764,13 @@ export default {
|
|
|
754
764
|
|
|
755
765
|
<style lang="scss" scoped>
|
|
756
766
|
.apos-doc-editor__body {
|
|
757
|
-
padding-top:
|
|
758
|
-
max-width: 90%;
|
|
759
|
-
margin-right: auto;
|
|
760
|
-
margin-left: auto;
|
|
767
|
+
padding-top: $spacing-double;
|
|
761
768
|
}
|
|
762
769
|
|
|
763
770
|
.apos-doc-editor__utility {
|
|
764
|
-
padding:
|
|
771
|
+
padding: $spacing-quadruple $spacing-base;
|
|
772
|
+
@include media-up(lap) {
|
|
773
|
+
padding: $spacing-quadruple $spacing-double;
|
|
774
|
+
}
|
|
765
775
|
}
|
|
766
776
|
</style>
|