Welcome to mirror list, hosted at ThFree Co, Russian Federation.

gitlab.com/gitlab-org/gitlab-foss.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'app/assets/javascripts/vue_shared/components/lib/utils/props_utils.js')
-rw-r--r--app/assets/javascripts/vue_shared/components/lib/utils/props_utils.js35
1 files changed, 35 insertions, 0 deletions
diff --git a/app/assets/javascripts/vue_shared/components/lib/utils/props_utils.js b/app/assets/javascripts/vue_shared/components/lib/utils/props_utils.js
new file mode 100644
index 00000000000..b115b1fb34b
--- /dev/null
+++ b/app/assets/javascripts/vue_shared/components/lib/utils/props_utils.js
@@ -0,0 +1,35 @@
+/**
+ * Return the union of the given components' props options. Required props take
+ * precendence over non-required props of the same name.
+ *
+ * This makes two assumptions:
+ * - All given components define their props in verbose object format.
+ * - The components all agree on the `type` of a common prop.
+ *
+ * @param {object[]} components The components to derive the union from.
+ * @returns {object} The union of the props of the given components.
+ */
+export const propsUnion = (components) =>
+ components.reduce((acc, component) => {
+ Object.entries(component.props ?? {}).forEach(([propName, propOptions]) => {
+ if (process.env.NODE_ENV !== 'production') {
+ if (typeof propOptions !== 'object' || !('type' in propOptions)) {
+ throw new Error(
+ `Cannot create props union: expected verbose prop options for prop "${propName}"`,
+ );
+ }
+
+ if (propName in acc && acc[propName]?.type !== propOptions?.type) {
+ throw new Error(
+ `Cannot create props union: incompatible prop types for prop "${propName}"`,
+ );
+ }
+ }
+
+ if (!(propName in acc) || propOptions.required) {
+ acc[propName] = propOptions;
+ }
+ });
+
+ return acc;
+ }, {});