@pingux/astro 2.193.1-alpha.0 → 2.193.2-alpha.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.
@@ -187,7 +187,12 @@ var ComboBoxField = /*#__PURE__*/(0, _react.forwardRef)(function (props, ref) {
187
187
  ref: inputWrapperRef,
188
188
  onResize: onResize
189
189
  });
190
- (0, _utils.useLayoutEffect)(onResize, [onResize]);
190
+
191
+ // Re-measure synchronously (before paint) whenever the menu opens or closes,
192
+ // so the Popover renders with the correct width on the first frame.
193
+ // Without state.isOpen in deps, width updates rely solely on ResizeObserver
194
+ // which fires asynchronously after paint, causing a visible flicker.
195
+ (0, _utils.useLayoutEffect)(onResize, [onResize, state.isOpen]);
191
196
  var style = _objectSpread(_objectSpread({}, overlayProps.style), {}, {
192
197
  width: menuWidth,
193
198
  minWidth: menuWidth
@@ -44,7 +44,7 @@ var _universalFormSubmitTest = require("../../utils/testUtils/universalFormSubmi
44
44
  var _react3 = require("@emotion/react");
45
45
  function _interopRequireWildcard(e, t) { if ("function" == typeof _WeakMap) var r = new _WeakMap(), n = new _WeakMap(); return (_interopRequireWildcard = function _interopRequireWildcard(e, t) { if (!t && e && e.__esModule) return e; var o, i, f = { __proto__: null, "default": e }; if (null === e || "object" != _typeof(e) && "function" != typeof e) return f; if (o = t ? n : r) { if (o.has(e)) return o.get(e); o.set(e, f); } for (var _t2 in e) "default" !== _t2 && {}.hasOwnProperty.call(e, _t2) && ((i = (o = _Object$defineProperty) && _Object$getOwnPropertyDescriptor(e, _t2)) && (i.get || i.set) ? o(f, _t2, i) : f[_t2] = e[_t2]); return f; })(e, t); }
46
46
  function ownKeys(e, r) { var t = _Object$keys(e); if (_Object$getOwnPropertySymbols) { var o = _Object$getOwnPropertySymbols(e); r && (o = _filterInstanceProperty2(o).call(o, function (r) { return _Object$getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; }
47
- function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var _context37, _context38; var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? _forEachInstanceProperty2(_context37 = ownKeys(Object(t), !0)).call(_context37, function (r) { (0, _defineProperty2["default"])(e, r, t[r]); }) : _Object$getOwnPropertyDescriptors ? _Object$defineProperties(e, _Object$getOwnPropertyDescriptors(t)) : _forEachInstanceProperty2(_context38 = ownKeys(Object(t))).call(_context38, function (r) { _Object$defineProperty(e, r, _Object$getOwnPropertyDescriptor(t, r)); }); } return e; }
47
+ function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var _context39, _context40; var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? _forEachInstanceProperty2(_context39 = ownKeys(Object(t), !0)).call(_context39, function (r) { (0, _defineProperty2["default"])(e, r, t[r]); }) : _Object$getOwnPropertyDescriptors ? _Object$defineProperties(e, _Object$getOwnPropertyDescriptors(t)) : _forEachInstanceProperty2(_context40 = ownKeys(Object(t))).call(_context40, function (r) { _Object$defineProperty(e, r, _Object$getOwnPropertyDescriptor(t, r)); }); } return e; }
48
48
  function _regeneratorRuntime() { "use strict"; var r = _regenerator(), e = r.m(_regeneratorRuntime), t = (_Object$getPrototypeOf ? _Object$getPrototypeOf(e) : e.__proto__).constructor; function n(r) { var e = "function" == typeof r && r.constructor; return !!e && (e === t || "GeneratorFunction" === (e.displayName || e.name)); } var o = { "throw": 1, "return": 2, "break": 3, "continue": 3 }; function a(r) { var e, t; return function (n) { e || (e = { stop: function stop() { return t(n.a, 2); }, "catch": function _catch() { return n.v; }, abrupt: function abrupt(r, e) { return t(n.a, o[r], e); }, delegateYield: function delegateYield(r, o, a) { return e.resultName = o, t(n.d, _regeneratorValues(r), a); }, finish: function finish(r) { return t(n.f, r); } }, t = function t(r, _t, o) { n.p = e.prev, n.n = e.next; try { return r(_t, o); } finally { e.next = n.n; } }), e.resultName && (e[e.resultName] = n.v, e.resultName = void 0), e.sent = n.v, e.next = n.n; try { return r.call(this, e); } finally { n.p = e.prev, n.n = e.next; } }; } return (_regeneratorRuntime = function _regeneratorRuntime() { return { wrap: function wrap(e, t, n, o) { return r.w(a(e), t, n, o && _reverseInstanceProperty(o).call(o)); }, isGeneratorFunction: n, mark: r.m, awrap: function awrap(r, e) { return new _OverloadYield(r, e); }, AsyncIterator: _regeneratorAsyncIterator, async: function async(r, e, t, o, u) { return (n(e) ? _regeneratorAsyncGen : _regeneratorAsync)(a(r), e, t, o, u); }, keys: _regeneratorKeys, values: _regeneratorValues }; })(); }
49
49
  function _regeneratorValues(e) { if (null != e) { var t = e["function" == typeof _Symbol && _Symbol$iterator || "@@iterator"], r = 0; if (t) return t.call(e); if ("function" == typeof e.next) return e; if (!isNaN(e.length)) return { next: function next() { return e && r >= e.length && (e = void 0), { value: e && e[r++], done: !e }; } }; } throw new TypeError(_typeof(e) + " is not iterable"); }
50
50
  function _regeneratorKeys(e) { var n = Object(e), r = []; for (var t in n) r.unshift(t); return function e() { for (; r.length;) if ((t = r.pop()) in n) return e.value = t, e.done = !1, e; return e.done = !0, e; }; }
@@ -1582,6 +1582,97 @@ test('a blank title does not render', /*#__PURE__*/(0, _asyncToGenerator2["defau
1582
1582
  }
1583
1583
  }, _callee33);
1584
1584
  })));
