@atlassian/clientside-extensions 2.4.0-e0cce94-kuewz5ow

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.
Files changed (122) hide show
  1. package/LICENSE.txt +30 -0
  2. package/README.md +7 -0
  3. package/dist/cjs/AbstractExtension.js +22 -0
  4. package/dist/cjs/AbstractExtension.js.map +1 -0
  5. package/dist/cjs/AsyncPanelExtension.js +19 -0
  6. package/dist/cjs/AsyncPanelExtension.js.map +1 -0
  7. package/dist/cjs/AsyncPanelExtension.test.js +121 -0
  8. package/dist/cjs/AsyncPanelExtension.test.js.map +1 -0
  9. package/dist/cjs/ButtonExtension.js +13 -0
  10. package/dist/cjs/ButtonExtension.js.map +1 -0
  11. package/dist/cjs/ButtonExtension.test.js +49 -0
  12. package/dist/cjs/ButtonExtension.test.js.map +1 -0
  13. package/dist/cjs/LinkExtension.js +14 -0
  14. package/dist/cjs/LinkExtension.js.map +1 -0
  15. package/dist/cjs/LinkExtension.test.js +49 -0
  16. package/dist/cjs/LinkExtension.test.js.map +1 -0
  17. package/dist/cjs/ModalExtension.js +121 -0
  18. package/dist/cjs/ModalExtension.js.map +1 -0
  19. package/dist/cjs/ModalExtension.test.js +121 -0
  20. package/dist/cjs/ModalExtension.test.js.map +1 -0
  21. package/dist/cjs/PageExtension.js +13 -0
  22. package/dist/cjs/PageExtension.js.map +1 -0
  23. package/dist/cjs/PageExtension.test.js +34 -0
  24. package/dist/cjs/PageExtension.test.js.map +1 -0
  25. package/dist/cjs/PanelExtension.js +36 -0
  26. package/dist/cjs/PanelExtension.js.map +1 -0
  27. package/dist/cjs/PanelExtension.test.js +112 -0
  28. package/dist/cjs/PanelExtension.test.js.map +1 -0
  29. package/dist/cjs/SectionExtension.js +13 -0
  30. package/dist/cjs/SectionExtension.js.map +1 -0
  31. package/dist/cjs/SectionExtension.test.js +46 -0
  32. package/dist/cjs/SectionExtension.test.js.map +1 -0
  33. package/dist/cjs/extension-type.js +15 -0
  34. package/dist/cjs/extension-type.js.map +1 -0
  35. package/dist/cjs/index.js +21 -0
  36. package/dist/cjs/index.js.map +1 -0
  37. package/dist/esm/AbstractExtension.js +18 -0
  38. package/dist/esm/AbstractExtension.js.map +1 -0
  39. package/dist/esm/AsyncPanelExtension.js +16 -0
  40. package/dist/esm/AsyncPanelExtension.js.map +1 -0
  41. package/dist/esm/AsyncPanelExtension.test.js +118 -0
  42. package/dist/esm/AsyncPanelExtension.test.js.map +1 -0
  43. package/dist/esm/ButtonExtension.js +10 -0
  44. package/dist/esm/ButtonExtension.js.map +1 -0
  45. package/dist/esm/ButtonExtension.test.js +46 -0
  46. package/dist/esm/ButtonExtension.test.js.map +1 -0
  47. package/dist/esm/LinkExtension.js +11 -0
  48. package/dist/esm/LinkExtension.js.map +1 -0
  49. package/dist/esm/LinkExtension.test.js +46 -0
  50. package/dist/esm/LinkExtension.test.js.map +1 -0
  51. package/dist/esm/ModalExtension.js +117 -0
  52. package/dist/esm/ModalExtension.js.map +1 -0
  53. package/dist/esm/ModalExtension.test.js +118 -0
  54. package/dist/esm/ModalExtension.test.js.map +1 -0
  55. package/dist/esm/PageExtension.js +10 -0
  56. package/dist/esm/PageExtension.js.map +1 -0
  57. package/dist/esm/PageExtension.test.js +31 -0
  58. package/dist/esm/PageExtension.test.js.map +1 -0
  59. package/dist/esm/PanelExtension.js +32 -0
  60. package/dist/esm/PanelExtension.js.map +1 -0
  61. package/dist/esm/PanelExtension.test.js +109 -0
  62. package/dist/esm/PanelExtension.test.js.map +1 -0
  63. package/dist/esm/SectionExtension.js +10 -0
  64. package/dist/esm/SectionExtension.js.map +1 -0
  65. package/dist/esm/SectionExtension.test.js +43 -0
  66. package/dist/esm/SectionExtension.test.js.map +1 -0
  67. package/dist/esm/extension-type.js +12 -0
  68. package/dist/esm/extension-type.js.map +1 -0
  69. package/dist/esm/index.js +10 -0
  70. package/dist/esm/index.js.map +1 -0
  71. package/dist/types/AbstractExtension.d.ts +11 -0
  72. package/dist/types/AbstractExtension.d.ts.map +1 -0
  73. package/dist/types/AsyncPanelExtension.d.ts +18 -0
  74. package/dist/types/AsyncPanelExtension.d.ts.map +1 -0
  75. package/dist/types/AsyncPanelExtension.test.d.ts +2 -0
  76. package/dist/types/AsyncPanelExtension.test.d.ts.map +1 -0
  77. package/dist/types/ButtonExtension.d.ts +10 -0
  78. package/dist/types/ButtonExtension.d.ts.map +1 -0
  79. package/dist/types/ButtonExtension.test.d.ts +2 -0
  80. package/dist/types/ButtonExtension.test.d.ts.map +1 -0
  81. package/dist/types/LinkExtension.d.ts +11 -0
  82. package/dist/types/LinkExtension.d.ts.map +1 -0
  83. package/dist/types/LinkExtension.test.d.ts +2 -0
  84. package/dist/types/LinkExtension.test.d.ts.map +1 -0
  85. package/dist/types/ModalExtension.d.ts +60 -0
  86. package/dist/types/ModalExtension.d.ts.map +1 -0
  87. package/dist/types/ModalExtension.test.d.ts +2 -0
  88. package/dist/types/ModalExtension.test.d.ts.map +1 -0
  89. package/dist/types/PageExtension.d.ts +11 -0
  90. package/dist/types/PageExtension.d.ts.map +1 -0
  91. package/dist/types/PageExtension.test.d.ts +5 -0
  92. package/dist/types/PageExtension.test.d.ts.map +1 -0
  93. package/dist/types/PanelExtension.d.ts +19 -0
  94. package/dist/types/PanelExtension.d.ts.map +1 -0
  95. package/dist/types/PanelExtension.test.d.ts +2 -0
  96. package/dist/types/PanelExtension.test.d.ts.map +1 -0
  97. package/dist/types/SectionExtension.d.ts +8 -0
  98. package/dist/types/SectionExtension.d.ts.map +1 -0
  99. package/dist/types/SectionExtension.test.d.ts +2 -0
  100. package/dist/types/SectionExtension.test.d.ts.map +1 -0
  101. package/dist/types/extension-type.d.ts +10 -0
  102. package/dist/types/extension-type.d.ts.map +1 -0
  103. package/dist/types/index.d.ts +11 -0
  104. package/dist/types/index.d.ts.map +1 -0
  105. package/lib/AbstractExtension.ts +31 -0
  106. package/lib/AsyncPanelExtension.test.ts +145 -0
  107. package/lib/AsyncPanelExtension.ts +34 -0
  108. package/lib/ButtonExtension.test.ts +61 -0
  109. package/lib/ButtonExtension.ts +20 -0
  110. package/lib/LinkExtension.test.ts +61 -0
  111. package/lib/LinkExtension.ts +22 -0
  112. package/lib/ModalExtension.test.ts +147 -0
  113. package/lib/ModalExtension.ts +188 -0
  114. package/lib/PageExtension.test.ts +38 -0
  115. package/lib/PageExtension.ts +21 -0
  116. package/lib/PanelExtension.test.ts +134 -0
  117. package/lib/PanelExtension.ts +51 -0
  118. package/lib/SectionExtension.test.ts +57 -0
  119. package/lib/SectionExtension.ts +18 -0
  120. package/lib/extension-type.ts +10 -0
  121. package/lib/index.ts +21 -0
  122. package/package.json +79 -0