1585
+ test('popover width re-measures when the menu opens to prevent flickering', /*#__PURE__*/(0, _asyncToGenerator2["default"])(/*#__PURE__*/_regeneratorRuntime().mark(function _callee34() {
1586
+ var mockWidth, offsetWidthSpy, button, listbox, popoverContainer;
1587
+ return _regeneratorRuntime().wrap(function _callee34$(_context36) {
1588
+ while (1) switch (_context36.prev = _context36.next) {
1589
+ case 0:
1590
+ // Simulate a scenario like the Country Picker recipe where the input wrapper
1591
+ // starts narrow (110px) and expands to full width when the menu opens.
1592
+ mockWidth = 110;
1593
+ offsetWidthSpy = jest.spyOn(window.HTMLElement.prototype, 'offsetWidth', 'get').mockImplementation(function () {
1594
+ return mockWidth;
1595
+ });
1596
+ getComponent();
1597
+
1598
+ // Simulate the wrapper expanding before the menu opens
1599
+ // (e.g., parent CSS changes from width: 110px to width: 100%)
1600
+ mockWidth = 500;
1601
+ button = _testWrapper.screen.queryByRole('button');
1602
+ _context36.next = 7;
1603
+ return _userEvent["default"].click(button);
1604
+ case 7:
1605
+ _context36.next = 9;
1606
+ return findListbox();
1607
+ case 9:
1608
+ listbox = _context36.sent;
1609
+ // The popover container receives the inline style with width/minWidth.
1610
+ // Without the fix, menuWidth would be stale (110) because useLayoutEffect
1611
+ // only ran on mount. With the fix, it re-measures on state.isOpen change.
1612
+ popoverContainer = listbox.closest('[role="presentation"]');
1613
+ expect(popoverContainer).toHaveStyle({
1614
+ width: '500px',
1615
+ 'min-width': '500px'
1616
+ });
1617
+ offsetWidthSpy.mockRestore();
1618
+ case 13:
1619
+ case "end":
1620
+ return _context36.stop();
1621
+ }
1622
+ }, _callee34);
1623
+ })));
1624
+ test('popover width stays in sync when closing and reopening at different widths', /*#__PURE__*/(0, _asyncToGenerator2["default"])(/*#__PURE__*/_regeneratorRuntime().mark(function _callee35() {
1625
+ var mockWidth, offsetWidthSpy, button, listbox, popoverContainer;
1626
+ return _regeneratorRuntime().wrap(function _callee35$(_context37) {
1627
+ while (1) switch (_context37.prev = _context37.next) {
1628
+ case 0:
1629
+ mockWidth = 500;
1630
+ offsetWidthSpy = jest.spyOn(window.HTMLElement.prototype, 'offsetWidth', 'get').mockImplementation(function () {
1631
+ return mockWidth;
1632
+ });
1633
+ getComponent();
1634
+ button = _testWrapper.screen.queryByRole('button'); // Open the menu at 500px
1635
+ _context37.next = 6;
1636
+ return _userEvent["default"].click(button);
1637
+ case 6:
1638
+ _context37.next = 8;
1639
+ return findListbox();
1640
+ case 8:
1641
+ listbox = _context37.sent;
1642
+ popoverContainer = listbox.closest('[role="presentation"]');
1643
+ expect(popoverContainer).toHaveStyle({
1644
+ width: '500px'
1645
+ });
1646
+
1647
+ // Close the menu
1648
+ _context37.next = 13;
1649
+ return _userEvent["default"].click(button);
1650
+ case 13:
1651
+ expect(_testWrapper.screen.queryByRole('listbox')).not.toBeInTheDocument();
1652
+
1653
+ // Simulate wrapper shrinking back
1654
+ mockWidth = 300;
1655
+
1656
+ // Reopen — width should reflect the new measurement
1657
+ _context37.next = 17;
1658
+ return _userEvent["default"].click(button);
1659
+ case 17:
1660
+ _context37.next = 19;
1661
+ return findListbox();
1662
+ case 19:
1663
+ listbox = _context37.sent;
1664
+ popoverContainer = listbox.closest('[role="presentation"]');
1665
+ expect(popoverContainer).toHaveStyle({
1666
+ width: '300px',
1667
+ 'min-width': '300px'
1668
+ });
1669
+ offsetWidthSpy.mockRestore();
1670
+ case 23:
1671
+ case "end":
1672
+ return _context37.stop();
1673
+ }
1674
+ }, _callee35);
1675
+ })));
1585
1676
  describe('when isReadOnly is true', function () {
1586
1677
  var testProp = {
1587
1678
  isReadOnly: true
@@ -1606,12 +1697,12 @@ describe('when isReadOnly is true', function () {
1606
1697
  name: defaultProps.label
1607
1698
  })).toHaveValue(TEST_DEFAULT_INPUT_VALUE);
1608
1699
  });