@@ -0,0 +1,34 @@
1
+ "use strict";
2
+ /**
3
+ * @jest-environment jsdom
4
+ */
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ const tslib_1 = require("tslib");
7
+ const PageExtension = tslib_1.__importStar(require("./PageExtension"));
8
+ describe('PageExtension', () => {
9
+ it('should generate the extension shape', () => {
10
+ // given
11
+ const fakeRenderCallback = jest.fn();
12
+ // when
13
+ const extensionProvider = PageExtension.factory(fakeRenderCallback);
14
+ const extension = extensionProvider();
15
+ // then
16
+ expect(extension).toEqual({
17
+ type: 'page',
18
+ onAction: expect.any(Function),
19
+ });
20
+ });
21
+ it('should call the render callback', () => {
22
+ // given
23
+ const fakeRenderCallback = jest.fn();
24
+ const extensionProvider = PageExtension.factory(fakeRenderCallback);
25
+ const extension = extensionProvider();
26
+ const fakeNode = document.createElement('div');
27
+ const fakeDataProvider = { foo: 'bar' };
28
+ // when
29
+ extension.onAction(fakeNode, fakeDataProvider);
30
+ // then
31
+ expect(fakeRenderCallback).toHaveBeenCalledWith(fakeNode, fakeDataProvider);
32
+ });
33
+ });
34
+ //# sourceMappingURL=PageExtension.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"PageExtension.test.js","sourceRoot":"","sources":["../../lib/PageExtension.test.ts"],"names":[],"mappings":";AAAA;;GAEG;;;AAEH,uEAAiD;AAEjD,QAAQ,CAAC,eAAe,EAAE,GAAG,EAAE;IAC3B,EAAE,CAAC,qCAAqC,EAAE,GAAG,EAAE;QAC3C,QAAQ;QACR,MAAM,kBAAkB,GAAG,IAAI,CAAC,EAAE,EAAE,CAAC;QAErC,OAAO;QACP,MAAM,iBAAiB,GAAG,aAAa,CAAC,OAAO,CAAC,kBAAkB,CAAC,CAAC;QACpE,MAAM,SAAS,GAAG,iBAAiB,EAAE,CAAC;QAEtC,OAAO;QACP,MAAM,CAAC,SAAS,CAAC,CAAC,OAAO,CAAC;YACtB,IAAI,EAAE,MAAM;YACZ,QAAQ,EAAE,MAAM,CAAC,GAAG,CAAC,QAAQ,CAAC;SACjC,CAAC,CAAC;IACP,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,iCAAiC,EAAE,GAAG,EAAE;QACvC,QAAQ;QACR,MAAM,kBAAkB,GAAG,IAAI,CAAC,EAAE,EAAE,CAAC;QACrC,MAAM,iBAAiB,GAAG,aAAa,CAAC,OAAO,CAAC,kBAAkB,CAAC,CAAC;QACpE,MAAM,SAAS,GAAG,iBAAiB,EAAE,CAAC;QAEtC,MAAM,QAAQ,GAAG,QAAQ,CAAC,aAAa,CAAC,KAAK,CAAC,CAAC;QAC/C,MAAM,gBAAgB,GAAG,EAAE,GAAG,EAAE,KAAK,EAAE,CAAC;QAExC,OAAO;QACP,SAAS,CAAC,QAAQ,CAAC,QAAQ,EAAE,gBAAgB,CAAC,CAAC;QAE/C,OAAO;QACP,MAAM,CAAC,kBAAkB,CAAC,CAAC,oBAAoB,CAAC,QAAQ,EAAE,gBAAgB,CAAC,CAAC;IAChF,CAAC,CAAC,CAAC;AACP,CAAC,CAAC,CAAC"}
@@ -0,0 +1,36 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.Api = exports.factory = void 0;
4
+ const extension_type_1 = require("./extension-type");
5
+ const AbstractExtension_1 = require("./AbstractExtension");
6
+ exports.factory = (provider) => {
7
+ return (...args) => {
8
+ return {
9
+ ...provider(...args),
10
+ type: extension_type_1.ExtensionType.panel,
11
+ };
12
+ };
13
+ };
14
+ const noop = () => { };
15
+ class Api {
16
+ constructor() {
17
+ this.renderCallback = noop;
18
+ this.cleanupCallback = noop;
19
+ }
20
+ onMount(callback) {
21
+ this.renderCallback = AbstractExtension_1.safeguard('onMount', callback);
22
+ return this;
23
+ }
24
+ onUnmount(callback) {
25
+ this.cleanupCallback = AbstractExtension_1.safeguard('onUnmount', callback);
26
+ return this;
27
+ }
28
+ getRenderCallback() {
29
+ return this.renderCallback;
30
+ }
31
+ getCleanupCallback() {
32
+ return this.cleanupCallback;
33
+ }
34
+ }
35
+ exports.Api = Api;
36
+ //# sourceMappingURL=PanelExtension.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"PanelExtension.js","sourceRoot":"","sources":["../../lib/PanelExtension.ts"],"names":[],"mappings":";;;AAEA,qDAAiD;AAEjD,2DAAgD;AAWnC,QAAA,OAAO,GAAG,CAAW,QAA2C,EAAqC,EAAE;IAChH,OAAO,CAAC,GAAG,IAAI,EAAE,EAAE;QACf,OAAO;YACH,GAAG,QAAQ,CAAC,GAAG,IAAI,CAAC;YACpB,IAAI,EAAE,8BAAa,CAAC,KAAK;SAC5B,CAAC;IACN,CAAC,CAAC;AACN,CAAC,CAAC;AAEF,MAAM,IAAI,GAAG,GAAG,EAAE,GAAE,CAAC,CAAC;AAEtB,MAAa,GAAG;IAAhB;QACY,mBAAc,GAAsB,IAAI,CAAC;QAEzC,oBAAe,GAAsB,IAAI,CAAC;IAqBtD,CAAC;IAnBU,OAAO,CAAC,QAA2B;QACtC,IAAI,CAAC,cAAc,GAAG,6BAAS,CAAC,SAAS,EAAE,QAAQ,CAAC,CAAC;QAErD,OAAO,IAAI,CAAC;IAChB,CAAC;IAEM,SAAS,CAAC,QAA2B;QACxC,IAAI,CAAC,eAAe,GAAG,6BAAS,CAAC,WAAW,EAAE,QAAQ,CAAC,CAAC;QAExD,OAAO,IAAI,CAAC;IAChB,CAAC;IAEM,iBAAiB;QACpB,OAAO,IAAI,CAAC,cAAc,CAAC;IAC/B,CAAC;IAEM,kBAAkB;QACrB,OAAO,IAAI,CAAC,eAAe,CAAC;IAChC,CAAC;CACJ;AAxBD,kBAwBC"}
@@ -0,0 +1,112 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const tslib_1 = require("tslib");
4
+ const clientside_extensions_debug_1 = require("@atlassian/clientside-extensions-debug");
5
+ const PanelExtension = tslib_1.__importStar(require("./PanelExtension"));
6
+ jest.mock('@atlassian/clientside-extensions-debug');
7
+ describe('PanelExtension', () => {
8
+ // @ts-expect-error - invalid values for type. Factory should overwrite it.
9
+ const testAttributesProvider = (api, context) => {
10
+ api.onCleanup(jest.fn());
11
+ api.updateAttributes({});
12
+ return {
13
+ type: 'not-valid',
14
+ label: context.value === 42 ? 'The meaning of life' : 'A label',
15
+ onAction: jest.fn(),
16
+ };
17
+ };
18
+ const testAPI = {
19
+ onCleanup: jest.fn(),
20
+ updateAttributes: jest.fn(),
21
+ };
22
+ it('should generate the extension descriptor with the correct type', () => {
23
+ const extensionProvider = PanelExtension.factory(testAttributesProvider);
24
+ const extension = extensionProvider(testAPI, {});
25
+ // expect all attributes to be merged, and type to be overwritten with the correct value.
26
+ expect(extension).toEqual({
27
+ type: 'panel',
28
+ label: 'A label',
29
+ onAction: expect.any(Function),
30
+ });
31
+ });
32
+ it('should provide a extensionAPI object to the extension provider', () => {
33
+ expect(testAPI.onCleanup).toHaveBeenCalledTimes(0);
34
+ expect(testAPI.updateAttributes).toHaveBeenCalledTimes(0);
35
+ const extensionProvider = PanelExtension.factory(testAttributesProvider);
36
+ extensionProvider(testAPI, {});
37
+ expect(testAPI.onCleanup).toHaveBeenCalledTimes(1);
38
+ expect(testAPI.updateAttributes).toHaveBeenCalledTimes(1);
39
+ });
40
+ it('should share any provided context with the attributes provider', () => {
41
+ const extensionProvider = PanelExtension.factory(testAttributesProvider);
42
+ const extension = extensionProvider(testAPI, { value: 42 });
43
+ // expect label to change because of context
44
+ expect(extension).toEqual({
45
+ type: 'panel',
46
+ label: 'The meaning of life',
47
+ onAction: expect.any(Function),
48
+ });
49
+ });
50
+ describe('API', () => {
51
+ let api;
52
+ const el = document.createElement('div');
53
+ beforeEach(() => {
54
+ api = new PanelExtension.Api();
55
+ });
56
+ it('#onMount callback used in getRenderCallback', () => {
57
+ const cb = jest.fn();
58
+ api.onMount(cb);
59
+ api.getRenderCallback()(el);
60
+ expect(cb).toHaveBeenCalledTimes(1);
61
+ });
62
+ it('#onMount does nothing if not set', () => {
63
+ expect(() => {
64
+ api.getRenderCallback()(el);
65
+ }).not.toThrow();
66
+ });
67
+ it('#onMount does nothing if callback is not function', () => {
68
+ // @ts-expect-error checking that non-TS consumers don't shoot themselves (or others) in the foot
69
+ api.onMount(null);
70
+ expect(() => {
71
+ api.getRenderCallback()(el);
72
+ }).not.toThrow();
73
+ });
74
+ it('#onMount fails gracefully if callback throws error', () => {
75
+ api.onMount(() => {
76
+ throw Error('whoops');
77
+ });
78
+ expect(() => {
79
+ api.getRenderCallback()(el);
80
+ }).not.toThrow();
81
+ });
82
+ it('#onUnmount callback used in getCleanupCallback', () => {
83
+ const cb = jest.fn();
84
+ api.onUnmount(cb);
85
+ api.getCleanupCallback()(el);
86
+ expect(cb).toHaveBeenCalledTimes(1);
87
+ });
88
+ it('#onUnmount does nothing if not set', () => {
89
+ expect(() => {
90
+ api.getCleanupCallback()(el);
91
+ }).not.toThrow();
92
+ });
93
+ it('#onUnmount does nothing if callback is not function', () => {
94
+ // @ts-expect-error checking that non-TS consumers don't shoot themselves (or others) in the foot
95
+ api.onUnmount(null);
96
+ expect(() => {
97
+ api.getCleanupCallback()(el);
98
+ }).not.toThrow();
99
+ expect(clientside_extensions_debug_1.onDebug).toHaveBeenCalledTimes(1);
100
+ });
101
+ it('#onUnmount fails gracefully if callback throws error', () => {
102
+ api.onUnmount(() => {
103
+ throw Error('whoops');
104
+ });
105
+ expect(() => {
106
+ api.getCleanupCallback()(el);
107
+ }).not.toThrow();
108
+ expect(clientside_extensions_debug_1.onDebug).toHaveBeenCalledTimes(1);
109
+ });
110
+ });
111
+ });
112
+ //# sourceMappingURL=PanelExtension.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"PanelExtension.test.js","sourceRoot":"","sources":["../../lib/PanelExtension.test.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,13 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.factory = void 0;
4
+ const extension_type_1 = require("./extension-type");
5
+ exports.factory = (provider) => {
6
+ return (...args) => {
7
+ return {
8
+ ...provider(...args),
9
+ type: extension_type_1.ExtensionType.section,
10
+ };
11
+ };
12
+ };
13
+ //# sourceMappingURL=SectionExtension.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"SectionExtension.js","sourceRoot":"","sources":["../../lib/SectionExtension.ts"],"names":[],"mappings":";;;AAEA,qDAAiD;AAQpC,QAAA,OAAO,GAAG,CAAW,QAA6C,EAAuC,EAAE;IACpH,OAAO,CAAC,GAAG,IAAI,EAAE,EAAE;QACf,OAAO;YACH,GAAG,QAAQ,CAAC,GAAG,IAAI,CAAC;YACpB,IAAI,EAAE,8BAAa,CAAC,OAAO;SAC9B,CAAC;IACN,CAAC,CAAC;AACN,CAAC,CAAC"}
@@ -0,0 +1,46 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const tslib_1 = require("tslib");
4
+ const SectionExtension = tslib_1.__importStar(require("./SectionExtension"));
5
+ describe('SectionExtension', () => {
6
+ // @ts-expect-error we set the invalid type
7
+ const testAttributesProvider = (api, context) => {
8
+ api.onCleanup(jest.fn());
9
+ api.updateAttributes({});
10
+ return {
11
+ type: 'not-valid',
12
+ label: context.value === 42 ? 'The meaning of life' : 'A label',
13
+ };
14
+ };
15
+ const testAPI = {
16
+ onCleanup: jest.fn(),
17
+ updateAttributes: jest.fn(),
18
+ };
19
+ it('should generate the extension descriptor with the correct type', () => {
20
+ const extensionProvider = SectionExtension.factory(testAttributesProvider);
21
+ const extension = extensionProvider(testAPI, {});
22
+ // expect all attributes to be merged, and type to be overwritten with the correct value.
23
+ expect(extension).toEqual({
24
+ type: 'section',
25
+ label: 'A label',
26
+ });
27
+ });
28
+ it('should provide a extensionAPI object to the extension provider', () => {
29
+ expect(testAPI.onCleanup).toHaveBeenCalledTimes(0);
30
+ expect(testAPI.updateAttributes).toHaveBeenCalledTimes(0);
31
+ const extensionProvider = SectionExtension.factory(testAttributesProvider);
32
+ extensionProvider(testAPI, {});
33
+ expect(testAPI.onCleanup).toHaveBeenCalledTimes(1);
34
+ expect(testAPI.updateAttributes).toHaveBeenCalledTimes(1);
35
+ });
36
+ it('should share any provided context with the attributes provider', () => {
37
+ const extensionProvider = SectionExtension.factory(testAttributesProvider);
38
+ const extension = extensionProvider(testAPI, { value: 42 });
39
+ // expect label to change because of context
40
+ expect(extension).toEqual({
41
+ type: 'section',
42
+ label: 'The meaning of life',
43
+ });
44
+ });
45
+ });
46
+ //# sourceMappingURL=SectionExtension.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"SectionExtension.test.js","sourceRoot":"","sources":["../../lib/SectionExtension.test.ts"],"names":[],"mappings":";;;AACA,6EAAuD;AAOvD,QAAQ,CAAC,kBAAkB,EAAE,GAAG,EAAE;IAC9B,2CAA2C;IAC3C,MAAM,sBAAsB,GAA8B,CAAC,GAAG,EAAE,OAAoB,EAAE,EAAE;QACpF,GAAG,CAAC,SAAS,CAAC,IAAI,CAAC,EAAE,EAAE,CAAC,CAAC;QACzB,GAAG,CAAC,gBAAgB,CAAC,EAAE,CAAC,CAAC;QAEzB,OAAO;YACH,IAAI,EAAE,WAAW;YACjB,KAAK,EAAE,OAAO,CAAC,KAAK,KAAK,EAAE,CAAC,CAAC,CAAC,qBAAqB,CAAC,CAAC,CAAC,SAAS;SAClE,CAAC;IACN,CAAC,CAAC;IACF,MAAM,OAAO,GAAgD;QACzD,SAAS,EAAE,IAAI,CAAC,EAAE,EAAE;QACpB,gBAAgB,EAAE,IAAI,CAAC,EAAE,EAAE;KAC9B,CAAC;IAEF,EAAE,CAAC,gEAAgE,EAAE,GAAG,EAAE;QACtE,MAAM,iBAAiB,GAAG,gBAAgB,CAAC,OAAO,CAAC,sBAAsB,CAAC,CAAC;QAC3E,MAAM,SAAS,GAAG,iBAAiB,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC;QAEjD,yFAAyF;QACzF,MAAM,CAAC,SAAS,CAAC,CAAC,OAAO,CAAC;YACtB,IAAI,EAAE,SAAS;YACf,KAAK,EAAE,SAAS;SACnB,CAAC,CAAC;IACP,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,gEAAgE,EAAE,GAAG,EAAE;QACtE,MAAM,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC,qBAAqB,CAAC,CAAC,CAAC,CAAC;QACnD,MAAM,CAAC,OAAO,CAAC,gBAAgB,CAAC,CAAC,qBAAqB,CAAC,CAAC,CAAC,CAAC;QAE1D,MAAM,iBAAiB,GAAG,gBAAgB,CAAC,OAAO,CAAC,sBAAsB,CAAC,CAAC;QAC3E,iBAAiB,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC;QAE/B,MAAM,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC,qBAAqB,CAAC,CAAC,CAAC,CAAC;QACnD,MAAM,CAAC,OAAO,CAAC,gBAAgB,CAAC,CAAC,qBAAqB,CAAC,CAAC,CAAC,CAAC;IAC9D,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,gEAAgE,EAAE,GAAG,EAAE;QACtE,MAAM,iBAAiB,GAAG,gBAAgB,CAAC,OAAO,CAAC,sBAAsB,CAAC,CAAC;QAC3E,MAAM,SAAS,GAAG,iBAAiB,CAAC,OAAO,EAAE,EAAE,KAAK,EAAE,EAAE,EAAE,CAAC,CAAC;QAE5D,4CAA4C;QAC5C,MAAM,CAAC,SAAS,CAAC,CAAC,OAAO,CAAC;YACtB,IAAI,EAAE,SAAS;YACf,KAAK,EAAE,qBAAqB;SAC/B,CAAC,CAAC;IACP,CAAC,CAAC,CAAC;AACP,CAAC,CAAC,CAAC"}
@@ -0,0 +1,15 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.ExtensionType = void 0;
4
+ // eslint-disable-next-line import/prefer-default-export
5
+ var ExtensionType;
6
+ (function (ExtensionType) {
7
+ ExtensionType["asyncPanel"] = "async-panel";
8
+ ExtensionType["button"] = "button";
9
+ ExtensionType["link"] = "link";
10
+ ExtensionType["modal"] = "modal";
11
+ ExtensionType["panel"] = "panel";
12
+ ExtensionType["page"] = "page";
13
+ ExtensionType["section"] = "section";
14
+ })(ExtensionType = exports.ExtensionType || (exports.ExtensionType = {}));
15
+ //# sourceMappingURL=extension-type.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"extension-type.js","sourceRoot":"","sources":["../../lib/extension-type.ts"],"names":[],"mappings":";;;AAAA,wDAAwD;AACxD,IAAY,aAQX;AARD,WAAY,aAAa;IACrB,2CAA4B,CAAA;IAC5B,kCAAiB,CAAA;IACjB,8BAAa,CAAA;IACb,gCAAe,CAAA;IACf,gCAAe,CAAA;IACf,8BAAa,CAAA;IACb,oCAAmB,CAAA;AACvB,CAAC,EARW,aAAa,GAAb,qBAAa,KAAb,qBAAa,QAQxB"}
@@ -0,0 +1,21 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.ExtensionType = exports.PageExtension = exports.SectionExtension = exports.PanelExtension = exports.ModalExtension = exports.LinkExtension = exports.ButtonExtension = exports.AsyncPanelExtension = void 0;
4
+ const tslib_1 = require("tslib");
5
+ const AsyncPanelExtension = tslib_1.__importStar(require("./AsyncPanelExtension"));
6
+ exports.AsyncPanelExtension = AsyncPanelExtension;
7
+ const ButtonExtension = tslib_1.__importStar(require("./ButtonExtension"));
8
+ exports.ButtonExtension = ButtonExtension;
9
+ const LinkExtension = tslib_1.__importStar(require("./LinkExtension"));
10
+ exports.LinkExtension = LinkExtension;
11
+ const ModalExtension = tslib_1.__importStar(require("./ModalExtension"));
12
+ exports.ModalExtension = ModalExtension;
13
+ const PanelExtension = tslib_1.__importStar(require("./PanelExtension"));
14
+ exports.PanelExtension = PanelExtension;
15
+ const SectionExtension = tslib_1.__importStar(require("./SectionExtension"));
16
+ exports.SectionExtension = SectionExtension;
17
+ const PageExtension = tslib_1.__importStar(require("./PageExtension"));
18
+ exports.PageExtension = PageExtension;
19
+ const extension_type_1 = require("./extension-type");
20
+ Object.defineProperty(exports, "ExtensionType", { enumerable: true, get: function () { return extension_type_1.ExtensionType; } });
21
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../lib/index.ts"],"names":[],"mappings":";;;;AAAA,mFAA6D;AAYzD,kDAAmB;AAXvB,2EAAqD;AAYjD,0CAAe;AAXnB,uEAAiD;AAY7C,sCAAa;AAXjB,yEAAmD;AAY/C,wCAAc;AAXlB,yEAAmD;AAY/C,wCAAc;AAXlB,6EAAuD;AAYnD,4CAAgB;AAXpB,uEAAiD;AAY7C,sCAAa;AAXjB,qDAAiD;AAY7C,8FAZK,8BAAa,OAYL"}
@@ -0,0 +1,18 @@
1
+ import { onDebug } from '@atlassian/clientside-extensions-debug';
2
+ export function safeguard(callbackDebugName, callback) {
3
+ return (...args) => {
4
+ let result;
5
+ try {
6
+ result = callback(...args);
7
+ }
8
+ catch (e) {
9
+ onDebug(({ error }) => ({
10
+ level: error,
11
+ message: `Failed to execute ${callbackDebugName} callback.
12
+ Error: ${e}`,
13
+ }));
14
+ }
15
+ return result;
16
+ };
17
+ }
18
+ //# sourceMappingURL=AbstractExtension.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"AbstractExtension.js","sourceRoot":"","sources":["../../lib/AbstractExtension.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,wCAAwC,CAAC;AAgBjE,MAAM,UAAU,SAAS,CAAqB,iBAAyB,EAAE,QAAW;IAChF,OAAO,CAAC,GAAG,IAAmB,EAAE,EAAE;QAC9B,IAAI,MAAM,CAAC;QACX,IAAI;YACA,MAAM,GAAG,QAAQ,CAAC,GAAG,IAAI,CAAC,CAAC;SAC9B;QAAC,OAAO,CAAC,EAAE;YACR,OAAO,CAAC,CAAC,EAAE,KAAK,EAAE,EAAE,EAAE,CAAC,CAAC;gBACpB,KAAK,EAAE,KAAK;gBACZ,OAAO,EAAE,qBAAqB,iBAAiB;aAClD,CAAC,EAAE;aACH,CAAC,CAAC,CAAC;SACP;QACD,OAAO,MAAM,CAAC;IAClB,CAAC,CAAC;AACN,CAAC"}
@@ -0,0 +1,16 @@
1
+ import { Api } from './PanelExtension';
2
+ import { ExtensionType } from './extension-type';
3
+ export const factory = (provider) => {
4
+ return (extensionApi, context) => {
5
+ return {
6
+ ...provider(extensionApi, context),
7
+ // We are passing the context provider function reference into the <AsyncPanelHandler.AsyncPanelRenderer> component
8
+ contextProvider() {
9
+ return context;
10
+ },
11
+ type: ExtensionType.asyncPanel,
12
+ };
13
+ };
14
+ };
15
+ export { Api };
16
+ //# sourceMappingURL=AsyncPanelExtension.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"AsyncPanelExtension.js","sourceRoot":"","sources":["../../lib/AsyncPanelExtension.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,GAAG,EAAE,MAAM,kBAAkB,CAAC;AACvC,OAAO,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAC;AAiBjD,MAAM,CAAC,MAAM,OAAO,GAAG,CAAW,QAAgD,EAAqD,EAAE;IACrI,OAAO,CAAC,YAAY,EAAE,OAAO,EAAmC,EAAE;QAC9D,OAAO;YACH,GAAG,QAAQ,CAAC,YAAY,EAAE,OAAO,CAAC;YAClC,mHAAmH;YACnH,eAAe;gBACX,OAAO,OAAO,CAAC;YACnB,CAAC;YACD,IAAI,EAAE,aAAa,CAAC,UAAU;SACjC,CAAC;IACN,CAAC,CAAC;AACN,CAAC,CAAC;AAEF,OAAO,EAAE,GAAG,EAAE,CAAC"}
@@ -0,0 +1,118 @@
1
+ import { onDebug } from '@atlassian/clientside-extensions-debug';
2
+ import * as AsyncPanelExtension from './AsyncPanelExtension';
3
+ jest.mock('@atlassian/clientside-extensions-debug');
4
+ describe('AsyncPanelExtension', () => {
5
+ // @ts-expect-error - invalid values for contextProvider and type. Factory should overwrite them.
6
+ const testAttributesProvider = (api, context) => {
7
+ api.onCleanup(jest.fn());
8
+ api.updateAttributes({});
9
+ return {
10
+ type: 'not-valid',
11
+ contextProvider: 'not-valid-context-provider',
12
+ label: context.value === 42 ? 'The meaning of life' : 'A label',
13
+ onAction: jest.fn(),
14
+ };
15
+ };
16
+ const testAPI = {
17
+ onCleanup: jest.fn(),
18
+ updateAttributes: jest.fn(),
19
+ };
20
+ it('should generate the extension descriptor with the correct type and contextProvider', () => {
21
+ const extensionProvider = AsyncPanelExtension.factory(testAttributesProvider);
22
+ const extension = extensionProvider(testAPI, {});
23
+ // expect all attributes to be merged, type and contextProvider to be overwritten with the correct values.
24
+ expect(extension).toEqual({
25
+ type: 'async-panel',
26
+ label: 'A label',
27
+ onAction: expect.any(Function),
28
+ contextProvider: expect.any(Function),
29
+ });
30
+ });
31
+ it('should provide a extensionAPI object to the extension provider', () => {
32
+ expect(testAPI.onCleanup).toHaveBeenCalledTimes(0);
33
+ expect(testAPI.updateAttributes).toHaveBeenCalledTimes(0);
34
+ const extensionProvider = AsyncPanelExtension.factory(testAttributesProvider);
35
+ extensionProvider(testAPI, {});
36
+ expect(testAPI.onCleanup).toHaveBeenCalledTimes(1);
37
+ expect(testAPI.updateAttributes).toHaveBeenCalledTimes(1);
38
+ });
39
+ it('should share any provided context with the attributes provider', () => {
40
+ const extensionProvider = AsyncPanelExtension.factory(testAttributesProvider);
41
+ const extension = extensionProvider(testAPI, { value: 42 });
42
+ // expect label to change because of context
43
+ expect(extension).toEqual({
44
+ type: 'async-panel',
45
+ label: 'The meaning of life',
46
+ onAction: expect.any(Function),
47
+ contextProvider: expect.any(Function),
48
+ });
49
+ });
50
+ it('should add a contextProvider method to retreive the shared context', () => {
51
+ const extensionProvider = AsyncPanelExtension.factory(testAttributesProvider);
52
+ const testContext = { value: 42 };
53
+ const extension = extensionProvider(testAPI, testContext);
54
+ expect(extension.contextProvider()).toBe(testContext);
55
+ });
56
+ describe('API', () => {
57
+ let api;
58
+ const el = document.createElement('div');
59
+ beforeEach(() => {
60
+ api = new AsyncPanelExtension.Api();
61
+ });
62
+ it('#onMount callback used in getRenderCallback', () => {
63
+ const cb = jest.fn();
64
+ api.onMount(cb);
65
+ api.getRenderCallback()(el);
66
+ expect(cb).toHaveBeenCalledTimes(1);
67
+ });
68
+ it('#onMount does nothing if not set', () => {
69
+ expect(() => {
70
+ api.getRenderCallback()(el);
71
+ }).not.toThrow();
72
+ });
73
+ it('#onMount does nothing if callback is not function', () => {
74
+ // @ts-expect-error checking that non-TS consumers don't shoot themselves (or others) in the foot
75
+ api.onMount(null);
76
+ expect(() => {
77
+ api.getRenderCallback()(el);
78
+ }).not.toThrow();
79
+ });
80
+ it('#onMount fails gracefully if callback throws error', () => {
81
+ api.onMount(() => {
82
+ throw Error('whoops');
83
+ });
84
+ expect(() => {
85
+ api.getRenderCallback()(el);
86
+ }).not.toThrow();
87
+ });
88
+ it('#onUnmount callback used in getCleanupCallback', () => {
89
+ const cb = jest.fn();
90
+ api.onUnmount(cb);
91
+ api.getCleanupCallback()(el);
92
+ expect(cb).toHaveBeenCalledTimes(1);
93
+ });
94
+ it('#onUnmount does nothing if not set', () => {
95
+ expect(() => {
96
+ api.getCleanupCallback()(el);
97
+ }).not.toThrow();
98
+ });
99
+ it('#onUnmount does nothing if callback is not function', () => {
100
+ // @ts-expect-error checking that non-TS consumers don't shoot themselves (or others) in the foot
101
+ api.onUnmount(null);
102
+ expect(() => {
103
+ api.getCleanupCallback()(el);
104
+ }).not.toThrow();
105
+ expect(onDebug).toHaveBeenCalledTimes(1);
106
+ });
107
+ it('#onUnmount fails gracefully if callback throws error', () => {
108
+ api.onUnmount(() => {
109
+ throw Error('whoops');
110
+ });
111
+ expect(() => {
112
+ api.getCleanupCallback()(el);
113
+ }).not.toThrow();
114
+ expect(onDebug).toHaveBeenCalledTimes(1);
115
+ });
116
+ });
117
+ });
118
+ //# sourceMappingURL=AsyncPanelExtension.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"AsyncPanelExtension.test.js","sourceRoot":"","sources":["../../lib/AsyncPanelExtension.test.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,OAAO,EAAE,MAAM,wCAAwC,CAAC;AACjE,OAAO,KAAK,mBAAmB,MAAM,uBAAuB,CAAC;AAE7D,IAAI,CAAC,IAAI,CAAC,wCAAwC,CAAC,CAAC;AAMpD,QAAQ,CAAC,qBAAqB,EAAE,GAAG,EAAE;IACjC,iGAAiG;IACjG,MAAM,sBAAsB,GAAqD,CAAC,GAAG,EAAE,OAAoB,EAAE,EAAE;QAC3G,GAAG,CAAC,SAAS,CAAC,IAAI,CAAC,EAAE,EAAE,CAAC,CAAC;QACzB,GAAG,CAAC,gBAAgB,CAAC,EAAE,CAAC,CAAC;QAEzB,OAAO;YACH,IAAI,EAAE,WAAW;YACjB,eAAe,EAAE,4BAA4B;YAC7C,KAAK,EAAE,OAAO,CAAC,KAAK,KAAK,EAAE,CAAC,CAAC,CAAC,qBAAqB,CAAC,CAAC,CAAC,SAAS;YAC/D,QAAQ,EAAE,IAAI,CAAC,EAAE,EAAE;SACtB,CAAC;IACN,CAAC,CAAC;IAEF,MAAM,OAAO,GAAgD;QACzD,SAAS,EAAE,IAAI,CAAC,EAAE,EAAE;QACpB,gBAAgB,EAAE,IAAI,CAAC,EAAE,EAAE;KAC9B,CAAC;IAEF,EAAE,CAAC,oFAAoF,EAAE,GAAG,EAAE;QAC1F,MAAM,iBAAiB,GAAG,mBAAmB,CAAC,OAAO,CAAC,sBAAsB,CAAC,CAAC;QAC9E,MAAM,SAAS,GAAG,iBAAiB,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC;QAEjD,0GAA0G;QAC1G,MAAM,CAAC,SAAS,CAAC,CAAC,OAAO,CAAC;YACtB,IAAI,EAAE,aAAa;YACnB,KAAK,EAAE,SAAS;YAChB,QAAQ,EAAE,MAAM,CAAC,GAAG,CAAC,QAAQ,CAAC;YAC9B,eAAe,EAAE,MAAM,CAAC,GAAG,CAAC,QAAQ,CAAC;SACxC,CAAC,CAAC;IACP,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,gEAAgE,EAAE,GAAG,EAAE;QACtE,MAAM,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC,qBAAqB,CAAC,CAAC,CAAC,CAAC;QACnD,MAAM,CAAC,OAAO,CAAC,gBAAgB,CAAC,CAAC,qBAAqB,CAAC,CAAC,CAAC,CAAC;QAE1D,MAAM,iBAAiB,GAAG,mBAAmB,CAAC,OAAO,CAAC,sBAAsB,CAAC,CAAC;QAC9E,iBAAiB,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC;QAE/B,MAAM,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC,qBAAqB,CAAC,CAAC,CAAC,CAAC;QACnD,MAAM,CAAC,OAAO,CAAC,gBAAgB,CAAC,CAAC,qBAAqB,CAAC,CAAC,CAAC,CAAC;IAC9D,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,gEAAgE,EAAE,GAAG,EAAE;QACtE,MAAM,iBAAiB,GAAG,mBAAmB,CAAC,OAAO,CAAC,sBAAsB,CAAC,CAAC;QAC9E,MAAM,SAAS,GAAG,iBAAiB,CAAC,OAAO,EAAE,EAAE,KAAK,EAAE,EAAE,EAAE,CAAC,CAAC;QAE5D,4CAA4C;QAC5C,MAAM,CAAC,SAAS,CAAC,CAAC,OAAO,CAAC;YACtB,IAAI,EAAE,aAAa;YACnB,KAAK,EAAE,qBAAqB;YAC5B,QAAQ,EAAE,MAAM,CAAC,GAAG,CAAC,QAAQ,CAAC;YAC9B,eAAe,EAAE,MAAM,CAAC,GAAG,CAAC,QAAQ,CAAC;SACxC,CAAC,CAAC;IACP,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,oEAAoE,EAAE,GAAG,EAAE;QAC1E,MAAM,iBAAiB,GAAG,mBAAmB,CAAC,OAAO,CAAC,sBAAsB,CAAC,CAAC;QAC9E,MAAM,WAAW,GAAgB,EAAE,KAAK,EAAE,EAAE,EAAE,CAAC;QAC/C,MAAM,SAAS,GAAG,iBAAiB,CAAC,OAAO,EAAE,WAAW,CAAC,CAAC;QAE1D,MAAM,CAAC,SAAS,CAAC,eAAe,EAAE,CAAC,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC;IAC1D,CAAC,CAAC,CAAC;IAEH,QAAQ,CAAC,KAAK,EAAE,GAAG,EAAE;QACjB,IAAI,GAA4B,CAAC;QACjC,MAAM,EAAE,GAAgB,QAAQ,CAAC,aAAa,CAAC,KAAK,CAAC,CAAC;QAEtD,UAAU,CAAC,GAAG,EAAE;YACZ,GAAG,GAAG,IAAI,mBAAmB,CAAC,GAAG,EAAE,CAAC;QACxC,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,6CAA6C,EAAE,GAAG,EAAE;YACnD,MAAM,EAAE,GAAG,IAAI,CAAC,EAAE,EAAE,CAAC;YACrB,GAAG,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC;YAChB,GAAG,CAAC,iBAAiB,EAAE,CAAC,EAAE,CAAC,CAAC;YAC5B,MAAM,CAAC,EAAE,CAAC,CAAC,qBAAqB,CAAC,CAAC,CAAC,CAAC;QACxC,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,kCAAkC,EAAE,GAAG,EAAE;YACxC,MAAM,CAAC,GAAG,EAAE;gBACR,GAAG,CAAC,iBAAiB,EAAE,CAAC,EAAE,CAAC,CAAC;YAChC,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,EAAE,CAAC;QACrB,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,mDAAmD,EAAE,GAAG,EAAE;YACzD,iGAAiG;YACjG,GAAG,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;YAClB,MAAM,CAAC,GAAG,EAAE;gBACR,GAAG,CAAC,iBAAiB,EAAE,CAAC,EAAE,CAAC,CAAC;YAChC,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,EAAE,CAAC;QACrB,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,oDAAoD,EAAE,GAAG,EAAE;YAC1D,GAAG,CAAC,OAAO,CAAC,GAAG,EAAE;gBACb,MAAM,KAAK,CAAC,QAAQ,CAAC,CAAC;YAC1B,CAAC,CAAC,CAAC;YACH,MAAM,CAAC,GAAG,EAAE;gBACR,GAAG,CAAC,iBAAiB,EAAE,CAAC,EAAE,CAAC,CAAC;YAChC,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,EAAE,CAAC;QACrB,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,gDAAgD,EAAE,GAAG,EAAE;YACtD,MAAM,EAAE,GAAG,IAAI,CAAC,EAAE,EAAE,CAAC;YACrB,GAAG,CAAC,SAAS,CAAC,EAAE,CAAC,CAAC;YAClB,GAAG,CAAC,kBAAkB,EAAE,CAAC,EAAE,CAAC,CAAC;YAC7B,MAAM,CAAC,EAAE,CAAC,CAAC,qBAAqB,CAAC,CAAC,CAAC,CAAC;QACxC,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,oCAAoC,EAAE,GAAG,EAAE;YAC1C,MAAM,CAAC,GAAG,EAAE;gBACR,GAAG,CAAC,kBAAkB,EAAE,CAAC,EAAE,CAAC,CAAC;YACjC,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,EAAE,CAAC;QACrB,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,qDAAqD,EAAE,GAAG,EAAE;YAC3D,iGAAiG;YACjG,GAAG,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC;YACpB,MAAM,CAAC,GAAG,EAAE;gBACR,GAAG,CAAC,kBAAkB,EAAE,CAAC,EAAE,CAAC,CAAC;YACjC,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,EAAE,CAAC;YACjB,MAAM,CAAC,OAAO,CAAC,CAAC,qBAAqB,CAAC,CAAC,CAAC,CAAC;QAC7C,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,sDAAsD,EAAE,GAAG,EAAE;YAC5D,GAAG,CAAC,SAAS,CAAC,GAAG,EAAE;gBACf,MAAM,KAAK,CAAC,QAAQ,CAAC,CAAC;YAC1B,CAAC,CAAC,CAAC;YACH,MAAM,CAAC,GAAG,EAAE;gBACR,GAAG,CAAC,kBAAkB,EAAE,CAAC,EAAE,CAAC,CAAC;YACjC,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,EAAE,CAAC;YACjB,MAAM,CAAC,OAAO,CAAC,CAAC,qBAAqB,CAAC,CAAC,CAAC,CAAC;QAC7C,CAAC,CAAC,CAAC;IACP,CAAC,CAAC,CAAC;AACP,CAAC,CAAC,CAAC"}
@@ -0,0 +1,10 @@
1
+ import { ExtensionType } from './extension-type';
2
+ export const factory = (provider) => {
3
+ return (...args) => {
4
+ return {
5
+ ...provider(...args),
6
+ type: ExtensionType.button,
7
+ };
8
+ };
9
+ };
10
+ //# sourceMappingURL=ButtonExtension.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ButtonExtension.js","sourceRoot":"","sources":["../../lib/ButtonExtension.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAC;AAUjD,MAAM,CAAC,MAAM,OAAO,GAAG,CAAW,QAA4C,EAAsC,EAAE;IAClH,OAAO,CAAC,GAAG,IAAI,EAAE,EAAE;QACf,OAAO;YACH,GAAG,QAAQ,CAAC,GAAG,IAAI,CAAC;YACpB,IAAI,EAAE,aAAa,CAAC,MAAM;SAC7B,CAAC;IACN,CAAC,CAAC;AACN,CAAC,CAAC"}
@@ -0,0 +1,46 @@
1
+ import * as ButtonExtension from './ButtonExtension';
2
+ describe('ButtonExtension', () => {
3
+ // @ts-expect-error We set the invalid type
4
+ const testAttributesProvider = (api, context) => {
5
+ api.onCleanup(jest.fn());
6
+ api.updateAttributes({});
7
+ return {
8
+ type: 'not-valid',
9
+ label: context.value === 42 ? 'The meaning of life' : 'A label',
10
+ onAction: jest.fn(),
11
+ };
12
+ };
13
+ const testAPI = {
14
+ onCleanup: jest.fn(),
15
+ updateAttributes: jest.fn(),
16
+ };
17
+ it('should generate the extension descriptor with the correct type', () => {
18
+ const extensionProvider = ButtonExtension.factory(testAttributesProvider);
19
+ const extension = extensionProvider(testAPI, {});
20
+ // expect all atributes to be merged, and type to be overwritten with the correct value.
21
+ expect(extension).toEqual({
22
+ type: 'button',
23
+ label: 'A label',
24
+ onAction: expect.any(Function),
25
+ });
26
+ });
27
+ it('should provide a extensionAPI object to the extension provider', () => {
28
+ expect(testAPI.onCleanup).toHaveBeenCalledTimes(0);
29
+ expect(testAPI.updateAttributes).toHaveBeenCalledTimes(0);
30
+ const extensionProvider = ButtonExtension.factory(testAttributesProvider);
31
+ extensionProvider(testAPI, {});
32
+ expect(testAPI.onCleanup).toHaveBeenCalledTimes(1);
33
+ expect(testAPI.updateAttributes).toHaveBeenCalledTimes(1);
34
+ });
35
+ it('should share any provided context with the attributes provider', () => {
36
+ const extensionProvider = ButtonExtension.factory(testAttributesProvider);
37
+ const extension = extensionProvider(testAPI, { value: 42 });
38
+ // expect label to change because of context
39
+ expect(extension).toEqual({
40
+ type: 'button',
41
+ label: 'The meaning of life',
42
+ onAction: expect.any(Function),
43
+ });
44
+ });
45
+ });
46
+ //# sourceMappingURL=ButtonExtension.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ButtonExtension.test.js","sourceRoot":"","sources":["../../lib/ButtonExtension.test.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,eAAe,MAAM,mBAAmB,CAAC;AAOrD,QAAQ,CAAC,iBAAiB,EAAE,GAAG,EAAE;IAC7B,2CAA2C;IAC3C,MAAM,sBAAsB,GAA6B,CAAC,GAAG,EAAE,OAAoB,EAAE,EAAE;QACnF,GAAG,CAAC,SAAS,CAAC,IAAI,CAAC,EAAE,EAAE,CAAC,CAAC;QACzB,GAAG,CAAC,gBAAgB,CAAC,EAAE,CAAC,CAAC;QAEzB,OAAO;YACH,IAAI,EAAE,WAAW;YACjB,KAAK,EAAE,OAAO,CAAC,KAAK,KAAK,EAAE,CAAC,CAAC,CAAC,qBAAqB,CAAC,CAAC,CAAC,SAAS;YAC/D,QAAQ,EAAE,IAAI,CAAC,EAAE,EAAE;SACtB,CAAC;IACN,CAAC,CAAC;IAEF,MAAM,OAAO,GAAgD;QACzD,SAAS,EAAE,IAAI,CAAC,EAAE,EAAE;QACpB,gBAAgB,EAAE,IAAI,CAAC,EAAE,EAAE;KAC9B,CAAC;IAEF,EAAE,CAAC,gEAAgE,EAAE,GAAG,EAAE;QACtE,MAAM,iBAAiB,GAAG,eAAe,CAAC,OAAO,CAAC,sBAAsB,CAAC,CAAC;QAC1E,MAAM,SAAS,GAAG,iBAAiB,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC;QAEjD,wFAAwF;QACxF,MAAM,CAAC,SAAS,CAAC,CAAC,OAAO,CAAC;YACtB,IAAI,EAAE,QAAQ;YACd,KAAK,EAAE,SAAS;YAChB,QAAQ,EAAE,MAAM,CAAC,GAAG,CAAC,QAAQ,CAAC;SACjC,CAAC,CAAC;IACP,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,gEAAgE,EAAE,GAAG,EAAE;QACtE,MAAM,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC,qBAAqB,CAAC,CAAC,CAAC,CAAC;QACnD,MAAM,CAAC,OAAO,CAAC,gBAAgB,CAAC,CAAC,qBAAqB,CAAC,CAAC,CAAC,CAAC;QAE1D,MAAM,iBAAiB,GAAG,eAAe,CAAC,OAAO,CAAC,sBAAsB,CAAC,CAAC;QAC1E,iBAAiB,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC;QAE/B,MAAM,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC,qBAAqB,CAAC,CAAC,CAAC,CAAC;QACnD,MAAM,CAAC,OAAO,CAAC,gBAAgB,CAAC,CAAC,qBAAqB,CAAC,CAAC,CAAC,CAAC;IAC9D,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,gEAAgE,EAAE,GAAG,EAAE;QACtE,MAAM,iBAAiB,GAAG,eAAe,CAAC,OAAO,CAAC,sBAAsB,CAAC,CAAC;QAC1E,MAAM,SAAS,GAAG,iBAAiB,CAAC,OAAO,EAAE,EAAE,KAAK,EAAE,EAAE,EAAE,CAAC,CAAC;QAE5D,4CAA4C;QAC5C,MAAM,CAAC,SAAS,CAAC,CAAC,OAAO,CAAC;YACtB,IAAI,EAAE,QAAQ;YACd,KAAK,EAAE,qBAAqB;YAC5B,QAAQ,EAAE,MAAM,CAAC,GAAG,CAAC,QAAQ,CAAC;SACjC,CAAC,CAAC;IACP,CAAC,CAAC,CAAC;AACP,CAAC,CAAC,CAAC"}
@@ -0,0 +1,11 @@
1
+ import { ExtensionType } from './extension-type';
2
+ // eslint-disable-next-line import/prefer-default-export
3
+ export const factory = (provider) => {
4
+ return (...args) => {
5
+ return {
6
+ ...provider(...args),
7
+ type: ExtensionType.link,
8
+ };
9
+ };
10
+ };
11
+ //# sourceMappingURL=LinkExtension.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"LinkExtension.js","sourceRoot":"","sources":["../../lib/LinkExtension.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAC;AAWjD,wDAAwD;AACxD,MAAM,CAAC,MAAM,OAAO,GAAG,CAAW,QAA0C,EAAoC,EAAE;IAC9G,OAAO,CAAC,GAAG,IAAI,EAAE,EAAE;QACf,OAAO;YACH,GAAG,QAAQ,CAAC,GAAG,IAAI,CAAC;YACpB,IAAI,EAAE,aAAa,CAAC,IAAI;SAC3B,CAAC;IACN,CAAC,CAAC;AACN,CAAC,CAAC"}
@@ -0,0 +1,46 @@
1
+ import * as LinkExtension from './LinkExtension';
2
+ describe('LinkExtension', () => {
3
+ // @ts-expect-error we set the invalid type
4
+ const testAttributesProvider = (api, context) => {
5
+ api.onCleanup(jest.fn());
6
+ api.updateAttributes({});
7
+ return {
8
+ type: 'not-valid',
9
+ label: context.value === 42 ? 'The meaning of life' : 'A label',
10
+ link: 'https://go.atlassian.com/clientside-extensions',
11
+ };
12
+ };
13
+ const testAPI = {
14
+ onCleanup: jest.fn(),
15
+ updateAttributes: jest.fn(),
16
+ };
17
+ it('should generate the extension descriptor with the correct type', () => {
18
+ const extensionProvider = LinkExtension.factory(testAttributesProvider);
19
+ const extension = extensionProvider(testAPI, {});
20
+ // expect all attributes to be merged, and type to be overwritten with the correct value.
21
+ expect(extension).toEqual({
22
+ type: 'link',
23
+ label: 'A label',
24
+ link: 'https://go.atlassian.com/clientside-extensions',
25
+ });
26
+ });
27
+ it('should provide a extensionAPI object to the extension provider', () => {
28
+ expect(testAPI.onCleanup).toHaveBeenCalledTimes(0);
29
+ expect(testAPI.updateAttributes).toHaveBeenCalledTimes(0);
30
+ const extensionProvider = LinkExtension.factory(testAttributesProvider);
31
+ extensionProvider(testAPI, {});
32
+ expect(testAPI.onCleanup).toHaveBeenCalledTimes(1);
33
+ expect(testAPI.updateAttributes).toHaveBeenCalledTimes(1);
34
+ });
35
+ it('should share any provided context with the attributes provider', () => {
36
+ const extensionProvider = LinkExtension.factory(testAttributesProvider);
37
+ const extension = extensionProvider(testAPI, { value: 42 });
38
+ // expect label to change because of context
39
+ expect(extension).toEqual({
40
+ type: 'link',
41
+ label: 'The meaning of life',
42
+ link: 'https://go.atlassian.com/clientside-extensions',
43
+ });
44
+ });
45
+ });
46
+ //# sourceMappingURL=LinkExtension.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"LinkExtension.test.js","sourceRoot":"","sources":["../../lib/LinkExtension.test.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,aAAa,MAAM,iBAAiB,CAAC;AAOjD,QAAQ,CAAC,eAAe,EAAE,GAAG,EAAE;IAC3B,2CAA2C;IAC3C,MAAM,sBAAsB,GAA2B,CAAC,GAAG,EAAE,OAAoB,EAAE,EAAE;QACjF,GAAG,CAAC,SAAS,CAAC,IAAI,CAAC,EAAE,EAAE,CAAC,CAAC;QACzB,GAAG,CAAC,gBAAgB,CAAC,EAAE,CAAC,CAAC;QAEzB,OAAO;YACH,IAAI,EAAE,WAAW;YACjB,KAAK,EAAE,OAAO,CAAC,KAAK,KAAK,EAAE,CAAC,CAAC,CAAC,qBAAqB,CAAC,CAAC,CAAC,SAAS;YAC/D,IAAI,EAAE,gDAAgD;SACzD,CAAC;IACN,CAAC,CAAC;IAEF,MAAM,OAAO,GAAgD;QACzD,SAAS,EAAE,IAAI,CAAC,EAAE,EAAE;QACpB,gBAAgB,EAAE,IAAI,CAAC,EAAE,EAAE;KAC9B,CAAC;IAEF,EAAE,CAAC,gEAAgE,EAAE,GAAG,EAAE;QACtE,MAAM,iBAAiB,GAAG,aAAa,CAAC,OAAO,CAAC,sBAAsB,CAAC,CAAC;QACxE,MAAM,SAAS,GAAG,iBAAiB,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC;QAEjD,yFAAyF;QACzF,MAAM,CAAC,SAAS,CAAC,CAAC,OAAO,CAAC;YACtB,IAAI,EAAE,MAAM;YACZ,KAAK,EAAE,SAAS;YAChB,IAAI,EAAE,gDAAgD;SACzD,CAAC,CAAC;IACP,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,gEAAgE,EAAE,GAAG,EAAE;QACtE,MAAM,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC,qBAAqB,CAAC,CAAC,CAAC,CAAC;QACnD,MAAM,CAAC,OAAO,CAAC,gBAAgB,CAAC,CAAC,qBAAqB,CAAC,CAAC,CAAC,CAAC;QAE1D,MAAM,iBAAiB,GAAG,aAAa,CAAC,OAAO,CAAC,sBAAsB,CAAC,CAAC;QACxE,iBAAiB,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC;QAE/B,MAAM,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC,qBAAqB,CAAC,CAAC,CAAC,CAAC;QACnD,MAAM,CAAC,OAAO,CAAC,gBAAgB,CAAC,CAAC,qBAAqB,CAAC,CAAC,CAAC,CAAC;IAC9D,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,gEAAgE,EAAE,GAAG,EAAE;QACtE,MAAM,iBAAiB,GAAG,aAAa,CAAC,OAAO,CAAC,sBAAsB,CAAC,CAAC;QACxE,MAAM,SAAS,GAAG,iBAAiB,CAAC,OAAO,EAAE,EAAE,KAAK,EAAE,EAAE,EAAE,CAAC,CAAC;QAE5D,4CAA4C;QAC5C,MAAM,CAAC,SAAS,CAAC,CAAC,OAAO,CAAC;YACtB,IAAI,EAAE,MAAM;YACZ,KAAK,EAAE,qBAAqB;YAC5B,IAAI,EAAE,gDAAgD;SACzD,CAAC,CAAC;IACP,CAAC,CAAC,CAAC;AACP,CAAC,CAAC,CAAC"}