1609
- test('the dropdown does not open when clicked', /*#__PURE__*/(0, _asyncToGenerator2["default"])(/*#__PURE__*/_regeneratorRuntime().mark(function _callee34() {
1610
- return _regeneratorRuntime().wrap(function _callee34$(_context36) {
1611
- while (1) switch (_context36.prev = _context36.next) {
1700
+ test('the dropdown does not open when clicked', /*#__PURE__*/(0, _asyncToGenerator2["default"])(/*#__PURE__*/_regeneratorRuntime().mark(function _callee36() {
1701
+ return _regeneratorRuntime().wrap(function _callee36$(_context38) {
1702
+ while (1) switch (_context38.prev = _context38.next) {
1612
1703
  case 0:
1613
1704
  getComponent(testProp);
1614
- _context36.next = 3;
1705
+ _context38.next = 3;
1615
1706
  return _userEvent["default"].click(_testWrapper.screen.getByRole('combobox', {
1616
1707
  name: defaultProps.label
1617
1708
  }));
@@ -1621,9 +1712,9 @@ describe('when isReadOnly is true', function () {
1621
1712
  })).not.toBeInTheDocument();
1622
1713
  case 4:
1623
1714
  case "end":
1624
- return _context36.stop();
1715
+ return _context38.stop();
1625
1716
  }
1626
- }, _callee34);
1717
+ }, _callee36);
1627
1718
  })));
1628
1719
  });
1629
1720
  (0, _universalComponentTest.universalComponentTests)({
@@ -35,7 +35,6 @@ var sx = {
35
35
  },
36
36
  comboBoxFieldWrapperOpen: {
37
37
  position: 'absolute',
38
- transition: '0.2s width ease',
39
38
  width: '100%'
40
39
  },
41
40
  comboBoxFieldWrapperClose: {
@@ -177,7 +177,12 @@ var ComboBoxField = /*#__PURE__*/forwardRef(function (props, ref) {
177
177
  ref: inputWrapperRef,
178
178
  onResize: onResize
179
179
  });
180
- useLayoutEffect(onResize, [onResize]);
180
+
181
+ // Re-measure synchronously (before paint) whenever the menu opens or closes,
182
+ // so the Popover renders with the correct width on the first frame.
183
+ // Without state.isOpen in deps, width updates rely solely on ResizeObserver
184
+ // which fires asynchronously after paint, causing a visible flicker.
185
+ useLayoutEffect(onResize, [onResize, state.isOpen]);
181
186
  var style = _objectSpread(_objectSpread({}, overlayProps.style), {}, {
182
187
  width: menuWidth,
183
188
  minWidth: menuWidth
@@ -19,7 +19,7 @@ import _asyncToGenerator from "@babel/runtime-corejs3/helpers/esm/asyncToGenerat
19
19
  import _slicedToArray from "@babel/runtime-corejs3/helpers/esm/slicedToArray";
20
20
  import _extends from "@babel/runtime-corejs3/helpers/esm/extends";
21
21
  function ownKeys(e, r) { var t = _Object$keys(e); if (_Object$getOwnPropertySymbols) { var o = _Object$getOwnPropertySymbols(e); r && (o = _filterInstanceProperty(o).call(o, function (r) { return _Object$getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; }
22
- function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var _context37, _context38; var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? _forEachInstanceProperty(_context37 = ownKeys(Object(t), !0)).call(_context37, function (r) { _defineProperty(e, r, t[r]); }) : _Object$getOwnPropertyDescriptors ? _Object$defineProperties(e, _Object$getOwnPropertyDescriptors(t)) : _forEachInstanceProperty(_context38 = ownKeys(Object(t))).call(_context38, function (r) { _Object$defineProperty(e, r, _Object$getOwnPropertyDescriptor(t, r)); }); } return e; }
22
+ function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var _context39, _context40; var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? _forEachInstanceProperty(_context39 = ownKeys(Object(t), !0)).call(_context39, function (r) { _defineProperty(e, r, t[r]); }) : _Object$getOwnPropertyDescriptors ? _Object$defineProperties(e, _Object$getOwnPropertyDescriptors(t)) : _forEachInstanceProperty(_context40 = ownKeys(Object(t))).call(_context40, function (r) { _Object$defineProperty(e, r, _Object$getOwnPropertyDescriptor(t, r)); }); } return e; }
23
23
  function _regeneratorRuntime() { "use strict"; var r = _regenerator(), e = r.m(_regeneratorRuntime), t = (_Object$getPrototypeOf ? _Object$getPrototypeOf(e) : e.__proto__).constructor; function n(r) { var e = "function" == typeof r && r.constructor; return !!e && (e === t || "GeneratorFunction" === (e.displayName || e.name)); } var o = { "throw": 1, "return": 2, "break": 3, "continue": 3 }; function a(r) { var e, t; return function (n) { e || (e = { stop: function stop() { return t(n.a, 2); }, "catch": function _catch() { return n.v; }, abrupt: function abrupt(r, e) { return t(n.a, o[r], e); }, delegateYield: function delegateYield(r, o, a) { return e.resultName = o, t(n.d, _regeneratorValues(r), a); }, finish: function finish(r) { return t(n.f, r); } }, t = function t(r, _t, o) { n.p = e.prev, n.n = e.next; try { return r(_t, o); } finally { e.next = n.n; } }), e.resultName && (e[e.resultName] = n.v, e.resultName = void 0), e.sent = n.v, e.next = n.n; try { return r.call(this, e); } finally { n.p = e.prev, n.n = e.next; } }; } return (_regeneratorRuntime = function _regeneratorRuntime() { return { wrap: function wrap(e, t, n, o) { return r.w(a(e), t, n, o && _reverseInstanceProperty(o).call(o)); }, isGeneratorFunction: n, mark: r.m, awrap: function awrap(r, e) { return new _OverloadYield(r, e); }, AsyncIterator: _regeneratorAsyncIterator, async: function async(r, e, t, o, u) { return (n(e) ? _regeneratorAsyncGen : _regeneratorAsync)(a(r), e, t, o, u); }, keys: _regeneratorKeys, values: _regeneratorValues }; })(); }
24
24
  function _regeneratorValues(e) { if (null != e) { var t = e["function" == typeof _Symbol && _Symbol$iterator || "@@iterator"], r = 0; if (t) return t.call(e); if ("function" == typeof e.next) return e; if (!isNaN(e.length)) return { next: function next() { return e && r >= e.length && (e = void 0), { value: e && e[r++], done: !e }; } }; } throw new TypeError(_typeof(e) + " is not iterable"); }
25
25
  function _regeneratorKeys(e) { var n = Object(e), r = []; for (var t in n) r.unshift(t); return function e() { for (; r.length;) if ((t = r.pop()) in n) return e.value = t, e.done = !1, e; return e.done = !0, e; }; }
@@ -1575,6 +1575,97 @@ test('a blank title does not render', /*#__PURE__*/_asyncToGenerator(/*#__PURE__
1575
1575
  }
1576
1576
  }, _callee33);
1577
1577
  })));
1578
+ test('popover width re-measures when the menu opens to prevent flickering', /*#__PURE__*/_asyncToGenerator(/*#__PURE__*/_regeneratorRuntime().mark(function _callee34() {
1579
+ var mockWidth, offsetWidthSpy, button, listbox, popoverContainer;
1580
+ return _regeneratorRuntime().wrap(function _callee34$(_context36) {
1581
+ while (1) switch (_context36.prev = _context36.next) {
1582
+ case 0:
1583
+ // Simulate a scenario like the Country Picker recipe where the input wrapper
1584
+ // starts narrow (110px) and expands to full width when the menu opens.
1585
+ mockWidth = 110;
1586
+ offsetWidthSpy = jest.spyOn(window.HTMLElement.prototype, 'offsetWidth', 'get').mockImplementation(function () {
1587
+ return mockWidth;
1588
+ });
1589
+ getComponent();
1590
+
1591
+ // Simulate the wrapper expanding before the menu opens
1592
+ // (e.g., parent CSS changes from width: 110px to width: 100%)
1593
+ mockWidth = 500;
1594
+ button = screen.queryByRole('button');
1595
+ _context36.next = 7;
1596
+ return userEvent.click(button);
1597
+ case 7:
1598
+ _context36.next = 9;
1599
+ return findListbox();
1600
+ case 9:
1601
+ listbox = _context36.sent;
1602
+ // The popover container receives the inline style with width/minWidth.
1603
+ // Without the fix, menuWidth would be stale (110) because useLayoutEffect
1604
+ // only ran on mount. With the fix, it re-measures on state.isOpen change.
1605
+ popoverContainer = listbox.closest('[role="presentation"]');
1606
+ expect(popoverContainer).toHaveStyle({
1607
+ width: '500px',
1608
+ 'min-width': '500px'
1609
+ });
1610
+ offsetWidthSpy.mockRestore();
1611
+ case 13:
1612
+ case "end":
1613
+ return _context36.stop();
1614
+ }
1615
+ }, _callee34);
1616
+ })));
1617
+ test('popover width stays in sync when closing and reopening at different widths', /*#__PURE__*/_asyncToGenerator(/*#__PURE__*/_regeneratorRuntime().mark(function _callee35() {
1618
+ var mockWidth, offsetWidthSpy, button, listbox, popoverContainer;
1619
+ return _regeneratorRuntime().wrap(function _callee35$(_context37) {
1620
+ while (1) switch (_context37.prev = _context37.next) {
1621
+ case 0:
1622
+ mockWidth = 500;
1623
+ offsetWidthSpy = jest.spyOn(window.HTMLElement.prototype, 'offsetWidth', 'get').mockImplementation(function () {
1624
+ return mockWidth;
1625
+ });
1626
+ getComponent();
1627
+ button = screen.queryByRole('button'); // Open the menu at 500px
1628
+ _context37.next = 6;
1629
+ return userEvent.click(button);
1630
+ case 6:
1631
+ _context37.next = 8;
1632
+ return findListbox();
1633
+ case 8:
1634
+ listbox = _context37.sent;
1635
+ popoverContainer = listbox.closest('[role="presentation"]');
1636
+ expect(popoverContainer).toHaveStyle({
1637
+ width: '500px'
1638
+ });
1639
+
1640
+ // Close the menu
1641
+ _context37.next = 13;
1642
+ return userEvent.click(button);
1643
+ case 13:
1644
+ expect(screen.queryByRole('listbox')).not.toBeInTheDocument();
1645
+
1646
+ // Simulate wrapper shrinking back
1647
+ mockWidth = 300;
1648
+
1649
+ // Reopen — width should reflect the new measurement
1650
+ _context37.next = 17;
1651
+ return userEvent.click(button);
1652
+ case 17:
1653
+ _context37.next = 19;
1654
+ return findListbox();
1655
+ case 19:
1656
+ listbox = _context37.sent;
1657
+ popoverContainer = listbox.closest('[role="presentation"]');
1658
+ expect(popoverContainer).toHaveStyle({
1659
+ width: '300px',
1660
+ 'min-width': '300px'
1661
+ });
1662
+ offsetWidthSpy.mockRestore();
1663
+ case 23:
1664
+ case "end":
1665
+ return _context37.stop();
1666
+ }
1667
+ }, _callee35);
1668
+ })));
1578
1669
  describe('when isReadOnly is true', function () {
1579
1670
  var testProp = {
1580
1671
  isReadOnly: true
@@ -1599,12 +1690,12 @@ describe('when isReadOnly is true', function () {
1599
1690
  name: defaultProps.label
1600
1691
  })).toHaveValue(TEST_DEFAULT_INPUT_VALUE);
1601
1692
  });
1602
- test('the dropdown does not open when clicked', /*#__PURE__*/_asyncToGenerator(/*#__PURE__*/_regeneratorRuntime().mark(function _callee34() {
1603
- return _regeneratorRuntime().wrap(function _callee34$(_context36) {
1604
- while (1) switch (_context36.prev = _context36.next) {
1693
+ test('the dropdown does not open when clicked', /*#__PURE__*/_asyncToGenerator(/*#__PURE__*/_regeneratorRuntime().mark(function _callee36() {
1694
+ return _regeneratorRuntime().wrap(function _callee36$(_context38) {
1695
+ while (1) switch (_context38.prev = _context38.next) {
1605
1696
  case 0:
1606
1697
  getComponent(testProp);
1607
- _context36.next = 3;
1698
+ _context38.next = 3;
1608
1699
  return userEvent.click(screen.getByRole('combobox', {
1609
1700
  name: defaultProps.label
1610
1701
  }));
@@ -1614,9 +1705,9 @@ describe('when isReadOnly is true', function () {
1614
1705
  })).not.toBeInTheDocument();
1615
1706
  case 4:
1616
1707
  case "end":
1617
- return _context36.stop();
1708
+ return _context38.stop();
1618
1709
  }
1619
- }, _callee34);
1710
+ }, _callee36);
1620
1711
  })));
1621
1712
  });
1622
1713
  universalComponentTests({
@@ -23,7 +23,6 @@ var sx = {
23
23
  },
24
24
  comboBoxFieldWrapperOpen: {
25
25
  position: 'absolute',
26
- transition: '0.2s width ease',
27
26
  width: '100%'
28
27
  },
29
28
  comboBoxFieldWrapperClose: {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pingux/astro",
3
- "version": "2.193.1-alpha.0",
3
+ "version": "2.193.2-alpha.0",
4
4
  "description": "React component library for Ping Identity's design system",
5
5
  "repository": {
6
6
  "type": "git",